From 4af765213c3502f6de5d0f02da4727673bb3f6ee Mon Sep 17 00:00:00 2001 From: levinsv <44033647+levinsv@users.noreply.github.com> Date: Wed, 10 Oct 2018 22:59:25 +0500 Subject: [PATCH] support PG11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Поддержка PostgreSQL 11 только для Windows --- .gitignore | 23 + Debug/Win32/libssh2/vc100.idb | Bin 0 -> 429056 bytes Debug/pgAdmin3.Build.CppClean.log | 56 + Debug/pgAdmin3.lastbuildstate | 2 + Debug/pgAdmin3.log | 5 + Debug/pgAdmin3.unsuccessfulbuild | 0 Debug/vc100.idb | Bin 0 -> 19456 bytes Debug/vc100.pdb | Bin 0 -> 36864 bytes Release/pgAdmin3.exe | Bin 0 -> 8907776 bytes agent/dlgJob.cpp | 513 + agent/dlgSchedule.cpp | 859 + agent/dlgStep.cpp | 483 + agent/module.mk | 23 + agent/pgaJob.cpp | 397 + agent/pgaSchedule.cpp | 576 + agent/pgaStep.cpp | 327 + ctl/calbox.cpp | 519 + ctl/ctlAuiNotebook.cpp | 41 + ctl/ctlCheckTreeView.cpp | 90 + ctl/ctlColourPicker.cpp | 121 + ctl/ctlComboBox.cpp | 240 + ctl/ctlDefaultSecurityPanel.cpp | 623 + ctl/ctlListView.cpp | 145 + ctl/ctlMenuToolbar.cpp | 193 + ctl/ctlProgressStatusBar.cpp | 202 + ctl/ctlSQLBox.cpp | 1044 + ctl/ctlSQLGrid.cpp | 554 + ctl/ctlSQLResult.cpp | 480 + ctl/ctlSeclabelPanel.cpp | 291 + ctl/ctlSecurityPanel.cpp | 445 + ctl/ctlTree.cpp | 398 + ctl/explainCanvas.cpp | 651 + ctl/explainShape.cpp | 581 + ctl/module.mk | 42 + ctl/timespin.cpp | 461 + ctl/xh_calb.cpp | 77 + ctl/xh_ctlchecktreeview.cpp | 33 + ctl/xh_ctlcolourpicker.cpp | 33 + ctl/xh_ctlcombo.cpp | 33 + ctl/xh_ctltree.cpp | 35 + ctl/xh_sqlbox.cpp | 45 + ctl/xh_timespin.cpp | 49 + db/keywords.c | 152 + db/module.mk | 20 + db/pgConn.cpp | 1334 + db/pgQueryThread.cpp | 901 + db/pgSet.cpp | 443 + dd/dditems/figures/ddColumnFigure.cpp | 538 + dd/dditems/figures/ddColumnKindIcon.cpp | 435 + dd/dditems/figures/ddColumnOptionIcon.cpp | 128 + dd/dditems/figures/ddRelationshipFigure.cpp | 930 + dd/dditems/figures/ddRelationshipItem.cpp | 132 + dd/dditems/figures/ddRelationshipTerminal.cpp | 154 + dd/dditems/figures/ddTableFigure.cpp | 1798 + dd/dditems/figures/ddTextTableItemFigure.cpp | 582 + dd/dditems/figures/module.mk | 25 + dd/dditems/figures/xml/ddXmlStorage.cpp | 1828 + dd/dditems/figures/xml/module.mk | 16 + dd/dditems/handles/ddAddColButtonHandle.cpp | 76 + dd/dditems/handles/ddAddFkButtonHandle.cpp | 73 + .../handles/ddMinMaxTableButtonHandle.cpp | 62 + .../handles/ddRemoveTableButtonHandle.cpp | 77 + dd/dditems/handles/ddScrollBarHandle.cpp | 131 + dd/dditems/handles/ddSouthTableSizeHandle.cpp | 94 + dd/dditems/handles/module.mk | 21 + dd/dditems/locators/ddAddColLocator.cpp | 41 + dd/dditems/locators/ddAddFkLocator.cpp | 41 + dd/dditems/locators/ddMinMaxTableLocator.cpp | 44 + dd/dditems/locators/ddRemoveTableLocator.cpp | 44 + .../locators/ddScrollBarTableLocator.cpp | 45 + dd/dditems/locators/ddTableBottomLocator.cpp | 45 + dd/dditems/locators/module.mk | 21 + dd/dditems/module.mk | 19 + dd/dditems/tools/ddColumnFigureTool.cpp | 130 + dd/dditems/tools/ddColumnTextTool.cpp | 83 + dd/dditems/tools/module.mk | 17 + .../utilities/ddPrecisionScaleDialog.cpp | 76 + .../utilities/ddSelectKindFksDialog.cpp | 316 + dd/dditems/utilities/ddTableNameDialog.cpp | 78 + dd/dditems/utilities/module.mk | 17 + dd/ddmodel/ddBrowserDataContainer.cpp | 42 + dd/ddmodel/ddDBReverseEnginering.cpp | 2087 + dd/ddmodel/ddDatabaseDesign.cpp | 710 + dd/ddmodel/ddDrawingEditor.cpp | 300 + dd/ddmodel/ddDrawingView.cpp | 90 + dd/ddmodel/ddGenerationWizard.cpp | 739 + dd/ddmodel/ddModelBrowser.cpp | 114 + dd/ddmodel/module.mk | 22 + dd/module.mk | 17 + debugger/ctlMessageWindow.cpp | 79 + debugger/ctlResultGrid.cpp | 100 + debugger/ctlStackWindow.cpp | 88 + debugger/ctlTabWindow.cpp | 175 + debugger/ctlVarWindow.cpp | 182 + debugger/dbgBreakPoint.cpp | 23 + debugger/dbgController.cpp | 913 + debugger/dbgEvents.cpp | 974 + debugger/dbgModel.cpp | 63 + debugger/dbgTargetInfo.cpp | 647 + debugger/debugger.cpp | 273 + debugger/dlgDirectDbg.cpp | 1073 + debugger/frmDebugger.cpp | 1025 + debugger/module.mk | 30 + dlg/dlgAddFavourite.cpp | 185 + dlg/dlgAggregate.cpp | 594 + dlg/dlgCast.cpp | 216 + dlg/dlgCheck.cpp | 185 + dlg/dlgClasses.cpp | 778 + dlg/dlgCollation.cpp | 187 + dlg/dlgColumn.cpp | 915 + dlg/dlgConnect.cpp | 102 + dlg/dlgConversion.cpp | 208 + dlg/dlgDatabase.cpp | 900 + dlg/dlgDomain.cpp | 443 + dlg/dlgEditGridOptions.cpp | 391 + dlg/dlgEventTrigger.cpp | 247 + dlg/dlgExtTable.cpp | 166 + dlg/dlgExtension.cpp | 198 + dlg/dlgFindReplace.cpp | 311 + dlg/dlgForeignDataWrapper.cpp | 400 + dlg/dlgForeignKey.cpp | 569 + dlg/dlgForeignServer.cpp | 329 + dlg/dlgForeignTable.cpp | 644 + dlg/dlgFunction.cpp | 1122 + dlg/dlgGroup.cpp | 221 + dlg/dlgHbaConfig.cpp | 436 + dlg/dlgIndex.cpp | 663 + dlg/dlgIndexConstraint.cpp | 688 + dlg/dlgLanguage.cpp | 263 + dlg/dlgMainConfig.cpp | 183 + dlg/dlgManageFavourites.cpp | 207 + dlg/dlgManageMacros.cpp | 229 + dlg/dlgMoveTablespace.cpp | 123 + dlg/dlgOperator.cpp | 469 + dlg/dlgPackage.cpp | 183 + dlg/dlgPgpassConfig.cpp | 124 + dlg/dlgProperty.cpp | 2372 + dlg/dlgReassignDropOwned.cpp | 122 + dlg/dlgResourceGroup.cpp | 170 + dlg/dlgRole.cpp | 930 + dlg/dlgRule.cpp | 196 + dlg/dlgSchema.cpp | 170 + dlg/dlgSearchObject.cpp | 971 + dlg/dlgSelectConnection.cpp | 382 + dlg/dlgSelectDatabase.cpp | 325 + dlg/dlgSequence.cpp | 386 + dlg/dlgServer.cpp | 745 + dlg/dlgSynonym.cpp | 316 + dlg/dlgTable.cpp | 2130 + dlg/dlgTablespace.cpp | 384 + dlg/dlgTextSearchConfiguration.cpp | 444 + dlg/dlgTextSearchDictionary.cpp | 350 + dlg/dlgTextSearchParser.cpp | 262 + dlg/dlgTextSearchTemplate.cpp | 190 + dlg/dlgTrigger.cpp | 551 + dlg/dlgType.cpp | 1432 + dlg/dlgUser.cpp | 571 + dlg/dlgUserMapping.cpp | 319 + dlg/dlgView.cpp | 1233 + dlg/module.mk | 72 + frm/events.cpp | 1179 + frm/frmAbout.cpp | 108 + frm/frmBackup.cpp | 636 + frm/frmBackupGlobals.cpp | 295 + frm/frmBackupServer.cpp | 270 + frm/frmConfig.cpp | 448 + frm/frmDatabaseDesigner.cpp | 929 + frm/frmEditGrid.cpp | 3385 ++ frm/frmExport.cpp | 588 + frm/frmGrantWizard.cpp | 340 + frm/frmHbaConfig.cpp | 394 + frm/frmHint.cpp | 510 + frm/frmImport.cpp | 379 + frm/frmMain.cpp | 1507 + frm/frmMainConfig.cpp | 717 + frm/frmMaintenance.cpp | 239 + frm/frmOptions.cpp | 1056 + frm/frmPassword.cpp | 117 + frm/frmPgpassConfig.cpp | 353 + frm/frmQuery.cpp | 4461 ++ frm/frmReport.cpp | 1557 + frm/frmRestore.cpp | 896 + frm/frmSplash.cpp | 83 + frm/frmStatus.cpp | 3657 ++ frm/module.mk | 40 + frm/plugins.cpp | 464 + gqb/gqbArrayCollection.cpp | 190 + gqb/gqbBrowser.cpp | 139 + gqb/gqbCollection.cpp | 98 + gqb/gqbColumn.cpp | 29 + gqb/gqbController.cpp | 606 + gqb/gqbDatabase.cpp | 157 + gqb/gqbGraphSimple.cpp | 494 + gqb/gqbGridJoinTable.cpp | 287 + gqb/gqbGridOrderTable.cpp | 293 + gqb/gqbGridProjTable.cpp | 327 + gqb/gqbGridRestTable.cpp | 372 + gqb/gqbModel.cpp | 114 + gqb/gqbObject.cpp | 32 + gqb/gqbObjectCollection.cpp | 112 + gqb/gqbQueryObjs.cpp | 513 + gqb/gqbSchema.cpp | 84 + gqb/gqbTable.cpp | 102 + gqb/gqbView.cpp | 844 + gqb/gqbViewPanels.cpp | 1646 + gqb/module.mk | 36 + hotdraw/connectors/hdChopBoxConnector.cpp | 82 + hotdraw/connectors/hdIConnector.cpp | 66 + hotdraw/connectors/hdLocatorConnector.cpp | 60 + .../connectors/hdStickyRectangleConnector.cpp | 73 + hotdraw/connectors/module.mk | 19 + .../defaultAttributes/hdFillAttribute.cpp | 45 + .../defaultAttributes/hdFontAttribute.cpp | 50 + .../hdFontColorAttribute.cpp | 38 + .../defaultAttributes/hdLineAttribute.cpp | 43 + hotdraw/figures/defaultAttributes/module.mk | 19 + hotdraw/figures/hdAbstractFigure.cpp | 130 + hotdraw/figures/hdAbstractMenuFigure.cpp | 59 + hotdraw/figures/hdAttribute.cpp | 34 + hotdraw/figures/hdAttributeFigure.cpp | 95 + hotdraw/figures/hdBitmapFigure.cpp | 62 + hotdraw/figures/hdCompositeFigure.cpp | 271 + hotdraw/figures/hdIConnectionFigure.cpp | 23 + hotdraw/figures/hdIFigure.cpp | 175 + hotdraw/figures/hdLineConnection.cpp | 293 + hotdraw/figures/hdLineTerminal.cpp | 59 + hotdraw/figures/hdPolyLineFigure.cpp | 446 + hotdraw/figures/hdRectangleFigure.cpp | 52 + hotdraw/figures/hdSimpleTextFigure.cpp | 139 + hotdraw/figures/module.mk | 31 + hotdraw/figures/xml/hdStorage.cpp | 34 + hotdraw/figures/xml/module.mk | 16 + hotdraw/handles/hdButtonHandle.cpp | 72 + .../handles/hdChangeConnectionEndHandle.cpp | 65 + hotdraw/handles/hdChangeConnectionHandle.cpp | 116 + .../handles/hdChangeConnectionStartHandle.cpp | 65 + hotdraw/handles/hdIHandle.cpp | 47 + hotdraw/handles/hdLineConnectionHandle.cpp | 46 + hotdraw/handles/hdLocatorHandle.cpp | 53 + hotdraw/handles/hdPolyLineHandle.cpp | 90 + hotdraw/handles/module.mk | 23 + hotdraw/locators/hdILocator.cpp | 27 + hotdraw/locators/hdPolyLineLocator.cpp | 59 + hotdraw/locators/module.mk | 17 + hotdraw/main/hdDrawing.cpp | 245 + hotdraw/main/hdDrawingEditor.cpp | 303 + hotdraw/main/hdDrawingView.cpp | 473 + hotdraw/main/module.mk | 18 + hotdraw/module.mk | 21 + hotdraw/tools/hdAbstractTool.cpp | 67 + hotdraw/tools/hdCanvasMenuTool.cpp | 82 + hotdraw/tools/hdCompositeFigureTool.cpp | 121 + hotdraw/tools/hdConnectionCreationTool.cpp | 140 + hotdraw/tools/hdCreationTool.cpp | 70 + hotdraw/tools/hdDragCreationTool.cpp | 36 + hotdraw/tools/hdDragTrackerTool.cpp | 101 + hotdraw/tools/hdFigureTool.cpp | 101 + hotdraw/tools/hdHandleTrackerTool.cpp | 45 + hotdraw/tools/hdITool.cpp | 94 + hotdraw/tools/hdMenuTool.cpp | 75 + hotdraw/tools/hdPolyLineFigureTool.cpp | 54 + hotdraw/tools/hdSelectAreaTool.cpp | 123 + hotdraw/tools/hdSelectionTool.cpp | 161 + hotdraw/tools/hdSimpleTextTool.cpp | 139 + hotdraw/tools/module.mk | 30 + hotdraw/utilities/hdArrayCollection.cpp | 221 + hotdraw/utilities/hdCollection.cpp | 112 + hotdraw/utilities/hdGeometry.cpp | 190 + hotdraw/utilities/hdKeyEvent.cpp | 36 + hotdraw/utilities/hdMouseEvent.cpp | 99 + hotdraw/utilities/hdMultiPosRect.cpp | 215 + hotdraw/utilities/hdPoint.cpp | 38 + hotdraw/utilities/hdRect.cpp | 83 + hotdraw/utilities/hdRemoveDeleteDialog.cpp | 169 + hotdraw/utilities/module.mk | 24 + include/.gitignore | 2 + include/agent/dlgJob.h | 61 + include/agent/dlgSchedule.h | 92 + include/agent/dlgStep.h | 67 + include/agent/module.mk | 22 + include/agent/pgaJob.h | 226 + include/agent/pgaSchedule.h | 151 + include/agent/pgaStep.h | 140 + include/copyright.h | 19 + include/ctl/calbox.h | 136 + include/ctl/ctlAuiNotebook.h | 36 + include/ctl/ctlCheckTreeView.h | 36 + include/ctl/ctlColourPicker.h | 48 + include/ctl/ctlComboBox.h | 61 + include/ctl/ctlDefaultSecurityPanel.h | 131 + include/ctl/ctlListView.h | 75 + include/ctl/ctlMenuToolbar.h | 91 + include/ctl/ctlProgressStatusBar.h | 61 + include/ctl/ctlSQLBox.h | 121 + include/ctl/ctlSQLGrid.h | 65 + include/ctl/ctlSQLResult.h | 115 + include/ctl/ctlSeclabelPanel.h | 63 + include/ctl/ctlSecurityPanel.h | 83 + include/ctl/ctlTree.h | 97 + include/ctl/explainCanvas.h | 159 + include/ctl/module.mk | 42 + include/ctl/timespin.h | 135 + include/ctl/wxgridsel.h | 26 + include/ctl/xh_calb.h | 30 + include/ctl/xh_ctlchecktreeview.h | 30 + include/ctl/xh_ctlcolourpicker.h | 31 + include/ctl/xh_ctlcombo.h | 31 + include/ctl/xh_ctltree.h | 30 + include/ctl/xh_sqlbox.h | 30 + include/ctl/xh_timespin.h | 30 + include/db/module.mk | 20 + include/db/pgConn.h | 313 + include/db/pgQueryResultEvent.h | 79 + include/db/pgQueryThread.h | 290 + include/db/pgSet.h | 244 + include/dd/dditems/figures/ddColumnFigure.h | 115 + include/dd/dditems/figures/ddColumnKindIcon.h | 72 + .../dd/dditems/figures/ddColumnOptionIcon.h | 54 + .../dd/dditems/figures/ddRelationshipFigure.h | 113 + .../dd/dditems/figures/ddRelationshipItem.h | 52 + .../dditems/figures/ddRelationshipTerminal.h | 34 + include/dd/dditems/figures/ddTableFigure.h | 191 + .../dditems/figures/ddTextTableItemFigure.h | 89 + include/dd/dditems/figures/module.mk | 25 + include/dd/dditems/figures/xml/ddXmlStorage.h | 66 + include/dd/dditems/figures/xml/module.mk | 16 + .../dd/dditems/handles/ddAddColButtonHandle.h | 32 + .../dd/dditems/handles/ddAddFkButtonHandle.h | 32 + .../handles/ddMinMaxTableButtonHandle.h | 34 + .../handles/ddRemoveTableButtonHandle.h | 32 + .../dd/dditems/handles/ddScrollBarHandle.h | 46 + .../dditems/handles/ddSouthTableSizeHandle.h | 36 + include/dd/dditems/handles/module.mk | 21 + include/dd/dditems/locators/ddAddColLocator.h | 30 + include/dd/dditems/locators/ddAddFkLocator.h | 30 + .../dditems/locators/ddMinMaxTableLocator.h | 30 + .../dditems/locators/ddRemoveTableLocator.h | 30 + .../locators/ddScrollBarTableLocator.h | 31 + .../dditems/locators/ddTableBottomLocator.h | 31 + include/dd/dditems/locators/module.mk | 21 + include/dd/dditems/module.mk | 19 + include/dd/dditems/tools/ddColumnFigureTool.h | 34 + include/dd/dditems/tools/ddColumnTextTool.h | 33 + include/dd/dditems/tools/module.mk | 17 + include/dd/dditems/utilities/ddDataType.h | 68 + .../utilities/ddPrecisionScaleDialog.h | 68 + .../dditems/utilities/ddSelectKindFksDialog.h | 102 + .../dd/dditems/utilities/ddTableNameDialog.h | 87 + include/dd/dditems/utilities/module.mk | 19 + include/dd/ddmodel/ddBrowserDataContainer.h | 28 + include/dd/ddmodel/ddDBReverseEngineering.h | 249 + include/dd/ddmodel/ddDatabaseDesign.h | 80 + include/dd/ddmodel/ddDrawingEditor.h | 44 + include/dd/ddmodel/ddDrawingView.h | 40 + include/dd/ddmodel/ddGenerationWizard.h | 224 + include/dd/ddmodel/ddModelBrowser.h | 46 + include/dd/ddmodel/module.mk | 22 + include/dd/module.mk | 17 + include/debugger/ctlMessageWindow.h | 44 + include/debugger/ctlResultGrid.h | 37 + include/debugger/ctlStackWindow.h | 84 + include/debugger/ctlTabWindow.h | 68 + include/debugger/ctlVarWindow.h | 80 + include/debugger/dbgBreakPoint.h | 49 + include/debugger/dbgConst.h | 80 + include/debugger/dbgController.h | 183 + include/debugger/dbgModel.h | 142 + include/debugger/dbgTargetInfo.h | 248 + include/debugger/debugger.h | 42 + include/debugger/dlgDirectDbg.h | 126 + include/debugger/frmDebugger.h | 176 + include/debugger/module.mk | 30 + include/dlg/dlgAddFavourite.h | 39 + include/dlg/dlgAggregate.h | 79 + include/dlg/dlgCast.h | 43 + include/dlg/dlgCheck.h | 47 + include/dlg/dlgClasses.h | 189 + include/dlg/dlgCollation.h | 42 + include/dlg/dlgColumn.h | 104 + include/dlg/dlgConnect.h | 36 + include/dlg/dlgConversion.h | 41 + include/dlg/dlgDatabase.h | 71 + include/dlg/dlgDomain.h | 53 + include/dlg/dlgEditGridOptions.h | 72 + include/dlg/dlgEventTrigger.h | 50 + include/dlg/dlgExtTable.h | 50 + include/dlg/dlgExtension.h | 42 + include/dlg/dlgFindReplace.h | 45 + include/dlg/dlgForeignDataWrapper.h | 51 + include/dlg/dlgForeignKey.h | 61 + include/dlg/dlgForeignServer.h | 53 + include/dlg/dlgForeignTable.h | 71 + include/dlg/dlgFunction.h | 105 + include/dlg/dlgGroup.h | 43 + include/dlg/dlgHbaConfig.h | 47 + include/dlg/dlgIndex.h | 73 + include/dlg/dlgIndexConstraint.h | 93 + include/dlg/dlgLanguage.h | 44 + include/dlg/dlgMainConfig.h | 38 + include/dlg/dlgManageFavourites.h | 40 + include/dlg/dlgManageMacros.h | 49 + include/dlg/dlgMoveTablespace.h | 43 + include/dlg/dlgOperator.h | 48 + include/dlg/dlgPackage.h | 53 + include/dlg/dlgPgpassConfig.h | 42 + include/dlg/dlgProperty.h | 383 + include/dlg/dlgReassignDropOwned.h | 44 + include/dlg/dlgResourceGroup.h | 44 + include/dlg/dlgRole.h | 70 + include/dlg/dlgRule.h | 44 + include/dlg/dlgSchema.h | 45 + include/dlg/dlgSearchObject.h | 82 + include/dlg/dlgSelectConnection.h | 52 + include/dlg/dlgSelectDatabase.h | 66 + include/dlg/dlgSequence.h | 50 + include/dlg/dlgServer.h | 59 + include/dlg/dlgSynonym.h | 60 + include/dlg/dlgTable.h | 131 + include/dlg/dlgTablespace.h | 57 + include/dlg/dlgTextSearchConfiguration.h | 59 + include/dlg/dlgTextSearchDictionary.h | 58 + include/dlg/dlgTextSearchParser.h | 46 + include/dlg/dlgTextSearchTemplate.h | 46 + include/dlg/dlgTrigger.h | 56 + include/dlg/dlgType.h | 94 + include/dlg/dlgUser.h | 61 + include/dlg/dlgUserMapping.h | 53 + include/dlg/dlgView.h | 82 + include/dlg/module.mk | 72 + include/frm/frmAbout.h | 41 + include/frm/frmBackup.h | 58 + include/frm/frmBackupGlobals.h | 55 + include/frm/frmBackupServer.h | 55 + include/frm/frmConfig.h | 85 + include/frm/frmDatabaseDesigner.h | 103 + include/frm/frmEditGrid.h | 376 + include/frm/frmExport.h | 43 + include/frm/frmGrantWizard.h | 58 + include/frm/frmHbaConfig.h | 71 + include/frm/frmHint.h | 79 + include/frm/frmImport.h | 49 + include/frm/frmMain.h | 363 + include/frm/frmMainConfig.h | 84 + include/frm/frmMaintenance.h | 45 + include/frm/frmOptions.h | 62 + include/frm/frmPassword.h | 43 + include/frm/frmPgpassConfig.h | 62 + include/frm/frmQuery.h | 448 + include/frm/frmReport.h | 168 + include/frm/frmRestore.h | 90 + include/frm/frmSplash.h | 30 + include/frm/frmStatus.h | 262 + include/frm/lib.txt | 1 + include/frm/menu.h | 155 + include/frm/module.mk | 40 + include/gqb/gqbArrayCollection.h | 70 + include/gqb/gqbBrowser.h | 68 + include/gqb/gqbCollection.h | 39 + include/gqb/gqbCollectionBase.h | 48 + include/gqb/gqbColumn.h | 25 + include/gqb/gqbDatabase.h | 34 + include/gqb/gqbEvents.h | 30 + include/gqb/gqbGraphBehavior.h | 39 + include/gqb/gqbGraphSimple.h | 46 + include/gqb/gqbGridJoinTable.h | 50 + include/gqb/gqbGridOrderTable.h | 51 + include/gqb/gqbGridProjTable.h | 55 + include/gqb/gqbGridRestTable.h | 101 + include/gqb/gqbModel.h | 104 + include/gqb/gqbObject.h | 68 + include/gqb/gqbObjectCollection.h | 45 + include/gqb/gqbQueryObjs.h | 195 + include/gqb/gqbSchema.h | 28 + include/gqb/gqbTable.h | 38 + include/gqb/gqbViewController.h | 241 + include/gqb/gqbViewPanels.h | 258 + include/gqb/module.mk | 37 + .../hotdraw/connectors/hdChopBoxConnector.h | 33 + include/hotdraw/connectors/hdIConnector.h | 40 + .../hotdraw/connectors/hdLocatorConnector.h | 40 + .../connectors/hdStickyRectangleConnector.h | 42 + include/hotdraw/connectors/module.mk | 19 + .../defaultAttributes/hdFillAttribute.h | 27 + .../defaultAttributes/hdFontAttribute.h | 29 + .../defaultAttributes/hdFontColorAttribute.h | 29 + .../defaultAttributes/hdLineAttribute.h | 27 + .../figures/defaultAttributes/module.mk | 19 + include/hotdraw/figures/hdAbstractFigure.h | 50 + .../hotdraw/figures/hdAbstractMenuFigure.h | 37 + include/hotdraw/figures/hdAttribute.h | 23 + include/hotdraw/figures/hdAttributeFigure.h | 55 + include/hotdraw/figures/hdBitmapFigure.h | 34 + include/hotdraw/figures/hdCompositeFigure.h | 44 + include/hotdraw/figures/hdIConnectionFigure.h | 55 + include/hotdraw/figures/hdIFigure.h | 69 + include/hotdraw/figures/hdLineConnection.h | 62 + include/hotdraw/figures/hdLineTerminal.h | 31 + include/hotdraw/figures/hdPolyLineFigure.h | 75 + include/hotdraw/figures/hdRectangleFigure.h | 35 + include/hotdraw/figures/hdSimpleTextFigure.h | 50 + include/hotdraw/figures/module.mk | 31 + include/hotdraw/figures/xml/hdStorage.h | 25 + include/hotdraw/figures/xml/module.mk | 16 + include/hotdraw/handles/hdButtonHandle.h | 41 + .../handles/hdChangeConnectionEndHandle.h | 30 + .../handles/hdChangeConnectionHandle.h | 44 + .../handles/hdChangeConnectionStartHandle.h | 30 + include/hotdraw/handles/hdIHandle.h | 48 + .../hotdraw/handles/hdLineConnectionHandle.h | 25 + include/hotdraw/handles/hdLocatorHandle.h | 39 + include/hotdraw/handles/hdPolyLineHandle.h | 40 + include/hotdraw/handles/module.mk | 23 + include/hotdraw/locators/hdILocator.h | 32 + include/hotdraw/locators/hdPolyLineLocator.h | 31 + include/hotdraw/locators/module.mk | 17 + include/hotdraw/main/hdDrawing.h | 85 + include/hotdraw/main/hdDrawingEditor.h | 52 + include/hotdraw/main/hdDrawingView.h | 123 + include/hotdraw/main/hdObject.h | 19 + include/hotdraw/main/module.mk | 19 + include/hotdraw/module.mk | 21 + include/hotdraw/tools/hdAbstractTool.h | 42 + include/hotdraw/tools/hdCanvasMenuTool.h | 34 + include/hotdraw/tools/hdCompositeFigureTool.h | 34 + .../hotdraw/tools/hdConnectionCreationTool.h | 38 + include/hotdraw/tools/hdCreationTool.h | 36 + include/hotdraw/tools/hdDragCreationTool.h | 26 + include/hotdraw/tools/hdDragTrackerTool.h | 42 + include/hotdraw/tools/hdFigureTool.h | 38 + include/hotdraw/tools/hdHandleTrackerTool.h | 38 + include/hotdraw/tools/hdITool.h | 42 + include/hotdraw/tools/hdMenuTool.h | 36 + include/hotdraw/tools/hdPolyLineFigureTool.h | 27 + include/hotdraw/tools/hdSelectAreaTool.h | 37 + include/hotdraw/tools/hdSelectionTool.h | 37 + include/hotdraw/tools/hdSimpleTextTool.h | 41 + include/hotdraw/tools/module.mk | 30 + include/hotdraw/utilities/hdArrayCollection.h | 77 + include/hotdraw/utilities/hdCollection.h | 43 + include/hotdraw/utilities/hdCollectionBase.h | 54 + include/hotdraw/utilities/hdGeometry.h | 40 + include/hotdraw/utilities/hdKeyEvent.h | 30 + include/hotdraw/utilities/hdMouseEvent.h | 43 + include/hotdraw/utilities/hdMultiPosRect.h | 342 + include/hotdraw/utilities/hdPoint.h | 24 + include/hotdraw/utilities/hdRect.h | 34 + .../hotdraw/utilities/hdRemoveDeleteDialog.h | 64 + include/hotdraw/utilities/module.mk | 25 + include/images/aggregate-sm.png | Bin 0 -> 351 bytes include/images/aggregate-sm.pngc | 88 + include/images/aggregate.png | Bin 0 -> 374 bytes include/images/aggregate.pngc | 91 + include/images/aggregates.png | Bin 0 -> 373 bytes include/images/aggregates.pngc | 91 + include/images/back.png | Bin 0 -> 353 bytes include/images/back.pngc | 89 + include/images/backup.png | Bin 0 -> 811 bytes include/images/backup.pngc | 146 + include/images/baddatabase.png | Bin 0 -> 788 bytes include/images/baddatabase.pngc | 143 + include/images/cast-sm.png | Bin 0 -> 385 bytes include/images/cast-sm.pngc | 93 + include/images/cast.png | Bin 0 -> 426 bytes include/images/cast.pngc | 98 + include/images/casts.png | Bin 0 -> 402 bytes include/images/casts.pngc | 95 + include/images/catalog-sm.png | Bin 0 -> 328 bytes include/images/catalog-sm.pngc | 85 + include/images/catalog.png | Bin 0 -> 387 bytes include/images/catalog.pngc | 93 + include/images/catalogobject-sm.png | Bin 0 -> 386 bytes include/images/catalogobject-sm.pngc | 93 + include/images/catalogobject.png | Bin 0 -> 409 bytes include/images/catalogobject.pngc | 96 + include/images/catalogobjects.png | Bin 0 -> 419 bytes include/images/catalogobjects.pngc | 97 + include/images/catalogs.png | Bin 0 -> 371 bytes include/images/catalogs.pngc | 91 + include/images/check.png | Bin 0 -> 406 bytes include/images/check.pngc | 95 + include/images/checkbad.png | Bin 0 -> 579 bytes include/images/checkbad.pngc | 117 + include/images/checked.png | Bin 0 -> 299 bytes include/images/checked.pngc | 82 + include/images/clearAll.png | Bin 0 -> 318 bytes include/images/clearAll.pngc | 84 + include/images/clip_copy.png | Bin 0 -> 489 bytes include/images/clip_copy.pngc | 106 + include/images/clip_cut.png | Bin 0 -> 563 bytes include/images/clip_cut.pngc | 115 + include/images/clip_paste.png | Bin 0 -> 646 bytes include/images/clip_paste.pngc | 125 + include/images/closeddatabase-sm.png | Bin 0 -> 853 bytes include/images/closeddatabase-sm.pngc | 151 + include/images/closeddatabase.png | Bin 0 -> 814 bytes include/images/closeddatabase.pngc | 146 + include/images/collation-sm.png | Bin 0 -> 233 bytes include/images/collation-sm.pngc | 74 + include/images/collation.png | Bin 0 -> 233 bytes include/images/collation.pngc | 74 + include/images/collations.png | Bin 0 -> 178 bytes include/images/collations.pngc | 67 + include/images/column-sm.png | Bin 0 -> 371 bytes include/images/column-sm.pngc | 91 + include/images/column.png | Bin 0 -> 435 bytes include/images/column.pngc | 99 + include/images/columns.png | Bin 0 -> 400 bytes include/images/columns.pngc | 94 + include/images/configuration.png | Bin 0 -> 346 bytes include/images/configuration.pngc | 88 + include/images/configurations.png | Bin 0 -> 369 bytes include/images/configurations.pngc | 91 + include/images/connect.png | Bin 0 -> 675 bytes include/images/connect.pngc | 129 + include/images/constraints.png | Bin 0 -> 314 bytes include/images/constraints.pngc | 84 + include/images/continue.png | Bin 0 -> 402 bytes include/images/continue.pngc | 95 + include/images/conversion.png | Bin 0 -> 356 bytes include/images/conversion.pngc | 89 + include/images/conversions.png | Bin 0 -> 356 bytes include/images/conversions.pngc | 89 + include/images/create.png | Bin 0 -> 1021 bytes include/images/create.pngc | 172 + include/images/database-sm.png | Bin 0 -> 688 bytes include/images/database-sm.pngc | 130 + include/images/database.png | Bin 0 -> 706 bytes include/images/database.pngc | 133 + include/images/databases.png | Bin 0 -> 771 bytes include/images/databases.pngc | 141 + include/images/ddAddColumn.png | Bin 0 -> 165 bytes include/images/ddAddColumn.pngc | 65 + include/images/ddAddColumnCursor.png | Bin 0 -> 612 bytes include/images/ddAddColumnCursor.pngc | 121 + include/images/ddAddForeignKey.png | Bin 0 -> 173 bytes include/images/ddAddForeignKey.pngc | 66 + include/images/ddDeleteTableCursor.png | Bin 0 -> 937 bytes include/images/ddDeleteTableCursor.pngc | 162 + include/images/ddDown.png | Bin 0 -> 291 bytes include/images/ddDown.pngc | 81 + include/images/ddMaximizeTable.png | Bin 0 -> 162 bytes include/images/ddMaximizeTable.pngc | 65 + include/images/ddMinMaxCursor.png | Bin 0 -> 1569 bytes include/images/ddMinMaxCursor.pngc | 241 + include/images/ddMinimizeTable.png | Bin 0 -> 159 bytes include/images/ddMinimizeTable.pngc | 64 + include/images/ddRelationshipCursor.png | Bin 0 -> 611 bytes include/images/ddRelationshipCursor.pngc | 121 + include/images/ddRemoveColumn.png | Bin 0 -> 151 bytes include/images/ddRemoveColumn.pngc | 63 + include/images/ddRemoveColumnCursor.png | Bin 0 -> 751 bytes include/images/ddRemoveColumnCursor.pngc | 138 + include/images/ddRemoveTable.png | Bin 0 -> 178 bytes include/images/ddRemoveTable.pngc | 67 + include/images/ddRemoveTable2.png | Bin 0 -> 759 bytes include/images/ddRemoveTable2.pngc | 139 + include/images/ddUp.png | Bin 0 -> 278 bytes include/images/ddUp.pngc | 79 + include/images/ddcancel.png | Bin 0 -> 485 bytes include/images/ddcancel.pngc | 105 + include/images/ddforeignkey.png | Bin 0 -> 329 bytes include/images/ddforeignkey.pngc | 86 + include/images/ddforeignkeyfromuk.png | Bin 0 -> 355 bytes include/images/ddforeignkeyfromuk.pngc | 89 + include/images/ddforeignkeyuniquekey.png | Bin 0 -> 361 bytes include/images/ddforeignkeyuniquekey.pngc | 90 + .../images/ddforeignkeyuniquekeyfromuk.png | Bin 0 -> 377 bytes .../images/ddforeignkeyuniquekeyfromuk.pngc | 92 + include/images/ddgendiagram.png | Bin 0 -> 332 bytes include/images/ddgendiagram.pngc | 86 + include/images/ddmodel-32.png | Bin 0 -> 640 bytes include/images/ddmodel-32.pngc | 124 + include/images/ddnewdiagram.png | Bin 0 -> 355 bytes include/images/ddnewdiagram.pngc | 89 + include/images/ddnotnull.png | Bin 0 -> 176 bytes include/images/ddnotnull.pngc | 66 + include/images/ddnull.png | Bin 0 -> 169 bytes include/images/ddnull.pngc | 66 + include/images/ddprimaryforeignkey.png | Bin 0 -> 367 bytes include/images/ddprimaryforeignkey.pngc | 90 + include/images/ddprimaryforeignkeyfromuk.png | Bin 0 -> 386 bytes include/images/ddprimaryforeignkeyfromuk.pngc | 93 + include/images/ddprimarykey.png | Bin 0 -> 344 bytes include/images/ddprimarykey.pngc | 87 + include/images/ddprimarykeyuniquekey.png | Bin 0 -> 361 bytes include/images/ddprimarykeyuniquekey.pngc | 90 + include/images/ddunique.png | Bin 0 -> 241 bytes include/images/ddunique.pngc | 75 + include/images/debugger.png | Bin 0 -> 350 bytes include/images/debugger.pngc | 88 + include/images/delete.png | Bin 0 -> 608 bytes include/images/delete.pngc | 120 + include/images/dictionaries.png | Bin 0 -> 362 bytes include/images/dictionaries.pngc | 90 + include/images/dictionary.png | Bin 0 -> 634 bytes include/images/dictionary.pngc | 124 + include/images/disabled.png | Bin 0 -> 267 bytes include/images/disabled.pngc | 78 + include/images/dnd_copy.png | Bin 0 -> 312 bytes include/images/dnd_copy.pngc | 83 + include/images/dnd_move.png | Bin 0 -> 302 bytes include/images/dnd_move.pngc | 82 + include/images/dnd_none.png | Bin 0 -> 367 bytes include/images/dnd_none.pngc | 90 + include/images/domain-sm.png | Bin 0 -> 401 bytes include/images/domain-sm.pngc | 95 + include/images/domain.png | Bin 0 -> 424 bytes include/images/domain.pngc | 97 + include/images/domains.png | Bin 0 -> 462 bytes include/images/domains.pngc | 102 + include/images/down.png | Bin 0 -> 388 bytes include/images/down.pngc | 93 + include/images/drop.png | Bin 0 -> 919 bytes include/images/drop.pngc | 159 + include/images/edit_clear.png | Bin 0 -> 621 bytes include/images/edit_clear.pngc | 122 + include/images/edit_find.png | Bin 0 -> 657 bytes include/images/edit_find.pngc | 127 + include/images/edit_redo.png | Bin 0 -> 654 bytes include/images/edit_redo.pngc | 126 + include/images/edit_undo.png | Bin 0 -> 657 bytes include/images/edit_undo.pngc | 127 + include/images/enumeration.png | Bin 0 -> 623 bytes include/images/enumeration.pngc | 122 + include/images/enumerations.png | Bin 0 -> 502 bytes include/images/enumerations.pngc | 107 + include/images/ex_aggregate.png | Bin 0 -> 1066 bytes include/images/ex_aggregate.pngc | 178 + include/images/ex_append.png | Bin 0 -> 1162 bytes include/images/ex_append.pngc | 190 + include/images/ex_bmp_and.png | Bin 0 -> 1006 bytes include/images/ex_bmp_and.pngc | 170 + include/images/ex_bmp_heap.png | Bin 0 -> 1106 bytes include/images/ex_bmp_heap.pngc | 183 + include/images/ex_bmp_index.png | Bin 0 -> 1172 bytes include/images/ex_bmp_index.pngc | 191 + include/images/ex_bmp_or.png | Bin 0 -> 685 bytes include/images/ex_bmp_or.pngc | 130 + include/images/ex_broadcast_motion.png | Bin 0 -> 334 bytes include/images/ex_broadcast_motion.pngc | 86 + include/images/ex_cte_scan.png | Bin 0 -> 1955 bytes include/images/ex_cte_scan.pngc | 289 + include/images/ex_delete.png | Bin 0 -> 1129 bytes include/images/ex_delete.pngc | 186 + include/images/ex_foreign_scan.png | Bin 0 -> 1607 bytes include/images/ex_foreign_scan.pngc | 245 + include/images/ex_gatcher.png | Bin 0 -> 1056 bytes include/images/ex_gatcher.pngc | 176 + include/images/ex_gather.png | Bin 0 -> 9757 bytes include/images/ex_gather.pngc | 1264 + include/images/ex_gather_motion.png | Bin 0 -> 218 bytes include/images/ex_gather_motion.pngc | 72 + include/images/ex_group.png | Bin 0 -> 1228 bytes include/images/ex_group.pngc | 198 + include/images/ex_hash.png | Bin 0 -> 1169 bytes include/images/ex_hash.pngc | 191 + include/images/ex_hash_anti_join.png | Bin 0 -> 1571 bytes include/images/ex_hash_anti_join.pngc | 241 + include/images/ex_hash_semi_join.png | Bin 0 -> 1452 bytes include/images/ex_hash_semi_join.pngc | 226 + include/images/ex_hash_setop_except.png | Bin 0 -> 1377 bytes include/images/ex_hash_setop_except.pngc | 217 + include/images/ex_hash_setop_except_all.png | Bin 0 -> 1402 bytes include/images/ex_hash_setop_except_all.pngc | 220 + include/images/ex_hash_setop_intersect.png | Bin 0 -> 1389 bytes include/images/ex_hash_setop_intersect.pngc | 218 + .../images/ex_hash_setop_intersect_all.png | Bin 0 -> 1417 bytes .../images/ex_hash_setop_intersect_all.pngc | 222 + include/images/ex_hash_setop_unknown.png | Bin 0 -> 1490 bytes include/images/ex_hash_setop_unknown.pngc | 231 + include/images/ex_index_only_scan.png | Bin 0 -> 498 bytes include/images/ex_index_only_scan.pngc | 107 + include/images/ex_index_scan.png | Bin 0 -> 1298 bytes include/images/ex_index_scan.pngc | 207 + include/images/ex_insert.png | Bin 0 -> 1065 bytes include/images/ex_insert.pngc | 178 + include/images/ex_join.png | Bin 0 -> 1090 bytes include/images/ex_join.pngc | 181 + include/images/ex_limit.png | Bin 0 -> 1237 bytes include/images/ex_limit.pngc | 199 + include/images/ex_lock_rows.png | Bin 0 -> 1520 bytes include/images/ex_lock_rows.pngc | 234 + include/images/ex_materialize.png | Bin 0 -> 1221 bytes include/images/ex_materialize.pngc | 197 + include/images/ex_merge.png | Bin 0 -> 1127 bytes include/images/ex_merge.pngc | 185 + include/images/ex_merge_anti_join.png | Bin 0 -> 1599 bytes include/images/ex_merge_anti_join.pngc | 244 + include/images/ex_merge_append.png | Bin 0 -> 980 bytes include/images/ex_merge_append.pngc | 167 + include/images/ex_merge_semi_join.png | Bin 0 -> 1344 bytes include/images/ex_merge_semi_join.pngc | 212 + include/images/ex_nested.png | Bin 0 -> 1108 bytes include/images/ex_nested.pngc | 183 + include/images/ex_nested_loop_anti_join.png | Bin 0 -> 1741 bytes include/images/ex_nested_loop_anti_join.pngc | 262 + include/images/ex_nested_loop_semi_join.png | Bin 0 -> 1679 bytes include/images/ex_nested_loop_semi_join.pngc | 254 + include/images/ex_pscan.png | Bin 0 -> 1275 bytes include/images/ex_pscan.pngc | 204 + include/images/ex_pscan2.png | Bin 0 -> 1275 bytes include/images/ex_recursive_union.png | Bin 0 -> 1224 bytes include/images/ex_recursive_union.pngc | 197 + include/images/ex_redistribute_motion.png | Bin 0 -> 218 bytes include/images/ex_redistribute_motion.pngc | 72 + include/images/ex_result.png | Bin 0 -> 1320 bytes include/images/ex_result.pngc | 209 + include/images/ex_scan.png | Bin 0 -> 1320 bytes include/images/ex_scan.pngc | 209 + include/images/ex_seek.png | Bin 0 -> 1326 bytes include/images/ex_seek.pngc | 210 + include/images/ex_setop.png | Bin 0 -> 1143 bytes include/images/ex_setop.pngc | 187 + include/images/ex_sort.png | Bin 0 -> 1157 bytes include/images/ex_sort.pngc | 189 + include/images/ex_subplan.png | Bin 0 -> 1283 bytes include/images/ex_subplan.pngc | 205 + include/images/ex_tid_scan.png | Bin 0 -> 1074 bytes include/images/ex_tid_scan.pngc | 179 + include/images/ex_unique.png | Bin 0 -> 1238 bytes include/images/ex_unique.pngc | 199 + include/images/ex_unknown.png | Bin 0 -> 1088 bytes include/images/ex_unknown.pngc | 180 + include/images/ex_update.png | Bin 0 -> 1090 bytes include/images/ex_update.pngc | 181 + include/images/ex_values_scan.png | Bin 0 -> 913 bytes include/images/ex_values_scan.pngc | 159 + include/images/ex_window_aggregate.png | Bin 0 -> 2021 bytes include/images/ex_window_aggregate.pngc | 297 + include/images/ex_worktable_scan.png | Bin 0 -> 1965 bytes include/images/ex_worktable_scan.pngc | 290 + include/images/exclude.png | Bin 0 -> 725 bytes include/images/exclude.pngc | 135 + include/images/extension-sm.png | Bin 0 -> 423 bytes include/images/extension-sm.pngc | 97 + include/images/extension.png | Bin 0 -> 996 bytes include/images/extension.pngc | 169 + include/images/extensions.png | Bin 0 -> 1017 bytes include/images/extensions.pngc | 172 + include/images/exttable-sm.png | Bin 0 -> 612 bytes include/images/exttable-sm.pngc | 121 + include/images/exttable.png | Bin 0 -> 793 bytes include/images/exttable.pngc | 144 + include/images/exttables.png | Bin 0 -> 662 bytes include/images/exttables.pngc | 127 + include/images/favourite.png | Bin 0 -> 581 bytes include/images/favourite.pngc | 117 + include/images/file_new.png | Bin 0 -> 226 bytes include/images/file_new.pngc | 73 + include/images/file_open.png | Bin 0 -> 738 bytes include/images/file_open.pngc | 137 + include/images/file_save.png | Bin 0 -> 636 bytes include/images/file_save.pngc | 124 + include/images/folder.png | Bin 0 -> 508 bytes include/images/folder.pngc | 108 + include/images/foreigndatawrapper-sm.png | Bin 0 -> 423 bytes include/images/foreigndatawrapper-sm.pngc | 97 + include/images/foreigndatawrapper.png | Bin 0 -> 411 bytes include/images/foreigndatawrapper.pngc | 96 + include/images/foreigndatawrappers.png | Bin 0 -> 444 bytes include/images/foreigndatawrappers.pngc | 100 + include/images/foreignkey.png | Bin 0 -> 299 bytes include/images/foreignkey.pngc | 82 + include/images/foreignkeybad.png | Bin 0 -> 618 bytes include/images/foreignkeybad.pngc | 122 + include/images/foreignserver-sm.png | Bin 0 -> 423 bytes include/images/foreignserver-sm.pngc | 97 + include/images/foreignserver.png | Bin 0 -> 518 bytes include/images/foreignserver.pngc | 109 + include/images/foreignservers.png | Bin 0 -> 476 bytes include/images/foreignservers.pngc | 104 + include/images/foreigntable.png | Bin 0 -> 563 bytes include/images/foreigntable.pngc | 115 + include/images/foreigntables.png | Bin 0 -> 492 bytes include/images/foreigntables.pngc | 106 + include/images/forward.png | Bin 0 -> 352 bytes include/images/forward.pngc | 88 + include/images/function.png | Bin 0 -> 325 bytes include/images/function.pngc | 85 + include/images/functions.png | Bin 0 -> 349 bytes include/images/functions.pngc | 88 + include/images/gqbAdd.png | Bin 0 -> 228 bytes include/images/gqbAdd.pngc | 73 + include/images/gqbAddRest.png | Bin 0 -> 533 bytes include/images/gqbAddRest.pngc | 111 + include/images/gqbColNotSel.png | Bin 0 -> 362 bytes include/images/gqbColNotSel.pngc | 90 + include/images/gqbColSel.png | Bin 0 -> 408 bytes include/images/gqbColSel.pngc | 95 + include/images/gqbDown.png | Bin 0 -> 388 bytes include/images/gqbDown.pngc | 93 + include/images/gqbDownBottom.png | Bin 0 -> 349 bytes include/images/gqbDownBottom.pngc | 88 + include/images/gqbJoin.png | Bin 0 -> 506 bytes include/images/gqbJoin.pngc | 108 + include/images/gqbJoinCursor.png | Bin 0 -> 238 bytes include/images/gqbJoinCursor.pngc | 74 + include/images/gqbOrderAdd.png | Bin 0 -> 308 bytes include/images/gqbOrderAdd.pngc | 83 + include/images/gqbOrderAddAll.png | Bin 0 -> 324 bytes include/images/gqbOrderAddAll.pngc | 85 + include/images/gqbOrderRemove.png | Bin 0 -> 309 bytes include/images/gqbOrderRemove.pngc | 83 + include/images/gqbOrderRemoveAll.png | Bin 0 -> 320 bytes include/images/gqbOrderRemoveAll.pngc | 84 + include/images/gqbRemove.png | Bin 0 -> 225 bytes include/images/gqbRemove.pngc | 73 + include/images/gqbRemoveRest.png | Bin 0 -> 730 bytes include/images/gqbRemoveRest.pngc | 136 + include/images/gqbUp.png | Bin 0 -> 389 bytes include/images/gqbUp.pngc | 93 + include/images/gqbUpTop.png | Bin 0 -> 347 bytes include/images/gqbUpTop.pngc | 88 + include/images/group.png | Bin 0 -> 804 bytes include/images/group.pngc | 145 + include/images/groups.png | Bin 0 -> 757 bytes include/images/groups.pngc | 139 + include/images/help.png | Bin 0 -> 651 bytes include/images/help.pngc | 126 + include/images/help2.png | Bin 0 -> 947 bytes include/images/help2.pngc | 163 + include/images/hint.png | Bin 0 -> 1152 bytes include/images/hint.pngc | 188 + include/images/hint2.png | Bin 0 -> 752 bytes include/images/hint2.pngc | 138 + include/images/index.png | Bin 0 -> 562 bytes include/images/index.pngc | 115 + include/images/indexes.png | Bin 0 -> 468 bytes include/images/indexes.pngc | 103 + include/images/job.png | Bin 0 -> 678 bytes include/images/job.pngc | 129 + include/images/jobdisabled.png | Bin 0 -> 601 bytes include/images/jobdisabled.pngc | 120 + include/images/jobs.png | Bin 0 -> 521 bytes include/images/jobs.pngc | 110 + include/images/key.png | Bin 0 -> 450 bytes include/images/key.pngc | 101 + include/images/language-sm.png | Bin 0 -> 423 bytes include/images/language-sm.pngc | 97 + include/images/language.png | Bin 0 -> 465 bytes include/images/language.pngc | 103 + include/images/languages.png | Bin 0 -> 477 bytes include/images/languages.pngc | 104 + include/images/loginroles.png | Bin 0 -> 767 bytes include/images/loginroles.pngc | 140 + include/images/module.mk | 330 + include/images/mview-sm.png | Bin 0 -> 344 bytes include/images/mview-sm.pngc | 87 + include/images/mview.png | Bin 0 -> 374 bytes include/images/mview.pngc | 91 + include/images/namespace-sm.png | Bin 0 -> 322 bytes include/images/namespace-sm.pngc | 85 + include/images/namespace.png | Bin 0 -> 376 bytes include/images/namespace.pngc | 91 + include/images/namespaces.png | Bin 0 -> 374 bytes include/images/namespaces.pngc | 91 + include/images/operator.png | Bin 0 -> 315 bytes include/images/operator.pngc | 84 + include/images/operatorclass.png | Bin 0 -> 588 bytes include/images/operatorclass.pngc | 118 + include/images/operatorclasses.png | Bin 0 -> 473 bytes include/images/operatorclasses.pngc | 104 + include/images/operatorfamilies.png | Bin 0 -> 429 bytes include/images/operatorfamilies.pngc | 98 + include/images/operatorfamily.png | Bin 0 -> 463 bytes include/images/operatorfamily.pngc | 102 + include/images/operators.png | Bin 0 -> 321 bytes include/images/operators.pngc | 85 + include/images/package.png | Bin 0 -> 673 bytes include/images/package.pngc | 129 + include/images/packages.png | Bin 0 -> 557 bytes include/images/packages.pngc | 114 + include/images/parser.png | Bin 0 -> 715 bytes include/images/parser.pngc | 134 + include/images/parsers.png | Bin 0 -> 620 bytes include/images/parsers.pngc | 122 + include/images/pgAdmin3-128.png | Bin 0 -> 8373 bytes include/images/pgAdmin3-16.png | Bin 0 -> 850 bytes include/images/pgAdmin3-16.pngc | 151 + include/images/pgAdmin3-22.png | Bin 0 -> 1180 bytes include/images/pgAdmin3-24.png | Bin 0 -> 1310 bytes include/images/pgAdmin3-256.png | Bin 0 -> 16995 bytes include/images/pgAdmin3-32.png | Bin 0 -> 1906 bytes include/images/pgAdmin3-32.pngc | 283 + include/images/pgAdmin3-36.png | Bin 0 -> 2174 bytes include/images/pgAdmin3-48.png | Bin 0 -> 3073 bytes include/images/pgAdmin3-96.png | Bin 0 -> 6233 bytes include/images/pgAdmin3.ico | Bin 0 -> 35147 bytes include/images/pgAdmin3.png | Bin 0 -> 7458 bytes include/images/pgAdmin3.pngc | 977 + include/images/pgAdmin3.svg | 54 + include/images/plugins.png | Bin 0 -> 1457 bytes include/images/plugins.pngc | 227 + include/images/primarykey.png | Bin 0 -> 443 bytes include/images/primarykey.pngc | 100 + include/images/procedure.png | Bin 0 -> 322 bytes include/images/procedure.pngc | 85 + include/images/procedures.png | Bin 0 -> 337 bytes include/images/procedures.pngc | 87 + include/images/properties.png | Bin 0 -> 908 bytes include/images/properties.pngc | 158 + include/images/property.png | Bin 0 -> 576 bytes include/images/property.pngc | 116 + include/images/query_cancel.png | Bin 0 -> 498 bytes include/images/query_cancel.pngc | 107 + include/images/query_commit.png | Bin 0 -> 707 bytes include/images/query_commit.pngc | 133 + include/images/query_execfile.png | Bin 0 -> 600 bytes include/images/query_execfile.pngc | 119 + include/images/query_execute.png | Bin 0 -> 402 bytes include/images/query_execute.pngc | 95 + include/images/query_explain.png | Bin 0 -> 455 bytes include/images/query_explain.pngc | 101 + include/images/query_pgscript.png | Bin 0 -> 450 bytes include/images/query_pgscript.pngc | 101 + include/images/query_rollback.png | Bin 0 -> 583 bytes include/images/query_rollback.pngc | 117 + include/images/readdata.png | Bin 0 -> 819 bytes include/images/readdata.pngc | 147 + include/images/refresh.png | Bin 0 -> 1190 bytes include/images/refresh.pngc | 193 + include/images/reload.png | Bin 0 -> 368 bytes include/images/reload.pngc | 90 + include/images/resourcegroup.png | Bin 0 -> 966 bytes include/images/resourcegroup.pngc | 165 + include/images/resourcegroups.png | Bin 0 -> 1173 bytes include/images/resourcegroups.pngc | 191 + include/images/restore.png | Bin 0 -> 822 bytes include/images/restore.pngc | 147 + include/images/roles.png | Bin 0 -> 620 bytes include/images/roles.pngc | 122 + include/images/rule.png | Bin 0 -> 373 bytes include/images/rule.pngc | 91 + include/images/rulebad.png | Bin 0 -> 630 bytes include/images/rulebad.pngc | 123 + include/images/rules.png | Bin 0 -> 357 bytes include/images/rules.pngc | 89 + include/images/schedule.png | Bin 0 -> 683 bytes include/images/schedule.pngc | 130 + include/images/schedules.png | Bin 0 -> 650 bytes include/images/schedules.pngc | 126 + include/images/sequence-repl.png | Bin 0 -> 587 bytes include/images/sequence-repl.pngc | 118 + include/images/sequence.png | Bin 0 -> 405 bytes include/images/sequence.pngc | 95 + include/images/sequences.png | Bin 0 -> 359 bytes include/images/sequences.pngc | 89 + include/images/server-sm.png | Bin 0 -> 598 bytes include/images/server-sm.pngc | 119 + include/images/server.png | Bin 0 -> 553 bytes include/images/server.pngc | 114 + include/images/serverbad-sm.png | Bin 0 -> 705 bytes include/images/serverbad-sm.pngc | 133 + include/images/serverbad.png | Bin 0 -> 643 bytes include/images/serverbad.pngc | 125 + include/images/servers.png | Bin 0 -> 504 bytes include/images/servers.pngc | 107 + include/images/setBreak.png | Bin 0 -> 299 bytes include/images/setBreak.pngc | 82 + include/images/slcluster.png | Bin 0 -> 628 bytes include/images/slcluster.pngc | 123 + include/images/slclusters.png | Bin 0 -> 673 bytes include/images/slclusters.pngc | 129 + include/images/sllisten.png | Bin 0 -> 393 bytes include/images/sllisten.pngc | 94 + include/images/sllistens.png | Bin 0 -> 409 bytes include/images/sllistens.pngc | 96 + include/images/slnode-disabled.png | Bin 0 -> 355 bytes include/images/slnode-disabled.pngc | 89 + include/images/slnode-local.png | Bin 0 -> 693 bytes include/images/slnode-local.pngc | 131 + include/images/slnode.png | Bin 0 -> 617 bytes include/images/slnode.pngc | 122 + include/images/slnodes.png | Bin 0 -> 490 bytes include/images/slnodes.pngc | 106 + include/images/slpath.png | Bin 0 -> 519 bytes include/images/slpath.pngc | 109 + include/images/slpaths.png | Bin 0 -> 518 bytes include/images/slpaths.pngc | 109 + include/images/slset.png | Bin 0 -> 625 bytes include/images/slset.pngc | 123 + include/images/slset2.png | Bin 0 -> 527 bytes include/images/slset2.pngc | 110 + include/images/slsets.png | Bin 0 -> 439 bytes include/images/slsets.pngc | 99 + include/images/slsubscription.png | Bin 0 -> 703 bytes include/images/slsubscription.pngc | 132 + include/images/slsubscription2.png | Bin 0 -> 639 bytes include/images/slsubscription2.pngc | 124 + include/images/slsubscriptions.png | Bin 0 -> 408 bytes include/images/slsubscriptions.pngc | 95 + include/images/sortfilter.png | Bin 0 -> 510 bytes include/images/sortfilter.pngc | 108 + include/images/splash.png | Bin 0 -> 100644 bytes include/images/splash.pngc | 12625 +++++ include/images/sql-16.png | Bin 0 -> 1030 bytes include/images/sql-16.pngc | 173 + include/images/sql-32.png | Bin 0 -> 1761 bytes include/images/sql-32.pngc | 265 + include/images/sql.ico | Bin 0 -> 82726 bytes include/images/sql.png | Bin 0 -> 24852 bytes include/images/sql.pngc | 3151 ++ include/images/statistics.png | Bin 0 -> 769 bytes include/images/statistics.pngc | 141 + include/images/step.png | Bin 0 -> 430 bytes include/images/step.pngc | 98 + include/images/stepInto.png | Bin 0 -> 253 bytes include/images/stepInto.pngc | 76 + include/images/stepOver.png | Bin 0 -> 249 bytes include/images/stepOver.pngc | 76 + include/images/steps.png | Bin 0 -> 505 bytes include/images/steps.pngc | 108 + include/images/stop.png | Bin 0 -> 498 bytes include/images/stop.pngc | 107 + include/images/storedata.png | Bin 0 -> 636 bytes include/images/storedata.pngc | 124 + include/images/synonym.png | Bin 0 -> 478 bytes include/images/synonym.pngc | 104 + include/images/synonyms.png | Bin 0 -> 448 bytes include/images/synonyms.pngc | 100 + include/images/table-repl-sm.png | Bin 0 -> 675 bytes include/images/table-repl-sm.pngc | 129 + include/images/table-repl.png | Bin 0 -> 839 bytes include/images/table-repl.pngc | 149 + include/images/table-sm.png | Bin 0 -> 526 bytes include/images/table-sm.pngc | 110 + include/images/table.png | Bin 0 -> 593 bytes include/images/table.pngc | 119 + include/images/tables.png | Bin 0 -> 555 bytes include/images/tables.pngc | 114 + include/images/tablespace.png | Bin 0 -> 378 bytes include/images/tablespace.pngc | 92 + include/images/tablespaces.png | Bin 0 -> 336 bytes include/images/tablespaces.pngc | 86 + include/images/template.png | Bin 0 -> 696 bytes include/images/template.pngc | 131 + include/images/templates.png | Bin 0 -> 601 bytes include/images/templates.pngc | 120 + include/images/terminate_backend.png | Bin 0 -> 368 bytes include/images/terminate_backend.pngc | 90 + include/images/textsearch.png | Bin 0 -> 788 bytes include/images/textsearch.pngc | 143 + include/images/trigger.png | Bin 0 -> 324 bytes include/images/trigger.pngc | 85 + include/images/triggerbad.png | Bin 0 -> 610 bytes include/images/triggerbad.pngc | 121 + include/images/triggerfunction.png | Bin 0 -> 334 bytes include/images/triggerfunction.pngc | 86 + include/images/triggerfunctions.png | Bin 0 -> 358 bytes include/images/triggerfunctions.pngc | 89 + include/images/triggers.png | Bin 0 -> 350 bytes include/images/triggers.pngc | 88 + include/images/type.png | Bin 0 -> 325 bytes include/images/type.pngc | 85 + include/images/types.png | Bin 0 -> 329 bytes include/images/types.pngc | 86 + include/images/uncheck.png | Bin 0 -> 617 bytes include/images/uncheck.pngc | 122 + include/images/unchecked.png | Bin 0 -> 267 bytes include/images/unchecked.pngc | 78 + include/images/unique.png | Bin 0 -> 422 bytes include/images/unique.pngc | 97 + include/images/up.png | Bin 0 -> 389 bytes include/images/up.pngc | 93 + include/images/user.png | Bin 0 -> 557 bytes include/images/user.pngc | 114 + include/images/usermapping-sm.png | Bin 0 -> 518 bytes include/images/usermapping-sm.pngc | 109 + include/images/usermapping.png | Bin 0 -> 518 bytes include/images/usermapping.pngc | 109 + include/images/usermappings.png | Bin 0 -> 557 bytes include/images/usermappings.pngc | 114 + include/images/users.png | Bin 0 -> 472 bytes include/images/users.pngc | 103 + include/images/vacuum.png | Bin 0 -> 969 bytes include/images/vacuum.pngc | 166 + include/images/variable.png | Bin 0 -> 311 bytes include/images/variable.pngc | 83 + include/images/variables.png | Bin 0 -> 350 bytes include/images/variables.pngc | 88 + include/images/view-sm.png | Bin 0 -> 395 bytes include/images/view-sm.pngc | 94 + include/images/view.png | Bin 0 -> 437 bytes include/images/view.pngc | 99 + include/images/viewdata.png | Bin 0 -> 1090 bytes include/images/viewdata.pngc | 181 + include/images/viewfiltereddata.png | Bin 0 -> 1162 bytes include/images/viewfiltereddata.pngc | 190 + include/images/views.png | Bin 0 -> 418 bytes include/images/views.pngc | 97 + include/libssh2/Win32/libssh2_config.h | 45 + include/libssh2/channel.h | 141 + include/libssh2/comp.h | 45 + include/libssh2/crypto.h | 142 + include/libssh2/libgcrypt.h | 181 + include/libssh2/libssh2.h | 1283 + include/libssh2/libssh2_config.h.in | 223 + include/libssh2/libssh2_priv.h | 1062 + include/libssh2/libssh2_publickey.h | 118 + include/libssh2/libssh2_sftp.h | 346 + include/libssh2/mac.h | 67 + include/libssh2/misc.h | 96 + include/libssh2/module.mk | 35 + include/libssh2/openssl.h | 222 + include/libssh2/packet.h | 76 + include/libssh2/session.h | 93 + include/libssh2/sftp.h | 235 + include/libssh2/transport.h | 87 + include/libssh2/userauth.h | 50 + include/module.mk | 40 + include/ogl/README | 3 + include/ogl/basic.h | 963 + include/ogl/basicp.h | 305 + include/ogl/bmpshape.h | 59 + include/ogl/canvas.h | 119 + include/ogl/composit.h | 294 + include/ogl/constrnt.h | 96 + include/ogl/divided.h | 72 + include/ogl/drawn.h | 280 + include/ogl/drawnp.h | 220 + include/ogl/lines.h | 403 + include/ogl/linesp.h | 86 + include/ogl/mfutils.h | 418 + include/ogl/misc.h | 109 + include/ogl/module.mk | 32 + include/ogl/ogl.h | 37 + include/ogl/ogldiag.h | 157 + include/parser/keywords.h | 44 + include/parser/module.mk | 16 + include/pgAdmin3.h | 266 + include/pgscript/FlexLexer.h | 223 + include/pgscript/exceptions/module.mk | 24 + .../exceptions/pgsArithmeticException.h | 35 + .../pgscript/exceptions/pgsAssertException.h | 34 + .../pgscript/exceptions/pgsBreakException.h | 30 + .../pgscript/exceptions/pgsCastException.h | 35 + .../exceptions/pgsContinueException.h | 30 + include/pgscript/exceptions/pgsException.h | 31 + .../exceptions/pgsInterruptException.h | 30 + .../exceptions/pgsParameterException.h | 34 + include/pgscript/expressions/module.mk | 54 + include/pgscript/expressions/pgsAnd.h | 38 + include/pgscript/expressions/pgsAssign.h | 43 + .../pgscript/expressions/pgsAssignToRecord.h | 44 + include/pgscript/expressions/pgsCast.h | 46 + include/pgscript/expressions/pgsColumns.h | 42 + include/pgscript/expressions/pgsDifferent.h | 38 + include/pgscript/expressions/pgsEqual.h | 43 + include/pgscript/expressions/pgsExecute.h | 50 + include/pgscript/expressions/pgsExpression.h | 48 + include/pgscript/expressions/pgsExpressions.h | 52 + include/pgscript/expressions/pgsGenDate.h | 48 + include/pgscript/expressions/pgsGenDateTime.h | 48 + .../pgscript/expressions/pgsGenDictionary.h | 49 + include/pgscript/expressions/pgsGenInt.h | 48 + include/pgscript/expressions/pgsGenReal.h | 50 + .../pgscript/expressions/pgsGenReference.h | 53 + include/pgscript/expressions/pgsGenRegex.h | 45 + include/pgscript/expressions/pgsGenString.h | 48 + include/pgscript/expressions/pgsGenTime.h | 48 + include/pgscript/expressions/pgsGreater.h | 38 + .../pgscript/expressions/pgsGreaterEqual.h | 38 + include/pgscript/expressions/pgsIdent.h | 46 + include/pgscript/expressions/pgsIdentRecord.h | 44 + include/pgscript/expressions/pgsLines.h | 42 + include/pgscript/expressions/pgsLower.h | 38 + include/pgscript/expressions/pgsLowerEqual.h | 38 + include/pgscript/expressions/pgsMinus.h | 38 + include/pgscript/expressions/pgsModulo.h | 38 + include/pgscript/expressions/pgsNegate.h | 38 + include/pgscript/expressions/pgsNot.h | 38 + include/pgscript/expressions/pgsOperation.h | 43 + include/pgscript/expressions/pgsOr.h | 38 + include/pgscript/expressions/pgsOver.h | 38 + include/pgscript/expressions/pgsParenthesis.h | 38 + include/pgscript/expressions/pgsPlus.h | 38 + include/pgscript/expressions/pgsRemoveLine.h | 43 + include/pgscript/expressions/pgsTimes.h | 38 + include/pgscript/expressions/pgsTrim.h | 42 + include/pgscript/generators/module.mk | 27 + include/pgscript/generators/pgsDateGen.h | 51 + include/pgscript/generators/pgsDateTimeGen.h | 51 + .../pgscript/generators/pgsDictionaryGen.h | 58 + include/pgscript/generators/pgsIntegerGen.h | 115 + include/pgscript/generators/pgsNumberGen.h | 41 + include/pgscript/generators/pgsObjectGen.h | 40 + include/pgscript/generators/pgsRealGen.h | 56 + include/pgscript/generators/pgsReferenceGen.h | 53 + include/pgscript/generators/pgsRegexGen.h | 102 + include/pgscript/generators/pgsStringGen.h | 54 + include/pgscript/generators/pgsTimeGen.h | 51 + include/pgscript/location.hh | 145 + include/pgscript/module.mk | 29 + include/pgscript/objects/module.mk | 22 + include/pgscript/objects/pgsGenerator.h | 94 + include/pgscript/objects/pgsNumber.h | 98 + include/pgscript/objects/pgsObjects.h | 20 + include/pgscript/objects/pgsRecord.h | 155 + include/pgscript/objects/pgsString.h | 85 + include/pgscript/objects/pgsVariable.h | 138 + include/pgscript/parser.tab.hh | 403 + include/pgscript/pgScript.h | 45 + include/pgscript/pgsApplication.h | 128 + include/pgscript/position.hh | 142 + include/pgscript/stack.hh | 152 + include/pgscript/statements/module.mk | 28 + include/pgscript/statements/pgsAssertStmt.h | 40 + include/pgscript/statements/pgsBreakStmt.h | 36 + include/pgscript/statements/pgsContinueStmt.h | 36 + .../statements/pgsDeclareRecordStmt.h | 42 + .../pgscript/statements/pgsExpressionStmt.h | 40 + include/pgscript/statements/pgsIfStmt.h | 43 + include/pgscript/statements/pgsPrintStmt.h | 43 + include/pgscript/statements/pgsProgram.h | 48 + include/pgscript/statements/pgsStatements.h | 26 + include/pgscript/statements/pgsStmt.h | 50 + include/pgscript/statements/pgsStmtList.h | 52 + include/pgscript/statements/pgsWhileStmt.h | 42 + .../pgscript/utilities/mapm-lib/license.txt | 13 + include/pgscript/utilities/mapm-lib/m_apm.h | 767 + .../pgscript/utilities/mapm-lib/m_apm_lc.h | 271 + include/pgscript/utilities/mapm-lib/module.mk | 18 + include/pgscript/utilities/module.mk | 26 + include/pgscript/utilities/pgsAlloc.h | 77 + include/pgscript/utilities/pgsContext.h | 119 + include/pgscript/utilities/pgsCopiedPtr.h | 80 + include/pgscript/utilities/pgsDriver.h | 98 + include/pgscript/utilities/pgsMapm.h | 36 + include/pgscript/utilities/pgsScanner.h | 87 + include/pgscript/utilities/pgsSharedPtr.h | 99 + include/pgscript/utilities/pgsThread.h | 92 + include/pgscript/utilities/pgsUtilities.h | 27 + include/postgres.h | 25 + include/precomp.h | 250 + include/schema/edbPackage.h | 189 + include/schema/edbPackageFunction.h | 166 + include/schema/edbPackageVariable.h | 78 + include/schema/edbPrivateSynonym.h | 101 + include/schema/edbResourceGroup.h | 71 + include/schema/edbSynonym.h | 102 + include/schema/gpExtTable.h | 91 + include/schema/gpPartition.h | 100 + include/schema/gpResQueue.h | 113 + include/schema/module.mk | 68 + include/schema/pgAggregate.h | 140 + include/schema/pgCast.h | 153 + include/schema/pgCatalogObject.h | 75 + include/schema/pgCheck.h | 142 + include/schema/pgCollation.h | 88 + include/schema/pgCollection.h | 105 + include/schema/pgColumn.h | 318 + include/schema/pgConstraints.h | 56 + include/schema/pgConversion.h | 113 + include/schema/pgDatabase.h | 360 + include/schema/pgDatatype.h | 113 + include/schema/pgDomain.h | 226 + include/schema/pgEventTrigger.h | 154 + include/schema/pgExtension.h | 94 + include/schema/pgForeignDataWrapper.h | 152 + include/schema/pgForeignKey.h | 225 + include/schema/pgForeignServer.h | 145 + include/schema/pgForeignTable.h | 105 + include/schema/pgFunction.h | 355 + include/schema/pgGroup.h | 105 + include/schema/pgIndex.h | 342 + include/schema/pgIndexConstraint.h | 113 + include/schema/pgLanguage.h | 101 + include/schema/pgObject.h | 393 + include/schema/pgOperator.h | 218 + include/schema/pgOperatorClass.h | 140 + include/schema/pgOperatorFamily.h | 91 + include/schema/pgPartition.h | 100 + include/schema/pgRole.h | 241 + include/schema/pgRule.h | 183 + include/schema/pgSchema.h | 286 + include/schema/pgSequence.h | 112 + include/schema/pgServer.h | 709 + include/schema/pgTable.h | 729 + include/schema/pgTablespace.h | 99 + include/schema/pgTextSearchConfiguration.h | 109 + include/schema/pgTextSearchDictionary.h | 91 + include/schema/pgTextSearchParser.h | 115 + include/schema/pgTextSearchTemplate.h | 91 + include/schema/pgTrigger.h | 280 + include/schema/pgType.h | 347 + include/schema/pgUser.h | 135 + include/schema/pgUserMapping.h | 99 + include/schema/pgView.h | 401 + include/slony/dlgRepCluster.h | 105 + include/slony/dlgRepListen.h | 45 + include/slony/dlgRepNode.h | 43 + include/slony/dlgRepPath.h | 45 + include/slony/dlgRepProperty.h | 30 + include/slony/dlgRepSequence.h | 47 + include/slony/dlgRepSet.h | 100 + include/slony/dlgRepSubscription.h | 44 + include/slony/dlgRepTable.h | 51 + include/slony/module.mk | 33 + include/slony/slCluster.h | 226 + include/slony/slListen.h | 80 + include/slony/slNode.h | 155 + include/slony/slPath.h | 75 + include/slony/slSequence.h | 63 + include/slony/slSet.h | 189 + include/slony/slSubscription.h | 132 + include/slony/slTable.h | 76 + include/utils/csvfiles.h | 53 + include/utils/factory.h | 237 + include/utils/favourites.h | 95 + include/utils/macros.h | 86 + include/utils/misc.h | 276 + include/utils/module.mk | 34 + include/utils/pgDefs.h | 80 + include/utils/pgconfig.h | 241 + include/utils/pgfeatures.h | 31 + include/utils/registry.h | 89 + include/utils/sshTunnel.h | 119 + include/utils/sysLogger.h | 77 + include/utils/sysProcess.h | 42 + include/utils/sysSettings.h | 857 + include/utils/utffile.h | 62 + include/version.h | 44 + libssh2/agent.c | 810 + libssh2/channel.c | 2621 + libssh2/comp.c | 366 + libssh2/crypt.c | 336 + libssh2/global.c | 78 + libssh2/hostkey.c | 566 + libssh2/keepalive.c | 99 + libssh2/kex.c | 2794 ++ libssh2/knownhost.c | 1245 + libssh2/libgcrypt.c | 624 + libssh2/mac.c | 414 + libssh2/misc.c | 654 + libssh2/module.mk | 40 + libssh2/openssl.c | 963 + libssh2/packet.c | 1267 + libssh2/pem.c | 324 + libssh2/publickey.c | 1059 + libssh2/scp.c | 1126 + libssh2/session.c | 1791 + libssh2/sftp.c | 3425 ++ libssh2/transport.c | 891 + libssh2/userauth.c | 1914 + libssh2/version.c | 54 + ogl/README | 3 + ogl/basic.cpp | 3217 ++ ogl/basic2.cpp | 1880 + ogl/bmpshape.cpp | 95 + ogl/canvas.cpp | 574 + ogl/composit.cpp | 1757 + ogl/constrnt.cpp | 606 + ogl/divided.cpp | 714 + ogl/drawn.cpp | 2498 + ogl/lines.cpp | 2498 + ogl/mfutils.cpp | 1087 + ogl/module.mk | 30 + ogl/ogldiag.cpp | 736 + ogl/oglmisc.cpp | 911 + pgscript/README | 10 + pgscript/exceptions/module.mk | 24 + .../exceptions/pgsArithmeticException.cpp | 30 + pgscript/exceptions/pgsAssertException.cpp | 28 + pgscript/exceptions/pgsBreakException.cpp | 28 + pgscript/exceptions/pgsCastException.cpp | 30 + pgscript/exceptions/pgsContinueException.cpp | 28 + pgscript/exceptions/pgsException.cpp | 22 + pgscript/exceptions/pgsInterruptException.cpp | 28 + pgscript/exceptions/pgsParameterException.cpp | 35 + pgscript/expressions/module.mk | 53 + pgscript/expressions/pgsAnd.cpp | 57 + pgscript/expressions/pgsAssign.cpp | 59 + pgscript/expressions/pgsAssignToRecord.cpp | 138 + pgscript/expressions/pgsCast.cpp | 100 + pgscript/expressions/pgsColumns.cpp | 58 + pgscript/expressions/pgsDifferent.cpp | 60 + pgscript/expressions/pgsEqual.cpp | 65 + pgscript/expressions/pgsExecute.cpp | 230 + pgscript/expressions/pgsExpression.cpp | 23 + pgscript/expressions/pgsGenDate.cpp | 123 + pgscript/expressions/pgsGenDateTime.cpp | 123 + pgscript/expressions/pgsGenDictionary.cpp | 126 + pgscript/expressions/pgsGenInt.cpp | 114 + pgscript/expressions/pgsGenReal.cpp | 128 + pgscript/expressions/pgsGenReference.cpp | 131 + pgscript/expressions/pgsGenRegex.cpp | 98 + pgscript/expressions/pgsGenString.cpp | 115 + pgscript/expressions/pgsGenTime.cpp | 123 + pgscript/expressions/pgsGreater.cpp | 60 + pgscript/expressions/pgsGreaterEqual.cpp | 60 + pgscript/expressions/pgsIdent.cpp | 56 + pgscript/expressions/pgsIdentRecord.cpp | 103 + pgscript/expressions/pgsLines.cpp | 58 + pgscript/expressions/pgsLower.cpp | 60 + pgscript/expressions/pgsLowerEqual.cpp | 61 + pgscript/expressions/pgsMinus.cpp | 60 + pgscript/expressions/pgsModulo.cpp | 60 + pgscript/expressions/pgsNegate.cpp | 60 + pgscript/expressions/pgsNot.cpp | 59 + pgscript/expressions/pgsOperation.cpp | 46 + pgscript/expressions/pgsOr.cpp | 56 + pgscript/expressions/pgsOver.cpp | 60 + pgscript/expressions/pgsParenthesis.cpp | 59 + pgscript/expressions/pgsPlus.cpp | 60 + pgscript/expressions/pgsRemoveLine.cpp | 89 + pgscript/expressions/pgsTimes.cpp | 60 + pgscript/expressions/pgsTrim.cpp | 57 + pgscript/generators/module.mk | 27 + pgscript/generators/pgsDateGen.cpp | 47 + pgscript/generators/pgsDateTimeGen.cpp | 62 + pgscript/generators/pgsDictionaryGen.cpp | 99 + pgscript/generators/pgsIntegerGen.cpp | 174 + pgscript/generators/pgsNumberGen.cpp | 23 + pgscript/generators/pgsObjectGen.cpp | 23 + pgscript/generators/pgsRealGen.cpp | 48 + pgscript/generators/pgsReferenceGen.cpp | 76 + pgscript/generators/pgsRegexGen.cpp | 309 + pgscript/generators/pgsStringGen.cpp | 83 + pgscript/generators/pgsTimeGen.cpp | 52 + pgscript/lex.pgs.cc | 2696 ++ pgscript/module.mk | 29 + pgscript/objects/module.mk | 21 + pgscript/objects/pgsGenerator.cpp | 154 + pgscript/objects/pgsNumber.cpp | 286 + pgscript/objects/pgsRecord.cpp | 509 + pgscript/objects/pgsString.cpp | 290 + pgscript/objects/pgsVariable.cpp | 128 + pgscript/parser.sh | 80 + pgscript/parser.tab.cc | 2703 ++ pgscript/pgsApplication.cpp | 215 + pgscript/pgsParser.yy | 1045 + pgscript/pgsScanner.ll | 421 + pgscript/statements/module.mk | 27 + pgscript/statements/pgsAssertStmt.cpp | 34 + pgscript/statements/pgsBreakStmt.cpp | 30 + pgscript/statements/pgsContinueStmt.cpp | 30 + pgscript/statements/pgsDeclareRecordStmt.cpp | 36 + pgscript/statements/pgsExpressionStmt.cpp | 28 + pgscript/statements/pgsIfStmt.cpp | 39 + pgscript/statements/pgsPrintStmt.cpp | 56 + pgscript/statements/pgsProgram.cpp | 63 + pgscript/statements/pgsStmt.cpp | 33 + pgscript/statements/pgsStmtList.cpp | 115 + pgscript/statements/pgsWhileStmt.cpp | 56 + pgscript/utilities/m_apm/mapm5sin.cpp | 154 + pgscript/utilities/m_apm/mapm_add.cpp | 329 + pgscript/utilities/m_apm/mapm_cpi.cpp | 161 + pgscript/utilities/m_apm/mapm_div.cpp | 300 + pgscript/utilities/m_apm/mapm_exp.cpp | 294 + pgscript/utilities/m_apm/mapm_fam.cpp | 55 + pgscript/utilities/m_apm/mapm_fft.cpp | 953 + pgscript/utilities/m_apm/mapm_flr.cpp | 120 + pgscript/utilities/m_apm/mapm_fpf.cpp | 415 + pgscript/utilities/m_apm/mapm_gcd.cpp | 260 + pgscript/utilities/m_apm/mapm_lg2.cpp | 152 + pgscript/utilities/m_apm/mapm_lg3.cpp | 204 + pgscript/utilities/m_apm/mapm_lg4.cpp | 93 + pgscript/utilities/m_apm/mapm_log.cpp | 138 + pgscript/utilities/m_apm/mapm_mul.cpp | 131 + pgscript/utilities/m_apm/mapm_pow.cpp | 147 + pgscript/utilities/m_apm/mapm_rcp.cpp | 168 + pgscript/utilities/m_apm/mapm_rnd.cpp | 360 + pgscript/utilities/m_apm/mapm_set.cpp | 357 + pgscript/utilities/m_apm/mapm_sin.cpp | 140 + pgscript/utilities/m_apm/mapmasin.cpp | 430 + pgscript/utilities/m_apm/mapmasn0.cpp | 157 + pgscript/utilities/m_apm/mapmcbrt.cpp | 129 + pgscript/utilities/m_apm/mapmcnst.cpp | 291 + pgscript/utilities/m_apm/mapmfact.cpp | 244 + pgscript/utilities/m_apm/mapmfmul.cpp | 685 + pgscript/utilities/m_apm/mapmgues.cpp | 147 + pgscript/utilities/m_apm/mapmhasn.cpp | 132 + pgscript/utilities/m_apm/mapmhsin.cpp | 100 + pgscript/utilities/m_apm/mapmipwr.cpp | 98 + pgscript/utilities/m_apm/mapmistr.cpp | 112 + pgscript/utilities/m_apm/mapmpwr2.cpp | 107 + pgscript/utilities/m_apm/mapmrsin.cpp | 164 + pgscript/utilities/m_apm/mapmsqrt.cpp | 130 + pgscript/utilities/m_apm/mapmstck.cpp | 108 + pgscript/utilities/m_apm/mapmutil.cpp | 475 + pgscript/utilities/m_apm/mapmutl1.cpp | 47 + pgscript/utilities/m_apm/mapmutl2.cpp | 329 + pgscript/utilities/m_apm/module.mk | 54 + pgscript/utilities/module.mk | 23 + pgscript/utilities/pgsAlloc.cpp | 123 + pgscript/utilities/pgsContext.cpp | 134 + pgscript/utilities/pgsDriver.cpp | 81 + pgscript/utilities/pgsMapm.cpp | 76 + pgscript/utilities/pgsThread.cpp | 94 + pgscript/utilities/pgsUtilities.cpp | 33 + schema/edbPackage.cpp | 355 + schema/edbPackageFunction.cpp | 562 + schema/edbPackageVariable.cpp | 227 + schema/edbPrivateSynonym.cpp | 227 + schema/edbResourceGroup.cpp | 205 + schema/edbSynonym.cpp | 239 + schema/gpExtTable.cpp | 575 + schema/gpPartition.cpp | 238 + schema/gpResQueue.cpp | 302 + schema/module.mk | 68 + schema/pgAggregate.cpp | 410 + schema/pgCast.cpp | 268 + schema/pgCatalogObject.cpp | 208 + schema/pgCheck.cpp | 333 + schema/pgCollation.cpp | 249 + schema/pgCollection.cpp | 147 + schema/pgColumn.cpp | 791 + schema/pgConstraints.cpp | 129 + schema/pgConversion.cpp | 245 + schema/pgDatabase.cpp | 1350 + schema/pgDatatype.cpp | 320 + schema/pgDomain.cpp | 425 + schema/pgEventTrigger.cpp | 350 + schema/pgExtension.cpp | 234 + schema/pgForeignDataWrapper.cpp | 408 + schema/pgForeignKey.cpp | 433 + schema/pgForeignServer.cpp | 351 + schema/pgForeignTable.cpp | 415 + schema/pgFunction.cpp | 1332 + schema/pgGroup.cpp | 233 + schema/pgIndex.cpp | 756 + schema/pgIndexConstraint.cpp | 504 + schema/pgLanguage.cpp | 280 + schema/pgObject.cpp | 2158 + schema/pgOperator.cpp | 379 + schema/pgOperatorClass.cpp | 426 + schema/pgOperatorFamily.cpp | 237 + schema/pgPartition.cpp | 321 + schema/pgRole.cpp | 820 + schema/pgRule.cpp | 356 + schema/pgSchema.cpp | 815 + schema/pgSequence.cpp | 369 + schema/pgServer.cpp | 2271 + schema/pgTable.cpp | 1956 + schema/pgTablespace.cpp | 467 + schema/pgTextSearchConfiguration.cpp | 277 + schema/pgTextSearchDictionary.cpp | 241 + schema/pgTextSearchParser.cpp | 253 + schema/pgTextSearchTemplate.cpp | 242 + schema/pgTrigger.cpp | 637 + schema/pgType.cpp | 572 + schema/pgUser.cpp | 387 + schema/pgUserMapping.cpp | 269 + schema/pgView.cpp | 967 + slony/dlgRepCluster.cpp | 1628 + slony/dlgRepListen.cpp | 159 + slony/dlgRepNode.cpp | 122 + slony/dlgRepPath.cpp | 154 + slony/dlgRepProperty.cpp | 25 + slony/dlgRepSequence.cpp | 166 + slony/dlgRepSet.cpp | 332 + slony/dlgRepSubscription.cpp | 182 + slony/dlgRepTable.cpp | 317 + slony/module.mk | 34 + slony/slCluster.cpp | 613 + slony/slListen.cpp | 244 + slony/slNode.cpp | 499 + slony/slPath.cpp | 236 + slony/slSequence.cpp | 230 + slony/slSet.cpp | 565 + slony/slSubscription.cpp | 294 + slony/slTable.cpp | 277 + ui/_xrcDialogs.cpp | 39917 +++++++++++++++ ui/ddPrecisionScaleDialog.xrc | 97 + ui/ddTableNameDialog.xrc | 84 + ui/dlgAddFavourite.xrc | 84 + ui/dlgAggregate.xrc | 288 + ui/dlgCast.xrc | 197 + ui/dlgCheck.xrc | 170 + ui/dlgCollation.xrc | 222 + ui/dlgColumn.xrc | 319 + ui/dlgConnect.xrc | 74 + ui/dlgConversion.xrc | 227 + ui/dlgDatabase.xrc | 368 + ui/dlgDirectDbg.xrc | 86 + ui/dlgDomain.xrc | 302 + ui/dlgEditGridOptions.xrc | 157 + ui/dlgEventTrigger.xrc | 229 + ui/dlgExtTable.xrc | 160 + ui/dlgExtension.xrc | 170 + ui/dlgFindReplace.xrc | 204 + ui/dlgForeignDataWrapper.xrc | 278 + ui/dlgForeignKey.xrc | 346 + ui/dlgForeignServer.xrc | 274 + ui/dlgForeignTable.xrc | 398 + ui/dlgFunction.xrc | 633 + ui/dlgGroup.xrc | 184 + ui/dlgHbaConfig.xrc | 156 + ui/dlgIndex.xrc | 377 + ui/dlgIndexConstraint.xrc | 379 + ui/dlgJob.xrc | 326 + ui/dlgLanguage.xrc | 215 + ui/dlgMainConfig.xrc | 139 + ui/dlgManageFavourites.xrc | 83 + ui/dlgManageMacros.xrc | 133 + ui/dlgMoveTablespace.xrc | 95 + ui/dlgOperator.xrc | 370 + ui/dlgPackage.xrc | 180 + ui/dlgPgpassConfig.xrc | 145 + ui/dlgReassignDropOwned.xrc | 90 + ui/dlgRepCluster.xrc | 235 + ui/dlgRepClusterUpgrade.xrc | 135 + ui/dlgRepListen.xrc | 107 + ui/dlgRepNode.xrc | 92 + ui/dlgRepPath.xrc | 105 + ui/dlgRepSequence.xrc | 107 + ui/dlgRepSet.xrc | 114 + ui/dlgRepSetMerge.xrc | 92 + ui/dlgRepSetMove.xrc | 92 + ui/dlgRepSubscription.xrc | 121 + ui/dlgRepTable.xrc | 143 + ui/dlgResourceGroup.xrc | 106 + ui/dlgRole.xrc | 479 + ui/dlgRule.xrc | 209 + ui/dlgSchedule.xrc | 460 + ui/dlgSchema.xrc | 142 + ui/dlgSearchObject.xrc | 214 + ui/dlgSelectConnection.xrc | 40 + ui/dlgSequence.xrc | 249 + ui/dlgServer.xrc | 538 + ui/dlgStep.xrc | 262 + ui/dlgSynonym.xrc | 185 + ui/dlgTable.xrc | 892 + ui/dlgTablespace.xrc | 256 + ui/dlgTextSearchConfiguration.xrc | 310 + ui/dlgTextSearchDictionary.xrc | 277 + ui/dlgTextSearchParser.xrc | 263 + ui/dlgTextSearchTemplate.xrc | 214 + ui/dlgTrigger.xrc | 394 + ui/dlgType.xrc | 832 + ui/dlgUser.xrc | 371 + ui/dlgUserMapping.xrc | 207 + ui/dlgView.xrc | 728 + ui/embed-xrc | 24 + ui/embed-xrc.bat | 13 + ui/frmBackup.xrc | 412 + ui/frmBackupGlobals.xrc | 105 + ui/frmBackupServer.xrc | 105 + ui/frmExport.xrc | 131 + ui/frmGrantWizard.xrc | 46 + ui/frmHint.xrc | 90 + ui/frmImport.xrc | 301 + ui/frmMaintenance.xrc | 128 + ui/frmOptions.xrc | 1344 + ui/frmPassword.xrc | 47 + ui/frmReport.xrc | 149 + ui/frmRestore.xrc | 364 + ui/module.mk | 104 + ui/xrcDialogs.cpp | 39966 ++++++++++++++++ utils/csvfiles.cpp | 142 + utils/factory.cpp | 428 + utils/favourites.cpp | 359 + utils/macros.cpp | 349 + utils/misc.cpp | 1407 + utils/module.mk | 34 + utils/pgconfig.cpp | 624 + utils/registry.cpp | 377 + utils/sshTunnel.cpp | 628 + utils/sysLogger.cpp | 312 + utils/sysProcess.cpp | 112 + utils/sysSettings.cpp | 935 + utils/tab-complete.inc | 1741 + utils/tabcomplete.c | 415 + utils/tabcomplete.pl | 55 + utils/utffile.cpp | 337 + 1765 files changed, 407959 insertions(+) create mode 100644 .gitignore create mode 100644 Debug/Win32/libssh2/vc100.idb create mode 100644 Debug/pgAdmin3.Build.CppClean.log create mode 100644 Debug/pgAdmin3.lastbuildstate create mode 100644 Debug/pgAdmin3.log create mode 100644 Debug/pgAdmin3.unsuccessfulbuild create mode 100644 Debug/vc100.idb create mode 100644 Debug/vc100.pdb create mode 100644 Release/pgAdmin3.exe create mode 100644 agent/dlgJob.cpp create mode 100644 agent/dlgSchedule.cpp create mode 100644 agent/dlgStep.cpp create mode 100644 agent/module.mk create mode 100644 agent/pgaJob.cpp create mode 100644 agent/pgaSchedule.cpp create mode 100644 agent/pgaStep.cpp create mode 100644 ctl/calbox.cpp create mode 100644 ctl/ctlAuiNotebook.cpp create mode 100644 ctl/ctlCheckTreeView.cpp create mode 100644 ctl/ctlColourPicker.cpp create mode 100644 ctl/ctlComboBox.cpp create mode 100644 ctl/ctlDefaultSecurityPanel.cpp create mode 100644 ctl/ctlListView.cpp create mode 100644 ctl/ctlMenuToolbar.cpp create mode 100644 ctl/ctlProgressStatusBar.cpp create mode 100644 ctl/ctlSQLBox.cpp create mode 100644 ctl/ctlSQLGrid.cpp create mode 100644 ctl/ctlSQLResult.cpp create mode 100644 ctl/ctlSeclabelPanel.cpp create mode 100644 ctl/ctlSecurityPanel.cpp create mode 100644 ctl/ctlTree.cpp create mode 100644 ctl/explainCanvas.cpp create mode 100644 ctl/explainShape.cpp create mode 100644 ctl/module.mk create mode 100644 ctl/timespin.cpp create mode 100644 ctl/xh_calb.cpp create mode 100644 ctl/xh_ctlchecktreeview.cpp create mode 100644 ctl/xh_ctlcolourpicker.cpp create mode 100644 ctl/xh_ctlcombo.cpp create mode 100644 ctl/xh_ctltree.cpp create mode 100644 ctl/xh_sqlbox.cpp create mode 100644 ctl/xh_timespin.cpp create mode 100644 db/keywords.c create mode 100644 db/module.mk create mode 100644 db/pgConn.cpp create mode 100644 db/pgQueryThread.cpp create mode 100644 db/pgSet.cpp create mode 100644 dd/dditems/figures/ddColumnFigure.cpp create mode 100644 dd/dditems/figures/ddColumnKindIcon.cpp create mode 100644 dd/dditems/figures/ddColumnOptionIcon.cpp create mode 100644 dd/dditems/figures/ddRelationshipFigure.cpp create mode 100644 dd/dditems/figures/ddRelationshipItem.cpp create mode 100644 dd/dditems/figures/ddRelationshipTerminal.cpp create mode 100644 dd/dditems/figures/ddTableFigure.cpp create mode 100644 dd/dditems/figures/ddTextTableItemFigure.cpp create mode 100644 dd/dditems/figures/module.mk create mode 100644 dd/dditems/figures/xml/ddXmlStorage.cpp create mode 100644 dd/dditems/figures/xml/module.mk create mode 100644 dd/dditems/handles/ddAddColButtonHandle.cpp create mode 100644 dd/dditems/handles/ddAddFkButtonHandle.cpp create mode 100644 dd/dditems/handles/ddMinMaxTableButtonHandle.cpp create mode 100644 dd/dditems/handles/ddRemoveTableButtonHandle.cpp create mode 100644 dd/dditems/handles/ddScrollBarHandle.cpp create mode 100644 dd/dditems/handles/ddSouthTableSizeHandle.cpp create mode 100644 dd/dditems/handles/module.mk create mode 100644 dd/dditems/locators/ddAddColLocator.cpp create mode 100644 dd/dditems/locators/ddAddFkLocator.cpp create mode 100644 dd/dditems/locators/ddMinMaxTableLocator.cpp create mode 100644 dd/dditems/locators/ddRemoveTableLocator.cpp create mode 100644 dd/dditems/locators/ddScrollBarTableLocator.cpp create mode 100644 dd/dditems/locators/ddTableBottomLocator.cpp create mode 100644 dd/dditems/locators/module.mk create mode 100644 dd/dditems/module.mk create mode 100644 dd/dditems/tools/ddColumnFigureTool.cpp create mode 100644 dd/dditems/tools/ddColumnTextTool.cpp create mode 100644 dd/dditems/tools/module.mk create mode 100644 dd/dditems/utilities/ddPrecisionScaleDialog.cpp create mode 100644 dd/dditems/utilities/ddSelectKindFksDialog.cpp create mode 100644 dd/dditems/utilities/ddTableNameDialog.cpp create mode 100644 dd/dditems/utilities/module.mk create mode 100644 dd/ddmodel/ddBrowserDataContainer.cpp create mode 100644 dd/ddmodel/ddDBReverseEnginering.cpp create mode 100644 dd/ddmodel/ddDatabaseDesign.cpp create mode 100644 dd/ddmodel/ddDrawingEditor.cpp create mode 100644 dd/ddmodel/ddDrawingView.cpp create mode 100644 dd/ddmodel/ddGenerationWizard.cpp create mode 100644 dd/ddmodel/ddModelBrowser.cpp create mode 100644 dd/ddmodel/module.mk create mode 100644 dd/module.mk create mode 100644 debugger/ctlMessageWindow.cpp create mode 100644 debugger/ctlResultGrid.cpp create mode 100644 debugger/ctlStackWindow.cpp create mode 100644 debugger/ctlTabWindow.cpp create mode 100644 debugger/ctlVarWindow.cpp create mode 100644 debugger/dbgBreakPoint.cpp create mode 100644 debugger/dbgController.cpp create mode 100644 debugger/dbgEvents.cpp create mode 100644 debugger/dbgModel.cpp create mode 100644 debugger/dbgTargetInfo.cpp create mode 100644 debugger/debugger.cpp create mode 100644 debugger/dlgDirectDbg.cpp create mode 100644 debugger/frmDebugger.cpp create mode 100644 debugger/module.mk create mode 100644 dlg/dlgAddFavourite.cpp create mode 100644 dlg/dlgAggregate.cpp create mode 100644 dlg/dlgCast.cpp create mode 100644 dlg/dlgCheck.cpp create mode 100644 dlg/dlgClasses.cpp create mode 100644 dlg/dlgCollation.cpp create mode 100644 dlg/dlgColumn.cpp create mode 100644 dlg/dlgConnect.cpp create mode 100644 dlg/dlgConversion.cpp create mode 100644 dlg/dlgDatabase.cpp create mode 100644 dlg/dlgDomain.cpp create mode 100644 dlg/dlgEditGridOptions.cpp create mode 100644 dlg/dlgEventTrigger.cpp create mode 100644 dlg/dlgExtTable.cpp create mode 100644 dlg/dlgExtension.cpp create mode 100644 dlg/dlgFindReplace.cpp create mode 100644 dlg/dlgForeignDataWrapper.cpp create mode 100644 dlg/dlgForeignKey.cpp create mode 100644 dlg/dlgForeignServer.cpp create mode 100644 dlg/dlgForeignTable.cpp create mode 100644 dlg/dlgFunction.cpp create mode 100644 dlg/dlgGroup.cpp create mode 100644 dlg/dlgHbaConfig.cpp create mode 100644 dlg/dlgIndex.cpp create mode 100644 dlg/dlgIndexConstraint.cpp create mode 100644 dlg/dlgLanguage.cpp create mode 100644 dlg/dlgMainConfig.cpp create mode 100644 dlg/dlgManageFavourites.cpp create mode 100644 dlg/dlgManageMacros.cpp create mode 100644 dlg/dlgMoveTablespace.cpp create mode 100644 dlg/dlgOperator.cpp create mode 100644 dlg/dlgPackage.cpp create mode 100644 dlg/dlgPgpassConfig.cpp create mode 100644 dlg/dlgProperty.cpp create mode 100644 dlg/dlgReassignDropOwned.cpp create mode 100644 dlg/dlgResourceGroup.cpp create mode 100644 dlg/dlgRole.cpp create mode 100644 dlg/dlgRule.cpp create mode 100644 dlg/dlgSchema.cpp create mode 100644 dlg/dlgSearchObject.cpp create mode 100644 dlg/dlgSelectConnection.cpp create mode 100644 dlg/dlgSelectDatabase.cpp create mode 100644 dlg/dlgSequence.cpp create mode 100644 dlg/dlgServer.cpp create mode 100644 dlg/dlgSynonym.cpp create mode 100644 dlg/dlgTable.cpp create mode 100644 dlg/dlgTablespace.cpp create mode 100644 dlg/dlgTextSearchConfiguration.cpp create mode 100644 dlg/dlgTextSearchDictionary.cpp create mode 100644 dlg/dlgTextSearchParser.cpp create mode 100644 dlg/dlgTextSearchTemplate.cpp create mode 100644 dlg/dlgTrigger.cpp create mode 100644 dlg/dlgType.cpp create mode 100644 dlg/dlgUser.cpp create mode 100644 dlg/dlgUserMapping.cpp create mode 100644 dlg/dlgView.cpp create mode 100644 dlg/module.mk create mode 100644 frm/events.cpp create mode 100644 frm/frmAbout.cpp create mode 100644 frm/frmBackup.cpp create mode 100644 frm/frmBackupGlobals.cpp create mode 100644 frm/frmBackupServer.cpp create mode 100644 frm/frmConfig.cpp create mode 100644 frm/frmDatabaseDesigner.cpp create mode 100644 frm/frmEditGrid.cpp create mode 100644 frm/frmExport.cpp create mode 100644 frm/frmGrantWizard.cpp create mode 100644 frm/frmHbaConfig.cpp create mode 100644 frm/frmHint.cpp create mode 100644 frm/frmImport.cpp create mode 100644 frm/frmMain.cpp create mode 100644 frm/frmMainConfig.cpp create mode 100644 frm/frmMaintenance.cpp create mode 100644 frm/frmOptions.cpp create mode 100644 frm/frmPassword.cpp create mode 100644 frm/frmPgpassConfig.cpp create mode 100644 frm/frmQuery.cpp create mode 100644 frm/frmReport.cpp create mode 100644 frm/frmRestore.cpp create mode 100644 frm/frmSplash.cpp create mode 100644 frm/frmStatus.cpp create mode 100644 frm/module.mk create mode 100644 frm/plugins.cpp create mode 100644 gqb/gqbArrayCollection.cpp create mode 100644 gqb/gqbBrowser.cpp create mode 100644 gqb/gqbCollection.cpp create mode 100644 gqb/gqbColumn.cpp create mode 100644 gqb/gqbController.cpp create mode 100644 gqb/gqbDatabase.cpp create mode 100644 gqb/gqbGraphSimple.cpp create mode 100644 gqb/gqbGridJoinTable.cpp create mode 100644 gqb/gqbGridOrderTable.cpp create mode 100644 gqb/gqbGridProjTable.cpp create mode 100644 gqb/gqbGridRestTable.cpp create mode 100644 gqb/gqbModel.cpp create mode 100644 gqb/gqbObject.cpp create mode 100644 gqb/gqbObjectCollection.cpp create mode 100644 gqb/gqbQueryObjs.cpp create mode 100644 gqb/gqbSchema.cpp create mode 100644 gqb/gqbTable.cpp create mode 100644 gqb/gqbView.cpp create mode 100644 gqb/gqbViewPanels.cpp create mode 100644 gqb/module.mk create mode 100644 hotdraw/connectors/hdChopBoxConnector.cpp create mode 100644 hotdraw/connectors/hdIConnector.cpp create mode 100644 hotdraw/connectors/hdLocatorConnector.cpp create mode 100644 hotdraw/connectors/hdStickyRectangleConnector.cpp create mode 100644 hotdraw/connectors/module.mk create mode 100644 hotdraw/figures/defaultAttributes/hdFillAttribute.cpp create mode 100644 hotdraw/figures/defaultAttributes/hdFontAttribute.cpp create mode 100644 hotdraw/figures/defaultAttributes/hdFontColorAttribute.cpp create mode 100644 hotdraw/figures/defaultAttributes/hdLineAttribute.cpp create mode 100644 hotdraw/figures/defaultAttributes/module.mk create mode 100644 hotdraw/figures/hdAbstractFigure.cpp create mode 100644 hotdraw/figures/hdAbstractMenuFigure.cpp create mode 100644 hotdraw/figures/hdAttribute.cpp create mode 100644 hotdraw/figures/hdAttributeFigure.cpp create mode 100644 hotdraw/figures/hdBitmapFigure.cpp create mode 100644 hotdraw/figures/hdCompositeFigure.cpp create mode 100644 hotdraw/figures/hdIConnectionFigure.cpp create mode 100644 hotdraw/figures/hdIFigure.cpp create mode 100644 hotdraw/figures/hdLineConnection.cpp create mode 100644 hotdraw/figures/hdLineTerminal.cpp create mode 100644 hotdraw/figures/hdPolyLineFigure.cpp create mode 100644 hotdraw/figures/hdRectangleFigure.cpp create mode 100644 hotdraw/figures/hdSimpleTextFigure.cpp create mode 100644 hotdraw/figures/module.mk create mode 100644 hotdraw/figures/xml/hdStorage.cpp create mode 100644 hotdraw/figures/xml/module.mk create mode 100644 hotdraw/handles/hdButtonHandle.cpp create mode 100644 hotdraw/handles/hdChangeConnectionEndHandle.cpp create mode 100644 hotdraw/handles/hdChangeConnectionHandle.cpp create mode 100644 hotdraw/handles/hdChangeConnectionStartHandle.cpp create mode 100644 hotdraw/handles/hdIHandle.cpp create mode 100644 hotdraw/handles/hdLineConnectionHandle.cpp create mode 100644 hotdraw/handles/hdLocatorHandle.cpp create mode 100644 hotdraw/handles/hdPolyLineHandle.cpp create mode 100644 hotdraw/handles/module.mk create mode 100644 hotdraw/locators/hdILocator.cpp create mode 100644 hotdraw/locators/hdPolyLineLocator.cpp create mode 100644 hotdraw/locators/module.mk create mode 100644 hotdraw/main/hdDrawing.cpp create mode 100644 hotdraw/main/hdDrawingEditor.cpp create mode 100644 hotdraw/main/hdDrawingView.cpp create mode 100644 hotdraw/main/module.mk create mode 100644 hotdraw/module.mk create mode 100644 hotdraw/tools/hdAbstractTool.cpp create mode 100644 hotdraw/tools/hdCanvasMenuTool.cpp create mode 100644 hotdraw/tools/hdCompositeFigureTool.cpp create mode 100644 hotdraw/tools/hdConnectionCreationTool.cpp create mode 100644 hotdraw/tools/hdCreationTool.cpp create mode 100644 hotdraw/tools/hdDragCreationTool.cpp create mode 100644 hotdraw/tools/hdDragTrackerTool.cpp create mode 100644 hotdraw/tools/hdFigureTool.cpp create mode 100644 hotdraw/tools/hdHandleTrackerTool.cpp create mode 100644 hotdraw/tools/hdITool.cpp create mode 100644 hotdraw/tools/hdMenuTool.cpp create mode 100644 hotdraw/tools/hdPolyLineFigureTool.cpp create mode 100644 hotdraw/tools/hdSelectAreaTool.cpp create mode 100644 hotdraw/tools/hdSelectionTool.cpp create mode 100644 hotdraw/tools/hdSimpleTextTool.cpp create mode 100644 hotdraw/tools/module.mk create mode 100644 hotdraw/utilities/hdArrayCollection.cpp create mode 100644 hotdraw/utilities/hdCollection.cpp create mode 100644 hotdraw/utilities/hdGeometry.cpp create mode 100644 hotdraw/utilities/hdKeyEvent.cpp create mode 100644 hotdraw/utilities/hdMouseEvent.cpp create mode 100644 hotdraw/utilities/hdMultiPosRect.cpp create mode 100644 hotdraw/utilities/hdPoint.cpp create mode 100644 hotdraw/utilities/hdRect.cpp create mode 100644 hotdraw/utilities/hdRemoveDeleteDialog.cpp create mode 100644 hotdraw/utilities/module.mk create mode 100644 include/.gitignore create mode 100644 include/agent/dlgJob.h create mode 100644 include/agent/dlgSchedule.h create mode 100644 include/agent/dlgStep.h create mode 100644 include/agent/module.mk create mode 100644 include/agent/pgaJob.h create mode 100644 include/agent/pgaSchedule.h create mode 100644 include/agent/pgaStep.h create mode 100644 include/copyright.h create mode 100644 include/ctl/calbox.h create mode 100644 include/ctl/ctlAuiNotebook.h create mode 100644 include/ctl/ctlCheckTreeView.h create mode 100644 include/ctl/ctlColourPicker.h create mode 100644 include/ctl/ctlComboBox.h create mode 100644 include/ctl/ctlDefaultSecurityPanel.h create mode 100644 include/ctl/ctlListView.h create mode 100644 include/ctl/ctlMenuToolbar.h create mode 100644 include/ctl/ctlProgressStatusBar.h create mode 100644 include/ctl/ctlSQLBox.h create mode 100644 include/ctl/ctlSQLGrid.h create mode 100644 include/ctl/ctlSQLResult.h create mode 100644 include/ctl/ctlSeclabelPanel.h create mode 100644 include/ctl/ctlSecurityPanel.h create mode 100644 include/ctl/ctlTree.h create mode 100644 include/ctl/explainCanvas.h create mode 100644 include/ctl/module.mk create mode 100644 include/ctl/timespin.h create mode 100644 include/ctl/wxgridsel.h create mode 100644 include/ctl/xh_calb.h create mode 100644 include/ctl/xh_ctlchecktreeview.h create mode 100644 include/ctl/xh_ctlcolourpicker.h create mode 100644 include/ctl/xh_ctlcombo.h create mode 100644 include/ctl/xh_ctltree.h create mode 100644 include/ctl/xh_sqlbox.h create mode 100644 include/ctl/xh_timespin.h create mode 100644 include/db/module.mk create mode 100644 include/db/pgConn.h create mode 100644 include/db/pgQueryResultEvent.h create mode 100644 include/db/pgQueryThread.h create mode 100644 include/db/pgSet.h create mode 100644 include/dd/dditems/figures/ddColumnFigure.h create mode 100644 include/dd/dditems/figures/ddColumnKindIcon.h create mode 100644 include/dd/dditems/figures/ddColumnOptionIcon.h create mode 100644 include/dd/dditems/figures/ddRelationshipFigure.h create mode 100644 include/dd/dditems/figures/ddRelationshipItem.h create mode 100644 include/dd/dditems/figures/ddRelationshipTerminal.h create mode 100644 include/dd/dditems/figures/ddTableFigure.h create mode 100644 include/dd/dditems/figures/ddTextTableItemFigure.h create mode 100644 include/dd/dditems/figures/module.mk create mode 100644 include/dd/dditems/figures/xml/ddXmlStorage.h create mode 100644 include/dd/dditems/figures/xml/module.mk create mode 100644 include/dd/dditems/handles/ddAddColButtonHandle.h create mode 100644 include/dd/dditems/handles/ddAddFkButtonHandle.h create mode 100644 include/dd/dditems/handles/ddMinMaxTableButtonHandle.h create mode 100644 include/dd/dditems/handles/ddRemoveTableButtonHandle.h create mode 100644 include/dd/dditems/handles/ddScrollBarHandle.h create mode 100644 include/dd/dditems/handles/ddSouthTableSizeHandle.h create mode 100644 include/dd/dditems/handles/module.mk create mode 100644 include/dd/dditems/locators/ddAddColLocator.h create mode 100644 include/dd/dditems/locators/ddAddFkLocator.h create mode 100644 include/dd/dditems/locators/ddMinMaxTableLocator.h create mode 100644 include/dd/dditems/locators/ddRemoveTableLocator.h create mode 100644 include/dd/dditems/locators/ddScrollBarTableLocator.h create mode 100644 include/dd/dditems/locators/ddTableBottomLocator.h create mode 100644 include/dd/dditems/locators/module.mk create mode 100644 include/dd/dditems/module.mk create mode 100644 include/dd/dditems/tools/ddColumnFigureTool.h create mode 100644 include/dd/dditems/tools/ddColumnTextTool.h create mode 100644 include/dd/dditems/tools/module.mk create mode 100644 include/dd/dditems/utilities/ddDataType.h create mode 100644 include/dd/dditems/utilities/ddPrecisionScaleDialog.h create mode 100644 include/dd/dditems/utilities/ddSelectKindFksDialog.h create mode 100644 include/dd/dditems/utilities/ddTableNameDialog.h create mode 100644 include/dd/dditems/utilities/module.mk create mode 100644 include/dd/ddmodel/ddBrowserDataContainer.h create mode 100644 include/dd/ddmodel/ddDBReverseEngineering.h create mode 100644 include/dd/ddmodel/ddDatabaseDesign.h create mode 100644 include/dd/ddmodel/ddDrawingEditor.h create mode 100644 include/dd/ddmodel/ddDrawingView.h create mode 100644 include/dd/ddmodel/ddGenerationWizard.h create mode 100644 include/dd/ddmodel/ddModelBrowser.h create mode 100644 include/dd/ddmodel/module.mk create mode 100644 include/dd/module.mk create mode 100644 include/debugger/ctlMessageWindow.h create mode 100644 include/debugger/ctlResultGrid.h create mode 100644 include/debugger/ctlStackWindow.h create mode 100644 include/debugger/ctlTabWindow.h create mode 100644 include/debugger/ctlVarWindow.h create mode 100644 include/debugger/dbgBreakPoint.h create mode 100644 include/debugger/dbgConst.h create mode 100644 include/debugger/dbgController.h create mode 100644 include/debugger/dbgModel.h create mode 100644 include/debugger/dbgTargetInfo.h create mode 100644 include/debugger/debugger.h create mode 100644 include/debugger/dlgDirectDbg.h create mode 100644 include/debugger/frmDebugger.h create mode 100644 include/debugger/module.mk create mode 100644 include/dlg/dlgAddFavourite.h create mode 100644 include/dlg/dlgAggregate.h create mode 100644 include/dlg/dlgCast.h create mode 100644 include/dlg/dlgCheck.h create mode 100644 include/dlg/dlgClasses.h create mode 100644 include/dlg/dlgCollation.h create mode 100644 include/dlg/dlgColumn.h create mode 100644 include/dlg/dlgConnect.h create mode 100644 include/dlg/dlgConversion.h create mode 100644 include/dlg/dlgDatabase.h create mode 100644 include/dlg/dlgDomain.h create mode 100644 include/dlg/dlgEditGridOptions.h create mode 100644 include/dlg/dlgEventTrigger.h create mode 100644 include/dlg/dlgExtTable.h create mode 100644 include/dlg/dlgExtension.h create mode 100644 include/dlg/dlgFindReplace.h create mode 100644 include/dlg/dlgForeignDataWrapper.h create mode 100644 include/dlg/dlgForeignKey.h create mode 100644 include/dlg/dlgForeignServer.h create mode 100644 include/dlg/dlgForeignTable.h create mode 100644 include/dlg/dlgFunction.h create mode 100644 include/dlg/dlgGroup.h create mode 100644 include/dlg/dlgHbaConfig.h create mode 100644 include/dlg/dlgIndex.h create mode 100644 include/dlg/dlgIndexConstraint.h create mode 100644 include/dlg/dlgLanguage.h create mode 100644 include/dlg/dlgMainConfig.h create mode 100644 include/dlg/dlgManageFavourites.h create mode 100644 include/dlg/dlgManageMacros.h create mode 100644 include/dlg/dlgMoveTablespace.h create mode 100644 include/dlg/dlgOperator.h create mode 100644 include/dlg/dlgPackage.h create mode 100644 include/dlg/dlgPgpassConfig.h create mode 100644 include/dlg/dlgProperty.h create mode 100644 include/dlg/dlgReassignDropOwned.h create mode 100644 include/dlg/dlgResourceGroup.h create mode 100644 include/dlg/dlgRole.h create mode 100644 include/dlg/dlgRule.h create mode 100644 include/dlg/dlgSchema.h create mode 100644 include/dlg/dlgSearchObject.h create mode 100644 include/dlg/dlgSelectConnection.h create mode 100644 include/dlg/dlgSelectDatabase.h create mode 100644 include/dlg/dlgSequence.h create mode 100644 include/dlg/dlgServer.h create mode 100644 include/dlg/dlgSynonym.h create mode 100644 include/dlg/dlgTable.h create mode 100644 include/dlg/dlgTablespace.h create mode 100644 include/dlg/dlgTextSearchConfiguration.h create mode 100644 include/dlg/dlgTextSearchDictionary.h create mode 100644 include/dlg/dlgTextSearchParser.h create mode 100644 include/dlg/dlgTextSearchTemplate.h create mode 100644 include/dlg/dlgTrigger.h create mode 100644 include/dlg/dlgType.h create mode 100644 include/dlg/dlgUser.h create mode 100644 include/dlg/dlgUserMapping.h create mode 100644 include/dlg/dlgView.h create mode 100644 include/dlg/module.mk create mode 100644 include/frm/frmAbout.h create mode 100644 include/frm/frmBackup.h create mode 100644 include/frm/frmBackupGlobals.h create mode 100644 include/frm/frmBackupServer.h create mode 100644 include/frm/frmConfig.h create mode 100644 include/frm/frmDatabaseDesigner.h create mode 100644 include/frm/frmEditGrid.h create mode 100644 include/frm/frmExport.h create mode 100644 include/frm/frmGrantWizard.h create mode 100644 include/frm/frmHbaConfig.h create mode 100644 include/frm/frmHint.h create mode 100644 include/frm/frmImport.h create mode 100644 include/frm/frmMain.h create mode 100644 include/frm/frmMainConfig.h create mode 100644 include/frm/frmMaintenance.h create mode 100644 include/frm/frmOptions.h create mode 100644 include/frm/frmPassword.h create mode 100644 include/frm/frmPgpassConfig.h create mode 100644 include/frm/frmQuery.h create mode 100644 include/frm/frmReport.h create mode 100644 include/frm/frmRestore.h create mode 100644 include/frm/frmSplash.h create mode 100644 include/frm/frmStatus.h create mode 100644 include/frm/lib.txt create mode 100644 include/frm/menu.h create mode 100644 include/frm/module.mk create mode 100644 include/gqb/gqbArrayCollection.h create mode 100644 include/gqb/gqbBrowser.h create mode 100644 include/gqb/gqbCollection.h create mode 100644 include/gqb/gqbCollectionBase.h create mode 100644 include/gqb/gqbColumn.h create mode 100644 include/gqb/gqbDatabase.h create mode 100644 include/gqb/gqbEvents.h create mode 100644 include/gqb/gqbGraphBehavior.h create mode 100644 include/gqb/gqbGraphSimple.h create mode 100644 include/gqb/gqbGridJoinTable.h create mode 100644 include/gqb/gqbGridOrderTable.h create mode 100644 include/gqb/gqbGridProjTable.h create mode 100644 include/gqb/gqbGridRestTable.h create mode 100644 include/gqb/gqbModel.h create mode 100644 include/gqb/gqbObject.h create mode 100644 include/gqb/gqbObjectCollection.h create mode 100644 include/gqb/gqbQueryObjs.h create mode 100644 include/gqb/gqbSchema.h create mode 100644 include/gqb/gqbTable.h create mode 100644 include/gqb/gqbViewController.h create mode 100644 include/gqb/gqbViewPanels.h create mode 100644 include/gqb/module.mk create mode 100644 include/hotdraw/connectors/hdChopBoxConnector.h create mode 100644 include/hotdraw/connectors/hdIConnector.h create mode 100644 include/hotdraw/connectors/hdLocatorConnector.h create mode 100644 include/hotdraw/connectors/hdStickyRectangleConnector.h create mode 100644 include/hotdraw/connectors/module.mk create mode 100644 include/hotdraw/figures/defaultAttributes/hdFillAttribute.h create mode 100644 include/hotdraw/figures/defaultAttributes/hdFontAttribute.h create mode 100644 include/hotdraw/figures/defaultAttributes/hdFontColorAttribute.h create mode 100644 include/hotdraw/figures/defaultAttributes/hdLineAttribute.h create mode 100644 include/hotdraw/figures/defaultAttributes/module.mk create mode 100644 include/hotdraw/figures/hdAbstractFigure.h create mode 100644 include/hotdraw/figures/hdAbstractMenuFigure.h create mode 100644 include/hotdraw/figures/hdAttribute.h create mode 100644 include/hotdraw/figures/hdAttributeFigure.h create mode 100644 include/hotdraw/figures/hdBitmapFigure.h create mode 100644 include/hotdraw/figures/hdCompositeFigure.h create mode 100644 include/hotdraw/figures/hdIConnectionFigure.h create mode 100644 include/hotdraw/figures/hdIFigure.h create mode 100644 include/hotdraw/figures/hdLineConnection.h create mode 100644 include/hotdraw/figures/hdLineTerminal.h create mode 100644 include/hotdraw/figures/hdPolyLineFigure.h create mode 100644 include/hotdraw/figures/hdRectangleFigure.h create mode 100644 include/hotdraw/figures/hdSimpleTextFigure.h create mode 100644 include/hotdraw/figures/module.mk create mode 100644 include/hotdraw/figures/xml/hdStorage.h create mode 100644 include/hotdraw/figures/xml/module.mk create mode 100644 include/hotdraw/handles/hdButtonHandle.h create mode 100644 include/hotdraw/handles/hdChangeConnectionEndHandle.h create mode 100644 include/hotdraw/handles/hdChangeConnectionHandle.h create mode 100644 include/hotdraw/handles/hdChangeConnectionStartHandle.h create mode 100644 include/hotdraw/handles/hdIHandle.h create mode 100644 include/hotdraw/handles/hdLineConnectionHandle.h create mode 100644 include/hotdraw/handles/hdLocatorHandle.h create mode 100644 include/hotdraw/handles/hdPolyLineHandle.h create mode 100644 include/hotdraw/handles/module.mk create mode 100644 include/hotdraw/locators/hdILocator.h create mode 100644 include/hotdraw/locators/hdPolyLineLocator.h create mode 100644 include/hotdraw/locators/module.mk create mode 100644 include/hotdraw/main/hdDrawing.h create mode 100644 include/hotdraw/main/hdDrawingEditor.h create mode 100644 include/hotdraw/main/hdDrawingView.h create mode 100644 include/hotdraw/main/hdObject.h create mode 100644 include/hotdraw/main/module.mk create mode 100644 include/hotdraw/module.mk create mode 100644 include/hotdraw/tools/hdAbstractTool.h create mode 100644 include/hotdraw/tools/hdCanvasMenuTool.h create mode 100644 include/hotdraw/tools/hdCompositeFigureTool.h create mode 100644 include/hotdraw/tools/hdConnectionCreationTool.h create mode 100644 include/hotdraw/tools/hdCreationTool.h create mode 100644 include/hotdraw/tools/hdDragCreationTool.h create mode 100644 include/hotdraw/tools/hdDragTrackerTool.h create mode 100644 include/hotdraw/tools/hdFigureTool.h create mode 100644 include/hotdraw/tools/hdHandleTrackerTool.h create mode 100644 include/hotdraw/tools/hdITool.h create mode 100644 include/hotdraw/tools/hdMenuTool.h create mode 100644 include/hotdraw/tools/hdPolyLineFigureTool.h create mode 100644 include/hotdraw/tools/hdSelectAreaTool.h create mode 100644 include/hotdraw/tools/hdSelectionTool.h create mode 100644 include/hotdraw/tools/hdSimpleTextTool.h create mode 100644 include/hotdraw/tools/module.mk create mode 100644 include/hotdraw/utilities/hdArrayCollection.h create mode 100644 include/hotdraw/utilities/hdCollection.h create mode 100644 include/hotdraw/utilities/hdCollectionBase.h create mode 100644 include/hotdraw/utilities/hdGeometry.h create mode 100644 include/hotdraw/utilities/hdKeyEvent.h create mode 100644 include/hotdraw/utilities/hdMouseEvent.h create mode 100644 include/hotdraw/utilities/hdMultiPosRect.h create mode 100644 include/hotdraw/utilities/hdPoint.h create mode 100644 include/hotdraw/utilities/hdRect.h create mode 100644 include/hotdraw/utilities/hdRemoveDeleteDialog.h create mode 100644 include/hotdraw/utilities/module.mk create mode 100644 include/images/aggregate-sm.png create mode 100644 include/images/aggregate-sm.pngc create mode 100644 include/images/aggregate.png create mode 100644 include/images/aggregate.pngc create mode 100644 include/images/aggregates.png create mode 100644 include/images/aggregates.pngc create mode 100644 include/images/back.png create mode 100644 include/images/back.pngc create mode 100644 include/images/backup.png create mode 100644 include/images/backup.pngc create mode 100644 include/images/baddatabase.png create mode 100644 include/images/baddatabase.pngc create mode 100644 include/images/cast-sm.png create mode 100644 include/images/cast-sm.pngc create mode 100644 include/images/cast.png create mode 100644 include/images/cast.pngc create mode 100644 include/images/casts.png create mode 100644 include/images/casts.pngc create mode 100644 include/images/catalog-sm.png create mode 100644 include/images/catalog-sm.pngc create mode 100644 include/images/catalog.png create mode 100644 include/images/catalog.pngc create mode 100644 include/images/catalogobject-sm.png create mode 100644 include/images/catalogobject-sm.pngc create mode 100644 include/images/catalogobject.png create mode 100644 include/images/catalogobject.pngc create mode 100644 include/images/catalogobjects.png create mode 100644 include/images/catalogobjects.pngc create mode 100644 include/images/catalogs.png create mode 100644 include/images/catalogs.pngc create mode 100644 include/images/check.png create mode 100644 include/images/check.pngc create mode 100644 include/images/checkbad.png create mode 100644 include/images/checkbad.pngc create mode 100644 include/images/checked.png create mode 100644 include/images/checked.pngc create mode 100644 include/images/clearAll.png create mode 100644 include/images/clearAll.pngc create mode 100644 include/images/clip_copy.png create mode 100644 include/images/clip_copy.pngc create mode 100644 include/images/clip_cut.png create mode 100644 include/images/clip_cut.pngc create mode 100644 include/images/clip_paste.png create mode 100644 include/images/clip_paste.pngc create mode 100644 include/images/closeddatabase-sm.png create mode 100644 include/images/closeddatabase-sm.pngc create mode 100644 include/images/closeddatabase.png create mode 100644 include/images/closeddatabase.pngc create mode 100644 include/images/collation-sm.png create mode 100644 include/images/collation-sm.pngc create mode 100644 include/images/collation.png create mode 100644 include/images/collation.pngc create mode 100644 include/images/collations.png create mode 100644 include/images/collations.pngc create mode 100644 include/images/column-sm.png create mode 100644 include/images/column-sm.pngc create mode 100644 include/images/column.png create mode 100644 include/images/column.pngc create mode 100644 include/images/columns.png create mode 100644 include/images/columns.pngc create mode 100644 include/images/configuration.png create mode 100644 include/images/configuration.pngc create mode 100644 include/images/configurations.png create mode 100644 include/images/configurations.pngc create mode 100644 include/images/connect.png create mode 100644 include/images/connect.pngc create mode 100644 include/images/constraints.png create mode 100644 include/images/constraints.pngc create mode 100644 include/images/continue.png create mode 100644 include/images/continue.pngc create mode 100644 include/images/conversion.png create mode 100644 include/images/conversion.pngc create mode 100644 include/images/conversions.png create mode 100644 include/images/conversions.pngc create mode 100644 include/images/create.png create mode 100644 include/images/create.pngc create mode 100644 include/images/database-sm.png create mode 100644 include/images/database-sm.pngc create mode 100644 include/images/database.png create mode 100644 include/images/database.pngc create mode 100644 include/images/databases.png create mode 100644 include/images/databases.pngc create mode 100644 include/images/ddAddColumn.png create mode 100644 include/images/ddAddColumn.pngc create mode 100644 include/images/ddAddColumnCursor.png create mode 100644 include/images/ddAddColumnCursor.pngc create mode 100644 include/images/ddAddForeignKey.png create mode 100644 include/images/ddAddForeignKey.pngc create mode 100644 include/images/ddDeleteTableCursor.png create mode 100644 include/images/ddDeleteTableCursor.pngc create mode 100644 include/images/ddDown.png create mode 100644 include/images/ddDown.pngc create mode 100644 include/images/ddMaximizeTable.png create mode 100644 include/images/ddMaximizeTable.pngc create mode 100644 include/images/ddMinMaxCursor.png create mode 100644 include/images/ddMinMaxCursor.pngc create mode 100644 include/images/ddMinimizeTable.png create mode 100644 include/images/ddMinimizeTable.pngc create mode 100644 include/images/ddRelationshipCursor.png create mode 100644 include/images/ddRelationshipCursor.pngc create mode 100644 include/images/ddRemoveColumn.png create mode 100644 include/images/ddRemoveColumn.pngc create mode 100644 include/images/ddRemoveColumnCursor.png create mode 100644 include/images/ddRemoveColumnCursor.pngc create mode 100644 include/images/ddRemoveTable.png create mode 100644 include/images/ddRemoveTable.pngc create mode 100644 include/images/ddRemoveTable2.png create mode 100644 include/images/ddRemoveTable2.pngc create mode 100644 include/images/ddUp.png create mode 100644 include/images/ddUp.pngc create mode 100644 include/images/ddcancel.png create mode 100644 include/images/ddcancel.pngc create mode 100644 include/images/ddforeignkey.png create mode 100644 include/images/ddforeignkey.pngc create mode 100644 include/images/ddforeignkeyfromuk.png create mode 100644 include/images/ddforeignkeyfromuk.pngc create mode 100644 include/images/ddforeignkeyuniquekey.png create mode 100644 include/images/ddforeignkeyuniquekey.pngc create mode 100644 include/images/ddforeignkeyuniquekeyfromuk.png create mode 100644 include/images/ddforeignkeyuniquekeyfromuk.pngc create mode 100644 include/images/ddgendiagram.png create mode 100644 include/images/ddgendiagram.pngc create mode 100644 include/images/ddmodel-32.png create mode 100644 include/images/ddmodel-32.pngc create mode 100644 include/images/ddnewdiagram.png create mode 100644 include/images/ddnewdiagram.pngc create mode 100644 include/images/ddnotnull.png create mode 100644 include/images/ddnotnull.pngc create mode 100644 include/images/ddnull.png create mode 100644 include/images/ddnull.pngc create mode 100644 include/images/ddprimaryforeignkey.png create mode 100644 include/images/ddprimaryforeignkey.pngc create mode 100644 include/images/ddprimaryforeignkeyfromuk.png create mode 100644 include/images/ddprimaryforeignkeyfromuk.pngc create mode 100644 include/images/ddprimarykey.png create mode 100644 include/images/ddprimarykey.pngc create mode 100644 include/images/ddprimarykeyuniquekey.png create mode 100644 include/images/ddprimarykeyuniquekey.pngc create mode 100644 include/images/ddunique.png create mode 100644 include/images/ddunique.pngc create mode 100644 include/images/debugger.png create mode 100644 include/images/debugger.pngc create mode 100644 include/images/delete.png create mode 100644 include/images/delete.pngc create mode 100644 include/images/dictionaries.png create mode 100644 include/images/dictionaries.pngc create mode 100644 include/images/dictionary.png create mode 100644 include/images/dictionary.pngc create mode 100644 include/images/disabled.png create mode 100644 include/images/disabled.pngc create mode 100644 include/images/dnd_copy.png create mode 100644 include/images/dnd_copy.pngc create mode 100644 include/images/dnd_move.png create mode 100644 include/images/dnd_move.pngc create mode 100644 include/images/dnd_none.png create mode 100644 include/images/dnd_none.pngc create mode 100644 include/images/domain-sm.png create mode 100644 include/images/domain-sm.pngc create mode 100644 include/images/domain.png create mode 100644 include/images/domain.pngc create mode 100644 include/images/domains.png create mode 100644 include/images/domains.pngc create mode 100644 include/images/down.png create mode 100644 include/images/down.pngc create mode 100644 include/images/drop.png create mode 100644 include/images/drop.pngc create mode 100644 include/images/edit_clear.png create mode 100644 include/images/edit_clear.pngc create mode 100644 include/images/edit_find.png create mode 100644 include/images/edit_find.pngc create mode 100644 include/images/edit_redo.png create mode 100644 include/images/edit_redo.pngc create mode 100644 include/images/edit_undo.png create mode 100644 include/images/edit_undo.pngc create mode 100644 include/images/enumeration.png create mode 100644 include/images/enumeration.pngc create mode 100644 include/images/enumerations.png create mode 100644 include/images/enumerations.pngc create mode 100644 include/images/ex_aggregate.png create mode 100644 include/images/ex_aggregate.pngc create mode 100644 include/images/ex_append.png create mode 100644 include/images/ex_append.pngc create mode 100644 include/images/ex_bmp_and.png create mode 100644 include/images/ex_bmp_and.pngc create mode 100644 include/images/ex_bmp_heap.png create mode 100644 include/images/ex_bmp_heap.pngc create mode 100644 include/images/ex_bmp_index.png create mode 100644 include/images/ex_bmp_index.pngc create mode 100644 include/images/ex_bmp_or.png create mode 100644 include/images/ex_bmp_or.pngc create mode 100644 include/images/ex_broadcast_motion.png create mode 100644 include/images/ex_broadcast_motion.pngc create mode 100644 include/images/ex_cte_scan.png create mode 100644 include/images/ex_cte_scan.pngc create mode 100644 include/images/ex_delete.png create mode 100644 include/images/ex_delete.pngc create mode 100644 include/images/ex_foreign_scan.png create mode 100644 include/images/ex_foreign_scan.pngc create mode 100644 include/images/ex_gatcher.png create mode 100644 include/images/ex_gatcher.pngc create mode 100644 include/images/ex_gather.png create mode 100644 include/images/ex_gather.pngc create mode 100644 include/images/ex_gather_motion.png create mode 100644 include/images/ex_gather_motion.pngc create mode 100644 include/images/ex_group.png create mode 100644 include/images/ex_group.pngc create mode 100644 include/images/ex_hash.png create mode 100644 include/images/ex_hash.pngc create mode 100644 include/images/ex_hash_anti_join.png create mode 100644 include/images/ex_hash_anti_join.pngc create mode 100644 include/images/ex_hash_semi_join.png create mode 100644 include/images/ex_hash_semi_join.pngc create mode 100644 include/images/ex_hash_setop_except.png create mode 100644 include/images/ex_hash_setop_except.pngc create mode 100644 include/images/ex_hash_setop_except_all.png create mode 100644 include/images/ex_hash_setop_except_all.pngc create mode 100644 include/images/ex_hash_setop_intersect.png create mode 100644 include/images/ex_hash_setop_intersect.pngc create mode 100644 include/images/ex_hash_setop_intersect_all.png create mode 100644 include/images/ex_hash_setop_intersect_all.pngc create mode 100644 include/images/ex_hash_setop_unknown.png create mode 100644 include/images/ex_hash_setop_unknown.pngc create mode 100644 include/images/ex_index_only_scan.png create mode 100644 include/images/ex_index_only_scan.pngc create mode 100644 include/images/ex_index_scan.png create mode 100644 include/images/ex_index_scan.pngc create mode 100644 include/images/ex_insert.png create mode 100644 include/images/ex_insert.pngc create mode 100644 include/images/ex_join.png create mode 100644 include/images/ex_join.pngc create mode 100644 include/images/ex_limit.png create mode 100644 include/images/ex_limit.pngc create mode 100644 include/images/ex_lock_rows.png create mode 100644 include/images/ex_lock_rows.pngc create mode 100644 include/images/ex_materialize.png create mode 100644 include/images/ex_materialize.pngc create mode 100644 include/images/ex_merge.png create mode 100644 include/images/ex_merge.pngc create mode 100644 include/images/ex_merge_anti_join.png create mode 100644 include/images/ex_merge_anti_join.pngc create mode 100644 include/images/ex_merge_append.png create mode 100644 include/images/ex_merge_append.pngc create mode 100644 include/images/ex_merge_semi_join.png create mode 100644 include/images/ex_merge_semi_join.pngc create mode 100644 include/images/ex_nested.png create mode 100644 include/images/ex_nested.pngc create mode 100644 include/images/ex_nested_loop_anti_join.png create mode 100644 include/images/ex_nested_loop_anti_join.pngc create mode 100644 include/images/ex_nested_loop_semi_join.png create mode 100644 include/images/ex_nested_loop_semi_join.pngc create mode 100644 include/images/ex_pscan.png create mode 100644 include/images/ex_pscan.pngc create mode 100644 include/images/ex_pscan2.png create mode 100644 include/images/ex_recursive_union.png create mode 100644 include/images/ex_recursive_union.pngc create mode 100644 include/images/ex_redistribute_motion.png create mode 100644 include/images/ex_redistribute_motion.pngc create mode 100644 include/images/ex_result.png create mode 100644 include/images/ex_result.pngc create mode 100644 include/images/ex_scan.png create mode 100644 include/images/ex_scan.pngc create mode 100644 include/images/ex_seek.png create mode 100644 include/images/ex_seek.pngc create mode 100644 include/images/ex_setop.png create mode 100644 include/images/ex_setop.pngc create mode 100644 include/images/ex_sort.png create mode 100644 include/images/ex_sort.pngc create mode 100644 include/images/ex_subplan.png create mode 100644 include/images/ex_subplan.pngc create mode 100644 include/images/ex_tid_scan.png create mode 100644 include/images/ex_tid_scan.pngc create mode 100644 include/images/ex_unique.png create mode 100644 include/images/ex_unique.pngc create mode 100644 include/images/ex_unknown.png create mode 100644 include/images/ex_unknown.pngc create mode 100644 include/images/ex_update.png create mode 100644 include/images/ex_update.pngc create mode 100644 include/images/ex_values_scan.png create mode 100644 include/images/ex_values_scan.pngc create mode 100644 include/images/ex_window_aggregate.png create mode 100644 include/images/ex_window_aggregate.pngc create mode 100644 include/images/ex_worktable_scan.png create mode 100644 include/images/ex_worktable_scan.pngc create mode 100644 include/images/exclude.png create mode 100644 include/images/exclude.pngc create mode 100644 include/images/extension-sm.png create mode 100644 include/images/extension-sm.pngc create mode 100644 include/images/extension.png create mode 100644 include/images/extension.pngc create mode 100644 include/images/extensions.png create mode 100644 include/images/extensions.pngc create mode 100644 include/images/exttable-sm.png create mode 100644 include/images/exttable-sm.pngc create mode 100644 include/images/exttable.png create mode 100644 include/images/exttable.pngc create mode 100644 include/images/exttables.png create mode 100644 include/images/exttables.pngc create mode 100644 include/images/favourite.png create mode 100644 include/images/favourite.pngc create mode 100644 include/images/file_new.png create mode 100644 include/images/file_new.pngc create mode 100644 include/images/file_open.png create mode 100644 include/images/file_open.pngc create mode 100644 include/images/file_save.png create mode 100644 include/images/file_save.pngc create mode 100644 include/images/folder.png create mode 100644 include/images/folder.pngc create mode 100644 include/images/foreigndatawrapper-sm.png create mode 100644 include/images/foreigndatawrapper-sm.pngc create mode 100644 include/images/foreigndatawrapper.png create mode 100644 include/images/foreigndatawrapper.pngc create mode 100644 include/images/foreigndatawrappers.png create mode 100644 include/images/foreigndatawrappers.pngc create mode 100644 include/images/foreignkey.png create mode 100644 include/images/foreignkey.pngc create mode 100644 include/images/foreignkeybad.png create mode 100644 include/images/foreignkeybad.pngc create mode 100644 include/images/foreignserver-sm.png create mode 100644 include/images/foreignserver-sm.pngc create mode 100644 include/images/foreignserver.png create mode 100644 include/images/foreignserver.pngc create mode 100644 include/images/foreignservers.png create mode 100644 include/images/foreignservers.pngc create mode 100644 include/images/foreigntable.png create mode 100644 include/images/foreigntable.pngc create mode 100644 include/images/foreigntables.png create mode 100644 include/images/foreigntables.pngc create mode 100644 include/images/forward.png create mode 100644 include/images/forward.pngc create mode 100644 include/images/function.png create mode 100644 include/images/function.pngc create mode 100644 include/images/functions.png create mode 100644 include/images/functions.pngc create mode 100644 include/images/gqbAdd.png create mode 100644 include/images/gqbAdd.pngc create mode 100644 include/images/gqbAddRest.png create mode 100644 include/images/gqbAddRest.pngc create mode 100644 include/images/gqbColNotSel.png create mode 100644 include/images/gqbColNotSel.pngc create mode 100644 include/images/gqbColSel.png create mode 100644 include/images/gqbColSel.pngc create mode 100644 include/images/gqbDown.png create mode 100644 include/images/gqbDown.pngc create mode 100644 include/images/gqbDownBottom.png create mode 100644 include/images/gqbDownBottom.pngc create mode 100644 include/images/gqbJoin.png create mode 100644 include/images/gqbJoin.pngc create mode 100644 include/images/gqbJoinCursor.png create mode 100644 include/images/gqbJoinCursor.pngc create mode 100644 include/images/gqbOrderAdd.png create mode 100644 include/images/gqbOrderAdd.pngc create mode 100644 include/images/gqbOrderAddAll.png create mode 100644 include/images/gqbOrderAddAll.pngc create mode 100644 include/images/gqbOrderRemove.png create mode 100644 include/images/gqbOrderRemove.pngc create mode 100644 include/images/gqbOrderRemoveAll.png create mode 100644 include/images/gqbOrderRemoveAll.pngc create mode 100644 include/images/gqbRemove.png create mode 100644 include/images/gqbRemove.pngc create mode 100644 include/images/gqbRemoveRest.png create mode 100644 include/images/gqbRemoveRest.pngc create mode 100644 include/images/gqbUp.png create mode 100644 include/images/gqbUp.pngc create mode 100644 include/images/gqbUpTop.png create mode 100644 include/images/gqbUpTop.pngc create mode 100644 include/images/group.png create mode 100644 include/images/group.pngc create mode 100644 include/images/groups.png create mode 100644 include/images/groups.pngc create mode 100644 include/images/help.png create mode 100644 include/images/help.pngc create mode 100644 include/images/help2.png create mode 100644 include/images/help2.pngc create mode 100644 include/images/hint.png create mode 100644 include/images/hint.pngc create mode 100644 include/images/hint2.png create mode 100644 include/images/hint2.pngc create mode 100644 include/images/index.png create mode 100644 include/images/index.pngc create mode 100644 include/images/indexes.png create mode 100644 include/images/indexes.pngc create mode 100644 include/images/job.png create mode 100644 include/images/job.pngc create mode 100644 include/images/jobdisabled.png create mode 100644 include/images/jobdisabled.pngc create mode 100644 include/images/jobs.png create mode 100644 include/images/jobs.pngc create mode 100644 include/images/key.png create mode 100644 include/images/key.pngc create mode 100644 include/images/language-sm.png create mode 100644 include/images/language-sm.pngc create mode 100644 include/images/language.png create mode 100644 include/images/language.pngc create mode 100644 include/images/languages.png create mode 100644 include/images/languages.pngc create mode 100644 include/images/loginroles.png create mode 100644 include/images/loginroles.pngc create mode 100644 include/images/module.mk create mode 100644 include/images/mview-sm.png create mode 100644 include/images/mview-sm.pngc create mode 100644 include/images/mview.png create mode 100644 include/images/mview.pngc create mode 100644 include/images/namespace-sm.png create mode 100644 include/images/namespace-sm.pngc create mode 100644 include/images/namespace.png create mode 100644 include/images/namespace.pngc create mode 100644 include/images/namespaces.png create mode 100644 include/images/namespaces.pngc create mode 100644 include/images/operator.png create mode 100644 include/images/operator.pngc create mode 100644 include/images/operatorclass.png create mode 100644 include/images/operatorclass.pngc create mode 100644 include/images/operatorclasses.png create mode 100644 include/images/operatorclasses.pngc create mode 100644 include/images/operatorfamilies.png create mode 100644 include/images/operatorfamilies.pngc create mode 100644 include/images/operatorfamily.png create mode 100644 include/images/operatorfamily.pngc create mode 100644 include/images/operators.png create mode 100644 include/images/operators.pngc create mode 100644 include/images/package.png create mode 100644 include/images/package.pngc create mode 100644 include/images/packages.png create mode 100644 include/images/packages.pngc create mode 100644 include/images/parser.png create mode 100644 include/images/parser.pngc create mode 100644 include/images/parsers.png create mode 100644 include/images/parsers.pngc create mode 100644 include/images/pgAdmin3-128.png create mode 100644 include/images/pgAdmin3-16.png create mode 100644 include/images/pgAdmin3-16.pngc create mode 100644 include/images/pgAdmin3-22.png create mode 100644 include/images/pgAdmin3-24.png create mode 100644 include/images/pgAdmin3-256.png create mode 100644 include/images/pgAdmin3-32.png create mode 100644 include/images/pgAdmin3-32.pngc create mode 100644 include/images/pgAdmin3-36.png create mode 100644 include/images/pgAdmin3-48.png create mode 100644 include/images/pgAdmin3-96.png create mode 100644 include/images/pgAdmin3.ico create mode 100644 include/images/pgAdmin3.png create mode 100644 include/images/pgAdmin3.pngc create mode 100644 include/images/pgAdmin3.svg create mode 100644 include/images/plugins.png create mode 100644 include/images/plugins.pngc create mode 100644 include/images/primarykey.png create mode 100644 include/images/primarykey.pngc create mode 100644 include/images/procedure.png create mode 100644 include/images/procedure.pngc create mode 100644 include/images/procedures.png create mode 100644 include/images/procedures.pngc create mode 100644 include/images/properties.png create mode 100644 include/images/properties.pngc create mode 100644 include/images/property.png create mode 100644 include/images/property.pngc create mode 100644 include/images/query_cancel.png create mode 100644 include/images/query_cancel.pngc create mode 100644 include/images/query_commit.png create mode 100644 include/images/query_commit.pngc create mode 100644 include/images/query_execfile.png create mode 100644 include/images/query_execfile.pngc create mode 100644 include/images/query_execute.png create mode 100644 include/images/query_execute.pngc create mode 100644 include/images/query_explain.png create mode 100644 include/images/query_explain.pngc create mode 100644 include/images/query_pgscript.png create mode 100644 include/images/query_pgscript.pngc create mode 100644 include/images/query_rollback.png create mode 100644 include/images/query_rollback.pngc create mode 100644 include/images/readdata.png create mode 100644 include/images/readdata.pngc create mode 100644 include/images/refresh.png create mode 100644 include/images/refresh.pngc create mode 100644 include/images/reload.png create mode 100644 include/images/reload.pngc create mode 100644 include/images/resourcegroup.png create mode 100644 include/images/resourcegroup.pngc create mode 100644 include/images/resourcegroups.png create mode 100644 include/images/resourcegroups.pngc create mode 100644 include/images/restore.png create mode 100644 include/images/restore.pngc create mode 100644 include/images/roles.png create mode 100644 include/images/roles.pngc create mode 100644 include/images/rule.png create mode 100644 include/images/rule.pngc create mode 100644 include/images/rulebad.png create mode 100644 include/images/rulebad.pngc create mode 100644 include/images/rules.png create mode 100644 include/images/rules.pngc create mode 100644 include/images/schedule.png create mode 100644 include/images/schedule.pngc create mode 100644 include/images/schedules.png create mode 100644 include/images/schedules.pngc create mode 100644 include/images/sequence-repl.png create mode 100644 include/images/sequence-repl.pngc create mode 100644 include/images/sequence.png create mode 100644 include/images/sequence.pngc create mode 100644 include/images/sequences.png create mode 100644 include/images/sequences.pngc create mode 100644 include/images/server-sm.png create mode 100644 include/images/server-sm.pngc create mode 100644 include/images/server.png create mode 100644 include/images/server.pngc create mode 100644 include/images/serverbad-sm.png create mode 100644 include/images/serverbad-sm.pngc create mode 100644 include/images/serverbad.png create mode 100644 include/images/serverbad.pngc create mode 100644 include/images/servers.png create mode 100644 include/images/servers.pngc create mode 100644 include/images/setBreak.png create mode 100644 include/images/setBreak.pngc create mode 100644 include/images/slcluster.png create mode 100644 include/images/slcluster.pngc create mode 100644 include/images/slclusters.png create mode 100644 include/images/slclusters.pngc create mode 100644 include/images/sllisten.png create mode 100644 include/images/sllisten.pngc create mode 100644 include/images/sllistens.png create mode 100644 include/images/sllistens.pngc create mode 100644 include/images/slnode-disabled.png create mode 100644 include/images/slnode-disabled.pngc create mode 100644 include/images/slnode-local.png create mode 100644 include/images/slnode-local.pngc create mode 100644 include/images/slnode.png create mode 100644 include/images/slnode.pngc create mode 100644 include/images/slnodes.png create mode 100644 include/images/slnodes.pngc create mode 100644 include/images/slpath.png create mode 100644 include/images/slpath.pngc create mode 100644 include/images/slpaths.png create mode 100644 include/images/slpaths.pngc create mode 100644 include/images/slset.png create mode 100644 include/images/slset.pngc create mode 100644 include/images/slset2.png create mode 100644 include/images/slset2.pngc create mode 100644 include/images/slsets.png create mode 100644 include/images/slsets.pngc create mode 100644 include/images/slsubscription.png create mode 100644 include/images/slsubscription.pngc create mode 100644 include/images/slsubscription2.png create mode 100644 include/images/slsubscription2.pngc create mode 100644 include/images/slsubscriptions.png create mode 100644 include/images/slsubscriptions.pngc create mode 100644 include/images/sortfilter.png create mode 100644 include/images/sortfilter.pngc create mode 100644 include/images/splash.png create mode 100644 include/images/splash.pngc create mode 100644 include/images/sql-16.png create mode 100644 include/images/sql-16.pngc create mode 100644 include/images/sql-32.png create mode 100644 include/images/sql-32.pngc create mode 100644 include/images/sql.ico create mode 100644 include/images/sql.png create mode 100644 include/images/sql.pngc create mode 100644 include/images/statistics.png create mode 100644 include/images/statistics.pngc create mode 100644 include/images/step.png create mode 100644 include/images/step.pngc create mode 100644 include/images/stepInto.png create mode 100644 include/images/stepInto.pngc create mode 100644 include/images/stepOver.png create mode 100644 include/images/stepOver.pngc create mode 100644 include/images/steps.png create mode 100644 include/images/steps.pngc create mode 100644 include/images/stop.png create mode 100644 include/images/stop.pngc create mode 100644 include/images/storedata.png create mode 100644 include/images/storedata.pngc create mode 100644 include/images/synonym.png create mode 100644 include/images/synonym.pngc create mode 100644 include/images/synonyms.png create mode 100644 include/images/synonyms.pngc create mode 100644 include/images/table-repl-sm.png create mode 100644 include/images/table-repl-sm.pngc create mode 100644 include/images/table-repl.png create mode 100644 include/images/table-repl.pngc create mode 100644 include/images/table-sm.png create mode 100644 include/images/table-sm.pngc create mode 100644 include/images/table.png create mode 100644 include/images/table.pngc create mode 100644 include/images/tables.png create mode 100644 include/images/tables.pngc create mode 100644 include/images/tablespace.png create mode 100644 include/images/tablespace.pngc create mode 100644 include/images/tablespaces.png create mode 100644 include/images/tablespaces.pngc create mode 100644 include/images/template.png create mode 100644 include/images/template.pngc create mode 100644 include/images/templates.png create mode 100644 include/images/templates.pngc create mode 100644 include/images/terminate_backend.png create mode 100644 include/images/terminate_backend.pngc create mode 100644 include/images/textsearch.png create mode 100644 include/images/textsearch.pngc create mode 100644 include/images/trigger.png create mode 100644 include/images/trigger.pngc create mode 100644 include/images/triggerbad.png create mode 100644 include/images/triggerbad.pngc create mode 100644 include/images/triggerfunction.png create mode 100644 include/images/triggerfunction.pngc create mode 100644 include/images/triggerfunctions.png create mode 100644 include/images/triggerfunctions.pngc create mode 100644 include/images/triggers.png create mode 100644 include/images/triggers.pngc create mode 100644 include/images/type.png create mode 100644 include/images/type.pngc create mode 100644 include/images/types.png create mode 100644 include/images/types.pngc create mode 100644 include/images/uncheck.png create mode 100644 include/images/uncheck.pngc create mode 100644 include/images/unchecked.png create mode 100644 include/images/unchecked.pngc create mode 100644 include/images/unique.png create mode 100644 include/images/unique.pngc create mode 100644 include/images/up.png create mode 100644 include/images/up.pngc create mode 100644 include/images/user.png create mode 100644 include/images/user.pngc create mode 100644 include/images/usermapping-sm.png create mode 100644 include/images/usermapping-sm.pngc create mode 100644 include/images/usermapping.png create mode 100644 include/images/usermapping.pngc create mode 100644 include/images/usermappings.png create mode 100644 include/images/usermappings.pngc create mode 100644 include/images/users.png create mode 100644 include/images/users.pngc create mode 100644 include/images/vacuum.png create mode 100644 include/images/vacuum.pngc create mode 100644 include/images/variable.png create mode 100644 include/images/variable.pngc create mode 100644 include/images/variables.png create mode 100644 include/images/variables.pngc create mode 100644 include/images/view-sm.png create mode 100644 include/images/view-sm.pngc create mode 100644 include/images/view.png create mode 100644 include/images/view.pngc create mode 100644 include/images/viewdata.png create mode 100644 include/images/viewdata.pngc create mode 100644 include/images/viewfiltereddata.png create mode 100644 include/images/viewfiltereddata.pngc create mode 100644 include/images/views.png create mode 100644 include/images/views.pngc create mode 100644 include/libssh2/Win32/libssh2_config.h create mode 100644 include/libssh2/channel.h create mode 100644 include/libssh2/comp.h create mode 100644 include/libssh2/crypto.h create mode 100644 include/libssh2/libgcrypt.h create mode 100644 include/libssh2/libssh2.h create mode 100644 include/libssh2/libssh2_config.h.in create mode 100644 include/libssh2/libssh2_priv.h create mode 100644 include/libssh2/libssh2_publickey.h create mode 100644 include/libssh2/libssh2_sftp.h create mode 100644 include/libssh2/mac.h create mode 100644 include/libssh2/misc.h create mode 100644 include/libssh2/module.mk create mode 100644 include/libssh2/openssl.h create mode 100644 include/libssh2/packet.h create mode 100644 include/libssh2/session.h create mode 100644 include/libssh2/sftp.h create mode 100644 include/libssh2/transport.h create mode 100644 include/libssh2/userauth.h create mode 100644 include/module.mk create mode 100644 include/ogl/README create mode 100644 include/ogl/basic.h create mode 100644 include/ogl/basicp.h create mode 100644 include/ogl/bmpshape.h create mode 100644 include/ogl/canvas.h create mode 100644 include/ogl/composit.h create mode 100644 include/ogl/constrnt.h create mode 100644 include/ogl/divided.h create mode 100644 include/ogl/drawn.h create mode 100644 include/ogl/drawnp.h create mode 100644 include/ogl/lines.h create mode 100644 include/ogl/linesp.h create mode 100644 include/ogl/mfutils.h create mode 100644 include/ogl/misc.h create mode 100644 include/ogl/module.mk create mode 100644 include/ogl/ogl.h create mode 100644 include/ogl/ogldiag.h create mode 100644 include/parser/keywords.h create mode 100644 include/parser/module.mk create mode 100644 include/pgAdmin3.h create mode 100644 include/pgscript/FlexLexer.h create mode 100644 include/pgscript/exceptions/module.mk create mode 100644 include/pgscript/exceptions/pgsArithmeticException.h create mode 100644 include/pgscript/exceptions/pgsAssertException.h create mode 100644 include/pgscript/exceptions/pgsBreakException.h create mode 100644 include/pgscript/exceptions/pgsCastException.h create mode 100644 include/pgscript/exceptions/pgsContinueException.h create mode 100644 include/pgscript/exceptions/pgsException.h create mode 100644 include/pgscript/exceptions/pgsInterruptException.h create mode 100644 include/pgscript/exceptions/pgsParameterException.h create mode 100644 include/pgscript/expressions/module.mk create mode 100644 include/pgscript/expressions/pgsAnd.h create mode 100644 include/pgscript/expressions/pgsAssign.h create mode 100644 include/pgscript/expressions/pgsAssignToRecord.h create mode 100644 include/pgscript/expressions/pgsCast.h create mode 100644 include/pgscript/expressions/pgsColumns.h create mode 100644 include/pgscript/expressions/pgsDifferent.h create mode 100644 include/pgscript/expressions/pgsEqual.h create mode 100644 include/pgscript/expressions/pgsExecute.h create mode 100644 include/pgscript/expressions/pgsExpression.h create mode 100644 include/pgscript/expressions/pgsExpressions.h create mode 100644 include/pgscript/expressions/pgsGenDate.h create mode 100644 include/pgscript/expressions/pgsGenDateTime.h create mode 100644 include/pgscript/expressions/pgsGenDictionary.h create mode 100644 include/pgscript/expressions/pgsGenInt.h create mode 100644 include/pgscript/expressions/pgsGenReal.h create mode 100644 include/pgscript/expressions/pgsGenReference.h create mode 100644 include/pgscript/expressions/pgsGenRegex.h create mode 100644 include/pgscript/expressions/pgsGenString.h create mode 100644 include/pgscript/expressions/pgsGenTime.h create mode 100644 include/pgscript/expressions/pgsGreater.h create mode 100644 include/pgscript/expressions/pgsGreaterEqual.h create mode 100644 include/pgscript/expressions/pgsIdent.h create mode 100644 include/pgscript/expressions/pgsIdentRecord.h create mode 100644 include/pgscript/expressions/pgsLines.h create mode 100644 include/pgscript/expressions/pgsLower.h create mode 100644 include/pgscript/expressions/pgsLowerEqual.h create mode 100644 include/pgscript/expressions/pgsMinus.h create mode 100644 include/pgscript/expressions/pgsModulo.h create mode 100644 include/pgscript/expressions/pgsNegate.h create mode 100644 include/pgscript/expressions/pgsNot.h create mode 100644 include/pgscript/expressions/pgsOperation.h create mode 100644 include/pgscript/expressions/pgsOr.h create mode 100644 include/pgscript/expressions/pgsOver.h create mode 100644 include/pgscript/expressions/pgsParenthesis.h create mode 100644 include/pgscript/expressions/pgsPlus.h create mode 100644 include/pgscript/expressions/pgsRemoveLine.h create mode 100644 include/pgscript/expressions/pgsTimes.h create mode 100644 include/pgscript/expressions/pgsTrim.h create mode 100644 include/pgscript/generators/module.mk create mode 100644 include/pgscript/generators/pgsDateGen.h create mode 100644 include/pgscript/generators/pgsDateTimeGen.h create mode 100644 include/pgscript/generators/pgsDictionaryGen.h create mode 100644 include/pgscript/generators/pgsIntegerGen.h create mode 100644 include/pgscript/generators/pgsNumberGen.h create mode 100644 include/pgscript/generators/pgsObjectGen.h create mode 100644 include/pgscript/generators/pgsRealGen.h create mode 100644 include/pgscript/generators/pgsReferenceGen.h create mode 100644 include/pgscript/generators/pgsRegexGen.h create mode 100644 include/pgscript/generators/pgsStringGen.h create mode 100644 include/pgscript/generators/pgsTimeGen.h create mode 100644 include/pgscript/location.hh create mode 100644 include/pgscript/module.mk create mode 100644 include/pgscript/objects/module.mk create mode 100644 include/pgscript/objects/pgsGenerator.h create mode 100644 include/pgscript/objects/pgsNumber.h create mode 100644 include/pgscript/objects/pgsObjects.h create mode 100644 include/pgscript/objects/pgsRecord.h create mode 100644 include/pgscript/objects/pgsString.h create mode 100644 include/pgscript/objects/pgsVariable.h create mode 100644 include/pgscript/parser.tab.hh create mode 100644 include/pgscript/pgScript.h create mode 100644 include/pgscript/pgsApplication.h create mode 100644 include/pgscript/position.hh create mode 100644 include/pgscript/stack.hh create mode 100644 include/pgscript/statements/module.mk create mode 100644 include/pgscript/statements/pgsAssertStmt.h create mode 100644 include/pgscript/statements/pgsBreakStmt.h create mode 100644 include/pgscript/statements/pgsContinueStmt.h create mode 100644 include/pgscript/statements/pgsDeclareRecordStmt.h create mode 100644 include/pgscript/statements/pgsExpressionStmt.h create mode 100644 include/pgscript/statements/pgsIfStmt.h create mode 100644 include/pgscript/statements/pgsPrintStmt.h create mode 100644 include/pgscript/statements/pgsProgram.h create mode 100644 include/pgscript/statements/pgsStatements.h create mode 100644 include/pgscript/statements/pgsStmt.h create mode 100644 include/pgscript/statements/pgsStmtList.h create mode 100644 include/pgscript/statements/pgsWhileStmt.h create mode 100644 include/pgscript/utilities/mapm-lib/license.txt create mode 100644 include/pgscript/utilities/mapm-lib/m_apm.h create mode 100644 include/pgscript/utilities/mapm-lib/m_apm_lc.h create mode 100644 include/pgscript/utilities/mapm-lib/module.mk create mode 100644 include/pgscript/utilities/module.mk create mode 100644 include/pgscript/utilities/pgsAlloc.h create mode 100644 include/pgscript/utilities/pgsContext.h create mode 100644 include/pgscript/utilities/pgsCopiedPtr.h create mode 100644 include/pgscript/utilities/pgsDriver.h create mode 100644 include/pgscript/utilities/pgsMapm.h create mode 100644 include/pgscript/utilities/pgsScanner.h create mode 100644 include/pgscript/utilities/pgsSharedPtr.h create mode 100644 include/pgscript/utilities/pgsThread.h create mode 100644 include/pgscript/utilities/pgsUtilities.h create mode 100644 include/postgres.h create mode 100644 include/precomp.h create mode 100644 include/schema/edbPackage.h create mode 100644 include/schema/edbPackageFunction.h create mode 100644 include/schema/edbPackageVariable.h create mode 100644 include/schema/edbPrivateSynonym.h create mode 100644 include/schema/edbResourceGroup.h create mode 100644 include/schema/edbSynonym.h create mode 100644 include/schema/gpExtTable.h create mode 100644 include/schema/gpPartition.h create mode 100644 include/schema/gpResQueue.h create mode 100644 include/schema/module.mk create mode 100644 include/schema/pgAggregate.h create mode 100644 include/schema/pgCast.h create mode 100644 include/schema/pgCatalogObject.h create mode 100644 include/schema/pgCheck.h create mode 100644 include/schema/pgCollation.h create mode 100644 include/schema/pgCollection.h create mode 100644 include/schema/pgColumn.h create mode 100644 include/schema/pgConstraints.h create mode 100644 include/schema/pgConversion.h create mode 100644 include/schema/pgDatabase.h create mode 100644 include/schema/pgDatatype.h create mode 100644 include/schema/pgDomain.h create mode 100644 include/schema/pgEventTrigger.h create mode 100644 include/schema/pgExtension.h create mode 100644 include/schema/pgForeignDataWrapper.h create mode 100644 include/schema/pgForeignKey.h create mode 100644 include/schema/pgForeignServer.h create mode 100644 include/schema/pgForeignTable.h create mode 100644 include/schema/pgFunction.h create mode 100644 include/schema/pgGroup.h create mode 100644 include/schema/pgIndex.h create mode 100644 include/schema/pgIndexConstraint.h create mode 100644 include/schema/pgLanguage.h create mode 100644 include/schema/pgObject.h create mode 100644 include/schema/pgOperator.h create mode 100644 include/schema/pgOperatorClass.h create mode 100644 include/schema/pgOperatorFamily.h create mode 100644 include/schema/pgPartition.h create mode 100644 include/schema/pgRole.h create mode 100644 include/schema/pgRule.h create mode 100644 include/schema/pgSchema.h create mode 100644 include/schema/pgSequence.h create mode 100644 include/schema/pgServer.h create mode 100644 include/schema/pgTable.h create mode 100644 include/schema/pgTablespace.h create mode 100644 include/schema/pgTextSearchConfiguration.h create mode 100644 include/schema/pgTextSearchDictionary.h create mode 100644 include/schema/pgTextSearchParser.h create mode 100644 include/schema/pgTextSearchTemplate.h create mode 100644 include/schema/pgTrigger.h create mode 100644 include/schema/pgType.h create mode 100644 include/schema/pgUser.h create mode 100644 include/schema/pgUserMapping.h create mode 100644 include/schema/pgView.h create mode 100644 include/slony/dlgRepCluster.h create mode 100644 include/slony/dlgRepListen.h create mode 100644 include/slony/dlgRepNode.h create mode 100644 include/slony/dlgRepPath.h create mode 100644 include/slony/dlgRepProperty.h create mode 100644 include/slony/dlgRepSequence.h create mode 100644 include/slony/dlgRepSet.h create mode 100644 include/slony/dlgRepSubscription.h create mode 100644 include/slony/dlgRepTable.h create mode 100644 include/slony/module.mk create mode 100644 include/slony/slCluster.h create mode 100644 include/slony/slListen.h create mode 100644 include/slony/slNode.h create mode 100644 include/slony/slPath.h create mode 100644 include/slony/slSequence.h create mode 100644 include/slony/slSet.h create mode 100644 include/slony/slSubscription.h create mode 100644 include/slony/slTable.h create mode 100644 include/utils/csvfiles.h create mode 100644 include/utils/factory.h create mode 100644 include/utils/favourites.h create mode 100644 include/utils/macros.h create mode 100644 include/utils/misc.h create mode 100644 include/utils/module.mk create mode 100644 include/utils/pgDefs.h create mode 100644 include/utils/pgconfig.h create mode 100644 include/utils/pgfeatures.h create mode 100644 include/utils/registry.h create mode 100644 include/utils/sshTunnel.h create mode 100644 include/utils/sysLogger.h create mode 100644 include/utils/sysProcess.h create mode 100644 include/utils/sysSettings.h create mode 100644 include/utils/utffile.h create mode 100644 include/version.h create mode 100644 libssh2/agent.c create mode 100644 libssh2/channel.c create mode 100644 libssh2/comp.c create mode 100644 libssh2/crypt.c create mode 100644 libssh2/global.c create mode 100644 libssh2/hostkey.c create mode 100644 libssh2/keepalive.c create mode 100644 libssh2/kex.c create mode 100644 libssh2/knownhost.c create mode 100644 libssh2/libgcrypt.c create mode 100644 libssh2/mac.c create mode 100644 libssh2/misc.c create mode 100644 libssh2/module.mk create mode 100644 libssh2/openssl.c create mode 100644 libssh2/packet.c create mode 100644 libssh2/pem.c create mode 100644 libssh2/publickey.c create mode 100644 libssh2/scp.c create mode 100644 libssh2/session.c create mode 100644 libssh2/sftp.c create mode 100644 libssh2/transport.c create mode 100644 libssh2/userauth.c create mode 100644 libssh2/version.c create mode 100644 ogl/README create mode 100644 ogl/basic.cpp create mode 100644 ogl/basic2.cpp create mode 100644 ogl/bmpshape.cpp create mode 100644 ogl/canvas.cpp create mode 100644 ogl/composit.cpp create mode 100644 ogl/constrnt.cpp create mode 100644 ogl/divided.cpp create mode 100644 ogl/drawn.cpp create mode 100644 ogl/lines.cpp create mode 100644 ogl/mfutils.cpp create mode 100644 ogl/module.mk create mode 100644 ogl/ogldiag.cpp create mode 100644 ogl/oglmisc.cpp create mode 100644 pgscript/README create mode 100644 pgscript/exceptions/module.mk create mode 100644 pgscript/exceptions/pgsArithmeticException.cpp create mode 100644 pgscript/exceptions/pgsAssertException.cpp create mode 100644 pgscript/exceptions/pgsBreakException.cpp create mode 100644 pgscript/exceptions/pgsCastException.cpp create mode 100644 pgscript/exceptions/pgsContinueException.cpp create mode 100644 pgscript/exceptions/pgsException.cpp create mode 100644 pgscript/exceptions/pgsInterruptException.cpp create mode 100644 pgscript/exceptions/pgsParameterException.cpp create mode 100644 pgscript/expressions/module.mk create mode 100644 pgscript/expressions/pgsAnd.cpp create mode 100644 pgscript/expressions/pgsAssign.cpp create mode 100644 pgscript/expressions/pgsAssignToRecord.cpp create mode 100644 pgscript/expressions/pgsCast.cpp create mode 100644 pgscript/expressions/pgsColumns.cpp create mode 100644 pgscript/expressions/pgsDifferent.cpp create mode 100644 pgscript/expressions/pgsEqual.cpp create mode 100644 pgscript/expressions/pgsExecute.cpp create mode 100644 pgscript/expressions/pgsExpression.cpp create mode 100644 pgscript/expressions/pgsGenDate.cpp create mode 100644 pgscript/expressions/pgsGenDateTime.cpp create mode 100644 pgscript/expressions/pgsGenDictionary.cpp create mode 100644 pgscript/expressions/pgsGenInt.cpp create mode 100644 pgscript/expressions/pgsGenReal.cpp create mode 100644 pgscript/expressions/pgsGenReference.cpp create mode 100644 pgscript/expressions/pgsGenRegex.cpp create mode 100644 pgscript/expressions/pgsGenString.cpp create mode 100644 pgscript/expressions/pgsGenTime.cpp create mode 100644 pgscript/expressions/pgsGreater.cpp create mode 100644 pgscript/expressions/pgsGreaterEqual.cpp create mode 100644 pgscript/expressions/pgsIdent.cpp create mode 100644 pgscript/expressions/pgsIdentRecord.cpp create mode 100644 pgscript/expressions/pgsLines.cpp create mode 100644 pgscript/expressions/pgsLower.cpp create mode 100644 pgscript/expressions/pgsLowerEqual.cpp create mode 100644 pgscript/expressions/pgsMinus.cpp create mode 100644 pgscript/expressions/pgsModulo.cpp create mode 100644 pgscript/expressions/pgsNegate.cpp create mode 100644 pgscript/expressions/pgsNot.cpp create mode 100644 pgscript/expressions/pgsOperation.cpp create mode 100644 pgscript/expressions/pgsOr.cpp create mode 100644 pgscript/expressions/pgsOver.cpp create mode 100644 pgscript/expressions/pgsParenthesis.cpp create mode 100644 pgscript/expressions/pgsPlus.cpp create mode 100644 pgscript/expressions/pgsRemoveLine.cpp create mode 100644 pgscript/expressions/pgsTimes.cpp create mode 100644 pgscript/expressions/pgsTrim.cpp create mode 100644 pgscript/generators/module.mk create mode 100644 pgscript/generators/pgsDateGen.cpp create mode 100644 pgscript/generators/pgsDateTimeGen.cpp create mode 100644 pgscript/generators/pgsDictionaryGen.cpp create mode 100644 pgscript/generators/pgsIntegerGen.cpp create mode 100644 pgscript/generators/pgsNumberGen.cpp create mode 100644 pgscript/generators/pgsObjectGen.cpp create mode 100644 pgscript/generators/pgsRealGen.cpp create mode 100644 pgscript/generators/pgsReferenceGen.cpp create mode 100644 pgscript/generators/pgsRegexGen.cpp create mode 100644 pgscript/generators/pgsStringGen.cpp create mode 100644 pgscript/generators/pgsTimeGen.cpp create mode 100644 pgscript/lex.pgs.cc create mode 100644 pgscript/module.mk create mode 100644 pgscript/objects/module.mk create mode 100644 pgscript/objects/pgsGenerator.cpp create mode 100644 pgscript/objects/pgsNumber.cpp create mode 100644 pgscript/objects/pgsRecord.cpp create mode 100644 pgscript/objects/pgsString.cpp create mode 100644 pgscript/objects/pgsVariable.cpp create mode 100644 pgscript/parser.sh create mode 100644 pgscript/parser.tab.cc create mode 100644 pgscript/pgsApplication.cpp create mode 100644 pgscript/pgsParser.yy create mode 100644 pgscript/pgsScanner.ll create mode 100644 pgscript/statements/module.mk create mode 100644 pgscript/statements/pgsAssertStmt.cpp create mode 100644 pgscript/statements/pgsBreakStmt.cpp create mode 100644 pgscript/statements/pgsContinueStmt.cpp create mode 100644 pgscript/statements/pgsDeclareRecordStmt.cpp create mode 100644 pgscript/statements/pgsExpressionStmt.cpp create mode 100644 pgscript/statements/pgsIfStmt.cpp create mode 100644 pgscript/statements/pgsPrintStmt.cpp create mode 100644 pgscript/statements/pgsProgram.cpp create mode 100644 pgscript/statements/pgsStmt.cpp create mode 100644 pgscript/statements/pgsStmtList.cpp create mode 100644 pgscript/statements/pgsWhileStmt.cpp create mode 100644 pgscript/utilities/m_apm/mapm5sin.cpp create mode 100644 pgscript/utilities/m_apm/mapm_add.cpp create mode 100644 pgscript/utilities/m_apm/mapm_cpi.cpp create mode 100644 pgscript/utilities/m_apm/mapm_div.cpp create mode 100644 pgscript/utilities/m_apm/mapm_exp.cpp create mode 100644 pgscript/utilities/m_apm/mapm_fam.cpp create mode 100644 pgscript/utilities/m_apm/mapm_fft.cpp create mode 100644 pgscript/utilities/m_apm/mapm_flr.cpp create mode 100644 pgscript/utilities/m_apm/mapm_fpf.cpp create mode 100644 pgscript/utilities/m_apm/mapm_gcd.cpp create mode 100644 pgscript/utilities/m_apm/mapm_lg2.cpp create mode 100644 pgscript/utilities/m_apm/mapm_lg3.cpp create mode 100644 pgscript/utilities/m_apm/mapm_lg4.cpp create mode 100644 pgscript/utilities/m_apm/mapm_log.cpp create mode 100644 pgscript/utilities/m_apm/mapm_mul.cpp create mode 100644 pgscript/utilities/m_apm/mapm_pow.cpp create mode 100644 pgscript/utilities/m_apm/mapm_rcp.cpp create mode 100644 pgscript/utilities/m_apm/mapm_rnd.cpp create mode 100644 pgscript/utilities/m_apm/mapm_set.cpp create mode 100644 pgscript/utilities/m_apm/mapm_sin.cpp create mode 100644 pgscript/utilities/m_apm/mapmasin.cpp create mode 100644 pgscript/utilities/m_apm/mapmasn0.cpp create mode 100644 pgscript/utilities/m_apm/mapmcbrt.cpp create mode 100644 pgscript/utilities/m_apm/mapmcnst.cpp create mode 100644 pgscript/utilities/m_apm/mapmfact.cpp create mode 100644 pgscript/utilities/m_apm/mapmfmul.cpp create mode 100644 pgscript/utilities/m_apm/mapmgues.cpp create mode 100644 pgscript/utilities/m_apm/mapmhasn.cpp create mode 100644 pgscript/utilities/m_apm/mapmhsin.cpp create mode 100644 pgscript/utilities/m_apm/mapmipwr.cpp create mode 100644 pgscript/utilities/m_apm/mapmistr.cpp create mode 100644 pgscript/utilities/m_apm/mapmpwr2.cpp create mode 100644 pgscript/utilities/m_apm/mapmrsin.cpp create mode 100644 pgscript/utilities/m_apm/mapmsqrt.cpp create mode 100644 pgscript/utilities/m_apm/mapmstck.cpp create mode 100644 pgscript/utilities/m_apm/mapmutil.cpp create mode 100644 pgscript/utilities/m_apm/mapmutl1.cpp create mode 100644 pgscript/utilities/m_apm/mapmutl2.cpp create mode 100644 pgscript/utilities/m_apm/module.mk create mode 100644 pgscript/utilities/module.mk create mode 100644 pgscript/utilities/pgsAlloc.cpp create mode 100644 pgscript/utilities/pgsContext.cpp create mode 100644 pgscript/utilities/pgsDriver.cpp create mode 100644 pgscript/utilities/pgsMapm.cpp create mode 100644 pgscript/utilities/pgsThread.cpp create mode 100644 pgscript/utilities/pgsUtilities.cpp create mode 100644 schema/edbPackage.cpp create mode 100644 schema/edbPackageFunction.cpp create mode 100644 schema/edbPackageVariable.cpp create mode 100644 schema/edbPrivateSynonym.cpp create mode 100644 schema/edbResourceGroup.cpp create mode 100644 schema/edbSynonym.cpp create mode 100644 schema/gpExtTable.cpp create mode 100644 schema/gpPartition.cpp create mode 100644 schema/gpResQueue.cpp create mode 100644 schema/module.mk create mode 100644 schema/pgAggregate.cpp create mode 100644 schema/pgCast.cpp create mode 100644 schema/pgCatalogObject.cpp create mode 100644 schema/pgCheck.cpp create mode 100644 schema/pgCollation.cpp create mode 100644 schema/pgCollection.cpp create mode 100644 schema/pgColumn.cpp create mode 100644 schema/pgConstraints.cpp create mode 100644 schema/pgConversion.cpp create mode 100644 schema/pgDatabase.cpp create mode 100644 schema/pgDatatype.cpp create mode 100644 schema/pgDomain.cpp create mode 100644 schema/pgEventTrigger.cpp create mode 100644 schema/pgExtension.cpp create mode 100644 schema/pgForeignDataWrapper.cpp create mode 100644 schema/pgForeignKey.cpp create mode 100644 schema/pgForeignServer.cpp create mode 100644 schema/pgForeignTable.cpp create mode 100644 schema/pgFunction.cpp create mode 100644 schema/pgGroup.cpp create mode 100644 schema/pgIndex.cpp create mode 100644 schema/pgIndexConstraint.cpp create mode 100644 schema/pgLanguage.cpp create mode 100644 schema/pgObject.cpp create mode 100644 schema/pgOperator.cpp create mode 100644 schema/pgOperatorClass.cpp create mode 100644 schema/pgOperatorFamily.cpp create mode 100644 schema/pgPartition.cpp create mode 100644 schema/pgRole.cpp create mode 100644 schema/pgRule.cpp create mode 100644 schema/pgSchema.cpp create mode 100644 schema/pgSequence.cpp create mode 100644 schema/pgServer.cpp create mode 100644 schema/pgTable.cpp create mode 100644 schema/pgTablespace.cpp create mode 100644 schema/pgTextSearchConfiguration.cpp create mode 100644 schema/pgTextSearchDictionary.cpp create mode 100644 schema/pgTextSearchParser.cpp create mode 100644 schema/pgTextSearchTemplate.cpp create mode 100644 schema/pgTrigger.cpp create mode 100644 schema/pgType.cpp create mode 100644 schema/pgUser.cpp create mode 100644 schema/pgUserMapping.cpp create mode 100644 schema/pgView.cpp create mode 100644 slony/dlgRepCluster.cpp create mode 100644 slony/dlgRepListen.cpp create mode 100644 slony/dlgRepNode.cpp create mode 100644 slony/dlgRepPath.cpp create mode 100644 slony/dlgRepProperty.cpp create mode 100644 slony/dlgRepSequence.cpp create mode 100644 slony/dlgRepSet.cpp create mode 100644 slony/dlgRepSubscription.cpp create mode 100644 slony/dlgRepTable.cpp create mode 100644 slony/module.mk create mode 100644 slony/slCluster.cpp create mode 100644 slony/slListen.cpp create mode 100644 slony/slNode.cpp create mode 100644 slony/slPath.cpp create mode 100644 slony/slSequence.cpp create mode 100644 slony/slSet.cpp create mode 100644 slony/slSubscription.cpp create mode 100644 slony/slTable.cpp create mode 100644 ui/_xrcDialogs.cpp create mode 100644 ui/ddPrecisionScaleDialog.xrc create mode 100644 ui/ddTableNameDialog.xrc create mode 100644 ui/dlgAddFavourite.xrc create mode 100644 ui/dlgAggregate.xrc create mode 100644 ui/dlgCast.xrc create mode 100644 ui/dlgCheck.xrc create mode 100644 ui/dlgCollation.xrc create mode 100644 ui/dlgColumn.xrc create mode 100644 ui/dlgConnect.xrc create mode 100644 ui/dlgConversion.xrc create mode 100644 ui/dlgDatabase.xrc create mode 100644 ui/dlgDirectDbg.xrc create mode 100644 ui/dlgDomain.xrc create mode 100644 ui/dlgEditGridOptions.xrc create mode 100644 ui/dlgEventTrigger.xrc create mode 100644 ui/dlgExtTable.xrc create mode 100644 ui/dlgExtension.xrc create mode 100644 ui/dlgFindReplace.xrc create mode 100644 ui/dlgForeignDataWrapper.xrc create mode 100644 ui/dlgForeignKey.xrc create mode 100644 ui/dlgForeignServer.xrc create mode 100644 ui/dlgForeignTable.xrc create mode 100644 ui/dlgFunction.xrc create mode 100644 ui/dlgGroup.xrc create mode 100644 ui/dlgHbaConfig.xrc create mode 100644 ui/dlgIndex.xrc create mode 100644 ui/dlgIndexConstraint.xrc create mode 100644 ui/dlgJob.xrc create mode 100644 ui/dlgLanguage.xrc create mode 100644 ui/dlgMainConfig.xrc create mode 100644 ui/dlgManageFavourites.xrc create mode 100644 ui/dlgManageMacros.xrc create mode 100644 ui/dlgMoveTablespace.xrc create mode 100644 ui/dlgOperator.xrc create mode 100644 ui/dlgPackage.xrc create mode 100644 ui/dlgPgpassConfig.xrc create mode 100644 ui/dlgReassignDropOwned.xrc create mode 100644 ui/dlgRepCluster.xrc create mode 100644 ui/dlgRepClusterUpgrade.xrc create mode 100644 ui/dlgRepListen.xrc create mode 100644 ui/dlgRepNode.xrc create mode 100644 ui/dlgRepPath.xrc create mode 100644 ui/dlgRepSequence.xrc create mode 100644 ui/dlgRepSet.xrc create mode 100644 ui/dlgRepSetMerge.xrc create mode 100644 ui/dlgRepSetMove.xrc create mode 100644 ui/dlgRepSubscription.xrc create mode 100644 ui/dlgRepTable.xrc create mode 100644 ui/dlgResourceGroup.xrc create mode 100644 ui/dlgRole.xrc create mode 100644 ui/dlgRule.xrc create mode 100644 ui/dlgSchedule.xrc create mode 100644 ui/dlgSchema.xrc create mode 100644 ui/dlgSearchObject.xrc create mode 100644 ui/dlgSelectConnection.xrc create mode 100644 ui/dlgSequence.xrc create mode 100644 ui/dlgServer.xrc create mode 100644 ui/dlgStep.xrc create mode 100644 ui/dlgSynonym.xrc create mode 100644 ui/dlgTable.xrc create mode 100644 ui/dlgTablespace.xrc create mode 100644 ui/dlgTextSearchConfiguration.xrc create mode 100644 ui/dlgTextSearchDictionary.xrc create mode 100644 ui/dlgTextSearchParser.xrc create mode 100644 ui/dlgTextSearchTemplate.xrc create mode 100644 ui/dlgTrigger.xrc create mode 100644 ui/dlgType.xrc create mode 100644 ui/dlgUser.xrc create mode 100644 ui/dlgUserMapping.xrc create mode 100644 ui/dlgView.xrc create mode 100644 ui/embed-xrc create mode 100644 ui/embed-xrc.bat create mode 100644 ui/frmBackup.xrc create mode 100644 ui/frmBackupGlobals.xrc create mode 100644 ui/frmBackupServer.xrc create mode 100644 ui/frmExport.xrc create mode 100644 ui/frmGrantWizard.xrc create mode 100644 ui/frmHint.xrc create mode 100644 ui/frmImport.xrc create mode 100644 ui/frmMaintenance.xrc create mode 100644 ui/frmOptions.xrc create mode 100644 ui/frmPassword.xrc create mode 100644 ui/frmReport.xrc create mode 100644 ui/frmRestore.xrc create mode 100644 ui/module.mk create mode 100644 ui/xrcDialogs.cpp create mode 100644 utils/csvfiles.cpp create mode 100644 utils/factory.cpp create mode 100644 utils/favourites.cpp create mode 100644 utils/macros.cpp create mode 100644 utils/misc.cpp create mode 100644 utils/module.mk create mode 100644 utils/pgconfig.cpp create mode 100644 utils/registry.cpp create mode 100644 utils/sshTunnel.cpp create mode 100644 utils/sysLogger.cpp create mode 100644 utils/sysProcess.cpp create mode 100644 utils/sysSettings.cpp create mode 100644 utils/tab-complete.inc create mode 100644 utils/tabcomplete.c create mode 100644 utils/tabcomplete.pl create mode 100644 utils/utffile.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..50ab838 --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ + +*.sbr +*.obj +*.cod +*.dll +*.tlog +*.7z +*.bsc +Release/pgAdmin3.Build.CppClean.log +Release/pgAdmin3.ilk +Release/pgAdmin3.log +Release/pgAdmin3.map +Release/pgAdmin3.pch +Release/pgAdmin3.pdb +Release/pgAdmin3.res +Release/vc110.pdb +Release/Win32/libssh2/vc110.pdb +Release/x64/libssh2/vc110.pdb +Release/pgAdmin3.lastbuildstate +Release/hist.log +Release/1.sql +Release/1.xml +Release/33.xml diff --git a/Debug/Win32/libssh2/vc100.idb b/Debug/Win32/libssh2/vc100.idb new file mode 100644 index 0000000000000000000000000000000000000000..edc3021d1a755ee4bade8df2b72de6e0895265e1 GIT binary patch literal 429056 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 W%z;}e+uOkKHk<>)Iq>PrfxiIsZ$je$ literal 0 HcmV?d00001 diff --git a/Debug/pgAdmin3.Build.CppClean.log b/Debug/pgAdmin3.Build.CppClean.log new file mode 100644 index 0000000..107fcd8 --- /dev/null +++ b/Debug/pgAdmin3.Build.CppClean.log @@ -0,0 +1,56 @@ +D:\PostgreSQL\pgadmin3\pgadmin\include\images\aggregate-sm.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\aggregate.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\aggregates.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\back.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\backup.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\baddatabase.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\cast-sm.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\cast.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\casts.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\catalog-sm.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\catalog.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\catalogobject-sm.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\catalogobject.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\catalogobjects.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\catalogs.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\check.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\checkbad.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\checked.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\clearAll.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\clip_copy.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\clip_cut.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\clip_paste.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\closeddatabase-sm.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\closeddatabase.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\collation-sm.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\collation.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\collations.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\column-sm.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\column.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\columns.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\configuration.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\configurations.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\connect.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\constraints.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\continue.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\conversion.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\conversions.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\create.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\database-sm.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\database.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\databases.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\ddAddColumn.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\ddAddColumnCursor.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\ddAddForeignKey.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\ddcancel.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\ddDeleteTableCursor.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\ddDown.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\ddforeignkey.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\ddforeignkeyfromuk.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\ddforeignkeyuniquekey.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\ddforeignkeyuniquekeyfromuk.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\ddgendiagram.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\ddMaximizeTable.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\ddMinimizeTable.pngc +D:\PostgreSQL\pgadmin3\pgadmin\include\images\ddMinMaxCursor.pngc +D:\PostgreSQL\pgadmin3\pgadmin\Debug\pgAdmin3.write.1.tlog diff --git a/Debug/pgAdmin3.lastbuildstate b/Debug/pgAdmin3.lastbuildstate new file mode 100644 index 0000000..515b8a6 --- /dev/null +++ b/Debug/pgAdmin3.lastbuildstate @@ -0,0 +1,2 @@ +#v4.0:v100:false +Debug|Win32|D:\PostgreSQL\pgadmin3\| diff --git a/Debug/pgAdmin3.log b/Debug/pgAdmin3.log new file mode 100644 index 0000000..daab5ef --- /dev/null +++ b/Debug/pgAdmin3.log @@ -0,0 +1,5 @@ + "git" не является внутренней или внешней + командой, исполняемой программой или пакетным файлом. + Not generating svnversion.h, not changed. + precomp.cpp +d:\wxwidgets-2.8.12\include\wx\setup.h(20): fatal error C1083: Cannot open include file: '../../../lib/vc_dll/mswud/wx/setup.h': No such file or directory diff --git a/Debug/pgAdmin3.unsuccessfulbuild b/Debug/pgAdmin3.unsuccessfulbuild new file mode 100644 index 0000000..e69de29 diff --git a/Debug/vc100.idb b/Debug/vc100.idb new file mode 100644 index 0000000000000000000000000000000000000000..cd7da98926e55b6ee988b643ab55205a52fc32fe GIT binary patch literal 19456 zcmeHP&2QsG6i;FKS||%zX%9$9)=DdZmbgyRX46U)q_&e<%9re<%~lqcW4oCKdo%CN zBt_fsUE*#A3_r);zt0qv9P@zXxY?T@2ucjnjaY03PPc(7$U}Osf1*c<07c-EBk-pUDsVM>!f&G0!R+t@_!~6?i;8cbI+9~{1$NVdJ7?ZFZ+=9?A zcy&W&_4LlGgp3CY6o@8@L^;{Bc`4;)oQN1nQY}&00?wv|Jx+&`!+e|#41CoINfjnF!Pv*JBG@KtZap|rB-SyoqUvDy-wqp_Iqh2Qc zvDzFu%EWv`)UMq!-7Zl(;4JH^-7=iEY27`S_8ptFb%!BA+q7LK!Lgj$F;qQpnw!Si zdIDEM{htS&L0gEr^9~+H66#{4k648|k9zqw5X#R2y$f^;2vAUo<##N2m(uum6E`gn z0PJ;bbIS@yic<}@75H`|>iij64uC&H3kUAgF*MV0)F$b+O?6`1;TJmXCZmEX+=Gy9 zP_+pNOlp8%6>8|QW{tM(n5qppbs~_)^?M-J{}?9=K=*o0CprB}C`g=Ox}fV>Ekc|~ zkck%s(5rF-3{yE^;_E3U{?HizH4L#B>L_UF#tK@{4KUCf#?q$iD+b&lWV*(-?rU(( z4diVgFT=!x$DU={&Tv%1k?3t}C*MB! zx$@ngOD2@fwe+S%VslM@F0_Voc5BlOS;Nr@8DX2Q*_Um%9<|(V3!4nfe6S7SHNxhO z-Lg!}33L+L60{#^V?Jfz0O=kO+L&h<|FJzy6ak9BbOf%V{=*1L=l^v6k8Z}myBN+b z==}e%Cj;~Uz1_WC9Cx4MM1I-~&9@A<>9L0AO%v@qbzZ+gf^{2T#NtBeLWaKZYIaT3 z_;RTvm2zdRl9d(oTf@?F1sr6hpz-p+NK^>YWb{kFENpj${km*vMqX*!qHm6GxD`Ycc5&X{^JLWZ7`~Wwg6-EXb)(j z2v7tr9|C6`|55i*=SRo?$R5!6-{t!TXpgTi0%KMZ4=rXM4G1i<3kNGaBWqNL>gf6( zUH^MYE+36C(LE+~j|u#k009C72oNAZfB*pk1d1&X|M>+00t5&UAV7cs0RjXF5Fk)&fgjw* B4Q~Jd literal 0 HcmV?d00001 diff --git a/Release/pgAdmin3.exe b/Release/pgAdmin3.exe new file mode 100644 index 0000000000000000000000000000000000000000..50a563235be4c9dadf3344f5664872bd71cbbc34 GIT binary patch literal 8907776 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 @ApdDn? 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

BP>^-g<6*;gD1PS!VYqg*`QpCx$xcV5X7Iw67RF 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

x{tU9P?WjJ(&uYD9xA%&VZ3pG7k4{ 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�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 z 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%0D3jUp$IiOm?+y#n9{^D~8v`Rk{lQ7Gp4^%zL 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≺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

  • 35q8zTW#X2mMxJtiZ?&xO(a3lXL*B^AYVDO;4_*anH_R)JqbuS{}~hT{hrXL zDNp!Cn`HaXF;%NXAAKMojdeXOrmmB4HCEy(Krl=fgYKKGVQqwO z3KqEr$_y-$-{&qXe>#=YpIIg!_8k7f!zUGclYeFBgXFa*mWYvS2MK&!?spfrC<_G= z9_+sqXt%@UINCf^okF!*eFsIQi)27tF`KWF73StE@<2e^ZN4ZW_#b0FOGp^r#XPAh z*dRy7x&MEwbdO_sS|W?EfR24@64 z_clkHBikBsqqu=jnKaE?_ZX_iK+h%q>0)%c;n!MynfdKkDG?^8b2B^`oO*3Hx)HXd z7l^ol)4K-)Eu1CNw!*s~ssQLBIQm0#2$Y5&*H)Nj3gNUO?J)HOu~-eR(qrX^#t82L zj~B^#ll|J-D80PR(o7WRS@mrI&&_@{J1jRh+V-#PXD{J8=xizc2|3YS7Jgj8HrD|x zV0K&-e*C-gf`>FG@_LlMPASZ(?W!4S*MS?ej-S!KN4R9$fn{$`1gO0$rJpeMa@&~& zgkzqDTPV?5h#SCeZUl3ipOA|zf!dz96_>CH&VJRY)(qjzG|)Qd^*T&=<%2SF1aW7% z>Ef3oa{S6r{()z&xb`%&=U@L?=5MDvFy-M&tj^eI)=bTAdHP|->DlyOieap#6FvMB z6OX86-IfhpmFjv~PL& zb)yTBnN1OBFxXzkVuR}KX}0nVWX|Cge{c$ZEj0PU@_FVrUt!Fg%C{1RH>QG|x|F&s zwGH@qjBS8i0P3kKvP=A|U1A8+fC2eAOrJ4(Y@Yo#UO ztnkOp7)0Y8BTq~}th4qQN*kH5$ae~`7XK~{iqlIMn>q#eBf5=$CYA_&Ek+EPR$3Ms zA8+j&_o`U)Wa6jQZQFb0UmH%yKPNn6cEV=PymRIIV6J?3o%4(Mj)ZZqa!mKNRj<}u z7|IJLZap4XKXK`8p8B{4v0ksgBfK<}8~)Op>@-e7+O?UAk6z4q(^kG4N2mJF6P2x_ z5&8A`I=58ZRaPDve_>g*67QqG#ja@c-ky?mFVgYm8l;HUFh#%#l90D<55GZIXbFpu zsf)%Eg_xbl$e8cw$;fZgph8_6Aq39TtoHOs*P z($-38C5c(>fY%C8j{#{XJ?!UKMAm~=wWi92so8k+g46lGO#m~@zx((oV&k&*Lk>2ndu!#8%44{m8Xx|Xcrplah^VUTei}MwHNds@l$imN^aBM8` zpX+zyAOZ^sR`3mKFW?PaA%s5pe~mohpGi9hstbBXPs&Y`X|~||I%pM>_!HnwiWx@) zDfmgbSLJt+|8f8(ds{h%Mx2ad?eU6d{uG-YrzJF{U;Dysm)|~$S9!TPyH<2MRPm2{ zr0|sN7H2Tj^GZiz03J{-u5@RIGdG9QvJq?J<&_0j%bOjV7Z$G%TuSY_!1Lsgj%1D^ z5lF}s-|3mH4J~)L@JN*GTKcT;0FACxj%#3t*owu}##0^iAESZw6TLK?;n{YgL4YD?~be5I(GCrfM@BpmO zGl(1=*5~x~*yMUTdawIFo$GcEpp>qGBFgEElwf6Smi#ZLmz#@QY!;jb<7)1Fr|>d1OIWWff>u4o#sHYb zG?KKc^>$RvqFEo)p^BrcS|rhABCy2&;j>a?%A&<~na^#r0mjgoQkreL0?A2eOlm3! zbDCmu78cr9`Uh=I8rAWa`q~X~q2dkJ-kNip;xXvPd^>(>Q+#6rW~G0ndWiS&b=`eXsOTLg-H4`J#miH`&wd9d@Ryn|qq-Hi)X|%fCPd^$E%*z7 zKV%vHa8<6||GPxmNdMpbYYb}QO)C}zM!!DE~f(e>M-2`|dMPj2(}4O&&C z{Fjn#W|gf(4RSJZ$x$ykR6xo~bgb0;@aH-vFpR2Z9y@`NN;D;Qwf`vNr|qZmJ8DFd zcFZi}2_Ah;9*&)YOB8rC>5~{@5+d^zUy!$)IWIM1dVxj%^_Z>ylHO?;uVDU%8YqYX z@9EbPnIjQ+%$IC<4)6q?m*vq9p1oLO+VFh$)+ju8Cq+B2%-kFU&)>5Zp7YNh9>?Cc z%z$@qfV(t&SPh)_h;;&q9_ zJ>-%}M|XBMV7kn07)pRtXWVU3@*@2w>?_1@q>W=T82Ny~vZkl^>jpa~N;)JUoZH*4 z$z+my>Dl%!by6vO>%)3Rm(ZF_7&Vy}`nZvUerPIuzTVxcx?1TvbvbA;Z@xX!j znoDV4TB$koQxSp6nN+bnNHe#NlU&g1nhQmDx;^G~xtVLf?D$on_E_BF8+Csvy;5_Y z`Q^>>omjz?zupU;xkSH^2Gy5mFeK*+ zTlLT-dE+8}Ol_B$o_ovaW>N5aR?Q-WBa3BqGw@%{GNhNC?4i4Z-w@}m2y{kNRSBJm zH#dm{RZ|%{+p(vm^;mBOzagSo>l;#jM@mRfhX$XJG-`oh9&gptqymcHYlmf^@%0$0 zi|3YbPiSg90@;R2DW$z*ke=(ZuIBtwsNpN5m4q6;ED!Z}I%T-}JCy`ZHn2a@ECdT3 zZ>RV8sWmZ+b0+W%H=2V^+CM((@4W=@h3V&I z`bE7~VS-m}Prrqm@4TSuL33)hl@Gn0aH8f*1M)V&2;76YW!+?&6)JJGeUW{A^D66lbhX(J1bW6pFT@MGG3-78Y_dss5g zd@#tV#Kx^S?R*_O#(mOO!t?tpR8=VlZw)~ z&P;|(EY}X!G>ZR6iME@W z8a-yF@q|iPT}*-?y13tchS$uq+%!G0Znfcf2Yt)iFP9{4i!Vxpou4j~Qj8;_X5ZcB zL%0@_*~8c}Zm3?L_#p|3B|jk)!4fZ1H|t}JtO}>m1PF3^=>Z5iywa ziML0P#vKLr_z(I58=%4{u(mf?+G1WJn^>9k0{fh%0GSw;&D6<_cT_Q){t0i8<_PPL z&X)4+!w zr6d+Ff3CXhtS$;_io<51_!Dp4oCjaeS8!M^6j63b_Lt0s;1mI~BgxVyw#PYJS6qYd zIlG{c>j{Cgr2K?K;ZBMFg#=Yf(Z-s#Pf`8|DbNNx=xQ>L_fN}ja+!xTQQBe+lkB0} z5`+0)bDO&*T~ihZT|Zwd8PLK=HrL8UH*VI>zR_|uo<>M_7D%D=!hN|8(?GI6rT;2o zw9Pcf!dI4Bix9ZirHPYyuIo8p@udxVE4Al4zFuf*>S zuR7wNAad~|mfPA`KQYcf*b3(s5U4qtdAzW^gaht!8lCNb$n|m68>eKpXZCdDI^>@N z;#nLQvp(LmmD~F+j&J!>Letlzj)biVEeR{7(rJzP7t0K4dW%cG_rU;A*vvUr5+DK? zu=a)RtIAf74(CDgB%3gi5j zkh^BEU0R$!6)XIj#F-sW;#olu2A2tSX^Vr4@Q!q5+u*YpvA$V#{B(RK6?kj!C@sgO z!``r{+sDSL+pTtn2D!PXYD2DWHjc94C&|{f2QS9Oo9+ql0C9me((`2g1>vT8=}^bl zL&CPkSr;(CneUb-Zbm6*{`3_5xH$Su!8ycPFoKFtZUh}ENUdt!*6rSc#KU-qyIt%9 z#6#RQG4=s+$%&`xTQ?YJga_9cUy&C>l&_p-22XqnUBOXOe2E} zQ~WnIHEIj$WyBhb!=c&niClTv6LDYR>!DR{Imm4qep9myYZUfFo+k^BhwchDeXIA= zXcr_r-?%W`=xOSh;cpk%7p62l*Dj$_z~GwJLRS~QiNgEJ!}~f?s`6!Y z;>>^Crufu4NIsXn=VGikq$K~<_$;IZd<#vOtWVIcb&w>mEusOp>|7Ybgz{n?U=XG-IuD_`N`&avPs6R5rWku2m&9|Kd;m#`HSuHgYodH zT6Qo#TIhNg0LPHyz!Ytnr$LO!=tbG@msfc|%3`d`<@v*-nn+|NEjfW^ay3kTjvt7l!T>}dMhzzbII0=wAi>st#H z8CwfdO8DHlRj0MUEx6NKAe#XmN{1;%n1J9XU;}y!`X9uZ^e8S=M1L1Ec#%e*;z@rv zQ>5lYHnK}~W*1^nH4QFVC)35aR6LEdNYPBE6i&L+dzVKI;C@U->ZWf*q%=Y@vl($` zw$2MqO%svP+_JiKvngM4r3C9x3B1-SoS#c>UNYatlWZh?Yj64~;O+lP;IDOy30cjk zs{LSFc*F`ELieRs^w@C|EzSHu( zp1bb4b>%y`pG>Y_aTCT9gXJ!gw_ickUfPlDthcszvNty3o$Qs39hW4&(zF?8LwTVz z47pMge)F+S$f5Fw{mOcQuUOCa+}K2{F$oFMbbt5Oq&UYD(zc)3;-Yy~?!2gf4b|PK zuJgyv>j4^Ynk3o>3uEnR8d85WZv{U$+%>3v8#{k%uKJ(B<$xk* zuHvW_w>9nrn_bCIe>7cC7T6`45I5#tS6Ho0?gFlV8J&CW4u3Z{Cs{pBsjGfdGi;*Q z@5;^Vc#BUuUU8Jsix&mj!Y8!>qkMK+;`*e_T#Qs2TvUNX#3xjL_ZH-z3)vGLIi`aM zK&|O%W!9I{%dM|??VD%@YrVqeyxoo%X+=&~&0pA8(X^FCqW+Yzw!tLX3yMStPb2hFx#7!04{xW#+qU;t`B-}MJ zy9Iff=Nn>d5pwxtM1e73mtY_PdvRJ}w-y;gj$0dc}&%+j|uLIX--3Q+!RTJ>d??gtL!~ z9ofs(LP+#uYdHyUBuoAC-GMIyU$p)iY1u6~GrXSfQeXcs$uHuE+h0AwC!4(8u8ocjYR7-47cwgwg#|c+UEXjVi$9|V=$I@5_dFPg#C3bkQ zQwKdYp>h_L?WQ||(=&q8(_2?|@wNQhnl~ygm{&=k{fC^UQwg$ST zn%00W)P#7G0(|kjIfo|?p_1{f0pSA0i{sXS%TCCW*ZgY@j3*?X-CF|_qiMN>k~A&f z2?=xMvRhyEXvWv#f`Q4rX$=(dD_%NU1EQCakPRojQMHEH)_{lf_^pBKc@XxP26L#;ORmysZIS4Tqjk+P5_11Q~! zzfJ~SK@1hUF?FENLO!f{X4mjKB|Kt-Bos?IBs&S1W0Yrrm2(u<(d`u6Yh=VvWaY3y=5~VJ6D+=$%08 zHm+>pam)93%&w${!B%`(xcLC;0Bd%J6(26~hVFI98#71dM(AFL^d*N!+#yxp>k!7I zNZgrsgCcQO1wtXh zBN_p~+C@}Y6$Fy>dLM*3L;Hx{k$P_-dwjRWjBnYAtC@_hz;3rCUeF)Fg-V>R9j6s< z+4Ubief_OTg8p_7+BM6Np1cQ7Rde8w`_K1fZj>JuzUz zx8U^fozZwiAY1gFAp@SdFx=^~MYJ{|y<8$klXjQMJ-QRwn=*?K0uC;-cH3*EwJ?JX zwZ6`URf^{LT$#pXIqg_z6CwHJVQ5NDdu>apM1W+xu$nKZR@2I=lIJu*AX7^fRbF#s(K3TCA;X*O)09a>QTmeh`qCl zO={)TBH2Vfb**%fFw)LS6uVr((ZfO6FA|(JE4og>@}O?-Di3T-iBdyp$<}G3PNaxu zgUbE8LgVy@cpgfzUPf$J$}-X1&WaJT?6pbSZsBOQ=ISy>-XN{gg{Q038c91C!uy-0 zXLeh!(OxINzkSi-8_$RVsDHX!I;SZ|!ALs+OJ$^68 zj-OaR3^0D|2a4OnBV?Bl*u2Er5v9=DD4d$sd>HvP@N0WYG_#^CDcTOQ_zze+!Xsog zrgv;qu;j~0kF(pf=UL={(G`Vkw6yK7)tiR z@S{rXADt6n4uY#?w-eLyiy{ESdF;R@R-)0~`s0bhLB>m1#=J_0>Jl#t{aglCz7%o; zx$>@;ElQ5hy-2pV;It44op{>Y7mMQ2-0_kN35UE02c4J1LRGnL5a)H zKkTWS=H_Q8f9Kug+2`vfQ0VSBPaphv_!}O1F%6B)F^L?k|CQ`JWn(vgKR?BtHFbbp zgsK>h^KCID=t=NjRZ8Tim~T*@v|xTGmF~HHi3Il(+;sbVf^*!SF?$YOOL0VsJM|@p zxN^mBq~%K&*O6~|D);7M?Y}4DOA<@_J#Tp`_Uh+{jw>XU#1@QL&-ny9)o9b57DxMl zcZF{1p61rZC(^u9>3}&T?(^*@l&pgH+pgdx-?Q32waI=NZ%1LA$*34{G9xt==xJZi{Jk z8?D~n0ZvwK=glyuwdX;L0-az(>MTKo)U?rvpAnBR&)&CX^aQ+pzY;hm`?St}){!U~ z{BUG;v$Yv)d8^}DXXm;4%<|t^yB9ACUnZpZl%NQ`DR#qsL<_$pQh15^^S{{)VJyx1 zy;625cR=F7HchyRnDVaSXsSbuxMH3a##!`U1@z&7z5~!f5Vw^?WLMa0y^S(OZgV+7 zwkHh{dVqeR)Oy)}X&KwVnUQUv1e|SPByACNE5elsZ+2t9o#5v0ZVR7|xurh%?UB=> z{I-3Y`-$tP>~Som{>Yev0a*q>+k!D5+%$f?1z8fxvI-^!r%kj9CI_cY4i)5=gl0N| zEzgsyMK;u^5+WkkYeasn)gsUes#uE`LRuPCuth`!NR28+qKefbMG6&EP-q2}sZhxg z@vN4eY)QzHhqJw3EyARrEem^cwFtr*RUAgC!!#nlL_~Dfr~))=^?1TTm67qnt1sl2 zh=|}CRS;*b7RgyqwwOXWS!GQc)t3_UBOU?LIFWI?zmC^?GaQ{aT}Iq7k|T%l|@<2mYN~uEXH5kfh}G_ zb_Td# zZWUEpsp0!oV3rK&-W@LKOUGl%;kvroV^tG3BUuJjb0<6(hdutsL-(c8{V}zTj$vFa zG}~?A`yZCtVyEQm{}>XikPo3J?XBq-g{}V0t7_Nq}yU zml^2G2SO9dv!)|HTo_)G?yOgwpJ8!0R{xCF;aRnb`mv*$9hs7H8z)=FoBPlY$i};} zDHg11-aTF{v7;*LwHtw zf<(s676~Cm>OrjNR$Z@X;@FXdZy#gH8ZmFIr8-2G{5eJ8+n4by&rM{b&9+a~jP}ki zwYY`dPMiILO^%bwM#nRTJy2yET*7?$;rKa|+3dd*5kyb+5lp?U-ND+FAZAM=9;Ish zlC4@p$BQen7A|Bq*6TW-%49j1Oor-F;uvkW6_wo`aK;nTHAU&m$z*q(CzsvPfwuV0 zlt%|s*pUKjM-;N0F3(q&gHIOyE%%buq)Kg%0aCds036sWI)`f~YrAM?al1t5l+@xq zM+%p@Jger5eD3xXnI*RP#ItIuitOxtiloVSHC#br{gk3-x4_Rfj3PoozLt=04{G`L z5qThg$g3QD(!)OIJS65UV-aa% zBidiX{*N!h0};aikEB8G=ZZm)Ew+d(QI6i&KU{?!VoL*QR*uKrOTODohxpWP*CDsIz5rnf8_DuE_cgs7tsY^lJ z!Z8>%fUNWkIO{EhxTVHD7B9CiY)XfsCirKDiq}U(tB=?L*7@Q`=8}%BY8qr*J2d=RoeacN&~-kr<=;L-(B;TJL!moZQV$7x?R>^LKIgO0 zL|&crORa+C&>ISgpV5JfXUS|6Md&xHdIwh;;UJ4|k9K4fTTTF>7*WzmAeZ`k?E2+o zcyImEHIe4&lHIR<`Z!wufz#9P0N7 z-WQ1c_r+oHvgY#qLx#w*Wbd+lRwflTypzrb-tqn5MM@qE@jcjQqU$;V z;+6=+Fa9GC120p8Aq?SWFbP`NH5Z!Oyo%uqJR{^Lu4Xh$m&%2C-kVR7a76rV69$bb zQc>K~F@$Me48`;Mx@6_G=Z!2k;^FyJ`*v&PQcCQzehEBcYAtBRiuwTWt&s@lu%8Uy z-$;xVZHOpErRX#klL`)^d4Bdi5j>-xwi~cQzN$?@^7M>nD}sD<DSgbVIL<(i8juZ+8DM##$v%+J3wmhzlzc2H5A$|L= z#37r0B5@KMBa!6W^h!jz5frk(lODwpMGm2?f*j(UJv{om2Y;>vsBjEz6$%=iO-Upa zW`O~f8?CMMNP$~@XhBSQA#^vwe8TH?yy%+WjqFL5^no^1O)LMxIP_L%EWgH0zbA^zBN$-s zShHJ1WpJeC)~J0OCOLD_QXgnQ!q6ULjMpi+SM0WW!XqS@)8ij5s|4HqokZbeT(&27 zzK?QvqEA@$s((ym^Bab#5@WrubC55FFO4eJkO2>rd_rHmmjoH#lgnE!SX*Vc59j-O zSVfpWnP)L#7fu$^F|DiUn61vcQvkxD!rs9mAN51g@^UE{!o)Nd!9!k=ga_m+-!FK7 zzxmAI1y@ASB1jf`N`6tPe9XE?RHiD=u$8E7;TKS#o@;%gZ%+U3RZ-lh!TtJ%_6RSW zbJU;A_FJZ9^k79)c=91Z6qzJqC-HXb_AqtzwIO^>wyW~-BBzjkwe&`*FL1CY(3vIe z3e6fl%1WNgBLkfPLK3(;y$bMPe&(v1!qIPW7Smrm~)VP~i0$`$^<|BDRbsOc&SAmx03j=z0O9%SFYU~GiM`Z8O&U2oNkF-v$4 zl@6-FA`x9+{%F~^pe{fq$ox)5fm|K?{GfMcQb_d|AEf&Km8d^0wtp@xhwW?haXUsj48SW^~Gmud~sxPz43yxe*Pi zI8A3vdR%0?bL!17xFvx|^|m*Dx>+SRv=_0cl8huEEaX!Yp|SvEi+Uy2qYfN+Cm z$J9te@RM^QAY*7@e?YE^ltBqKLjx^|>}2Z_agKIM6PSMp7wB)+M-#g~<`1wuT5noO zA|@7js>l!OWqy&;LP}dyqCkTeGCma-O{8%|ZfPTOg%c6EYo(~_DlYQwZ;q>agyEFe z5@9M`WD|-7N-&@=hi~$fPiR&@)v10%VgB`e@0a4A*PArOADp1!50uK*yl$-*7Jk zhtkB3zm*cefiYOBno*!pRvEE*H-`cdsg>$j14z}hz*IkVb@ zed?`u<1I1mW+qF$Cuz6z)POY?y{DQBV`~;JPg-1^Kw~3~)ZRW>t*mQ%{{CKCy!+;u z77L#lX>t1rBYm>EP1$>@d46ooaCBTrX_rsTiq$hzkC{`|*j~*t6@N_ z#nOR+4ZWQ%V!dE7vrq87Sqe=Pi)!!eEQ~fW$*@F>h4$Rah1}UBHdRC!9B7Wx8)fuG z5~9mE3-=e~J?7@5XknaVkp;RSE8P4DScXFs&fr0NS$5RcQ4Juvc_ZKTP%+28`j~@I zVT8Q*s}{zgWU?)0IfJv)17U@|US95t>MK@ut^t&Rwv^VloL0XF(_8Fr1;RexS*Bconu`tFhth@UjsUbzAQ!&dCVP ze-ti-M7cb@(yku0QVtalr=$)S@Js&Hx zXslpV4?3k_E%QY@G2rEt%k3jZp>=t(_|767t5Ix7YerTz-*X?Ax{bK`DqF<1%y~X4 zXDkyX*IdR*O)4=N?OgF}pQEVl6#r_?B64AtE|Qgqb;)i~ew}$m#qJOsDZ|`6Sy~W9 zjsmPpzEA1VA=fkYCk%L>9ap61-rLje@9*{Y_sY(EKpH@W`{ofn;o|atCE`mW1A@nK zST^-fA=rcAhIp^&0;h=~$*knxnQx7F8srZ=vIw^>q}p%`eAELc@$HHzPxXkI!j5+sev1yKhCoKvrgCkzS3Zw-!{Fr=|NgQaj~91 z?pz|rr$kSaT;quxUs8L~6gFm1FOGyXGR5U4NzbYhLLqFx`&)gm{@QjREspsI#-k$M z6a&%&{OwVlK(iQs;Jc!OTosAMW zVC~XpyZ-KBwSGWW?|0+tz@D+bHs^JVzFx1tk2#rycl6x*HE33-cufS@u3lif0CJ5g z^I%%lj8{s01VFTyHTv75zg`U$obpCaxCqeja0$m zkZLJoa{XPS1P%Sw*4?wHg&`{L2`^vfoU*vPh%_-UN@VaV+r;7s35jiqCh{4{E+Z;C z%tHLI3xz^`73Kfb)WkKK8#zYbYM*o{92H;xte8^7`EUAwtNiUAt&$Ug16p*vzxdQ| zyweAuFX+eWf90h^xxM52{4)5pGSTr|?{MBY#0-~>x2~z?{I`$<=z%6>g)C7HIN}m9 zD2O>PsK+7oFlemw?R8tB%#O}Em3wuc4WyJ2bqE3Hfz~cuQYjKWwVDtsg5R^N@860u z@3VgW5pjDHEkN-<<~~}X4e&t`TP5#8P|5q5G$ezS$XvX>(f^0Nw*ic^s`7^?ZQ4#D zWoDp(C_$qJjZ!62&|<5mq>}{Ow9}8I6G>WJ3&x0UrAb@Y77`}?m_AI&A}a2pBC;#H z%U^Nj4_#qP(v~KLz9m4#AVmUJ_le26LAwyvF7y6==icXQKJw9~toy#A%{(9Xx%b?2 z&OP_sbI(1;dWSJki>a%=ADcJ(xh&!iXhUA24$IT0qUQZ%?G}44>;MpnmAXb1Gc+NvhtN*5k6K+l<*K`@;NuC0f*S=Gdey zXR1=Q;sT`=ACr}_trhb&bUsx{hZF{=_PYa1%bx;3l*h(9o>5!DQi1 zBg1hpB2WXqvKKC@$v=s8uFXH=Sie?fSl`L`eaqLctIo*!bybG`rLJGc&?k#iC1nbJ za^9NteaRWY5BwI>{7ELlKXXR=Ug_i4rsA(Q)^)9GzO#24FjpZa1tzO&J(E@1W|LCB zrlI7uMO@#fN?jZNk0e`Q$P0$C=j7S^fo@}oP)DDUJtqwA$bzxt=L0$37VY*Hc-pfz zxTs0-^g#9|d)eXxIoaAx;kPMo4ZoG15q>Mpz%Qxe(Z=UR#2n0I87*&@H>7@NDIoUu z<6CbxjwAB)1sVs4iFJGmROBPhzjCrEvaVrYQFcwhu5Wzs-7pUL0M+>Yp@x1( z<@xmdq3*Nmpg&aAsrf^F)~-bPL%n$l{!s6<>HrwcXT>`Idt2vMrp7ua(;W)*0tbqh z=jaPMwVn*@{wCCe!I@Sx(In2lJ}4@_avg8J(ek@CZnM{AQ|)j7Mz0}Dv*eBIx%yJ8 zwb52)S5f!Nv@(M>XzsjL7D}=TXMSSaVb~fhr|>KIC}qqYEOD`#INR7%zwNa^`_HHq z!6HHW?ltuOIKNKTh6 zD|No@H)p7C%W_e;x*vZeULq@L!fuaUM|2;IGtlO7)<&uJfGD~Tb*ekDcy!s1V7hn| znq!31P!BF9d6fzL$$81?uE-3w`$8v?xE0!$SjhY7YbhbjT@z;N0#TgH+{-(}TS}dC zM!r=r}-gJ{<@6I8lX}n|uB$v@);8ZcF&3Om#Wg!J&}Yt=7C& zAdg#o=qK&PJzyO;8N0j(d-0^t<2^_^+TMd;6vun86BH-wDDOel2;Yy#eQ*T4(*l;O zZ(;pu?t@@01Z5%WYgvWlH%Bnv@#l7;n46u%sAo zw0G{@A)9P7n%5*d?nWai0o?-Iw&7t~$f^w%{j>Rh!CXp zl9qHqPKtd7q=FW18voCsv9Fum6wghf5i8!s08CIR&hq%s`NFOG(6v={4YM)Cy4Z&Uad ze9Uw3A@|lsBFd-tZ?>y{iK=E5pf__5@jd&tYk#LXr8tLO-PuM~i+_vU)jT#c)y$a? zGiiK6pf!IWc2hl~H_$g$d&Xj5OR!(JyR6WZU6wZ)DC`|Es9*47ZG_;SgE6?8qwx(4 zL2WJd8x)YVm$IK@4DKNOqWlcLa=SISgDHa>f|Y~&hle=08TG*nRrWi;mrlPF{!DHk zl|Okt)UlVxhGu6z|AK%OvyNlIu-cf(MGm4Iav70W%7kxVQmBH=hlagk+fGb>EyNX# zD*geORhOAL3=so-17F{A z;|tjU($CWx&&L~v>5AN&p28yD0B1{kmbuAj7`CJy4%Oozt;~doZHo;V?MA#GZp0Go z_ArSfD?h!TQkc`gQ%uoK9siDdWmRd|J*ne~x-duE1;FE1t1fIN=$8O=%v+qQ3gQ*@%??7yf>CT+`dZA5H98i7!NdH3-b55qR9I4@F;pl|3G_@gqr7+~mX2 zI6$ZOxYc&IP>nRVZ0zQNe?=n8-46iIHqq||y+F1HRxz2X_-XB?xYyoKVXn88KPvmq zX(7E&r$moh>;u1Q-huSq-P7;FQXMcnO8yi6Bo}mVzd`eZC$Fp}x)grqjg23S*AJl; zqKV3o=6}$SH>A|qgW$b^(;}sStl)j#ffxEv#`&ExhG8;>;5mUQo56-98=~N3`eC6H z4^+Up2q^3k>55p0lFv$|JJpGB6H7NM_jZ;xj>NiD5?slcYaD6o>flggB3zX=muIV) zFqP>sk>`YzV!cArYQ& z1O(>|%*R(#ZKQ{v1i=hmP0c#?B<$nV)MZxl#~V!C<`tXm~XshEfH&l@mmsDg}IK_0CjXHMJst2=#hNo`X>Caq}fu2|1Q*sA`e&D3;Q zw@%iKk>T8FmgIx(?c~*U_}9JN=3@8Mpf;GsXLvb9S}XeOanUDTAGP$GH(xwGdHLE* z>N~lg5~-dC#VCEw823DAb$8%LwXW==hYxq>h{CZ@6pn%0y)W_6z|G!A-tvFpeTni4 zKjzr@@lIDt{WC}MX>7pY$8b)Xxu`uwvm2AP15d#n)#|Jb&$>@J<0%Whx@At#a>wkO z%NgDg?L4Q3%)uB2$jvL~oUBG}b|4OHGmyhx- zQG)NG-`+PK{&A~cnx9L~bMy1%u67^&fW}J-gO4>ess5M)E1WKT*{Ukj#;Y#B4%}g( zYvDM`$6fV@#wZW`yx`y`t3C!T$k@&GoX%#8*kgI>fwoI%dwXJW&T{pfwiXE$$Drir zc*-KgnZ5ZL#K!3bP55i&D~w)%Nv5VBGf%{icdPNoe#M(mjcI=5{epj(a4_UCqtNCr z{xv2oe?2Iq4T-3RioePLD7uLPL<=e9O|KqRt-dns-{M#L$>0q1lgFizxbWW}J(O(S z%Z(u)g5Bv@0r%og9WB3`S8mhVIAgEtA$wXsia!+m$P7C}=lY}z`L^WdvvgR#kuAvm z(+e0Z+c^Nj5%I8= z4=5)xP0B9d-SxFiPJNh<=PY*g-Hhu;?tVbTuQq3)O|?7m0Dx^OG%tEL7W2xIZbg{@ zi<}D^2?Qe7lHJoc!_LHvlTC$s5{y4gscgRTF3+cU#QlwopT-|1nGJ*A*)yrlt4$Uc zH3g9s(?GR2u>?y4O48(wsrp?QWaZ4#>zb-*@U~`ZfY+&bH)2L@WE?(-Hkj<-fPqrmRET4*+r9?AG+%y) zZ3u%=>!fiJ#|x}s=V0_am3+2)h8{UdXXNZ9pP2W#J_Ntw5kGsc`?L67j+IO#pPS77 zF8&>VzDE6gtcCg z6%6tBN$`N+E@JL21f$H5W0(j&fh`d8i3i49B8=_q3OLa|`1cuyf3cyFY5N=57q`In zXOv0ct`;~zF#C+z^aWs3+z29cBXA`yQQid0Xaa#zQMnQ@2n?okv4^Av_3>1n--MM! zJ;JY`%V-sLaH*hji-(`b?KI`0hwAUlCH8!m)jvW^hFElNP3)yzhs20n@i-F8HlOF& z@>L32V;+_rEVBxhA51vMuxH<&%n#N*?n^#IGo&%A3~9b_W=Om(Flg}%xG2Iyl*H~H zZtbau7=q%?&)n<0Q|Yj)@4Q6+Awn0Hc#>-^gucn>y&1eTQ6B3nEG$%(aOT~52O>fs z$c#Hbj`{1uaCD)EM*%t?Xukl18_npkXdk9UNCD*6@#93SJ292kgRD}a8mQU9T7*>A z$tI$`fKE*Q5@oNZ-<6(fH$)S%qTD-sldpAe9_1kXADS;kI*KxQ>GvQ&G2H79l|f|} z5yFGx>eToetZa}71~tzdoQd|t+MJ_ujY&cW!oLQ134Vi9uAK3$XL#mmB_K2&&x|0h z9V!mh7th1rCB?+yqGGJ7g1SR^R)l8~3|j9HN-OmY&r0v09oQC(9jMZ|MhXZzzLo`I zj_ytKWtqA{h^(#%$f`HMTgX3{r#c~4b^^+OwFFBEQ4RGXfqIn%H6mRDALw6H`Zw@L zU~&=>O2`O@;1a)UN+s5Hln19(ga630v8w+h%3I%m3BB#m7X$+seU`qh*C%zp`KxDPiD&=+qTC67Ue+VdJ3C{vgnRhFq59nhei>V zMx)hcanB)~H_9LY$G|q=Z5a5sZnr%gt+t8oB^%#51wflt+~LIR@q|+HSl)`ihm|s* zO)K_U%8$GLU2Opf3uhZ-Ph+PyUrB4qeI(`n&Xjw9%6(DF{R1iY^St-F+RpL7v#V{E z=l(@Og#+)dwpE_@z!&g@^jK{@c#iZ~2n%vkTd%q<^QXCp(`M!B{^5a_e_+#!r1jW8 z&Q=VTSfAu_)sys*3Rw~T$F)v&Wv2WdYnkA~fjtxJ41C7hKKhevnFE#y7vVr|YzX|T zMUOs)OSvQSv+^-ns0#QkCd168b3bxM8GOA5GfF9E@{;k14YZF{F@~HspIR%hrr|^;{rMQ@CCK9ckD>bb(X=v=n1Tb0W_F{(p^#*(|E9k-DqI; zgJ(AeaJdjF%cWg`9p?#~UHXfSXXE~Ae_+QHJYZF}G4BU+4;lOS`hmUIe-r5Fdj0vc zdzPDb1kUos!y|msm z)viS3F1A%{esAzla;5o?p|gCo=DqkEJ5Ywi94hc|3E)x&OsG#_1)1oXT1yg`&Os?Y zQ;FopN8?Q6=2V}J&EIO=f$Ts7z_*Y?7SKE^Q$KsA-MmKR5~wa14tLL9)L69 zNO0Er*tbc%8k}e@P+@H9yJTod2j?m7#0%<$UHB4uOJRIVaRDwNvVe|j)mM_lZB=m; z&+3cI@OM>lqg+R%RF$eia(1D4HDWOu`ka9huP+X&!ScC03>GL~DWfHV$L`V6TwLTC zE{lo_F!IA5ja zgPFs8FlBZ=n2+OIK@ifqfaNphgDIHJy&)7+`C!gc4H&<4XM-u&@^ym@vZQ!RyZ~3$ zxSxCYfgJOXB%VNhs>Aqy>^qE4*hk9U_JWN0wvcm1jMI+&E71N7rU6S|XzasOf!$;C z-_HUrl)ao8v`~ab?`AloH4({_=|LE(3&dol1df%-L&g5iEnb=2P;ajPn&neU3rqL( zF&s*V(;P~v;uwo1E>NvyclsI}=fXZ)oSh zL0AIWK24MTEq4NU!gPLwUEw>wgh!T8zKDpC78J%+@foQP0|mjkxQa-Hk1z5BNNz2_ ztcPt_M%c(2hf?61-1>|*g|A>4H z9-D`9h!K|{8{f77H`u(x=@TAsk6aE*&J_p5!5k3)QMI)r!H@^RZ*qO20v0IsG=dw< zB9>c)gz($32!*I<;AON2;&(@xet^O-MYA-hxzAkBXPA5L(EKJ3mPa)w;n-&L=f_|qa)HGb42nS=lH|85b+ZZiM&@|?ZDb`f7$x)P!Kivl zOd=caQX34lXxC-{1%P4#r;U~7H>V4R(`4dUZdnsyi3ybj|ETpGOeivbL6#H)tFi_n z#mQDbIJ=hx)Y!0BlC;3e+5PH~K)Vlv(%5Ye{}~LHg5f_y4}aX0vWm?phP4#eQMi?; zhTk=w;;HiMt!0GM5*0?ltp+XHC8z~)w_DW51M!GZMft{(4)SIgucZ>mgdvE5!TK{* z`yI={OiR5I2fCL_;%pR&vs6hOji1p`vTEEYK|NegYXtF5dJY_jIAYgj0|E>;CIZH& ziygJLXsU*mvF0}J zAS$mFWPzNe@l6w`6l2gOI9W6JPYY z2JxVqi|-!N z^R*WrKw18$val%U8x!{ksBeA7*rAAKwWN3nS9ei6f-_llHdfz|l=TveiW6KN?t;~M zfs&{3bTzdbDq3~8i|#Y$U_yfopSBrCFfcw)a!K*3??U<39)Y-Bf;;Ue7!sdA2>HJX zqU5wvmEKTZx^sctTHH$bUHL$k6h{uW7avB?usJMAL9o8XlTJLbGJ`BCUKFu=n3@~p zRzVPiKa+!?ZR9$Ttdy9vvHB(4R-UO2A|FQL?KBwUcQ=j2#xf3+wIvd4@%q5c$k6)S zqT(&M>OlpFD2@AeX#&NFG?+BdMOF>k&=nUqg({WEGPuo2Dv>3{i*y&zSIH-$pac!s zFP>3=V?QZ;t73roEL7yHQ$jcE65*7_$z*+`fG4tba1UR7?`Bgiq zill_-@dm%;ZCdbKWRFqBgnOhV1Rg(6nAuG?<5v zuty!bhVXiUrnC6xK98KeXt+D?xEmK zjl+Y5)&P*yI0`?h>@R53+`nr(w|JOD>lNWk6|=eq5t{1P5GL%pTkc@h?0XnkTy+tr zGyLYOX{}Cjm;x91j6cS%26o9|X=LR3FeJs`N7>Cn>sj+G*}`A*Jih1~yf9GGHwZjT zZ3(>=F3f2@TM{U*>BY;ZcWvkX4xA>CRk?51c5eQt8?2m*h+tEpC4X3c1-rqe09)^y z!!C$x8PPcLH?SSwqYE{lPf+j-GWKqq4n`Or%*9_u)UHO)gBO!}bnb zHaqT@Px+@lMHj!WWiNNr^nS)rcy? zpQgB*EU`Ih^(guKo$<(DQ6#iHwe$#!LR#fiDg-m}IAYf;sXUU2r*p0Ox!NO{hLE&t zY{^9KE`Sz6Bi?jt7{jtBwoTZ_#yvHMk9lThhPY3im8GX>Lruz#8D^?Z2Do)1rLULA$N$FmX`so%yyU}x(2wVrw)t%Eg~e(kA; zyNVDjMk`lSV@*6{m}93i`xKqg*=LuYeb~vYvk!HT@y zIq!5PpjWI}2Q%9Mt|jd`W}n~S-ymlmJp+C4)Mua@JTp*n`V2&Fwlr^H-fT0FxMICk zBYslF$Al|W@@CFbm;N3E!(}?uEYjt;S8L~Os@87j*cSk>+#E8-Cw| zL)m6Y`=R9E$KkBgl!H}Qt6qKWl+_oPYI@a0ZB#G1pcOqQX)9)9YT(WoYI!FslZ3jD z0&I1)hp*(>eM;(3C5O_OmIMPDW0w3E1bbBOI8*8g=%MYiHX1W^N|0rSXf}#Fzb-K+z6PSIJCIMBJWCxpSp2WS%hoK+)y8 zqh7prwf_@VagHv}AC`^8Uum=}~ zXfJraI)BK8Shc?rcI|F%fx!=eg#tSwvcozX9i`t)@GR8(|f#*%fH*9#@kI%c4{H0Qv4-U2PqW;DIj{Dck6?H`-rlu7+>k z)t29f@st5`rH*q=rPB&XUEvo;sn!l~Nc@5O@K^6_KgG)Q9`_3^KY_Ew1iC5wDICP0 zyi5qSeFVIRcEclP{vT$_6$T0hkmc?G7KqK>OYDb#NA$3AI&^ zU_yn#t`4r!brR0kWM#v6+K(rkcJU@83Bj+!lMr%iYZpb7i?HUX_U)-_fE~C_K1D@! zbbhZx)@7_9xz`hgxkJvnMjQHgg}R~*y{NDXb%de?Hj0uh-*MAJLH&1GpyoKOt7Z*h z)TQ9YMIF10*ui+thC(%H5(l$g{*@?uJn@CdRV0;J_v@W|#5><9Ud?IF%BsIs{R`*uij1`onP{>^?m_*M4DwYK zeMZINa>5;@osM+Dzc6Cgk2GxA>$l;#)-DgHo6*Y$YpE-|3fQ$V9)2UZp^D+d__M0i z+rO4cK=z@{OS^DbB3sN{z%L>9@JX%2@b$J4ZyE76!>9*qc5{uTgqC~1ZWv&2tgYFd zx|3(>*+qm!9N~rJTzqWnNuM#&yb8Xxm~lQu9}3Pho*4&SgNQY%PXY||SX?6Nk)W08%*I??b}7Ku6Yy1!jY3)h!p)y$M2hf#)oA<%`SACS zd|00G04_4BQtta&=HtkE)30XwvQqIS^-O|5>qnbZE z-a~Cv`)S!H#P!MX&<>6PmpoM7-4oD+93Gm;73dB6{mMnZbm`tGO#k4^nW*;ZCaw|> zbR0@bJW1NKMh^=6G-B(FD=6$~2KLoRQ2o1bnZ5pAo;G; z6(~uloUBSE31#dQb6a(P&QB)!HxEz7R#z~Kb zI6s#br_S38O1kkfqJsZxqr=}vgs*!k6a3Aiqx^_D^0^84-2w;Q+eu#j2k|I7)7jXbEr)=4Dpu5 zr!~Y?`x{*CXT#?z0FXYOuMvE%GbW7B&p%8S8Z8**sSk1sx%gH6JLv9ThT#1Se~P(p zT1WIANK~p6N-do>JnK%f0E{`)MtYJ7*$vhzLHCR$IO*M8>0gD9pjSs=dk~i|wP(WU zzA7H6Jd}{92$;&aqbU(&Cm_A7{#>wpH2#-(q21F3yb1v?AsVb!8dUJegebkrB7T1Z zfU<%~nlDcAaMal2l;I*fZdb=96~0%WN%%ev_^jB2k3TP?B28qby8XF0!g~pLaaItK zix4#OZ*PR?mbf5@Tud1POp&S*7zB@~0jUL4b`S48C%xxcQ9tsjuTDH7OAIXjOR(;w zFUBnx)XY1TKL-!Md*vmt_4V**5iKrO1Ti{{*v`$cTa~K9i?Lm!A{D?Z52dwBvbNOd zl;Lx_tU~nK!}US!Ob^dcoQz(8s@ANXXzFzKN8*t@pD6>0AaQu zfnTe7EQ3mQ-t|r_a99L>gZAoi0S9>6x=0u&1&)Wnc#k$|dQ%K<5uo{U>z??xKv2&B z8%~#4xaJB=5oR#J1qbjgt3s4$JKroamv##;Q~6a;aEfq4#VKQP9CfTB~L~7jtB6L|8?(p(7rmRuYlwodvML)PW{`X ze|zzJa0eB-9CPy@U;*oPb)IRpM)m&muu{ewg%AIVamZuoh}#C(;J`Boge>qYc&pwrcr8I)c=R*{wZ=Z+H{xUlBc~yG zZDATsRR3;q`WG82OxI|Tloif#hk?(gbrJZ2XhuZHeRzw)Athp*Zyb?%e8oK5Rb&M3 zkiQdUm8Yfz;o&x8q#%VV-VhFHFuEVGKiK83&fB)rhhDW57_FuF#o|ssY5pBeh;utr z4T%muD3lNdA4w9q>O*J|;|=IAlCR1#u3=NdZVQ=;f zBf}C>)Ar+8vX|3tE3O)EIDq}qBgvn`({O|89b9SpjaGI78=EH(14sEFdGUt|c<{au z#F-h<-_JF|MI=@&RPiMUiVc6rB39XtKg^s6BUjJ}^GJT!1h_cnKRA{4!55m(C6IR! zc!Is{YHsXVeMMI>+^u)*Nx)@gVAgSpjkKP9k3E~W-|AUQsIkbt32ckut=(1A?&|O; zU0s>dRdn6%>Sw+rT`hH?vgJLre>Ru9VSvm(S!-?%!h;28l{=f?>+SQUvYA<6)QlM6 zlWW(+LlUUC5Ft@8qK4PT{a`59qneSm@u2f)Y-ai&D6yxY%M(9E_&I2_MaaR4AM?kx zdmcfm`PJHCmL za{hnU!aR@Z#AxGK+f`;gRaqmQB9vE-{4GkuaH_>Q?LKA8DRufyE1zP)PF3tv%L6{> zM~^!4zip@p9m;6*eYG}`IO_PbOjmdCYOtn*j#7NeY%AMX46f`)ReCcV2ZBx*K1zLB zR8~5vd@0<=d!Eb*g^}>>1ZJ0i!S~em!*7U0f@?pWn`2K+;q5w9vom})rBW@*adg6O zv0lz0Kx0SxXboLntvbShou&Hiy(s#vx%)1GhdItwhWqVOL6njgt$V5N;4t~I=C>;? z!wC1!Us!N6B7YsjZ(#SH8R*t-s!s>EOWAFQ)M@nCUTRl4Ep^@7d4cHy^Q_T&C$5vd z1aJuOe=zw_KOPv{S;1*%n{K(V1`&`dSKOU zK=D-ziW|L9aMMWjo-ix?BqSfTOaW$F7*6Nq1y2E~8T**YG&tnQO zo@7kTVlYWEe?+Qm4k%jVk#FF3{Bd#5JfpgQz6k%ow!h^!a*8iJ1R0lEm?k4712<|8 z^vhUop2N@;^vnTXNBM5fz{m7=Cly%p6 zF6TL29=y}Vc03UTl+Ox=F=&HF-rz{o_9K-2R>5fqNZ;JpAYk{G*M&9U1zeRmGU2p z^j<8|``sSzSEw_T!Rt(X@bh|i-qDRUNT=E0 z)=rebdCt0D;-&=$G>-&Ix=|L6xAps_d@(kDu0w^n}73GrZe!|7aE7bb<8lmWUsvsEE%R>YyM>NiYTlMlK*)a z`Io4(_yg0{U`yn>I|x=j-jb+H#>=B_2>_(4i~}cx5Ri=Tw!6i z;LNFmx^nwcoF*}4%7&a-fh@V*(+fW%X+ev@`YOXWvV+3QcC5%P$QM1D3)-uuiG)C& z+EMK&JyP^|!9|aZraR^vLPs)Dr2aWbl`AyX4L4n;3SG(-U7iC?44Wp;8Gk@^5_s53 z3?j#(Wb0pT$$`31OduUjfUMmWejgB~ax^D)n~Js=y^;d@J43iPo>b#jp6sRcl)X%y z3K#3Vv(@M`%YV?5JSZ_5pyvBg4*$m$mm>VHd;4Mgs@J|cYF~)~59N$27GaUqRFHfQ zw)3WfcpGg5xM^YZVATc5hpQG??v%I!zJ723^yex?66VScTolA<<%pS&=%gM`i?_%J zbhMG2ym$emo>M~cPeqL_@3Z*(!r{j=PVEs)8oOM0-$Q+hZoAvC>0<;T;(L-SAmj9L z7jCA#n7C~=QLS>LF*@@l#Gtr-Kgq*J;{S^cMR)+;eitcqK4%J41E1fYxdnq{cok8i z1Uv7Ir}X4#hF=0>JId_jAiq0D2L3`n2mZi)jj1Y>!sq{W;WP8>IqVr1iQVLP0M3=Z zmj1grD9|rVk1`urg9ZXo-8=i?3j%mQ?SGZO!vFpREFQb})$yCIW=( z+*A*y>|ib%x;Ob7fnZYmOeq-AC@|Ndp@OGOd-)`9-0y4-v6 zGGg4Sh1%%O%iI}Pzp`B_{-5vkcX{UCR+*RoB;DbLZZGT(9be45;B@NrNRR4lol23j z+*Th~Cxl;G{IzXe4uXh4S35GVXWK`__sU-i)1kO3S>9#1Us{UQ371PeiNX`BNPBtX zOk{Xf(6w$2`dYrob3FB3P40ahbudo*L2;=r$C0HTt9E@b8S5LJ5L4~E%Y@7ij)QY> zAX*s&Fn7YrTL1>o0oBKanamVMe+3Y`)B1#p<$xDm3coxo-!gWSxDX_HyDM&BJX%gK zHWWd65m-2&ILb*E)iW+Yt$3PI%ZuU+bW_n2K-AC)j_@`DZ%*41ONrrjFXiFU4D__R zD0F?=+tC^*lgM#1dPh;l=_q-p7>=T`O0_}{E zu$t#-wR&TW;F#J4$=e_0K)WCj?#1e}F9QG6+glYAi|yhfZS&yLrS4fAz3st>eFDr= zt@0p?1w_)|B4D1CcbAHKO)vgPaKUF?AF15P1U1ObgnHLU{caU2u&o9*M5_a9SsWy& zXG2!fWM=P?0P6q@MwgIIgvk@QQI?C+BPX;NaEHoECp{{;BU@6JHlPY++J8BUSmlV%ioSTjmm}beaGr>1N zL1@8&cnS?g^$4co{&)+$Au-%ww7(lKsmI-`^ti;b61+nF{7yTkHLteTI`E?ef2mgb zR4Yo`cQ=7DhPIut@>;1|@(5tXB)!D?spWp7We6JLEB~N1DlvM2#m+6PDmm1@1yigBD5b zqqk@P*t8KqbrPuE_CtobsUEgyNwSyas9P+KGX=oybEB zJ3kpqmi%*HKu6~Snf(?r9gT#saBQ}8O$k+H zs14}T=4-Mw6X^0l@D+Xw@i=kk+JL+|Hq)(aB7bKL|(}# zj>jltl!%PSXd6``D<0#hS1rZA!!lZ?KV|xU)RSDPbS;9EFLsbeO8Kc}2l3MmGIcp% z(smHPfdnD-yr&%m*kCp_Yb^+W4O#zm3u98OcgJXbrO8mjSKt(otO8UDHfLQFK9*qt zNPiP+X^V!C%5ADzBr=qYUL=C(o`uIz&-x2KD+B+E_DMmtstZ;h%}l&>x{*zozc$oB zKx&Si3I$09Qc%c|fr4sEipNsP82?Es0YN9KMDg#Cnl=SL@qZ?Rf*d*eNF1>2q9Bcv zih^iVQ4n}n6eQ+dOZf2d3={+kCrrWPDHJ?rOtlWZsntJHM;J2blfBnqH%IYtzWw)-7Z3t%%5kqba|Wl1o9W_g(<6D_Dp~JiMo?&!&7Z`Hu|yR z#^xv#DBvI5D!Zyl?rb;ZT6@8?Y2v6G4%WsF6sWCWlvLZGj`k#mZpWm53Pc0^vb^*x z1+hlpvg;kL_2iY&qULp;_0_K}`>;Lj&3BbI(pG8#nr5F`X};q#hmvsJ^e)zV=5}H~ zf>vW5WjfUS`}mdmJ{93(+|!b=TA4ER#KE4t-=2;~@RE|ko_}Y1I`#9lYvy)dv)|}O z>#0j|Y1wGw9O1m$!$UI8?cqKClzX12alKEpv32Lco{0DTo~@3Y)$}P&R-xy;kQOXs^#@LVQ>zL@}+- zqO6hJ5PI?x1%vtxZI?KeYc23n?8@M^qc>Blc*SdoS>o*Dvwc`8oV@@z*O^{Oy3yZ^@a-mwH2##a>^GU4U! zPAe!DGo^@F83uK3!P)Og+0)k^19asXN6J7);ORX~$er~an|yKn`!@bPgnt(P&-AaN z?_P(#I)6pl93aMXsF54%fz@dv`xqb$n8?B3{;C%nsrAgSxM^P!@ws7-8)T z1!b!QasF{&lTLL}>O&G2HHy3iOpdCsfa_HfnpuTj$IOV?6aI)}hhCSBrIZ6>XP6UbY z$rw8jRxmt`k{{AaEQV@j!LAcT-T(K(6r=vll|GZlbwzLF^H(JlJ1r-_$aaT*FEJvj{Q7$jbFy zff7vYH28(C>&G8)k=NU+P%o*Ss$Jm_14EN1LNz1Jb=d6u3C+7~s}%KFm8<-eJiLsD zDs?5p6Y++1bw!q=F{+;RI)bPo17lKPL5L&Mu}8Qf@-LHyrKZdSwnQ zl%g?5d*IG5IfG>{xF;gF5mlj5LeG%31oT*rC>E;|J7)t_J5(&U@vybne7S^xl8w6I zl?*zPynP6rgNLB6DY=rj)G63?dkgT$8bps>Y4+oo&DyayFVKF&z}IfJvpC}(_Kq#? z`7VeSGCB24INw9-UhY@>TIN}yL;~%H6o*0AxVjMj^#~v0b_}v~BA$!>E=qb6Mvx_x z#yS)s-+49GA@kpFllfM1mT|(WpQSa{i?qfni_Kc3eE>(nwF7^jg}`_GG{kk~IMFT3 zUnsFg>v1f>Xfkg(moxp>b$*Lvhl%GZn?<%&=xHiKS>~(M$1=WUstCfxyAZC6Ed_`x z;+e?&z!ntEe+WS{dgxA&1ena{7*%w^-CiX%gK_=arZm^!XG-w04#Tw$;RWiRFvQRe zIdB4Z{{;-cifd$RsmDl-Vz5VFM)9R3Dt{!7uY_7oRFP6cc&vpeD}r``?|zT(hVe}= z%aN8XC$JC>?D$vgY9gdq@wUj{$#Phn%Z3B7Wq1xJk^_NQ7+3i4Dcp4hVjsm_TbHr{ zSsSsyKtRP7JMUWNJIGpzP1>49wvuuVL$0$nC#h-Y@G8HoJ{%-^`$ zABg>0UF{3RUcl98xTWn(;Z`w>1x~Q4)WU5r5c@i686R#RV@W`&JQc2dnDqy?(IwSE zmfeOVC?yu92e=4TpV;u1jB}*@4ILAe@;KDQp;BkL;?dJiRjBa`zQWFnW80EL8RN!l z8S(mG5DkQi6bIja6Suem-zL-xmER)}y9u|WA(zu}M#g1`zi1h@<&Xd*HV?Io54nGV zk{xdBvVp+1+Z1*sZ#$4-&&zCN85`-+NCk!!!=65~qHdvr2wT~F8--aJ32ET(0INl6 zFzZ#g1!!Q_dFn+qBCZe}@5k+ENbSY@j2tUT6v`l&Sj(?C3AiWOtkQtlD&06`{WebZ z@U}Tt+K}9iJ(I$yZX@i(7?n63Tm^)RZ6bXyOPesWkh)quDAk`<=7+0tH z<|@0u&EMVRd+F{?zK`Cs$#?7b-#WWq>b&{q`%}Y!=o@tRgF2MV-wgfRGDNMn7QWgL z6=?5Ol4Y`uQB_*AqC!?t8c9@?M9f#WiS8%IvtWUQ2L|-YB1jpPmr0-D!X4&JnK*F? zA>=5W^OP<2J`Q}@ayY@ObPw~%*6M)ITHul1bJf_TOXfeY;&ERUcLY8L73k6XHenAD z0qdW+1?zY2;9?Dj@b&f`d|1r3gVsBo4K+7dcSiCSeBFV6-@(88@ozj72Rs@r_2B|| z!f=%WG)k0HDjfA;VwK@g?QOy;tSw8d4LN*Fn`jh74@#6A%o-ZkWhH#BMgQ$0`rXH- z{&g+9_s2e9n9>OkysO8AmusvBIINb`TJiI=o@fl?Jl6Ti+fBu@Tq>{+=dbjv5adK) zN*~OaAE9la+@;E5uQSm8O+3be@!n$m(rHI&N0L8+ z8Xe;ka!(0i<475(=3sC_J)$?Hjj1*Xuzr%DhL(!~7dGc%zvl|$btF6bKKzrElt!37 zsfG)*#i{YUGzBB2cJUONOypMj?`QuZQ<|x!3-B(8af!vty{~HnR)Jo%I0kP{W0Ngo zN>6p1qd!u9$-(YQ|H|xlK8PQ=sTiO+KehA+CqHIPkf+K2d{Bj0nJJ>*8N*3z!I>F@NO{A$&>_UEQ;jiZ9iWQTG9ERqF$#on&#VpH(V6j>Gx$Ypa}to6 zoRZ9^i=w?jFEJ^srcZyfbO3U)|E_G)+?vf^2CPSV{`ZosgeKn_ee zC~Jp(9!kR#1ps{;D~elYbXSPjiQQD}Ysshf2LS}v#w0Db;^!DN{s<54yVqO;u{RC} zBkrd^h#pu-mhq3&OvW3D+vMnB{=I+=flUIp$P7FKzA}ikF(PgVt@zL?#?HkaU zG2Ai-Ld-n}spC}KC5QNsjD8T2yd-ASXH&c%>GwPFp7I2|sdm}DA5Has#F8V{3NmX; zx!#X5wWKYk0-ji&C&_(*=QC+ha!0H3^ar!sZK@RS|T!`$dMFv=;PKe)3eIk-+r9YsqmpGhn6%?D88Dk&i= z+fSyInDbqfD3TJrtmC4z5*s>t7*RL3{e_l`I1`FRgMHYx2n!lH7s3fFhyjALBI?pe z`T_rk@GpXYH{zegdz0}C{9>rY+x!4H(*UsE6De8VOMW*dU>)uK-Pzwu`y2>azL)p( zG8*kYNs{G#TNjlzyMy|hpE%Tm9*Cu?PSkNGsO&b1#~grb?}Q}RpDn3}=( zX{V9(&B(R}&1Bpv0Ok zl=@p$mng@fudPSLf%cE!uiITsW>Q9rrQ5hTgJ3R|@UccHqNn`i?Zgg~dH#|k(UR1| zO>A&!31-Q~Fj~`2UB@XjDyP;QzwX7*RqMni#4DH%lj0+VZ-I>TgQiDiz*?z$MW9Q0 z1~obkQR}3S-?jZ5g{</zD(CG6j|ofZ$&U42YHLu9JdMr==6w+$t*?cEroI3IQM zavU3wP_|>tKT>UIVQ{p3buvCE5VMSrwl0$|lNa-3Q)&m%UR&4jsP8ep7CYlBgTDo3gLz$Z zW`B!mzw|_7fXqDwe~YiW+E3qlQl4tZH)QfuD<3`H%n@_*NhnV4Xf~dc^i=b`@XC`^ zEM~t4eu2M#a>1YGDb_eb{9O$2vFWM~T49*;d=&jvj=ggd{8e6cwVzQmGNBQs%a35W zxU5i%o$eVO(2rDz8l37|R-$~A8KD6z2Q4LDSzv_o8t-U=d-JkF9^M1j^4wggG8nHc z?yf9iKXf=4h#kiyP-HDr)zKI_mb$0wmVR&A4HeY=luqp{{4e~pJwIfQ$1t((D-BKe zw7ar^-Bf|JmKC}aH)#xXSE{ACCs5M_`N-lh)t|q1^(P}e8ShBbb8((U YjdL|Z2 z6b(gOP!qn|iN$#&VZ0niUnnUUg<~;@#%p80%VkQhq{c@M1@F&X@TQMnoqvklhV=!Y z#drYQNOYT}@d1kHo^p`}kq{+4MEXQ>GmamTozKPzeh?VSZa$7Z}KJ9lyEDE3s^`H<4Gj%rwX*=og92tP`zBTkg-&t!Rn&sq){tSVSb9i)K@#C1o@U`CPj zU_b^G(mE=nH3#rL!$tPrSd7QGt7k5B3G<+J)-WEbyaERX-=;5_Cq9Z(X4c+ceHVtQ z^w5q;03dWG6OiT34CL+gjqG(SxATqvlM!4 z#p);;fCE9Jk^#hs6xe{hIES^YqXKHdicbX`4}dkGD#W4)0wSnO1c9K4ynK+4&=eX- zkqob4U2aQ;%U%Gwb~Yf)g(V3B?Q}x3QPr0SKWdz(B;J#@#IuB5_!xk&NE@WfB-bnQBm z3cAPrsF9$D0lLJS$%Od#qQu}-_xJ|(9~A6^Q8QrwD6xNBgMLkEM(o3MBYXga@4qn} z`z3DdW7g4Kux1|e!Gy5?cJ#sJZ$tQre!!mr{e<6(e)IwJCH@HdM~A(#1lD*P{TX1N zAo_oR0PBgr1@}x6_p3g<#oYfl=!6IVr^fyq#$%1#$!7oeK}4tH|J3<^JUmoB>HLpQ zc<_H}{IBqT=J+3S(^jEmJEZqNF+b{Uc8*F4c3VthR)eAmmI&6BP{?EzDepv)g{5@C zgd+PBigB-!k>8aLBa)fuP1r=SVlVQr)* ze7%ot@-=sD^8I%ICf`3E*yQ`{q%{?CW{Qz!`yGe zLWFTp5@8cM?@;6sc=jVquSD_YCBQQW?!|up6r9c#93ou?s>k69e95qjxXH!MYx}1( z!y)^>nIDHXZ(3U;Rf4v}>at z+y)i2S2vnoXv-Q;+R%p5ply4y72naX6+oSfO9FiC9xuSTcsCpGY-TtQH|;Nc<=nPk z-3;c;2yz)gek=v#`&WBF&PO$1hb4`{&k4sWc4&K&QBxXAmSw z7_s5MFcbV><@9*})KLhZ;2k&gIc{gr=UVJIwy_5}pv@Qky zBMtr=YCQNaMuoyZtts%A0saSV_%F@`e=FdJ|2ANJFKQwDzoE;MO9V31XbIlg@V^f? zfFEB9csFN*zf2c+EDiqqS9#!nKPnXXdsE;C3pVC8icAOpe;^b5VB@Bl0{3Sa{MM=&jx?4F7U@x_~&@xpKHOtGZp@z zuknBl|K%CsFOn=Vfbj|q|KESx3;)@8_fa?eAJOm^Y4Bdk27gc&_>WZhZ&=~M|2zwR zGZp?aUt{6tE&jPOBmAwtraZy_$29!ExyuVb_p%qb;h(SJZ`I)4oDKdmUEr})`0rot zf&b$c{AB{Gi+_AMjazK^KamlB-;^dK)B}v4)bPJI1^!uhx6loL8E(k`zA1`-l2BwE zZ3U$v{we?A#;OZIopCfBCi)EuyK(*I}Z6% z<$}K-8rks(hq$k(DIoA)jcdaH_lQ#DmY)H%uo&-b_& z;It3xX(kV-xi2)$rT{py*p`lvnpo5Z+IL~d>$Hc*lch?&=zCMVx3JE1tx#oUDnbQH zI)#e%t6GX>)=4ajud{sQ;41{dl&gKJ4kni7b(e8*C~I82K_)l)Qc+f+sJh{T8X}2n zP-h{VCjWJwOL!BA@bTs=l0C9fX*Q9U3cn)`ewSzQ*Mey`^GU3{&w<9A1KIWN>Gwlq zBm3QhH{9bhbD<5UyCF^JNDkm*%f$$0F()NoVWDM1M_43WVqZ?>QToO+Xf+&+Z@&+V zsP5@U0SN#)_9Y~)W5&XgQSGc_<|~|s+C7zaOFQg*rp$%iIf9Udf{=lGzHA3t(M0Ob z5%?Agd;?W~RPULY>}jOuP?^czyx;i>_`tz9FPfL2R?E5SXq9&U$`V=J`rd^V^O^s0 zzQ1E!-zRqS%nl}1xHchkaUwU&u`<7R%d8bRn{*o>m*%%U6ZlqV7C?0W0Z+rgRWI8e z#6A3HFZ&By-r!70n!{eBH{NdaFR3|L;VRVtN3`8ZiMN~G@|Jm&0e+ECa(>G}Qf#ju z%;-xL3Zm#v+x|3AHh+I0aR|R2d~Pi?df*xc$HT&$D<8fa-!Lj$3rO1+hN@Hz&SXu{UKDd zmf3cENcX}MH#ndfo-LkFMz{c;Gl$9ml7xn|P6*;VxXJXacKe~`X_xdZ zhO z=#^KY_Y$PVMK*e(Fz^)8POI>6=wX%W;pdkt0$j-+7R7`BRSpG!n!t|B(My{M8|S6; zHUst-S2?H;67|IVuzUy1+f)n6lc4>?#v7?CL;G@|757u@o>Ad^03!0{|7XQ06E)=uo=(u6_qAg$;Ey0Vmf zk9}gM7tmf-b6-Q=B|4Y>mT0=#_BTOoI;LD*StD-fpA-!<$P2|+`1nQ~M?zheQw|5~ z?Wm#g0pQvEmxYc}s1+3~nU|s(1`Vq(FXg7Z9okrV`>S{mDS?gWKS9+3xlCQtr_wX1 z*x{ryvS{Sgq6x0zlO25!?Z~@Ew=12qpk=ticnUpqs2bSzHWYRFwrejahooopO40L& z4n5n33W2gr@xtFoZo(<>K3Jro%QB4dGMobEE&QW3R`n_Hhwnrc3{R>G_anS;V-iTf zsdW5Lk|14+3YxBK%0WgTZW1vTK4OR96>g9wIj@e2GqzrI75C$16UIV4esO9>J&s_i zk4ofXEAQOjH=<#XwU*wA2f%r7`m6gDNQ`Muj#fplF9F}+Y4lnA!yASfoO57#1b_D} zx0_=eL3A&f&&bFMLQqfzBxav13g>5vG=3Vg^h(o_5czGRmt2fjmx)|& z8KI2rIy7cHHEe0F`)pBy;rEvGG4v3DBouVD7~!`s|gTb?LKJ zndK!`no2qmkGa_Xzt_d8<~V>O&`QxgE`1!T9k(-id*v1 zihH@T)L1+Z=ek{r2Zu#W5y1*d6{_Y#IZ|5FFGpcHc<3+|s$tdDJ+3gVrAGOp#NtIp zS+S%MI>(rSJ2{%a6T{tDyZ~kAB*OP&q?R$1!v*klv_!@2x1va*`hI&Xam=?q^6z+x zh*@6-r@)6%g(9`^;CQmGz-#3XYDI^;Ai2H-q7_G*R?K1OoR6CSKCdT9-^yfeH!*!}t^JLfjV>FctJd;9Jmx4?qKoHFmF8 z;=NS&>RE`s!P|a9LGGA2waS*JAB@HSe`@cQyxif8zqX-L@J_}dh?I{KZIRwG&xTxiUxJ3tR z4j5P>)>Sr=MZk2*8D6xgn&b1g4z;{j`^+4$|Q+*fjjo&2?$GrUHc2o&B!B}Kr&6U z!zzum_Q&xqV*V9eTByQQ_e-Wr{S8t>>a8cNos0%}w-3>~eH$4kBDpK4CU5rxCH6eW zmTJw~c~EUzW}`yTqM^^ye~pofc*|^_cA8J*KWUzejX{KNLb#Pk5jt;FrN!e@OlnKx zG|fgY3;)yx_$0#vc>y!UeN&oen!o<7O2mMLIJh+&L@IkQk8<0!0>zm-UK>4IL;CuU ztAWIN=+HEt%|Eyi0fNlWJ_73CVl9?jTp(rd6ySr07b3U-Bx}mDCin=2#}i0js%$}t zooouRT>!LXoT~wcDVH=P5yfCk;I)&;aHNq-S2B=Jy(@8~+q%@+m4eL@XlS~u(O|vm zfQyC$fl@JoWy(CUQTg^G{8(W1A+&$nP8rqpWu@h~+tGnLTbziDXaSo}#>z+VQ-oD4 zA|@%wiDoVb86wpC3<{R340@x3fT*}tDGC-9plYvzWrZ-d@V}J!e;Slg8k4FVpE2Y; za`tHC%Sjx9=G9+D1X00CswX`+QazD)=ems`bumuv)wHxxo6s4xYep#S^dTF3q%DLD z!Sm(ElsJT(uMZFFVwRd0rRG!5uy&3d#WxSnIwYo~5z!FB!)^^>IY@NPqy{6(z~-PI zyB@41yss+g_`oj-6nXXro*|qkWUbbISGG4z>K}CHtNpNo>xUd&ubiDJE0j>#qblx?X?&?4IRj zPU%cvBJY#Sjp3EG=HZXh<{mT-f`P}%GllkH-+tE7M>6cUG`6CPX6}b=qlIPKhSB0G z;6=@8nEs^Gpjx~d;^PRXB=5#RJECBw?Z2E>cniHBclJ7aJ(CIk2MGTnpa^NN5#pl7 z1%I`eTC5(}@)Z0^(*RW6zCEMtuecOc2?5~AQ=<_IuAu7UyA53Z{K zWY|`USNOZ9U%N=6hE){E_E8F3xxdG!^1;0~>aC^>+OwknyixHd@d(iVw2tUKJS}36 zf@#CE?gW$^+}~K-lWg2D1Rt9x-YkRfWaE8c(1gS_wG4gT(~H;3*4IwJWB%asnZASD zi{O`+)4jbIKm0G9Ib5h2*QM%D&Nct(G7|&Wmp*%Ma**>G1*mAf#K46wXYOAfK?egj9268XSPD=^v4cBydntm zc)TL7d-@#!QuroI_zd^=8Z9pV%Y+tTu|nPV5~;g5dmr5OE947gfDcg4#@>KH*>7=d z+TN_9?_oE6SEt*WoNzM66^s|d@G(Uep=R8V{ki0Ge6~Q;X1QF4%PI2owpLIEcL-RC zh5Kq;<(e0AQ#mbuO1il^8(Hk<3jPmX=aN@v5Prq2JMLzOD*ZViUnNIxWkGjkJ)Zfx zE3Z{QQOuuJLes{4w}`H-B_R99M#?Er3!OW zn~OO7YNLKgCyWSM_mb>j!pj8>pE@R_03tZpm8@2vh-U+rMiwYaVPnV)s1Oh_2z?RS zschOo>J%Yao{G&sgFcojb6^-m=-FjO)=C*F_qYykU9srH*eSwy&taD1pLO^nGh6bx z?n)8&SRITl-=+US_|y=PS64t#o5g!6bN$A_#CPB}@4KW6erSn*pza`h}TxAw=P}bRS~bP`a~k{O4k=3POR-utSg4J)A7iID`75JQA7iLepUZR7TLHgWL5wOKxB+fN2>>*n8N^$5@x*!CoC zy4Ax#^sY84#cOxo!XKlJBVtYb7XFCEYaBe2%0s7f5Bg($SnkN@*idOkWA*b*5%cAD zL-vkviM4e|Yg;s3{vS>Ipiy3BY@j+Rxv|PQ807T2ut@kQxuS&64)dx^g~d4lv#!$B zrkau)GJGQGmnoCU<%CXo}sn$N^0rnM9dqY z2NB@Ps=>3nD@7;A);Vns11k3R~DoN4*&I~mazPG#a&7qe*Cq8d{H7J$?^-FYK8}=&3y(%#SN4y)s-89 zH(fgS(BO0(-=RFO0w~C(?wA`g%JULe2XVj1KY|B~LL>7x1h>G|)%;D72zl94kob8( z?>vAAdK-PRd&G!&;o*3BUVMYUdn(r@L6=V1FF=Zcj#K72!ow>)Qm-Z&!Q5_G;^rg5MMKu@qg5A4k z=yet1r+611n)xOlQ3@Y}ZhU0sKj`d3IJEn_cWAoX2AtQ5Ojgi=V>MnXV~8bZCwf?ehQot1v0{MvZswMKb;yt3XX zk0ur`h-30}#Qpmcn6O5yNhb5;@-muEEOyV}b|iS@AW^fD%!A;Xj;Ta+6>EA$;*l4#5j532!P{3sNGW4j}fr9qV<{5K4k)6O# z1xdbyvAIBf$0ygKF1d4me6REIULesoxY7F9^X>Xf-!{6wr5$Yt~GLn?X0J`)rIm&zP= zfglPfK9xrRc1c!X6>ll<^hRMShuM!&Q6ytU$&FQTGEgTQG*vJvP^s4X0gqh?-#Y-> zkFmBNM*VkTsHn3NN&=^zZlr76Z1{~V2yONq#hB&4f5LU}+|9mQ@b81T|2O<@)bCo) z+nn9_Jc)AWe@j(LKK`{MAC)$gMMj$Wf%aP=$EyPEKZS6QnKJ_0BA6nKHC$`#|0$+9;V-I0kdZW4k>y1MwKKB`v zCdsd?4c@c>JR+iTZqlg8y9#%?$dVfEigkl==5)pvJw1Zwc)V!F2%qbRC+F7&w;WlX z+{n?E%wGjog}46zeR{G0{EKsKfQRGNTpV%k1i%*(;0v{XjT>IBj{xtm4WS$E%TEPf z)Wiu#Wq6jM$Kxhi7Dw#f%&UIfH*g5hW$8*Ftt%+Yt`x8<1vGPvyB`bYChhg!gz<0p zM+>Noz3GEgPr`Qe(b>ut=*%Ko+f3QU{NFOXXfHJu`Y}+N163`{!H4u{T11%zye#Cj zLShS<7gCOkm{zw+5=X4JN=Bjvc>>WG1wW6PtAj{V%ciI<^ z4lYmd9^ElQ@DR;jgVXx^*g74-0`0r;Z4=%s;`B3X5ynEqn3>Ek#>L<@y6u716u7S? z+^bZp0{7+FTXn(x?i9Gsb-_Kp8u~d*T|MWK8ms4U{yniSJ_}ELby^V&JXG;^Ie!qr z)!X=|0LKpclleS^fbSAD{ciWpo%j^5wY*ek5yo37+$HTw535SiJ7mXG&d!I&s1(3p zYl1AWAic$o1#jQ%`zik2c;RN>gZMWSJhcY@{?`m%HGXPiUGByCd@&Vhv#$s@L(*0D z*!mkK98~Jn$rXjN+N3KQoW@$7VA{Je1R3Rp*mP5uzzxZ33o{^2jqmds?e%bMs5p~3 z@C}$>|6*2#6>*^b4iFrK#11<&(Hv$r1o&YSHw$wm&mj^wg~I)~_gOFda8o8P`Kni~ zsIi>B5LFQ+CLSx7lzv`8k_Bny(w-8%yrKct@rfwqqj~&Orad3zfD-(wtY)zc=WDpE z>6SHX%7>X(=KHevFl0dExF3y1pW+O)DEh1%7k&1fosm8~7Y6#E;~9v9?h9!a`rWiy znCB4Ap$-FkO(J#1w2Vw><1_>A_{he$j5IYUuzYG0(-1ljuQI;Lo66yrTMSXu;)ly{ z)^Voj@wKt(fm*qKteaJUgo4`t;TGvp7F_S^PIEJEX^3qY!YcExB}!{VnWSy zk&q9ur6x8;XGW6!(6MAz7SfIDu}$Cqm%ZnOZ&~BXH@Bx-NVBX>2ZGm)J9nzBKai`5 zQsDC};4>MoO^{SbMO4oU3r!-k9C-{MmxW&8LrcI%Qu{A`<_>t>sThSSq>%o?!R}a5 zZ2jIfw>9PJ)oB*4Or;zMY%YXAZ5L@&#td31a$wnrCF>d38igk1bR1cOxfs%(m`$*O z${@n%U0m-dhBkNRhpX3V;?IkK3ySCSY&Y@VN$aWPQo_EbGFJa5PLNah>$2nTDEZgJ zj=%D+Bl55Jh@>O&uhWz9ulnI?7()~I7sxmzI8{ufG#*t%=G59&nM3xX%`})$WB}oWY;HI5Gwr7nGpUzdFbQCfA)#RzhK1H3GB;~apcMq#$c`fuy+Mb z_|RVzk4yg>?D#)Qe*EbV(JOzICl4=Aew|1<5RKPW?;B|G&qAK$7{E9rwM%5nIhPi-_HT4h7#$EV> zGlHjtKgbSF34d^=YyIcsB}#;)=68oF6|W&hk1CmwLR86bD#9qS+T2U1d+{>f<_;$H zFh2pk%4+jIrtd>~yv_Yg>O_)s%h5EqIlv0~2dlIS_xkN?7HTE5qKeD91Mv4Wr(=gO zR>2p0bwQH2FP1owr;7ORRf)Xy_N)8;aJze6=qVN}Zf_C{Om2%~^Q#=kah`1To;1`#ya(o7)^8KP!*b#_sU`Y0qBm?{}JZWoTXF|NS ztrdySFcu~_ltoK(6P~rw+Jxsz+Mk|f*9l>~ato8Ju+$W+-CfuxlpG7TMDJ2wSWA>u z&a_Fz9%iHlU|rOL3-iP9Pa)|U%GF#g1rIpI5g|=W@?#;q#{j@v5~UXxda&^p7xNp? z2-L9>WoPo16xcoTVc#uard$-D?V4~A`m5MlC*Plto)v!P4!4vzDz#UtwVT~oCWpRC zxSZFzF7jso_&{gbx0e*Xu>QcB1={>fwaFcNnu|K*O(Aktq49Ev^TjVVyKq~IFBx0% z1K<#M|IvIhuJfF(jRQ!yEZpIq`O@mgpb6`WyGPWhUD@A!8xzb(;;Tr@yXxgayhQ1~ zVpdtG^%S*-JDm}12k;&YAA;`dHy8rZx!DnKiROJbT7B?>j*dU1UKa7ril%>$!y|eN zoV!Yp8-d>DWQMy5bvodeb3{wYRLTmG1HKh<-s#*v*zFN31ycLLz%9r!vY_C=Bk| z`jX8(vDWs`ClS$f3gUUCz)!}Xeo1?RzJa}%NeANSB9gRsD=%A=>=W_sqi@6ZDQ3J3 z!|bn(L|Qtvxz5=iKrC`?o&qmZSL=tkpZz|t;@TYHwRHtPyYM{#7ap1K+IT&lTo12x z&ZVHVex!UAPr>@(pN$4~qJj9H4LmotGE?hma#S}>(trGE#3N9yQwZaoJAf@W*e_vE zaU%s%Wo)H8Iu9WO%@9yfE+jZ9pdJV00fZ1@gI>o|Y{qiBTcAZo#FZ}so~d?tc*YUn z*^IEND=~#sH>K#VQSf|M3c88~@$fC9q?ssb+n;PLqh*ElmZFEO(o*#fM5?p5rA$f- zB$noCEkZI%ywP4FwdE}F&)7+2m6)b~YgCDEPevD{0I}hb(_9<>fG2c8qw0dC_(8E} z*^5QLvB{@097HuvSL)HvL5W%ql%U)1n47t&H2aRZ?oFj<-Z3|8Q|VcY4dB@`n@~1N z+xbUZv*|L8(mGXX=_qY?o|N_w>{&lGbM~VY?Dvx9wBi@cYOYv(Nr>%ya?_@OjQ|X^ z;zfsvhI_8lv{#X0=aP$hx9~2TckR5(D6IR zY6oF!RYOJFjfO;gSTJB(?ZJ1Cvg`|bBEFrE<{EdM(G~7The3=N^h7T^*rBJEM0|Uq znd|Wy+Zy-dYhynYj?%5#qxp8Gy_5#O33qxb+FL%Xaif{LER|D9`H1<19`H;uAJ7S& za;JJqPtkl7=nI*jWG(X+H_UkZx+DrDc4==Z!zZ6Dny3rpZRo4 zk=CPOCzlRG)CB~@*rAm&jQnLD6SR~Oc^p|7+J}h~CaCE^sIi%e_#{fWSucwl5#c;2 zW+)%3&?Af7-E*Cy%$+RTw&v1gMb0Xu@Dq0E`NHpZqm0?v?B?~~!4)LE`wyr@DQ{Q_ z`qx1xEiuu~&D0jTwUt@gZEzmlbHV%Cvk~vk3$VsiRd;rmI_c4%c@dZGhIRxAGtF;q zKJ%eF#n{bPnvEox&(X-zTs(A}nT?HrrKIrEVlWEdPMlj{c(C6I!b!{IWTIYN1nS!dThmsZE<=;6+?<1#W8SVB-`m*zDXbN9(v>3^Eh`HkQiO-{jinb@v07qrbp?vGxF=R+d^8z8A`#{2 zSyK|{#R65?3VUUlMrBJrh{fy$c(K4AHDj1QLvt;gsLToAS8i`F;F_BaQ29$B=jIQ* z_&(-Tzn+5X44l$)@FZ3UoOXd35T_W*7|Xa34i;*8Gz@)L+GqvT1Dt&#Ccf=Z%<_?--qg9Vp3Av z`mY=S;4R?U?v-E)u<>Q`#C7)6gN2^v#x{da(@wiT0{zut2lk_A&L6 znpiI)!6}4W^->I}!!(BoX+CEY^$yB=5MR^@>4{q*k%~+(7N=uTHQHS%6MDx_dRIAi z&0OU;V;1&+;2wL=%zr87&5?golVx!%p1sQPWBhH$->qLZ%1>ASQjFj9^whMEb6xh= zvj2*K|BDz<`pfW>#hAdb8d%2};I3JCz|NJ^>}t)(orV2K*6w2Di=TAv=yZHz`~Aor zY5n{@q+`z5P{#M73FQoyGZF41ltmrszL4xkU7K4E?EjpOKp z0i=YcB;SVSQM)WpfCt=Gyw0+`Ts(Qzi)`NJNFEUppujivz)&fwwo(-w;@s)YgA&dN zcRY~~_1T@>Q~>AMn`LkEVegebY36m7K520>Z4%?bX(1;LxBY@TvjLM2v`GF~^>je& zL(>|31=?+pIhIZ}=58jseQ1A!Z+g*o^93SrQj(NCaA>(NFVa%1)Va6qGvvNPNJhxQ z)xg<{wBc1a(9+n7)#YT!jZmT1QcM>rYb~%owx$-9nVW;FSaW?|(F?MF&O2NREsael zT8BNJ<`%eJBM7OXj5=jhj`Dm7>)pYbyH{hjEs%|wIN5@?nf_|1)VQ~-TK}il1mYwU zYyyQH7X3&4a`bU$=s&d9n+=+wCRXEqdF+k9Z(DaPvXMi7eS7Fj#Tyx}7t2OmjojIY zUm#DEo|%S=Ns~@h#)EHmOYB$>VPGS*nutUUL#DoHKNat=X7aNU{Y!XMr{KtIyNUB( z@ewkK5Qsu(1a;S=bi@m%-3<7KD8>Hpa1XLu9hs!#)$0WQXbu`h{A!r8WPSjKTANZ4f&hj~guwAoXaOYG;f)Wxb)yq<^8YF`8us)m|H!|Yy1lIp`-G{PuPN@j&sK+MJanloJa zI|p&b1Xd##zs#p@K0VDP(MsIBiJK32gVqLK#~;4;Fe(t%X}DYsAUwC^hd=m)YyC57 z08#l;D~3egxl4!HP~949SV<>#pys?vbH$ zzAS# zUl4ep2ewk+Rd^Xuy$^pfjDCv}7dVGe5^e&{k(oESSKohZHeulhs0G{)f%8!5#{1An ztaUTE)$5QjGI5w+jOf$xs5YW`N8%Gfu-Xjp!(79ZnruoOD^!F!y`Qvfd0yzXdN2 zv(9&qS?8nA$64od8DHmh%3-tKcacrj^<3-M$#k?2)6tM$#KiJ!J*7itAf5`KjzIH) zr3M%q&SM5r+$(_;HG3dMIY4Ax7gq%_A7bbgLdj;>Ye!+>sKpfP1LE%%=O+LcDOFAU z9cYBGj#7#Nq;z3?)KcZkJ8%@yLaTQmbx&!2kWF7)Y-TA$qVN`S#5&okGOwh5bnjVU zST`KM7`->T*L;aE0n6?xXVD828fzpu^qvyrtl_+zn$v#DznnxItyE6MAGv_hg1g>z+${j3crvt9vf>x(+ND z;6#B4``RRoU>aZOs?)n^ZZ=Ow)Jh6?f2O)GjP=&Qn|{;WvrM(8wFBK49>=~MRqg$O zt-VRtTWIc{UNl#^q*~2A5d4hnm_~Ee7AG2nx+h7C%TH7n{u>1{iEGhvn&?`TeG5bV%TW}6NJ$$gkF!V$?7gQJ8^8h zv9&Fkj-VUgC5B|PD?N{6PZ!!d?tb%GwsBzID*SvH#}D_LkBJt8@N56I%ff@Ldskv% z4b{x?Y-Hwe)G-WY!Vot>r6KNP8ki6)6u>ZS>%g!X*e&0tBc5nvU9-iBzlX!u(!{Lt zbh!MrN14CkDDy8k%KT+Vncts0Klt4R*IW9Qqa8p0zSE+c@y8DguM-|Wwyr-0?xyJd z%42WOA9qZkJ&?O5+#cZvQ-vQOX!F<&+sDBS(4S~8&TEn>4?Twoj|bygQ=XQFV8nQa z_R>7p#+0~33F4}G0iv`R@`l7;5@DKfrqbXkERYi>r3{LDZsWMLi=GwplDy{}EANM* zzv5wak5dkfE_7PwOD>lO38hT))}?0rDAUd~G)DfUU^$MR39stPNAR8(w--`P-6T9s zQu5;b&<4$ima1cW#B+@goc_g|P5<^UtYe~&5YZ#aAUTR8^oI!rg$)HlDYh~t6E;-; zVf<-vdR?4!08-wl+z!fA(U>g`ohWax1OCG0jnQ}z`Zd=xq@pqF8H=7=t=};T%%Z6T zyXE+j<|uoqv5LWxMJ-#R3w3?rL*p-5NOqIf?+s#{dCc)c;v2nSS#es4&m_+J`A9d{pOsJ#OP4V}!fLeDDQ*+B1ed!{Qz7!PDWdc-7n8 z_7hj27)w0BiwWcQwi&N%@UZoBL9c%gEfh!JQT6}k?_jWt3&+P+f8h<5{F0o1#t#sR zE-Ew(I^B~iupufo?I690>#;s4yjGjzyf(rp(V3CCTx!q3=z+fs??|%Zf@#E)W?F7^ zPNAP+==lyb_5?}_-&*VlenF1Q(toneXtNWUQei+kEp~G;aDKymJu!ZULlFi~EowJ! zCwI>+2C4wk1B>9(f=JX!gM=TZH;()Y^osc=WW!g|^&aeNY89ItT{7mb#gZ=;0=H2Z z5`FMoMn)DCN>DBFRL#(Ff-%Zb%>-I4Txs4spa2f|Xlr;R7D7b0nKl(k;+h!))+S&wXXFdPt-LdE+oABmw zatZAeWbkS!+S;9Xl0BEFhHncvf|(k(KBdIk+L@~caa%F0PhsfOwtLL)OeA(w)rwYrM=4o{W@auuNId(!lN>w@NL(apqP44=vH@ahHJ)Msl^ttv0EK#VJY4Rm|2X;$N-rxHTv2ad zct;8>uBa&$&DN_VeP4J-s@8+PAfpj%5L!TL13U{|sQKVJKN@a)Ms{{!TWZi1e)FTK zuTM%Kn>J|Vz_yfNCIAV)c}THuY2BH2w{Wm5qh%3qzvkXP!i;Od z)D;mg5J+w|}kf2+nvoqc>HjmNXDgM-25197vl|IG-D3~Yh8fK7es4>2}y z#Fx?Is_h~2{bH>39Disn0= zd;M$^CNwlSiya$zcg5VJTp5l0$JHm~$768uRWz@(GJ?Z_+XyiA)3Cv!y<(j11C4}7 z(pFB#rr!RQtFVhHc+Mau>`cetNw}sArsJ9lc3^Hlwl_h02dBUPmR*<-VAfW5!uMA7UnV}B8w3%%w(CQ0S!i~lW|Z3bI;*=sx(x_iV5tTqw$ z{1%syElKufeP62|76I@xe-8mr8#Mx#M1L$3ltFP#CEAGoEjuWNXn7LO6x09I+!JG+ zK+pK~J(Mu%o`~UcwB&ij{EB}65T{>QuaeE@MSImKjnsqJo9ccecAhzL`ka_y!tcj| z88a&~L*-H5e$J1+dpOnTm>gvuM0a8yL?Pr|$>u=_2jpX2-gk`o`yEr1F($kHw#n`t z2ZEu{!GkOUMlIL+8$eje_!=nH*Kg-*G4M6TA(Ha76BPhzR1c8f)r?_ypT;h^MEoz-ITP8tbl1aRY05G`CT^xkUDhNJ$Gr}`8Y%>$vh{ztS z{Y2Al4ojTl`7bgi?Ny@2BQI6Z-thhrs5n1+lO-~)8@d-np!DLMk=8u!RyMVso&IQR z9u?Hfe};=AvLLU7F;#K6V1!UdR_85brwpVNXl3|*lWMOt z4KCm2go5{FMnjD+v|t`KB)Bi!3I(aQ5W#D>5wRD4;5ksf!0j19RhH&aWx6zPI<5=y za>4^}oIe+=VVT9@vR2?fBb{LOS$+dWasDaQZ{}@{t=K;Zq<9 zDJU9M;)_5Jez{W;fa4Cvr#c#-7UUJ+i5~GZI!n_~W(~?jvb4GoDknH3cc@TSC~`U5 zkE#k_Zhjqquy5BbXJvH(sZ#KS9hGQb?ee@V-1XrukXJUaA9#^Z15!+2;I~Lv+mg*h z>{kpLaAyTCLBi!kSSkR9VK1-{54JWx@++gwn(7R6Ju(ZPnbZ9_{GHA= z01He6DiYhe19L3u5YsvO6kh;-i2&rzSD&lqx%r(NRA9CG$nE_W%09~Wj_PMZVDxpa z(dJshfq{W5Xw6mgN7V2U{Hh=#euK4r~)S>gE>+;GNXzC=Cnc)Y84xWh`I5;}+yA!`4=Y|gbVL=`cl%+q4 znH+dj!&1m5(2K9713(UW`gbLRB5b#SLsCa^!}v^SGXRH%S~$TgVCfD|fL)K2JMY2S zKZtfh&tGgsSiVuVA}qxZYFL<$GBDN}GJ0rtL4|%?@_Cug3pS3RPyNUQHFj+cIBwUj&a3ca8yW8Qp+bC#>jLf`1Ju;!2e>~6fB@~DS$TTthut{!vLgCW-df=7 zDba6%<;hu9vOx;ll*%}S3#5+<&_|%r1z^LQkY8RFXsh!|kZ`A&kQZB7Z18ExkR7>G zawARjV3Y8CA2Ndr-<{Wr8~l*P^JJq*v6ZvHbN$n!t$Aya)|5g!jlU_Kj93og>H>_w zQ#J7f-}hSJ1$S_6uN4SuO{`0&)lDOFMpLDSWNQTa03H4o(w62ez?X>GQnwqwUHHWx za)K6tpy?>FL%;Pw(t&%b;%nsY7e6b!jhjw{QGj@nwE-6S22c?QVgZI~i8eWQV=+nu zk=5g)?k+x#$h4oFfdC zH*{fGV{|TX)f_;2Fd;W*Dpevnh~xeee69k@InmDpn}I5sql6!Xk}SmA+(%m0~GCRZ*e+;XTrWI(8mYq^gKQI0D7LH336=}o0F^cZ_o(P z#d5NPRlEdwY4q!5-w{t3yh5LqAbntkKWhgC^an zL^tC&E*ySxrwDgNJN5iuKmdo;m}gCXJ-o{CmD^W29%;qie=tb|q#PY5AT?2H{p-_T zG4Pjx0j_6;a0&iWe6AFyJ~fU(2?Z9#gJgcC225?@kGp}#xPFY z4C`1s{6EltMevFW*ZL9MVYqqUMbu0(IFwcH7XQwvYoAhrkZ_462Y2!^G+BCHb*28y z=jFt8Zi}x~M=HN7vO547_=PI69Bv>|q?9(rC@naTwZZD1P+aqv;@BtzSpqY`NwfBX zK4BCTn%0z(P{t)FLs*A*|ESWl$CNI3+YfJ1wR%%nTfYYi%B#-=hUS#uGQSpm!L7b3r0|>y-syZxR_k>~=Oe3! zyNf*DKGQ$f)p`X;g*%D0UHa>P0y||$#WN(%BC3ICP#E=PTiT{Jp6shKKM8HV5+szq zj6#GhC*=oiem;~R(0DAS2vGnQFYqupa-F#`9vjD)-j8{J(}NE;>K&8Yk-|tdfer{P zd^TnXOkuWy3$-soU--2jbjOe@_O}!%HQ#X5+w0fQ1dvhR6Hp1E2~?#acp>8sQUHQQ zAuaY@%A3eR1B!CLiTZl2=CTp7n^zDD9h=#s47LiP0612$j>m3O2e23*{u;gY3?2ku zFjg6Nyv{r)fbJB%{fC|2PO$#%xz_)7{To!VaSuXc(*UM_nx97RlseIBHsCXfel2f| zer@KeSwT0KAl81j-xalUPumf=jqv{p#6Au`F8)KV*7rfn;m5^=$kjST*;|y{i~}Kh zQhB0fP4rK3Gln@4?2d3Rtmxa!Bfn-S z)yR^?u>Q2Yi*%K_G8Q@rCxy^Rv`WYO;U%$O(V7rzTZ-#oiI!rfYgHo>(N}aQ#%O}h z1$SUg;--vSCvWp*FvZ$rL~CrV3CL^!f&xcS(Lp;P%mYA12*|-`RUh8>0}z@x6d(gp z+@kDq9LTEP3M>W~lLqF;D-j5k*#vMfNSFZUt|;VVFCI$>pv2(xZN+|K!Oa+uh)5eq zV{wCmWUI1ot62@Xq^iN&t|helvSV#GD*j)i!xHfb?_a(Kz+C2KL5M%xpLa%EcpaT8$R_rOBXpiN8Z`LQgTnJFM^CSV^q z#BmerIDAGGEJ4ev6p3jffdrD2$8)UwzH z3hsd>b)E(y?zf3WFOBSR7=8AtcSK0`$aahID9>s?Ow`pi(Ro*ecgKnj7_FxPY-FZz z2^i!xvbw=ZnkJT99~J|_K$|81S2-_jBR>kAIdfZR^4gXxhpX%mq~J?8F?(oI`CuBK z+Q>#jSymqJp-VTh+)zq6qP?3U^9Zc|zkr=20_Sb_vPj{vk4v-<#+tKlwv06x3Q6T( z`s->Tw>G&t*5(I5QNtINQ&xB+#dZ5{Kz^2osu?7^o%5qP&B5!X4~LaGVH;OYpD^sl zZqC>?cB9j>o?2rO*$;{Jd=E~|xvJYn91B82~m>Cd<;sk#ye5O+IC01T^yUzJ6EaQFQ z&KzwAso()s|MiF(6>iT&{ODLU{W4}DxhWUUOZvHgW0qB1d?{(^?3en+{gY3A@v_h~Id*a+oeEn84arM~UEQUe;oW}-DJB(JZRZSFfz zz9QY#dH@x}UkUrIdZAj*jh4q{>A8i-w?I_NYUbzQr5MfD{tQm$EE8d03xRlVKl|X@ zYChnz^odKOvRJ#V$tMDALjw+W;l}PUxxNHuglvwi$qo9OVOHFES z6aa4t}t<1$xY>+Pa6(dEx#PipbhJI-wX3 z3BZlXpK8x94+;4ZLL-403xCZ;A7!kixmAq5=x|D9iW6iMSL4(qK8^6A+a{hXs9!Or z9+V&?L{)W%aX=B$N|;#Hk3{3_9p3szRE81UTL<+d%tyb(SFA69=rmqu11c7J)S1#R zp5U(Ia2w=?lPn}@Kg!)CDvZDbP`X8?_cor^CJ~d zS8x)7cc&?wj9H4IFpx)pk_nBNfn{hfYBcpDbw+UET4eCxeJ$U+iL`928&41qh?ZWJ zfG@4IIN=%iTO2JdL~qg035bIl*PdeOREzM7;^wm-4PrX{|9`!yu;hE#3isKK} z(0ODE5cw?T)_5rCi;;Q-k<7z!XlQJJ&3kDE!)k(mNf?1<_)K^_^?2v0a~>WEX8+}q zYrwlEGyD|2WuTXS3qR3~v`coC<(=$+3m+!PwrbLaDb3ME$D|W@axcn^t1?ATuploJ zCahfAv2y&?`mYDYko9#xfUhaR09r2UJ8`!`QizRO2GqJ2Rp4cSrqjCLfIvFYPDaNY zZk~bkJ-B+*7OhnB-83WA4+4Y8q& z%Q{MX9bZjVcE7qm;mv=74z8ov*07wb!2D-yG||)S5?7{+`)`^A+`N19r`E1UkA`yC zxVYzBig?b!Xa_!$4NA{m)(r#z1>PL8*L-#S(qDki)IN5txo-V-SL-f7TUl*N1Qw%L z^IxB#fit?#=1`19tE;sQ-`eB{4gKflxn&vmVcjWmE;zmWH2h5l4xerYCi8m+ai9OJ z96jj1(usFpM;~7NCSy8w4o(7L%29)KM&UrUCKAIGUyJlw4pIzqPbp$g#kG;H^*5t8 zU;s&A4)%sm@E+qE>$&;%^;~w+_1r7enZ?@r*x{moG|+`JaAfnbC@3w7L1E939nkPv zR}%-LVM*}#_5l}kNUB|gOFVhM{)r970%$0{0Qw{{d-o@-f7}wA4!c|9&b&u^Yj;hyK-k!2HXrtvWC`( z{9mnMGK%4Vji>ayn%K&Keg`+4$u1!*Q6n3uYS0!1xXG>Bw6wJK0m$g)dq4;nO6ph# zz$kp8Z)W|FtMzTt2o{`#)BtW+_X0R092vnw!43|q4b1BuZURIS+M)tJ+?>EgnP^{U zCITv}Jl`Juu}o}hzKe?uT7|kN*|u%P_cZsTJX$~9-aWi4?A|~PiG)6r76JtEK|g$x zp{rn<%{8{Y#p_SOV3d~X4Pmnnw0f@LIlma)Fvr=Hp4bg(04HfTq+!RJ>W0XV#_fYd zfJR$RPB2}MBJ&gWsK(2G#>Y$Y{qEL&1MJ&O2_)Zb@a8&;!pH;ItI#$cZnr^*8wk*K zF`PzOqx`Fz-1-ktjzqrTTcOkTASPG0aQXx;gi&K-KuLBNEDSxEVA4t|f*%(yfxlP? z{%g=0$3ltG5WrcfCK@`0u@lFemJ`3%o@e`RzXz>Wq^VU%+0c(jVM}8E#_`KyLq=Dm z`uFUhr7v7OHr@%fKKl7<4Xj&zr;jP~xPoM3V&bqDq=Djs+j= zZ7+7XK1bDp@&Od3 znvH9LHn5hdYqxTVkGbSR={EPqM)@@z`rI{SeTxdUMa2*^dU3yTg)IYJPtdTcVZ7|Y zjc)`BxSZHD9j=1w+cl`hL(bR?p8qhI1~*UmDOPJmO->cYpF4JU7*YH;u0pAhZj3;` zDx7|Uwxf9|Tt5VL@v2pfd_F5!Ydid=3&9A4g7_1lGM=#Z90EwD%g6DSMdvlMtO*mx zF=Rx4)ejV1V{LQCGv%%LcnA+=jw2tK3$3exS9BiwNgOHCXv~G0y;BS6+@FPfCa-K? zQ(3gvj9;wktxP=c7@Y(DQ7dBX9CU0?WWj6bS6K(CRQ7hH?6rd^c4pt|$57AOr?`6! zazpT>YV`F|xPA;~$}x?2>O;>HQf)^xy$jDP@U~iSg5nW~0TEJXjNPC}4Ua4j<|DCb zIYJjqE29I6#B=d$2v);5E*LRR?KEu5g1d}18M6i5LzEV^k%_(ECUK$!HCY z8t<^Dt$m!nM2^t4)ip)2XqfA6u1B%g%v^5=XIpD+c+`wQw?6EzfwxV=K3P_KVYReb zIg}aKFjGAJjqcc7RcJVtw)!6@jsn0ZzzGWqE(O1c2T7O(1K6*~+{Me>*uTVB3THEx zLO)s{u@t6ir`R;`;jZ*Wp;wkQFlmRr>dclbO@H{7QU3O>4zRm}EqnrrEAFoeKkwk|O&?(sRv4 z|D|Dm5p=~D)pHTk`gIt?qF!ChQm|6%pL#_N9jJ{0IL=gR87&h)!!NU&t}Rj4uS^S? zIr#w4n?)}?WSLW_fA{}^1bPhN6mu*Tv#srL#dF=g&ET$TmwxNsU@+Dkh(`P2<_Oy- zh*Db^h<=Zc5E%@)G}cy#HXtfBP8iYdVtf30A#0da6ZN?ltFPgYAavX2#Cs&;0gRCw z?A7~ty{IJF2JZahBfxR!a=c_kui82aHxOuvKR4thvM!3CYPBS~R)}JLL_8lQ*y4L^ zhJkz(eu~y}NJX#XC;Sw3+IZN5ANy1Zx2finWZQ(;|4p`O(f}-zf8Gp)ifC_Nn5#88 zpqrboNetFL-WLKwnhIeHqU*tK0a)5FEVpjH(&Noggrl4gl2jc;)l!%?`KXH{IHbNs zfGHq;nZ904c99cCK3x#${m1G*>V~CLNvgap+h9eVPzgp-f_eCp?nnXV+T;Z9+2~js&XL%R4cV$4T|7vPZdK8q6OGL zbCDSSzfH2~6}OBpn>tuf%_SyFMv1TkI zch$aWtRF+p@RRogiIYNK*F+8Wj%y9pZ!c}wf<)YxU|PXeL@zdAy`&=ZEDHGb`){&l zL^p!e$cN}3`nP%L-{x_eX_)w=<4DucACjg;?-m}(2xf#w(nDWqN`v?VeHw*yl&yKp ziSfGucCH9uN;Fyl`M>G3*tAWEvq{y=hI^3#-;5q03E~r1{-ajU38+4%2lNjHx3k8; zo%Vj{%YZ{2?}hWvBR4Aakm>u}CMuGn2YHMkZ=fgHkgtC__o(Jyzy~%7V;y$HzttuC z4>0?weqKo#LiMR%|LqE+Bat1EU;v9Tw;E~=QLLjC8@B@0_?6g^n#3DHUYY6^ss1+7 zR8GdFQSF*UH@`L#ld3->v{?H)_8X$4Wdafjlg5tbp&4-Y;hXm0h4Cj;ilg&z*pEG? zhoOb3j(s<1m7IR~k~iDU@DS9@Qg&Zz)&5_|5F1pYRm*mGD$ z%?~||b=(p3!1T0OgHU#B!cX1}%s7Ifn&@3h&rMYVdgN=BW`bBl#brXnO3AQ|?hTe= zNi*BBgVNSwIgOAKKqQ#?#J#Sh(BR^`S%6_#+#7o8%4HLX6ru1W^j)YzI9F=#>r=~n zVy$~!t+@a`D*j`b9KFOf93 zZbGqwld-`TR|aBjv@PP1Gk@DY1qj8&TKEo0DoR9c#`pvnwIV2)(~5<3fketawkPzr z_?H#%SO(=|7WCYo5-JP#q(sE!j3UwfDZ!$O_@l~8)+2edB`+V1ypxgFd^`eJX8jk1 zTQXBs{UOi&siBH+Pinlv`%{BogtJUMLFHy0lKU*lZB~igQzW;Ua2Oa+KgcVxPOLz1 z;9W;nZj%D>-W&{X=}#e)&bls2MoQyCe+BAWrf4aZu{Lg>679+$x^O(53d*~~>)f=C z%BEy_q&`d5Gq`}YA0@tpMXZ#TIT#~D{C;?9qQn>$4TUZJNH#-K+6 zTo~K2aG{fQAbgf=7+wb&EuA}VkFIjtAx$9 z=6vN$bCEdFh#-5KZD>Mr)}O|vOtgI*;zo!c8%G~8%*^8dCdT|-*lKB* zo3UL8Psk$OS~Ws@jQcG7d9Va{QJhB%$)4Uv5}HN4k04Grz%wU__tBa3rS{BoV(z$Q z=AmH7nm>~H(R@PdK^-WW-cE4eQR|6YSywg4M|nEIhh`j4Cso&CY>71{9W)2Aph6oV zE(#Ae_!_47Bg~d#`}1g1#MzFW4GKF6Cmmb`Wj5Uu?jnIErgd*%8vk`~;1~RN#Ch^s zoIzo41n2|nfhPNUAgR5fXm3*q+za#{Er(8B9a^F@+$O?Xl5hN^kqRTkd&CSrjN8Wv zkL=4#5vK$mpr%64!#MzFn#3dZ7qyc-5Tsus^h@Y@iOY{8;?Q#{);tu|D&9N|;$~oe zBe;I|+*xW3U__dSF(PK@tQhZW3V~9AiN^-tw6#uZ2^dk1H?ghsC!1hnlk}l#|JlvfdN)b` z(7vNTbM@H%IUQYb#i!v-aO_=y`Z1)zS1qjeo| z1F34y)wcE|3kPf+_kb;)i%N`TbNA#PRICCkGCiPFy^OO6$k0vH19#13I4xrsVv56X zj*At^XUs1oKeCgu%ph&oP?A$nQWFf)ms+#jii4IzlTiP|rU%o_96G&c7E} zOzdQZkAJn{BdKYC@iV*A*#78z;)7hsrepfNsbgZ5nj4Zfb`VK~A!8B3Af~4yc~|UI z?LABlyQA|B^sNH=P$qDP0{LJI=tyvFw4)^BqoZX-Kci6eovVaaEflRYo}m|Im1ZpK zkp`9Ra8#wr*MEc~#?8+<4)+=IYg79>JK@v4e)}4CTX@!by{8j`^w}jdJ669%5>JmZ zr8FYhqNTBV1nPB0G9}*;M>5OzI=jL*^In&P@$OnGZ2`k*-SG9$1tvp++&b$EO49c@Ec-p^s3B?DAc~dq!2hL+b z_v{#cLSIl(m&yh&WHmX~m#h!Uw+kQxftx0jLPrKV$SI#Wv~T_SnBzp7cpO75ao{A( zU*1&~e+&=R8Xh=s62MrB>jWddPIOIU*@ZuK_`5Sm1N;Y)`y8OfL88t`=n1;)Nigi$ zcO$hr_Hs2=^0+`WWI`U2*Ls~jaE^TO zVogl`$9FHvH^>l?i7Cf(%oX{Y&Ah^G$op;$Fx%r)GZJLrPY zOaw}6p}RDpFxrYp#VNtlVTKBNuqkB|aw5+q?E@{RI2_EX{NQY!;HPtiez772!eXoX;|8JrUQ+SHX--c z<+!-YdLj!m2hso%O6;n$mB`saN~BjmO8oZN5`(J5fewI&&o|mXpQb)Pt?@nF;PaXC zdBnSOFax_FLOV5YdrdUm`vIEhZ%S#@F_H{GvBmQq^K&#(b$vKMd zw3YgcIO7Y=VFHzK6_GjafeHo4p;}uzPFH~3(Kw<2`L{z5D~AEdz%8g7VE5W{qeZIK z>KG-_=s2-{3Y9O&xg4}0dTU)*Q)X*v>yP}pn-Y_H((G0 zPor5VXOq1g&^62HY0OmR%u?k%hJ07q^U=XrsEm^n8k{w@zEf0vnRzLNE6GInAdzWA>t40PM z0>+(w&Yxw}N{S5Ia7+7?$Xqw(zmUs7f;0_;g$hk%$U$NQ-*A#oP6Lg)Hh*6@=YQdT z-L?!MI{e}1TpJgF2EZo^`-M+t;|KU3UTW)nm%_ihF%KgG`2YC_Ad)`xz+P*7{|LOF z-hn-lIhl`v4jk{j;cDwp4uW5@b^Xw?Tg?09{*bE*G281-ZtM$(yh#wh7_|{C5 zrA2No?Dpgx^?9k7}Oj?`%%!)=tOrBFnQD~B$otOjYu;&SP z$ttvPMDy+}0ol%+lezkrl>@WTezf=ypafq)696LyjT&L+s}}#;`(s-C0NDR{EncuB zp~c{RV_Q4}_TzC|?7C|?_$>IR?nO0+Z}g`Ub4;w!bHPK<=qdI_pQRdoO5=xWnEm^R z8fF+d<^a^fr2jK-^nZ}+PvrUoTn%F6G+wjG`)j#AVvagXqS)kpSZ1c8B-jaA(>5g~2J^-uC$bXz+9QyXB#R59i#UD-W0R!F|7fD}EiW@3n{9 z%OOClJ5&I662hljuVjW#uRGLcCS1XUX+_A>iY|5C-Hv&bY2XqRzj`Qft!?==maugh z{aEd7t;fr!n8QUoO+yBwIT*^SEiuqr0VEnKtk$+X0#DFY)vzNwIJCF;0T1RCY#7=K zN;(@Q)WkyVn303X6ZLJ;On+BHyVSC?CbBY93w1^pVr9a4x+c2N8vEx#OTt-`DQe1= zaX)Ym1~EFYVzG^Cb5IwU`Du+@rDB{OJV2^N??HUPfjB#@(K?KoKpU=!gnIPv;g+mY z--nxUXJ+_NYH0G4*Px`qbHayGaQ}7Qd%`U}qj;TfYch6sugUJp;1XL+gxpJBcMb}P zP0K?X7zFGJo#1tpvl_ceTE7 z0Q1U63IiYf7pF5|V4wr3_#)f>1vn$|xz_SE`~G&QApun;8}pX?!)uQo;UvjBs~fle z8g3vu4qO00fTp(=+DZmtu;hmuvsKBzP$l1weB15$AVD$TU5#8k1D!1@-&*ARi9H|q zm4ftKm9J_nq-Yo+&D6_H0RIRs4f3R@b_Z~QGJWoNSh4wGNn-zWtGRl9Qhy5l}$6mYv&U5t_)J=}QUEO5s z?dm2=e?;B5^?$)lxHB7FRBb0@Qy4LpZs}~+z*`Uwtrh4PM^N8z(Q|qjuqp*b+y3WQ zIj(_d2l#svebftQcPe|jhi&%H+@RRBy~I4+4j}GRgO>n$12BpdsjJbeF?aF*~C$5#)ST*rMKno zTjlsR{(g$TXYnVvN(Yitf#$TN>Yl$Q{uKj%#lT-N@UdawlJ-OoWa{fH)qEm;k=3ym ztLZoJB6Y$qavO|IuS8#vx|ISc!B~2Ern+ zyFAmuoeEGQE%9QyRJQaX+T!5rz}?6&BgoljlZ~^_Vv#jD-R0Skl@m>+5@};B#ABL} zkf7Rg<}H@Kf4uX4Rb!$HomMNRx6pdX)qZqgwt16p-V~cR73!wDyq4|lE)Vc$tc^DT zs_`Ebyz?dsFYKB&h!+UNV&Jp~b~v0xS=D#Tk?T{vimhA*e&Cy79_6bY#}UY*ZJY|8 zUrz)cwiduZq;=>o)xs*j&}p+u9wSVu{(*_qPb!}XK1@4f-DM&@k0FhtG9?2(v9H_h zo({9%B-V7*p7XzbMEdWZWXI=*n#1GMY}5ME<7^Y)LyV}(YAEHjx3CO@Cv*;!DywN& z?xWN8!W>B9d_>63h1fh;WEu)P;CVhzpB!DKY$TZv z=&ka;Vha}=eyWhNuG8FjP|=}%QwFnOx!-S4JbJr4@LV_JYQ%#ut+MZ zX>w}skJ{WGUBvkah8RY;;#w&LAfi9d6UNtLIK}lv)G=RkpuKd@hv^Vu1sMaVcQ75- z=keULGEE{px#z?4NjBooVKgAxhnME%O6ESv{E97eppOxRpzcDDFLekHvIiLQ2?5e} zW6nWs%OwKT`6}8I4%Nv;_H)!zLqC*aeaKT;f$!lW7eL6U+C5G99zIFa@nVi24M(UV zt%$yLc*%f6IPVHq9LXcu&>Ll#6`t=;M7>{N<~0{t_Ol7{{ItAMb?S#SbLxE^asG6?1p-1N6>OdNU3C zV%m*e{$oQeL_Lt!^#U&(&m!J^5gxa}u&YfO zj33k!soEK-+Jm#KBOyIfHKg|0qi%qvw0KFjB#R>8+q0D-;6(0xQvIgz`;Z;KB}qMg zI-oApcQ1y11ng;^!7$KTj?ed@I2t`ZM;aL!(+E~oGUFK@%hCD-GHUAN*Il`zypzfCB|~s~X(G+fQI5!jt)NpMqjX zq`nu&TNqH#9y#+vS8E!fd7RrYwA~gcDB`Z)$N3Ed79>1Fu#WD%K%RP;7 zcRu%YwdMHn1-jOtMt+@DT7OTB-Ck&RR@BL zXy+COQW0q2V|YB0C{?MN7w5$cAqcEGG|?bua78Zwtp&^Ulvm)TxF~abp-PvHhUI=^ z8(g_l_P_yI*#AcFp*4v1_ELE^Zr~~8+sTJqGjG0;7qJIlDlarsi;dLbNO`S>u>14C z?q4b|iIfM7$vL#2y(#vBnSHK1bGf^_Wmxm|8=OxFX#G<#0c!P#)4b1e2te-Jzsh7^ zpP7|}zy1_S8-0exF}m)3yo~e&l}`C&UXFE`1_hAwC`N&#=&OF|)?u*9Q73u4ahQ`l zM!8S#+l5ScvHeI$0Aj;jK!N zI$3j9!Wr_rLqJmk5HD%B(K-Kg?TfaJm-LX6vJrVOp_vozO|ojc;Ah|mTPk6C6Hj>A z4fp`SNg~}_`z1=9M)mj}BUu6hl#a7Mg8NxYr^fS>UTppGX?uTY2(1Kc$Tlc@m;83T zEF2^Y{CG1NvPC_C$hLAyq!8b}I1t!h z>C40;Dpc=?10^o%9n#HAZG$%==U*9zYp0$ zJo(bluxpX%VmV#*MKMe54Sin&_}(GcgV-@!Pq|h?vExe}+aB=kAHht$`wnbNl_L#( z`H)PXL#}He-+HcrD3`yd`8-*h^Z4EXUIlt(TT2}m#EhX)wP)~5aBw^Zj7Jk+Bi zyEFV|N)T@maswAeHJ4I)kioZ4wz(mg1aPY~8bt^;8T^(x4Qo9>)Tc!vmo1U*bRII$ z(~LO6jK*h1#;sKaxfwSXanrSKv~(ywvv}rl${{oX?@m-(njN3Y8P@1Kv5>CMDpb7` zXZOdlU%?`*kLgCy>wukJlgH1s(`z5;^(KQ}8Ak5#^t!YF%McvOl8%*AJ!EZm3?{@I zc^(Tp%0{mnDvyI+xkWrJkzPllS3;@+z1H_zB#Q;Q+n0}vNwnfR2ciU}iJHg@GUb`l zxW0%aNCrY>+%+pSM{)y&;+3K~gVaWf4nTmbGFxP14y3=M?Q%Wn1KU&)B0)ymF+{eL zf<$(X6D)m2J_!mh|YCfnc2JltHX?+PUAq>ob z@P!t%MTULg8Yk|E_5h>R1m4463!M7%v0XKP5V#?Jy6}e~@8S3E85Nj7kqhfV9z$LS zWtxZexTkU9i&4u1>}PC}OcKmpVt`-#rJU;NBXIME&f?N8IZ6+$UE&%nC? zAYnrd8i7>Y$CFOjXa#<8zOAM4LI6i+C8Hfd1%VyLT1h^QBT63Wbv-=7XdYTgK@9hO z>b@{WvOT9!8h^uXQeMZO&qdO-RSI>PAJJLV^>8onj24r)3wl7L9j-^xeGgpyw1acO zwa~SwJ|N8(Ah`bxJEW+=bCJ!1Y24y1NBb z?w0X$O)l>0$>WRzRO-&(DhHOkGirrO^2v{$MK~*vG&9%j#g_7^#(@?c&Gka;b^Gy_ z!@k9d;=Cmo9db4ZBB<3J#Gv^QuYT{!?`%F(zX$RP@?ak2h!LjgQlhpX+Ra@@Hq1H%f_bB&RW%Uzf(` zSF}M^6y_P+Rk@mXmc}9AzMjLEVvORKei`F|4(R)Hqp~s)1D!G0)ly{$-RQ-TcFPb` zs(gwY;1EcZU<`hAEjlbfQIO}4{4VN!0EYmg8c+QLygY;p*CC#3p5PsLnCF^KT zG;I|)h{UbTk>jF-(0EkSbRvS~(5Y1zJy1~xa}wV)u<>$4JDM(QGkH^Jz5yiQHTW)h zKaQ6w{adKfK<7SR%_i=Eh_~4hKBL33vZe~i5vN(nXQr7o5UkJwicb*;2Rm7ibug8s&CjuT-fmU z2A&TJ+8`0RIq(DCY|UGYZy-C=sUH_$~%Xm}q5P?8W1IEFS z(BUeD4Ae12raA^~cMuVBF0qRIMyp`01ab4?6U#>PoT)8iKY*aD{cfzn-0;R=g-R$< znlUJ`?<7oLl*yLMrGKtIB%dp}-5@Lv&bKM)={du6HX;kDO!ZgIr&*4N^v zeCB(hsZHmjnAo(3iV#iVQtP8@!?RZ05SsKz${oKQ{G=_5m4T%~b!vQxl7i`og?$zd zkVnLIf%!fKA$%zWzSdZ7X!guT8bHuF8#oztPQ z##t{9o-JAotX`2JO<6?@yo?NHK9W-YtCWFeWJSn*->@o!cu}RN$B*=NwbITA` z2?`Hggn@uiKzlz6Pa2H>0F=VUQar-H3&DPwpQNO~1ck9#1FbBKfsG7h|0#{>2iQcU zl;M4)+;y@{pVLsMLV+*#0F)P-Mm;L%%)4LK%2)}xo2MV}=B9@(5;U2mDpZZBK3+U> z1AfaC(Q6$n?7IClU?l;>F>O)kY6q0)P&`-$gI-Jc;*rFOp=Oj@uoj!)y2bG-{`&EE z8ve@h=Sb(~htdDI8RGxWZU`msgeAm1XX2wdFS9*Y)<;u~vod>x(_@x$7f`xep2sOc z$6r65rnbpS)-55{Tfpiug;MUTuE}Af*Ni+}hXhiwU1c57uHC zOm{KLij=3yWEoM5Sv|m2CsHc#g9&BpNySrq^pcZ}$=PldzkAfq@1T%M z5;G~TFV;j|d@qI=Bg@>4UwDk*2yKpF7&XkL$q1CEwQZ*M6eLXhMf2>qK6n`R3vLj! zowTa#7ef|(llU)1DDd4dS)g2{K!yJFmpIJC^&s?kH?%|8X~xwBWB{c{)|n{dPh84z;` zCJif5w^x^MUe;#NKH203PXQ*4IVbkgXmbzBNmb>n=3;(T;1Qrt zw6I?2dSqT|`2EtGP6`ivv7wr{_Eyo$yfqfRgomalr@rI)npU&2%GHzt-^CHo48$Nl&kVS$LMY8E6bwUYhk4@{Z zWGxREwM1sHQ;eDz?J*Mth2K1+JP(?j`mo1>mer=KY6}~kIMg!g+XF{>K+U6|pb!b~ zNQJ(L;+WLLGkv-z-3=EF@fe)V4eOB^>}jjM)F6B)_k`d42+YN)w+ag#)kQ8F=6shAN+;9-691Kn^na%1d<%oQG4{-k@Mi_x>c2_@ZV_CAp_>Q()jx7qkfRx*Bq z!@^rk=O{g0Kq-I+B4E*WS8`?0Jy`(R+yp>2%kdn56+y?_Kqq(b@WpIx^A_B1+DLw= zfBIGCqqq^R>gTD6ZBO7{8&<9)IVcfpJ+4bZM_6p*1|CeBv1H>iBYY?poK!vV9efp= zk+YERvy_7lzDj>d|$*y@B3k=VUBnDL}MVbyjJ@(UK0@T!zMF62~_ zw}401`B4J>y8sd>G;6UR1!L)?9I6VUz5-Q|S`cO7!B~)DOQ1ANfBbUxSg!H(kEwjh zGoHR(#HW0P6MguQ+7g}*w>xkw z$O_(7|DEve+Z~V9IqhU6(~KFa6ZPqabEfVJ0|6$&GGs58CP$+IUFIXv%=3o$d{y@N zN^OOYe>ws_n)39jlLT@EnKXN^J($bk--GB{PJQ|MF`WYEyaeY{IcR>2!``Sa0z9!B z^I|vViU?l|FHxAcZLY}*-nZiLhKG{#D@Ksj(i$0>2q&^?umQJZM#4LR7A*~X&AP+w zxaGf?f3?Kh>k5mYre8P3XsA2hP*)|+O2^*k9(~U`6`iTEAD5nqP@ER^$eesQYU3V3STs$ILRTvT zri35o5Ola&MN@dVVl+9ADcqixGAIAA^(m0djKHbi9j(ApO<2TQV-d;r7&& zNvagES;A!dp5WTQ@3%F$ADgu42@4n}4W47bF(?0YIWogmO4xC_wz&-j=`$Y&MQgm( zhV_g1a5@~yc4_CvmO!}K9jjb`MSu6&9%NwG*f^50t1a_?h$W92QAhWP@g@5qu$xu? zUAm3WOwv+n=qYP58ta)v21a8%kLOo!LV@xt$uP86qVvs;hbjdLr$^^!McfwsHbk5_ z8)6K*!1vfMARI70V0UX;4hXc4@0SF58^=>6>4wQs0q9hLl0G#AdGfQ4t))st|la-V7!r| zU{AJUAmgwXp&WY#*TcS8Yx}at$SYmmXB+P5pjmz*QfnOLs(<4klsF(Kei5dE7YT`?4e(ispW zHjP%Egbf!7%Qo2@FqZ3?*g5*&XyWl9;x8DH-c6~G-A9ZhmZ?S9Z3CZu+ZaEZWF9!M zFHS!Y$YAR_Nn1w}plHU(ta#*y>M@m%tb~t6?Kbf(u`)bq>nM_0>>1Bo1=*fe{n^*Y z>tC#3!XcWL##7ID4+|*hddD1Wpsj09R$hwFD9;!l-#lQn_YRpa;`N6g<@b(IX82J8 z>IkJ>(!Om=d_Ga|Lu#9>^$fi7G8l2B9ocYb&-xvBLgvIK7qwq1Ek?9Td1KV?-)X@^ zH0r+`?ur#{pUsfJ2%2dtL-mgyQSVEWyl1ZrIO65W^Q;Tv_)}HZ58QsLk!FX`fJeu< zhmuTq*&q{Mj8E`WVIi1BYt&r+zW%TaEtmB@L;)OcC+RW&ER`mLn#iC@_+)fN8rI~D zVyN^6DBx0r)X+SY|DV0@0j#pD{=Z`brVj7WAyYx8O~s^I0*Va_g9|7OE`J0}P)f4v zG9%sfPca&911>KYP*JJ;gGPmgN@0RwI%IA$_Jx&vZ6@DZwd!44Isg0&zf$-2`JCr@ z-}ia%pD_^q{=*vgec$K*Ip;agdCqg5bFvW{9t>v&Y9Ua1tOZOoyBoUqh7(v;_TMwD zfo=_8KZm`v$oMf{&{a%e0IEMh!N=bG9ma)9vuVRhqgF!uk-vc?g@sn;OTxIpGGa&XM?$P~9Y|JR~+Cq?~Ax=h`U zgO@m+HnKSI;ABV#04JTZI8(Yz>G>VsdPC1Sqxxn|e^b7#+cx?$5vmX~t2`qe>%~hR zJX4km-q%vxNQ2W_u@0SsWl>^K&Q)Z_j_zA~Yw&Iw>s-KjKMke#am2VE*@{nG)73hTYmsVE-=|WQ3a>>P z(3c>a@uKY{j5e!`Hu=o6Pp^-htn+Z1`7+VO&@^MvUtDth-omf^mQW#tdL@Qu#%3eWH;)1?mV#N}V%F*BV7?H3>M#lkzT7njj*d zGom9!i)2H1&Yr z%P7GvVl0R*t$@LS!JC32P7XPBl*4D<P_(Z^Cwx_j0)<%;gHtpYd*NwX zY0Kc4CN`nCVL4}IpmBLC%i%wz@w7kv2#Sdw6w1#}@+FP(^TVK21@E~Yywl3dI3I27 zN65xk8^DGW2dW6&gQEwlFb+?;>y>InwZG!1v_BN>J3cJ(-slg3B*(Y;XNP){-AUu< z4|F$FfWnarMM}^T^#4>y-$!Yl`d3qFs`~$Dum9CuW75f!v9fNx!wuH_8|f1Eby?Q) zyqy3gyVZ)oC}4op)8mOwVC6Y+3(gg`CvGW9T$CuWr(#nC%innDSuoG-kjI{l$Hc)x zbbDe@6YMkS3~7FD_46dQKycM&{2SS~j%>fhF&_ZY(_H{FK(d8(f^{;i!Gzdnj6@oq zkU;Mw)+m~Ips2$@UrDYD;Vo2cVm~&B79vh<*@+n?sy47_`W7+ku|m&Q*Yz)l$wz2= zbzMJNqYWB82NMluC-l&P(Y!qkFi&jbjAQB;q*^kE;9+4!9AAU0morVKklhXG1LYv* z-H4{j`zfxUBV*jeBQ7|IgI(P2M0mKWWh?-g7s0F7SS%vEI(>-UIWZ-h+}`LI}L+IB#n+=(uz(5Z@E$5$KtwJ@Fj4<-?9+Aglk z31aKgjXwKV`-=5<-tR8%dB*4ZD2cFO1t z=|C+_yYgvCvJRyi`-M?^C(PbvyQMd%S|1tKT#xAU(OC#F|6M+dVH|N~&oU|{{88gj z*0@P(%tMW_QN<{stLz+%*m1rO{VaJ!xjeCHLAjc`=%ta%(Z5Lk3bMiG#Go#)SZe?) zDo@~WG8n(Ic?PN!W)Utx7Prd(bzp;RagFild_?u-^nhAenP{M~l^8@h5*A)DHmH69Y`S8b#y}}=pi) z@x#a8gk>M-{5${mM~uG`z{9~GpFRBTYx642gume^;lrQ#0r=x<3jXF2e+yzh{4ry% z@W+fFKK`EmVDWdu?>tZgoPZCZ)~o%)B*4SLAD=z^6&RIf!ryq5@Zrz=0Q~Va1%FC@ ziTm)!jJ?7iGk*B^J9qg9I{zN~k0Zw4Xu!k4AD=z^%`z&@gujs};lrQ#0r=x<3jW>z zc}2Fb^x=;gdxbw{{4nt+_6^i>OsB!z3OvBT`P!SH_*>1d4a-EIY^2S&5@~y`>G=BB z)0~bsH`AW|pZ7Y&8<)9yXs`BsUBl>fHMspzEoT`mx6V>62h4I-j5<5ot0vAVL0nXE z18myYEafn~57tul$apu(4`=yYUo!Qx;y(}erL$d?DV}oaf`RH&s7#@EqRRAQs7y~^ zhCYUJ#X2snPEM(mI!=cvuI$&VpAlV7<>^(=2&AJYX{FP<*;G13vtgTL8Xc`%%4}Z$ z(LXE3Dn`_m;@;}IWaBK_`!G59pt3qbe)`*%TI{E9PqBJY`hcIA^Ep3NonyVRQV2s4 z2~7glqYXPGeXf|LKHEhBT*k&ADlV}99pN{X#+2tDm{Q0NeVAzXaZ)BnAYB~`!I|xH zgqZbZCA;o?x%xQ)RC!`?q22gyQWh$7I=9%b|0C%;P4qg~>!QI`cjMLGfO|XW(?s3L zZ@|7mI(fRir8}uOl{6i*af)JJ`DRiQ%rOETrAShM&^3HKxnqd$8R#fr4KM#^QVso? z^e&v=*e9wU-Kwer(r5l&DUv5X2cO}(DqV0H`bq)W!B(*ySP0slVd?mD30s1nE6*%|D2cO*>>{du{tSw07+erMI&-%>N0>G~tkf z3U`ay$`f`6jgtDI97dd@jwC!5bySh6@Iw=DSUi7>TK(AP$NZw;Va|>?dd>%J2ap+bau%BsdNOaE7bD*NX{gW5*{#jK`>RL2K)e%J< zdbYHW7q*hGUPY^K{~$!L04Qt89>eO9#%kbiSU%?RDCZQA%YnpRzJN(u)t+V4M* z#+q?ZqiW7qsp>$@PEBjL@R?zvK1xWIe16=$e8j#ue!J5lcMBi4_@t zFNH|AhcXe-XpTD>Tb@vmVHL=TG-s%5rD(nyT%=7^gmfG)$^n#gDZ*)EWkqBb>(~c8 zcI@Xi@KrP*kRU{W0iKJ(GdE6&adVzF3vT2CLPIyMdJk@3@{MzJSI45OU_NHj@j8ht z1ukD!Jj^IL(m{g={`9y<1PHHF%Uzs91h@k4fi2*xR2O8S~`Ze;YF z4c-xLz8;8p!zXZoiFWkS-}@=LV;hlDeIQZsWq+OdNp*sXSQRYlJSsxHq#|E)>6-dI z?rC!(=%%9g&IFMr9V_elVZN7Azfd&~OXqpyuPG#%{PThIt}yxun?OJL(?9`z#gVj1 zWyj-X1h5{3LH-q=&OrKwdLX1*cv&Vj3G+rRnua*2( zs960B=_3#;J6KW4%PY8Dnb$kxr~Quc)AU;jJct8rV1@f({M6N0TISW?%1MmClM^lSay5X6V77x?xN9`P5ND5~7Mp2qGdgAfhaA6kg!WH$|_ zdSR7ka>&DbR`X|{iLdnj4AL1qSwm?*Y5?!x8Jp zS3%$G=*Ri&>BmPJl>#|w?W0zpgytN|KFa(6{WxEp1$?7pAGHN2i?rS6(~mP_uk_>0 zXrT5(vXA=y2aCU#>W>(IHGqeMKR$c-t1v3fgug13@Zrz=0Q~Va1%Hnbe0AV=}UB(r>m^8v2BS-7PdyDZ1r>9^KyZf@i%8)&?Ys^oyR)2mo> z3GfGsC$D00hAU=<*^Ezy)vsK_n~-yDY+UX&)-HId$i%!*UfgfIfm>!2j$#vX8WD9I z|KWBQK2+D|#`;O5$Mh2bOP6y(SK(7u+-PczBKO0kFg#`YQO;Bsqq5fGtQ*2aD}KEN%@LD{;Vtacnt09L#V z7pq$EP`=Os=Q27RYFx$}kA9#o8-`D6?_&RgF)mVEK&1z`Z*@q0QRBPP8=t5;Q|xJ} zf9|p$`a7?qm?P_Nj_fUSWN#*qY`KhVdFsfPb7acGS?W%dpdPHva{(?<6jp=h^M(Yq-k6}L_gX0O+pQg1}k`f zaTFa$0)FpnK34C{Nt{EShOQ9jk&(M^85_Wbh+8o)!-yi9xX7Jh`(%dYU*k>d!_Dt& z3~eg>KjFiFy89g#_TycR*@Et^L>OpWOwhNAhpa(1dPbA!T(Iw(<4bbph{z~YOrm&a zgC#n?*^s0#EJ~=05Rh<>CDqJ{TfC>57}Si~M*Qj@@5DcwRoZaN5bGYc7|*-YN>pDG z2-e<(sWBFiD{Z*>bp*A0C%W1iMMx>gN%s<}U#~P)I|OGW3Z3c<2{jrw8}3jFkcY%A z5<0SS(*gw1k+Iygvp-S^QZglci3VehytCtLphJf;KA2z9+d%C7aQr$j_4HN6^K#Sg zO+KA<@NN6>o$kC9j7+w0#9*Ux;2aN~AX++C6=TNKDMN@c(H!MxYA#XwH!can??RjJrPgImGU|X{YjAu2b+4 zaVrtY>~jdl_ldp>5P0wAnbXxWXPs$%Gso&i)NP6kiBX#=ij;LnD()H^2v46gGnN(m z8W6A_i8IxFL@-yJ0;EhjTvfBuoa|(zhE#ex+%JN^D7oB8E|JW(mpminaZRee3;7|c zQACkjS5u+R*39kJoNKHXQVQ^>7l#$M<)miEM{8=%XG?#1%V6uGc+P!t{#rdc5FPMY zWG?;X&2L>hqVAeqR?dCbniTFIA^HR7D?H77cV>K=*BjJ*u{H8OjH_^Fd;;!=O~cLZ zdLRILl%Pc(jo5@E>O?ZU7Sd8C5wVB*`^QJFwfaHHa2mQh)7Qd4>msH^|J6>=_&llP_v z8WJ5JMLiJjthdX*g!7l<8>&xcT{xb>xiC0}wFkxJlA~8#6gIo<7>jpePf=djAnihB zo~g;I9a62eTRO?-hU$~>Z)@8E)q7`&mj#2_0m z!Qj3E)ZKtfXrP)eK=lcC{`RS#$9bE&_Us%D@!q^%rJ>Nh6x)kVZws=OXJKq5eRtmLku}8_(5p zusEU+Dxl6OF{*eT+p^0C&B0oUBg|;t4jKi?nn@cTLC1!%V{SxZd`#h2dB65(!!is*90@$TpC&Q^!DLroRQdj`X3RGY`E5lKR zIyj>P2R%R@vO(=83E=kjs-IEUsqH8_PC`!`szt8u_!sI{&siOBQj)HABP7=)PXf*Qedrd3^nWygK4}$9nfws*1U!2Oa;fstlp;idPj!p=d60Nrsc^CVgUX}t}++oPcS18G4| z4ca2s3eCQ5>z_I8a$Iq-(g@#x6TI`vf)1njH(OuIM3aD?$2!DVryEV zy&rzAJEr4+{?bAO{0Y`h5e0a%C%)oJo_kDu*y`W<{cP;+D1qS~s z{F&?9vFHC@5HR->yMM$Dh+o#y@(9HVn(Xx??;h+y-i5HM1&~8*os_(>%9Jl z2{PuCO{^s+oNmF}Ri20pvP<7>zq*TzqxPL(&1U3+%kD>?z(UxLhV-TFmeriJMrc8>j#Q!ve2aaH=YnWDQ2*azs= zj#0|&-@|s9Yn9U5ff2HE&L%UyhFgBL+DE3i+GTnRS?mm}KbQy11m9*MiCNe46#an6 zNWuRl5B_P+O5dfM4JZb4&I2&S5J@dX6${iG850DY8CA~@!c(B)a*@uK%ZrxIy7H~& z*cbD#2IO7^bs-iSg-Rv6F;yqY!a_*cdw)Sdd)M@PA-tx6ks9B--uTih3uJr;`(u2v z1nBX7UcKq@!3R2=t;;yvP)qXAu#7{6NV$N5D6{y}-N7Iknhv($77)DA8S1sk(&5%ik>W3^BdCc zH95*AOlIK{%9MSqX?akWl~h%h1fqQ*Ms^}#kv5U5T8A>#b-4m22j|oB>^!Vg*0g-H z*pNdO%eVg>3!PHO0sJCaVyhRd{Sp9dRbr>OjlGVq8Hs=0jjPtmonqauwQ|tOMK9C( zxVNZ}3)Y^?3bcb24oSjqxlt%yG3iomtA+=lKkKYdMbJ_H0%RxaSK%8)D_H%kTv}H2 z{|yh{X*Y9kh`1KT?!Y=3 zeb|jnaAHOdcKu7=lik9Z=wN|jJv^*ZPc-Gg25IKws7&Utp0#ITe}II^O4StX|zAE^^h}SUFpp%Quhq%l=e|ZHWYT09c z;A}TTt+8l}@_LCWlZAcf<>I(52mv=T>4|$uY%~9b8jw}Zd&5Is#Au1nXbBqzp2j4*p}{&X9*tlPG8+v; zWmi9gTWalPiTp$t+3$F+K{nF~=a7->TuT!^qb&eOZK~)(uRR=@LAv9(;D%FqtZ5gI zHLfMFvHORb&^jgf^a|4IbPz4}lHVcb8(}YElN@092?2 z8CO5SjPtt;z^pX@!)FgLR$2ROd#kQx42G?es9;D2fK>*$i$m)U$Cu4QKf@Rr42RXw z_QyiTcD-r`2Lk8Omu%(6B%1T%tj<0czGPjwZ@SgT`UPSROel@E1Xs-^x1Dc`4hcF{ zSXd>uiZ*hMk!&$W!e?~1)dYL1a%d!Ahvl&9TdRN_Y6ap|IV;p^1qbXD0u|WPw12$O z{@X_TeD>NGk|KD}1zO*r<1h&}JK#DBO@nvJrVifW*F7UF@{GQeJnT&@K6`ypctS_U zp<00j)P`nPpl!?u3#ub}(-qUJ=NO|aeD=D+Ij*4+ayo;v<3ehiM1yr=ny!>r*uQ(! zWiB?D3!s?~wh}UipN6k!Qec~{Zj?MkV#CZ#W+~1A12tC&#@EW=cmfkm0By#+KiO!t z$`~o1F;dvpsd?W9?C%dpCOG4S-#9%vgaF}~QvsdInIr-vANLWU+5RA-{RfQp`RuiC zmD!FBW@I9&LnEj7J1{6y2dcKSeQ2XRKUqeTPZ>?}8BJ=ois_?^Rtz-?w73P%-p=RF z(~ZO~H?i+_KC9ZO=}ew_?u_b&Hj?JfgB><)OdzA?oDJT5;Ir3H(9@a?$@Elsxb&nW zA)a~&ddkuC^j=1KGQm+~behi|K3!x^a_DJ@ADyRXLg&)$j>^;8qm2@|poF@-gy=a2 z;6@vL;ByK}Oky+F~2dw-VE`+B1wpVRk#vg-ZW{@$O} zbMLRt)O#lQdcWW31fP5C{YQ-6A2bT`IeqV^sNNU*d;gK1dr$RxTFPO9ulI#eiaXZA zd`{`TEBvLfqH}s?MPrSc`K)TDBnnoP^FT5yI`?o{5iIB_Se|zXR+LK>Hx@-ho;9cP z`36FI!H3F#4QckHetevt4j(v_KV|6-=e)$^L*7>(G7gIgU10Qlo zme`0i?1pAB#*WFH*dvW$&ofvNpD{hK6QaN>+i!@hx#0-);nL73M>MDIYh;>HL-unN zHNsX>6=H|b`}?&J$KH-X;1~q{FG4`+A8)wJ&_Cv;JA%q|q=Zdj?~jxgL)+^eVDbDd zCPvrx=#5C&Yd>-+^k{}^_XuvjsquX4!x_)!C(ZG=qxlVt%{e%GTouya_jq7m+6c7( ztTiU(c!s8$SgDVm!_(q7?3Z3ZYX@o*(SGXgLSia>^v|@;fK+SR8lH5QIvzOl>T78M z5lB6wGUoy6NBgs_z#JMBqLu4(D-~yDsQ)Kx-THg3TADHXe_ZeSKf|lPcm2nGlRR|% z7qsZO(m0t*d)BAur}l1RJ`|=svU#^L#8U~^@Q$EVYWeEtOZb9x{sfn0!!#?h57szT zD01_G<7Q=`W({q@D=Z|-=uY2@4Eb_o-EY4I5dk`0tpBhy+lOp!NJu#JP?l#rR7axH zW>GVv&)}%`_NEz5SO+ZzynqaN2qMYqPN3Ys5 zBFaP#=)qBa6n|K(@E{c_6TIkDIDN1qx!;A%;}3Z$(ZHa&_O%S5NVUxRk(e^L$S~AI zNV2iSHXb1+te4qeNQn!qf^k z6W*X1?rD}>U5V$cg%xhF_61Ojw#0osGQ}9B(v>?0tfymiwde4NF4}E9oaTJ>tkB) z5{aEga#dUSbJUouoV7eG8HHX(N*=v8&{4u8h9P%#)@;|Ly?-XiK>-($B)E;HO)UvX z!Wf|ig?egfQ|Ow<8ldZ`FwzA6bQh5kT5QfJhqm_CI%r*Mh^Zy(OK)#qBUn)x^9B}9Z zb-gsDjURkjp>dlD@rsk*vl1IPtsDrfT*@;{ugJ=!JXAH`ncI7}mhzCoe5bO|dtbSf z2a(=842d?7`#SAeOL?;Fr7QWV!;_!V3QzFzvS24$$lzYildC~rjm*oKt0V@|a zWw>bGd9gAElY2=?24SBqeFe*hA+SWx6+!3~EFX2a*0b4)9>gvNVW0Qdx4~-CWLH zls9;PYlaIfv7M8JRPF$qH(BK>uy>o4Mr+kFK=i`gqbd&-*2ud$w_*po?J;`7sR**? z(+Xj9d*;n>GkH8L1@Zh9Y}jPH(n}e#zMCeUx2mO|`qI{{xHSs!#L!3qkZT|dW9O5P zt7wuS_qTrE`LTpmf^1elRA=SJ%50F-;P@oH?LcXJ#+^8~DYI!-Oe;Cs$c1x~;n*@zy#s`!c^oDB%wRN`#8)T*hV!|*x2ddYsMtOz6lMrW;eeIK$H6XHg#=H26elIua zH?6(4Yd@OCaI|7cveBqm{elnzcEb+@;U`d~FfHG{7csJvVJjEjexBL9Gj%qfZ4zko z&J=Qkw+Is4ACCeKtjlseW`_C{ytbO~N*~Xf4hkF|$F0j)?Ap~PnhcU(KJNQs4On#{ z?#w|tg>yoBln%PdvQ#A}cjNY!SD!Ul-BXi`Yl@}DALew4h3v#FIdY)rUWt!I>tpkq zXjuOfvJBp?6fa&}=v?+v{mr~U#o0Jan1(HMJCmm6g)vEY%u%*!n{Yn}Gx>ZJ^{+VO zILF7!>g_S#z-rcw#_-|WofA$;ex8?33|8% z;4&PnS%x*-?wYOobFj7{QCr6Y&Cpx+4`IPd6mYq(s(dSeym-P5grX(j73u~8sP_QWH3AJeA_1?PeuvCuUC0TGYu+tLi~v6M8masn1Zy6_cfFpdnF!mZw_R*fR1pjAV9g#p z+Rg8%(e31S7;WCh$e4N&k*gLdAO}h-a51pGa|G-)a9y|E+9G-a<9h2moTVpOCnyC$ z^g45f25Yb94lLS4%SQ)0wF|*fAw4Od$*8w#J3$Co-->I0aEi$(@?}0Y*}wgN1cG;U zz*|!u1(jU)-J~^T_m{mj<krwYk=M*i*@B~_1_YEH{@>b{J)8fg0Oh=2qo~gRi@@XF} z{$YO-En?b}t!RT1RdwN(C{tkk<@R1~f`SuMS!Pw7eA!IVB1)bLt zh)FGzK@sT1q3NWVbOPgDpTyB@x7|TH5jNsU94U0-AA83=0BWS=LEicW4fCK^zwHBz zc#~J3{=%6*E^Fps(({fc@8Lqb1O4kNy1K6~jF-`#*Hyu`_yL?U$Bx1ZdaR27N(d-< zsrD>1qH z+P{U<%ZAWfS-3gpr#Z?CkI^C`;|`_J-J!tW4(9h5|NOoI^BZyI!9oVAtJWefHQAe9 z&$Md1bo4Ny;5%!byZ__vHm$p=?!=%CkeMJ)Vf>h{fyVw3s14N_PyE^<j5^yF8mB&O_yGHMztq0iJCvRn}0(u{IU9{)20;SoF z@M?{HZPdBTgA}-}sW@>?;Vtj=@Av=;^|CF&e%j`W~JL~v@rTQZFkh6wg1h&rNiLLuK$yr20t4Ly(> zFZ&5yAc!xO$UbL4D5vPF{m}hyl>Wx27J<4bN9nT%adxF&TwxQ@D?o{cMAa+T$TEt= zIV|c8NcFGyUXT7W!1wU`=eQ&K@y$ZBDIm`16VU6Oz)wKTUON>oa4Jl5o~*`mi#MJO z{^#D%_k-yOioO#_1bXgHh0|oXwa9X&xpv6m1Q6*MLg9*K6q-1l!4yGY8cpIb1X>7* z(h#4TJDtyTS)Vk4j=-8h;4z(h@yiQ!_w1|CAMzXcl1XFZrQq?H2aj~WL zgu<1f{1p=ls9BwmXN3x46Y}GsAz=)|1ri5bwWJ_mP0gQ;^*4!T|McDg zkLlLsyk2Y#bVhVHHFemg1W)e?lBx-o2SH*>Fg4HqDtrJEG}-|QM!(@dWCi^wA#vIl zI`{$#LsYAT|;31~2!e6V0zfArj?LP3+5uZ9t52~?W71)ve=yPb6 z*ezNa%3A?P(kZUg(po*Z;A}Sd+s1VKtuc%3bo}zK8pLV%3#!n)`4MtCllVI~X|CX( z#29bNd|#A4t8^0itJ@F2MbhZ|To$&pYXcCf7V-L6O)<6g?y6oNj@J}#!Iy>K#Xo`A zl;RTl`H1Gm#uv}ynmoQ3)L#%^RZOagRTPiK7nodf?Qg7+j|2oBx3fI{i$7aTMZ*s6 z)7N4h|M<@v64i~llka%Tnup3yiI1aQcw$CLqM~?Sd`j_fd(OSsCRP*|;3aHdffs9W z@yPi2;^ATW2T3F2YrLIdgYASG`loA<|pE@>Wk9fPAYJj zzhN+D#uS0WLXLDHM|z`nT8}3+Qj919u#WwfHR6I7et95!eDQ+vLSSeC5*B?+e~REk zAvAGtU4_lOwL6@cU1E)Z6f|fa9N#;iMgr=?FIZe0wkiO#dBsyO^t~APOBcL_r&kDq z>x07xx1GUZzrYXv=I*qAc1!;N()Zx+*UYW+wZ0j=W;gy`els|4XcH&|W&el~6d>O& z{4PMgI#lv|{QU;hRRwB6eQih{Up!YO4qR9~1>aEBzsoQ;G}1b|Xpv_yri_a7;G(6Ts^bJ@4>1yt?jPqZA(t z?YsP?9`H(SP>(3pKc&>wx)dp(JPS>1)aA+pc-f2>C_HP5SzEZAUdINFX4s9zn1<7e z?9<`Ff@7-1cDsCGd7pAv>}X$Q92B5RZ)FW?W@mMbf=b2!@mvp(`1CI#A+nW@K&xWQbGl;E|xzDL7eino21ICD+57A)999;_}ycx^~ z*Tr1uyB$-B>3~gL7#<$goKUIrB$cC`YbK*|`2N7;e}o(W6CWYyoJn8Ou{YwpMwi4r8`np-UYZT91EGB-Gn8qtu+KIhj$~ z+nK6nX~!@g9e^q06|~SaH zn0Xtm@1_2}Nj3LNtr>>oUd_2lHQ(gb+;Kc>reT@Xd|Xn^$EVf|i*T=I_<<^7XPrJ5 zcr~v<%^1~y_%`0AhT_!^jT2LAhH0`_bAD3IKYPN3#wh9YVyDjolWIOGwPsiqdo>p% z)x5x~`L*K+jm=KYgOX}KCADU_hVW`GOsct`SMyS-dB0Qhscy{x(P`8@rO*bvEO<2! zNve4>oK9)lI8SQMgWMt*9O~ALT2c8KsWrogfLC)-Qq42Gn*S}A&=}*?d{$D;XQ$ST z8}eSw#Yr_EfM+P(=UZ6wn$4&gJ;arEYOUjIwy5`W6N9$n9pOQccpk2@z)iDw23E&8 zI30zDQwE;&`55)9?zzHcv?%&7VQU{+qe`Fl^KYB{%he6Ni1XIBm0pP6HhHC%)7QTC zyI^1s3j>qjkeY$PnUgvank?rujoAhRn`|<$$%=uED`IVp;}iqyk7F1?_-^~oek7%% z#=su`p-W1`q~@c>z-D?i@9BF~8Q8lpEY##*ftusnjv51d*sJ+8srjfeu#i`CT@L$v z)EHPNR!j|z>!s$S#=!3KYR;3Ij~WBJ*sJ*`*?`6&7#N2)oh&SgeckeLl%1Aq{}Gx+ zE1EZ?U`wDp^RokDDN3NmvNO>gP*yqb55pAC#kHn09vOE%$ zcCI{f?Djt~523aF2Q=kVqxbXpbgzoNWLJD1E%wYwfpU`1IedpmnY*jwx4bX;`a_5xmiwR!&z|IO zk+ZGkn?UA(D!sO?tfrn8#Ab{_BXG^Y*@n&W`HF}_<+K6iwGlH zIMKHpl^6s8NXhNExK|`XJeS2h^&-+24$8O%k8k4~bhAUS^|Is69bY6nq;!>?v)9dz zn{HnAd?P!Iq*Qj!dpA3TTQ57V%(=D0hDv28$8fX58Jm|KhZb&j*leoo7Z!YG%g?g_|8l9x6Nen_D}CT(9=ijO>^SDm!HoH#>ZHdD-EW%&i@} zDrT2MYbrwQA@hM{?@;#Wgf8o0Rvo=0#ZT6G^q+~JfD}RV06qrqK}EkDxg|xKcxT>x z-wq4#_=H?#<}(E+{_zR8jx-Hq#20HqQEXz7HK8~*vDlh0EH-hNHDP#c;_!^I1qn5b z*NKnF+9j@_dCZUWqY%HV$%7~PNvi$R8#pkBk%O`sOLDC)zyzEF_LQr+V1A(SyKp!R z8)Wb?#NRp_qJjj6G?+W#ks5!?Uj7;H{+LLERql&(A9&-8X(V#Eq%=-t^-iIZO z>L11*U(H!>hqx(OE%MN(wPvNDl} z{)R_u&ov!?{;6j*q1sOOuYy;p2d_iK6MJYX6s-SKK(TNI&g!$@RA=?@v^Se(f;@f0{9?GS^oAq7 zt#5LXbc*%r)9fCrb-JtMv%`pghW-E?)jJ`2(Eh**Bw0!QFNlwJ^y8I%I^5vgsYEQA z!;M!q6ANMK0`vii6fI5$WM$1j;^iAV?j)cPl8R)WH*igYs4v*6ny z{$zX$eIDKZCC?wamnp%BHN_nsrK5k)ug`zjU4N>(CZ*L+A%1E%f*dW>+oeQ!p$c*_ zt$bSfC*x(C8>=6Hkd6N%)Yb<4;6NS$xELS{GLQtmuxLOK#?*k64uLY~Dol?{^YAZ9 z<5M8|f;B^1*d1cj& zfK)_Dta=^lw6FUd+OqhF>sK(jVrA-mwzS8#B$u!-;J35&x}LKT*JEjW-V zv{ti=k~LfqpXAIV=j%Ys;~DtwP~80HD!F&->U2mTWk2i>KD(MWUXO4xOkYD zIi@^e4>%7maa>v(v<3HB%5%#hRnmbBs+)^oEah|U$_Wq{eA#b>uS19Wdbj{p_4z&CnBZ84(a zZASX(D zXm0!+JjrhFgAPuzulKhx2yKi(8`I1-PC*-|fGj?L02e73dNXuzko~t?(BR1<>f8_e z`N0Q;lk9Jzk;Jw|5Q^hvO^Izc;z1E4Uk5D$QH0BJC$>&~)jK+k@P&+h08_2`RU^G2^bG}!*xC)LN8Qq(NJ5fg_0H7;M|K2^9+x4Tb^@x+(L z}?6V5ktEH{-K5n5Wkk(y0|HiY+6VTA||DGSamb8WvkdvbI9QW6Ma@ z@U;?K#;IY2M#h$LW>}%ov1ObXR%i^bA;*?+ZrI~yi`E`=iDpDwS;o5()O)ErHHP9# zZX=8~uEQKQa!h^1-9xF5@CSXO{0if8I82!xUnBeWJ?Ate@Z5#DW51xDW#|61dX}yG z57o2m-5*lVvU$H-JSv>l7lObGk-raKzoGi@UV2wVSi z@DtzGf@e6vQ6m!Hg7x@fwYnd~U6E$nU5MAw9gi`G!^sf}`fu_B z#LL`M)oXRtHNL73(Q7YrPgU3Hs-HTXs=dtE%@WqD!z}Kgv9haSxsZyrW(!aVPZamU z5(ciVto+#$-L^<4WZ8?E;C&T_ETTvD&RAJ{X;Uy>hZ?khis`DDJy8lN>SWL>n-@I} zAOyVLFyP6%=y4H6rxK+-s;;aHESbtHH)Xc9p2Uq!O1Q_e+r6^S!oO-BMzQ216vt*~ zCSq1~_T#YdnVv=3E!Fkq9L8m;|Enf~^<&g~?H8cfu-3>XuFHmyD0lI1guOW)oQ?FL zjo66bRz@A~WZ*mQYxK?E`Y28G>%xgan;0`P8{em6^AsM=$?~vJG;Gct8Y@}aNP2b1 z&O#`7tO8YI@NH7|PPDpR!GiQ?6x-|Gj4=TwK`yq#GKHbh)H##qx2$iR)@YDRxhtyN;h#-dhyy*&Gk!x;?1 zoT0FlS{OP+k)lP7$Y5{gxHya*GR?f{x^x$(ki>LX&;?{%axjOkhj=9$UgbpKy2w&aY1nc@URYeUMZ_}$#NE-Z&^&Su7pdU8FLbFd9*_` zcEOszux+Rw+#5^Q-f-f+6=2Nbn-E6U2y(D~`BDCL%J`4FL?}F~?zxSDqAop9a z2N4A2hDmtqF>no`T*X*t&p`s9!h?T-3iYHKDqH}XWC0jyUCJwDxMYNQgxK%%vZ0^_ zcPjGb3%14}rh{|UveAZ8sHbltJlYy{03X%PxevF{qT=I&=hbBq>rUB1r$2f*lqh;E z{TKv3a0saV&7J1{W_0HL4WvL30cC&FbfdAqIq%s1hO3k#&g)&-0~Fp#`K|BB2BjDKn`Up1(i~V)c3AtHdarB~B!;{t1F^Z8iEU9dHxVvY z1LWSOEopDVZm*h*y$xLY!58jc`|{E5_GSQly+I_{ml(wDjWvp!8oWB294s>X60dl> zoP8N~IS35g>s^i#+qlWm3w*sNLuK0KxL^~p4Zayd%~&jrT@K6#=_}0?^|5>&VwZz0 z4(dZ?*cj`@I}fEGCeTMdr;H=_W!&ZTVlX}La+=Fr`(3dfLf zzu`80xEmF?oy@qyImEsSVx^M)nygT>yT@ryMBA$Cdb7vrdANsY{QVA?(1h8V?4dP? zWmj$em|Glf>12nal4O6AI$Z8=)Nl{EztQRd?lhD-z?dkR_BWX)3Olb$VGw{+EY1EV zU+r)9Tgz0dJ?w8#-xW#wn`a%m&=K$;Ny{8n426ny9FiTAR6lUx>VH84kPoZ7xDLNM z$FjCy$%W?*=(Z2M4b8hH+gYe*D|iYoZ!sL)$oVT(e1oyZ#X_(@$oK3L;5QjNz8U$} z*y8L^{>FNtsHl{@KwyG$BPDy9dnG{A~DI zUUF9LOG}1YWd|=Q%dH$_l^wXG?Cr_{RvCj}=gqXI!7sM&aqxdwRuwV_6w%GJtnQZ4SS)khH9#Wv+N(^&_7$Of}U9j6qN1^PT8rH z6tJ(bfAzA64p8AxbfABPP%E6pIHH3RD0bU_I1NsWAZi_mPaYDhv^A(<4}yhva=v;^ z+yY~p?TK54VL&DJb9*74Xi21%`&|6vi6HQLlcH#K8jpRE`bu^Ow;e_Qse}L#4Y;4i zec-hs`OS`7JcWpX7i&f6cAQpQ0q|Nl4^gVoXJhcr*d4R-@G-U{pGk4c(-T@{D1t96 zql=VaRM}gZGaMIx^y+&I-@9Yg6nVh><6DQ|A-;pBa5%||RdeycZOtPy3b)h|C#t74 z0*LQKODwvwLw4}Voe&B`HhkC3iCf$Y#HtrbTWWmhKE9jX&)&+u%uz##TMN9*m0hut zxZFWr+PEK|c?5UpE)#qyrtI{g1#5Pwx??N2%0L+(Td@HT@fB3!YEWLe9iU|gVwy%M zMg^>`96+|B9&4?eT_DVgtDEu7g~06Klhr)zjaxhhiB-3_1uUtb6}a`o!(U1ER(1qX zsdIB`4y@F4zUnr7aYvyc?6iVc(UNuR3@3u>cJRD6 zzLh7mJkeBOg~xO;Wt8gy6LCF&cDiysU}6#6v{@62V{p?paae4^Fl*xQ*o5JU+lrwP zO59eYjZeg^jJ|>GNB*5B-JYM}^h>aLTi}1e0`fkG0Dj5fC2PzLVCiz68dnYlH^VtH zX099_*`wzv2DjJV`Z~CKlHsuKhptabAhOJoQ&GtzUBN$a9fBNkuYGgI3Kai7_Yvbf zc-YKTn~KQoZL6_=19g$*F%Y23jvv5c3B_Y=9g>6VcHz4c$hg(1d9C8o@Ydqc=?$vZN7|d~1Dmp9 z`!1Z@S_4>7dBVyn55})-o`EWJkO}&6WO2J(a4|eSF{7a{Ri5VGC(ZO!T;cD&4;Ftn z4D~>b;T{hDx&RLce|+}vS720{34b<9`0!_b0RH%zg1^U!zryeP@W+h3!XGn!`1tGh z=m$Fg9y|Sr@%J|1;oy(Y9{y$-m1e?UH%j>MXMO=pi)@x#a8 zpFddqonLsw_{;e>4}X02@V9TUS7|2v1yI6=Kl20d$JZ46F{n=@f0GY?%-AdZG2@4f zKkSWE@SjZasCgmg4g1@F!3M3D@s|JN2QEKe+O-MrNV}zliClYQh(b0+BfyypqjHxs z-Kvj$5l*~$tlh`HXlFxWdOVbmT`V!BBOlDqn<=U1_k+*B`n>7`37FNR25S^!*(P4W z`Me6@dHavx*d3<{xt)Et^BH>eJVy}Qr`pJ|e^rO!9YBSBrQ}Hx2e-v3X?1t@eNNu6 zy*h}y*r)^hAN3R};2pRy8b$06m|jO{)-A{KsLl=jF$}Q*rFtEdmT^F!BTx})sovIS z)5@uTncT6Wum}hdE*i%$q-wJ_ zaz3XSd4IbVcT{BLumcCo)W}<%k}`66JKT}Oxqu3KqDKyGjv6dS?uLTy#mKWT@_1-J zFl7(8z9I1ppc{ylJu6pg;L)H9KtjJSVyqQp`Rf;v1+lxB1vaHkpeuS#P(iey+Q2?c z#mm*106>8)C>j~d_jqU> zzYR#d409Qb6wfCn2DLJMv`UvSGQq^l)%7JnVmC5?{8TJqf-~sAcE2jB0KE<`aOR+1 z>hXd`)yoRJXnON^8;Xg_wFrGx-I(7H+8;>VmJ_R7p*2|y#T|Qa5w<6>pEIT}!*cI{ zAa7N+tFYYb^voQWI~_rqFeo))aSuhJVePe-okwWIqU#y_>~DZ7!tfxPIK1J9?I(En z6>7oFrLl#Pd0X!dSd*X?EQpoWtBW)zHH03{Y6$JhiiL10Mik;Zf{q*?Spg7rJO>P5 z>OFwS)n@AO$VQ~9n-Xy2UOm1cQ5ve3IAgo)SGxGN4>89c?zmf(FZi9meE%6DFe zs`n>V-9OUCq)A8`?JpJm1it0?zg6^)X&m`Pv@58H2aEZZyaJ&qs;n2Jy^aCX5h|*P+y8;#YRh171DvqzJ`~gCdF9HYg z<2f=Uc9%h{WM(?P`xn4y!|~e1K(HAq+!{qn*MaP7Z$v7ov>@>cf*NUxgzpWZ$T(9a zQBhl*b$Q)`y{FU_53S-1xoQX1m7yBd7_z|)hs+EexV?()3^v;-bSS?{QZz}|sG^F# zSK&oN!zx=}o)r&m3fspwNlP0d?X$lna}e%4q$PXp8qUF|*wSfcOK{+!=Gaq`qFdU4 z7Zg=3ZSq?3Ls;R8cd!7r4r6tMwTQCsXoDuw?E$rzKv#0PKqI$YTQgr7w<3;zt zgL*5W{zrt_!jPL>sGs47`gXQ(rr84crfOlkr05oC^Ms-b7Q6|ln>vg&^#7L z0kdXhZLIn%v+A>*s@o(**Vg6L=7*dGYp}AG;L~+gcMJ$T!^JTe+KH=N@iHu4;FcztwD9xec@f@Q%Ld)S`=OWa?9k%tqm?6w>$h;V0+4bO{DL$IGNUgZ|u^3r<)|^{Rh}ha`^H%)}w^{fG(QViUgbV(4K@1Ir-} z03sgR4A(-q@d)&7cc}wj49z*&L=>KDHgTTQ1PKB@4pkE*6%-C(B%u#c4n14=gVoT>I29f!AoaUoWYn**ZRSj@nqPTkDjMc6AL2H$5u`jO$J(Sf4 zpMI&Pjus*ype8Id8sCW);24hPYYXV-7`Sc-HA7i7M5EpK(ZLiezT$lArYF!gyQ4ig5P!E!pYAlRK1);R{vO6Icpcr0t`+z{jFi6oh7G<4M)^5Lzl?B2RZ$OWfPDgXt zo?>1OwiqJpN7ijQxD)^hLPzA2sDGzeK^1W_SbIA9tOJ9+KH?pcbre&tsPnm8t|N})DQ_OB?xOD{(V_k$sRjM9;_7Jb~I5OR@^ zIYdGJ;*k7eLTdvtT-Ju`71#ZNSQ2)jpwn1O83!$+=^tQ0BqIUmL=6|%A1Q$5Uh-Pq zUX|7aoJ%zm&>$>DR^vfd%^ja+DCFHM%g{nT0cts77F^uqD zVh-w)=AcTw0iwqM0p*f(gJiU; zx6}x>J;P6fiX*OrRLGT%fE}I8r!FxEk5t8)2uv6T@#>roa%{nq^jzP9u!wE_F|C7a@zY zZ{{(+To-RH544(lMQ2-fh=DB2cgWoB{QkGQ1@5fI2kbZJrEy zR6~7(x!^hTURHp^cbOmRA`pHyx%zQV z^;}|*s;Xa)7Zg`7tGu=Z>ivEz4OK<*p7g|_b_LQJqIP_8BO#{|inT~p^;UWH`oR}> zWNgd|m31Go>gmP+-@)4N^IYkt6wSfOQy6)nFmj3S7_5B^lfuu+Z$M!jk@w}DV0B$= z&{&dhD>(gYOU~qFuEd}*{L{CeW$hv20az1XJ13`GbRGmDTjvhUG!^Vho6S;I#H&3^v* zYu}bqanQ-8OgY6w)Z{dX>i83Af(z?aj4nJ>)P66!>}xdUn!~>M>?yy5>k7x7VE+c5 zWJUWmF~Oor`?bO;D%vl3bG2VRYWpTRIxn307l5KBs$S!1g1FyPw3g@5TC%pUy6oAk zj{Kk+)|(ub?3JB$VmNvWYWLQOGI;sX8)aD|rkVhp<^Yh~eX0XMt`B9-3)csS><^eI zqzSV(rL}Hgy7v{m*b*5obMDuX!li0;AS(--J(%wFfQtiYMvZ@q(P$V|xO^YO9Pygk zib0aLPT?LbDX_d%Sr4U8k%d6>*n&Z9eK7~xlE!G(IDT?u}dpUwNKO*fQ z0=lk;u0U>!Dhc76Oe))Nm#eC8!80Vp%UT8Y{)I@xUKXMm$(#lNtjC;-mvJFNsv12P zA`SA%7&-W7|HzbI;{d;Jr1`IRK`}I*^VH~S?Hn>~H&pxlddyg`hWgU^PX$+9P0ox- z>~M#s5q0oxg3%z%;%a*M;0zX3k)O9ZGZ?!Pve%kQWKF~Bu2-zCO|!bP7T5<}a#?;9 zJLmne%kpviNexRl-OFh?-B96l`u?%-yL-S3%=IPuZStVd{;}wGX{a^0Y7z%*@T8j9 ze1!21u6_uSznt&jYP>5(mRS1RVEh&&m9_@sUuG7?6bRO_h7W+UTMXyi}^=*=%2hjVxv$4-Z`I)97 zAXs}BDNQQ_+IIjf=;b6vjD?x)tom^tf{&7 zllF_a|Gq!?^lQ$ZeSB-j9xjYc_H$orNca)}4WqQkKfgv+C}PqHKc@?Yc4h-VLZ5FZ zt;fOIZ=-MxHWQ*4bGf{0$>OvTr1lReIH7zCvctk8-a9r=x$<1I*{hspxfINGnl+XJS#F>){rUHV%V*g%|(&6IAQZ05X6RA#+4- z#G;&L9h!z2#I?p-idxiC)KWUXCb;Sg|B2-J?a)+ZC&CL9Gqq+ECVmCrP1F2e!wZ#7uO@2vwgw>Hf#S53IRE2<~anK{GweAZJ2k^e7#=uLTeL?$l?0nAl!Z( zq4cWj3#drg4mJT#J8Pwm_0+0MM8GC{SyIJcvcGk$wD=V#p+>bBu?PBEydhnS(@{tT zudBTSE&AC{2HhF8X8$6G_G!&z)}+y#m75BnFFQojg&~(abH~^ob%^A2B+~X5>>HsC z5NZ25L)yL_)Fy(uNZaz(J864ilC*uD>Mi>Hg^u{!AVyEu1|3WH2AMye?0lo2nTh=T z6%!OUIiMg%{)z(%(kqIp$z(81o-u(2J_Bu(2*-}P?W?*Oy$T4=Tx2%$HK!T!%tcPk zY#4{cx%P8{68*lNswMWkrb>Ut+ZwNfrWkJYb zeW)dxco}>^s*~{>HAbIuxer2p#A{gs7g9L23$VX<3XORa_*Qc|#cSuWw^7dIim?6X zLe8q4IZJSXk3H)pIFIc4b`$4!H~?mMZgBuq{V!jNmsBAH%uIY5cdk*s2mqZ)d=$Of+b2Ig{wd*E*6f(bm__J`B>U92pogJF$f%k zz%d9MgTVh~2&nr{H$LXtYs>BKIcXvY!Jm6$s2h7qxH!qRcKgh=DWD?}GBfOC7W2(f z0Q7S-@&naL$L>UlGREv&Xh`)Hb5t33hrkP)rJ=5h3n9$sxq3?&uW+C8@#7&9%b`Bh z7)rrzd$OTXZS*ng6iAzh8IS{WY(rw)l`1eEC7)aho}c)k0nZ_6jo%snp)o`+!cYa_ zj-el(F!w>C15c`@`*HsyfR!JBb;N7RDD7S-1)P*7`zGi%pl?Y!4uNsR>aS3Fz+*Zd z4)Tma%;0&lgX_Rl7wQLq`bh^|xGUawGhq#*Kb-IC zBQf|7XeE?#zl$R<-2tta6omo|)CnP4CdtrGFgt)muLDk-CA@T?QKazNlP>Xo5|E|~ zcFg|DH9`Piv&vd=Cb8=0=JwGKAh9#gOX?r>^FkYhITAf==>AQ%_R5h}$)or3$Z8gP zn?_Z519sIJCZ9i+vG|lfN|W!uAtP7(;GZTx$m~x|Uxu;zJIp{IN%`h}_3i{FKa440 zLe+wqKH9-Plq>d6=L+%>1J!=~FHj!uT5=p7AH^fQjNv3zt7D_PQCh_lfQkqlxf>|w z90Q+N@i=H4h5+;JOXjx+S3OLMzmy~_=Of8S5TFn}5pV=y@C!|8TK}PW1sp6oHacJw zip(<2b2{|lCHYUqg@E_DYzXWkWtR7&r$(o0Ok`Cxr#Lu`qTqdaaXC#3$Es3fiW>*e zT{Gh`TDhd0eP4|p`O?69n$k`CW-`58vqvt|X_ge-BWg~ZPAtGI@;ZU(JObxxnWw$) z{QFPDb2Mur>A+cS+YZe*zDLI4o`1vg*}ff~_o>&ujVZhB8(DG4j(%B8n8qoC@j9P+ zOLN+Kj@V#yN{8rjIv&NjoUYCr^|ac=k`v|V!8de0hG6Xi@{swquoy3g&?1h%?NX5E z>Kkby;hsm(S(l?yLJ56!3N5;NBU1`Ur#JfF%Zbu6N5!9>`q3ffl{aEhc&c#ZzewKx zhd?6^pHf~8%JLi;PT@g$q}nAk%T>2`+S+KCEbKXGDaHT`MvO z7rG0wwwuBQz1X<(yjQ}7nxe|+z{la;XHV z8$=3@za6WbNaB2TX?Yey?}~)gBd$K`JL)LU0@rM^2hhG7!raRybKdU?MphbG=>7S7 zQR6S~_4xHx&KN%@b;j}Y00+Lg3Y61o`O)mU;tG)ubV5~S9z2#ewE z=D{m1xnyaWV9S+GB=aV0sUnmD+&C+fkcsUW8=|K{2vt|y zpeWkI;)k;}GOu({I8rK6^zjdGyi2==V4Iohu?F#6R@1+m9=ZMbbHrX~%_I1RfMYq& z(C~-e$QcMO9&g3jj^d;B@bbmoAU0~6%gP71O_EHQW$-i@X}juPCGb%4gozsdN4`$p z%O%{c5G-5yH1F1x5gxcsWi)7u7jE)*OkoCq>m01QUY=zy_&$K1&%@<>YY}WRJ-~{y zrQ|5{8G@o787q=f@um9#UXSDy{4aUjNkj zxbsD-SF)=cPe2FVX)58_{ea`f)*E*(!IhFNzLf6Aym}PqJD_K!^7rZSrJ}ZhM`4G4)R{Bn{}kc|e5YG6GQQd6 z&NQ@7g9VNJ|sJhC2Hb9^b?3wrppmaf2iwcSU5vX0-Xe_C*hRj4 z?bYrqIP}njcF{hf`XB%q48R~;bgT8yv8?-p9CNu+9|_Pdors$GU-*RB*&#eL%! z0q@l$t>BYQvDNhbfYDbzPG^%{fEC^|kw`Bmxj`TpPgP|;{rgz&25VQLvxwvc1M=0P zUYegpy~F~m`oD-7gkk{VU?Xj>Bc{rJG)UDMood3l(L5+ znK2f>{UAs}J|(sZDXbwWlu8KK=vnr4e-x6q&`h+4w!TPL!Si3p3)r8P4AFtU3~yTE zOPCo9Kpmw=ML$=0^pmo;$Qf zS9j&XAM_h@tkvs~iF}*aa{frrsy$FKT|l?ug><&%bnBZiji~t_T`SHshlJ4igFo>?Ezaf zgqwfA){||n_6t=GaPbTHT3OtqP@oa_Ao>U;So0)k5s=5WgcMIfK+Mf`(=+sKB3>mD z<&kr2D;ts1oo`Kc=rl|eqhEh=yTv8bzPT?1jcsjcD_(XWv5oGIl_O!kDo^WW2VxV4 zDL3mZ0w>P)M@OMj&u2ui_DZ2b*K@?t*_{sPh@BP#3WeTbW}(Riozw7RofO?}vFyaaI%vqy8qtQLEZLHpSn&&b-t z_9-`0FbLU^I_k%<-$HNXjBNPKd#EqZ!x1XSCE^? zGjuX+l_mULa8z{|fh$$8#L6_PyQ3?5`Vpt!6#m{Z@t0n|0Ox}Mc{A9X-o5R$zquMB z(wa5^TBESBe=!1wDvyNmH8v6yY!4C&bGb4o|AhN411X2{D9$!6=M3e44a@(|pV;zt z{A)jV0NiJ<{U5-TH9tT0a4SAu-?*GRpR52v&R-;aWG&@l+(I6PtY@^K#2V(qk}3%x zkZs>Zc_$n~Y*A6;a_*Nfw-b%a={KKGsBMB*n^m=rRjlE^)pfby>YW&H&Q%~DGA>nb z)kev}fBjifH5wm?P-9?H;cw!Tu6#T_opc35ls zgo{0iCs3Z)Lk5wN?>k*m{aOBj^k+NHnBEEHW>p+F+n%zkAH9HEDH_ScoHMGwtzLg2 zouyMTz5#=xwRHd#sBKo&b35?_-#jnl-}2G+GcWXm(1Y$^j_9d?I}tS-kSdp`x*}~) zabA$)F`z^H&mPq?gI@^x&RMd+t);d^*Isc4YQEO1*+$KnLV?;u#TB~Nyd7q(!|{f? zz^8PreaaF039&zBW769HxZ8(J#qM(hBkBwcJ0B&Q*V_wY1JGRHD(9<%;-mTt_(R{c z3FJt{kOrQsA4*-4RQ}C}lOOBT%|CJH$I`A17*u){>WG(OW!<7jCC5UC-2OZZIl1ri z(D79t2nLt$24E7!wd-&HdLY8C*xTzs0LtOKEC{&8`whL=N%USKByvDh_;NwWJu8!h z!p~8+&&F`;4wJK+KMIS9QN{CkJg~id5Z0xqxHdi0AE}JOg1*XJg-1!`K3GP__D`*c z%S1S~hwT-rqgPMYM`te7F#3E%5^tlt>F|v)4WEP7=cCIMDIA;y3Q@IwaG5 zEG0rRbc_;Sk@njAo(D%ifZ=GTV&G6R1sMP@e@C0)_9k57fVy=qN(( zBJ(im;$<7Pq#;hg(D3nzwN=uH_)3aYArlmmEyR$$>@GIGipxK&F}VEGLoIh!Wg8WRkzgt9#QEDmdizj%}VwYQP#)z@UND+dso?A9rq?Rj?RE|mKJ z?7a_Q)>XYfzOgYLWV&e^OhuiFg=sYfOap5QV<-$B7(T<4Kleu6r(G@5P02u^f$Z_) z1E^S(mRNKz_2u5ENH9r<47Oqc8CPdeuG^|ZteQ$Vi~9UtulG5hf6w!IwxN*TUs^mn zpU>y~dB5N1ectDN-sgSZXE;h}J}rFO<5O!feLE0UuWr7Grz9@j5XlkO{P-xoo(5)& z08l?OS~*Xa;8krg_z!)?JqCo|K-Vn6FQ~T<{~nFfY8A?pg~+v`kZkv-WYwc#Y!@Nh z0hS=!1+cvM60w$@9(ei1Z98qm`!)P1pJ+c5hgKNP_Nre#3t|)?aBZMik+^{I6+(_) zgKmJ6-nHxv&1-HdyrFg=YF>+)8GH5nU&~Toxtb^ZBDg9TDR4Zm@?JEbkH8#z&~tS?VQNT&4FIsKoT%Hr+ub>RIRGe($5wAJ0_Z za6YyNdvABlbRGaZOASRRVqn#VfBW%|dEKsSm#%X|ywY{B#OcR2A6lmCO22Ko?$0k} z?7F$IIA-j+=w1@#T?NZOg>f3+gdcSULReD)tKi&nHk7oRz#5OhiUL@dMODW`LLKa{ zkP(MNtd)Xx>Y8^mg9I*&s%<(??8$lf(tRJ+b$-s&NMs5?=Se|R8ncERA4S@c|d z+E89s+|cn%GRXjlVG^yB5^Y(kL`yE8kNlWG)!Ed|#ze4pTYCyNB(Smtkfl7&$s8U5 z?Ro?YP`}bMf{ELwCSq{=iXl*}8{Etc8C|ULmm&-xAmlWu$c!{`q9VPJ{l%ZqxW8L{ z?9UmyZ9{M6zl8FKRzY2f=Rd)r*6a){>68nM3`8hd#HrC!;ZS3n`#j8!E^VGW02GyX}S@DYf;9daK-O*L}Eb{7o4rm$M85pp#l2_ioV-fkg^)}U0T-m zs%e<74lO|i@kv6C4kLLs$kR4teNTWuBMpHHQzZ_Sd{5}#0%ii<9r(8mP*D6(HH9xGRXw=nF(IOIzDSkrZUL{V3`TaAB|*6 zCgefb+0R18fkG)-8%8r^vKh`|^QDFl%W#FdItwwh>c?Ot{0k;ItGilnb&S+|+)aQC z-frrY#bBpAhAxbbu%?!%A+XdQ{?OGWpGDcLQT8H~wYSJppc|reFNLcR^$QWI;tTU2J}QPIsRjw&BNV@*i?I0*5q66%9?fSU0E04-^V|7SJry` z`#t^@e)_JgIr#Ul`1c9?tHr;&7TlHfo7?ZoI#PF6R^1(UorImO6S@q4r?Ph_@D2q) z0c{Vwb+cY>^oh~aUdN}6M}@|P@?tdsKDKj{1ivLO^0b{Al+snsgF2b zoZV4bdWy1u&4>~jeX2NFoB26aM0q(7=&_$dfDh6Ns!%90SM#5m=}7@g;Xis?|O#$&z_ zO5kLIfeMt!b@YG~khme_te#I7kP4P12%-PO-H*{Tp}sBzLK?|@-L=67A=9A{PH-T^ z*(nb~_v};(gs@1oM{!qUTo!%q`7uydY%3mhl&@{3y|&#Rt8iMz*@?AKY0;~?$6$EV zT3t%x{vNxy((5r<29ySf^fT-*!lTF6p){uWKzDf^p!5D8AK8YFUgL5((*Rv*b|a(l zSW0}N13Ii_8gvCk0zKVyQa)bvgAALXALNoJeIo?v z5RfY!ka5a005VK~n%cd9d?W0Unw&1khMcu^>fUde^(t1B9U$jvfDNnGVn7cS^-8b{ z*Oytj-&>P)7{?pAYvnKyP;v()7y5V*1DwZ4qkWh$osJn*c8>c(9Eq7hE>g0DFX#ta z|AlB-Kx;76CpvYyqux*H(}R@W)QE#MMg%hL!Gn|3E`Lk{u>lf{K8Dl+l5;;wijLOs zOefmNvxXL|X~NAWTq4dWH6zRq32fE=KEK&V8K%P_xlTh;6okYzO$Ga0Lo$GnY%h3X zdqzl#gOJqC`jSf%ro$n*UPA(lk)I~8NQH5qh9sv?NQMO=X+F;z2TX@UGFd|cyN(|c z*tar6lG`UFX9gkR#Z(TTFdYub6b;E)K}cNdQ&{f|>=Tl+gODun@d?ubNSsLW4Z65Qr$#iI&)0{R-{cWBX-ewBE9X@=|54Jr4JEBg{GmW-8 zJ$yTWZ)Y?fb=rnmM&rvvEay9IQ;d4}2DUZj(EM@k48Nleze9l&PXWEY_|5ly>x=w! zkBuiIxYo3#LSc|#0Z22_y!VGP2^F5@E)!+9Y&kOX2==kYv@CL&SZD6A=tc_bB7c-O)Wjwu&g_%oWOE|2J zOK}OK+Xmz*Rc0TvgkV0QW}R2UmlcKSJ`z%*F*8)ufl*35v1=&9*#%-a4?rV>Trcr>L!NE^E!%v9p6a6IB| z8B2&hnBE4jB=rm_80TFsb%&cag8C<%h~gCHI@B(%j`ry#Z_MNN#Lr3Z)aX$Fwu5!t z6?NWdf3ps}>7RcZ4t6-6f-sRS#davnP7&)~u2$#l&|XwctgTfY!jUg)QodUG@J<}b z(ixm)-M`k-cI5WlE`#--FZI`*AE@^MQ*TQf>!sxY4V%Aiy-p%n-%oKM18e(Web<=! z+Us_qz9XhS{nx3+{d?cit^mAR-`VqoPv03GYEOM}$x|!|r^?r%kI+B8K&}tP;RUho zakup)E&y`i90VT><9~q-eTWVgRL|98yNyeZagZN+@giHW5-J&muvS1^WUGOcZs>Ve z-8l_CgWy-uGZ=mqJq7Tq=ot>bik^W5%jxNbt)~m~c!Yo9J@Hv*PKu?Z$;L_2;T1IC+4DN_TvOb}5Sj3|tk5W^)dYPzA`z{j5Dst}=hFLgd12 zA8bR1D4|`<7-3Q9HITlcC%b-vZ=bVO;6rbHfFx;hNm835?gOx$dUVh(c}JU4%uQ6wd%uS4u$LP;gy%aIK(R z3%hn?dN+EDvt$FS@rgpS&z76DD&e53^3R zdg65mDTgToEr|vt%Vh_>Q`EOUmWrO$fm(>6#LO9@J4l?NEX1s&RXz-=EGiDqO#2rhJY z2}ydZb<@8B^Rzw9f6nDFpSaZ?3FvwEc2#AXo)wO{RCx`)r$TGuR~`rBN+Qdlw>Fau7ZE}COj}= z3~pcZNANl%n*%bF^e*3?VJkdjEuciiUTnmP_q__B1`q4YIvHY%C4Uj zz~gj{$0#c=S=Hu})ks7LCXb$aFt>U13{X;}NEiD68PE?hY}0kOlW;!Kok;tc;6XAu z^s@X%I1^(IzF;Hay*#cvQ=TPL zvI=qacW7OSdx;c!>PmCsXyqC_2agj;7Hj2te6ZxqQQ-5Ou=-Pb5bXt3yg%ZOB&ek4 zaw)QsP-+#?hvm4$PCH}WY4v?Iy*{djzWTZvd#_K)zoL*AGoU&xtz06Wh>3usE}Sf z^ppGYeAUt4fv1DE;4R!|J!qVhUYhzHXMIPdji@WuXI) z(V9_8Y@oplp!fOUVH)r_J{K-L+`Ex@jF`t=c&IlURoR6{9r|~$-lps{a6D%C2c*#d z@%>NZm>HPl{zfuM#9<9-UGqnypFc`M*LOJPGKQV^b@IFYyxWIy4g<3{%(R~G*@sS_ zdwCc7@-mIQ#wQc>%l1_ok`X#JE9FKKiLE|`K?shwP929i$~vbGzxHL=2iMNmIfy{m zqraiM_(4`dxp>_zhgh+^T7)84UdS%EJTP2$jXJi1RKf{mb}F1!mLMDI#RGa=KXBX1 zba#9i@TgIjp-@!4GGmt=zh7RI%8Os&1;YfZQ*MLDd-L$e2`s~qml-_r08lGx!wO8m ziLaH?lLQ8wTI!TNbZ9^ zC$0Vg4B1B$njfF@^J7T7n1-uG>J}`we4@q-Rfp|@Lwf`0>aZ!(9-GqJT#Fj|xd@y1 zMGY5%E+vDu!GNfd)3x+UmC*I^t5-w&yyxHQ${N)Cx>EiW;-~(za+dSV@$iBDcS*kI zGdu0W^CWp;1ClpDo9_B7wCZ@<*so>9*KE^6_g|KizaET|=ZgX|McRGe5wxaT7$$Ya zaQ^7``mD|xA`!b5qZ+aAM2HD~V@l&ndvy6kK5Q9aA61q|krHRuRZ(%d| zr&`7Cq7U*WNnbDNt&;vQ(ipYS#Q(lP3#(3`&T2Nt<3^e6zN^gkCsMb$I_g$&>#75{D~oHm*whd<9E z!v&9`z_gK(IZXQ(-|4pRu<%!m{L<+0OG8)qd<2eZ{~H}fc|b|1UY{%8lq@H2?%DrNad>6NRS{5Sa3U>i>XC(ZjUrRDMRBA;8GvF+NIP$@oIMBeA2rO`RR^u|+<5%D2ePW+@1~wZ=BUa6G z3PVMGex+`4Y|o;V)hfbIi{ZgvDczP>jP?lh*q(y>CqrwhR=>T6=%Gv17FZ*UG$bom zs~e<^d(j4`X$S&j`oXu@?I1KJ>?x2G%bU<~1rPILRYUq^2kLG$nUl!upNYkM2!+7y z4a~Rf4FvRy#(kpXpuhxCqJ$+-LbJqQuO}$MD_0KZFdX0>b;BVS`r*=VUqmHQ)hb1b zkRkVRH^WHDaEE00PdCFC>vr1DQ05rVKkB*HUb}Ye3%4U)E~`)GKCl}1U)N8O zyV+m3?bT8Ca=ZTP)#{UgrdoYWV8VG?DuRZK`WEKaxCahDnNd8x^Pvw4X!-vKzx)r6 zXM@l{jbNRadg61CC9_3i*sWS%3kaX5*GlFy7m=Z_haa^yxe#m$72~5dVzUS1xhjTr zwJaw@%Ru)#ipC2eO2&Gr_F2FXreyqzTW^y&H=&`Iaoq&x246#bl2*WB18iNtI~9oJ z*@XHzd(R8DfXPLxG54Sak!5H@SCyQMyEq(K7!+eosH|EQXQ*m4s;XAE-bGZv^}Q&* zfhFw;3$4`$XM}&&{1X3xt6yf)7Z^(Fp>^Pwdp}DSsH{NG7_OPAcH(ffqb?x6R8zM* zL3EO+syAJ;2a{4veF3$Kx}fIX}jrEyZ)zJv5D!)JTT{qDCZ^6l61tw_Eta=+ay-&*8b4IK`L;m5JucrCxZfU?Z!__& zp?OMFeO^A-xt}-6=P^?B6Y_1L`)!+iJ5#=0k8kldd9kpbXkUdF9Bx-Kboy?ISU4j2 z2$)N6VMmLiF?HE3=o1-|PM-Szb>j=h)EHD0Qy;*uNY9ilV{d2UZD?}|m#lBkw_4sm z<(K#2=ld38>DFNln$FW@+t`t?`Ncg|kbh_qSMv`X~Yck<2{fybghX zoXl&GHktQJ=4#2jOlQVI2Y7|@um#E<>c{)p*5rv`nBz5KvGa&wW4aK~|Q%55W3BZS;Z4 zbZxc)5vHn-r9m4&jsV@vqiE$ z1r;Q)KLxp^_XfC?(eLH#TRjU{a$khEMPV(aa^ioc=HP#(w%|Q$e*DljpM1JBR6a3m zdc{8UO_uudt$85i{#aDKcQp;bumBnkMGn{vK)k><=7{^f$ks?Ysi_Td4SA4pd14@hu?zg<>^!w|v=$G{1IOkZu1g`zR_ms|Kd z4r%KgGAYd>`QYLYTc?tZ?aQ?4NVRcajr}unl%I$9;Q<4K%n;z=n0j0)egwaw!bvPqf76{Y^~k@IybtqtS4Df4vgG+E z_?4}2G=EDv=Dy~kc&9a=!ZDj4@lIPa?Uxaa740eAatfLT`^b0~b^uy~)R9_(`A7LJ zGr(ow0s|cFSP?&P#_uzwxkseRhw&?eprzs+0xo$ z__g|l6m-wyL8`+bbu><-y73FZ!KeGP)UV~$MQqvFNf)G(vn@EWxo)v-UKgbhpm$!~ zpTazI1c+Jq)loy|kTVg!DnC(A^ZaQDS2>1z?y%2tW4^w_uE)}rG4E)7le?vrUB91O z2K%sU5LM5^K5lh0CaRu&z446dj2MG}3kc8<58WLpfpXtE4e70(QQzL}TT8k1>doKQ zQZDcP&s@@b&&j2<*7eddOm?#TU;3$HH;< zh8qN5G&k#NiV#<4=oXy;Hd%PFoo3;p%y{VzSaqX}D8rO2MJJH`{dqRHd6){%)8Xb} zDm+hVv)dL@;dye8t~Bs46`rTjt%s@bJk4$%ro!{|r>(-B4$Mr2*HiB1VJbY&LN^an z;dvs99yGW!6`p6GTMtv=dGdETFf$dNXNsGLsqj4g!K*(oFL2vpD!i?YZXTw>^C&kD zQ{j0=v^cmk6`rR*{XWmFhpF&-*1CC^3eVHn>cGQPc%D`_4^!cJ@_*#i!&G>lnQk7Y z!t<^K`j+m$%^}!&G>lCN~dL;d%N4Pk-{Xx@|EP-d5pr4tl zc|UXNVJbY&MmG;r;dy%8JWPe>iSBpWVk$h(1~(5=;d%N)!~W!n{Eq_lg>D|E!t=Dcd6){%Q}lDEEvCZr%yaWF6`rR* zG~D3U!&G=ZWd|I1meRH1+Mh5Pt`{cPQ{rKml#<$@!sge+aibrd=`{u=p&d z#m8|b(0g?-RR+yH>WkId@R_^(XnjF^1UBr{LcHR}W_Q|dW6bO}O09Z_NgIWIuBUpl zBxVh!1vu9VURC#oMGWwtedwtf?wLYOkLu&1M~DS1ogPWFLA!J=_D{yA5x}uZiy^I7 z0@OGJ@ZTJ#&-uL(cD0sn4%iDd{(pJe#}8A&_6tYB!5sd_9pZw_O&Qn$xlM=4ved)V zbw}gE(!gFqiEl4~Y3ysXYyQy(*l5uPc|K_Nv)k!=h|7HR5ixj_$Ps~R+U80KZv)H;!^XxVMGC&EstDwi<8NK(Vy_%jwoJoFi^` zHxsmG&f&-zF9#=r2#%`&%ym7#qberE_bVy|vR8k;|_X18Dih@AJ*RPNes!`Ahuaj;Cb zt^pM`&H{Wm%h!!e*FtqM8`ijGM7HY;fw>hu7qS0hYB_4QW_N%LOBTPHRnH*PIBp#+ zIh>33O`CsRp!d;w8g^%+*&&J9ohdEn`%c(0?b|3s{0eN9m!TQ7VYbSL>!)26uVjNN zXz3MN)pLRA(H+@!aH84P@aw;8R#>w5m8@97vd7V7>cuLlM4wk~!$VB%lHUlCfDqz7 zX)JwntjQ5WdaKFZnrmXuI_?v2x=7n^giuOUw3)5Bo2025MB{=3uk# zo?LUknr$`Bc1|Ilzr-)PhP#>Bc73Z|j~ie2+pBp*J*KwfW3r+H+%f&rhC3Q|4?ruY zrT5fuUr#aZ;}P`K8StYPz*cmDlO^-WVU_$5-Av7Bre*KyUO~LZ-!D}xuy958%Ky16! zPy`SlY<7Q#>@rM68w%F&tdl!x1=WuY6;xyDN7s`zcF6BQfawf@S?NPyLy#8{%v(;fo;Nz^y1i%fD}?uY4UpfO88=MC1wTZoVeYhP#dt zu*fH?nD+4@&=y%`0(--?;1lo{zmB+`hbD<7PYYe!E0%OmK|F2`OH*6QzV^LR?GpT= z(wMqa9-qXo=YqqwLL5^-QM%wzlS3Hrw07_%lR#0|=;!45hxm1x4)HTc;Uk0{Ps2Q=qeJ}+ zKpXnaHC8mI^vBUkQlXo_yDD0<)Nkc^mVx0#w^XQfe1}cU5#|scrK7cl`DrsI%WJP@O42eNce7OaleqmG{W=Cyxs# z1Z{tFluGqo`C5fm8{mwFIkUb~CQnSE&DC~2;`4b$d8!v0YSdehcwff1-Z3& zBS44hxqK?zvtsHL;xe1KIC}390#`-R?aoPDBDn5AT<5qhu3gXx=;oz~WbJsHcuK#K z)#^KC-l4$%zbT;YFMoW-XMY(HW`B|UC5{E{F1so^veYj=!s+e>`8~57g2Qz%&4+_& zi0AG>?O@ue<%gb8eBpCaq*$nyg0+IyQaWUst2T!Mp#K64ieS3*6Ijf^2wn6c0dBPX z-hp2_iW0aG|7`=DLOIuNL*QTxa_t{pbHDnqX%1?W(_F6FjkoZBmES@AYL2?9>qO1w zjFe5m?lz}6pQCu5x>*{E$?sbH_KjUPT7WyRM|zlgLa@t`D*twMa4}&FXfWr*qNpdL z?wF?+6PyE5{gm5$a}d*TB2 z6E$uu1sc^VDnsq|3+^(x2Pf5>_*P6qmxIiig`5y9A2BvrTppw^6;3;x1{=YLgd<^6 zgGpO60IkYaRVSA7RhtqBMJ9($;KTY6u`s)4+Uba1?Vd6L6X|hGo0(xE3o+Yd6u5Hn zN@)yoajjiE9IYg))+0MajyzN}%TUf!{|}6eQIe=&Wf%+FWM{xbI@LgARW(7C_Mg1@ z)m1XOj3WIL{X~PQHYdVxS=9`>%RM48?rGdCSavHK!YOr~9p~kdh^Yqo-HBf=oM=Lv zoxbGW=B@TI{xvDK0eUmiaQQ{bdS9l8wE#LFbPy^zXUbygbZK#j{0@}gO4B+Q{2{Hw zfaxswA^NLNCJbl(JtN!!6G=Irqfl9;GxgYoZ-V`itktu(;;}6>jAmXz+etBb&hT&ri!HX z7=Ah2Xk42RI^5)(CWbxW0x(#Yt|M$!>;+SK%BXs345{^f{3a`!z|j@6OfR?`UF5@I zo(~7612{AZM|(IduaE`nji_73b%zn=_3CJcj~b-bd^x`~tbeuo#*JHX-A7~Ux2TjnpW7!BbpRpPtVe2_dQ$YADpZK- zVrl{sG4)~jUBXsmI)NaCc!x9&*%#S{-9uwJbxn1?hEgS|-XMpmhMO^-C3=%sqIZpA z>rL|e1Nl9MUktuPMRR!TO+*E;TH)UEI9yY>BS-8;n!+;NIEDlJ|wzZ2y5Ui=E~?cuHO_gaSmO}EZt ztbK4@J6qrH?{{o(Jy%BD+vInb{6?JCJHuOV_gXJ?TIV{UkJdZcy4f?({oWo^Go{6; z@;ga>@58U)zB#=0POtUzoz|&}_R;!gw(cF`1?6#w_xTSH_kH-KAWqxsR}7MFwL{2F zmXnA$hS)AfUzmQeV@jhh1c_b04QAiO$Kl2x#}ga63X>I$dLed!xe;nN0aORiN4(Wf zJ3*$Kv|fQP7y6{}5}%A`8lr8R&gg}pZGydZ8>fm9zSH}Zc^7Jh0;)FKGY>L--8)^T z6!tfZ?przpwW-Y--#O7aH%6jYL%pd`!nW3G~1_inK# zS3^TQ6Qnd#^yxJSr*zq`@M5pJ>s-*}B}A#x6(%dz1G%+~w>03uP8%WIcdJUcX6OJ# zW)9VpIFuWPV1ca}C_zc1Dy1*aFgl*QUMQ8t!&+p+T0=jWb(1c$318gRYsw+fcMQRA zpJnqqko=QUK-)`Np7q&FCWPBdV0#iDC(k5e3?}OL7gG`52UY&ADU^k95{o@NQQ>;xhs=Ou45zW!>nQC;adF^l!yCF+wL8&6gS#-5P^GAOvO+N^S}H) zh+oHK5VA1y9mzL_7fDMBP*q4!y3THXD}0PS@&Zk6{Mm`<6Qr zL9WL{KMI>pA#T8~>O_PkYAiFbtYS9IaZTglM(ECB#b*cm8y9|Xz4RaSM($m<(lu!yJnX32co0Nz z)Y&n0NxG`lKcT@d=r`{X`sgmBU(l=E3pHJ~VL)9$L&x7>_>q`^UdR0>_(Zh&V=~=v zeS_(S4@eD4t{;JU6@9u@R}Sl2aDOwz0tYj^vA|trEN}=ggheMv?ONbqB{FWEl~OT0 zBb#K06&7(C;IQs3Hy)i~o{^mGTvHDf1rrw|z%j;rY)r={eAU*dieQFD{}EHya?L5% z)PZ6hE-yJ;v;=c|)xM~8x;>*Xrat{{cHL$SJ$sTKdhFRDDWpm5vA`O7v#g;_lic+E z674|(lsnsZHO@Y!)c`%P9frTkTD%WIy9U|O3HGL~=syGH#}@<2R#k;{u{DTczb269 zp>nj^50)U?VS0j1c$pAmW%{j)h{Pr!@gajm50J?Bv0R$S@SMM3xD^BpH`A;|(NnOz z=dVN~#bW-Bx%>prb9(-Geur=Vh=$D{bkXgE9ew%Hf@L=$wvw>}Vmt=yg0PS$$ZB%c zhyHLlzfrdqe^zARA&Vl4QA|! z_KVF)_Xz2l=Y^1xbX5d{L|d|VRSe0-jZY9`L+JfV_1<{D9`t#?4uRQvr+DfP(*U5k zlwlYmp}Mt%YQS}!b&iaZki=LCdNK-P+{mb}UqG}WquNDALFqO!>KbjE6EVlYQ~Ogx zsJZ)zT+Nz|fq;;b)exmE&9Ql^SXzR$alNxeKwTbULT?dZw#Q>cHBJ!PVtN%v*1_UW z*_ncPn*BI+#{a?jdP3C!y8c5yk?xrG9J)t@?wmY+jmcvl8qyMJ$zqb8;R0i7o-P?v zHAuwNboreuzZLTP5&6AJen-jg`|z8rXoK+i;dr7lQV5&su^nbtcRjY-L;#_;IhQRv zP`?EG-=%E-r}Dd7eosX^R6@9Ou)s_xt?nL9(CZWOTdN?n`Ivh39Fq8W1dPE@J$UB! zA~Ils#uvrDg~*}C~L z_51UP?4_vNS%x|@W>W})+)H5Ih4bU>Z$zOOxiDt71w!$EX3>x3ba4eY<#G=Pj~)o-lh z4QkHXhUs9{fr@oqjlQ~441cLQMX;_=Fv}nCf%!gP)le+_V2<-qfa$)fE{>`1{sp?Y zEImMnsA_%+^01-{)Yvu7qXrZye=|4xnqfN7OjjrdcYQ=Kc-#7=fIo3_r(B{ZcOaQ( zF2J2<+?Uzu@o(sTnTh&tyS~V-FN8Y}Z-@8>;*=(*PBN_8lDEDCXV;52%!b)?Dg``- zW&8##{QYMp7obG|r6-EDfJF{>a-L8f z(1?9qBzKsFwVwV?!!!Q`!xIHO&h4AuJxhc_I<5M3;r6pBcM5BG4|(t|?W)6I3KdB> zPFH4~8i!=HdZVwz;cxlW|8wax{=}?f>X9{7pryEa3Vo6>DwE}i1^-b&{P-TkR zPslQ!4(Ef^ukHey>`}jknc~nFAsXW4f;1FPA`Aft<3&Dl!T{1iLalZ_ALLWJJSm-7 zQwP3s@nrxWl*uP$mOyPmd1%{{rjat#YEZinLq2{FBWD>uIa$%v6v@hVjnP7@Muu** zV6=eXh|o=g1McXi!9i2XmEXA_n2-O>CGsh(lg|8a!JBY?p0KM=c@U6K0})`=FQ3|e zePZR)vcBPI$z!AaluzZ?yixfSa=$O+dGiT|Z(X@3uLcY~@$%|@EpGodbcOmaCaSu5 z{1@`-{>w4=?cxbzu=Z>!SoTG5yBwTWA1gNFoy!A^UM}#4V60cp0dXawt0kA#>7_%o z5TCyKTYQ>L`@KamaLw4)7r%>{aL(9j;G4>FTp;%c9GT8@DrejUd|>4`X&pl)R}4fY z`lNLp?vQr|-Rcd<+ z5MVa;KTU(`-M3>EJmN;ml}4JG;?*4V5qzeaqrUuZl;Mj+#YUCnLwRmBvf^yIUAzXC z-)ihNL%_AFVSDj$5K_3z0#aw74O$uU)1;{i{@!e3GxZtBP-H?52zTBmjmjM4i*J#} zQ?3X|9o%ml`LfpIzp(hLxP6@pP>H7itzQuoFbfWc3Yg^7Ss)K4!fjEIXX-pW(5)U1 z5LfymCq{WL#CM&xcI_&Ur`_ZHY*AmjQy4k5K5)#3UwW_+>-EIq?v_EsAvtXxx=^(5 z;*C`2rWpkEgVF6o)0*bjv>2U4G_56cyDfX<-zom3-7M6j%2G*BTv_o zEfDGi2t3;_O-xfC@K@u`_8Kb>!fMIgak+M~z3xnO_Vnabj7oMkXKH&3<;&qSlN0Af z10OK5cKx*(_r>g1Z4EnZsbg=!nx@8yaW!S=P8*Z=?EVj=)SRi$n%?Vu^vf`!C}nuH|;YvLrGHf8x&8WlQ9NQ(l?A3MFt4$}L+w`vB8afE{gE zfkiRwF}Gx?BU^cZgzCKiTJ_bw(oEa+`pRp&cpnvJb?*bzjP(WUcJY3^!zFRG*-+B+ zr$gB<(d&pD^&4y@>t%$ya_B}=&dNd5XjeC;qHN5yx(c(D$XcA0RX+x+gbU9CGjvy5 zLxJ>+k=8Km*F8vktBknk@hz{KoMyT5|GVMR=-r-^7O}`O8_T)*%`He)v{0pK1aF|!TDcC$n z^e&loC*}m1sQhUbX^j(n?8&kcSvvnt@54xP0&&+rb^+88>wB9dWV*7)r5 z@M-88S)DGj;|n`hLSOB6WLY=ONR(vIWWh=>8S+NwZXEQ$dy*JT1@Q#q>eaO+>h%aV zW^lvXM;Z-C)#Lw5blhSuz_GhIvl zoT~!0-d8Ev7&V^58fjH)$;(HLi81R@!c=*9*r=ny7kQR^N4b2KTaR+s#=SazA>fNI zcp1!8)n*rWLDRQRWkt0%?gl7G-q1D!Rf;7vT7)bv$VDH-0U>7e>2q^V_B|H5|E}2W zj*pYke^(89!~M4o^lmti6nv`b)q>wPVYT#1!Hol>5Y(>}TuL{q^)pb12Uvr`z2Va^iLK-NX;W0! zpP(>In__jVPyV^tzNCBk(R)te`qy5iHSwYiXNcp%^$ayu^>mY)9v=~h+z=l|lW}HNQBynfl$9J%XfO2EI?|zS)C-rM&Z1>{9 z=#^^q*=ndRPF22a$pyJ??_ZI#Am8PyOUO}I)kp6BU|+?e`Bq*-)8BKRy{aN&T3h@* zVF5KYBC9{nd?(CwtL5!Nzq}3KzZ5FQiU0}NcUG>t;13QbKL&l*qluLHtj_N^b z$P6gq1Jxbh#TsL79BOyPAduhZ1wiAIPsp7}RyX`hF1m9PMDx2Kfv(_MY1$-+oQNGO zJe<$_rO4GE0Dx8`F|FL1l$)$9PfVL2aYB1FAE15=j(qE7ZmUJGtZvDh2XSKUniJm1 zE!q5h=!VyuZP74U-g;RVQXj!vXIXhumRVM!BHsW)e$l7iWvJhmK9$O8h8`*7`9IzR z%*Ae62K(T+|JZ3mM3$F|jGP*wjNJO)tFl@q7SXaqQJI)n$br!Raqg(oXy3|?u>(M~ zR?R8u(SJwtd(``3h)pG%rVk~+mrqBg^4!G4a(^CthrRqee*Q1Xyq-Zd)utL~pg9oM z(K35X-Tr3uKW@Rci*La^1^J^70J$XQTP*(e9l_Api)FI<%^{{R3w#Xofs7q^jj9+P zu*`LaN~a8!@#UCGFWDuQH?`@@z=5~O=Z>xDy88;qdqh(zFTZ4$^*zcuYcIx2M4g6u zCLPXGdH7o%jiKg-&!8Oqr(pb@RBoHR>f^O|yIZ}6#e-g5Q~MP=?m?rZU@p4;qzx^n zO9Oww%qlC&VX#3D1MjLV$=8z2_lFi=xHHKAe5?KqZ(aWX+d!)EGLVA&j}@y`kq>=@ z=8rFcA<^I9+KN+2TLcBHPEIp7+FNB)bM730XG}=E;oi!clv7z6!xVPJOs`NhW*@`! z+|bmO7#~sDsDneJ$5#cOS&LUmO47=nt zk(O)nDIr_zlA!Iy8<3wZ0`yZiMMhwssoi|>-j#JA*#Ov7pNhwl&l4K4yA zkM#VabF1Ist%L7@o=o`q!?IBu`a-wYnL_ye_Xl zW?`T1$Xuw+iCBKa_CL=_ym?t7{f|>JEqS9e(1Y&}{o$Mxdho4!0dF08?0zj1Js2n` z-+D1Q+2P&l5mp&qU7wsB$$7=_eHGRaWscB|WZnWnfB5KIunio|itM9>Z^h7^v z$BXMT)qewKj-I*6YcWv&J||IO7ENX-$Q`DV|)fevN%Q6TQ_ku~eoR zYMz-bo?2g0p1w3aR9n(Jic+o7^2dA!^wFF5Jj$fE@9PFycb3vnW>uDAb9?gG9d(sZ zvWuY14MhI2JL(5R!P%ppz7>V{sFydnb+|R?3}0b}X{8XFgJ9HxD9rVYqgRc>w-eY@~rIH_Pmh+WgJ;jzF(U9-MR*ZDOmQ}w|CkiiSQhd zNGPv8PGy;!SbR)tP-_>DXd8Ms=pnBzKM4|YRD428y2fJ$Ct46u>`#iB_>hP zW9>#Cyw@5FuB{n|>{0cLdsr9r^w=%XLUG@W+Ko5ZD6wnG4-d0O*)g5(`{r$o%BnTl z;0raq(5%IL8kob0{re02W*>S6`n}1HXNV+gDw{ZmA;&R2UaB9Ro_83zDnBu`bPn=K zXmaEO@%vmiqkgOhMz#6ukNFua^zc9%&eQr`o(rNms8FI0Dq!EAFR*h8Q&W8*jDmny zM%@M9z^EIvnG#hG2^tJFOON^yyjm&%`?S%?suH}1QZD{sRl{ASoX^1vIj9_#ype5+ zmTW?Cs2kf;LSaqcmOQ>yKX*6BV`|7Np+(@RF>HDG@6sX%7^;0joorv+*IzUcDK=@g|fY z>DBm`1q1C5H~_4ErhO-94ES+26^w*6K+hKNyXz_>9k!a*`O6P9^yC&SXQ*4AG{rbL z4;G-OP&4mZVCUgN1`}2rHM$YOuAo;Wa(@t(o2R(;rT+}TqqRMx1P_ktlUKZ9LEJEo z?r=^3A#OXGVAtalTjrrG1mneNSiZb(_N&;Pc;EDyXzuecm}t617s-n)FqjxZ%5@G{ z$7UaeNEj*}gEMgIiCecWrv(oY9=?*q*{fc7bfao0gFjUGbef(`4<2 zxn~wk+t5;REVdPtIN6)6{a_s}j~?^-J6xYRIlb-c9!+GP-cIYH5Gn;!fPP@*i3mT2po?L+qz&+v+uh1wyn9Ks;~Q?%;*jms`>}1P+q^7 z;}y{K_^d~dwBuGB#Y?vvd4n!NpO~?UZuGXYeK=8h$fTg@_P*I?dxlL;P<#LDwMXqX z4M*$6UZjh5@wXprrcaM6dHs-e2PlE6vRjM@wG3#{~i$o=^$D146XK^U$YhUZc z`BoNi$hg0Q{8)c1-s{Rc*-Z~$fhYzUa2!zdu0fnT=8(+;S_WO3_4O<@?Y9FRPZgfR zp;O6q_LzCt84ftV)Z#SHNJwfNQ_%-kM752^U&iqpQhyK1=AtdT_}~P3qtsQe691OO zosRp8i4f53MhJ-C3`o@8-vrvvL;E+_W16|STLtyWIaY(fF*mYxoY0ACNN~K~95C8r z*O#LCL4ZRbSdGFhdBZVcTka*c%Z`1`z><%#$VrGgGZbUg&-p3kcJI_2rsZqdX=sR}H|28lhDr_eGnwq<{158X4~6dN-^2<6j>Fd3d_g-qrc0Ifour@A%>r#CY2#%$4Vd7q@7U+0Y2mjJ^Z{jzw z;??*K-sc-%ClkMfAV=*t^(bU2;WP9#;C)l_w_$s(eG!?})K7iminZlg_7(OWki*f- zFhH(wCF*{WsD(bRINtn$#?Ypw_mv*KGwW~UPira#3i-ot%A3mF5XZdZQ!Z2X{rjU_ zYIyGK4?N^%07HIN@r%KKD_fEFL$Y#T@P(%A6Xa)baF+c9S>6y?-nRJI-_Y8J&YRVh z*~R3S(_xAk)in0>f`^;ZCRUCA1`mJeS7GBDgH8+?oV3hkw8@Gg@XYFhJ;QX7dgim@ zhml;sPV=;&G+xg*yBntT{jstensR+(1N;Za0+@d42dZZ5@5^NG`%Zi-A{x!5hbXxZ z&5pa)LZJt$NKOT>a}+qL{nalS)joCB*7Rxj=yRg^)q&utU%vUph3;?Qr(TPB_UM0c zYEH$CWCni7kEjWlMIBJedMV)KpASQalRvBX{Lo*{_^D66!W%GMfq&T^(Iv%?_D+hIQ7_5o|@gMZW zT*Q5ayFZTGw0Hu64zo*89hCjzBT#W-{uk@uQdlcKwVMEPK*x9L@^SE+OKSeR?KvO) zLhqxoULJLzcD_U(f-m7gXjzE0lbcxFiEvVgxN~MLEOvHrqynRN(Eg9Y_ogy3Yy|4n@sOge>Myjig3#rX4YwMj78<`A7I#x_=G;Ah)B#_!tG@~}IZjwa4iDVQ zG@1p|&{U$UtyYiddcS7s9fwakQ!`S84aZK19N`*2c6Rro#}V^JE2!^3;F7KbZRdh^ zHI9O+94=H)O0|Nz&s9)GLpCbv-uUV7K{zIqA1GEqQBenpin_w5qS}e4n?Y?5mZo5% zF)LSNPEk}tsBHkURwzeu)oG0(}sZ{rz*61uA;TMsY>}?SsD;yM8HD#tw9kmnpVYuCnrW1Pq~~G zc$&*ueQ!1vB062#;;JUODSS+%V`6BN}IH z1|D!Y1I#SN+PF3x^ym~VW)e?RUBY+g;y?s4`x9D`telHo{*cRRJKf7_t(8PW__iA> zeex}9^7HM&7Xsue_Tyy+NyF~ac%9(Ih3`-wUfyW#^zbV8@cM(nYgi_{+B9AzGKk9= zpzRruGaau|u0jD0kqtqL)o7&j_6v?aF()JyD5JHhO)TkIPxWT1Py2aubIm)Y-#i8M ze0|tIUx%NEqenz-zIu8;IG6Wbzzq}|dgy6z5${Yoho1joHZqvV^o{Rba6hqdE0OSq zmD`xeu?8iEH`zqp1uFiv3O76}D@l~+M;pr0vA8p0Q?b>g}e8EecVVKie z@X_s`DEPp@dB}WQHR3AJ%4VHs-IHr|$MhQA9x zlOEO`IC_w87q{$RZy#n|k<9&q#Pe*pGOPa7Yms^EPj7p5?x?0YJFMI<%=InE1JH{;kHZcTm{?zj zACm_?>K>FFz1qsdKKEIut{Uf15cjYdxM7F+bodV9OZ{)>&KcDt*4MeP1@&Tvbz23! zxI>2Uqt=Tx$;n=Wx93`;tY;Af)Ea#+sDGY`UtE)%2)rkIO_y3%EI(S0>ue*SJEB+Y z%F0&1Tj)F3fY)<(!Ilho`r-1LDh%15I4%fT+6qtRwB;|?KZx*vK3PRwNb65@oh;!B zvtf^YxG3#Qa)BLqhe*W8U9hI&7%a=jurYq-BLu&aG1z%(p|};A)7Sy^ zF}lxNOO8Mo*!!@XK2bkYI>b3SD+o?EHvpNeeWvz$UL0rQi5)hUz ztJk7z*b>kKCL{&=VEuN%&wT5TqR{3aW(8M z>p3%S(Z&-+=>ma?Tc!$@{SGK4$Ah7uM&Jq#y^V0YV=}U)=Iahcv<}m!b@O0RnhuLd zbK>J2QF}(YZW9_ow)*%7xeP%vOHJ*BGsM(<>pRpC4O8^ku@YXwjN=mB)^(<4JH}&e zK%9`P|LUQ`K83i?_;EG>U0%Z%^_`X=kzBQj2swh~=(S^?zkR6n7_m&|KEx4!nT+`7 zZ+msr0hT@!g?(I{E>?51tlByP*Ko=qPf$ed~)MSy=}APu4_q}Jo* zM*n!pF#jhX0rP^b)0i6vi6h`xMvDG#^7kBu<$>C$_sAmEnthC>0JXtoBw;RVh47IP z^;KY2n0%+pY_sY+!gfaHpJHVGFAk5iSJ4V@oonS_?G4?dSoY+od{(Oq+XiAbm&47t zhq23N?o8$MLuF*sRa|O`J67~cO}PMuG%%BZD;&Fj8Z!s`??m%2`UmzweS#t}DK~9G zAb;SJQfx4)wL2gLdY0Sud3rC;o*J<}SZ$q~qDu_eExJVFyqo6o%uOF6R<|FsvTE2R zXytO#O5OPx>i^o0-TKqnGmShx_}icD7yQ?H_4fmQD`kA4JbO`VsxC$NQbfr21sM5%Tbda; z5A%8;bTfDG9NQ4nm>Dp$a{Y<`>e``6f*@o2t{VZvw1bkj(9$+2Y@=3mCuZkk9$Gn$ zV9Zy;euPn=PxwdBEcZ>%tj(oSP)urhVp5yvnADCsqX4FsZdM?+pzMT%_%UXPLbanc zP-iacye4Ut)#JKdZ1MtK?M$lgd4dR_F%4c=v}SQ0(gFddJG{vA0WdclqSiF2)0zh925-e+ac;dFA4N5^8&B__3f$Zz4Ls1Yv^%e`<7H6#J+8E zG@s|?T>fgBX=t-rL@iYA!I*EYq7jnXSb3V{Kbh;mG(q`)^o5qUTmAAjT)%iT9*VgG zxo>}r12@GVHEB_GMSsJltiQ86@r>m^p9B7?1J$FAj=w5ALOp*~NHOtO-5NnVm}_^d z-|tKFSN#Ug5a?Sn#Hop=eQ4u1uc$saudE7$BBtAFqJfseT@tAg2vA`P_^`q%zK!q1 zE!BjMO7UUk*n*RoRG*$14pp6mIm9&#vra}I)^Jy%e+UO^eyRE&cYZ$c{;Y4DTLRq+ z%A-p%b#c1q_=(XIHGTH@=o7X%Dedru8cD<@&jJ z8+N|wh%_+*N9(~*x_L}6jl0^~TC(}ozNipdqu~dX*JbQtzID6^e(=Ly*wn?$x+W4p z*t(9Vx#q>441n)V`A6yg{F1LfLsv7N|7!AcxrnF$W4@VhXx^Nb>vo|m+S7$s7^xf- z0)I6;zxUw5Y1VM>PuKw%QYGp6-wi4y=`;D?Rpz%;7D9?4hvPU~2_K)AwdB%Hdq67a zv{yO2rLxp3l&CDJEk%I=>gZGKJ=~?uUBet0nG3OsW<(A+>#g0}EWy+6eOaOG!cJYsGp(U-ax9t`@T_9oH-~1f%dxnjc|?U`mmS{R!@HS<_DEt6c=Bud4Q}`GXE=YHnC_xJ(GP#dY7ZXB z%UD>Kim#F^S>Q|tx#w)XY9@}kTkv`jK~G1-w`KVA0jlULF!L{mp`@1s~7>4dcZ~l;*5!k*re@Iqh#+OH*aCwrvvmZlD&)hXC>j^z`zY!4w zc&M+o{kIpX>O0@>MG?^OH+%5+avp;F>vK?9=>B?{Z-3pH!_5woY*9|jMSnttmkE4v z_uFO5{p;7gy|>(T|Ge(?PuSpFOvkeK3y($mkP9{HYv0rC;K_3tK>;n$9Uf^3z;j&t z`LY*$a`)#?{C;`UN8j*%IR>BWPhE#<-qikGX6Eeo{+;HZ%U^WoleF1{SLble*s#3> zQ!$otS?Z4av;(PU+;Igl&j9%ZvByOHR5}5V)(5SrWwctBT2n_dhQvUnb~W4SOCFtH z$L}*mO57sfmm-0f6U=|S`;jU0b3gVYZ}aFGV&1r}3`Q^@SMO|`BTffGHj>U&g+`^U zD1pD;xu~CZnnf$3KU#7`eu>8|In|16H zeh2;f+Rvkf@wzg#c@4J1c+`BxmA-C6dFa=_^XQ|ar=)Qm)~prXvUGu`3vag|<7t~G z*Ev(67ILR2OI5kel*KQteux`eSVc{Mf*Rj{3KU3~!}*Z1xuN*U_%t&uH^NJynM1rn zrb1nVIDnLwh&RZm_+UqitafX+^)7oxyrE}){ggm}#0nPddKk`Cj)j{g21@ zx+fX$+}D8CebiGkA4;Mo|{raX*5P;Gz*^)T2Z182c7?V(zAoUYV{5cu>|KngVxp zxd4TrTRo$WF1POGPA+8aWV;!65!OwcIQF$g2i?V|NE3ZD2Ii9qs77W9`OYV2 znkZQILsEs5aHonx-#%_a<@qQ&(l_NW-4~&-c@`j)d)rDs2z4Pg_P5Hs=3*A-#O6J5 zs&t=7$byw028~yPnlPv^*y_?N7r+C*Zm9pwZFp0#JRcb|Q2l@Y){FyPRl~(QP}ic% zG=g>x@y&c%)tRhlkE*K>EC~wc!T5a2X>bG_3ih#MuKX{aH9`OqE+RfNoCkC4vbpT^yk!8czA=sa1_}{Q^>ZjvP`UtA( zQV~S0n@+{lqYsIL(>$l+xT7HtJ&VyZ$toXt#*ckz(Y--WG1RYU&eJl6^ZE#^0yNrM<%M% zwfx1PFVvHjV|e6wCL;$9eF>s4S#_yhtN<0S!@TRbVLZbJW9g~htjly?Fuu!$@r*-s zdG2+T1w?-Mv}Xj+Y9AO(bEuoyvX@yT*!ZXeqA&Z$oAm6*GfA5-zt#+wZCq6l5Xg4@ zNF#IZf7l&k2vnOUbAqi?0xg3EAvc+5#}wL#MU6oBxkluCJiw1Y`^*i;1J+`tq9R?2 z2V>R1g4e$-pjFe6PDF=)3bpecB;O(mXnp^S2YmW|xc^yZdx_6ja%e@fmJz*LNvu{F z+)hIrU#jL(H96K6rD9LyAFNtrlTb+gAm3r}v z!KsHjwce9xDDmM;^-JS?f(#`y{YC?a2sDzU;r%2cy=%N(BZ&|16J#Xup-SaSqk4jj zB>hKq>q|}-yY`WjiYoOcjVe(dafWseB-<;11Cj64Q3`^AiWR5iqAusmY zGjiwl8d@wkQw#tGtk}6n|+6A@g_G(73)_WD@W}@9zj-9+7 zUY|ur8O*PpSjUKP+#tSfUH8$7;&jU5?qvrGDi$kxKk+!M9t8D|_yiWWw0!%2Au{WY z_M9e{rq9nj`b<}e)}_Db zb3DC>yVuxRo^8{W3S6w(w_|s;OQgi@FxbdRNt}P;LHbW8@6N@Q%vgcZH-ddd0RqKH z`bs{qvmikh;6ZmIEnsrcdxv%VaGVn#;T~E%n!Gl9?5^93tm=|v{^wUWT$NQnx*SIq z$L_-E*P}QZ{s0`?f-=g#yXfBSW{v**;h*BF6XcfYO?s2k*ZkohgfjS>e2M;_ZrI+n znw=+h+QudmrbzcPiOPi=9Cq05b~hgKJWtcW2}Z@OBjcbSY&q@_m`;{+w4aU>?v~Lg%9u8~v}MM0N7|U4t#FVXp?h$bhxWWOQUI#6 zPRMjyMtm;8`x^C$2b=90H4nelYSxBk+g~9=WTjS!zLN^8)oiJ;(Cr9a-%!*9eMNO& zwi7iLXuT5Y?ZVB~%;+utvg48eN=PO2tpT?e`rEWhL%#)km?WBdcY z@q5m`ARew{upcae=<~S=xPz195pM6-I2X6*@hSca!_Gi=DMRH%}3t_R>MR6BKEy(wJ5FCF*OJXqW8=F?G=(D zd({9OJ3QKcR?`LT{>gRETz7Vzb6;+4oz|eAw3WtNk z)IpXWc^`R+KA4HhDoUI}5g{9z8GF=CnZb_OSW<_qo?BGX#HQ38ut@-jwF z^Q@jsBO@j|W=z{c?B-?=*2eD67$+PI6TRc(Qy?!taA*|_$24J-d=Y=5>b3+iC(_i{ScqJP9GzyBb`=ZiFhp?Z61AvG2T6t$hscu5%+= z3XNh|tJ_h8?#nIXu>lH7Pb+I^E>gqq09VT#V6@hPWexcH%qh$wcViaO|Ar9@w9+@L z2B8+?Gf8382l7H%U}~xAGWT8NssFlyN>X=>U=LEO=Hsc=Ij%#0TXzqVHgE%aL(3^_ z%^4`mt;HQy4hA*u=FA18s=nR~zM+nC{eEW<_`PTHtBL!zyK$8=qV@W;%jevI$J*YL zR$EzWZCAH~0QI`QThi;>=hnvtui$mLq-USfx%y`!Ih@yhO16K@$@A;ML<$Hzo`Vz$2u>9uqW4|o=znC`i{;iC6 z4|VQM#mk5M{h43>BK~Ta0)kkfqYhMac#nx9AfP@@()3|!t@(^BdaPy8#*4q6mDn;L zf+4ZuX8t}l55MX!U@Kp6glsuLk09|Gf+N&s@hQOr;R9~lx6zJAvT7~kRit`mW%?;eHBE8HPH$4Ys++aO1WW4$MJ*O%j1^OTDwN# z@{PWZcp(nRxH^eW*pyf?3t%AIKxFeSS<3fE@xvGAk|hXO%1o+S@vKtF^=x|!D0VmLtI5715`;C|SHUCQgccu1!a#b9d2?HFvfCtL90`p|m5cC5y zOnp%7)zpJxD;BZLV@vR>&zB`uEF^u%OYGsqmPTgqv(fjKYc|SH)N?_pV{G)zMwo4d zjiRVeeHwKL8?lC5%&p6oqtl!l4mvfz;L|{7aT|;=v1yt&^D~W^UpYL6fEArliJa=( zji5Ad37hG=5o*9dd1%nR8UgsWWSQF$JRW113y;ST0n@M(N<&9*BEcd8=HERwBdY~@ zto9Ug+oK3ZY^@+MF=)=PmgJ)bq_7CytGaOEU;Gx*rDmCrE`#xXu05u4CcDwl1hE8( zpBY0d*y9Mnj1l8RdNol`LAz7pH=YgEK%nkmWC!B7aTtQ5FJT{yJNxUre*xH1P`D`N zGWaDLOB*)KabAbVv5?qO#|EUo5|6R#)q6g#$07u>O4L&(^Qw+> zs;g^rY6q~ldKlX^ZyX~@PmFBF9~_W5ny6QfaEFrVjmj67`h@$S)KO`aRkQ)?gxJ7b zON#dW>xg=zl4*>}d}maOH3ry#1RagABF}yL02YM^_r-nGPV#X-<3ux`J}XV1&rL9zLh_ zf)6KUjJpECC&GBNuYqFznM~s&F^PeXiAhWeqooWhaE7GDXP6(K)7gWcN9}1i6`~W* zkcPPS0@}I*M^5)Tkm-JPAOiM!=rU$-rtYIA0(6T6-BP0aQYgBGru+Wn2_cOxD{#>j zaXIoHU-u0K9ydGU($9GLMqD=RE|0H=-^3e{RA=Aq$O4&{&x9a|#^>GeFnAXRA~G$H<2W-1#gY>r zeCck~2riLu*?Xe#n@I@J<}B&T%{NelEc)i-`nn!b2n-399r$bkYG3;6duY6qIU_|T z%=fVr(_kqBjJ1kT6C|_*)AeR}_u?ZSAd@)zXsjw02e3Lvup05x$HTEA-8`(a@Z@1N z+hBEWC|36)ufgiI9V}R)@fLjjco(Sb+Y`G$62qSa*)G|0q~VW}fhs>dyrSkaBN zRZ*B&!4)i*C-d+E6%0x|*3Qf;O7LE-tk<#D#*p)(%Wo zwL>HgfjE{viQ_6o5Iq7*lPxV$^rT#pxTOe?pb+oe^A;TXHbaUse9{&Ixz8I=iPl14 zu2$9g#O`TSuuUtiHEQ{Yof2lpT18C7WS&@&g(UXcL6i7aRxs6HK>;c_!`{L?7AhDs zg!Xl;-G5|Bxx^}-m5RrmerRNmsC<77g}MgjV+{*wk(L^kEXIXOEBHRKD#G7JR%5MT zn%&W|gq88Xx^t=1@_z;uYz!Zy*|F6`6bCTi6*5l}6IJQO&HlJc4+4Ut6*mIDpUZmBHNe|Y5z zhYO$dFiEi>_0wy{>uwGIS55}}kZFm^qWdZe8!Pkgt0-!$Jk_cwK?E(UVmQ_(iORyh z5P1XFTbg(;?S6dH9F%nYCLKM@y>GE4&+CeoiJI&aHQ6T$+0$2aAHq0S&mz#V#mNxNaRvZ$p}K=mf3%EIKdQWV1MC)3-s5qN+} zOibD?!(qOY0aGDCMG+|NL~>XdJ+}0V9_~;vglQR+N(e>}7R0Xfs&FrVW-Qu&I?E9bJcKFgg1lk;R!0120{o9PsQoQYQ z3;@Qv%nwGoOubLHuV*d)UiZd(XuME~H_P2tYvnAcNoKtJLeBYu-8EBJ^5WX`7VHiK zRJT9zx32un+&(w^td+h^9Dn-)m+wXV-llR~%(f8FLSkgwPjLUw1i6#9E%z=l3ZK3q z3a&57l}5Eh#!VD3UKrftL#h|Sqw(GE$2WYoL4ZH*u2`##IhmGNAAZ&<>Z^el?3uue zTT)-p^bp9=nEHZBeIUo`)EBhK_;ZYrRh!%(Bcl0vZNf!52O-$KT_B{_qNsER(xzh^ zN;86uR+>^MeLS(XdLetpPr5%Q{LbUQjNQRisI|(hmAISZBSZY#{|k28!Zjl>9AIzZ zdeX3)ylq+0gE#z7vzzA6EgcR?ws6_%6!`zx`yTkJtGfRU#<;-XUUh@1BlqYuQc857 z7-&G z_E|~LSk+Y^LqbcB2Hy}Em{2CBep+rUW3wrTTjO=;G2vzHH;*N1d}j-1{!=)lQiG## z6PsOt@p1C?rP$e&-XO8C*Wr)eQIuwWiHA<<=9h2@SGv^vQlME0s1BbQ*r591oGB&? zQCJ)lYMq3CP01<;m_PCTbhamlJ;3sBCcmVulc@h>@+Xc5VXUkUY=IvG@b9_6!JoJC zUU>jlyrE2cJKrl;_`Uw^>EHb=r=ox5=J`!F%=_{u`q}IO`4fd$q%58Fd+P`8Q&$z_ zqyip5K{$C-Bx^bQ{`Ds$yYb3WEYM5-Z=YoT&-IZX_Hd6m^V7Tha}x5GHLT;e>R}}a zWCM2ht;a9EJJj*tztyTVm4|f&FHsCjPpcDm4j}(c$DRCF4zv}^>;>1b-?V($R`;4eNPzleNy=wT3fyEx1=S6ixR?(3Gcn^sPMc`+^{(zye%Pozc*~G z;l9{W1SW^M$9K}-lm3-I`~4<7=&SFgVR}yDJz~t~+wbpr?cd&Xe~dNMZ#eUj9Hzp@ zNmuL5_uTv~_5H1*@&GyyIzgkBijde1?MC`My*V}OTCsA&Y_RqfEZ{OH9Y6B^X?IQI z%DcOK`uba)DqLbb7GfPd)27!xyg#HW#XU#$9IsjCGis?{(P6m<%$YAwwBwE}fa|OY zRp4+@+AMcZo6@%YzSsh@=J2wKuJ+fm^Cd=ur+wABIl*c>|GK-MQ*runU|iXRwRvT> zimcFY24e?`w$KHDL1|m^2_HvUH?TKtDR;cte`@|-aON+izyG62gWc@fy1!J`YYzJTqZUxiuN~*eQ&;+fk3i=Fh1yS3Tf?2@mZ~`ruImNR9XO z|FPxCs_y>rm3Z`~@s)*B;j66Fi?2kjlfhS3(J#KL_7m|{7EQoc#wFn^Bj0uSdaW~m zz2R%ZU>tl^1G4bd$>zaV*G%+-uigsa0RB|q>)pCgGnikpYy-qMW4y?S7l(s!W4*Mbc?u4pq5SZY=VfrXu-jM){|?u| zu5Leh^fRx?2g=VdM#M7itK;kBAGKd6r+nwjQzG=M-WU|Q&Mk%#{5w;wOn^06PTsI9 zFTasj+ltG{3TL2E=|Mr+j6>9s$E9w-%jn-ph`*l>`ib`Emc<9|Ca>FudQ;bV&%A7`b+$JY(I z-g5A!3%{79TR;EOm!K6^E(+G9p16Tm6zXMbS!(b=!m}eijJ;v&44+3 z(zv3*oe;yDlrvl2#vUXpy0ey2;OmeApS&@Kj_=UOsn(n3U_Hwy^xYAP)#~H6 z!Qvr!*F$dgz_>oXF)ve<8YrC92SI(D7iS8eA+HwGbM!4~%*;Qh^-rxDH| zS}-;6@2>jYS+kaT5}9HOfl4SL2@UxP0f#9rvt}B?7r((x{LyqkZU439B?hr z@Xw4GIQ3RTAReflHp398{53EC9bI!V2{Q6LVkeu@7>X zTQnk4z`|6DMjbZ(C5T1?H7LVY1k?6BiIp{(qTbBt9PMjX$(@}*vL(vCvP^e4i- zpO2i(dus!4uXp|b$+Sl^I;k~IrRBl+2b3NLHTF^-Q*J8j1-U)G!3PgH(LvEKW*AQ; zAJEZ0BEcSm)IP((xU)d(hA&$D2SbKG|0tropn$YMIsA*<8@%4(2PR5r?L zwje_XdbZms$~(45*NT8Pw1PZPkc5yZWm_XGHK6mJ>ZC;;wa$E0c?caVr`etiX_NXF$m@B~No>eI0dU&-_Fy4We9cOe^(|8Co><2JKB4LaR*NBSaO@%wJoHFQk44TQ2IlZa^?ryi*(b z7gOQ`{?g(6{AQBiJM`WyqVGQFKM<=fq`^5j;D&M-;iEMZciFYGnF{UGI zQHiS>4kA2J)_n`=vg+kG>g~4c9WK7A>Sdoml&W5)BWy|FF&0Bu6CmBq?zUacVpPi2 ztiSq-kzi7bWuw=-8s#@QLcJPEmdHnou^3}f=O{&5;pwv2cvmrgqgb^n<`14M6l0l`=J1%I3U7b!}~MQ;C3|Ui4P&ZYQ^@nXw7_7;IFQP^v_Mg9rzpW-oFXJ zEO52WZ@_6e|48_sE-Ga6OhEH6bd(UTl)aWWbM(ydTe3e{EJqZ|VvI$xF{&8w{}WQS z&bXYq(8^)W!Hxx3C%Tp(<%@|aH!`IZDYqr2+{BcrNLieiatl+=Mat)0DUY*_hMV!@ z4+3R7jL4yIogBadbk9N&eq-p<`A3c+SA1b1AoOtSE}OX(d8}smjb@ruGanE$WiyOLGx>HiAeSa=mnLz|mY=gooPl2x=|ZmR_>JmX zRdxR+dTwE_8H?)9b63~uREJMiXH4Slh*)ef>wB)bW(od`x~d3G-;crthzf3z;aHQR z?em$d72hhhO~qco*bW^VzJAAjsB(hpzz5Z+LHsq0k>ifVs#Uph;ARku?aUXd-Wrp7 zWGr);&jHhK;QOGlnpv^}Sr}3ev#2O^^&)ZC8}gV$kL3}LBxF7xi?I+g=&DuItTgiP zx}*8X;B=B93C&n+i|XWftCLJZO&?L6ROzyNA$5LJQzXmEa#sIj6bfA|p2vH3IK}~F z&BzwnGp41gFY*YvUMzNk!%~^m%tYbm+Y9# z?Q~hX1#d8xX5-8WS=?t%V~pzpICR39lfPyxqy~NN^osNgUSnWYUm7r%CibivJ?k2( z4GL8M8f_q8L}>a_tA9kdSd0kh>K}8TbpLA5s<(e|uPH~q{@axjJo2eaNhEyjlA$Sk zBR6SOli@-W>O3f7iyeD}GAo@Xy9hL)Z!FHBF=~o0k~4G4ium%jt}}78*7--K;)rcE z94-%fI9;{e9Nf?Ls}I8;yP{Fq*eoE2q*zr~`Dz$h>=UbAhD@<6ppv31_N$I!FYuQ^ z%RU7E;HBG9W8!1-Ox@w@*U&o{1b!?yzM-r#zOF6yPv`(0zdf@mz` zjkZGAVXPc)m~bqQI6YX-i)XMyXHNOY@*`a^_FS*H%LZLB24j_jzgP6@pm>Da^aTO< z7ODCN7TuRHKghE;*ad-_eNkgN4^O@624$&LEXC36@z>B+1*7?$c~_wDuz8mk&nmy{ zoVUh$&`}%z4VauP$pZpiE-q2EO$o;Ff?P~yOF*nAj9`12u_W8*iOosC{xgg@8v7%k z_nf#IvdbKUe^+tWl(q(t2A0*9^~D?P6eB*HI>~Vv~7q zQPym3<7Rf@;>d>du3r#^zBvs;|4oeznLbR^u%(W#qGqN8ABiqeK<|9!wOhd19Wye@?aiCPJ{0+Efaf2mW*I`^&>OgE6 zN+Eoe6(+4A{4s@nG<|A|mUlo7tfkUB_V_sbg5XLL2&{Ou=z=6qg|lplLNctH9Gt}@ z{>si!r=)0zrVaK$jF=q2Gqa_1dL$OCbCQa;i(eo<8f-)fFa&m5RZ&qO&b?GkW{m)P zqw7V0_Xq&{%aCV{Hu#A+JU3Ru5~xp&jC(J@5t`vhBW#8u+e^i$tC9J-tco;o=Wy<* zV!5&j=4`IX!#7}wC77|e?$4V`SKEugT^YvZ##88=F>x&{IxhnMv2xD9wr>vK`UDkl zm-8~9Cs&f+8!Pr3(1YuYU<4PRKo8=oVbx8F&(VcGqa0#r94`iROet^kZ@34eR1iQe zOdE5>iuIhTKm$@dD>uTB3F7F4EsjuDA$u9ii!BxdJaK{ftYY3MaX!AaXoN_O7w0ju z6{%WwgRq8xmKPxrBA}(;SZq3gg|L?BA!Q=~?j-vd8s$5Tv(=8h=7u=(muH!eaE}iAk|gtzY-wI%n6xiB*XDMIb@9Ej|CBJdj&gQb$YTJ);Wb=uJ5%E)hIgocP2Js#faGChl^ zJyD%Fu$Inl5`W@RN1rWEdJ8RIX16@4D{^wpPIfh0ceMiP4glt2{ExrpL9izpCj69ppQexm4|5PC=cMC^u2 z$D@x+Iu?32YUAFl7VrIX??d2y2>kyD0j0mcB5v#Nd$CWA;<*0KfO%)aCh4}=!VE~O zScNI@87qA_+|z6mu~*E@gJ)eOEYR}w8Dm9viE&qU(pG4++6qDbqkK?c%LlYS{dQqv z67PliIQK9w>bkv-YvetSH)~&Rtf4)U!`qEDw0w2K3SK>Kc%}5`*Bqo>AWz)nbBw41 zQd0w91h60t(k#MKNv{vyux z*WraaQp1UaI-?t`XN zf>hV;-4zfctmDlCqUe`uBXB)-8yMA=N=kvRou{Ng?}=tM3hEsMW(5IYc0D?u!rz=j zNB>uNtv;_m>f)a%?V%;vOFQ4HgV=$S^40Nt^i%Rg9FQjmMI0Y#1`t7yjKGOzDJMpJ z?R08}VIe7S>aLIXZXcV9l#FvD`lh`_g zB)h}MDsi-liu92^YUQ!KJcb7`wz2Ld%wiwayN*7|S3pV*`C3PY64z{6CR*DE>qk_l ziQ`007*rk*S7L;UsD7JLQnTLA z@H7!CRtK5^$LO|B6C)RRQJ-DY$NcC=P&Qln^{y+zi+9osdb`z_Ce)GQ`%BqSyV2t` zrRdhF<@0xvVt$#gDaON92{G&NS3a(3lTQFCARon+vb`ISc5$8ejx(a3+AmC;_-0_3Wj08{sA+9#zxQfxCaX*ylIuzRO4sEHVuXoJ3EY}io zhvHvyh2TrGVi5ds9~ArMNK#o4&i;w3CS%gh=bF;OZLhF{N3^g)_v519vxPXt*|fI^3c1OKrZ?`(tvKi>=hkc8Fx za45We*;Z>AH70RI3%7k(E~e7l2am-;zd?ePoC7#03HFXIS~0+s0PSSLcxL|3HZ$DB z@KE!)s-~%+3F4)__BP2BjeRY$m=5emK;yRBu-oFoA*ASKgOm)L)PrK_C{S`w;qj_{ zW;B8aNSh!!R1c?m=b-rWx7?M~R7*6T*#S2-p@2RIo51P)Cc`I+-8O_Hp)g5fc|hX8NYglq$oSP#F>; z0HaidTJEJe3{2?g|H5R;iKOCiDwTK85SKS0sp1a4Kl(ru`nLu zqJ8U!Bej*Q#B+_nz*j{PHa{lovH3Brme4OO-*V`9=l9s+D9lpQ(r#2n)9(R({BD=K z)OzvlWA=Knrh5YboNCFy5lguMhlh)FB@oH2k(8#=#h+g#R&ql`1`>`FLok?}4B~Wyv+XA9k$grY2G)96SaU-co7a|r-664Z7|&U%Y50?mqfuj4 z7W~-_yJD8lUmM_2sb&2Zo-f5Vq8&IYxqP@z#$c&pNY;q$->i>mxouXMa+_Yrm^!4w zCoZ&78xm79Du#+IE44i_l^e^yTqSGH3#V1MY7Xb$?he&WpeX5Tl_htolB2>(mei>d z?l7EQinlER?ISK}5(`s{ZQz+8NlMWBXvIkbI)dJoBFW-yDUzVKrAUI_mLe(X=~by> zq9_?N#CoQ1I}(QDL@7^pEz3FdgLwCq3ph`$T|=9Lt)yKp|5&&nM3Ns45xa&`4AoY5 z`MgbaKwR3O7Oiv!gRNDK0hocw^Wlnoadqz}lX43_!_4jbJ`>Zz_leC29e)yx0X z>m}4dt0nl3z$v;lms)@>5N}|(5TM~Z-I+`Jx0l;5?u3=Rv>vJFtF3W!kShcDB@8kt zi?1guzd$@cmKCj6R}qnwuTcxAmzoOKXW6RC#xTV$({*`8F{zzI>SMrLiz^6e*%VdXoA2i?#n z9dXo$2gJICK+ZN?#l%7b;fYHw&3vjip)Tu@4s3<>e{*9q^LeFYzizUsI}n>$ptMua zUhJf-vX51WtIR!ke>&ipP+>LnanE-(Dvr&BDMxW@6jo|Vqji_BuyHc{Y|qa1e;o_X ziNP=z9&$CdgRq#9+SOx|(9IdSFzlHXFp9FH#Ugym!&Jn?kvrqj^h;q|b4clO5Qm-f z@bLPdelM-_JAefQ|INRD07ON*ag~~NsTtnJbUd2J^z1))(}#weklJ+{l8z)49U5+D z(kvuR_LhoVjJOPM9Cq*-KSTC2ku)70w$x3P0dyoBM@az|Y{|M3A#3HjY@LJz1j<5;wiO}la+XEUoEhDJsR-d5+KP}Y1Z+_y05qc> zM3wwMMURT!hQ8*ax2Y-DDFU-iIs8N#LcX;hQEH9%LT6DTJ zBU;{~E}=J1lXp_hU3Bw8&9XS}Wl5WDHf>^dNSk3%w~=ZMdG8Vwa|m(HCK~jl$j+si zRmu!Kx!|YH%o?>k?^YXN@t-{wfjxpg0Bb+`BSl`{U~nvHBz)p5p1-*0gWE)T{xU>- z|3XP4s9o>ZH8pB{RHrr2(UPKkA|i7W1-;aGh+YuekvVYHr700B9w{s-u_oF(k?^Vl{Rku=qwyBzQy@Z3kt2~0b^=+F`;)M?p^u-Ox0N(>-rp>|K zoMNN6MeQ~k$O8l7r{Cg`8)D0RDy!sca-%K2bBIYz(V@NUTzJ&q&wW-rteYbT&qLxFD8%Z6@;SAlHhk&&fDNF1`d5Zwyx~kG$hIO?(aI9E=YhPqD+v*~%!_frIon0X^`-K|?I1C-7Qs2eE6&tuVzr zpbTajwiu|QIkV{xwdx)2NwTKBiFFN-u2uiPk5TT9vY)`e-nV#lQq3H{2Tqc zO+Tjs|Ask(I$8YN05Dnj$8QJ!cD`XliVQj>{;fv|5B|9$fPV}o;on5!pUC#$A2SXJ z|CrG|t?vx}-R#U?O8i^KaeDb5qud?U__y$%HdF_Sf3l{xhJU-9{+|l`i-KKfqB>dp zs|1)V{NuNSe-mAm_J)5;P{MQH?fXTu?emnTL^K~0iz4E{1 zDB;0BcLeZ{!6f{fMEt8i!-Id!I3WCEM)$P7Gx+!Y6ZZVA=?7-8^m4yAEzxoE;2y9dZYw+&pE7MPd(aMvb_3meU%2gcq-r4qBRr?h`M5 zfFif;+v*%!RH`JrKAz;>7$^H4A5S}3 z!!XCk(+-A*dwo2OaC|(;eN~p_!)`jV4HYzCvR^$ zb|YZ#t+ydyYbWawz-CVFDwL0>){xltXY9(f4~#s3FA60)Tv_mfv2t*s{l<)9>|`Bl z1Pf4?->m1oU$cHZf0c)YvGkHag8_L&av2h0i+G6w+b%hKclmJgF*|_L0WlWGiLhRX zehSVYWGW^*kKqV5;U7<;X5M57wn{Ol~;*nQ$aa_thm zWbJ1p){f&+ckQdK+Btl6$6D8}G%wm|qdE>a6IqNE1trF#ghXs3g%}dbjgW$gO?o(WEZHD2tg*sCL<~;EQRxR&ppRekT z$?N<;A8?80np@Em#borQ@C&SzkWN8^sGJ(Y4??p~n^QOfYE+(klp~(xuszc3|=vUSd8vfQ2rvzFo=xx!`3jE zNOL=y0bzxiq5Nq`Hv}^2dAcM(fscq6B`3*x3un3&q{1?_i3WlCnB2iN#OXE8{eTG804cm`?{ zODe#M@wg))eX(E;l_1u6_&6{u@#xydamP)EQ0yAj_2Vp~K=XB2s?fj&fZ-`jELcE3 z?Q)jUIUY%t6A-8N%UuWKDV%`xS^H$$C&uNS2f(VxFK9Nn;)uUS`tL6<0B7i!+hqE8 zmA_K>^pqY5wEo}=fXsJ?HJOD^`*$6l5?2w|{B92-CI{n)Q!zjLII~O+{?(3o;~^CT zq|su+vYDDFrp+u{LETQ-6!AwNY17Yn2Ru>$xXo9yvF=CCvHPpcK>f2{EM z6rb$N@8N~4VEHq4Yq}^HJB7rf_r8=af#dr}U%J z%?UD-I@F<;wVpoIG`x^atNpw&@6Ww^J=}wmWnKR@O#9m z@&M1`-p}?v1m1_hdkX@Eja7FCO#gQq^&zj3?mg{I46F0noBwI+i&LIg+)BN;_q>8p zZpF4fulUGIwibS%=M}Q1w{~8!%jy5AI4`^LMSD;udtPx1z+|0Q@Y^}B$Z%E4g$LW@ zBzu7cDB(G;a7W<0g2ANoiZ4L~3WrB|&MTO4K<5?A=$_Vh=DcFn8#ew`b>Eumu);VR z`_3{BOxZU^%NyhamZ3`^ZLQ^F9z2I=(Ke3JAaqIdVW4l_`d8A4b=@Bjh4_Od{M6t0 zf59(LKl-}yuSF-Sz4&UMww_8CA2?=N#A{(=^@c;;d@r5DOyLCV% z*6WS`{q7t8*2R4vw?MYJCmrW-dzN9HicpVaOGn%aYUzl^WmG1M-yOg)Mh|t~S3zh; z#4W4Te(oFwU03nl`W1a2|A?9)nx#scXmwTcVcZ>1)};D0Mc>EQR+jR@A#?h~7bh?$ zuAWdDwlmB7__)bIwW4(&UmiUS6Dx6>n|jSdypMlB3c-$3T|R64AUi2!%I*8q8)`}ndA-p6lD zypP|i#$n-!_OyPQIDV9PLfKV!lz39P)F|G~nGqpnxvK5Xp>dV^bJ>@Al+h%yJ>15k9mw-)Pv zL2uQ1Uv0Yh?c`Mac57JfW8n&0V@xrhrc!K^2gTv_Kj5`lnj2$dBneF2b0z_6HyMM( zNU#Kz32a1dm_UvK<)LaH6~6u<)&UMC?=10B1*=xKJ8;&l0z@60pE6K^yXW$7VW_xQ zvIbtxx;Q*O{Xt*~>%i4@WDuW2B2qpQo`n=?B`7)lc7(bD;aP*M?6~B{bf|Y^2jC_M z?o7gg%du0{$IfF9q1JFX<3a3Qf%oVN-Z?~ z?A^$Zv*X>!po~|wvA7~v`|Oy^)Mvqm>_;;&?KS4Rxc!FFj0)%a^wkrN29MmBOYk_- z?vS|oVUSZ?>9HEa`F`{Sm4Jt}vS*tnbK|YtvcQVA6yLI!;8?Qf>MA?m#lIh_dG>j;HCXA>oJvgugb!5(7pJok#;|W-SRs^h_w{&@cb`>U&JKDUJeB0)_ zuJd#9FkYP(t6G%la^(tWQwH75366ZyFvH^m1d3}#AV{PE@)=_3-}m5{P2MWYwx)q~ z;#ZQ5kVk07 zM4&2eC3#c1^ud66;}r~EDoq!6K5fZYwp7zJK;DE&b$F9zRFXHb=1lPyd6zLIZ`vn* zgTyz>n+|z+lXBFgd6Q&D@VcaVlV(*O-lQZS-k`I16WEdBO(fsc?1<#6DMT65Yf~1< zoA!ypYBY(wX$2Tlqj^_WNIdZ~hc_Luc@vnTn>R^*1nMWVC4Z6^kH8wppY%mRH*fV0*tb_6d04krEJDTE@d+&4%22#9-)sc!e&fd?rdWqvMdW4ic9Si zFYFcSTCoz7$0mmukZp9CwFSiB3tx@p>v2E179w`4Oep>UtXOB82_ zf5(*#wS?vKAOxa){y8o~Y1nE~a+>TK0p<1%AK7JRfm0jI7d92H~R`r8R|_niLT ztCramJ+GO;Lxl4EMx?>b_SLWf8zr-nD74IrS=;zUIcwF|LCU1%Mr=-jnX`$;_y@#G z|Hc*Kir;9_bvp_IG3q7kxjfh_0+$DSMd0$_upR{L6~TE0lnY6!6@dr3GrLEEtH+$c69~osrj^*-?g*kiB>nG%KwaaPTqF zoP6BGKsK)9YCW5rZm(yl^le9R*#Wdm4+FD#zk~}}b7nOfv+8om2z|c{E8AyH&6x$N zvtDVUGwty`ZY(m-&qHUO!8E6{n0fwYRKZxn1EBcTf9)}k2Yu<4!%D@~2b5$)I3&46 z*7>h}#>szL|M^vCahC_JTFw0Tuls1m?l9V`>dq}OUckFO;)@XCjF!SiczB2gPt-i^ zue}L8x3ml*fcWFjsjV;$8e^g>j+yf&7;VNr;|w^hFy`f&&tQcPOM3xhFx=XPvaQq} zb6)sLz6BGx0xSvDEP*cxFkc~FLUqMGh`hH=Ty}$sd=`6SI=u%@&_PssgGS#`UaNlqyx{+fHEoJut zs5Wu}jnv6kYUuU>ZR)6*b>y)7IZ}>5|;=ja4ot*CgBtnwtlXxRY zWc`OTv6wDSHJkRc z>^3Q#k`K%m-pgL&@V~0=tW@&6@p{E%@#52xfZ|MsyxCa(Q8YF{;> zSbYd}RIG{yeZczR6~m=_E$X3&{(zjK1dt2~A|Jk#jlrcP<)Vr_QDAl6x*>?p`%BEb za?$^bAvU|7sM7s6>o%jg)i4Z>Tx872Dm+fK83%icu?Ur_cjp5s@Sx532^* z>*1R2V*o;Gl)&>=d}6veC@`~W;@qDCiV`4UWus7H9EAIJf6Wx&gvem(tN_f=M|=a= zf_%Uuka|_mVt-8r+CVk@~R-0|r5Y{LeAL$dAG%B|u!g=39|;sywV>WwnkfMZ?* z()O;-Rh-}OoC9&XL+g^lVy*O-D=!{E7s|~Jj7E%jMLPOTSx|iPT+lW39WVk+14k88 z!K0P_!WJQ^I?%fgwIQ>2XOt%`HIgiD=A0Y2BTj%{_I!tVsA93fPOaX$X`zk2``?iTQtwhfiZ3mj_^e#1RbZ&1P3 z%7IFnf=ZUS9@4c3Di?q+E2!98HbTYT%yE}yZ}SKhOEcwy3N~p9E)g3p-^y$3M=dWXv;?k2(q}NvVz_?*0;3i{ z9J~WC$8KN~5W$Alb{Dkx4PZkQqz(g6#TvPZDP~X+BOzOJgty40l#Vwn#_3=GVlUTsD5n@tHr}F`6%C3`O8-|9w2^UIL>tGf=OZiEtcne2LWyn##++Pn zJABkzMW3_>sO7{QmhAeW(`YAwkYwPsovZo4JH)Jg7!pUR5z{YU zjR#B+sTm72PPOxamCQbWWRp2%ufK+_1ju^Q#A~%K%#=GCf6Z#b#DkxWKX6cms8jER zvqAc^(O@UnVuhcVTlfjIEWI7|>*p>>pVoIbzg_6M`)cIVHPOFb5-x^a6TojwfL8W{ z-035ixbpxM@zzD>HJxm-^C~a_R~kQ6{UQUUEX7Xx?miSdR)1KlRiO1hdoO_e*kAtD*-y+( zTP*d#`9Gx6xyDG^LztIH1p**#Li%I-5L5NgY-m$0H$?aP4u8_pV3L+T`RZ*W99HYOSPYbi;N@5!hfCgnNKEp3JT z)m11X9sY_hG+^j$bhlGZwFTZ4zy+epj~bJ9T!i62_rPN}A?CH$*F3cWf9JU)s1%(y zcRm)z`Band6JN%5ipmrt(r%PvOR|gfVqBN22Pe+LuH23kKCmkTIs$6bGCZh63&eNN z!m04>88^Q9wr;!YskFjhf{czW{yxCqLJlu!dPU1d7b)`_TX>omcax^Id(|R}BXPV*sHyQS%y7|DFZwyW*jISCgg84XbQAiFhs4l{tK_m# zu^4pIJalK|`)ScfX`LBecME^NdnKu3LZ( zYD#pd8xJx#)J-HIb%PMmRT84*9@~7Br3s7iXp|a9oPx~7s2jj6MC(r1sE1+~?GNw9 zTL4svuE%ay>MqYTS_rJ@y2Yr-%&EK@{aeR5Fjmt+sIh(tf7cL-Yo6pU32q}ZqYr~Z zSQDqB#6j^;gcg!mCDQWgz|(w`S*(t2-HnNssZT|V(s(sfb_56QII&6LFYg`IL7vQl zqVWByAufFHb^SOZ@x40{-(wpkh7;j8e4a;i4VceZ@d(TUR@4@(FtOrSVeo*Dip6G5 zJN|~E>y`tW(eJLtFYFu;6HkalWnX{Lk;*E z&NH#f^RP-?pD@4^Yn%b{+u;s0M}xd1XB+^6&CC`#*#xAvZw=pphQtN`Ve>fZCiz&* z&E}-_kYa6tjWwB*@^3_xq|fjKFcrj*?O-)mkTVX1ZzP4Iju8?F?PX+-A6SKN-73d3?dWm!LrkwIaRHcJMjlkE`Z*l{85V~&I=rRe*m>fdS^vg zHq>cy@?r^*FOJp|>AgMVkORLRa?p!qI1T#$zSm105cIQN4wrOok-TTUbUjzp-4Dqt z@!*F)b&WVHk;8%WkXwPs0FRNfTOJ0NalF>vWbu1I1FqWVbHsyDeGHc}5a`q|hig53 zlVZ3T6#g;XetiW1`)o>ejxQ2ULufyf0?)2p0PFUs4FTV#k+8gi`)tSww**6dr2NwLv|{02(t&KMh65xaz0fSP+J+}t7&0e!@& zM)jv3c}6u>j;i1{d{#BZs0cS_RA~q~qbk><`asH2ZE!~Q+8!3HR3kH?&UXaBl|ZwvdZ2@#`$-R43dj8vW0qN=cXK4oo8eyXpIclZBmY`#Wga1 zyGO>#^vDW&9oePZJ#%)x99dg$BO@NWMg{_PMz%@Sm4Lk&)>XU#Yw)QZENT!6l=%6>hg=-;LU71MeR0S&`_g>S03|WWi`0x@ z62dogM*3lrOVB&bAwWy0k^5UMgJOJAZb@Q{EMyI-OzN{RkYn6bC%;GiuH8jC^5*+r z|FiOJcH#6o$}lc4@3FSS$m9tlDNY~5*)04xV_gPSaQ3sU!nUJ;Dp z1^_}-ZgsKDQDB(?-AYTTsKRqCQkPxJb}6|4XzeHk7o&hln4DY`x-0Obg44}i%wwQ} zZ^2Ah8~n*~(b^8ANM0=~TOVc(N4L1T5KuKRA8UAdidDnv71?RVTE<6f1%6cpoXpA( zQ2yk9y6a%2N6yj2V4=nnR0so5ogzQrt5rKN_`lQAyDWxoyLoLrw6Xv^zINh^|0?jk z-j3a1f7RJv_uF5a?61xC*B1M0oBg%j{@S6xwobU7n~m`0*B4Ryig{iD#Vbv}_`Mn( z505)YVVRT&9XO3NKo@akL8d6~2q=!n47~L!@P8J{A~$%;_C*}HEUGBP2*#@#GiBXN zP@b#8TC<1;pr!FVDPAYg2~BQXbMJ5Q1Ii4kO+o*Z?F5fpjdIVQUXMz; z7Gwhs@Zf!-e^xp6AV(kQqoB_J@pIs#PTxOzvY-602l>o92XCua7g@bZAmfuf%2wmW z%wra;s#`bp4j|;O>JF5^OtrMkcpX=r*WJP;!x+pQ=K$-ffFBF&X^ zL+WofPDG$LW;~4Lu>x*@dmST=4exoeU=MCh!O00wN*+ry=V~lMhA%qGD9VV=$VgS! zCS->J!f0dNG2n4@9aqU_`Atp;H60GWFtRs)`J}=3Y*U(xUK?7T@rEZSggfBi$en-u z=brL}3lhS43E^yS*jPip=v0^-CXaWglfU*A=7Qs-V?KeuKX>rAsyp@h#Zg$qn>l${ zS&UjT;@A!CMmk@HBB0H>RxDu93)jAakjzP^pRk7scH@4@-HyLbRk*}>EW|okWiB#8 z#88z&SkQ;YWj>>J3G(PL_z(Eee0zt2C5_BTJv-p80um`UJuow!Hl=O(eX#{FnOru} z)&5#`zQkzow69t>Cs=LgUw8L&Do({nOM1x5*($QaI@!)SgtjmWdtJ>Zd>kW*H;;EV z1MBBQ&0nW8f2r-!k_JO#w3VMVOlv?IY;qRVn4xG+kKGWTXNJ5pVNJO;8TQ!a;*d}Q zZY|BJF;_j{fytXR9g&bw<2^UaUf%|Suf(G_jjt@63SVWVUVJ5LoeaLRihl7`wV#Nu zvSU8Tqcm*BhPr>kVHM2IJtX8jyvrPBss|x@MvueDzjvD)1HBQ(qY_dAyEI zO(+)^eqiA#?O{sAq2JP-0yjG?*j_D4alu*P`=F67e4noE!EieTC(T$awN)4zn8ag7 zm%)1FN=GrxZ)k5PM1tsik^gfUmswSd~ej)$l^ebC<~X;Igy!D1erj(v8YGAL#?Mj^|d!uB@ViwADU~`tV#eR zC;*|N1HHs>VBxtP6IVea$l>8TarLMZcW=;t=-yIf85;f~vUJ@j;owcj4e2Q`{^0Z^ zC7jCys1*_ua7>UMUdkF_*ce`d4*<^0$-)|ht`TBtk(}+19>;Oh+}Jv*^Z5D>Z*b97 zhWRLUb#TdnTe6IAqUs4oCq7gGF%PdOsi$S($Ym$88yl&})Bc?@#X{Wrz%gStDn&6| zu2arl=m5mNL8vE^>!Nxk1XIkts5wdQErRXvYm>oN)5MD#;bu)oAHv<&3|{=>ZdEiR z#j}Fkj7uhkzZT~){@rA~+0SAAcA#TH(rfTG*_EH)$PXY`&@9t-^wgutQ*Adusp_`D z$!qKmINALKKq|v|5RGeO*OMnCj*RTJJ=Ku4ZJL=g6?2UM6;k4hi=jLI=6Y6?7QLq} zRfV2%>Wm(e68Vv08_Ire?hwVHG<#B!X1!uk?IH2x3H2bHG`7QF!Hr;WDo+=_2xcT% zRy$ahW>+$sPS2b}f0B-*PA1fKjcTEJHT$d}=P}fwMi4VaeVNlvtY)SJMPC#DbjN}&mipUZd|7<0eR)=B&Ffkx!;8@dA8k3)=VG7;s-^-euomR$b&_040w$ZqN<( zWzCau{6Ze%Ft{VVqVPC=3tjtlnXlB!NUr0&T!mX8e}8q4Ib+Ie%b!P=Z0<+e_K@MJ z_A>2ExUq&RD5weo(KS>_HOnx_z@>9>a?A4qUVxKYo>YrG@Ij`BQCBbNY6r{(*LdB` zxdW$|U|BhpP?f;@5LV@C2)mErog4F_mcd60pN|h3Mi*o2 zc(MeaJB5c0L`FtRJ>FvE7~IyCe|Ih|L7@HeZ*mw%2S<&O|4n3wi&l%YY zB_W1)4&)es9h-rit&DQvpgdv0d*h$4!s>f+?~Tiv5>L7u4W1jDlD}2|_d5NrItB0D zKX8vdD6(1333R#vN*VpVcfTKCvi#Tc+wosN-Bl?Vc}oBFEhwR>UcGnkj)4Dq2GJAm zd-q>O|H5J1q;kD?&x`}|U(by0X*~rf=b1z!>RDEA&G4k|-+%9#1`lsB)=*e-u)|nG z>Bt>U(*Mp?ZSdl$ytRX~Y0qLp1t1(0VV{-abXDQk2*15vrKFE7oChy`Fv<-`)V~Mx zF?+R*N|a_XHcnt}g(>FYQyv4?gT!$2_z$(paCDNa>8;Vnr=9+v3i`Nvl|87FrH{=3 zlSLo=cIczPRcUYZu?ZzS^x=*GeK43rAJa)6OBQ+PgBb@zAI#{U)>BO%3jcoM%wJ0U zYvMS)_{S)BM>YN(SYc1qK=Du3^w#h%GhoxtsldP2m)nCnS^R4Rm@NF`w}XG%T$T2Q zf4fn_gMaP_;2(oY_&1UGH{mu9{xRc#@Q)eY)B4Wf-*wLXrNqA-9H$rm80GG$#s9uy zPt`#2PuBF-@b4j~|EB`~?*6hpsFTIN?EsU7fBbgvufSDlZ}_(jB|P}&jsX5Kn1p{t z#J`4HJ^06r1HwOMbWiI$gMVGl{H4Ud29DE)Z%~3?5P?k{>hr&8ve~V?bPzW zyX--oEdK2Tm@NF`w}XG%T$T2QfAuKg!9RBd@Q=YH{F_Al>-mHS|Cn(=_{WUyX?&`;=qS`dozJ!%fbWx@D$}gI-hD`2W}HTq15|GVF$3_Hgz_UF8dMEUh#)yk?lI=D){`^j?Pu2uqC2|AUXH7hdwDhX{MomyzuxBVurLL=0o<&-D z`Hj5oDle(dm9fur$qZM<0i8?Y^pX83gF2KsM2UMqSWG*g~ak1 z(D|zQQkv-WU-9_HU;PcF-@BUIGy09Y3!&IdxXur@g~LDkIxb?{J{09#@>Gqtu;FgA z!A2LHg7H>Ni;N&jl&NOvR7?zJ!?G;qk42$l+`$Qzk2Ptxo$!MAk1vAzDW5C!f;bEg zSH{rPYBCOkng{2t+?v)rEr4EfJ9Su9SW=O$`*I8w;*Qdzs6*cHmEJdjVW&ZvSKL0g z0#0E>CsgmsdYyaAkX^Qi-A+Wx6w~QJN`*x7KDsp=9%bs`sP2VZVPqvC6PJ)-vnmeW zc5@h~p2M*Ybc6e6PU-P)D8eCVXPpy-M~;Qm75OYLloA_acs(cz*SzqU3j{HjKN8^3BY5mLD6 z#*sfvOTdv)7EoI;KHUxA$n#4)IN~2Tj-U>WBVR)uHjV@=9BG+LuT+Q) zoJ6+isM(mb^SP$9aN8^Qxmtr{!3QVNBCmZ65kEu-%-Z;NtW+T)}b|+rJH^DGaCt~7L-JW-m6jY1&#y-C@|NxV0C zx>&o4L+A3OJL-9FvKw;K7DBFZ4B-sXmzb^kvIAwnC~4T#9HdzW*tULeaz_Yh+2Ve7ofwl!?DUHzBl>dU+lqqlhvP< zi=sk3jrVRd1kOal;vx;2-hXd0HHTLGGBex7FL4tg*+2m|j^Icu_eRoo+(HuUC#9PT z9AZZ3Cy*%Oc4}(obl)rsV0QJDJax;bdFcK3@d_;2fDz0iq2)%`Z3e%^MKszf1rgjN zgC6^l)eF9E3o`r$!Qj;^Vk~?SLV}eQ&5adj&s84!%{tzuFjV!d&*?}-mbmmY5IEG? zVJ;FfpgG6|n@q0=RLHZoH2B*7#Q;E60o!wc01;C;taUM zQE>>FG9S-&eY4Rw@6C9~I8XKM)HU@~y{T9=zt=kRn@XR>_lue{IVIL4<}_jATsM;h zgN`B2!0)%I_V0c>+PALLtof9_PLt4~0o~MT=zv1UIlkN9aLju@MD_RAPJgSqi&D}9 zOi`%eOiceU)sKOhrAYbgB3mN_ic%4<8 zmX50>@#Hk&8s^rXdBCYqs0@oGunt_Vo_@$6q^k&!(hfur*>_@hi_fZ_L6tX!eczyP zqNy`HS%$bMYm;ElzREU!!-{Q7!aB2B&EiCOYiZN{*vWp#S3yCjE$Avng08!4H&$NBB($E#hHlBls-jip7%c0jl}GpoHeEjsBIl+e&q_8aa9 z=*JmM(vR1JWran|qaSC+0qMt?(LERMjDCFVXq&!!^B;`|!;fk_Y8xK9O=f*QTPzV z-3#2rfHMK^MKPTi@$&1)oxOX}uFRP1KRaPRL;>#{E>F(#J*>JrC^e~1`ZsV*u)2Zg zT0r}ux3`+C==El2zEkn@k@Jby-t#y{x%zF{i(OT2ljcDArL5_#@k^th{x4Ad_wviH z-IA)Seep|HqxmI2Eq=-GL{JQLUKITQ)J0`DF-Wv-l;y9ez3ARcUYh z@_Lle1f}?;I|BTY!6be;iu|(8@bF7!91y=`M)zF2GyHPg7@J?Fq96HwDc+!{zZ={6 z*;#-HWufNG28fVi6&zK^W@n3LzMqmv28rTV5?TR&VC+`_q2P_4?Hc)Cc=--L-LuwRQ!!->7#5UK?hudAl@ zg*@T{yfgW`^6tO-19&-Z|6l#5O)tom1ydCG9hF5`NW}Cr(HUQ~I2*nKu+^z*Du@Pi z(R@h!Lh6&8g@tdvcAclB>27fmmnEm1Rj3AqX!Pjb9uW1P%6^C4837-vq`!p#{VhaS zoTxb*`2bBdaXo2FsX4Czvs&^75mMhZ$1@-FxlosZSys;nisC>?G}vQ)g9l&; zREa^M67w5v4Ec=6iK^x-<1$QM)K3WRFN@C15UW=1fvd0{m}>)%pgbuZ4^YYUVxP>g z5E%d_yXhoy>NmnQKI3RvG{W&s!uX^=2s}W`@hyec&hW)bv*tyItLcqilObMO;cXi) zc^iYvICPE>JIoc6;O`G!B_#H2)?;5!2+NPzf0D1yJL;1ye_fi*$` zt0X!tL(F46#V7FGCpvEdOQsk5WQI!;8tNA|1IeKHi+ao%GZCHPYtHNe2kMPMHK#K* z@x5hL#`_-fujZ#@Pzjwv`^L3+<_t`y+-y%sL@<%zB0phy8XaIsL2d(I^( z|EK%TFFRx28nAj|T z{3ceM^6zj6S<#u}qIZpNo|(ntm=rp+6xP#LFP*>5>8!Hz4J=|Z68)3whiph7)>=O< zDoHs#5?%ouaw;EVp$WVTB5>iR7XYW6A0Ou@i*FmZh`&VppC5Pr$NSA+)txVW$IKjO zOu(zvc-MB$xDfH7GysKBj~Mo4v^XcrcyjJs(9;7KJ@uQOi(2r>Uu<&3Opr0wgETA$ zGXwZ2;({}iOGFV@=$ZMknSlW-a|mBLvPtMn7CM7v1lAo8F(ijeY5i{b`)YLX2RErx z`-h8Th@zqe_){z_{K;I7$yUS*A8K5P!GYl^P2IXq7jG=%sSdPqTOO3~N2)1ac zAlM3pBfhWpg(yih-9^CwS4JSs{|zlL0Gb3jx2UZJ zf&pn z?SYEiqEm5GM6x6LP@r5Zk&tq2kbuLvpyYhC*we0}^r-8^-P5FQ$##S^Q z^XNiDm)t4E&Vdnk67-TI6uh=L@alEF6ZyCr8k;lU;#EWUOI~#d8qL_8FgOwP{4%g{ zJ=Qyfp?vSa@38ni(VxS3=~^-3GI7myiV=Gb z<+v5;-RYgHr|2I<6KC;K{r#lV->UA3Dftbg>2%|X27r#dx~Pa7H zFY;`Cx|eW?|LJp4ff<^gie!*p^`x)7^J7PqK!k8f8Ml%z80+eRyX;J~iX6^Zw-e!L z6<;P4XJHYl-Rw}9i})0NlyJlI0 zn5w(`y`z)(hh7A5^BeUJMZIQdi7`}m3@;tdPXZI_mx+n+1$3hpz>5RXUg3-K<(*q0 z>#P3U-cNrj3dA3$ z%LZ`mUV|S8IQc}P7QFZC6Y-loD%Vwy(+i(eSAuQW@FOupV*mH9X#@s177i-x z5b?b--N77tJ;{5L&noodlg#=N8vD0p_Xy zz!^>b)DL`^b#~wUt|B0YT%Anc!=TTZ_y_%tXCAPGJC5jDj#vD)$dw-p9S?Mwf4WZ@ z?pJX0uJRKm;s@^hJi^ua*Fd4p%OI}&1ha^^^W%)x%74)vx<5|+oC^_j=ZF28mA~@$ zN&Vl#{5kIY(z&?mfA!F${t)Kkj~{c5SH456@;{k8UQVNU#GRjSJYc+I0iWA%-vbbG zdJ|aVo@N<~grt;yaQajxd+_t5@IN)ud+IwWeDAeB;P)06ey7}>a67NLoY;071POyk z%uPY_;0|zF{U{>*rP(R84dX+KGAG`vz&@7ls>PpAhgF-5j4sJHb0%2v2N{oNyq6Sc z#D^6d%|G|J=J~DbIRHP5x6L))UgZ~#D^|;K>XGXX**x}fJ~HoJpS_D?3dBQor+^O5&lLVkl}a$4vVUrRgfl-W z^?S;In$uy_va1#=-B81;g)6Ud`CpUi6?kwM>!`|%1Bo7S6ZR^A*DzxYuJ;`@=Vhog z@o`zhsumUW$d_^|E>tZP!L;i^2_U%xME!dq!5KP$`u`3wBB6d+{(q|3L)OoryMCJu z?uU~|7uS(TLH+WPU>O80Z)8IxwPGg{L%KFx3G`itNA{AY~TDF`@O$i=8|^^dB`uW{ocp18+QTi zP4D*zA8>96*hj^XNxh6aPeB8t#>?{NJQ=ix-C+-#0z$t!PP8|-#CV|$Mh`1|M$z?U za5qQr`D->}jD|rhDJ>J9rz#CLF4SeVh%(}GJT}cIpP>-55S$WUaTXr6s58b8n{$nQ zGsGn_dinnvw6U0`1FaKU2CJ4`uYWgE`6i3)~|eVEuFD>W-z|8ijH_ zX_N;rg)myO0UD5+vz9V*-eh+(?XfC)QjLroSw+> zmy}+5*y@~3td|44fjVol1JI&DS3*VJHANEPb{(d&Jk1|$b9eUOB4f1d%)E?+_wIqd zub;jcQDSW8i^sKwO^1))=$zLAex;VwP`4Vny-ejYpaSSh<3W#v;TZOFUJ+3H8E_WA zyMxbl4Te<_FvIF5q#;TD{d80#Dd1JrJs%PPR)yE~4UYxT+k?Co!GUtL{Frt{c_2Cs z()AKZ(9vlHik_AmaQxT?*N^2Lg~!EHFel?R_zz+;8Jp>YVk$N>8}ElGORXJd4&Ud4 z-|tfEl-Te`G4b7aH;`w>#+(cUaiRxo-y1a3<(yPEVoKDzG1;qEn7E4t*O&h4zY=Jt zne%Y2(aQn!g7TEm}N zpnBA2>-(+Nt5)n!^VfE;$HhJB;JlAcH#x;xQ0%8D24JLha?9Iq;oVN*-DxW;2h!e7 zr$|HE%BxX?r=aQ4PYHQy)C+W%78tM%(8v4B4ufA7A1f8td=4Mw9hkwvnq&EE=(0gU zE04%>aE5p=oy^+5;g5J`7;@Y&1J+s4!9xIP*3wsB?DJihMt&nnzPz&ub}dQ$gFjhJ zog)AszrDVmcb>e9?ORlzE|*Fp6Ly~t=dwNeUSu%?tbN8c*O&Fdu6}E?0Whn9EWqfG zT6$hD0Z|uS&$=t;D_i^!7tAq#?RCN2s20p4lY3h*jg4f6CE^#zfyHwG;(*?t{KAok zXg!(gLL4;+dUvrDj7l@q=E2h+{C*lPOX#H8+<2rnXV(4bd)RpJISQB-BMQm{6&Q!W z;N}_m=x18%=>b<>dv_tth_itQ)&B}2q#KJ3|gWJ1*CCMd*c zb;FYzm7%cZ{t)lX$W4&!3(WhRO%OcdB3Gu!4arT=aVzX&*xCdQiB6j=UK?+>$BOxO zD%)#kv}%t#pyA2wjYw{9nAkqY-QF;YEX+?yMVvSs| zoMmC0wJeNJp<8he9#0ne5)X%$bVN8DhphP=frn^!Bki#2wxnM;Bsu`GA=U0fA2PO$~_@xG*Uno}!-x zfLIzbIWG{(pj$C8aO;L-5S!<-Cr&)zQI6Ly?Ktu$i2i5&+Swnixv-D@5%T+Y!5|YB zpyv6+7pH3Zh00>HePSF8jU{%?p03c!+7qFCqJ4ur&z&4l%oOREua%zpO34piuUa+v z|FQQz@KqL9-grVnxN7iTG{LB`MvXNU)W{!=3)Udy55)#b`Op=b$tp7Yx(0jlB z1IP!m+qZy?$g~gogUVY|Cw4FRPgfB^dGU{}pQ!4PoVwJwkW;^-T<8_&jo!t@yY7NB z*xc{IgnmSO)>O*Iyt&=m%C{x`bH3zLS|b1H4Egl$j+zhs{jJMi1J`eN^A7o-j|vZc z1WE_7X0F(V$$UDGSd%>yd3zz<)oC9BD|18f`?4n_mgbM@gR}1UVehGLI|5gz#A==+ zkkYGpAcH@E{YncHWlL5=GCI!cyXIAvfh}kxHHPHFJt$-4HDT=}8Oik}$cFE1`gg3+ z{jS&jjv3}V?`HGyuZGixCoO@({*JBNk{TO9{Y|V60UZ7$R_B{1GnuB z>Q8&g0+0hoIOOX((WwR_#c|dfKw2T$%#AeYOgoWFuQJ~JRz@-Z$%PWYZPkbPTvo#C zi+~s8MAeR8ZcBFmg4G6AFr@8Mtl-z5V~mFE@T%`QH5A)5tYi&e%UnZv?Q(vETAoBL zydgr3LqNF+JC^-jORd^{p(EkBAIsswBsU(a;`fjv(cP%P4uSFTG>~hj`pl(TF1BPv zL9*0U)V@{+N%a*5J8BFYtFNeyHmV!W#3OBS>kkl;VGVrj;G-*5KMqn2ptkfR&r)`lWr;dheQ7g@4b5u?ox@$h`qF zQ`0|=CO{kvCs~zP5zJ4?nX`herQY^L&Y1QBrA$D3U^bj9d{Il3QqV)f5oGgHd+O!S z0Qlwv!)NLzXvy`uem?UjuzqU=L2+?z#rO_n4CTyPGS)X7Mqhu$!~a41tL?9fWNN## zrBdxYKV1Td3Q&ukZuHXvS9(o_^!o5T(`>{@uk&CYSMiItB^w;M zRRXcxlHGk3kTbRe(QJ%3J4Gj-FUiOsi3bO|6aim5VPAOFYEUjhf*sf*@($9q0`N`P zvGntR@AH7d1D|-o9BCa3_?o=%VJzE45zh){eMP}mR*Re!h(FcmZaLmELt zm0}81;gp-MkT(*vgV=F-#)$cdf7O?Xd;a|Cke?7NaH|#J@6{YNEX;?# zDN@O=tFi?0F`pFBKQ{sm0yU{FsFD6DB_jsx`Y9zc)K4W`bo6ybloVMbtgB&{u(mff zAc8h-Yu}xGlulLFIwLH7B?_bjZNwOmpjKSGgS)MxYRJEDOTG$-vT(olgm;#W#E3Vl z+-~$sPev1~Cw#EvKT%nlKtz8aFLt}~qM!3lwh?ZcqjKj={2CnqX5siid>V-~TdfCS z8yl0FNBc=AHZ6ivxy_-fufy=v8=H&+W{kK7pN~Cc{$ybUXFpmN&=CajRV5%L3@8u5 zHzbOq4JZQJ${e;}XRSw;^RXN(sOx3hI@r`lYqZk%30>gI)1diE{Bej2cR7+QB$$pf zv#|oXtTs6DZsyC1kEngy8)#XP2$mFY2w6A}Xxq^EXm{ah@0l1p!-z|dK5n>QLK;9r zuL)UaM%^=VGt0q(I5MKXaUBSyt$^pW86Y9q)*D}|PpW|C=p_Vh#qg_TD95O23}usS zQ+A<)x)4((z5;@2-wJ{;B*!3;n%*{PDsky;6XGgbqJ*bH!i7=1RTl9-S$LrbC>j{R>KLJ^nAd4Vfp%nf1)A?kw>S1ehyOCkCs+h})PgXOd>;Lg;%m7WG(aTs7En&T z9$&i`i6jEmy#SQ7c0XR#JMzdKJ@vXg_Tf(7P^_xM8P z8pov9G4VoaY0}N3EX13_pxIXU)ztI(lUU6a27h*}<}xNrUAcn<5)+s}9OjGI>I2Ly zFqwqko4JpfAO1jp$u4*$?P`SthxjRM5o^~aep}cgT(uUqYuRy>LTq1Rf;w2~8wq>}iPBpfFY7O!O7Gghu- zT*)cBkxZ&B3t~ioch+Q28rI;@_ll9iU2$CwY1rE?YEq#ywbbpx7I{h)_kZ81qP-%k z^&;oZs=&49Y_a?b#yiIDDsC1BNYC?XK%s8#dG)gu;1wJ@qxjQ@Gg2WHaS9# z0HmO7P>WB1tl=Gbkw?A-?_af)sI8G8U_S$AvgeQ^3kB{PW@Dj1-PVGq4%FKhKdF}k zQNGCSy~J8 zplHBbZV^_JPoZ{0%^qvvB+&T-cDuH<@Eoxg7LTN|?kugp1+F_(;9YD#&J?UA(W1SY zRR6jYEe~QT$(em{PD}mZ*PjJ^GlCq<4vp4V>EMMZMS8MrfTtn6iBiY`QHR10{S2iT zr{oBHgmLax{U7{oe^n;p)+pl!tfo+uTgvxB4YSsYEe_OFV99h%R)WJ@OE#l;t>=u3 z7)J8^7{8O^&_+YarpTewJUQ*J$`sE?7Y8sc$EpstE(mH)OpR=g4T)M{eLC58%ql{2 zUs{hQ7#fNRcr~r-xAhyOeSRnX>3|@aXnP;phW#&AwcpBKv4dTOwWi!!+BfzH zmYIm~l!CEZx_mvydaLq>QU#Ay<#RP^m`v!e7zr**!avO#Q5nT8#qb<$MEC@F3%@az z@&zZ)c@MY(aMwJK!mjU=pw0J=30YJDM;jwDz zbM&{E_w?-K*+KGC%%Ari^yxo;pzQ(imnrwq6KWJG5^LF&p8jbB19xyZlT)LOfV?sI$it}28q`b`I-`kA$Y#J4MBMm{s-wS=z+o!2719&la} zIPj7r) zww2w`vDDJl4smD17F9e=YL zvE03;*aI{l+0=}Dtn!PkS~xz()*K+7B!7T2Ce{jSn=W(#{zI_Ok0^E4hZ*b_>YJC! z0^^AxfeQ??pZ6oI75ZObxchlrWaQVQJQo>HeM1%*_h6AR5iNK&&7dOEC4t*j7usz{ zX!x?Xt2UkDZdYZiX*Y6-;ci!Dt818|ml)2DmD=?F)(2_NDn) zpdMX%Ui<-?)DjOU{N_(We$Uq?OC01dTcS1zP=ALGRGdO1tifBrA(Gj#HLO>+Vd@M7 zDJ2o`1?q2^=3ArbT}&GmE5i3&kH4kvEo1B(GrxKPWDlGSkD8AdJR@-Qr>Id?W`P2x zRlwk&4#9Pj>vOgI84}2{Gm+k;e)MCcO4!x|=%Ho8>xfT@Xs*X$Q~mtY_0t$!#S^7)==WZR4^-w?Q?LBo0S^yf&V%;V@J?jFM%k~;gUC3lX41mCZ|sp(Z=1c^S==cdXs?#=(l|Q#Li+bD zc_JX(4&#X;y?Zh^kj2?Qe4yqp*!oZ$FD1)P(kLku`~ z?f*hAQkMPpVSlsum&H97_6z}MSn)W7f$qY>ej_T5!oXF{UlDqtj1E$w1oZb=p zPu@xNc*l-?EsSS7+PC06D>=Ru_Y}k}lZg%d8;~hM7V3Hv?UczpfT8aO6myR(^H2|V zm^O1$NoJ4dQ3gu^B%=m>t5j%5dk0b}`=DxLJ5jcv0%Cv+xRWjHG2kzazmXTa`d7yN ze_|=VmR$yLx_b+G?of6j(Ffz7phKSF9o^r^t~v+hpZ-3{(>ZQ1C=US*-#vd8_;LWB zEj}jp8S&u*ILHUFKO}4Tx4ZB&UUL9>9$o(LLRqa#TgIuEKg_XJ&|WhMLIs`vR5Q>y z!`d0Ut%t`Tx#@2wCCl{yFil5~$2`*}`}pdo-%LTfz3&mY83L=Qr^9y9{yI279{LaY zEd0C~r`e*KIuQ6ocLk!7*Jo;<{v{CAerbvCPbxmkgR<8LOYH$zV)tVn^T%iLMQ1q{ zg|B>ea{Y3UIiLo7+Y!X)ghaVu=49dj;RYkp|8nr_)gmLON8+`R%X0de23!!BHa{R8 z0$->16DyMl@$--7k57Kmkw0R6NmB}&7vugev6_&=DN!Be@NpdRhN`}*1KHt6wxtNp zm2bCR+ft(?gm}!Qwt&I?fY~1?B1VK;HebM z7kJ;;o%q63sqfG6CgA=YzJjx%6(V{uT7>EJ+U9S9^qPw(YI7`(XFtZO6R&#=i>Y|v_85%(EgKC!UOcrJVqwRe|@41AY@M1WlS`K2i z`QG_@11dZ;p}AuN$D&tDT;~%IA->TKMF9Xb2A0?Jxjh#O#K;7=Y8EqKAihtm6;wuC{Kr>tW$ALEKi;JtpH1%gwD;g9m^6NbiiRsad-Uay*qe9`mBN9| z-h7Zdep*h&rk5ElHF^c)*h_>Zr`H+=uQ4c((Fh`-u~d&59+-_9z2VS4ii4%---A`5 zH7iJ!Y04yUr~BXS_CJU+MbWc0AykCXrT!*Uu3k@9Y1>v~ zkI&OpE$EB{1{pUY5`~_tW{b7GJP#!e* zd8H)dvAZLmEUau4$vA_Cgm~3n%1eytVQh=GZ;x2xwbNY(Qgf1TXbEaoL@f(gT&4gI zabOkY5(i3hfZ&E|%hoqM{HAr-!4tTT6LtS@bo(Fd|3YdngN54db7I&HPm$WWYBbA5 zp=)$oWJOAN{Xs2-1TqcJ8ZSKQ!kMQ>z4R+0=w#@3(@D2y)9=CmJZbvHdVlDrJoJco zfN3Zg`*uqR3x4%EG-r(Y3jQXVq)Z^3_`d4<|x%c=S>4ys5N z9%$eNvd=I5x~PaTS^67FJF+di^%SYdFI7);gDj0dN2l_q9{=l8`k&r?>%HbXL48ga z*}?W5Ax7G!#^lTreVPHIy0^xPArcpqD~o%WGi;UE-$hPj$IVy4@+I!=Pf?(JA&2dN zjn&Ixj|qqIQjnHYeX|LcdWE5zy|YO!-r#Gl%TeHb1ha{)FLb)_4`x1*)=!2X`%bz& zn;&odkCW!dl=ea}5bd7}QA@^y4Q%4bO94c+!NQ<(K~_aZ*ROx9_Ce zv+3>N!H<^S8p}Pzh8fZ?k^J%o#wfE$$t(GKzy<^QD@C~0uwgE@VNPvI=41bPZ2!B) zU%@Dc{xi}KWV3n&K>_0Ra4f1 z=bgInaMz`}_4MBwo<}|ocpmuKR>$01_p6g5O9ybki>m`+N-$#xHy^0J*b>b!TcSL6 zEU=}L&&xxtqfyw|UevcBjixIRV@AiTj=^}@2i^IYeIg8Qz;rfkPn2^LrbA3et!GHX zD1|#zvEe%r^WuOOT+=>?PY&Kki=b=wsUsoKAzFkIiG3Il6t;MR&(E3fxo5LzBGjuh zVG+EF{iv;B;}mv}a8%r;FN*LUKYZBjYB;;MSpX?Y}d$B)})Fqj-Adi#);A$svisTz2ln00jvHV5aB z8_f-4_pPpBZWcO^X<#--yqJf3qo-)dJrD zKlih6Q}j4M6RV~}4SWzQK>dNWp?rH!f!*cU(!*-Z|3P1i&~L0q)x~_N%#Aj{n2N5e z{5V7;LQXIy>33xsSnu{9lD$#w#nGl%%{Z&wMw09#vk*=VXgon+=BwvX4g-U`t$`<| zU}R>FL&`--so08u1!gdjS5+_nM-k0+JpcxgaCO_(br2)q4ICX&2ZzvKwCylD+f->y zFE^FgxXpo#XINAlx5q{EfrvJV#5cPD`QJhLKk;c%+5%+_KS^Y>M0Z}NPu?(9^(I_- zGy7+mgqw0^JqA%2b-~iPGOxoS+v)tf$s88cZ{R2{M#C-nE zeh`E57~ej3d~xkDq*c1kk0~jn?&*fO;=VZIWUD*)qQwPe5Oh8WnLZ zIVc8mj+*vgfC6(xm$i`+k(zb|yd$M#rKjXUbpcAkNNn#>?Pbsgo@MFfS(cy!GPnuY zdq4)tgL#z$GVXa9IUwVnmyrW9_IVi`kU5G&h&Ui2k>)c1N;vlt1Fj8QM^$x~ODFDv z;NyVfd)4$&Hrlg(O{Wdo8%V6jCPJ5*KF+8uiM;Y>AOYsXEP?@wRhOqrfWRp;1wh^Y ztbyCttzl*|t$Ws^t_RX1J3%ZiP6uIj*X^(Qh}the`!-wt>~+JIK7jldj1+XFz4*0` zf!@&{$}=Z?exLgCN{mk=)-;Z;{Waw=L<;U`J1t%_&R(2Z<=V>wYr1kO7+BNUS!v*; zC0LWn1LRviT^i7(P{l8P|Bgd$G?6k zF)Cg;C6&ZHgy${1MRz4%5}gd9u2aoFYg@ARn(E4M{9$k|<_5__ndoSHxdEBrEH`lf z_8V17J$@8INaDC004@*4*Xb}Y2h8D6p4Guoyf2U1`eUq5?&^fdc}83ZfCNpWrGGEd89b&yn6}?ODg#1>g^JyV`(e=Cn$6?qp=s;c|n^wiEL(fU-o++|1njag;bmWP77|H?FsL^hwvVCJX2!Liy%_m1qI-q z3Hz3uH5;a-`HAZM$KiLC$l`Ay7KG_!S##_aD4ZUGe40H!Ha(xVD6Y2V+Yi1jro3|e z8J{;|Rt$Q4ue{8e&obR7#(?Vf0Q2ff&|6kwSi!UC_RouGr5&d|geAa!w#wU;V+ZkO zjEW&9g7@!!gk&ATS|OQEV!i!9JRc&KUbez!e>k(b`yu=MtZs+yGchN`PgdojdfstP4)^4a@XO-S5L*>xItv7s>w zJE=aJKEZQyDT8(#FM2#zx#O8>|1FWnv9qQ}FqY60X|Fz0Row|Tn9fkgPDq*Q1?mXK z7jbV&;|ogh0nS#cFMoyQ`1F&n$&>ntl)3)^QaxWo`2k{J`Ify>+wy&U9wYsCp8N#< zJ$JFI-~UrrKa3xrRGcDW$PZHqGU8dk7E6zJ?bkjues{U}h4v7*K0rMCh>qv}#~(VR z*=s9f`p&&yGUxc?xqtJwUT(l>@EzQM%IU00B5ezS($BRZVR5ZcQm+JdC1=)J^^r#P z%QYA?SL-vHbda>`ANN7I8lQ8!?}jSFd>(&6qiQ`3IVncFQ4;?}n~MspdQ6o#vilub zv%m;b%MAMv?$21mH}60VZU~o@QFI}(rbfD}vB0oXO!Ig0>N%`<6GDwFr8r!pHY7!`f$m5B$wQntj2PnuW5dc)JS6fg`rT6R{U)$~ud4!^d*J6grdAV=uq# z{rOfzEl4#zNq%H*_a@}APk7f6+^nPD&Bh4CmiDcgn^Y?-U$??5=?e*qvP}@3@KwIW zToTn3pJw}0_d)(LOr&)PV4^>;)I93$9?XX;v)L;Ez6#J&6>AHSgbf#vXy)F6RT=$+i0M0w_t^@mdX!K){ z{lqWl?|gUurgAP)_aceAr1F0ZWpR2wWZDRX4@Ovx!Y@;r9DdRA{}IUszx1g+!8St-rUoX9FRNfr0+nD1o+w?W?%`iK6oBUUx& z8X`dpFI);(t7oRXCUxl^YPqR|XX+vUmqL!))e1cp%04!o#S@4?ofoevx5&yONEyqNJaI$OZhcPhEYvS6>S6-aeB&yMjOUW{^V%m<@|><IieGuRulFtJ%80t7N3ixnHr6q zP5c{~zoWW<*RmnX-E01ogHcN z9AMbgW&)nfp*p7>4?X%Ccp&pw>h^!*Z6E%i0ru;oEfwmoJ7nar!DZUUc33{HgjL7> z2&ndfd*5y@$4;7oL|uvUMqlL@vTQigdPVcbT%6G1FWDNNMF;=-Py^zxB;h&0<5Cza zYz3&#*6Gj>vL-Pr| z*@Ggt;ud>HoR2PYMz5H{dJ5eyePWL1uyn>>)Z!q_pXAlv%^%47Z>cZEkE3cha=t5AcZwopIB z+>By~P-WqApRFJt5gbdyp#0O2p@|rD-(l5awW=P5qG|1eUkl7W5SP_NB^qF6{UluOs!iT$u-1uwIB)65cH z-Vf?jkUT4aJcD{|6hv|T;V>3B8X}VPROTiH)y*{2Z|0ZQdq_90wSLYsulxS6w|Qyr_#1H% zIAsqH15qCEG)*(uZEL)$Ald-et$lFi(%WxQSRY`Y!t(MVIlR~lcD8wU?MA=^Uyg6V zd2%%s!3F$J|z6X6*-vdx=&E*C{E|zt70s~NS<8?4XvHQ)3bJyXGk(S|=*^BQ1ipC4}9>QUZ#Y4&QrFgVI;zf(dNzU47RBXUjQ-_ z!2@r;}@n^9kgNgHi zIT&A;KSLwFy({7Y7;p*Jfw9wpg=q8l39TT~4{nJDH;iIOwnd2Z-=TUbN-ur~=OLbV z1D<4qV=ceZ-DoLJtR9Uw{v=j!CsE)>{qA4Qii^}Tf^#h|H@#=$)?`cy9Xi!5oZ=p0 zjPyn69(et6|Nr}WT0U)bN1?sEkouIHS{ekfYXko`Zt3HfnE)N)|HNY&9ooq7~pKM)9yS6$h`Ah97Ia2 zs)G1*fi+fLs!oG+)N&SHBr6#y-h1z;xZ4dFxlMNl@M`Bijmkt`6kcH&cf)P}fZBok z=NI&rNGEibtl_m{t)(nTNg!9HB#@mv30nMP+`xOjjmGsnROaedgK%*2jj8rDfV!|@ zJD`yJgEw?KPdlBbJ{I^58z#e)h|64QM}uO$g^+Y}bN~ z{d}-7Wp%W3=cdIlu6mTFO~)2)^}ciQC?gSH%{kN>5lueKURi62WLfZx)&;a&vt)Se zXII_@%`Jf!NTy&z=m#J)S!*dQVfDwbo&tpms`$i1ms)E%O(6+uMkK9&2&8hTz*@^` z45_E;)Mt>&TT+5RaD^}&ig1K2!>)l3D9@|r-+%PbcaSX&UOG6I2Ijn0VS)>!4*;y0;xmmV&Dxe%$y}*%6gDiIxavAU$~4Q z@kfK~m!7T<>Jfw2sA+{N^+!)Cev{l*-wde7=M~TR1e~TF-t$w$6?(1peBc3-H@0dD zpJI|Hiywhu)HRjG{+cix7KfCdO3!nHhQ~k+=O9Iz&=zywv2Ew;q=37mphL zkz<_s;p2$+bnm}7ojTrlPYP(V<2~`&jrUaQsT4HmYy~|h=*dR}so3~~_`;B&j`!qE zK)ffuVy`_l-qWKHJk7l@7I@-4vEZQMJ+Yv7SWh(WK)-|L$<*U_vv>T0*H3Rf^$_ji zb)g1WH$FLRQdY7Y{z4E*B0EZPbQK&9TT(ur@L+@jgUYkdFte6A3&7i>T=EyGNV`ka`K97vtF)P6(XluViTgfEp1!o2^Xf{lb&FZ7nnk zSeHj==#x<&h1hT~sPXr(7k{C24%U8Fu%iKITv-K+%o2~t1SeBAuLV}+Oo9Pw_gpk={%)&4Fa zD@MZu_5jAdjpgOBWORY{;fb~NnSF)u%67~rP3vuU7csJzVJ-OCW@zszj#881&OEok z+^1m5BME`3aZ%2&8Qc@AgbOJxN^NH_-*%gNo!0{mwSEBz9H$fu5V$8N+m_F_DLmKQ zVz9N~q?VZ03hIO|KCBhQg!i55z4x6)3in;}M|7-bJ`CKy)Y?x^6c@VykKo=`95|)% zjSImZY!YgJ2G7;CdKJhO6ugPF0MIXb6?Jz>?7mX96>;dfH_4kIreh#ZI?$}{&jxRQ ziURjz-?PL97Qe~daym19)4`dEs{PWtsB={+?Nl2%kyIUoP&2)qt726LbdO>FGQttD zDHB<4r%}3ni>Kcx2qX+a#5oJGk;-DrO4SeE+nR(s*#Yd-R$`|%WexdJISE=ZvBY5u zs8Z$t|B_ncYo8Zi1?lqvlunR63^M8#-fSmpmH15utZZOR7X5TBU^GMLd@ITt!4&9y z>IcJ_pZpIRzR)-iefA6AzkMzPd^jiY@xfQ&g|9Sd#qv}i1ZU;b{Ehw4Iozbj70ZdC zOyG~Yo>qi9o0yV?3&>yVxG0R@1W5x_x1LF_m0{8g_@x&i>ktl_VOwfXCR88)vP0v$ z+1sCSLH)tmx%F}eLZa1oq6aeP!@N6 z?8LL0aSJ+ZI>_!hloUzrBfj|Py5}b^&L7y%e9YV5(jfYWQ-SU;T_e`BznUZVs2I+n z*c`FP+m8Z2#bq3(=-J zU=AN~9vx}ToRa*BuBT}RC>I!O9h!`ml33wWf=cvOf7>=^+s;~Nx3VC$mAU!|PJ!jj z*Du`)bf?VM7ddk}JBtpdxGdms-?CB(s4k~+GlM;x`;oZ%o zrqsnvUGLZ*sp*eHc|MU)ZfU&y-ys3~Df@pkuVvW(lYAQ55-Upan?G(zet%QQ8WLN< zQMazojjbRlSl5Sgkj9agG!DN>wT$wR_jitW^obQcBm**i?f;Z@71h8g5$o zx9(v3mfRd3g2hg}oOWHu)s@o*Uvy2i(@jlGg2E5iQ(s-D+f{A0tKve=RE4oHa+LNW z88t_aJ_8`TU&C-1>Ra`FJU4S%SJ{s`c8L8b4~F9Ee|Gcp*yxwY1G0VIA#Z!oKyJ$R zx!$YA6w{nbNaC1hWak{KGrEZmMQySlTZ^rcL|*Ctep=#@B8MC4?ne0@DP%UvY1cAA zN)h-#Hj6}oI!3hEhl?OxaA->Q3w#sA|8J%RugL26S<5r^#wx1LI3HV($Xg848V;xe z$@mlDpMLfS6WJ`@eQ2}qyew1IPmyYGYQ6o>fxBRq&p*(=Q1ib7UI`b4MguSvt1ePsScXjhHiN&pw6WCftAX3s4SAbZS!{875oT8BG^p*Ltv(%w z%yqRVt{7Y+P8t+$f`+H)DrdgSgpUAt7B0;U&$n>ZyiH2$|H+V&4?zD|x=^`K98dUj zz@~@H+|5Hb^U?Be9Y%JxczJISrRyzzr`a?yVba-(I*5gRHOKS$XC3C zH2PgU?^ZY9kQuK<-U1ebo*Q3G=~Y+(qdac?gq$Pmsg`04M5nrO2|gJcU&S(rwWb=7 z9OX%)3ODUKUGz$LRiVVceSItMlIT%qZ(;}rZYE+1giL&uEQAlx*ChpY! z`*YbS;wo?s6u1Bmp+l6#40{IFv?6^B!!sx!l~KtZzO*Nf*Hpy6qZc$YJ?}-n_X6{t z5^pGHBI6Aezd(^!LWBpzN%LbJ^{JwSkgbe{gdOs?++^1n`t~R%3&6tngtv6~Is)L$uK@;@FyC zl_#4fqKc>*&eC;#(PZPDa4*8{ulgg-xs$J&Di57yjZHS{a=$jIjfnXXvZk5-HbRX& zSrP|+=63%s*E!Ir@vq1FJjfuPt-;|E@6g+X3KzlYCG&uK$}%~FsPbR)m+cu&#A1VR(BQ_mu=FD5k^*zMv^ddRkww|8oiRxnfw)tpBHG&Bo_jG21 z>HLL$fwsH9jR38Zrtza8QeQ@@Jt^F01yZT*?;*Fp?LEQg2k8Hb{e=eg08ZOOMt=Yf zpm6>fMI@rRb*Y;tgIKy?@=|Yol||sGu6E+QxxS-1wzMbta0ey~&Mgtj*-jHZXJ&D% z>L7{y22_QiY(I*_2frcqs=5C|7sTTH0e4zaR;OsWK6K#-Tnefe*6Wv?60Z!xVRz3A@$#U)q{X-dzO1 zbyOcYTBR=rrRFTwusL#=PvSG8915e*4XBJWWih%In_L_u`@?I$#5Ssnba$9~Ky0UBqFzmSS~(%vpihrfjT0MqsqYpcXRpA6Dz& z31Dh7hpDsJK&Q&%;naX?9oqZv@BsQ1fAr$4)=S0tyh|Mg&R`Hd$EqoA+)-1Sjp6Q6 zlM!FWsxOWYX0 z{qACr;vLKHE6r+~*?wP1cH0eLw6Ef{yg4{db`62sM|^o}Qg|Y&?)nyR>@vP+kazG4 zuxtuD92#L=h1%*QuQ=M2Y%DdLn2V+n&@7KF-d~)O7+$pw7_OLH8eS=r;%+sZ-;=pT zav83+uGc5y&P4+~BLWH}XHr4=u`i3_U=G^T6N1bR_6uhReDNf|=v3c*7@f2QNU7jw zlr^~oCzbBMsBM8$gM1V)u;BXGs$j0)ttO%ga(!;Q&Gl5Isko{ObnB6WXg#3X{|?L! z7(j2@KUej=0zer@un0>f%z>hq`c|Ke7s|ZubqIJWJ>d6@7s^z1FH-IKarVl7=Es;z z-=M?*jR3yaDt{c}e1U6ei)sWK3GdwDSMyn*oCE!iJ4 zJl3S56kQtdAzn2DOuW~C%gXin?k@F%9L@O4LFotppA3PdlKi}$k)7%BgeY3$|B#FS zptI$qhCSbdCq=RPuN7cLeT2rDfRmVjcd73TCoAq&_ug-_qGMcm6j=}is}A^B@dUPI z0I%3*ip;_S@8BO3Z?UaO7I)vv#5}-IBD)yb-Lv=l>{m=xRY*O+~8R-%;2f3Fz;G z>G8GDS=<9}y`}1Yg+A_9FXONRC&5R+3pgsIuB5!D38ah`;TF#m;hCFpgO19{oJUT2V?Apen+S-%?wywHcmHX0dl~vb!Lfj$p84{8b zps4{@1ms)}*t^v2V|15)D_!nVpZ+K5a#svSzcF}jzrQ34;ru`(OLJn2O4{!)&B8-{ zskLKNP5zh1ZXLC?y)XCvGp#M&*W9rkIATntXiZHq5xNGCXl&N0sraHy(Eev5>3?SS z%j?a4InCcVzutwdk@NXs-LX+h#4Q7zi}W2_Se$16|RT=UjWbyu399sW^p2K6KL9R z&Ov#se~T&{{Wr6HQa+zvWTv=4+e^_O&}Ql^moi(V6Pa$m_9JTlF+^9j8TKER7>4x$ zG#IO>3#Wg+v(ot;63nspl=$sA94}8k1}xPU@5{HtR5}3o@{0%f-WL0rzAp&+p7wnE zL$=3vyCJ+A{cG{RlAg3Y&3ZA@6q3khUU#_9Cr_EGj(+G4&)feHC{NKI%*RH6<|C*Y zSMj^CD)<6Teps_ZwJ*k$?(c`)VSX>+Wbs`SBFRoLpK)Q-RFW?0{N;Ha2%C}erRn9N z=a^mEyjpbW_C$3ELTHB*>noAXK910>FrQkCVB(^9QM*np#L{ynpi&$ zKY+mky}%-^6rVN8(Dr)jV=|7L|ADdm!YeR}QPGS5M# zSKHJps@-acFFkp8F|%m1`45mFWOA>12M>%yj;a}?9HwMz*ZbiSQ%dCu1i4oMueqg8 zleC@gCalk}ieAh#uzgt(aTqKMT0kpftw2yPn!ToZH)pZhTHl%j?+&Qtj92Fb=qg0L zTxng0MrizqU8lov33t%;5u043E+hn<>KtGT)&3>6>bzv*7d+9j4QH00G{|hM|gPW$lF16|d2}pSzRDmv)MQ02ebw6B* z2P_&ZbL00SmPK)5QVEDSD>12*f3O2_wOj|nh;I4V3ONx$0(i}O22E>|#uXQUQo7W` zn6|K%y$_GS!MZTM3`EnZo*5>Ya|sziypa#MNa3bqGvELi8)jV}!4bB;*!9KQ%?NY} zhf|(i>rzjm8rE^Eu46r3!4qB9r`74G#h5_<4%SdG?Uy!zcTS)~nx1C4^hA4BfJ6Cv zRJqh?@EZ{W660GYs(Qo^&DnbYG~)IG1GmfO?7iXa>Y}LnG)x!dKkNuqm#*qyYH?JR z*{P*q!%fG8O2Opn9%@&+)i;nr2AzRo3=s+*4Rg-ltsX)S%6<3W1rCS#c^hZS3~>UM z5trt@Pcq)6xPkx|48UXgD80+MYo(XX4X#a%vpzWD1!kHZwS+V+~HM=IJw&)m<*AmSw_9R9{e-#W9$Fl;Qd<*AuSTsMZ#}B z(~nfD>1~ZmZ<*JVtO^^Z{jDcE4}ly`U_H6%BWk}E?b`zI(z}cR^a148sQbq)@yR`N zoJsQ%+8lSpHRVn8JIS!GfUhY(nUX6Ao?iO}V zjTk|v3g9bE|ABh19ub>gwCe5f%0}u-IdDhnp2{b2lhpgyJ!HUMOidbwnZ*PkyfV%? zhw&!OW|4$?ENv-MfA~8OShQDR2T+6c3xrm-bRfwbm`Uv&*ktrh*<6H5Wnqa7@Sr0J zxCl=%(+}>VqE$!2D;e(%G(=KDytVGH;uRRVA5EKUA&3(oD+{=q)Kac)vw`C2-yA@6 zHu3c0J&?rqEfaa7lpQJ@+uGV32saD_izaaF zn_wJ1F^CxVXVdlj=fuI~y7I4#zA@8_=wPCKdu$U)N<~`!&Gzy~uzv;j4DOf* z;R|O!>d<_z(*oRr9QOvjO`Yd%ADPcdzwYNH++c!_w`_Qs5+pLa#6d$NMqhVD_X(&j zDR|BF;*L-K%b+p)@80RMqy~y7&sXS|L_gXmZXnN+2jS#UUYizI_Q-Al= zR@~hYURlm*Z2D;HtNM%wLJakL$V0h@JQVz7d)4Jjf#kUeBykw7vc0f~9*$e$APX-l zIpo1qkk=nUUXVEYoJZ9$s}|s+Ejj0*oO2#>CvunCWeV$~9*0fpCXE24)J92X%<8T5`&X2Iz0lEhp@INjoJce?1`$2lx0hhFz%?KjFp7fEz~cIX z85kX0+>0CJkw7xwNhnO>s_c%f$?s+#8Zzc>{h2EU9`uTV6O4U={!tm_nYCT&m#`#a zR;s|`8+as^8JrQXUwJO&bq*Xp?Oe()l(>E@FC5;jvT%OsIHFi-{66pEcSX-~;3Zf^ zWfVPe>UyFT;BZUui+qUY&P>vq=w+_u>w!6I`3B;a=gwB{!4s%v!+&Zk+ZMdi4BINg zl)maXO0#IRsCLN8QvXKx$xd}QZJqU_<6mS!8e-RTJ2<|IucX3%*2Px6K|s{$00TUz z)ZfD>t0TE6Fd*YRv?=vjlufn8f?=JSrb2H ze~4!g-lEa!_cRfAs&CP7+O?ymJX^i1Q<9u?>kv|gLhIAk2o!&KIX=UZKKUiah(l*K zv1nayR1Kq9yGuQ%Ki$qx#q`sO50JiIr#~<0pnZ5@@rq;Q+@o`D!wM9UmAyH0bWSnt z&)yt&Zg5!Ix>{Y1(lo%(i}~<^*l^UIb+cPwx7v6v>k&o%|0yjsMZPS*w>+zDxH?F~ zg0XVDW;x9t%H@wt^RWr9;Y378xo1lYlcpo|tXTO(OG*JvaGi++5cR=)B$%SZYz5BLI5sMh1LOl(+$N!E5P>`*2y2S7UrAlAEWx z4*me|omblMYWyzry}S4(^6m)+6I2^wCmCFym?P!1ZQyo`i-z9|;bZ}aEHiU#tBAsiR)8Ebck z>oe%*f9v7rK;u$NL_Km#%H9uq3IF2p#GBmCRL^)n*#n6!eN_-HIPgvggFV~_jA?kk zItX|V-W&w)xqRb=u&V>cY3}BknL%UtGlNVF) znJQBLXnN6gIyxvP2rX5YjdQE63tbax9SKpoMEjy*j zlo#Tk>?8C{{z<3j#yDgOsA8uaF>5=6%!XIZuEJjZT=T*D!7ur&A1)+?lmuR#w14uYlA`s45?**v{JO#)E-Ufzx?B0}DIjM2c?Ul0fMM^+q+L5q8O%Hp$< z;B;s_E~CS!DJa4gM{=g0*BgRa9XlA{_Rv7wZrfjsa>4mO1P>5BvHN-ddV|TTM!SNrrrWJ4M&#wx{o|u~Xf@9(c-`>Unq1r{cgK;2+0) z18*&#`Qs^XpI5c}>z-%T-&gp`SDJUw&o$RN`eA!dMbL}_b8Nh>#Fb#!wnIVzuC|jc zykuK>yl!){ZFG_sZ;ppmJYF>sE3_WfbswJ*_NQ*M8e?IB($+JoT;c>F;Q}Vq^^U5| zrJKZdnr-pG8{J=fKYa5RJnz!aBY1D;T~)mAz2oOq2bl?LZ`DCOtE(GxvVK1IpaxHj zt%W53572RfLrf%j$#+(HRQ>SXiOy)mTIL^&2X~NZVnG;IRrw%$T*4mfge#a(S8943 z>95Bn>~X=*t4dhN?r{m;RTVg6VAd2MNgvoN>9}{uhx>v~WprGDxua;aw=CfK%e zA)dZtL>a9A+1#Vsj$kPK&^xZQ)H>rzn=#iHMs|4}JC1j4L4@i4?Q;8v(M%JlPla$} zC8DC1w0CAd&F7boAxxg>o>~iIodJr7C{>?;W=tXLO=IK4T6f4@R~5T+4nw6NcmFEr1Fc z2bh5tbuDNBHO|@hL3rM;@$cv1TegI6`A-bEx;qD*;ppM}4%8pMVte?3(*Tzg`5}sI zVG$W%r^tcu0}4x#@GU#Sx9mod&h#Rvg*T8nMS^SjI*Jf*BL21l;u9FZWo!7Box!zk zTXeUR9Z=)GMK`iGJ*tDL?c)Ax%iEYu`W(~om!Q(Y6Sc_y(Nz(MYPexVF`DoVRL{cI zO3zpaRL@OYlT1eb0m+9~)1nBD(hWhl#<~MoC^Y>5a%OZDGyq+o3|4i8M3~ug*?WkW zxtLcXZAJL?_hq+-FMkKJ3EN;cvf|Lk0)0|E5DdI#Xtp+|r-tmiA9ys1Ma#12IvTHkXr1Wc(vl9GJS4^cLUDuW8DyZ+buV)v>-RyS^<_Uq`0;*tC={BA)L#)zv&4pcWnC{28E*nE5*N zX-9t@&|V94n3+0}w-MqLh6Jp#U|d45wODl|#i$@>>iYE*13qZNN;$buGBvY3(V7%- zY)!5FJjp*Ly4NWOt@80O$$qp@wh_7?JzE};R&od6C)Z{-{UB0F! z6mW-8zunV=?)e?m-}2hb{Y81WJ;PV@DEHgyBM=QH{%)W8?R)~)7hhBmuP>Sr%d@JE zHO8uQlf1|`dDV(7I@-{znYg9}cJ2P@+y)W%y(cdYH9E!^dGCX7v?(C(#c(6^zGwN$ zAM=$z?7o}+Snshr(^IK4DSG(o+O5noovyP!RT0mrRLN5 z2}F>>52gy7e$2;KBT2^8P)d%LATRQ~N*^?H$-ifZfHc1Moud!8_mnrJ8L$9IylOjkF{0}Cw6ZNd zm=*rwHht9-yJ;Iucj}#dZ9&~`j9OaRO>u@A{CEOBx;5}*z8tx--%H$gfF-+CTH@!& zLSEU2@{(^)c<@E_=ePIdQ{Q9^h49Kd&>eCFkO-Zb}&?qZ8**21@e{QaY}mks|GOn>F(Uz7CLkq)OGHyN!QTqE?0Dv z12$X)U5fHKwv@=qsVQxkuw&VoZY4~DNWra#b+!^fKF+BvjbXu9cg&t>Om!sy+gn`; ztBWAfz)+sEs06X0oNn>6oP{NxsRL)TsBt*>K0K-oDHy|1Tc9M&MqCFgA<7_TD$Fyu za&?n?AX7E~Q#hT^6e;v#LkOYDT-Y^he$wdmiWu=kd0PyoW0c zc7k2)gS{(Pb8+YoF~zMe$bC9mfLJU@jkaSs(@SQk1znO$6@_6tCATfY?=Hr7Kr}v$ zPc7gEqS-p3j6T+w6D^&oF2Tok5pJhCq$Ck&W1&%RAvbn&2`iAQV-@&z)Q9t93rn>> z;)x3mgIVFn{N%!1c)Q{R<@bKHHR)wPz5W1^&&|gk$6*{=gma$J*x*;% zhLHNzP6A^xZD_bTgHJu+NZA)rRzp*4D>MU8AdCUHmjkCx!D0Cz4gG@Q;)~z;1a%4g zI3WbqfqK!1nN*J~o?Hs)gjyk5PR_6>BA@9;95m>Qsy}w4Hw|U5nxCpI=3G9h##=#1 zRUxCN_lHTeFCYUm9+){lFuafe?H_;0R&kLLDY6&LZr)IyZ>g~ag`RK`GY)IKXFE_s z6${+UCTdThJkHEXEmLV1i^W)J*+!qIF=}jOBfNdPMznHL&J`jrd8n z6#)3Q2-*RfaI(OZf7UMVxl37>x8W(7rE9*=F6qFPeVO5Muk&UX`zeYUh&XdzS;%H3w*H8_%E>afhg_s>;kyms?OJ}U!5DZszdrYFRDKLHAXBHZ;Z^e zg#cy1%sEJ{3W*6bGYU{Y^y4ph^~L;vcz%pe4Oe;GRDmNkYgTW7(uC6miM)e!O&R_I z_UEETYgYSkmJ!~0dXKhw9w@a=X*F^oEUe_!T_7uZ?MKv{J%DkoT)l;$u$|Pvy&Jd! zyN9`axCwd{{vezNHaGH&F0K3fO}D?9?8WB$wHwh@(>1Tl%-R=_o|3>*Bq<4-{RzD3 zE~SM3QW(L6w}c%54}MIzw9I3H3A7Cc;lrPX{sTqoiM!ncIiDYs*?dd+1p4@ui!X3% z!2P5!-3S$MmRE1^{9{VA$64q(Hh7%{giylx4qViMGZxrEl7n2m(Pj`pNpgG{`?^bC z_kmCFEyxBcla{_~pg^qbz<1$CwmB8@)Yi(kTMMz>=9;PW%pJkU5g2?%Ah-f_mV@Fs zx|~`_Cn$Of{8*@w+X)+HU_O)khc^N`?BS(X=SS&Dy=(kFKgqLR!~L%TCja-wzTL6_ zr{vV;a`;K=2#N|9^uROw>=to#3sr&YhwZ&(T~?wdbi?d*y#53MFJbI5Xo|i13~-q& zEaP;zme05`r|@z1c!9djQ>{U|RE==ySltFyZK}Xb%Kw_2MxK*KdVyJMEuUM?){QjN zp0ECNg$q7DpA%5~;t8er?% z$3RxeH*rKKg3}XO&3iUO+TrYI2yyoKjQQYzh8I2I{WG4jYrgN6~nq$pN}T?eG4{MwieD&?PFue~c| zQ=7&fa2FO3AHgSJvSVKt?uxxiA@6_~G9Z5F2eG-gM2-r*$l@AGu-yBj9iT|jBLLLd zErZ}Un{u1*QC{rT=cP{ao9^pZ-D)}Uo`Gs_PmV9Y#lv3hU6JMzp+Yu%ru58ayX5#1 zkX^irXX=EQ+Pg|@WJH^b?gi7K!v&yr`D~}~-s3meyvIon`Gv?ovaJN6x8MB*P%K5w zolBa|B8Dx0r*XCXRq7O3kko5g16<~z5J;5zwd@~=Z)kIGNF$L2yfpYPqZ~Z4!)Kwx zccgW=viU}*!$tjfctzK8fa3N!YpL$@*+>oS^L7A)KA(g9m2cmB#)^0EhvW(Db*1U` zzuOd&);ZSY?c9$pbvoCB&K09`ciNp(n)6q5W#Oad*0=we)Qm#sdHRQQasB~Cd5B%N zf4`+51^l1L)ITa{$Uh(XA8zBft>|MCmnR1F5d~1X^%Q7*8T-ikf_N1o63`FT-$Ayb zP0Dank2@0&MzKGsS^0lH{!3wCQv_=X&w_SSneTo7-CMo+o}vP>mEBBoPOi_w?Q#L3 zXOK^J?k}GrE@Qsd*Z#ljJ^ETnu)Y>++sDfp_b12aik@rF{-JL^3pSiyS2!RMNvZ?*wok+^0*iN+|cUt!p>Kb=x|x7ukpMbi86&Kiq%C1S;#n_F1(%azp*zpUsPjiCu-88}7skY&IdQ0gVRM}4mFiGJqP24>JN`FO#; zo4hQ-`VOx-vG2{1>Ebyexd!3wk(e7>)$B2>vq|+e<7c2P+el_^MCE(y3ew*^u z^B`d{j)BygN8h&reFUw|;@iX@Kg(?{^R}38tD=CXxe~M+y*)PnRv-ce+qdU8;3C&f zToH>#z)D5j(}}Yv-iI53B>4aU49_qCNvz!(;;ZgNA@eN`m?5tPuULcQ!_(E{>$q2v zACI#XQX)orL>^p6_SbA@Zk5Ho(D5D(!3d0c1t6#+*PUrM&rAp_WU%?aMf28qoq%50 zTt0ZWaxIn$lCLAq6ZjaZ3<{FR565?a7qQ+`>j_A2@(onEst05cU$sCw zM59H=)l%kh;7w?%F!@G2&TJ7|FotXH?p=vcSii)GwOkutRl%=eLZuk%YYr_(^{Z|` znnpRgGtxmhLIw!@0F^7Zvy!hzijayTpt~p-(Gn)m7C5ZD zNtxavkC8XxtVn9rP{s*_ZeE~{6HvUHUeG}D489{8MnU~k)rh?!b`;i*8>G5-4+CDY*9(9g56LGIVs z_=JrOw}@b)ZX>!{Y!ecj$2%I<1NdAp9xj3yP|Ke3;UR&=O?=g@Y|=r+UKBD9RO7)A`UwDZYZYGPzS8oX8-T;n#F`xC>cpJan;(i^NqgH_v8TRSyg zUp9jgHBkE{$=4|J#^pm^1Cx4Ch4b7gF9d3tlz>|bSC|Ip%SyTwm= zT8y)(ua7sgQGE%gLv2yJ-AhSri}6v0rfY+mF1MQ=#b=3fl$%j%6)9XK>}?2%X-%|HxAWK8)7 zT~j{Pl2Vk#0`64EXuOr-?Wx==agd{GA5kKz(v0^4?(G6;8Iv0P}yFBs=;i@q7^?LS6cn86UUbk~b zdsnX22?R~WSCVl9h5-%lZ;tML79WPVFZ&rga}PQSjT`1)^c5M?>Le?~tPeqm-mDuWE4TFwnCLaIl3NRS@L{#&4xwFeukJp_D}D6h zb$j%9fcO_kDO=P_;Xd znh-##rR5lJdvOD4MRP%V!OuJX^KP?}-dt|E-XEcKHp1 zDDSO*;ULO$!n5nI?7uwxMeeF`?0tdperCipHp$Y^Q~a(exyKs65gABB z!_e=t@Od^hsZu;-CEo~;_ghC}5@vIyra5Tm!OfwyyhfBev`$P*^vfizb09*&NDAlHY9fYL&j6K}+y$k{!i}&H zLE}O)Q4AE&qH6noJ&#Nun(6$O*)c6cmp4UWob*h_n+jS}_Jef)&a8Fl?}Yk?5Ym64 z{%QDcap9j4yaC=Ti^_z>Sj-uz=U{L4Z8Z#b zFf@F}T=?J*7UVD3T>kR282w(&35Wnok83F44lwG01Mm}kc_M~WxX~;VxlBNRwBpUE zy;$j)4dCX=eyXGhQRAe_ak@fgxSl}0oGpwud({Zz?)E%nP^5K8Xmpcd>*yH!FU z1VTBdpDOA4pw>#2G_s>gY&N)6VjCi`%GQ3Wz>MCLM*HvmTj(k|rL+8Yx z{iv8&AguAvU5d?;7l5zi8(58C)q|x8on@N$BF!+O$)edn{AlVn0a4hi>ccc1k3X(g zZXiN=uX_%eAW!|W950|H{jwe}pfdegGbkVLpbEa@B!MBA8?i15ztllsWWxcChOi_u z9+=u5i0?w`HeR6HYhBCj0(wbXT+`^v*xulRX5*|^C;J&(n!8EVyYj`3AhI}z>4cu zZ>kd*0fv}6?3p*b>MIzk=Dph?SzsMurK~U?6%wPT+ZEb%|Q z1xNS`KA)lB8UBL%GZZ}2U$AILaAykq1#2@DLN-tRKFQ|tqz2JHNf_kXZ z3x2|1P!CmlL2eWU3{`r;5`RHGROtmT@E7dmn9|lF;tIAE>`?%F7qT49BsLl=6M^L} z@|W8XTuwH3y!G`4m%G?sU$ir@UD>V?Y-h=Jqmq_O_1VHTI3hY)U8jx zA#J&>+-kRi(vZ|_h3(xbab$8prfx^I+S3&5_p#d#b1;?A)O7!rr_v zL&3}Z1@~kqC>t;-{pd`CBb6)(#})qSH5};$%l!p494xrOnFLs)Y`$=wGNWRR&&7-u z$1Za`&iNGeV3*E)Uhh2H2N(`S)$0t>XwEb2kD{_M>Kb0nXp;6ZX{_4)hb>OhUM7uG z)0110&EtLuqze;`*X(7De}UA*V~WqkZaauuCs6n*s0>Wmq+hY)VSSA|9@-fS{Kzv- zjHG^*YJL%_n09x-&V^RQdZh|8aqhtj+9DM;&tmKG(d?@5w%x4K?Oc=EEcZ0v(G*|B z58O7dQHQ_hv^l}sCbm+9*rf$evrDAeP^MYR=?PmFb zr`gA)*(`6f$o;?Uy$gJl#q~bEAqhlX+^7jejT#j#3MvX}D5ycmMJ2c~u!~9n>!q)$ zZLwqlD`4!B=<>Qs>)l!l1ud=A(rOWvVz`t=#hSKMW1%*+w4F4xrb=m4>i(bS%zND= zh`oLL`~0Cb`@Zv@IcF~CoH=vm%*;iJ>rq{Hx}R*BO_mv4vKOiTE?GGG-4?#cCd&*S zvd;+FZV5S|0+qTo3RU*)#eTBmNfzrfP0Zkuy;$Azj5IRW7bbYg+A9x9X7G^RDP+6) zB3mv7TZPlmHd$tH$(E}kmu#h%Y`I-qX7G^Bd4(*+lWRqnE5825=wzV&^HGZ;J*kqZ( zC0nD$x@2(_fJ?T?b?LCd&*i*~#iBKX7Ub->eSz+DBHR5*=o)^HZKq%2)zyVjh=rovPE68QMETQ^r%B_*ry? znZZLje;Y-2`+g|T^i#gZrp!Dp<(cYt-JY*LM*>z5Z@#!Y- zu_v9WM|uCnZd2?m()=%*#gs-Ak%sqF$U*;{S0%-|tA zLCES*UdOI-hx~cK`xTok zGq_}LS1sR_+LCPCOZIk~EHik>8dBR;D2ppVeigaMPq~SdIV>=bPzJU|xB#p|Q>Jom z_EKJCQ)UJa_@Mx!BgAfpHgG(?5nm9_{lzKlVt{% z>;r1HOZFiz*#~U0%-|tAR>%hXs_nymvX9tgnZYIdu-f;8Q`@h5$v$k8Wd;w~$wKxS ze{Eg;{HUMoH%OMl0yDT|A5~47EQf{1yksA>$ufh7?0g}cJ^p2(RxGK?Psh_{?CHuHd)(UR7EsdQ* zHtZwo*ODv!75)w@O#RF}ZiQE>CvYFHr7^zirM%Ln%nY6icMIjJ{ZM|=PkEJ1nR#5w zPpaWACDs?G8?WOz!n=&(aD6hD3De64JN7MC)$rl znJSujT*}X=_1|)|#~Lr?XKc#M(1Y^Oz9>K2gEAMygfjEEl%G`-T*}XRDL-pdW`-V= zOZuYxd=JVm*p!*arTn~l8P_SJpE*9P^HP4^rpydIC>Qlb`NusdueT{Pk4yQ-D(q5z zQBww)AA2Ul%+P~!zMrzIy;^!u-ayJ!*UaNmZc(q}iWk(G3T&gd&MkJGnV|>e`F&B| z)PwS7n==o zDOWG;Rb#)@gY3&B3#AQrzN4{UQeV(Csj*-2(tOFHS-sRlP@FsV0WwJ6CIf;sOlX3( zxBXR{+HRNHHWhHG{nSehD=Ok#krfkba4;{p2@5&cBPhxPn-$+M&*ko9gespcdl&Vd z}3?(cwB!oR#mp5Oh4DakX_l^U{wpDb?0L71SbF(rF9Pg!*0z@q5`q{FS~w!f!>iV zSzLXxd&gR-0g1*JED~0E`X*ucNkHyx62II(i7o9|2x2W>|F~K_>L)>dw`%dm{z?38 zmqo&A@V;wN;3olV#3u1(FC_FVW)!|iPm?`H+Am}_oWHNXP`wYeU$}UgXT3-S3f>XO zL`W;rQr6m#+8=^ey#x=rd}zc&4j*&?4EFeNOhsZpCa%Rp79ZG@0h`t~U%-|p$msux z?eTp?F&<1l*a8Pz;9v_JY=MIVg!Eq zIJUmLZWQo$`DPf=co`xuTjeEw0TTnux8v{hhJ2$8->~oIJlS+PW0SGf|9)U))bZ87 zu65$8x&NZ)_7eB7*a8F7%IAV7ZgN7YEr(!6bh(}e%$mk&K$o5dFl=4P1WR@maMy{d z3*va_j3|GzT-E0+&oA2;P`B;q7qB)Y6F+wiV6P~4Az_OyVyyKhF>Zsc&$8^!#JStp zT7|pt87D@{^G-bD9Dm#qj|Y!Q`cI$A+jrZdJ#XKAAF5`xA#NkUsXFu?8(B!j{?#*h za1CZ=t(aq_3s*_ea?*uc&%}vDQ}$xoP`z*DtLjcx`~bGG8cPI?#RVOI3vW#O3a9(` zxT~E0y?yr*G-7Y@^E}FFttWgwQMVnla7NIpu^~NF|O_UD+lk@a`dNu-98D(528QbldC>gNbvxOZ8 zR&7VU)r3E7z|7`7Zcfj^FWHIQ#!c+lJpB=-*K7}&Gc_)FFVHZM^E4Jx*k3cHdhE9w z(h=3#){pz3b;Kq%705ixk|0DY?!6o{Tpesbi=yIzyMvngybEE@peakD{)` zdV}FDB(@;1kcX<4H#e}sJ%z+J7I*6T@rB&%6!NfM3K{ek5&%6gdkXpb9T|ljs0(?x zy6T$Lls%U-%S-HV587 zrz=;7)nOCamHBew15abMJBW@pDj7@Ju(NoWD-UtNaSS-bVYLlub>(sL)jr2z7ryGU zQWc?WQm%%RIKb`-FDt-)BkZ9Sjl(jQsPmH>(;Y7W2TtIE($?iK;kOg5@^}4`qT(z6 zF33MtDdMk`N%>FOfB8?85|*+2FXFV2UdwMEFU;Dxw}QF#CzY3X~@ z0w~#=7FeFsZ11rb3&&A$H)F>{-=*Y8qh`K@kU0Zl~C7L6++&3tykI24hLK)Q2sPad1!}Ai4yX0y7ll%r$$(QtVS68d z*a@Mz(FV*}N8uty=rn6zA5C-NU5_)Z*~9?>*oQykbrAFfO{N3oJ{2byoi8|T(U8a__1Bfe$Hz}!djMM{ zdg}oK`g@>)fIWMFfc_q+Bw)`TAfUeouwA0J9w6W|z8>I43ORPp?y6qY*fW;AU_(Ww zU2>VN#-2eZR@#+hWj_|#a#wNzp2938lMmPhAMdmi*}D#s-(tNCC_B4l4_m>XsZ&a2jICv1M`&96R09? za#-8nu(fu>B7=zEN(a!-$=Lm%i*Ez&asd6D%zY6uve|$o>uss>b8>`$RJ1nWGzZYH zOW?WDoNNO=f9G7OTM)KP&ggi{EEeQ>iU}K9aiG z_a}ba=UL)s^eKL4@t|A3_}%D=-xAooM*fSo4EV*5`yNEEA%lpY;Q;#C>2n06_OJn4 z96&!i-9$jLlMPtZVw3i>6Zbv{JK2D<96&!ieSv_~l{Vm32hh(>*yW(v$p$RhV3YQ< z6Zby|JK2Eq96115y2u2V02{E~0bJz+ zoJYV_9>7vL4uWP|s}JxN0=BwPg~S;lXvkg)3jLkMH<&5UR?H81(EuUay=AQLx{^;$FEzsiZ!lB zy|}Okfmm!r$0F>qmJLOaFu9W&Rz!g<2P(vw1_NRP#KmZLd_s9ZympB;TocG zE%lbm-k>1rC8Jz$%N<2r-a0O`a1GVCu+c#8I$*h$+2x`JvTzw>MAdPG<%EqLDN7^5 zo@uy*7{+LjztomY5T-gHWE-_S6NIS_2)RLRY_U8;HX)`uAnauI%}fxcIw0&jH9r%C zsSXIcL_PF+1|g<8AZ%$B%LHMn1HuMWS7d@P)ds;hi*^jyjml#J8GWqZJ&UCW|cv=AQHn{H?3*ZRp>g^DE9gp+JX-+&&e0M=_!8qo);f$La zkt%P;8WBcky$;@mS;_7&hG?C5r<}N-7k-Wl_u3lLb`o77&XC^a8`1^VcKslXY{^~s z1gtdK2vWXVR_(%S(JI;=7IL6~j|eC&{63V83-a}`&uy@?A~=UxV+b`>AP<5u01WRh zG8c2P2^r*fw2hflH~1<2*glW`(0PyOE*3>ZtqzYx?# z(3d;#)XaRA0(T6tJZPN$c43O8Fi6R@Euf%}O0qnN!d)+DHO^(*QOk6zgA`Y30jZQ2 zX!6uV6c-Nz;+so=yLYU8lzlDA-a8Rob7qzN&>kf}q<0#+6eZ8=ysI-bVD zsmupt!Id#DnO9Eq%1}dlV<-mHsPBHqW~h!EfP23zgUd-#DxS5v6`hK}7hXPsC3fqw z3!8focc3R;{)+29DBTbD@Zx2+)`QgHC>sbBcKjIk^?Ld)lj{ci%2m`?xe#U3ce(b% z8@xN&E!Ht=?n)`v(H*C2bPyZ^yR>|HH?(dq#$Xk8A;R;A({AHob(K(;>wxaP^Oq zGQiBL$5pO*+Q9&j{*nLHeli>%b?j-naPwI#YRl}UQdEN{wOjZS=dP1D=q?>>jN%yg&3ph&N~1zI zw~mJaJcmfN^QRl&C~P;oECgCy&4ENypB+K8GHCIZADtu@m8J_@k!WmXeajn#Jk%t| z%K9vfzbh!ea-RAW)EN3yZ!cstDnQ^H*CvU+%hSAIG7`BkJd~qGd*}Ub8(NV&a(e3` zh&@KXeWk=eudov;x(E@CNM%5B8~TDC>|`|(d8KH5Hcnlw5q%y^7v3qE=}S7?F3UFC zJPI`}KxSUz34DLLL+7# zI*5^nH=)(*dq|IT@@%&A(94C9MjA#g>D;3`E>W&{=jm(cqGVN$9MzqE1Ht6inAIwI zNse9W*k$^v((Ua8q{AARv}BZKo9@JhA_l@^=EA zIrz(nXbx6;H{~#*^g}rI1(v16rvmxZuOW#2pollsrEgsDPN3mr#`9;TM?AM%m@vp5 zK)B!L@N?aguvFSH^kfEns=`+=qZ~Wmc$ZJcJ{@ zHETIj0W>)MI+`jUw=M*X-C$BGlDy8`wR~Pa9Jf-Wa!24V4b@ccC_M3BD!0^m8jGj9 zPJ0k(Wq2C?U4-wu7)$YLW90Ml34lrER^hM4I1x`g`#+T%#uL>;Dt9uTc7Jd;o~Gid z>$V5I81M98^d^~B~jd;>!T!g36Cm#pgop>t4lLzB0yxO(q^YXg@lgeF!zZ%bd&eKEA)1!FW zE*O{M>820w_hM}GVC3`i6@W?QuEbwm##MOIxL4yzm+={jQM!d7z^<9kYFsb;5-gyO@hZ*E*TwZHi51V-tAb_B6X=x|wYc6j?*eD#bUmq>$7L@S-MLpKl_zKo3~Q7Ntkfg)<-j6>4mO+D8x z3<{uAaTpoW@`%ZEZkjwk{RX~E>>7HFcrYiylx{0|r(+HN7!)}N2iMx&+$Z#w`w-;r zhm4)K8kDU*vX=CfmHgjXW>ARw$a-QgSzko1fLO_)^6tcftp-KLlON$165MhU*R*~0 z4Xqj2ieXvuV%lE5^-g)mjq6jv(buUzFPF_tiE;+|oQx6m5Ob@_duD?evBorELe9pH zUcO33cZ-Du#x|L==8!Br_+4|3xn30 z)ju77#DvtWZc%yNv{_eLlImatz1NPRs!HtxLW%xi1*fX z;Z4@B{qFtMbgdwD^EmFgGr}ww?NzKS&Klc5B{n7mp87RVJ!cD>T)#B|=sw{un z{qRGZnyh$Qsbx;8EOJ_@vz$~}*R)cXI;pahX{EM0sj_-$r3Rn2smX$+m0BgK#tNuX zHDejMF{rt5D7bMTt!nih@PgTmX%$^5r#7Wy`No~hRoIOVLT7cJ1&)cP3rB#b%>gjp zUrR4}2ohrs;8QU$;~PL>EaLX*^cC~TVD<3p)lXErmtvyV1|*3(ioj`2J7844k}jM! z@+W~*_Dw5frnsY)ghB62AUSU0jY3sll|30R^<&lJKtm)VN2gnIbY{Jt4AMG3RfA8} z;B&m-!z}RkTD92q1h4dh54XVY-`P8OSQXje6s$7>1@8wI`k5 zeAB80GoEQ@EU`1r`g30ypYUcpt4GG`R9_iC@69;E&N$qm*n3eeX_d{glvcH^aAR5} za}YP_XbLrmryEsEEwQg6AN}cqCNJ^V%ZH~K}$V&|*tP-92YTjBJ+ z1~sZ2gop(M!e9o%QdLES*@AGiI?9W%)S6mLw4v1y9S_4ZoLPlgAi|Aw9G$QdA_LT4 zzpyb~3&0wd^waA32R$XVaa99X;{_Z>0}Wx_8rubxv6M>dyN^<6^0erW0Sg}nmG$+X zp{={ga&;+cNYlo6xM=iK(=;aY>KqV=ePBHq0{g+HLc( zUGH16Y`qK6X||<#mcer^Bp~@N$U7)s-dWcN`Wg>ix&OnG`6mm|r zhrKf`uZgSZF_yvgN;r%-S3(*s_XB+_=U5|Ot352V0y^J;zRClgG58S?20y?y6k_mu zhdQ%0!?7_{!+^TL{GBkFjuQ@nz=N8|7>Nef?i1aXdL(>6MncrcI})x7quN)i88={Z z+XB`>kF+ysnqGF1Uf~pFy45S%@8nk0YB8cdyI{wVzPrJ{Y8tY9bp5gBr4u3tWezSM@v#VaVmQ|PWZ`-Q3sJG%H~q0-`6IZsVf34B43pwjKN_DxTA3oZnpQQE}{UlY7erw&)Pg3>hx7i*2Bvp@o7;@dw zZyQIyP}CazwtGjvE>)5wP9D8c-FLJ- z3f^Fkf)<w`1E9sOU(@kjS-pkzWo>iu88S8`rlUC+;2>!YFGC-K9Hrz{3Xs1?M}sn-q#XZ(;}K&RbGhNwMp?gv{}gDE*xbcvXnpihrBP7Q3wE5 z&NSKu?3-4YCdXbyIqbzR>rMhx118Pe(UCk?#3|?VB8A$Wz789=FblD51KHHH zFvB)z)LCmV{+Qbm*JF31djwm3pvK%Lhp^qQt8B^`-Kfsly&;W>4eja+s8lmF4x9HY zb|X>a*bRkSmbAvPATl-1(XPhPUK3F}tr&E*+PT^Eshve=%jvGlv6@p<4%@LGwzy~q zUQ>p?f$bh^7o8w{Lf{;&bDGh*)Hy$WggOVD$tJ(UYVsT{IOz|CC#k|L!TE{>&`$)% zGRYx0-+l~Ogk@`!iAT{=Shs>Y)v{!@JUPP=Ha*=vRU-!bB5a~?)Kn}TrW=luDOq6| zrYn}mI?OePr?Y^-_6oeUEA2o1&y9;Z_;j!Z4z|F-7C6`f2V3A^3mj~LgDr4iEuiDc z`(N+GlkW!F5Q;#9kFb`q+*~j56!<(@ZAZl5o6EnUW zW?U8`xld=%`JQUzyqjxWUZ3O2|tDOJL z&I#S#S9{yLptfgozlrH*x^MzaV>#ED?gBQ7`py#@c+nTf)?1#M&%*M zuc&eFI#B(3fikP}l2h8vtSiz>7`X*>K(Cvk3K%_cWwPh&Uup?m-zWds`abu#Q^HUGGmgi0x<=2` z8!o6XQkN`n^G4>{j`;a@;KMd>?Aa_5|K13<6`~+|9^g6{vGCRyTbK{Y`mAz993hKt2R+USM27FUp0U<4jV{B^=UXXLdhxHt^i7S-2&+_Tyoni{OQ7i^AYk+Ko3JsCr55NFxB=?L1}(% z{?GPb;#Rk*QQc3{f30W_yZ`v?_TMNE(!Tm{8*=#i&zpe$<7OTVh_xo?}f42W#y5*nlzc#do-G6*``>(-+w6Ff#jvT)J^CqDG_}ZiYh9t5ORP&Or z{|I}d4^b_Sfu{u>^%+&PHQ}4ihz~bt3eN)FUr#y?Dl7M+fVD5EX# zzkWbAlpu)RZfn9v_Ly1To}QHhpC(Q^Q;E~KezXhNQ{~&94^L`L)?_8G8xmNYH4cNy z`@>#Nj>}4vw}Nz{9BWeB!oYfI8VfOntE5Roci#z=QFX{!^v$=MaI)qkYJ#_az;ezR zf!Np~ppRmV!jGZss_%g%0h%+ewkrSIIlA&@|1jF|3Ixk-MKR&9O;qKq=<1u`RFovzNZzPl{X)zU9Vl6p^2NSj4sQTZ#k8D}!6g(}%^5N|vV+*{Sh4;MqWGd_I57?8ef= z8U`6N-$1*+nLb->mD@LhVv(5R@*qQlj1l(7C%qrbaw5@M1jUeV%DcHwCJKz^t-;I9 z*?EcVTMm8kb+k^$1SB?I7>xb3BK}U!yv~T4I9%!x-vVnewCE)iVo4P~CCa4JXFzo$s=uVghMQWO$O3&X8sj5=A}9434F^-Tvm*|%%jZmJ>e~A zuSj}!u{wrhS$SS|Y)`ypNNres@zX$5-i3%oR=yOKH5YVuMqkA0UAi+@Y7eCaAxqCL z&>c&83)Zs9@)68lo+qGEVV#=Sc{Bket2AuqAsSmhvm5+G9^# zBmP1WFZdrh?u+tKotL;IKRGU#3jF+|x5oH+7T;^k@?vvJk(oz9iI_K+M9qq#_{M?B zTY}jefL9gK_FRb1?51UMaC zErI6fyG|@$6irq?JgVAH1p`5e1%gjJVTjayBuMx)6~DEKXx9fvBMW)Vb6{YX4!@b*4R5n5Cz_KcZ>bob1(^yaE5hMOZEgBz7#TH6V8j#w ziu96hGlgdFi`D#$_fNi|KddQ6e0?dKDt2b7nGd?zB6 zOE!2|L+dj4&eFb;fu87x_3db%K&Yt$f6a=CxwOopVRh-xEORl{yo&(%mugnl6DJl= zA*D8|esa!6M0Dhtm1OwEMU5X$Z#bm!!x^EbMtm;|tG7=QNgY#B9J?7GV>u&V!XNG&Ib4W+l#V8FqO=yyd+tDG-X9 zbvMfclNCc528*cr{9Kf|VxnWY7Eob|RXCaKlWJyF*_<;>smf^;Ri{;ynt~6KH3&SJ z6^^J4a_DKk-L4u|XGY$@0ko~Jp%3r{{Sn`tkK<;b6V1!>%^5-SuLw*|MzWG$C)vgQ zD`bB5Zv3{Pfn>!=iSj+xd_2@-;ycXv8e_yxm?inO>NnUPVvWEUFku>_i_nb4#@1hH zyXAUZGmpV{E$u{0p=?1@mgm(MKsg!L0Z&*>$9XGg!pIh4&&NmVEmeh75R>OY2u3tx z-7rycm{O{eXRZV~v(34~QOJI=>nY@rDfLT)Yf-krsmB|Q#9ga?_d6*;V(xHTyg3&} zHym#mJ5b2?YgLN|0bU9>Y72dxrm-MHR-ToftSkzvujAYqx$YCri6NcY$xC3YpFUz^ zI%2k|e_;0_ln|&l+-JVmv?I35tm_h+1C;{XoEJl0m`G8}K>EM2V5R@_r2FG9j$%Wa zb0@|QP2Is~zBb-AJP4x87U$}mHL`AT!18!+*x#a|g73XpZR!&3F{9nvFo8IzSQnL}1i^l(pm? zL6jh@uH1%F$Ed|n!U8irdRB46l(72!8KS=+Jby{vQ6!LO5z-nE&rV)mRHKeViq3c> zvmGB+Pr2EmY8hUv46)a=IrH&FwaaHdTL7wdDW84?v^jCah&5>R&BZmL%A1Q-842jr z*q@SVV%EtFKQRyH zDdzDolJ6!_Fl%C5(3Ff&?8tkTQPM`W6;V$iuQ1;lLXxoy+>(mjLM0M~%P_3oxe-%k z!Dvd^%({ZaxMB-$bx~p}G(WKWImvnHm6K(bl$#vz=pqm1b_tT)LPC!|@l zS`8XgrFn`aRt4YU7Fj=zbu3=9^)EyXdEp1w4ECFSVS@*x?Z&dK`Va8^D>$n7k(wMc0L>k$l zrZMbk>8r3Qb*az6n4F!W)HgQ*CY*eX{atIcqT?d!MsOaKJhe@c(WR-L(1U8I>31l; znY}o#@%^hqP29jHBmItJ(1Ow#iE$&$?0Cx|VU_Zv4YAUm_N0|CZD3e^(@BdY#tltN zD~MVXP8jJjC^$%Zlw*-JC8)!iO|jkq;kCy1r^U*pK$ik(733)1ojv#D^pK_ruPnr_ zk2kRg{}`i;KSvp}_!Bf%@F&-3!%sb2N5g(CEp0Zlagyu#7mc0oYT6W!^$h4Xr7H1! zaYRX%lTM<00UN>OTq>lwPCfnwaJkeZJqucUUsyH$m_!SbkFjI4JwO!=y`5DXrS5)2 z#scc@qdgy>wQsjS%sWb&>wFmvbQwEekR(TzV5i$sKf`T6&ITw|7*kJvd12sm{C76~ zE5&~wuf_iV3*qSRN^Mi){)(TVTQSSc!7Mk26IV7yah0r1;M-S|f?1J2 ztfD|3KWR^({PErJigAY6ycNpATsSe_osaqXx^_syn^AS*uS62`5RJNs3$lg0U!EUt zITRy9qPZ0rIVQB>7Zn>2mz12fJAngk)$&bY%ofvgilH=(UBsIoRVU%dTC*}InqI@) zbHV+nH9MpM$N*aV185N#sfR!%fWvUxi)hE?)8e!z5;1=8wU zo?^EprAfmOb`9#9a>gz?&D3+?HYh^s>j4&GXrmHitrXWo{3;=Cw<27G(Zxk!lwKwUK=~)YWk_z*v2mQ!Jne4*q8g0GTDC-UicaFD=_rPm*VRg8*mt0A5omynW)Zd z7;H|0r@df9N55oFRrZF_6{Vs0`{)~U;izE?OV=XIKajlu#)jlW`k3y}#oh7syMZPU zyULt2A(=D!0zzTkp<+VEY9zz`0B2oj(F#1LDkk7>U`ulsGSq=j&F*CLU-2AP-+30B zWSakmXH2^v#fx+}5tA3iPjX07@JEe=zp9s?QQTLQ}35KYf$_o)_hKSdl3NY z-v>lu;RH2H194EYV6qmLrkbS=ETdG8#pHTmt*XTiNoXr9iZr#{)^*FVoInjSwvlA5 z8lrJoc#?6t4Z^Bm15}(gjYEr$N7BfaG35mdCPmdZFxAJD6?_GC_v(?5AlR#U@dd#^ z;%-(H9~#C|?F|||sW^6osJ$luh60Q(4>pY9RK9wT`99VLzsGTN1B$8V?^Y2k#W<?iac)D>VcU|40rus28kJTawvOxyfJx#0y%sd#Jp`Pz2W>iI`! zE)9exY{VXqpw>#YhGP3+33{Kp3w>)=7GzfjF|jVs&)xv(oFR)bSu+ZN%6WT&(o z9RfMhZgB|GA)^;g2rZ%`Bzxh69>Qdc(sZ0A=7>@aUiL3a7s}P^;+8nZ6{SmYEH7On zbUAVig}5AT_~dA)hTun^0DZg@{}Z$++KXfA+I6?VK!nm7(-x|1i?7e2Qix(K4mE|q z!1UWDoAZ!J&MP!Vk$wIURZTy)*+)Ba@o5@A{XVMdJ)ffL3v_-!6fvQ^?XQsW_bKC# z0Bj_Y8+gzn$axMBL8d7klj zcYhgVG5!s-=07^YtQa!7nHlHwPsp!XG1Q-sUc=8ad-^u=fYPunP#tGTrJIZJE!E6c z!T&LDlBbwqWs;Vm4}A^cFiKx`ilaRXjIF39(yoN7Q;Qm%sM5edMJ;JVobQ1!rIe>t z41wOky3O>pZ-Gz#v##M@xh8YjgZv`W6<>cRCJFH9a^p2b%jCj?nYNZ5z*56rHh+=0 zdkJR}7bDao&+;$!yO{n(G}f>wd6>i&CCBC08hbeF$GMDnrPm12@;nT5{RY_fSy;8=G_CX+;@7P42XwP- zoIQhY@y(d^38gh8VgwrbCr}co4;u48DWV>KS&uu#P!%Uc)L+U-Ry<=zU?#)%Ab03> z4L#=}BK-v)qzZZP@u!-Z&VT=5Z~r!~&uM3`wLXNQLjCq;R71}YZhI#=qo`JG5(AJf zsbRHh4PMNyh-#X-A)UUw#GEwo_6imwN7;bUP}4g6n6EInNUw+5 z{I?)KT087z<37MA#~oXrpSXJkawM8p;xDEQ;z3%CXLT%(XA~ymCo&nFE=vhpPN&e( zmM=S^9)8uWo}LK6ksYjuo(UTJKqjp22NR*JH2v3*8b0GAoG|n80Z-t^iT&7s@EfrF zT9wFCsHq7Rp%s>1Bjs4bB1BX_tlv9Mn0z>_;e^T0C-)0W;POov+zH90;nL3?c%CgFHGZi)ij8U()GHb zY$qGf(9!;GL`C&SO^QWw>=9 zZw(m>XK{KTYTAs}z?wIjG<(wp9OdT>Hg^3QZShuAodX@Khe--qyyY}VBN?%xfiwN` zJWlghBEdfo-}4bpz8C=JH1gh}C?1+6LwK!tNjVdjfqhSa8egwaY(x&YJtcjOJP(oQ z@5=K~d43Gf@y%s;#yEj6(Xjd8ep@(Yf({*4g@BF{lLURf`0mH#b0cLWv^vCnJIOm!j3AR|U@ z5G`ifOimsu#i`|KcXIh0L$JN>!+#NvCk$e z3@Rr;c{Ed-Xr@I!Ab6%`Ivgx3)T|gpxCk3ducePLRw$#X_1V!wl4z`Af&YX8>yo}J zE6;XIe{zQSH|GF<$#eg7t=(9V;*bzelk#-d${$7lYmU5$sH?#y9hU&*HQh z993t+(}SGyiu||zxv6DdP=m354s^9w<^$IBZ8-6xSR}`1O%9%-qNsZDdLc(w-1(q1 zh#sT{1^YxY2|;)zjNy<`Xe1|9#Wpe@8Xr?u8SC({{{|KL8|vy4*k9%p+&Cx;0+S}< zII6^ywnX(#=!ASYGiPKi9#AO(Djy>57{}NKntl$a>aUXHF~w}h+R@_d@$$K@y)*ZP z5`2%ZUk#OydFt8t;dHO^ct~_JV+nC~bW_W7RZy!qMt<#B{5JhORK78c<a$RcX!_2xaY|c#epvnBLcZsXOo!G?xIn>|xXTE%V=|O8&)WD= z3Fvq_fBtXKC|Pxy#P|Nj{=)(t+l&mMTd$wFU}vc5TX@%_msEKTYa3NF3t(y4%M>RW zd7uF`bCX;h9W>#&xLPajXt`F=5N9k{FfS)3{N+D5Y)&^uAuks!q{EP?P8BSobwv3e zW#JIZXdSZRY}utOF_tcvNl#zoNl&Pf(t%2iOAOwLlY`<8wW&21Dl;=W}krWF^?Fc*Q^iqq^LX<-Xn}YheRwClDh*kJm zO2A;#+sYVhy4M$MItV@*jtlr^b|KjGBLM4=4oB@^Q$dMxGT3x)=#nlL zXN*}nF+L9=z~`i6*a+7ZR@*Lg+9$N=3pl!K`qfs)-9JuuT;f@l4d;MY??dR%)!=3I zW$V-bJ+EqePP|2XV*{*ZL$ZHuTu=bpjE>7_ACAk^pKPDf$2cy_UtsqIN2WVgfV|_lgo?ied-&|>#o#VH+m1^( zk{I$U$K~!Hp;O^bq2uxxcvprC*U%t`5n=l+J5Sc$pN2ImNAbu<8F>oPqwgR8D`Y94r}Fff3jr^=p`4 zmfy2sl;tlpCk5eon%whG zZS(>i&1^>Vhea7IosE4(4=5BoVMk4S;-xRR6lL!|&ZhKj@6@U}IF6G7)6#HCt-28}W_MJTRzZhNDxoxTEdg5WSaF5tcb>?- z7Rv>+H z(n;8giAln2Y;nB83Z{>$uiJ5rAfOEtTmgc`u)@L z*}MM$4o(Z|V`bsL0U-P(yT35N*!GH#y}GcZ1nYQDRK^E)4a}6q0`AAh%vel(g}}^(^12 z*KL6Hev;{J&s8s$1#4cD0iChtrFSk^YhEvl(J%AG0y{jpQM_5fj+1n$3Z3}`b$`!b|0?Io+uPxZF6b?s`RM?{+qHZmPcbhS10=NQPhdT5g#2-Y)x-_o=kyK~4`5HvXYXMqinX<;XAe9n zdQZ<+U;%J;;oH+=eMWTnwf5(a+tYJo8JO+gw5P|a*eC3dPYRCy)A1EFR7DZbEkc7M z))VvktFf)lHUR2^!`_9L>w=nOMOGM|Ly?|DHdO3jV<^M_;492iqhwH|_quKqf+{e4 z-g7?0I2-b?C8s|_o;eIBMsywn;lN}66#5j}Mbe!Ygh;zzio7rABKJ#)`yy_u1Dw+A zw~5dm7zR+Qe&DIHf*vUGU7ME;XL?xN-iw;QxIBp6r|ynaceiODo@57KtUo7Lb(=mJ z)&toO-?u$%)|I#>v5r51X8=*=Tr6fhSS%P(vz`#ypw`2F;8URYPK>ChizItn|kw7Uas7FL)27J8tMIQl~XDgzHg)aiG#%m{7* zLd$1F(Qo(%Fky}@QS^iCDEe1rJss}pj$g3W;*#D5bQv-9$M=k(zgKb=bUZ+6ZUp^h zvgz9sLEo7Rdm?siZ}IcE4+Uz|il4vb0oFzgihiA!pzn{A(0Mm-KHPaq=9;`WSia#r zCq}+|rSK2O(v$5;CkEASjH@;3Z>L+#6&uj;R}87}VElI-GyByVeSZXh+w$jd_c9(Y zz^K*enCYdV=HH?J>-QU6sXwuM&VoBc<}s&g*$=D8X;$}y7F~$hYv(|p zUqLF&D#EOHYN_o3#Cuc8jFvgKY$h+Z``%J4HR}DL7V?Il{l`09^pWi6!F=Y>wNMD@ zOpll4f~6n9Oxt~h4e}qtEgPF50ovHAIf0=;Iq-yig{NUS{m9PVe?PV~d;0NdyzIXp zm%i`xqsIxfN*1&&ClEXH8h>ZrrN6T?BX)aN>&~oE32{(Bk%tx?M^{8O4hNWlCC009 z1`BPitmzYw1~0rn)w@Z82is-j>RU$sl`p-?m&ZHl=_}1|mdmrCDMh2_@04aj51)?FpfI<{_-JP#H3)Wvw# zv2`$+5Lq`B`O$Y)tQ3dOez6<0Tfhyidr#ccR%D_4+0xH}= z&$kTLI!5ZTuP}!lO{Yid>Ai*1StGR$r+e*g=CVfW2_TX$k#rW3`gc1|${eSi*f|UZ zcF0_kAA{oUQKb%(L8~OUy~+$F+>Y z!zQ(+ub?LmI1cZGUxM{Kad_u~WndM8>3CF##djZUw=Ku8`inek_vhR4tQW~%$Fm!U zhYo+gU+goPy!GIF1QOmFWC!9s4&SAtP{yLqi!!3{7HNRaV?FG3Q6n?qR0)eU*w@}w zfPGj6xIz3LGDQ5!?dg9-ksn}Qtxxv1KL6CodYQL}52B0fOFGWaS&gr~4P8X}jJ4u)L0GnXHU}ztizcw6B-8O5Y`uhFSoAyMucYW*~F^ilj7u(CMm}=?c zWz@&qvU~s$h0WWniBx7pVbF5Nc8rD!_fMhz`ZIKeCya0am|mnMLs7qjZDmxsqJ`g< zJ!W0{nfeuxzU*m)Wiu@ySlP$iBQi4wHFGZbgr*QNMm zymM_eJls~pFC8ZzsfI6bg;Tpbb(G=%luGvTGx*bT23Y)ej##9N z9qEK3KKqE&yYrmB0ue9Zd9KSZkeuF7#9M~2A&1!wc@j)2Nbpz0$3cHa5~dP2y-9c@ zctx7emMCBGKlbGS>K9+%XK3TmOR#Bntdt)mZUEQJ8?0j+-5^G*a6N+?A9`4thgJPG z?po%;m|f#nb&Z!CD-dLyx!Q#M#Fa$-ti{G$IUWxOS&FqieiZhxVjFYARp$7Kk*J)X z79N>ahrm>}SJz4zKjn#MI9lQvQW!de z1e7+lJg>u$TjLAb0}_fHDo3R16)-|{BywCLk!O!cOlidd&4wL@T(=oYh+)W2OH3|& zV8at}2G#ZqL;e|3X)(;k;UzlS_r;g=)Xok={v~(JmG8otYpweUL;gOX5QdBe-P@2~ zPE(gK`t}(e-|sRgS3bSYhUxsvPe*NXH^aRQtWcoMx(H2QzYWq`<@3D@}z& zUSN5=#2-f^nj90=6Oyx_<1xIT)st}@b3DC)2=g^yHokS{p*ZyS8cFFV1{`Zx1|0Lc z)vY?myBTZixIkRLu$-~r^Xk=Vs zdH0<^JF>+erzhi8(8R%Pc`(Lt+;qnA!TesGw|3W@je+~{PIZQ0W*>nAHdErt4lDTViQ48;&8JJosplY$O$Jaup#UpgV-Tlp5x)9 zR{xc&>T27z9la`t2;dlXL~I? zO-MTxv2wCLIFAqt?PRk*%5@yFgw=|}!57%UmOf9;Jf&ZzKbf=VavAc+cYET!<*@N0 zZsEWY4VI$K!vUja-4IMVN)mNA-MuSZb43J)x~|4Z!L=Er?uH6J$1LYZbHs}+Acgjl z`Q~igBD<$1eO`J_PFOuBp6mjAyFB)Lvm9MzG4lHb|0E-??M4TCSR{VIPTZJ+)0fo~ z1N#NkxA|u!|C|TwFP+Pe9_Ve`mN5nG*1u|bk8f;Zw2y#@QP&bXe($EN*wN}zV!Vuh zCi2g(5UMCphaA@qbY+4{%)j3H*MDC~HTbx=*5rv8R&y8C53NbarPSCGqdH}8F>Wb9 zA#dhI8>#+7(Y)%(_gfHqiJi+iBlkA#Sa^aR&o}Dt07^If9j(1F*e^i6Jm$Umio3rR z6xlZHEJ3o|39ZuS)fYhPx2w2VOI%!r6AX8a+ia6JV>-Co+5s}#EW?=E%iJ7_I%Jts8fJCQq4-loMP0)q%PAN+w^ z!|MBceY{_kCev@#O#kX3J((U^)*(3^Yl9GAOP6r{E;4@emtk>mOV5zMx6L@VMF!Q+ z=l_$sh%K$#Hwb>d5EKuHpLw3Mm!os7j4nrSPO;f|3kWzm)RY9LhmB{z)e$dO-x7^) z84ytq5_n5aBDN>H3$50znstKtmb~v%bMOu;YYWcBhY5@2dYqJ@u0bMMUiTGvohSF= zwn->`Eiq=CKyncl~?0-sMr77{nPj5Rh^R8G`RA7q`AGb@9lB-6A3%#jbq7 zhj3V`ybByKAXUC+_H5&f8&c)nUz)w8{DW&!<-2scveI{7hxEV9o}JI-NbbJ=8b&LL z7Mp@2q;bEY`Riz}muH zZ6U$+Q0uMS{dDe)ybZ+4-B0Jn$!f?=?^X3H_a^o#V-KJjcvbCjiefEUrM>t-t0~ZX%z6yAA z`X#cUit;h%$WPC?ESohC*j%@^|1gzJ@ z?YnEy2#-c1|BOJj)x}7}>>|~ltdOiI(#Q6kP>;j#k)XlTYnY$9WMdwB43p&{ z+M;u#}L-LqN475gdxZw3L*9iQ3cxyZ#G};ID53s95#A5sz+tXG@u+ zzMLExt6ASGq)fflmoS<2{W+MpxBBW@sB~5@wf++lGi&`X*H_PsvZEu@umG=Dji8Z; zOCQJNku9H${{Vjt2Ec^3#Cgo;N$QW+!toOSk)&fb7FMrI0wbG@06G&FT_7R8xhNIK z3??uT|E0hY;A&Y+p9IOKc%`4_*Q6lDK^#k8XCCni9%^5aAV+WvGFJbYqNbM0a(U3~ z?)bf+)E*DIJF0;)IUXnYi`*vTTk$;%7YKjqaX{L4K11Aeb~LPjJ{x4TYmAc|j69b* zm5o|T6km>BAU2;ShKh&^zKA*3(`*{CH=+?W0}+4Oe~+klF?gq+W=mmWjj2i{(xotP zn@BOL@JlRZ;rbKnOQIT!&Jj_mT+Ip-!1|#@{prXTuMjiHGLHsKi3O#8pUy&~u@tE| zDe|9cMWW`6=_%}p*;4*Uw2%S!C!ME!NXtIBjJiy=C%=i!z|h1=qw+@X7=1$Q3_N9xt_wCCkLB;g z^fJi)5m*(1>2qkZVp=%D%a8IB)2F6jJqH4#r>s&u+ZeBp+1xxuPCtoWE1&aMq7d`cLa};K_5>i7BPR;p50;-XW#ZB|HJd_iE1v zOu6QV@I5mp3E`AW$w}IY=11{2{Vbo;&+=NzBMg%$TNf zKY$9XEK`N@J3$SU-zqD8qWZ`CS-ABU3oVR`NK}SlT~^M+pF0{+@ATXWsucj~xn*>1 z%$-2*#@s6P2T7|^&+FfK%YcXDZx6`cxS=~c-qJr&IZ7?X7c9t}0>h*6mfWiN*6y-~ z?DXZMWV_wmQ8LotDn?iVgN^N-=qem>I8xT-gJxUDk1&8Qt}eP0mtKvEt6ZFel!NVB zZ(j|S1?m$7chHL)0GyfRb{=x)R2)T!dp2+%CqT~@&^#?{+7_q~LjXmXi#z%r`zg6Y zG&DAz$hx*{as>+^h6m+>4e%)Z9Mq_79mk_sUb#DGZ^eYHh9Sv2?nGMw^73jz%C^oQ z;-I1d$kG`k_e}W6CxI&k&Rqk%B; zAL*3jKA<(T%fgAu$?EMj8`6o2>*AG@b1;R1637rZZg9j@3+rPzH+`nG_*f!Di*LBa zuG)AYB-Gr=VO5j^gQDWPtjfvB^3Awfbryl>EI1tyNW!cwtd{*9d;?3{fMXOu58;)= zW5qmhU!ZdU9`FmtDZY)}MfV4bb%qDQObfw$jUZ|vXkLPBf&*tW@tOaiN|TeO;ci77 znaoL}2s}$P*qG0%?2V|s^X#h3JB*AwS-t!t%#bdhoSr)ov-8B|Q^62Zv$rNHuS;A$ zSse*-1bQ4m;BGb^I6P5#Q+n3J=_{P_ZaowgtTf_^mo9%amE{SmnSwNf$ET6Ub2<;* zQkH`p(|BqDVJ89>tCA#AISWU>zYP!H-P_P?Z1k5Jrs9NH*+1)??vb2Zrvpv>(Y5L_4-ymK>W>DP zu^sgct6K%O#Ju}H;6*uXd@tA3s-rylYK1s~dM94KtL6$E{sE};n(ctXg=bN>=!H%? zC}RT-0KzIDi5yyL)k+Vr+QZ_PrPuJ2z*Ebk{zwOR)v8-Pz%S@Tf|2Q0N#5a&3yMl& z=gADER!szWvJ!`y$-Lx3c`LFeB_oK6cZ{QbXGz{6W_bzt7H;Ap;Cr;@m69BUqJ!B^ zH7BX#Np~&^^OuNQ%`Tzt# zT=2G*9BzvnZ0sQ?{w<=`#cavBFb~V*l_LuEU`utG8@o^@I9bWc5m0bnlvQb}%g~}% zaj_ln3^Gde#3tsT`8$+;Y5*6_7@5&O)bs}=c=g>_=(}KTePKk!r;xT*ck^w8RT|+C z2jLUQ53{PD%v45-CW|ku3dAm>h}9R^5;mzyBzQar=26T+B)<;(LVE!cTNeU`D5ZKH-D1&7BI$DFFLDii>CMfYW651>Xg z0BKgqH({kKIA&^I=qtB!x+fKlU~v=W<_W@1u@TA;TJ$mvP^;L%P&57I_WoN@=3jiv zD*k3E{v)_y!!ABly@^*T{${KALvdz>r0L=t7v6{BUyl?iK86w$KOz7q{!pv@uh4yImPNDMj7nELL4INyI~6!)Yi!0Kp{Jh{DLDCgl%F&**W?>u_F}DK>ID4H6+}WdGlD z=6UuK0wUVJ{(rB0NHWh{&di)SbLPyMGiPeWnUEH=G9(l%?=?V*mvm8AfET1F&ybWn z>Z*Hypg7gshmSbbP)ah@Fu7>Na~P`e&r{b>F{YSbBETr`-{Zb{N~06mT4I7v_UbMr?cCTTikaE2s$ z0-(P42R1)WPt<&-Cmuawp?#8`dQ<7i7W^G7NG3XaiE5~jMm77f{3cTk$O=>=q3Trg za!MX`)h-lQs~nQo(3U4oHIx!qW(BX=kI)gA4A0gAG9y?+Ws;Z-Mr+IKDJ0YTUIME~ zeH))~k|8DotiHr?602?J{{pl0X~ZPW(uX)h5>^4|7l@OcNg@hnGTbJ$t{}XMdq;Cr zEr%<6o`gKJfJADyhQx6$1bA>q|-ie57t|C)guGpv@skUk3vxa zI9htXgmYqeRU*A)2XgQR9pId=Mbog7V8i&QDA3YS6>&`iB!l<`f6k1!s`&FK{0S%W zGx@WbKg%L6H-FaQleTZriWc;NA<1eN7q^%&gwtcTZ!t$Bi~JhDFQ z#_#FPD)N%t7`hNZNEHbeb}EC>Rqb_ zK+-jlKFmUUk%T_%BG!)&)Q8;+zl}-yuoiqCP9IkE(qQ^9w+2Adhq*KW$Epu|=SsaR zH)#5>$A57IeOMZ*BYoJd$aF+~SoB|%5z?Xjn@Z}e5Bn8TKEFQf+<1GpCF{f9cS?Pj zn}H6X@x$oDCL=HOAi6&66PRZmr9P|?wdwk>_O~$VN23q>DKbJ3itEEllYm@@v}AqQ z)tq;5eV8e!Tm@Ht3&}czD&wR+>_p_!^ie1#eb@r1 z-X*&{R3CO_9E=fQQuJXxht-EInVMjC1NC8!IKYPvqYv}4J}ggap(?9b)vs&AUgh&^ z>eb>TZ5XS?NE=pWA-z~0h3ph6pb*sgGxLZBk4iU22bzQE#`5@?s<@Jgbz`@u>c(17 z2ksL=o#htQn`pwv)nk+XiBZgptH%oQ$s4mI_1I{RlN&Rs9!p0|l0IM`9*s{?XP_E^ zI9YzWtsZv5w{6s#E!AQHfY+OiR6n->YK$bc*kv3in=RF1 zvk;TCpS*xGr0yrrMqFyM<7y1jG=4#~*u{gZ#YRDBNbJoASBri4c5A`(F-A7Q;xmMaf2$yyx3lna%?vK z#+74_A%D`a+|R`^EV{B4B_MbK%G?`DU;w^0IyRMQcvd= zq$r)wO0nWprC2M9@c9?h%X?&3Mf^oh)Yo56pcVu996kps zejejEiCU={`xRo6DB?EGkUCLY5T|R#;uLXAnz7qS6!?OgvB9vEbr{Xq^JHF@K+s=a zOF_^B_#B9!+c-`lNNUEK5tD=Ctr`1osS>`f=W7i7ufqWJV>NKt z8-oG->37oY0bI3!iHN$a7>{tk_}|}nfx+*rFY?AlZZ3SrK(`CXbwh@_w{U-Sn7SWM z{q-yVdk74Zj7P*FQ#DYxsnF(J%h?5toXUI|l^wo0&`l3@%?u5Sp zv@7~(>&t|6Dn@%>hY>e8m*pD#+50-u{MXTOyP~MeiJDC=Wle%OK${;DkdK8!Eq88>cUdODYfggLyGI zNOzR(Uy?z0kZ|t^PCRHfq+H4!UV6}<(KxxZNXg_|KX3(IgbX~3$>$gOkFPI6h9nTm)3^;pO@P<*&SSX=!t;rI zka*SWiq==*vKUbZ9WcuM9MQ+pIDLF3`=P70Vmsd+!(CURq;L8ND5zu`HnQZJfbRC^ z(|y6^bfY%5)PjfTAoj`uPU2U=q>*$@3pJG8Z?rYvjD~>*N~`(0%kBhJ*hq$zBX>)_F@hEmv9TurQHbb8qu9MToBGt;a$xUyT(#0p6}P2GJ-A- z;?~n6N$to8Rg|d})9yF=vnS#*S_V~Lk*NO5Ag}>2bbj}HeQ{uZht~?e0Kc1{qx*=< z!zr}yPFWrt$H4F6_{8PuBdrfQ>;c{X+@HV~+h1dXTEh*)J>p^&j1O;nzgYM}prhaP z92QsH?xS0O*MaSaXVD!|x=38zE6${>Df#S_uU5;~F7x$^^h5IXP`*N$FI3$ft|I$Q z*nA0hZP;lwz2J3+s;wfAF$!-RwqOj)K-jqxS$1(2uUn)gQn7hr#Tz{gNdS<#o0oJh zyOC3$N7=1T+N9+;q}jB3gWpNTz-Nl4>@gZ!LvA3gzqBtIG)a_h5PtK z>Tpiog`4Uqb%suTw%`HIygjD8g8U;A@o#ecR``rT{@3@#YuUo_o8e9d`8Oou>28`@ zSr#kyZN-I~df1S^{Z~xz%8L=xqs6>TF|0F1q=POZAlrJ5yobOR`zC0SzvakXh$Iz! zvF}nX{$`G+jW8k`waDu^lD4;qyibe#9!C-rMdW5JatQ`~u96n06`Oi|*(C2S>RZ?w?2`^*+Tbk?= zDGO`>zn~n-KjDan99kUl;aS<^9ZkJ06y+l%O^tccFS{sU<)>)*Xn{IU~pLYLZkj< z@oP~Vuie4|b3xjZY*!nK+0$6ko+G5}jvgnz3Ev%Vv5VJzv)TjS7V1sC0F7Z7o@`+r zs_u&p7q1;`NA8DZZZKo@rY8r@+l#!v=e(=*yuIp8eKM~DaLM19d|#^Y*-&*4vah<0 z8sgQn_oz3u%j_d5JLKJ@{N2d!;r!$D{N3tJq|8LK2gxs@BfO#skIuNoKIT=Bm4$lK zro**oSJdGZHJraw=EsF}=Pvc9bd>_+Ga@_{k3{d(p7Jc5yA#G*+tk&Y0T1`qK~g8; zfoT`A^y_a-FYga6?Pu}{+fXy1=;t1z* zMVO`@@qb>TbcbngbU2d+(ywNL$!h8etSlxY%R1uy&yV9m#ayT^UTCC9$6+I~xRK|a zc)_QMR1A11wyqEHYq{)W6vxF+iWhf?yZb>oSe!hfmscjL_Guy>F5QdLb7X0XMeGN%VlY-YwHrFiJZ7}4@x^^X^P|0zep-wcne0JAB0+#DBZ4?1{V~so=&}fjN-WT z6-lMvgI_e1?)HdDiPA)CT(>~!+hu8r4ve zB8yWT7k~Ffz2l?2;<+0M?GQCQ;)z6gzS5)C?X30qbH(wpJjHSO-^9yji%(CZ6Ht(a zIq)=*Cs*1JV7rlk9#b3_S{yHABOQa-6ffABfrDRMp?(-KY8|v3766Q_CI$qt$$+1W8;9Is^c10;sFEA`&w$%Zn)kFL!7ggQe)u>R0ePQ8vEWIP4nrb;7Y@ zfY&EGixesERXVMO@IEudwwjzt#PWl^3s>S~)e?bk6zurI6-8a`7$wAnD~iDv#m_H* z!I9J2^?NNgK>UOfF70dQgj@6kVilB7Arqo22uOff0L6Z5EyIcWIJRAj9jnF8L2PX} zKy#KdU%~Ehu)nb4S$0mL=}0Lv5-DJjfKT%*I)sBXd(aR3rmWZ{c`Kz&HrAJ36|Zi9 zanI}_#$7A!D<`_u88>_y+2O?RIhyI#_xZ{IO$>qtA?Sz95FJ*! zymu*HE|1}?uQL<=TY3R3>B1S@&{tR?&TaKIQ~%(zY*Sgvyj1#Gtjwx)Bcoi&&X3PO zUk(*|gH)$sE@qVzf9=jIRvO;NkNL`#h7<8qf}iR5S%9Bw@$(b>+=ZWGr_%pkNtzGK z?FPjWaoRVbzaSKP!=|q5XCQD$uC*R=p|yG_$O*)RiDAELrGfQ0(LC|f$sMuiXmQm? z?Xjp`)ME{a4yhIER}qdOrol&~!`H`1tQ9i=4^%`Cy{Q@Ak}c#7#MXQdQPKp1-{?}O ztudE_EcTFoh{!5zehR-0G&B%0)VX#dFA{f0`s{loweCA#r&b8RTP6;JPsi6wUtBU; z)6Qh7rt;85E&a5vK+*CxIsh=GFZxd>vWT4ns7|}Dn1H=j8==Y!;+G7P7&qD(;Xm;% ztWK(K{yZRTmqge<8DUo;RgHc0y_JT3{Fr?5Ckub+XSnwBpB`C^C#fc&zqvwn6_cj| zT6PlF^r{QT<*5<*10!+=Mvx9a83sj^yT}~+c zJOpF%Ng95I0|iiY+C$;3_y|{-0#Q?|(G$9r)P3rnW_T}zJU;n)|M1pIV`X!@(%X3c z^|s(YFlt`)VBvv4Z0zDwd=KrVi5@#gybjvbI2pS`ige&C6~d^uhV&w$Ai_*75X-Z% zlM}cEER2}8cTStK)6nz@y;^>35^p;^bxD&B%@lGd0X!?X$?UJkE z&a~bDUtMVih+##jBlaluqqF%$$_|}HUhGloCA5LDN2%XBAX$rBoP&i2*1{w*aDzu_ z4aOJT>_Igq%vy|i87i71qy3mud405igmN%Nw_!gOg15hzW6AN5SA2aMCdBemiCjV` zt)-6EjH2SnLmIN+XToggdJyPSUqE4y;fU4@44rjyp5HQgh~Hc}TX|nSkz7kc_uL`9 z^3`BjioJ}%!sN~b1gjxh0P&9fP?DyIlGN?{cZ}K5^e=;0$Bsi|eReypvsWBsC~;JF+crULyLQKvmA7e=1*&;_JKo?{-1qbbPaMV?Tt5NBw= zs=dGMEGpb{n!%8ZCBIkU!D}Wy_eQK(v`>_rmVaNRJ|K*;)x$M8I=Igk zT*?{x!GJ?9D|x3i9JuN1ayOu0J1>1q2jouU>Z@h$ABCHVe_^d(6^i4z2=wj@q z0V}ZFVepqV;eIIwMLAE+R+XI8w^4~RqfjFingY?w;TAV=O$Ay_p@t$=$%lrdj*gxR z$_WSXd|M<17gsTgkMli58wXc0dJCD?488D`0YHJbLeRxNf3{b2ler*NL>ci{!j6VYzdCt%J+gq+Cap(K z3oS`=^H^(@Te2?{%mIG}HJ9uN1+55%!Up<%tDSy7>fqmI{Eh@I_)YuEg@ITaeCmVh zboT9iLasMpE_ik0hi;W2!7Vz*CoC71VW4ZcgYO12#9na<$yj(ym+O)_BEf!e5`vFg zyMsMhJ(}v z5N=LQ>^w0SGMpsaaZI)#q4UITgVnJjUI&#A1qn4_mpK&dLtEFn#rN_gBQcX8hr6N% z^--!&_lN)3?40TFL5BG0{)?vDg3~BRb?(Bz0X#>39(~NVs-3O&NyC-=W+<^*-Ns2Z zMkOcEo)+jxYu={pE@>~>0on1Eja?RGAJZP#Y}6y@;8+4P+JgVaM>v>AofO~tGcf^k zV5Qw*3%-PedV?5)IQY`YlX+qdnAs;FN;X%00Yj3!m#C51Fl#<}7}jw(KY@E_4f+R& z(Zeqxta@Q%ksGcS>+RGaV`-Z5ZSoeX`TLYLfIcv;GqvU_7jVDVQpatGog3`^33tUUmSL^Ue zcI5=dZ;f%1+o%i!asgf9H=52^B?0|6)PW$8JiewyLL4mF;T5MgCWbk9I?`3180u3r zB~+d&lH?`5!Hd&~SeVFJWkRt9w;>Fkasu{%I7YjLMxIL%cS(DikfYv86h@j%N&M=N z8g;sL4tvvrR7B!AIrV?U=NjRI6e8vLUJ@T5m7Kx8v#q*BX;mvF*-jyOaAm3g z3PQ90z(Ctx39h>kDWf^f->XyIST)pI;P7bS90!iEy+tOCU2 zVZLT~o;0ZQi@fTJ{N(3LFpEqs(@AHnELJPA?EB9`yH7^DVE2HtRk#!H z^ECqoS$yd0OJ1}R8Q~#oX?`>dzfeLxXT!OFJ|K5)6lM#Y^3Z^koYb~*v-`AH6YO0- zrfFMg544+-8hIsfSx)t-mHBhraOY(8wGV)r8!bboT+Tr0TL+})MDvj5rs1iHzCk&5 z4#?r)-F+{eRn3TnETw;M7?RNBXsc$4*u);Hb^R6%*LIx%e=C!uj_3dSygS+kU_MFF zlRcdAL+mnS*Y+Yi_LAgRbhv#wm&a}kl*0n-AQ0|25(F*}LIJsuX<$7h3*G|V!g{{k zL#jpox~>K!Y8}M4rmvXTbOEs#CUR8fLIgjzSZHqa|H;uQL9&t7f*?B0blMp1`AxNX_^v+Bx z{1KtEyhAo<%8 z3icukD&pj?)pD&NyMAxkmN@_1`w z3|eLU)C$x45X~4%5PU%>Cq_rhB;O**Axp&SZ}3QAp_>_dl#rE#BbQsEI2l#Je?okl zFSEu*wlE55Of?19xBejIHs9@3!8YttPnQ*_eTOe(&KXQ_yBK7_1AX7w~;g&RR73Nsx+#NQI^slKXfNKLmyN z-=mQfwRm^94))U=KY%j4YF{C}Sw5QdK}0#OL#bmt(xD#SemL?VBN#Ari-<;v(>mra zU_%g#P7TH4TAXF04;23ea0&c0b>|&%{_@N{S(g+`gh8(uqmDNk-hWUdqur1QlBe@- zP$+2iWM75(K; zv&*ysZdEn8^hT0PnR~Hl8YF~C>2&4WQaTOplDHV5-bsm?jM|ltn!-Wik0_XjjTsjt z>9kT71p3a9MM%!$IX^%`UBV~uj;?>94QiOG33QN%+Se2VVhpy`&k!49A@wRqZ{H&M zQ?d=oel+gzC^dp*R-NNYtw>&15aq#+ijoTw?}^DGB)Fy)$&Jp9*MS-f2B~MTLQu~q zfhDOo6>QF6cwnqh)8hj0@6g;p#AI4w*AYMm!H{ih(3aEU0Rdlq8E@rEYkt{1Qx3Y%Qsq=mQw*ZWPidgsBnm|Wpf+MC9&w~nwBY=sY}Nt zLOqqI4vvds%50TO#2%#?rZu77h^hAovv_+cCo6FEc<@Ky%{?SsKm+_I8018c^9l5Y z8TSMoqy!{a2ccH%%aq zErO3*iwO1*7tcAARWtuB!sJcThmtZB@*z&*1nF|Bb3I^A94a8oK`2PWWQvCcpMLZC zT-Zu)vMd3YmPbVAiEqo+;FVqG(pA5fBUxMetZmhI!CkfWZhB=XOb2A8&-$|(uZ=ZEk-CgJDa~n zABIqPH~u8{_G(Ar$C8f+`LHoajmJqx{8;3-&|3mJoaonsE#ge1SlkV-FGRld+TlrH zk0_y^j9~qX=buCjJ4n@qD*154)=Xw0RsJzmw&q_Vq!pD%C9&cz_$4%WwO)b$q9A5b zFa41@QT1>fBap1@AY%u1K)@M7l~$DtU}>qer|2i4k{ldV=l%ZX2GpmHUsP-R}! zB`XfkHmU|bR*+{3m2@QM(3($YD^Lp;cabqRa@K^ygy|Z$*zsF=#InM^pV7dlESISp zQ5bBKNC#%0+IgL+0!Oz83SWb)DdW}52Is|v6DMv8N^&aO3o+6Sq_$!;9A}XL2Sec~S)HrgvzQAY zDN`xDE=TOBQXa>c459f&fv0F982k&>Otr3v`cVPjqqLcz6;CPFPh-v#7oG%C!gyl% zsNb}Qt=UC$lFr+%l3j_Gpe6$779pysx(Ev=cNZr!v*=`|Ql8AXNM3pFDxz15%F{>X zSy=k)((ICb(=o+X-v?&PS9j#}+wu!J{pQh@N=B{IqV)6a^TcmXOi0r67R(p7XgS1p zVf6oHF|hw-aF~A*r6%!DSk0()xlk+QlLC%(b-^+aW;i$*zu~jy({_ZXarn-k@yx+# z#72bN@N0aop0oxL@Jl2M>5(fD39cnSaXj}UE>D)#(5B`=P8tqQLZIOgx|Y-6z&7@% ztX@_*7127le1t&_m@L>k%_kd!d+w2ha;(Ed>l52|gp620q)|<>iU8?!Sgj7j{$nWi zM5N=8dK4(_(=l4Q|{35TZfRlzAS;?ZzAFl{EkIrGJb7besKKmyot>bqS!m0QzyZZ~{x2gN{(c9f0C-8Bm-e%!K$X%b8z{g35I0PRyL?+`S_EYNf z;Q06#ryW9X+Yqhe;}L{Y@lkx&e;pq;;U!qTK_}{M7DEwAnSa9&aR@$Qx259a1AHG2 zA1`y-A^6yUXubOT5KhHM-ko0dh&DO`?z~l>pMOHgU2jj&;~GR9g8!9> zOs2;larwdNv6j;g!T(f5>(%EYoQnT@{^!X3{Vcu+d<=LW`Vjng4~l=NX?q93zx^}X z({>rmlamxMs2}gzV*P=M9-b(Y3>YGYUHycFyO@5};{X)RVe3;^xD0I%KJdT;``?6y z_N9O0h}ts;T3Ql%VI>c_H=S)D=`24JV&B@5Z6)ncgJ-v9PpxQ~nQosQ9fp_DYylGz zJEx`F4Q2Se{vWN?_SPQ^Z@qFvYe&0CYjN6IpJ{y4)Go~JZ<@07?vF!k~IJR}qB!V4@pwp&@eTGjUji%$avQ!l0M(d8EQ18bn zg>s?=wsnJp?@rC>fDI{0;-6x+VAaABhYJTGW7uufE}$)#U$_C9Ffjr1<+Ety%S`9- zwsvC&oJ=u6hI1kYj1d{LWb3*S~r#_dwOYyL+H&*>h{o)YWmX1T! z5Lj*@-bd~!tf5r|AF`^1h_FF3$c=Ey^%xy3B6JsJrH^AmE8&lBz**D{9U`a2NPp}t z<^0#uQl8dQV@iQc`EkD$#;Y|Jn2_S1nieWIhqADBKu>T>u5M#!hB>87a>J-R=%-B2 zA;0A`jg*-QU`kmne>`%q@^dZf3^Q&5Zb9`%*n`ZlphaqyI+b36Nk}{#DU~;$WLZc)hJSKyhGiNKWVo6Ubo+2yKjR9xjX)4 z&qkz?zH>Tu<IIi$Yg|9E|56isK8>PB^#q|uEUjp8rU=q08=2Hj7Eg9x0yo+~bt zliqmJXHN?n|7x-ywWuBHC<33Rb`bcfM*3@MnVQxzgTNmunln;Rz6NLRbl~O*o6Ec% zBCU)~_Q|jY>}W2gGggv*w%pHg`|csWii;*&pI}BqmTPa*F$j+Db4;&=>T*h-vjtXQ zAT<3DNXhn?!`Zg~SB8bbZOd@`>NKc*|fqsNu}SC_Ed5n_?{9&@LQQ2 zN$XhN>Q|w z97;g}vO^KyMbvA#(w4gaABx;amIAN*H{4#Vbhn0txw)F9W(+LgW7J3#yLL z3|ZgL@5IX^P^2oBL~Z|W8LYOPcx?-{+SXCNqpXeXA!-Ddz#L4%`P)Ea=bz zHm`$<^dmUx(A;=~Ov1To9iN!O7sdhyj%&Ck)?gNYOQf6lg-2wn!o9|R$}tp89wl0OvG04PTzyO@*EcLQv`epgex8O zFuIT8GwgicEmojaJ}dSa;z@*XvjK67xTSQ5sssayC^#K)ixw2oOoA!XN_@hv$}SWU z1o0cPklF{&C1Mp4W6CbE0)KhKXPLeKpJQUAn584Hv0+3XI|?*@{KZ&tU$m+SH7r+xBZ%F^z-Pm zR)mmJtM-YP5s8QCF-b@I`ZSOyNRYhyrpJLZ{F4KHe*Y=HmVR01fpo4@?eU7UWNoYL8flNJ7p&Wt4^-8qiP7660k4mqFO6A?%#0 zVTW?OCUdB8<^XeFfZ$W*x{bJ5lRyt;oX&myxz z@aGYKy8)Qv^|qEmSa0>U6AP9|6;{^w z{H=$s=O+wWTVg#YJWy@#G#-6zay=)%n^w_DBSC<7ET3N7NgGx9w0ehYWAtQ$1^DH;$Km7Y7)>ka9q*|sMqiDo- zx0sH)<)XP7A*_IiE9Lg!9+cmO$%iN?d*-f8ESbnM6QAU604t^!OC~z;7GfX=RxQ}S zef}6Y!elc7BQ2WLhw6S>E=gbz?}7V$o-U*i5cdbQ_PE7Os8F{2uLz;#h->0TP|GEj zd%!T<;*J&6c5W^5+>9?^yQG~O(MCF1-fPXK0rM_ z2dyq=QWC1ATV?iGjWx?D+d&oXo6PbX;#VM6Kcx`jakxgFjxM z1>I14Vk3W!K_s37MY!MXyAkb`afk`6mg5dTZSf%{M|AK>ifMvd!Qy;?q8%>qe?p9% zFR9-mT8O>sjlBvLk@PZ(+?*!HAv*>I2{@ZFU^lUv@Plv}InJSP16mbYcF}^vQqs|( zO3r_9F=CTTtYYVnLA6V;k>S_v!;{lGVkQ^7Vu_8M;LsDsr*#}ORfd#4@c~p2rbrab=;Na06`mt>O8`S~m_O#3ZU~lYO75Q9bbyU{)Cc z2497JO+Vd*_V6uwTn`FY_PfQ6fDK|JWqXHNEwh{U(B)x&t;eh~pC4gS71-%R)ivi%ej%-0r5`b$40_c$ddZZ(O zx*h<)0c;_|D0KVf# zGvIgn4ERIp48U9G8tG0zB?;0!j>(@$w;z_Nm=Ne>oc;m%aP+?vKxQ%h8yl73;fk2M z26pms5R&*VBmn;n;!B~YQgrZW>FK*TsZ6G)*A${B#wO8|#3ty8u=zRZX$?Rfo}Mm; zx#1V0C(t#{mv9(Hde~4ELRQwumN{7UT9(6l*Rotvx(<*=SYF0qf=Aus1tlc=!yu2I zg&$Ux_Sk0kkgv{h5XaHXPV@POBe}K){#m>opeh_g*gX8!0_s*0^*`|=*HLaPG=8Ml z2U%WfB_U;srwPs>wZ*p012M7#CuCnqeAO1))QsuED!F3 z=#wby>c@gU{Z$%fOW1rKD;*BUP6w*;n4Xj5JLVmzsid7ui^<{T>fJ9G3?*AyvrD#V zvYz(#PiSs;OZDDBpRHkmZC#^yd?op5dmeuvBgT|+)kS`bhI*-~Td{oM1D-9cxaS1- zUkAbK`n}?rUTQSor)ANR)+!PmTdVh?Hm;fE_rTNC2DlKo9j8FB5U2|DU2a?5#2<|X zPjJP3RPn)d+YLWQ0kRzxv-k$H85eT{2Zt=49~O^p zQ-@pRQOZ`;*TKLm_MeI?k}y+7N4>F^q9arnA$S<{TE3rOb`NeE6Uw!! zKo%wK3Fx%4Ft(>9LH)69T?Jf^?hYKxSX>#dNP}4HvLA{o0MBmKesTtrMHyn?I)|tnpgDQZG zboU&eAW(L%=3hFe88>*ylw0bwe0!j+1I~$_Xd@s_t|Yw`J+^8K{uSBaWp@WaY8X0& z7(DR)xEXl^8-{@7OFy*T;KYb=YofTLjFX|^*J1U+olPseiqnmu(~#bH?Np;u*SLJ| z0>!KKNUiQw=XR^*Rq7=Z3OATKF)pPW7iZ#Wk87$-9~Qo0dOdW>gwRa_Z9{8~pi+12 zG5V72rDH#l{V$>nd)G5)5drHg+%U0x@{%#Wsu;Tcu2(GHLrW=Fbj@Tm$@C#AoLD}g zA=h_1Wf5L6o3iLgc699m&Z#+_<>iLb@(D{%@x7vDJUsymjlO0=VGje0ngEhYgvzUA z(=ZdYNeZVSkKs#onZ5NnY>ZiD(Z)^#CVU27pozA^ROz|PD)3S%O zIQPPTnRBmgUAsG6I|OHZn3{QpUo)+|!%k9j0|&Bg!P5ctFBc;LgB@`Smg8`{(^#4T zwy0bZaCV!?cgPQfdC9w~(!EeME|f{iMw>&Gj;@Ch_ZJ`P)GLIG5?hcsndYX1YWp`=h4^N~qpnF))0FE` z(c%WKarJUR^x3=y#|U%)BydzLD;~OFu65M1z%-;q_Lu( zF4mU-Q2wc)SElxQ)K7OZpqF2OAaE93$_#>TMt_Q7GA_#R`Uro)E8L-rt)WHsklPVn zjbTMwa@d&|eD4xFBo+sD$u5Tn`ak`WIQu?g-*YRIt;Mg$$c^x{d zT2DI7U|cu}y@I6$TM^PG{1~@f;I*pNX`NtH=EJF;IyWb5K4+rKzL-3D3SD`BA& zRw75-pnL{usQ<8G>xTOIb&ogs^#byb-v_PEns>ow$beMIZR#K_K`3iA+iO~!F){Du zIJRuf%aLy_<0}SyeHZt2fG^VqLYD{1^9HpOC^Wrvc#O?WU~EP*#-=1=tXRWX0onuK z$>S49Ylc>+3~esmxcoe}dF}1G2#dv`D7+p*(4iJ>b3%F36(!>3B7?* zxO28B^$!`te9N%Kc(6S@-8eb6_#>9A4cdjtFkh#`r6;~33IX6_gZQA0mL%*3mDA*H zJ8x@F-0!+=-A3I3#Uocs#vd`^0w?6jd^E%0QOdpIk0D?H0+cy$aEJd#!F|i-_)i(E zS{yw#+^kjRAFDy|KRtgz8+_*ILVdMX4GAH!N9p#TG@S07zaT<_tU+6GPt)_^6abc9 za$g{9TI^@g>9HpBe%zw%!t=dqr6n6zOo91t$y5CJVLANb-?&!CYg|u_BY<73T7y_= z33;p<3Y0Uv;_4R44N(O$*jn@wUJx5>>z*s^fLl5o5b4Nz6+0k_thf2JfZ?gLEQOl` z9oSEpLv!J;YvlUG>^hP>v$ z6GWdekH4l?*j8)w8QgbmCTLUv16g?zPEREEY$?cFF^{Nt2Gm$E+~>#LXlKx_)M*fv zKhBTPuEP*4{+(Fc_X%aq*+vd3X{bR&prnzLXe= zf4OAk0AEiq%zLTF-2?Ov+Nur=|6j)+*zq8Aj!7T3Sc8R;5jvk*4I+(rRff zGfkRm0wu!ZtD6R%4(CoLPj}59;j31ZLEE68T?7|m#Jg|=jOO8vwtq-zMV@WV75Mg* zq0Q8|;urX$?J;qe@Pl*5xb{9A-!XAsGxMF84$=JUhJ5fu()uzX5w zje-M`1l0opxxPkfvPaGjarG`DZv7NRb-9tn4h>O`Tb#oCZcD5J&!5uUNlgCW4!&Xl zAY1seP?kK>v#&2lbcB{bICV&{AX;-IlNJm4JKSK#(PL-ErLl(b=q~r;O-Dz}w%!RH z9rgBQeASOc(Dw*qwhL~)=q$ERti=@{)Xv>J9nSCWEz)R{Pk_6g0))z z)PE-T?@O7gUr8YG^^jhyT#i=}`iU$87Z}urX+XJh1@jEp1YR~q=NZM~qIh_`sEUUt zh{-an^Ncc4hzKx)kZUq{LXoeR2*6$|{w^SfDUhm*BvS}nmuK*okkub_(Ab^IIR>_m z;`$5={vWi` z-YuRdVgYeD#1eSjW6CH1WhkuBmXtvv8d1g^YE24dTqCR2=sGl?COc6oo^7bD*VI6k z&@A%Lof~iOWE4t}d>7qJhug?9x9Kj!c_NhbhCtR@1zY?Hk&Iyz{i%0r6@M8$kU{-K1De>~Glq4n84B z2@P9g;xlkQcm=*d22U-cSX`(Ke;iw$ zSFN{F9yorxC>*9xvYUPX=*B09UWdpmWoSz?hvL~!)3PT$q2nK}Wgn_!YT5C|4%f@_ z2RrJPj-;id?qP8s)o|3UIg(bnGbD9QLB+M_>}a`@n{`FLp?QbDA^a$RrMzEoCv{m3 z5;kz!6DBm6-f-9AASzoev#`eqYn1L$%DoiaQrVg((Ik^?bF2J9kSPMoqwj*3>{ma* zh=v|zbUww82U%7AQu!pd9fUQ})XXi@&W=%rF`QvQ`cRpE z^!Ev8E`n#jXaC-Sh;4U6AFiFugGcs-HzG>CsL7&EYqEys_F}V+4Bco)$(F!I*tMWKTQi+u2V!R14ZlTT zq3uWCa$A0FC~044`{8Ca64+%@|Bm3s!mUuB*}U&9w0&nYe!2qfMVfszQr)5qt|j-QhBK z>9dO;L_3~YXj`(~f<_`*=--qNA1k7Gbnf)9IYd4Ed)V3p2!(SkQa@8}F&P6JhnTj9 zr#ogSJupfnt6vx;sW=|TzKD*;kM|W|B;Z?5=@+MLP1!kA^t)?9vvS4j40VFshZg%8%&PTetWbO2ESmfne<)d+)cZFXta<5qX}} z^5CnXpCYCMo|l@7h;3zc7iXwhfP z{C={E^Z62!<$L{@EOVji%867uSU<4Bk)~Xx&dLGC@v2!(y%~p;~oAv zdYZR%1I__z{Mh&T+Gx-Zc(vIm3SQuKM%zfUT&pFa7TQsJ#G2u>2$D`cbq5Lsw*wjA z2IW7fT0H`n`syZuU)I3DF|HcNHE8nWk5dInKOS)g9Dxu{SGZwg=|2@V$YVXibUuv* zBYHSyCG4~Bn?*6?t>*d9V`KOy&gNeVIg!wNO@xyPo5| zYPkTIs4qNwTG&;F2U+Rf^hmxxYGtKi2&qtwMV#Ha$VLL%d9=(lOjBKD;f7)l3}MfO ztq!vtTgwon1%$!YyqE+!k>=0$`Aw*KXRR2AYDp;s#W~m`ZjIvwrrBj(eYA!+dnP)2 z7nj1`DbNlxQR1Ub9lKCpEes-SNWQ~6p%$7nv@N6;LuGx20?hP?%YhOG^+IT`9K83zi+AW$^8<*E7-;>&+d(+9 zp(7L6W2zbarVxymM5v0M73wUr8;rxE!vF|5aHzs-ExfXP6BXhH2P#AvmzkJP2BJrE zv|Wn^1Up)8%;Z*X*SL53IMXa~V_IhbN?&1(P)3vkD-H0?Q6 zRH1e2Wh4bwI>-_XA;Z!ilga!)nzehYxqF>R?Y0MbX#5yhFHu`Kg8(qbe*n%&0cA1P&UDHe*z~Mw!@zN2# z=5$G?D`h>=%OLyU9PLb^S-Ql7OJvpk5my7M zrv>-#kJv+6kDvgAo-$mYu}Fl)t~A1nxA*K3kQ0xRgZba+mPEWFcZeG)<#_U zG`!kl$SgX}&WGqY+P9lU$6C?#Ofu6ZZr4t-QK;*4Ot(b`8eO&hmY?>Ky<;f)~FAc|-v!Svt(50m^DD>mf(j|IYEu^IiNK4}& zE%|AdL%}W)0Z@bwv3C>o8d@)2(4^25&q2$US6l+a0c|a}&XY&ioOzxGLl!;asC{{f z7=PNe(f*d!f2_e7L}<9C4Kf=}mb21}Q$*T1Nb*aGmwdC54q;Q`nLgCYvVrksgeS1{ z>Zb@(EYg_iW+qXsd|gQ1)I7RAqW#hzU|@Y48Cxm^kyV>0fPaxyPsT&-@epMr{w)jO zK54D&U1Zqwu^n`w4pacz8#O_Cme@_R#9=V*6(=4wd3_><7EsCsP8^vkWr5~ zuz?b+D(8)?qH1VKrltCLGtjS(Nz5i~N~$DG?rZP?)vN(v}q6h5>0*M_c3v745F={QaTHrs-~z(>7N z12}6h0ki<1|Bv-m9&t_#Gk_=d8bTxHHeM?Nu=Eh@g5xjST{bmD%jD`13Mu0Dlo{s=7j)q;?^|)=(O8K#WS+xsr=$~wE zIzqC!>B{o9EPvi+yD12{O`)e@&rsdz~j9*;k<5Ugoc@xP8kTSuo#pj@M{bTB^N-8*jAC}QI>9Df_qne zX8%av#c3eAonB#Mu1K~e^o%4ZdpA6Kd-48*yk`MgU~?MWvbd2-;FiTdnAgh^Fq~uV zw!&gkys@QrJO@J+?|+OanJV_LF0Hiti)cMS8dlm(1m!L0C9KqR&G1fy7$)7F1FgbF zu-Xb{gy*X&?IELXU`L)6zFeXJJ_F0GX3|J|)G_Nf<3`Am%=wUaQIEG)ynX<)kFTM( z(;hCc(Oeo?To{=0Jn|X*r>L=sD=f+g+yPu_PSRPz(rePhs0AhQ_ zXUcHN6iee>Z3%Q+R3ip`(M&H{-;g(!8nK7&4KaVRHE#wYSszG@>Op+K5(kPU%1F)y zMiGPGPRweD|6+9(`676Uzm}C~yJL?S@+5eG1{`x8rXDmpLgiZMT7&XSO?Bj}qUC9) zN4(13DRrYH(k?#G2YeBH+-OD(R(P>WJd=ro4=}WPK&58GVUtuRY0SeTR;PeV#=^0O zdA@)OGn69W5y!jV3|tHSb3q%e*?Q;dwt@ge6!Vdtjc4zF!m zM@^`%E#!Pev&gJ_gjNUVlcBloP$oWvg+yDtq}J&)$p0sMM7WUJ&LY}zF{M4GJn0cd zles_O$en6k8|b5?zL@5(Qbq!Kcc>x{x{**tzUtf^s=&p65vssd(4Cjkv(ad; zF3&$gSEg*iZv4h}SbZ6SJt_3@FS2TLJoJ1#v{eg*XBb=4rqZiEI2kK^sbmYzac=Dh zo9B1}9a*N1(5fc^SaVq=<=Zwy@ZR+bR?>LHnY`Q+BC&D}SC9j~**q6-qh&RXSL*YMz1-x}shuna2b%Z$hFK4VGD3?ax zBh+IElBH}3uJ>4GlbaAKU{Y4d{>B(;z1g>RIL_VHQT5`=8mgIhBBOje0S}^gH``Y0 z;NYK~QQVG(`5gn=)b$&P*RidTK~WL?>s-}NA*?sD8FI@)%`hu9xE9RGEctWww|$$c z*Cc<-5U&0QDb=&tVmWGwtZI)_3&Eq^g~}KS^rib@WC!tn1WD=3?U2n6Vl>vOYp4j` zuLlRQ1)_+G7qA6?iSl}baHL9`5pGf;Te47-Y|ZqXB8mLhQ@C-#8Z6qrZXlq3w?|z42w}zAH3JoLze8nyOD@roXA7pIg+50%Bd|yo z*Y>2*A=+uCime6VqqX^LY9#DL%#*Y5hDUh}TV%vXclkDJ4fyw;WdpWg_+%$Ln=|CV zuBWWHMY6PsjePQqXOO)% zw2CIaRtW3{?~?g1FT^^$VxB7jjixu&@DhTw;!J|#?Zky%1`=9D45L#gHmf8y+Uj-D zQ(V5SSrU^cYaO8rqP`ooNUIhZ1-1CxTIBwRWtU&2$XqS*EiICEe{lk7BxUM$4_%?< zmj~z`8F`x->1!tR!3)lVTCr9Xt0m?wDeI-*wZ}TmW8nmX+wFw|b1IPM5&yyk6yHM{ z@_&HR#02=p*@P}9HRv*=VP?+J0G~~9<0(I8{}dUi4L8r1;YgP#A<0KFrA#;h88C&Q z%Zkqk3r(RRw%{(rHSr+JS<{K{XofuBlCvk`q;eoks1t8OKoUqgkw?AJ)R~~qHy@1C zXY(vjFwG?Lg%8oRrAHX=t3sCg|eci*&kBzTEtd>Z7-WpuQ{SEj|x)?&`qCRNT_ z0tV-}wq}K9{sh3Io{rP)DCS1C|!O}urZMhc(JcIGLW z>c(tmfj_+s>zbIQ;xWFOuOl|SbR|d$;VV6E+13I$SUd^SUZ*?4joZGzW&$LRLIBT zC0#!5$mK~+GgOn0sSZsRr6B!-e9S0BaDaR~h8H5e^D-M&NUb#{ z;jE;ZQ|065A4tX}j`wv)@;IWAl%mc39Um9QE4FkZY|GG2?cmp7G}v@sob6Wwj!If znj9SGTizp_7s(!w+$DQpIUJ^()$tyT^6dt2U@AAI1942{4wIPr^f%nUF1n{F>!D>^ z)&qf%E((J(@1hZ@C0Uk7B%P0ZhqH;lsLPDvD|MKO92m2Bjar%*|bXORk_= zFO3(Bo`g6z0ZWR@f&uyDPQ#^uQ4&KKW_^~j)*&rb(CS&rr&gl#Fgmsc9bkSy$ZY?p z*~-{(m9g}>CFz}pQ=-H9xhb3rany(ChuR^-?<~MRun;=cW7hQ^4Sis|K1*MYD}C}f ztkV6Lf|h#>Pv3XPJ%->m+q4&Jd_}`Ct?eH147!I^GvslTX~GdIMtx1)xxjWp1y8`k z!QJ3wxQ)GPJdG{>i3{w+VEFjA0&#et9XZt73Mjn!sx1O5YHe_vH*~9@c+W*oQw$mv z+_qwN5HIApuR@7eF zVY}&fXhPv;T4fB;%#t1O(s%d9wwJ5FW8dG^@o@&dGC0<>A;bW#YNwhDwKj#qJ=C5s zwW=hxufym+NnMo(IH6!4q9Vaw{3fvBTPXy0hTHaar1^98Oymb8!cI{*6Th-vvL(zl z!Nb6`4!6u%sID1m?u$3ZZ+76gZ4`JTDYg9;{se%kZwxmi{)C>5k~3D zOTu{LunJoKr;DCNrU3tagh%&@TK)*Yw&vULyVaSE>rjhZn$Ir=fJzDX`Ue5@ zcuhyp+I$|t#;q;$XsI)QH{f5wFT@`jorVZ5b3+9$T6A=;>~AA^=D z-%xLQ9)F=<9I5VscVBt`G^3JE9tuBHUrW%1dJ_$V9Q;o)`0!c@Z=L4jOaO^veDZ>-lSE>Kzf>s$_=+DILB5g<3Y=7DqDaT#G@Uck*|9Ivjv>a~L7X(v z2{P?xVj~^k0XRbnwm(i(WOF`?ryw!q2OU|!tLvK3-X7CZxqehjj{`tz zE3s4Bx!j1(!O4qlU1h&!(okh<#zcTU(6TC9uouZC+dy1n)C{=QR~wmA#3nZ1N*vXn zKDG3v#UGZw1m7tK%9e~x$`g_~RIapK){SJhRlR{gly0=Swg;Y~l>&!r?@;q@rH`&1 z2y%rd5U`oD!nH@JPs?(+`esJgKmfnr=yx$xhnhk9%tPRfq4tl01^OV(o_G=<*jy*6 zjI{gB{xX1y`SHXMz|iVLX!twO@ONcQAf|(%1eKBPk~p7uQXB@xYHFa`;&vX&eWphpS$T&cPtEmpr$) z0?pB#Xue6D`!?z^=3*8OUJv!$^N$hgliU-OiV3=Io9T;h}L^ znL){DTvlZ8XEY6KM4f1E*P9rPzW@ma&<>*q_RRiF3?mH;#;r<@h%M-&VXKChZk)(E zH{&uzwS5q2W+zJN(o8tWUo2-qD*$(GNObG&+HepP3X>yXT>`PK*+6Z=0r(olqL(L?n5mUG zmrM97DfdkAbW-jTEjLVNhs#Xnz$}YV>i}Xu0R@qOh*;bjvKahE7f^MfEjS0=NwTz< zd!nS7WOnv-_;X?a{GV*UV5gK3u6T`1&njldol*8TVbb(qLP6eg(gRe}4bT^0wrzZw z`N71BT;-%d%%}`SbgNL|t~DS^hqjx-5>B(?D7H>$ zAJi9#HA{YjC#0dNjU-Ve(x~gQKR7AGX_j5xiNb|N*KM4Gnl8i7 z5Akz7ep>N!JAQtRpU*?0Xg}nu6nh^$WsTRQaG0l=M8WzH7udyH5VkbM@bPrn&<_(Y zGJ^X5*n1oJsH!`Ce8LQ5(9sz+K-8$w#)<|tZK4K)ZIDb7ZGsa+W~hMD7VVT`OJxS5 z5{#WBWV{U0mbKXOSK4J;w#)91t}H}l;{YiWEmd^cHdbn5i|t86+qBJMu&MKZzR$UL zUPAC~ySuiZ4j-P}d+xdC?S9YO_wD%A4O98OFs2+bRqjq+0^MGj=;C6`l4tqXyvmhET6kE;8*`V#VXrR#$C6vJn+Nf zGjp@<=cVtn^|f5OX|xIE4K`%)#Ho_8D8h%QF=Nx>^24dDe|++0(fKvD$Nhn)ZKt$i z^(xw+?eV7yc>~QWPka1{O5XH}r>CIpMJ&PUoyi}Wp0q+$41!N-bsitwUvXl{5yZJQvP;|b ze+X{WUO`3G-=`z2zZs>u1^+*Z|99elGyX^Le;ximg8$v-|FPfr-P}w4>s?*K7kiR? zv1df%4TU#ZV?OmAGQ!cntuB_8Jl@BOkUlb``1ep-G`0KF=i$is;EL8-U2^REiw3IC z&D_s{@mLz4IlBle&l4$>-^~!OJ?53Otb8EQCKdu=vE2jj9C4pBO z)$qFXR2Qp0&7O!xI)8vAVx$?lLMpM}mXq{4Z>H9Kd|x~XV)pRnC0NVh0`5Wo5y3bz z2(w=zB4w5Be4ruucsd=Z5-$Cj?n++b`(hI@*4uu#Zq^^@PA{Y=^Na+Jju zE==x}MMQ8jTgN6Q#q~| za}Z9!v0{W@)#-r!Xr^Ni&x&>DGo8n*SfLAi>d9kIBU=%!xZ5I3q}6(CB_h0pW7TEY zs=bOUqk29{aE4J^h_84`ta>5NrV*8PqeHqf9_1Oe1$cB?tm7~OQcsWSr&EnuIK~LM zV;w{CbZHLXhOt+_evY^E^xGneOufB1_0&vzOXgFK25}6cR@$;t#NNb8TgDJwGBfS% z8E;qD;?XH-lNqB!zRTD!`DSCns%MN103RtkrGqEFWgVoMmE*`b@x%&XYz!n(!@J2Xz%;c>zaj1x9IPT1%; zVUFicEML($VKc@Fs~jgRG)~y6al+P)6SjGrFfqp(+kRT%H=C}sl0$abCg}WSzZ>bE zKN}x2RvD4{RHY{95^!&pczp!EntCNq*8 zWBGEVdj{ULEeI9JU>jV0hod#QQ+Dd6B4Tn%zVIBY7iX8m=#XU!!p=I@QI4yetfC{Q zOncQ7xBKLS>EE8b>lWbr?uz1cQ8>fYA5M6)^0}-jJ}XVc$MJ~RMs!!Aqhq2MeQB(~ zBO{_+8 z(Lvc0u5>N!(B2#YvpRgGkp%zXH8Yv;JosqQv-K#F<7uT}1pGv2E>+X7JHj`{I^-A| znR?X6f5Bp+6qf}ZnB-CN3v?+Ku;{^lU9?j&19g(vu$f6tgwvRgdL+5j<=fv;hl`17 z>mBhV4$Pfcf<$p(Zbt(`VHOOb3RdrINq+Uf?UHOE8s`Qh z7wnq6y>jn}b}UAW$cQUE(+B6r@rk~m6y9n`_+r5Lbd6Tbl03}{$Q6|2bcw7u!R2^! z>F+J~+y~lN5i`;P?wr}YS;YJoaD)E#4&?3BpAfOBvCp_>kIL_yWbE6cJe}1!^4Hl} zJpm7%b#L2~FAwKB%sWr#t#(8+_PV$AIXmZ0+%t%%lREvmk=%FS+Jdbo>sMx+3u8z> z#0lc?oo4Oahi#F47<7VWMdW)>^ohYDI@{F{tAQ8h*XaTa+mDm(COJM~|AEMF-btzf zah`_}$n?iIbGa*YnoqSqZ$1nE2J+Ci_^wDVa+HqrU}5F7Tryd5e<4b*YQ)KG0m~wz z8iV7gfxX3$F~82}@L)uW#7~1T13qiK!$ONQyDJeGzB0qrPDd?5upI%#*9O<;OB*ys z8BKloi);zZue^ubX)?lFMgqy5@)n8`9#R)xqNiX_B>8gq)`3Ux0KS265+}rZ*qy%y z-6z@b){pMDIk4d|W}`DzAyRTSh9tRQv~EO8?vx_OU_8vA7rG?-0(4}A$^bdIW@gJs z==@->loIYX_&}BwlH#0^Cp)V-WWo)FsCKgopOV(7P>+0Z`vbDI8v+Cu5HeHsb zw~Hz2^-XwNEJ>tF69>S^fVo%59UMZ&u-|;%R@{#C+X4b zf8-a4;HMQ72y<^}W30qgRxdp2hZDx^M&DUH9sofo8@;ebWyi8xt(0SuLdeGQjB z5Z&#Gx$2#W-04hW(5ObI?8IGir(k8Y8eRbK%5-@J#vgG{a=Q&_>4eH@Qdc0RaUn27 z<>+el+Yd`2oH^dnL`N%X-LyrK`n z$Iwg+%=I|h^@$+r(NzVI>Wf1{))w(V;;r%rKlNaXq?SjmIkT&?9q>%YlF>lhr%OMV z8U{DXXg|TPe%Zjr6ArJ#=pAfICktwE2CJrE*)w>hv1qup0w+mM^o4I#IZvWd;C{Lh zUmE?}i-7`M-B5s?8{Ynxz8X-kuhLz*SA5!i6f7t7!*tKP0^=q+pHKbj&8PKgshEMz z9(YoOj!=Go9BnBs5Ab!-NTtuf3(y{#A9uZk2ybtQ{Qm2jED`%tfy}@%&J^LJfcFPd zq)(iz4s`_6n(`ZWyNor`F$_3vzc|vp72nN9cZ5S|d7OZZTXQ0l!P*IL1+<&1l}-Zp zYAf#JHyHT;Bnf;a_?#k9H*OcA#&pzcQNA!!k~;-clz#;xEyeK^qru(hfCN+(%;HY$ z30E+5gkwCs4M_=w@CPRu-P`b2mw7_?Q$A?=G^p1vKpL=)@G?VzH@I% z(f2g;v`u&xW!at(g{%RY0YSUx1~;M6aH2{&m#cIxgP$~7hFd>+d$=@KgV}8&tf6IU zOGm_9XP_IHGh1VHb&+}lhqPfp8oVUZa&*y(PneYp_Mst{zM7fG3yheDHaY&XyM3~J zC#(x=(me&|6{CQdq;N>GPwoC=s<*h?UO{KM6~5nJgMukamM)OGS5_QhNJC;Zr}?6O zhx!ZxATo*7Ou?;7-NIW>tmZu2=BbbIHa}K#F>VXgEZ!EzYA(lZk-D6>IJ@I2+|E$v z^R^^ba~*EW6i(1Z%H^>dFK%Zk8*eLPHTAfyQoqAE8M~=TP9*&WE$(b+y@f22Pr z+A!}C92p#KsEhn!g0cUR$+K%GH`Jk}NCjo3&%ocn9#)Qho>%YFZvCE%rPsH5Jiz)E zF6QK8W(@>f-}z}U#_ z^uyBW{Z^;1&+PQWkl8Im6>KdY_IRWwcT0~C-ib@yzlYJkhu|4``O@2A2y&zJYjXWh z$GjDYu3p9-Jy>tP%IS-}8WO3NA@<%Hna;5`g%77;nYmDInYlg|>_sg(b2X~#R_gM) zWacUz(;q_@S!>3Uk&M3hNvPnMeKCV_-!ozSnO@|2Q1&&V?=TLFNU!f?y$B)ZRLBP$ zaG#c!he7HUzq&fi$phZlg(zuut$m6JvoYE-gnd_}dm|W@HZg=2&ZYbk9TFsTVDQR# zRG#3(p71@wZWza{+)q9)`M^AFGa{m_Ucb8N7nVQ+{>ye~Cko#N3lkr!^yPt{A@!7_ zx%E0&XDbCjgguC$1B7e_C*lyd@IsiOZ9WqW`4r~iW_OtJaYpzSOs{Mrhu28B|C zA;bqGOs3*KnY-CgP^Fm?EJJ+RhwsoY3`~`-%jSvNV;x&i@TC~;=Sbc*b?ZC~u^s;? zfp)N$w&Eg3-GD#}qPF8!e!8^6lal6`82*B>P9AlMWs<1hGF8)S11nIU&lF@;I5oIL zSD+|Wf!k0b=-ZwdTq{L|b=YM6Xz+769g=ROTX3@2t_e8^7t8XF1S)`R@n_Yk&I<+n z0XNeNoe|uwb9(YFHr3z-k(QB(D{c=Sm26)1t8XHlOe830h?20`+U{i%U0W9!B*g@q z3)#vC%<`p{O{fwB`9Fj|@c2{{P#>h3vjcA4qI2;1?C=ve$0=llvD5Aytr%Hxkueld zNeq1OLM!gyhUGGWOMJwNH}Cp6dQ+;1hCMppXV?>!^M2&7#6F||voyO563px~(&X|} z$DzE7u?mDvWs6Hd41y4^uGwKrQ3(KS&6ME_WMzswZzV_WcEJSN}|-TsoPo z@vai8Md?Sp;&?Ypk9Q~Xld#_sBHA+r+nS?tC`0{dKyPM+mlVh6aR=fFZ;$l5JKSe^ z4PV!qKPVa%Oq*L8cgrw`?j;$!i3zsr+yoSNZHh8Mh-Gjd}P~YAlhJe_k-jFBV zihI=4qI`_?^G?K?iT$#y*FzV=Azf;D9>){;snO5LdwBzGxG{I5aa>9-g4-gX{L;Ho zDY{JP&t0Dy6J#Tbt`f%+`Ee#+dp1T3#{GevZ2%*9zF%lGT_2Ij_oFvp6^EnH0YP|9B@N(Pn?$*!RIkJqN5PFnCnIC zQ}R;=2r#_88sGkO>`ROr>Ogk)fCF|Z$nN3>_1#xe0}NbO!Ofm%zd`l3?ziSJ6WZ}! zIAR&)O>u8C77{HUXh5aQ41F`W@}FKMQ~(jx%i#;*49}R1!m_B)$itbvqYY};Z>&N+ z|1Ozy?El&R;iBFi^fXb4iF)JW3Cs&OZs9XUofY%|vl&{H`5=^}_HX z<4X4Dr$ttWY{oq}E1);(J>YJa<5(k4iMj?jX0nMhB89l|MZE`A92UgJkl{UuIfM;x zup;ca>y+*v%Z_v_;`-59dsN{uyyfi?tuDm1@8`R1@@`Yy=(S$QX8HgU1;6dGNJ~Dv zCRNnu-<8X>25*Bxk9rA~$OdXxe*g`;A7W!kY>!djC2zr|0>c_)P&xQN8z-pzaJEMv zU!c&}{!Gk!$nD+ZQx{x_RO&J7I_SkHupuVe{ZCK%S$(A0EPSPCibK;T&O=Bj{VOSVjs)J-7=6iE1&{x8Z|K2!8_mg=XPB+=sOuw;{5u z&ozbyr2H)N%I2B%2SOL8#xgk9Y{u)@kc8xqn!!@$(Xd{RXQ}5hrp3IyD8p{#vnsgJ zWIBBLBSOV={3u!d8=_$lJ6ChlkiJg%KR%KM&xse&3yG_ z_%Mv>uNC%0Ntz(JM&+zw$)SIVldG#R%%_=lS0}?e;2+Vat{TL!DT|c$WA3)sW&MH8 zI(y5Tzeby)w@AC1`T)o9MEu^#v0FbiACH-r|5|T3-iWQVxD-!~fS6plkz&Um0;6x( zl3&4KVIoeZGNzszhkyAARFaRe zQ)0_M>I>z-Q})$OV3kXe*;!fm3E}&Uby6zqcYu}y`lnBocT(K)Q&2K+(^bUC+Y_@u>~JOs#9& zZQlZ)@cp`?dF!6f{zG}zc>Tv(ub-B=UjGPOkKrR3x7EqgJ1Sory+E^&%XK#BO?EyQr<|(GD~;>Q+C$>G9?W5|isk}48(Pyd*U6k3&Y#&KOP?_A zWnmF^&g>ADYv>MtlmSuRMj1KEs4B(}0a3T8=-Wb9S+Z$-E77Hbb)-2`mB@4a(hd}$ z^<;+ar!t=HtraOw(#=x!vCg|lFU~PJi4_R80z3diM9EnPT9in6a9Z}*@H!nXlIE=V zTu>R5UE)!u^;AlpX>_c|%VVEPnEb%k0gioYjo}6bMq{6DXA2{}1 z36meZ7XrsVl`#3iITvv3QwftF9M=HHK9w-}8P&`1D65s0NjQ!(E5QhJwJQI(kRX|e zg~sXDJ_sBjXCt<3uckOa^U;~G6UrjhlYH_2*?_|9Ls;bWeVTr{4_ylNWz~!>m z6X>4+RRK#+K$HX=oudCAci8trParPdtoK1lz|vHAx67B1G;+J9W2hX&5o$SI<+ysH z3V@9Zy0b6nlTj2}1E0kP%hVd+`bR#LHU7_+IByJm3jIne41kex*;i!nhxviCHsleb zmk|8AoG}Q)p2>rgI4k5@vqC?Tg4;7-YF0S<<*Zr3{&yU%Vaqci45b0AkDThsGi5A> z(g1ideRwxLQ{06GjucM@q*2uk1(l2i5LApsT|k~|bpe?w)=LFMLBJwEoh0Je)Mpkk z?@R@O>{xoL(2fXnHG-YyUS|J?q>S9lm=GZX|yECqr2s$V8etspQeOCL;y z;8lk1OfzS&4qPZjGAE6u^dja)YZ3E2m=dyKgM>VM)xa~Nl~bQT{$90#n^m<6ttmT? zl-j`il#g?=UdaAq>btqyK7elm+86zRd|YO28x$s^**whJBJEgn6s1Y-62t+lJg7&tBZZ93*QS_M zD=&hhio<6LtIG?vF*K6f818~Eox~ccstiB6(i6gW`IEb(p28<=gpN&WsvR1*3H_~6 zKdl(Dcnxh*6Yv_?ICu}V7$AH2mC=gLrouOHkYwFIHeuxd0|3BI9EO_21#{&Q4>^H;z@SMIZwlRCnF3+2s=)n%!Kz~tU7+;ocWp+Gk1mXDbuK6QtgNW$-hY7-e+P z<59e0@<*gJTnVK3BkK_&{E=s0&*+G~RQ5~pMCQGrqbQ3%GRQ+g-hw}J{Sd!u_hb=|&1&rI^P{I|tZ;2g>5aD6NR~KE>4}o^HNe-lz81A;X z(D*~*fu#5$(!1AVe@Hke6?^WQZ2uizE8ZhB8B7ThbC$?EqV(`#c?%=PbtPeFu?V

    ViB226H@J<&xflbiKEt0TodHg|*WL_RFpc-!ec1vM z1NVW&!91XKFNdGPIHuGaT%tQ(1Kv*=I;sCH~@7x^xpAf4l46L>sNcyM1n>)=X4 zE`HD9=PK9p&P(Z}Sl8x^>q2h6xh%*Z5Pg>DyuprXSKCPAS@nRm3>E4fq*Cbr>AB&U z-33WQkgW7FX+XDi4HBLODwcp%5UpC0tXcvWylgEp$yu>}1#pu_6VeN>*NkL6-?pwo z_liaP>idp0>#jBXt~IEGcI{aQ%oQ=T32{Xb)zsA12@ypPiWbkO&*FZXCPev(^=l=0(Va^2qCgz$WS16$ndWDO%7<8?vpMap_z& zZdvwiU4o=1xW~?}?eu70v2I_vk~K@7F>^C_)~9zpuxAb8nW!>n?&QruCRD=MHndyc zFPt}QU4_gk<%IsU$sN_kRl1y6qt>;;*<#VAs9QTY|i7m#bcM>DhQzKCjiV49Q9m3*}Nf7t*;5=~4Fz79hmxIMd1r zXyEQO#e{xHh9b|LHE3MYYgkffSbbi#@S=J_v1ajA?PAct#;uI$v#B%IJ)5o?ufP7% z+?e`pZuH42BKuS~X|7A6Ul8Bo?Q(UU_NJ8MzJh+GQ7W3iPeN3(G;O#>`rGnVD<+o` zw-JqnZ-|lLp|SI}?>rHBKDH-M5j*Ca#CGjQ*Nkdq4L|NSnU@HR{n6W`)cKGZhbEms zeRn6w!cwI>jyfV)Yom2_lx8X}($9_)NzG zSMjz{PmOJVIV%K8hu^2Yda5Hr#o)`W5=6Go-Fya_q#OLU8DtJ(n1^0g6AgK=CGbg; z1=-T78&mgj4jS=?Q})n^cM`^)b(HU|@OzTYy|SVddMzo7=%50ku8qtt-PF~1VLruT zz^g(cs(fxn&bwIkzRL3fFOKg9m9E8)w!W!rF)&+M8J#*?p#L~gmN+6}y)yjZslAa+ z-Lr9qXWtF|IHC&HE@w;}d{8en{Xpyd?j6|)UlhY#U%zL>__wiNGWPm*pue!R z6H)RcXptJqs9c_y(c8lDT$0!JRrGlD|LVM8Me>g{DA!-Scmez)guDYa_m`FKR@IL3lywTu$=)11nU)O za*%=SBcEX9SsV|By$seO(4fP<2743iZm==IP6yg_2uX*94wf(2{$Rg@r3_X=xblTP z4)!}(5@FSX6%STIsCoj0I&6!uLc-<@Nk56sZZ*I7QQo-2;lPe-$P=9jJl4c)}c z=v@M3w?o_RE#oZRTwdPoC64;u{X8O>bt5hU&9i4|_jS|OJ2s~x`j$IE{65U6UvW^% zl7%QP$-Sz6ohL_b^OBb6h*B+Q>8jGJExUxf0)kR6%Xx-9~R5t>|{#U zGwdn*#|mK3eyd(cMPGYM*GDPv_}P7u%=Vb|3V|(Q;jZw?xS=FmeqzjT-ofc%fl;kr z1)!EO#>S38mDkqCUei+A4=+lgmAu)fr>z!FvFS-B8NLE89zm^>N>uUTCFWw%AQk2dH#xkONiV&5A8Go6Dn?xEBRWoBfUwM6vYW;1*hNxkDib|Jk=A{BwJf?+1Gj7GIFFN8hgj=`$UU~B!7JMwb zLmL~t{@lC>hXunw;j$W@r$1G%)MlNi7EAWX8XpJS)n2LFkLOg9MxRf0($X*;NUaa4 zW_uKA1hmzUlhN&%_&)ovgIM{BUPM!27{t6B0dLwr(boU1y`-(Sw#?MDfs-@k!iA>H z%mP~4SvB>}_I4NzFgx<4uC?;=wh0L2@Y5XA!%(3NMasvS-5}n`eQbAX7n|yxpOUUL%8bN-fgu|pjYT6ncVQN&oIh|&huBZG>{B8L+~ zw_#2dGBFkMJb<(@FnoZeql}fcM_nCK96EjVnxv$llc8Qj1oFfR@7~RNL{+Fl*ZNAe z_^DvAni{a_K-fET7`d})LY?SuA?ZI7&!L$f2>W!Vd%by$rDZEWgV8~i2vWk*@QPIW z+fZkjt8P)5*qm|y5d^8%)vh)b^h2(Co?9AHWmvJ6BBq{WhH1W$68p1=Ev}B4FPAkU%Qn8ut#aYp#b4|pxZEEULFRov5oeZM z&+~$o%+))0lxeU6X4c1RD0k!P=mOi=#}ZH3=8Pm7;^+mNJO~pZQ8V1h9aTHYNLovG z_EN^s>R#9OnN|1j8Y+~{ccbr{F$fqh;swv9v2DbBy{Cvmb%qg3NY}P2RC9RH^KGnO z%Y(r=s*at<-A`Caxa9|v&4_umvaC@pt2)shId9rh(ihj{^UHIk_=RC`%e@U1sCggWJI9lFaKtav-0#0E46=JNbjeB`TDoi#C^^fYl z`A5(4mW$(aL@O22;qli!*H+7L_nRbdnI`alc}-sBX5bCl`ww4OIhHhGU)&R*5~K6? zgMX8fal*~}y+TUGB1Y_73eDTu7Vk$)B}I2Hpa!MAjvryzk>Rq<(^EIOFihwhQj#HO zk#R6VnpEI(&y#=6bmNKT*SGBF@jPktE^#$x4O!A(mSc1D;(D@op8B0`G3EUj_B^rq zDx#Nyy0%z8<7NsGymkN5-RT$ZVbNY7aS#TIkiL$Nfu7!LeSPCMZwge!?2TR)s)-e9 zh!tvyS-g8!tSwfoBL+aJSYPbDrDgGJG3)p5OO3?rtgTCp#T;yH%if7OJ35wIin%&F zS6GX=ySf6Ts<0LN=+1^>GsNGr+C$7AK7daN z3=9kks`U}84H5(V6%r8<8UZGphOp@9>Ikv=2(buYNaEreV#SVeSyQ4|Q<50qvgQ=A zfh3XUG_i&ZiPj9U#H_5=Z1JR=8~|(I(ojF;<$cP}2h`SVI>xcu7MKZCe`g5ZEo1`r2B7MSLL3(EbDN44N*HXl{Ev5dhupc=9o(+nq@M6Qv!>;&7|- zaI5OeRt;jS9I@5?ZMO}v(~H>cLhLsn_L~sdh-FH&p&r zcC5&hh|MFSJ=tj4Zo^4Ky*+rsY+|8k1NU@D@&{2&to#JY$M*QA(QPHEZ%{EYIW-nh z6A_=SlN}m5$IYXlJjGy3Lcq<7f*5b{^!a^Rb z^NXvx2Zqa9y1J_;+{d)nPUdzc85uSXxm_G==(ZYp7)MUEMw)fUI!i8%dGYpgy;qVS zsr$`|C!suSYl|9jRwk_6#c2f}nGKh1+xlHsoPCD)kIq?S3;*cx42y#4*hvK`d?{QSYFH;ZLR`h=~;X^HOHhgsNp zi4mKT-t%BIVa4lTME3|;7C0?>nunHGq-_848P0E5rvrGa@})mX5+&VW@PC2-=BqzN zQH9EAizZ|=_)5dI(bt_48LDgB>PBsNKFW3BxpO1eymO~N}hr8K(D zRKlvcd^3&aW-d+9W>N?tk&3pGBqT{HDUu=yQD}*hq>@{Oq?!5ue(!V6ocH}MU98=| z*7wf5-*et`dCob{xjpAO&pGF!{gXO$Jh33N#m>!-yfEq7t~Xxw(5Ai%zs$biZ}}77 zoKb6C@SC-n%`Y8V_S086-z?d>wR-KBcXul~MahLJmO|78C4Iah9bB6voZ zli!+h+=-8MJ?2kGo%?9db9R(o(QN!f!ygayn{mw0KF4?XaQQj4-ml-hamy+r63;&K zrxROW`u&8Y_is6FQQRqQoZBWhxO(utk5sumnAr86myYZ3-t*6|efh(bHD7+@+}S(n zy``7doBY>rRPSx|$5%V`@q}qxFZ(vNTKyaP&Q3n=3Gka|ZLzhCj(@@vjMs%`aIISn4qsq%;Go;!6=j|awouuHwp<)R?C~o>b?7aa_KtWM>bdzpwHSt=Ekc%OT@| zbP6IU$a`=uH_j)A_y@wXv{@e(JijS_$!8@v(|h?BgI9dx3ycm&3WOAOBZcz|H2m?mu&0$;un3FZBKu7d(P`SZdvoy zh-F){W`8)vJ?A`k;UV^LblZ&Ho%5Je=owa(I^|yqb96 zYujZ4tQnTsk1-(DxPRe`O0KXT6th!w}T+xh)+RZ_RvlTmI`i9{Av!j5!X-S;wqCnp zM~|i3M!fhbq;x4uKCeFWQyiIIvSjnHx4sH1pNv>%TtyX%{KF8ZL34qrcW{XHei{`UI53$LwF zt^I&`3u?b|;yG=;FKTnaN!{8$^v{RB*y7~J@9ev7^X>sH$L;U(ZkM5FKlEjA&92KY zxoOJcP3Jv%VcCaEuc}|MtKY86uifY@n%+HeT&rClF1YZ?d;j+Nf(w^q+&S*4I%hv~ z`;H&FKR=^?{bN3<@|U^KKD6P5GuQ4cJ#N{)OP=n(>)Hi#7bP!iaLN3%q|1_9H%cA* z`m%~UZ++pXGroW3qZV&}`quisTK_T6OkFdv?rRs#Z?K@-vE>gpySvVcffG-D>rb7k z{jvPi*B)xyyxOPLZ|}Y!aO>-TYdH7b8moGye0Sr-Hx{m}R=xfui4S%idu>Y3ard9y z=d+j2D;?8n!`rc93Uj0^Al(hNF){*O$#=m{mmp$?di)(d$ z{rls;o=~v1VfvQWz8d`f4_`d}*~Y#-3#xo|)ymVmTzb!#OFR8MtZMIBU+zIY`7d&e zhthwTdk-r0hYxTX_kr)*y5_Exa@u$03^M$hEwGGN-?lK~9b0n2mQkfzfQx=#eeD~$ z869U}%eCmZA00QNW5Vj4i{pR>OujK+zx$Ra<-RSjJD6uzULu1dz`+&ac+^cXgvDT+t5zk6~gBu^TSE!u?j*cZNx}dn*<%DaRxm znp?O4i}zTqpAQxdCn@N&u5nNK8$3J$QUOf9q5B2i4l+HkWzh7ZF4xO9gTH*P{nylM zIjH_{m7jDMa^JtMUhC9dk=EV0zt@WR?)Sg<{RPc>wR)ubGfjf$G;Laa(N%Fd=Vv|s zhw3$(RwsEAeyaV5YNb4=kWxESFd$3LGi>ZE%&!rg^{ds8C z$nCe>J~V#om_D`BN53@eqBrjRd-WUJel~KVDtxix>R0#F|E%+f3o}!9O+RMJ-&*Yd ztlH+!FF(H9U(Q^6-m{qv2i3X$r=f+r>o$L@Z@qr^ce`Tsh2<+AEq&d|zp(DLpY}X) zi?e+H`8A%J{nTaWTs!HD9VaBDK5%*K$(?328nt`O$-}N1skYzsX1|($xPH>PcaK@# z^6^#y$C;N1Q%ty(<$%jD)Ao7Vg}zxGqpTlPP<%6ZT1J7(91wdb!IHn{me)WliS zw(M-2-Mr&{7c?I8MDKx(n~&|<;BU`PO&)muU4Od$?7Maizv|qRPpD`=;o4cd;=8V` zwR?Qmoj1(RxLcK{FIZIbp>f0iyFCbE!*eM8$R(N&375ZnCGVKqVPYp@cg*A}CGVKD z$&5_|?lNP8%v~mJp)LU2{&plEMYDek?d{e8c|1`b8$Gt!7 zUi+37^V>h(Vc?158c*x6ZdBDe@iiVUbxISew2!aRs>7-&-&9n+_`)w#eEac#n*H9j zt^f3M<9>60oP7I=T^CgJza(y7ljQS8UcWwj{vR?*g2lyC{#CI#e^SfGUbykbKdoNz z>383iyju5}rp=pwG~tiapIn^@wf6oO)PC``(`G+?(cKgK>|1rw&LIy!c*eJ_>m7f3 z!wfc~-uSb6@cy?K#9#4fotm{%_kWZ- zrTumF9zQYRUFVH2b~kR7bo;Tp(%OEVk#g&v>-MJ1I$`X{F@wt6JlgK!6YuGB&e%6U z9M@v?-2N47>t1^O9T|V!clmQ09_@RGO^rv}gD` zBWB#ye|_$g?YDjK$48I*d*25xy6;bKx0v(nd9jv29e^-IGa9(8u- z>FbmKa{u1<9zDJwZt&TsUbpP{T7Qerf2MJ>`8S+W>y7ShFG?%yKQVJ>)x>Apc6;Z< z!skz}H@?c<}toVt&;-gL%}>tDFAaO7#Xo_ONoV>9nU zhC45BsCVJ<(-t4|SpN2Ns&;*B_lDCt@7wcA;M7-EyjA<93+qp9x_oBGkK5EKcz#lq z*8N6r_^!p4DKlGic=?+j|5X0&`uDq(uUhcal&vQW*uF4O?VglH>^XeL>Cqzg#3&G> zK#T%03dAT7qd<%TF$%;e5Tihh0x=52C=jDSi~=zV#3&G>K#T%03dAT7qd<%TF$%;e z5Tihh0x=52C=jDSi~=zV#3&G>K#T%03dAT7qd<%TF$%;e5Tihh0x=52C=jDSi~_$Z z1x_0=L#;is9relkj{5REM?JLD zQOUa;)uO$lc3k7A8yrWCecn+gKkKM-pK{b6KXp{WXO60NqN6@q<*1?i9o6OxN3~t< zsLi)IYS%lC%KMw6_MPge6UI7f;#^0a`hcSzne3?US34@}B}d%>|0j%cRQuN)b?fbp z`uR~uEqTUK@rxXFZN8&U`OZ-npXsQRPIlD2)#Ftcr0J~}9aSUMQA>9?>h2DX8kCJR zAnXkfI_llG95t$`qwZPksPESz-AMnt$V;Dwj=J$QN4@uY8y1-Gro^(_vxNYu& zxIoAHtsJ#ryQ5Cq>!_N*Ik(JF4Kp0oubrccx;yH2#DCQJj!NC_sQbn_>TS@b74V!_ z=%{a|IjT13m3oJxHlFRMDG2wUde)4bp;{aluWD~8Rn_p;#9RJZsWQ(txIYQ{HEiy$ zC&NLDHMjWdN#hcKJ=xq+>d9NVC?AydMgR2Ilg^zTb=g$V|5`^)0?qGR0ybl1aWh^I&msKneACZ;;5-4l_PJcQtLIZTX?Pdp%F=W~S{ znyHhg6L1y+Cm*IWNBcAOlJ;&It5O}*U^m72z{sbwi<@~ZL}*e?o+MB&Rb7u?x((5` zN_B)yuIn!gDU|fl@d`I@^qb{UGfUl2nZ_jeEYO(aUD_7FEmMaO)R)0W9&qO)x1@f! z4~5etB(KqZDAfyT%F^j3=Ft2n!j&{K`6SKL)Iik}umm(PPdnF74q}w@Af3{Y>cQHB z*PZ1fC9IU!z8i93o+QMQqUqHRCdOF;SWp>~bup{*tB*^wfv`(KIk3*k(;hY*w7H|} zCx}p)8naTp;Xm6gHOWgixMb_{BQ1i6mrqZa(%_Hfo}~s=;urealI;Um=8n`6x=ZAw z2WyNe*IuAgI^t$+=92)(RGaTBfPr<`U~Y$ydGMd^(uJ)+9;PcD{%FIxl!`PO9Q4r) ze|!RNc$S#7`2f;K>al%^jq8m+PNm5;1l;elP@CGQvrupOo8p95QdJdi+oOl8#(3Mo?gG4R@y6lZP*JMpR~fF({<&0*EGtzBfKBi&hTZ0$ zO4a3n9ru^2{rgJQYP|2_od$n(6ygJ13HN1qFF}~rc&EX=E8Z=5Z^ic}xGjRYHgJ51 z?~?&vMYypr*M#{3m}ddb1T2Ex0QheQ^L*szeZ>DF+WpupaNX@Us>6Yhb?)us`gs!rT9-;i?|olJTC7 z_Y>I7fqO3EYmDz542w4xcBca0=}6Obn8(2F4!pf#PQ`l--sADD@E(mffbTfKx_}J; zn<3s-cng4Q622G0JOFN0@m`L%5z~b@=b~Iz!F($0_8{N&;D0g9TaOv8GGJ~Aa|Y6o z0UX=l_js6-VShT_VR+l(-2?khfEVCh40?`6m@zQlfj1lPX1GrR9E^7x;+P3I53hrG z+u%JK<|hy)fb^V-_e0<~9(G^D?`p)m72lii=ELtGyc6KJ2GZ9P=KJy9jdv>EEAd{7 zcNE?S@h(TaX9HgoytVMQMcR+XyAHVC!n+bL&RbV|0e9go$Ga2nZ}nM@vHsjQ9QEU0 zqPM?qz_XkHemboE{n7c4x4)Bmf)4@R52yXjKpDl_->=vHUU=5|x7%ML%Fx^XZpQa) z^jp7H`}?i6uM%)CdV>a{C2JcxI-8pJT z8bQy(7)&?+uTY}c=k~S7#$E$JI#fdLG<< zt#-W>xMt#Agm)U=-{R9?)C^VoAxG``mmNb_J?N+)WE$pSTW=2@oP0WYe9lJNp|uZI zSE7%|cIR8Pr@NiWNN9#lz^u9-emh`R7>}7(B6=6|Sob9O>a4nI2Wy{zIY>9SCE&MD zr8~V@Kk>kssNK84kD2*+{Ujls#LynDU6F!bz}wd(!<|PAadRM6ob8yIX+H95W_*k@ zGA$}msga=R;%vwaXIq*+1=-t4kb9YjGw5t!;w+zYJjxR|>*|eogUH#zD0{H*CLY4L z+h?fkV~48;FSO|i?N3L-eK6iIJ_-EDB{hG0^OXOO{ ze#Z>;(r8CrnQGH=-*89GygpJ|av)R5JEVTz#_tUy@z%Z*`Tx;T%@^7@-+#_r< z)AWD`?)fAx<5%J+LL3vuIO@;u+c;KW47(4nc_dtt>Va|MP{uCy^OT_VgXBj>tj-9@ z@yS27B*E?qlvkqbw;e{9p6*E3(?kqNTuH#vRdsR4o_Y?FXi&NgK!KK1g{yaw3nUnfCFp=Lp;fW~RSyh!jkr zhTiK2>aSt8hD90<)v#2E+C(J8U{3M0$3IHZS{924ZCZ2C14e}r)!uENdHCpd$5Kh0hyoCfPBVi zI6=dy8qU&iAt3!P)o`V@U#H;)K*qa8!*8{HwW<>CctAdApsPrvviI*KnwYqcj|&;UqwYo29=OYq(Ow^?<~`O@Hszu-Z|AzqW<}4I60~2gq=( z0g2zy_6Zs$YIr3e{bg%7RKwAL3^!GO&(UzDhU)?OY|?O>hTm$qUqe+*rxTF$s;gl@ z+cyDp)2Y7`^mnrU?yq6ChD92dYB)y2Nr1#NU4PHgaIuCfHCzWsf15PiqV2!caIc1{ zx}>{?hP441uAcr5XxK!<*4n+T{!Y*^QNv{IevSSfpka}Qr5cU~B%SWp-%~Z5rQt&D zz8sM0S*`8Y>F*8tdy9rU0f}#q{#HjzxN3lWj@RGy^mhY5mU|Oz-%5YC)$W}%OxCc! zh64bZo_zg16p-+b=8j4vOM`53J2OEny$;RFq*1Jd724d($8-%|a( zT7RztQcAtES=c8rIV=pkX6G#?wkeN82X?GCj$FjOQ9{pRT{N z0U54H+Yi-nq=uul`veVVY5Rp5F4b_QhHEt3py3t`_h_h&mHgDuu(pP$Y1lx+CK|TV zu&ss(fXq*KKsP`7J6*dE&@f-aBJDmDkohdt_MhGC=^fw2P@hsH#OZE3^ z{k=}Z^%`yfWVkK*d#8rqYWqDJ?$`D;Y6=}{Yj_$U!v{2Mr0rV+G97IJna%`lpQyjD z)b8opzDUEN8jjR(jD{05oUY*<4Hs*;5|HUwr@uF7xCM~u_*Q@K*WWdclYG?GFrZ-* zK;mhwza0&`YuI1IYz+r%I7-7Y8cxt~Dj?&ZslVrGxKzW{8m<9kyqom*w;Jx(u*UH^ zy&48IY@}gp4HGo%uHls$rfZlF$ase8?@=0#0c1H%(BD%voTcGBK(}7$@1+{9)Nq}K z8#LUe;kO#@)lmIG@^L&M(@|G{2Q+M=VOtFoH0%yY|NZrMIv~@Nt-p&j9ID|+K;~zR z{+^)WR6vHCrN0*f67N#|yKcL0$18fp7h8af(w(y+UR*Jzln;ZQ(^AF1JJZ9hT7=^D<_aG{1v0U2(khHJF_ zdJQ*exKqQu8miioj~W`*1tgvTAfG0Hq-SgWouFZ&hRGWC2V}Sb8s=;JQvE$j!!g=^ zf`-#IoTcGH4VP-T9FXO*PQy(aeyibr4Qrez{_1JiK*J^)w$`wdhRJ|@uFRkWWlIX zGKzv+FGTtjh*^g@Hw{-&!h1H0 zlHVCwnZ*Sbe{M#0R+{8LFE=-+>y`FfSX2NyxUOzk{cX~bTV&IbTa=Ystn-pPC|FP^ z8F1sw*Kun)7X;m`rWND~Z3+jewBl3=D~VE+6TrU=pvi#dMT43dU_iu6OmSW5-xy&F+95sq< zI5Rshl_}0FNO7B@3#Dqnj%`WWRc1k6F$=aJ z?FR?s6}$C4D;>1YDstOuR)$hp*;xZglPq*M=~+^}VJ=4PcdKbuPCmL0_BiyD?+#Y% zG*NF*W|9Dy3xc}hWaXv@2h%TMQ0iw^?tox{pn$z=b{(>Evx>6NteBXr+-%f;LTLqA zxp~EmG%Gh>!$OvCk<QuR}La+yjGH=}$=wvOu#_ax;rlGD$X=3tR(+0GCGW;0tu0 zfPu?22?g`O{DQnZkep`Mb9OL8!k|I8c%>+m+v@2L)to~ks-v4h_CKyaLfz51b|Iad z+fV8G2D7V_O~~qmu`iP_CnY~$S09+A9RQ-7QnIsdkcyX+G8hz-{vPB0fINo70KmQp z(7NSGVRzFk^sXZeXtm;M`z|%0=UK?NCCwd8`qH zMSKUC^unB#fl31?1?KuGNnsT;7KE(dgl^pE*$m^7mwKIBDOebJ85w*Fg9w|KB^@f8 z4Ee6STp3UE^4Ux|O295(TCza58Y{Zw6}Zif5Zp_)Zeg%T?ZxZXGLS`Z0A{D;yMbw! z?Q&r73v)qMWtCBRCAn@v5Hess*b{I&F416iM=(IPAtsIPXxdWn`DEUtJBEE>VF?oE z`pHg7tF%W&W+L+Q(8NK{{5&==<{ajNU>Z6E7X!^%x^IOU(YVDzKQs&8f*{f(<(^-F zVUY}+izmw^9P9>VWus{d$q+UV_$#YGZ&<3_T{snJMtG1wJ1fd#<~d}A!eKxNWnz71{gjU36|7xebJS0f&F z4U$io5u4BgxZK(flAyD$9B$zsW0bIet{HjJ>2a$Z?7*G4GXUZS>!ta$f*{&QuB1lH zLb!q;`z-j)${fIkVt69JZ1UM|USZ}SQIJ={*9}-uEL=xn%AlZOT@C*vQ1BOmVdJP( z7)&YP;E3)s4?{R%G5T<~Pz#Z7cB+NJ>x)T3#%avNf{NhwB8CcX#Xtov#H_}Yqc-<5 zd>E;L*X-4t#xa^btUvsqF%Vx7I3ng9{ed0=V3txNWMT@7 zQ$fZo-BZXnoZPnLokA53Da>N!1w_1%#b|=L5EKvy-c>V<@||z0lR_Xj?}Qw8fXcN) z%G}mhr2EpM0W!fdys>w<;7CaRAGC9MH<)t^&BT-V_zfn9t+9xFhzqkYh)6jgUv5J! zDv)skFxPO&Fe77b^HfDc$oT;WAPcuRH#M&qt%|M);hD|w+si@nTWSp;DjdHD=Aus| zI+)EU>6-QEMsraXJA~qVnMIg-R;+u)K`Cj)1CE*9>Wb>_@rZawgbL!}pDa>fqhWmHj z44X}VWO-el1!i|RXUa4Vi~-UK!Y!XW2?4?BxXq7d(;c|wk8e}W)e!VC@D5n0ZqTg} z3F7>e)||(Jd}8KYMFb2|pEw_&AI{~`lHIyX-h^q&1%D*c0gnGUsU!u`JJ7V({OrPh zUOurP1^uMk-=ZzDA7Pczjm7;o69V9NzrpB$9dsYGU8!JnLpzq~rrRtPCReBvl75;^ zd(?HPB@r~jn*@zc?t$xyU+!b$u21HJPr!Av`%mpR_qU}(*Xv^O==zmibAvPv;}U?s zRA}L*xZ3%~mbi-%5B0^wE&#oK?t&~tTDYq+-G`eRt=y4k{L)`GFy_Hu5Vq7s<(|$g z*JKhEaPfKl<-6_~ZoI}9(-Ml0y2I3MbDNCoG2D;r=JW4jjD(AO5V_+o1G^QQg1#~a zo7ltg`u%4hS4@ld354WVQh%{(;qesBPn^$>gk+gp>e@U|pKpk-9K=6&II^~ch9hc| zpEO|1ju4hRnsZRrEHPq}os$XfDq`fm(iGsLZe|f^ zz~75qY@{Y>5*ZJ1P%n^saRUg=eWy)e%12uIAr$vVv&9KL`vGen?9)IyYS=dl^KlNs z#v{LhFc)H_UOx3e+3LZ6A>D;K&YExyK=+<}+p;Gh z_Yc^Inwr$V?1q}x!CC{8cYix-A5Ad!&Lp?QQ>6=(ZM~W{?6pdmpxlhM)*rfpPJ-NA63{ zM;nxpG`xKn7y9Bpe6|n?Bkk#OloRWaX-}jE&j{c*smXmPVrDNXu~=N}hxpaZ(?-4R zPq3MA0Uc8#H%}Z%bCENlnd$Qzs&l*qI7G9b3KHlXjVXW}baVSI_D}(rzo8FnPmO5m z1PAaoL~b(GHE3C9!OWhjE80&$P*(m%3VSFa`?*x*2?Wv-*qf8z;^Qw@_MU}Eg?;?) zEG5hz(TlU^W=VzijN*fB%ikx8y(yE6E9;ewNla%oE)1NN-pu`{jqEpKPtzSQN3IT_ zOgq)s6Rr42U?k#gBTjC%iPh2^rA+6FL$&` z06j>Pc6dn%OB-7BUcZPy`NtGmL%gZbISY|Af1JJOs1XKkjr4*C{$O2kNP|E zDxZA*^giR2~Q|k`?-9N?6KkAMZbU6V5W&FB}XQ0!s|z3WPI#Ln72r- z>^J2!81~Lma<*sm_r2aeUMMWQI!9Gf$KvOSJHpHVvOfPH&G1)q_P0DiYwe`%naB>M zP8q+1rY+JeVcBQ->loemh+mn_iP@d5>u?9EdlH_%633y|J{!)4J$N1ThLZRq*F)ov ze!}aaxO&}eEfhD?*9$FJKQllh&Wky3Fx--YNlMG>ZxDQP^t8VIQ{$85J$$V3w~A(! zB_pF($ePZ7{1R+_H>?aFA0iN2#k%@B{+jsgU0HI;YtFdl|N(*E@cDN~1 znAwqo%0^0ZQKCgi38gEXq`XW=vRRHQG@-4Du-UYYJWxj1~d8QnDQK^H(!JYeT7jl9iYr6F< zWy`uW*b@SJySo24M>T*+q&YH2BEM(;Qc%LCmnsG?6Hu4njl*kZRAyFYeRA$k`7uug zBpi&a_8O|!J)@{V4rqoAv3}>l(*0-7o}udFjJL}kwf_J4j=0GP&vBc59VPti)BOEzxF7Nn z97`kf5R6p%!_ajCza%nrgpx6&K+Cv?{3gVf`g8S^c7WsBG6ieuk#02f`ZOhiPVCBlKiHO>A7Tp_IY@a0So!PN=Q@^IFY}IOod0sHB9CWjLJpAJ9?ObS5K>LJ9?EI0+rg!XR`F{l3KxaGq#INUfH^M5+t zW>HtG4^bO=#+rr)@|*W9y;}N%{ox=S-cXz`L$#W>aS&6_Ls$ly+wR;>E$R1~>Zzu9~tv z2hh4DR{xwSQamO{ha2C&7n`4MLUoy+9VmbPvLl6~=jibBb7MMPj`o*~w>twWW zTy>H8gYd(lcq7Y^O{^wevfe9kT743mtLP>_pYC0s<65@J&>QL8G(k#xL8hPR&U?5n zU~*;n#Bl!E;E0q`;Wk-92Y(JPoy5tx*?%vM^;La06XcV4CU=fI{!m83F`RVe7|H&^ zj!a3Y7vT~Sp~dapyI%H(ny0c0{6ptX2|WR8^R00dej7DCAqiko_r&B56%`e$C$@TH z!g;Sh(BifGn{V8>@rNINSawh2l`B_PR7_lQ$61SRtG{66U!S}AFV7DD^PFMze*E#r ziXZQ-*mL*np(l?XJ^GVRKB@TfmWr*zSB!1C^sYvWZ*Q>hmcYE>r&Vma@saC~t5}z} zcSZlHxixZfaw=A5ezUmGZj2JQE{rBI0q`3XrNN1JQE|(>!QPuy_2_MJicj`+a0L`6L$JYm50>k*u z3GvDG)&}3+Uh8J(_-dOzy>jZ*MmL{UKQL=nqs_y=smQI`cg6B=F1zpb23H)nKPmZ& z%vZaeep}Wlg)^#TXFgNZC;JaGKgnn{ZrGga^WyGk_T<2j$6UNPvVEy0iHef;cg zDc`5Qe|720*FL+k;iG@+U0(a^hvE{~Ac->{*xk-SLeC@2dBIV~)DJ(mxemf*m*E`ipZ({i7r>6^roX?xG~&7G4;qCUAUR^2x}qDJU6{D(lQcn=(*|bU}w%vkApe%Ji-RBJCt+NuLI4~ z@kTn|btvq;=ey3p_rcC1oC`nu@Xkm2_u_pE?=HMoAus*$Zo#_~-?IU409=Z6J^=F` zgjtF2^)T0mxjW3&0C(W~Rro2#_a?l{Vb=+Ezx8L2Zns}-h~92*%*2^=kVS-^BN}VB za^FF$-QrAS)cr{J9mLx0f2Id0!c3EP;jH!kOIX6rn_>FK`xg{85QTx_MuF~?`BtVc*bOBthn^UT16Kfq&?!W zD{-8Gm$*D|I2PfIDb4bx%f#FPsTau^<$q>{AP?L$zYSLM+u`Bk-59N#cV26x4V0>L z_DDT+>VT3vxA9OmC;3Qsr6indQhLYr_2{z0L*d)IkZ(sO^YZdu-}v3Cjo+=_^xd1A zcD?=St~H8MlZTw=-r`z^?w*C9hw}1b| zj_N(sAtzC{Ma1|NeI8TFc_umo#DW^^S`ei3?eDsMY{(8kn-@h_p$~l)zy6iR>t8v0{nH;cTmQ-#>t8u%{a?TM`G%4ke}3tN>t8wg|7+7~s|u&pO=~;BYx+oL4zztZIGFugf!24^HOPNSuC#-XnZ(-&N7a&o>is z2jZC6`1vjPp-A@y#m3M7z47x~+#y)It)mu~I_k--xVIAKPiEu(%&Q%hJk3#^Z*>x?j5;93T-I6dqhz`nu+|12- z-f*&;%ii8+#%~#){n(6KPmEfW!E+@n)CczBxuaEhYVGK)Fy;vl5bYkmE0M$w*h$14 zFuf25$1Og7c^vQXqpaPG(V?sO;!Z8gNIDJv(1Jho*XF{=9Jx{;59!_!V>9E=hKZ6k zcQYcKg>PbLay4>ap}}1r{;7j6k~`(eMqj_*|qwM zO#r|Hhp|4pBM0Q2L}tuiep747yE@2q6xK4nBBKrENJ8;gPKVlDWZnKh?S zOp=Mn=^yA)oqSVUSHq80$L`;ELhh#qo<)Gt4UxsK%5N1=`QA;(6I zUZIMlIvb-W<<#6p-|HwlZ1%JJ{H-@av4gO<6fW=6<3xT>9z9q?rs<3<3OQsrl}6Yu%ahr z_QNDYx34?mu;T#zik~FJ?sqlz9WgR>#kg!j*)Sc!qsWfPP(RFs^+#Wwfu9<%T!rL* zDBB}b*U{)Z9xM#QdBYwo9z#rvmwSPGA}!R#H92Cvrv9gB0+_rcBh9iiPq2hj-C$S1 z$J?1i|B?EW`R>SCjPWxMJI_N$QPIhvPOq%n$vVF5%C~EGIT$gi%bexn6Ae<1{6+Pk&phf3NBwp5kvq@iUFzI%K@I(6-%L}%E){mdS+M5`b(eV^ zwa3Wo%Oi6kV`oNtag#ZeeE z&eT7Cn-JVdV{#iB0{1Y4%!@+jGv2VFy?W@3CKQ)Yrb)Fa}`Me>J^OMt}rWK{=jWC{a<{z3Sa*!=t4V+8dbTL&%H_8`HlhBx#_|G-V`L03Iwh zlmFiE&+~HRJd;BSCuz0PiUZ}!o~vWyVR-jRyI0k|4`UMGU_k1KF4tp}SA)9ReKS<~ zABL;7S>fZ=;Ll4{0p4u98F)j-tD3cjtJ-*z>kL=b03$s+$Iejq!|kcl!tvLDo@iCP zZI2$V8siPczX3X>k@P+nR~hc=eO?aO5qfm{(SNSS`!3#TSVOL(hP!&7E8)HjZ#2En zO>jFLz0U#gPrc9UkRPM>`2*rIdY|2i5ALPV?+YMb`(ge8?=pPX0o;tV)`I=ncqhYd z1HS9RtdQ>Ycz-Rq#H#AU|6_We>yXE}D3?Rk``iY<$AdA5HIb5a_!Z?uVlH zxgPa~_fQ{--sg+JdoaDvp73)e-dT9B#rrkh2k~yedo$iqczS`M9JRlpxYN^VX!mu{Zm&Dj`U#a6Rv+Q0sdElrUN{VR*)Hn=dfVlp z>SNDFxL?vPXQ0lQcInl}9!Y%v&+T#%((vEV$Id`Jr=oA!^AqTgK4me?zeFE>2k{aZ1`>Ze)r{g^oe*3qy&x-B$NNB?~#>x0wes}ctn+vJJ^!>5+ z8ykOrKkN9W{T>Nzn5*IgA&C^7S!x5dgY1@P)`}FA_S8NO-NO_uoMAic-YKp?QIm@+ z!SXbBPp&ZLo~}e#P6VQ+GuL2^_A_Or0oNn<+Bb(hGsWGh#FKJwfIoY>g2=K3C+`ZO zYJ}SW?-pv#~IJn;u$ER57!UJ+%M~g_v`+DMtt=Cf7MV&Eeyo^|5*S3 z`|1CU9@pjV?fT&}SWEnPU-2VoCgE_H?xoT{Bs?5 zAMdP>998??BY9ko$N0tb9Asw4U!$|kK7x;5|HpgAJbm*H4?AYlzZti!jx24BJ!ctm z;)J>JNnDM40$ekISN4|}H>*=qgn1X;>}-s@K!VFVu-BGdk0zY#|E0bWb#P2-?Yxm; z#np_x5|Z|u?Q&$0JNLxi%Uj3^cVZtJgNdK_|A^*}*j(ZH;+|sB`|;o0X6&h%#2c2( zlTuJJm}cq$QP-9`g_^h~_WQh@uL-n4yCZ~*IZfR0r=#nWdOn<6CmCcK@@_#nb&^~R z_Y51Yc7?BSw|=fKtJCD2TN9<7&s+T_zdgsqD==R529!tYi|B+=^V>XEL#Lb1rP{); zU(8x-I3tdp(avr3`}3aOC|bEvV@&BseN}?!GLjgvB-`>v9o-w z)x{HzjkkC4G*kPCrkt0z6gT!h{9_M9-9}S(UVFKl*0?bJMw?!I$&CiqJ+zL9FVR-? z#=#VL+dg*^a28_xXQ4mi39-S-9U5#+)I9e;yrq=$obGU8@56n)Jnz)2D;{wB9ESD# z@ZvIlh~46pxU7z!X^m!gBmJ6mQR|WY81I?mZ+k#W=;Zz*!E|u{#-Ax)gWc%c8++EG zP&a>CIPc;v%MM6|eN1@i?M%%GuQO5_>;*&u$eXa5;nW4n(Clbe-y()7oKE5#jqZ`^ ztJjX9IS#Uq=3~uSZ|2XxJ+%A(=x2j&^e!XUlQkM2j7jP&|2kO zEblIz0CsLs3d$ZY7d;@M>}(Y|GUc7z%_HY`bN`9 z?b}OBOL4=-{rBHLa^#4cZo28`pMS=Y#>0jUyYtRFi;9XeGc#Ad_R@FXefPl!AKZB3 zjW^tI!{7h@_db34On+p`v(G;J`RAX%_~MI$2M-=NaA4oQeR23Pjy+zqXwhSjJyu*? zoSK^2uV24{f&!d*JbU)+M<0E3(xgdgX=(ZS`RmrLn>KCQ)TvWv&YU@8#*ABT88L3$ zy+el%ef;sqOG-)}dT{(5cieH;U3WeF@WbQBj~_dB>=`ePjz>;?N36NW8lSQ=_qkDU ziFmB>H#~2x^&5}Alhx;Dr(X3{k4s)w>_8fZ51WUVTFO-aT!HO#Ihz^QSgVJK>c+PUh3! zZmiSqABDLmCX6>IcN7j_e|+{&!|RM2KrY2?$~$E zxolFOm5b`HI(5jhGnWtRJxn#N{nzoIUbgL4(Br>)_#5K;tvrjhT&dsM=yIjLSnEj{ z7n3W+W#|rT&1GK=6bi-jmIp)=d$cKb)1}P_A8yaoRkc#*19L zLEGs4Ps7_C_2Gh8{}bzfen0(>S#NH$#>%xXdJN}K-eTq2=6uTG(8Vhpb!5u5MRsdX z!{8ap>|Z!1Vqan&`b$QyV&vV?{CWFC|IM5Rlj-*&%dXAb*UEZ0KcN&(;^qvErwp8L z(YYqdBaCF%oD5;)l$3b-*L@|H&{b-QDGk04?^LpX|2zfu{ze)`J)y%tMO=KUJ@ zBzOM$d1xnFQbyF(mB;sl49vfZEw#!>#*!d~Rqv2uz|C+d<@Xx&i zVu@eVZfuicob_L0%vjZFg75)nxe^@lzh3hL3031O_YQ{c3+#Zs`Hkzx_<#EFCq$hel8|s=S>1&ACIX8}!f1XEbT*GPMclFZ6t2-8%CXrI?w_~fY zlomIC8pO_DYGTLwpX|1*e2nC*AEsp}oU`p;HRH-nc#XNlpBQ}k=_xBoruKyA*Q_*| zHbIWKr@P`wo*HK$04)3 zELYman!+<91E??N6eR928LZBTl1zW^ew}J83(C3;-9ew)UoOhm~ruu{Y;{bBOHy4GjwCCq~04J zj)DR+&|k?Tx@R~?0lX#Y6^LT5t@Rv_KB-S)HFc8Eo5Z7)SPT-vJJ*aB7k$dOZckG5 zw>Q&o@*Jxx@G|aDX#nS{!YL67XG5I~YTr=}pT8XY;H{_9d zy$mtf$ID+Hhzf!;fV9b9H}o6iK6`qwh59kvs?pi^#vAI_XuO+q&=2f4d_TaU_%}NQ z4&?V>^~xKTR1D2Wq#ExH!?g|dpvW`^Oq6wvIsKxqYoz_tQODyB+t72zV)s_Y?yVfW zuT*XO>3{RyEy^*DxxlV#EVh1bgj$wPY-@Zv^{+vMFMOH`1OW1QcO_)d+$+d{A-uSZe5)->$Lc%fI@XQj%^tWaWfP9b4vkY!K!g~8% zhL({ldPuK-*=N99n49k{JrckJ7`^|1Bn!NQSNqt{Geq*wV3HRzzIO#y@-2qTwK}xc zuhr!}uy2Fg`uEG^BjGmb@cRrfa{WkpElwFLqn&1I(!lkaB;-q;P<|tvk~SRihihe9 z_h>0KbtIHVIti6y_MxU<)=0dkvMRJzn{wjywlvQ4!rPPC^MPj08#?3Z3fWd zWVT^#O3<Qn%)>AJoAzwyo?dwb_ir3({3az4^dW1*t+uNV*{JCWN%&Y`^dYCe za^tWC`Gxa_k67~6*FSu_wPM?ctXCO+{DDn>XXV#ZPY-*yE|Er@g!I$$zDGe(cG~Z|~T;d+X+JCrn&= z(!^2IkOiNjV?^D?VRDyjT7T!5(TS@&mEL~u@LR^+_0JLa-TBaMd!+W+Isw7OMJIy33Kx>X93j_Xpl%DLxt8JJ$>&toplt~cr^)p|qC zy+3tdumx#71XaWH<(}EeUpITg7vS*kndP~=jUKZ4HbD0uefDdxHO|HpZ|vGe;%)y?}$)lj_ocn9H~@N=p9EuH`MA8mBM0&>H1QpUzd zzR3j|8)MfSe4gwL@Jjl*29W3Sn&CW^@LRkci0eJVcNvaLPO6tPg2)}46*=KcJ7B~k z|H<1;DF^H3%I!poXfR0Tz1&!ukZV2$FLNLg$UuG?K-1iz?KHV5`Tlv2q7jq%~|HP~W87172^g^ojDg zo{$Gq`t79%%a1EAJR>POHlB5Kh7Tt{D5DuX$&QC39~3#wr{_c;uTHziQ9okucuYO5h@{*V z16keSeAvHd+Pk0HyLQpR)d}qCN*QYbUZY!ql+e=N@0`6;j$@(i+J>)7S?-`?_+1P~XHaE8sQ;zaJ}+I8Y8d zW3*vPuSB{iv#>G=riqVVHgO8B9zE#+z3;VsQ?afs{s%>6hS-j_uI2@?~Dp=%038QTHL4 zS6osfx*mJ!%Z}P~Vr*U!(_{br=&_r5MU65$uQ+9dqiSH@5UR&Ma^2NF^w%4H3gE*lGcxip>cx>O@wm;#&EO79IZrc zo%H7_@|Vd8U5Sx@hDQ@R8y}3H^TIA6GYu7`EG0hw99GWQ(8W0;`X1K<)5jB z&+(#Tvw4ZMOU~qzr{0C{vO|incWtL0>!<5+zWL|T<%dHdGfBvdjq|Z_{`WJ^f4W}o zTmHC_9p_)T)lqwv;+^lP&Nn*B>|bwG8}~5B$v9tip<|l-5dkSf^Y;Brw0Epdt{j&n zJEm_jeJIc5ma)$Cqjs(zIu;!~Y-otkbGbyG!I6+NC>bSXr&~5`yyGloA6y;s>VHL= zS%seI=6eeZDdMf|!1Rw|)K+vps9rtRTpa5%PbD9)w&^>4yGEPDIRw9FBT(JkPjtzQ!TzIsVo8UI-rqCntNg2E(serIA3=UvovC@?rXu9cR2<$2^f;n`7NULK%Ou z?&G&LUw+KZqr{}p53^_X`!@Kgoe>S6mu|*CVKn~=|M*w`$BB~5u1Pf z{^lQTzq9j?-e)@Mt%sa2Ib(4*NA*4V$dxm8LJ!7~i#?_pB}I7{qARD6V<@*h5zGI80nvKX^j%e)w7?@FJYgAu=fHP!f&bxxk7ZzW=pRxQKlWR@Dy zO`$ktUDd367OJbUPx(`qVP$>DdjeU~kXj>gY<}JAe{ohZcV3l9$k2abryccbf|0(i_X~U!QU;nzuQO%!? z@n13i>-WQd&3aJezq3xV{MRj=!FypI61vXYu^rmSUye-vE6JU!mVh&&rW)5~bI>b# z*LkJi;IGUpx#J+i<$pLj?;xGS);%hyp-YaZdxtbJEKdKq`}eUuzX43ziE z9l>6A?_LQb39;cKxthHnvL{*a3&!xh$X-_?3m2Jz;SswaeM3xw05c#R=%>GF&eC5U zv6g7;Y3{7Q#E%3BrzzJ)?Q>wgqBPK0R&y!E$;1dI(i~F!z#2;j$7}b&M3S4EaoMZ` zP#Qt4NuJjdP?zA1!}t~I%j|j;-`qc%?((g|XQ%5B;p_Nb?3Om6rqI~P)!Um@{d}yS z&ouajlM+0kT)X(8WY64gB)d0?Jo=2h)kaPZr}k#H$Hj1ImNPfpEo1X?=q4VfU2a{H zyK+Lc7X7)iczKJfcWw|$75|*YPnA%L9{5{Y3g>L5o!XjfZ{QUiQqQdvsv~NO_g=k@ z?#)jkNi6_{yCE07FsqRhrmS?!xUm-sJ(0lV+n+;;-@o#2^X0Dx{*YFW!<1gQK7?_x z^f%=yvlX7F7FsJpOZ-qv($1+Q1bZ6Jn=b~(Sb*2)Qrp}e+~lWAWD0WMzwH0F`Vk!v zA2nF6LH=aa$al?W9V8vUG`_=)?cmx#;ic=Pmdt%9<2UmIaiv64P8Hw|g5=5|+)Y4T z49=rEXj?PiG8!$$v$6M|5g@LtVeJ3xOp5v_ebGnQ$3M>y$t(8`c>Pevn^;0`Wc2zm z^PPaZGawnM?}Sj^mMC*1na_!yInPZpI84vN6P*KSt@buZSUR|J|ee-*%5i?|+Li*PdS^ruP!-e}6yyuh~!V$Wyle-F&a3R?iCW zf6w3Os3))<`0DwNy6s7a&FqMI%=sML+js?f(j3h3>}sEp&$Nd$N_GSWBl9&U=}^T2Ye6i~#UF7B|k=?a%*nK?x094&Ml z4AtpmioIjz)^5cmj(f9|uvL|QMh2IY?rDIn7qWHr6Nlmxo z_oyi{e`@_{^zr+4=stfH8^2X-{Qmun-)8n(4eh%07V& z%^Wpmprd{YIO@SpGJmQQ=eTY8Nco|xuQ~eC>mhaJ{VMGFDXHd44ac2GI+)DcX;Y=& zxbl%$zp)wTy45N#RcGU!{Bx<=fbY66E1Z?Q9&fDQi1i!ZexvrA|I7V`(SqZ8r<^V8 z?F-4h_6CQ^^)zaCb1jTqw0Y>xyPU{%a~+ARLFSRQCZ2c1)jIY}@)&z+j7yBNmd#ZZ z?_9*_5ZYC6YDhB<`-q=J*ym!!m#gQT(J;OC5kH(EaDE_<*!6^632fz&bR`0R3UGBt zs`Kz?Zn-e)?wk{FP2FoRYvpni2v2(P&N5_PkqDgL6IOJTNGH=2kGOdHN)B*)Pk%CV zBysNw9Q0uxtKZEP14_PlQj+D`v(bZ3d{6AOYq1HTC0jWp8N51K9 z?X11v%0hfR1Ce_S_y}G5xMh^?Qe5oK+%D3%CFOHybdlP_xNWJM`59xn0&%8mx{2Qu zDpxKl&sOn&10!phHNiK~;GwHPU>V72)& zvoLc?R6{r4Ln_1j&tfrghUUJXmL9Nt*`AF*dpb(^i8|*XUBBe9dGW6qA9$@)R!j4c zJGMTqmHs<;C_z}w!Z?nhGLQ&`qSdw_ZrG?Q^G;n5AXTmd1cfI zVy_d9mvzpo+Z8&h(fvRp8e1oyZdmIzE8o&$tqs5Jm%=OV^QcTvXY!HCV<=< zC>qiR0oQg~KPIxFg?fIsWl;3_-6hG`zcnqkt{$7;{eI?mW?iRjrj-jFhqGu~K>ib| zKRkY=qgG5gGS}6!(Lc*RQSNf?im|82!^LwQ#_MkRd+$8Kgg5<*xRGPduEcHJgm>q8 z>KyaTuIbQyS;a^T$INJav$&hNiNWm;CAQ>CyxN(WZp;R=RyL!o zY*u;M-172|Dk{D%D}S-9d}&$vvhwnm%FCZFFI!k%{>j4+KU`LJXIa^p^72pjm)%-c zHmjB1mv1dEUr}DRvb^lgin49x<*!wg?I%08^vzrLbuXIa_Y@4uS*gX+((12f2GhRSv}N$~G>)I9dixbx!fyyNyRoi2~x`)*68N{haIFC5ahQFm2y)VZr(KR15M zxL(P_tJax2_wxO5f4t7AQap0;tus#U?p)oww^MsYyJH$Ho&DrvPv`U>&_6vp^}38& zbvMnKGjHzP`7P!?H+Sx{C8}oYHW$9Iu=NXzu6lmqmCrvv;_o$!E^XPl1~f3P{57dzS281CiNv#&}BkA9s}S zY+xf@HG6nEA#{q?*T}%kJhL*9=A1?&#pCH6oD1_YX5tHVr|yNo^=qOYnH%hDx?GRdb!mun8g7y@O>;K7 zpVJG+Z9};UJ;0BwopKjQ7V<(ldsEPel5O4}$?r%dCGzNN|VN_`HRZ+|>| z-u~hoN40wJ$egzim?nJk!ndQh|9-=8uI2Ty_8)8izrXfhW4D#tamFjsSgi-Vfm@DC|$(MR} z>x(<(miEp`kyldg$y^SuMA!{sX=7xNM*o;AU&4i3w{DveItVJE9HEq1-_(#muhgAGIfJXt`vRsRVCX1y+exdZ1k*={OXl9a#NFkF)~ z=LyLACwW!6^X6z-;bZQo0V6bJeiK|*a|3ngebdA#yfaT72&(Wrn7o8S(Ix4MP)u4WKYAfmSh*14B3}#*6?LNu;3OcGqGKU+{h#Ttc;67p@_*9ORKS*`AcGrVzaYYm`0f!k$Lpr=rQz!NU7Pao#xL37I!mdqnugGcfi= zldm>wcVlBZ;Uo?y!mHGC0%)B@{Ln<`)~I|to_II z`AgL>>|1Dyw;kS2crU;khj%pgH;e)NJ-7eKdn3;qkL32BFkQy~Q~Sl*f2{q-+W&Iw z;p$XYsv?d5bw2#xYyVqx`)~eWto_H@f2{o19*$S1xc_m$;`k;R4NcdX5m8??c#`SvM zpKfHfetEID+7R{(ej7sKqYTeVTEx}5_+>1b9AUt#drJE8p6g`1lyCWEhAm(hxx%#&NGRYLhIcWE8y@unw~PLxK<9;`w@iCbz0<;0CpH$H>HDHl=Ox|5^&xoN*g~lrTJP z;?u}&J?LDcoJ~nNKk><3Q3Fs0-WuW02lvjf+$jy@eh?GZ#1LNc#O-a9OsBW(8Ucs= zNh(lU0sG-==?dwBt2ckc3YR#HaXlxe)H+`Dexpw3o1N^Ss;Z456@LcpAKC*?zVQ6wV zFd7asA{l731%#6b-wPb+P92Wd^2fB3OOnv!yU6E=cCmM)wQFK#Tt1XA{&M#30T&*U zI;Dp4*2bR>Yacmx~e#LushlawGKpIft2y?+YWDOay}t@4RTlE zyO6zW%F%ZRE36Ag-Z|{wryR|fLch?na%DNv-Y#-p%rW-`2Xux*v1w};#P)r~_I-Ib zisj^`XJrggE#q3mHI2KlXU3@YUYB_1`deMqkTu)ZPZ(6!o4vG^l43dRMrdJis>3F(LdG8=KBIkp=+^=nYvhV+pXa7#^5(6xx5eQ zCvlNJJi$S9x%@FRUviQIeH0?3%uUVi3_oW1>gD#x1?Xq9KzpA36e%7lLB>kV(eN2u z#y4r>Pp@$~FdnANo-|~r$q}K@&6k{0l?^k~OFPn-W}Zw$ds4!y>G*%_T?w4dRrmi< z2`z7L%lnqM^i+yULQ;RBXUy0lh8aYQeal!HV@(<&Eh=eMk`zgj5RoL=_b4HI$iDB) z%>R6U=Q-}ZzvX$JF^J4FpF6+pF6W+m?z!ild+xa%?f1%3%)~^3O`id~h2Yr~SVU{F zWFbDA@Ex>#rr!&()FD3hRAX5Ry z&^dwT!DsZ8mQAgoQLb}!Y7@lao~LFG3O9g@^I^+dUoAR8Rf}ry+^j*}t zN^ikgSPRNLUR6VX>*W04AdrQS8rI&o+Wy6FRf*}2_Y5GH);1s1EttWXs)hI?65&*O zaIEGO8#_GZ$1vbaXZp^+SgHqjCB`@KP_I!DzWNwOPIE~g>$=!;|f5kxfugJ*A zm_MMzy!Y>$^KP+OZ{NFi?b<_!4o!RGuGzC^XJicc;g#Db^|^IIubaQ^dDGY){~O)? z`oo70XB>Vr`dXpMFBkZ(cVJwP8#C5D`{^^6 zW&GOq$czSq+vINDx^>3<=DR1?8I+VODJg05*lGixzWB$!1y_9$_d$!CO9wwRpm~lj zyIeE8<5ff3Us0t>l^0%kVcD`}pLU47gQ}FHQI(2u)=QV%REZw)w5wDXLk{jMSrz8A zDoZ!-u@8!-i?&|bGkE#M>()OucyOVfH{Kc;IkM1(9=kKzz467O^$eaX0@uN0h9WcBw&UKliEZHIsFv!3~6 z@vI(m^WITs&Ref1URI#=u=r9nZfmgrzNSlh*UQo8^TbMZw%s*)eg2G&&u?tHdfe)< zeHtEYwCwTJpPm}Kw&2hQYNubd>%*c|7ZZqQ(f35+rDLq`MzU@{n)&RB5FIR;{Q8_P zYX0^^?^R>+9ooNr%bM9+7k520Gw-VTBlqvxxbv^ym(LiK{%4zvMR}J_Y`=5!?=uI- zZeG-V?ZUn*roXUi_JE9Kg)^1~*3EAA`?Owbrl)M4-F*ItDy!!YU;26e6I-6j*wZ>= zRq>34xiZ!VGmiAhIFy?4N0H^jFIzhKrG=xLY@T#|#?osumi{MWd;N^`cXltYJ^S-2 zd$z5bKc;iW@Aqe{E|GDld&be17mg@-?C8Ore=S=xtwYA*D-W%#ym!m6j6KP_r{Az< z(Wu1}UrJx~*skd}&L7=s$q#RAUeYgPX<*@~+6zZF-#G5drBhy6Id|x)>AhF}kofDA zm)0*Gvw79@`QuZM9X*su)U5rgpCU zPnGSSt9FhYqf-a>8~xJo_rL4)+1ukTe=JzL+EXz#D%UMv>(M7K8q%j$LY2oW)~UXB z>Q!y}zWL3|UksRd$-uTPo3?J;s`+l~zwJ_zJ3iB){o&NhI(O}IU(q8+j{UTH^Uc<+ z7roH)<$ZM2!Ky2MUj5>n4bc%)37(@qINSkt~IoHsmb+DftlbF$2e*&yFOWLH2@<0<%l? zt4Yt2GxP$^xDqo`JZM31A`AS2U`DL}%G>fD-a=E?l=cwf%5!Xq7h}tX0g@mADQk}) zDXKS}Cw^Xs`X6rR;OQ%0;UJolm8_mjvNmguq*j6(=v)VX z#qv(!&v`ySi~I}v@$tf4gVxAfv-x;7AHQ(;c|>}j_$I1Ad{HbKV(AUE@b_r%q;%Gz zbDol8-4LH{P23tf0dQ<{O%H-zk`no-EFP6_`G@INS!v^`m{mz@;g zYkZQQos3FrY34bLdMvk1k6N2n^)+p{%yLRw&2@ghxaMo)49T@bgvzc0z zq2GDMd6aBn*h2!J|6bXuM_7uZGHTOmd3mx~Q$P5!o2~Kn;Bc0EzkI--ueTTyw4R!g z&DXQ}`h~;S#gE;b3d(-BD*2h8xWjF~`$Es46Xhot z#~jBwzSIL&#-@cbW6poKSmrE2euYl9xck&6z2BPl)P6Zz|{z+zI-e0@vSPA6-#x9_xM&Z%r|Z@oDG>kSOV^Yf>z%C+46q2yno@y`?6o}re;dsU$8f5ZN4vP zJxFuo%FojIlq*eLxmnME zeO>_X6Y$!5q)v~**?+O53zJg`%Mt&Nb9n27%!D0(ED1QrN$j1&sH2~c=*(4cgKJ)j z3s04S(92WF&l^g}$7XFpML6E`+i2{*vd^!=EH3-}D!+Y9qcwR$XzgrWTYSO#%ywby zvFel$T4f)}mT$7OS*oAmgy zbImI+SYAO^@jAIl&b*2z$pbP3;wXzEb@CPVSvRMXyRr7wi0+>uNeXWyjY0+1U8awr zc^J*dt{*$iK2s=(t{&rUfKml=Uqt`oK6_;*nHRSRofo-gVY7{MZ=&-e*DP#opBK3- zJ$-h1`keIidFko%)6?nb#>Mu*kxS|9$n^Bz?c*b-q@@i=OM5FV?Y*?L5A35P>43(U3S_@~abR&z?wo?nGMZ ziL{<4(t4jr>ywuDN?O`$bk^jqwXx}G6VlUHrKe4zGbq#3*QKXVPfz=a&Y(0vU26~ z87F?pNZXo`u`lDqQaY#d!w;XBFrjV6iDemS+vm;ewsPf5_VJWEGfw<0 z(syN~@8k0;2R1KOl29M<{K_1U!>0Sec|Y`D@o>%>*9ZT+^69smj$8Td;~$i)^1m-y zH0(DmaK+Wd#+P{a`L(P5DEZp)rPr+ebKw5f`-^^DZttR{OD|g)+n{s(jMSRtuN-lI z?9aD-YW@60v9GGNE&9RCf_HpA?8BVDbiHQZfE73YyJ++AkG1aDr+xRBjqm3!dT)`5 zEhfy`zW>!5ugUT5rnR?CU3q)Xq$h8kTI7v!N9Nvj^^IdHefaey{nqX1Tj{~;;>zW& zFuL@OG1E%*{cg)^g*JZJKhLZUl`2imy>rdVcX!X~e`kS04KLo`z3_mAftX8f%fEYJ zk&R2@K3EZ(GtX^LtxfOI?c+K5Z@uNx+ulDsASpffue)RV9{F}w!G2Y)>2he?-iK$r zRJ&8hB5Rvp_TMXF`Zie8{Ic>_mUyGu&PdYw!Lod-reM zcVOGT1Kal>+;QOGu7ihmA3S_KEp6e3&5Qs1Ystnfzi!&PZ1c9|TeknPb;s)MyVma5 zy=7K5*n{r*Gyr`F!@SgU7}!U4QWCv89_2ui0_* ziv?>AA3MHm>(Q=b7ZvXFZL2TmZP|Bd?2@%lee}boy+#I0dx0$v|!(YO$X!O`~Lm!e(wGC)UvOSAHQt#w6%wS zUU%??iA$5eUf6c%53?7}3HG1-=k9~wFW*@5weLp#c3}QrN5-w(HFwM5F~9vac*))u zXYKl8<=!qcw~bo8@A;p1bey{V*=gH`F5COWq)khf%p3d1foFc)mNaE+`=7SGzHn#X zc{^%-x9N+iGn!7`(&+omH79Hw`p2GbU;a3C-M-#)w%47wsoMBIC#~80$hRAYtk_fW z+w~o$Z;czfe(;LjHNN{ZX6(8_%XgO@vu@MD<42F5IC|p5@e^rj>FKojXu&h}Iy?KR zy%FR2N9ep5YjcaEmENxNst$W_?SL52cV{3gqWK5GAdVNte z_b-hWEL*&x{^4Q&S8jFtNe@q1^w&LyyX{UWl&|(%``X_B+hvbj_et%y7UUbzds*>P zw+F8J>Z{f}Z~Exis9pJA`1jSn7T-N%V9_4sdLKUcuj_L!xjfHj(=T0d%d&DcYgcM9 zYR~$AFKhJa&VGZx*i)n9{9cKN&3Lp_+#Jw_}>9PPPt`B+2_7^{+6Rf_D+7O(uk7J4XAVI zuZQE}e(AgI$E#MoGQD%zx8`hG6Sw!8U;2I%-@e>cXzsAn>TM>zkdC1zy0>ybI&bUu;86{-r2Hc%gXi3=ln5! z){37Nt(@QLtHcT)-u+PjTb~+M>5nxl6Nda>&#@_E=8agobm<2_y;g0|{XhTqLxp#W zFI)NR(CGu;oY=eL$Yzt~eLM5_srSBoL*H*+7(HXems5w$Su|_mk_B@X&Q5$k?x(p^ zzWr%z?JktTX)qh#TxbP z`O&zQSMJQnc&FAa?;qLRW%aX9Uisdpk;Ot=|GIKDzm>qw|}M-8$gk z6}HFDxogp(2GxfRy5Y87-wrGFcFKTn%({T)w@>yXZnWY&sJPEuurb`H{?(M{jw{Po=hp7 zyWT4k|4NJ9viXVY_fCJ~-eLo;YBF`iQ~x@0bko{q$B)gtCi&W{lY+nBd#u*lhbN@9 z`TfU3LvNciXF-iy{@OnC>)~CVUHRhV*oy0G^n3HoF|Eqwe>i7G>f-YIHjZd~_v(2o z_wPKO(J;7e!_u+M<0l>ZYWt+s1y3yBS-Q`i4_$Xxfr-_(Ui5ISZ5P$(a94}V4_*J_ z#eH$Mcz#i%+AS}h_|~YZZ;r});;rNDdVQI;y5h)bFJsYjNU(Rj+8#B^F%&-+6iS{yJs+uRnjk zxKr}-a%DGmY`5dB-UmN>^~lIK_kHx@j#r;s+u-p7ueCbRv);arRSvWbo_PD2!{3kI z)4BS-XW|aDDt)j;$>U9n9cohSSi6T0ywrH-3+?y6-EEF#Eo#?lRjrzPyCocHaQD%= zw;X?_+@Y?I9ZSr2y!tgK`X?QFztiE5o;%VunBMQ{bxj+jRk>ox&_RFJt9rD>1Ao+b z^x%N*2i|(-=r`{j|DaRG^sg7zNj$dr=T8?t{_Gs9`TMG_1oprR%Zzp>EwE4veo3Hjci-06>Jc}6M(slDh8N0t<>F&s zAHMqP!S|l%w(_sltM~u#*8|n=INoW_bqSAHx5QVwbK|rb-~X6&U9R7j=KHGJmk(6^ z@|I!!=M+tS^hn+YzqWYv!G;Px%0pO@q|)0?!M{fWxxNo@NL%POaJIsJ$H`U`Gd)mR$VH}hSL(@8SNuCZ#|v|+UH#eW#(VC(B{AQ7?Jn)Qd*$2K{4L+URp8}& zj|axz{$AULdzLo;>*7G4d>^iRzV1!CF1_fEyK|PjJ^0D8A=dY^Cft>)=hv^6yCl#1 zAFSDY(dF^0?tOp7(PrN~w(5WXTiYkK|JT8!W~+An+KZk_Yll0Qp4)v|WZ$J*Tc zR^?sITc%%?`{vxGN|!1-=Zdt_wF))sKQy`gmRs7j>)N$z$J$?|m2Oxu$KI}ErpM)b z^xqFY{P34gJ@H8Q^liU)C|39B)vIcD$rJ2;y#J@mA1ici<2!eC{W0+Y6!_PDJ?{ZIF_d${YO zRjaPc_vz3%OJ=p0((H|SGrynFb=blk@7*@xiLd`}%|mz3|G4oN6>k6Vl?n+f9(kcr z`?nsxEq}R3AO7gdTuaCOIN-gsKIztd<@#+|TcSaq=-AZ#yy11wt|B9h1gEg!mG%@Z z{zk30Qg+$DYz$;$AOZ&BM+~zLT++kpOm+u;`|nET>R}b2;5-*?RYt0nL}y6cL1*Ul zqH7#o3sab!qldNOXsY!HT`QbOwN4yMwdPY;LSYESyV~kuO{ME>`aX?9SxWODg(394 z8ikD%UZm%B^lcK|UqyMWr04(8bta|jPxpE0z9ij`r0a0HrqH|8O9@80Uw3g2YZ;Y4 zg}xo4vUbsR72u)oljwUY#SNqrTy%ek!Yfp_tLb{S&PA9@`2LJw=!dc?)TaAJ6rP}P zIXznxa#0A-b5XipOV=6kR4KfT@g+y6(0`u~{6{QLh4orBi6N!jv$w)}tL$p2#J zAC3I~pTg&F|DPS|{|9FH_y4D9Uqd>bN#xY0T}^VMmp(0-WKihSmXZF$OP}^GrGq}L zJB7{^{PbyS=v!v=X{9MX^l6JxHU;R@Zloakv@LY+rB9nix}3AAPs^77z4d9ssC^>o z)5cJoV-&_yn;oIBkitF+^{Cw&P}oRe2R)CXYgf8XC0cuz?hjC!+4Q`e?r)|0c)Gus zuG{E&CdEmo=XDh1oY69Uf>DqE&i)_Y^!(BRKuxhO#0OU1;m-$d{3&Rq&CKQl*>b>z zBL|2c;JX|#R-}1=Qx6E)0pWc59U(qYwsp{IwmWDQem-ao{5@!Gqy3DxZ3v#M#uHx- zvlfy}AaO1oMe&GV>TxDhoY&}`#HsvB(7J4*87DAunDxqUDo*YCLF<3h%s9O$&V5x> zoOkXGTB~k0rWcyqX_WS{V90{~ju?4+{zdHRFPchrlckHc)zt2u&kq_T@d_GWn z`UXF(@Bk68y_S}uYc+Zc|5c6X+Lm@1!pj4ncLa~C@R;9(d~f8XT>{t}37dXg;Zv_I z{l|_;>xnZ1@1sPe|mq^(iI$F@Wb4=MGK=jPt<>IbA|6E~l~J^dgj;O6s|^_cn>q(|+&p_bBADgJS#hAOT}AL={_ zz|Am#j^Pzp{XiSo-O49msk3m{GedQ18Td-T&Q$n|2%JnPo))kJHId%KON4wi@xtC% zWH*i84xp?0R5pBXsJ%GIt0qxBms-x=L0jx(x%!P+j_KvhT@HU|KWaL?@q0cU8|~8E zrk&`aP!O5$@cBpn_2%#JU2}Hp3y&UXu`^Zg=625h_2%#3J<-n0Pq|QdTwd=aPT-a_8=d3 zTbuAGYKs2O#E&|E9T-sl5Zyh3dmTnUKU_I;fUiT;mV0hny^ zGMe+rq{>?tr{XjW73hLbqvMm@@Z6YagU=||y~T6d1gi%5R>Qe-P3&}_DEY2V>KHtq>4ZIz`EPXQ1kCw&H>-gTu?^^?d|e1N9r z4E`z97l{qo8@~0_7k4Qt?`UF6PE5(bPqejB^-*b2Gq3k5&uCym9*>jnwp(#SKk(Um ziDGyj0XYD)rsgo_cl09k$Yg3ioioGBoO!Ngd(QskfAn1Z%y9&5i1W|*q%({gD33V- z_jrD;Z%h1*XdHp$--ya;5*l@$p)`J@Na@flvoggl8-nCi%NLme9x^dH0}{N84id`( zEGbkw9hR))1Jr>TEkgr(iv}+!w;ajx6$u*55a3S@vQz^7hgY@ABoS2$;R_d;S5&rT z)JU-{%B?!}<*HN$`>Tmu0{T7p7Wgu_`Mp#t<`C$Q%sD}0&e<^dX*0XeavY2*XdQ4@ z2`&?b6;`xi@Z#s3m~`a@3P6J2x;=!Tn5 zdqHix5Ej7qcw~^;pIXfrzB{N63M#IbKpsbB0b{7oz0?YfV}?e+6d3R)v- zXRj+{uPak9t8`P}%DOi~c~Irs@?d+@B6Nc>2C_%3`0@7SlGGlj&cPBJsbDP0T6 zezt2;p5VM9&v|J}z`@mN2?7CMO?k_V>DGSmcRzigXp#I*cYr?L=|xE3HsOdP83%r3 zA^$+)0e8pzSxRt2=GKVn`bznVk)ti)l4rJUOjH<8N_*ujS#)14n~5)AB=*9+nOYU$ z^&Y;9riOTbyRVq<|9Xx8dUA&!g4Wk%viW{C-@kD9zN{x-TsCMex{2*dZ(JL+u6a4= z+E;R4p`g|9sq^!^2wuyKrI}AH8b?@nDBMH*v9%;w6!Q`1cQuyiE12%}OXO$rUHG<7 zCMmix1!xMnT<9;cI+$X6$Cfyl|8e>5cmZ3wg~pckrqB!|+oKe8AiO?Y-!2Q!(7Wi| zT1rsdp4SVc{^73S{nRo(p_k>F1!z2wx_QqK!smxsG2NXX` z(#$qMS^>=8YY}AxG(=#%Qnd)M%{8pA)zG;j3|(${dvxXYjxLo&S_Al7=e5RY;WPd0 zMw`mA{r3gGRr4Wh6pxG7f9^jn-hU)$O&gg#E@qF57tXl&A?-iJev7~?HhmU~363iN7I#UOU1lD{~@Ahmn)Hc^v6% z^>npp>|~5Iwewf&0-QF%9$ldcl@%$epF3}vNlFaNF9A2|#OraqhRLh+5=-P1XxcDC zg=UvyRHZ9R4H6euJ{LBIpl(7rGydhfekQo{8|IE^(PWxIHlmXB)3-(5(Q|XkHTn#g z?R18*|D4 zMF_bw%(Dq~-juR*ZE%wk(j93FZ&VR_snno0nubq*3eAfEaJ0T~`(iCfYFY zO1|#l88paRcu*wQrwPF)b|GvRkYe+gTO>2>%De}Bg6$Hk6U7T>k!XdiyJ&5Ze@^-` zsiTY}v1MoUr$FcpdRO((N*i9G*J5={f5-1(wFfD-E^&BBzi|{7Cq5+5Umc1M`?~<5 zp8P?+hMW#bxt1+!*VMkDoN(WvU&5J0I7=zfkO@GfTgXKe|xzm~7 z5lx-GffJu_ew4X7$$3ED#|a(YafFxFwr3Ww-VG4GU?W+X(gZ@#DE{LYPb|vN12B$u zp|xlI7a$117h#>L)=@zLmFYYuUOl~s&YseL(WKGi>y{dLZ}MsIUj8K#w`417eh!e$ z6s)FLN+?LsgCnTX9TsHn(H>F|_$~UMbA=z4*UXbSH{BA3txDXmfio~1AuxR}=8TdJsU6Pu6s?j6GsIi_Kg8?e4O)Xf3t{8da>{i1HInGNH%7bngy)j_G zj#)FtJdC3F0e-Z2CA#y=$&MKMXO_(`^`3)%0KTC(OLS#C~b2?uYpazpqRqHTaY|YlPqH zBb^>!N!v~Nb!d(X8%xd$b~3QukRR4rI}=xi6uTZ{4A0C8UI*MM||)yMMo z$Pkbu^o76U1;>GO#>?G2K+_gS+$h3mAgH84qC}>%Zi$%yR+Qf zbe7EY?|8fme9ijjxI6sy&xiU3t($0lDto_wsAPsnd6T)1N$2MYlq)3nN2!!R zC{vSXdc{!uFF>jA7ekO@mIDr3*{WxAT%MszuAI4^8{X8S^6`T`;*k*V!}H`2|7%5i zmi_z(Us5Azjf&0Yf7$Z>g(L5yZ=B1&xY5I`-E);6fR&F0t=3abKLEV`l3+{Fu+eA{ zs*qaqN+C%S(z?D*)|fa8ECN}ZZLVEaBdHTB4Dwdilpx1DB}iu+Xy#knsUf$^SK+IW z@)^eJB;m`BE!6^8g@XnhKkN&D#kkn+OI|v6mUk!>JMvmn9pzmjl?2^A_AFv`MSivE zE%pw`o0>KbRBdDIG|+xy&kQgpF^R7lc|vDpO4%wVWM!;TU@r-*Iv{r|d|>8-9d>vt zX{ypQ)&M%t6)?+t&Ij^8YQgg~^$jx+m9JW-gdEN*M-o?A61l%&ohpHF&1IpD0S8;7 zm?bh6B|a=^)EonC%l;Gu*Afry3h4EgkZ+0fmUp>1v2784u{Hv)3b4e*Ob&6d|D%o# z9rhgRd7@lr8uSeDlOee9il=nDDpsu!%mEtFd50rftU0|^Kdf<}1V9F8<(u<8uq!i0 z)w&jq@n(8Z75X1m$4zWnBw1iz7v_0RN?>|Jj{zLcHj}=DT@qM*0__Q$kCMh6UK8A3 zkSC}BEdc5@V_{Y6c1kB}IlzdyehVnu(R`V&GXI5q<6Om+Z-|ex*P#RDRNnh%!^va3 zb^(pC-#&L>5EK{9u6J4S^v|oUjms2!_q?JC@4L*xt?$my8q{V^nS+^E$=Gs?y;PVj zs_LqbLOO@Pm-OSHOVmLhhmg`gO=4)*Ry6tRqe3+C-D6yMSi+Be;nRYvy2nJM0Y{V( z5q@C2#ze%E^;+}~SZlPj$6@zgJggmI%^99g+R)k)`YhI?p%21)-WLuYruL#?e8N6y zFI^DI*4u}78q9^%bZBXVg(yJq-4bVdUUlkKn8>|u?-BPD1;>Ip1h%@(*+ zQWh*y6%K_jODvs2rC;M7y2&Ag%YYIS#;Glzw@ z0oX$|v9Ebt_HHI+phRhBDPOGJRDR6E+3GEPj*J1xQSf2r7(O>?C7q@)Lh{;&qQx@Q zC%mw&r^{oneR$J+6QUE0-#jYulax}3u!pZjh}LD6z_n-k=XT=qVbvzRLsq6FHFIcp zO27EP3}gdH9?%A`7YG?MixSm>_wz_0WpEl3&N4K5nf*gb496$*{>p76ZBd3w7QW)1 zNAuX|gp1)5eF1W4Ndcp%-YVFIfmJ2gnm8>pAw5C1)#vQsK6tBIil2*ws6lTHv{g7P zDO^e(f+crK)smU10ZPYQ4l{9Od&f|ze#f!EW6|ymLm8X$zzqbZXt5T)O!j`p@(srX zl{-rYhE>UW%c6Hld?$q#4YjULM~qpa0;g4PWWKJXOC?pp69MNa^eH_Al%lju=q=FO zD+yEo3dz{1FG31^Z1;=dC#wNB?88GKJH7H4Y|$`F(d||H%5euddW53IPo6Q;2DBU-GW-sznf9(2SPmsb>X;zah?C;D{~7s z6nZ@Lcb($Hm!zl}a5(b^=fvDve4HR}w2|~< zmeI&C&iG~y`u;+H3`PTOEY(fvdl}k>RAbgL=nx~ftVmwypK4~JdIMuIk7mscjPn?# z?37@Nyik(uhS%&w_MDMMcnSX}s!K&`k zmeL9=(VFeAOSEn(khyC#a~dZ%V0r=%Z$v!^+AH2E0ICAkuy+Rb{XB*$&Y)x?w7c|J z1sl_elG60vid6t;EffwEJ*k$G`HQo~0NJT>ELEalJsihknnF#06V>;y3KOusXBMSv zw7uCWb)i>)vxt<%^EE*2!)P|!Zrs+h&BHNb3A9X>S>$qD)#YZ1-V@*ot?dr+t4kY zgUXoF{3+kNN2<0D*CWICDKlsIP2=%d<;~uwc;_R_jZ8)Q`0Nk4P?_Erm6YM85Ivq# z%7AuL{-WubYHgHzBX*`?S0bPlxK5Soy(v`smKV=+@;ZHVf}TT-Pdp;1KJMMac&}5F zh&@eVL3$Ug^1U$;4IP8l^nD!|K{7*QLScZxX^SfKWlDeNCUu#!0pa+VQDL@)6<@YP z_@`2sj448$`dpF60Eyv^lW1rSDb@TGQpKrKn}Xrgd8M?d&ZAD1m!Ze#GKj1*WnZ%~ zkd1+C3}j;<^BCaqfk$7=r!e0Xn+@zvWa&cRsc4qrOz$nRLn`&p138-dD)-7;Vo2Ae zWCo{x_EcmB8Es`eW__A-B=#!FYb18BmMIM#bOO<8*HtRaw0TVm)*7O<#|%K?K+ePL zJKDVUxeIFoIe*-Hm7tIOqNC@y{6$Iaa(+f*n#o2FPh|OkYw8uxJ=f7!1r(M9R{={- zG-+bPDD_b>r4&DlGTnYG57qMA`th7tYNfZRb4^67aTNTK`XB2aoHnVVv1v=R!#!Ux znDyT1T_Vr(SX+YTQZ!)}QjduUyX9vn-vGqyeEcE>8RoC$=JX_$K!vg1hUg=r<3z3X62 zlXY3pu(7s_t<=2o!0Lv|gP*tr{@4)OT%`yZt7Nf0n?I~-Ucc!SR}w3B37Ux(~R53 zooNRa574HY^L=-0y*1rwGLKizL)qNJvn21hHEoIbt(>JG{1az3)S}hf$n_RmcjjW= z_VvO&n-Mm_$8dFG#9XD*vEjw#m@l$46Ac7v)+snZ1f?e`FhRR)L+6Gn?&b3gl*71WuZy71S2yr}yNrwcb zxXbcuAISmsA)ME#v<`R}>%1iwH*D@UGA&KQk2TUpup(FcNVsLNVvoG|s^cQkx~~_e zyjsO9Rc{ObvNP8XSeul3u~#7AH1qvLwS+fhr>7MX?O6uA3u1kgEuAs)rqJ92Z!sU? zyED-m?$Y%Zk&?Y($Xu(SZu-t7Rl}^cjX#W;Yagc#hq_wi*nw-kn241@d z6`%65)ygWD@+whp6L11&xq*}RJ?^o>*)otCA?2~pGUUWQEU~i^vwqnn32Bx`_i!x- zXmF+>b2%9|kg|xKzB$PVZ77DajbQlYO;&g!m+8cXPD4x^;YKF2y;-7$UPf6bu)i*R z(fw-5x*S$d5no@s^xm}zYSULRz4vc&EU`Y|vW4o=(@zhCrO2vTJcR1IN1ZU1BHs#t z0Y32D@c^Z+V?$~lZ{2W5mgSvv%6VWkLZ1%bOLbcdjJ>j72N(lAsIz2+TY9HJKSK@N zX(GYzgdROitUm-IcRfrC>w>PmqoNOOOLf4!4}C|chOF`$=U!D)H|kevw4*N4>pN+| z9Y9A}>GNJNWv<6Z!nt!_FLQfUuA7#^jl7X$(&{c8#oBThytsn)b0wuv_!nQ0ZQp70KF?A_)%WxZwGaD{Ih zr7zCD%f>)92C^}5rZEsnuB$-25Ob2q{z7$hLPG|j#(CDh;R3v=S zLi@vI$}WEJWfiBulz4-ItPg9r@V5NXw+h!>=CpbZXjx0ypmUy!}S_{hT8aKe?&@*MX*|i7ES3B0c&)< zLolh&f>0;v^X^*fF*B=6EJ!QKZtq^)x}6DTcv(55*;D~;YV-YFyTO!s;rmyTT@ z;(07U@L(@Vw6-zKIo$9loRy*6^|o>Ds%uEH3Vh~a-HCN&^+QI&yw15M4?60_2Dc@p3XGjgs*otC$W0+6$5wBe)RVzOUSg%vQ z5)@Zd)}Y{p1&QLI@i+Y=h>b12h|Ntky7$i|vLCPL@@eLRCfsPp@adi!qTA~X&rN>5 z8&n;oMP#osd&l72`SJ~1;dJd~*L|o(hb?#8!6(t_Xg$-nQS@}+Za?^nFz1)Lypr`6 zR2&w0@socWVigCgd}uc>z6$9EvjfaIWK9(|c3!*9GcW(B9ogaJAK7cJYN7fp%4DB( zXnXj`l0E0ZJa`AV$Eo?oP~{1A>%5*NCnX8U>MCkt?lqV37cxOOK6V<|?m3+WT0{3% zW^(F++Rj)db!2|F5MJhR?!NWwAO8KpZS@LC4=Y<34?u5c%b%RSb3oCm>Kp$48UdyB zD(=;68w+`p{ra&STF4&Zcpie*J9`w2*$cE@IB%zj{U5V=;MX4ple(aDK+lIgB*t}? zHldTi?0_ju@gM2oS(R#ao(rk~FTkJJ?|@rj&c}4E+KOclmKt=c3$JlUS#kL1lt48! z?Kk}VLPmm2aoBJ>+x30zJcj93A<;=8=bEpTXh*(q8dLm7 zE{xh3g}I+{KXK>o9930s(!U5NP*A}?2}XQSrAi}j!_`;UbD-bxd|KtKmy6s%!J_97 zIJ~G@QK5|QPHObWmGo_W^hQ5q*i>m=@tmW)K7UcQ63oC03;UB%{Iw9(5pBvXEoFq` zW9RfBej0%@$A7m^W^he2j+)J>nH<{BiCgBTETziX3gAlStj_c~;O)UppG*10@S8cg zeXD^gSTpCI=VIhJeRC%-i@MBU$~gu_gDaimpB|5Rg0D!klsv9kif+Nlcs*7A;BG~o zk2v`QTF}2Frc<`86#k>~2X6#d=lQDGVk-V9`U{+8huN6eh>B!XnIzB3p%ZLRV>dl3 zSwXsNPotUWjqohLaB^KcI~8!Ge1xJW$$K>(@hF3DPQ5axReK8&N6FKQW4q_VkZX8{ zqT81#Ljc-yYKRp~JY(Q-$PZ$s1HdEWq&@~oDnBUvrDefx=C9D!>9RFWlJ;r=yj68o z_}Al~3fBGVihMJJZ!h>FVH;`u%0FGWHpe`#aZ$BdCz=m|SA*hFdmdl-JHO$3`HrVN zE{ZfqN=RjxdkI~l&Mdd7zQ7|a&mGOw7-vP2(_31o7b%fK=s6s}RMdks0uiT%?%jKRL2Q+idyf?^j5KGU= zI(OB3Fxt+PIttRhcJ}coy%)SE+wUXJvGK#i`PggSoWMOkn)EDk0!tszEh_* zi0(d`9*g<2NHHSeDD9CKPxsSRx#t9;&vW{4W-g>OP5%AeTk2BsHP>9_#5$|9)06$z z##qnDdNaMhyGLy3@11;>dww3Gc+8|k->&P&z5F1cF-!l`$7kV4ku0_K^qHND>hd3C70e#>{P_NK;8fRy!yZo8RePPz$I@pcYXpg< z%e>)m7+zXMZU4Rz|7=MX=T|x5rG>`SV$sfs)o2xsRIY3G&xS3qlLN|Xt&;uK3{o_b zn47v!l-Bv9)As5@J4ssKQTF%Jy=f01HgMAF)rgKkaV$BhHrI6-rrn#;976l2Eb07n zVNHgfO9Dx;&(Qh{#wPJg7AY@(dvrZ#WuXt~bo;w#tcXwNPNvhPeadQ!Ic>lr;h9_B z-Dchv;E{5RuGO5{r&Dh?mLs6GR#JtcOs8ZMepEhp`fz4Ahv47$G|gO<~thds`-8?6_Mi8XZ~Y{Q^26(0je2Kb>j- z2lQ}GZQS42*S+b@%SU8pdaIuP@1Z&6l`~vV%`DBu5(mRf7ISZ%;+%ATX6Vf<-AQd; zFq}KI#(HI^K9O~i(6;NX#3vg>Kg03LB^s*Zaulyq9&O$8hw8*fb*gr^zM{A@(fX$E zE^rraZ?n|1-`;L}7Sn$d){ml{slsyz^d;C)7ESvlYb!`*Pd0U9u$WZy21s2Z^`oVP z3P6Esq>?uDPKmw;SV?>xbemXZp^Mt{{E6&tb|OMd^7&Lrv(1N;{JkT9TajD(&p%ZhC3qW)*Vk zmixpdp(*JHLd8<%>EK`frJIx%4hC;t_IFSmQ?wu5$+>CzIc%AuI>{j#ij%l%l*_C| znbJS1yyQ-3AnSA&uk}Wm(R$PP>7+NaRGrrR%RX1=%#XgOX=R{Cx@rKssz2>lZ4Wko`o+8g}Gzv zRN+n&Nh5f6WF|K*dDJm|HG@W!=ly7C1ijVFBRYCf=ccD+g)9KHR zekS8}RNj_b5BlRZW7y&EkwZr-Br{&DMMbk60}d+HLCN-0huKt)wgbU=}nyy7fV_u?-s7(#aCtg3#T~^ zFJXC?sE?k0<^G)#RaSd4rw=cIB!>K_3I5%!optQ1GIWf4mvs8@?Y;i*JedURw$8Jo zqP05-msd1gPe0Ws{OX6Zq;v61pXl%%8S+!bzF*GKw1jznm)>LGq0qUuUx7v$@OC+o zEU^AJwsEopK_aX@4OQ@>TM5>LC2#GIR5TFOnqlckJ8H zTO)E?_+yh>#v6}kqHU08czlAkvW`)=yoRyNJedZwE0L0-n_HRbqv=EXJ`U$RTwLuYxqq~cfV>62AXg{~u|@v`SocG;Qb2r?&%hSC)$ z01Qrlu1;A-*;2~ca7^{loc0!8Y7z=jy@hR|Wey8Cd5-24(`ko=y6E~7r&Lh>Z#e0V zJ%eDyKzV04dm3Mp0?j_{#Ew(y(XAYLWOlbkG(9`=x{N6k>E$~6xJe5r-D@o->m#;h zpS0879+UIhNW7EEYDs_M&spZ)_^8j?@r-z4?F8Ki=v03E&7=o22FgZh>gSzC_A!~f z+0F5ETMzbc>(!Sq*6a09`QS{mHn#lCa29g-uU`D? zj*?V*fy;>xg^9>_)ya!u9PP5JNu`vt>eByW_E}KH?f>_k%s_N1c)^-j^V~0qs8b_s zOxQ}8zltQ=$ks-|UY&o42b*R5oMRq#t}=gRy)Ca_)u*(LDFw7(4LK9-eIqN>bkV1t!T3d*)P0$SLy>>3ieu4Q1@im0KNaKNvmO%2!~()d@8q ziKmu;ew+OuCs;K|d!_%}u!k=N91Y_E=<#;@KYU9A#|kU{aa76GC?B>#$4U@<|FP!+ zv?J%Q;^GdoO{{GL&#*0F90-+Q4CS+cFeZTNTGAV=cVpD^Z#m1l!;!NYy9o8eA~au# zC0LUQ~rq-)pw5 zuDWsV{{{?rr)}G|ufO*CXPC?Qd-ZzZ`RAWMe*AbwMn?DU-Cuq6)s&Q!=FOYWp7rD2y?cNE z{r6{|eYR`Yu1`MsWSu&7KKu0Jv17+>+O%oPlqsD%cW%|HRo%LE*REYVd-m)}lO}!s z`R5%vbZFG5QT_V$larGVA3i*4)Tp6DhYlP#uyNzY?b@~b_19mA3>h+b@ZjOYhYuSz ztatAh-g)QEZr!?l@x>RNI(7Q+gZEx}<(1c7d+n1?K6&rG_xktmf6J7}d1tOZ1SZU8TC9kV%8NIY?($>V!}C}DU+nDX%iVe1_XU<- z{@#O^ToU~Ev%7M>Uai*n-rWcEDYv8l$T623Xq2Z=r#`vr%&1xSuU+wjYu-P1Qp+5( zzHW7J?t-sc-oK;CthEnr`L@~iQL9Hk`LCL5wsu;)`|*FR9<;s7bE|$TeB+5@?Me)) z`a}BsT*I!K|F85T2TFGtu;Q}ugYRklub=A#n}5A$?bY>v%2#t>()iuqJpWnXj=UXL z|FHMyw|^e%GbIwqe=Ma*!<43_8YefUi&ea6v7+}BD}GPWVu{6zmMU>ysS+jbE_#2d zqD3DZaC?3uLF=|nS~ly#35x!oodB^*6)njL=Dt^JBqgvam#-E#s$7Gfmeu%8EBB;n zcz4eHhL0X*Rl2B$Rbqb7x@$wKRe(Yz3e_m&PEWORQb?lj%_x+kcO@y5rcji^s*F_Y z5WTQCAmGt}{y3V9@{pmh0-It{Mk#rqS*A#l!g5sB> z`(XsvGAe%xeLF;D?V{@{dX7ha^gWg02B=;q=>8CeY4m(GT{lp?E9w0m6b8||RrGu< z-CG31ateDW&SrYQnBMi9)$*kgX`&AB8B`E*3i4r^t}z0cNaZxLs|-L=v_X_ zFF(Qb8Qu4zZ?90OP4|r`JVD`ddbTL!q7b0xqIA8Mt_A2?gvu>JA(`?TNYCHVeGB@Q zlfoku3IQ%Ea}3pgF5Ty&cL%86*Hiq-bbsx|)Q)stobH(;*6qq?daN(!uu3=5+A(Z5j8>X|pj#V4+&bV=0aPCk)L z@4zRPQM-EaiFYX-_(XRKohkV7i8b^sGkl^n#Rs2QjIt?!PuvLFq5wXzg|26UPvj;V z_u>=P2o^6sF^cMcruf7-D)SiC)r(Iop>M(`t|XYjC+;FxdQouliE{L=5(V&yq7=X< z`q349B8fr)3eoV1rwQjxC{(539Tqy1$sN+vs^F#Yv~Os`E2D|;oF7D! zMrPA8V~!?`?7?-XF*OKrG^J>jnr;UR^>xh&VOB=}^!jz+GR@p>1@@Xql%TDd+zWkRmc zO~E-{7pHgncwLsBuch!H1;6onI>91x{go8&q+CyJ(49h8dN-KjETroYdVZI}D-?!P z=tZF)g%R}aGYWkv45IKNh5i&qQ%I%oK7|t$FDG5M(RB}njT90GklPJuj(3!$i3iBz9Bv|HBSVmzng_88{JGxGxu!Hj7N8t#CCnyx9Z?)-KfUZdt z?xGM!&zmWfqkD_OF-mv6eXn)m^YFGC@tu|pf+rzgMbDTwtnTa2hi-j2Xnp!{(8Y(c z=MAi1$euU&>le<~dBe#La*p0W&o8ru0IfQidVU4;9VFdW2|eCHGBtLTU>zwb^v;wQ zO}Q6qoc>a?Q-U?uTj0Z_IobP4dRc)`kePQ9&ncZttU^{H>v4kTN#f3r(@F!bcUpH- zC?iqm&Oeq!f=yLk>k9i(s3w@!qLfJzy4N(@0Cux z!5AJdcJK5bFPiTPT7y%v#|uAwboO}h&l@k+FArK1N(HTj&jqb7HwUfzN(ZeQiqN|x z((w)nT9uy-T2ph!Sp8ZBtv6Q(tv9v?t!F0(tv+7{Pj=e?`U}Zg7<9Gc2 zQR0Pd>}tq!LyC_dKV$r13jq7&$@kC{;M8xdkMmqzz9TmDTwUlp&!hQE!{km)YIaVk zCGns!!dO<5X4Qr5JM8Cy4ymwJi&ppJh_ffso5Hq*2EOrAP5O$b!j!T+X+w}hd0YEb zo^mNnv1*bYqayv`3-U^!obcrTQ~EsJt24*P7~{sCMI|du0sJXpw=a+D=>IbnZSZ;=HPKtY*t`H`6j*N4gWF&mzhV_AcDSE?VK}h@I-b2gic)}q*3k% zfshUo{?*mb86UP!ov9bKCMm5omB@O_NNK?BGMA(KD!dEq`HgU45cHB@Tx=1`{49N#EB@XuaA+H$gu?TsYG4#9u z0XQ*i=KNqsnV5^fwg@e9r}YrQz&~^T0&QRN7$z*KZye$ z^Rc9LD)0HNE`0+x;-92pT*Q*qpZ?XNCzQowPq-QeD5joP^2KUM4CSH2iIKMxjSe;K zv6$g-;!f(c<>UTVp~*^qKM<1N*I(r?zrRV}uB)Fdzh}$u7tT8Im9Mk>KB=dY-(Pt< zX!ZTkEx%W!IF&v)KjnAm6Ci`KovT{Qg7*--kE1JOd#AoezSp8ySVzft1JJaL!g2;_$rU%=#mV!FnaE zNkcM-w@Ykg*G*!y)828pvG#Xe+vJW@h2nIPEC`EiF#w!#9>4)?i=)XamQp31%nS9e zNN)gfyU<&%r$E=1WGKu`fJIp4qu%Prcuu6$Sbv8uQfMJu96!nf{xC;G*_CLVRJlrS z@YaO6R9jljNud(sZCYC~L@7=y5n2Cb-{8-6F%Ta>HVbjaE*c}m>00G z20Vdtq)^EMHN&KrQ<>_|Gkn;?ccJ-?6T6(IJjs;t#4%!QNtGohNL_3dQjE%W>Yqh} zESxK^v8RN;N`DW8axJ8g=D1@VdSjS5mRWmAZrUB_mJK**26PDRGWUxjk|=ZypO*dn zIC)~`@(^vZnJRp_qP2$A2A?^tgB?CCdO!9dfF`7`2j~rtK_(QO>#5}DU8_^i&s}3T zqzP0f=Je2(`*9T7+FnXeKjwKR ze$nUAJBv`VtnFb~E~OV@0P7_dVt! zMStYENUyQHj_~#y{_~JB9|o-hZ)MLzvgaWe&OBrf*=J)Np$N^tWgX$}=CodLx0;8v zuMxD@5pFshv>v8)h4XP80jtBXSAB+LlzWK(VN8VVfb+Z|xnMsh_+cBmwsx=*$e)Q6 zJDKu;zDM8xCsCbo^nHmEM`Sdwl5}|pyx2PqWMIrbnh?yW0skPsxi$Y5>B!)5wv!#n zv`yvwWqft+K~?%s>}NLPLc-vkp}IEIA|9>psCB2)V>`!O-Lin!c^Jc10M z;vzrnTCH#UYG_1P%MGSZfXqtm)CtY|GPA`?FmS zrYuE~r>7Rq{%7(m_uS3ouU;1UW)A+8ltA>=kwSt8$Hq#MyMEzwHrvCD8@V2kp`-KW z!}@;qZsz9JI$tvVHYy$>D+Z{g@}Qt-SoZ`GT_?o6z>P2N{gSWV5(0}3382A@L(a64 z5d?1mk-kO)s7!pj_k)L8EZ!TR-o1K*e0}&rH_*ePOlW+n0MFq z^kCnzqMdMj9jQ*JlRE5(P6^DJwf0{q*pP?R}1+s%Z|-A_zULz!h(W@);-q+t&N3ySYOdR>s_+Rn(|uE%1v>%bqHE{#s{s% zGlSOlszK}R8-v!7uY%UDF+uC`3PG#(_Mp|SI_W5W4_fo81+D6fg4T-bgI4LLLF?Kg zLF?GCpw*q`ayuUix)B}b%{rw9npVx2S z|M_Z{FLss|^-Nm#5wWu@osaA;sh^&Y`jPqLhFQt6CZ9_$K|F={%9-YK zrOPm%yYwQmbgXw~`P?|FXMv@l|kz_s*{Y*UiIuYSG8vsYAdht zdBF=jK1+MHqjv2>6?9vK|3a^$k01hr&&p2NK+<5Jg2Ed@_Kvvj{VT>8h% zehF)a(0B58PR8GAQpq@L0xPi27#2YnE?=zX^7%4NZOa6GeV=WvvC@P!sMaK-LB}XR zt_!~_Z_hy(GQk1j@p^SRyS_~w>CJC3lmq|xJuFS(^#E&MX1VU~&a@mK)+0%jOBW+w z{#KQ6-3zx!cd;1&Ek(}fVD)l1<#Qe5YEC$^<*XFMn7-SH~e+SPEa5GjpUi-b?(-#V6s zJqB^K$pF~WZQnDqzW}z-wP>ydo6=L+aiChteaGt;ss<9HGW95E*I}ZAemVz39RZ2dL1LlT0}oPX=x`Ydi2>aOEV8hI!!{|1gZSVg zUh$FA)KlTK3WkpDl#7I*7VU&v1EOk`5>ZcOu0^PmF(i*Nr18P2F``=l&YTb^{fO=p zT&0lJibB-pMJOP?f*v*nut|fyjx}mH$3?VE?i7G1x-|xPn|13Lxn@$nYN@Q>ne7Ih zi)uHl*}(#%DXnpU(wL&XFmk8Wjs6N!>Vo#2UrMFZk-DJ1&ef;PX~RrvaF-CNrBw>0 zXX16HtY8;wRLK-T{{=}Nk-KJecc+%I#FKY!+TqBGGWi)Y5_&GE5K<4ucPD4!@f6$- z80|nU2pVioHaOsB4e3o1rBU(~a`sCD9)w;18&K@b!s?ls(myRA0QGdHpr`RGD}nNc zw8QIkT;E8rDUPd`U=j9ZJyOxOTECL@L{)}Y?=!WRik{H6ih6{iRbKjCxPIo&BVf~w z$#qz-9=@+|oak0qP*bd?g5tQ(<4i`;k4tS-ZIQRWHo#bsJ_8O1dY64Ddfg-4oA~9} zZHT^ELhV3w+WKS`CLRS!v;=G~al$0ixSOk(-?0*<*G6&*P@hn|{dVfPkOUb9#p6xw zwxm4?WSAQh3XX`L2#VLss_%HhSdQKY4+5q%uL?8Mhfk5YGJz9)mJqp2uN2Xg35y7L z$ikQd9wjp$Rbn`tVg82HUF?|)d-9H)TQqQCuPNvh_M4EZbh!%0$rruLcBaK#z?~MbhbvP_$KGkp{&*MlDkq2Xg3j!FTt0IF$QimV z4&aj?$E#1A0dqo7h>lN*g|>huB62**FI-P?$8l4(#EC?^0#~GX&Xxm5b7J2a$E$UD zJqh~}Ytq_Qfb8DO)0Ka`W>%i&aTV=RK>vpMS>@2KNyO&8f3YY1rtm0(u@id&v1X-q zz&z%xW+Q#fo~ZfPD3OzLBv5I%KeZV*1bS-Kw;h0ntY!>Q$BLgLkb!b9PgUiGc; z>7CTC_mIq`)cZ|lQo8wKUSl6FX!h^?nLYx}3{Q@xKj}E|jvuZq_0)c2teM{3E@mF! zN#F{+gBVYV#6!d`#tXtiq480TPmng9T!VL@H})NMkVg2w_xObv+%Np)7CjgLo~!cl z?wMZS^`6JtF+aHjFqk-JUjZ^g-5KJb0g~TkKYaq(Y@XgCL+-ol)gS8s~Y)oYGx<|^ZF2vvVk^dCKRet9Vl6n$RK@kHuB~nJ&(v~&31S97dJ8Jz`wlou0rT3Z%9IvaYyYe z;kdj*9lnHWk#+#mUqwoZSxyC#GU2l>k;W?Z^Nt@&B|`qkDm3q;H&a1xfV`dM;2p|( zjDlW@Uwo8+RXn$6Jn#Gg*P|yrFzF=-K2S4ooVS${?N%(GTsH~ zsRF&PN`Jr^JO{9Sw7wI9%M+~%%N)FBUp`c_=wi$`$g!#|Eu4&I!z=3nI!uyMVybUW z9gxI8neh7rt8KJEybV8Wq~*tOi?qUCqHt~o?qKH){OCW9uY21<8-ThVrM6aa15~o) zs_+Y3^6H6qDy9o5(`?;HDKXDwe^&4;iC;WDL;sHV@S4E>E9_6ylDsFrC9UhhQbGTQ zGj?U=4{O!26xX?i$GPx-p*2}CV~O5>MaU@yMwi}9g*AzG<_*Q-NwBvuNFl${80m18kC!UnexhDQ)s5O{q(>UY#W0LFbjPH+CXZ*}yIDFdh*bbLA z8q8Z{CDO_!Xz&u{w*_nVuxaF7OFZ{Qf974N&@i*DPa%qdnEZ@262z@$k9$?^QGw64 z)?=Z^yY+s^1KgyMJs)dI+|8WJi`@(71j``!XMr~ioJj+#BH<1KJ631Q8asdai?=>N z_3FrXQiASfh2IHYIFFhHnOJ?o)<=56!&(tBc3%t-KH;S)K=tAs>gr7=!isojfwx(} zujk6XX0h&s)k&;NGCsV^(~2fJK+g&5kx7(4BvG->YH#VVB5e%CkXi!ksub9LVSNiD zf%qkX6pr?m6xajpETIU!i3yd>XXwHr&KV0Q>cRsNAY{KQX8Ut4z>UJ37cMb(h3}RW zf)@63_zx(7V`p7;T>0HQ`wcV-XRhx^kBp`VL9dJ6$aY|+?ULzpN%bv(K79X@SbRE^ zvyaJFv<2oISU1&eT%@16Z8~79ak_qbe-y0gc?-pbqs()G=FC2-_f3;p&m14|FH^^- zu4hvczsTeqQ)%r&5-aT&9RBk(`(tb7GrZ?@i9n{dBy4qbiNd>_bJjY1j8L zgIzf7>Xl7kh?&sE9G_(*z_`!s%;} zCFfP0+OZnVim+3kfBYUAL*6A)Iiza|eYW5?uibPW&vH-Tacq8$7~k{YC(H|4$uqLY zv24G27oOj|;)m3}@CvnqR$50jj#Z?6rZ|6R&@Dl$3Hf_CANPf0*5&Ot5Bn3q@8Q`C z+EMkx-idhP{O~4>Ik5cjK9*9nqp=FVB>J90e5|d#%L1BH{_*})dCTv3JdLB0)Ctun zLH1lC7Se@_A>%A|O2CUBJOCzBsum&5E!P8j3(UIo5u0If=MDdQ0=1>pgyZACIc~#S zQ2Uc34#w(e_8zH6%dGA?+Y=?b@ivAGW#H)&Xe3Lv>+4`MdEN*e7HD&x2 zao|z4q>}PD_vq3)Q-${(*^uafeK#`ygGLdWK)lzf)#Nmy%R>xsNKGAX@Yq`1?CrROyO|b$Cn{l)WVc#UY}Dr z@twe+B;LqyV4b-p22DPoFQX#<|J0E;Bk7$)4UcMt$$Ln z;?Q@`I-yacI&)XIY~f6id3j9uwygF@3lt$to3f9BMtD18RE-Of^Dt97bzN#@lw}Dg zew`A7-#7{TE?6h=7%scl1X{jwy;&YK^;g~_W%PLhsz+%I#91r2H|?&Y8<(Rg&9e1a zooDjcTJ$^CV@-U?e_YMjL4F*c%^p{?$JGmOT%FlljjQ*OZ_%e#sBv`;`7DDTtN6D; z>!OYS#Bo)httmbTeNqCATo`BBQjm2_6=^Kf^;VJs@ypX#DSOxPT$SQN+r+CgYOaoN zmFOEzXu>=mC*8=;e+>81s&OiF+=j*lnz_vBQ#e)Q(7Hj^v`eaVH7@d)qOU4(iNJ4j z4M(t_C{BM5S~z#BxOJcH_kwLgo!SGlrkNk#1?T@{{3%TG9lVH~S!_DxNVApPQY7AR z99Y|k9iB*x&Xr1zdG_hlgsqHCqYn_3D(w?P7LK0J2JVHXam^fEpTF(Eyh0@G^SvFo zf1WFJAC8{EpM}5NXO$$5eg9eD*6ukKS{&zC@Kr`WHTIY@t7y|ZQ$^PMVnvJP1?=L+ zDTHdh$~iwn|BN)pgIxvqq3G(P$u)eQ*u?;?KdfFOLl{0USX`L$O*DD>%}aH?X#mIx z{bYwC?7E@%txH(LE){d;i2b_UZ*UepG~oKa8~Ij|QYO-0b=zA@HAgI=3*O(tJ`7YY z(alZ$YN6l@*nVB0r^hZV*k&j?gFblhETs>g9-6ndd&qy@x|wXLCXoDIZbPb7l0s<; zMJZ(45oX&F{!{G;<=n!H=zI+E%RgsC(CSrQ&0GJ|jpwb6#?ToW|44nXQv)a*ldqU# zRwhm_-lx@kw59F8O=A1cHxr4w>l$21ky*L&+>&R!em?z@Y5v-XY?4~iykED$WS`ftGKFoP?oC_O zj^os%IGya5{G3QR@qC?Et2w^NM%dHaoc?rsR>)SOyAKerild$O_t3l)Yn$>bZQV|A zl$A%CZ@O2hO)El-FA20ht8{Uq&5$pFlewuIQ%>;n4{w$PyF&PthX-|dmX{~L)T~t# zXvF`SpOy+z6xRVK2}>$9GQ##%eTRQ__)hOYS6~^M1&jygYJr^U>6M%JDU5(ZQb`%C z8Azh{?3Y`O=y=Dmq=bNVi>*f}NHBro0DqE=D^u6#lqprqoW8qqL}TJt7P-dI6Gq#b zp&~GzLURGzJ?KB+{Y8Gxb3x?2xwa2qv+PAi?G}N5TI@%W)q3`6;ym*a`Fo{BIc9pc zCIpNoYqMBfMA18zTYgt0p$#Qv`M6pQL3^mhw*b?k4Y)j~(`x1L*~A zAm6<)4@+6bBrwZ%mZ2mB1NQ9jk2O&&Q$eql7EJmn3)zp%4_ zzhdn90jGi;C*J8lKg>#gLh&ioLqYGdD_ZjKiYNU@WIV*JNom#2e;udLOyX=Q>}`Ko zvbC=&4c1DV6Xdcd-!Hws>lu5(aJm%uill>`t@sB3x4~Xnaei-3ccgy|*+2;YU!`?{P zzAPGjb$B>&GJF$HTV}}fx#uc*en&{2zrC2hJYQ!To%5EKEzf7$=UjO9IX}_)!XnSl zX-Ve?w^e#hk>@AV8H82J(EjQpbZ+67K?jF9w;x%aPYl_~Fs!1#Y)8CXx4)@wKkIKT z`VK1_NaQKD%?-u~aC-T%j1ON-kmSXK4S&_oJuF9DyBTpUjBi!#co^r@PmdczF`54IcP@?|cfzf-9>4o=ZZqEX6yo*KNBF|=(|bx4}^ zi;p=Jv|8BF&F8vl$-<o;lxvJt!n4 zNWidc#V8LfL92$VNFgktIA<)_Z=?H_;b)HPw1ScrkrKpCnbTlKfxIB2NX#-PVd2>Z z=c~_a%(OV!4wQ?Lvy4@OJU`v%Yp-M0PH&&g-UH|53Dc0wSpMQ1xGmt1sVUV8vYC31 z9h742hIolKt|8gMHd;}c^BX)w>HRszZXY>SM&%!Cw|i5f5A??_p^`x#I4?Bb?xW2J z2J}_2xs!dOES>V1I{KWQ)0U&$zzZP%NsXB9V(1E4b>N`Hjr9{_qg+bJ%2O$Gk<2kFlX$TZJQbZXMd2BJYXFrf0@e> zWw5u2LR3dsAv#x49w&-^((tJU>%XG5E+A6MVjd}rg?fj;D_3VPXJ{G|eC>QvIQzPA z4O3?!Jzn3LVB%TDXZ#98e648D!Z2&W92Doqn5q3*NzbJc%^7Rk+^!;}$E*XIs}!08 znt4IP1HB0BDDj79_GE|nEy;Ta=wGZr0IklKxaEq{+tQ@L3Q!v0)lDI1iXwC@bE)8A%I>iYwWL`i(NsC9T1FYO<;-zGPRC54(FCU>3MI*W zo+0q=r>7qhc!^=nEYIXK0}=W^G&8XM5$}wsO(dNv>lt;M=)ZwP?IO)qHG8XH&v&-@ zKbcNXoi;G4oPKI$NiK8!=6t47lRmS`b=t{S#{C#7A8;kyL z1i$(SbL#U8PAPJbSE(kR&5|S?_?r1epC5UT#T*|qzxMPe>AhP*je&e85}JRR&N-Qr z!Z;u2?9rq!FKl?fV>kpG9EacOc;NSFKm1I*GCYv;%-OJ)zYW$7M3M)%H1~hMk|d@H z*ZJMA9w50@B;)^Q?>PW+?7n{@Ss}a6XC(CDQ?h;Ln}+Np^E0Ahh3pU&MRxWkAz2AY z8dQ>YsiZ|ydruMl&v|dR=Xpou_l@88{eL~2-e=r-?z!ild+#~tA_aU~9{NvPpJ47s z*W)+A-Zbts;4E|ve?Cd{+i5${-ycmEXO_6mk3EabQpK(Ei|QK*uJa?^lJz$-`&i3g z8Nd>forC)9P}B!6WToKG$m!d7BK;8839y$M0e(fY0@4CIXSNs{CfxEO)!^}YWtnaA$mV@}m`gUj)sDKLe9vlIX`x3c` z)ij#`-zNY^Mu`kH1kkEVI1J)IbQeW@I5kKEcV`B|Up$KjIls8{kk082i?|RI;rm30 zje9q^qJ+C$dUd2V3Bpe2heBCn1FWgz{=Yu_!__DvcZ(~-bbdVCJzyOl@Y>l#l9j5XqJ9f+5`@5Nwb&Rq zaw_siQ>;T>Wx#dP)c~j~$ju#+;9sc6a5k9LV=#9kddX)$)UC&GG@QpA9oC@7(4fcg zzoW-+<^}Qlo_3DaW2krpeIS{~=-BZD^pcrSu;beL@ANZb1akgF;EFhNF$V539qx!; zLJh-!AK@^QfV0qx>`$ulIWQR!D0ibF82(IREsRdcsoA{9ccOPdPJ|NvM)U^+(-WM} zqh25DxkGeyfqciB315OS$yXeox$96w1COqQuo4DJDJW6kh^!701eS@_!$j$&?(dir zSF)h7u zxAt%z)3ZdBe~%9W8NDh@9O5?3d_KMF8EVuunTOk z3p@aJkVXK#0WJdkfAyD;47PtyM)4TOOqPGIzQtqYQ+bT9qM-c!0Az2s*@S<81wVlQ zri;kWsF|n-5;)H6aSZ@ZWyQ4|Jg;GcKy`@D9iHx}2lM9C0n!;RuX;;9?E#|b84GecnH*D3{HlbRR z42&&k>xFW%4y>PYN0$LG`e;EKM4BD|cVyiaW$OVD9?$Y7cXYKF*Ya>BeE_7zwc-*e z0Ox^>k+jt019x0Oo=sNzaLpLULA2yXi!{_(Q-?W$949qgj}d&!uIT+}O2Xp^j+x{{ zKjLo|Ygtz*@C;f(s#yZ<$fX-`YrWWxgm#udo3qq27ASKZ-;W|CGtqLO;lCBFQ9isMi-ygtb zKasSs1YB7{m_G13k!yY=KSRJQYTO%u2Apu|F-62P%5-d+b+wha_`>C>D{ftMQUCaL z(+Spri?<)83U2+WCa|~@?OTY!AeTnJMJb43lyni#c(%lkmyzuY;%Jf53gQAU9e)4B zT~oonji>K&`!>-qp}b!XI5BFS&^=c&3qYQa*eB50O)_l`TtmbBLF7>>;diqoCmN4sOv)8N!$m=9TQdl2#RB_ z7StX&CyvaBe|C=r)6s@!L->MkR{#gX)9Fb&tgg*Q_>3yt`#?={#5lW~fI1Cz=Y;EY zR1;gUEZBCKKmOwRiFkT5O9RAK2wRby5KW{G43GNQgzm7utQWxAVvF41ehAVMu|!2$ zV@prUNA~^&L;QW^!&ODZ4dNC5qMeIiYvFzp;t{_KhQvKIoJA9SVe1I@wZ9s>42)fZ zrNXm`=q0|~*nx35 z$?53AVX=oH)d*4-rb)Oc_P;gtwzyWS;RW?6r7({bXVv{z;z?Y7*h=-UgJ23eQ1@-M z_$H$m+iDx(8}b>%reKQ+QU-Y<<16Kltq(*#^7Q_)}Bfks=;H^dU zLLRpUBu&yv10g=~dVt=8kS}pBnm+PeTra>G9a3svra!drMzEMN0_oS3^JEG#H{n=V zPfU*u-@i6&e{Lq6`&kg4$_LomXcOjgv>rHw)+ndGJ2W2%fc5MPb)uvEdqE|T}g zJ`6d!CY`bTaKzG@-V+Xnp_FU?jfR|&x==S5z0czp_T3789>e(W$O+&Wio_oc^pE`r z!_asrO_=agQskF~JYxv*Y{+jF9C1zfvCzBsXpk4Mt?=zO{#*3K$bE}>3dg5uaD~ea7GkX7h9HaHMFpgRL zAx60^!Qz<3`j6mP7;lJS;dk}LuVDWa#VzG?l#dEywk|3j(tu&;OW4x|IhiPib%1h_ z)6ta%aTp#6r$-F zjQWuc@5*DwKK=3i;$4ug2KZc+h2LPrE-34F*Fz&NCGZMfK-cJWe z1K11Cju6ic?qwj2IC$;^zkU$@INY~@`{8hZ7k(Y!cN4r@Apz@qaBp92&O}$5Gtb~# zSAcwg1bDW@^x(TWgp~vTxK(gp4&VdN?cg^B!nKC?3ILbkT>?CJfO`hY5CiaM==-=q z85|+4>yW+;T@GA}J{#Es16Tu`2Y3kZ3BU!)^AR8v zpcr5Q)I}G-8RF!^vm@MZhhHx!^J%y*g*g8390T|AaIXdT6CmsX02_eb0GUwN1@PM+ z;55KR06Tzuc&`h;$^Z@kQUDBq5kM(?O99vb_a*?t0mcAy2lzK#`kwZTE}VO3SioZj znDLnWCvXNH{Ps%W2~>lflaLhy)O*Ak1>G^gT?L%;;A#X}nZng+)YT+oD_Y&)KjCW* ze^$WS&kcgP*=_=Md z;cN)gCbN8$;{|a+>V>mQObz8KvTCjacZk)xFSZ>vLR|F2wH0EJwIVWS#Cx2xvh9Jo z{J0v5D@&W8%s5}xg4j3@!FDtN?2^@msZcAN^^&=-_*pV3+bl>2=ef8JguDJYf5%l1 zcCAY=wgR*O4TmZ0*P1@DRf{gT?b>RRrW&ff${;jr41fD7wwc8+66RV{b=2YUQ)OxT zd#}is$6h$CdSW}}{^=2~UmSjTVYHv~%DA8-=?S;;GChlneF}1)q$S!#hgt`EuJO31 zegEum?|XXh!p~KI$*=yB`n58qvhsCV;me|YkKC+>A3oekOSVl+yzt6nmDAbLS;xu(UM3sCDtS zC0TK1m!A$W^xShJrZ_XU`cuJ$@Z{pks??Io_@a+#WuGtkr&oU}t**?kE{WX!{OyAW z5Bzf~b~z{Qcovgg{y8H5V_fkkvxmv19&w}1e8=qYH+M??TKd}5Eq> zI{!xJ%-h+gV$B^>i?d^QK1~?2({JpyfH}wG&F_8)^4MMdvG~M`)TH9dIW`Fvx6_@@ z{pRCn5bt*~@7?2)^k=&+J;|-8N+|hc`z&wS_PrMpO3)rfVw3jtSqv{d1|2UoH`bhw z%V3&(&V#V+0z!O&YJRj)4sNMZm!c^p>JfgY?a~Kt1a6( zIX`rH@c7YI<4qg3STu8O)FdI{s#oK_Nh|XVa`N-?Q*$y3x+k@6*G#&_mNx4vTD5Am zvCX~~F>VuGCu&%!yT5XM;q2>YG1Yno)7({Rdmp!7`rN#3e`C4+Zpnwd1rIlxx7bip zY|*I694nrM{MIYW%qos+Z8~{0h7pt%m4AacI)gFvDCOb5Di4DQfoEplg$T?f_33Jk6LfboAD10tR=i>NH1Xp< z_40-Bq#VXxeW$wRN|UiXX4vH)mn)-T{6@L53ex{i2b1|$OXyh(Q(=n6FXPV9BWe?vV&4Sw3V4#VpH z;chVMDx&AkZ6F)sx1}}N34Rl|bIgEbgYl4W$^AngmlNiIaG^ zW5H@OpiYIj(Bi@hrztKBmB)m`VhPAT4(=S_8WC%SMADhSmm<+aKfTC%HIT({cZk*t z*W_@0jnxAcP50Y-L?};FJM_8G4tOT<*qTi78(L~lh5aV<5Ww|Jz@xt{sE>#m zoHRD-sL=S|`ZfjPv0ebUakL?4np$tBH^`#&GzVO*UQSU1UwZTJ32jb;Hbi@0;_ZTB z5Lxe{CFyK}wQvx%B%{56)s01M1vw}^>WAsTov^#Czf|{2a+XH|fu0Hx$=8ky3HLeJMYk+D7_= zH+7Wwypw=hce*Cw+c>jcdNsAFLD3Fi|sr?!mJA!GHDsF|IyP-pJ-J zj1Md;my5C?*^+WoqWj(4cYkcxo6>?HZ$`Zo(NlI%FIN%%;XE5#QI4Xz<~_AhqO}zM z&aQ*dh$KDS{X=RI4v(WbwlLu}#4`e}=CBuuzno7As4atQ7P!wR8iw23k!uOkA*M*u z!m&xPw~#(Xy+Redfu*JN&z32Unkx z;vf4MjtgsH66=-Z&|O3Q@hCu!1tTz5!rIP4Qd zLKHW;(7cIe3`)S8KmsCtQc$Ofq)B)ZdKbZv3`WEO*KlvsLtk#xwKv-odR&O};9 zJwGG(Md~3VI{GR{ZDCxo=3XRS(pI=Wi+qsIMv!;VRuNCdw5{n#i`s1DBI&Mz)KCVI ztId+UXVYb4(6qSxi2bS!Wk-ENKv{g3#LoIBb{Ijc9iDo917+xP!#?Hu9IW#6hpYa-va*iffVr6C?TXxjOx92vnq&0iFQm$VGR)1@eh2gdmaC|7LPf(zF{5z&(IHPSjUGw9oTEx4f_nH0LB1Y0M32} zy&m}G>WA3E^N;F>q(R#C)en(`^s^znAJG3-$Uh0d7v5>YJLe%hW)b*)+5U+4PwK8> z%cA+*o(c2e)#`RcPvbEM^90xNMc05Q^5p}R8_;T)Uf&D%?UiE&WXR><+%Y6_uedHp)@DZyV&O2EB*|y@>kiMF{q~f9BI&;K3+IEqhb99QCX>kMTLuAV)RG zQU5!B^<28~nBTw;Q``2ue`d$!lxmEZJ=3?Gm7{(-&SQ8jRRnZoMdc%0C#BY=Y+~OI z_dO{J{rr$sD_p&=&${EK_C(wF)UsM@a_%R(69|O{fzGFyk#ZH&^A4)z&oD&yryOcy#ejt*Q&fhv?>k4KD72> zq$PE?D0kiKK3aO~)~#nM%-U*LSUP>KyfJM@yZwEoclk79`sok&b#C9;t5y^?Qk>UK zy-j{&scQj758`r-Wky~#o#C3KQ0SEt`MI&TmTcSID{^=Ax-6$@|8bMTg`my{ZVXnj zx^KAZ>Go@}tF|_Cd(&O9G=5J{i8CF?{e1YBv!Usd2m8!XzCR)+zuZ=-Y1bJUK^>ob zZd{!wyT0<5ZSC95$T`_(Q~|U>rQ%3+3BKc;(Xrm<>Wn{dXA|po)<0kDxT|_JLN{as=50$=T}qqJX`6K zz1%&2u}k(m_x$NjA2jZ#jkABJV(z}u#$)-zbVIkiId-v=4!ls^?xJSx!#f`_{N}qs zm)@Mc_i~ku$2rHBvyKI>^eoi56t(M;*Il=OppdW;$Ac8E#Sh=>z3|*?qeq!@&V(&< zN?ZIeed$3rNB4ji{vo|DM9H5HGdk{}zTIW>tB-46mK%DPE_jkN^+JUDKJR^YJ|}Mb z4m{}F;X>4`-A~Led1=}BFZU^3{H$oUd;XLsITM`HrtNa^eibs-)V1ZsHuq?H*4v0^iTMiOn^9{r1F z2t@c#h_Zfk$#~Y#Wn@(3y)6d#DJvCclr7G z@6zLDT^srPHT8)X26()7Nls1%WpcA8M*Cb%M%(l{_tfS=utR)eoL`jBqnD0xadA(B zop1PD8g%gInPZbO$}&xoY+Ck~Xmq@t_2U*z8qe0gqkXIMr>{rfc$w_V+qH3v zp#;-i?d->K-V&weE&CkWH*>)8QYE=4iBQ=Y2J*9>1q{jMz21E*;!~;b@hC6m7d+N+;)3EVp337p2C)}$AcCP{8_Twiast)ON!k_s9tk!JY`{W-w*Lw zi`u!5NttN>$tn7C*L%-%ZKd1H-aPI|YG=i{XO)T*4u84zIX$w)-7l5hq~2AB{Or<5 zZQ9w;lcB@+{A#YdYIEkIxPDA^KbdEX2lYQ)Db?$C`&}U??*s@?4NGQ1ybqMZQOA4a zxjx+mBK#)sSC zjVsyW9JIhMZev=-@r1l%7ayrS4PP8nyf&&xH@0N+rdu}r|o`Mwl|@~ zA~MtJvA0!h?$P)Xv$&F7F}a5#bGC&SEDS67{dM-1nB2p$B|Bq_P2c7oXxI9%R=p_q z4&`!8BMk*ZL&HvUr26XWWhAAgq$ht!?QGu6sb!1i2dxk6pQ2g3r}D0L#NdY;id!6* z9N7Q1oJ6N#n_Ep&G+fhd(b%0DPW!t`?bYzBQm{8nmywXt*kY)+tL2nmSO5I`?6c}s z$4_sGE^mEAdEA{7k4`;4`0MyXVO}Ze`N>&UNkdFNfBaNAq~}Lz3BTZAKMBo7eika; zJ^lO}U0s^owr`_jGhYw#8yUAiEOv$Hes7neJCBKGV_b#N&1dr|n} zS;`IDh}{;qZr!?l`}Vtc?|^lExOea4o5+gD(DLwCWg%Xv_LqQZ-n@A;J3Bi)EbQvh z(;I9qJ#ca^4)ZSx@^-v^YyFXPwg-=%IdcYBRbgSF-37ZF?!LK&#ZGq}9q-)Uy?ghE z4ge{K=Ci z=gyrwcI?=lJ9mJg@7c5G{JwoICk|U!SU5U5I-K0+d&2Ul7yUNkrR`0*of zc`x&wR+g4|d3hcl9@lJb?d|RD?CgMjCnY6$dwXBKdezIz>(Qe}l^fJE0Q29MA>UCF z*3~7(IR;A&m+3Q&hf~v>)?0?lTv@`?(wwKJGj-tvO)c{)7AkbWo;hj0y2gUZ$5n`l z&aB^?YOZj&b8B#B_N1JjWxL4sYutS2%CU>2X6v<|HDn_a^u{5x+Uw1hn)LJUqjxl& z_)F8}O*@bN{pU%xio+e(=6AomxcmEY&xTj&?)XyGxT?|YFJ1e@?(u5fvUT%TEsr)k zbm&0zVT+N&Mh;g}7}ry7P^ZAAyL)@4rJdA~lGL0M<}V#Qp`EVN(nkRr=|j>iGbYSu ze*fC*t+nHfNq~yKQTD8h|4O3$THd=9ZTM+dL+|G1=GE2JJRUD9+#g=^wyG<_k3hRg zESoY>t&w3%Q`9;VYhI;_jo9q1o~{>jXt$i4q`vGP^Y%7NuS-fQYsj3u+G43>KdT9{ zS8rdH8Fuxmij0&NbNkn3SGxrpOGwD=nbcfb=5%8wwYrVg%A^jvA&+{X>dzXgAh){t z0~cRy#Ney#&D^FC{RfeyP$#mY^j*QA+55VrRI?xnbv5a-S8WbANU|-o)vg2+;PP&gg?J@So%LT!S*BpbEpK|~0wCA|X zJ~P}REu2D(&Uo^!_{?;R-19JW{goH9+@kilMOlR=-Mmy~i56}GC>KkTb17f(l9D|q zJG05zv#-_8&YL$={cKFkZ(3?+M?Q7kW}|-Ar1E1E$zy6~EiKj6UizMsY1HmGjFSHS z^*^L_)C$(p(bjmZuF)i<+wB!fFAG~P23j#~+_}k-duVAWu33a6sy}l!SvQ?>?NaB| zw9BPiVa{&h%gw`7^+PAE2-PzU-G4sp;DxZj;P8`nVTNX5UQWv%pX>Ok{AziDSy|q$ zilUQ+X)_B_W)!5(FU{SXmoz=+{nVWIbMsTz6r^pv^o3z#^UTVWw|>8oqzSZ zuN&lduO!Db%6r)B=ZnfqT}q2?mloYDE4o%zbfv85d|A=yvZ7-jOD-iwY%0#)o)tgk z`HdbqY3B=aPvmD?7i8}#$lg_uWm1^6p)kv+D04+wfu+x#!9|(d-vy2Hy*Ij~$UZ;& zKtZ-;LAF^z*0#c|jfGijiZYiMXB%ZFo4MZ@TbOS0%BgQ+ltp3Q>4I#lf^74GtnGza zn+mhm7G*9g&D$F0Im6HWKu)5uo2`6tfqh}lfr6|Zg;|@6GWCkH^on!#Jh|8kzVSAyQ%Hl zoj7jMsNb!XSwF>{n;-kz(`}W~S~pcyRC+dU%q$qv&0*`4@?rlCI)^+Pt_BP=VBmiQ z11G)h8Iz6{%-8;P??aA}0v{*(Sr1T#4g(p()hFe z{h&TqU=xeK%->HG)bSy-OMUIKGa;-r;7HitPbs`de?N8EWv9UR`kW6F19Z~`$}|<) zLK@P`2fCYhR00aZ*0(b!w0$cvuZv{{PFlOpD=M1aW$lKjHBI;>;E+P*%R&m4Sx3O9(Vu0`Pmzm z#$!JH&SP#)<}qmlfPVnY>CR(x3wi%GHo-5i3TX7K2K!3%Dvu|{pq(+=XQ3B&YX8hy z;WFTxft)o$ti#X_5w&}`7Wgb06ly~gO`hhEK3XWFwIZ&#(2Gq|&@zmcidb`_M|GlE zB+i0Np|%d(TxQWMYQGA{W%HnU%R!x3-*xQi9>kYJ8EN&ibZshzPHb1T=6&p$c z?Ap;LS{Re8);$CMHqb5+Ef2p{CbUXK%UHonol&TX&25LdwSmwJ4qDWrMIhn~b3s1} zw5~Lu0^eT_hUBKRfPMyBN#b!3b<#xXgZLq@4GcF50x_ENy~Rwe3Bb}H^;C#Mw#s7wj)w`u!Fq3S`ZHsE=JRYg^0pn84b$3g%9&hq?V3>x0^mbz^zFXwd}T2>SIw zYn3H@9!LA|lG?QUiuDt!3cZ7HYth!Bl#3-K=V{P#QV%2a`Hy-R;f@J3O|*d*=3%r% z0w~}=%!OJbHnEqWUxfOkLOCe6orF`K#J5&P>th_tjNl2a^3n4t^5bviLTtdPr8V*x z?6rgnD39Rgj9z;P$3)Mw)JH2?o)dqi#D6XEd9a30HCy>y0#n6N4f!DY31M-7B_-b| zH4yA5fgO3>^i9k5{kmZYGNK~y{T`(XV^;K;9SgseH>CmO`P>l){Q;u_$dRx-NDYY9Z(HAQg#1xLLb~CO#oxl564-4m1?lP+ z=)I$Biuw!RNAEBECndl<+M;pa;RmE9;S)5)@d}Df!ZoN*p1zQt=p~pJ`7T(#79gQ; z{frTQ#O6VJg8}dp(Hy=Vmw1~%3SKQHHe0rS{DOU(7HByHdnNi<5WdiR$+!DC_Tf#O zUWXnuFkS2ugiBzLB7P`{9U;;o`qe-?J@i0~J_QZo*QidZjP?J7Tm(7KwZO5 z&fmG;s6BB4;~3gC3*JegW(iY`|7<;Po`5$sd-*NfGfd0&63qFFvhcF$rb*M(o5oB1 z)Jncjal6|g4AY3gE!KH2KAe8AHeR`ddcjV^X%9A9$gA!>GVQt7=~f?qckB4YqDu43 z+DoIh=JnoeH%@NKX}M=BBBg=lgba&IE6`2wZY_ubEWki7QSmL zuhQ;BfMoBU@^brU-1L2QqVte);6mE*lnS@)h~`&dIp(&Y1k?4Mg- zdNG(`W_FluvGtdx<|B{vlyCMTeAo+vyfdDSG?xv(Fig@$O?L0>=9)*E9~sxSm4u(H zjamowvtb!>%~vbVxzkZiGCt2`L<)2HWSeafGBU5$KkjtQv)zDB2PYoQ3q0Z3E-F${ zexA~q9b4_zxfWk`kgv~7JOl2uie7o-!hmk`zplOPut@Pp{MPk`M|;hX zdlr!He?p<@!m9WY3r+0&K0P_{^vIZ*ii^8%xie~e+vQ}cMV>?7Q%OLc{j9Ou7}Yfi^nc4R@{5JX_Qs8 zTVBw-o6F-j1$kM&H-A4RDg5W~oIaaM2k&gQ%`LUH&x{2nz25qS19{XsBd$yDNdg0n zu=W8hM5YnnS2VNbM94^d;uE06y94d7!;@G=l1@}z$6VrTW9h2SUTJM|n@KYtR9m<# zzOvpOqWu%~K$w^sJ&>NKG7g7V9}oL%7g^>OllM9?D={_WLwZJfdU{;)hr6K}dJi&{ zE@U1ItF{XMy34<6^NUYL&ps}7EuZtSWXjz_-p%|Gwz-NIvlY%}Sp|Pt{p_QPeg5#P zxk?waoul(X`4Kd|6B83b`ww&gQ&LhuOA%BT_dU-5O+(NO&&bFCHAzrB1Z{B8Lj<+K zf`S52iUie22M33H_wL=le?KQD2UH+IwGh<8K@}0SFF_Uj;lqcZv{+J70=ng(N?BfB z4(f+4E-tRFt`!v(8{=Gd0OG%|iQz;vF=mIoZMR!l#wuC&Xty1mTgpkO&g^NsOeOhC zqUO7iqjKL>razx=X&Kei(sJtXGXpzJkv;S4o4BUghwWolZFTefs@qI`XH&{MH z-ZlNW^E}7shjuBgyv$ZxHjW;q`d&NoVK?)aYuCvhnB2xON5XW+rIGecoaBA4&fB^s zy(zOgRr8j{^bBQvrXXg>J@Z9XIjwk4ernlx%X9Uk&CFk&`8?!Ed-Ekd`gDybc+Na* z^K+ZjEw{0De>+*#Wv|kf&%dMY5Aa2t{~`V@r+lw+0CcrRTd`qA23y{`3m<@Nl$Rl8FMhh}^Y9;@i**s8Bu4-ezeWYdBQ&%_-^G*>S=Sv4{Et$hn- zyw{CuDmqzCk?Y#(=;cOq-STmfOC`@HX~}~=14_CMZ zp3i%@>gnADMUqBmhDCljle%nFyV3dEB?G0-BEa0%mvM&#`>#*;Q#)h2}Ui{ zXUa?{OgfSDzC%E_s?`te`bO#Zo7Bz3ohO&H)YSB1j}cw=@0~DUk^2$*mEGrb>0&bP zLg3w{nlpCG>^^p^?fqqGtD5de|LlM7{_=;n_Pd8YH~v_z9(>_&?#{6)TV{9c5f^uM zm~_901)V<_Pa1IR!-~FYYZrAJ**apqNqoeFs;VZYi}Lj6&Ph415aDcHTHd>Nv!2Z) z8)dp3am8?&#zLEfUV|A39CmbF5^m#>b-F`YyTnK=$XK zOZGN#`aEf1{+BHqZr@q2*z)P(*$WhoJsY=sueZ0$@Z_divrpOC$#+mM(o|bNXsd=@ zcxp>3%pH%&pxehvU$Y;Xo z=%$%ZZTn6>-g2GN6NTeJf$jF&zbs8+ernPL3OBZ^Vfwnxi)Vj2vC#VZbr~haGW)S( zhx!LT?cy>%TW;*Hhny9!uNm^h$tE+&U+4eX8*IA~GuXxM9YnAIYub=$Zr|z37-Mbl9 zpIcY4&+LBY16{*8akA<&=YP2s;yk!yj+DXgLp2-*XGaaYd1u(?F^zR)+HBi7DXwR3 z$)PJ1{W6|3f2A5-)i&}?mx8g3{BCO|$#eO$c?%SMHb1nsy=^Ho@^JeDcIKsbe%gKe zz0y9JwHZ5RuT{3**LA!hbJ4H)?a37z8}sh>sP2Ax$8Q5Jy2 zAH1>X+>S4DtOD4^~!I zt^(!r@dxC3_3HINN;&yBZ^X&ooxOZtFH}F?@@uc9`g4(_- z@MTBi#-Y#Sd~Mb&d1?Ihjl$i%kVKCo>$fLoxj&Mgsqi31y7Fky?^7M7>n}C=nmkzb z(ER?>&)B|d*Ycsu*a}>xUeQv1@NQ zTH33L`v`@vN6#x(J>Q|1VwT42S$5I9?e8m6H9KGLV{m+M`<~_lmuTfSV%A3QFK+ul zlkeWJmYIADpPch!8tk7M?4Lx=XZbJMKQ-9FH`u}dH|^jX>=qjA7XIya3-y^tjIUXj zc^G)e^v0O;LDTFaXWx6T`!w6guVPzN_0hn%`!~EzVxOcw-y3E(!|mP!b)`RM*8)sMPZ{PcTu|B^ZD z9Ww$(x1Tots?1%jL+ho&Gv zWI;b(2cSE^d(b&|0v-9&P*!nz^WDKdr!Mu~+d0np1!@2LQAN7z6c?037Yb9`syzZoiuh>6k!2&IH>e2l#ac;DJ5ZC;%zAzYYES@9K9^ zP!@B5Ljc%w#C{3IHd7kpR~LmH`x&f{i6W6+jnw zRsd)XFaV$f0QVXSX*~iv(}nQEq^YnekUIr9Z`1%z?-O^905=}js$#lOBCI_GYRPlYsiGR%-!2nsuTm{t)V`)V zq(a&7A6XkAIXJ}^wQ^C%UeJ<;t6R*~y+u5s{m8dVBbX~|C&bN5b+0O$1VKEYPv+6~nwcRZVo*aB_kW(fD+>I*9&f7EkDYb@@?(mh)%q>Q@4tMTcK zX#2|XdncYa$?E;q9TV+az8AahG6>_0)&Xr_s0R0sm*;!2f4n?cu35GA3j={#P%{~6 zh}&=E;G{NUYelRf@MPz@S{3m&t(M}1V^TcSmFFxt!FVd?wqlyNi~DYvUta8m=9r@QHxpQsRaeO$%#C>xZXwqm>%k)NxOd z6tu&sU!L4_Ssq64`MuuE=1s!mU%@!SDUxus9<-g1zUaxT;;e}TIgq$q1=B@40-7HA zLjF$V^AhCoI6h*Jr4&vqpfGQ=QAFDaw9-QB8njRR)`%dQrfA!VhN*A9by09#^$|zW z!s92~Cf^=E#dBoLK^)JZc%~cxpV7L7@^1Z_0Ap%6%=bl77jwS1hG9v3$1N6 z`H(m$8KK1;&70a#v3%iM_Eh~r4n(^bic?lTW8>E(Ef7+TPxp1n-82T;ob~5F;Mrbs z%CJn zx5ocT8d`u6v>zias|Pj1C&Hl-XDn3$*2a~>`pgj43qAuP6ND8W%d z4raoFJ{u_geJ`A#G>zC}=N!cDl;CX?%@}^a6-Ri4soQ>cTMY-<3OSMynY0h$5NU_d zig1bK`L?j~fNOS^$YN(ar<8)Xf-;O?s@zy}86B|bCvOO^{5FS0$%A{<6$fiY*D-|S z2+GK!G{TL$k((LZqa2R?s;&_L^Wv_5Xb8psvAhNSHT;pB#poHyLDA&+_6lm(5BPy@ zka>-s(b?ybGmk$kuKb)@RFPO%9+zJpom=)Mrz|47EG)AmIHSz}L#ba{sc&kjS8{1$ zVP$YeQNV{nzqCT%)I#r+!e>c^Ztn|R5(*y0=R3va-;K$4h|aqnm3K8F@6zkMb78rs zf^$y<=f=m!!|5Af=LN=Dv9Ynof^wg}F9E}@&!0bog7-oHoG)L#So`H14aj*EUu@}{ zz0*6}F{XIi^Q;XXS+}B#Z$uTH3C=wBGHt(4s^#+(Q}^V}t|{wWl2$t>Uk%IFvbi4} z9UUGX{^G?8I9>#-z}DXhnRPL6+QD0=&OA2R?rgl#`KeoMXlS&>9?!y}lEU=r4>6zL zMV7{f6h{W+hWq3Ocx1fvNY2hEF}8Mob~c%;aQSv`w~d+4$Exy$zPk-`W4*^(qI2 zTPvnY-7S)wHd@!aMbfC>n#gAP1q7F8$vMs%Z2KU#kC{_bv+*C>tBpKA-Cp~rpPW>s zp2#=07@|MOJonuJX-UV8gKamP-a55Jz{lHH`SdFKIpiX>H!jUH%aRyMhjwEsBY@aEZ%W41r~ z_13$rO%>(u^S8E9lT0eV85E+rz9REo(dQE<+VmJ-HqI=zb8;(<@%rXpH-7Qs8TIH_ zKBGNjTeRMPu`E_w{NY`UfUu0QKfnQ(y0|kuk5(~++f7zD^;;u!-1&&cEiCR;Ya75 zM-YCLR$P(7XG!l1%Mn7s=y<$!1Z0hCi;dm0 z9HNUIqVsJ6b1h%ySiH#I;g!AlS=Ji2tQ&8NfT1jZl4%!NWayF^npt)sJa?~O&L+<+ zeV5Fo&Y89mMN1xKTz*{?lwP{%VaD$dGA@P}={?Sz=ag|itZ4TA4B$%I_tKvymtKh| zx)5G;Il6U}4~**{qS$m)ty zT<(e8dV$TooDB`5KcpKPnnkRCnjz<&P}0F>rJ171nC-=050;fbYjiLrC?X|(>(Mrk z#xuN|M^a0tNToiE>EV3W^6ofynJsE_Jik8P+``z`+ka%UOqq9#ZOiO4KkZXamu-@E z?RtdoNZ&!f9A`Eie3dx#@VPxzll{{#bZ|*Ic5;Mgr^9^)$1|m})_cya*Sz|ob(8If zuWvZBKIX;65Q*@nWn)rp{5;GU-gDQli@wUdH9J{+^JvL~3F*Dv%@#=V22JmJ_mFD$ zZj+lyPP%b;y{4|xTt;hw=8a41`|3JsCms4FXZ+2a=ho@%t)@=P9eB!Y$zloH7H#(_ zr)sJ0%NfO(C4EXgq}r*ZRg);=FKzvjJCx*gV;XPS@@4d}2hVgopL;xe`X!#x)skzy z*zfA0*3()@|E6hhe!au8wJwb8W%*OD4!szg-n2#4jwfHWfBJkOq^YFF#ZaE^&R*vd zLO--V@N)8pY%|ZVF)N%G%m_Pvzv@EbrOrFt?k`_|`|F&)n~$Im3FQPI$o3odXdL^g z278qTdzJsDy$Y4D!(3fMHg66ZJvy*$+tAaeLpyhTKX*p9<)-3GR>c=~=a?HO>P!vm z)INC5oB)Q28qhb(%((R2_7ZEoVzap=J7$*cnq6_wAZLqSRR7*pk1v%RGcK{xEjwUX zer#R&kyYj9b1OEeecV1RW6`8f=CiAguKeg~SANa9_^f&IlG(3&bS*Q{sa!Ga(~|z5 z=XS3$pB)aeYsZcuD^`R#I;Kn;^GQ$Xvv%jI8STF8)cS0>plX`TmnqU;cTBq+JZDD$ z^X0*rF9-F%?40@4boy6Yv)E#*z`Qx(1! zhpey+>=+sz7?eNXGkbtn&IsRJoqLJX4!!PrKY4a|v3X2|b@Hccw-aaF3EBL*&?vBA z?&A*{uL`F77N`Xj%?&GE6<)S3w9GK5T=#Xwdhgr~`@%ZYn9y)U%=t@l%3zlXbPNLR{pwYVn+vdAH zItctiK)x0yQZw1a5JFFve^6SdPKF8^a8jCq9yuz_;6rLg#R{TR?`t+{6@zEkX zR`P}co&wY1)XCX87LBInuFCFme!+s=xKVD~Kk+0QkK46NwU?gWIR3#>yUuz`n^v9P zJ|}v3m9)ziUEQE{1xcCuslj2o87X)O*xII1%^I0XZ*lAnXH0EzG4|Zz_#RH0a@n=( zs|4?`1uarg%d~WOH;M)6< zv-FC+_b#oOzfIj>_U378=KK_#lpEvr>62TGk<8CbioB9#+fHGd0WW{IASgx-l!0Q% zaP8Hj&?DoOTiTo8?A+Wk z^F5x4Z_A=QDqr0xeSWRL^036Uj%4~w5(&UzbG z;Ax+E>*)K}0Xg?h#UI%eaLO$3g?POTPx_vIv*Co|-nY)WajJI>rrUlN<_HR7y zC#;@%4_2>S@5C;fbo0*Tu}Z?b?We? zJtq!c*mveA9^!b`;+Q)B9LJgy9M86O*r%>Cv-$ou?PkuIsh+Y&Eh@@j=+MWyrZ(0t zdygpX4)gN5d-K{luS03FhN?Sz>2;83-)q*84iXz@wVcvH;@2TlR_jarY%|_S*19n> zGNHxCO06epfA`Q=AHLM!@1eop!#~L119Ps1A00VzL|0e0xUwpFCh0 zv*d%muDj)2J*r;}8X~Ek^0caC*trGKiAMgpO1jEj5C5X!9d#~bnw6FISgRZE%N}oe zaBR0?bM3&?xm~yH@>`aM=fr_-w2VlV2}?`}Qrk^@H6U*tmfmoCpu&_*Zj}?3rO@GAqDw zX`J7@kVhke9*hid{O#49Q7;`v`&=L6b#>gc%j4b8^PZkjd3ASLjPE>a)0uC5<^yd3 zJ$)!f!b-|7edD#@ZFWgyW)aX+U<%MsVcaVt|9h%Hc|d1CMsHuN33XW<;=CmAfi93; zXj)!Ca<=cgjOTG_KuM1y-UTORyw5A~f0q`YQ}iMs-7_}T^-UtslVfP??VxBNrni{| zKCww33QEIMvqO?H1K+0uZ2^S=Vaa}2v{IO`_&YM~c6jhjKEzHR9SN0r|+ z?O*mAGGxfCz~Erd>e;JCuUvlf!PiHU7V^90TXbo6>}q6IE1Uh-4STKF9U$Fugl~%r z@AS8fT%_dMynXk9Lrr%nHS*RP+3xVm_5nKQ4@w8kf81-xF}(u+&IfJ`uD+l%uZPvD zd+&KCx(+|}W5 z&XR=uqZv6>U#l!XUKqGb;&WUFy`$5I9{aBlBV^ieHDI6t0}U8xz`(x)1G)b8OhPZP zAq6|E{wd~6Zvahz=>W~(tjI2UG+b$wUqv$&MkdXikpyS~@HG|sQn@)}4^Rs52_OOBJb)`e z3P3nO651tKz!|D={}8|y;2D6pOESQo*>r=)DCN{`pWJ;Lk0~50YM+dL5yYM2Db63s z;u3Qv0&L~&p#Rl%er}gm7R+=AGXQ?~eujDg{m+AV_4SKj-V}HYq@N^d!9;_tzVP|E zli|C#^K%bKSupJ&UJBUrw+4Qt0B{-dKLUA+J3sd_lrIXt>q1!<05pSpasEiALz?3H z?_YI(?p`bx;Ox&nKX)kL!5q@Ifx2@2BGjk<{>b^chaeAaXoHggM*zf~pW6Z2a4*0p zD3dn8Q~(VC9>5j=YXE(KRRE>{#sIqk?jPncAu&90UEm+_&KmlmUMC*o0XVo0un<5F zU^_rFfYtz2(r}(A{Q3i|05}WK0pK=(@YOfao{b^#0rU;rinEIGqt_WSUdF>s#(@$UkU zS?I`PO83KAh44-XpcLMZ)Zj6iaK8XxI>7g?Ls0ey2YDjA598Sap3t9y^j@}J!t#bp za~0-_ohZL*@Tc(O{Hnp9LW4hr@AcPz!gp(!hfE&G6Y!_7|COLWh3mjq#vfqADE0&X zB@{*`$exh^S;(*e_@o(+;kk&0F@-Qacd%hRrBp=HK`V(hwPzAegeSCYCKqdCM(tC$ z)>~+GMC_fpTK{PKfoY;O!wRrOqZfPDB{vN`ozakQ7ej0m*zhzS+8G)1tzOYmNYEa9aS|1J4}9 zlkCuLa0_4*Jr)Spm$bdOkmB;@QVrIZ@BlgB0&+kf_2mQTccJc>!q#=7=i;LEGC5-z z>5cYO%B2VuA}Tp@OfUJEJywY6e|>P1d}#t~^V^c8A#`t4d0+ex%nBsSBCZKQbaIDuRaYfsvW z;GVU47C;(25MIQl$fY!HSQY5g9gl>6RT#lm?fSp*mT&lr{(y5gK*@*evbXlm?i|j zEH5Q-*^!9r34swa(vU=muLVI_lG=i@In%J*5d+6tDt#i404vB{+rV|U{P0V1% z6ey9{H;;vSlW~BQbu^^06lzE1s<9&D#AyB)fIQED84GgFaApKE68;Sa`DP@XRg1K@ zf&XPR;0bd@X$?av!&kyN$MWyV*`xFxzZlnqBeE5SN1p~b=4^#8gP9=!?7I~;??&@w zv$gy%ijWU|#_#lbDfqF#G`P>~cS9&CO2C^S6b-|^+a~56n-&|6rpLvuFfEAUS5*G^ z^D#V_849=?4fy>&mWiY)jAa(9Y|T+3UJLz!Vhp_>)gQ}4p{0gFnOOWGo<}gh@k`3S zW%Fa-(LA}B7VJf$coywZ!gyBZ(=bcHSUN5R|55rK0#whXX{-hI8hl4^iFFlxgJEck z{1|=-rL#EuBUCIX&l0X9ied5mM;Ob0W!vnJ zq%OYv-1PrQ>NqpURUv~KeBv79MtFx*iZ#%$!ClQ~{*Mk{9wzGnWNw8X&BVo`Ghp-= zM5I6^phGp_cycw8sT@dXg1&16R~s-SUG<@5p);uQ+(L=D#~R?w3;lnxE4B>W;geBL+e63g=^NO-OmU zF$BNk?2NQK{>9lUt{>xUn_EXNePHY2cQRW>UWj?%N-m2-I`5}=M2XdazoLZxq%bx& zH>99H3v-w*N?2F|S_*E@;$lKP{=~ig|5JZ%tBR|s;5#nn=;{_(OV>2d%}buENi!w*6B3h?hQFalwpWoKn{JQFNE zc|wn|ny^Zu4S?f?Aa}(1wmOWE>NR5;_5kF4n?Ppk50VDHu5qK}= zgKM1V{Y??dv6=+s|0RCma3zbBnU*IL_RN<3D!QkS`b@7uUx2I6)Mo>a$ruBBcUO6Q zeWpIY@C5al9`l%lb?{Eir4ww=bPpBH$3BF|XpI!ir@A+fak>xheuMl5^O(w|kY)v| zH`N04CF;_f@`8LMY(?|Qhx#~!UPRXt9 zz8*Xw&2s;#@^OmXlhD+3xWn8?s=|4&w2y0oaxhas?u&8i#x0&OKx9^K$|QY)eK~#_ zYLE)IeaW}KtHdZ(;SPkjveIv4-$1aGVS{-LxIHF)rr!9$i!f}DN z1>rVh#p0OqAvs1kHA-(tjZ676C+w4K%7l_>+H9MP#uHy!+y_EBLy1qXw!C_^luFA> zdi{@sb*G2n3k_%~N zl(w-C66qO#NtZ|;Vg52Ei;_C}2d>Lr<`z%cR<7dia~xWfx2Yw8JHm~YcqgaWwZ z1Np*^5abzGHx0nQ_%9&qjH*q!A58{mlH^5p&->P{ISIx?8ea~jqzklG94)hfoQ+WQ+AHJ|Wo+g58Fo+GhW=Nzs?&$`&Ux#glk{e247=9Go z(>cW~ct*aAvlqk}wg#SxfS4ot45FGTGC#6T3YjJ47|ZS2-UE;jANtl=Nrf` z37$mjg!>0npG*zzaW|e`IPXIqf}<2WPb7Qi_y+UFuSh{CwPLNvniusLj_2dxswvL% z>hg&!=pmi-0-~pZX=5IkKfx*DNpRhdN|rPXmPNP>KQddMP)p$q&Bt6 zI>CTn%JbB>sxpl5()+*MRkUR-1|RZ(4hzpTxz%L=Fz{mYYspsnjn% zVgo6i=sA*d2(O`_l!5a}Y?(ja?zAdw9Z)CD7*ZxX8Waol3r9n7aWWNJ6gf>@DSkgJ zO;xAqL&iVRhdwgBL+qJyu$#F%sBU|O<^y@mGQS_USBM5184Z9cNIw{W+E<;1doQp( z+67<&Fzz$hU;x;`d$g}g13>$#_wemU>?6lOc(kty2iq!YU)2@z&j(0=cbV`j&c4bA z@)BoXRp0ZTf7HIp5$g9>o%iev_5TEQ4TQROfqIp~y)5MC0rwH`jh^@18lDZ|xj%ff z1keHK4zLSg48Q~cO@QG5$^gRlk-gzveeA1NK{@mRrUFPqoO~!xFyy-%o=pL`=RMoQ z^Y`ql9zvK;04`Aej{ujin9hWk>8;}6d;SQ$AIg^G*dB6)zHo++!Z!!;m0;C|@Spl@te< zt^ucg@L3+#99zIYa*uM~Mv!hvYGky=k&28ISO&5JKelGp!jH!PGX{30Okiw7X%Y7` zaUY&&&0^R=ATuh%?|6Q07cZiQJhmoEsw57sso*%c9G-F2Q=VTUvVW`u zbb^v2O5JRVb0PEwSW!nyi*@iTS5q34W-&gVrL`7nhMG1Q8&@qiLjE`!qgEeE>L?T9 z$~@B58VHNeD8FF77?bRkk=Yho0-Vj0nqyuV>(9xLo4Y);5H}ChqWd%Igw#N=Dx3q- z!Jm^y-FV~HXa!&%sR#4K`%QrDQNTe4f-HpplmLdnUu@;&@D|tj2Lj;kkRm?@#vaP2 zGNkA+KqWXYMM-&M4b`!4D4kD&c?{-AR(eQZ7z6t_mMQJmf>jCvn!q#+eKG<7u>r4GcX9VBimyW-6qCG|i^^ zf9!n+AeG(!_@%wx_ITgMtG!FRybT)Co|>{rMM;E`5DjG{WRye{*`X5IBU_ZcviBy% z^*^6`oSx@$mA>Qse*fQJkDl(m&vW+qoX`2}^Pg(T{%?Kx&$k6r!T-K?EbazDYthV6 zbKey{36v0MltZuwa-r^!_X`^NkmU5AUl;$^p;53C^AN}*zjvcuQ2~uF;2W^}Ao8D0 z2$KRt!cNEcjg|v?4dW)Tsa;OPGJpl;J9ln^w|;I7NVBlkuNCm`+8O?@uYlcXw?8!d|+c2jfh5Lo!|9zCt|8@A@#-c2-3?HDI zz%}M0;R!(XbcD+{A&yg!^+{1gpg{mC7V@8Er3C*j;L@bO1MzekhfpenF9VBC%(Ib} z(DxdmOCc+QZo|fzBgOrIHGCGey=T6Z;!uBm`!xdpTO+WR1^GlTN7j`9+FgME1lf-= zqLyLJg0797hwM5Mvsjd$BJ!}o7yQQlgZRlTq)*1OJn|cS(aHCdwC~ed-ZZ3~wVkpf zpyc3!osww4@V>bT;RV#>m?M;LDU!E0lL@y<1)TK(!FUrMH>NK#eTsYQ9A>Mp6>e# zdoGX!^$ckdD+UiC_SvjTFqVx0w31_FJCs?}X$Gcw!F%V-9_w`b{9btBkhi z9T7ONo^o-L>_U26E4@ro0y{>*K9__F#-)*z?3hRh!Bkgy7O90`fbXx2??V?g)<63V zMiNUw7a^{flRTO#vFpskYTwg|2S}gxqd2MvSQSvwcW{ZgE(`;dT_Ju) za5&gpQaTZ=vzB7@1>4yJ9D^6hV1yY#^AG*R+HFV$(obx2g7GTU2$nCDWfitmfv3Qm zK^|x?lynw-hiBMF0hfj~4^Sthz*w4$C|KiQjSG~6>%qOo?dy61Jj@l?^MIWNH80eh zVX7K-7O))w*)85-cv$v}g2-DDkH!U*A6o@=-52Qd*4yv@+_>Wr{59&m9c`SBzNV;E zi{JG$A6?e~z$2_RDf9=c?gCo#SPG!tjb4C~HzBI!5XwU+3s?u>_p%7(zkoDsbCE|e z^-F_B|8&oRVV2~;zcdi0qsMZAHjx^@y9Sp&4|noA|APz=C?C8^*l_`A3BeuoVtR3Y z2BWI;{ES=AbC+CAnyV4>r)t=;t4Ry4#7$L;7jw)(G2NnnC zH3VeWze=xr@v+A3eYI13<&)@&y&{r(j!W)7Cb9E~#OsVYp+n+=2gNoY5Z$;>)Hbs0 zU2#)HVN*zcTczIq>oHj&pDr1#JLTG4AD?9k+x%*fQ?lJonla-JW>U|2W)c5wC>6L-|ozxBAoTFJYNpghV(hz?Kx?(Z(0 z_DCm2^=yx1FVD{qwfJR^REz9XijmDqBC=WeXW~8ovPb&ww?}IJou6?~k^kSl{Ql|k z*Ty?C`k3;6i%(jQd?nwVWsh?zi6}LYCIW>`xBkJ;!IB44#PoOg324=U&cheB6#{Eu z>}?Mm(=^6FF5mAb2j6RT z_ngS4NmUrdq`=gV1d_$TH*(R-!qhZKR)|j`W#f*0t+0JLNVU8B-{N;9FDak?3B81| z+mFTzJPW`RPJoSDW1v2h*#o)=q(|5i1M?#w{Q)m&kb!~iI+p#=?XanyQ8mw^l?om} z6jZRsNj%bQ%8<*)`y7gC)(&Q}bXTM2;^>nX-Ote7AKeUe%cHvyz59f2CG=el-7C?( z7Tr_Oy`qqx@#Q!_7R2_t#By^B zN)MU`kdJh~u-D5!mj3|qSKfp0Cd7yYA33pa+%Z)TE`KJAn}s%Fi9B$&@QjZog`zy! z7|1hdF8agQY_#Kn|2_PV_Zh;$im@;}=np`eM0w2NeC&Hy*PO&Bj6D~o5rkO%ppORW zi7;v{XkX#lhUkHXXa=OwACv~t19HKB3T*;QXt)M5hOs`eR~5`2ShPayU@Qm2_J(v@ zTUPRK|B=}PX$91eC2HWgL!W<;ZuB(&WXw2AyNIlmNTN8y5XkQc3_;W)_>SW|gQqo~ zeUOCUR&cHfe7%T%2G2?Ne6a7bUmWBTJSYXvz&_~z%}?|r5O=QCDVIom^CrRGKHkVE zQA;y8IM~C@?UkWn`aR9l^evNVOn&QJM{k&6+?nFgJd3bnOT3S9bHcryfZb?pP zNs4JsjBJVvu8nw|Z)fT4?S1Rkt)!@^PhOs%KfG^@_Ah*9{rK@?7Z=wLA3l8k{JA0O zWkZCQvy-!uc>}@zw}+Wq=Aj%^PtP2*+qfwc|Mj^FYg%}8rDSwmAl`KxP3d-*SYfT(ke%6H!x4mtw+$|06T-Wij*3YrLeqT!~-^0kn#Khf1&(7TZt-aY(vpesd@4DYL zczjDc+}}SjI5^klUdW?IpFVxcOL01lrsRjB67E$XDp?(4cCX?<2LG6F`%&sQcTMA2 z!8KENdz8-1Te>&u_TANaHte9n0^yOzoQ^EWIAZ(3x8u@%-QS|MmaP+uk7dTk=e$;3 ztkY%`5ixtGhRq3EwY#q{^_jhw7Cu@^Vg4@QqMnp#MGmrJ`3Dk&&j*E&m467EPLc z$w0@|&C0b|ZBxFw!+D3quvA$mB?Y(l?do?|nOkj)*5OH>Q7LYvpqc4E^-sgmqZ=4f zD|BXUJC@w0SLym$E^A=@!`bz&8C#xbpH<Fez4StMu zk_+V?BC0R-~fJMj;~0|=|wSy{R2>IPrAf^dkD zk&*B7=kKpwD|q&-E+Vux^zA1H+xI%!PEJnF&dzA1=X-hv(tG)OWWH<_wV12kB>)Z728?cIlKw0 ztgZKOadUg_tfQlYu!_P>v&c`Cr&Tr18(D>ihZhtSSZUo*cMdRlmwoB6hnw>=XNSj^ zAGzAt*d!+>#~T~pGd8(-^QM)Rm6^dUTU*cZ`_EBi%Sd- zf1q_0A0s z!2a#W1P|>N71+1!=oZ0a+f4+7cb(XDV8?;u1BB$BJ$G7KTE4Af;)FjY%7>!A0`;$?-pB^!@2jx(pH-gMiu?eB$mhSXigm{0#1nJ((-ud8ze zFfDZ!(TZT@hjo@`JKuqhhoS_D-j$vXYd-0N2^802lneWdVT%&%Sw-l^>EC@z(t-yc z=$5*lz(CbTwH;G<b8l5ED_U#F@v1h6sG=r2y63LA}aUV!-@NuJfgbT>#lX}y=ep1pVG&`WR zCL<5lPT-vmK5#IbBt8Xjh@k%l-R4R32cwJi@1!K^6SoVv82NAG1F3<31PD?_dAnXc zwFA<_*r}nq;XBCaz}E>N6-HEw^%Sfuz`}sUL+ni}aSM9W*6FAP-|Ndl)E;__Khigd zyCQ|g3#?b++K;}SMSpk|@gTjg080i7(o)VJBhp+BkaQAgg@H_(9ZsNzN+kb* zxC-$OJ$mbt@{}or^zdNqNeRTHe zfBU7D=*XBjnv&fOy|@4J=?@=}Nsa0>mAtM_fe7QA9;4~KIGwxK^x*Cy6(JR9x7&?^!_ilSAZ zS48fK$FL{bt9$8~zJoKn*y#*Nxdn|Bribv@6DpHEb#JJSAJG`!YX#M2B5x+GxroLb z&bGV2lETAo33>z=A>4nk;e=lR)tHjUc9=ks0BjI?l@8}rZJ@J;c>AO_h^+~$M3q$w z#91X5*7*yflxnO;L|zX$iJl+eMvSE+$GH|E$uy2)fPXJWzj68th!-Nys9c=hLn^Xn zdA_Y$oOdmPrQL`I+JmgK;Ucw>wT)A8%1`yHtJa$2S^KRtu&W1OEr@f0?Xxle0JIQ^ z%&-u>2g>Rc8cXo7*o4Lp#s&HY`Uc{CF%9K`l}^2b)Q}Eh9YX){c>TpnN4Lpc$AW&K zcCo!MoVEjJy)6A^n-2WvSwvrBSjCYe;1rCbEURnK6>UL(2T^*U*C=lgs&=rX#1R+d zSkNTP>I>)u7PIJQ7y*245Ja9JsqvTqoGG(tto0n`>jKN`fSv}t2G~axdAdI&n zYoy6s{Hs2pPO27MDz1xsXMejEjoGqJ*n+&&FYw!uV|z#a!ah9$o%x8@2q|kV!h>*n z3FTK#^$zNQd=PPCe`kJpi}MJfXJFX^5CcY$_@dST z>u!nDsv_tFA0sgYOJGeyF6ueNWbK+3;B6<;)ZvSB$&7C+nqUO1KUG03CYS=}Kgfa> zz;S?~@h9+3um(v=cmp^de2*v|mqand`aW2HfGeQ{ScSmHe?MAaXZ-`b7+Od!$3Y%F z0i~GG7xZDHj`GBykBK0U{+JvuB@@4dS1KYj;(=AiRGz5}hHiX9hpvvUX6hD5Hb_zE zC?Fys)-Cw%49tWjmZ=&TdJYcd8F76q-z%GaQ5IQ=0ehoFJgOF@4Hy^}z>{T_6j^;r z-pfog`AS>IA5%xIv%LIl-5Rs7NCl_q(=MM4 zIezX>YenhE6NTY1C;I-jbdj1ym|b*G$L@crxK4_qW`OrS1En9Z){r$o^ zmE@btnkz0IDbo3Tf4ExW45u@^BL<*G{*Cf~RNKGwN<%aw@OvGLdgk{AKj&wdtN-Hn ze%Y;RG4v6v$fNsL9KC<(GW_Yn#FHEuCe9SEXDG$b*s+hD*TXdFHbkSa$E2e_q5M@q zVobcuh>Zr8onk*J_9lXVnKFy6BmTt~5G{2M?TcM&!})OfZHSwLT?%#^9907-L#hO- z4kEP!>X7ckhP_*GI=n}N-yl$8AW0+7>2dz3XIoI4!LkLcKFHOzz3g6IVBpQkt!uu+2Z2R3)oC&$rj0S$1XGZVxN+|247v=eAmYWyHCwkqC+YTJft!_oG) zpgKiRN~&fCiwonFmb48{bX7+59bFy_<##>b4xRypB*3b9KgrH2e;?wZAjbU`l!jc8 z9-pTnfX0w|gP(()^Bz+a7X*m+bxKC!;$mhlSrSb*x``lFstuE-}2KV zZ^QeItnvj=c}KscA!E)13DEVuv7ze4X^Br4{GyKq4}Ohg(Cp*DssB{}V2ts}0A1^W z;^1^WY`>?3dO@vOvhq8tM57K|3E&302RmSmbLja61ph=vp@vcbP5^Jo@2?^f?;GHi zDw*>dfp(lkkPF%)vT6Zm08W6sl#XjEX)+5dae7au_33>Edqs9{Iy&A1z83Hm(9lGB z@U1G=msxBh$Zo5R?G4#$13U>>kA88Wqr2I4jPJDTcokx3>$B6;ZT_>@l0lJA!lON1 z{1sltil&z76}A|CYQA02Vic3B<{Yxq)&E>vd}LInT0zT=oF?VW#GXzkAL=AB8ZLUr9E-@fP}pLURdx5l3xU^(qG|PKQ|iRi8&rH^j%PJ! ze5jL3sh3Kt(R}oZ??at*M#E+An4_L=FF6PA$Z6EhY|wNH-X5K!mR7HjTql-Rukyry zaJgNL*TBSjH!f^NR|`YYp@mGI-GKoBFqQ z2-RO}b=m)Zsh3jyVEygU^PG9O#;s5pwrioR!sHX{t_XVEn$-WgU_={u#*N_WFL+T_ zN)ya7CLR~I*wSWVe(_`TZ-%_*!TuMy*H?1oLGz{3wf6;T(aum zlI46$m-8)IHJ^7SA1`m-o6F5?85GV*pORH)EahFoyO4Jc%5!k(GQQ=@`FK~(=Uss^ zMBf*70Z`nwW%p*cjp91+ofBWjgC29Va}0~NeHo(l*mnm4NwhO_z2 z`sJ-p9bO#@in4eSq?X@&C96>(vr#_1;Z$0~$^0h$v|^jEXuGIbm&dO*mNYq~*2^Gh z&1up}&bM%WBOae^gn<2Hz0`+#$&YoipPKJK4cL{G6lC>cRaTQyUeoo$7OSEbn@`OK znGMPaiV?JCH(rfQz2Oyfv9Q^&u-Pp5{bdBsDRp8Q4XUwO1_{~s@|vy%y;luPx{%qZ zmRu*A-k|y>?tJx^*Cj2Ft6Kw;iwx826>}P|zYNt$$~XQ{C-c5eG__tKxB5|5gJxd6 z)rUIC3IJfcMqB(Cs0{KJ0 z=Q@q;9Hqo6?f`}Wn--Lg46Y~~Dy%?>i3 zWr`9Di~7AD8#cyFt3En<-n{+Jr@hMO)c;|1Y_Ptfx&mt@jOpjn|GK15y&yP={vlLf zJZ`Buk2-55{AKGOaLxYSG867uyT^O@Kc6_{w(XlSdvijQZ;wsye{Q64>-x9+HA`As z`xN!z-Z#c$K)*hHcxD{jdrjcP$_10={5c{&LU+{QJRa$h;y1l-zBgzdc=MLQ3*N|4 zR`T3B=j+5<`@Rrzsc-w3e`^ZYw)}Up^=WpSv^LBfD|hvnhTp71>Vm(W@zB`Zf7xFj zOFt$w_Kl8|mKi85wP*O6*G^No)LZ+FTV43O(%?<{`ug(vmgl3EZ7$a8)8|H?n_P)` zeXq~HxYzFY)2B}#J9aEW=YYU=b@eSW!YkJI<8O8TBWv(!fqIqCW3&n@%FoXq=<4R? zrkH8J(`&7S;2wIFH~9@-d>HM=%tX`|pyY{IB_8-6}`ESAzu@f1IM$ z8(DY%?Vm%F9U15DV4MQ@A}^>rPLW4x28mE=Nd_n~{5ogW+-PhU`JmT&K#2Fssz zv3N9MD++!~pq~JHDbPfK&H?KW!EO+wJ3K5Oti`PVfn%S^;u0a2I@W7+pK;J00cQrj zNFccYzEleFY~XoII5v=%%tX)WvI{6_S7&jXQF;laQv^#z@VkYQutno+lm<>p1AY6t zZ>@rOdC)RwA;_MfMxsF>&#@L0TKEf z+68I;{t;uKh)TM#tEv~+o*3=6J%qivhjX_Y{ryK61%5(m;3@c9FH#`X`O z6@(U2?WWfZQL;$nEf}ZnkU0y;#;}NiIamsJhQNu`nQ#;_fHheXEl7g|cym`2%?rj1Qh$YEIb4YjN0!N(v~BajPtxT~hPdrz?3xa&BQT4u3uF?%iK-2qe+=&fOP=(e>)Hbz-D z0Y;{lb;vwqJTAvDXN*Q z(Z&Ch)yqCA^!)H0!v=kn308u905f1Ch)*;HTN2pa$mqh%!|5?F-*|0M?e1wjFeC&1 zqHOU_$w;C7G}kTu-3B^$a| z-1%gGx3b7wV6AD_l7RA~Rwgdwdt(APm-4OpPmKq?6+Mpy^yWw7K`#l9MbEJpI)|9` z(RGZ7#|6yi&z1>o1k4AxhRhbWhz83~z$$=g06)QRpo`A3cog7Ox?WpYB@v5RSQ(^5 zb_naqKMib;53tQK`&xw3VE@246xJTz0YL+eAsO3Q0!)98qxexhfTiIya;(kcR4b08 z3e*mcpag3M>jv>}zyWwa1nmF)*1-M&yBO?JSg(fhK3T6Y(ws-ExA}ly16x*@XZQvs zgPt6pu_}r1!Flu@`<79yz;#YV`aH7Nz#ha7U)W0sW(C6_KnGae!LHIBKDxpS`TfuL z1F$4L0!vSQfqeybe@>AxFqA`1tWAYk=-u`AwSOCeOTt-Wn{j|T3?X#d8)yki8{E5I zfW14|K4R$Wx?<@#hQK-<768V&V{=^d0R#(l{6cxd0{2fZ1t5*=)p#uc#^=P-LCFVD z-^qReHlj1p=n&g+p-vbSK+hl&47q?#pwrOwl|{+}K8EPm*`I+83BEQXn1^z}7XVtJ zj@Aiz2l5$M_i&NE!@1b1s3qjukJ13W0@4tW`H+i_kIB=WC=IM9pygq{VFiO~oDa|R(F4O{8E9|4rK)+Sch+$q8 z_fQbE4rYS7s8t5LjXJWEVNXGCCw;D=1UT1)nx!Aj4A{f~Hio?d<`_ncKyY{XhEatv zBl86HQSe11X%5 zI#d~upHMb)I|~+M!3O4Cp-1Et^b4#wTF@8#4&WX`543^(nuY2UKpZon7>ov$yTr!h#`KL9jwG9km%* za8dS;1R4RBdeg?9OZ;cr2~tNm2k9(oC$@_Oh+|(by=ftiCHdo$IJNa>#+5D;gO)?9 z*=1tAX)VYu=p}V;72rmYcww#zRxge_2huPsVZyaz$R_Csbi#UoT@kMb7*QG49tK!J z5j};{fKEJ!zIB%i(&23uf*Fva5D6f)>oFJ*my^E$$0~6_`Vr6vJDurSAKb@_pD}gR zFMaU8!mj?8KDg)e>HpXC!6YtcUlo2v>tTKdUl~8cDuti%6~&tV|M6P=(UGy)i2s}3 z)^iU(!=;Y^WBMnmKNcv>IHU(By4|3f?)p~1X2222ci~1iqGxnY5ojvT(qyoy1{w+T zE?vhGq;LP|Bd^g?$Eg31|&`(%XgiC9>aq zuS7@*yh%^g54~6T`)uUl2p131OA${;ik}1@W1#hb{7`6;F>UuLTxf=#GvN@ zv-GjVD-n+lmI8nj3FZ}~ObXwsqNH_L_5*WH&bAXnqgz~22C%Sx#>`>r$47*TQ zXv2IZln;I+M^PFTR3^Y0j;{}TKbUjCzZmCIGsJ`NB)wivcyZdde01yrl4~k{G0ZZK z=Ol+_f?c)%?ZZ+7YX5*fD5G`(TtU16jNyBa-@gIHcfP>>25rIkylXU$uCid*@2Hhd z=8)`L>=JAk=WVR<#4`=M2w7b)MzDIRd1W6pSfj8nf@A<-h`#fKCIN6UUe{0}mg9g8 z7W4!2Z?ie}2vXqLosIH=Rs!p*dxGE92wIlWO2v8zm?xMo&`ium?Zem|um}DQ@=A0eG+Ls_TktsC@*m3*PHEjoKd8?g!M~_euZ=2Uy0i zLgMOx)`X5Nu}>;Q`oQ!vr~068RGmM{-&N|!V89txc}Rx9!5@qV70u>IFS6fpPe*RLHN9Vi^IxVZTHq$m{S76tRo z%*;e_cpDoVnM~%pckjf+#8OjJQS@7BX=z^{_lWSfC=4!&OD-uXsi>%!lao_ZQ`6qw zE-x?t($`%|N-8ok^17Z5iZG7i=eD)A$;il{n7K_&O<%rzX>M-z^Lr5<9-ftz6%Y_` z{`~oK=gy%Z!guc)sHmu*z`H0SFpA-e0+)aM_z}hA)zsAV^Yb${x-BXy+R)IDo}L~P z6N91^qtLyco}MVSZ*+9@nKNg~%E|%*1Kr)-QBdQsu&~0yLSy4QC}uH=JM8Q0Yh-l$ z>eZ_#?s;fvXh=v%Zfae~JS8Q?%+xp`KHShyAB8GDc~TZd z7`|(K2Sqn7E-tpTG)2+PQ5<1iUETZlO*F4uPE1UE_|QT^LR?Nx4uu;=k%&{0qh&w(uu%PtzH>e#fUZN2YC&QR;VnzVK-e zo)2;=m-ikpQ_tP3_a=hS^dkj3ziGV>`R)lxaju`*M)~g4s$=%|D$Y% z`^O0x^IwXlo}1?~H)D?7{&$5ME396rEVpXnn=e0F`)T>%eZ!NKENV3LrcvZ#? z!9Q1TH4(9#cYM9Tq(5Gs67aBEFq!9uVB8_?f>G`6i!2(J=>|3pYu_`->V6`x@RRES zxv#mGPcYcpM{ZwhA5V{seFu!(aSKh+FRvUl2tRdwM)C)U6C(1YXL+XeIey0E{^+En zPg;zX=w6F%UUdKHoS|QFA+>(Rg+%^M(&*la?x6_Is#|-OXF8%Z^mB%6(eIx-p7PKghMozbXEqo48P*T@e`+oLClcRGb!12eQ}RQZDg2DP ze(do=ln^DahV&$qWgc!RyW9_ScfiL3k4$NhLBp~bQIqEp?Y5Bh7N|INmL~=2FMAr` zGl0_q{z8o;K@=Cg9FRC*8y=tw$pswW8KeiL$CMz?pi~)Jt@ybBtHoX0!yY>rmrf!G z^K@1QC(A*cxMS!h&kmvQ`;i`K57JptPZ?E4oRvpnaFFM_&=_NB1pcJBQFcz9lYSFZxmW`a{0t{LcGfpJFZ+Dcb>h&L zg9E%6{Dr-vSLHhC)tq?Q!sy9`(GzpxrK)qzGuuBhnNf%cWin%!%vdHfp2#2K7h78&dihe0*%sf?UK$gloRM+0qb;eUy{x07zN0OcM5I?&$dX z;N+5(XnxqpRF0JCaZH&8n51vu-Zz22;J4GJGTs?J$E{ZGnCK)YVI0CUY}69p<>ps& zvocp2d`%vmTkxPEyMg!7#=3;$C)(W%k)1-@}BfPqHyuX1x6?thI7q*8+E3Gh`Ot*>-z{dsC1i8MVg z@EY_^Z*_o7DQKr1QO)ji%~Q)qB#W0br%_E^mzdF3}m`slSjAYr0bqA53mo>+%T@{ zs5}Am9VDjv(GBu*qJy9c?m5pUln1nTAakWIs)eBS2P-mc&)U@%6)Y|(E6_Bv8Pu@V~Rb>sh%>B9)AUr zTT391WogEm&KF>V3-tJ2R=a__0u3UJ6~G^{WX6ece#i^u;EQl>u#$RL2IQAutfG~H zVO{kn@~=d-QEk}BYAfh`K&IZCRsi2bL6Rz~zw8#jU<(c!InaoLmH@_yTp(*F8s!U! zSHf1~2hj)uAGnPL9hBCUfuI!5aNmsHQJQ~J7UmVZMrMZDW!LiJbo)^mSm)I}1-73! zgJvG=V6p8seU%Z59I%$fdNJu9=DBOzIF~2Lf@RQ2_oh6E{RmJ6G4fzVgEb4`W}kqUa$0ciFnVFMQ{PDmAXK4C5`4Ab~$)M-_eL10&KlW3;`GyY=;GQRn$dK z3y=zBQ8Prr7Wf>gc0w1}l3*x+HHYmdAYWG-5~zj1xgu&W#xgkPLG)XaHiw+yWK*X# z3%$MA9|K?o)`T3|U(O;31N|mo0&?N<@h^JW2T(3(3uU=Oa!_rBH4bIL?0}4kT(~b7 zHi+G^43f3bWkZk_&pT+*VZDKM5@gKivlY$jkIMNmb%o2K<4?|13hv+cX$PE!qBQ8V5PgkP zt?Ewe(bKWheOUh4JqLTdRZjFNjOCB=ZAB?KQK-02^w`RW(3}EBVD~|yxBF*k4S)@L z-k+s2y5|2G8l!98e}ulEx4k#CW7j%iPw9!4q?gUU6LqC3*~buQbLCEq4J#Ua%oNay zqF?l~F(rZ5H>L%bd`tTMbW3}gZdotWE$?Nz6}?OcQc8S%zaOheGB#M`G%mc~QnHUZ zr?k{4lD!6d$WbT$z}_N^>csdN?5lz5qhFk;NqS#kccrM7u5E(dtZNGPH014OwED?~ z6*kze4`0=x!&KY;o${R;SG zF?tKs4N%0KQ)8+aLn!PlB)SWZ{6Sg|IuWRao{rusD%~d5+JGGo>ZSInEiCE^_YbIj zunz=Uhi+2~I|kUi0q3qj%S++*g@~$z=+AU56TJ>tqfjR3yTB$1Q!rge2=F%0CS5Id zDei|lkBan+?8Ox4y$8+FX;d3%->5clqP#bITmf|hbP=`(r`kYq{n#oGV1!)scXTT%@}7>dNQrpvvDGzL>;nXzqTxPz znO&)DIxdDf*l{jp3r6Y(`i}TZgH0J|y_8uLAV~o+;9wPfZv?0{0NOi%Iw%!5NXSJl zLg{cCYwFA{Io7Pu=NNMgBn}fU4Y)Ikuf@;kI0fUfpW`E;_XGz54Ga4L?^#_i+F$0lWt}kpkltdds`#0Z0P7e!yivHwGeTZosA+ zRyBBhFG4kgbve1VpmG7HlC=rXiTy4+y@+Q6ENC%CC2JHQ74{pT_hALV%Ia#x3( z#IjbM1~c{)4|d;G#1ewbNvzd;dwspA+qk{eb_zIe@*h=XU(B z&jg+`G9R$(clA>K`(}a%oet8y{{Q6}Ama{_G)kI)BjjN31uPlCYZCA%B`d);*|0__ zNe$%0dkKYga5Of`hlP`U30b)UXpLjremXwmjH3WY;MfBco&awUpdq^BOHSAdOAj$_ zf_{Pogy1SdX#lMUQc&>t>yEz&t`$ZU?9RUtn{ghep0UXP<*@?T;yhm6S3Ac2|93}= z^Ego)5M_@jPQ~W2+`GD5J+JK&OGSJyt>^l$8ci<8o1Jqx+O zhZAIwK+C~ztknap2~{$C++lc*_hUls!Y@j%0Ce#8b`#PY&}n1sNcXlvUx++`y)1~8 zOCKS+t>bPMB~8)zWFG|z8(;&pvz&Gz(ho8+)Go(fH?&+4jh{T?MSyo8+&%joQvKtU z_D6aIPI<75U@saG*a@kNQ(D3&lTePHB5C2Xr}T7glgJ3ZmwrEj z35a9_ai)8dUJ$jWtIVdSws4XU_ofeB)e~%xbVRZNJp#!HH6!fxaFTNL>YOP? zPN&_l{hiU}**lTlu%)FL@+dPjFnsdliJ$G**RTDMZ`&i&oyaQ;`I}w8u4`js!l9CegG()~> z4h{|v9y~y8?Z4slz(_6Z+--p0`42>OP)@ z0;4^$#>?-Ec1SGm=y;sdcZ2fv-`A=Ku5XFWTC*wY>c+Wa-^@rJdVh7le*7aZS92Tg z7WUQCw7jvg(!|B9U!&xpIjT4M9}eGtw4{2k?fwVB>CF zgyTA)lKv~M6l8A)cCu%Y@5wymV>JWaLg?O&?t$n`9&U7t-{EJ>eDups_FoZS>JK!Y zf5&-4(a5jpUvb{hN(3A9^M-z%+x%a#Y#Acyj*O4!Y#tKFDdZ_XW7>LlKP+r>1^X`8 z{}D|jZa=n#*uFQ7+3`iy0+SfWZVWhzOGK1o@etdQ`#-KZQ@R*tT% z0htTPn<<(fYq3GEMX!TYN9bk6F1_MmwHRnQkYf`n8S@WN7U4;xIh5M9O+bIEpz=T` z1AT_LMZiG;XY!-6==={4%0VdluI;5$?VC{4LaK!zS!bUyI{yIU0Pz8Nit#?;kKh2} z1BOWSjK6;uNAbCfIa)u{;$RdOpxMdC`9u!%FwxK7fkpW;UAKtDlO_g#`z5JW%(?JcQzU7B~ z%67TrZ_@TZW$dr$Q+6S+R?IPT*X{7lmwmVChwiZXAn01K!7lyqy%^Py1`*qjnh%3q z{NBaHB?y?uuXN5^do$G1E&Q~xzlCeKyovuAuj13b-3&RP^HMRe?vQ2TJ?F3+b|L(FL96e@&UunG*)e;pea3LxGy!#=?HWD`!HrwB z-ULU+?b7t+b;_INlsC>k^EcbHCAxuE9|mn!_m&H8*re_gpOCo7Bxbx_=5X8e5thlq z*IsSA9_$wqyHY1$kWK0modBb!p)cM>UwIJ3f64bi+41k& zc65vIF5xXFHXYb;{D!u`;XS!QBj!j*i_1%%mW>Y*mpCOetS~bzBmJ+{d~25RzIx^N zx=+8gYXc_vU(slvFrlpv_ci``Yjrkl3=Pp|8)-G$6|Bs-C|Cfy;)-( zu-+zQk6*I3N1Xiq0RBfI`}~rxdBvZ96nelf<(glLUVPruhi$rzy_(y@WNw4{Pq3V@ zub+iQ(q@YzNA_*8NK0F@ceBOn*RRx#w^*pPe(u-z?q&;J)`8WQBe+MIpwrr;=1CV7 zj@=u(_uzg(pDlv@;wC%GEefw4B8t|kMxXKh3|(b=Hz)tvW0`w_Cm5Hz&I>}p|L&T@gw*83KqOOIKv>exK;A#U6-SN$Ikh_S$BZ3cG8{_yQYw3m z8oc~At-Sf``|8gb^@eh@o94J|oy6NbkCcfX0B`O21Dn70d%8^QmB=~X=<_!k_tvKDjN*3B zpO_KZ_k`w+D_kchjuL#xC@lMXp{qCeLAMjGqFf|H?v1U;v?@uyP?;guRH|1Tx3cQv z?3U7fbp;0Xc_-TIm2LIbUR9OS*47Ts_@r~=CJLg4gy2Y2{h{WwPeh!~^_$66pUrIS z?rH7(Q2jY9{nPu(R#O}Ml&a4mX$8i{#$Ms^USaXt*Ka12x88ebuc4{s6&fG(u^_(e zOI+EPAwi`xdo|sc@N^3&#EjG79l9mS+wSJga3#I{oBQ?sv#q0}?AfWM{@1P?5-RJM z`zhI4`b~13@sqDRhu&EGSH!jV;Z8S)O*>$tpr@}QQr_RKNnq5tsX$RzrzRg zM=$?u=#W4keNPJP5@0YqjfS*I^h3Wp3ESV0MCi8=uCa5rYoUh|l(!sFK5$M}Sye&_ zxu!{+I;*_stc)_x@C)E_6>~QpD4|kz;>14{^EUwNd%e zjR!CK?Hixnca%!zi7_*j(}h)&R1&q9EZaU~NCU5@OUm3B<;hP5-Z@r&}mDX<;|b+4Mbipm`npXYRuM8z&v=W*@D@bVry7X5I8o82Nm=|+85|7@RYwj&~T z4eM)YRqN|BVojP*noF%jZgtAkiGK`InVNLZI_A~mNi7n3Mzbdln!IcUn1`M~J^l)~QHZQ+(1r zQS8V~doP`q6(4rixPGz`YQFSot)celG=*8h4u7njxZ0rP#DF%DQME68%ZuNteGOjt z#dP(A%ISF(Ar)1HdiImw-RJut9wnRqp>%Gss7=xHle%V!g?yhb+P$rqCoNWQbMfV= zVPD)o6o^^y_^pm^czn@Dd2;Akg?&>yiZrM3?W&BKV6s@{k88Fk^`&En(zJEM%ca)lf|9R1<<;E*glA=@cejg{YYUKdSDW4*0XI(P7eRBEpc?Q9P z?dNWu(m$qEJ$~s*$*t~LF|4>-+qUf9?6y%{2La#T3&&jH7>@PsX74y~enMpXpI`p; zAGM$R;mwiCPxE$U5337#CgfMTacb@MievKW=cSA#)E=)~74kCfMRco)*AvNA4u%B} z7C&4Qpx9^EvpruYt7=wxFT0!qZ;rAzLKMW^^RIv$RV_C0ld!zuTU zA#+b#A*V8&lmedIL(_-)}e`A0*Px zEpdftZ0gc6Z-Z+;DICAqPdxhUwUF1ABfSpFw^~X}*gyG|j__-RNptcmhHgD(pqVo( zhFh(|RZ6B@TVj%!%2LmdhKnfrV`Q?DkAKte0pFK)k-grS8|AiOK z$8RR^%*%6{xm5jroLO+-jo3ev){3gR%xsxBd8rJSg-ZI!hH*#v)BkLTTHU5?ml=S@H$a6t^RCEop^eKicie(tOkt_by6wyQfW1sk6!V8sFTiUxa=Ks z)bs5n=inVVjoO(FnohynqjS{K>J^gf#M0_jp7?Kk^73$Ep-y(w^{fW%H8 zqs)e@84a3gm3NXW)Dvq&5^9bom0wJ&G)Ql_l3uToTB$$kH-o)sIsRA>@|^6g3~s?$ zva+({4)vcSE>)6O_^CL*s9?O-K#w7V2i?A@e`|+O{k2vX#36er)eqL+9zD;Qhilvl zm0`OU$|_7gvF?hX$E`{IuM0-B&2p429>LXL@S?1g=8zrp&rCcnY_X-y#QfsN=HCo? z*FV4a!p!IP{0(;!f<6^j=a=c_EmQmY`Ah4vsh@{(Ma0HNa0zioXbS{SjfmoYERjEQ z4)57Wf)6&m#{YIC94iDS_Xl?xf8I1%5g_zzmLxF>HbMui2$Hj{mb8_-B zGO|$|;m42dyu7>>70+M1sH&o@lAN53OgK=W;hgL|WI&>)ciqwP+2hCdu`vl=p58h- zI$O7HMKO_)H3$lJtfF%9)Tz_fRu9wCGNYnmgoO{GNW@v0ImkHV`Sa)3babCRb#`!g z77_7IL_`$DR?f`GM&>1V?ieN}B%e4Th5|QBh)brVq@sAl8R=OuF>xGcU`B%}L{ zGG4LlMuwE6#Gn~*t}YVekT^}kZye*Y&OqNMcVr>-45#VmUASZ^BGC>m<>gzxjBokB zUH-y@+Ch(}&0Wzs|0sktGW>~)4h`{he(PiY*7Hu#3;huPXYsM&S(#ah-U_ubVoh-; zni54DQzRPGB^$G(;{BA~zIcG5XMg$HhGr(nUB4zmy!o9-bA(7`jAWpe3|B1J0zSCg`NHzdq#oK=o~4kiGqr4gCC@Hf=hve?JOHeo|Hzt&EE*Dg_0FPByw# z-oo$fF9iD7HrwrP_7To-5w^T<8WkBSAt9l!e_Q9;we#ndkm*)QNvXe|U(($J!Oprt zFCI3#?hCXOMJ8H*{q@(QN4AKMt*>vasjc(Bce=%9r`sI~^-EV!;PIH~i2IgS28PD! z>gp{mpI_K%L^!CpT|2g8$Bt#om%lW<5NdJwiQ_YA2~iZoJj_TU*!gCQ)80a-1D5yn zGfj6ldmVgbDP7>W*Y=*e`=fhTB>8u4T7607tef3E&nug^@~>aayKMf#MFuxDO^gkS z{EjYJ%C}$wb&rzF`Xax>(a%r#Ih^xzy&e@{ z^FGq)L*$bWfriUh@~>LGY8~J5Czm%je3EU952@#FBRl!P*hkD?{dEOtw_z=6Tv>VL0;B@9;RXbu5KeQ zi}VIt^jXNF(_)aY{SOefdw6*w+c+h~rAs7*E_f<6)UvR}z=4AY)($~i&9oi2Z|$hv zwtd^iu>*BXg<_(n6&4lFoH=vs7_Gr$%uLM?L)Z6nYpdFa72@?)#|G~=8JsZ~vvz{l zBhcof?{8vKY_&J_s9YbFGslk|1z~(2?Q8b-_g>t7VyZJg%=M46)%;_p*ofw=f2*X) zpI1}L6FFwYgeN?|4?Q$uRJoh$WLbqj7ey9M3?4hRWd4A@hIiNRJ3BZ@yx$Vf$JOWS z2Ib${X83OI-MLE4TOx0rZfQzhml!;5M88v>WxrpvY(AR4=Jn2L>TA}t-s-0}ZHwWS z@R<(c{bY*9nhAgCzjKApP9H;+rn__1hxKccG?=EeD{i59Ki49KDj&oClLa5HQSnmu zy>sV8Q?}l^fXRl2SLFB3|1x{$&S8(19}Qciy4@gn#$Bgmzag`CS=m_eNzK|Ua6Hq+ zudltSKi}7^1=rG#reE;)Yq;ZIG-+~)xz6+%Py8iw4)ScUTYv6!WMk`)`i9dA;}^L+ zI``(^LJIohZKQf&g6EtVu;E-g?2~U^lM?3tn_=cavma7@jt%C2Gz3hhCjbI#{ z`6+M3s>#LIz3YXaD@^CxU!)~5{9xbZGJX#N+N~TsjTJ{M67#v3eQD&#KCdHAZ=GeE zpM38?)#%Dq2mM+$WsP`oKDl^ddb00XYZEh`Pebm+#r9nj>G*r*CKRZjzkcVCi9Jw7Zad9|BwKeY4wbm+S^82eDogsM63Q~ zjaJqXi@>1f>VTP^COr297(2H|IGW{NWi%Itp4v8asL>SnXNo0b)#@A58^-U6A5wcd z(oN`c>tGYdH?y@b#8<4cHJ#tooPF7NSoPy`>u(Ay>$l*>75VnYqx$3J{ZsDm5wr9t z5?!*}{9NvEZ|1;pqh)xeFc^of4KiPQbei|ScAHy$kar0m?=rp>YcN?P7jbVWs)6y1 z;zoV}$WF1e)4rq!dS?U|xy|~rz3(hcLaAoU{eu92+RJx5L zRD%{5v(M1B@j->dD+dl`6m1&pEBfesPh{QSy|0fz&1ciU9_rlJA37y?`z4;#O4uYF zzfCS)N+bT3Rl;rSgy`5rQ@aG&s|i6Kl0KGWzcfE?uDRM&rP)$vT3fiU=F^^3Ov!= z=-XK5+*tRtsm{Ks?om^nRa2dLQ{COq4G(kQE7zA_D$Cpv=a}GTYReSr zN>A38%a`Y0edDmMwpcCFV@__0c5Rh;O}So8xmHctrP?y(+Oo5CrIL+RstEymBHrj% z`U^K+e1R{ZH;uTy?@D`KO3trT@ZdiG;BC6ur!T3mvHv-(R1#fC&j#0PPg zT;N@%sC52?hwU6majrqNwcK38O%n!>$wR!$2wiYXkhXWj`Z!WkBEl{cfn~Uf0{o=r_&YPKsNqV53XH=u!7fw7KUxohti1 z!xDA^_12+#pKcNmnA)cgarK%lpdanDVBu(kB0+M(=_~*ZhX?a?l+il~G`6 z^VJu5mjlvESh^#mQwl3@2`Xy|C~f{&_vNa`Cr~13g{{35rR83r;g_+`E@7W-5>g`V zf0*2@GJCBCOVNas zOV5i78(OpKJ{L88J!G7H*eDyRn@ocXMQzhc8o&4!Hbz#o95&23Y>=bvRATzJ7^${W zYCgwQwuF|qq}6@Vb}rFzDtR1GHQ?&);9kL}1BOqTgd!x49okp?BJZT@Z~hvJjP>ug zTpcN>t?Ti%)nV7=QMcv{)eITPm@Bor{!w77ap0sWq5U;{`T+WJu@m5N34FV zvFBCZtlFT8EwNX zKLqx)pU~`F7-^mGXKrq;pr8=;E(SSEG}PBe#U(gCefH=PI8-1$;6r*wTtecF8#ltk z!;@1|3X4m=eEoXs)-810P-N6Q%Rl%A0h79N4v7{ocp#Kt0z3v^Bq;=>VjX=-kcoGU)2riO)wqeF_UtgS<0 z;*sx%g@uKokrCqX-2L7n#ychD13J{m!pchDz{t_d*TB%QsIc&%jZMPGG?$nDI@fR9 zy?YmVhS)rOC@MQ2iQapG=}a&r?LsO}q#W;;Soq#cb>bmyuT>5%UM*ibHrQ<(<~cKP z($UnFQkv&$#X5#el}i-hnRF}S)0k234)Sf9Y8^9i7T3Nx=Fwvx2RVN%zZfbh{UrVL z5CaBZwy4yDdFCM&A-fV0#(;5eVAn@+!z`fii?Z?KlZ)@E{o&&`z$fh zn8X-cnjwiIDk6$4)&~(=R1gqL>>!p{2=)?#EozFrm#8rs>@^nb*s&Mv1r$L68zA=N zo$n3H-raK#U^FJb|LgHNp1a#NJ3Bi&GdsIW6WiC59>yd+h`xLO>YbF>qz7l>lOt{< zj-591+THua*sk2ZcjVfwgI5!d$KHv&m2~-LQg~GSh4{O>FJ0ep{@T9CxZRgxx170h zEIR(|joXK>T#tyk8G0&e-HA(E&t45Z6}kH8`S8mzdoM&s-Mo7sGIsx^Yio{OSaJC5 zl7pv1_DAeGe`Uwn$UPUL!_G$SI1_m`HlgJ=NJIlCa_qww2NmBXgElyqTx-Y@0t@B4e7puMFhYfDqIk(?=`p%3t3BK9R?#fwXL-sKX|Ap4hRC{O1s%!80)7lRU%-_AE zE3Mw5bI8ahF?p;X*-)r=jvEyab*v-xKR(TidMX`bc6@W-`MpiY4D%S#&wKy!cIWmq zJG7?afmN0EFaKiilFGY7s)YSkb^E;PTYsssX@+IvRM)*r+n?FhY}BB}r^A{PZ4o_P zO9Wv>-b#+x-r{sz(uwPLiJro*5Dncqx3}xQWo|@yL}x@sr+0Qcysq`3wQa&zwI#AU z9DQ?tRNStMvD?l?6D9p|{NlmL*h@E)_FarVAAfh}g_td8uWpFAO!Tz;@Y%%&P7yJk zzJ5FGY~;1u$w#lo9g4gjekq1%izti;tI)Mpn5xvtPU@PkyaP9@8!Va1;LDlHs*Q0k zu+uqTw)b`ycX4s?4nKHs%U?~pRO#ID_f>zc$v)(>p`YdYAn*8jCvLnoZuD;fpLZI% zKlhszcjcOS(Z5fnR!$pozE`+(xj}=SvhMJ#l=tV|@9p=Q@nh}-&Hwn^WxU_*eHf$u zn(5Q*lM!8(U9wF4;CPo41AFCjzp=Vx=={^4{v-F~(BBP_D#*G_Gix6og;OyD6FI~DwC-BiZd_=%>7~aK;7Y-iWOG6M1O*GIQ zIdb^kz2w`sZ;?^=3@$S2UZsVE4<4i>B_+}^c<0Zby>jJJXy`gxTDW7!cCrRvxNv^& z-km@F^dlX=H+JmU%a<=DBqY$F7Zr6mBI4+*Sv1bg+`M@+osc(o?i@NHj|SB%SI8`R zaoMuPaY^!-gI`dT{*saWoFoV0$2Ev4TcwG$p`UOn_uM&Q_@L z#s&u+m)31rq0ifmoVr)2G-vY2sbkw%Jl_byNI^ez(ce2Ftpg>Gpo1t~V1t4jxpe zSjU1*E3V9ctMIR?$>*cN&J~>>Lw^5!Zn9=T-`weJ^K71BZy0 zO>UVP=dyf|N^c~;5Dm}*QabODjyde!qsM}fMF&ruzIr!h|B2J{e_s@~cmJISPaZz` z^TCrpuctgFxqaQXo!xr$_$_47?FUaDKmC(L`V%+rA4#}R{#+!+&t14E{KV;N$&dEk zfEd3mCVA7fv~W-kb#?m#PBS8v_9`$o#zXwngq zmt9HP5OZ(Ymawkfdk_z&V)4zuM?QKD&OevSWU=t#fMZT3B_*uhocGZ<$?V)~D~U&lClwvOvGK!3s@z6$r4e zoug3O4(gm&fZvGyYwq6R*$cM_=h5oKSN(bioL#d|>+p~~L&*Z!WZI`$9T#_*5ck0h zaw>83%ujwL^)dBj@0ovLfLBb50#kfXRmkJg_2%%Ksfy$FbsGlu8_*x~T(55!axtoK zq3CzJcFfgx(ZIHKJ53u|>cX*GL!#atKjcgfRB;>OKBi_mD8kJ31wW`pl zQZ0^u@X~3L3d|H;7Eh&1gMWJcVO#u`UnS4<&MwnlWC6X6(=09pMSo>_d8lnKh|~4b>FE++OLdmy*h@x)X7Di z9My}=Jo(v_BjmmAK44w%y$`zYP6^nN++uxvgPF(ONA4g;b#hlP{o}5DGf$EOJ9(gc zj@#EUEV=d8yG=IT`f`1I&6UyQs7~(c)dp>Nb5;a7u#+qLSL@<@H{EWqKHhD{adK3z z*>7$3SrO#APCn^%f85n@LxS5#_^OxxZWH;ZyA51Nj_Ty1{_s*_VMy<+{F9z(UYF1kDtm?;#kCqiq7TA=BPit(DWJ8U7VXWOSOr+e?(S|_Y1WY zc8#pnw+{Z(Qo_#Jq0+7ofBUSQW7Vv6-D|t=-LPxuGVih8uQw+5bmxNhHA9MgR_%?~ zl+(@fJ9cm{{EZE|{72oTK$@?vR~UGOfmaxKg@IQXc!hyi7TPxnR=i~CXnzRDB4(&kIC^d~6?da`JE0({cmBb$EcafVyUmMUjoVm-F z{%lh3`2HDixg>`xd-YpZz| zFV0Ek2doRYQKm1!@ntGZ-c%CcGq#vEjW=PzgU+DCg*pSLB0oKBSV@i@W_uA_*bNXn zfB-(@sniTx6T*lQj|f3qq8xtqpjdbV{?R_7WW+-lpXlsOVR#c4+RKAZKj7BJ8gx&p zCGzm0XD<;;Qc;4CfeTbqxL+D^7!7X{XSmAeoe3T`}qH7 zzmL4FEQ)(ki}HJYi|B6uGrx}K7b;l_%e_6K9fv4`N9y;3`ibKFuvs6+d$m4JH1U_V z@5?wPI$5mpse5su^2=Bmr@|$RvXwa1=T{`&mQoz|mNJfGX^S$Q_D|8qDRgO}64FP; z*;3A;xE9gFGo0eo%z^3~`1I4v(PR8|sC6#He3 zjI}7mx9a2Uqd0ND%Q$b9v?!ZS>EqlX9RB&%5T)i%*8I2MwO}QP?yhtP&|ULNuu_5U zs&qTko$Ku(N*=nKI9ZhJ^lQ9$pA@+dYH8y8IC&K(7+^H@rI9s=b~nK;DIE-nGfImc zS1=;>)TGNOO-jf~?4#Hzt>_llSA?%-6bcCfvJJ*yeRyLUV==-ur&Ro>4{u6T>_w?Cw%1W( z=);i~W4V`U`f`yAl`$R`C2yf2N)EaU(Vd%ah3-cMhbW`FSp=vgok1e$NcmtF8tiH; z_k_kyt9BHMU5tUnjM`dciv4V{XBqZ#6Fb3*cEgUu2;qEDVqbdxhFTb{i=EB-s;z~+ z*!qeLQ-AFV8ysI7CnsSVa#dH7ucWMlB(nAF6bFifeW!aV#dW!QQ~e+*^2rJ92s)f+ z<40eytFtx-$d-Vb_xH!{aM)YgcwtBO^m1`fG0AE5kZ?{C9_-lGi{Qb3v`zs1*Y`s} zlNp$dscgX@%SOI@W!zqnZrkh7AX-VB24hb(KpbsLNr@GDhdkFAyYPYTnCh?}pP)xs zguO0>epfm#!k3^fP!*rDX-BQX+5qHmeF}wky+b=^920P2H>S+cE1xlDNBtZpKlh_F z;ClU4&SFRZ!AC)L=nL562|JYwoQs;uv<@VD*G{8ck#{ZP0N#HiXOYf9p=Fz(>SJNo}c%U_^1?H750Hnk-+OAY0HzmRA8WnuimsZ*INk9Ab+tS)x;vc>PP z7o&`=<#%b|tGpG|!(0i!Oy$5Z_^-r?Ok;173K-|n9jUa~s4WwwK8aD1cgGZ*lJ}$p z72_Nh@O@dfXb(P_1lZ*BNYD%9DFV#NM4UjiCV)ot4cTX`K+=7%r;(G-t>sf#1Uw>= zeqT&cUdGgf(*^m&M6@)ZwdVaO!=8G)bxbWz;k78QzY7oc=;Z1oK7iBm<)dIQcw=s{4((|fso@@!K(!izSyoFo_NM-30P)kJH7W}dAy zeOdb4auS!6bu^X?p28;_3(Dn@H$4~xuaWJDC*)&KynxRfM<4JZj6vqm;+t(?A|-gd zpP_u)bvG|ppND;F|1&FFiw8X%0vw4T6{bh^OmqV5~O|AG8k%LN}N(5c)GQ0CNekX%VV;L z4>-z;sOm4`OAXT;NA83rZ7k$cF*O%sdZtDm89~wgl>s(!k1Wj6%XE4UB1`4MjcK7z zNd4HnF1B=NV_r;cX7FqG19edQhWx@DtT?qGdZ$s}PDPpe1D>S~f6?W)CtA0qy9+qX z^!pbL2Wzn0uSL1qU!$D>dJob-D~68Mjh-Nj1P~<&&S!*?vCbNsHg7x|f>ex>;H$htypTK1=2##NLW4$s!q_HGG!^F= zVRQhWgGK_W)7GVh(+HC`jjX$9AJ!bTPy=oub7VX-#JOwBN8g3Cft2(Z{;@u$aU|z+zNM}NdIHx)9|bhM3HP8Rmda5g&IHFB z`VrcmQ&^XzjUhE8adx8ysfNdTRH8U#8{=Ww)bNbtA8QEoSkcQlX0fetQ(MI!IGZ)D zGlB>5AS4=$M%qgchc=eJeEU?3g)s+6mC%2{KLvk73rYSV>`mY-;8S`HN9-$(&>$1u z3RuynFit=cl@<-08izDm>XyAtTgQxH)Q&8C1_sK~@?(a>gD@{`hS=pC@ysB=DrfEG zPBEd8VI&Z^!gvQ-6kqwBsb7vr7!83@=DygG9cMUO_cAU`uLt6+bo2OsA0DG^O;1mv z&VN7uzUmmsd;}N?kSzL^A?T9A&rzUPh@92@jKFro(4#b&%unM8y;T&E$hT+t3 ziRW7MCbc>AD|LyPnu*9)@EqVqTp8KtA&cU4Jy5Vr#i_-~b#`QTmHmvv^zt2lt4lda z368&MdopZ{=%3=!<|=zRhr*`Er?~VY9zTfEu@$WvQ5T<5Sd+d4DOHFbK`BCZtwuHo z4j25WiV72S_zp@nr3~qV6-m>qM7cWC|0+~-oNPIR2`rR0A9!O*ty7yyjac`c_tPp)Wi`hd8Cwa`_$M;=LWoz1ncR%kTh# zv8hD|v!-a#zoo2a#BxQVHD|gdHG}T7)cm}(>_U{RrEkV8)4aqj`V?YG zdPXneFaH)rn{gm(9GmkZBc8!KDiS@GC5l9?1n)qfev#NNZ-Q+>+y8BB_f(}?a3(+E zSK#>mgc~D|W^0~^#k?Q!z&Z7t+6>!eUof`InqXT`$>5%nk|C3T{^ggKOWT-NgiW9g z;j6Q1=W`%f994K6i7ty1Y^c*9!o79O@)Xlqy*VEGr+G{lL(DI1#w=@y3Hlu*hWS^& z{}BvSBH06Ujmz4P$WxVja7wt)>R{I`rGec#jj;MaD;GMEOkf>f$n8yOEQi!4FYCBM zOVs9#vx?2NE!*jB>m;Id+iAso3$zM<>TU8WLE31$)YrxY6=X&s@8fe*3dKwk>o0bM zN6e1dvedyw$MQ`_iUYY{Tb3+Up*(n=F!NSG=oH|qkn&+814ObkF3U;DMSs9F>%y!J z2#XSU^4A2Fv?1V3clf74`xlm4SDH9(H=&8$L*w zbAg_3ezDaJ5Mx%_==~zocu^i&o2`*oNNTJh6Qw>0{(?GTCR^|efhRkqD76LVP1u74 zQXbj@^TYmx?Ofzx32!9U-C^ZLDDvSMQP|hm|4^H9yDvXUM>W#R0D}OF^dvJ zoF8^j=0i>t$5?wwO0!v zmk4Vn!sLvJIbMw^(TmyB2KDPf>A`=&rQv4=I|$kv?F)-vS9(Vb%nnFOLEYiU1WN@p zB~VFv{MMVWiTNGyFmQU5fe}N@QK4*nL21T(^l7<{4X8xWtG_z>p!c9o@*VAhH|>RY zlmqJ0dSC0m%M{x75jB^*hq;#EJ^VI^`ljBWLE=oNM4X;!oQU6^pKCGP(#KWX>H>OM zH!0!heT((H!8neC2WYW^aBu+jrSG7_FUAPu22At#4{i$lLu)rbQyRIk#{p8JwV2W| z+XVUqy`i5m{fc(PY$qV|r0-(g9G9a#ZCm6atYAWtfJ6d{goRf0IY>M3Sz!(d`e&=J zkuoJdGyC+F(pq_oJm_LLivui4`!+@{(I3&1 zAejPps3GRQxxGD}~z7s{Di!Sld3 z!I{}J1o%dO!2ASof>Gc4a-*7xk&fFz^8Q>Tk&9KsRnn*&J|o&SxOQooV$Chq_%>Hs zP#pBh?kYzY5v;?ZouEbK#VbUyz8Pyht@E%Bx6T7v23DbZo21u=>C@IE&8Rm0VHJx= zDRUwX?bWhC-K!*>_&unIg6#G zZ%BFIH`Y{aqz&dYW--lk{<~5h{Fk}!fJ;DDLf-@5(`%3j6LqSu|7n%K|ED3hQyd3+JlA28 z(|Y|)(74bmU@71cRP+kqzf{^7DB??~({EE*V}8Q;B*veNTE}+V$R24&G7vP+R;2&v zTS(E3CMeyg^FWg6sJ1u52E0PL7djD3u#lDb3(H3w*OqNUZ*Sqa=5{L%p<|6N&6vm}>Q=|A(2 zg`Uw$kel@@hXlQ7+cRT5lxKn1TU*HI##T{5N&AQ0D6|x&Ef4Ub7r>s%d^rzl{p@53m@$W+rsi|R_njlZf5m0mh@t3RaBJ#7^lp4 z|Ec<9RMLy7k2{Sz@P2{rCb=c@wx)k0)oaHuK^=Oz9WDH+AO-c8O*rq`$T zA>IU>ccoG!%?YVZ@E3-mr=eB#P%(d&^{~dfHhxC2^*EH&uKzCUVwC*Yf`a}eJni(l zt+w9QX<7QTuDy|}xjW?|jTU1xWb{rdk4JxH4?sL2AJ8sFWISUuz?cB-u9(W*i_sIP z1fw8ZC!pKN*#|KL!_o|9-!OB^bfN3grZ4|4e7Oit{E6NzXvq{*-A5kx98#$tTIsXl z7-NDFtHpJaiLN-cB{0*(bo%V&Jxgh9sS;X|uv0-om-aS6!}tmbPwzD@VTbQJEPd#4 zf}06TJ>J=t%DM|UDce5ib zUtSZR+NH2wkjEpy#dBgje+GGx`-}jz7S&YrYT!t(7i+ng>_K{H%=K-3zTk;kuE;*T z+FqGap5}gNQu`70;c=Qd1?mGk3D3fb*3@c-+{!|hXFY=@gubdy>66;NSm()hde%tW z6Bc1Pfo~gY7m|AlNc6vYxG?Vn`oj1OnZeo%`b9(GMCGujFxOH**C_QXV1f3J87wgq zDewW^0euFRP-8vyS~qwq;{))E_5IMdFutQ5w3-9!il9;Ki{VdFhD^hj=3<%|lVXMu zQ`CTe_4oy+!b&}!Q5C%wtp!-5MNN+jZH_*vJzd)ac&tHgthpQMhQFc&F;`%;yyQxo zp%h$7*x-P9d;^w{59Z()2N>yu#aP6K=FZl5@CY&UC@?JQ%e6DMn6{SI&y9%+gngnY zK_V`#OpG$24|6ZTOh0o$fe(Q*?&a3y^FAx06x1A+bnWUC=_ew}_a>~eZ9=~rk4UYh zE9}RFT_UmPC2T)(g|sy+`nc?Wsb5Xa5NOL6^@DElyyZVjzOc{>i(5wZ(#L%<^};*^ z?0p%PE#q02`z-avKBcH{X4+97*ScIYI?AXWS>C~a=JM!i;2`*q@iZempiC_!m{WsX zs?8C6OXet`l)uk{FYM@9E0c7ukE?}JmW`)pDIc>jykn?OhPctkwOxKq;z7Ms3vwXk zDda3jqwK}hUe)u3Cjq|=QtA^XFq3AMq6b4xkJJ6@(_m!^{cfk< z!F2bdyZYl`r4rr0()UJmN7Ma1yZ2>te= zZ&m5HCf!FL1}mrN-b!H~(S3{V3-o@SenTldnBv+|y`Io>3f*D!o|k^FQ25*Q-Jb4W z=-UN)&qvP+!ElD|7qK7f2bAA(%Ii1Ee;k$h1Kqy#+@9{1bmyjbh3*`5+tIr-{pO?J zBJ}G-@RXxFh|G=ctmQ2ruDE?-8K2Bi)^jwyn z-=;f&-b>K?aJqfyE=>1ex~tM%lkU27SD@RO?w=_BIQsp8?yhtfp?enH{ph|>25%GZu)kM;vS@Ohtm5Xx&!I%L-#a_yO4gp=$=IP7`o@u z-Hh(mbdREY2HmUaenj^=ivNJ_!*nOo-GcILOLsKg3G}|4eh1L+b}DlUJttF|ee`~Y zogeMw=*96qUMk}`URkJ|rF~-qZd(+`?<@-PYe4&retyNGM1{(D<0xKWbA7yk zz8vo%?L8~5WQzCmczwJ)-8tTO-^+N-t}ayGX{(P{VH3xzGFrylOz|QKE-idD^Km?7 zu#9IHy-->Ikv`tW6pl9{LdJtMT2~z@*h>`e&4_ynpHXeN@Gpg&-d&NGHV*8^kg|op zi8ic(nojPJAj^U_#5`W)D#P@t(}lb?nb2L6^_Dn+%qbyH;?VM}KCJJAm$A@Q{* z?clC`udQl6Y`@_Y{J)<`I??84kO;qFZ63fOXab|EwoJgl7|m=>*6AClvRp5cB4DRP zd&-M(Z5?8SLFAEMy=1PoVX$2nZED-;Mfv(x=d`w9Hm6AIGU^dE$yt8Z8nsZtYV$Qo zlJLUEWh_tlX(FGRYVU!EmYm~78qUK!G)PB#h>gAgIaBsAwjjwiM9V?mx9(5cok}qq zE&MatPY`86Td-4m1N*-V{X8JGNAcVbY`N}Kn;?Rn{oSjn)>CVpl_BQ;bxAvFNLmtX z8fLJGGNi=pN41b1wEXt`9<<(6PhgK%zL?`lz#^r3V-(`N*k z9xBdL=2M!W7rjOwvkF0jehAxtkh-?ubAn9%Asi!A5b0p3A66E@j|9CK>t6#2Lx=-^ z71(+ar=uELHZ6>2Rbfd8qV#yfda0Q@Uj_ ztj|)4NRhexjhOp_)`p8e)Zkm9710X#{anZ6G5+%iinSZCkq@NXm?!)b#2@k$R9Q;J z3}W*dB%bd87QxeDZ5I$&Q`n3Dg0h5HzSt$V6x9i>*^!_DT#Q@9giRL~bhHewU`BW) zqNk!N)N;=m#1OtvqHdTs!s<~`KP`rxbQt!bcrtg#9f zV+3YnN*Q{@i>KXZ$q`T*d#L1=+~?BcTmLM-GeRbK5q<%A`uwOawJ%$I!H>XOnevRh zu>3Rk(#&&)XM+&(=0LhLpT7}9#D9Xa&?m4Txv}ngEJ;q8e!TRsnLc$JA?-!n7oLQY6J$i2dWg04lG30) zj=okh*0Vw?cvX76!`Sz+myh^EJEoWRMe}WA{q%iB-x40w4*qGrP+mlT@S^}7Wsbg) zTKt*OYkFn7tGu=QbCjMDht-!ZB{uD7q?g(LUaj@5|14wvtGNF>20)kk7P1~0jeSNh zxoYX>NwbYJvjA7gM66_~uEunX!_A|Ecv+H4H)E&;43SQ(!%a%9VH z^sF>#99!5EE{L!XDX_09QNfE1qaS?sfMH3UX0h2e0M95$-#u-#Nm;8l(aP#&s80$@ z#`E;KjJeOti&2$!Dq$O|(6&%xNW-vUmLbmJOusc$>u6Pq39EHw`Y$XIa$YXI^meIb zpf6QU%?0_x;sASbWwO7Prgp`j6WuQKANDVtja(+x@`m{>Z<;A6O%`t0iI5j~Bm9Fu zGr*^}Lu2JCxEQztO6B^(Ud#LFp)RluqnFFob(w_^yEv7mJcTvA487GN7;726YWHq} z?S`=otBDiA0h!zkBAmhiOBZ+&ASy+e2*{ zoHgY(%S9G;fjL;P!O!u9Ef(Sne-+fnCm^6S&>^>zv~ZNBZ(=UYj#fEUqa2ITAD5>c zFRE%{R;N-${(T5)tll-9K~Hp;p7(3D2oWzZghws4q&EE%vM&z`CZA6SSu?#r&eA zjTeJqmP%Qg{bz9dV(_Dd^W|VhteAvN0j2*l*ilqT^!e$>2<^+k5wskhL*hLa(;qAU zUf+a&xGY2V?H5B=`Wn0(tijtIqX%T0e~PMJ6kTayeL2`cTZ?m6{t0?|F?1uLd^uR@ zLXuhge}r1na1Lk8`#?Ppir6-}unLU=z#0boC;NRnE z65ISF%a9>@I+Zd&RiXoHd4Qo2auv85JQ<)d8Z|26O9e^PdN-jC^i?ap%GyfV2D84< zhD(tY3;!R?gvr&8oUdH(2pYinX#G$~v}dW`r7JDz~dPBqPZ*Jxb8e zy;$Q(Vu(*D!rY*B3t*#VJhzGY-vS50j%b4{r>^=9tRL8&w<`^tay zNvr9Z?`(&i%jE@4f^~OmFF;_eosKSS^UMtVB8vCu++c{su!&Sd|nu(ECYX5cy5V3J@xN6 zMYlTLu;&WsnLi7zDXqHTBGy)PvBJKJAqUPy!lBJwazBhIW+9wf;3|DSWX&;O7WVWw z6SWe*k|zHvyj?)1$8N@Bzobl1ym5Szp)ZqeMc5*ws=+D|vgqTUgMoB^6+pWi)7l|E6mY9FDJz_I7SoeP9VX>x%K7>nXXA_@1#G@VxE8ClA+6nrQTSbErq^m`z=SuS84R!jvsIxz$)~8Xo_3@! z`m^?bKCKU$GSAZ$QKev(u0_3y>NF&4SVT+d`KRsn*2A7zJB)0Rj7L1k;_x>T+PhH_ zgQbA?rxJCPbgQK;+jS6iMr^b<-nA*8mnt(Otw@ZdN2BH=KYJf=i)ke|nJ4V@usQ&D zvbI9gz*;2ONc1z9nAwE~jPTEZrYdAEJJLS|uPsAkgve7*HP+Onrxw|(kb~C7ptn$Y z5JelkgSG8rU57t`W*CvZ)K<@z^_M-JaR^_j%#BXI#3RvSa&@4-O(Yby=*8G-W;~-vsvZW5RtehA zUT|jS9T{1_1}QTAv!@pP$lSw8554WNK+mBvJDwqT*gOSC$(W`y8r38wUOpzR$5E~y z`-g}++Qy-EUzZwzkqgV5MZUJVnux2%HF_!5u*0Hf?7jS5@&-;Rp-I0iZEj}0g87EO z%G*Wy#wQ&N^J%dBMtrN~%h3_?Pk~Jl~6uZVwLJ zjpQF|*tsNGPR3fgY+oVO!Y5qr0-7-ldaR4OGA2bYLd^ozc{_8z%_3Awsom>)h_Oz# zd;0TmOFg{L&oRyLiW3&l8-p^@vbM2m#7D-k3W_o7Lz141{fEoZ{+D!>ahak$jWSYZ zT3T{M+iflTp1_ApC3=^296^uib6QzvS>ud*lD@B+V^hmV(t|-8&&W}JC6I6aMXh3x>B$WO>X_$J3wyy^4S*QKYb0dXv2JiX_I zKBh6Qn8OvAOgB52bz`i%M)6;kc&V~>F)`L7}~NyyK;RI>MJlJa1INU*v&`cL*UC8DpM<| zbfnK+)YR-87uG-_S)-Q78S4yrw?;Eud@3^2{ANC1tnGxY(;COmmoLN1D?Q;E1xn~e z>jKR$GkB#vRf`AP@FEuG#f>=2EDV4QSPxRyqciVqr^-sJn9q-+XwXZnsP@HO`r9fUq507QkhEE8AFMAhCgPw0|cTaoTjUGJ9 zn74MmgCR=~zFM@t6;$#35ZO~soR>KS=J=_Viglb=g%!ABR!E!}^89e2_JECB*H$^^ zFe5Fn%=_^3875y-yYwfHA};n#x1-g*e3qsNDM46;#|7vIIe>GqRbA^rh}LH-5byD7 z-P-2mbLsH;1%`O1Ks(w)6R`1x69wcRx&m5-&OAW>1WdpPI1W5&z3Cb6pg;V_zMU_E zDu8?Qylr9J96rq4fzriVYCnPztCL?8jJETCJ~(^*gD`U5&jKIjVm&mx#g6(uw|K^Q zWFH8zN`cqbTT?63nZ3{;9S+<`GM7Z%;T zu{AL<>~_NX=*z#JIy@?TOSjF-yjD!Buw$A3#iP^zdV1@xr&pJ5_758WUdV=)cW-S@ zxUu@$wI$I}b1z?>xp#AymD8%+h+4m7bC-1&2QFCO{N~L~H*bcgBwu;*FmdSw=d0(p z%wO4b{)wg&50zbfw%O9HJ@4E+o^WGV+?CL47sF;B{qnanwRgr2iaa;)^10#BQB$s8 zUGn=M9YRj~jtX&X@?CSsfGxuooJqWX_OAy?Yc98+x2w^xB^?tVKDnCo;C$l4=zEW6 z?~D2CQF8Bz1y)~fzBIz4-_#GvbY4Z*zWDp!t%({wzvSxkEtX%XJ9R_#0g}RGwJ5VKayg$ z4xYWf+}Dc}?mwBk^=A74-%n3?^Al==EWNxMc`KHfGXeCHGq7%Rh^BSbyY~LCA%Whk zSIgC>&?HoCB^m)6HQ}@EHs}IiN`f0m9bAv~POxrO0w@GV% zS~_d<&^J6Sjq5dN?&a>)f1-ibP(GkNqUi^>_2-OURS; z-8bHPbL_a}QMprw=c-h)j{Dv-5BF5Av}^aU?0E;}b(=WB+v~*f<1S@gvo^1O_KSBn zW*K66t^Y&IkfAkW6Mnri!K?2(rAKZq`+AO)pz%M1FOK_Q_>bql zolV)8r^52Qd3JqB6))P$y;(2+cD*`O_6zDjKT28WGR~#Slr804#;2@v<#H~S%at$b zT)wii^DnoY7V8pp>*3!ypg$*Y{z6SavCCC)(N|2MAT zbY26_pK*7yeg4duCKe^!@zwb=ug;(O|L6Rfg6AxXhnGcZwb}BY@5uSCEmWGfv!tEP z62H=-d_iZt;OrQ2^`kgf=kPn91>&p9Y<*KBK-w5@Vu7@QeTc+m zmZmhxFz|ftWjKEXX*eHmDi>aU$gLU0g_a>Njsq!P=m;!TYxPtgO2xXKw7basA!$Rt z_n=bTsaBBZr9I4z^a8FSR)Hb}njZ8UdErcCtX_k^6jqI5Z#Uk1M~@e8`YI$asr`yw z9eYzs_R>UZ)Do$MJ|If7qY|(Ky7nwheHiva0>pfAe0b~$9BTJjVr;TBC~|=v1!Z8} zDoSF_tCZ@?j(zL{=nJ0|gFUK&3p3mzH_ius7{D*~3c^16&|UO6Hp7-|330ut00-N7J(Mri0$BP+pTgQ$J=TQYsz#)Lu4=d)(GOPA!ES{0 zh0qtp7t9^=Ii!qFKFgH#Nqyd0EmvAOB#!0jxke}iH2hnWAonBA07}Q@N#30v#3$UT z?>3=lSKg7Rud^Jja#+ihTDF^J?h1{SeAr$$Ft9B|5 zagJnd%BczEhf@q)DTOElahp)9qD`T#qU~AhH>N`WV*Oj#%h(PCit$(XJP~J=e<}db z{9=bb*5UahPC3Q}PKaLGn|?thcIsEOrG(L&pb|DM5svdXafT*NXRJqc7kB|@Lk+MK z9QSdNLZR5kG%^h5)L5s?C|pr5J$&FH=p&fFz&yJaOZ<$UptYCDQaC^HAGFVWm}!&g zRL?u5Ee19b-VYlVL6oFD+e+k#UwhTVSmuni5>A>3XJ{PEn|Fw^XrgU-clkPta_mi4 zrREhne~<2}bUV|Xm*nKGPw9NZ$8=^N{nnyiN4kUP`3jw@H<rOE7hi!~|k4|I>Cy9nLasje;Pw*=i&=$=LQuXNv{?``SVneGs} zbI`5O-IeZS3cEsg5Iy&!y8_)+=`Kw7|I+14{0BP%3OefY}th?tw9r=r%KxU}``)zDLstB;-! zzZ|poLUh#4y9Xj;_g}iU=GcW5htDoKcsgW%#IEyKcASmeb0IqHY}Af3k!NEQT7EMg z!(GOPr;%)U>Tu-j+e4l6jA&PBc}V_(*;hGi7;3j+^Itp5xMcUbvhhh$`ROfAUGBOs z!KtnDM?V*cFY)VueADpkVYefRK`DTfQ@ztq$t zZg{W6*&`BX4vh~EyzJB9NP+hb`ugryl#`AQH@*u@o<1OHlwaa^O_K&TzBjnZ{U1BT z_whSfqR5j!W+#mgOd8Sl-VXsO<9nox>5>xM^nOsS2Ll?$wyO6ixXF{TogZxYHD&&& z#A(4%ZJHeW(cx|ENug$4v`A32t&UJUl#q{zIKQ9a+BoO2ev;{G1+p6@226 z_vyEukB7H-(lF1{FLVDnu;DKUeFyGWp01ku^hf`v-!}epP@_NRes?x;MEFhLqqjR= zzBhecOu>!U?GD^(xjweg*7&j^7psLGS-$X4r{UrG4<8LbaI5*2ILGbr6?Y~0EW6zB zr(++jh-z{)G5E~=QBjZPFTU)to9hoYY}oVw1f|Ui*`q9!l{)`Ebz0lf^e2 zo-*?Ady6hL*cl&qJbCEJd*AQ6*=NaR&xr@B3=MzxR_K}^Gey>M!k(&Rt!*DrK((ei zwC&&*8yS5iCaS}=tFhVczLtH&aQ9lfcNH!2aKVEiac8qH=-_`XI)A>&lbZMp$=V>H zOWX%DTC_+wS2=XRBTJTS)dvrD``pj3`g`6kJ>MKWZAb1wPo@m;JyqdJ?sa|Iwms0} zcI0*cs|Sy?jlB{V7Z=n0^^b=}~>e`c}#Jj61@ z?nvagqbu*+8MQCu`m|;Y{eGN1Uz}2^#|w_l>=}eZ+-D%`W}!6}h0n)%mq!=GM6J zOU1iu{jY5s61CvVtG~L(%&mT7c7=qQrIS{-irMmQ)Pnlazt)PKTQzQW`I|GG?o6}4 zx3cMtO?{((b&H)-C2n@Pn=?w?nOZbya^VNd8YgW0CU#EcxLGbYXOz4%wMf#Wk5eWT zc)Ya1t#x0=&nkOsdWpMJK2M(XQObn;568aqWO1G3y+0)I7^ZP4&9xn5Eyrll0 zTfUi<>s0ehkzRlxJ-auZ%erRy+$VVS^bwPPo;_^hk2&qPAKH0fZ)rP+>;?10L&fmuHHQwi?N4Z)ND_<7mvEeo=} z=QMKs8%o@!H$uKzG`h2mW-mkb@KR;V`;;Nmd8NuOl}b8SARGE8B@#V!3H~0#%uKtt zknJ8(uwXjv&aKSN%8kfP#tmevIX3^EZ(XLEqaioP?86lc1Uu((bG@C_-tX7__qW-P z_^EQPCkOhM@NeMr>!&&A)|+v5vqQ;m=k1yM>Du5ikxI38%1^^{I=@#SxY*M3gJ(_M zb}#lj#)E4Ygv~DV)z}}gr_CIXI+I-d7kCX>+Gp(8 zvAcKg-WeWt;lhRRL*biuh8{kAI5049LAk$Rg2`BBImb;}>TtZ*Fy}n4MUH#3NS3S< z@{al=*K66DcrEc-RPfQCVzc&prWJl)|;9J*d7TOLFj=MSmLE*l|L#likTI zhYNXh_{@9jewPHxv7w8O&vw}JN6@(VN@I3EO=(xq-ThXu>!*e1EDpU?vEG4?EcShl z{86S==?}Ai+^Oig*OL-ME4s~Jo9)Y%Q4ZJ6-)NP0Q`IYV7Cu^e>hVX*wk6EX{Z5nK z)yG^dSgPqXr^E|CKV9@V=0vWgPal4qNtBCmpUZtYmQ8F1@d}I#*oz zt9YKRt;>{{@-WBei{Bf3XwniA9bTpwlnMIE@^&hH1y0ya;_S?$Q6%!-xc4X~`O(#+ zhnMa?Ja^|o49&;xj~TG-G?B)kg!|vFyL2t-(eZ?o19A6uUB9>aTJqYf$;+aWcE{Zx zyf$*+)-&6#r+l|2a^RM;u_=#fdY0yFcg5Y`e&ha@>nW%1KKgFul|h?nvT|3|0sDei zTpbj8uJNx&8qYoEHRrh3>=WLzPI}LX@R@!}ovl67WYW3d<Yh{YfA?6Fz`Ua! zat{uBLn-d>ShA@@lP;a^WG&U~WA}G%Wy>*tf7ey#5(4v7nm5Q}L!|wk?eQlbXWQXf z=-r{65(a+$i(TD?4|>_pJW%k51!Y}FtO)3`alrhuUHZNe8d11Z^7&z(W|^A5`iDOk zn|3%R`;SF^omW&mb1P-8)9W93#2(1M{&BXyZWj9HVX^-2<@Jc4^l{_N(cX)kl{KNi zw+Mn*YmLtjzclc6;9n&ttazhC9}hRj3ijVjiht-@Xm`C5yCz(7ZywR`{EgqwzH_x) z>5@wK$KSNhF*kJ1Cy`%g`C!mSpR9ikxHWx}jdswE>=i4!&}278_N|4F&(S3?j_j3u zoXb>pcBx$c3r^5!&&1r6KsP)7?Cn4pqIO_x8Bl1BX4}m|O`1-7Ccj_!4ndo7U#lLt}@|Iw)~W*a-J*itj+D(xymQ5r;~==DN5}zm=gZ)3)5NMcJ*DDOX!oUl`K)%?8%D6&g z#|^PPztH*(3a8sRzi@%<`0L1~Z=7G)Oy4lSP@jG=zwm_SA++-gd6gl`cCz#Dqwp}g ztJ9oBCAxp5c#Y_eru%z(kEAf;{K7(lV*-WcqI@e*9!u#rgnoO`H?#SL6e{Z$#koN6 zcp^WF`=aL;ya=WlbkC)`Fy()V;9p7bbf@x4(0d%c-=VuZef!|gV5Km@^cy{oqp%<7 z_NC|cbho5CH@z!#=b+n;-ks?;AN>}gUniTj6Oo7vWOf7?;gqMT~^?EY)7=JSHB`rE7dJlWp{QGe3*xBqMNd86YjO3z%b%J20p z|JCkq6Rx$y7v4HxN%M&-@t#F#u|)3^*D_|IGA$-pnd&Ne2Qu7{`rZ9&{r86C$I*{w z1Tk~Svw;n0&aWeV>8uQ(ui~mjU%S)JDZ;A_H`NGp@GgNzO)=Vm#+briEd#mo+%4i`_mcqA*bHqO@>&68 zGL?DBrKnx1q(Ykhj}a>Kdf0}`2+zM!3;5tj+LRuQpiAM`$o^7T8Hx7jszZuCeNOUf z!k#)f$HOZvo`>pr#k&sjib|aBhaQA;YvHMe^;hr-gij%M;S{R~t)Y-9)3UdEaHIUN zBM#?nr=BHfEKLikHvr(m@%=kLL5Pu_ph2bFPw_J9we@JHs8emiLJE-=|g?Ildz z@YB_LwsBrEe-T$p?XJ|;pmbN+2=tV3`Rsf5HF0a;*Q{iF@^egoM+ zjIy?1K=$_Jbt`$ZOk)NQO!wN$m3V+y5h{G8aE1%GxRy%Oizo8a$6?=YJEHd9grNY+ z4}M#=^E8hy^2V<|fAB5#DuqPBoU>y(`J2bLoj>n0C;Y^HKVRE=`hv~M{W~S-a|LaCtCSUIdyx#|PPy4BHI?RRaYac28r#2JsYG76(2M*o2a$9s z_Pi0}qZq%cP`T|0UMcTe#}KWFQ$i|GeqWGIRGu^@XOiZzPdd&CD@V^y4G=Rf}dh-|5dn&2D?OAyS^N;@yb(c5g8RboIU5092 zLFHt!Wq|F96t|3yzQGx!ENhKtW4Io_<~$i~Z;K~`cmFqeGV^hXFHo}ao8<2@9`K5I z+R;u(ZZ(OE2T_fUW1TTvi`BB~=v0aRm(x)#s8NemjA2#O5e-oN9lTbgGQb1%qaFJ5 ziyiICQ~%TRTHv-kjbGMWq8!E5a}?mW9QEQsH0HA|3M(JmW*w*ojw-$!2?NC`Ch|0o zS&m{ltFaLeD>=&8j9Wf6uE-Oz%&Y7F1_mHELHfdFZO<-E>wH)j6>Cdz9uHO_YcHd$ zD#E0k#b0d61R}n*{UW0jSbwVJ*qoCb4J9WLWymmZRV&cW7wGj0So@8-L_4ZIuOt^M z$lDM$jO$LJZE1B3Dfbs6ZV#R0n=~7Q)<$1U0BPgbtbMF?Nl`C3A0e_cOE2*uapkMF zxv*^5&JX!!HcuboQCN4JUT&GqtER?E@*?sBmC04^>E&o%U%ei!P4A`ZEpkSRTf(fK z`aDF>`Mc@Go)dpJJ@+c})S1D78C99*=1Hr+#fo>f6~TT22|?(>u*R_7Ea(`!bYL$w z?D>dG`!4K&SfwZ~35|8A53MP;{tDZz-s&LVvD0iPf(WbLWy?agfn}IyEU>4hte16I zLxR7%0FQV@8?rNiucAh6$g07Y{yTrGscOSql0QMNJ*~P8<5PV#M)2#bb>njP>aF-`%RkkC3lvA z-50%u=XbeX(Hpp(k*XWPfn9;Rsn|kWf?s!}IGt!VA{X%n#6~R4U1Eel`+!4tP-7w| z-miv7HxdS@{?6bzuy$8hKgxIP%+36axv-uWa%|2=^lTv!22#0N&cN@m?D*-v z`%z7??~xdnB;F)^*p0@UYRUOI(i2~>X5%D2{aD^6jizKwjt?00mVCqj#3-G|e@D%} z*+}K4mW_VTRMd!`u>Y)(4bZ!IzXG;N*bxO_haSW$M)6Qz=IekS8cs0^v3v~BNT zC=>JCz_@_AIJF%7nq=8}7>)4{Ui~6JorGy`|B;eVgJRUJXF%Bx- zps%(eNZ~PMtN}QtKec;t`pX#Iz)xoMB>E0!U5crtGbdtNk!_m!I>=t6hrcqlxo9Vh zWTNeG3LxGY!$z3R-T|rP6V=u95>n0&yqEuENiV(*nS&YdqK+QwT$}B-5Ow9){Kjo= zj#DG;Wxjs>Qd?TzLW07~LerxyNkfR0c_?JMHbnJO=a95+D@JO*;9cR{HsfUn3pU?)DdWMV{wK4WY*k#olR3L0YR z0egsP^#jxrGCcUdgF%{2FNIN(5%5A{>`L}oG5+w3GQNoMwVD7uQ@=)-7~c+526pb@ z5f*q$A0F7Pv{F?a>Q!hDNXX2ixosTOkzK3n*}@GZ0DZjlAt-BrpexxJ1^my35k{Nn zce0o3Da4F#%edM;j2c2(X{7F@*MOdw=g59kl}79I_&j!!#5ur_>?G&3Ra#Yw1&y>X z(HmN>6y3$BHLd-eG2&NN`xnLlXr(NfJPY495*hYduSa_bLITi_2t`$XE60TYcCDVj zeT|q=Qe}mn)Rt%+*?!uyRU9b<)?P?TtZlJROpc+UZ6TkfI7AHu&%xSi?KJ0-e9eHLCyzNVLwXn z_4?F*n4hv;Tc%|160xgnPr`$?X7HXv-vcL>+DJ7ObIj-L^dOqPJuBSWOwjN3-aQ-& z`xopayp}=evZ7wlN5J!;A6lQ2!jN-58RRx@xU}*=z8NJ6#-_9pB982VT7HcXg|u!S#jQgW zwH?@M#c@STL7ULZOdM(r3(GznYJ^irJR)uS+(5)qOu2>#wU%}`L@TeSuh~0`tkhp2 z-@w*@%bKI9pNZCawTaf^(44;YCVCcpgm*jbNng=6kO0{W+swYe=Yk2FDto!XD&|S4 z(FWY}y~%EgQI;hLP&#;%6MYe7gL{E?VS7WF(5!iHZ9AI#c2Z?2u0h8C_4Y|4M}oB; zoZQ&T+-n^OvOWYSWJD>Oau}pxqin`fywLHjWik%8<#pIYEys>@O7>FhN;Ng6kWgrM z&IT;di7|?RM`7iL1M$#~^yHL^X8{%BA_Tb`WjL)AFH1tt1@?QY+BRcQ;EioDK`K=M zOI)hxlfbNqX~eKd$*Ht>M#(5oSbBoe$_31@_kj|zw{Tb0_GYc6i2CW{noINAIt!W7 zJf;?N-3Z&*4_Nz6ug@SP^I9EaRq!d>Sd%>)5=ei-ujHG0YL)G0&P4^}B8T+a%2=wt zB!M+qjy2_HTrjg>+#~|JBm^jOdG6ok>uY zkVQm4%?t+3`H3xgBV(@ie<#K({>)tX{|bM8#XG?*#hkyjw)Bd3LauwoJD-(kR1}&sV(ker z^;#3BZB8(VeKQ(STwHqoXD(%Ebvg8nj;cn@y#(9?-b46>WfWEl;jM)?qo!@G!?0J5 z%%e@34GOyI-<9PvQ?LJ(x|q|Bd0VAtGv#(;S}m-dVH z**dLte0*`FnGiAS&T}y0P2`}Y>ZtM^rNjCHk1FsP=(8vrb~5-l!^=f_R5|Kwn<95d ziov#f@N-Cts3Y53d8PpJB)o6nPXt>FEHmAy9LzfvBl~_af(zO+Lhzj}XRuTR5d=bW z1ytDOg88A*b4qypImpUo;>o=2wKf4UMq!rBoQI$oTNo1{$Q*$Yz0V`pnq!*PT;zdY zFSY-J3IRDd60D_=P1(X(pS}R|-~-sj0A&TyY#gk9U(sA$DOzvSN-0U$w!V0*WeXMT zoZvJ)N#;#2WjS?Sjx)^z@@4HG$ZPYM!eEUR-h3P%92#rw1+~B)i1o`dzVu*Z?$;0C91dF@L%>!NrbO6;g-`CwfJNHE zP-FIq1)O@`%QiSs`!*_egfE}IFKBZC^_Y*B@OLz)bCe`KP%D!)T)SR{DMs`{qd%aV z+6u6cOW#etq3R*$%Y>YJ0LtTH$8^$g>ntu~3_a%2qpVrY!QL3KK z0gv#H)s_mn2F3EM1LnUmBM#3R>1zysOT04=g?}t~C_F0BdpI6Ail`~#Vk`p(*3Uh` zR~GUa=2v;d>rY=Krv@#$(mQ*`=&2tyFu$;i0aiZa!n5GJcrL3+!hMr_GI|{#=|R7M zSMV_IRXjhY-OtNNn;1QcswvH9;&Z8xaN++%x#p#c^>W%e^6Fby;o*sjnhDsAd4MiD zs;he$Zb&Wog3Cc|6ZRj+_*Q|V&{J8O6XXluD{7wQcdUu!%eZG;<<##u|I&wUvB#1p zJvSoX1F@f(lsLf4K&Pk$U)VFkliJ!P?H#)yfF}6zR&#bsJ#AB=l)SzX^nnZK=}JFn z(IYr5{_Fdj==p*pXt|W&2JHL(?{GzwZLPrws0D;LAI_a>Ch#k3oBk8ivdB$4z8O#K zg%1vRk@Ufr=e@$G9wE$oWNu8O;4jP*5C^CR$=OMZ==fz2%<8%#WJp*-1@!uijpMb#tkpQcoV=fBYcv zVM@ZiJCR8VXXB&7u3rp|IlKC5#G=S!^X88A_@Hfp!W}*;-rb>dNZ{hD8#^rt{Lt@x z%b@BP4^9i2+O&L^qQC5)zyId(c}EwoiQ2M0cIV1#TjxiunSFWrxYP6c>=^OQw&3qh zOg^`7+_D+X+`BstTQ_QF{NX7VL&lw(Kl;q(SCU7 zkAX}3R2W#Xkze7D+rK~Y)ci_6*NoUU`1qzi6Ni*{Yn87?_mZw1KkM4Y+vXz`+JvV6RL#$R(nGK&uaH7=eMkTr^CbAAN;n$gqrqU ziU!W^UUz7nV&A)juV}S*Nt4~bH{3qA#t%UsH5^d2Wq3c|eLd@M4se;_UU^Yt%l39# zXMgc+$9J0z|I&A1d(S;RzTDNtJuINgwpR1TemQ2K%lAEt|JcuQ!(6X*v+DfN>(ilK z-yhzsK#!I=Ta5PdUF2V3OY`CVsx6$|bKlO8(Y@`r|K_o2?ZiDh7VO&kYn$<{KI;5& z-q!Da(B5`3-(!z}3{NY{avi4?RXX6;cJ2pl z{o4oZD0U=#&*2@Tcg0?bac#04M@5c`%$4)UQ9sOEoM-B|Nj2~MhBHd%b$!jfXovjy zo0RYUR>LCq=&(rVg)^4_vUSLidE-}&UNmFI^o>rnPKF)NwS4=zJyR|pzI0~Sj$`}J z?v6MVR`bBcu$?CkoZox;bXeBkl;)R?)Ub1Qs8pof!ID)!D_f#+j-^WT>J^--f7-Z! z{Mg`MOJd z+=q@Iw0ksj#`}d@Y|k|}W&NX*f4o+7-OlJLm0epWWGx;Xx?)ovhp{WS{a&!}+n)FD z-}9(DX?CT~Wlw(Vy)Z1lCHnVXe3zwag$TREHw%_(y}H-g#QY_j z4!PEJMe*$6<%fM%>#Y*o`dobU)`u0lU0R*raa*^?V`gvab34o9toGabUjDP;>u(p1 z3*Prh^`PW4ci(IK+P=hM9#GpcE8;1lGQv1JlL0TcjE8$>(@W>%eIv(`#p?Hh_6^6e~(K(+r7t~JKuL-&O1-< zz7tYB@#^mlUvEDCL4i5j=9YL6dSiRV>e=r<{^gSzjq^J^d9>{NUEkil8urQNvkAAi z{pFjxS2m?bjrfK^O8uim6`45S_(dMBMkT(wY-1qb^@U1dI!__swncIL&Z2m{>8gCV zTz@7(FN*WVN0ziWrkHtzECFjut5hJ6M=#0^>qv1436$+%a#a+p z=CHqGE=ao{Xlgd9-M4>Qon^WrN)eK)uoj~h{g->w<9kz8-~Un#tz#07v)pZ^#hS62 zCZWjJn`Ak7SvEHb2fS>->qXE46Wvm44j*-?4T`liq9(?6!Zf12e?v=;xe z4cz>{(07;)gyk*c^tDXsB=hM3O)XX8l|JeE_`P^V-*-*wTTXR z9uZbKwrpXx7S=XCk;T|+z@0I>ieJ5*4LS0Tm|_h{PntjPnp%=VdBWlZ{sFxd^8~Pv zwNDFoH)op4?xtfA{x~lIJ{3ociGInESU!+=~xN zit8K}+VE~n)5j^l@7wv^!^9~M?*4rL_VARO1C!&wNxIP~@p_vb8{F?iH++=*%igfQ z5AOVQ|Mswyn*);L1CwraOpI-PH>Sz-JZ43bi3ep?YHkb7zRaQfA*=QDMVenS}=HVyS(}G7Eq6rpEM!Il6DiuPoCJ+ z)5puVag$+hgnZqpOXqlp__!M%TC(T<`KN{r4jnAzxNPaCSu3pTlk)bMMu(l2ch8fh z?>io)dwkNS#$UmfQ5Mg@QGGi#>sQO)r`&rdKQ6QCo4Ywj*9%-zoCKd^zahEvm=MmuoXYr%Hr@PB%Y&u=YvH(nt4xCE^O-Gj{vDy1Qq(K7ANU zq)H_D0JxZDh%H26+Z&*Jf2O>k2;wIm}^Fzw5?{;lzNi?OB;V(ol_wS4* z`Xw?93-uz3*tc`=gTx6S>YIa9>gy1;vF@E~p40q&K$QWovK@uI-M=bhg&Qv4$9q-VTX$7!&=5IRO~8P6uTcS%G~_= zumnoCExW6-@{mOt+1R2aY_uqUma{1NI#`tHM=i>_MHc1A4APG%th&2J8TizqRBdZf zvL3T2iKI7e{=uTW{jNnBZLuglzO^VJ9qBtgHy{|3C~R3ti!x=2McMkZMY$PgQC^R< zC^^?zl%sp7til#$66s^T8n7x<&X+YDL?){kiSIur#VA8TKu^irfZpK5FV5xYEL z-!mgDcFJd}Z1x$2pbqf(?XA&)Fb{~Cz#b%dbs9plQPm=8nTr<`o#Y)=(=EBAPUV7wYCcQR= zF+Q}a2Gm-%N-&QvbJWjKidFH}Uem(k0lqt^F=pqrt187xOL$$GT^X0dvOc_9^%%{3 zDbO!HNYjD#%Ck_eq-DA5Aj(DFwWa6}8gj<5mDIR;EK2Vah0Y>+i*n>TgO+eXbHT;l zQU0{cJYVA7F7+Khdiw)*HGsAS4MyAlgyv<$4RkE)3;T8mZMQD96zpuEM_e^2U;k8} zQ*Zi(jRk(QMlPYHaXW&N_Z5O~SRnBXan_A2TgC|_uE+iau)s*`3&)jS3*edTrQt;J zpy$c;()xO0w`#zQS_F`0$xt}aS9oVj-$E`~#O_Ho_EY`n{!W>gF$LZ-SEh(9$~1ac zNj%wl;yUSJ2Tr}!mid3|eFZ>O$@lODu?stQ7aIf>?DipGVqrI-*oD2iim?_Z7Ah(R zs0b+74JKkCAT|gHNSA;p_`Y-AFwDL81rOb2_xJzy8t=WiGiPSbIa8+wF)DnAmPe$F zux?=);X7euC1Fd@x|HCPv>jzg{EcyeuG99CrsfP`*C0@4$7L_`>VTI2HBb1nY#B-9%%B zQHVfAi&YvGf|j6h?B&}|Y><)u7?FaO(<@RuA|ch4{}Qej1ZQ-_Gv03r5+P#I!_sKG zg?vC$m5l+UhdloY=Q2M33EM|-hi%}ur#Wx-QOD8%MlB+X)T3qvfbtUU!8lK$Vd2pX)9R}~#?lU#Jsm57tZQa#tZ8iNGyL5_=mbjEL zn)agM_K3~>I#1CFHM-K#c-ETNl}m9S_SY~TzX$XPisfuZEewrXv~D-ds9k5n4xQVy z*Eek6+0gLjuR(_e1!m2eG|hG?*V@p?u!UhKC^M{eo6c?9b~c0pP|`49?{E(&!1Xm7 zXzJC|ay5R3M;*L2&&TU-kH~&@Ph3NCBhsXK((hpzIp^PH?7x%r$MM)Hn_93^JtyH zjeUJXG)k4LVBW^q(vchW#C^Estj%w(by!u=y7T-})3+u!(HM3u5W;i0R=e|HsxJ1f zcx9H#@W_*^b8W9i*D7CS2&X+&)98Mavai;i z`*!!NP1&t}dQV;b@;oXzcIq^x@BK>i`|17usJ?O4MfE>Lf40gy-{14aH@l!Q2fiK4 z{{AgC+dD&Z?YiGTHghf4o@IId%Y8#jNcgga7*oOAmpCg)rqsapO=<(w#!<;yw6 z^1lv=ME+L>WT9K`NVxIsRLeP!f~kju4kqliau-wEzdw;+K0DCqKM{ej?3p?v3OY#-V`gPzmk5oa82k~E>EVHEJ*M&TYu@tDqAyOKn z@1m5HKH@x7W-t__3`AOv{wa1)3;ItB;nBPZi_ANi6Sa&~s!D1Z0kF`|%NqU>+t#JD zdXOVyi%=pyS(e5mfrKxpd<^gFpbyJ~_EPND8-5-lnPNHT3S=Ktrbr>u_M>d2s5(@6 z{^R3?*6?HVraYvg$bZynnV1vBBU(Kv5z5cdyOl~4(Gm~ohcRT3O9|%?orM+98>vR( z{ZgqeYCQRx7pfbf(p+USUMfvhUIXJJpfpnFQ@%gs)&#^8k?$*S3HsxqH#zZf zHUsRS_pvqn&*Jdt%5X&@@Jxi(qK`lNt17QoPbSU9_&i211L%T`tvTqP#(@<$M(aWS z32M_(n}*aO(T?#}W!m1q7C#h+Wc*S69HAzu31ddHI&p3iOMppkI`Y|DDrYCK<)z}n z*?_i0@h6=hP&SQ!6y5hgZOD-`F&fZPXg7&`jXaHWBHlemQc=cEZ}>pmk|-aGARlUR z@TMVl^F=e5yD^2`<B#g8 zLW)w}5>kY;P#$-}+|(MMk68vC$1odf$Ri|$!A2Q3_4B5X(JDr~0-?r*QlEU1T8Nzq zflJ%KYE=A|Upux(Q8{6{xCG;N+Gf%MmM$(qqulY^hIO!X14_id>GMa%p^%>#|HyL+ zNm0ZN;&FkP5psfh^j1zwG4-(qMf4zP4CCSv%JgBVDaUrBO#{(W<872b{wTwvvN?-k znmcAu}9ZznqNp;lByW@^qp|5P&i@=2-6uAXu5FL z5U>0+7ne_2#qZnXXCrq3{_Jjr)k(hz=}6{R`CSy-`(io9>jaA8kwV@n8VTeLo?meH zfje>=S<+ybOHsE-w0$I(P;;w{y9lOLuZRs4tch%YfU5%KK(^wOb(FSO(WkI|;+cW2 z!(?@3wej_!WMn9-NeKUE`Y*pDVD0(Q-g7W7@iptp`cL*7tUmSouU!8tKC?32F4BqW zfaP=XwZIsA1Gz?#ei^w@c)k_Z!0J$xQ&@|7`p??=db@1@bt$f$vO|wcQ$oLmU64lJ zOYt7z=RYw6`c=5La|G3P`fBy;2g=|{y5+82u3cB7PC&n=Tl*PH*6rWEe}{F|4LeRw zXk5zrWT{%G)~`OkYl}n37QamuUpTBau3*+cTgzydR>|GI6^wPXSC2koe{VK-!LY*c z==ITF(1zmFc&ek1qk3aN8elB@#vH&H;4M4M6L6T~+7t2V*)QdS4WKdQ#*8O37yY6Z zCTCDgR@c%jrK4@3si~oTN4t4r&1zNuEW2^zhCTYHc9%8W;IOHE)5+({8TQ$FOKJUuWQ7_2E7V zXYHG`9@c>L8eT7F7@%OHIMEB${qs-P6gRFn*yNuaFX5&%5b90*L4Ll~NWwX-E1KR! zk)J?yu$kw}&(mfL^(N23=AW-Oxg7HIdJ}cA>j5~3g!YslBPn)2f#TGcpd9MQY?tu< zJlugzga1ivS4Fr*_=VXssRPMawk{}&(^ho90&%{SJCwY^6gMpKQKZx@`U;UD#xJv zJ5mqbP4lJVT!GAk<`tgJ`Tw?1P+_^5ZnAcH+e7AFDN@rh_R*kH`XAJcOkCCC57im zhIe5pf?-9nFy(k85X6}JaeNXhT!bo=g$S`qYGtwndXgIfa#F+(c8=lOZJx|O{~f&jboAcS{$HhjU%p??%=1jkJ(BcwXI##oAF~}VUVZRY zI@>$C-OAuWZV|SxGwy$t-pu~~C^qYE8A5n&Sm6I z@{BS*8s6(!O6Nz(h7XdiW#xHi z7x%>Hj64nq|k4w0g0>&)-JURZ)UoBZbO4ueqjqi9zgitp zsX52pb1!XGZ)IX1Xj-wJqtv1A3I+7Nl9}g~o_j3$+dAK;3r}6Slk@#jX5PuvZ-D=K zK1k)U?vZPvvI%{!yh-y4N}Burv-PVCTd$A(T_eVarVkEEHF=tH^kKY{Uu^%t)EJkpLUPK8u;CZU?la%%kle%k`)K!aWO9|Efc=oo^YC~y1X%jP`VI;L%|GyWc|2-)c9rbIrW79&73zK9e1r5c)mu-2SpI z$t6Gee)0$?ZVEzu|D%sisvGBiM8ajk`Ed*Qzw_-5H^aM?Dew-?m8$Fxr?q7Er#=5r zY=8O=Y!UhA=V}Lq=jZBcz-Fx<^FJ@DpZ)T53HJ+}!Png@x}SY6^z&7J2{#G+{fpcF zw7C52`JTDM!DH1N{8>$4FESM37!8#9yNw3#4jlm(vofl3aj>63Ip~j_cjto+dbUh{ zz7(`e>~t%C+9FM3XFp*{etvmhWOaMY?3I{y0pmRL+bBH0i0e{@DQY{#*HWm4jPmhb zvb{8=3i?@N)G9N;IC?gcowklFWiU__{j)K3FnB(yM`40fb>S-O8)X{4P6j!Pk2RWS zm~5v+v_xWCE8#n|>O+6GSx|yK!aRI$Se6HCWhbwRc3Lf^pwokInB<8!9V56-*nC|fx4a9VAn#TCB()!4GhGGIETJUKl4?(_uc?c9XS_BaYVq7V*a+zCTk3-MO^sHqlXSZSt zDQHpDP{vm%4QvR#L}xbwi!3}-H-kUSHVZA{P#4a(G*XO1%1N_f+~OL5Rw42} z+lsJ*d`Z2v(NCK|Qk0Y6k@#|>RTH1TF;x+Vvl-?8);A%RNZ%Aui}sq*M?BIMy{EXR z@9?u|atBo_Bs~%Hp(~d=6ctioa)+Y8qp+xUnBtJ|IC5>_{>#`)?lL_O1U3_?y@F*q2_1lY1ZhV7C9AiPO72`$7jg zKan`awptU^X#VYHc2}C(UG9A(LvQJw-bXUc4yX4!{}CNb2<>&+CQM zGemmmiPYwt)NF6?n_-pSjMexszHIoY^6!UK3yG7yNstD`N{<9e%}+|ZZG9YRU0S-L ze%_`Qd4KACn4tA4UTS(Mt>Xs&7~9g)RliEtHO|}AGJK-eu|R20=j673K8l=JR=Pk( z`loK*ABG<$lyrV9UFj?BwmYWX`lqi)=)40oy$;O$hf)H^iKGbHbD zVB(0=(SXA}0n*bUd8b39FXE&jad~dfznVBF0Ip62=LN>(y@>l36#LaHH0w=5Ui&TY zy6=hg4*ll*IIqq6=UsM2od}Yi2~G13mF@}1Yque&>#iv8SLufWBY{lj<_#|ah4mI# z3>?a(WGj0FZ&L1lY=0ICX;}B~ZOUyZ`3nk9%FgXG8b)f%M)*%-iEEEVkQhltIlkOx z^T!4T1|BmL>pPEow^^dmbU=$)zl`tpM+uWgHr0N0;T*P}+IQto*WDMkcpmK5s*mK+ z;}E~wB!K+E%8gxSC0oWv#6>4XCB#0fTs1Hxq+*#0^?b)>lW5^GG8L~;E zq|=3je!m#R*IQ7(-{ZRXj5RyEE_564q=je9Lf2VUB^rGPc;3(2`n08kbMl*C^<3=F zZ}xD$zWS)6&nEZ%S4+9YYV2#@`ucdoL$#r|isVOaTNrj|VF*t0Z8{r*&wB@b{NHfl zuwOR{3NXiGDA2w|>rTUr+IDW+y0Z~@Dr12z3+5q`c~0``$d7(v9BZ26IPS6g9q@?B z?%Nhle=I#%vF{$YTBD~|AHA^isIo?*eyKEkwc+qz4!BLfcx#vG{@jtSDIv`va zTo=bn?Y2HJatJY4|FY4FFw=eUop&bn*mW1;{G7Cwobo{h1Va9#`|(xZ_CnK6IyfDeZ#G}-FBsz?2GNbE4t;Tcda(P+;lr* zhIgFahK#czP*K*_yIGxfW_a0D30zY9%Ji1a)vm6dxvJNy`G}KDWmtn+~2Q2V=}ByXXySJcWOfUGu9PPjji_E!uvqG zCadFGZIyO+3~RaeQOiH?c6Z8McS}0&d~WwWxeG7m?hnXv@{jL%AQz_6b+>Z#HzsYp z6BQDd;TsWkCN$@ESniseDNR?0Z@KgGc38&6H^@b;x@Y5h)m=8zATJj@k*TSvdEdW( zPOX@l_pL%|)r^v}A z3a6j1`P0vbs9M_9ea_XYX=SNZqSTPmy_-#`HL}CvrYG&4)}PpWY1^5@w>q{ll{6%` zQW$jYY0+2Dds@JTsS2mTj zZrGY3aL8 z1-m_S>NKN$iAJSQggRfzh-o$I^3*g(*GGHS)c5c_cKVWaP=N37(=R< zT-nVN)?Aejw(s`eB)3o0>#4P*_Li)~_m`x;ekS*|H6~OW+Gc+F{`xcOjpZ&i98kj3 z_WTk+P2tlLon=~DRqie*Q1of3fT;g{`S)XBW||vk*-OI3UXgHX<_qP(kKtWvBEj^}H!d{ZYITrBe|3Yns}qYBhZHH)G2M;3w_L(4x-KbpIq>C$KNp7p+pq3Zl=B!$ zsOE!gi26C|z=Irv^4oF8VnM#_^)dd!V^AB-$d>R!3d5P`8ti>@C|=sBwGGc z4&>D41#upWQckQ(QNOHM=c9f}s$Wu7La1Ldk!f>K$3rDa=D;5qpONtd-us9=vJ`Nm zDj!N;`I2WM@$XiEPUW&Dc~0qFunO=cPXrW|KdCMymPRSJziSTd#&renAjNpUB(5!T zB7bE<4{l{E69;ebEsL{DJ5AGV;2o}U1j{I!6XKZWL$79nYvp+om5Be@Sk1Me|Aa#*(LpFmqh18bw8(OxN*PilyGr} zB;2nZh3C;+IH%oBm2lg2*m;!R|G__x-h#M!^gQYXXGcYTJt3=v=h2?Sh38SvQ4((G zB6c3_+KrskN|%5*_+S@R*!>@uZ6%!T2MIS4?%gQLy%>n6$AE)I!4huvisCHZI)4o%2Oiq}I`C4TNaCWQRYpD@|^PTVrpC%T~mEn?A6W9pRWQ%an_u+x^} z`~;%--H)84)P;$y?5uQ)5ed^5V{8H5Bg50f%mPcr3L42&l zwwC;ISeI~2s%M{}{JgBn5>okjS#>Gld0ACnao^N9r)m6=?_bbhckGrxspGS6M}sr3 zzDjx?9v2=J8yyoH6BF|$BHH6=tc~}lmIppLJd^(U`1=a~+=X|(&b;}>>T=cypN#$< zsge`P9b6JyIL9}2iu?0%-i(`HjNOvkA4zPnFJ|n_^;4%`djI}?SXfwic=(48A0i?m zA|oTCqN0r2%x%zO;Nin(8#VQ|7VcT0TLL*(_kPs5`LRWun zOQSnY^>(-IaQEH2*u=!dq@<*{xVWubw>M~fR#!j7(eXk`N(!hP)6>(Flao)KI(7Q= zX=mp{4H`Qeo8IZ#ZH}%%z?Q8Se0+RjV`FdJxZ9|yXa51W5)u+kOlRmCJaan{m64H= znVEU>rhnsRXNQfv=k4ut;lc%*NvoPQ_jlOxCMzrJ#K}vInx5;^&nGP{?c&9Y6D{X8 z(Y>(IAw*|qbW^=8Q>XhmIy&#%bwp=Jl#8~{E?~sMonnHiC55G_MuiF$(3(PKO993d z;0~kFeT9Z`1FI@SjOLZ?d$wG6Jq_b&F7}%}>YGX?7!TXpa$0J*tU&!}0$7sg6>cx10W9!+#_*-qICW5~_TZPaLo zrg{&1^*PnT(63Qbr}gW10OP~3u(G+@Oh34BvkRB6JOE~gq44b4+t%&88#F$3@Q~-I zF&<6y?$5J33j7G8VcYf#P4(^>wQ)Fn_(*hg^s3da&Gc_K({u3mf3k7ojvqbmI+}(JH8yb7+LYI?*QIpnX0awku^gX$bEkDV(ixghg1@+n*%>!Rsn zXBSg*&xlal_JcJ#jqS3G=$>$AJc(;aE{g9V(!BHRCstftO9T(<~(W^p$C+>0dO1{Dkkyj8$+Mow|Sb};w$ z8sgKn`~HxSmxSl6hCeaX4_fa10{HCSy`c6T&oz76 z-swN!RMY0qR;{^A*lw21HGTb1<926Ho;(R`_xm!ZCc4*Jw>=gb8s4$x{nbmZ5w?qr z{Mf_zgnr9wgzXyH2d?tldQ>g8J4e`V{4=wfwGw z!06Yi*SoLeN>^HMsr%S&$5ewuz6~}GXnycv)A>0)cRV;^YJSDS^F_TUBkFC}(Z1t- zaQ2yJm&|;&IQh+Od&qoBM#-|T3`QnA*%O{rxp$mN$AhiL_PZXITv@M7+l=Kqe(~zC zoGaI_W?c71BOew&XF`qtJ^xw^czkx_x`3=J>x_h}3i2qvj~+I*vYN362qWkI9&UE8u*ugy!uEj48D=t4hAgAoyqwX0BqZMO(T#Q|f zaS73#pfyYA^ePehN@crdFdHq{paL?>h(`(7eQ(z|1h_AId+OO|{1{Ars|xFfxLt)w9e)I# zusuS5NqQ?IKkf{P0m}DRl(#n^US&ea_+BYGavCEBd$c9~%7{ zy#q~w^XMbC(NG^Ewb78LAo`w?=wU(|4KZF?!aR)8AJLXz8ho2A^Nw2rUS_r+=Mu)< zW~mq_3TcR*beM|w9n6A1R#1LYL8=|h_4EdDW~D&OD1J+QBMl(Jy0ER7f2M5Zz{tMp zQ*sdWYZAmnWv#~*2<;*eKg!^hc)t&)iC!rH{=Xd9@B&((+nf=7M?AM|;pzo{oJ zKMnm6|EWjF1K9q*hhJMjRDX;;jnY)boQZg!4R$v(;g9N^jEBYfmGPK-KD4c4eDxo{ z@cD15Y)s6RC6$9QM&o-6;|<8qq9b9>?FqC~K0lM07y;`*-cj(+B>!e+{7s`n_W|p^ zp#Y_Gext|@%rq4>AmkYgWh`Jepl|Y%Wf3fN3Q~1wGWaNCoN#gv^h8-MbBK6B9#RKC z2P=nTq&Ji{gXkE;pgz3)UD!5Z4q9>;)PcA#hcYC`P*FLO6LYXUw4R})Vemg`8_7js zqu2Eyz#c|_=$oGdDTUf8{6lesK&TfzKfN5x%$OS=dc!pK591V=0>pvPV?GqD4O0-~ zXnkn`J<^fo!(I|N2uq9!v~KJN|4g8rLQiqbO&+vV90cW_U&$7JmeHCCz{;c%KW7E!Fw#Wcm2qNN9t6j8^Mbu%E+SC4;J$KLg>c zM9T@eiXSoKpWGv{QNq3{=U0}8&z&^Y0>Z(f#b?U0}V*lu)h8~A|#q>CThd#ZfbNunLqJ}6Gm1o&r!<+fjz)he%} zVKStFi?wk?UU;AP9Xlt!&xyG;dhObf25Z-vx8K{UdjHyc^oE;caMx(JS(O&HzTUgsa^wP4JUCauiALpkIzl0D7jRpe2GQ3%(j)Wf3Wvko2}LC zC;rx?eo)FS&Zly{%2A8lv3F|dp}`{`udP3n+|pf8;P2BzbC(!j{Z)EsqC?~>p^=4r zV}VIPAxJm}tRsM(K>Y`71A0KhIlxH3V4&#(W&<_@)*{+HcXxN-B48n4JYcN?o$<`h z5#egF%~rxTTb?~cw$U0q_m>*u=9P5pqw~DBuWs^p>Eh7=gQItJzZq|GY4VE=d3&qY zeKO)&aLG@ZrJHn2mTB9<>eqW3S^m-POTAuwS)pAuz|!GE2~+3$8@Ja;JbJ@A&GHvT(%c6I+HIV1CJ+Qo!%d7S&TidBwX z$*3WqG1C~6yU^PVGlaMf#5e&jls66OwqH=7=uDx`JaeN6{7_VVF;Ny19Wh}E;0NFe zK1&d#aKU5(ECGt(B5{RRUX$-?afK^Y={~3_n@l#hYhKr5L&**2OL7#7a(`r_aI9G0?+pVzZt(BK+9G<0p{$XYf9|7$dvxv+K z{^A(~D*f;IOE9njbd4VkR&lR_BwXi9LY?bpcsF~4gqxNn;oeOq?=F6q6x2H@%Z)4R zE#U^3Nw}*oC0ru-)KmWiMf%ug;OC$R`NaMS6Pif4Ci(se=@JQN4sDsHC*huI8FPD1 z!@c1UuXObV3HMuTrjNA+AN@v_OdqQ^Ny629AmQeM-get2&>tsDxIxb(+~jEzuK95Z zx38&$(}B;sb&9T!HOzM7N<$x~-urv>v0pMkAD!RNGSGJZ{VL((i^o3!i8>HYGkEq# zssAvLLSqbi9gvuqf;0g=%JG*K{KLKfT-pEg;TzstiqZjk9-RaGbR8&-r(D$1Vr)x1 zL8D9?bFrN0c{l~$FM#(bnVka>BB^u~>tV8M`F(Ez6Y{=@_8*C@t;_62f8d5APdB8QWxl zjMPQV0+XTN^&Da;jLpiRJ9XZOWTR^9bp?7H+GZtN%?zzU*zFnU*^kt zgO>Y?fF^eEn~dV3^@lG>MO+dtBr-7ao#L8tInKBE4*8I3DbyX=|IU0kUJAQSo9IA= zw`~&)5xp_NKE0RR04RhQV_x&kWOFX+*=%9#;}}8-T{jq4V_}YL!F7T=xAE?6egs#X zf5jzGuBz^X{lZy)5^y5bFybej`{+9=LnpF*Tul|%Q9O9Ef)>+w9Jp4^1Rf`NvI0E) zt^iMpN+|1tBHR^Ezi|GY1wBKqnGb((F2%7svk)#&Ualy8#C{h~KasC7f{JkerJ90@ z%lte0C#DD0jPrY_Y(y(7TeO}Q4;|5x1lQjgz^l_>+)XZoPv!Hg+pFT~4~b?^`hz-5 zKE34UUU6=9`$ET=aP=f{uTYyK+(qGRfV%+PiD8X6-%paw5Ja2FUqQ$oOa8nv5%Qx2 z2RY5yjoQn+)+oOJca(+^rf(NqGN&0soQS9mAx9iA7K zK&m*maAj21FL5goM+B>6x5wH@;IntA<)Y^`+^xvt0nao=p{Sx&qwqA`Gm7`fY*$au zG4het<=ZQ!G1+D6=Hr7=iQq&vPa$sP_ppdv;VBsTgzROJf()jRM`+!|vOyj)o*?n0 zjcWq2ketSYD;_1-{%OE+iSif5{)73L=URkBn6JG9m6Vj5R8jNOl?Dk~Y?@T_J7{|N8k z>4oHB)KuO_mYc1r&4ByxRP(?0sKc*BDucF`^lU*aUC4O?=kPf&w@(8cqTGe-*eP!5 z{$0Gc7vr}u+zBme2%W?>3B=Zb(SV&$*?1-M7TNiUt&9m&CN-gu`0^M`Bl(2#5t^60 zKhoYS}c`q(c#}h3rzgwf_aJFWx+`HY^i{aNh$W{qW}Tv( zd@BL@_oROLbY^Fvh8|C2alRf8bf@#?&9ku`T5z+yVlPA_~Fj6BaWj-jhbvV ze*3Dqcih$o`#AU>Uu|t=dBSDi`{(}ep9i?PI9pp;`Ma-san9kk>#AF~ZdqGTJbu*i zOMLj3_=xQIsOa01NoLvw2T%R&)-nsYI_rBQprdvth?A?3JH7G9iNo?A~=(M|0X}2QMu7#&L z93OWl%j$NfrS#>FD~|#%zE5}Y4VtlNq~GU>2M!#NhHf1*YD7R((z&b2NFydo+jW8d0sO<4S5BBd#9q~&vb~)wR;`qs9r%%kWoI0sOkhS%6TQ9AT zV@HjtGqyyI%nLt2a`V{Ea}KBLl~{9a{f!fQ%WY3dii%8#opVQ9`%|6j9@8!3K31z5 zU#n*FQ|*X4)mfl&=c>NiRd&_gvFFf^eY+1I6H}|k-j92G8SXOM zHFDVMoZ&CpxmKB6K~kmh;QJ5-Ij7Chm=>Rh07i=01VW8*!o}u~leKHtjvF@)xYotR zW!>r(kNhsDe|-DM@0#Nlhu;@3_#E@*OZ-MPn~NzQexJ8K5!WbJP`B_SeClSEJJG?Ch>R3-ygi zJ0Fn>Ha2I%Q%=86sq0*Es+ccj7i~1SJF{Xz>!Ev-J$l57(%d<+Y)tRJ!b)?x#NvTzS~HjNjY_EzQ42GWVxqYUNnN_9p_|Ze!9n{=3VI}9ku5XL#cb+fN z^s%lR6XG-Eag0L~-S~iUW3x*6FM6<~@=U4kmogt0*e=(2a-`Cu8XK0`EH8b~dgUM7 z(yNERg?P`qT|(OFOIDb^c2G)i2d{_qT_#lPlm$&MW`2Vj|9g~RAQyDIvqIy`VH6yj_6M-`KsSg!7%i^xH*^2Oj~k z;Lm^`a^}*a$KUgZe(vZd;p$ueJ^F1=edYS?|DAa7^FaDDS@uuNN*0hVZ<~s{Xkp}8 zWe|*IyYU~pS5#Fk{}=p?)$3mmF-Z!3Gk;^%kkt1#Rs~1c4ht0=fD%5`yP^h$?AVc8 zsBHzFI2IK2fqp4EJX(@`sxD9MJg|Rw8kTQ?I_3E_s?Lvc7OHb&T$ z)f=oD(3?X&xPxRZKu@ee;QvPM_#{>9$lxe{Pa7zQH*Q`*&k!o#GD3M7Wi4mv#(+bVtD~luSe=oY5!0ya zp^pjtMhT#*JbeMzvmqZsP?c{`zD)?R0zw~ll)bYxz(Q6x!6EvLp|pKUK17uB&_~Qi z^8rVUj}R-Ef|90%kiG!=L!DU`KdJ&z|ik=yjom)p#lGv{G=T0nT(;}2<1KBPa3 zNDqui4~k3=iOLB5nBjcW^i_1m+vtqSqn`4o=V=Y|dQYKFVI zyZ<)eZRQ=PwI?3+{KL3P;{2s$D}LT?Rdq~l7hi){gEAVvy3_pCou;qOylwgFPJ>r> z^j`fI`|bC|%f8*JJnv4a_hTMUkV1RZkYN0E!7J6ldsl{c5G@1hAB6+n(*W;)^cPVw zjDJLohs7es0o@_?B%7F5s8mK`n|dzxwxOM7a}(zq z7fUyO?qBlLa_`@Jbnwr9d26x8hJ+HWQkx$;UCanp2fsZE!SCwr)xa^Mq`mGx^$)4D zuS=uyPwuDHtv{fm@tPBQVe3ye2;_e4Q@3Ho>}hBG%2m`}l{>+rLUzuQXRS)TT6HdO zXm)I7$+rV)b*S$D@N+W9jjIqX;XJ@!q#gKP@MHOPgm*2^zo(S?5i=r@1{%S zhi8U>FH0KQ4_5uIW!EBU6M8)sit)W%>0P%hA2) z5-@dP(0<{kqB4a^x|Ek;kQL?m5s6k&;IP^i_e)%VVUjC#>K03@n5+u!1%f{)ZRrhI z#>hiDyatM8OsaF!Sak9&;zyv9mwBm%N@E7~g!bVXdl;NZG5QYk1Y_}oP{JgBOQaq{ z!M1QXoHaZNTZ3ur=?XQF_-fr{iGATW@iip%qGSUtYnlHczwBh0 z4G^{sJyeM263S`_EX*m4TVy3SoAKv5!Z*xvi{!S2`iUf^Gk921D@4``ahxKO1LZX2 zW)HOTT>vsbib36c7?^{kk^g5w`XrfUF7d=8sZ^pOZz)UR@mr$!yHHN0yjR#FqTOJ% zlD3dCG?nB-xhBTX!M@2yRw8hiJsVop@?o(z2#vreHj-#9i8#m6K-)_BkfhUAqRrHl z0=yF6A~7V2CDu3QYlxA`5I0nsiN1BZ01rLrNI8_GqBShq-I8d5)Y_Dvi}?NF-JcC) zISpl0LLR)i_00IPxGR5^VSJ2-~;5?4&2a%R#xMeRYHFNZ%UhaL-lK^Qd&BaD$g z^GmQ+V2e?fPog3+iqISkk9IQJQ~V04ix!7iVrD)bC(EqvmEqe~Eqt?F{|^qo3c>{DO>|C?04Y#43A>EuoM63ePXY-tx^k3J+%uoM({&_>i``Nij zmMDw$sJf&vU`i-g#5z$Mj^{blk}I}qQXYp<9->$iN%fG5a`Ls0>gZQ&^7SjOTf4q_ zerEKbs|WXnz7MbM=e=a}x@WGg(tsPA!#@0a@}x98Lf6Yn8WGjz+&SsT=pI+EN@HTp z{rse#;>P&fr+hlNSg(zZlJNi)*-eEKB4ekp3K^Z1E?>B4m| zD~Jwe*0Z-5o32FQ{TCJYHf*?|&y_FIiPQXQe*3VrzgwFpbu)e&*z2S7M~Bvr8sD#P zcEq56C!Y%=Mi2M)eK9n2q3+zbx(8y$ez-aGqNo4&YS+Dnc3%`RJY4_qfwLv=xGY~f zuipJ3an4;XTJPVLk^6S*lDB*CPVx^|63lEp3r|*o3L0Yevd*H(F79-T6)L25P-CG~klo)E8=$ASYa=`t8bfufu z`9<&EAKdwHqeXb1?fq&l-MZRU>x@gggt=2KH(S+P5xDf#qiS`y&CaGrCp;e4^++jw z&kOUckIhf3n%H&1qk-dENgq`7H7+snVuH-3rP#@!79Gaq(*bY>bO5v!3>`uQpup}` zBY-|Yft%hPV8q<==>{|bYQWGbAO)bGPy;AHMh{Q}ND)+jpL)Y(4k5zAXKyR5(b3il zoP2d*Ki8?P#%0DY-#qDZpmOOKL0uvr={jgB{S%IRV7u2sv? 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

    mqCJBd{RqDCXtH!VQ{Vs zG7b`1?D7(}N>i_IEYC)=KI?jWHN~`YT(2n?dVE_Yv|4>FUumIB-0)33k74|FHIHfa z9B%0hbqlK;ug9J1us%MtyD#HtwMP%_(5+6za?0A1+3qWf;~OXoTQx{Cv}dWaC$_F! z*k{d>eor3WJhI=vUDJ%q4lJ!V)^qlbS^IX(ojtMX%V*&cVaHl}rCu4lqRvFmiTkHF zn)z${+3osvD0KDQ_T_WiuUkIkz=Z>42miAB{*hiA2DlF_H@I7gMYB5W-8Sp^;kCD} zAKx7~{nr`}F;N!-R}Gv$tyS56rKcbFFWR%{j!l#2{q8quc#Q#_UFJ@1dgb({C-=`j zx)(BYY^}D9zwX^SN1Dc8uD!FXVAq0wzJ2-j)zjC1Jbdva^x4BJ55f*a-q;a-W#gR- zD?-mK^q*KWt53%7T4c-D(Yej?&MWV1Z@sGXH-1@6{mb4sK6Cku`aibKJ^$$9qtRy< zo?f{rZ1>iPp!N6mEDqZ=@7CH$mlpQiKcdUt!Gq3CyLx2On%NCJIu;lfI6COT$>}$i zPrADJx6AW}UYyzg{O_msO`JBu!>d-})(uk69$kLbj5_@`4C!%p{J;UFoLf0LcgXAA z`{ywOisthBX6c2sJr9mDO{|o*$yb?MWd3DZmCZ}qy0&r}zG>8jnCojUY;H2cyV?Af zzf7n&W83uR)BJ|^ay|9<($>5Co2+W%`@7HN&6B!y$X#q$sr5(KPaIS-`-Y zVqvW*p5u?s`k|l8o^yLH2anpnx=qPn)Bif#cleI6omclP-mgRrzwf^F&GP%j#XpTN zcVX|qvpakKKIF&pP1FC<@dvk7Ioo&0Hf>CugLc0RSW!--8T_AT?A zH?ruODL)@rQejG;oE5qk^IOxg^~qtr#|IRjQZ7&1+@0rjtTeP@-jPK^)-^r6s@}nX z>ihhE8Phde^}eN>g!J}0(yhv_mPKcKlv+{Sw6EEoc_jz5O50#~Rj*~fwGMTv8r;_7 zK+B)^HeEQe>V$qpM|R6Mws(PT{&fQ9Rvgnk$I$j!hIh!=sY!}Pzt!1!q3O)yKUS2W6GDCe!5NM#qzJ-w23@3_-bI0=a0N!ziD?h@TcdGecrt7aQ|Y(w{JUL+m`!L zXx%^m?0RLBQ~1eWV(vA3^P>H`Kf7OC^WFKC8UK3MGyFu)*mu2?jok7FVXGl&92M#C zutNV=INGi(eQD1m8$Yq~mxGuA5?GJ<`q0yuJ3;wM&YYQ3fW?^+gJI z?_~vQOqqEmeYZp15}j&a$o;p`A)|M+nY^s%q6f*AY+aN!Z}ZI=X3n^<{&?@))2{x<`ys-4%;N~EStF$J z``_n(o&u$l2Po$co0LcUP0IT3rOgx#_osJTwwsh3kBsN;GORQyfh$bPso5sQ9y{rp zyL|3W*h#-l<)*Qdo}=@1g{oS&lcu|3+fKTL?5q{Co0N7P5^g8`B1M4mygZ#ji}~NR zlcGNprcdZix(Dpo#F-R8kdHMTf~`^?r~lDI{-;mbDWnVSN)&P;>tw>u3$`GAgqFUt zJ;t3e(_O7gG?uoli?mf%U7v>qyb`V>Gh$~6hU6ybCX8j`*QZ%4BOzOY3tg?yV}ir| zNFQqZWT9pJtih4B+gHx^sXhB)sOweh*czBM{541)CSt_MoUj_e6F}a8;Y595tAr)H zhdud?J)yQ?01MolR^A+=3Fi%+-XjTF!!Zt_hZgoG$+ceezN=17F+6Ea>iypKBTvO4 zkI}0eIa`>yQE%@O2*KA`#2JKMQCOAO&K#ew26$H5@}zZLrU8x-3#7t_o$Xx$H*H?X zBO|4>d7z(@)WSPh+O#%1^o7xuZ5(aA&D>**W-72#+t}f&&oQKpZIk&B`$^D~`;bpl zpfvlzG$VZ^JceQ2MAT3CKX8AkXDi%;2-@Pt7l94hiZLra&%MpMO)WLFlmHC2XBn|( zySsoctZ#x#KK-X9F6A`Kd>}C5JX$^w@9>H7X20D*&lP%WfpvR>t&$#w`M^Hgf-N1q zzCOMFTI$}7In_FMBW_H+gz8I_Q?ye3pY;f30Xg5#p#2`p2j?V{p$6L zn5S=Ezln){eD~U|CyyTg@#2rrbC-fwZP`3+Vep#3$B!PpeDO!{s?8fG%@10$<&PIH z!p>g~Uc2q_qsKujH*K6WFL=$?!-o!sp1-_k+|(`87cZPJ{lxL(lY0!_Jbhu%n!weI z0-ij2vSa<`ep8oJowHCuPhulwb7!@*{>e1vt(1NVN)6}4fJ!qeV%BcQJ>kr z3H~-iT9>lv_P-_wKeKvm_o*|f6;t9wr?W18TR8t(j{=>`j(%C&AvmA^;I%_$zH=z} zW8$xWbjWZdNzc>Dx4TY{irqip7l-W6krJr!=N$G|@nyVMRl!@uJNy zVxGNz{W|<{%&BXkG-QHSZKfeZqi^Pt$XOpXQgY=wnqfFW=*uIe>4Xg_6X!@%e#`C- z2c0grE;^}fY;3y{rFM?()h5@(nUzCEot?6`!vkgStm}Uj`DSjGWRqW~-?T7O^Tlm4 zXYp_GWp@YX66+n#oc{T{(D^It+z2YNrF7K8F+sb+^VgdaX2U>3!vE7Jl5`1K2bh$5Jxt2pHd=j3e|p!9{JtkP z_&9yav$`gw@LyVe%8<@lzw@P+O-e{Z>-v>QOv3M&Ji>qp7VQYQWDYmgoO5I zLe_&E*B56&ThY23>uuh%A+9z2oW*VEmKX~481IhxaEKqHpRu=AskQm1ysAD<50&tC z%6+%K52cRDeyFy!R$N2E;c9WLVD@#1pC=RU4aWF=9DF?$720{jH^&})C9y2Xm*`wSmFMCgM4u0ClJ+{mvOckStYp!L4f9|lF}BK0kEe?RNg z*UUOPhy37&+aNr`q2-&P4^@}V{w*8z!oQyxJHJLvOP(z*v`v!A}_|E@gx%7G$TxGoxS2(5#JFq z4Z2H?afOpn>T^lf^2K*7~PDnkLxlnMY&@o$! zBgCx~BUV~97%I{cb%^gV;S*sl)E04)M&z;{ame0Y{M-?V)ZAzMuJ!NM(nv}e!O1ek z*pu>|S|0r?V~jMnC*_}%6aS83-g#S>#Q)3~wlu47nzVZg-r{r~iAdw$EaT;G9>wyv zcAiGMcs_;xLcbmsb>Z{l^cY6S`qiy9or--HGKr~mTbaH_YwKyf1x=wQ`AA;Jl z#<O+zW`3#4w#%1Hng5`KgMa9`CRG3D z^zEkV?6HSAIL7(m@7lF%;>3xQCQUkX`V1QzM~oP;dGqEoAt&DleIiREhkFVO3)`__ zD+O_)h)+QktIioYakn|*(}fEcLPJCQckgR4?$fPXxBB+%V~qQB?(DhKM~>^_K5g2x z>Fn9Fr%#;+76`E0)pO`7e#5|w!8JBNyMPiAUu zI*?)O+e9_X#MEiMpl`j{q{D8eoiuDhh`SYb`&1@9u-kv-Gc#3y(uw?1>lZgECvs`+ zInMO%k9zcOtx1_e_Kb&QGZArwW}TM)v6CWY9HC=fC_SA?c}n*m>>}I6muXE3?rZ4X zR(mhS<&IiAM_#%Yqfo50bLj7-h)@4NkKz+e8A>*t-U+*xBJmdi%DtAR_xCkaSY=X< z{qW)UHMG=eKX7Mc9}Ape-yCWzU5ob7ZAd=={~*L-VZT1E6?;&vX4P08sQjIF1Fqpe z!AkIH+ojdG%MP`!yBCzPZ2^d{yt-cfxJkdIROWUiU92_Os70%%X+|-EWPTA*iS?fFy@bAo@#J@`sYR@FZMx8v zavAt^s!MU3^ggVd2QvijJcs{1pt#0Gh=S*?vEY&ST zvy88V+L36erh$3==0DaAKev{S$N+(FZMYhIK8e)|Sd; z#h5NbcEOhBxRg?6f#Q-sw2{X?1@|WmrjaAKyp$sHH;-xl&7+*91ycC8%pu@vWhIvt z@3hiV`_3pY`91#P98+~#tAVHR2zV?t%}H@-s6j8|`MoTs&I3s=pE^|9-g6L^XEQlR z3#fn@zmFTYL|zzfpi|w_o2|m9WIU(@a^d%(P$U%TS=-)t2$1aVY%(um-b! z?|@~xYT==EMwpgMihjVSReiB4?!7v`g>nkY(Djq%kV247ZTxQ>*{JzLF3>`w*-Xfh zjigyae;Bu&AS`Chr^kfdUmkGzV)!@Co2O<>KFBpq>!mJEuFa25a%!>R&%aK&uiV!8 z+JLePnx?OubJeRh#S3RTw({5Ndm3(Sv2{h@&XGeVy)EBsb=0}dxlX1m)Oq*)U$*`7 zChX2{i<pVWy!xxTTZEwrh$9FT+b~2)w`t#NqoZp#}((> zv?%iAvZK>7-wY*l96otI|LfHgyFPFI`l}qHC%s6r?zb$nDit)PLW||m5PSIG-*X}V zh37&xV7$_arB6Lx|K6h^gO_9|{ZS(_)BM>_5)*_OVniPMdZ^169xE0(gXNf#(gNFq zJPL0bHfrY5+lwNDl_jYXS8S2{=bz@Z^eO+S^5Q|6%LmUcoL))4bg1LRpS7b9zy5tJ zQJ^*H;O`a~qFg>pHiG3^8wBznr}w4%n3RPSLt|8JtsNqvaXR$pEl{ueJ_G%Ei{T6S z974;QCgpNsw|LJXsP8lQDl3(x`xESamZuI-R)?CD3K5p+@DsgH{mi8Fyzp^!2wXzv zB)VwNovicG+GCEBO(!dz{SfC)-fh*=q3+kV&(}1{XHx2rO~(6%Nl7Rj(tjDCJj`NJ zuBH9_=T06}`|mh+f;0MEc*@X(*D*(-m!}w@M^CAX@M1Zi{!E7D zT;j|{U6q8DRwvdcdXg;+r#_tC6Hb4=!y0T9__*^FS}xB``aVmK)DPm`ke(`Srp%4D z82#fpztE7%+1}#i`HuT@BLF?fOZ%b<@ z8pN3a(IY~;%-C~kLh85NQ=$ijUfN_I88gYwdJ*=OuYLTJ+!)iEJ?zIuZ6WxY^_o3^+&c}FI`tP zwv9SqYreL2ugcdDU#&A6^@uRbBnW6!55o z|HFcFqw>tWKjQeic6(mAEqhda;lo06qc&fBbmPX2n>TNg(=55vlEdxo+qduBxpVK{ zy-|B3A|oU3-@hLb5wT*$iq)%EKYaKwIy(CCHbv&)(qYB9#zH)P3{Hpef+C#4fy~=lDe%`{byBGKV;BnE9lm3_|>5twcR{pYiP4VX6=ZwnI z|GU&9T)uDjTeEtX`YlnMx-aei#e+YV{NB}JN|RRKC%te!O|O#GLXPzKZuYzpGnXqz zjx7D+#p@Y&a+LU?($iL*ulL+Nx%?$lzbC_94~qSvO4sz~_Iy|O9@s@HmFY)<`DO?B z#&7!{#5ZG3{x$W~>opgihFp)jc_$(~0!(x8a(K_}kuGy1N1yns&ibdDE<_U(3_JE$ z-$QRZ?R!m3Q+d^sGE1Xf=Re3h>pn5Zuw(D4P|A{M=UMlOQ6!7(iy)>UR$%6!?k9F3 z9$L0+*?Z<7UYQi~jChE+g!qX#i5Q4DgE(pB%9X?`#3;n##6bN}`zz;Jk-sfC_&qiI z!WewZjj*-J7XKs&eP=oS1ws z^Ph*t4fAMmqielOsbkV#eX-Z==b}%F4m)wU^!I6hY%+9q^n{t^oGx}Q6n-GrmES5A z+mbxr(7&cdnN zo{p>$n!n?l9KKKP%=;~1($&iYIt@zH=WObfPfVd12~%x{BjJDO8BBVn!xK!3`+SNo z;%(GB(p|+$*@h-%59!AAdPi&i&!cXe6vs10|L5$a&syG!(#aRP8tFL)lMYXJc$Km5duk9}(l>k$4UL?hTe4rQ>&Dd7iBH33OUEYRsBzG* zwPdb@Yu6GAOSayqZ&BkBpH|IQy?TwBt-RJWO|~^^wsE%xQ{8raPY7P|X|ECrOO1=v zTj{k!h#w-ntYr!5_ib5w#Jg-KiulTpQSW76Jt(c$h1pxuvTwF0X<67$R%*%wj_k!= zlk{cqB!|}?yw^n=kPGb+{$%W*+|leITvl;0zfReop`Y)&lT?pTcCh|)E z*p_C`T=u}ieZ1@~>`dQ;UZDVCST_i(~x%{vmQ#c20lkc2!h(D z8!3h2+AG>o#@uRc+tB8+^gr&p<+da4QFF6jF!P{ZN5wSO`<;V2oL}#Is>V`id?fYD z5I3PL=Sry8DLgaPFtu%yew&EIj9;S98B_aoXcB*43w5zSInE&XYM`t8f?HT9uBBaR zU18}If|{%Ux$hsNpOJHqR8+BSg|&D_4+{b)jOE zv?Pw@6pU~qBy~P*9mpS_9+^wXXaZ6)alJynETjmh>SOz`j!v{qjgj^ZFtV(v74Y@4 zNv&tcec`Q0MsW;t@HVj3OAYAm*lXF>%>U@MZj={tM?F?J4b+BiSLmN5{Us%2eUQdH zqV2(xPtf61CECo9itNQ!FJ*x(TB&5hq1n9>DdjgvMf<~P7^WpFsq3f87EP2 z5qLJFp9Iv3{^VLw2iK&|0}Q&oA4LhN*)nGejuo|9 zvmr>%0sr%D+zipS7rpSWx7Q9}lmK$}`ERoeNGX`GZ<4!&%;EA#=aH=bEo7KX(@G_o zZpo5hzn)#LSM^$UYdUsy39W|RxZjX@8DH_&n!YqK{IR2N+^$0(`Jp1E&uOb~SLu3U z>G?myVq)LL{&n-&>&@4n%?^qluq2|@xUlAm6YQ?UAqiP?z(bhQil&eMw0duh6$!>yf%QvIJdvWGP~CRh2j z7uC~o!iw8%#$4Ec??u0bH|qC4Gw<-D_S3HQT^RoOW$d%Je>NW#+J5rwF&iUK|Kj?k zT?B0wr^B6C@ymTK$rHzvy73}*-S~WNJ;M*RO`IxiZ6!@>N7qBSQ(PXo>22_OzZ4Vp z=R3J{|GU*+PAOTkRpmopcB_)F@3CxdU-!%wdGC3%cbluOx$w5@*+z5TE`Isf+lZGN zo;ePml_>R-=uZ8t(3e74xE3t(qo?bSrCdssa{2KGm*S;dTpaqG3eyzm(5ZQwmVJ~W zF0L*GT}o0J&mu)j6)RTCrT7mnRMI76M!nTkK&|MtMqf*OI%3b!!jl(we|kG4_SL)C z*u$}}2E2XH;?B7$N46E)xX5+gf^z%TH@z6fd4w-I+hT6ejl*Td!|DNy8F3=Q6IImK1t9Cv0_zDfHFT)9J{Da>tQ!z>Tc-CpIB+BFWy@SiJ z+8&iNxTngOFUvPclq_xA+|OSnt7&9-&gGLz)vDC5M6GFQD$!7PSf3`1^U&cf9rx$* zFBx^u-L}AIt;t=RZ=B%b_Tbm)9G}bLfn*7JKg zoxR%3oi&tw*E|=|wD^ ziMCeid_}|QWFpN7yn`}0Chfi3##7%{~B}`TRr-$Xl_T`Yw{UE z#9DXqIjFBHQ;YH;sx2be!Y@!j6Y)3UQ&*R;(x>ChaecF|qJW>$48@b6;PkO|>H%VP z`iE$}fXhA**7E~?HR5mdd=L7>`cOPP*JI{}w;E2f@;L0SiaT1<>=y%H8u)p%Bp#A} z>eb8~)y`b1k9kxf{whBn1d&HF(n#DW?S>s17#tIf?aMBc#2XYmy;9J8)ZiZNwaw0$4D&EvL=WTArN~Gyy zv1)g7BA2DJ@(v(v2QA#N@WN1@ zPw7)=8CQM1Qcm0E()izECaXj9E6;!B%<TBgW4M4jTDkaeADL}Gtsxdq@+^?Z&P zruZ#d!oOrKOchazVcO@54jE;Pd||IIBb(!njbPU#q^{PFTHH#?s|5KDvdJ=iZM99m-j@^xJf^tVg~*irW(jHSYzjx55j}-c z_MA`=JPR*d?HLp?H^>~F&Gj<}iqV34684C7Uc0z8nHmCXHn3~#MRDR0=U?Q;`4aXS z7qN2jE-$6!wUWD69DMYZwoET`8SGTCs{#~`SdIFy!WDH|!q9eGQ<^DMo<<3JSnLw9 zli@z)F#)-N2<+Ic0t?=!=cP2X#Z#$7Wl<(C$x^I+Jn6HtdEbaTG>}LAkNx27t)rWv zj=F>`?heTtC#NLrghB3MfQ-GM9y(g)PWbb9%1Lz5(juq1ZU4>)kWT;32)0MtKlk>- z<+o9KYG)&(Mu)XOyuaYNNyvD)`V=x+o?sLy_RIBzP?P1DkdIta+cHk$e2k0GSmcb` zy$LH<&bW$m62~Jl5N@S_=1*<45_yo7Ve;-v%tB%XE8an}at=|q$e}II=P$83;zyL1 zJ3F!eiOZm?U%UG==0zwEhKc!0JtHwZ*6nqtc4Id1eqRZfk*yOeNs&QtiCl;98}JHt zR9$Hv!y``-vmTJ)V%GCBuUcAiu{a!28hcp$?^q>3 z-l@?*VCM_#fZf|C_XIo{K}^})s_Now(fk@(otJh-)>+E z8x3YlYhE<&=J$|i&CFU8)?1+j&-C~P3k+bfzQR(w1w};5<)L7#z$A_9NQGmE-a+VAD5tlGY7jB zTgoYx+A8uI+skjjgS-v|O)T{)+u>~8TBPMUQ9K@G4k6>8H^z#-%HD)x+VM_?Xg#ma6Yk%GS;IV;qZF!S$c%C}R zujd4NWD;7K5c=`VrS^X^QVj5n^s-&jHf?N|MH^6FJI~nLdh6%%ROg-@dc~b@q!^Z6 zx^(ev=Dl>`h$-*hmqfb1;e<$b78TV_GMiU2j**bstwgtnc4DIst(aGu4 zMu)5(e|*ijlWWJFSwC*-@XmKbgBCBG(y&2;7R{PY8qzsv*{E|H$L?D))VG;Wfd8x; zXO7%B6SB;Iu5YtuM^=u!uxadpr9<}a-RtY?y=2jpS5dcKMTNbLy7MwBe3}1(X~R2T z-ZEz9$j;q5wm7(P;>y{B8a1r{GAi==nX|2YoA@+sMA16e%pVpTx-#}wK$mvSUPe8* ze&&3GMqZOvdM^t0ZPT?u@7}$y2hWPV;lFZbpO;b5%lsFGylZ{rZOch3n>K3H=*_jI zvDfGAT|UsaneY5P%?`h5vG$Try?XV+g2uM*+~!Fbr~doSw(D7c|8ws-bLPZeoY1I&SIC{{P1l~Tz4)j>!+I}&s`@o`as1~T@ABDk zI_K!))7;m$xykW(fz|CFRyr`QK(@I}np`ivtN)*lrJWq|csY638ePAEyJxj*OGf@S zer(lpb*eO~;8m^0{1i(@%&S_?t#;*x9`&j>O_a-j#nOUHmM>lv(8;HD^DoZ&`nGMk zHu2rY4H{)>oalA&z@C468DiSA`1eg?SACOc*v?VA17@V0^f>y??FSK^g3_dk%#wa} zTc7)P(|sM4DdVG)X~MFk&ywNWbl+rJFlpx0xnJ)~lXhy>$0Mg+02(%ZdUiW~aM$UBd&Z6$!2{;lk@fw$ zv|c@Z(7G7|2XcqSd(+4{wQk(zIRgju?Mfqr< zjT+GSq47YBIB9Ta8a!L)4eZ*f)7Vj?8#HRPb?er7QwGpr=+e%2?5Lqrhjkv(qZM&{ zmtKA6Z`w6v(u~1_2cO?FgT}+4o~>vsHTACFbx@;G^O`hk>D8i5yV)CdE!Y{-xN+mx zSC<@IJKVcTgKk|q?c2Jk%Ya4;5BN-3wQb?Tg$)}vT)M!&Q@;jYUS3Up_3qTO@1D?@ zxq-pIjUGtDuVJG`n=U^Xh)`v6qOzFwaL=3WFJ@m!H(Z7STtqhn9VC^ z@7OgmPoiPd11GHguGZE)vxh94yy3Tu!&c1No+M!D=;hP4j9)Wv_pp4!%-lX_?yjB5 zjufw1F=^pWlagjnUEO<9hk?JE+PP)@bA0uwZh=GEr@iy_E7$iF%+N$MuG!~kN_{^R=Wp>6$pQy;hcLQ4eROF|Yj;|YD znegj`5L0O6L8X<+L3y?}PphjN!q0ww#-|$peG*QA_2~kXn}3;b2Fy!ACXZ1yU!a~YKNsghdd{sF2Nc*{Dp0!`Fjsarm&?l0(Qmsea>2N#9x9B zGIn#=Gg;Fm0CId~MgOYv**Y^|%*PPa>1baX6 z{G!F8COuv9Q(5dHI}v^u8|;0A-+BqDuU|mqbfJ~w)DM%#qU8dzwHTXRBk)s~sQ7-2 z+qWmRuIrVM)S4loYgNBhYi?yaV`VLFl4>2VM8~b;e_M6SbPTl>E=t1*PVN` z^3=nn#~%0}iJE&bvPL7{Y7LuJY2dT|+#~n8-sS52YO3{X*_usf9*79K{e17OXFION z1YUl!{`{j=r=yo0f3Waq)VzcDXB~)`wlBPD1E0!XJ{9ZvczAjToOtL~>(^guHk}m| zvFrNNtyi9GyzqFzp%H=Nw9jnWut+jvX%S(MPip3 z`y;?E_0j9Z5X52B<-{Vyj;l{c6IW4B6YGrWQ3KL1{%-Chx_O^6uG;Ye&W@x>$Tqi9 z|3V!zhYn5N`5E1S6O$@=$`sv#61&&B(0S~l6=506*9|H-VOi4FscMZMzGUj=ajWN+ zc28Gp{7`JLR?aRJoX0gokMeA~3gw#LEc-XGVj|F(A9Gmmyqre#VIbMB^D!hH6g zHP`w-^CwrP0Oi3dlX9?%+*kZn%%r4mVNw!$zsOY=ZG53Bfpo9QMj3Z!Da980%~kFz zaKDH;zK}yflQJ;eWQZ^He7H#|P56|i@^fF9lzWRfzEDCsVSUB`WofSe?RFNRHsUVn zr77K%&^y{aWNGT>pfc32)YtlVpyO(KUu~308A=w5GR}Oz^}5>hyQoR2O>uMrSD2Jx zrA;9rtNjKV-~pTR&vXFRJ+%{g8zE->o0A)DEG;5p=?* z)b*%K*sC9sWd!WX@B2LA`l0yB3cS_%Z0U!L`51ya-IDKtEge>TWi8?OAv!2^J=V&L zy6|Z$e|$Qq_{xfUqz;PD*Lx@pNYlZO)Is50MP0gD`@;F1$V03eX|do7%;yOCrZAPRWUAz&V`=7rvSe}UH@PBOsrOq}R+Hsi**m`<$kgrBD5HZ7IV3-;BH{)E0A9(Xtbz&$MM7X2;j z1f>`o)QQvL$fMxu@heNJVGQrWC`n-={3!g3qjeGivIL4XvAJh zzBHzA)}P~Mu%tmufkI|FB9Gu#Jzm;=l76@ho9`#%GS=xP-q=S!!N2Td$sTedO;A!| zF5bx8Wz4+|2_k5n(oWtIV?}*7T8uVPv#8HFHf1Ssqn5m1#oFi-l(GD&o;4(==z9d? zO8fjL^Fe$(ELy^JX6cGFamu$YwH9Y(FmH-S{jLJ71nOwsYUM3P07ixAYjH*s^&w6D zj-|04W6lFlWHG9cPu*7{hZs|8`-;F>{i&W0;I*su#n;y_Pg3ydVT@f!8Av?KHEH2P z`pJ3J82yRg!{@mh{nNJ0dM!qOKBxChtZ9(hQrf|0DxP}O18tNpB&%Ayx5)Ay2p+{< zi7sN54gdP~ln=8IW&^Da*Nxf-k4MHI@wwo^i#rJAqm7FrC8?}IA zVaDO7GT{pD>`iaWQ6Bg*wlmYK5|t9C$2is(dZss>d&A9;$m31eAdgs~NvyQ%SS{Q- zR2%Ho@_{e65jLoSd`9SMoIQzp@N8$Bbp`tDPA!1u_{@u-G5RXgbPDmZL@fWbI zW3Q!6UBVV#=7M{)JT9mLk96d+jb~k=Vqa>Lc=DOgRPm}4X`nOPGhw?$PH*}ROgY*H z&a1-Oi4<`P5YmL>m?6J0J{is(so}Esxi?`8j`OB^1b=Z4iG7;DQG8mGQ6jH|fsvuQT3#vk@ zsUJ~iGb#((%DOS?(C;Evmh2}{9#D~A#PX_T##Jq8+ro;+1rd2M3}yLl)22U#Vh5zZ}k z62zuY(RSGSk(VVMOGIy~4=Z3jEm2&Qvpu#X7t8S^cWo*(%wOSS--7-zmx1p@ls8!) zuXizuL1E5g2}6ue=3HyO6nRk2 zaz1XQ9xFMMV-E=4*tC1u1t<#sP-6cs^2tgOUnK?+vRm~Sy!__tVFBgN7K zeTsd1LCbX`6)RrM>-aADEPl-G*@mtz3_>q&@W3(*e?* zby?g7-kV`WVGV(_?&e`>S8ZFxuB-+@7m*31eiiLU-xZ?P;hP^(q7D5PYddXe zeMF;#mF`XTt985amzJ7d&TAb@t^U_?Tf`ayV~79oY66jkuo8jn25&+`3rURcqSrZv zr5q&Kr+&116nD~8K#Kv*K4K5^=z{i?XCuZ-@Dav@cq92kq-gUBPUKyXfFLLiWpYI1?-O@!ArgJ|brGZXWN9a@E+QAKNdeC%%}f z*xU1(4H$CFRV{U)7ZD?f~RUdqtEr)*7gF24#r<8dH4Lf=Wq>z=}w$T#i?h zmP*7I(?d-Y$abUGt`>X21?qAbFZ%VI$fuV5Qu3?izGW#W%UND8LejFl6|)IagdBwK zR?Yo*r=Pj>7(*@y4|k46Ame26&DW5GfXf;!@GGw&MP1wytZ;Z_$(13)26nh{-B{9E zevB}z_E3sBPnOL~d;ppGf9yR6KvYN54@)$*7-NklqOp)zf+fZn%UMvd7wi=fm8gi= zYwWT2UJ;d|VzBq#v0xVwln$bRfG9TZpSfY(_ujp`dxwVj<@ZeBcyD)hXLfdWc4l^# zX`ieOsw3?u@{Lq#uomT3L0*qZcgoZwl?<36gybWwC(<>Q@g&cE$<`3s(IS-*g0qf$ z<>P`e`OKFoA0wsK*lNxA03{!4T~%S0F^!X9i#Bd!bmG)xFbvn^V~P1^a1N-`im-j9 zwUnN7Ea-2>Gt>{x*Q{US(Z{_9A3s)uj}+rv!#PGj78dfELs|q;jP*-SVJRl$ZB^oX zYZ=cIY-4yMH^?~@b1NZF4-ip|#!QL6kx*iP@5sSrcOLc^R$^>Aw?eMD&)|lj=mQE>S?*KRFdxS$d9T(H_k#;;jFCZTj~5_ zB?KK^#I4f^%H=F8VX4z)c`jZK2fuXy3gg}lPso|d8$`GuKccjieh>~?p79NOP$(ad z;TpD30;Ms*GM(?o@Hrk1NokaIhWBVm%n7}xWa{(>7nzQkG;jld|e1H`kEl znjOxs&)PSau^*;=o2QW~N$^ics}}2HC|^D_GnjO4X2oBoqy*^@D5c2D%=*Nh%O$9x z_lBgXnsc8^GtTdY2F$(eSO0=fm4{dUOo%z05OW~p%J>UDm0zS>fBx)za>Bvq3Hw9* zN1Spm{@}vs)a0uvi3guOUXv8JCgtho=kc4LKUtF!w>UX=N=oe1m(P3?Vh*JyT}+AJ z^(4|&tlMNx4hJ;)h7a!>z zAL$X|?{>lGrwZ}Gl>lGU$M*WLV|(s-Fb7bR=o)+Qe5U24J+5xUQl2F@6dGjD{>^q_ zqx&MiS>CG-PTx|vbURJ=nQc3_>8(rqQ)J83_N{w0?$~ne!qT}LPWa-B0^jwjH!*w7 zK|T?aY70W3Z_a~P;yYrF;;cTVr)K=7WQ^amt$~&MA6wuX?6T?R%rn93u0*t+cF}F$ z-7Y=>6AnM{x*fIP{KG$X-|4jV`ou%Q&RcGG-EwQ<{*d2?ot|;%VYf|pChdLHZ()F& zS77&z_x{`+I%9umk9GGa`-P9%8q|C3gULH1Ts8#tUL8EjGh*B2ryl3x79EV4wliwp z?pXH|Pj{S8bSXHnxT?|WNuxD?!7l|)w#(P}&tCoe_dlq$s5H{Ky4|*48~nCwM%s^G zF7jSkq*L~!>-le$74}Drs~dMjt7(0 z6>A>Vls8o!TMZ1h~ni-fpYU{qX=btv-a;o8(Csk){YrEyR zR;z8Z^<2-(@tQMFEc;BZxooe`mB5tP#}Ah+yFGB=?LYnqU9;wOV&c=}REK>x%a2{x z^ONd_^Q2q)X0%foSdS@jJe*g--D91cu_w!5HvL*f9yNC%B&MsN;t;>?)qt})1G2Zv$?GvrrJnYsjZo`K3^z^6R-bcIj zC_Z9UiJ3bp44Ad^>iq+a8v8eG8n$d%)TT}Q+qNq))w{&9qa_9}T6^K%KGzW^+qZxB z=1t)8<#*=IOMmwmYj-In=7v z_ImXXUw`nu`^6GF?$$pVUTWT+27b4LlhP9J-#_l?=vAqbca>vgHpmMf#Z_LV;p*=~Wm)3t;;yY5yPKIhEjv{`btvv6qHtV!;f50{UFH($Co z?}od8=DPozUK&&%zWmK31|IYs2r0t`;!)px`AU^4Wm&6Yu|=WLVNnsq3KlL@^y?zu ztQ5X%-op0sMgL2eD#3y7;nQ;1+1JtFn_scc`&YzoJ@J^P=B1KoWsDh(>x z~Uu4c{3b<0-IQ?B6qtYAyltSC_E z;>CVBexEn3Or;-6mRqzm@8}V2zW;U2ugN!ZP8Nh!JxY#Dbtruqx~?RFs#URu|9-Kn zR=bY%Z*^)^uVh`TjwR!G*i-*q2hf$x-v={|&d^Ss zqloa0?T^($YNy+)<4zrI;^;}kXebuFz_lW^@IKagG-Z9atWX~MS5{}ga?x1@N5b9^ zdpQ7}Q9K>)qtPZwkrjvy#$e#CjMx=f5AC0+6MmWLo7j>{ z{UiGdp4nq({KTj7_?;ddA^wuxEiA^2>f^nEcoS6z_{VMmvD87d)kOo)eHqVh$X_l71Sh zXKJ-DUXQn6sGPa0f;n(_>jFqAaWoF6uOTUI>|D6HurkvRQ&L`SALNqV9C;`98o-!|+FKe-1nT3mW#UC|rOvz$|ryh>Db#?X3mDOtdqXbvlJ9Yibj4W5%M?MxL9^3NXafCrvYn6-#(Lhh{o50%)|WvaZPE-dOKhe4H{AjFgksG29Q+8k`go z<_mFxn}{uCx}TCw%$$Cx_GyU!*xb3-^0;=I6wy4r#CYha9hz{G@x@tASCMhs8Z;{_3^!{k_#wpV_~9 zJt#HF;q{v#Pam{=^Ty@ji7Kh_ec!%ujSt=scD6=xOpmv3-R|!z8+En*v+&MoNdw=$ z8UF6=h}+wWroS5*eRWj&yV2TrW6rK@^*iu_=@^hHC-{QmDK2PrRJnmf3fgheeY?=0IK=gIz*t?C>UOUI$m>jgf`tyW7Fq}dAYd=ry z3nTjYZnHOUhCVo0J|VOtj^ZB6=xYsEWp=_jY~v;81xODj2ZDXgeIIggzAO2i!azQMd=^F# zhEUD;)!%M4K-Kuoq4Ddq@P5&$*73zNXcAFhViZwYkRjVC8v(U-0edNF^!~V!! z^~UYMb+bBbs_i(u%r;wLd+PG*Zr?kuS-ZK~-WB^^HoKQP@y+<$r@g-WBCmGdi>SOc ze>hpPK%4w)hpsM_lEtG7&3*nzC{XuXFJa0T4TaU0HNrfIXOQ0qbsb_I!XO`dEld4; zzvkWt)iFqVAJlBPv&pv-&)1!HR3o^|=Xt8@)}#E*xw1DDnswI*--p0GRFE&*wXH^I zbWbB(Zle*}255x)#VK!l4BS)I!lI#Yah7@aK_Nlhfeuf?p)aj8|43ePF`n|gcf zb-RLLe58AGMssdE(64FAMqs!uZ>yDTtd;lThWCH!>N9Kv@NG+Z%Mz^IP2j1a77UeV z5cS_1+FKfGfgq`e!&+9tMc%gY{io?RrTa^spBOVFViw{~@Vgo8yDi^$iedxQlw|pZ z<-L%`5a4bS_o&TvE#gQ~He=RcJFu>{g&n31jAAEU!~>3{e*eVz$p|9GRw2kw-V37?vDZ`vqZNn4-__u^^h^ytlbIzs@SB;gtW%-FwIY!dIX)elpD(4qAKg{2TSa z5wO7d#NtP3Zn4wL1QBN?uE?0*5o2kQf8~}qY5!2J@{@PQ@+qnfxXCtD}dq1Y(kjoqwe4Aar&eql2YA zU~`DeYJ$pU9M9`f4>Ee_m!dh0IcOPNmeE1ZVaD=0h-W<2!&p(|C5##D2tVy$RqX_; z#K-^0`>7;3sSK?u*aP~T@gwz#^_$5{`kO{rTt~iYQEl`5vjm$Od2Y6Y`a zyx&2I%xnxQ+eYdktJ8hmp9s4CPvtrD;gB1_ zyuz&6n28#1rp7GV4!RW*XBhSELtBxy@nO(D#7-flJ3F(&_XT3A^L@Fv7B4HsiNPWW zI9BLY#vKdpaHMaEckn&x=9tl(Vpymy>b}N7w*(EA)?%s5!4X59 zhD#Zyz4Mij)st$n*wew#5@oUAt+4fy*T;-&l<^RALMz4HD3y@r@RgR3uNTs{Y#oz6 zb%MAE$_LA0fapEPjwFuppA0+1eza~p5T>*xMiZV@P5Pe35qA}+cgx>V&Qa-8)TXc& z>N5RhH7FM{X4mYaE8`4s8Dz}0f%tLRh#8^frxX~c{Byq&|9c*yr(9p5 zY&v+FjeYR^lY@@G>B)FFlYy%US}M9iWORp&f=DNx{fr)>G6${RpJcd8HfdF2l3)F0N=BZG&7ujK1l{yiUZCd_C^W1At`{* zk!n?SKZ$nIXTzblWG!H$#AX0n#h+7$JW-DVe(F$f+L;h2bi%TY2L0M{EE3TPn1?9PUtqjgYD{dgM z&1E`f6Ls{EuTA`U|9*#Du+hIC1&1*}Y z{AdEypscHm8v6NW^`!{X4{viqDZ(`sCMk&PJeaHD(`kZ>sEDcQKC;ft*si(iF zB(pH+XCCG{4z2ObN+;D-Xay%NiRK5%C{xgx-pg<8LTv_Ti0O8u+)neH)=D<#l={fE zjCvU@Ree7vN2Cg5$IEMUA0VT|c`ZV9v zQQr_QxbGL=T_Byka$G34EVgcHw59tZ($-i@hA|TBbf#ON-4$6+)WGJNoGI9bsKt2| z<(6D}$*G0&Tixg=?W0M~n#N14qnN@=I>T{AW$+0K^@GnZy2(*J2OFXrzX?a&j(%yH zF|g%9?W@7&Q6j1kAg&xW~-q^sJI!Ig;au|w*KTVQ{)QLd+ZTNU~=N@p8kHBDim zPY04S%5Bl;=+`0InS&dxvD{Kmem2we!+H$o%;ILc6RsV>x#c+jaFmp!<$aak-OiRwSlIxD3gVXS1CluBo|)*0SGvt0o7 zTW%#VT#xU(4b{y2-ka~Z4Z$Y-jqgkG78=|&^n)=XyyUiM;v|eilJXPdN9of%diM{= zxvQE<-CkY;BZ!#J#p9u9k3#+CoFtCYz_M~qvlPmJ^<9cDuT8Wtyo2I%jLkaMGd2da z%F=BVVw$RNgXtQ^_OX1dI9$2@fIXu4Mlns~HMx|M*C(wck0c_kpDrGaQ-Q`n9udcA zAeS|~9X|M`M0fPtK<=#A5#w^I6WPC^dkAL&SE#$P6djIs}( zFp1Cn<@lWI@BeF_GU8c2^FRB@P)>;VgKAdvicrIRf1lW?^-|~{_Q^WXvgfwtQ zFQs@7l+*ve{bXXDle80cwq~YJ8{1is_9bpXx>r`-RfubGy~5Cr0!P>I9*fO6?(O(D zy<%cYh}UjYJ4HiS{G0wTF)km^6DEcFU+{s6G5YNN!Z>1#XjArniD_kyZ;0=+Xoscj zi()w8 zfByEF0-q^hngUFp=9W{^*tit_cPzQsFL|Hj_EWxF%X)jR+**!Q`q4DGRhN+3D+zOE zYh)TE^Rv)f_LRIbynoV>q_;H2B&C@bkU^6^CAn?N0*>%ZNqB5nZ;Y!C$zFR`fKZgHCH8cJL1#$n5_X=Ug27VUJ z67&W1ALC6TE?`^dALaX$DP~Z9rx3fX3h#!p)ZGxp;ovvCL8UdE^Fg0`L-@a2#%uK6 zbcUxbb+OoV7YnP2z6d| zu48kS*HXq)IajPHJX?e2h4Ew97T$-2zo`zMUy`2xV?D6b-PMX&C-|+c{B$4YFhJWj zMk8W|3XI#rSU!Y?H%g&&!Sm@(@C37UFkdKA0OJWzXT%%`QuxEc^J?saGmHDzsAL|| zX<#wc#W&>8Z95I2B;J~1sXN(at2?=iHU`X%gBCwpJMhd9o-%3;BWtP98S~*vfsk}W zOt>s%CHOlj2by|sh!3$1RL(Jt_le>%X3VwM*i zY1#uyGfpATh))}v;#CHj^#xiYoe3iWl*9U=NrE|c+eG0GG= zX^h!pa9@chNLiF5t~hw+KwP&nU`0{BSQ2lXAFS&SKW&cdC7xl=qvLesd6Z)~BSyjh zmB1fPFs1FFM-A~9AZnlXxfJWEzAu=;2=N*MZSqsOIO}*{`st|hQ^wkC2|coc`HAOe zu^p7LCAobA3pUNsGr5$E_8vxRaMRieMnIx32V2mPC%?4Ld z>HZs~DQeuPIgi!6F zhUX(-`=dN2serm9*#bCpuAd>su0SU&g}R;+O~rj?dsM8)zKgY;5g-R~Jo*DH%Z#jP zxU!Q5L*qgjX6!*z!xmAma)h5aVyFwqH8;BV!f-|xC9L>dka9ep855rvGuBh4`&;V9 zjP=jTL=Ral<*aRn`$aS+?+9@rM#f9|nU7?>3_fDzjnQ2Hv?J2oG_|Gm%*BW17WFR= zv_?5)5GUGSVZKU~V>oXs!}^Jo!S8q_#OKdv3jFU=fLjC6X44pKOdY_Qgw`b+;Pw$P zw`tFa5|>F0+S}6#MBkNmzbGFlQvmJirE8;ls{&acOtmJK?w_p)`gS3vMSYkRK}==C z76Up3`)OMXG@T`80YB^fK+d4TK<){yD#ePdhH-c9N-v6qD`62M6whn4RYz@FC zN*XBZ3$p;=-{cRbH_WDme=&?@P;l&#~{xFN)7_&u8Dvs&To3 z{smi4_byntQsEpvg+{eb>^ZUEma;n>?rxZ?nd#vk*{Gp~-%mdC+x5DcYg4|}bFC}o z@C(W(yiLgK@+QZ-DbQ+G-#n;>eib?Wh*CLVpBuk(=RgRPDIMB@Z{l#hwfHI zy!MQE8lkC$RpX05xKV|3w%;+;q0vkW%Od`d3zlj6&8kI~?X21hKiOI3E)v%>f1x}z zx3AjQOc*>lvXNim#_qS9dfx{^&eK?w`&AHX_s&25n&VN+e}Rh7kzgleyHSkQV)ldeD~8JJviImi5o5^eV`O7vT{Nrm`(_5-Bd<~Ba_SMIDW1Va3Q$%ZW229E zoG?!y+eHwp4lrv6fXqgTEq%l8pungu{kL*XLaQm>+QH+48TACf86)3@zx?m&xHi%bh3>~NR+i)5F+;MV?Nch{d2bPKP7^gX5I*I8#E4w<{Tqkh zOy}cev1V+|G+wJCP|p?q;l7Kc9kzse0bgVE%M5{@VWfkTsFeH;L^&lmJZ6JpXFISY z%kL%5CK1w{>$20_7A8@=e8WUGG(g5VG4Hpw0zN^!Dq_x`0#u8gIb?+16rk}@+ zVTfxpvpMn(O3!()vfP?Z)DhRk6+s#?sDCpegG2g&{=JC!p64bXYlC0u&7zZ=F(6WIXEFL4)M|?L#M{8Fdz3{Yyp|bdHfDVpv${|dg2doWj8D}Jo zHQm7>rZnAchmrv2HjmmcRG#(*D4nT1`&-%q^X?;6`8}UR8y?|Ke9C&r}Q8(h>wlec}kVIuUnJ6hb{6vT z0QLtx>TTc_Vpdlig~Y~!-N_`Ur*dozMfvelDN+f_WEGG7l4@sM{(t^voC5#L>m%_x zTPLI(!X(t^^^dJH;`I;ZJl>tk+iU!2J63AdttD6kM!T7yyP;3YDi}|J)>0v>E^0?z%?>@ zPq;Jd5IsZ7Tz`<3W9UyE#n3Lpo**=|sq!a857c$U)})N;y0+OnZcC!KhVNBx3+;-% zp5n|A0_^ez~*xQN^sS7KG=E41LB%!rFPaNxkwrAx<-9eeup=~=Vp z?(p4n>B{YgVNXLspI*3p+h@n_nX~5X-o1O%CeJ(fLLq`8S{H#5`8YK^7K2c(-g>xh zdZO*51uSvzh%hvGB*Ji)6p(xFkqwjt$GV%3Qg7Io4)Y(c3T2- z&hNV^&m8xzLf%Ae=iZvD3tNp!ZoRu@?iHF6o3p)IZZ-0-Tif=(?7B1VPwP_iE8bdd zA9wY5gVGC%3N0`9_FcT#^{cg20v9}a^|p7ev4LNN9t^8mD0h6>uNq!?kiMwh>3)&Z z(pL4aSUYB(-}lM$kDp9EpSzQ1%QjvmhQ9RJ(xlyh74bsyJ&$p&N7kIuS|r<~PS{j! zc+|}Ck=sXytm!lUNcQA_?pn{3&E-xkU$`-I53j#N2DJr7IpKdNsBd%NlAA4lzY&_S zdgIn37w_DTNWKxCyxw!?_=$h|9y+_M#h^r046%?HqSwOvMW2{}j$lTEtEWUM*Z(jAwONFocmbU)(LdbgCDc`T^Kh7raua&BW z9^bL?iypoAty*#6#k)t_j|}U5VB<{f{N)=)`+PYl#p7kstRGxx@xS)zS;|Wo?V%A~ zmemNWA+DyGvqmU+O!FSii}1ehR*g_SXG7ty_7LlHNF$`z)Ch&0p!{{^xS~nFYJ@cp zDX!?~9L@WH+ah#^Q<= z*U$)&Q2*LI^Wuuo=KM3PTEk%NuLA27uE%7(#1)W78owtBe5w7NmryTEBb*tb5$ahH zUH%68OocwQFF|yfR#zhovxWYg;qg}4Zs^lxoFm0sEqI_2suY1(ta?(q z?IE2JdyI$ska#IEzZ-%n?v*Jz%3&Cfr7}$yC3w>QGy%zk(JH9r%j2sWL!=5u=X8X( z;t$4@n~IGxRM&Kzl%bj|#!7!=8^4#1(ikdB@LbtIPA`_pjN!m6$t>HK9b~dY+{IY3 zGWt|uP%yThd=yQ=1KUOy0Y&-jl;B{T6y?pscqU!~Vd%#`V1|aFz@aSeAI~-pfEa)M zkJQg&s2_U!^t$=w_c$5V``DY^th;nj&H|rtwmCDGy!$=kJj+MMa zNJF%KGYDA9P2{&lOC7=cxPEhP<;Wa#w2HF6<9DeA)eUf9Q5^_h>@{VWk^~}4q&|22 zb5F28%s0&Xf_4XtIYwU$`E79=`e%5f`U6k%_e%Adorc+gI1J`fVkPw3=9DsAo0q}X zKV;UKrt9ZBk(d}LOntr65qP(5_l zd8VPVrS5GC`#Aq#*VT?YcNB;9`x|oMP{tQP7Fg$T=#D9xtPE+81 z%nQc&gpFfUkp_a#I)ZM5bKD8w5>2JMBd+C0?L!~S9*K5Gr4Pb4&n~GCsVz{-5H?sE zcd3}E9rsWu$Ixer(p>&goRHJ?dwq4&Dkd7T!}{ZgDN-KJnj(XaDz4lqE0GjoG7#=cuH7jU{M?=RBh-%1-f| zr+8~q^Bv)m5GVQGQ(r+Z(~gz?|2L05bk?ZhYxEf4K9pItg&OfnwBnzeG)yL)F*)-F%3EN4#@}kC28m0qZ@yg5zGax#Mqp{hZB}Q<@7$@5iRrJ#+A0%=0zwp0}f( z-;7MT9+7e_Ecr@ka=H1VyF(`>!8jHUEt@sT{&l`q$?)b&*XG?&L20i0zv-nx_2J8O z3d9()@P2`*)`gqcyPnH`E>G?}`_E~$O%kpw{W?0V!tilRY?t<1QMiF^e#;)dzdi`5 z-=I|60R{c~Og{a()8xd1%l#%5b6-Ti>a>)^UB<}vGpO5B@-Ttz8j^xu% z_wPwb$`<6+AkET!;_LcNEE4WLZ(J(p!AI8@Migtg@y+ENePX}dIw)q*b?8r4hSsPV z&+hW^e3!0$^G-LIuij;hWXkKF4 zhtXTR$@6aX^IN)cyBd}}XUBz0fVG)}HjxI+X_c;*i`<@a*YZWEb=V<-iTi{ z%g?`h`Z%ardpFO@9S+)^KYTc8N_M+@eR3`RE%3@Irvm%xoZmm9ev_Q@>)gHZO?c}m zUA$&koVRV*yiJ4Pm|Sfw+#L;aAU(83!ZQbot;;2fDPbs1Z(o{W%T>_Y_Je@G-9d-%W7Zv2SYkoW`Jh z+;|ajOP@wWOjh70wKTBN5x^TyS$34{6jDl=iilAUOWqfKy+_(I*=Ed%j1j<-D7RCX zhRLa7y1uFC7*p-*N5`0MQyw{@E~8N9;fm>j-%a5p@1N;Nnasfy_sdwU3`Uu>hRiUn zAeO{ZR7p*&jG?*+#&o=l;o8c1hVYg%;KopYh3aS74b`x$7V-`q!g7>|svq4gQ zw1ug&LL!f_o*A}j@R8s?dMYiqNg%w;+w0`^FK(s$`1UVz_T}QaB;T1E-j_>jNq6Q- za!OoY%Ij+ObAcKAxiZUR=3mz?33%giEA?<-{EbJCA4SAOMaM)(M+b#P?YI`>xGT2m z+Ss`P+8I~UCtZ9y^33bO$J6W&zUaI=rR9!i8n1+3-Je!j7gu4`;~7`p4LY9I&@-Xd zrl(cc#qGVD5E2sd@ZrNpj~<1FhK7ZOg@=bnL_|bIMg4UmCN?(q@#DuaF)=W)d$@s| z5!QF%cjJrYwX|s5zKpv=!?1UcnupY`^EBjD^oefMr{69!eR``}D}OHBviQnMcY<=o z&G!uaWAx!;>3wtCOuSwA!q8Q%29%0kvbXEbySqKY^Pl{4(Ddwge`)-%!>!%lO+M!` zwD_DBU+sKiF=71r+MYT6%AVcSb@Y(vT*9D;<~~i^#8~$e5(8`aPVV*gNq)_N5_z+a zI$^Ug_v8yJ-_%&}&E!6%%a^*DctY6yRmra+Mr}jvveH68{H2Dk4sgDjb1i*Yz$@Q7 z$^OA{4(&kdpc!Y5$X+?}Tkf@_)VgP)ZR4Oi`_hb+szhYuH)Ws007itXavr zRvl~WCb#RYkyIEmw4ZbTu|jq0YSvY(e}g)9)vspnpe}M}AD?9B#KCrcE(`09( zzEjoN0gsu%4;}oHX{?Pf2FMdJZ-8tOvjp%1aD|v9fEkD@-m}Ca{}i*hV&}W^>43Ir zVX~FDqF2BLILigXWZo}7eY;~;&RKh#Y@O}!@?Gi6`6}0~epx$V?(aD!HS?d=bkCiH z5kJPK=IV5PruK`yYo@fnDr_%NWZ8`iOCJwDZoNWtvdNy)eh-WHC{nrRJUII0dbr~$ zo5nsdbtV5IQW1|-ZH)vXIQMrbWhi-cM%&HMQGrF8x#rfA(X3M^&?g_WALlW#$ z%QSy;%DHIauswNZd!Be0wcx7>78{2Y+ zW4|Gx>NZIQ^O*&zfBt+t3Oonf(9dofp|y`j_~Hk$sojPA(D>cjU; zpDU}lR3rQd<>cq5`oY<->yxGSG-t4vUCYt%y*(}9xke~mo!iq|tkMWS^wkI~U-ggu zG(yn}8o{-#Mpy`EtqOtdt!;otaB|iNKS8eQ)o`ZF5`LeBb6w`&J9I7CymP1oR(b zP5QfP#&0o9Q~465ZA$kQ)E1TCZ}fX=4}BS&k%fq`r8<;TlX^Ma;Cs3;iATBU!ylo` z)`{_31O+Vz!-1ys8&4^UGx1@4q>T%dpxBi0T^(+b)`tk^B* zn6FkI%O<^3knN&*{ww3(v`A!^f_r!f5asc12QyHqyu*SQM217~A zdqB}^n8DNyo_@@JIzlh#1P5|vRp>cd3RxdG2iMc#Wca-p7kxO0%WxewE)WYdN{7dA zpaHgI9zNpTDAJNR7O7b;<2$1@zm*Onm9U(vj@$F#Wd9F+q&zC;dYm_ykr?my`w8-K zf6O_cek?e5;F#ffkf$H{8F_6m^b4a6(W2H$CyDv!Nx7fnli6|9ms4az#y(LzALehy zERoU{upY@gitI%U1^`v<0S7nuiTA)@Ubj9vC^%#3J#i?z?HBD%c1ZaAp`A8ewHj zO~L#$amV~VbW?U8qdeXN)}&rWxLyrS47K&CPzJLKAuYxNpF8QK$j9Id(@;NE{0)tl zT>fQ_H{^6N)Y_*)9qIhW^$*vdJ|HbnyTx@!P8aFApk{_BLH*S6N8b-dVvhKz_;aYA z3jP$!@01}M5Mvh@eS6S7oHB*EF?gRU&i0V4?PKCBhWBaW%&iC?4{v>#AA&pj{c&eY z`mI{MR#_TlM(;!I5wo|TEK~#aQ^8d#&&|~VO=E2e{-;R?L#wcSZ8Npzn@b-lOt z^bGIw;dX8EvT^8~T2i~SF`Mn@cb_TnnF60FpoRkaey^b*v)FlMd`sWu`48mM2)*uB zI+=-Q@9Fkgu@4L_Q|K2%+oXfeMycd=L^(;Z15^fcN}z`rz4T(gB0WQ&u7g0g59oV( zxpz@on!I)78@3inUfwh13>wC%sTP0oq~lGXXsLCRdH5*4!w?nl?p!$)s_UW%)KY<$ zHbez^|IDRDW$yT4`%Bh|G($Z4C=Q4to;$y^cWcMlZH^y#KRGWbi_r~b!M@1xHyM@#qOL5w*j5 ziX4YM#PdZcQ|05LFLl{1?rlKM*+Ka>ki)qZ{QD99kqlw2b6H1F&`W?kfupbPgCo~L zmy5as)M=zUA*f6z4v*f8N0;7>gkSVdIbMiCVD-guKJ1<0Js&F}0EUc{`((5y^{udy z;&N*IAFLkxZMweHil}dSW{{-6&4p{omMVoRrHeAY(*7#hB;_#iZ*%+0;d1+4=HME$ znCU|_-A_3@u?6bG;qf(}c_fu!iX&B#QWSg0N-}96)&}M8xagO0 zvHN%Kd>I!P5g7C`?rB8egO_m$`*-fTd*%AXaT9vV3k0weJC^K|{KC@4ne@&+WKpHy%H`7W3?Kbkc>$q_Yu8r^1qsg(fZW z-rKc%k7;w}9e$X6AS8M8jCsqJE!(>1z~12GMcWR#xVW6Sb$|DRswG zpk%+mXPr8A%DL4K)6Sbd5wo05#MoSYTwe39$-a^G>$bP@!%?~XQ#V{LHmCf(j^}5(9tz)H$)QD;>>g9g_sZMp`%UdbatmpLbkKb|&PSBjWkrs1lM6EuRyF9r%>cGk{_X%~^&$yL0ZCuN- z7ZXA+)QFgJ{AA)+QB&G~u{qyFi?)_UYi-|`>u;)&@-DiE$P;^tCM}NMN?eQc>Z;3_uP|PraIX7^>SYwa^qsi4S!Gf zbq@CS7q`v4vuEz{OxNKqPUm(n+_vV= z?%lcohX&ucIl!T3-(KC}+?DT!Y1+_j+DBf)2HC%idlG!(cGvEm7j5g~an`}vt?QUE zV}j4F)`qxmTQ&A&T)d~dhyS~Q7vJ<>w5=EL>FWnuwZZF8cu#V$ci3>;{=#dgo%i|z zuZ5kNJJ{8A+rcACH+nb^89H#t&^hb2uHAifz>r~kLLAPeIi5_m*9NUzxq0i&$Iq_D zBwdO^20sy&bmURe+$}xNys$r=+E;sT@uADt_lG3ApS(F}RF_lF`>b8NR(p3r_pY7& zBjWcwNZxrjp=-BJFKf3fq>8U2iLV{|!l$2uLqAQnE0uQ)e%k!>yvn84_3Rm3_vnPT z+3H$aROoEkr`@bBU7OgoDz#t5N* zx%+Ibvc-GzcCVp*2lmT%)4}17{yTF-_UPKZM33yRYV9BOqJY2V_~xa1=58;UecF+~ zj(M%jvnVk>BK%3r&@%-K#+E3&H9VrLJa3=n(?nH%v6zf`GJX2=o;`a4*SfpA&zw5x@~MN#kq<7PItT@Fnx-!6k#o_U<6*>VN8#tE=n7TmB$plOm(x`0(20OI9se z0&EBT(a+K0)}`~1x$JFvdfMCcl-KX#)859Uz79)y74$5vbLY>JhlSMe&5dba72=uo7<6qyC=hv_J%!!v&?@#O57fj`0cv<1Lb_F z%V<{S?BM)G;f>?bx&z+sxQBm`+o4kl$_^ncAd@X(X-*syN#xJ|2o~_o43seb|3O} zonGDA|FS;YoZf#57iZd5DSYO}m~6WpzKy=UyZx2ux#g|m{CoCz@x{ea7sh-wSbH)p zcjSov6D+Q7DsZ{TtnrQ$a;&{E1+p3ecHJLJ=gnfTd`u|j9Igf1l;kDdKPqkWXyw&@lm@H zAOD^FbZ5xrp#l3E1njF9u&++Q-dX|s>fSuuX^88vOJQ;6Ba#vyAA4|dSai_*XR*tZ z9T$U8OGB#*Ta_qFn560d&&=RzW0fPoRIS;yf$~iW~6QVaq+?sU7@3(tr{s=hGO89=?X!%4?lVvd8b^b2Y1& z`_cV#LFeyW4LNh`@`GHJL!S(YC|$64;ZlXZE&Bb}C5l`v_|22j14`>e@RBtkeJ?Fq zzJBS_wJZCy>uT4tL-)?TEvk9%-gelt==~GWs1^^3E93P6jWKc6XJ zoB{_ey@bfhQ-mkAHA0;nr;F3!6eAuU(K_xC+^v7>XmHz04|#=H#$Q~Cdz1AHeqD}89CMu`7i z1HD)O2?aW|t_AoP{%_;iuB?~P4|u`0&3_xulYr-4;M*s_S6O{e=|Q-&6z^|M^VJ9m zyEP{Hwrf|&Z~0OqWQTccF5g=J;3c$qq!I2o{CDwm2OJ+A)d>9|pJ-*sMS6X(Mz|3V zxeUTJ?-sYvt{qfZ5IA;9y|SO)FRc!tjDJskE0 z;gMxbd{3+Cnjey{Q3?9LorUtB!>0iwwd6O?IjKwyQ<)}>*XM1vQs4nRflnDP(YLDZ zo>ld5IGW0JjAxBBR);}WE`xIbeGlko!Jq0fLz)MR^?-h>t4p41^m`b(2Shy_-o80< z0P_H#tr_pVGfxhfuK6MJMhW`=vK%mu51*5K6vg>sm20b)14{LIo6Qt>ATx46Jsggu zavkGxz*rpyS-DK+X%@- zUOQxH5Ii&MPmpCn{EszEerg-=UE^)cc!#ka^s5Q{EB73*3Go#A~e z@a|(-yt~*=m$_D4itc~w2=zMw?8Z8L+rxJo-T%B~V<^!Y{$VfBk4{lT`q&{n)ScuS z6~h*FDY_d8z4sJnM>%u!Bf=1GeUExIU2cWyh@j{r&8Jim)+~w=K<$l1SYXs)KhWw% zz-oqBN}Y6&=m|!Y4c7Gy{fI8`kC*NT(SY_D(E{?=D^?pzP&77{&ZDC?-4dNg7QI*z zsE9EZECx#47rYq^`+;xScN%?pyWBs@W1=j9vJ~Hi5#SV4#i)(>JU-+@coHQLjyxul zMv|h{<$Xm>SS&^KV^T0j5yl!)^rTWh4f8^EpjM6dRe0nT#xbx68B3u)P(=I@j}X?u zm=OJu8k#XuY%FkG5H7!W)Dm)qOn|2qb$V@6G>RFU?Q;@i|vQ;l3unvK*K+?9-ge{=(%lEme7#C66n9o6)s zBFGb3Nf@1wifsMjD;#^POhqa$&5}k?q!g9*S3N~h4`DHONEv0E)!?f{ccL|?I9vI} zl8kf#F&B=_;7gQeaxNrT>ba1$O?rluX84ZdYYxrCyvpf^k-cImA)kGMMDxIU%Ig~D z!IR@nu+`(uN{aOlf+3}WywB>X!12adT~0?a)>6HX%Hb>=3}*n)Qb%$3`fD)V?pPH{ zVE-8|G=B!e-|{!O7NdrTdYQb2GIW-!LJnL0oI|F5n<~%xLD;d7$8-#SK_wC z`hu7OEP`7sH9pPn()mi(Ge#+#efBV8S=J%ch*L6_vM&(a)55_st7w;TE(hmoJ_!x!>DW=dv@jsM;m7tLd4vUPO$%yL&{uxY~ROv zfx9=9<#e(P`!N`H^G<*--w%sh*0*167A7qH}@jzgLnqYI8NwJ+bF>r)wHrCp$Z zc=CnvxQ>uehT|gcwf^ZdvB8Da{KY+_mBdi5r0pP2u@TiD!OZb3=TGT8p;a5@ z4gE7dYckh%X6B4lhJ?djiK!#)ueg-FB=gdU$Eyd(h+ZPdSclJ3T4(qOO50LDn(BDV zRH=qAFR|}*y1^3W7oItF*2y)o6ln}H2ek{dW0Iem`zt!?{8hLHjMU8|H-W#C-h(8c zU&BQu1=w*SU!d&;ZH$~k9GU>yo-3>*tc>);t{9pv^j3TxmBHu$uxSOLx|F||y~RF| zg_i8b^cH0d%h1T^*&5)mwF~Wb{WD(RNjEu`mKpD`ZPE{Mok40U+o;X=(-GZJ^JI|8 z<}7ak|K=8Q2iQU4&JyW_vXtkT$DGA{1UPjV_WHj&fDVqczay+2&A^t2a<&WnCSL-b zR}? z6Y+g+(iwv59A;=XuFoXFAv@^oJCh0R6W5++(W8CAp!2f7HWgqGfp6J9CbTr6EH-JDN)>qOB^v}uC zd&E{>t6=auz*~KZ6g1uk<&x4qD3xJ-z%drg;YK=B>xi(^9diY=IVN=pW$7`e3Y9m)_BNnBH&rT1UnjShKJ#@4-YLzx}i8f+x zdieD8u!-rRW70#%Zpo2?+Y8g@r#sOxCf^0W7M*OJukjDff0+Nr>vsXOmwx&EpyL(( z%)h(fFDKW|OkDB9CU^V3?VIGvwQ%yRWi~(Onm6wB;9~8HZh!Fh`vqe>=gw)@v*ga9 z9%a`Av{-&ZTX#|2>=yYf652u+KE3nL1vuS*(@(4i4u8;d+;D0ow+@4w-*w<-&8#T820~?_K+se|x(Zqeq`>YI|(mn&b5v zC3We7!xOdo_}1AkMvZ#m=9cQ>a`bmiQs>TzZQCX^x7Cf)@=JcRQilwAK5$@)g999N zPizCPn(Ia#26bM{EuR#7`=lN{p4r(Ywr-QqtXc53@>h?q3UYFK))AhxPH5V6Tjd(p z&t1L?)jM`fY}G2k#^!1L22X0&o;G;Gk;XR9I&?^E*)qO~&68h$jjLAeaivPn+P6<= z(IUQalhut|JpQRtZ29srmX`628lP?2V!*T|tDCfpDQ&qT@pNrf?6NU~UFP2@a#|?d z_>F7+-oYUuo5l=#`L5WeD%CAsU9R`_%vXQSYF?p>)oi;z@;m4J`-fwvaxcB_uML-ro04$=1$|D;?b% z^xcT@6J4K={XSo{Z`*p-*i~lEM#o(}?T_7`^yR2G*%#Da|MQsaMY{wid{y_)?+TO( zfE!=?^nCZttoxPkjxxY_a8GHCD%Q2_s#UL3?bkZiztKIVx1zmKm*AYrubxz{;Blnj zL#SZpJ*AB@_zw6Bro3*x!vtTUo4gB8hj z#lL7;x#K9;z4NYIshn{7b+s|UolC4=cedu}LQ89H`NGX_`MY|h&Mt}E`g_F42C1tb z4WBs9qGa=IeZ7V^f>X&Ns(rrU6L}(QKRL>I2~KC|T-#smP2a<5>|EP8N9jGBcn;6E zlHvO)pMFp0gV;Tsrp~n$uBs7UduoJ9eayRuGZt_h?5z>vhxC4NjZoJ~BQ#v15xU;d2zFmIH0vJHKA?%%fOiEWV%ub}mtA=; zq4Iu>kRxxyEI$`k^t-G%7j_nKyn2?Om+A{=H7%!TgmUnkeazWkpsiVcMoM`vpZm{UkPj z{qh`chm0|1(R*YOFntEfcs<5#xF;YUvV^@r6WEjC*ejj#|nF z{gk(3{G5W}Hn1N5aQk%!kW12Y2^g2#5c198Q~Y2IzPJpY8bHfG#^B&i3gd9_Njs>~ zP#2TT+tEM2AcjQcs0`~lKfllf{0bf4_e93f=rg%3_Cu$4(j1gjF`{%W(74Gjh7W;)1QnGZ?bJjlk z>aZO4K$?%3j~@ESDK?#z<#;oHJG1XfsckIhs@Pj0rzZI);Mv9or-|9BQi9K+3T&1G@iNd1mbMw~a3ES2IY9R0XS zWA6;(%t{D4t8E|ni4pa!0R_MtXEuvFrt%%&sapFr!&AJzAQXh5Z?D!b-62D=s`+c*C&&0`k{Yc6?1KS$<1Q1|)qW6(+#QV?2$j~Y5w zF-XUYK)#6+1A$eg)GRW))O-MLCN+l>HLEOWUu3d%ZktV~ww$`YshL;lrd_AoSkC!+ zUf&!)6hD=_!s6Cpe+>_qkxN)Kt$X0>q3+9mI&Hb>=Xtg6O#G!*o|gAYc->Fwmjf z-FE?NVy(O9+kAZC;3jv9_x*NWwbq+YuWG;U_n$+@75}?$Ox&HoO54Lb*$y_VE)~iT8->Y|mdQV)mV_MX(+a=F6xLh~j&t4J5mOaXD zJJ8oQS=}JitYrO59c$~_tIK~cslbiK)>W*3t72Wvu6m6+HEY(fu0<96S9aO~6+}j3 z_`}dRh~)_5|M%kngRoC0MqmWqli$Y`X%B?o&^!IB_|hmd%;bMl(&R2mlQqkBm31!E zyh#t=)+Ki|k8O9ej9;y$y?S{!Y_u@P^;S)D3abX?nfujrkE_tW3Xc9*#56=lF+bOk z^YeQ;E*N+bNV%|gAaF9!5oikh{GOVT+G_6RQ}Ykv;Z6(l769veW9LqG&qix+b?;Cx zxcZV*-^;lhT9ln<(WXJpb<2ytp3#0^=lsF9nlNQlE*YUG}=|m=iLcpJzcR&cL0zn*_BsU3a{*n}6a<97JE^~fHbD|>zx{%9ex1hCqp~@h}Rk+U%E!93ICg$r_2iIchEy4%&Yz1##001 zIewT%=zb~lc#a#Q5i&EL6~SkMeiawU@AprSrytaU;|7~B`$Hzl%$)VBVzAY*C>il8iIvjpS5f7N_7c*U#bCtBLasQZ7Sq4e^4lR%7 z`N`DPXRQffE9P^A&f1FGGwv@lU6;4hNaxWQ1lCH7ARI1fwX9Gco|NT<;Tz6Rw9uk8 zkxtu)`>9{U9JwGp;~{C*fZf$_jmCf%MkNo1p5h5hio#dxdByWnrt6D)C@*iE)AZp} zd4ed1Wj?p*!#4!O7!L9}#<|XPn^JGB0KV0sI$j!}2~= z(-8hgOEl(@qFQ*!|3av0>WbS!I30Cd=b}56 zhCVhtO-LsQ5F-EJX@Q{`f8spBQ~em9k7w4YaLlCD z9DD$+flik18zsNAl*71pn&sUSOA!8+{FV*D+lAgQ^pV>N-2pmg%p*VO`)0s5n+Mt# z`_zr~$5gKgZbQHt{TFm*8pjUL9LRIz;i(w(e~U-gQYXoH@93MZk5>}TW=%0mhlt>eHBP*+kUKKpY&uZhD5bTLGUY|X!3K;VinIDdOm(_b+ z)#Bd~Jf7l@+IsynSr0Q}i9gbq1@X9YeL_krxj&vmW2YYQi52{ldR&>0S4jfVDRc6m z+X!8CaU6C!pRWAOAKsWOk6+-vc4<#>73DDk^7dI=g1BvI4f(iBF~<`cwjcp84}vA! z2JoU#wD=0&sjk)dze9ZAGL$dKhI(v{!MBbqLZ36B`c{%Cl@h> z5N|Z)v-{tq9nDYq>_l#Esf)F!2%}wI(p&R+jC4Xrz*ro`LQk1oMfs0sR&iY(3o!+h zA%((<>a))J6jPqj0eN4ESPmh|AX-*Y%Vd`LchgP z9VEA`We`|BCUcGTbO`i<&0oBu9M3diCK@~eiF_!gwRoh}$X*7`*f^USF?N@(bex&I zc7tBJyzf8uRbTEZQCFYdN>B91fN>|wX(iSw!LFt^X1qKb3qF%X+4ZqlvL& zRD(2A{Rl96E6>S?v2E-PKgUh_4T~0I*-kKz2A(-)^OWV-aMNiG6u-teiO&~ainm4j zEB=kTDr#&Pxyf^l;T!Qkal9PHSYxy%&N!^cGO5t+L#|ip_lMz|by1d5`f_>OHl-6HCQ*q+#vo=D>KH}GOje; z8cHqHb9s!Wd}UHczYoD*Dn;ZnRou4^$6nml$G}}ofAM#o9kvEgmu0$Uaseg6e^EBk z4e?TI5osvWvp0-CSrjg~6dZq^IDs4xneKjSUxDpyVTraP;HD4cF)hT*!Q(II~RUFEOW| zQmdo9r-owL4cBT6IvMw=sOc^G1h@u=+00Noque24%%!pBEWTY@g2%Yyco~K(?WGtp zgDWo~g={$fQ5?7DoDsKoz$>-@bnP_T3xp+qdc3 zH`;`_v}bXzpT(sGU4IsI?b)ea(WiGuZC@F@ZB>Zx%HZuQANsC*=sxS-2KaC0z4bHh zZe19-bz#tMkC0uP9{Rb59N!(W&L!7eKw1(zsTh3iNCAFM3om`EvCj9!+Q61RK|S^z z(>4xobUL_y0qx4%!z^-7%~sqmTk)pVs;nyKykc=SE2rMgJKOo#otv|B-`yR>Zxv4| zd~*MjzZR$UTfgUQ%-Ycw@4}A_nEPb^pDqn1JsLJ(U4cV6Y})0qLeGVYV9H-8&~!sW z)oqdrnTSkP6Hm$FgK1n~6le%wEMOG;Hrxk-FPjhmbOvg}hyb-=P=MetA}}sA78P1o zuvA6uJ{i;w=urTZ8Qi#*rm?ZO@$T`@gKYv}tIu ztsVty|D1DE!rh&%E)L#${kIGAj=mgikv(sa+?$=J#Tq zn`JxM|6AdPgmC}(F#>4q)BF_w$xG-{P$Qfhs1fE@*N^w}hB%wI5bx*K1!CxI44=DS z6l*-*5AW0Mw@G^L{%c2wNetzA2Z}e>2nSd3ct3gGf$zMGpS%C&p+@lP4gV*amv;b1 zW;)QJGMv|U$@$+sXK&6rhZ-tnP(+J?I71upv7t5DP^}M(tC2$ew_}8m0{;v?-1kOQ zrk~8-QB6KK5GqQ5#*zQv=_$`sk^gOJsfk|HXc!8x=m?Bi8zYD2BJyuR4(2J zh-Y)z2X}e$9Uf8$>5aNKMiZcCMEsH3fs}m1RYB+H@g@A+DdmhG2IGpi9U*kI3bcWq z;hi&lH(VBMRdgRxSzS(3vDF28j6Ebi!EAuw#P zJ$qSQ{LC2e5~!(*UQV*#;{6B|rNiLpzv}~j+p!R9rf=6)vO5w*9H9p8;V}-4+xjZP zQ|8I!7ORTT1H7qDZnr86qk^6%4y&JHFIbDXW28LO3>TDV^vo1p$O?>+9-My253C22 z>lr1Zz7+;r;d?I@K|;O4yuq~cRTi`Dzy4i1Zwz6t&yPqGjMS2H8a`E~wU~yCBWR`> z;xlm#PIbBcMJ)l9Fk^M~v7qbVDLp5Aaeh&xm}Lea zdfpM{R70?fVB`pW=sCudb#108lE+0!@nSVmuR_kC+g;GZ$L<_a z(mPo8D7j?8`~fcSIUxhdj9=1uj+q4p>0~Nmin<=oHvSZ&_HYf;w==W;3-{?1IK>wF9k0>SI9c z4ULerMLCyaO;ff-={SlhgCj_kX0}y)V#pR3<{0)b1%5y9mBE>(|`U$x8 z|Ks~T#MI+>^A@F}rHID+hidVWdmqffN}bOK7nD+Yf9vk-dOZO;56L}^gjLYTiO6kUZAGnv0?`XtSRsUT+ zYgtXhws^S|5?kYGO~owY`lX~6c{O(5y&3j+NI1M=%EGuuG2wR}-oJF``mxLBcbz=p zd1$uV)YUVW9`xSx_)%2grP~3={7-lvTt9uqgByWykD|lxgajP-_gm=$NsN<|l3%60 zN=-_B{pxj6d}8E-N6!)xU!=YWy>;*G_I=}*ZRxpX|Ge!76B80%roK44eQyuH9n>IqY`enQeP|Y~7!jkQjP9u!qOq)TESGuU-mEhbTkW1{%XekW)_XR-=ej9mv1`j3j>-l?z`vf^L>Teii`Jj@ zJ#gXt1sHUXdCT^#*t}`MimO+yEFL*|?}|-leE0A0@OqZ;?6BWnV5F9-yn&H`88*#Z z2Fw6l)M3jWNPi7%b1*1zg(|LCAmWPLeJ5u(#T91_aYZF(OP}kvJ9M3FkQ?&99xe*3t@T1)3@cRE z*La59ydQq|;k}Eut{%Q{#`oy|vG)~#Q610!4=YkyphemO<)Bz`hf*jPf)gMl!3vZR z!5s=k3c=mo-Q67m1PJZ~clQJW!IJ-cZnErq@7`HTY5(6}UmNc3?e6UC?Ck9B%(L75_V*J=(t|Pmrj{~=f*7(4|gwLJG1xD;Y~Y_ zZrwAX_lVoqZ$`d|ymI2q&iO0XjGnP=&a$yRhTOS+EAqvQt0&LyoWElA=;_<%E+5-t z=n7 z=+b}osHxX3UOBWgWW${0y@yR1J7?w49z*Akn|bWek??2XC-)tiHgR_Kh-rekEPX)L*4dmFDY-L7!KuQu$Em!2`KX2~&?BSIg(j=~VH* zoAT?0l3ThZiT7u=zyulHv!&^QMzADIoLmVG=jo^LMh}NU!|6O_0i{_ z5AptK{$V-9@%}}y|0*PkIM}~ojDPFU{lxSn9a%$ zul3~~b4vHM^T$oz71*RnmC2Kz_8PgstMkK=quisue&h4&B)(NyiJh2qJNTBfqm|`+EI5+NV11V(r$g6Akm_?rzSWa_ICbFolOacS@@?7F z1y@d9P|LTK6Bmu?Hgq}3x2w0F+aE+CZ(cop>ExaxZ!_=&-dR*ZLxu-Mirmhb^I)n}mzy=4U$oTq;>GE%iTkC0 z*^=t(MY-~y`{tXw*|Ocvlxc5*1T!1A+@3k>)x7z3B>!@L-NrpybXk@?cUbB)hts9I z)V%qOGL?5F`fO3YVv{R+?fCqQi@v@ud!0|=6f?(ONkKvI;(wD_$s8PVc=y45M|-Ed zcI(ES>$h*F3;H}svZO-?4H;ZDI8oO5^8y2I-%69Zar`O=b1iA{020$PUdD!{|4iWi zga6mwi-IO^?mvJ0`r*qndi0;Sy)R_t()5=+yQHX*zip;QWhMpnGW&YAtJJLS9|?U- zg>se5UM$})nF}V(HEP)WeWueWdCQgpbU zJ$nuvIX6 zju|s1^NwL|)Kbj^Y>8v}?V~p92T_WlhtE@p$r6X=pJ-mEkNKNK*S@`0v_s~aro3)n zuey}3Rn3F*k3WcsnSCW;nN9<~E!B1BFRus9aW6VF**MGtOi9&i83mXQaKEN@=)QNaGI zCGM?n@^HoFRSi>kUAf=o_|y6+F3)(__0LPY@??1Trd^R49^0c2f3_gy;S|wPFG_Wt zeE#zdv-0|<*i*;cbmgL*Q`wX+N?~^$o^Dm+|0^%N6d;kep>s= z>`(O~75PLxHY@Ljnw6(x&C0eRX5~wI_qMoM5%;)^xM)`LrlB}*y~w}n7Tr(smhLZE zY*vy`-uiu{Kh;AIjzcx)8?!Q&{Jo6saVbc5jo=;=zmaC;lqbbcBmb=S_g#yh1|4>O zi?tD&ZN3q@DOr{HUPi=8hHeq|WcjQkxvi7j-!`VwRxUVo~oH-o*#Cam9HCU^Z4Xns61FE^ZZD03df|@<|#oIv?8&zDoCd# z@ZcSPv1i-=wn*r`TXCE8uk_z2x z0gIH3kA(Bzdn(dHL0(E&*@()pv6rWJ9f+2QT@y$aiEQ)B;qy+YbVN} z2EJuhYe$fn@i+FK;_v0CoZ8zBmS=$ z;D|^(0R$lj)uyiV=U55@a;I2dDcQ4srC)(J_YdE9>I^OAC={($$fE^37ngqFbN=x4 zfDeVO9dpYKYZXmCd6`*qr%x%Vk}`k zLaaJ?^JV@3Q~d?-)f7_GQ@>tSm$OY5F+ROX>Q%CgSH!VEAGD%hf1PS-EUdpf#!FxT zT$<5%5q&FW1%W>#5%)LWh%PxanWfjP>sG(f(+)oS@V$l{<=AwHf{0iKZK)Ql8Q@C_ zsRy4h_*QjNgZuD3?);$U`ph5Ti7za_^jzANaQdBa5;Ki{JgK<_ILlVxR35KsFy_Hy zEV(f{**g_=Aws0^NavX!9=n{A;X$HeRUmqaS5_D``7Co6zOiQ~$_W}aA;|Dv6><5{ z0^|d2G4~<`_1PQwf-=UR|5xdS^@6uSziDS6ZO?=9f`hofSYC548q?R+w^~0lmcVLB ziO5Cp2;&syJV;{wgFHsw;renWm3KJ%tclSLFIlPSU16gAHJJ`B=zA%CH=^S z@4oaSXKuyl;2G2C1d<+e{{8pi|My}acf469H6dDKu7hu=>y#ES1O&(i*C-!%{2}M~ zma;~~F_2AdVzwMIa3 zrEfl7d!X;Z86EVGz(h(Zo+A(;&6WPK2M3rt_c+gg!n>VkJI7K>o}N;dP|FJ00<6h- zhDD?>=VnJ>pr)r9hI4IK=laxi(2m)E4<(HKp}B9MTTsWb;kUwjzcleU;wqv~uuEQ`voBb;WvMl)IuIXiRPn<3R)q?QkOkChkCXX+G1!+Ay{S@4##T&i8a zB2r~5sv8)vK7-!`TILJuRIF~TPrryVSbwYgjo*uYV^3~defP6yh@DSpUGrIVubinC zNiyF52GSVKPrsVdXM1W4Ziy@2&bNvadO zKu@J2;L!oex4=>cpN;VC|3*eF06cV{kQ2IjGFLFl&7pnxf@5 z?WqGtry)#=v$t8}EC%B2Au^IY5e2T6@u}sh0>~aMpQ`gAYA!g*I3_d4UJ^Vl^NQI0 zIb!?I)ekM5oR8ZkaFz9AhRI>!8M?iTcmk2zY(Lt1F%F>j6#7nm4{6i&<6TfiMt03% znQyTR$H_yCeVj7PVUaG-y+bPo`w7l4LjweP&JlfWW6UZ4B;LG^0;bx1H`>7G9I*<6 zj#ji(T>?_E3zdYn2_vVKgC4S`L?wa%h=SfChguHdoydoCHn@EN;{m#G@vy{WZ8PQo zoZ@GFmB^t`9YR~kC*qCrl&4&>y!I|@QAag`13jmB#Cvyo2YXd>i(a1h5YVbupf{k9 z`VnQS(tBv(^m#tf!Pz8)V6(3f(Q7q>g`9St}I3I3Ec z^`?@-ZYH$VxS^v1L6ulp-k>EBAjvIqigh95tL8fa7oWDuixt29 z(%SMkQ|}X7zbr5Ga_ED`7Cu(juiq76oXE2JR4(adk@&(QDfy=yc`k74Q5U#IYS=}c z7*l$y4|A7<;}Z)XGS);k7?zq0L7T=qfezF^Xqn_5x?I>IwZPwc>x{reA?b=fhh3KQ zsrv{v1Fht<2b1kqfTe##d&?6&Fz!0g>JckLV9XYBw&lYX3HidSd7MvVI*In;95q{0 zU|HatV$G?q6Td}y$MrH_u~B2r1YTwu*QL16aVsWtW7|F zYyFMLfxIFYuaZPc7or6Em$iv{=`QON`B(~TVKgBw10OYWfPu^hxub=F{t%-c(*jZekfHBpmpT*AD78@GQf6oNHIFZjm3mH}D&e zGFU*crbLSEM_We7V0E3^vI1|8n}If2>l*~G@~u;l%vg;ePL;Kfk+yze1GdK5wR*)k z#mppE6xx>XFVtjB`5YFx#Xa=#dO_P(BU)>7*rtY2OR&bOPV*sl+OW;Su2?>Hr6BWb zYtZ9hE1$rG)3q=JpK)4A((M$C1ta%6%;&JUiwANZYhA1ykSeSeV$H`pPWY)o53GH( zZR4_z^{9Uh4mb*$NMX0tVr0Dr2gNXxqjh35smqkNq(Lf3Pd1TH_>JXe zS{7DyjCG^Oh|cO22-_ksVi`K3&kN`|bpXAH2Cl@c5wcY7Xc-{j*!Qp1mhh(h5*Aj< zyqjanXn9kh>_M#nRm5tFcXg0M&|@I-IwTi*6@K|>Kk5)W4Rw72qV`h{A9PmZXbf5U zzhIrD9v|=)K%_U|D@Td8PH)1!31JG`3E(#{yydb1jeW*N_~2=w=wmh^W}tReU5&LJs#O(bu*xWY=_ocP}HT)A+YhbP?A^Op43usn)XgoQHpy@ zl*6aGtgT!!kKlCUoXE#MqOM}WcyL)`*ud4z(*GtJRqQDSSqUDMZ@O5*tg~dEi{1( zK6$+fy@B+igr^|(g3yP=twtlb*$I}GXVrLM*9blZ<%O>m@7Z|#V!UA{!|GD&7m9c2 zWvm~8Ipzbr0qyXKU(%0T?L~-^&m)W z)1`)}E+gp3lyFoMcODDtxtJN@n}e3Iw`3g}rP6{X^NV`GHDY&bs|@fH>mcW95o;r? zom{C2G6ky|xqiZT;MkG++IlUdrlR3F@RXDzrTU(QbFt^ZGmpPJ{CLcmV{hl2irjMU z@rkSVuim_S`_A1vckW!cetX%`yZ)>1<(qnM=&_johogIjzWaU8n^rrb8gF`8d(HEz z%buARJ}ExyQQm0}vQN6-|M2^kJEGhcJSjH&QNC#p)}4KF`SRr}SFX@W?`zktUB7<) z#*G^{Z{DPH-~)Hwy?5^(ohQG0_b#2{zIE%?vSrI2J$m%`@#CjYpFVi-fX;-|VejS3 zm#=Q!I~4`hKIgaacqoQ$HKnqQy^vk>%Jp1c2D=YDV}@H%(ML5uD`!p z>2isZk1oHyv$I~mey20{>*rByV*b=sznPf(%!R}chA%kRqRW=;(Y{H_|9Lv~{(rWzL3`V@{bop&6e}La>(PCBi3N#PWeJ&G zw@d3giItW&D=n^2{ceE(<>|S?%Yz!ed-#QUzp{X{Soho0EamfCu8=%g0I%>>NS14_wdCf4Y_O7Vz-&QYp=P~ zdGt#6g=_mP*wk#q^0IR`_%P&yH$C zc6kimRd?{nsYiS#9QkczXzc+T-9PYW$9-4Zhg@m1>vF)V(>_Dy4O(Az$X>60!Bu;$ zDaB0Nj#7g!H`{dHYvA18n;H(-Rjv1qO5L}V?Ygqq2Y&Wnak}Zo^L3^lsx^4}{EaO} z&i0wNvBju4wV25pFFVy~&N0u?dw*Mc>eu7I+(CfxCz6;^xP{#G-O7oBpeS>7s9P7RRDB1Vy~Z@GBM%^!lJRnOPv z``<<>nRW)v8ntTBqDh<;J)X>`)mgN_|Mdf>>R{GquI z=gE~XezI}nCXBD+v+uKcb!vs3K3%BL=`+QP6f3%MU7yqG&YbPDymiZ`_a61>nn@X0 zztG7^V|ujv#G}cXaa2f-qajD5#~pjU{7l5bOAoHxynE*^g!A5WcRFvrS76$`K}Vwd z9*XX^?`_-Q*Z!L!mMbrPR(k&9f-@fGn0&wQq4!nj=e)-`C*NOt=J5xCEJbnf-7!nt zSDkGedSb=Rn^zYuo_qe{DVD}0Z%IUtTTyY<#ZF7Y+KgZ9F?4Rpk?Sk)Fd->T!=d<) zV@<|(8@|zJ;(=es9H={R%`YUd`?{cR6I=zLllXtF|EF|rK(>|qs zNu-pC__pAIa~^)5m`ABPXXL%I@ze1sEedEIq2^5@HZ2oqW$}R}nfqvQL4yASuPs@! zgxQJ~8pJ`}F;>7Ytx8_M>J+oY1_K;^>;RSt2|e3oOw*u!qA`_BC%y^J`6N1~OTB}h zw@3f7^R-uV2`_>C3LMfFVi)j{8( z*AkSQwr}vLG>_(N_X~Ghn8YnKO>d6{Kb8Gs+<+!;I^|2bsbIS7k&)R`rrumQbZpsD zOENxr9(gf*!@~yel_guhNHur!^E5VCqF~+v1@jgv>{Fm{N&3GCg>ETUvOs}yr%O-K z6mb2bC@18WvfTxK@LCnYGRckrqxGX&hS6G5ExL#wh%3}ALCnBh@qr~q9enN*SFCuS zE!rurn9m}l;j#T`EsMutMRR?(Y*3;>>&nd^?Dy(@rbEf|lqz&6rpM5q6ZWiluy2L6 zXP$KW@o{A0TE_>(e70^%@0v%HrQfC*cVhoo3XoP{f;qU{+TE+Jd{aM7o+860Pk7vJ zi}$Yb?u+l1?3prInygc{cNul5Oof7@vbyYG;R3 zm!C9_%v|a1uI6b|UtgPS@PeIJZjVUOBi_u`Dc2o{OtVJQ_y2eAx*{_C_xvBAz;TMN z@fF26c~pvG$$YDg!Ly0d;wNxZs+Bh@Tf!XQXO@Fv?)*sk;-4@p5fnc}#NVmclFByH z-e=bQN3(J?p_?*csae@E+^mF*HY=G5$v88(&+G?ZiuG~CtoYX4ORbZjAli)Yo`|;!Hgq5ZkGSB6` zZTfgRX)}JBI5R%f#%D*(AL6luT{bH}uhzy<*+hAkddfWCQ=Fuq)>0f9>O1jdD7a90 zO8qI~y40t*O$T3V;RI2hs$*oH2P3HODDKh^Hzb@}lqXRMnWy#VZp!k^+B}sCEmYc< zlzBGaB_1K3QNvkAc?KVrc{iMN_Mwu(m&#bn3+JcPvtwv>y+NzIt;>^u$Y8-8q z7j@y&UVi(xwK*;;>e0qj0^J11WU-v-$RaY*C&s;6mux>b7sOc;oNic+ExozL z`XSCZa0+rjGL^RUou8!ye(TRRaGh+0hb;qMb$k*>g{bbUz(L}xzn4Ou%TO1^c{=uK zk(Oup%A)V|=e^YBwEh+XV{RY(XGDv6Ov1(vh{m2r+R|K$t?~i~Yiv11-pPmCq{>?S zT}-ise5iNf4}&xOIC*2DfAx8gRogc9B@tsr_(q`L(4TC*!2E%eUV^jKXCu(+j^wdo z{OIqKGQx=S_|B0Lwdrx&jsRmh%d}6(ZykpA( zWU^SV8|Dj~S;B2yIM>7;M&R}en*2t2%F@XvS+C%+%G6UHRGR&maZ5{SRB3tK2p>=C zFWjI6PbLq7AX44wO*KmOqI7t$!oR6D{ds)Ip->Jl!Vu*_U4gBD0N*?<3?Iwctnw-d z@bQC(x4Tl6>Zq*zO3>8hE75OGt3}v|6mA=Py?fJJ=D+fyS+V0wrla*97Vi6yg*^2b z3aograH-GaG$O8pe-KNv0IC729{3e%AJ<^u^Z`!i>!IL0x; zwp=3`0OPp9g(nrPvY4l=ANw$Q#T*z*S#cL3Z0Lxd9jr9-Kw_>Kn`dK_; zodz!^thuaV;zSc9iC7<7=g@k&GUOj)=Uv1Zt!-H&;2u=0%p`6(Re3lbsr*;qhuK?w zhPo8ZqVT7J*OzGZFUrpZNj^N|n=GpmoG%j(*3Rh7ik9=rIPs3Pi`tV&PjA%4r-gG; z%tpEIfF`7ig(mXkvRLKG`b53J$NCOGtiqcS4BT!hPH>76)_CNj8nGWiKl+mg8P+NC z%(=<(UVCPosUY#=JptE>^*!i^UTq%R3v#c;IpLFren%dEOAElos9U|eYfirzCi4ZK z+TgnN5V3}V-?=;?51%Np--PchLq_BceG6q7z*cjF#DHny%+6EN+0i%l-Qpb+T90vp zl_C7fWYkURk11BRMo|hpsr}mVYVEUJgEV-6#(N#cu9Ss8FgDR^@UUjR3(n7URet%< z1TVsgxiY7P$`~KW4WDqF-4c&FpX6|D9&jZ5Gqvdq!IQ=W*6)xQ@X{0>`_M!1SusAX zB2#d#m`?{cx8x8$kMP1~k9D;Sscab;Y95tR+jc(G2Fi&ZV7?XOSF|0UTKLxGL|&YF z#GbvWWi2SrDp#U90G)S19Y35%*4{NNF%fz{!1einAN(|VU6xm~L*jGtq7|}M#>$!U zkhktMV_{zhk5*tSJWI9v8_`nv={kJ5QZfd~H8qB!SzZMTP8!N2~SoSK!JOUfkeft|(9cK~n%9X-GXt5MIUbjzbUG8GQ9{ z)wh1Lx3cxV-F3K~h@wJAY71AfCyLwHL)(3*7crjDkG96Iw%=VHf3CuJg=^!2zq5Sn zD&7*VeZF-JSI=M0@vZA{o#R_q;X3A9%&V^32Guhqk6OUt-4Nz&P^l?#v8-QR!qc+W zfDRn`E9^Khc)JGm7scsgt4j4hwpseM4d~Uhi4LShwVI-Xr1Ci zm>a`GTRfTMCY$*ICl9Wuhh{obh(o*K&55; zQ~Z+Az8PD4_&BOV;#b46?uVYpoodKQ|7pjGw`EV`3=JSDFLm7eOmoUv2sdMO*k!I!ZK0|SZZV|py-2tcN^7`h-qfjCaDR7H5pv@Z+ncj zUt+#TL=T+Qg!~e_2C-&=4pOhV((1xmQ4U@WFh>Zjm7aEbO%+z^(3e0bBXnVod?eI# zwVn+)RsEjjxAlAVjG)f1mHVOYXoEI`)-3Qz^!ly-G2iu@FANQ@}e7wRm&WADm z2lXHC8nL2fPa09HH}NOO#DNs!lhu&@s9UUHy(kZ6fAs@gS(h!=1nhOfYe#JzC}&)c zH;oWbTduLS@?X?o3ww@5$aSi5W=sV=^}MU6fm{#UhM^xDdKl`GCW;`(Yw%h`Me8*^ zuoJj-ie1-f$E6;+b{}7vD26uuL48n`dI@pGS`rOWFSPvX2lb#|nG2vVLC!{&{UG*G z`kqqjJ8aiu#1Y&kqq;Ds+Tsg!efHYI?GStIMi$MF{g!BHriE>dzis%ov9DxlS38Hj z0N9uZ5F^YP%x%HdV{HqrZH(3XD>p+4CU^(19m!p5?$N?GlI421>O79%S?}fqw#<9h z_^M|FYv>--BbdWsv6Q<>hN;EVJ{;tAJRexskD9ownhNSU#JY^SE;Uy6OL0A}q{?e1uaDOg)A&4BpS4emQ zVdSXuSxZ%gv;-Jifay)SF&k+2xB{kqnI~(M{tLG0SdQw@uU&1m32hTN=-0ELkTY#G zuFr!?!!iI5JNbyZ?6=n#6X4Uvq6x7*@{DnDr;)|}Hv$uZhjC4?DRF+IK9y^7+f)_s zC9gTAq#CX<^<-b!r=Pl3$5d0-tEW^l%ScqivrikNafe-ET*ff^is9+?C;}d0e$|?AB4c zxHo{QAkPIzd8fruwn^=~C+OkqC*~V*hKb=rcI6~&5WgHg7SKn4+ZapeMvxBaF15Kh z*C;gUY-7QV8ko;u^Mtn_{5WyT2%=#_njzXByo0)uk9ba{KBeR(J!nIVmmrs8S!Yzj zr14g?-_lRpKJ_4qyTUmfw`IA8_ZI^SUt)RrGZ7-s)iAdAZmSVq0jm!MI z+o|s#;a{k3sk416%DUF#Pus81YY8nF+b6iCw%TZ&-?i3#YQAMV0&Dr;ou%$aYZ;`^ z?MmCwZ$egzSpYKBdX8fMU(SoYvs!ZUs)utx&I(xz`3jv2-=J-s4zC9LvjamG9`Sr1 zb_Xl@E+G36S73d}e$?7_0T=dxhu=QO@q{i~tLN5BYs{efxmdl*;5v9U0^LUii!Vlv z*z*MNLD#R5u;KzgLeB!cvGc$j*N(mkyA%Hs^Rk?$xi%vRu3&(*HRg86MmaCC-y-^o z*GxHyGROxk;0Z0PU|OnT9nNPWw7GfC2A`BxU{BWPk~9=>`35rRwOFr*`@68yM}19I zZ^g+2=commrqfcJVagU1D^Cxtcdhhb0`01qEjO$tRH*OJ1iNrL%02a>5$E+!r$xA)AaPAIfV- zw3;5;6h4z7vm} ztLGh-Lwa2dzZIOMl~pV||Jq7Mt3T38V==QiT3dYVHHH0|@4r+>6tH~XVmhY~=UyM1@a5Ep0uvDdjqyz{9S!z!fU_P%mNJ ziW9wY<(TZG_s~M(KG44fe9;=&OA6@+wA|vDe?Vhv%&ps=j8-1FQN)Y(QP??FB%K00 z9z{e1>_vpWN`1!*-9$r4nSwazPR!A{CnIY9Wk`q`Qy5+_JQ$U*cRN4wzD zP<##y_aZkXnwc#3Rf>3rYFe^K6f_nL=bz`Xj!I_P9e?SY7x4>hk)Vv2|Ij`;L-L(G zah*r9)3}p0$UZTyP1_W8Nh93Uxn1Wgj1*^EZr$VRx~;!wHEZAH)cr1^{cRrk;kPq! z+iS+gZNGM~=fU||-@Kag`sIYEm!n@r4!gXs#>*G|FYWWVcR3*PMbFnS$KJc-`}}#A zSCND7Uivj6qW$fQKH(89Bc6A>b+OuokTT&B&2L_)cxqkc!^^(E8n5k5!rJjgJiZ)D zefY78Uj>(~PM*VMoL0c^>25xc%_@vz%Yu+nBF%o0}=m^iAB@ z;|sUE&3?Twrqj6K-Gi^(&Yb+2-;2~9tNb>k&XdINi%yBtckXP8xPI~5m~GwSosLYn zFvpkmvlBL-{Nfy2^iP<8uz7s>h8KN&A4`8CK6QbG{$q*4m-kgCniFk_s)?(f#x+ik ziP;>)OcLhr8x*gCTjnJ0=gy_vow_|e2@96nlQ7ZOZpp*T`un@NCHm~M!4+mr8>%Ge zdn@F4Ik$o)_nNCREE&Bz!IIJK7c`^Ch4%^aF=@Q4v3Dx`GpaOd#kuQR_) zmMmFt!+6THv|ncl8}@FF4XSEyA}CmxZz4D__6zNeE3V%}K=u8Lo*so4D(@DXm8_}F zid$)ItZ|^3lG1NiGb?>gnU#SxIo^00H?vZ^qghF_#H?(fvd5;FmG+g*$}bd?y!(5~ zcf&f~_+YbH`698KvZ$$989{NU^HLn^Z&T8z2gl()zu&C19!&K&lJUmt_;4KV6BOHe z=I3ro{R&j?L$gwIf>|j`G0hKEH(TP3pZ~_JlnOK}=3mUp(t&2hpWrVqC^v z^lzMrF~XP22*}2Hj85O2-%C{6Kk7P#HXXfWeU^rI^!bQ0Al1}83K)p3r%i#*ojq@~?`=aD zZP&xrzn739-(-wJKvuU$z!7+Ws{=k@Zp=|A53I3c$9K-9w}c4DTKNu4q#Z=|rFCvT z=`Z6EaxKpJlW;5eEGB;!b@DHcmI%3_j!Yn83$XRkmHM<4Y5t*w+S<4$*wO<|5mrxE zYO z_MlyLx5SmRzQ4c-7vRM8IEy{bn8LQtwi{SA#1og8PuWPe=pUmtf(}NJFSPQTIoke- zJ)=279nD3L4Pt2`h7q*RMrGw%6eV3>XX9>khOUlq3W+N{;Xx(T4viyd_N8(J>TN%WQYU{>W51zeXt zx5UEwECbgnd}OUXwiu%H$C5KRr-%}=4(Xp|+)lnh0bZdTDa6{FG$*wd^ATVQ&rTz5 z79NM*ln=9}H6%dL#|dg|nGN{#2iC$k@qv|tA3R;Z;tS1lo^8qhclF|@pr3YjW$9@wZ`5f# z_u>ub)z0^vQ}_YJJ>IF%Ct0tCxdv@NGbYySpTD;9EE)boA^MfH zU8Q>9mP(et3I|%^dWhIN@BMv)6HN%qR=vWV8q>PIYR`<4Tf0wmFF5%3l&^~x>@{QhCXESle2xVDG)bH^WQ?>*xTd%eU;ux z+ZPP~`rDMguMg)Q*=zp~Nl$0owmoO|>-%b!2FZ zH-6FE?k8UQI#Y@@Evp^A8dlo3XiTqH`x87~vSr7b_;c<&JT$P*lf6o!H?v!`nR$N4 zn{FBQOv$xq%EN`#XPz(9F@AzQQ&O**GBk19{aMfEOC3<6N1yaW>bRq&nNYn$T?4)S_3m)+|b1HlD*>hvd4RPTKb!*Y;0a z`z5_TRXc5KBpDZJ&v%A;j=Te~-o{x2#C~)P&j>firJz&fI^{eY`~)K(Ro$%O74dpY>O zyVI(XZOhfEKHQU6i{8rHhfO+QY(3=rk^uuceEo@UYg^7=tyS2Ee5ki^S_b$dZW`jg zHM8K4U6_&d)>^Z;G0>`mZ%t%X;X9l841kF!z?Oe)qxs(DYSdcX%q%RQuweW(TA~(D zODmv-?qI2u=_@Uk{?sa15qMv$wNQNAdCr<|fKXiLIz2SUyo~YS%x;qXHLQ2}f>Qh` z^b!`L#{Q$#Ux@tDCL!KvA;8w)NaLg}X=GL595Mw^wWYBC#W`GX0@o>j^9kOLAFNHn ze?nbGv>0WLb!W_5*1BB8f>y781ZJGyIUfkf9YoEOID=~HU*cS|d?&fuHYHra!MN3e z8e-hqieVyfV1AGzkf91FZvEhtAEU-Ao3Av)@dA*I6 zxfj|Q#B$&`{d^lIJVqda)tF1WEM_A9Pu;7iondiY0rVlaM%EzW!>D12+9l?~Uk2wQ zaUxAnHJMe5xCQD_+$gqAS4NOE6ftTTf2IYZ53o&J&-Y?PyI!Ygp|(EpR$HTZD{E6z zUyG^Wzfbuods+6Rx_;aGP%%ro6DJz4XSA9_g;peiAN=TpiS8)9M3lYZss|6GS0gF?ev@JMxPuzt?BncYcllNka6_U z3^Q+iJLc5rDJ}M|sc?Mf&);@mk><~JX$R~cIkDB=6;+OGEi-40PnvEk4{j(sb48ur z%XUv+_Uo8^nW6b~eDr4)pQCDh^vsvLJyRw;e(}dPdoN$U+;HgD=P{Y$Upj97`ep0t zO^R0yz1mo*ogv%FmD}cctngftFy86!mXA1*&%M4vRY;GX+O5KT@N)BFKb8lq%ZQ-RiKK0o3yvV9YxfkCj4)}K3 z%~TVwCmVA$rQgUzBQ7_cx$Sj}jj5gLutwZrfyb(TNeAD`*UVWaUc8#;VrsA7yKU0B z7uAn0s`a4wlwn;b{BXo~`m0;nntmHURqM9Bd;59Z>pv{*qeOWtrO6xmMbbyN&G8p^ z&N}Mi;DiT@jxs+^Q1I}v`_E&xZizQ@N1{!O3gvqGPtcp{{Qv%GRcxVBBEYOXtVw5< zVzheSccc$(L1{N!(EEPoW~}#pI9sdtEwn(Z_Z?f$tc22TGwBAia-4LydcAM{!}j&Q z2kBhd9+z2W> zH@i|DztgAVI0n{wUZYz6EgIgxzkNp9Q|={e9jq~>9BFf%gQLa69uFC7SnX^4T!*LS zRQu%}YigY-uddO4ep}kpzd{3BFx6N|y{R!L=wV>b^D%J(JniFH|5}bTukN&huS~n) z>NHDuDfI{^{lmK|_&t{=&7~)KQ49Zit(L%9{i`#zGAvtq*K)D@QnmE7*0{Q+KXnEx zoTspu- z)OCv75+=?eAqutHcaCv4@-SyU((8>_KO$gDT5xVxG^OBKHUFX|LieGLP$}w??a-HW zrEb<`#x=^b#3imeQUSqP{iw(f4QSW8aj(Inm*aiSP+j&(!j3}mieD`c$~ zGA^an2nktZlvm(~PiOQ%4Py7#3)rrX3C+do^aq)~sO%-VPnJruou6Lyk`h3CVRUB-hP#zb_Aqn%8|nzDv=Y zj=rCK=-uehH-kf72c3B{_xRAz^ZvK4?A>%JWZgNxE60a~UU-5_>y%%`)T2T4Vd1W`es5f9))j7L5uK9i8!J^l9|9E9($63cB zN3@@1YBlw{gU=@JdiDF}$j0lR*Ipgru{^x&n(*p-UUb^^yiIUKi#-u-cRp-CeM7sx ztBdV_IyCfUP)KB#T`$`1eBNwZgx}_f`WwS*Z+zyn@qVLTD}RjY-nJ9^-vQ(Ej|v@l&Tv{Z-mjX}+E~YTTF!qthfzR^ZTq zLx*zb%=P2aMN1a93`$sJ{kq>fMZWkV`S4-Yg5xh}awqMC+GmSx==}0a-*^>sG)-5h zc$XA4^0&>jDrn`*US?m>xPfNxmhT0&#K>bcUZ3 z+2iM{F*`3uZ@n13;r#nmVeb~5c{?xo_TXO23otV;4QtnRNsi77O-(1IoORHz)r>U6 z3Fl%~pN?L5JbLDlcN2-jEj-qB$E&tGU$)!#bP(|XarlYoImG09UiX+DIA+TaXSR(U zyCY{rid+d&Ezw>!>;=SOpQ}-9Suye!=V!ZCAbl06?ycvS=f|X$&hf@ZJ zB)PM8)tc2E+jVIF{8>c!+Mt996ZY>nyGproZt)NMHLEgd?}>2*=H?!)> zr_WcuzMf5*)UH{}+uJ+L^VI2+O+I^YqVd@?r-~OSQm9zLqJ1(zErx@_HBRm$YzdzuxFL%c)i_rWzIai@xhc~pPMgd4&H4}s3^g+ zziKw^NO82~Q!^Y@`QM``n~E<~ex$fUnHy3(p0irr9OzSt(pQf%D+^aR@0Xc7 z$;62>=~W=;QJyp!0kJR2k$tamSePe_1wa#j`dNVDtW2ZL+O2!v^kA+ zPwG4ZKWFym)nfPOC-!$ey8Wk^n6oi4r=z1!Mn@lyjz04K{lWL|_rH4=(xgePn3z*d zns`S?9}Ntw`Tl)qU|@}R?{)&Lc=c+^%a;@U{7Obf4uAc6 z+3VK}qoU@%dNuRatEn$vPJH=tY-Hq!7cYjqcroDl^FC2gv;6&kdHHhE%a`LKBS%I? z4t?=r;ENZ1pFa<3+_+Fg#2+tTj*pBS6&X3~#fw2NUi5qZy!Z3xe?~-fjfm(R9^NrL zyzPq@gZ=!9MnrUL+_-?RZ{BCmTKoFue)g={^XI)HBD#l%cM1=0A0FQ3*|V0lgCe=JbMEB`hH15zxj6Rq$!iJ zt#?n@s@3C188b}Brrs3)$@epUyYkD9p0uM+*?ZQtQO8$38x*?e-Zz8Ht)|sC_bA)R z&#ObSa;Bnr3zYt$aPFUT6d##%X`>|Zlt1o&dv=+3R)j10gnNA__*Qvs&9|p4OiO$i zN*qf}7!z}5?&NaBvG3pSB`zhdYtqCgI{H|XCd9z|0|TqSd$%JXpvs#!Yl&4XtWMm! z%fhI{y2Oyni1CQ20t2gA_?ftL6|<0Scvq!J&I*~Mw;&t=UjR$w0T)&^FzDSebZ z`$HAw#g!DZE*<^6^QUDjs_p;!lklg7O7h>#ihq9ciSp9wj>eHbWjdXoJwC*Fy;0Ki z#(Ja4ep5a5{BfXVWKVIzXj_jBI82T1{4ga(b3H14U+a>in`o6H%Cs|X+b)AwPhPHmOkJRV- zEBYnpU};-#8xQ-sCO~miR@7uWpDkUHb9yK1_S%9cFyT+<@o`@N9I zX-O)GZ;tg^BB!7nv_Ir% zz6WEX-p9o3kBR#8?Zd#Er>cZ*Dzauy!Id-12Cu4r{=kZ|n-@4m;+nA}_6S+@8z3As(hp1b^@NBY30 zOvhJIQE%S7jd~UJE;{<)gS%mVeuV$=I`u+ALifFYIdHJ((e{9E^72W$F7wr>5R zS+nPUe$Q&vdRm>{S1K`V#-ttFo;PkBUcde`AD^eysz0e%vDnI4bAz{E2n>AYO>e3_ zsZe1_p28z{?>I{Zy}h4$cswaz{?RXG9+oIkt?#%kf>_d9~LkEpkTrK zxpVhz)#F*snop`!dF)LxpLpjmhG;|^th~hNQEks%T>Lb$+Yry*_lqUg*ab% zgw9v`CQo#&SH>NEw;pQu>iU;^9>32tAYT1KUv)b%uhE6?_eH0!SZ><)gYI^H6R)pV zx6E_tT;+p)t>QoWa^aybj-}i7OH`^P15(z`)~8vX5edgEF7nH$RHKjFu9ERv9 zo7dNFTV#Ev(=ECje;k>)`Hy`wSGakg(}LEA)74#Z_FStjOG3|O8d2hUkIg;315y>g zbUs0i#{(*ly49u5opklSPZ?Uh_PHS2Tvj-5ff7Ci3zaNbykvo&_(rxR&VA>Y47`+m2!#Q zlwIV{g!|td#lf@H{xjqYm29|-gZH$FR&O@siCK9**S6m5J^5l8`CBFF%=g^ICx5Yt z!_3P1XRfs$TwdVkg-Ww4X2s`!*xzavwecM36q`IXD|vd+-%nNDiIK|+u@scv7$$+QB8kEKc$8GZ_u{=HGP|{ z_GqKage;g%F<}y(a8l_q5z>IP!geU9z0a56?)EKL^TC5ikaoymv#S!lW zHk{5atWJ<~#wPH4=(*tcQ;RT$uFKOxDcqz~&JrgN@8pA%i{4a2S<+G=#kiHW^<&1Z zMSHbT>150x#QSMQXUbbsKXxSCJCWSPD1f&Ydkk@oHkLfN6;Iul>a^0dABT?_=af1P zEkuz^)*)MO`$P8FeL;e(91rL zqqo(R5fQ#@w@II(E)8EBp&e4|A2~J;@asU-#@Orh;TEL|^cz$a`o#*=vxqhh4=%(w z6p!{MEqP(?tJS-&82HZ2YM|%Lu(9T8UU~;0N{XOdLh8EzuZp zBaxF^0ev-Ypej$J7h^jo<@lYrk9!LJgu8^aF#xrc2QE!4TqpYdM+^KMv0TNHC7+VZ zau1PXse&7jfZyMXhe>ImWF_jWc?dO2`O?J_^}Y>J3-shWp_pd&#}ig@oKJsGql}`5 zD1)u2jT{${c~fwiR_Yi-5`8N<7~BG_B16P?(Ho_yjp}m1I)>R^ z;M`6{DKV0<9*6vJg+e^)5J8)7qs3ShbzoGA)}cPeLzF-*Y8k4Q1OF@Ewez6l2aI(5 z5-T$CJC{WUXgL>Y?j)@MOHd5bg>#AfV%aK}gWl$#G#`rbi`cciBB^C5S)RCsVN|fl zKK_neh>OcNudwedd`J;_ntf0Co@-#?+EblI7RDDwHem7WhrJ}mX{!&wkdAc;6(Ze#zFY@A(IathRTG^tvUxHh`hz7i7<+}?}LP#3{SN{&b#fU*3Z7p01@AUJa zfagUuRn$D4j{Fx7Bve<&gn_irF^Iba&_mN zMcB5DO$$wJSrdNR`W#wonnHXcc>sGbtWOcspyP*L!-@s-Ebdgq%00j`;?=EC*DENa ztru%vSx>-+6|!^oq^z;_q+btBIUDofXw2;)*Ea8txw{+$w^4|{t5 zSmh~0(wn}?k#kS}M#)OotFd}vK+geHMl|kUrSb;1`FA$C?;YPM=AF&CG`oSG4HcvQ^Z zJ~7+7#B3yz1|~?^(kYVG62`gUgk`IkXC(>9nLa`9RHJ6!h@Y^!c|ePtDHF!~wncOE zsDuHFCMIyBgcI=+Rx=N{<6)YVFreA;_koTntyZt^k(2cCWSg*cj=J&J#(MqpbRN4@pjq)s;->sD&8&pexo}tg zVXsj;1G<_Ox1;~N{;;miM|>Jk&6X%{bpM=nPKDM3SXIU?ZlRcu{|%bojsAdv7p3P=fw0CEyMM%x1eMj$fG7CT$I=Eji|t0X z18JZJtUA>VN?X^1USW)wj;Iy;T4*FBT%c-QR?XdFXKG9#a0?*w`E0Fy0XVZ|8TSHo zB2MWPD^*}45E`jGgcT_3q0)VFKI}wVQ;z_SfQ&s)Ym)5p9p`OLdm^^Fu+};s?PH*6 zlrZGjU3n0#Gr{bEpf3@yQXaHK#e*!B|j%njh*lDRG?zWL-)HF20im9sCNDJ$a zv?GZgA=`C`YJb>7mHH!hU1-6yhc zKo&Jx=NJ8=u0L*+LyxL8jD9p)1z)o5Rl?PdZY_1NGG{BVR*qt&)PyMbJEeAt1*Mgb z(5}E@49&Zr1&ZQ4Vk|)ZK)p_fJwlMNHa4p^l&XW1D zJ7`0x&~V~=E6c2+#u>9s6Z+5EQVwk?+7?J@a{TEfl4vuxSd2Apy|Blq>l69y!L+81 zppAepD5b5zx}3dQm}cl*Sh=8a1Pw(ElCqG-u<*%#<}|Ih1E)LYTFGA@`TF4~S-Hys*UC@L+VGkGcmuPVfOS+?6Yy-e8_wav&Zp9WnZ%RefAKN*g zpMgASMKee@yRhJIiCF3eUPETt|PP@ zdOsFk)rwSMv%~t7Et2Y$n4q~AwFWyT#7gUI!M`cB05hPGZH8+Qysm~}TOTHKgNF8e zR*j%Dec8Jed&?QR9UW-& zccnZ5v7Rg}qhu6o>>Kz#Jt4hh8gLA>nomW3wh4*RhWgP<(2aqr?WlFU8Uz%KEwRcI z`xE9L{roTb(A7`WuitsWHi-GOEA0^By8w?LxvoIV_4^CR81~x`G7~dwE6c7*y%O12TOc^4+@lYD2dZO*oXJuNUoK=lq5o^ZA``aLFEgI%WM*63?>u1#pK z@p@G79L56YkZT@$UOTcJ>s4i$J z+bsG)&KjJ?@8Rdlen9*ib5UoK#cJOmaG4xI0cJAGlfq1wqzvmWk ziogZ)Jyz1#(fJw`kE~`}XZUyLH*PV&ScGM{k`wzG20Zp53~J9o`f5;A+%^>#rW% zc=g~`*x>^`yLEf@;LfWD_cp9p@#?{Yo98aPdhqDxxr?tJJlU{f_1VM6|LoSIeuD*3q4g^yXZuI{h(`wkhl(;G%`1X_47a~@jqtmjr63t(QOXeKAo{Wc|#5bqPAG!b4t^%nC zT+e#Bb>3RF%0GU)BW?LnZ+B*|>@ni$)#r3_Imv;>WedEiaq5dxYchV(XU3s)L$ZZ= z?;Fr=^Npps{i@VSFsDzphM(68-q5LZpNb=LUmA41>Z#{_3k<1$@bSD;k0TTBIT3aD zK&N7j^3-{Fr1Qp!*Jt%8HNF3-&!f6k?Hc;z+Wx{fd+!K-n&NivnxD;0{%5=zrnJSD zu8&wmP587vE6(uCz*v6SyLWG|UcH76>~nnYw&Qzu3?10t!XUSf?F}KmIJS5H&Ye4l z4je>W@MqtCZ98^q)3H<6-u;LpHg4QFZ2Uy(^W*oP9lV3y?$9Hsb?eqsr%nwD3R)Ku zI%V~?`t|D{zWH#+weZ$mdUWd6z4xezvuDqyj_ugB`^>EeXRO+|=}N@vut%*2U+w2q zKM&%5t~TO)+CBx6Cps1SWwL`=YK@LRWYfEtSEGw1+1|EtlcQfKNy^2m9dfjN>F#|; zWa^hB{opn!_cj|nINiRtAz4y1?_BD3`g-HeY@RSN_m#A3HlMoGqKv=S@9Q5Weq82W zL>^zC{6k*m*s?8s^xh(W2E@Go@wawgk8V+M>y-@l6XS33{hgm5ZrS-)@D?KTF5uL9+PiKt>*5q@xY23&!rlVO& zv&5`ypt}H$(LDlP=zOXpf1FXT*dJ%aMYEDOjag|IE&Xw()G;f!3Ye9j(@TGxI#lPl z3})p7!JhfKo8su4@o_(jZ#T%SjG-8FkEu=0K3+6~IlDI(yH7Q2l(*iOTj%to8Orv) z+&Vw%_$&S(0^r^!9Y4t|wtc?i6Lf;VK{5-KpvhqG zg&c%Q4htSag9m(J&w!?%eGyDb5Bd-L*qro-6G7NlAQHStu|Cn(iCU`PnE`SR9Rz5j z7`o9Z6NbW?6BF%>y(zcYDGLt@sn>w~7kU=kx#j5;v|HaE_5+eQ=}+o$9lT=^^s(PA zoN&|Dg8YKo#=0laACe0@IQDzT8@-;$w&e|U6Ph744NF^k7BoWtLi^N&YH$TEq$%sP z)YR6(#SGb$tRxIst()X}#i#=;Tj#nRbNAnu!({On0w;i9edrI`7;%0HC*}AJECuSm z#COmYV_SOh*zal1?;l%ItC`_6*Qw>)xOb;k=&=`a$yw|Zs?HVccG>Ur^S^fYVLQ2 zJ~@adt@~T+38m%+W4R>wTCH(p7}~b+ySTPZJI_K(Cr*(IZ8b2po^x=EQ5(u@-73Ja zPQl#6v$u5#W9R}8K?mTW#!tMLkfB-A`k@)+7kB{w0Q%$cXWR!U53J##fbX13KNkoX z>YhSw*j!nD8{r{y!}p14#ayq<1K~24;UklGx%ft==>pz^#!lS1$um3xeM8=#2&XW)H0Iup0 z^t%PXu&qmwxdpDyoU~;7c}H4R;dBRhgCBk`b~OCXh}4Y87omr(sq^V5xGA9 z8h`PWDbv28mx()7u2w$r#e}I+B}kE?XB~ff6?=(u`6Cy<+-*u8)Y!Lajj7(N2iMG> z@#3~ZLl=Bk;oAGF2iAl>x*XF#?Y;%q%eH$tGiUXadGgQs_Qu{0>#vNf)oe!8m9tw{ zWjnd}RpL~pslR@o;Mt|(bIwGKowKZFf^U>&*-O+qop!X+V`lz3FIw;V^7}T!%T_I| zR4R}##hE!{23`1WRKjC*F3yf`elf79|I->_r#fDky)?m}rKUt*xwotMm_m0d+|6+G zd7?kNeRr~YtAq~;V^wU)|M=iPK0u67m-*lpPygn7tU;rF z_g-ANa-~g&j-j{1Pfwm1eEa#LMT;iPnNN14?>(1qA!|~H4qK0%4Za?}?)tM$n>MYy z`gG~#r?da?Nlim0&T=AAmJDx~jUou^V=aaw!oJ*HAi3iG^2*%gYcGx4o+W3cL`hdo zdL0w9%PrB9$JIA{ojG~!&}2i)jBb`^Mx_eTna3Xu==gf~v7y;sc9`GdPxs|*F16{m zWA^!j<1eN>UU2@!rRH8iBRUQIp+MtOllz39Z_xb6jt0xq%ql#y`MT1#R-NzmbGuu= z&COo+dZu$DO$`GZRBc~!ZKL39@3VB9l{zf_+l&KlT^uqu$BeLJZ-0nLmF8)}nSB$D zeEx-(+r8k*WkR2Q_GP^9r?oE9Wwcgo;Mado94V0DmxT&q&YnAIR;Far+MoteT85^^ zacRWLiWKdIx~b|M?uxN>Ht>3y@)RB2Ua zp;BzRS$TcWnhsG!hiaqD%8!?%9Ztl%b(IdI>7J)WL{mYBaWkYHZU@D|?NY?7yf8^S zTC6 z$GUaRia*&l6OjGX6}uza8J9hSiTrCC)4IAHt&QPTu7B+BA?%m_IQB*@e*Zi6M_cWZ zc0+w%7}+HCQ0&<#0nafEZT(_zqwi^94HFS>)h%Gn8qRmaCX7?~UetU1*s}}kVXI-b;_KJwz7%Z_DRP5cTpn|>YdWy?yh4^VYq)R}m!Ui;v&&?%nOq?##~4 z?##~4)+5^tY)bHzx3(sMTu9f!Z0+C`FgMexs#xdLu1~;66rPgceO^TrHXQAm6e3T; z+9oZ{c&m-Ahw}WXb|N?Gr`>~qb;f#>hHYOMk#bYXTvx2xi5(NX3!PU^Vdd6iu1#mT ze^B6D&oK6Zaz-nx(VmSRrr3D}+QM2c?5#59CR0+>S(IgI`(vEg*2F7UiM0x8Yy-j9 zTE4+E@motxkrv+xG2ak2Gb3Evc1z<(q=(@1il6l(qcgTm)WNY`(3K)UXlG3J?Sz)8 zrQHza$@=P{;+^<7V?XF%_W#^E?Sx5k#+m0}*Y zihj^w>+MR*FXcS*a?sXWl}^9td;D3CBTqUUc+@iTrn>H0kyTgn-T!({1FET|4xc`D zX{lB8#%$}O&=(3_<+iu{k#1VB!tPr?LK$4Sf|4U*)6R`iTXt{QzIpSm$Q>y%oGza` zUHx7uQ9qz@V~I>@E^qWUhyg92CdDfyc+VVYaZ z2H!@1Hj7Ty&YSPczo*YhUZZDh@p6^-Bvl44NzwjUi969$>f7hHTi4uf%MR9}cB9st zyv;TC+32$mLSk>MJ9lOO`HLsH>0-|xJ#=yQlD&1b?RNZH7&i{Jn6`bW(O$Jr(I;)6 z5bAMkpIV}QT$8vJ*x*vIR^VTwhD_=`a?pec{l74946FU6Ew_iyuwOF-x~3^p z_(o{|&=uWY`u^P0eZsJ`BiAkavSRvCIcMbkK59;zKFwC2%ocPy&ABPrKHZS5z~RqB ze=4|fScPUG_0#=5dw%{uk~L|tBSV_Tr<&aFJ0#zc3KcSp&gXae$geM_wEk&lmlMNs z^&haeUde*VPmTIu!B&b+=d!2u%$Kvj`|{H7rI>J}YzE(v$FELJmT~;Y+w11* z*R98?$DKY5E}0}E+r-)BA3m$Mardk|83LPMZV}QYWwj3qPyB1Dd*ShaXTO@#r;^9d z-R}&IoUr1;jG*o~g@DsW&$J;6Icl*L+tO&zk4P(Q;7-2NoOByJeT* z%W8U#y;s}2(P#6!?zz5WLxuIfMfgqcSM++ipNCcLy7KGuNrE%{_3@mK+8rIga^sSF zn@+aAm+^-z^?$0{yDApTFF^ytha50>R%javS|!lScLF)ARjxPkIDz*tKL}&)Z{M zBVT?Io2K%g9@(2A%wb+a71 zbu?f2w#~OESm_2;Q z3)v-~>FvW6=v^K1_y4`Rs{FOw@i|~&8?DC+O}CBCC^Oqd#W`p@SL^Mfk=In^>+I4l zTJ}$}@BT&m4d@Iu-S-*;zFp6D8G0L@wBOYrdmTsL7o}U;;oy0NofBor zx`&vch@t69bu{K=2u6FHwRD_D)K>1@fDOi%tR3(dhc|3JvUIUc3hm~v^UK1SL`dC| zQfci`!ghz+SmFYkAjgBONO#ycYubkn%CIE}`@Tgy8+fb1MrRqdQ^0^F558E4M-V@FHHluZMWX+Jj_%42 zTv_@r-(f$7wG?b?g5Oep+K3_B;0efQYw%tHfiZvU?dvl3A$wWt&#S>(jM~!TotLD8 zc*YSLfRXgQ6}D>j<{c=C(B5tSa;LE&1)(bFt{{n zb;nrOlw=qvjp(qj2}9P&NJz3|=>aUMC|X3m6Vzd9a8wIC1HG+BJkr-dK;-txZK4NL zN8dUL_v@c%XKsi8c6(sW=bw&41@0E>Tw*0oAF+yK4zgdinNr3}3&_=V%>JE0N@AWn2lA-u$^tGR^+XF1J#L zWa)P_FX~RGB7LV6SL&KhE5vR|AzK~I4;|rad=IIZIQV0n!(LxR#znL(?BOg$eXov9 zT&?AhGbbY^)_*4+e$LG+ooQodAb}45G;Y}UAZO%QiN<(~{TO`0n*G+bj-?}*Zy(+q zg#q)bdUkoc4oUgCcDUUcde|!KZJ-Kb%|fr^NT`VMpAh`u80y=IyRCLI_K4Tx2_sEx zmG(AJM&F;IV_=-EXPQl5_R__{7~o8=um<&Q#vQf~j&E$_2Si1XV}0Ckmr&mZ+*!|V zY_jpdw+T8fM|H)nb9K>K(T5??L6w+~-wTSz#ZEn&t7Z&-g}{bP%O z)>>+B&TgF-jkZT;=5*2m2@1h)&%Qeo-xwMR>^M*rSvku+HB59BmF!nuD!@w32!?s~UAG0@vi2weC(UVFn)j+ou0k7I)>J+b+?1QR5`Ish zgFoRYVT%~0m)KqUuV73lJ$E9HwoB?(>o>#53uUaC@>o)w|1BwcQFWuSbmo(C#9p9U&@=-Y$7 z^U~!{_py%ym4nX$m2z}FqjWpz+DF%PdN-QBBj~#aU7hLrk@6IyYdSsmr0X1Aed+f} zdbf)1(-DlL^gAjquN>Gvi2 zUPbQ%DXlBv^^EQx(6y0%XQ1y`dY_h_=cH>gJv&anGts?5bvR7dElP8No=4O382YYH z&uY_^lJ2w8J8!x^r|Tp=TR_h|>Hb@~t{^X6ZRpv@1aBVQ&!GDtdN+`+8g$=~uHWcN zL%$WelGEi%zuo9N6Mg5P?|f8lA-eo2|3vz|g6^BqyCih|OjmCDy@Z}WAzY*A{$qM} zkM6Tl`ZaXFkKQ$*`vP>ImaZoB`&;_mhc0irKBub(T_x!%O;-iFiqPdo*I-H?MBfAH zYDHHLx+c=qnXXGzMkswRp-ZK5OVE{^?&naR7Ifc;uF7l3AUbO%l=hh+UAHx~S8OidEB~_3EwdaLp2M~r zxISK0-rMv}4!n~C{~bB7s;X*|1NmuRrjP@jo~ep8IWU1_MxoQRm(nZ;TK}g0%cOv! z^eMyhfnIfN%Yme{Pqo~LcXHsJ9QY5(fzB)kcF;Uo$bkiaSeFBvMypC6+H)-Az}g1? zE;)cb63~shkgq&6E38xSc~W1IO#}8IoE8L|k^K0Q&hJG}{K4OTcv%1Nj}O?RBb{s4ECb- zWGQQ}v?Kb9kL`5WYlX|rA`kMaw9~f=?RWN}HZM!NwSkKl^%1nCDuB~B_Q!*s-h?B* z-RVgg+ACd;cFkk2bOp^`X_2jrDHrcZ7dBMmKKpW1vL`|EHkZl!MIqURU$Mljo>{Jo zleco4Brxn|0Yn#^-v?O?3D0Nsv24zzRe=%_!Thwb%De??3oR5as0iH^E!pEKdBZfd3L5Mhh|J&%s{KY(Gn}!95j=09xFNU*?I^LZvldN)CNLmnjsTOzcc@1Cm?3*XNh;QCG&p zSR?JYk1}N*y|h+H3R#ZfW|WDm5Zf9ui_atC*a6>**BbeymqL(-T0Z6ROs@Qik=VJ> zo^h#Xl7y%S#(Iog7;|}iw_M?}RYFA@Gm2LznQlPuH#wg$?gi(yTI^VYmnvrPSSynA zb$#tDe{p>UP58ZD#>kQ17F?!b4dRB%G;&~!#fmI{O4IN1H2!$fGjHMwj4xjFUyhdA z*4FZ#ekKpT(0R1sZ%!e9qLt`Cr(3Dx@GH?gkJ<%sIshAI5yFJtA&1qB$FD zi9Oo3OR>bk+7ms0ateNizRJ3#n9K8X%xMEm3B_+jw}#I)R>&LDTk+xdSpAlBrSv6h5=>;Ci}z5tM;h|VNigCX;C@VhTv%}tmfLOM$2 zcM@yuQ_DJl^44X8texeZ;5AT<=>a%ejf=|%o%v2`Yw#!)+M!IP#nHZQhT7=cM{t^i zW=-yjvBaMA6}$o2)rsiZ=vDnC4bXn5EqI5=D%tv=we*qYJV+;EO&N1wG&Pfy$Zm`u1!??I^8N#uoB2aRJ-XDiU-li^U1X zLLwpB1>__sfmvn)QxC%UAZYXhJp~W5RBu7|=-EQ%LO;e#6S58d7GfqPsHXp}YDxoX zWAxGBi1)@Z0xg9;YJ_TpgR??#Vnq|v$b%lh^B2Yo^A}edRXr@=cv4FF7H7GF7LX}C zb~Q4=1FneRk6P<%@;ddfg_A4UJyH61#7p>(GQ|hKeaydc@29zMZc1H_{^RL)rZH0F zGwPL9X?}rOg*TM}3q~2@SwwmA5*f_j9OJF5Nvnp{ReI5YZ!p$lL`L62&umS1jz(id zuCx6?d6s{Cwl1g+3k=U95Jk#pF+jXM=yk9^X-|^?-|A19Z%?&wL=!E9d`d}znVZIA z^l-!pgxv%d4eoJ5e`rPZgRJ2{*j36AjbSkw-?%hZ>>X^zD$r{~}7 z#KFuPB3%Io=_;5cLIvU^FPgPsJd9iW0b6HU5W0fIBJul-Y!zqPP_(zb76eAN+mPSt zTk&=1>l}5P{=*VUaGf)>ElJjO=23gp)k+#*XREIm)5V|SsGl<&jrq?%$=jKqWh*yD6@*mudA6Ghx+?l1lRfSTeD@1lom2Dc&O) zd2Ue(toqqrZ_Gy=CL-rT1LKI&QkOI8>VRuYSI65RK)y&mV+J!Z4>$%YbEGatan3F3HznAE;Xfo1}#gZ5_%|7;Ph11e59@= zAUM*w@;TL8rCmd4!&>|qn=({CVasK#cwI^A*S1=M31i!T!iO-l=GmhVHQ3Jsv|;N` z0CA6Y4OUPc_9yTOC@y?wVAq2-jr~i)(*ZVOP9=B=whhJ~x-;4d5wfwzge^+Y`epsV zJ+L&|{&-PdvFikoQCqgm!|pDmtEeqJo!B~~^(7Kouke0C>)R?*U!K^bA=aQ0qfGm_ z80)RAuk}>{qvfA_31|W8ixmdY74&UOEfqkNg_dfx&1hQ*{mz=z7}||?M1vg@);N4y z`a2k{Y(~4M-rI`Hgna~7r3S<~O-(ZuP6giZHQAn;Xr3Y^_z|NmY%UT8@Z&kJ_Gw3g z4oe**hnRiJTKH3m91lyB=}%B4%!VeKVy`aGN5p?XM4yqKZ>Ui|Dy0iiQ9Oqn;2wsW zi9L3f&;m?;D8{@TTO94yl-{FG0i?lNmZ43T-<%FBvG(8#EUtF+eNf=dsCd#y3|IZ zHQJcl%vS3B6dP5Wnp@6R>H>z;++xIJ`dIJ4x)!7_Rvo0@ zAAaRCNjRL^!SF2eF^?JHvy{Qy2eJ{+TfKtZ$^xoLZ5@`7K9C|98Q3q8r55kM7PVtJ zD$+AFVS92V&(kV2B6|`9rh!NYxNaJ_@T}9rfsZl4 z5q!v#xWF%}fse7o5qwCXxWLCszTh8>L5|=09f9pl|uM$xtiayzJPT+ ztk&YAAB{|ph^Kj$m5YCpFLP%H*2#+b(+ z*eY;l6|XXu*1Q2cSasZ~1~NUbS+Lfm_xsRO-b+JyX;BbmLe~&pC(vI4h??+L{n0ee zia0W$Pb;!RLifWABNtK3)-Dx9{6K0k|8P~lG}(~h2L`_vX>Wly4(J-H6Hy!1 zegyUGf9vVs2&T3ac&N9g8p>xphiFamk3EP)ec+z~8sXFpPTh#|35^c9j9L*=Ax}QK z^xh(@xp7JQcS6%KdQO6Ru%y6x25&B{ccbN833CmtTn;dK&x-PxvN+|xyid`o~gbXH%wcr24~W=fe`o?8#TM%Lj7 z{sKkiyjZ{kwZ+J#=L2ne^i%c`u$*%WeBhVTgz5>e2CgftiL!Q<^#$*8{3WF1{v=ZI zFY6d_yI=;6J5d_9j=+U$#VO-P8*re6sihB>z%VVTYB{!B@-fzk{*9m4kr$%3a~r~KKWIvub*9)}L$(n?GbDRa+CHrDC=j!Joa z`De%;fPPk;(rWjo$vF9Ybdg|R-Rb$(I%F*bTP2~5Acr}v zwq87zh_eIvJ=Qr`8s;|Vz!ND6F=mLd0`ia3TJI+kB1*R|549r&EUQ9#$-J^`jAEc9 z%SmV8>7nT%*@q+Oq#a45Y}HFvW82C+sH2|y@lL?Dv~j;`{5Np(X88%Uv7D#KR(!_+ z?8&H~0lrBNVA^y41UrEjEhU!lwC9-t<|Se#?`LP;E>?=LM!`NI{6ugzWD!5HCEX;0 zJHwZ@%46uVG+91N2k<2S>17?mjbyL0eW&Ghq{4XbL4WXIhi(Kb1^n7!yT|&i_|&7PVuufW z$i*iWrK>_IE7DBrS510Y3g98o#k^{--FL3tc{hF>KDU1YJj6MSF~>E`>cMf0MrO4g z$0)t3DwQMO#W8vp$LPNk$7p+dj$;)0g^Xk5pWI!!OEC<+r|aVy=IN*^O)1`yh+`!B z?7!h#$`9<(fo9rF`O2i1VqAw$n*1Q%Ocl~%jQcwAysAkyTv|V>%9PUxm3^il z^W;865fusJkL6se4aqy++bzmKI=y}%Qn=Dy0@&u{hb^lDQ=!@5H}5kP-cN{7B%uhq zFQ_!BY>`Phjt7;t*|Q1nf5xyM+-M$JWPQxt47q z%NEh3<5N2NCVLU0O+-(XDIqR3(7s6UKQ%(bB4t=kmXQ-T)g3qy>E7ThZ)6NF}X|)6N4tNy=bk z6dxXwMJ^e4!MLI)cIhLfi0-1bmI-+Hwml=z+sUnYi`$Z+qK5Fm)$7~ZlKI|PcW8Zx zpMpJ#*o%qqm}=y&q? zojm^U$m37?vOLZeBjs^WAyql}y`? zE0?R<%~zcyHvCiNDqDV%RpKLkV=T1`tuAF6d zjo8ADQCaTeg0C{XGq3_`?eltihb1gM9DV&=i6=QWE3c!9)eY=3$KDZs3QZ=iaJ6w{ z;|?42uwQSEqyj%}P&F>~u3V1wB#*yrkIRcrsmfl8mH+PCn0M#K{MXNo!TB&oJ?WXR z{@fUA^6PDVhBSUV`s-G>gM(3+(3F57t(&2ie+t?cCi~8qBw? zt)XZ=s9<$~%|m*kYiq#wJWn>(6g!&58VbjIM@{RQp$Si1%!~8UtWJ92YVH5peC!RW zpX1BfJ;ULe3J-gpH|HW6iQNa5b=N-8+ig5d`UF#uXR#kO36w zx!uaFrx^XaEqzFg`xW)AB7IGa=Vx#&9IY{F>0s|(Z#&~Q*SD!rTQSa`kw+g@K+C`I z+J<%m?EEO5h#_rlKRh78vIrkZBlpRb35DLtNTISP*|sIxw#Ny4!Hc}(!g-4v`&Kl{ z7HRUa2r_?1)3^9MGLQe8j@usp$0l`GBD~*?|L?~C|IYY-p)!yE8_US?e-2s98*H>3 z|4Rm_N~b;lFXKN;hQa08POzkgZMhIKTUB~}^G+_jlMDYHxlnfp%Z2cEQZCHvsw%zP zSjvS<2UX?7%YVOI5GN>!=vwW?GeYCPsVAq`dVE4E;zR{UKa}aQ|L8(`+6SE)pg z^?os;p4zgJ%UMfwQ{{wiIn0#68kjo;f4np)KvfN2Kr?CTkC(+=Dj| zVtj_H&eoRIQ0CITB)9x@$rA zSoehu(UwKX7|R_ITYsU|TG%uZ?+|-ov^$Vte}gY~0F~uO-vU=W5$A)nr}pMw++TQA zH-OH91Mlz~VVlEm?A_%UhTyNxWToYJ5c+re*3`d)-$YX@`8YBOtdHm~)d>@D4mh$3 z-MtPjmKflPzTSAEuPx`&))8@G-sDFs{n`+wjv^(n{F80S{m*DoHQHT;bktgPvHuyI zptopRhbLNET3(G7THc8&tlOnb{3h+_G9SaYW}#(^F*pSKDlnSB&j9^U#I8b=6hxdw zA4W^^DC;~H?1kY=`D7$K_<;Z_ye%Y585=Jy^pH@IpG&hwIgBve)^aUCJ1z-~g!HpL zA|*U$>c=Zl6Ho?yL$tDS-*I=PJH5?CSm&Z|{>AMi@aLYz{ASq;MLE`bqm&oi7WO&B0x z7+WJh%ijVUJh9|-J%@{^W0I$h^LERXInh@{pXA?hDOKxD?cCTZ_pbAN!Wezo9tT*y zW4Xp_SzLR}$+WX2%=0k^L)0YfRKhRq${FUVyuu19SW?k8R-CWBDf)_t_%8NES)Yr+ zE3Xr^CD#ZiR>?YZ^e-Vfc+BEw#v0@NDt%wDq>D38xE6vgvL^bOoFzr###af&A+L`y za~NyK0$c1X)6bUK3lWjDF&nVmLa*N%Lf_Q$UwouF*Cp|1UD}aM)PX6cw^lgAg)&XT z=_Onz=p>?cJOZPQg-*h6gsju+7JA7l-@UGGVZA<(>iSyXiN0*~K0W7aF+zH4^Cw56 zo`9h*>viTtvh|$5lQt~9wA0HS;D+~dgte4Jwq>)FX3&JS{Hlj3tqO<)A-&+^GAfB! zm@Hv155p-Lh_#1kg)(MW+;wWyBCh!buOYAFkC2DRr9Be`IVFFxPA`9pUV|rk9*RpF zX=^IRPn@$0=-Bnv#Z&`PLr83`Y&P}_$G9Se(Z&edkapjkH9I5rYHK~ngdDeRH)OjN zv=;52ZF_q*^tLklQk3mkZOk>dZ_(nqqbK3KZ}bIjX*{uIeX?iglBKeB2@y&`9c>B1 zJ|ujQtl7eB+r1c`kssmnTj*o<`B`FKuS+q*_Ih3E3953p*1Pq(ck6Zko%Om|{diqJ zV~kv{%X>#v7EQKXuY2&7s<>_Vcdpk#{&IXKoRy4m3;w=ZX^b=KSn6m;1;hYvNxOfs zM#HBCHG1`0FZUh8!W^cmNu!i;JOr@n2DvYuBaf|jNW?W7bD0%dtmKTdX!1rL$s+?2Pj;#Oe;tmcZ})X5_{10_NY4=VQ(C zyh26xzi6_;wmdI2n%0-cyp!ke$U5;)}e?x$n|ONaRMHCpM=L{TIMm*NWV&LEi#^U8fl;E=Y4<(n+@s%>WC=A zrD(pUw;1X32|h%AaG^CA`uxDflAn=Z;4N#ZFH0|}Y{i|hXQ$9hb!T@*+23;|d0KD1 z5Ed#uugNti<2Yl>XVA7^osb`pb8+84#k7?Y(MVmavD>p4TS_W!HzQu$FD%b8aZX|g z99dpSZwA!f*kc9%82g&^nqVAdf744nnUCwNl}e%>!cO*j9uvkjG69u!G`U7AdjRGm zu&JS@wm6AX52)%{{)1E>qqBWbv4Tf+`c8){Wm5W|`@0Xl6vZWN)ym#w>F2czdr!v9 zi(J@h!@Q>3S9IIAdH8{CV^8dxyJ>Non61OFor~x)Yx&m!v-~HA9NHZmxu|9I#vvDu zFM0XmPLHtlA^Q(@nlbOduHl;&wY_mU>d)}aTV2-_O9vip^Dd%CaQ-fr=hFaqB#Wt!g|y^7+&I_ivtk`Si|<2PeCREc{{6iemkj7yfHm!zqzB zuk1R!Yx={RXYXB)DA03R{Ye|IU)d13sP*2BLvLT$e*fB@E;HwU|L4-*Cv51sV8@@~ zJ336Cb>m9J#dDJ{o}GC#dfc6>Yfc;(dLXLb#)Yjer=PTdDB==O-P21^FC1<{Ki>DN z@GG_gR4`rTwzvF|ZlWrBxO->aUpDASN0(}uJlfuKPw|m&j{Z{%AC127&8#9Lvt}>7 z?d8k>fhkx>gjWQSSJT-7ah22?#N-vx-{Wq7Q!+#4uFg#D;@!=g) zoG6y!i?uJ57VV4e+cGxY-2 z!q>kseJKUp^1FSPzrc5H`MnFcl_*rOM4`fY+zOX)bDMl4-yB_r)@>U#Z_0A(7>rd3;KtSUD0PoChtj0 z1}_MkxF$*I&jw8&u_)D`MRUfl3LV>b)@awHsVjTd@%+7f%_>uRzSk;w)!h-%+YWCE z{tG`U?B02N$mnzJ-p!J#S2orU#wUO_j42Lx_wY<7pp2s_NvMqim|e0psJ)zuPP(fsY=P+suJ2% zRfZl@mG5YeR0}F6Jddi3o~tVBhN#NyGOBWj(!5W5r=qt|`ckSA{Hdy>p#9k8YpY6~ za;j3}s;ZRRt}4g7sLBpcRjESzP>)dT{E}3kO!-vh$t+drQBPH_|G@P(A>qWoW<-NN zTPg2URVkI5@tjZi_A00<)v__3y-PBlyCZGmIe=pIclFidd5G}P;+c|Ya)szD@H|2> z?||o{a8Ng>0CIEb**GYgN7vRVC@8xZ`=4@SK)ORi;s#)cCZgH9QeJ$R3`y z+S3-E@o7(w$|1@{!V!4>zqaRbvV{kGsY(;-XLurO=JP7SPEv(?ATWQoJs z9Pm77MK&GGn&IDV`2pM}rulSx)9N?FbsmDdDX%M)g?NBiIqzV2(#fO=H=}pF8ZI0;^Bn zG+wsq;X%}c2c~`MAi_JW3-F|DOqV4zXW(da*=q~7!*Kk1tgB&dOGHtDE++N@3PQ#e zmdJ;1dwFq=O=UYJJI*UhvX>S#6}-c-ksRafsP494${O)qT zEbWK=w0!8P@LRz*`X6Ko_doPB;kSZb-j$yF6E_M!CGPL=(uGeitZ0xz>;;2wiR*W? z`$%wt$Fzg9T1oYkA+EWD8D_;Mk-_i=pEiI!=)p$L(QLKWR9U)0 z*oZZZHl~^g$t+qkM`nuQV|AvEx#%awFO*WPN*jrnep= zFLpQqazj%NoVf;>=tmfc9X-gWx7KMf;d?zT>_N0{x2Z>Cn>dF85cTl1=RSZ_MC~Lj z#@?7tk1cwF+yiCHBFFgXsV(i#BEmc8=2aa~8~Y(Kk~Ze-ul_R}ZY`vcEy(_WY&(;- zxmOv@H^`6C$=W$u;2|$+QP9nwT9^9+LzI*;LNwAA93_1d`Ip`w5vwEGkDfNtUahw> zat?RmA~`N&r4e%xaF*70T#Wttp6qHGi>Zzek zWtorppZ9#%GtKD06Ag)PP_ihgE&1%Qtd%=R1YBv)m8no8j0BiVU=2w61R1%E%eREZ z>o?-Wak*BA9nRP@Tb)Xf+|N*~mndo?`XZ+SZLtSItSmES1jUWLi{b0ns<5shSF6z1 zco(gthcT+1l->FjD3%Gih+5YBY%ZrpCc%jb^PMnyfqv{q&El#T7$Jy0WT}II^MxE2 zW4`6=r3~>SJj8j%Aoc`Fs61mpEwz#S#EhW~m0(ZnQE0C-?=mt%)c47J)VK8`qy6-< zO;Ix*t1&N=a!3o!n8wpA>jV@Y(Xq3Y$7;*x&=q_w-p6I;@lVb>1U}ZjwezZangsfJ z19(I`;>%HyC4t~GF$1+XU$DMzT!whC4Xym44N;o4Hq}&*_)3gdQiE+n&p1CU0z7wY zs>x*J1Eh!a6CYderIxJK>bVF|UA$Z)et5nwZyD z!o$Pcw{IU46SZYa#Kw)Q!^6W?tXLEivupF_h&5|gPMs9zA-_oEdA@EDs6_nl)?kwr%TX&z>=6%&36_2Tq?pJ}hj;;K2i@Oc^t4)}$FT z#;;yIx5bPC8>m)}moaMdGDe3z#WM%Grb$*cYx=T&r#h{D`Sr|#d$$JM^~#Yxd)D_K zUrwJ@-R$b6UOxBUjGX%qrg!VoV8=l9dbj-Av5 z3%8zrJvN2^xFk1f9LkoP>XG=14$icPue0qjWXK?Dj{yS)P)ks&?AQ@WEyQiZ4HF(d zd*Z|i+%^jrh7KP-j9O*(?5Wfq)EHyV{hh+8#%RrrQ8(yFhTd*zl8!u|GSksMi#wfp zxjw_TOc~A=ZQilbk)I#$ZT8WyobFc&oeeA$bfIt3>AAn};*+BPovs^6KgyN&%7SFyj`^nE zcmGKHP@!+_XDZoZVQW9UPgQOO=+|qKdCGS;+Ueh=s~V!5PwlRZ|3p=OqPX7Lbsmo@ zAxbQ*Z|ocy|8)Vsjr#SE-=p;FAK#B6|I@m1{Ub5g1^kFUEw-sjb?^V*bpc^n){gp+ za`<2jWsi}#+0V7G7?S)CnD%YwwsR+xeOX(AoDcj{R&#|c7XCz)_^$_8$4fuYku9N+ zZNQq{To1*O)!Z=*efd%skQxnUn&SK<=Pl;2D+ry^8CY7(?d5f3F?XC-lw`Ypn5o9y zS{`?Jq9*+9e11n(a(gr|;%2mxE2JITjt}T+igJXxEc%2sJ++ZZ!-drras=lryXw(Y z*bXmd%do(~(vF?KMm}L{yEc0jf~h?-Tl-sU^QvkpTkg@)zSC<==uh>io)Ru>BHE9& z^uS)b$CvFW+FY=gTYAA-mIiwjKV{2|tg{}PVzSXlTP!pOt=}VTcF?leE?UY4OlkR) z(A!g5JzQyD0z_+Ywe&JttR!T4$7N_`m+f47eK;-@le9Fp58h~T(OZj!^-_x!D8g1X z&MWC_J+HC#WPYRFQBuXZJL|RLytYe~uq`Rb?;LSmb>i{(&M%BMG?Wau&d)LQ5Nydv z=PYmvc_e@{gbfZ-O4#8llN^901f!i^7Z-LlZ3;nM<1^4yKoK=}Mn4>9)(=;Y+A;X& zkb|49?pkqa{kYwsoi{8GKCp7a=?yc^E(|&~#cx}1?WL>69USYsZg{mhk)dZ-25k@P z9IsEL9UuMtkcYJRDqszx0pV5BZp4Asd`h zqQQHnG+#EkL(G(p`<9J49NPQHgm!x;wvV3ED{8^8qf?N)mPE@rw_0eYbhqwLO#C z=KM701ui zn`PGAvOQ{cPI)R<)y-&vL^lXH(cUg8b?v=(?bYbjmp6ufGx^&d(IsJ}Pi_RN-Y+3MuiH(=78WFX0*q)`M zPtX4A*sQ>#GyXU{z5Btr{SMFX7d5{AqV>~Hgbg@OZ9k=B%+xOXmySBPdgAek?e|Rz z*tcNl{xzd_j`?lDvQbB81s)miw|Bf>^xVFC$JAZ4WZ2&MLypf3JT$%Qfyo{BPwc<1oyb4Pg14XQRby!V!cgLaIpId9d-9UG@ckMIev@kfbJ zr`T((aD+?(9^f{+~ndDr{7R}4N7Z7m&UeE4H%Y0S$vju?* z2h1L~@~>GlM=c!^{#j7lo2M_GyB2%p!i_VR&$s?C)2-Y0?>_vns&|@{Y0{)h{{E#t zeM*1uVd@XI#_Ir*;thsvi;Um?KYikyWvEO)km8QYdn1WuLCz#>$SR^nKOS| zKpfjv2|+I z{`J`5qs@=}P^?7HWO*mn{q4l@QYDwJS@TEt=YdIHxb$@2P+Lux;p5DoyJYekFnHk5 z0S69{S#eMmB~^}`Ux&YqI9o|>=Q_D;o11-W?6xt@3b=K-x6AG=&`)2e=7XWg50 z=Ab3lZ(aVlN7&SpQL&$Pte=ebZ+u#|_)T@ss4tecD02H@iXfL?GH&~QY)h(lq7O(^ z=DW|ohXReNg($r%sY=eHsom%_W1aH2NIsoza&5Y!EeUCdvu`0^PlwN zkEZr6)#m@-kN* ze{=ZgZR3LW)@|yN8n0)Q7x`tGT3d&B8(%xTeK-O`z5Q6`v2S~~USG~5AX`skv`PDt z6$O49!paN_n9(EORvm4@5;fp&=jstRJG-Qlu?~70JKMkYmMB=ItXb0~Onv>?rfBW- z7I^kbA788t!lGrQUVD?xmpy+1Onzm6sND~bcb0Z>SA8{1zx4K6FY=Q7h2$RRM@^cV ztjir}C7>SFMbxLg$!nCof#G4=+Eij^Ik{3&I_C4ajn^Zc>KcAr*Y-;aLr6@PvkU zQ5P$FT14IOoiO!#Q?)~XD@%J-$`X#=gqLhzzLONpOLV}hj{K9SV(GaPZ6Q}t8WDdm zeZR8;-!iQ%k@HFaV5~dAFRc;5V;^A4Iwd5ZVuipqJzQzU%hj|Cu9nmNg1xCZ@-2I? zaZi#sTViC3$}&&f=!>?HG)3H@&eUF_cXEB4@1a^wPq=%_mS)(tB#J26jiTO^pbP); zLHpq&pJ2UB&#e-7Q&Q8v%0v~U(@GHW_7@YygpVcmGr`jvG6C`d@=7S=Ntz@405$)j6CNXE|yLniw%DWg#aaF^v&q zeleY5mD@xgEgjG^rEjpY&encgAM;&JGQFHhrpsLo+WgMTeS1=nWsfyUX>2=Z(g2U!3YNWWa?FCO8(@CmwD~oj2 zWV@8zfCB#jKat$@E%R8PMK;o;HrB&fUwv&9>Zf9?Vc5>s1(2~f$leH~khhApS*@54 zi`8t!#8EsKW-b&cd77lNs2fg0le_bcoGJ2D&~cHqQB*PQf0vxbIWf;}Z5p{S%i|A5 z2aLq10Y+HNRKzE4d-?zgI-K?0eC`JL*tdts1x#U#(9kmY!}N9f{U4}7b<_MfIaWfgPHkY{_e9{Q&+SF6ir$00UowUCSF>lS@E~3UhUhKW+sN@ASbl&{ zafe+gnEi3D(U*a85syQ=|I0dOGM=7h?!~X_bg$QhIE}5oZk(BxeKp^AHSGi9-27k9 zzbws+GR)doF6FKMtt~r&J{6ZEVX&06md2U77}E%7Z|}T<urk3qR(ZWrmVM0*nDT5Vyq^x!n&WEcq>W~zlB7!xo$7xP%05-f0LCz_dUO6 z-^z-8*VPC*5*)d!bJ%wO=@-`S-_d?n%)sTbi+4u&8D^u80LcO46kIy!vov60)31Z`gHJ><;H9jE`^c67@6j-yMT zAtE?-d+Q;5JzSHx71&U#@=n(ge~lV4De2Cp7tb|pQ2+FWGw07{NtdZ%x=fkVf0XfJ zllnnH!6QZwA2qUORqyIGhAXqZeY_4u$Lu?}_kfqzUmxe3*0z4LMy;~%|G(GjaE^;_#T^vbI97w26*KPUFc z$W7~ff~chr4PAF?Qp|}ld(MRJT2pN>H}lTUVUcym@9(+h^rS;4$Lymvj_x^s!|%bH z8&2EPZT>p%p_>|yyEyN{j!rXT2Cljoe(vn_Q)i|gBSr)t4BL1-X#df{dzcT1z1G(X zIyh|A$+2K2V!Pv`cAgkZY_a`x$j;L8NF(_n)PV1hA0$x>ISxWg?fYI~mC-&V}?RrBiAe7v@X59nF!mydIgFEn%M zk`4hI#%G8dyOV>+0L)m z%W`b5*UL1<_3gN?*E@zKal@T;{EYQrTPZXY>(S%l0!Nn5>-Ffpd;$XOIM@Lvao~Mw zZOnSNtITS;^D?D}H43@Jt|CsPeFq|m_Z7AQ@j-2{w%Nt}fORXe(tw)PBZ~rT zN^Ggq?r0O5V|CKm7z@_K{7t&Pzi#)NwX|Be#uXiFd)~M5jeFP_hG-4e+^wx-=t%CROovG9=-w7zWvO4ZfpG)_AX)dv}ZrFt;be1 z*VMWmE8dFwi{An-XY`lrW<7R!$nieSH$`oUJ$35lnN!zePu_U?{OPl2&z?Mc_WbF~ zXU|@|eERanl}ER(Jh^q{(b4EzM|a=au<*jhMdv3j@>zDWOYpQN{ruL<9eX5X?C$XK z`{#~189wIZ#Kk^y_P1DYqSN5e64Mv79kISjzp42r_di6NBRY@RQEx!czKfbo*xg{r znxBVlt3kUb+Hb+m2-^GLJ8yr(;XQ_ItTtd%)n4l>`bD0k%?@>E?x{VXU;mBOdateU z$Eq@&m;cy${qbtUH`kpNU1w%={Xgc+4_n!*{j@oMFK#<=r|+bl!xkNCG-1c@VKLQ5 zZ)?zXL;Vq3YK@EP7alX?P{v$DF~>^pD52~qF6DBTOWr7A+or+UH*VXsF{*Fgjhl9p z)-xan{oG87&tKU$?%29x$FS_#U30s-24>HmBS+pG$v#SN(t}77?m0WitPA(N<>TXX zAf|93Qh%o2nX{_vljMENZOK`p>is#hnq0^{y2imGC92-_X?^|LXP-`*Shs%WRjXEZ z>)f@=-%k#1J@n!3toWJCBrQ#g7P(5y;#(V0drGPsgdv`xl%ew4+ zKHn!@A@8S$CS&lA#vjOV>T2(>um5O@S~BovH5&D z#0A%Tjlcdnm=UV6!#Ezx?L$Z?z0_FBKdqk%I=y-Pr0yun6yMf$R!d5~p6+Udqpyc{ zu4YUbUwzg&c!CQ2ZNEPDbzDGjCcm~s`{|83XWVsPOB&dMsjZbGJd7~nrVBf+6X5AT za6 z0Qr}wfyl{EjhZO?Z$Nv79}l!2+@l6qjm3RF8VwK^6@G*m5%edAT8Ag>3Ggt0e+9f& zIHItCtdB2TipCsmgi)E#s8?%ow{-BJfsf;$wm@^Gok47B@ zo_M0i08a#z*VVQ~e$)aV@mmj%@xZwGI&o1LrlgXwKLI*m+t;t{L$N2joYl8Qyb~{~ zi?&r6d*}3=XJ$Qz;s=oC8hL&2#%qICU+lB;La(J~dn`EJWx`(H@Dm;XKG<^Xp86wq z)FGAk_dz|T#xxrr-Eh>-x6e+kA4}jF!5mB{=Z1wIRS*3SG zCDMjT6>hceI4Q>zAz;Q7x0U@qnL06VyUnLa8y>vHtKUY?-s^vU_Aq?f(9iugo@}ui z!2p5>cs#i`<cI#Y~Tjwg5NV-3k24ta z%*g_kFRyFd-m^*el%J;eIP*pNG*dIyPnPkLfBj{(+>?FM?6V(=MO=5(k_R-syV-wcgX{fToNCqSX=Js?Z_@0}vMPGOnXYFi zr61Y5d({G6*JT(U+~VXjx96+R)m-`AgEn`PW)4q1Fi*>eA0;wZIKvPAW_}%%g+Z=T$15SJxJ;_3u*{4W3sGup54}e3xrLri91Mygq`Rx>quJ?NF;bjGLe)T zvek!Ljl@r{^*{GmQ?~0$cZx95VOATGD~*>PZn)@B!-a?H&W))%CuZQw2j4o?l-66285dmyvdS9Tis^qJxDq*=^KR(0{msF+VPkK91&_cEoy%^k+FiGkW{ZS%jvi#YbkT4))Y9F%SRW#Md_{KR)mp}D$>@E@(Fi(o0QJMZ6 z*|j8vaVPhQ8PK-+Q_@0DPwZ)I7$RVJfsV$!R`!j_sEA?S6u0dOIDr zgQSRc%PXgn?aZk}dD1TG$ezl4%k{U+Z7e0X1-I$xAX)&JiQO~;OYu(2F(QrRACU?p z9s8Gd=e>Ge;I93FShv&xQ6Kh*Lq>Z0G_kMYtdjUemwaZ5NAdK}`s zFl{8S=&K@9d6~vy=^czcb++EcZLg`2iC>cp(|@Xvom<4Z=iPT0A^77(bDD;f!`GBX zo^hy!QQ3^4t5S>pq;H|EH4i~MQ46Luyx35#R^lS1KJEchG36~+5sYnSOSX!1TFe@n zO75hI+{33)T9^3Rkp@t}yJ#sP;cd0Dz*x}M8o!7>$nB-aAH9evpzke0f`eYhH^!c1 zjQfB+`50NeDI!FE)4qG>YR@=WtEIq_DJW?po>w>VICw5@{(@YVmh%`Q;5lB)(9cl3 zOudTt*$TMMcnR9}5kxI4*Ct&_DnJhCJqP6(iuQ8}ib1vjip1A;Ns>OlP#%9%Oex6T zPQ;_a`w`xdn6G0OE_=cX8W`)Tg`uqjY9jkR_Wb$Vz@H&ww|rB&pdDc^p)2(lKkDxs zA-}x^ef044CHrV(BH%hxHg@lGy6-3l&HzEwEoW+>Q16g3ShOd%1pohqV8QF!aXr|7 z8#-bW`a|omw=VZ;DRs5b6^iI2;Opt&gk9R@8?#-Syd7V@eEFQ*N1wlV^z6m`r_XOc zes=xQv&#>jp1=R(%-zQ)Za;eR{Kdm(FYY~ke*MwY*i+~BcIkff_}RlZA3l8c{MO@V zn-yher*8YNKe%=7;*st>F2$a|^x)|kN_OPT?yL9jK6!qi+aJ+gx^KUH@8;uY2fF^T z>+1bY7w=tt`1IoaC#O%Hi#~j2+vR)f<_FN~S&)Chvv(h#yz}_*v9mimb=!G`Qr@Kn zG+HZ*z5Dpctw#rLJdD2fVEz06UPJr5YPjXP*^!$MV{Sa$apnHjOZPTjxNCI*E#~?| z%LTMOS06-OxxeMoy>;jAtU7ypMOgb+i)r6)x|Ne?uUkxWK`iJbO;UHqg00n1&=JBx zwZ4avJRP>=HE8U6@$|Xa3oe7)3f#SOdvR*NRH@z{q$cZJ_VH%5JB8rx9~g=l+@A)0 zKVL~-H8^w45njn}`?w~VQ=mnx>$+6~lY6LMl|I>asM?_e`->{6n`Qer+k{JFuZ+Ju z;cA`0WO;{#g|)8S`u_d<*RQ!}A6zo6>(rZ<5J5h9rUn5I7u>#g=ioz%A^%~@H2a#? zPt!Lv<@+C`9@anE?EV9X-X1z+P>S)xgHq=IDEYmS5#4i4{V=0sbX+BjzQ}BF;T}>(S_O0_0$Iw6S-lixc}!*%&#HJ(rv1;ri7}@H2B2=@A~xq2E~KE?XD_!$Y1r^ zN>zDLNL4b?TE|CoRAt$0RoOFMRoYcll^@HhO1J0aCmX9ON%m5DvbU}os48jGtI7aX zRf?|CuWNMuLGS09QGK4Oe9|*v*EKGY-PViN zRLYV6ZK>Rh=lp7_(yO4VR3pD!;MtqbcLbihBkkka)mM+_p;CH0jd8CN%MOlNInP6d z4uhFK&q<_~g;tM`eOjwYNF9lx>i=WD=V-3#EVP8PXIn4vpSN%`?Gg`9ttDFDZun)( zhHZ;__ATNJKW;Gf_0#JxwrUYq>p64{%#MX_6c@O9nmGr@k(J%q`WP+m&gL^(!=16l zGoH@jXA8cbR`~UL@Elq1;{#V;N4DwPvIx1--op-N-Hxp(i1!J74|YF%vjvRxO=vzc zA}{Y(W&01jdF_9=9+pzwk^Y6#CS8fjTC0n-lHzJtv(-Z^Ep1#{Rnq&Q(ZSLK9S}A* zJ^@hH2IGXDKGLpc`OY#wV!|SZ7{~eIGv}ee;8T%W$@oSaF%A}4jyF z3c=G`NI?^6JL7Wk-(EWBe5M()@jODdfblycZ^_d6u06>&?KzZ4FRYHZ*PcVkb+SbV z>zrzYkGcx@xVH`8h!xxJZ%&LY>Vgq>B71E+HYnQ^ez$J&#X(0*=vc?(!@ zKmnqMpsx{sQSa>Q6IU+XQzu%JO67)z4piUP8hZ>{GyVxi3sekp5O z8}K4Kvlsm`TA}mPv-r^3NPFAZ$dsZ*wA2!B#XCKX`K@?oEJNhA%~K);e^)0ydp-Yt zEw@U2Lt1`iIVj`x^bJdBUQWyl!AbGkYwxA&ixNA%Wm@hXuucm>0b9_-dwe@#hjN)_ zwnKe6>f(^-mm~H(oxcD6s>9d!p1OSM?8WmJE?&5B;pmz3VY@H-F1(a)!lglbUjDW7 zMUQRIIz&EcweC@a6%T4Gx?3simKt)S=+tZ9O}vtG?B&09K5x11k^8J0MW$WLH}T4n zgEvl`IC1ji$y29Joj!f~%$YN>v9V{*o;`p5e82SK| zK6mb1SXkJ#YuBz{zkc)P%_~=~1kHAzva!aZ;~j_3FB7u3*Q^!IhK85^ds)Nq@bLNb z=U=^gHTuB%Icq!3KGhR6K&)r{pX0%`M%B4$}E?c&2#flXVA3h{^Xy4$i#V4E{ zzw$`UG217wZG31}*3xI(9{$9JSt?5*#?SP*t^DjkMWa=TDs) zIwNfQoLRePyJS{x6RK#Ep}Zxt7x?yQshmZMD7n*RnG!TMc;blh z7bbr`cKG|5`tOO_y?xh?@3-aInfKd#Nm2y|j~-RidrR^eHGK}n#1tqHbD(IUB88VP z=@paZz`(r?E5zBV%U$r}C)t&>ZsiRS_jK-684w`?k?)a#>v-eT3jOO#sw~cs|d)%ek zBewLcaCDzjjQ#2~P}k&c*Qsl}~)FZIpm|^wQsugN^WSY~fe3~4t z`M%8l{zpM0Mw=o;p03&_W$th0hR&J2qh&KXu{Ie_toPOU+Mwi+1`jC@{pt)_(>rYga!ga|OZIQ8o6L$@6jUbQwP}F?O1c zSA$U*a)yK*NX6zu1u`Z^;5XUUnb!L$V&_qk5NHeBegF zH`ni{@QLpGGWnA6J*(|f=4SgSc<lO*Z*lI#7`pSaQB z{+AV=ZfKr4)0xGo2FzN2^8C;bySq$joo>nY`yVa(2lxd%^X~I@QoyZFh*D=Jtz8UO zl`od)_o%F?P5$jWRi(f;@sDGoOw+G#oIj~w-?$v8D#ZuMb)3Z9&)`9LZe6A-4RWdf zx9d2pH8&zH6>&`1lMue3+BKZl)u$vhOCEQuKiSTmQ0o@5gtucw=1th1N~e2!L1Y}MPiGGZ&8t(6L4SBEF2@Ie#x zjVmmX58uw_b+p0}7dYDTZN&xA(p;NfZ_f)Le>UNTEqs{SnuBQi`nS@u#lGJn9nO1% zZ8*Rj;}JQT%Y5mnpXRA3N$)MLx2D6(5aq&V#a`X8()-a<@mtvS@r=u{1{b;7SjmNF zdS7|A&uVG(I`{2O_IN!_U@_FLD2TV9EOrh^{PZOn+lW1z_3gpdYuP4R2-BL%JbOf$yp^{lNc(@ns!wELGb(@Lzv7_Ii!cPogM z3hgc#3CW*07OTU+&^kP89K~ECAoDN5m2VS0S|dy z=~C$mq|1~Li9`ZCGbeJzy_*@nO80?^5&^(z>7wWO;HSurdt}A@4EGu667NLWc&=)m z2hu&>xzc4W)|6K}$3q^#!AGSlBVBlwm9FG;0lz@H;11lIJg1M*RhaHUv-ETUw?dR5 z>9dzFcfGLxZYt@hJ=Uqpxx771SM{G&C6|l4;zN6+#pe;FNqdQ69kf%G4S%bOwKPo| zw`uI(+}D()Lz|Xu+IDK=+SuQ}tv@~S{w+kg?4c^hKUS4*u3FFEylwjc|Hchk1Aw@9 zb36|pSvIhCK1gYN1P291=e zCd}YZ)SfP2?nP;kqcQoC$-McfTwreNV;ei?>LF#6CzTG$#iev5o^)tM)M1aBa#VUp zb2~RTQQbb~@xz4y^<0FADl9Y zID%rQP-2vaz7Ji)ey>OvI-*xXBH`3bMV}3i-d1364rl2s}MZEr|Io_|twb zNSN}Pn`K`B$(n}L`|M#Ef4X{*R1w~W_DW(28~^gkl5~dzD^FNrHeH3}zUUzs3G8!j zLX?mFX7H@^Hq`)94weM_B_~9=7$;G(7}4yNm{8@(@ylLm3BkAJs5P-u5LyMFql)>6 z{ZbRAT+Cz|Q|Yidh~8S0o;5JdDIB*gI6MCIE=T=H)}s>DsEb4F6TVz8Dp#D~;)wQd z0`J7+H|$U0Q=~Bx*~d2i?F)H@c{c2Swq;cO%c)=*Y06MpZA|m`H!c4wQaP|*cYeco z$#NJs%=OSmAvF?X{_rzVw4q%b6Q(~@CY*43bO-vz$YPIM5~BaZTOBlXmSccrLX`_E z9dNYNP8^TqZ=xQc1)^=Vr7`x+)17ygONl4f7wngvF!aZ~39=sg1x6nGWyW7F;bbOg zP0nz2Lhx5r;w(fHf(9f7fMpfZ z09w#*#}>=@^C`*&Jy90VUxclc*E1aBo^bd(FYyxwZ|5x#2~i$q2lln{gy{EPWY0nT zIPC3j?T~ZhkC$^2H6hDMT>ZtHS`8LaZU5BH^Rc4o+}eqd?FrLgtknx^e$vteY2u7+ z@6FW*vqr3fIHwc5xq5(Bt*P(vDwm@%F`??gere8F?GvKkdsACO)3z_KWZ%Y^Fzr@@N@`3x^qZq2e3@D+r3o+CDI8g9fmQtY!?L{c)DvK3gr9;V z3)Gt^AF|ZBu{S<^#CVq_>FsB-JiTeXj?2S5AC}bs@@;LdbftTLCu}kC$FqW|hd9D9 z{^e9ONm5wy9F>(Yd@Jn6m_5Oc%cla`@0|(JUlMP|bwb6#HwkH2$XU~i(_xOj!VNxGvR&U%Zz89F%cJ@%%`hbK^6yvY*29>QP6Iq$MJ zQGQ&!&E6b8#?1>Y;pq@Rue3K&pV#qHdlU7Di`Uwl;}2*X@YsVNreiC0!qegPyxZPH zJ$Rlc)}~=0Yd{(ibR%f<|6}hv0HY|r|2GI25D^g+74_($g-}HVzjvgNKuAIgT_6=A zAqgooQG+1T)PP8lA}B&YkRmElG$JZhQ4kRk15!ejE-lIb^Vzw{?p^l61rx;o&rRO# z?(CE|Z{EC_c{B6IS&dL}_OsZI-`eW8lBSRI<6+6UB}q*bc?nsulUoK+7|r`N8y|xc(J(o zfq4A=ReL2vABh)nbZ!-2N#OB!R`nG>K1EyQSN!Qyd*=MAzmiD*R#pKPKOWSw{ry#e zC4*NYv?xVeC3t)ADEg|wlETZ`RfHwi{tKVnRCg>jiGM+Oj0* zUX<0B#h<>jEkbeATT8bnt20X?|0S_n^Y-9*>#H|!4}L{o&3Sw9D*EcqlEAAdt3691 zeP>pG7Js_Vtp+W*bg6@LesyT^+y5$eiA;-`Ul!vGGH~<6@&|rZG0YzbP>xIW{FWAzoGTTHR6-5=?Ok@%{4^znmo}k8vjf z`Hkxve$Zk%AZ*y4{v+? z@YYBF%o={?z~J1RpL27!=H~9m&HX+%_s87apYrl9<>q{mlQTCbXI4(myquhcIXO#n zb5`Z%!sO3JuA4!L}KL2k~L%cmDzKD{I_=U`sWnY_FUxw*%)cUi8S z`#LZ8Y+ml=yu9nLxj(-Q)V}#KQ}4)QrZQcs&7ARNTA6S9M@JsZI(+D8cuYT+PAkrz zKX;F7`EnCIntM!~Fus#-N6VETo0(mj_UQ4{@E&eKO8IdOw{B@@Is8^w=%`YaSFP%J z!=vhRW|!14>&Gs9Fv#4iYgconh3)Tl%lz1z*+n7^&l$d5Mve606`b<@@z zn6>%O@f%K!`t-z0tFy;^l0EhFlap8f+H2gpX=@Km`RYvCniJ1|bbR>AV?#eYn)<^2%S|-+C(TljFly92-IpzYKlPJ#lW`#JOz}=5~so6P++8 zar}of-rs!k#gDR6mK+}Z-kbBjjM#Hx`o;r8KmTRq>K}%z`hMh`FCu!5A2Isl?8F5> z4O`&x?V%wnfALzi*KhSNp&Je)e6cq@adz;CdE4GxeCp`+xFd z+6#+X_j+~R8!Pus`sm2e1zCe;?H~M(+m=J=UuHc&eueLfZ&wbRvo(FizL}pM9_44k}E%5iuottNrbIT+b$A`y84~iVv|N9D+ z6BAnuO&T&dHTkcz7tfcCJ$P~Oj~6aoxX-mh`HJPrJp9OmkKg}r)yKpkQ>9mpefp_7 zEgQG1)x6=;^&UF3YWGC1r$EZP?(0B?BubZ|l;w+pICa{h@4aR$UG^*tdjDjG(XW5S0dq$b6tNL$3T7$s~Ivu)+>6`p;W09U>jjGdOnr8VOkYD%_0 zM)4)7y6obMZzy^N!uGDjxafH1)4^(voqB$;)qtQnTRTy22;?QVv z>v3p!SkNP4*@<2ucLCGpV__v#I8MbAUxK<0HXe8sJwBEGC>tX@3zmP;<2Q;|!`Hbo zA*UF{QxHGr;;W;s9ufRk2Pd4jQd*!EiYo&$VaCxkWeIGfOIzjq;@@|Xa--TP<;p6} zz2d{8lq!H{04Bg*d_Ms=3pfC{4EPc72);D~lmavY)CIH#xB?tqXOW(dX_S)KN=q*o z@7)0}1EK)#fEIu@fWt_~jJq444`3v~ACL%m4j|JTg6DC7>VO9Ul>jvXj;f$xW-$Iq*dD!L|73vR9@`NU&&*-` znniaJtD@9|6p6=Zc7X(l=3kDDaztzeJQmLAPWZSF}^sR!Q$Sra)->IGIyY&K=`F*5+8XZA<}Q#HrZQ z!g3RQBd!tocv;c2!%zBhhhG`1eT=jqBXcKX5qI0X4h22ATVJbR(?Gtj9bJp}kBBw4vQio}$H?9-?$n{PVx{ z2E7ULYOY=v)MG_NpG2G;L5l*6gDn^D)Wpb(cC-6~%Czjji+kosdzO!EuXw(^*abtY ziCSp+#`D$5!SXCNh8==;+IWn|7rwLfhahg|QSLXAIPhLrxk~wA@1JLQaOE{Qj5v^^ zQMSZ~{4OuXA}B;UkeldFTteE5T#^pl0Wa)MiSI%E#JGWd z{J$2MRmTjty>Q*Ey#AP3X_+D1N{25}!iJj_uPbIHaj0;sg*@;ohd=o&>Zm*|i?~o1 zCiaXc121{igu6ILL+}F6^dPR3o3yGUubRk_?H7%AlEDK)1Ie>Om^bbGkD7QZ_*Dxl zX0f?j$|$VSS1oK!m2)VW$Q^O{+)Vdy)G2#+!6(ce_pXVH`68!DR~dUvHBQ=o5c7@F z-S(U9$UJInj!I|i)ayK?uCn<9{Mx4 z#JOph%tnh;*DPuBuWqb%DhUBDB8UoV&LVgbV95>P&S^BMixjVQZxkb!ALU@ zI|{W+?>7wJgW)p(K154I+_X#c>yKDG5wk!1b;jKjY5F0Yx8@m7nt!%xj7zj_^rU_B zM4P8i*AsCEps(+T(-Lg2eyEpokESUL0N;FLRvyeUs~*TYng;EyNnPzqB@gyL%m_=?hob=ZPXG2m})v_2HiZ0+>1i8hqAk-c6`cG+UB zV5cHeWc-w`DXO$~CVtUM6^xg%G(yFD0D9Uc6=z~6P6!fqV)#Zbb|xKX^I=R+Z{$f( zS70K3Sx-&Kub#>#^viCYiah_*s60K9Py2q1kT=rypwwKjHze9l;`aA&VHrD*54p;= zgvc{8ylq=m!=8Qe-=%+Be%8}}C^(d@IVGj!Ho?&*E7!?5Y}5Sv)DYva?nqf&1EYsW zB!nkLHI9u>iB1ZSOo<&Ln`tF6H6kuH5JW z#mVhfC-+~FAJ|8fwyW6FV(nya*b#-@D!I286GzP2gf<28_!}DeZu0Bu*Ugjf08Ewi#jh`RyTF*Q(P&F>>H;~ zDJ^>Q#Vdu`p0H&iPqD2cC$Viap%wGQctl8Z&CZCdF`_k~u7a8w>Oi#7lx;B@=O+xQ z$&rDSsG|L(_M5$Mq0MGJjZ^uCxi`9QJ$`Z{W0m7Kqu3qQSB@8`spZK_#aH`0<6@)Z zQ%q5@$&m^1@zIcTn01d&NE#F#7boSL;6&LLveZ~&MZ>{SUw{8b)iGC04fWx!`F1>72%VVDDOx9%76ct4d{k`(hh1RF#oJb4l(i zoSy6p4N`MX$tuPyjwq?8V}vS=HJu7mV!al!n$%+ifo`i4lEA>8-&dG>_a^D_neitze#hs}M%_hh0EPb9V&9sHafwF}-df}T1?(`vg z7#yb>^MvFEE!P?)*pC~EaDoOLYf0a?k9TZ2!nrr+`Hgxgp89RUNGL!ZN!gEmn4*u$ z4=e%N^pn!xsBW-cOFq;jzNEb7Vw?{t18nI>t^X|^ws3N#%a!uMM)Cl^!52G zo_-!VUn>#WpK`wZs8^?S)VHZdMQT!dsjcd>){oRIuvMU?V$MIy6?;CA6QKZq#A&kn zwcv@l74t8)S_;-Z%53(8sR8GBoqW|smD0ADP)kEC5p_~p-0Z>X%gFf{jbs}8uSuY& zkYKi0bXGN0)R%O~*CtW35~()q!SZ4c?yvxC49uH34k^!GJ!1*8wjB9t2bZybV|gSa2#$Spk><*a!Fyuo=n-nVn<=ws3n(7Q4(`geW2dUvhtr7L^b(U1m(muErW z`V<_|Cj{jo`u;)a6-s%-9LV@s8UlA)pSH0V^v~~2AnU{qcc~R|OdETj&cz=F+=$`L zPAMr6ygw?CBzX=;O2ZBWS^1gf?eu??-&q$D*J;VBebhv}E+#g_LJoX3D2) zvW6I*WFDRI&3&8P^~!Z+!%T$XS*7eGta{yOJ$sn!&2Vrt&Q1+DVUbf6bp$Yc$2cvD7AuNg?@rkO4tx! zo5r@vD73)X_w9K~C}0?XS0&slyfsg0G;W@<0Qa`I$IY0h^qwZZ`{KQd)$ie{^OPXG z_X8vX(g5jz1pr>F`Ti#SOcC$Ch%eLnZ5ZNYyu5gyYJJ{}@4Er~&MOPg+14=f`HJ^-WE`;%RI#&_wImx0DU}-@GirT!Lye&u9Vm3DI)=m-ay#N^OQ;H z$Pezsy%F*d2Vj1007!!Y@Vgg&L*d5@ZluXhyvJG78;LvfItlj~fO%H;1-LH-tOl&N zx^2gOHy{f@dTqDn{UY9P07_2~c?d-rj05Zi9V=Mf7`BS_*@U~B_1O(+dsv?j1FwF- zlUED4G5+o|L32O~pe+IJYjEEQ*aX-Mhyr8)#sC!Lk8xbYvl)JU>4uB>^u>F3KtDhn zfL99cX@GR=`ziRFif743$w^-M8I34<5_Um{II2Sg`DoA4MPJ}A0fy*kPD6lFHz&#fYsJCjlLK5jdaRH*zJJ5fWy{!&f<7@j^lO?s-FPt`UiR@+gWnbaf51pU zI)E45*8q&%cRFy-cHmwK_01@r76$JAa3h`i;m%9{%zDc!E)BeIedasse!BIYGN3hp z7wa^y+3?T$&TBQES*Olg-zh6*0C-V$@Y)VPlnwG?-I4xTX7jAyC|}a7@{w|e*I|UE zyy0~N&y)%CtnY0hYve__6J&j-Y~nQr{!i)rT*R|Xm$HkO*C=sUU+^;kxQqj|1|Ho3 z)sa?fKzBfjHC@usUiL72Y494`3)TZSfCs<~psWuC^aBh4kT-_`SZAgJ*tRSMkXP3O zHUoA7SiiCW*?_ZvD*y#)y8@~JOn^p!7J#+@UjT8VTqBd%?fIHB2b({jAUQ$9f~%N7f0} z1=a!CR+87rk)$)d1B2CO{)VZEK%}Z5`V#wtsBj*#5D7n+jlC$2M>ifbAgLK&E>b zcjC;pkL@7wB7VHs&Mttvj9=c_k0Or~SNiA0J_5gc0C>q~**|IvciA87hvzszB7l7} zNiQ|ve?R|cC=eK+D4zadA)(&ECO-2D_71Rg_Ewb8Kzs}I59w-*pcB9ujH^^$Q90^9)g=P~!{<4Ggw)Kw`MM`GxuhhKcwC z{k&9P7B4STScrEpzpHUtU%CYbccNQpuq7bG;u-2^MLsAPL)~C+Rm~E^srwYHvrb4- z_wYpzOAL>XijHEqnAqsJsO0EGHI6`2h^4D{P@rFcns`cTVqA1`--LMUtba;)L|k-u zN=gzuCx-Xuc0eU5Iufyp2>dO<9lT9}?K^sVs^Q!F1z3W6V2&?1uruTL^7i-Z><0?t zS<=Tdq^siVZSkUGm$1N4QouXJ(-MRSpTJ;GZWk&O!bb)vMwi;2G%U z7obiphJ}cS_MySvjK|j!;)|Qo0mSAV>3cJjf1oD{KoF|EH&TI{#Yf;32s|uao&CrH z{0Zq1;zuI-1%!A9g!qLDO#<9Kg9BN@0ic=nQSl554qc9Fn4GAEKSf!(<8!Ho1kMpgluPk?wFG7#q(o^&;z;$cOro z5aW#tPfj*Pn$#je0H6)eTAcOkn=Aod!hzVEYP@Kw*QYNAK@P5hxa#SWVnY`-8OJmc z)mF_fatX{DsZvE!1?8d*>h$!>k5>9r9aOS`4p9PkU096_);wu+^9wM!)r+lXjmS2P zDh>3RQ>iD@WK?QAj`OF-Ip3=cZ-+yO#KF!z$)S5A6A;Hw2!Do1ZvrQkC)B(p8F;bx zlONbB_f1_b{$a8%$!AN44#D0Xgiu1gR_mWR^O0S z6XJ(NCnck%S-CYiH9}ZFal1)ujhZ&96II_jc(<0Z(ap;eYH4o~f~Rmiqry`h;)!qJ z5#hU_cw7MQSK0K}-P*>&EO)-}V z=rA`Kv4oAAUx1f)cen%wc?Vn2U*Sizf@(u$@kH|yVhZs^r^D1a(Auiudzknh9N4Yk zM}#k&4oRtT(GD4nACsLfDjAb5$Hd>!MSQ)xvqy-ARhOXLiW*i9hnB7cskfIgZ5Z6H0=!nX2) zkrzev6B1+*sobpmlM^Ey(noE7ibfzAos$G&KZ&$J$E-sK(e=IwzoztejBZkFe{`9h zKax z4Eo-l7#@fh(GOSUFN3J#8Q#4EusWr?x2Ltci)VE6RjeTIy+b|OneTvc4)enPI5Xvs zzP&fv1OGsa+Al_$>UgMgpgQG;{&}dM4=}TihnNid!%~v*+27mRd-6SsZi&PB&O2CUKnlO&J&F(xhyX+aJQY6-4b*{*$=|!Hw>sQ}dld2^Xwf^$ z3-2+2{(x9O93UQ$07wKR13~~PfKb2?K&sL^8fisG4oG0S(eaT9QCI-ZXH4Do#zXG` zq+1XQ+FIfHZ9sG!2Mj0`Ka0O#Px+-c3axi6AdZmGH+E1WW**=X7vC`!wRw+=O;*41 zTWWkHw_m2>p7ZEy2(olv9-gCQFFPemGBW$X7rB#x>|q zn$&?b-58g>Oa)&kAzl2HAZ%IbpA?-;e;uNs1Bh3Y9-T4k+qs9**{cWS1nOLBQbJ-h zzhEqz5U+pb*gCjJkf3f@fc{O^bFcPlxIj_s#hd&lr4Yx+;=6PaZ?fkA`uh0f`;o4G z0T?7xun;dOB;=cappa7mf%1uU%HI##k$_M?Q3pc8&_S^#77(a^7Wr%yZXeZv!#3fGso?s<`Ylk-GYLJAI~11YFij&2?>FYMwLwr zTX=r}<5kgsX#KuO>$F||C{6TD-Rf|lir!KGlmTv>mcvL@^!+%5#n{Gr$+0jQfn#KY zF)*wusx6ZYVr`-v3@WS*lRBD^gEeOCCRgG4hEl1Jd{gBV8mdr2_q-~b@AUqXN_O} z0XqAk-Esr{Ex1GMvpuwuy`EHI)U$J!>H>RrIV87t7sEVzSFNFStN^s~g~Z4Kqe{&I z`PqOC{=OcQ*l`Ia<{gCZ{GwC#f%NaRvM7$&5fy%Y{QHlT3X~K@a#CpUmCk3Gv1rlB1KU<}?0C z)-e8p-I?|3o1o4vFvettog-@@6u13ULUb=kEh{lh;i)MD5|Uy^ggd5NaT6c}8ZD{3 zwd*NT@_xxlQ4I;Vl3WHEn1N#va3*Feh3uxcV&;_XcF zvP;G(uy}W?dXbZ9n%p!jKoaIA7jzC*T83KhL)5!$t-LrEhKgU`(?hCK8__o

    O1X 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

    OtTD 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%0DeMucv?D+CvivAX~LYkaDx{28Ht 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

    SgXMpPs8%4#v%Mij0S((eNwPZ*wIg) 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

    hc?r0z2BYG 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 JcXhW<^Y!l0zz*?2f{t%w_; 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∨t^S3}IR*iX{TG+H8NzMB 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 + txtCreated->Disable(); + txtChanged->Disable(); + txtNextrun->Disable(); + txtLastrun->Disable(); + txtLastresult->Disable(); + lstSteps->CreateColumns(0, _("Step"), _("Comment"), 90); + lstSteps->AddColumn(wxT("cmd"), 0); + lstSteps->AddColumn(wxT("id"), 0); + + lstSchedules->CreateColumns(0, _("Schedule"), _("Comment"), 90); + lstSchedules->AddColumn(wxT("cmd"), 0); + lstSchedules->AddColumn(wxT("id"), 0); + btnChangeStep->Disable(); + btnRemoveStep->Disable(); + btnChangeSchedule->Disable(); + btnRemoveSchedule->Disable(); +} + + +pgObject *dlgJob::GetObject() +{ + return job; +} + + +#ifdef __WXMAC__ +void dlgJob::OnChangeSize(wxSizeEvent &ev) +{ + lstSteps->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350); + lstSchedules->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + + +int dlgJob::Go(bool modal) +{ + int returncode; + + pgSet *jcl = connection->ExecuteSet(wxT("SELECT jclname FROM pgagent.pga_jobclass")); + if (jcl) + { + while (!jcl->Eof()) + { + cbJobclass->Append(jcl->GetVal(0)); + jcl->MoveNext(); + } + delete jcl; + } + + if (job) + { + // edit mode + recId = job->GetRecId(); + txtID->SetValue(NumToStr(recId)); + cbJobclass->SetValue(job->GetJobclass()); + chkEnabled->SetValue(job->GetEnabled()); + txtHostAgent->SetValue(job->GetHostAgent()); + txtCreated->SetValue(DateToStr(job->GetCreated())); + txtChanged->SetValue(DateToStr(job->GetChanged())); + txtNextrun->SetValue(DateToStr(job->GetNextrun())); + txtLastrun->SetValue(DateToStr(job->GetLastrun())); + txtLastresult->SetValue(job->GetLastresult()); + + wxCookieType cookie; + pgObject *data = 0; + + wxTreeItemId item, stepsItem, schedulesItem; + item = mainForm->GetBrowser()->GetFirstChild(job->GetId(), cookie); + while (item) + { + data = mainForm->GetBrowser()->GetObject(item); + if (data->GetMetaType() == PGM_STEP) + stepsItem = item; + else if (data->GetMetaType() == PGM_SCHEDULE) + schedulesItem = item; + + item = mainForm->GetBrowser()->GetNextChild(job->GetId(), cookie); + } + + if (stepsItem) + { + pgCollection *coll = (pgCollection *)data; + // make sure all columns are appended + coll->ShowTreeDetail(mainForm->GetBrowser()); + // this is the columns collection + item = mainForm->GetBrowser()->GetFirstChild(stepsItem, cookie); + + // add columns + while (item) + { + data = mainForm->GetBrowser()->GetObject(item); + if (data->IsCreatedBy(stepFactory)) + { + pgaStep *step = (pgaStep *)data; + int pos = lstSteps->AppendItem(stepFactory.GetIconId(), step->GetName(), step->GetComment()); + lstSteps->SetItem(pos, 3, NumToStr((long)step)); + previousSteps.Add(NumToStr((long)step)); + } + item = mainForm->GetBrowser()->GetNextChild(stepsItem, cookie); + } + } + + if (schedulesItem) + { + pgCollection *coll = (pgCollection *)data; + // make sure all columns are appended + coll->ShowTreeDetail(mainForm->GetBrowser()); + // this is the columns collection + item = mainForm->GetBrowser()->GetFirstChild(schedulesItem, cookie); + + // add columns + while (item) + { + data = mainForm->GetBrowser()->GetObject(item); + if (data->IsCreatedBy(scheduleFactory)) + { + pgaSchedule *schedule = (pgaSchedule *)data; + int pos = lstSchedules->AppendItem(scheduleFactory.GetIconId(), schedule->GetName(), schedule->GetComment()); + lstSchedules->SetItem(pos, 3, NumToStr((long)schedule)); + previousSchedules.Add(NumToStr((long)schedule)); + } + item = mainForm->GetBrowser()->GetNextChild(schedulesItem, cookie); + } + } + } + else + { + // create mode + cbJobclass->SetSelection(0); + btnChangeStep->Hide(); + btnChangeSchedule->Hide(); + } + + returncode = dlgProperty::Go(modal); + + SetSqlReadOnly(true); + + // This fixes a UI glitch on MacOS X + // Because of the new layout code, the Columns pane doesn't size itself properly + SetSize(GetSize().GetWidth() + 1, GetSize().GetHeight()); + SetSize(GetSize().GetWidth() - 1, GetSize().GetHeight()); + + return returncode; +} + + +pgObject *dlgJob::CreateObject(pgCollection *collection) +{ + pgObject *obj = jobFactory.CreateObjects(collection, 0, wxT(" WHERE jobid=") + NumToStr(recId) + wxT("\n")); + return obj; +} + + +void dlgJob::CheckChange() +{ + bool enable = true; + wxString name = GetName(); + if (job) + { + enable = txtComment->GetValue() != job->GetComment() + || name != job->GetName() + || chkEnabled->GetValue() != job->GetEnabled() + || txtHostAgent->GetValue() != job->GetHostAgent(); + if (!enable) + { + enable = !GetUpdateSql().IsEmpty(); + } + } + + if (statusBar) + statusBar->SetStatusText(wxEmptyString); + + CheckValid(enable, !txtName->GetValue().IsEmpty(), _("Please specify name.")); + + EnableOK(enable); +} + + +void dlgJob::OnChangeStep(wxCommandEvent &ev) +{ + long pos = lstSteps->GetSelection(); + pgaStep *obj = (pgaStep *) StrToLong(lstSteps->GetText(pos, 3)); + + dlgStep step(&stepFactory, mainForm, obj, job); + step.CenterOnParent(); + step.SetConnection(connection); + + if (step.Go(true) != wxID_CANCEL) + { + lstSteps->SetItem(pos, 0, step.GetName()); + lstSteps->SetItem(pos, 1, step.GetComment()); + + if (lstSteps->GetText(pos, 3).IsEmpty()) + { + wxString *stepSql = new wxString(step.GetInsertSql()); + lstSteps->SetItemData(pos, (long)stepSql); + } + else + { + wxString *stepSql = new wxString(step.GetUpdateSql()); + lstSteps->SetItemData(pos, (long)stepSql); + } + + CheckChange(); + } +} + + +void dlgJob::OnSelChangeStep(wxListEvent &ev) +{ + btnChangeStep->Enable(); + btnRemoveStep->Enable(); +} + + +void dlgJob::OnAddStep(wxCommandEvent &ev) +{ + dlgStep step(&stepFactory, mainForm, NULL, job); + step.CenterOnParent(); + step.SetConnection(connection); + if (step.Go(true) != wxID_CANCEL) + { + int pos = lstSteps->AppendItem(stepFactory.GetIconId(), step.GetName(), step.GetComment()); + wxString *stepSql = new wxString(step.GetInsertSql()); + lstSteps->SetItemData(pos, (long)stepSql); + CheckChange(); + } +} + + +void dlgJob::OnRemoveStep(wxCommandEvent &ev) +{ + delete (wxString *)lstSteps->GetItemData(lstSteps->GetSelection()); + lstSteps->DeleteCurrentItem(); + + btnChangeStep->Disable(); + btnRemoveStep->Disable(); + + CheckChange(); +} + + +void dlgJob::OnSelChangeSchedule(wxListEvent &ev) +{ + btnChangeSchedule->Enable(); + btnRemoveSchedule->Enable(); +} + + +void dlgJob::OnChangeSchedule(wxCommandEvent &ev) +{ + long pos = lstSchedules->GetSelection(); + pgaSchedule *obj = (pgaSchedule *) StrToLong(lstSchedules->GetText(pos, 3)); + + dlgSchedule schedule(&scheduleFactory, mainForm, obj, job); + schedule.CenterOnParent(); + schedule.SetConnection(connection); + + if (schedule.Go(true) != wxID_CANCEL) + { + lstSchedules->SetItem(pos, 0, schedule.GetName()); + lstSchedules->SetItem(pos, 1, schedule.GetComment()); + + if (lstSchedules->GetText(pos, 3).IsEmpty()) + { + wxString *scheduleSql = new wxString(schedule.GetInsertSql()); + lstSchedules->SetItemData(pos, (long)scheduleSql); + } + else + { + wxString *scheduleSql = new wxString(schedule.GetUpdateSql()); + lstSchedules->SetItemData(pos, (long)scheduleSql); + } + + CheckChange(); + } +} + + +void dlgJob::OnAddSchedule(wxCommandEvent &ev) +{ + dlgSchedule schedule(&scheduleFactory, mainForm, NULL, job); + schedule.CenterOnParent(); + schedule.SetConnection(connection); + if (schedule.Go(true) != wxID_CANCEL) + { + int pos = lstSchedules->AppendItem(scheduleFactory.GetIconId(), schedule.GetName(), schedule.GetComment()); + wxString *scheduleSql = new wxString(schedule.GetInsertSql()); + lstSchedules->SetItemData(pos, (long)scheduleSql); + CheckChange(); + } +} + + +void dlgJob::OnRemoveSchedule(wxCommandEvent &ev) +{ + delete (wxString *)lstSchedules->GetItemData(lstSchedules->GetSelection()); + lstSchedules->DeleteCurrentItem(); + + btnChangeSchedule->Disable(); + btnRemoveSchedule->Disable(); + + CheckChange(); +} + + +wxString dlgJob::GetInsertSql() +{ + wxString sql; + + if (!job) + { + sql = wxT("INSERT INTO pgagent.pga_job (jobid, jobjclid, jobname, jobdesc, jobenabled, jobhostagent)\n") + wxT("SELECT , jcl.jclid, ") + qtDbString(GetName()) + + wxT(", ") + qtDbString(txtComment->GetValue()) + wxT(", ") + BoolToStr(chkEnabled->GetValue()) + + wxT(", ") + qtDbString(txtHostAgent->GetValue()) + wxT("\n") + wxT(" FROM pgagent.pga_jobclass jcl WHERE jclname=") + qtDbString(cbJobclass->GetValue()) + wxT(";\n"); + } + return sql; +} + + +wxString dlgJob::GetUpdateSql() +{ + wxString sql, name; + name = GetName(); + + if (job) + { + // edit mode + wxString vars; + + if (name != job->GetName()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jobname = ") + qtDbString(name)); + } + if (cbJobclass->GetValue().Trim() != job->GetJobclass()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jobjclid= (SELECT jclid FROM pgagent.pga_jobclass WHERE jclname=") + qtDbString(cbJobclass->GetValue()) + wxT(")")); + } + if (chkEnabled->GetValue() != job->GetEnabled()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jobenabled = ") + BoolToStr(chkEnabled->GetValue())); + } + if (txtHostAgent->GetValue() != job->GetHostAgent()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jobhostagent = ") + qtDbString(txtHostAgent->GetValue())); + } + if (txtComment->GetValue() != job->GetComment()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jobdesc = ") + qtDbString(txtComment->GetValue())); + } + + if (!vars.IsEmpty()) + sql = wxT("UPDATE pgagent.pga_job SET ") + vars + wxT("\n") + wxT(" WHERE jobid=") + NumToStr(recId) + wxT(";\n"); + + } + else + { + // create mode + // done by GetInsertSql + } + + int pos, index; + + wxArrayString tmpSteps = previousSteps; + for (pos = 0 ; pos < lstSteps->GetItemCount() ; pos++) + { + wxString str = lstSteps->GetText(pos, 3); + if (!str.IsEmpty()) + { + index = tmpSteps.Index(str); + if (index >= 0) + tmpSteps.RemoveAt(index); + } + + if(lstSteps->GetItemData(pos)) + { + str = *(wxString *)lstSteps->GetItemData(pos); + if (!str.IsEmpty()) + sql += str; + } + } + + for (index = 0 ; index < (int)tmpSteps.GetCount() ; index++) + { + sql += wxT("DELETE FROM pgagent.pga_jobstep WHERE jstid=") + + NumToStr(((pgaStep *)StrToLong(tmpSteps.Item(index)))->GetRecId()) + wxT(";\n"); + } + + wxArrayString tmpSchedules = previousSchedules; + for (pos = 0 ; pos < lstSchedules->GetItemCount() ; pos++) + { + wxString str = lstSchedules->GetText(pos, 3); + if (!str.IsEmpty()) + { + index = tmpSchedules.Index(str); + if (index >= 0) + tmpSchedules.RemoveAt(index); + } + if(lstSchedules->GetItemData(pos)) + { + str = *(wxString *)lstSchedules->GetItemData(pos); + if (!str.IsEmpty()) + sql += str; + } + } + + for (index = 0 ; index < (int)tmpSchedules.GetCount() ; index++) + { + sql += wxT("DELETE FROM pgagent.pga_schedule WHERE jscid=") + + NumToStr(((pgaStep *)StrToLong(tmpSchedules.Item(index)))->GetRecId()) + wxT(";\n"); + } + + return sql; + +} diff --git a/agent/dlgSchedule.cpp b/agent/dlgSchedule.cpp new file mode 100644 index 0000000..f50e925 --- /dev/null +++ b/agent/dlgSchedule.cpp @@ -0,0 +1,859 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgSchedule.cpp - PostgreSQL Schedule Property +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// App headers +#include "utils/misc.h" +#include "agent/dlgSchedule.h" +#include "agent/pgaSchedule.h" + +// image for de/-select all +#include "images/check.pngc" +#include "images/uncheck.pngc" + +// pointer to controls +#define txtID CTRL_TEXT("txtID") +#define chkEnabled CTRL_CHECKBOX("chkEnabled") +#define calStart CTRL_CALENDAR("calStart") +#define timStart CTRL_TIME("timStart") +#define calEnd CTRL_CALENDAR("calEnd") +#define timEnd CTRL_TIME("timEnd") +#define chkWeekdays CTRL_CHECKLISTBOX("chkWeekdays") +#define chkMonthdays CTRL_CHECKLISTBOX("chkMonthdays") +#define chkMonths CTRL_CHECKLISTBOX("chkMonths") +#define chkHours CTRL_CHECKLISTBOX("chkHours") +#define chkMinutes CTRL_CHECKLISTBOX("chkMinutes") +#define lstExceptions CTRL_LISTVIEW("lstExceptions") +#define timException CTRL_TIME("timException") +#define calException CTRL_CALENDAR("calException") +#define btnAddException CTRL_BUTTON("btnAddException") +#define btnChangeException CTRL_BUTTON("btnChangeException") +#define btnRemoveException CTRL_BUTTON("btnRemoveException") +#define btnWeekdays CTRL_BUTTON("btnWeekdays") +#define btnMonthdays CTRL_BUTTON("btnMonthdays") +#define btnMonths CTRL_BUTTON("btnMonths") +#define btnHours CTRL_BUTTON("btnHours") +#define btnMinutes CTRL_BUTTON("btnMinutes") + +BEGIN_EVENT_TABLE(dlgSchedule, dlgAgentProperty) + EVT_CHECKBOX(XRCID("chkEnabled"), dlgSchedule::OnChangeCom) + EVT_CALENDAR_SEL_CHANGED(XRCID("calStart"), dlgSchedule::OnChangeCal) + EVT_TEXT(XRCID("timStart"), dlgSchedule::OnChangeCom) + EVT_CALENDAR_SEL_CHANGED(XRCID("calEnd"), dlgSchedule::OnChangeCal) + EVT_TEXT(XRCID("timEnd"), dlgSchedule::OnChangeCom) + EVT_LIST_ITEM_SELECTED(XRCID("lstExceptions"), dlgSchedule::OnSelChangeException) + EVT_BUTTON(XRCID("btnAddException"), dlgSchedule::OnAddException) + EVT_BUTTON(XRCID("btnChangeException"), dlgSchedule::OnChangeException) + EVT_BUTTON(XRCID("btnRemoveException"), dlgSchedule::OnRemoveException) + EVT_BUTTON(XRCID("btnWeekdays"), dlgSchedule::OnSelectAllWeekdays) + EVT_BUTTON(XRCID("btnMonthdays"), dlgSchedule::OnSelectAllMonthdays) + EVT_BUTTON(XRCID("btnMonths"), dlgSchedule::OnSelectAllMonths) + EVT_BUTTON(XRCID("btnHours"), dlgSchedule::OnSelectAllHours) + EVT_BUTTON(XRCID("btnMinutes"), dlgSchedule::OnSelectAllMinutes) + EVT_CHECKLISTBOX(XRCID("chkWeekdays"), dlgSchedule::OnChangeCom) + EVT_CHECKLISTBOX(XRCID("chkMonthdays"), dlgSchedule::OnChangeCom) + EVT_CHECKLISTBOX(XRCID("chkMonths"), dlgSchedule::OnChangeCom) + EVT_CHECKLISTBOX(XRCID("chkHours"), dlgSchedule::OnChangeCom) + EVT_CHECKLISTBOX(XRCID("chkMinutes"), dlgSchedule::OnChangeCom) +#ifdef __WXMAC__ + EVT_SIZE( dlgSchedule::OnChangeSize) +#endif +END_EVENT_TABLE(); + + +dlgProperty *pgaScheduleFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgSchedule(this, frame, (pgaSchedule *)node, (pgaJob *)parent); +} + + +dlgSchedule::dlgSchedule(pgaFactory *f, frmMain *frame, pgaSchedule *node, pgaJob *j) + : dlgAgentProperty(f, frame, wxT("dlgSchedule")) +{ + schedule = node; + job = j; + if (job) + jobId = job->GetRecId(); + else + jobId = 0; + + lstExceptions->CreateColumns(0, _("Date"), _("Time"), 90); + lstExceptions->AddColumn(wxT("dirty"), 0); + lstExceptions->AddColumn(wxT("id"), 0); + + txtID->Disable(); + + btnChangeException->Disable(); + btnRemoveException->Disable(); + + int i; + + for (i = 0 ; i < 24 ; i++) + chkHours->Append(wxString::Format(wxT("%02d"), i)); + + for (i = 0 ; i < 60 ; i++) + chkMinutes->Append(wxString::Format(wxT("%02d"), i)); +} + + +pgObject *dlgSchedule::GetObject() +{ + return schedule; +} + + +#ifdef __WXMAC__ +void dlgSchedule::OnChangeSize(wxSizeEvent &ev) +{ + lstExceptions->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + + +int dlgSchedule::Go(bool modal) +{ + int returncode; + + if (schedule) + { + // edit mode + recId = schedule->GetRecId(); + txtID->SetValue(NumToStr(recId)); + chkEnabled->SetValue(schedule->GetEnabled()); + calStart->SetValue(schedule->GetStart().GetDateOnly()); + timStart->SetTime(schedule->GetStart()); + if (schedule->GetEnd().IsValid()) + { + calEnd->SetValue(schedule->GetEnd().GetDateOnly()); + timEnd->SetTime(schedule->GetEnd()); + } + else + { + calEnd->SetValue(wxInvalidDateTime); + timEnd->SetTime(wxInvalidDateTime); + timEnd->Disable(); + } + + unsigned int x; + for (x = 0; x < schedule->GetMonths().Length(); x++ ) + if (schedule->GetMonths()[x] == 't') chkMonths->Check(x, true); + + for (x = 0; x < schedule->GetMonthdays().Length(); x++ ) + if (schedule->GetMonthdays()[x] == 't') chkMonthdays->Check(x, true); + + for (x = 0; x < schedule->GetWeekdays().Length(); x++ ) + if (schedule->GetWeekdays()[x] == 't') chkWeekdays->Check(x, true); + + for (x = 0; x < schedule->GetHours().Length(); x++ ) + if (schedule->GetHours()[x] == 't') chkHours->Check(x, true); + + for (x = 0; x < schedule->GetMinutes().Length(); x++ ) + if (schedule->GetMinutes()[x] == 't') chkMinutes->Check(x, true); + + wxString id, dateToken, timeToken; + wxDateTime val; + long pos = 0; + wxStringTokenizer tkz(schedule->GetExceptions(), wxT("|")); + + while (tkz.HasMoreTokens() ) + { + dateToken.Empty(); + timeToken.Empty(); + + // First is the ID + id = tkz.GetNextToken(); + + // Look for a date + if (tkz.HasMoreTokens()) + dateToken = tkz.GetNextToken(); + + // Look for a time + if (tkz.HasMoreTokens()) + timeToken = tkz.GetNextToken(); + + if (!dateToken.IsEmpty() && !timeToken.IsEmpty()) + { + val.ParseDate(dateToken); + val.ParseTime(timeToken); + pos = lstExceptions->AppendItem(0, val.FormatDate(), val.FormatTime()); + } + else if (!dateToken.IsEmpty() && timeToken.IsEmpty()) + { + val.ParseDate(dateToken); + pos = lstExceptions->AppendItem(0, val.FormatDate(), _("")); + } + else if (dateToken.IsEmpty() && !timeToken.IsEmpty()) + { + val.ParseTime(timeToken); + pos = lstExceptions->AppendItem(0, _(""), val.FormatTime()); + } + + lstExceptions->SetItem(pos, 2, BoolToStr(false)); + lstExceptions->SetItem(pos, 3, id); + + } + + wxNotifyEvent ev; + } + else + { + // create mode + } + + // setup de-/select buttons + InitSelectAll(); + + returncode = dlgProperty::Go(modal); + + SetSqlReadOnly(true); + + return returncode; +} + + +pgObject *dlgSchedule::CreateObject(pgCollection *collection) +{ + pgObject *obj = scheduleFactory.CreateObjects(collection, 0, wxT(" AND jscid=") + NumToStr(recId) + wxT("\n")); + return obj; +} + + +void dlgSchedule::OnChangeCal(wxCalendarEvent &ev) +{ + CheckChange(); +} + + +void dlgSchedule::OnChangeCom(wxCommandEvent &ev) +{ + CheckChange(); +} + + +void dlgSchedule::CheckChange() +{ + timEnd->Enable(calEnd->GetValue().IsValid()); + + wxString name = GetName(); + bool enable = true; + + if (statusBar) + statusBar->SetStatusText(wxEmptyString); + + InitSelectAll(); + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, calStart->GetValue().IsValid(), _("Please specify start date.")); + + if (enable) + { + EnableOK(!GetSql().IsEmpty()); + } + else + EnableOK(false); +} + + +void dlgSchedule::OnSelChangeException(wxListEvent &ev) +{ + int sel = lstExceptions->GetSelection(); + if (sel >= 0) + { + wxString exDate = lstExceptions->GetText(sel, 0); + wxString exTime = lstExceptions->GetText(sel, 1); + wxDateTime val, null; + + if (exDate == _("")) + calException->SetValue(null); + else + { + val.ParseDate(exDate); + calException->SetValue(val); + } + if (exTime == _("")) + timException->SetTime(null); + else + { + val.ParseTime(exTime); + timException->SetTime(val); + } + + btnChangeException->Enable(); + btnRemoveException->Enable(); + } +} + + +void dlgSchedule::OnAddException(wxCommandEvent &ev) +{ + if (!calException->GetValue().IsValid() && timException->GetValue().IsNull()) + { + wxMessageBox(_("You must enter a valid date and/or time!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this); + return; + } + + wxString exDate, exTime; + + if (calException->GetValue().IsValid()) + exDate = calException->GetValue().FormatDate(); + else + exDate = _(""); + + if (!timException->GetValue().IsNull()) + exTime = timException->GetValue().Format(); + else + exTime = _(""); + + for (int pos = 0; pos < lstExceptions->GetItemCount(); pos++) + { + + if (lstExceptions->GetText(pos, 0) == exDate && + lstExceptions->GetText(pos, 1) == exTime) + { + wxMessageBox(_("The specified exception already exists!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this); + return; + } + + if (lstExceptions->GetText(pos, 0) == exDate && + lstExceptions->GetText(pos, 1) == _("")) + { + wxMessageBox(_("An exception already exists for any time on this date!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this); + return; + } + + if (lstExceptions->GetText(pos, 1) == exTime && + lstExceptions->GetText(pos, 0) == _("")) + { + wxMessageBox(_("An exception already exists for this time on any date!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this); + return; + } + } + + lstExceptions->AppendItem(0, exDate, exTime); + CheckChange(); +} + + +void dlgSchedule::OnChangeException(wxCommandEvent &ev) +{ + if (!calException->GetValue().IsValid() && timException->GetValue().IsNull()) + { + wxMessageBox(_("You must enter a valid date and/or time!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this); + return; + } + + wxString exDate, exTime; + + if (calException->GetValue().IsValid()) + exDate = calException->GetValue().FormatDate(); + else + exDate = _(""); + + if (!timException->GetValue().IsNull()) + exTime = timException->GetValue().Format(); + else + exTime = _(""); + + long item = lstExceptions->GetFocusedItem(); + + for (int pos = 0; pos < lstExceptions->GetItemCount(); pos++) + { + if (item != pos) + { + if (lstExceptions->GetText(pos, 0) == exDate && + lstExceptions->GetText(pos, 1) == exTime) + { + wxMessageBox(_("The specified exception already exists!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this); + return; + } + + if (lstExceptions->GetText(pos, 0) == exDate && + lstExceptions->GetText(pos, 1) == _("")) + { + wxMessageBox(_("An exception already exists for any time on this date!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this); + return; + } + + if (lstExceptions->GetText(pos, 1) == exTime && + lstExceptions->GetText(pos, 0) == _("")) + { + wxMessageBox(_("An exception already exists for this time on any date!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this); + return; + } + } + } + + lstExceptions->SetItem(item, 0, exDate); + lstExceptions->SetItem(item, 1, exTime); + lstExceptions->SetItem(item, 2, BoolToStr(true)); + CheckChange(); +} + + +void dlgSchedule::OnRemoveException(wxCommandEvent &ev) +{ + if (lstExceptions->GetText(lstExceptions->GetFocusedItem(), 3) != wxEmptyString) + { + deleteExceptions.Add(lstExceptions->GetText(lstExceptions->GetFocusedItem(), 3)); + } + lstExceptions->DeleteCurrentItem(); + + btnChangeException->Disable(); + btnRemoveException->Disable(); + + CheckChange(); +} + + +wxString dlgSchedule::GetComment() +{ + return txtComment->GetValue(); +} + + +wxString dlgSchedule::GetInsertSql() +{ + wxString sql; + if (!schedule) + { + wxString name = GetName(); + wxString jscjobid, list = wxT("NULL"); + if (jobId) + jscjobid = NumToStr(jobId); + else + jscjobid = wxT(""); + + // Build the various arrays of values + sql = wxT("INSERT INTO pgagent.pga_schedule (jscid, jscjobid, jscname, jscdesc, jscminutes, jschours, jscweekdays, jscmonthdays, jscmonths, jscenabled, jscstart, jscend)\n") + wxT("VALUES(, ") + jscjobid + wxT(", ") + qtDbString(name) + wxT(", ") + qtDbString(txtComment->GetValue()) + wxT(", ") + + wxT("'") + ChkListBox2PgArray(chkMinutes) + wxT("', ") + + wxT("'") + ChkListBox2PgArray(chkHours) + wxT("', ") + + wxT("'") + ChkListBox2PgArray(chkWeekdays) + wxT("', ") + + wxT("'") + ChkListBox2PgArray(chkMonthdays) + wxT("', ") + + wxT("'") + ChkListBox2PgArray(chkMonths) + wxT("', ") + + BoolToStr(chkEnabled->GetValue()) + wxT(", ") + + wxT("'") + DateToAnsiStr(calStart->GetValue() + timStart->GetValue()) + wxT("'"); + + if (calEnd->GetValue().IsValid()) + sql += wxT(", '") + DateToAnsiStr(calEnd->GetValue() + timEnd->GetValue()) + wxT("'"); + else + sql += wxT(", NULL"); + + sql += wxT(");\n"); + } + + return sql; +} + + +wxString dlgSchedule::GetUpdateSql() +{ + wxString sql, name; + name = GetName(); + + if (schedule) + { + // edit mode + wxString vars; + + if (name != schedule->GetName()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jscname = ") + qtDbString(name)); + } + if (txtComment->GetValue() != schedule->GetComment()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jscdesc = ") + qtDbString(txtComment->GetValue())); + } + + if ((!chkEnabled->IsChecked() && schedule->GetEnabled()) || (chkEnabled->IsChecked() && !schedule->GetEnabled())) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jscenabled = ") + BoolToStr(chkEnabled->IsChecked())); + } + + if (calStart->GetValue() + timStart->GetValue() != schedule->GetStart()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jscstart = '") + DateToAnsiStr(calStart->GetValue() + timStart->GetValue()) + wxT("'")); + } + + if (calEnd->GetValue().IsValid()) + { + if (schedule->GetEnd().IsValid()) + { + if (calEnd->GetValue() + timEnd->GetValue() != schedule->GetEnd()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jscend = '") + DateToAnsiStr(calEnd->GetValue() + timEnd->GetValue()) + wxT("'")); + } + } + else + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jscend = '") + DateToAnsiStr(calEnd->GetValue() + wxTimeSpan()) + wxT("'")); + } + } + else + { + if (schedule->GetEnd().IsValid()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jscend = NULL")); + } + } + + if (ChkListBox2StrArray(chkMinutes) != schedule->GetMinutes()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jscminutes = '") + ChkListBox2PgArray(chkMinutes) + wxT("'")); + } + + if (ChkListBox2StrArray(chkHours) != schedule->GetHours()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jschours = '") + ChkListBox2PgArray(chkHours) + wxT("'")); + } + + if (ChkListBox2StrArray(chkWeekdays) != schedule->GetWeekdays()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jscweekdays = '") + ChkListBox2PgArray(chkWeekdays) + wxT("'")); + } + + if (ChkListBox2StrArray(chkMonthdays) != schedule->GetMonthdays()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jscmonthdays = '") + ChkListBox2PgArray(chkMonthdays) + wxT("'")); + } + + if (ChkListBox2StrArray(chkMonths) != schedule->GetMonths()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jscmonths = '") + ChkListBox2PgArray(chkMonths) + wxT("'")); + } + + if (!vars.IsEmpty()) + sql = wxT("UPDATE pgagent.pga_schedule SET ") + vars + wxT("\n") + wxT(" WHERE jscid=") + NumToStr(recId) + wxT(";\n"); + } + else + { + // create mode + // Handled by GetInsertSQL + } + + unsigned int x = 0; + int y = 0; + wxDateTime tmpDateTime; + wxString newDate, newTime; + + // Remove old exceptions + for (x = 0; x < deleteExceptions.Count(); x++) + { + sql += wxT("DELETE FROM pgagent.pga_exception\n WHERE jexid = ") + deleteExceptions[x] + wxT(";\n"); + } + + // Update dirty exceptions + for (y = 0; y < lstExceptions->GetItemCount(); y++) + { + if (lstExceptions->GetText(y, 2) == BoolToStr(true) && + lstExceptions->GetText(y, 3) != wxEmptyString) + { + if (lstExceptions->GetText(y, 0) == _("")) + newDate = wxT("null"); + else + { + tmpDateTime.ParseFormat(lstExceptions->GetText(y, 0), wxT("%x")); + newDate = wxT("'") + tmpDateTime.FormatISODate() + wxT("'"); + } + + if (lstExceptions->GetText(y, 1) == _("")) + newTime = wxT("null"); + else + { + tmpDateTime.ParseTime(lstExceptions->GetText(y, 1)); + newTime = wxT("'") + tmpDateTime.FormatISOTime() + wxT("'"); + } + + sql += wxT("UPDATE pgagent.pga_exception SET jexdate = ") + newDate + + wxT(", jextime = ") + newTime + wxT("\n WHERE jexid = ") + + lstExceptions->GetText(y, 3) + wxT(";\n"); + } + } + + // Insert new exceptions + for (y = 0; y < lstExceptions->GetItemCount(); y++) + { + if (lstExceptions->GetText(y, 2) == wxEmptyString && + lstExceptions->GetText(y, 3) == wxEmptyString) + { + if (lstExceptions->GetText(y, 0) == _("")) + newDate = wxT("null"); + else + { + tmpDateTime.ParseFormat(lstExceptions->GetText(y, 0), wxT("%x")); + newDate = wxT("'") + tmpDateTime.FormatISODate() + wxT("'"); + } + + if (lstExceptions->GetText(y, 1) == _("")) + newTime = wxT("null"); + else + { + tmpDateTime.ParseTime(lstExceptions->GetText(y, 1)); + newTime = wxT("'") + tmpDateTime.FormatISOTime() + wxT("'"); + } + + sql += wxT("INSERT INTO pgagent.pga_exception (jexscid, jexdate, jextime)\n VALUES (") + + NumToStr(recId) + wxT(", ") + newDate + wxT(", ") + newTime + wxT(");\n"); + + } + } + + + + return sql; +} + + +const wxString dlgSchedule::ChkListBox2PgArray(wxCheckListBox *lb) +{ + wxString res = wxT("{"); + + for (unsigned int x = 0; x < lb->GetCount(); x++) + { + if (lb->IsChecked(x)) + res += wxT("t,"); + else + res += wxT("f,"); + } + if (res.Length() > 1) + res.RemoveLast(); + + res += wxT("}"); + + return res; +} + + +const wxString dlgSchedule::ChkListBox2StrArray(wxCheckListBox *lb) +{ + wxString res; + + for (unsigned int x = 0; x < lb->GetCount(); x++) + { + if (lb->IsChecked(x)) + res += wxT("t"); + else + res += wxT("f"); + } + + return res; +} + + +void dlgSchedule::OnSelectAll(wxCommandEvent &ev, int origin) +{ + bool check = false; + wxBitmapButton *btn; + wxCheckListBox *lb; + wxString tooltip; + + switch (origin) + { + case 1: + btn = ((wxBitmapButton *)btnWeekdays); + lb = chkWeekdays; + break; + case 2: + btn = ((wxBitmapButton *)btnMonthdays); + lb = chkMonthdays; + break; + case 3: + btn = ((wxBitmapButton *)btnMonths); + lb = chkMonths; + break; + case 4: + btn = ((wxBitmapButton *)btnHours); + lb = chkHours; + break; + case 5: + btn = ((wxBitmapButton *)btnMinutes); + lb = chkMinutes; + break; + default: + return; + break; + } + + for (unsigned int x = 0; x < lb->GetCount(); x++) + { + if (!lb->IsChecked(x)) + { + check = true; + break; + } + } + for (unsigned int x = 0; x < lb->GetCount(); x++) + { + lb->Check(x, check); + } + + CheckChange(); +} + + +void dlgSchedule::InitSelectAll() +{ + bool check = false; + wxBitmapButton *btn; + wxCheckListBox *lb; + wxString tooltip; + + btn = ((wxBitmapButton *)btnWeekdays); + lb = chkWeekdays; + for (unsigned int x = 0; x < lb->GetCount(); x++) + { + if (!lb->IsChecked(x)) + { + check = true; + break; + } + } + + if (check) + { + btn->SetBitmapLabel(*check_png_bmp); + tooltip = _("Select all week days"); + } + else + { + btn->SetBitmapLabel(*uncheck_png_bmp); + tooltip = _("Deselect all week days"); + } + btn->SetToolTip(tooltip); + + check = false; + btn = ((wxBitmapButton *)btnMonthdays); + lb = chkMonthdays; + for (unsigned int x = 0; x < lb->GetCount(); x++) + { + if (!lb->IsChecked(x)) + { + check = true; + break; + } + } + + if (check) + { + btn->SetBitmapLabel(*check_png_bmp); + tooltip = _("Select all month days"); + } + else + { + btn->SetBitmapLabel(*uncheck_png_bmp); + tooltip = _("Deselect all month days"); + } + btn->SetToolTip(tooltip); + + check = false; + btn = ((wxBitmapButton *)btnMonths); + lb = chkMonths; + for (unsigned int x = 0; x < lb->GetCount(); x++) + { + if (!lb->IsChecked(x)) + { + check = true; + break; + } + } + + if (check) + { + btn->SetBitmapLabel(*check_png_bmp); + tooltip = _("Select all months"); + } + else + { + btn->SetBitmapLabel(*uncheck_png_bmp); + tooltip = _("Deselect all months"); + } + btn->SetToolTip(tooltip); + + check = false; + btn = ((wxBitmapButton *)btnHours); + lb = chkHours; + for (unsigned int x = 0; x < lb->GetCount(); x++) + { + if (!lb->IsChecked(x)) + { + check = true; + break; + } + } + + if (check) + { + btn->SetBitmapLabel(*check_png_bmp); + tooltip = _("Select all hours"); + } + else + { + btn->SetBitmapLabel(*uncheck_png_bmp); + tooltip = _("Deselect all hours"); + } + btn->SetToolTip(tooltip); + + + check = false; + btn = ((wxBitmapButton *)btnMinutes); + lb = chkMinutes; + for (unsigned int x = 0; x < lb->GetCount(); x++) + { + if (!lb->IsChecked(x)) + { + check = true; + break; + } + } + + if (check) + { + btn->SetBitmapLabel(*check_png_bmp); + tooltip = _("Select all minutes"); + } + else + { + btn->SetBitmapLabel(*uncheck_png_bmp); + tooltip = _("Deselect all minutes"); + } + btn->SetToolTip(tooltip); +} diff --git a/agent/dlgStep.cpp b/agent/dlgStep.cpp new file mode 100644 index 0000000..2641d3d --- /dev/null +++ b/agent/dlgStep.cpp @@ -0,0 +1,483 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgStep.cpp - PostgreSQL Step Property +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "agent/dlgStep.h" +#include "agent/pgaStep.h" +#include "dlg/dlgSelectDatabase.h" +#include "schema/pgTable.h" + + +// pointer to controls +#define txtID CTRL_TEXT("txtID") +#define chkEnabled CTRL_CHECKBOX("chkEnabled") +#define rbxKind CTRL_RADIOBOX("rbxKind") +#define rbxOnError CTRL_RADIOBOX("rbxOnError") +#define pnlDefinition CTRL_PANEL("pnlDefinition") +#define txtSqlBox CTRL_TEXT("txtSqlBox") +#define cbDatabase CTRL_COMBOBOX2("cbDatabase") +#define txtConnStr CTRL_TEXT("txtConnStr") +#define btnSelDatabase CTRL_BUTTON("btnSelDatabase") +#define rbRemoteConn CTRL_RADIOBUTTON("rbRemoteConn") +#define rbLocalConn CTRL_RADIOBUTTON("rbLocalConn") + +#define CTL_SQLBOX 188 + +BEGIN_EVENT_TABLE(dlgStep, dlgAgentProperty) + EVT_CHECKBOX(XRCID("chkEnabled"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbDatabase"), dlgProperty::OnChange) + EVT_RADIOBOX(XRCID("rbxKind"), dlgProperty::OnChange) + EVT_RADIOBOX(XRCID("rbxOnError"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtConnStr"), dlgProperty::OnChange) + EVT_STC_MODIFIED(CTL_SQLBOX, dlgProperty::OnChangeStc) + EVT_BUTTON(XRCID("btnSelDatabase"), dlgStep::OnSelectDatabase) + EVT_RADIOBUTTON(XRCID("rbRemoteConn"), dlgStep::OnSelRemoteConn) + EVT_RADIOBUTTON(XRCID("rbLocalConn"), dlgStep::OnSelLocalConn) +END_EVENT_TABLE(); + + +dlgProperty *pgaStepFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgStep(this, frame, (pgaStep *)node, (pgaJob *)parent); +} + + +dlgStep::dlgStep(pgaFactory *f, frmMain *frame, pgaStep *node, pgaJob *j) + : dlgAgentProperty(f, frame, wxT("dlgStep")) +{ + step = node; + job = j; + if (job) + jobId = job->GetRecId(); + else + jobId = 0; + + sqlBox = new ctlSQLBox(pnlDefinition, CTL_SQLBOX, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_RICH2); + + wxWindow *placeholder = CTRL_TEXT("txtSqlBox"); + wxSizer *sizer = placeholder->GetContainingSizer(); + sizer->Add(sqlBox, 1, wxRIGHT | wxGROW, 5); + sizer->Detach(placeholder); + delete placeholder; + sizer->Layout(); + + + txtID->Disable(); +} + + +pgObject *dlgStep::GetObject() +{ + return step; +} + + +int dlgStep::Go(bool modal) +{ + int returncode; + + hasConnStrSupport = connection->TableHasColumn(wxT("pgagent"), wxT("pga_jobstep"), wxT("jstconnstr")); + cbDatabase->Append(wxT(" ")); + cbDatabase->SetSelection(0); + + pgSet *db = connection->ExecuteSet(wxT("SELECT datname FROM pg_database")); + if (db) + { + while (!db->Eof()) + { + cbDatabase->Append(db->GetVal(0)); + db->MoveNext(); + } + delete db; + } + + if (step) + { + // edit mode + recId = step->GetRecId(); + txtID->SetValue(NumToStr(recId)); + + if (step->HasConnectionString()) + { + rbRemoteConn->SetValue(true); + txtConnStr->Enable(true); + txtConnStr->ChangeValue(step->GetConnStr()); + btnSelDatabase->Enable(true); + cbDatabase->Enable(false); + } + else + { + rbLocalConn->SetValue(true); + if (step->GetDbname().IsEmpty()) + cbDatabase->SetSelection(0); + else + cbDatabase->SetValue(step->GetDbname()); + } + + rbxKind->SetSelection(wxString(wxT("sb")).Find(step->GetKindChar())); + rbxOnError->SetSelection(wxString(wxT("fsi")).Find(step->GetOnErrorChar())); + sqlBox->SetText(step->GetCode()); + + chkEnabled->SetValue(step->GetEnabled()); + } + else + { + // create mode + rbLocalConn->SetValue(true); + cbDatabase->Enable(true); + btnSelDatabase->Enable(false); + txtConnStr->Enable(false); + if (!hasConnStrSupport) + rbLocalConn->Enable(false); + } + + returncode = dlgProperty::Go(modal); + + SetSqlReadOnly(true); + + return returncode; +} + + +pgObject *dlgStep::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + pgObject *obj = stepFactory.CreateObjects(collection, 0, wxT(" AND jstid=") + NumToStr(recId) + wxT("\n")); + return obj; +} + + +void dlgStep::CheckChange() +{ + wxString name = GetName(); + bool enable; + if (step) + { + enable = name != step->GetName() + || chkEnabled->GetValue() != step->GetEnabled() + || rbxKind->GetSelection() != wxString(wxT("sb")).Find(step->GetKindChar()) + || rbxOnError->GetSelection() != wxString(wxT("fsi")).Find(step->GetOnErrorChar()) + || txtComment->GetValue() != step->GetComment() + || sqlBox->GetText() != step->GetCode(); + + if (!enable && rbxKind->GetSelection() == 0) + { + if (hasConnStrSupport) + { + if (step->HasConnectionString()) + { + if (rbRemoteConn->GetValue()) + enable = txtConnStr->GetValue().Trim() != step->GetConnStr(); + else + enable = true; + } + else + { + if (rbRemoteConn->GetValue()) + enable = true; + else + enable = cbDatabase->GetValue().Trim() != step->GetDbname(); + } + } + else + { + enable = cbDatabase->GetValue().Trim() != step->GetDbname(); + } + } + } + else + { + enable = true; + } + + if (statusBar) + statusBar->SetStatusText(wxEmptyString); + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, sqlBox->GetLength() > 0, _("Please specify code to execute.")); + + // Disable/enable the database combo + if (rbxKind->GetSelection() == 1) + { + rbRemoteConn->Enable(false); + rbLocalConn->Enable(false); + // I don't see any reason to make + // the database combobox selection to 0 + //cbDatabase->SetSelection(0); + txtConnStr->Enable(false); + btnSelDatabase->Enable(false); + cbDatabase->Enable(false); + } + else + { + if (hasConnStrSupport) + { + rbRemoteConn->Enable(true); + rbLocalConn->Enable(true); + if (rbRemoteConn->GetValue()) + { + wxString validConnStr; + + btnSelDatabase->Enable(true); + txtConnStr->Enable(true); + cbDatabase->Enable(false); + CheckValid(enable, !txtConnStr->GetValue().Trim().IsEmpty(), _("Please select a connection string.")); + CheckValid(enable, dlgSelectDatabase::getValidConnectionString(txtConnStr->GetValue().Trim(), validConnStr), _("Please enter a valid connection string")); + } + else + { + cbDatabase->Enable(true); + btnSelDatabase->Enable(false); + txtConnStr->Enable(false); + CheckValid(enable, !cbDatabase->GetValue().Trim().IsEmpty(), _("Please select a database.")); + } + } + else + { + cbDatabase->Enable(true); + // Make sure both radio buttons are disabled + rbRemoteConn->Enable(false); + rbLocalConn->Enable(false); + CheckValid(enable, !cbDatabase->GetValue().Trim().IsEmpty(), _("Please select a database.")); + } + } + + EnableOK(enable); +} + + + +wxString dlgStep::GetComment() +{ + return txtComment->GetValue(); +} + + + +wxString dlgStep::GetInsertSql() +{ + wxString sql; + + if (!step) + { + wxString name = GetName(); + wxString kind = wxT("sb")[rbxKind->GetSelection()]; + wxString onerror = wxT("fsi")[rbxOnError->GetSelection()]; + wxString db, connstr; + wxString jstjobid; + if (jobId) + jstjobid = NumToStr(jobId); + else + jstjobid = wxT(""); + // SQL script expected + if (rbxKind->GetSelection() == 0) + { + if (hasConnStrSupport && rbRemoteConn->GetValue()) + { + connstr = qtDbString(txtConnStr->GetValue().Trim()); + db = wxT("''"); + } + else + { + db = qtDbString(cbDatabase->GetValue().Trim()); + connstr = wxT("''"); + } + } + else + { + db = wxT("''"); + connstr = wxT("''"); + } + + sql = wxT("INSERT INTO pgagent.pga_jobstep (jstid, jstjobid, jstname, jstdesc, jstenabled, jstkind, jstonerror, jstcode, jstdbname"); + if (hasConnStrSupport) + sql += wxT(", jstconnstr"); + sql += wxT(")\n ") \ + wxT("SELECT , ") + jstjobid + wxT(", ") + qtDbString(name) + wxT(", ") + qtDbString(txtComment->GetValue()) + wxT(", ") + + BoolToStr(chkEnabled->GetValue()) + wxT(", ") + qtDbString(kind) + wxT(", ") + + qtDbString(onerror) + wxT(", ") + qtDbString(sqlBox->GetText()) + wxT(", ") + db; + if (hasConnStrSupport) + { + sql += wxT(", ") + connstr; + } + sql += wxT(";\n"); + } + return sql; +} + + +wxString dlgStep::GetUpdateSql() +{ + wxString sql; + + if (step) + { + // edit mode + wxString name = GetName(); + wxString kind = wxT("sb")[rbxKind->GetSelection()]; + + wxString vars; + if (name != step->GetName()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jstname=") + qtDbString(name)); + } + if (chkEnabled->GetValue() != step->GetEnabled()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jstenabled=") + BoolToStr(chkEnabled->GetValue())); + } + if (hasConnStrSupport && kind == wxT("s")) + { + if (rbRemoteConn->GetValue()) + { + if (step->HasConnectionString()) + { + if (txtConnStr->GetValue().Trim() != step->GetConnStr()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jstconnstr=") + qtDbString(txtConnStr->GetValue().Trim())); + } + } + else + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jstconnstr=") + qtDbString(txtConnStr->GetValue().Trim()) + wxT(", ")); + vars.Append(wxT("jstdbname=''")); + } + } + else + { + if (step->HasConnectionString()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jstdbname=") + qtDbString(cbDatabase->GetValue().Trim()) + wxT(", ")); + vars.Append(wxT("jstconnstr=''")); + } + else + { + if (cbDatabase->GetValue().Trim() != step->GetDbname()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jstdbname=") + qtDbString(cbDatabase->GetValue().Trim())); + } + } + } + } + else if (kind == wxT("s")) + { + if (cbDatabase->GetValue().Trim() != step->GetDbname()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jstdbname=") + qtDbString(cbDatabase->GetValue().Trim())); + } + } + else + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jstdbname=''")); + if (hasConnStrSupport) + vars.Append(wxT(", jstconnstr=''")); + } + if (rbxKind->GetSelection() != kind) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jstkind=") + qtDbString(kind)); + } + if (rbxOnError->GetSelection() != wxString(wxT("fsi")).Find(step->GetOnErrorChar())) + { + wxString onerror = wxT("fsi")[rbxOnError->GetSelection()]; + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jstonerror='") + onerror + wxT("'")); + } + if (txtComment->GetValue() != step->GetComment()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jstdesc=") + qtDbString(txtComment->GetValue())); + } + if (sqlBox->GetText() != step->GetCode()) + { + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jstcode=") + qtDbString(sqlBox->GetText())); + } + } + + if (!vars.IsEmpty()) + sql = wxT("UPDATE pgagent.pga_jobstep\n") + wxT(" SET ") + vars + wxT("\n") + wxT(" WHERE jstid=") + NumToStr(step->GetRecId()) + + wxT(";\n"); + } + else + { + // create mode; handled by GetInsertSql() + } + return sql; +} + +bool dlgStep::IsUpToDate() +{ + if (step && !step->IsUpToDate()) + return false; + else + return true; +} + +void dlgStep::OnSelectDatabase(wxCommandEvent &ev) +{ + dlgSelectDatabase dlgSD(this, wxID_ANY); + if (dlgSD.ShowModal() == wxID_OK) + { + wxString strConnStr = dlgSD.getConnInfo(); + if (!strConnStr.IsEmpty()) + txtConnStr->SetValue(strConnStr); + } +} + +void dlgStep::OnSelRemoteConn(wxCommandEvent &ev) +{ + if (rbRemoteConn->GetValue()) + { + cbDatabase->Enable(false); + btnSelDatabase->Enable(true); + txtConnStr->Enable(true); + } + dlgProperty::OnChange(ev); +} + +void dlgStep::OnSelLocalConn(wxCommandEvent &ev) +{ + if (rbLocalConn->GetValue()) + { + cbDatabase->Enable(true); + btnSelDatabase->Enable(false); + txtConnStr->Enable(false); + } + dlgProperty::OnChange(ev); +} + + diff --git a/agent/module.mk b/agent/module.mk new file mode 100644 index 0000000..f0ede73 --- /dev/null +++ b/agent/module.mk @@ -0,0 +1,23 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/agent/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + agent/dlgJob.cpp \ + agent/dlgSchedule.cpp \ + agent/dlgStep.cpp \ + agent/pgaJob.cpp \ + agent/pgaSchedule.cpp \ + agent/pgaStep.cpp + +EXTRA_DIST += \ + agent/module.mk + + diff --git a/agent/pgaJob.cpp b/agent/pgaJob.cpp new file mode 100644 index 0000000..989c15a --- /dev/null +++ b/agent/pgaJob.cpp @@ -0,0 +1,397 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgaJob.h - PostgreSQL Agent Job +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "frm/frmMain.h" +#include "schema/pgObject.h" +#include "schema/pgCollection.h" +#include "schema/pgDatabase.h" +#include "agent/pgaJob.h" +#include "agent/pgaStep.h" +#include "agent/pgaSchedule.h" + +pgaJob::pgaJob(const wxString &newName) + : pgServerObject(jobFactory, newName) +{ +} + +wxString pgaJob::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on pgAgent job"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing pgAgent job"); + break; + case PROPERTIESREPORT: + message = _("pgAgent job properties report"); + break; + case PROPERTIES: + message = _("pgAgent job properties"); + break; + case DDLREPORT: + message = _("pgAgent job DDL report"); + break; + case DEPENDENCIESREPORT: + message = _("pgAgent job dependencies report"); + break; + case DEPENDENCIES: + message = _("pgAgent job dependencies"); + break; + case DEPENDENTSREPORT: + message = _("pgAgent job dependents report"); + break; + case DEPENDENTS: + message = _("pgAgent job dependents"); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop job \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPTITLE: + message = _("Drop job?"); + break; + } + + if (!message.IsEmpty() && !(kindOfMessage == DROPEXCLUDINGDEPS || kindOfMessage == DROPTITLE)) + message += wxT(" - ") + GetName(); + + return message; +} + +int pgaJob::GetIconId() +{ + if (GetEnabled()) + return jobFactory.GetIconId(); + else + return jobFactory.GetDisabledId(); +} + + +wxMenu *pgaJob::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + if (1) // check priv. + { + stepFactory.AppendMenu(menu); + scheduleFactory.AppendMenu(menu); + } + return menu; +} + + +bool pgaJob::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return GetConnection()->ExecuteVoid(wxT("DELETE FROM pgagent.pga_job WHERE jobid=") + NumToStr(GetRecId())); +} + + +void pgaJob::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + + // Log + wxLogInfo(wxT("Adding child objects to Job.")); + + browser->AppendCollection(this, scheduleFactory); + browser->AppendCollection(this, stepFactory); + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("ID"), GetRecId()); + properties->AppendYesNoItem(_("Enabled"), GetEnabled()); + properties->AppendItem(_("Host agent"), GetHostAgent()); + properties->AppendItem(_("Job class"), GetJobclass()); + properties->AppendItem(_("Created"), GetCreated()); + properties->AppendItem(_("Changed"), GetChanged()); + properties->AppendItem(_("Next run"), GetNextrun()); + properties->AppendItem(_("Last run"), GetLastrun()); + properties->AppendItem(_("Last result"), GetLastresult()); + if (!GetCurrentAgent().IsEmpty()) + properties->AppendItem(_("Running at"), GetCurrentAgent()); + else + properties->AppendItem(_("Running at"), _("Not currently running")); + + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgaJob::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *job = 0; + + pgObject *obj = browser->GetObject(browser->GetItemParent(item)); + if (obj && obj->IsCollection()) + job = jobFactory.CreateObjects((pgCollection *)obj, 0, wxT("\n WHERE j.jobid=") + NumToStr(GetRecId())); + + return job; +} + + + +pgObject *pgaJobFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgaJob *job = 0; + + pgSet *jobs = collection->GetConnection()->ExecuteSet( + wxT("SELECT j.*, cl.*, ag.*, sub.jlgstatus AS joblastresult ") + wxT(" FROM pgagent.pga_job j JOIN") + wxT(" pgagent.pga_jobclass cl ON cl.jclid=jobjclid LEFT OUTER JOIN") + wxT(" pgagent.pga_jobagent ag ON ag.jagpid=jobagentid LEFT OUTER JOIN") + wxT(" (SELECT DISTINCT ON (jlgjobid) jlgstatus, jlgjobid") + wxT(" FROM pgagent.pga_joblog") + wxT(" ORDER BY jlgjobid, jlgid desc) sub ON sub.jlgjobid = j.jobid ") + + restriction + + wxT("ORDER BY jobname;")); + + if (jobs) + { + while (!jobs->Eof()) + { + wxString status; + if (jobs->GetVal(wxT("joblastresult")) == wxT("r")) + status = _("Running"); + else if (jobs->GetVal(wxT("joblastresult")) == wxT("s")) + status = _("Successful"); + else if (jobs->GetVal(wxT("joblastresult")) == wxT("f")) + status = _("Failed"); + else if (jobs->GetVal(wxT("joblastresult")) == wxT("d")) + status = _("Aborted"); + else if (jobs->GetVal(wxT("joblastresult")) == wxT("i")) + status = _("No steps"); + else + status = _("Unknown"); + + job = new pgaJob(jobs->GetVal(wxT("jobname"))); + job->iSetServer(collection->GetServer()); + job->iSetRecId(jobs->GetLong(wxT("jobid"))); + job->iSetComment(jobs->GetVal(wxT("jobdesc"))); + + job->iSetEnabled(jobs->GetBool(wxT("jobenabled"))); + job->iSetJobclass(jobs->GetVal(wxT("jclname"))); + job->iSetHostAgent(jobs->GetVal(wxT("jobhostagent"))); + job->iSetCreated(jobs->GetDateTime(wxT("jobcreated"))); + job->iSetChanged(jobs->GetDateTime(wxT("jobchanged"))); + job->iSetNextrun(jobs->GetDateTime(wxT("jobnextrun"))); + job->iSetLastrun(jobs->GetDateTime(wxT("joblastrun"))); + job->iSetLastresult(status); + job->iSetCurrentAgent(jobs->GetVal(wxT("jagstation"))); + + if (browser) + { + browser->AppendObject(collection, job); + jobs->MoveNext(); + } + else + break; + } + + delete jobs; + } + return job; +} + +void pgaJob::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + wxString sql = + wxT("SELECT jlgid") + wxT(", jlgstatus") + wxT(", jlgstart") + wxT(", jlgduration") + wxT(", (jlgstart + jlgduration) AS endtime") + wxT(" FROM pgagent.pga_joblog\n") + wxT(" WHERE jlgjobid = ") + NumToStr(GetRecId()) + + wxT(" ORDER BY jlgstart DESC") + + wxT(" LIMIT ") + NumToStr(settings->GetMaxRows()); + + if (statistics) + { + wxLogInfo(wxT("Displaying statistics for job %s"), GetFullIdentifier().c_str()); + + // Add the statistics view columns + statistics->ClearAll(); + statistics->AddColumn(_("Run"), 50); + statistics->AddColumn(_("Status"), 60); + statistics->AddColumn(_("Start time"), 95); + statistics->AddColumn(_("End time"), 95); + statistics->AddColumn(_("Duration"), 70); + + pgSet *stats = GetConnection()->ExecuteSet(sql); + wxString status; + wxDateTime startTime; + wxDateTime endTime; + + if (stats) + { + while (!stats->Eof()) + { + if (stats->GetVal(1) == wxT("r")) + status = _("Running"); + else if (stats->GetVal(1) == wxT("s")) + status = _("Successful"); + else if (stats->GetVal(1) == wxT("f")) + status = _("Failed"); + else if (stats->GetVal(1) == wxT("d")) + status = _("Aborted"); + else if (stats->GetVal(1) == wxT("i")) + status = _("No steps"); + else + status = _("Unknown"); + + startTime.ParseDateTime(stats->GetVal(2)); + endTime.ParseDateTime(stats->GetVal(4)); + + long pos = statistics->AppendItem(stats->GetVal(0), status, startTime.Format()); + if (stats->GetVal(4).Length() > 0) + statistics->SetItem(pos, 3, endTime.Format()); + statistics->SetItem(pos, 4, stats->GetVal(3)); + + stats->MoveNext(); + } + delete stats; + } + } +} + +bool pgaJob::RunNow() +{ + if (!GetConnection()->ExecuteVoid(wxT("UPDATE pgagent.pga_job SET jobnextrun = now() WHERE jobid=") + NumToStr(GetRecId()))) + return false; + + return true; +} + + +pgaJobCollection::pgaJobCollection(pgaFactory *factory, pgServer *sv) + : pgServerObjCollection(factory, sv) +{ +} + + +wxString pgaJobCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on pgAgent jobs"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing pgAgent jobs"); + break; + case OBJECTSLISTREPORT: + message = _("pgAgent jobs list report"); + break; + } + + return message; +} + + +pgaJobObject::pgaJobObject(pgaJob *_job, pgaFactory &factory, const wxString &newName) + : pgServerObject(factory, newName) +{ + job = _job; + server = job->GetServer(); +} + + +pgaJobObjCollection::pgaJobObjCollection(pgaFactory *factory, pgaJob *_job) + : pgServerObjCollection(factory, _job->GetServer()) +{ + job = _job; +} + + +bool pgaJobObjCollection::CanCreate() +{ + return job->CanCreate(); +} + + +pgCollection *pgaJobObjFactory::CreateCollection(pgObject *obj) +{ + return new pgaJobObjCollection(GetCollectionFactory(), (pgaJob *)obj); +} + + +///////////////////////////// + + +#include "images/job.pngc" +#include "images/jobs.pngc" +#include "images/jobdisabled.pngc" + +pgaJobFactory::pgaJobFactory() + : pgServerObjFactory(__("pgAgent Job"), __("New Job"), __("Create a new Job."), job_png_img) +{ + metaType = PGM_JOB; + disabledId = addIcon(jobdisabled_png_img); +} + + +pgCollection *pgaJobFactory::CreateCollection(pgObject *obj) +{ + return new pgaJobCollection(GetCollectionFactory(), (pgServer *)obj); +} + + +pgaJobFactory jobFactory; +static pgaCollectionFactory cf(&jobFactory, __("Jobs"), jobs_png_img); + +runNowFactory::runNowFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Run now"), _("Reschedule the job to run now.")); +} + + +wxWindow *runNowFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (!((pgaJob *)(obj))->RunNow()) + { + wxLogError(_("Failed to reschedule the job.")); + } + + form->Refresh(obj); + + return 0; +} + + +bool runNowFactory::CheckEnable(pgObject *obj) +{ + if (obj) + { + if (obj->GetMetaType() == PGM_JOB && !obj->IsCollection()) + return true; + } + return false; +} diff --git a/agent/pgaSchedule.cpp b/agent/pgaSchedule.cpp new file mode 100644 index 0000000..0022621 --- /dev/null +++ b/agent/pgaSchedule.cpp @@ -0,0 +1,576 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgaSchedule.cpp - PostgreSQL Agent Schedule +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "utils/misc.h" +#include "schema/pgObject.h" +#include "schema/pgDatabase.h" +#include "schema/pgCollection.h" +#include "agent/pgaSchedule.h" +#include "agent/pgaStep.h" +#include "agent/pgaSchedule.h" + + +pgaSchedule::pgaSchedule(pgCollection *_collection, const wxString &newName) + : pgaJobObject(_collection->GetJob(), scheduleFactory, newName) +{ +} + +wxString pgaSchedule::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on pgAgent schedule"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing pgAgent schedule"); + break; + case PROPERTIESREPORT: + message = _("pgAgent schedule properties report"); + break; + case PROPERTIES: + message = _("pgAgent schedule properties"); + break; + case DDLREPORT: + message = _("pgAgent schedule DDL report"); + break; + case DEPENDENCIESREPORT: + message = _("pgAgent schedule dependencies report"); + break; + case DEPENDENCIES: + message = _("pgAgent schedule dependencies"); + break; + case DEPENDENTSREPORT: + message = _("pgAgent schedule dependents report"); + break; + case DEPENDENTS: + message = _("pgAgent schedule dependents"); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop schedule \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPTITLE: + message = _("Drop schedule?"); + break; + } + + if (!message.IsEmpty() && !(kindOfMessage == DROPEXCLUDINGDEPS || kindOfMessage == DROPTITLE)) + message += wxT(" - ") + GetName(); + + return message; +} + +bool pgaSchedule::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return GetConnection()->ExecuteVoid(wxT("DELETE FROM pgagent.pga_schedule WHERE jscid=") + NumToStr(GetRecId())); +} + + +void pgaSchedule::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("ID"), GetRecId()); + properties->AppendYesNoItem(_("Enabled"), GetEnabled()); + + properties->AppendItem(_("Start date"), GetStart()); + properties->AppendItem(_("End date"), GetEnd()); + properties->AppendItem(_("Minutes"), GetMinutesString()); + properties->AppendItem(_("Hours"), GetHoursString()); + properties->AppendItem(_("Weekdays"), GetWeekdaysString()); + properties->AppendItem(_("Monthdays"), GetMonthdaysString()); + properties->AppendItem(_("Months"), GetMonthsString()); + properties->AppendItem(_("Exceptions"), GetExceptionsString()); + + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgaSchedule::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *schedule = 0; + + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + schedule = scheduleFactory.CreateObjects(coll, 0, wxT("\n AND jscid=") + NumToStr(GetRecId())); + + return schedule; +} + + + +pgObject *pgaScheduleFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgaSchedule *schedule = 0; + wxString tmp; + + pgSet *schedules = collection->GetConnection()->ExecuteSet( + wxT("SELECT * FROM pgagent.pga_schedule\n") + wxT(" WHERE jscjobid=") + NumToStr(collection->GetJob()->GetRecId()) + wxT("\n") + + restriction + + wxT(" ORDER BY jscname")); + + if (schedules) + { + while (!schedules->Eof()) + { + + schedule = new pgaSchedule(collection, schedules->GetVal(wxT("jscname"))); + schedule->iSetRecId(schedules->GetLong(wxT("jscid"))); + schedule->iSetStart(schedules->GetDateTime(wxT("jscstart"))); + schedule->iSetEnd(schedules->GetDateTime(wxT("jscend"))); + schedule->iSetEnabled(schedules->GetBool(wxT("jscenabled"))); + + tmp = schedules->GetVal(wxT("jscminutes")); + tmp.Replace(wxT("{"), wxT("")); + tmp.Replace(wxT("}"), wxT("")); + tmp.Replace(wxT(","), wxT("")); + schedule->iSetMinutes(tmp); + + tmp = schedules->GetVal(wxT("jschours")); + tmp.Replace(wxT("{"), wxT("")); + tmp.Replace(wxT("}"), wxT("")); + tmp.Replace(wxT(","), wxT("")); + schedule->iSetHours(tmp); + + tmp = schedules->GetVal(wxT("jscweekdays")); + tmp.Replace(wxT("{"), wxT("")); + tmp.Replace(wxT("}"), wxT("")); + tmp.Replace(wxT(","), wxT("")); + schedule->iSetWeekdays(tmp); + + tmp = schedules->GetVal(wxT("jscmonthdays")); + tmp.Replace(wxT("{"), wxT("")); + tmp.Replace(wxT("}"), wxT("")); + tmp.Replace(wxT(","), wxT("")); + schedule->iSetMonthdays(tmp); + + tmp = schedules->GetVal(wxT("jscmonths")); + tmp.Replace(wxT("{"), wxT("")); + tmp.Replace(wxT("}"), wxT("")); + tmp.Replace(wxT(","), wxT("")); + schedule->iSetMonths(tmp); + + schedule->iSetComment(schedules->GetVal(wxT("jscdesc"))); + + pgSet *exceptions = collection->GetConnection()->ExecuteSet( + wxT("SELECT * FROM pgagent.pga_exception\n") + wxT(" WHERE jexscid=") + NumToStr(schedule->GetRecId()) + wxT("\n")); + + tmp.Empty(); + if (exceptions) + { + while (!exceptions->Eof()) + { + tmp += exceptions->GetVal(wxT("jexid")); + tmp += wxT("|"); + tmp += exceptions->GetVal(wxT("jexdate")); + tmp += wxT("|"); + tmp += exceptions->GetVal(wxT("jextime")); + tmp += wxT("|"); + + exceptions->MoveNext(); + } + } + schedule->iSetExceptions(tmp); + delete exceptions; + + if (browser) + { + browser->AppendObject(collection, schedule); + schedules->MoveNext(); + } + else + break; + } + + delete schedules; + } + return schedule; +} + +wxString pgaSchedule::GetMinutesString() +{ + size_t x = 0; + bool isWildcard = true; + wxString res, tmp; + + for (x = 0; x <= minutes.Length(); x++) + { + if (minutes[x] == 't') + { + tmp.Printf(wxT("%.2d, "), (int)x); + res += tmp; + isWildcard = false; + } + } + + if (isWildcard) + { + res = _("Every minute"); + } + else + { + if (res.Length() > 2) + { + res.RemoveLast(); + res.RemoveLast(); + } + } + + return res; +} + +wxString pgaSchedule::GetHoursString() +{ + size_t x = 0; + bool isWildcard = true; + wxString res, tmp; + + for (x = 0; x <= hours.Length(); x++) + { + if (hours[x] == 't') + { + tmp.Printf(wxT("%.2d, "), (int)x); + res += tmp; + isWildcard = false; + } + } + + if (isWildcard) + { + res = _("Every hour"); + } + else + { + if (res.Length() > 2) + { + res.RemoveLast(); + res.RemoveLast(); + } + } + + return res; +} + +wxString pgaSchedule::GetWeekdaysString() +{ + size_t x = 0; + bool isWildcard = true; + wxString res; + + for (x = 0; x <= weekdays.Length(); x++) + { + if (weekdays[x] == 't') + { + switch (x) + { + case 0: + res += _("Sunday"); + res += wxT(", "); + break; + case 1: + res += _("Monday"); + res += wxT(", "); + break; + case 2: + res += _("Tuesday"); + res += wxT(", "); + break; + case 3: + res += _("Wednesday"); + res += wxT(", "); + break; + case 4: + res += _("Thursday"); + res += wxT(", "); + break; + case 5: + res += _("Friday"); + res += wxT(", "); + break; + case 6: + res += _("Saturday"); + res += wxT(", "); + break; + default: + res += _("The mythical 8th day!"); + res += wxT(", "); + break; + } + isWildcard = false; + } + } + + if (isWildcard) + { + res = _("Any day of the week"); + } + else + { + if (res.Length() > 2) + { + res.RemoveLast(); + res.RemoveLast(); + } + } + + return res; +} + +wxString pgaSchedule::GetMonthdaysString() +{ + size_t x = 0; + bool isWildcard = true; + wxString res, tmp; + + for (x = 0; x <= monthdays.Length(); x++) + { + if (monthdays[x] == 't') + { + if (x < 31) + { + tmp.Printf(wxT("%.2d, "), (int)(x + 1)); + res += tmp; + } + else + { + res += _("Last day"); + res += wxT(", "); + } + isWildcard = false; + } + } + + if (isWildcard) + { + res = _("Every day"); + } + else + { + if (res.Length() > 2) + { + res.RemoveLast(); + res.RemoveLast(); + } + } + + return res; +} + +wxString pgaSchedule::GetMonthsString() +{ + size_t x = 0; + bool isWildcard = true; + wxString res; + + for (x = 0; x <= months.Length(); x++) + { + if (months[x] == 't') + { + switch (x) + { + case 0: + res += _("January"); + res += wxT(", "); + break; + case 1: + res += _("February"); + res += wxT(", "); + break; + case 2: + res += _("March"); + res += wxT(", "); + break; + case 3: + res += _("April"); + res += wxT(", "); + break; + case 4: + res += _("May"); + res += wxT(", "); + break; + case 5: + res += _("June"); + res += wxT(", "); + break; + case 6: + res += _("July"); + res += wxT(", "); + break; + case 7: + res += _("August"); + res += wxT(", "); + break; + case 8: + res += _("September"); + res += wxT(", "); + break; + case 9: + res += _("October"); + res += wxT(", "); + break; + case 10: + res += _("November"); + res += wxT(", "); + break; + case 11: + res += _("December"); + res += wxT(", "); + break; + default: + res += _("The mythical 13th month!"); + res += wxT(", "); + break; + } + isWildcard = false; + } + } + + if (isWildcard) + { + res = _("Every month"); + } + else + { + if (res.Length() > 2) + { + res.RemoveLast(); + res.RemoveLast(); + } + } + + return res; +} + +wxString pgaSchedule::GetExceptionsString() +{ + wxString tmp, token, dateToken, timeToken; + wxDateTime val; + wxStringTokenizer tkz(exceptions, wxT("|")); + + while (tkz.HasMoreTokens() ) + { + + dateToken.Empty(); + timeToken.Empty(); + + // First is the ID which can be ignored + token = tkz.GetNextToken(); + + // Look for a date + if (tkz.HasMoreTokens()) + dateToken = tkz.GetNextToken(); + + // Look for a time + if (tkz.HasMoreTokens()) + timeToken = tkz.GetNextToken(); + + if (tmp.IsEmpty()) + tmp += wxT("["); + else + tmp += wxT(", ["); + + if (!dateToken.IsEmpty() && !timeToken.IsEmpty()) + { + val.ParseDate(dateToken); + val.ParseTime(timeToken); + tmp += val.Format(); + } + else if (!dateToken.IsEmpty() && timeToken.IsEmpty()) + { + val.ParseDate(dateToken); + tmp += val.FormatDate(); + } + else if (dateToken.IsEmpty() && !timeToken.IsEmpty()) + { + val.ParseTime(timeToken); + tmp += val.FormatTime(); + } + + tmp += wxT("]"); + + } + + return tmp; +} + + +///////////////////////////// + + +pgaScheduleCollection::pgaScheduleCollection(pgaFactory *factory, pgaJob *job) + : pgaJobObjCollection(factory, job) +{ +} + + +wxString pgaScheduleCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on pgAgent schedules"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing pgAgent schedules"); + break; + case OBJECTSLISTREPORT: + message = _("pgAgent schedules list report"); + break; + } + + return message; +} + +///////////////////////////// + + +#include "images/schedule.pngc" +#include "images/schedules.pngc" + +pgaScheduleFactory::pgaScheduleFactory() + : pgaJobObjFactory(__("Schedule"), __("New Schedule"), __("Create a new Schedule."), schedule_png_img) +{ + metaType = PGM_SCHEDULE; +} + + +pgCollection *pgaScheduleFactory::CreateCollection(pgObject *obj) +{ + return new pgaScheduleCollection(GetCollectionFactory(), (pgaJob *)obj); +} + + +pgaScheduleFactory scheduleFactory; +static pgaCollectionFactory cf(&scheduleFactory, __("Schedules"), schedules_png_img); diff --git a/agent/pgaStep.cpp b/agent/pgaStep.cpp new file mode 100644 index 0000000..eee6fc9 --- /dev/null +++ b/agent/pgaStep.cpp @@ -0,0 +1,327 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgaStep.cpp - PostgreSQL Agent Step +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgObject.h" +#include "schema/pgDatabase.h" +#include "schema/pgCollection.h" +#include "agent/pgaStep.h" +#include "agent/pgaSchedule.h" + +pgaStep::pgaStep(pgCollection *_collection, const wxString &newName) + : pgaJobObject(_collection->GetJob(), stepFactory, newName) +{ +} + +wxString pgaStep::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on pgAgent step"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing pgAgent step"); + break; + case PROPERTIESREPORT: + message = _("pgAgent step properties report"); + break; + case PROPERTIES: + message = _("pgAgent step properties"); + break; + case DDLREPORT: + message = _("pgAgent step DDL report"); + break; + case DEPENDENCIESREPORT: + message = _("pgAgent step dependencies report"); + break; + case DEPENDENCIES: + message = _("pgAgent step dependencies"); + break; + case DEPENDENTSREPORT: + message = _("pgAgent step dependents report"); + break; + case DEPENDENTS: + message = _("pgAgent step dependents"); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop step \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPTITLE: + message = _("Drop step?"); + break; + } + + if (!message.IsEmpty() && !(kindOfMessage == DROPEXCLUDINGDEPS || kindOfMessage == DROPTITLE)) + message += wxT(" - ") + GetName(); + + return message; +} + +bool pgaStep::IsUpToDate() +{ + wxString sql = wxT("SELECT xmin FROM pgagent.pga_jobstep WHERE jstid = ") + NumToStr(GetRecId()); + if (!GetConnection() || GetConnection()->ExecuteScalar(sql) != NumToStr(GetXid())) + return false; + else + return true; +} + +bool pgaStep::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return GetConnection()->ExecuteVoid(wxT("DELETE FROM pgagent.pga_jobstep WHERE jstid=") + NumToStr(GetRecId())); +} + + +void pgaStep::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("ID"), GetRecId()); + properties->AppendYesNoItem(_("Enabled"), GetEnabled()); + properties->AppendItem(_("Kind"), GetKind()); + if (GetConnStr().IsEmpty()) + properties->AppendItem(_("Database"), GetDbname()); + else + properties->AppendItem(_("Connection String"), GetConnStr()); + properties->AppendItem(_("Code"), GetCode()); + properties->AppendItem(_("On error"), GetOnError()); + + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgaStep::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *step = 0; + + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + step = stepFactory.CreateObjects(coll, 0, wxT("\n AND jstid=") + NumToStr(GetRecId())); + + return step; +} + + + +pgObject *pgaStepFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgaStep *step = 0; + + pgSet *steps = collection->GetConnection()->ExecuteSet( + wxT("SELECT xmin, * FROM pgagent.pga_jobstep\n") + wxT(" WHERE jstjobid=") + NumToStr(collection->GetJob()->GetRecId()) + wxT("\n") + + restriction + + wxT(" ORDER BY jstname")); + + if (steps) + { + while (!steps->Eof()) + { + + step = new pgaStep(collection, steps->GetVal(wxT("jstname"))); + step->iSetRecId(steps->GetLong(wxT("jstid"))); + step->iSetXid(steps->GetOid(wxT("xmin"))); + step->iSetDbname(steps->GetVal(wxT("jstdbname"))); + if (steps->HasColumn(wxT("jstconnstr"))) + step->iSetConnStr(steps->GetVal(wxT("jstconnstr"))); + step->iSetCode(steps->GetVal(wxT("jstcode"))); + step->iSetEnabled(steps->GetBool(wxT("jstenabled"))); + + wxChar kindc = *steps->GetVal(wxT("jstkind")).c_str(); + wxString kinds; + switch (kindc) + { + case 'b': + kinds = _("Batch"); + break; + case 's': + kinds = wxT("SQL"); + break; + } + step->iSetKindChar(kindc); + step->iSetKind(kinds); + + wxChar onerrc = *steps->GetVal(wxT("jstonerror")).c_str(); + wxString onerrs; + switch (onerrc) + { + case 's': + onerrs = _("Succeed"); + break; + case 'f': + onerrs = _("Fail"); + break; + case 'i': + onerrs = _("Ignore"); + break; + + + } + + step->iSetOnErrorChar(onerrc); + step->iSetOnError(onerrs); + step->iSetComment(steps->GetVal(wxT("jstdesc"))); + + + if (browser) + { + browser->AppendObject(collection, step); + steps->MoveNext(); + } + else + break; + } + + delete steps; + } + return step; +} + + +void pgaStep::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + wxString sql = + wxT("SELECT jsljlgid") + wxT(", jslstatus") + wxT(", jslresult") + wxT(", jslstart") + wxT(", jslduration") + wxT(", (jslstart + jslduration) AS endtime") + wxT(", jsloutput") + wxT(" FROM pgagent.pga_jobsteplog\n") + wxT(" WHERE jsljstid = ") + NumToStr(GetRecId()) + + wxT(" ORDER BY jslstart DESC") + wxT(" LIMIT ") + NumToStr(settings->GetMaxRows()); + + if (statistics) + { + wxLogInfo(wxT("Displaying statistics for job %s"), GetFullIdentifier().c_str()); + + // Add the statistics view columns + statistics->ClearAll(); + statistics->AddColumn(_("Run"), 50); + statistics->AddColumn(_("Status"), 60); + statistics->AddColumn(_("Result"), 60); + statistics->AddColumn(_("Start time"), 95); + statistics->AddColumn(_("End time"), 95); + statistics->AddColumn(_("Duration"), 70); + statistics->AddColumn(_("Output"), 200); + + pgSet *stats = GetConnection()->ExecuteSet(sql); + wxString status; + wxDateTime startTime; + wxDateTime endTime; + + if (stats) + { + while (!stats->Eof()) + { + if (stats->GetVal(1) == wxT("r")) + status = _("Running"); + else if (stats->GetVal(1) == wxT("s")) + status = _("Successful"); + else if (stats->GetVal(1) == wxT("f")) + status = _("Failed"); + else if (stats->GetVal(1) == wxT("i")) + status = _("Ignored"); + else if (stats->GetVal(1) == wxT("d")) + status = _("Aborted"); + else + status = _("Unknown"); + + startTime.ParseDateTime(stats->GetVal(3)); + endTime.ParseDateTime(stats->GetVal(5)); + + long pos = statistics->AppendItem(stats->GetVal(0), status, stats->GetVal(2)); + statistics->SetItem(pos, 3, startTime.Format()); + if (stats->GetVal(5).Length() > 0) + statistics->SetItem(pos, 4, endTime.Format()); + statistics->SetItem(pos, 5, stats->GetVal(4)); + statistics->SetItem(pos, 6, stats->GetVal(6)); + + stats->MoveNext(); + } + delete stats; + } + } +} + + +///////////////////////////// + + +pgaStepCollection::pgaStepCollection(pgaFactory *factory, pgaJob *job) + : pgaJobObjCollection(factory, job) +{ +} + + +wxString pgaStepCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on pgAgent steps"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing pgAgent steps"); + break; + case OBJECTSLISTREPORT: + message = _("pgAgent steps list report"); + break; + } + + return message; +} + + +///////////////////////////// + + +#include "images/step.pngc" +#include "images/steps.pngc" + +pgaStepFactory::pgaStepFactory() + : pgaJobObjFactory(__("Step"), __("New Step"), __("Create a new Step."), step_png_img) +{ + metaType = PGM_STEP; +} + + +pgCollection *pgaStepFactory::CreateCollection(pgObject *obj) +{ + return new pgaStepCollection(GetCollectionFactory(), (pgaJob *)obj); +} + + +pgaStepFactory stepFactory; +static pgaCollectionFactory cf(&stepFactory, __("Steps"), steps_png_img); diff --git a/ctl/calbox.cpp b/ctl/calbox.cpp new file mode 100644 index 0000000..0945126 --- /dev/null +++ b/ctl/calbox.cpp @@ -0,0 +1,519 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// calbox.cpp - Date-picker control box +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include + +#include "ctl/calbox.h" + +#if !defined(wxUSE_DATEPICKCTRL) || !wxUSE_DATEPICKCTRL + +#if defined(__WXMSW__) +#define TXTCTRL_FLAGS wxNO_BORDER +#define CALBORDER 0 +#define TXTPOSX 0 +#define TXTPOSY 1 +#elif defined(__WXGTK__) +#define TXTCTRL_FLAGS 0 +#define CALBORDER 4 +#define TXTPOSX 0 +#define TXTPOSY 0 +#else +#define TXTCTRL_FLAGS 0 +#define CALBORDER 4 +#define TXTPOSX 0 +#define TXTPOSY 0 +#endif + + +#define CTRLID_TXT 101 +#define CTRLID_CAL 102 +#define CTRLID_BTN 103 +#define CTRLID_PAN 104 + +BEGIN_EVENT_TABLE(wxCalendarBox, wxControl) + EVT_BUTTON(CTRLID_BTN, wxCalendarBox::OnClick) + EVT_TEXT(CTRLID_TXT, wxCalendarBox::OnText) + EVT_CHILD_FOCUS(wxCalendarBox::OnChildSetFocus) + EVT_SIZE(wxCalendarBox::OnSize) +END_EVENT_TABLE() + +IMPLEMENT_DYNAMIC_CLASS(wxCalendarBox, wxControl) + + + +wxCalendarBox::wxCalendarBox(wxWindow *parent, + wxWindowID id, + const wxDateTime &date, + const wxPoint &pos, + const wxSize &size, + long style, + const wxString &name) +{ + Init(); + Create(parent, id, date, pos, size, style, name); +} + + +bool wxCalendarBox::Create(wxWindow *parent, + wxWindowID id, + const wxDateTime &date, + const wxPoint &pos, + const wxSize &size, + long style, + const wxString &name) +{ + wxString txt; + if (date.IsValid()) + txt = date.FormatISODate(); + + if ( !wxControl::Create(parent, id, pos, size, + style | wxCLIP_CHILDREN | wxWANTS_CHARS, + wxDefaultValidator, name) ) + + { + return false; + } + + InheritAttributes(); + + wxSize cs = GetClientSize(); + wxSize bs = ConvertDialogToPixels(wxSize(10, 0)); + + wxBitmap bmp(8, 4); + { + wxMemoryDC dc; + + dc.SelectObject(bmp); + dc.SetBrush(wxBrush(GetBackgroundColour())); + dc.SetPen(wxPen(GetBackgroundColour())); + dc.DrawRectangle(0, 0, 8, 4); + + dc.SetBrush(wxBrush(GetForegroundColour())); + dc.SetPen(wxPen(GetForegroundColour())); + wxPoint pt[3] = { wxPoint(0, 0), wxPoint(6, 0), wxPoint(3, 3) }; + dc.DrawPolygon(3, pt); + dc.SelectObject(wxNullBitmap); + } + + m_txt = new wxTextCtrl(this, CTRLID_TXT, txt, wxDefaultPosition, size, TXTCTRL_FLAGS); + m_txt->Connect(wxID_ANY, wxID_ANY, wxEVT_KEY_DOWN, wxKeyEventHandler(wxCalendarBox::OnEditKey), 0, this); + m_txt->Connect(wxID_ANY, wxID_ANY, wxEVT_KILL_FOCUS, wxFocusEventHandler(wxCalendarBox::OnKillFocus), 0, this); + SetFormat(wxT("%Y-%m-%d")); + + m_btn = new wxBitmapButton(this, CTRLID_BTN, bmp, wxDefaultPosition, bs); + + m_dlg = new wxDialog(this, CTRLID_CAL, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER); + m_dlg->SetFont(GetFont()); + + wxPanel *panel = new wxPanel(m_dlg, CTRLID_PAN, wxPoint(0, 0), wxDefaultSize, wxSUNKEN_BORDER | wxCLIP_CHILDREN); + m_cal = new pgCompatCalendarCtrl(panel, CTRLID_CAL, wxDefaultDateTime, wxPoint(0, 0), wxDefaultSize, wxSUNKEN_BORDER); + m_cal->Connect(CTRLID_CAL, CTRLID_CAL, wxEVT_CALENDAR_SEL_CHANGED, wxCalendarEventHandler(wxCalendarBox::OnSelChange), 0, this); + m_cal->Connect(wxID_ANY, wxID_ANY, wxEVT_KEY_DOWN, wxKeyEventHandler(wxCalendarBox::OnCalKey), 0, this); + m_cal->Connect(CTRLID_CAL, CTRLID_CAL, wxEVT_CALENDAR_DOUBLECLICKED, wxCalendarEventHandler(wxCalendarBox::OnSelChange), 0, this); + m_cal->Connect(CTRLID_CAL, CTRLID_CAL, wxEVT_CALENDAR_DAY_CHANGED, wxCalendarEventHandler(wxCalendarBox::OnSelChange), 0, this); + m_cal->Connect(CTRLID_CAL, CTRLID_CAL, wxEVT_CALENDAR_MONTH_CHANGED, wxCalendarEventHandler(wxCalendarBox::OnSelChange), 0, this); + m_cal->Connect(CTRLID_CAL, CTRLID_CAL, wxEVT_CALENDAR_YEAR_CHANGED, wxCalendarEventHandler(wxCalendarBox::OnSelChange), 0, this); + + wxWindow *yearControl = m_cal->GetYearControl(); + + Connect(wxID_ANY, wxID_ANY, wxEVT_SET_FOCUS, wxFocusEventHandler(wxCalendarBox::OnSetFocus)); + + wxClientDC dc(yearControl); + dc.SetFont(m_font); + wxCoord width, dummy; + dc.GetTextExtent(wxT("2000"), &width, &dummy); + width += ConvertDialogToPixels(wxSize(20, 0)).x; + + wxSize calSize = m_cal->GetBestSize(); + wxSize yearSize = yearControl->GetSize(); + yearSize.x = width; + + wxPoint yearPosition = yearControl->GetPosition(); + + width = yearPosition.x + yearSize.x + 2 + CALBORDER / 2; + if (width < calSize.x - 4) + width = calSize.x - 4; + + int calPos = (width - calSize.x) / 2; + if (calPos == -1) + { + calPos = 0; + width += 2; + } + m_cal->SetSize(calPos, 0, calSize.x, calSize.y); + yearControl->SetSize(width - yearSize.x - CALBORDER / 2, yearPosition.y, yearSize.x, yearSize.y); + m_cal->GetMonthControl()->Move(0, 0); + + SetInitialSize(size); + + panel->SetClientSize(width + CALBORDER / 2, calSize.y - 2 + CALBORDER); + m_dlg->SetClientSize(panel->GetSize()); + + return true; +} + + +void wxCalendarBox::Init() +{ + m_dlg = NULL; + m_txt = NULL; + m_cal = NULL; + m_btn = NULL; + + m_dropped = false; + m_ignoreDrop = false; +} + + +bool wxCalendarBox::Destroy() +{ + if (m_cal) + m_cal->Destroy(); + if (m_dlg) + m_dlg->Destroy(); + if (m_txt) + m_txt->Destroy(); + if (m_btn) + m_btn->Destroy(); + + m_dlg = NULL; + m_txt = NULL; + m_cal = NULL; + m_btn = NULL; + + return wxControl::Destroy(); +} + + +void wxCalendarBox::DoMoveWindow(int x, int y, int w, int h) +{ + wxControl::DoMoveWindow(x, y, w, h); + if (m_dropped) + { + DropDown(); + } +} + + +wxSize wxCalendarBox::DoGetBestSize() const +{ + int bh = m_btn->GetBestSize().y; + int eh = m_txt->GetBestSize().y; + return wxSize(100, bh > eh ? bh : eh); +} + + +void wxCalendarBox::OnSize(wxSizeEvent &event) +{ + if ( m_btn ) + { + wxSize sz = GetClientSize(); + + wxSize bs = m_btn->GetSize(); + int eh = m_txt->GetBestSize().y; + + m_txt->SetSize(TXTPOSX, TXTPOSY, sz.x - bs.x - TXTPOSX, sz.y > eh ? eh - TXTPOSY : sz.y - TXTPOSY); + m_btn->SetSize(sz.x - bs.x, 0, bs.x, sz.y); + } + + event.Skip(); +} + + +bool wxCalendarBox::Show(bool show) +{ + if ( !wxControl::Show(show) ) + { + return false; + } + + if (!show) + { + if (m_dlg) + { + m_dlg->Hide(); + m_dropped = false; + } + } + + return true; +} + + +bool wxCalendarBox::Enable(bool enable) +{ + if ( !wxControl::Enable(enable) ) + { + return false; + } + + if (m_cal) + { + if (enable) + m_cal->Show(); + else + m_cal->Hide(); + } + + if (m_btn) + m_btn->Enable(enable); + return true; +} + + +bool wxCalendarBox::SetFormat(const wxChar *fmt) +{ + wxDateTime dt; + dt.ParseFormat(wxT("2003-10-13"), wxT("%Y-%m-%d")); + wxString str = dt.Format(fmt); + const wxChar *p = (const wxChar *) str; + + m_format = wxEmptyString; + + while (*p) + { + int n = wxAtoi(p); + if (n == dt.GetDay()) + { + m_format.Append(wxT("%d")); + p += 2; + } + else if (n == (int)dt.GetMonth() + 1) + { + m_format.Append(wxT("%m")); + p += 2; + } + else if (n == dt.GetYear()) + { + m_format.Append(wxT("%Y")); + p += 4; + } + else + m_format.Append(*p++); + } + + if (m_txt) + { + wxArrayString valArray; + wxChar c; + for (c = '0'; c <= '9'; c++) + valArray.Add(wxString(c, 1)); + const wxChar *p = (const wxChar *) m_format; + while (*p) + { + if (*p == '%') + p += 2; + else + valArray.Add(wxString(*p++, 1)); + } + wxTextValidator tv(wxFILTER_INCLUDE_CHAR_LIST); + tv.SetIncludes(valArray); + + m_txt->SetValidator(tv); + } + return true; +} + + +wxDateTime wxCalendarBox::GetValue() +{ + wxDateTime dt; + wxString txt = m_txt->GetValue(); + + if (!txt.IsEmpty()) + dt.ParseFormat(txt, m_format); + + return dt; +} + + +bool wxCalendarBox::SetValue(const wxDateTime &date) +{ + bool retval = false; + + if (m_cal) + { + if (date.IsValid()) + m_txt->SetValue(date.FormatISODate()); + else + m_txt->SetValue(wxEmptyString); + } + return retval; +} + + +void wxCalendarBox::DropDown(bool down) +{ + if (m_dlg) + { + if (down) + { + if (m_txt->GetValue().IsEmpty()) + m_cal->SetDate(wxDateTime::Today()); + else + { + wxDateTime dt; + dt.ParseFormat(m_txt->GetValue(), m_format); + m_cal->SetDate(dt); + } + wxPoint pos = GetParent()->ClientToScreen(GetPosition()); + + m_dlg->Move(pos.x, pos.y + GetSize().y); + m_dlg->Show(); + m_dropped = true; + } + else + { + if (m_dropped) + m_dlg->Hide(); + m_dropped = false; + } + } +} + + +void wxCalendarBox::OnChildSetFocus(wxChildFocusEvent &ev) +{ + ev.Skip(); + m_ignoreDrop = false; + + wxWindow *w = (wxWindow *)ev.GetEventObject(); + while (w) + { + if (w == m_dlg) + return; + w = w->GetParent(); + } + + if (m_dropped) + { + DropDown(false); + if (ev.GetEventObject() == m_btn) + m_ignoreDrop = true; + } +} + + +void wxCalendarBox::OnClick(wxCommandEvent &event) +{ + if (m_ignoreDrop) + { + m_ignoreDrop = false; + m_txt->SetFocus(); + } + else + { + DropDown(); + m_cal->SetFocus(); + } +} + + +void wxCalendarBox::OnSetFocus(wxFocusEvent &ev) +{ + if (m_txt) + { + m_txt->SetFocus(); + m_txt->SetSelection(0, 100); + } +} + + +void wxCalendarBox::OnKillFocus(wxFocusEvent &ev) +{ + wxDateTime dt; + dt.ParseFormat(m_txt->GetValue(), m_format); + if (!dt.IsValid()) + m_txt->SetValue(wxEmptyString); + else + m_txt->SetValue(dt.Format(m_format)); +} + + +void wxCalendarBox::OnSelChange(wxCalendarEvent &ev) +{ + if (m_cal) + { + m_txt->SetValue(m_cal->GetDate().FormatISODate()); + if (ev.GetEventType() == wxEVT_CALENDAR_DOUBLECLICKED) + { + DropDown(false); + m_txt->SetFocus(); + } + } + ev.SetEventObject(this); + ev.SetId(GetId()); + +#if wxCHECK_VERSION(2, 9, 0) + GetParent()->GetEventHandler()->ProcessEvent(ev); +#else + GetParent()->ProcessEvent(ev); +#endif + +} + + +void wxCalendarBox::OnText(wxCommandEvent &ev) +{ + ev.SetEventObject(this); + ev.SetId(GetId()); + +#if wxCHECK_VERSION(2, 9, 0) + GetParent()->GetEventHandler()->ProcessEvent(ev); +#else + GetParent()->ProcessEvent(ev); +#endif + + // We'll create an additional event if the date is valid. + // If the date isn't valid, the user's probably in the middle of typing + wxString txt = m_txt->GetValue(); + wxDateTime dt; + if (!txt.IsEmpty()) + dt.ParseFormat(txt, m_format); + +#if wxCHECK_VERSION(2, 9, 0) + wxCalendarEvent cev(m_cal, dt, wxEVT_CALENDAR_SEL_CHANGED); +#else + wxCalendarEvent cev(m_cal, wxEVT_CALENDAR_SEL_CHANGED); + cev.SetDate(dt); +#endif + cev.SetEventObject(this); + cev.SetId(GetId()); + +#if wxCHECK_VERSION(2, 9, 0) + GetParent()->GetEventHandler()->ProcessEvent(cev); +#else + GetParent()->ProcessEvent(cev); +#endif + +} + + +void wxCalendarBox::OnEditKey(wxKeyEvent &ev) +{ + if (ev.GetKeyCode() == WXK_DOWN && !ev.HasModifiers()) + DropDown(); + else + ev.Skip(); +} + + +void wxCalendarBox::OnCalKey(wxKeyEvent &ev) +{ + if (ev.GetKeyCode() == WXK_ESCAPE && !ev.HasModifiers()) + DropDown(false); + else + ev.Skip(); +} + +#endif // !defined(wxUSE_DATEPICKCTRL) || !wxUSE_DATEPICKCTRL diff --git a/ctl/ctlAuiNotebook.cpp b/ctl/ctlAuiNotebook.cpp new file mode 100644 index 0000000..ed3bc20 --- /dev/null +++ b/ctl/ctlAuiNotebook.cpp @@ -0,0 +1,41 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlAuiNotebook.cpp - Custom AUI Notebook class +// +////////////////////////////////////////////////////////////////////////// + +// The primary purpose of this class is to pass child focus events from +// the notebook to the parent window. This is the only way we can grab +// focus events from the page controls. + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include + +BEGIN_EVENT_TABLE(ctlAuiNotebook, wxAuiNotebook) + EVT_CHILD_FOCUS(ctlAuiNotebook::OnChildFocus) +END_EVENT_TABLE() + +// Handle, and pass up child focus events +void ctlAuiNotebook::OnChildFocus(wxChildFocusEvent &event) +{ + +#if wxCHECK_VERSION(2, 9, 0) + wxAuiNotebook::OnChildFocusNotebook(event); + GetParent()->GetEventHandler()->AddPendingEvent(event); +#else + wxAuiNotebook::OnChildFocus(event); + GetParent()->AddPendingEvent(event); +#endif + +} diff --git a/ctl/ctlCheckTreeView.cpp b/ctl/ctlCheckTreeView.cpp new file mode 100644 index 0000000..bff9ab1 --- /dev/null +++ b/ctl/ctlCheckTreeView.cpp @@ -0,0 +1,90 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlCheckTreeView.cpp - TreeView with Checkboxes +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include +#include + +// App headers +#include "ctl/ctlCheckTreeView.h" +#include "images/checked.pngc" +#include "images/disabled.pngc" +#include "images/unchecked.pngc" + +BEGIN_EVENT_TABLE(ctlCheckTreeView, wxTreeCtrl) + EVT_LEFT_DOWN( ctlCheckTreeView::OnLeftClick) +END_EVENT_TABLE() + + +ctlCheckTreeView::ctlCheckTreeView(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style) + : wxTreeCtrl(parent, id, pos, size, style) +{ + wxImageList *treeimages = new wxImageList(16, 16, true, 3); + treeimages->Add(*unchecked_png_img); + treeimages->Add(*checked_png_img); + treeimages->Add(*disabled_png_img); + SetImageList(treeimages); +} + + +void ctlCheckTreeView::OnLeftClick(wxMouseEvent &evt) +{ + int flags; + wxTreeItemId node = HitTest(evt.GetPosition(), flags); + int newimage = 0; + + if ((flags & wxTREE_HITTEST_ONITEMLABEL) || (flags & wxTREE_HITTEST_ONITEMICON)) + { + if (GetItemImage(node) == 0) + newimage = 1; + else if (GetItemImage(node) == 1) + newimage = 0; + + if (newimage == 0 || newimage == 1) + SetParentAndChildImage(node, newimage); + if (newimage == 1) + SetParentImage(node, newimage); + } + + evt.Skip(); +} + +void ctlCheckTreeView::SetParentAndChildImage(wxTreeItemId node, int newimage) +{ + SetItemImage(node, newimage); + wxTreeItemIdValue childData; + wxTreeItemId child = GetFirstChild(node, childData); + while (child.IsOk()) + { + SetParentAndChildImage(child, newimage); + child = GetNextChild(node, childData); + } +} + +void ctlCheckTreeView::SetParentImage(wxTreeItemId node, int newimage) +{ + if (node.IsOk()) + { + SetItemImage(node, newimage); + SetParentImage(GetItemParent(node), newimage); + } +} + +bool ctlCheckTreeView::IsChecked(const wxTreeItemId &node) +{ + return (GetItemImage(node) == 1); +} + diff --git a/ctl/ctlColourPicker.cpp b/ctl/ctlColourPicker.cpp new file mode 100644 index 0000000..ecc07fd --- /dev/null +++ b/ctl/ctlColourPicker.cpp @@ -0,0 +1,121 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the BSD Licence +// +// ctlColourPicker.cpp - Colour Picker with a wxBitmapButton +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include +#include + +// App headers +#include "pgAdmin3.h" +#include "ctl/ctlColourPicker.h" + + +void ctlColourPicker::Create(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size) +{ + // Set Default Title + m_title = _("Choose the colour"); + + // Create the wxBitmapButton + ((wxBitmapButton *)this)->Create(parent, id, wxNullBitmap, pos, size); + + // Set the handler for a click + Connect(id, wxEVT_LEFT_DOWN, wxMouseEventHandler(ctlColourPicker::DoProcessLeftClick) ); +} + + +void ctlColourPicker::DoProcessLeftClick(wxMouseEvent &event) +{ + wxColourData clrData; + + // Initialise custom colours + for (int index = 0; index < 16; index++) + clrData.SetCustomColour(index, settings->GetCustomColour(index)); + + // If there is an initial colour, set it for wxColourDialog + if (m_colour_clr.IsOk()) + clrData.SetColour(m_colour_clr); + + // Declare the new dialog + wxColourDialog dialog(this, &clrData); + + // and set its title + dialog.SetTitle(m_title); + + // Now, show it + if (dialog.ShowModal() == wxID_OK) + { + clrData = dialog.GetColourData(); + SetColour(clrData.GetColour()); + + // Store custom colours + for (int index = 0; index < 16; index++) + settings->SetCustomColour(index, clrData.GetCustomColour(index).GetAsString(wxC2S_HTML_SYNTAX)); + } +} + + +void ctlColourPicker::UpdateColour() +{ + if (!m_colour_clr.IsOk()) + { + wxLogError(wxT("ohoh")); + wxBitmap empty(1, 1); + SetBitmapLabel(empty); + return; + } + + wxSize sz = GetSize(); + sz.x -= 2 * GetMarginX(); + sz.y -= 2 * GetMarginY(); + + wxPoint topleft; + if ( sz.x < 1 ) + sz.x = 1; + else if ( sz.y < 1 ) + sz.y = 1; + wxBitmap bmp(sz.x, sz.y); + + wxMemoryDC dc(bmp); + dc.SetBrush(wxBrush(m_colour_clr)); + dc.DrawRectangle(topleft, sz); + + ((wxBitmapButton *)this)->SetBitmapLabel(bmp); +} + +wxColour ctlColourPicker::GetColour() +{ + return m_colour_clr; +} + +wxString ctlColourPicker::GetColourString() +{ + if (!m_colour_clr.IsOk()) + return wxEmptyString; + return m_colour_clr.GetAsString(); +} + +void ctlColourPicker::SetColour(const wxColour &colour) +{ + m_colour_clr = colour; + UpdateColour(); +} + +void ctlColourPicker::SetColour(const wxString &colour) +{ + m_colour_clr = wxColour(colour); + UpdateColour(); +} + +void ctlColourPicker::SetTitle(const wxString &title) +{ + m_title = title; +} diff --git a/ctl/ctlComboBox.cpp b/ctl/ctlComboBox.cpp new file mode 100644 index 0000000..0dca72a --- /dev/null +++ b/ctl/ctlComboBox.cpp @@ -0,0 +1,240 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlComboBox.cpp - enhanced combobox control +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// App headers +#include "ctl/ctlComboBox.h" +#include "db/pgConn.h" +#include "db/pgSet.h" + + +class StringClientData : public wxClientData +{ +public: + StringClientData(const wxChar *c) + { + str = c; + } + wxString str; +}; + + + + +int ctlComboBoxFix::Append(const wxString &item, const wxString &str) +{ + return wxComboBox::Append(item, new StringClientData(str)); +} + + +int ctlComboBoxFix::Append(const wxString &item, long l) +{ + return wxComboBox::Append(item, (void *)l); +} + + +int ctlComboBoxFix::Append(const wxString &item, OID oid) +{ + return wxComboBox::Append(item, (void *)oid); +} + + +int ctlComboBoxFix::FillLongKey(pgConn *conn, const wxChar *qry) +{ + int cnt = 0; + pgSetIterator set(conn->ExecuteSet(qry)); + while (set.RowsLeft()) + { + long l = set.GetLong(0); + wxString txt = set.GetVal(1); + Append(txt, l); + cnt++; + } + return cnt; +} + + +int ctlComboBoxFix::FillOidKey(pgConn *conn, const wxChar *qry) +{ + int cnt = 0; + pgSetIterator set(conn->ExecuteSet(qry)); + while (set.RowsLeft()) + { + OID oid = set.GetOid(0); + wxString txt = set.GetVal(1); + Append(txt, oid); + cnt++; + } + return cnt; +} + + +int ctlComboBoxFix::FillStringKey(pgConn *conn, const wxChar *qry) +{ + int cnt = 0; + pgSetIterator set(conn->ExecuteSet(qry)); + while (set.RowsLeft()) + { + wxString str = set.GetVal(0); + wxString txt = set.GetVal(1); + Append(txt, str); + cnt++; + } + return cnt; +} + +long ctlComboBoxFix::GetLongKey(int sel) +{ + if (sel < 0) + sel = GetSelection(); + return (long)wxItemContainer::GetClientData(sel); +} + +OID ctlComboBoxFix::GetOIDKey(int sel) +{ + if (sel < 0) + sel = GetSelection(); + return (OID)wxItemContainer::GetClientData(sel); +} + +wxString ctlComboBoxFix::GetStringKey(int sel) +{ + if (sel < 0) + sel = GetSelection(); + StringClientData *scd = (StringClientData *)wxItemContainer::GetClientObject(sel); + if (scd) + return scd->str; + return wxEmptyString; +} + + +ctlComboBoxFix::ctlComboBoxFix(wxWindow *wnd, int id, wxPoint pos, wxSize siz, long attr) + : wxComboBox(wnd, id, wxEmptyString, pos, siz, 0, NULL, attr) +{ +} + + +bool ctlComboBoxFix::SetKey(long val) +{ + unsigned int i; + for (i = 0 ; i < GetCount() ; i++) + { + if (GetLongKey(i) == val) + { + SetSelection(i); + return true; + } + } + SetSelection(wxNOT_FOUND); + return false; +} + + +bool ctlComboBoxFix::SetKey(OID val) +{ + unsigned int i; + for (i = 0 ; i < GetCount() ; i++) + { + if (GetOIDKey(i) == val) + { + SetSelection(i); + return true; + } + } + SetSelection(wxNOT_FOUND); + return false; +} + + +bool ctlComboBoxFix::SetKey(const wxString &val) +{ + unsigned int i; + for (i = 0 ; i < GetCount() ; i++) + { + if (GetStringKey(i) == val) + { + SetSelection(i); + return true; + } + } + SetSelection(wxNOT_FOUND); + return false; +} + + +//////////////////////////////////////////// + +ctlComboBox::ctlComboBox(wxWindow *wnd, int id, wxPoint pos, wxSize siz, long attr) + : ctlComboBoxFix(wnd, id, pos, siz, attr) +{ +#ifdef __WXGTK__ + SetEditable(false); +#endif +} + + +int ctlComboBox::GuessSelection(wxCommandEvent &ev) +{ + if (ev.GetEventType() != wxEVT_COMMAND_TEXT_UPDATED) + return GetGuessedSelection(); + + wxString str = wxComboBox::GetValue(); + if (str.Length()) + { + long pos = GetInsertionPoint(); + + long sel, count = GetCount(); + int len = str.Length(); + for (sel = 0 ; sel < count ; sel++) + { + if (str == GetString(sel).Left(len)) + { + SetSelection(sel); + wxString current = GetString(sel); + SetSelection(pos, current.Length()); + return sel; + } + } + } + return -1; +} + + +int ctlComboBox::GetGuessedSelection() const +{ + int sel = GetCurrentSelection(); + + if (sel < 0) + sel = FindString(GetValue()); + return sel; +} + +int ctlComboBox::GetSelection() const +{ + int sel = 0; +#ifdef __WXMSW__ + sel = GetCurrentSelection(); + + if (sel < 0) +#endif + sel = FindString(GetValue()); + return sel; +} + +wxString ctlComboBox::GetGuessedStringSelection() const +{ + int sel = GetGuessedSelection(); + if (sel < 0) + return wxEmptyString; + else + return GetString(sel); +} diff --git a/ctl/ctlDefaultSecurityPanel.cpp b/ctl/ctlDefaultSecurityPanel.cpp new file mode 100644 index 0000000..c425025 --- /dev/null +++ b/ctl/ctlDefaultSecurityPanel.cpp @@ -0,0 +1,623 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlDefaultSecurityPanel.cpp - Panel with default security information +// +////////////////////////////////////////////////////////////////////////// + + +// wxWindows headers +#include +#include +#include + +// App headers +#include "pgAdmin3.h" +#include "ctl/ctlDefaultSecurityPanel.h" +#include "db/pgConn.h" +#include "dlg/dlgProperty.h" +#include "schema/pgGroup.h" +#include "schema/pgUser.h" +#include "utils/sysLogger.h" + +#include + +defaultPrivilegesOn g_defPrivTables('r', wxT("Tables"), wxT("arwdDxt")), + g_defPrivSequences('S', wxT("Sequences"), wxT("rwU")), + g_defPrivFunctions('f', wxT("Functions"), wxT("X")), + g_defPrivTypes('T', wxT("Types"), wxT("U")); + +defaultPrivilegesOn::defaultPrivilegesOn(const wxChar privType, const wxString &privOn, const wxString &privileges) + : m_privilegeType(privType), m_privilegesOn(privOn), m_privileges(privileges) {} + +ctlDefaultSecurityPanel::ctlDefaultSecurityPanel(pgConn *conn, wxNotebook *nb, wxImageList *imgList) + : wxPanel(nb, -1, wxDefaultPosition, wxDefaultSize), nbNotebook(NULL) +{ + nb->AddPage(this, _("Default Privileges")); + + wxFlexGridSizer *mainSizer = new wxFlexGridSizer(1, 1, 1, 1); + mainSizer->AddGrowableCol(0); + mainSizer->AddGrowableRow(0); + + nbNotebook = new wxNotebook(this, -1, wxDefaultPosition, wxDefaultSize, 0, _("Default ACLs")); + + m_defPrivOnTablesPanel = new ctlDefaultPrivilegesPanel(this, nbNotebook, g_defPrivTables, imgList); + m_defPrivOnSeqsPanel = new ctlDefaultPrivilegesPanel(this, nbNotebook, g_defPrivSequences, imgList); + m_defPrivOnFuncsPanel = new ctlDefaultPrivilegesPanel(this, nbNotebook, g_defPrivFunctions, imgList); + if (conn->BackendMinimumVersion(9, 2)) + m_defPrivOnTypesPanel = new ctlDefaultPrivilegesPanel(this, nbNotebook, g_defPrivTypes, imgList); + else + m_defPrivOnTypesPanel = NULL; + + mainSizer->Add(nbNotebook, 0, wxEXPAND | wxALL, 2); + + this->SetSizer(mainSizer); + mainSizer->Fit(this); +} + +void ctlDefaultSecurityPanel::UpdatePrivilegePages(bool createDefPrivs, const wxString &defPrivsOnTables, + const wxString &defPrivsOnSeqs, const wxString &defPrivsOnFuncs, const wxString &defPrivsOnTypes) +{ + if (!createDefPrivs) + { + nbNotebook->Enable(false); + return; + } + m_defPrivOnTablesPanel->Update(defPrivsOnTables); + m_defPrivOnSeqsPanel->Update(defPrivsOnSeqs); + m_defPrivOnFuncsPanel->Update(defPrivsOnFuncs); + if (m_defPrivOnTypesPanel) + m_defPrivOnTypesPanel->Update(defPrivsOnTypes); +} + + +wxString ctlDefaultSecurityPanel::GetDefaultPrivileges(const wxString &schemaName) +{ + wxString strDefPrivs; + int nPageCount = nbNotebook->GetPageCount(); + for (int index = 0; index < nPageCount; index++) + { + strDefPrivs += (dynamic_cast(nbNotebook->GetPage(index)))->GetDefaultPrivileges(schemaName); + } + return strDefPrivs; +} + + +/////////////////////////////////////////////////////////////////////////////// +// ctlDefaultPrivilegesPanel +/////////////////////////////////////////////////////////////////////////////// + +BEGIN_EVENT_TABLE(ctlDefaultPrivilegesPanel, wxPanel) + EVT_LIST_ITEM_SELECTED(CTL_DEFLBPRIV, ctlDefaultPrivilegesPanel::OnPrivSelChange) + EVT_BUTTON(CTL_DEFADDPRIV, ctlDefaultPrivilegesPanel::OnAddPriv) + EVT_BUTTON(CTL_DEFDELPRIV, ctlDefaultPrivilegesPanel::OnDelPriv) + EVT_TEXT(CTL_DEFCBGROUP, ctlDefaultPrivilegesPanel::OnGroupChange) + EVT_COMBOBOX(CTL_DEFCBGROUP, ctlDefaultPrivilegesPanel::OnGroupChange) + EVT_CHECKBOX(CTL_DEFALLPRIV, ctlDefaultPrivilegesPanel::OnPrivCheckAll) + EVT_CHECKBOX(CTL_DEFALLPRIVGRANT, ctlDefaultPrivilegesPanel::OnPrivCheckAllGrant) + EVT_CHECKBOX(CTL_DEFPRIVCB, ctlDefaultPrivilegesPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_DEFPRIVCB + 2, ctlDefaultPrivilegesPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_DEFPRIVCB + 4, ctlDefaultPrivilegesPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_DEFPRIVCB + 6, ctlDefaultPrivilegesPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_DEFPRIVCB + 8, ctlDefaultPrivilegesPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_DEFPRIVCB + 10, ctlDefaultPrivilegesPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_DEFPRIVCB + 12, ctlDefaultPrivilegesPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_DEFPRIVCB + 14, ctlDefaultPrivilegesPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_DEFPRIVCB + 16, ctlDefaultPrivilegesPanel::OnPrivCheck) +END_EVENT_TABLE(); + +DEFINE_LOCAL_EVENT_TYPE(EVT_DEFAULTSECURITYPANEL_CHANGE) + +ctlDefaultPrivilegesPanel::ctlDefaultPrivilegesPanel(ctlDefaultSecurityPanel *defSecurityPanel, wxNotebook *nb, + defaultPrivilegesOn &privOn, wxImageList *imgList) + : wxPanel(nb, -1, wxDefaultPosition, wxDefaultSize), m_defPrivChanged(false), + m_privilegeType(privOn), m_defSecurityPanel(defSecurityPanel) +{ + + nb->AddPage(this, m_privilegeType.m_privilegesOn); + + allPrivileges = 0; + privCheckboxes = 0; + m_currentSelectedPriv = NULL; + + privilegeCount = m_privilegeType.m_privileges.Length(); + + wxFlexGridSizer *item0 = new wxFlexGridSizer(3, 1, 5, 5); + item0->AddGrowableCol(0); + item0->AddGrowableRow(0); + + privCheckboxes = new wxCheckBox*[privilegeCount * 2]; + + wxFlexGridSizer *itemSizer1 = new wxFlexGridSizer(1, 1, 5, 5); + itemSizer1->AddGrowableCol(0); + itemSizer1->AddGrowableRow(0); + + wxString strGroupLabel = settings->GetShowUsersForPrivileges() ? _("Role/Group") : _("Role"); + + lbPrivileges = new ctlListView(this, CTL_DEFLBPRIV, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER | wxLC_REPORT); + lbPrivileges->SetImageList(imgList, wxIMAGE_LIST_SMALL); + lbPrivileges->AddColumn(_("Role/Group"), 60, wxLIST_FORMAT_LEFT); + lbPrivileges->AddColumn(_("Privileges"), 60, wxLIST_FORMAT_LEFT); + itemSizer1->Add(lbPrivileges, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + item0->Add(itemSizer1, 0, wxEXPAND | wxALL, 5); + + wxBoxSizer *itemSizer2 = new wxBoxSizer(wxHORIZONTAL); + btnAddPriv = new wxButton(this, CTL_DEFADDPRIV, _("Add/Change")); + itemSizer2->Add(btnAddPriv, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + btnDelPriv = new wxButton(this, CTL_DEFDELPRIV, _("Remove")); + itemSizer2->Add(btnDelPriv, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + item0->Add(itemSizer2, 0, wxEXPAND | wxALL, 0); + + wxStaticBox *sb = new wxStaticBox(this, -1, _("Privileges")); + wxBoxSizer *itemSizer3 = new wxStaticBoxSizer( sb, wxVERTICAL ); + item0->Add(itemSizer3, 0, wxEXPAND | wxALL, 5); + + wxBoxSizer *itemSizer4a = new wxBoxSizer(wxHORIZONTAL); + stGroup = new wxStaticText(this, CTL_DEFSTATICGROUP, strGroupLabel); + itemSizer4a->Add(stGroup, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + cbGroups = new ctlComboBox(this, CTL_DEFCBGROUP, wxDefaultPosition, wxDefaultSize); + cbGroups->Append(wxT("public")); + cbGroups->SetSelection(0); + itemSizer4a->Add(cbGroups, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT); + itemSizer3->Add(itemSizer4a, 0, wxEXPAND | wxALL, 0); + + /* border size depends on the plateform */ +#ifdef __WXMSW__ + int bordersize = 4; +#endif +#ifdef __WXMAC__ + int bordersize = 3; +#endif +#ifdef __WXGTK__ + int bordersize = 0; +#endif + + wxBoxSizer *itemSizer5 = new wxBoxSizer(wxHORIZONTAL); + allPrivileges = new wxCheckBox(this, CTL_DEFALLPRIV, wxT("ALL")); + itemSizer5->Add(allPrivileges, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT); + allPrivilegesGrant = new wxCheckBox(this, CTL_DEFALLPRIVGRANT, wxT("WITH GRANT OPTION")); + itemSizer5->Add(allPrivilegesGrant, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT); + allPrivilegesGrant->Disable(); + itemSizer3->Add(itemSizer5, 0, wxALL, bordersize); + + for (int index = 0; index < privilegeCount; index++) + { + int i = index * 2; + wxChar privilege = m_privilegeType.m_privileges.GetChar(index); + wxString priv = pgObject::GetPrivilegeName(privilege); + + wxCheckBox *cb; + wxBoxSizer *itemSizer6 = new wxBoxSizer(wxHORIZONTAL); + cb = new wxCheckBox(this, CTL_DEFPRIVCB + i, priv); + itemSizer6->Add(cb, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT); + privCheckboxes[i++] = cb; + cb = new wxCheckBox(this, CTL_DEFPRIVCB + i, wxT("WITH GRANT OPTION")); + itemSizer6->Add(cb, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT); + cb->Disable(); + privCheckboxes[i] = cb; + itemSizer3->Add(itemSizer6, 0, wxALL, bordersize); + + } + + this->SetSizer(item0); + item0->Fit(this); +} + + +ctlDefaultPrivilegesPanel::~ctlDefaultPrivilegesPanel() +{ + cbGroups->Clear(); + if (privCheckboxes) + delete[] privCheckboxes; +} + +// Find the privileges for the selected user from the map +// and select the check-boxes accordingly +bool ctlDefaultPrivilegesPanel::PrivCheckBoxUpdate(wxString &strRole) +{ + int index = 0; + wxString strKey = strRole; + defPrivHash::iterator priv = m_privileges.find(strKey); + bool canGrant = CanGrant(); + + if (priv == m_privileges.end()) + { + m_currentSelectedPriv = NULL; + allPrivileges->SetValue(true); + allPrivilegesGrant->Enable(canGrant); + for (; index < privilegeCount; index++) + { + privCheckboxes[index * 2]->Enable(); + privCheckboxes[index * 2]->SetValue(true); + privCheckboxes[index * 2 + 1]->Enable(canGrant); + } + return false; + } + else + { + allPrivileges->SetValue(false); + allPrivilegesGrant->SetValue(false); + allPrivilegesGrant->Enable(false); + } + + wxString currentPrivileges = priv->second.m_modified ? priv->second.m_newPriv : priv->second.m_origPriv; + m_currentSelectedPriv = &priv->second; + + for (index = 0; index < privilegeCount; index++) + { + int privAt = currentPrivileges.Find(m_privilegeType.m_privileges.GetChar(index)); + if (privAt != wxNOT_FOUND) + { + privCheckboxes[index * 2]->SetValue(true); + privCheckboxes[index * 2 + 1]->Enable(canGrant); + if (canGrant && (unsigned int)privAt < currentPrivileges.Length() - 1 && currentPrivileges.GetChar(privAt + 1) == wxT('*')) + privCheckboxes[index * 2 + 1]->SetValue(true); + else + privCheckboxes[index * 2 + 1]->SetValue(false); + } + else + { + privCheckboxes[index * 2]->SetValue(false); + privCheckboxes[index * 2 + 1]->SetValue(false); + privCheckboxes[index * 2 + 1]->Disable(); + } + } + return false; +} + + +bool ctlDefaultPrivilegesPanel::CanGrant() +{ + if (cbGroups->GetValue() == wxT("public")) + return false; + return true; +} + + +void ctlDefaultPrivilegesPanel::OnGroupChange(wxCommandEvent &ev) +{ + cbGroups->GuessSelection(ev); + + wxString strRole = cbGroups->GetValue(); + + if (strRole.IsEmpty()) + return; + + btnAddPriv->Enable(!PrivCheckBoxUpdate(strRole)); +} + + +void ctlDefaultPrivilegesPanel::OnPrivCheckAll(wxCommandEvent &ev) +{ + bool all = allPrivileges->GetValue(); + allPrivilegesGrant->Enable(all && CanGrant()); + + for (int i = 0; i < privilegeCount; i++) + { + privCheckboxes[i * 2]->SetValue(all); + CheckGrantOpt(i); + } +} + +void ctlDefaultPrivilegesPanel::OnPrivCheckAllGrant(wxCommandEvent &ev) +{ + bool grant = allPrivilegesGrant->GetValue(); + for (int i = 0 ; i < privilegeCount ; i++) + privCheckboxes[i * 2 + 1]->SetValue(grant); +} + + +void ctlDefaultPrivilegesPanel::OnPrivCheck(wxCommandEvent &ev) +{ + int id = (ev.GetId() - CTL_DEFPRIVCB) / 2; + CheckGrantOpt(id); + btnAddPriv->Enable(); + if (!privCheckboxes[id * 2]->GetValue()) + allPrivileges->SetValue(false); +} + + +void ctlDefaultPrivilegesPanel::CheckGrantOpt(int id) +{ + bool canGrant = (privCheckboxes[id * 2]->GetValue() && CanGrant()); + if (canGrant) + privCheckboxes[id * 2 + 1]->Enable(true); + else + { + privCheckboxes[id * 2 + 1]->SetValue(false); + privCheckboxes[id * 2 + 1]->Disable(); + } + btnAddPriv->Enable(); +} + + +void ctlDefaultPrivilegesPanel::OnDelPriv(wxCommandEvent &ev) +{ + int pos; + wxString strRole; + if ((pos = lbPrivileges->GetFirstSelected()) == -1) + return; + + wxListItem info; + info.m_itemId = pos; + info.m_col = 0; + info.m_mask = wxLIST_MASK_TEXT; + + if (lbPrivileges->GetItem(info)) + strRole = info.m_text; + + wxString strKey = strRole; + defPrivHash::iterator priv = m_privileges.find(strKey); + + if (priv != m_privileges.end()) + { + priv->second.m_modified = true; + priv->second.m_newPriv = wxT(""); + if (m_currentSelectedPriv == &priv->second) + PrivCheckBoxUpdate(strRole); + } + + lbPrivileges->DeleteCurrentItem(); + m_defPrivChanged = true; + + ev.Skip(); +} + + +void ctlDefaultPrivilegesPanel::OnAddPriv(wxCommandEvent &ev) +{ + wxString strRole, strPriv; + bool isPresent = (m_currentSelectedPriv != NULL && + ((m_currentSelectedPriv->m_modified && + !m_currentSelectedPriv->m_newPriv.IsEmpty()) || + (!m_currentSelectedPriv->m_modified))) + || lbPrivileges->FindItem(-1, cbGroups->GetGuessedStringSelection()) >= 0; + + if (allPrivileges && allPrivileges->GetValue()) + { + if (allPrivilegesGrant->GetValue()) + { + for (int index = 0; index < privilegeCount; index++) + { + strPriv += m_privilegeType.m_privileges.GetChar(index); + strPriv += wxT('*'); + } + } + else + strPriv = m_privilegeType.m_privileges; + } + else + { + for (int index = 0; index < privilegeCount; index++) + { + if (privCheckboxes[index * 2]->GetValue()) + { + strPriv += m_privilegeType.m_privileges.GetChar(index); + if(privCheckboxes[index * 2 + 1]->IsEnabled() && privCheckboxes[index * 2 + 1]->GetValue()) + strPriv += wxT('*'); + } + } + } + + if (!m_currentSelectedPriv) + { + strRole = cbGroups->GetGuessedStringSelection(); + + if (strRole.IsEmpty()) + return; + + defPrivilege priv; + priv.m_username = strRole; + priv.m_origPriv = wxT(""); + priv.m_modified = true; + priv.m_newPriv = strPriv; + + wxString strKey = strRole; + m_privileges[strKey] = priv; + + defPrivHash::iterator itr = m_privileges.find(strKey); + m_currentSelectedPriv = &itr->second; + } + else + { + if (m_currentSelectedPriv->m_modified ? + m_currentSelectedPriv->m_newPriv == strPriv : + m_currentSelectedPriv->m_origPriv == strPriv) + { + ev.Skip(); + return; + } + strRole = m_currentSelectedPriv->m_username; + m_currentSelectedPriv->m_modified = true; + m_currentSelectedPriv->m_newPriv = strPriv; + } + + if (!isPresent) + { + int icon; + if (strRole.IsSameAs(wxT("public"), true)) + icon = PGICON_PUBLIC; + else if (strRole.StartsWith(wxT("group "))) + icon = groupFactory.GetIconId(); + else + icon = userFactory.GetIconId(); + long pos = lbPrivileges->GetItemCount(); + + lbPrivileges->InsertItem(pos, strRole, icon); + lbPrivileges->SetItem(pos, 1, strPriv); + } + else + { + long nCount = lbPrivileges->GetItemCount(); + wxListItem info; + + for (int index = 0; index < nCount; index++) + { + wxString strTempRole; + + info.m_itemId = index; + info.m_col = 0; + info.m_mask = wxLIST_MASK_TEXT; + + if (lbPrivileges->GetItem(info)) + strTempRole = info.m_text; + + if (strTempRole == strRole) + { + lbPrivileges->SetItem(index, 1, strPriv); + break; + } + } + } + m_defPrivChanged = true; + + ev.Skip(); +} + + +void ctlDefaultPrivilegesPanel::OnPrivSelChange(wxListEvent &ev) +{ + if (!cbGroups) + return; + if (allPrivileges) + { + allPrivileges->SetValue(false); + allPrivilegesGrant->SetValue(false); + allPrivilegesGrant->Disable(); + } + long pos = lbPrivileges->GetSelection(); + if (pos >= 0) + { + wxString name = lbPrivileges->GetText(pos); + wxString value = lbPrivileges->GetText(pos, 1); + + pos = cbGroups->FindString(name); + if (pos < 0) + { + cbGroups->Append(name); + pos = cbGroups->GetCount() - 1; + } + cbGroups->SetSelection(pos); + + int i; + for (i = 0 ; i < privilegeCount ; i++) + { + if (privCheckboxes[i * 2]->GetName() != wxT("DISABLE")) + { + privCheckboxes[i * 2]->Enable(); + int index = value.Find(m_privilegeType.m_privileges.GetChar(i)); + if (index >= 0) + { + privCheckboxes[i * 2]->SetValue(true); + privCheckboxes[i * 2 + 1]->SetValue(value.Mid(index + 1, 1) == wxT("*")); + } + else + privCheckboxes[i * 2]->SetValue(false); + } + CheckGrantOpt(i); + } + PrivCheckBoxUpdate(name); + } + btnAddPriv->Enable(); +} + + +void ctlDefaultPrivilegesPanel::Update(wxString strDefPrivs) +{ + unsigned int index = 0; + + lbPrivileges->DeleteAllItems(); + + m_privileges.clear(); + + cbGroups->Clear(); + cbGroups->Append(wxT("public")); + for (; index < m_defSecurityPanel->m_groups.GetCount(); index++) + { + cbGroups->Append(m_defSecurityPanel->m_groups[index]); + } + + if (!strDefPrivs.IsEmpty()) + { + wxString strRole, strPriv; + strDefPrivs.Replace(wxT("\\\""), wxT("\""), true); + strDefPrivs.Replace(wxT("\\\\"), wxT("\\"), true); + + // Removing starting brace '{' and ending brace '}' + strDefPrivs = strDefPrivs.SubString(1, strDefPrivs.Length() - 1); + + long pos = 0; + + while (pgObject::findUserPrivs(strDefPrivs, strRole, strPriv)) + { + int icon; + if (strRole.IsSameAs(wxT("public"), true)) + icon = PGICON_PUBLIC; + else if (cbGroups->FindString(strRole) != wxNOT_FOUND) + icon = userFactory.GetIconId(); + else if (cbGroups->FindString(wxT("group ") + strRole) != wxNOT_FOUND) + { + icon = groupFactory.GetIconId(); + strRole = wxT("group ") + strRole; + } + else + continue; + + defPrivilege priv; + priv.m_username = strRole; + priv.m_origPriv = strPriv; + priv.m_modified = false; + priv.m_newPriv = wxT(""); + + wxString strKey = strRole; + m_privileges[strKey] = priv; + + pos = lbPrivileges->GetItemCount(); + + lbPrivileges->InsertItem(pos, strRole, icon); + lbPrivileges->SetItem(pos, 1, strPriv); + + strRole = wxT(""); + strPriv = wxT(""); + pos++; + } + } +} + + +wxString ctlDefaultPrivilegesPanel::GetDefaultPrivileges(const wxString &schemaName) +{ + if(!m_defPrivChanged) + return wxT(""); + + wxString strDefPrivs; + defPrivHash::iterator itr = m_privileges.begin(); + + for (; itr != m_privileges.end(); itr++) + { + if(itr->second.m_modified) + { + wxString strRole = itr->second.m_username; + + if (strRole.StartsWith(wxT("group "))) + { + strRole = strRole.Mid(6); + strRole = qtIdent(strRole); + } + else if (strRole != wxT("public")) + strRole = qtIdent(strRole); + + wxString strOrigDefPrivs = itr->second.m_origPriv; + wxString strNewDefPrivs = itr->second.m_newPriv; + + strDefPrivs += pgObject::GetDefaultPrivileges(m_privilegeType.m_privilegesOn.Upper(), m_privilegeType.m_privileges, schemaName, strOrigDefPrivs, strNewDefPrivs, strRole); + } + } + return strDefPrivs; +} + + diff --git a/ctl/ctlListView.cpp b/ctl/ctlListView.cpp new file mode 100644 index 0000000..4f3b76d --- /dev/null +++ b/ctl/ctlListView.cpp @@ -0,0 +1,145 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlListView.cpp - enhanced listview control +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "ctl/ctlListView.h" +#include "utils/misc.h" + + +ctlListView::ctlListView(wxWindow *p, int id, wxPoint pos, wxSize siz, long attr) + : wxListView(p, id, pos, siz, attr | wxLC_REPORT) +{ +} + + +long ctlListView::GetSelection() +{ + return GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); +} + + +wxString ctlListView::GetText(long row, long col) +{ + wxListItem item; + item.SetId(row); + item.SetColumn(col); + item.SetMask(wxLIST_MASK_TEXT); + GetItem(item); + return item.GetText(); +}; + + +void ctlListView::AddColumn(const wxString &text, int size, int format) +{ + if (size == wxLIST_AUTOSIZE || size == wxLIST_AUTOSIZE_USEHEADER) + { + InsertColumn(GetColumnCount(), text, format, size); + } + else + { + InsertColumn(GetColumnCount(), text, format, ConvertDialogToPixels(wxPoint(size, 0)).x); + } +} + + +long ctlListView::AppendItem(int icon, const wxString &val, const wxString &val2, const wxString &val3, const wxString &val4) +{ + long pos = InsertItem(GetItemCount(), val, icon); + if (!val2.IsEmpty()) + SetItem(pos, 1, val2); + if (!val3.IsEmpty()) + SetItem(pos, 2, val3); + if (!val4.IsEmpty()) + SetItem(pos, 3, val4); + + return pos; +} + + +void ctlListView::CreateColumns(wxImageList *images, const wxString &left, const wxString &right, int leftSize) +{ + int rightSize; + if (leftSize < 0) + { +#ifdef __WXMAC__ + leftSize = rightSize = (GetParent()->GetSize().GetWidth() - 20) / 2; +#else + leftSize = rightSize = GetSize().GetWidth() / 2; +#endif + } + else + { + if (leftSize) + leftSize = ConvertDialogToPixels(wxPoint(leftSize, 0)).x; + +#ifdef __WXMAC__ + rightSize = (GetParent()->GetSize().GetWidth() - 20) - leftSize; +#else + rightSize = GetClientSize().GetWidth() - leftSize; +#endif + } + if (!leftSize) + { + InsertColumn(0, left, wxLIST_FORMAT_LEFT, GetClientSize().GetWidth()); + } + else + { + InsertColumn(0, left, wxLIST_FORMAT_LEFT, leftSize); + InsertColumn(1, right, wxLIST_FORMAT_LEFT, rightSize); + } + + if (images) + SetImageList(images, wxIMAGE_LIST_SMALL); +} + + +void ctlListView::CreateColumns(wxImageList *images, const wxString &str1, const wxString &str2, const wxString &str3, int leftSize) +{ + int rightSize; + if (leftSize < 0) + { +#ifdef __WXMAC__ + leftSize = rightSize = (GetParent()->GetSize().GetWidth() - 20) / 2; +#else + leftSize = rightSize = GetSize().GetWidth() / 2; +#endif + } + else + { + if (leftSize) + leftSize = ConvertDialogToPixels(wxPoint(leftSize, 0)).x; + +#ifdef __WXMAC__ + rightSize = (GetParent()->GetSize().GetWidth() - 20) - leftSize; +#else + rightSize = GetClientSize().GetWidth() - leftSize; +#endif + } + if (!leftSize) + { + InsertColumn(0, str1, wxLIST_FORMAT_LEFT, GetClientSize().GetWidth()); + } + else + { + InsertColumn(0, str1, wxLIST_FORMAT_LEFT, leftSize); + InsertColumn(1, str2, wxLIST_FORMAT_LEFT, rightSize / 2); + InsertColumn(2, str3, wxLIST_FORMAT_LEFT, rightSize / 2); + } + + if (images) + SetImageList(images, wxIMAGE_LIST_SMALL); +} diff --git a/ctl/ctlMenuToolbar.cpp b/ctl/ctlMenuToolbar.cpp new file mode 100644 index 0000000..ed35259 --- /dev/null +++ b/ctl/ctlMenuToolbar.cpp @@ -0,0 +1,193 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlMenuToolbar.cpp - Menu tool bar +// +// This code is essentially stolen (with the authors permission) from +// Paul Nelson (http://www.pnelsoncomposer.com/) +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "ctl/ctlMenuToolbar.h" + +#include +WX_DEFINE_LIST(ctlMenuToolList); + +/* XPM */ +static const char *pulldown_xpm[] = +{ + "16 16 2 1", + ". c Black", + " c None", + /* pixels */ + " ", + " ", + " ", + " ", + " ", + " ", + " ....... ", + " ..... ", + " ... ", + " . ", + " ", + " ", + " ", + " ", + " ", + " " +}; + + +DEFINE_EVENT_TYPE(wxEVT_FILL_MENU) + +////////////////// +// ctlMenuButton +////////////////// + +void ctlMenuButton::Create(wxWindow *window, wxToolBar *toolBar, int ID, wxMenu *menu) +{ + wxBitmap bmpPulldown(pulldown_xpm); + wxSize pulldownSize; + +#ifdef __WXMSW__ + pulldownSize.Set(12, 16); +#else +#ifdef __WXGTK__ + pulldownSize.Set(18, 16); +#else + pulldownSize.Set(10, 16); +#endif +#endif + + m_toolBar = toolBar; + m_menu = menu; + + ((wxBitmapButton *)this)->Create(window, ID, bmpPulldown, wxDefaultPosition, pulldownSize, wxNO_BORDER); + Connect(ID, wxEVT_LEFT_DOWN, wxMouseEventHandler(ctlMenuButton::DoProcessLeftClick) ); +} + + +void ctlMenuButton::DoProcessLeftClick(wxMouseEvent &event) +{ + wxPoint menu_pos; + + if(m_toolBar) + { + wxSize tool_size = m_toolBar->GetToolSize(); + wxSize button_size = GetSize(); + + // ** Assume that pulldown is to the right of a standard toolbar button, + // so, move the x position back one standard toolbar button's width + menu_pos.x = - tool_size.GetWidth(); + menu_pos.y = button_size.GetHeight() / 2 + tool_size.GetHeight() / 2; + +#ifdef __WXMAC__ + wxSize tbar_size = m_toolBar->GetSize(); + wxPoint button_pos = GetPosition(); + int iToolSep = m_toolBar->GetToolSeparation(); + if(iToolSep == 0) iToolSep = 5; + + menu_pos.x += - iToolSep; + menu_pos.y = tbar_size.GetHeight() - button_pos.y / 2; +#endif + } + else + { + wxSize button_size; + button_size = GetSize(); + menu_pos.x = 0; + menu_pos.y = button_size.GetHeight(); + } + + DoPopupMenu(m_menu, menu_pos.x, menu_pos.y); +} + + + +//////////////// +// ctlMenuTool +//////////////// + +ctlMenuTool::ctlMenuTool(wxToolBarToolBase *new_tool, int toolId) +{ + m_tool = new_tool; + m_menu = NULL; + m_toolId = toolId; +} + + +//////////////////// +// ctlMenuToolbar +//////////////////// + +ctlMenuToolbar::ctlMenuToolbar(wxFrame *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, const wxString &name) + : wxToolBar(parent, id, pos, size, style, name) +{ + m_frame = parent; + m_menuTools = NULL; + + Connect(id, wxEVT_LEFT_DOWN, wxMouseEventHandler(ctlMenuToolbar::DoProcessLeftClick) ); +} + + +ctlMenuToolbar::~ctlMenuToolbar() +{ + if(m_menuTools) + delete m_menuTools; +} + +ctlMenuButton *ctlMenuToolbar::AddMenuPulldownTool(int toolId, const wxString &label, const wxString &shortHelpString, wxMenu *popupmenu) +{ + ctlMenuButton *menu_button = new ctlMenuButton(this, toolId, popupmenu); + + AddControl(menu_button); + + return menu_button; +} + + +void ctlMenuToolbar::DoProcessLeftClick(wxMouseEvent &event) +{ + ctlMenuToolList::Node *node = NULL; + ctlMenuTool *menu_tool = NULL; + wxToolBarToolBase *clickTool = FindToolForPosition(event.m_x, event.m_y); + + if(clickTool == NULL || m_menuTools == NULL) + { + event.Skip(); + return; + } + + // search for clickTool in the list of menu tools + node = m_menuTools->GetFirst(); + for( ; node ; node = node->GetNext()) + { + menu_tool = node->GetData(); + if(menu_tool->m_tool == clickTool) + break; + } + + if(node == NULL) + { + event.Skip(); + return; + } + + wxSize tbar_size = GetSize(); + wxPoint menu_pos; + + menu_pos.x = event.m_x - 20; + menu_pos.y = tbar_size.GetHeight() - 2; + + PopupMenu(menu_tool->m_menu, menu_pos); +} diff --git a/ctl/ctlProgressStatusBar.cpp b/ctl/ctlProgressStatusBar.cpp new file mode 100644 index 0000000..24dc4ec --- /dev/null +++ b/ctl/ctlProgressStatusBar.cpp @@ -0,0 +1,202 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlProgressStatusBar.cpp - A status bar with progress indicator +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "ctl/ctlProgressStatusBar.h" + +BEGIN_EVENT_TABLE(ctlProgressStatusBar, wxStatusBar) + EVT_SIZE(ctlProgressStatusBar::OnSize) + EVT_TIMER(wxID_ANY, ctlProgressStatusBar::OnTimer) +END_EVENT_TABLE() + +const unsigned short ctlProgressStatusBar::ms_increment = 100; +const unsigned short ctlProgressStatusBar::ms_progressbar_width = 70; +const unsigned short ctlProgressStatusBar::ms_progressstatus_width = 130; + +ctlProgressStatusBar::ctlProgressStatusBar(wxWindow *parent, bool showProgressInitially, bool autoProgressive, int max) + : wxStatusBar(parent, wxID_ANY), m_progressStopped(!showProgressInitially), + m_autoProgressive(autoProgressive), m_autoValIncrementing(true), + m_hr(0), m_min(0), m_sec(0), m_mil(0), m_val(0) +{ + static int widths[] = { -1, ms_progressbar_width, ms_progressstatus_width}; + int fields = 0; + + if (max <= 0) + max = 100; + + if (m_autoProgressive) + fields = 3; + else + fields = 2; + + m_progress = new wxGauge(this, -1, max); + + wxStatusBar::SetFieldsCount(fields); + wxStatusBar::SetStatusWidths(fields, widths); + + m_timer.SetOwner(this->GetEventHandler()); + + if (!showProgressInitially) + { + m_progressStopped = true; + } + else + { + m_progressStopped = false; + if (m_autoProgressive) + { + m_timer.Start(ms_increment); + + m_hr = 0; + m_min = 0; + m_sec = 0; + m_mil = 0; + } + } + // Dummy event to place the progressbar at right place + wxSizeEvent ev; + this->OnSize(ev); +} + +ctlProgressStatusBar::~ctlProgressStatusBar() +{ + if (m_timer.IsRunning()) + { + m_timer.Stop(); + } +} + + +void ctlProgressStatusBar::OnSize(wxSizeEvent &ev) +{ + // We should have hide the progress bar + if (GetFieldsCount() <= ProgressBar_field) + return; + + wxRect r; + GetFieldRect(ProgressBar_field, r); + + m_progress->SetSize(r.x + 1, r.y + 1, r.width - 2, r.height - 2); + + ev.Skip(); +} + + +void ctlProgressStatusBar::OnTimer(wxTimerEvent &ev) +{ + if (m_progressStopped || !m_autoProgressive) + { + m_timer.Stop(); + return; + } + + m_val = m_progress->GetValue(); + int max = m_progress->GetRange(); + + if (m_val == max) + { + m_val -= 1; + m_autoValIncrementing = false; + } + else if (m_val == 0) + { + m_val = 1; + m_autoValIncrementing = true; + } + else if (m_autoValIncrementing) + { + m_val += 1; + } + else + { + m_val -= 1; + } + + m_progress->SetValue(m_val); + + m_mil += ms_increment; + + if (m_mil >= 1000) + { + m_mil = m_mil - 1000; + m_sec += 1; + + if (m_sec == 60) + { + m_sec = 0; + m_min += 1; + + if (m_min == 60) + { + m_min = 0; + m_hr += 1; + } + } + } + + wxStatusBar::SetStatusText(wxString::Format(_("%d:%02d:%02d.%03d"), m_hr, m_min, m_sec, m_mil), ProgressStatus_field); +} + + +void ctlProgressStatusBar::ShowProgress(bool restart) +{ + if (m_progressStopped) + { + m_progressStopped = false; + + if (!m_timer.IsRunning()) + { + if (restart) + { + m_val = 0; + m_hr = m_min = m_sec = m_mil = 0; + } + + m_progress->SetValue(m_val); + m_timer.Start(ms_increment); + } + } +} + +void ctlProgressStatusBar::StopProgress() +{ + if (m_timer.IsRunning()) + m_timer.Stop(); + + m_progress->SetValue(0); + m_progressStopped = true; +} + +void ctlProgressStatusBar::SetFieldsCount(int number, const int *widths) +{ + m_progress->Show(number > ProgressBar_field); + wxStatusBar::SetFieldsCount( number, widths); + + // Dummy Size event (to reposition the progress bar) + wxSizeEvent ev; + this->OnSize(ev); +} + +void ctlProgressStatusBar::SetStatusWidths(int n, const int widths_field[]) +{ + wxStatusBar::SetStatusWidths( n, widths_field); + + // Dummy Size event (to reposition the progress bar) + wxSizeEvent ev; + this->OnSize(ev); +} \ No newline at end of file diff --git a/ctl/ctlSQLBox.cpp b/ctl/ctlSQLBox.cpp new file mode 100644 index 0000000..efc3860 --- /dev/null +++ b/ctl/ctlSQLBox.cpp @@ -0,0 +1,1044 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlSQLBox.cpp - SQL syntax highlighting textbox +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "db/pgSet.h" +#include "ctl/ctlSQLBox.h" +#include "dlg/dlgFindReplace.h" +#include "frm/menu.h" +#include "utils/sysProcess.h" + +wxString ctlSQLBox::sqlKeywords; + +// Additional pl/pgsql keywords we should highlight +wxString plpgsqlKeywords = wxT(" elsif exception exit loop raise record return text while call"); +// +// Additional Text Search keywords we should highlight +wxString ftsKeywords = wxT(" gettoken lextypes headline init lexize"); + +// Additional pgScript keywords we should highlight +wxString pgscriptKeywords = wxT(" assert break columns continue date datetime file go lines ") + wxT(" log print record reference regexrmline string waitfor while"); + +BEGIN_EVENT_TABLE(ctlSQLBox, wxStyledTextCtrl) + EVT_KEY_DOWN(ctlSQLBox::OnKeyDown) + EVT_MENU(MNU_FIND, ctlSQLBox::OnSearchReplace) + EVT_MENU(MNU_AUTOCOMPLETE, ctlSQLBox::OnAutoComplete) + EVT_KILL_FOCUS(ctlSQLBox::OnKillFocus) +#ifdef __WXMAC__ + EVT_STC_PAINTED(-1, ctlSQLBox::OnPositionStc) +#else + EVT_STC_UPDATEUI(-1, ctlSQLBox::OnPositionStc) +#endif + EVT_STC_MARGINCLICK(-1, ctlSQLBox::OnMarginClick) + EVT_END_PROCESS(-1, ctlSQLBox::OnEndProcess) +END_EVENT_TABLE() + + +IMPLEMENT_DYNAMIC_CLASS(ctlSQLBox, wxStyledTextCtrl) + + +ctlSQLBox::ctlSQLBox() +{ + m_dlgFindReplace = 0; + m_autoIndent = false; + m_autocompDisabled = false; + process = 0; + processID = 0; +} + + +ctlSQLBox::ctlSQLBox(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style) +{ + m_dlgFindReplace = 0; + + m_database = NULL; + + m_autocompDisabled = false; + process = 0; + processID = 0; + + Create(parent, id, pos, size, style); +} + + +void ctlSQLBox::Create(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style) +{ + wxStyledTextCtrl::Create(parent, id , pos, size, style); + + // Clear all styles + StyleClearAll(); + + // Font + extern sysSettings *settings; + wxFont fntSQLBox = settings->GetSQLFont(); + + wxColour bgColor = settings->GetSQLBoxColourBackground(); + if (settings->GetSQLBoxUseSystemBackground()) + { + bgColor = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); + } + + wxColour frColor = settings->GetSQLBoxColourForeground(); + if (settings->GetSQLBoxUseSystemForeground()) + { + frColor = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); + } + StyleSetBackground(wxSTC_STYLE_DEFAULT, bgColor); + StyleSetForeground(wxSTC_STYLE_DEFAULT, frColor); + StyleSetFont(wxSTC_STYLE_DEFAULT, fntSQLBox); + + SetSelBackground(true, wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT)); + SetSelForeground(true, wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT)); + + SetCaretForeground(settings->GetSQLColourCaret()); + autoreplace=0; + SetMarginWidth(1, 0); + SetTabWidth(settings->GetIndentSpaces()); + SetUseTabs(!settings->GetSpacesForTabs()); + + // Setup the different highlight colurs + for (int i = 0; i < 34; ++ i ) + { + if (i > 0 && i < 12) + StyleSetForeground(i, settings->GetSQLBoxColour(i)); + else + StyleSetForeground(i, frColor); + StyleSetBackground(i, bgColor); + StyleSetFont(i, fntSQLBox); + } + + // Keywords in uppercase? + + if (settings->GetSQLKeywordsInUppercase()) + StyleSetCase(5, wxSTC_CASE_UPPER); + + // Margin style + StyleSetBackground(wxSTC_STYLE_LINENUMBER, settings->GetSQLMarginBackgroundColour()); + + // Brace maching styles + StyleSetBackground(34, wxColour(0x99, 0xF9, 0xFF)); + StyleSetBackground(35, wxColour(0xFF, 0xCF, 0x27)); + StyleSetFont(34, fntSQLBox); + StyleSetFont(35, fntSQLBox); + + // SQL Lexer and keywords. + if (sqlKeywords.IsEmpty()) + FillKeywords(sqlKeywords); + SetLexer(wxSTC_LEX_SQL); + SetKeyWords(0, sqlKeywords + plpgsqlKeywords + ftsKeywords + pgscriptKeywords); + + // Enable folding + SetMarginSensitive(2, true); + + SetMarginType(2, wxSTC_MARGIN_SYMBOL); // margin 2 for symbols + SetMarginMask(2, wxSTC_MASK_FOLDERS); // set up mask for folding symbols + SetMarginSensitive(2, true); // this one needs to be mouse-aware + SetMarginWidth(2, 16); // set margin 2 16 px wide + + MarkerDefine(wxSTC_MARKNUM_FOLDEREND, wxSTC_MARK_BOXPLUSCONNECTED, *wxWHITE, *wxBLACK); + MarkerDefine(wxSTC_MARKNUM_FOLDEROPENMID, wxSTC_MARK_BOXMINUSCONNECTED, *wxWHITE, *wxBLACK); + MarkerDefine(wxSTC_MARKNUM_FOLDERMIDTAIL, wxSTC_MARK_TCORNER, *wxWHITE, *wxBLACK); + MarkerDefine(wxSTC_MARKNUM_FOLDERTAIL, wxSTC_MARK_LCORNER, *wxWHITE, *wxBLACK); + MarkerDefine(wxSTC_MARKNUM_FOLDERSUB, wxSTC_MARK_VLINE, *wxWHITE, *wxBLACK); + MarkerDefine(wxSTC_MARKNUM_FOLDER, wxSTC_MARK_BOXPLUS, *wxWHITE, *wxBLACK); + MarkerDefine(wxSTC_MARKNUM_FOLDEROPEN, wxSTC_MARK_BOXMINUS, *wxWHITE, *wxBLACK); + + SetProperty(wxT("fold"), wxT("1")); + SetFoldFlags(16); + + // Setup accelerators + wxAcceleratorEntry entries[2]; + entries[0].Set(wxACCEL_CTRL, (int)'F', MNU_FIND); + entries[1].Set(wxACCEL_CTRL, WXK_SPACE, MNU_AUTOCOMPLETE); + wxAcceleratorTable accel(2, entries); + SetAcceleratorTable(accel); + + // Autocompletion configuration + AutoCompSetSeparator('\t'); + AutoCompSetChooseSingle(true); + AutoCompSetIgnoreCase(true); + AutoCompSetFillUps(wxT(" \t")); + AutoCompSetDropRestOfWord(true); + + SetEOLMode(settings->GetLineEndingType()); +} + +void ctlSQLBox::SetDatabase(pgConn *db) +{ + m_database = db; +} + +void ctlSQLBox::SetChanged(bool b) +{ + if (m_changed != b) + { + m_changed = b; + UpdateTitle(); + } +} + +bool ctlSQLBox::IsChanged() +{ + return m_changed; +} + +void ctlSQLBox::SetOrigin(int origin) +{ + m_origin = origin; +} + +int ctlSQLBox::GetOrigin() +{ + return m_origin; +} + +void ctlSQLBox::SetFilename(wxString &filename) +{ + m_filename = filename; + UpdateTitle(); +} + +wxString ctlSQLBox::GetFilename() +{ + return m_filename; +} + +void ctlSQLBox::SetTitle(wxString &title) +{ + m_title = title; +} + +wxString ctlSQLBox::GetTitle(bool withChangeInd) +{ + wxString title = m_title; + wxString chStr; + if (!withChangeInd) + { + chStr = GetChangeIndicator(); + if (title.EndsWith(chStr)) + title = title.Mid(0, title.Len() - chStr.Len()); + } + return title; +} + +wxString ctlSQLBox::GetChangeIndicator() +{ + if (m_changestr.IsEmpty()) + m_changestr = _("*"); + return m_changestr; +} + +void ctlSQLBox::UpdateTitle() +{ + bool hasCh = false; + wxString chStr = GetChangeIndicator(); + wxString title = GetFilename(); + + if (!title.IsEmpty()) + title = wxFileName::FileName(title).GetFullName(); + else + title = GetTitle(); + + hasCh = title.EndsWith(chStr); + + if (IsChanged() && !hasCh) + title = title + chStr; + else if (!IsChanged() && hasCh) + title = title.Mid(0, title.Len() - chStr.Len()); + + SetTitle(title); +} + +void ctlSQLBox::OnSearchReplace(wxCommandEvent &ev) +{ + if (!m_dlgFindReplace) + { + m_dlgFindReplace = new dlgFindReplace(this); + m_dlgFindReplace->Show(true); + } + else + { + m_dlgFindReplace->Show(true); + m_dlgFindReplace->SetFocus(); + } + + wxString selText = GetSelectedText(); + if (!selText.IsEmpty()) + { + m_dlgFindReplace->SetFindString(selText); + } + + m_dlgFindReplace->FocusSearch(); +} + +bool ctlSQLBox::Find(const wxString &find, bool wholeWord, bool matchCase, bool useRegexps, bool startAtTop, bool reverse) +{ + if (!DoFind(find, wxString(wxEmptyString), false, wholeWord, matchCase, useRegexps, startAtTop, reverse)) + { + wxWindow *w = wxWindow::FindFocus(); + wxMessageBox(_("Reached the end of the document"), _("Find text"), wxICON_EXCLAMATION | wxOK, w); + return false; + } + return true; +} + +bool ctlSQLBox::Replace(const wxString &find, const wxString &replace, bool wholeWord, bool matchCase, bool useRegexps, bool startAtTop, bool reverse) +{ + if (!DoFind(find, replace, true, wholeWord, matchCase, useRegexps, startAtTop, reverse)) + { + wxWindow *w = wxWindow::FindFocus(); + wxMessageBox(_("Reached the end of the document"), _("Replace text"), wxICON_EXCLAMATION | wxOK, w); + return false; + } + return true; +} + +bool ctlSQLBox::ReplaceAll(const wxString &find, const wxString &replace, bool wholeWord, bool matchCase, bool useRegexps) +{ + // Use DoFind to repeatedly replace text + int count = 0; + int initialPos = GetCurrentPos(); + GotoPos(0); + + while(DoFind(find, replace, true, wholeWord, matchCase, useRegexps, false, false)) + count++; + + GotoPos(initialPos); + + wxString msg; + msg.Printf(wxPLURAL("%d replacement made.", "%d replacements made.", count), count); + wxMessageBox(msg, _("Replace all"), wxOK | wxICON_INFORMATION); + + if (count) + return true; + else + return false; +} + +bool ctlSQLBox::DoFind(const wxString &find, const wxString &replace, bool doReplace, bool wholeWord, bool matchCase, bool useRegexps, bool startAtTop, bool reverse) +{ + int flags = 0; + int startPos = GetSelectionStart(); + int endPos = GetTextLength(); + + // Setup flags + if (wholeWord) + flags |= wxSTC_FIND_WHOLEWORD; + + if (matchCase) + flags |= wxSTC_FIND_MATCHCASE; + + // Replace the current selection, if there is one and it matches the find param. + wxString current = GetSelectedText(); + if (doReplace) + { + if (useRegexps) + { + CharacterRange cr = RegexFindText(GetSelectionStart(), GetSelectionEnd(), find); + if (GetSelectionStart() == cr.cpMin && GetSelectionEnd() == cr.cpMax) + { + if (cr.cpMin == cr.cpMax) // Must be finding a special char, such as $ (line end) + { + InsertText(cr.cpMax, replace); + SetSelection(cr.cpMax, cr.cpMax + replace.Length()); + SetCurrentPos(cr.cpMax + replace.Length()); + + // Stop if we've got to the end. This is important for the $ + // case where it'll just keep finding the end of the line!! + if ((int)(cr.cpMin + replace.Length()) == GetLength()) + return false; + } + else + { + ReplaceSelection(replace); + SetSelection(startPos, startPos + replace.Length()); + SetCurrentPos(startPos + replace.Length()); + } + } + } + else if ((matchCase && current == find) || (!matchCase && current.Upper() == find.Upper())) + { + ReplaceSelection(replace); + if (!reverse) + { + SetSelection(startPos, startPos + replace.Length()); + SetCurrentPos(startPos + replace.Length()); + } + else + { + SetSelection(startPos + replace.Length(), startPos); + SetCurrentPos(startPos); + } + } + } + + //////////////////////////////////////////////////////////////////////// + // Figure out the starting position for the next search + //////////////////////////////////////////////////////////////////////// + + if (startAtTop) + { + startPos = 0; + endPos = GetTextLength(); + } + else + { + if (reverse) + { + endPos = 0; + startPos = GetCurrentPos(); + } + else + { + endPos = GetTextLength(); + startPos = GetCurrentPos(); + } + } + + size_t selStart = 0, selEnd = 0; + + if (useRegexps) + { + CharacterRange cr = RegexFindText(startPos, endPos, find); + selStart = cr.cpMin; + selEnd = cr.cpMax; + } + else + { + selStart = FindText(startPos, endPos, find, flags); + selEnd = selStart + find.Length(); + } + + if (selStart != (size_t)(-1)) + { + if (reverse) + { + SetCurrentPos(selStart); + SetSelection(selEnd, selStart); + } + else + { + SetCurrentPos(selEnd); + SetSelection(selStart, selEnd); + } + EnsureCaretVisible(); + return true; + } + else + return false; +} +void ctlSQLBox::SetAutoReplaceList(queryMacroList *autorep) { + autoreplace=autorep; +} +void ctlSQLBox::OnKeyDown(wxKeyEvent &event) +{ + //wxString autoreplace[]={wxT("se"),wxT("select * from"),wxT("sc"),wxT("select count(*) from"),wxT("si"),wxT("select * from info_oper where"),wxT("sh"),wxT("select * from info_history where")}; +#ifdef __WXGTK__ + event.m_metaDown = false; +#endif + + // Get the line ending type + wxString lineEnd; + switch (GetEOLMode()) + { + case wxSTC_EOL_LF: + lineEnd = wxT("\n"); + break; + case wxSTC_EOL_CRLF: + lineEnd = wxT("\r\n"); + break; + case wxSTC_EOL_CR: + lineEnd = wxT("\r"); + break; + } + // AutoReplace + if (event.GetKeyCode() == ' ') { + //int start = GetSelectionStart(); + //int column = GetColumn(start); + //int curLineNum = GetCurrentLine(); + int pos = GetCurrentPos(); + //wxString line = GetLine(GetCurrentLine()); + wxString t; + wxString wc; + char c; + bool f; + wxString rpl = wxT(""); + wxString rpl2 = wxT(""); + for (int k=0;autoreplace!=0&&kCount();k=k+1 ) { + f=false; + queryMacroItem *mi=autoreplace->GetItem(k); + rpl = mi->GetName(); + //rpl2 =ss[k+1]; + //rpl=mi->GetName(); + rpl2 =mi->GetQuery(); + if ((pos-rpl.Length())==0) { + t = GetTextRange(pos-rpl.Length(), pos); + f=true; + } else {t = GetTextRange(pos-rpl.Length()-1, pos);} + //wc = GetTextRange(pos-rpl.Length()-1, pos-rpl.Length()-1); + wxChar c = t.GetChar(0); + if (!((c >= '0' && c <= '9')) && + !(c >= 'a' && c <= 'z') && + !(c >= 'A' && c <= 'Z') && + !(c == '_')) + { + f=true; + } + + + if (t.EndsWith(rpl)&&f) + { + //SetTargetStart(pos-2); + //SetTargetEnd(pos); + //ReplaceTarget(rpl2); + + SetSelection(pos-rpl.Length(),pos); + // Lose any selected text. + ReplaceSelection(wxEmptyString); + // Insert a replacement \n (or whatever), and the indent at the insertion point. + InsertText(GetCurrentPos(), rpl2); + // Now, reset the position, and clear the selection + SetCurrentPos(GetCurrentPos() + rpl2.Length()); + SetSelection(GetCurrentPos(), GetCurrentPos()); + + } + } + } + // Block comment/uncomment + if (event.GetKeyCode() == 'K') + { + // Comment (Ctrl+k) + if (event.GetModifiers() == wxMOD_CONTROL) + { + if (BlockComment(false)) + return; + } + // Uncomment (Ctrl+Shift+K) + else if (event.GetModifiers() == (wxMOD_CONTROL | wxMOD_SHIFT)) + { + if (BlockComment(true)) + return; + } + } + + // Autoindent + if (m_autoIndent && event.GetKeyCode() == WXK_RETURN) + { + wxString indent, line; + line = GetLine(GetCurrentLine()); + + // Get the offset for the current line - basically, whether + // or not it ends with a \r\n, \n or \r, and if so, the length + int offset = 0; + if (line.EndsWith(wxT("\r\n"))) + offset = 2; + else if (line.EndsWith(wxT("\n"))) + offset = 1; + else if (line.EndsWith(wxT("\r"))) + offset = 1; + + // Get the indent. This is every leading space or tab on the + // line, up until the current cursor position. + int x = 0; + int max = line.Length() - (GetLineEndPosition(GetCurrentLine()) - GetCurrentPos()) - offset; + if(line != wxEmptyString) + { + while ((line[x] == '\t' || line[x] == ' ') && x < max) + indent += line[x++]; + } + + // Select any indent in front of the cursor to be removed. If + // the cursor is positioned after any non-indent characters, + // we don't remove anything. If there is already some selected, + // don't select anything new at all. + if (indent.Length() != 0 && + (unsigned int)GetCurrentPos() <= ((GetLineEndPosition(GetCurrentLine()) - line.Length()) + indent.Length() + offset) && + GetSelectedText() == wxEmptyString) + SetSelection(GetLineEndPosition(GetCurrentLine()) - line.Length() + offset, GetLineEndPosition(GetCurrentLine()) - line.Length() + indent.Length() + offset); + + // Lose any selected text. + ReplaceSelection(wxEmptyString); + + // Insert a replacement \n (or whatever), and the indent at the insertion point. + InsertText(GetCurrentPos(), lineEnd + indent); + + // Now, reset the position, and clear the selection + SetCurrentPos(GetCurrentPos() + indent.Length() + lineEnd.Length()); + SetSelection(GetCurrentPos(), GetCurrentPos()); + } + else if (m_dlgFindReplace && event.GetKeyCode() == WXK_F3) + { + m_dlgFindReplace->FindNext(); + } + else + event.Skip(); +} + +bool ctlSQLBox::BlockComment(bool uncomment) +{ + wxString lineEnd; + switch (GetEOLMode()) + { + case wxSTC_EOL_LF: + lineEnd = wxT("\n"); + break; + case wxSTC_EOL_CRLF: + lineEnd = wxT("\r\n"); + break; + case wxSTC_EOL_CR: + lineEnd = wxT("\r"); + break; + } + + // Save the start position + const wxString comment = wxT("-- "); + int start = GetSelectionStart(); + + if (!GetSelectedText().IsEmpty()) + { + wxString selection = GetSelectedText(); + if (!uncomment) + { + selection.Replace(lineEnd, lineEnd + comment); + selection.Prepend(comment); + if (selection.EndsWith(comment)) + selection = selection.Left(selection.Length() - comment.Length()); + } + else + { + selection.Replace(lineEnd + comment, lineEnd); + if (selection.StartsWith(comment)) + selection = selection.Right(selection.Length() - comment.Length()); + } + ReplaceSelection(selection); + SetSelection(start, start + selection.Length()); + } + else + { + // No text selection - (un)comment the current line + int column = GetColumn(start); + int curLineNum = GetCurrentLine(); + int pos = PositionFromLine(curLineNum); + + if (!uncomment) + { + InsertText(pos, comment); + } + else + { + wxString t = GetTextRange(pos, pos + comment.Length()); + if (t == comment) + { + // The line starts with a comment, so we remove it + SetTargetStart(pos); + SetTargetEnd(pos + comment.Length()); + ReplaceTarget(wxT("")); + } + else + { + // The line doesn't start with a comment, do nothing + return false; + } + } + + if (GetLineCount() > curLineNum) + { + wxString nextLine = GetLine(curLineNum + 1); + if (nextLine.EndsWith(lineEnd)) + nextLine = nextLine.Left(nextLine.Length() - lineEnd.Length()); + + int nextColumn = (nextLine.Length() < (unsigned int)column ? nextLine.Length() : column); + GotoPos(PositionFromLine(curLineNum + 1) + nextColumn); + } + } + + return true; +} + +void ctlSQLBox::OnKillFocus(wxFocusEvent &event) +{ + AutoCompCancel(); + event.Skip(); +} + +void ctlSQLBox::UpdateLineNumber() +{ + bool showlinenumber; + + settings->Read(wxT("frmQuery/ShowLineNumber"), &showlinenumber, false); + if (showlinenumber) + { + long int width = TextWidth(wxSTC_STYLE_LINENUMBER, + wxT(" ") + NumToStr((long int)GetLineCount()) + wxT(" ")); + if (width != GetMarginWidth(0)) + { + SetMarginWidth(0, width); + Update(); + } + } + else + { + SetMarginWidth(0, 0); + } +} + +void ctlSQLBox::OnEndProcess(wxProcessEvent &ev) +{ + if (process) + { + processErrorOutput = process->ReadErrorStream(); + processOutput += process->ReadInputStream(); + processExitCode = ev.GetExitCode(); + delete process; + process = 0; + processID = 0; + } +} + +wxString ctlSQLBox::ExternalFormat() +{ + wxString msg; + processOutput = wxEmptyString; + + bool isSelected = true; + wxString processInput = GetSelectedText(); + if (processInput.IsEmpty()) + { + processInput = GetText(); + isSelected = false; + } + if (processInput.IsEmpty()) + return _("Nothing to format."); + + wxString formatCmd = settings->GetExtFormatCmd(); + if (formatCmd.IsEmpty()) + { + return _("You need to setup a formatting command"); + } + + if (process) + { + delete process; + process = NULL; + processID = 0; + } + processOutput = wxEmptyString; + processErrorOutput = wxEmptyString; + processExitCode = 0; + + process = new sysProcess(this, wxConvUTF8); + processID = wxExecute(formatCmd, wxEXEC_ASYNC | wxEXEC_MAKE_GROUP_LEADER, process); + if (!processID) + { + delete process; + process = NULL; + processID = 0; + msg = _("Couldn't run formatting command: ") + formatCmd; + return msg; + } + process->WriteOutputStream(processInput); + process->CloseOutput(); + + int timeoutMs = settings->GetExtFormatTimeout(); + int timeoutStepMs = 100; + int i = 0; + while (process && i * timeoutStepMs < timeoutMs) + { + wxSafeYield(); + if (process) + processOutput += process->ReadInputStream(); + wxSafeYield(); + wxMilliSleep(timeoutStepMs); + i++; + } + + if (process) + { + AbortProcess(); + return wxString::Format(_("Formatting command did not respond in %d ms"), timeoutMs); + } + + if (processExitCode != 0) + { + processErrorOutput.Replace(wxT("\n"), wxT(" ")); + msg = wxString::Format(_("Error %d: "), processExitCode) + processErrorOutput; + return msg; + } + else if (processOutput.Trim().IsEmpty()) + { + return _("Formatting command error: Output is empty."); + } + + if (isSelected) + ReplaceSelection(processOutput); + else + SetText(processOutput); + + return _("Formatting complete."); +} + +void ctlSQLBox::AbortProcess() +{ + if (process && processID) + { +#ifdef __WXMSW__ + // SIGTERM is useless for Windows console apps + wxKill(processID, wxSIGKILL, NULL, wxKILL_CHILDREN); +#else + wxKill(processID, wxSIGTERM, NULL, wxKILL_CHILDREN); +#endif + processID = 0; + } +} +long ctlSQLBox::SelectQuery(int startposition) +{ + int pos = GetCurrentPos(); + wxChar ch = GetCharAt(pos - 1); + wxChar nextch = GetCharAt(pos); + int st = GetStyleAt(pos - 1); + int endPos = GetTextLength(); + int match; + int pend=endPos; + int pstart=0; + if ((ch == ';')) { + pend=pos; + pos=pos-1; + } else + { + while (pos= 0) + { + ch = GetCharAt(pos); + st = GetStyleAt(pos); + if ((ch == ';') && + st != 2 && st != 6 && st != 7) + { + //pstart=pos+1; + break; + } + if (ch>' ') pstart=pos; + + } + if (startposition<0) SetSelection(pstart,pend); + return (pstart <<16)+pend; + +} +void ctlSQLBox::OnPositionStc(wxStyledTextEvent &event) +{ + int pos = GetCurrentPos(); + wxChar ch = GetCharAt(pos - 1); + wxChar nextch = GetCharAt(pos); + int st = GetStyleAt(pos - 1); + int match; + + + // Line numbers + // Ensure we don't recurse through any paint handlers on Mac +#ifdef __WXMAC__ + Freeze(); +#endif + UpdateLineNumber(); +#ifdef __WXMAC__ + Thaw(); +#endif + + // Clear all highlighting + BraceBadLight(wxSTC_INVALID_POSITION); + + // Check for braces that aren't in comment styles, + // double quoted styles or single quoted styles + if ((ch == '{' || ch == '}' || + ch == '[' || ch == ']' || + ch == '(' || ch == ')') && + st != 2 && st != 6 && st != 7) + { + match = BraceMatch(pos - 1); + if (match != wxSTC_INVALID_POSITION) + BraceHighlight(pos - 1, match); + } + else if ((nextch == '{' || nextch == '}' || + nextch == '[' || nextch == ']' || + nextch == '(' || nextch == ')') && + st != 2 && st != 6 && st != 7) + { + match = BraceMatch(pos); + if (match != wxSTC_INVALID_POSITION) + BraceHighlight(pos, match); + } + + // Roll back through the doc and highlight any unmatched braces + while ((pos--) >= 0) + { + ch = GetCharAt(pos); + st = GetStyleAt(pos); + + if ((ch == '{' || ch == '}' || + ch == '[' || ch == ']' || + ch == '(' || ch == ')') && + st != 2 && st != 6 && st != 7) + { + match = BraceMatch(pos); + if (match == wxSTC_INVALID_POSITION) + { + BraceBadLight(pos); + break; + } + } + } + + event.Skip(); +} + + +void ctlSQLBox::OnMarginClick(wxStyledTextEvent &event) +{ + if (event.GetMargin() == 2) + ToggleFold(LineFromPosition(event.GetPosition())); + + event.Skip(); +} + + +extern "C" char *tab_complete(const char *allstr, const int startptr, const int endptr, void *dbptr); +void ctlSQLBox::OnAutoComplete(wxCommandEvent &rev) +{ + if (GetReadOnly()) + return; + if (m_database == NULL) + return; + if (m_autocompDisabled) + return; + + wxString what = GetCurLine().Left(GetCurrentPos() - PositionFromLine(GetCurrentLine()));; + int spaceidx = what.Find(' ', true); + + char *tab_ret; + if (spaceidx == -1) + tab_ret = tab_complete(what.mb_str(wxConvUTF8), 0, what.Len() + 1, m_database); + else + tab_ret = tab_complete(what.mb_str(wxConvUTF8), spaceidx + 1, what.Len() + 1, m_database); + + if (tab_ret == NULL || tab_ret[0] == '\0') + return; /* No autocomplete available for this string */ + + wxString wxRet = wxString(tab_ret, wxConvUTF8); + free(tab_ret); + + // Switch to the generic list control. Native doesn't play well with + // autocomplete on Mac. +#ifdef __WXMAC__ + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), true); +#endif + + if (spaceidx == -1) + AutoCompShow(what.Len(), wxRet); + else + AutoCompShow(what.Len() - spaceidx - 1, wxRet); + + // Now switch back +#ifdef __WXMAC__ + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), false); +#endif +} + + +ctlSQLBox::~ctlSQLBox() +{ + if (m_dlgFindReplace) + { + m_dlgFindReplace->Destroy(); + m_dlgFindReplace = 0; + } + AbortProcess(); +} + + +/* + * Callback function from tab-complete.c, bridging the gap between C++ and C. + * Execute a query using the C++ APIs, returning it as a tab separated + * "char*-string" + * The query is expected to return only one column, and will have an ORDER BY + * clause for this column added automatically. + */ +extern "C" +char *pg_query_to_single_ordered_string(char *query, void *dbptr) +{ + pgConn *db = (pgConn *)dbptr; + pgSet *res = db->ExecuteSet(wxString(query, wxConvUTF8) + wxT(" ORDER BY 1")); + if (!res) + return NULL; + + wxString ret = wxString(); + wxString tmp; + + while (!res->Eof()) + { + tmp = res->GetVal(0); + if (tmp.Mid(tmp.Length() - 1) == wxT(".")) + ret += tmp + wxT("\t"); + else + ret += tmp + wxT(" \t"); + + res->MoveNext(); + } + + if(res) + { + delete res; + res = NULL; + } + ret.Trim(); + // Trims both space and tab, but we want to keep the space! + if (ret.Length() > 0) + ret += wxT(" "); + + return strdup(ret.mb_str(wxConvUTF8)); +} + + +// Find some text in the document. +CharacterRange ctlSQLBox::RegexFindText(int minPos, int maxPos, const wxString &text) +{ + TextToFind ft; + ft.chrg.cpMin = minPos; + ft.chrg.cpMax = maxPos; + wxWX2MBbuf buf = text.mb_str(wxConvUTF8); + ft.lpstrText = (char *)(const char *)buf; +/* + wx 2.8.12 + if (SendMsg(2150, wxSTC_FIND_REGEXP, (long)&ft) == -1) + { + ft.chrgText.cpMin = -1; + ft.chrgText.cpMax = -1; + } +*/ + return ft.chrgText; +} diff --git a/ctl/ctlSQLGrid.cpp b/ctl/ctlSQLGrid.cpp new file mode 100644 index 0000000..b189054 --- /dev/null +++ b/ctl/ctlSQLGrid.cpp @@ -0,0 +1,554 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlSQLGrid.cpp - SQL Query result window +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +#include "db/pgConn.h" +#include "ctl/ctlSQLGrid.h" +#include "utils/sysSettings.h" +#include "frm/frmExport.h" + + +#define EXTRAEXTENT_HEIGHT 6 +#define EXTRAEXTENT_WIDTH 6 + +BEGIN_EVENT_TABLE(ctlSQLGrid, wxGrid) + EVT_MOUSEWHEEL(ctlSQLGrid::OnMouseWheel) + EVT_GRID_COL_SIZE(ctlSQLGrid::OnGridColSize) + EVT_GRID_LABEL_LEFT_CLICK(ctlSQLGrid::OnLabelClick) +END_EVENT_TABLE() + +IMPLEMENT_DYNAMIC_CLASS(ctlSQLGrid, wxGrid) + +ctlSQLGrid::ctlSQLGrid() +{ +} + +ctlSQLGrid::ctlSQLGrid(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size) + : wxGrid(parent, id, pos, size, wxWANTS_CHARS | wxVSCROLL | wxHSCROLL) +{ + // Set cells font + wxFont fntCells(settings->GetSQLFont()); + SetDefaultCellFont(fntCells); + // Set labels font + wxFont fntLabel(settings->GetSystemFont()); + fntLabel.SetWeight(wxBOLD); + SetLabelFont(fntLabel); + SetColLabelAlignment(wxALIGN_LEFT, wxALIGN_CENTER); + SetRowLabelSize(50); + SetDefaultRowSize(fntCells.GetPointSize() * 2 + 2); + SetColLabelSize(fntLabel.GetPointSize() * 4); + SetDefaultCellOverflow(false); + + Connect(wxID_ANY, wxEVT_GRID_LABEL_LEFT_DCLICK, wxGridEventHandler(ctlSQLGrid::OnLabelDoubleClick)); +} + +void ctlSQLGrid::OnGridColSize(wxGridSizeEvent &event) +{ + // Save key="index:label", value=size + int col = event.GetRowOrCol(); + colSizes[GetColKeyValue(col)] = GetColSize(col); +} +void ctlSQLGrid::OnCopy(wxCommandEvent &ev) +{ + Copy(); +} + +void ctlSQLGrid::OnMouseWheel(wxMouseEvent &event) +{ + if (event.ControlDown() || event.CmdDown()) + { + wxFont fontlabel = GetLabelFont(); + wxFont fontcells = GetDefaultCellFont(); + if (event.GetWheelRotation() > 0) + { + fontlabel.SetPointSize(fontlabel.GetPointSize() - 1); + fontcells.SetPointSize(fontcells.GetPointSize() - 1); + } + else + { + fontlabel.SetPointSize(fontlabel.GetPointSize() + 1); + fontcells.SetPointSize(fontcells.GetPointSize() + 1); + } + SetLabelFont(fontlabel); + SetDefaultCellFont(fontcells); + SetColLabelSize(fontlabel.GetPointSize() * 4); + SetDefaultRowSize(fontcells.GetPointSize() * 2); + for (int index = 0; index < GetNumberCols(); index++) + SetColSize(index, -1); + ForceRefresh(); + } + else + event.Skip(); +} + +wxString ctlSQLGrid::GetExportLine(int row) +{ + return GetExportLine(row, 0, GetNumberCols() - 1); +} + + +wxString ctlSQLGrid::GetExportLine(int row, int col1, int col2) +{ + wxArrayInt cols; + wxString str; + int i; + + if (col2 < col1) + return str; + + cols.Alloc(col2 - col1 + 1); + for (i = col1; i <= col2; i++) + { + cols.Add(i); + } + + return GetExportLine(row, cols); +} + +wxString ctlSQLGrid::GetExportLine(int row, wxArrayInt cols) +{ + wxString str; + unsigned int col; + + if (GetNumberCols() == 0) + return str; + + for (col = 0 ; col < cols.Count() ; col++) + { + if (col > 0) + str.Append(settings->GetCopyColSeparator()); + + wxString text = GetCellValue(row, cols[col]); + + bool needQuote = false; + if (settings->GetCopyQuoting() == 1) + { + needQuote = IsColText(cols[col]); + } + else if (settings->GetCopyQuoting() == 2) + /* Quote everything */ + needQuote = true; + + if (needQuote) + str.Append(settings->GetCopyQuoteChar()); + str.Append(text); + if (needQuote) + str.Append(settings->GetCopyQuoteChar()); + } + return str; +} + +wxString ctlSQLGrid::GetColumnName(int colNum) +{ + wxString columnName = GetColLabelValue(colNum); + columnName = columnName.Left(columnName.find(wxT("\n"))); + return columnName; +} + +void ctlSQLGrid::AppendColumnHeader(wxString &str, int start, int end) +{ + size_t i, arrsize; + arrsize = (end - start + 1); + wxArrayInt columns; + + for(i = 0; i < arrsize; i++) + { + columns.Add(start + i); + } + + AppendColumnHeader(str, columns); +} + +void ctlSQLGrid::AppendColumnHeader(wxString &str, wxArrayInt columns) +{ + if(settings->GetColumnNames()) + { + bool CopyQuoting = (settings->GetCopyQuoting() == 1 || settings->GetCopyQuoting() == 2); + size_t i; + + for(i = 0; i < columns.Count() ; i++) + { + long columnPos = columns.Item(i); + if(i > 0) + str.Append(settings->GetCopyColSeparator()); + + if(CopyQuoting) + str.Append(settings->GetCopyQuoteChar()); + str.Append(GetColumnName(columnPos)); + if(CopyQuoting) + str.Append(settings->GetCopyQuoteChar()); + + } + str.Append(END_OF_LINE); + } +} + +int ctlSQLGrid::Copy() +{ + wxString str; + int copied = 0; + size_t i; + + + + if (GetSelectedRows().GetCount()) + { + AppendColumnHeader(str, 0, (GetNumberCols() - 1)); + + wxArrayInt rows = GetSelectedRows(); + + for (i = 0 ; i < rows.GetCount() ; i++) + { + str.Append(GetExportLine(rows.Item(i))); + if (rows.GetCount() > 1) + str.Append(END_OF_LINE); + } + + copied = rows.GetCount(); + } + else if (GetSelectedCols().GetCount()) + { + wxArrayInt cols = GetSelectedCols(); + size_t numRows = GetNumberRows(); + + AppendColumnHeader(str, cols); + + for (i = 0 ; i < numRows ; i++) + { + str.Append(GetExportLine(i, cols)); + + if (numRows > 1) + str.Append(END_OF_LINE); + } + + copied = numRows; + } + else if (GetSelectionBlockTopLeft().GetCount() > 0 && + GetSelectionBlockBottomRight().GetCount() > 0) + { + unsigned int x1, x2, y1, y2; + + x1 = GetSelectionBlockTopLeft()[0].GetCol(); + x2 = GetSelectionBlockBottomRight()[0].GetCol(); + y1 = GetSelectionBlockTopLeft()[0].GetRow(); + y2 = GetSelectionBlockBottomRight()[0].GetRow(); + + AppendColumnHeader(str, x1, x2); + + for (i = y1; i <= y2; i++) + { + str.Append(GetExportLine(i, x1, x2)); + + if (y2 > y1) + str.Append(END_OF_LINE); + } + + copied = y2 - y1 + 1; + } + else + { + int row, col; + + row = GetGridCursorRow(); + col = GetGridCursorCol(); + + AppendColumnHeader(str, col, col); + + str.Append(GetExportLine(row, col, col)); + copied = 1; + } + + if (copied && wxTheClipboard->Open()) + { + wxTheClipboard->SetData(new wxTextDataObject(str)); + wxTheClipboard->Close(); + } + else + { + copied = 0; + } + + return copied; +} + +void ctlSQLGrid::OnLabelDoubleClick(wxGridEvent &event) +{ + int maxHeight, maxWidth; + GetClientSize(&maxWidth, &maxHeight); + int row = event.GetRow(); + int col = event.GetCol(); + + int extent, extentWant = 0; + + if (row >= 0) + { + for (col = 0 ; col < GetNumberCols() ; col++) + { + extent = GetBestSize(row, col).GetHeight(); + if (extent > extentWant) + extentWant = extent; + } + + extentWant += EXTRAEXTENT_HEIGHT; + extentWant = wxMax(extentWant, GetRowMinimalAcceptableHeight()); + extentWant = wxMin(extentWant, maxHeight * 3 / 4); + int currentHeight = GetRowHeight(row); + + if (currentHeight >= maxHeight * 3 / 4 || currentHeight == extentWant) + extentWant = GetRowMinimalAcceptableHeight(); + else if (currentHeight < maxHeight / 4) + extentWant = wxMin(maxHeight / 4, extentWant); + else if (currentHeight < maxHeight / 2) + extentWant = wxMin(maxHeight / 2, extentWant); + else if (currentHeight < maxHeight * 3 / 4) + extentWant = wxMin(maxHeight * 3 / 4, extentWant); + + if (extentWant != currentHeight) + { + BeginBatch(); + if(IsCellEditControlShown()) + { + HideCellEditControl(); + SaveEditControlValue(); + } + + SetRowHeight(row, extentWant); + EndBatch(); + } + } + else if (col >= 0) + { + // Holding Ctrl or Meta switches back to automatic column's sizing + if (event.ControlDown() || event.CmdDown()) + { + colSizes.erase(GetColKeyValue(col)); + BeginBatch(); + if(IsCellEditControlShown()) + { + HideCellEditControl(); + SaveEditControlValue(); + } + AutoSizeColumn(col, false); + EndBatch(); + } + else // toggle between some predefined sizes + { + + if (col < (int)colMaxSizes.GetCount() && colMaxSizes[col] >= 0) + extentWant = colMaxSizes[col]; + else + { + for (row = 0 ; row < GetNumberRows() ; row++) + { + if (CheckRowPresent(row)) + { + extent = GetBestSize(row, col).GetWidth(); + if (extent > extentWant) + extentWant = extent; + } + } + } + + extentWant += EXTRAEXTENT_WIDTH; + extentWant = wxMax(extentWant, GetColMinimalAcceptableWidth()); + extentWant = wxMin(extentWant, maxWidth * 3 / 4); + int currentWidth = GetColumnWidth(col); + + if (currentWidth >= maxWidth * 3 / 4 || currentWidth == extentWant) + extentWant = GetColMinimalAcceptableWidth(); + else if (currentWidth < maxWidth / 4) + extentWant = wxMin(maxWidth / 4, extentWant); + else if (currentWidth < maxWidth / 2) + extentWant = wxMin(maxWidth / 2, extentWant); + else if (currentWidth < maxWidth * 3 / 4) + extentWant = wxMin(maxWidth * 3 / 4, extentWant); + + if (extentWant != currentWidth) + { + BeginBatch(); + if(IsCellEditControlShown()) + { + HideCellEditControl(); + SaveEditControlValue(); + } + SetColumnWidth(col, extentWant); + EndBatch(); + colSizes[GetColKeyValue(col)] = extentWant; + } + } + } +} + +void ctlSQLGrid::OnLabelClick(wxGridEvent &event) +{ + int row = event.GetRow(); + int col = event.GetCol(); + + // add support for (de)selecting multiple rows and cols with Control pressed + if ( row >= 0 && (event.ControlDown() || event.CmdDown()) ) + { + if (GetSelectedRows().Index(row) == wxNOT_FOUND) + SelectRow(row, true); + else + DeselectRow(row); + } + else if ( col >= 0 && (event.ControlDown() || event.CmdDown()) ) + { + if (GetSelectedCols().Index(col) == wxNOT_FOUND) + SelectCol(col, true); + else + DeselectCol(col); + } + else + event.Skip(); +} + +void ctlSQLGrid::AutoSizeColumn(int col, bool setAsMin, bool doLimit) +{ + ColKeySizeHashMap::iterator it = colSizes.find(GetColKeyValue(col)); + if (it != colSizes.end()) // Restore user-specified size + SetColSize(col, it->second); + else + wxGrid::AutoSizeColumn(col, setAsMin); + + if (doLimit) + { + int newSize, oldSize; + int maxSize, totalSize = 0, availSize; + + oldSize = GetColSize(col); + availSize = GetClientSize().GetWidth() - GetRowLabelSize(); + maxSize = availSize / 2; + for (int i = 0 ; i < GetNumberCols() ; i++) + totalSize += GetColSize(i); + + if (oldSize > maxSize && totalSize > availSize) + { + totalSize -= oldSize; + /* Shrink wide column to maxSize. + * If the rest of the columns are short, make sure to use all the remaining space, + * but no more than oldSize (which is enough according to AutoSizeColumns()) + */ + newSize = wxMin(oldSize, wxMax(maxSize, availSize - totalSize)); + SetColSize(col, newSize); + } + } +} + +void ctlSQLGrid::AutoSizeColumns(bool setAsMin) +{ + wxCoord newSize, oldSize; + wxCoord maxSize, totalSize = 0, availSize; + int col, nCols = GetNumberCols(); + int row, nRows = GetNumberRows(); + colMaxSizes.Empty(); + + /* We need to check each cell's width to choose best. wxGrid::AutoSizeColumns() + * is good, but looping through long result sets gives a noticeable slowdown. + * Thus we'll check every first 500 cells for each column. + */ + + // First pass: auto-size columns + for (col = 0 ; col < nCols; col++) + { + ColKeySizeHashMap::iterator it = colSizes.find(GetColKeyValue(col)); + if (it != colSizes.end()) // Restore user-specified size + { + newSize = it->second; + colMaxSizes.Add(-1); + } + else + { + wxClientDC dc(GetGridWindow()); + newSize = 0; + // get cells's width + for (row = 0 ; row < wxMin(nRows, 500) ; row++) + { + wxSize size = GetBestSize(row, col); + if ( size.x > newSize ) + newSize = size.x; + } + // get column's label width + wxCoord w, h; + dc.SetFont( GetLabelFont() ); + dc.GetMultiLineTextExtent( GetColLabelValue(col), &w, &h ); + if ( GetColLabelTextOrientation() == wxVERTICAL ) + w = h; + + if ( w > newSize ) + newSize = w; + + if (!newSize) + newSize = GetRowLabelSize(); + else + // leave some space around text + newSize += 6; + + colMaxSizes.Add(newSize); + } + SetColSize(col, newSize); + totalSize += newSize; + } + + availSize = GetClientSize().GetWidth() - GetRowLabelSize(); + + // Second pass: shrink wide columns if exceeded available width + if (totalSize > availSize) + { + // A wide column shouldn't take up more than 50% of the visible space + maxSize = availSize / 2; + for (col = 0 ; col < nCols ; col++) + { + oldSize = GetColSize(col); + // Is too wide and no user-specified size + if (oldSize > maxSize && !(col < (int)colMaxSizes.GetCount() && colMaxSizes[col] == -1)) + { + totalSize -= oldSize; + /* Shrink wide column to maxSize. + * If the rest of the columns are short, make sure to use all the remaining space, + * but no more than oldSize (which is enough according to first pass) + */ + newSize = wxMin(oldSize, wxMax(maxSize, availSize - totalSize)); + SetColSize(col, newSize); + totalSize += newSize; + } + } + } +} + +wxString ctlSQLGrid::GetColKeyValue(int col) +{ + wxString colKey = wxString::Format(wxT("%d:"), col) + GetColLabelValue(col); + return colKey; +} + +wxSize ctlSQLGrid::GetBestSize(int row, int col) +{ + wxSize size; + + wxGridCellAttr *attr = GetCellAttr(row, col); + wxGridCellRenderer *renderer = attr->GetRenderer(this, row, col); + if ( renderer ) + { + wxClientDC dc(GetGridWindow()); + size = renderer->GetBestSize(*this, *attr, dc, row, col); + renderer->DecRef(); + } + + attr->DecRef(); + + return size; +} diff --git a/ctl/ctlSQLResult.cpp b/ctl/ctlSQLResult.cpp new file mode 100644 index 0000000..b95fd20 --- /dev/null +++ b/ctl/ctlSQLResult.cpp @@ -0,0 +1,480 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlSQLResult.cpp - SQL Query result window +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +#include "db/pgConn.h" +#include "db/pgQueryThread.h" +#include "ctl/ctlSQLResult.h" +#include "utils/sysSettings.h" +#include "frm/frmExport.h" + + + +ctlSQLResult::ctlSQLResult(wxWindow *parent, pgConn *_conn, wxWindowID id, const wxPoint &pos, const wxSize &size) + : ctlSQLGrid(parent, id, pos, size) +{ + conn = _conn; + thread = NULL; + + SetTable(new sqlResultTable(), true); + + EnableEditing(false); + SetSizer(new wxBoxSizer(wxVERTICAL)); + + Connect(wxID_ANY, wxEVT_GRID_RANGE_SELECT, wxGridRangeSelectEventHandler(ctlSQLResult::OnGridSelect)); +} + + + +ctlSQLResult::~ctlSQLResult() +{ + Abort(); + + if (thread) + { + if (thread->IsRunning()) + { + thread->CancelExecution(); + thread->Wait(); + } + + delete thread; + thread = NULL; + } +} + + +void ctlSQLResult::SetConnection(pgConn *_conn) +{ + conn = _conn; +} + + +bool ctlSQLResult::Export() +{ + if (NumRows() > 0) + { + frmExport dlg(this); + if (dlg.ShowModal() == wxID_OK) + return dlg.Export(NULL); + } + return false; +} + +bool ctlSQLResult::ToFile() +{ + if (NumRows() > 0) + { + frmExport dlg(this); + if (dlg.ShowModal() == wxID_OK) + return dlg.Export(thread->DataSet()); + } + return false; +} + +bool ctlSQLResult::ToFile(frmExport *frm) +{ + if (NumRows() > 0) + { + return frm->Export(thread->DataSet()); + } + return false; +} + +bool ctlSQLResult::IsColText(int col) +{ + switch (colTypClasses.Item(col)) + { + case PGTYPCLASS_NUMERIC: + case PGTYPCLASS_BOOL: + return false; + } + + return true; +} + + +int ctlSQLResult::Execute(const wxString &query, int resultToRetrieve, wxWindow *caller, long eventId, void *data) +{ + wxGridTableMessage *msg; + sqlResultTable *table = (sqlResultTable *)GetTable(); + msg = new wxGridTableMessage(table, wxGRIDTABLE_NOTIFY_ROWS_DELETED, 0, GetNumberRows()); + ProcessTableMessage(*msg); + delete msg; + msg = new wxGridTableMessage(table, wxGRIDTABLE_NOTIFY_COLS_DELETED, 0, GetNumberCols()); + ProcessTableMessage(*msg); + delete msg; + + Abort(); + + colNames.Empty(); + colTypes.Empty(); + colTypClasses.Empty(); + + thread = new pgQueryThread(conn, query, resultToRetrieve, caller, eventId, data); + + if (thread->Create() != wxTHREAD_NO_ERROR) + { + Abort(); + return -1; + } + + ((sqlResultTable *)GetTable())->SetThread(thread); + sqlquerytext= wxString(query); + thread->Run(); + return RunStatus(); +} + + +int ctlSQLResult::Abort() +{ + if (thread) + { + ((sqlResultTable *)GetTable())->SetThread(0); + + if (thread->IsRunning()) + { + thread->CancelExecution(); + thread->Wait(); + } + + delete thread; + thread = NULL; + } + return 0; +} + + + +void ctlSQLResult::DisplayData(bool single) +{ + if (!thread || !thread->DataValid()) + return; + + if (thread->ReturnCode() != PGRES_TUPLES_OK) + return; + + rowcountSuppressed = single; + Freeze(); + + /* + * Resize and repopulate by informing it to delete all the rows and + * columns, then append the correct number of them. Probably is a + * better way to do this. + */ + wxGridTableMessage *msg; + sqlResultTable *table = (sqlResultTable *)GetTable(); + msg = new wxGridTableMessage(table, wxGRIDTABLE_NOTIFY_ROWS_DELETED, 0, GetNumberRows()); + ProcessTableMessage(*msg); + delete msg; + msg = new wxGridTableMessage(table, wxGRIDTABLE_NOTIFY_COLS_DELETED, 0, GetNumberCols()); + ProcessTableMessage(*msg); + delete msg; + msg = new wxGridTableMessage(table, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, NumRows()); + ProcessTableMessage(*msg); + delete msg; + msg = new wxGridTableMessage(table, wxGRIDTABLE_NOTIFY_COLS_APPENDED, thread->DataSet()->NumCols()); + ProcessTableMessage(*msg); + delete msg; + if (NumRows()<1000) { + wxGridCellAttr* pAttr = new wxGridCellAttr; + pAttr->SetBackgroundColour(wxColour(224,255,224)); + for(int row = 0; row < NumRows(); ++row) { + if (row%2==0) SetRowAttr(row,pAttr); + } + } + if (single) + { + colNames.Add(thread->DataSet()->ColName(0)); + colTypes.Add(wxT("")); + colTypClasses.Add(0L); + + AutoSizeColumn(0, false, false); + } + else + { + long col, nCols = thread->DataSet()->NumCols(); + + AutoSizeColumns(false); + + for (col = 0 ; col < nCols ; col++) + { + colNames.Add(thread->DataSet()->ColName(col)); + colTypes.Add(thread->DataSet()->ColFullType(col)); + colTypClasses.Add(thread->DataSet()->ColTypClass(col)); + + if (thread->DataSet()->ColTypClass(col) == PGTYPCLASS_NUMERIC) + { + /* + * For numeric columns, set alignment to right. + */ + wxGridCellAttr *attr = new wxGridCellAttr(); + attr->SetAlignment(wxALIGN_RIGHT, wxALIGN_TOP); + SetColAttr(col, attr); + } + } + } + Thaw(); +} + + + +wxString ctlSQLResult::GetMessagesAndClear() +{ + if (thread) + return thread->GetMessagesAndClear(); + return wxEmptyString; +} + + +wxString ctlSQLResult::GetErrorMessage() +{ + return conn->GetLastError(); +} + +pgError ctlSQLResult::GetResultError() +{ + if (thread) + return thread->GetResultError(); + + pgError dummy; + memset(&dummy, 0, sizeof(dummy)); + return dummy; +} + +long ctlSQLResult::NumRows() const +{ + if (thread && thread->DataValid()) + return thread->DataSet()->NumRows(); + return 0; +} + + +long ctlSQLResult::InsertedCount() const +{ + if (thread) + return thread->RowsInserted(); + return -1; +} + + +OID ctlSQLResult::InsertedOid() const +{ + if (thread) + return thread->InsertedOid(); + return (OID) - 1; +} + + +int ctlSQLResult::RunStatus() +{ + if (!thread) + return -1; + + if (thread->IsRunning()) + return CTLSQL_RUNNING; + + return thread->ReturnCode(); +} + + +wxString ctlSQLResult::OnGetItemText(long item, long col) const +{ + if (thread && thread->DataValid()) + { + if (!rowcountSuppressed) + { + if (col) + col--; + else + return NumToStr(item + 1L); + } + if (item >= 0) + { + thread->DataSet()->Locate(item + 1); + return thread->DataSet()->GetVal(col); + } + else + return thread->DataSet()->ColName(col); + } + return wxEmptyString; +} +wxString ctlSQLResult::SummaryColumn() +{ + //ce=cells.Item(0); + double sum=0; + size_t i; + if (GetSelectedRows().GetCount()) + { + //AppendColumnHeader(str, 0, (GetNumberCols() - 1)); + + wxArrayInt rows = GetSelectedRows(); + + for (i = 0 ; i < rows.GetCount() ; i++) + { + //str.Append(GetExportLine(rows.Item(i))); + //if (rows.GetCount() > 1) + // str.Append(END_OF_LINE); + } + + //copied = rows.GetCount(); + } + else if (GetSelectedCols().GetCount()) + { + wxArrayInt cols = GetSelectedCols(); + size_t numRows = GetNumberRows(); + + //AppendColumnHeader(str, cols); + for (i = 0 ; i < numRows ; i++) + { + //str.Append(GetExportLine(i, cols)); + for (size_t col = 0 ; col < cols.Count() ; col++) + { + wxString text = GetCellValue(i, cols[col]); + sum=sum+wxAtof(text); + } + + } + + //copied = numRows; + } + else if (GetSelectionBlockTopLeft().GetCount() > 0 && + GetSelectionBlockBottomRight().GetCount() > 0) + { + unsigned int x1, x2, y1, y2; + + x1 = GetSelectionBlockTopLeft()[0].GetCol(); + x2 = GetSelectionBlockBottomRight()[0].GetCol(); + y1 = GetSelectionBlockTopLeft()[0].GetRow(); + y2 = GetSelectionBlockBottomRight()[0].GetRow(); + + //AppendColumnHeader(str, x1, x2); + + for (i = y1; i <= y2; i++) + { +// str.Append(GetExportLine(i, x1, x2)); + wxString text = GetCellValue(i, x1); + sum=sum+wxAtof(text); + + //copied = y2 - y1 + 1; + } + } + else + { + int row, col; + + row = GetGridCursorRow(); + col = GetGridCursorCol(); + + //AppendColumnHeader(str, col, col); + +// str.Append(GetExportLine(row, col, col)); + //copied = 1; + } + + + wxString result; + result.Printf(wxT("%f"), sum); + return result; +} + +void ctlSQLResult::OnGridSelect(wxGridRangeSelectEvent &event) +{ + SetFocus(); +} + +wxString sqlResultTable::GetValue(int row, int col) +{ + if (thread && thread->DataValid()) + { + if (col >= 0) + { + thread->DataSet()->Locate(row + 1); + if (settings->GetIndicateNull() && thread->DataSet()->IsNull(col)) + return wxT(""); + else + { + + wxString decimalMark = wxT("."); + wxString s = thread->DataSet()->GetVal(col); + + if(thread->DataSet()->ColTypClass(col) == PGTYPCLASS_NUMERIC && + settings->GetDecimalMark().Length() > 0) + { + decimalMark = settings->GetDecimalMark(); + s.Replace(wxT("."), decimalMark); + + } + if (thread->DataSet()->ColTypClass(col) == PGTYPCLASS_NUMERIC && + settings->GetThousandsSeparator().Length() > 0) + { + /* Add thousands separator */ + size_t pos = s.find(decimalMark); + if (pos == wxString::npos) + pos = s.length(); + while (pos > 3) + { + pos -= 3; + if (pos > 1 || !s.StartsWith(wxT("-"))) + s.insert(pos, settings->GetThousandsSeparator()); + } + return s; + } + else + { + wxString data = thread->DataSet()->GetVal(col); + + if (data.Length() > (size_t)settings->GetMaxColSize()) + return thread->DataSet()->GetVal(col).Left(settings->GetMaxColSize()) + wxT(" (...)"); + else + return thread->DataSet()->GetVal(col); + } + } + } + else + return thread->DataSet()->ColName(col); + } + return wxEmptyString; +} + +sqlResultTable::sqlResultTable() +{ + thread = NULL; +} + +int sqlResultTable::GetNumberRows() +{ + if (thread && thread->DataValid()) + return thread->DataSet()->NumRows(); + return 0; +} + + +wxString sqlResultTable::GetColLabelValue(int col) +{ + if (thread && thread->DataValid()) + return thread->DataSet()->ColName(col) + wxT("\n") + + thread->DataSet()->ColFullType(col); + return wxEmptyString; +} + +int sqlResultTable::GetNumberCols() +{ + if (thread && thread->DataValid()) + return thread->DataSet()->NumCols(); + return 0; +} + diff --git a/ctl/ctlSeclabelPanel.cpp b/ctl/ctlSeclabelPanel.cpp new file mode 100644 index 0000000..04ed065 --- /dev/null +++ b/ctl/ctlSeclabelPanel.cpp @@ -0,0 +1,291 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlSeclabelPanel.cpp - Panel with security label information +// +////////////////////////////////////////////////////////////////////////// + + +// wxWindows headers +#include +#include +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/sysLogger.h" +#include "ctl/ctlSeclabelPanel.h" +#include "db/pgConn.h" +#include "schema/pgObject.h" +#include "utils/pgDefs.h" + + +BEGIN_EVENT_TABLE(ctlSeclabelPanel, wxPanel) + EVT_LIST_ITEM_SELECTED(CTL_LBSECLABEL, ctlSeclabelPanel::OnSeclabelSelChange) + EVT_BUTTON(CTL_ADDSECLABEL, ctlSeclabelPanel::OnAddSeclabel) + EVT_BUTTON(CTL_DELSECLABEL, ctlSeclabelPanel::OnDelSeclabel) + EVT_TEXT(CTL_PROVIDER, ctlSeclabelPanel::OnChange) + EVT_TEXT(CTL_SECLABEL, ctlSeclabelPanel::OnChange) +END_EVENT_TABLE(); + +DEFINE_LOCAL_EVENT_TYPE(EVT_SECLABELPANEL_CHANGE) + + +ctlSeclabelPanel::ctlSeclabelPanel(wxNotebook *nb) + : wxPanel(nb, -1, wxDefaultPosition, wxDefaultSize) +{ + wxStaticText *label; + + nbNotebook = nb; + nbNotebook->AddPage(this, _("Security Labels")); + + connection = NULL; + + // root sizer + wxFlexGridSizer *sizer0 = new wxFlexGridSizer(4, 1, 5, 5); + sizer0->AddGrowableCol(0); + sizer0->AddGrowableRow(0); + + // grid sizer + wxFlexGridSizer *sizer1 = new wxFlexGridSizer(1, 1, 5, 5); + sizer1->AddGrowableCol(0); + sizer1->AddGrowableRow(0); + lbSeclabels = new ctlListView(this, CTL_LBSECLABEL, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER | wxLC_REPORT); + lbSeclabels->AddColumn(_("Provider"), 70, wxLIST_FORMAT_LEFT); + lbSeclabels->AddColumn(_("Security label"), 70, wxLIST_FORMAT_LEFT); + sizer1->Add(lbSeclabels, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + sizer0->Add(sizer1, 0, wxEXPAND | wxALL, 5); + + // buttons sizer + wxBoxSizer *sizer2 = new wxBoxSizer(wxHORIZONTAL); + btnAddSeclabel = new wxButton(this, CTL_ADDSECLABEL, _("Add/Change")); + sizer2->Add(btnAddSeclabel, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + btnDelSeclabel = new wxButton(this, CTL_DELSECLABEL, _("Remove")); + sizer2->Add(btnDelSeclabel, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + sizer0->Add(sizer2, 0, wxEXPAND | wxALL, 0); + + + // textboxes sizer + wxFlexGridSizer *sizer3 = new wxFlexGridSizer(2, 2, 5, 5); + sizer3->AddGrowableCol(1); + label = new wxStaticText(this, 0, _("Provider")); + sizer3->Add(label, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + txtProvider = new wxTextCtrl(this, CTL_PROVIDER); + sizer3->Add(txtProvider, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + label = new wxStaticText(this, 0, _("Security label")); + sizer3->Add(label, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + txtSeclabel = new wxTextCtrl(this, CTL_SECLABEL); + sizer3->Add(txtSeclabel, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + sizer0->Add(sizer3, 0, wxEXPAND | wxALL, 5); + + // compute sizes + this->SetSizer(sizer0); + sizer0->Fit(this); + + btnAddSeclabel->Enable(false); +} + + +ctlSeclabelPanel::~ctlSeclabelPanel() +{ +} + + +void ctlSeclabelPanel::Disable() +{ + lbSeclabels->Disable(); + btnAddSeclabel->Disable(); + btnDelSeclabel->Disable(); + txtProvider->Disable(); + txtSeclabel->Disable(); +} + + +void ctlSeclabelPanel::SetConnection(pgConn *conn) +{ + connection = conn; +} + + +void ctlSeclabelPanel::SetObject(pgObject *obj) +{ + object = obj; + + if (object && !object->GetLabels().IsEmpty()) + { + wxArrayString seclabels = object->GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + lbSeclabels->AppendItem(seclabels.Item(index), + seclabels.Item(index + 1)); + } + } + } +} + + +void ctlSeclabelPanel::OnDelSeclabel(wxCommandEvent &ev) +{ + if (lbSeclabels->GetFirstSelected() == -1) + return; + + lbSeclabels->DeleteCurrentItem(); + + wxCommandEvent event( EVT_SECLABELPANEL_CHANGE, GetId() ); + event.SetEventObject( this ); + GetEventHandler()->ProcessEvent( event ); + + ev.Skip(); +} + + +void ctlSeclabelPanel::OnAddSeclabel(wxCommandEvent &ev) +{ + bool found = false; + + for (int indexList = 0; indexList < lbSeclabels->GetItemCount(); indexList++) + { + if (lbSeclabels->GetText(indexList) == txtProvider->GetValue()) + { + found = true; + lbSeclabels->SetItem(indexList, 1, txtSeclabel->GetValue()); + break; + } + } + + if (!found) + { + int pos = lbSeclabels->GetItemCount(); + lbSeclabels->InsertItem(pos, txtProvider->GetValue()); + lbSeclabels->SetItem(pos, 1, txtSeclabel->GetValue()); + } + + wxCommandEvent event( EVT_SECLABELPANEL_CHANGE, GetId() ); + event.SetEventObject( this ); + GetEventHandler()->ProcessEvent( event ); + + ev.Skip(); +} + +void ctlSeclabelPanel::OnChange(wxCommandEvent &event) +{ + wxString provider = txtProvider->GetValue().Trim(true).Trim(false); + wxString label = txtSeclabel->GetValue().Trim(true).Trim(false); + btnAddSeclabel->Enable(!provider.IsEmpty() && !label.IsEmpty()); +} + +void ctlSeclabelPanel::OnSeclabelSelChange(wxListEvent &ev) +{ + if (lbSeclabels->GetFirstSelected() == -1) + return; + + txtProvider->SetValue(lbSeclabels->GetText(lbSeclabels->GetSelection())); + txtSeclabel->SetValue(lbSeclabels->GetText(lbSeclabels->GetSelection(), 1)); +} + +void ctlSeclabelPanel::GetCurrentProviderLabelArray(wxArrayString &secLabels) +{ + for(int indexList = 0; indexList < lbSeclabels->GetItemCount(); indexList++) + { + secLabels.Add(lbSeclabels->GetText(indexList)); + secLabels.Add(lbSeclabels->GetText(indexList, 1)); + } +} + +wxString ctlSeclabelPanel::GetSqlForSecLabels(wxString objecttype, wxString objectname) +{ + wxASSERT(connection != NULL); + + wxString sql; + wxArrayString seclabels; + int indexList; + unsigned int indexArray; + wxString oldprovider, newprovider, oldlabel, newlabel; + bool found; + + if (object) + { + seclabels = object->GetProviderLabelArray(); + + // find new or changed seclabels + for (indexList = 0; indexList < lbSeclabels->GetItemCount(); indexList++) + { + found = false; + newprovider = lbSeclabels->GetText(indexList); + newlabel = lbSeclabels->GetText(indexList, 1); + + // try to find the provider in the current providers list + if (object && seclabels.GetCount() > 0) + { + for (indexArray = 0 ; indexArray < seclabels.GetCount() - 1 ; indexArray += 2) + { + oldprovider = seclabels.Item(indexArray); + oldlabel = seclabels.Item(indexArray + 1); + + if (oldprovider == newprovider) + { + found = true; + // provider is available on the old and new list + // we should check is the label has changed + if (oldlabel != newlabel) + sql += wxT("SECURITY LABEL FOR ") + newprovider + + wxT("\n ON ") + objecttype + wxT(" ") + objectname + + wxT("\n IS ") + object->qtDbString(newlabel) + wxT(";\n"); + } + } + } + + if (!found) + sql += wxT("SECURITY LABEL FOR ") + newprovider + + wxT("\n ON ") + objecttype + wxT(" ") + objectname + + wxT("\n IS ") + object->qtDbString(newlabel) + wxT(";\n"); + } + + // find old seclabels + if (seclabels.GetCount() > 0) + { + for (indexArray = 0 ; indexArray < seclabels.GetCount() - 1 ; indexArray += 2) + { + found = false; + oldprovider = seclabels.Item(indexArray); + + for (indexList = 0; indexList < lbSeclabels->GetItemCount(); indexList++) + { + newprovider = lbSeclabels->GetText(indexList); + + if (oldprovider == newprovider) + { + found = true; + } + } + + if (!found) + sql += wxT("SECURITY LABEL FOR ") + oldprovider + + wxT("\n ON ") + objecttype + wxT(" ") + objectname + + wxT("\n IS NULL;\n"); + } + } + } + else + { + // find new or changed seclabels + for (indexList = 0; indexList < lbSeclabels->GetItemCount(); indexList++) + { + newprovider = lbSeclabels->GetText(indexList); + newlabel = lbSeclabels->GetText(indexList, 1); + + sql += wxT("SECURITY LABEL FOR ") + newprovider + + wxT("\n ON ") + objecttype + wxT(" ") + objectname + + wxT("\n IS ") + connection->qtDbString(newlabel) + wxT(";\n"); + } + } + + return sql; +} diff --git a/ctl/ctlSecurityPanel.cpp b/ctl/ctlSecurityPanel.cpp new file mode 100644 index 0000000..7b3bffe --- /dev/null +++ b/ctl/ctlSecurityPanel.cpp @@ -0,0 +1,445 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlSecurityPanel.cpp - Panel with security information +// +////////////////////////////////////////////////////////////////////////// + + +// wxWindows headers +#include +#include +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/sysLogger.h" +#include "ctl/ctlSecurityPanel.h" +#include "db/pgConn.h" +#include "schema/pgObject.h" +#include "schema/pgGroup.h" +#include "schema/pgUser.h" + + + +BEGIN_EVENT_TABLE(ctlSecurityPanel, wxPanel) + EVT_LIST_ITEM_SELECTED(CTL_LBPRIV, ctlSecurityPanel::OnPrivSelChange) + EVT_BUTTON(CTL_ADDPRIV, ctlSecurityPanel::OnAddPriv) + EVT_BUTTON(CTL_DELPRIV, ctlSecurityPanel::OnDelPriv) + EVT_TEXT(CTL_CBGROUP, ctlSecurityPanel::OnGroupChange) + EVT_COMBOBOX(CTL_CBGROUP, ctlSecurityPanel::OnGroupChange) + EVT_CHECKBOX(CTL_ALLPRIV, ctlSecurityPanel::OnPrivCheckAll) + EVT_CHECKBOX(CTL_ALLPRIVGRANT, ctlSecurityPanel::OnPrivCheckAllGrant) + EVT_CHECKBOX(CTL_PRIVCB, ctlSecurityPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_PRIVCB + 2, ctlSecurityPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_PRIVCB + 4, ctlSecurityPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_PRIVCB + 6, ctlSecurityPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_PRIVCB + 8, ctlSecurityPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_PRIVCB + 10, ctlSecurityPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_PRIVCB + 12, ctlSecurityPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_PRIVCB + 14, ctlSecurityPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_PRIVCB + 16, ctlSecurityPanel::OnPrivCheck) +END_EVENT_TABLE(); + +DEFINE_LOCAL_EVENT_TYPE(EVT_SECURITYPANEL_CHANGE) + +ctlSecurityPanel::ctlSecurityPanel(wxNotebook *nb, const wxString &privList, const char *privChars, wxImageList *imgList) + : wxPanel(nb, -1, wxDefaultPosition, wxDefaultSize) +{ + nbNotebook = nb; + nbNotebook->AddPage(this, _("Privileges")); + + connection = 0; + privilegeChars = privChars; + allPrivileges = 0; + + privCheckboxes = 0; + + wxStringTokenizer privileges(privList, wxT(",")); + privilegeCount = privileges.CountTokens(); + + wxFlexGridSizer *item0 = new wxFlexGridSizer(3, 1, 5, 5); + item0->AddGrowableCol(0); + item0->AddGrowableRow(0); + + if (privilegeCount) + { + bool needAll = (privilegeCount > 1); + privCheckboxes = new wxCheckBox*[privilegeCount * 2]; + int i = 0; + + wxFlexGridSizer *itemSizer1 = new wxFlexGridSizer(1, 1, 5, 5); + itemSizer1->AddGrowableCol(0); + itemSizer1->AddGrowableRow(0); + lbPrivileges = new ctlListView(this, CTL_LBPRIV, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER | wxLC_REPORT); + lbPrivileges->SetImageList(imgList, wxIMAGE_LIST_SMALL); + lbPrivileges->AddColumn(_("User/Group"), 70, wxLIST_FORMAT_LEFT); + lbPrivileges->AddColumn(_("Privileges"), 70, wxLIST_FORMAT_LEFT); + itemSizer1->Add(lbPrivileges, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + item0->Add(itemSizer1, 0, wxEXPAND | wxALL, 5); + + wxBoxSizer *itemSizer2 = new wxBoxSizer(wxHORIZONTAL); + btnAddPriv = new wxButton(this, CTL_ADDPRIV, _("Add/Change")); + itemSizer2->Add(btnAddPriv, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + btnDelPriv = new wxButton(this, CTL_DELPRIV, _("Remove")); + itemSizer2->Add(btnDelPriv, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + item0->Add(itemSizer2, 0, wxEXPAND | wxALL, 0); + + wxStaticBox *sb = new wxStaticBox(this, -1, _("Privileges")); + wxBoxSizer *itemSizer3 = new wxStaticBoxSizer( sb, wxVERTICAL ); + item0->Add(itemSizer3, 0, wxEXPAND | wxALL, 5); + + wxBoxSizer *itemSizer4 = new wxBoxSizer(wxHORIZONTAL); + stGroup = new wxStaticText(this, CTL_STATICGROUP, _("Group")); +#ifdef __WXMSW__ + stGroup->SetMinSize(wxSize(30, 15)); +#endif // __WXMSW__ + itemSizer4->Add(stGroup, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + cbGroups = new ctlComboBox(this, CTL_CBGROUP, wxDefaultPosition, wxDefaultSize); + cbGroups->Append(wxT("public")); + cbGroups->SetSelection(0); + itemSizer4->Add(cbGroups, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT); + itemSizer3->Add(itemSizer4, 0, wxEXPAND | wxALL, 0); + + /* border size depends on the plateform */ +#ifdef __WXMSW__ + int bordersize = 4; +#endif +#ifdef __WXMAC__ + int bordersize = 3; +#endif +#ifdef __WXGTK__ + int bordersize = 0; +#endif + + if (needAll) + { + wxBoxSizer *itemSizer5 = new wxBoxSizer(wxHORIZONTAL); + allPrivileges = new wxCheckBox(this, CTL_ALLPRIV, wxT("ALL")); + itemSizer5->Add(allPrivileges, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT); + allPrivilegesGrant = new wxCheckBox(this, CTL_ALLPRIVGRANT, wxT("WITH GRANT OPTION")); + itemSizer5->Add(allPrivilegesGrant, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT); + allPrivilegesGrant->Disable(); + itemSizer3->Add(itemSizer5, 0, wxALL, bordersize); + } + + while (privileges.HasMoreTokens()) + { + wxString priv = privileges.GetNextToken(); + wxCheckBox *cb; + wxBoxSizer *itemSizer6 = new wxBoxSizer(wxHORIZONTAL); + cb = new wxCheckBox(this, CTL_PRIVCB + i, priv); + itemSizer6->Add(cb, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT); + privCheckboxes[i++] = cb; + cb = new wxCheckBox(this, CTL_PRIVCB + i, wxT("WITH GRANT OPTION")); + itemSizer6->Add(cb, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT); + cb->Disable(); + privCheckboxes[i++] = cb; + itemSizer3->Add(itemSizer6, 0, wxALL, bordersize); + } + } + + this->SetSizer(item0); + item0->Fit(this); +} + + +ctlSecurityPanel::~ctlSecurityPanel() +{ + if (privCheckboxes) + delete[] privCheckboxes; +} + + +void ctlSecurityPanel::SetConnection(pgConn *conn) +{ + connection = conn; + if (connection && stGroup && connection->BackendMinimumVersion(8, 1)) + stGroup->SetLabel(_("Role")); +} + +wxString ctlSecurityPanel::GetUserPrivileges() +{ + wxString strPrivilages = wxEmptyString; + int cnt = lbPrivileges->GetItemCount(); + int pos; + if(cnt > 0) + { + strPrivilages += wxT("{"); + for (pos = 0 ; pos < cnt ; pos++) + { + if (pos != 0) + strPrivilages += wxT(","); + + strPrivilages += + lbPrivileges->GetText(pos) + wxT("=") + lbPrivileges->GetText(pos, 1) + wxT("/") + connection->GetUser(); + } + strPrivilages += wxT("}"); + } + return strPrivilages; +} + +wxString ctlSecurityPanel::GetGrant(const wxString &allPattern, const wxString &grantObject, wxArrayString *currentAcl, wxString column) +{ + wxArrayString tmpAcl; + if (currentAcl) + tmpAcl = *currentAcl; + + wxString sql; + int cnt = lbPrivileges->GetItemCount(); + int pos; + unsigned int i; + + for (pos = 0 ; pos < cnt ; pos++) + { + wxString name = lbPrivileges->GetText(pos); + wxString value = lbPrivileges->GetText(pos, 1); + + int nameLen = name.Length(); + + bool privWasAssigned = false; + bool privPartiallyAssigned = false; + for (i = 0 ; i < tmpAcl.GetCount() ; i++) + { + if (tmpAcl.Item(i).Left(nameLen + 1) == name + wxT("=")) + { + privPartiallyAssigned = true; + if (tmpAcl.Item(i).Mid(nameLen + 1) == value) + privWasAssigned = true; + tmpAcl.RemoveAt(i); + break; + } + } + + if (name.Left(6).IsSameAs(wxT("group "), false)) + name = wxT("GROUP ") + qtIdent(name.Mid(6)); + else + name = qtIdent(name); + + if (!privWasAssigned) + { + if (privPartiallyAssigned) + sql += pgObject::GetPrivileges(allPattern, wxT(""), grantObject, name, column); + sql += pgObject::GetPrivileges(allPattern, value, grantObject, name, column); + } + } + + for (i = 0 ; i < tmpAcl.GetCount() ; i++) + { + wxString name = tmpAcl.Item(i).BeforeLast('='); + + if (name.Left(6).IsSameAs(wxT("group "), false)) + name = wxT("GROUP ") + qtIdent(name.Mid(6)); + else + name = qtIdent(name); + sql += pgObject::GetPrivileges(allPattern, wxT(""), grantObject, name, column); + } + return sql; +} + + +void ctlSecurityPanel::OnGroupChange(wxCommandEvent &ev) +{ + cbGroups->GuessSelection(ev); + wxString name = cbGroups->GetGuessedStringSelection(); + + btnAddPriv->Enable(!name.Strip(wxString::both).IsEmpty()); +} + + +void ctlSecurityPanel::OnPrivCheckAll(wxCommandEvent &ev) +{ + bool all = allPrivileges->GetValue(); + int i; + for (i = 0 ; i < privilegeCount ; i++) + { + if (all) + { + // We use the Name property of the checkboxes as a flag to note if that + // box should remain disabled (eg. CONNECT for a DB on PG < 8.2 + if (privCheckboxes[i * 2]->GetName() != wxT("DISABLE")) + { + privCheckboxes[i * 2]->SetValue(true); + privCheckboxes[i * 2]->Disable(); + privCheckboxes[i * 2 + 1]->Disable(); + allPrivilegesGrant->Enable(GrantAllowed()); + } + } + else + { + if (privCheckboxes[i * 2]->GetName() != wxT("DISABLE")) + { + allPrivilegesGrant->Disable(); + allPrivilegesGrant->SetValue(false); + privCheckboxes[i * 2]->Enable(); + CheckGrantOpt(i); + } + } + } +} + + + +void ctlSecurityPanel::OnPrivCheckAllGrant(wxCommandEvent &ev) +{ + bool grant = allPrivilegesGrant->GetValue(); + int i; + for (i = 0 ; i < privilegeCount ; i++) + privCheckboxes[i * 2 + 1]->SetValue(grant); +} + + +void ctlSecurityPanel::OnPrivCheck(wxCommandEvent &ev) +{ + int id = (ev.GetId() - CTL_PRIVCB) / 2; + CheckGrantOpt(id); +} + + +void ctlSecurityPanel::CheckGrantOpt(int id) +{ + bool canGrant = (GrantAllowed() && privCheckboxes[id * 2]->GetValue()); + if (canGrant) + privCheckboxes[id * 2 + 1]->Enable(); + else + { + privCheckboxes[id * 2 + 1]->SetValue(false); + privCheckboxes[id * 2 + 1]->Disable(); + } +} + + +void ctlSecurityPanel::OnDelPriv(wxCommandEvent &ev) +{ + if (lbPrivileges->GetFirstSelected() == -1) + return; + + lbPrivileges->DeleteCurrentItem(); + + wxCommandEvent event( EVT_SECURITYPANEL_CHANGE, GetId() ); + event.SetEventObject( this ); + GetEventHandler()->ProcessEvent( event ); + + ev.Skip(); +} + + +void ctlSecurityPanel::OnAddPriv(wxCommandEvent &ev) +{ + wxString name = cbGroups->GetGuessedStringSelection(); + + long pos = lbPrivileges->FindItem(-1, name); + if (pos < 0) + { + pos = lbPrivileges->GetItemCount(); + int icon = userFactory.GetIconId(); + + if (name.Left(6).IsSameAs(wxT("group "), false)) + icon = groupFactory.GetIconId(); + else if (name.IsSameAs(wxT("public"), false)) + icon = PGICON_PUBLIC; + + lbPrivileges->InsertItem(pos, name, icon); + } + wxString value; + int i; + for (i = 0 ; i < privilegeCount ; i++) + { + if (privCheckboxes[i * 2]->GetValue()) + { + value += privilegeChars[i]; + if (privCheckboxes[i * 2 + 1]->GetValue()) + value += '*'; + } + } + lbPrivileges->SetItem(pos, 1, value); + + wxCommandEvent event( EVT_SECURITYPANEL_CHANGE, GetId() ); + event.SetEventObject( this ); + GetEventHandler()->ProcessEvent( event ); + + ev.Skip(); +} + + +void ctlSecurityPanel::OnPrivSelChange(wxListEvent &ev) +{ + if (!cbGroups) + return; + if (allPrivileges) + { + allPrivileges->SetValue(false); + allPrivilegesGrant->SetValue(false); + allPrivilegesGrant->Disable(); + } + long pos = lbPrivileges->GetSelection(); + if (pos >= 0) + { + wxString name = lbPrivileges->GetText(pos); + wxString value = lbPrivileges->GetText(pos, 1); + + pos = cbGroups->FindString(name); + if (pos < 0) + { + cbGroups->Append(name); + pos = cbGroups->GetCount() - 1; + } + cbGroups->SetSelection(pos); + + int i; + for (i = 0 ; i < privilegeCount ; i++) + { + if (privCheckboxes[i * 2]->GetName() != wxT("DISABLE")) + { + privCheckboxes[i * 2]->Enable(); + int index = value.Find(privilegeChars[i]); + if (index >= 0) + { + privCheckboxes[i * 2]->SetValue(true); + privCheckboxes[i * 2 + 1]->SetValue(value.Mid(index + 1, 1) == wxT("*")); + } + else + privCheckboxes[i * 2]->SetValue(false); + } + CheckGrantOpt(i); + } + } + btnAddPriv->Enable(); +} + + + +bool ctlSecurityPanel::GrantAllowed() const +{ + if (!connection->BackendMinimumVersion(7, 4)) + return false; + + wxString user = cbGroups->GetValue(); + if (user.IsSameAs(wxT("public"), false)) + return false; + + if (!connection->BackendMinimumVersion(8, 1) && + user.Left(6).IsSameAs(wxT("group "), false)) + return false; + + return true; +} + +bool ctlSecurityPanel::DisablePrivilege(const wxString &priv) +{ + for (int i = 0; i < privilegeCount; i++) + { + if (privCheckboxes[i * 2]->GetLabel() == priv) + { + // Use the Name property as a flag so we don't accidently reenable the control later + privCheckboxes[i * 2]->SetName(wxT("DISABLE")); + privCheckboxes[i * 2]->Disable(); + return true; + } + } + return false; +} diff --git a/ctl/ctlTree.cpp b/ctl/ctlTree.cpp new file mode 100644 index 0000000..6a33309 --- /dev/null +++ b/ctl/ctlTree.cpp @@ -0,0 +1,398 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlTree.cpp - wxTreeCtrl containing pgObjects +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "ctl/ctlTree.h" + +#include "schema/pgObject.h" +#include "schema/pgCollection.h" +#include "schema/pgServer.h" + +BEGIN_EVENT_TABLE(ctlTree, wxTreeCtrl) + EVT_CHAR(ctlTree::OnChar) +END_EVENT_TABLE() + + +wxTreeItemId ctlTree::FindItem(const wxTreeItemId &idParent, const wxString &prefixOrig) +{ + // match is case insensitive as this is more convenient to the user: having + // to press Shift-letter to go to the item starting with a capital letter + // would be too bothersome + wxString prefix = prefixOrig.Lower(); + + // determine the starting point: we shouldn't take the current item (this + // allows to switch between two items starting with the same letter just by + // pressing it) but we shouldn't jump to the next one if the user is + // continuing to type as otherwise he might easily skip the item he wanted + wxTreeItemId id = idParent; + + if ( prefix.length() == 1 ) + { + wxCookieType cookie; + if (HasChildren(id)) + id = GetFirstChild(id, cookie); + else + { + // Try a sibling of this or ancestor instead + wxTreeItemId p = id; + wxTreeItemId toFind; + do + { + toFind = GetNextSibling(p); + p = GetItemParent(p); + } + while (p.IsOk() && !toFind.IsOk()); + id = toFind; + } + } + + // look for the item starting with the given prefix after it + while ( id.IsOk() && + ( ( GetItemText(id) == wxT("Dummy") && !GetItemData(id) ) || + !GetItemText(id).Lower().StartsWith(prefix) )) + { + wxCookieType cookie; + if ( HasChildren(id) ) + id = GetFirstChild(id, cookie); + else + { + // Try a sibling of this or ancestor instead + wxTreeItemId p = id; + wxTreeItemId toFind; + do + { + toFind = GetNextSibling(p); + p = GetItemParent(p); + } + while (p.IsOk() && !toFind.IsOk()); + id = toFind; + } + } + + // if we haven't found anything... + if ( !id.IsOk() ) + { + // ... wrap to the beginning + id = GetRootItem(); + if ( HasFlag(wxTR_HIDE_ROOT) ) + { + wxCookieType cookie; + // can't select virtual root + if ( HasChildren(id) ) + id = GetFirstChild(id, cookie); + else + { + // Try a sibling of this or ancestor instead + wxTreeItemId p = id; + wxTreeItemId toFind; + do + { + toFind = GetNextSibling(p); + p = GetItemParent(p); + } + while (p.IsOk() && !toFind.IsOk()); + id = toFind; + } + } + + // and try all the items (stop when we get to the one we started from) + while ( id.IsOk() && id != idParent && + (( GetItemText(id) == wxT("Dummy") && !GetItemData(id) ) || + !GetItemText(id).Lower().StartsWith(prefix) )) + { + wxCookieType cookie; + if ( HasChildren(id) ) + id = GetFirstChild(id, cookie); + else + { + // Try a sibling of this or ancestor instead + wxTreeItemId p = id; + wxTreeItemId toFind; + do + { + toFind = GetNextSibling(p); + p = GetItemParent(p); + } + while (p.IsOk() && !toFind.IsOk()); + id = toFind; + } + } + // If we haven't found the item, id.IsOk() will be false, as per + // documentation + } + + return id; +} + +void ctlTree::OnChar(wxKeyEvent &event) +{ + int keyCode = event.GetKeyCode(); + if ( !event.HasModifiers() && + ((keyCode >= '0' && keyCode <= '9') || + (keyCode >= 'a' && keyCode <= 'z') || + (keyCode >= 'A' && keyCode <= 'Z'))) + { + wxTreeItemId currItem = GetSelection(); + + if (!currItem.IsOk()) + return; + + wxTreeItemId matchItem = FindItem(currItem, m_findPrefix + (wxChar)keyCode); + + if ( matchItem.IsOk() ) + { + EnsureVisible(matchItem); + SelectItem(matchItem); + + m_findPrefix += (wxChar)keyCode; + + // also start the timer to reset the current prefix if the user + // doesn't press any more alnum keys soon -- we wouldn't want + // to use this prefix for a new item search + if ( !m_findTimer ) + { + m_findTimer = new ctlTreeFindTimer(this); + } + + m_findTimer->Start(ctlTreeFindTimer::CTLTREE_DELAY, wxTIMER_ONE_SHOT); + return; + } + } + else + { + event.Skip(true); + } +} + +ctlTree::ctlTree(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style) + : wxTreeCtrl(parent, id, pos, size, style), m_findTimer(NULL) +{ +} + +ctlTree::~ctlTree() +{ + if ( m_findTimer ) + delete m_findTimer; + m_findTimer = NULL; +} + + +void ctlTree::RemoveDummyChild(pgObject *obj) +{ + wxCookieType cookie; + wxTreeItemId childItem = GetFirstChild(obj->GetId(), cookie); + if (childItem && !GetItemData(childItem)) + { + // The child was a dummy item, which will be replaced by the following ShowTreeDetail by true items + Delete(childItem); + } +} + + +pgObject *ctlTree::GetObject(wxTreeItemId id) +{ + if (id) + return (pgObject *)GetItemData(id); + return 0; +} + + +pgCollection *ctlTree::GetParentCollection(wxTreeItemId id) +{ + pgCollection *coll = (pgCollection *)GetParentObject(id); + if (coll && coll->IsCollection()) + return coll; + return 0; +} + + +void ctlTree::SetItemImage(const wxTreeItemId &item, int image, wxTreeItemIcon which) +{ + wxTreeCtrl::SetItemImage(item, image, which); + + wxTreeItemData *data = GetItemData(item); + + // Set the item colour + if (data) + { + if (((pgObject *)data)->GetMetaType() == PGM_SERVER) + { + if (!((pgServer *)data)->GetColour().IsEmpty()) + SetItemBackgroundColour(item, wxColour(((pgServer *)data)->GetColour())); + } + else if (((pgObject *)data)->GetServer()) + { + if (!((pgObject *)data)->GetServer()->GetColour().IsEmpty()) + SetItemBackgroundColour(item, wxColour(((pgObject *)data)->GetServer()->GetColour())); + } + } +} + +wxTreeItemId ctlTree::AppendItem(const wxTreeItemId &parent, const wxString &text, int image, int selImage, wxTreeItemData *data) +{ + wxTreeItemId itm = wxTreeCtrl::AppendItem(parent, text, image, selImage, data); + + // Set the item colour + if (data) + { + if (((pgObject *)data)->GetMetaType() == PGM_SERVER) + { + if (!((pgServer *)data)->GetColour().IsEmpty()) + SetItemBackgroundColour(itm, wxColour(((pgServer *)data)->GetColour())); + } + else if (((pgObject *)data)->GetServer()) + { + if (!((pgObject *)data)->GetServer()->GetColour().IsEmpty()) + SetItemBackgroundColour(itm, wxColour(((pgObject *)data)->GetServer()->GetColour())); + } + } + + return itm; +} + +wxTreeItemId ctlTree::AppendObject(pgObject *parent, pgObject *object) +{ + wxString label; + wxTreeItemId item; + + if (object->IsCollection()) + label = object->GetTypeName(); + else + label = object->GetDisplayName(); + item = AppendItem(parent->GetId(), label, object->GetIconId(), -1, object); + if (object->IsCollection()) + object->ShowTreeDetail(this); + else if (object->WantDummyChild()) + AppendItem(object->GetId(), wxT("Dummy")); + + return item; +} + + +pgCollection *ctlTree::AppendCollection(pgObject *parent, pgaFactory &factory) +{ + pgCollection *collection = factory.CreateCollection(parent); + AppendObject(parent, collection); + return collection; +} + + +pgObject *ctlTree::FindObject(pgaFactory &factory, wxTreeItemId parent) +{ + wxCookieType cookie; + wxTreeItemId item = GetFirstChild(parent, cookie); + while (item) + { + pgObject *obj = (pgObject *)GetItemData(item); + if (obj && obj->IsCreatedBy(factory)) + return obj; + item = GetNextChild(parent, cookie); + } + return 0; +} + + +pgCollection *ctlTree::FindCollection(pgaFactory &factory, wxTreeItemId parent) +{ + pgaFactory *cf = factory.GetCollectionFactory(); + if (!cf) + return 0; + + pgCollection *collection = (pgCollection *)FindObject(*cf, parent); + + if (!collection || !collection->IsCollection()) + return 0; + return collection; +} + + +void ctlTree::NavigateTree(int keyCode) +{ + switch(keyCode) + { + case WXK_LEFT: + { + //If tree item has children and is expanded, collapse it, otherwise select it's parent if has one + wxTreeItemId currItem = GetSelection(); + + if (ItemHasChildren(currItem) && IsExpanded(currItem)) + { + Collapse(currItem); + } + else + { + wxTreeItemId parent = GetItemParent(currItem); + if (parent.IsOk()) + { + SelectItem(currItem, false); + SelectItem(parent, true); + } + } + } + break; + case WXK_RIGHT: + { + //If tree item do not have any children ignore it, + //otherwise expand it if not expanded, and select first child if already expanded + wxTreeItemId currItem = GetSelection(); + + if(ItemHasChildren(currItem)) + { + if (!IsExpanded(currItem)) + { + Expand(currItem); + } + else + { + wxCookieType cookie; + wxTreeItemId firstChild = GetFirstChild(currItem, cookie); + SelectItem(currItem, false); + SelectItem(firstChild, true); + } + } + } + break; + default: + wxASSERT_MSG(false, _("Currently handles only right and left arrow key, other keys are working")); + break; + } +} + +////////////////////// + +treeObjectIterator::treeObjectIterator(ctlTree *brow, pgObject *obj) +{ + browser = brow; + object = obj; +} + + +pgObject *treeObjectIterator::GetNextObject() +{ + if (!object || !browser) + return 0; + + if (!lastItem) + lastItem = browser->GetFirstChild(object->GetId(), cookie); + else + lastItem = browser->GetNextChild(object->GetId(), cookie); + + if (lastItem) + return browser->GetObject(lastItem); + else + object = 0; + + return 0; +} diff --git a/ctl/explainCanvas.cpp b/ctl/explainCanvas.cpp new file mode 100644 index 0000000..18a7722 --- /dev/null +++ b/ctl/explainCanvas.cpp @@ -0,0 +1,651 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// explainCanvas.cpp - Explain Canvas +// +////////////////////////////////////////////////////////////////////////// + + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" + +#include "ctl/explainCanvas.h" + + +BEGIN_EVENT_TABLE(ExplainCanvas, wxShapeCanvas) + EVT_MOTION(ExplainCanvas::OnMouseMotion) +END_EVENT_TABLE() + + +ExplainCanvas::ExplainCanvas(wxWindow *parent) + : wxShapeCanvas(parent), rootShape(NULL) +{ + SetDiagram(new wxDiagram); + GetDiagram()->SetCanvas(this); + SetBackgroundColour(*wxWHITE); + popup = NULL; +} + + +ExplainCanvas::~ExplainCanvas() +{ +} + + +void ExplainCanvas::Clear() +{ + GetDiagram()->DeleteAllShapes(); + rootShape = NULL; +} + + +void ExplainCanvas::SetExplainString(const wxString &str) +{ + // filtred block never executed + wxString rez=wxT(""); + wxString flt=wxT(""); + wxStringTokenizer tmpstr(str, wxT("\n")); + int p=-1; + while (tmpstr.HasMoreTokens()) + { + wxString tmp = tmpstr.GetNextToken(); + if (p>-1) + { + // never executed + const wxChar *cp = tmp.c_str(); + int pp=0; + while (pp<=p) + { + if (*cp != ' ') + { + break; + } + cp++; + pp++; + } + if (pp<=p) p=-1; + } + if (p==-1) + { + p=tmp.Find(wxT("->")); + if (p>-1) { + int p2=tmp.Find(wxT("(never executed)")); + if (p2==-1) { + p=-1; + } else + { + continue; + + } + } + flt=flt+tmp+wxT("\n"); + + } + } + + Clear(); + + // We can have multiple plans in a single explain string + // Add a empty root shape, which will never get drawn, but it will help us + // to keep track of all these plans + rootShape = ExplainShape::Create(0, NULL, wxEmptyString); + AddShape(rootShape); + + ExplainShape *last = rootShape; + int maxLevel = 0; + + wxStringTokenizer lines(flt, wxT("\n")); + + while (lines.HasMoreTokens()) + { + wxString tmp = lines.GetNextToken(); + wxString line = tmp.Strip(wxString::both); + int braceCount = 0; + do + { + const wxChar *cp = line.c_str(); + while (*cp) + { + if (*cp == '(') + braceCount++; + else if (*cp == ')') + braceCount--; + cp++; + } + if (braceCount > 0) + { + wxString tmp = lines.GetNextToken(); + line += wxT(" ") + tmp.Strip(wxString::both); + braceCount = 0; + } + else + break; + } + while (lines.HasMoreTokens()); + + long level = ((tmp.Length() - line.Length() + 4) / 6) + 1; + + if (last) + { + if (level != 1) + { + if (line.Left(4) == wxT("-> ")) + line = line.Mid(4); + else + { + last->SetCondition(line); + continue; + } + } + + while (last != rootShape && level <= last->GetLevel()) + last = last->GetUpper(); + } + + + ExplainShape *s = ExplainShape::Create(level, last, line); + if (!s) + continue; + s->SetCanvas(this); + InsertShape(s); + s->Show(true); + + if (level > maxLevel) + maxLevel = level; + + last = s; + } + + + int x0 = (int)(rootShape->GetWidth() * 3); + int y0 = (int)(rootShape->GetHeight() * 3 / 2); + int xoffs = (int)(rootShape->GetWidth() * 3); + int yoffs = (int)(rootShape->GetHeight() * 5 / 4); + + wxNode *current = GetDiagram()->GetShapeList()->GetFirst(); + while (current) + { + ExplainShape *s = (ExplainShape *)current->GetData(); + + if (!s->totalShapes) + s->totalShapes = 1; + if (s->GetUpper()) + s->GetUpper()->totalShapes += s->totalShapes; + current = current->GetNext(); + } + + current = GetDiagram()->GetShapeList()->GetLast(); + while (current) + { + ExplainShape *s = (ExplainShape *)current->GetData(); + + s->SetX(y0 + (maxLevel - s->GetLevel()) * xoffs); + ExplainShape *upper = s->GetUpper(); + + if (upper) + { + s->SetY(upper->GetY() + upper->usedShapes * yoffs); + upper->usedShapes += s->totalShapes; + + // We don't require to draw a line from the root shape to its + // childrens + if (upper != rootShape) + { + wxLineShape *l = new ExplainLine(s, upper); + l->Show(true); + AddShape(l); + } + } + else + { + s->SetY(y0); + } + + current = current->GetPrevious(); + } + +#define PIXPERUNIT 20 + int w = (maxLevel * xoffs + x0 * 2 + PIXPERUNIT - 1) / PIXPERUNIT; + int h = (rootShape->totalShapes * yoffs + y0 * 2 + PIXPERUNIT - 1) / PIXPERUNIT; + + SetScrollbars(PIXPERUNIT, PIXPERUNIT, w, h); +} + + +void ExplainCanvas::OnMouseMotion(wxMouseEvent &ev) +{ + ev.Skip(true); + + if (ev.Dragging()) + return; + + wxClientDC dc(this); + PrepareDC(dc); + + wxPoint logPos(ev.GetLogicalPosition(dc)); + + double x, y; + x = (double) logPos.x; + y = (double) logPos.y; + + // Find the nearest object + int attachment = 0; + ExplainShape *nearestObj = dynamic_cast(FindShape(x, y, &attachment)); + + if (nearestObj) + { + ShowPopup(nearestObj); + } +} + + +void ExplainCanvas::ShowPopup(ExplainShape *s) +{ + if (popup || s == NULL) + return; + + popup = new ExplainPopup(this, s, &popup); + +} + + +void ExplainCanvas::SaveAsImage(const wxString &fileName, wxBitmapType imageType) +{ + if (GetDiagram()->GetCount() == 0) + { + wxMessageBox(_("Nothing to be saved!"), _("Save As an image"), wxOK | wxICON_INFORMATION); + return; + } + + int width = 0, height = 0; + GetVirtualSize(&width, &height); + + /* + * Create the bitmap from the Explain window + */ + wxMemoryDC memDC; + wxBitmap tempBitmap(width, height); + + memDC.SelectObject(tempBitmap); + memDC.Clear(); + + // Draw the diagram on the bitmap (Memory Device Context) + GetDiagram()->Redraw(memDC); + + memDC.SelectObject(wxNullBitmap); + + if (!tempBitmap.SaveFile(fileName, imageType)) + { + wxLogError(_("Could not write file \"%s\": error code %d."), fileName.c_str(), wxSysErrorCode()); + } +} + +class ExplainText : public wxWindow +{ +public: + ExplainText(ExplainPopup *parent, ExplainShape *s); + +protected: + void OnMouseMove(wxMouseEvent &ev); +#ifdef wxUSE_POPUPWIN + void OnMouseLost(wxMouseCaptureLostEvent &ev); +#endif + +private: + ExplainPopup *popup; + void OnPaint(wxPaintEvent &ev); + + wxString m_desc, m_detail, m_condition, m_cost, m_actual; + + DECLARE_EVENT_TABLE() +}; + +BEGIN_EVENT_TABLE(ExplainText, wxWindow) + EVT_PAINT(ExplainText::OnPaint) + EVT_MOTION(ExplainText::OnMouseMove) +#ifdef wxUSE_POPUPWIN + EVT_MOUSE_CAPTURE_LOST(ExplainText::OnMouseLost) +#endif +END_EVENT_TABLE() + +ExplainText::ExplainText(ExplainPopup *parent, ExplainShape *s) : wxWindow(parent, -1) +{ + SetBackgroundColour(wxColour(255, 255, 224)); + + popup = parent; + + wxWindowDC dc(this); + dc.SetFont(settings->GetSystemFont()); + + m_desc = s->description; + m_detail = s->detail; + m_condition = s->condition; + m_cost = s->cost; + m_actual = s->actual; + + int w1, w2, h; + dc.GetTextExtent(m_desc, &w1, &h); + + dc.GetTextExtent(m_detail, &w2, &h); + if (w1 < w2) w1 = w2; + dc.GetTextExtent(m_condition, &w2, &h); + if (w1 < w2) w1 = w2; + dc.GetTextExtent(m_cost, &w2, &h); + if (w1 < w2) w1 = w2; + dc.GetTextExtent(m_actual, &w2, &h); + if (w1 < w2) w1 = w2; + + int n = 2; + if (!m_detail.IsEmpty()) + n++; + if (!m_condition.IsEmpty()) + n++; + if (!m_cost.IsEmpty()) + n++; + if (!m_actual.IsEmpty()) + n++; + + if (!h) + h = GetCharHeight(); + + SetSize(GetCharHeight() + w1, GetCharHeight() + h * n + h / 3); +} + +void ExplainText::OnMouseMove(wxMouseEvent &ev) +{ + popup->OnMouseMove(ev); +} + +#ifdef wxUSE_POPUPWIN +void ExplainText::OnMouseLost(wxMouseCaptureLostEvent &ev) +{ + /* + * We will not do anything here. + * But - in order to resolve a weird bug on window, when using + * wxPopupTransientWindow, related to loosing the mouse control, + * was not taken care properly, we have to introduce this function + * to avoid the crash. + * + * Please refer: + * http://article.gmane.org/gmane.comp.lib.wxwidgets.devel/82376 + */ +} +#endif + +void ExplainText::OnPaint(wxPaintEvent &ev) +{ + wxPaintDC dc(this); + + wxFont stdFont = settings->GetSystemFont(); + wxFont boldFont = stdFont; + boldFont.SetWeight(wxBOLD); + + int x = GetCharHeight() / 2; + int y = GetCharHeight() / 2; + int w, yoffs; + dc.GetTextExtent(wxT("Dummy"), &w, &yoffs); + + dc.SetFont(boldFont); + dc.DrawText(m_desc, x, y); + + dc.SetFont(stdFont); + + if (!m_detail.IsEmpty()) + { + y += yoffs; + dc.DrawText(m_detail, x, y); + + } + y += yoffs / 3; + + if (!m_condition.IsEmpty()) + { + y += yoffs; + dc.DrawText(m_condition, x, y); + } + if (!m_cost.IsEmpty()) + { + y += yoffs; + dc.DrawText(m_cost, x, y); + } + if (!m_actual.IsEmpty()) + { + y += yoffs; + dc.DrawText(m_actual, x, y); + } + +#if wxUSE_POPUPWIN + + wxPen pen1 = wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE)), + pen2 = wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW)), + pen3 = wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DHIGHLIGHT)), + pen4 = wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW)); + + wxRect rect(wxPoint(0, 0), GetSize()); + + // draw the rectangle + dc.SetPen(pen1); + dc.DrawLine(rect.GetLeft(), rect.GetTop(), rect.GetLeft(), rect.GetBottom()); + dc.DrawLine(rect.GetLeft() + 1, rect.GetTop(), rect.GetRight(), rect.GetTop()); + dc.SetPen(pen2); + dc.DrawLine(rect.GetRight(), rect.GetTop(), rect.GetRight(), rect.GetBottom()); + dc.DrawLine(rect.GetLeft(), rect.GetBottom(), rect.GetRight() + 1, rect.GetBottom()); + + // adjust the rect + rect.Inflate(-1); + + // draw the rectangle + dc.SetPen(pen3); + dc.DrawLine(rect.GetLeft(), rect.GetTop(), rect.GetLeft(), rect.GetBottom()); + dc.DrawLine(rect.GetLeft() + 1, rect.GetTop(), rect.GetRight(), rect.GetTop()); + dc.SetPen(pen4); + dc.DrawLine(rect.GetRight(), rect.GetTop(), rect.GetRight(), rect.GetBottom()); + dc.DrawLine(rect.GetLeft(), rect.GetBottom(), rect.GetRight() + 1, rect.GetBottom()); + + // adjust the rect + rect.Inflate(-1); + + dc.SetPen(pen1); + dc.SetBrush(*wxTRANSPARENT_BRUSH); + dc.DrawRectangle(rect); + +#endif + +} + + +BEGIN_EVENT_TABLE(ExplainPopup, pgTipWindowBase) + EVT_MOTION(ExplainPopup::OnMouseMove) + EVT_LEFT_DOWN(ExplainPopup::OnMouseClick) + EVT_RIGHT_DOWN(ExplainPopup::OnMouseClick) + EVT_MIDDLE_DOWN(ExplainPopup::OnMouseClick) +#if wxUSE_POPUPWIN + EVT_MOUSE_CAPTURE_LOST(ExplainPopup::OnMouseLost) +#else + EVT_KILL_FOCUS(ExplainPopup::OnKillFocus) + EVT_ACTIVATE(ExplainPopup::OnActivate) +#endif // !wxUSE_POPUPWIN +END_EVENT_TABLE() + +ExplainPopup::ExplainPopup(ExplainCanvas *parent, ExplainShape *shape, ExplainPopup **popup) +#if wxUSE_POPUPWIN + : wxPopupTransientWindow(parent, wxNO_BORDER) +#else + : wxFrame(parent, wxID_ANY, wxEmptyString, + wxDefaultPosition, wxDefaultSize, + wxNO_BORDER | wxFRAME_NO_TASKBAR ) +#endif +{ + wxASSERT(parent != NULL); + wxASSERT(shape != NULL); + + if (popup) + m_ptr = popup; + else + m_ptr = NULL; + + m_explainText = new ExplainText(this, shape); +#if !wxUSE_POPUPWIN + m_creationTime = wxGetLocalTime(); +#endif + double width = 0.0, height = 0.0; + + shape->GetBoundingBoxMin(&width, &height); + if (fabs(width) < 4.0) width = 4.0; + if (fabs(height) < 4.0) height = 4.0; + + width += (double)4.0; + height += (double)4.0; // Allowance for inaccurate mousing + + int x = (int)(shape->GetX() - (width / 2.0)); + int y = (int)(shape->GetY() - (height / 2.0)); + + int sx, sy; + parent->CalcScrolledPosition(x, y, &sx, &sy); + parent->ClientToScreen(&sx, &sy); + + m_rectBound.x = sx; + m_rectBound.y = sy; + m_rectBound.width = WXROUND(width); + m_rectBound.height = WXROUND(height); + + wxSize popupSize; + popupSize = m_explainText->GetSize(); + popupSize.DecTo(wxGetDisplaySize()); + SetSize(popupSize); + + if (sy > GetClientSize().y * 2 / 3) + sy -= GetSize().y; + sx -= GetSize().x / 2; + + if (sx < 5) sx = 5; + + if (sx < 0) x = 0; + +#if wxUSE_POPUPWIN + Position(wxPoint(sx, sy), wxSize(0, 0)); + Popup(m_explainText); + m_explainText->SetFocus(); +#ifdef __WXGTK__ + m_explainText->CaptureMouse(); +#endif +#else + Move(sx, sy); + Show(true); + + m_explainText->SetFocus(); + m_explainText->CaptureMouse(); +#endif +} + + +void ExplainPopup::OnMouseMove(wxMouseEvent &ev) +{ + if ( m_rectBound.width && + !m_rectBound.Contains(ClientToScreen(ev.GetPosition())) ) + { + // mouse left the bounding rect, disappear + Close(); + } + else + { + ev.Skip(); + } +} + + +void ExplainPopup::OnMouseClick(wxMouseEvent &ev) +{ + Close(); +} + + +ExplainPopup::~ExplainPopup() +{ + if (m_ptr) + { + *m_ptr = NULL; + } +#ifdef wxUSE_POPUPWIN +#ifdef __WXGTK__ + if (m_explainText->HasCapture() ) + m_explainText->ReleaseMouse(); +#endif +#endif + if(HasCapture()) + ReleaseMouse(); +} + +void ExplainPopup::Close() +{ + if (m_ptr) + { + *m_ptr = NULL; + m_ptr = NULL; + } + + if (m_explainText->HasCapture()) + m_explainText->ReleaseMouse(); + + if(HasCapture()) + ReleaseMouse(); + +#if wxUSE_POPUPWIN + Show(false); +#ifdef __WXGTK__ +#endif + Destroy(); +#else + wxFrame::Close(); +#endif +} + + +#if wxUSE_POPUPWIN +void ExplainPopup::OnDismiss() +{ + Close(); +} + +void ExplainPopup::OnMouseLost(wxMouseCaptureLostEvent &ev) +{ + /* Do Nothing */ +} +#else +void ExplainPopup::OnKillFocus(wxFocusEvent &event) +{ + // Workaround the kill focus event happening just after creation in wxGTK + if (wxGetLocalTime() > m_creationTime + 1 && + m_rectBound.width && + !m_rectBound.Contains(::wxGetMousePosition())) + { + Close(); + return; + } + m_explainText->SetFocus(); + m_explainText->CaptureMouse(); +} + + +void ExplainPopup::OnActivate(wxActivateEvent &event) +{ + if (!event.GetActive()) + { + if ( m_rectBound.width && + !m_rectBound.Contains(::wxGetMousePosition()) ) + { + Close(); + return; + } + m_explainText->SetFocus(); + m_explainText->CaptureMouse(); + } +} +#endif // !wxUSE_POPUPWIN diff --git a/ctl/explainShape.cpp b/ctl/explainShape.cpp new file mode 100644 index 0000000..48a8068 --- /dev/null +++ b/ctl/explainShape.cpp @@ -0,0 +1,581 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// explainShape.cpp - Explain Shapes +// +////////////////////////////////////////////////////////////////////////// + + + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "ctl/explainCanvas.h" + +#include + +#include "images/ex_aggregate.pngc" +#include "images/ex_append.pngc" +#include "images/ex_bmp_and.pngc" +#include "images/ex_bmp_heap.pngc" +#include "images/ex_bmp_index.pngc" +#include "images/ex_bmp_or.pngc" +#include "images/ex_cte_scan.pngc" +#include "images/ex_delete.pngc" +#include "images/ex_foreign_scan.pngc" +#include "images/ex_group.pngc" +#include "images/ex_hash.pngc" +#include "images/ex_hash_anti_join.pngc" +#include "images/ex_hash_semi_join.pngc" +#include "images/ex_hash_setop_except.pngc" +#include "images/ex_hash_setop_except_all.pngc" +#include "images/ex_hash_setop_intersect.pngc" +#include "images/ex_hash_setop_intersect_all.pngc" +#include "images/ex_hash_setop_unknown.pngc" +#include "images/ex_index_only_scan.pngc" +#include "images/ex_index_scan.pngc" +#include "images/ex_insert.pngc" +#include "images/ex_lock_rows.pngc" +#include "images/ex_join.pngc" +#include "images/ex_limit.pngc" +#include "images/ex_materialize.pngc" +#include "images/ex_merge.pngc" +#include "images/ex_merge_anti_join.pngc" +#include "images/ex_merge_append.pngc" +#include "images/ex_merge_semi_join.pngc" +#include "images/ex_gatcher.pngc" +#include "images/ex_nested.pngc" +#include "images/ex_nested_loop_anti_join.pngc" +#include "images/ex_nested_loop_semi_join.pngc" +#include "images/ex_recursive_union.pngc" +#include "images/ex_result.pngc" +#include "images/ex_scan.pngc" +#include "images/ex_pscan.pngc" +#include "images/ex_seek.pngc" +#include "images/ex_setop.pngc" +#include "images/ex_sort.pngc" +#include "images/ex_subplan.pngc" +#include "images/ex_tid_scan.pngc" +#include "images/ex_unique.pngc" +#include "images/ex_unknown.pngc" +#include "images/ex_update.pngc" +#include "images/ex_values_scan.pngc" +#include "images/ex_window_aggregate.pngc" +#include "images/ex_worktable_scan.pngc" + +// Greenplum images +#include "images/ex_broadcast_motion.pngc" +#include "images/ex_redistribute_motion.pngc" +#include "images/ex_gather_motion.pngc" + +#define BMP_BORDER 3 + +ExplainShape::ExplainShape(const wxImage &bmp, const wxString &description, long tokenNo, long detailNo) +{ + SetBitmap(wxBitmap(bmp)); + SetLabel(description, tokenNo, detailNo); + kidCount = 0; + totalShapes = 0; + usedShapes = 0; + m_rootShape = false; +} + + +void ExplainShape::SetLabel(const wxString &str, int tokenNo, int detailNo) +{ + if (tokenNo < 0) + { + description = str; + label = str; + } + else + { + wxStringTokenizer tokens(str, wxT(" ")); + + while (tokenNo-- >= 0) + { + label = tokens.GetNextToken(); + + if (detailNo <= 0) + { + if (!description.IsEmpty()) + description.Append(wxT(" ")); + + description.Append(label); + } + } + if (detailNo > 0) + { + tokens.SetString(str, wxT(" ")); + + while (detailNo--) + { + if (!description.IsEmpty()) + description.Append(wxT(" ")); + + description.Append(tokens.GetNextToken()); + } + detail = tokens.GetString(); + } + } +} + +void ExplainShape::OnDraw(wxDC &dc) +{ + wxBitmap &bmp = GetBitmap(); + if (!bmp.Ok()) + return; + + // We do not draw the root shape + if (m_rootShape) + return; + + int x, y; + x = WXROUND(m_xpos - bmp.GetWidth() / 2.0); + y = WXROUND(m_ypos - GetHeight() / 2.0); + + dc.DrawBitmap(bmp, x, y, true); + + int w, h; + dc.SetFont(GetCanvas()->GetFont()); + dc.GetTextExtent(label, &w, &h); + + x = WXROUND(m_xpos - w / 2.0); + y += bmp.GetHeight() + BMP_BORDER; + + dc.DrawText(label, x, y); +} + + +void ExplainShape::OnLeftClick(double x, double y, int keys, int attachment) +{ + ((ExplainCanvas *)GetCanvas())->ShowPopup(this); +} + + +#define ARROWMARGIN 5 +wxRealPoint ExplainShape::GetStartPoint() +{ + wxRealPoint rp(GetX() + GetBitmap().GetWidth() / 2.0 + ARROWMARGIN, GetY() - (GetHeight() - GetBitmap().GetHeight()) / 2.); + return rp; +} + + +wxRealPoint ExplainShape::GetEndPoint(int kidNo) +{ + wxRealPoint rp(GetX() - GetBitmap().GetWidth() / 2.0 - ARROWMARGIN, GetY() - (GetHeight() - GetBitmap().GetHeight()) / 2. + (kidCount > 1 ? GetBitmap().GetHeight() * 2. / 3. * kidNo / (2 * kidCount - 2) : 0 )); + return rp; +} + + + +ExplainShape *ExplainShape::Create(long level, ExplainShape *last, const wxString &str) +{ + ExplainShape *s = 0; + + int costPos = str.Find(wxT("(cost=")); + int actPos = str.Find(wxT("(actual")); + bool parallel=false; + int inc=0; + wxStringTokenizer tokens(str, wxT(" ")); + wxString token = tokens.GetNextToken(); + if (token == wxT("Parallel")) + { + token = tokens.GetNextToken(); + parallel=true; + inc=1; + } + + wxString token2 = tokens.GetNextToken(); + wxString token3 = tokens.GetNextToken(); + wxString token4; + if (tokens.HasMoreTokens()) + token4 = tokens.GetNextToken(); + wxString descr; + if (costPos > 0) + descr = str.Left(costPos); + else if (actPos > 0) + descr = str.Left(actPos); + else + descr = str; + + // Requested an empty shape, which can be treated as a root shape + if (level == 0) + { + s = new ExplainShape(*ex_unknown_png_img, wxEmptyString); + s->SetDraggable(false); + s->m_rootShape = true; + s->level = level; + int w = 50, h = 20; + + wxBitmap &bmp = s->GetBitmap(); + if (w < bmp.GetWidth()) + w = bmp.GetWidth(); + + s->SetHeight(bmp.GetHeight() + BMP_BORDER + h); + s->SetWidth(w); + + s->upperShape = NULL; + s->kidNo = 0; + + return s; + } + + + // possible keywords can be found in postgresql/src/backend/commands/explain.c + + if (token == wxT("Total")) return 0; + else if (token == wxT("Trigger")) return 0; + else if (token == wxT("Settings:")) return 0; /* Greenplum */ + else if (token == wxT("Slice")) return 0; /* Greenplum */ + else if (token.Mid(0, 6) == wxT("(slice")) return 0; /* Greenplum */ + else if (token == wxT("Result")) s = new ExplainShape(*ex_result_png_img, descr); + else if (token == wxT("Append")) s = new ExplainShape(*ex_append_png_img, descr); + else if (token == wxT("Gather")) s = new ExplainShape(*ex_gatcher_png_img, descr); + else if (token == wxT("Nested")) + { + if (token2 == wxT("Loop") && token4 == wxT("Join")) + { + // Nested Loop Anti Join + if (token3 == wxT("Anti")) + { + s = new ExplainShape(*ex_nested_loop_anti_join_png_img, descr); + } + // Nested Loop Semi Join + else + { + s = new ExplainShape(*ex_nested_loop_semi_join_png_img, descr); + } + } + if (!s) + s = new ExplainShape(*ex_nested_png_img, descr); + } + else if (token == wxT("Merge")) + { + if (token3 == wxT("Join")) + { + // Merge Anti Join + if (token2 == wxT("Anti")) + { + s = new ExplainShape(*ex_merge_anti_join_png_img, descr); + } + // Merge Semi Join + else + { + s = new ExplainShape(*ex_merge_semi_join_png_img, descr); + } + } + // Merge Append + else if (token2 == wxT("Append")) + { + s = new ExplainShape(*ex_merge_append_png_img, descr); + } + else + { + s = new ExplainShape(*ex_merge_png_img, descr); + } + } + else if (token == wxT("Hash")) + { + if (token2 == wxT("Join")) + { + s = new ExplainShape(*ex_join_png_img, descr); + } + else + { + if (token3 == wxT("Join")) + { + // Hash Anti Join + if (token2 == wxT("Anti")) + { + s = new ExplainShape(*ex_hash_anti_join_png_img, descr); + } + // Hash Semi Join + else if (token2 == wxT("Semi")) + { + s = new ExplainShape(*ex_hash_semi_join_png_img, descr); + } + else + { + s = new ExplainShape(*ex_hash_png_img, descr); + } + } + else + { + s = new ExplainShape(*ex_hash_png_img, descr); + } + } + } + else if (token == wxT("HashSetOp")) + { + if (token2 == wxT("Except")) + { + // HashSetOp Except ALL + if (token3 == wxT("ALL")) + { + s = new ExplainShape(*ex_hash_setop_except_all_png_img, descr); + } + // HashSetOp Except + else + { + s = new ExplainShape(*ex_hash_setop_except_png_img, descr); + } + } + else if (token2 == wxT("Intersect")) + { + // HashSetOp Intersect ALL + if (token3 == wxT("ALL")) + { + s = new ExplainShape(*ex_hash_setop_intersect_all_png_img, descr); + } + // HashSetOp Intersect + else + { + s = new ExplainShape(*ex_hash_setop_intersect_png_img, descr); + } + } + else + { + // HashSetOp ??? + s = new ExplainShape(*ex_hash_setop_unknown_png_img, descr); + } + } + else if (token == wxT("Subquery")) s = new ExplainShape(*ex_subplan_png_img, descr, 0, 2); + else if (token == wxT("Function")) s = new ExplainShape(*ex_result_png_img, descr, 0, 2); + else if (token == wxT("Materialize")) s = new ExplainShape(*ex_materialize_png_img, descr); + else if (token == wxT("Sort")) s = new ExplainShape(*ex_sort_png_img, descr); + else if (token == wxT("Group")) s = new ExplainShape(*ex_group_png_img, descr); + else if (token == wxT("Aggregate") || token == wxT("GroupAggregate") || token == wxT("HashAggregate")) + s = new ExplainShape(*ex_aggregate_png_img, descr); + else if (token == wxT("Unique")) s = new ExplainShape(*ex_unique_png_img, descr); + else if (token == wxT("SetOp")) s = new ExplainShape(*ex_setop_png_img, descr); + else if (token == wxT("Limit")) s = new ExplainShape(*ex_limit_png_img, descr); + else if (token == wxT("LockRows")) s = new ExplainShape(*ex_lock_rows_png_img, descr); + else if (token == wxT("Bitmap")) + { + if (token2 == wxT("Index")) s = new ExplainShape(*ex_bmp_index_png_img, descr, 4+inc, 3+inc); + else s = new ExplainShape(*ex_bmp_heap_png_img, descr, 4+inc, 3+inc); + } + else if (token == wxT("BitmapAnd")) s = new ExplainShape(*ex_bmp_and_png_img, descr); + else if (token == wxT("BitmapOr")) s = new ExplainShape(*ex_bmp_or_png_img, descr); + else if (token2 == wxT("Scan")) + { + if (token == wxT("Index")) + // Scan Index Backward + if (token3 == wxT("Backward")) + s = new ExplainShape(*ex_index_scan_png_img, descr, 4+inc, 3+inc); + else + s = new ExplainShape(*ex_index_scan_png_img, descr, 3+inc, 2+inc); + // Tid Scan + else if (token == wxT("Tid")) + s = new ExplainShape(*ex_tid_scan_png_img, descr, 3+inc, 2+inc); + // WorkTable Scan + else if (token == wxT("WorkTable")) + s = new ExplainShape(*ex_worktable_scan_png_img, descr, 3+inc, 2+inc); + // CTE Scan + else if (token == wxT("CTE")) + s = new ExplainShape(*ex_cte_scan_png_img, descr, 3, 2); + // Foreign Scan + else if (token == wxT("Foreign")) + s = new ExplainShape(*ex_foreign_scan_png_img, descr, 3, 2); + // Values Scan + else if (token == wxT("Values")) + s = new ExplainShape(*ex_values_scan_png_img, descr, 3, 2); + else if (parallel) s = new ExplainShape(*ex_pscan_png_img, descr, 4, 3); + else + s = new ExplainShape(*ex_scan_png_img, descr, 3+inc, 2+inc); + } + else if (token == wxT("Index")) + { + // Index Only Scan + if (token2 == wxT("Only") && token3 == wxT("Scan")) + { + s = new ExplainShape(*ex_index_only_scan_png_img, descr, 4+inc, 3+inc); + } + } + else if (token2 == wxT("Seek")) s = new ExplainShape(*ex_seek_png_img, descr, 3, 2); + // Recursive Union + else if (token == wxT("Recursive") && token2 == wxT("Union")) + s = new ExplainShape(*ex_recursive_union_png_img, descr); + else if (token == wxT("WindowAgg")) + s = new ExplainShape(*ex_window_aggregate_png_img, descr); + + // DML + else if (token == wxT("Insert")) + s = new ExplainShape(*ex_insert_png_img, descr, 2, 1); + else if (token == wxT("Update")) + s = new ExplainShape(*ex_update_png_img, descr, 2, 1); + else if (token == wxT("Delete")) + s = new ExplainShape(*ex_delete_png_img, descr, 2, 1); + + // Greenplum additions + else if (token == wxT("Gather") && token2 == wxT("Motion")) + s = new ExplainShape(*ex_gather_motion_png_img, descr); + else if (token == wxT("Broadcast") && token2 == wxT("Motion")) + s = new ExplainShape(*ex_broadcast_motion_png_img, descr); + else if (token == wxT("Redistribute") && token2 == wxT("Motion")) + s = new ExplainShape(*ex_redistribute_motion_png_img, descr); + + if (!s) + s = new ExplainShape(*ex_unknown_png_img, descr); + + s->SetDraggable(false); + + s->level = level; + + if (costPos > 0) + { + if (actPos > 0) + { + s->actual = str.Mid(actPos); + s->cost = str.Mid(costPos, actPos - costPos); + } + else + s->cost = str.Mid(costPos); + } + else if (actPos > 0) + s->actual = str.Mid(actPos); + + int w = 50, h = 20; + + wxBitmap &bmp = s->GetBitmap(); + if (w < bmp.GetWidth()) + w = bmp.GetWidth(); + + s->SetHeight(bmp.GetHeight() + BMP_BORDER + h); + s->SetWidth(w); + + s->upperShape = last; + if (last) + { + s->kidNo = last->kidCount; + last->kidCount++; + } + else + s->kidNo = 0; + + if (costPos > 0) + { + wxChar *cl = const_cast((const wxChar *)str + costPos + 6); + wxChar *ch = wxStrstr(cl, wxT("..")); + if (ch) + { + *ch = 0; + ch += 2; + } + s->costLow = StrToDouble(cl); + if (ch) + { + wxChar *r = wxStrstr(ch, wxT(" rows=")); + if (r) + { + *r = 0; + r += 6; + } + s->costHigh = StrToDouble(ch); + if (r) + { + wxChar *w = wxStrstr(r, wxT(" width=")); + if (w) + { + *w = 0; + w += 7; + } + s->rows = StrToLong(r); + if (w) + s->width = StrToLong(w); + } + } + } + return s; +} + + +ExplainLine::ExplainLine(ExplainShape *from, ExplainShape *to, double weight) +{ + SetCanvas(from->GetCanvas()); + from->AddLine(this, to); + MakeLineControlPoints(4); + + width = (int) log(from->GetAverageCost()); + if (width > 10) + width = 10; + + // If we got an average cost of 0, width is probably negative + // which will look pretty darn ugly as an arrow width! + // This may happen on Greenplum. + if (width < 1) + width = 1; + + wxNode *first = GetLineControlPoints()->GetFirst(); + wxNode *last = GetLineControlPoints()->GetLast(); + *(wxRealPoint *)first->GetData() = from->GetStartPoint(); + *(wxRealPoint *)last->GetData() = to->GetEndPoint(from->GetKidno()); + + wxRealPoint *p1 = (wxRealPoint *)first->GetNext()->GetData(); + wxRealPoint *p2 = (wxRealPoint *)last->GetPrevious()->GetData(); + *p1 = from->GetStartPoint(); + *p2 = to->GetEndPoint(from->GetKidno()); + p1->x -= (p1->x - p2->x) / 3. + 8; + p2->x += (p1->x - p2->x) / 3. - 8; + + Initialise(); +} + + +#define ARROWWIDTH 4 + + +void ExplainLine::OnDraw(wxDC &dc) +{ + if (m_lineControlPoints) + { + dc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, 1, wxSOLID)); + dc.SetBrush(*wxTheBrushList->FindOrCreateBrush(*wxLIGHT_GREY, wxSOLID)); + + wxPoint *points = new wxPoint[11]; + wxRealPoint *point0 = (wxRealPoint *) m_lineControlPoints->Item(0)->GetData(); + wxRealPoint *point1 = (wxRealPoint *) m_lineControlPoints->Item(1)->GetData(); + wxRealPoint *point2 = (wxRealPoint *) m_lineControlPoints->Item(2)->GetData(); + wxRealPoint *point3 = (wxRealPoint *) m_lineControlPoints->Item(3)->GetData(); + + double phi = atan2(point2->y - point1->y, point2->x - point1->x); + double offs = width * tan(phi / 2); + + points[0].x = WXROUND(point0->x); + points[0].y = WXROUND(point0->y) - width; + points[10].x = WXROUND(point0->x); + points[10].y = WXROUND(point0->y) + width; + + points[1].x = WXROUND(point1->x + offs); + points[1].y = WXROUND(point1->y) - width; + points[9].x = WXROUND(point1->x - offs); + points[9].y = WXROUND(point1->y) + width; + + points[2].x = WXROUND(point2->x + offs); + points[2].y = WXROUND(point2->y) - width; + points[8].x = WXROUND(point2->x - offs); + points[8].y = WXROUND(point2->y) + width; + + points[3].x = WXROUND(point3->x) - width - ARROWWIDTH; + points[3].y = WXROUND(point3->y) - width; + points[7].x = WXROUND(point3->x) - width - ARROWWIDTH; + points[7].y = WXROUND(point3->y) + width; + + points[4].x = points[3].x; + points[4].y = points[3].y - ARROWWIDTH; + points[6].x = points[7].x; + points[6].y = points[7].y + ARROWWIDTH; + + points[5].x = WXROUND(point3->x); + points[5].y = WXROUND(point3->y); + + dc.DrawPolygon(11, points, 0, 0); + } +} diff --git a/ctl/module.mk b/ctl/module.mk new file mode 100644 index 0000000..66e9bbe --- /dev/null +++ b/ctl/module.mk @@ -0,0 +1,42 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/ctl/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + ctl/calbox.cpp \ + ctl/ctlAuiNotebook.cpp \ + ctl/ctlCheckTreeView.cpp \ + ctl/ctlColourPicker.cpp \ + ctl/ctlComboBox.cpp \ + ctl/ctlListView.cpp \ + ctl/ctlMenuToolbar.cpp \ + ctl/ctlSQLBox.cpp \ + ctl/ctlSQLGrid.cpp \ + ctl/ctlSQLResult.cpp \ + ctl/ctlDefaultSecurityPanel.cpp \ + ctl/ctlSeclabelPanel.cpp \ + ctl/ctlSecurityPanel.cpp \ + ctl/ctlTree.cpp \ + ctl/ctlProgressStatusBar.cpp \ + ctl/explainCanvas.cpp \ + ctl/explainShape.cpp \ + ctl/timespin.cpp \ + ctl/xh_calb.cpp \ + ctl/xh_ctlcolourpicker.cpp \ + ctl/xh_ctlcombo.cpp \ + ctl/xh_ctlchecktreeview.cpp \ + ctl/xh_ctltree.cpp \ + ctl/xh_sqlbox.cpp \ + ctl/xh_timespin.cpp + +EXTRA_DIST += \ + ctl/module.mk + + diff --git a/ctl/timespin.cpp b/ctl/timespin.cpp new file mode 100644 index 0000000..ac6b025 --- /dev/null +++ b/ctl/timespin.cpp @@ -0,0 +1,461 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// timespin.cpp - timeSpin SpinCtrl +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include +#include "ctl/timespin.h" + + +#define CTRLID_TXT 101 +#define CTRLID_SPN 102 + + +BEGIN_EVENT_TABLE(wxTimeSpinCtrl, wxControl) + EVT_TEXT(CTRLID_TXT, wxTimeSpinCtrl::OnText) + EVT_NAVIGATION_KEY(wxTimeSpinCtrl::OnNavigate) + EVT_SPIN_UP(CTRLID_SPN, wxTimeSpinCtrl::OnSpinUp) + EVT_SPIN_DOWN(CTRLID_SPN, wxTimeSpinCtrl::OnSpinDown) + EVT_SPIN(CTRLID_SPN, wxTimeSpinCtrl::OnSpin) + EVT_SET_FOCUS(wxTimeSpinCtrl::OnSetFocus) + EVT_SIZE(wxTimeSpinCtrl::OnSize) +END_EVENT_TABLE() + + +IMPLEMENT_DYNAMIC_CLASS(wxTimeSpinCtrl, wxControl) + + +wxTimeSpinCtrl::wxTimeSpinCtrl(wxWindow *parent, + wxWindowID id, + const wxPoint &pos, + const wxSize &size, + long style, + const wxString &name) +{ + Init(); + Create(parent, id, pos, size, style, name); +} + + +bool wxTimeSpinCtrl::Create(wxWindow *parent, + wxWindowID id, + const wxPoint &pos, + const wxSize &size, + long style, + const wxString &name) +{ + wxControl::Create(parent, id, pos, size, style & ~(wxSP_WRAP | wxSP_ARROW_KEYS), wxDefaultValidator, name); + SetFont(parent->GetFont()); + + m_spn = new wxSpinButton(this, CTRLID_SPN, wxDefaultPosition, wxDefaultSize, wxSP_WRAP | wxSP_VERTICAL | (style & wxSP_ARROW_KEYS)); + + wxSize cs = GetClientSize(); + wxSize ss = m_spn->GetBestSize(); + + m_txt = new wxTextCtrl(this, CTRLID_TXT, wxEmptyString, wxPoint(0, 0), wxSize(cs.x - ss.x, cs.y), wxWANTS_CHARS); + m_txt->Connect(wxID_ANY, wxID_ANY, wxEVT_KEY_DOWN, wxKeyEventHandler(wxTimeSpinCtrl::OnEditKey), 0, this); + m_txt->Connect(wxID_ANY, wxID_ANY, wxEVT_KILL_FOCUS, wxFocusEventHandler(wxTimeSpinCtrl::OnKillFocus), 0, this); + + wxArrayString valArray; + wxChar c; + for (c = '0'; c <= '9'; c++) + valArray.Add(wxString(c, 1)); + valArray.Add(wxT(":")); + wxTextValidator tv(wxFILTER_INCLUDE_CHAR_LIST); + tv.SetIncludes(valArray); + m_txt->SetValidator(tv); + + m_spn->SetSize(ss.x, cs.y); + m_spn->SetPosition(wxPoint(cs.x - ss.x, 0)); + + canWrap = (style & wxSP_WRAP) != 0; + SetMax(24 * 60 * 60 - 1); + + SetInitialSize(size); + + return true; +} + +#define TXTPOSX 0 +#define TXTPOSY 0 +void wxTimeSpinCtrl::OnSize(wxSizeEvent &event) +{ + if ( m_spn ) + { + wxSize sz = GetClientSize(); + + wxSize ss = m_spn->GetSize(); + int eh = m_txt->GetBestSize().y; + + m_txt->SetSize(TXTPOSX, TXTPOSY, sz.x - ss.x - TXTPOSX, sz.y > eh ? eh - TXTPOSY : sz.y - TXTPOSY); + m_spn->SetSize(sz.x - ss.x, 0, ss.x, sz.y); + } + + event.Skip(); +} + + +bool wxTimeSpinCtrl::Destroy() +{ + if (m_txt) + { + m_txt->Destroy(); + m_txt = NULL; + } + if (m_spn) + { + m_spn->Destroy(); + m_spn = NULL; + } + return true; +} + + +void wxTimeSpinCtrl::Init() +{ + m_txt = NULL; + m_spn = NULL; + spinValue = 0; +} + + +wxSize wxTimeSpinCtrl::DoGetBestSize() const +{ +#ifdef __WXGTK__ + return wxSize(100, m_spn->GetBestSize().y); +#else + return wxSize(100, m_txt->GetBestSize().y); +#endif +} + + +bool wxTimeSpinCtrl::Enable(bool enable) +{ + m_txt->Enable(enable); + m_spn->Enable(enable); + + return true; +} + +void wxTimeSpinCtrl::SetMax(long seconds, bool useDay) +{ + hasDay = useDay; + if (hasDay) + m_format = wxT("%D:%H:%M:%S"); + else + m_format = wxT("%H:%M:%S"); + maxSpinValue = seconds + 1; + if (maxSpinValue < 2) + maxSpinValue = 2; + m_spn->SetRange(0, 32767); +} + + +bool wxTimeSpinCtrl::SetTime(const wxDateTime &time) +{ + if (time.IsValid()) + { + wxDateTime tt(time); + tt.ResetTime(); + return SetValue(time - tt); + } + else + { + m_txt->SetValue(wxEmptyString); + return false; + } +} + + +bool wxTimeSpinCtrl::SetValue(const wxTimeSpan &span) +{ + m_txt->SetValue(span.Format(m_format)); + spinValue = span.GetSeconds().GetLo(); + return true; +} + + + +wxTimeSpan wxTimeSpinCtrl::GetValue() +{ + return wxTimeSpan(0, 0, spinValue); +} + + +int wxTimeSpinCtrl::GetTimePart() +{ + wxString strAfter = m_txt->GetRange(m_txt->GetInsertionPoint(), 9999); + int cnt = 0; + const wxChar *p = (const wxChar *)strAfter; + while (*p) + { + if (*p++ == ':') + cnt++; + } + return cnt; +} + + +void wxTimeSpinCtrl::Highlight(int tp) +{ + wxString txt = m_txt->GetValue(); + long from = 0, to; + int i; + + for (i = 3 - tp - (hasDay ? 0 : 1) ; i > 0 ; i--) + from += txt.Mid(from).Find(':') + 1; + + to = txt.Mid(from).Find(':') + from; + if (to < from) + to = 999; + + m_txt->SetSelection(from, to); +} + + +void wxTimeSpinCtrl::OnSpinUp(wxSpinEvent &ev) +{ +#ifdef __WXMSW__ + m_txt->SetFocus(); +#endif + DoSpin(1); +} + +void wxTimeSpinCtrl::OnSpinDown(wxSpinEvent &ev) +{ +#ifdef __WXMSW__ + m_txt->SetFocus(); +#endif + DoSpin(-1); +} + + +void wxTimeSpinCtrl::OnSpin(wxSpinEvent &ev) +{ + wxCommandEvent parentSpinEvt(ev.GetEventType(), this->GetId()); + this->GetEventHandler()->AddPendingEvent(parentSpinEvt); +} + +void wxTimeSpinCtrl::DoSpin(int diff) +{ + int tp = GetTimePart(); + long oldValue = 0, maxValue = 0, mult = 0; + + switch (tp) + { + case 0: + oldValue = spinValue; + maxValue = 60; + mult = 1; + break; + case 1: + oldValue = spinValue / 60; + maxValue = 60; + mult = 60; + break; + + case 2: + oldValue = spinValue / 60 / 60; + if (hasDay) + maxValue = 24; + else + maxValue = maxSpinValue / 60 / 60; + mult = 60 * 60; + break; + case 3: + oldValue = spinValue / 60 / 60 / 24; + maxValue = maxSpinValue / 60 / 60 / 24; + mult = 60 * 60 * 24; + break; + default: + // can't happen + break; + } + oldValue %= maxValue; + int newValue = oldValue + diff; + + if (!canWrap) + { + if (newValue < 0) + diff += maxValue; + else if (newValue >= maxValue) + diff -= maxValue; + } + + long newSpinValue = spinValue + diff * mult; + if (newSpinValue < 0) + newSpinValue = maxSpinValue - 1; + else if (newSpinValue > maxSpinValue) + newSpinValue = 0; + + if (spinValue != newSpinValue) + { + spinValue = newSpinValue; + wxTimeSpan span(0, 0, spinValue); + wxString txt = span.Format(m_format); + m_txt->SetValue(txt); + Highlight(tp); + + wxSpinEvent ev; + ev.SetEventObject(this); + ev.SetId(GetId()); + +#if wxCHECK_VERSION(2, 9, 0) + GetParent()->GetEventHandler()->ProcessEvent(ev); +#else + GetParent()->ProcessEvent(ev); +#endif + } +} + + +void wxTimeSpinCtrl::OnText(wxCommandEvent &ev) +{ + long time = GetTextTime(); + if (time >= 0) + { + spinValue = time; + ev.SetEventObject(this); + ev.SetId(GetId()); +#if wxCHECK_VERSION(2, 9, 0) + GetParent()->GetEventHandler()->ProcessEvent(ev); +#else + GetParent()->ProcessEvent(ev); +#endif + } +} + + +void wxTimeSpinCtrl::OnNavigate(wxNavigationKeyEvent &ev) +{ + if (wxWindow::FindFocus() == m_txt) + { + int tp = GetTimePart(); + if (ev.GetDirection()) + tp++; + else + tp--; + if ((tp >= 0 && tp < 3) || (hasDay && tp == 3)) + { + Highlight(tp); + return; + } + } + ev.Skip(); +} + + +void wxTimeSpinCtrl::OnEditKey(wxKeyEvent &ev) +{ + if (!ev.HasModifiers()) + { + switch(ev.GetKeyCode()) + { + case WXK_LEFT: + { + if (!ev.ShiftDown()) + { + int tp = GetTimePart() + 1; + if (tp < 3 || (hasDay && tp == 3)) + { + Highlight(tp); + return; + } + } + break; + } + case WXK_RIGHT: + { + if (!ev.ShiftDown()) + { + int tp = GetTimePart() - 1; + if (tp >= 0) + { + Highlight(tp); + return; + } + } + break; + } + case WXK_UP: + DoSpin(1); + return; + break; + case WXK_DOWN: + DoSpin(-1); + return; + break; + default: + break; + } + } + ev.Skip(); +} + + +long wxTimeSpinCtrl::GetTextTime() +{ + int t1, t2, t3, t4; + int scanned = wxSscanf(m_txt->GetValue(), wxT("%d:%d:%d:%d"), &t1, &t2, &t3, &t4); + + switch (scanned) + { + case 1: + if (t1 >= 0) + return t1; + break; + case 2: + if (t1 >= 0 && t2 >= 0 && t2 < 60) + return t1 * 60 + t2; + break; + case 3: + if (t1 >= 0 && t2 >= 0 && t2 < 60 && t3 >= 0 && t3 < 60) + return (t1 * 60 + t2) * 60 + t3; + break; + case 4: + if (t1 >= 0 && t2 >= 0 && t2 < 24 && t3 >= 0 && t3 < 60 && t4 >= 0 && t4 < 60) + return ((t1 * 24 + t2) * 60 + t3) * 60 + t4; + break; + default: + break; + } + return -1; +} + + +void wxTimeSpinCtrl::OnKillFocus(wxFocusEvent &ev) +{ +#ifdef __WXGTK__ + ev.Skip(); +#endif + + long time = GetTextTime(); + + if (time < 0) + { + m_txt->SetValue(wxEmptyString); + spinValue = 0; + m_spn->SetValue(0); + } + else + { + int tp = GetTimePart(); + SetValue(wxTimeSpan(0, 0, time)); + Highlight(tp); + } +} + + +void wxTimeSpinCtrl::OnSetFocus(wxFocusEvent &ev) +{ + m_txt->SetFocus(); + Highlight(hasDay ? 3 : 2); +} diff --git a/ctl/xh_calb.cpp b/ctl/xh_calb.cpp new file mode 100644 index 0000000..271b094 --- /dev/null +++ b/ctl/xh_calb.cpp @@ -0,0 +1,77 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// xh_calb.cpp - wxCalendarBox handler +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include "wx/wx.h" +#include "ctl/xh_calb.h" +#include "ctl/calbox.h" + + +IMPLEMENT_DYNAMIC_CLASS(wxCalendarBoxXmlHandler, wxXmlResourceHandler) + +wxCalendarBoxXmlHandler::wxCalendarBoxXmlHandler() + : wxXmlResourceHandler() +{ + /* + * Only available with the wxDatePickerCtrl + */ + XRC_ADD_STYLE(wxDP_DEFAULT); + XRC_ADD_STYLE(wxDP_SPIN); + XRC_ADD_STYLE(wxDP_DROPDOWN); + XRC_ADD_STYLE(wxDP_ALLOWNONE); + XRC_ADD_STYLE(wxDP_SHOWCENTURY); + + AddWindowStyles(); +} + + +wxObject *wxCalendarBoxXmlHandler::DoCreateResource() +{ + XRC_MAKE_INSTANCE(calendar, wxCalendarBox); + +#if pgUSE_WX_CAL + calendar->Create(m_parentAsWindow, + GetID(), + wxDefaultDateTime, + GetPosition(), GetSize(), + wxDP_DEFAULT | wxDP_SHOWCENTURY | wxDP_ALLOWNONE, + wxDefaultValidator, + GetName()); + +#else // pgUSE_WX_CAL +#if !defined(wxUSE_DATEPICKCTRL) || !wxUSE_DATEPICKCTRL + calendar->Create(m_parentAsWindow, + GetID(), + wxDefaultDateTime, + GetPosition(), GetSize(), + GetStyle(), + GetName()); +#else // !defined(wxUSE_DATEPICKCTRL) || !wxUSE_DATEPICKCTRL + calendar->Create(m_parentAsWindow, + (wxWindowID)GetID(), + wxDefaultDateTime, + GetPosition(), GetSize(), + (long int)GetStyle(), + wxDefaultValidator, + GetName()); +#endif // !defined(wxUSE_DATEPICKCTRL) || !wxUSE_DATEPICKCTRL +#endif // pgUSE_WX_CAL + + SetupWindow(calendar); + + return calendar; +} + +bool wxCalendarBoxXmlHandler::CanHandle(wxXmlNode *node) +{ + return IsOfClass(node, wxT("wxCalendarBox")); +} diff --git a/ctl/xh_ctlchecktreeview.cpp b/ctl/xh_ctlchecktreeview.cpp new file mode 100644 index 0000000..ef44934 --- /dev/null +++ b/ctl/xh_ctlchecktreeview.cpp @@ -0,0 +1,33 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// xh_ctlchecktreeview.cpp - ctlCheckTreeView handler +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include "wx/wx.h" +#include "ctl/ctlCheckTreeView.h" +#include "ctl/xh_ctlchecktreeview.h" + +IMPLEMENT_DYNAMIC_CLASS(ctlCheckTreeViewXmlHandler, wxTreeCtrlXmlHandler) + + +wxObject *ctlCheckTreeViewXmlHandler::DoCreateResource() +{ + ctlCheckTreeView *ctl = new ctlCheckTreeView(m_parentAsWindow, GetID(), GetPosition(), GetSize(), GetStyle()); + + SetupWindow(ctl); + + return ctl; +} + +bool ctlCheckTreeViewXmlHandler::CanHandle(wxXmlNode *node) +{ + return IsOfClass(node, wxT("ctlCheckTreeView")); +} diff --git a/ctl/xh_ctlcolourpicker.cpp b/ctl/xh_ctlcolourpicker.cpp new file mode 100644 index 0000000..51e8607 --- /dev/null +++ b/ctl/xh_ctlcolourpicker.cpp @@ -0,0 +1,33 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the BSD Licence +// +// xh_ctlcolourpicker.cpp - ctlColourPicker handler +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include "wx/wx.h" +#include "ctl/ctlColourPicker.h" +#include "ctl/xh_ctlcolourpicker.h" + +IMPLEMENT_DYNAMIC_CLASS(ctlColourPickerXmlHandler, wxBitmapButtonXmlHandler) + + +wxObject *ctlColourPickerXmlHandler::DoCreateResource() +{ + ctlColourPicker *ctl = new ctlColourPicker(m_parentAsWindow, GetID(), GetPosition(), GetSize()); + + SetupWindow(ctl); + + return ctl; +} + +bool ctlColourPickerXmlHandler::CanHandle(wxXmlNode *node) +{ + return IsOfClass(node, wxT("ctlColourPicker")); +} diff --git a/ctl/xh_ctlcombo.cpp b/ctl/xh_ctlcombo.cpp new file mode 100644 index 0000000..5fc0025 --- /dev/null +++ b/ctl/xh_ctlcombo.cpp @@ -0,0 +1,33 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// xh_ctlcombo.cpp - ctlComboBox handler +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include "wx/wx.h" +#include "ctl/ctlComboBox.h" +#include "ctl/xh_ctlcombo.h" + +IMPLEMENT_DYNAMIC_CLASS(ctlComboBoxXmlHandler, wxComboBoxXmlHandler) + + +wxObject *ctlComboBoxXmlHandler::DoCreateResource() +{ + ctlComboBox *ctl = new ctlComboBox(m_parentAsWindow, GetID(), GetPosition(), GetSize(), GetStyle()); + + SetupWindow(ctl); + + return ctl; +} + +bool ctlComboBoxXmlHandler::CanHandle(wxXmlNode *node) +{ + return IsOfClass(node, wxT("ctlComboBox")); +} diff --git a/ctl/xh_ctltree.cpp b/ctl/xh_ctltree.cpp new file mode 100644 index 0000000..2efd446 --- /dev/null +++ b/ctl/xh_ctltree.cpp @@ -0,0 +1,35 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// xh_ctltree.cpp - ctlTree handler +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include "wx/wx.h" + +#include "utils/misc.h" +#include "ctl/ctlTree.h" +#include "ctl/xh_ctltree.h" + +IMPLEMENT_DYNAMIC_CLASS(ctlTreeXmlHandler, wxTreeCtrlXmlHandler) + + +wxObject *ctlTreeXmlHandler::DoCreateResource() +{ + ctlTree *ctl = new ctlTree(m_parentAsWindow, GetID(), GetPosition(), GetSize(), GetStyle()); + + SetupWindow(ctl); + + return ctl; +} + +bool ctlTreeXmlHandler::CanHandle(wxXmlNode *node) +{ + return IsOfClass(node, wxT("ctlTree")); +} diff --git a/ctl/xh_sqlbox.cpp b/ctl/xh_sqlbox.cpp new file mode 100644 index 0000000..3d615a9 --- /dev/null +++ b/ctl/xh_sqlbox.cpp @@ -0,0 +1,45 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// xh_sqlbox.cpp - ctlSQLBox handler +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include "wx/wx.h" +#include "ctl/xh_sqlbox.h" +#include "ctl/ctlSQLBox.h" + + +IMPLEMENT_DYNAMIC_CLASS(ctlSQLBoxXmlHandler, wxXmlResourceHandler) + +ctlSQLBoxXmlHandler::ctlSQLBoxXmlHandler() + : wxXmlResourceHandler() +{ + XRC_ADD_STYLE(wxTE_MULTILINE); + XRC_ADD_STYLE(wxSIMPLE_BORDER); + XRC_ADD_STYLE(wxSUNKEN_BORDER); + XRC_ADD_STYLE(wxTE_RICH2); + + AddWindowStyles(); +} + + +wxObject *ctlSQLBoxXmlHandler::DoCreateResource() +{ + ctlSQLBox *sqlbox = new ctlSQLBox(m_parentAsWindow, GetID(), GetPosition(), GetSize(), GetStyle()); + + SetupWindow(sqlbox); + + return sqlbox; +} + +bool ctlSQLBoxXmlHandler::CanHandle(wxXmlNode *node) +{ + return IsOfClass(node, wxT("ctlSQLBox")); +} diff --git a/ctl/xh_timespin.cpp b/ctl/xh_timespin.cpp new file mode 100644 index 0000000..6c1cb3d --- /dev/null +++ b/ctl/xh_timespin.cpp @@ -0,0 +1,49 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// xh_timespin.cpp - wxTimeSpinCtrl handler +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include "wx/wx.h" +#include "ctl/timespin.h" +#include "ctl/xh_timespin.h" + + +IMPLEMENT_DYNAMIC_CLASS(wxTimeSpinXmlHandler, wxXmlResourceHandler) + +wxTimeSpinXmlHandler::wxTimeSpinXmlHandler() + : wxXmlResourceHandler() +{ + XRC_ADD_STYLE(wxSP_WRAP); + XRC_ADD_STYLE(wxSP_ARROW_KEYS); + + AddWindowStyles(); +} + + +wxObject *wxTimeSpinXmlHandler::DoCreateResource() +{ + XRC_MAKE_INSTANCE(timespin, wxTimeSpinCtrl); + + timespin->Create(m_parentAsWindow, + GetID(), + GetPosition(), GetSize(), + GetStyle(), + GetName()); + + SetupWindow(timespin); + + return timespin; +} + +bool wxTimeSpinXmlHandler::CanHandle(wxXmlNode *node) +{ + return IsOfClass(node, wxT("wxTimeSpinCtrl")); +} diff --git a/db/keywords.c b/db/keywords.c new file mode 100644 index 0000000..f9adb83 --- /dev/null +++ b/db/keywords.c @@ -0,0 +1,152 @@ +/*------------------------------------------------------------------------- + * + * keywords.c + * lexical token lookup for reserved words in PostgreSQL + * + * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.177 2006/10/07 21:51:02 petere Exp $ + * + *------------------------------------------------------------------------- + */ + +/////////////////////////////////////////////////////////////////////////// +// +// pgAdmin note: This file is based on src/backend/parser/keywords.c and +// src/backend/parser/kwlookup.c from PostgreSQL, but extended +// to support EntepriseDB and Greenplum. +// +// This file is under the BSD licence, per PostgreSQL. +/////////////////////////////////////////////////////////////////////////// + +#include "postgres.h" +#include "parser/keywords.h" + +/* + * List of (keyword-name, keyword-token-value) pairs. + */ +#define PG_KEYWORD(a,b,c) {a,c}, +const ScanKeyword ScanKeywords[] = { +#include +}; +const int NumScanKeywords = lengthof(ScanKeywords); + +/* + * Additional pairs here. They need to live in a separate array since + * the ScanKeywords array needs to be sorted! + * + * !!WARNING!!: This list must be sorted, because binary + * search is used to locate entries. + */ +#define PG_KEYWORD2(a,b) {a,b}, +const ScanKeyword ScanKeywordsExtra[] = { + PG_KEYWORD2("connect", RESERVED_KEYWORD) + PG_KEYWORD2("convert", RESERVED_KEYWORD) + PG_KEYWORD2("distributed", UNRESERVED_KEYWORD) + PG_KEYWORD2("exec", RESERVED_KEYWORD) + PG_KEYWORD2("log", UNRESERVED_KEYWORD) + PG_KEYWORD2("long", RESERVED_KEYWORD) + PG_KEYWORD2("minus", RESERVED_KEYWORD) + PG_KEYWORD2("nocache", RESERVED_KEYWORD) + PG_KEYWORD2("number", RESERVED_KEYWORD) + PG_KEYWORD2("package", RESERVED_KEYWORD) + PG_KEYWORD2("pls_integer", RESERVED_KEYWORD) + PG_KEYWORD2("raw", RESERVED_KEYWORD) + PG_KEYWORD2("return", RESERVED_KEYWORD) + PG_KEYWORD2("smalldatetime", RESERVED_KEYWORD) + PG_KEYWORD2("smallfloat", RESERVED_KEYWORD) + PG_KEYWORD2("smallmoney", RESERVED_KEYWORD) + PG_KEYWORD2("sysdate", RESERVED_KEYWORD) + PG_KEYWORD2("systimestap", RESERVED_KEYWORD) + PG_KEYWORD2("tinyint", RESERVED_KEYWORD) + PG_KEYWORD2("tinytext", RESERVED_KEYWORD) + PG_KEYWORD2("varchar2", RESERVED_KEYWORD) +}; +const int NumScanKeywordsExtra = lengthof(ScanKeywordsExtra); + +/* + * ScanKeywordLookup - see if a given word is a keyword + * + * Returns a pointer to the ScanKeyword table entry, or NULL if no match. + * + * The match is done case-insensitively. Note that we deliberately use a + * dumbed-down case conversion that will only translate 'A'-'Z' into 'a'-'z', + * even if we are in a locale where tolower() would produce more or different + * translations. This is to conform to the SQL99 spec, which says that + * keywords are to be matched in this way even though non-keyword identifiers + * receive a different case-normalization mapping. + */ +const ScanKeyword * +ScanKeywordLookup(const char *text) +{ + int len, + i; + char word[NAMEDATALEN]; + const ScanKeyword *low; + const ScanKeyword *high; + + len = strlen(text); + /* We assume all keywords are shorter than NAMEDATALEN. */ + if (len >= NAMEDATALEN) + return NULL; + + /* + * Apply an ASCII-only downcasing. We must not use tolower() since it may + * produce the wrong translation in some locales (eg, Turkish). + */ + for (i = 0; i < len; i++) + { + char ch = text[i]; + + if (ch >= 'A' && ch <= 'Z') + ch += 'a' - 'A'; + word[i] = ch; + } + word[len] = '\0'; + + /* + * Now do a binary search using plain strcmp() comparison. + */ + low = &ScanKeywords[0]; + high = endof(ScanKeywords) - 1; + while (low <= high) + { + const ScanKeyword *middle; + int difference; + + middle = low + (high - low) / 2; + difference = strcmp(middle->name, word); + if (difference == 0) + return middle; + else if (difference < 0) + low = middle + 1; + else + high = middle - 1; + } + + /* + * If not found, also do a binary search in the list of extra + * keywords. + */ + low = &ScanKeywordsExtra[0]; + high = endof(ScanKeywordsExtra) - 1; + while (low <= high) + { + const ScanKeyword *middle; + int difference; + + middle = low + (high - low) / 2; + difference = strcmp(middle->name, word); + if (difference == 0) + return middle; + else if (difference < 0) + low = middle + 1; + else + high = middle - 1; + } + + return NULL; +} diff --git a/db/module.mk b/db/module.mk new file mode 100644 index 0000000..84324ba --- /dev/null +++ b/db/module.mk @@ -0,0 +1,20 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/db/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + db/keywords.c \ + db/pgConn.cpp \ + db/pgSet.cpp \ + db/pgQueryThread.cpp + +EXTRA_DIST += \ + db/module.mk + diff --git a/db/pgConn.cpp b/db/pgConn.cpp new file mode 100644 index 0000000..2ca7caf --- /dev/null +++ b/db/pgConn.cpp @@ -0,0 +1,1334 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgConn.cpp - PostgreSQL Connection class +// +///////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// PostgreSQL headers +#include +#include "utils/pgfeatures.h" + +// Network headers +#ifdef __WXMSW__ +#include +typedef u_long in_addr_t; + +#else + +#include +#include +#include + +#ifndef INADDR_NONE +#define INADDR_NONE (-1) +#endif + +#endif + +// App headers +#include "utils/misc.h" +#include "utils/sysLogger.h" +#include "db/pgConn.h" +#include "utils/misc.h" +#include "db/pgSet.h" + +double pgConn::libpqVersion = 8.0; + +static void pgNoticeProcessor(void *arg, const char *message) +{ + ((pgConn *)arg)->Notice(message); +} + +pgConn::pgConn(const wxString &server, const wxString &service, const wxString &hostaddr, const wxString &database, const wxString &username, const wxString &password, + int port, const wxString &rolename, int sslmode, OID oid, const wxString &applicationname, + const wxString &sslcert, const wxString &sslkey, const wxString &sslrootcert, const wxString &sslcrl, + const bool sslcompression) : m_cancelConn(NULL) +{ + wxString msg; + + save_server = server; + save_hostaddr = hostaddr; + save_service = service; + save_database = database; + save_username = username; + save_password = password; + save_port = port; + save_rolename = rolename; + save_sslmode = sslmode; + save_oid = oid; + save_applicationname = applicationname; + save_sslcert = sslcert; + save_sslkey = sslkey; + save_sslrootcert = sslrootcert; + save_sslcrl = sslcrl; + save_sslcompression = sslcompression; + + memset(features, 0, sizeof(features)); + majorVersion = 0; + + conv = &wxConvLibc; + needColQuoting = false; + utfConnectString = false; + + // Check the hostname/ipaddress + conn = 0; + noticeArg = 0; + connStatus = PGCONN_BAD; + + // Create the connection string + if (!server.IsEmpty()) + { + connstr.Append(wxT(" host=")); + connstr.Append(qtConnString(server)); + } + if (!hostaddr.IsEmpty()) + { + connstr.Append(wxT(" hostaddr=")); + connstr.Append(qtConnString(hostaddr)); + } + if (!service.IsEmpty()) + { + connstr.Append(wxT(" service=")); + connstr.Append(qtConnString(service)); + } + if (!database.IsEmpty()) + { + connstr.Append(wxT(" dbname=")); + connstr.Append(qtConnString(database)); + } + if (!username.IsEmpty()) + { + connstr.Append(wxT(" user=")); + connstr.Append(qtConnString(username)); + } + if (!password.IsEmpty()) + { + connstr.Append(wxT(" password=")); + connstr.Append(qtConnString(password)); + } + + if (port > 0) + { + connstr.Append(wxT(" port=")); + connstr.Append(NumToStr((long)port)); + } + + if (libpqVersion > 7.3) + { + switch (sslmode) + { + case 1: + connstr.Append(wxT(" sslmode=require")); + break; + case 2: + connstr.Append(wxT(" sslmode=prefer")); + break; + case 3: + connstr.Append(wxT(" sslmode=allow")); + break; + case 4: + connstr.Append(wxT(" sslmode=disable")); + break; + case 5: + connstr.Append(wxT(" sslmode=verify-ca")); + break; + case 6: + connstr.Append(wxT(" sslmode=verify-full")); + break; + } + } + else + { + switch (sslmode) + { + case 1: + connstr.Append(wxT(" requiressl=1")); + break; + case 2: + connstr.Append(wxT(" requiressl=0")); + break; + } + } + + if (libpqVersion > 8.3 && sslmode != 4) + { + if (!sslcert.IsEmpty()) + { + connstr.Append(wxT(" sslcert=")); + connstr.Append(qtConnString(sslcert)); + } + if (!sslkey.IsEmpty()) + { + connstr.Append(wxT(" sslkey=")); + connstr.Append(qtConnString(sslkey)); + } + if (!sslrootcert.IsEmpty()) + { + connstr.Append(wxT(" sslrootcert=")); + connstr.Append(qtConnString(sslrootcert)); + } + if (!sslcrl.IsEmpty()) + { + connstr.Append(wxT(" sslcrl=")); + connstr.Append(qtConnString(sslcrl)); + } + } + + if (libpqVersion > 9.1 && sslmode != 4) + { + if (!sslcompression) + { + connstr.Append(wxT(" sslcompression=0")); + } + } + + connstr.Trim(false); + + dbHost = server; + dbHostName = server; + dbRole = rolename; + +#ifdef HAVE_CONNINFO_PARSE + if (!applicationname.IsEmpty()) + { + // Check connection string with application_name + char *errmsg; + wxString connstr_with_applicationname = connstr + wxT(" application_name='") + applicationname + wxT("'"); + if (PQconninfoParse(connstr_with_applicationname.mb_str(wxConvUTF8), &errmsg)) + { + connstr = connstr_with_applicationname; + } + else if (PQconninfoParse(connstr_with_applicationname.mb_str(wxConvLibc), &errmsg)) + { + connstr = connstr_with_applicationname; + } + } +#endif + + // Open the connection + wxString cleanConnStr = connstr; + cleanConnStr.Replace(qtConnString(password), wxT("'XXXXXX'")); + wxLogInfo(wxT("Opening connection with connection string: %s"), cleanConnStr.c_str()); + + DoConnect(); +} + + +pgConn::~pgConn() +{ + Close(); +} + + +bool pgConn::DoConnect() +{ + wxCharBuffer cstrUTF = connstr.mb_str(wxConvUTF8); + conn = PQconnectdb(cstrUTF); + if (PQstatus(conn) == CONNECTION_OK) + utfConnectString = true; + else + { + wxCharBuffer cstrLibc = connstr.mb_str(wxConvLibc); + if (strcmp(cstrUTF, cstrLibc)) + { + PQfinish(conn); + conn = PQconnectdb(cstrLibc); + } + } + + if (!Initialize()) + return false; + + return true; +} + + +bool pgConn::Initialize() +{ + // Set client encoding to Unicode/Ascii, Datestyle to ISO, and ask for notices. + if (PQstatus(conn) == CONNECTION_OK) + { + connStatus = PGCONN_OK; + PQsetNoticeProcessor(conn, pgNoticeProcessor, this); + + wxString sql = wxT("SET DateStyle=ISO;\nSET client_min_messages=notice;\n"); + if (BackendMinimumVersion(9, 0)) + sql += wxT("SET bytea_output=escape;\n"); + + sql += wxT("SELECT oid, pg_encoding_to_char(encoding) AS encoding, datlastsysoid\n") + wxT(" FROM pg_database WHERE "); + + if (save_oid) + sql += wxT("oid = ") + NumToStr(save_oid); + else + { + // Note, can't use qtDbString here as we don't know the server version yet. + wxString db = save_database; + db.Replace(wxT("\\"), wxT("\\\\")); + db.Replace(wxT("'"), wxT("''")); + sql += wxT("datname=") + qtString(db); + } + + pgSet *set = ExecuteSet(sql); + if (set) + { + if (set->ColNumber(wxT("\"datlastsysoid\"")) >= 0) + needColQuoting = true; + + lastSystemOID = set->GetOid(wxT("datlastsysoid")); + dbOid = set->GetOid(wxT("oid")); + wxString encoding = set->GetVal(wxT("encoding")); + + if (encoding != wxT("SQL_ASCII") && encoding != wxT("MULE_INTERNAL")) + { + encoding = wxT("UNICODE"); + conv = &wxConvUTF8; + } + else + conv = &wxConvLibc; + + wxLogInfo(wxT("Setting client_encoding to '%s'"), encoding.c_str()); + if (PQsetClientEncoding(conn, encoding.ToAscii())) + { + wxLogError(wxT("%s"), GetLastError().c_str()); + } + + delete set; + + // Switch to the requested default role if supported by backend + if (dbRole != wxEmptyString && BackendMinimumVersion(8, 1)) + { + sql = wxT("SET ROLE TO "); + sql += qtIdent(dbRole); + + pgSet *set = ExecuteSet(sql); + + if (set) + delete set; + else + return false; + } + return true; + } + } + return false; +} + + +void pgConn::Close() +{ + if (conn) + { + CancelExecution(); + PQfinish(conn); + } + conn = 0; + connStatus = PGCONN_BAD; +} + + +// Reconnect to the server +bool pgConn::Reconnect() +{ + // Close the existing (possibly broken) connection + Close(); + + // Reset any vars that need to be in a defined state before connecting + needColQuoting = false; + + // Attempt the reconnect + if (!DoConnect()) + { + wxLogError(_("Failed to re-establish the connection to the server %s"), GetName().c_str()); + return false; + } + + return true; +} + + +pgConn *pgConn::Duplicate(const wxString &_appName) +{ + pgConn *res = new pgConn(wxString(save_server), wxString(save_service), + wxString(save_hostaddr), wxString(save_database), wxString(save_username), + wxString(save_password), save_port, save_rolename, save_sslmode, save_oid, + _appName.IsEmpty() ? save_applicationname : _appName, save_sslcert, save_sslkey, + save_sslrootcert, save_sslcrl, save_sslcompression); + + // Save the version and features information from the existing connection + res->majorVersion = majorVersion; + res->minorVersion = minorVersion; + res->patchVersion = patchVersion; + res->isEdb = isEdb; + res->isGreenplum = isGreenplum; + res->isHawq = isHawq; + res->reservedNamespaces = reservedNamespaces; + + for (size_t index = FEATURE_INITIALIZED; index < FEATURE_LAST; index++) + res->features[index] = features[index]; + + return res; +} + + +// Return the SSL mode name +wxString pgConn::GetSslModeName() +{ + switch (save_sslmode) + { + case 1: + return wxT("require"); + case 2: + return wxT("prefer"); + case 3: + return wxT("allow"); + case 4: + return wxT("disable"); + case 5: + return wxT("verify-ca"); + case 6: + return wxT("verify-full"); + default: + return wxT("prefer"); + } +} + +bool pgConn::GetIsEdb() +{ + // to retrieve edb flag + BackendMinimumVersion(0, 0); + return isEdb; +} + +bool pgConn::GetIsGreenplum() +{ + // to retrieve Greenplum flag + BackendMinimumVersion(0, 0); + return isGreenplum; +} + +bool pgConn::GetIsHawq() +{ + // to retrieve Greenplum HAWQ flag + BackendMinimumVersion(0, 0); + return isHawq; +} + +wxString pgConn::SystemNamespaceRestriction(const wxString &nsp) +{ + if (reservedNamespaces.IsEmpty()) + { + reservedNamespaces = wxT("'information_schema'"); + + if (GetIsEdb()) + reservedNamespaces += wxT(", 'sys'"); + + pgSet *set = ExecuteSet( + wxT("SELECT nspname FROM pg_namespace nsp\n") + wxT(" JOIN pg_proc pr ON pronamespace=nsp.oid\n") + wxT(" WHERE proname IN ('slonyversion')")); + if (set) + { + while (!set->Eof()) + { + reservedNamespaces += wxT(", ") + qtDbString(set->GetVal(wxT("nspname"))); + set->MoveNext(); + } + delete set; + } + } + + if (BackendMinimumVersion(8, 1)) + return wxT("(") + nsp + wxT(" NOT LIKE E'pg\\_%' AND ") + nsp + wxT(" NOT in (") + reservedNamespaces + wxT("))"); + else + return wxT("(") + nsp + wxT(" NOT LIKE 'pg\\_%' AND ") + nsp + wxT(" NOT in (") + reservedNamespaces + wxT("))"); +} + +bool pgConn::HasPrivilege(const wxString &objTyp, const wxString &objName, const wxString &priv) +{ + wxString res = ExecuteScalar( + wxT("SELECT has_") + objTyp.Lower() + + wxT("_privilege(") + qtDbString(objName) + + wxT(", ") + qtDbString(priv) + wxT(")")); + + return StrToBool(res); +} + +bool pgConn::IsSuperuser() +{ + wxString res = ExecuteScalar( + wxT("SELECT rolsuper FROM pg_roles ") + wxT("WHERE rolname='") + qtIdent(GetUser()) + wxT("'")); + + return StrToBool(res); +} + +bool pgConn::BackendMinimumVersion(int major, int minor) +{ + if (GetStatus() != PGCONN_OK) + return false; + if (!majorVersion) + { + wxString version = GetVersionString(); + sscanf(version.ToAscii(), "%*s %d.%d.%d", &majorVersion, &minorVersion, &patchVersion); + isEdb = version.Upper().Matches(wxT("ENTERPRISEDB*")); + if (version.Upper().Matches(wxT("*11BETA*"))) { + majorVersion=11; + minorVersion=0; + } + // EnterpriseDB 8.3 beta 1 & 2 and possibly later actually have PostgreSQL 8.2 style + // catalogs. This is expected to change either before GA, but in the meantime we + // need to check the catalogue version in more detail, and if we don't see what looks + // like a 8.3 catalog, force the version number back to 8.2. Yuck. + if (isEdb && majorVersion == 8 && minorVersion == 3) + { + if (ExecuteScalar(wxT("SELECT count(*) FROM pg_attribute WHERE attname = 'proconfig' AND attrelid = 'pg_proc'::regclass")) == wxT("0")) + minorVersion = 2; + } + + isGreenplum = version.Upper().Matches(wxT("*GREENPLUM DATABASE*")); + isHawq = version.Upper().Matches(wxT("*GREENPLUM DATABASE*")) && version.Upper().Matches(wxT("*HAWQ*"));; + } + + return majorVersion > major || (majorVersion == major && minorVersion >= minor); + +} + + +// Greenplum sometimes adds features in patch releases, because Greenplum +// releases are not coordinated with PostgreSQL minor releases. +bool pgConn::BackendMinimumVersion(int major, int minor, int patch) +{ + if (!majorVersion) + BackendMinimumVersion(0, 0); + + return majorVersion > major || (majorVersion == major && minorVersion > minor) || (majorVersion == major && minorVersion == minor && patchVersion >= patch); + +} + + +bool pgConn::EdbMinimumVersion(int major, int minor) +{ + return BackendMinimumVersion(major, minor) && GetIsEdb(); +} + + +bool pgConn::HasFeature(int featureNo, bool forceCheck) +{ + if (!features[FEATURE_INITIALIZED] || forceCheck) + { + features[FEATURE_INITIALIZED] = true; + + wxString sql = + wxT("SELECT proname, pronargs, proargtypes[0] AS arg0, proargtypes[1] AS arg1, proargtypes[2] AS arg2\n") + wxT(" FROM pg_proc\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE proname IN ('pg_tablespace_size', 'pg_file_read', 'pg_logfile_rotate',") + wxT( " 'pg_postmaster_starttime', 'pg_terminate_backend', 'pg_reload_conf',") + wxT( " 'pgstattuple', 'pgstatindex')\n") + wxT(" AND nspname IN ('pg_catalog', 'public')"); + + pgSet *set = ExecuteSet(sql); + + if (set) + { + while (!set->Eof()) + { + wxString proname = set->GetVal(wxT("proname")); + long pronargs = set->GetLong(wxT("pronargs")); + + if (proname == wxT("pg_tablespace_size") && pronargs == 1 && set->GetLong(wxT("arg0")) == 26) + features[FEATURE_SIZE] = true; + else if (proname == wxT("pg_file_read") && pronargs == 3 && set->GetLong(wxT("arg0")) == 25 + && set->GetLong(wxT("arg1")) == 20 && set->GetLong(wxT("arg2")) == 20) + features[FEATURE_FILEREAD] = true; + else if (proname == wxT("pg_logfile_rotate") && pronargs == 0) + features[FEATURE_ROTATELOG] = true; + else if (proname == wxT("pg_postmaster_starttime") && pronargs == 0) + features[FEATURE_POSTMASTER_STARTTIME] = true; + else if (proname == wxT("pg_terminate_backend") && pronargs == 1 && set->GetLong(wxT("arg0")) == 23) + features[FEATURE_TERMINATE_BACKEND] = true; + else if (proname == wxT("pg_reload_conf") && pronargs == 0) + features[FEATURE_RELOAD_CONF] = true; + else if (proname == wxT("pgstattuple") && pronargs == 1 && set->GetLong(wxT("arg0")) == 25) + features[FEATURE_PGSTATTUPLE] = true; + else if (proname == wxT("pgstatindex") && pronargs == 1 && set->GetLong(wxT("arg0")) == 25) + features[FEATURE_PGSTATINDEX] = true; + + set->MoveNext(); + } + delete set; + } + + // Check for EDB function parameter default support + wxString defCol = wxT("'proargdefaults'"); + + if (EdbMinimumVersion(8, 3) && !EdbMinimumVersion(8, 4)) + defCol = wxT("'proargdefvals'"); + + wxString hasFuncDefs = ExecuteScalar(wxT("SELECT count(*) FROM pg_attribute WHERE attrelid = 'pg_catalog.pg_proc'::regclass AND attname = ") + defCol); + if (hasFuncDefs == wxT("1")) + features[FEATURE_FUNCTION_DEFAULTS] = true; + else + features[FEATURE_FUNCTION_DEFAULTS] = false; + } + + if (featureNo <= FEATURE_INITIALIZED || featureNo >= FEATURE_LAST) + return false; + return features[featureNo]; +} + + +// Encrypt a password using the appropriate encoding conversion +wxString pgConn::EncryptPassword(const wxString &user, const wxString &password) +{ + char *chrPassword; + wxString strPassword; + + chrPassword = PQencryptPassword(password.mb_str(*conv), user.mb_str(*conv)); + strPassword = wxString::FromAscii(chrPassword); + + PQfreemem(chrPassword); + + return strPassword; +} + +wxString pgConn::qtDbString(const wxString &value) +{ + wxString result = value; + + result.Replace(wxT("\\"), wxT("\\\\")); + result.Replace(wxT("'"), wxT("''")); + result.Append(wxT("'")); + + if (BackendMinimumVersion(8, 1)) + { + if (result.Contains(wxT("\\"))) + result.Prepend(wxT("E'")); + else + result.Prepend(wxT("'")); + } + else + result.Prepend(wxT("'")); + + return result; +} + +void pgConn::ExamineLibpqVersion() +{ + libpqVersion = 7.3; + PQconninfoOption *cio = PQconndefaults(); + + if (cio) + { + PQconninfoOption *co = cio; + while (co->keyword) + { + if (!strcmp(co->keyword, "sslmode")) + { + if (libpqVersion < 7.4) + libpqVersion = 7.4; + } + if (!strcmp(co->keyword, "sslrootcert")) + { + if (libpqVersion < 8.4) + libpqVersion = 8.4; + } + if (!strcmp(co->keyword, "sslcompression")) + { + if (libpqVersion < 9.2) + libpqVersion = 9.2; + } + co++; + } + PQconninfoFree(cio); + } +} + +wxString pgConn::GetName() const +{ + wxString str; + if (save_service.IsEmpty()) + { + if (dbHost.IsEmpty()) + str.Printf(_("%s on local socket"), save_database.c_str()); + else + str.Printf(_("%s on %s@%s:%d"), save_database.c_str(), GetUser().c_str(), dbHost.c_str(), GetPort()); + } + else + str.Printf(_("service %s"), save_service.c_str()); + + + return str; +} + +#ifdef PG_SSL +// we don't define USE_SSL so we don't get ssl.h included +extern "C" +{ + extern void *PQgetssl(PGconn *conn); +} + +bool pgConn::IsSSLconnected() +{ + return (conn && PQstatus(conn) == CONNECTION_OK && PQgetssl(conn) != NULL); +} +#else + +bool pgConn::IsSSLconnected() +{ + return false ; +} +#endif + + +void pgConn::RegisterNoticeProcessor(PQnoticeProcessor proc, void *arg) +{ + noticeArg = arg; + noticeProc = proc; +} + + + + +void pgConn::Notice(const char *msg) +{ + if (noticeArg && noticeProc) + (*noticeProc)(noticeArg, msg); + else + { + wxString str(msg, *conv); + + // Display the notice if required + if (settings->GetShowNotices()) + wxMessageBox(str, _("Notice"), wxICON_INFORMATION | wxOK); + + wxLogNotice(wxT("%s"), str.Trim().c_str()); + } +} + + +pgNotification *pgConn::GetNotification() +{ + pgNotify *notify; + + notify = PQnotifies(conn); + if (!notify) + return NULL; + + pgNotification *ret = new pgNotification; + ret->name = wxString(notify->relname, *conv); + ret->pid = notify->be_pid; + ret->data = wxString(notify->extra, *conv); + + return ret; +} + +int pgConn::GetTxStatus() +{ + return PQtransactionStatus(conn); +} + +////////////////////////////////////////////////////////////////////////// +// Execute SQL +////////////////////////////////////////////////////////////////////////// + +bool pgConn::ExecuteVoid(const wxString &sql, bool reportError) +{ + if (GetStatus() != PGCONN_OK) + return false; + + // Execute the query and get the status. + PGresult *qryRes; + + wxLogSql(wxT("Void query (%s:%d): %s"), this->GetHost().c_str(), this->GetPort(), sql.c_str()); + + SetConnCancel(); + qryRes = PQexec(conn, sql.mb_str(*conv)); + ResetConnCancel(); + + lastResultStatus = PQresultStatus(qryRes); + SetLastResultError(qryRes); + + // Check for errors + if (lastResultStatus != PGRES_TUPLES_OK && + lastResultStatus != PGRES_COMMAND_OK) + { + LogError(!reportError); + PQclear(qryRes); + return false; + } + + // Cleanup & exit + PQclear(qryRes); + return true; +} + + + +wxString pgConn::ExecuteScalar(const wxString &sql, bool reportError) +{ + wxString result; + + if (GetStatus() == PGCONN_OK) + { + // Execute the query and get the status. + PGresult *qryRes; + wxLogSql(wxT("Scalar query (%s:%d): %s"), this->GetHost().c_str(), this->GetPort(), sql.c_str()); + + SetConnCancel(); + qryRes = PQexec(conn, sql.mb_str(*conv)); + ResetConnCancel(); + + lastResultStatus = PQresultStatus(qryRes); + SetLastResultError(qryRes); + + // Check for errors + if (lastResultStatus != PGRES_TUPLES_OK && lastResultStatus != PGRES_COMMAND_OK) + { + LogError(!reportError); + PQclear(qryRes); + return wxEmptyString; + } + + // Check for a returned row + if (PQntuples(qryRes) < 1) + { + wxLogInfo(wxT("Query returned no tuples")); + PQclear(qryRes); + return wxEmptyString; + } + + // Retrieve the query result and return it. + result = wxString(PQgetvalue(qryRes, 0, 0), *conv); + + wxLogSql(wxT("Query result: %s"), result.c_str()); + + // Cleanup & exit + PQclear(qryRes); + } + + return result; +} + +pgSet *pgConn::ExecuteSet(const wxString &sql, bool reportError) +{ + // Execute the query and get the status. + if (GetStatus() == PGCONN_OK) + { + PGresult *qryRes; + wxLogSql(wxT("Set query (%s:%d): %s"), this->GetHost().c_str(), this->GetPort(), sql.c_str()); + + SetConnCancel(); + qryRes = PQexec(conn, sql.mb_str(*conv)); + ResetConnCancel(); + + lastResultStatus = PQresultStatus(qryRes); + SetLastResultError(qryRes); + + if (lastResultStatus == PGRES_TUPLES_OK || lastResultStatus == PGRES_COMMAND_OK) + { + pgSet *set = new pgSet(qryRes, this, *conv, needColQuoting); + if (!set) + { + if (reportError) + wxLogError(_("Couldn't create a pgSet object!")); + else + wxLogQuietError(_("Couldn't create a pgSet object!")); + PQclear(qryRes); + } + return set; + } + else + { + LogError(!reportError); + PQclear(qryRes); + } + } + return new pgSet(); +} + +////////////////////////////////////////////////////////////////////////// +// COPY functions +////////////////////////////////////////////////////////////////////////// + +bool pgConn::StartCopy(const wxString query) +{ + if (GetStatus() != PGCONN_OK) + return false; + + // Execute the query and get the status + PGresult *qryRes; + + wxLogSql(wxT("COPY query (%s:%d): %s"), this->GetHost().c_str(), this->GetPort(), query.c_str()); + qryRes = PQexec(conn, query.mb_str(*conv)); + lastResultStatus = PQresultStatus(qryRes); + SetLastResultError(qryRes); + + // Check for errors + if (lastResultStatus != PGRES_COPY_IN) + { + LogError(false); + PQclear(qryRes); + return false; + } + + // NO cleanup & exit + return true; +} + +bool pgConn::PutCopyData(const char *data, long count) +{ + // Execute the query and get the status + int result = PQputCopyData(conn, data, count); + + return result == 1; +} + +bool pgConn::EndPutCopy(const wxString errormsg) +{ + int result; + + // Execute the query and get the status + if (errormsg.Length() == 0) + result = PQputCopyEnd(conn, NULL); + else + result = PQputCopyEnd(conn, errormsg.mb_str(*conv)); + + return result == 1; +} + +bool pgConn::GetCopyFinalStatus(void) +{ + PGresult *qryRes; + + // Get status + qryRes = PQgetResult(conn); + lastResultStatus = PQresultStatus(qryRes); + + // Check for errors + if (lastResultStatus != PGRES_COMMAND_OK) + { + LogError(false); + PQclear(qryRes); + return false; + } + + // Cleanup & exit + PQclear(qryRes); + return true; +} + +////////////////////////////////////////////////////////////////////////// +// Info +////////////////////////////////////////////////////////////////////////// + +wxString pgConn::GetLastError() const +{ + wxString errmsg; + char *pqErr; + if (conn && (pqErr = PQerrorMessage(conn)) != 0) + { + errmsg = wxString(pqErr, wxConvUTF8); + if (errmsg.IsNull()) + errmsg = wxString(pqErr, wxConvLibc); + } + else + { + if (connStatus == PGCONN_BROKEN) + errmsg = _("Connection to database broken."); + else + errmsg = _("No connection to database."); + } + return errmsg; +} + + + +void pgConn::LogError(const bool quiet) +{ + if (conn) + { + if (quiet) + { + wxLogQuietError(wxT("%s"), GetLastError().Trim().c_str()); + } + else + { + wxLogError(wxT("%s"), GetLastError().Trim().c_str()); + IsAlive(); + } + } +} + + + +bool pgConn::IsAlive() +{ + if (GetStatus() != PGCONN_OK) + { + if (conn) + { + PQfinish(conn); + conn = 0; + connStatus = PGCONN_BROKEN; + } + return false; + } + + PGresult *qryRes = PQexec(conn, "SELECT 1;"); + lastResultStatus = PQresultStatus(qryRes); + if (lastResultStatus != PGRES_TUPLES_OK) + { + PQclear(qryRes); + qryRes = PQexec(conn, "ROLLBACK TRANSACTION; SELECT 1;"); + lastResultStatus = PQresultStatus(qryRes); + SetLastResultError(qryRes); + } + PQclear(qryRes); + + // Check for errors + if (lastResultStatus != PGRES_TUPLES_OK) + { + PQfinish(conn); + conn = 0; + connStatus = PGCONN_BROKEN; + return false; + } + + return true; +} + + +int pgConn::GetStatus() const +{ + if (!this) + return PGCONN_BAD; + + if (conn) + ((pgConn *)this)->connStatus = PQstatus(conn); + + return connStatus; +} + + +void pgConn::Reset() +{ + PQreset(conn); + + // Reset any vars that need to be in a defined state before connecting + needColQuoting = false; + + Initialize(); +} + + +void pgConn::SetConnCancel(void) +{ + wxMutexLocker lock(m_cancelConnMutex); + PGcancel *oldCancelConn = m_cancelConn; + + m_cancelConn = NULL; + + if (oldCancelConn != NULL) + PQfreeCancel(oldCancelConn); + + if (!conn) + return; + + m_cancelConn = PQgetCancel(conn); + +} + + +void pgConn::ResetConnCancel(void) +{ + wxMutexLocker lock(m_cancelConnMutex); + PGcancel *oldCancelConn = m_cancelConn; + + m_cancelConn = NULL; + + if (oldCancelConn != NULL) + PQfreeCancel(oldCancelConn); +} + + +void pgConn::CancelExecution(void) +{ + char errbuf[256]; + wxMutexLocker lock(m_cancelConnMutex); + + if (m_cancelConn) + { + PGcancel *cancelConn = m_cancelConn; + m_cancelConn = NULL; + + if (PQcancel(cancelConn, errbuf, sizeof(errbuf))) + { + SetLastResultError(NULL, wxT("Cancel request sent")); + } + else + { + SetLastResultError(NULL, wxString::Format(wxT("Could not send cancel request:\n%s"), errbuf)); + } + PQfreeCancel(cancelConn); + } +} + + +wxString pgConn::GetVersionString() +{ + return ExecuteScalar(wxT("SELECT version();")); +} + +void pgConn::SetLastResultError(PGresult *res, const wxString &msg) +{ + if (res) + { + lastResultError.severity = wxString(PQresultErrorField(res, PG_DIAG_SEVERITY), *conv); + lastResultError.sql_state = wxString(PQresultErrorField(res, PG_DIAG_SQLSTATE), *conv); + lastResultError.msg_primary = wxString(PQresultErrorField(res, PG_DIAG_MESSAGE_PRIMARY), *conv); + lastResultError.msg_detail = wxString(PQresultErrorField(res, PG_DIAG_MESSAGE_DETAIL), *conv); + lastResultError.msg_hint = wxString(PQresultErrorField(res, PG_DIAG_MESSAGE_HINT), *conv); + lastResultError.statement_pos = wxString(PQresultErrorField(res, PG_DIAG_STATEMENT_POSITION), *conv); + lastResultError.internal_pos = wxString(PQresultErrorField(res, PG_DIAG_INTERNAL_POSITION), *conv); + lastResultError.internal_query = wxString(PQresultErrorField(res, PG_DIAG_INTERNAL_QUERY), *conv); + lastResultError.context = wxString(PQresultErrorField(res, PG_DIAG_CONTEXT), *conv); + lastResultError.source_file = wxString(PQresultErrorField(res, PG_DIAG_SOURCE_FILE), *conv); + lastResultError.source_line = wxString(PQresultErrorField(res, PG_DIAG_SOURCE_LINE), *conv); + lastResultError.source_function = wxString(PQresultErrorField(res, PG_DIAG_SOURCE_FUNCTION), *conv); + } + else + { + lastResultError.severity = wxEmptyString; + lastResultError.sql_state = wxEmptyString; + if (msg.IsEmpty()) + lastResultError.msg_primary = GetLastError(); + else + lastResultError.msg_primary = msg; + lastResultError.msg_detail = wxEmptyString; + lastResultError.msg_hint = wxEmptyString; + lastResultError.statement_pos = wxEmptyString; + lastResultError.internal_pos = wxEmptyString; + lastResultError.internal_query = wxEmptyString; + lastResultError.context = wxEmptyString; + lastResultError.source_file = wxEmptyString; + lastResultError.source_line = wxEmptyString; + lastResultError.source_function = wxEmptyString; + } + + wxString errMsg; + + if (lastResultError.severity != wxEmptyString && lastResultError.msg_primary != wxEmptyString) + errMsg = lastResultError.severity + wxT(": ") + lastResultError.msg_primary; + else if (lastResultError.msg_primary != wxEmptyString) + errMsg = lastResultError.msg_primary; + + if (!lastResultError.sql_state.IsEmpty()) + { + if (!errMsg.EndsWith(wxT("\n"))) + errMsg += wxT("\n"); + errMsg += _("SQL state: "); + errMsg += lastResultError.sql_state; + } + + if (!lastResultError.msg_detail.IsEmpty()) + { + if (!errMsg.EndsWith(wxT("\n"))) + errMsg += wxT("\n"); + errMsg += _("Detail: "); + errMsg += lastResultError.msg_detail; + } + + if (!lastResultError.msg_hint.IsEmpty()) + { + if (!errMsg.EndsWith(wxT("\n"))) + errMsg += wxT("\n"); + errMsg += _("Hint: "); + errMsg += lastResultError.msg_hint; + } + + if (!lastResultError.statement_pos.IsEmpty()) + { + if (!errMsg.EndsWith(wxT("\n"))) + errMsg += wxT("\n"); + errMsg += _("Character: "); + errMsg += lastResultError.statement_pos; + } + + if (!lastResultError.context.IsEmpty()) + { + if (!errMsg.EndsWith(wxT("\n"))) + errMsg += wxT("\n"); + errMsg += _("Context: "); + errMsg += lastResultError.context; + } + lastResultError.formatted_msg = errMsg; +} + +// String quoting - only for use during the connection phase!! +wxString pgConn::qtString(const wxString &value) +{ + wxString result = value; + + result.Replace(wxT("\\"), wxT("\\\\")); + result.Replace(wxT("'"), wxT("\\'")); + result.Append(wxT("'")); + result.Prepend(wxT("'")); + + return result; +} + +// Check if, TABLE (tblname) has column with name colname +bool pgConn::TableHasColumn(wxString schemaname, wxString tblname, const wxString &colname) +{ + // + // SELECT a.attname + // FROM pg_catalog.pg_attribute a + // WHERE a.attrelid = (SELECT c.oid + // FROM pg_catalog.pg_class c + // LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace + // WHERE c.relname ~ '^(TABLENAME)$' AND + // pg_catalog.pg_table_is_visible(c.oid) AND + // n.nspname ~ '^(SCHEMANAME)$') AND + // a.attnum > 0 AND NOT a.attisdropped + // ORDER BY a.attnum + // + + if (tblname.IsEmpty() || colname.IsEmpty()) + return false; + + if (schemaname.IsEmpty()) + schemaname = wxT("public"); + + if (this && GetStatus() == PGCONN_OK) + { + tblname.Replace(wxT("\\"), wxT("\\\\")); + tblname.Replace(wxT("'"), wxT("''")); + schemaname.Replace(wxT("\\"), wxT("\\\\")); + schemaname.Replace(wxT("'"), wxT("''")); + + wxString sql + = wxT("SELECT a.attname AS colname FROM pg_catalog.pg_attribute a ") \ + wxT("WHERE a.attrelid = (SELECT c.oid FROM pg_catalog.pg_class c ") \ + wxT(" LEFT JOIN pg_catalog.pg_namespace n ON ") \ + wxT(" n.oid = c.relnamespace ") \ + wxT(" WHERE c.relname ~ '^(") + tblname + wxT(")$' AND ") \ + wxT(" n.nspname ~ '^(") + schemaname + wxT(")$') AND ") \ + wxT(" a.attnum > 0 AND NOT a.attisdropped ") \ + wxT("ORDER BY a.attnum"); + + pgSet *set = ExecuteSet(sql); + if (set) + { + while (!set->Eof()) + { + if (set->GetVal(wxT("colname")) == colname) + { + delete set; + return true; + } + set->MoveNext(); + } + } + delete set; + } + + return false; +} + +void pgError::SetError(PGresult *_res, wxMBConv *_conv) +{ + if (!_conv) + { + _conv = &wxConvLibc; + } + if (_res) + { + msg_primary = wxString(PQresultErrorField(_res, PG_DIAG_MESSAGE_PRIMARY), *_conv); + severity = wxString(PQresultErrorField(_res, PG_DIAG_SEVERITY), *_conv); + sql_state = wxString(PQresultErrorField(_res, PG_DIAG_SQLSTATE), *_conv); + msg_detail = wxString(PQresultErrorField(_res, PG_DIAG_MESSAGE_DETAIL), *_conv); + msg_hint = wxString(PQresultErrorField(_res, PG_DIAG_MESSAGE_HINT), *_conv); + statement_pos = wxString(PQresultErrorField(_res, PG_DIAG_STATEMENT_POSITION), *_conv); + internal_pos = wxString(PQresultErrorField(_res, PG_DIAG_INTERNAL_POSITION), *_conv); + internal_query = wxString(PQresultErrorField(_res, PG_DIAG_INTERNAL_QUERY), *_conv); + context = wxString(PQresultErrorField(_res, PG_DIAG_CONTEXT), *_conv); + source_file = wxString(PQresultErrorField(_res, PG_DIAG_SOURCE_FILE), *_conv); + source_line = wxString(PQresultErrorField(_res, PG_DIAG_SOURCE_LINE), *_conv); + source_function = wxString(PQresultErrorField(_res, PG_DIAG_SOURCE_FUNCTION), *_conv); + } + else + { + msg_primary = wxEmptyString; + severity = wxEmptyString; + sql_state = wxEmptyString; + msg_detail = wxEmptyString; + msg_hint = wxEmptyString; + statement_pos = wxEmptyString; + internal_pos = wxEmptyString; + internal_query = wxEmptyString; + context = wxEmptyString; + source_file = wxEmptyString; + source_line = wxEmptyString; + source_function = wxEmptyString; + } + + wxString errMsg; + + if (severity != wxEmptyString && msg_primary != wxEmptyString) + errMsg = severity + wxT(": ") + msg_primary; + else if (msg_primary != wxEmptyString) + errMsg = msg_primary; + + if (!sql_state.IsEmpty()) + { + if (!errMsg.EndsWith(wxT("\n"))) + errMsg += wxT("\n"); + errMsg += _("SQL state: "); + errMsg += sql_state; + } + + if (!msg_detail.IsEmpty()) + { + if (!errMsg.EndsWith(wxT("\n"))) + errMsg += wxT("\n"); + errMsg += _("Detail: "); + errMsg += msg_detail; + } + + if (!msg_hint.IsEmpty()) + { + if (!errMsg.EndsWith(wxT("\n"))) + errMsg += wxT("\n"); + errMsg += _("Hint: "); + errMsg += msg_hint; + } + + if (!statement_pos.IsEmpty()) + { + if (!errMsg.EndsWith(wxT("\n"))) + errMsg += wxT("\n"); + errMsg += _("Character: "); + errMsg += statement_pos; + } + + if (!context.IsEmpty()) + { + if (!errMsg.EndsWith(wxT("\n"))) + errMsg += wxT("\n"); + errMsg += _("Context: "); + errMsg += context; + } + formatted_msg = errMsg; +} diff --git a/db/pgQueryThread.cpp b/db/pgQueryThread.cpp new file mode 100644 index 0000000..656609c --- /dev/null +++ b/db/pgQueryThread.cpp @@ -0,0 +1,901 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgQueryThread.cpp - PostgreSQL threaded query class +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// PostgreSQL headers +#include + +// App headers +#include "db/pgSet.h" +#include "db/pgConn.h" +#include "db/pgQueryThread.h" +#include "db/pgQueryResultEvent.h" +#include "utils/pgDefs.h" +#include "utils/sysLogger.h" + +const wxEventType PGQueryResultEvent = wxNewEventType(); + +// default notice processor for the pgQueryThread +// we do assume that the argument passed will be always the +// object of pgQueryThread +void pgNoticeProcessor(void *_arg, const char *_message) +{ + wxString str(_message, wxConvUTF8); + + wxLogNotice(wxT("%s"), str.Trim().c_str()); + if (_arg) + { + ((pgQueryThread *)_arg)->AppendMessage(str); + } +} + + +// support for multiple queries support +pgQueryThread::pgQueryThread(pgConn *_conn, wxEvtHandler *_caller, + PQnoticeProcessor _processor, void *_noticeHandler) : + wxThread(wxTHREAD_JOINABLE), m_currIndex(-1), m_conn(_conn), + m_cancelled(false), m_multiQueries(true), m_useCallable(false), + m_caller(_caller), m_processor(pgNoticeProcessor), m_noticeHandler(NULL), + m_eventOnCancellation(true) +{ + // check if we can really use the enterprisedb callable statement and + // required +#ifdef __WXMSW__ + if (PQiGetOutResult && PQiPrepareOut && PQiSendQueryPreparedOut) + { + // we do not need all of pqi stuff as90 onwards + if (m_conn && m_conn->conn && m_conn->GetIsEdb() + && !m_conn->EdbMinimumVersion(9, 0)) + { + m_useCallable = true; + } + } +#else // __WXMSW__ +#ifdef EDB_LIBPQ + // use callable statement only with enterprisedb advanced servers + // we do not need all of pqi stuff as90 onwards + if (m_conn && m_conn->conn && m_conn->GetIsEdb() + && !m_conn->EdbMinimumVersion(9, 0)) + { + m_useCallable = true; + } +#endif // EDB_LIBPQ +#endif // __WXMSW__ + + if (m_conn && m_conn->conn) + { + PQsetnonblocking(m_conn->conn, 1); + } + + if (_processor != NULL) + { + m_processor = _processor; + if (_noticeHandler) + m_noticeHandler = _noticeHandler; + else + m_noticeHandler = (void *)this; + } + else + { + m_noticeHandler = (void *)this; + } +} + +pgQueryThread::pgQueryThread(pgConn *_conn, const wxString &_qry, + int _resultToRetrieve, wxWindow *_caller, long _eventId, void *_data) + : wxThread(wxTHREAD_JOINABLE), m_currIndex(-1), m_conn(_conn), + m_cancelled(false), m_multiQueries(false), m_useCallable(false), + m_caller(NULL), m_processor(pgNoticeProcessor), m_noticeHandler(NULL), + m_eventOnCancellation(true) +{ + if (m_conn && m_conn->conn) + { + PQsetnonblocking(m_conn->conn, 1); + } + m_queries.Add( + new pgBatchQuery(_qry, (pgParamsArray *)NULL, _eventId, _data, false, + _resultToRetrieve)); + + wxLogInfo(wxT("queueing : %s"), _qry.c_str()); + m_noticeHandler = (void *)this; + + if (_caller) + { + m_caller = _caller->GetEventHandler(); + } +} + +void pgQueryThread::SetEventOnCancellation(bool eventOnCancelled) +{ + m_eventOnCancellation = eventOnCancelled; +} + +void pgQueryThread::AddQuery(const wxString &_qry, pgParamsArray *_params, + long _eventId, void *_data, bool _useCallable, int _resultToRetrieve) +{ + m_queries.Add( + new pgBatchQuery(_qry, _params, _eventId, _data, + // use callable statement only if supported + m_useCallable && _useCallable, _resultToRetrieve)); + + wxLogInfo(wxT("queueing (%ld): %s"), GetId(), _qry.c_str()); +} + + +pgQueryThread::~pgQueryThread() +{ + m_conn->RegisterNoticeProcessor(0, 0); + WX_CLEAR_ARRAY(m_queries); +} + + +wxString pgQueryThread::GetMessagesAndClear(int idx) +{ + wxString msg; + + if (idx == -1) + idx = m_currIndex; + + if (idx >= 0 && idx <= m_currIndex) + { + wxCriticalSectionLocker lock(m_criticalSection); + msg = m_queries[idx]->m_message; + m_queries[idx]->m_message = wxT(""); + } + + return msg; +} + + +void pgQueryThread::AppendMessage(const wxString &str) +{ + if (m_queries[m_currIndex]->m_message.IsEmpty()) + { + wxCriticalSectionLocker lock(m_criticalSection); + if (str != wxT("\n")) + m_queries[m_currIndex]->m_message.Append(str); + } + else + { + wxCriticalSectionLocker lock(m_criticalSection); + m_queries[m_currIndex]->m_message.Append(wxT("\n")).Append(str); + } +} + + +int pgQueryThread::Execute() +{ + wxMutexLocker lock(m_queriesLock); + + PGresult *result = NULL; + wxMBConv &conv = *(m_conn->conv); + + wxString &query = m_queries[m_currIndex]->m_query; + int &resultToRetrieve = m_queries[m_currIndex]->m_resToRetrieve; + long &rowsInserted = m_queries[m_currIndex]->m_rowsInserted; + Oid &insertedOid = m_queries[m_currIndex]->m_insertedOid; + // using the alias for the pointer here, in order to save the result back + // in the pgBatchQuery object + pgSet *&dataSet = m_queries[m_currIndex]->m_resultSet; + int &rc = m_queries[m_currIndex]->m_returnCode; + pgParamsArray *params = m_queries[m_currIndex]->m_params; + bool useCallable = m_queries[m_currIndex]->m_useCallable; + pgError &err = m_queries[m_currIndex]->m_err; + + wxCharBuffer queryBuf = query.mb_str(conv); + + if (PQstatus(m_conn->conn) != CONNECTION_OK) + { + rc = pgQueryResultEvent::PGQ_CONN_LOST; + err.msg_primary = _("Connection to the database server lost"); + + return(RaiseEvent(rc)); + } + + if (!queryBuf && !query.IsEmpty()) + { + rc = pgQueryResultEvent::PGQ_STRING_INVALID; + m_conn->SetLastResultError(NULL, _("the query could not be converted to the required encoding.")); + err.msg_primary = _("Query string is empty"); + + return(RaiseEvent(rc)); + } + + // Honour the parameters (if any) + if (params && params->GetCount() > 0) + { + int pCount = params->GetCount(); + int ret = 0, + idx = 0; + + Oid *pOids = (Oid *)malloc(pCount * sizeof(Oid)); + const char **pParams = (const char **)malloc(pCount * sizeof(const char *)); + int *pLens = (int *)malloc(pCount * sizeof(int)); + int *pFormats = (int *)malloc(pCount * sizeof(int)); + // modes are used only by enterprisedb callable statement +#if defined (__WXMSW__) || (EDB_LIBPQ) + int *pModes = (int *)malloc(pCount * sizeof(int)); +#endif + + for (; idx < pCount; idx++) + { + pgParam *param = (*params)[idx]; + + pOids[idx] = param->m_type; + pParams[idx] = (const char *)param->m_val; + pLens[idx] = param->m_len; + pFormats[idx] = param->GetFormat(); +#if defined (__WXMSW__) || (EDB_LIBPQ) + pModes[idx] = param->m_mode; +#endif + } + + if (useCallable) + { +#if defined (__WXMSW__) || (EDB_LIBPQ) + wxLogInfo(wxString::Format( + _("using an enterprisedb callable statement (queryid:%ld, threadid:%ld)"), + (long)m_currIndex, (long)GetId())); + wxString stmt = wxString::Format(wxT("pgQueryThread-%ld-%ld"), this->GetId(), m_currIndex); + PGresult *res = PQiPrepareOut(m_conn->conn, stmt.mb_str(wxConvUTF8), + queryBuf, pCount, pOids, pModes); + + if( PQresultStatus(res) != PGRES_COMMAND_OK) + { + rc = pgQueryResultEvent::PGQ_ERROR_PREPARE_CALLABLE; + err.SetError(res, &conv); + + PQclear(res); + + goto return_with_error; + } + + ret = PQiSendQueryPreparedOut(m_conn->conn, stmt.mb_str(wxConvUTF8), + pCount, pParams, pLens, pFormats, 1); + + if (ret != 1) + { + rc = pgQueryResultEvent::PGQ_ERROR_EXECUTE_CALLABLE; + + m_conn->SetLastResultError(NULL, _("Failed to run PQsendQuery in pgQueryThread")); + err.msg_primary = wxString(PQerrorMessage(m_conn->conn), conv); + + PQclear(res); + res = NULL; + + goto return_with_error; + } + + PQclear(res); + res = NULL; +#else + rc = -1; + wxASSERT_MSG(false, + _("the program execution flow must not reach to this point in pgQueryThread")); + + goto return_with_error; +#endif + } + else + { + // assumptions: we will need the results in text format only + ret = PQsendQueryParams(m_conn->conn, queryBuf, pCount, pOids, pParams, pLens, pFormats, 0); + + if (ret != 1) + { + rc = pgQueryResultEvent::PGQ_ERROR_SEND_QUERY; + + m_conn->SetLastResultError(NULL, + _("Failed to run PQsendQueryParams in pgQueryThread")); + + err.msg_primary = _("Failed to run PQsendQueryParams in pgQueryThread.\n") + + wxString(PQerrorMessage(m_conn->conn), conv); + + goto return_with_error; + } + } + goto continue_without_error; + +return_with_error: + { + free(pOids); + free(pParams); + free(pLens); + free(pFormats); +#if defined (__WXMSW__) || (EDB_LIBPQ) + free(pModes); +#endif + return (RaiseEvent(rc)); + } + } + else + { + // use the PQsendQuery api in case, we don't have any parameters to + // pass to the server + if (!PQsendQuery(m_conn->conn, queryBuf)) + { + rc = pgQueryResultEvent::PGQ_ERROR_SEND_QUERY; + + err.msg_primary = _("Failed to run PQsendQueryParams in pgQueryThread.\n") + + wxString(PQerrorMessage(m_conn->conn), conv); + + return(RaiseEvent(rc)); + } + } + +continue_without_error: + int resultsRetrieved = 0; + PGresult *lastResult = 0; + bool connExecutionCancelled = false; + + while (true) + { + // This is a 'joinable' thread, it is not advisable to call 'delete' + // function on this. + // Hence - it does not make sense to use the function 'testdestroy' here. + // We introduced the 'CancelExecution' function for the same purpose. + // + // We will have to call the CancelExecution function of pgConn to + // inform the backend that the user has cancelled the execution. + // + // We will need to consume all the results before quiting from the thread. + // Otherwise - the connection object will become unusable, and throw + // error - because libpq connections expects application to consume all + // the result, before executing another query + // + if (m_cancelled && rc != pgQueryResultEvent::PGQ_EXECUTION_CANCELLED) + { + // We shouldn't be calling cancellation multiple time + if (!connExecutionCancelled) + { + m_conn->CancelExecution(); + connExecutionCancelled = true; + } + rc = pgQueryResultEvent::PGQ_EXECUTION_CANCELLED; + + err.msg_primary = _("Execution Cancelled"); + + if (lastResult) + { + PQclear(lastResult); + lastResult = NULL; + } + } + + if ((rc = PQconsumeInput(m_conn->conn)) != 1) + { + if (m_cancelled) + { + rc = pgQueryResultEvent::PGQ_EXECUTION_CANCELLED; + err.msg_primary = _("Execution Cancelled"); + + if (lastResult) + { + PQclear(lastResult); + lastResult = NULL; + } + // There is nothing more to consume. + // We can quit the thread now. + // + // Raise the event - if the component asked for it on + // execution cancellation. + if (m_eventOnCancellation) + RaiseEvent(rc); + + return rc; + } + + if (rc == 0) + { + err.msg_primary = wxString(PQerrorMessage(m_conn->conn), conv); + } + if (PQstatus(m_conn->conn) == CONNECTION_BAD) + { + err.msg_primary = _("Connection to the database server lost"); + rc = pgQueryResultEvent::PGQ_CONN_LOST; + } + else + { + rc = pgQueryResultEvent::PGQ_ERROR_CONSUME_INPUT; + } + + return(RaiseEvent(rc)); + } + + if (PQisBusy(m_conn->conn)) + { + Yield(); + this->Sleep(10); + + continue; + } + + // if resultToRetrieve is given, the nth result will be returned, + // otherwise the last result set will be returned. + // all others are discarded + PGresult *res = PQgetResult(m_conn->conn); + + if (!res) + break; + + if((PQresultStatus(res) == PGRES_NONFATAL_ERROR) || + (PQresultStatus(res) == PGRES_FATAL_ERROR) || + (PQresultStatus(res) == PGRES_BAD_RESPONSE)) + { + result = res; + err.SetError(res, &conv); + + // Wait for the execution to be finished + // We need to fetch all the results, before sending the error + // message + do + { + if (PQconsumeInput(m_conn->conn) != 1) + { + if (m_cancelled) + { + rc = pgQueryResultEvent::PGQ_EXECUTION_CANCELLED; + + // Release the result as the query execution has been cancelled by the + // user + if (result) + PQclear(result); + + result = NULL; + + if (m_eventOnCancellation) + RaiseEvent(rc); + + return rc; + } + goto out_of_consume_input_loop; + } + + if ((res = PQgetResult(m_conn->conn)) == NULL) + { + goto out_of_consume_input_loop; + } + + // Release the temporary results + PQclear(res); + res = NULL; + + if (PQisBusy(m_conn->conn)) + { + Yield(); + this->Sleep(10); + } + } + while (true); + + break; + } + +#if defined (__WXMSW__) || (EDB_LIBPQ) + // there should be 2 results in the callable statement - the first is the + // dummy, the second contains our out params. + if (useCallable) + { + PQclear(res); + result = PQiGetOutResult(m_conn->conn); + } +#endif + if (PQresultStatus(res) == PGRES_COPY_IN) + { + rc = PGRES_COPY_IN; + PQputCopyEnd(m_conn->conn, "not supported by pgadmin"); + } + + if (PQresultStatus(res) == PGRES_COPY_OUT) + { + int copyRc; + char *buf; + int copyRows = 0; + int lastCopyRc = 0; + + rc = PGRES_COPY_OUT; + + AppendMessage(_("query returned copy data:\n")); + + while((copyRc = PQgetCopyData(m_conn->conn, &buf, 1)) >= 0) + { + // Ignore processing the query result, when it has already been + // cancelled by the user + if (m_cancelled) + { + if (!connExecutionCancelled) + { + m_conn->CancelExecution(); + connExecutionCancelled = true; + } + continue; + } + + if (buf != NULL) + { + if (copyRows < 100) + { + wxString str(buf, conv); + wxCriticalSectionLocker cs(m_criticalSection); + m_queries[m_currIndex]->m_message.Append(str); + + } + else if (copyRows == 100) + AppendMessage(_("Query returned more than 100 copy rows, discarding the rest...\n")); + + PQfreemem(buf); + } + if (copyRc > 0) + copyRows++; + + if (lastCopyRc == 0 && copyRc == 0) + { + Yield(); + this->Sleep(10); + } + if (copyRc == 0) + { + if (!PQconsumeInput(m_conn->conn)) + { + // It might be the case - it is a result of the + // execution cancellation. + if (m_cancelled) + { + rc = pgQueryResultEvent::PGQ_EXECUTION_CANCELLED; + + // Release the result as the query execution has been cancelled by the + // user + if (result) + PQclear(result); + + result = NULL; + + if (m_eventOnCancellation) + RaiseEvent(rc); + + return rc; + } + if (PQstatus(m_conn->conn) == CONNECTION_BAD) + { + err.msg_primary = _("Connection to the database server lost"); + rc = pgQueryResultEvent::PGQ_CONN_LOST; + } + else + { + rc = pgQueryResultEvent::PGQ_ERROR_CONSUME_INPUT; + + err.msg_primary = wxString(PQerrorMessage(m_conn->conn), conv); + } + return(RaiseEvent(rc)); + } + } + lastCopyRc = copyRc; + } + + res = PQgetResult(m_conn->conn); + + if (!res) + break; + } + + resultsRetrieved++; + + // Save the current result, as asked by the component + // But - only if the execution is not cancelled + if (!m_cancelled && resultsRetrieved == resultToRetrieve) + { + result = res; + insertedOid = PQoidValue(res); + if (insertedOid && insertedOid != (Oid) - 1) + AppendMessage(wxString::Format(_("query inserted one row with oid %d.\n"), insertedOid)); + else + AppendMessage(wxString::Format(wxPLURAL("query result with %d row will be returned.\n", "query result with %d rows will be returned.\n", + PQntuples(result)), PQntuples(result))); + continue; + } + + if (lastResult) + { + if (!m_cancelled && PQntuples(lastResult)) + AppendMessage(wxString::Format(wxPLURAL("query result with %d row discarded.\n", "query result with %d rows discarded.\n", + PQntuples(lastResult)), PQntuples(lastResult))); + PQclear(lastResult); + } + lastResult = res; + } + +out_of_consume_input_loop: + if (m_cancelled) + { + rc = pgQueryResultEvent::PGQ_EXECUTION_CANCELLED; + + // Release the result as the query execution has been cancelled by the + // user + if (result) + PQclear(result); + + result = NULL; + + if (m_eventOnCancellation) + RaiseEvent(rc); + + return rc; + } + + if (!result) + result = lastResult; + + err.SetError(result, &conv); + + AppendMessage(wxT("\n")); + + rc = PQresultStatus(result); + if (rc == PGRES_TUPLES_OK) + { + dataSet = new pgSet(result, m_conn, conv, m_conn->needColQuoting); + dataSet->MoveFirst(); + } + else if (rc == PGRES_COMMAND_OK) + { + char *s = PQcmdTuples(result); + if (*s) + rowsInserted = atol(s); + } + else if (rc == PGRES_FATAL_ERROR || + rc == PGRES_NONFATAL_ERROR || + rc == PGRES_BAD_RESPONSE) + { + if (result) + { + AppendMessage(wxString(PQresultErrorMessage(result), conv)); + PQclear(result); + result = NULL; + } + else + { + AppendMessage(wxString(PQerrorMessage(m_conn->conn), conv)); + } + + return(RaiseEvent(rc)); + } + + insertedOid = PQoidValue(result); + if (insertedOid == (Oid) - 1) + insertedOid = 0; + + return(RaiseEvent(1)); +} + +int pgQueryThread::RaiseEvent(int _retval) +{ +#if !defined(PGSCLI) + if (m_caller) + { + pgQueryResultEvent resultEvent(GetId(), m_queries[m_currIndex], m_queries[m_currIndex]->m_eventID); + + // client data + resultEvent.SetClientData(m_queries[m_currIndex]->m_data); + resultEvent.SetInt(_retval); + + m_caller->AddPendingEvent(resultEvent); + } +#endif + return _retval; +} + + +void *pgQueryThread::Entry() +{ + do + { + if (m_currIndex < (((int)m_queries.GetCount()) - 1)) + { + // Create the PGcancel object to enable cancelling the running + // query + m_conn->SetConnCancel(); + m_currIndex++; + + m_queries[m_currIndex]->m_returnCode = -2; + m_queries[m_currIndex]->m_rowsInserted = -1l; + + wxLogSql(wxT("Thread executing query (%d:%s:%d): %s"), + m_currIndex + 1, m_conn->GetHost().c_str(), m_conn->GetPort(), + m_queries[m_currIndex]->m_query.c_str()); + + // register the notice processor for the current query + m_conn->RegisterNoticeProcessor(m_processor, m_noticeHandler); + + // execute the current query now + Execute(); + + // remove the notice processor now + m_conn->RegisterNoticeProcessor(0, 0); + + // reset the PGcancel object + m_conn->ResetConnCancel(); + } + + if (!m_multiQueries || m_cancelled) + break; + + wxThread::Sleep(10); + } + while (true); + + return(NULL); +} + +int pgQueryThread::DeleteReleasedQueries() +{ + int res = 0, + idx = 0; + + if (m_queriesLock.TryLock() == wxMUTEX_BUSY) + return res; + + for (; idx <= m_currIndex; idx++) + { + if (m_queries[idx]->m_resultSet != NULL) + { + pgSet *set = m_queries[idx]->m_resultSet; + m_queries[idx]->m_resultSet = NULL; + delete set; + set = NULL; + + res++; + } + } + m_queriesLock.Unlock(); + + return res; +} + + +pgError pgQueryThread::GetResultError(int idx) +{ + wxMutexLocker lock(m_queriesLock); + + if (idx == -1) + idx = m_currIndex; + + return m_queries[idx]->m_err; +} + + +const wxString &pgBatchQuery::GetErrorMessage() +{ + return m_err.msg_primary; +} + +pgBatchQuery::~pgBatchQuery() +{ + if (m_resultSet) + { + delete m_resultSet; + m_resultSet = NULL; + } + + if (m_params) + { + WX_CLEAR_ARRAY((*m_params)); + delete m_params; + m_params = NULL; + } +} + +bool pgBatchQuery::Release() +{ + bool res = false; + + if (m_resultSet != NULL) + { + res = true; + + pgSet *set = m_resultSet; + m_resultSet = NULL; + + if (set) + delete set; + set = NULL; + } + + if (m_params) + { + res = true; + + WX_CLEAR_ARRAY((*m_params)); + delete m_params; + m_params = NULL; + } + + return res; +} + +pgQueryResultEvent::pgQueryResultEvent( + unsigned long _thrdId, pgBatchQuery *_qry, int _id) : + wxCommandEvent(PGQueryResultEvent, _id), m_thrdId(_thrdId), + m_query(_qry) { } + +pgQueryResultEvent::pgQueryResultEvent(const pgQueryResultEvent &_ev) + : wxCommandEvent(_ev), m_thrdId(_ev.m_thrdId), m_query(_ev.m_query) { } + + +pgParam::pgParam(Oid _type, void *_val, int _len, short _mode) + : m_type(_type), m_val(_val), m_len(_len), m_mode(_mode) +{ + switch(m_type) + { + case PGOID_TYPE_CHAR: + case PGOID_TYPE_NAME: + case PGOID_TYPE_TEXT: + case PGOID_TYPE_VARCHAR: + case PGOID_TYPE_CSTRING: + m_format = 0; + default: + m_format = 1; + } +} + +// wxString data +pgParam::pgParam(Oid _oid, wxString *_val, wxMBConv *_conv, short _mode) + : m_mode(_mode) +{ + if (m_mode == PG_PARAM_OUT || !_val) + { + m_len = 0; + } + else + { + m_len = _val->Len(); + } + if (_val) + { + char *str = (char *)malloc(m_len + 1); + if (!_val->IsEmpty() && _mode != PG_PARAM_OUT) + { + strncpy(str, + (const char *)_val->mb_str( + *(_conv != NULL ? _conv : &wxConvLocal)), m_len); + str[m_len] = '\0'; + } + else + { + str[0] = '\0'; + } + m_val = (void *)(str); + } + else + { + m_val = NULL; + } + m_type = _oid; + + // text format + m_format = 0; +} + + +pgParam::~pgParam() +{ + if (m_val) + free(m_val); + m_val = NULL; +} + + +int pgParam::GetFormat() +{ + return m_format; +} diff --git a/db/pgSet.cpp b/db/pgSet.cpp new file mode 100644 index 0000000..4ab6cf2 --- /dev/null +++ b/db/pgSet.cpp @@ -0,0 +1,443 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgSet.cpp - PostgreSQL ResultSet class +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// PostgreSQL headers +#include + +// App headers +#include "db/pgSet.h" +#include "db/pgConn.h" +#include "utils/sysLogger.h" +#include "utils/pgDefs.h" + +pgSet::pgSet() + : conv(wxConvLibc) +{ + conn = 0; + res = 0; + nCols = 0; + nRows = 0; + pos = 0; +} + +pgSet::pgSet(PGresult *newRes, pgConn *newConn, wxMBConv &cnv, bool needColQt) + : conv(cnv) +{ + needColQuoting = needColQt; + + conn = newConn; + res = newRes; + + // Make sure we have tuples + if (PQresultStatus(res) != PGRES_TUPLES_OK) + { + nCols = 0; + nRows = 0; + pos = 0; + } + else + { + nCols = PQnfields(res); + for (int x = 0; x < nCols + 1; x++) + { + colTypes.Add(wxT("")); + colFullTypes.Add(wxT("")); + colClasses.Add(0); + } + + nRows = PQntuples(res); + MoveFirst(); + } +} + + +pgSet::~pgSet() +{ + PQclear(res); +} + + + +OID pgSet::ColTypeOid(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + return PQftype(res, col); +} + +long pgSet::ColTypeMod(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + return PQfmod(res, col); +} + + +long pgSet::GetInsertedCount() const +{ + char *cnt = PQcmdTuples(res); + if (!*cnt) + return -1; + else + return atol(cnt); +} + + +pgTypClass pgSet::ColTypClass(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + if (colClasses[col] != 0) + return (pgTypClass)colClasses[col]; + + wxString typoid = ExecuteScalar( + wxT("SELECT CASE WHEN typbasetype=0 THEN oid else typbasetype END AS basetype\n") + wxT(" FROM pg_type WHERE oid=") + NumToStr(ColTypeOid(col))); + + switch (StrToLong(typoid)) + { + case PGOID_TYPE_BOOL: + colClasses[col] = PGTYPCLASS_BOOL; + break; + case PGOID_TYPE_INT8: + case PGOID_TYPE_INT2: + case PGOID_TYPE_INT4: + case PGOID_TYPE_OID: + case PGOID_TYPE_XID: + case PGOID_TYPE_TID: + case PGOID_TYPE_CID: + case PGOID_TYPE_FLOAT4: + case PGOID_TYPE_FLOAT8: + case PGOID_TYPE_MONEY: + case PGOID_TYPE_BIT: + case PGOID_TYPE_NUMERIC: + colClasses[col] = PGTYPCLASS_NUMERIC; + break; + case PGOID_TYPE_BYTEA: + case PGOID_TYPE_CHAR: + case PGOID_TYPE_NAME: + case PGOID_TYPE_TEXT: + case PGOID_TYPE_VARCHAR: + colClasses[col] = PGTYPCLASS_STRING; + break; + case PGOID_TYPE_TIMESTAMP: + case PGOID_TYPE_TIMESTAMPTZ: + case PGOID_TYPE_TIME: + case PGOID_TYPE_TIMETZ: + case PGOID_TYPE_INTERVAL: + colClasses[col] = PGTYPCLASS_DATE; + break; + default: + colClasses[col] = PGTYPCLASS_OTHER; + break; + } + + return (pgTypClass)colClasses[col]; +} + + +wxString pgSet::ColType(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + if (!colTypes[col].IsEmpty()) + return colTypes[col]; + + wxString szSQL, szResult; + szSQL.Printf(wxT("SELECT format_type(oid,NULL) as typname FROM pg_type WHERE oid = %d"), (int)ColTypeOid(col)); + szResult = ExecuteScalar(szSQL); + colTypes[col] = szResult; + + return szResult; +} + +wxString pgSet::ColFullType(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + if (!colFullTypes[col].IsEmpty()) + return colFullTypes[col]; + + wxString szSQL, szResult; + szSQL.Printf(wxT("SELECT format_type(oid,%d) as typname FROM pg_type WHERE oid = %d"), (int)ColTypeMod(col), (int)ColTypeOid(col)); + szResult = ExecuteScalar(szSQL); + colFullTypes[col] = szResult; + + return szResult; +} + +int pgSet::ColScale(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + // TODO + return 0; +} +wxString pgSet::ColName(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + return wxString(PQfname(res, col), conv); +} + + +int pgSet::ColNumber(const wxString &colname) const +{ + int col; + + if (needColQuoting) + { + wxString quotedColName = colname; + quotedColName.Replace(wxT("\""), wxT("\"\"")); + col = PQfnumber(res, (wxT("\"") + quotedColName + wxT("\"")).mb_str(conv)); + } + else + col = PQfnumber(res, colname.mb_str(conv)); + + if (col < 0) + { + wxLogError(__("Column not found in pgSet: %s"), colname.c_str()); + } + return col; +} + +bool pgSet::HasColumn(const wxString &colname) const +{ + if (needColQuoting) + { + wxString quotedColName = colname; + quotedColName.Replace(wxT("\""), wxT("\"\"")); + return (PQfnumber(res, (wxT("\"") + quotedColName + wxT("\"")).mb_str(conv)) < 0 ? false : true); + } + else + return (PQfnumber(res, colname.mb_str(conv)) < 0 ? false : true); + +} + + + +char *pgSet::GetCharPtr(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + return PQgetvalue(res, pos - 1, col); +} + + +char *pgSet::GetCharPtr(const wxString &col) const +{ + return PQgetvalue(res, pos - 1, ColNumber(col)); +} + + +wxString pgSet::GetVal(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + return wxString(GetCharPtr(col), conv); +} + + +wxString pgSet::GetVal(const wxString &colname) const +{ + return GetVal(ColNumber(colname)); +} + + +long pgSet::GetLong(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + char *c = PQgetvalue(res, pos - 1, col); + if (c) + return atol(c); + else + return 0; +} + + +long pgSet::GetLong(const wxString &col) const +{ + char *c = PQgetvalue(res, pos - 1, ColNumber(col)); + if (c) + return atol(c); + else + return 0; +} + + +bool pgSet::GetBool(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + char *c = PQgetvalue(res, pos - 1, col); + if (c) + { + if (*c == 't' || *c == '1' || !strcmp(c, "on")) + return true; + } + return false; +} + + +bool pgSet::GetBool(const wxString &col) const +{ + return GetBool(ColNumber(col)); +} + + +wxDateTime pgSet::GetDateTime(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + wxDateTime dt; + wxString str = GetVal(col); + /* This hasn't just been used. ( Is not infinity ) */ + if (!str.IsEmpty()) + dt.ParseDateTime(str); + return dt; +} + + +wxDateTime pgSet::GetDateTime(const wxString &col) const +{ + return GetDateTime(ColNumber(col)); +} + + +wxDateTime pgSet::GetDate(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + wxDateTime dt; + wxString str = GetVal(col); + /* This hasn't just been used. ( Is not infinity ) */ + if (!str.IsEmpty()) + dt.ParseDate(str); + return dt; +} + + +wxDateTime pgSet::GetDate(const wxString &col) const +{ + return GetDate(ColNumber(col)); +} + + +double pgSet::GetDouble(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + return StrToDouble(GetVal(col)); +} + + +double pgSet::GetDouble(const wxString &col) const +{ + return GetDouble(ColNumber(col)); +} + + +wxULongLong pgSet::GetLongLong(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + char *c = PQgetvalue(res, pos - 1, col); + if (c) + return atolonglong(c); + else + return 0; +} + +wxULongLong pgSet::GetLongLong(const wxString &col) const +{ + return GetLongLong(ColNumber(col)); +} + + +OID pgSet::GetOid(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + char *c = PQgetvalue(res, pos - 1, col); + if (c) + return (OID)strtoul(c, 0, 10); + else + return 0; +} + + +OID pgSet::GetOid(const wxString &col) const +{ + return GetOid(ColNumber(col)); +} + + +wxString pgSet::ExecuteScalar(const wxString &sql) const +{ + return conn->ExecuteScalar(sql); +} + + +////////////////////////////////////////////////////////////////// + +pgSetIterator::pgSetIterator(pgConn *conn, const wxString &qry) +{ + set = conn->ExecuteSet(qry); + first = true; +} + + +pgSetIterator::pgSetIterator(pgSet *s) +{ + set = s; + first = true; +} + + +pgSetIterator::~pgSetIterator() +{ + if (set) + delete set; +} + + +bool pgSetIterator::RowsLeft() +{ + if (!set) + return false; + + if (first) + { + if (!set->NumRows()) + return false; + first = false; + } + else + set->MoveNext(); + + return !set->Eof(); +} + + +bool pgSetIterator::MovePrev() +{ + if (!set) + return false; + + set->MovePrevious(); + return true; +} diff --git a/dd/dditems/figures/ddColumnFigure.cpp b/dd/dditems/figures/ddColumnFigure.cpp new file mode 100644 index 0000000..e2b53fd --- /dev/null +++ b/dd/dditems/figures/ddColumnFigure.cpp @@ -0,0 +1,538 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddColumnFigure.cpp - Minimal Composite Figure for a column of a table +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "dd/dditems/figures/ddColumnFigure.h" +#include "dd/dditems/figures/ddTextTableItemFigure.h" +#include "dd/dditems/tools/ddColumnFigureTool.h" +#include "dd/dditems/figures/ddColumnKindIcon.h" +#include "dd/dditems/figures/ddColumnOptionIcon.h" +#include "dd/dditems/utilities/ddDataType.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/dditems/figures/ddRelationshipItem.h" + +void ddColumnFigure::Init(wxString &columnName, ddTableFigure *owner, ddRelationshipItem *sourceFk) +{ + setKindId(DDCOLUMNFIGURE); + fkSource = sourceFk; + usedAsFkDestFor = NULL; + setOwnerTable(owner); + deactivateGenFkName(); //initializae by default at not generate auto fk name + columnText = new ddTextTableItemFigure(columnName, dt_null, this); + kindImage = new ddColumnKindIcon(this); + optionImage = new ddColumnOptionIcon(this); + + + //Initialize displaybox and image coords + basicDisplayBox.SetPosition(0, wxPoint(0, 0)); + basicDisplayBox.SetSize( columnText->displayBox().GetSize()); + if(kindImage && optionImage) + { + basicDisplayBox.width += kindImage->displayBox().GetSize().GetWidth() + 3; + basicDisplayBox.width += optionImage->displayBox().GetSize().GetWidth() + 3; + columnText->displayBox().x[0] += kindImage->displayBox().GetSize().GetWidth() + 2; + columnText->displayBox().x[0] += optionImage->displayBox().GetSize().GetWidth() + 3; + } + else + { + basicDisplayBox.width += 22; //default value = 1 + 8 + 3 + 8 + 2 + columnText->displayBox().x[0] += 22; + } + + //Set Value default Attributes + fontAttribute->font().SetPointSize(owner->fontAttribute->font().GetPointSize()); + pgAttNumColNumber = -1; +} + +ddColumnFigure::ddColumnFigure(wxString &columnName, ddTableFigure *owner, ddRelationshipItem *sourceFk) +{ + Init(columnName, owner, sourceFk); +} + +//Constructor for creation of existing column from storage +ddColumnFigure::ddColumnFigure(wxString &columnName, ddTableFigure *owner, ddColumnOptionType option, bool isGenFk, bool isPkColumn, wxString colDataType, int p, int s, int ukIdx, ddRelationshipItem *srcFk, ddRelationshipItem *usedAsFk ) +{ + Init(columnName, owner, srcFk); + setColumnOption(option); + generateFkName = isGenFk; + kindImage->setPrimaryKey(isPkColumn); + + int dtype = columnText->dataTypes().Index(colDataType, false); + if(dtype != wxNOT_FOUND) + { + setDataType((ddDataType)dtype); + } + else + { + wxMessageBox(wxString::Format(_("%s column has a non compatible data type (%s).\n%s will now have the default data type."), + columnName.c_str(), colDataType.c_str(), columnName.c_str())); + setDataType((ddDataType)0); + } + + columnText->setPrecision(p); + columnText->setScale(s); + kindImage->setUkIndex(ukIdx); + + usedAsFkDestFor = usedAsFk; + if(ownerTable) + ownerTable->updateTableSize(); + +} + +ddColumnFigure::~ddColumnFigure() +{ + if(columnText) + delete columnText; + if(kindImage) + delete kindImage; + if(optionImage) + delete optionImage; +} + +void ddColumnFigure::AddPosForNewDiagram() +{ + //Add position for new displaybox at new diagram + hdAttributeFigure::AddPosForNewDiagram(); + //Add position to each figure inside this composite figure + if(kindImage) + kindImage->AddPosForNewDiagram(); + if(optionImage) + optionImage->AddPosForNewDiagram(); + if(columnText) + columnText->AddPosForNewDiagram(); +} + +void ddColumnFigure::RemovePosOfDiagram(int posIdx) +{ + //Remove this position at displaybox of this figure + hdAttributeFigure::RemovePosOfDiagram(posIdx); + //Remove this position at each figure inside this composite figure + if(kindImage) + kindImage->RemovePosOfDiagram(posIdx); + if(optionImage) + optionImage->RemovePosOfDiagram(posIdx); + if(columnText) + columnText->RemovePosOfDiagram(posIdx); + +} + +void ddColumnFigure::basicMoveBy(int posIdx, int x, int y) +{ + hdAbstractFigure::basicMoveBy(posIdx, x, y); + if(kindImage) + kindImage->moveBy(posIdx, x, y); + if(optionImage) + optionImage->moveBy(posIdx, x, y); + columnText->moveBy(posIdx, x, y); +} + +void ddColumnFigure::moveTo(int posIdx, int x, int y) +{ + hdAbstractFigure::moveTo(posIdx, x, y); + int distance = 0; + + if(kindImage) + { + kindImage->moveTo(posIdx, x, y); + distance += kindImage->displayBox().GetSize().GetWidth() + 3; + } + else + { + distance += 11; //value = 8 + 3 + } + + if(optionImage) + { + optionImage->moveTo(posIdx, x + distance, y); + distance += optionImage->displayBox().GetSize().GetWidth() + 3; + } + else + { + distance += 11; //value = 8 + 3 + } + + columnText->moveTo(posIdx, x + distance, y); +} + + +bool ddColumnFigure::containsPoint(int posIdx, int x, int y) +{ + bool out = false; + + if(columnText->containsPoint(posIdx, x, y)) + out = true; + else if(kindImage->containsPoint(posIdx, x, y)) + out = true; + else if(optionImage->containsPoint(posIdx, x, y)) + out = true; + + return out; +} + +hdMultiPosRect &ddColumnFigure::getBasicDisplayBox() +{ + return basicDisplayBox; +} + +void ddColumnFigure::basicDraw(wxBufferedDC &context, hdDrawingView *view) +{ + columnText->draw(context, view); + if(kindImage) + kindImage->draw(context, view); + if(optionImage) + optionImage->draw(context, view); +} + +void ddColumnFigure::basicDrawSelected(wxBufferedDC &context, hdDrawingView *view) +{ + columnText->drawSelected(context, view); + if(kindImage) + kindImage->drawSelected(context, view); + if(optionImage) + optionImage->drawSelected(context, view); +} + +hdIFigure *ddColumnFigure::findFigure(int posIdx, int x, int y) +{ + hdIFigure *out = NULL; + + if(columnText->containsPoint(posIdx, x, y)) + out = columnText; + + if(kindImage && kindImage->containsPoint(posIdx, x, y)) + out = kindImage; + + if(optionImage && optionImage->containsPoint(posIdx, x, y)) + out = optionImage; + + return out; +} + +hdITool *ddColumnFigure::CreateFigureTool(hdDrawingView *view, hdITool *defaultTool) +{ + return new ddColumnFigureTool(view, this, defaultTool); +} + +hdIFigure *ddColumnFigure::getFigureAt(int pos) +{ + if(pos == 0) + return (hdIFigure *) kindImage; + + if(pos == 1) + return (hdIFigure *) optionImage; + + if(pos == 2) + return (hdIFigure *) columnText; + + return NULL; +} + +ddTableFigure *ddColumnFigure::getOwnerTable() +{ + return ownerTable; +} + +void ddColumnFigure::setOwnerTable(ddTableFigure *table) +{ + ownerTable = table; +} + +void ddColumnFigure::displayBoxUpdate() +{ + if(kindImage && optionImage) + { + columnText->displayBoxUpdate(); + basicDisplayBox.width = columnText->displayBox().GetSize().GetWidth(); + basicDisplayBox.width += kindImage->displayBox().GetSize().GetWidth() + 3; + basicDisplayBox.width += optionImage->displayBox().GetSize().GetWidth() + 3; + } + else + { + columnText->displayBoxUpdate(); + basicDisplayBox.width += 22; //default value = 1 + 8 + 3 + 8 +2 + } +} + +bool ddColumnFigure::isNull() +{ + return optionImage->getOption() == null; +} + +bool ddColumnFigure::isNotNull() +{ + return optionImage->getOption() == notnull; +} + +bool ddColumnFigure::isNone() +{ + return kindImage->isNone(); +} + +bool ddColumnFigure::isPrimaryKey() +{ + return kindImage->isPrimaryKey(); +} + +void ddColumnFigure::disablePrimaryKey() +{ + kindImage->disablePrimaryKey(); +} + +void ddColumnFigure::enablePrimaryKey() +{ + kindImage->enablePrimaryKey(); +} + +bool ddColumnFigure::isUniqueKey() +{ + return kindImage->isUniqueKey(); +} + +bool ddColumnFigure::isUniqueKey(int uniqueIndex) +{ + return kindImage->isUniqueKey(uniqueIndex); +} + +bool ddColumnFigure::isPlain() +{ + return kindImage->isNone(); +} + +void ddColumnFigure::setColumnKindToNone() +{ + kindImage->disablePrimaryKey(); + kindImage->disableUniqueKey(); + //Foreign key cannot be changed by set / toggle functions +} + +void ddColumnFigure::setRightIconForColumn() +{ + kindImage->setRightIconForColumn(); +} + +void ddColumnFigure::toggleColumnKind(ddColumnType type, hdDrawingView *view) +{ + kindImage->toggleColumnKind(type, view); +} + +void ddColumnFigure::setColumnOption(ddColumnOptionType type) +{ + optionImage->changeIcon(type); +} + +wxString &ddColumnFigure::getColumnName(bool datatype) +{ + return columnText->getText(datatype); +} + +void ddColumnFigure::setPrecision(int n) +{ + columnText->setPrecision(n); +} + +int ddColumnFigure::getPrecision() +{ + return columnText->getPrecision(); +} + +void ddColumnFigure::setScale(int n) +{ + columnText->setScale(n); +} + +int ddColumnFigure::getScale() +{ + return columnText->getScale(); +} + +int ddColumnFigure::getUniqueConstraintIndex() +{ + return kindImage->getUniqueConstraintIndex(); +} + +void ddColumnFigure::setUniqueConstraintIndex(int i) +{ + kindImage->setUniqueConstraintIndex(i); +} + +ddColumnOptionType ddColumnFigure::getColumnOption() +{ + return optionImage->getOption(); +} + +ddDataType ddColumnFigure::getDataType() +{ + return columnText->getDataType(); +} + +void ddColumnFigure::setDataType(ddDataType type) +{ + columnText->setDataType(type); +} + +void ddColumnFigure::setColumnName(wxString name) +{ + columnText->setText(name); +} + +bool ddColumnFigure::isForeignKeyFromPk() +{ + if(fkSource) + { + return fkSource->isForeignKeyFromPk(); + } + else if(usedAsFkDestFor) + { + return usedAsFkDestFor->isForeignKeyFromPk(); + } + return false; +} + +bool ddColumnFigure::isForeignKey() +{ + bool a = isUserCreatedForeignKey(); + bool b = isGeneratedForeignKey(); + return (a || b); +} + +bool ddColumnFigure::isGeneratedForeignKey() +{ + return fkSource != NULL; +} + +bool ddColumnFigure::isUserCreatedForeignKey() +{ + return usedAsFkDestFor != NULL; +} + +ddRelationshipItem *ddColumnFigure::getRelatedFkItem() +{ + return usedAsFkDestFor; +} + +void ddColumnFigure::setAsUserCreatedFk(ddRelationshipItem *relatedFkItem) +{ + usedAsFkDestFor = relatedFkItem; + //Now fix icons of kind of column + if(relatedFkItem == NULL) + { + kindImage->setRightIconForColumn(); + } +} + +bool ddColumnFigure::isFkNameGenerated() +{ + return generateFkName; +} + +void ddColumnFigure::activateGenFkName() +{ + generateFkName = true; +} + +void ddColumnFigure::deactivateGenFkName() +{ + generateFkName = false; +} + +wxString ddColumnFigure::generateSQL(bool forAlterColumn) +{ + wxString tmp; + tmp = wxT("\"") + getColumnName() + wxT("\" "); + if(forAlterColumn) + tmp += wxT("TYPE "); + tmp += columnText->getType(); + return tmp; +} + +ddRelationshipItem *ddColumnFigure::getFkSource() +{ + return fkSource; +} + +void ddColumnFigure::setTextColour(wxColour colour) +{ + columnText->fontColorAttribute->fontColor = colour; +} + + +//Validate status of column for SQL DDL generation +bool ddColumnFigure::validateColumn(wxString &errors) +{ + bool out = true; + wxString tmp; + + if(usedAsFkDestFor) + { + //Validate if relationship is marked as identifying but column isn't marked as primary key + wxString sourceTableName = usedAsFkDestFor->sourceTableName(); + wxString destTableName = usedAsFkDestFor->destTableName(); + wxString fkColName = usedAsFkDestFor->fkColumn->getColumnName(false); + wxString sourceColName = usedAsFkDestFor->original->getColumnName(false); + + if(usedAsFkDestFor->relationIsIdentifying() && !this->isPrimaryKey()) + { + out = false; + tmp = _("relation between table: ") + sourceTableName + _(" and table: ") + destTableName; + tmp += _(" is marked as identifying but user created foreign key column: ") + fkColName; + tmp += _(" isn't set as primary key \n"); + errors.Append(tmp); + } + //Validate if relationship is marked as optional but column is mandatory + if( !usedAsFkDestFor->relationIsMandatory() && this->isNotNull()) + { + out = false; + tmp = _("relation between table:") + sourceTableName + _(" and table: ") + destTableName; + tmp += _("is marked as optional but user created foreign key column: ") + fkColName; + tmp += _("is set as mandatory \n"); + errors.Append(tmp); + } + //Validate if relationship is marked as mandatory buy column is optional + if( usedAsFkDestFor->relationIsMandatory() && this->isNull()) + { + out = false; + tmp = _("relation between table:") + sourceTableName + _(" and table: ") + destTableName + + tmp += _(" is marked as mandatory but user created foreign key column: ") + fkColName; + tmp += _("is set as optional \n"); + errors.Append(tmp); + } + + //Validate datatype compatibility (right now only exactly same datatype) + if(this->getDataType() != usedAsFkDestFor->original->getDataType()) + { + out = false; + tmp = _("User created foreign key column: ") + fkColName + _("have different datatype from source column of relationship: "); + tmp += sourceColName + _(" \n"); + errors.Append(tmp); + } + } + + return out; +} + +//Used by persistence classes +void ddColumnFigure::setFkSource(ddRelationshipItem *newColumn) +{ + fkSource = newColumn; +} + +//Used by reverse engineering functions +wxString ddColumnFigure::getRawDataType() +{ + return columnText->getType(true); +} diff --git a/dd/dditems/figures/ddColumnKindIcon.cpp b/dd/dditems/figures/ddColumnKindIcon.cpp new file mode 100644 index 0000000..b58d152 --- /dev/null +++ b/dd/dditems/figures/ddColumnKindIcon.cpp @@ -0,0 +1,435 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddColumnKindIcon.cpp - Figure container for kind of Column Images (fk,pk,uk) only used +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "dd/dditems/figures/ddColumnKindIcon.h" +#include "hotdraw/main/hdDrawingView.h" +#include "dd/dditems/figures/ddColumnFigure.h" +#include "dd/dditems/figures/ddTableFigure.h" + +//Images +#include "images/ddforeignkey.pngc" +#include "images/ddprimarykey.pngc" +#include "images/ddunique.pngc" +#include "images/ddprimaryforeignkey.pngc" +#include "images/ddprimarykeyuniquekey.pngc" +#include "images/ddforeignkeyfromuk.pngc" +#include "images/ddprimaryforeignkeyfromuk.pngc" +#include "images/ddforeignkeyuniquekey.pngc" +#include "images/ddforeignkeyuniquekeyfromuk.pngc" + +ddColumnKindIcon::ddColumnKindIcon(ddColumnFigure *owner) +{ + setKindId(DDCOLUMNKINDICON); + ownerColumn = owner; + // Initialize with an image to allow initial size calculations + icon = wxBitmap(*ddprimarykey_png_img); + iconToDraw = NULL; + getBasicDisplayBox().SetSize(wxSize(getWidth(), getHeight())); + isPk = false; + ukIndex = -1; + + //Set Value default Attributes + fontAttribute->font().SetPointSize(owner->fontAttribute->font().GetPointSize()); +} + +ddColumnKindIcon::~ddColumnKindIcon() +{ +} + +void ddColumnKindIcon::createMenu(wxMenu &mnu) +{ + wxMenuItem *item; + + item = mnu.AppendCheckItem(MNU_DDCTPKEY, _("Primary key")); + item->Check(isPrimaryKey()); + item->Enable(!getOwnerColumn()->isGeneratedForeignKey()); + item = mnu.AppendCheckItem(MNU_DDCTUKEY, _("Unique key")); + item->Check(isUniqueKey()); +} + +void ddColumnKindIcon::OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view) +{ + toggleColumnKind((ddColumnType)event.GetId(), view); +} + +ddColumnFigure *ddColumnKindIcon::getOwnerColumn() +{ + return ownerColumn; +} + +//if columntype attribute (type) is active then disable, is disable then active. +void ddColumnKindIcon::toggleColumnKind(ddColumnType type, hdDrawingView *view, bool interaction) +{ + + switch(type) + { + case pk: + //Set Pk attribute + if(isPrimaryKey()) + { + disablePrimaryKey(); + } + else + { + enablePrimaryKey(); + if(getOwnerColumn()->isNull()) + { + getOwnerColumn()->setColumnOption(notnull); + } + } + break; + case uk: + if(isUniqueKey()) + { + disableUniqueKey(); + } + else + { + uniqueConstraintManager(false, view, interaction); + } + break; + default: + break; + } + getBasicDisplayBox().SetSize(wxSize(getWidth(), getHeight())); +} + +void ddColumnKindIcon::basicDraw(wxBufferedDC &context, hdDrawingView *view) +{ + if(iconToDraw) + { + hdRect copy = displayBox().gethdRect(view->getIdx()); + view->CalcScrolledPosition(copy.x, copy.y, ©.x, ©.y); + //Adding a yellow circle to increase visibility of uk index + if(isUniqueKey()) + { + context.SetBrush(wxBrush(wxColour(wxT("YELLOW")), wxSOLID)); + context.SetPen(wxPen(wxColour(wxT("YELLOW")))); + context.DrawCircle(copy.x + 6, copy.y + 7, 4); + } + //Draw icon + context.DrawBitmap(*iconToDraw, copy.GetPosition(), true); + //Draw Uk index if needed + if(isUniqueKey() && ukIndex > 0) + { + wxFont font = fontAttribute->font(); + font.SetPointSize(6); + context.SetFont(font); + wxString inumber = wxString::Format(wxT("%d"), (int)ukIndex + 1); + context.DrawText(inumber, copy.x + 4, copy.y + 2); + } + + } +} + +void ddColumnKindIcon::basicDrawSelected(wxBufferedDC &context, hdDrawingView *view) +{ + basicDraw(context, view); +} + +int ddColumnKindIcon::getWidth() +{ + if(iconToDraw) + return iconToDraw->GetWidth(); + else + return 8; +} + +int ddColumnKindIcon::getHeight() +{ + if(iconToDraw) + return iconToDraw->GetHeight(); + else + return 10; +} + +/* +ddColumnType ddColumnKindIcon::getKind() +{ + return colType; +} +*/ + +int ddColumnKindIcon::getUniqueConstraintIndex() +{ + return ukIndex; +} + +void ddColumnKindIcon::setUniqueConstraintIndex(int i) +{ + ukIndex = i; +} + +bool ddColumnKindIcon::uniqueConstraintManager(bool ukCol, hdDrawingView *view, bool interaction) +{ + wxString tmpString; + bool isColUk = true; + + if(ukCol) //if already this column kind is Unique Key then convert in a normal column + { + syncUkIndexes(); + setUniqueConstraintIndex(-1); + } + else //colType!=uk + { + if(interaction) + { + if(ownerColumn->getOwnerTable()->getUkConstraintsNames().Count() == 0) + { + tmpString = getOwnerColumn()->getOwnerTable()->getTableName(); + tmpString.append(wxT("_uk")); + tmpString = wxGetTextFromUser(wxT("Name of new Unique Key constraint:"), tmpString, tmpString, view); + if(tmpString.length() > 0) + { + getOwnerColumn()->getOwnerTable()->getUkConstraintsNames().Add(tmpString); + ukIndex = 0; + } + else + { + setUniqueConstraintIndex(-1); + } + } + else //>0 + { + getOwnerColumn()->getOwnerTable()->getUkConstraintsNames().Add(wxString(wxT("Add new Unique Constraint..."))); + int i = wxGetSingleChoiceIndex(wxT("Select Unique Key to add Column"), wxT("Select Unique Key to add Column:"), getOwnerColumn()->getOwnerTable()->getUkConstraintsNames(), view); + getOwnerColumn()->getOwnerTable()->getUkConstraintsNames().RemoveAt(getOwnerColumn()->getOwnerTable()->getUkConstraintsNames().Count() - 1); + if(i >= 0) + { + if(i == getOwnerColumn()->getOwnerTable()->getUkConstraintsNames().Count()) + { + tmpString = getOwnerColumn()->getOwnerTable()->getTableName(); + tmpString.append(wxT("_uk")); + + int newIndex = i + 1; + wxString inumber = wxString::Format(wxT("%s%d"), tmpString.c_str(), (int)newIndex); + //Validate new name of uk doesn't exists + while(getOwnerColumn()->getOwnerTable()->getUkConstraintsNames().Index(inumber, false) != -1) + { + newIndex++; + inumber = wxString::Format(wxT("%s%d"), tmpString.c_str(), (int)newIndex); + } + inumber = wxString::Format(wxT("%d"), (int)newIndex); + tmpString.append(inumber); + tmpString = wxGetTextFromUser(wxT("Name of new Unique Key constraint:"), tmpString, tmpString, view); + if(tmpString.length() > 0) + { + getOwnerColumn()->getOwnerTable()->getUkConstraintsNames().Add(tmpString); + ukIndex = i; + } + else + { + setUniqueConstraintIndex(-1); + } + } + else + { + ukIndex = i; + } + } + else + { + setUniqueConstraintIndex(-1); + } + } + } + else //without user interaction + { + + } + } + + //synchronize observers if this uk column is used as source of fk + setRightIconForColumn(); + getOwnerColumn()->getOwnerTable()->updateFkObservers(); + + if(!isUniqueKey()) + return false; + else + return true; +} + +//synchronize uk indexes when an uk is change kind from uk to other and other index should be update with that info +void ddColumnKindIcon::syncUkIndexes() +{ + ddColumnFigure *col; + bool lastUk = true; + hdIteratorBase *iterator = getOwnerColumn()->getOwnerTable()->figuresEnumerator(); + iterator->Next(); //First Figure is Main Rect + iterator->Next(); //Second Figure is Table Title + while(iterator->HasNext()) + { + col = (ddColumnFigure *) iterator->Next(); + + if(col != getOwnerColumn() && (col->getUniqueConstraintIndex() == getOwnerColumn()->getUniqueConstraintIndex())) + { + lastUk = false; + break; + } + } + if(lastUk) + { + //here uks indexes are fixed + iterator->ResetIterator(); + iterator->Next(); //First Figure is Main Rect + iterator->Next(); //Second Figure is Table Title + while(iterator->HasNext()) + { + col = (ddColumnFigure *) iterator->Next(); + if( col->getUniqueConstraintIndex() > getOwnerColumn()->getUniqueConstraintIndex() ) + col->setUniqueConstraintIndex(col->getUniqueConstraintIndex() - 1); + } + getOwnerColumn()->getOwnerTable()->getUkConstraintsNames().RemoveAt(getOwnerColumn()->getUniqueConstraintIndex()); + getOwnerColumn()->setUniqueConstraintIndex(-1); + } + delete iterator; +} + +void ddColumnKindIcon::setRightIconForColumn() +{ + //for a pk Column + if(isPrimaryKey()) + { + if(isForeignKey()) + { + if(getOwnerColumn()->isForeignKeyFromPk()) + { + icon = wxBitmap(*ddprimaryforeignkey_png_img); + } + else + { + icon = wxBitmap(*ddprimaryforeignkeyfromuk_png_img); + } + } + else if(isUniqueKey()) + { + icon = wxBitmap(*ddprimarykeyuniquekey_png_img); + } + else + { + icon = wxBitmap(*ddprimarykey_png_img); + } + } + else if(isUniqueKey()) + { + if(isForeignKey()) + { + if(getOwnerColumn()->isForeignKeyFromPk()) + { + icon = wxBitmap(*ddforeignkeyuniquekey_png_img); + } + else + { + icon = wxBitmap(*ddforeignkeyuniquekeyfromuk_png_img); + } + + } + else if(isPrimaryKey()) + { + icon = wxBitmap(*ddprimarykeyuniquekey_png_img); + } + else + { + icon = wxBitmap(*ddunique_png_img); + } + + } + else if(isForeignKey() && !isPrimaryKey() && !isUniqueKey() ) + { + + if(getOwnerColumn()->isForeignKeyFromPk()) + { + icon = wxBitmap(*ddforeignkey_png_img); + } + else + { + icon = wxBitmap(*ddforeignkeyfromuk_png_img); + } + } + + + if(isNone()) + { + iconToDraw = NULL; + } + else + { + iconToDraw = &icon; + } +} + +bool ddColumnKindIcon::isPrimaryKey() +{ + return isPk; +} + +bool ddColumnKindIcon::isUniqueKey() +{ + return ukIndex >= 0; +} + +bool ddColumnKindIcon::isUniqueKey(int uniqueIndex) +{ + return (ukIndex == uniqueIndex); +} + +bool ddColumnKindIcon::isNone() +{ + return !isUniqueKey() && !isPrimaryKey() && !isForeignKey(); +} +bool ddColumnKindIcon::isForeignKey() +{ + return getOwnerColumn()->isForeignKey(); +} + +void ddColumnKindIcon::disableUniqueKey() +{ + syncUkIndexes(); //prepare to remove uk attribute to this column + ukIndex = -1; + getOwnerColumn()->getOwnerTable()->updateFkObservers(); + setRightIconForColumn(); +} + +void ddColumnKindIcon::disablePrimaryKey() +{ + getOwnerColumn()->getOwnerTable()->prepareForDeleteFkColumn(getOwnerColumn()); + isPk = false; + getOwnerColumn()->getOwnerTable()->updateFkObservers(); + setRightIconForColumn(); +} + +void ddColumnKindIcon::enablePrimaryKey() +{ + isPk = true; + getOwnerColumn()->getOwnerTable()->updateFkObservers(); + setRightIconForColumn(); +} + +//Only used for figures created from storage +void ddColumnKindIcon::setPrimaryKey(bool value) +{ + isPk = value; + setRightIconForColumn(); +} + +//Only used for figures created from storage +void ddColumnKindIcon::setUkIndex(int ukIdx) +{ + ukIndex = ukIdx; +} diff --git a/dd/dditems/figures/ddColumnOptionIcon.cpp b/dd/dditems/figures/ddColumnOptionIcon.cpp new file mode 100644 index 0000000..d79f61e --- /dev/null +++ b/dd/dditems/figures/ddColumnOptionIcon.cpp @@ -0,0 +1,128 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddColumnOptionIcon.cpp - Part of composite column figure, allow to choose between: not null and null +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "dd/dditems/figures/ddColumnOptionIcon.h" +#include "hotdraw/main/hdDrawingView.h" +#include "dd/dditems/figures/ddColumnFigure.h" + +//Images +#include "images/ddnull.pngc" +#include "images/ddnotnull.pngc" + +ddColumnOptionIcon::ddColumnOptionIcon(ddColumnFigure *owner) +{ + setKindId(DDCOLUMNOPTIONICON); + ownerColumn = owner; + colOption = null; + icon = wxBitmap(*ddnull_png_img); + iconToDraw = &icon; + getBasicDisplayBox().SetSize(wxSize(getWidth(), getHeight())); + + //Set Value default Attributes + fontAttribute->font().SetPointSize(owner->fontAttribute->font().GetPointSize()); +} + +ddColumnOptionIcon::~ddColumnOptionIcon() +{ +} + +void ddColumnOptionIcon::createMenu(wxMenu &mnu) +{ + wxMenuItem *item; + + item = mnu.AppendCheckItem(MNU_COLNULL, _("NULL")); + item->Check(colOption == null); + item->Enable(!getOwnerColumn()->isGeneratedForeignKey()); + item = mnu.AppendCheckItem(MNU_COLNOTNULL, _("Not NULL")); + item->Check(colOption == notnull); + item->Enable(!getOwnerColumn()->isGeneratedForeignKey()); +} + +void ddColumnOptionIcon::OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view) +{ + changeIcon((ddColumnOptionType)event.GetId()); +} + +void ddColumnOptionIcon::changeIcon(ddColumnOptionType type) +{ + colOption = type; + switch(type) + { + case MNU_COLNULL: + icon = wxBitmap(*ddnull_png_img); + if(getOwnerColumn()->isPrimaryKey()) + { + if(getOwnerColumn()->isForeignKey() || getOwnerColumn()->isUniqueKey()) + { + getOwnerColumn()->toggleColumnKind(pk); //remove pk attribute because column now is null + getOwnerColumn()->setRightIconForColumn(); + } + else + { + getOwnerColumn()->disablePrimaryKey(); + } + } + break; + case MNU_COLNOTNULL: + icon = wxBitmap(*ddnotnull_png_img); + break; + } + getBasicDisplayBox().SetSize(wxSize(getWidth(), getHeight())); +} + +void ddColumnOptionIcon::basicDraw(wxBufferedDC &context, hdDrawingView *view) +{ + if(iconToDraw) + { + hdRect copy = displayBox().gethdRect(view->getIdx()); + view->CalcScrolledPosition(copy.x, copy.y, ©.x, ©.y); + context.DrawBitmap(*iconToDraw, copy.GetPosition(), true); + } +} + +void ddColumnOptionIcon::basicDrawSelected(wxBufferedDC &context, hdDrawingView *view) +{ + basicDraw(context, view); +} + +int ddColumnOptionIcon::getWidth() +{ + if(iconToDraw) + return iconToDraw->GetWidth(); + else + return 8; +} + +int ddColumnOptionIcon::getHeight() +{ + if(iconToDraw) + return iconToDraw->GetHeight(); + else + return 10; +} + +ddColumnOptionType ddColumnOptionIcon::getOption() +{ + return colOption; +} + +ddColumnFigure *ddColumnOptionIcon::getOwnerColumn() +{ + return ownerColumn; +} diff --git a/dd/dditems/figures/ddRelationshipFigure.cpp b/dd/dditems/figures/ddRelationshipFigure.cpp new file mode 100644 index 0000000..008d18d --- /dev/null +++ b/dd/dditems/figures/ddRelationshipFigure.cpp @@ -0,0 +1,930 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddRelationshipFigure.cpp - Figure to draw foreign keys between tables. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "dd/dditems/figures/ddRelationshipFigure.h" +#include "dd/dditems/figures/ddRelationshipItem.h" +#include "dd/ddmodel/ddDrawingEditor.h" +#include "dd/ddmodel/ddDatabaseDesign.h" +#include "dd/dditems/utilities/ddDataType.h" +#include "dd/dditems/utilities/ddSelectKindFksDialog.h" +#include "hotdraw/utilities/hdRemoveDeleteDialog.h" + + +ddRelationshipFigure::ddRelationshipFigure(): + hdLineConnection() +{ + constraintName = wxEmptyString; + setKindId(DDRELATIONSHIPFIGURE); + fkFromPk = true; + fkMandatory = true; + fkOneToMany = true; + fkIdentifying = false; + matchSimple = false; + ukIndex = -1; + disconnectedEndTable = NULL; + paintingFkColumns = false; + //DEFERRABLE, NOT DEFERRABLE, INITIALLY IMMEDIATE, INITIALLY DEFERRED can be added in a future + onUpdateAction = FK_ACTION_NO; + onDeleteAction = FK_ACTION_NO; + enablePopUp(); +} + +ddRelationshipFigure::ddRelationshipFigure(int posIdx, hdIFigure *figure1, hdIFigure *figure2): + hdLineConnection(posIdx, figure1, figure2) +{ + enablePopUp(); +} + +ddRelationshipFigure::~ddRelationshipFigure() +{ + columnsHashMap::iterator it; + ddRelationshipItem *item; + for (it = chm.begin(); it != chm.end(); ++it) + { + wxString key = it->first; + item = it->second; + delete item; + } + chm.clear(); +} + +wxString ddRelationshipFigure::getConstraintName() +{ + return constraintName; +} + +//This function avoid a bug with recursive indentifying relationships when +//a column is removed from pk or delete. +void ddRelationshipFigure::prepareFkForDelete(ddColumnFigure *column) +{ + ddTableFigure *endTable = (ddTableFigure *) getEndFigure(); + ddRelationshipItem *fkColumnRelItem; + + columnsHashMap::iterator it; + for (it = chm.begin(); it != chm.end(); ++it) + { + fkColumnRelItem = it->second; + if(fkColumnRelItem->original == column) + fkColumnRelItem->original = NULL; + } + //go recursive to next table + if(endTable) + endTable->prepareForDeleteFkColumn(column); +} + +void ddRelationshipFigure::updateForeignKey() +{ + if(getEndFigure() && getStartFigure() && getStartFigure()->ms_classInfo.IsKindOf(&ddTableFigure::ms_classInfo) && getEndFigure()->ms_classInfo.IsKindOf(&ddTableFigure::ms_classInfo)) + { + ddTableFigure *startTable = (ddTableFigure *) getStartFigure(); + ddTableFigure *endTable = (ddTableFigure *) getEndFigure(); + ddColumnFigure *col; + ddRelationshipItem *fkColumnRelItem; + + //STEP 0: Look for changes on source columns names and short table names. + + //Before iterate over all columns of source table look if any column used at relationship + //and changed their name and updated it when needed + columnsHashMap::iterator it; + for (it = chm.begin(); it != chm.end(); ++it) + { + wxString key = it->first; + fkColumnRelItem = it->second; + if(fkColumnRelItem->original != NULL) //original column wasn't mark for delete. + { + //if autonaming is set on this item and column name at original source column of fk have been changed + if(!fkColumnRelItem->original->getColumnName(false).IsSameAs(fkColumnRelItem->originalStartColName, false)) + { + chm[fkColumnRelItem->original->getColumnName(false)] = fkColumnRelItem; + chm[fkColumnRelItem->originalStartColName] = NULL; + chm.erase(it); + fkColumnRelItem->syncAutoFkName(); + break; + } + } + } + + //STEP 1: Look at all source table columns add and delete fk + hdIteratorBase *iterator = startTable->figuresEnumerator(); + iterator->Next(); //first figure is main rect + iterator->Next(); //second figure is table title + while(iterator->HasNext()) + { + col = (ddColumnFigure *) iterator->Next(); + if(fkFromPk) //fk is generated from a pk column: add new fk/pk(s) column(s) from source fk table to destination + { + //STEP 1.1a: Add fk columns from table source pk if not exists using same name + it = chm.find(col->getColumnName()); + bool NotFound = it == chm.end(); + + if( col->isPrimaryKey() && NotFound ) + { + fkColumnRelItem = new ddRelationshipItem(this, col, endTable, (fkMandatory ? notnull : null), (fkIdentifying ? pk : none) ); + chm[col->getColumnName()] = fkColumnRelItem; //hashmap key will be original table name always + endTable->addColumn(0, fkColumnRelItem->fkColumn); + updateConnection(0); + } + + //STEP 1.2a: Delete old Fk columns not pk now or deleted from source fk table. + //This part of code (repeat) is a hack cause every time a column is delete hashmap is modified inside and becomes invalid iterator at that loop + bool repeat; + do + { + repeat = false; + for (it = chm.begin(); it != chm.end(); ++it) + { + wxString key = it->first; + fkColumnRelItem = it->second; + if( fkColumnRelItem->original == NULL || !fkColumnRelItem->original->isPrimaryKey() || !startTable->includes(fkColumnRelItem->original) ) //order matters fkColumnRelItem->original==NULL short circuit evaluation should be first + { + if(fkColumnRelItem->isAutomaticallyGenerated()) //don't remove from fk_dest table fk column created from existing column, just mark now as not foreign key + { + fkColumnRelItem->getDestinationTable()->removeColumn(0, fkColumnRelItem->fkColumn); + } + else + { + fkColumnRelItem->fkColumn->setAsUserCreatedFk(NULL); + } + chm.erase(it); + delete fkColumnRelItem; + repeat = true; + updateConnection(0); + } + if (repeat) + break; + } + } + while(repeat); + } + else //fk is generated from a uk column: add new fk/pk(s) column(s) from source fk table to destination + { + //STEP 1.1b: Add fk columns from table source uk if not exists + columnsHashMap::iterator it = chm.find(col->getColumnName()); + bool NotFound = it == chm.end(); + + if( col->isUniqueKey(ukIndex) && NotFound ) + { + fkColumnRelItem = new ddRelationshipItem(this, col, endTable, (fkMandatory ? notnull : null), (fkIdentifying ? pk : none) ); + chm[col->getColumnName()] = fkColumnRelItem; //hashmap key will be original table name always + endTable->addColumn(0, fkColumnRelItem->fkColumn); + updateConnection(0); + } + + //STEP 1.2b: Delete old Fk columns not pk now or deleted from source fk table. + //This part of code (repeat) is a hack cause every time a column is delete hashmap is modified inside and becomes invalid iterator at that loop + bool repeat; + do + { + repeat = false; + for (it = chm.begin(); it != chm.end(); ++it) + { + wxString key = it->first; + fkColumnRelItem = it->second; + if( fkColumnRelItem->original == NULL || !fkColumnRelItem->original->isUniqueKey(ukIndex) || !startTable->includes(fkColumnRelItem->original) ) //order matters fkColumnRelItem->original==NULL short circuit evaluation should be first + { + if(fkColumnRelItem->isAutomaticallyGenerated()) //don't remove from fk_dest table fk column created from existing column, just mark now as not foreign key + { + fkColumnRelItem->getDestinationTable()->removeColumn(0, fkColumnRelItem->fkColumn); + } + else + { + fkColumnRelItem->fkColumn->setAsUserCreatedFk(NULL); + } + chm.erase(it); + delete fkColumnRelItem; + repeat = true; + updateConnection(0); + } + if (repeat) + break; + } + } + while(repeat); + + } + } + delete iterator; + //Now if relationship is an identifying one, I should alert all observers of my observer to update it. + if(fkIdentifying) + { + if(endTable) + endTable->updateFkObservers(); + } + } + else + { + wxMessageBox(wxT("Error invalid kind of start figure at relationship"), wxT("Error invalid kind of start figure at relationship"), wxICON_ERROR | wxOK); + } +} + +void ddRelationshipFigure::createMenu(wxMenu &mnu) +{ + wxMenu *submenu; + wxMenuItem *item; + wxString tmp; + + submenu = new wxMenu(_("Select one")); + + tmp = _("Foreign Key From"); + mnu.AppendSubMenu(submenu, tmp); + item = submenu->AppendCheckItem(MNU_FKEYFROMPKEY, _("Primary Key")); + item->Check(fkFromPk); + + if(getStartFigure()) + { + ddTableFigure *startTable = (ddTableFigure *) getStartFigure(); + int i, last = startTable->getUkConstraintsNames().Count(); + int eventID; //Hack to allow multiple submenu items for select uk as fk origin + for(i = 0; i < last; i++) + { + eventID = MNU_FKEYFROMUKEYBASE + i; + tmp = _("Unique Key: "); + tmp += startTable->getUkConstraintsNames()[i]; + item = submenu->AppendCheckItem(eventID, tmp ); + item->Check(!fkFromPk && ukIndex == i); + } + } + mnu.AppendSeparator(); + //disable right now item = mnu.AppendCheckItem(MNU_FKEYCUSTOMMAPPING, _("Foreign Key Columns Custom Mapping")); + item = mnu.AppendCheckItem(MNU_MANDATORYRELATIONSHIP, _("Mandatory relationship kind")); + item->Check(fkMandatory); + item = mnu.AppendCheckItem(MNU_IDENTIFYINGRELATIONSHIP, _("Identifying relationship")); + item->Check(fkIdentifying); + mnu.AppendSeparator(); + item = mnu.AppendCheckItem(MNU_1MRELATIONSHIP, _("1:M")); + item->Check(fkOneToMany); + mnu.AppendSeparator(); + mnu.Append(MNU_FKCONSTRAINTNAME, _("Foreign Key Constraint Name")); + + submenu = new wxMenu(_("Select one")); + item = submenu->AppendCheckItem(MNU_FKMATCHTYPESIMPLE, _("Type Simple")); + item->Check(matchSimple); + item = submenu->AppendCheckItem(MNU_FKMATCHTYPEFULL, _("Type Full")); + item->Check(!matchSimple); + tmp = _("Match Type "); + if(matchSimple) + tmp += _("[ Simple ]"); + else + tmp += _("[ Full ]"); + mnu.AppendSubMenu(submenu, tmp); + + tmp = _("On Delete "); + submenu = new wxMenu(_("Select one")); + item = submenu->AppendCheckItem(MNU_FKONDELETENOACTION, _("No Action")); + item->Check(onDeleteAction == FK_ACTION_NO); + if(onDeleteAction == FK_ACTION_NO) + tmp += _("[ No Action ]"); + item = submenu->AppendCheckItem(MNU_FKONDELETERESTRICT, _("Restrict")); + item->Check(onDeleteAction == FK_RESTRICT); + if(onDeleteAction == FK_RESTRICT) + tmp += _("[ Restrict ]"); + item = submenu->AppendCheckItem(MNU_FKONDELETECASCADE, _("Cascade")); + item->Check(onDeleteAction == FK_CASCADE); + if(onDeleteAction == FK_CASCADE) + tmp += _("[ Cascade ]"); + item = submenu->AppendCheckItem(MNU_FKONDELETESETNULL, _("Set Null")); + item->Check(onDeleteAction == FK_SETNULL); + if(onDeleteAction == FK_SETNULL) + tmp += _("[ Set Null ]"); + item = submenu->AppendCheckItem(MNU_FKONDELETESETDEFAULT, _("Set Default")); + item->Check(onDeleteAction == FK_SETDEFAULT); + if(onDeleteAction == FK_SETDEFAULT) + tmp += _("[ Set Default ]"); + mnu.AppendSubMenu(submenu, tmp); + + tmp = _("On Update "); + submenu = new wxMenu(_("Select one")); + item = submenu->AppendCheckItem(MNU_FKONUPDATENOACTION, _("No Action")); + item->Check(onUpdateAction == FK_ACTION_NO); + if(onUpdateAction == FK_ACTION_NO) + tmp += _("[ No Action ]"); + item = submenu->AppendCheckItem(MNU_FKONUPDATERESTRICT, _("Restrict")); + item->Check(onUpdateAction == FK_RESTRICT); + if(onUpdateAction == FK_RESTRICT) + tmp += _("[ Restrict ]"); + item = submenu->AppendCheckItem(MNU_FKONUPDATECASCADE, _("Cascade")); + item->Check(onUpdateAction == FK_CASCADE); + if(onUpdateAction == FK_CASCADE) + tmp += _("[ Cascade ]"); + item = submenu->AppendCheckItem(MNU_FKONUPDATESETNULL, _("Set Null")); + item->Check(onUpdateAction == FK_SETNULL); + if(onUpdateAction == FK_SETNULL) + tmp += _("[ Set Null ]"); + item = submenu->AppendCheckItem(MNU_FKONUPDATESETDEFAULT, _("Set Default")); + item->Check(onUpdateAction == FK_SETDEFAULT); + if(onUpdateAction == FK_SETDEFAULT) + tmp += _("[ Set Default ]"); + mnu.AppendSubMenu(submenu, tmp); + + mnu.AppendSeparator(); + mnu.Append(MNU_DELETERELATIONSHIP, _("Delete Relationship...")); +}; + +void ddRelationshipFigure::OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view) +{ + int answer; + ddTableFigure *startTable = NULL; + ddTableFigure *endTable = NULL; + wxTextEntryDialog *nameDialog = NULL; + hdRemoveDeleteDialog *delremDialog = NULL; + ddSelectKindFksDialog *mappingDialog = NULL; + wxString tmpString; + + switch(event.GetId()) + { + case MNU_MANDATORYRELATIONSHIP: + fkMandatory = !fkMandatory; + if(fkMandatory) + { + setLinePen(wxPen(*wxBLACK_PEN)); + setOptionAtForeignKeys(notnull); + } + else + { + fkIdentifying = false; + setLinePen(wxPen(*wxBLACK, 1, wxSHORT_DASH)); + setOptionAtForeignKeys(null); + } + view->notifyChanged(); + break; + case MNU_IDENTIFYINGRELATIONSHIP: + fkMandatory = true; + setLinePen(wxPen(*wxBLACK_PEN)); + fkIdentifying = !fkIdentifying; + fkOneToMany = true; + updatePkAtFkCols(); + view->notifyChanged(); + break; + case MNU_FKCONSTRAINTNAME: + startTable = (ddTableFigure *) getStartFigure(); + endTable = (ddTableFigure *) getEndFigure(); + if(constraintName.IsEmpty() && startTable && endTable ) + { + constraintName = endTable->getTableName(); + constraintName += _("_"); + constraintName += startTable->getTableName(); + } + nameDialog = new wxTextEntryDialog(view, wxT("Change Constraint Name"), wxT("Constraint Name"), constraintName ); + answer = nameDialog->ShowModal(); + if (answer == wxID_OK) + { + tmpString = nameDialog->GetValue(); + constraintName = tmpString; + view->notifyChanged(); + } + delete nameDialog; + break; + case MNU_FKMATCHTYPEFULL: + matchSimple = false; + view->notifyChanged(); + break; + case MNU_FKMATCHTYPESIMPLE: + matchSimple = true; + view->notifyChanged(); + break; + case MNU_FKONDELETENOACTION: + onDeleteAction = FK_ACTION_NO; + view->notifyChanged(); + break; + case MNU_FKONDELETERESTRICT: + onDeleteAction = FK_RESTRICT; + view->notifyChanged(); + break; + case MNU_FKONDELETECASCADE: + onDeleteAction = FK_CASCADE; + view->notifyChanged(); + break; + case MNU_FKONDELETESETNULL: + onDeleteAction = FK_SETNULL; + view->notifyChanged(); + break; + case MNU_FKONDELETESETDEFAULT: + onDeleteAction = FK_SETDEFAULT; + view->notifyChanged(); + break; + + case MNU_FKONUPDATENOACTION: + onUpdateAction = FK_ACTION_NO; + view->notifyChanged(); + break; + case MNU_FKONUPDATERESTRICT: + onUpdateAction = FK_RESTRICT; + view->notifyChanged(); + break; + case MNU_FKONUPDATECASCADE: + onUpdateAction = FK_CASCADE; + view->notifyChanged(); + break; + case MNU_FKONUPDATESETNULL: + onUpdateAction = FK_SETNULL; + view->notifyChanged(); + break; + case MNU_FKONUPDATESETDEFAULT: + onUpdateAction = FK_SETDEFAULT; + view->notifyChanged(); + break; + case MNU_1MRELATIONSHIP: + fkOneToMany = !fkOneToMany; + view->notifyChanged(); + break; + case MNU_DELETERELATIONSHIP: + if(getStartFigure() && getEndFigure()) + { + ddTableFigure *t1 = (ddTableFigure *)getStartFigure(); + ddTableFigure *t2 = (ddTableFigure *)getEndFigure(); + //Relationship can be delete only NOT REMOVED + delremDialog = new hdRemoveDeleteDialog( + wxString::Format(_("Are you sure you wish to delete relationship between tables %s and %s?"), + t1->getTableName().c_str(), t2->getTableName().c_str()), + _("Delete relationship?"), + (wxScrolledWindow *)view, + false); + answer = delremDialog->ShowModal(); + ddDrawingEditor *editor = (ddDrawingEditor *) view->editor(); + if (answer == DD_DELETE) + { + editor->removeFromAllSelections(this); + removeForeignKeys(); + disconnectStart(); + disconnectEnd(); + //Hack to autodelete relationship + ddRelationshipFigure *r = this; + if(r) + editor->deleteModelFigure(r); + editor->getDesign()->refreshBrowser(); + view->notifyChanged(); + } + else if(answer == DD_REMOVE) + { + editor->getExistingDiagram(view->getIdx())->removeFromSelection(this); + editor->getExistingDiagram(view->getIdx())->remove(this); + view->notifyChanged(); + } + delete delremDialog; + } + break; + case MNU_FKEYFROMPKEY: + fkFromPk = true; + updateForeignKey(); + view->notifyChanged(); + break; + case MNU_FKEYCUSTOMMAPPING: + //disable right now + /* + mappingDialog = new ddSelectKindFksDialog(view,this); + mappingDialog->ShowModal(); + delete mappingDialog; + */ + break; + default: + //Hack to allow multiple selection of Uk in submenu + answer = event.GetId(); + if( answer >= MNU_FKEYFROMUKEYBASE) + { + fkFromPk = false; + ukIndex = answer - MNU_FKEYFROMUKEYBASE; + updateForeignKey(); + view->notifyChanged(); + } + break; + } +} + +bool ddRelationshipFigure::getIdentifying() +{ + return fkIdentifying; +} + +bool ddRelationshipFigure::getOneToMany() +{ + return fkOneToMany; +} + +bool ddRelationshipFigure::getMandatory() +{ + return fkMandatory; +} + + +// relationship is observed by several tables at same time, one is the +// owner (start connector table) others are just observers of that +// relationship (end connectors table) +void ddRelationshipFigure::connectEnd(hdIConnector *end, hdDrawingView *view) +{ + ddSelectKindFksDialog *mappingDialog = NULL; + hdLineConnection::connectEnd(end); + if(view) + view->Refresh(); + + //Hack to allow abort of mapping of Fk + int answer = -1; //By default + + //If connecte destination and start figure + if(getEndFigure() && getStartFigure()) + { + mappingDialog = new ddSelectKindFksDialog(view, this); + answer = mappingDialog->ShowModal(); + delete mappingDialog; + if(answer == wxID_OK) + { + if(view) + { + view->AcceptsFocus(); + view->SetFocus(); + } + updateForeignKey(); + } + } + + //Is Start is connected Tell to check consistency + if(getStartFigure()) + { + getStartTable()->setSelectFkDestMode(false); + ddDrawingEditor *editor = (ddDrawingEditor *) view->editor(); + editor->checkAllDigramsRelConsistency(); + } + + //Hack to Abort Connection because user press cancel button at fk mapping dialog + if (answer == wxID_CANCEL) + { + //By disconnecting both sides I force to delete relationship at ConnectionCreationTool + getStartTable()->setSelectFkDestMode(false); + this->disconnectStart(); + this->disconnectEnd(); + } +} + +bool ddRelationshipFigure::isForeignKeyFromPk() +{ + return fkFromPk; +} + +void ddRelationshipFigure::setFkFrom(bool primaryKey, int useUkIndex, bool issueUpdateFk) +{ + if(useUkIndex >= 0) + { + fkFromPk = false; + ukIndex = useUkIndex; + } + else + { + fkFromPk = true; + ukIndex = -1; + } + + if(issueUpdateFk) + updateForeignKey(); +} + +void ddRelationshipFigure::connectStart(hdIConnector *start, hdDrawingView *view) +{ + hdLineConnection::connectStart(start); + if(getEndFigure() && getStartFigure()) + updateForeignKey(); +} + +void ddRelationshipFigure::disconnectStart(hdDrawingView *view) +{ + paintingFkColumns = false; + changeFkOSTextColor( *wxBLACK, *wxBLACK, true ); + disconnectedEndTable = (ddTableFigure *) getEndFigure(); + removeForeignKeys(); + hdLineConnection::disconnectStart(); +} + +void ddRelationshipFigure::disconnectEnd(hdDrawingView *view) +{ + paintingFkColumns = false; + changeFkOSTextColor( *wxBLACK, *wxBLACK, true ); + disconnectedEndTable = (ddTableFigure *) getEndFigure(); + hdLineConnection::disconnectEnd(); + removeForeignKeys(); +} + +void ddRelationshipFigure::addExistingColumnFk(ddColumnFigure *startTablesourceCol, wxString destColumn) +{ + ddTableFigure *endTable = (ddTableFigure *) getEndFigure(); + ddRelationshipItem *fkColumnRelItem; + ddColumnFigure *endTablesourceCol = endTable->getColumnByName(destColumn); + //Create a new relationship item but with an existing column for fk at destination table + if(endTablesourceCol) + { + fkColumnRelItem = new ddRelationshipItem(this, startTablesourceCol, endTable, (fkMandatory ? notnull : null), (fkIdentifying ? pk : noaction), endTablesourceCol); + //Mark it as Custom Fk (fk from existing column not an automatic generated) + endTablesourceCol->setAsUserCreatedFk(fkColumnRelItem); + chm[startTablesourceCol->getColumnName()] = fkColumnRelItem; //hashmap key will be original table name always + updateConnection(0); + } +} + +void ddRelationshipFigure::removeForeignKeys() +{ + if(disconnectedEndTable) + { + columnsHashMap::iterator it; + ddRelationshipItem *fkColumnRelItem; + + //This part of code (repeat) is a hack cause every time a column is delete hashmap is modified inside and becomes invalid iterator at that loop + bool repeat; + do + { + repeat = false; + for( it = chm.begin(); it != chm.end(); ++it ) + { + wxString key = it->first; + fkColumnRelItem = it->second; + if(fkColumnRelItem->getDestinationTable()->includes(fkColumnRelItem->fkColumn)) + { + //Remove fk column only if that column is automatically generated + if(fkColumnRelItem->isAutomaticallyGenerated()) + { + fkColumnRelItem->getDestinationTable()->removeColumn(0, fkColumnRelItem->fkColumn); + } //is an existing column use as fk + else + { + //Mark as existing column not used as foreign key destination + fkColumnRelItem->fkColumn->setAsUserCreatedFk(NULL); + } + chm.erase(it); + delete fkColumnRelItem; + repeat = true; + break; + } + } + } + while(repeat); + chm.clear(); + disconnectedEndTable = NULL; + } +} + +void ddRelationshipFigure::setOptionAtForeignKeys(ddColumnOptionType type) +{ + columnsHashMap::iterator it; + ddRelationshipItem *item; + for (it = chm.begin(); it != chm.end(); ++it) + { + wxString key = it->first; + item = it->second; + if(item->isAutomaticallyGenerated()) + item->fkColumn->setColumnOption(type); + } +} + +void ddRelationshipFigure::updatePkAtFkCols() +{ + bool changed = false; + columnsHashMap::iterator it; + ddRelationshipItem *item; + for (it = chm.begin(); it != chm.end(); ++it) + { + wxString key = it->first; + item = it->second; + if(item->isAutomaticallyGenerated()) //only update fk status at fk NOT created from an existing column + { + if(fkIdentifying) + { + item->fkColumn->enablePrimaryKey(); + } + else + { + item->fkColumn->disablePrimaryKey(); + } + changed = true; + } + } + + if(changed) //set as identifying relationship (hierarchy) + { + ddTableFigure *table = (ddTableFigure *) getEndFigure(); + table->updateFkObservers(); + } +} +wxString ddRelationshipFigure::generateSQL(wxString schemaName) +{ + wxString tmp; + if(chm.size() > 0) + { + tmp = wxT("\nALTER TABLE "); + if(!schemaName.IsEmpty()) + tmp += wxT("\"") + schemaName + wxT("\"."); + tmp += wxT("\"") + ((ddTableFigure *)getEndFigure())->getTableName() + wxT("\"") ; + + tmp += wxT(" ADD "); + if(!constraintName.IsEmpty()) + { + tmp += wxT("CONSTRAINT \"") + constraintName + wxT("\" "); + } + tmp += wxT("FOREIGN KEY ( "); + columnsHashMap::iterator it, end; + ddRelationshipItem *item; + for( it = chm.begin(); it != chm.end(); ++it ) + { + wxString key = it->first; + item = it->second; + tmp += wxT("\"") + item->fkColumn->getColumnName() + wxT("\""); + end = it; + end++; + if(end != chm.end()) + { + tmp += wxT(" , "); + } + else + { + tmp += wxT(" )"); + } + } + + tmp += wxT(" REFERENCES "); + if(!schemaName.IsEmpty()) + tmp += wxT("\"") + schemaName + _("\"."); + tmp += wxT("\"") + ((ddTableFigure *)getStartFigure())->getTableName() + wxT("\"") ; + + tmp += wxT(" ( "); + for( it = chm.begin(); it != chm.end(); ++it ) + { + wxString key = it->first; + item = it->second; + tmp += wxT("\"") + item->original->getColumnName() + wxT("\""); + end = it; + end++; + if(end != chm.end()) + { + tmp += wxT(" , "); + } + else + { + tmp += wxT(" )"); + } + } + + if(matchSimple) + tmp += wxT(" MATCH SIMPLE "); + else + tmp += wxT(" MATCH FULL "); + + tmp += wxT(" ON DELETE "); + switch(onDeleteAction) + { + case FK_ACTION_NO: + tmp += wxT(" NO ACTION "); + break; + case FK_RESTRICT: + tmp += wxT(" RESTRICT "); + break; + case FK_CASCADE: + tmp += wxT(" CASCADE "); + break; + case FK_SETNULL: + tmp += wxT(" SET NULL "); + break; + case FK_SETDEFAULT: + tmp += wxT(" SET DEFAULT "); + break; + } + + tmp += wxT(" ON UPDATE "); + switch(onUpdateAction) + { + case FK_ACTION_NO: + tmp += wxT(" NO ACTION "); + break; + case FK_RESTRICT: + tmp += wxT(" RESTRICT "); + break; + case FK_CASCADE: + tmp += wxT(" CASCADE "); + break; + case FK_SETNULL: + tmp += wxT(" SET NULL "); + break; + case FK_SETDEFAULT: + tmp += wxT(" SET DEFAULT "); + break; + } + + tmp += _(";\n"); + } + return tmp; +} + +ddTableFigure *ddRelationshipFigure::getStartTable() +{ + return (ddTableFigure *) getStartFigure(); +} + +ddTableFigure *ddRelationshipFigure::getEndTable() +{ + return (ddTableFigure *) getEndFigure(); +} + +void ddRelationshipFigure::basicDrawSelected(wxBufferedDC &context, hdDrawingView *view) +{ + hdLineConnection::basicDrawSelected(context, view); + if(getEndFigure() && getStartFigure()) + { + paintingFkColumns = true; + changeFkOSTextColor(wxColour(255, 0, 0), wxColour(255, 0, 0)); + } +} + +void ddRelationshipFigure::basicDraw(wxBufferedDC &context, hdDrawingView *view) +{ + hdLineConnection::basicDraw(context, view); + if(getEndFigure() && getStartFigure() && paintingFkColumns) + { + paintingFkColumns = false; + changeFkOSTextColor( *wxBLACK, *wxBLACK, true ); + } +} + +void ddRelationshipFigure::changeFkOSTextColor(wxColour originalColour, wxColour fkColour, bool reset) +{ + columnsHashMap::iterator it; + ddRelationshipItem *item; + for (it = chm.begin(); it != chm.end(); ++it) + { + wxString key = it->first; + item = it->second; + if(item->original) + { + if(!reset) + item->original->setTextColour(originalColour); + else + item->original->setTextColour(item->original->getOwnerTable()->fontColorAttribute->fontColor); + + } + if(item->fkColumn) + { + if(!reset) + item->fkColumn->setTextColour(fkColour); + else + item->fkColumn->setTextColour(item->fkColumn->getOwnerTable()->fontColorAttribute->fontColor); + } + } + +} + +//Used by persistence classes +int ddRelationshipFigure::getUkIndex() +{ + return ukIndex; +} + +//Used by persistence classes +actionKind ddRelationshipFigure::getOnUpdateAction() +{ + return onUpdateAction; +} + +//Used by persistence classes +actionKind ddRelationshipFigure::getOnDeleteAction() +{ + return onDeleteAction; +} + +//Used by persistence classes +bool ddRelationshipFigure::getMatchSimple() +{ + return matchSimple; +} + +//Used by persistence classes +void ddRelationshipFigure::initRelationValues( ddTableFigure *source, ddTableFigure *destination, int ukIdx, wxString constraint, actionKind onUpdate, actionKind onDelete, bool simpleMatch, bool identifying, bool oneToMany, bool mandatory, bool fromPk ) +{ + ukIndex = ukIdx; + fkFromPk = fromPk; + fkMandatory = mandatory; + fkOneToMany = oneToMany; + fkIdentifying = identifying; + matchSimple = simpleMatch; + onUpdateAction = onUpdate; + onDeleteAction = onDelete; + constraintName = constraint; + + //I need to add two points to relationship if there aren't any points for it a first position + int i, start = pointCount(0); + for(i = start; i < 2 ; i++) + { + addPoint(0, -100, -100); + } + + //reestablish connections between figures + hdLineConnection::connectStart(source->connectorAt(0, getStartPoint(0).x, getStartPoint(0).y)); + hdLineConnection::connectEnd(destination->connectorAt(0, getEndPoint(0).x, getEndPoint(0).y)); +} diff --git a/dd/dditems/figures/ddRelationshipItem.cpp b/dd/dditems/figures/ddRelationshipItem.cpp new file mode 100644 index 0000000..f820704 --- /dev/null +++ b/dd/dditems/figures/ddRelationshipItem.cpp @@ -0,0 +1,132 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddRelationshipItem.cpp - Items (fk columns) inside a relationship figure hashmap +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "dd/dditems/figures/ddRelationshipItem.h" +#include "dd/dditems/figures/ddRelationshipFigure.h" +#include "hotdraw/main/hdDrawingView.h" +#include "dd/dditems/utilities/ddDataType.h" + +ddRelationshipItem::ddRelationshipItem() +{ + ownerRel = NULL; + original = NULL; + destinationTable = NULL; +} + +ddRelationshipItem::ddRelationshipItem(ddRelationshipFigure *owner, ddColumnFigure *originalColumn, ddTableFigure *destination, ddColumnOptionType type, ddColumnType colType, ddColumnFigure *existingColumn) +{ + ownerRel = owner; + original = originalColumn; + originalStartColName = original->getColumnName(false); + destinationTable = destination; + + if(existingColumn == NULL) //Fk destination column will be automatically generated + { + generatedName = autoGenerateNameForFk(); + fkColumn = new ddColumnFigure( generatedName, destinationTable, this); + fkColumn->setColumnOption(type); + fkColumn->toggleColumnKind(colType); + fkColumn->activateGenFkName(); //By default fk name is generate by using ( alias | tableName) . ColumnName combination + fkIsAutoGenerated = true; + } + else //using existing column as fk destination (Validation Required at user choices compatibility of types, precision and scale) + { + generatedName = wxEmptyString; + fkColumn = existingColumn; + fkColumn->setAsUserCreatedFk(this); + fkColumn->deactivateGenFkName(); + fkIsAutoGenerated = false; + } + + fkColumn->setRightIconForColumn(); +} + +ddRelationshipItem::~ddRelationshipItem() +{ +} + +void ddRelationshipItem::initRelationshipItemValues(ddRelationshipFigure *owner, ddTableFigure *destination, bool fromExistingColumn, ddColumnFigure *fkCol, ddColumnFigure *sourceCol, wxString initialColName) +{ + ownerRel = owner; + destinationTable = destination; + fkIsAutoGenerated = fromExistingColumn; + original = sourceCol; + fkColumn = fkCol; + originalStartColName = initialColName; + if(fkIsAutoGenerated) + fkColumn->setFkSource(this); + else + fkColumn->setAsUserCreatedFk(this); + + fkColumn->setRightIconForColumn(); +} + + +bool ddRelationshipItem::isAutomaticallyGenerated() +{ + return fkIsAutoGenerated; +} + +wxString ddRelationshipItem::autoGenerateNameForFk() +{ + wxString newName; + newName = original->getOwnerTable()->getTableName(); + newName.append(wxT("_")); + newName.append(originalStartColName); + return newName; +} + +void ddRelationshipItem::syncAutoFkName() +{ + originalStartColName = original->getColumnName(false); //Because original name was probably changed, now I should update it. + if(fkColumn->isGeneratedForeignKey() && fkColumn->isFkNameGenerated() ) + { + fkColumn->setColumnName(autoGenerateNameForFk()); + //Update all connections, but need to be notified to all views only doing it right now for first view + ownerRel->updateConnection(0); + } +} + +bool ddRelationshipItem::relationIsIdentifying() +{ + return ownerRel->getIdentifying(); +} + +bool ddRelationshipItem::relationIsMandatory() +{ + return ownerRel->getMandatory(); +} + +wxString ddRelationshipItem::sourceTableName() +{ + return original->getOwnerTable()->getTableName(); +} + +wxString ddRelationshipItem::destTableName() +{ + return destinationTable->getTableName(); +} + +bool ddRelationshipItem::isForeignKeyFromPk() +{ + if(ownerRel) + { + return ownerRel->isForeignKeyFromPk(); + } + return false; +} diff --git a/dd/dditems/figures/ddRelationshipTerminal.cpp b/dd/dditems/figures/ddRelationshipTerminal.cpp new file mode 100644 index 0000000..7d43d77 --- /dev/null +++ b/dd/dditems/figures/ddRelationshipTerminal.cpp @@ -0,0 +1,154 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddRelationshipTerminal.cpp - Draw inverse arrows at fk terminal based on kind of relationship. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "dd/dditems/figures/ddRelationshipTerminal.h" +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/main/hdDrawingView.h" +#include "hotdraw/utilities/hdGeometry.h" + +ddRelationshipTerminal::ddRelationshipTerminal(ddRelationshipFigure *owner, bool endFigureTerminal) +{ + ownerFigure = owner; + endTerminal = endFigureTerminal; +} + +ddRelationshipTerminal::~ddRelationshipTerminal() +{ +} + +hdPoint &ddRelationshipTerminal::draw (wxBufferedDC &context, hdPoint &a, hdPoint &b, hdDrawingView *view) +{ + hdGeometry g; + hdPoint points[3]; + + context.SetPen(terminalLinePen); + + hdPoint aCopy = a, bCopy = b; + view->CalcScrolledPosition(aCopy.x, aCopy.y, &aCopy.x, &aCopy.y); + view->CalcScrolledPosition(bCopy.x, bCopy.y, &bCopy.x, &bCopy.y); + + if(endTerminal) + { + //Calc a point very far away of center of table to intersect one of the sides lines of the table rectangle figure + double X = aCopy.x + (bCopy.x - aCopy.x) * 0.9; + double Y = aCopy.y + (bCopy.y - aCopy.y) * 0.9; + + if(ownerFigure->getEndFigure() && ownerFigure->getOneToMany()) + { + hdRect r = ownerFigure->getEndFigure()->displayBox().gethdRect(view->getIdx()); + + view->CalcScrolledPosition(r.x, r.y, &r.x, &r.y); + + int centerX = r.x + r.width / 2; + int centerY = r.y + r.height / 2; + + context.SetPen(*wxBLACK_PEN); + context.SetBrush(*wxBLACK_BRUSH); + + double XX, YY, distance; + + //Calculate a new point to a given distance from the end of the relationship to draw many ( ----<| ) connector + //first calculate vector from point1 & point2 + double vectorx = aCopy.x - bCopy.x; + double vectory = aCopy.y - bCopy.y; + //calculate the length + double length = sqrt(vectorx * vectorx + vectory * vectory); + //normalize the vector to unit length + double normalizevx = vectorx / length; + double normalizevy = vectory / length; + distance = -15; + //calculate point a given distance + XX = bCopy.x + normalizevx * (length + distance); + YY = bCopy.y + normalizevy * (length + distance); + + wxPoint intersectionLine1(centerX, centerY); + wxPoint intersectionLine2(X, Y); + + //TOP + if(g.intersection(intersectionLine1, intersectionLine2, r.GetTopLeft(), r.GetTopRight())) + { + points[0] = wxPoint(XX, YY); + points[1] = wxPoint(aCopy.x - 7, aCopy.y); + points[2] = wxPoint(aCopy.x + 7, aCopy.y); + context.DrawPolygon(3, points); + + if(ownerFigure->getIdentifying()) + { + context.SetPen(wxPen(*wxBLACK, 2)); + context.DrawLine(wxPoint(XX - 7, YY), wxPoint(XX + 7, YY)); + context.SetPen(*wxBLACK_PEN); + } + + } //RIGHT + else if(g.intersection(intersectionLine1, intersectionLine2, r.GetTopRight(), r.GetBottomRight())) + { + points[0] = wxPoint(XX, YY); + points[1] = wxPoint(aCopy.x, aCopy.y - 7); + points[2] = wxPoint(aCopy.x, aCopy.y + 7); + context.DrawPolygon(3, points); + + if(ownerFigure->getIdentifying()) + { + context.SetPen(wxPen(*wxBLACK, 2)); + context.DrawLine(wxPoint(XX, YY - 7), wxPoint(XX, YY + 7)); + context.SetPen(*wxBLACK_PEN); + } + } //BOTTOM + else if(g.intersection(intersectionLine1, intersectionLine2, r.GetBottomLeft(), r.GetBottomRight())) + { + points[0] = wxPoint(XX, YY); + points[1] = wxPoint(aCopy.x - 7, aCopy.y); + points[2] = wxPoint(aCopy.x + 7, aCopy.y); + context.DrawPolygon(3, points); + + if(ownerFigure->getIdentifying()) + { + context.SetPen(wxPen(*wxBLACK, 2)); + context.DrawLine(wxPoint(XX - 7, YY), wxPoint(XX + 7, YY)); + context.SetPen(*wxBLACK_PEN); + } + } //LEFT + else if(g.intersection(intersectionLine1, intersectionLine2, r.GetTopLeft(), r.GetBottomLeft())) + { + points[0] = wxPoint(XX, YY); + points[1] = wxPoint(aCopy.x, aCopy.y - 7); + points[2] = wxPoint(aCopy.x, aCopy.y + 7); + context.DrawPolygon(3, points); + + if(ownerFigure->getIdentifying()) + { + context.SetPen(wxPen(*wxBLACK, 2)); + context.DrawLine(wxPoint(XX, YY - 7), wxPoint(XX, YY + 7)); + context.SetPen(*wxBLACK_PEN); + } + } + else + { + //CENTER of star figure or invalid place, do nothing + } + + value = hdPoint(XX, YY); + return value; + } + value = hdPoint(0, 0); + return value; + } + value = hdPoint(0, 0); + return value; +} diff --git a/dd/dditems/figures/ddTableFigure.cpp b/dd/dditems/figures/ddTableFigure.cpp new file mode 100644 index 0000000..1290a55 --- /dev/null +++ b/dd/dditems/figures/ddTableFigure.cpp @@ -0,0 +1,1798 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddTableFigure.cpp - Draw table figure of a model +// +//////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/dditems/figures/ddTextTableItemFigure.h" +#include "dd/dditems/figures/ddColumnFigure.h" +#include "hotdraw/main/hdDrawingView.h" +#include "hotdraw/main/hdDrawingEditor.h" +#include "dd/dditems/utilities/ddDataType.h" +#include "dd/dditems/handles/ddAddColButtonHandle.h" +#include "dd/dditems/locators/ddAddColLocator.h" +#include "dd/dditems/handles/ddAddFkButtonHandle.h" +#include "dd/dditems/locators/ddAddFkLocator.h" +#include "dd/dditems/handles/ddRemoveTableButtonHandle.h" +#include "dd/dditems/locators/ddRemoveTableLocator.h" +#include "dd/dditems/handles/ddMinMaxTableButtonHandle.h" +#include "dd/dditems/locators/ddMinMaxTableLocator.h" +#include "dd/dditems/handles/ddScrollBarHandle.h" +#include "dd/dditems/locators/ddScrollBarTableLocator.h" +#include "dd/dditems/handles/ddSouthTableSizeHandle.h" +#include "dd/dditems/locators/ddTableBottomLocator.h" +#include "dd/ddmodel/ddDBReverseEngineering.h" +#include "hotdraw/utilities/hdGeometry.h" +#include "dd/dditems/figures/ddRelationshipFigure.h" +#include "hotdraw/connectors/hdLocatorConnector.h" +#include "hotdraw/main/hdDrawing.h" +#include "dd/ddmodel/ddDatabaseDesign.h" + +//Images +#include "images/ddAddColumn.pngc" +#include "images/ddRemoveColumn.pngc" +#include "images/ddAddForeignKey.pngc" +#include "images/ddMaximizeTable.pngc" +#include "images/ddMinimizeTable.pngc" +#include "images/ddRemoveTable.pngc" + +/* +All figures title, colums, indexes are store at same array to improve performance in the following order: + [0] = table border rect + [1] = table title + [2] = first column index + [maxColIndex] = last column index + [minIdxIndex] = first index index + [maxIdxIndex] = last index index +*/ + +void ddTableFigure::Init(wxString tableName, int x, int y) +{ + setKindId(DDTABLEFIGURE); + internalPadding = 2; + externalPadding = 4; + selectingFkDestination = false; + + //Set Value default Attributes + fontColorAttribute->fontColor = wxColour(49, 79, 79); + //Set Value default selected Attributes + lineSelAttribute->pen().SetColour(wxColour(204, 0, 0)); + lineSelAttribute->pen().SetStyle(wxSOLID); + lineSelAttribute->pen().SetWidth(1); + fillSelAttribute->brush().SetColour(wxColour(255, 250, 205)); + fillAttribute->brush().SetColour(wxColour(248, 248, 255)); + fontSelColorAttribute->fontColor = wxColour(49, 79, 79); + + //Set table size, width and position + rectangleFigure = new hdRectangleFigure(); + rectangleFigure->moveTo(0, x, y); + add(rectangleFigure); + + tableTitle = new ddTextTableItemFigure(tableName, dt_null, NULL); + tableTitle->setOwnerTable(this); + tableTitle->setEditable(true); + tableTitle->moveTo(0, x, y); + tableTitle->disablePopUp(); + tableTitle->setShowDataType(false); + add(tableTitle); + tableTitle->moveTo(0, rectangleFigure->getBasicDisplayBox().x[0] + internalPadding * 2, rectangleFigure->getBasicDisplayBox().y[0] + internalPadding / 2); + + //Intialize handles + wxBitmap image = wxBitmap(*ddAddColumn_png_img); + wxSize valueSize = wxSize(8, 8); + figureHandles->addItem(new ddAddColButtonHandle((hdIFigure *)this, (hdILocator *)new ddAddColLocator(), image, valueSize)); + image = wxBitmap(*ddAddForeignKey_png_img); + figureHandles->addItem(new ddAddFkButtonHandle((hdIFigure *)this, (hdILocator *)new ddAddFkLocator(), image, valueSize)); + image = wxBitmap(*ddRemoveTable_png_img); + figureHandles->addItem(new ddRemoveTableButtonHandle((hdIFigure *)this, (hdILocator *)new ddRemoveTableLocator(), image, valueSize)); + image = wxBitmap(*ddMinimizeTable_png_img); + wxBitmap image2 = wxBitmap(*ddMaximizeTable_png_img); + figureHandles->addItem(new ddMinMaxTableButtonHandle((hdIFigure *)this, (hdILocator *)new ddMinMaxTableLocator(), image, image2, valueSize)); + figureHandles->addItem(new ddSouthTableSizeHandle(this, (hdILocator *)new ddTableBottomLocator())); + + //Intialize special handle + valueSize = wxSize(10, colsRect.GetSize().GetHeight()); + scrollbar = new ddScrollBarHandle(this, (hdILocator *)new ddScrollBarTableLocator(), valueSize); + + //Intialize columns window (min is always 1 in both, with or without cols & indxs) + colsRowsSize = 0; + colsWindow = 0; + idxsRowsSize = 0; + idxsWindow = 0; + + //Initialize indexes (pointers to array segments) + maxColIndex = 2; + minIdxIndex = 2; + maxIdxIndex = 2; + + //Initialize position where start to draw columns & indexes, this is the value to allow scrollbars + beginDrawCols = 2; + beginDrawIdxs = 2; + + //Initialize + pkName = wxEmptyString; + ukNames.clear(); + + updateTableSize(); + + basicDisplayBox.x[0] = x; + basicDisplayBox.y[0] = y; + belongsToSchema = false; +} + +ddTableFigure::ddTableFigure(wxString tableName, int x, int y): + hdCompositeFigure() +{ + Init(tableName, x, y); +} + +ddTableFigure::ddTableFigure(wxString tableName, int posIdx, int x, int y): + hdCompositeFigure() +{ + Init(tableName, 0, 0); + //Check figure available positions for diagrams, add at least needed to allow initialization of the class + int i, start; + start = basicDisplayBox.CountPositions(); + for(i = start; i < (posIdx + 1); i++) + { + AddPosForNewDiagram(); + } + syncInternalsPosAt(posIdx, x, y); +} + +//Used by persistence classes +void ddTableFigure::InitTableValues(wxArrayString UniqueKeysName, wxString primaryKeyName, int bdc, int bdi, int maxcolsi, int minidxsi, int maxidxsi, int colsrs, int colsw, int idxsrs, int idxsw) +{ + ukNames = UniqueKeysName; + pkName = primaryKeyName; + beginDrawCols = bdc; + beginDrawIdxs = bdi; + maxColIndex = maxcolsi; + minIdxIndex = minidxsi; + maxIdxIndex = maxidxsi; + colsRowsSize = colsrs; + colsWindow = colsw; + idxsRowsSize = idxsrs; + idxsWindow = idxsw; + updateTableSize(); +} + +ddTableFigure::~ddTableFigure() +{ + if(scrollbar) + { + if(figureHandles->existsObject(scrollbar)) + figureHandles->removeItem(scrollbar); + delete scrollbar; + } +} + +void ddTableFigure::AddPosForNewDiagram() +{ + //Add new position to internal calculations figure + fullSizeRect.addNewXYPosition(); + titleRect.addNewXYPosition(); + titleColsRect.addNewXYPosition(); + colsRect.addNewXYPosition(); + titleIndxsRect.addNewXYPosition(); + indxsRect.addNewXYPosition(); + unScrolledColsRect.addNewXYPosition(); + unScrolledFullSizeRect.addNewXYPosition(); + unScrolledTitleRect.addNewXYPosition(); + //Add to all figure figures + hdCompositeFigure::AddPosForNewDiagram(); +} + +void ddTableFigure::RemovePosOfDiagram(int posIdx) +{ + //Remove position for internal calculations figure + fullSizeRect.removeXYPosition(posIdx); + titleRect.removeXYPosition(posIdx); + titleColsRect.removeXYPosition(posIdx); + colsRect.removeXYPosition(posIdx); + titleIndxsRect.removeXYPosition(posIdx); + indxsRect.removeXYPosition(posIdx); + unScrolledColsRect.removeXYPosition(posIdx); + unScrolledFullSizeRect.removeXYPosition(posIdx); + unScrolledTitleRect.removeXYPosition(posIdx); + //remove position at all figure figures + hdCompositeFigure::RemovePosOfDiagram(posIdx); +} + +ddColumnFigure *ddTableFigure::getColByName(wxString name) +{ + ddColumnFigure *out = NULL; + ddColumnFigure *f; + + hdIteratorBase *iterator = figuresEnumerator(); + iterator->Next(); //First figure is main rect + iterator->Next(); //Second figure is main title + + while(iterator->HasNext()) + { + f = (ddColumnFigure *) iterator->Next(); + if(f->getColumnName(false).IsSameAs(name)) + { + out = f; + break; + } + } + delete iterator; + + return out; +} + +//WARNING: Columns SHOULD BE ADDED only using this function to avoid strange behaviors +void ddTableFigure::addColumn(int posIdx, ddColumnFigure *column) +{ + column->setOwnerTable(this); + add(column); + //Update Indexes + if(maxColIndex == minIdxIndex) //maxColIndex == minIdxIndex means not indexes at this table, then update too + { + minIdxIndex++; + maxIdxIndex++; + } + maxColIndex++; + colsWindow++; //by default add a column increase initial window + colsRowsSize++; + + updateTableSize(true); + + //Fix column position at all available positions (Diagrams) + int i; + for(i = 0; i < basicDisplayBox.CountPositions(); i++) + { + syncInternalsPosAt(i, basicDisplayBox.x[i], basicDisplayBox.y[i]); + } +} + +//WARNING: Function should be called on a table generated from a storage or to sync values after a big change at model (not derived from hotdraw events) +void ddTableFigure::syncInternalsPosAt(int posIdx, int x, int y) +{ + basicDisplayBox.x[posIdx] = x; + basicDisplayBox.y[posIdx] = y; + rectangleFigure->moveTo(posIdx, x, y); + tableTitle->moveTo(posIdx, rectangleFigure->getBasicDisplayBox().x[posIdx] + internalPadding * 2, rectangleFigure->getBasicDisplayBox().y[posIdx] + internalPadding / 2); + calcInternalSubAreas(posIdx); + recalculateColsPos(posIdx); +} + +//WARNING: Function should be called on a table generated from a storage or to sync values after a big change at model (not derived from hotdraw events) +void ddTableFigure::syncInternalsPosAt(wxArrayInt &x, wxArrayInt &y) +{ + unsigned int posIdx, pointsCount = tableTitle->getBasicDisplayBox().CountPositions(), finalValue = x.Count(); + //I need to check that figures inside figure have all points too + while(pointsCount < finalValue) + { + AddPosForNewDiagram(); + pointsCount = tableTitle->getBasicDisplayBox().CountPositions(); + } + + //optimize this, because this is hack right now to avoid some weird problem when recreating figure status + basicDisplayBox.x = x; + basicDisplayBox.y = y; + + for(posIdx = 0; posIdx < finalValue; posIdx++) + { + rectangleFigure->moveTo(posIdx, x[posIdx], y[posIdx]); + tableTitle->moveTo(posIdx, rectangleFigure->getBasicDisplayBox().x[posIdx] + internalPadding * 2, rectangleFigure->getBasicDisplayBox().y[posIdx] + internalPadding / 2); + calcInternalSubAreas(posIdx); + recalculateColsPos(posIdx); + } +} + +//WARNING: Columns SHOULD BE ADDED only using this columns if was created as an image from storage one +void ddTableFigure::addColumnFromStorage(ddColumnFigure *column) +{ + add(column); +} + +void ddTableFigure::removeColumn(int posIdx, ddColumnFigure *column) +{ + //Hack to allow to remove Fk before delete it. + if(column->isPrimaryKey() || column->isUniqueKey()) + { + column->setColumnKindToNone(); + } + + column->setOwnerTable(NULL); + remove(column); + + if(column) + delete column; + //Update Indexes + if(maxColIndex == minIdxIndex) //means not indexes at this table, then update too + { + minIdxIndex--; + maxIdxIndex--; + } + maxColIndex--; + if(colsRowsSize == colsWindow) //only decrease if size of window and columns is the same + colsWindow--; + colsRowsSize--; + if(beginDrawCols > 2) + beginDrawCols--; + calcInternalSubAreas(posIdx); + recalculateColsPos(posIdx); + if(colsWindow == colsRowsSize) //if handle need to be removed, remove it + { + if(figureHandles->existsObject(scrollbar)) + figureHandles->removeItem(scrollbar); + } + //hack to update relationship position when table size change + manuallyNotifyChange(posIdx); + column = NULL; +} + +void ddTableFigure::recalculateColsPos(int posIdx) +{ + wxFont font = fontAttribute->font(); + int defaultHeight = getColDefaultHeight(font); + + hdIFigure *f = (hdIFigure *) figureFigures->getItemAt(0); //first figure is always Rect + int horizontalPos = f->displayBox().x[posIdx] + 2; + int verticalPos = 0; + + for(int i = 2; i < maxColIndex ; i++) + { + f = (hdIFigure *) figureFigures->getItemAt(i); //table title + if( (i >= beginDrawCols) && (i <= (colsWindow + beginDrawCols)) ) //Visible to draw + { + verticalPos = colsRect.y[posIdx] + (defaultHeight * (i - beginDrawCols) + ((i - beginDrawCols) * internalPadding)); + f->moveTo(posIdx, horizontalPos, verticalPos); + } + else + f->moveTo(posIdx, -65000, -65000); //any figure outside canvas (x<0 || y<0) is not draw & not used to calculate displaybox + } +} + + + +void ddTableFigure::basicDraw(wxBufferedDC &context, hdDrawingView *view) +{ + int idx = view->getIdx(); + calcInternalSubAreas(idx); + + if(calcScrolled) //Hack to avoid pass view as parameter to calcInternalSubAreas() because is sometimes called outside a paint event + { + view->CalcScrolledPosition(fullSizeRect.x[idx], fullSizeRect.y[idx], &fullSizeRect.x[idx], &fullSizeRect.y[idx]); + view->CalcScrolledPosition(titleRect.x[idx], titleRect.y[idx], &titleRect.x[idx], &titleRect.y[idx]); + view->CalcScrolledPosition(titleColsRect.x[idx], titleColsRect.y[idx], &titleColsRect.x[idx], &titleColsRect.y[idx]); + view->CalcScrolledPosition(colsRect.x[idx], colsRect.y[idx], &colsRect.x[idx], &colsRect.y[idx]); + view->CalcScrolledPosition(titleIndxsRect.x[idx], titleIndxsRect.y[idx], &titleIndxsRect.x[idx], &titleIndxsRect.y[idx]); + view->CalcScrolledPosition(indxsRect.x[idx], indxsRect.y[idx], &indxsRect.x[idx], &indxsRect.y[idx]); + calcScrolled = false; + } + + hdIFigure *f = (hdIFigure *) figureFigures->getItemAt(0); //table rectangle + f->draw(context, view); + f = (hdIFigure *) figureFigures->getItemAt(1); //table title + f->draw(context, view); + + for(int i = beginDrawCols; i < (colsWindow + beginDrawCols); i++) + { + f = (hdIFigure *) figureFigures->getItemAt(i); //table title + if(f->displayBox().GetPosition(view->getIdx()).x > 0 && f->displayBox().GetPosition(view->getIdx()).y > 0) + { + f->draw(context, view); + } + } + + reapplyAttributes(context, view); //reset attributes to default of figure because can be modified at Draw functions. + + //Set Font for title "Columns" + wxFont font = fontAttribute->font(); + int newSize = font.GetPointSize() * 0.7; + font.SetPointSize(newSize); + context.SetFont(font); + + //Draw Columns Title Line 1 + context.DrawLine(titleColsRect.GetTopLeft(idx), titleColsRect.GetTopRight(idx)); + //Draw Columns Title + context.DrawText(wxT("Columns"), titleColsRect.x[idx] + 3, titleColsRect.y[idx]); + //Draw Columns Title Line 2 + context.DrawLine(titleColsRect.GetBottomLeft(idx), titleColsRect.GetBottomRight(idx)); + //DrawVertical Lines + context.DrawLine(titleColsRect.GetBottomLeft(idx).x + 11, titleColsRect.GetBottomLeft(idx).y, titleColsRect.GetBottomLeft(idx).x + 11, titleIndxsRect.GetTopLeft(idx).y); + context.DrawLine(titleColsRect.GetBottomLeft(idx).x + 22, titleColsRect.GetBottomLeft(idx).y, titleColsRect.GetBottomLeft(idx).x + 22, titleIndxsRect.GetTopLeft(idx).y); + //Draw Indexes Title Line 1 + context.DrawLine(titleIndxsRect.GetTopLeft(idx), titleIndxsRect.GetTopRight(idx)); + //Draw Indexes Title + //disable until implemented in a future: context.DrawText(wxT("Indexes"),titleIndxsRect.x+3,titleIndxsRect.y); + //Draw Indexes Title Line 2 + context.DrawLine(titleIndxsRect.GetBottomLeft(idx), titleIndxsRect.GetBottomRight(idx)); + + context.SetFont(fontAttribute->font()); //after change font return always to initial one + + //Draw scrollbar is needed + if(scrollbar && figureHandles->existsObject(scrollbar)) + scrollbar->draw(context, view); + + //Use this in a future + //Hack to show message to select fk destination table + if(selectingFkDestination) + { + context.SetTextForeground(*wxWHITE); + wxBrush old = context.GetBrush(); + context.SetBrush(*wxBLACK_BRUSH); + + int w, h, x, y; + context.GetTextExtent(wxString(wxT("Select Destination table of foreign key")), &w, &h); + x = fullSizeRect.GetTopLeft(idx).x + (((fullSizeRect.GetTopRight(idx).x - fullSizeRect.GetTopLeft(idx).x) - w) / 2); + y = fullSizeRect.GetTopLeft(idx).y - h - 2; + context.DrawRectangle(wxRect(x, y, w, h)); + context.DrawText(wxString(wxT("Select Destination table of foreign key")), x, y); + + context.SetBrush(old); + context.SetTextForeground(*wxBLACK); + context.SetBackground(*wxWHITE); + + //don't draw anything else then don't reapply default attributes + } +} + +void ddTableFigure::basicDrawSelected(wxBufferedDC &context, hdDrawingView *view) +{ + int idx = view->getIdx(); + calcInternalSubAreas(idx); + + if(calcScrolled) //Hack to avoid pass view as parameter to calcInternalSubAreas() because is sometimes called outside a paint event + { + view->CalcScrolledPosition(fullSizeRect.x[idx], fullSizeRect.y[idx], &fullSizeRect.x[idx], &fullSizeRect.y[idx]); + view->CalcScrolledPosition(titleRect.x[idx], titleRect.y[idx], &titleRect.x[idx], &titleRect.y[idx]); + view->CalcScrolledPosition(titleColsRect.x[idx], titleColsRect.y[idx], &titleColsRect.x[idx], &titleColsRect.y[idx]); + view->CalcScrolledPosition(colsRect.x[idx], colsRect.y[idx], &colsRect.x[idx], &colsRect.y[idx]); + view->CalcScrolledPosition(titleIndxsRect.x[idx], titleIndxsRect.y[idx], &titleIndxsRect.x[idx], &titleIndxsRect.y[idx]); + view->CalcScrolledPosition(indxsRect.x[idx], indxsRect.y[idx], &indxsRect.x[idx], &indxsRect.y[idx]); + calcScrolled = false; + } + + hdIFigure *f = (hdIFigure *) figureFigures->getItemAt(0); //table rectangle + f->drawSelected(context, view); + f = (hdIFigure *) figureFigures->getItemAt(1); //table title + f->drawSelected(context, view); + + for(int i = beginDrawCols; i < (colsWindow + beginDrawCols); i++) + { + f = (hdIFigure *) figureFigures->getItemAt(i); //table title + if(f->displayBox().GetPosition(view->getIdx()).x > 0 && f->displayBox().GetPosition(view->getIdx()).y > 0) + { + f->drawSelected(context, view); + } + } + + reapplySelAttributes(context, view); //reset attributes to default of figure because can be modified at Draw functions. + wxFont font = fontAttribute->font(); + float t = font.GetPointSize(); + int newSize = font.GetPointSize() * 0.7; + font.SetPointSize(newSize); + context.SetFont(font); + + //Draw Columns Title Line 1 + context.DrawLine(titleColsRect.GetTopLeft(idx), titleColsRect.GetTopRight(idx)); + //Draw Columns Title + context.DrawText(wxT("Columns"), titleColsRect.x[idx] + 3, titleColsRect.y[idx]); + //Draw Columns Title Line 2 + context.DrawLine(titleColsRect.GetBottomLeft(idx), titleColsRect.GetBottomRight(idx)); + //DrawVertical Lines + context.DrawLine(titleColsRect.GetBottomLeft(idx).x + 11, titleColsRect.GetBottomLeft(idx).y, titleColsRect.GetBottomLeft(idx).x + 11, titleIndxsRect.GetTopLeft(idx).y); + context.DrawLine(titleColsRect.GetBottomLeft(idx).x + 22, titleColsRect.GetBottomLeft(idx).y, titleColsRect.GetBottomLeft(idx).x + 22, titleIndxsRect.GetTopLeft(idx).y); + //Draw Indexes Title Line 1 + context.DrawLine(titleIndxsRect.GetTopLeft(idx), titleIndxsRect.GetTopRight(idx)); + //Draw Indexes Title + //disable until implemented in a future: context.DrawText(wxT("Indexes"),titleIndxsRect.x+3,titleIndxsRect.y); + //Draw Indexes Title Line 2 + context.DrawLine(titleIndxsRect.GetBottomLeft(idx), titleIndxsRect.GetBottomRight(idx)); +} + +hdMultiPosRect &ddTableFigure::getBasicDisplayBox() +{ + return basicDisplayBox; +} + +void ddTableFigure::setColsRowsWindow(int num) +{ + if(num > 0) + { + colsWindow = num; + wxFont font = fontAttribute->font(); + colsRect.height = getColDefaultHeight(font) * colsWindow; + colsRect.width = getFiguresMaxWidth(); + } +} + +int ddTableFigure::getHeightFontMetric(wxString text, wxFont font) +{ + int width, height; + wxBitmap emptyBitmap(*ddAddColumn_png_img); + wxMemoryDC temp_dc; + temp_dc.SelectObject(emptyBitmap); + temp_dc.SetFont(font); + temp_dc.GetTextExtent(text, &width, &height); + return height; +} + +int ddTableFigure::getColDefaultHeight(wxFont font) +{ + if(figureFigures->count() <= 0) + { + int width, height; + wxBitmap emptyBitmap(*ddAddColumn_png_img); + wxMemoryDC temp_dc; + temp_dc.SelectObject(emptyBitmap); + temp_dc.SetFont(font); + temp_dc.GetTextExtent(wxT("NewColumn"), &width, &height); + return height; + } + else + { + hdIFigure *f = (hdIFigure *) figureFigures->getItemAt(1); //table title + return f->displayBox().height; + } +} + +//Show select fk destination Message Hack +void ddTableFigure::setSelectFkDestMode(bool value) +{ + selectingFkDestination = value; +} + +int ddTableFigure::getFiguresMaxWidth() +{ + ddColumnFigure *cf; + hdGeometry g; + + hdIteratorBase *iterator = figuresEnumerator(); + iterator->Next(); //First figure is main rect + int maxWidth = 0; + cf = (ddColumnFigure *) iterator->Next(); //Second figure is main title + maxWidth = g.max(maxWidth, cf->displayBox().width + 20); + while(iterator->HasNext()) + { + cf = (ddColumnFigure *) iterator->Next(); + maxWidth = g.max(maxWidth, cf->displayBox().width); + } + delete iterator; + if(figureHandles->existsObject(scrollbar)) + return maxWidth + 11; //as defined at locator + else + return maxWidth; +} + +void ddTableFigure::calcInternalSubAreas(int posIdx) +{ + calcScrolled = true; + + int maxWidth = getFiguresMaxWidth() + externalPadding; + if(maxWidth < 100) + maxWidth = 100; + wxFont font = fontAttribute->font(); + int defaultHeight = getColDefaultHeight(font); + + hdRect db = basicDisplayBox.gethdRect(posIdx); + + //*** titleRect + float t = font.GetPointSize(); + int newSize = font.GetPointSize() * 0.7; + font.SetPointSize(newSize); + int colsTitleHeight = getHeightFontMetric(wxT("Columns"), font); + + titleRect.x[posIdx] = db.x; + titleRect.y[posIdx] = db.y; + titleRect.width = maxWidth; + titleRect.height = defaultHeight; + + titleColsRect.x[posIdx] = db.x; + titleColsRect.y[posIdx] = titleRect.y[posIdx] + titleRect.height; + titleColsRect.width = maxWidth; + titleColsRect.height = colsTitleHeight; + unScrolledTitleRect = titleColsRect; + + //*** colsRect + colsRect.width = maxWidth; + if(colsWindow > 0) + colsRect.height = defaultHeight * colsWindow + (colsWindow * internalPadding); + else + colsRect.height = defaultHeight; + colsRect.x[posIdx] = db.x; + colsRect.y[posIdx] = titleRect.y[posIdx] + titleRect.height + titleColsRect.height; + unScrolledColsRect = colsRect; + + //*** idxTitleRect + titleIndxsRect.width = maxWidth; + titleIndxsRect.height = colsTitleHeight; + titleIndxsRect.x[posIdx] = db.x; + titleIndxsRect.y[posIdx] = colsRect.y[posIdx] + colsRect.height; + + //*** indexesRect + indxsRect.width = maxWidth; + indxsRect.height = defaultHeight * idxsWindow + (idxsWindow * internalPadding); + indxsRect.x[posIdx] = db.x; + indxsRect.y[posIdx] = titleIndxsRect.y[posIdx] + titleIndxsRect.height; + + //*** FullTable Size + fullSizeRect.width = maxWidth; + fullSizeRect.height = titleRect.height + titleColsRect.height + colsRect.height + titleIndxsRect.height + indxsRect.height; + fullSizeRect.x[posIdx] = db.x; + fullSizeRect.y[posIdx] = titleRect.y[posIdx]; + unScrolledFullSizeRect = fullSizeRect; + + //Update size + wxSize sizeValue = fullSizeRect.GetSize(); + rectangleFigure->setSize(sizeValue); +} + +void ddTableFigure::updateTableSize(bool notifyChange) +{ + //Step 0: Recalculate displaybox size, in case of an external modification as change of datatype in a fk from a source (data is stored in original table) + ddColumnFigure *cf; + hdIteratorBase *iterator = figuresEnumerator(); + iterator->Next(); //First figure is main rect + cf = (ddColumnFigure *) iterator->Next(); //Second figure is main title + while(iterator->HasNext()) + { + cf = (ddColumnFigure *) iterator->Next(); + cf->displayBoxUpdate(); + } + delete iterator; + + //Step 1: Update table size + calcInternalSubAreas(0); + basicDisplayBox.SetSize(fullSizeRect.GetSize()); + if(notifyChange) + { + //hack to update relationship position when table size change, but need to be notified to all views only doing it right now for first view + manuallyNotifyChange(0); + } +} + +hdMultiPosRect &ddTableFigure::getColsSpace() +{ + return unScrolledColsRect; +} + +hdMultiPosRect &ddTableFigure::getFullSpace() +{ + return unScrolledFullSizeRect; +} + +hdMultiPosRect &ddTableFigure::getTitleRect() +{ + return unScrolledTitleRect; +} + + +int ddTableFigure::getTotalColumns() +{ + return colsRowsSize; +} + +int ddTableFigure::getColumnsWindow() +{ + return colsWindow; +} + +void ddTableFigure::setColumnsWindow(int posIdx, int value, bool maximize) +{ + + if(!maximize) + { + + //if value >0 && <= max size table && table+offset < maxColIndex with window + if( (value > 0) && (value <= colsRowsSize) && (maxColIndex >= ( beginDrawCols + value ) ) ) + { + colsWindow = value; + calcInternalSubAreas(posIdx); + recalculateColsPos(posIdx); + } + + //if special case of needing to modify beginDrawCols then do it + if( (value > 0) && (value <= colsRowsSize) && (maxColIndex < ( beginDrawCols + value ) ) ) + { + if( (beginDrawCols + colsWindow) == maxColIndex) //if index is at max + { + int diff = value - colsWindow; // value should be always higher tan colsWindows + if(diff > 0 && (beginDrawCols - diff) >= 0 ) + { + beginDrawCols -= diff; + colsWindow = value; + calcInternalSubAreas(posIdx); + recalculateColsPos(posIdx); + + } + } + } + } + else + { + beginDrawCols = 2; + colsWindow = value; + calcInternalSubAreas(posIdx); + recalculateColsPos(posIdx); + } + + + //Hide Scrollbar if needed + if(colsWindow == colsRowsSize) + { + if(figureHandles->existsObject(scrollbar)) + figureHandles->removeItem(scrollbar); + } + else + { + if (!figureHandles->existsObject(scrollbar)) + figureHandles->addItem(scrollbar); + } + +} + +void ddTableFigure::columnsWindowUp(int posIdx) //move window from number to zero +{ + if( beginDrawCols > 2 ) + { + beginDrawCols--; + calcInternalSubAreas(posIdx); + recalculateColsPos(posIdx); + } +} + +void ddTableFigure::columnsWindowDown(int posIdx) //move window from number to maxcolumns +{ + if( (beginDrawCols + colsWindow) < maxColIndex) + { + beginDrawCols++; + calcInternalSubAreas(posIdx); + recalculateColsPos(posIdx); + } +} + +int ddTableFigure::getTopColWindowIndex() +{ + return (beginDrawCols - 2); +} + +void ddTableFigure::setPkConstraintName(wxString name) +{ + pkName = name; +} + +wxString ddTableFigure::getPkConstraintName() +{ + return pkName; +} + +wxArrayString ddTableFigure::getAllColumnsNames() +{ + wxArrayString tmp; + ddColumnFigure *f; + tmp.Clear(); + hdIteratorBase *iterator = figuresEnumerator(); + iterator->Next(); //First figure is main rect + iterator->Next(); //Second figure is main title + + while(iterator->HasNext()) + { + f = (ddColumnFigure *) iterator->Next(); + tmp.Add(f->getColumnName(false)); + } + delete iterator; + return tmp; +} + +wxArrayString ddTableFigure::getAllFkSourceColsNames(bool pk, int ukIndex) +{ + wxArrayString tmp; + ddColumnFigure *f; + tmp.Clear(); + hdIteratorBase *iterator = figuresEnumerator(); + iterator->Next(); //First figure is main rect + iterator->Next(); //Second figure is main title + + while(iterator->HasNext()) + { + f = (ddColumnFigure *) iterator->Next(); + if(pk) + { + if(f->isPrimaryKey()) + tmp.Add(f->getColumnName(false)); + } + else + { + if(f->isUniqueKey(ukIndex)) + tmp.Add(f->getColumnName(false)); + } + } + delete iterator; + return tmp; +} + +ddColumnFigure *ddTableFigure::getColumnByName(wxString name) +{ + ddColumnFigure *f; + hdIteratorBase *iterator = figuresEnumerator(); + iterator->Next(); //First figure is main rect + iterator->Next(); //Second figure is main title + + while(iterator->HasNext()) + { + f = (ddColumnFigure *) iterator->Next(); + if(f->getColumnName().IsSameAs(name)) + { + return f; + } + } + delete iterator; + return NULL; +} + +wxArrayString &ddTableFigure::getUkConstraintsNames() +{ + return ukNames; +} + +wxString ddTableFigure::getTableName() +{ + ddTextTableItemFigure *c = (ddTextTableItemFigure *) figureFigures->getItemAt(1); + c->setOneTimeNoAlias(); + return c->getText(false); +} + +//set Null on all relationship items with a fk column to be delete or a pk to be removed (pk attribute) +void ddTableFigure::prepareForDeleteFkColumn(ddColumnFigure *column) +{ + hdIteratorBase *iterator = observersEnumerator(); + while(iterator->HasNext()) + { + ddRelationshipFigure *r = (ddRelationshipFigure *) iterator->Next(); + if(r->getStartFigure() == this) //Only update FK of connection with this table as source. source ---<| destination + r->prepareFkForDelete(column); + } + delete iterator; + +} + +// Note about observers: +// A table is observed by several relationships at same time, where that observers +// are just looking for changes that will affect relationship behavior. +// Ex: if I delete a pk on observed table (source) all observers (destination) +// should modify their columns to remove that fk created from that pk column. +// Warning: when a relationship is created an observer is added to both sides of relationship +// because this behavior (needed for update connection) to identify if is an observer +// of source table or destination table, should be check end figure, start!=end and end=this is end figure +// If start = and is recursive +void ddTableFigure::updateFkObservers() +{ + hdIteratorBase *iterator = observersEnumerator(); + while(iterator->HasNext()) + { + ddRelationshipFigure *r = (ddRelationshipFigure *) iterator->Next(); + if(r->getStartFigure() == this) //Only update FK of connection with this table as source. source ---<| destination + { + r->updateForeignKey(); + } + } + delete iterator; +} + +//If a column change datatype, should alert all others table to adjust their size with new values +void ddTableFigure::updateSizeOfObservers() +{ + //For all tables that are observing this table, update their size + hdIteratorBase *iterator = observersEnumerator(); + while(iterator->HasNext()) + { + ddRelationshipFigure *r = (ddRelationshipFigure *) iterator->Next(); + ddTableFigure *destFkTable = (ddTableFigure *) r->getEndFigure(); + destFkTable->updateTableSize(); + } + delete iterator; +} + +//drop foreign keys with this table as origin or destination because table is going to be deleted +void ddTableFigure::processDeleteAlert(hdDrawing *drawing) +{ + hdIteratorBase *iterator = observersEnumerator(); + bool repeatFlag; + do + { + repeatFlag = false; + iterator->ResetIterator(); + while(iterator->HasNext()) + { + ddRelationshipFigure *rel = (ddRelationshipFigure *) iterator->Next(); + rel->disconnectStart(); + rel->disconnectEnd(); + + drawing->getOwnerEditor()->removeFromAllSelections(rel); + drawing->getOwnerEditor()->deleteModelFigure(rel); + repeatFlag = true; + break; + } + } + while(repeatFlag); + + delete iterator; +} + +void ddTableFigure::basicMoveBy(int posIdx, int x, int y) +{ + + hdIFigure *f = (hdIFigure *) figureFigures->getItemAt(0); +//Hack to avoid bug in if clause + int width = spaceForMovement.GetWidth(); + int height = spaceForMovement.GetHeight(); + int bottom = f->displayBox().y[posIdx] + f->displayBox().height + y; + int right = f->displayBox().x[posIdx] + f->displayBox().width + x; + int left = f->displayBox().x[posIdx] + x; + int top = f->displayBox().y[posIdx] + y; + +//limit movemnt of table figures to canvas space + if( (left > 0) && (top > 0) && (right < width) && (bottom < height) ) + hdCompositeFigure::basicMoveBy(posIdx, x, y); +} + +//Validate status of table for SQL DDL generation +bool ddTableFigure::validateTable(wxString &errors) +{ + bool out = true; + wxString tmp = wxEmptyString; + ddColumnFigure *f; + + hdIteratorBase *iterator = figuresEnumerator(); + iterator->Next(); //First figure is main rect + iterator->Next(); //Second figure is main title + + while(iterator->HasNext()) + { + f = (ddColumnFigure *) iterator->Next(); + if(!f->validateColumn(tmp)) + { + out = false; + } + } + + if(!out) + { + errors.Append(wxT("\n")); + errors.Append(wxT("Errors detected at table") + this->getTableName() + wxT(" \n")); + errors.Append(tmp); + errors.Append(wxT("\n")); + } + + delete iterator; + + return out; +} + +//Using some options from http://www.postgresql.org/docs/8.1/static/sql-createtable.html, but new options can be added in a future. +wxString ddTableFigure::generateSQLCreate(wxString schemaName) +{ + //Columns and table + wxString tmp(wxT("CREATE TABLE ")); + if(!schemaName.IsEmpty()) + { + tmp += wxT("\"") + schemaName + wxT("\".\"") + getTableName() + wxT("\" (\n"); + } + else + { + tmp += wxT("\"") + getTableName() + wxT("\" (\n"); + } + hdIteratorBase *iterator = figuresEnumerator(); + iterator->Next(); //Fixed Position for table rectangle + iterator->Next(); //Fixed Position for table name + while(iterator->HasNext()) + { + ddColumnFigure *column = (ddColumnFigure *) iterator->Next(); + tmp += column->generateSQL(); + if(column->isNotNull()) + { + tmp += wxT(" NOT NULL"); + } + if(iterator->HasNext()) + { + tmp += wxT(" , \n"); + } + } + tmp += wxT("\n ); "); + + return tmp; +} + +wxString ddTableFigure::generateSQLAlterPks(wxString schemaName) +{ + wxString tmp; + hdIteratorBase *iterator = figuresEnumerator(); + //Pk, Uk Constraints + iterator->Next(); //Fixed Position for table rectangle + iterator->Next(); //Fixed Position for table name + int contPk = 0; + while(iterator->HasNext()) + { + ddColumnFigure *column = (ddColumnFigure *) iterator->Next(); + if(column->isPrimaryKey()) + contPk++; + } + if(contPk > 0) + { + tmp += wxT("\nALTER TABLE "); + if(!schemaName.IsEmpty()) + { + tmp += wxT("\"") + schemaName + wxT("\".\"") + getTableName() + wxT("\""); + } + else + { + tmp += wxT("\"") + getTableName() + wxT("\"") ; + } + + tmp += wxT(" ADD "); + + if(!pkName.IsEmpty()) + { + tmp += wxT("CONSTRAINT \"") + pkName + wxT("\" "); + } + tmp += wxT("PRIMARY KEY ( "); + iterator->ResetIterator(); + iterator->Next(); //Fixed Position for table rectangle + iterator->Next(); //Fixed Position for table name + + while(iterator->HasNext()) + { + ddColumnFigure *column = (ddColumnFigure *) iterator->Next(); + if(column->isPrimaryKey()) + { + tmp += wxT("\"") + column->getColumnName() + wxT("\""); + contPk--; + if(contPk > 0) + { + tmp += wxT(" , "); + } + else + { + tmp += wxT(" ); "); + } + } + } + } + delete iterator; + + return tmp; +} + +wxString ddTableFigure::generateSQLAlterFks(wxString schemaName) +{ + wxString tmp; + hdIteratorBase *iterator = figuresEnumerator(); + //Fk Constraint + iterator = observersEnumerator(); + if(!iterator->HasNext()) + { + tmp = wxEmptyString; + } + else + { + while(iterator->HasNext()) + { + ddRelationshipFigure *rel = (ddRelationshipFigure *) iterator->Next(); + if(rel->getStartFigure() != this) + { + tmp += rel->generateSQL(schemaName); + } + } + } + delete iterator; + return tmp; +} + +wxString ddTableFigure::generateSQLAlterUks(wxString schemaName) +{ + hdIteratorBase *iterator = figuresEnumerator(); + + //Pk, Uk Constraints + iterator->Next(); //Fixed Position for table rectangle + iterator->Next(); //Fixed Position for table name + int MaxUk = -1; + while(iterator->HasNext()) + { + ddColumnFigure *column = (ddColumnFigure *) iterator->Next(); + if(column->isUniqueKey() && column->getUniqueConstraintIndex() > MaxUk) + MaxUk = column->getUniqueConstraintIndex(); + } + + wxString tmp = wxEmptyString; + if(MaxUk >= 0) + { + int i; + for(i = 0; i <= MaxUk; i++) + { + tmp += wxT("\nALTER TABLE "); + + if(!schemaName.IsEmpty()) + tmp += wxT("\"") + schemaName + wxT("\"."); + tmp += wxT("\"") + getTableName() + wxT("\"") ; + + tmp += wxT(" ADD "); + + if(!getUkConstraintsNames()[i].IsEmpty()) + { + tmp += wxT("CONSTRAINT \"") + getUkConstraintsNames()[i] + wxT("\" ") ; + } + tmp += wxT("UNIQUE ( "); + + int countUk = 0; + iterator->ResetIterator(); + iterator->Next(); //Fixed Position for table rectangle + iterator->Next(); //Fixed Position for table name + while(iterator->HasNext()) + { + ddColumnFigure *column = (ddColumnFigure *) iterator->Next(); + if(column->getUniqueConstraintIndex() == i) + countUk++; + } + + iterator->ResetIterator(); + iterator->Next(); //Fixed Position for table rectangle + iterator->Next(); //Fixed Position for table name + while(iterator->HasNext()) + { + ddColumnFigure *column = (ddColumnFigure *) iterator->Next(); + if(column->isUniqueKey() && column->getUniqueConstraintIndex() == i) + { + tmp += wxT("\"") + column->getColumnName() + wxT("\""); + countUk--; + if(countUk > 0) + { + tmp += wxT(", "); + } + } + } + tmp += wxT(" ); "); + } + } + delete iterator; + return tmp; +} + +wxString ddTableFigure::generateAltersTable(pgConn *connection, wxString schemaName, ddDatabaseDesign *design) +{ + wxString out; + + OID oidTable = ddImportDBUtils::getTableOID(connection, schemaName, getTableName()); + if(oidTable == -1) + { + wxMessageBox(wxString::Format(_("Cannot build an ALTER TABLE statement for a non existing table (%s.%s)."), + schemaName.c_str(), getTableName().c_str()), _("Error when trying to get table OID"), wxICON_ERROR); + return wxEmptyString; + } + + ddStubTable *dbTable = ddImportDBUtils::getTable(connection, getTableName(), oidTable); + if(!dbTable) + { + wxMessageBox(wxString::Format(_("Cannot reverse engineering table %s.%s."), + schemaName.c_str(), getTableName().c_str()), _("Error when trying to get stub table"), wxICON_ERROR); + return wxEmptyString; + } + + //--------------- DETECT TABLE LEVEL CHANGES + + // Check if TABLE was renamed + // **Not supported yet** + + // Check if PRIMARY KEY constraint was renamed + // Some models don't set a name for the primary key, so we ignore those models + if(this->getPkConstraintName().Len() > 0 && !dbTable->PrimaryKeyName.IsSameAs(this->getPkConstraintName())) + { + out += wxT("\n"); + out += wxT("ALTER INDEX \"") + dbTable->PrimaryKeyName + wxT("\" RENAME TO \"") + this->getPkConstraintName() + wxT("\";"); + out += wxT("\n"); + } + + // Check if a UNIQUE KEY constraint was renamed + // **Not supported yet** (is it possible?) + + //--------------- DETECT COLUMN LEVEL CHANGES + + // Check if A COLUMN was renamed + // **Not supported yet** + + // Look for columns that exist in the database but not in the model + bool pkRemovedflag = false; + bool ukRemoved = false; + stubColsHashMap::iterator it; + ddStubColumn *item; + + for (it = dbTable->cols.begin(); it != dbTable->cols.end(); ++it) + { + wxString key = it->first; + item = it->second; + ddColumnFigure *column = getColumnByName(key); + + // Check for changes at the column + if(column) + { + // Generate ALTER COLUMN statement if needed + // Datatype change, length, and precision are checked + + // Temporary conversion fix to datatype of designer should be improved in a future + wxString dataType = item->typeColumn->Name(); + bool sameDatatype = true, sameScale = true, samePrecision = true; + int s = -1, p = -1; + bool useScale = true, needps = false; + + s = item->typeColumn->Length(); + p = item->typeColumn->Precision(); + + if(dataType.IsSameAs(wxT("character varying"), false)) + { + needps = true; + dataType = wxT("varchar(n)"); + } + + else if(dataType.IsSameAs(wxT("numeric"), false)) + { + needps = true; + useScale = false; + dataType = wxT("numeric(p,s)"); + } + else if(dataType.IsSameAs(wxT("interval"), false)) + { + needps = true; + dataType = wxT("interval(n)"); + } + else if(dataType.IsSameAs(wxT("bit"), false)) + { + needps = true; + dataType = wxT("bit(n)"); + } + else if(dataType.IsSameAs(wxT("char"), false)) + { + needps = true; + dataType = wxT("char(n)"); + } + else if(dataType.IsSameAs(wxT("varbit"), false)) + { + needps = true; + dataType = wxT("varbit(n)"); + } + else if(dataType.IsSameAs(wxT("character"), false)) + { + needps = true; + dataType = wxT("char(n)"); + } + + if(needps) + { + if(useScale) + { + samePrecision = column->getPrecision() == s; + } + else + { + samePrecision = column->getPrecision() == s; + sameScale = column->getScale() == p; + } + } + + + sameDatatype = column->getRawDataType().IsSameAs(dataType, false); + + if(!samePrecision || !sameScale || !sameDatatype) + { + out += wxT("\n"); + out += wxT("ALTER TABLE "); + + if(!schemaName.IsEmpty()) + out += wxT("\"") + schemaName + wxT("\"."); + out += wxT("\"") + getTableName() + wxT("\"") ; + + out += wxT(" ALTER COLUMN ") + column->generateSQL(true) + wxT(";"); + out += wxT("\n"); + } + } + else // DROP COLUMN because it doesn't exist in the model anymore + { + out += wxT("\n"); + out += wxT("ALTER TABLE "); + + if(!schemaName.IsEmpty()) + out += wxT("\"") + schemaName + wxT("\"."); + out += wxT("\"") + getTableName() + wxT("\"") ; + + out += wxT(" DROP COLUMN \"") + key + wxT("\";"); + out += wxT("\n"); + if(item->isPrimaryKey) + { + pkRemovedflag = true; + } + } + } + + // Look for columns that exist in the model but not in the database + hdIteratorBase *iteratorPK = figuresEnumerator(); + iteratorPK->Next(); //Fixed Position for table rectangle + iteratorPK->Next(); //Fixed Position for table name + + bool pkAddedflag = false; + while(iteratorPK->HasNext()) + { + ddColumnFigure *column = (ddColumnFigure *) iteratorPK->Next(); + if(dbTable->cols.find(column->getColumnName()) == dbTable->cols.end()) //Exist in model but not in db + { + out += wxT("\n"); + out += wxT("ALTER TABLE "); + if(!schemaName.IsEmpty()) + out += wxT("\"") + schemaName + wxT("\"."); + out += wxT("\"") + getTableName() + wxT("\"") ; + out += wxT(" ADD COLUMN ") + column->generateSQL() + wxT(";"); + out += wxT("\n"); + if(column->isPrimaryKey()) + { + pkAddedflag = true; + } + } + } + + // Look for all PRIMARY columns in the database's tables + bool pkChanged = false; + iteratorPK->ResetIterator(); + iteratorPK->Next(); //Fixed Position for table rectangle + iteratorPK->Next(); //Fixed Position for table name + while(iteratorPK->HasNext()) + { + ddColumnFigure *column = (ddColumnFigure *) iteratorPK->Next(); + if(column->isPrimaryKey()) + { + if(dbTable->cols.find(column->getColumnName()) == dbTable->cols.end()) + { + pkChanged = true; + } + else + { + if(!dbTable->cols[column->getColumnName()]->isPrimaryKey) + { + pkChanged = true; + } + } + } + } + delete iteratorPK; + + // Look for all PRIMARY columns in the model + stubColsHashMap::iterator itCol; + ddStubColumn *itemCol; + for (itCol = dbTable->cols.begin(); itCol != dbTable->cols.end(); ++itCol) + { + wxString colStubName = itCol->first; + itemCol = itCol->second; + if(itemCol->isPrimaryKey) + { + ddColumnFigure *col = getColumnByName(colStubName); + if(col != NULL) + { + if(!col->isPrimaryKey()) + { + pkChanged = true; + } + } + else + { + pkChanged = true; + } + } + } + + + // Handle the addition of a new column to the primary key + if(pkAddedflag || pkRemovedflag || pkChanged) + { + // Drop existing primary key + out += wxT("\n"); + out += wxT("ALTER TABLE "); + if(!schemaName.IsEmpty()) + out += wxT("\"") + schemaName + wxT("\"."); + out += wxT("\"") + getTableName() + wxT("\"") ; + out += wxT(" DROP CONSTRAINT \"") + this->getPkConstraintName() + wxT("\";"); + // Create the new one + out += generateSQLAlterPks(schemaName); + } + + // Handle changes from NOT NULL to NULL (always after dropping PK) + for (it = dbTable->cols.begin(); it != dbTable->cols.end(); ++it) + { + wxString key = it->first; + item = it->second; + ddColumnFigure *column = getColumnByName(key); + + // Check for changes at the column level + if(column) + { + // Generate ALTER COLUMN statement if needed + // Datatype change, length and precision are handled. + + // Temporary conversion fix to datatype of designer should be improved in a future + wxString dataType = item->typeColumn->Name(); + bool sameDatatype = true, sameScale = true, samePrecision = true; + int s = -1, p = -1; + + // Model has now NULL constraint, so drop the NOT NULL constraint + if(column->isNotNull()) + { + if(!item->isNotNull) + { + out += wxT("\n"); + out += wxT("ALTER TABLE "); + if(!schemaName.IsEmpty()) + out += wxT("\"") + schemaName + wxT("\"."); + out += wxT("\"") + getTableName() + wxT("\"") ; + out += wxT(" ALTER COLUMN \"") + column->getColumnName() + _("\" SET NOT NULL;"); + out += wxT("\n"); + } + } + else if(!column->isNotNull()) + { + if(item->isNotNull) + { + out += wxT("\n"); + out += wxT("ALTER TABLE \""); + if(!schemaName.IsEmpty()) + out += wxT("\"") + schemaName + wxT("\"."); + out += wxT("\"") + getTableName() + wxT("\"") ; + out += wxT("\" ALTER COLUMN \"") + column->getColumnName() + wxT("\" DROP NOT NULL;"); + out += wxT("\n"); + } + } + } + } + + // Check UK conditions + int i, maxUkn = this->getUkConstraintsNames().Count(); + for(i = 0; i < maxUkn; i++) + { + if(this->getUkConstraintsNames()[i].Len() == 0) + { + wxMessageBox(wxString::Format(_("Some UNIQUE keys on table %s have no name.\nYou should set a name for them, so that pgAdmin can check consistency with the already available database constraints."), + getTableName().c_str()), _("Trying to build ALTER sentences"), wxICON_ERROR); + return wxEmptyString; + } + } + + // Search for UNIQUE key deleted from model, but available in the database + // Two steps process: first drop then delete from wxarraystring + int maxUkStub = dbTable->UniqueKeysNames.Count(); + for(i = 0; i < maxUkStub; i++) + { + // Drop UK [in db but not in model] + if(this->getUkConstraintsNames().Index(dbTable->UniqueKeysNames[i]) == wxNOT_FOUND) + { + // Drop it + out += wxT("\n"); + out += wxT("DROP INDEX \"") + dbTable->UniqueKeysNames[i] + wxT("\";"); + out += wxT("\n"); + + // This index metadata is not useful anymore, so erase it at temporary stub table. + stubColsHashMap::iterator itDelUkIdx; + ddStubColumn *itemDelUkIdx; + for (itDelUkIdx = dbTable->cols.begin(); itDelUkIdx != dbTable->cols.end(); ++itDelUkIdx) + { + wxString keyDelUkIdx = itDelUkIdx->first; + itemDelUkIdx = itDelUkIdx->second; + if(itemDelUkIdx->uniqueKeyIndex == i) + { + itemDelUkIdx->uniqueKeyIndex = -1; + } + } + } + } + + maxUkStub = dbTable->UniqueKeysNames.Count(); + for(i = 0; i < maxUkStub; i++) + { + // Drop UK [in db but not in model] + if(this->getUkConstraintsNames().Index(dbTable->UniqueKeysNames[i]) == wxNOT_FOUND) + { + dbTable->UniqueKeysNames.RemoveAt(i); + maxUkStub = dbTable->UniqueKeysNames.Count(); + } + } + + // Search for new UK in model to add ADD CONSTRAINT clause + int maxUkModel = this->getUkConstraintsNames().Count(); + for(i = 0; i < maxUkModel; i++) + { + // Add UK [in model but not in db] + if(dbTable->UniqueKeysNames.Index(this->getUkConstraintsNames()[i]) == wxNOT_FOUND) + { + // Create it + out += wxT("\nALTER TABLE "); + if(!schemaName.IsEmpty()) + out += wxT("\"") + schemaName + wxT("\"."); + out += wxT("\"") + getTableName() + wxT("\"") ; + out += wxT(" ADD "); + if(!getUkConstraintsNames()[i].IsEmpty()) + { + out += wxT(" CONSTRAINT \"") + getUkConstraintsNames()[i] + wxT("\" "); + } + out += wxT(" UNIQUE ( "); + + int countUk = 0; + hdIteratorBase *iteratorUk = figuresEnumerator(); + iteratorUk->Next(); //Fixed Position for table rectangle + iteratorUk->Next(); //Fixed Position for table name + while(iteratorUk->HasNext()) + { + ddColumnFigure *column = (ddColumnFigure *) iteratorUk->Next(); + if(column->getUniqueConstraintIndex() == i) + countUk++; + } + + iteratorUk->ResetIterator(); + iteratorUk->Next(); //Fixed Position for table rectangle + iteratorUk->Next(); //Fixed Position for table name + while(iteratorUk->HasNext()) + { + ddColumnFigure *column = (ddColumnFigure *) iteratorUk->Next(); + if(column->isUniqueKey() && column->getUniqueConstraintIndex() == i) + { + out += wxT("\"") + column->getColumnName() + wxT("\""); + countUk--; + if(countUk > 0) + { + out += wxT(", "); + } + else + { + out += wxT(");"); + } + } + } + delete iteratorUk; + } + } + + // After delete/create UK, look for changes at existing UK + // Unified UK indexes at both dbtable and ddTableFigure [same index at dbtable that in tablefigure] + // BUT in table figure exists indexes without an equivalent in dbtable + maxUkStub = this->getUkConstraintsNames().Count(); + for(i = 0; i < maxUkStub; i++) + { + int oldIndex = dbTable->UniqueKeysNames.Index(this->getUkConstraintsNames()[i]); + int newIndex = i; + + if(oldIndex != wxNOT_FOUND) + { + stubColsHashMap::iterator itDelUkIdx; + ddStubColumn *itemDelUkIdx; + for (itDelUkIdx = dbTable->cols.begin(); itDelUkIdx != dbTable->cols.end(); ++itDelUkIdx) + { + wxString keyDelUkIdx = itDelUkIdx->first; + itemDelUkIdx = itDelUkIdx->second; + if(item->uniqueKeyIndex == oldIndex) + { + item->uniqueKeyIndex = newIndex; + } + } + } + } + + // Generate again those UK that fill one of these conditions: + // 1. UK at tablefigure have more columns that at stub + // 2. Uk at stub have more column that at tablefigure + // Right now, UK constraints have unified indexes (same index at tablefigure and stub) + maxUkStub = this->getUkConstraintsNames().Count(); + + // for each UK + for(i = 0; i < maxUkStub; i++) + { + // Only for UKs with number unified that exists at both sides [db and tablefigure] [with boundaries check] + int boundarie1 = getUkConstraintsNames().Count(); + int boundarie2 = dbTable->UniqueKeysNames.Count(); + if( (i < boundarie1) && (i < boundarie2) && getUkConstraintsNames().Index( dbTable->UniqueKeysNames[i]) != wxNOT_FOUND ) + { + // Assumption + bool createUkAgain = false; + + // CHECK FIRST CONDITION ---> 1. UK at tablefigure have more columns that at stub? + hdIteratorBase *iteratorUk = figuresEnumerator(); + iteratorUk->Next(); //Fixed Position for table rectangle + iteratorUk->Next(); //Fixed Position for table name + + while(iteratorUk->HasNext()) + { + ddColumnFigure *column = (ddColumnFigure *) iteratorUk->Next(); + // For each UK column of the constraint with same index (position i, constraint at getUkConstraintsNames()[] ) + if(column->getUniqueConstraintIndex() == i) + { + if(dbTable->cols.find(column->getColumnName()) == dbTable->cols.end()) //found at dbtable that uk column + { + createUkAgain = true; + } + else + { + ddStubColumn *stubCol = dbTable->cols[column->getColumnName()]; + if(!stubCol->isUniqueKey()) + { + createUkAgain = true; + } + } + } + } + delete iteratorUk; + + // CHECK SECOND CONDITION ---> UK at stub have more uk column of same index that at tablefigure? + stubColsHashMap::iterator itCol; + ddStubColumn *itemCol; + for (itCol = dbTable->cols.begin(); itCol != dbTable->cols.end(); ++itCol) + { + bool isAtFigure = false; + wxString colStubName = itCol->first; + itemCol = itCol->second; + if(itemCol->uniqueKeyIndex == i) + { + ddColumnFigure *colUk = getColumnByName(colStubName); + if(colUk == NULL) + { + createUkAgain = true; + } + else + { + if(!colUk->isUniqueKey()) + { + createUkAgain = true; + } + } + } + } + + if(createUkAgain) + { + // Drop it + out += wxT("\n"); + out += wxT("DROP INDEX \"") + dbTable->UniqueKeysNames[i] + wxT("\";"); + out += wxT("\n"); + + // Create it + out += wxT("\nALTER TABLE "); + if(!schemaName.IsEmpty()) + out += wxT("\"") + schemaName + wxT("\"."); + out += wxT("\"") + getTableName() + wxT("\"") ; + out += wxT(" ADD "); + if(!getUkConstraintsNames()[i].IsEmpty()) + { + out += wxT(" CONSTRAINT \"") + getUkConstraintsNames()[i] + wxT("\" "); + } + out += wxT(" UNIQUE ( "); + + int countUk = 0; + hdIteratorBase *iteratorUk = figuresEnumerator(); + iteratorUk->Next(); //Fixed Position for table rectangle + iteratorUk->Next(); //Fixed Position for table name + while(iteratorUk->HasNext()) + { + ddColumnFigure *column = (ddColumnFigure *) iteratorUk->Next(); + if(column->getUniqueConstraintIndex() == i) + countUk++; + } + + iteratorUk->ResetIterator(); + iteratorUk->Next(); //Fixed Position for table rectangle + iteratorUk->Next(); //Fixed Position for table name + while(iteratorUk->HasNext()) + { + ddColumnFigure *column = (ddColumnFigure *) iteratorUk->Next(); + if(column->isUniqueKey() && column->getUniqueConstraintIndex() == i) + { + out += wxT("\"") + column->getColumnName() + wxT("\""); + countUk--; + if(countUk > 0) + { + out += wxT(", "); + } + else + { + out += wxT(" );"); + } + } + } + delete iteratorUk; + } + } + } + + // Validate all FKs have a name defined at model + hdIteratorBase *iteratorRelations = observersEnumerator(); + while(iteratorRelations->HasNext()) + { + ddRelationshipFigure *r = (ddRelationshipFigure *) iteratorRelations->Next(); + if(r->getConstraintName().Len() == 0) // Add to list, FKs with this table as destination. source ---<| destination + { + wxMessageBox(wxString::Format(_("Some foreign keys keys on table %s have no name.\nYou should set a name for them, so that pgAdmin can check consistency with the already available database constraints."), + getTableName().c_str()), _("Trying to build ALTER sentences"), wxICON_ERROR); + return wxEmptyString; + } + } + + //Check Foreign Keys + // FK at model are same (including attributes and columns) at db + iteratorRelations->ResetIterator(); + while(iteratorRelations->HasNext()) + { + ddRelationshipFigure *r = (ddRelationshipFigure *) iteratorRelations->Next(); + if(r->getEndFigure() == this) // Only check FK this table as destination. source ---<| destination + { + // Check relationship from model exists a db? + if(ddImportDBUtils::existsFk(connection, dbTable->OIDTable, schemaName, r->getConstraintName(), r->getStartTable()->getTableName())) + { + // Columns and other properties are exactly the same? if not, then drop and create again + if(!ddImportDBUtils::isModelSameDbFk(connection, dbTable->OIDTable, schemaName, r->getConstraintName(), r->getStartTable()->getTableName(), r->getEndTable()->getTableName(), dbTable, r)) + { + // Drop it first + out += wxT("\n"); + out += wxT("ALTER TABLE "); + if(!schemaName.IsEmpty()) + out += wxT("\"") + schemaName + wxT("\"."); + out += wxT("\"") + this->getTableName() + wxT("\"") ; + out += wxT(" DROP CONSTRAINT \"") + r->getConstraintName() + wxT("\";"); + out += wxT("\n"); + + // Then Add it again with changes + out += r->generateSQL(schemaName); + + } + } + else //relationship only exists at model and not in db + { + //Create because it doesn't exists + out += r->generateSQL(schemaName); + } + } + } + + // Check foreign keys available in the database but not in the model + // because we need to drop them + // First, create a list of FKs at destination table in the model + wxArrayString validFks; + iteratorRelations->ResetIterator(); + while(iteratorRelations->HasNext()) + { + ddRelationshipFigure *r = (ddRelationshipFigure *) iteratorRelations->Next(); + if(r->getEndFigure() == this) // Add to list, FKs with this table as destination. source ---<| destination + { + validFks.Add(r->getConstraintName()); + } + } + delete iteratorRelations; + + wxArrayString fksToDelete = ddImportDBUtils::getFkAtDbNotInModel(connection, dbTable->OIDTable, schemaName, validFks , design); + + int max = fksToDelete.Count(); + for(i = 0; i < max; i++) + { + // Drop it + out += wxT("\n"); + out += wxT("ALTER TABLE "); + if(!schemaName.IsEmpty()) + out += wxT("\"") + schemaName + wxT("\"."); + out += wxT("\"") + this->getTableName() + wxT("\"") ; + out += wxT(" DROP CONSTRAINT \"") + fksToDelete[i] + wxT("\";"); + out += wxT("\n"); + } + + if(dbTable) + delete dbTable; + return out; +} diff --git a/dd/dditems/figures/ddTextTableItemFigure.cpp b/dd/dditems/figures/ddTextTableItemFigure.cpp new file mode 100644 index 0000000..6bfbb0b --- /dev/null +++ b/dd/dditems/figures/ddTextTableItemFigure.cpp @@ -0,0 +1,582 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddTextTableItemFigure.cpp - Draw a column inside a table +// +//////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "dd/dditems/figures/ddTextTableItemFigure.h" +#include "dd/dditems/figures/ddRelationshipItem.h" +#include "dd/dditems/tools/ddColumnTextTool.h" +#include "dd/dditems/utilities/ddDataType.h" +#include "hotdraw/figures/hdSimpleTextFigure.h" +#include "hotdraw/main/hdDrawingView.h" +#include "dd/ddmodel/ddDrawingEditor.h" +#include "dd/ddmodel/ddDatabaseDesign.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/dditems/utilities/ddPrecisionScaleDialog.h" +#include "hotdraw/utilities/hdRemoveDeleteDialog.h" + +ddTextTableItemFigure::ddTextTableItemFigure(wxString &columnName, ddDataType dataType, ddColumnFigure *owner): + hdSimpleTextFigure(columnName) +{ + setKindId(DDTEXTTABLEITEMFIGURE); + ownerTable = NULL; //table name item is the only one case of use of this variable + oneTimeNoAlias = false; + columnType = dataType; + this->setEditable(true); + enablePopUp(); + ownerColumn = owner; + showDataType = true; + showAlias = false; + recalculateDisplayBox(); + precision = -1; + scale = -1; + + if(owner) //is Column Object + { + fontColorAttribute->fontColor = owner->getOwnerTable()->fontColorAttribute->fontColor; + fontSelColorAttribute->fontColor = owner->getOwnerTable()->fontSelColorAttribute->fontColor; + } +} + +ddTextTableItemFigure::~ddTextTableItemFigure() +{ +} + +void ddTextTableItemFigure::recalculateDisplayBox() +{ + if (ownerColumn && ownerColumn->getOwnerTable()) + { + hdSimpleTextFigure::recalculateDisplayBox(); + displayBox().width = ownerColumn->getOwnerTable()->getFiguresMaxWidth(); + } +} + +void ddTextTableItemFigure::displayBoxUpdate() +{ + recalculateDisplayBox(); +} + +void ddTextTableItemFigure::setOwnerTable(ddTableFigure *table) +{ + ownerTable = table; + if(table)//is Table Name object + { + fontColorAttribute->fontColor = ownerTable->fontColorAttribute->fontColor; + fontSelColorAttribute->fontColor = ownerTable->fontSelColorAttribute->fontColor; + } +} + +wxString &ddTextTableItemFigure::getText(bool extended) +{ + if(showDataType && extended && getOwnerColumn()) + { + wxString ddType = dataTypes()[getDataType()]; //Should use getDataType() & getPrecision(), because when column is fk, type is not taken from this column, instead from original column (source of fk) + bool havePrecision = columnType == dt_numeric || columnType == dt_bit || columnType == dt_char || columnType == dt_interval || columnType == dt_varbit || columnType == dt_varchar; + if( havePrecision && getPrecision() >= 0) + { + ddType.Truncate(ddType.Find(wxT("("))); + if(getScale() == -1) + ddType += wxString::Format(wxT("(%d)"), getPrecision()); + else + ddType += wxString::Format(wxT("(%d,%d)"), getPrecision(), getScale()); + } + //Fix to serial is integer at automatically generated foreign key + if(getDataType() == dt_serial && getOwnerColumn()->isGeneratedForeignKey()) + ddType = dataTypes()[dt_integer]; + + out = wxString( hdSimpleTextFigure::getText() + wxString(wxT(" : ")) + ddType ); + return out; + } + else if( showAlias && getOwnerColumn() == NULL ) + { + if(!oneTimeNoAlias) + out = wxString( hdSimpleTextFigure::getText() + wxString(wxT(" ( ")) + colAlias + wxString(wxT(" ) ")) ); + else + { + out = wxString( hdSimpleTextFigure::getText() ); + oneTimeNoAlias = false; + } + return out; + } + else + { + return hdSimpleTextFigure::getText(); + } +} + +wxString ddTextTableItemFigure::getType(bool raw) +{ + wxString ddType = dataTypes()[columnType]; + if(raw) + return ddType; + + bool havePrecision = columnType == dt_numeric || columnType == dt_bit || columnType == dt_char || columnType == dt_interval || columnType == dt_varbit || columnType == dt_varchar; + if( havePrecision && getPrecision() >= 0) + { + ddType.Truncate(ddType.Find(wxT("("))); + if(getScale() == -1) + ddType += wxString::Format(wxT("(%d)"), getPrecision()); + else + ddType += wxString::Format(wxT("(%d,%d)"), getPrecision(), getScale()); + } + + //Fix to serial is integer at automatically generated foreign key + if(columnType == dt_serial && getOwnerColumn()->isGeneratedForeignKey()) + ddType = dataTypes()[dt_integer]; + + return ddType; +} + +//WARNING: event ID must match enum ddDataType!!! this event was created on view +void ddTextTableItemFigure::OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view) +{ + wxTextEntryDialog *nameDialog = NULL; + ddPrecisionScaleDialog *numericDialog = NULL; + wxString tmpString; + int answer; + int tmpprecision; + long tmpvalue; + hdRemoveDeleteDialog *delremDialog = NULL; + + switch(event.GetId()) + { + case MNU_DDADDCOLUMN: + nameDialog = new wxTextEntryDialog(view, wxT("New column name"), wxT("Add a column")); + answer = nameDialog->ShowModal(); + if (answer == wxID_OK) + { + tmpString = nameDialog->GetValue(); + getOwnerColumn()->getOwnerTable()->addColumn(view->getIdx(), new ddColumnFigure(tmpString, getOwnerColumn()->getOwnerTable())); + view->notifyChanged(); + } + delete nameDialog; + break; + case MNU_DELCOLUMN: + answer = wxMessageBox(wxT("Are you sure you wish to delete column ") + getText(true) + wxT("?"), wxT("Delete column?"), wxYES_NO | wxNO_DEFAULT, view); + if (answer == wxYES) + { + getOwnerColumn()->getOwnerTable()->removeColumn(view->getIdx(), getOwnerColumn()); + view->notifyChanged(); + } + break; + case MNU_AUTONAMCOLUMN: + getOwnerColumn()->activateGenFkName(); + getOwnerColumn()->getFkSource()->syncAutoFkName(); + view->notifyChanged(); + break; + case MNU_RENAMECOLUMN: + nameDialog = new wxTextEntryDialog(view, wxT("New column name"), wxT("Rename Column"), getText()); + nameDialog->ShowModal(); + if(getOwnerColumn()->isGeneratedForeignKey()) //after a manual user column rename, deactivated automatic generation of fk name. + getOwnerColumn()->deactivateGenFkName(); + setText(nameDialog->GetValue()); + delete nameDialog; + view->notifyChanged(); + break; + case MNU_NOTNULL: + if(getOwnerColumn()->isNotNull()) + getOwnerColumn()->setColumnOption(null); + else + getOwnerColumn()->setColumnOption(notnull); + view->notifyChanged(); + break; + case MNU_PKEY: + if(getOwnerColumn()->isPrimaryKey()) + { + getOwnerColumn()->disablePrimaryKey(); + } + else + { + getOwnerColumn()->enablePrimaryKey(); + getOwnerColumn()->setColumnOption(notnull); + } + view->notifyChanged(); + break; + case MNU_UKEY: + getOwnerColumn()->toggleColumnKind(uk, view); + view->notifyChanged(); + break; + case MNU_TYPESERIAL: + setDataType(dt_serial); //Should use setDataType always to set this value to allow fk to work flawlessly + recalculateDisplayBox(); + getOwnerColumn()->displayBoxUpdate(); + getOwnerColumn()->getOwnerTable()->updateTableSize(); + view->notifyChanged(); + break; + case MNU_TYPEBOOLEAN: + setDataType(dt_boolean); + recalculateDisplayBox(); + getOwnerColumn()->displayBoxUpdate(); + getOwnerColumn()->getOwnerTable()->updateTableSize(); + view->notifyChanged(); + break; + case MNU_TYPEINTEGER: + setDataType(dt_integer); + recalculateDisplayBox(); + getOwnerColumn()->displayBoxUpdate(); + getOwnerColumn()->getOwnerTable()->updateTableSize(); + view->notifyChanged(); + break; + case MNU_TYPEMONEY: + setDataType(dt_money); + recalculateDisplayBox(); + getOwnerColumn()->displayBoxUpdate(); + getOwnerColumn()->getOwnerTable()->updateTableSize(); + view->notifyChanged(); + break; + case MNU_TYPEVARCHAR: + setDataType(dt_varchar); + tmpprecision = wxGetNumberFromUser(_("Varchar size"), + _("Size for varchar datatype"), + _("Varchar size"), + getPrecision(), 0, 255, view); + if (tmpprecision >= 0) + { + setPrecision(tmpprecision); + setScale(-1); + } + recalculateDisplayBox(); + getOwnerColumn()->displayBoxUpdate(); + getOwnerColumn()->getOwnerTable()->updateTableSize(); + view->notifyChanged(); + break; + case MNU_TYPEOTHER: + answer = wxGetSingleChoiceIndex(wxT("New column datatype"), wxT("Column Datatypes"), dataTypes(), view); + if(answer >= 0) + { + view->notifyChanged(); + if(answer == dt_varchar || answer == dt_bit || answer == dt_char || answer == dt_interval || answer == dt_varbit) + { + tmpprecision = wxGetNumberFromUser(_("datatype size"), + _("Size for datatype"), + _("size"), + getPrecision(), 0, 255, view); + if (tmpprecision >= 0) + { + setPrecision(tmpprecision); + setScale(-1); + } + recalculateDisplayBox(); + getOwnerColumn()->displayBoxUpdate(); + getOwnerColumn()->getOwnerTable()->updateTableSize(); + } + if(answer == dt_numeric) + { + numericDialog = new ddPrecisionScaleDialog( view, + NumToStr((long)getPrecision()), + NumToStr((long)getScale())); + numericDialog->ShowModal(); + numericDialog->GetValue1().ToLong(&tmpvalue); + setPrecision(tmpvalue); + numericDialog->GetValue2().ToLong(&tmpvalue); + setScale(tmpvalue); + delete numericDialog; + recalculateDisplayBox(); + getOwnerColumn()->displayBoxUpdate(); + getOwnerColumn()->getOwnerTable()->updateTableSize(); + } + + + setDataType( (ddDataType) answer ); + recalculateDisplayBox(); + getOwnerColumn()->displayBoxUpdate(); + getOwnerColumn()->getOwnerTable()->updateTableSize(); + } + break; + case MNU_TYPEPKEY_CONSTRAINTNAME: + tmpString = wxGetTextFromUser(wxT("New name of primary key:"), getOwnerColumn()->getOwnerTable()->getPkConstraintName(), getOwnerColumn()->getOwnerTable()->getPkConstraintName(), view); + if(tmpString.length() > 0) + { + getOwnerColumn()->getOwnerTable()->setPkConstraintName(tmpString); + view->notifyChanged(); + } + break; + case MNU_TYPEUKEY_CONSTRAINTNAME: + answer = wxGetSingleChoiceIndex(wxT("Select Unique Key constraint to edit name"), wxT("Select Unique Constraint to edit name:"), getOwnerColumn()->getOwnerTable()->getUkConstraintsNames(), view); + if(answer >= 0) + { + tmpString = wxGetTextFromUser(wxT("Change name of Unique Key constraint:"), getOwnerColumn()->getOwnerTable()->getUkConstraintsNames().Item(answer), getOwnerColumn()->getOwnerTable()->getUkConstraintsNames().Item(answer), view); + if(tmpString.length() > 0) + { + getOwnerColumn()->getOwnerTable()->getUkConstraintsNames().Item(answer) = tmpString; + view->notifyChanged(); + } + } + break; + case MNU_DELTABLE: + + delremDialog = new hdRemoveDeleteDialog(wxT("Are you sure you wish to delete table ") + getOwnerColumn()->getOwnerTable()->getTableName() + wxT("?"), wxT("Delete table?"), view); + answer = delremDialog->ShowModal(); + ddTableFigure *table = getOwnerColumn()->getOwnerTable(); + if (answer == DD_DELETE) + { + ddDrawingEditor *editor = (ddDrawingEditor *) view->editor(); + //Unselect table at all diagrams + editor->removeFromAllSelections(table); + //Drop foreign keys with this table as origin or destination + table->processDeleteAlert(view->getDrawing()); + //Drop table + editor->deleteModelFigure(table); + editor->getDesign()->refreshBrowser(); + view->notifyChanged(); + } + else if(answer == DD_REMOVE) + { + ddDrawingEditor *editor = (ddDrawingEditor *) view->editor(); + editor->getExistingDiagram(view->getIdx())->removeFromSelection(table); + editor->getExistingDiagram(view->getIdx())->remove(table); + view->notifyChanged(); + } + delete delremDialog; + break; + } +} + +void ddTextTableItemFigure::createMenu(wxMenu &mnu) +{ + wxMenu *submenu; + wxMenuItem *item; + + mnu.Append(MNU_DDADDCOLUMN, _("Add a column...")); + item = mnu.Append(MNU_DELCOLUMN, _("Delete the selected column...")); + if(getOwnerColumn()->isGeneratedForeignKey()) + item->Enable(false); + mnu.Append(MNU_RENAMECOLUMN, _("Rename the selected column...")); + if(getOwnerColumn()->isGeneratedForeignKey() && !getOwnerColumn()->isFkNameGenerated()) + mnu.Append(MNU_AUTONAMCOLUMN, _("Activate fk auto-naming...")); + mnu.AppendSeparator(); + item = mnu.AppendCheckItem(MNU_NOTNULL, _("Not NULL constraint")); + if(getOwnerColumn()->isNotNull()) + item->Check(true); + if(getOwnerColumn()->isGeneratedForeignKey()) + item->Enable(false); + mnu.AppendSeparator(); + item = mnu.AppendCheckItem(MNU_PKEY, _("Primary Key")); + if(getOwnerColumn()->isPrimaryKey()) + item->Check(true); + if(getOwnerColumn()->isGeneratedForeignKey()) + item->Enable(false); + item = mnu.AppendCheckItem(MNU_UKEY, _("Unique Key")); + if(getOwnerColumn()->isUniqueKey()) + item->Check(true); + mnu.AppendSeparator(); + submenu = new wxMenu(); + item = mnu.AppendSubMenu(submenu, _("Column datatype")); + if(getOwnerColumn()->isGeneratedForeignKey()) + item->Enable(false); + item = submenu->AppendCheckItem(MNU_TYPESERIAL, _("serial")); + item->Check(columnType == dt_bigint); + item = submenu->AppendCheckItem(MNU_TYPEBOOLEAN, _("boolean")); + item->Check(columnType == dt_boolean); + item = submenu->AppendCheckItem(MNU_TYPEINTEGER, _("integer")); + item->Check(columnType == dt_integer); + item = submenu->AppendCheckItem(MNU_TYPEMONEY, _("money")); + item->Check(columnType == dt_money); + item = submenu->AppendCheckItem(MNU_TYPEVARCHAR, _("varchar(n)")); + item->Check(columnType == dt_varchar); + item = submenu->Append(MNU_TYPEOTHER, _("Choose another datatype...")); + mnu.AppendSeparator(); + mnu.Append(MNU_TYPEPKEY_CONSTRAINTNAME, _("Primary Key Constraint name...")); + mnu.Append(MNU_TYPEUKEY_CONSTRAINTNAME, _("Unique Key Constraint name...")); + mnu.AppendSeparator(); + mnu.Append(MNU_DELTABLE, _("Delete table...")); +}; + + +const wxArrayString ddTextTableItemFigure::dataTypes() +{ + if(ddDatatypes.IsEmpty()) + { + //Fast access ddDatatypes + ddDatatypes.Add(wxT("ANY")); + ddDatatypes.Add(wxT("serial")); + ddDatatypes.Add(wxT("boolean")); + ddDatatypes.Add(wxT("integer")); + ddDatatypes.Add(wxT("money")); + ddDatatypes.Add(wxT("varchar(n)")); + //Normal access ddDatatypes + ddDatatypes.Add(wxT("bigint")); + ddDatatypes.Add(wxT("bit(n)")); + ddDatatypes.Add(wxT("bytea")); + ddDatatypes.Add(wxT("char(n)")); + ddDatatypes.Add(wxT("cidr")); + ddDatatypes.Add(wxT("circle")); + ddDatatypes.Add(wxT("date")); + ddDatatypes.Add(wxT("double precision")); + ddDatatypes.Add(wxT("inet")); + ddDatatypes.Add(wxT("interval(n)")); + ddDatatypes.Add(wxT("line")); + ddDatatypes.Add(wxT("lseg")); + ddDatatypes.Add(wxT("macaddr")); + ddDatatypes.Add(wxT("numeric(p,s)")); + ddDatatypes.Add(wxT("path")); + ddDatatypes.Add(wxT("point")); + ddDatatypes.Add(wxT("polygon")); + ddDatatypes.Add(wxT("real")); + ddDatatypes.Add(wxT("smallint")); + ddDatatypes.Add(wxT("text")); + ddDatatypes.Add(wxT("time")); + ddDatatypes.Add(wxT("timestamp")); + ddDatatypes.Add(wxT("varbit(n)")); + } + return ddDatatypes; +} + +void ddTextTableItemFigure::setText(wxString textString) +{ + hdSimpleTextFigure::setText(textString); + + //Hack to allow column text to submit new size of text signal to tablefigure + //and then recalculate displaybox. Helps with fk autorenaming too. + if(ownerColumn) + { + ownerColumn->displayBoxUpdate(); + ownerColumn->getOwnerTable()->updateTableSize(); + ownerColumn->getOwnerTable()->updateFkObservers(); + } +} + +wxString ddTextTableItemFigure::getAlias() +{ + return colAlias; +} + +//Activate use of alias or short names at ddtextTableItems like TableNames [Columns don' use it] +void ddTextTableItemFigure::setAlias(wxString alias) +{ + if(alias.length() <= 0 || alias.length() > 3 ) + { + showAlias = false; + colAlias = wxEmptyString; + } + else + { + showAlias = true; + colAlias = alias; + } + recalculateDisplayBox(); + ownerTable->updateFkObservers(); //Only triggered by a tableName item [Not a column] + ownerTable->updateTableSize(); +} + +void ddTextTableItemFigure::setOneTimeNoAlias() +{ + oneTimeNoAlias = true; +} + +ddColumnFigure *ddTextTableItemFigure::getOwnerColumn() +{ + return ownerColumn; +} + +void ddTextTableItemFigure::setOwnerColumn(ddColumnFigure *column) +{ + ownerColumn = column; +} + +void ddTextTableItemFigure::setShowDataType(bool value) +{ + showDataType = value; +} + +hdITool *ddTextTableItemFigure::CreateFigureTool(hdDrawingView *view, hdITool *defaultTool) +{ + if(getOwnerColumn()) + { + return textEditable ? new ddColumnTextTool(view, this, defaultTool, false, wxT("New Column Name"), wxT("Rename Column")) : defaultTool; + } + else + { + setOneTimeNoAlias(); + return textEditable ? new ddColumnTextTool(view, this, defaultTool, false, wxT("New Table Name"), wxT("Rename Table")) : defaultTool; + } +} + +int ddTextTableItemFigure::getTextWidth() +{ + int w, h; + getFontMetrics(w, h); + return w; +} + +int ddTextTableItemFigure::getTextHeight() +{ + int w, h; + getFontMetrics(w, h); + return h; +} + +ddDataType ddTextTableItemFigure::getDataType() +{ + if(!getOwnerColumn()->isGeneratedForeignKey()) + return columnType; + else + { + columnType = getOwnerColumn()->getFkSource()->original->getDataType(); + return columnType; + } +} + +void ddTextTableItemFigure::setDataType(ddDataType type) +{ + columnType = type; + ownerColumn->getOwnerTable()->updateSizeOfObservers(); +} + +int ddTextTableItemFigure::getPrecision() +{ + if(getOwnerColumn()->isGeneratedForeignKey()) + { + precision = getOwnerColumn()->getFkSource()->original->getPrecision(); + return precision; + } + else + { + return precision; + } +} + +void ddTextTableItemFigure::setPrecision(int value) +{ + if(!getOwnerColumn()->isGeneratedForeignKey()) + { + precision = value; + ownerColumn->getOwnerTable()->updateSizeOfObservers(); + } +} + +void ddTextTableItemFigure::setScale(int value) +{ + if(!getOwnerColumn()->isGeneratedForeignKey()) + { + scale = value; + ownerColumn->getOwnerTable()->updateSizeOfObservers(); + } +} + +int ddTextTableItemFigure::getScale() +{ + if(getOwnerColumn()->isGeneratedForeignKey()) + { + scale = getOwnerColumn()->getFkSource()->original->getScale(); + return scale; + } + else + { + return scale; + } +} diff --git a/dd/dditems/figures/module.mk b/dd/dditems/figures/module.mk new file mode 100644 index 0000000..14e0f4c --- /dev/null +++ b/dd/dditems/figures/module.mk @@ -0,0 +1,25 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/dd/dditems/figures/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + dd/dditems/figures/ddColumnFigure.cpp \ + dd/dditems/figures/ddColumnKindIcon.cpp \ + dd/dditems/figures/ddColumnOptionIcon.cpp \ + dd/dditems/figures/ddRelationshipFigure.cpp \ + dd/dditems/figures/ddRelationshipItem.cpp \ + dd/dditems/figures/ddRelationshipTerminal.cpp \ + dd/dditems/figures/ddTableFigure.cpp \ + dd/dditems/figures/ddTextTableItemFigure.cpp + +EXTRA_DIST += \ + dd/dditems/figures/module.mk + +include dd/dditems/figures/xml/module.mk diff --git a/dd/dditems/figures/xml/ddXmlStorage.cpp b/dd/dditems/figures/xml/ddXmlStorage.cpp new file mode 100644 index 0000000..ddf3bfd --- /dev/null +++ b/dd/dditems/figures/xml/ddXmlStorage.cpp @@ -0,0 +1,1828 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddXmlStorage.cpp - Database designer class for storing / loading objects +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + + +#include +#include +#include + +// App headers +#include "dd/dditems/figures/xml/ddXmlStorage.h" +#include "dd/dditems/utilities/ddDataType.h" +#include "hotdraw/figures/hdIFigure.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/dditems/figures/ddColumnFigure.h" +#include "dd/dditems/figures/ddRelationshipFigure.h" +#include "dd/dditems/figures/ddRelationshipItem.h" +#include "dd/dditems/figures/ddRelationshipTerminal.h" +#include "dd/dditems/figures/ddColumnKindIcon.h" +#include "dd/dditems/figures/ddColumnOptionIcon.h" +#include "dd/ddmodel/ddDatabaseDesign.h" + +ddDatabaseDesign *ddXmlStorage::design = NULL; +ctlAuiNotebook *ddXmlStorage::tabs = NULL; + +ddXmlStorage::ddXmlStorage(): + hdStorage() +{ + design = NULL; + tabs = NULL; +} + +#define XML_FROM_WXSTRING(s) ((xmlChar *)(const char *)s.mb_str(wxConvUTF8)) +#define WXSTRING_FROM_XML(s) wxString((char *)s, wxConvUTF8) + +void ddXmlStorage::setModel(ddDatabaseDesign *sourceDesign) +{ + design = sourceDesign; +} + +void ddXmlStorage::setNotebook(ctlAuiNotebook *notebook) +{ + tabs = notebook; +} + +void ddXmlStorage::StartModel(xmlTextWriterPtr writer, ddDatabaseDesign *sourceDesign) +{ + int tmp; + design = sourceDesign; + // but add all dtd to doc instead url + wxString name = _("MODEL"); + wxString pubid = _("pgrm"); + wxString uri = _("pgrm"); + + xmlTextWriterWriteDTD(writer, XML_FROM_WXSTRING(name), NULL, NULL, XML_FROM_WXSTRING(getModelDTD())); + // + tmp = xmlTextWriterStartElement(writer, BAD_CAST "MODEL"); + processResult(tmp); + + // + tmp = xmlTextWriterStartElement(writer, BAD_CAST "VERSION"); + processResult(tmp); + // + wxString version = sourceDesign->getVersionXML(); + tmp = xmlTextWriterWriteAttribute(writer, BAD_CAST "VERIXLU", XML_FROM_WXSTRING(version) ); + processResult(tmp); + //Close VERSION Element + xmlTextWriterEndElement(writer); +} + +void ddXmlStorage::EndModel( xmlTextWriterPtr writer) +{ + //Close MODEL Element + xmlTextWriterEndElement(writer); + design = NULL; +} + +bool ddXmlStorage::Write(xmlTextWriterPtr writer, hdIFigure *figure) +{ + if(design == NULL) + { + wxMessageBox(_("Error saving model: not source model have been set")); + return false; + } + + switch(figure->getKindId()) + { + case DDCOLUMNOPTIONICON: + WriteLocal(writer, (ddColumnOptionIcon *)figure); + break; + case DDCOLUMNKINDICON: + WriteLocal(writer, (ddColumnKindIcon *)figure); + break; + case DDTEXTTABLEITEMFIGURE: + WriteLocal(writer, (ddTextTableItemFigure *)figure); + break; + case DDCOLUMNFIGURE: + WriteLocal(writer, (ddColumnFigure *)figure); + break; + case DDTABLEFIGURE: + WriteLocal(writer, (ddTableFigure *)figure); + break; + case DDRELATIONSHIPFIGURE: + WriteLocal(writer, (ddRelationshipFigure *)figure); + break; + } + return true; +} + +bool ddXmlStorage::processResult(int value) +{ + if (value < 0) + { + wxMessageBox(_("Fatal Error at libxml for figure persistency")); + return false; + } + return true; +} + +void ddXmlStorage::WriteLocal(xmlTextWriterPtr writer, ddColumnOptionIcon *figure) +{ + int tmp; + + //At COLUMN Element + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "OPTION", "%d", figure->getOption() ); + processResult(tmp); +} + +void ddXmlStorage::WriteLocal(xmlTextWriterPtr writer, ddColumnKindIcon *figure) +{ + int tmp; + + //At COLUMN Element + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "UKINDEX", "%d", figure->getUniqueConstraintIndex()); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ISPK", "%c", figure->isPrimaryKey() ? 'T' : 'F' ); + processResult(tmp); +} + +void ddXmlStorage::WriteLocal( xmlTextWriterPtr writer, ddTextTableItemFigure *figure) +{ + int tmp; + + // + wxString ddType = figure->dataTypes()[figure->getDataType()]; + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "COLUMNTYPE", "%s", XML_FROM_WXSTRING(ddType)); + processResult(tmp); + + if(figure->getPrecision() != -1) + { + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PRECISION", "%d", figure->getPrecision()); + processResult(tmp); + } + + if(figure->getScale() != -1) + { + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "SCALE", "%d", figure->getScale()); + processResult(tmp); + } + +} + +void ddXmlStorage::WriteLocal( xmlTextWriterPtr writer, ddColumnFigure *figure) +{ + int tmp; + + //At TABLE Element + // + tmp = xmlTextWriterStartElement(writer, BAD_CAST "COLUMN"); + + // + wxString columnName = figure->getColumnName(false); + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "NAME", "%s", XML_FROM_WXSTRING(columnName)); + processResult(tmp); + + //At Column Element + Write(writer, figure->getOptionImage()); + Write(writer, figure->getKindImage()); + Write(writer, figure->getColumnText()); + + //At Column Element + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "GENERATEFKNAME", "%c", figure->isFkNameGenerated() ? 'T' : 'F' ); + processResult(tmp); + + //Close COLUMN Element + xmlTextWriterEndElement(writer); + processResult(tmp); +} + +void ddXmlStorage::WriteLocal( xmlTextWriterPtr writer, ddTableFigure *figure) +{ + int tmp; + + //At TABLES ELEMENT + // + tmp = xmlTextWriterStartElement(writer, BAD_CAST "TABLE"); + processResult(tmp); + + // --> ddTableFigure ID + wxString TableId = design->getTableId(figure->getTableName()); + tmp = xmlTextWriterWriteAttribute(writer, BAD_CAST "TableID", XML_FROM_WXSTRING(TableId) ); + processResult(tmp); + + //Start POINTS + tmp = xmlTextWriterStartElement(writer, BAD_CAST "POINTS"); + processResult(tmp); + int posIdx, positionsCount = figure->getBasicDisplayBox().CountPositions(); + for(posIdx = 0; posIdx < positionsCount; posIdx++) + { + //Start POINT + tmp = xmlTextWriterStartElement(writer, BAD_CAST "POINT"); + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "X", "%d", figure->getBasicDisplayBox().x[posIdx]); + processResult(tmp); + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "Y", "%d", figure->getBasicDisplayBox().y[posIdx]); + processResult(tmp); + //Close POINT Element + xmlTextWriterEndElement(writer); + } + xmlTextWriterEndElement(writer); + //Close POINTS Element + + //Add Table Title + ddColumnFigure *f; + hdIteratorBase *iterator = figure->figuresEnumerator(); + iterator->Next(); //First figure is main rect + + // + tmp = xmlTextWriterStartElement(writer, BAD_CAST "TITLE"); + processResult(tmp); + f = (ddColumnFigure *) iterator->Next(); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "NAME", "%s", XML_FROM_WXSTRING(figure->getTableName())); + processResult(tmp); + + //Close TITLE Element + xmlTextWriterEndElement(writer); + + if(figure->getUkConstraintsNames().Count() > 0) + { + // + tmp = xmlTextWriterStartElement(writer, BAD_CAST "UKNAMES"); + processResult(tmp); + + // one for each name + int i, last = figure->getUkConstraintsNames().Count(); + wxString ukName; + for(i = 0; i < last; i++) + { + ukName = figure->getUkConstraintsNames()[i]; + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "UKNAME", "%s", XML_FROM_WXSTRING(ukName)); + processResult(tmp); + } + + //Close UKNAMES Element + xmlTextWriterEndElement(writer); + } + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PKNAME", "%s", XML_FROM_WXSTRING(figure->getPkConstraintName())); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "BEGINDRAWCOLS", "%d", figure->getBeginDrawCols()); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "BEGINDRAWIDXS", "%d", figure->getBeginDrawIdxs()); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MAXCOLINDEX", "%d", figure->getMaxColIndex()); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MINIDXINDEX", "%d", figure->getMinIdxIndex()); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MAXIDXINDEX", "%d", figure->getMaxIdxIndex()); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "COLSROWSSIZE", "%d", figure->getColsRowsSize()); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "COLSWINDOW", "%d", figure->getColsWindow()); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "IDXSROWSSIZE", "%d", figure->getIdxsRowsSize()); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "IDXSWINDOW", "%d", figure->getIdxsWindow()); + processResult(tmp); + + // + tmp = xmlTextWriterStartElement(writer, BAD_CAST "COLUMNS"); + processResult(tmp); + + //ALL COLUMN ELEMENT + while(iterator->HasNext()) + { + f = (ddColumnFigure *) iterator->Next(); + Write(writer, f); + } + delete iterator; + + //Close COLUMNS Element + xmlTextWriterEndElement(writer); + + //Close TABLE Element + xmlTextWriterEndElement(writer); + +} + + +void ddXmlStorage::WriteLocal( xmlTextWriterPtr writer, ddRelationshipFigure *figure) +{ + int tmp; + + //At RELATIONSHIPS Element + // + tmp = xmlTextWriterStartElement(writer, BAD_CAST "RELATIONSHIP"); + + // --> ddTableFigure ID + wxString TableId = design->getTableId(figure->getStartTable()->getTableName()); + tmp = xmlTextWriterWriteAttribute(writer, BAD_CAST "SourceTableID", XML_FROM_WXSTRING(TableId) ); + processResult(tmp); + + // + TableId = design->getTableId(figure->getEndTable()->getTableName()); + tmp = xmlTextWriterWriteAttribute(writer, BAD_CAST "DestTableID", XML_FROM_WXSTRING(TableId) ); + processResult(tmp); + + //At RELATIONSHIP Element + + //Start POINTSRELATION + tmp = xmlTextWriterStartElement(writer, BAD_CAST "POINTSRELATION"); + hdPoint point; + + for(int posIdx = 0 ; posIdx < figure->pointLinesCount(); posIdx++) + { + //At POINTSRELATION Element + //Start POINTS + tmp = xmlTextWriterStartElement(writer, BAD_CAST "POINTS"); + for(int i = 0; i < figure->pointCount(posIdx); i++) + { + //At POINTS Element + //Start POINT + tmp = xmlTextWriterStartElement(writer, BAD_CAST "POINT"); + point = figure->pointAt(posIdx, i); + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "X", "%d", point.x); + processResult(tmp); + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "Y", "%d", point.y); + processResult(tmp); + //Close POINT Element + xmlTextWriterEndElement(writer); + } + //Close POINTS Element + xmlTextWriterEndElement(writer); + } + //Close POINTSRELATION Element + xmlTextWriterEndElement(writer); + + //At RELATIONSHIP Element + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "UKINDEX", "%d", figure->getUkIndex()); + processResult(tmp); + + if(figure->getConstraintName().Length() > 0) + { + // + wxString name = figure->getConstraintName(); + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "NAME", "%s", XML_FROM_WXSTRING(name)); + processResult(tmp); + } + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ONUPDATE", "%d", figure->getOnUpdateAction()); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ONDELETE", "%d", figure->getOnDeleteAction()); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MATCHSIMPLE", "%c", figure->getMatchSimple() ? 'T' : 'F' ); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "IDENTIFYING", "%c", figure->getIdentifying() ? 'T' : 'F' ); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ONETOMANY", "%c", figure->getOneToMany() ? 'T' : 'F' ); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MANDATORY", "%c", figure->getMandatory() ? 'T' : 'F' ); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "FKFROMPK", "%c", figure->isForeignKeyFromPk() ? 'T' : 'F' ); + processResult(tmp); + + //At RELATIONSHIP Element + //Start RELATIONITEMS + tmp = xmlTextWriterStartElement(writer, BAD_CAST "RELATIONITEMS"); + + ddRelationshipItem *item; + wxString key; + columnsHashMap::iterator it; + for( it = figure->getItemsHashMap().begin(); it != figure->getItemsHashMap().end(); ++it ) + { + key = it->first; + item = it->second; + ddXmlStorage::WriteLocal(writer, item); + } + + //Close RELATIONITEMS + xmlTextWriterEndElement(writer); + + //Close RELATIONSHIP Element + xmlTextWriterEndElement(writer); +} + +void ddXmlStorage::WriteLocal( xmlTextWriterPtr writer, ddRelationshipItem *item) +{ + int tmp; + + //At RELATIONITEMS Element + // + tmp = xmlTextWriterStartElement(writer, BAD_CAST "RELATIONITEM"); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "AUTOGENFK", "%c", item->isAutomaticallyGenerated() ? 'T' : 'F' ); + processResult(tmp); + + // + wxString fkColName = item->fkColumn->getColumnName(); + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "FKCOLNAME", "%s", XML_FROM_WXSTRING(fkColName)); + processResult(tmp); + + // + wxString sourceColName = item->original->getColumnName(); + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "SOURCECOLNAME", "%s", XML_FROM_WXSTRING(sourceColName)); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "INITIALCOLNAME", "%s", XML_FROM_WXSTRING(item->originalStartColName)); + processResult(tmp); + + //Close RELATIONITEM Element + xmlTextWriterEndElement(writer); +} + +void ddXmlStorage::StarDiagrams( xmlTextWriterPtr writer) +{ + //At MODEL Element + // + xmlTextWriterStartElement(writer, BAD_CAST "DIAGRAMS"); +} + +void ddXmlStorage::EndDiagrams( xmlTextWriterPtr writer) +{ + + //Close DIAGRAMS Element + xmlTextWriterEndElement(writer); +} + +void ddXmlStorage::WriteLocal(xmlTextWriterPtr writer, hdDrawing *diagram) +{ + int tmp; + + //At DIAGRAMS Element + // + tmp = xmlTextWriterStartElement(writer, BAD_CAST "DIAGRAM"); + + //At DIAGRAM Element + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "NAME", "%s", XML_FROM_WXSTRING(diagram->getName()) ); + processResult(tmp); + + hdIteratorBase *iterator = diagram->figuresEnumerator(); + hdIFigure *tmpFigure; + ddTableFigure *table; + + while(iterator->HasNext()) + { + tmpFigure = (hdIFigure *)iterator->Next(); + if(tmpFigure->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmpFigure; + // + tmp = xmlTextWriterStartElement(writer, BAD_CAST "TABLEREF"); + + // --> ddTableFigure ID + wxString TableId = design->getTableId(table->getTableName()); + tmp = xmlTextWriterWriteAttribute(writer, BAD_CAST "TableID", XML_FROM_WXSTRING(TableId) ); + processResult(tmp); + + //Close TABLEREF Element + xmlTextWriterEndElement(writer); + } + } + delete iterator; + + //Close DIAGRAM Element + xmlTextWriterEndElement(writer); +} + +//This is needed because table doesn't have any explicit order when stored then I created all first +void ddXmlStorage::initialModelParse(xmlTextReaderPtr reader) +{ + int ret, tmp; + xmlChar *value; + + if(reader != NULL) + { + wxString tableName = wxEmptyString, tableAlias = wxEmptyString, TableID; + xmlTextReaderSetParserProp( reader, XML_PARSER_VALIDATE, 1 ); + ret = xmlTextReaderRead(reader); + while (ret == 1) + { + if(getNodeType(reader) == 1 && getNodeName(reader).IsSameAs(_("TABLE"), false)) //libxml 1 for start element + { + //Look for table ID + tmp = xmlTextReaderHasAttributes(reader); + TableID = _("TableID"); + if(tmp) + { + value = xmlTextReaderGetAttribute(reader, XML_FROM_WXSTRING(TableID)); + } + + if(value) + { + TableID = WXSTRING_FROM_XML(value); + xmlFree(value); + } + + // + wxString tmpInt; + tmp = xmlTextReaderRead(reader); //go to POINTS + wxArrayInt x, y; + if(getNodeName(reader).IsSameAs(_("POINTS")) && getNodeType(reader) == 1 && !xmlTextReaderIsEmptyElement(reader) ) + { + tmp = xmlTextReaderRead(reader); //go POINT + do + { + // --> POINT + // + tmp = xmlTextReaderRead(reader); //go X + tmp = xmlTextReaderRead(reader); //go X Value + tmp = xmlTextReaderRead(reader); //go to /X + + tmp = xmlTextReaderRead(reader); //go Y + tmp = xmlTextReaderRead(reader); //go Y Value + tmp = xmlTextReaderRead(reader); //go to /Y + + tmp = xmlTextReaderRead(reader); //go /POINT + tmp = xmlTextReaderRead(reader); //go POINT or /POINTS ? + } + while(getNodeName(reader).IsSameAs(_("POINT"), false)); + } + + tmp = xmlTextReaderRead(reader); //go to TITLE + tmp = xmlTextReaderRead(reader); //go to NAME + tmp = xmlTextReaderRead(reader); //go to NAME Value + value = xmlTextReaderValue(reader); //Value of NAME + if(value) + { + tableName = WXSTRING_FROM_XML(value); + design->addTableToMapping(TableID, tableName); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /NAME + + tmp = xmlTextReaderRead(reader); //go to ALIAS or /TITLE + if(getNodeName(reader).IsSameAs(_("ALIAS"), false)) + { + tmp = xmlTextReaderRead(reader); //go to ALIAS Value + value = xmlTextReaderValue(reader); //Value of ALIAS + if(value) + { + tableAlias = WXSTRING_FROM_XML(value); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /ALIAS + tmp = xmlTextReaderRead(reader); //go to /TITLE + } + ddTableFigure *t = new ddTableFigure(tableName, -1, -1); + + design->addTableToModel(t); + } + ret = xmlTextReaderRead(reader); + } + + //Once the document has been fully parsed check the validation results + if (xmlTextReaderIsValid(reader) != 1) + { + wxMessageBox(_("Model is not following embedded DTD definition, check it.\n")); + return; + } + } + //reset reader to begining of stream +} + + + +bool ddXmlStorage::Read(xmlTextReaderPtr reader) +{ + int ret; + + if(reader != NULL) + { + xmlTextReaderSetParserProp( reader, XML_PARSER_VALIDATE, 1 ); + ret = xmlTextReaderRead(reader); + while (ret == 1) + { + selectReader(reader); + ret = xmlTextReaderRead(reader); + } + + //Once the document has been fully parsed check the validation results + if (xmlTextReaderIsValid(reader) != 1) + { + wxMessageBox(_("Model is not following embedded DTD definition, check it.\n")); + return false; + } + + if (ret != 0) + { + wxMessageBox(_("Failed to load document from disk")); + return false; + } + else + { + return true; + } + } + return false; +} + +wxString ddXmlStorage::getNodeName(xmlTextReaderPtr reader) +{ + xmlChar *name; + wxString out = wxEmptyString; + name = xmlTextReaderName(reader); + if (name == NULL) + name = xmlStrdup(BAD_CAST "--"); + out = WXSTRING_FROM_XML(name); + xmlFree(name); + return out; +} +int ddXmlStorage::getNodeType(xmlTextReaderPtr reader) +{ + return xmlTextReaderNodeType(reader); +} + +wxString ddXmlStorage::getNodeValue(xmlTextReaderPtr reader) +{ + wxString out = wxEmptyString; + xmlChar *value; + value = xmlTextReaderValue(reader); + if (value != NULL) + { + out = WXSTRING_FROM_XML(value); + xmlFree(value); + } + return out; +} + + +void ddXmlStorage::selectReader(xmlTextReaderPtr reader) +{ + if(getNodeType(reader) == 1) //libxml 1 for start element + { + if(getNodeName(reader).IsSameAs(_("VERSION"), false)) + { + checkVersion(reader); + } + if(getNodeName(reader).IsSameAs(_("MODEL"), false)) + { + // + } + + if(getNodeName(reader).IsSameAs(_("TABLE"), false)) + { + getTable(reader); + } + + if(getNodeName(reader).IsSameAs(_("RELATIONSHIP"), false)) + { + ddRelationshipFigure *r = getRelationship(reader); + design->addTableToModel(r); + } + + if(getNodeName(reader).IsSameAs(_("DIAGRAMS"), false)) + { + initDiagrams(reader); + } + } +} + +//Check if version of modeler with xml input is compatible +void ddXmlStorage::checkVersion(xmlTextReaderPtr reader) +{ + /* + + + + */ + int tmp; + wxString Number; + xmlChar *value; + // + tmp = xmlTextReaderHasAttributes(reader); + Number = _("VERIXLU"); + if(tmp) + { + value = xmlTextReaderGetAttribute(reader, XML_FROM_WXSTRING(Number)); + } + + if(value) + { + Number = WXSTRING_FROM_XML(value); + xmlFree(value); + } + if(!Number.IsSameAs(_("1.0"))) + { + wxMessageBox(_("Invalid version of XML file for pgAdmin database designer found"), _("Invalid XML"), wxOK | wxICON_ERROR); + } +} + +//Table isn't create here because fk needs all tables created before assign it +ddTableFigure *ddXmlStorage::getTable(xmlTextReaderPtr reader) +{ + /* + + + + + + + + + + + + + + + + + + + + + + + + + */ + + int tmp; + wxString TableID, node, tmpInt; + xmlChar *value; + + // + tmp = xmlTextReaderHasAttributes(reader); + TableID = _("TableID"); + if(tmp) + { + value = xmlTextReaderGetAttribute(reader, XML_FROM_WXSTRING(TableID)); + } + + if(value) + { + TableID = WXSTRING_FROM_XML(value); + xmlFree(value); + } + + // --> ATTRIBUTE* + //Element(s) Attribute* + // NEED TO IMPLEMENT THIS + + + // -->POINTS + // + tmp = xmlTextReaderRead(reader); //go to POINTS + wxArrayInt x, y; + if(getNodeName(reader).IsSameAs(_("POINTS")) && getNodeType(reader) == 1 && !xmlTextReaderIsEmptyElement(reader) ) + { + tmp = xmlTextReaderRead(reader); //go POINT + do + { + // --> POINT + // + tmp = xmlTextReaderRead(reader); //go X + tmp = xmlTextReaderRead(reader); //go X Value + value = xmlTextReaderValue(reader); //Value of X + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + x.Add(wxAtoi(tmpInt)); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /X + + tmp = xmlTextReaderRead(reader); //go Y + tmp = xmlTextReaderRead(reader); //go Y Value + value = xmlTextReaderValue(reader); //Value of Y + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + y.Add(wxAtoi(tmpInt)); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /Y + tmp = xmlTextReaderRead(reader); //go /POINT + tmp = xmlTextReaderRead(reader); //go POINT or /POINTS ? + } + while(getNodeName(reader).IsSameAs(_("POINT"), false)); + } + + if(!getNodeName(reader).IsSameAs(_("POINTS"), false)) + processResult(-1); + + // --> TITLE + // + // + // + wxString tableName = wxEmptyString; + wxString tableAlias = wxEmptyString; + + tmp = xmlTextReaderRead(reader); //go to TITLE + tmp = xmlTextReaderRead(reader); //go to NAME + tmp = xmlTextReaderRead(reader); //go to NAME Value + value = xmlTextReaderValue(reader); //Value of NAME + + if(value) + { + tableName = WXSTRING_FROM_XML(value); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /NAME + tmp = xmlTextReaderRead(reader); //go to ALIAS or /TITLE + if(getNodeName(reader).IsSameAs(_("ALIAS"), false)) + { + tmp = xmlTextReaderRead(reader); //go to ALIAS Value + value = xmlTextReaderValue(reader); //Value of ALIAS + if(value) + { + tableAlias = WXSTRING_FROM_XML(value); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /ALIAS + tmp = xmlTextReaderRead(reader); //go to /TITLE + } + + // --> UKNAMES? + // + // + tmp = xmlTextReaderRead(reader); //go to UKNAMES or PKNAMES? + wxArrayString ukNames; + if(getNodeName(reader).IsSameAs(_("UKNAMES"), false)) + { + tmp = xmlTextReaderRead(reader); //go UKNAME + do + { + tmp = xmlTextReaderRead(reader); //go UKNAME Value + value = xmlTextReaderValue(reader); //Value of UKNAME + if(value) + { + ukNames.Add(WXSTRING_FROM_XML(value)); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /UKNAME + tmp = xmlTextReaderRead(reader); //go to UKNAME or /UKNAMES ? + } + while(getNodeName(reader).IsSameAs(_("UKNAME"), false)); + tmp = xmlTextReaderRead(reader); //go to PKNAME + } + + // --> PKNAME + // + wxString pkName; + if(getNodeName(reader).IsSameAs(_("PKNAME"))) + { + tmp = xmlTextReaderRead(reader); //go to PKNAME Value or PKNAME node? + if(!getNodeName(reader).IsSameAs(_("PKNAME"))) + { + value = xmlTextReaderValue(reader); //Value of PKNAME + if(value) + { + pkName = WXSTRING_FROM_XML(value); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /PKNAME + } + } + + int beginDrawCols, beginDrawIdxs, maxColIndex, minIdxIndex, maxIdxIndex, colsRowsSize, colsWindow, idxsRowsSize, idxsWindow; + // --> BEGINDRAWCOLS + // + tmp = xmlTextReaderRead(reader); //go to BEGINDRAWCOLS + tmp = xmlTextReaderRead(reader); //go to BEGINDRAWCOLS Value + value = xmlTextReaderValue(reader); //Value + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + beginDrawCols = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /BEGINDRAWCOLS + tmp = xmlTextReaderRead(reader); //go to BEGINDRAWIDXS + + // --> BEGINDRAWIDXS + // + tmp = xmlTextReaderRead(reader); //go to BEGINDRAWIDXS Value + value = xmlTextReaderValue(reader); //Value + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + beginDrawIdxs = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /BEGINDRAWIDXS + tmp = xmlTextReaderRead(reader); //go to MAXCOLINDEX + + // --> MAXCOLINDEX + // + tmp = xmlTextReaderRead(reader); //go to MAXCOLINDEX Value + value = xmlTextReaderValue(reader); //Value + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + maxColIndex = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /MAXCOLINDEX + tmp = xmlTextReaderRead(reader); //go to MINIDXINDEX + + // --> MINIDXINDEX + // + tmp = xmlTextReaderRead(reader); //go to MINIDXINDEX Value + value = xmlTextReaderValue(reader); //Value + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + minIdxIndex = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /MINIDXINDEX + tmp = xmlTextReaderRead(reader); //go to MAXIDXINDEX + + // --> MAXIDXINDEX + // + tmp = xmlTextReaderRead(reader); //go to MAXIDXINDEX Value + value = xmlTextReaderValue(reader); //Value + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + maxIdxIndex = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /MAXIDXINDEX + tmp = xmlTextReaderRead(reader); //go to COLSROWSSIZE + + // --> COLSROWSSIZE + // + tmp = xmlTextReaderRead(reader); //go to COLSROWSSIZE Value + value = xmlTextReaderValue(reader); //Value + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + colsRowsSize = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /COLSROWSSIZE + tmp = xmlTextReaderRead(reader); //go to COLSWINDOW + + // --> COLSWINDOW + // + tmp = xmlTextReaderRead(reader); //go to COLSWINDOW Value + value = xmlTextReaderValue(reader); //Value + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + colsWindow = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /COLSWINDOW + tmp = xmlTextReaderRead(reader); //go to IDXSROWSSIZE + + // --> IDXSROWSSIZE + // + tmp = xmlTextReaderRead(reader); //go to IDXSROWSSIZE Value + value = xmlTextReaderValue(reader); //Value + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + idxsRowsSize = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /IDXSROWSSIZE + tmp = xmlTextReaderRead(reader); //go to IDXSWINDOW + + // --> IDXSWINDOW + //*/ + tmp = xmlTextReaderRead(reader); //go to IDXSWINDOW Value + value = xmlTextReaderValue(reader); //Value + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + idxsWindow = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /IDXSWINDOW + // --> COLUMNS + // + + tmp = xmlTextReaderRead(reader); //go to COLUMNS + + //Use empty table without columns created at preparsing to fill it with metadata + + ddTableFigure *t = design->getTable(tableName); + if(t != NULL) + t->InitTableValues(ukNames, pkName, beginDrawCols, beginDrawIdxs, maxColIndex, minIdxIndex, maxIdxIndex, colsRowsSize, colsWindow, idxsRowsSize, idxsWindow); + else + wxMessageBox(_("Table initial metadata info not found")); + + + //CHANGE 300,300 for right value when displaybox metadata will be added + + + //COLUMNS node have COLUMN children? + if(getNodeName(reader).IsSameAs(_("COLUMNS")) && getNodeType(reader) == 1 && !xmlTextReaderIsEmptyElement(reader) ) + { + ddColumnFigure *c; + do + { + c = getColumn(reader, t); + if(c) + { + t->addColumnFromStorage(c); + c->setRightIconForColumn(); + } + } + while(c != NULL); + //now at + } + + tmp = xmlTextReaderRead(reader); //go to + t->syncInternalsPosAt(x, y); //synchronize positions + t->updateTableSize(); + return t; +} + +ddColumnFigure *ddXmlStorage::getColumn(xmlTextReaderPtr reader, ddTableFigure *colOwner) +{ + /* + + + + + + + + + + */ + + xmlChar *value; + int tmp; + tmp = xmlTextReaderRead(reader); //go to COLUMN + if(getNodeName(reader).IsSameAs(_("COLUMN")) && getNodeType(reader) == 1 && !xmlTextReaderIsEmptyElement(reader) ) + { + // --> ATTRIBUTE* + //Element(s) Attribute* + // NEED TO IMPLEMENT THIS + + // --> NAME + // + wxString columnName; + tmp = xmlTextReaderRead(reader); //go to NAME + tmp = xmlTextReaderRead(reader); //go to NAME Value + value = xmlTextReaderValue(reader); //Value of NAME + if(value) + { + columnName = WXSTRING_FROM_XML(value); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /NAME + tmp = xmlTextReaderRead(reader); //go to OPTION + + // --> OPTION + // + int option; + wxString tmpInt; + tmp = xmlTextReaderRead(reader); //go to OPTION Value + value = xmlTextReaderValue(reader); //Value + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + option = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /OPTION + tmp = xmlTextReaderRead(reader); //go to UKINDEX + + // --> UKINDEX + // + int ukindex; + tmp = xmlTextReaderRead(reader); //go to UKINDEX Value + value = xmlTextReaderValue(reader); //Value + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + ukindex = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /UKINDEX + tmp = xmlTextReaderRead(reader); //go to ISPK + + // --> ISPK + // + bool isPk = false; + tmp = xmlTextReaderRead(reader); //go to ISPK Value + value = xmlTextReaderValue(reader); //Value of ISPK + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + isPk = tmpInt.IsSameAs(_("T")); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /ISPK + + // --> COLUMNTYPE + // + wxString columnType; + tmp = xmlTextReaderRead(reader); //go to COLUMNTYPE + tmp = xmlTextReaderRead(reader); //go to COLUMNTYPE Value + value = xmlTextReaderValue(reader); //Value of COLUMNTYPE + if(value) + { + columnType = WXSTRING_FROM_XML(value); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /COLUMNTYPE + + // --> PRECISION? + // + tmp = xmlTextReaderRead(reader); //go to PRECISION? or SCALE? or ALIAS? or GENERATEFKNAME + int precision = -1; + if(getNodeName(reader).IsSameAs(_("PRECISION"))) + { + tmp = xmlTextReaderRead(reader); //go to PRECISION Value + value = xmlTextReaderValue(reader); //Value of PRECISION + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + precision = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /PRECISION + tmp = xmlTextReaderRead(reader); //go to SCALE? or ALIAS? or GENERATEFKNAME + } + + // --> SCALE? + // + + int scale = -1; + if(getNodeName(reader).IsSameAs(_("SCALE"))) + { + tmp = xmlTextReaderRead(reader); //go to SCALE Value + value = xmlTextReaderValue(reader); //Value of SCALE + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + scale = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /SCALE + tmp = xmlTextReaderRead(reader); //go to ALIAS? or GENERATEFKNAME + } + + // --> GENERATEFKNAME + // + bool generateFkName = false; + tmp = xmlTextReaderRead(reader); //go to GENERATEFKNAME Value + value = xmlTextReaderValue(reader); //Value of GENERATEFKNAME + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + generateFkName = tmpInt.IsSameAs(_("T")); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /GENERATEFKNAME + tmp = xmlTextReaderRead(reader); //go to /COLUMN + + return new ddColumnFigure(columnName, colOwner, (ddColumnOptionType)option, generateFkName, isPk, columnType, precision, scale, ukindex, NULL, NULL); + } + return NULL; //found /COLUMNS node +} + +ddRelationshipFigure *ddXmlStorage::getRelationship(xmlTextReaderPtr reader) +{ + /* + + + + + + + + + + + + + + + + + + + + + + + + */ + + xmlChar *value; + wxString tmpInt; + int tmp; + + // + tmp = xmlTextReaderHasAttributes(reader); + wxString SourceTableID = _("SourceTableID"); + if(tmp) + { + value = xmlTextReaderGetAttribute(reader, XML_FROM_WXSTRING(SourceTableID)); + } + + if(value) + { + SourceTableID = WXSTRING_FROM_XML(value); + xmlFree(value); + } + + // + tmp = xmlTextReaderHasAttributes(reader); + wxString DestTableID = _("DestTableID"); + if(tmp) + { + value = xmlTextReaderGetAttribute(reader, XML_FROM_WXSTRING(DestTableID)); + } + + if(value) + { + DestTableID = WXSTRING_FROM_XML(value); + xmlFree(value); + } + + ddTableFigure *source = design->getTable(design->getTableName(SourceTableID)); + ddTableFigure *destination = design->getTable(design->getTableName(DestTableID)); + + ddRelationshipFigure *relation = new ddRelationshipFigure(); + relation->setStartTerminal(new ddRelationshipTerminal(relation, false)); + relation->setEndTerminal(new ddRelationshipTerminal(relation, true)); + relation->clearPoints(0); + bool firstPoint = true; + // --> ATTRIBUTE* + //Element(s) Attribute* + // NEED TO IMPLEMENT THIS + + // --> POINTSRELATION + // + int x, y, posIdx = 0; + + tmp = xmlTextReaderRead(reader); //go to POINTSRELATION + if(getNodeName(reader).IsSameAs(_("POINTSRELATION"), false)) + { + //only first time inside POINTSRELATION this is needed + tmp = xmlTextReaderRead(reader); //go POINTS + do + { + + if(!firstPoint) //because at first time position for diagram exists at relationship yet + { + relation->AddPosForNewDiagram(); + } + else + { + firstPoint = false; + } + + if(getNodeName(reader).IsSameAs(_("POINTS")) && getNodeType(reader) == 1 && !xmlTextReaderIsEmptyElement(reader) ) + { + //only first time inside POINTS this is needed + tmp = xmlTextReaderRead(reader); //go POINT + do + { + tmp = xmlTextReaderRead(reader); //go X + tmp = xmlTextReaderRead(reader); //go X Value + value = xmlTextReaderValue(reader); //Value of X + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + x = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /X + + tmp = xmlTextReaderRead(reader); //go Y + tmp = xmlTextReaderRead(reader); //go Y Value + value = xmlTextReaderValue(reader); //Value of Y + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + y = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /Y + tmp = xmlTextReaderRead(reader); //go /POINT + relation->addPoint(posIdx, x, y); + + tmp = xmlTextReaderRead(reader); //go POINT or /POINTS? + } + while(getNodeName(reader).IsSameAs(_("POINT"), false) && getNodeType(reader) == 1); + } + else + { + if(! (getNodeName(reader).IsSameAs(_("POINTS")) && xmlTextReaderIsEmptyElement(reader)) ) + { + processResult(-1); + } + } + posIdx++; //change of points array then change view position index + tmp = xmlTextReaderRead(reader); //go POINTS or /POINTSRELATION? + } + while(getNodeName(reader).IsSameAs(_("POINTS"), false) && getNodeType(reader) == 1); + } + + if(!getNodeName(reader).IsSameAs(_("POINTSRELATION"), false)) + { + processResult(-1); + } + + // --> UKINDEX + // + int ukindex; + tmp = xmlTextReaderRead(reader); //go to UKINDEX + tmp = xmlTextReaderRead(reader); //go to UKINDEX Value + value = xmlTextReaderValue(reader); //Value + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + ukindex = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /UKINDEX + + // --> NAME + // + tmp = xmlTextReaderRead(reader); //go to NAME or ONUPDATE + wxString RelationshipName = wxEmptyString; + if(getNodeName(reader).IsSameAs(_("NAME"), false)) + { + + tmp = xmlTextReaderRead(reader); //go to NAME Value + value = xmlTextReaderValue(reader); //Value of NAME + if(value) + { + RelationshipName = WXSTRING_FROM_XML(value); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /NAME + tmp = xmlTextReaderRead(reader); //go to ONUPDATE + } + + // --> ONUPDATE + // + int onUpdate; + + tmp = xmlTextReaderRead(reader); //go to ONUPDATE Value + value = xmlTextReaderValue(reader); //Value + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + onUpdate = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /ONUPDATE + tmp = xmlTextReaderRead(reader); //go to ONDELETE + + // --> ONDELETE + // + int onDelete; + tmp = xmlTextReaderRead(reader); //go to ONDELETE Value + value = xmlTextReaderValue(reader); //Value + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + onDelete = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /ONDELETE + tmp = xmlTextReaderRead(reader); //go to MATCHSIMPLE + + // --> MATCHSIMPLE + // + bool matchSimple = false; + tmp = xmlTextReaderRead(reader); //go to MATCHSIMPLE Value + value = xmlTextReaderValue(reader); //Value of MATCHSIMPLE + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + matchSimple = tmpInt.IsSameAs(_("T")); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /MATCHSIMPLE + tmp = xmlTextReaderRead(reader); //go to IDENTIFYING + + // --> IDENTIFYING + // + bool identifying = false; + tmp = xmlTextReaderRead(reader); //go to IDENTIFYING Value + value = xmlTextReaderValue(reader); //Value of IDENTIFYING + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + identifying = tmpInt.IsSameAs(_("T")); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /IDENTIFYING + tmp = xmlTextReaderRead(reader); //go to ONETOMANY + + // --> ONETOMANY + // + bool oneToMany = false; + tmp = xmlTextReaderRead(reader); //go to ONETOMANY Value + value = xmlTextReaderValue(reader); //Value of ONETOMANY + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + oneToMany = tmpInt.IsSameAs(_("T")); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /ONETOMANY + tmp = xmlTextReaderRead(reader); //go to MANDATORY + + // --> MANDATORY + // + bool mandatory = false; + tmp = xmlTextReaderRead(reader); //go to MANDATORY Value + value = xmlTextReaderValue(reader); //Value of MANDATORY + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + mandatory = tmpInt.IsSameAs(_("T")); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /MANDATORY + tmp = xmlTextReaderRead(reader); //go to FKFROMPK + + // --> FKFROMPK + // + bool fkFromPk = false; + tmp = xmlTextReaderRead(reader); //go to FKFROMPK Value + value = xmlTextReaderValue(reader); //Value of FKFROMPK + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + fkFromPk = tmpInt.IsSameAs(_("T")); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /FKFROMPK + + + //refresh relationship after all values were setted + relation->initRelationValues(source, destination, ukindex, RelationshipName, (actionKind) onUpdate, (actionKind) onDelete, matchSimple, identifying, oneToMany, mandatory, fkFromPk); + + + // --> RELATIONITEMS + // + tmp = xmlTextReaderRead(reader); //go to RELATIONITEMS + if(getNodeName(reader).IsSameAs(_("RELATIONITEMS")) && getNodeType(reader) == 1 && !xmlTextReaderIsEmptyElement(reader) ) + { + tmp = xmlTextReaderRead(reader); //go RELATIONITEM + do + { + //Now only add item to relationship + ddRelationshipItem *item = getRelationshipItem(reader, relation, source, destination); + relation->getItemsHashMap()[item->original->getColumnName()] = item; + + tmp = xmlTextReaderRead(reader); //go to RELATIONITEM or /RELATIONITEMS + } + while(getNodeName(reader).IsSameAs(_("RELATIONITEM"), false)); + } + + tmp = xmlTextReaderRead(reader); //go to /RELATIONSHIP + + relation->updateConnection(0); + return relation; +} + +ddRelationshipItem *ddXmlStorage::getRelationshipItem(xmlTextReaderPtr reader, ddRelationshipFigure *itemOwner, ddTableFigure *source, ddTableFigure *destination) +{ + /* + + + + + + + */ + xmlChar *value; + wxString tmpInt; + int tmp; + + // --> AUTOGENFK + // + bool autoGenFk = false; + tmp = xmlTextReaderRead(reader); //go to AUTOGENFK + tmp = xmlTextReaderRead(reader); //go to AUTOGENFK Value + value = xmlTextReaderValue(reader); //Value of AUTOGENFK + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + autoGenFk = tmpInt.IsSameAs(_("T")); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /AUTOGENFK + + // + wxString fkColName; + tmp = xmlTextReaderRead(reader); //go to FKCOLNAME + tmp = xmlTextReaderRead(reader); //go to FKCOLNAME Value + value = xmlTextReaderValue(reader); //Value of FKCOLNAME + if(value) + { + fkColName = WXSTRING_FROM_XML(value); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /FKCOLNAME + + // + wxString sourceColName; + tmp = xmlTextReaderRead(reader); //go to SOURCECOLNAME + tmp = xmlTextReaderRead(reader); //go to SOURCECOLNAME Value + value = xmlTextReaderValue(reader); //Value of SOURCECOLNAME + if(value) + { + sourceColName = WXSTRING_FROM_XML(value); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /SOURCECOLNAME + + // + wxString initialColName; + tmp = xmlTextReaderRead(reader); //go to INITIALCOLNAME + tmp = xmlTextReaderRead(reader); //go to INITIALCOLNAME Value + value = xmlTextReaderValue(reader); //Value of INITIALCOLNAME + if(value) + { + initialColName = WXSTRING_FROM_XML(value); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /INITIALCOLNAME + + // + tmp = xmlTextReaderRead(reader); //go to INITIALALIASNAME + wxString initialAliasName = wxEmptyString; + if(getNodeName(reader).IsSameAs(_("INITIALALIASNAME"), false)) + { + tmp = xmlTextReaderRead(reader); //go to INITIALALIASNAME Value + value = xmlTextReaderValue(reader); //Value of INITIALALIASNAME + if(value) + { + initialAliasName = WXSTRING_FROM_XML(value); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /INITIALALIASNAME + tmp = xmlTextReaderRead(reader); //go to /RELATIONITEM + } + + ddRelationshipItem *item = new ddRelationshipItem(); + ddColumnFigure *sourceCol = source->getColByName(sourceColName); + ddColumnFigure *destinationCol = destination->getColByName(fkColName); + item->initRelationshipItemValues(itemOwner, destination, autoGenFk, destinationCol, sourceCol, initialColName); + + return item; + +} + +void ddXmlStorage::initDiagrams(xmlTextReaderPtr reader) +{ + /* + + + + + + + + */ + + //At DIAGRAMS Element + xmlChar *value = NULL; + wxString diagramName; + hdDrawing *newDiagram; + int tmp; + + // + tmp = xmlTextReaderRead(reader); //go to DIAGRAM + if(getNodeName(reader).IsSameAs(_("DIAGRAM")) && getNodeType(reader) == 1 && !xmlTextReaderIsEmptyElement(reader) ) + { + do + { + // + tmp = xmlTextReaderRead(reader); //go to NAME + tmp = xmlTextReaderRead(reader); //go to NAME Value + value = xmlTextReaderValue(reader); //Value of NAME + if(value) + { + diagramName = WXSTRING_FROM_XML(value); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /NAME + + if(tabs && design) + { + newDiagram = design->createDiagram(tabs, diagramName, true); + tabs->AddPage(newDiagram->getView(), diagramName); + } + else + { + processResult(-1); + } + // + // + tmp = xmlTextReaderRead(reader); //go to TABLEREF + bool firstTime = true; + if(getNodeName(reader).IsSameAs(_("TABLEREF")) && xmlTextReaderIsEmptyElement(reader)) + { + wxString TableID, tableName; + if(firstTime) + { + firstTime = false; + } + else + { + tmp = xmlTextReaderRead(reader); //go to TABLEREF + } + do + { + // + tmp = xmlTextReaderHasAttributes(reader); + TableID = _("TableID"); + if(tmp) + { + value = xmlTextReaderGetAttribute(reader, XML_FROM_WXSTRING(TableID)); + } + + if(value) + { + TableID = WXSTRING_FROM_XML(value); + xmlFree(value); + } + + tableName = design->getTableName(TableID); + //Add table to diagram + newDiagram->add(design->getTable(tableName)); + tmp = xmlTextReaderRead(reader); //go to TABLEREF or /DIAGRAM? + } + while(getNodeName(reader).IsSameAs(_("TABLEREF"), false)); + } + //After adding a new diagram check for all needed relationships at diagram and add it. + if(design) + { + design->getEditor()->checkRelationshipsConsistency(newDiagram->getView()->getIdx()); + newDiagram->getView()->Refresh(); + } + else + { + processResult(-1); + } + tmp = xmlTextReaderRead(reader); //go to DIAGRAM or /DIAGRAMS? + } + while(getNodeName(reader).IsSameAs(_("DIAGRAM"), false)); + } + + + +} + +//Temporary DTD will change later +wxString ddXmlStorage::getModelDTD() +{ + wxString dtd = wxEmptyString; + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(" "); + dtd += _(""); + dtd += _(""); + dtd += _(" "); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(" "); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(" "); + dtd += _(" "); + dtd += _(""); + dtd += _(""); + dtd += _(" "); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(" "); + dtd += _(""); + dtd += _(" "); + dtd += _(" "); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(" "); + dtd += _(" "); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(" "); + dtd += _(" "); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(" "); + dtd += _(""); + dtd += _(""); + dtd += _(" "); + dtd += _(" "); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + + return dtd; +} diff --git a/dd/dditems/figures/xml/module.mk b/dd/dditems/figures/xml/module.mk new file mode 100644 index 0000000..d68fdc9 --- /dev/null +++ b/dd/dditems/figures/xml/module.mk @@ -0,0 +1,16 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/dd/dditems/figures/xml/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + dd/dditems/figures/xml/ddXmlStorage.cpp + +EXTRA_DIST += \ + dd/dditems/figures/xml/module.mk diff --git a/dd/dditems/handles/ddAddColButtonHandle.cpp b/dd/dditems/handles/ddAddColButtonHandle.cpp new file mode 100644 index 0000000..ece6568 --- /dev/null +++ b/dd/dditems/handles/ddAddColButtonHandle.cpp @@ -0,0 +1,76 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddAddColButtonHandle.cpp - A handle for a table figure that allow to graphically add columns +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dd/dditems/handles/ddAddColButtonHandle.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/dditems/utilities/ddDataType.h" +#include "hotdraw/main/hdDrawingView.h" + +//Images +#include "images/ddAddColumnCursor.pngc" + +ddAddColButtonHandle::ddAddColButtonHandle(hdIFigure *owner, hdILocator *buttonLocator , wxBitmap &buttonImage, wxSize &size): + hdButtonHandle(owner, buttonLocator, buttonImage, size) +{ +} + +ddAddColButtonHandle::~ddAddColButtonHandle() +{ +} + +void ddAddColButtonHandle::invokeStart(hdMouseEvent &event, hdDrawingView *view) +{ + ddTableFigure *table = (ddTableFigure *) getOwner(); + wxTextEntryDialog nameDialog(view, wxT("New column name"), wxT("Add a column")); + bool again; + do + { + again = false; + int answer = nameDialog.ShowModal(); + if (answer == wxID_OK) + { + wxString name = nameDialog.GetValue(); + if(table->getColByName(name) == NULL) + { + table->addColumn(view->getIdx(), new ddColumnFigure(name, table)); + view->notifyChanged(); + } + else + { + wxString msg(wxT("Error trying to add new column '")); + msg.Append(name); + msg.Append(wxT("' column name already in use")); + wxMessageDialog info( view, msg , + wxT("Column name already in use"), + wxNO_DEFAULT | wxOK | wxICON_EXCLAMATION); + again = true; + info.ShowModal(); + } + } + + } + while(again); + view->Refresh(); +} + +void ddAddColButtonHandle::invokeStep(hdMouseEvent &event, hdDrawingView *view) +{ +} + +void ddAddColButtonHandle::invokeEnd(hdMouseEvent &event, hdDrawingView *view) +{ +} diff --git a/dd/dditems/handles/ddAddFkButtonHandle.cpp b/dd/dditems/handles/ddAddFkButtonHandle.cpp new file mode 100644 index 0000000..ffb0d57 --- /dev/null +++ b/dd/dditems/handles/ddAddFkButtonHandle.cpp @@ -0,0 +1,73 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddAddFkButtonHandle.cpp - A handle for a table figure that allow to graphically add relationships (fk) +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dd/dditems/handles/ddAddFkButtonHandle.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/dditems/utilities/ddDataType.h" +#include "hotdraw/tools/hdConnectionCreationTool.h" +#include "hotdraw/utilities/hdMouseEvent.h" +#include "dd/dditems/figures/ddRelationshipFigure.h" +#include "dd/dditems/figures/ddRelationshipTerminal.h" + +//Images +#include "images/ddRelationshipCursor.pngc" + +ddAddFkButtonHandle::ddAddFkButtonHandle(hdIFigure *owner, hdILocator *buttonLocator , wxBitmap &buttonImage, wxSize &size): + hdButtonHandle(owner, buttonLocator, buttonImage, size) +{ +} + +ddAddFkButtonHandle::~ddAddFkButtonHandle() +{ +} + +void ddAddFkButtonHandle::invokeStart(hdMouseEvent &event, hdDrawingView *view) +{ + if(getOwner()->ms_classInfo.IsKindOf(&ddTableFigure::ms_classInfo)) + { + ddRelationshipFigure *fkConnection = new ddRelationshipFigure(); + //Check figure available positions for diagrams, add at least needed to allow initialization of the class + int i, start; + start = fkConnection->displayBox().CountPositions(); + for(i = start; i < (view->getIdx() + 1); i++) + { + fkConnection->AddPosForNewDiagram(); + } + fkConnection->setStartTerminal(new ddRelationshipTerminal(fkConnection, false)); + fkConnection->setEndTerminal(new ddRelationshipTerminal(fkConnection, true)); + hdConnectionCreationTool *conn = new hdConnectionCreationTool(view, fkConnection); + view->setTool(conn); + // Simulate button down to start connection of foreign key + wxMouseEvent e(wxEVT_LEFT_DOWN); + e.m_x = event.GetPosition().x; + e.m_y = event.GetPosition().y; + e.SetEventObject(view); + hdMouseEvent evento(e, view); + conn->mouseDown(evento); + ddTableFigure *table = (ddTableFigure *) getOwner(); + table->setSelectFkDestMode(true); + view->notifyChanged(); + } +} + +void ddAddFkButtonHandle::invokeStep(hdMouseEvent &event, hdDrawingView *view) +{ +} + +void ddAddFkButtonHandle::invokeEnd(hdMouseEvent &event, hdDrawingView *view) +{ +} diff --git a/dd/dditems/handles/ddMinMaxTableButtonHandle.cpp b/dd/dditems/handles/ddMinMaxTableButtonHandle.cpp new file mode 100644 index 0000000..153e686 --- /dev/null +++ b/dd/dditems/handles/ddMinMaxTableButtonHandle.cpp @@ -0,0 +1,62 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddMinMaxTableButtonHandle.cpp - A handle for a table figure that allow to graphically minimize or maximize table window size +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dd/dditems/handles/ddMinMaxTableButtonHandle.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/dditems/utilities/ddDataType.h" +#include "hotdraw/main/hdDrawingView.h" + +//Images +#include "images/ddMinMaxCursor.pngc" + +ddMinMaxTableButtonHandle::ddMinMaxTableButtonHandle(hdIFigure *owner, hdILocator *buttonLocator , wxBitmap &buttonImage, wxBitmap &buttonSecondImage, wxSize &size): + hdButtonHandle(owner, buttonLocator, buttonImage, size) +{ + buttonMaximizeImage = buttonSecondImage; + tmpImage = buttonImage; + showFirst = true; +} + +ddMinMaxTableButtonHandle::~ddMinMaxTableButtonHandle() +{ +} + +void ddMinMaxTableButtonHandle::invokeStart(hdMouseEvent &event, hdDrawingView *view) +{ +} + +void ddMinMaxTableButtonHandle::invokeStep(hdMouseEvent &event, hdDrawingView *view) +{ +} + +void ddMinMaxTableButtonHandle::invokeEnd(hdMouseEvent &event, hdDrawingView *view) +{ + ddTableFigure *table = (ddTableFigure *) getOwner(); + + if(showFirst) + { + buttonIcon = buttonMaximizeImage; + table->setColumnsWindow(view->getIdx(), 1); + } + else + { + buttonIcon = tmpImage; + table->setColumnsWindow(table->getTotalColumns(), true); + } + showFirst = !showFirst; + view->notifyChanged(); +} diff --git a/dd/dditems/handles/ddRemoveTableButtonHandle.cpp b/dd/dditems/handles/ddRemoveTableButtonHandle.cpp new file mode 100644 index 0000000..0c8852c --- /dev/null +++ b/dd/dditems/handles/ddRemoveTableButtonHandle.cpp @@ -0,0 +1,77 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddRemoveTableButtonHandle.cpp - A handle for a table figure that allow to delete it +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dd/dditems/handles/ddRemoveTableButtonHandle.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/dditems/figures/ddRelationshipFigure.h" +#include "dd/dditems/utilities/ddDataType.h" +#include "hotdraw/main/hdDrawingView.h" +#include "hotdraw/utilities/hdRemoveDeleteDialog.h" +#include "dd/ddmodel/ddDrawingEditor.h" +#include "dd/ddmodel/ddDatabaseDesign.h" + +//Images +#include "images/ddDeleteTableCursor.pngc" + +ddRemoveTableButtonHandle::ddRemoveTableButtonHandle(hdIFigure *owner, hdILocator *buttonLocator , wxBitmap &buttonImage, wxSize &size): + hdButtonHandle(owner, buttonLocator, buttonImage, size) +{ +} + +ddRemoveTableButtonHandle::~ddRemoveTableButtonHandle() +{ +} + +void ddRemoveTableButtonHandle::invokeStart(hdMouseEvent &event, hdDrawingView *view) +{ +} + +void ddRemoveTableButtonHandle::invokeStep(hdMouseEvent &event, hdDrawingView *view) +{ +} + +void ddRemoveTableButtonHandle::invokeEnd(hdMouseEvent &event, hdDrawingView *view) +{ + if(view && getOwner()) + { + ddTableFigure *table = (ddTableFigure *) getOwner(); + hdRemoveDeleteDialog dialog(_("Are you sure you wish to delete table ") + table->getTableName() + wxT("?"), _("Delete table?"), view); + int answer = dialog.ShowModal(); + if (answer == DD_DELETE) + { + ddDrawingEditor *editor = (ddDrawingEditor *) view->editor(); + //Unselect table at all diagrams + editor->removeFromAllSelections(table); + //Drop foreign keys with this table as origin or destination + table->processDeleteAlert(view->getDrawing()); + //Drop table + editor->deleteModelFigure(table); + editor->getDesign()->refreshBrowser(); + editor->checkRelationshipsConsistency(view->getIdx()); + view->notifyChanged(); + } + else if(answer == DD_REMOVE) + { + ddDrawingEditor *editor = (ddDrawingEditor *) view->editor(); + editor->getExistingDiagram(view->getIdx())->removeFromSelection(table); + editor->getExistingDiagram(view->getIdx())->remove(table); + editor->checkRelationshipsConsistency(view->getIdx()); + view->notifyChanged(); + } + + } +} diff --git a/dd/dditems/handles/ddScrollBarHandle.cpp b/dd/dditems/handles/ddScrollBarHandle.cpp new file mode 100644 index 0000000..9542e88 --- /dev/null +++ b/dd/dditems/handles/ddScrollBarHandle.cpp @@ -0,0 +1,131 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddScrollBarHandle.cpp - A handle for a table figure that allow to scroll it when table is not in full size +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dd/dditems/handles/ddScrollBarHandle.h" +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/main/hdDrawingView.h" +#include "hotdraw/utilities/hdGeometry.h" + +//Images +#include "images/ddUp.pngc" +#include "images/ddDown.pngc" + +ddScrollBarHandle::ddScrollBarHandle(ddTableFigure *owner, hdILocator *scrollBarLocator , wxSize &size): + hdLocatorHandle(owner, scrollBarLocator) +{ + table = owner; + scrollLocator = scrollBarLocator; + displayBox.SetSize(size); + upBitmap = wxBitmap(*ddUp_png_img); + downBitmap = wxBitmap(*ddDown_png_img); +} + +ddScrollBarHandle::~ddScrollBarHandle() +{ +} + + +wxCursor ddScrollBarHandle::createCursor() +{ + return wxCursor(wxCURSOR_HAND); +} + +//avoid to use inflate on this handle +hdRect &ddScrollBarHandle::getDisplayBox(int posIdx) +{ + hdPoint p = locate(posIdx); + displayBox.width = 11; //as defined at locator + displayBox.height = table->getColsSpace().height; + displayBox.SetPosition(p); + return displayBox; +} + +void ddScrollBarHandle::draw(wxBufferedDC &context, hdDrawingView *view) +{ + int idx = view->getIdx(); + context.SetBrush(*wxWHITE_BRUSH); + wxPoint copy = getDisplayBox(idx).GetPosition(); + view->CalcScrolledPosition(copy.x, copy.y, ©.x, ©.y); + context.DrawRectangle(copy.x, copy.y, getDisplayBox(idx).width, getDisplayBox(idx).height); + context.DrawBitmap(upBitmap, copy.x + 1, copy.y + 2, true); + context.DrawBitmap(downBitmap, copy.x + 1, copy.y + getDisplayBox(idx).height - 2 - downBitmap.GetHeight(), true); + + barSize.SetHeight((getDisplayBox(idx).height - 12) * 0.45); + barSize.SetWidth(getDisplayBox(idx).width - 4); + + int divBy = (table->getTotalColumns() - table->getColumnsWindow()); + if(divBy <= 0) + divBy = table->getColumnsWindow(); + int colOffset = barSize.GetHeight() / divBy; + int verticalPosBar = 3 + copy.y + downBitmap.GetHeight() + colOffset * table->getTopColWindowIndex(); + if(table->getColumnsWindow() > 1) + context.DrawRectangle(wxPoint(copy.x + 2, verticalPosBar), barSize); + +} + +void ddScrollBarHandle::invokeStart(hdMouseEvent &event, hdDrawingView *view) +{ + int idx = view->getIdx(); + int y = event.GetPosition().y; + anchorY = y; + if( (y > (getDisplayBox(idx).GetPosition().y + 2)) && (y < (getDisplayBox(idx).GetPosition().y + 2 + 6)) ) //6 image height + table->columnsWindowUp(idx); + + if( (y > (getDisplayBox(idx).GetPosition().y + getDisplayBox(idx).height - 2 - downBitmap.GetHeight()) ) && (y < (getDisplayBox(idx).GetPosition().y + getDisplayBox(idx).height - 2) ) ) + table->columnsWindowDown(idx); + view->notifyChanged(); +} + +void ddScrollBarHandle::invokeStep(hdMouseEvent &event, hdDrawingView *view) +{ + int y = event.GetPosition().y; + int divBy = (table->getTotalColumns() - table->getColumnsWindow()); + if(divBy <= 0) + divBy = table->getColumnsWindow(); + int colOffset = barSize.GetHeight() / divBy; + + hdGeometry g; + if ( g.ddabs(anchorY - y) > colOffset) + { + if((anchorY - y) > 0) + { + table->columnsWindowUp(view->getIdx()); + } + else + { + table->columnsWindowDown(view->getIdx()); + } + anchorY = y; + } + view->notifyChanged(); +} + +void ddScrollBarHandle::invokeEnd(hdMouseEvent &event, hdDrawingView *view) +{ +} + +hdPoint &ddScrollBarHandle::locate(int posIdx) +{ + if(scrollLocator) + { + pointLocate = scrollLocator->locate(posIdx, getOwner()); + return pointLocate; + } + else + pointLocate = hdPoint(0, 0); + return pointLocate; +} diff --git a/dd/dditems/handles/ddSouthTableSizeHandle.cpp b/dd/dditems/handles/ddSouthTableSizeHandle.cpp new file mode 100644 index 0000000..77c182c --- /dev/null +++ b/dd/dditems/handles/ddSouthTableSizeHandle.cpp @@ -0,0 +1,94 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddSouthTableSizeHandle.cpp - Allow to change table size by using drag and drop from south side of table rectangle +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dd/dditems/handles/ddSouthTableSizeHandle.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "hotdraw/utilities/hdGeometry.h" +#include "hotdraw/figures/defaultAttributes/hdFontAttribute.h" +#include "hotdraw/main/hdDrawingView.h" + +ddSouthTableSizeHandle::ddSouthTableSizeHandle(ddTableFigure *owner, hdILocator *locator): + hdLocatorHandle(owner, locator) +{ +} + +hdRect &ddSouthTableSizeHandle::getDisplayBox(int posIdx) +{ + hdPoint p = locate(posIdx); + ddTableFigure *table = (ddTableFigure *) getOwner(); + displayBox.width = table->getFullSpace().width * 0.5; //as defined at locator + displayBox.height = 3; + displayBox.SetPosition(p); + return displayBox; +} + + +wxCursor ddSouthTableSizeHandle::createCursor() +{ + return wxCursor(wxCURSOR_SIZENS); +} + +void ddSouthTableSizeHandle::draw(wxBufferedDC &context, hdDrawingView *view) +{ +} + +ddSouthTableSizeHandle::~ddSouthTableSizeHandle() +{ +} + +void ddSouthTableSizeHandle::invokeStart(hdMouseEvent &event, hdDrawingView *view) +{ + anchorY = event.GetPosition().y; +} + +void ddSouthTableSizeHandle::invokeStep(hdMouseEvent &event, hdDrawingView *view) +{ + int y = event.GetPosition().y; + ddTableFigure *table = (ddTableFigure *) getOwner(); + wxFont font = *hdFontAttribute::defaultFont; + int colOffset = table->getColDefaultHeight(font); + + int divBy = (table->getTotalColumns() - table->getColumnsWindow()); + if(divBy <= 0) + divBy = table->getColumnsWindow(); + + hdGeometry g; + if ( g.ddabs(anchorY - y) > colOffset) + { + if((anchorY - y) > 0) + { + table->setColumnsWindow(view->getIdx(), table->getColumnsWindow() - 1); + } + else + { + table->setColumnsWindow(view->getIdx(), table->getColumnsWindow() + 1); + } + anchorY = y; + } + + //hack to update relationship position when table size change + table->manuallyNotifyChange(view->getIdx()); + view->notifyChanged(); +} + +void ddSouthTableSizeHandle::invokeEnd(hdMouseEvent &event, hdDrawingView *view) +{ + //hack to update relationship position when table size change + ddTableFigure *table = (ddTableFigure *) getOwner(); + table->manuallyNotifyChange(view->getIdx()); + view->notifyChanged(); +} diff --git a/dd/dditems/handles/module.mk b/dd/dditems/handles/module.mk new file mode 100644 index 0000000..19fab2d --- /dev/null +++ b/dd/dditems/handles/module.mk @@ -0,0 +1,21 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/dd/dditems/handles/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + dd/dditems/handles/ddAddColButtonHandle.cpp \ + dd/dditems/handles/ddAddFkButtonHandle.cpp \ + dd/dditems/handles/ddMinMaxTableButtonHandle.cpp \ + dd/dditems/handles/ddRemoveTableButtonHandle.cpp \ + dd/dditems/handles/ddScrollBarHandle.cpp \ + dd/dditems/handles/ddSouthTableSizeHandle.cpp + +EXTRA_DIST += \ + dd/dditems/handles/module.mk diff --git a/dd/dditems/locators/ddAddColLocator.cpp b/dd/dditems/locators/ddAddColLocator.cpp new file mode 100644 index 0000000..e847e94 --- /dev/null +++ b/dd/dditems/locators/ddAddColLocator.cpp @@ -0,0 +1,41 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddAddColLocator.cpp - Locate table add column button inside a table. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dd/dditems/locators/ddAddColLocator.h" +#include "dd/dditems/figures/ddTableFigure.h" + +ddAddColLocator::ddAddColLocator() +{ +} + +ddAddColLocator::~ddAddColLocator() +{ +} + +hdPoint &ddAddColLocator::locate(int posIdx, hdIFigure *owner) +{ + if(owner) + { + ddTableFigure *table = (ddTableFigure *) owner; + locatePoint.x = table->getTitleRect().GetBottomRight(posIdx).x - 20; + locatePoint.y = table->getTitleRect().GetBottomRight(posIdx).y - 9; + return locatePoint; + } + locatePoint.x = 0; + locatePoint.y = 0; + return locatePoint; +} diff --git a/dd/dditems/locators/ddAddFkLocator.cpp b/dd/dditems/locators/ddAddFkLocator.cpp new file mode 100644 index 0000000..f320f0f --- /dev/null +++ b/dd/dditems/locators/ddAddFkLocator.cpp @@ -0,0 +1,41 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddAddFkLocator.cpp - Locate table add fk relationship button inside a table. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dd/dditems/locators/ddAddFkLocator.h" +#include "dd/dditems/figures/ddTableFigure.h" + +ddAddFkLocator::ddAddFkLocator() +{ +} + +ddAddFkLocator::~ddAddFkLocator() +{ +} + +hdPoint &ddAddFkLocator::locate(int posIdx, hdIFigure *owner) +{ + if(owner) + { + ddTableFigure *table = (ddTableFigure *) owner; + locatePoint.x = table->getTitleRect().GetBottomRight(posIdx).x - 10; + locatePoint.y = table->getTitleRect().GetBottomRight(posIdx).y - 9; + return locatePoint; + } + locatePoint.x = 0; + locatePoint.y = 0; + return locatePoint; +} diff --git a/dd/dditems/locators/ddMinMaxTableLocator.cpp b/dd/dditems/locators/ddMinMaxTableLocator.cpp new file mode 100644 index 0000000..98209c4 --- /dev/null +++ b/dd/dditems/locators/ddMinMaxTableLocator.cpp @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddMinMaxTableLocator.cpp - Locate table minimize/maximize button inside a table. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dd/dditems/locators/ddMinMaxTableLocator.h" +#include "dd/dditems/figures/ddTableFigure.h" + +ddMinMaxTableLocator::ddMinMaxTableLocator() +{ +} + +ddMinMaxTableLocator::~ddMinMaxTableLocator() +{ +} + +hdPoint &ddMinMaxTableLocator::locate(int posIdx, hdIFigure *owner) +{ + if(owner) + { + ddTableFigure *table = (ddTableFigure *) owner; + int x = table->displayBox().x[posIdx] + table->displayBox().width - 20; //(8+2) + int y = table->displayBox().y[posIdx] + 6; + + locatePoint.x = x; + locatePoint.y = y; + return locatePoint; + } + locatePoint.x = 0; + locatePoint.y = 0; + return locatePoint; +} diff --git a/dd/dditems/locators/ddRemoveTableLocator.cpp b/dd/dditems/locators/ddRemoveTableLocator.cpp new file mode 100644 index 0000000..07dc79b --- /dev/null +++ b/dd/dditems/locators/ddRemoveTableLocator.cpp @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddRemoveColLocator.cpp - Locate table delete button inside a table. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dd/dditems/locators/ddRemoveTableLocator.h" +#include "dd/dditems/figures/ddTableFigure.h" + +ddRemoveTableLocator::ddRemoveTableLocator() +{ +} + +ddRemoveTableLocator::~ddRemoveTableLocator() +{ +} + +hdPoint &ddRemoveTableLocator::locate(int posIdx, hdIFigure *owner) +{ + if(owner) + { + ddTableFigure *table = (ddTableFigure *) owner; + int x = table->displayBox().x[posIdx] + table->displayBox().width - 10; //(8+2) + int y = table->displayBox().y[posIdx] + 6; + + locatePoint.x = x; + locatePoint.y = y; + return locatePoint; + } + locatePoint.x = 0; + locatePoint.y = 0; + return locatePoint; +} diff --git a/dd/dditems/locators/ddScrollBarTableLocator.cpp b/dd/dditems/locators/ddScrollBarTableLocator.cpp new file mode 100644 index 0000000..3a78340 --- /dev/null +++ b/dd/dditems/locators/ddScrollBarTableLocator.cpp @@ -0,0 +1,45 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddScrollBarTableLocator.cpp - Locate table scrollbar inside a table. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dd/dditems/locators/ddScrollBarTableLocator.h" +#include "dd/dditems/figures/ddTableFigure.h" + +ddScrollBarTableLocator::ddScrollBarTableLocator() +{ +} + +ddScrollBarTableLocator::~ddScrollBarTableLocator() +{ +} + +hdPoint &ddScrollBarTableLocator::locate(int posIdx, hdIFigure *owner) +{ + if(owner) + { + ddTableFigure *table = (ddTableFigure *) owner; + ; + int x = table->getColsSpace().GetTopRight(posIdx).x - 11; //scrollwidth + int y = table->getColsSpace().y[posIdx]; + + locatePoint.x = x; + locatePoint.y = y; + return locatePoint; + } + locatePoint.x = 0; + locatePoint.y = 0; + return locatePoint; +} diff --git a/dd/dditems/locators/ddTableBottomLocator.cpp b/dd/dditems/locators/ddTableBottomLocator.cpp new file mode 100644 index 0000000..37ba2ab --- /dev/null +++ b/dd/dditems/locators/ddTableBottomLocator.cpp @@ -0,0 +1,45 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddTableBottomLocator.cpp - Locate bottom (south) of table for use of south table size handle. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dd/dditems/locators/ddTableBottomLocator.h" +#include "dd/dditems/figures/ddTableFigure.h" + +ddTableBottomLocator::ddTableBottomLocator() +{ +} + +ddTableBottomLocator::~ddTableBottomLocator() +{ +} + +hdPoint &ddTableBottomLocator::locate(int posIdx, hdIFigure *owner) +{ + if(owner) + { + ddTableFigure *table = (ddTableFigure *) owner; + + int x = table->getFullSpace().GetLeftBottom(posIdx).x + table->getFullSpace().width * 0.25; + int y = table->getFullSpace().GetLeftBottom(posIdx).y - 2; + + locatePoint.x = x; + locatePoint.y = y; + return locatePoint; + } + locatePoint.x = 0; + locatePoint.y = 0; + return locatePoint; +} diff --git a/dd/dditems/locators/module.mk b/dd/dditems/locators/module.mk new file mode 100644 index 0000000..ab06b22 --- /dev/null +++ b/dd/dditems/locators/module.mk @@ -0,0 +1,21 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/dd/dditems/locators/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + dd/dditems/locators/ddAddColLocator.cpp \ + dd/dditems/locators/ddAddFkLocator.cpp \ + dd/dditems/locators/ddMinMaxTableLocator.cpp \ + dd/dditems/locators/ddRemoveTableLocator.cpp \ + dd/dditems/locators/ddScrollBarTableLocator.cpp \ + dd/dditems/locators/ddTableBottomLocator.cpp + +EXTRA_DIST += \ + dd/dditems/locators/module.mk diff --git a/dd/dditems/module.mk b/dd/dditems/module.mk new file mode 100644 index 0000000..acb36fa --- /dev/null +++ b/dd/dditems/module.mk @@ -0,0 +1,19 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/dd/dditems/ Makefile fragment +# +####################################################################### + +include dd/dditems/figures/module.mk +include dd/dditems/handles/module.mk +include dd/dditems/locators/module.mk +include dd/dditems/tools/module.mk +include dd/dditems/utilities/module.mk + +EXTRA_DIST += \ + dd/dditems/module.mk diff --git a/dd/dditems/tools/ddColumnFigureTool.cpp b/dd/dditems/tools/ddColumnFigureTool.cpp new file mode 100644 index 0000000..037d787 --- /dev/null +++ b/dd/dditems/tools/ddColumnFigureTool.cpp @@ -0,0 +1,130 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddColumnFigureTool.cpp - Improvement to hdFigureTool to work with composite table figures +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dd/dditems/tools/ddColumnFigureTool.h" +#include "dd/dditems/figures/ddColumnFigure.h" +#include "hotdraw/tools/hdDragTrackerTool.h" + + +ddColumnFigureTool::ddColumnFigureTool(hdDrawingView *view, hdIFigure *fig, hdITool *dt): + hdFigureTool(view, fig, dt) +{ + delegateTool = NULL; +} + +ddColumnFigureTool::~ddColumnFigureTool() +{ + //This tool destructor is at compositeTool, because this is only a selection tool and neither tool belongs to it. + hdITool *tmpDefault = hdFigureTool::getDefaultTool(); + hdFigureTool *tmpDelegateDefault; + + if(delegateTool->ms_classInfo.IsKindOf(&hdFigureTool::ms_classInfo)) + tmpDelegateDefault = (hdFigureTool *)delegateTool; + else + tmpDelegateDefault = NULL; + + if(delegateTool && delegateTool != tmpDefault) + { + //Hack to avoid delete defaultTool (Delegate->defaultTool) of delegate tool + // if this is the same as defaultTool (this->defaultTool) of this Object. + if(tmpDelegateDefault && tmpDelegateDefault->getDefaultTool() == tmpDefault) + tmpDelegateDefault->setDefaultTool(NULL); + + //Hack to avoid delete hdDragTrackerTool Default twice because this figure is only used inside + //a table, and then create a compositeTool and default in both tools is hdDragTrackerTool + //but I can't hard code this is Composite because that class should remain generic + if(tmpDelegateDefault->getDefaultTool()->ms_classInfo.IsKindOf(&hdDragTrackerTool::ms_classInfo)) + tmpDelegateDefault->setDefaultTool(NULL); + delete delegateTool; + } + +} + +void ddColumnFigureTool::setDefaultTool(hdITool *dt) +{ + hdFigureTool::setDefaultTool(dt); +} + +hdITool *ddColumnFigureTool::getDefaultTool() +{ + if(delegateTool) + { + return delegateTool; + } + else + { + return hdFigureTool::getDefaultTool(); + } +} + +void ddColumnFigureTool::mouseDown(hdMouseEvent &event) +{ + int x = event.GetPosition().x, y = event.GetPosition().y; + ddColumnFigure *cfigure = (ddColumnFigure *) getFigure(); + hdIFigure *figure = cfigure->findFigure(event.getView()->getIdx(), x, y); + + if(figure) + { + setDelegateTool(event.getView(), figure->CreateFigureTool(event.getView(), getDefaultTool())); + } + else + { + setDelegateTool(event.getView(), getDefaultTool()); + } + + if(delegateTool) + { + delegateTool->mouseDown(event); + } +} + +void ddColumnFigureTool::activate(hdDrawingView *view) +{ + if(delegateTool) + { + delegateTool->activate(view); + } +} + +void ddColumnFigureTool::deactivate(hdDrawingView *view) +{ + if(delegateTool) + { + delegateTool->deactivate(view); + } +} + +void ddColumnFigureTool::setDelegateTool(hdDrawingView *view, hdITool *tool) +{ + if(delegateTool) + { + delegateTool->deactivate(view); + delete delegateTool; + delegateTool = NULL; + } + + delegateTool = tool; + if(delegateTool) + { + delegateTool->activate(view); + } +} + +hdITool *ddColumnFigureTool::getDelegateTool() +{ + return delegateTool; +} diff --git a/dd/dditems/tools/ddColumnTextTool.cpp b/dd/dditems/tools/ddColumnTextTool.cpp new file mode 100644 index 0000000..4aef3ff --- /dev/null +++ b/dd/dditems/tools/ddColumnTextTool.cpp @@ -0,0 +1,83 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddColumnTextTool.cpp - Modification of simple text tool for editing composite figure columns +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "dd/dditems/tools/ddColumnTextTool.h" +#include "dd/dditems/figures/ddTextTableItemFigure.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/dditems/utilities/ddTableNameDialog.h" + +class hdDrawingEditor; + + +ddColumnTextTool::ddColumnTextTool(hdDrawingView *view, hdIFigure *fig, hdITool *dt, bool fastEdit , wxString dialogCaption, wxString dialogMessage): + hdSimpleTextTool(view, fig, dt, fastEdit, dialogCaption, dialogMessage) +{ + if(colTextFigure->ms_classInfo.IsKindOf(&ddTextTableItemFigure::ms_classInfo)) + colTextFigure = (ddTextTableItemFigure *) fig; + else + colTextFigure = NULL; +} + +ddColumnTextTool::~ddColumnTextTool() +{ +} + +void ddColumnTextTool::mouseDown(hdMouseEvent &event) +{ + hdSimpleTextTool::mouseDown(event); +} + +bool ddColumnTextTool::callDialog(hdDrawingView *view) +{ + if(colTextFigure->getOwnerColumn() == NULL) + { + wxString colName = colTextFigure->getText(); + wxString colShortName = colTextFigure->getAlias(); + ddTableNameDialog *nameAliasDialog = new ddTableNameDialog( + view, + colName, + colShortName, + colTextFigure + ); + + int answer = nameAliasDialog->ShowModal(); + bool change = false; + + if(answer == wxOK) + { + //check if names changed + change = ! (colShortName.IsSameAs(nameAliasDialog->GetValue1()) && colShortName.IsSameAs(nameAliasDialog->GetValue2())); + if(change) + { + colTextFigure->setText(nameAliasDialog->GetValue1()); + colTextFigure->setAlias(nameAliasDialog->GetValue2()); + view->notifyChanged(); + } + } + delete nameAliasDialog; + return change; + } + else + { + bool change = hdSimpleTextTool::callDialog(view); + if( change && colTextFigure->getOwnerColumn()->isGeneratedForeignKey()) //after a manual user column rename, deactivated automatic generation of fk name. + colTextFigure->getOwnerColumn()->deactivateGenFkName(); + return change; + } +} diff --git a/dd/dditems/tools/module.mk b/dd/dditems/tools/module.mk new file mode 100644 index 0000000..294b639 --- /dev/null +++ b/dd/dditems/tools/module.mk @@ -0,0 +1,17 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/dd/dditems/tools/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + dd/dditems/tools/ddColumnFigureTool.cpp \ + dd/dditems/tools/ddColumnTextTool.cpp + +EXTRA_DIST += \ + dd/dditems/tools/module.mk diff --git a/dd/dditems/utilities/ddPrecisionScaleDialog.cpp b/dd/dditems/utilities/ddPrecisionScaleDialog.cpp new file mode 100644 index 0000000..064c499 --- /dev/null +++ b/dd/dditems/utilities/ddPrecisionScaleDialog.cpp @@ -0,0 +1,76 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddPrecisionScaleDialog.cpp - Utility dialog class to allow user input of table name and short name +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "dd/dditems/utilities/ddPrecisionScaleDialog.h" +#include "dd/dditems/figures/ddTableFigure.h" + +#define txtPrecision CTRL_TEXT("txtPrecision") +#define txtScale CTRL_TEXT("txtScale") + + +BEGIN_EVENT_TABLE(ddPrecisionScaleDialog, pgDialog) +END_EVENT_TABLE() + +ddPrecisionScaleDialog::ddPrecisionScaleDialog( wxWindow *parent, + const wxString &defaultValue1, + const wxString &defaultValue2 + ) +{ + SetFont(settings->GetSystemFont()); + LoadResource(parent, wxT("ddPrecisionScaleDialog")); + RestorePosition(); + Init(); + SetValue1(defaultValue1); + SetValue2(defaultValue2); + + txtPrecision->SetFocus(); +} + +ddPrecisionScaleDialog::~ddPrecisionScaleDialog() +{ +} + +ddPrecisionScaleDialog::ddPrecisionScaleDialog() +{ + Init(); +} + +void ddPrecisionScaleDialog::Init( ) +{ + m_value1 = wxT("0"); + m_value2 = wxT("0"); +} + +//Transfer data to the window +bool ddPrecisionScaleDialog::TransferDataToWindow() +{ + txtPrecision->SetValue(m_value1); + txtScale->SetValue(m_value2); + + return true; +} + +//Transfer data from the window +bool ddPrecisionScaleDialog::TransferDataFromWindow() +{ + m_value1 = txtPrecision->GetValue(); + m_value2 = txtScale->GetValue(); + + return true; +} diff --git a/dd/dditems/utilities/ddSelectKindFksDialog.cpp b/dd/dditems/utilities/ddSelectKindFksDialog.cpp new file mode 100644 index 0000000..5e30c7d --- /dev/null +++ b/dd/dditems/utilities/ddSelectKindFksDialog.cpp @@ -0,0 +1,316 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddSelectKindFksDialog.cpp - Utility dialog class to allow user select destination of fk: automatically generated or existing column +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include "wx/stattext.h" + + +// App headers +#include "dd/dditems/utilities/ddSelectKindFksDialog.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "hotdraw/main/hdDrawingView.h" +#include "hotdraw/main/hdDrawingEditor.h" + + +IMPLEMENT_CLASS( ddSelectKindFksDialog, wxDialog ) + +BEGIN_EVENT_TABLE( ddSelectKindFksDialog, wxDialog ) + EVT_BUTTON(wxID_OK, ddSelectKindFksDialog::OnOkButtonClicked) + EVT_BUTTON(wxID_CANCEL, ddSelectKindFksDialog::OnCancelButtonClicked) + EVT_CHOICE(DDSELECTKINDFK, ddSelectKindFksDialog::OnChoiceFkKind) +END_EVENT_TABLE() + +ddSelectKindFksDialog::ddSelectKindFksDialog( wxWindow *parent, + ddRelationshipFigure *relation, + wxWindowID id, + const wxPoint &pos, + const wxSize &size, + long style + ) +{ + tablesRelation = relation; + Init(); + Create(parent, id, pos, size, style); +} + +ddSelectKindFksDialog::~ddSelectKindFksDialog() +{ + //before delete all items inside to free memory + deleteColsControls(); + delete ok; + delete line; +} + +ddSelectKindFksDialog::ddSelectKindFksDialog() +{ + Init(); +} + +void ddSelectKindFksDialog::Init( ) +{ + // choices.clear(); and delete all items inside hash map + +} + +bool ddSelectKindFksDialog::Create( wxWindow *parent, + wxWindowID id, + const wxPoint &pos = wxDefaultPosition, + const wxSize &size = wxDefaultSize, + long style = wxCAPTION ) +{ + if (!wxDialog::Create( parent, id, wxT("Select Foreign Key Mapping for each Column"), pos, size, style )) + return false; + + CreateControls(); + + // This fits the dialog to the minimum size dictated by + // the sizers + GetSizer()->Fit(this); + + // This ensures that the dialog cannot be sized smaller + // than the minimum size + + GetSizer()->SetSizeHints(this); + + // Centre the dialog on the parent or (if none) screen + + Centre(); + + return true; +} + +void ddSelectKindFksDialog::CreateControls() +{ + // A top-level sizer + + topSizer = new wxBoxSizer(wxVERTICAL ); + this->SetSizer(topSizer); + + // A wxChoice to choice kind of foreign key: from Uk or from pk + wxArrayString kindFks; + kindFks.Add(_("From Primary")); + + int i, last = tablesRelation->getStartTable()->getUkConstraintsNames().Count(); + wxString tmp; + + for(i = 0; i < last; i++) + { + tmp = _("Unique Key: "); + tmp += tablesRelation->getStartTable()->getUkConstraintsNames()[i]; + kindFks.Add(tmp); + } + + kindFkCtrl = new wxChoice(this, DDSELECTKINDFK, wxDefaultPosition, wxDefaultSize, kindFks); + kindFkCtrl->SetStringSelection(_("From Primary")); + topSizer->Add(kindFkCtrl, 0, wxALIGN_CENTER, 5); + + // A dividing line before the mapping items and kind of mapping + line = new wxStaticLine ( this, wxID_STATIC, + wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + topSizer->Add(line, 0, wxGROW | wxALL, 5); + + + //Hack to allow multiple pairs of wxStaticText wxchoice at dialog + colsTopSizer = new wxBoxSizer(wxVERTICAL ); + topSizer->Add(colsTopSizer); + populateColumnsControls(true, -1); + + // A dividing line before the OK and Cancel buttons + + line = new wxStaticLine ( this, wxID_STATIC, + wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + topSizer->Add(line, 0, wxGROW | wxALL, 5); + + // A horizontal box sizer to contain Reset, OK, Cancel and Help + + okCancelBox = new wxBoxSizer(wxHORIZONTAL); + topSizer->Add(okCancelBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5); + + // The OK button + + ok = new wxButton ( this, wxID_OK, wxT("&OK"), + wxDefaultPosition, wxDefaultSize, 0 ); + okCancelBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); + + // The Cancel button + + cancel = new wxButton ( this, wxID_CANCEL, wxT("&Cancel"), + wxDefaultPosition, wxDefaultSize, 0 ); + okCancelBox->Add(cancel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); +} + +void ddSelectKindFksDialog::OnChoiceFkKind(wxCommandEvent &event) +{ + int selectedUk = kindFkCtrl->GetSelection() == 0 ? -1 : kindFkCtrl->GetSelection() - 1; + bool frompk = kindFkCtrl->GetSelection() == 0; + + populateColumnsControls(frompk, selectedUk); +} + +void ddSelectKindFksDialog::deleteColsControls() +{ + choicesControlsHashMap::iterator it; + bool repeat; + ddSelectFkKindLine *columnLine; + do + { + repeat = false; + for (it = choices.begin(); it != choices.end(); ++it) + { + wxString key = it->first; + columnLine = it->second; + choices.erase(it); + delete columnLine; + repeat = true; + if (repeat) + break; + } + } + while(repeat); + colsTopSizer->Clear(); + choices.clear(); +} +void ddSelectKindFksDialog::populateColumnsControls(bool primaryKey, int useUkIndex) +{ + // Adding all columns mapping items + ddTableFigure *source = (ddTableFigure *) tablesRelation->getStartFigure(); + ddTableFigure *destination = (ddTableFigure *) tablesRelation->getEndFigure(); + + //Delete existing controllers + deleteColsControls(); + + //Populate controllers + if(primaryKey) + { + wxArrayString sourceCols = source->getAllFkSourceColsNames(true); + wxArrayString destCols = destination->getAllColumnsNames(); + destCols.Insert(_("Automatically Generated"), 0); + int i, last = sourceCols.Count(); + int eventID; + for(i = 0; i < last; i++) + { + // A sizer to allow lines of controls + linesSizer = new wxBoxSizer(wxHORIZONTAL ); + colsTopSizer->Add(linesSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5); + //Create controls and put inside linesizer + eventID = DDCHOICESELECTBASE + i; + ddSelectFkKindLine *newLineControls = new ddSelectFkKindLine(this, sourceCols[i], destCols, eventID); + choices[ sourceCols[i] ] = newLineControls; + linesSizer->Add(newLineControls->sourceCtrl, 0, wxALIGN_LEFT | wxALL, 5); + linesSizer->Add(newLineControls->destinationCtrl, 0, wxGROW | wxALL, 5); + } + } + else + { + wxArrayString sourceCols = source->getAllFkSourceColsNames(false, useUkIndex); + wxArrayString destCols = destination->getAllColumnsNames(); + destCols.Insert(_("Automatically Generated"), 0); + int i, last = sourceCols.Count(); + int eventID; + for(i = 0; i < last; i++) + { + // A sizer to allow lines of controls + linesSizer = new wxBoxSizer(wxHORIZONTAL ); + colsTopSizer->Add(linesSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5); + //Create controls and put inside linesizer + eventID = DDCHOICESELECTBASE + i; + ddSelectFkKindLine *newLineControls = new ddSelectFkKindLine(this, sourceCols[i], destCols, eventID); + choices[ sourceCols[i] ] = newLineControls; + linesSizer->Add(newLineControls->sourceCtrl, 0, wxALIGN_LEFT | wxALL, 5); + linesSizer->Add(newLineControls->destinationCtrl, 0, wxGROW | wxALL, 5); + } + } + this->Layout(); + this->InvalidateBestSize(); + this->Fit(); + topSizer->RecalcSizes(); +} + +//Transfer data to the window +bool ddSelectKindFksDialog::TransferDataToWindow() +{ + return true; +} + +//Transfer data from the window +bool ddSelectKindFksDialog::TransferDataFromWindow() +{ + return true; +} + +void ddSelectKindFksDialog::OnEnterPressed( wxCommandEvent &event ) +{ + if (event.GetEventType() == wxEVT_COMMAND_TEXT_ENTER) + { + if ( Validate() && TransferDataFromWindow() ) + { + if ( IsModal() ) + EndModal(wxID_OK); // If modal + else + { + SetReturnCode(wxID_OK); + this->Show(false); // If modeless + } + } + + } +} + +void ddSelectKindFksDialog::OnCancelButtonClicked( wxCommandEvent &event ) +{ + //Do nothing, just return wxID_CANCEL to don't allow connection + event.Skip(); +} + +void ddSelectKindFksDialog::OnOkButtonClicked( wxCommandEvent &event ) +{ + choicesControlsHashMap::iterator it; + ddSelectFkKindLine *lineOfCtrls; + + int selectedUk = kindFkCtrl->GetSelection() == 0 ? -1 : kindFkCtrl->GetSelection() - 1; + bool fromPk = kindFkCtrl->GetSelection() == 0; + tablesRelation->setFkFrom(fromPk, selectedUk); //true or bigger from zero both are mutually exclusive + + for( it = choices.begin(); it != choices.end(); ++it ) + { + wxString key = it->first; + lineOfCtrls = it->second; + if(lineOfCtrls->destinationCtrl->GetSelection() != 0) //No automatic Generated + { + ddColumnFigure *col = tablesRelation->getStartTable()->getColumnByName(lineOfCtrls->sourceCtrl->GetLabel()); + tablesRelation->addExistingColumnFk(col, lineOfCtrls->destinationCtrl->GetString(lineOfCtrls->destinationCtrl->GetSelection())); + } + } + event.Skip(); +} + +ddSelectFkKindLine::ddSelectFkKindLine(wxWindow *parent, wxString sourceColumn, wxArrayString possibleTargets, wxWindowID eventId) +{ + sourceCtrl = new wxStaticText(parent, wxID_STATIC, sourceColumn, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); + destinationCtrl = new wxChoice(parent, eventId, wxDefaultPosition, wxDefaultSize, possibleTargets); + destinationCtrl->SetStringSelection(_("Automatically Generated")); +} + +ddSelectFkKindLine::ddSelectFkKindLine() +{ + sourceCtrl = NULL; + destinationCtrl = NULL; +} + +ddSelectFkKindLine::~ddSelectFkKindLine() +{ + delete sourceCtrl; + delete destinationCtrl; +} diff --git a/dd/dditems/utilities/ddTableNameDialog.cpp b/dd/dditems/utilities/ddTableNameDialog.cpp new file mode 100644 index 0000000..6b7a749 --- /dev/null +++ b/dd/dditems/utilities/ddTableNameDialog.cpp @@ -0,0 +1,78 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddTableNameDialog.cpp - Utility dialog class to allow user input of table name and short name +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "dd/dditems/utilities/ddTableNameDialog.h" +#include "dd/dditems/figures/ddTableFigure.h" + +#define txtUsualTableName CTRL_TEXT("txtUsualTableName") + + +BEGIN_EVENT_TABLE(ddTableNameDialog, pgDialog) +END_EVENT_TABLE() + + +ddTableNameDialog::ddTableNameDialog( wxWindow *parent, + const wxString &defaultValue1, + const wxString &defaultValue2, + ddTextTableItemFigure *tableItem + ) : + pgDialog() +{ + SetFont(settings->GetSystemFont()); + LoadResource(parent, wxT("ddTableNameDialog")); + RestorePosition(); + Init(); + tabItem = tableItem; + checkGenerate = false; + + SetValue1(defaultValue1); + SetValue2(defaultValue2); + + txtUsualTableName->SetFocus(); +} + +ddTableNameDialog::~ddTableNameDialog() +{ +} + +ddTableNameDialog::ddTableNameDialog() : + pgDialog() +{ + Init(); +} + +void ddTableNameDialog::Init( ) +{ + m_value1 = wxEmptyString; + m_value2 = wxEmptyString; +} + +//Transfer data to the window +bool ddTableNameDialog::TransferDataToWindow() +{ + txtUsualTableName->SetValue(m_value1); + return true; +} + +//Transfer data from the window +bool ddTableNameDialog::TransferDataFromWindow() +{ + m_value1 = txtUsualTableName->GetValue(); + return true; +} + diff --git a/dd/dditems/utilities/module.mk b/dd/dditems/utilities/module.mk new file mode 100644 index 0000000..a31ff0f --- /dev/null +++ b/dd/dditems/utilities/module.mk @@ -0,0 +1,17 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/dd/dditems/utilities/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + dd/dditems/utilities/ddPrecisionScaleDialog.cpp \ + dd/dditems/utilities/ddSelectKindFksDialog.cpp \ + dd/dditems/utilities/ddTableNameDialog.cpp +EXTRA_DIST += \ + dd/dditems/utilities/module.mk diff --git a/dd/ddmodel/ddBrowserDataContainer.cpp b/dd/ddmodel/ddBrowserDataContainer.cpp new file mode 100644 index 0000000..5521e8b --- /dev/null +++ b/dd/ddmodel/ddBrowserDataContainer.cpp @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddBrowserDataContainer.cpp - Item to contain data for each treview child. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dd/ddmodel/ddBrowserDataContainer.h" +#include "hotdraw/figures/hdIFigure.h" + + +ddBrowserDataContainer::ddBrowserDataContainer(hdIFigure *data) +{ + figure = data; +} + + +// Destructor +ddBrowserDataContainer::~ddBrowserDataContainer() +{ + +} + +int ddBrowserDataContainer::getFigureKindId() +{ + return figure->getKindId(); +} + +hdIFigure *ddBrowserDataContainer::getFigure() +{ + return figure; +} diff --git a/dd/ddmodel/ddDBReverseEnginering.cpp b/dd/ddmodel/ddDBReverseEnginering.cpp new file mode 100644 index 0000000..473041b --- /dev/null +++ b/dd/ddmodel/ddDBReverseEnginering.cpp @@ -0,0 +1,2087 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddDBReverseEnginering.cpp - Reverse engineering database functions for database designer. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "schema/pgSchema.h" +#include "schema/pgDatatype.h" +#include "dd/ddmodel/ddDBReverseEngineering.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/ddmodel/ddDatabaseDesign.h" +#include "dd/dditems/figures/ddRelationshipFigure.h" +#include "dd/dditems/figures/ddRelationshipItem.h" +#include "dd/dditems/figures/ddRelationshipTerminal.h" +#include "images/namespaces.pngc" +#include "images/namespace-sm.pngc" +#include "images/gqbOrderAddAll.pngc" +#include "images/gqbOrderRemoveAll.pngc" +#include "images/gqbOrderRemove.pngc" +#include "images/gqbOrderAdd.pngc" + + +BEGIN_EVENT_TABLE(ddDBReverseEngineering, wxWizard) + EVT_WIZARD_FINISHED(wxID_ANY, ddDBReverseEngineering::OnFinishPressed) +END_EVENT_TABLE() + +BEGIN_EVENT_TABLE(SelSchemaPage, wxWizardPage) + EVT_WIZARD_PAGE_CHANGING(wxID_ANY, SelSchemaPage::OnWizardPageChanging) +END_EVENT_TABLE() + +BEGIN_EVENT_TABLE(SelTablesPage, wxWizardPage) + EVT_BUTTON(DDREMOVE, SelTablesPage::OnButtonRemove) + EVT_BUTTON(DDREMOVEALL, SelTablesPage::OnButtonRemoveAll) + EVT_BUTTON(DDADD, SelTablesPage::OnButtonAdd) + EVT_BUTTON(DDADDALL, SelTablesPage::OnButtonAddAll) + EVT_WIZARD_PAGE_CHANGING(wxID_ANY, SelTablesPage::OnWizardPageChanging) +END_EVENT_TABLE() + +BEGIN_EVENT_TABLE(ReportPage, wxWizardPage) + EVT_WIZARD_PAGE_CHANGING(wxID_ANY, ReportPage::OnWizardPageChanging) +END_EVENT_TABLE() + +// +// +// +// ----- Stub & reverse engineering classes Implementation +// +// +// + +wxArrayString ddImportDBUtils::getTablesNames(pgConn *connection, wxString schemaName) +{ + + wxArrayString out; + wxString query; + + OID schemaOID = ddImportDBUtils::getSchemaOID(connection, schemaName); + + // Get the child objects. + query = wxT("SELECT oid, relname, relkind\n") + wxT(" FROM pg_class\n") + wxT(" WHERE relkind IN ('r') AND relnamespace = ") + NumToStr(schemaOID) + wxT(";"); + + pgSet *tables = connection->ExecuteSet(query); + + if (tables) + { + while (!tables->Eof()) + { + wxString tmpname = tables->GetVal(wxT("relname")); + wxString relkind = tables->GetVal(wxT("relkind")); + + if (relkind == wxT("r")) // Table + { + out.Add(tables->GetVal(wxT("relname"))); + } + + tables->MoveNext(); + } + + delete tables; + } + + return out; +} + +OID ddImportDBUtils::getSchemaOID(pgConn *connection, wxString schemaName) +{ + // Search Schemas and insert it + wxString restr = wxT(" WHERE "); + + restr += wxT("NOT "); + restr += wxT("((nspname = 'pg_catalog' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'pg_class' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname = 'pgagent' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'pga_job' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname = 'information_schema' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'tables' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname LIKE '_%' AND EXISTS (SELECT 1 FROM pg_proc WHERE proname='slonyversion' AND pronamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname = 'dbo' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'systables' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname = 'sys' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'all_tables' AND relnamespace = nsp.oid LIMIT 1)))\n"); + + if (connection->EdbMinimumVersion(8, 2)) + { + restr += wxT(" AND nsp.nspparent = 0\n"); + // Do not show dbms_job_procedure in schemas + if (!settings->GetShowSystemObjects()) + restr += wxT("AND NOT (nspname = 'dbms_job_procedure' AND EXISTS(SELECT 1 FROM pg_proc WHERE pronamespace = nsp.oid and proname = 'run_job' LIMIT 1))\n"); + } + + wxString sql; + + if (connection->BackendMinimumVersion(8, 1)) + { + sql = wxT("SELECT CASE WHEN nspname LIKE E'pg\\\\_temp\\\\_%' THEN 1\n") + wxT(" WHEN (nspname LIKE E'pg\\\\_%') THEN 0\n"); + } + else + { + sql = wxT("SELECT CASE WHEN nspname LIKE 'pg\\\\_temp\\\\_%' THEN 1\n") + wxT(" WHEN (nspname LIKE 'pg\\\\_%') THEN 0\n"); + } + sql += wxT(" ELSE 3 END AS nsptyp, nspname, nsp.oid\n") + wxT(" FROM pg_namespace nsp\n") + + restr + wxT(" AND nspname = '") + schemaName + wxT("' ") + + wxT(" ORDER BY 1, nspname"); + + pgSet *schemas = connection->ExecuteSet(sql); + + int times = 0; + OID schemaOID = -1; + if (schemas) + { + while (!schemas->Eof()) + { + wxString name = schemas->GetVal(wxT("nspname")); + long nsptyp = schemas->GetLong(wxT("nsptyp")); + + wxStringTokenizer tokens(settings->GetSystemSchemas(), wxT(",")); + while (tokens.HasMoreTokens()) + { + wxRegEx regex(tokens.GetNextToken()); + if (regex.Matches(name)) + { + nsptyp = SCHEMATYP_USERSYS; + break; + } + } + + if (nsptyp <= SCHEMATYP_USERSYS && !settings->GetShowSystemObjects()) + { + schemas->MoveNext(); + continue; + } + + schemaOID = schemas->GetOid(wxT("oid")); + times++; + schemas->MoveNext(); + } + + delete schemas; + } + + if(times > 1 || schemaOID == -1) + { + wxMessageBox(_("Schema not found"), _("getting table OID"), wxICON_ERROR | wxOK); + return -1; + } + return schemaOID; +} + +OID ddImportDBUtils::getTableOID(pgConn *connection, wxString schemaName, wxString tableName) +{ + + OID schemaOID = ddImportDBUtils::getSchemaOID(connection, schemaName); + wxString query; + OID tableOID = -1; + + // Get the child objects. + query = wxT("SELECT oid, relname, relkind\n") + wxT(" FROM pg_class\n") + wxT(" WHERE relkind IN ('r') AND relnamespace = ") + NumToStr(schemaOID) + + wxT(" AND relname = '") + tableName + wxT("';"); + + pgSet *tables = connection->ExecuteSet(query); + int times; + if (tables) + { + times = 0; + while (!tables->Eof()) + { + wxString relkind = tables->GetVal(wxT("relkind")); + if (relkind == wxT("r")) // Table + { + tableOID = tables->GetOid(wxT("oid")); + times++; + } + + tables->MoveNext(); + } + + delete tables; + } + + if(times > 1 || tableOID == -1) + { + wxMessageBox(_("Table not found"), _("getting table OID"), wxICON_ERROR | wxOK); + return -1; + } + return tableOID; +} + +// Don't support inherited tables right now, or tables where a column is part of more than one Unique Key. +ddStubTable *ddImportDBUtils::getTable(pgConn *connection, wxString tableName, OID tableOid) +{ + wxString sql; + int currentcol; + ddStubTable *table = NULL; + ddStubColumn *column = NULL; + + + // grab inherited tables [if found don't allow table import because this feature isn't supported right now] + sql = wxT("SELECT inhparent::regclass AS inhrelname,\n") + wxT(" (SELECT count(*) FROM pg_attribute WHERE attrelid=inhparent AND attnum>0) AS colscount\n") + wxT(" FROM pg_inherits\n") + wxT(" WHERE inhrelid = ") + NumToStr(tableOid) + wxT("::oid\n") + wxT(" ORDER BY inhseqno"); + pgSet *inhtables = connection->ExecuteSet(sql); + + if(inhtables && inhtables->Eof()) + { + wxString systemRestriction; + systemRestriction = wxT("\n AND att.attnum > 0"); + + sql = + wxT("SELECT att.*, def.*, pg_catalog.pg_get_expr(def.adbin, def.adrelid) AS defval, CASE WHEN att.attndims > 0 THEN 1 ELSE 0 END AS isarray, format_type(ty.oid,NULL) AS typname, format_type(ty.oid,att.atttypmod) AS displaytypname, tn.nspname as typnspname, et.typname as elemtypname,\n") + wxT(" ty.typstorage AS defaultstorage, cl.relname, na.nspname, att.attstattarget, description, cs.relname AS sername, ns.nspname AS serschema,\n") + wxT(" (SELECT count(1) FROM pg_type t2 WHERE t2.typname=ty.typname) > 1 AS isdup, indkey"); + + if (connection->BackendMinimumVersion(9, 1)) + sql += wxT(",\n coll.collname, nspc.nspname as collnspname"); + if (connection->BackendMinimumVersion(8, 5)) + sql += wxT(",\n attoptions"); + if (connection->BackendMinimumVersion(7, 4)) + sql += + wxT(",\n") + wxT(" EXISTS(SELECT 1 FROM pg_constraint WHERE conrelid=att.attrelid AND contype='f'") + wxT(" AND att.attnum=ANY(conkey)) As isfk"); + if (connection->BackendMinimumVersion(9, 1)) + { + sql += wxT(",\n(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=att.attrelid AND sl1.objsubid=att.attnum) AS labels"); + sql += wxT(",\n(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=att.attrelid AND sl2.objsubid=att.attnum) AS providers"); + } + + sql += wxT("\n") + wxT(" FROM pg_attribute att\n") + wxT(" JOIN pg_type ty ON ty.oid=atttypid\n") + wxT(" JOIN pg_namespace tn ON tn.oid=ty.typnamespace\n") + wxT(" JOIN pg_class cl ON cl.oid=att.attrelid\n") + wxT(" JOIN pg_namespace na ON na.oid=cl.relnamespace\n") + wxT(" LEFT OUTER JOIN pg_type et ON et.oid=ty.typelem\n") + wxT(" LEFT OUTER JOIN pg_attrdef def ON adrelid=att.attrelid AND adnum=att.attnum\n") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=att.attrelid AND des.objsubid=att.attnum\n") + wxT(" LEFT OUTER JOIN (pg_depend JOIN pg_class cs ON classid='pg_class'::regclass AND objid=cs.oid AND cs.relkind='S') ON refobjid=att.attrelid AND refobjsubid=att.attnum\n") + wxT(" LEFT OUTER JOIN pg_namespace ns ON ns.oid=cs.relnamespace\n") + wxT(" LEFT OUTER JOIN pg_index pi ON pi.indrelid=att.attrelid AND indisprimary\n"); + if (connection->BackendMinimumVersion(9, 1)) + sql += wxT(" LEFT OUTER JOIN pg_collation coll ON att.attcollation=coll.oid\n") + wxT(" LEFT OUTER JOIN pg_namespace nspc ON coll.collnamespace=nspc.oid\n"); + sql += wxT(" WHERE att.attrelid = ") + NumToStr(tableOid) + + systemRestriction + wxT("\n") + wxT(" AND att.attisdropped IS FALSE\n") + wxT(" ORDER BY att.attnum"); + + table = new ddStubTable(tableName, tableOid); + + pgSet *columns = connection->ExecuteSet(sql); + if (columns) + { + currentcol = 0; + while (!columns->Eof()) + { + currentcol++; + column = new ddStubColumn(columns->GetVal(wxT("attname")), tableOid); + column->pgColNumber = columns->GetLong(wxT("attnum")); + wxString pkCols = columns->GetVal(wxT("indkey")); + bool isPK = false; + wxStringTokenizer indkey(pkCols); + while (indkey.HasMoreTokens()) + { + wxString str = indkey.GetNextToken(); + if (StrToLong(str) == column->pgColNumber) + { + isPK = true; + break; + } + } + column->isPrimaryKey = isPK; + + long typmod = columns->GetLong(wxT("atttypmod")); + pgDatatype *dt = new pgDatatype(columns->GetVal(wxT("typnspname")), columns->GetVal(wxT("typname")), + columns->GetBool(wxT("isdup")), + columns->GetLong(wxT("attndims")), typmod); + + column->typeColumn = dt; + column->isNotNull = columns->GetBool(wxT("attnotnull")); + wxString colName = column->columnName; + table->cols[colName] = column; + columns->MoveNext(); + } + + delete columns; + } + setUniqueConstraints(connection, table); + setPkName(connection, table); + if(inhtables) + { + delete inhtables; + inhtables = NULL; + } + return table; + } + + return table; +} + +//true on everything fine, false when some error is found +bool ddImportDBUtils::setUniqueConstraints(pgConn *connection, ddStubTable *table) +{ + bool out = true; + //temporary fix, this should be adapted to pgadmin way of working + // check for extended ruleutils with pretty-print option + wxString prettyOption; + wxString exprname = connection->ExecuteScalar(wxT("SELECT proname FROM pg_proc WHERE proname='pg_get_viewdef' AND proargtypes[1]=16")); + if (!exprname.IsEmpty()) + prettyOption = wxT(", true"); + + wxString query; + + wxString proname, projoin; + if (connection->BackendMinimumVersion(7, 4)) + { + proname = wxT("indnatts, "); + if (connection->BackendMinimumVersion(7, 5)) + { + proname += wxT("cls.reltablespace AS spcoid, spcname, "); + projoin = wxT(" LEFT OUTER JOIN pg_tablespace ta on ta.oid=cls.reltablespace\n"); + } + } + else + { + proname = wxT("proname, pn.nspname as pronspname, proargtypes, "); + projoin = wxT(" LEFT OUTER JOIN pg_proc pr ON pr.oid=indproc\n") + wxT(" LEFT OUTER JOIN pg_namespace pn ON pn.oid=pr.pronamespace\n"); + } + query = wxT("SELECT DISTINCT ON(cls.relname) cls.oid, cls.relname as idxname, indrelid, indkey, indisclustered, indisunique, indisprimary, n.nspname,\n") + wxT(" ") + proname + wxT("tab.relname as tabname, indclass, con.oid AS conoid, CASE contype WHEN 'p' THEN desp.description WHEN 'u' THEN desp.description WHEN 'x' THEN desp.description ELSE des.description END AS description,\n") + wxT(" pg_get_expr(indpred, indrelid") + prettyOption + wxT(") as indconstraint, contype, condeferrable, condeferred, amname\n"); + if (connection->BackendMinimumVersion(8, 2)) + query += wxT(", substring(array_to_string(cls.reloptions, ',') from 'fillfactor=([0-9]*)') AS fillfactor \n"); + query += wxT(" FROM pg_index idx\n") + wxT(" JOIN pg_class cls ON cls.oid=indexrelid\n") + wxT(" JOIN pg_class tab ON tab.oid=indrelid\n") + + projoin + + wxT(" JOIN pg_namespace n ON n.oid=tab.relnamespace\n") + wxT(" JOIN pg_am am ON am.oid=cls.relam\n") + wxT(" LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i')\n") + wxT(" LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)\n") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid\n") + wxT(" LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0)\n") + wxT(" WHERE indrelid = ") + NumToStr(table->OIDTable) + wxT("::oid") + + wxT(" AND contype='u' ") + + wxT("\n") + wxT(" ORDER BY cls.relname"); + pgSet *indexes = connection->ExecuteSet(query); + int ukIndex = -1; + wxArrayString UniqueKeysNames; + + if (indexes) + { + while (!indexes->Eof()) + { + ukIndex++; + wxString uniqueKeys = indexes->GetVal(wxT("indkey")); + + UniqueKeysNames.Add(indexes->GetVal(wxT("idxname"))); + + wxStringTokenizer indkey(uniqueKeys); + while (indkey.HasMoreTokens()) + { + //Get column number in unique key + wxString str = indkey.GetNextToken(); + //look at all columns [change for hashmap in a future if that option is more optimized] + stubColsHashMap::iterator it; + ddStubColumn *item; + for (it = table->cols.begin(); it != table->cols.end(); ++it) + { + wxString key = it->first; + item = it->second; + //If column belong to unique constraint mark it + if (StrToLong(str) == item->pgColNumber) + { + item->uniqueKeyIndex = ukIndex; + } + } + } + indexes->MoveNext(); + } + table->UniqueKeysNames = UniqueKeysNames; + delete indexes; + } + return out; //false in a future when detect a column in more than one unique key because this is not supported by database designer right now +} + +//true on everything fine, false when some error is found +bool ddImportDBUtils::setPkName(pgConn *connection, ddStubTable *table) +{ + bool out = true; + wxString pkName = wxEmptyString; + + //temporary fix, this should be adapted to pgadmin way of working + // check for extended ruleutils with pretty-print option + wxString prettyOption; + wxString exprname = connection->ExecuteScalar(wxT("SELECT proname FROM pg_proc WHERE proname='pg_get_viewdef' AND proargtypes[1]=16")); + if (!exprname.IsEmpty()) + prettyOption = wxT(", true"); + + wxString query; + + wxString proname, projoin; + if (connection->BackendMinimumVersion(7, 4)) + { + proname = wxT("indnatts, "); + if (connection->BackendMinimumVersion(7, 5)) + { + proname += wxT("cls.reltablespace AS spcoid, spcname, "); + projoin = wxT(" LEFT OUTER JOIN pg_tablespace ta on ta.oid=cls.reltablespace\n"); + } + } + else + { + proname = wxT("proname, pn.nspname as pronspname, proargtypes, "); + projoin = wxT(" LEFT OUTER JOIN pg_proc pr ON pr.oid=indproc\n") + wxT(" LEFT OUTER JOIN pg_namespace pn ON pn.oid=pr.pronamespace\n"); + } + query = wxT("SELECT DISTINCT ON(cls.relname) cls.oid, cls.relname as idxname, indrelid, indkey, indisclustered, indisunique, indisprimary, n.nspname,\n") + wxT(" ") + proname + wxT("tab.relname as tabname, indclass, con.oid AS conoid, CASE contype WHEN 'p' THEN desp.description WHEN 'u' THEN desp.description WHEN 'x' THEN desp.description ELSE des.description END AS description,\n") + wxT(" pg_get_expr(indpred, indrelid") + prettyOption + wxT(") as indconstraint, contype, condeferrable, condeferred, amname\n"); + if (connection->BackendMinimumVersion(8, 2)) + query += wxT(", substring(array_to_string(cls.reloptions, ',') from 'fillfactor=([0-9]*)') AS fillfactor \n"); + query += wxT(" FROM pg_index idx\n") + wxT(" JOIN pg_class cls ON cls.oid=indexrelid\n") + wxT(" JOIN pg_class tab ON tab.oid=indrelid\n") + + projoin + + wxT(" JOIN pg_namespace n ON n.oid=tab.relnamespace\n") + wxT(" JOIN pg_am am ON am.oid=cls.relam\n") + wxT(" LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i')\n") + wxT(" LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)\n") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid\n") + wxT(" LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0)\n") + wxT(" WHERE indrelid = ") + NumToStr(table->OIDTable) + wxT("::oid") + + wxT(" AND contype='p' ") + + wxT("\n") + wxT(" ORDER BY cls.relname"); + pgSet *indexes = connection->ExecuteSet(query); + if (indexes) + { + while (!indexes->Eof()) + { + pkName = indexes->GetVal(wxT("idxname")); + indexes->MoveNext(); + } + delete indexes; + } + + table->PrimaryKeyName = pkName; + return out; //false in a future when detect a column in more than one unique key because this is not supported by database designer right now +} + +void ddImportDBUtils::getAllRelationships(pgConn *connection, stubTablesHashMap &tables, ddDatabaseDesign *design) +{ + wxString sql; + ddRelationshipFigure *relation = NULL; + ddTableFigure *sourceTabFigure = NULL; + ddTableFigure *destTabFigure = NULL; + //Add Tables to the Model + stubTablesHashMap::iterator mainIt; + ddStubTable *destStubTable = NULL; + for (mainIt = tables.begin(); mainIt != tables.end(); ++mainIt) + { + wxString key = mainIt->first; + destStubTable = mainIt->second; + + sql = wxT("SELECT ct.oid, conname, condeferrable, condeferred, confupdtype, confdeltype, confmatchtype, ") + wxT("conkey, confkey, confrelid, nl.nspname as fknsp, cl.relname as fktab, ") + wxT("nr.nspname as refnsp, cr.relname as reftab, description"); + if (connection->BackendMinimumVersion(9, 1)) + sql += wxT(", convalidated"); + sql += wxT("\n FROM pg_constraint ct\n") + wxT(" JOIN pg_class cl ON cl.oid=conrelid\n") + wxT(" JOIN pg_namespace nl ON nl.oid=cl.relnamespace\n") + wxT(" JOIN pg_class cr ON cr.oid=confrelid\n") + wxT(" JOIN pg_namespace nr ON nr.oid=cr.relnamespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=ct.oid\n") + wxT(" WHERE contype='f' AND conrelid = ") + NumToStr(destStubTable->OIDTable) + wxT("::oid") + //+ restriction + + + wxT("\n") + wxT(" ORDER BY conname"); + + pgSet *foreignKeys = connection->ExecuteSet(sql); + + if (foreignKeys && foreignKeys->NumRows() > 0) + { + while (!foreignKeys->Eof()) + { + wxString sourceSchema, destSchema; + sourceSchema = foreignKeys->GetVal(wxT("refnsp")); + destSchema = foreignKeys->GetVal(wxT("fknsp")); + + // Source Table ----------------------<| Destination Table + + if(sourceSchema.IsSameAs(destSchema, false)) + { + wxString sourceTableName = foreignKeys->GetVal(wxT("reftab")); + wxString destTableName = foreignKeys->GetVal(wxT("fktab")); + + destTabFigure = design->getTable(destTableName); + sourceTabFigure = design->getTable(sourceTableName); + + //Only if both tables were imported at same time + if(destTabFigure != NULL && sourceTabFigure != NULL) + { + + int ukindex = -1; //Only Supporting foreign keys from PK right now when importing model + wxString RelationshipName = foreignKeys->GetVal(wxT("conname")); + + wxString onUpd = foreignKeys->GetVal(wxT("confupdtype")); + actionKind onUpdate = onUpd.IsSameAs('a') ? FK_ACTION_NO : + onUpd.IsSameAs('r') ? FK_RESTRICT : + onUpd.IsSameAs('c') ? FK_CASCADE : + onUpd.IsSameAs('d') ? FK_SETDEFAULT : + onUpd.IsSameAs('n') ? FK_SETNULL : FK_ACTION_NO; + + + wxString onDel = foreignKeys->GetVal(wxT("confdeltype")); + actionKind onDelete = onUpd.IsSameAs('a') ? FK_ACTION_NO : + onUpd.IsSameAs('r') ? FK_RESTRICT : + onUpd.IsSameAs('c') ? FK_CASCADE : + onUpd.IsSameAs('d') ? FK_SETDEFAULT : + onUpd.IsSameAs('n') ? FK_SETNULL : FK_ACTION_NO; + + wxString match = foreignKeys->GetVal(wxT("confmatchtype")); + bool matchSimple = match.IsSameAs('f') ? false : + match.IsSameAs('u') ? true : false; + + + //------ Preparing metada to allow discovery of some relationship attributes + //Source table columns + wxString fkColsSourceTable = foreignKeys->GetVal(wxT("confkey")); + //remove {} of string + fkColsSourceTable.Remove(0, 1); + fkColsSourceTable.RemoveLast(); + wxString fkColsDestTable = foreignKeys->GetVal(wxT("conkey")); + //remove {} of string + fkColsDestTable.Remove(0, 1); + fkColsDestTable.RemoveLast(); + + wxSortedArrayInt sourceFkCols(sortFunc); + wxSortedArrayInt destFkCols(sortFunc); + wxSortedArrayInt sourcePKs(sortFunc); + wxSortedArrayInt destPKs(sortFunc); + + //Split columns from sourceFk + wxStringTokenizer confkey(fkColsSourceTable); + while (confkey.HasMoreTokens()) + { + wxString str = confkey.GetNextToken(); + sourceFkCols.Add(StrToLong(str)); + } + + //Split columns from destFk + wxStringTokenizer conkey(fkColsDestTable); + while (conkey.HasMoreTokens()) + { + wxString str = conkey.GetNextToken(); + destFkCols.Add(StrToLong(str)); + } + + //Get Stub of source table + ddStubTable *sourceStubTable = tables[sourceTableName]; + + //Get PK columns of source + stubColsHashMap::iterator it; + ddStubColumn *column; + for (it = sourceStubTable->cols.begin(); it != sourceStubTable->cols.end(); ++it) + { + wxString key = it->first; + column = it->second; + if(column->isPrimaryKey) + sourcePKs.Add(column->pgColNumber); + } + + //Get PK columns of dest + for (it = destStubTable->cols.begin(); it != destStubTable->cols.end(); ++it) + { + wxString key = it->first; + column = it->second; + if(column->isPrimaryKey) + destPKs.Add(column->pgColNumber); + } + + // Source Table ----------------------<| Destination Table + //Default assumption is the source of this fk is a Primary Key. + bool fkFromPk = true; + + //first check: number of columns used as fk at Source is the same of the pk at Source + if(sourceFkCols.Count() == sourcePKs.Count()) + { + int i; + //Because postgres columns numbers are stored in an ordered array, + //their index should be the same at all positions + int srcFkCount = sourceFkCols.Count(); + for(i = 0; i < srcFkCount; i++) + { + if( sourceFkCols[i] != sourcePKs[i] ) + { + fkFromPk = false; + break; + } + } + } + else + { + fkFromPk = true; + } + + //------ Finding fk from uk or pk? + int ukIndex = -1; + //if fkFromPk = false then is fkfromUK?, check that + //all source fk columns should belong to one Uk at source table. + if( fkFromPk == false ) + { + bool error = false; + int baseColNumber = sourceFkCols[sourceFkCols.Count() - 1]; + int baseUkIdxSourceCol = sourceStubTable->getColumnByNumber(baseColNumber)->uniqueKeyIndex; + int nextColNumber, nextUkIdxSourceCol; + int countSrcFkCols = sourceFkCols.Count() - 2; + while(countSrcFkCols >= 0) + { + nextColNumber = sourceFkCols[countSrcFkCols]; + nextUkIdxSourceCol = sourceStubTable->getColumnByNumber(nextColNumber)->uniqueKeyIndex; + countSrcFkCols--; + if(baseUkIdxSourceCol != nextUkIdxSourceCol) + { + error = true; + wxMessageBox(_("Error detecting kind of foreign key source: from Pk or from Uk"), _("Error importing relationship"), wxICON_ERROR | wxOK); + delete foreignKeys; + return; + } + } + if(!error) + { + ukIndex = baseUkIdxSourceCol; + } + } + + //Last check of consistency + if(fkFromPk == false && ukIndex < 0) + { + wxMessageBox(_("Error detecting kind of foreign key source: from Pk or from Uk"), _("Error importing relationship"), wxICON_ERROR | wxOK); + delete foreignKeys; + return; + } + + + //------ identifying relationship or not -----|-<|? + //Default assumption is relationship is identifying + bool identifying = true; + + //first check: number of columns used as fk at Source is the same of the pk at Source + if(destFkCols.Count() == destPKs.Count()) + { + int i; + //Because postgres columns numbers are stored in an ordered array, + //their index should be the same at all positions + int destFkCount = destFkCols.Count(); + for(i = 0; i < destFkCount; i++) + { + if( destFkCols[i] != destPKs[i] ) + { + identifying = false; + break; + } + } + } + else + { + identifying = false; + } + + //------ 1:1 or 1:M ? as a fact 1:1 have a fk,uk at destination table. + // A foreign key have an one to many relationship when there is an UK for same column(s) + // inside the foreign key. Assumption, a column on belong to one Uk (no more than one). + bool oneToMany = true; + int baseColNumber = destFkCols[destFkCols.Count() - 1]; + int baseUkIdxDestCol = destStubTable->getColumnByNumber(baseColNumber)->uniqueKeyIndex; + if(baseUkIdxDestCol != -1) + { + oneToMany = false; + int nextUkIdxDestCol, nextColNumber; + int countDestFkCols = destFkCols.Count() - 2; + while(countDestFkCols >= 0) + { + nextColNumber = destFkCols[countDestFkCols]; + nextUkIdxDestCol = destStubTable->getColumnByNumber(nextColNumber)->uniqueKeyIndex; + countDestFkCols--; + //if a dest fk column is not in the same Uk index of first one + if(nextUkIdxDestCol != baseUkIdxDestCol) + { + oneToMany = true; + break; + } + } + } + + //Step two check all column of fk are inside a unique key (all and not more) + if(oneToMany == false) //assumption is 1:1 relationship until now + { + int numberColsInUk = 0, nextUkIdxDestCol, nextColNumber; + ddStubColumn *item; + for (it = destStubTable->cols.begin(); it != destStubTable->cols.end(); ++it) + { + wxString key = it->first; + item = it->second; + //at each column with same uk index that base comparison column, count it + nextColNumber = item->pgColNumber; + nextUkIdxDestCol = destStubTable->getColumnByNumber(nextColNumber)->uniqueKeyIndex; + if( nextUkIdxDestCol == baseUkIdxDestCol) + { + numberColsInUk++; + } + } + + //number of columns in uk used by relationship is bigger or lesser than number of columns + //in destination table used by relationship as fk dest(dest fk columnn), then is not 1:1 + if(numberColsInUk != destFkCols.Count()) + oneToMany = true; + } + + //Optional or Mandatory consistency + bool mandatoryRelationship; + + int countDestFkCols = destFkCols.Count() - 1; + bool isNotNull; + int nnCols = 0, nullCols = 0, nextColNumber; + while(countDestFkCols >= 0) + { + nextColNumber = destFkCols[countDestFkCols]; + isNotNull = destStubTable->getColumnByNumber(nextColNumber)->isNotNull; + countDestFkCols--; + if(isNotNull) + nnCols++; + else + nullCols++; + } + + if(nnCols == 0 && nullCols > 0) + { + mandatoryRelationship = false; + } + else if(nnCols > 0 && nullCols == 0) + { + mandatoryRelationship = true; + } + else + { + wxMessageBox(_("Error detecting kind of foreign key: null or not null"), _("Error importing relationship"), wxICON_ERROR | wxOK); + delete foreignKeys; + return; + } + + relation = new ddRelationshipFigure(); + relation->setStartTerminal(new ddRelationshipTerminal(relation, false)); + relation->setEndTerminal(new ddRelationshipTerminal(relation, true)); + relation->clearPoints(0); + relation->initRelationValues(sourceTabFigure, destTabFigure, ukIndex, RelationshipName, onUpdate, onDelete, matchSimple, identifying, oneToMany, mandatoryRelationship, fkFromPk); + relation->updateConnection(0); + design->addTableToModel(relation); + + //Add items to relationship + wxString srcColName, destColName; + ddColumnFigure *sourceCol = NULL, *destinationCol = NULL; + bool autoGenFk = false; + wxString initialColName; + ddRelationshipItem *item = NULL; + int i, srcFkCount = sourceFkCols.Count(); + for(i = 0; i < srcFkCount ; i++) + { + srcColName = sourceStubTable->getColumnByNumber(sourceFkCols[i])->columnName; + destColName = destStubTable->getColumnByNumber(destFkCols[i])->columnName; + sourceCol = sourceTabFigure->getColByName(srcColName); + destinationCol = destTabFigure->getColByName(destColName); + initialColName = srcColName; + item = new ddRelationshipItem(); + item->initRelationshipItemValues(relation, destTabFigure, autoGenFk, destinationCol, sourceCol, initialColName); + relation->getItemsHashMap()[item->original->getColumnName()] = item; + } + } + } + foreignKeys->MoveNext(); + } + delete foreignKeys; + } + } +} + +bool ddImportDBUtils::existsFk(pgConn *connection, OID destTableOid, wxString schemaName, wxString fkName, wxString sourceTableName) +{ + wxString sql; + OID sourceOID = getTableOID(connection, schemaName, sourceTableName); + if(sourceOID == -1 ) + { + return false; + } + + sql = wxT("SELECT ct.oid, conname, condeferrable, condeferred, confupdtype, confdeltype, confmatchtype, ") + wxT("conkey, confkey, confrelid, nl.nspname as fknsp, cl.relname as fktab, ") + wxT("nr.nspname as refnsp, cr.relname as reftab, description"); + if (connection->BackendMinimumVersion(9, 1)) + sql += wxT(", convalidated"); + sql += wxT("\n FROM pg_constraint ct\n") + wxT(" JOIN pg_class cl ON cl.oid=conrelid\n") + wxT(" JOIN pg_namespace nl ON nl.oid=cl.relnamespace\n") + wxT(" JOIN pg_class cr ON cr.oid=confrelid\n") + wxT(" JOIN pg_namespace nr ON nr.oid=cr.relnamespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=ct.oid\n") + wxT(" WHERE contype='f' AND conrelid = ") + NumToStr(destTableOid) + wxT("::oid") + wxT(" AND conname ='") + fkName + wxT("' ") + wxT(" AND confrelid = ") + NumToStr(sourceOID) + wxT("::oid") + wxT("\n") + wxT(" ORDER BY conname"); + + pgSet *foreignKeys = connection->ExecuteSet(sql); + + //relation don't exists then + if(foreignKeys->NumRows() == 0) + { + return false; + } + delete foreignKeys; + + return true; +} + +int ddImportDBUtils::getPgColumnNum(pgConn *connection, wxString schemaName, wxString tableName, wxString columnName) +{ + int out = -1; + wxString sql; + OID tableOid = getTableOID(connection, schemaName, tableName); + wxString systemRestriction; + systemRestriction = wxT("\n AND att.attnum > 0"); + + sql = wxT("SELECT att.attrelid,att.attname, att.attnum ") + wxT("\n") + wxT(" FROM pg_attribute att\n") + wxT(" JOIN pg_type ty ON ty.oid=atttypid\n") + wxT(" JOIN pg_namespace tn ON tn.oid=ty.typnamespace\n") + wxT(" JOIN pg_class cl ON cl.oid=att.attrelid\n") + wxT(" JOIN pg_namespace na ON na.oid=cl.relnamespace\n") + wxT(" LEFT OUTER JOIN pg_type et ON et.oid=ty.typelem\n") + wxT(" LEFT OUTER JOIN pg_attrdef def ON adrelid=att.attrelid AND adnum=att.attnum\n") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=att.attrelid AND des.objsubid=att.attnum\n") + wxT(" LEFT OUTER JOIN (pg_depend JOIN pg_class cs ON classid='pg_class'::regclass AND objid=cs.oid AND cs.relkind='S') ON refobjid=att.attrelid AND refobjsubid=att.attnum\n") + wxT(" LEFT OUTER JOIN pg_namespace ns ON ns.oid=cs.relnamespace\n") + wxT(" LEFT OUTER JOIN pg_index pi ON pi.indrelid=att.attrelid AND indisprimary\n"); + if (connection->BackendMinimumVersion(9, 1)) + sql += wxT(" LEFT OUTER JOIN pg_collation coll ON att.attcollation=coll.oid\n") + wxT(" LEFT OUTER JOIN pg_namespace nspc ON coll.collnamespace=nspc.oid\n"); + sql += wxT(" WHERE att.attrelid = ") + NumToStr(tableOid) + + systemRestriction + wxT("\n") + wxT(" AND att.attisdropped IS FALSE\n") + wxT(" ORDER BY att.attnum"); + + pgSet *columns = connection->ExecuteSet(sql); + if (columns) + { + while (!columns->Eof()) + { + wxString colName = columns->GetVal(wxT("attname")); + if(colName.IsSameAs(columnName, false)) + { + out = columns->GetLong(wxT("attnum")); + break; + } + columns->MoveNext(); + } + delete columns; + } + return out; +} + +wxArrayString ddImportDBUtils::getFkAtDbNotInModel(pgConn *connection, OID destTableOid, wxString schemaName, wxArrayString existingFkList, ddDatabaseDesign *design) +{ + wxArrayString out; + wxString sql; + + sql = wxT("SELECT ct.oid, conname, condeferrable, condeferred, confupdtype, confdeltype, confmatchtype, ") + wxT("conkey, confkey, confrelid, nl.nspname as fknsp, cl.relname as fktab, ") + wxT("nr.nspname as refnsp, cr.relname as reftab, description"); + if (connection->BackendMinimumVersion(9, 1)) + sql += wxT(", convalidated"); + sql += wxT("\n FROM pg_constraint ct\n") + wxT(" JOIN pg_class cl ON cl.oid=conrelid\n") + wxT(" JOIN pg_namespace nl ON nl.oid=cl.relnamespace\n") + wxT(" JOIN pg_class cr ON cr.oid=confrelid\n") + wxT(" JOIN pg_namespace nr ON nr.oid=cr.relnamespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=ct.oid\n") + wxT(" WHERE contype='f' AND conrelid = ") + NumToStr(destTableOid) + wxT("::oid"); + //Add Fk names in model + int i, max = existingFkList.Count(); + if(max > 0) + { + sql += wxT(" AND conname NOT IN( "); + for(i = 0; i < max - 1; i++) + { + sql += wxT("'") + existingFkList[i] + wxT("',"); + } + if(max >= 1) + { + sql += wxT("'") + existingFkList[max - 1] + wxT("'"); + } + sql += wxT(" ) "); + } + + //Add valid tables sources names to search (others outside a model shouldn't be modified) + sql += wxT("\n ORDER BY conname"); + + pgSet *foreignKeys = connection->ExecuteSet(sql); + + if (foreignKeys && foreignKeys->NumRows() > 0) + { + while (!foreignKeys->Eof()) + { + //Create a list will all relationships in db but not in model [but only for tables IN MODEL because tables not in model SHOULDN'T BE modified] + wxString sourceTableName = foreignKeys->GetVal(wxT("reftab")); + if(design->getTable(sourceTableName)) + { + wxString RelationshipName = foreignKeys->GetVal(wxT("conname")); + out.Add(RelationshipName); + } + foreignKeys->MoveNext(); + } + delete foreignKeys; + } + //return a list with Fks to delete from db because don't exists at model. + return out; +} + +//Assumption Fk exists, and this should be checked before with existsFk function +bool ddImportDBUtils::isModelSameDbFk(pgConn *connection, OID destTableOid, wxString schemaName, wxString fkName, wxString sourceTableName, wxString destTableName, ddStubTable *destStubTable, ddRelationshipFigure *relation) +{ + bool equalFk = true; + + wxString sql; + OID sourceOID = getTableOID(connection, schemaName, sourceTableName); + sql = wxT("SELECT ct.oid, conname, condeferrable, condeferred, confupdtype, confdeltype, confmatchtype, ") + wxT("conkey, confkey, confrelid, nl.nspname as fknsp, cl.relname as fktab, ") + wxT("nr.nspname as refnsp, cr.relname as reftab, description"); + if (connection->BackendMinimumVersion(9, 1)) + sql += wxT(", convalidated"); + sql += wxT("\n FROM pg_constraint ct\n") + wxT(" JOIN pg_class cl ON cl.oid=conrelid\n") + wxT(" JOIN pg_namespace nl ON nl.oid=cl.relnamespace\n") + wxT(" JOIN pg_class cr ON cr.oid=confrelid\n") + wxT(" JOIN pg_namespace nr ON nr.oid=cr.relnamespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=ct.oid\n") + wxT(" WHERE contype='f' AND conrelid = ") + NumToStr(destTableOid) + wxT("::oid") + wxT(" AND conname ='") + fkName + wxT("' ") + wxT(" AND confrelid = ") + NumToStr(sourceOID) + wxT("::oid") + wxT("\n") + wxT(" ORDER BY conname"); + + pgSet *foreignKeys = connection->ExecuteSet(sql); + + + //First Step create array with columns from pgCol numbers from destTable (MODEL) in relationship; + //Second Step create array with columns from pgCol numbers from srcTable (MODEL) in relationship; + wxSortedArrayInt destPgs(sortFunc); + wxSortedArrayInt srcPgs(sortFunc); + columnsHashMap::iterator it; + ddRelationshipItem *item; + for (it = relation->getItemsHashMap().begin(); it != relation->getItemsHashMap().end(); ++it) + { + wxString key = it->first; + item = it->second; + int pgColDest = getPgColumnNum(connection, schemaName, destTableName, item->fkColumn->getColumnName()); + destPgs.Add(pgColDest); + int pgColSrc = getPgColumnNum(connection, schemaName, sourceTableName, item->original->getColumnName()); + srcPgs.Add(pgColSrc); + } + + //Extracting relationship metadata information from DB relationship + int ukindex = -1; //Only Supporting foreign keys from PK right now when importing model + wxString RelationshipName; + actionKind onUpdate; + actionKind onDelete; + bool matchSimple; + bool identifying = true; //Default assumption is relationship is identifying + bool oneToMany = true; + bool mandatoryRelationship; + bool fkFromPk = true; //Default assumption is the source of this fk is a Primary Key. + wxSortedArrayInt sourceFkCols(sortFunc); + wxSortedArrayInt destFkCols(sortFunc); + + + if (foreignKeys && foreignKeys->NumRows() == 1) + { + while (!foreignKeys->Eof()) + { + + //------ Preparing metada to allow discovery of some relationship attributes + RelationshipName = foreignKeys->GetVal(wxT("conname")); + + wxString onUpd = foreignKeys->GetVal(wxT("confupdtype")); + onUpdate = onUpd.IsSameAs('a') ? FK_ACTION_NO : + onUpd.IsSameAs('r') ? FK_RESTRICT : + onUpd.IsSameAs('c') ? FK_CASCADE : + onUpd.IsSameAs('d') ? FK_SETDEFAULT : + onUpd.IsSameAs('n') ? FK_SETNULL : FK_ACTION_NO; + + + wxString onDel = foreignKeys->GetVal(wxT("confdeltype")); + onDelete = onUpd.IsSameAs('a') ? FK_ACTION_NO : + onUpd.IsSameAs('r') ? FK_RESTRICT : + onUpd.IsSameAs('c') ? FK_CASCADE : + onUpd.IsSameAs('d') ? FK_SETDEFAULT : + onUpd.IsSameAs('n') ? FK_SETNULL : FK_ACTION_NO; + + wxString match = foreignKeys->GetVal(wxT("confmatchtype")); + matchSimple = match.IsSameAs('f') ? false : + match.IsSameAs('u') ? true : false; + + + //------ Preparing metada to allow discovery of some relationship attributes + //Source table columns + wxString fkColsSourceTable = foreignKeys->GetVal(wxT("confkey")); + wxSortedArrayInt sourcePKs(sortFunc); + wxSortedArrayInt destPKs(sortFunc); + //remove {} of string + fkColsSourceTable.Remove(0, 1); + fkColsSourceTable.RemoveLast(); + wxString fkColsDestTable = foreignKeys->GetVal(wxT("conkey")); + //remove {} of string + fkColsDestTable.Remove(0, 1); + fkColsDestTable.RemoveLast(); + + //Separe columns from sourceFk + wxStringTokenizer confkey(fkColsSourceTable); + while (confkey.HasMoreTokens()) + { + wxString str = confkey.GetNextToken(); + sourceFkCols.Add(StrToLong(str)); + } + + //Separe columns from destFk + wxStringTokenizer conkey(fkColsDestTable); + while (conkey.HasMoreTokens()) + { + wxString str = conkey.GetNextToken(); + destFkCols.Add(StrToLong(str)); + } + + //Get Stub of source table + ddStubTable *sourceStubTable = ddImportDBUtils::getTable(connection, sourceTableName, sourceOID); + + //Get PK columns of source + stubColsHashMap::iterator it; + ddStubColumn *column; + for (it = sourceStubTable->cols.begin(); it != sourceStubTable->cols.end(); ++it) + { + wxString key = it->first; + column = it->second; + if(column->isPrimaryKey) + sourcePKs.Add(column->pgColNumber); + } + + //Get PK columns of dest + for (it = destStubTable->cols.begin(); it != destStubTable->cols.end(); ++it) + { + wxString key = it->first; + column = it->second; + if(column->isPrimaryKey) + destPKs.Add(column->pgColNumber); + } + + // Source Table ----------------------<| Destination Table + + //first check: number of columns used as fk at Source is the same of the pk at Source + if(sourceFkCols.Count() == sourcePKs.Count()) + { + int i; + //Because postgres columns numbers are stored in an ordered array, + //their index should be the same at all positions + int srcFkCount = sourceFkCols.Count(); + for(i = 0; i < srcFkCount; i++) + { + if( sourceFkCols[i] != sourcePKs[i] ) + { + fkFromPk = false; + break; + } + } + } + else + { + fkFromPk = true; + } + + //------ Finding fk from uk or pk? + int ukIndex = -1; + //if fkFromPk = false then is fkfromUK?, check that + //all source fk columns should belong to one Uk at source table. + if( fkFromPk == false ) + { + bool error = false; + int baseColNumber = sourceFkCols[sourceFkCols.Count() - 1]; + int baseUkIdxSourceCol = sourceStubTable->getColumnByNumber(baseColNumber)->uniqueKeyIndex; + int nextColNumber, nextUkIdxSourceCol; + int countSrcFkCols = sourceFkCols.Count() - 2; + while(countSrcFkCols >= 0) + { + nextColNumber = sourceFkCols[countSrcFkCols]; + nextUkIdxSourceCol = sourceStubTable->getColumnByNumber(nextColNumber)->uniqueKeyIndex; + countSrcFkCols--; + if(baseUkIdxSourceCol != nextUkIdxSourceCol) + { + error = true; + wxMessageBox(_("Error detecting kind of foreign key source: from Pk or from Uk"), _("Error importing relationship"), wxICON_ERROR | wxOK); + delete foreignKeys; + return false; + } + } + if(!error) + { + ukIndex = baseUkIdxSourceCol; + } + } + + //Last check of consistency + if(fkFromPk == false && ukIndex < 0) + { + wxMessageBox(_("Error detecting kind of foreign key source: from Pk or from Uk"), _("Error importing relationship"), wxICON_ERROR | wxOK); + delete foreignKeys; + return false; + } + + + //------ identifying relationship or not -----|-<|? + //first check: number of columns used as fk at Source is the same of the pk at Source + if(destFkCols.Count() == destPKs.Count()) + { + int i; + //Because postgres columns numbers are stored in an ordered array, + //their index should be the same at all positions + int destFkCount = destFkCols.Count(); + for(i = 0; i < destFkCount; i++) + { + if( destFkCols[i] != destPKs[i] ) + { + identifying = false; + break; + } + } + } + else + { + identifying = false; + } + + //------ 1:1 or 1:M ? as a fact 1:1 have a fk,uk at destination table. + // A foreign key have an one to many relationship when there is an UK for same column(s) + // inside the foreign key. Assumption, a column on belong to one Uk (no more than one). + int baseColNumber = destFkCols[destFkCols.Count() - 1]; + int baseUkIdxDestCol = destStubTable->getColumnByNumber(baseColNumber)->uniqueKeyIndex; + if(baseUkIdxDestCol != -1) + { + oneToMany = false; + int nextUkIdxDestCol, nextColNumber; + int countDestFkCols = destFkCols.Count() - 2; + while(countDestFkCols >= 0) + { + nextColNumber = destFkCols[countDestFkCols]; + nextUkIdxDestCol = destStubTable->getColumnByNumber(nextColNumber)->uniqueKeyIndex; + countDestFkCols--; + //if a dest fk column is not in the same Uk index of first one + if(nextUkIdxDestCol != baseUkIdxDestCol) + { + oneToMany = true; + break; + } + } + } + + //Step two check all column of fk are inside a unique key (all and not more) + if(oneToMany == false) //assumption is 1:1 relationship until now + { + int numberColsInUk = 0, nextUkIdxDestCol, nextColNumber; + ddStubColumn *item; + for (it = destStubTable->cols.begin(); it != destStubTable->cols.end(); ++it) + { + wxString key = it->first; + item = it->second; + //at each column with same uk index that base comparison column, count it + nextColNumber = item->pgColNumber; + nextUkIdxDestCol = destStubTable->getColumnByNumber(nextColNumber)->uniqueKeyIndex; + if( nextUkIdxDestCol == baseUkIdxDestCol) + { + numberColsInUk++; + } + } + + //number of columns in uk used by relationship is bigger or lesser than number of columns + //in destination table used by relationship as fk dest(dest fk columnn), then is not 1:1 + if(numberColsInUk != destFkCols.Count()) + oneToMany = true; + } + + //Optional or Mandatory consistency + int countDestFkCols = destFkCols.Count() - 1; + bool isNotNull; + int nnCols = 0, nullCols = 0, nextColNumber; + while(countDestFkCols >= 0) + { + nextColNumber = destFkCols[countDestFkCols]; + isNotNull = destStubTable->getColumnByNumber(nextColNumber)->isNotNull; + countDestFkCols--; + if(isNotNull) + nnCols++; + else + nullCols++; + } + + if(nnCols == 0 && nullCols > 0) + { + mandatoryRelationship = false; + } + else if(nnCols > 0 && nullCols == 0) + { + mandatoryRelationship = true; + } + else + { + wxMessageBox(_("Error detecting kind of foreign key: null or not null"), _("Error importing relationship"), wxICON_ERROR | wxOK); + delete foreignKeys; + return false; + } + delete sourceStubTable; + foreignKeys->MoveNext(); + } + //After collection db info compare with model info + + //Is safe to check if this UKindex is the same Ukindex of relationship because both aren't equal. + //Before should by unified by same uk index like in comparing uk at table figure class + //Todo in a future + + //relation is fromPk in model and db? + if(fkFromPk && !relation->isForeignKeyFromPk()) + equalFk = false; + + //OnUpdateAction is the same kind? + if(onUpdate != relation->getOnUpdateAction()) + equalFk = false; + + //OnDeleteAction is the same kind? + if(onDelete != relation->getOnDeleteAction()) + equalFk = false; + + //Are same match kind + if(matchSimple != relation->getMatchSimple()) + equalFk = false; + + //are both identifying? + if(identifying != relation->getIdentifying()) + equalFk = false; + + //are both 1:1 or 1:M + if(oneToMany != relation->getOneToMany()) + equalFk = false; + + //Mandatory value is the same? + if(mandatoryRelationship != relation->getMandatory()) + equalFk = false; + + //Columns at both arrays: created from model and created from db are supposed to have same number of item + //if not fk has changed. + + //Number of source fk columns at DB is the same number of source fk columns at model + if(sourceFkCols.Count() != srcPgs.Count()) + equalFk = false; + + //Number of destination fk columns at DB is the same number of destination fk columns at model + if(destFkCols.Count() != destPgs.Count()) + equalFk = false; + + //Now because arrays are sorted they numbers should match exactly (same pg column number) + int i, max = sourceFkCols.Count(); + for(i = 0; i < max; i++) + { + if(sourceFkCols[i] != srcPgs[i]) + equalFk = false; + } + + max = destFkCols.Count(); + for(i = 0; i < max; i++) + { + if(destFkCols[i] != destPgs[i]) + equalFk = false; + } + + return equalFk; + } + else + { + wxMessageBox(_("Error fk is repeated"), _("Error comparing relationships"), wxICON_ERROR | wxOK); + } + delete foreignKeys; + + return equalFk; +} + +ddTableFigure *ddImportDBUtils::getTableFigure(ddStubTable *table) +{ + wxString name = table->tableName; + ddTableFigure *tableFigure = new ddTableFigure(name, -1, -1); + if(tableFigure != NULL) + { + //Default Values + int colsRowsSize = 0; + int colsWindow = 0; + int idxsRowsSize = 0; + int idxsWindow = 0; + int maxColIndex = 2; + int minIdxIndex = 2; + int maxIdxIndex = 2; + int beginDrawCols = 2; + int beginDrawIdxs = 2; + + tableFigure->InitTableValues(table->UniqueKeysNames, table->PrimaryKeyName, beginDrawCols, beginDrawIdxs, maxColIndex, minIdxIndex, maxIdxIndex, colsRowsSize, colsWindow, idxsRowsSize, idxsWindow); + + //Add Columns to Table + stubColsHashMap::iterator it; + ddStubColumn *item; + for (it = table->cols.begin(); it != table->cols.end(); ++it) + { + wxString key = it->first; + item = it->second; + + ddColumnOptionType option = item->isNotNull ? notnull : null; + bool generateFkName = false; //Not automatic names will be used by default at user imported tables. + + wxString dataType = item->typeColumn->Name(); + + //temporary conversion fix to datatype of designer should be improved in a future + int s = -1, p = -1; + bool useScale = true, needps = false; + s = item->typeColumn->Length(); + p = item->typeColumn->Precision(); + + if(dataType.IsSameAs(wxT("character varying"), false)) + { + needps = true; + dataType = wxT("varchar(n)"); + } + + else if(dataType.IsSameAs(wxT("numeric"), false)) + { + needps = true; + useScale = false; + dataType = wxT("numeric(p,s)"); + } + else if(dataType.IsSameAs(wxT("interval"), false)) + { + needps = true; + dataType = wxT("interval(n)"); + } + else if(dataType.IsSameAs(wxT("bit"), false)) + { + needps = true; + dataType = wxT("bit(n)"); + } + else if(dataType.IsSameAs(wxT("char"), false)) + { + needps = true; + dataType = wxT("char(n)"); + } + else if(dataType.IsSameAs(wxT("varbit"), false)) + { + needps = true; + dataType = wxT("varbit(n)"); + } + else if(dataType.IsSameAs(wxT("character"), false)) + { + needps = true; + dataType = wxT("char(n)"); + } + + int precision = -1; + int scale = -1; + wxString colName = item->columnName; + + int ukindex = -1; //By default no ukindex is set + + ddColumnFigure *columnFigure = new ddColumnFigure(colName, tableFigure, option, generateFkName, item->isPrimaryKey, dataType, precision, scale, ukindex, NULL, NULL); + //a conversion problem I called precision to length of types, pgadmin called scale. + //this should be fixed, at the same time the datatype subsystem of the database designer will be redesigned. + + /* + Disable right now, it can be useful at the future when db designer will be improved again + columnFigure->setPgAttNumCol(item->pgColNumber); + */ + if(needps) + { + if(useScale) + { + columnFigure->setPrecision(s); + columnFigure->setScale(-1); + } + else + { + columnFigure->setPrecision(p); + columnFigure->setScale(s); + } + } + + if(item->isUniqueKey()) + { + columnFigure->setUniqueConstraintIndex(item->uniqueKeyIndex); + } + + tableFigure->addColumn(-1, columnFigure); + columnFigure->setRightIconForColumn(); + } + return tableFigure; + } + else + { + return NULL; + } +} + +ddStubTable::ddStubTable() +{ + tableName = wxEmptyString; +} + +ddStubTable::ddStubTable(wxString name, OID tableOID) +{ + tableName = name; + OIDTable = tableOID; +} + +ddStubTable::~ddStubTable() +{ +} + +ddStubColumn *ddStubTable::getColumnByNumber(int pgColNumber) +{ + stubColsHashMap::iterator it; + ddStubColumn *item, *out = NULL; + for (it = cols.begin(); it != cols.end(); ++it) + { + wxString key = it->first; + item = it->second; + //If found pgColNumber at table columns + if (item->pgColNumber == pgColNumber) + { + out = item; + break; + } + } + return out; +} + +ddStubColumn::ddStubColumn(wxString name, OID oidSource, bool notNull, bool pk, pgDatatype *type, int ukIndex) +{ + columnName = name; + OIDTable = oidSource; + isNotNull = notNull; + isPrimaryKey = pk; + typeColumn = type; + uniqueKeyIndex = ukIndex; +} + +ddStubColumn::ddStubColumn(const ddStubColumn ©) +{ + columnName = copy.columnName; + OIDTable = copy.OIDTable; + isNotNull = copy.isNotNull; + isPrimaryKey = copy.isPrimaryKey; + typeColumn = copy.typeColumn; + uniqueKeyIndex = copy.uniqueKeyIndex; +} + +ddStubColumn::ddStubColumn(wxString name, OID oidSource) +{ + columnName = name; + OIDTable = oidSource; + uniqueKeyIndex = -1; + OIDTable = -1; + typeColumn = NULL; +} + +ddStubColumn::ddStubColumn() +{ + uniqueKeyIndex = -1; + OIDTable = -1; + typeColumn = NULL; +} + +ddStubColumn::~ddStubColumn() +{ + if(typeColumn) + delete typeColumn; +} + +bool ddStubColumn::isUniqueKey() +{ + return uniqueKeyIndex > -1; +}; + +// +// +// +// ----- ddDBReverseEngineering Implementation +// +// +// + +ddDBReverseEngineering::ddDBReverseEngineering(wxFrame *frame, ddDatabaseDesign *design, pgConn *connection, bool useSizer) + : wxWizard(frame, wxID_ANY, wxT("Import tables from schema wizard"), + wxBitmap(*namespaces_png_bmp), wxDefaultPosition, + wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) +{ + conn = connection; + OIDSelectedSchema = 0; + figuresDesign = design; + + // a wizard page may be either an object of predefined class + initialPage = new wxWizardPageSimple(this); + + frontText = new wxStaticText(initialPage, wxID_ANY, + wxT("Import database tables to model tables wizard.\n") + wxT("\n") + wxT("The next pages will allow you to import database tables inside a database model.") + wxT("\n\n") + wxT("\nSome restrictions apply:\n\n") + wxT("1. Columns that belong to more than one unique constraint aren't supported.\n\n") + wxT("2. Relationships are imported only if both tables (source and destination) are imported.\n\n") + wxT("3. User defined datatypes aren't supported.\n\n") + wxT("4. No indexes, views, sequences and others objects different from tables/relationships can be imported.\n\n") + wxT("5. Tables with same name cannot be imported.\n\n") + wxT("6. Inherited tables cannot be imported.\n\n") + , wxPoint(5, 5) + ); + + page2 = new SelSchemaPage(this, initialPage); + initialPage->SetNext(page2); + page3 = new SelTablesPage(this, page2); + page2->SetNext(page3); + page4 = new ReportPage(this, page3); + page3->SetNext(page4); + page4->SetNext(NULL); + + if ( useSizer ) + { + // allow the wizard to size itself around the pages + GetPageAreaSizer()->Add(initialPage); + } +} + +// Destructor +ddDBReverseEngineering::~ddDBReverseEngineering() +{ + if(frontText) + delete frontText; +} + + + +wxArrayString ddDBReverseEngineering::getTables() +{ + + wxArrayString out; + wxString query; + + tablesOIDHM.clear(); + + + // Get the child objects. + query = wxT("SELECT oid, relname, relkind\n") + wxT(" FROM pg_class\n") + wxT(" WHERE relkind IN ('r') AND relnamespace = ") + NumToStr(OIDSelectedSchema) + wxT(";"); + + pgSet *tables = conn->ExecuteSet(query); + + if (tables) + { + while (!tables->Eof()) + { + wxString tmpname = tables->GetVal(wxT("relname")); + wxString relkind = tables->GetVal(wxT("relkind")); + + if (relkind == wxT("r")) // Table + { + out.Add(tables->GetVal(wxT("relname"))); + tablesOIDHM[tables->GetVal(wxT("relname"))] = tables->GetOid(wxT("oid")); + } + + tables->MoveNext(); + } + + delete tables; + } + + return out; +} + +void ddDBReverseEngineering::OnFinishPressed(wxWizardEvent &event) +{ + //Add Tables to the Model + stubTablesHashMap::iterator it; + ddStubTable *item; + for (it = stubsHM.begin(); it != stubsHM.end(); ++it) + { + wxString key = it->first; + item = it->second; + figuresDesign->addTableToModel(ddImportDBUtils::getTableFigure(item)); + } + //Add All relationships to the Model + ddImportDBUtils::getAllRelationships(getConnection(), stubsHM, getDesign()); +} + + +// +// +// +// ----- SelSchemaPage Implementation +// +// +// + +SelSchemaPage::SelSchemaPage(wxWizard *parent, wxWizardPage *prev) + : wxWizardPage(parent) +{ + wparent = (ddDBReverseEngineering *) parent; + m_prev = prev; + m_next = NULL; + + // A top-level sizer + wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL ); + this->SetSizer(topSizer); + + //Add a message + message = new wxStaticText(this, wxID_STATIC, _("Please, select a schema to use at import tables process:"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER); + topSizer->Add(message); + topSizer->AddSpacer(10); + + //Get Schemas info + if(wparent && wparent->getConnection()) + refreshSchemas(wparent->getConnection()); + + //Add a listbox with schemas + m_allSchemas = new wxListBox(this, DDALLSCHEMAS, wxDefaultPosition, wxDefaultSize, schemasNames, wxLB_SORT | wxLB_ALWAYS_SB | wxLB_SINGLE); + topSizer->Add(m_allSchemas, 1, wxEXPAND); +} + +SelSchemaPage::~SelSchemaPage() +{ + if(m_allSchemas) + delete m_allSchemas; + if(message) + delete message; +} + +void SelSchemaPage::OnWizardPageChanging(wxWizardEvent &event) +{ + if(event.GetDirection() && m_allSchemas->GetSelection() == wxNOT_FOUND) + { + wxMessageBox(_("Please, select a Schema to continue to next step."), _("Select a Schema..."), wxICON_WARNING | wxOK, this); + event.Veto(); + } + else if(event.GetDirection()) + { + wparent->OIDSelectedSchema = schemasHM[schemasNames[m_allSchemas->GetSelection()]]; + wparent->schemaName = schemasNames[m_allSchemas->GetSelection()]; + wparent->page3->RefreshTablesList(); + } +} + +void SelSchemaPage::refreshSchemas(pgConn *connection) +{ + + schemasHM.clear(); + schemasNames.Clear(); + // Search Schemas and insert it + wxString restr = wxT(" WHERE "); + + restr += wxT("NOT "); + restr += wxT("((nspname = 'pg_catalog' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'pg_class' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname = 'pgagent' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'pga_job' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname = 'information_schema' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'tables' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname LIKE '_%' AND EXISTS (SELECT 1 FROM pg_proc WHERE proname='slonyversion' AND pronamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname = 'dbo' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'systables' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname = 'sys' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'all_tables' AND relnamespace = nsp.oid LIMIT 1)))\n"); + + if (connection->EdbMinimumVersion(8, 2)) + { + restr += wxT(" AND nsp.nspparent = 0\n"); + // Do not show dbms_job_procedure in schemas + if (!settings->GetShowSystemObjects()) + restr += wxT("AND NOT (nspname = 'dbms_job_procedure' AND EXISTS(SELECT 1 FROM pg_proc WHERE pronamespace = nsp.oid and proname = 'run_job' LIMIT 1))\n"); + } + + wxString sql; + + if (connection->BackendMinimumVersion(8, 1)) + { + sql = wxT("SELECT CASE WHEN nspname LIKE E'pg\\\\_temp\\\\_%' THEN 1\n") + wxT(" WHEN (nspname LIKE E'pg\\\\_%') THEN 0\n"); + } + else + { + sql = wxT("SELECT CASE WHEN nspname LIKE 'pg\\\\_temp\\\\_%' THEN 1\n") + wxT(" WHEN (nspname LIKE 'pg\\\\_%') THEN 0\n"); + } + sql += wxT(" ELSE 3 END AS nsptyp, nspname, nsp.oid\n") + wxT(" FROM pg_namespace nsp\n") + + restr + + wxT(" ORDER BY 1, nspname"); + + pgSet *schemas = connection->ExecuteSet(sql); + + if (schemas) + { + while (!schemas->Eof()) + { + wxString name = schemas->GetVal(wxT("nspname")); + long nsptyp = schemas->GetLong(wxT("nsptyp")); + + wxStringTokenizer tokens(settings->GetSystemSchemas(), wxT(",")); + while (tokens.HasMoreTokens()) + { + wxRegEx regex(tokens.GetNextToken()); + if (regex.Matches(name)) + { + nsptyp = SCHEMATYP_USERSYS; + break; + } + } + + if (nsptyp <= SCHEMATYP_USERSYS && !settings->GetShowSystemObjects()) + { + schemas->MoveNext(); + continue; + } + + //Build Schema Tree item + //this->AppendItem(rootNode, name , DD_IMG_FIG_SCHEMA, DD_IMG_FIG_SCHEMA, NULL); + schemasNames.Add(name); + schemasHM[name] = schemas->GetOid(wxT("oid")); + schemas->MoveNext(); + } + + delete schemas; + } + +} + +// +// +// +// ----- SelTablesPage Implementation +// +// +// + +SelTablesPage::SelTablesPage(wxWizard *parent, wxWizardPage *prev) + : wxWizardPage(parent) +{ + wparent = (ddDBReverseEngineering *) parent; + m_prev = prev; + m_next = NULL; + + wxFlexGridSizer *mainSizer = new wxFlexGridSizer(2, 3, 0, 0); + this->SetSizer(mainSizer); + + leftText = new wxStaticText(this, wxID_STATIC, _("Table(s) from selected schema"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER); + mainSizer->Add(leftText); + centerText = new wxStaticText(this, wxID_STATIC, wxT(" "), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER); + mainSizer->Add(centerText); + + rightText = new wxStaticText(this, wxID_STATIC, _("Tables(s) to be imported"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER); + mainSizer->Add(rightText, wxALIGN_LEFT); + + //left listbox with all tables from selected schema + m_allTables = new wxListBox( this, DDALLTABS, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_EXTENDED | wxLB_ALWAYS_SB | wxLB_SORT); + mainSizer->AddGrowableRow(1); + mainSizer->AddGrowableCol(0); + mainSizer->Add(m_allTables , 1, wxEXPAND); + + addBitmap = *gqbOrderAdd_png_bmp; + addAllBitmap = *gqbOrderAddAll_png_bmp; + removeBitmap = *gqbOrderRemove_png_bmp; + removeAllBitmap = *gqbOrderRemoveAll_png_bmp; + + buttonAdd = new wxBitmapButton( this, DDADD, addBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Add Column") ); + buttonAdd->SetToolTip(_("Add the selected table(s)")); + buttonAddAll = new wxBitmapButton( this, DDADDALL, addAllBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Add All Columns") ); + buttonAddAll->SetToolTip(_("Add all tables")); + buttonRemove = new wxBitmapButton( this, DDREMOVE, removeBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Remove Column") ); + buttonRemove->SetToolTip(_("Remove the selected table(s)")); + buttonRemoveAll = new wxBitmapButton( this, DDREMOVEALL, removeAllBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Remove All Columns") ); + buttonRemoveAll->SetToolTip(_("Remove all tables")); + + wxBoxSizer *buttonsSizer = new wxBoxSizer( wxVERTICAL ); + + buttonsSizer->Add( + this->buttonAdd, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 3 + + buttonsSizer->Add( + this->buttonAddAll, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 3 + + buttonsSizer->Add( + this->buttonRemove, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 3 + + buttonsSizer->Add( + this->buttonRemoveAll, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 3 + + mainSizer->Add( + buttonsSizer, + 0, // make vertically unstretchable + wxALIGN_CENTER ); // no border and centre horizontally + + //right listbox with selected tables from schema to be imported. + m_selTables = new wxListBox( this, DDSELTABS, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_EXTENDED | wxLB_ALWAYS_SB | wxLB_SORT); + mainSizer->AddGrowableCol(2); + mainSizer->Add(m_selTables , 1, wxEXPAND); + mainSizer->Fit(this); +} + +SelTablesPage::~SelTablesPage() +{ + if(rightText) + delete rightText; + if(centerText) + delete centerText; + if(leftText) + delete leftText; + if(m_allTables) + delete m_allTables; + if(m_selTables) + delete m_selTables; + if(buttonAdd) + delete buttonAdd; + if(buttonAddAll) + delete buttonAddAll; + if(buttonRemove) + delete buttonRemove; + if(buttonRemoveAll) + delete buttonRemoveAll; +} + +void SelTablesPage::RefreshTablesList() +{ + m_allTables->Set(wparent->getTables(), (void **)NULL); +} + +void SelTablesPage::OnButtonAdd(wxCommandEvent &) +{ + wxArrayInt positions; + if(m_allTables->GetSelections(positions) > 0) + { + int i; + int size = positions.Count(); + for(i = 0; i < size; i++) + { + m_selTables->Append(m_allTables->GetString(positions[i])); + m_allTables->Deselect(positions[i]); + } + + for(i = (size - 1); i >= 0 ; i--) + { + m_allTables->Delete(positions[i]); + } + + if(m_allTables->GetCount() > 0) + m_allTables->Select(0); + } +} + +void SelTablesPage::OnButtonAddAll(wxCommandEvent &) +{ + int itemsCount = m_allTables->GetCount(); + if( itemsCount > 0) + { + do + { + m_allTables->Deselect(0); + m_selTables->Append(m_allTables->GetString(0)); + m_allTables->Delete(0); + itemsCount--; + } + while(itemsCount > 0); + } +} + +void SelTablesPage::OnButtonRemove(wxCommandEvent &) +{ + wxArrayInt positions; + if(m_selTables->GetSelections(positions) > 0) + { + int i; + int size = positions.Count(); //warning about conversion should be ignored + for(i = 0; i < size; i++) + { + m_allTables->Append(m_selTables->GetString(positions[i])); + m_selTables->Deselect(positions[i]); + } + + for(i = (size - 1); i >= 0 ; i--) + { + m_selTables->Delete(positions[i]); + } + + if(m_selTables->GetCount() > 0) + m_selTables->Select(0); + } +} + +void SelTablesPage::OnButtonRemoveAll(wxCommandEvent &) +{ + int itemsCount = m_selTables->GetCount(); + if( itemsCount > 0) + { + do + { + m_selTables->Deselect(0); + m_allTables->Append(m_selTables->GetString(0)); + m_selTables->Delete(0); + itemsCount--; + } + while(itemsCount > 0); + } +} + +void SelTablesPage::OnWizardPageChanging(wxWizardEvent &event) +{ + if(event.GetDirection() && m_selTables->GetCount() <= 0) + { + wxMessageBox(_("Please, select at least a table to continue to next step."), _("Select some Tables..."), wxICON_WARNING | wxOK, this); + event.Veto(); + } + else if(event.GetDirection()) + { + + int itemsCount = m_selTables->GetCount(); + if( itemsCount > 0) + { + int item = 0; + do + { + ddStubTable *table = ddImportDBUtils::getTable(wparent->getConnection(), m_selTables->GetString(item), wparent->tablesOIDHM[m_selTables->GetString(item)]); + if(table == NULL) + { + ReportPage *tmp = (ReportPage *) m_next; + tmp->results->AppendText(_("Error when preparing to import table: ") + m_selTables->GetString(item) + _(", this table have inherited columns and this feature is not supported at this moment.\n\n")); + } + else if(wparent->getDesign()->getTable(m_selTables->GetString(item)) != NULL) + { + ReportPage *tmp = (ReportPage *) m_next; + tmp->results->AppendText(_("Error when preparing to import table: ") + m_selTables->GetString(item) + _(", this table already exists in the model and updating table at a model is not supported at this moment.\n\n")); + } + else if(table->tableName.Length() > 0) + { + if(m_next) + { + ReportPage *tmp = (ReportPage *) m_next; + tmp->results->AppendText(_("Prepared to import table: ") + table->tableName + _("\n")); + wparent->stubsHM[table->tableName] = table; + } + } + else + { + if(m_next) + { + ReportPage *tmp = (ReportPage *) m_next; + tmp->results->AppendText(_("Error when preparing to import table: ") + m_selTables->GetString(item) + _("\n")); + } + } + item++; + } + while(item < itemsCount); + } + } + else if(!event.GetDirection()) + { + //Reset tables after a warning + int answer = wxMessageBox(_("Returning to previous dialog will remove all selected tables, do you like to continue?"), _("Confirm"), wxYES_NO | wxCANCEL, this); + if (answer == wxYES) + { + m_selTables->Clear(); + m_allTables->Clear(); + wparent->tablesOIDHM.clear(); + } + else + event.Veto(); + } +} + +// +// +// +// ----- ReportPage Implementation +// +// +// + +ReportPage::ReportPage(wxWizard *parent, wxWizardPage *prev) + : wxWizardPage(parent) +{ + wparent = (ddDBReverseEngineering *) parent; + m_prev = prev; + m_next = NULL; + + // A top-level sizer + wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL ); + this->SetSizer(topSizer); + + //Add a message + results = new wxTextCtrl(this, wxID_ANY , wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_LEFT + ); + topSizer->Add(results, 1, wxEXPAND); + topSizer->Fit(this); +} + +ReportPage::~ReportPage() +{ + if(results) + delete results; +} + +void ReportPage::OnWizardPageChanging(wxWizardEvent &event) +{ + if(!event.GetDirection()) + { + int answer = wxMessageBox(_("Returning to previous dialog will delete imported tables before adding it to the model?"), _("Confirm"), wxYES_NO | wxCANCEL, this); + if (answer == wxYES) + { + results->Clear(); + wparent->stubsHM.clear(); + } + else + event.Veto(); + } +} + diff --git a/dd/ddmodel/ddDatabaseDesign.cpp b/dd/ddmodel/ddDatabaseDesign.cpp new file mode 100644 index 0000000..68e52d2 --- /dev/null +++ b/dd/ddmodel/ddDatabaseDesign.cpp @@ -0,0 +1,710 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddDatabaseDesign.cpp - Manages all design related info and contains all model(s) and tables. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// libxml2 headers +#include +#include + +// App headers +#include "dd/ddmodel/ddDatabaseDesign.h" +#include "hotdraw/tools/hdSelectionTool.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/dditems/figures/ddRelationshipFigure.h" +#include "dd/dditems/utilities/ddDataType.h" +#include "dd/ddmodel/ddDrawingEditor.h" +#include "dd/dditems/figures/xml/ddXmlStorage.h" +#include "dd/ddmodel/ddModelBrowser.h" + + +ddDatabaseDesign::ddDatabaseDesign(wxWindow *parent, wxWindow *frmOwner) +{ + editor = new ddDrawingEditor(parent, frmOwner, this); + attachedBrowser = NULL; +} + +ddDatabaseDesign::~ddDatabaseDesign() +{ + if(editor) + delete editor; +} + +ddDrawingEditor *ddDatabaseDesign::getEditor() +{ + return editor; +} + +hdDrawingView *ddDatabaseDesign::getView(int diagramIndex) +{ + return editor->getExistingView(diagramIndex); +} + +void ddDatabaseDesign::registerBrowser(ddModelBrowser *browser) +{ + attachedBrowser = browser; +} + +void ddDatabaseDesign::addTableToModel(hdIFigure *figure) +{ + editor->addModelFigure(figure); + if(attachedBrowser) + { + attachedBrowser->refreshFromModel(); + } +} + +void ddDatabaseDesign::addTableToView(int diagramIndex, hdIFigure *figure) +{ + editor->addDiagramFigure(diagramIndex, figure); + if(attachedBrowser) + { + attachedBrowser->refreshFromModel(); + } +} + +void ddDatabaseDesign::refreshBrowser() +{ + if(attachedBrowser) + { + attachedBrowser->refreshFromModel(); + } +} + +void ddDatabaseDesign::removeTable(int diagramIndex, hdIFigure *figure) +{ + editor->removeDiagramFigure(diagramIndex, figure); +} + +void ddDatabaseDesign::refreshDraw(int diagramIndex) +{ + editor->getExistingView(diagramIndex)->Refresh(); +} + +void ddDatabaseDesign::eraseDiagram(int diagramIndex) +{ + editor->getExistingDiagram(diagramIndex)->removeAllFigures(); +} + +void ddDatabaseDesign::emptyModel() +{ + editor->deleteAllModelFigures(); + if(attachedBrowser) + { + attachedBrowser->refreshFromModel(); + } +} + +bool ddDatabaseDesign::validateModel(wxString &errors) +{ + bool out = true; + + hdIteratorBase *iterator = editor->modelFiguresEnumerator(); + hdIFigure *tmpFigure; + ddTableFigure *table; + + while(iterator->HasNext()) + { + tmpFigure = (hdIFigure *)iterator->Next(); + if(tmpFigure->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmpFigure; + if(!table->validateTable(errors)) + { + out = false; + } + } + } + delete iterator; + + return out; +} + +wxString ddDatabaseDesign::generateList(wxArrayString tables, wxArrayInt options, pgConn *connection, wxString schemaName) +{ + int i; + + // Validate + if(tables.Count() != options.Count()) + { + // shouldn't it be a WXASSERT? + wxMessageBox(_("Invalid number of arguments in call of function generate tables of list"), _("Error at generation process"), wxICON_ERROR | wxOK); + return wxEmptyString; + } + + int tablesCount = tables.Count(); + for(i = 0; i < tablesCount; i++) + { + ddTableFigure *table = getTable(tables[i]); + if(table == NULL) + { + // shouldn't it be a WXASSERT? + wxMessageBox(_("Metadata of table to be generated not found at database designer model"), _("Error at generation process"), wxICON_ERROR | wxOK); + return wxEmptyString; + } + } + + // Start building of CREATE + ALTER PK(s) + ALTER UK(s) + ALTER FK(s) + wxString out; + out += wxT(" \n"); + out += wxT("--\n-- "); + out += _("Generating Create sentence(s) for table(s) "); + out += wxT(" \n--\n"); + out += wxT(" \n"); + for(i = 0; i < tablesCount; i++) + { + if(options[i] == DDGENCREATE || options[i] == DDGENDROPCRE) + { + ddTableFigure *table = getTable(tables[i]); + if(options[i] == DDGENDROPCRE) + { + out += wxT(" \n"); + out += wxT("DROP TABLE \"") + table->getTableName() + wxT("\";"); + out += wxT(" \n"); + } + out += wxT(" \n"); + out += table->generateSQLCreate(schemaName); + out += wxT(" \n"); + } + } + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT("--\n-- "); + out += _("Generating Pk sentence for table(s) "); + out += wxT(" \n--\n"); + out += wxT(" \n"); + out += wxT(" \n"); + for(i = 0; i < tablesCount; i++) + { + if(options[i] == DDGENCREATE || options[i] == DDGENDROPCRE) + { + ddTableFigure *table = getTable(tables[i]); + out += table->generateSQLAlterPks(schemaName); + } + } + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT("--\n-- "); + out += _("Generating Uk sentence(s) for table(s) "); + out += wxT(" \n--\n"); + out += wxT(" \n"); + out += wxT(" \n"); + for(i = 0; i < tablesCount; i++) + { + if(options[i] == DDGENCREATE || options[i] == DDGENDROPCRE) + { + ddTableFigure *table = getTable(tables[i]); + out += table->generateSQLAlterUks(schemaName); + } + } + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT("--\n-- "); + out += _("Generating Fk sentence(s) for table(s) "); + out += wxT(" \n--\n"); + out += wxT(" \n"); + out += wxT(" \n"); + for(i = 0; i < tablesCount; i++) + { + if(options[i] == DDGENCREATE || options[i] == DDGENDROPCRE) + { + ddTableFigure *table = getTable(tables[i]); + out += table->generateSQLAlterFks(schemaName); + } + } + + //Start generation of alter table instead of create + //Check there is some + int countAlter = 0; + for(i = 0; i < tablesCount; i++) + { + if(options[i] == DDGENALTER) + { + countAlter++; + } + } + + if(countAlter > 0 && connection == NULL) + { + wxMessageBox(_("No connection found when building ALTER objects DDL."), _("Error at generation process"), wxICON_ERROR | wxOK); + return out; + } + else if(countAlter > 0 && connection != NULL) + { + if(schemaName.IsEmpty()) + { + wxMessageBox(_("Schema defined when building ALTER TABLE DDL"), _("Error at generation process"), wxICON_ERROR | wxOK); + return out; + } + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT("--\n-- "); + out += _("Generating Alter table sentence(s) for table(s) "); + out += wxT(" \n--\n"); + out += wxT(" \n"); + out += wxT(" \n"); + for(i = 0; i < tablesCount; i++) + { + if(options[i] == DDGENALTER) + { + ddTableFigure *table = getTable(tables[i]); + out += table->generateAltersTable(connection, schemaName, this); + out += wxT(" \n"); + } + } + } + + return out; +} + +wxArrayString ddDatabaseDesign::getModelTables() +{ + wxArrayString out; + hdIteratorBase *iterator = editor->modelFiguresEnumerator(); + hdIFigure *tmp; + ddTableFigure *table; + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmp; + out.Add(table->getTableName()); + } + } + return out; +} + +wxString ddDatabaseDesign::generateModel(wxString schemaName) +{ + wxString out; + hdIteratorBase *iterator = editor->modelFiguresEnumerator(); + hdIFigure *tmp; + ddTableFigure *table; + out += wxT(" \n"); + out += wxT("--\n-- "); + out += _("Generating Create sentence(s) for table(s) "); + out += wxT(" \n--\n"); + out += wxT(" \n"); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDTABLEFIGURE) + { + out += wxT(" \n"); + table = (ddTableFigure *)tmp; + out += table->generateSQLCreate(schemaName); + out += wxT(" \n"); + } + } + + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT("--\n-- "); + out += _("Generating Pk sentence for table(s) "); + out += wxT(" \n--\n"); + out += wxT(" \n"); + out += wxT(" \n"); + iterator->ResetIterator(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmp; + out += table->generateSQLAlterPks(schemaName); + } + } + + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT("--\n-- "); + out += _("Generating Uk sentence(s) for table(s) "); + out += wxT(" \n--\n"); + out += wxT(" \n"); + out += wxT(" \n"); + iterator->ResetIterator(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmp; + out += table->generateSQLAlterUks(schemaName); + } + } + + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT("--\n-- "); + out += _("Generating Fk sentence(s) for table(s) "); + out += wxT(" \n--\n"); + out += wxT(" \n"); + out += wxT(" \n"); + iterator->ResetIterator(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmp; + out += table->generateSQLAlterFks(schemaName); + } + } + + delete iterator; + return out; +} + +wxArrayString ddDatabaseDesign::getDiagramTables(int diagramIndex) +{ + wxArrayString out; + hdIteratorBase *iterator = editor->getExistingDiagram(diagramIndex)->figuresEnumerator(); + hdIFigure *tmp; + ddTableFigure *table; + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmp; + out.Add(table->getTableName()); + } + } + + return out; +} + +wxString ddDatabaseDesign::generateDiagram(int diagramIndex, wxString schemaName) +{ + wxString out; + hdIteratorBase *iterator = editor->getExistingDiagram(diagramIndex)->figuresEnumerator(); + hdIFigure *tmp; + ddTableFigure *table; + out += wxT(" \n"); + out += wxT("--\n-- "); + out += _("Generating Create sentence(s) for table(s) "); + out += wxT(" \n--\n"); + out += wxT(" \n"); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDTABLEFIGURE) + { + out += wxT(" \n"); + table = (ddTableFigure *)tmp; + out += table->generateSQLCreate(schemaName); + out += wxT(" \n"); + } + } + + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT("--\n-- "); + out += _("Generating Pk sentence for table(s) "); + out += wxT(" \n--\n"); + out += wxT(" \n"); + out += wxT(" \n"); + iterator->ResetIterator(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmp; + out += table->generateSQLAlterPks(schemaName); + } + } + + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT("--\n-- "); + out += _("Generating Uk sentence(s) for table(s) "); + out += wxT(" \n--\n"); + out += wxT(" \n"); + out += wxT(" \n"); + iterator->ResetIterator(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmp; + out += table->generateSQLAlterUks(schemaName); + } + } + + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT("--\n-- "); + out += _("Generating Fk sentence(s) for table(s) "); + out += wxT(" \n--\n"); + out += wxT(" \n"); + out += wxT(" \n"); + iterator->ResetIterator(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmp; + out += table->generateSQLAlterFks(schemaName); + } + } + + delete iterator; + return out; +} + +ddTableFigure *ddDatabaseDesign::getSelectedTable(int diagramIndex) +{ + hdIteratorBase *iterator = editor->getExistingDiagram(diagramIndex)->figuresEnumerator(); + hdIFigure *tmp; + ddTableFigure *table = NULL; + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if (tmp->isSelected(diagramIndex) && tmp->getKindId() == DDTABLEFIGURE) + table = (ddTableFigure *)tmp; + } + delete iterator; + return table; +} + +ddTableFigure *ddDatabaseDesign::getTable(wxString tableName) +{ + ddTableFigure *out = NULL; + hdIteratorBase *iterator = editor->modelFiguresEnumerator(); + hdIFigure *tmp; + ddTableFigure *table; + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmp; + if(table->getTableName().IsSameAs(tableName, false)) + { + out = table; + } + } + } + delete iterator; + return out; +} + +#define XML_FROM_WXSTRING(s) ((xmlChar *)(const char *)s.mb_str(wxConvUTF8)) +#define WXSTRING_FROM_XML(s) wxString((char *)s, wxConvUTF8) + +bool ddDatabaseDesign::writeXmlModel(wxString file) +{ + int rc; + + xmlWriter = xmlNewTextWriterFilename(file.mb_str(wxConvUTF8), 0); + if (xmlWriter == NULL) + { + wxMessageBox(_("Failed to write the model file!"), _("Error"), wxICON_ERROR | wxOK); + return false; + } + rc = xmlTextWriterStartDocument(xmlWriter, NULL, "UTF-8" , NULL); + if(rc < 0) + { + wxMessageBox(_("Failed to write the model file!"), _("Error"), wxICON_ERROR | wxOK); + return false; + } + else + { + ddXmlStorage::StartModel(xmlWriter, this); + //initialize IDs of tables + mappingNameToId.clear(); + hdIteratorBase *iterator = editor->modelFiguresEnumerator(); + hdIFigure *tmp; + ddTableFigure *table; + int nextID = 10; + + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmp; + mappingNameToId[table->getTableName()] = wxString::Format(wxT("TID%d"), nextID); + nextID += 10; + } + } + delete iterator; + + + //Create table xml info + iterator = editor->modelFiguresEnumerator(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmp; + ddXmlStorage::Write(xmlWriter, table); + } + } + delete iterator; + + + //Create relationships xml info + ddRelationshipFigure *relationship; + iterator = editor->modelFiguresEnumerator(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDRELATIONSHIPFIGURE) + { + relationship = (ddRelationshipFigure *)tmp; + ddXmlStorage::Write(xmlWriter, relationship); + } + } + delete iterator; + + //Create Diagrams xml info + + ddXmlStorage::StarDiagrams(xmlWriter); + + iterator = editor->diagramsEnumerator(); + hdDrawing *tmpDiagram; + + while(iterator->HasNext()) + { + tmpDiagram = (hdDrawing *)iterator->Next(); + ddXmlStorage::WriteLocal(xmlWriter, tmpDiagram); + } + delete iterator; + + ddXmlStorage::EndDiagrams(xmlWriter); + + //End model xml info + ddXmlStorage::EndModel(xmlWriter); + xmlTextWriterEndDocument(xmlWriter); + xmlFreeTextWriter(xmlWriter); + return true; + } + return false; +} + +bool ddDatabaseDesign::readXmlModel(wxString file, ctlAuiNotebook *notebook) +{ + emptyModel(); + + mappingIdToName.clear(); + //Initial Parse Model + xmlTextReaderPtr reader = xmlReaderForFile(file.mb_str(wxConvUTF8), NULL, 0); + ddXmlStorage::setModel(this); + ddXmlStorage::setModel(this); + ddXmlStorage::initialModelParse(reader); + + //Parse Model + xmlReaderNewFile(reader, file.mb_str(wxConvUTF8), NULL, 0); + ddXmlStorage::setModel(this); + ddXmlStorage::setNotebook(notebook); + + if(!ddXmlStorage::Read(reader)) + { + return false; + } + xmlFreeTextReader(reader); + return true; +} + +wxString ddDatabaseDesign::getTableId(wxString tableName) +{ + return mappingNameToId[tableName]; +} + +void ddDatabaseDesign::addTableToMapping(wxString IdKey, wxString tableName) +{ + mappingIdToName[IdKey] = tableName; +} + +wxString ddDatabaseDesign::getTableName(wxString Id) +{ + wxString tableName = wxEmptyString; + + tablesMappingHashMap::iterator it; + for (it = mappingIdToName.begin(); it != mappingIdToName.end(); ++it) + { + wxString key = it->first; + if(key.IsSameAs(Id, false)) + { + tableName = it->second; + break; + } + } + return tableName; +} + +hdDrawing *ddDatabaseDesign::createDiagram(wxWindow *owner, wxString name, bool fromXml) +{ + hdDrawing *drawing = editor->createDiagram(owner, fromXml); + drawing->setName(name); + return drawing; +} + +void ddDatabaseDesign::deleteDiagram(int diagramIndex, bool deleteView) +{ + editor->deleteDiagram(diagramIndex, deleteView); +} + +wxString ddDatabaseDesign::getVersionXML() +{ + return wxString(_("1.0")); +} + +void ddDatabaseDesign::markSchemaOn(wxArrayString tables) +{ + + int i, tablesCount = tables.Count(); + for(i = 0; i < tablesCount; i++) + { + ddTableFigure *table = getTable(tables[i]); + if(table != NULL) //mark on if table exists in other case do nothing + { + table->setBelongsToSchema(true); + } + } +} + +void ddDatabaseDesign::unMarkSchemaOnAll() +{ + hdIteratorBase *iterator = editor->modelFiguresEnumerator(); + hdIFigure *tmpFigure; + ddTableFigure *table; + + while(iterator->HasNext()) + { + tmpFigure = (hdIFigure *)iterator->Next(); + if(tmpFigure->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmpFigure; + table->setBelongsToSchema(false); + } + } + delete iterator; +} diff --git a/dd/ddmodel/ddDrawingEditor.cpp b/dd/ddmodel/ddDrawingEditor.cpp new file mode 100644 index 0000000..ddf593c --- /dev/null +++ b/dd/ddmodel/ddDrawingEditor.cpp @@ -0,0 +1,300 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdDrawingEditor.cpp - Main class that manages all other classes +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "dd/ddmodel/ddDrawingEditor.h" +#include "dd/dditems/utilities/ddTableNameDialog.h" +#include "dd/ddmodel/ddDatabaseDesign.h" +#include "dd/ddmodel/ddDrawingView.h" +#include "hotdraw/utilities/hdRemoveDeleteDialog.h" +#include "dd/dditems/figures/ddRelationshipFigure.h" +#include "frm/frmDatabaseDesigner.h" + + +ddDrawingEditor::ddDrawingEditor(wxWindow *owner, wxWindow *frmOwner, ddDatabaseDesign *design) + : hdDrawingEditor(owner, true) +{ + databaseDesign = design; + frm = (frmDatabaseDesigner *) frmOwner; +} + +hdDrawing *ddDrawingEditor::createDiagram(wxWindow *owner, bool fromXml) +{ + + hdDrawing *_tmpModel = new hdDrawing(this); + + ddDrawingView *_viewTmp = new ddDrawingView(_diagrams->count(), owner, this, wxSize(1200, 1200), _tmpModel); + + // Set Scroll Bar & split + _viewTmp->SetScrollbars( 10, 10, 127, 80 ); + _viewTmp->EnableScrolling(true, true); + _viewTmp->AdjustScrollbars(); + + _tmpModel->registerView(_viewTmp); + + _viewTmp->SetDropTarget(new ddDropTarget(databaseDesign, _tmpModel)); + + if(!fromXml) + { + //Add a new position inside each figure to allow use of this new diagram existing figures. + int i; + hdIFigure *tmp; + for(i = 0; i < _model->count(); i++) + { + tmp = (hdIFigure *) _model->getItemAt(i); + tmp->AddPosForNewDiagram(); + } + } + //Add Diagram + _diagrams->addItem((hdObject *) _tmpModel); + modelChanged = true; + return _tmpModel; +} + + +void ddDrawingEditor::remOrDelSelFigures(int diagramIndex) +{ + hdIFigure *tmp; + ddTableFigure *table; + ddRelationshipFigure *relation; + hdIteratorBase *iterator; + hdCollection *tmpSelection; + int answer; + int numbTables = 0; + int numbRelationships = 0; + + if (getExistingDiagram(diagramIndex)->countSelectedFigures() == 1) + { + tmp = (hdIFigure *) getExistingDiagram(diagramIndex)->selectedFigures()->getItemAt(0); + if(tmp->getKindId() == DDTABLEFIGURE) + { + numbTables = 1; + table = (ddTableFigure *)tmp; + hdRemoveDeleteDialog dialog(_("Are you sure you wish to delete table ") + table->getTableName() + wxT("?"), _("Delete table?"), getExistingView(diagramIndex)); + answer = dialog.ShowModal(); + } + if(tmp->getKindId() == DDRELATIONSHIPFIGURE) + { + numbRelationships = 1; + relation = (ddRelationshipFigure *)tmp; + //Relationship can be delete only NOT REMOVED + hdRemoveDeleteDialog dialog2(_("Are you sure you wish to delete relationship ") + relation->getConstraintName() + wxT("?"), _("Delete relationship?"), getExistingView(diagramIndex), false); + answer = dialog2.ShowModal(); + } + } + else if (getExistingDiagram(diagramIndex)->countSelectedFigures() > 1) + { + numbTables = 0; + iterator = getExistingDiagram(diagramIndex)->selectionFigures(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDTABLEFIGURE) + numbTables++; + } + delete iterator; + + + //Improve messages to display about relationships and tables and only relationship + hdRemoveDeleteDialog dialog3( + wxString::Format(_("Are you sure you wish to delete %d tables, removing from model related relationships?"), numbTables), + _("Delete tables?"), getExistingView(diagramIndex)); + answer = dialog3.ShowModal(); + } + + if (answer == DD_DELETE || answer == DD_REMOVE) + { + modelChanged = true; + tmpSelection = new hdCollection(new hdArrayCollection()); + + //Preprocess relationships counting and storing at temporary collection + numbRelationships = 0; + iterator = getExistingDiagram(diagramIndex)->selectionFigures(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDRELATIONSHIPFIGURE) + { + numbRelationships++; + tmpSelection->addItem(tmp); + } + } + delete iterator; + + while(numbTables > 0) + { + tmp = (hdIFigure *) getExistingDiagram(diagramIndex)->selectedFigures()->getItemAt(0); + if(tmp->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmp; + if(table && answer == DD_REMOVE) + { + getExistingDiagram(diagramIndex)->removeFromSelection(table); + getExistingDiagram(diagramIndex)->remove(table); + } + //if table is going to be delete all others diagrams should be alerted about it + if(table && answer == DD_DELETE) + { + removeFromAllSelections(table); + table->processDeleteAlert(getExistingDiagram(diagramIndex)); + deleteModelFigure(table); + databaseDesign->refreshBrowser(); + } + numbTables--; + } + else if(tmp->getKindId() == DDRELATIONSHIPFIGURE) + { + getExistingDiagram(diagramIndex)->removeFromSelection(tmp); //isn't a tables is probably a relationship + } + else + { + wxMessageBox(_("Invalid figure kind found"), _("Error while deleting tables"), wxCENTRE | wxICON_ERROR, getExistingView(diagramIndex)); + } + } + + if( numbRelationships > 0 ) + { + + //check again: Are there relationships selected that wasn't delete (only selected relationship not source/destination table) + numbRelationships = 0; + iterator = tmpSelection->createIterator(); //getExistingDiagram(diagramIndex)->selectionFigures(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + //only way a relationship don't exists at diagram is + //it had been deleted before by deleting source/destination table that owns it + if(getExistingDiagram(diagramIndex)->includes(tmp)) + { + if(tmp->getKindId() == DDRELATIONSHIPFIGURE) + { + numbRelationships++; + } + else + { + wxMessageBox(_("Invalid figure kind found"), _("Error while deleting table"), wxCENTRE | wxICON_ERROR, getExistingView(diagramIndex)); + } + } + else + { + tmpSelection->removeItem(tmp); + } + } + delete iterator; + + while(numbRelationships > 0 && tmpSelection->count() == numbRelationships) + { + tmp = (hdIFigure *) tmpSelection->getItemAt(0); + if(tmp->getKindId() == DDRELATIONSHIPFIGURE) + { + relation = (ddRelationshipFigure *)tmp; + if(relation && answer == DD_REMOVE) + { + getExistingDiagram(diagramIndex)->removeFromSelection(relation); + getExistingDiagram(diagramIndex)->remove(relation); + } + //if relation is going to be delete all others diagrams should be alerted about it + if(relation && answer == DD_DELETE) + { + removeFromAllSelections(relation); + relation->removeForeignKeys(); + relation->disconnectEnd(); + relation->disconnectStart(); + deleteModelFigure(relation); + databaseDesign->refreshBrowser(); + } + numbRelationships--; + } + else + { + wxMessageBox(_("Invalid figure kind found"), _("Error while deleting realtionships"), wxCENTRE | wxICON_ERROR, getExistingView(diagramIndex)); + // getExistingDiagram(diagramIndex)->removeFromSelection(tmp); //isn't neither a table or relationship + } + } + } + getExistingDiagram(diagramIndex)->clearSelection(); //after delete all items all relationships remains at selection and should be removed + tmpSelection->removeAll(); + delete tmpSelection; + } +} + +void ddDrawingEditor::checkRelationshipsConsistency(int diagramIndex) +{ + hdIFigure *tmp; + ddRelationshipFigure *relation; + hdDrawing *diagram = getExistingDiagram(diagramIndex); + + // First Step Removel all orphan [relations without source or destination] relationships + // from DIAGRAM but NOT from MODEL + hdIteratorBase *iterator = diagram->figuresEnumerator(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDRELATIONSHIPFIGURE) + { + relation = (ddRelationshipFigure *)tmp; + //test if all tables of a relationship are included if this is not the case then remove relationship from this diagram + bool sourceExists = diagram->getFiguresCollection()->existsObject(relation->getStartTable()); + bool destinationExists = diagram->getFiguresCollection()->existsObject(relation->getEndTable()); + if(!sourceExists || !destinationExists) + { + diagram->remove(relation); + } + + } + } + delete iterator; + + // Now add all existing relationships in MODEL to DIAGRAM if both source and destination + // tables exists at DIAGRAM + iterator = _model->createIterator(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDRELATIONSHIPFIGURE) + { + relation = (ddRelationshipFigure *)tmp; + + //test if all tables of a relationship are included if this is the case then include relationship at this diagram + bool sourceExists = diagram->getFiguresCollection()->existsObject(relation->getStartTable()); + bool destinationExists = diagram->getFiguresCollection()->existsObject(relation->getEndTable()); + bool relationExists = diagram->getFiguresCollection()->existsObject(relation); + if(sourceExists && destinationExists && !relationExists) + { + diagram->add(relation); + relation->updateConnection(diagramIndex); + } + } + } + delete iterator; +} + +void ddDrawingEditor::checkAllDigramsRelConsistency() +{ + int i, size = modelCount(); + + for(i = 0; i < size ; i++) + { + checkRelationshipsConsistency(i); + } +} + +void ddDrawingEditor::notifyChanged() +{ + if(frm) + frm->setModelChanged(true); + modelChanged = true; +} diff --git a/dd/ddmodel/ddDrawingView.cpp b/dd/ddmodel/ddDrawingView.cpp new file mode 100644 index 0000000..0683eac --- /dev/null +++ b/dd/ddmodel/ddDrawingView.cpp @@ -0,0 +1,90 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddDrawingView.cpp - Main canvas where all tables and relationships are drawn +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "dd/ddmodel/ddDrawingView.h" +#include "hotdraw/utilities/hdArrayCollection.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/dditems/figures/ddRelationshipFigure.h" +#include "dd/dditems/utilities/ddDataType.h" +#include "dd/dditems/utilities/ddTableNameDialog.h" + +ddDrawingView::ddDrawingView(int diagram, wxWindow *ddParent, ddDrawingEditor *editor , wxSize size, hdDrawing *drawing) + : hdDrawingView(diagram, ddParent, editor, size, drawing) +{ +} + +void ddDrawingView::createViewMenu(wxMenu &mnu) +{ + mnu.Append(MNU_NEWTABLE, _("Add new Table")); +} + +void ddDrawingView::OnGenericViewPopupClick(wxCommandEvent &event) +{ + ddDrawingEditor *ed = (ddDrawingEditor *) editor(); + switch(event.GetId()) + { + case MNU_NEWTABLE: + ddTableNameDialog *newTableDialog = new ddTableNameDialog( + this, + wxEmptyString, + wxEmptyString, + NULL + ); + int answer = newTableDialog->ShowModal(); + if (answer == wxID_OK && !newTableDialog->GetValue1().IsEmpty()) + { + ddTableFigure *newTable = new ddTableFigure(newTableDialog->GetValue1(), + rand() % 90 + 200, + rand() % 90 + 140); + ed->getDesign()->addTableToView(this->getIdx(), newTable); + ed->getDesign()->refreshDraw(this->getIdx()); + } + delete newTableDialog; + break; + } +} + +ddDropTarget::ddDropTarget(ddDatabaseDesign *sourceDesign, hdDrawing *targetDrawing) +{ + target = targetDrawing; + source = sourceDesign; + +} + +bool ddDropTarget::OnDropText(wxCoord x, wxCoord y, const wxString &text) +{ + ddTableFigure *t = source->getTable(text); + if(t != NULL && !target->includes(t)) + { + target->add(t); + t->syncInternalsPosAt(target->getView()->getIdx(), x, y); + source->getEditor()->checkRelationshipsConsistency(target->getView()->getIdx()); + target->getView()->Refresh(); + return true; + } + else + { + if(target->includes(t)) + { + wxMessageBox(_("Table exists already at this diagram"), _("Drag and drop warning"), wxICON_EXCLAMATION | wxOK); + return true; + } + else + return false; + } +} diff --git a/dd/ddmodel/ddGenerationWizard.cpp b/dd/ddmodel/ddGenerationWizard.cpp new file mode 100644 index 0000000..54913fa --- /dev/null +++ b/dd/ddmodel/ddGenerationWizard.cpp @@ -0,0 +1,739 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddGenerationWizard.cpp - Wizard to allow generation of tables. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "schema/pgSchema.h" +#include "dd/ddmodel/ddGenerationWizard.h" +#include "dd/ddmodel/ddDBReverseEngineering.h" +#include "gqb/gqbGridRestTable.h" +#include "images/gqbOrderAddAll.pngc" +#include "images/gqbOrderRemoveAll.pngc" +#include "images/gqbOrderRemove.pngc" +#include "images/gqbOrderAdd.pngc" + + +#include "images/continue.pngc" + +const wxColour LIGHT_YELLOW(0xff, 0xff, 0x80); + +BEGIN_EVENT_TABLE(ddGenerationWizard, wxWizard) + EVT_WIZARD_FINISHED(wxID_ANY, ddGenerationWizard::OnFinishPressed) + EVT_WIZARD_PAGE_CHANGING(wxID_ANY, ddGenerationWizard::OnWizardPageChanging) +END_EVENT_TABLE() + +BEGIN_EVENT_TABLE(SelGenTablesPage, wxWizardPage) + EVT_BUTTON(DDREMOVE, SelGenTablesPage::OnButtonRemove) + EVT_BUTTON(DDREMOVEALL, SelGenTablesPage::OnButtonRemoveAll) + EVT_BUTTON(DDADD, SelGenTablesPage::OnButtonAdd) + EVT_BUTTON(DDADDALL, SelGenTablesPage::OnButtonAddAll) + EVT_WIZARD_PAGE_CHANGING(wxID_ANY, SelGenTablesPage::OnWizardPageChanging) +END_EVENT_TABLE() + +BEGIN_EVENT_TABLE(SelGenSchemaPage, wxWizardPage) + EVT_WIZARD_PAGE_CHANGING(wxID_ANY, SelGenSchemaPage::OnWizardPageChanging) +END_EVENT_TABLE() + +BEGIN_EVENT_TABLE(ReportGridPage, wxWizardPage) + EVT_WIZARD_PAGE_CHANGING(wxID_ANY, ReportGridPage::OnWizardPageChanging) +END_EVENT_TABLE() + +ddGenerationWizard::ddGenerationWizard(wxFrame *frame, ddDatabaseDesign *design, pgConn *connection, bool useSizer) + : wxWizard(frame, wxID_ANY, wxT("Generate DDL from model"), + wxBitmap(*continue_png_bmp), wxDefaultPosition, + wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) +{ + conn = connection; + figuresDesign = design; + + // a wizard page may be either an object of predefined class + initialPage = new wxWizardPageSimple(this); + + frontText = new wxStaticText(initialPage, wxID_ANY, + wxT("Build DDL from model tables.\n") + wxT("\n") + wxT("The next pages will allow the built of DDL of the current database designer model.") + wxT("\n\n") + wxT("Restrictions apply when using experimental function ALTER TABLE instead of DROP/CREATE:\n\n") + wxT("1. Database connection is required to check differences with existing tables.\n\n") + wxT("2. Only changes done in the design will be applied to the db, not otherwise.\n\n") + wxT("3. Rename of columns or tables is not (yet) supported.\n\n") + wxT("4. Rename of constraints generate a drop and create, except for primary key constraints.\n\n") + wxT("5. All constraints should have a defined name.\n\n") + , wxPoint(5, 5) + ); + + page2 = new SelGenTablesPage(this, initialPage); + initialPage->SetNext(page2); + page3 = new SelGenSchemaPage(this, page2); + page2->SetNext(page3); + page4 = new ReportGridPage(this, page3); + page3->SetNext(page4); + + if (useSizer) + { + // allow the wizard to size itself around the pages + GetPageAreaSizer()->Add(initialPage); + } +} + +ddGenerationWizard::~ddGenerationWizard() +{ +} + +void ddGenerationWizard::OnFinishPressed(wxWizardEvent &event) +{ + wxString strChoicesSimple[1] = {_("Create table")}; + wxString strChoicesAlter[4] = {_("Alter table"), _("Drop, then create"), _("Create table [conflict]"), wxT("No action")}; + wxArrayString tables; + wxArrayInt options; + if(page4->getGrid()->GetRows() > 0) + { + int i; + for(i = page4->getGrid()->GetRows() - 1; i >= 0; i--) + { + tables.Add(page4->getGrid()->GetCellValue(i, 0)); + wxString value = page4->getGrid()->GetCellValue(i, 1); + if(value.IsSameAs(strChoicesAlter[0])) + { + options.Add(DDGENALTER); + } + else if(value.IsSameAs(strChoicesAlter[1])) + { + options.Add(DDGENDROPCRE); + } + else if(value.IsSameAs(strChoicesAlter[2]) || value.IsSameAs(strChoicesSimple[0])) + { + options.Add(DDGENCREATE); + } + else if(value.IsSameAs(strChoicesAlter[3])) + { + options.Add(DDGENNOTHING); + } + } + } + DDL = getDesign()->generateList(tables, options, conn, schemaName); +} + +void ddGenerationWizard::OnWizardPageChanging(wxWizardEvent &event) +{ + if(event.GetDirection()) + { + page2->RefreshTablesList(); + } +} + +// ----- SelGenTablesPage Implementation + +SelGenTablesPage::SelGenTablesPage(wxWizard *parent, wxWizardPage *prev) + : wxWizardPage(parent) +{ + wparent = (ddGenerationWizard *) parent; + m_prev = prev; + m_next = NULL; + + wxFlexGridSizer *mainSizer = new wxFlexGridSizer(2, 3, 0, 0); + this->SetSizer(mainSizer); + + leftText = new wxStaticText(this, wxID_STATIC, _("Table(s) from selected schema"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER); + mainSizer->Add(leftText); + centerText = new wxStaticText(this, wxID_STATIC, _(" "), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER); + mainSizer->Add(centerText); + + rightText = new wxStaticText(this, wxID_STATIC, _("Tables(s) to be generated"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER); + mainSizer->Add(rightText, wxALIGN_LEFT); + + // Left listbox with all tables + m_allTables = new wxListBox( this, DDALLTABS, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_EXTENDED | wxLB_ALWAYS_SB | wxLB_SORT); + mainSizer->AddGrowableRow(1); + mainSizer->AddGrowableCol(0); + mainSizer->Add(m_allTables , 1, wxEXPAND); + + addBitmap = *gqbOrderAdd_png_bmp; + addAllBitmap = *gqbOrderAddAll_png_bmp; + removeBitmap = *gqbOrderRemove_png_bmp; + removeAllBitmap = *gqbOrderRemoveAll_png_bmp; + + buttonAdd = new wxBitmapButton( this, DDADD, addBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Add Column") ); + buttonAdd->SetToolTip(_("Add the selected table(s)")); + buttonAddAll = new wxBitmapButton( this, DDADDALL, addAllBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Add All Columns") ); + buttonAddAll->SetToolTip(_("Add all tables")); + buttonRemove = new wxBitmapButton( this, DDREMOVE, removeBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Remove Column") ); + buttonRemove->SetToolTip(_("Remove the selected table(s)")); + buttonRemoveAll = new wxBitmapButton( this, DDREMOVEALL, removeAllBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Remove All Columns") ); + buttonRemoveAll->SetToolTip(_("Remove all tables")); + + wxBoxSizer *buttonsSizer = new wxBoxSizer( wxVERTICAL ); + + buttonsSizer->Add( + this->buttonAdd, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 3 + + buttonsSizer->Add( + this->buttonAddAll, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 3 + + buttonsSizer->Add( + this->buttonRemove, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 3 + + buttonsSizer->Add( + this->buttonRemoveAll, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 3 + + mainSizer->Add( + buttonsSizer, + 0, // make vertically unstretchable + wxALIGN_CENTER ); // no border and centre horizontally + + //right listbox with selected tables from schema to be imported. + m_selTables = new wxListBox( this, DDSELTABS, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_EXTENDED | wxLB_ALWAYS_SB | wxLB_SORT); + mainSizer->AddGrowableCol(2); + mainSizer->Add(m_selTables , 1, wxEXPAND); + mainSizer->Fit(this); +} + +SelGenTablesPage::~SelGenTablesPage() +{ + if(rightText) + delete rightText; + if(centerText) + delete centerText; + if(leftText) + delete leftText; + if(m_allTables) + delete m_allTables; + if(m_selTables) + delete m_selTables; + if(buttonAdd) + delete buttonAdd; + if(buttonAddAll) + delete buttonAddAll; + if(buttonRemove) + delete buttonRemove; + if(buttonRemoveAll) + delete buttonRemoveAll; +} + +void SelGenTablesPage::OnButtonAdd(wxCommandEvent &) +{ + wxArrayInt positions; + if(m_allTables->GetSelections(positions) > 0) + { + int i; + int size = positions.Count(); + for(i = 0; i < size; i++) + { + m_selTables->Append(m_allTables->GetString(positions[i])); + m_allTables->Deselect(positions[i]); + } + + for(i = (size - 1); i >= 0 ; i--) + { + m_allTables->Delete(positions[i]); + } + + if(m_allTables->GetCount() > 0) + m_allTables->Select(0); + } +} + +void SelGenTablesPage::OnButtonAddAll(wxCommandEvent &) +{ + int itemsCount = m_allTables->GetCount(); + if( itemsCount > 0) + { + do + { + m_allTables->Deselect(0); + m_selTables->Append(m_allTables->GetString(0)); + m_allTables->Delete(0); + itemsCount--; + } + while(itemsCount > 0); + } +} + +void SelGenTablesPage::OnButtonRemove(wxCommandEvent &) +{ + wxArrayInt positions; + if(m_selTables->GetSelections(positions) > 0) + { + int i; + int size = positions.Count(); // Warning about conversion should be ignored + for(i = 0; i < size; i++) + { + m_allTables->Append(m_selTables->GetString(positions[i])); + m_selTables->Deselect(positions[i]); + } + + for(i = (size - 1); i >= 0 ; i--) + { + m_selTables->Delete(positions[i]); + } + + if(m_selTables->GetCount() > 0) + m_selTables->Select(0); + } +} + +void SelGenTablesPage::OnButtonRemoveAll(wxCommandEvent &) +{ + int itemsCount = m_selTables->GetCount(); + if( itemsCount > 0) + { + do + { + m_selTables->Deselect(0); + m_allTables->Append(m_selTables->GetString(0)); + m_selTables->Delete(0); + itemsCount--; + } + while(itemsCount > 0); + } +} + + +void SelGenTablesPage::moveToSelectList(wxString tableName) +{ + int position = m_allTables->FindString(tableName); + if(position != wxNOT_FOUND) + { + m_selTables->Append(m_allTables->GetString(position)); + m_allTables->Delete(position); + } +} + + +void SelGenTablesPage::RefreshTablesList() +{ + wxArrayString tablesList; + m_allTables->Clear(); + m_selTables->Clear(); + + hdIteratorBase *iterator = wparent->getDesign()->getEditor()->modelFiguresEnumerator(); + hdIFigure *tmpFigure; + ddTableFigure *table; + + while(iterator->HasNext()) + { + tmpFigure = (hdIFigure *)iterator->Next(); + if(tmpFigure->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmpFigure; + tablesList.Add(table->getTableName()); + } + } + delete iterator; + m_allTables->Set(tablesList, (void **)NULL); + + int max = wparent->preSelTables.Count(); + if(max > 0) + { + int i; + for(i = 0; i < max; i++) + { + moveToSelectList(wparent->preSelTables[i]); + } + } + +} + + +void SelGenTablesPage::OnWizardPageChanging(wxWizardEvent &event) +{ + if(event.GetDirection() && m_selTables->GetCount() <= 0) + { + wxMessageBox(_("Please select at least one table to move to next step."), _("No tables selected"), wxICON_WARNING | wxOK, this); + event.Veto(); + } +} + +// ----- SelGenSchemaPage Implementation + +SelGenSchemaPage::SelGenSchemaPage(wxWizard *parent, wxWizardPage *prev) + : wxWizardPage(parent) +{ + wparent = (ddGenerationWizard *) parent; + m_prev = prev; + m_next = NULL; + + // A top-level sizer + wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL ); + this->SetSizer(topSizer); + + //Add a message + message = new wxStaticText(this, wxID_STATIC, _("Please select a schema to use as check target.\n\nThis affects the choice between CREATE/ALTER table(s) matching for the DDL generated depending on whether or not the table exists in that schema."), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); + topSizer->Add(message); + topSizer->AddSpacer(10); + + //Get Schemas info + if(wparent && wparent->getConnection()) + refreshSchemas(wparent->getConnection()); + else + schemasNames.Add(_("No schema")); + + //Add a listbox with schemas + m_allSchemas = new wxListBox(this, DDALLSCHEMAS, wxDefaultPosition, wxDefaultSize, schemasNames, wxLB_SORT | wxLB_ALWAYS_SB | wxLB_SINGLE); + topSizer->Add(m_allSchemas, 1, wxEXPAND); +} + +SelGenSchemaPage::~SelGenSchemaPage() +{ + if(m_allSchemas) + delete m_allSchemas; + if(message) + delete message; +} + +void SelGenSchemaPage::OnWizardPageChanging(wxWizardEvent &event) +{ + if(event.GetDirection() && m_allSchemas->GetSelection() == wxNOT_FOUND) + { + wxMessageBox(_("Please select an item to move to next step."), _("No choice made"), wxICON_WARNING | wxOK, this); + event.Veto(); + } + else if(event.GetDirection()) + { + if(m_allSchemas->GetSelection() > 0) + { + wparent->OIDSelectedSchema = schemasHM[schemasNames[m_allSchemas->GetSelection()]]; + wparent->schemaName = schemasNames[m_allSchemas->GetSelection()]; + wxArrayString tables = ddImportDBUtils::getTablesNames(wparent->getConnection(), wparent->schemaName); + wparent->getDesign()->unMarkSchemaOnAll(); + wparent->getDesign()->markSchemaOn(tables); + } + else + { + wparent->OIDSelectedSchema = -1; + wparent->schemaName = _(""); + } + wparent->page4->populateGrid(); + } +} + +void SelGenSchemaPage::refreshSchemas(pgConn *connection) +{ + + schemasHM.clear(); + schemasNames.Clear(); + schemasNames.Add(wxT("Not schema selected")); + + // Search schemas and insert them + wxString restr = wxT(" WHERE ") + wxT("NOT ") + wxT("((nspname = 'pg_catalog' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'pg_class' AND relnamespace = nsp.oid LIMIT 1)) OR\n") + wxT("(nspname = 'pgagent' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'pga_job' AND relnamespace = nsp.oid LIMIT 1)) OR\n") + wxT("(nspname = 'information_schema' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'tables' AND relnamespace = nsp.oid LIMIT 1)) OR\n") + wxT("(nspname LIKE '_%' AND EXISTS (SELECT 1 FROM pg_proc WHERE proname='slonyversion' AND pronamespace = nsp.oid LIMIT 1)) OR\n") + wxT("(nspname = 'dbo' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'systables' AND relnamespace = nsp.oid LIMIT 1)) OR\n") + wxT("(nspname = 'sys' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'all_tables' AND relnamespace = nsp.oid LIMIT 1)))\n"); + + if (connection->EdbMinimumVersion(8, 2)) + { + restr += wxT(" AND nsp.nspparent = 0\n"); + // Do not show dbms_job_procedure in schemas + if (!settings->GetShowSystemObjects()) + restr += wxT("AND NOT (nspname = 'dbms_job_procedure' AND EXISTS(SELECT 1 FROM pg_proc WHERE pronamespace = nsp.oid and proname = 'run_job' LIMIT 1))\n"); + } + + wxString sql; + + if (connection->BackendMinimumVersion(8, 1)) + { + sql = wxT("SELECT CASE WHEN nspname LIKE E'pg\\\\_temp\\\\_%' THEN 1\n") + wxT(" WHEN (nspname LIKE E'pg\\\\_%') THEN 0\n"); + } + else + { + sql = wxT("SELECT CASE WHEN nspname LIKE 'pg\\\\_temp\\\\_%' THEN 1\n") + wxT(" WHEN (nspname LIKE 'pg\\\\_%') THEN 0\n"); + } + sql += wxT(" ELSE 3 END AS nsptyp, nspname, nsp.oid\n") + wxT(" FROM pg_namespace nsp\n") + + restr + + wxT(" ORDER BY 1, nspname"); + + pgSet *schemas = connection->ExecuteSet(sql); + wxTreeItemId parent; + + if (schemas) + { + while (!schemas->Eof()) + { + wxString name = schemas->GetVal(wxT("nspname")); + long nsptyp = schemas->GetLong(wxT("nsptyp")); + + wxStringTokenizer tokens(settings->GetSystemSchemas(), wxT(",")); + while (tokens.HasMoreTokens()) + { + wxRegEx regex(tokens.GetNextToken()); + if (regex.Matches(name)) + { + nsptyp = SCHEMATYP_USERSYS; + break; + } + } + + if (nsptyp <= SCHEMATYP_USERSYS && !settings->GetShowSystemObjects()) + { + schemas->MoveNext(); + continue; + } + schemasNames.Add(name); + schemasHM[name] = schemas->GetOid(wxT("oid")); + schemas->MoveNext(); + } + + delete schemas; + } +} + +// ----- SelGenSchemaPage Implementation + +ReportGridPage::ReportGridPage(wxWizard *parent, wxWizardPage *prev) + : wxWizardPage(parent) +{ + wparent = (ddGenerationWizard *) parent; + m_prev = prev; + m_next = NULL; + + // A top-level sizer + wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL ); + this->SetSizer(topSizer); + + // Add a message + message = new wxStaticText(this, wxID_STATIC, _("Please check the choice for each table:"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); + topSizer->Add(message); + topSizer->AddSpacer(10); + + reportGrid = new wxDDGrid(this, DDTABSGRID); + reportGrid->SetRowLabelSize(25); + reportGrid->CreateGrid(wparent->page2->countSelTables(), 2); + populateGrid(); + topSizer->Add(reportGrid, 1, wxEXPAND); + + // Add Event + this->Connect(DDTABSGRID, wxEVT_GRID_CELL_LEFT_CLICK, (wxObjectEventFunction) (wxEventFunction) (wxGridEventFunction) &ReportGridPage::OnCellLeftClick); +} + +ReportGridPage::~ReportGridPage() +{ + +} + +void ReportGridPage::populateGrid() +{ + reportGrid->ClearGrid(); + if(reportGrid->GetNumberRows() > 0) + reportGrid->DeleteRows(0, reportGrid->GetNumberRows()); + int row , max = wparent->page2->countSelTables(); + reportGrid->InsertRows(0, max); + reportGrid->SetColLabelValue(0, _("Tables")); + reportGrid->SetColLabelValue(1, _("Select an action")); + wxString strChoicesSimple[1] = {_("Create table")}; + wxString strChoicesAlter[4] = {_("Alter table"), _("Drop, then create"), _("Create table [conflict]"), wxT("No action")}; + + //Two Steps process first for tables that belongs to a schema (need alter table) + //Later for normal tables (just create table) + int useRow = 0; + for(row = 0; row < max; row++) + { + ddTableFigure *table = wparent->getDesign()->getTable(wparent->page2->getSelTableName(row)); + if(table != NULL && table->getBelongsToSchema()) + { + wxString labelString = wxString::Format(wxT("%i"), (row + 1)); + reportGrid->SetRowLabelValue(row, labelString); + reportGrid->SetReadOnly( row, 0, true); + reportGrid->SetCellValue( row, 0, wparent->page2->getSelTableName(row)); + reportGrid->SetCellRenderer(row, 1, new wxGridCellComboBoxRenderer); + reportGrid->SetCellEditor(row, 1, new dxGridCellSizedChoiceEditor(WXSIZEOF(strChoicesAlter), strChoicesAlter)); + reportGrid->SetCellValue( row, 1, _("Alter table")); + reportGrid->SetCellBackgroundColour(row, 0, LIGHT_YELLOW); + reportGrid->SetCellBackgroundColour(row, 1, LIGHT_YELLOW); + useRow++; + } + else if(table == NULL) + { + wxMessageBox(_("Metadata of table to be generated not found at database designer model"), _("Error at generation process"), wxICON_ERROR | wxOK); + return; + } + } + + // Normal tables (just create table) + for(row = 0; row < max; row++) + { + ddTableFigure *table = wparent->getDesign()->getTable(wparent->page2->getSelTableName(row)); + if(table != NULL && !table->getBelongsToSchema()) + { + reportGrid->SetCellValue( row, 0, wparent->page2->getSelTableName(row)); + reportGrid->SetCellRenderer(row, 1, new wxGridCellComboBoxRenderer); + reportGrid->SetCellEditor(row, 1, new dxGridCellSizedChoiceEditor(WXSIZEOF(strChoicesSimple), strChoicesSimple)); + reportGrid->SetCellValue( row, 1, _("Create table")); + useRow++; + } + else if(table == NULL) + { + wxMessageBox(_("Metadata of table to be generated not found at database designer model"), _("Error importing at generation process"), wxICON_ERROR | wxOK); + return; + } + + } + + reportGrid->AutoSizeColumns(); + reportGrid->Fit(); + +} + +void ReportGridPage::OnWizardPageChanging(wxWizardEvent &event) +{ + if(!event.GetDirection()) + { + //Reset tables after a warning + int answer = wxMessageBox(_("Going back to \"Select schema\" page will reinitialize all selections.\nDo you want to continue?"), _("Going back?"), wxYES_NO | wxCANCEL, this); + if (answer != wxYES) + { + event.Veto(); + } + } +} + +void ReportGridPage::OnCellLeftClick(wxGridEvent &event) +{ + // Only show editor y case of column 1 + if(event.GetCol() == 1) + { + reportGrid->ComboBoxEvent(event); + } + + event.Skip(); +} + + +// +// -- Special version of wxGrid to allow use of fast comboboxes and grid columns auto fit +// +wxDDGrid::wxDDGrid(wxWindow *parent, wxWindowID id): + wxGrid(parent, id, wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxTE_BESTWRAP, wxT("")), + m_selTemp(NULL), keepFit(1) +{ + // Initially all columns have s-factor=1 + for( unsigned i = 0; i < 10; ++i ) sf[i] = 1; + + Connect( wxEVT_SIZE, wxSizeEventHandler( wxDDGrid::OnSizeEvt) ); + // Adjust the default row height to be more compact + wxFont font = GetLabelFont(); + int nWidth = 0; + int nHeight = 18; + GetTextExtent(wxT("W"), &nWidth, &nHeight, NULL, NULL, &font); + SetColLabelSize(nHeight + 6); + SetRowLabelSize(35); +#ifdef __WXGTK__ + SetDefaultRowSize(nHeight + 8, TRUE); +#else + SetDefaultRowSize(nHeight + 4, TRUE); +#endif +} + +void wxDDGrid::ComboBoxEvent(wxGridEvent &event) +{ + + // This forces the cell to go into edit mode directly + this->m_waitForSlowClick = TRUE; + int row = event.GetRow(); + int col = event.GetCol(); + + this->SetGridCursor(row, col); + + // Store the click co-ordinates in the editor if possible + // if an editor has created a ClientData area, we presume it's + // a wxPoint and we store the click co-ordinates + wxGridCellEditor *pEditor = this->GetCellEditor(event.GetRow(), event.GetCol()); + wxPoint *pClickPoint = (wxPoint *)pEditor->GetClientData(); + if (pClickPoint) + { + *pClickPoint = this->ClientToScreen(event.GetPosition()); +#ifndef __WINDOWS__ + EnableCellEditControl(true); +#endif + } + + // hack to prevent selection from being lost when click combobox + if (this->IsInSelection(event.GetRow(), event.GetCol())) + { + this->m_selTemp = this->m_selection; + this->m_selection = NULL; + } + pEditor->DecRef(); +} + +void wxDDGrid::RevertSel() +{ + if (m_selTemp) + { + wxASSERT(m_selection == NULL); + m_selection = m_selTemp; + m_selTemp = NULL; + } +} + +void wxDDGrid::OnSizeEvt( wxSizeEvent &ev ) +{ + if( !StretchIt() ) ev.Skip(); +} + +int wxDDGrid::StretchIt() +{ + int new_width = GetClientSize().GetWidth() - GetRowLabelSize() - 10; + int fixedWidth = 0, numStretches = 0, numStretched = 0; + + for( int i = 0; i < GetNumberCols(); ++i ) + { + if( sf[i] == 0 ) fixedWidth += GetColSize(i); + else if( sf[i] < 0 ) + { + AutoSizeColumn(i, false); + fixedWidth += GetColSize(i); + } + else + { + numStretches += sf[i]; + numStretched += 1; + } + } + + // Now either we have space for normal layout or resort to wxGrid default behaviour + if( numStretched && ((fixedWidth + numStretched * 10) < new_width) ) + { + int stretchSpace = (new_width - fixedWidth) / numStretches; + //BeginBatch(); + int i, max = GetNumberCols(); + for(i = 0; i < max; ++i ) + if( sf[i] > 0 ) + SetColSize(i, stretchSpace * sf[i]); + //EndBatch(); + return 1; + } + return 0; +} diff --git a/dd/ddmodel/ddModelBrowser.cpp b/dd/ddmodel/ddModelBrowser.cpp new file mode 100644 index 0000000..f2d838e --- /dev/null +++ b/dd/ddmodel/ddModelBrowser.cpp @@ -0,0 +1,114 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddModelBrowser.cpp - Tables Tree of Database Designer. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "dd/ddmodel/ddModelBrowser.h" +#include "dd/ddmodel/ddDatabaseDesign.h" +#include "dd/ddmodel/ddBrowserDataContainer.h" + +// Images +#include "images/table-sm.pngc" +#include "images/database-sm.pngc" + + +BEGIN_EVENT_TABLE(ddModelBrowser, wxTreeCtrl) + EVT_TREE_ITEM_ACTIVATED(DD_BROWSER, ddModelBrowser::OnItemActivated) + EVT_TREE_BEGIN_DRAG(DD_BROWSER, ddModelBrowser::OnBeginDrag) +END_EVENT_TABLE() + +ddModelBrowser::ddModelBrowser(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, ddDatabaseDesign *design) + : wxTreeCtrl(parent, id, pos, size, style) +{ + ownerDesign = design; + rootNode = (wxTreeItemId *)NULL; + createRoot(_("Database Design")); + + // Create normal images list of browser + // Remember to update enum gqbImages in ddModelBrowser.h if changing the images!! + imageList = new wxImageList(16, 16); + imageList->Add(*database_sm_png_ico); + imageList->Add(*table_sm_png_ico); + this->AssignImageList(imageList); +} + + +// Destructor +ddModelBrowser::~ddModelBrowser() +{ + this->DeleteAllItems(); // This remove and delete data inside tree's node +} + + +// Create root node +wxTreeItemId &ddModelBrowser::createRoot(wxString Name) +{ + rootNode = this->AddRoot(Name, DD_IMG_FIG_DATABASE, DD_IMG_FIG_DATABASE); + return rootNode; +} + + +void ddModelBrowser::refreshFromModel() +{ + + this->DeleteAllItems(); + createRoot(_("Database Design")); + + hdIteratorBase *iterator = ownerDesign->getEditor()->modelFiguresEnumerator(); + hdIFigure *tmpFigure; + ddTableFigure *table; + + while(iterator->HasNext()) + { + tmpFigure = (hdIFigure *)iterator->Next(); + if(tmpFigure->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmpFigure; + this->AppendItem(rootNode, table->getTableName(), DD_IMG_FIG_TABLE, DD_IMG_FIG_TABLE, new ddBrowserDataContainer(table)); + } + } + delete iterator; + + this->Expand(rootNode); + this->SortChildren(rootNode); +} + +void ddModelBrowser::OnItemActivated(wxTreeEvent &event) +{ +} + +void ddModelBrowser::OnBeginDrag(wxTreeEvent &event) +{ + wxTreeItemId itemId = event.GetItem(); + + // Simplest solution, simulate DnD but actually don't do it + ddBrowserDataContainer *object = (ddBrowserDataContainer *) GetItemData(itemId); + + if(object != NULL && (object->getFigureKindId() == DDTABLEFIGURE)) + { + ddTableFigure *item = (ddTableFigure *) object->getFigure(); + wxString tableName = item->getTableName(); + wxTextDataObject textData(tableName); + wxDropSource dragSource(this); + dragSource.SetData(textData); + wxDragResult result = dragSource.DoDragDrop(wxDrag_CopyOnly); + if(result != wxDragCopy) + { + wxMessageBox(wxT("Invalid kind of data during drag and drop operation"), wxT("Drag and drop error"), wxICON_ERROR | wxOK); + } + } +} diff --git a/dd/ddmodel/module.mk b/dd/ddmodel/module.mk new file mode 100644 index 0000000..2438c46 --- /dev/null +++ b/dd/ddmodel/module.mk @@ -0,0 +1,22 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/dd/ddmodel/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + dd/ddmodel/ddDatabaseDesign.cpp \ + dd/ddmodel/ddDrawingEditor.cpp \ + dd/ddmodel/ddDBReverseEnginering.cpp \ + dd/ddmodel/ddModelBrowser.cpp \ + dd/ddmodel/ddGenerationWizard.cpp \ + dd/ddmodel/ddDrawingView.cpp \ + dd/ddmodel/ddBrowserDataContainer.cpp + +EXTRA_DIST += \ + dd/ddmodel/module.mk diff --git a/dd/module.mk b/dd/module.mk new file mode 100644 index 0000000..d4387ae --- /dev/null +++ b/dd/module.mk @@ -0,0 +1,17 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/dd/ Makefile fragment +# +####################################################################### + +include dd/dditems/module.mk +include dd/ddmodel/module.mk + + +EXTRA_DIST += \ + dd/module.mk diff --git a/debugger/ctlMessageWindow.cpp b/debugger/ctlMessageWindow.cpp new file mode 100644 index 0000000..5e9482b --- /dev/null +++ b/debugger/ctlMessageWindow.cpp @@ -0,0 +1,79 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlMessageWindow.cpp - debugger +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "debugger/ctlMessageWindow.h" + +IMPLEMENT_CLASS(ctlMessageWindow, wxTextCtrl) + +BEGIN_EVENT_TABLE(ctlMessageWindow, wxTextCtrl) + EVT_TIMER(wxID_ANY, ctlMessageWindow::OnTimer) +END_EVENT_TABLE() + +//////////////////////////////////////////////////////////////////////////////// +// ctlMessageWindow constructor +// +// Initialize the grid control and clear it out.... +// + +ctlMessageWindow::ctlMessageWindow(wxWindow *parent, wxWindowID id) + : wxTextCtrl(parent, wxID_ANY, wxT(""), wxPoint(0, 0), wxSize(0, 0), + wxTE_MULTILINE | wxTE_READONLY) +{ + SetFont(settings->GetSQLFont()); + m_timer.SetOwner(this); +} + +//////////////////////////////////////////////////////////////////////////////// +// AddMessage() +// +// Adds the message in the 'DBMS Messages' window. +// + +void ctlMessageWindow::AddMessage(wxString message) +{ + m_mutex.Lock(); + m_currMsg += message + wxT("\n"); + m_mutex.Unlock(); + + if (!m_timer.IsRunning()) + m_timer.Start(100, true); +} + +void ctlMessageWindow::OnTimer(wxTimerEvent &ev) +{ + m_mutex.Lock(); + AppendText(m_currMsg); + m_currMsg = wxEmptyString; + m_mutex.Unlock(); +} + +//////////////////////////////////////////////////////////////////////////////// +// delMessage() +// +// Removes the given message from the 'DBMS Messages' window. +// + +void ctlMessageWindow::DelMessage(const char *name) +{ + SetValue(wxT("")); +} + + +wxString ctlMessageWindow::GetMessage(int row) +{ + return(GetValue()); +} diff --git a/debugger/ctlResultGrid.cpp b/debugger/ctlResultGrid.cpp new file mode 100644 index 0000000..7f12677 --- /dev/null +++ b/debugger/ctlResultGrid.cpp @@ -0,0 +1,100 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlResultGrid.cpp - debugger +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "debugger/ctlResultGrid.h" + +IMPLEMENT_CLASS( ctlResultGrid, wxGrid ) + +//////////////////////////////////////////////////////////////////////////////// +// ctlResultGrid constructor +// +// We use a ctlResultGrid to display the result set from a query. This class +// is a minor extension of the wxGrid class. + +ctlResultGrid::ctlResultGrid( wxWindow *parent, wxWindowID id ) + : wxGrid( parent, id ) +{ + SetFont(settings->GetSystemFont()); + + CreateGrid( 0, 0 ); +} + +//////////////////////////////////////////////////////////////////////////////// +// fillGrid() +// +// Given a result set handle, this function copies the values in that result +// set into the grid. + +void ctlResultGrid::FillResult(pgSet *set) +{ + // Clear out the old results (if any) and resize + // grid to match the result set + if( GetNumberRows()) + DeleteRows( 0, GetNumberRows()); + if( GetNumberCols()) + DeleteCols( 0, GetNumberCols()); + + if (!set) + return; + + int rowCount = set->NumRows(); + int colCount = set->NumCols(); + + // If this PGresult represents a non-query command + // (like an INSERT), there won't be any columns in + // the result set - just return + if( colCount == 0 ) + return; + + // Disable repaints to we don't flicker too much + + BeginBatch(); + + AppendRows(rowCount); + AppendCols(colCount); + + EnableEditing(false); + + // Copy the column names from the result set into the column headers + int row = 0, + col; + for(col = 0; col < colCount; ++col) + SetColLabelValue(col, set->ColName(col)); + wxGridCellAttr* pAttr = new wxGridCellAttr; + pAttr->SetBackgroundColour(wxColour(128,128,128)); + //SetDefaultCellBackgroundColour(wxColour(128,128,128)); + + // Now copy each value from the result set into the grid + while(!set->Eof()) + { + for(col = 0; col < colCount; ++col) + { + if(set->IsNull(col)) + SetCellValue(row, col, wxT("")); + else + SetCellValue(row, col, set->GetVal(col)); + } + row++; + set->MoveNext(); + } + + // Resize each column to fit its content + AutoSizeColumns(false); + + // Enable repaints + EndBatch(); +} diff --git a/debugger/ctlStackWindow.cpp b/debugger/ctlStackWindow.cpp new file mode 100644 index 0000000..423ef36 --- /dev/null +++ b/debugger/ctlStackWindow.cpp @@ -0,0 +1,88 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlStackWindow.cpp - debugger +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "debugger/ctlStackWindow.h" + +WX_DEFINE_LIST(dbgStackFrameList); + +IMPLEMENT_CLASS(ctlStackWindow, wxListBox) + +//////////////////////////////////////////////////////////////////////////////// +// ctlStackWindow constructor +// +// Initialize the grid control and clear it out.... +// + +ctlStackWindow::ctlStackWindow(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, const wxString &name ) + : wxListBox(parent , id, pos, size, 0, NULL, style | wxLB_HSCROLL | wxLB_NEEDED_SB ) +{ + SetFont(settings->GetSystemFont()); +} + +//////////////////////////////////////////////////////////////////////////////// +// ClearStack() +// +// Remove all stack frames from the display +// +void ctlStackWindow::ClearStack() +{ + Set(0, NULL); +} + +//////////////////////////////////////////////////////////////////////////////// +// SetStack() +// +// Add an array of stack frames to the display +// +void ctlStackWindow::SetStack(const dbgStackFrameList &stacks, int selected) +{ + Set(0, NULL); + + for (dbgStackFrameList::Node *node = stacks.GetFirst(); node; + node = node->GetNext()) + { + dbgStackFrame *frame = node->GetData(); + Append(frame->GetDescription(), (wxClientData *)frame); + } + if (selected != -1) + { + SetSelection(selected); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// SelectFrame() +// +// Select the frame based on the input function and package +// +void ctlStackWindow::SelectFrame(const wxString &pkg, const wxString &func) +{ + int cnt = GetCount(); + + for (int idx = 0; idx < cnt; idx++) + { + dbgStackFrame *frame = (dbgStackFrame *)GetClientObject(idx); + + if (frame && frame->GetFunction() == func && frame->GetPackage() == pkg) + { + SetSelection(idx); + + return; + } + } +} diff --git a/debugger/ctlTabWindow.cpp b/debugger/ctlTabWindow.cpp new file mode 100644 index 0000000..19f3967 --- /dev/null +++ b/debugger/ctlTabWindow.cpp @@ -0,0 +1,175 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlTabWindow.cpp - debugger +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "ctl/ctlAuiNotebook.h" +#include "debugger/ctlTabWindow.h" +#include "debugger/dbgConst.h" + + +IMPLEMENT_CLASS(ctlTabWindow, wxWindow) + +//////////////////////////////////////////////////////////////////////////////// +// ctlTabWindow constructor +// +// This constructor creates a new notebook (a tab control) and clears out the +// rest of the data members. +// +ctlTabWindow::ctlTabWindow(wxWindow *parent, wxWindowID id, const wxPoint &pos, + const wxSize &size, long style, const wxString &name) + : ctlAuiNotebook(parent, id, pos, size, style), + m_resultWindow(NULL), + m_varWindow(NULL), + m_pkgVarWindow(NULL), + m_stackWindow(NULL), + m_paramWindow(NULL), + m_messageWindow(NULL) +{ + SetFont(settings->GetSystemFont()); + m_tabMap = new wsTabHash(); +} + +void ctlTabWindow::SelectTab(wxWindowID id) +{ + wsTabHash::iterator result = m_tabMap->find(id); + + if (result != m_tabMap->end()) + { + SetSelection(result->second); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// GetResultWindow() +// +// This function returns a pointer to our child result window (m_resultWindow) +// and creates that window when we first need it. +// +ctlResultGrid *ctlTabWindow::GetResultWindow() +{ + if (m_resultWindow == 0) + { + // We don't have a result window yet - go ahead and create one + + m_resultWindow = new ctlResultGrid(this, -1); + AddPage(m_resultWindow, _("Results"), true); + } + + return m_resultWindow; +} + +//////////////////////////////////////////////////////////////////////////////// +// GetVarWindow() +// +// This function returns a pointer to our child 'local-variables' window +// (m_varWindow) and creates that window when we first need it. +// +ctlVarWindow *ctlTabWindow::GetVarWindow(bool _create) +{ + if ((m_varWindow == NULL) && _create) + { + // We don't have a variable window yet - go ahead and create one + + (*m_tabMap)[ID_VARGRID] = GetPageCount(); + + m_varWindow = new ctlVarWindow(this, ID_VARGRID); + AddPage(m_varWindow, _("Local Variables"), true); + } + + return m_varWindow; +} + +//////////////////////////////////////////////////////////////////////////////// +// GetPkgVarWindow() +// +// This function returns a pointer to our child 'package-variables' window +// (m_varWindow) and creates that window when we first need it. +// +ctlVarWindow *ctlTabWindow::GetPkgVarWindow(bool create) +{ + if ((m_pkgVarWindow == NULL) && create) + { + // We don't have a variable window yet - go ahead and create one + + (*m_tabMap)[ID_PKGVARGRID] = GetPageCount(); + + m_pkgVarWindow = new ctlVarWindow(this, ID_PKGVARGRID); + AddPage(m_pkgVarWindow, _("Package Variables"), true); + } + + return m_pkgVarWindow; +} + +//////////////////////////////////////////////////////////////////////////////// +// GetParamWindow() +// +// This function returns a pointer to our child 'parameters' window +// (m_paramWindow) and creates that window when we first need it. +// +ctlVarWindow *ctlTabWindow::GetParamWindow(bool create) +{ + if ((m_paramWindow == NULL) && create) + { + // We don't have a variable window yet - go ahead and create one + + (*m_tabMap)[ID_PARAMGRID] = GetPageCount(); + + m_paramWindow = new ctlVarWindow(this, ID_PARAMGRID); + AddPage(m_paramWindow, _("Parameters"), true); + } + + return m_paramWindow; +} + +//////////////////////////////////////////////////////////////////////////////// +// GetMessageWindow() +// +// This function returns a pointer to our child 'messages' window +// (m_messageWindow) and creates that window when we first need it. +// +ctlMessageWindow *ctlTabWindow::GetMessageWindow() +{ + if (m_messageWindow == 0) + { + // We don't have a variable window yet - go ahead and create one + + (*m_tabMap)[ID_MSG_PAGE] = GetPageCount(); + + m_messageWindow = new ctlMessageWindow(this, ID_MSG_PAGE); + AddPage(m_messageWindow, _("DBMS Messages"), true); + } + return m_messageWindow; +} + +//////////////////////////////////////////////////////////////////////////////// +// GetStackWindow() +// +// This function returns a pointer to our child stack-trace window +// (m_stackWindow) and creates that window when we first need it. +// +ctlStackWindow *ctlTabWindow::GetStackWindow() +{ + if (m_stackWindow == 0) + { + // We don't have a stack-trace window yet - go ahead and create one + m_stackWindow = new ctlStackWindow(this, -1); + AddPage(m_stackWindow, _("Stack"), true); + } + + return m_stackWindow; +} + diff --git a/debugger/ctlVarWindow.cpp b/debugger/ctlVarWindow.cpp new file mode 100644 index 0000000..1865b78 --- /dev/null +++ b/debugger/ctlVarWindow.cpp @@ -0,0 +1,182 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlVarWindow.cpp - debugger +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "debugger/ctlVarWindow.h" + +IMPLEMENT_CLASS(ctlVarWindow, wxGrid) + +//////////////////////////////////////////////////////////////////////////////// +// ctlVarWindow constructor +// +// Initialize the grid control and clear it out.... +// +ctlVarWindow::ctlVarWindow(wxWindow *parent, wxWindowID id) + : wxGrid(parent, id), + m_cells(NULL), + m_nameFont(GetDefaultCellFont()) +{ + SetFont(settings->GetSystemFont()); + + // Create the grid control + CreateGrid(0, 0); + SetRowLabelSize(0); // Turn off the row labels + + // Set up three columns: name, value, and data type + AppendCols(3); + SetColLabelValue(COL_NAME, _("Name")); + SetColLabelValue(COL_TYPE, _("Type")); + SetColLabelValue(COL_VALUE, _("Value")); + + EnableDragGridSize(true); + + // EDB wants to hide certain PL variables. To do that, we + // keep a hash of hidden names and a hash of hidden types... + m_hiddenNames.insert(wxT("found")); + m_hiddenNames.insert(wxT("rowcount")); + m_hiddenNames.insert(wxT("sqlcode")); + m_hiddenNames.insert(wxT("sqlerrm")); + m_hiddenNames.insert(wxT("_found")); + m_hiddenNames.insert(wxT("_rowcount")); + m_hiddenNames.insert(wxT("sqlstate")); + + m_hiddenTypes.insert(wxT("refcursor")); + +} + +//////////////////////////////////////////////////////////////////////////////// +// AddVar() +// +// Adds (or updates) the given variable in the 'local variables' window. If +// we find a variabled named 'name' in the window, we simply update the value, +// otherwise, we create a new entry in the grid +// +void ctlVarWindow::AddVar(wxString name, wxString value, wxString type, bool readOnly) +{ + // If this is a 'hidden' variable, just ignore it + + if (m_hiddenNames.find(name) != m_hiddenNames.end()) + return; + + if (m_hiddenTypes.find(type) != m_hiddenTypes.end()) + return; + + if (m_cells == NULL) + { + // This is the first variable we're adding to this grid, + // layout the grid and set the column headers. + + m_cells = new wsCellHash; + } + + // Try to find an existing grid cell for this variable... + wxString key(name); + + wsCellHash::iterator cell = m_cells->find(key); + + if (cell == m_cells->end()) + { + // Can't find this variable in the grid, go ahead and add it + + gridCell newCell; + + newCell.m_row = m_cells->size(); + newCell.m_type = type; + newCell.m_value = value; + + AppendRows(1); + + SetRowLabelValue(newCell.m_row, key); + + SetCellValue(newCell.m_row, COL_NAME, key); + SetCellValue(newCell.m_row, COL_TYPE, type); + SetCellValue(newCell.m_row, COL_VALUE, value); + + SetCellFont(newCell.m_row, COL_NAME, m_nameFont); + + SetReadOnly(newCell.m_row, COL_NAME, true); + SetReadOnly(newCell.m_row, COL_TYPE, true); + SetReadOnly(newCell.m_row, COL_VALUE, readOnly); + + (*m_cells)[key] = newCell; + } + else + { + // This variable is already in the grid, update the value + // and hilite it so the user knows that it has changed. + + cell->second.m_value = value; + + if (GetCellValue(cell->second.m_row, COL_VALUE).IsSameAs(value)) + SetCellTextColour(cell->second.m_row, COL_VALUE, *wxBLACK); + else + SetCellTextColour(cell->second.m_row, COL_VALUE, *wxRED); + + SetCellValue(cell->second.m_row, COL_VALUE, value); + + // FIXME: why is this part conditional? + // FIXME: why do we need this code? can the type ever change? + + if (GetCellValue(cell->second.m_row, COL_TYPE) == wxT("")) + { + SetCellValue(cell->second.m_row, COL_TYPE, type); + } + } + + // AutoSizeColumns(false); +} + +//////////////////////////////////////////////////////////////////////////////// +// delVar() +// +// Removes the given variable from the 'local variables' window. +// + +void ctlVarWindow::DelVar(wxString name) +{ + if (name.IsEmpty()) + { + delete m_cells; + m_cells = NULL; + + if (GetNumberRows()) + DeleteRows(0, GetNumberRows()); + } + else + { + for (int row = 0; row < GetNumberRows(); row++) + { + if (GetCellValue(row, COL_NAME) == name) + { + DeleteRows(row, 1); + break; + } + } + } +} + + +wxString ctlVarWindow::GetVarName(int row) +{ + return(GetCellValue(row, COL_NAME)); + +} + +wxString ctlVarWindow::GetVarValue(int row) +{ + return(GetCellValue(row, COL_VALUE)); +} diff --git a/debugger/dbgBreakPoint.cpp b/debugger/dbgBreakPoint.cpp new file mode 100644 index 0000000..a611350 --- /dev/null +++ b/debugger/dbgBreakPoint.cpp @@ -0,0 +1,23 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dbgBreakPoint.cpp - debugger +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "debugger/dbgBreakPoint.h" + +WX_DEFINE_LIST( dbgBreakPointList ); + + diff --git a/debugger/dbgController.cpp b/debugger/dbgController.cpp new file mode 100644 index 0000000..d9f6d37 --- /dev/null +++ b/debugger/dbgController.cpp @@ -0,0 +1,913 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dbgController.cpp - debugger controller +// - Flow and data controller for the debugger +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +#include "ctl/ctlAuiNotebook.h" +#include "db/pgConn.h" +#include "db/pgQueryThread.h" +#include "db/pgQueryResultEvent.h" +#include "schema/pgObject.h" +#include "schema/pgTrigger.h" +#include "debugger/dbgConst.h" +#include "debugger/dbgBreakPoint.h" +#include "debugger/dbgController.h" +#include "debugger/dbgModel.h" +#include "debugger/ctlStackWindow.h" +#include "debugger/ctlMessageWindow.h" +#include "debugger/ctlTabWindow.h" +#include "debugger/frmDebugger.h" +#include "debugger/dlgDirectDbg.h" + +#include "utils/pgDefs.h" + +#include + +#define LOG_DBG_MUTEX_LOCKING 0 + +#if LOG_DBG_MUTEX_LOCKING + +#define LOCKMUTEX(m) \ + wxPrintf(wxT("Mutex locking @ %s:%d\n"), wxString::FromAscii(__WXFUNCTION__).c_str(), __LINE__); \ + m.Lock(); \ + wxPrintf(wxT("Mutex locked @ %s:%d\n"), wxString::FromAscii(__WXFUNCTION__).c_str(), __LINE__); + +#define UNLOCKMUTEX(m) \ + wxPrintf(wxT("Mutex unlocking @ %s:%d\n"), wxString::FromAscii(__WXFUNCTION__).c_str(), __LINE__); \ + m.Unlock(); \ + wxPrintf(wxT("Mutex unlocked @ %s:%d\n"), wxString::FromAscii(__WXFUNCTION__).c_str(), __LINE__); + +#else + +#define LOCKMUTEX(m) \ + m.Lock(); + +#define UNLOCKMUTEX(m) \ + m.Unlock(); + +#endif + +const wxString dbgController::ms_cmdDebugSPLV1( + wxT("SELECT edb_oid_debug(%lu, %lu)")); +const wxString dbgController::ms_cmdDebugSPLV2( + wxT("SELECT edb_oid_debug(%lu)")); + +const wxString dbgController::ms_cmdDebugPLPGSQLV1( + wxT("SELECT plpgsql_oid_debug(%lu, %lu)")); +const wxString dbgController::ms_cmdDebugPLPGSQLV2( + wxT("SELECT plpgsql_oid_debug(%lu)")); + +const wxString dbgController::ms_cmdAttachToPort( + wxT("SELECT * FROM pldbg_attach_to_port(%s)")); +const wxString dbgController::ms_cmdWaitForBreakpointV1( + wxT("SELECT\n") + wxT(" p.pkg AS pkg, p.func AS func, p.targetName AS targetName,\n") + wxT(" p.linenumber AS linenumber, pldbg_get_source($1::INTEGER, p.pkg, p.func) AS src,\n") + wxT(" (SELECT\n") + wxT(" s.args\n") + wxT(" FROM pldbg_get_stack($1::INTEGER) s\n") + wxT(" WHERE s.func = p.func AND s.pkg = p.pkg) AS args\n") + wxT("FROM pldbg_wait_for_breakpoint($1::INTEGER) p")); +const wxString dbgController::ms_cmdWaitForBreakpointV2( + wxT("SELECT\n") + wxT(" p.func AS func, p.targetName AS targetName, \n") + wxT(" p.linenumber AS linenumber,\n") + wxT(" pldbg_get_source($1::INTEGER, p.func) AS src,\n") + wxT(" (SELECT\n") + wxT(" s.args\n") + wxT(" FROM pldbg_get_stack($1::INTEGER) s\n") + wxT(" WHERE s.func = p.func) AS args\n") + wxT("FROM pldbg_wait_for_breakpoint($1::INTEGER) p")); + +const wxString dbgController::ms_cmdGetVars( + wxT("SELECT\n") + wxT(" name, varClass, value,\n") + wxT(" pg_catalog.format_type(dtype, NULL) as dtype, isconst\n") + wxT("FROM pldbg_get_variables(%s) ORDER BY varClass")); +const wxString dbgController::ms_cmdGetStack( + wxT("SELECT * FROM pldbg_get_stack(%s) ORDER BY level")); +const wxString dbgController::ms_cmdGetBreakpoints( + wxT("SELECT * FROM pldbg_get_breakpoints(%s)")); + +const wxString dbgController::ms_cmdStepOverV1( + wxT("SELECT\n") + wxT(" p.pkg AS pkg, p.func AS func, p.targetName AS targetName,\n") + wxT(" p.linenumber AS linenumber, pldbg_get_source($1::INTEGER, p.pkg, p.func) AS src,\n") + wxT(" (SELECT\n") + wxT(" s.args\n") + wxT(" FROM pldbg_get_stack($1::INTEGER) s\n") + wxT(" WHERE s.func = p.func AND s.pkg = p.pkg) AS args\n") + wxT("FROM pldbg_step_over($1::INTEGER) p")); +const wxString dbgController::ms_cmdStepOverV2( + wxT("SELECT\n") + wxT(" p.func, p.targetName, p.linenumber,\n") + wxT(" pldbg_get_source($1::INTEGER, p.func) AS src,\n") + wxT(" (SELECT\n") + wxT(" s.args\n") + wxT(" FROM pldbg_get_stack($1::INTEGER) s\n") + wxT(" WHERE s.func = p.func) AS args\n") + wxT("FROM pldbg_step_over($1::INTEGER) p")); +const wxString dbgController::ms_cmdStepIntoV1( + wxT("SELECT\n") + wxT(" p.pkg AS pkg, p.func AS func, p.targetName AS targetName,\n") + wxT(" p.linenumber AS linenumber, pldbg_get_source($1::INTEGER, p.pkg, p.func) AS src,\n") + wxT(" (SELECT\n") + wxT(" s.args\n") + wxT(" FROM pldbg_get_stack($1::INTEGER) s\n") + wxT(" WHERE s.func = p.func AND s.pkg = p.pkg) AS args\n") + wxT("FROM pldbg_step_into($1::INTEGER) p")); +const wxString dbgController::ms_cmdStepIntoV2( + wxT("SELECT\n") + wxT(" p.func, p.targetName, p.linenumber,\n") + wxT(" pldbg_get_source($1::INTEGER, p.func) AS src,\n") + wxT(" (SELECT\n") + wxT(" s.args\n") + wxT(" FROM pldbg_get_stack($1::INTEGER) s\n") + wxT(" WHERE s.func = p.func) AS args\n") + wxT("FROM pldbg_step_into($1::INTEGER) p")); +const wxString dbgController::ms_cmdContinueV1( + wxT("SELECT\n") + wxT(" p.pkg AS pkg, p.func AS func, p.targetName AS targetName,\n") + wxT(" p.linenumber AS linenumber, pldbg_get_source($1::INTEGER, p.pkg, p.func) AS src,\n") + wxT(" (SELECT\n") + wxT(" s.args\n") + wxT(" FROM pldbg_get_stack($1::INTEGER) s\n") + wxT(" WHERE s.func = p.func AND s.pkg = p.pkg) AS args\n") + wxT("FROM pldbg_continue($1::INTEGER) p")); +const wxString dbgController::ms_cmdContinueV2( + wxT("SELECT\n") + wxT(" p.func, p.targetName, p.linenumber,\n") + wxT(" pldbg_get_source($1::INTEGER, p.func) AS src,\n") + wxT(" (SELECT\n") + wxT(" s.args\n") + wxT(" FROM pldbg_get_stack($1::INTEGER) s\n") + wxT(" WHERE s.func = p.func) AS args\n") + wxT("FROM pldbg_continue($1::INTEGER) p")); + +const wxString dbgController::ms_cmdSetBreakpointV1( + wxT("SELECT * FROM pldbg_set_breakpoint(%s,%s,%s,%d)")); +const wxString dbgController::ms_cmdSetBreakpointV2( + wxT("SELECT * FROM pldbg_set_breakpoint(%s,%s,%d)")); + +const wxString dbgController::ms_cmdClearBreakpointV1( + wxT("SELECT * FROM pldbg_drop_breakpoint(%s,%s,%s,%d)")); +const wxString dbgController::ms_cmdClearBreakpointV2( + wxT("SELECT * FROM pldbg_drop_breakpoint(%s,%s,%d)")); + +const wxString dbgController::ms_cmdSelectFrameV1( + wxT("SELECT\n") + wxT(" p.pkg AS pkg, p.func AS func, p.targetName AS targetName,\n") + wxT(" p.linenumber AS linenumber,\n") + wxT(" CASE WHEN p.func <> 0 THEN pldbg_get_source($1::INTEGER, p.func, p.pkg) ELSE '' END AS src,\n") + wxT(" (SELECT\n") + wxT(" s.args\n") + wxT(" FROM pldbg_get_stack($1::INTEGER) s\n") + wxT(" WHERE s.func = p.func AND s.pkg = p.pkg) AS args\n") + wxT("FROM pldbg_select_frame($1::INTEGER, $2::INTEGER) p")); +const wxString dbgController::ms_cmdSelectFrameV2( + wxT("SELECT\n") + wxT(" p.func AS func, p.targetName AS targetName, p.linenumber AS linenumber,\n") + wxT(" CASE WHEN p.func <> 0 THEN pldbg_get_source($1::INTEGER, p.func) ELSE '' END AS src,\n") + wxT(" (SELECT\n") + wxT(" s.args\n") + wxT(" FROM pldbg_get_stack($1::INTEGER) s\n") + wxT(" WHERE s.func = p.func) AS args\n") + wxT("FROM pldbg_select_frame($1::INTEGER, $2::INTEGER) p")); + +const wxString dbgController::ms_cmdDepositValue( + wxT("SELECT * FROM pldbg_deposit_value(%s,%s,%d,%s)")); +const wxString dbgController::ms_cmdAbortTarget( + wxT("SELECT * FROM pldbg_abort_target(%s)")); + +const wxString dbgController::ms_cmdAddBreakpointEDB( + wxT("SELECT * FROM pldbg_set_global_breakpoint(%s, %s, %s, -1, %s)")); +const wxString dbgController::ms_cmdAddBreakpointPG( + wxT("SELECT * FROM pldbg_set_global_breakpoint(%s, %s, -1, %s)")); + +const wxString dbgController::ms_cmdCreateListener( + wxT("SELECT * from pldbg_create_listener()")); +const wxString dbgController::ms_cmdWaitForTarget( + wxT("SELECT * FROM pldbg_wait_for_target(%s)")); + +const wxString dbgController::ms_cmdIsBackendRunning( + wxT("SELECT COUNT(*) FROM (SELECT pg_catalog.pg_stat_get_backend_idset() AS bid) AS s WHERE pg_catalog.pg_stat_get_backend_pid(s.bid) = '%d'::integer;")); + +dbgController::dbgController(frmMain *main, pgObject *_obj, bool _directDebugging) + : m_ver(DEBUGGER_UNKNOWN_API), m_sessionType(DBG_SESSION_TYPE_UNKNOWN), + m_lineOffset(1), m_terminated(false), m_frm(NULL), m_dbgConn(NULL), + m_dbgThread(NULL), m_execConnThread(NULL), m_model(NULL), + m_isStopping(false) +{ + // Create the connection for listening the debugger port and doing the + // debugging operations. + // i.e. + // - step in, step over, continue, fetch stack-frames, fetch variables, etc. + m_dbgConn = _obj->GetConnection()->Duplicate( + wxT("pgAdmin Debugger - Global Listener")); + + if (!m_dbgConn->IsAlive()) + { + wxLogError(_("Couldn't create a connection for the debugger")); + + delete m_dbgConn; + m_dbgConn = NULL; + + throw (std::runtime_error("Couldn't create a connection for the debugger")); + } + + m_dbgConn->ExecuteVoid(wxT("SET client_min_messages TO error")); + + if (!m_dbgConn->BackendMinimumVersion(9, 1)) + m_lineOffset = 0; + + OID target; + if (_obj->GetMetaType() == PGM_TRIGGER) + { + target = ((pgTrigger *)_obj)->GetFunctionOid(); + } + else + { + target = _obj->GetOid(); + } + + // Fetch the target information + try + { + m_model = new dbgModel((Oid)target, m_dbgConn); + } + catch (const std::runtime_error &error) + { + // Catching the runtime error thrown by dbgTargetInfo, so that we can + // delete the created connection object and then rethrow it + m_dbgConn->Close(); + delete m_dbgConn; + m_dbgConn = NULL; + + // Rethrow the error + throw error; + } + + if (m_model->GetTarget()->HasVariadic() && + m_model->GetTarget()->GetLanguage() == wxT("edbspl")) + { + wxLogError( + _("An 'edbspl' target with a variadic argument is not supported by this version of pgAdmin debugger!")); + + throw (std::runtime_error( + "Unsupported target specified!")); + } + + // Fetch the debugger version + wxString strCntProxyInfo = m_dbgConn->ExecuteScalar( + wxT("SELECT COUNT(*) FROM pg_catalog.pg_proc p\n") + wxT(" LEFT JOIN pg_catalog.pg_namespace n ON p.pronamespace = n.oid\n") + wxT("WHERE n.nspname = ANY(current_schemas(false))\n") + wxT(" AND p.proname = 'pldbg_get_proxy_info'"), false); + + if(!strCntProxyInfo.IsEmpty() && m_dbgConn->GetLastResultStatus() == PGRES_TUPLES_OK) + { + if (strCntProxyInfo == wxT("0")) + { + m_ver = DEBUGGER_V1_API; + } + wxString strVer = m_dbgConn->ExecuteScalar( + wxT("SELECT proxyapiver FROM pldbg_get_proxy_info()"), false); + + if (!strVer.IsEmpty() && m_dbgConn->GetLastResultStatus() == PGRES_TUPLES_OK) + { + long ver; + strVer.ToLong(&ver); + + switch (ver) + { + case DEBUGGER_V3_API: + case DEBUGGER_V2_API: + m_ver = (DebuggerApiVersion)ver; + break; + default: + wxLogError( + wxString::Format( + _("pgAdmin does not support this version of the debugger plugin (v:%ld)"), + ver)); + + m_dbgConn->Close(); + delete m_dbgConn; + m_dbgConn = NULL; + + delete m_model; + m_model = NULL; + + throw (std::runtime_error( + "Unsupported version of debugger plugin installed")); + break; + } + } + else + { + wxLogError( + wxString::Format( + _("Couldn't determine the debugger plugin version.\n%s"), + m_dbgConn->GetLastError().c_str())); + + m_dbgConn->Close(); + delete m_dbgConn; + m_dbgConn = NULL; + + delete m_model; + m_model = NULL; + + throw (std::runtime_error( + "Couldn't determine the debugger version (function execution error).")); + } + } + else + { + wxLogError( + wxString::Format( + _("Couldn't determine the debugger plugin version.\n%s"), + m_dbgConn->GetLastError().c_str())); + + m_dbgConn->Close(); + delete m_dbgConn; + m_dbgConn = NULL; + + delete m_model; + m_model = NULL; + + throw (std::runtime_error( + "Couldn't determine the debugger version (function check)")); + } + + // Store debugging type + if (_directDebugging) + { + m_sessionType = DBG_SESSION_TYPE_DIRECT; + m_frm = new frmDebugger( + main, this, wxString::Format( + _("Debugger - %s"), + m_model->GetTarget()->GetQualifiedName().c_str())); + } + else + { + m_sessionType = DBG_SESSION_TYPE_INCONTEXT; + m_frm = new frmDebugger( + main, this, _("Global Debugger")); + } + + if (!Start()) + m_frm->EnableToolsAndMenus(false); +} + + +dbgController::~dbgController() +{ + if (m_dbgConn) + { + m_dbgConn->Close(); + delete m_dbgConn; + m_dbgConn = NULL; + } + + if (m_model) + { + delete m_model; + m_model = NULL; + } +} + + +bool dbgController::Start() +{ + m_frm->EnableToolsAndMenus(false); + m_frm->Show(true); + + if(m_frm->GetTabWindow()->GetPageCount()) // Clearing message window, result grid, and re-setting the status message during the module re-exeuction. + { + m_frm->GetMessageWindow()->Clear(); + m_frm->GetResultWindow()->ClearGrid(); + m_frm->LaunchWaitingDialog(_("Initializing...")); + } + + if (!m_dbgConn->IsAlive()) + { + if (!m_dbgConn->Reconnect()) + { + // Unable to re-establish the connection for debugger + return false; + } + } + + LOCKMUTEX(m_dbgThreadLock); + m_dbgThread = new pgQueryThread( + m_dbgConn, this, &(dbgController::NoticeHandler), this); + m_dbgThread->SetEventOnCancellation(false); + + if (m_dbgThread->Create() != wxTHREAD_NO_ERROR) + { + delete m_dbgThread; + m_dbgThread = NULL; + UNLOCKMUTEX(m_dbgThreadLock); + + return false; + } + + m_dbgThread->Run(); + UNLOCKMUTEX(m_dbgThreadLock); + + wxTheApp->Yield(true); + + m_terminated = false; + m_isStopping = false; + + if (m_sessionType == DBG_SESSION_TYPE_DIRECT) + { + pgConn *conn = m_dbgConn->Duplicate( + wxT("pgAdmin Debugger - Target Invoker")); + + if (m_model->GetTarget()->RequireUserInput()) + { + dlgDirectDbg dlg(m_frm, this, conn); + + if (dlg.ShowModal() != wxID_OK) + { + // Close the connection for the debugging listener + m_dbgConn->Close(); + + // Close the connection for the debugging executor + conn->Close(); + delete conn; + conn = NULL; + + // Declare that execution has been cancelled + m_terminated = true; + m_frm->EnableToolsAndMenus(false); + m_frm->CloseProgressBar(); + + return false; + } + } + + m_execConnThread = new pgQueryThread( + conn, this, &(dbgController::NoticeHandler), this); + m_execConnThread->SetEventOnCancellation(false); + + if (m_execConnThread->Create() != wxTHREAD_NO_ERROR) + { + delete m_execConnThread; + m_execConnThread = NULL; + + conn->Close(); + delete conn; + conn = NULL; + + Stop(); + + return false; + } + return ExecuteTarget(); + } + else if (m_sessionType == DBG_SESSION_TYPE_INCONTEXT) + { + // TODO:: Ask for the target session and different targets + dbgBreakPointList &breakpoints = m_model->GetBreakPoints(); + + WX_CLEAR_ARRAY(breakpoints); + + dbgTargetInfo *target = m_model->GetTarget(); + breakpoints.Append(new dbgBreakPoint( + wxString::Format(wxT("%lu"), target->GetOid()), + wxString::Format(wxT("%lu"), target->GetPkgOid()))); + + LOCKMUTEX(m_dbgThreadLock); + m_dbgThread->AddQuery(ms_cmdCreateListener, NULL, (long)RESULT_ID_LISTENER_CREATED); + UNLOCKMUTEX(m_dbgThreadLock); + } + + return true; +} + + +bool dbgController::ExecuteTarget() +{ + dbgTargetInfo *target = m_model->GetTarget(); + wxString strDebugCmdPkgInitializer, strDebugCmdTarget; + + if (m_ver <= DEBUGGER_V2_API) + { + if (target->GetLanguage() == wxT("edbspl")) + { + strDebugCmdPkgInitializer = wxString::Format( + ms_cmdDebugSPLV1, target->GetPkgOid(), target->GetPkgInitOid()); + strDebugCmdTarget = wxString::Format( + ms_cmdDebugSPLV1, target->GetPkgOid(), target->GetOid()); + } + else + { + strDebugCmdPkgInitializer = wxString::Format( + ms_cmdDebugPLPGSQLV1, target->GetPkgOid(), target->GetPkgInitOid()); + strDebugCmdTarget = wxString::Format( + ms_cmdDebugPLPGSQLV1, target->GetPkgOid(), target->GetOid()); + } + } + else + { + if (target->GetLanguage() == wxT("edbspl")) + { + strDebugCmdPkgInitializer = wxString::Format( + ms_cmdDebugSPLV2, target->GetPkgInitOid()); + strDebugCmdTarget = wxString::Format(ms_cmdDebugSPLV2, target->GetOid()); + } + else + { + strDebugCmdPkgInitializer = wxString::Format( + ms_cmdDebugPLPGSQLV2, target->GetPkgInitOid()); + strDebugCmdTarget = wxString::Format(ms_cmdDebugPLPGSQLV2, target->GetOid()); + } + } + if (target->DebugPackageConstructor()) + { + m_execConnThread->AddQuery(strDebugCmdPkgInitializer); + } + m_execConnThread->AddQuery(strDebugCmdTarget); + + if (target->AddForExecution(m_execConnThread)) + { + // Start the execution thread + m_execConnThread->Run(); + } + else + { + wxLogError(_("Couldn't determine how to execute the selected target.")); + + Stop(); + + return false; + } + return true; +} + + +void dbgController::NoticeHandler(void *_arg, const char *_msg) +{ + dbgController *controller = (dbgController *)_arg; + + if (controller->m_terminated) + return; + + wxMBConv *conv = controller->m_dbgConn->GetConv(); + + wxString strMsg(_msg, *conv); + + if (strMsg.EndsWith(wxT("\n"))) + { + strMsg.RemoveLast(); + } + + if (strMsg.Find(wxT("PLDBGBREAK")) != wxNOT_FOUND) + { + // NOTICE: PLDBGBREAK 1 + wxStringTokenizer tokens(strMsg, wxT(":\n")); + + tokens.GetNextToken(); // NOTICE: + tokens.GetNextToken(); // PLDBGBREAK + + controller->m_model->GetPort() = tokens.GetNextToken(); // + + wxCommandEvent btnEvt(wxEVT_COMMAND_BUTTON_CLICKED, MENU_ID_START_DEBUGGING); + controller->AddPendingEvent(btnEvt); + } + else + { + wxCommandEvent btnEvt(wxEVT_COMMAND_BUTTON_CLICKED, MENU_ID_NOTICE_RECEIVED); + + btnEvt.SetString(strMsg); + controller->AddPendingEvent(btnEvt); + } +} + + +// Debugging actions (called from the frmDebugger) +void dbgController::ClearBreakpoint(int _lineNo) +{ + if (m_terminated || m_isStopping) + return; + + if (m_ver <= DEBUGGER_V2_API) + { + LOCKMUTEX(m_dbgThreadLock); + m_dbgThread->AddQuery( + wxString::Format( + ms_cmdClearBreakpointV1, m_model->GetSession().c_str(), + m_model->GetDisplayedPackage().c_str(), + m_model->GetDisplayedFunction().c_str(), _lineNo + 1), + NULL, (long) RESULT_ID_NEW_BREAKPOINT); + UNLOCKMUTEX(m_dbgThreadLock); + } + else + { + LOCKMUTEX(m_dbgThreadLock); + m_dbgThread->AddQuery( + wxString::Format( + ms_cmdClearBreakpointV2, m_model->GetSession().c_str(), + m_model->GetDisplayedFunction().c_str(), _lineNo + 1), + NULL, RESULT_ID_NEW_BREAKPOINT); + UNLOCKMUTEX(m_dbgThreadLock); + } +} + + +void dbgController::SetBreakpoint(int _lineNo) +{ + if (m_terminated || m_isStopping) + return; + + if (m_ver <= DEBUGGER_V2_API) + { + LOCKMUTEX(m_dbgThreadLock); + m_dbgThread->AddQuery( + wxString::Format( + ms_cmdSetBreakpointV1, m_model->GetSession().c_str(), + m_model->GetDisplayedPackage().c_str(), + m_model->GetDisplayedFunction().c_str(), _lineNo + 1), + NULL, RESULT_ID_NEW_BREAKPOINT); + UNLOCKMUTEX(m_dbgThreadLock); + } + else + { + LOCKMUTEX(m_dbgThreadLock); + m_dbgThread->AddQuery( + wxString::Format( + ms_cmdSetBreakpointV2, m_model->GetSession().c_str(), + m_model->GetDisplayedFunction().c_str(), _lineNo + 1), + NULL, RESULT_ID_NEW_BREAKPOINT); + UNLOCKMUTEX(m_dbgThreadLock); + } +} + + +void dbgController::Countinue() +{ + if (m_terminated || m_isStopping) + return; + + pgParamsArray *params = new pgParamsArray; + params->Add(new pgParam(PGOID_TYPE_INT4, &(m_model->GetSession()))); + + if (m_ver <= DEBUGGER_V2_API) + { + m_dbgThread->AddQuery(ms_cmdContinueV1, params, RESULT_ID_BREAKPOINT); + } + else + { + m_dbgThread->AddQuery(ms_cmdContinueV2, params, RESULT_ID_BREAKPOINT); + } + + // Do not allow any action at this time + m_frm->EnableToolsAndMenus(false); +} + + +void dbgController::StepOver() +{ + if (m_terminated || m_isStopping) + return; + + pgParamsArray *params = new pgParamsArray; + params->Add(new pgParam(PGOID_TYPE_INT4, &(m_model->GetSession()))); + + if (m_ver <= DEBUGGER_V2_API) + { + LOCKMUTEX(m_dbgThreadLock); + m_dbgThread->AddQuery(ms_cmdStepOverV1, params, RESULT_ID_BREAKPOINT); + UNLOCKMUTEX(m_dbgThreadLock); + } + else + { + LOCKMUTEX(m_dbgThreadLock); + m_dbgThread->AddQuery(ms_cmdStepOverV2, params, RESULT_ID_BREAKPOINT); + UNLOCKMUTEX(m_dbgThreadLock); + } + + // Do not allow any action at this time + m_frm->EnableToolsAndMenus(false); +} + + +void dbgController::StepInto() +{ + if (m_terminated || m_isStopping) + return; + + pgParamsArray *params = new pgParamsArray; + params->Add(new pgParam(PGOID_TYPE_INT4, &(m_model->GetSession()))); + + if (m_ver <= DEBUGGER_V2_API) + { + LOCKMUTEX(m_dbgThreadLock); + m_dbgThread->AddQuery(ms_cmdStepIntoV1, params, RESULT_ID_BREAKPOINT); + UNLOCKMUTEX(m_dbgThreadLock); + } + else + { + LOCKMUTEX(m_dbgThreadLock); + m_dbgThread->AddQuery(ms_cmdStepIntoV2, params, RESULT_ID_BREAKPOINT); + UNLOCKMUTEX(m_dbgThreadLock); + } + + // Do not allow any action at this time + m_frm->EnableToolsAndMenus(false); +} + + +bool dbgController::Stop() +{ + if (m_terminated) + return true; + + if (m_isStopping) + return false; + + LOCKMUTEX(m_dbgThreadLock); + + m_frm->EnableToolsAndMenus(false); + m_frm->LaunchWaitingDialog(_("Waiting for target stop execution...")); + m_isStopping = true; + + switch(m_sessionType) + { + case DBG_SESSION_TYPE_DIRECT: + { + // We must send the abort target command to the executor + // session + if (m_execConnThread) + { + if (m_execConnThread->IsRunning()) + { + // Ask the direct debugging executor to not to handle any of the error or + // result any more. + m_execConnThread->CancelExecution(); + if (m_dbgConn->GetStatus() != CONNECTION_BAD && m_model->GetSession() != wxEmptyString) + { + // And then, we will ask the backend to abort the target, so that the + // target backend will wait for any commands from debugging proxy. + pgConn *conn = m_dbgThread->GetConn(); + pgSet *set = conn->ExecuteSet( + wxString::Format(ms_cmdAbortTarget, m_model->GetSession().c_str())); + + if (set) + delete set; + + } + while (m_execConnThread && m_execConnThread->IsRunning()) + { + wxTheApp->Yield(true); + wxMilliSleep(3); + } + if (m_execConnThread) + m_execConnThread->Wait(); + } + if (m_execConnThread) + { + // We also need to deallocate the momory for the connection + pgConn *conn = m_execConnThread->GetConn(); + + delete m_execConnThread; + m_execConnThread = NULL; + + conn->Close(); + delete conn; + conn = NULL; + } + } + } + break; + default: + break; + } + + if (m_dbgThread) + { + if (m_dbgThread->IsRunning()) + { + m_dbgThread->CancelExecution(); + m_dbgThread->Wait(); + } + + delete m_dbgThread; + m_dbgThread = NULL; + } + + // Disconnect the debugger connection + m_dbgConn->Close(); + m_frm->CloseProgressBar(); + m_terminated = true; + m_isStopping = false; + + UNLOCKMUTEX(m_dbgThreadLock); + + return true; +} + + +void dbgController::DepositValue(const wxString &_name, const wxString &_val) +{ + if (m_terminated || m_isStopping) + return; + + LOCKMUTEX(m_dbgThreadLock); + m_dbgThread->AddQuery( + wxString::Format( + ms_cmdDepositValue, m_model->GetSession().c_str(), + m_dbgConn->qtDbString(_name).c_str(), -1, + m_dbgConn->qtDbString(_val).c_str()), + NULL, RESULT_ID_DEPOSIT_VALUE); + UNLOCKMUTEX(m_dbgThreadLock); +} + + +bool dbgController::SelectFrame(int _frameNo) +{ + LOCKMUTEX(m_dbgThreadLock); + if (m_terminated || m_isStopping) + { + UNLOCKMUTEX(m_dbgThreadLock); + return true; + } + + ctlStackWindow *stackWin = m_frm->GetStackWindow(); + dbgStackFrame *frame = (dbgStackFrame *)stackWin->GetClientObject(_frameNo); + + if (!frame || frame->GetFunction() == wxT("0")) + { + UNLOCKMUTEX(m_dbgThreadLock); + wxMessageBox( + _("Cannot fetch information about the anonymous block!"), + _("Invalid Stack"), wxICON_ERROR | wxOK); + return false; + } + + wxString strLevel = frame->GetLevel(); + pgParamsArray *params = new pgParamsArray; + + params->Add(new pgParam(PGOID_TYPE_INT4, &(m_model->GetSession()))); + params->Add(new pgParam(PGOID_TYPE_INT4, &strLevel)); + + if (m_ver <= DEBUGGER_V2_API) + { + m_dbgThread->AddQuery(ms_cmdSelectFrameV1, params, RESULT_ID_BREAKPOINT); + } + else + { + m_dbgThread->AddQuery(ms_cmdSelectFrameV2, params, RESULT_ID_BREAKPOINT); + } + UNLOCKMUTEX(m_dbgThreadLock); + + return true; +} + +void dbgController::UpdateBreakpoints() +{ + if (m_terminated || m_isStopping) + return; + + LOCKMUTEX(m_dbgThreadLock); + m_dbgThread->AddQuery( + wxString::Format(ms_cmdGetBreakpoints, m_model->GetSession().c_str()), + NULL, RESULT_ID_GET_BREAKPOINTS); + UNLOCKMUTEX(m_dbgThreadLock); +} + + +// Closing Debugger +bool dbgController::CloseDebugger() +{ + if (Stop()) + { + if (m_dbgConn) + { + delete m_dbgConn; + + m_dbgConn = NULL; + } + + return true; + } + return false; +} + +dbgTargetInfo *dbgController::GetTargetInfo() +{ + return m_model->GetTarget(); +} diff --git a/debugger/dbgEvents.cpp b/debugger/dbgEvents.cpp new file mode 100644 index 0000000..ed62c4d --- /dev/null +++ b/debugger/dbgEvents.cpp @@ -0,0 +1,974 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dbgEvents.cpp - debugger controller events +// - This files contains the functions related to the event handling of the +// debugger controller. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +#include "ctl/ctlAuiNotebook.h" +#include "db/pgConn.h" +#include "db/pgQueryThread.h" +#include "db/pgQueryResultEvent.h" +#include "schema/pgObject.h" +#include "debugger/dbgConst.h" +#include "debugger/dbgBreakPoint.h" +#include "debugger/dbgController.h" +#include "debugger/dbgModel.h" +#include "debugger/ctlStackWindow.h" +#include "debugger/ctlMessageWindow.h" +#include "debugger/ctlTabWindow.h" +#include "debugger/frmDebugger.h" +#include "debugger/dlgDirectDbg.h" +#include "utils/pgDefs.h" + +#define LOG_DBG_MUTEX_LOCKING 0 + +#if LOG_DBG_MUTEX_LOCKING + +#define LOCKMUTEX(m) \ + wxPrintf(wxT("Mutex locking @ %s:%d\n"), wxString::FromAscii(__WXFUNCTION__).c_str(), __LINE__); \ + m.Lock(); \ + wxPrintf(wxT("Mutex locked @ %s:%d\n"), wxString::FromAscii(__WXFUNCTION__).c_str(), __LINE__); + +#define UNLOCKMUTEX(m) \ + wxPrintf(wxT("Mutex unlocking @ %s:%d\n"), wxString::FromAscii(__WXFUNCTION__).c_str(), __LINE__); \ + m.Unlock(); \ + wxPrintf(wxT("Mutex unlocked @ %s:%d\n"), wxString::FromAscii(__WXFUNCTION__).c_str(), __LINE__); + +#else + +#define LOCKMUTEX(m) \ + m.Lock(); + +#define UNLOCKMUTEX(m) \ + m.Unlock(); + +#endif + +BEGIN_EVENT_TABLE(dbgController, wxEvtHandler) + EVT_BUTTON(MENU_ID_NOTICE_RECEIVED, dbgController::OnNoticeReceived) + EVT_BUTTON(MENU_ID_START_DEBUGGING, dbgController::OnStartDebugging) + + EVT_PGQUERYRESULT(RESULT_ID_DIRECT_TARGET_COMPLETE, dbgController::ResultTargetComplete) + EVT_PGQUERYRESULT(RESULT_ID_ATTACH_TO_PORT, dbgController::ResultPortAttach) + EVT_PGQUERYRESULT(RESULT_ID_LISTENER_CREATED, dbgController::ResultListenerCreated) + + EVT_PGQUERYRESULT(RESULT_ID_TARGET_READY, dbgController::ResultTargetReady) + + EVT_PGQUERYRESULT(RESULT_ID_DEL_BREAKPOINT, dbgController::ResultDeletedBreakpoint) + + EVT_PGQUERYRESULT(RESULT_ID_BREAKPOINT, dbgController::ResultBreakpoint) + EVT_PGQUERYRESULT(RESULT_ID_NEW_BREAKPOINT, dbgController::ResultNewBreakpoint) + EVT_PGQUERYRESULT(RESULT_ID_NEW_BREAKPOINT_WAIT, dbgController::ResultNewBreakpointWait) + + EVT_PGQUERYRESULT(RESULT_ID_GET_VARS, dbgController::ResultVarList) + EVT_PGQUERYRESULT(RESULT_ID_GET_STACK, dbgController::ResultStack) + EVT_PGQUERYRESULT(RESULT_ID_GET_BREAKPOINTS, dbgController::ResultBreakpoints) + + EVT_PGQUERYRESULT(RESULT_ID_DEPOSIT_VALUE, dbgController::ResultDepositValue) +END_EVENT_TABLE() + + +// Event functions +void dbgController::OnNoticeReceived(wxCommandEvent &_ev) +{ + m_frm->GetMessageWindow()->AddMessage(_ev.GetString()); + m_frm->GetTabWindow()->SelectTab(ID_MSG_PAGE); +} + + +void dbgController::OnStartDebugging(wxCommandEvent &_ev) +{ + LOCKMUTEX(m_dbgThreadLock); + // Do not bother to process the result, if the debugger thread is not + // running or not exists + if (m_dbgThread && m_dbgThread->IsRunning()) + { + m_dbgThread->AddQuery( + wxString::Format(ms_cmdAttachToPort, m_model->GetPort().c_str()), + NULL, RESULT_ID_ATTACH_TO_PORT); + } + UNLOCKMUTEX(m_dbgThreadLock); +} + + +void dbgController::ResultTargetComplete(pgQueryResultEvent &_ev) +{ + pgBatchQuery *qry = _ev.GetQuery(); + + m_frm->EnableToolsAndMenus(false); + m_terminated = true; + m_frm->SetStatusText(_("Debugging Completed")); + m_frm->CloseProgressBar(); + + wxTheApp->Yield(true); + + if (m_execConnThread) + { + switch(qry->ReturnCode()) + { + case pgQueryResultEvent::PGQ_CONN_LOST: + wxLogInfo( + wxString::Format( + _("Debugger(%ld): Execution of the debugging target terminated due to connection loss.\n"), + m_execConnThread->GetId())); + break; + // This is very unlikely, unless we made mistake creating the query + case pgQueryResultEvent::PGQ_STRING_INVALID: + wxLogInfo( + wxString::Format( + _("Debugger(%ld): Execution of the debugging target terminated due to empty query string.\n"), + m_execConnThread->GetId())); + break; + case pgQueryResultEvent::PGQ_ERROR_PREPARE_CALLABLE: + case pgQueryResultEvent::PGQ_ERROR_EXECUTE_CALLABLE: + case pgQueryResultEvent::PGQ_ERROR_SEND_QUERY: + case pgQueryResultEvent::PGQ_ERROR_CONSUME_INPUT: + wxLogInfo( + wxString::Format( + _("Debugger(%ld): Execution of the debugging target terminated due to execution error (%d).\n"), + m_execConnThread->GetId(), qry->ReturnCode())); + break; + case pgQueryResultEvent::PGQ_EXECUTION_CANCELLED: + m_frm->SetStatusText(_("Debugging Cancelled")); + wxLogInfo( + wxString::Format( + _("Debugger(%ld): Execution of the debugging target cancelled.\n"), + m_execConnThread->GetId())); + break; + case pgQueryResultEvent::PGQ_RESULT_ERROR: + { + wxString strErr = qry->GetErrorMessage(); + + m_frm->SetStatusText(_("Execution completed with an error.")); + wxLogInfo( + wxString::Format( + _("Debugger(%ld): Function/Procedure terminated with an error.\n%s"), + m_execConnThread->GetId(), strErr.c_str())); + + m_frm->GetMessageWindow()->AddMessage(qry->GetMessage()); + m_frm->GetMessageWindow()->SetFocus(); + } + + break; + case PGRES_FATAL_ERROR: + case PGRES_NONFATAL_ERROR: + case PGRES_BAD_RESPONSE: + { + wxString strErr = qry->GetErrorMessage(); + m_frm->SetStatusText(_("Execution completed with an error.")); + wxLogInfo( + wxString::Format( + _("Debugger(%ld): Function/Procedure terminated with an error.\n%s"), + m_execConnThread->GetId(), strErr.c_str())); + + m_frm->GetMessageWindow()->AddMessage(qry->GetMessage()); + m_frm->GetMessageWindow()->SetFocus(); + } + + break; + case PGRES_TUPLES_OK: + { + m_frm->SetStatusText(_("Execution completed.")); + pgSet *set = qry->ResultSet(); + m_frm->GetMessageWindow()->AddMessage(set->GetCommandStatus()); + + m_frm->GetResultWindow()->FillResult(set); + } + + break; + default: + m_frm->SetStatusText(_("Execution completed.")); + wxLogInfo( + wxString::Format( + _("Debugger(%ld): Execution of the debugging function/procedure completed\n"), + m_execConnThread->GetId())); + + m_frm->GetMessageWindow()->AddMessage(qry->GetMessage()); + m_frm->GetMessageWindow()->SetFocus(); + + break; + } + + if (m_execConnThread->IsRunning()) + { + m_execConnThread->CancelExecution(); + m_execConnThread->Wait(); + } + + pgConn *execConn = m_execConnThread->GetConn(); + delete m_execConnThread; + + m_execConnThread = NULL; + execConn->Close(); + delete execConn; + } + + LOCKMUTEX(m_dbgThreadLock); + pgQueryThread *oldDebugThread = m_dbgThread; + m_dbgThread = NULL; + UNLOCKMUTEX(m_dbgThreadLock); + + if (oldDebugThread) + { + oldDebugThread->CancelExecution(); + oldDebugThread->Wait(); + + delete oldDebugThread; + } + + // We won't keep the connection open, we will open it only when required + if (m_dbgConn) + m_dbgConn->Close(); + + if (m_frm) + m_frm->EnableToolsAndMenus(false); +} + + +void dbgController::ResultPortAttach(pgQueryResultEvent &_ev) +{ + pgBatchQuery *qry = _ev.GetQuery(); + + if (!HandleQuery(qry, _("Error attaching the proxy session."))) + { + return; + } + + if (qry->ReturnCode() != PGRES_TUPLES_OK) + { + Stop(); + + return; + } + + m_frm->EnableToolsAndMenus(false); + + wxString strSession = qry->ResultSet()->GetVal(0); + m_model->GetSession() = strSession; + + pgParamsArray *params = new pgParamsArray; + + params->Add(new pgParam(PGOID_TYPE_INT4, &strSession)); + + LOCKMUTEX(m_dbgThreadLock); + if (m_dbgThread && m_dbgThread->IsRunning()) + { + if (m_ver <= DEBUGGER_V2_API) + { + m_dbgThread->AddQuery(ms_cmdWaitForBreakpointV1, params, RESULT_ID_BREAKPOINT); + } + else + { + m_dbgThread->AddQuery(ms_cmdWaitForBreakpointV2, params, RESULT_ID_BREAKPOINT); + } + qry->Release(); + + // Now create any breakpoints that the user created in last execution. We + // start by asking the server to resolve the breakpoint name into an OID (or, + // a pair of OID's if the target is defined in a package). As each + // (targetInof) result arrives, we add a break-point at the resulting OID. + dbgBreakPointList breakpoints = m_model->GetBreakPoints(); + + for (dbgBreakPointList::Node *node = breakpoints.GetFirst(); node; + node = node->GetNext()) + { + dbgBreakPoint *breakpoint = node->GetData(); + /* + * In EnterpriseDB versions <= 9.1 the + * pldbg_set_global_breakpoint function took five arguments, + * the 2nd argument being the package's OID, if any. Starting + * with 9.2, the package OID argument is gone, and the function + * takes four arguments like the community version has always + * done. + */ + if (m_dbgConn->GetIsEdb() && !m_dbgConn->BackendMinimumVersion(9, 2)) + { + m_dbgThread->AddQuery( + wxString::Format( + ms_cmdSetBreakpointV1, m_model->GetSession().c_str(), + breakpoint->GetPackageOid().c_str(), + breakpoint->GetFunctionOid().c_str(), + breakpoint->GetLineNo()), + NULL, RESULT_ID_NEW_BREAKPOINT); + } + else + { + m_dbgThread->AddQuery( + wxString::Format( + ms_cmdSetBreakpointV2, m_model->GetSession().c_str(), + breakpoint->GetFunctionOid().c_str(), + breakpoint->GetLineNo()), + NULL, RESULT_ID_NEW_BREAKPOINT); + } + } + } + UNLOCKMUTEX(m_dbgThreadLock); +} + + +bool dbgController::HandleQuery(pgBatchQuery *_qry, const wxString &_err) +{ + if (!_qry) + return false; + + LOCKMUTEX(m_dbgThreadLock); + + // It is possible that we found one error, while running the previous query + // and, called Stop function from it, because of an error found. + // That may have released the debugger thread + // + // In this case, we should exit this flow gracefully instead showing any + // error + if (!m_dbgThread || !m_dbgThread->IsRunning()) + { + UNLOCKMUTEX(m_dbgThreadLock); + return false; + } + + switch(_qry->ReturnCode()) + { + case pgQueryResultEvent::PGQ_CONN_LOST: + // This is very unlikely, unless we made mistake creating the query + case pgQueryResultEvent::PGQ_STRING_INVALID: + case PGRES_EMPTY_QUERY: + case pgQueryResultEvent::PGQ_ERROR_PREPARE_CALLABLE: + case pgQueryResultEvent::PGQ_ERROR_EXECUTE_CALLABLE: + case pgQueryResultEvent::PGQ_ERROR_SEND_QUERY: + case pgQueryResultEvent::PGQ_ERROR_CONSUME_INPUT: + case pgQueryResultEvent::PGQ_RESULT_ERROR: + case PGRES_BAD_RESPONSE: + case PGRES_NONFATAL_ERROR: + case PGRES_FATAL_ERROR: + break; + + // This is unlikely, we do not generate an event, when execution is + // cancelled + case pgQueryResultEvent::PGQ_EXECUTION_CANCELLED: + break; + case PGRES_COMMAND_OK: + case PGRES_TUPLES_OK: + UNLOCKMUTEX(m_dbgThreadLock); + return true; + // Hmm - where did it come from? + // We never call a function, which results into these results + // Anyway - we will return true as we have the result + case PGRES_COPY_IN: + case PGRES_COPY_OUT: + UNLOCKMUTEX(m_dbgThreadLock); + return true; + } + + m_frm->EnableToolsAndMenus(false); + wxTheApp->Yield(true); + + if (!m_dbgConn->IsAlive()) + { + UNLOCKMUTEX(m_dbgThreadLock); + wxMessageBox( + _("Connection to the database server lost, debugging cannot continue!"), + _("Connection Lost"), wxICON_ERROR | wxOK); + } + else + { + wxString strErr; + if (!_err.IsEmpty()) + strErr = _err + wxT("\n\n"); + strErr += _qry->GetErrorMessage(); + UNLOCKMUTEX(m_dbgThreadLock); + + if (_qry->ReturnCode() == PGRES_FATAL_ERROR) + { + // We will start start listening for new in-context session, if the + // current session is closed. On which, the query/target was + // running. + // + // This allows us to have the same behaviour as the old one. + // + if (m_sessionType == DBG_SESSION_TYPE_INCONTEXT && m_currTargetPid != wxT("")) + { + // Let's check if the target pid has stopped or exited after + // successful debugging, let's move on and wait for the next + // target to hit. + wxString isTargetRunning = m_dbgConn->ExecuteScalar(wxString::Format(ms_cmdIsBackendRunning, m_currTargetPid.c_str())); + + if (isTargetRunning == wxT("0")) + { + // Reset the current backend-pid of the target + m_currTargetPid = wxT(""); + m_dbgThread->AddQuery( + wxString::Format( + ms_cmdWaitForTarget, m_model->GetSession().c_str()), + NULL, RESULT_ID_TARGET_READY); + + m_frm->LaunchWaitingDialog(); + + return false; + } + } + else + { + wxMessageBox(_("The calling connection was closed or lost."), _("Connection Lost"), wxICON_ERROR | wxOK); + } + } + else + { + wxMessageBox(strErr, _("Execution Error"), wxICON_ERROR | wxOK); + } + + wxLogQuietError(strErr); + } + + Stop(); + m_terminated = true; + + m_frm->SetStatusText(_("Debugging aborting...")); + + return false; +} + + +void dbgController::ResultBreakpoint(pgQueryResultEvent &_ev) +{ + if (m_frm) + m_frm->CloseProgressBar(); + + pgBatchQuery *qry = _ev.GetQuery(); + + if (!HandleQuery(qry, wxEmptyString)) + return; + + LOCKMUTEX(m_dbgThreadLock); + // Do not bother to process the result, if the debugger thread is not + // running or not exists + if (m_dbgThread && m_dbgThread->IsRunning()) + { + if (qry->ReturnCode() == PGRES_TUPLES_OK) + { + wxString func, + pkg = wxT("0"); + + pgSet *set = qry->ResultSet(); + + if (set->HasColumn(wxT("pkg"))) + { + pkg = set->GetVal(wxT("pkg")); + } + func = set->GetVal(wxT("func")); + + m_model->GetFocusedPackage() = pkg; + m_model->GetFocusedFunction() = func; + + int lineNo = (int)(set->GetLong(wxT("linenumber")) - 1); + + if (lineNo < 0) + lineNo = -1; + else + lineNo -= m_lineOffset; + m_model->GetCurrLineNo() = lineNo; + + wxString strSource = set->GetVal(wxT("src")); + + if (strSource.IsEmpty()) + strSource = _(""); + + dbgCachedStack src(pkg, func, set->GetVal(wxT("targetname")), + set->GetVal(wxT("args")), strSource); + + m_model->AddSource(func, src); + m_frm->DisplaySource(src); + + m_dbgThread->AddQuery( + wxString::Format(ms_cmdGetStack, m_model->GetSession().c_str()), + NULL, RESULT_ID_GET_STACK); + + m_frm->EnableToolsAndMenus(true); + } + + // Release the result-set + qry->Release(); + } + UNLOCKMUTEX(m_dbgThreadLock); +} + + +void dbgController::ResultVarList(pgQueryResultEvent &_ev) +{ + pgBatchQuery *qry = _ev.GetQuery(); + + if (!HandleQuery(qry, _("Error fetching variables."))) + return; + + LOCKMUTEX(m_dbgThreadLock); + // Do not bother to process the result, if the debugger thread is not + // running or not exists + if (m_dbgThread && m_dbgThread->IsRunning()) + { + if (qry->ReturnCode() == PGRES_TUPLES_OK) + { + ctlVarWindow *paramWin = NULL, *pkgVarWin = NULL, *varWin = NULL; + pgSet *set = qry->ResultSet(); + + while (!set->Eof()) + { + switch((char)(set->GetVal(wxT("varclass"))[0])) + { + case 'A': + { + if (paramWin == NULL) + paramWin = m_frm->GetParamWindow(true); + + paramWin->AddVar( + set->GetVal(wxT("name")), + set->GetVal(wxT("value")), + set->GetVal(wxT("dtype")), + set->GetBool(wxT("isconst"))); + + break; + } + case 'P': + { + if (pkgVarWin == NULL) + pkgVarWin = m_frm->GetPkgVarWindow(true); + + pkgVarWin->AddVar( + set->GetVal(wxT("name")), + set->GetVal(wxT("value")), + set->GetVal(wxT("dtype")), + set->GetBool(wxT("isconst"))); + + break; + } + default: + { + if (varWin == NULL) + varWin = m_frm->GetVarWindow(true); + + varWin->AddVar( + set->GetVal(wxT("name")), + set->GetVal(wxT("value")), + set->GetVal(wxT("dtype")), + set->GetBool(wxT("isconst"))); + + break; + } + } + set->MoveNext(); + } + } + + // Release the result-set + qry->Release(); + } + UNLOCKMUTEX(m_dbgThreadLock); +} + + +void dbgController::ResultStack(pgQueryResultEvent &_ev) +{ + pgBatchQuery *qry = _ev.GetQuery(); + + if (!HandleQuery(qry, _("Error fetching the call stack."))) + return; + + LOCKMUTEX(m_dbgThreadLock); + // Do not bother to process the result, if the debugger thread is not + // running or not exists + if (m_dbgThread && m_dbgThread->IsRunning()) + { + if (qry->ReturnCode() == PGRES_TUPLES_OK) + { + pgSet *set = qry->ResultSet(); + + dbgStackFrameList stacks; + ctlStackWindow *stackWin = m_frm->GetStackWindow(); + + // Fetched the stack, now fetch the break-points + m_dbgThread->AddQuery( + wxString::Format(ms_cmdGetBreakpoints, m_model->GetSession().c_str()), + NULL, RESULT_ID_GET_BREAKPOINTS); + + stackWin->ClearStack(); + + int selected = 0, + levelCol = set->ColNumber(wxT("level")), + pkgCol = set->HasColumn(wxT("pkg")) ? set->ColNumber(wxT("level")) : -1, + funCol = set->ColNumber(wxT("func")), + targetCol = set->ColNumber(wxT("targetname")), + argsCol = set->ColNumber(wxT("args")), + lineCol = set->ColNumber(wxT("linenumber")); + + while (!set->Eof()) + { + // The result set contains one tuple per frame: + // package, function, linenumber, args + dbgStackFrame *frame = new dbgStackFrame( + set->GetVal(levelCol), + pkgCol != -1 ? set->GetVal(wxT("pkg")) : wxT("0"), + set->GetVal(funCol), + wxString::Format( + wxT("%s(%s)@%s"), + set->GetVal(targetCol).c_str(), + set->GetVal(argsCol).c_str(), + set->GetVal(lineCol).c_str())); + + // Select this one in the stack window + if (frame->GetFunction() == m_model->GetDisplayedFunction() && + frame->GetPackage() == m_model->GetDisplayedPackage()) + { + selected = set->CurrentPos() - 1; + } + + stacks.Append(frame); + set->MoveNext(); + } + stackWin->SetStack(stacks, selected); + } + + // Release the result-set + qry->Release(); + } + UNLOCKMUTEX(m_dbgThreadLock); +} + + +void dbgController::ResultBreakpoints(pgQueryResultEvent &_ev) +{ + pgBatchQuery *qry = _ev.GetQuery(); + + if (!HandleQuery(qry, _("Error fetching breakpoints."))) + return; + + LOCKMUTEX(m_dbgThreadLock); + // Do not bother to process the result, if the debugger thread is not + // running or not exists + if (m_dbgThread && m_dbgThread->IsRunning()) + { + if (qry->ReturnCode() == PGRES_TUPLES_OK) + { + pgSet *set = qry->ResultSet(); + + int pkgCol = -1, funcCol = set->ColNumber(wxT("func")), + lineCol = set->ColNumber(wxT("linenumber")); + + if (set->HasColumn(wxT("pkg"))) + { + pkgCol = set->ColNumber(wxT("pkg")); + } + + m_dbgThread->AddQuery( + wxString::Format(ms_cmdGetVars, m_model->GetSession().c_str()), + NULL, RESULT_ID_GET_VARS); + + m_frm->ClearBreakpointMarkers(); + dbgBreakPointList &breakpoints = m_model->GetBreakPoints(); + WX_CLEAR_ARRAY(breakpoints); + + while (!set->Eof()) + { + // The result set contains one tuple per breakpoint: + // pkg, func, linenumber, target + // or, + // func, linenumber, target + wxString pkg = (pkgCol == -1) ? wxT("0") : set->GetVal(pkgCol); + wxString func = set->GetVal(funcCol); + int lineNumber = (int)set->GetLong(lineCol); + + // Save this break-points in break-point list + breakpoints.Append(new dbgBreakPoint(func, pkg, lineNumber)); + + // Mark the break-point in the viewer + if (pkg == m_model->GetDisplayedPackage() && + func == m_model->GetDisplayedFunction()) + { + m_frm->MarkBreakpoint(lineNumber - 1); + } + set->MoveNext(); + } + } + + // Release the result-set + qry->Release(); + } + UNLOCKMUTEX(m_dbgThreadLock); +} + + +void dbgController::ResultNewBreakpoint(pgQueryResultEvent &_ev) +{ + // We will wait for the last new break-point, which will be handled in + // dbgController::ResultNewBreakpointWait function + if (!HandleQuery(_ev.GetQuery(), _("Could not create the breakpoint."))) + return; + + LOCKMUTEX(m_dbgThreadLock); + // Do not bother to process the result, if the debugger thread is not + // running or not exists + if (m_dbgThread && m_dbgThread->IsRunning()) + { + // Release the result-set + _ev.GetQuery()->Release(); + } + UNLOCKMUTEX(m_dbgThreadLock); +} + + +void dbgController::ResultNewBreakpointWait(pgQueryResultEvent &_ev) +{ + pgBatchQuery *qry = _ev.GetQuery(); + + if (!HandleQuery(qry, _("Could not create the breakpoint."))) + return; + + LOCKMUTEX(m_dbgThreadLock); + // Do not bother to process the result, if the debugger thread is not + // running or not exists + if (m_dbgThread && m_dbgThread->IsRunning()) + { + if (qry->ReturnCode() == PGRES_TUPLES_OK) + { + pgSet *set = _ev.GetQuery()->ResultSet(); + m_frm->EnableToolsAndMenus(false); + + m_dbgThread->AddQuery( + wxString::Format( + ms_cmdWaitForTarget, m_model->GetSession().c_str()), + NULL, RESULT_ID_TARGET_READY); + + m_frm->LaunchWaitingDialog(); + } + + // Release the result-set + qry->Release(); + } + UNLOCKMUTEX(m_dbgThreadLock); +} + + +void dbgController::ResultDeletedBreakpoint(pgQueryResultEvent &_ev) +{ + pgBatchQuery *qry = _ev.GetQuery(); + + if (!HandleQuery(qry, _("Could not drop the breakpoint."))) + return; + + LOCKMUTEX(m_dbgThreadLock); + // Do not bother to process the result, if the debugger thread is not + // running or not exists + if (m_dbgThread && m_dbgThread->IsRunning()) + { + if (qry->ReturnCode() == PGRES_TUPLES_OK) + { + pgSet *set = qry->ResultSet(); + + if (set->GetBool(0)) + { + m_frm->SetStatusText(_("Breakpoint dropped")); + } + } + + // Release the result-set + qry->Release(); + } + UNLOCKMUTEX(m_dbgThreadLock); +} + + +//////////////////////////////////////////////////////////////////////////////// +// ResultDepositValue() +// +// This event handler is called when the proxy completes a 'deposit' operation +// (in response to an earlier call to pldbg_deposit_value()). +// +// We schedule a refresh of our variable window(s) for the next idle period. +// +void dbgController::ResultDepositValue(pgQueryResultEvent &_ev) +{ + pgBatchQuery *qry = _ev.GetQuery(); + + if (!HandleQuery(qry, _("Could not deposit the new value."))) + return; + + LOCKMUTEX(m_dbgThreadLock); + // Do not bother to process the result, if the debugger thread is not + // running or not exists + if (m_dbgThread && m_dbgThread->IsRunning()) + { + if (qry->ReturnCode() == PGRES_TUPLES_OK) + { + pgSet *set = qry->ResultSet(); + + if (set->GetBool(0)) + { + m_frm->SetStatusText(_("Value changed")); + + m_dbgThread->AddQuery( + wxString::Format(ms_cmdGetVars, m_model->GetSession().c_str()), + NULL, RESULT_ID_GET_VARS); + } + else + { + wxLogError(_("Could not deposit the new value.")); + } + } + + // Release the result-set + qry->Release(); + } + UNLOCKMUTEX(m_dbgThreadLock); +} + + +void dbgController::ResultListenerCreated(pgQueryResultEvent &_ev) +{ + pgBatchQuery *qry = _ev.GetQuery(); + + if (!HandleQuery(qry, + _("Could not create the proxy listener for in-process debugging."))) + return; + + LOCKMUTEX(m_dbgThreadLock); + // Do not bother to process the result, if the debugger thread is not + // running or not exists + if (m_dbgThread && m_dbgThread->IsRunning()) + { + if (qry->ReturnCode() == PGRES_TUPLES_OK) + { + pgSet *set = qry->ResultSet(); + + // We now have a global listener and a session handle. Grab the session + // handle (we'll need it for just about everything else). + m_model->GetSession() = set->GetVal(0); + + // Release the result-set + qry->Release(); + + // Now create any global breakpoints that the user requested. We start + // by asking the server to resolve the breakpoint name into an OID (or, + // a pair of OID's if the target is defined in a package). As each + // (targetInof) result arrives, we add a break-point at the resulting + // OID. + unsigned int idx = 1; + long resultId; + + dbgBreakPointList breakpoints = m_model->GetBreakPoints(); + for (dbgBreakPointList::Node *node = breakpoints.GetFirst(); node; + node = node->GetNext(), ++idx) + { + dbgBreakPoint *breakpoint = node->GetData(); + + if(idx < breakpoints.GetCount()) + { + resultId = RESULT_ID_NEW_BREAKPOINT; + } + else + { + resultId = RESULT_ID_NEW_BREAKPOINT_WAIT; + } + + /* + * In EnterpriseDB versions <= 9.1 the + * pldbg_set_global_breakpoint function took five arguments, + * the 2nd argument being the package's OID, if any. Starting + * with 9.2, the package OID argument is gone, and the function + * takes four arguments like the community version has always + * done. + */ + if (m_dbgConn->GetIsEdb() && !m_dbgConn->BackendMinimumVersion(9, 2)) + { + m_dbgThread->AddQuery( + wxString::Format( + ms_cmdAddBreakpointEDB, m_model->GetSession().c_str(), + breakpoint->GetPackageOid().c_str(), + breakpoint->GetFunctionOid().c_str(), + m_model->GetTargetPid().c_str()), + NULL, resultId); + } + else + { + m_dbgThread->AddQuery( + wxString::Format( + ms_cmdAddBreakpointPG, m_model->GetSession().c_str(), + breakpoint->GetFunctionOid().c_str(), + m_model->GetTargetPid().c_str()), + NULL, resultId); + } + } + UNLOCKMUTEX(m_dbgThreadLock); + } + else + { + // Release the result-set + qry->Release(); + UNLOCKMUTEX(m_dbgThreadLock); + } + } + else + { + UNLOCKMUTEX(m_dbgThreadLock); + } +} + + +void dbgController::ResultTargetReady(pgQueryResultEvent &_ev) +{ + pgBatchQuery *qry = _ev.GetQuery(); + + if (m_frm) + { + m_frm->CloseProgressBar(); + m_frm->EnableToolsAndMenus(false); + } + + if (!HandleQuery(qry, + _("Error fetching target information."))) + return; + + LOCKMUTEX(m_dbgThreadLock); + // Do not bother to process the result, if the debugger thread is not + // running or not exists + if (m_dbgThread && m_dbgThread->IsRunning()) + { + bool goAhead = false; + goAhead = (qry->ReturnCode() == PGRES_TUPLES_OK); + pgSet *set = qry->ResultSet(); + + // Save the current running target pid + m_currTargetPid = set->GetVal(0); + + // Next line release the actual result-set + set = NULL; + + // Release the result-set + qry->Release(); + UNLOCKMUTEX(m_dbgThreadLock); + + pgParamsArray *params = new pgParamsArray; + + params->Add(new pgParam(PGOID_TYPE_INT4, &(m_model->GetSession()))); + if (m_ver <= DEBUGGER_V2_API) + { + m_dbgThread->AddQuery(ms_cmdWaitForBreakpointV1, params, RESULT_ID_BREAKPOINT); + } + else + { + m_dbgThread->AddQuery(ms_cmdWaitForBreakpointV2, params, RESULT_ID_BREAKPOINT); + } + } + else + { + UNLOCKMUTEX(m_dbgThreadLock); + } +} diff --git a/debugger/dbgModel.cpp b/debugger/dbgModel.cpp new file mode 100644 index 0000000..a1d97ae --- /dev/null +++ b/debugger/dbgModel.cpp @@ -0,0 +1,63 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dbgModel.cpp - debugger model +// - It contains the data and information related the debugging session +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +#include "db/pgConn.h" +#include "db/pgQueryThread.h" +#include "db/pgQueryResultEvent.h" +#include "debugger/dbgModel.h" + + +dbgModel::dbgModel(Oid _target, pgConn *_conn) + : m_target(NULL), m_currLineNo(-1), m_targetPid(wxT("NULL")) +{ + m_target = new dbgTargetInfo(_target, _conn); +} + + +bool dbgModel::GetSource(const wxString &_funcOid, dbgCachedStack *_cached) +{ + dbgSourceHash::iterator match = m_sourceMap.find(_funcOid); + + if (match == m_sourceMap.end()) + return false; + else + { + if (_cached) + { + *_cached = match->second; + } + + return true; + } +} + + +void dbgModel::ClearCachedSource() +{ + m_sourceMap.clear(); + + // Put a dummy entry for invalid function OID to the cache. This is + // displayed at least for inline code blocks, as we currently have no way + // to fetch the source for those + m_sourceMap[wxT("0")] = dbgCachedStack(wxT("0"), wxT("0"), wxT(""), wxT(""), _("")); +} + + +void dbgModel::AddSource(const wxString &_funcOid, const dbgCachedStack &_source) +{ + m_sourceMap[_funcOid] = _source; +} diff --git a/debugger/dbgTargetInfo.cpp b/debugger/dbgTargetInfo.cpp new file mode 100644 index 0000000..3b33cf0 --- /dev/null +++ b/debugger/dbgTargetInfo.cpp @@ -0,0 +1,647 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dbgTargetInfo.cpp - debugger +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" +#include "utils/pgDefs.h" + +// wxWindows headers +#include + +// App headers +#include "debugger/dbgTargetInfo.h" +#include "debugger/dbgConst.h" +#include "utils/misc.h" +#include "utils/pgfeatures.h" + +#include + +//////////////////////////////////////////////////////////////////////////////// +// dbgTargetInfo constructor +// +// This class implements a container that holds information necessary to invoke +// a debugger target (a function or procedure). +// +// When the constructor is called, it sends a query to the server to retreive: +// the OID of the target, +// the name of the target, +// the name of the schema in which the target is defined +// the name of the language in which the target is defined +// the number of arguments expected by the target +// the argument names +// the argument types +// the argument modes (IN, OUT, or INOUT) +// the target type (function or procedure) +// +// This class offers a number of (inline) member functions that you can call +// to extract the above information after it's been queried from the server. + +dbgTargetInfo::dbgTargetInfo(Oid _target, pgConn *_conn) + : m_args(NULL), m_inputParamCnt(0), m_hasVariadic(false) +{ + wxMBConv *conv = _conn->GetConv(); + wxString targetQuery = + wxT("SELECT\n") + wxT(" p.proname AS name, l.lanname, p.proretset, p.prorettype, y.typname AS rettype,\n") + wxT(" CASE WHEN proallargtypes IS NOT NULL THEN\n") + wxT(" pg_catalog.array_to_string(ARRAY(\n") + wxT(" SELECT\n") + wxT(" pg_catalog.format_type(p.proallargtypes[s.i], NULL)\n") + wxT(" FROM\n") + wxT(" pg_catalog.generate_series(0, pg_catalog.array_upper(\n") + wxT(" p.proallargtypes, 1)) AS s(i)), ',')\n") + wxT(" ELSE\n") + wxT(" pg_catalog.array_to_string(ARRAY(\n") + wxT(" SELECT\n") + wxT(" pg_catalog.format_type(p.proargtypes[s.i], NULL)\n") + wxT(" FROM\n") + wxT(" pg_catalog.generate_series(0, pg_catalog.array_upper(\n") + wxT(" p.proargtypes, 1)) AS s(i)), ',')\n") + wxT(" END AS proargtypenames,\n") + wxT(" CASE WHEN proallargtypes IS NOT NULL THEN\n") + wxT(" pg_catalog.array_to_string(ARRAY(\n") + wxT(" SELECT proallargtypes[s.i] FROM\n") + wxT(" pg_catalog.generate_series(0, pg_catalog.array_upper(proallargtypes, 1)) s(i)), ',')\n") + wxT(" ELSE\n") + wxT(" pg_catalog.array_to_string(ARRAY(\n") + wxT(" SELECT proargtypes[s.i] FROM\n") + wxT(" pg_catalog.generate_series(0, pg_catalog.array_upper(proargtypes, 1)) s(i)), ',')\n") + wxT(" END AS proargtypes,\n") + wxT(" pg_catalog.array_to_string(p.proargnames, ',') AS proargnames,\n") + wxT(" pg_catalog.array_to_string(proargmodes, ',') AS proargmodes,\n"); + + if (_conn->GetIsEdb()) + { + targetQuery += + wxT(" CASE WHEN n.nspparent <> 0 THEN n.oid ELSE 0 END AS pkg,\n") + wxT(" CASE WHEN n.nspparent <> 0 THEN n.nspname ELSE '' END AS pkgname,\n") + wxT(" CASE WHEN n.nspparent <> 0 THEN (SELECT oid FROM pg_proc WHERE pronamespace=n.oid AND proname='cons') ELSE 0 END AS pkgconsoid,\n") + wxT(" CASE WHEN n.nspparent <> 0 THEN g.oid ELSE n.oid END AS schema,\n") + wxT(" CASE WHEN n.nspparent <> 0 THEN g.nspname ELSE n.nspname END AS schemaname,\n") + wxT(" NOT (l.lanname = 'edbspl' AND protype = '1') AS isfunc,\n"); + } + else + { + targetQuery += + wxT(" 0 AS pkg,\n") + wxT(" '' AS pkgname,\n") + wxT(" 0 AS pkgconsoid,\n") + wxT(" n.oid AS schema,\n") + wxT(" n.nspname AS schemaname,\n") + wxT(" true AS isfunc,\n"); + } + if (_conn->BackendMinimumVersion(8, 4)) + { + targetQuery += wxT(" pg_catalog.pg_get_function_identity_arguments(p.oid) AS signature,"); + } + else if (_conn->BackendMinimumVersion(8, 1)) + { + targetQuery += + wxT(" CASE\n") + wxT(" WHEN proallargtypes IS NOT NULL THEN pg_catalog.array_to_string(ARRAY(\n") + wxT(" SELECT\n") + wxT(" CASE\n") + wxT(" WHEN p.proargmodes[s.i] = 'i' THEN ''\n") + wxT(" WHEN p.proargmodes[s.i] = 'o' THEN 'OUT '\n") + wxT(" WHEN p.proargmodes[s.i] = 'b' THEN 'INOUT '\n") + wxT(" WHEN p.proargmodes[s.i] = 'v' THEN 'VARIADIC '\n") + wxT(" END ||\n") + wxT(" CASE WHEN COALESCE(p.proargnames[s.i], '') = '' THEN ''\n") + wxT(" ELSE p.proargnames[s.i] || ' '\n") + wxT(" END ||\n") + wxT(" pg_catalog.format_type(p.proallargtypes[s.i], NULL)\n") + wxT(" FROM\n") + wxT(" pg_catalog.generate_series(1, pg_catalog.array_upper(p.proallargtypes, 1)) AS s(i)\n") + wxT(" WHERE p.proargmodes[s.i] != 't'\n") + wxT(" ), ', ')\n") + wxT(" ELSE\n") + wxT(" pg_catalog.array_to_string(ARRAY(\n") + wxT(" SELECT\n") + wxT(" CASE\n") + wxT(" WHEN COALESCE(p.proargnames[s.i+1], '') = '' THEN ''\n") + wxT(" ELSE p.proargnames[s.i+1] || ' '\n") + wxT(" END ||\n") + wxT(" pg_catalog.format_type(p.proargtypes[s.i], NULL)\n") + wxT(" FROM\n") + wxT(" pg_catalog.generate_series(1, pg_catalog.array_upper(p.proargtypes, 1)) AS s(i)\n") + wxT(" ), ', ')\n") + wxT(" END AS signature,\n"); + } + else + { + targetQuery += wxT(" '' AS signature,"); + } + + if (_conn->HasFeature(FEATURE_FUNCTION_DEFAULTS)) + { + // EnterpriseDB 8.3R2 + if(!_conn->BackendMinimumVersion(8, 4)) + { + targetQuery += + wxT(" pg_catalog.array_to_string(ARRAY(\n") + wxT(" SELECT\n") + wxT(" CASE WHEN p.proargdefvals[x.j] != '-' THEN\n") + wxT(" pg_catalog.pg_get_expr(p.proargdefvals[x.j], 'pg_catalog.pg_class'::regclass, true)\n") + wxT(" ELSE '-' END\n") + wxT(" FROM\n") + wxT(" pg_catalog.generate_series(1, pg_catalog.array_upper(p.proargdefvals, 1)) AS x(j)\n") + wxT(" ), ',') AS proargdefaults,\n") + wxT(" CASE WHEN p.proargdefvals IS NULL THEN '0'\n") + wxT(" ELSE pg_catalog.array_upper(p.proargdefvals, 1)::text END AS pronargdefaults\n"); + } + else + { + targetQuery += + wxT(" pg_catalog.pg_get_expr(p.proargdefaults, 'pg_catalog.pg_class'::regclass, false) AS proargdefaults,\n") + wxT(" p.pronargdefaults\n"); + } + } + else + { + targetQuery += + wxT(" '' AS proargdefaults, 0 AS pronargdefaults\n"); + } + targetQuery += + wxT("FROM\n") + wxT(" pg_catalog.pg_proc p\n") + wxT(" LEFT JOIN pg_catalog.pg_namespace n ON p.pronamespace = n.oid\n") + wxT(" LEFT JOIN pg_catalog.pg_language l ON p.prolang = l.oid\n") + wxT(" LEFT JOIN pg_catalog.pg_type y ON p.prorettype = y.oid\n"); + if(_conn->GetIsEdb()) + { + targetQuery += + wxT(" LEFT JOIN pg_catalog.pg_namespace g ON n.nspparent = g.oid\n"); + } + targetQuery += + wxString::Format(wxT("WHERE p.oid = %ld"), (long)_target); + + pgSet *set = _conn->ExecuteSet(targetQuery); + + if (conv == NULL) + { + conv = &wxConvLibc; + } + + if (!set || _conn->GetLastResultStatus() != PGRES_TUPLES_OK) + { + if (set) + delete set; + wxLogError(_("Could not fetch information about the debugger target.\n") + + _conn->GetLastError()); + + throw (std::runtime_error( + (const char *)(_conn->GetLastError().c_str()))); + } + + if (set->NumRows() == 0) + { + delete set; + + wxLogError(_("Can't find the debugging target")); + throw (std::runtime_error("Can't find target!")); + } + + m_oid = _target; + m_name = set->GetVal(wxT("name")); + m_schema = set->GetVal(wxT("schemaname")); + m_package = set->GetVal(wxT("pkgname")); + m_language = set->GetVal(wxT("lanname")); + m_returnType = set->GetVal(wxT("rettype")); + m_funcSignature = set->GetVal(wxT("signature")); + m_isFunction = set->GetBool(wxT("isfunc")); + m_returnsSet = set->GetBool(wxT("proretset")); + m_pkgOid = set->GetOid(wxT("pkg")); + m_pkgInitOid = set->GetOid(wxT("pkgconsoid")); + m_schemaOid = set->GetOid(wxT("schema")); + m_fqName = qtIdent(m_schema) + wxT(".") + + (m_pkgOid == 0 ? wxT("") : (qtIdent(m_package) + wxT("."))) + qtIdent(m_name); + + wxArrayString argModes, argNames, argTypes, argTypeOids, argDefVals, + argBaseTypes; + + // Fetch Argument Modes (if available) + if (!set->IsNull(set->ColNumber(wxT("proargmodes")))) + { + wxString tmp; + tmp = set->GetVal(wxT("proargmodes")); + + if (!tmp.IsEmpty()) + getArrayFromCommaSeparatedList(tmp, argModes); + } + // Fetch Argument Names (if available) + if (!set->IsNull(set->ColNumber(wxT("proargnames")))) + { + wxString tmp; + tmp = set->GetVal(wxT("proargnames")); + + if (!tmp.IsEmpty()) + getArrayFromCommaSeparatedList(tmp, argNames); + } + // Fetch Argument Type-Names (if available) + if (!set->IsNull(set->ColNumber(wxT("proargtypenames")))) + { + wxString tmp; + tmp = set->GetVal(wxT("proargtypenames")); + + if (!tmp.IsEmpty()) + getArrayFromCommaSeparatedList(tmp, argTypes); + } + // Fetch Argument Type-Names (if available) + if (!set->IsNull(set->ColNumber(wxT("proargtypes")))) + { + wxString tmp; + tmp = set->GetVal(wxT("proargtypes")); + if (!tmp.IsEmpty()) + getArrayFromCommaSeparatedList(tmp, argTypeOids); + } + + size_t nArgDefs = (size_t)set->GetLong(wxT("pronargdefaults")); + // Fetch Argument Default Values (if available) + if (!set->IsNull(set->ColNumber(wxT("proargdefaults"))) && nArgDefs != 0) + { + wxString tmp; + tmp = set->GetVal(wxT("proargdefaults")); + + if (!tmp.IsEmpty()) + getArrayFromCommaSeparatedList(tmp, argDefVals); + } + + wxString argName, argDefVal; + short argMode; + Oid argTypeOid; + size_t argCnt = argTypes.Count(); + + // This function/procedure does not take any arguments + if (argCnt == 0) + { + return; + } + + size_t idx = 0; + m_args = new pgDbgArgs(); + + for (; idx < argCnt; idx++) + { + argTypeOid = (Oid)strtoul(argTypeOids[idx].mb_str(wxConvUTF8), 0, 10); + argDefVal = wxEmptyString; + + argName = wxEmptyString; + if (idx < argNames.Count()) + argName = argNames[idx]; + + if (argName.IsEmpty()) + argName.Printf( wxT( "dbgParam%d" ), (idx + 1)); + + if (idx < argModes.Count()) + { + wxString tmp = argModes[idx]; + switch ((char)(tmp.c_str())[0]) + { + case 'i': + argMode = pgParam::PG_PARAM_IN; + m_inputParamCnt++; + break; + case 'b': + m_inputParamCnt++; + argMode = pgParam::PG_PARAM_INOUT; + break; + case 'o': + argMode = pgParam::PG_PARAM_OUT; + break; + case 'v': + m_inputParamCnt++; + argMode = pgParam::PG_PARAM_VARIADIC; + m_hasVariadic = true; + break; + case 't': + continue; + default: + m_inputParamCnt++; + argMode = pgParam::PG_PARAM_IN; + break; + } + } + else + { + m_inputParamCnt++; + argMode = pgParam::PG_PARAM_IN; + } + + // In EDBAS 90, if an SPL-function has both an OUT-parameter + // and a return value (which is not possible on PostgreSQL otherwise), + // the return value is transformed into an extra OUT-parameter + // named "_retval_" + if (argName == wxT("_retval_") && _conn->EdbMinimumVersion(9, 0)) + { + // this will be the return type for this object + m_returnType = argTypes[idx]; + + continue; + } + + m_args->Add(new dbgArgInfo(argName, argTypes[idx], argTypeOid, argMode)); + } + + if (m_args->GetCount() == 0) + { + delete m_args; + m_args = NULL; + + return; + } + + if (nArgDefs != 0) + { + argCnt = m_args->GetCount(); + + // Set the default as the value for the argument + for (idx = argCnt - 1;; idx--) + { + dbgArgInfo *arg = (dbgArgInfo *)((*m_args)[idx]); + + if (arg->GetMode() == pgParam::PG_PARAM_INOUT || + arg->GetMode() == pgParam::PG_PARAM_IN) + { + nArgDefs--; + + if (argDefVals[nArgDefs] != wxT("-")) + { + arg->SetDefault(argDefVals[nArgDefs]); + } + + if (nArgDefs == 0) + { + break; + } + } + if (idx == 0) + break; + } + } +} + +//////////////////////////////////////////////////////////////////////////////// +// operator[] +// +// This operator function makes it easy to index into the m_args array +// using concise syntax. +dbgArgInfo *dbgTargetInfo::operator[](int index) +{ + if (m_args == NULL) + return (dbgArgInfo *)NULL; + + if (index < 0 || index >= (int)m_args->GetCount()) + return (dbgArgInfo *)NULL; + + return (dbgArgInfo *)((*m_args)[index]); +} + +dbgArgInfo::dbgArgInfo(const wxString &_name, const wxString &_type, Oid _typeOid, + short _mode) + : m_name(_name), m_type(_type), m_typeOid(_typeOid), m_mode(_mode), + m_hasDefault(false), m_useDefault(false), m_null(false) +{ + if (!_type.EndsWith(wxT("[]"), &m_baseType)) + { + m_baseType = wxEmptyString; + } +} + + +pgParam *dbgArgInfo::GetParam(wxMBConv *_conv) +{ + return new pgParam(m_typeOid, + (m_null ? (wxString *)NULL : &m_val), + _conv, m_mode); +} + +bool dbgTargetInfo::AddForExecution(pgQueryThread *_thread) +{ + wxASSERT(_thread != NULL); + + if (_thread == NULL) + return false; + + pgConn *conn = _thread->GetConn(); + + pgParamsArray *params = NULL; + wxString strQuery; + bool useCallable = false; + + // Basically - we can call the function/target three ways: + // 1. If it is a edbspl procedure, we can use callable statement + // 2. If the database server is of type EnterpriseDB, and + // function/procedure is type 'edbspl', we should use the anonymous + // function block for: + // a. Version < 9.0 + // b. Package function/procedure + // 3. Otherwise, we should use the simple function call (except using EXEC + // for the procedure in 'edbspl' instead of using SELECT) + if (_thread->SupportCallableStatement() && + m_language == wxT("edbspl") && + !m_isFunction) + { + useCallable = true; + strQuery = wxT("CALL ") + m_fqName + wxT("("); + + if (m_args) + { + params = new pgParamsArray(); + wxMBConv *conv = conn->GetConv(); + + for(int idx = 0; idx < (int)m_args->GetCount(); idx++) + { + params->Add(((*m_args)[idx])->GetParam(conv)); + + if (idx != 0) + strQuery += wxT(", "); + strQuery += wxString::Format(wxT("$%d::"), idx + 1) + + ((*m_args)[idx])->GetTypeName(); + } + } + strQuery += wxT(")"); + } + else if (conn->GetIsEdb() && !conn->BackendMinimumVersion(9, 3)) + { + wxString strDeclare, strStatement, strResult; + bool useAnonymousBlock = false; + + if (m_language == wxT("edbspl")) + { + useAnonymousBlock = true; + if (!m_isFunction) + { + strStatement = wxT("\tEXEC ") + m_fqName; + } + else if (m_returnType == wxT("void") || m_returnsSet || + !conn->BackendMinimumVersion(8, 4)) + { + strStatement = wxT("\tPERFORM ") + m_fqName; + } + else + { + wxString resultVar = wxT("v_retVal"); + strStatement = wxT("\t") + resultVar + wxT(" := ") + m_fqName; + strDeclare.Append(wxT("\t")) + .Append(resultVar) + .Append(wxT(" ")) + .Append(m_returnType) + .Append(wxT(";\n")); + strResult = wxT("\tDBMS_OUTPUT.PUT_LINE(E'\\n\\nResult:\\n--------\\n' || ") + + resultVar + + wxT("::text || E'\\n\\nNOTE: This is the result generated during the function execution by the debugger.\\n');\n"); + } + } + else + { + if (m_returnType == wxT("record")) + { + strStatement = wxT("\tSELECT ") + m_fqName; + } + else + { + strStatement = wxT("\tSELECT * FROM ") + m_fqName; + } + } + + if (m_args && m_args->GetCount() > 0) + { + strStatement.Append(wxT("(")); + + for(int idx = 0, firstProcessed = false; idx < (int)m_args->GetCount(); idx++) + { + dbgArgInfo *arg = (*m_args)[idx]; + + if (!conn->EdbMinimumVersion(8, 4) && + arg->GetMode() == pgParam::PG_PARAM_OUT && + (!m_isFunction || m_language == wxT("edbspl"))) + { + if (firstProcessed) + strStatement.Append(wxT(", ")); + firstProcessed = true; + + strStatement.Append(wxT("NULL::")).Append(arg->GetTypeName()); + } + else if (conn->EdbMinimumVersion(8, 4) && useAnonymousBlock && + (arg->GetMode() == pgParam::PG_PARAM_OUT || + arg->GetMode() == pgParam::PG_PARAM_INOUT)) + { + wxString strParam = wxString::Format(wxT("p_param%d"), idx); + + strDeclare.Append(wxT("\t")) + .Append(strParam) + .Append(wxT(" ")) + .Append(arg->GetTypeName()); + + if (arg->GetMode() == pgParam::PG_PARAM_INOUT) + { + strDeclare.Append(wxT(" := ")) + .Append(arg->Null() ? wxT("NULL") : conn->qtDbString(arg->Value())) + .Append(wxT("::")) + .Append(arg->GetTypeName()); + } + strDeclare.Append(wxT(";\n")); + + if (firstProcessed) + strStatement.Append(wxT(", ")); + firstProcessed = true; + + strStatement.Append(strParam); + } + else if (arg->GetMode() != pgParam::PG_PARAM_OUT) + { + if (firstProcessed) + strStatement.Append(wxT(", ")); + firstProcessed = true; + + if (arg->GetMode() == pgParam::PG_PARAM_VARIADIC) + strStatement += wxT("VARIADIC "); + + strStatement + .Append(arg->Null() ? wxT("NULL") : conn->qtDbString(arg->Value())) + .Append(wxT("::")) + .Append(arg->GetTypeName()); + } + } + strStatement.Append(wxT(")")); + strQuery = strStatement; + } + else if (!m_isFunction && m_language == wxT("edbspl")) + { + strQuery = strStatement; + } + else + { + strQuery = strStatement.Append(wxT("()")); + } + if (useAnonymousBlock) + { + strQuery = wxT("DECLARE\n") + + strDeclare + wxT("BEGIN\n") + strStatement + wxT(";\n") + strResult + wxT("END;"); + } + } + else + { + if (!m_isFunction) + { + strQuery = wxT("EXEC ") + m_fqName + wxT("("); + } + else if (m_returnType == wxT("record")) + { + strQuery = wxT("SELECT ") + m_fqName + wxT("("); + } + else + { + strQuery = wxT("SELECT * FROM ") + m_fqName + wxT("("); + } + + if (m_args) + { + params = new pgParamsArray(); + wxMBConv *conv = conn->GetConv(); + unsigned int noInParams = 0; + + for(int idx = 0; idx < (int)m_args->GetCount(); idx++) + { + dbgArgInfo *arg = (*m_args)[idx]; + + if (arg->GetMode() != pgParam::PG_PARAM_OUT) + { + params->Add(arg->GetParam(conv)); + + if (noInParams != 0) + strQuery += wxT(", "); + + if (arg->GetMode() == pgParam::PG_PARAM_VARIADIC) + strQuery += wxT("VARIADIC "); + + noInParams++; + strQuery += wxString::Format(wxT("$%d::"), noInParams) + + ((*m_args)[idx])->GetTypeName(); + } + } + + /* + * The function may not have IN/IN OUT/VARIADIC arguments, but only + * OUT one(s). + */ + if (params->GetCount() == 0) + { + delete params; + params = NULL; + } + } + strQuery += wxT(")"); + } + + _thread->AddQuery(strQuery, params, RESULT_ID_DIRECT_TARGET_COMPLETE, NULL, useCallable); + + return true; +} diff --git a/debugger/debugger.cpp b/debugger/debugger.cpp new file mode 100644 index 0000000..e5c5e7c --- /dev/null +++ b/debugger/debugger.cpp @@ -0,0 +1,273 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// debugger.cpp - Debugger factories +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "frm/frmMain.h" +#include "debugger/debugger.h" +#include "debugger/dbgController.h" +#include "schema/pgFunction.h" +#include "schema/pgTrigger.h" +#include "schema/edbPackageFunction.h" + +#include + +/////////////////////////////////////////////////// +// Debugger factory +/////////////////////////////////////////////////// +debuggerFactory::debuggerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, _("&Debug"), _("Debug the selected object")); +} + +wxWindow *debuggerFactory::StartDialog(frmMain *form, pgObject *obj) +{ + // Check here to make sure the function still exists before proceeding. + // There is still a very small window in which it might be dropped, but + // that will be handled by a cache lookup failure error in the database + // We also make sure the function name doesn't contain a : as that will + // sent the debugger API nuts. + pgSet *res = obj->GetConnection()->ExecuteSet(wxT("SELECT proname FROM pg_proc WHERE oid = ") + NumToStr((long)obj->GetOid())); + + if (res->NumRows() != 1) + { + wxLogError(_("The selected function could not be found.")); + ctlTree *browser = form->GetBrowser(); + wxTreeItemId item = browser->GetSelection(); + if (obj == browser->GetObject(item)) + { + form->Refresh(obj); + } + delete res; + return (wxWindow *)NULL; + } + + if (res->GetVal(wxT("proname")).Contains(wxT(":"))) + { + wxLogError(_("Functions with a colon in the name cannot be debugged.")); + delete res; + return (wxWindow *)NULL; + } + try + { + new dbgController(form, obj, true); + } + catch (const std::runtime_error &) + { + // just ignore this errors, we already logged them in native messages to + // the end-user + } + delete res; + return (wxWindow *)NULL; +} + +bool debuggerFactory::CheckEnable(pgObject *obj) +{ + if (!obj) + return false; + + // Can't debug catalog objects. + if (obj->GetSchema() && obj->GetSchema()->GetMetaType() == PGM_CATALOG) + return false; + + // Must be a super user or object owner to create breakpoints of any kind. + if (!obj->GetServer() || !(obj->GetServer()->GetSuperUser() || obj->GetServer()->GetUsername() == obj->GetOwner())) + return false; + + // EnterpriseDB 8.3 or earlier does not support debugging by the non-superuser + if (!obj->GetServer()->GetSuperUser() && !obj->GetConnection()->EdbMinimumVersion(8, 4) && obj->GetConnection()->GetIsEdb()) + return false; + + if (!obj->IsCollection()) + { + switch (obj->GetMetaType()) + { + case PGM_FUNCTION: + { + pgFunction *func = (pgFunction *)obj; + + // If this is an EDB wrapped function, no debugging allowed + if (obj->GetConnection()->GetIsEdb() && func->GetSource().Trim(false).StartsWith(wxT("$__EDBwrapped__$"))) + return false; + + if (func->GetReturnType() != wxT("trigger") && + func->GetReturnType() != wxT("\"trigger\"")) + { + if (func->GetLanguage() == wxT("plpgsql") && + obj->GetDatabase()->CanDebugPlpgsql()) + return true; + else if (func->GetLanguage() == wxT("edbspl") && + obj->GetDatabase()->CanDebugEdbspl()) + return true; + else + return false; + } + else + return false; + } + break; + + case EDB_PACKAGEFUNCTION: + if (obj->GetDatabase()->GetConnection()->EdbMinimumVersion(8, 2) && + obj->GetDatabase()->CanDebugEdbspl() && + obj->GetName() != wxT("cons") && + ((edbPackageFunction *)obj)->GetSource() != wxEmptyString && + (!((edbPackageFunction *)obj)->GetSource().Trim(false).StartsWith(wxT("$__EDBwrapped__$")))) + return true; + break; + + default: + break; + } + } + return false; +} + +/////////////////////////////////////////////////// +// Breakpoint factory +/////////////////////////////////////////////////// +breakpointFactory::breakpointFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, _("&Set breakpoint"), _("Set a breakpoint on the selected object")); +} + +wxWindow *breakpointFactory::StartDialog(frmMain *form, pgObject *obj) +{ + wxString dbgOid; + if (obj->GetMetaType() == PGM_TRIGGER) + dbgOid = NumToStr((long)((pgTrigger *)obj)->GetFunctionOid()); + else + dbgOid = NumToStr((long)obj->GetOid()); + + // Check here to make sure the function still exists before proceeding. + // There is still a very small window in which it might be dropped, but + // we should be able to handle most cases here without having to do this + // deep down in query threads. + // We also make sure the function name doesn't contain a : as that will + // sent the debugger API nuts. + pgSet *res = obj->GetConnection()->ExecuteSet( + wxT("SELECT count(*) AS count, proname FROM pg_proc WHERE oid = ") + dbgOid + wxT(" GROUP BY proname")); + if (res->GetVal(wxT("proname")).Contains(wxT(":"))) + { + wxLogError(_("Functions with a colon in the name cannot be debugged.")); + delete res; + return (wxWindow *)NULL; + } + + if (res->GetLong(wxT("count")) != 1) + { + wxLogError(_("The selected function could not be found.")); + + ctlTree *browser = form->GetBrowser(); + wxTreeItemId item = browser->GetSelection(); + if (obj == browser->GetObject(item)) + { + pgCollection *coll = browser->GetParentCollection(obj->GetId()); + browser->DeleteChildren(coll->GetId()); + coll->ShowTreeDetail(browser); + } + delete res; + return (wxWindow *)NULL; + } + + try + { + new dbgController(form, obj, false); + } + catch (const std::runtime_error &) + { + // just ignore this errors, we already logged them in native messages to + // the end-user + } + + delete res; + return (wxWindow *)NULL; +} + +bool breakpointFactory::CheckEnable(pgObject *obj) +{ + if (!obj) + return false; + + // Can't debug catalog objects. + if (obj->GetSchema() && obj->GetSchema()->GetMetaType() == PGM_CATALOG) + return false; + + // Must be a super user to create breakpoints of any kind. + if (!obj->GetServer() || !obj->GetServer()->GetSuperUser()) + return false; + + if (!obj->IsCollection()) + { + switch (obj->GetMetaType()) + { + case PGM_FUNCTION: + { + pgFunction *func = (pgFunction *)obj; + + // If this is an EDB wrapped function, no debugging allowed + if (obj->GetConnection()->GetIsEdb() && + func->GetSource().Trim(false).StartsWith(wxT("$__EDBwrapped__$"))) + return false; + + if (func->GetLanguage() == wxT("plpgsql") && + obj->GetDatabase()->CanDebugPlpgsql()) + return true; + else if (func->GetLanguage() == wxT("edbspl") && + obj->GetDatabase()->CanDebugEdbspl()) + return true; + else + return false; + } + break; + + case EDB_PACKAGEFUNCTION: + if (obj->GetDatabase()->GetConnection()->EdbMinimumVersion(8, 2) && + obj->GetDatabase()->CanDebugEdbspl() && + obj->GetName() != wxT("cons") && + ((edbPackageFunction *)obj)->GetSource() != wxEmptyString && + (!((edbPackageFunction *)obj)->GetSource().Trim(false).StartsWith(wxT("$__EDBwrapped__$")))) + return true; + break; + + case PGM_TRIGGER: + { + pgTrigger *trig = (pgTrigger *)obj; + + // If this is an EDB wrapped function, no debugging allowed + if (obj->GetConnection()->GetIsEdb() && + trig->GetSource().Trim(false).StartsWith(wxT("$__EDBwrapped__$"))) + return false; + + if (trig->GetLanguage() == wxT("plpgsql") && + obj->GetDatabase()->CanDebugPlpgsql()) + return true; + else if (trig->GetLanguage() == wxT("edbspl") && + obj->GetDatabase()->CanDebugEdbspl()) + return true; + else + return false; + } + break; + + default: + break; + } + } + return false; +} + + + + diff --git a/debugger/dlgDirectDbg.cpp b/debugger/dlgDirectDbg.cpp new file mode 100644 index 0000000..40d9e2b --- /dev/null +++ b/debugger/dlgDirectDbg.cpp @@ -0,0 +1,1073 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgDirectDbg.cpp - debugger +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "ctl/ctlAuiNotebook.h" +#include "db/pgConn.h" +#include "db/pgQueryThread.h" +#include "db/pgQueryResultEvent.h" +#include "schema/pgObject.h" +#include "debugger/dbgConst.h" +#include "debugger/dbgBreakPoint.h" +#include "debugger/dbgController.h" +#include "debugger/dbgModel.h" +#include "debugger/ctlStackWindow.h" +#include "debugger/ctlMessageWindow.h" +#include "debugger/ctlTabWindow.h" +#include "debugger/frmDebugger.h" +#include "debugger/dlgDirectDbg.h" + +#include "images/debugger.pngc" + +#define lblMessage CTRL_STATIC("lblMessage") +#define grdParams CTRL("grdParams", wxGrid) +#define chkPkgInit CTRL_CHECKBOX("chkPkgInit") +#define btnDebug CTRL_BUTTON("wxID_OK") + +IMPLEMENT_CLASS(dlgDirectDbg, pgDialog) + +BEGIN_EVENT_TABLE(dlgDirectDbg, pgDialog) + EVT_BUTTON(wxID_OK, dlgDirectDbg::OnOk) + EVT_BUTTON(wxID_CANCEL, dlgDirectDbg::OnCancel) + EVT_GRID_CMD_LABEL_LEFT_CLICK(XRCID("grdParams"), dlgDirectDbg::OnClickGridLabel) + EVT_MENU(RESULT_ID_ARGS_UPDATED, dlgDirectDbg::ResultArgsUpdated) + EVT_MENU(RESULT_ID_ARGS_UPDATE_ERROR, dlgDirectDbg::ResultArgsUpdateError) +END_EVENT_TABLE() + + +//////////////////////////////////////////////////////////////////////////////// +// dlgDirectDbg constructor +// +// This class implements 'direct-debugging'. In direct-debugging, the user +// provides a function signature, procedure signature, or OID on the command +// line (this identifies the debug target). We query the server for the +// names, types, and in/out modes for each target parameter and then prompt +// the user to enter a value for each of the IN (and IN/OUT) parameters. +// +// When the user fills in the parameter values and clicks OK, we set a +// breakpoint at the target and then execute a SELECT statement or an +// EXEC statement that invokes the target (with the parameter values +// provided by the user). + +dlgDirectDbg::dlgDirectDbg(frmDebugger *_parent, dbgController *_controller, + pgConn *_conn) + : m_controller(_controller), m_thread(NULL), m_conn(_conn) +{ + int width, height, totalWidth = 0; + + SetFont(settings->GetSystemFont()); + LoadResource(_parent, wxT("dlgDirectDbg")); + + // Icon + SetIcon(*debugger_png_ico); + RestorePosition(); + + grdParams->SetRowLabelSize(wxGRID_AUTOSIZE); + grdParams->SetColLabelSize(20); + grdParams->AutoSizeColumns(true); + + chkPkgInit->SetValue(false); + + PopulateParamGrid(); + + LoadSettings(); + + for(int i = 0; i < grdParams->GetNumberCols(); i++) + grdParams->AutoSizeColumn(i, true); + + if (grdParams->GetNumberCols() > 1) + { + // Extend grid to it's parent width + grdParams->GetClientSize(&width, &height); + for (int i = 0; i < grdParams->GetNumberCols(); i++) + { + totalWidth += grdParams->GetColumnWidth(i); + } + // Total client width - total six column widths - the first (an empty) column + // width + grdParams->SetColumnWidth(COL_DEF_VAL, width - totalWidth - 100); + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// PopulateParamGrid() +// +// This function reads parameter descriptions from m_targetInfo and adds a +// new row to the grid control for each IN (or IN/OUT, VARAIADIC) parameter. +// Each row displays the parameter name, the data type, and an entry box +// where the user can type in a value for that parameter +// +void dlgDirectDbg::PopulateParamGrid() +{ + pgDbgArgs *args = m_controller->GetTargetInfo()->GetArgs(); + + // If the target is defined within package, offer the user + // a chance to debug the initializer (there may or may not + // be an initializer, we don't really know at this point) + if(m_controller->GetTargetInfo()->GetPkgOid() == 0) + chkPkgInit->Disable(); + else + chkPkgInit->Enable(); + + if (!args) + { + grdParams->CreateGrid(0, 1); + grdParams->SetColLabelValue(COL_NAME, _("No arguments required")); + grdParams->SetColSize(0, 350); + + return; + } + + // Add seven columns to the grid control: + // - Name, Type, NULL?, EXPR?, Value, Default?, And Default Value + grdParams->CreateGrid(0, 7); + + grdParams->SetColLabelValue(COL_NAME, _("Name")); + grdParams->SetColLabelValue(COL_TYPE, _("Type")); + grdParams->SetColLabelValue(COL_NULL, _("Null?")); + grdParams->SetColLabelValue(COL_EXPR, _("Expression?")); + grdParams->SetColLabelValue(COL_VALUE, _("Value")); + grdParams->SetColLabelValue(COL_USE_DEF, _("Use default?")); + grdParams->SetColLabelValue(COL_DEF_VAL, _("Default Value")); + + size_t idx = 0; + + for(size_t pIdx = 0; pIdx < args->Count(); pIdx++) + { + dbgArgInfo *arg = (*args)[pIdx]; + + // If this is an IN parameter (or an IN/OUT parameter), add + // a new row to the grid + if(arg->GetMode() != pgParam::PG_PARAM_OUT) + { + grdParams->AppendRows(1); + grdParams->SetCellValue(idx, COL_NAME, arg->GetName()); + + // Make it obvious which are variadics + if (arg->GetMode() != pgParam::PG_PARAM_VARIADIC) + { + grdParams->SetRowLabelValue(idx, wxEmptyString); + grdParams->SetCellValue(idx, COL_TYPE, arg->GetTypeName()); + + if (!arg->IsArray()) + { + // Is the value an expression? + grdParams->SetCellEditor(idx, COL_EXPR, new ctlGridCellBoolEditor()); + grdParams->SetCellRenderer(idx, COL_EXPR, new wxGridCellBoolRenderer()); + grdParams->SetCellValue(idx, COL_EXPR, wxT("")); + } + else + { + grdParams->SetCellBackgroundColour(idx, COL_EXPR, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(idx, COL_VALUE, wxColour(235, 235, 235, 90)); + } + + // Use the default value? + grdParams->SetCellRenderer(idx, COL_USE_DEF, new wxGridCellBoolRenderer()); + grdParams->SetCellEditor(idx, COL_USE_DEF, new ctlGridCellBoolEditor()); + } + else + { + grdParams->SetCellValue(idx, COL_TYPE, wxT("VARIADIC ") + arg->GetTypeName()); + grdParams->SetRowLabelValue(idx, wxEmptyString); + + grdParams->AppendRows(1); + grdParams->SetRowLabelValue(idx + 1, wxT("+")); + grdParams->SetCellValue(idx + 1, COL_NAME, _("Click '+/-' to add/remove value to variadic")); + + grdParams->SetCellBackgroundColour(idx + 1, COL_EXPR, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(idx + 1, COL_VALUE, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(idx + 1, COL_USE_DEF, wxColour(235, 235, 235, 90)); + } + + // Set value to NULL? + grdParams->SetCellEditor(idx, COL_NULL, new ctlGridCellBoolEditor(arg)); + grdParams->SetCellRenderer(idx, COL_NULL, new wxGridCellBoolRenderer()); + grdParams->SetCellValue(idx, COL_NULL, wxT("")); + + if (arg->HasDefault()) + { + // Whenever the default value is available, use that by default + grdParams->SetCellValue(idx, COL_USE_DEF, wxT("1")); + grdParams->SetCellValue(idx, COL_DEF_VAL, arg->Default()); + + // When "Use Defalut?" is enabled, disable VALUE, NULL? and + // EXPR? columns + grdParams->SetReadOnly(idx, COL_USE_DEF, false); + grdParams->SetReadOnly(idx, COL_VALUE, false); + grdParams->SetReadOnly(idx, COL_EXPR, false); + } + else + { + grdParams->SetCellValue(idx, COL_USE_DEF, wxT("")); + grdParams->SetCellValue(idx, COL_DEF_VAL, _("")); + + // When default value is not available, we should ask the user + // to enter them + grdParams->SetReadOnly(idx, COL_USE_DEF, true); + grdParams->SetReadOnly(idx, COL_VALUE, arg->IsArray()); + grdParams->SetReadOnly(idx, COL_EXPR, arg->IsArray()); + + grdParams->SetCellBackgroundColour(idx, COL_USE_DEF, wxColour(235, 235, 235, 90)); + if (arg->IsArray()) + { + grdParams->SetCellBackgroundColour(idx, COL_VALUE, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(idx, COL_EXPR, wxColour(235, 235, 235, 90)); + } + } + + grdParams->SetReadOnly(idx, COL_NULL, false); + grdParams->SetReadOnly(idx, COL_NAME, true); + grdParams->SetReadOnly(idx, COL_TYPE, true); + grdParams->SetReadOnly(idx, COL_DEF_VAL, true); + grdParams->SetCellBackgroundColour(idx, COL_NAME, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(idx, COL_TYPE, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(idx, COL_DEF_VAL, wxColour(235, 235, 235, 90)); + + idx++; + + if (arg->GetMode() != pgParam::PG_PARAM_VARIADIC && + arg->IsArray()) + { + grdParams->AppendRows(1); + + grdParams->SetRowLabelValue(idx, wxT("+")); + grdParams->SetCellValue(idx, COL_NAME, _("Click '+/-' to add/remove value to the array")); + + grdParams->SetReadOnly(idx, COL_NAME, true); + grdParams->SetReadOnly(idx, COL_TYPE, true); + grdParams->SetReadOnly(idx, COL_NULL, true); + grdParams->SetReadOnly(idx, COL_EXPR, true); + grdParams->SetReadOnly(idx, COL_VALUE, true); + grdParams->SetReadOnly(idx, COL_USE_DEF, true); + grdParams->SetReadOnly(idx, COL_DEF_VAL, true); + + grdParams->SetCellBackgroundColour(idx, COL_NAME, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(idx, COL_TYPE, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(idx, COL_NULL, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(idx, COL_EXPR, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(idx, COL_VALUE, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(idx, COL_USE_DEF, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(idx, COL_DEF_VAL, wxColour(235, 235, 235, 90)); + + idx++; + } + } + } + + // Move the cursor to the first value (so that the user + // can just start typing) + + grdParams->SetGridCursor(0, COL_VALUE); + grdParams->SetFocus(); +} + +void dlgDirectDbg::LoadLastCellSetting(int row_number, int parameter_index, + int index_array_bound, bool isArray) +{ + wxString lastValue, valKey; + dbgTargetInfo *target = m_controller->GetTargetInfo(); + long num; + + settings->Read(wxT("Debugger/Proc/OID"), &num, -1L); + if(num != target->GetOid()) + { + return; + } + else + { + if(!isArray) + { + // Non array elements cell index is 0 + valKey = wxString::Format(wxT("Debugger/Proc/%d/0/"), parameter_index); + settings->Read(valKey + wxT("VAL"), &lastValue, wxEmptyString); + grdParams->SetCellValue(row_number, COL_VALUE, lastValue); + } + else + { + long arrCnt; + + settings->Read( + wxString::Format( + wxT("Debugger/Proc/%d/"), parameter_index) + + wxT("ArrCnt"), &arrCnt, 0L); + + // Refresh an entire array element + for( int i = 0; i <= index_array_bound && i <= arrCnt - 1; i++ ) + { + valKey = wxString::Format(wxT("Debugger/Proc/%d/%d/"), parameter_index, i); + settings->Read(valKey + wxT("VAL"), &lastValue, wxEmptyString); + grdParams->SetCellValue(row_number - index_array_bound + i, COL_VALUE, + lastValue); + } + } + } + +} + +//////////////////////////////////////////////////////////////////////////////// +// LoadSettings() +// +// Loads default values from our .ini file. We save the OID of the most +// recent direct-debugging target when close a session. If we're direct- +// debugging the same target this time around, we load the argument values +// from the .ini file. +void dlgDirectDbg::LoadSettings() +{ + long num, arrCnt; + wxString tmp, key; + bool initPkgCon = false; + + settings->Read(wxT("Debugger/Proc/OID"), &num, -1L); + + dbgTargetInfo *target = m_controller->GetTargetInfo(); + pgDbgArgs *args = m_controller->GetTargetInfo()->GetArgs(); + + if (num != target->GetOid()) + { + chkPkgInit->SetValue(target->GetPkgInitOid() != 0L); + chkPkgInit->Enable(target->GetPkgInitOid() != 0L); + + return; + } + else + { + settings->Read(wxT("Debugger/Proc/initialize_package_constructor"), &initPkgCon, true); + + chkPkgInit->SetValue(&initPkgCon && target->GetPkgInitOid() != 0L); + chkPkgInit->Enable(target->GetPkgInitOid() != 0L); + } + + settings->Read(wxT("Debugger/Proc/args"), &num, 0L); + + if (num <= 0L) + return; + + if (!args) + return; + + for (int cnt = 0, row = 0; cnt < num && cnt < (int)args->Count();) + { + ctlGridCellBoolEditor *editor = + dynamic_cast( + grdParams->GetCellEditor(row, COL_NULL)); + dbgArgInfo *arg + = editor != NULL ? editor->GetArg() : NULL; + + if (arg == NULL) + { + row++; + + continue; + } + + key = wxString::Format(wxT("Debugger/Proc/%d/"), cnt); + + // Use NULL? + settings->Read(key + wxT("NULL"), &tmp, wxEmptyString); + grdParams->SetCellValue(row, COL_NULL, tmp); + + // Use Default (if available) + settings->Read(key + wxT("USE_DEF"), &tmp, wxEmptyString); + grdParams->SetCellValue(row, COL_USE_DEF, tmp); + + // Is Array/VARIADIC? + settings->Read(key + wxT("ArrCnt"), &arrCnt, 0L); + + if (arrCnt > 0L) + { + // An individual variable can be an expression or can be the 'NULL' value + wxString valKey, strVal, strExpr, strNull; + + for (int idx = 0; idx < arrCnt; idx++, row++) + { + valKey = wxString::Format(wxT("Debugger/Proc/%d/%d/"), cnt, idx); + + // Use 'NULL'? + settings->Read(valKey + wxT("NULL"), &strNull, wxEmptyString); + + // Use EXPR? + settings->Read(valKey + wxT("EXPR"), &strExpr, wxEmptyString); + + // Value + settings->Read(valKey + wxT("VAL"), &strVal, wxEmptyString); + + if (arg->IsArray()) + { + int arrRow = row + 1; + + if (idx == 0) + { + grdParams->SetReadOnly(row, COL_EXPR, true); + grdParams->SetReadOnly(row, COL_VALUE, true); + + grdParams->SetCellBackgroundColour(row, COL_EXPR, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(row, COL_VALUE, wxColour(235, 235, 235, 90)); + + grdParams->SetRowLabelValue( + row, wxString::Format(wxT("%d"), cnt + 1)); + } + grdParams->InsertRows(arrRow, 1, false); + grdParams->SetRowLabelValue(arrRow, wxT("-")); + + grdParams->SetCellValue(arrRow, COL_TYPE, arg->GetBaseType()); + + // Is the value an expression? + grdParams->SetCellEditor(arrRow, COL_EXPR, new ctlGridCellBoolEditor()); + grdParams->SetCellRenderer(arrRow, COL_EXPR, + new wxGridCellBoolRenderer()); + grdParams->SetCellValue(arrRow, COL_EXPR, strExpr); + + // Set value to NULL? + grdParams->SetCellEditor(arrRow, COL_NULL, + new ctlGridCellBoolEditor(arg)); + grdParams->SetCellRenderer(arrRow, COL_NULL, + new wxGridCellBoolRenderer()); + grdParams->SetCellValue(arrRow, COL_NULL, strNull); + + // Set value + grdParams->SetCellValue(arrRow, COL_VALUE, strVal); + + grdParams->SetReadOnly(arrRow, COL_NULL, false); + grdParams->SetReadOnly(arrRow, COL_EXPR, false); + grdParams->SetReadOnly(arrRow, COL_VALUE, false); + + grdParams->SetCellBackgroundColour(arrRow, COL_NAME, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(arrRow, COL_TYPE, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(arrRow, COL_USE_DEF, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(arrRow, COL_DEF_VAL, wxColour(235, 235, 235, 90)); + + grdParams->SetReadOnly(arrRow + 1, COL_NAME, true); + grdParams->SetReadOnly(arrRow + 1, COL_TYPE, true); + grdParams->SetReadOnly(arrRow + 1, COL_NULL, true); + grdParams->SetReadOnly(arrRow + 1, COL_EXPR, true); + grdParams->SetReadOnly(arrRow + 1, COL_VALUE, true); + grdParams->SetReadOnly(arrRow + 1, COL_USE_DEF, true); + grdParams->SetReadOnly(arrRow + 1, COL_DEF_VAL, true); + + grdParams->SetCellBackgroundColour(arrRow + 1, COL_NAME, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(arrRow + 1, COL_TYPE, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(arrRow + 1, COL_NULL, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(arrRow + 1, COL_EXPR, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(arrRow + 1, COL_VALUE, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(arrRow + 1, COL_USE_DEF, + wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(arrRow + 1, COL_DEF_VAL, + wxColour(235, 235, 235, 90)); + + grdParams->SetRowLabelValue(arrRow + 1, wxT("+")); + } + else + { + grdParams->SetCellValue(row, COL_VALUE, strVal); + grdParams->SetCellValue(row, COL_EXPR, strExpr); + grdParams->SetCellValue(row, COL_NULL, strNull); + + grdParams->SetReadOnly(row, COL_NULL, false); + grdParams->SetReadOnly(row, COL_EXPR, false); + grdParams->SetReadOnly(row, COL_VALUE, false); + + grdParams->SetRowLabelValue( + row, wxString::Format(wxT("%d"), cnt + 1)); + } + } + if (arg->IsArray()) + row++; + } + cnt++; + } +} + + +void dlgDirectDbg::OnOk(wxCommandEvent &_ev) +{ + if (m_thread) + return; + + grdParams->Enable(false); + btnDebug->Enable(false); + + m_thread = new dbgArgValueEvaluator(m_conn, this); + + if (m_thread->Create() != wxTHREAD_NO_ERROR) + { + delete m_thread; + m_thread = NULL; + + wxLogError(_("Failed to create a debugging thread.")); + EndModal(wxID_CANCEL); + + return; + } + + m_thread->Run(); +} + + +void dlgDirectDbg::OnCancel(wxCommandEvent &_ev) +{ + if (m_thread) + { + if (m_thread->IsRunning()) + { + m_thread->CancelEval(); + m_thread->Wait(); + } + + delete m_thread; + m_thread = NULL; + } + _ev.Skip(); +} + +void dlgDirectDbg::OnClickGridLabel(wxGridEvent &_ev) +{ + if (_ev.AltDown() || _ev.ControlDown() || _ev.ShiftDown()) + { + _ev.Skip(); + + return; + } + + int row = _ev.GetRow(); + int col = _ev.GetCol(); + + if (row < 0 || col > 0) + { + _ev.Skip(); + + return; + } + + wxString strLabel = grdParams->GetRowLabelValue(row); + + if (strLabel == wxT("+")) + { + wxASSERT(row != 0); + + ctlGridCellBoolEditor *editor = + dynamic_cast( + grdParams->GetCellEditor(row - 1, COL_NULL)); + dbgArgInfo *arg + = editor != NULL ? editor->GetArg() : NULL; + + grdParams->InsertRows(row, 1, false); + grdParams->SetRowLabelValue(row, wxT("-")); + + grdParams->SetCellValue(row, COL_TYPE, arg->GetBaseType()); + grdParams->SetCellBackgroundColour(row, COL_TYPE, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(row, COL_NAME, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(row, COL_USE_DEF, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(row, COL_DEF_VAL, wxColour(235, 235, 235, 90)); + + // Is the value an expression? + grdParams->SetCellEditor(row, COL_EXPR, new ctlGridCellBoolEditor()); + grdParams->SetCellRenderer(row, COL_EXPR, new wxGridCellBoolRenderer()); + grdParams->SetCellValue(row, COL_EXPR, wxT("")); + + // Set value to NULL? + grdParams->SetCellEditor(row, COL_NULL, new ctlGridCellBoolEditor(arg)); + grdParams->SetCellRenderer(row, COL_NULL, new wxGridCellBoolRenderer()); + grdParams->SetCellValue(row, COL_NULL, wxT("1")); + + row++; + grdParams->SetRowLabelValue(row, wxT("+")); + } + else if (strLabel == wxT("-")) + { + dbgArgInfo *arg = NULL; + grdParams->DeleteRows(row, 1, false); + } + else + return; + + // Update the row labels + ctlGridCellBoolEditor *editor = NULL; + dbgArgInfo *arg = NULL, + *prev = NULL; + wxString strName; + + int totalRows = grdParams->GetNumberRows(), + idx = 0; + row = 0; + + while (row < totalRows) + { + editor = + dynamic_cast( + grdParams->GetCellEditor(row, COL_NULL)); + arg = editor != NULL ? editor->GetArg() : NULL; + strName = grdParams->GetCellValue(row, COL_NAME); + + if (strName.IsEmpty() && arg) + grdParams->SetRowLabelValue(row, wxT("-")); + else if (!strName.IsEmpty() && !arg) + grdParams->SetRowLabelValue(row, wxT("+")); + else + { + idx++; + grdParams->SetRowLabelValue(row, wxString::Format(wxT("%d"), idx)); + } + + row++; + } +} + +//////////////////////////////////////////////////////////////////////////////// +// SaveSettings() +// +// Save default values to our .ini file. We save the OID of the most +// recent direct-debugging target when close a session. We also save the +// value of each argument - if you debug the same target again next time, +// loadSettings() will initialize the parameter-values window with the +// same parameter values that you entered in this session. +// +void dlgDirectDbg::SaveSettings() +{ + wxString strName, strExpr, strVal, strNull, strDef, strKey, strValExpr; + dbgArgInfo *prev = NULL, + *arg = NULL; + int row = 0, + idx = -1, + arrCnt = 1; + + // Save the current function/procedure/trigger OID + settings->WriteLong(wxT("Debugger/Proc/OID"), + m_controller->GetTargetInfo()->GetOid()); + + // Save - whether we need to debug the package constructor + settings->WriteBool(wxT("Debugger/Proc/initialize_package_constructor"), + (chkPkgInit->IsEnabled() && chkPkgInit->GetValue())); + + for (; row < grdParams->GetNumberRows(); row++) + { + ctlGridCellBoolEditor *editor = + dynamic_cast( + grdParams->GetCellEditor(row, COL_NULL)); + arg = editor != NULL ? editor->GetArg() : NULL; + + // This should be the information for add/remove values for an array + if (arg == NULL) + { + continue; + } + else if (prev != arg) + { + idx++; + prev = arg; + + if (arg->IsArray()) + { + arrCnt = 0; + } + else + { + arrCnt = 1; + } + } + else + { + arrCnt++; + } + + settings->WriteInt(wxString::Format(wxT("Debugger/Proc/%d/ArrCnt"), idx), arrCnt); + + if ((arrCnt == 0 && arg->IsArray()) || + (arrCnt == 1 && !arg->IsArray())) + { + // Use Default (if available) + settings->Write(wxString::Format(wxT("Debugger/Proc/%d/USE_DEF"), idx), + grdParams->GetCellValue(row, COL_USE_DEF)); + + // Use NULL? + settings->Write(wxString::Format(wxT("Debugger/Proc/%d/NULL"), idx), + grdParams->GetCellValue(row, COL_NULL)); + + if (arrCnt == 0 && arg->IsArray()) + continue; + } + + strKey = wxString::Format(wxT("Debugger/Proc/%d/%d/"), idx, arrCnt - 1); + + // Use NULL? + settings->Write(strKey + wxT("NULL"), + grdParams->GetCellValue(row, COL_NULL)); + + // Is value EXPR? + settings->Write(strKey + wxT("EXPR"), + grdParams->GetCellValue(row, COL_EXPR)); + + // Value + settings->Write(strKey + wxT("VAL"), + grdParams->GetCellValue(row, COL_VALUE)); + } + + // Save the number of arguments + settings->WriteLong(wxT("Debugger/Proc/args"), (long)(idx + 1)); +} + + +ctlGridCellBoolEditor::ctlGridCellBoolEditor(dbgArgInfo *_arg) + : m_arg(_arg) +{} + + +void ctlGridCellBoolEditor::BeginEdit(int _row, int _col, wxGrid *_grid) +{ + wxGridCellBoolEditor::BeginEdit(_row, _col, _grid); + + wxFocusEvent event (wxEVT_KILL_FOCUS); + if (m_control) + { + m_control->GetEventHandler()->AddPendingEvent(event); + } +} + + +wxGrid *dlgDirectDbg::GetParamsGrid() +{ + return grdParams; +} + +bool dlgDirectDbg::DebugPkgConstructor() +{ + return chkPkgInit->IsEnabled() && chkPkgInit->GetValue(); +} + + +wxGridCellEditor *ctlGridCellBoolEditor::Clone() const +{ + return new ctlGridCellBoolEditor(m_arg); +} + + +void dlgDirectDbg::ResultArgsUpdated(wxCommandEvent &_ev) +{ + SaveSettings(); + SavePosition(); + + if (m_thread) + { + if (m_thread->IsRunning()) + { + m_thread->CancelEval(); + m_thread->Wait(); + } + + delete m_thread; + m_thread = NULL; + } + + if (IsModal()) + EndModal(wxID_OK); + else + Destroy(); +} + + +void dlgDirectDbg::ResultArgsUpdateError(wxCommandEvent &_ev) +{ + if (_ev.GetInt() == pgQueryResultEvent::PGQ_CONN_LOST) + { + if(wxMessageBox( + _("Connection to the database server lost!\nDo you want to try to reconnect to the server?"), + _("Connection Lost"), wxICON_ERROR | wxICON_QUESTION | wxYES_NO) == wxID_YES) + { + if (m_thread) + { + if (m_thread->IsRunning()) + { + m_thread->CancelEval(); + m_thread->Wait(); + } + + delete m_thread; + m_thread = NULL; + } + m_conn->Reconnect(); + + return; + } + EndModal(wxID_CANCEL); + + return; + } + + if (m_thread) + { + if (m_thread->IsRunning()) + { + m_thread->CancelEval(); + m_thread->Wait(); + } + + delete m_thread; + m_thread = NULL; + } + + wxLogError(_ev.GetString()); + + grdParams->Enable(true); + btnDebug->Enable(true); +} + + +void dbgArgValueEvaluator::NoticeHandler(void *, const char *) +{ + // Ignore the notices +} + + +void *dbgArgValueEvaluator::Entry() +{ + bool argNull, nullVal, useDef; + wxString strVal, strValExpr; + dbgArgInfo *prev = NULL, + *arg = NULL; + + wxGrid *grd = m_dlg->GetParamsGrid(); + + m_dlg->m_controller->GetTargetInfo()->DebugPackageConstructor() + = m_dlg->DebugPkgConstructor(); + + m_conn->RegisterNoticeProcessor(dbgArgValueEvaluator::NoticeHandler, NULL); + + for (int row = 0, idx = 0, arrCnt = 1, arr_idx_bound = 0; + row < grd->GetNumberRows() && !m_cancelled; row++) + { + ctlGridCellBoolEditor *editor = + dynamic_cast( + grd->GetCellEditor(row, dlgDirectDbg::COL_NULL)); + arg = editor != NULL ? editor->GetArg() : NULL; + + // This should be the information for add/remove values for an array + if (arg == NULL) + { + // prev was an array, can we fetch value for the same + if (prev && !prev->Null()) + { + wxString res = + m_conn->ExecuteScalar( + wxT("SELECT ARRAY[") + strValExpr + wxT("]::") + prev->GetTypeName(), + false); + + if (m_cancelled) + { + m_conn->RegisterNoticeProcessor(NULL, NULL); + + return (void *)NULL; + } + if (m_conn->GetStatus() == PGCONN_BAD) + { + wxCommandEvent ev(wxEVT_COMMAND_MENU_SELECTED, RESULT_ID_ARGS_UPDATE_ERROR); + + ev.SetInt(pgQueryResultEvent::PGQ_CONN_LOST); + + m_dlg->GetEventHandler()->AddPendingEvent(ev); + + m_conn->RegisterNoticeProcessor(NULL, NULL); + + return (void *)NULL; + } + if (m_conn->GetLastResultStatus() == PGRES_TUPLES_OK) + { + prev->Value() = res; + } + else + { + wxCommandEvent ev(wxEVT_COMMAND_MENU_SELECTED, RESULT_ID_ARGS_UPDATE_ERROR); + wxString strName = prev->GetName(); + wxString strMsg; + + if (strName.IsEmpty()) + { + ev.SetString( + wxString::Format( + _("The specified value for argument #%d is not valid.\nPlease re-enter the value for it."), + idx)); + } + else + { + ev.SetString( + wxString::Format( + _("Specified value for argument '%s' is not valid.\nPlease re-enter the value for it."), + strName.c_str())); + } + ev.SetInt(pgQueryResultEvent::PGQ_RESULT_ERROR); + m_dlg->LoadLastCellSetting(row - 1, idx - 1, arr_idx_bound - 1, true); + m_dlg->GetEventHandler()->AddPendingEvent(ev); + + m_conn->RegisterNoticeProcessor(NULL, NULL); + + return (void *)NULL; + + } + prev = NULL; + arr_idx_bound = 0; + } + + continue; + } + else if (prev != arg) + { + idx++; + argNull = false; + nullVal = false; + useDef = false; + + strValExpr = wxEmptyString; + } + + if (prev != arg) + { + prev = arg; + + // Use Default (if available) + arg->UseDefault() = wxGridCellBoolEditor::IsTrueValue( + grd->GetCellValue(row, dlgDirectDbg::COL_USE_DEF)); + // NULL? + arg->Null() = wxGridCellBoolEditor::IsTrueValue( + grd->GetCellValue(row, dlgDirectDbg::COL_NULL)); + + if (arg->UseDefault()) + strValExpr = arg->Default(); + + if (arg->IsArray()) + continue; + } + + // Use NULL? + // + // Keep this just before 'Use Default' column as - we may have non-empty + // value in the 'VAL' column + + if (!arg->UseDefault() || !arg->Null()) + { + if (!strValExpr.IsEmpty()) + { + strValExpr += wxT(", "); + } + + if (wxGridCellBoolEditor::IsTrueValue( + grd->GetCellValue(row, dlgDirectDbg::COL_NULL))) + { + strValExpr += wxT("NULL"); + } + else if (wxGridCellBoolEditor::IsTrueValue( + grd->GetCellValue(row, dlgDirectDbg::COL_EXPR))) + { + strValExpr += wxT("(") + grd->GetCellValue(row, dlgDirectDbg::COL_VALUE) + wxT(")"); + } + else + { + strValExpr += m_conn->qtDbString( + grd->GetCellValue(row, dlgDirectDbg::COL_VALUE)); + } + strValExpr.Append(wxT("::")) + .Append(arg->IsArray() ? + arg->GetBaseType() : arg->GetTypeName()); + + if(arg->IsArray()) + { + arr_idx_bound ++; + } + } + + if (!arg->IsArray() && !arg->Null()) + { + pgSet *set = + m_conn->ExecuteSet(wxT("SELECT ") + strValExpr, false); + + if (m_cancelled) + { + return (void *)NULL; + } + if (m_conn->GetStatus() == PGCONN_BAD) + { + wxCommandEvent ev(wxEVT_COMMAND_MENU_SELECTED, RESULT_ID_ARGS_UPDATE_ERROR); + + ev.SetString(_("Connection to the database server lost!")); + ev.SetInt(pgQueryResultEvent::PGQ_CONN_LOST); + + m_dlg->GetEventHandler()->AddPendingEvent(ev); + + m_conn->RegisterNoticeProcessor(NULL, NULL); + + if (set) + delete set; + + return (void *)NULL; + } + if (m_conn->GetLastResultStatus() == PGRES_TUPLES_OK && + set && set->NumRows() > 0L) + { + if (set->IsNull(0)) + { + arg->Null() = true; + } + else + { + arg->Null() = false; + arg->Value() = set->GetVal(0); + } + } + else + { + wxString strName = arg->GetName(); + + if (strName.IsEmpty()) + strName = wxString::Format(_("Param#%d"), idx); + + wxCommandEvent ev(wxEVT_COMMAND_MENU_SELECTED, RESULT_ID_ARGS_UPDATE_ERROR); + + ev.SetString( + wxString::Format(_("Please re-enter the value for argument '%s'."), + strName.c_str())); + ev.SetInt(pgQueryResultEvent::PGQ_RESULT_ERROR); + + m_dlg->GetEventHandler()->AddPendingEvent(ev); + m_dlg->LoadSettings(); + // For scalar variable, always index of array bound is 0. + m_dlg->LoadLastCellSetting(row, idx - 1, 0, false); + m_conn->RegisterNoticeProcessor(NULL, NULL); + + return (void *)NULL; + } + } + } + + wxCommandEvent ev(wxEVT_COMMAND_MENU_SELECTED, RESULT_ID_ARGS_UPDATED); + m_dlg->GetEventHandler()->AddPendingEvent(ev); + + m_conn->RegisterNoticeProcessor(NULL, NULL); + + return (void *)NULL; +} + + +void dbgArgValueEvaluator::CancelEval() +{ + m_cancelled = true; + + if (m_conn->GetTxStatus() == PGCONN_TXSTATUS_ACTIVE) + m_conn->CancelExecution(); +} + +dbgArgValueEvaluator::dbgArgValueEvaluator(pgConn *_conn, dlgDirectDbg *_dlg) + : wxThread(wxTHREAD_JOINABLE), m_conn(_conn), m_dlg(_dlg), m_cancelled(false) +{} diff --git a/debugger/frmDebugger.cpp b/debugger/frmDebugger.cpp new file mode 100644 index 0000000..1ba02ee --- /dev/null +++ b/debugger/frmDebugger.cpp @@ -0,0 +1,1025 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmDebugger.cpp - debugger +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +#include + +// App headers +#include "ctl/ctlMenuToolbar.h" +#include "ctl/ctlSQLBox.h" +#include "ctl/ctlAuiNotebook.h" +#include "ctl/ctlProgressStatusBar.h" +#include "debugger/dbgController.h" +#include "debugger/ctlTabWindow.h" +#include "debugger/frmDebugger.h" +#include "frm/frmMain.h" +#include "debugger/dbgConst.h" + +#include "images/debugger.pngc" +#include "images/clearAll.pngc" +#include "images/continue.pngc" +#include "images/setBreak.pngc" +#include "images/stepOver.pngc" +#include "images/stepInto.pngc" +#include "images/stop.pngc" + +IMPLEMENT_CLASS(frmDebugger, pgFrame) + +BEGIN_EVENT_TABLE(frmDebugger, pgFrame) + EVT_CLOSE(frmDebugger::OnClose) + EVT_SIZE(frmDebugger::OnSize) + EVT_ERASE_BACKGROUND(frmDebugger::OnEraseBackground) + EVT_AUI_PANE_CLOSE(frmDebugger::OnAuiUpdate) + + EVT_MENU_RANGE(MENU_ID_TOGGLE_BREAK, MENU_ID_STOP, frmDebugger::OnDebugCommand) + + EVT_STC_MARGINCLICK(wxID_ANY, frmDebugger::OnMarginClick) + EVT_STC_UPDATEUI(wxID_ANY, frmDebugger::OnPositionStc) + EVT_LISTBOX(wxID_ANY, frmDebugger::OnSelectFrame) + EVT_GRID_CELL_CHANGE( frmDebugger::OnVarChange) + + EVT_MENU(MNU_EXIT, frmDebugger ::OnExit) + EVT_MENU(MENU_ID_VIEW_TOOLBAR, frmDebugger::OnToggleToolBar) + EVT_MENU(MENU_ID_VIEW_STACKPANE, frmDebugger::OnToggleStackPane) + EVT_MENU(MENU_ID_VIEW_OUTPUTPANE, frmDebugger::OnToggleOutputPane) + EVT_MENU(MENU_ID_VIEW_DEFAULTVIEW, frmDebugger::OnDefaultView) + + EVT_MENU(MNU_CONTENTS, frmDebugger::OnContents) + EVT_MENU(MNU_HELP, frmDebugger::OnHelp) +END_EVENT_TABLE() + +//////////////////////////////////////////////////////////////////////////////// +// frmDebugger constructor +// +// frmDebugger manages the user interface for the workstation. This class +// manages the toolbar, menu, status bar, and top-level windows. + +frmDebugger::frmDebugger(frmMain *_parent, dbgController *_controller, + const wxString &_title) : pgFrame(_parent, _title), m_menuBar(NULL), + m_toolBar(NULL), m_viewMenu(NULL), m_debugMenu(NULL), m_statusBar(NULL), + m_parent(_parent), m_controller(_controller), m_stackWindow(NULL), + m_tabWindow(NULL), m_codeViewer(NULL) +{ + dlgName = wxT("frmDebugger"); + RestorePosition(100, 100, 600, 500, 450, 300); + + SetFont(settings->GetSystemFont()); + + m_manager.SetManagedWindow(this); + m_manager.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_TRANSPARENT_DRAG); + + // Define the icon for this window + SetIcon(*debugger_png_ico); + + // Create (and configure) the menu bar, toolbar, and status bar + m_menuBar = SetupMenuBar(); + m_toolBar = SetupToolBar(); + m_statusBar = SetupStatusBar(); + + m_manager.AddPane( + m_toolBar, + wxAuiPaneInfo().Name(wxT("toolBar")).Caption(wxT("Toolbar")) + .ToolbarPane().Top().Row(1).Position(1).LeftDockable(false) + .RightDockable(false)); + + // Now load the layout + wxString perspective; + settings->Read( + wxT("Debugger/frmDebugger/Perspective-") + + wxString(FRMDEBUGGER_PERSPECTIVE_VER), + &perspective, FRMDEBUGGER_DEFAULT_PERSPECTIVE); + + m_manager.LoadPerspective(perspective, true); + + // and reset the captions for the current language + m_manager.GetPane(wxT("toolBar")).Caption(_("Toolbar")); + + // Sync the View menu options + m_viewMenu->Check(MENU_ID_VIEW_TOOLBAR, m_manager.GetPane(wxT("toolBar")).IsShown()); + + SetupDebugger(); + + m_manager.Update(); +} + + +frmDebugger::~frmDebugger() +{ + // Only save the settings if the window was completely setup + // This may not be the case if the params dialog was displayed, + // and the user hit cancel before the main form opened. + wxAuiPaneInfo &pane = m_manager.GetPane(wxT("sourcePane")); + if (pane.IsOk()) + settings->Write(wxT("Debugger/frmDebugger/Perspective-") + wxString(FRMDEBUGGER_PERSPECTIVE_VER), m_manager.SavePerspective()); + + m_manager.UnInit(); + + if (m_parent) + m_parent->RemoveFrame(this); + + if (m_controller) + { + PopEventHandler(); + delete m_controller; + m_controller = NULL; + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// OnContents() +// OnHelp() +// +// Help menu options +void frmDebugger::OnContents(wxCommandEvent &event) +{ + DisplayHelp(wxT("debugger"), HELP_PGADMIN); +} + + +void frmDebugger::OnHelp(wxCommandEvent &event) +{ + DisplayHelp(wxT("plpgsql"), HELP_POSTGRESQL); +} + + +//////////////////////////////////////////////////////////////////////////////// +// SetupDebugger() +// +// This function creates the debugger views... +// +void frmDebugger::SetupDebugger() +{ + SetFont(settings->GetSystemFont()); + + // Initializing Stack Frame Window + if (m_stackWindow == NULL) + { + m_stackWindow = new ctlStackWindow(this, WINDOW_ID_STACK, wxDefaultPosition, + wxDefaultSize, 0); + + m_manager.AddPane(m_stackWindow, + wxAuiPaneInfo().Name(wxT("stackPane")).Caption(_("Stack pane")).Right() + .MinSize(wxSize(100, 100)).BestSize(wxSize(250, 200))); + } + // Initializing Tab Window + if (m_tabWindow == NULL) + { + m_tabWindow = new ctlTabWindow(this, WINDOW_ID_TABS, wxDefaultPosition, + wxDefaultSize, wxAUI_NB_BOTTOM | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS | wxAUI_NB_WINDOWLIST_BUTTON); + + m_manager.AddPane(m_tabWindow, + wxAuiPaneInfo().Name(wxT("outputPane")).Caption(_("Output pane")).Bottom() + .MinSize(wxSize(200, 100)).BestSize(wxSize(550, 300))); + } + // Initialing Code viewer Window + if (m_codeViewer == NULL) + { + m_codeViewer = new ctlSQLBox(this, -1); + + // Set up the markers that we use to indicate the current line and + // the break-point + m_codeViewer->MarkerDefine(MARKER_CURRENT, wxSTC_MARK_ARROW, *wxGREEN, + *wxGREEN); + m_codeViewer->MarkerDefine(MARKER_CURRENT_BG, wxSTC_MARK_BACKGROUND, *wxGREEN, + *wxGREEN); + m_codeViewer->MarkerDefine(MARKER_BREAKPOINT, wxSTC_MARK_CIRCLEPLUS, *wxRED, + *wxRED); + + m_codeViewer->SetMarginWidth(1, 16); + m_codeViewer->SetMarginType(1, wxSTC_MARGIN_SYMBOL); + + // Make sure that the text control tells us when the user clicks in the + // left margin + m_codeViewer->SetMarginSensitive(0, true); + m_codeViewer->SetMarginSensitive(1, true); + m_codeViewer->SetMarginSensitive(2, true); + + m_manager.AddPane(m_codeViewer, + wxAuiPaneInfo().Name(wxT("sourcePane")).Caption(_("Source pane")).Center() + .CaptionVisible(false).CloseButton(false).MinSize(wxSize(200, 100)) + .BestSize(wxSize(350, 200))); + } + + // Make sure the user can't edit the source code for this function + m_codeViewer->SetReadOnly(true); + + // Now (re)load the layout + wxString perspective; + settings->Read( + wxT("Debugger/frmDebugger/Perspective-") + + wxString(FRMDEBUGGER_PERSPECTIVE_VER), &perspective, + FRMDEBUGGER_DEFAULT_PERSPECTIVE); + m_manager.LoadPerspective(perspective, true); + + // And reset the captions + m_manager.GetPane(wxT("sourcePane")).Caption(_("Source pane")); + m_manager.GetPane(wxT("stackPane")).Caption(_("Stack pane")); + m_manager.GetPane(wxT("outputPane")).Caption(_("Output pane")); + + // Sync the View menu options + m_viewMenu->Check(MENU_ID_VIEW_STACKPANE, + m_manager.GetPane(wxT("stackPane")).IsShown()); + m_viewMenu->Check(MENU_ID_VIEW_OUTPUTPANE, + m_manager.GetPane(wxT("outputPane")).IsShown()); + + // Enable the options for these controls + m_viewMenu->Enable(MENU_ID_VIEW_OUTPUTPANE, true); + m_viewMenu->Enable(MENU_ID_VIEW_STACKPANE, true); + + m_manager.Update(); + + // force + EnableToolsAndMenus(false); + + PushEventHandler(m_controller); +} + + +//////////////////////////////////////////////////////////////////////////////// +// EnableToolsAndMenus +// +// Enable or disable the debugging tools and menus +// +// Parameters: +// - enable/disable (boolean) +// +void frmDebugger::EnableToolsAndMenus(bool enable) +{ + if (m_toolBar) + { + m_toolBar->EnableTool(MENU_ID_STEP_INTO, enable); + m_toolBar->EnableTool(MENU_ID_STEP_OVER, enable); + m_toolBar->EnableTool(MENU_ID_CONTINUE, + (enable || + (m_controller && m_controller->CanRestart()))); + m_toolBar->EnableTool(MENU_ID_TOGGLE_BREAK, enable); + m_toolBar->EnableTool(MENU_ID_CLEAR_ALL_BREAK, enable); + m_toolBar->EnableTool(MENU_ID_STOP, enable); + } + + if (m_debugMenu) + { + m_debugMenu->Enable(MENU_ID_STEP_INTO, enable); + m_debugMenu->Enable(MENU_ID_STEP_OVER, enable); + m_debugMenu->Enable(MENU_ID_CONTINUE, + (enable || + (m_controller && m_controller->CanRestart()))); + m_debugMenu->Enable(MENU_ID_TOGGLE_BREAK, enable); + m_debugMenu->Enable(MENU_ID_CLEAR_ALL_BREAK, enable); + m_debugMenu->Enable(MENU_ID_STOP, enable); + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// GetLineNo +// +// This function returns the current line-number, where the execution flow +// has been stopped +// +// Returns: +// Current line-number +// +int frmDebugger::GetLineNo() +{ + if (m_codeViewer) + { + return (m_codeViewer->LineFromPosition(m_codeViewer->GetCurrentPos())); + } + else + { + return -1; + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// IsBreakpoint(int) +// +// This function helps checking if break-point is set on the particular line +// +// Parameters: +// - line-number +// +// Returns: +// - True if a break-point is set on the line-no, otherwise false +// +bool frmDebugger::IsBreakpoint(int _lineNo) +{ + if (m_codeViewer) + return (m_codeViewer->MarkerGet(_lineNo) & + MARKERINDEX_TO_MARKERMASK(MARKER_BREAKPOINT) ? true : false); + else + return false; +} + + +//////////////////////////////////////////////////////////////////////////////// +// ClearAllBreakpoints +// +// This function clears all the break-points +// +void frmDebugger::ClearAllBreakpoints() +{ + int lineNo = -1; + bool updateBreakpoints = false; + + if (m_codeViewer) + { + while((lineNo = m_codeViewer->MarkerNext(lineNo + 1, + MARKERINDEX_TO_MARKERMASK(MARKER_BREAKPOINT))) != -1) + { + // Clear the break-point at particular location + m_controller->ClearBreakpoint(lineNo); + updateBreakpoints = true; + } + + // Update break-points only if required + if (updateBreakpoints) + m_controller->UpdateBreakpoints(); + } +} + + +void frmDebugger::ClearBreakpointMarkers() +{ + int lineNo = 0; + if (m_codeViewer) + { + while((lineNo = m_codeViewer->MarkerNext(lineNo, + MARKERINDEX_TO_MARKERMASK(MARKER_BREAKPOINT))) != -1) + { + m_codeViewer->MarkerDelete(lineNo++, MARKER_BREAKPOINT); + } + } +} + + +void frmDebugger::MarkBreakpoint(int _line) +{ + if (m_codeViewer) + { + m_codeViewer->MarkerAdd(_line, MARKER_BREAKPOINT); + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// UnhilightCurrentLine +// +// This function removes the hilight from the current line +// +void frmDebugger::UnhilightCurrentLine() +{ + if (m_codeViewer) + { + int lineNo + = m_codeViewer->MarkerNext(0, MARKERINDEX_TO_MARKERMASK(MARKER_CURRENT)); + + if(lineNo != -1) + { + m_codeViewer->MarkerDelete(lineNo, MARKER_CURRENT); + m_codeViewer->MarkerDelete(lineNo, MARKER_CURRENT_BG); + } + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// OnDebugCommand(wxCommandEvent) +// +// This function handles the user clicks one of the debugger tools and menus +// and take care of actions requires. These events are toggle break-point, +// clear all break-points, debugging continue, step-in, step-over and stop +// debugging. +// +// Parameters +// - event object +// +void frmDebugger::OnDebugCommand(wxCommandEvent &_event) +{ + switch(_event.GetId()) + { + case MENU_ID_TOGGLE_BREAK: + { + int lineNo = GetLineNo(); + + // This event should have not been called + if (lineNo == -1) + return; + + // The user wants to set or clear a breakpoint at the line that + // contains the insertion point (the caret) + if (IsBreakpoint(lineNo)) + { + m_controller->ClearBreakpoint(lineNo); + } + else + { + m_controller->SetBreakpoint(lineNo); + } + m_controller->UpdateBreakpoints(); + } + break; + + case MENU_ID_CLEAR_ALL_BREAK: + // The user wants to clear all the breakpoint + ClearAllBreakpoints(); + + break; + + case MENU_ID_CONTINUE: + // The user wants to continue execution (as opposed to + // single-stepping through the code). Unhilite all + // variables and tell the debugger server to continue. + if (m_controller) + { + if (m_controller->CanRestart()) + { + m_controller->Start(); + } + else + { + EnableToolsAndMenus(false); + LaunchWaitingDialog(_("Waiting for target (continue)...")); + m_controller->Countinue(); + UnhilightCurrentLine(); + } + } + break; + + case MENU_ID_STEP_OVER: + // The user wants to step-over a function invocation (or + // just single-step). Unhilite all variables and tell the + // debugger server to step-over + EnableToolsAndMenus(false); + LaunchWaitingDialog(_("Waiting for target (step over)...")); + m_controller->StepOver(); + UnhilightCurrentLine(); + + break; + + case MENU_ID_STEP_INTO: + // The user wants to step-into a function invocation (or + // just single-step). Unhilite all variables and tell the + // debugger server to step-into + EnableToolsAndMenus(false); + LaunchWaitingDialog(_("Waiting for target (step into)...")); + m_controller->StepInto(); + UnhilightCurrentLine(); + + break; + + case MENU_ID_STOP: + EnableToolsAndMenus(false); + LaunchWaitingDialog(_("Waiting for target to stop execution...")); + m_controller->Stop(); + UnhilightCurrentLine(); + + break; + + default: + break; + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// OnSelectFrame() +// +// This function handles the user click on one of the stack-frames, and +// asks the debugger server to switch to that frame, update the breakpoint +// markers, and send a list of variables that are in-scope in the selected +// frame +// +// Parametes: +// Selection Event Object +// +void frmDebugger::OnSelectFrame(wxCommandEvent &_ev) +{ + if(_ev.GetSelection() != -1) + { + if (!m_controller->SelectFrame(_ev.GetSelection())) + { + // Reset to previous selection + dbgModel *model = m_controller->GetModel(); + m_stackWindow->SelectFrame(model->GetDisplayedPackage(), + model->GetDisplayedFunction()); + } + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// OnMarginClick() +// +// This function handles the user clicks in the margin to the left of a +// line of source code. We use the margin to display breakpoint indicators +// so it makes sense that if you click on an breakpoint indicator, we will +// clear that breakpoint. If you click on a spot that does not contain a +// breakpoint indicator (but it's still in the margin), we create a new +// breakpoint at that line +// +// Parametes: +// Selection Event Object +// +void frmDebugger::OnMarginClick(wxStyledTextEvent &event) +{ + int lineNo; + + // Check that the user clicked on the line number or breakpoint margin + // We don't want to set a breakpoint when the user folds/unfolds code + if (!(event.GetMargin() == 0 || event.GetMargin() == 1)) + return; + + lineNo = m_codeViewer->LineFromPosition(event.GetPosition()); + + if (lineNo <= 0) + return; + + // If we already have a breakpoint at the clickpoint, disable it, otherwise + // create a new breakpoint + if(m_codeViewer->MarkerGet(lineNo) & + MARKERINDEX_TO_MARKERMASK(MARKER_BREAKPOINT)) + { + m_controller->ClearBreakpoint(lineNo); + } + else + { + m_controller->SetBreakpoint(lineNo); + } + m_controller->UpdateBreakpoints(); +} + + +//////////////////////////////////////////////////////////////////////////////// +// OnPositionStc() +// +// This function handles the event called when the user positions the cursor +// in the code viewer. We will update the current line number etc in the +// status bar. +// +// Parametes: +// wxStyledTextEvent Object +// +void frmDebugger::OnPositionStc(wxStyledTextEvent &event) +{ + if (m_codeViewer) + { + wxString strPos; + + int pos = m_codeViewer->GetCurrentPos(); + + strPos.Printf(_("Ln %d Col %d Ch %d"), m_codeViewer->LineFromPosition(pos) + 1, + m_codeViewer->GetColumn(pos) + 1, pos + 1); + + GetStatusBar()->SetStatusText(strPos, 3); + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// OnVarChange() +// +// This functions handles the event occurred when the user edits a variable +// value. Submit the changed value to the debugger server +// +void frmDebugger::OnVarChange(wxGridEvent &_ev) +{ + ctlVarWindow *varWin = NULL; + wxString varName, varValue; + + if(_ev.GetId() == ID_PARAMGRID) + { + varWin = GetParamWindow(false); + varName = varWin->GetVarName(_ev.GetRow()); + varValue = varWin->GetVarValue(_ev.GetRow()); + } + else if (_ev.GetId() == ID_VARGRID) + { + varWin = GetVarWindow(false); + varName = varWin->GetVarName(_ev.GetRow()); + varValue = varWin->GetVarValue(_ev.GetRow()); + } + else if (_ev.GetId() == ID_PKGVARGRID) + { + varWin = GetPkgVarWindow(false); + varName = wxT("@") + varWin->GetVarName(_ev.GetRow()); + varValue = varWin->GetVarValue(_ev.GetRow()); + } + else + { + // Theorically - the execution flow must not reach at this point. + return; + } + + m_controller->DepositValue(varName, varValue); +} + +//////////////////////////////////////////////////////////////////////////////// +// OnSize() +// +// This event handler is called when a resize event occurs (that is, when +// wxWidgets needs to size the application window) +// +void frmDebugger::OnSize(wxSizeEvent &event) +{ + event.Skip(); +} + + +void frmDebugger::OnEraseBackground(wxEraseEvent &event) +{ + event.Skip(); +} + + +//////////////////////////////////////////////////////////////////////////////// +// setupToolBar() +// +// This function creates the standard toolbar +// +ctlMenuToolbar *frmDebugger::SetupToolBar(void) +{ + m_toolBar = new ctlMenuToolbar(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTB_FLAT | wxTB_NODIVIDER); + + m_toolBar->SetToolBitmapSize(wxSize(16, 16)); + + m_toolBar->AddTool(MENU_ID_STEP_INTO, wxEmptyString, *stepInto_png_bmp, + _("Step into")); + m_toolBar->AddTool(MENU_ID_STEP_OVER, wxEmptyString, *stepOver_png_bmp, + _("Step over")); + m_toolBar->AddTool(MENU_ID_CONTINUE, wxEmptyString, *continue_png_bmp, + _("Continue/Start")); + m_toolBar->AddSeparator(); + m_toolBar->AddTool(MENU_ID_TOGGLE_BREAK, wxEmptyString, *setBreak_png_bmp, + _("Toggle breakpoint")); + m_toolBar->AddTool(MENU_ID_CLEAR_ALL_BREAK, wxEmptyString, *clearAll_png_bmp, + _("Clear all breakpoints")); + m_toolBar->AddSeparator(); + m_toolBar->AddTool(MENU_ID_STOP, wxEmptyString, *stop_png_bmp, + _("Stop debugging")); + + m_toolBar->EnableTool(MENU_ID_STEP_INTO, false); + m_toolBar->EnableTool(MENU_ID_STEP_OVER, false); + m_toolBar->EnableTool(MENU_ID_CONTINUE, false); + m_toolBar->EnableTool(MENU_ID_TOGGLE_BREAK, false); + m_toolBar->EnableTool(MENU_ID_CLEAR_ALL_BREAK, false); + m_toolBar->EnableTool(MENU_ID_STOP, false); + + m_toolBar->Realize(); + + return(m_toolBar); +} + + +//////////////////////////////////////////////////////////////////////////////// +// SetupStatusBar() +// +// This function initializes the status bar (we don't have one at the moment +// so this function simply returns) +// +ctlProgressStatusBar *frmDebugger::SetupStatusBar(void) +{ + ctlProgressStatusBar *bar = new ctlProgressStatusBar(this, false); + int widths[] = { -1, ctlProgressStatusBar::ms_progressbar_width, ctlProgressStatusBar::ms_progressstatus_width, 190}; + + bar->SetFieldsCount(4); + bar->SetStatusWidths(4, widths); + this->SetStatusBar(bar); + + return(bar); +} + + +//////////////////////////////////////////////////////////////////////////////// +// SetupMenuBar() +// +// This function creates the standard menu bar +// +wxMenuBar *frmDebugger::SetupMenuBar(void) +{ + m_menuBar = new wxMenuBar; + + // Don't append the File menu on Mac, as the Exit option + // will be moved to the application menu, leaving File empty. +#ifndef __WXMAC__ + wxMenu *fileMenu = new wxMenu; + fileMenu->Append(MNU_EXIT, _("E&xit\tAlt-F4"), _("Exit debugger window")); + + m_menuBar->Append(fileMenu, _("&File")); +#endif + + m_debugMenu = new wxMenu; +#ifdef __WXGTK__ + // + // F10 is treated as a System menu under GTK. Hence, we will use Ctrl+F10 for + // "step over" operation under GTK, instead of F10. + // + // To make the behavior consitent, we will also use Ctrl+ for all the operations + // under GTK. (i.e. Step into, Step over, Continue, Toggle breakpoint, Stop + // debugging) + // + // Please follow this link for more details: + // http://trac.wxwidgets.org/ticket/2404 + // + m_debugMenu->Append(MENU_ID_STEP_INTO, _("Step into\tCtrl+F11")); + m_debugMenu->Append(MENU_ID_STEP_OVER, _("Step over\tCtrl+F10")); + m_debugMenu->Append(MENU_ID_CONTINUE, _("Continue/Start\tCtrl+F5")); + m_debugMenu->AppendSeparator(); + m_debugMenu->Append(MENU_ID_TOGGLE_BREAK, _("Toggle breakpoint\tCtrl+F9")); + m_debugMenu->Append(MENU_ID_CLEAR_ALL_BREAK, _("Clear all breakpoints\tCtrl+Shift+F9")); + m_debugMenu->AppendSeparator(); + m_debugMenu->Append(MENU_ID_STOP, _("Stop debugging\tCtrl+F8")); +#else + m_debugMenu->Append(MENU_ID_STEP_INTO, _("Step into\tF11")); + m_debugMenu->Append(MENU_ID_STEP_OVER, _("Step over\tF10")); + m_debugMenu->Append(MENU_ID_CONTINUE, _("Continue/Start\tF5")); + m_debugMenu->AppendSeparator(); + m_debugMenu->Append(MENU_ID_TOGGLE_BREAK, _("Toggle breakpoint\tF9")); + m_debugMenu->Append(MENU_ID_CLEAR_ALL_BREAK, _("Clear all breakpoints\tCtrl+Shift+F9")); + m_debugMenu->AppendSeparator(); + m_debugMenu->Append(MENU_ID_STOP, _("Stop debugging\tF8")); +#endif //__WXGTK__ + m_debugMenu->Enable(MENU_ID_STEP_INTO, false); + m_debugMenu->Enable(MENU_ID_STEP_OVER, false); + m_debugMenu->Enable(MENU_ID_CONTINUE, false); + m_debugMenu->Enable(MENU_ID_TOGGLE_BREAK, false); + m_debugMenu->Enable(MENU_ID_CLEAR_ALL_BREAK, false); + m_debugMenu->Enable(MENU_ID_STOP, false); + m_menuBar->Append(m_debugMenu, _("&Debug")); + + m_viewMenu = new wxMenu; + m_viewMenu->Append(MENU_ID_VIEW_OUTPUTPANE, _("&Output pane\tCtrl-Alt-O"), _("Show or hide the output pane."), wxITEM_CHECK); + m_viewMenu->Append(MENU_ID_VIEW_STACKPANE, _("&Stack pane\tCtrl-Alt-S"), _("Show or hide the stack pane."), wxITEM_CHECK); + m_viewMenu->Append(MENU_ID_VIEW_TOOLBAR, _("&Tool bar\tCtrl-Alt-T"), _("Show or hide the tool bar."), wxITEM_CHECK); + m_viewMenu->AppendSeparator(); + m_viewMenu->Append(MENU_ID_VIEW_DEFAULTVIEW, _("&Default view\tCtrl-Alt-V"), _("Restore the default view.")); + m_viewMenu->Enable(MENU_ID_VIEW_OUTPUTPANE, false); + m_viewMenu->Enable(MENU_ID_VIEW_STACKPANE, false); + m_menuBar->Append(m_viewMenu, _("&View")); + + wxMenu *helpMenu = new wxMenu(); + helpMenu->Append(MNU_CONTENTS, _("&Help"), _("Open the helpfile.")); + helpMenu->Append(MNU_HELP, _("&SQL Help\tF1"), _("Display help on SQL commands.")); + m_menuBar->Append(helpMenu, _("&Help")); + + SetMenuBar(m_menuBar); + + return(m_menuBar); +} + +//////////////////////////////////////////////////////////////////////////////// +// OnClose() +// +// wxWidgets invokes this event handler when the user closes the main window + +void frmDebugger::OnClose(wxCloseEvent &_ev) +{ + if (!m_controller->CanRestart() && _ev.CanVeto()) + { + if (wxMessageBox( + _("Are you sure you wish to abort the debugging session?\nThis will abort the function currently being debugged."), + _("Close debugger"), wxICON_QUESTION | wxYES_NO) != wxYES) + { + _ev.Veto(); + + return; + } + } + + if (!m_controller->CloseDebugger() && _ev.CanVeto()) + { + _ev.Veto(); + + return; + } + + _ev.Skip(); +} + +//////////////////////////////////////////////////////////////////////////////// +// OnExit() +// +// Close the debugger + +void frmDebugger::OnExit(wxCommandEvent &event) +{ + Close(); +} + + +//////////////////////////////////////////////////////////////////////////////// +// OnToggleToolBar() +// +// Turn the tool bar on or off +void frmDebugger::OnToggleToolBar(wxCommandEvent &event) +{ + if (m_viewMenu->IsChecked(MENU_ID_VIEW_TOOLBAR)) + m_manager.GetPane(wxT("toolBar")).Show(true); + else + m_manager.GetPane(wxT("toolBar")).Show(false); + + m_manager.Update(); +} + +//////////////////////////////////////////////////////////////////////////////// +// OnToggleStackPane() +// +// Turn the tool bar on or off +void frmDebugger::OnToggleStackPane(wxCommandEvent &event) +{ + if (m_viewMenu->IsChecked(MENU_ID_VIEW_STACKPANE)) + m_manager.GetPane(wxT("stackPane")).Show(true); + else + m_manager.GetPane(wxT("stackPane")).Show(false); + + m_manager.Update(); +} + +//////////////////////////////////////////////////////////////////////////////// +// OnToggleOutputPane() +// +// Turn the tool bar on or off +void frmDebugger::OnToggleOutputPane(wxCommandEvent &event) +{ + if (m_viewMenu->IsChecked(MENU_ID_VIEW_OUTPUTPANE)) + m_manager.GetPane(wxT("outputPane")).Show(true); + else + m_manager.GetPane(wxT("outputPane")).Show(false); + + m_manager.Update(); +} + +//////////////////////////////////////////////////////////////////////////////// +// OnAuiUpdate() +// +// Update the view menu to reflect AUI changes +void frmDebugger::OnAuiUpdate(wxAuiManagerEvent &event) +{ + if(event.pane->name == wxT("toolBar")) + { + m_viewMenu->Check(MENU_ID_VIEW_TOOLBAR, false); + } + else if(event.pane->name == wxT("stackPane")) + { + m_viewMenu->Check(MENU_ID_VIEW_STACKPANE, false); + } + else if(event.pane->name == wxT("outputPane")) + { + m_viewMenu->Check(MENU_ID_VIEW_OUTPUTPANE, false); + } + event.Skip(); +} + +//////////////////////////////////////////////////////////////////////////////// +// OnDefaultView() +// +// Reset the AUI view to the default +void frmDebugger::OnDefaultView(wxCommandEvent &event) +{ + m_manager.LoadPerspective(FRMDEBUGGER_DEFAULT_PERSPECTIVE, true); + + // Reset the captions for the current language + m_manager.GetPane(wxT("toolBar")).Caption(_("Toolbar")); + m_manager.GetPane(wxT("stackPane")).Caption(_("Stack pane")); + m_manager.GetPane(wxT("outputPane")).Caption(_("Output pane")); + + // tell the m_manager to "commit" all the changes just made + m_manager.Update(); + + // Sync the View menu options + m_viewMenu->Check(MENU_ID_VIEW_TOOLBAR, m_manager.GetPane(wxT("toolBar")).IsShown()); + m_viewMenu->Check(MENU_ID_VIEW_STACKPANE, m_manager.GetPane(wxT("stackPane")).IsShown()); + m_viewMenu->Check(MENU_ID_VIEW_OUTPUTPANE, m_manager.GetPane(wxT("outputPane")).IsShown()); +} + + +void frmDebugger::HighlightLine(int _lineNo) +{ + int lineNo = m_codeViewer->MarkerNext( + 0, MARKERINDEX_TO_MARKERMASK( MARKER_CURRENT)); + + if (lineNo != -1) + { + m_codeViewer->MarkerDelete(lineNo, MARKER_CURRENT); + m_codeViewer->MarkerDelete(lineNo, MARKER_CURRENT_BG); + } + + // Add the current-line indicator to the current line of code + m_codeViewer->MarkerAdd(_lineNo, MARKER_CURRENT); + m_codeViewer->MarkerAdd(_lineNo, MARKER_CURRENT_BG); + + // Scroll the source code listing (if required) to make sure + // that this line of code is visible + // + // (NOTE: we set the anchor and the caret to the same position to avoid + // creating a selection region) + int pos = m_codeViewer->PositionFromLine(_lineNo); + + m_codeViewer->SetAnchor(pos); + m_codeViewer->SetCurrentPos(pos); + + m_codeViewer->EnsureCaretVisible(); +} + +void frmDebugger::DisplaySource(dbgCachedStack &_cached) +{ + dbgModel *model = m_controller->GetModel(); + + m_codeViewer->SetFocus(); + + if (model->RequireDisplayUpdate()) + { + ctlVarWindow *varWin = NULL; + if ((varWin = GetVarWindow(false)) != NULL) + { + varWin->DelVar(); + } + if ((varWin = GetParamWindow(false)) != NULL) + { + varWin->DelVar(); + } + if ((varWin = GetPkgVarWindow(false)) != NULL) + { + varWin->DelVar(); + } + + model->GetDisplayedFunction() = _cached.m_func; + model->GetDisplayedPackage() = _cached.m_pkg; + + // Now erase any old code and write out the new listing + m_codeViewer->SetReadOnly(false); + + m_codeViewer->SetText(_cached.m_source); + m_codeViewer->Colourise(0, _cached.m_source.Length()); + + m_codeViewer->SetReadOnly(true); + } + HighlightLine(model->GetCurrLineNo()); +} + + +void frmDebugger::SetStatusText(const wxString &_status) +{ + m_statusBar->SetStatusText(_status, 0); +} + + +void frmDebugger::LaunchWaitingDialog(const wxString &msg) +{ + dbgModel *model = m_controller->GetModel(); + wxString strStatus, + strTargetPid = model->GetTargetPid(), + strTarget = model->GetTarget()->GetQualifiedName(); + + if (msg.IsEmpty()) + { + if (strTargetPid != wxT("NULL")) + { + strStatus = + wxString::Format( + _("Waiting for the session (pid:%s) to invoke the specified targets."), + strTargetPid.c_str()); + } + else + { + strStatus = + wxString::Format( + _("Waiting for another session to invoke the target - \"%s\""), strTarget.c_str()); + } + } + else + { + strStatus = msg; + } + m_statusTxt = strStatus; + + SetStatusText(strStatus); + m_statusBar->ShowProgress(); +} + + +void frmDebugger::CloseProgressBar() +{ + if (!m_statusTxt.IsEmpty()) + { + SetStatusText(m_statusTxt + wxT(" Done")); + m_statusTxt = wxT(""); + } + m_statusBar->StopProgress(); +} diff --git a/debugger/module.mk b/debugger/module.mk new file mode 100644 index 0000000..afb13ec --- /dev/null +++ b/debugger/module.mk @@ -0,0 +1,30 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/debugger/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + debugger/ctlMessageWindow.cpp \ + debugger/ctlResultGrid.cpp \ + debugger/ctlStackWindow.cpp \ + debugger/ctlTabWindow.cpp \ + debugger/ctlVarWindow.cpp \ + debugger/dbgBreakPoint.cpp \ + debugger/dbgController.cpp \ + debugger/dbgEvents.cpp \ + debugger/dbgModel.cpp \ + debugger/dbgTargetInfo.cpp \ + debugger/debugger.cpp \ + debugger/dlgDirectDbg.cpp \ + debugger/frmDebugger.cpp + +EXTRA_DIST += \ + debugger/module.mk + + diff --git a/dlg/dlgAddFavourite.cpp b/dlg/dlgAddFavourite.cpp new file mode 100644 index 0000000..061083c --- /dev/null +++ b/dlg/dlgAddFavourite.cpp @@ -0,0 +1,185 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgAddFavourite.cpp - Add a favourite +// +////////////////////////////////////////////////////////////////////////// + + + +// App headers +#include "pgAdmin3.h" + +#include "dlg/dlgAddFavourite.h" +#include "db/pgConn.h" +#include "schema/pgServer.h" +#include "utils/sysLogger.h" +#include "ctl/ctlTree.h" + +#include "images/folder.pngc" + +#include "utils/favourites.h" + +#include + +BEGIN_EVENT_TABLE(dlgAddFavourite, pgDialog) + EVT_TEXT(XRCID("txtTitle"), dlgAddFavourite::OnChange) + EVT_TREE_SEL_CHANGED(XRCID("trLocation"), dlgAddFavourite::OnTreeChange) + EVT_BUTTON (wxID_OK, dlgAddFavourite::OnOK) + EVT_BUTTON (wxID_CANCEL, dlgAddFavourite::OnCancel) + EVT_BUTTON (XRCID("btnNewFolder"), dlgAddFavourite::OnNewFolder) +END_EVENT_TABLE() + + +#define btnOK CTRL_BUTTON("wxID_OK") +#define txtTitle CTRL_TEXT("txtTitle") +#define trLocation CTRL_TREE("trLocation") +#define btnNewFolder CTRL_BUTTON("btnNewFolder") + + +dlgAddFavourite::dlgAddFavourite(wxWindow *parent, queryFavouriteFolder *favourites) : + pgDialog() +{ + SetFont(settings->GetSystemFont()); + LoadResource(parent, wxT("dlgAddFavourite")); + RestorePosition(); + + anythingChanged = false; + + this->favourites = favourites; + + wxImageList *imgList = new wxImageList(16, 16, true, 2); + imgList->Add(*folder_png_ico); + trLocation->AssignImageList(imgList); + + trLocation->AddRoot(_("Favourites"), 0); + trLocation->SelectItem(trLocation->GetRootItem()); + favourites->AppendAllToTree(trLocation, trLocation->GetRootItem(), true); + trLocation->Expand(trLocation->GetRootItem()); +} + +int dlgAddFavourite::AddFavourite(wxString newtext) +{ + int ret = 1; + int r = ShowModal(); + if (r != wxID_OK) + { + if (anythingChanged) + // Need rollback! + ret = -1; + else + ret = 0; + } + + wxString title = txtTitle->GetValue().Trim(); + if (title.IsEmpty()) + { + if (anythingChanged) + // Need rollback! + ret = -1; + else + ret = 0; + } + + if (!trLocation->GetSelection().IsOk()) + { + if (anythingChanged) + // Need rollback! + ret = -1; + else + ret = 0; + } + + queryFavouriteFolder *fld = (queryFavouriteFolder *)favourites->FindTreeItem(trLocation->GetSelection()); + + if (!fld) + { + if (anythingChanged) + // Need rollback! + ret = -1; + else + ret = 0; + } + + if (r == wxID_OK) + fld->AddNewFavourite(title, newtext); + return ret; +} + +dlgAddFavourite::~dlgAddFavourite() +{ + SavePosition(); +} + + +void dlgAddFavourite::OnOK(wxCommandEvent &ev) +{ +#ifdef __WXGTK__ + if (!btnOK->IsEnabled()) + return; +#endif + EndModal(wxID_OK); +} + + +void dlgAddFavourite::OnCancel(wxCommandEvent &ev) +{ + EndModal(wxID_CANCEL); +} + +void dlgAddFavourite::OnChange(wxCommandEvent &ev) +{ + bool ok = true; + + if (txtTitle->GetValue().Trim().IsEmpty()) + ok = false; + else if (!trLocation->GetSelection().IsOk()) + ok = false; + else if (favourites->FindTreeItem(trLocation->GetSelection()) == NULL) + ok = false; + + btnOK->Enable(ok); +} + +void dlgAddFavourite::OnTreeChange(wxTreeEvent &ev) +{ + wxCommandEvent evt; + OnChange(evt); +} + +void dlgAddFavourite::OnNewFolder(wxCommandEvent &ev) +{ + if (!trLocation->GetSelection().IsOk()) + return; + + queryFavouriteItem *item = favourites->FindTreeItem(trLocation->GetSelection()); + if (!item) + return; + if (item->GetId() != -2) + return; + + wxTextEntryDialog dlg(this, _("Enter name of new folder"), _("Create new favourites folder")); + if (dlg.ShowModal() != wxID_OK) + return; + + wxString title = dlg.GetValue().Trim(); + if (title.IsEmpty()) + return; + + queryFavouriteFolder *fld = (queryFavouriteFolder *)item; + if (fld->ContainsFolder(title)) + { + wxMessageBox(_("A folder with the specified name already exists.")); + return; + } + + + queryFavouriteFolder *newfld = fld->AddNewFolder(dlg.GetValue()); + newfld->SetTreeId(trLocation->AppendItem(trLocation->GetSelection(), title, 0)); + trLocation->Expand(fld->GetTreeId()); + anythingChanged = true; +} diff --git a/dlg/dlgAggregate.cpp b/dlg/dlgAggregate.cpp new file mode 100644 index 0000000..1c62f55 --- /dev/null +++ b/dlg/dlgAggregate.cpp @@ -0,0 +1,594 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgAggregate.cpp - Aggregate properties dialog +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgAggregate.h" +#include "schema/pgSchema.h" +#include "schema/pgAggregate.h" +#include "schema/pgDatatype.h" +#include "ctl/ctlSeclabelPanel.h" +#include "frm/frmMain.h" +#include "schema/pgUser.h" +#include "schema/pgGroup.h" + +#include "images/aggregate.pngc" + +// pointer to controls +#define cbInputType CTRL_COMBOBOX2("cbInputType") +#define lstInputTypes CTRL_LISTCTRL("lstInputTypes") +#define cbStateType CTRL_COMBOBOX2("cbStateType") +#define cbStateFunc CTRL_COMBOBOX("cbStateFunc") +#define cbFinalFunc CTRL_COMBOBOX("cbFinalFunc") +#define cbSortOp CTRL_COMBOBOX("cbSortOp") +#define txtInitial CTRL_TEXT("txtInitial") +#define btnAddType CTRL_BUTTON("btnAddType") +#define btnRemoveType CTRL_BUTTON("btnRemoveType") + +dlgProperty *pgAggregateFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgAggregate(this, frame, (pgAggregate *)node, (pgSchema *)parent); +} + +BEGIN_EVENT_TABLE(dlgAggregate, dlgTypeProperty) + EVT_TEXT(XRCID("cbInputType"), dlgAggregate::OnChangeTypeBase) + EVT_TEXT(XRCID("cbStateType"), dlgAggregate::OnChangeTypeState) + EVT_COMBOBOX(XRCID("cbStateType"), dlgAggregate::OnChangeType) + EVT_COMBOBOX(XRCID("cbStateFunc"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbSortOp"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbStateFunc"), dlgProperty::OnChange) + EVT_BUTTON(XRCID("btnAddType"), dlgAggregate::OnAddInputType) + EVT_BUTTON(XRCID("btnRemoveType"), dlgAggregate::OnRemoveInputType) + EVT_LIST_ITEM_SELECTED(XRCID("lstInputTypes"), dlgAggregate::OnSelectInputType) + EVT_BUTTON(CTL_ADDPRIV, dlgAggregate::OnAddPriv) + EVT_BUTTON(CTL_DELPRIV, dlgAggregate::OnDelPriv) +#ifdef __WXMAC__ + EVT_SIZE( dlgAggregate::OnChangeSize) +#endif +END_EVENT_TABLE(); + +dlgAggregate::dlgAggregate(pgaFactory *f, frmMain *frame, pgAggregate *agg, pgSchema *sch) + : dlgTypeProperty(f, frame, wxT("dlgAggregate")) +{ + schema = sch; + aggregate = agg; + seclabelPage = new ctlSeclabelPanel(nbNotebook); + + /* Aggregate Privileges */ + securityChanged = false; + if (agg) + connection = agg->GetConnection(); + securityPage = new ctlSecurityPanel(nbNotebook, wxT("EXECUTE"), "X", frame->GetImageList()); + if (connection && (!agg || agg->CanCreate())) + { + // Fetch Groups Information + pgSet *setGrp = connection->ExecuteSet(wxT("SELECT groname FROM pg_group ORDER BY groname")); + + if (setGrp) + { + while (!setGrp->Eof()) + { + groups.Add(setGrp->GetVal(0)); + setGrp->MoveNext(); + } + delete setGrp; + } + + if (agg) + { + wxString strAcl = agg->GetAcl(); + if (!strAcl.IsEmpty()) + { + wxArrayString aclArray; + strAcl = strAcl.Mid(1, strAcl.Length() - 2); + getArrayFromCommaSeparatedList(strAcl, aclArray); + wxString roleName; + for (unsigned int index = 0; index < aclArray.Count(); index++) + { + wxString strCurrAcl = aclArray[index]; + + /* + * In rare case, we can have ',' (comma) in the user name. + * But, we need to handle them also + */ + if (strCurrAcl.Find(wxChar('=')) == wxNOT_FOUND) + { + // Check it is start of the ACL + if (strCurrAcl[0U] == (wxChar)'"') + roleName = strCurrAcl + wxT(","); + continue; + } + else + strCurrAcl = roleName + strCurrAcl; + + if (strCurrAcl[0U] == (wxChar)'"') + strCurrAcl = strCurrAcl.Mid(1, strCurrAcl.Length() - 1); + roleName = strCurrAcl.BeforeLast('='); + + wxString value = strCurrAcl.Mid(roleName.Length() + 1).BeforeLast('/'); + + int icon = userFactory.GetIconId(); + + if (roleName.Left(6).IsSameAs(wxT("group "), false)) + { + icon = groupFactory.GetIconId(); + roleName = wxT("group ") + qtStrip(roleName.Mid(6)); + } + else if (roleName.IsEmpty()) + { + icon = PGICON_PUBLIC; + roleName = wxT("public"); + } + else + { + roleName = qtStrip(roleName); + for (unsigned int index = 0; index < groups.Count(); index++) + if (roleName == groups[index]) + { + roleName = wxT("group ") + roleName; + icon = groupFactory.GetIconId(); + break; + } + } + + securityPage->lbPrivileges->AppendItem(icon, roleName, value); + currentAcl.Add(roleName + wxT("=") + value); + + // Reset roleName + roleName.Empty(); + } + } + } + } + else + securityPage->Disable(); +} + +pgObject *dlgAggregate::GetObject() +{ + return aggregate; +} + +int dlgAggregate::Go(bool modal) +{ + if (!connection->BackendMinimumVersion(8, 0)) + cbOwner->Disable(); + + if (!connection->BackendMinimumVersion(8, 1)) + cbSortOp->Disable(); + + if (connection->BackendMinimumVersion(9, 1)) + { + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(aggregate); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgAggregate::OnChange)); + } + else + seclabelPage->Disable(); + + lstInputTypes->InsertColumn(0, _("Input types"), wxLIST_FORMAT_LEFT, lstInputTypes->GetSize().x - 10); + + if (aggregate) + { + // edit mode + txtName->Enable(connection->BackendMinimumVersion(7, 4)); + cbSchema->Enable(connection->BackendMinimumVersion(8, 1)); + + for (unsigned int x = 0; x < aggregate->GetInputTypesArray().Count(); x++ ) + { + lstInputTypes->InsertItem(x, aggregate->GetInputTypesArray().Item(x)); + AddType(wxT(" "), 0, aggregate->GetInputTypesArray().Item(x)); + } + + cbStateType->Append(aggregate->GetStateType()); + cbStateType->SetSelection(0); + + cbStateFunc->Append(aggregate->GetStateFunction()); + cbStateFunc->SetSelection(0); + cbFinalFunc->Append(aggregate->GetFinalFunction()); + cbFinalFunc->SetSelection(0); + + cbSortOp->Append(aggregate->GetSortOp()); + cbSortOp->SetSelection(0); + + txtInitial->SetValue(aggregate->GetInitialCondition()); + + cbInputType->Disable(); + btnAddType->Disable(); + btnRemoveType->Disable(); + cbStateFunc->Disable(); + cbStateType->Disable(); + cbFinalFunc->Disable(); + cbSortOp->Disable(); + txtInitial->Disable(); + } + else + { + // create mode + AddType(wxT(" "), PGOID_TYPE_ANY, wxT("\"any\"")); + cbInputType->Append(wxT("ANY")); + + FillDatatype(cbInputType, cbStateType, false); + btnRemoveType->Disable(); + } + + securityPage->SetConnection(connection); + + if (securityPage->cbGroups) + { + // Fetch Groups Information + for ( unsigned int index = 0; index < groups.Count();) + securityPage->cbGroups->Append(wxT("group ") + groups[index++]); + + // Fetch Users Information + if (settings->GetShowUsersForPrivileges()) + { + securityPage->stGroup->SetLabel(_("Group/User")); + dlgProperty::AddUsers(securityPage->cbGroups); + } + } + securityPage->lbPrivileges->GetParent()->Layout(); + + return dlgProperty::Go(modal); +} + +pgObject *dlgAggregate::CreateObject(pgCollection *collection) +{ + pgObject *obj = aggregateFactory.CreateObjects(collection, 0, + wxT("\n AND proname=") + qtDbString(GetName()) + + wxT("\n AND pronamespace=") + schema->GetOidStr()); + + return obj; +} + +#ifdef __WXMAC__ +void dlgAggregate::OnChangeSize(wxSizeEvent &ev) +{ + lstInputTypes->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350); + securityPage->lbPrivileges->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 550); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + +void dlgAggregate::CheckChange() +{ + bool enable = true; + if (aggregate) + { + enable = GetName() != aggregate->GetName() + || cbSchema->GetValue() != aggregate->GetSchema()->GetName() + || txtComment->GetValue() != aggregate->GetComment() + || cbOwner->GetValue() != aggregate->GetOwner(); + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); + } + else + { + // For pre 8.2 servers, we can only have one input type. + if (!connection->BackendMinimumVersion(8, 2)) + { + if (lstInputTypes->GetItemCount() >= 1) + btnAddType->Disable(); + else + btnAddType->Enable(); + } + + // Multi parameter aggregates cannot have sort ops. + if (connection->BackendMinimumVersion(8, 2)) + { + if (lstInputTypes->GetItemCount() > 1) + { + cbSortOp->SetValue(wxEmptyString); + cbSortOp->Disable(); + } + else + cbSortOp->Enable(); + } + + wxString name = GetName(); + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, cbStateType->GetGuessedSelection() >= 0, _("Please select state datatype.")); + CheckValid(enable, cbStateFunc->GetCurrentSelection() >= 0, _("Please specify state function.")); + } + EnableOK(enable || securityChanged); +} + +void dlgAggregate::OnChangeTypeBase(wxCommandEvent &ev) +{ + cbInputType->GuessSelection(ev); + OnChangeType(ev); +} + +void dlgAggregate::OnChangeTypeState(wxCommandEvent &ev) +{ + cbStateType->GuessSelection(ev); + OnChangeType(ev); +} + +void dlgAggregate::OnChangeType(wxCommandEvent &ev) +{ + cbStateFunc->Clear(); + cbFinalFunc->Clear(); + cbSortOp->Clear(); + + pgSet *set; + wxString qry; + + // Get the possible state functions. They must return the state type, and take + // input_types + 1 parameters, the first of which is of the state type. + // If there are no input_types specified, assume "ANY" for a count(*) style aggregate. + if (lstInputTypes->GetItemCount() > 0 && cbStateType->GetGuessedSelection() >= 0) + { + set = connection->ExecuteSet( + wxT("SELECT proname, nspname, prorettype\n") + wxT(" FROM pg_proc p\n") + wxT(" JOIN pg_type t ON t.oid=p.prorettype\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE prorettype = ") + GetTypeOid(cbStateType->GetGuessedSelection() + 1) + + wxT("\n AND prokind <> 'a'") + wxT("\n AND proargtypes = '") + GetTypeOid(cbStateType->GetGuessedSelection() + 1) + wxT(" ") + GetInputTypesOidList() + wxT("'")); + + if (set) + { + while (!set->Eof()) + { + cbStateFunc->Append(database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")), + database->GetQuotedSchemaPrefix(set->GetVal(wxT("nspname"))) + qtIdent(set->GetVal(wxT("proname")))); + + set->MoveNext(); + } + delete set; + } + + // Get the possible final_func options. This may be nothing, or a + // function taking an argument of state_type + cbFinalFunc->Append(wxT(" ")); + + set = connection->ExecuteSet( + wxT("SELECT proname, nspname, prorettype\n") + wxT(" FROM pg_proc p\n") + wxT(" JOIN pg_type t ON t.oid=p.prorettype\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE proisagg = FALSE") + wxT("\n AND proargtypes = '") + GetTypeOid(cbStateType->GetGuessedSelection() + 1) + wxT("'")); + + if (set) + { + while (!set->Eof()) + { + cbFinalFunc->Append(database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")), + database->GetQuotedSchemaPrefix(set->GetVal(wxT("nspname"))) + qtIdent(set->GetVal(wxT("proname")))); + + set->MoveNext(); + } + delete set; + } + + // Get the sort operators. This is only valid for a single arguement operator. + cbSortOp->Append(wxT(" "), wxEmptyString); + + set = connection->ExecuteSet( + wxT("SELECT oprname, nspname\n") + wxT(" FROM pg_operator op\n") + wxT(" JOIN pg_namespace nsp on nsp.oid=oprnamespace\n") + wxT(" WHERE oprleft = ") + NumToStr(GetInputTypeOid(0)) + wxT("\n") + wxT(" AND oprright = ") + NumToStr(GetInputTypeOid(0)) + wxT("\n")); + + if (set) + { + while (!set->Eof()) + { + wxString key = database->GetQuotedSchemaPrefix(set->GetVal(wxT("nspname"))) + qtIdent(set->GetVal(wxT("oprname"))); + wxString txt = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("oprname")); + cbSortOp->Append(txt, key); + set->MoveNext(); + } + delete set; + } + } + + CheckChange(); +} + +wxString dlgAggregate::GetSql() +{ + wxString sql, name; + + if (aggregate) + { + // edit mode + name = schema->GetQuotedPrefix() + qtIdent(GetName()) + wxT("(") + GetInputTypesList() + wxT(")"); + + AppendNameChange(sql, wxT("AGGREGATE ") + aggregate->GetQuotedFullName()); + AppendOwnerChange(sql, wxT("AGGREGATE ") + name); + AppendSchemaChange(sql, wxT("AGGREGATE ") + name); + } + else + { + // create mode + name = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()); + + if (connection->BackendMinimumVersion(8, 2)) + { + sql = wxT("CREATE AGGREGATE ") + name + + wxT("(") + GetInputTypesList() + wxT(") (\n"); + } + else + { + sql = wxT("CREATE AGGREGATE ") + name + + wxT("(\n BASETYPE=") + GetInputTypesList() + wxT(",\n"); + } + + sql += wxT(" SFUNC=") + cbStateFunc->GetStringKey() + + wxT(",\n STYPE=") + GetQuotedTypename(cbStateType->GetGuessedSelection() + 1); // skip "any" type + + if (cbFinalFunc->GetCurrentSelection() > 0) + { + sql += wxT(",\n FINALFUNC=") + + cbFinalFunc->GetStringKey(); + } + wxString initial = txtInitial->GetValue().Strip(wxString::both); + if (!initial.IsEmpty()) + { + if (initial == wxT("''")) // Empty string + sql += wxT(",\n INITCOND=''"); + else if (initial == wxT("\\'\\'")) // Pair of quotes + sql += wxT(",\n INITCOND=''''''"); + else + sql += wxT(",\n INITCOND=") + qtDbString(initial); + } + + if (!cbSortOp->GetValue().IsEmpty()) + { + wxString opr = cbSortOp->GetStringKey(); + if (!opr.IsEmpty()) + sql += wxT(",\n SORTOP=") + opr; + } + + sql += wxT("\n);\n"); + + AppendOwnerNew(sql, wxT("AGGREGATE ") + name + wxT("(") + GetInputTypesList() + wxT(")")); + } + + AppendComment(sql, wxT("AGGREGATE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()) + + wxT("(") + GetInputTypesList() + wxT(")"), aggregate); + + sql += securityPage->GetGrant(wxT("X"), + wxT("FUNCTION ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()) + wxT("(") + GetInputTypesList() + wxT(")"), + ¤tAcl); + + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + sql += seclabelPage->GetSqlForSecLabels(wxT("AGGREGATE"), + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()) + + wxT("(") + GetInputTypesList() + wxT(")")); + + return sql; +} + +// Return the list of input types +wxString dlgAggregate::GetInputTypesList() +{ + wxString types; + + for (int i = 0; i < lstInputTypes->GetItemCount(); i++) + { + if (i > 0) + types += wxT(", "); + + if (lstInputTypes->GetItemText(i) == wxT("ANY") || lstInputTypes->GetItemText(i) == wxT("*")) + return wxT("*"); + else + types += qtTypeIdent(lstInputTypes->GetItemText(i)); + } + return types; +} + +void dlgAggregate::OnAddInputType(wxCommandEvent &ev) +{ + if (cbInputType->GetValue() != wxEmptyString) + { + if (cbInputType->GetValue() == wxT("ANY") && lstInputTypes->GetItemCount() > 0) + { + wxLogError(_("The ANY pseudo-datatype cannot be used in multi parameter aggregates.")); + return; + } + + wxListItem itm; + itm.SetMask(wxLIST_MASK_DATA | wxLIST_MASK_TEXT); + + itm.SetData(StrToLong(GetTypeOid(cbInputType->GetGuessedSelection()))); + itm.SetText(cbInputType->GetValue()); + + lstInputTypes->InsertItem(itm); + + if (cbInputType->GetValue() == wxT("ANY")) + btnAddType->Disable(); + + OnChangeType(ev); + } +} + +void dlgAggregate::OnRemoveInputType(wxCommandEvent &ev) +{ + long pos = lstInputTypes->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);; + if (pos >= 0) + { + lstInputTypes->DeleteItem(pos); + + OnChangeType(ev); + btnRemoveType->Disable(); + + // Re-enable the Add button, in case it was disabled because + // ANY was specified. + btnAddType->Enable(); + } +} + +void dlgAggregate::OnSelectInputType(wxListEvent &ev) +{ + if (!aggregate) + btnRemoveType->Enable(); +} + +// Returnt the datatype OID for the given parameter number +long dlgAggregate::GetInputTypeOid(int param) +{ + wxListItem itm; + itm.SetMask(wxLIST_MASK_DATA | wxLIST_MASK_TEXT); + itm.SetId(param); + + lstInputTypes->GetItem(itm); + + return itm.GetData(); +} + +// Return the list of datatype OIDs +wxString dlgAggregate::GetInputTypesOidList() +{ + wxString types; + + for (int i = 0; i < lstInputTypes->GetItemCount(); i++) + { + if (i > 0) + types += wxT(" "); + + types += NumToStr(GetInputTypeOid(i)); + } + return types; +} + +void dlgAggregate::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} + +void dlgAggregate::OnAddPriv(wxCommandEvent &ev) +{ + securityChanged = true; + CheckChange(); +} + +void dlgAggregate::OnDelPriv(wxCommandEvent &ev) +{ + securityChanged = true; + CheckChange(); +} diff --git a/dlg/dlgCast.cpp b/dlg/dlgCast.cpp new file mode 100644 index 0000000..7b67215 --- /dev/null +++ b/dlg/dlgCast.cpp @@ -0,0 +1,216 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgCast.cpp - PostgreSQL Operator Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgCast.h" +#include "schema/pgCast.h" +#include "schema/pgDatatype.h" + + +// pointer to controls +#define txtCastname CTRL_TEXT("txtCastname") +#define cbSourceType CTRL_COMBOBOX2("cbSourceType") +#define cbTargetType CTRL_COMBOBOX2("cbTargetType") +#define cbFunction CTRL_COMBOBOX("cbFunction") +#define chkImplicit CTRL_CHECKBOX("chkImplicit") +#define stComment CTRL_STATIC("stComment") + +dlgProperty *pgCastFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgCast(this, frame, (pgCast *)node); +} + + +BEGIN_EVENT_TABLE(dlgCast, dlgTypeProperty) + EVT_TEXT(XRCID("cbSourceType"), dlgCast::OnChangeTypeSrc) + EVT_COMBOBOX(XRCID("cbSourceType"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbTargetType"), dlgCast::OnChangeTypeTrg) + EVT_COMBOBOX(XRCID("cbTargetType"), dlgProperty::OnChange) +END_EVENT_TABLE(); + + +dlgCast::dlgCast(pgaFactory *f, frmMain *frame, pgCast *node) + : dlgTypeProperty(f, frame, wxT("dlgCast")) +{ + cast = node; + + txtCastname->Disable(); +} + + +pgObject *dlgCast::GetObject() +{ + return cast; +} + + +int dlgCast::Go(bool modal) +{ + + if (!connection->BackendMinimumVersion(7, 5)) + txtComment->Disable(); + + if (cast) + { + // edit mode + cbSourceType->Append(cast->GetSourceType()); + cbSourceType->SetSelection(0); + cbSourceType->Disable(); + + cbTargetType->Append(wxEmptyString); + cbTargetType->Append(cast->GetTargetType()); + cbTargetType->SetSelection(1); + cbTargetType->Disable(); + + AddType(wxT(" "), cast->GetSourceTypeOid()); + AddType(wxT(" "), cast->GetTargetTypeOid()); + + cbFunction->Append(cast->GetCastFunction()); + cbFunction->SetSelection(0); + + cbFunction->Disable(); + chkImplicit->Disable(); + } + else + { + // create mode + FillDatatype(cbSourceType, cbTargetType, false); + } + + return dlgProperty::Go(modal); +} + + +pgObject *dlgCast::CreateObject(pgCollection *collection) +{ + pgObject *obj = castFactory.CreateObjects(collection, 0, + wxT(" WHERE castsource = ") + GetTypeOid(cbSourceType->GetGuessedSelection()) + + wxT("\n AND casttarget = ") + GetTypeOid(cbTargetType->GetGuessedSelection())); + + return obj; +} + + +void dlgCast::CheckChange() +{ + if (cast) + { + EnableOK(txtComment->GetValue() != cast->GetComment()); + } + else + { + bool enable = true; + CheckValid(enable, cbSourceType->GetGuessedSelection() > 0, _("Please specify source datatype.")); + CheckValid(enable, cbTargetType->GetGuessedSelection() > 0, _("Please select target datatype.")); + + if (enable) + txtCastname->SetValue(cbSourceType->GetValue() + wxT(" -> ") + cbTargetType->GetValue()); + else + txtCastname->SetValue(wxEmptyString); + + EnableOK(enable); + } +} + + +void dlgCast::OnChangeTypeSrc(wxCommandEvent &ev) +{ + cbSourceType->GuessSelection(ev); + OnChangeType(ev); +} + +void dlgCast::OnChangeTypeTrg(wxCommandEvent &ev) +{ + cbTargetType->GuessSelection(ev); + OnChangeType(ev); +} + + +void dlgCast::OnChangeType(wxCommandEvent &ev) +{ + functions.Clear(); + cbFunction->Clear(); + + if (cbSourceType->GetGuessedSelection() > 0 && cbTargetType->GetGuessedSelection() > 0) + { + functions.Add(wxEmptyString); + cbFunction->Append(wxT(" ")); + + wxString qry = + wxT("SELECT proname, nspname\n") + wxT(" FROM pg_proc p\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE proargtypes[0] = ") + + GetTypeOid(cbSourceType->GetGuessedSelection()) + + wxT("\n AND CASE ") + + wxT("\n WHEN array_length(proargtypes, 1) = 2 THEN") + + wxT("\n proargtypes[1] = 23") + + wxT("\n WHEN array_length(proargtypes, 1) >= 3 THEN") + + wxT("\n proargtypes[1] = 23 AND proargtypes[2] = 16") + + wxT("\n ELSE true END") + + wxT("\n AND prorettype = ") + + GetTypeOid(cbTargetType->GetGuessedSelection()); + pgSet *set = connection->ExecuteSet(qry); + if (set) + { + while (!set->Eof()) + { + functions.Add(database->GetQuotedSchemaPrefix(set->GetVal(wxT("nspname"))) + qtIdent(set->GetVal(wxT("proname")))); + cbFunction->Append(database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname"))); + + set->MoveNext(); + } + delete set; + } + } + + CheckChange(); +} + + +wxString dlgCast::GetSql() +{ + wxString sql; + + if (cast) + { + // edit mode + } + else + { + // create mode + sql = wxT("CREATE CAST (") + cbSourceType->GetValue() + + wxT(" AS ") + cbTargetType->GetValue() + + wxT(")\n "); + if (cbFunction->GetCurrentSelection() > 0) + sql += wxT("WITH FUNCTION ") + functions.Item(cbFunction->GetCurrentSelection()) + + wxT("(") + cbSourceType->GetValue() + wxT(")"); + else + sql += wxT("WITHOUT FUNCTION"); + + if (chkImplicit->GetValue()) + sql += wxT("\n AS IMPLICIT"); + + sql += wxT(";\n"); + + } + AppendComment(sql, wxT("CAST (") + cbSourceType->GetValue() + + wxT(" AS ") + cbTargetType->GetValue() + wxT(")"), cast); + + return sql; +} diff --git a/dlg/dlgCheck.cpp b/dlg/dlgCheck.cpp new file mode 100644 index 0000000..44ddd2f --- /dev/null +++ b/dlg/dlgCheck.cpp @@ -0,0 +1,185 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgCheck.cpp - PostgreSQL Check Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "frm/frmMain.h" +#include "schema/pgObject.h" +#include "schema/pgCheck.h" +#include "dlg/dlgCheck.h" + +#define txtWhere CTRL_TEXT("txtWhere") +#define chkNoInherit CTRL_CHECKBOX("chkNoInherit") +#define chkDontValidate CTRL_CHECKBOX("chkDontValidate") + + +BEGIN_EVENT_TABLE(dlgCheck, dlgProperty) + EVT_TEXT(XRCID("txtWhere"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkDontValidate"), dlgCheck::OnChangeValidate) +END_EVENT_TABLE(); + + +dlgProperty *pgCheckFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgCheck(this, frame, (pgCheck *)node, parent); +} + + +dlgCheck::dlgCheck(pgaFactory *f, frmMain *frame, pgCheck *node, pgObject *parentNode) + : dlgProperty(f, frame, wxT("dlgCheck")) +{ + check = node; + object = parentNode; +} + +void dlgCheck::CheckChange() +{ + bool enable = true; + if (check) + { + enable = txtName->GetValue() != check->GetName() || txtComment->GetValue() != check->GetComment(); + if (connection->BackendMinimumVersion(9, 2) && !check->GetValid() && !chkDontValidate->GetValue()) + enable = true; + EnableOK(enable); + } + else + { + // We don't allow changing the comment if the dialog is launched from dlgTable or dlgDomain + // so we check IsModal() + txtComment->Enable(!GetName().IsEmpty() && !IsModal() && object->GetTypeName().Upper() == wxT("TABLE")); + CheckValid(enable, !txtWhere->GetValue().IsEmpty(), _("Please specify condition.")); + EnableOK(enable); + } +} + + +pgObject *dlgCheck::GetObject() +{ + return check; +} + + +pgObject *dlgCheck::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + if (name.IsEmpty()) + return 0; + + pgObject *obj = checkFactory.CreateObjects(collection, 0, wxT( + "\n AND conname=") + qtDbString(name) + wxT( + "\n AND relnamespace=") + object->GetSchema()->GetOidStr()); + return obj; +} + + +int dlgCheck::Go(bool modal) +{ + if (check) + { + // edit mode + txtName->Enable(connection->BackendMinimumVersion(9, 2)); + txtComment->Enable(object->GetTypeName().Upper() == wxT("TABLE")); + + txtWhere->SetValue(check->GetDefinition()); + txtWhere->Disable(); + + if (connection->BackendMinimumVersion(9, 2)) + { + chkNoInherit->SetValue(check->GetNoInherit()); + chkDontValidate->SetValue(!check->GetValid()); + } + else + chkDontValidate->SetValue(true); + chkDontValidate->Enable(connection->BackendMinimumVersion(9, 2) && !check->GetDefinition().IsEmpty() && !check->GetValid()); + } + else + { + // create mode + txtComment->Disable(); + if (!object) + { + cbClusterSet->Disable(); + cbClusterSet = 0; + } + chkDontValidate->Enable(connection->BackendMinimumVersion(9, 2)); + } + + chkNoInherit->Enable(connection->BackendMinimumVersion(9, 2) && !check); + + return dlgProperty::Go(modal); +} + + +void dlgCheck::OnChangeValidate(wxCommandEvent &ev) +{ + CheckChange(); +} + + +wxString dlgCheck::GetSql() +{ + wxString sql; + wxString name = GetName(); + + if (!check) + { + sql = wxT("ALTER ") + object->GetTypeName().Upper() + wxT(" ") + object->GetQuotedFullIdentifier() + + wxT("\n ADD"); + if (name.Length() > 0) + { + sql += wxT(" CONSTRAINT ") + qtIdent(name) + wxT("\n "); + } + sql += wxT(" CHECK "); + sql += GetDefinition(); + if (connection->BackendMinimumVersion(9, 2) && chkNoInherit->GetValue()) + { + sql += wxT(" NO INHERIT"); + } + sql += wxT(";\n"); + } + else + { + if (check->GetName() != name) + { + sql = wxT("ALTER ") + object->GetTypeName().Upper() + wxT(" ") + object->GetQuotedFullIdentifier() + + wxT("\n RENAME CONSTRAINT ") + qtIdent(check->GetName()) + + wxT(" TO ") + qtIdent(name) + wxT(";\n"); + } + if (connection->BackendMinimumVersion(9, 2) && !check->GetValid() && !chkDontValidate->GetValue()) + { + sql += wxT("ALTER ") + object->GetTypeName().Upper() + wxT(" ") + object->GetQuotedFullIdentifier() + + wxT("\n VALIDATE CONSTRAINT ") + qtIdent(name) + wxT(";\n"); + } + } + + if (!name.IsEmpty()) + AppendComment(sql, wxT("CONSTRAINT ") + qtIdent(name) + + wxT(" ON ") + object->GetQuotedFullIdentifier(), check); + return sql; +} + + +wxString dlgCheck::GetDefinition() +{ + wxString sql; + + sql = wxT("(") + txtWhere->GetValue() + wxT(")"); + + if (chkDontValidate->GetValue()) + sql += wxT(" NOT VALID"); + + return sql; +} diff --git a/dlg/dlgClasses.cpp b/dlg/dlgClasses.cpp new file mode 100644 index 0000000..7e5cdfc --- /dev/null +++ b/dlg/dlgClasses.cpp @@ -0,0 +1,778 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgClasses.cpp - Some dialogue base classes +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include +#include + + +// App headers +#include "pgAdmin3.h" +#include "frm/frmMain.h" +#include "db/pgConn.h" +#include "schema/pgObject.h" +#include "schema/pgDatabase.h" +#include "utils/sysProcess.h" +#include "frm/menu.h" +#include "db/pgQueryThread.h" + +#include +WX_DEFINE_LIST(windowList); + +#define STATUSBAR_XRCNAME wxT("unkStatusBar") +#define STATUSBAR_CONTAINER STATUSBAR_XRCNAME wxT("_container") + + +BEGIN_EVENT_TABLE(pgDialog, wxDialog) + EVT_BUTTON (wxID_CANCEL, pgDialog::OnCancel) + EVT_CLOSE( pgDialog::OnClose) +END_EVENT_TABLE() + + + +void pgDialog::AddStatusBar() +{ + if (!statusBar) + { + long flags = 0; + if (GetWindowStyle() & wxRESIZE_BORDER) + flags = wxST_SIZEGRIP; + statusBar = new wxStatusBar(this, -1, flags); + + wxWindow *statusBarContainer = FindWindow(STATUSBAR_CONTAINER); + + if (statusBarContainer) + { + wxXmlResource::Get()->AttachUnknownControl(STATUSBAR_XRCNAME, statusBar); + } + else + { + int sbHeight = statusBar->GetSize().y; + wxSize size = GetSize(); + size.y += sbHeight; + SetSize(size); + + size = GetClientSize(); + statusBar->Move(0, size.y - sbHeight); + } + } +} + + +void pgDialog::PostCreation() +{ + if (!statusBar && FindWindow(STATUSBAR_CONTAINER)) + AddStatusBar(); + + if (GetWindowStyle() & wxRESIZE_BORDER) // is designed with sizers; don't change + return; + + if (!btnCancel) + return; + + wxSize size = btnCancel->GetSize(); + wxPoint pos = btnCancel->GetPosition(); + int height = pos.y + size.GetHeight() + ConvertDialogToPixels(wxSize(0, 3)).y; + if (statusBar) + height += statusBar->GetSize().GetHeight(); + + int right = pos.x + ConvertDialogToPixels(wxSize(50, 0)).x - size.GetWidth(); + btnCancel->Move(right, pos.y); + + if (btnOK) + { + size = btnOK->GetSize(); + right -= size.GetWidth() + ConvertDialogToPixels(wxSize(3, 0)).x; + btnOK->Move(right, pos.y); + } + +// On OS X, reverse the buttons for UI consistency +#ifdef __WXMAC__ + wxPoint pos2; + pos = btnCancel->GetPosition(); + + if (btnOK) + { + pos2 = btnOK->GetPosition(); + btnOK->Move(pos.x, pos.y); + } + + btnCancel->Move(pos2.x, pos2.y); +#endif + + int w, h; + size = GetSize(); + GetClientSize(&w, &h); + + SetSize(size.GetWidth(), size.GetHeight() + height - h); +} + + +void pgDialog::RestorePosition(int defaultX, int defaultY, int defaultW, int defaultH, int minW, int minH) +{ + if (minW == -1) + minW = GetSize().GetX(); + + if (minH == -1) + minH = GetSize().GetY(); + + wxPoint pos(settings->Read(dlgName, wxPoint(defaultX, defaultY))); + wxSize size; + + if ((this->GetWindowStyle() & wxRESIZE_BORDER) == wxRESIZE_BORDER) + { + if (defaultW < 0) + size = settings->Read(dlgName, GetSize()); + else + size = settings->Read(dlgName, wxSize(defaultW, defaultH)); + } + else + { + size = GetSize(); + } + + bool posDefault = (pos.x == -1 && pos.y == -1); + + CheckOnScreen(this, pos, size, minW, minH); + SetSize(pos.x, pos.y, size.x, size.y); + if (posDefault) + CenterOnParent(); +} + +void pgDialog::SavePosition() +{ +#ifndef __WXGTK__ + if (!IsIconized()) + { +#endif + wxPoint pos = GetPosition(); + if (pos.x < 0) + pos.x = 0; + if (pos.y < 0) + pos.y = 0; + settings->WriteSizePoint(dlgName, GetSize(), pos); +#ifndef __WXGTK__ + } +#endif +} + +void pgDialog::LoadResource(wxWindow *parent, const wxChar *name) +{ + if (name) + dlgName = name; + wxXmlResource::Get()->LoadDialog(this, parent, dlgName); + PostCreation(); +} + + + +void pgDialog::OnClose(wxCloseEvent &event) +{ + if (IsModal()) + EndModal(wxID_CANCEL); + else + Destroy(); +} + + +void pgDialog::OnCancel(wxCommandEvent &ev) +{ + if (IsModal()) + EndModal(wxID_CANCEL); + else + Destroy(); +} + + +/////////////////////////////////////////////////////////////////////////////////////// + + +BEGIN_EVENT_TABLE(pgFrame, wxFrame) + EVT_MENU(MNU_EXIT, pgFrame::OnExit) + EVT_MENU(MNU_RECENT + 1, pgFrame::OnRecent) + EVT_MENU(MNU_RECENT + 2, pgFrame::OnRecent) + EVT_MENU(MNU_RECENT + 3, pgFrame::OnRecent) + EVT_MENU(MNU_RECENT + 4, pgFrame::OnRecent) + EVT_MENU(MNU_RECENT + 5, pgFrame::OnRecent) + EVT_MENU(MNU_RECENT + 6, pgFrame::OnRecent) + EVT_MENU(MNU_RECENT + 7, pgFrame::OnRecent) + EVT_MENU(MNU_RECENT + 8, pgFrame::OnRecent) + EVT_MENU(MNU_RECENT + 9, pgFrame::OnRecent) +#ifdef __WXGTK__ + EVT_KEY_DOWN( pgFrame::OnKeyDown) +#endif +END_EVENT_TABLE() + + +pgFrame::pgFrame(wxFrame *parent, const wxString &title, const wxPoint &pos, const wxSize &size, long flags) + : wxFrame(parent, -1, title, pos, size, flags) +{ + changed = false; + recentFileMenu = 0; + menuFactories = 0; +} + + +pgFrame::~pgFrame() +{ + if (!dlgName.IsEmpty()) + SavePosition(); + if (menuFactories) + delete menuFactories; + +} + + +void pgFrame::RemoveFrame(wxWindow *frame) +{ + frames.DeleteObject(frame); +} + + +void pgFrame::OnAction(wxCommandEvent &ev) +{ + actionFactory *af = menuFactories->GetFactory(ev.GetId()); + if (af) + { + wxWindow *wnd = af->StartDialog((frmMain *)this, 0); + if (wnd) + AddFrame(wnd); + } +} + + +// Event handlers +void pgFrame::OnKeyDown(wxKeyEvent &event) +{ + event.m_metaDown = false; + event.Skip(); +} + + +void pgFrame::OnExit(wxCommandEvent &event) +{ + Close(); +} + + +void pgFrame::OnHelp(wxCommandEvent &WXUNUSED(event)) +{ + wxString page = GetHelpPage(); + DisplayHelp(page, HELP_PGADMIN); +} + + +void pgFrame::OnRecent(wxCommandEvent &event) +{ + int fileNo = event.GetId() - MNU_RECENT; + wxString newPath = settings->Read(recentKey + wxString::Format(wxT("/%d"), fileNo), wxT("")); + + if (!newPath.IsNull()) + { + if (CheckChanged(true)) + return; + + lastPath = newPath; + int dirsep; + dirsep = lastPath.Find(wxFILE_SEP_PATH, true); + lastDir = lastPath.Mid(0, dirsep); + lastFilename = lastPath.Mid(dirsep + 1); + OpenLastFile(); + } +} + + + +void pgFrame::UpdateRecentFiles(bool updatefile) +{ + if (!recentFileMenu) + return; + + if (recentKey.IsEmpty()) + recentKey = dlgName + wxT("/RecentFiles"); + + wxString lastFiles[10]; // 0 will be unused for convenience + int i, maxFiles = 9; + int recentIndex = maxFiles; + + for (i = 1 ; i <= maxFiles ; i++) + { + lastFiles[i] = settings->Read(recentKey + wxString::Format(wxT("/%d"), i), wxT("")); + if (!lastPath.IsNull() && lastPath.IsSameAs(lastFiles[i], wxARE_FILENAMES_CASE_SENSITIVE)) + recentIndex = i; + } + while (i <= maxFiles) + lastFiles[i++] = wxT(""); + + if (recentIndex > 1 && !lastPath.IsNull() && updatefile) + { + for (i = recentIndex ; i > 1 ; i--) + lastFiles[i] = lastFiles[i - 1]; + lastFiles[1] = lastPath; + } + + i = recentFileMenu->GetMenuItemCount(); + while (i) + { + wxMenuItem *item = recentFileMenu->Remove(MNU_RECENT + i); + if (item) + delete item; + i--; + } + + for (i = 1 ; i <= maxFiles ; i++) + { + if (updatefile) + settings->Write(recentKey + wxString::Format(wxT("/%d"), i), lastFiles[i]); + + if (!lastFiles[i].IsNull()) + recentFileMenu->Append(MNU_RECENT + i, wxT("&") + wxString::Format(wxT("%d"), i) + wxT(" ") + lastFiles[i]); + } +} + + +void pgFrame::RestorePosition(int defaultX, int defaultY, int defaultW, int defaultH, int minW, int minH) +{ + bool maximized = false; + wxPoint pos(settings->Read(dlgName, wxPoint(defaultX, defaultY))); + wxSize size; + if (defaultW < 0) + size = GetSize(); + else + size = settings->Read(dlgName, wxSize(defaultW, defaultH)); + + bool posDefault = (pos.x == -1 && pos.y == -1); + + CheckOnScreen(this, pos, size, minW, minH); + SetSize(pos.x, pos.y, size.x, size.y); + if (posDefault) + CenterOnParent(); + + settings->Read(dlgName + wxT("/Maximized"), &maximized, false); + if (maximized) + Maximize(); +} + + +void pgFrame::SavePosition() +{ +#ifndef __WXGTK__ + if (!IsIconized()) + { +#endif + wxPoint pos = GetPosition(); + if (pos.x < 0) + pos.x = 0; + if (pos.y < 0) + pos.y = 0; + settings->WriteSizePoint(dlgName, GetSize(), pos); + settings->WriteBool(dlgName + wxT("/Maximized"), IsMaximized()); +#ifndef __WXGTK__ + } +#endif +} + + + +////////////////////////////////////////////////////// + +BEGIN_EVENT_TABLE(DialogWithHelp, pgDialog) + EVT_MENU(MNU_HELP, DialogWithHelp::OnHelp) + EVT_BUTTON(wxID_HELP, DialogWithHelp::OnHelp) +END_EVENT_TABLE(); + + +DialogWithHelp::DialogWithHelp(frmMain *frame) : pgDialog() +{ + mainForm = frame; + + wxAcceleratorEntry entries[2]; + entries[0].Set(wxACCEL_NORMAL, WXK_F1, MNU_HELP); +// this is for GTK because Meta (usually Numlock) is interpreted like Alt +// there are too many controls to reset m_Meta in all of them + entries[1].Set(wxACCEL_ALT, WXK_F1, MNU_HELP); + wxAcceleratorTable accel(2, entries); + + SetAcceleratorTable(accel); +} + + +void DialogWithHelp::OnHelp(wxCommandEvent &ev) +{ + wxString page = GetHelpPage(); + + if (!page.IsEmpty()) + { + if (page.StartsWith(wxT("pg/"))) + DisplayHelp(page.Mid(3), HELP_POSTGRESQL); + else if (page.StartsWith(wxT("slony/"))) + DisplayHelp(page.Mid(6), HELP_SLONY); + else + DisplayHelp(page, HELP_PGADMIN); + } +} + + + +////////////////////////////////////////////////////////////////77 + + +BEGIN_EVENT_TABLE(ExecutionDialog, DialogWithHelp) + EVT_BUTTON (wxID_OK, ExecutionDialog::OnOK) + EVT_BUTTON (wxID_CANCEL, ExecutionDialog::OnCancel) + EVT_CLOSE( ExecutionDialog::OnClose) +END_EVENT_TABLE() + + +ExecutionDialog::ExecutionDialog(frmMain *frame, pgObject *_object) : DialogWithHelp(frame) +{ + thread = 0; + object = _object; + txtMessages = 0; + bIsAborted = false; + bIsExecutionStarted = false; + bIsExecutionCompleted = false; + + pgDatabase *db = object->GetDatabase(); + wxString applicationname = appearanceFactory->GetLongAppName() + _(" - Execution Tool"); + conn = db->CreateConn(applicationname); +} + +void ExecutionDialog::EnableOK(const bool enable) +{ + btnOK->Enable(enable); +} + + +void ExecutionDialog::OnClose(wxCloseEvent &event) +{ + Abort(); + // If execution is started and not yet complete it means thread is still + // running, so we should not delete the connection object and destroy the dialog. + if(bIsExecutionStarted && !bIsExecutionCompleted) + return; + + delete conn; + if (IsModal()) + EndModal(-1); + else + Destroy(); +} + + +void ExecutionDialog::OnCancel(wxCommandEvent &ev) +{ + if (thread) + { + btnCancel->Disable(); + Abort(); + btnCancel->Enable(); + btnOK->Enable(); + } + else + { + delete conn; + if (IsModal()) + EndModal(-1); + else + Destroy(); + } +} + + +void ExecutionDialog::Abort() +{ + // If bIsAborted is true it means abort is still in progress + if (thread && !bIsAborted) + { + bIsAborted = true; + if (thread->IsRunning()) + { + thread->CancelExecution(); + thread->Wait(); + } + + delete thread; + thread = 0; + } +} + + +void ExecutionDialog::OnOK(wxCommandEvent &ev) +{ +#ifdef __WXGTK__ + if (!btnOK->IsEnabled()) + return; +#endif + if (!thread) + { + wxString sql = GetSql(); + if (sql.IsEmpty()) + return; + + btnOK->Disable(); + // Reset the variables + bIsAborted = false; + bIsExecutionStarted = false; + bIsExecutionCompleted = false; + + thread = new pgQueryThread(conn, sql); + if (thread->Create() != wxTHREAD_NO_ERROR) + { + Abort(); + return; + } + + wxLongLong startTime = wxGetLocalTimeMillis(); + thread->Run(); + // When execution is started then set the variable + bIsExecutionStarted = true; + wxNotebook *nb = CTRL_NOTEBOOK("nbNotebook"); + if (nb) + nb->SetSelection(nb->GetPageCount() - 1); + + while (thread && thread->IsRunning()) + { + wxMilliSleep(10); + // here could be the animation + if (txtMessages) + { + wxString msg = thread->GetMessagesAndClear(); + if (!msg.IsEmpty()) + txtMessages->AppendText(msg + wxT("\n")); + } + + wxTheApp->Yield(true); + } + + if (thread) + { + bool isOk = (thread->ReturnCode() == PGRES_COMMAND_OK || thread->ReturnCode() == PGRES_TUPLES_OK); + + if (txtMessages) + { + txtMessages->AppendText(thread->GetMessagesAndClear()); + } + + if (thread->DataSet() != NULL) + { + wxLogInfo(wxString::Format(wxT("%d rows."), thread->DataSet()->NumRows())); + } + + if (isOk) + { + if (txtMessages) + txtMessages->AppendText( + _("Total query runtime: ") + + ElapsedTimeToStr( + wxGetLocalTimeMillis() - startTime + ) + ); + + btnOK->SetLabel(_("Done")); + btnCancel->Disable(); + } + else + { + if (txtMessages) + txtMessages->AppendText(conn->GetLastError()); + Abort(); + } + } + else if (txtMessages) + txtMessages->AppendText(_("\nCancelled.\n")); + + btnOK->Enable(); + bIsExecutionCompleted = true; + } + else + { + Abort(); + delete conn; + Destroy(); + } +} + + + +#define TIMER_ID 4442 + +BEGIN_EVENT_TABLE(ExternProcessDialog, DialogWithHelp) + EVT_BUTTON(wxID_OK, ExternProcessDialog::OnOK) + EVT_BUTTON(wxID_CANCEL, ExternProcessDialog::OnCancel) + EVT_CLOSE( ExternProcessDialog::OnClose) + EVT_END_PROCESS(-1, ExternProcessDialog::OnEndProcess) + EVT_TIMER(TIMER_ID, ExternProcessDialog::OnPollProcess) +END_EVENT_TABLE() + + + +ExternProcessDialog::ExternProcessDialog(frmMain *frame) : DialogWithHelp(frame) +{ + txtMessages = 0; + process = 0; + done = false; + processID = 0; + + timer = new wxTimer(this, TIMER_ID); +} + + + +ExternProcessDialog::~ExternProcessDialog() +{ + Abort(); + delete timer; +} + + +void ExternProcessDialog::OnOK(wxCommandEvent &ev) +{ +#ifdef __WXGTK__ + if (!btnOK->IsEnabled()) + return; +#endif + if (!done) + Execute(0); + else + { + Abort(); + pgDialog::OnCancel(ev); + } +} + + +bool ExternProcessDialog::Execute(int step, bool finalStep) +{ + btnOK->Disable(); + final = finalStep; + + if (txtMessages) + txtMessages->AppendText(GetDisplayCmd(step) + END_OF_LINE); + + if (process) + { + delete process; + process = NULL; + processID = 0; + } + + process = new sysProcess(this); + process->SetEnvironment(environment); + + processID = wxExecute(GetCmd(step), wxEXEC_ASYNC, process); + + if (processID) + { + wxNotebook *nb = CTRL_NOTEBOOK("nbNotebook"); + if (nb) + nb->SetSelection(nb->GetPageCount() - 1); + if (txtMessages) + { + checkStreams(); + timer->Start(100L); + } + return true; + } + else + { + delete process; + process = NULL; + processID = 0; + return false; + } +} + + +void ExternProcessDialog::OnCancel(wxCommandEvent &ev) +{ + if (process) + { + btnCancel->Disable(); + Abort(); + wxMilliSleep(100); + if (txtMessages) + txtMessages->AppendText(END_OF_LINE + wxString(_("Cancelled on user request.")) + END_OF_LINE + END_OF_LINE); + } + else + pgDialog::OnCancel(ev); +} + + +void ExternProcessDialog::OnClose(wxCloseEvent &ev) +{ + btnCancel->Disable(); + Abort(); + pgDialog::OnClose(ev); +} + + +void ExternProcessDialog::OnPollProcess(wxTimerEvent &event) +{ + checkStreams(); +} + + +void ExternProcessDialog::checkStreams() +{ + if (txtMessages && process) + { + txtMessages->AppendText(process->ReadErrorStream()); + txtMessages->AppendText(process->ReadInputStream()); + } +} + + +void ExternProcessDialog::OnEndProcess(wxProcessEvent &ev) +{ + if (process) + { + if (!ev.GetExitCode()) + { + if (final) + btnOK->SetLabel(_("Done")); + done = true; + } + } + timer->Stop(); + + if (txtMessages) + { + checkStreams(); + txtMessages->AppendText(END_OF_LINE + + wxString::Format(_("Process returned exit code %d."), ev.GetExitCode()) + + END_OF_LINE); + } + + if (process) + { + delete process; + processID = 0; + process = 0; + } + btnOK->Enable(); + btnCancel->Enable(); +} + + +void ExternProcessDialog::Abort() +{ + timer->Stop(); + if (process) + { + done = false; + // Kill the child process started with wxExecute in Execute method + wxKill(processID); + processID = 0; + } +} + diff --git a/dlg/dlgCollation.cpp b/dlg/dlgCollation.cpp new file mode 100644 index 0000000..47ad3c7 --- /dev/null +++ b/dlg/dlgCollation.cpp @@ -0,0 +1,187 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgCollation.cpp - PostgreSQL Collation Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgCollation.h" +#include "schema/pgSchema.h" +#include "schema/pgCollation.h" +#include "schema/pgDatatype.h" + + +// pointer to controls +#define txtLocale CTRL_TEXT("txtLocale") +#define txtLcCollate CTRL_TEXT("txtLcCollate") +#define txtLcCtype CTRL_TEXT("txtLcCtype") +#define cbCollation CTRL_COMBOBOX2("cbCollation") + + +BEGIN_EVENT_TABLE(dlgCollation, dlgTypeProperty) + EVT_TEXT(XRCID("txtLocale"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtLcCollate"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtLcCtype"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbCollation"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbCollation"), dlgProperty::OnChange) +END_EVENT_TABLE(); + + +dlgProperty *pgCollationFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgCollation(this, frame, (pgCollation *)node, (pgSchema *)parent); +} + + +dlgCollation::dlgCollation(pgaFactory *f, frmMain *frame, pgCollation *node, pgSchema *sch) + : dlgTypeProperty(f, frame, wxT("dlgCollation")) +{ + schema = sch; + collation = node; +} + + +pgObject *dlgCollation::GetObject() +{ + return collation; +} + + +int dlgCollation::Go(bool modal) +{ + if (collation) + { + // edit mode + txtLcCollate->SetValue(collation->GetLcCollate()); + txtLcCtype->SetValue(collation->GetLcCtype()); + + txtLocale->Disable(); + txtLcCollate->Disable(); + txtLcCtype->Disable(); + cbCollation->Disable(); + } + else + { + // create mode + // fill collation combobox + cbCollation->Append(wxEmptyString); + pgSet *set = connection->ExecuteSet( + wxT("SELECT nspname, collname\n") + wxT(" FROM pg_collation c, pg_namespace n\n") + wxT(" WHERE c.collnamespace=n.oid\n") + wxT(" ORDER BY nspname, collname")); + if (set) + { + while (!set->Eof()) + { + wxString name = qtIdent(set->GetVal(wxT("nspname"))) + wxT(".") + qtIdent(set->GetVal(wxT("collname"))); + cbCollation->Append(name); + set->MoveNext(); + } + delete set; + } + cbCollation->SetSelection(0); + } + + return dlgProperty::Go(modal); +} + + +pgObject *dlgCollation::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + pgObject *obj = collationFactory.CreateObjects(collection, 0, + wxT(" AND c.collname=") + qtDbString(name) + + wxT("\n AND c.collnamespace=") + schema->GetOidStr() + + wxT("\n")); + return obj; +} + + +void dlgCollation::CheckChange() +{ + if (collation) + { + EnableOK(txtName->GetValue() != collation->GetName() + || cbSchema->GetValue() != collation->GetSchema()->GetName() + || cbOwner->GetValue() != collation->GetOwner() + || txtComment->GetValue() != collation->GetComment()); + } + else + { + bool enable = true; + CheckValid(enable, !GetName().IsEmpty(), _("Please specify name.")); + CheckValid(enable, + !txtLocale->GetValue().IsEmpty() || + !(txtLcCollate->GetValue().IsEmpty() && txtLcCtype->GetValue().IsEmpty()) || + !cbCollation->GetValue().IsEmpty(), + _("Please specify a locale, or LC_COLLATE and LC_CTYPE, or a collation")); + + txtLocale->Enable(cbCollation->GetValue().IsEmpty() && txtLcCollate->GetValue().IsEmpty() && txtLcCtype->GetValue().IsEmpty()); + txtLcCollate->Enable(cbCollation->GetValue().IsEmpty() && txtLocale->GetValue().IsEmpty()); + txtLcCtype->Enable(cbCollation->GetValue().IsEmpty() && txtLocale->GetValue().IsEmpty()); + cbCollation->Enable(txtLocale->GetValue().IsEmpty() && txtLcCollate->GetValue().IsEmpty() && txtLcCtype->GetValue().IsEmpty()); + + EnableOK(enable); + } +} + + +wxString dlgCollation::GetSql() +{ + wxString sql; + wxString name; + + if (collation) + { + // edit mode + name = schema->GetQuotedPrefix() + qtIdent(GetName());; + AppendNameChange(sql, wxT("COLLATION ") + collation->GetQuotedFullIdentifier()); + AppendOwnerChange(sql, wxT("COLLATION ") + name); + AppendSchemaChange(sql, wxT("COLLATION ") + name); + } + else + { + // create mode + name = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()); + + sql = wxT("CREATE COLLATION ") + name; + if (cbCollation->GetValue().IsEmpty()) + { + if (txtLocale->GetValue().IsEmpty()) + { + sql += wxT("(LC_COLLATE=") + qtDbString(txtLcCollate->GetValue()) + + wxT(", LC_CTYPE=") + qtDbString(txtLcCtype->GetValue()) + + wxT(")"); + } + else + { + sql += wxT("(LOCALE=") + qtDbString(txtLocale->GetValue()) + wxT(")"); + } + } + else + { + sql += wxT(" FROM ") + cbCollation->GetValue(); + } + sql += wxT(";\n"); + + AppendOwnerNew(sql, wxT("COLLATION ") + schema->GetQuotedPrefix() + qtIdent(name)); + } + AppendComment(sql, wxT("COLLATION ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), collation); + + return sql; +} + diff --git a/dlg/dlgColumn.cpp b/dlg/dlgColumn.cpp new file mode 100644 index 0000000..be68a67 --- /dev/null +++ b/dlg/dlgColumn.cpp @@ -0,0 +1,915 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgColumns.cpp - PostgreSQL Columns Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgColumn.h" +#include "schema/pgSchema.h" +#include "schema/pgColumn.h" +#include "schema/pgTable.h" +#include "schema/pgDatatype.h" +#include "frm/frmMain.h" +#include "schema/pgUser.h" +#include "schema/pgGroup.h" +#include "ctl/ctlSeclabelPanel.h" + + +// pointer to controls +#define txtDefault CTRL_TEXT("txtDefault") +#define chkNotNull CTRL_CHECKBOX("chkNotNull") +#define txtAttstattarget CTRL_TEXT("txtAttstattarget") +#define lstVariables CTRL_LISTVIEW("lstVariables") +#define cbVarname CTRL_COMBOBOX2("cbVarname") +#define txtValue CTRL_TEXT("txtValue") +#define btnAdd CTRL_BUTTON("wxID_ADD") +#define btnRemove CTRL_BUTTON("wxID_REMOVE") +#define cbStorage CTRL_COMBOBOX1("cbStorage") +#define cbCollation CTRL_COMBOBOX("cbCollation") + + +BEGIN_EVENT_TABLE(dlgColumn, dlgTypeProperty) + EVT_TEXT(XRCID("txtLength"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtPrecision"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtDefault"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkNotNull"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtAttstattarget"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbDatatype"), dlgColumn::OnSelChangeTyp) + EVT_COMBOBOX(XRCID("cbDatatype"), dlgColumn::OnSelChangeTyp) + EVT_COMBOBOX(XRCID("cbCollation"), dlgColumn::OnSelChangeTyp) + EVT_BUTTON(CTL_ADDPRIV, dlgColumn::OnAddPriv) + EVT_BUTTON(CTL_DELPRIV, dlgColumn::OnDelPriv) + EVT_LIST_ITEM_SELECTED(XRCID("lstVariables"), dlgColumn::OnVarSelChange) + EVT_BUTTON(wxID_ADD, dlgColumn::OnVarAdd) + EVT_BUTTON(wxID_REMOVE, dlgColumn::OnVarRemove) + EVT_TEXT(XRCID("cbVarname"), dlgColumn::OnVarnameSelChange) + EVT_COMBOBOX(XRCID("cbVarname"), dlgColumn::OnVarnameSelChange) + EVT_TEXT(XRCID("cbStorage"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbStorage"), dlgProperty::OnChange) + +#ifdef __WXMAC__ + EVT_SIZE( dlgColumn::OnChangeSize) +#endif +END_EVENT_TABLE(); + + +dlgProperty *pgColumnFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgColumn(this, frame, (pgColumn *)node, (pgTable *)parent); +} + + +dlgColumn::dlgColumn(pgaFactory *f, frmMain *frame, pgColumn *node, pgTable *parentNode) + : dlgTypeProperty(f, frame, wxT("dlgColumn")) +{ + column = node; + table = parentNode; + wxASSERT(!table || (table->GetMetaType() == PGM_TABLE || table->GetMetaType() == PGM_VIEW || table->GetMetaType() == GP_EXTTABLE || table->GetMetaType() == GP_PARTITION)); + + changedColumn = NULL; + + dirtyVars = false; + + txtAttstattarget->SetValidator(numericValidator); + + lstVariables->CreateColumns(0, _("Variable"), _("Value")); + + cbStorage->Append(wxT("PLAIN")); + cbStorage->Append(wxT("MAIN")); + cbStorage->Append(wxT("EXTERNAL")); + cbStorage->Append(wxT("EXTENDED")); + + /* Column Level Privileges */ + securityChanged = false; + if (node) + connection = node->GetConnection(); + securityPage = new ctlSecurityPanel(nbNotebook, wxT("INSERT,SELECT,UPDATE,REFERENCES"), "arwx", frame->GetImageList()); + if (connection && connection->BackendMinimumVersion(8, 4) && (!node || node->CanCreate())) + { + // Fetch Groups Information + pgSet *setGrp = connection->ExecuteSet(wxT("SELECT groname FROM pg_group ORDER BY groname")); + + if (setGrp) + { + while (!setGrp->Eof()) + { + groups.Add(setGrp->GetVal(0)); + setGrp->MoveNext(); + } + delete setGrp; + } + + SetSecurityPage(node); + } + else + securityPage->Disable(); + + seclabelPage = new ctlSeclabelPanel(nbNotebook); +} + + +#ifdef __WXMAC__ +void dlgColumn::OnChangeSize(wxSizeEvent &ev) +{ + securityPage->lbPrivileges->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 550); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + +pgObject *dlgColumn::GetObject() +{ + return column; +} + +void dlgColumn::SetSecurityPage(const pgColumn *node) +{ + if (node) + { + wxString strAcl = node->GetAcl(); + securityPage->lbPrivileges->DeleteAllItems(); + if (!strAcl.IsEmpty()) + { + wxArrayString aclArray; + strAcl = strAcl.Mid(1, strAcl.Length() - 2); + getArrayFromCommaSeparatedList(strAcl, aclArray); + wxString roleName; + for (unsigned int index = 0; index < aclArray.Count(); index++) + { + wxString strCurrAcl = aclArray[index]; + + /* + * In rare case, we can have ',' (comma) in the user name. + * But, we need to handle them also + */ + if (strCurrAcl.Find(wxChar('=')) == wxNOT_FOUND) + { + // Check it is start of the ACL + if (strCurrAcl[0U] == (wxChar)'"') + roleName = strCurrAcl + wxT(","); + continue; + } + else + strCurrAcl = roleName + strCurrAcl; + + if (strCurrAcl[0U] == (wxChar)'"') + strCurrAcl = strCurrAcl.Mid(1, strCurrAcl.Length() - 1); + roleName = strCurrAcl.BeforeLast('='); + + wxString value = strCurrAcl.Mid(roleName.Length() + 1).BeforeLast('/'); + + int icon = userFactory.GetIconId(); + + if (roleName.Left(6).IsSameAs(wxT("group "), false)) + { + icon = groupFactory.GetIconId(); + roleName = wxT("group ") + qtStrip(roleName.Mid(6)); + } + else if (roleName.IsEmpty()) + { + icon = PGICON_PUBLIC; + roleName = wxT("public"); + } + else + { + roleName = qtStrip(roleName); + for (unsigned int index = 0; index < groups.Count(); index++) + if (roleName == groups[index]) + { + roleName = wxT("group ") + roleName; + icon = groupFactory.GetIconId(); + break; + } + } + + securityPage->lbPrivileges->AppendItem(icon, roleName, value); + + if(changedColumn == NULL) + currentAcl.Add(roleName + wxT("=") + value); + + // Reset roleName + roleName.Empty(); + } + } + } +} + +int dlgColumn::Go(bool modal) +{ + if (connection->BackendMinimumVersion(8, 4)) + { + securityPage->SetConnection(connection); + + if (securityPage->cbGroups) + { + // Fetch Groups Information + for ( unsigned int index = 0; index < groups.Count();) + securityPage->cbGroups->Append(wxT("group ") + groups[index++]); + + // Fetch Users Information + if (settings->GetShowUsersForPrivileges()) + { + securityPage->stGroup->SetLabel(_("Group/User")); + dlgProperty::AddUsers(securityPage->cbGroups); + Layout(); + } + } + securityPage->lbPrivileges->GetParent()->Layout(); + } + + if (connection->BackendMinimumVersion(8, 5)) + { + cbVarname->Append(wxT("n_distinct")); + cbVarname->Append(wxT("n_distinct_inherited")); + cbVarname->SetSelection(0); + } + else + { + lstVariables->Enable(false); + btnAdd->Enable(false); + btnRemove->Enable(false); + cbVarname->Enable(false); + txtValue->Enable(false); + } + + if (connection->BackendMinimumVersion(9, 1)) + { + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(column); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgColumn::OnChange)); + } + else + seclabelPage->Disable(); + + cbStorage->Enable(true); + + if (connection->BackendMinimumVersion(9, 1)) + { + // fill collation combobox + cbCollation->Append(wxEmptyString); + pgSet *set = connection->ExecuteSet( + wxT("SELECT nspname, collname\n") + wxT(" FROM pg_collation c, pg_namespace n\n") + wxT(" WHERE c.collnamespace=n.oid\n") + wxT(" ORDER BY nspname, collname")); + if (set) + { + while (!set->Eof()) + { + wxString name = qtIdent(set->GetVal(wxT("nspname"))) + wxT(".") + qtIdent(set->GetVal(wxT("collname"))); + cbCollation->Append(name); + set->MoveNext(); + } + delete set; + } + cbCollation->SetSelection(0); + } + else + cbCollation->Disable(); + + if (column) + { + // edit mode + if (column->GetLength() > 0) + txtLength->SetValue(NumToStr(column->GetLength())); + if (column->GetPrecision() >= 0) + txtPrecision->SetValue(NumToStr(column->GetPrecision())); + txtDefault->SetValue(column->GetDefault()); + chkNotNull->SetValue(column->GetNotNull()); + txtAttstattarget->SetValue(NumToStr(column->GetAttstattarget())); + + wxString fullType = column->GetRawTypename(); + if (column->GetIsArray()) + fullType += wxT("[]"); + cbDatatype->Append(fullType); + AddType(wxT("?"), column->GetAttTypId(), fullType); + + if (!column->IsReferenced()) + { + wxString typeSql = + wxT("SELECT tt.oid, format_type(tt.oid,NULL) AS typname\n") + wxT(" FROM pg_cast\n") + wxT(" JOIN pg_type tt ON tt.oid=casttarget\n") + wxT(" WHERE castsource=") + NumToStr(column->GetAttTypId()) + wxT("\n"); + + if (connection->BackendMinimumVersion(8, 0)) + typeSql += wxT(" AND castcontext IN ('i', 'a')"); + else + typeSql += wxT(" AND castfunc=0"); + + pgSetIterator set(connection, typeSql); + + while (set.RowsLeft()) + { + if (set.GetVal(wxT("typname")) != column->GetRawTypename()) + { + cbDatatype->Append(set.GetVal(wxT("typname"))); + AddType(wxT("?"), set.GetOid(wxT("oid")), set.GetVal(wxT("typname"))); + } + } + } + if (cbDatatype->GetCount() <= 1) + cbDatatype->Disable(); + + cbDatatype->SetSelection(0); + wxNotifyEvent ev; + OnSelChangeTyp(ev); + + previousDefinition = GetDefinition(); + if (column->GetColNumber() < 0) // Disable controls not valid for system columns + { + txtName->Disable(); + txtDefault->Disable(); + chkNotNull->Disable(); + txtLength->Disable(); + cbDatatype->Disable(); + txtAttstattarget->Disable(); + cbStorage->Disable(); + cbCollation->Disable(); + } + else if (column->GetTable()->GetMetaType() == PGM_VIEW) // Disable controls not valid for view columns + { + txtName->Disable(); + chkNotNull->Disable(); + txtLength->Disable(); + cbDatatype->Disable(); + txtAttstattarget->Disable(); + cbStorage->Disable(); + cbCollation->Disable(); + } + else if (column->GetTable()->GetMetaType() == GP_EXTTABLE) // Disable controls not valid for external table columns + { + txtName->Disable(); + chkNotNull->Disable(); + txtLength->Disable(); + cbDatatype->Disable(); + txtAttstattarget->Disable(); + txtDefault->Disable(); + cbStorage->Disable(); + cbCollation->Disable(); + } + else if (table->GetOfTypeOid() > 0) + { + txtName->Disable(); + chkNotNull->Enable(); + txtLength->Disable(); + cbDatatype->Disable(); + txtAttstattarget->Enable(); + txtDefault->Enable(); + cbStorage->Enable(); + cbCollation->Disable(); + } + + cbStorage->SetValue(column->GetStorage()); + cbCollation->SetValue(column->GetCollation()); + + size_t i; + for (i = 0 ; i < column->GetVariables().GetCount() ; i++) + { + wxString item = column->GetVariables().Item(i); + lstVariables->AppendItem(0, item.BeforeFirst('='), item.AfterFirst('=')); + } + + } + else + { + // create mode + FillDatatype(cbDatatype, true, true); + + if (!table) + { + cbClusterSet->Disable(); + cbClusterSet = 0; + } + + txtAttstattarget->Disable(); + cbStorage->Disable(); + } + + if (changedColumn) + ApplyChangesToDlg(); + + return dlgTypeProperty::Go(modal); +} + + +wxString dlgColumn::GetSql() +{ + wxString sql; + wxString name = GetName(); + + bool isSerial = (cbDatatype->GetValue() == wxT("serial") || cbDatatype->GetValue() == wxT("bigserial") || cbDatatype->GetValue() == wxT("smallserial")); + + if (table) + { + if (column) + { + if (name != column->GetName()) + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT(" RENAME ") + qtIdent(column->GetName()) + + wxT(" TO ") + qtIdent(name) + + wxT(";\n"); + + wxString len; + if (txtLength->IsEnabled()) + len = txtLength->GetValue(); + + wxString prec; + if (txtPrecision->IsEnabled()) + prec = txtPrecision->GetValue(); + + if (connection->BackendMinimumVersion(7, 5)) + { + if ((cbDatatype->GetValue() != column->GetRawTypename() && !column->GetIsArray()) || + (cbDatatype->GetValue() != column->GetRawTypename() + wxT("[]") && column->GetIsArray()) || + (!cbCollation->GetValue().IsEmpty() && cbCollation->GetValue() != column->GetCollation()) || + (isVarLen && txtLength->IsEnabled() && StrToLong(len) != column->GetLength()) || + (isVarPrec && txtPrecision->IsEnabled() && StrToLong(prec) != column->GetPrecision())) + { + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n ALTER COLUMN ") + qtIdent(name) + wxT(" TYPE ") + + GetQuotedTypename(cbDatatype->GetGuessedSelection()); + if (!cbCollation->GetValue().IsEmpty() && cbCollation->GetValue() != column->GetCollation()) + sql += wxT(" COLLATE ") + cbCollation->GetValue(); + sql += wxT(";\n"); + } + } + else + { + wxString sqlPart; + if (cbDatatype->GetCount() > 1 && cbDatatype->GetValue() != column->GetRawTypename()) + sqlPart = wxT("atttypid=") + dlgTypeProperty::GetTypeOid(cbDatatype->GetGuessedSelection()); + + + if (!sqlPart.IsEmpty() || + (isVarLen && txtLength->IsEnabled() && StrToLong(prec) != column->GetLength()) || + (isVarPrec && txtPrecision->IsEnabled() && StrToLong(prec) != column->GetPrecision())) + { + long typmod = pgDatatype::GetTypmod(column->GetRawTypename(), len, prec); + + if (!sqlPart.IsEmpty()) + sqlPart += wxT(", "); + sqlPart += wxT("atttypmod=") + NumToStr(typmod); + } + if (!sqlPart.IsEmpty()) + { + sql += wxT("UPDATE pg_attribute\n") + wxT(" SET ") + sqlPart + wxT("\n") + wxT(" WHERE attrelid=") + table->GetOidStr() + + wxT(" AND attnum=") + NumToStr(column->GetColNumber()) + wxT(";\n"); + } + } + + if (txtDefault->GetValue() != column->GetDefault()) + { + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n ALTER COLUMN ") + qtIdent(name); + if (txtDefault->GetValue().IsEmpty()) + sql += wxT(" DROP DEFAULT"); + else + sql += wxT(" SET DEFAULT ") + txtDefault->GetValue(); + + sql += wxT(";\n"); + } + if (chkNotNull->GetValue() != column->GetNotNull()) + { + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n ALTER COLUMN ") + qtIdent(name); + if (chkNotNull->GetValue()) + sql += wxT(" SET"); + else + sql += wxT(" DROP"); + + sql += wxT(" NOT NULL;\n"); + } + if (txtAttstattarget->GetValue() != NumToStr(column->GetAttstattarget())) + { + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n ALTER COLUMN ") + qtIdent(name); + if (txtAttstattarget->GetValue().IsEmpty()) + sql += wxT(" SET STATISTICS -1"); + else + sql += wxT(" SET STATISTICS ") + txtAttstattarget->GetValue(); + sql += wxT(";\n"); + } + + wxArrayString vars; + size_t index; + + for (index = 0 ; index < column->GetVariables().GetCount() ; index++) + vars.Add(column->GetVariables().Item(index)); + + int cnt = lstVariables->GetItemCount(); + int pos; + + // check for changed or added vars + for (pos = 0 ; pos < cnt ; pos++) + { + wxString newVar = lstVariables->GetText(pos); + wxString newVal = lstVariables->GetText(pos, 1); + + wxString oldVal; + + for (index = 0 ; index < vars.GetCount() ; index++) + { + wxString var = vars.Item(index); + if (var.BeforeFirst('=').IsSameAs(newVar, false)) + { + oldVal = var.Mid(newVar.Length() + 1); + vars.RemoveAt(index); + break; + } + } + if (oldVal != newVal) + { + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n ALTER COLUMN ") + qtIdent(name) + + wxT("\n SET (") + newVar + wxT("=") + newVal + wxT(");\n"); + } + } + + // check for removed vars + for (pos = 0 ; pos < (int)vars.GetCount() ; pos++) + { + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n ALTER COLUMN ") + qtIdent(name) + + wxT("\n RESET (") + vars.Item(pos).BeforeFirst('=') + wxT(");\n"); + } + + if (cbStorage->GetValue() != column->GetStorage()) + { + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n ALTER COLUMN ") + qtIdent(name) + + wxT(" SET STORAGE ") + cbStorage->GetValue() + + wxT(";\n"); + } + } + else + { + sql = wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n ADD COLUMN ") + qtIdent(name) + + wxT(" ") + GetQuotedTypename(cbDatatype->GetGuessedSelection()); + + if (!cbCollation->GetValue().IsEmpty() && cbCollation->GetValue() != wxT("pg_catalog.\"default\"")) + sql += wxT(" COLLATE ") + cbCollation->GetValue(); + + if (chkNotNull->GetValue()) + sql += wxT(" NOT NULL"); + + if (!isSerial && !txtDefault->GetValue().IsEmpty()) + sql += wxT(" DEFAULT ") + txtDefault->GetValue(); + + sql += wxT(";\n"); + + if (!txtAttstattarget->GetValue().IsEmpty()) + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n ALTER COLUMN ") + qtIdent(name) + + wxT(" SET STATISTICS ") + txtAttstattarget->GetValue() + + wxT(";\n"); + + // check for added vars + for (int pos = 0 ; pos < lstVariables->GetItemCount() ; pos++) + { + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n ALTER COLUMN ") + qtIdent(name) + + wxT("\n SET (") + lstVariables->GetText(pos) + wxT("=") + + lstVariables->GetText(pos, 1) + wxT(");\n"); + } + } + + AppendComment(sql, wxT("COLUMN ") + table->GetQuotedFullIdentifier() + + wxT(".") + qtIdent(name), column); + + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + sql += seclabelPage->GetSqlForSecLabels(wxT("COLUMN"), table->GetQuotedFullIdentifier() + + wxT(".") + qtIdent(name)); + + // securityPage will exists only for PG 8.4 and later + if (connection->BackendMinimumVersion(8, 4)) + sql += securityPage->GetGrant(wxT("arwx"), table->GetQuotedFullIdentifier(), ¤tAcl, qtIdent(name)); + } + return sql; +} + + +void dlgColumn::SetChangedCol(pgColumn *changedCol) +{ + changedColumn = changedCol; +} + + +void dlgColumn::ApplyChangesToObj(pgColumn *changedCol) +{ + changedCol->iSetName(txtName->GetValue()); + changedCol->iSetComment(txtComment->GetValue()); + + changedCol->iSetRawTypename(cbDatatype->GetValue()); + + if (!txtLength->GetValue().IsEmpty()) + changedCol->iSetLength(StrToLong(txtLength->GetValue())); + if (!txtPrecision->GetValue().IsEmpty()) + changedCol->iSetPrecision(StrToLong(txtPrecision->GetValue())); + changedCol->iSetCollation(cbCollation->GetValue()); + + changedCol->iSetStorage(cbStorage->GetValue()); + changedCol->iSetAttstattarget(StrToLong(txtAttstattarget->GetValue())); + changedCol->iSetNotNull(chkNotNull->GetValue()); + changedCol->iSetDefault(txtDefault->GetValue()); + + changedCol->GetVariables().Clear(); + for (int pos = 0 ; pos < lstVariables->GetItemCount() ; pos++) + { + changedCol->GetVariables().Add(lstVariables->GetText(pos) + wxT("=") + lstVariables->GetText(pos, 1)); + } + + if(securityPage && connection->BackendMinimumVersion(8, 4)) + { + changedCol->iSetAcl(securityPage->GetUserPrivileges()); + } + + if(seclabelPage && connection->BackendMinimumVersion(9, 1)) + { + wxArrayString secLabels; + wxString providers; + wxString labels; + seclabelPage->GetCurrentProviderLabelArray(secLabels); + + if(!secLabels.IsEmpty()) + { + for(size_t pos = 0; pos < secLabels.Count(); pos += 2) + { + if(pos == 0) + { + providers += wxT("{") + secLabels.Item(pos); + labels += wxT("{") + secLabels.Item(pos + 1); + } + else + { + providers += wxT(",") + secLabels.Item(pos); + labels += wxT(",") + secLabels.Item(pos + 1); + } + } + providers += wxT("}"); + labels += wxT("}"); + } + changedCol->iSetProviders(providers); + changedCol->iSetLabels(labels); + } +} + + +void dlgColumn::ApplyChangesToDlg() +{ + txtName->SetValue(changedColumn->GetName()); + txtComment->SetValue(changedColumn->GetComment()); + + cbDatatype->SetValue(changedColumn->GetRawTypename()); + + txtLength->SetValue(NumToStr(changedColumn->GetLength())); + txtPrecision->SetValue(NumToStr(changedColumn->GetPrecision())); + cbCollation->SetValue(changedColumn->GetCollation()); + + cbStorage->SetValue(changedColumn->GetStorage()); + txtAttstattarget->SetValue(NumToStr(changedColumn->GetAttstattarget())); + chkNotNull->SetValue(changedColumn->GetNotNull()); + txtDefault->SetValue(changedColumn->GetDefault()); + + lstVariables->DeleteAllItems(); + for (size_t i = 0 ; i < changedColumn->GetVariables().GetCount() ; i++) + { + wxString item = changedColumn->GetVariables().Item(i); + lstVariables->AppendItem(0, item.BeforeFirst('='), item.AfterFirst('=')); + } + + //setting privileges to changed values + SetSecurityPage(changedColumn); + + if (connection->BackendMinimumVersion(9, 1)) + { + wxArrayString seclabels = changedColumn->GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + seclabelPage->lbSeclabels->AppendItem(seclabels.Item(index), + seclabels.Item(index + 1)); + } + } + } + else if (seclabelPage != NULL) + { + seclabelPage->Disable(); + } +} + +void dlgColumn::GetVariableList(wxArrayString &variableList) +{ + wxString name; + wxString value; + for(int pos = 0; pos < lstVariables->GetItemCount(); pos++) + { + name = lstVariables->GetText(pos); + value = lstVariables->GetText(pos, 1); + variableList.Add(name + wxT("=") + value); + } +} + +void dlgColumn::GetSecLabelList(wxArrayString &secLabelList) +{ + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + seclabelPage->GetCurrentProviderLabelArray(secLabelList); +} + +wxString dlgColumn::GetDefinition() +{ + wxString sql; + sql = GetQuotedTypename(cbDatatype->GetGuessedSelection()); + if (!cbCollation->GetValue().IsEmpty() && cbCollation->GetValue() != wxT("pg_catalog.\"default\"")) + sql += wxT(" COLLATE ") + cbCollation->GetValue(); + if (chkNotNull->GetValue()) + sql += wxT(" NOT NULL"); + + AppendIfFilled(sql, wxT(" DEFAULT "), txtDefault->GetValue()); + + return sql; +} + + +wxString dlgColumn::GetTypeOid() +{ + return dlgTypeProperty::GetTypeOid(cbDatatype->GetGuessedSelection()); +} + + +pgObject *dlgColumn::CreateObject(pgCollection *collection) +{ + pgObject *obj; + obj = columnFactory.CreateObjects(collection, 0, + wxT("\n AND attname=") + qtDbString(GetName()) + + wxT("\n AND cl.relname=") + qtDbString(table->GetName()) + + wxT("\n AND cl.relnamespace=") + table->GetSchema()->GetOidStr() + + wxT("\n")); + return obj; +} + + +void dlgColumn::OnSelChangeTyp(wxCommandEvent &ev) +{ + cbDatatype->GuessSelection(ev); + + CheckLenEnable(); + txtLength->Enable(isVarLen); + + bool isSerial = (cbDatatype->GetValue() == wxT("serial") || cbDatatype->GetValue() == wxT("bigserial") || cbDatatype->GetValue() == wxT("smallserial")); + txtDefault->Enable(!isSerial); + + CheckChange(); +} + + +void dlgColumn::CheckChange() +{ + bool enable = true; + long varlen = StrToLong(txtLength->GetValue()), + varprec = StrToLong(txtPrecision->GetValue()); + + if (column) + { + txtPrecision->Enable(column->GetTable()->GetMetaType() != PGM_VIEW && isVarPrec && varlen > 0); + + CheckValid(enable, cbDatatype->GetGuessedSelection() >= 0, _("Please select a datatype.")); + if (!connection->BackendMinimumVersion(7, 5)) + { + CheckValid(enable, !isVarLen || !txtLength->GetValue().IsEmpty() || varlen >= column->GetLength(), + _("New length must not be less than old length.")); + CheckValid(enable, !txtPrecision->IsEnabled() || varprec >= column->GetPrecision(), + _("New precision must not be less than old precision.")); + CheckValid(enable, !txtPrecision->IsEnabled() || varlen - varprec >= column->GetLength() - column->GetPrecision(), + _("New total digits must not be less than old total digits.")); + } + + if (enable) + enable = GetName() != column->GetName() + || txtDefault->GetValue() != column->GetDefault() + || txtComment->GetValue() != column->GetComment() + || chkNotNull->GetValue() != column->GetNotNull() + || (cbDatatype->GetCount() > 1 && cbDatatype->GetGuessedStringSelection() != column->GetRawTypename() && !column->GetIsArray()) + || (cbDatatype->GetCount() > 1 && cbDatatype->GetGuessedStringSelection() != column->GetRawTypename() + wxT("[]") && column->GetIsArray()) + || (!cbCollation->GetValue().IsEmpty() && cbCollation->GetValue() != column->GetCollation()) + || (isVarLen && varlen != column->GetLength()) + || (isVarPrec && varprec != column->GetPrecision()) + || txtAttstattarget->GetValue() != NumToStr(column->GetAttstattarget()) + || cbStorage->GetValue() != column->GetStorage() + || dirtyVars; + + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); + + EnableOK(enable || securityChanged); + } + else + { + txtPrecision->Enable(isVarPrec && varlen > 0); + + wxString name = GetName(); + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, cbDatatype->GetGuessedSelection() >= 0, _("Please select a datatype.")); + CheckValid(enable, !isVarLen || txtLength->GetValue().IsEmpty() + || (varlen >= minVarLen && varlen <= maxVarLen && NumToStr(varlen) == txtLength->GetValue()), + _("Please specify valid length.")); + CheckValid(enable, !txtPrecision->IsEnabled() + || (varprec >= 0 && varprec <= varlen && NumToStr(varprec) == txtPrecision->GetValue()), + _("Please specify valid numeric precision (0..") + NumToStr(varlen) + wxT(").")); + + EnableOK(enable); + } +} + + +void dlgColumn::OnAddPriv(wxCommandEvent &ev) +{ + securityChanged = true; + CheckChange(); +} + + +void dlgColumn::OnDelPriv(wxCommandEvent &ev) +{ + securityChanged = true; + CheckChange(); +} + +void dlgColumn::OnVarnameSelChange(wxCommandEvent &ev) +{ + cbVarname->GuessSelection(ev); +} + +void dlgColumn::OnVarSelChange(wxListEvent &ev) +{ + long pos = lstVariables->GetSelection(); + if (pos >= 0) + { + wxString value = lstVariables->GetText(pos, 1); + cbVarname->SetValue(lstVariables->GetText(pos)); + cbVarname->FindString(lstVariables->GetText(pos)); + txtValue->SetValue(value); + } +} + + +void dlgColumn::OnVarAdd(wxCommandEvent &ev) +{ + wxString name = cbVarname->GetValue(); + wxString value = txtValue->GetValue().Strip(wxString::both); + + if (value.IsEmpty()) + value = wxT("DEFAULT"); + + if (!name.IsEmpty()) + { + long pos = lstVariables->FindItem(-1, name); + if (pos < 0) + { + pos = lstVariables->GetItemCount(); + lstVariables->InsertItem(pos, name, 0); + } + lstVariables->SetItem(pos, 1, value); + } + + dirtyVars = true; + CheckChange(); +} + + +void dlgColumn::OnVarRemove(wxCommandEvent &ev) +{ + if (lstVariables->GetSelection() >= 0) + { + lstVariables->DeleteCurrentItem(); + dirtyVars = true; + CheckChange(); + } +} + + +void dlgColumn::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} diff --git a/dlg/dlgConnect.cpp b/dlg/dlgConnect.cpp new file mode 100644 index 0000000..c006660 --- /dev/null +++ b/dlg/dlgConnect.cpp @@ -0,0 +1,102 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgConnect.cpp - Connect to a database +// +////////////////////////////////////////////////////////////////////////// + + + +// App headers +#include "pgAdmin3.h" + +#include "dlg/dlgConnect.h" +#include "db/pgConn.h" +#include "frm/frmHint.h" +#include "schema/pgServer.h" +#include "utils/sysLogger.h" + +#include "images/connect.pngc" + + + +BEGIN_EVENT_TABLE(dlgConnect, DialogWithHelp) + EVT_BUTTON (wxID_OK, dlgConnect::OnOK) + EVT_BUTTON (wxID_CANCEL, dlgConnect::OnCancel) +END_EVENT_TABLE() + + +#define stDescription CTRL_STATIC("stDescription") +#define chkStorePwd CTRL_CHECKBOX("chkStorePwd") +#define txtPassword CTRL_TEXT("txtPassword") + + + +dlgConnect::dlgConnect(frmMain *form, const wxString &description, bool storePwd) : + DialogWithHelp(form) +{ + SetFont(settings->GetSystemFont()); + LoadResource((wxWindow *)form, wxT("dlgConnect")); + + SetIcon(*connect_png_ico); + RestorePosition(); + + // Setup the default values + stDescription->SetLabel(description); + chkStorePwd->SetValue(storePwd); + txtPassword->Enable(true); + + if (form == NULL) + chkStorePwd->Hide(); +} + +dlgConnect::~dlgConnect() +{ + SavePosition(); +} + + +wxString dlgConnect::GetHelpPage() const +{ + return wxT("connect"); +} + + +void dlgConnect::OnOK(wxCommandEvent &ev) +{ + // Display the 'save password' hint if required + if(chkStorePwd->GetValue()) + { + if (frmHint::ShowHint(this, HINT_SAVING_PASSWORDS) == wxID_CANCEL) + return; + } + + EndModal(wxID_OK); +} + + +void dlgConnect::OnCancel(wxCommandEvent &ev) +{ + EndModal(wxID_CANCEL); +} + +int dlgConnect::Go() +{ + // Set focus on the Password textbox and show modal + txtPassword->SetFocus(); + return ShowModal(); +} + +wxString dlgConnect::GetPassword() +{ + return txtPassword->GetValue(); +} + +bool dlgConnect::GetStorePwd() +{ + return chkStorePwd->GetValue(); +} diff --git a/dlg/dlgConversion.cpp b/dlg/dlgConversion.cpp new file mode 100644 index 0000000..eea5056 --- /dev/null +++ b/dlg/dlgConversion.cpp @@ -0,0 +1,208 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgConversion.cpp - PostgreSQL Conversion Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgConversion.h" +#include "schema/pgConversion.h" +#include "schema/pgSchema.h" + + +// pointer to controls +#define cbSourceEncoding CTRL_COMBOBOX("cbSourceEncoding") +#define cbTargetEncoding CTRL_COMBOBOX("cbTargetEncoding") +#define cbFunction CTRL_COMBOBOX("cbFunction") +#define chkDefault CTRL_CHECKBOX("chkDefault") + + + +BEGIN_EVENT_TABLE(dlgConversion, dlgProperty) + EVT_TEXT(XRCID("cbSourceEncoding"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbSourceEncoding"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbTargetEncoding"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbTargetEncoding"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbFunction"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbFunction"), dlgProperty::OnChange) +END_EVENT_TABLE(); + + +dlgProperty *pgConversionFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgConversion(this, frame, (pgConversion *)node, (pgSchema *)parent); +} + + + +dlgConversion::dlgConversion(pgaFactory *f, frmMain *frame, pgConversion *node, pgSchema *sch) + : dlgProperty(f, frame, wxT("dlgConversion")) +{ + conversion = node; + schema = sch; +} + + +pgObject *dlgConversion::GetObject() +{ + return conversion; +} + + +int dlgConversion::Go(bool modal) +{ + if (!connection->BackendMinimumVersion(7, 4)) + txtComment->Disable(); + + if (!connection->BackendMinimumVersion(7, 5)) + cbOwner->Disable(); + + if (conversion) + { + // edit mode + cbSchema->Enable(connection->BackendMinimumVersion(9, 1)); + cbSourceEncoding->Append(conversion->GetForEncoding()); + cbSourceEncoding->SetSelection(0); + cbTargetEncoding->Append(conversion->GetToEncoding()); + cbTargetEncoding->SetSelection(0); + + cbFunction->Append(database->GetSchemaPrefix(conversion->GetProcNamespace()) + conversion->GetProc()); + cbFunction->SetSelection(0); + + if (!connection->BackendMinimumVersion(7, 4)) + txtName->Disable(); + chkDefault->SetValue(conversion->GetDefaultConversion()); + cbSourceEncoding->Disable(); + cbTargetEncoding->Disable(); + cbFunction->Disable(); + chkDefault->Disable(); + } + else + { + // create mode + + wxString qry = + wxT("SELECT proname, nspname\n") + wxT(" FROM pg_proc p\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace") + wxT("\n WHERE prorettype = ") + NumToStr(PGOID_TYPE_VOID) + + wxT("\n AND pronargs = 5"); + + pgSet *set = connection->ExecuteSet(qry); + if (set) + { + while (!set->Eof()) + { + functions.Add(database->GetQuotedSchemaPrefix(set->GetVal(wxT("nspname"))) + qtIdent(set->GetVal(wxT("proname")))); + cbFunction->Append(database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname"))); + + set->MoveNext(); + } + delete set; + } + + long encNo = 0; + wxString encStr; + do + { + encStr = connection->ExecuteScalar( + wxT("SELECT pg_encoding_to_char(") + NumToStr(encNo) + wxT(")")); + if (!encStr.IsEmpty()) + { + cbSourceEncoding->Append(encStr); + cbTargetEncoding->Append(encStr); + } + encNo++; + } + while (!encStr.IsEmpty()); + } + + return dlgProperty::Go(modal); +} + + +pgObject *dlgConversion::CreateObject(pgCollection *collection) +{ + pgObject *obj = conversionFactory.CreateObjects(collection, 0, + wxT("\n AND conname = ") + qtDbString(GetName())); + + return obj; +} + + +void dlgConversion::CheckChange() +{ + if (conversion) + { + EnableOK(txtName->GetValue() != conversion->GetName() + || cbSchema->GetValue() != conversion->GetSchema()->GetName() + || txtComment->GetValue() != conversion->GetComment() + || cbOwner->GetValue() != conversion->GetOwner()); + } + else + { + bool enable = true; + CheckValid(enable, !GetName().IsEmpty(), _("Please specify name.")); + CheckValid(enable, !cbSourceEncoding->GetValue().IsEmpty(), _("Please specify source encoding.")); + CheckValid(enable, !cbTargetEncoding->GetValue().IsEmpty(), _("Please specify target encoding.")); + CheckValid(enable, cbFunction->GetCurrentSelection() >= 0, _("Please specify conversion function.")); + + EnableOK(enable); + } +} + + + + +wxString dlgConversion::GetSql() +{ + wxString sql; + wxString name; + + if (conversion) + { + // edit mode + name = GetName(); + + AppendNameChange(sql); + AppendOwnerChange(sql, wxT("CONVERSION ") + schema->GetQuotedPrefix() + qtIdent(name)); + + if (cbSchema->GetValue() != conversion->GetSchema()->GetName()) + { + sql += wxT("ALTER CONVERSION ") + qtIdent(conversion->GetSchema()->GetName()) + wxT(".") + qtIdent(name) + + wxT("\n SET SCHEMA ") + qtIdent(cbSchema->GetValue()) + + wxT(";\n"); + } + } + else + { + name = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()); + + // create mode + sql = wxT("CREATE "); + if (chkDefault->GetValue()) + sql += wxT("DEFAULT "); + sql += wxT("CONVERSION ") + name + + wxT("\n FOR ") + qtDbString(cbSourceEncoding->GetValue()) + + wxT(" TO ") + qtDbString(cbTargetEncoding->GetValue()) + + wxT("\n FROM ") + functions.Item(cbFunction->GetCurrentSelection()) + + wxT(";\n"); + + AppendOwnerNew(sql, wxT("CONVERSION ") + schema->GetQuotedPrefix() + qtIdent(name)); + } + AppendComment(sql, wxT("CONVERSION ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), conversion); + + return sql; +} diff --git a/dlg/dlgDatabase.cpp b/dlg/dlgDatabase.cpp new file mode 100644 index 0000000..2309bae --- /dev/null +++ b/dlg/dlgDatabase.cpp @@ -0,0 +1,900 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgDatabase.cpp - PostgreSQL Database Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "dlg/dlgDatabase.h" +#include "schema/pgDatabase.h" +#include "ctl/ctlDefaultSecurityPanel.h" +#include "ctl/ctlSeclabelPanel.h" + + +// pointer to controls +#define cbEncoding CTRL_COMBOBOX("cbEncoding") +#define cbTemplate CTRL_COMBOBOX("cbTemplate") +#define stPath CTRL_STATIC("stPath") +#define txtPath CTRL_TEXT("txtPath") +#define stTablespace CTRL_STATIC("stTablespace") +#define cbTablespace CTRL_COMBOBOX("cbTablespace") +#define txtSchemaRestr CTRL_TEXT("txtSchemaRestr") + +#define lstVariables CTRL_LISTVIEW("lstVariables") +#define cbVarname CTRL_COMBOBOX2("cbVarname") +#define cbVarUsername CTRL_COMBOBOX2("cbVarUsername") +#define txtValue CTRL_TEXT("txtValue") +#define chkValue CTRL_CHECKBOX("chkValue") +#define btnAdd CTRL_BUTTON("wxID_ADD") +#define btnRemove CTRL_BUTTON("wxID_REMOVE") +#define cbCollate CTRL_COMBOBOX2("cbCollate") +#define cbCType CTRL_COMBOBOX2("cbCType") +#define txtConnLimit CTRL_TEXT("txtConnLimit") + +dlgProperty *pgDatabaseFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + dlgDatabase *dlg = new dlgDatabase(this, frame, (pgDatabase *)node); + if (dlg && !node) + { + // use the server's connection to avoid "template1 in use" + dlg->SetConnection(parent->GetConnection()); + } + return dlg; +} + + +BEGIN_EVENT_TABLE(dlgDatabase, dlgDefaultSecurityProperty) + EVT_TEXT(XRCID("txtPath"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbTablespace"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbTablespace"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbEncoding"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbEncoding"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtSchemaRestr"), dlgDatabase::OnChangeRestr) + EVT_LIST_ITEM_SELECTED(XRCID("lstVariables"), dlgDatabase::OnVarSelChange) + EVT_BUTTON(wxID_ADD, dlgDatabase::OnVarAdd) + EVT_BUTTON(wxID_REMOVE, dlgDatabase::OnVarRemove) + EVT_TEXT(XRCID("cbVarname"), dlgDatabase::OnVarnameSelChange) + EVT_TEXT(XRCID("cbVarUsername"), dlgDatabase::OnVarnameSelChange) + EVT_COMBOBOX(XRCID("cbVarname"), dlgDatabase::OnVarnameSelChange) + EVT_BUTTON(wxID_OK, dlgDatabase::OnOK) + EVT_TEXT(XRCID("cbCollate"), dlgDatabase::OnCollateSelChange) + EVT_TEXT(XRCID("cbCType"), dlgDatabase::OnCTypeSelChange) + EVT_TEXT(XRCID("txtConnLimit"), dlgDatabase::OnConnLimitChange) +#ifdef __WXMAC__ + EVT_SIZE( dlgDatabase::OnChangeSize) +#endif +END_EVENT_TABLE(); + + +dlgDatabase::dlgDatabase(pgaFactory *f, frmMain *frame, pgDatabase *node) + : dlgDefaultSecurityProperty(f, frame, node, wxT("dlgDatabase"), wxT("CREATE,TEMP,CONNECT"), "CTc", node != NULL ? true : false) +{ + database = node; + schemaRestrictionOk = true; + lstVariables->CreateColumns(0, _("Username"), _("Variable"), _("Value")); + + chkValue->Hide(); + + dirtyVars = false; + + seclabelPage = new ctlSeclabelPanel(nbNotebook); + + if (!node) + { + int icon = PGICON_PUBLIC; + wxString name = wxT("public"); + wxString value = wxT("Tc"); + securityPage->lbPrivileges->AppendItem(icon, name, value); + AppendCurrentAcl(name, value); + } +} + +pgObject *dlgDatabase::GetObject() +{ + return database; +} + + +wxString dlgDatabase::GetHelpPage() const +{ + if (nbNotebook->GetSelection() == 1) + return wxT("pg/runtime-config"); + return dlgDefaultSecurityProperty::GetHelpPage(); +} + + +int dlgDatabase::Go(bool modal) +{ + bool createDefPriv = false; + wxString strDefPrivsOnTables, strDefPrivsOnSeqs, strDefPrivsOnFuncs, strDefPrivsOnTypes; + + if (connection->BackendMinimumVersion(9, 2)) + { + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(database); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgDatabase::OnChange)); + } + else + seclabelPage->Disable(); + + if (connection->BackendMinimumVersion(9, 0)) + { + cbVarUsername->Append(wxT("")); + // AddUsers function of dlgDefaultSecurity has already been called. + // Hence, calling dlgProperty::AddUsers instead of that. + dlgProperty::AddUsers(cbVarUsername); + } + else + cbVarUsername->Enable(false); + + if (connection->BackendMinimumVersion(8, 0)) + { + stPath->Hide(); + txtPath->Hide(); + } + else + { + stTablespace->Hide(); + cbTablespace->Hide(); + } + + if (!connection->BackendMinimumVersion(8, 1)) + { + txtConnLimit->Disable(); + } + else + txtConnLimit->SetValidator(numericValidator); + + if (!connection->BackendMinimumVersion(8, 4)) + { + cbCollate->Disable(); + cbCType->Disable(); + } + + pgSet *set; + if (connection->BackendMinimumVersion(7, 4)) + set = connection->ExecuteSet(wxT("SELECT name, vartype, min_val, max_val\n") + wxT(" FROM pg_settings WHERE context in ('user', 'superuser')")); + else + set = connection->ExecuteSet(wxT("SELECT name, 'string' as vartype, '' as min_val, '' as max_val FROM pg_settings")); + if (set) + { + while (!set->Eof()) + { + cbVarname->Append(set->GetVal(0)); + varInfo.Add(set->GetVal(wxT("vartype")) + wxT(" ") + + set->GetVal(wxT("min_val")) + wxT(" ") + + set->GetVal(wxT("max_val"))); + set->MoveNext(); + } + delete set; + + cbVarname->SetSelection(0); + + if (connection->BackendMinimumVersion(9, 0)) + { + cbVarUsername->SetSelection(0); + } + SetupVarEditor(0); + } + + if (database) + { + // edit mode + + if (!connection->BackendMinimumVersion(7, 4)) + txtName->Disable(); + + if (!connection->BackendMinimumVersion(8, 0)) + cbOwner->Disable(); + + readOnly = !database->GetServer()->GetCreatePrivilege(); + + + if (connection->BackendMinimumVersion(9, 0)) + { + createDefPriv = true; + strDefPrivsOnTables = database->GetDefPrivsOnTables(); + strDefPrivsOnSeqs = database->GetDefPrivsOnSequences(); + strDefPrivsOnFuncs = database->GetDefPrivsOnFunctions(); + } + if (connection->BackendMinimumVersion(9, 2)) + strDefPrivsOnTypes = database->GetDefPrivsOnTypes(); + + if (readOnly) + { + cbVarname->Disable(); + cbVarUsername->Disable(); + txtValue->Disable(); + btnAdd->Disable(); + btnRemove->Disable(); + } + + size_t i; + wxString username; + wxString varname; + wxString varvalue; + for (i = 0 ; i < database->GetVariables().GetCount() ; i += 3) + { + username = database->GetVariables().Item(i); + varname = database->GetVariables().Item(i + 1); + varvalue = database->GetVariables().Item(i + 2); + + lstVariables->AppendItem(0, username, varname, varvalue); + } + + PrepareTablespace(cbTablespace, database->GetTablespaceOid()); + if (connection->BackendMinimumVersion(8, 4)) + cbTablespace->Enable(); + else + cbTablespace->Disable(); + txtPath->SetValue(database->GetPath()); + txtPath->Disable(); + + cbEncoding->Append(database->GetEncoding()); + cbEncoding->SetSelection(0); + + if (connection->BackendMinimumVersion(8, 1)) + { + wxString strConnLimit; + strConnLimit.Printf(wxT("%ld"), database->GetConnectionLimit()); + txtConnLimit->SetValue(strConnLimit); + } + + if (connection->BackendMinimumVersion(8, 4)) + { + cbCollate->Append(database->GetCollate()); + cbCollate->SetSelection(0); + cbCType->Append(database->GetCType()); + cbCType->SetSelection(0); + } + + cbTemplate->Disable(); + cbEncoding->Disable(); + cbCollate->Disable(); + cbCType->Disable(); + + txtSchemaRestr->SetValue(database->GetSchemaRestriction()); + } + else + { + // create mode + if (!connection->BackendMinimumVersion(8, 2)) + txtComment->Disable(); + + PrepareTablespace(cbTablespace); + + // Add the default tablespace + cbTablespace->Insert(_(""), 0, (void *)0); + cbTablespace->SetSelection(0); + + cbTemplate->Append(wxEmptyString); + FillCombobox(wxT("SELECT datname FROM pg_database ORDER BY datname"), cbTemplate); + cbTemplate->SetSelection(0); + + if (connection->BackendMinimumVersion(8, 4)) + { + FillCombobox(wxT("select DISTINCT(datctype) from pg_database UNION SELECT DISTINCT(datcollate) from pg_database"), cbCollate, cbCType); + if (cbCollate->FindString(wxT("C")) < 0) + { + cbCollate->AppendString(wxT("C")); + cbCType->AppendString(wxT("C")); + } + if (cbCollate->FindString(wxT("POSIX")) < 0) + { + cbCollate->AppendString(wxT("POSIX")); + cbCType->AppendString(wxT("POSIX")); + } + } + if (connection->BackendMinimumVersion(8, 1)) + { + txtConnLimit->SetValue(wxT("-1")); + } + + + long encNo = 0; + wxString encStr; + do + { + encStr = connection->ExecuteScalar( + wxT("SELECT pg_encoding_to_char(") + NumToStr(encNo) + wxT(")")); + if (pgConn::IsValidServerEncoding(encNo) && !encStr.IsEmpty()) + cbEncoding->Append(encStr); + + encNo++; + } + while (!encStr.IsEmpty()); + + encStr = connection->ExecuteScalar(wxT("SELECT pg_encoding_to_char(encoding) FROM pg_database WHERE datname = 'template0'")); + encNo = cbEncoding->FindString(encStr); + + if (encNo < 0) + { + encNo = cbEncoding->FindString(wxT("UNICODE")); + if (encNo < 0) + encNo = cbEncoding->FindString(wxT("UTF8")); + } + + if (encNo >= 0) + cbEncoding->SetSelection(encNo); + + } + + // Find, and disable the CONNECT ACL option if we're on pre 8.2 + if (!connection->BackendMinimumVersion(8, 2)) + { + // Disable the checkbox + if (!DisablePrivilege(wxT("CONNECT"))) + { + wxLogError(_("Failed to disable the CONNECT privilege checkbox!")); + } + } + + return dlgDefaultSecurityProperty::Go(modal, createDefPriv, strDefPrivsOnTables, strDefPrivsOnSeqs, strDefPrivsOnFuncs, strDefPrivsOnTypes); +} + + +pgObject *dlgDatabase::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + pgObject *obj = databaseFactory.CreateObjects(collection, 0, wxT(" WHERE datname=") + qtDbString(name) + wxT("\n")); + return obj; +} + + +#ifdef __WXMAC__ +void dlgDatabase::OnChangeSize(wxSizeEvent &ev) +{ + lstVariables->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 550); + dlgSecurityProperty::OnChangeSize(ev); +} +#endif + + +void dlgDatabase::OnChangeRestr(wxCommandEvent &ev) +{ + if (txtSchemaRestr->GetValue().IsEmpty()) + schemaRestrictionOk = true; + else + { + wxString sql = wxT("EXPLAIN SELECT 1 FROM pg_namespace\n") + wxT("WHERE nspname IN (") + txtSchemaRestr->GetValue() + wxT(")"); + + wxLogNull nix; + wxString result = connection->ExecuteScalar(sql); + + schemaRestrictionOk = !result.IsEmpty(); + } + OnChange(ev); +} + + +void dlgDatabase::OnOK(wxCommandEvent &ev) +{ +#ifdef __WXGTK__ + if (!btnOK->IsEnabled()) + return; +#endif + if (database) + { + database->iSetSchemaRestriction(txtSchemaRestr->GetValue().Trim()); + settings->Write(wxString::Format(wxT("Servers/%ld/Databases/%s/SchemaRestriction"), database->GetServer()->GetServerIndex(), database->GetName().c_str()), txtSchemaRestr->GetValue().Trim()); + + /* + * The connection from the database will get disconnected before execution of any + * sql statements for the database. + * + * Hence, we need to hack the execution of the default privileges statements(sqls) + * before getting disconnected from this database. So that, these statements will + * run against the current database connection, and not against the server connection. + */ + // defaultSecurityChanged will be true only for PostgreSQL 9.0 or later + if (defaultSecurityChanged) + { + wxString strDefPrivs = GetDefaultPrivileges(); + if (!executeDDLSql(strDefPrivs)) + { + EnableOK(true); + return; + } + defaultSecurityChanged = false; + } + } + dlgDefaultSecurityProperty::OnOK(ev); +} + +/* + * Execute default privileges statement + * + * - Hacked to execute the default privileges statement (sql) for dlgDatabse against this database, + * because connection for this database object is getting disconnected, and replaced by the server + * connection, before execution of any statements (sqls) in dlgPropery::apply function called + * from dlgPropery::OnOK event handler. + * + * NOTE: This will work only if the database object exists. + */ +bool dlgDatabase::executeDDLSql(const wxString &strSql) +{ + pgConn *myConn = connection; + + if (!strSql.IsEmpty()) + { + wxString tmp; + if (cbClusterSet && cbClusterSet->GetSelection() > 0) + { + replClientData *data = (replClientData *)cbClusterSet->wxItemContainer::GetClientData(cbClusterSet->GetSelection()); + + if (data->majorVer > 1 || (data->majorVer == 1 && data->minorVer >= 2)) + { + // From slony version 2.2.0 onwards ddlscript_prepare() method is removed and + // ddlscript_complete() method arguments got changed so we have to use ddlcapture() method + // instead of ddlscript_prepare() and changed the argument of ddlscript_complete() method + if ((data->majorVer == 2 && data->minorVer >= 2) || (data->majorVer > 2)) + { + tmp = wxT("SELECT ") + qtIdent(data->cluster) + + wxT(".ddlcapture(") + qtDbString(strSql) + wxT(", ") + wxT("NULL::text") + wxT(");\n") + + wxT("SELECT ") + qtIdent(data->cluster) + + wxT(".ddlscript_complete(") + wxT("NULL::text") + wxT(");\n"); + } + else + { + tmp = wxT("SELECT ") + qtIdent(data->cluster) + + wxT(".ddlscript_prepare(") + NumToStr(data->setId) + wxT(", -1);\n") + + strSql + wxT(";\n") + + wxT("SELECT ") + qtIdent(data->cluster) + + wxT(".ddlscript_complete(") + NumToStr(data->setId) + wxT(", ") + + qtDbString(strSql) + wxT(", -1);\n"); + } + } + else + { + tmp = wxT("SELECT ") + qtIdent(data->cluster) + + wxT(".ddlscript(") + NumToStr(data->setId) + wxT(", ") + + qtDbString(strSql) + wxT(", 0);\n"); + } + } + else + tmp = strSql; + + if (!myConn->ExecuteVoid(tmp)) + // error message is displayed inside ExecuteVoid + return false; + } + return true; +} + + +void dlgDatabase::CheckChange() +{ + bool enable = true; + + if (database) + { + long connLimit; + if (!txtConnLimit->GetValue().ToLong(&connLimit)) + connLimit = database->GetConnectionLimit(); + + enable = txtSchemaRestr->GetValue() != database->GetSchemaRestriction() + || txtComment->GetValue() != database->GetComment() + || txtName->GetValue() != database->GetName() + || cbOwner->GetValue() != database->GetOwner() + || cbTablespace->GetValue() != database->GetTablespace() + || connLimit != database->GetConnectionLimit() + || dirtyVars; + if (seclabelPage && connection->BackendMinimumVersion(9, 2)) + enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); + } + + CheckValid(enable, !GetName().IsEmpty(), _("Please specify name.")); + CheckValid(enable, schemaRestrictionOk, _("Restriction not valid.")); + + // If there's a schema restriction, we need to ignore the SQL + // for the dialogue when enabling the OK button. + if (schemaRestrictionOk) + EnableOK(enable, true); + else + EnableOK(enable); +} + + +void dlgDatabase::OnVarnameSelChange(wxCommandEvent &ev) +{ + int sel = cbVarname->GuessSelection(ev); + + SetupVarEditor(sel); +} + +void dlgDatabase::OnCollateSelChange(wxCommandEvent &ev) +{ + cbCollate->GuessSelection(ev); +} + +void dlgDatabase::OnCTypeSelChange(wxCommandEvent &ev) +{ + cbCType->GuessSelection(ev); +} + +void dlgDatabase::OnConnLimitChange(wxCommandEvent &ev) +{ + if (ev.GetEventType() == wxEVT_COMMAND_TEXT_UPDATED) + { + wxString strConnLimit = txtConnLimit->GetValue(); + long val = 0; + if (strConnLimit.ToLong(&val)) + { + CheckChange(); + } + else if (strConnLimit.Contains(wxT("."))) + { + double val; + + // Stop Propagation of the event to the parents + ev.StopPropagation(); + if (strConnLimit.ToDouble(&val)) + { + strConnLimit.Printf(wxT("%ld"), (long)val); + txtConnLimit->SetValue(strConnLimit); + txtConnLimit->SetInsertionPointEnd(); + return; + } + } + else if (strConnLimit.length() > 9) + { + // Maximum value support is 2147483647 + wxString newVal = strConnLimit.substr(0, 10); + if (!newVal.ToLong(&val)) + { + newVal = strConnLimit.substr(0, 9); + } + ev.StopPropagation(); + txtConnLimit->SetValue(newVal); + txtConnLimit->SetInsertionPointEnd(); + return; + } + } +} + +void dlgDatabase::SetupVarEditor(int var) +{ + if (var >= 0 && varInfo.Count() > 0) + { + wxStringTokenizer vals(varInfo.Item(var)); + wxString typ = vals.GetNextToken(); + + if (typ == wxT("bool")) + { + txtValue->Hide(); + chkValue->Show(); + chkValue->SetMinSize(wxSize(cbVarname->GetSize().GetWidth(), cbVarname->GetSize().GetHeight())); + chkValue->GetParent()->Layout(); + } + else + { + chkValue->Hide(); + txtValue->Show(); + if (typ == wxT("string") || typ == wxT("enum")) + txtValue->SetValidator(wxTextValidator()); + else + txtValue->SetValidator(numericValidator); + txtValue->SetMinSize(wxSize(cbVarname->GetSize().GetWidth(), cbVarname->GetSize().GetHeight())); + txtValue->GetParent()->Layout(); + } + } +} + +void dlgDatabase::OnVarSelChange(wxListEvent &ev) +{ + long pos = lstVariables->GetSelection(); + if (pos >= 0) + { + cbVarUsername->SetValue(lstVariables->GetText(pos)); + cbVarname->SetValue(lstVariables->GetText(pos, 1)); + + // We used to raise an OnVarnameSelChange() event here, but + // at this point the combo box hasn't necessarily updated. + wxString value = lstVariables->GetText(pos, 2); + int sel = cbVarname->FindString(lstVariables->GetText(pos, 1)); + SetupVarEditor(sel); + + txtValue->SetValue(value); + chkValue->SetValue(value == wxT("on")); + } +} + + +void dlgDatabase::OnVarAdd(wxCommandEvent &ev) +{ + wxString username = cbVarUsername->GetValue(); + wxString name = cbVarname->GetValue(); + wxString value; + if (chkValue->IsShown()) + value = chkValue->GetValue() ? wxT("on") : wxT("off"); + else + value = txtValue->GetValue().Strip(wxString::both); + + if (value.IsEmpty()) + value = wxT("DEFAULT"); + + if (!name.IsEmpty()) + { + bool found = false; + long prevpos = -1; + for (long item = 0; item < lstVariables->GetItemCount(); item++) + { + if (name == lstVariables->GetText(item, 1)) + { + if (username == lstVariables->GetText(item)) + { + found = true; + lstVariables->SetItem(item, 2, value); + } + else + { + prevpos = item; + } + } + } + if (!found) + { + if (prevpos != -1) + { + lstVariables->InsertItem(prevpos, username, 1); + lstVariables->SetItem(prevpos, 1, name); + lstVariables->SetItem(prevpos, 2, value); + } + else + { + long pos = lstVariables->GetItemCount(); + lstVariables->InsertItem(pos, username, 1); + lstVariables->SetItem(pos, 1, name); + lstVariables->SetItem(pos, 2, value); + } + } + } + dirtyVars = true; + CheckChange(); +} + + +void dlgDatabase::OnVarRemove(wxCommandEvent &ev) +{ + if (lstVariables->GetSelection() == wxNOT_FOUND) + return; + lstVariables->DeleteCurrentItem(); + dirtyVars = true; + CheckChange(); +} + + +// Note: CREATE DATABASE cannot be part of a multi-statement query as of +// PG83, and never actually would have been transaction-safe prior +// to then. Therefore, when creating a new database, only the CREATE +// statement comes from GetSql(), subsequent ALTERs come from GetSql2() +wxString dlgDatabase::GetSql() +{ + wxString sql, name; + name = GetName(); + + if (database) + { + // edit mode + + AppendNameChange(sql); + AppendOwnerChange(sql, wxT("DATABASE ") + qtIdent(name)); + + AppendComment(sql, wxT("DATABASE"), 0, database); + + if (seclabelPage && connection->BackendMinimumVersion(9, 2)) + sql += seclabelPage->GetSqlForSecLabels(wxT("DATABASE"), qtIdent(name)); + + if (connection->BackendMinimumVersion(8, 4)) + { + if (cbTablespace->GetCurrentSelection() > 0 && cbTablespace->GetOIDKey() > 0 + && cbTablespace->GetOIDKey() != database->GetTablespaceOid()) + sql += wxT("ALTER DATABASE ") + qtIdent(name) + + wxT("\n SET TABLESPACE ") + qtIdent(cbTablespace->GetValue()) + + wxT(";\n"); + } + if (connection->BackendMinimumVersion(8, 1)) + { + long connLimit; + + if (txtConnLimit->GetValue().IsEmpty()) + connLimit = -1; + else if (!txtConnLimit->GetValue().ToLong(&connLimit)) + connLimit = database->GetConnectionLimit(); + + if (connLimit != database->GetConnectionLimit()) + { + wxString strConnLimit; + strConnLimit << connLimit; + sql += wxT("ALTER DATABASE ") + qtIdent(name) + + wxT("\n WITH CONNECTION LIMIT = ") + + strConnLimit + + wxT(";\n"); + } + } + + if (!connection->BackendMinimumVersion(8, 2)) + sql += GetGrant(wxT("CT"), wxT("DATABASE ") + qtIdent(name)); + else + sql += GetGrant(wxT("CTc"), wxT("DATABASE ") + qtIdent(name)); + + wxArrayString vars; + wxString username; + wxString varname; + wxString varvalue; + size_t index; + int pos; + + // copy database->GetVariables() into vars + for (index = 0 ; index < database->GetVariables().GetCount() ; index++) + vars.Add(database->GetVariables().Item(index)); + + // check for changed or added vars + for (pos = 0 ; pos < lstVariables->GetItemCount() ; pos++) + { + wxString newUsr = lstVariables->GetText(pos); + wxString newVar = lstVariables->GetText(pos, 1); + wxString newVal = lstVariables->GetText(pos, 2); + + wxString oldVal; + + for (index = 0 ; index < vars.GetCount() ; index += 3) + { + username = vars.Item(index); + varname = vars.Item(index + 1); + varvalue = vars.Item(index + 2); + + if (newUsr == username && newVar == varname) + { + oldVal = varvalue; + vars.RemoveAt(index); + vars.RemoveAt(index); + vars.RemoveAt(index); + break; + } + } + if (oldVal != newVal) + { + if (newUsr.Length() == 0) + sql += wxT("ALTER DATABASE ") + qtIdent(name); + else + sql += wxT("ALTER ROLE ") + newUsr + wxT(" IN DATABASE ") + qtIdent(name); + + if (newVar != wxT("search_path") && newVar != wxT("temp_tablespaces")) + { + sql += wxT("\n SET ") + newVar + wxT(" = '") + newVal + wxT("';\n"); + } + else + { + sql += wxT("\n SET ") + newVar + wxT(" = ") + newVal + wxT(";\n"); + } + } + } + + // check for removed vars + for (pos = 0 ; pos < (int)vars.GetCount() ; pos += 3) + { + username = vars.Item(pos); + varname = vars.Item(pos + 1); + varvalue = vars.Item(pos + 2); + + if (username.Length() == 0) + { + sql += wxT("ALTER DATABASE ") + qtIdent(name) + + wxT("\n RESET ") + varname + + wxT(";\n"); + } + else + { + sql += wxT("ALTER ROLE ") + username + wxT(" IN DATABASE ") + qtIdent(name) + + wxT("\n RESET ") + varname + wxT(";\n"); + } + } + + if (defaultSecurityChanged) + sql += wxT("\n") + GetDefaultPrivileges(); + } + else + { + // create mode + sql = wxT("CREATE DATABASE ") + qtIdent(name) + + wxT("\n WITH ENCODING=") + qtDbString(cbEncoding->GetValue()); + + AppendIfFilled(sql, wxT("\n OWNER="), qtIdent(cbOwner->GetValue())); + AppendIfFilled(sql, wxT("\n TEMPLATE="), qtIdent(cbTemplate->GetValue())); + AppendIfFilled(sql, wxT("\n LOCATION="), txtPath->GetValue()); + if (connection->BackendMinimumVersion(8, 4)) + { + wxString strCollate = cbCollate->GetValue(); + if (!strCollate.IsEmpty()) + AppendIfFilled(sql, wxT("\n LC_COLLATE="), qtDbString(strCollate)); + wxString strCType = cbCType->GetValue(); + if (!strCType.IsEmpty()) + AppendIfFilled(sql, wxT("\n LC_CTYPE="), qtDbString(strCType)); + } + if (connection->BackendMinimumVersion(8, 1)) + { + AppendIfFilled(sql, wxT("\n CONNECTION LIMIT="), (txtConnLimit->GetValue() == wxT("-") ? wxT("-1") : txtConnLimit->GetValue())); + } + if (cbTablespace->GetCurrentSelection() > 0 && cbTablespace->GetOIDKey() > 0) + sql += wxT("\n TABLESPACE=") + qtIdent(cbTablespace->GetValue()); + + sql += wxT(";\n"); + } + + return sql.Trim(false); +} + +wxString dlgDatabase::GetSql2() +{ + wxString sql, name; + name = GetName(); + + // We only use GetSql2() in the CREATE case + if (!database) + { + if (connection->BackendMinimumVersion(8, 2)) + AppendComment(sql, wxT("DATABASE"), 0, database); + + if (!connection->BackendMinimumVersion(8, 2)) + sql += GetGrant(wxT("CT"), wxT("DATABASE ") + qtIdent(name)); + else + sql += GetGrant(wxT("CTc"), wxT("DATABASE ") + qtIdent(name)); + + int cnt = lstVariables->GetItemCount(); + int pos; + + // check for changed or added vars + for (pos = 0 ; pos < cnt ; pos++) + { + wxString newUsr = lstVariables->GetText(pos); + wxString newVar = lstVariables->GetText(pos, 1); + wxString newVal = lstVariables->GetText(pos, 2); + + if (newUsr.Length() == 0) + sql += wxT("ALTER DATABASE ") + qtIdent(name); + else + sql += wxT("ALTER ROLE ") + newUsr + wxT(" IN DATABASE ") + qtIdent(name); + + if (newVar != wxT("search_path") && newVar != wxT("temp_tablespaces")) + { + sql += wxT("\n SET ") + newVar + wxT(" = '") + newVal + wxT("';\n"); + } + else + { + sql += wxT("\n SET ") + newVar + wxT(" = ") + newVal + wxT(";\n"); + } + } + if (seclabelPage && connection->BackendMinimumVersion(9, 2)) + sql += seclabelPage->GetSqlForSecLabels(wxT("DATABASE"), qtIdent(name)); + } + + return sql; +} + +bool dlgDatabase::GetDisconnectFirst() +{ + if (database) + return true; + return false; +} + +void dlgDatabase::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} diff --git a/dlg/dlgDomain.cpp b/dlg/dlgDomain.cpp new file mode 100644 index 0000000..a3992f2 --- /dev/null +++ b/dlg/dlgDomain.cpp @@ -0,0 +1,443 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgDomain.cpp - PostgreSQL Domain Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "frm/frmMain.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgDomain.h" +#include "dlg/dlgCheck.h" +#include "schema/pgSchema.h" +#include "schema/pgCheck.h" +#include "schema/pgDomain.h" +#include "schema/pgDatatype.h" +#include "ctl/ctlSeclabelPanel.h" + + +// pointer to controls +#define chkNotNull CTRL_CHECKBOX("chkNotNull") +#define txtDefault CTRL_TEXT("txtDefault") +#define cbCollation CTRL_COMBOBOX("cbCollation") +#define lstConstraints CTRL_LISTVIEW("lstConstraints") +#define btnAddConstr CTRL_BUTTON("btnAddConstr") +#define cbConstrType CTRL_COMBOBOX("cbConstrType") +#define btnRemoveConstr CTRL_BUTTON("btnRemoveConstr") + +BEGIN_EVENT_TABLE(dlgDomain, dlgTypeProperty) + EVT_TEXT(XRCID("txtLength"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtPrecision"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbDatatype"), dlgDomain::OnSelChangeTyp) + EVT_COMBOBOX(XRCID("cbDatatype"), dlgDomain::OnSelChangeTyp) + EVT_TEXT(XRCID("txLength"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtDefault"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkNotNull"), dlgProperty::OnChange) + EVT_BUTTON(XRCID("btnAddConstr"), dlgDomain::OnAddConstr) + EVT_BUTTON(XRCID("btnRemoveConstr"), dlgDomain::OnRemoveConstr) + EVT_LIST_ITEM_SELECTED(XRCID("lstConstraints"), dlgDomain::OnSelChangeConstr) +END_EVENT_TABLE(); + + +dlgProperty *pgDomainFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgDomain(this, frame, (pgDomain *)node, (pgSchema *)parent); +} + + +dlgDomain::dlgDomain(pgaFactory *f, frmMain *frame, pgDomain *node, pgSchema *sch) + : dlgTypeProperty(f, frame, wxT("dlgDomain")) +{ + schema = sch; + domain = node; + + seclabelPage = new ctlSeclabelPanel(nbNotebook); + + txtLength->Disable(); + txtPrecision->Disable(); + + lstConstraints->CreateColumns(0, _("Constraint name"), _("Definition"), 90); +} + + +pgObject *dlgDomain::GetObject() +{ + return domain; +} + + +int dlgDomain::Go(bool modal) +{ + if (connection->BackendMinimumVersion(9, 1)) + { + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(domain); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgDomain::OnChange)); + } + else + seclabelPage->Disable(); + + if (domain) + { + // edit mode + cbSchema->Enable(connection->BackendMinimumVersion(8, 1)); + cbDatatype->Append(domain->GetBasetype()); + AddType(wxT(" "), 0, domain->GetBasetype()); + cbDatatype->SetSelection(0); + if (domain->GetLength() >= 0) + { + txtLength->SetValue(NumToStr(domain->GetLength())); + if (domain->GetPrecision() >= 0) + txtPrecision->SetValue(NumToStr(domain->GetPrecision())); + } + chkNotNull->SetValue(domain->GetNotNull()); + txtDefault->SetValue(domain->GetDefault()); + + wxCookieType cookie; + pgObject *data = 0; + wxTreeItemId item = mainForm->GetBrowser()->GetFirstChild(domain->GetId(), cookie); + while (item) + { + data = mainForm->GetBrowser()->GetObject(item); + pgaFactory *factory = data->GetFactory(); + if (factory == checkFactory.GetCollectionFactory()) + constraintsItem = item; + else if (data->GetMetaType() == PGM_CONSTRAINT) + constraintsItem = item; + + if (constraintsItem) + break; + + item = mainForm->GetBrowser()->GetNextChild(domain->GetId(), cookie); + } + + if (constraintsItem) + { + pgCollection *coll = (pgCollection *)mainForm->GetBrowser()->GetObject(constraintsItem); + // make sure all constraints are appended + coll->ShowTreeDetail(mainForm->GetBrowser()); + // this is the constraints collection + item = mainForm->GetBrowser()->GetFirstChild(constraintsItem, cookie); + + // add constraints + while (item) + { + data = mainForm->GetBrowser()->GetObject(item); + switch (data->GetMetaType()) + { + case PGM_CHECK: + { + pgCheck *obj = (pgCheck *)data; + + lstConstraints->AppendItem(data->GetIconId(), obj->GetName(), obj->GetDefinition()); + constraintsDefinition.Add(obj->GetDefinition()); + previousConstraints.Add(obj->GetQuotedIdentifier() + + wxT(" ") + obj->GetTypeName().Upper() + wxT(" ") + obj->GetDefinition()); + break; + } + } + + item = mainForm->GetBrowser()->GetNextChild(constraintsItem, cookie); + } + } + + cbDatatype->Disable(); + + cbCollation->SetValue(domain->GetQuotedCollation()); + cbCollation->Disable(); + + if (!connection->BackendMinimumVersion(7, 4)) + { + cbOwner->Disable(); + txtDefault->Disable(); + chkNotNull->Disable(); + } + } + else + { + // create mode + FillDatatype(cbDatatype, false); + + cbCollation->Enable(connection->BackendMinimumVersion(9, 1)); + if (connection->BackendMinimumVersion(9, 1)) + { + // fill collation combobox + cbCollation->Append(wxEmptyString); + pgSet *set = connection->ExecuteSet( + wxT("SELECT nspname, collname\n") + wxT(" FROM pg_collation c, pg_namespace n\n") + wxT(" WHERE c.collnamespace=n.oid\n") + wxT(" ORDER BY nspname, collname")); + if (set) + { + while (!set->Eof()) + { + wxString name = qtIdent(set->GetVal(wxT("nspname"))) + wxT(".") + qtIdent(set->GetVal(wxT("collname"))); + cbCollation->Append(name); + set->MoveNext(); + } + delete set; + } + cbCollation->SetSelection(0); + } + } + + cbConstrType->Clear(); + cbConstrType->Append(_("Check")); + cbConstrType->SetSelection(0); + btnRemoveConstr->Disable(); + + return dlgProperty::Go(modal); +} + + +pgObject *dlgDomain::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + pgObject *obj = domainFactory.CreateObjects(collection, 0, + wxT(" AND d.typname=") + qtDbString(name) + + wxT("\n AND d.typnamespace=") + schema->GetOidStr() + + wxT("\n")); + return obj; +} + + +void dlgDomain::CheckChange() +{ + bool enable = true; + + if (domain) + { + enable = false; + if (connection->BackendMinimumVersion(7, 4) || lstColumns->GetItemCount() > 0) + { + enable = !GetSql().IsEmpty(); + } + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); + } + else + { + wxString name = GetName(); + long varlen = StrToLong(txtLength->GetValue()), + varprec = StrToLong(txtPrecision->GetValue()); + + txtPrecision->Enable(isVarPrec && varlen > 0); + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, cbDatatype->GetGuessedSelection() >= 0, _("Please select a datatype.")); + CheckValid(enable, !isVarLen || txtLength->GetValue().IsEmpty() + || (varlen >= minVarLen && varlen <= maxVarLen && NumToStr(varlen) == txtLength->GetValue()), + _("Please specify valid length.")); + CheckValid(enable, !txtPrecision->IsEnabled() + || (varprec >= 0 && varprec <= varlen && NumToStr(varprec) == txtPrecision->GetValue()), + _("Please specify valid numeric precision (0..") + NumToStr(varlen) + wxT(").")); + } + EnableOK(enable); +} + + + +void dlgDomain::OnSelChangeTyp(wxCommandEvent &ev) +{ + if (!domain) + { + cbDatatype->GuessSelection(ev); + CheckLenEnable(); + txtLength->Enable(isVarLen); + CheckChange(); + } +} + + +void dlgDomain::OnChangeValidate(wxCommandEvent &ev) +{ + CheckChange(); +} + + +wxString dlgDomain::GetSql() +{ + wxString sql, name; + int pos; + wxString definition; + int index = -1; + wxArrayString tmpDef = previousConstraints; + wxString tmpsql = wxEmptyString; + + if (domain) + { + // edit mode + name = GetName(); + + if (txtName->GetValue() != domain->GetName()) + { + + if (connection->BackendMinimumVersion(9, 2)) + AppendNameChange(sql, wxT("DOMAIN ") + domain->GetQuotedFullIdentifier()); + else + AppendNameChange(sql, wxT("TYPE ") + domain->GetQuotedFullIdentifier()); + } + if (chkNotNull->GetValue() != domain->GetNotNull()) + { + sql += wxT("ALTER DOMAIN ") + domain->GetQuotedFullIdentifier(); + if (chkNotNull->GetValue()) + sql += wxT("\n SET NOT NULL;\n"); + else + sql += wxT("\n DROP NOT NULL;\n"); + } + if (txtDefault->GetValue() != domain->GetDefault()) + { + sql += wxT("ALTER DOMAIN ") + domain->GetQuotedFullIdentifier(); + if (txtDefault->GetValue().IsEmpty()) + sql += wxT("\n DROP DEFAULT;\n"); + else + sql += wxT("\n SET DEFAULT ") + txtDefault->GetValue() + wxT(";\n"); + } + + // Build a temporary list of ADD CONSTRAINTs, and fixup the list to remove + for (pos = 0; pos < lstConstraints->GetItemCount() ; pos++) + { + wxString conname = qtIdent(lstConstraints->GetItemText(pos)); + definition = conname; + definition += wxT(" CHECK ") + constraintsDefinition.Item(pos); + index = tmpDef.Index(definition); + if (index >= 0) + tmpDef.RemoveAt(index); + else + { + tmpsql += wxT("ALTER DOMAIN ") + domain->GetQuotedFullIdentifier() + + wxT("\n ADD"); + if (!conname.IsEmpty()) + tmpsql += wxT(" CONSTRAINT "); + + tmpsql += definition + wxT(";\n"); + } + } + + // Add the DROP CONSTRAINTs... + for (index = 0 ; index < (int)tmpDef.GetCount() ; index++) + { + definition = tmpDef.Item(index); + if (definition[0U] == '"') + definition = definition.Mid(1).BeforeFirst('"'); + else + definition = definition.BeforeFirst(' '); + sql += wxT("ALTER DOMAIN ") + domain->GetQuotedFullIdentifier() + + wxT("\n DROP CONSTRAINT ") + qtIdent(definition) + wxT(";\n"); + + } + + // Add the ADD CONSTRAINTs... + sql += tmpsql; + + AppendOwnerChange(sql, wxT("DOMAIN ") + domain->GetQuotedFullIdentifier()); + AppendSchemaChange(sql, wxT("DOMAIN ") + domain->GetQuotedFullIdentifier()); + } + else + { + // create mode + name = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()); + sql = wxT("CREATE DOMAIN ") + name + + wxT("\n AS ") + GetQuotedTypename(cbDatatype->GetGuessedSelection()); + + if (!cbCollation->GetValue().IsEmpty() && cbCollation->GetValue() != wxT("pg_catalog.\"default\"")) + sql += wxT("\n COLLATE ") + cbCollation->GetValue(); + + AppendIfFilled(sql, wxT("\n DEFAULT "), txtDefault->GetValue()); + + if (chkNotNull->GetValue()) + sql += wxT("\n NOT NULL"); + + for (pos = 0 ; pos < lstConstraints->GetItemCount() ; pos++) + { + wxString name = lstConstraints->GetItemText(pos); + wxString definition = constraintsDefinition.Item(pos); + if (!name.IsEmpty()) + sql += wxT("\n CONSTRAINT ") + qtIdent(name) + wxT(" CHECK ") + definition; + else + sql += wxT("\n CHECK ") + definition; + } + + sql += wxT(";\n"); + + AppendOwnerNew(sql, wxT("DOMAIN ") + name); + } + + AppendComment(sql, wxT("DOMAIN ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), domain); + + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + sql += seclabelPage->GetSqlForSecLabels(wxT("DOMAIN"), name); + + return sql; +} + +void dlgDomain::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} + +void dlgDomain::OnAddConstr(wxCommandEvent &ev) +{ + int sel = cbConstrType->GetCurrentSelection(); + + switch (sel) + { + case 0: // Check + { + dlgCheck chk(&checkFactory, mainForm); + chk.CenterOnParent(); + chk.SetDatabase(database); + if (chk.Go(true) != wxID_CANCEL) + { + wxString tmpDef = chk.GetDefinition(); + tmpDef.Replace(wxT("\n"), wxT(" ")); + + lstConstraints->AppendItem(checkFactory.GetIconId(), chk.GetName(), tmpDef); + constraintsDefinition.Add(tmpDef); + } + break; + } + } + CheckChange(); +} + + +void dlgDomain::OnRemoveConstr(wxCommandEvent &ev) +{ + if (settings->GetConfirmDelete()) + { + if (wxMessageBox(_("Are you sure you wish to remove the selected constraint?"), _("Remove constraint?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) + return; + } + + int pos = lstConstraints->GetSelection(); + if (pos < 0) + return; + + lstConstraints->DeleteItem(pos); + constraintsDefinition.RemoveAt(pos); + btnRemoveConstr->Disable(); + + CheckChange(); +} + + +void dlgDomain::OnSelChangeConstr(wxListEvent &ev) +{ + btnRemoveConstr->Enable(); +} + + diff --git a/dlg/dlgEditGridOptions.cpp b/dlg/dlgEditGridOptions.cpp new file mode 100644 index 0000000..349ac03 --- /dev/null +++ b/dlg/dlgEditGridOptions.cpp @@ -0,0 +1,391 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgEditGridOptions.cpp - Edit Grid Box Options +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include +#include + +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/pgDefs.h" +#include "frm/frmMain.h" + +#include "frm/frmEditGrid.h" +#include "dlg/dlgEditGridOptions.h" +#include "schema/pgTable.h" +#include "schema/pgView.h" + +// Icons +#include "images/sortfilter.pngc" + +#define nbOptions CTRL_NOTEBOOK("nbOptions") +#define btnAsc CTRL_BUTTON("btnAsc") +#define btnDesc CTRL_BUTTON("btnDesc") +#define btnRemove CTRL_BUTTON("wxID_REMOVE") +#define btnValidate CTRL_BUTTON("btnValidate") +#define cboColumns CTRL_COMBOBOX("cboColumns") +#define lstSortCols CTRL_LISTVIEW("lstSortCols") +#define pnlSort CTRL_PANEL("pnlSort") +#define pnlFilter CTRL_PANEL("pnlFilter") +#define filter CTRL_SQLBOX("sqlFilter") + +BEGIN_EVENT_TABLE(dlgEditGridOptions, pgDialog) + EVT_CLOSE( dlgEditGridOptions::OnClose) + EVT_BUTTON (wxID_OK, dlgEditGridOptions::OnOK) + EVT_BUTTON (wxID_CANCEL, dlgEditGridOptions::OnCancel) + EVT_BUTTON (wxID_REMOVE, dlgEditGridOptions::OnRemove) + EVT_BUTTON (XRCID("btnAsc"), dlgEditGridOptions::OnAsc) + EVT_BUTTON (XRCID("btnDesc"), dlgEditGridOptions::OnDesc) + EVT_BUTTON (XRCID("btnValidate"), dlgEditGridOptions::OnValidate) + EVT_COMBOBOX (XRCID("cboColumns"), dlgEditGridOptions::OnCboColumnsChange) + EVT_LIST_ITEM_SELECTED (XRCID("lstSortCols"), dlgEditGridOptions::OnLstSortColsChange) + EVT_LIST_ITEM_DESELECTED (XRCID("lstSortCols"), dlgEditGridOptions::OnLstSortColsChange) + EVT_STC_MODIFIED (XRCID("sqlFilter"), dlgEditGridOptions::OnFilterChange) +#ifdef __WXMAC__ + EVT_SIZE( dlgEditGridOptions::OnChangeSize) +#endif +END_EVENT_TABLE() + +dlgEditGridOptions::dlgEditGridOptions(frmEditGrid *win, pgConn *conn, const wxString &rel, ctlSQLEditGrid *grid) +{ + editGrid = grid; + connection = conn; + relation = rel; + parent = win; + SetFont(settings->GetSystemFont()); + LoadResource(win, wxT("dlgEditGridOptions")); + conv = conn->GetConv(); + + // Icon + SetIcon(*sortfilter_png_ico); + RestorePosition(); + + int cols = grid->GetNumberCols(); + long x; + + for (x = 0; x < cols; x++) + cboColumns->Append(grid->GetColLabelValue(x).BeforeFirst('\n')); + + // Setup the buttons + wxCommandEvent nullEvent; + OnCboColumnsChange(nullEvent); + wxListEvent nullLstEvent; + OnLstSortColsChange(nullLstEvent); + + // Setup the list box + int leftSize = 140, rightSize; + leftSize = ConvertDialogToPixels(wxPoint(leftSize, 0)).x; + rightSize = lstSortCols->GetClientSize().GetWidth() - leftSize; + // This check is to work around a bug in wxGTK that doesn't set + // appropriately the GetClientSize(). + // Without this workaround, we have an invisible second column. + if (rightSize < leftSize) + rightSize = leftSize + 1; + lstSortCols->InsertColumn(0, _("Column name"), wxLIST_FORMAT_LEFT, leftSize); + lstSortCols->InsertColumn(1, _("Sort order"), wxLIST_FORMAT_LEFT, rightSize); + + // Setup the filter SQL box. This is an XRC 'unknown' control so must + // be manually created and attache to the XRC global resource. + filter->SetText(parent->GetFilter()); + + // Get the current sort columns, and populate the listbox. + // The current columns will be parsed char by char to allow us + // to cope with quoted column names with commas in them (let's hope + // no one ever does that, but sod's law etc....) + bool inColumn = true, inQuote = false; + wxString sortCols = parent->GetSortCols(); + wxString col, dir; + size_t pos, len = sortCols.Length(); + int itm = 0; + + for (pos = 0; pos < len; pos++) + { + if (inColumn) + { + if (sortCols.GetChar(pos) == '"') inQuote = !inQuote; + if (!inQuote && (sortCols.GetChar(pos) == ' ' || sortCols.GetChar(pos) == ',')) + inColumn = false; + else if (sortCols.GetChar(pos) != '"') col += sortCols.GetChar(pos); + } + else + { + if (sortCols.GetChar(pos - 1) == ',') + { + inColumn = true; + lstSortCols->InsertItem(itm, col); + if (dir.GetChar(0) == 'D') + { + lstSortCols->SetItem(itm, 1, _("Descending")); + lstSortCols->SetItemData(itm, 0); + } + else + { + lstSortCols->SetItem(itm, 1, _("Ascending")); + lstSortCols->SetItemData(itm, 1); + } + col = wxT(""); + dir = wxT(""); + ++itm; + } + else + { + dir += sortCols.GetChar(pos); + } + } + } + + // Insert the last column + if (col.Length() > 0) + { + lstSortCols->InsertItem(itm, col); + if (dir.GetChar(0) == 'D') + { + lstSortCols->SetItem(itm, 1, _("Descending")); + lstSortCols->SetItemData(itm, 0); + } + else + { + lstSortCols->SetItem(itm, 1, _("Ascending")); + lstSortCols->SetItemData(itm, 1); + } + } + + // Finally (phew!) remove all columns we're already sorting on from the list. + long count = lstSortCols->GetItemCount(); + + for (x = 0; x < count; x++) + { + int idx = cboColumns->FindString(lstSortCols->GetItemText(x)); + if (idx >= 0) + cboColumns->Delete(idx); + } + + // Display the appropriate tab. If the EditGrid is not shown, we must be + // doing a View Filtered Data. + if (!parent->IsShown()) + nbOptions->DeletePage(0); + + btnValidate->Disable(); + filter->SetFocus(); +} + +dlgEditGridOptions::~dlgEditGridOptions() +{ + SavePosition(); +} + +// Enable/disable the validation button +void dlgEditGridOptions::OnFilterChange(wxStyledTextEvent &ev) +{ + btnValidate->Enable(!filter->GetText().Trim().IsEmpty()); +} + +void dlgEditGridOptions::OnRemove(wxCommandEvent &ev) +{ + long itm = -1; + itm = lstSortCols->GetNextItem(itm, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + cboColumns->Append(lstSortCols->GetItemText(itm)); + lstSortCols->DeleteItem(itm); + if (lstSortCols->GetItemCount() > 0) + { + if (lstSortCols->GetItemCount() < itm + 1) + lstSortCols->SetItemState(lstSortCols->GetItemCount() - 1, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); + else + lstSortCols->SetItemState(itm, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); + } + wxListEvent nullLstEvent; + OnLstSortColsChange(nullLstEvent); +} + + +void dlgEditGridOptions::OnAsc(wxCommandEvent &ev) +{ + long itm = lstSortCols->GetItemCount(); + lstSortCols->InsertItem(itm, cboColumns->GetValue()); + lstSortCols->SetItem(itm, 1, _("Ascending")); + lstSortCols->SetItemData(itm, 1); + cboColumns->Delete(cboColumns->GetCurrentSelection()); + + // Setup the buttons + OnCboColumnsChange(ev); + wxListEvent nullLstEvent; + OnLstSortColsChange(nullLstEvent); +} + +void dlgEditGridOptions::OnDesc(wxCommandEvent &ev) +{ + long itm = lstSortCols->GetItemCount(); + lstSortCols->InsertItem(itm, cboColumns->GetValue()); + lstSortCols->SetItem(itm, 1, _("Descending")); + lstSortCols->SetItemData(itm, 0); + cboColumns->Delete(cboColumns->GetCurrentSelection()); + + // Setup the buttons + OnCboColumnsChange(ev); + wxListEvent nullLstEvent; + OnLstSortColsChange(nullLstEvent); +} + +#ifdef __WXMAC__ +void dlgEditGridOptions::OnChangeSize(wxSizeEvent &ev) +{ + if (lstSortCols) + lstSortCols->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + +void dlgEditGridOptions::OnValidate(wxCommandEvent &ev) +{ + if (Validate()) + wxMessageBox(_("Filter string syntax validates OK!"), _("Syntax Validation"), wxICON_INFORMATION | wxOK); +} + +void dlgEditGridOptions::OnCboColumnsChange(wxCommandEvent &ev) +{ + // Set the command buttons appropriately + if (cboColumns->GetCurrentSelection() == wxNOT_FOUND) + { + btnAsc->Enable(false); + btnDesc->Enable(false); + } + else + { + btnAsc->Enable(true); + btnDesc->Enable(true); + } +} + +void dlgEditGridOptions::OnLstSortColsChange(wxListEvent &ev) +{ + // Set the command buttons appropriately + if (lstSortCols->GetSelectedItemCount() == 0) + btnRemove->Enable(false); + else + btnRemove->Enable(true); +} + +void dlgEditGridOptions::OnCancel(wxCommandEvent &ev) +{ + EndModal(false); +} + + +void dlgEditGridOptions::OnClose(wxCloseEvent &ev) +{ + EndModal(false); +} + +void dlgEditGridOptions::OnOK(wxCommandEvent &ev) +{ +#ifdef __WXGTK__ + if (!btnOK->IsEnabled()) + return; +#endif + // Check the filter syntax + if (!Validate()) return; + + if (nbOptions->GetPageCount() > 1) + { + wxString sortCols; + long x, count = lstSortCols->GetItemCount(); + + for (x = 0; x < count; x++) + { + sortCols += qtIdent(lstSortCols->GetItemText(x)); + if (lstSortCols->GetItemData(x) == 0) + sortCols += wxT(" DESC"); + else + sortCols += wxT(" ASC"); + sortCols += wxT(", "); + } + + if (sortCols.Length() > 2) + { + sortCols.RemoveLast(); + sortCols.RemoveLast(); + } + + parent->SetSortCols(sortCols); + } + + parent->SetFilter(filter->GetText().Trim()); + EndModal(true); +} + +bool dlgEditGridOptions::Validate() +{ + winMain->StartMsg(_("Validating filter string")); + filter->MarkerDeleteAll(0); + if (!filter->GetText().Trim().Length()) + { + winMain->EndMsg(); + return true; + } + + wxString sql = wxT("EXPLAIN SELECT * FROM ") + relation + wxT(" WHERE "); + int queryOffset = sql.Length(); + sql += filter->GetText(); + + PGresult *qryRes; + qryRes = PQexec(connection->connection(), sql.mb_str(*conv)); + int res = PQresultStatus(qryRes); + + // Check for errors + if (res == PGRES_TUPLES_OK || + res == PGRES_COMMAND_OK) + { + // No errors, all OK! + winMain->EndMsg(); + return true; + } + + // Figure out where the error is + wxString errMsg = connection->GetLastError(); + + wxString atChar = wxT(" at character "); + int chp = errMsg.Find(atChar); + + if (chp > 0) + { + int selStart = filter->GetSelectionStart(), selEnd = filter->GetSelectionEnd(); + if (selStart == selEnd) + selStart = 0; + + long errPos = 0; + errMsg.Mid(chp + atChar.Length()).ToLong(&errPos); + errPos -= queryOffset; // do not count EXPLAIN or similar + wxLogError(wxT("%s"), _("ERROR: Syntax error at character %d!"), errPos); + + int line = 0, maxLine = filter->GetLineCount(); + while (line < maxLine && filter->GetLineEndPosition(line) < errPos + selStart + 1) + line++; + if (line < maxLine) + { + filter->MarkerAdd(line, 0); + filter->EnsureVisible(line); + } + } + else + wxLogError(wxT("%s"), errMsg.BeforeFirst('\n').c_str()); + + // Cleanup + PQclear(qryRes); + winMain->EndMsg(); + return false; +} diff --git a/dlg/dlgEventTrigger.cpp b/dlg/dlgEventTrigger.cpp new file mode 100644 index 0000000..b04cbec --- /dev/null +++ b/dlg/dlgEventTrigger.cpp @@ -0,0 +1,247 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgEventTrigger.cpp - PostgreSQL Trigger Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "frm/frmMain.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgEventTrigger.h" +#include "schema/pgEventTrigger.h" +#include "ctl/ctlSeclabelPanel.h" + +// pointer to controls +#define chkEnable CTRL_CHECKBOX("chkEnable") +#define rdbEnableStatus CTRL_RADIOBOX("rdbEnableStatus") +#define cbFunction CTRL_COMBOBOX2("cbFunction") +#define rdbEvents CTRL_RADIOBOX("rdbEvents") +#define txtWhen CTRL_TEXT("txtWhen") +#define cbOwner CTRL_COMBOBOX2("cbOwner") + +BEGIN_EVENT_TABLE(dlgEventTrigger, dlgProperty) + EVT_CHECKBOX(XRCID("chkEnable"), dlgEventTrigger::OnChangeEnable) + EVT_RADIOBOX(XRCID("rdbEnableStatus"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbFunction"), dlgProperty::OnChange) + EVT_RADIOBOX(XRCID("rdbEvents"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtWhen"), dlgProperty::OnChange) +END_EVENT_TABLE(); + +dlgEventTrigger::dlgEventTrigger(pgaFactory *factory, frmMain *frame, pgEventTrigger *node, pgObject *parent) + : dlgProperty(factory, frame, wxT("dlgEventTrigger")) +{ + seclabelPage = new ctlSeclabelPanel(nbNotebook); + eventTrigger = node; +} + +dlgProperty *pgEventTriggerFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgEventTrigger(this, frame, (pgEventTrigger *)node, parent); +} + +wxString dlgEventTrigger::GetSql() +{ + wxString sql = wxEmptyString; + wxString name = GetName(); + + if (eventTrigger) + { + if (!GetName().IsEmpty() && GetName() != eventTrigger->GetName()) + sql = wxT("ALTER EVENT TRIGGER ") + eventTrigger->GetQuotedFullIdentifier() + wxT("\nRENAME TO ") + qtIdent(GetName()) + wxT(";\n\n"); + + if (!cbOwner->GetValue().IsEmpty() && cbOwner->GetValue() != eventTrigger->GetOwner()) + sql += wxT("ALTER EVENT TRIGGER ") + eventTrigger->GetQuotedFullIdentifier() + wxT("\nOWNER TO ") + cbOwner->GetValue() + wxT(";\n\n"); + + if (rdbEnableStatus->GetSelection() != 0 && chkEnable->GetValue()) + sql += wxT("ALTER EVENT TRIGGER ") + qtIdent(name) + ((rdbEnableStatus->GetSelection() == 1) ? wxT(" ENABLE REPLICA ;\n\n") : wxT(" ENABLE ALWAYS ;\n\n")); + else if (!chkEnable->GetValue()) + sql += wxT("ALTER EVENT TRIGGER ") + qtIdent(name) + wxT(" DISABLE ;\n\n"); + } + + if (!eventTrigger || + ( + cbFunction->GetValue() != (eventTrigger->GetFunction()) || + rdbEvents->GetStringSelection().Lower() != (eventTrigger->GetEventName().Lower()) || + txtWhen->GetValue() != (eventTrigger->GetWhen()) + ) + ) + { + if (eventTrigger) + sql = wxT("DROP EVENT TRIGGER IF EXISTS ") + ((eventTrigger) ? qtIdent(eventTrigger->GetName()) : qtIdent(GetName())) + wxT(";\n\n"); + + sql += wxT("CREATE EVENT TRIGGER ") + qtIdent(name) + wxT(" ON "); + + if (rdbEvents->GetSelection() == 0) + sql += wxT(" DDL_COMMAND_START "); + else if (rdbEvents->GetSelection() == 1) + sql += wxT(" DDL_COMMAND_END "); + else + sql += wxT(" SQL_DROP "); + + if (!txtWhen->IsEmpty()) + sql += wxT("\nWHEN TAG IN (") + txtWhen->GetValue() + wxT(")"); + + if (!cbFunction->GetValue().IsEmpty()) + sql += wxT("\nEXECUTE PROCEDURE ") + (cbFunction->GetValue()) + wxT("();\n\n"); + + if (rdbEnableStatus->GetSelection() != 0 && chkEnable->GetValue()) + sql += wxT("ALTER EVENT TRIGGER ") + qtIdent(name) + ((rdbEnableStatus->GetSelection() == 1) ? wxT(" ENABLE REPLICA ;\n\n") : wxT(" ENABLE ALWAYS ;\n\n")); + else if (!chkEnable->GetValue()) + sql += wxT("ALTER EVENT TRIGGER ") + qtIdent(name) + wxT(" DISABLE ;\n\n"); + + if (!eventTrigger && !cbOwner->GetValue().IsEmpty()) + sql += wxT("ALTER EVENT TRIGGER ") + qtIdent(GetName()) + wxT("\nOWNER TO ") + cbOwner->GetValue() + wxT(";\n\n"); + } + + AppendComment(sql, wxT("EVENT TRIGGER ") + qtIdent(GetName()), eventTrigger); + + if (seclabelPage) + sql += seclabelPage->GetSqlForSecLabels(wxT("EVENT TRIGGER"), qtIdent(name)); + + return sql; +} + +pgObject *dlgEventTrigger::CreateObject(pgCollection *pgcol) +{ + pgObject *obj = eventTriggerFactory.CreateObjects(pgcol, 0, + wxT(" \n AND e.evtname = ") + qtDbString(GetName())); + return obj; +} + +pgObject *dlgEventTrigger::GetObject() +{ + return eventTrigger; +} + +int dlgEventTrigger::Go(bool modal) +{ + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(eventTrigger); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgEventTrigger::OnChange)); + + if (eventTrigger) + { + // Edit mode + chkEnable->SetValue(eventTrigger->GetEnabled()); + + if (eventTrigger->GetEnableStatus() == wxT("enabled")) + rdbEnableStatus->SetSelection(0); + else if(eventTrigger->GetEnableStatus() == wxT("replica")) + rdbEnableStatus->SetSelection(1); + else if(eventTrigger->GetEnableStatus() == wxT("always")) + rdbEnableStatus->SetSelection(2); + else + rdbEnableStatus->Disable(); + + if(eventTrigger->GetEventName().Lower() == wxT("ddl command start")) + rdbEvents->SetSelection(0); + else if(eventTrigger->GetEventName().Lower() == wxT("ddl command end")) + rdbEvents->SetSelection(1); + else + rdbEvents->SetSelection(2); + + cbFunction->SetValue(eventTrigger->GetFunction()); + cbOwner->SetValue(eventTrigger->GetOwner()); + (!eventTrigger->GetWhen().IsEmpty()) ? txtWhen->SetValue(eventTrigger->GetWhen()) : txtWhen->SetValue(wxEmptyString); + } + else + { + // Create mode + chkEnable->SetValue(true); + rdbEnableStatus->Disable(); + } + + pgSet *funcSet = connection->ExecuteSet( + wxT("SELECT quote_ident(nspname) || '.' || quote_ident(proname)\n") + wxT(" FROM pg_proc p, pg_namespace n, pg_language l\n") + wxT(" WHERE p.pronamespace = n.oid AND p.prolang = l.oid AND p.pronargs = 0 AND l.lanname != 'sql' AND prorettype::regtype::text = 'event_trigger'\n") + wxT(" ORDER BY nspname ASC, proname ASC ")); + if (funcSet) + { + while (!funcSet->Eof()) + { + cbFunction->Append(funcSet->GetVal(0)); + funcSet->MoveNext(); + } + delete funcSet; + } + + pgSet *userSet = connection->ExecuteSet( + wxT("SELECT usename ") + wxT("FROM pg_user ") + wxT("WHERE usesuper IS TRUE")); + if (userSet) + { + while (!userSet->Eof()) + { + cbOwner->Append(userSet->GetVal(0)); + userSet->MoveNext(); + } + delete userSet; + } + + return dlgProperty::Go(modal); +} + +void dlgEventTrigger::CheckChange() +{ + bool enable = true; + + wxString function = cbFunction->GetValue(); + wxString name = GetName(); + wxString owner = cbOwner->GetValue(); + + (chkEnable->GetValue()) ? rdbEnableStatus->Enable() : rdbEnableStatus->Disable(); + + CheckValid(enable, !name.IsEmpty(), _("Please specify event trigger name.")); + CheckValid(enable, !owner.IsEmpty(), _("Please specify owner of event trigger.")); + CheckValid(enable, !function.IsEmpty(), _("Please specify event trigger function.")); + + if (eventTrigger) + { + EnableOK(enable && + (txtComment->GetValue() != eventTrigger->GetComment() || + txtName->GetValue() != eventTrigger->GetName() || + txtWhen->GetValue() != eventTrigger->GetWhen() || + chkEnable->GetValue() != eventTrigger->GetEnabled() || + rdbEvents->GetStringSelection().Lower() != eventTrigger->GetEventName().Lower() || + rdbEnableStatus->GetStringSelection().Lower() != eventTrigger->GetEnableStatus().Lower() || + !function.IsEmpty() || + !owner.IsEmpty() + ) + ); + } + else + { + EnableOK(enable); + } +} + +bool dlgEventTrigger::IsUpToDate() +{ + if (eventTrigger && !eventTrigger->IsUpToDate()) + return false; + else + return true; +} + +void dlgEventTrigger::OnChange(wxCommandEvent &ev) +{ + CheckChange(); +} + +void dlgEventTrigger::OnChangeEnable(wxCommandEvent &ev) +{ + CheckChange(); +} diff --git a/dlg/dlgExtTable.cpp b/dlg/dlgExtTable.cpp new file mode 100644 index 0000000..d6f47a8 --- /dev/null +++ b/dlg/dlgExtTable.cpp @@ -0,0 +1,166 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgExtTable.cpp - Greenplum Externtal Table Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "ctl/ctlSQLBox.h" +#include "dlg/dlgExtTable.h" +#include "schema/gpExtTable.h" +#include "schema/pgSchema.h" + + + +// pointer to controls +#define pnlDefinition CTRL_PANEL("pnlDefinition") +#define txtSqlBox CTRL_SQLBOX("txtSqlBox") + + + +BEGIN_EVENT_TABLE(dlgExtTable, dlgSecurityProperty) + EVT_STC_MODIFIED(XRCID("txtSqlBox"), dlgProperty::OnChangeStc) +END_EVENT_TABLE(); + + +dlgProperty *gpExtTableFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgExtTable(this, frame, (gpExtTable *)node, (pgSchema *)parent); +} + +dlgExtTable::dlgExtTable(pgaFactory *f, frmMain *frame, gpExtTable *node, pgSchema *sch) + : dlgSecurityProperty(f, frame, node, wxT("dlgExtTable"), wxT("SELECT"), "r") +{ + schema = sch; + extTable = node; + +} + + +pgObject *dlgExtTable::GetObject() +{ + return extTable; +} + + +int dlgExtTable::Go(bool modal) +{ + int returncode; + + if (extTable) + { + // edit mode + + // TODO: Make this more like dlgTable, so that it is easier to use. + // Right now, this is just dummy code until that code is written. + txtSqlBox->SetText(wxT("(") + extTable->GetSql(NULL).AfterFirst('(')); + oldDefinition = txtSqlBox->GetText(); + txtSqlBox->Enable(false); + } + else + { + // create mode + } + + returncode = dlgSecurityProperty::Go(modal); + + // This fixes a UI glitch on MacOS X and Windows + // Because of the new layout code, the Privileges pane don't size itself properly + SetSize(GetSize().GetWidth() + 1, GetSize().GetHeight()); + SetSize(GetSize().GetWidth() - 1, GetSize().GetHeight()); + + return returncode; +} + + +pgObject *dlgExtTable::CreateObject(pgCollection *collection) +{ + pgObject *obj = extTableFactory.CreateObjects(collection, 0, + wxT("\n AND c.relname=") + qtDbString(txtName->GetValue()) + + wxT("\n AND c.relnamespace=") + schema->GetOidStr()); + return obj; +} + + +void dlgExtTable::CheckChange() +{ + wxString name = GetName(); + if(!name.IsEmpty()) + { + if (extTable) + EnableOK(txtComment->GetValue() != extTable->GetComment() + || txtSqlBox->GetText() != oldDefinition + || cbOwner->GetValue() != extTable->GetOwner() + || name != extTable->GetName()); + else + EnableOK(!txtComment->GetValue().IsEmpty() + || !txtSqlBox->GetText().IsEmpty() + || !cbOwner->GetValue().IsEmpty()); + } + else + { + bool enable = true; + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, txtSqlBox->GetText().Length() > 0 , _("Please enter external table definition.")); + + EnableOK(enable); + } +} + + +wxString dlgExtTable::GetSql() +{ + wxString sql, name = GetName(); + + + if (extTable) + { + // edit mode + + if (name != extTable->GetName()) + { + sql += wxT("ALTER TABLE ") + extTable->GetQuotedFullIdentifier() + + wxT(" RENAME TO ") + qtIdent(name) + wxT(";\n"); + } + } + + if (!extTable || txtSqlBox->GetText() != oldDefinition) + { + sql += wxT("CREATE EXTERNAL TABLE ") + schema->GetQuotedPrefix() + qtIdent(name) + wxT("\n") + + txtSqlBox->GetText() + + wxT(";\n"); + } + + if (extTable) + AppendOwnerChange(sql, wxT("TABLE ") + schema->GetQuotedPrefix() + qtIdent(name)); + else + AppendOwnerNew(sql, wxT("TABLE ") + schema->GetQuotedPrefix() + qtIdent(name)); + + + sql += GetGrant(wxT("r"), wxT("TABLE ") + schema->GetQuotedPrefix() + qtIdent(name)); + + AppendComment(sql, wxT("TABLE"), schema, extTable); + return sql; +} + +bool dlgExtTable::IsUpToDate() +{ + if (extTable && !extTable->IsUpToDate()) + return false; + else + return true; +} + diff --git a/dlg/dlgExtension.cpp b/dlg/dlgExtension.cpp new file mode 100644 index 0000000..cfa62a3 --- /dev/null +++ b/dlg/dlgExtension.cpp @@ -0,0 +1,198 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgExtension.cpp - PostgreSQL Extension Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgExtension.h" +#include "schema/pgExtension.h" + + +// pointer to controls +#define cbName CTRL_COMBOBOX("cbName") +#define cbObjectsSchema CTRL_COMBOBOX("cbObjectsSchema") +#define cbVersion CTRL_COMBOBOX("cbVersion") + + +dlgProperty *pgExtensionFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgExtension(this, frame, (pgExtension *)node); +} + + +BEGIN_EVENT_TABLE(dlgExtension, dlgProperty) + EVT_TEXT(XRCID("cbName"), dlgExtension::OnChangeName) + EVT_COMBOBOX(XRCID("cbName"), dlgExtension::OnChangeName) + EVT_TEXT(XRCID("cbObjectsSchema"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbObjectsSchema"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbVersion"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbVersion"), dlgProperty::OnChange) +END_EVENT_TABLE(); + + +dlgExtension::dlgExtension(pgaFactory *f, frmMain *frame, pgExtension *node) + : dlgProperty(f, frame, wxT("dlgExtension")) +{ + extension = node; +} + + +pgObject *dlgExtension::GetObject() +{ + return extension; +} + + +int dlgExtension::Go(bool modal) +{ + txtComment->Disable(); + + // add all schemas + cbObjectsSchema->Append(wxEmptyString); + pgSetIterator schemas(connection, + wxT("SELECT nspname FROM pg_namespace\n") + wxT(" ORDER BY nspname")); + + while (schemas.RowsLeft()) + cbObjectsSchema->Append(schemas.GetVal(wxT("nspname"))); + cbObjectsSchema->SetSelection(0); + + if (extension) + { + // edit mode + cbName->Append(extension->GetName()); + cbName->SetSelection(0); + cbName->Disable(); + + cbObjectsSchema->SetValue(extension->GetSchemaStr()); + cbObjectsSchema->Enable(extension->GetIsRelocatable()); + + // add all versions + cbVersion->Clear(); + cbVersion->Append(wxEmptyString); + pgSetIterator versions(connection, + wxT("SELECT version, relocatable FROM pg_available_extension_versions\n") + wxT(" WHERE name=") + qtDbString(cbName->GetValue()) + wxT(" ") + wxT(" ORDER BY version")); + + while (versions.RowsLeft()) + cbVersion->Append(versions.GetVal(wxT("version"))); + cbVersion->SetValue(extension->GetVersion()); + } + else + { + // create mode + + // add available extensions (but not the installed ones) + cbName->Append(wxEmptyString); + pgSetIterator extensions(connection, + wxT("SELECT name FROM pg_available_extensions\n") + wxT(" WHERE installed_version IS NULL\n") + wxT(" ORDER BY name")); + + while (extensions.RowsLeft()) + cbName->Append(extensions.GetVal(wxT("name"))); + cbName->SetSelection(0); + } + + return dlgProperty::Go(modal); +} + + +pgObject *dlgExtension::CreateObject(pgCollection *collection) +{ + wxString name = cbName->wxComboBox::GetValue(); + + pgObject *obj = extensionFactory.CreateObjects(collection, 0, wxT("\n AND extname ILIKE ") + qtDbString(name)); + return obj; +} + + +void dlgExtension::OnChangeName(wxCommandEvent &ev) +{ + bool relocatable; + + // add all versions + cbVersion->Clear(); + cbVersion->Append(wxEmptyString); + pgSetIterator versions(connection, + wxT("SELECT version, relocatable FROM pg_available_extension_versions\n") + wxT(" WHERE name=") + qtDbString(cbName->GetValue()) + wxT(" ") + wxT(" ORDER BY version")); + + while (versions.RowsLeft()) + { + relocatable = versions.GetBool(wxT("relocatable")); + cbVersion->Append(versions.GetVal(wxT("version"))); + } + cbVersion->SetSelection(0); + + if (relocatable) + { + cbObjectsSchema->Enable(); + } + else + { + cbObjectsSchema->SetSelection(0); + cbObjectsSchema->Disable(); + } + + OnChange(ev); +} + + +void dlgExtension::CheckChange() +{ + bool didChange = true; + if (extension) + { + didChange = cbObjectsSchema->GetValue() != extension->GetSchemaStr() + || cbVersion->GetValue() != extension->GetVersion(); + EnableOK(didChange); + } + else + { + bool enable = true; + + CheckValid(enable, !cbName->GetValue().IsEmpty(), _("Please specify name.")); + EnableOK(enable); + } +} + + +wxString dlgExtension::GetSql() +{ + wxString sql; + + if (extension) + { + // edit mode + if (cbObjectsSchema->GetValue() != extension->GetSchemaStr()) + sql += wxT("ALTER EXTENSION ") + qtIdent(extension->GetName()) + + wxT("\n SET SCHEMA ") + qtIdent(cbObjectsSchema->GetValue()) + wxT(";\n"); + if (cbVersion->GetValue() != extension->GetVersion()) + sql += wxT("ALTER EXTENSION ") + qtIdent(extension->GetName()) + + wxT("\n UPDATE TO ") + qtIdent(cbVersion->GetValue()) + wxT(";\n"); + } + else + { + sql = wxT("CREATE EXTENSION ") + qtIdent(cbName->GetValue()); + AppendIfFilled(sql, wxT("\n SCHEMA "), qtIdent(cbObjectsSchema->GetValue())); + AppendIfFilled(sql, wxT("\n VERSION "), qtIdent(cbVersion->GetValue())); + } + + return sql; +} diff --git a/dlg/dlgFindReplace.cpp b/dlg/dlgFindReplace.cpp new file mode 100644 index 0000000..a4dc9f3 --- /dev/null +++ b/dlg/dlgFindReplace.cpp @@ -0,0 +1,311 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgFindReplace.cpp - Search and replace +// +////////////////////////////////////////////////////////////////////////// + + + +// App headers +#include "pgAdmin3.h" + +#include "dlg/dlgFindReplace.h" +#include "ctl/ctlSQLBox.h" + +BEGIN_EVENT_TABLE(dlgFindReplace, pgDialog) + EVT_BUTTON (wxID_FIND, dlgFindReplace::OnFind) + EVT_BUTTON (wxID_REPLACE, dlgFindReplace::OnReplace) + EVT_BUTTON (XRCID("wxID_REPLACEALL"), dlgFindReplace::OnReplaceAll) + EVT_BUTTON (wxID_CANCEL, dlgFindReplace::OnCancel) + EVT_RADIOBUTTON(XRCID("rdOriginCursor"), dlgFindReplace::OnChange) + EVT_RADIOBUTTON(XRCID("rdOriginTop"), dlgFindReplace::OnChange) + EVT_CHECKBOX(XRCID("chkOptionsUseRegexps"), dlgFindReplace::OnChange) + EVT_CLOSE( dlgFindReplace::OnClose) +END_EVENT_TABLE() + + +#define btnFind CTRL_BUTTON("wxID_FIND") +#define btnReplace CTRL_BUTTON("wxID_REPLACE") +#define btnReplaceAll CTRL_BUTTON("wxID_REPLACEALL") +#define btnCancel CTRL_BUTTON("wxID_CANCEL") +#define txtFind CTRL_TEXT("txtFind") +#define txtReplace CTRL_TEXT("txtReplace") +#define rdOriginTop CTRL_RADIOBUTTON("rdOriginTop") +#define rdOriginCursor CTRL_RADIOBUTTON("rdOriginCursor") +#define rdDirectionForward CTRL_RADIOBUTTON("rdDirectionForward") +#define rdDirectionBackward CTRL_RADIOBUTTON("rdDirectionBackward") +#define chkOptionsWholeWord CTRL_CHECKBOX("chkOptionsWholeWord") +#define chkOptionsMatchCase CTRL_CHECKBOX("chkOptionsMatchCase") +#define chkOptionsUseRegexps CTRL_CHECKBOX("chkOptionsUseRegexps") + +dlgFindReplace::dlgFindReplace(ctlSQLBox *parent) : + pgDialog() +{ + sqlbox = parent; + + SetFont(settings->GetSystemFont()); + LoadResource(parent, wxT("dlgFindReplace")); + RestorePosition(); + + // Icon + appearanceFactory->SetIcons(this); + + // Accelerator table + wxAcceleratorEntry entries[2]; + entries[0].Set(wxACCEL_NORMAL, WXK_F3, wxID_FIND); + entries[1].Set(wxACCEL_SHIFT, WXK_F3, wxID_FIND); + wxAcceleratorTable accel(2, entries); + SetAcceleratorTable(accel); + + + // Load up the defaults + wxString val; + bool bVal; + + // Find/Replace values + settings->Read(wxT("FindReplace/Find"), &val, wxT("")); + txtFind->SetValue(val); + + settings->Read(wxT("FindReplace/Replace"), &val, wxT("")); + txtReplace->SetValue(val); + + // Origin + settings->Read(wxT("FindReplace/Origin"), &val, wxT("c")); + if (val == wxT("t")) + { + rdOriginCursor->SetValue(false); + rdOriginTop->SetValue(true); + } + else + { + rdOriginCursor->SetValue(true); + rdOriginTop->SetValue(false); + } + + // Direction + settings->Read(wxT("FindReplace/Direction"), &val, wxT("f")); + if (val == wxT("b")) + { + rdDirectionForward->SetValue(false); + rdDirectionBackward->SetValue(true); + } + else + { + rdDirectionForward->SetValue(true); + rdDirectionBackward->SetValue(false); + } + + // WholeWord + settings->Read(wxT("FindReplace/WholeWord"), &bVal, false); + chkOptionsWholeWord->SetValue(bVal); + + // MatchCase + settings->Read(wxT("FindReplace/MatchCase"), &bVal, false); + chkOptionsMatchCase->SetValue(bVal); + + // UseRegexps + settings->Read(wxT("FindReplace/UseRegexps"), &bVal, false); + chkOptionsUseRegexps->SetValue(bVal); + + wxCommandEvent ev; + OnChange(ev); + ResetTabOrder(); +} + +dlgFindReplace::~dlgFindReplace() +{ + SavePosition(); +} + +void dlgFindReplace::FocusSearch() +{ + txtFind->SetFocus(); + txtFind->SetSelection(-1, -1); +} + +void dlgFindReplace::SaveSettings() +{ + settings->Write(wxT("FindReplace/Find"), txtFind->GetValue()); + settings->Write(wxT("FindReplace/Replace"), txtReplace->GetValue()); + + if (rdOriginTop->GetValue()) + settings->Write(wxT("FindReplace/Origin"), wxT("t")); + else + settings->Write(wxT("FindReplace/Origin"), wxT("c")); + + if (rdDirectionBackward->GetValue()) + settings->Write(wxT("FindReplace/Direction"), wxT("b")); + else + settings->Write(wxT("FindReplace/Direction"), wxT("f")); + + settings->WriteBool(wxT("FindReplace/WholeWord"), chkOptionsWholeWord->GetValue()); + settings->WriteBool(wxT("FindReplace/MatchCase"), chkOptionsMatchCase->GetValue()); + settings->WriteBool(wxT("FindReplace/UseRegexps"), chkOptionsUseRegexps->GetValue()); +} + +void dlgFindReplace::OnClose(wxCloseEvent &ev) +{ + SaveSettings(); + this->Hide(); + if (ev.CanVeto()) + ev.Veto(); +} + +void dlgFindReplace::OnCancel(wxCommandEvent &ev) +{ + SaveSettings(); + this->Hide(); +} + +void dlgFindReplace::OnChange(wxCommandEvent &ev) +{ + if (chkOptionsUseRegexps->GetValue() == true || rdOriginTop->GetValue() == true) + { + rdDirectionForward->SetValue(true); + rdDirectionBackward->SetValue(false); + rdDirectionBackward->Enable(false); + } + else + { + rdDirectionBackward->Enable(true); + } + + if (chkOptionsUseRegexps->GetValue() == true) + { + chkOptionsWholeWord->Enable(false); + chkOptionsMatchCase->Enable(false); + } + else + { + chkOptionsWholeWord->Enable(true); + chkOptionsMatchCase->Enable(true); + } +} + +void dlgFindReplace::OnFind(wxCommandEvent &ev) +{ + if (txtFind->GetValue().IsEmpty()) + return; + + bool wholeWord = false, + matchCase = false, + useRegexps = false, + startAtTop = false, + reverse = false; + + if (rdOriginTop->GetValue() == true) + startAtTop = true; + + if (rdDirectionBackward->GetValue() == true) + reverse = true; + + if (wxGetKeyState(WXK_SHIFT)) + reverse = !reverse; + + if (chkOptionsWholeWord->GetValue() == true) + wholeWord = true; + + if (chkOptionsMatchCase->GetValue() == true) + matchCase = true; + + if (chkOptionsUseRegexps->GetValue() == true) + useRegexps = true; + + if (sqlbox->Find(txtFind->GetValue(), wholeWord, matchCase, useRegexps, startAtTop, reverse)) + { + if (startAtTop) + { + rdOriginTop->SetValue(false); + rdOriginCursor->SetValue(true); + wxCommandEvent nullEvent; + OnChange(nullEvent); + } + } +} + +void dlgFindReplace::OnReplace(wxCommandEvent &ev) +{ + if (txtFind->GetValue().IsEmpty()) + return; + + bool wholeWord = false, + matchCase = false, + useRegexps = false, + startAtTop = false, + reverse = false; + + if (rdOriginTop->GetValue() == true) + startAtTop = true; + + if (rdDirectionBackward->GetValue() == true) + reverse = true; + + if (chkOptionsWholeWord->GetValue() == true) + wholeWord = true; + + if (chkOptionsMatchCase->GetValue() == true) + matchCase = true; + + if (chkOptionsUseRegexps->GetValue() == true) + useRegexps = true; + + if (sqlbox->Replace(txtFind->GetValue(), txtReplace->GetValue(), wholeWord, matchCase, useRegexps, startAtTop, reverse)) + { + if (startAtTop) + { + rdOriginTop->SetValue(false); + rdOriginCursor->SetValue(true); + wxCommandEvent nullEvent; + OnChange(nullEvent); + } + } +} + +void dlgFindReplace::OnReplaceAll(wxCommandEvent &ev) +{ + if (txtFind->GetValue().IsEmpty()) + return; + + bool wholeWord = false, + matchCase = false, + useRegexps = false; + + if (chkOptionsWholeWord->GetValue() == true) + wholeWord = true; + + if (chkOptionsMatchCase->GetValue() == true) + matchCase = true; + + if (chkOptionsUseRegexps->GetValue() == true) + useRegexps = true; + + sqlbox->ReplaceAll(txtFind->GetValue(), txtReplace->GetValue(), wholeWord, matchCase, useRegexps); +} + +void dlgFindReplace::FindNext() +{ + if (btnFind->IsEnabled() && !txtFind->IsEmpty()) + { + wxCommandEvent ev; + OnFind(ev); + } +} + +void dlgFindReplace::SetFindString(const wxString &val) +{ + txtFind->SetValue(val); +} + +void dlgFindReplace::ResetTabOrder() +{ + btnFind->MoveAfterInTabOrder(chkOptionsUseRegexps); + btnReplace->MoveAfterInTabOrder(btnFind); + btnReplaceAll->MoveAfterInTabOrder(btnReplace); + btnCancel->MoveAfterInTabOrder(btnReplaceAll); +} + diff --git a/dlg/dlgForeignDataWrapper.cpp b/dlg/dlgForeignDataWrapper.cpp new file mode 100644 index 0000000..65595d8 --- /dev/null +++ b/dlg/dlgForeignDataWrapper.cpp @@ -0,0 +1,400 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgForeignDataWrapper.cpp - PostgreSQL ForeignDataWrapper Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgForeignDataWrapper.h" +#include "schema/pgForeignDataWrapper.h" + + +// pointer to controls +#define cbHandler CTRL_COMBOBOX("cbHandler") +#define cbValidator CTRL_COMBOBOX("cbValidator") +#define lstOptions CTRL_LISTVIEW("lstOptions") +#define txtOption CTRL_TEXT("txtOption") +#define txtValue CTRL_TEXT("txtValue") +#define btnAdd CTRL_BUTTON("wxID_ADD") +#define btnRemove CTRL_BUTTON("wxID_REMOVE") + + +dlgProperty *pgForeignDataWrapperFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgForeignDataWrapper(this, frame, (pgForeignDataWrapper *)node); +} + + +BEGIN_EVENT_TABLE(dlgForeignDataWrapper, dlgSecurityProperty) + EVT_TEXT(XRCID("cbHandler"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbHandler"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbValidator"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbValidator"), dlgProperty::OnChange) + EVT_LIST_ITEM_SELECTED(XRCID("lstOptions"), dlgForeignDataWrapper::OnSelChangeOption) + EVT_TEXT(XRCID("txtOption"), dlgForeignDataWrapper::OnChangeOptionName) + EVT_BUTTON(wxID_ADD, dlgForeignDataWrapper::OnAddOption) + EVT_BUTTON(wxID_REMOVE, dlgForeignDataWrapper::OnRemoveOption) +END_EVENT_TABLE(); + + +dlgForeignDataWrapper::dlgForeignDataWrapper(pgaFactory *f, frmMain *frame, pgForeignDataWrapper *node) + : dlgSecurityProperty(f, frame, node, wxT("dlgForeignDataWrapper"), wxT("USAGE"), "U") +{ + fdw = node; +} + + +pgObject *dlgForeignDataWrapper::GetObject() +{ + return fdw; +} + + +int dlgForeignDataWrapper::Go(bool modal) +{ + wxString val; + + if(!connection->BackendMinimumVersion(9, 1)) + cbHandler->Disable(); + + // Fill handler combobox + cbHandler->Append(wxT("")); + pgSet *set = connection->ExecuteSet( + wxT("SELECT nspname, proname\n") + wxT(" FROM pg_proc p\n") + wxT(" JOIN pg_namespace nsp ON nsp.oid=pronamespace\n") + wxT(" WHERE pronargs=0") + wxT(" AND prorettype=") + NumToStr(PGOID_TYPE_HANDLER)); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + cbHandler->Append(procname); + set->MoveNext(); + } + delete set; + } + cbHandler->SetSelection(0); + + // Fill validator combobox + cbValidator->Append(wxT("")); + set = connection->ExecuteSet( + wxT("SELECT nspname, proname\n") + wxT(" FROM pg_proc p\n") + wxT(" JOIN pg_namespace nsp ON nsp.oid=pronamespace\n") + wxT(" WHERE proargtypes[0]=") + NumToStr(PGOID_TYPE_TEXT_ARRAY) + + wxT(" AND proargtypes[1]=") + NumToStr(PGOID_TYPE_OID)); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + cbValidator->Append(procname); + set->MoveNext(); + } + delete set; + } + cbValidator->SetSelection(0); + + // Initialize options listview and buttons + lstOptions->AddColumn(_("Option"), 80); + lstOptions->AddColumn(_("Value"), 40); + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnAdd->Disable(); + btnRemove->Disable(); + + if (fdw) + { + // edit mode + txtName->Enable(connection->BackendMinimumVersion(9, 2)); + + val = fdw->GetHandlerProc(); + if (!val.IsEmpty()) + { + for (unsigned int i = 0 ; i < cbHandler->GetCount() ; i++) + { + if (cbHandler->GetString(i) == val) + cbHandler->SetSelection(i); + } + } + + val = fdw->GetValidatorProc(); + if (!val.IsEmpty()) + { + for (unsigned int i = 0 ; i < cbValidator->GetCount() ; i++) + { + if (cbValidator->GetString(i) == val) + cbValidator->SetSelection(i); + } + } + + wxString options = fdw->GetOptions(); + wxString option, optionname, optionvalue; + while (options.Length() > 0) + { + option = options.BeforeFirst(','); + optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim(); + optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim(); + lstOptions->AppendItem(optionname, optionvalue); + options = options.AfterFirst(','); + } + } + else + { + // create mode + } + + return dlgSecurityProperty::Go(modal); +} + + +pgObject *dlgForeignDataWrapper::CreateObject(pgCollection *collection) +{ + wxString name = txtName->GetValue(); + + pgObject *obj = foreignDataWrapperFactory.CreateObjects(collection, 0, wxT("\n AND fdwname ILIKE ") + qtDbString(name)); + return obj; +} + + +void dlgForeignDataWrapper::CheckChange() +{ + bool didChange = true; + wxString name = txtName->GetValue(); + if (fdw) + { + didChange = name != fdw->GetName() + || cbOwner->GetValue() != fdw->GetOwner() + || txtComment->GetValue() != fdw->GetComment() + || cbHandler->GetValue() != fdw->GetHandlerProc() + || cbValidator->GetValue() != fdw->GetValidatorProc() + || GetOptionsSql().Length() > 0; + EnableOK(didChange); + } + else + { + bool enable = true; + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + EnableOK(enable); + } +} + + + +void dlgForeignDataWrapper::OnChangeOptionName(wxCommandEvent &ev) +{ + btnAdd->Enable(txtOption->GetValue().Length() > 0); +} + + +void dlgForeignDataWrapper::OnSelChangeOption(wxListEvent &ev) +{ + int row = lstOptions->GetSelection(); + if (row >= 0) + { + txtOption->SetValue(lstOptions->GetText(row, 0)); + txtValue->SetValue(lstOptions->GetText(row, 1)); + } + + btnRemove->Enable(row >= 0); +} + + +void dlgForeignDataWrapper::OnAddOption(wxCommandEvent &ev) +{ + bool found = false; + + for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + if (lstOptions->GetText(pos).IsSameAs(txtOption->GetValue(), false)) + { + lstOptions->SetItem(pos, 1, txtValue->GetValue()); + found = true; + break; + } + } + + if (!found) + { + lstOptions->AppendItem(txtOption->GetValue(), txtValue->GetValue()); + } + + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnAdd->Disable(); + + CheckChange(); +} + + +void dlgForeignDataWrapper::OnRemoveOption(wxCommandEvent &ev) +{ + int sel = lstOptions->GetSelection(); + lstOptions->DeleteItem(sel); + + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnRemove->Disable(); + + CheckChange(); +} + + +wxString dlgForeignDataWrapper::GetOptionsSql() +{ + wxString options = fdw->GetOptions(); + wxString option, optionname, optionvalue, sqloptions; + bool found; + int pos; + + while (options.Length() > 0) + { + option = options.BeforeFirst(','); + optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim(); + optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim(); + + // check for options + found = false; + for (pos = 0 ; pos < lstOptions->GetItemCount() && !found; pos++) + { + found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0; + if (found) break; + } + + if (found) + { + if (lstOptions->GetText(pos, 1).Cmp(optionvalue) != 0) + { + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += wxT("SET ") + optionname + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("'"); + } + } + else + { + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += wxT("DROP ") + optionname; + } + + options = options.AfterFirst(','); + } + + for (pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + options = fdw->GetOptions(); + found = false; + + while (options.Length() > 0 && !found) + { + option = options.BeforeFirst(','); + optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim(); + found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0; + options = options.AfterFirst(','); + } + + if (!found) + { + optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim(); + + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += wxT("ADD ") + lstOptions->GetText(pos, 0) + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("'"); + } + } + + return sqloptions; +} + + +wxString dlgForeignDataWrapper::GetSql() +{ + wxString sql, name; + name = txtName->GetValue(); + + if (fdw) + { + // edit mode + sql = wxEmptyString; + + AppendNameChange(sql); + + if (cbHandler->GetValue() != fdw->GetHandlerProc()) + { + if (cbHandler->GetValue().IsEmpty()) + sql += wxT("ALTER FOREIGN DATA WRAPPER ") + qtIdent(name) + + wxT("\n NO HANDLER;\n"); + else + sql += wxT("ALTER FOREIGN DATA WRAPPER ") + qtIdent(name) + + wxT("\n HANDLER ") + qtIdent(cbHandler->GetValue()) + + wxT(";\n"); + } + + if (cbValidator->GetValue() != fdw->GetValidatorProc()) + { + if (cbValidator->GetValue().IsEmpty()) + sql += wxT("ALTER FOREIGN DATA WRAPPER ") + qtIdent(name) + + wxT("\n NO VALIDATOR;\n"); + else + sql += wxT("ALTER FOREIGN DATA WRAPPER ") + qtIdent(name) + + wxT("\n VALIDATOR ") + qtIdent(cbValidator->GetValue()) + + wxT(";\n"); + } + + wxString sqloptions = GetOptionsSql(); + if (sqloptions.Length() > 0) + { + sql += wxT("ALTER FOREIGN DATA WRAPPER ") + name + + wxT(" OPTIONS (") + sqloptions + wxT(");"); + } + + AppendOwnerChange(sql, wxT("FOREIGN DATA WRAPPER ") + qtIdent(name)); + } + else + { + // create mode + sql = wxT("CREATE FOREIGN DATA WRAPPER ") + qtIdent(name); + AppendIfFilled(sql, wxT("\n HANDLER "), qtIdent(cbHandler->GetValue())); + AppendIfFilled(sql, wxT("\n VALIDATOR "), qtIdent(cbValidator->GetValue())); + + // check for options + if (lstOptions->GetItemCount() > 0) + { + wxString options = wxEmptyString; + for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + if (options.Length() > 0) + options += wxT(", "); + + options += lstOptions->GetText(pos, 0) + + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("' "); + } + sql += wxT("\n OPTIONS (") + options + wxT(")"); + } + + sql += wxT(";\n"); + AppendOwnerNew(sql, wxT("FOREIGN DATA WRAPPER ") + qtIdent(name)); + } + + sql += GetGrant(wxT("U"), wxT("FOREIGN DATA WRAPPER ") + qtIdent(name)); + AppendComment(sql, wxT("FOREIGN DATA WRAPPER"), 0, fdw); + + return sql; +} + + diff --git a/dlg/dlgForeignKey.cpp b/dlg/dlgForeignKey.cpp new file mode 100644 index 0000000..9fa9dbd --- /dev/null +++ b/dlg/dlgForeignKey.cpp @@ -0,0 +1,569 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgForeignKey.cpp - PostgreSQL Foreign Key Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "frm/frmMain.h" +#include "frm/frmHint.h" +#include "schema/pgTable.h" +#include "schema/pgForeignKey.h" +#include "dlg/dlgForeignKey.h" +#include "schema/pgColumn.h" + + +#define chkDeferrable CTRL_CHECKBOX("chkDeferrable") +#define chkDeferred CTRL_CHECKBOX("chkDeferred") +#define cbReferences CTRL_COMBOBOX("cbReferences") +#define chkMatchFull CTRL_CHECKBOX("chkMatchFull") +#define chkDontValidate CTRL_CHECKBOX("chkDontValidate") + +#define chkAutoIndex CTRL_CHECKBOX("chkAutoIndex") +#define txtIndexName CTRL_TEXT("txtIndexName") + +#define cbRefColumns CTRL_COMBOBOX("cbRefColumns") +#define btnAddRef CTRL_BUTTON("btnAddRef") +#define btnRemoveRef CTRL_BUTTON("btnRemoveRef") + +#define rbOnUpdate CTRL_RADIOBOX("rbOnUpdate") +#define rbOnDelete CTRL_RADIOBOX("rbOnDelete") + + +BEGIN_EVENT_TABLE(dlgForeignKey, dlgProperty) + EVT_CHECKBOX(XRCID("chkDeferrable"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkAutoIndex") , dlgProperty::OnChange) + EVT_TEXT(XRCID("txtIndexName"), dlgProperty::OnChange) + + EVT_CHECKBOX(XRCID("chkDontValidate"), dlgForeignKey::OnChangeValidate) + EVT_LIST_ITEM_SELECTED(XRCID("lstColumns"), dlgForeignKey::OnSelChangeCol) + EVT_TEXT(XRCID("cbReferences"), dlgForeignKey::OnSelChangeRef) + EVT_COMBOBOX(XRCID("cbReferences"), dlgForeignKey::OnSelChangeRef) + EVT_TEXT(XRCID("cbColumns"), dlgForeignKey::OnSelChangeRefCol) + EVT_COMBOBOX(XRCID("cbColumns"), dlgForeignKey::OnSelChangeRefCol) + EVT_TEXT(XRCID("cbRefColumns"), dlgForeignKey::OnSelChangeRefCol) + EVT_COMBOBOX(XRCID("cbRefColumns"), dlgForeignKey::OnSelChangeRefCol) + EVT_BUTTON(XRCID("btnAddRef"), dlgForeignKey::OnAddRef) + EVT_BUTTON(XRCID("btnRemoveRef"), dlgForeignKey::OnRemoveRef) + EVT_BUTTON(wxID_OK, dlgForeignKey::OnOK) +#ifdef __WXMAC__ + EVT_SIZE( dlgForeignKey::OnChangeSize) +#endif +END_EVENT_TABLE(); + + +dlgProperty *pgForeignKeyFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgForeignKey(this, frame, (pgForeignKey *)node, (pgTable *)parent); +} + + +dlgForeignKey::dlgForeignKey(pgaFactory *f, frmMain *frame, pgForeignKey *node, pgTable *parentNode) + : dlgCollistProperty(f, frame, wxT("dlgForeignKey"), parentNode) +{ + foreignKey = node; +} + + +dlgForeignKey::dlgForeignKey(pgaFactory *f, frmMain *frame, ctlListView *colList) + : dlgCollistProperty(f, frame, wxT("dlgForeignKey"), colList) +{ + foreignKey = 0; +} + + +wxString dlgForeignKey::DefaultIndexName(const wxString &name) +{ + if (name.IsEmpty()) + return wxEmptyString; + + if (name.Left(3) == wxT("fk_")) + return wxT("fki_") + name.Mid(3); + else if (name.Left(3) == wxT("FK_")) + return wxT("FKI_") + name.Mid(3); + else + return wxT("fki_") + name; +} + + +void dlgForeignKey::OnOK(wxCommandEvent &ev) +{ + if (chkAutoIndex->IsEnabled() && !chkAutoIndex->GetValue() + && frmHint::ShowHint(this, HINT_FKINDEX) == wxID_CANCEL) + return; + + dlgProperty::OnOK(ev); +} + + +#ifdef __WXMAC__ +void dlgForeignKey::OnChangeSize(wxSizeEvent &ev) +{ + lstColumns->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 450); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + + +void dlgForeignKey::CheckChange() +{ + if (processing) + return; + + processing = true; + + wxString name = GetName(); + + wxString cols; + int pos; + for (pos = 0 ; pos < lstColumns->GetItemCount() ; pos++) + { + if (pos) + cols += wxT(", "); + cols += qtIdent(lstColumns->GetText(pos)); + } + + bool canDef = chkDeferrable->GetValue(); + if (!canDef) + chkDeferred->SetValue(false); + chkDeferred->Enable(canDef); + + txtIndexName->Enable(table && chkAutoIndex->GetValue()); + + wxString coveringIndex; + if (table) + { + coveringIndex = table->GetCoveringIndex(mainForm->GetBrowser(), cols); + + if (coveringIndex.IsEmpty()) + { + if (!chkAutoIndex->IsEnabled()) + { + chkAutoIndex->Enable(); + chkAutoIndex->SetValue(true); + txtIndexName->Enable(); + txtIndexName->SetValue(savedIndexName); + } + + wxString idxName = txtIndexName->GetValue().Strip(wxString::both); + + if (name != savedFKName || idxName == savedIndexName) + { + if (idxName.IsEmpty() || idxName == DefaultIndexName(savedFKName)) + { + idxName = DefaultIndexName(name); + txtIndexName->SetValue(idxName); + } + } + savedIndexName = idxName; + } + else + { + if (chkAutoIndex->IsEnabled()) + savedIndexName = txtIndexName->GetValue(); + + txtIndexName->SetValue(coveringIndex); + chkAutoIndex->SetValue(false); + + txtIndexName->Disable(); + chkAutoIndex->Disable(); + } + } + + savedFKName = name; + processing = false; + + if (foreignKey) + { + bool enable = true; + if (chkAutoIndex->GetValue()) + { + CheckValid(enable, !txtIndexName->GetValue().IsEmpty(), + _("Please specify covering index name.")); + } + else + enable = txtName->GetValue() != foreignKey->GetName() || txtComment->GetValue() != foreignKey->GetComment(); + + if (connection->BackendMinimumVersion(9, 1) && !foreignKey->GetValid() && !chkDontValidate->GetValue()) + enable = true; + + EnableOK(enable); + } + else + { + bool enable = true; + txtComment->Enable(!name.IsEmpty()); + CheckValid(enable, lstColumns->GetItemCount() > 0, _("Please specify columns.")); + CheckValid(enable, !chkAutoIndex->GetValue() || !txtIndexName->GetValue().IsEmpty(), + _("Please specify covering index name.")); + EnableOK(enable); + } + +} + + +void dlgForeignKey::OnChangeValidate(wxCommandEvent &ev) +{ + CheckChange(); +} + + +void dlgForeignKey::OnSelChangeCol(wxListEvent &ev) +{ + btnRemoveRef->Enable(); +} + + +void dlgForeignKey::OnSelChangeRefCol(wxCommandEvent &ev) +{ + btnAddRef->Enable(cbColumns->GetCurrentSelection() >= 0 && cbRefColumns->GetCurrentSelection() >= 0); +} + + +void dlgForeignKey::OnSelChangeRef(wxCommandEvent &ev) +{ + cbRefColumns->Clear(); + + wxString tab = cbReferences->GetValue(); + wxString nsp; + if (tab.Find('.') >= 0) + { + nsp = tab.BeforeFirst('.'); + tab = tab.AfterFirst('.'); + } + else + nsp = database->GetDefaultSchema(); + + pgSet *set = connection->ExecuteSet( + wxT("SELECT attname\n") + wxT(" FROM pg_attribute att, pg_class cl, pg_namespace nsp\n") + wxT(" WHERE attrelid=cl.oid AND relnamespace=nsp.oid\n") + wxT(" AND nspname=") + qtDbString(nsp) + + wxT("\n AND relname=") + qtDbString(tab) + + wxT("\n AND attnum > 0\n") + wxT("\n AND NOT attisdropped\n") + wxT("\n ORDER BY attnum")); + if (set) + { + while (!set->Eof()) + { + cbRefColumns->Append(set->GetVal(0)); + set->MoveNext(); + } + delete set; + + if (cbRefColumns->GetCount()) + cbRefColumns->SetSelection(0); + } + + OnSelChangeRefCol(ev); +} + + +void dlgForeignKey::OnAddRef(wxCommandEvent &ev) +{ + wxString col = cbColumns->GetValue(); + wxString ref = cbRefColumns->GetValue(); + if (!col.IsEmpty() && !ref.IsEmpty()) + { + lstColumns->AppendItem(columnFactory.GetIconId(), col, ref); + cbColumns->Delete(cbColumns->GetCurrentSelection()); + cbRefColumns->Delete(cbRefColumns->GetCurrentSelection()); + cbReferences->Disable(); + + if (cbColumns->GetCount()) + cbColumns->SetSelection(0); + + if (cbRefColumns->GetCount()) + cbRefColumns->SetSelection(0); + + OnSelChangeRefCol(ev); + CheckChange(); + } +} + + +void dlgForeignKey::OnRemoveRef(wxCommandEvent &ev) +{ + long pos = lstColumns->GetSelection(); + + if (pos >= 0) + { + wxString col = lstColumns->GetText(pos); + wxString ref = lstColumns->GetText(pos, 1); + cbColumns->Append(col); + cbRefColumns->Append(ref); + + lstColumns->DeleteItem(pos); + cbReferences->Enable(lstColumns->GetItemCount() == 0); + btnRemoveRef->Disable(); + } +} + + +pgObject *dlgForeignKey::GetObject() +{ + return foreignKey; +} + + +pgObject *dlgForeignKey::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + if (name.IsEmpty()) + return 0; + + pgObject *obj = foreignKeyFactory.CreateObjects(collection, 0, wxT( + "\n AND conname=") + qtDbString(name) + wxT( + "\n AND cl.relnamespace=") + table->GetSchema()->GetOidStr()); + return obj; +} + + +int dlgForeignKey::Go(bool modal) +{ + lstColumns->CreateColumns(0, _("Local"), _("Referenced"), -1); + + processing = true; // protect from OnChange execution + + btnAddRef->Disable(); + btnRemoveRef->Disable(); + + if (readOnly) + { + chkAutoIndex->Disable(); + txtIndexName->Disable(); + } + + + if (foreignKey) + { + // edit mode + txtName->Enable(connection->BackendMinimumVersion(9, 2)); + cbReferences->Append(foreignKey->GetReferences()); + cbReferences->SetValue(foreignKey->GetReferences()); + cbReferences->Disable(); + + chkDeferrable->SetValue(foreignKey->GetDeferrable()); + chkDeferred->SetValue(foreignKey->GetDeferred()); + chkMatchFull->SetValue(foreignKey->GetMatch() == wxT("FULL")); + if (connection->BackendMinimumVersion(9, 1)) + chkDontValidate->SetValue(!foreignKey->GetValid()); + chkDeferrable->Disable(); + chkDeferred->Disable(); + chkMatchFull->Disable(); + chkDontValidate->Enable(connection->BackendMinimumVersion(9, 1)); + if(!connection->BackendMinimumVersion(9, 1)) + { + chkDontValidate->SetValue(true); + } + rbOnUpdate->SetStringSelection(foreignKey->GetOnUpdate()); + rbOnDelete->SetStringSelection(foreignKey->GetOnDelete()); + rbOnUpdate->Disable(); + rbOnDelete->Disable(); + + chkAutoIndex->SetValue(false); + txtIndexName->SetValue(foreignKey->GetCoveringIndex()); + if (!txtIndexName->GetValue().IsEmpty()) + { + chkAutoIndex->Disable(); + txtIndexName->Disable(); + } + + btnAddRef->Disable(); + btnRemoveRef->Disable(); + cbColumns->Disable(); + cbRefColumns->Disable(); + + int pos = 0; + wxStringTokenizer cols(foreignKey->GetFkColumns(), wxT(",")); + wxStringTokenizer refs(foreignKey->GetRefColumns(), wxT(",")); + while (cols.HasMoreTokens()) + { + wxString col = cols.GetNextToken().Trim(false).Trim(true); + wxString ref = refs.GetNextToken().Trim(false).Trim(true); + if (pos++) + { + if (col.Last() == ',') + col.RemoveLast(); + if (ref.Last() == ',') + ref.RemoveLast(); + } + lstColumns->AppendItem(columnFactory.GetIconId(), col, ref); + } + } + else + { + // create mode + txtComment->Disable(); + + chkDontValidate->Enable(connection->BackendMinimumVersion(9, 1)); + + wxString systemRestriction; + if (!settings->GetShowSystemObjects()) + systemRestriction = wxT(" AND ") + connection->SystemNamespaceRestriction(wxT("nsp.nspname")); + + wxString sql = wxT("SELECT nspname, relname FROM pg_namespace nsp, pg_class cl\n") + wxT(" WHERE relnamespace=nsp.oid AND relkind='r'\n"); + + if (connection->BackendMinimumVersion(8, 1)) + sql += wxT(" AND nsp.nspname NOT LIKE E'pg\\_temp\\_%'\n"); + else + sql += wxT(" AND nsp.nspname NOT LIKE 'pg\\_temp\\_%'\n"); + + sql += systemRestriction + + wxT(" ORDER BY nspname, relname"); + + pgSet *set = connection->ExecuteSet(sql); + + if (set) + { + while (!set->Eof()) + { + cbReferences->Append(database->GetSchemaPrefix(set->GetVal(0)) + set->GetVal(1)); + set->MoveNext(); + } + delete set; + cbReferences->SetSelection(0); + } + if (!table) + { + chkAutoIndex->Disable(); + chkAutoIndex->SetValue(false); + txtIndexName->Disable(); + cbClusterSet->Disable(); + cbClusterSet = 0; + } + } + + processing = false; + + // Reset the labels as the XRC defined values will have been localised :-( + + rbOnUpdate->SetString(0, wxT("NO ACTION")); + rbOnUpdate->SetString(1, wxT("RESTRICT")); + rbOnUpdate->SetString(2, wxT("CASCADE")); + rbOnUpdate->SetString(3, wxT("SET NULL")); + rbOnUpdate->SetString(4, wxT("SET DEFAULT")); + + rbOnDelete->SetString(0, wxT("NO ACTION")); + rbOnDelete->SetString(1, wxT("RESTRICT")); + rbOnDelete->SetString(2, wxT("CASCADE")); + rbOnDelete->SetString(3, wxT("SET NULL")); + rbOnDelete->SetString(4, wxT("SET DEFAULT")); + + wxCommandEvent nullEvent; + OnSelChangeRef(nullEvent); + + return dlgCollistProperty::Go(modal); +} + + +wxString dlgForeignKey::GetSql() +{ + wxString sql; + wxString name = GetName(); + + if (!foreignKey) + { + sql = wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n ADD"); + AppendIfFilled(sql, wxT(" CONSTRAINT "), qtIdent(name)); + sql += wxT(" FOREIGN KEY ") + GetDefinition() + + wxT(";\n"); + } + else + { + if (foreignKey->GetName() != name) + { + sql = wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n RENAME CONSTRAINT ") + qtIdent(foreignKey->GetName()) + + wxT(" TO ") + qtIdent(name) + wxT(";\n"); + } + if (connection->BackendMinimumVersion(9, 1) && !foreignKey->GetValid() && !chkDontValidate->GetValue()) + { + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n VALIDATE CONSTRAINT ") + qtIdent(name) + wxT(";\n"); + } + } + + if (!name.IsEmpty()) + AppendComment(sql, wxT("CONSTRAINT ") + qtIdent(name) + + wxT(" ON ") + table->GetQuotedFullIdentifier(), foreignKey); + + if (chkAutoIndex->GetValue()) + { + sql += wxT("CREATE INDEX ") + qtIdent(txtIndexName->GetValue()) + + wxT("\n ON ") + table->GetQuotedFullIdentifier() + + wxT("("); + + int pos; + for (pos = 0 ; pos < lstColumns->GetItemCount() ; pos++) + { + if (pos) + sql += wxT(", "); + + sql += qtIdent(lstColumns->GetText(pos)); + } + + sql += wxT(");\n"); + } + return sql; +} + + +wxString dlgForeignKey::GetDefinition() +{ + wxString sql; + wxString cols, refs; + + int pos; + + for (pos = 0 ; pos < lstColumns->GetItemCount() ; pos++) + { + if (pos) + { + cols += wxT(", "); + refs += wxT(", "); + } + cols += qtIdent(lstColumns->GetText(pos)); + refs += qtIdent(lstColumns->GetText(pos, 1)); + } + + sql = wxT("(") + cols + + wxT(") REFERENCES "); + AppendQuoted(sql, cbReferences->GetValue()); + sql += wxT(" (") + refs + + wxT(")"); + + if (chkMatchFull->GetValue()) + sql += wxT(" MATCH FULL"); + + sql += wxT("\n ") + wxT(" ON UPDATE ") + rbOnUpdate->GetStringSelection() + + wxT(" ON DELETE ") + rbOnDelete->GetStringSelection(); + + if (chkDeferrable->GetValue()) + sql += wxT("\n DEFERRABLE"); + if (chkDeferred->GetValue()) + sql += wxT(" INITIALLY DEFERRED"); + + if (chkDontValidate->GetValue()) + sql += wxT("\n NOT VALID"); + + return sql; +} diff --git a/dlg/dlgForeignServer.cpp b/dlg/dlgForeignServer.cpp new file mode 100644 index 0000000..457e6db --- /dev/null +++ b/dlg/dlgForeignServer.cpp @@ -0,0 +1,329 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgForeignServer.cpp - PostgreSQL Foreign Server Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgForeignServer.h" +#include "schema/pgForeignServer.h" + + +// pointer to controls +#define cbForeignDataWrapper CTRL_COMBOBOX("cbForeignDataWrapper") +#define txtType CTRL_TEXT("txtType") +#define txtVersion CTRL_TEXT("txtVersion") +#define lstOptions CTRL_LISTVIEW("lstOptions") +#define txtOption CTRL_TEXT("txtOption") +#define txtValue CTRL_TEXT("txtValue") +#define btnAdd CTRL_BUTTON("wxID_ADD") +#define btnRemove CTRL_BUTTON("wxID_REMOVE") + + +dlgProperty *pgForeignServerFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgForeignServer(this, frame, (pgForeignServer *)node, (pgForeignDataWrapper *)parent); +} + + +BEGIN_EVENT_TABLE(dlgForeignServer, dlgSecurityProperty) + EVT_LIST_ITEM_SELECTED(XRCID("lstOptions"), dlgForeignServer::OnSelChangeOption) + EVT_TEXT(XRCID("txtOption"), dlgForeignServer::OnChangeOptionName) + EVT_BUTTON(wxID_ADD, dlgForeignServer::OnAddOption) + EVT_BUTTON(wxID_REMOVE, dlgForeignServer::OnRemoveOption) +END_EVENT_TABLE(); + + +dlgForeignServer::dlgForeignServer(pgaFactory *f, frmMain *frame, pgForeignServer *node, pgForeignDataWrapper *parent) + : dlgSecurityProperty(f, frame, node, wxT("dlgForeignServer"), wxT("USAGE"), "U") +{ + foreigndatawrapper = parent; + foreignserver = node; +} + + +pgObject *dlgForeignServer::GetObject() +{ + return foreignserver; +} + + +int dlgForeignServer::Go(bool modal) +{ + // Initialize options listview and buttons + lstOptions->AddColumn(_("Option"), 80); + lstOptions->AddColumn(_("Value"), 40); + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnAdd->Disable(); + btnRemove->Disable(); + + if (foreignserver) + { + // edit mode + txtName->Enable(connection->BackendMinimumVersion(9, 2)); + txtType->Disable(); + + txtType->SetValue(foreignserver->GetType()); + txtVersion->SetValue(foreignserver->GetVersion()); + + wxString options = foreignserver->GetOptions(); + wxString option, optionname, optionvalue; + while (options.Length() > 0) + { + option = options.BeforeFirst(','); + optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim(); + optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim(); + lstOptions->AppendItem(optionname, optionvalue); + options = options.AfterFirst(','); + } + } + else + { + // create mode + } + + return dlgSecurityProperty::Go(modal); +} + + +pgObject *dlgForeignServer::CreateObject(pgCollection *collection) +{ + wxString name = txtName->GetValue(); + + pgObject *obj = foreignServerFactory.CreateObjects(collection, 0, wxT("\n AND srvname ILIKE ") + qtDbString(name)); + return obj; +} + + +void dlgForeignServer::CheckChange() +{ + bool didChange = true; + wxString name = txtName->GetValue(); + if (foreignserver) + { + didChange = name != foreignserver->GetName() + || txtComment->GetValue() != foreignserver->GetComment() + || cbOwner->GetValue() != foreignserver->GetOwner() + || txtType->GetValue() != foreignserver->GetType() + || txtVersion->GetValue() != foreignserver->GetVersion() + || GetOptionsSql().Length() > 0; + EnableOK(didChange); + } + else + { + bool enable = true; + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + EnableOK(enable); + } +} + + + +void dlgForeignServer::OnChange(wxCommandEvent &ev) +{ + CheckChange(); +} + + +void dlgForeignServer::OnChangeOptionName(wxCommandEvent &ev) +{ + btnAdd->Enable(txtOption->GetValue().Length() > 0); +} + + +void dlgForeignServer::OnSelChangeOption(wxListEvent &ev) +{ + int row = lstOptions->GetSelection(); + if (row >= 0) + { + txtOption->SetValue(lstOptions->GetText(row, 0)); + txtValue->SetValue(lstOptions->GetText(row, 1)); + } + + btnRemove->Enable(row >= 0); +} + + +void dlgForeignServer::OnAddOption(wxCommandEvent &ev) +{ + bool found = false; + + for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + if (lstOptions->GetText(pos).IsSameAs(txtOption->GetValue(), false)) + { + lstOptions->SetItem(pos, 1, txtValue->GetValue()); + found = true; + break; + } + } + + if (!found) + { + lstOptions->AppendItem(txtOption->GetValue(), txtValue->GetValue()); + } + + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnAdd->Disable(); + + CheckChange(); +} + + +void dlgForeignServer::OnRemoveOption(wxCommandEvent &ev) +{ + int sel = lstOptions->GetSelection(); + lstOptions->DeleteItem(sel); + + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnRemove->Disable(); + + CheckChange(); +} + + +wxString dlgForeignServer::GetOptionsSql() +{ + wxString options = foreignserver->GetOptions(); + wxString option, optionname, optionvalue, sqloptions; + bool found; + int pos; + + while (options.Length() > 0) + { + option = options.BeforeFirst(','); + optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim(); + optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim(); + + // check for options + found = false; + for (pos = 0 ; pos < lstOptions->GetItemCount() && !found; pos++) + { + found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0; + if (found) break; + } + + if (found) + { + if (lstOptions->GetText(pos, 1).Cmp(optionvalue) != 0) + { + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += wxT("SET ") + optionname + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("'"); + } + } + else + { + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += wxT("DROP ") + optionname; + } + + options = options.AfterFirst(','); + } + + for (pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + options = foreignserver->GetOptions(); + found = false; + + while (options.Length() > 0 && !found) + { + option = options.BeforeFirst(','); + optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim(); + found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0; + options = options.AfterFirst(','); + } + + if (!found) + { + optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim(); + + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += wxT("ADD ") + lstOptions->GetText(pos, 0) + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("'"); + } + } + + return sqloptions; +} + + +wxString dlgForeignServer::GetSql() +{ + wxString sql, name; + name = txtName->GetValue(); + + if (foreignserver) + { + // edit mode + AppendNameChange(sql, wxT("SERVER ") + qtIdent(foreignserver->GetName())); + + if (txtVersion->GetValue() != foreignserver->GetVersion()) + { + sql = wxT("ALTER SERVER ") + qtIdent(name) + + wxT("\n VERSION ") + qtDbString(txtVersion->GetValue()) + wxT(";\n"); + } + + wxString sqloptions = GetOptionsSql(); + if (sqloptions.Length() > 0) + { + sql += wxT("ALTER SERVER ") + name + + wxT("\n OPTIONS (") + sqloptions + wxT(");\n"); + } + + AppendOwnerChange(sql, wxT("SERVER ") + qtIdent(name)); + } + else + { + // create mode + sql = wxT("CREATE SERVER ") + qtIdent(name); + if (!(txtType->GetValue()).IsEmpty()) + sql += wxT("\n TYPE ") + qtDbString(txtType->GetValue()); + if (!(txtVersion->GetValue()).IsEmpty()) + sql += wxT("\n VERSION ") + qtDbString(txtVersion->GetValue()); + sql += wxT("\n FOREIGN DATA WRAPPER ") + qtIdent(foreigndatawrapper->GetName()); + + // check for options + if (lstOptions->GetItemCount() > 0) + { + wxString options = wxEmptyString; + for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + if (options.Length() > 0) + options += wxT(", "); + + options += lstOptions->GetText(pos, 0) + + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("' "); + } + sql += wxT("\n OPTIONS (") + options + wxT(")"); + } + + sql += wxT(";\n"); + AppendOwnerNew(sql, wxT("SERVER ") + qtIdent(name)); + } + + sql += GetGrant(wxT("U"), wxT("SERVER ") + qtIdent(name)); + AppendComment(sql, wxT("SERVER"), 0, foreignserver); + + return sql; +} + + + diff --git a/dlg/dlgForeignTable.cpp b/dlg/dlgForeignTable.cpp new file mode 100644 index 0000000..c65746f --- /dev/null +++ b/dlg/dlgForeignTable.cpp @@ -0,0 +1,644 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgForeignTable.cpp - PostgreSQL Foreign Table Property +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + + +// App headers +#include "utils/misc.h" +#include "dlg/dlgForeignTable.h" +#include "schema/pgSchema.h" +#include "schema/pgForeignTable.h" +#include "schema/pgDatatype.h" +#include "ctl/ctlSeclabelPanel.h" + + +// pointer to controls +#define cbForeignServer CTRL_COMBOBOX("cbForeignServer") +#define lstMembers CTRL_LISTVIEW("lstMembers") +#define txtMembername CTRL_TEXT("txtMembername") +#define btnAddMember CTRL_BUTTON("btnAddMember") +#define btnChangeMember CTRL_BUTTON("btnChangeMember") +#define btnRemoveMember CTRL_BUTTON("btnRemoveMember") +#define lstOptions CTRL_LISTVIEW("lstOptions") +#define txtOption CTRL_TEXT("txtOption") +#define txtValue CTRL_TEXT("txtValue") +#define btnAdd CTRL_BUTTON("wxID_ADD") +#define btnRemove CTRL_BUTTON("wxID_REMOVE") +#define chkNotNull CTRL_CHECKBOX("chkNotNull") + + +BEGIN_EVENT_TABLE(dlgForeignTable, dlgTypeProperty) + EVT_BUTTON(XRCID("btnAddMember"), dlgForeignTable::OnMemberAdd) + EVT_BUTTON(XRCID("btnChangeMember"), dlgForeignTable::OnMemberChange) + EVT_BUTTON(XRCID("btnRemoveMember"), dlgForeignTable::OnMemberRemove) + EVT_LIST_ITEM_SELECTED(XRCID("lstMembers"), dlgForeignTable::OnMemberSelChange) + EVT_TEXT(XRCID("cbDatatype"), dlgForeignTable::OnSelChangeTyp) + EVT_COMBOBOX(XRCID("cbDatatype"), dlgForeignTable::OnSelChangeTyp) + EVT_TEXT(XRCID("txtMembername"), dlgForeignTable::OnChangeMember) + EVT_TEXT(XRCID("cbDatatype"), dlgForeignTable::OnSelChangeTyp) + EVT_COMBOBOX(XRCID("cbDatatype"), dlgForeignTable::OnSelChangeTyp) + EVT_TEXT(XRCID("txtLength"), dlgForeignTable::OnSelChangeTypOrLen) + EVT_TEXT(XRCID("txtPrecision"), dlgForeignTable::OnSelChangeTypOrLen) + EVT_CHECKBOX(XRCID("chkNotNull"), dlgForeignTable::OnChangeMember) + EVT_LIST_ITEM_SELECTED(XRCID("lstOptions"), dlgForeignTable::OnSelChangeOption) + EVT_TEXT(XRCID("txtOption"), dlgForeignTable::OnChangeOptionName) + EVT_BUTTON(wxID_ADD, dlgForeignTable::OnAddOption) + EVT_BUTTON(wxID_REMOVE, dlgForeignTable::OnRemoveOption) +END_EVENT_TABLE(); + + +dlgProperty *pgForeignTableFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgForeignTable(this, frame, (pgForeignTable *)node, (pgSchema *)parent); +} + + +dlgForeignTable::dlgForeignTable(pgaFactory *f, frmMain *frame, pgForeignTable *node, pgSchema *sch) + : dlgTypeProperty(f, frame, wxT("dlgForeignTable")) +{ + foreigntable = node; + schema = sch; + + seclabelPage = new ctlSeclabelPanel(nbNotebook); + + lstMembers->CreateColumns(0, _("Member"), _("Data type"), _("Constraint"), -1); + + queriesToBeSplitted = false; +} + + +void dlgForeignTable::OnChangeMember(wxCommandEvent &ev) +{ + btnAddMember->Enable( + !txtMembername->GetValue().Strip(wxString::both).IsEmpty() + && cbDatatype->GetGuessedSelection() >= 0); + btnChangeMember->Enable(true); +} + + +pgObject *dlgForeignTable::GetObject() +{ + return foreigntable; +} + + +int dlgForeignTable::Go(bool modal) +{ + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(foreigntable); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgForeignTable::OnChange)); + + // Fill owner combobox + if (!foreigntable) + cbOwner->Append(wxT("")); + AddGroups(); + AddUsers(cbOwner); + + // Fill datatype combobox + FillDatatype(cbDatatype); + + // Initialize options listview and buttons + lstOptions->AddColumn(_("Option"), 80); + lstOptions->AddColumn(_("Value"), 40); + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnAdd->Disable(); + btnRemove->Disable(); + + if (foreigntable) + { + // Edit Mode + cbForeignServer->SetValue(foreigntable->GetForeignServer()); + cbForeignServer->Disable(); + + txtMembername->Enable(true); + btnAddMember->Enable(true); + btnChangeMember->Enable(false); + btnRemoveMember->Enable(false); + + wxArrayString elements = foreigntable->GetTypesArray(); + wxString fullType, typeName, typeLength, typePrecision; + size_t pos; + size_t i; + for (i = 0 ; i < elements.GetCount() ; i += 3) + { + lstMembers->AppendItem(0, elements.Item(i), elements.Item(i + 1), elements.Item(i + 2)); + + fullType = elements.Item(i + 1); + typeName = fullType; + typeLength = wxEmptyString; + typePrecision = wxEmptyString; + + if (fullType.Find(wxT("(")) > 0) + { + // there is at least a length + typeName = fullType.BeforeFirst('('); + if (fullType.Find(wxT(",")) > 0) + { + // there is also a precision + typeLength = fullType.AfterFirst('(').BeforeFirst(','); + typePrecision = fullType.AfterFirst(',').BeforeFirst(')'); + } + else + typeLength = fullType.AfterFirst('(').BeforeFirst(')'); + if (!fullType.AfterFirst(')').IsEmpty()) typeName += fullType.AfterFirst(')'); + } + int fnd=-1; + for (pos = 0; pos < cbDatatype->GetCount() - 1; pos++) + { + if (cbDatatype->GetString(pos) == typeName) + { + memberTypes.Add(GetTypeInfo(pos)); + fnd=pos; + break; + } + } + if (fnd==-1) { + wxLogWarning(_("Type %s not found in cbDatatype(%d)\n"), + typeName.c_str(), + cbDatatype->GetCount() + ); + + } + memberLengths.Add(typeLength); + memberPrecisions.Add(typePrecision); + memberNotNulls.Add(elements.Item(i + 2)); + } + + cbDatatype->Enable(); + txtLength->Enable(); + + wxArrayString options = foreigntable->GetOptionsArray(); + wxString optionname, optionvalue; + for (unsigned int index = 0; index < options.Count(); index += 2) + { + optionname = options.Item(index); + optionvalue = options.Item(index + 1); + lstOptions->AppendItem(optionname, optionvalue); + } + } + else + { + // Create mode + cbOwner->Append(wxEmptyString); + cbOwner->Disable(); + + pgSet *set = connection->ExecuteSet( + wxT("SELECT srvname\n") + wxT(" FROM pg_foreign_server\n") + wxT(" ORDER BY srvname")); + if (set) + { + while (!set->Eof()) + { + wxString srvname = set->GetVal(wxT("srvname")); + cbForeignServer->Append(srvname); + set->MoveNext(); + } + delete set; + } + cbForeignServer->SetSelection(0); + } + + txtLength->SetValidator(numericValidator); + + return dlgTypeProperty::Go(modal); +} + + +void dlgForeignTable::OnSelChangeTyp(wxCommandEvent &ev) +{ + txtLength->SetValue(wxEmptyString); + txtPrecision->SetValue(wxEmptyString); + cbDatatype->GuessSelection(ev); + chkNotNull->SetValue(false); + OnSelChangeTypOrLen(ev); +} + + +void dlgForeignTable::OnSelChangeTypOrLen(wxCommandEvent &ev) +{ + CheckLenEnable(); + txtLength->Enable(isVarLen); + txtPrecision->Enable(isVarPrec); + CheckChange(); + OnChangeMember(ev); +} + + +void dlgForeignTable::CheckChange() +{ + bool enable = true; + if (foreigntable) + { + enable = txtComment->GetValue() != foreigntable->GetComment() + || cbSchema->GetValue() != foreigntable->GetSchema()->GetName() + || cbOwner->GetValue() != foreigntable->GetOwner() + || GetSqlForTypes() != wxEmptyString + || GetSql().Length() > 0; + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); + } + else + { + wxString name = GetName(); + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, cbForeignServer->GetCurrentSelection() >= 0, _("Please specify a foreign server.")); + } + EnableOK(enable); +} + + +void dlgForeignTable::OnMemberSelChange(wxListEvent &ev) +{ + long pos = lstMembers->GetSelection(); + if (pos >= 0) + { + txtMembername->SetValue(lstMembers->GetText(pos)); + cbDatatype->SetValue(memberTypes.Item(pos).AfterFirst(':')); + txtLength->SetValue(memberLengths.Item(pos)); + txtLength->Enable(!txtLength->GetValue().IsEmpty()); + txtPrecision->SetValue(memberPrecisions.Item(pos)); + txtPrecision->Enable(!txtPrecision->GetValue().IsEmpty()); + chkNotNull->SetValue(memberNotNulls.Item(pos) == wxT("NOT NULL")); + chkNotNull->Enable(); + btnChangeMember->Enable(); + btnRemoveMember->Enable(); + } +} + + +void dlgForeignTable::OnMemberAdd(wxCommandEvent &ev) +{ + wxString name = txtMembername->GetValue().Strip(wxString::both); + wxString type = cbDatatype->GetValue(); + wxString length = wxEmptyString; + wxString precision = wxEmptyString; + wxString notnull = wxEmptyString; + + if (txtLength->GetValue() != wxT("") && txtLength->IsEnabled()) + length = txtLength->GetValue(); + if (txtPrecision->GetValue() != wxT("") && txtPrecision->IsEnabled()) + precision = txtPrecision->GetValue(); + notnull = chkNotNull->GetValue() ? wxT("NOT NULL") : wxEmptyString; + + if (!length.IsEmpty()) + { + type += wxT("(") + length; + if (!precision.IsEmpty()) + type += wxT(",") + precision; + type += wxT(")"); + } + + if (!name.IsEmpty()) + { + size_t pos = lstMembers->GetItemCount(); + lstMembers->InsertItem(pos, name, 0); + lstMembers->SetItem(pos, 1, type); + lstMembers->SetItem(pos, 2, notnull); + memberTypes.Add(GetTypeInfo(cbDatatype->GetGuessedSelection())); + memberLengths.Add(length); + memberPrecisions.Add(precision); + memberNotNulls.Add(notnull); + } + + txtMembername->SetValue(wxEmptyString); + cbDatatype->SetValue(wxEmptyString); + txtLength->SetValue(wxEmptyString); + txtPrecision->SetValue(wxEmptyString); + chkNotNull->SetValue(false); + + CheckChange(); +} + + +void dlgForeignTable::OnMemberChange(wxCommandEvent &ev) +{ + wxString name = txtMembername->GetValue().Strip(wxString::both); + wxString type = cbDatatype->GetValue(); + wxString length = wxEmptyString; + wxString precision = wxEmptyString; + wxString notnull = wxEmptyString; + + if (txtLength->GetValue() != wxT("") && txtLength->IsEnabled()) + length = txtLength->GetValue(); + if (txtPrecision->GetValue() != wxT("") && txtPrecision->IsEnabled()) + precision = txtPrecision->GetValue(); + notnull = chkNotNull->GetValue() ? wxT("NOT NULL") : wxEmptyString; + + if (!length.IsEmpty()) + { + type += wxT("(") + length; + if (!precision.IsEmpty()) + type += wxT(",") + precision; + type += wxT(")"); + } + + if (!name.IsEmpty()) + { + long pos = lstMembers->GetFirstSelected(); + if (pos >= 0) + { + lstMembers->SetItem(pos, 0, name); + lstMembers->SetItem(pos, 1, type); + lstMembers->SetItem(pos, 2, notnull); + memberTypes.Insert(GetTypeInfo(cbDatatype->GetGuessedSelection()), pos); + memberLengths.Insert(length, pos); + memberPrecisions.Insert(precision, pos); + memberNotNulls.Insert(notnull, pos); + memberTypes.RemoveAt(pos + 1); + memberLengths.RemoveAt(pos + 1); + memberPrecisions.RemoveAt(pos + 1); + memberNotNulls.RemoveAt(pos + 1); + } + } + + CheckChange(); +} + + +void dlgForeignTable::OnMemberRemove(wxCommandEvent &ev) +{ + long pos = lstMembers->GetSelection(); + + if (pos >= 0) + { + lstMembers->DeleteItem(pos); + memberTypes.RemoveAt(pos); + memberLengths.RemoveAt(pos); + memberPrecisions.RemoveAt(pos); + memberNotNulls.RemoveAt(pos); + } + CheckChange(); +} + + +pgObject *dlgForeignTable::CreateObject(pgCollection *collection) +{ + pgObject *obj = 0; + return obj; +} + + +void dlgForeignTable::OnChangeOptionName(wxCommandEvent &ev) +{ + btnAdd->Enable(txtOption->GetValue().Length() > 0); +} + + +void dlgForeignTable::OnSelChangeOption(wxListEvent &ev) +{ + int row = lstOptions->GetSelection(); + if (row >= 0) + { + txtOption->SetValue(lstOptions->GetText(row, 0)); + txtValue->SetValue(lstOptions->GetText(row, 1)); + } + + btnRemove->Enable(row >= 0); +} + + +void dlgForeignTable::OnAddOption(wxCommandEvent &ev) +{ + bool found = false; + + for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + if (lstOptions->GetText(pos).IsSameAs(txtOption->GetValue(), false)) + { + lstOptions->SetItem(pos, 1, txtValue->GetValue()); + found = true; + break; + } + } + + if (!found) + { + lstOptions->AppendItem(txtOption->GetValue(), txtValue->GetValue()); + } + + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnAdd->Disable(); + + CheckChange(); +} + + +void dlgForeignTable::OnRemoveOption(wxCommandEvent &ev) +{ + int sel = lstOptions->GetSelection(); + lstOptions->DeleteItem(sel); + + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnRemove->Disable(); + + CheckChange(); +} + + +wxString dlgForeignTable::GetOptionsSql() +{ + wxArrayString options = foreigntable->GetOptionsArray(); + wxString optionname, optionvalue, sqloptions; + bool found; + int pos; + + for (unsigned int index = 0; index < options.Count(); index += 2) + { + optionname = options.Item(index); + optionvalue = options.Item(index + 1); + + // check for options + found = false; + for (pos = 0 ; pos < lstOptions->GetItemCount() && !found; pos++) + { + found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0; + if (found) break; + } + + if (found) + { + if (lstOptions->GetText(pos, 1).Cmp(optionvalue) != 0) + { + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += wxT("SET ") + optionname + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("'"); + } + } + else + { + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += wxT("DROP ") + optionname; + } + } + + for (pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + options = foreigntable->GetOptionsArray(); + found = false; + + for (unsigned int index = 0; index < options.Count() && !found; index += 2) + { + optionname = options.Item(index); + optionvalue = options.Item(index + 1); + found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0; + } + + if (!found) + { + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += wxT("ADD ") + lstOptions->GetText(pos, 0) + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("'"); + } + } + + return sqloptions; +} + + +wxString dlgForeignTable::GetSql() +{ + wxString sql; + wxString name; + + if (foreigntable) + { + // Edit Mode + name = qtIdent(foreigntable->GetSchema()->GetName()) + wxT(".") + qtIdent(GetName()); + + AppendNameChange(sql, wxT("FOREIGN TABLE ") + foreigntable->GetQuotedFullIdentifier()); + AppendOwnerChange(sql, wxT("FOREIGN TABLE ") + name); + + sql += GetSqlForTypes(); + + wxString sqloptions = GetOptionsSql(); + if (sqloptions.Length() > 0) + { + sql += wxT("ALTER FOREIGN TABLE ") + name + + wxT("\n OPTIONS (") + sqloptions + wxT(");\n"); + } + AppendSchemaChange(sql, wxT("FOREIGN TABLE ") + name); + } + else + { + name = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()); + + // Create Mode + sql = wxT("CREATE FOREIGN TABLE " + name); + sql += wxT(" ("); + + int i; + for (i = 0 ; i < lstMembers->GetItemCount() ; i++) + { + if (i) + sql += wxT(",\n "); + sql += qtIdent(lstMembers->GetItemText(i)) + wxT(" ") + + GetFullTypeName(i); + } + + sql += wxT(") SERVER ") + cbForeignServer->GetValue(); + + // check for options + if (lstOptions->GetItemCount() > 0) + { + wxString options = wxEmptyString; + for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + if (options.Length() > 0) + options += wxT(", "); + + options += lstOptions->GetText(pos, 0) + + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("' "); + } + sql += wxT("\n OPTIONS (") + options + wxT(")"); + } + + sql += wxT(";\n"); + } + AppendComment(sql, wxT("FOREIGN TABLE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), foreigntable); + + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + sql += seclabelPage->GetSqlForSecLabels(wxT("FOREIGN TABLE "), qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName())); + + return sql; +} + +wxString dlgForeignTable::GetFullTypeName(int type) +{ + wxString typname = memberTypes.Item(type).AfterFirst(':'); + + if (!memberLengths.Item(type).IsEmpty()) + { + typname += wxT("(") + memberLengths.Item(type); + if (!memberPrecisions.Item(type).IsEmpty()) + typname += wxT(",") + memberPrecisions.Item(type); + typname += wxT(")"); + } + + typname += wxT(" ") + memberNotNulls.Item(type); + + return typname; +} + +wxString dlgForeignTable::GetSqlForTypes() +{ + wxString sql = wxEmptyString; + wxString old_name, old_type, new_name, new_type; + wxArrayString elements = foreigntable->GetTypesArray(); + bool modified = lstMembers->GetItemCount() * 3 != (int)elements.GetCount(); + size_t i; + + // Check if there is a change + for (int i = 0 ; i < lstMembers->GetItemCount() && !modified; i++) + { + old_name = elements.Item(i * 3); + old_type = elements.Item(i * 3 + 1) + wxT(" ") + elements.Item(i * 3 + 2); + new_name = lstMembers->GetItemText(i); + new_type = GetFullTypeName(i); + modified = modified || old_name != new_name || old_type != new_type; + } + + if (modified) + { + // Drop all old attributes + for (i = 0 ; i < elements.GetCount() ; i += 3) + { + old_name = elements.Item(i); + sql += wxT("ALTER FOREIGN TABLE ") + foreigntable->GetQuotedFullIdentifier() + + wxT("\n DROP COLUMN ") + old_name + wxT(";\n"); + } + + // Add all new attributes + for (int i = 0 ; i < lstMembers->GetItemCount() ; i++) + { + new_name = lstMembers->GetItemText(i); + new_type = GetFullTypeName(i); + sql += wxT("ALTER FOREIGN TABLE ") + foreigntable->GetQuotedFullIdentifier() + + wxT("\n ADD COLUMN ") + new_name + wxT(" ") + new_type + wxT(";\n"); + } + } + + return sql; +} + +void dlgForeignTable::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} diff --git a/dlg/dlgFunction.cpp b/dlg/dlgFunction.cpp new file mode 100644 index 0000000..7cba8f2 --- /dev/null +++ b/dlg/dlgFunction.cpp @@ -0,0 +1,1122 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgFunction.cpp - PostgreSQL Function Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "ctl/ctlSQLBox.h" +#include "dlg/dlgFunction.h" +#include "schema/pgFunction.h" +#include "schema/pgSchema.h" +#include "schema/pgDatatype.h" +#include "ctl/ctlSeclabelPanel.h" + + + +// pointer to controls +#define txtArguments CTRL_TEXT("txtArguments") +#define cbReturntype CTRL_COMBOBOX2("cbReturntype") +#define cbLanguage CTRL_COMBOBOX2("cbLanguage") +#define chkSetof CTRL_CHECKBOX("chkSetof") +#define cbVolatility CTRL_COMBOBOX("cbVolatility") +#define cbParallel CTRL_COMBOBOX("cbParallel") +#define chkStrict CTRL_CHECKBOX("chkStrict") +#define chkWindow CTRL_CHECKBOX("chkWindow") +#define chkSecureDefiner CTRL_CHECKBOX("chkSecureDefiner") +#define txtCost CTRL_TEXT("txtCost") +#define txtRows CTRL_TEXT("txtRows") +#define chkLeakProof CTRL_CHECKBOX("chkLeakProof") + +#define lstArguments CTRL_LISTVIEW("lstArguments") +#define rdbIn CTRL_RADIOBUTTON("rdbIn") +#define rdbOut CTRL_RADIOBUTTON("rdbOut") +#define rdbInOut CTRL_RADIOBUTTON("rdbInOut") +#define rdbVariadic CTRL_RADIOBUTTON("rdbVariadic") + +#define txtArgName CTRL_TEXT("txtArgName") +#define txtArgDefVal CTRL_TEXT("txtArgDefVal") +#define btnAdd CTRL_BUTTON("wxID_ADD") +#define btnChange CTRL_BUTTON("wxID_CHANGE") +#define btnRemove CTRL_BUTTON("wxID_REMOVE") + +#define pnlParameters CTRL_PANEL("pnlParameters") +#define sbxDefinition CTRL_STATICBOX("sbxDefinition") +#define stObjectFile CTRL_STATIC("stObjectFile") +#define txtObjectFile CTRL_TEXT("txtObjectFile") +#define stLinkSymbol CTRL_STATIC("stLinkSymbol") +#define txtLinkSymbol CTRL_TEXT("txtLinkSymbol") +#define txtSqlBox CTRL_SQLBOX("txtSqlBox") + +#define lstVariables CTRL_LISTVIEW("lstVariables") +#define btnAddVar CTRL_BUTTON("btnAddVar") +#define btnRemoveVar CTRL_BUTTON("btnRemoveVar") +#define cbVarname CTRL_COMBOBOX2("cbVarname") +#define txtValue CTRL_TEXT("txtValue") +#define chkValue CTRL_CHECKBOX("chkValue") + +#define TXTOBJ_LIB wxT("$libdir/") + +BEGIN_EVENT_TABLE(dlgFunction, dlgSecurityProperty) + EVT_TEXT(XRCID("cbVolatility"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbParallel"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkStrict"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkSecureDefiner"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtObjectFile"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtLinkSymbol"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtCost"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtRows"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkLeakProof"), dlgProperty::OnChange) + EVT_STC_MODIFIED(XRCID("txtSqlBox"), dlgProperty::OnChangeStc) + + EVT_CHECKBOX(XRCID("chkSetof"), dlgFunction::OnChangeSetof) + EVT_TEXT(XRCID("cbReturntype"), dlgFunction::OnChangeReturn) + EVT_COMBOBOX(XRCID("cbReturntype"), dlgFunction::OnChangeReturn) + EVT_TEXT(XRCID("cbDatatype"), dlgFunction::OnSelChangeType) + EVT_COMBOBOX(XRCID("cbDatatype"), dlgFunction::OnSelChangeType) + EVT_TEXT(XRCID("cbLanguage"), dlgFunction::OnSelChangeLanguage) + EVT_COMBOBOX(XRCID("cbLanguage"), dlgFunction::OnSelChangeLanguage) + + EVT_LIST_ITEM_SELECTED(XRCID("lstArguments"), dlgFunction::OnSelChangeArg) + EVT_TEXT(XRCID("txtArgName"), dlgFunction::OnChangeArgName) + EVT_BUTTON(wxID_ADD, dlgFunction::OnAddArg) + EVT_BUTTON(XRCID("wxID_CHANGE"), dlgFunction::OnChangeArg) + EVT_BUTTON(wxID_REMOVE, dlgFunction::OnRemoveArg) + + EVT_LIST_ITEM_SELECTED(XRCID("lstVariables"), dlgFunction::OnVarSelChange) + EVT_BUTTON(XRCID("btnAddVar"), dlgFunction::OnVarAdd) + EVT_BUTTON(XRCID("btnRemoveVar"), dlgFunction::OnVarRemove) + EVT_TEXT(XRCID("cbVarname"), dlgFunction::OnVarnameSelChange) + EVT_COMBOBOX(XRCID("cbVarname"), dlgFunction::OnVarnameSelChange) + EVT_RADIOBUTTON(XRCID("rdbIn"), dlgFunction::OnChangeArgMode) + EVT_RADIOBUTTON(XRCID("rdbOut"), dlgFunction::OnChangeArgMode) + EVT_RADIOBUTTON(XRCID("rdbInOut"), dlgFunction::OnChangeArgMode) + EVT_RADIOBUTTON(XRCID("rdbVariadic"), dlgFunction::OnChangeArgMode) + EVT_CHECKBOX(XRCID("chkWindow"), dlgFunction::OnChangeWindow) +#ifdef __WXMAC__ + EVT_SIZE( dlgFunction::OnChangeSize) +#endif +END_EVENT_TABLE(); + + +dlgProperty *pgFunctionFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + pgSchema *sch; + + if (parent->GetMetaType() == PGM_TRIGGER) + sch = parent->GetSchema(); + // Event triggers are at database level. So, we do not have a schema for an event trigger. + else if(parent->GetMetaType() == PGM_EVENTTRIGGER) + sch = 0; + else + sch = (pgSchema *)parent; + + return new dlgFunction(this, frame, (pgFunction *)node, sch); +} + + +dlgFunction::dlgFunction(pgaFactory *f, frmMain *frame, pgFunction *node, pgSchema *sch) + : dlgSecurityProperty(f, frame, node, wxT("dlgFunction"), wxT("EXECUTE"), "X"), + isEdbWrapped( false ) +{ + schema = sch; + function = node; + isProcedure = false; + + seclabelPage = new ctlSeclabelPanel(nbNotebook); + + txtArguments->Disable(); + + if (!node) + { + int icon = PGICON_PUBLIC; + wxString name = wxT("public"); + wxString value = wxT("X"); + securityPage->lbPrivileges->AppendItem(icon, name, value); + AppendCurrentAcl(name, value); + } + + bool bVal; + settings->Read(wxT("frmQuery/ShowLineNumber"), &bVal, false); + if (!bVal) + { + txtSqlBox->SetMarginType(1, wxSTC_MARGIN_NUMBER); + txtSqlBox->SetMarginWidth(1, ConvertDialogToPixels(wxPoint(16, 0)).x); + } + + btnAdd->Disable(); + btnRemove->Disable(); + btnChange->Disable(); + + lstVariables->CreateColumns(0, _("Variable"), _("Value"), -1); + chkValue->Hide(); +} + + + +dlgProperty *pgProcedureFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgProcedure(this, frame, (pgFunction *)node, (pgSchema *)parent); +} + +dlgProcedure::dlgProcedure(pgaFactory *f, frmMain *frame, pgFunction *node, pgSchema *sch) + : dlgFunction(f, frame, node, sch) +{ + isProcedure = true; +} + +pgObject *dlgFunction::GetObject() +{ + return function; +} + + +int dlgFunction::Go(bool modal) +{ + isBackendMinVer84 = connection->BackendMinimumVersion(8, 4); + + if (connection->BackendMinimumVersion(9, 1)) + { + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(function); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgFunction::OnChange)); + } + else + seclabelPage->Disable(); + + if (function) + { + cbSchema->Enable(connection->BackendMinimumVersion(8, 1)); + rdbIn->Disable(); + rdbOut->Disable(); + rdbInOut->Disable(); + rdbVariadic->Disable(); + isProcedure = function->GetIsProcedure(); + } + + if (!isBackendMinVer84) + txtArgDefVal->Disable(); + chkLeakProof->Enable(connection->BackendMinimumVersion(9, 2)); + + lstArguments->AddColumn(_("Type"), 60); + lstArguments->AddColumn(_("Mode"), 40); + lstArguments->AddColumn(_("Name"), 60); + lstArguments->AddColumn(_("Default Value"), 60); + + if (!connection->BackendMinimumVersion(8, 0)) + cbOwner->Disable(); + + if (!connection->BackendMinimumVersion(8, 3)) + txtCost->Disable(); + + txtRows->Disable(); + + if (!connection->BackendMinimumVersion(8, 0)) + txtArgName->Disable(); + + // Window function can not be modified + // Disable it for editing + if (function || !isBackendMinVer84) + chkWindow->Disable(); + + if (isProcedure) + { + if (function && !connection->EdbMinimumVersion(8, 2)) + txtName->Disable(); + cbOwner->Disable(); + //cbLanguage->Disable(); + chkStrict->Disable(); + chkWindow->Disable(); + chkSecureDefiner->Disable(); + chkSetof->Disable(); + cbVolatility->Disable(); + cbParallel->Disable(); + cbReturntype->Disable(); + txtCost->Disable(); + txtRows->Disable(); + chkLeakProof->Disable(); + } + else + { + if (!connection->BackendMinimumVersion(8, 1)) + { + rdbIn->SetValue(true); + rdbIn->Disable(); + rdbOut->Disable(); + rdbInOut->Disable(); + } + + if (!isBackendMinVer84) + { + rdbVariadic->Disable(); + } + } + + pgSet *lang = connection->ExecuteSet(wxT("SELECT lanname FROM pg_language")); + if (lang) + { + while (!lang->Eof()) + { + wxString language = lang->GetVal(0); + if (factory == &triggerFunctionFactory) + { + if (language.IsSameAs(wxT("SQL"), false) || + language.IsSameAs(wxT("edbspl"), false)) + { + lang->MoveNext(); + continue; + } + } + cbLanguage->Append(language); + lang->MoveNext(); + } + delete lang; + } + + if (connection->BackendMinimumVersion(8, 3)) + { + pgSet *set; + set = connection->ExecuteSet(wxT("SELECT name, vartype, min_val, max_val\n") + wxT(" FROM pg_settings WHERE context in ('user', 'superuser')")); + if (set) + { + while (!set->Eof()) + { + cbVarname->Append(set->GetVal(0)); + varInfo.Add(set->GetVal(wxT("vartype")) + wxT(" ") + + set->GetVal(wxT("min_val")) + wxT(" ") + + set->GetVal(wxT("max_val"))); + set->MoveNext(); + } + delete set; + + cbVarname->SetSelection(0); + SetupVarEditor(0); + } + + } + else + { + btnAddVar->Disable(); + btnRemoveVar->Disable(); + cbVarname->Disable(); + txtValue->Disable(); + chkValue->Disable(); + } + + if (function) + { + // edit mode + + if (factory != &triggerFunctionFactory) + { + wxArrayString argTypes = function->GetArgTypesArray(); + wxArrayString argNames = function->GetArgNamesArray(); + wxArrayString argModes = function->GetArgModesArray(); + wxArrayString argDefs = function->GetArgDefsArray(); + + for (unsigned int i = 0; i < argTypes.Count(); i++) + { + if (argModes[i] != wxT("TABLE")) + { + if (isBackendMinVer84) + lstArguments->AppendItem(-1, argTypes.Item(i), argModes[i], argNames[i], (argDefs.Count() > i ? argDefs[i] : wxString(wxEmptyString))); + else + lstArguments->AppendItem(-1, argTypes.Item(i), argModes[i], argNames[i]); + } + } + } + + txtArguments->SetValue(function->GetArgListWithNames()); + cbReturntype->Append(function->GetReturnType()); + cbReturntype->SetValue(function->GetReturnType()); + + cbLanguage->SetValue(function->GetLanguage()); + cbVolatility->SetValue(function->GetVolatility()); + cbParallel->SetValue(function->GetParallel()); + + chkSetof->SetValue(function->GetReturnAsSet()); + chkStrict->SetValue(function->GetIsStrict()); + if (connection->BackendMinimumVersion(8, 4)) + chkWindow->SetValue(function->GetIsWindow()); + chkSecureDefiner->SetValue(function->GetSecureDefiner()); + chkLeakProof->SetValue(function->GetIsLeakProof()); + + if (function->GetLanguage().IsSameAs(wxT("C"), false)) + { + txtObjectFile->SetValue(function->GetBin()); + txtLinkSymbol->SetValue(function->GetSource()); + } + else + txtSqlBox->SetText(function->GetSource()); + + if (!connection->BackendMinimumVersion(7, 4)) + txtName->Disable(); + + if (connection->BackendMinimumVersion(8, 3)) + { + txtCost->SetValue(NumToStr(function->GetCost())); + if (function->GetReturnAsSet()) + { + txtRows->SetValue(NumToStr(function->GetRows())); + txtRows->Enable(); + } + else + txtRows->Disable(); + } + + size_t index; + for (index = 0 ; index < function->GetConfigList().GetCount() ; index++) + { + wxString item = function->GetConfigList().Item(index); + lstVariables->AppendItem(0, item.BeforeFirst('='), item.AfterFirst('=')); + } + + cbReturntype->Disable(); + chkSetof->Disable(); + cbDatatype->Disable(); + // Editing parameter for wrapped functions is not allowed + // It will anyway throw an error, if we try to edit the parameter list + if ( connection->GetIsEdb() && + function->GetSource().Trim(false).StartsWith( wxT( "$__EDBwrapped__$" ))) + { + isEdbWrapped = true; + cbDatatype->Disable(); + rdbIn->Disable(); + rdbOut->Disable(); + rdbInOut->Disable(); + rdbVariadic->Disable(); + txtArgName->Disable(); + txtArgDefVal->Disable(); + btnAdd->Disable(); + btnChange->Disable(); + btnRemove->Disable(); + } + } + else + { + wxString restrict; + // create mode + restrict = wxT("(typtype IN ('b', 'c', 'd', 'e', 'p', 'r') AND typname NOT IN ('any', 'trigger', 'language_handler', 'event_trigger'))"); + if (!settings->GetShowSystemObjects()) + restrict += wxT(" AND nspname NOT LIKE E'pg\\\\_toast%' AND nspname NOT LIKE E'pg\\\\_temp%'"); + + DatatypeReader tr(database, restrict); + while (tr.HasMore()) + { + pgDatatype dt = tr.GetDatatype(); + + typOids.Add(tr.GetOidStr()); + types.Add(dt.GetQuotedSchemaPrefix(database) + dt.QuotedFullName()); + + cbDatatype->Append(dt.GetQuotedSchemaPrefix(database) + dt.QuotedFullName()); + if (factory != &triggerFunctionFactory) + cbReturntype->Append(dt.GetQuotedSchemaPrefix(database) + dt.QuotedFullName()); + tr.MoveNext(); + } + + long sel; + if (factory == &triggerFunctionFactory) + { + cbReturntype->Append(wxT("trigger")); + + if (connection->BackendMinimumVersion(9, 3)) + cbReturntype->Append(wxT("event_trigger")); + + cbReturntype->SetSelection(0); + lstArguments->Disable(); + cbDatatype->Disable(); + txtArgName->Disable(); + txtArgDefVal->Disable(); + rdbIn->Disable(); + rdbOut->Disable(); + rdbInOut->Disable(); + rdbVariadic->Disable(); + sel = cbLanguage->FindString(wxT("c")); + } + else if (isProcedure) + sel = cbLanguage->FindString(wxT("plpgsql")); + else + sel = cbLanguage->FindString(wxT("sql")); + + if (sel >= 0) + cbLanguage->SetSelection(sel); + txtObjectFile->SetValue(TXTOBJ_LIB); + } + + wxNotifyEvent event; + OnSelChangeLanguage(event); + + return dlgSecurityProperty::Go(modal); +} + +#ifdef __WXMAC__ +void dlgFunction::OnChangeSize(wxSizeEvent &ev) +{ + lstArguments->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350); + lstVariables->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350); + dlgSecurityProperty::OnChangeSize(ev); +} +#endif + + +void dlgFunction::OnVarnameSelChange(wxCommandEvent &ev) +{ + int sel = cbVarname->GuessSelection(ev); + + SetupVarEditor(sel); +} + +void dlgFunction::SetupVarEditor(int var) +{ + if (var >= 0 && varInfo.Count() > 0) + { + wxStringTokenizer vals(varInfo.Item(var)); + wxString typ = vals.GetNextToken(); + + if (typ == wxT("bool")) + { + txtValue->Hide(); + chkValue->Show(); + chkValue->GetParent()->Layout(); + } + else + { + chkValue->Hide(); + txtValue->Show(); + txtValue->GetParent()->Layout(); + if (typ == wxT("string") || typ == wxT("enum")) + txtValue->SetValidator(wxTextValidator()); + else + txtValue->SetValidator(numericValidator); + } + } +} + +void dlgFunction::OnVarSelChange(wxListEvent &ev) +{ + long pos = lstVariables->GetSelection(); + if (pos >= 0) + { + wxString value = lstVariables->GetText(pos, 1); + cbVarname->SetValue(lstVariables->GetText(pos)); + + + // We used to raise an OnVarnameSelChange() event here, but + // at this point the combo box hasn't necessarily updated. + int sel = cbVarname->FindString(lstVariables->GetText(pos)); + SetupVarEditor(sel); + + txtValue->SetValue(value); + chkValue->SetValue(value == wxT("on")); + } +} + + + +void dlgFunction::OnVarAdd(wxCommandEvent &ev) +{ + wxString name = cbVarname->GetValue(); + wxString value; + if (chkValue->IsShown()) + value = chkValue->GetValue() ? wxT("on") : wxT("off"); + else + value = txtValue->GetValue().Strip(wxString::both); + + if (value.IsEmpty()) + value = wxT("DEFAULT"); + + if (!name.IsEmpty()) + { + long pos = lstVariables->FindItem(-1, name); + if (pos < 0) + { + pos = lstVariables->GetItemCount(); + lstVariables->InsertItem(pos, name, 0); + } + lstVariables->SetItem(pos, 1, value); + } + CheckChange(); +} + + +void dlgFunction::OnVarRemove(wxCommandEvent &ev) +{ + if (lstVariables->GetSelection() == wxNOT_FOUND) + return; + lstVariables->DeleteCurrentItem(); + CheckChange(); +} + + +pgObject *dlgFunction::CreateObject(pgCollection *collection) +{ + wxString sql = wxT(" WHERE proname=") + qtDbString(GetName()) + + wxT("\n AND pronamespace=") + schema->GetOidStr(); + + long argCount; + for (argCount = 0 ; argCount < (int)argOids.GetCount() ; argCount++) + sql += wxT("\n AND proargtypes[") + NumToStr(argCount) + wxT("] = ") + argOids.Item(argCount); + + sql += wxT("\n AND proargtypes[") + NumToStr(argCount) + wxT("] = 0\n"); + + pgObject *obj = functionFactory.AppendFunctions(collection, collection->GetSchema(), 0, sql); + return obj; +} + + +void dlgFunction::CheckChange() +{ + wxString name = GetName(); + bool isC = cbLanguage->GetValue().IsSameAs(wxT("C"), false); + bool enable = true, didChange = true; + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + if (!isProcedure) + CheckValid(enable, cbReturntype->GetValue().Trim() != wxEmptyString, _("Please select return type.")); + + CheckValid(enable, cbLanguage->GetGuessedSelection() >= 0, _("Please select language.")); + + if (isC) + { + wxString objfile = txtObjectFile->GetValue(); + CheckValid(enable, !objfile.IsEmpty() && objfile != TXTOBJ_LIB, _("Please specify object library.")); + } + else + { + CheckValid(enable, !txtSqlBox->GetText().IsEmpty(), _("Please enter function source code.")); + } + + if (function && enable) + { + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); + EnableOK(enable && !GetSql().IsEmpty()); + } + else + { + EnableOK(enable && didChange); + } +} + +bool dlgFunction::IsUpToDate() +{ + if (function && !function->IsUpToDate()) + return false; + else + return true; +} + +void dlgFunction::OnSelChangeLanguage(wxCommandEvent &ev) +{ + bool isC = (cbLanguage->GetValue().IsSameAs(wxT("C"), false)); + + stObjectFile->Show(isC); + txtObjectFile->Show(isC); + stLinkSymbol->Show(isC); + txtLinkSymbol->Show(isC); + txtSqlBox->Show(!isC); + + txtSqlBox->GetContainingSizer()->Layout(); + + CheckChange(); +} + + +void dlgFunction::OnSelChangeArg(wxListEvent &ev) +{ + int row = lstArguments->GetSelection(); + if (row >= 0) + { + cbDatatype->SetValue(lstArguments->GetText(row, 0)); + wxString mode = lstArguments->GetText(row, 1); + if (mode == wxT("IN")) + rdbIn->SetValue(true); + else if (mode == wxT("OUT")) + rdbOut->SetValue(true); + else if (mode == wxT("IN OUT") || mode == wxT("INOUT")) + rdbInOut->SetValue(true); + else if (mode == wxT("VARIADIC")) + rdbVariadic->SetValue(true); + txtArgName->SetValue(lstArguments->GetText(row, 2)); + if (isBackendMinVer84) + { + txtArgDefVal->SetValue(lstArguments->GetText(row, 3)); + txtArgDefVal->Enable(mode == wxT("IN") || mode.IsEmpty()); + } + + wxCommandEvent ev; + OnChangeArgName(ev); + } +} + + +void dlgFunction::OnChangeReturn(wxCommandEvent &ev) +{ + cbReturntype->GuessSelection(ev); + CheckChange(); +} + + +void dlgFunction::OnChangeSetof(wxCommandEvent &ev) +{ + if (chkSetof->GetValue() && connection->BackendMinimumVersion(8, 3) && !isProcedure) + txtRows->Enable(); + else + txtRows->Disable(); + + CheckChange(); +} + + +void dlgFunction::OnSelChangeType(wxCommandEvent &ev) +{ + cbDatatype->GuessSelection(ev); + OnChangeArgName(ev); +} + + +void dlgFunction::OnChangeArgName(wxCommandEvent &ev) +{ + int argNameRow = -1; + if (!txtArgName->GetValue().IsEmpty()) + argNameRow = lstArguments->FindItem(-1, txtArgName->GetValue()); + + int pos = lstArguments->GetSelection(); + + bool typeValid = (function != 0 || cbDatatype->GetGuessedSelection() >= 0); + + // EDBWrapped function does not allow modification in parameter list + btnChange->Enable(pos >= 0 && typeValid && !isEdbWrapped); + if (!function) + { + // EDBWrapped function does not allow modification in parameter list + btnAdd->Enable(argNameRow < 0 && typeValid && !isEdbWrapped); + btnRemove->Enable(pos >= 0 && !isEdbWrapped); + } +} + +void dlgFunction::OnChangeArgMode(wxCommandEvent &ev) +{ + // Do nothing, if Default value for function parameter not supported + if (!isBackendMinVer84) + return; + + // Only IN parameter supports default value + if (!rdbIn->GetValue()) + { + txtArgDefVal->SetValue(wxEmptyString); + txtArgDefVal->Enable(false); + } + else + { + // EDBWrapped function does not allow modification in parameter list + txtArgDefVal->Enable(true && !isEdbWrapped); + } +} + +void dlgFunction::OnChangeArg(wxCommandEvent &ev) +{ + if (GetSelectedDirection() == wxT("VARIADIC") && + !cbDatatype->GetValue().EndsWith(wxT("[]"))) + { + wxLogError(_("Only array types can be VARIADIC.")); + return; + } + + int row = lstArguments->GetSelection(); + + if (row >= 0) + { + lstArguments->SetItem(row, 0, cbDatatype->GetValue()); + lstArguments->SetItem(row, 1, GetSelectedDirection()); + lstArguments->SetItem(row, 2, txtArgName->GetValue()); + if (isBackendMinVer84) + lstArguments->SetItem(row, 3, txtArgDefVal->GetValue()); + + if (!function) + argOids.Item(row) = typOids.Item(cbDatatype->GetGuessedSelection()); + txtArguments->SetValue(GetArgs()); + } + OnChangeArgName(ev); + CheckChange(); +} + + +void dlgFunction::OnAddArg(wxCommandEvent &ev) +{ + if (GetSelectedDirection() == wxT("VARIADIC") && + !cbDatatype->GetValue().EndsWith(wxT("[]"))) + { + wxLogError(_("Only array types can be VARIADIC.")); + return; + } + + lstArguments->AppendItem(-1, cbDatatype->GetValue(), GetSelectedDirection(), txtArgName->GetValue(), txtArgDefVal->GetValue().Trim()); + + if (!function) + argOids.Add(typOids.Item(cbDatatype->GetGuessedSelection())); + + txtArguments->SetValue(GetArgs()); + OnChangeArgName(ev); +} + + +void dlgFunction::OnRemoveArg(wxCommandEvent &ev) +{ + unsigned int sel = lstArguments->GetSelection(); + argOids.RemoveAt(sel); + lstArguments->DeleteItem(sel); + btnRemove->Disable(); + txtArguments->SetValue(GetArgs()); + OnChangeArgName(ev); +} + +wxString dlgFunction::GetSelectedDirection() +{ + if (rdbIn->GetValue()) + return wxT("IN"); + else if (rdbOut->GetValue()) + return wxT("OUT"); + else if (rdbInOut->GetValue()) + { + if (isProcedure) + return wxT("INOUT"); + else + return wxT("INOUT"); + } + else if (rdbVariadic->GetValue()) + return wxT("VARIADIC"); + else + return wxEmptyString; +} + + +wxString dlgFunction::GetArgs(const bool withNames, const bool inOnly) +{ + wxString args; + bool isEdbspl = cbLanguage->GetValue() == wxT("edbspl"); + + for (int i = 0; i < lstArguments->GetItemCount(); i++) + { + if (!isEdbspl && inOnly && lstArguments->GetText(i, 1) == wxT("OUT")) + continue; + + if (i && !args.IsEmpty() && !args.EndsWith(wxT(", "))) + args += wxT(", "); + + if (isProcedure) + { + if (withNames && lstArguments->GetText(i, 2) != wxEmptyString) + args += qtIdent(lstArguments->GetText(i, 2)) + wxT(" "); + + // edbspl functions should list OUT params, but only by type. + // although this is not true for EDB AS90 onwards.. + if (!inOnly || !isEdbspl || lstArguments->GetText(i, 1) != wxT("OUT") || + connection->EdbMinimumVersion(9, 0)) + { + if (lstArguments->GetText(i, 1) != wxEmptyString) + args += lstArguments->GetText(i, 1) + wxT(" "); + } + + args += lstArguments->GetText(i, 0); + } + else + { + // edbspl functions should list OUT params, but only by type. + // although this is not true for EDB AS90 onwards.. + if (!inOnly || !isEdbspl || lstArguments->GetText(i, 1) != wxT("OUT") || + connection->EdbMinimumVersion(9, 0)) + { + if (connection->BackendMinimumVersion(8, 1) && lstArguments->GetText(i, 1) != wxEmptyString) + args += lstArguments->GetText(i, 1) + wxT(" "); + } + + if (connection->BackendMinimumVersion(8, 0) && withNames && lstArguments->GetText(i, 2) != wxEmptyString) + args += qtIdent(lstArguments->GetText(i, 2)) + wxT(" "); + + args += lstArguments->GetText(i, 0); + } + if (withNames && isBackendMinVer84 && !lstArguments->GetText(i, 3).IsEmpty()) + args += wxT(" DEFAULT ") + lstArguments->GetText(i, 3); + } + + return args; +} + + +wxString dlgFunction::GetSql() +{ + wxString sql; + wxString name; + wxString objType; + if (isProcedure) + objType = wxT("PROCEDURE "); + else + objType = wxT("FUNCTION "); + + bool isC = cbLanguage->GetValue().IsSameAs(wxT("C"), false); + bool didChange = !function + || cbLanguage->GetValue() != function->GetLanguage() + || cbVolatility->GetValue() != function->GetVolatility() + || cbParallel->GetValue() != function->GetParallel() + || chkSecureDefiner->GetValue() != function->GetSecureDefiner() + || chkStrict->GetValue() != function->GetIsStrict() + || GetArgs() != function->GetArgListWithNames() + || chkLeakProof->GetValue() != function->GetIsLeakProof() + || (isC && (txtObjectFile->GetValue() != function->GetBin() || txtLinkSymbol->GetValue() != function->GetSource())) + || (!isC && txtSqlBox->GetText() != function->GetSource()); + + if (connection->BackendMinimumVersion(8, 3)) + { + didChange = (didChange || + txtCost->GetValue() != NumToStr(function->GetCost()) || + (chkSetof->GetValue() && txtRows->GetValue() != NumToStr(function->GetRows()))); + } + + if (function) + { + name = GetName(); + // edit mode + if (name != function->GetName()) + { + if (!isProcedure) + AppendNameChange(sql, wxT("FUNCTION ") + function->GetQuotedFullIdentifier() + + wxT("(") + function->GetArgSigList() + wxT(")")); + else + AppendNameChange(sql, wxT("PROCEDURE ") + function->GetQuotedFullIdentifier()); + } + if (didChange) + sql += wxT("CREATE OR REPLACE ") + objType; + } + else + { + name = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()); + + // create mode + sql = wxT("CREATE " ) + objType; + } + + if (didChange) + { + if (isProcedure && GetArgs().IsEmpty()) + { + sql += schema->GetQuotedPrefix() + qtIdent(GetName()); + } + else + { + // While creating trigger functions from the Event trigger, we may get the schema as null. + // Since, Event triggers are at database level. + + if (schema) + sql += schema->GetQuotedPrefix() + qtIdent(GetName()) + + wxT("(") + GetArgs() + wxT(")"); + else if(!function) + sql += qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()) + + wxT("(") + GetArgs() + wxT(")"); + else + sql += function->GetSchema()->GetQuotedPrefix() + qtIdent(GetName()) + + wxT("(") + GetArgs() + wxT(")"); + } + //sql += wxT("\n LANGUAGE ") + GetLanguage() + wxT(" "); + if (!isProcedure) + { + sql += wxT(" RETURNS "); + sql += cbReturntype->GetValue(); + } + + sql += wxT(" AS\n"); + + if (isProcedure) + { + sql += qtDbStringDollar(txtSqlBox->GetText()); + sql = sql.Trim(true); + sql += wxT("\nLANGUAGE ") + cbLanguage->GetValue(); + if (!sql.EndsWith(wxT(";"))) + sql += wxT(";\n"); + else + sql += wxT("\n"); + + + } + else + { + if (cbLanguage->GetValue().IsSameAs(wxT("C"), false)) + { + sql += qtDbString(txtObjectFile->GetValue()); + if (!txtLinkSymbol->GetValue().IsEmpty()) + sql += wxT(", ") + qtDbString(txtLinkSymbol->GetValue()); + } + else + { + if (connection->BackendMinimumVersion(7, 5)) + sql += qtDbStringDollar(txtSqlBox->GetText()); + else + sql += qtDbString(txtSqlBox->GetText()); + } + + sql += wxT("\nLANGUAGE ") + cbLanguage->GetValue(); + if (chkWindow->GetValue()) + sql += wxT(" WINDOW "); + else + sql += wxT(" "); + sql += cbVolatility->GetValue(); + if (connection->BackendMinimumVersion(9, 2)) + { + if (!chkLeakProof->GetValue()) + sql += wxT(" NOT"); + sql += wxT(" LEAKPROOF"); + } + if (chkStrict->GetValue()) + sql += wxT(" STRICT"); + if (chkSecureDefiner->GetValue()) + sql += wxT(" SECURITY DEFINER"); + if (connection->BackendMinimumVersion(10, 0)) + { + sql += wxT(" PARALLEL "); + sql += cbParallel->GetValue(); + } + // PostgreSQL 8.3+ cost/row estimations + if (connection->BackendMinimumVersion(8, 3)) + { + if (txtCost->GetValue().Length() > 0) + sql += wxT("\nCOST ") + txtCost->GetValue(); + + if (chkSetof->GetValue() && txtRows->GetValue().Length() > 0) + sql += wxT("\nROWS ") + txtRows->GetValue(); + } + + sql += wxT(";\n"); + } + } + + + if (function ) + { + if (schema) + name = schema->GetQuotedPrefix() + qtIdent(name) + wxT("(") + GetArgs(false, true) + wxT(")"); + // Event triggers do not have it's schema definition. Hence, getting the schema from the trigger function. + else + name = function->GetSchema()->GetQuotedPrefix() + qtIdent(name) + + wxT("(") + GetArgs(false, true) + wxT(")"); + + AppendOwnerChange(sql, objType + name); + AppendSchemaChange(sql, objType + name); + } + //else if (function && isProcedure) + //{ + // name = schema->GetQuotedPrefix() + qtIdent(name); + // AppendOwnerChange(sql, wxT("PROCEDURE ") + name); + // AppendSchemaChange(sql, wxT("PROCEDURE ") + name); + //} + + else + { + name = name + wxT("(") + GetArgs(false, true) + wxT(")"); + + if (cbOwner->GetCurrentSelection() > 0) + AppendOwnerNew(sql, wxT("FUNCTION ") + name); + } + + if (false) + sql += GetGrant(wxT("X"), wxT("PROCEDURE ") + name); + else + { + wxArrayString vars; + size_t index; + if (isProcedure) sql += GetGrant(wxT("X"), objType + name); + + if (function) + { + for (index = 0 ; index < function->GetConfigList().GetCount() ; index++) + vars.Add(function->GetConfigList().Item(index)); + } + + int cnt = lstVariables->GetItemCount(); + int pos; + + // check for changed or added vars + for (pos = 0 ; pos < cnt ; pos++) + { + wxString newVar = lstVariables->GetText(pos); + wxString newVal = lstVariables->GetText(pos, 1); + + wxString oldVal; + + for (index = 0 ; index < vars.GetCount() ; index++) + { + wxString var = vars.Item(index); + if (var.BeforeFirst('=').IsSameAs(newVar, false)) + { + oldVal = var.Mid(newVar.Length() + 1); + vars.RemoveAt(index); + break; + } + } + + // Reset the vars if they've changed, or the function definition has + // changed, which will remove them all :-( + if ((oldVal != newVal) || didChange) + { + if (newVar != wxT("search_path") && newVar != wxT("temp_tablespaces")) + sql += wxT("ALTER ")+ objType + name + + wxT("\n SET ") + newVar + + wxT("='") + newVal + + wxT("';\n"); + else + sql += wxT("ALTER ")+ objType + name + + wxT("\n SET ") + newVar + + wxT("=") + newVal + + wxT(";\n"); + } + } + + // check for removed vars + for (pos = 0 ; pos < (int)vars.GetCount() ; pos++) + { + sql += wxT("ALTER ")+ objType + name + + wxT("\n RESET ") + vars.Item(pos).BeforeFirst('=') + + wxT(";\n"); + } + + sql += GetGrant(wxT("X"), objType + name); + } + + if (isProcedure) + AppendComment(sql, wxT("PROCEDURE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), function); + else + { + AppendComment(sql, wxT("FUNCTION ") + name, function); + + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + sql += seclabelPage->GetSqlForSecLabels(wxT("FUNCTION"), name); + } + + return sql; +} + + +void dlgFunction::OnChangeWindow(wxCommandEvent &ev) +{ + CheckChange(); +} + + +void dlgFunction::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} diff --git a/dlg/dlgGroup.cpp b/dlg/dlgGroup.cpp new file mode 100644 index 0000000..75021c2 --- /dev/null +++ b/dlg/dlgGroup.cpp @@ -0,0 +1,221 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgGroup.cpp - PostgreSQL Group Property +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "utils/misc.h" +#include "dlg/dlgGroup.h" +#include "schema/pgGroup.h" + + +// pointer to controls +#define txtID CTRL_TEXT("txtID") + +#define lbUsersNotIn CTRL_LISTBOX("lbUsersNotIn") +#define lbUsersIn CTRL_LISTBOX("lbUsersIn") +#define btnAddUser CTRL_BUTTON("btnAddUser") +#define btnDelUser CTRL_BUTTON("btnDelUser") + + +dlgProperty *pgGroupFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgGroup(this, frame, (pgGroup *)node); +} + + + +BEGIN_EVENT_TABLE(dlgGroup, dlgProperty) + EVT_LISTBOX_DCLICK(XRCID("lbUsersNotIn"), dlgGroup::OnUserAdd) + EVT_LISTBOX_DCLICK(XRCID("lbUsersIn"), dlgGroup::OnUserRemove) + EVT_BUTTON(XRCID("btnAddUser"), dlgGroup::OnUserAdd) + EVT_BUTTON(XRCID("btnDelUser"), dlgGroup::OnUserRemove) +END_EVENT_TABLE(); + + + +dlgGroup::dlgGroup(pgaFactory *f, frmMain *frame, pgGroup *node) + : dlgProperty(f, frame, wxT("dlgGroup")) +{ + group = node; +} + + +pgObject *dlgGroup::GetObject() +{ + return group; +} + + +int dlgGroup::Go(bool modal) +{ + pgSet *set = connection->ExecuteSet(wxT("SELECT usename FROM pg_user")); + if (set) + { + while (!set->Eof()) + { + wxString userName = set->GetVal(wxT("usename")); + + if (group && group->GetUsersIn().Index(userName) >= 0) + lbUsersIn->Append(userName); + else + lbUsersNotIn->Append(userName); + + set->MoveNext(); + } + delete set; + } + + if (group) + { + // Edit Mode + readOnly = !group->GetServer()->GetSuperUser(); + + txtID->SetValue(NumToStr(group->GetGroupId())); + if (!connection->BackendMinimumVersion(7, 4)) + txtName->Disable(); + txtID->Disable(); + if (readOnly) + { + btnAddUser->Disable(); + btnDelUser->Disable(); + } + } + else + { + txtID->SetValidator(numericValidator); + } + + return dlgProperty::Go(modal); +} + + +void dlgGroup::CheckChange() +{ + if (group) + { + EnableOK(!GetSql().IsEmpty()); + } + else + { + wxString name = GetName(); + + bool enable = true; + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + + EnableOK(enable); + } +} + + +void dlgGroup::OnUserAdd(wxCommandEvent &ev) +{ + if (!readOnly) + { + int pos = lbUsersNotIn->GetSelection(); + if (pos >= 0) + { + lbUsersIn->Append(lbUsersNotIn->GetString(pos)); + lbUsersNotIn->Delete(pos); + } + CheckChange(); + } +} + + +void dlgGroup::OnUserRemove(wxCommandEvent &ev) +{ + if (!readOnly) + { + int pos = lbUsersIn->GetSelection(); + if (pos >= 0) + { + lbUsersNotIn->Append(lbUsersIn->GetString(pos)); + lbUsersIn->Delete(pos); + } + CheckChange(); + } +} + + +pgObject *dlgGroup::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + pgObject *obj = groupFactory.CreateObjects(collection, 0, wxT("\n WHERE groname=") + qtDbString(name)); + return obj; +} + + +wxString dlgGroup::GetSql() +{ + wxString sql; + wxString name = GetName(); + int cnt, pos; + + if (group) + { + // Edit Mode + + AppendNameChange(sql); + + cnt = lbUsersIn->GetCount(); + wxArrayString tmpUsers = group->GetUsersIn(); + + // check for added users + for (pos = 0 ; pos < cnt ; pos++) + { + wxString userName = lbUsersIn->GetString(pos); + + int index = tmpUsers.Index(userName); + if (index >= 0) + tmpUsers.RemoveAt(index); + else + sql += wxT("ALTER GROUP ") + qtIdent(name) + + wxT("\n ADD USER ") + qtIdent(userName) + wxT(";\n"); + } + + // check for removed users + for (pos = 0 ; pos < (int)tmpUsers.GetCount() ; pos++) + { + sql += wxT("ALTER GROUP ") + qtIdent(name) + + wxT("\n DROP USER ") + qtIdent(tmpUsers.Item(pos)) + wxT(";\n"); + } + } + else + { + // Create Mode + wxString name = GetName(); + + long id = StrToLong(txtID->GetValue()); + + sql = wxT( + "CREATE GROUP ") + qtIdent(name); + if (id) + sql += wxT("\n WITH SYSID ") + NumToStr(id); + cnt = lbUsersIn->GetCount(); + if (cnt) + sql += wxT("\n USER "); + for (pos = 0 ; pos < cnt ; pos++) + { + if (pos) + sql += wxT(", "); + sql += qtIdent(lbUsersIn->GetString(pos)); + } + sql += wxT(";\n"); + + } + return sql; +} + diff --git a/dlg/dlgHbaConfig.cpp b/dlg/dlgHbaConfig.cpp new file mode 100644 index 0000000..47365da --- /dev/null +++ b/dlg/dlgHbaConfig.cpp @@ -0,0 +1,436 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgHbaConfig.cpp - Configure setting +// +////////////////////////////////////////////////////////////////////////// + + + +// App headers +#include "pgAdmin3.h" + +#include "dlg/dlgHbaConfig.h" +#include "db/pgConn.h" +#include "db/pgSet.h" + +// Icons +#include "images/property.pngc" + + + + + +BEGIN_EVENT_TABLE(dlgHbaConfig, DialogWithHelp) + EVT_BUTTON (wxID_OK, dlgHbaConfig::OnOK) + EVT_BUTTON (wxID_CANCEL, dlgHbaConfig::OnCancel) + EVT_BUTTON(wxID_REFRESH, dlgHbaConfig::OnAddValue) + EVT_CHECKBOX(XRCID("chkEnabled"), dlgHbaConfig::OnChange) + EVT_COMBOBOX(XRCID("cbType"), dlgHbaConfig::OnChange) + EVT_TEXT(XRCID("cbDatabase"), dlgHbaConfig::OnChange) + EVT_TEXT(XRCID("cbUser"), dlgHbaConfig::OnChange) + EVT_COMBOBOX(XRCID("cbDatabase"), dlgHbaConfig::OnAddDatabase) + EVT_COMBOBOX(XRCID("cbUser"), dlgHbaConfig::OnAddUser) + EVT_COMBOBOX(XRCID("cbMethod"), dlgHbaConfig::OnChange) + EVT_TEXT(XRCID("txtIPaddress"), dlgHbaConfig::OnChange) + EVT_TEXT(XRCID("txtOption"), dlgHbaConfig::OnChange) +END_EVENT_TABLE() + + +#define chkEnabled CTRL_CHECKBOX("chkEnabled") +#define cbType CTRL_COMBOBOX("cbType") +#define cbDatabase CTRL_COMBOBOX("cbDatabase") +#define cbUser CTRL_COMBOBOX("cbUser") +#define cbMethod CTRL_COMBOBOX("cbMethod") +#define txtIPaddress CTRL_TEXT("txtIPaddress") +#define txtOption CTRL_TEXT("txtOption") +#define stIPaddress CTRL_STATIC("stIPaddress") +#define stOption CTRL_STATIC("stOption") + + +dlgHbaConfig::dlgHbaConfig(pgFrame *parent, pgHbaConfigLine *_line, pgConn *_conn) : + DialogWithHelp((frmMain *)parent) +{ + SetFont(settings->GetSystemFont()); + LoadResource((wxWindow *)parent, wxT("dlgHbaConfig")); + + conn = _conn; + + userAdding = databaseAdding = false; + + // Icon + SetIcon(*property_png_ico); + RestorePosition(); + + line = _line; + + cbType->Append(wxT("local")); + cbType->Append(wxT("host")); + cbType->Append(wxT("hostssl")); + cbType->Append(wxT("hostnossl")); + + cbDatabase->Append(wxT("all")); + cbDatabase->Append(wxT("sameuser")); + cbDatabase->Append(wxT("@")); + if (conn) + { + // role is supported from 8.1 + if (conn->BackendMinimumVersion(8, 1)) + cbDatabase->Append(wxT("samerole")); + else + cbDatabase->Append(wxT("samegroup")); + + // replication is supported from 9.0 + if (conn->BackendMinimumVersion(9, 0)) + cbDatabase->Append(wxT("replication")); + } + else + { + cbDatabase->Append(wxT("samegroup")); + cbDatabase->Append(wxT("samerole")); + cbDatabase->Append(wxT("replication")); + } + + cbUser->Append(wxT("all")); + + cbMethod->Append(wxT("trust")); + cbMethod->Append(wxT("reject")); + cbMethod->Append(wxT("md5")); + cbMethod->Append(wxT("password")); + cbMethod->Append(wxT("krb4")); + cbMethod->Append(wxT("krb5")); + cbMethod->Append(wxT("ident")); + cbMethod->Append(wxT("pam")); + + if (conn) + { + // LDAP is supported from 8.2 + if (conn->BackendMinimumVersion(8, 2)) + cbMethod->Append(wxT("ldap")); + + // GSS/SSPI are supported from 8.3 + if (conn->BackendMinimumVersion(8, 3)) + { + cbMethod->Append(wxT("gss")); + cbMethod->Append(wxT("sspi")); + } + + // CERT is supported from 8.4 + // but crypt is no longer supported in 8.4 + if (conn->BackendMinimumVersion(8, 4)) + { + cbMethod->Append(wxT("cert")); + } + else + { + cbMethod->Append(wxT("crypt")); + } + + // Radius is supported from 9.0 + if (conn->BackendMinimumVersion(9, 0)) + { + cbMethod->Append(wxT("radius")); + } + + // Peer is supported from 9.1 + if (conn->BackendMinimumVersion(9, 1)) + { + cbMethod->Append(wxT("peer")); + } + } + else + { + // Add all version-dependent methods if we don't know what version we have. + cbMethod->Append(wxT("ldap")); + cbMethod->Append(wxT("gss")); + cbMethod->Append(wxT("sspi")); + cbMethod->Append(wxT("cert")); + cbMethod->Append(wxT("crypt")); + cbMethod->Append(wxT("radius")); + cbMethod->Append(wxT("peer")); + } + + if (conn) + { + pgSet *set = conn->ExecuteSet(wxT("SELECT datname FROM pg_database")); + if (set) + { + while (!set->Eof()) + { + cbDatabase->Append(set->GetVal(0)); + set->MoveNext(); + } + delete set; + } + + wxString sql = wxT("SELECT usename FROM pg_user\n") + wxT("UNION\n") + wxT("SELECT 'group ' || groname FROM pg_group"); + set = conn->ExecuteSet(sql); + if (set) + { + while (!set->Eof()) + { + cbUser->Append(set->GetVal(0)); + set->MoveNext(); + } + delete set; + } + } + + // Setup the default values + + chkEnabled->SetValue(!line->isComment); + if(line->connectType != pgHbaConfigLine::PGC_INVALIDCONF) + { + database = line->database; + user = line->user; + + cbType->SetSelection(line->connectType); + cbMethod->SetSelection(line->method); + cbDatabase->SetValue(database); + cbUser->SetValue(user); + txtIPaddress->SetValue(line->ipaddress); + txtOption->SetValue(line->option); + } + wxCommandEvent noEvent; + OnChange(noEvent); +} + + +dlgHbaConfig::~dlgHbaConfig() +{ + SavePosition(); +} + + +wxString dlgHbaConfig::GetHelpPage() const +{ + return wxT("pg/client-authentication"); + // auth-methods#auth-trust #auth-password #kerberos-auth #auth-ident #auth-pam +} + + +void dlgHbaConfig::OnAddDatabase(wxCommandEvent &ev) +{ + int sel = cbDatabase->GetCurrentSelection(); + if (sel < 3) + return; + + wxString newDatabase; + if (database == wxT("all") || database == wxT("sameuser") || database == wxT("samegroup") + || database == wxT("samerole") || database == wxT("replication") || database.Left(1) == wxT("@")) + database = wxEmptyString; + + if (sel == 3) // file + newDatabase = wxT("@"); + else + { + wxString str = cbDatabase->GetString(sel); + if (str.Find(' ') >= 0) + str = wxT("\"") + str + wxT("\""); + + int pos = database.Find(str); + if (pos >= 0) + { + if (pos > 0 && database.Mid(pos - 1, 1) != wxT(",")) + pos = -1; + if (database.Length() > str.Length() + pos && database.Mid(pos + str.Length(), 1) != wxT(",")) + pos = -1; + } + if (pos < 0) + { + if (!database.IsEmpty()) + database += wxT(","); + + newDatabase = database + str; + } + else + newDatabase = database; + } + + wxTheApp->Yield(true); + + database = newDatabase; + databaseAdding = true; + wxCommandEvent buttonEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_REFRESH); + AddPendingEvent(buttonEvent); +} + + +void dlgHbaConfig::OnAddUser(wxCommandEvent &ev) +{ + int sel = cbUser->GetCurrentSelection(); + if (sel < 1) + return; + + wxString newUser; + + wxString str = cbUser->GetString(sel); + if (str.Left(6) == wxT("group ")) + { + if (str.Find(' ', true) > 5) + str = wxT("+\"") + str.Mid(6) + wxT("\""); + else + str = wxT("+") + str.Mid(6); + } + else + { + if (str.Find(' ') >= 0) + str = wxT("\"") + str + wxT("\""); + } + + if (user == wxT("all")) + newUser = str; + else + { + int pos = user.Find(str); + if (pos >= 0) + { + if (pos > 0 && user.Mid(pos - 1, 1) != wxT(",")) + pos = -1; + if (user.Length() > str.Length() + pos && user.Mid(pos + str.Length(), 1) != wxT(",")) + pos = -1; + } + + if (pos < 0) + { + if (!user.IsEmpty()) + user += wxT(","); + newUser = user + str; + } + else + newUser = user; + } + + wxTheApp->Yield(true); + + user = newUser; + userAdding = true; + wxCommandEvent buttonEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_REFRESH); + AddPendingEvent(buttonEvent); +} + + + +void dlgHbaConfig::OnAddValue(wxCommandEvent &ev) +{ + if (databaseAdding) + { + cbDatabase->SetSelection(-1); + cbDatabase->SetValue(database); + cbDatabase->SetInsertionPointEnd(); + databaseAdding = false; + } + + if (userAdding) + { + cbUser->SetSelection(-1); + cbUser->SetValue(user); + cbUser->SetInsertionPointEnd(); + userAdding = false; + } + OnChange(ev); +} + + +void dlgHbaConfig::OnChange(wxCommandEvent &ev) +{ + if (databaseAdding || userAdding) + return; + + database = cbDatabase->GetValue(); + user = cbUser->GetValue(); + + bool needIp = (cbType->GetCurrentSelection() != 0); + + stIPaddress->Enable(needIp); + txtIPaddress->Enable(needIp); + + bool needOption = false; + // IDENT and LDAP always take an option + if (cbMethod->GetCurrentSelection() == pgHbaConfigLine::PGC_IDENT || + cbMethod->GetCurrentSelection() == pgHbaConfigLine::PGC_LDAP) + { + needOption = true; + } + else if (cbMethod->GetCurrentSelection() == pgHbaConfigLine::PGC_GSS || + cbMethod->GetCurrentSelection() == pgHbaConfigLine::PGC_SSPI || + cbMethod->GetCurrentSelection() == pgHbaConfigLine::PGC_KRB5 || + cbMethod->GetCurrentSelection() == pgHbaConfigLine::PGC_PAM || + cbMethod->GetCurrentSelection() == pgHbaConfigLine::PGC_CERT) + { + // GSS/SSPI/KRB5/PAM/CERT take options from 8.4 onwards. If we don't know the version + // then allow the option to be specified. + if (conn) + { + if (conn->BackendMinimumVersion(8, 4)) + needOption = true; + } + else + needOption = true; + } + + // On 8.4 and above, any hostssl lines can take an option + if (cbType->GetCurrentSelection() == pgHbaConfigLine::PGC_HOSTSSL) + { + if (conn) + { + if (conn->BackendMinimumVersion(8, 4)) + needOption = true; + } + else + needOption = true; + } + + stOption->Enable(needOption); + txtOption->Enable(needOption); + + bool ipValid = !chkEnabled->GetValue() || !needIp; + if (!ipValid) + { + // we should check for validity of txtIPaddress->GetValue() here + ipValid = true; + } + btnOK->Enable(cbType->GetCurrentSelection() >= 0 && !database.IsEmpty() && !user.IsEmpty() && + cbMethod->GetCurrentSelection() >= 0 && ipValid); +} + + +void dlgHbaConfig::OnOK(wxCommandEvent &ev) +{ +#ifdef __WXGTK__ + if (!btnOK->IsEnabled()) + return; +#endif + line->isComment = !chkEnabled->GetValue(); + line->connectType = (pgHbaConfigLine::pgHbaConnectType)cbType->GetCurrentSelection(); + line->database = database; + line->user = user; + line->ipaddress = txtIPaddress->GetValue(); + line->method = (pgHbaConfigLine::pgHbaMethod)cbMethod->GetCurrentSelection(); + if (txtOption->IsEnabled()) + line->option = txtOption->GetValue(); + else + line->option = wxEmptyString; + line->changed = true; + + EndModal(wxID_OK); +} + + +void dlgHbaConfig::OnCancel(wxCommandEvent &ev) +{ + EndModal(wxID_CANCEL); +} + + +int dlgHbaConfig::Go() +{ + // Set focus on the Password textbox and show modal + return ShowModal(); +} diff --git a/dlg/dlgIndex.cpp b/dlg/dlgIndex.cpp new file mode 100644 index 0000000..48cce98 --- /dev/null +++ b/dlg/dlgIndex.cpp @@ -0,0 +1,663 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgIndex.cpp - PostgreSQL Index Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "frm/frmMain.h" +#include "dlg/dlgIndex.h" +#include "schema/pgIndex.h" +#include "schema/pgColumn.h" +#include "schema/pgTable.h" + + +#define cbTablespace CTRL_COMBOBOX("cbTablespace") +#define cbType CTRL_COMBOBOX("cbType") +#define chkUnique CTRL_CHECKBOX("chkUnique") +#define chkClustered CTRL_CHECKBOX("chkClustered") +#define chkConcurrent CTRL_CHECKBOX("chkConcurrent") +#define txtWhere CTRL_TEXT("txtWhere") +#define txtFillFactor CTRL_TEXT("txtFillFactor") +#define cbOpClass CTRL_COMBOBOX("cbOpClass") +#define chkDesc CTRL_CHECKBOX("chkDesc") +#define rdbNullsFirst CTRL_RADIOBUTTON("rdbNullsFirst") +#define rdbNullsLast CTRL_RADIOBUTTON("rdbNullsLast") +#define cbCollation CTRL_COMBOBOX("cbCollation") + + +BEGIN_EVENT_TABLE(dlgIndexBase, dlgCollistProperty) + EVT_TEXT(XRCID("cbTablespace"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbTablespace"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtFillFactor"), dlgProperty::OnChange) + EVT_LIST_ITEM_SELECTED(XRCID("lstColumns"), dlgIndexBase::OnSelectListCol) + EVT_COMBOBOX(XRCID("cbColumns"), dlgIndexBase::OnSelectComboCol) +END_EVENT_TABLE(); + + +dlgProperty *pgIndexFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgIndex(this, frame, (pgIndex *)node, (pgTable *)parent); +} + + +dlgIndexBase::dlgIndexBase(pgaFactory *f, frmMain *frame, const wxString &resName, pgIndexBase *node, pgTable *parentNode) + : dlgCollistProperty(f, frame, resName, parentNode) +{ + index = node; + wxASSERT(!table || table->GetMetaType() == PGM_TABLE || table->GetMetaType() == GP_PARTITION); +} + + +dlgIndexBase::dlgIndexBase(pgaFactory *f, frmMain *frame, const wxString &resName, ctlListView *colList) + : dlgCollistProperty(f, frame, resName, colList) +{ + index = 0; +} + + +pgObject *dlgIndexBase::GetObject() +{ + return index; +} + + +int dlgIndexBase::Go(bool modal) +{ + + if (index) + { + // edit mode + txtName->Enable(connection->BackendMinimumVersion(9, 2)); + cbColumns->Disable(); + + if (txtFillFactor) + { + txtFillFactor->SetValue(index->GetFillFactor()); + } + } + else + { + // create mode + } + + if (txtFillFactor) + { + txtFillFactor->SetValidator(numericValidator); + if (connection->BackendMinimumVersion(8, 2)) + txtFillFactor->Enable(); + else + txtFillFactor->Disable(); + } + + btnAddCol->Disable(); + btnRemoveCol->Disable(); + + return dlgCollistProperty::Go(modal); +} + +void dlgIndexBase::OnSelectListCol(wxListEvent &ev) +{ + OnSelectCol(); +} + +void dlgIndexBase::OnSelectComboCol(wxCommandEvent &ev) +{ + if (cbType) + { + wxString method = wxEmptyString; + + if (cbType->GetValue().Length() == 0) + { + method = cbType->GetStringKey(1); + } + else + { + method = cbType->GetStringKey(cbType->GetCurrentSelection()); + } + + cbOpClass->Clear(); + + wxString sql = wxT("SELECT opcname FROM pg_opclass ") + wxT("WHERE opcmethod=") + method + + wxT(" AND NOT opcdefault") + wxT(" ORDER BY 1"); + pgSet *set = connection->ExecuteSet(sql); + if (set) + { + while (!set->Eof()) + { + cbOpClass->Append(set->GetVal(0)); + set->MoveNext(); + } + delete set; + } + } + + OnSelectCol(); +} + +void dlgIndexBase::OnSelectCol() +{ + // Can't change the columns on an existing index. + if (index) + return; + + if (lstColumns->GetSelection() != wxNOT_FOUND) + btnRemoveCol->Enable(true); + else + btnRemoveCol->Enable(false); + + if (cbColumns->GetSelection() != wxNOT_FOUND && !cbColumns->GetValue().IsEmpty()) + btnAddCol->Enable(true); + else + btnAddCol->Enable(false); +} + + +void dlgIndexBase::CheckChange() +{ + if (index) + { + EnableOK(txtName->GetValue() != index->GetName() || + txtComment->GetValue() != index->GetComment() || + cbTablespace->GetOIDKey() != index->GetTablespaceOid() || + txtFillFactor->GetValue() != index->GetFillFactor()); + } + else + { + bool enable = true; + txtComment->Enable(!GetName().IsEmpty()); + CheckValid(enable, lstColumns->GetItemCount() > 0, _("Please specify columns.")); + EnableOK(enable); + } +} + + +BEGIN_EVENT_TABLE(dlgIndex, dlgIndexBase) + EVT_BUTTON(XRCID("btnAddCol"), dlgIndex::OnAddCol) + EVT_BUTTON(XRCID("btnRemoveCol"), dlgIndex::OnRemoveCol) + EVT_CHECKBOX(XRCID("chkClustered"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkDesc"), dlgIndex::OnDescChange) +#ifdef __WXMAC__ + EVT_SIZE( dlgIndex::OnChangeSize) +#endif + EVT_COMBOBOX(XRCID("cbType"), dlgIndex::OnSelectType) +END_EVENT_TABLE(); + + +dlgIndex::dlgIndex(pgaFactory *f, frmMain *frame, pgIndex *index, pgTable *parentNode) + : dlgIndexBase(f, frame, wxT("dlgIndex"), index, parentNode) +{ + lstColumns->AddColumn(_("Column name"), 90); + lstColumns->AddColumn(_("Order"), 40); + lstColumns->AddColumn(_("NULLs order"), 50); + lstColumns->AddColumn(_("Op. class"), 40); + lstColumns->AddColumn(_("Collation"), 40); +} + + +void dlgIndex::CheckChange() +{ + bool fill = false; + + txtComment->Enable(!txtName->GetValue().IsEmpty()); + chkClustered->Enable(!txtName->GetValue().IsEmpty()); + + if (index) + { + if (txtFillFactor) + { + fill = txtFillFactor->GetValue() != index->GetFillFactor() && !txtFillFactor->GetValue().IsEmpty(); + } + + EnableOK(fill || + txtComment->GetValue() != index->GetComment() || + chkClustered->GetValue() != index->GetIsClustered() || + cbTablespace->GetOIDKey() != index->GetTablespaceOid() || + (txtName->GetValue() != index->GetName() && + txtName->GetValue().Length() != 0)); + } + else + { + wxString name = GetName(); + + bool enable = true; + CheckValid(enable, !name.IsEmpty() || (name.IsEmpty() && this->database->BackendMinimumVersion(9, 0)), _("Please specify name.")); + CheckValid(enable, lstColumns->GetItemCount() > 0, _("Please specify columns.")); + EnableOK(enable); + } +} + +void dlgIndex::OnSelectType(wxCommandEvent &ev) +{ + // The column options available change depending on the + // index type. We need to clear the column list, and + // setup some of the other controls accordingly. + + wxString newType = cbType->GetValue(); + bool changingDefault = false; + + // Detect if we're changing between default and btree (which are the same) to + // avoid annoying the user needlessly. + if ((m_previousType == wxEmptyString && cbType->GetValue() == wxT("btree")) || + (m_previousType == wxT("btree") && cbType->GetValue() == wxEmptyString)) + changingDefault = true; + + if (lstColumns->GetItemCount() > 0 && !changingDefault) + { + if (wxMessageBox(_("Changing the index type will cause the column list to be cleared. Do you wish to continue?"), _("Change index type?"), wxYES_NO) != wxYES) + { + cbType->SetValue(m_previousType); + return; + } + + // Move all the columns back to the combo + for (int pos = lstColumns->GetItemCount(); pos > 0; pos--) + { + wxString colName = lstColumns->GetItemText(pos - 1); + + lstColumns->DeleteItem(pos - 1); + cbColumns->Append(colName); + } + } + + if (newType == wxT("btree") || newType == wxEmptyString) + { + cbOpClass->Enable(true); + chkDesc->Enable(true); + rdbNullsFirst->Enable(true); + rdbNullsLast->Enable(true); + } + else + { + cbOpClass->Enable(false); + chkDesc->Enable(false); + rdbNullsFirst->Enable(false); + rdbNullsLast->Enable(false); + } + + // Make a note of the type so we can compare if it changes again. + m_previousType = cbType->GetValue(); +} + + +wxString dlgIndex::GetColumns() +{ + wxString sql; + + int pos; + // iterate cols + for (pos = 0 ; pos < lstColumns->GetItemCount() ; pos++) + { + if (pos) + sql += wxT(", "); + + sql += qtIdent(lstColumns->GetItemText(pos)); + + if (this->database->BackendMinimumVersion(9, 1)) + { + wxString collation = lstColumns->GetText(pos, 4); + if (!collation.IsEmpty() && collation != wxT("pg_catalog.\"default\"")) + sql += wxT(" COLLATE ") + collation; + } + + wxString opclass = lstColumns->GetText(pos, 3); + if (!opclass.IsEmpty()) + sql += wxT(" ") + opclass; + + if (this->database->BackendMinimumVersion(8, 3)) + { + wxString order = lstColumns->GetText(pos, 1); + if (!order.IsEmpty()) + sql += wxT(" ") + order; + + wxString nullsOrder = lstColumns->GetText(pos, 2); + if (!nullsOrder.IsEmpty()) + sql += wxT(" NULLS ") + nullsOrder; + } + } + return sql; +} + + +int dlgIndex::Go(bool modal) +{ + if (!connection->BackendMinimumVersion(7, 4)) + chkClustered->Disable(); + + if (index) + { + // edit mode: view only + + // We only display the column options (ASC/DESC, NULLS FIRST/LAST) + // on PostgreSQL 8.3+, for btree indexes. + wxArrayString colsArr = index->GetColumnList(); + wxArrayString collationsArray = index->GetCollationsArray(); + wxString colDef, descDef, nullsDef, opclassDef; + if (this->database->BackendMinimumVersion(8, 3) && index->GetIndexType() == wxT("btree")) + { + for (unsigned int colIdx = 0, colsCount = colsArr.Count(); colIdx < colsCount; colIdx++) + { + colDef = colsArr.Item(colIdx); + descDef = index->GetOrdersArray().Item(colIdx); + nullsDef = index->GetNullsArray().Item(colIdx); + opclassDef = index->GetOpClassesArray().Item(colIdx); + + lstColumns->InsertItem(colIdx, colDef, columnFactory.GetIconId()); + lstColumns->SetItem(colIdx, 1, descDef); + lstColumns->SetItem(colIdx, 2, nullsDef); + lstColumns->SetItem(colIdx, 3, opclassDef); + if (colIdx < collationsArray.Count()) + lstColumns->SetItem(colIdx, 4, collationsArray.Item(colIdx)); + } + } + else + { + for (unsigned int colIdx = 0, colsCount = colsArr.Count(); colIdx < colsCount; colIdx++) + { + int pos = colDef.First(wxT(" ")); + if (pos > 0) + { + opclassDef = colDef.Mid(pos + 1); + colDef = colDef.Mid(0, pos); + } + else + opclassDef = wxEmptyString; + + lstColumns->InsertItem(colIdx, colsArr.Item(colIdx), columnFactory.GetIconId()); + lstColumns->SetItem(colIdx, 3, cbOpClass->GetValue()); + if (colIdx < collationsArray.Count()) + lstColumns->SetItem(colIdx, 4, collationsArray.Item(colIdx)); + } + } + + cbType->Append(index->GetIndexType()); + chkUnique->SetValue(index->GetIsUnique()); + chkClustered->SetValue(index->GetIsClustered()); + txtWhere->SetValue(index->GetConstraint()); + cbType->SetSelection(0); + cbType->Disable(); + txtWhere->Disable(); + chkUnique->Disable(); + chkConcurrent->Disable(); + PrepareTablespace(cbTablespace, index->GetTablespaceOid()); + cbOpClass->Disable(); + chkDesc->Disable(); + rdbNullsFirst->Disable(); + rdbNullsLast->Disable(); + cbCollation->Disable(); + lstColumns->Disable(); + } + else + { + // create mode + PrepareTablespace(cbTablespace); + cbType->Append(wxT("")); + pgSet *set = connection->ExecuteSet(wxT( + "SELECT oid, amname FROM pg_am")); + if (set) + { + while (!set->Eof()) + { + cbType->Append(set->GetVal(1), set->GetVal(0)); + set->MoveNext(); + } + delete set; + } + + if (connection->BackendMinimumVersion(9, 1)) + { + // fill collation combobox + cbCollation->Append(wxEmptyString); + set = connection->ExecuteSet( + wxT("SELECT nspname, collname\n") + wxT(" FROM pg_collation c, pg_namespace n\n") + wxT(" WHERE c.collnamespace=n.oid\n") + wxT(" ORDER BY nspname, collname")); + if (set) + { + while (!set->Eof()) + { + wxString name = qtIdent(set->GetVal(wxT("nspname"))) + wxT(".") + qtIdent(set->GetVal(wxT("collname"))); + cbCollation->Append(name); + set->MoveNext(); + } + delete set; + } + cbCollation->SetSelection(0); + } + else + cbCollation->Disable(); + + if (!this->database->BackendMinimumVersion(8, 2)) + chkConcurrent->Disable(); + + if (!this->database->BackendMinimumVersion(8, 3)) + { + chkDesc->Disable(); + rdbNullsFirst->Disable(); + rdbNullsLast->Disable(); + } + + // Add the default tablespace + cbTablespace->Insert(_(""), 0, (void *)0); + cbTablespace->SetSelection(0); + } + + // Reset the labels as the XRC defined values will have been localised :-( + rdbNullsFirst->SetLabel(wxT("FIRST")); + rdbNullsLast->SetLabel(wxT("LAST")); + + int returnCode = dlgIndexBase::Go(modal); + + if (index && connection->BackendMinimumVersion(8, 0)) + txtName->Enable(true); + + // This fixes a UI glitch on MacOS X + // Because of the new layout code, the Columns pane doesn't size itself properly + SetSize(GetSize().GetWidth() + 1, GetSize().GetHeight()); + SetSize(GetSize().GetWidth() - 1, GetSize().GetHeight()); + + return returnCode; +} + + +void dlgIndex::OnAddCol(wxCommandEvent &ev) +{ + wxString colName = cbColumns->GetValue(); + + if (!colName.IsEmpty()) + { + long colIndex = lstColumns->InsertItem(lstColumns->GetItemCount(), colName, columnFactory.GetIconId()); + + + if (this->database->BackendMinimumVersion(8, 3)) + { + if (chkDesc->GetValue()) + { + if (chkDesc->IsEnabled()) + lstColumns->SetItem(colIndex, 1, wxT("DESC")); + + + if (rdbNullsLast->GetValue()) + { + if (rdbNullsLast->IsEnabled()) + lstColumns->SetItem(colIndex, 2, wxT("LAST")); + } + else + { + if (rdbNullsLast->IsEnabled()) + lstColumns->SetItem(colIndex, 2, wxT("FIRST")); + } + } + else + { + if (chkDesc->IsEnabled()) + lstColumns->SetItem(colIndex, 1, wxT("ASC")); + + if (rdbNullsFirst->GetValue()) + { + if (rdbNullsFirst->IsEnabled()) + lstColumns->SetItem(colIndex, 2, wxT("FIRST")); + } + else + { + if (rdbNullsLast->IsEnabled()) + lstColumns->SetItem(colIndex, 2, wxT("LAST")); + } + } + + lstColumns->SetItem(colIndex, 3, cbOpClass->GetValue()); + lstColumns->SetItem(colIndex, 4, cbCollation->GetValue()); + } + + cbColumns->Delete(cbColumns->GetCurrentSelection()); + if (cbColumns->GetCount()) + cbColumns->SetSelection(0); + + CheckChange(); + if (!cbColumns->GetCount()) + btnAddCol->Disable(); + } +} + + +void dlgIndex::OnRemoveCol(wxCommandEvent &ev) +{ + long pos = lstColumns->GetSelection(); + if (pos >= 0) + { + wxString colName = lstColumns->GetItemText(pos); + + lstColumns->DeleteItem(pos); + cbColumns->Append(colName); + + CheckChange(); + btnRemoveCol->Disable(); + } +} + +#ifdef __WXMAC__ +void dlgIndex::OnChangeSize(wxSizeEvent &ev) +{ + lstColumns->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 700); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + +wxString dlgIndex::GetSql() +{ + wxString sql; + + if (table) + { + wxString name = GetName(); + if (!index) + { + sql = wxT("CREATE "); + if (chkUnique->GetValue()) + sql += wxT("UNIQUE "); + + sql += wxT("INDEX "); + + if (chkConcurrent->GetValue()) + sql += wxT("CONCURRENTLY "); + + sql += qtIdent(name); + + sql += wxT("\n ON ") + table->GetQuotedFullIdentifier(); + + if (cbType->GetCurrentSelection() > 0) + AppendIfFilled(sql, wxT(" USING "), cbType->GetValue()); + + sql += wxT(" (") + GetColumns() + + wxT(")"); + + if (txtFillFactor) + { + if (connection->BackendMinimumVersion(8, 2) && txtFillFactor->GetValue().Length() > 0) + sql += wxT("\n WITH (FILLFACTOR=") + txtFillFactor->GetValue() + wxT(")"); + } + + if (cbTablespace->GetOIDKey() > 0) + AppendIfFilled(sql, wxT("\n TABLESPACE "), qtIdent(cbTablespace->GetValue())); + + AppendIfFilled(sql, wxT(" WHERE "), txtWhere->GetValue()); + sql += wxT(";\n"); + } + else + { + if (connection->BackendMinimumVersion(8, 2) && txtFillFactor->GetValue().Length() > 0) + sql += wxT("ALTER INDEX ") + qtIdent(index->GetSchema()->GetName()) + wxT(".") + + qtIdent(index->GetName()) + wxT("\n SET (FILLFACTOR=") + + txtFillFactor->GetValue() + wxT(");\n"); + + if(connection->BackendMinimumVersion(8, 0)) + { + if (index->GetName() != txtName->GetValue() && + !txtName->GetValue().IsEmpty()) + sql += wxT("ALTER INDEX ") + qtIdent(index->GetSchema()->GetName()) + wxT(".") + + qtIdent(index->GetName()) + wxT("\n RENAME TO ") + + qtIdent(txtName->GetValue()) + wxT(";\n"); + + if (cbTablespace->GetOIDKey() != index->GetTablespaceOid()) + sql += wxT("ALTER INDEX ") + qtIdent(index->GetSchema()->GetName()) + wxT(".") + qtIdent(name) + + wxT("\n SET TABLESPACE ") + qtIdent(cbTablespace->GetValue()) + + wxT(";\n"); + } + } + if (connection->BackendMinimumVersion(7, 4) && chkClustered->IsEnabled()) + { + if (index && index->GetIsClustered() && !chkClustered->GetValue()) + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n SET WITHOUT CLUSTER;\n"); + else if (chkClustered->GetValue() && (!index || !index->GetIsClustered())) + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n CLUSTER ON ") + qtIdent(name) + wxT(";\n"); + } + + if (txtComment->IsEnabled()) + { + AppendComment(sql, wxT("INDEX"), table->GetSchema(), index); + } + } + return sql; +} + + +pgObject *dlgIndex::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + pgObject *obj = indexFactory.CreateObjects(collection, 0, wxT( + "\n AND cls.relname=") + qtDbString(name) + wxT( + "\n AND cls.relnamespace=") + table->GetSchema()->GetOidStr()); + return obj; +} + +void dlgIndex::OnDescChange(wxCommandEvent &ev) +{ + if (chkDesc->GetValue()) + { + rdbNullsFirst->SetValue(true); + } + else + { + rdbNullsLast->SetValue(true); + } +} diff --git a/dlg/dlgIndexConstraint.cpp b/dlg/dlgIndexConstraint.cpp new file mode 100644 index 0000000..27c19d7 --- /dev/null +++ b/dlg/dlgIndexConstraint.cpp @@ -0,0 +1,688 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgIndexConstraint.cpp - PostgreSQL IndexConstraint Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "frm/frmMain.h" +#include "dlg/dlgIndexConstraint.h" +#include "schema/pgIndex.h" +#include "schema/pgColumn.h" +#include "schema/pgTable.h" +#include "schema/pgIndexConstraint.h" + + +#define cbTablespace CTRL_COMBOBOX("cbTablespace") +#define cbIndex CTRL_COMBOBOX("cbIndex") +#define cbType CTRL_COMBOBOX("cbType") +#define txtFillFactor CTRL_TEXT("txtFillFactor") +#define txtWhere CTRL_TEXT("txtWhere") +#define chkDeferrable CTRL_CHECKBOX("chkDeferrable") +#define chkDeferred CTRL_CHECKBOX("chkDeferred") +#define cbOpClass CTRL_COMBOBOX("cbOpClass") +#define chkDesc CTRL_CHECKBOX("chkDesc") +#define rdbNullsFirst CTRL_RADIOBUTTON("rdbNullsFirst") +#define rdbNullsLast CTRL_RADIOBUTTON("rdbNullsLast") +#define cbOperator CTRL_COMBOBOX("cbOperator") + +BEGIN_EVENT_TABLE(dlgIndexConstraint, dlgIndexBase) + EVT_CHECKBOX(XRCID("chkDeferrable"), dlgProperty::OnChange) + EVT_BUTTON(XRCID("btnAddCol"), dlgIndexConstraint::OnAddCol) + EVT_BUTTON(XRCID("btnRemoveCol"), dlgIndexConstraint::OnRemoveCol) +#ifdef __WXMAC__ + EVT_SIZE( dlgIndexConstraint::OnChangeSize) +#endif + EVT_COMBOBOX(XRCID("cbIndex"), dlgIndexConstraint::OnChangeIndex) + EVT_COMBOBOX(XRCID("cbType"), dlgIndexConstraint::OnSelectType) + EVT_COMBOBOX(XRCID("cbColumns"), dlgIndexConstraint::OnSelectComboCol) +END_EVENT_TABLE(); + + +dlgIndexConstraint::dlgIndexConstraint(pgaFactory *f, frmMain *frame, const wxString &resName, pgIndexBase *index, pgTable *parentNode) + : dlgIndexBase(f, frame, resName, index, parentNode) +{ + lstColumns->AddColumn(_("Column name"), 90); + lstColumns->AddColumn(_("Order"), 40); + lstColumns->AddColumn(_("NULLs order"), 50); + lstColumns->AddColumn(_("Op. class"), 40); + lstColumns->AddColumn(_("Operator"), 40); +} + + +dlgIndexConstraint::dlgIndexConstraint(pgaFactory *f, frmMain *frame, const wxString &resName, ctlListView *colList) + : dlgIndexBase(f, frame, resName, colList) +{ + lstColumns->AddColumn(_("Column name"), 90); + lstColumns->AddColumn(_("Order"), 40); + lstColumns->AddColumn(_("NULLs order"), 50); + lstColumns->AddColumn(_("Op. class"), 40); + lstColumns->AddColumn(_("Operator"), 40); +} + + +wxString dlgIndexConstraint::GetColumns() +{ + wxString sql; + + int pos; + // iterate cols + for (pos = 0 ; pos < lstColumns->GetItemCount() ; pos++) + { + if (pos) + sql += wxT(", "); + + sql += qtIdent(lstColumns->GetItemText(pos)); + + wxString opclass = lstColumns->GetText(pos, 3); + if (!opclass.IsEmpty()) + sql += wxT(" ") + opclass; + + wxString order = lstColumns->GetText(pos, 1); + if (!order.IsEmpty()) + sql += wxT(" ") + order; + + wxString nullsOrder = lstColumns->GetText(pos, 2); + if (!nullsOrder.IsEmpty()) + sql += wxT(" NULLS ") + nullsOrder; + + wxString oper = lstColumns->GetText(pos, 4); + if (!oper.IsEmpty()) + sql += wxT(" WITH ") + oper; + } + return sql; +} + + +int dlgIndexConstraint::Go(bool modal) +{ + pgSet *set; + + PrepareTablespace(cbTablespace); + + if (wxString(factory->GetTypeName()).Upper() == wxT("EXCLUDE")) + { + cbIndex->Disable(); + } + else + { + cbIndex->Enable(connection->BackendMinimumVersion(9, 1)); + cbType->Disable(); + txtWhere->Disable(); + cbOpClass->Disable(); + chkDesc->Disable(); + rdbNullsFirst->Disable(); + rdbNullsLast->Disable(); + cbOperator->Disable(); + } + + if (index) + { + pgIndexConstraint *idc = (pgIndexConstraint *)index; + + // We only display the column options (ASC/DESC, NULLS FIRST/LAST) + // on exclude constraints with btree + wxArrayString colsArr = index->GetColumnList(); + wxString colDef, colRest, descDef, nullsDef, opclassDef, withDef; + const wxString firstOrder = wxT(" NULLS FIRST"), lastOrder = wxT(" NULLS LAST"); + const wxString descOrder = wxT(" DESC"); + if (wxString(factory->GetTypeName()).Upper() == wxT("EXCLUDE") && index->GetIndexType() == wxT("btree")) + { + for (int colIdx = 0, colsCount = colsArr.Count(); colIdx < colsCount; colIdx++) + { + colDef = colsArr.Item(colIdx); + + int withStartPoint = colDef.Find(wxT(" WITH ")); + if (withStartPoint > 0) + { + withDef = colDef.Mid(withStartPoint + 6, colDef.Length() - withStartPoint - 6); + colDef = colDef.Mid(0, withStartPoint); + } + else + withDef = wxT(""); + + if (colDef.EndsWith(firstOrder.GetData(), &colRest)) + { + colDef = colRest; + nullsDef = wxT("FIRST"); + } + else if (colDef.EndsWith(lastOrder.GetData(), &colRest)) + { + colDef = colRest; + nullsDef = wxT("LAST"); + } + else + nullsDef = wxT(""); + + if (colDef.EndsWith(descOrder.GetData(), &colRest)) + { + colDef = colRest; + descDef = wxT("DESC"); + if (nullsDef.IsEmpty()) + nullsDef = wxT("FIRST"); + } + else + { + descDef = wxT("ASC"); + if (nullsDef.IsEmpty()) + nullsDef = wxT("LAST"); + } + + int pos = colDef.First(wxT(" ")); + if (pos > 0) + { + opclassDef = colDef.Mid(pos + 1); + colDef = colDef.Mid(0, pos); + } + else + opclassDef = wxEmptyString; + + lstColumns->InsertItem(colIdx, colDef, columnFactory.GetIconId()); + lstColumns->SetItem(colIdx, 1, descDef); + lstColumns->SetItem(colIdx, 2, nullsDef); + lstColumns->SetItem(colIdx, 3, opclassDef); + lstColumns->SetItem(colIdx, 4, withDef); + } + } + else + { + for (int colIdx = 0, colsCount = colsArr.Count(); colIdx < colsCount; colIdx++) + { + colDef = colsArr.Item(colIdx); + + int withStartPoint = colDef.Find(wxT(" WITH ")); + if (withStartPoint > 0) + { + withDef = colDef.Mid(withStartPoint + 6, colDef.Length() - withStartPoint - 6); + colDef = colDef.Mid(0, withStartPoint); + } + else + withDef = wxT(""); + + int pos = colDef.First(wxT(" ")); + if (pos > 0) + { + opclassDef = colDef.Mid(pos + 1); + colDef = colDef.Mid(0, pos); + } + else + opclassDef = wxEmptyString; + + lstColumns->InsertItem(colIdx, colDef, columnFactory.GetIconId()); + lstColumns->SetItem(colIdx, 3, cbOpClass->GetValue()); + lstColumns->SetItem(colIdx, 4, withDef); + } + } + + if (idc->GetTablespaceOid() != 0) + cbTablespace->SetKey(idc->GetTablespaceOid()); + cbTablespace->Enable(connection->BackendMinimumVersion(8, 0)); + + if (txtFillFactor) + { + txtFillFactor->SetValue(idc->GetFillFactor()); + } + + if (index->GetIndexType().Length() > 0) + { + cbType->Append(index->GetIndexType()); + cbType->SetSelection(0); + cbType->Disable(); + } + + chkDeferrable->SetValue(index->GetDeferrable()); + chkDeferred->SetValue(index->GetDeferred()); + chkDeferrable->Enable(false); + chkDeferred->Enable(false); + } + else + { + txtComment->Disable(); + if (!table) + { + cbClusterSet->Disable(); + cbClusterSet = 0; + } + + // Add the indexes + if (table) + { + cbIndex->Append(wxT("")); + set = connection->ExecuteSet( + wxT("SELECT relname FROM pg_class, pg_index WHERE pg_class.oid=indexrelid AND indrelid=") + table->GetOidStr()); + if (set) + { + while (!set->Eof()) + { + cbIndex->Append(set->GetVal(0)); + set->MoveNext(); + } + delete set; + } + } + else + { + cbIndex->Disable(); + } + + // Add the default tablespace + cbTablespace->Insert(_(""), 0, (void *)0); + cbTablespace->SetSelection(0); + wxString can_exclude = wxT("WHERE EXISTS (SELECT 1 FROM pg_proc WHERE oid=amgettuple) "); + if (connection->BackendMinimumVersion(9, 6)) + can_exclude = wxT("WHERE pg_indexam_has_property(oid,'can_exclude') "); + + cbType->Append(wxT("")); + + set = connection->ExecuteSet( + wxT("SELECT oid, amname FROM pg_am ") + + can_exclude+ + wxT("ORDER BY amname")); + if (set) + { + while (!set->Eof()) + { + cbType->Append(set->GetVal(1), set->GetVal(0)); + set->MoveNext(); + } + delete set; + } + + chkDeferrable->Enable(connection->BackendMinimumVersion(9, 0)); + chkDeferred->Enable(connection->BackendMinimumVersion(9, 0)); + } + + txtFillFactor->SetValidator(numericValidator); + if (connection->BackendMinimumVersion(8, 2)) + txtFillFactor->Enable(); + else + txtFillFactor->Disable(); + + return dlgIndexBase::Go(modal); +} + + +void dlgIndexConstraint::OnAddCol(wxCommandEvent &ev) +{ + wxString colName = cbColumns->GetValue(); + + if (!colName.IsEmpty()) + { + long colIndex = lstColumns->InsertItem(lstColumns->GetItemCount(), colName, columnFactory.GetIconId()); + + if (chkDesc->GetValue()) + { + if (chkDesc->IsEnabled()) + lstColumns->SetItem(colIndex, 1, wxT("DESC")); + + + if (rdbNullsLast->GetValue()) + { + if (rdbNullsLast->IsEnabled()) + lstColumns->SetItem(colIndex, 2, wxT("LAST")); + } + else + { + if (rdbNullsLast->IsEnabled()) + lstColumns->SetItem(colIndex, 2, wxT("FIRST")); + } + } + else + { + if (chkDesc->IsEnabled()) + lstColumns->SetItem(colIndex, 1, wxT("ASC")); + + if (rdbNullsFirst->GetValue()) + { + if (rdbNullsFirst->IsEnabled()) + lstColumns->SetItem(colIndex, 2, wxT("FIRST")); + } + else + { + if (rdbNullsLast->IsEnabled()) + lstColumns->SetItem(colIndex, 2, wxT("LAST")); + } + } + + lstColumns->SetItem(colIndex, 3, cbOpClass->GetValue()); + lstColumns->SetItem(colIndex, 4, cbOperator->GetValue()); + + cbColumns->Delete(cbColumns->GetCurrentSelection()); + if (cbColumns->GetCount()) + cbColumns->SetSelection(0); + + CheckChange(); + if (!cbColumns->GetCount()) + btnAddCol->Disable(); + } +} + + +void dlgIndexConstraint::OnRemoveCol(wxCommandEvent &ev) +{ + long pos = lstColumns->GetSelection(); + if (pos >= 0) + { + wxString colName = lstColumns->GetItemText(pos); + + lstColumns->DeleteItem(pos); + cbColumns->Append(colName); + + CheckChange(); + btnRemoveCol->Disable(); + } +} + +#ifdef __WXMAC__ +void dlgIndexConstraint::OnChangeSize(wxSizeEvent &ev) +{ + lstColumns->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + + +void dlgIndexConstraint::OnSelectComboCol(wxCommandEvent &ev) +{ + cbOperator->Clear(); + cbOperator->Append(wxT("")); + + if (cbColumns->GetValue().Length() > 0) + { + pgSet *set = connection->ExecuteSet( + wxT("SELECT DISTINCT oprname FROM pg_operator \n") + wxT("WHERE (") + wxT(" oprleft=") + NumToStr(cbColumns->GetOIDKey(cbColumns->GetCurrentSelection())) + + wxT(" OR oprright=") + NumToStr(cbColumns->GetOIDKey(cbColumns->GetCurrentSelection())) + + wxT(") AND oprcom > 0 \n") + wxT("ORDER BY oprname")); + if (set) + { + while (!set->Eof()) + { + cbOperator->Append(set->GetVal(0)); + set->MoveNext(); + } + delete set; + } + } + + dlgIndexBase::OnSelectComboCol(ev); +} + + +void dlgIndexConstraint::OnChangeIndex(wxCommandEvent &ev) +{ + bool indexselected = cbIndex->GetCurrentSelection() > 0; + bool btreeindex = cbType->GetValue() == wxT("btree") || cbType->GetValue() == wxEmptyString; + bool excludeconstraint = wxString(factory->GetTypeName()).Upper() == wxT("EXCLUDE"); + + cbTablespace->Enable(!indexselected && connection->BackendMinimumVersion(8, 0)); + cbType->Enable(!indexselected && excludeconstraint); + txtFillFactor->Enable(!indexselected && connection->BackendMinimumVersion(8, 2)); + txtWhere->Enable(!indexselected && excludeconstraint); + chkDeferrable->Enable(!indexselected && connection->BackendMinimumVersion(9, 0)); + chkDeferred->Enable(!indexselected && connection->BackendMinimumVersion(9, 0)); + cbOpClass->Enable(!indexselected && excludeconstraint && btreeindex); + chkDesc->Enable(!indexselected && excludeconstraint && btreeindex); + rdbNullsFirst->Enable(!indexselected && excludeconstraint && btreeindex); + rdbNullsLast->Enable(!indexselected && excludeconstraint && btreeindex); + cbOperator->Enable(!indexselected && excludeconstraint); + cbColumns->Enable(!indexselected); + btnAddCol->Enable(!indexselected); + btnRemoveCol->Enable(!indexselected); +} + + +void dlgIndexConstraint::OnSelectType(wxCommandEvent &ev) +{ + // The column options available change depending on the + // index type. We need to clear the column list, and + // setup some of the other controls accordingly. + + wxString newType = cbType->GetValue(); + bool changingDefault = false; + + // Detect if we're changing between default and btree (which are the same) to + // avoid annoying the user needlessly. + if ((m_previousType == wxEmptyString && cbType->GetValue() == wxT("btree")) || + (m_previousType == wxT("btree") && cbType->GetValue() == wxEmptyString)) + changingDefault = true; + + if (lstColumns->GetItemCount() > 0 && !changingDefault) + { + if (wxMessageBox(_("Changing the index type will cause the column list to be cleared. Do you wish to continue?"), _("Change index type?"), wxYES_NO) != wxYES) + { + cbType->SetValue(m_previousType); + return; + } + + // Move all the columns back to the combo + for (int pos = lstColumns->GetItemCount(); pos > 0; pos--) + { + wxString colName = lstColumns->GetItemText(pos - 1); + + lstColumns->DeleteItem(pos - 1); + cbColumns->Append(colName); + } + } + + if (newType == wxT("btree") || newType == wxEmptyString) + { + cbOpClass->Enable(true); + chkDesc->Enable(true); + rdbNullsFirst->Enable(true); + rdbNullsLast->Enable(true); + } + else + { + cbOpClass->Enable(false); + chkDesc->Enable(false); + rdbNullsFirst->Enable(false); + rdbNullsLast->Enable(false); + } + + // Make a note of the type so we can compare if it changes again. + m_previousType = cbType->GetValue(); +} + + +void dlgIndexConstraint::CheckChange() +{ + if (cbIndex->GetCurrentSelection() > 0) + EnableOK(true); + else + dlgIndexBase::CheckChange(); +} + + +wxString dlgIndexConstraint::GetDefinition() +{ + wxString sql = wxEmptyString; + + if (cbIndex->GetCurrentSelection() > 0) + { + sql += wxT(" USING INDEX ") + qtIdent(cbIndex->GetValue()); + } + else + { + if (cbType->GetCurrentSelection() > 0) + AppendIfFilled(sql, wxT(" USING "), cbType->GetValue()); + + sql += wxT("(") + GetColumns() + wxT(")"); + + if (txtFillFactor) + { + if (connection->BackendMinimumVersion(8, 2) && txtFillFactor->GetValue().Length() > 0) + sql += wxT("\n WITH (FILLFACTOR=") + txtFillFactor->GetValue() + wxT(")"); + } + + if (cbTablespace->GetOIDKey() > 0) + sql += wxT(" USING INDEX TABLESPACE ") + qtIdent(cbTablespace->GetValue()); + + if (chkDeferrable->GetValue()) + { + sql += wxT(" DEFERRABLE"); + if (chkDeferred->GetValue()) + sql += wxT(" INITIALLY DEFERRED"); + } + + if (txtWhere->GetValue().Length() > 0) + sql += wxT(" WHERE (") + txtWhere->GetValue() + wxT(")"); + } + + return sql; +} + + +wxString dlgIndexConstraint::GetSql() +{ + wxString sql; + wxString name = GetName(); + + if (!index) + { + sql = wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n ADD"); + AppendIfFilled(sql, wxT(" CONSTRAINT "), qtIdent(name)); + + sql += wxT(" ") + wxString(factory->GetTypeName()).Upper() + wxT(" ") + GetDefinition() + + wxT(";\n"); + } + else + { + if (index->GetName() != name) + { + sql = wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n RENAME CONSTRAINT ") + qtIdent(index->GetName()) + + wxT(" TO ") + qtIdent(name) + wxT(";\n"); + } + if (connection->BackendMinimumVersion(8, 0) && cbTablespace->GetOIDKey() != index->GetTablespaceOid()) + { + sql += wxT("ALTER INDEX ") + index->GetSchema()->GetQuotedIdentifier() + wxT(".") + qtIdent(name) + + wxT("\n SET TABLESPACE ") + qtIdent(cbTablespace->GetValue()) + + wxT(";\n"); + } + + if (txtFillFactor->GetValue().Trim().Length() > 0 && txtFillFactor->GetValue() != index->GetFillFactor()) + { + sql += wxT("ALTER INDEX ") + index->GetSchema()->GetQuotedIdentifier() + wxT(".") + qtIdent(name) + + wxT("\n SET (FILLFACTOR=") + + txtFillFactor->GetValue() + wxT(");\n"); + } + } + + if (!name.IsEmpty()) + AppendComment(sql, wxT("CONSTRAINT ") + qtIdent(name) + + wxT(" ON ") + table->GetQuotedFullIdentifier(), index); + + return sql; +} + + + +dlgProperty *pgPrimaryKeyFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgPrimaryKey(this, frame, (pgPrimaryKey *)node, (pgTable *)parent); +} + + + + +dlgPrimaryKey::dlgPrimaryKey(pgaFactory *f, frmMain *frame, pgPrimaryKey *index, pgTable *parentNode) + : dlgIndexConstraint(f, frame, wxT("dlgIndexConstraint"), index, parentNode) +{ +} + + +dlgPrimaryKey::dlgPrimaryKey(pgaFactory *f, frmMain *frame, ctlListView *colList) + : dlgIndexConstraint(f, frame, wxT("dlgIndexConstraint"), colList) +{ +} + + +pgObject *dlgPrimaryKey::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + if (name.IsEmpty()) + return 0; + + pgObject *obj = primaryKeyFactory.CreateObjects(collection, 0, wxT( + "\n AND cls.relname=") + qtDbString(name) + wxT( + "\n AND cls.relnamespace=") + table->GetSchema()->GetOidStr()); + + return obj; +} + + + +dlgProperty *pgUniqueFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgUnique(this, frame, (pgUnique *)node, (pgTable *)parent); +} + + +dlgUnique::dlgUnique(pgaFactory *f, frmMain *frame, pgUnique *index, pgTable *parentNode) + : dlgIndexConstraint(f, frame, wxT("dlgIndexConstraint"), index, parentNode) +{ +} + + +dlgUnique::dlgUnique(pgaFactory *f, frmMain *frame, ctlListView *colList) + : dlgIndexConstraint(f, frame, wxT("dlgIndexConstraint"), colList) +{ +} + + +pgObject *dlgUnique::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + pgObject *obj = uniqueFactory.CreateObjects(collection, 0, wxT( + "\n AND cls.relname=") + qtDbString(name) + wxT( + "\n AND cls.relnamespace=") + table->GetSchema()->GetOidStr()); + return obj; +} + + +dlgProperty *pgExcludeFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgExclude(this, frame, (pgExclude *)node, (pgTable *)parent); +} + + +dlgExclude::dlgExclude(pgaFactory *f, frmMain *frame, pgExclude *index, pgTable *parentNode) + : dlgIndexConstraint(f, frame, wxT("dlgIndexConstraint"), index, parentNode) +{ +} + + +dlgExclude::dlgExclude(pgaFactory *f, frmMain *frame, ctlListView *colList) + : dlgIndexConstraint(f, frame, wxT("dlgIndexConstraint"), colList) +{ +} + + +pgObject *dlgExclude::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + pgObject *obj = excludeFactory.CreateObjects(collection, 0, wxT( + "\n AND cls.relname=") + qtDbString(name) + wxT( + "\n AND cls.relnamespace=") + table->GetSchema()->GetOidStr()); + return obj; +} diff --git a/dlg/dlgLanguage.cpp b/dlg/dlgLanguage.cpp new file mode 100644 index 0000000..7c8c5bc --- /dev/null +++ b/dlg/dlgLanguage.cpp @@ -0,0 +1,263 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgLanguage.cpp - Language properties dialog +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgLanguage.h" +#include "schema/pgLanguage.h" +#include "ctl/ctlSeclabelPanel.h" + +// pointer to controls +#define cbName CTRL_COMBOBOX("cbName") +#define chkTrusted CTRL_CHECKBOX("chkTrusted") +#define cbHandler CTRL_COMBOBOX("cbHandler") +#define cbInline CTRL_COMBOBOX("cbInline") +#define cbValidator CTRL_COMBOBOX("cbValidator") + +dlgProperty *pgLanguageFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgLanguage(this, frame, (pgLanguage *)node, parent); +} + +BEGIN_EVENT_TABLE(dlgLanguage, dlgSecurityProperty) + EVT_TEXT(XRCID("cbName"), dlgLanguage::OnChangeName) + EVT_COMBOBOX(XRCID("cbName"), dlgLanguage::OnChangeName) + EVT_TEXT(XRCID("cbHandler"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbHandler"), dlgProperty::OnChange) +END_EVENT_TABLE(); + +dlgLanguage::dlgLanguage(pgaFactory *f, frmMain *frame, pgLanguage *node, pgObject *parent) + : dlgSecurityProperty(f, frame, node, wxT("dlgLanguage"), wxT("USAGE"), "U") +{ + language = node; + seclabelPage = new ctlSeclabelPanel(nbNotebook); + + if (!node) + { + int icon = PGICON_PUBLIC; + wxString name = wxT("public"); + wxString value = wxT("U"); + securityPage->lbPrivileges->AppendItem(icon, name, value); + AppendCurrentAcl(name, value); + } +} + +pgObject *dlgLanguage::GetObject() +{ + return language; +} + +int dlgLanguage::Go(bool modal) +{ + if (!connection->BackendMinimumVersion(8, 3)) + cbOwner->Disable(); + + if (!connection->BackendMinimumVersion(7, 5)) + txtComment->Disable(); + + if (!connection->BackendMinimumVersion(9, 0)) + cbInline->Disable(); + + if (connection->BackendMinimumVersion(9, 1)) + { + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(language); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgLanguage::OnChange)); + } + else + seclabelPage->Disable(); + + if (language) + { + // edit mode + chkTrusted->SetValue(language->GetTrusted()); + + cbHandler->Append(language->GetHandlerProc()); + cbHandler->SetSelection(0); + + if (connection->BackendMinimumVersion(9, 0)) + { + cbInline->Append(language->GetInlineProc()); + cbInline->SetSelection(0); + } + + wxString val = language->GetValidatorProc(); + if (!val.IsEmpty()) + { + cbValidator->Append(val); + cbValidator->SetSelection(0); + } + + cbName->SetValue(language->GetName()); + if (!connection->BackendMinimumVersion(7, 4)) + cbName->Disable(); + + chkTrusted->Disable(); + cbHandler->Disable(); + cbInline->Disable(); + cbValidator->Disable(); + } + else + { + // create mode + if (connection->BackendMinimumVersion(8, 1)) + { + pgSetIterator languages(connection, + wxT("SELECT tmplname FROM pg_pltemplate\n") + wxT(" LEFT JOIN pg_language ON tmplname=lanname\n") + wxT(" WHERE lanname IS NULL\n") + wxT(" ORDER BY tmplname")); + + while (languages.RowsLeft()) + cbName->Append(languages.GetVal(wxT("tmplname"))); + } + else + { + // to clear drop down list + cbName->Append(wxT(" ")); + cbName->Delete(0); + } + + cbValidator->Append(wxT("")); + pgSet *set = connection->ExecuteSet( + wxT("SELECT nspname, proname, prorettype, proargtypes[0] AS argtype\n") + wxT(" FROM pg_proc p\n") + wxT(" JOIN pg_namespace nsp ON nsp.oid=pronamespace\n") + wxT(" WHERE prorettype=") + NumToStr(PGOID_TYPE_LANGUAGE_HANDLER) + wxT("\n") + wxT(" OR (prorettype=") + NumToStr(PGOID_TYPE_VOID) + + wxT(" AND proargtypes[0]=") + NumToStr(PGOID_TYPE_LANGUAGE_HANDLER) + wxT(")") + wxT(" OR (prorettype=") + NumToStr(PGOID_TYPE_VOID) + + wxT(" AND proargtypes[0]=") + NumToStr(PGOID_TYPE_INTERNAL) + wxT(")")); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + + if (set->GetOid(wxT("prorettype")) == PGOID_TYPE_LANGUAGE_HANDLER) + cbHandler->Append(procname); + else + { + if (set->GetOid(wxT("argtype")) == PGOID_TYPE_LANGUAGE_HANDLER) + cbValidator->Append(procname); + else + cbInline->Append(procname); + } + set->MoveNext(); + } + delete set; + } + cbHandler->SetSelection(0); + cbInline->SetSelection(0); + cbValidator->SetSelection(0); + } + + return dlgSecurityProperty::Go(modal); +} + +pgObject *dlgLanguage::CreateObject(pgCollection *collection) +{ + wxString name = cbName->wxComboBox::GetValue(); + + pgObject *obj = languageFactory.CreateObjects(collection, 0, wxT("\n AND lanname ILIKE ") + qtDbString(name)); + return obj; +} + +void dlgLanguage::OnChangeName(wxCommandEvent &ev) +{ + if (connection->BackendMinimumVersion(8, 1) && !language) + { + bool useTemplate = (cbName->FindString(cbName->wxComboBox::GetValue()) >= 0); + chkTrusted->Enable(!useTemplate); + cbHandler->Enable(!useTemplate); + cbInline->Enable(!useTemplate && connection->BackendMinimumVersion(9, 0)); + cbValidator->Enable(!useTemplate); + } + OnChange(ev); +} + +void dlgLanguage::CheckChange() +{ + bool enable = true; + wxString name = cbName->GetValue(); + if (language) + { + enable = name != language->GetName() + || txtComment->GetValue() != language->GetComment() + || (connection->BackendMinimumVersion(8, 3) && cbOwner->GetValue() != language->GetOwner()); + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); + } + else + { + bool useTemplate = (cbName->FindString(name) >= 0); + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, useTemplate || !cbHandler->GetValue().IsEmpty(), _("Please specify language handler.")); + } + EnableOK(enable); +} + +wxString dlgLanguage::GetSql() +{ + wxString sql, name; + name = cbName->GetValue(); + + if (language) + { + // edit mode + if (name != language->GetName()) + sql += wxT("ALTER LANGUAGE ") + qtIdent(language->GetName()) + + wxT("\n RENAME TO ") + qtIdent(name) + wxT(";\n"); + if (connection->BackendMinimumVersion(8, 3)) + AppendOwnerChange(sql, wxT("LANGUAGE ") + qtIdent(name)); + } + else + { + // create mode + if (connection->BackendMinimumVersion(8, 1) && cbName->FindString(name) >= 0) + { + sql = wxT("CREATE LANGUAGE ") + qtIdent(name) + wxT(";\n"); + } + else + { + sql = wxT("CREATE "); + if (chkTrusted->GetValue()) + sql += wxT("TRUSTED "); + sql += wxT("LANGUAGE ") + qtIdent(name) + wxT("\n HANDLER ") + qtIdent(cbHandler->GetValue()); + if (connection->BackendMinimumVersion(9, 0)) + AppendIfFilled(sql, wxT("\n INLINE "), qtIdent(cbInline->GetValue())); + AppendIfFilled(sql, wxT("\n VALIDATOR "), qtIdent(cbValidator->GetValue())); + sql += wxT(";\n"); + } + if (connection->BackendMinimumVersion(8, 3)) + AppendOwnerNew(sql, wxT("LANGUAGE ") + qtIdent(name)); + } + + sql += GetGrant(wxT("U"), wxT("LANGUAGE ") + qtIdent(name)); + AppendComment(sql, wxT("LANGUAGE ") + qtIdent(name), 0, language); + + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + sql += seclabelPage->GetSqlForSecLabels(wxT("LANGUAGE"), qtIdent(name)); + + return sql; +} + +void dlgLanguage::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} diff --git a/dlg/dlgMainConfig.cpp b/dlg/dlgMainConfig.cpp new file mode 100644 index 0000000..b59301a --- /dev/null +++ b/dlg/dlgMainConfig.cpp @@ -0,0 +1,183 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgMainConfig.cpp - Configure setting +// +////////////////////////////////////////////////////////////////////////// + + + +// App headers +#include "pgAdmin3.h" + +#include "dlg/dlgMainConfig.h" + + +// Icons +#include "images/property.pngc" + + + + + +BEGIN_EVENT_TABLE(dlgMainConfig, DialogWithHelp) + EVT_BUTTON (wxID_OK, dlgMainConfig::OnOK) + EVT_BUTTON (wxID_CANCEL, dlgMainConfig::OnCancel) + EVT_TEXT(XRCID("txtValue"), dlgMainConfig::OnChange) + EVT_TEXT(XRCID("cbValue"), dlgMainConfig::OnChange) + EVT_CHECKBOX(XRCID("chkValue"), dlgMainConfig::OnChange) +END_EVENT_TABLE() + + +#define chkEnabled CTRL_CHECKBOX("chkEnabled") +#define cbValue CTRL_COMBOBOX("cbValue") +#define txtValue CTRL_TEXT("txtValue") +#define chkValue CTRL_CHECKBOX("chkValue") +#define txtComment CTRL_TEXT("txtComment") +#define stName CTRL_STATIC("stName") +#define stDescription CTRL_STATIC("stDescription") + + +static const wxChar *contextStrings[] = +{ + __("Internal - not externally settable"), + __("Postmaster - set on server start"), + __("SIGHUP - reloaded on SIGHUP signal"), + __("Backend - overridable in individual backend"), + __("Suset - may be overridden by superuser"), + __("Userlimit - may be set by user"), + __("Userset - may be set by user"), + __("Unknown") +}; + + +static const wxChar *sourceStrings[] = +{ + __("Variable has still its initial default value"), + __("Set via environment variable"), + __("Set in configuration file"), + __("Set on command line"), + __("Set by unprivileged command"), + __("Set in database variables"), + __("Set in user variables"), + __("Set in client parameters"), + __("set by Override"), + __("Set interactively"), + __("Set by test"), + __("Set by session parameters") +}; + + +dlgMainConfig::dlgMainConfig(pgFrame *parent, pgSettingItem *_item) : + DialogWithHelp((frmMain *)parent) +{ + SetFont(settings->GetSystemFont()); + LoadResource((wxWindow *)parent, wxT("dlgMainConfig")); + + // Icon + SetIcon(*property_png_ico); + RestorePosition(); + + item = _item; + + SetTitle(wxString::Format(_("Configuration setting \"%s\""), item->name.c_str())); + + // Setup the default values + + cbValue->Hide(); + chkValue->Hide(); + + if (!item->newLine) + { + if (item->orgLine) + item->newLine = new pgConfigLine(item->orgLine); + else + { + item->newLine = new pgConfigLine(); + item->newLine->item = item; + } + } + + chkEnabled->SetValue(!item->newLine->isComment); + txtValue->SetValue(item->newLine->value); + txtComment->SetValue(item->newLine->comment); + + wxFont fntLabel = stName->GetFont(); + fntLabel.SetWeight(wxBOLD); + stName->SetFont(fntLabel); + stName->SetLabel(item->name); + + wxString str; + str += _("Category") + wxString(wxT(": ")) + item->category + END_OF_LINE; + str += _("Context") + wxString(wxT(": ")); + str += wxGetTranslation(contextStrings[item->context]); + str += END_OF_LINE; + + if (item->source != pgSettingItem::PGC_UNKNOWNSOURCE) + { + str += _("Current value") + wxString(wxT(": ")); + + if (item->value == wxT("unset") && item->source == pgSettingItem::PGC_DEFAULT) + str += _("unset"); + else + str += item->value + END_OF_LINE wxT(" ") + wxGetTranslation(sourceStrings[item->source]); + + str += END_OF_LINE; + } + + stDescription->SetLabel(str + END_OF_LINE + item->short_desc + END_OF_LINE + item->extra_desc); + btnOK->Enable(); +} + + +dlgMainConfig::~dlgMainConfig() +{ + SavePosition(); +} + + +wxString dlgMainConfig::GetValue() +{ + return txtValue->GetValue(); +} + + +wxString dlgMainConfig::GetHelpPage() const +{ + return wxT("pg/runtime-config"); +} + + +void dlgMainConfig::OnChange(wxCommandEvent &ev) +{ +} + + +void dlgMainConfig::OnOK(wxCommandEvent &ev) +{ +#ifdef __WXGTK__ + if (!btnOK->IsEnabled()) + return; +#endif + item->newLine->value = GetValue(); + item->newLine->comment = txtComment->GetValue(); + item->newLine->isComment = !chkEnabled->GetValue(); + + EndModal(wxID_OK); +} + + +void dlgMainConfig::OnCancel(wxCommandEvent &ev) +{ + EndModal(wxID_CANCEL); +} + +int dlgMainConfig::Go() +{ + // Set focus on the Password textbox and show modal + return ShowModal(); +} diff --git a/dlg/dlgManageFavourites.cpp b/dlg/dlgManageFavourites.cpp new file mode 100644 index 0000000..a04fc06 --- /dev/null +++ b/dlg/dlgManageFavourites.cpp @@ -0,0 +1,207 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgManageFavourites.cpp - Manage favourites +// +////////////////////////////////////////////////////////////////////////// + + + +// App headers +#include "pgAdmin3.h" + +#include "dlg/dlgManageFavourites.h" +#include "db/pgConn.h" +#include "schema/pgServer.h" +#include "utils/sysLogger.h" + +#include "images/folder.pngc" +#include "images/favourite.pngc" + +#include "utils/favourites.h" + +#include + +BEGIN_EVENT_TABLE(dlgManageFavourites, pgDialog) + EVT_TREE_SEL_CHANGED(XRCID("trLocation"), dlgManageFavourites::OnTreeChange) + EVT_BUTTON (wxID_OK, dlgManageFavourites::OnOK) + EVT_BUTTON (wxID_CANCEL, dlgManageFavourites::OnCancel) + EVT_BUTTON (XRCID("btnRename"), dlgManageFavourites::OnRename) + EVT_BUTTON (XRCID("btnDelete"), dlgManageFavourites::OnDelete) + EVT_BUTTON (XRCID("btnNewFolder"), dlgManageFavourites::OnNewFolder) +END_EVENT_TABLE() + + +#define btnRename CTRL_BUTTON("btnRename") +#define btnDelete CTRL_BUTTON("btnDelete") +#define btnNewFolder CTRL_BUTTON("btnNewFolder") +// #define txtTitle CTRL_TEXT("txtTitle") +#define trLocation CTRL_TREE("trLocation") + + +dlgManageFavourites::dlgManageFavourites(wxWindow *parent, queryFavouriteFolder *favourites) : + pgDialog() +{ + SetFont(settings->GetSystemFont()); + LoadResource(parent, wxT("dlgManageFavourites")); + RestorePosition(); + + anythingChanged = false; + + this->favourites = favourites; + + wxImageList *imgList = new wxImageList(16, 16, true, 2); + imgList->Add(*favourite_png_ico); + imgList->Add(*folder_png_ico); + + trLocation->AssignImageList(imgList); + + // Setup the default values + trLocation->AddRoot(_("Favourites"), 1); + trLocation->SetItemImage(trLocation->GetRootItem(), 1, wxTreeItemIcon_Normal); + trLocation->SelectItem(trLocation->GetRootItem()); + favourites->AppendAllToTree(trLocation, trLocation->GetRootItem(), false); + trLocation->Expand(trLocation->GetRootItem()); +} + +int dlgManageFavourites::ManageFavourites() +{ + int r = ShowModal(); + if (r == wxID_OK) + return 1; + else + { + if (anythingChanged) + // Need rollback! + return -1; + else + return 0; + } +} + +dlgManageFavourites::~dlgManageFavourites() +{ + SavePosition(); +} + + +void dlgManageFavourites::OnOK(wxCommandEvent &ev) +{ + EndModal(wxID_OK); +} + + +void dlgManageFavourites::OnCancel(wxCommandEvent &ev) +{ + EndModal(wxID_CANCEL); +} + +void dlgManageFavourites::OnTreeChange(wxTreeEvent &ev) +{ + if (!trLocation->GetSelection().IsOk()) + { + btnRename->Enable(false); + btnDelete->Enable(false); + btnNewFolder->Enable(false); + return; + } + if (trLocation->GetSelection() == trLocation->GetRootItem()) + { + // On root item + btnRename->Enable(false); + btnDelete->Enable(false); + btnNewFolder->Enable(true); + } + else + { + btnRename->Enable(true); + btnDelete->Enable(true); + btnNewFolder->Enable(trLocation->GetItemImage(trLocation->GetSelection()) == 1); + } +} + + +void dlgManageFavourites::OnRename(wxCommandEvent &ev) +{ + if (!trLocation->GetSelection().IsOk() || + trLocation->GetSelection() == trLocation->GetRootItem()) + return; + + queryFavouriteItem *item = favourites->FindTreeItem(trLocation->GetSelection()); + if (!item) + return; + + wxTextEntryDialog dlg(this, _("Enter new name"), (item->GetId() != -2) ? _("Rename favourite") : _("Rename favourites folder"), item->GetTitle()); + if (dlg.ShowModal() != wxID_OK) + return; + + if (dlg.GetValue() != item->GetTitle()) + { + item->SetTitle(dlg.GetValue()); + trLocation->SetItemText(trLocation->GetSelection(), dlg.GetValue()); + anythingChanged = true; + } +} + +void dlgManageFavourites::OnDelete(wxCommandEvent &ev) +{ + wxString msg; + + if (!trLocation->GetSelection().IsOk() || + trLocation->GetSelection() == trLocation->GetRootItem()) + return; + + queryFavouriteItem *item = favourites->FindTreeItem(trLocation->GetSelection()); + if (!item) + return; + + if (item->GetId() != -2) + msg = wxString::Format(_("Are you sure you want to delete the favourite '%s'?"), item->GetTitle().c_str()); + else + msg = wxString::Format(_("Are you sure you want to delete the folder '%s'?"), item->GetTitle().c_str()); + if (wxMessageDialog(this, msg, _("Confirm delete"), wxYES_NO | wxICON_QUESTION).ShowModal() != wxID_YES) + return; + + if (favourites->DeleteTreeItem(trLocation->GetSelection())) + { + trLocation->Delete(trLocation->GetSelection()); + anythingChanged = true; + } +} + +void dlgManageFavourites::OnNewFolder(wxCommandEvent &ev) +{ + if (!trLocation->GetSelection().IsOk()) + return; + + queryFavouriteItem *item = favourites->FindTreeItem(trLocation->GetSelection()); + if (!item) + return; + if (item->GetId() != -2) + return; + + wxTextEntryDialog dlg(this, _("Enter name of new folder"), _("Create new favourites folder")); + if (dlg.ShowModal() != wxID_OK) + return; + + wxString title = dlg.GetValue().Trim(); + if (title.IsEmpty()) + return; + + queryFavouriteFolder *fld = (queryFavouriteFolder *)item; + if (fld->ContainsFolder(title)) + { + wxMessageBox(_("A folder with the specified name already exists.")); + return; + } + + + queryFavouriteFolder *newfld = fld->AddNewFolder(dlg.GetValue()); + newfld->SetTreeId(trLocation->AppendItem(trLocation->GetSelection(), title, 1)); + trLocation->Expand(fld->GetTreeId()); + anythingChanged = true; +} diff --git a/dlg/dlgManageMacros.cpp b/dlg/dlgManageMacros.cpp new file mode 100644 index 0000000..98b2194 --- /dev/null +++ b/dlg/dlgManageMacros.cpp @@ -0,0 +1,229 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgManageMacros.cpp - Manage macros +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +#include "dlg/dlgManageMacros.h" +#include "db/pgConn.h" +#include "schema/pgServer.h" +#include "utils/sysLogger.h" +#include "ctl/ctlSQLBox.h" +#include "utils/macros.h" + +#include + +//pointer to controls +#define lstKeys CTRL_LISTVIEW("lstKeys") +#define txtName CTRL_TEXT("txtName") +#define txtSqlBox CTRL_SQLBOX("txtSqlBox") +#define btnClear CTRL_BUTTON("btnClear") +#define btnSave CTRL_BUTTON("btnSave") + +BEGIN_EVENT_TABLE(dlgManageMacros, DialogWithHelp) + EVT_LIST_ITEM_SELECTED (XRCID("lstKeys"), dlgManageMacros::OnKeySelect) + EVT_BUTTON (wxID_OK, dlgManageMacros::OnOK) + EVT_BUTTON (wxID_CANCEL, dlgManageMacros::OnCancel) + EVT_BUTTON (XRCID("btnClear"), dlgManageMacros::OnClear) + EVT_BUTTON (XRCID("btnSave"), dlgManageMacros::OnSave) + EVT_TEXT (XRCID("txtName"), dlgManageMacros::OnNameChange) + EVT_STC_CHANGE (XRCID("txtSqlBox"), dlgManageMacros::OnQueryChange) +END_EVENT_TABLE() + +dlgManageMacros::dlgManageMacros(wxWindow *parent, frmMain *form, queryMacroList *macros) : + DialogWithHelp(form) +{ + SetFont(settings->GetSystemFont()); + LoadResource(parent, wxT("dlgManageMacros")); + RestorePosition(); + + this->macros = macros; + + // Setup list of keys + lstKeys->CreateColumns(NULL, _("Key"), _("Name"), 40); + + lstKeys->Hide(); + size_t i; + int num = 0; + for (i = 1; i < 13; i++) + { + wxString key; + key.Printf(wxT("Alt-F%d"), (int)i); + AddKeyToList(num++, key); + } + for (i = 1; i < 11; i++) + { + wxString key; + key.Printf(wxT("Ctrl-%d"), (int)i % 10); // in order of keys 1,2,...,8,9,0 + AddKeyToList(num++, key); + } + lstKeys->Show(); + + // Initialy no key is selected, so disable editor keys + btnClear->Disable(); + btnSave->Disable(); + + // Clear Markers + anythingChanged = false; + thisMacroChanged = false; + + txtSqlBox->SetModEventMask(wxSTC_MOD_INSERTTEXT | wxSTC_MOD_DELETETEXT); +} + +void dlgManageMacros::AddKeyToList(int position, const wxString &key) +{ + long tmp = lstKeys->InsertItem(position, key); + queryMacroItem *item = macros->FindMacro(key); + if (item != NULL) + lstKeys->SetItem(tmp, 1, item->GetName()); +} + +int dlgManageMacros::ManageMacros() +{ + int r = ShowModal(); + if (r == wxID_OK) + { + return 1; + } + else + { + if (anythingChanged) + return -1; + else + return 0; + } +} + +dlgManageMacros::~dlgManageMacros() +{ + SavePosition(); +} + +void dlgManageMacros::OnOK(wxCommandEvent &ev) +{ + if (thisMacroChanged) + SetMacro(true); + EndModal(wxID_OK); +} + +void dlgManageMacros::OnCancel(wxCommandEvent &ev) +{ + EndModal(wxID_CANCEL); +} + +void dlgManageMacros::DeleteMacro(int listItem) +{ + wxString key; + key = lstKeys->GetItemText(listItem); + + if (macros->DelMacro(key)) + { + anythingChanged = true; + lstKeys->SetItem(listItem, 1, wxT("")); + txtName->ChangeValue(wxT("")); + txtSqlBox->SetText(wxT("")); + thisMacroChanged = false; + btnSave->Disable(); + btnClear->Disable(); + } +} + +void dlgManageMacros::OnClear(wxCommandEvent &ev) +{ + int item; + item = lstKeys->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + + if (item == -1) + return; + + DeleteMacro(item); +} + +void dlgManageMacros::OnSave(wxCommandEvent &ev) +{ + if (!thisMacroChanged) + return; + SetMacro(false); +} + +void dlgManageMacros::SetMacro(bool silent) +{ + int item; + wxString key, Name, query; + + item = lstKeys->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item == -1) + return; + + key = lstKeys->GetItemText(item); + Name = txtName->GetValue().Trim(); + query = txtSqlBox->GetText().Trim(); + + if (Name.IsEmpty() && query.IsEmpty()) + { + DeleteMacro(item); + } + else if (Name.IsEmpty() || query.IsEmpty()) + { + if (!silent) + wxMessageBox(_("You must specify a query and a name for the macro"), _("Save macro"), wxICON_EXCLAMATION | wxOK); + return; + } + else + { + macros->AddOrUpdateMacro(key, Name, query); + anythingChanged = true; + thisMacroChanged = false; + lstKeys->SetItem(item, 1, Name); + btnClear->Enable(); + btnSave->Disable(); + } +} + +void dlgManageMacros::OnKeySelect(wxListEvent &ev) +{ + wxString key; + key = ev.GetText(); + + queryMacroItem *item = macros->FindMacro(key); + if (item != NULL) + { + txtName->ChangeValue(item->GetName()); + txtSqlBox->SetText(item->GetQuery()); + btnClear->Enable(); + btnSave->Disable(); + } + else + { + txtName->ChangeValue(wxT("")); + txtSqlBox->SetText(wxT("")); + btnClear->Disable(); + btnSave->Disable(); + } + thisMacroChanged = false; +} + +void dlgManageMacros::OnNameChange(wxCommandEvent &ev) +{ + thisMacroChanged = true; + btnSave->Enable(); +} + +void dlgManageMacros::OnQueryChange(wxStyledTextEvent &ev) +{ + thisMacroChanged = true; + btnSave->Enable(); +} + +wxString dlgManageMacros::GetHelpPage() const +{ + return wxT("macros"); +} diff --git a/dlg/dlgMoveTablespace.cpp b/dlg/dlgMoveTablespace.cpp new file mode 100644 index 0000000..111d245 --- /dev/null +++ b/dlg/dlgMoveTablespace.cpp @@ -0,0 +1,123 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgMoveTablespace.cpp - Reassign or drop owned objects +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/pgDefs.h" +#include "frm/frmMain.h" +#include "dlg/dlgMoveTablespace.h" +#include "utils/misc.h" +#include "schema/pgTablespace.h" + + +// pointer to controls +#define cbMoveTo CTRL_COMBOBOX("cbMoveTo") +#define cbKind CTRL_COMBOBOX("cbKind") +#define cbOwner CTRL_COMBOBOX("cbOwner") +#define btnOK CTRL_BUTTON("wxID_OK") + + +BEGIN_EVENT_TABLE(dlgMoveTablespace, pgDialog) + EVT_BUTTON(wxID_OK, dlgMoveTablespace::OnOK) +END_EVENT_TABLE() + + +dlgMoveTablespace::dlgMoveTablespace(frmMain *win, pgConn *conn, pgTablespace *tblspc) +{ + wxString query; + + connection = conn; + parent = win; + + SetFont(settings->GetSystemFont()); + LoadResource(win, wxT("dlgMoveTablespace")); + RestorePosition(); + + cbKind->Clear(); + cbKind->Append(_("All")); + cbKind->Append(_("Tables")); + cbKind->Append(_("Indexes")); + cbKind->Append(_("Materialized views")); + cbKind->SetSelection(0); + + cbMoveTo->Clear(); + query = wxT("SELECT spcname FROM pg_tablespace WHERE spcname<>") + conn->qtDbString(tblspc->GetName()) + wxT(" ORDER BY spcname"); + pgSetIterator tblspcs(connection, query); + while (tblspcs.RowsLeft()) + { + cbMoveTo->Append(tblspcs.GetVal(wxT("spcname"))); + } + cbMoveTo->SetSelection(0); + + cbOwner->Clear(); + cbOwner->Append(wxEmptyString); + query = wxT("SELECT rolname FROM pg_roles ORDER BY rolname"); + pgSetIterator roles(connection, query); + while (roles.RowsLeft()) + { + cbOwner->Append(roles.GetVal(wxT("rolname"))); + } + cbOwner->SetSelection(0); + cbOwner->Enable(cbOwner->GetStrings().Count() > 0); + + SetSize(330, 160); +} + +dlgMoveTablespace::~dlgMoveTablespace() +{ + SavePosition(); +} + + +void dlgMoveTablespace::OnOK(wxCommandEvent &ev) +{ + EndModal(wxID_OK); +} + + +void dlgMoveTablespace::OnCancel(wxCommandEvent &ev) +{ + EndModal(wxID_CANCEL); +} + +wxString dlgMoveTablespace::GetTablespace() +{ + return cbMoveTo->GetValue(); +} + +wxArrayString dlgMoveTablespace::GetKind() +{ + wxArrayString kinds; + if (cbKind->GetValue().Cmp(_("Tables")) == 0) + kinds.Add(wxT("TABLE")); + else if (cbKind->GetValue().Cmp(_("Indexes")) == 0) + kinds.Add(wxT("INDEX")); + else if (cbKind->GetValue().Cmp(_("Materialized views")) == 0) + kinds.Add(wxT("MATERIALIZED VIEW")); + else + { + kinds.Add(wxT("TABLE")); + kinds.Add(wxT("INDEX")); + kinds.Add(wxT("MATERIALIZED VIEW")); + } + return kinds; +} + +wxString dlgMoveTablespace::GetOwner() +{ + return cbOwner->GetValue(); +} + diff --git a/dlg/dlgOperator.cpp b/dlg/dlgOperator.cpp new file mode 100644 index 0000000..986c47f --- /dev/null +++ b/dlg/dlgOperator.cpp @@ -0,0 +1,469 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgOperator.cpp - PostgreSQL Operator Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgOperator.h" +#include "schema/pgSchema.h" +#include "schema/pgOperator.h" +#include "schema/pgDatatype.h" + + +// pointer to controls +#define cbLeftType CTRL_COMBOBOX2("cbLeftType") +#define cbRightType CTRL_COMBOBOX2("cbRightType") +#define cbProcedure CTRL_COMBOBOX2("cbProcedure") +#define cbRestrict CTRL_COMBOBOX("cbRestrict") +#define cbJoin CTRL_COMBOBOX("cbJoin") +#define cbCommutator CTRL_COMBOBOX("cbCommutator") +#define cbNegator CTRL_COMBOBOX("cbNegator") +#define cbLeftSort CTRL_COMBOBOX("cbLeftSort") +#define cbRightSort CTRL_COMBOBOX("cbRightSort") +#define cbLess CTRL_COMBOBOX("cbLess") +#define cbGreater CTRL_COMBOBOX("cbGreater") +#define chkCanHash CTRL_CHECKBOX("chkCanHash") +#define chkCanMerge CTRL_CHECKBOX("chkCanMerge") + + +BEGIN_EVENT_TABLE(dlgOperator, dlgTypeProperty) + EVT_TEXT(XRCID("cbLeftType"), dlgOperator::OnChangeTypeLeft) + EVT_COMBOBOX(XRCID("cbLeftType"), dlgOperator::OnChangeTypeLeft) + EVT_TEXT(XRCID("cbRightType"), dlgOperator::OnChangeTypeRight) + EVT_COMBOBOX(XRCID("cbRightType"), dlgOperator::OnChangeTypeRight) + EVT_TEXT(XRCID("cbProcedure"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbProcedure"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbLeftSort") , dlgOperator::OnChangeJoin) + EVT_COMBOBOX(XRCID("cbLeftSort") , dlgOperator::OnChangeJoin) + EVT_TEXT(XRCID("cbRightSort") , dlgOperator::OnChangeJoin) + EVT_COMBOBOX(XRCID("cbRightSort") , dlgOperator::OnChangeJoin) + EVT_TEXT(XRCID("cbLess") , dlgOperator::OnChangeJoin) + EVT_COMBOBOX(XRCID("cbLess") , dlgOperator::OnChangeJoin) + EVT_TEXT(XRCID("cbGreater") , dlgOperator::OnChangeJoin) + EVT_COMBOBOX(XRCID("cbGreater") , dlgOperator::OnChangeJoin) +END_EVENT_TABLE(); + + + +dlgProperty *pgOperatorFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgOperator(this, frame, (pgOperator *)node, (pgSchema *)parent); +} + +dlgOperator::dlgOperator(pgaFactory *f, frmMain *frame, pgOperator *node, pgSchema *sch) + : dlgTypeProperty(f, frame, wxT("dlgOperator")) +{ + schema = sch; + oper = node; + + cbRestrict->Disable(); + cbJoin->Disable(); + cbCommutator->Disable(); + cbNegator->Disable(); + cbLeftSort->Disable(); + cbRightSort->Disable(); + cbLess->Disable(); + cbGreater->Disable(); + chkCanHash->Disable(); + chkCanMerge->Disable(); +} + + +pgObject *dlgOperator::GetObject() +{ + return oper; +} + + +int dlgOperator::Go(bool modal) +{ + if (oper) + { + // edit mode + cbSchema->Enable(connection->BackendMinimumVersion(9, 1)); + + cbLeftType->Append(oper->GetLeftType()); + cbLeftType->SetSelection(0); + + cbRightType->Append(oper->GetRightType()); + cbRightType->SetSelection(0); + + cbProcedure->Append(oper->GetOperatorFunction()); + cbProcedure->SetSelection(0); + + AddType(wxT(" "), oper->GetLeftTypeOid()); + AddType(wxT(" "), oper->GetRightTypeOid()); + + cbRestrict->Append(oper->GetRestrictFunction()); + cbRestrict->SetSelection(0); + + cbJoin->Append(oper->GetJoinFunction()); + cbJoin->SetSelection(0); + + cbCommutator->Append(oper->GetCommutator()); + cbCommutator->SetSelection(0); + + cbNegator->Append(oper->GetNegator()); + cbNegator->SetSelection(0); + + if (!connection->BackendMinimumVersion(8, 3)) + { + cbLeftSort->Append(oper->GetLeftSortOperator()); + cbLeftSort->SetSelection(0); + + cbRightSort->Append(oper->GetRightSortOperator()); + cbRightSort->SetSelection(0); + + cbLess->Append(oper->GetLessOperator()); + cbLess->SetSelection(0); + + cbGreater->Append(oper->GetGreaterOperator()); + cbGreater->SetSelection(0); + } + + chkCanHash->SetValue(oper->GetHashJoins()); + chkCanMerge->SetValue(oper->GetMergeJoins()); + + + txtName->Disable(); + cbProcedure->Disable(); + cbLeftType->Disable(); + cbRightType->Disable(); + if (!connection->BackendMinimumVersion(8, 0)) + cbOwner->Disable(); + } + else + { + // create mode + wxArrayString incl; + incl.Add(wxT("+")); + incl.Add(wxT("-")); + incl.Add(wxT("*")); + incl.Add(wxT("/")); + incl.Add(wxT("<")); + incl.Add(wxT(">")); + incl.Add(wxT("=")); + incl.Add(wxT("~")); + incl.Add(wxT("!")); + incl.Add(wxT("@")); + incl.Add(wxT("#")); + incl.Add(wxT("%")); + incl.Add(wxT("^")); + incl.Add(wxT("&")); + incl.Add(wxT("|")); + incl.Add(wxT("`")); + incl.Add(wxT("?")); + incl.Add(wxT("$")); + + wxTextValidator validator(wxFILTER_INCLUDE_CHAR_LIST); + validator.SetIncludes(incl); + txtName->SetValidator(validator); + + AddType(wxT(" "), 0); + cbLeftType->Append(wxT(" ")); + cbRightType->Append(wxT(" ")); + FillDatatype(cbLeftType, cbRightType, false); + } + + return dlgProperty::Go(modal); +} + + +pgObject *dlgOperator::CreateObject(pgCollection *collection) +{ + pgObject *obj = operatorFactory.CreateObjects(collection, 0, + wxT("\n AND op.oprname=") + qtDbString(GetName()) + + wxT("\n AND op.oprnamespace=") + schema->GetOidStr() + + wxT("\n AND op.oprleft = ") + GetTypeOid(cbLeftType->GetGuessedSelection()) + + wxT("\n AND op.oprright = ") + GetTypeOid(cbRightType->GetGuessedSelection())); + + return obj; +} + + +void dlgOperator::CheckChange() +{ + if (oper) + { + EnableOK(txtComment->GetValue() != oper->GetComment() + || cbSchema->GetValue() != oper->GetSchema()->GetName() + || cbOwner->GetValue() != oper->GetOwner()); + } + else + { + wxString name = GetName(); + bool enable = true; + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, cbLeftType->GetGuessedSelection() > 0 || cbRightType->GetGuessedSelection() > 0 , _("Please select left or right datatype.")); + CheckValid(enable, cbProcedure->GetGuessedSelection() >= 0, _("Please specify a procedure.")); + + EnableOK(enable); + } +} + + +void dlgOperator::OnChangeTypeLeft(wxCommandEvent &ev) +{ + cbLeftType->GuessSelection(ev); + CheckChangeType(); +} + +void dlgOperator::OnChangeTypeRight(wxCommandEvent &ev) +{ + cbRightType->GuessSelection(ev); + CheckChangeType(); +} + +void dlgOperator::CheckChangeType() +{ + bool binaryOp = cbLeftType->GetGuessedSelection() > 0 && cbRightType->GetGuessedSelection() > 0; + + cbRestrict->Enable(binaryOp); + cbJoin->Enable(binaryOp); + + if (!connection->BackendMinimumVersion(8, 3)) + { + cbLeftSort->Enable(binaryOp); + cbRightSort->Enable(binaryOp); + cbLess->Enable(binaryOp); + cbGreater->Enable(binaryOp); + } + + chkCanHash->Enable(binaryOp); + chkCanMerge->Enable(binaryOp); + + procedures.Clear(); + + cbProcedure->Clear(); + cbJoin->Clear(); + cbRestrict->Clear(); + cbCommutator->Clear(); + cbNegator->Clear(); + + if (!connection->BackendMinimumVersion(8, 3)) + { + cbLeftSort->Clear(); + cbRightSort->Clear(); + cbLess->Clear(); + cbGreater->Clear(); + } + + cbRestrict->Append(wxEmptyString); + cbJoin->Append(wxEmptyString); + if (cbRestrict->GetCurrentSelection() < 0) + cbRestrict->SetSelection(0); + if (cbJoin->GetCurrentSelection() < 0) + cbJoin->SetSelection(0); + + + if (cbLeftType->GetGuessedSelection() > 0 || cbRightType->GetGuessedSelection() > 0) + { + wxString qry = + wxT("SELECT proname, nspname\n") + wxT(" FROM pg_proc p\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE pronargs = "); + + if (binaryOp) + qry += wxT("2"); + else + qry += wxT("1"); + + qry += wxT("\n AND proargtypes[0] = "); + + if (cbLeftType->GetGuessedSelection() > 0) + qry += GetTypeOid(cbLeftType->GetGuessedSelection()); + + if (binaryOp) + qry += wxT("\n AND proargtypes[1] = "); + + if (cbRightType->GetGuessedSelection() > 0) + qry += GetTypeOid(cbRightType->GetGuessedSelection()); + + + pgSet *set = connection->ExecuteSet(qry); + if (set) + { + while (!set->Eof()) + { + procedures.Add(database->GetQuotedSchemaPrefix(set->GetVal(wxT("nspname"))) + qtIdent(set->GetVal(wxT("proname")))); + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + cbProcedure->Append(procname); + if (binaryOp) + { + cbJoin->Append(procname); + cbRestrict->Append(procname); + } + + set->MoveNext(); + } + delete set; + } + + qry = wxT("SELECT oprname, nspname\n") + wxT(" FROM pg_operator o\n") + wxT(" JOIN pg_namespace n ON n.oid=oprnamespace\n"); + + if (cbLeftType->GetGuessedSelection() > 0) + qry += wxT(" WHERE oprleft = ") + GetTypeOid(cbLeftType->GetGuessedSelection()); + + + if (cbRightType->GetGuessedSelection() > 0) + { + if (binaryOp) + qry += wxT("\n AND oprright = "); + else + qry += wxT(" WHERE oprright = "); + qry += GetTypeOid(cbRightType->GetGuessedSelection()); + } + + cbCommutator->Append(wxT(" ")); + cbNegator->Append(wxT(" ")); + if (!connection->BackendMinimumVersion(8, 3)) + { + cbLeftSort->Append(wxT(" ")); + cbRightSort->Append(wxT(" ")); + cbLess->Append(wxT(" ")); + cbGreater->Append(wxT(" ")); + } + + set = connection->ExecuteSet(qry); + if (set) + { + while (!set->Eof()) + { + wxString opname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("oprname")); + + cbCommutator->Append(opname); + cbNegator->Append(opname); + if (binaryOp && !connection->BackendMinimumVersion(8, 3)) + { + cbLeftSort->Append(opname); + cbRightSort->Append(opname); + cbLess->Append(opname); + cbGreater->Append(opname); + } + set->MoveNext(); + } + delete set; + } + } + + CheckChange(); +} + + +void dlgOperator::OnChangeJoin(wxCommandEvent &ev) +{ + bool implicitMerges = (cbLeftSort->GetCurrentSelection() > 0 || cbRightSort->GetCurrentSelection() > 0 + || cbLess->GetCurrentSelection() > 0 || cbGreater->GetCurrentSelection() > 0); + + if (implicitMerges) + chkCanMerge->SetValue(true); + chkCanMerge->Enable(!implicitMerges); +} + + + +void dlgOperator::AppendFilledOperator(wxString &sql, const wxChar *txt, ctlComboBoxFix *cb) +{ + wxString op = cb->GetValue().Trim(); + if (!op.IsNull()) + { + sql += txt; + if (op.Find('.') > 0) + sql += wxT("OPERATOR(") + op + wxT(")"); + else + sql += op; + } +} + + +wxString dlgOperator::GetSql() +{ + wxString sql, name; + + if (oper) + { + // edit mode + name = oper->GetQuotedFullIdentifier() + + wxT("(") + oper->GetOperands() + wxT(")"); + + AppendOwnerChange(sql, wxT("OPERATOR ") + name); + AppendSchemaChange(sql, wxT("OPERATOR ") + name); + name = qtIdent(cbSchema->GetValue()) + wxT(".") + GetName() + + wxT("(") + oper->GetOperands() + wxT(")"); + } + else + { + // create mode + name = qtIdent(cbSchema->GetValue()) + wxT(".") + GetName() + wxT("("); + if (cbLeftType->GetGuessedSelection() > 0) + name += GetQuotedTypename(cbLeftType->GetGuessedSelection()); + else + name += wxT("NONE"); + name += wxT(", "); + if (cbRightType->GetGuessedSelection() > 0) + name += GetQuotedTypename(cbRightType->GetGuessedSelection()); + else + name += wxT("NONE"); + name += wxT(")"); + + + sql = wxT("CREATE OPERATOR ") + qtIdent(cbSchema->GetValue()) + wxT(".") + GetName() + + wxT("(\n PROCEDURE=") + procedures.Item(cbProcedure->GetGuessedSelection()); + + AppendIfFilled(sql, wxT(",\n LEFTARG="), GetQuotedTypename(cbLeftType->GetGuessedSelection())); + AppendIfFilled(sql, wxT(",\n RIGHTARG="), GetQuotedTypename(cbRightType->GetGuessedSelection())); + AppendIfFilled(sql, wxT(",\n COMMUTATOR="), cbCommutator->GetValue().Trim()); + AppendIfFilled(sql, wxT(",\n NEGATOR="), cbNegator->GetValue().Trim()); + + if (cbLeftType->GetGuessedSelection() > 0 && cbRightType->GetGuessedSelection() > 0) + { + if (cbRestrict->GetCurrentSelection() > 0) + sql += wxT(",\n RESTRICT=") + procedures.Item(cbRestrict->GetCurrentSelection() - 1); + if (cbJoin->GetCurrentSelection() > 0) + sql += wxT(",\n JOIN=") + procedures.Item(cbJoin->GetCurrentSelection() - 1); + + if (!connection->BackendMinimumVersion(8, 3)) + { + AppendFilledOperator(sql, wxT(",\n SORT1="), cbLeftSort); + AppendFilledOperator(sql, wxT(",\n SORT2="), cbRightSort); + AppendFilledOperator(sql, wxT(",\n LTCMP="), cbLess); + AppendFilledOperator(sql, wxT(",\n GTCMP="), cbGreater); + } + + if (chkCanMerge->GetValue() || chkCanHash->GetValue()) + { + sql += wxT(",\n "); + if (chkCanHash->GetValue()) + { + if (chkCanMerge->GetValue()) + sql += wxT("HASHES, MERGES"); + else + sql += wxT("HASHES"); + } + else if (chkCanMerge->GetValue()) + sql += wxT("MERGES"); + } + } + sql += wxT(");\n"); + AppendOwnerChange(sql, wxT("OPERATOR ") + name); + } + AppendComment(sql, wxT("OPERATOR ") + name, oper); + + return sql; +} diff --git a/dlg/dlgPackage.cpp b/dlg/dlgPackage.cpp new file mode 100644 index 0000000..dd3d4fd --- /dev/null +++ b/dlg/dlgPackage.cpp @@ -0,0 +1,183 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgPackage.cpp - EnterpriseDB package Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" + +#include "dlg/dlgPackage.h" +#include "schema/edbPackage.h" + +// pointer to controls +#define txtName CTRL_TEXT("txtName") +#define txtComment CTRL_TEXT("txtComment") +#define txtHeader CTRL_SQLBOX("txtHeader") +#define txtBody CTRL_SQLBOX("txtBody") + +dlgProperty *edbPackageFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgPackage(this, frame, (edbPackage *)node, (pgSchema *)parent); +} + + +BEGIN_EVENT_TABLE(dlgPackage, dlgSecurityProperty) + EVT_STC_MODIFIED(XRCID("txtHeader"), dlgProperty::OnChangeStc) + EVT_STC_MODIFIED(XRCID("txtBody"), dlgProperty::OnChangeStc) +END_EVENT_TABLE(); + + +dlgPackage::dlgPackage(pgaFactory *f, frmMain *frame, edbPackage *node, pgSchema *sch) + : dlgSecurityProperty(f, frame, node, wxT("dlgPackage"), wxT("EXECUTE"), "X") +{ + schema = sch; + package = node; + + bool bVal; + settings->Read(wxT("frmQuery/ShowLineNumber"), &bVal, false); + if (!bVal) + { + txtHeader->SetMarginType(1, wxSTC_MARGIN_NUMBER); + txtHeader->SetMarginWidth(1, ConvertDialogToPixels(wxPoint(16, 0)).x); + + txtBody->SetMarginType(1, wxSTC_MARGIN_NUMBER); + txtBody->SetMarginWidth(1, ConvertDialogToPixels(wxPoint(16, 0)).x); + } +} + + + +pgObject *dlgPackage::GetObject() +{ + return package; +} + + +int dlgPackage::Go(bool modal) +{ + if (!connection->EdbMinimumVersion(8, 2)) + txtComment->Disable(); + + cbOwner->Disable(); + + if (package) + { + // edit mode + txtName->Disable(); + + txtHeader->SetText(package->GetHeaderInner()); + txtBody->SetText(package->GetBodyInner()); + } + else + { + // create mode + + } + + return dlgSecurityProperty::Go(modal); +} + + +pgObject *dlgPackage::CreateObject(pgCollection *collection) +{ + pgObject *obj; + + if (collection->GetConnection()->EdbMinimumVersion(8, 2)) + obj = packageFactory.CreateObjects(collection, 0, + wxT(" AND nspname = ") + qtDbString(GetName())); + else + obj = packageFactory.CreateObjects(collection, 0, + wxT(" AND pkgname = ") + qtDbString(GetName())); + + return obj; +} + + +#ifdef __WXMAC__ +void dlgPackage::OnChangeSize(wxSizeEvent &ev) +{ + SetPrivilegesLayout(); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + + +void dlgPackage::CheckChange() +{ + bool enable = true; + + CheckValid(enable, !txtName->GetValue().IsEmpty(), _("Please specify name.")); + CheckValid(enable, !txtHeader->GetText().IsEmpty(), _("Please specify package header.")); + + if (package) + { + if (!(txtBody->GetText() != package->GetBodyInner() || + txtHeader->GetText() != package->GetHeaderInner())) + enable = false; + + if (txtComment->GetValue() != package->GetComment()) + enable = true; + } + + EnableOK(enable); +} + +bool dlgPackage::IsUpToDate() +{ + if (package && !package->IsUpToDate()) + return false; + else + return true; +} + + +wxString dlgPackage::GetSql() +{ + wxString sql; + wxString qtName = schema->GetQuotedSchemaPrefix(schema->GetName()) + qtIdent(txtName->GetValue()); + + if (!package || (package && txtHeader->GetText() != package->GetHeaderInner())) + { + if (package) + sql = wxT("DROP PACKAGE BODY ") + qtName + wxT(";\n\n"); + + sql += wxT("CREATE OR REPLACE PACKAGE ") + qtName + wxT("\nIS\n"); + sql += txtHeader->GetText(); + sql += wxT("\nEND ") + qtIdent(txtName->GetValue()) + wxT(";\n\n"); + } + + if (!package || (package && txtBody->GetText() != package->GetBodyInner()) + || (package && txtHeader->GetText() != package->GetHeaderInner())) + { + if (!txtBody->GetText().Trim().IsEmpty()) + { + sql += wxT("CREATE OR REPLACE PACKAGE BODY ") + qtName + wxT("\nIS\n"); + sql += txtBody->GetText().Trim().Trim(false); + sql += wxT("\nEND ") + qtIdent(txtName->GetValue()) + wxT(";\n\n"); + } + else + { + if (package && !package->GetBodyInner().Trim().IsEmpty()) + sql = wxT("DROP PACKAGE BODY ") + qtName + wxT(";\n\n"); + } + } + + sql += GetGrant(wxT("X"), wxT("PACKAGE ") + qtName); + + AppendComment(sql, wxT("PACKAGE"), schema, package); + + return sql; +} diff --git a/dlg/dlgPgpassConfig.cpp b/dlg/dlgPgpassConfig.cpp new file mode 100644 index 0000000..bbf6b91 --- /dev/null +++ b/dlg/dlgPgpassConfig.cpp @@ -0,0 +1,124 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgPgpassConfig.cpp - Configure setting +// +////////////////////////////////////////////////////////////////////////// + + + +// App headers +#include "pgAdmin3.h" + +#include "dlg/dlgPgpassConfig.h" +#include "db/pgConn.h" +#include "db/pgSet.h" + +// Icons +#include "images/property.pngc" + + + + + +BEGIN_EVENT_TABLE(dlgPgpassConfig, DialogWithHelp) + EVT_BUTTON (wxID_OK, dlgPgpassConfig::OnOK) + EVT_BUTTON (wxID_CANCEL, dlgPgpassConfig::OnCancel) + EVT_CHECKBOX(XRCID("chkEnabled"), dlgPgpassConfig::OnChange) + EVT_TEXT(XRCID("txtHostname"), dlgPgpassConfig::OnChange) + EVT_TEXT(XRCID("txtPort"), dlgPgpassConfig::OnChange) + EVT_TEXT(XRCID("txtDatabase"), dlgPgpassConfig::OnChange) + EVT_TEXT(XRCID("txtUsername"), dlgPgpassConfig::OnChange) + EVT_TEXT(XRCID("txtPassword"), dlgPgpassConfig::OnChange) + EVT_TEXT(XRCID("txtRePassword"), dlgPgpassConfig::OnChange) +END_EVENT_TABLE() + + +#define chkEnabled CTRL_CHECKBOX("chkEnabled") +#define txtHostname CTRL_TEXT("txtHostname") +#define txtPort CTRL_TEXT("txtPort") +#define txtDatabase CTRL_TEXT("txtDatabase") +#define txtUsername CTRL_TEXT("txtUsername") +#define txtPassword CTRL_TEXT("txtPassword") +#define txtRePassword CTRL_TEXT("txtRePassword") + +dlgPgpassConfig::dlgPgpassConfig(pgFrame *parent, pgPassConfigLine *_line) : + DialogWithHelp((frmMain *)parent) +{ + SetFont(settings->GetSystemFont()); + LoadResource((wxWindow *)parent, wxT("dlgPgpassConfig")); + + userAdding = databaseAdding = false; + + // Icon + SetIcon(*property_png_ico); + RestorePosition(); + line = _line; + + chkEnabled->SetValue(!line->isComment); + txtHostname->SetValue(line->hostname); + txtPort->SetValue(line->port); + txtDatabase->SetValue(line->database); + txtUsername->SetValue(line->username); + txtPassword->SetValue(line->password); + txtRePassword->SetValue(line->password); + btnOK->Disable(); + +} + + +dlgPgpassConfig::~dlgPgpassConfig() +{ + SavePosition(); +} + + +wxString dlgPgpassConfig::GetHelpPage() const +{ + return wxT("pg/libpq-pgpass"); +} + + +void dlgPgpassConfig::OnChange(wxCommandEvent &ev) +{ + /* Add any required validation rules here */ + wxString passwd = txtPassword->GetValue(); + wxString repasswd = txtRePassword->GetValue(); + if (passwd.IsEmpty() || (passwd.Length() > 1)) + { + if (!passwd.compare(repasswd)) + btnOK->Enable(); + } +} + + +void dlgPgpassConfig::OnOK(wxCommandEvent &ev) +{ +#ifdef __WXGTK__ + if (!btnOK->IsEnabled()) + return; +#endif + line->isComment = !chkEnabled->GetValue(); + line->hostname = txtHostname->GetValue(); + line->port = txtPort->GetValue(); + line->database = txtDatabase->GetValue(); + line->username = txtUsername->GetValue(); + line->password = txtPassword->GetValue(); + EndModal(wxID_OK); +} + + +void dlgPgpassConfig::OnCancel(wxCommandEvent &ev) +{ + EndModal(wxID_CANCEL); +} + + +int dlgPgpassConfig::Go() +{ + return ShowModal(); +} diff --git a/dlg/dlgProperty.cpp b/dlg/dlgProperty.cpp new file mode 100644 index 0000000..7381729 --- /dev/null +++ b/dlg/dlgProperty.cpp @@ -0,0 +1,2372 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgQuery.cpp - Property Dialog +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include + +// App headers +#include "pgAdmin3.h" +#include "ctl/ctlMenuToolbar.h" +#include "ctl/ctlSQLBox.h" +#include "schema/pgCollection.h" +#include "schema/pgDatatype.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" +#include "ctl/ctlSecurityPanel.h" +#include "ctl/ctlDefaultSecurityPanel.h" + +// Images +#include "images/properties.pngc" + +#include "frm/frmMain.h" +#include "frm/frmHint.h" + +// Property dialogs +#include "dlg/dlgProperty.h" +#include "dlg/dlgServer.h" +#include "dlg/dlgAggregate.h" +#include "dlg/dlgColumn.h" +#include "dlg/dlgIndex.h" +#include "dlg/dlgIndexConstraint.h" +#include "dlg/dlgForeignKey.h" +#include "dlg/dlgCheck.h" +#include "dlg/dlgRule.h" +#include "dlg/dlgTrigger.h" +#include "dlg/dlgEventTrigger.h" +#include "agent/dlgJob.h" +#include "agent/dlgStep.h" +#include "agent/dlgSchedule.h" + +#include "slony/dlgRepCluster.h" +#include "slony/dlgRepNode.h" +#include "slony/dlgRepPath.h" +#include "slony/dlgRepListen.h" +#include "slony/dlgRepSet.h" +#include "slony/dlgRepSequence.h" +#include "slony/dlgRepTable.h" +#include "slony/dlgRepSubscription.h" +#include "schema/pgTable.h" +#include "schema/pgColumn.h" +#include "schema/pgTrigger.h" +#include "schema/pgGroup.h" +#include "schema/pgUser.h" +#include "schema/pgEventTrigger.h" + +void dataType::SetOid(OID id) +{ + oid = id; +} + +void dataType::SetTypename(wxString name) +{ + typeName = name; +} + +OID dataType::GetOid() +{ + return oid; +} + +wxString dataType::GetTypename() +{ + return typeName; +} + +#define CTRLID_CHKSQLTEXTFIELD 1000 + + +BEGIN_EVENT_TABLE(dlgProperty, DialogWithHelp) + EVT_NOTEBOOK_PAGE_CHANGED(XRCID("nbNotebook"), dlgProperty::OnPageSelect) + + EVT_TEXT(XRCID("txtName"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbOwner"), dlgProperty::OnChangeOwner) + EVT_COMBOBOX(XRCID("cbOwner"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbSchema"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbSchema"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtComment"), dlgProperty::OnChange) + + EVT_CHECKBOX(CTRLID_CHKSQLTEXTFIELD, dlgProperty::OnChangeReadOnly) + + EVT_BUTTON(wxID_HELP, dlgProperty::OnHelp) + EVT_BUTTON(wxID_OK, dlgProperty::OnOK) +END_EVENT_TABLE(); + + +dlgProperty::dlgProperty(pgaFactory *f, frmMain *frame, const wxString &resName) : DialogWithHelp(frame) +{ + readOnly = false; + sqlPane = 0; + sqlTextField1 = 0; + sqlTextField2 = 0; + processing = false; + mainForm = frame; + database = 0; + connection = 0; + factory = f; + item = (void *)NULL; + owneritem = (void *)NULL; + chkReadOnly = (wxCheckBox *)NULL; + SetFont(settings->GetSystemFont()); + LoadResource(frame, resName); + +#ifdef __WXMSW__ + SetWindowStyleFlag(GetWindowStyleFlag() & ~wxMAXIMIZE_BOX); +#endif + + nbNotebook = CTRL_NOTEBOOK("nbNotebook"); + if (!nbNotebook) + { + wxMessageBox(wxString::Format(_("Problem with resource %s: Notebook not found.\nPrepare to crash!"), resName.c_str())); + return; + } + + // Set the icon + wxBitmap bm(factory->GetImage()); + wxIcon ico; + ico.CopyFromBitmap(bm); + SetIcon(ico); + + txtName = CTRL_TEXT("txtName"); + txtOid = CTRL_TEXT("txtOID"); + txtComment = CTRL_TEXT("txtComment"); + cbOwner = CTRL_COMBOBOX2("cbOwner"); + cbSchema = CTRL_COMBOBOX2("cbSchema"); + cbClusterSet = CTRL_COMBOBOX1("cbClusterSet"); + + wxString db = wxT("Database"); + wxString ts = wxT("Tablespace"); + wxString rg = wxT("Resource Group"); + enableSQL2 = db.Cmp(factory->GetTypeName()) == 0 + || ts.Cmp(factory->GetTypeName()) == 0 + || rg.Cmp(factory->GetTypeName()) == 0; + + wxNotebookPage *page = nbNotebook->GetPage(0); + wxASSERT(page != NULL); + page->GetClientSize(&width, &height); + + numericValidator.SetStyle(wxFILTER_NUMERIC); + btnOK->Disable(); + + statusBar = XRCCTRL(*this, "unkStatusBar", wxStatusBar); +} + + +dlgProperty::~dlgProperty() +{ + wxString prop = wxT("Properties/") + wxString(factory->GetTypeName()); + settings->WritePoint(prop, GetPosition()); + + if (GetWindowStyle() & wxRESIZE_BORDER) + settings->WriteSize(prop, GetSize()); + + if (obj) + obj->SetWindowPtr(NULL); +} + + +wxString dlgProperty::GetHelpPage() const +{ + wxString page; + + pgObject *obj = ((dlgProperty *)this)->GetObject(); + if (obj) + page = obj->GetHelpPage(false); + else + { + // Attempt to get he page from the dialogue, otherwise, take a shot at it! + page = this->GetHelpPage(true); + if (page.Length() == 0) + { + page = wxT("pg/sql-create"); + page += wxString(factory->GetTypeName()).Lower(); + } + } + + return page; +} + + +void dlgProperty::CheckValid(bool &enable, const bool condition, const wxString &msg) +{ + if (enable) + { + if (!condition) + { + if (statusBar) + statusBar->SetStatusText(msg); + enable = false; + } + } +} + + +void dlgProperty::SetDatabase(pgDatabase *db) +{ + database = db; + if (db) + connection = db->GetConnection(); +} + +void dlgProperty::SetDatatypeCache(dataTypeCache cache) +{ + dtCache = cache; +} + +void dlgProperty::EnableOK(bool enable) +{ + btnOK->Enable(enable); + if (enable) + { + if (statusBar) + statusBar->SetStatusText(wxEmptyString); + } +} + + +void dlgProperty::SetSqlReadOnly(bool readonly) +{ + if (chkReadOnly) + chkReadOnly->Enable(!readonly); +} + + +int dlgProperty::Go(bool modal) +{ + wxASSERT(factory != 0); + + if(GetObject()) + obj = GetObject(); + else + obj = mainForm->GetBrowser()->GetObject(mainForm->GetBrowser()->GetSelection()); + + // restore previous position and size, if applicable + wxString prop = wxT("Properties/") + wxString(factory->GetTypeName()); + + wxSize origSize = GetSize(); + + if (GetWindowStyle() & wxRESIZE_BORDER) + SetSize(settings->Read(prop, GetSize())); + + wxPoint pos = settings->Read(prop, GetPosition()); + if (pos.x < 0) + pos.x = 0; + if (pos.y < 0) + pos.y = 0; + Move(pos); + + wxSize size = GetSize(); + CheckOnScreen(this, pos, size, origSize.GetWidth(), origSize.GetHeight()); + Move(pos); + + ctlComboBoxFix *cbowner = (ctlComboBoxFix *)cbOwner; + ctlComboBoxFix *cbschema = (ctlComboBoxFix *)cbSchema; + + if (cbClusterSet) + { + cbClusterSet->Append(wxEmptyString); + cbClusterSet->SetSelection(0); + + if (mainForm && database) + { + wxArrayString clusters = database->GetSlonyClusters(mainForm->GetBrowser()); + + size_t i; + for (i = 0 ; i < clusters.GetCount() ; i++) + { + wxString cluster = wxT("_") + clusters.Item(i); + pgSetIterator sets(connection, + wxT("SELECT set_id, ") + qtIdent(cluster) + wxT(".slonyversionmajor(), ") + qtIdent(cluster) + wxT(".slonyversionminor()\n") + wxT(" FROM ") + qtIdent(cluster) + wxT(".sl_set\n") + wxT(" WHERE set_origin = ") + qtIdent(cluster) + + wxT(".getlocalnodeid(") + qtDbString(cluster) + wxT(");")); + + while (sets.RowsLeft()) + { + wxString str; + long setId = sets.GetLong(wxT("set_id")); + long majorVer = sets.GetLong(wxT("slonyversionmajor")); + long minorVer = sets.GetLong(wxT("slonyversionminor")); + str.Printf(_("Cluster \"%s\", set %ld"), clusters.Item(i).c_str(), setId); + cbClusterSet->Append(str, static_cast(new replClientData(cluster, setId, majorVer, minorVer))); + } + } + } + if (cbClusterSet->GetCount() < 2) + cbClusterSet->Disable(); + } + + if (cbowner && !cbowner->GetCount()) + { + if (!GetObject()) + cbOwner->Append(wxEmptyString); + AddGroups(cbowner); + AddUsers(cbowner); + } + if (txtOid) + txtOid->Disable(); + + if (cbschema && !cbschema->GetCount()) + AddSchemas(cbschema); + + if (GetObject()) + { + if (txtName) + txtName->SetValue(GetObject()->GetName()); + if (txtOid) + txtOid->SetValue(NumToStr((unsigned long)GetObject()->GetOid())); + if (cbOwner) + cbOwner->SetValue(GetObject()->GetOwner()); + if (cbSchema) + cbSchema->SetValue(GetObject()->GetSchema()->GetName()); + if (txtComment) + txtComment->SetValue(GetObject()->GetComment()); + + + if (!readOnly && !GetObject()->CanCreate()) + { + // users who can't create will usually not be allowed to change either. + readOnly = false; + } + + wxString typeName = factory->GetTypeName(); + SetTitle(wxString(wxGetTranslation(typeName)) + wxT(" ") + GetObject()->GetFullIdentifier()); + } + else + { + if (factory) + SetTitle(wxGetTranslation(factory->GetNewString())); + if (cbSchema) + { + if (obj->GetMetaType() == PGM_SCHEMA) + cbSchema->SetValue(obj->GetName()); + else + cbSchema->SetValue(obj->GetSchema()->GetName()); + } + } + if (statusBar) + statusBar->SetStatusText(wxEmptyString); + + if (nbNotebook) + { + wxNotebookPage *pg = nbNotebook->GetPage(0); + if (pg) + pg->SetFocus(); + } + + // This fixes a UI glitch on MacOS X and Windows + // Because of the new layout code, the Privileges pane don't size itself properly + SetSize(GetSize().GetWidth() + 1, GetSize().GetHeight()); + SetSize(GetSize().GetWidth() - 1, GetSize().GetHeight()); + + if (modal) + return ShowModal(); + else + Show(true); + + return 0; +} + + +void dlgProperty::CreateAdditionalPages() +{ + if (wxString(factory->GetTypeName()).Cmp(wxT("Server"))) + { + // create a panel + sqlPane = new wxPanel(nbNotebook); + + // add panel to the notebook + nbNotebook->AddPage(sqlPane, wxT("SQL")); + + // create a flex grid sizer + wxFlexGridSizer *fgsizer = new wxFlexGridSizer(1, 5, 5); + + // add checkbox to the panel + chkReadOnly = new wxCheckBox(sqlPane, CTRLID_CHKSQLTEXTFIELD, _("Read only")); + chkReadOnly->SetValue(true); + fgsizer->Add(chkReadOnly, 1, wxALL | wxALIGN_LEFT, 5); + + // text entry box + sqlTextField1 = new ctlSQLBox(sqlPane, CTL_PROPSQL, + wxDefaultPosition, wxDefaultSize, + wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_RICH2); + fgsizer->Add(sqlTextField1, 1, wxALL | wxEXPAND, 5); + + // text entry box + if (enableSQL2) + { + sqlTextField2 = new ctlSQLBox(sqlPane, CTL_PROPSQL, + wxDefaultPosition, wxDefaultSize, + wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_RICH2); + fgsizer->Add(sqlTextField2, 1, wxALL | wxEXPAND, 5); + } + + fgsizer->AddGrowableCol(0); + fgsizer->AddGrowableRow(1); + if (fgsizer->GetRows() > 1) + { + fgsizer->AddGrowableRow(2); + } + + sqlPane->SetAutoLayout(true); + sqlPane->SetSizer(fgsizer); + } +} + + +wxString dlgProperty::GetName() +{ + if (txtName) + { + if (GetObject()) + { + // If there is an existing object name with a leading or trailing + // space, don't try to remove it. + if (GetObject()->GetName() == txtName->GetValue()) + return txtName->GetValue(); + else + return txtName->GetValue().Strip(wxString::both); + } + else + return txtName->GetValue().Strip(wxString::both); + } + return wxEmptyString; +} + + +void dlgProperty::AppendNameChange(wxString &sql, const wxString &objName) +{ + if (GetObject()->GetName() != GetName()) + { + if (objName.Length() > 0) + { + sql += wxT("ALTER ") + objName + + wxT("\n RENAME TO ") + qtIdent(GetName()) + + wxT(";\n"); + } + else + { + sql += wxT("ALTER ") + GetObject()->GetTypeName().MakeUpper() + + wxT(" ") + GetObject()->GetQuotedFullIdentifier() + + wxT("\n RENAME TO ") + qtIdent(GetName()) + + wxT(";\n"); + } + } +} + + +void dlgProperty::AppendOwnerChange(wxString &sql, const wxString &objName) +{ + if (!GetObject() || GetObject()->GetOwner() != cbOwner->GetValue()) + { + sql += wxT("ALTER ") + objName + + wxT("\n OWNER TO ") + qtIdent(cbOwner->GetValue()) + + wxT(";\n"); + } +} + + +void dlgProperty::AppendOwnerNew(wxString &sql, const wxString &objName) +{ + if (cbOwner->GetGuessedSelection() > 0) + sql += wxT("ALTER ") + objName + + wxT("\n OWNER TO ") + qtIdent(cbOwner->GetValue()) + + wxT(";\n"); +} + + +void dlgProperty::AppendSchemaChange(wxString &sql, const wxString &objName) +{ + wxString currentschema; + + if (GetObject()->GetMetaType() == PGM_SCHEMA) + { + currentschema = GetObject()->GetName(); + } + else + { + currentschema = GetObject()->GetSchema()->GetName(); + } + + if (currentschema != cbSchema->GetValue()) + { + sql += wxT("ALTER ") + objName + + wxT("\n SET SCHEMA ") + qtIdent(cbSchema->GetValue()) + + wxT(";\n"); + } +} + + +void dlgProperty::AppendComment(wxString &sql, const wxString &objName, pgObject *obj) +{ + wxString comment = txtComment->GetValue(); + if ((!obj && !comment.IsEmpty()) || (obj && obj->GetComment() != comment)) + { + sql += wxT("COMMENT ON ") + objName + + wxT("\n IS ") + qtDbString(comment) + wxT(";\n"); + } +} + + +void dlgProperty::AppendComment(wxString &sql, const wxString &objType, pgSchema *schema, pgObject *obj) +{ + wxString comment = txtComment->GetValue(); + if ((!obj && !comment.IsEmpty()) || (obj && obj->GetComment() != comment)) + { + sql += wxT("COMMENT ON ") + objType + wxT(" "); + if (schema) + sql += schema->GetQuotedPrefix(); + sql += qtIdent(GetName()) + wxT("\n IS ") + qtDbString(comment) + wxT(";\n"); + } +} + + +void dlgProperty::AppendQuoted(wxString &sql, const wxString &name) +{ + // quick and quite dirty: + // !!! this is unsafe if the name itself contains a dot which isn't meant as separator between schema and object + if (name.First('.') >= 0) + { + sql += qtIdent(name.BeforeFirst('.')) + wxT(".") + qtIdent(name.AfterFirst('.')); + } + else + sql += qtIdent(name); +} + +void dlgProperty::AppendQuotedType(wxString &sql, const wxString &name) +{ + // see AppendQuoted() + if (name.First('.') >= 0) + { + sql += qtIdent(name.BeforeFirst('.')) + wxT(".") + qtTypeIdent(name.AfterFirst('.')); + } + else + sql += qtTypeIdent(name); +} + + +void dlgProperty::FillCombobox(const wxString &query, ctlComboBoxFix *cb1, ctlComboBoxFix *cb2) +{ + if (!cb1 && !cb2) + return; + + pgSet *set = connection->ExecuteSet(query); + if (set) + { + while (!set->Eof()) + { + if (cb1) + cb1->Append(set->GetVal(0)); + if (cb2) + cb2->Append(set->GetVal(0)); + set->MoveNext(); + } + delete set; + } + +} + + +void dlgProperty::AddDatabases(ctlComboBoxFix *cb) +{ + FillCombobox(wxT("SELECT datname FROM pg_database ORDER BY 1"), cb); +} + + +void dlgProperty::AddUsers(ctlComboBoxFix *cb1, ctlComboBoxFix *cb2) +{ + if (connection->BackendMinimumVersion(8, 1)) + { + FillCombobox(wxT("SELECT rolname FROM pg_roles WHERE rolcanlogin ORDER BY 1"), cb1, cb2); + } + else + { + FillCombobox(wxT("SELECT usename FROM pg_user ORDER BY 1"), cb1, cb2); + } +} + + +void dlgProperty::AddGroups(ctlComboBoxFix *combo) +{ + if (connection->BackendMinimumVersion(8, 1)) + { + FillCombobox(wxT("SELECT rolname FROM pg_roles WHERE NOT rolcanlogin ORDER BY 1"), combo); + } + else + { + FillCombobox(wxT("SELECT groname FROM pg_group ORDER BY 1"), combo); + } +} + + +void dlgProperty::AddSchemas(ctlComboBoxFix *combo) +{ + if (connection->BackendMinimumVersion(8, 1)) + { + FillCombobox(wxT("SELECT nspname FROM pg_namespace WHERE nspname NOT LIKE E'pg\\\\_%' AND nspname != 'information_schema' ORDER BY nspname"), + combo); + } +} + + +void dlgProperty::PrepareTablespace(ctlComboBoxFix *cb, const OID current) +{ + wxASSERT(cb != 0); + + if (connection->BackendMinimumVersion(8, 0)) + { + // Populate the combo + cb->FillOidKey(connection, wxT("SELECT oid, spcname FROM pg_tablespace WHERE spcname <> 'pg_global' ORDER BY spcname")); + + if (current) + cb->SetKey(current); + else + { + if (database) + cb->SetValue(database->GetDefaultTablespace()); + else + { + wxString def = connection->ExecuteScalar(wxT("SELECT current_setting('default_tablespace');")); + if (def == wxEmptyString || def == wxT("unset")) + def = wxT("pg_default"); + cb->SetValue(def); + } + } + } + else + cb->Disable(); +} + + +void dlgProperty::OnChangeStc(wxStyledTextEvent &ev) +{ + CheckChange(); +} + + +void dlgProperty::OnChange(wxCommandEvent &ev) +{ + CheckChange(); +} + + +void dlgProperty::OnChangeOwner(wxCommandEvent &ev) +{ + ctlComboBox *cb = cbOwner; + if (cb) + cb->GuessSelection(ev); + CheckChange(); +} + + +void dlgProperty::OnChangeReadOnly(wxCommandEvent &ev) +{ + size_t pos; + bool showmessage; + + showmessage = chkReadOnly->GetValue() + && ! (!enableSQL2 && GetSql().Length() == 0 && sqlTextField1->GetText().Cmp(_("-- nothing to change")) == 0) + && ! (!enableSQL2 && GetSql().Length() == 0 && sqlTextField1->GetText().Cmp(_("-- definition incomplete")) == 0) + && ! (enableSQL2 && GetSql().Length() == 0 && GetSql2().Length() == 0 && sqlTextField1->GetText().Cmp(_("-- nothing to change")) == 0 && sqlTextField2->GetText().Length() == 0) + && ! (enableSQL2 && GetSql().Length() == 0 && GetSql2().Length() == 0 && sqlTextField1->GetText().Cmp(_("-- definition incomplete")) == 0 && sqlTextField2->GetText().Length() == 0) + && (sqlTextField1->GetText().Cmp(GetSql()) != 0 || (enableSQL2 && sqlTextField2->GetText().Cmp(GetSql2()) != 0)); + + if (showmessage) + { + if (wxMessageBox(_("Are you sure you wish to cancel your edit?"), _("SQL editor"), wxYES_NO | wxNO_DEFAULT) != wxYES) + { + chkReadOnly->SetValue(false); + return; + } + } + + sqlTextField1->SetReadOnly(chkReadOnly->GetValue()); + if (enableSQL2) + { + sqlTextField2->SetReadOnly(chkReadOnly->GetValue()); + } + for (pos = 0; pos < nbNotebook->GetPageCount() - 1; pos++) + { + nbNotebook->GetPage(pos)->Enable(chkReadOnly->GetValue()); + } + + if (chkReadOnly->GetValue()) + { + FillSQLTextfield(); + } +} + + +void dlgProperty::FillSQLTextfield() +{ + // create a function because this is a duplicated code + sqlTextField1->SetReadOnly(false); + if (enableSQL2) + { + sqlTextField2->SetReadOnly(false); + } + if (btnOK->IsEnabled()) + { + wxString tmp; + if (cbClusterSet && cbClusterSet->GetSelection() > 0) + { + replClientData *data = (replClientData *)cbClusterSet->wxItemContainer::GetClientData(cbClusterSet->GetSelection()); + if(data) + tmp.Printf(_("-- Execute replicated using cluster \"%s\", set %ld\n"), data->cluster.c_str(), data->setId); + } + sqlTextField1->SetText(tmp + GetSql()); + if (enableSQL2) + { + sqlTextField2->SetText(GetSql2()); + } + } + else + { + if (GetObject()) + sqlTextField1->SetText(_("-- nothing to change")); + else + sqlTextField1->SetText(_("-- definition incomplete")); + if (enableSQL2) + { + sqlTextField2->SetText(wxT("")); + } + } + sqlTextField1->SetReadOnly(true); + if (enableSQL2) + { + sqlTextField2->SetReadOnly(true); + } +} + + +bool dlgProperty::tryUpdate(wxTreeItemId collectionItem) +{ + ctlTree *browser = mainForm->GetBrowser(); + pgCollection *collection = (pgCollection *)browser->GetObject(collectionItem); + if (collection && collection->IsCollection() && factory->GetCollectionFactory() == collection->GetFactory()) + { + pgObject *data = CreateObject(collection); + if (data) + { + + wxString nodeName = this->GetDisplayName(); + if (nodeName.IsEmpty()) + nodeName = data->GetDisplayName(); + + size_t pos = 0; + wxTreeItemId newItem; + + if (!data->IsCreatedBy(columnFactory)) + { + // columns should be appended, not inserted alphabetically + + wxCookieType cookie; + newItem = browser->GetFirstChild(collectionItem, cookie); + while (newItem) + { + if (browser->GetItemText(newItem) > nodeName) + break; + pos++; + newItem = browser->GetNextChild(collectionItem, cookie); + } + } + + if (newItem) + browser->InsertItem(collectionItem, pos, nodeName, data->GetIconId(), -1, data); + else + browser->AppendItem(collectionItem, nodeName, data->GetIconId(), -1, data); + + if (data->WantDummyChild()) + browser->AppendItem(data->GetId(), wxT("Dummy")); + + if (browser->GetSelection() == item) + collection->ShowTreeDetail(browser, 0, mainForm->GetProperties()); + else + collection->UpdateChildCount(browser); + } + else + { + // CreateObject didn't return a new pgObject; refresh the complete collection + mainForm->Refresh(collection); + } + return true; + } + return false; +} + + + +void dlgProperty::ShowObject() +{ + mainForm->ObjectBrowserRefreshing(true); + pgObject *data = GetObject(); + + // We might have a parent to refresh. If so, the children will + // inherently get refreshed as well. Yay :-) + if (owneritem) + { + // Get the object node in case we need it later + wxTreeItemId objectnode = mainForm->GetBrowser()->GetItemParent(owneritem); + + // Stash the selected items path + wxString currentPath = mainForm->GetCurrentNodePath(); + + pgObject *tblobj = mainForm->GetBrowser()->GetObject(owneritem); + + if (tblobj) + { + dlgProperty *ownDialog = NULL; + if (data) + { + ownDialog = data->GetWindowPtr(); + data->SetWindowPtr(NULL); + } + mainForm->Refresh(tblobj); + if (data) + { + data->SetWindowPtr(ownDialog); + } + } + + // Restore the previous selection... + mainForm->SetCurrentNode(mainForm->GetBrowser()->GetRootItem(), currentPath); + } + else if (data) + { + pgObject *newData = data->Refresh(mainForm->GetBrowser(), item); + if (newData && newData != data) + { + mainForm->SetCurrentObject(newData); + mainForm->GetBrowser()->SetItemData(item, newData); + + newData->SetId(item); + delete data; + SetObject(newData); + + newData->UpdateIcon(mainForm->GetBrowser()); + } + if (newData) + { + mainForm->GetBrowser()->DeleteChildren(newData->GetId()); + + if (item == mainForm->GetBrowser()->GetSelection()) + newData->ShowTree(mainForm, mainForm->GetBrowser(), mainForm->GetProperties(), 0); + mainForm->GetBrowser()->SetItemText(item, newData->GetFullName()); + mainForm->GetSqlPane()->SetReadOnly(false); + mainForm->GetSqlPane()->SetText(newData->GetSql(mainForm->GetBrowser())); + mainForm->GetSqlPane()->SetReadOnly(true); + } + } + else if (item && chkReadOnly->GetValue()) + { + wxTreeItemId collectionItem = item; + + while (collectionItem) + { + // search up the tree for our collection + if (tryUpdate(collectionItem)) + break; + collectionItem = mainForm->GetBrowser()->GetItemParent(collectionItem); + } + } + else // Brute force update the current item + { + pgObject *currobj = mainForm->GetBrowser()->GetObject(mainForm->GetBrowser()->GetSelection()); + + if (currobj) + mainForm->Refresh(currobj); + } + mainForm->ObjectBrowserRefreshing(false); +} + + +bool dlgProperty::apply(const wxString &sql, const wxString &sql2) +{ + wxString tmp; + pgConn *myConn = connection; + + if (GetDisconnectFirst()) + { + myConn = database->GetServer()->GetConnection(); + database->Disconnect(); + } + + if (!sql.IsEmpty()) + { + wxArrayString queries; + + if (WannaSplitQueries()) + queries = SplitQueries(BuildSql(sql)); + else + queries.Add(BuildSql(sql)); + + for (size_t index = 0; index < queries.GetCount(); index++) + { + tmp = queries.Item(index); + if (!myConn->ExecuteVoid(tmp)) + { + // error message is displayed inside ExecuteVoid + return false; + } + + if (database) + database->AppendSchemaChange(tmp); + } + } + + // Process the second SQL statement. This is primarily only used by + // CREATE DATABASE which cannot be run in a multi-statement query in + // PostgreSQL 8.3+ + if (!sql2.IsEmpty()) + { + tmp = BuildSql(sql2); + + if (!myConn->ExecuteVoid(tmp)) + { + // error message is displayed inside ExecuteVoid + // Warn the user about partially applied changes, but don't bail out. + // Carry on as if everything was successful (because the most important + // change was!! + wxMessageBox(_("An error occurred executing the second stage SQL statement.\n\nChanges may have been partially applied."), _("Warning"), wxICON_EXCLAMATION | wxOK, this); + } + else // Only apend schema changes if there was no error. + { + if (database) + database->AppendSchemaChange(tmp); + } + } + + ShowObject(); + + return true; +} + + +wxString dlgProperty::BuildSql(const wxString &sql) +{ + wxString tmp; + + if (cbClusterSet && cbClusterSet->GetSelection() > 0) + { + replClientData *data = (replClientData *)cbClusterSet->wxItemContainer::GetClientData(cbClusterSet->GetSelection()); + if (data) + { + if (data->majorVer > 1 || (data->majorVer == 1 && data->minorVer >= 2)) + { + // From slony version 2.2.0 onwards ddlscript_prepare() method is removed and + // ddlscript_complete() method arguments got changed so we have to use ddlcapture() method + // instead of ddlscript_prepare() and changed the argument of ddlscript_complete() method + if ((data->majorVer == 2 && data->minorVer >= 2) || (data->majorVer > 2)) + { + tmp = wxT("SELECT ") + qtIdent(data->cluster) + + wxT(".ddlcapture(") + qtDbString(sql) + wxT(", ") + wxT("NULL::text") + wxT(" );\n") + + wxT("SELECT ") + qtIdent(data->cluster) + + wxT(".ddlscript_complete(") + wxT("NULL::text") + wxT(" );\n"); + } + else + { + tmp = wxT("SELECT ") + qtIdent(data->cluster) + + wxT(".ddlscript_prepare(") + NumToStr(data->setId) + wxT(", -1);\n") + + sql + wxT(";\n") + + wxT("SELECT ") + qtIdent(data->cluster) + + wxT(".ddlscript_complete(") + NumToStr(data->setId) + wxT(", ") + + qtDbString(sql) + wxT(", -1);\n"); + } + } + else + { + tmp = wxT("SELECT ") + qtIdent(data->cluster) + + wxT(".ddlscript(") + NumToStr(data->setId) + wxT(", ") + + qtDbString(sql) + wxT(", 0);\n"); + } + } + } + else + tmp = sql; + + return tmp; +} + + +wxArrayString dlgProperty::SplitQueries(const wxString &sql) +{ + wxArrayString queries; + wxString query; + wxString c; + + bool antislash = false; + bool quote_string = false; + bool doublequote_string = false; + + for (size_t item = 0; item < sql.Length(); item++) + { + c = sql.GetChar(item); + + if (c == wxT("\\")) + antislash = true; + + if (c == wxT("'")) + { + if (antislash) + antislash = false; + else if (quote_string) + quote_string = false; + else if (!doublequote_string) + quote_string = true; + } + + if (c == wxT("\"")) + { + if (antislash) + antislash = false; + else if (doublequote_string) + doublequote_string = false; + else if (!quote_string) + doublequote_string = true; + } + + query = query + c; + + if (c == wxT(";") && !antislash && !quote_string && !doublequote_string) + { + queries.Add(query); + query = wxEmptyString; + } + } + + return queries; +} + + +void dlgProperty::OnOK(wxCommandEvent &ev) +{ +#ifdef __WXGTK__ + if (!btnOK->IsEnabled()) + return; +#endif + if (!IsUpToDate()) + { + if (wxMessageBox(wxT("The object has been changed by another user. Do you wish to continue to try to update it?"), wxT("Overwrite changes?"), wxYES_NO) != wxYES) + return; + } + + EnableOK(false); + + if (IsModal()) + { + EndModal(0); + return; + } + + wxString sql; + wxString sql2; + if (chkReadOnly->GetValue()) + { + sql = GetSql(); + sql2 = GetSql2(); + } + else + { + sql = sqlTextField1->GetText(); + if (enableSQL2) + { + sql2 = sqlTextField2->GetText(); + } + else + { + sql2 = wxT(""); + } + } + + if (!apply(sql, sql2)) + { + EnableOK(true); + return; + } + + Destroy(); +} + + +void dlgProperty::OnPageSelect(wxNotebookEvent &event) +{ + if (sqlTextField1 && chkReadOnly->GetValue() && + event.GetSelection() == (int)nbNotebook->GetPageCount() - 1) + { + FillSQLTextfield(); + } +} + + + +void dlgProperty::InitDialog(frmMain *frame, pgObject *node) +{ + CenterOnParent(); + if (!connection) + connection = node->GetConnection(); + database = node->GetDatabase(); + + if (factory != node->GetFactory() && !node->IsCollection()) + { + wxCookieType cookie; + wxTreeItemId collectionItem = frame->GetBrowser()->GetFirstChild(node->GetId(), cookie); + while (collectionItem) + { + pgCollection *collection = (pgCollection *)frame->GetBrowser()->GetObject(collectionItem); + if (collection && collection->IsCollection() && collection->IsCollectionFor(node)) + break; + + collectionItem = frame->GetBrowser()->GetNextChild(node->GetId(), cookie); + } + item = collectionItem; + } + else + item = node->GetId(); + + // Additional hacks to get the table to refresh when modifying sub-objects + if (!item && (node->GetMetaType() == PGM_TABLE || node->GetMetaType() == PGM_VIEW + || node->GetMetaType() == GP_PARTITION || node->GetMetaType() == PGM_DOMAIN)) + owneritem = node->GetId(); + + int metatype = node->GetMetaType(); + + switch (metatype) + { + case PGM_COLUMN: + owneritem = node->GetTable()->GetId(); + break; + + case PGM_CHECK: + case PGM_FOREIGNKEY: + case PGM_CONSTRAINT: + case PGM_EXCLUDE: + case PGM_INDEX: + case PGM_PRIMARYKEY: + case PGM_UNIQUE: + case PGM_TRIGGER: + case PGM_RULE: // Rules are technically table objects! Yeuch + case EDB_PACKAGEFUNCTION: + case EDB_PACKAGEVARIABLE: + case PGM_SCHEDULE: + case PGM_STEP: + if (node->IsCollection()) + owneritem = frame->GetBrowser()->GetParentObject(node->GetId())->GetId(); + else + owneritem = frame->GetBrowser()->GetParentObject(frame->GetBrowser()->GetParentObject(node->GetId())->GetId())->GetId(); + break; + + default: + // we want to do this as objects can change schema + owneritem = node->GetId(); + break; + } +} + + +dlgProperty *dlgProperty::CreateDlg(frmMain *frame, pgObject *node, bool asNew, pgaFactory *factory) +{ + if (!factory) + { + factory = node->GetFactory(); + if (node->IsCollection()) + factory = ((pgaCollectionFactory *)factory)->GetItemFactory(); + } + + pgObject *currentNode, *parentNode; + if (asNew) + currentNode = 0; + else + currentNode = node; + + if (factory != node->GetFactory()) + parentNode = node; + else + parentNode = frame->GetBrowser()->GetObject( + frame->GetBrowser()->GetItemParent(node->GetId())); + + if (parentNode && parentNode->IsCollection() && parentNode->GetMetaType() != PGM_SERVER) + parentNode = frame->GetBrowser()->GetObject( + frame->GetBrowser()->GetItemParent(parentNode->GetId())); + + dlgProperty *dlg = 0; + + if (factory) + { + dlg = factory->CreateDialog(frame, currentNode, parentNode); + if (dlg) + { + if (factory->IsCollection()) + factory = ((pgaCollectionFactory *)factory)->GetItemFactory(); + wxASSERT(factory); + + dlg->InitDialog(frame, node); + + if (currentNode) + currentNode->SetWindowPtr(dlg); + } + } + return dlg; +} + + +bool dlgProperty::CreateObjectDialog(frmMain *frame, pgObject *node, pgaFactory *factory) +{ + if (node->GetMetaType() != PGM_SERVER) + { + pgConn *conn = node->GetConnection(); + if (!conn || conn->GetStatus() != PGCONN_OK || !conn->IsAlive()) + return false; + } + + dlgProperty *dlg = NULL; + + if (node) + dlg = node->GetWindowPtr(); + + if (dlg) + dlg->Raise(); + else + { + dlg = CreateDlg(frame, node, true, factory); + + if (dlg) + { + dlg->SetTitle(wxGetTranslation(dlg->factory->GetNewString())); + + dlg->CreateAdditionalPages(); + dlg->Go(); + dlg->CheckChange(); + } + else + wxMessageBox(_("Not implemented.")); + } + + return true; +} + + +bool dlgProperty::EditObjectDialog(frmMain *frame, ctlSQLBox *sqlbox, pgObject *node) +{ + if (node->GetMetaType() != PGM_SERVER) + { + pgConn *conn = node->GetConnection(); + if (!conn || conn->GetStatus() != PGCONN_OK || !conn->IsAlive()) + return false; + } + + // If this is a function or view, hint that the user might want to edit the object in + // the query tool. + if (node->GetMetaType() == PGM_FUNCTION || node->GetMetaType() == PGM_VIEW) + { + if (frmHint::ShowHint(frame, HINT_OBJECT_EDITING) == wxID_CANCEL) + return false; + } + + dlgProperty *dlg = NULL; + + if (node) + dlg = node->GetWindowPtr(); + + if (dlg) + dlg->Raise(); + else + { + dlg = CreateDlg(frame, node, false); + + if (dlg) + { + wxString typeName = dlg->factory->GetTypeName(); + dlg->SetTitle(wxString(wxGetTranslation(typeName)) + wxT(" ") + node->GetFullIdentifier()); + + dlg->CreateAdditionalPages(); + dlg->Go(); + + dlg->CheckChange(); + } + else + wxMessageBox(_("Not implemented.")); + } + + return true; +} + +wxString dlgProperty::qtDbString(const wxString &str) +{ + // Use the server aware version if possible + if (connection) + return connection->qtDbString(str); + else if (database) + return database->GetConnection()->qtDbString(str); + else + { + wxString ret = str; + ret.Replace(wxT("\\"), wxT("\\\\")); + ret.Replace(wxT("'"), wxT("''")); + ret.Append(wxT("'")); + ret.Prepend(wxT("'")); + return ret; + } +} + +void dlgProperty::OnHelp(wxCommandEvent &ev) +{ + wxString page = GetHelpPage(); + + if (!page.IsEmpty()) + { + if (page.StartsWith(wxT("pg/"))) + { + if (connection) + { + if (connection->GetIsEdb()) + DisplayHelp(page.Mid(3), HELP_ENTERPRISEDB); + else if (connection->GetIsGreenplum()) + DisplayHelp(page.Mid(3), HELP_GREENPLUM); + else + DisplayHelp(page.Mid(3), HELP_POSTGRESQL); + } + else + DisplayHelp(page.Mid(3), HELP_POSTGRESQL); + } + else if (page.StartsWith(wxT("slony/"))) + DisplayHelp(page.Mid(6), HELP_SLONY); + else + DisplayHelp(page, HELP_PGADMIN); + } +} + +///////////////////////////////////////////////////////////////////////////// + + +dlgTypeProperty::dlgTypeProperty(pgaFactory *f, frmMain *frame, const wxString &resName) + : dlgProperty(f, frame, resName) +{ + isVarLen = false; + isVarPrec = false; + if (wxWindow::FindWindow(XRCID("txtLength"))) + { + txtLength = CTRL_TEXT("txtLength"); + txtLength->SetValidator(numericValidator); + txtLength->Disable(); + } + else + txtLength = 0; + if (wxWindow::FindWindow(XRCID("txtPrecision"))) + { + txtPrecision = CTRL_TEXT("txtPrecision"); + txtPrecision->SetValidator(numericValidator); + txtPrecision->Disable(); + } + else + txtPrecision = 0; +} + + +void dlgTypeProperty::FillDatatype(ctlComboBox *cb, bool withDomains, bool addSerials) +{ + FillDatatype(cb, 0, withDomains, addSerials); +} + +void dlgTypeProperty::FillDatatype(ctlComboBox *cb, ctlComboBox *cb2, bool withDomains, bool addSerials) +{ + + if (dtCache.IsEmpty()) + { + // A column dialog is directly called, no datatype caching is done. + // Fetching datatypes from server. + DatatypeReader tr(database, withDomains, addSerials); + while (tr.HasMore()) + { + pgDatatype dt = tr.GetDatatype(); + + AddType(wxT("?"), tr.GetOid(), dt.GetQuotedSchemaPrefix(database) + dt.QuotedFullName()); + cb->Append(dt.GetQuotedSchemaPrefix(database) + dt.QuotedFullName()); + if (cb2) + cb2->Append(dt.GetQuotedSchemaPrefix(database) + dt.QuotedFullName()); + tr.MoveNext(); + } + } + else + { + // A column dialog is called from a table dialog where we have already cached the datatypes. + // Using cached datatypes. + size_t i; + for (i = 0; i < dtCache.GetCount(); i++) + { + AddType(wxT("?"), dtCache.Item(i)->GetOid(), dtCache.Item(i)->GetTypename()); + cb->Append(dtCache.Item(i)->GetTypename()); + if (cb2) + cb2->Append(dtCache.Item(i)->GetTypename()); + } + } + +} + + +int dlgTypeProperty::Go(bool modal) +{ + if (GetObject()) + { + if (txtLength) + txtLength->SetValidator(numericValidator); + if (txtPrecision) + txtPrecision->SetValidator(numericValidator); + } + return dlgProperty::Go(modal); +} + + + +void dlgTypeProperty::AddType(const wxString &typ, const OID oid, const wxString quotedName) +{ + wxString vartyp; + if (typ == wxT("?")) + { + switch ((long)oid) + { + case PGOID_TYPE_BIT: + case PGOID_TYPE_BIT_ARRAY: + case PGOID_TYPE_VARBIT: + case PGOID_TYPE_VARBIT_ARRAY: + case PGOID_TYPE_BPCHAR: + case PGOID_TYPE_BPCHAR_ARRAY: + case PGOID_TYPE_VARCHAR: + case PGOID_TYPE_VARCHAR_ARRAY: + vartyp = wxT("L"); + break; + case PGOID_TYPE_TIME: + case PGOID_TYPE_TIME_ARRAY: + case PGOID_TYPE_TIMETZ: + case PGOID_TYPE_TIMETZ_ARRAY: + case PGOID_TYPE_TIMESTAMP: + case PGOID_TYPE_TIMESTAMP_ARRAY: + case PGOID_TYPE_TIMESTAMPTZ: + case PGOID_TYPE_TIMESTAMPTZ_ARRAY: + case PGOID_TYPE_INTERVAL: + case PGOID_TYPE_INTERVAL_ARRAY: + vartyp = wxT("D"); + break; + case PGOID_TYPE_NUMERIC: + case PGOID_TYPE_NUMERIC_ARRAY: + vartyp = wxT("P"); + break; + default: + vartyp = wxT(" "); + break; + } + } + else + vartyp = typ; + + types.Add(vartyp + NumToStr(oid) + wxT(":") + quotedName); +} + + +wxString dlgTypeProperty::GetTypeInfo(int sel) +{ + wxString str; + if (sel >= 0) + str = types.Item(sel); + + return str; +} + + +wxString dlgTypeProperty::GetTypeOid(int sel) +{ + wxString str; + if (sel >= 0) + str = types.Item(sel).Mid(1).BeforeFirst(':'); + + return str; +} + + +wxString dlgTypeProperty::GetQuotedTypename(int sel) +{ + wxString sql, suffix; + bool isArray = false; + + if (sel >= 0) + { + sql = types.Item(sel).AfterFirst(':'); + + // Deal with time/timestamp first as they're special cases + if (sql.Left(19) == wxT("time with time zone")) + { + if (sql.Right(2) == wxT("[]")) + isArray = true; + sql = wxT("time"); + suffix = wxT("with time zone"); + } + else if (sql.Left(21) == wxT("time without time zone")) + { + if (sql.Right(2) == wxT("[]")) + isArray = true; + sql = wxT("time"); + suffix = wxT("without time zone"); + } + else if (sql.Left(24) == wxT("timestamp with time zone")) + { + if (sql.Right(2) == wxT("[]")) + isArray = true; + sql = wxT("timestamp"); + suffix = wxT("with time zone"); + } + else if (sql.Left(27) == wxT("timestamp without time zone")) + { + if (sql.Right(2) == wxT("[]")) + isArray = true; + sql = wxT("timestamp"); + suffix = wxT("without time zone"); + } + else if (sql.Right(2) == wxT("[]")) + { + sql = sql.SubString(0, sql.Len() - 3); + isArray = true; + } + else if (sql.Right(3) == wxT("[]\"")) + { + sql = sql.SubString(1, sql.Len() - 4); + isArray = true; + } + + // Stick the length on + if (isVarLen && txtLength) + { + wxString varlen = txtLength->GetValue(); + if (!varlen.IsEmpty() && NumToStr(StrToLong(varlen)) == varlen && StrToLong(varlen) >= minVarLen) + { + sql += wxT("(") + varlen; + if (isVarPrec && txtPrecision) + { + wxString varprec = txtPrecision->GetValue(); + if (!varprec.IsEmpty()) + sql += wxT(",") + varprec; + } + sql += wxT(")"); + } + } + } + + // Append any post-length suffix + if (suffix.length()) + sql += wxT(" ") + suffix; + + // Append any array decoration + if (isArray) + sql += wxT("[]"); + + return sql; +} + + +void dlgTypeProperty::CheckLenEnable() +{ + int sel = cbDatatype->GetGuessedSelection(); + if (sel >= 0) + { + wxString info = types.Item(sel); + isVarPrec = info.StartsWith(wxT("P")); + isVarLen = isVarPrec || info.StartsWith(wxT("L")) || info.StartsWith(wxT("D")); + minVarLen = (info.StartsWith(wxT("D")) ? 0 : 1); + maxVarLen = isVarPrec ? 1000 : + minVarLen ? 0x7fffffff : 10; + } +} + + +///////////////////////////////////////////////////////////////////////////// + + +dlgCollistProperty::dlgCollistProperty(pgaFactory *f, frmMain *frame, const wxString &resName, pgTable *parentNode) + : dlgProperty(f, frame, resName) +{ + columns = 0; + table = parentNode; +} + + +dlgCollistProperty::dlgCollistProperty(pgaFactory *f, frmMain *frame, const wxString &resName, ctlListView *colList) + : dlgProperty(f, frame, resName) +{ + columns = colList; + table = 0; +} + + +int dlgCollistProperty::Go(bool modal) +{ + if (columns) + { + int pos; + // iterate cols + for (pos = 0 ; pos < columns->GetItemCount() ; pos++) + { + wxString col = columns->GetItemText(pos); + if (cbColumns->FindString(col) < 0) + { + cbColumns->Append(col, StrToOid(columns->GetText(pos, 7))); + } + } + } + if (table) + { + wxCookieType cookie; + pgObject *data; + wxTreeItemId columnsItem = mainForm->GetBrowser()->GetFirstChild(table->GetId(), cookie); + while (columnsItem) + { + data = mainForm->GetBrowser()->GetObject(columnsItem); + if (data->GetMetaType() == PGM_COLUMN && data->IsCollection()) + break; + columnsItem = mainForm->GetBrowser()->GetNextChild(table->GetId(), cookie); + } + + if (columnsItem) + { + wxCookieType cookie; + pgColumn *column; + wxTreeItemId item = mainForm->GetBrowser()->GetFirstChild(columnsItem, cookie); + + // check columns + while (item) + { + column = (pgColumn *)mainForm->GetBrowser()->GetObject(item); + if (column->IsCreatedBy(columnFactory)) + { + if (column->GetColNumber() > 0) + { + cbColumns->Append(column->GetName(), column->GetAttTypId()); + } + } + + item = mainForm->GetBrowser()->GetNextChild(columnsItem, cookie); + } + } + } + + return dlgProperty::Go(modal); +} + + + +///////////////////////////////////////////////////////////////////////////// + + +BEGIN_EVENT_TABLE(dlgSecurityProperty, dlgProperty) + EVT_BUTTON(CTL_ADDPRIV, dlgSecurityProperty::OnAddPriv) + EVT_BUTTON(CTL_DELPRIV, dlgSecurityProperty::OnDelPriv) +#ifdef __WXMAC__ + EVT_SIZE( dlgSecurityProperty::OnChangeSize) +#endif +END_EVENT_TABLE(); + +void dlgSecurityProperty::SetPrivilegesLayout() +{ + securityPage->lbPrivileges->GetParent()->Layout(); +} + +dlgSecurityProperty::dlgSecurityProperty(pgaFactory *f, frmMain *frame, pgObject *obj, const wxString &resName, const wxString &privList, const char *privChar) + : dlgProperty(f, frame, resName) +{ + securityChanged = false; + + + if (!privList.IsEmpty() && (!obj || obj->CanCreate())) + { + securityPage = new ctlSecurityPanel(nbNotebook, privList, privChar, frame->GetImageList()); + + if (obj) + { + + wxArrayString groups; + // Fetch Groups Information + pgSet *setGrp = obj->GetConnection()->ExecuteSet(wxT("SELECT groname FROM pg_group ORDER BY groname")); + + if (setGrp) + { + while (!setGrp->Eof()) + { + groups.Add(setGrp->GetVal(0)); + setGrp->MoveNext(); + } + delete setGrp; + } + + wxString str = obj->GetAcl(); + if (!str.IsEmpty()) + { + str = str.Mid(1, str.Length() - 2); + wxStringTokenizer tokens(str, wxT(",")); + + while (tokens.HasMoreTokens()) + { + wxString str = tokens.GetNextToken(); + if (str[0U] == '"') + str = str.Mid(1, str.Length() - 2); + + wxString name = str.BeforeLast('='); + wxString value; + + connection = obj->GetConnection(); + if (connection->BackendMinimumVersion(7, 4)) + value = str.Mid(name.Length() + 1).BeforeLast('/'); + else + value = str.Mid(name.Length() + 1); + + int icon = userFactory.GetIconId(); + + if (name.Left(6).IsSameAs(wxT("group "), false)) + { + icon = groupFactory.GetIconId(); + name = wxT("group ") + qtStrip(name.Mid(6)); + } + else if (name.IsEmpty()) + { + icon = PGICON_PUBLIC; + name = wxT("public"); + } + else + { + name = qtStrip(name); + for (unsigned int index = 0; index < groups.Count(); index++) + if (name == groups[index]) + { + name = wxT("group ") + name; + icon = groupFactory.GetIconId(); + break; + } + } + + securityPage->lbPrivileges->AppendItem(icon, name, value); + currentAcl.Add(name + wxT("=") + value); + } + } + else + { + int icon = PGICON_PUBLIC; + wxString name = wxT("public"); + wxString value; + if (obj->GetMetaType() == PGM_DATABASE) + value = wxT("Tc"); + else if (obj->GetMetaType() == PGM_FUNCTION) + value = wxT("X"); + else if (obj->GetMetaType() == PGM_LANGUAGE) + value = wxT("U"); + + if (value != wxEmptyString) + { + securityPage->lbPrivileges->AppendItem(icon, name, value); + currentAcl.Add(name + wxT("=") + value); + } + } + } + } + else + securityPage = NULL; +} + + +dlgSecurityProperty::~dlgSecurityProperty() +{ +} + + + +#ifdef __WXMAC__ +void dlgSecurityProperty::OnChangeSize(wxSizeEvent &ev) +{ + if (securityPage) + securityPage->lbPrivileges->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 550); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + + +int dlgSecurityProperty::Go(bool modal) +{ + if (securityPage) + { + if (cbOwner && !cbOwner->GetCount()) + { + if (!GetObject()) + cbOwner->Append(wxEmptyString); + AddGroups(cbOwner); + AddUsers(cbOwner); + } + + securityPage->SetConnection(connection); + //securityPage->Layout(); + } + + return dlgProperty::Go(modal); +} + + +void dlgSecurityProperty::AddGroups(ctlComboBox *comboBox) +{ + if (!((securityPage && securityPage->cbGroups) || comboBox)) + return; + + pgSet *set = connection->ExecuteSet(wxT("SELECT groname FROM pg_group ORDER BY groname")); + + if (set) + { + while (!set->Eof()) + { + if (securityPage && securityPage->cbGroups) + securityPage->cbGroups->Append(wxT("group ") + set->GetVal(0)); + if (comboBox) + comboBox->Append(set->GetVal(0)); + set->MoveNext(); + } + delete set; + } +} + + +void dlgSecurityProperty::AddUsers(ctlComboBox *combobox) +{ + if (securityPage && securityPage->cbGroups && settings->GetShowUsersForPrivileges()) + { + securityPage->stGroup->SetLabel(_("Group/User")); + dlgProperty::AddUsers(securityPage->cbGroups, combobox); + Layout(); + } + else + dlgProperty::AddUsers(combobox); +} + + +void dlgSecurityProperty::OnAddPriv(wxCommandEvent &ev) +{ + securityChanged = true; + EnableOK(btnOK->IsEnabled()); +} + + +void dlgSecurityProperty::OnDelPriv(wxCommandEvent &ev) +{ + securityChanged = true; + EnableOK(btnOK->IsEnabled()); +} + + +wxString dlgSecurityProperty::GetHelpPage() const +{ + if (nbNotebook->GetSelection() == (int)nbNotebook->GetPageCount() - 2) + return wxT("pg/sql-grant"); + else + return dlgProperty::GetHelpPage(); +} + + +void dlgSecurityProperty::EnableOK(bool enable, bool ignoreSql) +{ + // Don't enable the OK button if the object isn't yet created, + // leave that to the object dialog. + if (securityChanged && GetObject() && !ignoreSql) + { + wxString sql = GetSql(); + if (sql.IsEmpty()) + { + enable = false; + securityChanged = false; + } + else + enable = true; + } + dlgProperty::EnableOK(enable); +} + + +wxString dlgSecurityProperty::GetGrant(const wxString &allPattern, const wxString &grantObject) +{ + if (securityPage) + return securityPage->GetGrant(allPattern, grantObject, ¤tAcl); + else + return wxString(); +} + +bool dlgSecurityProperty::DisablePrivilege(const wxString &priv) +{ + if (securityPage) + return securityPage->DisablePrivilege(priv); + else + return true; +} + +void dlgSecurityProperty::AppendCurrentAcl(const wxString &name, const wxString &value) +{ + if (!(name.IsEmpty() && value.IsEmpty())) + currentAcl.Add(name + wxT("=") + value); +} + + +///////////////////////////////////////////////////////////////////////////// + + +BEGIN_EVENT_TABLE(dlgDefaultSecurityProperty, dlgSecurityProperty) + EVT_BUTTON(CTL_DEFADDPRIV, dlgDefaultSecurityProperty::OnAddPriv) + EVT_BUTTON(CTL_DEFDELPRIV, dlgDefaultSecurityProperty::OnDelPriv) +#ifdef __WXMAC__ + EVT_SIZE( dlgDefaultSecurityProperty::OnChangeSize) +#endif +END_EVENT_TABLE(); + + +dlgDefaultSecurityProperty::dlgDefaultSecurityProperty(pgaFactory *f, frmMain *frame, pgObject *obj, const wxString &resName, const wxString &privList, const char *privChar, bool createDefPrivPanel) + : dlgSecurityProperty(f, frame, obj, resName, privList, privChar), defaultSecurityChanged(false) +{ + pgConn *l_conn = obj ? obj->GetConnection() : connection; + if ((!obj || obj->CanCreate()) && createDefPrivPanel) + defaultSecurityPage = new ctlDefaultSecurityPanel(l_conn, nbNotebook, frame->GetImageList()); + else + defaultSecurityPage = NULL; +} + + +void dlgDefaultSecurityProperty::AddGroups(ctlComboBox *comboBox) +{ + if (!((securityPage && securityPage->cbGroups) || comboBox || defaultSecurityPage)) + return; + + pgSet *set = connection->ExecuteSet(wxT("SELECT groname FROM pg_group ORDER BY groname")); + + if (set) + { + while (!set->Eof()) + { + if (securityPage && securityPage->cbGroups) + securityPage->cbGroups->Append(wxT("group ") + set->GetVal(0)); + + if (comboBox) + comboBox->Append(set->GetVal(0)); + + if (defaultSecurityPage) + defaultSecurityPage->m_groups.Add(wxT("group ") + set->GetVal(0)); + + set->MoveNext(); + } + delete set; + } +} + + +void dlgDefaultSecurityProperty::AddUsers(ctlComboBox *combobox) +{ + if ((securityPage && securityPage->cbGroups) || defaultSecurityPage || combobox) + { + wxString strFetchUserQuery = + connection->BackendMinimumVersion(8, 1) ? + wxT("SELECT rolname FROM pg_roles WHERE rolcanlogin ORDER BY 1") : + wxT("SELECT usename FROM pg_user ORDER BY 1"); + + pgSet *set = connection->ExecuteSet(strFetchUserQuery); + if (set) + { + while (!set->Eof()) + { + if (settings->GetShowUsersForPrivileges()) + { + if (securityPage && securityPage->cbGroups) + securityPage->cbGroups->Append(set->GetVal(0)); + + if (defaultSecurityPage) + defaultSecurityPage->m_groups.Add(set->GetVal(0)); + } + + if (combobox) + combobox->Append(set->GetVal(0)); + + set->MoveNext(); + } + delete set; + } + } +} + +#ifdef __WXMAC__ +void dlgDefaultSecurityProperty::OnChangeSize(wxSizeEvent &ev) +{ + wxSize l_size = ev.GetSize(); + if (defaultSecurityPage && l_size.GetWidth() > 10 && l_size.GetHeight() > 25) + defaultSecurityPage->SetSize(l_size.GetWidth() - 10, l_size.GetHeight() - 25); + dlgSecurityProperty::OnChangeSize(ev); +} +#endif + + +void dlgDefaultSecurityProperty::EnableOK(bool enable, bool ignoreSql) +{ + // Don't enable the OK button if the object isn't yet created, + // leave that to the object dialog. + if (GetObject() && !ignoreSql) + { + wxString sql = GetSql(); + if (sql.IsEmpty()) + { + enable = false; + } + else + enable = true; + } + dlgSecurityProperty::EnableOK(enable, ignoreSql); +} + + +void dlgDefaultSecurityProperty::OnAddPriv(wxCommandEvent &ev) +{ + defaultSecurityChanged = true; + EnableOK(btnOK->IsEnabled()); +} + + +void dlgDefaultSecurityProperty::OnDelPriv(wxCommandEvent &ev) +{ + defaultSecurityChanged = true; + EnableOK(btnOK->IsEnabled()); +} + +wxString dlgDefaultSecurityProperty::GetDefaultPrivileges(const wxString &schemaName) +{ + if (defaultSecurityChanged) + return defaultSecurityPage->GetDefaultPrivileges(schemaName); + return wxT(""); +} + +int dlgDefaultSecurityProperty::Go(bool modal, bool createDefPrivs, const wxString &defPrivsOnTables, + const wxString &defPrivsOnSeqs, const wxString &defPrivsOnFuncs, + const wxString &defPrivsOnTypes) +{ + if (securityPage) + { + if (cbOwner && !cbOwner->GetCount()) + { + if (!GetObject()) + cbOwner->Append(wxEmptyString); + AddGroups(cbOwner); + AddUsers(cbOwner); + } + + securityPage->SetConnection(connection); + //securityPage->Layout(); + } + + int res = dlgSecurityProperty::Go(modal); + + if (defaultSecurityPage) + { + if (createDefPrivs && connection->BackendMinimumVersion(9, 0)) + defaultSecurityPage->UpdatePrivilegePages(createDefPrivs, defPrivsOnTables, + defPrivsOnSeqs, defPrivsOnFuncs, defPrivsOnTypes); + else + defaultSecurityPage->Enable(false); + } + + return res; +} + +wxString dlgDefaultSecurityProperty::GetHelpPage() const +{ + int nDiff = nbNotebook->GetPageCount() - nbNotebook->GetSelection(); + + switch (nDiff) + { + case 3: + return wxT("pg/sql-grant"); + case 2: + return wxT("pg/sql-alterdefaultprivileges"); + default: + return dlgProperty::GetHelpPage(); + } +} + +///////////////////////////////////////////////////////////////////////////// + + +BEGIN_EVENT_TABLE(dlgAgentProperty, dlgProperty) + EVT_BUTTON (wxID_OK, dlgAgentProperty::OnOK) +END_EVENT_TABLE(); + +dlgAgentProperty::dlgAgentProperty(pgaFactory *f, frmMain *frame, const wxString &resName) + : dlgProperty(f, frame, resName) +{ + recId = 0; +} + + +wxString dlgAgentProperty::GetSql() +{ + wxString str = GetInsertSql(); + if (!str.IsEmpty()) + str += wxT("\n\n"); + return str + GetUpdateSql(); +} + + + +bool dlgAgentProperty::executeSql() +{ + wxString sql; + bool dataChanged = false; + + sql = GetInsertSql(); + if (!sql.IsEmpty()) + { + int pos; + long jobId = 0, schId = 0, stpId = 0; + if (sql.Contains(wxT(""))) + { + recId = jobId = StrToLong(connection->ExecuteScalar(wxT("SELECT nextval('pgagent.pga_job_jobid_seq');"))); + while ((pos = sql.Find(wxT(""))) >= 0) + sql = sql.Left(pos) + NumToStr(jobId) + sql.Mid(pos + 7); + } + + if (sql.Contains(wxT(""))) + { + // Each schedule ID should be unique. This'll need work if a schedule hits more than + // one table or anything. + recId = schId = StrToLong(connection->ExecuteScalar(wxT("SELECT nextval('pgagent.pga_schedule_jscid_seq');"))); + while ((pos = sql.Find(wxT(""))) >= 0) + { + sql = sql.Left(pos) + NumToStr(schId) + sql.Mid(pos + 7); + recId = schId = StrToLong(connection->ExecuteScalar(wxT("SELECT nextval('pgagent.pga_schedule_jscid_seq');"))); + } + } + + if (sql.Contains(wxT(""))) + { + // Each step ID should be unique. This'll need work if a step hits more than + // one table or anything. + recId = stpId = StrToLong(connection->ExecuteScalar(wxT("SELECT nextval('pgagent.pga_jobstep_jstid_seq');"))); + while ((pos = sql.Find(wxT(""))) >= 0) + { + sql = sql.Left(pos) + NumToStr(stpId) + sql.Mid(pos + 7); + recId = stpId = StrToLong(connection->ExecuteScalar(wxT("SELECT nextval('pgagent.pga_jobstep_jstid_seq');"))); + } + } + + pgSet *set = connection->ExecuteSet(sql); + if (set) + { + delete set; + } + if (!set) + { + return false; + } + dataChanged = true; + } + + sql = GetUpdateSql(); + if (!sql.IsEmpty()) + { + int pos; + while ((pos = sql.Find(wxT(""))) >= 0) + sql = sql.Left(pos) + NumToStr(recId) + sql.Mid(pos + 7); + + long newId; + if (sql.Contains(wxT(""))) + { + // Each schedule ID should be unique. This'll need work if a schedule hits more than + // one table or anything. + newId = StrToLong(connection->ExecuteScalar(wxT("SELECT nextval('pgagent.pga_schedule_jscid_seq');"))); + while ((pos = sql.Find(wxT(""))) >= 0) + { + sql = sql.Left(pos) + NumToStr(newId) + sql.Mid(pos + 7); + newId = StrToLong(connection->ExecuteScalar(wxT("SELECT nextval('pgagent.pga_schedule_jscid_seq');"))); + } + } + + if (sql.Contains(wxT(""))) + { + // Each step ID should be unique. This'll need work if a step hits more than + // one table or anything. + newId = StrToLong(connection->ExecuteScalar(wxT("SELECT nextval('pgagent.pga_jobstep_jstid_seq');"))); + while ((pos = sql.Find(wxT(""))) >= 0) + { + sql = sql.Left(pos) + NumToStr(newId) + sql.Mid(pos + 7); + newId = StrToLong(connection->ExecuteScalar(wxT("SELECT nextval('pgagent.pga_jobstep_jstid_seq');"))); + } + } + + if (!connection->ExecuteVoid(sql)) + { + // error message is displayed inside ExecuteVoid + return false; + } + dataChanged = true; + } + + return dataChanged; +} + + +void dlgAgentProperty::OnOK(wxCommandEvent &ev) +{ +#ifdef __WXGTK__ + if (!btnOK->IsEnabled()) + return; +#endif + if (!IsUpToDate()) + { + if (wxMessageBox(wxT("The object has been changed by another user. Do you wish to continue to try to update it?"), wxT("Overwrite changes?"), wxYES_NO) != wxYES) + return; + } + + if (IsModal()) + { + EndModal(0); + return; + } + + connection->ExecuteVoid(wxT("BEGIN TRANSACTION")); + + if (executeSql()) + { + connection->ExecuteVoid(wxT("COMMIT TRANSACTION")); + ShowObject(); + } + else + { + connection->ExecuteVoid(wxT("ROLLBACK TRANSACTION")); + } + + Destroy(); +} + + +propertyFactory::propertyFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + if (mnu) + mnu->Append(id, _("&Properties...\tCtrl-Alt-Enter"), _("Display/edit the properties of the selected object.")); + else + context = false; + if (toolbar) + toolbar->AddTool(id, wxEmptyString, *properties_png_bmp, _("Display/edit the properties of the selected object."), wxITEM_NORMAL); +} + + +wxWindow *propertyFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (!dlgProperty::EditObjectDialog(form, form->GetSqlPane(), obj)) + form->CheckAlive(); + + return 0; +} + + +bool propertyFactory::CheckEnable(pgObject *obj) +{ + return obj && ((obj->GetMetaType() == PGM_DATABASE) ? (obj->GetConnection() != NULL) : true) && obj->CanEdit(); +} + + +#include "images/create.pngc" +createFactory::createFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, _("&Create..."), _("Create a new object of the same type as the selected object.")); + toolbar->AddTool(id, wxEmptyString, *create_png_bmp, _("Create a new object of the same type as the selected object."), wxITEM_NORMAL); +} + + +wxWindow *createFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (!dlgProperty::CreateObjectDialog(form, obj, 0)) + form->CheckAlive(); + + return 0; +} + + +bool createFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->CanCreate(); +} + + +#include "images/drop.pngc" +dropFactory::dropFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Delete/Drop...\tDel"), _("Delete/Drop the selected object.")); + toolbar->AddTool(id, wxEmptyString, *drop_png_bmp, _("Drop the currently selected object."), wxITEM_NORMAL); +} + + +wxWindow *dropFactory::StartDialog(frmMain *form, pgObject *obj) +{ + form->ExecDrop(false); + return 0; +} + + +bool dropFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->CanDrop(); +} + + +dropCascadedFactory::dropCascadedFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Drop cascaded..."), _("Drop the selected object and all objects dependent on it.")); +} + + +wxWindow *dropCascadedFactory::StartDialog(frmMain *form, pgObject *obj) +{ + form->ExecDrop(true); + return 0; +} + + +bool dropCascadedFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->CanDrop() && obj->CanDropCascaded(); +} + + +#include "images/refresh.pngc" +refreshFactory::refreshFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + if (mnu) + mnu->Append(id, _("Re&fresh\tF5"), _("Refresh the selected object.")); + else + context = false; + if (toolbar) + toolbar->AddTool(id, wxEmptyString, *refresh_png_bmp, _("Refresh the selected object."), wxITEM_NORMAL); +} + + +wxWindow *refreshFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (form) + obj = form->GetBrowser()->GetObject(form->GetBrowser()->GetSelection()); + + if (obj) + if (CheckEnable(obj)) + form->Refresh(obj); + return 0; +} + + +bool refreshFactory::CheckEnable(pgObject *obj) +{ + // This isn't really clean... But we don't have a pgObject::CanRefresh() so far, + // so it's Good Enough (tm) for now. + return obj != 0 && !obj->IsCreatedBy(serverFactory.GetCollectionFactory()); +} + diff --git a/dlg/dlgReassignDropOwned.cpp b/dlg/dlgReassignDropOwned.cpp new file mode 100644 index 0000000..95b3d97 --- /dev/null +++ b/dlg/dlgReassignDropOwned.cpp @@ -0,0 +1,122 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgReassignDropOwned.cpp - Reassign or drop owned objects +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/pgDefs.h" +#include "frm/frmMain.h" +#include "utils/misc.h" +#include "schema/pgRole.h" +#include "dlg/dlgReassignDropOwned.h" + + +// pointer to controls +#define rbReassignTo CTRL_RADIOBUTTON("rbReassignTo") +#define rbDrop CTRL_RADIOBUTTON("rbDrop") +#define cbRoles CTRL_COMBOBOX("cbRoles") +#define cbDatabases CTRL_COMBOBOX("cbDatabases") +#define btnOK CTRL_BUTTON("wxID_OK") + +BEGIN_EVENT_TABLE(dlgReassignDropOwned, pgDialog) + EVT_RADIOBUTTON(XRCID("rbReassignTo"), dlgReassignDropOwned::OnChange) + EVT_RADIOBUTTON(XRCID("rbDrop"), dlgReassignDropOwned::OnChange) + EVT_BUTTON(wxID_OK, dlgReassignDropOwned::OnOK) +END_EVENT_TABLE() + + +dlgReassignDropOwned::dlgReassignDropOwned(frmMain *win, pgConn *conn, + pgRole *role, wxString dbrestriction) +{ + wxString query; + + connection = conn; + parent = win; + + SetFont(settings->GetSystemFont()); + LoadResource(win, wxT("dlgReassignDropOwned")); + RestorePosition(); + + cbRoles->Clear(); + query = wxT("SELECT rolname FROM pg_roles WHERE rolname<>") + conn->qtDbString(role->GetName()) + wxT(" ORDER BY rolname"); + pgSetIterator roles(connection, query); + while (roles.RowsLeft()) + { + cbRoles->Append(roles.GetVal(wxT("rolname"))); + } + cbRoles->SetSelection(0); + cbRoles->Enable(cbRoles->GetStrings().Count() > 0); + + cbDatabases->Clear(); + query = wxT("SELECT DISTINCT datname FROM pg_database WHERE datallowconn"); + if (!dbrestriction.IsEmpty()) + { + query += wxT(" AND datname NOT IN (") + dbrestriction + wxT(")"); + } + query += wxT(" ORDER BY datname"); + + pgSetIterator databases(connection, query); + while (databases.RowsLeft()) + { + cbDatabases->Append(databases.GetVal(wxT("datname"))); + } + cbDatabases->SetSelection(0); + + if(rbReassignTo->GetValue() && cbRoles->GetStrings().Count() <= 0) + btnOK->Disable(); + + SetSize(330, 160); +} + +dlgReassignDropOwned::~dlgReassignDropOwned() +{ + SavePosition(); +} + + +void dlgReassignDropOwned::OnOK(wxCommandEvent &ev) +{ + EndModal(wxID_OK); +} + + +void dlgReassignDropOwned::OnCancel(wxCommandEvent &ev) +{ + EndModal(wxID_CANCEL); +} + +void dlgReassignDropOwned::OnChange(wxCommandEvent &ev) +{ + cbRoles->Enable(rbReassignTo->GetValue() && cbRoles->GetStrings().Count() > 0); + if(rbReassignTo->GetValue() && cbRoles->GetStrings().Count() <= 0) + btnOK->Disable(); + else + btnOK->Enable(); +} + +wxString dlgReassignDropOwned::GetDatabase() +{ + return cbDatabases->GetValue(); +} + +wxString dlgReassignDropOwned::GetRole() +{ + return cbRoles->GetValue(); +} + +bool dlgReassignDropOwned::IsReassign() +{ + return rbReassignTo->GetValue(); +} diff --git a/dlg/dlgResourceGroup.cpp b/dlg/dlgResourceGroup.cpp new file mode 100644 index 0000000..c7088fd --- /dev/null +++ b/dlg/dlgResourceGroup.cpp @@ -0,0 +1,170 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgResourceGroup.cpp - Resource Group Property +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dlg/dlgResourceGroup.h" +#include "schema/edbResourceGroup.h" + + +// pointer to controls +#define txtResGrpName CTRL_TEXT("txtResGrpName") +#define txtCPURate CTRL_TEXT("txtCPURate") +#define txtDirtyRate CTRL_TEXT("txtDirtyRate") + +dlgProperty *edbResourceGroupFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgResourceGroup(this, frame, (edbResourceGroup *)node); +} + + +BEGIN_EVENT_TABLE(dlgResourceGroup, dlgProperty) + EVT_TEXT(XRCID("txtCPURate"), dlgResourceGroup::OnChange) + EVT_TEXT(XRCID("txtDirtyRate"), dlgResourceGroup::OnChange) + EVT_BUTTON(wxID_OK, dlgResourceGroup::OnOK) +END_EVENT_TABLE(); + +dlgResourceGroup::dlgResourceGroup(pgaFactory *f, frmMain *frame, edbResourceGroup *node) + : dlgProperty(f, frame, wxT("dlgResourceGroup")) +{ + resourceGroup = node; + m_cpuRate = wxEmptyString; + m_dirtyRate = wxEmptyString; + m_isNameChange = false; +} + +pgObject *dlgResourceGroup::GetObject() +{ + return resourceGroup; +} + +int dlgResourceGroup::Go(bool modal) +{ + txtCPURate->SetValidator(numericValidator); + txtDirtyRate->SetValidator(numericValidator); + + if (resourceGroup) + { + wxString sql = wxT("SELECT rgrpcpuratelimit, rgrpdirtyratelimit from edb_resource_group WHERE rgrpname = '") + + resourceGroup->GetName() + wxT("'"); + + pgSet *set = connection->ExecuteSet(sql); + if (set && set->NumRows() > 0) + { + txtCPURate->SetValue(set->GetVal(0)); + txtDirtyRate->SetValue(set->GetVal(1)); + delete set; + } + } + else + { + txtCPURate->SetValue(wxT("0")); + txtDirtyRate->SetValue(wxT("0")); + } + + m_cpuRate = txtCPURate->GetValue(); + m_dirtyRate = txtDirtyRate->GetValue(); + + return dlgProperty::Go(modal); +} + +void dlgResourceGroup::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} + +void dlgResourceGroup::CheckChange() +{ + if (resourceGroup) + { + EnableOK(!GetSql().IsEmpty()); + } + else + { + wxString name = GetName(); + wxString cpuRate = txtCPURate->GetValue(); + wxString dirtyRate = txtDirtyRate->GetValue(); + + bool enable = true; + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, !cpuRate.IsEmpty(), _("Please specify CPU rate limit.")); + CheckValid(enable, !dirtyRate.IsEmpty(), _("Please specify Dirty rate limit.")); + + EnableOK(enable); + } +} + +pgObject *dlgResourceGroup::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + pgObject *obj = resourceGroupFactory.CreateObjects(collection, 0, wxT("\n WHERE rgrpname= ") + qtDbString(name)); + return obj; +} + +wxString dlgResourceGroup::GetSql() +{ + wxString sql = wxEmptyString; + wxString name = GetName(); + wxString cpuRate = txtCPURate->GetValue(); + wxString dirtyRate = txtDirtyRate->GetValue(); + + if (resourceGroup) + { + AppendNameChange(sql, wxT("RESOURCE GROUP ") + resourceGroup->GetQuotedFullIdentifier()); + + // Update the flag if resource group name is changed so that next + // ALTER command will be displayed in the second SQL text box. + m_isNameChange = !sql.IsEmpty(); + + // Check the "cpu rate/dirty rate" limit is changed or not + if (!m_isNameChange && (m_cpuRate.compare(cpuRate) != 0 || m_dirtyRate.compare(dirtyRate) != 0)) + { + sql += wxT("ALTER RESOURCE GROUP ") + qtIdent(name) + wxT(" SET cpu_rate_limit = ") + + cpuRate + wxT(", dirty_rate_limit = ") + dirtyRate + wxT(";\n"); + } + } + else + { + sql = wxT("CREATE RESOURCE GROUP ") + qtIdent(name) + wxT(";\n"); + } + + return sql; +} + +wxString dlgResourceGroup::GetSql2() +{ + wxString sql = wxEmptyString; + wxString name = GetName(); + wxString cpuRate = txtCPURate->GetValue(); + wxString dirtyRate = txtDirtyRate->GetValue(); + + if (!resourceGroup || m_isNameChange) + { + // Check the "cpu rate/dirty rate" limit is changed or not + if (m_cpuRate.compare(cpuRate) != 0 || m_dirtyRate.compare(dirtyRate) != 0) + { + sql = wxT("ALTER RESOURCE GROUP ") + qtIdent(name) + wxT(" SET cpu_rate_limit = ") + + cpuRate + wxT(", dirty_rate_limit = ") + dirtyRate + wxT(";\n"); + } + } + + return sql; +} + +void dlgResourceGroup::OnOK(wxCommandEvent &ev) +{ + dlgProperty::OnOK(ev); +} diff --git a/dlg/dlgRole.cpp b/dlg/dlgRole.cpp new file mode 100644 index 0000000..00f6b83 --- /dev/null +++ b/dlg/dlgRole.cpp @@ -0,0 +1,930 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRole.cpp - PostgreSQL Role Property +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "utils/misc.h" +#include "dlg/dlgRole.h" +#include "schema/pgRole.h" +#include "ctl/ctlSeclabelPanel.h" + + +// pointer to controls +#define txtPasswd CTRL_TEXT("txtPasswd") +#define txtRePasswd CTRL_TEXT("txtRePasswd") +#define datValidUntil CTRL_CALENDAR("datValidUntil") +#define timValidUntil CTRL_TIME("timValidUntil") +#define chkCanLogin CTRL_CHECKBOX("chkCanLogin") +#define chkSuperuser CTRL_CHECKBOX("chkSuperuser") +#define chkInherits CTRL_CHECKBOX("chkInherits") +#define chkCreateDB CTRL_CHECKBOX("chkCreateDB") +#define chkCreateRole CTRL_CHECKBOX("chkCreateRole") +#define chkUpdateCat CTRL_CHECKBOX("chkUpdateCat") +#define chkReplication CTRL_CHECKBOX("chkReplication") +#define txtConnectionLimit CTRL_TEXT("txtConnectionLimit") + +#define lbRolesNotIn CTRL_LISTBOX("lbRolesNotIn") +#define lbRolesIn CTRL_LISTBOX("lbRolesIn") +#define btnAddRole CTRL_BUTTON("btnAddRole") +#define btnDelRole CTRL_BUTTON("btnDelRole") +#define chkAdminOption CTRL_CHECKBOX("chkAdminOption") + +#define lstVariables CTRL_LISTVIEW("lstVariables") +#define btnAdd CTRL_BUTTON("wxID_ADD") +#define btnRemove CTRL_BUTTON("wxID_REMOVE") +#define cbVarname CTRL_COMBOBOX2("cbVarname") +#define cbVarDbname CTRL_COMBOBOX2("cbVarDbname") +#define txtValue CTRL_TEXT("txtValue") +#define chkValue CTRL_CHECKBOX("chkValue") + + + +dlgProperty *pgLoginRoleFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgRole(this, frame, (pgRole *)node, true); +} + +dlgProperty *pgGroupRoleFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgRole(this, frame, (pgRole *)node, false); +} + +BEGIN_EVENT_TABLE(dlgRole, dlgProperty) + EVT_CALENDAR_SEL_CHANGED(XRCID("datValidUntil"), dlgRole::OnChangeCal) + EVT_DATE_CHANGED(XRCID("datValidUntil"), dlgRole::OnChangeDate) + EVT_SPIN(XRCID("timValidUntil"), dlgRole::OnChangeSpin) + EVT_TEXT(XRCID("timValidUntil"), dlgRole::OnChange) + + EVT_LISTBOX_DCLICK(XRCID("lbRolesNotIn"), dlgRole::OnRoleAdd) + EVT_LISTBOX_DCLICK(XRCID("lbRolesIn"), dlgRole::OnRoleRemove) + EVT_TEXT(XRCID("txtPasswd"), dlgRole::OnChangePasswd) + EVT_TEXT(XRCID("txtRePasswd"), dlgRole::OnChangePasswd) + EVT_CHECKBOX(XRCID("chkCanLogin"), dlgRole::OnChange) + EVT_CHECKBOX(XRCID("chkInherits"), dlgRole::OnChange) + EVT_CHECKBOX(XRCID("chkCreateDB"), dlgRole::OnChange) + EVT_CHECKBOX(XRCID("chkUpdateCat"), dlgRole::OnChange) + EVT_CHECKBOX(XRCID("chkSuperuser"), dlgRole::OnChangeSuperuser) + EVT_CHECKBOX(XRCID("chkCreateRole"), dlgRole::OnChange) + EVT_CHECKBOX(XRCID("chkReplication"), dlgRole::OnChange) + EVT_TEXT(XRCID("txtConnectionLimit"), dlgRole::OnChange) + + EVT_BUTTON(XRCID("btnAddRole"), dlgRole::OnRoleAdd) + EVT_BUTTON(XRCID("btnDelRole"), dlgRole::OnRoleRemove) + + EVT_LIST_ITEM_SELECTED(XRCID("lstVariables"), dlgRole::OnVarSelChange) + EVT_BUTTON(wxID_ADD, dlgRole::OnVarAdd) + EVT_BUTTON(wxID_REMOVE, dlgRole::OnVarRemove) + EVT_TEXT(XRCID("cbVarname"), dlgRole::OnVarnameSelChange) + EVT_TEXT(XRCID("cbVarDbname"), dlgRole::OnVarnameSelChange) + EVT_COMBOBOX(XRCID("cbVarname"), dlgRole::OnVarnameSelChange) + + EVT_BUTTON(wxID_OK, dlgRole::OnOK) + +#ifdef __WXMAC__ + EVT_SIZE( dlgRole::OnChangeSize) +#endif +END_EVENT_TABLE(); + + + +dlgRole::dlgRole(pgaFactory *f, frmMain *frame, pgRole *node, bool chkLogin) + : dlgProperty(f, frame, wxT("dlgRole")) +{ + role = node; + lstVariables->CreateColumns(0, _("Database"), _("Variable"), _("Value"), -1); + btnOK->Disable(); + chkValue->Hide(); + if (chkLogin) + chkCanLogin->SetValue(true); + + seclabelPage = new ctlSeclabelPanel(nbNotebook); +} + + +pgObject *dlgRole::GetObject() +{ + return role; +} + + +#ifdef __WXMAC__ +void dlgRole::OnChangeSize(wxSizeEvent &ev) +{ + lstVariables->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + + +int dlgRole::Go(bool modal) +{ + +// In wxMac, the text deletion of "calenderBox" is not raising the EVT_CALENDAR_SEL_CHANGED, EVT_DATE_CHANGED events properly. +// Hence, raising these events with wxEVT_CHILD_FOCUS events. +// +#ifdef __WXMAC__ + + datValidUntil->Connect(wxEVT_CHILD_FOCUS, wxCommandEventHandler(dlgRole::OnChange), NULL, this); + timValidUntil->Connect(wxEVT_CHILD_FOCUS, wxCommandEventHandler(dlgRole::OnChange), NULL, this); + +#endif + + if (connection->BackendMinimumVersion(9, 0)) + { + cbVarDbname->Append(wxT("")); + AddDatabases(cbVarDbname); + } + else + { + cbVarDbname->Enable(false); + } + + if (connection->BackendMinimumVersion(9, 2)) + { + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(role); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgRole::OnChange)); + } + else + seclabelPage->Disable(); + + wxString roleSql = + wxT("SELECT rolname\n") + wxT(" FROM pg_roles r\n"); + + varInfo.Add(wxT("role")); + cbVarname->Append(wxT("role")); + + pgSet *set; + set = connection->ExecuteSet(wxT("SELECT name, vartype, min_val, max_val\n") + wxT(" FROM pg_settings WHERE context in ('user', 'superuser')")); + + if (set) + { + while (!set->Eof()) + { + cbVarname->Append(set->GetVal(0)); + varInfo.Add(set->GetVal(wxT("vartype")) + wxT(" ") + + set->GetVal(wxT("min_val")) + wxT(" ") + + set->GetVal(wxT("max_val"))); + set->MoveNext(); + } + delete set; + + cbVarname->SetSelection(0); + + if (connection->BackendMinimumVersion(9, 0)) + { + cbVarDbname->SetSelection(0); + } + + SetupVarEditor(0); + } + + if (role) + { + wxArrayString roles = role->GetRolesIn(); + size_t i; + for (i = 0 ; i < roles.GetCount() ; i++) + lbRolesIn->Append(roles.Item(i)); + + roleSql += + wxT(" LEFT JOIN pg_auth_members ON r.oid=roleid AND member = ") + role->GetOidStr() + wxT("\n") + wxT(" WHERE r.oid <> ") + role->GetOidStr() + wxT("\n") + wxT(" AND roleid IS NULL"); + + // Edit Mode + if (role->GetServer()->GetSuperUser() || role->GetServer()->GetCreateRole()) + readOnly = false; + else + readOnly = true; + + chkCreateDB->SetValue(role->GetCreateDatabase()); + chkCreateRole->SetValue(role->GetCreateRole()); + chkSuperuser->SetValue(role->GetSuperuser()); + chkInherits->SetValue(role->GetInherits()); + if (!connection->BackendMinimumVersion(9, 5)) + chkUpdateCat->SetValue(role->GetUpdateCatalog()); + else + chkUpdateCat->Disable(); + chkCanLogin->SetValue(role->GetCanLogin()); + chkReplication->SetValue(role->GetReplication()); + if (role->GetAccountExpires().IsValid() && role->GetAccountExpires().GetValue() != -1) + { + datValidUntil->SetValue(role->GetAccountExpires().GetDateOnly()); + timValidUntil->SetTime(role->GetAccountExpires()); + } + else + { + wxDateTime empty; + datValidUntil->SetValue(empty); + } + txtConnectionLimit->SetValue(NumToStr(role->GetConnectionLimit())); + txtComment->SetValue(role->GetComment()); + + size_t index; + wxString dbname; + wxString parameter; + wxString value; + for (index = 0 ; index < role->GetVariables().GetCount() ; index += 3) + { + dbname = role->GetVariables().Item(index); + parameter = role->GetVariables().Item(index + 1); + value = role->GetVariables().Item(index + 2); + + lstVariables->AppendItem(0, dbname, parameter, value); + } + + timValidUntil->Enable(!readOnly && role->GetAccountExpires().IsValid()); + + if (readOnly) + { + chkCanLogin->Disable(); + chkCreateDB->Disable(); + chkCreateRole->Disable(); + chkSuperuser->Disable(); + chkInherits->Disable(); + chkUpdateCat->Disable(); + chkReplication->Disable(); + datValidUntil->Disable(); + timValidUntil->Disable(); + btnAddRole->Disable(); + btnDelRole->Disable(); + cbVarname->Disable(); + cbVarDbname->Disable(); + txtValue->Disable(); + txtConnectionLimit->Disable(); + btnRemove->Disable(); + /* Its own password can be changed. */ + if (connection->GetUser() != role->GetName()) + { + txtPasswd->Disable(); + txtRePasswd->Disable(); + btnAdd->Disable(); + } + else + { + txtPasswd->Enable(); + txtRePasswd->Enable(); + btnAdd->Enable(); + } + } + } + else + { + chkCanLogin->Disable(); + wxDateTime empty; + datValidUntil->SetValue(empty); + timValidUntil->Disable(); + } + + // Role comments are only appropriate in 8.2+ + if (!connection->BackendMinimumVersion(8, 2)) + txtComment->Disable(); + + // Replication roles added in 9.1 + if (!connection->BackendMinimumVersion(9, 1)) + { + chkReplication->Disable(); + } + + + if (!settings->GetShowUsersForPrivileges()) + { + if (role) + roleSql += wxT("\n AND NOT rolcanlogin"); + else + roleSql += wxT("\n WHERE NOT rolcanlogin"); + } + roleSql += wxT("\n ORDER BY rolname"); + + pgSetIterator roles(connection, roleSql); + + while (roles.RowsLeft()) + lbRolesNotIn->Append(roles.GetVal(wxT("rolname"))); + + return dlgProperty::Go(modal); +} + + +wxString dlgRole::GetHelpPage() const +{ + if (nbNotebook->GetSelection() == 2) + return wxT("pg/runtime-config"); + else + return wxT("pg/sql-createrole"); +} + + +void dlgRole::OnOK(wxCommandEvent &ev) +{ + dlgProperty::OnOK(ev); + + if (role && ((role->GetCanLogin() != chkCanLogin->GetValue()) == !btnOK->IsEnabled())) + { + // LOGIN attribute changed successfully; need to put object under different collection + } +} + + +void dlgRole::OnChangeCal(wxCalendarEvent &ev) +{ + bool timEn = ev.GetDate().IsValid(); + timValidUntil->Enable(timEn); + if (!timEn) + timValidUntil->SetTime(wxDefaultDateTime); + else + timValidUntil->SetTime(wxDateTime::Today()); + + CheckChange(); +} + + +void dlgRole::OnChangeDate(wxDateEvent &ev) +{ + bool timEn = ev.GetDate().IsValid(); + timValidUntil->Enable(timEn); + if (!timEn) + timValidUntil->SetTime(wxDefaultDateTime); + else + timValidUntil->SetTime(wxDateTime::Today()); + + CheckChange(); +} + +void dlgRole::OnChangeSpin(wxSpinEvent &ev) +{ + CheckChange(); +} + + +void dlgRole::OnChangeSuperuser(wxCommandEvent &ev) +{ + if (role && role->GetSuperuser() && !chkSuperuser->GetValue()) + { + wxMessageDialog dlg(this, + _("Deleting a superuser might result in unwanted behaviour (e.g. when restoring the database).\nAre you sure?"), + _("Confirm superuser deletion"), + wxICON_EXCLAMATION | wxYES_NO | wxNO_DEFAULT); + if (dlg.ShowModal() != wxID_YES) + { + chkSuperuser->SetValue(true); + return; + } + } + chkUpdateCat->SetValue(chkSuperuser->GetValue() && + !connection->BackendMinimumVersion(9, 5)); + CheckChange(); +} + +void dlgRole::OnChangePasswd(wxCommandEvent &ev) +{ + CheckChange(); +} + +void dlgRole::CheckChange() +{ + bool enable = true; + bool timEn = datValidUntil->GetValue().IsValid(); + timValidUntil->Enable(timEn); + if (!timEn) + timValidUntil->SetTime(wxDefaultDateTime); + + if (!readOnly) + chkUpdateCat->Enable(chkSuperuser->GetValue() && + !connection->BackendMinimumVersion(9, 5)); + + // Check the passwords match + if (txtPasswd->GetValue() != txtRePasswd->GetValue()) + { + bool enable = true; + CheckValid(enable, false, _("The passwords entered do not match!")); + EnableOK(enable); + return; + } + + if (!role) + { + wxString name = GetName(); + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + } + else + { + enable = !GetSql().IsEmpty(); + if (seclabelPage && connection->BackendMinimumVersion(9, 2)) + enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); + } + EnableOK(enable); +} + + +void dlgRole::OnRoleAdd(wxCommandEvent &ev) +{ + if (!readOnly) + { + int pos = lbRolesNotIn->GetSelection(); + if (pos >= 0) + { + wxString roleName = lbRolesNotIn->GetString(pos); + if (chkAdminOption->GetValue()) + roleName += PGROLE_ADMINOPTION; + lbRolesIn->Append(roleName); + lbRolesNotIn->Delete(pos); + } + CheckChange(); + } +} + + +void dlgRole::OnRoleRemove(wxCommandEvent &ev) +{ + if (!readOnly) + { + int pos = lbRolesIn->GetSelection(); + if (pos >= 0) + { + wxString role = lbRolesIn->GetString(pos); + if (role.Right(PGROLE_ADMINOPTION_LEN) == PGROLE_ADMINOPTION) + role = role.Left(role.Length() - PGROLE_ADMINOPTION_LEN); + + lbRolesNotIn->Append(role); + lbRolesIn->Delete(pos); + } + CheckChange(); + } +} + + +void dlgRole::OnVarnameSelChange(wxCommandEvent &ev) +{ + int sel = cbVarname->GuessSelection(ev); + + SetupVarEditor(sel); +} + +void dlgRole::SetupVarEditor(int var) +{ + if (var >= 0 && varInfo.Count() > 0) + { + wxStringTokenizer vals(varInfo.Item(var)); + wxString typ = vals.GetNextToken(); + + if (typ == wxT("bool")) + { + txtValue->Hide(); + chkValue->Show(); + chkValue->GetParent()->Layout(); + } + else + { + chkValue->Hide(); + txtValue->Show(); + txtValue->GetParent()->Layout(); + if (typ == wxT("string") || typ == wxT("enum")) + txtValue->SetValidator(wxTextValidator()); + else + txtValue->SetValidator(numericValidator); + } + + } +} + +void dlgRole::OnVarSelChange(wxListEvent &ev) +{ + long pos = lstVariables->GetSelection(); + if (pos >= 0) + { + cbVarDbname->SetValue(lstVariables->GetText(pos)); + cbVarname->SetValue(lstVariables->GetText(pos, 1)); + + // We used to raise an OnVarnameSelChange() event here, but + // at this point the combo box hasn't necessarily updated. + wxString value = lstVariables->GetText(pos, 2); + int sel = cbVarname->FindString(lstVariables->GetText(pos, 1)); + + txtValue->SetValue(value); + chkValue->SetValue(value == wxT("on")); + } +} + + +void dlgRole::OnVarAdd(wxCommandEvent &ev) +{ + wxString dbname = cbVarDbname->GetValue(); + wxString name = cbVarname->GetValue(); + wxString value; + if (chkValue->IsShown()) + value = chkValue->GetValue() ? wxT("on") : wxT("off"); + else + value = txtValue->GetValue().Strip(wxString::both); + + if (value.IsEmpty()) + value = wxT("DEFAULT"); + + if (!name.IsEmpty()) + { + bool found = false; + long prevpos = -1; + for (long item = 0; item < lstVariables->GetItemCount(); item++) + { + if (name == lstVariables->GetText(item, 1)) + { + if (dbname == lstVariables->GetText(item)) + { + found = true; + lstVariables->SetItem(item, 2, value); + } + else + { + prevpos = item; + } + } + } + if (!found) + { + if (prevpos != -1) + { + lstVariables->InsertItem(prevpos, dbname, 1); + lstVariables->SetItem(prevpos, 1, name); + lstVariables->SetItem(prevpos, 2, value); + } + else + { + long pos = lstVariables->GetItemCount(); + lstVariables->InsertItem(pos, dbname, 1); + lstVariables->SetItem(pos, 1, name); + lstVariables->SetItem(pos, 2, value); + } + } + } + CheckChange(); +} + + +void dlgRole::OnVarRemove(wxCommandEvent &ev) +{ + if (lstVariables->GetSelection() == wxNOT_FOUND) + return; + lstVariables->DeleteCurrentItem(); + CheckChange(); +} + + +pgObject *dlgRole::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + pgObject *obj = loginRoleFactory.CreateObjects(collection, 0, wxT("\n WHERE rolname=") + qtDbString(name)); + return obj; +} + + +wxString dlgRole::GetSql() +{ + int pos; + wxString sql; + wxString name = GetName(); + + wxString passwd = txtPasswd->GetValue(); + bool createDB = chkCreateDB->GetValue(), + createRole = chkCreateRole->GetValue(), + superuser = chkSuperuser->GetValue(), + inherits = chkInherits->GetValue(), + canLogin = chkCanLogin->GetValue(), + replication = chkReplication->GetValue(); + + if (role) + { + // Edit Mode + + AppendNameChange(sql, wxT("ROLE ") + role->GetQuotedFullIdentifier()); + + + wxString options; + if (canLogin != role->GetCanLogin()) + { + if (canLogin) + options = wxT(" LOGIN"); + else + options = wxT(" NOLOGIN"); + } + if (canLogin && !passwd.IsEmpty()) + options += wxT(" ENCRYPTED PASSWORD ") + qtDbString(connection->EncryptPassword(name, passwd)); + + if (createDB != role->GetCreateDatabase() || createRole != role->GetCreateRole() + || superuser != role->GetSuperuser() || inherits != role->GetInherits() + || replication != role->GetReplication()) + { + options += wxT("\n "); + + if (superuser != role->GetSuperuser()) + { + if (superuser) + options += wxT(" SUPERUSER"); + else + options += wxT(" NOSUPERUSER"); + } + if (inherits != role->GetInherits()) + { + if (inherits) + options += wxT(" INHERIT"); + else + options += wxT(" NOINHERIT"); + } + if (createDB != role->GetCreateDatabase()) + { + if (createDB) + options += wxT(" CREATEDB"); + else + options += wxT(" NOCREATEDB"); + } + if (createRole != role->GetCreateRole()) + { + if (createRole) + options += wxT(" CREATEROLE"); + else + options += wxT(" NOCREATEROLE"); + } + if (connection->BackendMinimumVersion(9, 1)) + { + if (replication != role->GetReplication()) + { + if (replication) + options += wxT(" REPLICATION"); + else + options += wxT(" NOREPLICATION"); + } + } + } + if (!datValidUntil->GetValue().IsValid() || DateToStr(datValidUntil->GetValue() + timValidUntil->GetValue()) != DateToStr(role->GetAccountExpires())) + { + if (datValidUntil->GetValue().IsValid()) + options += wxT("\n VALID UNTIL ") + qtDbString(DateToAnsiStr(datValidUntil->GetValue() + timValidUntil->GetValue())); + else if (!role->GetIsValidInfinity() && role->GetAccountExpires().GetValue() != -1) + options += wxT("\n VALID UNTIL 'infinity'"); + } + + if (txtConnectionLimit->GetValue().Length() == 0) + { + if (role->GetConnectionLimit() != -1) + { + options += wxT(" CONNECTION LIMIT -1"); + } + } + else + { + if (txtConnectionLimit->GetValue() != NumToStr(role->GetConnectionLimit())) + { + options += wxT(" CONNECTION LIMIT ") + txtConnectionLimit->GetValue(); + } + } + + if (!options.IsNull()) + sql += wxT("ALTER ROLE ") + qtIdent(name) + options + wxT(";\n"); + + if (!connection->BackendMinimumVersion(9, 5) && + chkUpdateCat->GetValue() != role->GetUpdateCatalog()) + { + if (!connection->HasPrivilege(wxT("Table"), wxT("pg_authid"), wxT("update"))) + sql += wxT(" -- Can't update 'UpdateCatalog privilege: can't write to pg_authid.\n") + wxT("-- "); + + sql += wxT("UPDATE pg_authid SET rolcatupdate=") + BoolToStr(chkUpdateCat->GetValue()) + + wxT(" WHERE OID=") + role->GetOidStr() + wxT(";\n"); + } + int cnt = lbRolesIn->GetCount(); + wxArrayString tmpRoles = role->GetRolesIn(); + + // check for added roles + for (pos = 0 ; pos < cnt ; pos++) + { + wxString roleName = lbRolesIn->GetString(pos); + + int index = tmpRoles.Index(roleName); + if (index >= 0) + { + // role membership unchanged + tmpRoles.RemoveAt(index); + } + else + { + bool admin = false; + if (roleName.Right(PGROLE_ADMINOPTION_LEN) == PGROLE_ADMINOPTION) + { + admin = true; + roleName = roleName.Left(roleName.Length() - PGROLE_ADMINOPTION_LEN); + } + else + { + // new role membership without admin option + index = tmpRoles.Index(roleName + PGROLE_ADMINOPTION); + if (index >= 0) + { + // old membership with admin option + tmpRoles.RemoveAt(index); + sql += wxT("REVOKE ADMIN OPTION FOR ") + qtIdent(roleName) + + wxT(" FROM ") + qtIdent(name) + wxT(";\n"); + continue; + } + } + + index = tmpRoles.Index(roleName); + if (index >= 0) + { + // admin option added to existing membership + tmpRoles.RemoveAt(index); + } + + sql += wxT("GRANT ") + qtIdent(roleName) + + wxT(" TO ") + qtIdent(name); + + if (admin) + sql += wxT(" WITH ADMIN OPTION"); + + sql += wxT(";\n"); + } + } + + // check for removed roles + for (pos = 0 ; pos < (int)tmpRoles.GetCount() ; pos++) + { + sql += wxT("REVOKE ") + qtIdent(tmpRoles.Item(pos)) + + wxT(" FROM ") + qtIdent(name) + wxT(";\n"); + } + } + else + { + // Create Mode + sql = wxT( + "CREATE ROLE ") + qtIdent(name); + if (canLogin) + { + sql += wxT(" LOGIN"); + if (!passwd.IsEmpty()) + sql += wxT(" ENCRYPTED PASSWORD ") + qtDbString(connection->EncryptPassword(name, passwd)); + } + + if (createDB || createRole || !inherits || superuser) + sql += wxT("\n "); + if (superuser) + sql += wxT(" SUPERUSER"); + if (!inherits) + sql += wxT(" NOINHERIT"); + if (createDB) + sql += wxT(" CREATEDB"); + if (createRole) + sql += wxT(" CREATEROLE"); + if (connection->BackendMinimumVersion(9, 1)) + { + if (replication) + sql += wxT(" REPLICATION"); + } + if (datValidUntil->GetValue().IsValid()) + sql += wxT("\n VALID UNTIL ") + qtDbString(DateToAnsiStr(datValidUntil->GetValue() + timValidUntil->GetValue())); + else + sql += wxT("\n VALID UNTIL 'infinity'"); + + if (txtConnectionLimit->GetValue().Length() > 0) + { + sql += wxT(" CONNECTION LIMIT ") + txtConnectionLimit->GetValue(); + } + + int cnt = lbRolesIn->GetCount(); + wxString grants; + + if (cnt) + { + wxString roleName; + + for (pos = 0 ; pos < cnt ; pos++) + { + bool admin = false; + roleName = lbRolesIn->GetString(pos); + if (roleName.Right(PGROLE_ADMINOPTION_LEN) == PGROLE_ADMINOPTION) + { + roleName = roleName.Left(roleName.Length() - PGROLE_ADMINOPTION_LEN); + admin = true; + + } + grants += wxT("GRANT ") + qtIdent(roleName) + + wxT(" TO ") + qtIdent(name); + + if (admin) + grants += wxT(" WITH ADMIN OPTION;\n"); + else + grants += wxT(";\n"); + } + } + sql += wxT(";\n") + grants; + + if (superuser && !chkUpdateCat->GetValue() && + !connection->BackendMinimumVersion(9, 5)) + sql += wxT("UPDATE pg_authid SET rolcatupdate=false WHERE rolname=") + qtDbString(name) + wxT(";\n"); + } + + wxArrayString vars; + wxString dbname; + wxString parameter; + wxString value; + + size_t index; + + if (role) + { + for (index = 0 ; index < role->GetVariables().GetCount() ; index++) + vars.Add(role->GetVariables().Item(index)); + } + + int cnt = lstVariables->GetItemCount(); + + // check for changed or added vars + for (pos = 0 ; pos < cnt ; pos++) + { + wxString newDb = lstVariables->GetText(pos); + wxString newVar = lstVariables->GetText(pos, 1); + wxString newVal = lstVariables->GetText(pos, 2); + + wxString oldVal; + + for (index = 0 ; index < vars.GetCount() ; index += 3) + { + dbname = vars.Item(index); + parameter = vars.Item(index + 1); + value = vars.Item(index + 2); + + if (newDb == dbname && newVar == parameter) + { + oldVal = value; + vars.RemoveAt(index); + vars.RemoveAt(index); + vars.RemoveAt(index); + break; + } + } + if (oldVal != newVal) + { + if (newDb.Length() == 0) + sql += wxT("ALTER ROLE ") + qtIdent(name); + else + sql += wxT("ALTER ROLE ") + qtIdent(name) + wxT(" IN DATABASE ") + newDb; + + if (newVar != wxT("search_path") && newVar != wxT("temp_tablespaces")) + { + sql += wxT("\n SET ") + newVar + wxT(" = '") + newVal + wxT("';\n"); + } + else + { + sql += wxT("\n SET ") + newVar + wxT(" = ") + newVal + wxT(";\n"); + } + } + } + + // check for removed vars + for (pos = 0 ; pos < (int)vars.GetCount() ; pos += 3) + { + dbname = vars.Item(pos); + parameter = vars.Item(pos + 1); + value = vars.Item(pos + 2); + + if (dbname.Length() == 0) + { + sql += wxT("ALTER ROLE ") + qtIdent(name) + + wxT(" RESET ") + parameter + + wxT(";\n"); + } + else + { + sql += wxT("ALTER ROLE ") + qtIdent(name) + wxT(" IN DATABASE ") + dbname + + wxT(" RESET ") + parameter + wxT(";\n"); + } + } + + AppendComment(sql, wxT("ROLE"), 0, role); + + if (seclabelPage && connection->BackendMinimumVersion(9, 2)) + sql += seclabelPage->GetSqlForSecLabels(wxT("ROLE"), qtIdent(name)); + + return sql; +} + + +void dlgRole::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} diff --git a/dlg/dlgRule.cpp b/dlg/dlgRule.cpp new file mode 100644 index 0000000..32ced00 --- /dev/null +++ b/dlg/dlgRule.cpp @@ -0,0 +1,196 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRule.cpp - PostgreSQL View Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "ctl/ctlSQLBox.h" +#include "dlg/dlgRule.h" +#include "schema/pgRule.h" +#include "schema/pgTable.h" +#include "schema/pgCollection.h" + + + +// pointer to controls +#define rbxEvent CTRL_RADIOBOX("rbxEvent") +#define chkDoInstead CTRL_CHECKBOX("chkDoInstead") +#define txtCondition CTRL_TEXT("txtCondition") + +#define pnlDefinition CTRL_PANEL("pnlDefinition") +#define txtSqlBox CTRL_SQLBOX("txtSqlBox") + + +BEGIN_EVENT_TABLE(dlgRule, dlgProperty) + EVT_TEXT(XRCID("txtCondition"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkSelect"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkInsert"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkUpdate"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkDelete"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkDoInstead"), dlgProperty::OnChange) + EVT_RADIOBOX(XRCID("rbxEvent"), dlgProperty::OnChange) + EVT_STC_MODIFIED(XRCID("txtSqlBox"), dlgProperty::OnChangeStc) +END_EVENT_TABLE(); + + +dlgProperty *pgRuleFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgRule(this, frame, (pgRule *)node, (pgTable *)parent); +} + + + +dlgRule::dlgRule(pgaFactory *f, frmMain *frame, pgRule *node, pgTable *tab) + : dlgProperty(f, frame, wxT("dlgRule")) +{ + table = tab; + rule = node; +} + + +pgObject *dlgRule::GetObject() +{ + return rule; +} + + +int dlgRule::Go(bool modal) +{ + if (rule) + { + // edit mode + + oldDefinition = rule->GetFormattedDefinition(); + if (!oldDefinition.IsEmpty()) + { + int doPos = oldDefinition.Find(wxT(" DO INSTEAD ")); + if (doPos > 0) + oldDefinition = oldDefinition.Mid(doPos + 12).Strip(wxString::both); + else + { + doPos = oldDefinition.Find(wxT(" DO ")); + if (doPos > 0) + oldDefinition = oldDefinition.Mid(doPos + 4).Strip(wxString::both); + } + } + chkDoInstead->SetValue(rule->GetDoInstead()); + rbxEvent->SetStringSelection(rule->GetEvent()); + txtCondition->SetValue(rule->GetCondition()); + txtSqlBox->SetText(oldDefinition); + + txtName->Disable(); + } + else + { + // create mode + } + + // Reset the labels as they XRC values will have been localised :-( + rbxEvent->SetString(0, wxT("SELECT")); + rbxEvent->SetString(1, wxT("INSERT")); + rbxEvent->SetString(2, wxT("UPDATE")); + rbxEvent->SetString(3, wxT("DELETE")); + + return dlgProperty::Go(modal); +} + + +pgObject *dlgRule::CreateObject(pgCollection *collection) +{ + pgObject *obj = ruleFactory.CreateObjects(collection, 0, + wxT("\n AND rulename=") + qtDbString(GetName()) + + wxT("\n AND rw.ev_class=") + table->GetOidStr()); + return obj; +} + + +bool dlgRule::didChange() +{ + if (!rule) + return true; + + if (GetName() != rule->GetName()) + return true; + if (txtSqlBox->GetText().Strip(wxString::both) != oldDefinition) + return true; + if (chkDoInstead->GetValue() != rule->GetDoInstead()) + return true; + if (rbxEvent->GetStringSelection() != rule->GetEvent()) + return true; + if (txtCondition->GetValue() != rule->GetCondition()) + return true; + if (txtSqlBox->GetText() != oldDefinition) + return true; + + return false; +} + + +void dlgRule::CheckChange() +{ + if (rule) + { + EnableOK(didChange() || txtSqlBox->GetText() != oldDefinition || txtComment->GetValue() != rule->GetComment()); + } + else + { + wxString name = GetName(); + + bool enable = true; + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, rbxEvent->GetSelection() >= 0, + _("Please select at an event.")); + CheckValid(enable, !txtSqlBox->GetTextLength() || txtSqlBox->GetTextLength() > 6 , _("Please enter function definition.")); + + EnableOK(enable); + } +} + + +wxString dlgRule::GetSql() +{ + wxString sql, name = GetName(); + + + if (!rule || didChange()) + { + sql += wxT("CREATE OR REPLACE RULE ") + qtIdent(name) + + wxT(" AS\n ON ") + rbxEvent->GetStringSelection() + + wxT(" TO ") + table->GetQuotedFullIdentifier(); + AppendIfFilled(sql, wxT("\n WHERE ") , txtCondition->GetValue()); + + sql += wxT("\n DO "); + + if (chkDoInstead->GetValue()) + sql += wxT("INSTEAD "); + + if (txtSqlBox->GetTextLength()) + { + sql += wxT("\n") + txtSqlBox->GetText().Strip(wxString::both); + if (sql.Right(1) != wxT(";")) + sql += wxT(";"); + } + else + sql += wxT("NOTHING;"); + + sql += wxT("\n"); + } + AppendComment(sql, wxT("RULE ") + qtIdent(name) + + wxT(" ON ") + table->GetQuotedFullIdentifier(), rule); + return sql; +} + diff --git a/dlg/dlgSchema.cpp b/dlg/dlgSchema.cpp new file mode 100644 index 0000000..168340b --- /dev/null +++ b/dlg/dlgSchema.cpp @@ -0,0 +1,170 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgSchema.cpp - PostgreSQL Schema Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "dlg/dlgSchema.h" +#include "schema/pgSchema.h" +#include "ctl/ctlSeclabelPanel.h" + + +// pointer to controls + +BEGIN_EVENT_TABLE(dlgSchema, dlgDefaultSecurityProperty) +END_EVENT_TABLE(); + +dlgProperty *pgSchemaBaseFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgSchema(this, frame, (pgSchema *)node, parent); +} + +dlgSchema::dlgSchema(pgaFactory *f, frmMain *frame, pgSchema *node, pgObject *parent) + : dlgDefaultSecurityProperty(f, frame, node, wxT("dlgSchema"), wxT("USAGE,CREATE"), "UC", node != NULL ? true : false) +{ + schema = node; + seclabelPage = new ctlSeclabelPanel(nbNotebook); +} + + +pgObject *dlgSchema::GetObject() +{ + return schema; +} + + +int dlgSchema::Go(bool modal) +{ + wxString strDefPrivsOnTables, strDefPrivsOnSeqs, strDefPrivsOnFuncs, strDefPrivsOnTypes; + + if (connection->BackendMinimumVersion(9, 1)) + { + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(schema); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgSchema::OnChange)); + } + else + seclabelPage->Disable(); + + if (schema) + { + if (connection->BackendMinimumVersion(9, 0)) + { + strDefPrivsOnTables = schema->GetDefPrivsOnTables(); + strDefPrivsOnSeqs = schema->GetDefPrivsOnSequences(); + strDefPrivsOnFuncs = schema->GetDefPrivsOnFunctions(); + } + if (connection->BackendMinimumVersion(9, 2)) + strDefPrivsOnTypes = schema->GetDefPrivsOnTypes(); + + // edit mode + if (!connection->BackendMinimumVersion(7, 5)) + cbOwner->Disable(); + + if (schema->GetMetaType() == PGM_CATALOG) + { + cbOwner->Disable(); + txtName->Disable(); + } + } + else + { + // create mode + } + + return dlgDefaultSecurityProperty::Go(modal, true, strDefPrivsOnTables, strDefPrivsOnSeqs, strDefPrivsOnFuncs, strDefPrivsOnTypes); +} + + +pgObject *dlgSchema::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + pgObject *obj = schemaFactory.CreateObjects(collection, 0, wxT(" WHERE nspname=") + qtDbString(name) + wxT("\n")); + return obj; +} + + +#ifdef __WXMAC__ +void dlgSchema::OnChangeSize(wxSizeEvent &ev) +{ + SetPrivilegesLayout(); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + + +void dlgSchema::CheckChange() +{ + bool enable = true; + wxString name = GetName(); + + if (schema) + { + enable = name != schema->GetName() + || txtComment->GetValue() != schema->GetComment() + || cbOwner->GetValue() != schema->GetOwner(); + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); + } + else + { + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + } + + EnableOK(enable); +} + + + +wxString dlgSchema::GetSql() +{ + wxString sql, name; + name = qtIdent(GetName()); + + if (schema) + { + // edit mode + AppendNameChange(sql); + AppendOwnerChange(sql, wxT("SCHEMA ") + name); + } + else + { + // create mode + sql = wxT("CREATE SCHEMA ") + name; + AppendIfFilled(sql, wxT("\n AUTHORIZATION "), qtIdent(cbOwner->GetValue())); + sql += wxT(";\n"); + + } + AppendComment(sql, wxT("SCHEMA"), 0, schema); + + sql += GetGrant(wxT("UC"), wxT("SCHEMA ") + name); + + if (connection->BackendMinimumVersion(9, 0) && defaultSecurityChanged) + sql += GetDefaultPrivileges(name); + + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + sql += seclabelPage->GetSqlForSecLabels(wxT("SCHEMA"), name); + + return sql; +} + + +void dlgSchema::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} diff --git a/dlg/dlgSearchObject.cpp b/dlg/dlgSearchObject.cpp new file mode 100644 index 0000000..670c33a --- /dev/null +++ b/dlg/dlgSearchObject.cpp @@ -0,0 +1,971 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgSearchObject.h - Search dialogue +// +////////////////////////////////////////////////////////////////////////// + + +//AVANT DE LE COMMITER, IL FAUT AJOUTER LA MODIF DU PROJET VS2008 + +// App headers +#include "pgAdmin3.h" + +#include "frm/frmMain.h" +#include "dlg/dlgSearchObject.h" +#include "utils/sysSettings.h" +#include "utils/misc.h" +#include "ctl/ctlListView.h" + +#define txtPattern CTRL_TEXT("txtPattern") +#define cbType CTRL_COMBOBOX("cbType") +#define cbSchema CTRL_COMBOBOX("cbSchema") +#define lcResults CTRL_LISTCTRL("lcResults") +#define btnSearch CTRL_BUTTON("btnSearch") +#define chkNames CTRL_CHECKBOX("chkNames") +#define chkDefinitions CTRL_CHECKBOX("chkDefinitions") +#define chkComments CTRL_CHECKBOX("chkComments") + +BEGIN_EVENT_TABLE(dlgSearchObject, pgDialog) + EVT_BUTTON(wxID_HELP, dlgSearchObject::OnHelp) + EVT_BUTTON(XRCID("btnSearch"), dlgSearchObject::OnSearch) + EVT_BUTTON(wxID_CANCEL, dlgSearchObject::OnCancel) + EVT_TEXT(XRCID("txtPattern"), dlgSearchObject::OnChange) + EVT_COMBOBOX(XRCID("cbType"), dlgSearchObject::OnChange) + EVT_LIST_ITEM_SELECTED(XRCID("lcResults"), dlgSearchObject::OnSelSearchResult) + EVT_CHECKBOX(XRCID("chkNames"), dlgSearchObject::OnChange) + EVT_CHECKBOX(XRCID("chkDefinitions"), dlgSearchObject::OnChange) + EVT_CHECKBOX(XRCID("chkComments"), dlgSearchObject::OnChange) +END_EVENT_TABLE() + +dlgSearchObject::dlgSearchObject(frmMain *p, pgDatabase *db, pgObject *obj) +{ + parent = p; + header = wxT(""); + currentdb = db; + + SetFont(settings->GetSystemFont()); + LoadResource(p, wxT("dlgSearchObject")); + statusBar = XRCCTRL(*this, "unkStatusBar", wxStatusBar); + + // Icon + appearanceFactory->SetIcons(this); + RestorePosition(); + + ToggleBtnSearch(false); + + lcResults->InsertColumn(0, _("Type")); + lcResults->InsertColumn(1, _("Name")); + lcResults->InsertColumn(2, _("Path")); + + // Mapping table between local language and english, + // because in SQL we're using only english and translate it later + // to the local language. + + aMap[_("All types")] = wxT("All types"); + aMap[_("Schemas")] = wxT("Schemas"); + aMap[_("Tables")] = wxT("Tables"); + aMap[_("Columns")] = wxT("Columns"); + aMap[_("Triggers")] = wxT("Triggers"); + aMap[_("Views")] = wxT("Views"); + aMap[_("Rules")] = wxT("Rules"); + aMap[_("Indexes")] = wxT("Indexes"); + aMap[_("Functions")] = wxT("Functions"); + aMap[_("Aggregates")] = wxT("Aggregates"); + aMap[_("Trigger Functions")] = wxT("Trigger Functions"); + aMap[_("Constraints")] = wxT("Constraints"); + aMap[_("Sequences")] = wxT("Sequences"); + aMap[_("Types")] = wxT("Types"); + aMap[_("Domains")] = wxT("Domains"); + aMap[_("Languages")] = wxT("Languages"); + aMap[_("Conversions")] = wxT("Conversions"); + aMap[_("Casts")] = wxT("Casts"); + aMap[_("Login Roles")] = wxT("Login Roles"); + aMap[_("Group Roles")] = wxT("Group Roles"); + aMap[_("FTS Configurations")] = wxT("FTS Configurations"); + aMap[_("FTS Dictionaries")] = wxT("FTS Dictionaries"); + aMap[_("FTS Parsers")] = wxT("FTS Parsers"); + aMap[_("FTS Templates")] = wxT("FTS Templates"); + aMap[_("Foreign Data Wrappers")] = wxT("Foreign Data Wrappers"); + aMap[_("Foreign Servers")] = wxT("Foreign Servers"); + aMap[_("Foreign Tables")] = wxT("Foreign Tables"); + aMap[_("User Mappings")] = wxT("User Mappings"); + aMap[_("Operators")] = wxT("Operators"); + aMap[_("Operator Classes")] = wxT("Operator Classes"); + aMap[_("Operator Families")] = wxT("Operator Families"); + aMap[_("Extensions")] = wxT("Extensions"); + aMap[_("Collations")] = wxT("Collations"); + + cbType->Clear(); + cbType->Append(_("All types")); + cbType->Append(_("Schemas")); + cbType->Append(_("Tables")); + cbType->Append(_("Columns")); + cbType->Append(_("Triggers")); + cbType->Append(_("Views")); + cbType->Append(_("Rules")); + cbType->Append(_("Indexes")); + cbType->Append(_("Functions")); + cbType->Append(_("Aggregates")); + cbType->Append(_("Trigger Functions")); + cbType->Append(_("Constraints")); + cbType->Append(_("Sequences")); + cbType->Append(_("Types")); + cbType->Append(_("Languages")); + cbType->Append(_("Domains")); + cbType->Append(_("Conversions")); + cbType->Append(_("Casts")); + cbType->Append(_("Login Roles")); + cbType->Append(_("Group Roles")); + cbType->Append(_("FTS Configurations")); + cbType->Append(_("FTS Dictionaries")); + cbType->Append(_("FTS Parsers")); + cbType->Append(_("FTS Templates")); + if(currentdb->BackendMinimumVersion(8, 4)) + { + cbType->Append(_("Foreign Data Wrappers")); + cbType->Append(_("Foreign Servers")); + cbType->Append(_("User Mappings")); + } + if(currentdb->BackendMinimumVersion(9, 1)) + { + cbType->Append(_("Foreign Tables")); + } + cbType->Append(_("Operators")); + cbType->Append(_("Operator Classes")); + cbType->Append(_("Operator Families")); + + if(currentdb->BackendMinimumVersion(9, 1)) + { + cbType->Append(_("Extensions")); + cbType->Append(_("Collations")); + } + + cbSchema->Clear(); + cbSchema->Append(_("All schemas")); + cbSchema->Append(_("My schemas")); + + if (obj->GetSchema()) + { + if (obj->GetSchema()->GetSchema()) + currentSchema = obj->GetSchema()->GetSchema()->GetName(); + else + currentSchema = obj->GetSchema()->GetName(); + } + else if (obj->GetMetaType() == PGM_SCHEMA && !obj->IsCollection()) + currentSchema = obj->GetName(); + else + currentSchema = wxEmptyString; + + if (!currentSchema.IsEmpty()) + cbSchemaIdxCurrent = cbSchema->Append(wxString::Format(_("Current schema (%s)"), currentSchema.c_str())); + + wxString sql; + + sql = wxT("SELECT nsp.nspname") + wxT(" FROM pg_namespace nsp\n"); + if (!settings->GetShowSystemObjects()) + { + if (currentdb->BackendMinimumVersion(8, 1)) + sql += wxT(" WHERE nspname NOT LIKE E'pg\\\\_temp\\\\_%' AND nspname NOT LIKE E'pg\\\\_toast%'"); + else + sql += wxT(" WHERE nspname NOT LIKE 'pg\\\\_temp\\\\_%' AND nspname NOT LIKE 'pg\\\\_toast%'"); + } + sql += wxT(" ORDER BY nspname"); + + pgSet *set = currentdb->GetConnection()->ExecuteSet(sql); + if(set) + { + while(!set->Eof()) + { + cbSchema->Append(set->GetVal(wxT("nspname"))); + set->MoveNext(); + } + delete set; + } + + RestoreSettings(); + txtPattern->SetFocus(); +} + + +dlgSearchObject::~dlgSearchObject() +{ + SaveSettings(); + SavePosition(); +} + +void dlgSearchObject::SaveSettings() +{ + settings->Write(wxT("SearchObject/Pattern"), txtPattern->GetValue()); + settings->Write(wxT("SearchObject/Type"), aMap[cbType->GetValue()]); + settings->Write(wxT("SearchObject/Schema"), cbSchema->GetValue()); + settings->WriteBool(wxT("SearchObject/Names"), chkNames->GetValue()); + settings->WriteBool(wxT("SearchObject/Definitions"), chkDefinitions->GetValue()); + settings->WriteBool(wxT("SearchObject/Comments"), chkComments->GetValue()); +} + +wxString dlgSearchObject::getMapKeyByValue(wxString search_value) +{ + wxString key = wxEmptyString; + LngMapping::iterator it; + + for (it = aMap.begin(); it != aMap.end(); ++it) + { + if (search_value.IsSameAs(it->second)) + { + key = it->first; + break; + } + } + return key; +} + +void dlgSearchObject::RestoreSettings() +{ + wxString val, mapkey; + bool bVal; + + // Pattern + settings->Read(wxT("SearchObject/Pattern"), &val, wxEmptyString); + txtPattern->SetValue(val); + + // Type + settings->Read(wxT("SearchObject/Type"), &val, wxT("All types")); + mapkey = getMapKeyByValue(val); + if (cbType->FindString(mapkey, true) == wxNOT_FOUND) + cbType->SetValue(getMapKeyByValue(wxT("All types"))); + else + cbType->SetValue(mapkey); + + // Schema + settings->Read(wxT("SearchObject/Schema"), &val, wxT("All schemas")); + if (cbSchema->FindString(val, true) == wxNOT_FOUND) + cbSchema->SetValue(wxT("All schemas")); + else + cbSchema->SetValue(val); + + // names + settings->Read(wxT("SearchObject/Names"), &bVal, true); + chkNames->SetValue(bVal); + + // definitions + settings->Read(wxT("SearchObject/Definitions"), &bVal, false); + chkDefinitions->SetValue(bVal); + + // comments + settings->Read(wxT("SearchObject/Comments"), &bVal, false); + chkComments->SetValue(bVal); +} + +void dlgSearchObject::OnHelp(wxCommandEvent &ev) +{ + DisplayHelp(wxT("search_object"), HELP_PGADMIN); +} + +void dlgSearchObject::OnSelSearchResult(wxListEvent &ev) +{ + + long row_number = ev.GetIndex(); + + if(lcResults->GetItemTextColour(row_number) == wxColour(128, 128, 128)) + { + /* Result type is not enabled in settings, so we don't search for it in the tree */ + return; + } + + //Taken from: http://wiki.wxwidgets.org/WxListCtrl#Get_the_String_Contents_of_a_.22cell.22_in_a_LC_REPORT_wxListCtrl + wxListItem row_info; + wxString path; + + // Set what row it is (m_itemId is a member of the regular wxListCtrl class) + row_info.m_itemId = row_number; + // Set what column of that row we want to query for information. + row_info.m_col = 2; + // Set text mask + row_info.m_mask = wxLIST_MASK_TEXT; + + // Get the info and store it in row_info variable. + lcResults->GetItem(row_info); + + // Extract the text out that cell + path = row_info.m_text; + + + if(!parent->SetCurrentNode(parent->GetBrowser()->GetRootItem(), path)) + { + wxMessageBox(_("The specified object couldn't be found in the tree.")); + } + +} + +void dlgSearchObject::OnChange(wxCommandEvent &ev) +{ + ToggleBtnSearch(true); +} + +void dlgSearchObject::ToggleBtnSearch(bool enable) +{ + if(enable && + /* When someone searches for operators, the limit of 3 characters is ignored */ + (aMap[cbType->GetValue()] == wxT("Operators") || txtPattern->GetValue().Length() >= 3) && + // At least one search mode enabled + (chkNames->GetValue() || chkDefinitions->GetValue() || chkComments->GetValue())) + { + btnSearch->Enable(); + } + else + btnSearch->Disable(); +} + +void dlgSearchObject::OnSearch(wxCommandEvent &ev) +{ + if (!(chkNames->GetValue() || chkDefinitions->GetValue() || chkComments->GetValue())) + return; // should not happen + + wxBusyCursor wait; + ToggleBtnSearch(false); + if (statusBar) + statusBar->SetStatusText(_("Searching...")); + + wxString txtPatternStr; + if (txtPattern->GetValue().Contains(wxT("%"))) + txtPatternStr = currentdb->GetConnection()->qtDbString(txtPattern->GetValue().Lower()); + else + txtPatternStr = currentdb->GetConnection()->qtDbString(wxT("%") + txtPattern->GetValue().Lower() + wxT("%")); + + /* + Adding objects: + + Create a sql statement which lists all objects of the specified type and add it to the inner statement with an union. + We need four columns: type, objectname, path and nspname (schema name). If object is schemaless, set nspname to NULL. + Parts of the path which has to be translated to the local langauge (because of tree path) must begin with a colon. + Append the type to the combobox and the mapping table in the constructor. */ + + wxString databasePath = parent->GetNodePath(currentdb->GetDatabase()->GetId()); + wxString searchSQL = wxT("SELECT * FROM ( "); + + bool nextMode = false; + // search names + if (chkNames->GetValue()) + { + if (nextMode) + searchSQL += wxT("UNION \n"); + nextMode = true; + searchSQL += wxT("SELECT * FROM ( ") + wxT(" SELECT ") + wxT(" CASE ") + wxT(" WHEN c.relkind = 'r' THEN 'Tables' ") + wxT(" WHEN c.relkind = 'S' THEN 'Sequences' ") + wxT(" WHEN c.relkind IN ('v','m') THEN 'Views' ") + wxT(" ELSE 'should not happen' ") + wxT(" END AS type, c.relname AS objectname, ") + wxT(" ':Schemas/' || n.nspname || '/' || ") + wxT(" CASE ") + wxT(" WHEN c.relkind = 'r' THEN ':Tables' ") + wxT(" WHEN c.relkind = 'S' THEN ':Sequences' ") + wxT(" WHEN c.relkind IN ('v','m') THEN ':Views' ") + wxT(" ELSE 'should not happen' ") + wxT(" END || '/' || c.relname AS path, n.nspname ") + wxT(" FROM pg_class c ") + wxT(" LEFT JOIN pg_namespace n ON n.oid = c.relnamespace ") + wxT(" WHERE c.relkind in ('r','S','v','m') ") + wxT(" UNION ") + wxT(" SELECT 'Indexes', cls.relname, ':Schemas/' || n.nspname || '/:Tables/' || tab.relname || '/:Indexes/' || cls.relname, n.nspname ") + wxT(" FROM pg_index idx ") + wxT(" JOIN pg_class cls ON cls.oid=indexrelid ") + wxT(" JOIN pg_class tab ON tab.oid=indrelid ") + wxT(" JOIN pg_namespace n ON n.oid=tab.relnamespace ") + wxT(" LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i') ") + wxT(" LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid) ") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid ") + wxT(" LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0) ") + wxT(" WHERE contype IS NULL ") + wxT(" UNION ") + wxT(" SELECT CASE WHEN t.typname = 'trigger' THEN 'Trigger Functions' ELSE 'Functions' END AS type, p.proname, ") + wxT(" ':Schemas/' || n.nspname || '/' || case when t.typname = 'trigger' then ':Trigger Functions' else ':Functions' end || '/' || p.proname, n.nspname ") + wxT(" from pg_proc p ") + wxT(" left join pg_namespace n on p.pronamespace = n.oid ") + wxT(" left join pg_type t on p.prorettype = t.oid ") + wxT(" union ") + wxT(" select 'Schemas', nspname, ':Schemas/' || nspname, nspname from pg_namespace ") + wxT(" union ") + wxT(" select 'Columns', a.attname, ") + wxT(" ':Schemas/' || n.nspname || '/' || ") + wxT(" case ") + wxT(" when t.relkind = 'r' then ':Tables' ") + wxT(" when t.relkind = 'S' then ':Sequences' ") + wxT(" when t.relkind in ('v','m') then ':Views' ") + wxT(" else 'should not happen' ") + wxT(" end || '/' || t.relname || '/:Columns/' || a.attname AS path, n.nspname ") + wxT(" from pg_attribute a ") + wxT(" inner join pg_class t on a.attrelid = t.oid and t.relkind in ('r','v','m') ") + wxT(" left join pg_namespace n on t.relnamespace = n.oid where a.attnum > 0 ") + wxT(" union ") + wxT(" select 'Constraints', case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end, ':Schemas/' || n.nspname||'/:Tables/'||t.relname||'/:Constraints/'||case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end, n.nspname from pg_constraint c ") + wxT(" left join pg_class t on c.conrelid = t.oid ") + wxT(" left join pg_class tf on c.confrelid = tf.oid ") + wxT(" left join pg_namespace n on t.relnamespace = n.oid ") + wxT(" union ") + wxT(" select 'Rules', r.rulename, ':Schemas/' || n.nspname||case when t.relkind in ('v','m') then '/:Views/' else '/:Tables/' end||t.relname||'/:Rules/'|| r.rulename, n.nspname from pg_rewrite r ") + wxT(" left join pg_class t on r.ev_class = t.oid ") + wxT(" left join pg_namespace n on t.relnamespace = n.oid ") + wxT(" union ") + wxT(" select 'Triggers', tr.tgname, ':Schemas/' || n.nspname||case when t.relkind in ('v','m') then '/:Views/' else '/:Tables/' end||t.relname || '/:Triggers/' || tr.tgname, n.nspname from pg_trigger tr ") + wxT(" left join pg_class t on tr.tgrelid = t.oid ") + wxT(" left join pg_namespace n on t.relnamespace = n.oid ") + wxT(" where "); + if(currentdb->BackendMinimumVersion(9, 0)) + searchSQL += wxT(" tr.tgisinternal = false "); + else + searchSQL += wxT(" tr.tgisconstraint = false "); + searchSQL += wxT(" union ") + wxT(" SELECT 'Types', t.typname, ':Schemas/' || n.nspname || '/:Types/' || t.typname, n.nspname ") + wxT(" FROM pg_type t ") + wxT(" LEFT OUTER JOIN pg_type e ON e.oid=t.typelem ") + wxT(" LEFT OUTER JOIN pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c' ") + wxT(" LEFT OUTER JOIN pg_namespace n on t.typnamespace = n.oid ") + wxT(" WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\\\_%' "); + if (!settings->GetShowSystemObjects()) + searchSQL += wxT(" AND ct.oid IS NULL\n"); + searchSQL += wxT(" union ") + wxT(" SELECT 'Conversions', co.conname, ':Schemas/' || n.nspname || '/:Conversions/' || co.conname, n.nspname ") + wxT(" FROM pg_conversion co ") + wxT(" JOIN pg_namespace n ON n.oid=co.connamespace ") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=co.oid AND des.objsubid=0 ") + wxT(" union ") + wxT(" SELECT 'Casts', format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod), ':Casts/' || format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod), NULL as nspname ") + wxT(" FROM pg_cast ca ") + wxT(" JOIN pg_type st ON st.oid=castsource ") + wxT(" JOIN pg_type tt ON tt.oid=casttarget ") + wxT(" union ") + wxT(" SELECT 'Languages', lanname, ':Languages/' || lanname, NULL as nspname ") + wxT(" FROM pg_language lan ") + wxT(" WHERE lanispl IS TRUE ") + wxT(" union ") + wxT(" SELECT 'FTS Configurations', cfg.cfgname, ':Schemas/' || n.nspname || '/:FTS Configurations/' || cfg.cfgname, n.nspname ") + wxT(" FROM pg_ts_config cfg ") + wxT(" left join pg_namespace n on cfg.cfgnamespace = n.oid ") + wxT(" union ") + wxT(" SELECT 'FTS Dictionaries', dict.dictname, ':Schemas/' || ns.nspname || '/:FTS Dictionaries/' || dict.dictname, ns.nspname ") + wxT(" FROM pg_ts_dict dict ") + wxT(" left join pg_namespace ns on dict.dictnamespace = ns.oid ") + wxT(" union ") + wxT(" SELECT 'FTS Parsers', prs.prsname, ':Schemas/' || ns.nspname || '/:FTS Parsers/' || prs.prsname, ns.nspname ") + wxT(" FROM pg_ts_parser prs ") + wxT(" left join pg_namespace ns on prs.prsnamespace = ns.oid ") + wxT(" union ") + wxT(" SELECT 'FTS Templates', tmpl.tmplname, ':Schemas/' || ns.nspname || '/:FTS Templates/' || tmpl.tmplname, ns.nspname ") + wxT(" FROM pg_ts_template tmpl ") + wxT(" left join pg_namespace ns on tmpl.tmplnamespace = ns.oid ") + wxT(" union ") + wxT(" select 'Domains', t.typname, ':Schemas/' || n.nspname || '/:Domains/' || t.typname, n.nspname from pg_type t ") + wxT(" inner join pg_namespace n on t.typnamespace = n.oid ") + wxT(" where t.typtype = 'd' ") + wxT(" union ") + wxT(" select 'Aggregates', pr.proname, ':Schemas/' || ns.nspname || '/:Aggregates/' || pr.proname , ns.nspname from pg_catalog.pg_aggregate ag ") + wxT(" inner join pg_proc pr on ag.aggfnoid = pr.oid ") + wxT(" left join pg_namespace ns on pr.pronamespace = ns.oid ") + wxT(" union ") + wxT(" select case when rolcanlogin = true then 'Login Roles' else 'Group Roles' end, rolname, case when rolcanlogin = true then ':Login Roles' else ':Group Roles' end || '/' || rolname, NULL as nspname ") + wxT(" from pg_roles ") + wxT(" union ") + wxT(" select 'Tablespaces', spcname, ':Tablespaces/'||spcname, NULL as nspname from pg_tablespace ") + wxT(" union ") + wxT(" SELECT 'Operators', op.oprname, ':Schemas/' || ns.nspname || '/:Operators/' || op.oprname, ns.nspname ") + wxT(" FROM pg_operator op ") + wxT(" left join pg_namespace ns on op.oprnamespace = ns.oid ") + wxT(" union ") + wxT(" SELECT 'Operator Classes', op.opcname, ':Schemas/' || ns.nspname || '/:Operator Classes/' || op.opcname, ns.nspname ") + wxT(" FROM pg_opclass op ") + wxT(" left join pg_namespace ns on op.opcnamespace = ns.oid ") + wxT(" union ") + wxT(" SELECT 'Operator Families', opf.opfname, ':Schemas/' || ns.nspname || '/:Operator Families/' || opf.opfname, ns.nspname ") + wxT(" FROM pg_opfamily opf ") + wxT(" left join pg_namespace ns on opf.opfnamespace = ns.oid "); + + if(currentdb->BackendMinimumVersion(8, 4) && currentdb->GetConnection()->IsSuperuser()) + { + searchSQL += wxT(" union ") + wxT(" select 'Foreign Data Wrappers', fdwname, ':Foreign Data Wrappers/' || fdwname, NULL as nspname from pg_foreign_data_wrapper ") + wxT(" union ") + wxT(" select 'Foreign Server', sr.srvname, ':Foreign Data Wrappers/' || fdw.fdwname || '/:Foreign Servers/' || sr.srvname, NULL as nspname from pg_foreign_server sr ") + wxT(" inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid ") + wxT(" union ") + wxT(" select 'User Mappings', ro.rolname, ':Foreign Data Wrappers/' || fdw.fdwname || '/:Foreign Servers/' || sr.srvname || '/:User Mappings/' || ro.rolname, NULL as nspname from pg_user_mapping um ") + wxT(" inner join pg_roles ro on um.umuser = ro.oid ") + wxT(" inner join pg_foreign_server sr on um.umserver = sr.oid ") + wxT(" inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid "); + } + + if(currentdb->BackendMinimumVersion(9, 1)) + { + searchSQL += wxT(" union ") + wxT(" select 'Foreign Tables', c.relname, ':Schemas/' || ns.nspname || '/:Foreign Tables/' || c.relname, ns.nspname from pg_foreign_table ft ") + wxT(" inner join pg_class c on ft.ftrelid = c.oid ") + wxT(" inner join pg_namespace ns on c.relnamespace = ns.oid ") + wxT(" union ") + wxT(" select 'Extensions', x.extname, ':Extensions/' || x.extname, NULL as nspname ") + wxT(" FROM pg_extension x ") + wxT(" JOIN pg_namespace n on x.extnamespace=n.oid ") + wxT(" join pg_available_extensions() e(name, default_version, comment) ON x.extname=e.name ") + wxT(" union ") + wxT(" SELECT 'Collations', c.collname, ':Schemas/' || n.nspname || '/:Collations/' || c.collname, n.nspname ") + wxT(" FROM pg_collation c ") + wxT(" JOIN pg_namespace n ON n.oid=c.collnamespace "); + } + + searchSQL += wxT(") sn \n") + wxT("where lower(sn.objectname) like ") + txtPatternStr + wxT(" \n"); + } // search names + + // search definitions + if (chkDefinitions->GetValue()) + { + if (nextMode) + searchSQL += wxT("UNION \n"); + nextMode = true; + searchSQL += wxT("SELECT * FROM ( ") // Function's source code + wxT(" SELECT CASE WHEN t.typname = 'trigger' THEN 'Trigger Functions' ELSE 'Functions' END AS type, p.proname as objectname, ") + wxT(" ':Schemas/' || n.nspname || '/' || case when t.typname = 'trigger' then ':Trigger Functions' else ':Functions' end || '/' || p.proname as path, n.nspname ") + wxT(" from pg_proc p ") + wxT(" left join pg_namespace n on p.pronamespace = n.oid ") + wxT(" left join pg_type t on p.prorettype = t.oid ") + wxT("WHERE p.prosrc ILIKE ") + txtPatternStr + wxT(" ") + wxT("UNION ") // Column's type name and default value + wxT("select 'Columns', a.attname, ") + wxT("':Schemas/' || n.nspname || '/' || ") + wxT("case ") + wxT(" when t.relkind = 'r' then ':Tables' ") + wxT(" when t.relkind = 'S' then ':Sequences' ") + wxT(" when t.relkind in ('v','m') then ':Views' ") + wxT(" else 'should not happen' ") + wxT("end || '/' || t.relname || '/:Columns/' || a.attname AS path, n.nspname ") + wxT("from pg_attribute a ") + wxT("inner join pg_type ty on a.atttypid = ty.oid ") + wxT("left join pg_attrdef ad on a.attrelid = ad.adrelid and a.attnum = ad.adnum ") + wxT("inner join pg_class t on a.attrelid = t.oid and t.relkind in ('r','v','m') ") + wxT("left join pg_namespace n on t.relnamespace = n.oid ") + wxT("where a.attnum > 0 ") + wxT(" and (ty.typname ilike ") + txtPatternStr + wxT(" or ad.adsrc ilike ") + txtPatternStr + wxT(") ") + wxT("UNION ") // View's definition + wxT("SELECT 'Views', c.relname, ") + wxT("':Schemas/' || n.nspname || '/:Views/' || c.relname, n.nspname ") + wxT(" FROM pg_class c ") + wxT(" LEFT JOIN pg_namespace n ON n.oid = c.relnamespace ") + wxT(" WHERE c.relkind IN ('v','m') ") + wxT(" and pg_get_viewdef(c.oid) ilike ") + txtPatternStr + wxT(" ") + wxT("UNION ") // Relation's column names except for Views (searched earlier) + wxT("SELECT CASE ") + wxT(" WHEN c.relkind = 'c' THEN 'Types' ") + wxT(" WHEN c.relkind = 'r' THEN 'Tables' ") + wxT(" WHEN c.relkind = 'f' THEN 'Foreign Tables' ") + wxT(" ELSE 'should not happen' ") + wxT(" END AS type, c.relname AS objectname, ") + wxT(" ':Schemas/' || n.nspname || '/' || ") + wxT(" CASE ") + wxT(" WHEN c.relkind = 'c' THEN ':Types' ") + wxT(" WHEN c.relkind = 'r' THEN ':Tables' ") + wxT(" WHEN c.relkind = 'f' THEN ':Foreign Tables' ") + wxT(" ELSE 'should not happen' ") + wxT(" END || '/' || c.relname AS path, n.nspname ") + wxT(" from pg_attribute a ") + wxT(" inner join pg_class c on a.attrelid = c.oid and c.relkind in ('c','r','f') ") + wxT(" left join pg_namespace n on c.relnamespace = n.oid ") + wxT(" where a.attname ilike ") + txtPatternStr + wxT(" "); + // TODO: search for other object's definitions (indexes, constraints and so on) + searchSQL += wxT(") sd \n"); + } // search definitions + + // search comments + if (chkComments->GetValue()) + { + if (nextMode) + searchSQL += wxT("UNION \n"); + nextMode = true; + + wxString pd = wxT("(select pd.objoid, pd.classoid, pd.objsubid, c.relname") + wxT(" from pg_description pd") + wxT(" join pg_class c on pd.classoid = c.oid") + wxT(" where pd.description ilike ") + txtPatternStr + wxT(" UNION ") + wxT("select psd.objoid, psd.classoid, NULL as objsubid, c.relname") + wxT(" from pg_shdescription psd") + wxT(" join pg_class c on psd.classoid = c.oid") + wxT(" where psd.description ilike ") + txtPatternStr + wxT(") "); + + searchSQL += wxT("SELECT * FROM ( "); + if(currentdb->BackendMinimumVersion(8, 4)) // Common Table Expressions are available + { + searchSQL += wxT("with pd as ") + pd; + pd = wxT("pd "); + } + else // use pd as a subquery + pd += wxT(" pd "); + + searchSQL += wxT("SELECT CASE") + wxT(" WHEN c.relkind = 'r' THEN 'Tables'") + wxT(" WHEN c.relkind = 'S' THEN 'Sequences'") + wxT(" WHEN c.relkind IN ('v','m') THEN 'Views'") + wxT(" ELSE 'should not happen'") + wxT(" END AS type, c.relname AS objectname,") + wxT(" ':Schemas/' || n.nspname || '/' ||") + wxT(" CASE") + wxT(" WHEN c.relkind = 'r' THEN ':Tables'") + wxT(" WHEN c.relkind = 'S' THEN ':Sequences'") + wxT(" WHEN c.relkind IN ('v','m') THEN ':Views'") + wxT(" ELSE 'should not happen'") + wxT(" END || '/' || c.relname AS path, n.nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_class c on pd.relname = 'pg_class' and pd.objoid = c.oid") + wxT(" LEFT JOIN pg_namespace n ON n.oid = c.relnamespace") + wxT(" WHERE c.relkind in ('r','S','v','m')") + wxT(" UNION") + wxT(" SELECT 'Indexes', cls.relname, ':Schemas/' || n.nspname || '/:Tables/' || tab.relname || '/:Indexes/' || cls.relname, n.nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_class cls ON pd.relname = 'pg_class' and pd.objoid = cls.oid") + wxT(" JOIN pg_index idx ON cls.oid=indexrelid") + wxT(" JOIN pg_class tab ON tab.oid=indrelid") + wxT(" JOIN pg_namespace n ON n.oid=tab.relnamespace") + wxT(" LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i')") + wxT(" LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid") + wxT(" LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0)") + wxT(" WHERE contype IS NULL") + wxT(" UNION") + wxT(" select case when p_t.typname = 'trigger' THEN 'Trigger Functions' ELSE 'Functions' end as type,") + wxT(" p_.proname AS objectname,") + wxT(" ':Schemas/' || n.nspname || '/' ||") + wxT(" case when p_t.typname = 'trigger' then ':Trigger Functions/' else ':Functions/' end || p_.proname AS path, n.nspname") + wxT(" from ") + pd + + wxT(" join pg_proc p_ on pd.relname = 'pg_proc' and pd.objoid = p_.oid and p_.prokind <> 'a'") + wxT(" left join pg_type p_t on p_.prorettype = p_t.oid") + wxT(" left join pg_namespace n on p_.pronamespace = n.oid") + wxT(" union") + wxT(" select 'Schemas', n_.nspname, ':Schemas/' || n_.nspname, n_.nspname") + wxT(" from ") + pd + + wxT(" join pg_namespace n_ on pd.relname = 'pg_namespace' and pd.objoid = n_.oid") + wxT(" union") + wxT(" select 'Columns', a.attname,") + wxT(" ':Schemas/' || n.nspname || '/' ||") + wxT(" case") + wxT(" when t.relkind = 'r' then ':Tables'") + wxT(" when t.relkind = 'S' then ':Sequences'") + wxT(" when t.relkind in ('v','m') then ':Views'") + wxT(" else 'should not happen'") + wxT(" end || '/' || t.relname || '/:Columns/' || a.attname AS path, n.nspname") + wxT(" from ") + pd + + wxT(" join pg_class t on pd.relname = 'pg_class' and pd.objoid = t.oid and t.relkind in ('r','v','m')") + wxT(" join pg_attribute a on a.attrelid = t.oid and pd.objsubid = a.attnum") + wxT(" left join pg_namespace n on t.relnamespace = n.oid where a.attnum > 0") + wxT(" union") + wxT(" select 'Constraints',") + wxT(" case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end,") + wxT(" ':Schemas/' || n.nspname||'/:Tables/'||t.relname||'/:Constraints/'") + wxT(" ||case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end, n.nspname") + wxT(" from ") + pd + + wxT(" join pg_constraint c on pd.relname = 'pg_constraint' and pd.objoid = c.oid") + wxT(" left join pg_class t on c.conrelid = t.oid") + wxT(" left join pg_class tf on c.confrelid = tf.oid") + wxT(" left join pg_namespace n on t.relnamespace = n.oid") + wxT(" union") + wxT(" select 'Rules', r.rulename, ':Schemas/' || n.nspname||case when t.relkind in ('v','m') then '/:Views/' else '/:Tables/' end||t.relname||'/:Rules/'|| r.rulename, n.nspname") + wxT(" from ") + pd + + wxT(" join pg_rewrite r on pd.relname = 'pg_rewrite' and pd.objoid = r.oid") + wxT(" left join pg_class t on r.ev_class = t.oid") + wxT(" left join pg_namespace n on t.relnamespace = n.oid") + wxT(" union") + wxT(" select 'Triggers', tr.tgname, ':Schemas/' || n.nspname||case when t.relkind in ('v','m') then '/:Views/' else '/:Tables/' end||t.relname || '/:Triggers/' || tr.tgname, n.nspname") + wxT(" from ") + pd + + wxT(" join pg_trigger tr on pd.relname = 'pg_trigger' and pd.objoid = tr.oid") + wxT(" left join pg_class t on tr.tgrelid = t.oid") + wxT(" left join pg_namespace n on t.relnamespace = n.oid WHERE "); + if(currentdb->BackendMinimumVersion(9, 0)) + searchSQL += wxT(" tr.tgisinternal = false "); + else + searchSQL += wxT(" tr.tgisconstraint = false "); + searchSQL += wxT(" union") + wxT(" SELECT 'Types', t.typname, ':Schemas/' || n.nspname || '/:Types/' || t.typname, n.nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_type t on pd.relname = 'pg_type' and pd.objoid = t.oid") + wxT(" LEFT OUTER JOIN pg_type e ON e.oid=t.typelem") + wxT(" LEFT OUTER JOIN pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c'") + wxT(" LEFT OUTER JOIN pg_namespace n on t.typnamespace = n.oid") + wxT(" WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\\\_%'") + wxT(" union") + wxT(" SELECT 'Conversions', co.conname, ':Schemas/' || n.nspname || '/:Conversions/' || co.conname, n.nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_conversion co on pd.relname = 'pg_conversion' and pd.objoid = co.oid") + wxT(" JOIN pg_namespace n ON n.oid=co.connamespace") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=co.oid AND des.objsubid=0") + wxT(" union") + wxT(" SELECT 'Casts', format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod), ':Casts/' || format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod), NULL as nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_cast ca on pd.relname = 'pg_cast' and pd.objoid = ca.oid") + wxT(" JOIN pg_type st ON st.oid=castsource") + wxT(" JOIN pg_type tt ON tt.oid=casttarget") + wxT(" union") + wxT(" SELECT 'Languages', lanname, ':Languages/' || lanname, NULL as nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_language lan on pd.relname = 'pg_language' and pd.objoid = lan.oid") + wxT(" WHERE lanispl IS TRUE") + wxT(" union") + wxT(" SELECT 'FTS Configurations', cfg.cfgname, ':Schemas/' || n.nspname || '/:FTS Configurations/' || cfg.cfgname, n.nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_ts_config cfg on pd.relname = 'pg_ts_config' and pd.objoid = cfg.oid") + wxT(" left join pg_namespace n on cfg.cfgnamespace = n.oid") + wxT(" union") + wxT(" SELECT 'FTS Dictionaries', dict.dictname, ':Schemas/' || ns.nspname || '/:FTS Dictionaries/' || dict.dictname, ns.nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_ts_dict dict on pd.relname = 'pg_ts_dict' and pd.objoid = dict.oid") + wxT(" left join pg_namespace ns on dict.dictnamespace = ns.oid") + wxT(" union") + wxT(" SELECT 'FTS Parsers', prs.prsname, ':Schemas/' || ns.nspname || '/:FTS Parsers/' || prs.prsname, ns.nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_ts_parser prs on pd.relname = 'pg_ts_parser' and pd.objoid = prs.oid") + wxT(" left join pg_namespace ns on prs.prsnamespace = ns.oid") + wxT(" union") + wxT(" SELECT 'FTS Templates', tmpl.tmplname, ':Schemas/' || ns.nspname || '/:FTS Templates/' || tmpl.tmplname, ns.nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_ts_template tmpl on pd.relname = 'pg_ts_template' and pd.objoid = tmpl.oid") + wxT(" left join pg_namespace ns on tmpl.tmplnamespace = ns.oid") + wxT(" union") + wxT(" select 'Domains', t.typname, ':Schemas/' || n.nspname || '/:Domains/' || t.typname, n.nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_type t on pd.relname = 'pg_type' and pd.objoid = t.oid") + wxT(" inner join pg_namespace n on t.typnamespace = n.oid") + wxT(" where t.typtype = 'd'") + wxT(" union") + wxT(" select 'Aggregates', pr.proname, ':Schemas/' || ns.nspname || '/:Aggregates/' || pr.proname, ns.nspname") + wxT(" from ") + pd + + wxT(" join pg_proc pr on pd.relname = 'pg_proc' and pd.objoid = pr.oid") + wxT(" JOIN pg_catalog.pg_aggregate ag on ag.aggfnoid = pr.oid") + wxT(" left join pg_namespace ns on pr.pronamespace = ns.oid") + wxT(" union") + wxT(" select case when r_.rolcanlogin = true then 'Login Roles' else 'Group Roles' end, r_.rolname,") + wxT(" case when r_.rolcanlogin = true then ':Login Roles' else ':Group Roles' end || '/' || rolname, NULL as nspname") + wxT(" from ") + pd + + wxT(" join pg_roles r_ on pd.relname = 'pg_authid' and pd.objoid = r_.oid") + wxT(" union") + wxT(" select 'Tablespaces', ts_.spcname, ':Tablespaces/'||ts_.spcname, NULL as nspname") + wxT(" from ") + pd + + wxT(" JOIN pg_tablespace ts_ on pd.relname = 'pg_tablespace' and pd.objoid = ts_.oid") + wxT(" union") + wxT(" SELECT 'Operators', op.oprname, ':Schemas/' || ns.nspname || '/:Operators/' || op.oprname, ns.nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_operator op ON pd.relname = 'pg_operator' and pd.objoid = op.oid") + wxT(" left join pg_namespace ns on op.oprnamespace = ns.oid") + wxT(" union") + wxT(" SELECT 'Operator Classes', op.opcname, ':Schemas/' || ns.nspname || '/:Operator Classes/' || op.opcname, ns.nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_opclass op ON pd.relname = 'pg_opclass' and pd.objoid = op.oid") + wxT(" left join pg_namespace ns on op.opcnamespace = ns.oid") + wxT(" union") + wxT(" SELECT 'Operator Families', opf.opfname, ':Schemas/' || ns.nspname || '/:Operator Families/' || opf.opfname, ns.nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_opfamily opf ON pd.relname = 'pg_opfamily' and pd.objoid = opf.oid") + wxT(" left join pg_namespace ns on opf.opfnamespace = ns.oid"); + + if(currentdb->BackendMinimumVersion(8, 4) && currentdb->GetConnection()->IsSuperuser()) + { + searchSQL += wxT(" union") + wxT(" select 'Foreign Data Wrappers', fdw.fdwname, ':Foreign Data Wrappers/' || fdw.fdwname, NULL as nspname ") + wxT(" from ") + pd + + wxT(" JOIN pg_foreign_data_wrapper fdw ON pd.relname = 'pg_foreign_data_wrapper' and pd.objoid = fdw.oid") + wxT(" union ") + wxT(" select 'Foreign Server', sr.srvname, ':Foreign Data Wrappers/' || fdw.fdwname || '/:Foreign Servers/' || sr.srvname, NULL as nspname") + wxT(" from ") + pd + + wxT(" JOIN pg_foreign_server sr ON pd.relname = 'pg_foreign_server' and pd.objoid = sr.oid") + wxT(" inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid "); + } + + if(currentdb->BackendMinimumVersion(9, 1)) + { + searchSQL += wxT(" union") + wxT(" select 'Foreign Tables', c.relname, ':Schemas/' || ns.nspname || '/:Foreign Tables/' || c.relname, ns.nspname") + wxT(" from ") + pd + + wxT(" JOIN pg_class c ON pd.relname = 'pg_class' and pd.objoid = c.oid") + wxT(" join pg_foreign_table ft on ft.ftrelid = c.oid") + wxT(" inner join pg_namespace ns on c.relnamespace = ns.oid") + wxT(" union") + wxT(" select 'Extensions', x.extname, ':Extensions/' || x.extname, NULL AS nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_extension x ON pd.relname = 'pg_extension' and pd.objoid = x.oid") + wxT(" JOIN pg_namespace n on x.extnamespace=n.oid") + wxT(" join pg_available_extensions() e(name, default_version, comment) ON x.extname=e.name") + wxT(" union") + wxT(" SELECT 'Collations', c.collname, ':Schemas/' || n.nspname || '/:Collations/' || c.collname, n.nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_collation c ON pd.relname = 'pg_collation' and pd.objoid = c.oid") + wxT(" JOIN pg_namespace n ON n.oid=c.collnamespace"); + } + searchSQL += wxT(") sc \n"); + } // search comments + + searchSQL += wxT(") ii \n"); + + bool nextPredicate = false; + if (cbType->GetValue() != _("All types")) + { + searchSQL += (nextPredicate) ? wxT("AND ") : wxT("WHERE "); + nextPredicate = true; + searchSQL += wxT("ii.type = ") + currentdb->GetConnection()->qtDbString(aMap[cbType->GetValue()]) + wxT(" "); + } + + if (cbSchema->GetSelection() == cbSchemaIdxCurrent && !currentSchema.IsEmpty()) + { + searchSQL += (nextPredicate) ? wxT("AND ") : wxT("WHERE "); + nextPredicate = true; + searchSQL += wxT("ii.nspname = ") + currentdb->GetConnection()->qtDbString(currentSchema) + wxT(" "); + } + else if (cbSchema->GetValue() == _("My schemas")) + { + searchSQL += (nextPredicate) ? wxT("AND ") : wxT("WHERE "); + nextPredicate = true; + searchSQL += wxT("ii.nspname IN (SELECT n.nspname FROM pg_namespace n WHERE n.nspowner = (SELECT u.usesysid FROM pg_user u WHERE u.usename = ") + + currentdb->GetConnection()->qtDbString(currentdb->GetConnection()->GetUser()) + wxT(")) "); + } + else if (cbSchema->GetValue() != _("All schemas")) + { + searchSQL += (nextPredicate) ? wxT("AND ") : wxT("WHERE "); + nextPredicate = true; + searchSQL += wxT("ii.nspname = ") + currentdb->GetConnection()->qtDbString(cbSchema->GetValue()) + wxT(" "); + } + + searchSQL += wxT("ORDER BY 1, 2, 3"); + + pgSet *set = currentdb->GetConnection()->ExecuteSet(searchSQL); + int i = 0; + if(set) + { + lcResults->DeleteAllItems(); + + while(!set->Eof()) + { + wxString objectType = set->GetVal(wxT("type")); + wxString objectName = set->GetVal(wxT("objectname")); + wxString ItemPath; + + + /* Login Roles, Group Roles and Tablespaces are "outside" the database, so we have to adjust the path */ + if(objectType == wxT("Login Roles") || objectType == wxT("Group Roles") || objectType == wxT("Tablespaces")) + { + wxStringTokenizer tkz(databasePath, wxT("/")); + while(tkz.HasMoreTokens()) + { + wxString token = tkz.GetNextToken(); + if(token == _("Databases")) + break; + ItemPath += token + wxT("/"); + } + ItemPath += set->GetVal(wxT("path")); + } + else + { + ItemPath = databasePath + wxT("/") + set->GetVal(wxT("path")); + } + + if(ItemPath.Contains(wxT("Schemas/information_schema"))) + { + /* In information Schema only views and columns are displayed, nothing else */ + if(objectType == wxT("Views") || objectType == wxT("Columns")) + { + ItemPath.Replace(wxT(":Schemas/information_schema"), wxT(":Catalogs/ANSI/:Catalog Objects")); + ItemPath.Replace(wxT(":Views/"), wxT("")); + } + else + { + set->MoveNext(); + continue; + } + } + + if(ItemPath.Contains(wxT("Schemas/pg_catalog"))) + { + ItemPath.Replace(wxT(":Schemas/pg_catalog"), wxT(":Catalogs/PostgreSQL")); + } + + wxListItem item; + item.SetId(i); + lcResults->InsertItem(item); + + wxString locTypeStr = wxGetTranslation(set->GetVal(wxT("type"))); + + /* Check if viewing of the specified object is enabled in settings */ + if(!settings->GetDisplayOption(locTypeStr)) + { + lcResults->SetItemTextColour(i, wxColour(128, 128, 128)); + } + + lcResults->SetItem(i, 0, locTypeStr); + lcResults->SetItem(i, 1, objectName); + lcResults->SetItem(i, 2, TranslatePath(ItemPath)); + set->MoveNext(); + i++; + } + delete set; + } + + if(lcResults->GetItemCount() > 0) + { + lcResults->SetColumnWidth(0, wxLIST_AUTOSIZE); + lcResults->SetColumnWidth(1, wxLIST_AUTOSIZE); + lcResults->SetColumnWidth(2, wxLIST_AUTOSIZE); + } + + if (statusBar) + { + if (i > 0) + statusBar->SetStatusText(wxString::Format(wxPLURAL("Found %d item", "Found %d items", i), i)); + else + statusBar->SetStatusText(_("Nothing was found")); + } + + ToggleBtnSearch(true); +} + +wxString dlgSearchObject::TranslatePath(wxString &path) +{ + /* Translate a path, but only word that start's with a colon (:) */ + wxStringTokenizer tkz(path, wxT("/")); + wxString newPath; + while(tkz.HasMoreTokens()) + { + wxString token = tkz.GetNextToken(); + if(token.StartsWith(wxT(":"))) + { + token = wxGetTranslation(token.AfterFirst(':')); + } + newPath = newPath + token.Trim() + wxT("/"); + } + return newPath.BeforeLast('/'); + +} + +void dlgSearchObject::OnCancel(wxCommandEvent &ev) +{ + if (IsModal()) + EndModal(wxID_CANCEL); + else + Destroy(); +} + +searchObjectFactory::searchObjectFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Search objects...\tCtrl-G"), _("Search database for specific objects")); +} + +wxWindow *searchObjectFactory::StartDialog(frmMain *form, pgObject *obj) +{ + dlgSearchObject *so = new dlgSearchObject(form, obj->GetDatabase(), obj); + so->Show(); + return 0; +} + +bool searchObjectFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->GetDatabase() && obj->GetDatabase()->GetConnected(); +} diff --git a/dlg/dlgSelectConnection.cpp b/dlg/dlgSelectConnection.cpp new file mode 100644 index 0000000..11b8ef8 --- /dev/null +++ b/dlg/dlgSelectConnection.cpp @@ -0,0 +1,382 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgSelectConnection.cpp - Connect to a database +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "frm/frmMain.h" +#include "dlg/dlgSelectConnection.h" +#include "dlg/dlgConnect.h" +#include "schema/pgServer.h" +#include "images/connect.pngc" + +#define CTRLID_CBSERVER 4242 +#define CTRLID_CBDATABASE 4243 +#define CTRLID_CBUSERNAME 4244 +#define CTRLID_CBROLENAME 4245 + +BEGIN_EVENT_TABLE(dlgSelectConnection, DialogWithHelp) + EVT_COMBOBOX(CTRLID_CBSERVER, dlgSelectConnection::OnChangeServer) + EVT_COMBOBOX(CTRLID_CBDATABASE, dlgSelectConnection::OnChangeDatabase) + EVT_TEXT(CTRLID_CBSERVER, dlgSelectConnection::OnTextChange) + EVT_TEXT(CTRLID_CBDATABASE, dlgSelectConnection::OnTextChange) + EVT_TEXT(CTRLID_CBUSERNAME, dlgSelectConnection::OnTextChange) + EVT_BUTTON (wxID_OK, dlgSelectConnection::OnOK) + EVT_BUTTON (wxID_CANCEL, dlgSelectConnection::OnCancel) +END_EVENT_TABLE() + +#define stUsername CTRL_STATIC("stUsername") + + +dlgSelectConnection::dlgSelectConnection(wxWindow *parent, frmMain *form) : + DialogWithHelp(form) +{ + long style = wxCB_DROPDOWN; + remoteServer = NULL; + + SetFont(settings->GetSystemFont()); + LoadResource(parent, wxT("dlgSelectConnection")); + + SetIcon(*connect_png_ico); + RestorePosition(); + + if (form != NULL) + style |= wxCB_READONLY; + + cbServer = new ctlComboBoxFix(this, CTRLID_CBSERVER, ConvertDialogToPixels(wxPoint(65, 5)), ConvertDialogToPixels(wxSize(135, 12)), style); + cbDatabase = new wxComboBox(this, CTRLID_CBDATABASE, wxEmptyString, ConvertDialogToPixels(wxPoint(65, 20)), ConvertDialogToPixels(wxSize(135, 12)), wxArrayString(), style); + cbUsername = new wxComboBox(this, CTRLID_CBUSERNAME, wxEmptyString, ConvertDialogToPixels(wxPoint(65, 35)), ConvertDialogToPixels(wxSize(135, 12)), wxArrayString(), style); + cbRolename = new wxComboBox(this, CTRLID_CBROLENAME, wxEmptyString, ConvertDialogToPixels(wxPoint(65, 50)), ConvertDialogToPixels(wxSize(135, 12)), wxArrayString(), style); + + if (form == NULL) + { + cbServer->SetValue(settings->Read(wxT("QuickConnect/server"), wxEmptyString)); + cbDatabase->SetValue(settings->Read(wxT("QuickConnect/database"), wxEmptyString)); + cbUsername->SetValue(settings->Read(wxT("QuickConnect/username"), wxEmptyString)); + cbRolename->SetValue(settings->Read(wxT("QuickConnect/rolename"), wxEmptyString)); + } + + btnOK->Enable(cbServer->GetValue().Length() > 0 && cbDatabase->GetValue().Length() > 0 && cbUsername->GetValue().Length() > 0); +} + + +dlgSelectConnection::~dlgSelectConnection() +{ + SavePosition(); +} + + +wxString dlgSelectConnection::GetHelpPage() const +{ + return wxT("connect"); +} + + +void dlgSelectConnection::OnChangeServer(wxCommandEvent &ev) +{ + int item; + wxString olddatabase, oldusername; + + if (!GetServer()) + return; + + // Keep old value for these comboboxes so that we can restore them if needed + olddatabase = cbDatabase->GetValue(); + oldusername = cbUsername->GetValue(); + + // Clear the comboboxes + cbDatabase->Clear(); + cbUsername->Clear(); + cbRolename->Clear(); + + int sel = cbServer->GetCurrentSelection(); + if (sel >= 0) + { + remoteServer = (pgServer *)cbServer->wxItemContainer::GetClientData(sel); + + if (!remoteServer->GetConnected()) + { + remoteServer->Connect(mainForm, remoteServer->GetStorePwd()); + if (!remoteServer->GetConnected()) + { + wxLogError(wxT("%s"), remoteServer->GetLastError().c_str()); + return; + } + } + if (remoteServer->GetConnected()) + { + pgSetIterator set1(remoteServer->GetConnection(), + wxT("SELECT DISTINCT datname\n") + wxT(" FROM pg_database db\n") + wxT(" WHERE datallowconn ORDER BY datname")); + + item = 0; + while(set1.RowsLeft()) + { + cbDatabase->Append(set1.GetVal(wxT("datname"))); + if (set1.GetVal(wxT("datname")) == olddatabase) + item = cbDatabase->GetCount() - 1; + } + + if (cbDatabase->GetCount()) + cbDatabase->SetSelection(item); + + pgSetIterator set2(remoteServer->GetConnection(), + wxT("SELECT DISTINCT usename\n") + wxT("FROM pg_user db\n") + wxT("ORDER BY usename")); + + item = 0; + while(set2.RowsLeft()) + { + cbUsername->Append(set2.GetVal(wxT("usename"))); + if (set2.GetVal(wxT("usename")) == oldusername) + item = cbDatabase->GetCount() - 1; + } + + if (cbUsername->GetCount()) + cbUsername->SetSelection(item); + + if (remoteServer->GetConnection()->BackendMinimumVersion(8, 1)) + { + pgSetIterator set3(remoteServer->GetConnection(), + wxT("SELECT DISTINCT rolname\n") + wxT("FROM pg_roles db\n") + wxT("ORDER BY rolname")); + + cbRolename->Append(wxEmptyString); + + while(set3.RowsLeft()) + cbRolename->Append(set3.GetVal(wxT("rolname"))); + + cbRolename->Enable(true); + } + else + cbRolename->Disable(); + + cbRolename->SetValue(wxEmptyString); + } + + } + OnChangeDatabase(ev); +} + + +wxString dlgSelectConnection::GetDatabase() +{ + return cbDatabase->GetValue(); +} + +wxString dlgSelectConnection::GetServerName() +{ + return cbServer->GetValue(); +} + +void dlgSelectConnection::OnChangeDatabase(wxCommandEvent &ev) +{ + btnOK->Enable(cbServer->GetValue().Length() > 0 && cbDatabase->GetValue().Length() > 0 && cbUsername->GetValue().Length() > 0); +} + +void dlgSelectConnection::OnTextChange(wxCommandEvent &ev) +{ + btnOK->Enable(cbServer->GetValue().Length() > 0 && cbDatabase->GetValue().Length() > 0 && cbUsername->GetValue().Length() > 0); +} + +void dlgSelectConnection::OnOK(wxCommandEvent &ev) +{ +#ifdef __WXGTK__ + if (!btnOK->IsEnabled()) + return; +#endif + + if (cbDatabase->GetCurrentSelection() == wxNOT_FOUND || + cbServer->GetCurrentSelection() == wxNOT_FOUND) + remoteServer = NULL; + + EndModal(wxID_OK); +} + + +void dlgSelectConnection::OnCancel(wxCommandEvent &ev) +{ + EndModal(wxID_CANCEL); +} + +pgConn *dlgSelectConnection::CreateConn(wxString &applicationname, bool &createdNew) +{ + /* gcc requires that we store this in temporary variables for some reason... */ + wxString serv = cbServer->GetValue(); + wxString db = cbDatabase->GetValue(); + + createdNew = true; + + long port = 0; + if (serv.Find(':') > 0) + { + if (!serv.Mid(serv.Find(':') + 1).ToLong(&port)) + { + wxMessageBox(_("Invalid port number specified.")); + return NULL; + } + serv = serv.Mid(0, serv.Find(':')); + } + + wxString user = cbUsername->GetValue(); + wxString role = cbRolename->GetValue(); + + if (cbConnection) + { + /* Check if selected combination already exists */ + for (unsigned int index = 0; index < cbConnection->GetCount() - 1; index++) + { + pgConn *conn = (pgConn *)cbConnection->GetClientData(index); + if (conn && + conn->GetHost() == serv && + conn->GetPort() == port && + conn->GetUser() == user && + conn->GetRole() == role && + conn->GetDbname() == db) + { + createdNew = false; + return conn; + } + } + } + + + int sslmode = remoteServer ? remoteServer->GetSSL() : 0; + + return CreateConn(serv, db, user, port, role, sslmode, applicationname, true); +} + +pgConn *dlgSelectConnection::CreateConn(wxString &server, wxString &dbname, wxString &username, int port, wxString &rolename, int sslmode, wxString &applicationname, bool writeMRU) +{ + pgConn *newconn; + newconn = new pgConn(server, wxEmptyString, wxEmptyString, dbname, username, wxT(""), port, rolename, sslmode, 0, applicationname); + if (newconn->GetStatus() != PGCONN_OK && + newconn->GetLastError().Cmp(wxString(PQnoPasswordSupplied, wxConvUTF8)) == 0) + { + /* Needs password */ + delete newconn; + newconn = NULL; + + wxString txt; + txt.Printf(_("Please enter password for user %s\non server %s"), username.c_str(), server.c_str()); + dlgConnect dlg(NULL, txt, false); + if (dlg.Go() != wxID_OK) + return NULL; + + newconn = new pgConn(server, wxEmptyString, wxEmptyString, dbname, username, dlg.GetPassword(), port, rolename, sslmode, 0, applicationname); + } + + if (newconn) + { + if (newconn->GetStatus() != PGCONN_OK) + { + wxMessageBox(wxT("Connection failed: ") + newconn->GetLastError()); + return NULL; + } + + if (writeMRU) + { + settings->Write(wxT("QuickConnect/server"), cbServer->GetValue()); + settings->Write(wxT("QuickConnect/database"), cbDatabase->GetValue()); + settings->Write(wxT("QuickConnect/username"), cbUsername->GetValue()); + settings->Write(wxT("QuickConnect/rolename"), cbRolename->GetValue()); + } + } + return newconn; +} + +int dlgSelectConnection::Go(pgConn *conn, wxBitmapComboBox *cb) +{ + bool foundServer = false; + cbConnection = cb; + if (mainForm != NULL) + { + ctlTree *browser = mainForm->GetBrowser(); + wxTreeItemIdValue foldercookie, servercookie; + wxTreeItemId folderitem, serveritem; + pgObject *object; + pgServer *server; + + folderitem = browser->GetFirstChild(browser->GetRootItem(), foldercookie); + while (folderitem) + { + if (browser->ItemHasChildren(folderitem)) + { + serveritem = browser->GetFirstChild(folderitem, servercookie); + while (serveritem) + { + object = browser->GetObject(serveritem); + if (object && object->IsCreatedBy(serverFactory)) + { + server = (pgServer *)object; + cbServer->Append(server->GetIdentifier(), (void *)server); + if (server->GetConnected() && + server->GetConnection()->GetHost() == conn->GetHost() && + server->GetConnection()->GetPort() == conn->GetPort()) + { + cbServer->SetSelection(cbServer->GetCount() - 1); + remoteServer = server; + foundServer = true; + } + } + serveritem = browser->GetNextChild(folderitem, servercookie); + } + } + folderitem = browser->GetNextChild(browser->GetRootItem(), foldercookie); + } + } + + cbServer->SetFocus(); + + wxCommandEvent ev; + OnChangeServer(ev); + + if (foundServer) + { + + unsigned int index = 0; + for (; index < cbDatabase->GetCount(); index++) + { + if (cbDatabase->GetString(index) == conn->GetDbname()) + { + cbDatabase->SetSelection(index); + break; + } + } + for (index = 0; index < cbUsername->GetCount(); index++) + { + if (cbUsername->GetString(index) == conn->GetUser()) + { + cbUsername->SetSelection(index); + break; + } + } + for (index = 0; index < cbRolename->GetCount(); index++) + { + if (cbRolename->GetString(index) == conn->GetRole()) + { + cbRolename->SetSelection(index); + break; + } + } + } + + return ShowModal(); +} + diff --git a/dlg/dlgSelectDatabase.cpp b/dlg/dlgSelectDatabase.cpp new file mode 100644 index 0000000..f4a4d08 --- /dev/null +++ b/dlg/dlgSelectDatabase.cpp @@ -0,0 +1,325 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgSelectDatabase.cpp - Database Selection for connection string +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +#include + +#include "utils/misc.h" +#include "dlg/dlgSelectDatabase.h" +#include "schema/pgServer.h" +#include "schema/pgDatabase.h" +#include "frm/frmMain.h" + +extern frmMain *winMain; +wxWindowID TCSERVER_ID = ::wxNewId(); + +BEGIN_EVENT_TABLE(dlgSelectDatabase, wxDialog) + EVT_TREE_ITEM_ACTIVATED (TCSERVER_ID, dlgSelectDatabase::OnSelActivate) + EVT_TREE_SEL_CHANGED (TCSERVER_ID, dlgSelectDatabase::OnSelect) +END_EVENT_TABLE() + + +dlgSelectDatabase::dlgSelectDatabase(wxWindow *parent, int id, const wxPoint &pos, const wxSize &size, long style): + wxDialog(parent, id, wxT("Select Database"), pos, size, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) +{ + +#ifdef __WXMSW__ + SetWindowStyleFlag(GetWindowStyleFlag() & ~wxMAXIMIZE_BOX); +#endif + + wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL); + + tcServers = new wxTreeCtrl(this, TCSERVER_ID); + mainSizer->Add(tcServers, 1, wxEXPAND, 0); + + wxBoxSizer *bottomSizer = new wxBoxSizer(wxHORIZONTAL); + + bottomSizer->AddStretchSpacer(); + + wxButton *btnOk = new wxButton(this, wxID_OK, wxT("&OK")); + bottomSizer->Add(btnOk); + + wxButton *btnCANCEL = new wxButton(this, wxID_CANCEL, wxT("&Cancel")); + bottomSizer->Add(btnCANCEL, 0, wxLEFT, 10); + + mainSizer->Add(bottomSizer, 0, wxALL | wxALIGN_RIGHT, 5); + SetSizer(mainSizer); + + SetSize(wxSize(200, 240)); + + Layout(); + Centre(); + + Initialize(); +} + +void dlgSelectDatabase::Initialize() +{ + // Add the root node + pgServerCollection *serversObj = new pgServerCollection(serverFactory.GetCollectionFactory()); + wxTreeItemId rootItemID = tcServers->AddRoot(wxGetTranslation(serverFactory.GetCollectionFactory()->GetTypeName()), + serversObj->GetIconId(), -1, serversObj); + tcServers->SetImageList(imageList); + + ctlTree *browser = winMain->GetBrowser(); + + wxTreeItemId servers = tcServers->GetRootItem(); + + wxTreeItemIdValue foldercookie; + wxTreeItemId folderitem = browser->GetFirstChild(browser->GetRootItem(), foldercookie); + while (folderitem) + { + if (browser->ItemHasChildren(folderitem)) + { + wxCookieType cookie; + wxTreeItemId serverItem = browser->GetFirstChild(folderitem, cookie); + + wxTreeItemId tcGroupsItem = tcServers->AppendItem(rootItemID, browser->GetItemText(folderitem), serversObj->GetIconId()); + while (serverItem) + { + pgServer *server = (pgServer *)browser->GetObject(serverItem); + + if (server && server->IsCreatedBy(serverFactory)) + { + dlgSelDBNode *cnInfo = new dlgSelDBNode(server); + wxTreeItemId itm = tcServers->AppendItem(tcGroupsItem, server->GetFullName(), server->GetIconId(), -1, cnInfo); + + pgConn *conn = server->connection(); + + if (conn && conn->IsAlive()) + { + pgSet *res = conn->ExecuteSet(wxT("SELECT datname, datallowconn FROM pg_catalog.pg_database")); + if (res) + { + while (!res->Eof()) + { + if (res->GetBool(wxT("datallowconn"))) + { + dlgSelDBNode *cnInfo = new dlgSelDBNode(server, res->GetVal(wxT("datname"))); + tcServers->AppendItem(itm, cnInfo->getDatabase(), databaseFactory.GetIconId(), -1, cnInfo); + } + + res->MoveNext(); + } + delete res; + } + } + } + + serverItem = browser->GetNextChild(folderitem, cookie); + } + folderitem = browser->GetNextChild(browser->GetRootItem(), foldercookie); + } + } + + tcServers->Expand(servers); + selectedConn = NULL; +} + +void dlgSelectDatabase::OnSelect(wxTreeEvent &ev) +{ + wxTreeItemId sel = tcServers->GetSelection(); + + if (sel.IsOk() && sel != tcServers->GetRootItem() && tcServers->GetItemParent(sel) != tcServers->GetRootItem()) + { + selectedConn = (dlgSelDBNode *)tcServers->GetItemData(sel); + } + else + { + selectedConn = NULL; + } +} + +void dlgSelectDatabase::OnSelActivate(wxTreeEvent &ev) +{ + wxTreeItemId selID = tcServers->GetSelection(); + + if (selID.IsOk() && selID != tcServers->GetRootItem()) + { + selectedConn = (dlgSelDBNode *)tcServers->GetItemData(selID); + + if (selectedConn->dbname.IsEmpty() && tcServers->GetChildrenCount(selID, false) == 0) + { + winMain->ReconnectServer(selectedConn->server, true); + + pgConn *conn = selectedConn->server->connection(); + if (conn && conn->GetStatus() == PGCONN_OK) + { + pgSet *res = conn->ExecuteSet(wxT("SELECT datname, datallowconn FROM pg_catalog.pg_database")); + if (res) + { + while (!res->Eof()) + { + if (res->GetBool(wxT("datallowconn"))) + { + dlgSelDBNode *cnInfo = new dlgSelDBNode(selectedConn->server, res->GetVal(wxT("datname"))); + tcServers->AppendItem(selID, cnInfo->getDatabase(), databaseFactory.GetIconId(), -1, cnInfo); + } + + res->MoveNext(); + } + } + delete res; + } + tcServers->Expand(selID); + } + } + else + { + selectedConn = NULL; + } +} + + +wxString dlgSelectDatabase::getConnInfo() +{ + if (selectedConn) + { + return selectedConn->getConnectionString(); + } + + return wxEmptyString; +} + +bool dlgSelectDatabase::getValidConnectionString(wxString connStr, wxString &resultStr) +{ + wxString user; + wxString dbname; + wxString host; + unsigned long port = 0; + wxString password; + unsigned long connection_timeout = 0; + + wxRegEx propertyExp; + + // Remove white-spaces ahead the '=" + bool res = propertyExp.Compile(wxT("(([ ]*[\t]*)+)=")); + propertyExp.ReplaceAll(&connStr, wxT("=")); + + // Remove white-spaces after the '=" + res = propertyExp.Compile(wxT("=(([ ]*[\t]*)+)")); + propertyExp.ReplaceAll(&connStr, wxT("=")); + wxArrayString tokens = wxStringTokenize(connStr, wxT("\t \n\r")); + + unsigned int index = 0; + while (index < tokens.Count()) + { + wxString prop, value; + + // Find pairs + // i.e. user=xxx + // password=xxx + wxArrayString pairs = wxStringTokenize(tokens[index++], wxT("=")); + + // pair must exist in pair=value format + if (pairs.GetCount() != 2) + return false; + + prop = pairs[0]; + value = pairs[1]; + + if (prop.CmpNoCase(wxT("user")) == 0) + user = value; + else if (prop.CmpNoCase(wxT("host")) == 0 || prop.CmpNoCase(wxT("hostAddr")) == 0) + host = value; + else if (prop.CmpNoCase(wxT("port")) == 0) + { + if (!value.ToULong(&port)) + // port must be an unsigned integer + return false; + } + else if (prop.CmpNoCase(wxT("password")) == 0) + password = value; + else if (prop.CmpNoCase(wxT("connection_timeout")) == 0) + { + if (!value.ToULong(&connection_timeout)) + // connection timeout must be an unsigned interger + return false; + } + else if (prop.CmpNoCase(wxT("dbname")) == 0) + dbname = value; + else + // Not valid property found + return false; + } + + if (dbname.IsEmpty()) + return false; + + if (!user.IsEmpty()) + resultStr = wxT("user=") + user + wxT(" "); + + if (!host.IsEmpty()) + { + resultStr += wxT("host=") + host + wxT(" "); + } + + + if (!resultStr.IsEmpty()) + resultStr += wxT(" "); + resultStr += wxT("dbname=") + dbname + wxT(" "); + + if (port != 0) + { + wxString portStr; + portStr.Printf(wxT("port=%ld"), port); + resultStr += portStr + wxT(" "); + } + + + if (connection_timeout != 0) + { + wxString strConnTimeOut; + strConnTimeOut.Printf(wxT("connection_timeout=%ld"), connection_timeout); + resultStr += strConnTimeOut + wxT(" "); + } + + if (!password.IsEmpty()) + { + resultStr += wxT("password=") + password + wxT(" "); + } + + resultStr = resultStr.Trim(); + + return true; +} + +dlgSelDBNode::dlgSelDBNode (pgServer *_server, const wxString &_dbname) +{ + server = _server; + dbname = _dbname; +} + +wxString dlgSelDBNode::getConnectionString() +{ + if (dbname.IsEmpty()) + return wxEmptyString; + + pgConn *conn = server->connection(); + wxString connStr; + + if (conn && conn->GetStatus() == PGCONN_OK) + { + connStr += wxT("user=") + conn->GetUser() + wxT(" "); + connStr += wxT("host=") + conn->GetHostName() + wxT(" "); + + wxString port; + port.Printf(wxT("port=%d "), conn->GetPort()); + connStr += port; + + connStr += wxT("dbname=") + dbname; + } + + return connStr; +} + diff --git a/dlg/dlgSequence.cpp b/dlg/dlgSequence.cpp new file mode 100644 index 0000000..e58e9dc --- /dev/null +++ b/dlg/dlgSequence.cpp @@ -0,0 +1,386 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgSequence.cpp - PostgreSQL Sequence Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "dlg/dlgSequence.h" + +#include "schema/pgSchema.h" +#include "schema/pgSequence.h" +#include "ctl/ctlSeclabelPanel.h" + + +#define txtIncrement CTRL_TEXT("txtIncrement") +#define cbOwner CTRL_COMBOBOX2("cbOwner") +#define txtMin CTRL_TEXT("txtMin") +#define txtMax CTRL_TEXT("txtMax") +#define txtStart CTRL_TEXT("txtStart") +#define txtCache CTRL_TEXT("txtCache") +#define chkCycled CTRL_CHECKBOX("chkCycled") +#define stStart CTRL_STATIC("stStart") + +// pointer to controls + +BEGIN_EVENT_TABLE(dlgSequence, dlgSecurityProperty) + EVT_TEXT(XRCID("txtStart"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtMin"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtMax"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtCache"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtIncrement"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkCycled"), dlgProperty::OnChange) +END_EVENT_TABLE(); + + +dlgProperty *pgSequenceFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgSequence(this, frame, (pgSequence *)node, (pgSchema *)parent); +} + + +dlgSequence::dlgSequence(pgaFactory *f, frmMain *frame, pgSequence *node, pgSchema *sch) + : dlgSecurityProperty(f, frame, node, wxT("dlgSequence"), wxT("INSERT,SELECT,UPDATE,DELETE,RULE,REFERENCES,TRIGGER,USAGE"), "arwdRxtU") +{ + schema = sch; + sequence = node; + seclabelPage = new ctlSeclabelPanel(nbNotebook); +} + + +pgObject *dlgSequence::GetObject() +{ + return sequence; +} + + +int dlgSequence::Go(bool modal) +{ + if (connection->BackendMinimumVersion(9, 1)) + { + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(sequence); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgSequence::OnChange)); + } + else + seclabelPage->Disable(); + + if (sequence) + { + // edit mode + txtIncrement->SetValue(sequence->GetIncrement().ToString()); + txtStart->SetValue(sequence->GetLastValue().ToString()); + txtMin->SetValue(sequence->GetMinValue().ToString()); + txtMax->SetValue(sequence->GetMaxValue().ToString()); + txtCache->SetValue(sequence->GetCacheValue().ToString()); + chkCycled->SetValue(sequence->GetCycled()); + + stStart->SetLabel(_("Current value")); + + cbSchema->Enable(connection->BackendMinimumVersion(8, 1)); + + if (!connection->BackendMinimumVersion(7, 4)) + { + txtIncrement->Disable(); + txtMin->Disable(); + txtMax->Disable(); + txtCache->Disable(); + chkCycled->Disable(); + } + } + else + { + // create mode + txtIncrement->SetValidator(numericValidator); + txtMin->SetValidator(numericValidator); + txtMax->SetValidator(numericValidator); + txtCache->SetValidator(numericValidator); + } + + txtStart->SetValidator(numericValidator); + + // Find, and disable the USAGE ACL option if we're on pre 8.2 + // 8.2+ only supports SELECT, UPDATE and USAGE + if (!connection->BackendMinimumVersion(8, 2)) + { + // Disable the checkbox + if (!DisablePrivilege(wxT("USAGE"))) + { + wxLogError(_("Failed to disable the USAGE privilege checkbox!")); + } + } + else + { + if (!DisablePrivilege(wxT("INSERT"))) + { + wxLogError(_("Failed to disable the INSERT privilege checkbox!")); + } + if (!DisablePrivilege(wxT("DELETE"))) + { + wxLogError(_("Failed to disable the DELETE privilege checkbox!")); + } + if (!DisablePrivilege(wxT("RULE"))) + { + wxLogError(_("Failed to disable the RULE privilege checkbox!")); + } + if (!DisablePrivilege(wxT("REFERENCES"))) + { + wxLogError(_("Failed to disable the REFERENCES privilege checkbox!")); + } + if (!DisablePrivilege(wxT("TRIGGER"))) + { + wxLogError(_("Failed to disable the TRIGGER privilege checkbox!")); + } + } + + return dlgSecurityProperty::Go(modal); +} + + +pgObject *dlgSequence::CreateObject(pgCollection *collection) +{ + pgObject *obj = sequenceFactory.CreateObjects(collection, 0, + wxT(" AND relname=") + qtDbString(GetName()) + + wxT("\n AND relnamespace=") + schema->GetOidStr()); + + return obj; +} + + +#ifdef __WXMAC__ +void dlgSequence::OnChangeSize(wxSizeEvent &ev) +{ + SetPrivilegesLayout(); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + + +void dlgSequence::CheckChange() +{ + bool enable = true; + wxString name = GetName(); + bool maxOk = true; + + if (statusBar) + statusBar->SetStatusText(wxEmptyString); + + // Check we don't overflow INT64_MAX + if (doesOverflowBigInt(txtCache->GetValue(), !sequence)) + { + if (statusBar) + statusBar->SetStatusText(_("Invalid cache value")); + maxOk = false; + } + + if (doesOverflowBigInt(txtMax->GetValue(), !sequence)) + { + if (statusBar) + statusBar->SetStatusText(_("Invalid maximum value")); + maxOk = false; + } + + if (doesOverflowBigInt(txtMin->GetValue(), !sequence)) + { + if (statusBar) + statusBar->SetStatusText(_("Invalid minimum value")); + maxOk = false; + } + + if (doesOverflowBigInt(txtStart->GetValue(), !sequence)) + { + if (statusBar) + statusBar->SetStatusText(_("Invalid current value")); + maxOk = false; + } + + if (doesOverflowBigInt(txtIncrement->GetValue(), !sequence)) + { + if (statusBar) + statusBar->SetStatusText(_("Invalid increment value")); + maxOk = false; + } + + if (sequence) + { + enable = maxOk && (name != sequence->GetName() + || cbSchema->GetValue() != sequence->GetSchema()->GetName() + || txtComment->GetValue() != sequence->GetComment() + || cbOwner->GetValue() != sequence->GetOwner() + || txtStart->GetValue() != sequence->GetLastValue().ToString() + || txtMin->GetValue() != sequence->GetMinValue().ToString() + || txtMax->GetValue() != sequence->GetMaxValue().ToString() + || txtCache->GetValue() != sequence->GetCacheValue().ToString() + || txtIncrement->GetValue() != sequence->GetIncrement().ToString() + || chkCycled->GetValue() != sequence->GetCycled()); + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); + EnableOK(enable); + } + else + { + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + EnableOK(enable && maxOk); + } +} + +bool dlgSequence::doesOverflowBigInt(const wxString &str, bool emptyAllowed) +{ + if (emptyAllowed && str.IsEmpty()) + return false; + + if (NumToStr(StrToLongLong(str)) != str) + return true; + + return false; +} + +wxString dlgSequence::GetSql() +{ + wxString sql, name; + + if (sequence) + { + // edit mode + name = GetName(); + + if (connection->BackendMinimumVersion(8, 3)) + AppendNameChange(sql, wxT("SEQUENCE ") + sequence->GetQuotedFullIdentifier()); + else + AppendNameChange(sql, wxT("TABLE ") + sequence->GetQuotedFullIdentifier()); + + if (connection->BackendMinimumVersion(8, 4)) + AppendOwnerChange(sql, wxT("SEQUENCE ") + schema->GetQuotedPrefix() + qtIdent(name)); + else + AppendOwnerChange(sql, wxT("TABLE ") + schema->GetQuotedPrefix() + qtIdent(name)); + + // This is where things get hairy. Per some thought by Horvath Gabor, + // we need to adjust the min/max sequence values, and the current + // value per the rules: + // + // 1 Any ALTER SEQUENCE MIN/MAXVALUE statements that widen the range + // 2 SETVAL + // 3 Any ALTER SEQUENCE MIN/MAXVALUE statements that narrow the range. + // + // We'll change any other options at the end. + wxString tmp; + + // MIN/MAX changes that widen the range. + if (connection->BackendMinimumVersion(7, 4)) + { + tmp = wxEmptyString; + if (txtMin->GetValue().IsEmpty()) + tmp += wxT("\n NO MINVALUE"); + else if (StrToLongLong(txtMin->GetValue()) < sequence->GetMinValue()) + tmp += wxT("\n MINVALUE ") + txtMin->GetValue(); + + if (txtMax->GetValue().IsEmpty()) + tmp += wxT("\n NO MAXVALUE"); + else if (StrToLongLong(txtMax->GetValue()) > sequence->GetMaxValue()) + tmp += wxT("\n MAXVALUE ") + txtMax->GetValue(); + + if (!tmp.IsEmpty()) + { + sql += wxT("ALTER SEQUENCE ") + schema->GetQuotedPrefix() + qtIdent(name) + + tmp + wxT(";\n"); + } + } + + // The new sequence value + if (txtStart->GetValue() != sequence->GetLastValue().ToString()) + sql += wxT("SELECT setval('") + qtIdent(schema->GetName()) + wxT(".") + qtIdent(name) + + wxT("', ") + txtStart->GetValue() + + wxT(", true);\n"); + + // Min/Max changes that narrow the ranges, as well as other changes. + if (connection->BackendMinimumVersion(7, 4)) + { + tmp = wxEmptyString; + if (txtIncrement->GetValue() != sequence->GetIncrement().ToString()) + tmp += wxT("\n INCREMENT ") + txtIncrement->GetValue(); + + if ((!txtMin->GetValue().IsEmpty()) && StrToLongLong(txtMin->GetValue()) > sequence->GetMinValue()) + tmp += wxT("\n MINVALUE ") + txtMin->GetValue(); + + if ((!txtMax->GetValue().IsEmpty()) && StrToLongLong(txtMax->GetValue()) < sequence->GetMaxValue()) + tmp += wxT("\n MAXVALUE ") + txtMax->GetValue(); + + if (txtCache->GetValue() != sequence->GetCacheValue().ToString()) + tmp += wxT("\n CACHE ") + txtCache->GetValue(); + + if (chkCycled->GetValue() != sequence->GetCycled()) + { + if (chkCycled->GetValue()) + tmp += wxT("\n CYCLE"); + else + tmp += wxT("\n NO CYCLE"); + } + + if (!tmp.IsEmpty()) + { + sql += wxT("ALTER SEQUENCE ") + schema->GetQuotedPrefix() + qtIdent(name) + + tmp + wxT(";\n"); + } + + if (connection->BackendMinimumVersion(8, 1)) + AppendSchemaChange(sql, wxT("SEQUENCE ") + schema->GetQuotedPrefix() + qtIdent(name)); + } + } + else + { + name = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()); + + // create mode + sql = wxT("CREATE SEQUENCE ") + name; + if (chkCycled->GetValue()) + sql += wxT(" CYCLE"); + AppendIfFilled(sql, wxT("\n INCREMENT "), txtIncrement->GetValue()); + AppendIfFilled(sql, wxT("\n START "), txtStart->GetValue()); + AppendIfFilled(sql, wxT("\n MINVALUE "), txtMin->GetValue()); + AppendIfFilled(sql, wxT("\n MAXVALUE "), txtMax->GetValue()); + AppendIfFilled(sql, wxT("\n CACHE "), txtCache->GetValue()); + sql += wxT(";\n"); + + if (cbOwner->GetGuessedSelection() > 0) + { + if (connection->BackendMinimumVersion(8, 4)) + { + AppendOwnerChange(sql, wxT("SEQUENCE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName())); + } + else + { + AppendOwnerChange(sql, wxT("TABLE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName())); + } + } + } + + if (!connection->BackendMinimumVersion(8, 2)) + sql += GetGrant(wxT("arwdRxt"), wxT("TABLE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName())); + else + sql += GetGrant(wxT("rwU"), wxT("SEQUENCE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName())); + + AppendComment(sql, wxT("SEQUENCE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), sequence); + + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + sql += seclabelPage->GetSqlForSecLabels(wxT("SEQUENCE"), qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName())); + + return sql; +} + +void dlgSequence::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} diff --git a/dlg/dlgServer.cpp b/dlg/dlgServer.cpp new file mode 100644 index 0000000..4576c3e --- /dev/null +++ b/dlg/dlgServer.cpp @@ -0,0 +1,745 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgServer.cpp - PostgreSQL Database Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" + +// Must be after pgAdmin3.h or MSVC++ complains +#include +#include +#include + +// Other app headers +#include "utils/misc.h" +#include "frm/frmMain.h" +#include "frm/frmHint.h" +#include "dlg/dlgServer.h" +#include "schema/pgDatabase.h" + +// pointer to controls +#define txtHostAddr CTRL_TEXT("txtHostAddr") +#define txtDescription CTRL_TEXT("txtDescription") +#define txtService CTRL_TEXT("txtService") +#define txtServiceID CTRL_TEXT("txtServiceID") +#define cbDatabase CTRL_COMBOBOX("cbDatabase") +#define txtPort CTRL_TEXT("txtPort") +#define cbSSL CTRL_COMBOBOX("cbSSL") +#define txtUsername CTRL_TEXT("txtUsername") +#define stTryConnect CTRL_STATIC("stTryConnect") +#define chkTryConnect CTRL_CHECKBOX("chkTryConnect") +#define stStorePwd CTRL_STATIC("stStorePwd") +#define chkStorePwd CTRL_CHECKBOX("chkStorePwd") +#define txtRolename CTRL_TEXT("txtRolename") +#define stRestore CTRL_STATIC("stRestore") +#define chkRestore CTRL_CHECKBOX("chkRestore") +#define stPassword CTRL_STATIC("stPassword") +#define txtPassword CTRL_TEXT("txtPassword") +#define txtDbRestriction CTRL_TEXT("txtDbRestriction") +#define colourPicker CTRL_COLOURPICKER("colourPicker") +#define cbGroup CTRL_COMBOBOX("cbGroup") +#define pickerSSLCert CTRL_FILEPICKER("pickerSSLCert") +#define pickerSSLKey CTRL_FILEPICKER("pickerSSLKey") +#define pickerSSLRootCert CTRL_FILEPICKER("pickerSSLRootCert") +#define pickerSSLCrl CTRL_FILEPICKER("pickerSSLCrl") +#define chkSSLCompression CTRL_CHECKBOX("chkSSLCompression") +#define nbNotebook CTRL_NOTEBOOK("nbNotebook") + +// SSH Tunnel Tab +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) +#define chkSSHTunnel CTRL_CHECKBOX("chkSSHTunnel") +#define txtTunnelHost CTRL_TEXT("txtTunnelHost") +#define txtTunnelUsername CTRL_TEXT("txtTunnelUsername") +#define radioBtnPassword CTRL_RADIOBUTTON("radioBtnPassword") +#define radioBtnKeyfile CTRL_RADIOBUTTON("radioBtnKeyfile") +#define txtTunnelPassword CTRL_TEXT("txtTunnelPassword") +#define pickerPublicKeyFile CTRL_FILEPICKER("pickerPublicKeyFile") +#define pickerIdentityFile CTRL_FILEPICKER("pickerIdentityFile") +#define stPublicKeyFile CTRL_STATIC("stPublicKeyFile") +#define txtTunnelPort CTRL_TEXT("txtTunnelPort") +#endif + +BEGIN_EVENT_TABLE(dlgServer, dlgProperty) + EVT_NOTEBOOK_PAGE_CHANGED(XRCID("nbNotebook"), dlgServer::OnPageSelect) + EVT_TEXT(XRCID("txtHostAddr"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtDescription"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtService"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtServiceID"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbDatabase"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbDatabase"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtPort") , dlgProperty::OnChange) + EVT_TEXT(XRCID("txtUsername"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtRolename"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtDbRestriction"), dlgServer::OnChangeRestr) + EVT_COMBOBOX(XRCID("cbSSL"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkStorePwd"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkRestore"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkTryConnect"), dlgServer::OnChangeTryConnect) + EVT_COLOURPICKER_CHANGED(XRCID("colourPicker"), dlgServer::OnChangeColour) + EVT_FILEPICKER_CHANGED(XRCID("pickerSSLCert"), dlgServer::OnChangeFile) + EVT_FILEPICKER_CHANGED(XRCID("pickerSSLKey"), dlgServer::OnChangeFile) + EVT_FILEPICKER_CHANGED(XRCID("pickerSSLRootCert"), dlgServer::OnChangeFile) + EVT_FILEPICKER_CHANGED(XRCID("pickerSSLCrl"), dlgServer::OnChangeFile) + EVT_TEXT(XRCID("cbGroup"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbGroup"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkSSLCompression"), dlgProperty::OnChange) + EVT_BUTTON(wxID_OK, dlgServer::OnOK) +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + EVT_TEXT(XRCID("txtTunnelHost"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtTunnelUsername"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkSSHTunnel"), dlgServer::OnCheckSSHTunnel) + EVT_RADIOBUTTON(XRCID("radioBtnPassword"), dlgServer::OnChangeAuthOption) + EVT_RADIOBUTTON(XRCID("radioBtnKeyfile"), dlgServer::OnChangeAuthOption) + EVT_TEXT(XRCID("txtTunnelPort"), dlgProperty::OnChange) +#endif +END_EVENT_TABLE(); + + +dlgProperty *pgServerFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgServer(this, frame, (pgServer *)node); +} + + +dlgServer::dlgServer(pgaFactory *f, frmMain *frame, pgServer *node) + : dlgProperty(f, frame, wxT("dlgServer")) +{ + server = node; + dbRestrictionOk = true; + + cbDatabase->Append(wxT("postgres")); + cbDatabase->Append(wxT("edb")); + cbDatabase->Append(wxT("template1")); + wxString lastDB = settings->GetLastDatabase(); + if (lastDB != wxT("postgres") && lastDB != wxT("edb") && lastDB != wxT("template1")) + cbDatabase->Append(lastDB); + cbDatabase->SetSelection(0); + + txtPort->SetValue(NumToStr((long)settings->GetLastPort())); + if (!cbSSL->GetValue().IsEmpty()) + cbSSL->SetSelection(settings->GetLastSSL()); + txtUsername->SetValue(settings->GetLastUsername()); + + chkTryConnect->SetValue(true); + chkStorePwd->SetValue(true); + chkRestore->SetValue(true); + if (node) + { + chkTryConnect->SetValue(false); + chkTryConnect->Disable(); + } + + // Fill the group combobox + cbGroup->Append(_("Servers")); + ctlTree *browser = frame->GetBrowser(); + wxTreeItemId groupitem; + wxTreeItemIdValue groupcookie, servercookie; + pgServer *firstserver; + if (browser->ItemHasChildren(browser->GetRootItem())) + { + groupitem = browser->GetFirstChild(browser->GetRootItem(), groupcookie); + while (groupitem) + { + firstserver = (pgServer *)browser->GetObject(browser->GetFirstChild(groupitem, servercookie)); + if (firstserver && !firstserver->GetGroup().IsEmpty() && firstserver->GetGroup() != _("Servers")) + cbGroup->Append(firstserver->GetGroup()); + groupitem = browser->GetNextChild(browser->GetRootItem(), groupcookie); + } + } + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + EnableSSHTunnelControls(false); + radioBtnPassword->SetValue(true); + radioBtnKeyfile->SetValue(false); + txtTunnelPassword->SetMaxLength(SSH_MAX_PASSWORD_LEN); + txtTunnelPort->SetValue(NumToStr((long)DEFAULT_SSH_PORT)); +#ifdef HAVE_OPENSSL_CRYPTO + stPublicKeyFile->Show(false); + pickerPublicKeyFile->Show(false); +#endif +#else + for(size_t i = 0; i < nbNotebook->GetPageCount(); i++) + { + if(nbNotebook->GetPageText(i).compare(wxT("SSH Tunnel")) == 0) + { + nbNotebook->RemovePage(i); + } + } +#endif +} + + +dlgServer::~dlgServer() +{ + if (!server) + { + settings->SetLastDatabase(cbDatabase->GetValue()); + settings->SetLastPort(StrToLong(txtPort->GetValue())); + settings->SetLastSSL(cbSSL->GetCurrentSelection()); + settings->SetLastUsername(txtUsername->GetValue()); + } +} + + +pgObject *dlgServer::GetObject() +{ + return server; +} + + +void dlgServer::OnOK(wxCommandEvent &ev) +{ +#ifdef __WXGTK__ + if (!btnOK->IsEnabled()) + return; +#endif + + // Display the 'save password' hint if required + if(chkStorePwd->GetValue()) + { + if (frmHint::ShowHint(this, HINT_SAVING_PASSWORDS) == wxID_CANCEL) + return; + } + + // notice: changes active after reconnect + EnableOK(false); + + if (server) + { + server->iSetName(GetName()); + server->iSetHostAddr(txtHostAddr->GetValue()); + server->iSetDescription(txtDescription->GetValue()); + server->iSetService(txtService->GetValue()); + if (txtServiceID->GetValue() != server->GetServiceID()) + { + mainForm->StartMsg(_("Checking server status")); + server->iSetServiceID(txtServiceID->GetValue()); + mainForm->EndMsg(); + } + server->iSetPort(StrToLong(txtPort->GetValue())); + server->iSetSSL(cbSSL->GetCurrentSelection()); + server->iSetDatabase(cbDatabase->GetValue()); + server->iSetUsername(txtUsername->GetValue()); + server->iSetRolename(txtRolename->GetValue()); + server->iSetStorePwd(chkStorePwd->GetValue()); + server->iSetRestore(chkRestore->GetValue()); + server->iSetDbRestriction(txtDbRestriction->GetValue().Trim()); + server->SetSSLCert(pickerSSLCert->GetPath()); + server->SetSSLKey(pickerSSLKey->GetPath()); + server->SetSSLRootCert(pickerSSLRootCert->GetPath()); + server->SetSSLCrl(pickerSSLCrl->GetPath()); + server->iSetSSLCompression(chkSSLCompression->GetValue()); +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + server->iSetSSHTunnel(chkSSHTunnel->GetValue()); + server->iSetTunnelPort(StrToLong(txtTunnelPort->GetValue())); + server->SetTunnelHost(txtTunnelHost->GetValue()); + server->SetTunnelUserName(txtTunnelUsername->GetValue()); + server->iSetAuthModePwd(radioBtnPassword->GetValue()); + server->SetTunnelPassword(txtTunnelPassword->GetValue()); + server->SetPublicKeyFile(pickerPublicKeyFile->GetPath()); + server->SetIdentityFile(pickerIdentityFile->GetPath()); +#endif + wxColour colour = colourPicker->GetColour(); + wxString sColour = colour.GetAsString(wxC2S_HTML_SYNTAX); + server->iSetColour(sColour); + if (cbGroup->GetValue().IsEmpty()) + cbGroup->SetValue(_("Servers")); + if (server->GetGroup() != cbGroup->GetValue()) + { + ctlTree *browser = mainForm->GetBrowser(); + wxTreeItemId oldgroupitem, groupitem, serveritem; + wxTreeItemIdValue groupcookie; + bool found; + int total; + wxString label, oldgroupname; + + // Duplicate server object + pgServer *newserver = new pgServer( + server->GetName(), + server->GetHostAddr(), + server->GetDescription(), + server->GetService(), + server->GetDatabaseName(), + server->GetUsername(), + server->GetPort(), + server->GetStorePwd(), + server->GetRolename(), + server->GetRestore(), + server->GetSSL(), + server->GetColour(), +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + server->GetGroup(), + server->GetSSHTunnel(), + server->GetTunnelHost(), + server->GetTunnelUserName(), + server->GetAuthModePwd(), + server->GetTunnelPassword(), + server->GetPublicKeyFile(), + server->GetIdentityFile(), + server->GetTunnelPort()); +#else + server->GetGroup()); +#endif + newserver->iSetDbRestriction(server->GetDbRestriction().Trim()); + newserver->iSetServiceID(server->GetServiceID().Trim()); + newserver->iSetDiscoveryID(server->GetDiscoveryID().Trim()); + newserver->SetSSLCert(server->GetSSLCert()); + newserver->SetSSLKey(server->GetSSLKey()); + newserver->SetSSLRootCert(server->GetSSLRootCert()); + newserver->SetSSLCrl(server->GetSSLCrl()); + newserver->iSetSSLCompression(server->GetSSLCompression()); + + // Drop the old item + // (will also take care of dropping the pgServer item) + oldgroupitem = browser->GetItemParent(item); + oldgroupname = server->GetGroup(); + if (oldgroupname.IsEmpty()) + oldgroupname = _("Servers"); + browser->Delete(item); + + // Move the item + found = false; + if (browser->ItemHasChildren(browser->GetRootItem())) + { + groupitem = browser->GetFirstChild(browser->GetRootItem(), groupcookie); + while (!found && groupitem) + { + if (browser->GetItemText(groupitem).StartsWith(cbGroup->GetValue())) + found = true; + else + groupitem = browser->GetNextChild(browser->GetRootItem(), groupcookie); + } + } + + if (!found) + { + groupitem = browser->AppendItem(browser->GetRootItem(), cbGroup->GetValue(), browser->GetItemImage(browser->GetRootItem())); + browser->SortChildren(browser->GetRootItem()); + } + + serveritem = browser->AppendItem(groupitem, newserver->GetFullName(), newserver->GetIconId(), -1, newserver); + browser->SortChildren(groupitem); + browser->Expand(groupitem); + browser->SelectItem(serveritem); + + // Count the number of items in the old group item + total = browser->GetChildrenCount(oldgroupitem, false); + if (total == 0) + browser->Delete(oldgroupitem); + else + { + label = oldgroupname + wxT(" (") + NumToStr((long)total) + wxT(")"); + browser->SetItemText(oldgroupitem, label); + } + + // Count the number of items in the new group item + total = browser->GetChildrenCount(groupitem, false); + label = cbGroup->GetValue() + wxT(" (") + NumToStr((long)total) + wxT(")"); + browser->SetItemText(groupitem, label); + + // Re-initialize old variables to have their new meanings + server = newserver; + item = serveritem; + } + server->iSetGroup(cbGroup->GetValue()); + + mainForm->execSelChange(server->GetId(), true); + mainForm->GetBrowser()->SetItemText(item, server->GetFullName()); + mainForm->SetItemBackgroundColour(item, wxColour(server->GetColour())); + mainForm->StoreServers(); + } + + if (IsModal()) + { + EndModal(wxID_OK); + return; + } + else + Destroy(); +} + + +void dlgServer::OnChangeColour(wxColourPickerEvent &ev) +{ + dlgProperty::OnChange(ev); +} + + +void dlgServer::OnChangeFile(wxFileDirPickerEvent &ev) +{ + dlgProperty::OnChange(ev); +} + + +void dlgServer::OnChangeRestr(wxCommandEvent &ev) +{ + if (!connection || txtDbRestriction->GetValue().IsEmpty()) + dbRestrictionOk = true; + else + { + wxString sql = wxT("EXPLAIN SELECT 1 FROM pg_database\n") + wxT("WHERE datname IN (") + txtDbRestriction->GetValue() + wxT(")"); + + wxLogNull nix; + wxString result = connection->ExecuteScalar(sql); + + dbRestrictionOk = !result.IsEmpty(); + } + dlgProperty::OnChange(ev); +} + + +void dlgServer::OnPageSelect(wxNotebookEvent &event) +{ + // to prevent dlgProperty from catching it +} + + +wxString dlgServer::GetHelpPage() const +{ + return wxT("connect"); +} + + +int dlgServer::GoNew() +{ + if (cbSSL->GetValue().IsEmpty()) + return Go(true); + else + { + CheckChange(); + return ShowModal(); + } +} + + +int dlgServer::Go(bool modal) +{ + chkSSLCompression->Disable(); + + cbSSL->Clear(); + cbSSL->Append(wxT(" ")); + +#ifdef PG_SSL + cbSSL->Append(_("require")); + cbSSL->Append(_("prefer")); + + if (pgConn::GetLibpqVersion() > 7.3) + { + cbSSL->Append(_("allow")); + cbSSL->Append(_("disable")); + } + + if (pgConn::GetLibpqVersion() >= 8.4) + { + cbSSL->Append(_("verify-ca")); + cbSSL->Append(_("verify-full")); + } + + if (pgConn::GetLibpqVersion() >= 9.2) + { + chkSSLCompression->Enable(); + } +#endif + + if (server) + { + if (cbDatabase->FindString(server->GetDatabaseName()) < 0) + cbDatabase->Append(server->GetDatabaseName()); + txtHostAddr->SetValue(server->GetHostAddr()); + txtDescription->SetValue(server->GetDescription()); + txtService->SetValue(server->GetService()); + txtServiceID->SetValue(server->GetServiceID()); + txtPort->SetValue(NumToStr((long)server->GetPort())); + cbSSL->SetSelection(server->GetSSL()); + cbDatabase->SetValue(server->GetDatabaseName()); + txtUsername->SetValue(server->GetUsername()); + chkStorePwd->SetValue(server->GetStorePwd()); + txtRolename->SetValue(server->GetRolename()); + chkRestore->SetValue(server->GetRestore()); + txtDbRestriction->SetValue(server->GetDbRestriction()); + colourPicker->SetColour(server->GetColour()); + cbGroup->SetValue(server->GetGroup()); + + pickerSSLCert->SetPath(server->GetSSLCert()); + pickerSSLKey->SetPath(server->GetSSLKey()); + pickerSSLRootCert->SetPath(server->GetSSLRootCert()); + pickerSSLCrl->SetPath(server->GetSSLCrl()); + + chkSSLCompression->SetValue(server->GetSSLCompression()); + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + chkSSHTunnel->SetValue(server->GetSSHTunnel()); + if(server->GetSSHTunnel()) + { + chkStorePwd->SetValue(false); + chkStorePwd->Enable(false); + } + txtTunnelPort->SetValue(NumToStr((long)server->GetTunnelPort())); + txtTunnelHost->SetValue(server->GetTunnelHost()); + txtTunnelUsername->SetValue(server->GetTunnelUserName()); + if (server->GetAuthModePwd()) + { + radioBtnPassword->SetValue(true); + radioBtnKeyfile->SetValue(false); + } + else + { + radioBtnPassword->SetValue(false); + radioBtnKeyfile->SetValue(true); + } + txtTunnelPassword->SetValue(server->GetTunnelPassword()); + pickerPublicKeyFile->SetPath(server->GetPublicKeyFile()); + pickerIdentityFile->SetPath(server->GetIdentityFile()); +#endif + stPassword->Disable(); + txtPassword->Disable(); + if (connection) + { + txtHostAddr->Disable(); + txtDescription->Disable(); + txtService->Disable(); + txtServiceID->Disable(); + txtName->Disable(); + cbDatabase->Disable(); + txtPort->Disable(); + cbSSL->Disable(); + txtUsername->Disable(); + chkStorePwd->Disable(); + txtRolename->Disable(); + chkRestore->Disable(); + txtDbRestriction->Disable(); + colourPicker->Disable(); + cbGroup->Disable(); + pickerSSLCert->Disable(); + pickerSSLKey->Disable(); + pickerSSLRootCert->Disable(); + pickerSSLCrl->Disable(); + chkSSLCompression->Disable(); + EnableOK(false); +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + chkSSHTunnel->Enable(false); + EnableSSHTunnelControls(false); + } + else + { + if (server->GetSSHTunnel()) + { + chkSSHTunnel->Enable(true); + EnableSSHTunnelControls(true); + EnableAuthenticationOptions(); + } +#endif + } + } + else + { + SetTitle(_("Add server")); + cbGroup->SetValue(_("Servers")); + wxString colour = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW).GetAsString(wxC2S_HTML_SYNTAX); + colourPicker->SetColour(colour); + } + + // Call CheckRange to set state on OK button + CheckChange(); + return dlgProperty::Go(modal); +} + + +bool dlgServer::GetTryConnect() +{ + return chkTryConnect->GetValue(); +} + + +wxString dlgServer::GetPassword() +{ + return txtPassword->GetValue(); +} + + +pgObject *dlgServer::CreateObject(pgCollection *collection) +{ + pgServer *obj = NULL; + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + if (chkSSHTunnel->GetValue()) + { + obj = new pgServer(GetName(), txtHostAddr->GetValue(), txtDescription->GetValue(), + txtService->GetValue(), cbDatabase->GetValue(), + txtUsername->GetValue(), StrToLong(txtPort->GetValue()), + chkTryConnect->GetValue() && chkStorePwd->GetValue(), + txtRolename->GetValue(), chkRestore->GetValue(), cbSSL->GetCurrentSelection(), + colourPicker->GetColourString(), cbGroup->GetValue(), + chkSSHTunnel->GetValue(), txtTunnelHost->GetValue(), txtTunnelUsername->GetValue(), + radioBtnPassword->GetValue(), + txtTunnelPassword->GetValue(), pickerPublicKeyFile->GetPath(), + pickerIdentityFile->GetPath(), StrToLong(txtTunnelPort->GetValue())); + } + else +#endif + { + obj = new pgServer(GetName(), txtHostAddr->GetValue(), txtDescription->GetValue(), + txtService->GetValue(), cbDatabase->GetValue(), + txtUsername->GetValue(), StrToLong(txtPort->GetValue()), + chkTryConnect->GetValue() && chkStorePwd->GetValue(), + txtRolename->GetValue(), chkRestore->GetValue(), cbSSL->GetCurrentSelection(), + colourPicker->GetColourString(), cbGroup->GetValue()); + } + + obj->iSetDbRestriction(txtDbRestriction->GetValue().Trim()); + obj->iSetServiceID(txtServiceID->GetValue()); + obj->SetSSLCert(pickerSSLCert->GetTextCtrlValue()); + obj->SetSSLKey(pickerSSLKey->GetTextCtrlValue()); + obj->SetSSLRootCert(pickerSSLRootCert->GetTextCtrlValue()); + obj->SetSSLCrl(pickerSSLCrl->GetTextCtrlValue()); + obj->iSetSSLCompression(chkSSLCompression->GetValue()); + + return obj; +} + + +void dlgServer::OnChangeTryConnect(wxCommandEvent &ev) +{ + chkStorePwd->Enable(chkTryConnect->GetValue() && !connection); + txtPassword->Enable(chkTryConnect->GetValue() && !connection); + OnChange(ev); +} + + +void dlgServer::CheckChange() +{ + wxString name = GetName(); + bool enable = true; + + if (server) + { + // Get old value + wxColour colour; + wxString sColour = wxEmptyString; + + if (colour.Set(server->GetColour())) + sColour = colour.GetAsString(wxC2S_HTML_SYNTAX); + + // Get new value + wxString sColour2 = colourPicker->GetColourString(); + + enable = name != server->GetName() + || txtHostAddr->GetValue() != server->GetHostAddr() + || txtDescription->GetValue() != server->GetDescription() + || txtService->GetValue() != server->GetService() + || txtServiceID->GetValue() != server->GetServiceID() + || StrToLong(txtPort->GetValue()) != server->GetPort() + || cbDatabase->GetValue() != server->GetDatabaseName() + || txtUsername->GetValue() != server->GetUsername() + || cbSSL->GetCurrentSelection() != server->GetSSL() + || chkStorePwd->GetValue() != server->GetStorePwd() + || txtRolename->GetValue() != server->GetRolename() + || chkRestore->GetValue() != server->GetRestore() + || txtDbRestriction->GetValue() != server->GetDbRestriction() + || sColour != sColour2 + || cbGroup->GetValue() != server->GetGroup() + || pickerSSLCert->GetPath() != server->GetSSLCert() + || pickerSSLKey->GetPath() != server->GetSSLKey() + || pickerSSLRootCert->GetPath() != server->GetSSLRootCert() + || pickerSSLCrl->GetPath() != server->GetSSLCrl() + || chkSSLCompression->GetValue() != server->GetSSLCompression(); + } + +#ifdef __WXMSW__ + CheckValid(enable, !name.IsEmpty(), _("Please specify address.")); +#else + bool isPipe = (name.IsEmpty() || name.StartsWith(wxT("/"))); + cbSSL->Enable(!isPipe && !connection); +#endif + CheckValid(enable, !txtDescription->GetValue().IsEmpty(), _("Please specify description.")); + if (txtService->GetValue().IsEmpty()) + { + CheckValid(enable, StrToLong(txtPort->GetValue()) > 0, _("Please specify port.")); + CheckValid(enable, !txtUsername->GetValue().IsEmpty(), _("Please specify user name")); + } + CheckValid(enable, dbRestrictionOk, _("Restriction not valid.")); + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + if(chkSSHTunnel->GetValue()) + { + CheckValid(enable, !txtTunnelHost->GetValue().IsEmpty(), _("Please specify ssh tunnel host.")); + CheckValid(enable, !txtTunnelPort->GetValue().IsEmpty(), _("Please specify ssh tunnel port.")); + CheckValid(enable, !txtTunnelUsername->GetValue().IsEmpty(), _("Please specify ssh tunnel user name.")); + } +#endif + + EnableOK(enable && !connection); +} + + +wxString dlgServer::GetSql() +{ + return wxEmptyString; +} + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + +void dlgServer::OnCheckSSHTunnel(wxCommandEvent &ev) +{ + if (chkSSHTunnel->IsChecked()) + { + if(chkStorePwd->GetValue()) + { + wxMessageBox(_("Database passwords cannot be stored when using SSH tunnelling. The 'Store password' option has been turned off."), _("Stored Password"), wxICON_EXCLAMATION | wxOK, this); + } + chkStorePwd->SetValue(false); + chkStorePwd->Enable(false); + EnableSSHTunnelControls(true); + EnableAuthenticationOptions(); + } + else + { + chkStorePwd->Enable(); + EnableSSHTunnelControls(false); + } + + CheckChange(); +} + +void dlgServer::OnChangeAuthOption(wxCommandEvent &ev) +{ + EnableAuthenticationOptions(); +} + +void dlgServer::EnableSSHTunnelControls(const bool &bEnable) +{ + txtTunnelHost->Enable(bEnable); + txtTunnelUsername->Enable(bEnable); + pickerPublicKeyFile->Enable(bEnable); + pickerIdentityFile->Enable(bEnable); + radioBtnPassword->Enable(bEnable); + radioBtnKeyfile->Enable(bEnable); + txtTunnelPassword->Enable(bEnable); + txtTunnelPort->Enable(bEnable); +} + +void dlgServer::EnableAuthenticationOptions() +{ + if (radioBtnPassword->GetValue()) + { + pickerIdentityFile->Enable(false); + pickerPublicKeyFile->Enable(false); + } + else + { + pickerIdentityFile->Enable(true); + pickerPublicKeyFile->Enable(true); + } +} +#endif diff --git a/dlg/dlgSynonym.cpp b/dlg/dlgSynonym.cpp new file mode 100644 index 0000000..a3bd189 --- /dev/null +++ b/dlg/dlgSynonym.cpp @@ -0,0 +1,316 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgSynonym.cpp - EnterpriseDB Synonym Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgSynonym.h" +#include "schema/edbSynonym.h" +#include "schema/edbPrivateSynonym.h" + +// pointer to controls +#define txtName CTRL_TEXT("txtName") +#define cbTargetType CTRL_COMBOBOX2("cbTargetType") +#define cbTargetSchema CTRL_COMBOBOX2("cbTargetSchema") +#define cbTargetObject CTRL_COMBOBOX("cbTargetObject") +#define stComment CTRL_STATIC("stComment") + +dlgProperty *edbSynonymFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgSynonym(this, frame, (edbSynonym *)node); +} + +dlgProperty *edbPrivateSynonymFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgSynonym(this, frame, (edbPrivateSynonym *)node, (pgSchema *)parent); +} + + +BEGIN_EVENT_TABLE(dlgSynonym, dlgProperty) + EVT_TEXT(XRCID("cbTargetType"), dlgSynonym::OnChangeTargetType) + EVT_COMBOBOX(XRCID("cbTargetType"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbTargetSchema"), dlgSynonym::OnChangeTargetSchema) + EVT_COMBOBOX(XRCID("cbTargetSchema"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbTargetObject"), dlgProperty::OnChange) +END_EVENT_TABLE(); + + +dlgSynonym::dlgSynonym(pgaFactory *f, frmMain *frame, edbSynonym *node) + : dlgProperty(f, frame, wxT("dlgSynonym")) +{ + synonym = node; + privSynonym = NULL; + synonymSchema = NULL; + cbOwner->Disable(); +} + +dlgSynonym::dlgSynonym(edbPrivateSynonymFactory *factory, frmMain *frame, edbPrivateSynonym *syn, pgSchema *schema) + : dlgProperty((pgaFactory *)factory, frame, wxT("dlgSynonym")) +{ + synonym = NULL; + privSynonym = syn; + synonymSchema = schema; + cbOwner->Disable(); +} + + +pgObject *dlgSynonym::GetObject() +{ + if (!synonymSchema) + return synonym; + return (pgObject *)privSynonym; +} + + +int dlgSynonym::Go(bool modal) +{ + if (synonym) + { + // edit mode + txtName->Disable(); + + cbTargetType->SetSelection(cbTargetType->FindString(synonym->GetTargetType())); + ProcessTypeChange(); + + if (cbTargetType->GetValue() != _("Public synonym")) + { + cbTargetSchema->SetSelection(cbTargetSchema->FindString(synonym->GetTargetSchema())); + ProcessSchemaChange(); + } + cbTargetObject->SetSelection(cbTargetObject->FindString(synonym->GetTargetObject())); + } + else if (privSynonym) + { + // edit mode + txtName->Disable(); + + cbTargetType->SetSelection(cbTargetType->FindString(privSynonym->GetTargetType())); + ProcessTypeChange(); + + cbTargetSchema->SetSelection(cbTargetSchema->FindString(privSynonym->GetTargetSchema())); + ProcessSchemaChange(); + + cbTargetObject->SetSelection(cbTargetObject->FindString(privSynonym->GetTargetObject())); + } + else + { + // create mode + cbTargetType->Enable(); + cbTargetSchema->Disable(); + cbTargetObject->Disable(); + } + + txtComment->Disable(); + + // Functions and Procedures are available 8.4 onwards. So check for the + // same. Unfortunately we need a connection object for that and so we + // re-use an existing one.. + if (connection && connection->BackendMinimumVersion(8, 4)) + { + cbTargetType->Append(_("Function")); + cbTargetType->Append(_("Procedure")); + } + cbTargetType->Append(_("Sequence")); + cbTargetType->Append(_("Public synonym")); + cbTargetType->Append(_("Table")); + cbTargetType->Append(_("View")); + + return dlgProperty::Go(modal); +} + + +pgObject *dlgSynonym::CreateObject(pgCollection *collection) +{ + pgObject *obj = NULL; + if (!synonymSchema) + obj = synonymFactory.CreateObjects(collection, 0, + wxT(" WHERE synname = ") + qtDbString(GetName())); + else + obj = edbPrivFactory.CreateObjects(collection, 0, + wxT(" WHERE s.synname=") + qtDbString(GetName()) + + wxT(" AND s.synnamespace=") + collection->GetSchema()->GetOidStr() + wxT(" \n")); + + return obj; +} + + +void dlgSynonym::CheckChange() +{ + bool enable = true; + CheckValid(enable, !txtName->GetValue().IsEmpty(), _("Please specify name.")); + CheckValid(enable, !cbTargetType->GetValue().IsEmpty(), _("Please select target type.")); + // Public Synonyms does supported in public only + if (!synonymSchema && cbTargetType->GetValue() != _("Public synonym")) + CheckValid(enable, !cbTargetSchema->GetValue().IsEmpty(), _("Please select target schema.")); + CheckValid(enable, !cbTargetObject->GetValue().IsEmpty(), _("Please select target object.")); + + if (!enable) + { + EnableOK(enable); + return; + } + + if (synonym) + EnableOK(synonym->GetTargetObject() != cbTargetObject->GetValue()); + else if (privSynonym) + EnableOK(privSynonym->GetTargetObject() != cbTargetObject->GetValue()); + else + EnableOK(txtName->GetValue() != wxEmptyString && cbTargetObject->GetValue() != wxEmptyString); +} + +void dlgSynonym::ProcessTypeChange() +{ + cbTargetSchema->Clear(); + cbTargetObject->Clear(); + if (cbTargetType->GetValue() != _("Public synonym")) + { + pgSet *schemas; + if (connection->BackendMinimumVersion(8, 2)) + schemas = connection->ExecuteSet(wxT("SELECT nspname FROM pg_namespace WHERE nspparent = 0 AND nspname NOT LIKE E'pg\\_%' AND nspname NOT IN ('pg_catalog', 'sys', 'dbo', 'pgagent', 'information_schema', 'dbms_job_procedure') ORDER BY nspname;")); + else if (connection->BackendMinimumVersion(8, 1)) + schemas = connection->ExecuteSet(wxT("SELECT nspname FROM pg_namespace WHERE nspname NOT LIKE E'pg\\_%' ORDER BY nspname;")); + else + schemas = connection->ExecuteSet(wxT("SELECT nspname FROM pg_namespace WHERE nspname NOT LIKE 'pg\\_%' ORDER BY nspname;")); + + for (int x = 0; x < schemas->NumRows(); x++) + { + cbTargetSchema->Append(schemas->GetVal(0)); + schemas->MoveNext(); + } + delete schemas; + + cbTargetSchema->Enable(); + cbTargetSchema->SetValue(wxT("public")); + ProcessSchemaChange(); + } + else + { + pgSet *synonyms = connection->ExecuteSet(wxT("SELECT synname FROM pg_synonym ORDER BY synname;")); + for (int x = 0; x < synonyms->NumRows(); x++) + { + cbTargetObject->Append(synonyms->GetVal(0)); + synonyms->MoveNext(); + } + delete synonyms; + + cbTargetSchema->Disable(); + cbTargetObject->Enable(); + } +} + +void dlgSynonym::ProcessSchemaChange() +{ + cbTargetObject->Clear(); + + wxString restriction; + if (cbTargetType->GetValue() == _("Sequence")) + restriction = wxT("S"); + else if (cbTargetType->GetValue() == _("Table")) + restriction = wxT("r"); + else if (cbTargetType->GetValue() == _("View")) + restriction = wxT("v"); + else if (cbTargetType->GetValue() == _("Function")) + restriction = wxT("0"); + else if (cbTargetType->GetValue() == _("Procedure")) + restriction = wxT("1"); + + wxString sql; + if (cbTargetType->GetValue() == _("Synonym")) + { + sql = wxT("SELECT synname FROM pg_synonym s JOIN pg_namespace n\n") + wxT(" ON s.synnamespace = n.oid AND \n") + wxT(" n.nspname = ") + qtDbString(cbTargetSchema->GetValue()) + + wxT(" ORDER BY synname;"); + } + else if (cbTargetType->GetValue() == _("Function") || + cbTargetType->GetValue() == _("Procedure")) + { + // "protype" is available, no need to check for version again here.. + sql = wxT("SELECT DISTINCT proname from pg_proc p, pg_namespace n\n") + wxT(" WHERE p.pronamespace = n.oid AND\n") + wxT(" n.nspname = ") + qtDbString(cbTargetSchema->GetValue()) + wxT(" AND\n") + wxT(" p.protype = '") + restriction + wxT("' ORDER BY proname;"); + } + else if (cbTargetType->GetValue() == _("View")) + { + wxString mviewRestriction = wxT("m"); + sql = wxT("SELECT relname FROM pg_class c, pg_namespace n\n") + wxT(" WHERE c.relnamespace = n.oid AND\n") + wxT(" n.nspname = ") + qtDbString(cbTargetSchema->GetValue()) + wxT(" AND\n") + wxT(" (c.relkind = '") + restriction + wxT("' OR c.relkind = '") + mviewRestriction + wxT("') ORDER BY relname;"); + } + else + { + sql = wxT("SELECT relname FROM pg_class c, pg_namespace n\n") + wxT(" WHERE c.relnamespace = n.oid AND\n") + wxT(" n.nspname = ") + qtDbString(cbTargetSchema->GetValue()) + wxT(" AND\n") + wxT(" c.relkind = '") + restriction + wxT("' ORDER BY relname;"); + } + + pgSet *objects = connection->ExecuteSet(sql); + for (int x = 0; x < objects->NumRows(); x++) + { + cbTargetObject->Append(objects->GetVal(0)); + objects->MoveNext(); + } + delete objects; + + cbTargetObject->Enable(); +} + + +wxString dlgSynonym::GetSql() +{ + wxString sql; + + if (!synonymSchema) + { + + sql = wxT("CREATE OR REPLACE PUBLIC SYNONYM ") + qtIdent(txtName->GetValue()) + wxT("\n FOR "); + + if (cbTargetSchema->GetValue() != wxEmptyString) + sql += qtIdent(cbTargetSchema->GetValue()) + wxT("."); + + sql += qtIdent(cbTargetObject->GetValue()) + wxT(";\n"); + + AppendComment(sql, wxT("PUBLIC SYNONYM ") + qtIdent(txtName->GetValue()), synonym); + } + else + { + wxString createSql, commentSql; + if (synonymSchema->GetName() == wxT("public")) + { + createSql = wxT("CREATE OR REPLACE PUBLIC SYNONYM "); + commentSql = wxT("PUBLIC SYNONYM "); + } + else + { + createSql = wxT("CREATE OR REPLACE SYNONYM ") + qtIdent(synonymSchema->GetName()) + wxT("."); + commentSql = wxT("PRIVATE SYNONYM "); + } + + sql = createSql + qtIdent(txtName->GetValue()) + wxT("\n FOR "); + + if (cbTargetSchema->GetValue() != wxEmptyString) + sql += qtIdent(cbTargetSchema->GetValue()) + wxT("."); + + sql += qtIdent(cbTargetObject->GetValue()) + wxT(";\n"); + + AppendComment(sql, commentSql + qtIdent(txtName->GetValue()), synonym); + } + + return sql; +} diff --git a/dlg/dlgTable.cpp b/dlg/dlgTable.cpp new file mode 100644 index 0000000..b6f8a67 --- /dev/null +++ b/dlg/dlgTable.cpp @@ -0,0 +1,2130 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgTable.cpp - PostgreSQL Table Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "frm/frmMain.h" +#include "frm/frmHint.h" + +#include "dlg/dlgTable.h" +#include "dlg/dlgColumn.h" +#include "dlg/dlgIndexConstraint.h" +#include "dlg/dlgForeignKey.h" +#include "dlg/dlgCheck.h" + +#include "schema/gpPartition.h" +#include "schema/pgPartition.h" +#include "schema/pgSchema.h" +#include "schema/pgTable.h" +#include "schema/pgColumn.h" +#include "schema/pgCheck.h" +#include "schema/pgForeignKey.h" +#include "schema/pgIndexConstraint.h" +#include "schema/pgDatatype.h" +#include "ctl/ctlSeclabelPanel.h" + + +#define stUnlogged CTRL_STATIC("stUnlogged") +#define chkUnlogged CTRL_CHECKBOX("chkUnlogged") +#define stHasOids CTRL_STATIC("stHasOids") +#define chkHasOids CTRL_CHECKBOX("chkHasOids") +#define lbTables CTRL_LISTBOX("lbTables") +#define btnAddTable CTRL_BUTTON("btnAddTable") +#define btnRemoveTable CTRL_BUTTON("btnRemoveTable") +#define cbTables CTRL_COMBOBOX2("cbTables") +#define cbTablespace CTRL_COMBOBOX("cbTablespace") +#define cbOfType CTRL_COMBOBOX("cbOfType") +#define txtFillFactor CTRL_TEXT("txtFillFactor") + +#define btnAddCol CTRL_BUTTON("btnAddCol") +#define btnChangeCol CTRL_BUTTON("btnChangeCol") +#define btnRemoveCol CTRL_BUTTON("btnRemoveCol") + +#define lstConstraints CTRL_LISTVIEW("lstConstraints") +#define btnAddConstr CTRL_BUTTON("btnAddConstr") +#define cbConstrType CTRL_COMBOBOX("cbConstrType") +#define btnRemoveConstr CTRL_BUTTON("btnRemoveConstr") + +#define cbLikeRelation CTRL_COMBOBOX("cbLikeRelation") +#define chkIncludingDefaults CTRL_CHECKBOX("chkIncludingDefaults") +#define chkIncludingConstraints CTRL_CHECKBOX("chkIncludingConstraints") +#define chkIncludingIndexes CTRL_CHECKBOX("chkIncludingIndexes") +#define chkIncludingStorage CTRL_CHECKBOX("chkIncludingStorage") +#define chkIncludingComments CTRL_CHECKBOX("chkIncludingComments") + +/* AutoVacuum Settings */ +#define nbVaccum CTRL_NOTEBOOK("nbVacuum") +#define chkCustomVac CTRL_CHECKBOX("chkCustomVac") +#define chkVacEnabled CTRL_CHECKBOX("chkVacEnabled") +#define txtBaseVac CTRL_TEXT("txtBaseVac") +#define stBaseVacCurr CTRL_STATIC("stBaseVacCurr") +#define txtBaseAn CTRL_TEXT("txtBaseAn") +#define stBaseAnCurr CTRL_STATIC("stBaseAnCurr") +#define txtFactorVac CTRL_TEXT("txtFactorVac") +#define stFactorVacCurr CTRL_STATIC("stFactorVacCurr") +#define txtFactorAn CTRL_TEXT("txtFactorAn") +#define stFactorAnCurr CTRL_STATIC("stFactorAnCurr") +#define txtVacDelay CTRL_TEXT("txtVacDelay") +#define stVacDelayCurr CTRL_STATIC("stVacDelayCurr") +#define txtVacLimit CTRL_TEXT("txtVacLimit") +#define stVacLimitCurr CTRL_STATIC("stVacLimitCurr") +#define txtFreezeMinAge CTRL_TEXT("txtFreezeMinAge") +#define stFreezeMinAgeCurr CTRL_STATIC("stFreezeMinAgeCurr") +#define txtFreezeMaxAge CTRL_TEXT("txtFreezeMaxAge") +#define stFreezeMaxAgeCurr CTRL_STATIC("stFreezeMaxAgeCurr") +#define txtFreezeTableAge CTRL_TEXT("txtFreezeTableAge") +#define stFreezeTableAgeCurr CTRL_STATIC("stFreezeTableAgeCurr") + +/* TOAST TABLE AutoVacuum Settings */ +#define chkCustomToastVac CTRL_CHECKBOX("chkCustomToastVac") +#define chkToastVacEnabled CTRL_CHECKBOX("chkToastVacEnabled") +#define txtBaseToastVac CTRL_TEXT("txtBaseToastVac") +#define stBaseToastVacCurr CTRL_STATIC("stBaseToastVacCurr") +#define txtFactorToastVac CTRL_TEXT("txtFactorToastVac") +#define stFactorToastVacCurr CTRL_STATIC("stFactorToastVacCurr") +#define txtToastVacDelay CTRL_TEXT("txtToastVacDelay") +#define stToastVacDelayCurr CTRL_STATIC("stToastVacDelayCurr") +#define txtToastVacLimit CTRL_TEXT("txtToastVacLimit") +#define stToastVacLimitCurr CTRL_STATIC("stToastVacLimitCurr") +#define txtToastFreezeMinAge CTRL_TEXT("txtToastFreezeMinAge") +#define stToastFreezeMinAgeCurr CTRL_STATIC("stToastFreezeMinAgeCurr") +#define txtToastFreezeMaxAge CTRL_TEXT("txtToastFreezeMaxAge") +#define stToastFreezeMaxAgeCurr CTRL_STATIC("stToastFreezeMaxAgeCurr") +#define txtToastFreezeTableAge CTRL_TEXT("txtToastFreezeTableAge") +#define stToastFreezeTableAgeCurr CTRL_STATIC("stToastFreezeTableAgeCurr") + + +BEGIN_EVENT_TABLE(dlgTable, dlgSecurityProperty) + EVT_CHECKBOX(XRCID("chkUnlogged"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbTablespace"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbTablespace"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtFillFactor"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbOfType"), dlgTable::OnChangeOfType) + EVT_CHECKBOX(XRCID("chkHasOids"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbTables"), dlgTable::OnChangeTable) + EVT_BUTTON(XRCID("btnAddTable"), dlgTable::OnAddTable) + EVT_BUTTON(XRCID("btnRemoveTable"), dlgTable::OnRemoveTable) + EVT_LISTBOX(XRCID("lbTables"), dlgTable::OnSelChangeTable) + + EVT_BUTTON(XRCID("btnAddCol"), dlgTable::OnAddCol) + EVT_BUTTON(XRCID("btnChangeCol"), dlgTable::OnChangeCol) + EVT_BUTTON(XRCID("btnRemoveCol"), dlgTable::OnRemoveCol) + EVT_LIST_ITEM_SELECTED(XRCID("lstColumns"), dlgTable::OnSelChangeCol) + + EVT_BUTTON(XRCID("btnAddConstr"), dlgTable::OnAddConstr) + EVT_BUTTON(XRCID("btnRemoveConstr"), dlgTable::OnRemoveConstr) + EVT_LIST_ITEM_SELECTED(XRCID("lstConstraints"), dlgTable::OnSelChangeConstr) + + /* AutoVacuum Settings */ + EVT_CHECKBOX(XRCID("chkCustomVac"), dlgTable::OnChangeVacuum) + EVT_CHECKBOX(XRCID("chkVacEnabled"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtBaseVac"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtBaseAn"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtFactorVac"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtFactorAn"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtVacDelay"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtVacLimit"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtFreezeMinAge"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtFreezeMaxAge"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtFreezeTableAge"), dlgTable::OnChangeVacuum) + + /* TOAST TABLE AutoVacuum Settings */ + EVT_CHECKBOX(XRCID("chkCustomToastVac"), dlgTable::OnChangeVacuum) + EVT_CHECKBOX(XRCID("chkToastVacEnabled"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtBaseToastVac"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtFactorToastVac"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtToastVacDelay"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtToastVacLimit"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtToastFreezeMinAge"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtToastFreezeMaxAge"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtToastFreezeTableAge"), dlgTable::OnChangeVacuum) + + EVT_BUTTON(wxID_OK, dlgTable::OnOK) + +#ifdef __WXMAC__ + EVT_SIZE( dlgTable::OnChangeSize) +#endif +END_EVENT_TABLE(); + + +dlgProperty *pgTableFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgTable(this, frame, (pgTable *)node, (pgSchema *)parent); +} + +dlgProperty *gpPartitionFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgTable(this, frame, (gpPartition *)node, (pgSchema *)parent); +} +dlgProperty *pgPartitionFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + pgObject *parentNode; + parentNode = parent; + // found schema node + while (parentNode->GetMetaType() != PGM_SCHEMA) { + if (parentNode && /*parentNode->IsCollection() && */parentNode->GetMetaType() != PGM_SERVER) + parentNode = frame->GetBrowser()->GetObject( + frame->GetBrowser()->GetItemParent(parentNode->GetId())); + else + break; + } + parent=parentNode; + return new dlgTable(this, frame, (pgPartition *)node, (pgSchema *)parent); +} + +dlgTable::dlgTable(pgaFactory *f, frmMain *frame, pgTable *node, pgSchema *sch) + : dlgSecurityProperty(f, frame, node, wxT("dlgTable"), wxT("INSERT,SELECT,UPDATE,DELETE,TRUNCATE,RULE,REFERENCES,TRIGGER"), "arwdDRxt") +{ + schema = sch; + table = node; + + seclabelPage = new ctlSeclabelPanel(nbNotebook); + + btnAddTable->Disable(); + btnRemoveTable->Disable(); + + // Visible columns + lstColumns->AddColumn(_("Column name"), 90); + lstColumns->AddColumn(_("Definition"), 135); +#ifndef __WXMAC__ + lstColumns->AddColumn(_("Inherited from table"), 40); +#else + lstColumns->AddColumn(_("Inherited from table"), 80); +#endif + // Invisible columns + // ... sql definition + lstColumns->AddColumn(_("Column definition"), 0); + // ... new comment + lstColumns->AddColumn(_("Column comment"), 0); + // ... new statistics + lstColumns->AddColumn(_("Column statistics"), 0); + // ... pgColumn* handle (used for new columns) + lstColumns->AddColumn(_("Column"), 0); + // ... new type OID + lstColumns->AddColumn(_("Column type oid"), 0); + // ... pgColumn* handle (used for changed columns) + lstColumns->AddColumn(_("Changed column"), 0); + // ... pgColumn* handle (used for variable list) + lstColumns->AddColumn(_("Variable List"), 0); + // ... pgColumn* handle (used for security label list) + lstColumns->AddColumn(_("Security Label List"), 0); + lstConstraints->CreateColumns(0, _("Constraint name"), _("Definition"), 90); +} + +dlgTable::~dlgTable() +{ + //Clear the cached datatypes + size_t i; + for (i = 0; i < dtCache.GetCount(); i++) + delete dtCache.Item(i); +} + +bool dlgTable::Destroy() +{ + for(int pos = 0; pos < lstColumns->GetItemCount(); pos++) + { + pgColumn *column2 = (pgColumn *) StrToLong(lstColumns->GetText(pos, COL_CHANGEDCOL)); + if(column2) delete column2; + } + return dlgProperty::Destroy(); +} + +pgObject *dlgTable::GetObject() +{ + return table; +} + + +int dlgTable::Go(bool modal) +{ + PrepareTablespace(cbTablespace); + PopulateDatatypeCache(); + + if (connection->BackendMinimumVersion(9, 1)) + { + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(table); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgTable::OnChange)); + } + else + seclabelPage->Disable(); + + // new "of type" combobox + wxString typeQuery = wxT("SELECT t.oid, t.typname ") + wxT("FROM pg_type t, pg_namespace n ") + wxT("WHERE t.typtype='c' AND t.typnamespace=n.oid ") + wxT("AND NOT (n.nspname like 'pg_%' OR n.nspname='information_schema') ") + wxT("ORDER BY typname"); + cbOfType->Insert(wxEmptyString, 0, (void *)0); + cbOfType->FillOidKey(connection, typeQuery); + cbOfType->SetSelection(0); + + // "like relation" tab + nbNotebook->GetPage(TAB_LIKE)->Enable(!table); + + hasPK = false; + + if (table) + { + // edit mode + chkUnlogged->SetValue(table->GetUnlogged()); + chkHasOids->SetValue(table->GetHasOids()); + + if (table->GetTablespaceOid() != 0) + cbTablespace->SetKey(table->GetTablespaceOid()); + + if (table->GetOfTypeOid() != 0) + cbOfType->SetKey(table->GetOfTypeOid()); + + inheritedTableOids = table->GetInheritedTablesOidList(); + + wxArrayString qitl = table->GetQuotedInheritedTablesList(); + size_t i; + for (i = 0 ; i < qitl.GetCount() ; i++) + { + previousTables.Add(qitl.Item(i)); + lbTables->Append(qitl.Item(i)); + } + + btnAddTable->Enable(connection->BackendMinimumVersion(8, 2) && cbTables->GetGuessedSelection() >= 0); + lbTables->Enable(connection->BackendMinimumVersion(8, 2)); + chkHasOids->Enable((connection->BackendMinimumVersion(8, 0) && table->GetHasOids()) + || connection->BackendMinimumVersion(8, 4)); + cbSchema->Enable(connection->BackendMinimumVersion(8, 1)); + cbTablespace->Enable(connection->BackendMinimumVersion(7, 5)); + + wxCookieType cookie; + pgObject *data = 0; + wxTreeItemId item = mainForm->GetBrowser()->GetFirstChild(table->GetId(), cookie); + while (item) + { + data = mainForm->GetBrowser()->GetObject(item); + pgaFactory *factory = data->GetFactory(); + if (factory == columnFactory.GetCollectionFactory()) + columnsItem = item; + else if (factory == checkFactory.GetCollectionFactory()) + constraintsItem = item; + if (data->GetMetaType() == PGM_COLUMN && data->IsCollection()) + columnsItem = item; + else if (data->GetMetaType() == PGM_CONSTRAINT) + constraintsItem = item; + + if (columnsItem && constraintsItem) + break; + + item = mainForm->GetBrowser()->GetNextChild(table->GetId(), cookie); + } + + if (columnsItem) + { + pgCollection *coll = (pgCollection *)data; + // make sure all columns are appended + coll->ShowTreeDetail(mainForm->GetBrowser()); + // this is the columns collection + item = mainForm->GetBrowser()->GetFirstChild(columnsItem, cookie); + + // add columns + while (item) + { + data = mainForm->GetBrowser()->GetObject(item); + if (data->IsCreatedBy(columnFactory)) + { + pgColumn *column = (pgColumn *)data; + // make sure column details are read + column->ShowTreeDetail(mainForm->GetBrowser()); + + if (column->GetColNumber() > 0) + { + bool inherited = (column->GetInheritedCount() != 0); + int pos = lstColumns->AppendItem((inherited ? tableFactory.GetIconId() : column->GetIconId()), + column->GetName(), column->GetDefinition()); + previousColumns.Add(column->GetQuotedIdentifier() + + wxT(" ") + column->GetDefinition()); + lstColumns->SetItem(pos, COL_PGCOLUMN, NumToStr((long)column)); + if (inherited) + lstColumns->SetItem(pos, COL_INHERIT, column->GetInheritedTableName()); + } + } + + item = mainForm->GetBrowser()->GetNextChild(columnsItem, cookie); + } + } + if (constraintsItem) + { + pgCollection *coll = (pgCollection *)mainForm->GetBrowser()->GetObject(constraintsItem); + // make sure all constraints are appended + coll->ShowTreeDetail(mainForm->GetBrowser()); + // this is the constraints collection + item = mainForm->GetBrowser()->GetFirstChild(constraintsItem, cookie); + + // add constraints + while (item) + { + data = mainForm->GetBrowser()->GetObject(item); + switch (data->GetMetaType()) + { + case PGM_PRIMARYKEY: + hasPK = true; + case PGM_UNIQUE: + { + pgIndexConstraint *obj = (pgIndexConstraint *)data; + + lstConstraints->AppendItem(data->GetIconId(), obj->GetName(), obj->GetDefinition()); + constraintsDefinition.Add(obj->GetDefinition()); + previousConstraints.Add(obj->GetQuotedIdentifier() + + wxT(" ") + obj->GetTypeName().Upper() + wxT(" ") + obj->GetDefinition()); + break; + } + case PGM_EXCLUDE: + { + pgIndexConstraint *obj = (pgIndexConstraint *)data; + + lstConstraints->AppendItem(data->GetIconId(), obj->GetName(), obj->GetDefinition()); + constraintsDefinition.Add(obj->GetDefinition()); + previousConstraints.Add(obj->GetQuotedIdentifier() + + wxT(" ") + obj->GetTypeName().Upper() + wxT(" ") + obj->GetDefinition()); + break; + } + case PGM_FOREIGNKEY: + { + pgForeignKey *obj = (pgForeignKey *)data; + wxString def = obj->GetDefinition(); + + lstConstraints->AppendItem(data->GetIconId(), obj->GetName(), def); + constraintsDefinition.Add(obj->GetDefinition()); + previousConstraints.Add(obj->GetQuotedIdentifier() + + wxT(" ") + obj->GetTypeName().Upper() + wxT(" ") + def); + break; + } + case PGM_CHECK: + { + pgCheck *obj = (pgCheck *)data; + + lstConstraints->AppendItem(data->GetIconId(), obj->GetName(), obj->GetDefinition()); + constraintsDefinition.Add(obj->GetDefinition()); + previousConstraints.Add(obj->GetQuotedIdentifier() + + wxT(" ") + obj->GetTypeName().Upper() + wxT(" ") + obj->GetDefinition()); + break; + } + } + + item = mainForm->GetBrowser()->GetNextChild(constraintsItem, cookie); + } + } + } + else + { + // create mode + btnChangeCol->Hide(); + + // Add the default tablespace + cbTablespace->Insert(_(""), 0, (void *)0); + cbTablespace->SetSelection(0); + + // new "like relation" combobox + wxString likeRelationQuery = wxT("SELECT c.oid, quote_ident(n.nspname)||'.'||quote_ident(c.relname) ") + wxT("FROM pg_class c, pg_namespace n ") + wxT("WHERE c.relnamespace=n.oid AND c.relkind IN "); + if (connection->BackendMinimumVersion(9, 2)) + { + likeRelationQuery += wxT("('r', 'v', 'f')"); + } + else + { + likeRelationQuery += wxT("('r')"); + } + if (!settings->GetShowSystemObjects()) + likeRelationQuery += wxT(" AND ") + connection->SystemNamespaceRestriction(wxT("n.nspname")); + likeRelationQuery += wxT(" ORDER BY 1"); + cbLikeRelation->Insert(wxEmptyString, 0, (void *)0); + cbLikeRelation->FillOidKey(connection, likeRelationQuery); + cbLikeRelation->SetSelection(0); + + // Enable the "like relation" comboboxes + chkIncludingDefaults->Enable(); + chkIncludingConstraints->Enable(connection->BackendMinimumVersion(8, 2)); + chkIncludingIndexes->Enable(connection->BackendMinimumVersion(8, 3)); + chkIncludingStorage->Enable(connection->BackendMinimumVersion(9, 0)); + chkIncludingComments->Enable(connection->BackendMinimumVersion(9, 0)); + } + + chkUnlogged->Enable(connection->BackendMinimumVersion(9, 1) && !table); + cbOfType->Enable(connection->BackendMinimumVersion(9, 0) && !table); + cbTables->Enable(connection->BackendMinimumVersion(8, 2) && cbOfType->GetCurrentSelection() == 0); + + if (connection->BackendMinimumVersion(8, 2) || !table) + { + wxString systemRestriction; + if (!settings->GetShowSystemObjects()) + systemRestriction = + wxT(" AND ") + connection->SystemNamespaceRestriction(wxT("n.nspname")); + + if (table) + { + wxString oids = table->GetOidStr(); + int i; + for (i = 0 ; i < (int)inheritedTableOids.GetCount() ; i++) + { + oids += wxT(", ") + inheritedTableOids.Item(i); + } + if (oids.Length() > 0) + systemRestriction += wxT(" AND c.oid NOT IN (") + oids + wxT(")"); + } + + pgSet *set = connection->ExecuteSet( + wxT("SELECT c.oid, c.relname , nspname\n") + wxT(" FROM pg_class c\n") + wxT(" JOIN pg_namespace n ON n.oid=c.relnamespace\n") + wxT(" WHERE relkind='r'\n") + + systemRestriction + + wxT(" ORDER BY relnamespace, c.relname")); + if (set) + { + while (!set->Eof()) + { + cbTables->Append(database->GetQuotedSchemaPrefix(set->GetVal(wxT("nspname"))) + + qtIdent(set->GetVal(wxT("relname")))); + + tableOids.Add(set->GetVal(wxT("oid"))); + set->MoveNext(); + } + delete set; + } + } + + FillConstraint(); + + btnChangeCol->Disable(); + btnRemoveCol->Disable(); + btnRemoveConstr->Disable(); + btnOK->Disable(); + + if ((connection->BackendMinimumVersion(8, 1) && table) || connection->BackendMinimumVersion(8, 4)) + { + if (!connection->BackendMinimumVersion(8, 4)) + { + txtFreezeTableAge->Disable(); + /* Remove Toast Table AutoVacuume setting page */ + nbVaccum->DeletePage(1); + } + + settingAutoVacuum = false; + + pgSetIterator avSet(connection, + wxT("SELECT name, setting FROM pg_settings WHERE name like '%vacuum%' ORDER BY name")); + while (avSet.RowsLeft()) + { + wxString name = avSet.GetVal(wxT("name")); + wxString setting = avSet.GetVal(wxT("setting")); + + if (name == wxT("autovacuum_vacuum_cost_delay")) + settingCostDelay = setting; + else if (name == wxT("vacuum_cost_delay")) + { + if (StrToLong(settingCostDelay) < 0) + settingCostDelay = setting; + } + else if (name == wxT("autovacuum_vacuum_cost_limit")) + settingCostLimit = setting; + else if (name == wxT("vacuum_cost_limit")) + { + if (StrToLong(settingCostLimit) < 0) + settingCostLimit = setting; + } + else if (name == wxT("autovacuum_vacuum_scale_factor")) + settingVacFactor = setting; + else if (name == wxT("autovacuum_analyze_scale_factor")) + settingAnlFactor = setting; + else if (name == wxT("autovacuum_vacuum_threshold")) + settingVacBaseThr = setting; + else if (name == wxT("autovacuum_analyze_threshold")) + settingAnlBaseThr = setting; + else if (name == wxT("vacuum_freeze_min_age")) + settingFreezeMinAge = setting; + else if (name == wxT("autovacuum_freeze_max_age")) + settingFreezeMaxAge = setting; + else if (name == wxT("vacuum_freeze_table_age")) + settingFreezeTableAge = setting; + else + settingAutoVacuum = avSet.GetBool(wxT("setting")); + } + + tableVacBaseThr = wxT("-1"); + tableAnlBaseThr = wxT("-1"); + tableCostDelay = wxT("-1"); + tableCostLimit = wxT("-1"); + tableFreezeMinAge = wxT("-1"); + tableFreezeMaxAge = wxT("-1"); + tableVacFactor = wxT("-1"); + tableAnlFactor = wxT("-1"); + tableFreezeTableAge = wxT("-1"); + + toastTableVacBaseThr = wxT("-1"); + toastTableCostDelay = wxT("-1"); + toastTableCostLimit = wxT("-1"); + toastTableFreezeMinAge = wxT("-1"); + toastTableFreezeMaxAge = wxT("-1"); + toastTableVacFactor = wxT("-1"); + toastTableFreezeTableAge = wxT("-1"); + + toastTableHasVacuum = false; + toastTableVacEnabled = false; + + if (!connection->BackendMinimumVersion(8, 4)) + { + pgSetIterator set(connection, wxT("SELECT * FROM pg_autovacuum WHERE vacrelid=") + table->GetOidStr()); + if (set.RowsLeft()) + { + hasVacuum = true; + + tableVacEnabled = set.GetBool(wxT("enabled")); + chkVacEnabled->SetValue(tableVacEnabled); + + tableVacBaseThr = set.GetVal(wxT("vac_base_thresh")); + tableAnlBaseThr = set.GetVal(wxT("anl_base_thresh")); + tableCostDelay = set.GetVal(wxT("vac_cost_delay")); + tableCostLimit = set.GetVal(wxT("vac_cost_limit")); + tableVacFactor = set.GetVal(wxT("vac_scale_factor")); + tableAnlFactor = set.GetVal(wxT("anl_scale_factor")); + + if (connection->BackendMinimumVersion(8, 2)) + { + tableFreezeMinAge = set.GetVal(wxT("freeze_min_age")); + tableFreezeMaxAge = set.GetVal(wxT("freeze_max_age")); + } + } + else + { + hasVacuum = false; + chkVacEnabled->SetValue(true); + } + } + else if (table) + { + if (table->GetAutoVacuumEnabled() == 2) + tableVacEnabled = settingAutoVacuum; + else + tableVacEnabled = table->GetAutoVacuumEnabled() == 1; + if (!table->GetAutoVacuumVacuumThreshold().IsEmpty()) + tableVacBaseThr = table->GetAutoVacuumVacuumThreshold(); + if (!table->GetAutoVacuumAnalyzeThreshold().IsEmpty()) + tableAnlBaseThr = table->GetAutoVacuumAnalyzeThreshold(); + if (!table->GetAutoVacuumVacuumScaleFactor().IsEmpty()) + tableVacFactor = table->GetAutoVacuumVacuumScaleFactor(); + if (!table->GetAutoVacuumAnalyzeScaleFactor().IsEmpty()) + tableAnlFactor = table->GetAutoVacuumAnalyzeScaleFactor(); + if (!table->GetAutoVacuumVacuumCostDelay().IsEmpty()) + tableCostDelay = table->GetAutoVacuumVacuumCostDelay(); + if (!table->GetAutoVacuumVacuumCostLimit().IsEmpty()) + tableCostLimit = table->GetAutoVacuumVacuumCostLimit(); + if (!table->GetAutoVacuumFreezeMinAge().IsEmpty()) + tableFreezeMinAge = table->GetAutoVacuumFreezeMinAge(); + if (!table->GetAutoVacuumFreezeMaxAge().IsEmpty()) + tableFreezeMaxAge = table->GetAutoVacuumFreezeMaxAge(); + if (!table->GetAutoVacuumFreezeTableAge().IsEmpty()) + tableFreezeTableAge = table->GetAutoVacuumFreezeTableAge(); + + hasVacuum = table->GetCustomAutoVacuumEnabled(); + chkVacEnabled->SetValue(hasVacuum ? tableVacEnabled : settingAutoVacuum); + + toastTableVacEnabled = false; + + if (!table->GetHasToastTable()) + { + nbVaccum->GetPage(1)->Enable(false); + } + else + { + toastTableHasVacuum = table->GetToastCustomAutoVacuumEnabled(); + if (toastTableHasVacuum) + { + if (table->GetToastAutoVacuumEnabled() == 2) + toastTableVacEnabled = settingAutoVacuum; + else + toastTableVacEnabled = table->GetToastAutoVacuumEnabled() == 1; + if (!table->GetToastAutoVacuumVacuumThreshold().IsEmpty()) + toastTableVacBaseThr = table->GetToastAutoVacuumVacuumThreshold(); + if (!table->GetToastAutoVacuumVacuumScaleFactor().IsEmpty()) + toastTableVacFactor = table->GetToastAutoVacuumVacuumScaleFactor(); + if (!table->GetToastAutoVacuumVacuumCostDelay().IsEmpty()) + toastTableCostDelay = table->GetToastAutoVacuumVacuumCostDelay(); + if (!table->GetToastAutoVacuumVacuumCostLimit().IsEmpty()) + toastTableCostLimit = table->GetToastAutoVacuumVacuumCostLimit(); + if (!table->GetToastAutoVacuumFreezeMinAge().IsEmpty()) + toastTableFreezeMinAge = table->GetToastAutoVacuumFreezeMinAge(); + if (!table->GetToastAutoVacuumFreezeMaxAge().IsEmpty()) + toastTableFreezeMaxAge = table->GetToastAutoVacuumFreezeMaxAge(); + if (!table->GetToastAutoVacuumFreezeTableAge().IsEmpty()) + toastTableFreezeTableAge = table->GetToastAutoVacuumFreezeTableAge(); + } + chkToastVacEnabled->SetValue(toastTableHasVacuum ? toastTableVacEnabled : settingAutoVacuum); + } + } + else + { + hasVacuum = false; + chkVacEnabled->SetValue(settingAutoVacuum); + } + + //txtBaseVac->SetValue(tableVacBaseThr); + txtBaseAn->SetValue(tableAnlBaseThr); + txtFactorVac->SetValue(tableVacFactor); + txtFactorAn->SetValue(tableAnlFactor); + txtVacDelay->SetValue(tableCostDelay); + txtVacLimit->SetValue(tableCostLimit); + + if (connection->BackendMinimumVersion(8, 2)) + { + txtFreezeMinAge->SetValue(tableFreezeMinAge); + txtFreezeMaxAge->SetValue(tableFreezeMaxAge); + } + if (connection->BackendMinimumVersion(8, 4)) + { + txtFreezeTableAge->SetValue(tableFreezeTableAge); + txtBaseToastVac->SetValue(toastTableVacBaseThr); + txtFactorToastVac->SetValue(toastTableVacFactor); + txtToastVacDelay->SetValue(toastTableCostDelay); + txtToastVacLimit->SetValue(toastTableCostLimit); + txtToastFreezeMinAge->SetValue(toastTableFreezeMinAge); + txtToastFreezeMaxAge->SetValue(toastTableFreezeMaxAge); + txtToastFreezeTableAge->SetValue(toastTableFreezeTableAge); + + chkCustomToastVac->SetValue(toastTableHasVacuum); + chkToastVacEnabled->SetValue(toastTableHasVacuum ? toastTableVacEnabled : settingAutoVacuum); + } + chkCustomVac->SetValue(hasVacuum); + wxCommandEvent ev; + OnChangeVacuum(ev); + } + else + { + /* Remove 'Vacuum Settings' Page */ + nbNotebook->DeletePage(TAB_AUTOVACUUM); + } + + // Find, and disable the RULE ACL option if we're 8.2 + if (connection->BackendMinimumVersion(8, 2)) + { + // Disable the checkbox + if (!DisablePrivilege(wxT("RULE"))) + { + wxLogError(_("Failed to disable the RULE privilege checkbox!")); + } + + if (table) + { + txtFillFactor->SetValue(table->GetFillFactor()); + } + + txtFillFactor->SetValidator(numericValidator); + txtFillFactor->Enable(); + } + else + { + txtFillFactor->Disable(); + } + + return dlgSecurityProperty::Go(modal); +} + + + +wxString dlgTable::GetItemConstraintType(ctlListView *list, long pos) +{ + wxString con; + wxListItem item; + item.SetId(pos); + item.SetColumn(0); + item.SetMask(wxLIST_MASK_IMAGE); + list->GetItem(item); + if (item.GetImage() == primaryKeyFactory.GetIconId()) + con = wxT("PRIMARY KEY"); + if (item.GetImage() == foreignKeyFactory.GetIconId()) + con = wxT("FOREIGN KEY"); + if (item.GetImage() == excludeFactory.GetIconId()) + con = wxT("EXCLUDE"); + if (item.GetImage() == uniqueFactory.GetIconId()) + con = wxT("UNIQUE"); + if (item.GetImage() == checkFactory.GetIconId()) + con = wxT("CHECK"); + return con; +} + + +wxString dlgTable::GetSql() +{ + int pos; + wxString sql; + wxString tabname; + + if (table) + { + int pos; + int index = -1; + + wxString definition; + + wxArrayString tmpDef = previousColumns; + wxString tmpsql; + + tabname = schema->GetQuotedPrefix() + qtIdent(GetName()); + + // Build a temporary list of ADD COLUMNs, and fixup the list to remove + for (pos = 0; pos < lstColumns->GetItemCount() ; pos++) + { + index = -1; + + if (lstColumns->GetText(pos, COL_INHERIT).IsEmpty()) + { + definition = lstColumns->GetText(pos, COL_SQLCHANGE); + if (definition.IsEmpty()) + { + definition = qtIdent(lstColumns->GetText(pos)) + wxT(" ") + lstColumns->GetText(pos, COL_DEFINITION); + index = tmpDef.Index(definition); + if (index < 0) + { + tmpsql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n ADD COLUMN ") + definition + wxT(";\n"); + } + } + else + { + tmpsql += definition; + + pgColumn *column = (pgColumn *) StrToLong(lstColumns->GetText(pos, COL_PGCOLUMN)); + if (column) + { + index = tmpDef.Index(column->GetQuotedIdentifier() + + wxT(" ") + column->GetDefinition()); + } + } + } + else + { + if (! lstColumns->GetText(pos, COL_INHERIT).IsEmpty()) + { + definition = qtIdent(lstColumns->GetText(pos)) + wxT(" ") + lstColumns->GetText(pos, COL_DEFINITION); + index = tmpDef.Index(definition); + } + } + if (index >= 0 && index < (int)tmpDef.GetCount()) + tmpDef.RemoveAt(index); + } + + + for (index = 0 ; index < (int)tmpDef.GetCount() ; index++) + { + definition = tmpDef.Item(index); + if (definition[0U] == '"') + definition = definition.Mid(1).BeforeFirst('"'); + else + definition = definition.BeforeFirst(' '); + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n DROP COLUMN ") + qtIdent(definition) + wxT(";\n"); + } + // Add the ADD COLUMNs... + sql += tmpsql; + + AppendNameChange(sql); + AppendOwnerChange(sql, wxT("TABLE ") + tabname); + + tmpDef = previousTables; + tmpsql.Empty(); + + // Build a temporary list of INHERIT tables, and fixup the list to remove + for (pos = 0 ; pos < (int)lbTables->GetCount() ; pos++) + { + definition = lbTables->GetString(pos); + index = tmpDef.Index(definition); + if (index < 0) + tmpsql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n INHERIT ") + definition + wxT(";\n"); + else + tmpDef.RemoveAt(index); + } + + for (index = 0 ; index < (int)tmpDef.GetCount() ; index++) + { + definition = tmpDef.Item(index); + // We don't need to quote the table because it's already quoted + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n NO INHERIT ") + definition + wxT(";\n"); + } + // Add the INHERIT COLUMNs... + sql += tmpsql; + + tmpDef = previousConstraints; + tmpsql.Empty(); + + // Build a temporary list of ADD CONSTRAINTs, and fixup the list to remove + for (pos = 0; pos < lstConstraints->GetItemCount() ; pos++) + { + wxString conname = qtIdent(lstConstraints->GetItemText(pos)); + definition = conname; + definition += wxT(" ") + GetItemConstraintType(lstConstraints, pos) + + wxT(" ") + constraintsDefinition.Item(pos); + index = tmpDef.Index(definition); + if (index >= 0) + tmpDef.RemoveAt(index); + else + { + tmpsql += wxT("ALTER TABLE ") + tabname + + wxT("\n ADD"); + if (!conname.IsEmpty()) + tmpsql += wxT(" CONSTRAINT "); + + tmpsql += definition + wxT(";\n"); + } + } + + for (index = 0 ; index < (int)tmpDef.GetCount() ; index++) + { + definition = tmpDef.Item(index); + if (definition[0U] == '"') + definition = definition.Mid(1).BeforeFirst('"'); + else + definition = definition.BeforeFirst(' '); + sql += wxT("ALTER TABLE ") + tabname + + wxT("\n DROP CONSTRAINT ") + qtIdent(definition) + wxT(";\n"); + + } + // Add the ADD CONSTRAINTs... + sql += tmpsql; + + if (!chkHasOids->GetValue() && table->GetHasOids()) + { + sql += wxT("ALTER TABLE ") + tabname + + wxT("\n SET WITHOUT OIDS;\n"); + } + if (chkHasOids->GetValue() && !table->GetHasOids()) + { + sql += wxT("ALTER TABLE ") + tabname + + wxT("\n SET WITH OIDS;\n"); + } + if (connection->BackendMinimumVersion(8, 0) && cbTablespace->GetOIDKey() != table->GetTablespaceOid()) + sql += wxT("ALTER TABLE ") + tabname + + wxT("\n SET TABLESPACE ") + qtIdent(cbTablespace->GetValue()) + + wxT(";\n"); + + if (txtFillFactor->GetValue().Trim().Length() > 0 && txtFillFactor->GetValue() != table->GetFillFactor()) + { + sql += wxT("ALTER TABLE ") + tabname + + wxT("\n SET (FILLFACTOR=") + + txtFillFactor->GetValue() + wxT(");\n"); + } + + if (connection->BackendMinimumVersion(8, 1)) + { + if (!chkCustomVac->GetValue()) + { + if (hasVacuum) + { + if (connection->BackendMinimumVersion(8, 4)) + sql += wxT("ALTER TABLE ") + tabname + + wxT(" RESET(\n") + wxT(" autovacuum_enabled,\n") + wxT(" autovacuum_vacuum_threshold,\n") + wxT(" autovacuum_analyze_threshold,\n") + wxT(" autovacuum_vacuum_scale_factor,\n") + wxT(" autovacuum_analyze_scale_factor,\n") + wxT(" autovacuum_vacuum_cost_delay,\n") + wxT(" autovacuum_vacuum_cost_limit,\n") + wxT(" autovacuum_freeze_min_age,\n") + wxT(" autovacuum_freeze_max_age,\n") + wxT(" autovacuum_freeze_table_age\n") + wxT(");\n"); + else + sql += wxT("DELETE FROM pg_autovacuum WHERE vacrelid=") + table->GetOidStr() + wxT(";\n"); + } + } + else + { + wxString vacStr; + bool changed = (chkVacEnabled->GetValue() != tableVacEnabled); + if (connection->BackendMinimumVersion(8, 4)) + { + bool valChanged = false; + wxString newVal; + wxString setStr; + wxString resetStr; + if (changed) + { + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_enabled"), BoolToStr(chkVacEnabled->GetValue())); + } + newVal = AppendNum(valChanged, txtBaseVac, tableVacBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_vacuum_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtBaseAn, tableAnlBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_analyze_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorVac, tableVacFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_vacuum_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorAn, tableAnlFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_analyze_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtVacDelay, tableCostDelay); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_vacuum_cost_delay"), newVal); + } + + newVal = AppendNum(valChanged, txtVacLimit, tableCostLimit); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_vacuum_cost_limit"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeMinAge, tableFreezeMinAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_freeze_min_age"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeMaxAge, tableFreezeMaxAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_freeze_max_age"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeTableAge, tableFreezeTableAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_freeze_table_age"), newVal); + } + + if (!setStr.IsEmpty()) + { + vacStr = wxT("ALTER TABLE ") + tabname + setStr + wxT("\n);\n");; + changed = true; + } + if (!resetStr.IsEmpty()) + { + vacStr += wxT("ALTER TABLE ") + tabname + resetStr + wxT("\n);\n");; + changed = true; + } + } + else if (!hasVacuum) + { + if (connection->BackendMinimumVersion(8, 2)) + { + vacStr = wxT("INSERT INTO pg_autovacuum(vacrelid, enabled, vac_base_thresh, anl_base_thresh, vac_scale_factor, anl_scale_factor, vac_cost_delay, vac_cost_limit, freeze_min_age, freeze_max_age)") + wxT("\n VALUES(") + + table->GetOidStr() + wxT(", ") + + BoolToStr(chkVacEnabled->GetValue()) + wxT(", ") + + AppendNum(changed, txtBaseVac, tableVacBaseThr) + wxT(", ") + + AppendNum(changed, txtBaseAn, tableAnlBaseThr) + wxT(", ") + + AppendNum(changed, txtFactorVac, tableVacFactor) + wxT(", ") + + AppendNum(changed, txtFactorAn, tableAnlFactor) + wxT(", ") + + AppendNum(changed, txtVacDelay, tableCostDelay) + wxT(", ") + + AppendNum(changed, txtVacLimit, tableCostLimit) + wxT(", ") + + AppendNum(changed, txtFreezeMinAge, tableFreezeMinAge) + wxT(", ") + + AppendNum(changed, txtFreezeMaxAge, tableFreezeMaxAge) + wxT(");\n"); + } + else + { + vacStr = wxT("INSERT INTO pg_autovacuum(vacrelid, enabled, vac_base_thresh, anl_base_thresh, vac_scale_factor, anl_scale_factor, vac_cost_delay, vac_cost_limit)") + wxT("\n VALUES(") + + table->GetOidStr() + wxT(", ") + + BoolToStr(chkVacEnabled->GetValue()) + wxT(", ") + + AppendNum(changed, txtBaseVac, tableVacBaseThr) + wxT(", ") + + AppendNum(changed, txtBaseAn, tableAnlBaseThr) + wxT(", ") + + AppendNum(changed, txtFactorVac, tableVacFactor) + wxT(", ") + + AppendNum(changed, txtFactorAn, tableAnlFactor) + wxT(", ") + + AppendNum(changed, txtVacDelay, tableCostDelay) + wxT(", ") + + AppendNum(changed, txtVacLimit, tableCostLimit) + wxT(");\n"); + } + } + else + { + if (connection->BackendMinimumVersion(8, 2)) + { + vacStr = wxT("UPDATE pg_autovacuum\n") + wxT(" SET enabled=") + + BoolToStr(chkVacEnabled->GetValue()) + + wxT(", vac_base_thresh = ") + AppendNum(changed, txtBaseVac, tableVacBaseThr) + + wxT(", anl_base_thresh = ") + AppendNum(changed, txtBaseAn, tableAnlBaseThr) + + wxT(", vac_scale_factor = ") + AppendNum(changed, txtFactorVac, tableVacFactor) + + wxT(", anl_scale_factor = ") + AppendNum(changed, txtFactorAn, tableAnlFactor) + + wxT(", vac_cost_delay = ") + AppendNum(changed, txtVacDelay, tableCostDelay) + + wxT(", vac_cost_limit = ") + AppendNum(changed, txtVacLimit, tableCostLimit) + + wxT(", freeze_min_age = ") + AppendNum(changed, txtFreezeMinAge, tableFreezeMinAge) + + wxT(", freeze_max_age = ") + AppendNum(changed, txtFreezeMaxAge, tableFreezeMaxAge) + + wxT("\n WHERE vacrelid=") + table->GetOidStr() + wxT(";\n"); + } + else + { + vacStr = wxT("UPDATE pg_autovacuum\n") + wxT(" SET enabled=") + + BoolToStr(chkVacEnabled->GetValue()) + + wxT(", vac_base_thresh = ") + AppendNum(changed, txtBaseVac, tableVacBaseThr) + + wxT(", anl_base_thresh = ") + AppendNum(changed, txtBaseAn, tableAnlBaseThr) + + wxT(", vac_scale_factor = ") + AppendNum(changed, txtFactorVac, tableVacFactor) + + wxT(", anl_scale_factor = ") + AppendNum(changed, txtFactorAn, tableAnlFactor) + + wxT(", vac_cost_delay = ") + AppendNum(changed, txtVacDelay, tableCostDelay) + + wxT(", vac_cost_limit = ") + AppendNum(changed, txtVacLimit, tableCostLimit) + + wxT("\n WHERE vacrelid=") + table->GetOidStr() + wxT(";\n"); + } + + } + if (changed) + sql += vacStr; + } + } + if (connection->BackendMinimumVersion(8, 4)) + { + if (!chkCustomToastVac->GetValue()) + { + if (toastTableHasVacuum) + { + sql += wxT("ALTER TABLE ") + tabname + + wxT(" RESET(\n") + wxT(" toast.autovacuum_enabled,\n") + wxT(" toast.autovacuum_vacuum_threshold,\n") + wxT(" toast.autovacuum_analyze_threshold,\n") + wxT(" toast.autovacuum_vacuum_scale_factor,\n") + wxT(" toast.autovacuum_analyze_scale_factor,\n") + wxT(" toast.autovacuum_vacuum_cost_delay,\n") + wxT(" toast.autovacuum_vacuum_cost_limit,\n") + wxT(" toast.autovacuum_freeze_min_age,\n") + wxT(" toast.autovacuum_freeze_max_age,\n") + wxT(" toast.autovacuum_freeze_table_age\n") + wxT(");\n"); + } + } + else + { + wxString vacStr; + bool changed = (chkToastVacEnabled->GetValue() != toastTableVacEnabled); + bool valChanged = false; + wxString newVal; + wxString setStr; + wxString resetStr; + if (changed) + { + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_enabled"), BoolToStr(chkToastVacEnabled->GetValue())); + } + newVal = AppendNum(valChanged, txtBaseToastVac, toastTableVacBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_vacuum_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorToastVac, toastTableVacFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_vacuum_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtToastVacDelay, toastTableCostDelay); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_vacuum_cost_delay"), newVal); + } + + newVal = AppendNum(valChanged, txtToastVacLimit, toastTableCostLimit); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_vacuum_cost_limit"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeMinAge, toastTableFreezeMinAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_freeze_min_age"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeMaxAge, toastTableFreezeMaxAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_freeze_max_age"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeTableAge, toastTableFreezeTableAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_freeze_table_age"), newVal); + } + + if (!setStr.IsEmpty()) + { + vacStr = wxT("ALTER TABLE ") + tabname + setStr + wxT("\n);\n");; + changed = true; + } + if (!resetStr.IsEmpty()) + { + vacStr += wxT("ALTER TABLE ") + tabname + resetStr + wxT("\n);\n");; + changed = true; + } + if (changed) + sql += vacStr; + } + } + // This needs to always be last so that other statements use correct schema + if (connection->BackendMinimumVersion(8, 1) && cbSchema->GetValue() != table->GetSchema()->GetName()) + { + AppendSchemaChange(sql, wxT("TABLE ") + tabname); + } + } + else + { + bool needComma = false; + bool typedTable = cbOfType->GetCurrentSelection() > 0 && cbOfType->GetOIDKey() > 0; + + tabname = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()); + + sql = wxT("CREATE "); + if (chkUnlogged->GetValue()) + sql += wxT("UNLOGGED "); + sql += wxT("TABLE ") + tabname; + if (typedTable) + sql += wxT("\nOF ") + qtIdent(cbOfType->GetValue()); + + if (!typedTable || (typedTable && lstConstraints->GetItemCount() > 0)) + sql += wxT("\n("); + + if (!cbLikeRelation->GetValue().IsEmpty()) + { + sql += wxT("\n LIKE ") + cbLikeRelation->GetValue(); + if (chkIncludingDefaults->GetValue()) + sql += wxT(" INCLUDING DEFAULTS"); + if (chkIncludingConstraints->GetValue()) + sql += wxT(" INCLUDING CONSTRAINTS"); + if (chkIncludingIndexes->GetValue()) + sql += wxT(" INCLUDING INDEXES"); + if (chkIncludingStorage->GetValue()) + sql += wxT(" INCLUDING STORAGE"); + if (chkIncludingComments->GetValue()) + sql += wxT(" INCLUDING COMMENTS"); + needComma = true; + } + + if (!typedTable) + { + for (pos = 0 ; pos < lstColumns->GetItemCount() ; pos++) + { + if (lstColumns->GetText(pos, COL_INHERIT).IsEmpty()) + { + // standard definition, not inherited + if (needComma) + sql += wxT(", "); + else + needComma = true; + + wxString name = lstColumns->GetText(pos); + wxString definition = lstColumns->GetText(pos, COL_DEFINITION); + + sql += wxT("\n ") + qtIdent(name) + + wxT(" ") + definition; + } + } + } + + for (pos = 0 ; pos < lstConstraints->GetItemCount() ; pos++) + { + wxString name = lstConstraints->GetItemText(pos); + wxString definition = constraintsDefinition.Item(pos); + + if (needComma) + sql += wxT(", "); + else + needComma = true; + + sql += wxT("\n "); + if (!name.IsEmpty()) + sql += wxT("CONSTRAINT ") + qtIdent(name) + wxT(" "); + sql += GetItemConstraintType(lstConstraints, pos) + wxT(" ") + definition; + } + + if (!typedTable || (typedTable && lstConstraints->GetItemCount() > 0)) + sql += wxT("\n) "); + + + if (lbTables->GetCount() > 0) + { + sql += wxT("\nINHERITS ("); + + unsigned int i; + for (i = 0 ; i < lbTables->GetCount() ; i++) + { + if (i) + sql += wxT(", "); + sql += lbTables->GetString(i); + } + sql += wxT(")"); + } + + if (connection->BackendMinimumVersion(8, 2)) + { + sql += wxT("\nWITH ("); + if (txtFillFactor->GetValue().Trim().Length() > 0) + sql += wxT("\n FILLFACTOR = ") + txtFillFactor->GetValue() + wxT(", "); + if (chkHasOids->GetValue()) + sql += wxT("\n OIDS = TRUE"); + else + sql += wxT("\n OIDS = FALSE"); + if (connection->BackendMinimumVersion(8, 4) && chkCustomVac->GetValue()) + { + bool valChanged = false; + wxString newVal; + wxString resetStr; + + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_enabled"), BoolToStr(chkVacEnabled->GetValue())); + newVal = AppendNum(valChanged, txtBaseVac, tableVacBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_vacuum_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtBaseAn, tableAnlBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_analyze_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorVac, tableVacFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_vacuum_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorAn, tableAnlFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_analyze_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtVacDelay, tableCostDelay); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_vacuum_cost_delay"), newVal); + } + + newVal = AppendNum(valChanged, txtVacLimit, tableCostLimit); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_vacuum_cost_limit"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeMinAge, tableFreezeMinAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_freeze_min_age"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeMaxAge, tableFreezeMaxAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_freeze_max_age"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeTableAge, tableFreezeTableAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_freeze_table_age"), newVal); + } + } + if (connection->BackendMinimumVersion(8, 4) && chkCustomToastVac->GetValue()) + { + bool valChanged = false; + wxString newVal; + wxString resetStr; + + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_enabled"), BoolToStr(chkToastVacEnabled->GetValue())); + newVal = AppendNum(valChanged, txtBaseToastVac, toastTableVacBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_vacuum_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorToastVac, toastTableVacFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_vacuum_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtToastVacDelay, toastTableCostDelay); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_vacuum_cost_delay"), newVal); + } + + newVal = AppendNum(valChanged, txtToastVacLimit, toastTableCostLimit); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_vacuum_cost_limit"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeMinAge, toastTableFreezeMinAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_freeze_min_age"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeMaxAge, toastTableFreezeMaxAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_freeze_max_age"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeTableAge, toastTableFreezeTableAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_freeze_table_age"), newVal); + } + } + + sql += wxT("\n)\n"); + } + else + { + sql += (chkHasOids->GetValue() ? wxT("\nWITH OIDS") : wxT("\nWITHOUT OIDS")); + } + + if (cbTablespace->GetCurrentSelection() > 0 && cbTablespace->GetOIDKey() > 0) + sql += wxT("\nTABLESPACE ") + qtIdent(cbTablespace->GetValue()); + + sql += wxT(";\n"); + + AppendOwnerNew(sql, wxT("TABLE ") + tabname); + + // Extra column info + // Statistics + for (pos = 0 ; pos < lstColumns->GetItemCount() ; pos++) + { + if (!lstColumns->GetText(pos, COL_STATISTICS).IsEmpty()) + sql += wxT("ALTER TABLE ") + tabname + + wxT("\n ALTER COLUMN ") + qtIdent(lstColumns->GetText(pos, COL_NAME)) + + wxT("\n SET STATISTICS ") + lstColumns->GetText(pos, COL_STATISTICS) + + wxT(";\n"); + } + } + + //variables + for (pos = 0; pos < lstColumns->GetItemCount(); pos++) + { + wxStringTokenizer varToken(lstColumns->GetText(pos, COL_VARIABLE_LIST), wxT(",")); + while (varToken.HasMoreTokens()) + { + sql += wxT("ALTER TABLE ") + tabname + + wxT("\n ALTER COLUMN ") + + qtIdent(lstColumns->GetText(pos, COL_NAME)) + + wxT(" \nSET ("); + sql += varToken.GetNextToken() + wxT(");\n"); + } + } + + //security labels + for (pos = 0; pos < lstColumns->GetItemCount(); pos++) + { + wxStringTokenizer varToken(lstColumns->GetText(pos, COL_SECLABEL_LIST), wxT(",")); + wxString providerLabel = wxEmptyString; + wxString provider = wxEmptyString; + while (varToken.HasMoreTokens()) + { + provider = varToken.GetNextToken(); + if(varToken.HasMoreTokens()) + providerLabel = varToken.GetNextToken(); + + sql += wxT("SECURITY LABEL FOR ") + provider + + wxT("\n ON COLUMN ") + qtIdent(lstColumns->GetText(pos, COL_NAME)) + + wxT("\n IS ") + connection->qtDbString(providerLabel) + wxT(";\n"); + } + } + + // Comments + for (pos = 0 ; pos < lstColumns->GetItemCount() ; pos++) + { + if (!lstColumns->GetText(pos, COL_COMMENTS).IsEmpty()) + sql += wxT("COMMENT ON COLUMN ") + tabname + + wxT(".") + qtIdent(lstColumns->GetText(pos, COL_NAME)) + + wxT(" IS ") + qtDbString(lstColumns->GetText(pos, COL_COMMENTS)) + + wxT(";\n"); + } + + AppendComment(sql, wxT("TABLE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), table); + + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + sql += seclabelPage->GetSqlForSecLabels(wxT("TABLE"), qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName())); + + if (connection->BackendMinimumVersion(8, 4)) + sql += GetGrant(wxT("arwdDxt"), wxT("TABLE ") + tabname); + else if (connection->BackendMinimumVersion(8, 2)) + sql += GetGrant(wxT("arwdxt"), wxT("TABLE ") + tabname); + else + sql += GetGrant(wxT("arwdRxt"), wxT("TABLE ") + tabname); + + return sql; +} + + +void dlgTable::FillConstraint() +{ + cbConstrType->Clear(); + if (!hasPK) + cbConstrType->Append(_("Primary Key")); + +// chkHasOids->Enable(!table || (table && table->GetHasOids() && hasPK && connection->BackendMinimumVersion(7, 4))); + cbConstrType->Append(_("Foreign Key")); + cbConstrType->Append(_("Exclude Constraint")); + cbConstrType->Append(_("Unique")); + cbConstrType->Append(_("Check")); + cbConstrType->SetSelection(0); +} + + +pgObject *dlgTable::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + pgObject *obj = tableFactory.CreateObjects(collection, 0, wxT( + "\n AND rel.relname=") + qtDbString(name) + wxT( + "\n AND rel.relnamespace=") + schema->GetOidStr()); + + return obj; +} + + +wxString dlgTable::GetNumString(wxTextCtrl *ctl, bool enabled, const wxString &val) +{ + if (!enabled) + return val; + wxString str = ctl->GetValue(); + if (str.IsEmpty() || StrToLong(val) < 0) + return val; + else + return str; +} + + +wxString dlgTable::AppendNum(bool &changed, wxTextCtrl *ctl, wxString val) +{ + wxString str = ctl->GetValue(); + if (str.IsEmpty() || str.StartsWith(wxT("-"))) + str = wxT("-1"); + + changed |= (str != val); + return str; +} + + +#ifdef __WXMAC__ +void dlgTable::OnChangeSize(wxSizeEvent &ev) +{ + if (lstConstraints) + { + lstConstraints->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 150); + } + + lstColumns->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 150); + + dlgSecurityProperty::OnChangeSize(ev); +} +#endif + + +void dlgTable::OnChangeVacuum(wxCommandEvent &ev) +{ + if (connection->BackendMinimumVersion(8, 1)) + { + bool vacEn = chkCustomVac->GetValue() && chkVacEnabled->GetValue(); + chkVacEnabled->Enable(chkCustomVac->GetValue()); + + txtBaseVac->Enable(vacEn); + txtBaseAn->Enable(vacEn); + txtFactorVac->Enable(vacEn); + txtFactorAn->Enable(vacEn); + txtVacDelay->Enable(vacEn); + txtVacLimit->Enable(vacEn); + + if (connection->BackendMinimumVersion(8, 2)) + { + txtFreezeMinAge->Enable(vacEn); + txtFreezeMaxAge->Enable(vacEn); + } + else + { + txtFreezeMinAge->Enable(false); + txtFreezeMaxAge->Enable(false); + } + + stBaseVacCurr->SetLabel(tableVacBaseThr == wxT("-1") ? settingVacBaseThr : tableVacBaseThr); + stBaseAnCurr->SetLabel(tableAnlBaseThr == wxT("-1") ? settingAnlBaseThr : tableAnlBaseThr); + stFactorVacCurr->SetLabel(tableVacFactor == wxT("-1") ? settingVacFactor : tableVacFactor); + stFactorAnCurr->SetLabel(tableAnlFactor == wxT("-1") ? settingAnlFactor : tableAnlFactor); + stVacDelayCurr->SetLabel(tableCostDelay == wxT("-1") ? settingCostDelay : tableCostDelay); + stVacLimitCurr->SetLabel(tableCostLimit == wxT("-1") ? settingCostLimit : tableCostLimit); + + if (connection->BackendMinimumVersion(8, 2)) + { + stFreezeMinAgeCurr->SetLabel(tableFreezeMinAge == wxT("-1") ? settingFreezeMinAge : tableFreezeMinAge); + stFreezeMaxAgeCurr->SetLabel(tableFreezeMaxAge == wxT("-1") ? settingFreezeMaxAge : tableFreezeMaxAge); + } + if (connection->BackendMinimumVersion(8, 4)) + { + txtFreezeTableAge->Enable(vacEn); + stFreezeTableAgeCurr->SetLabel(tableFreezeTableAge == wxT("-1") ? settingFreezeTableAge : tableFreezeTableAge); + /* Toast Table Vacuum Settings */ + bool toastVacEn = chkCustomToastVac->GetValue() && chkToastVacEnabled->GetValue(); + chkToastVacEnabled->Enable(chkCustomToastVac->GetValue()); + + txtBaseToastVac->Enable(toastVacEn); + txtFactorToastVac->Enable(toastVacEn); + txtToastVacDelay->Enable(toastVacEn); + txtToastVacLimit->Enable(toastVacEn); + txtToastFreezeMinAge->Enable(toastVacEn); + txtToastFreezeMaxAge->Enable(toastVacEn); + txtToastFreezeTableAge->Enable(toastVacEn); + + stBaseToastVacCurr->SetLabel(toastTableVacBaseThr == wxT("-1") ? settingVacBaseThr : toastTableVacBaseThr); + stFactorToastVacCurr->SetLabel(toastTableVacFactor == wxT("-1") ? settingVacFactor : toastTableVacFactor); + stToastVacDelayCurr->SetLabel(toastTableCostDelay == wxT("-1") ? settingCostDelay : toastTableCostDelay); + stToastVacLimitCurr->SetLabel(toastTableCostLimit == wxT("-1") ? settingCostLimit : toastTableCostLimit); + stToastFreezeMinAgeCurr->SetLabel(toastTableFreezeMinAge == wxT("-1") ? settingFreezeMinAge : toastTableFreezeMinAge); + stToastFreezeMaxAgeCurr->SetLabel(toastTableFreezeMaxAge == wxT("-1") ? settingFreezeMaxAge : toastTableFreezeMaxAge); + txtToastFreezeTableAge->Enable(toastVacEn); + stToastFreezeTableAgeCurr->SetLabel(toastTableFreezeTableAge == wxT("-1") ? settingFreezeTableAge : toastTableFreezeTableAge); + } + else + { + stFreezeTableAgeCurr->SetLabel(wxEmptyString); + txtFreezeTableAge->Enable(false); + } + } + OnChange(ev); +} + + +void dlgTable::OnChangeTable(wxCommandEvent &ev) +{ + cbTables->GuessSelection(ev); + btnAddTable->Enable((table || connection->BackendMinimumVersion(8, 2)) && cbTables->GetGuessedSelection() >= 0); +} + + +void dlgTable::OnOK(wxCommandEvent &ev) +{ +#ifdef __WXGTK__ + if (!btnOK->IsEnabled()) + return; +#endif + if (lstColumns->GetItemCount() > 0 && !hasPK + && frmHint::ShowHint(this, HINT_PRIMARYKEY) == wxID_CANCEL) + return; + + dlgProperty::OnOK(ev); +} + + +void dlgTable::CheckChange() +{ + bool enable = true; + if (table) + { + enable = false; + if (connection->BackendMinimumVersion(7, 4) || lstColumns->GetItemCount() > 0) + { + enable = !GetSql().IsEmpty(); + } + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); + } + else + { + wxString name = GetName(); + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, connection->BackendMinimumVersion(7, 4) || lstColumns->GetItemCount() > 0, + _("Please specify columns.")); + } + EnableOK(enable); +} + + +void dlgTable::OnAddTable(wxCommandEvent &ev) +{ + int sel = cbTables->GetGuessedSelection(); + if (sel >= 0) + { + wxString tabname = cbTables->GetValue(); + wxString taboid = tableOids.Item(sel); + inheritedTableOids.Add(taboid); + tableOids.RemoveAt(sel); + + lbTables->Append(tabname); + cbTables->Delete(sel); + + pgSet *set = connection->ExecuteSet( + wxT("SELECT attname, format_type(atttypid, NULL) AS atttype FROM pg_attribute\n") + wxT (" WHERE NOT attisdropped AND attnum>0 AND attrelid=") + taboid); + if (set) + { + bool found; + while (!set->Eof()) + { + found = false; + + size_t row = lstColumns->GetItemCount(); + while (row--) + { + if (set->GetVal(wxT("attname")).Cmp(lstColumns->GetText(row, COL_NAME)) == 0) + { + found = true; + break; + } + } + + if (found) + { + lstColumns->SetItem(row, COL_INHERIT, tabname); + } + else + { + lstColumns->AppendItem(tableFactory.GetIconId(), + set->GetVal(wxT("attname")), + set->GetVal(wxT("atttype")), + tabname); + } + set->MoveNext(); + } + delete set; + } + CheckChange(); + } +} + + +void dlgTable::OnRemoveTable(wxCommandEvent &ev) +{ + if (settings->GetConfirmDelete()) + { + if (wxMessageBox(_("Are you sure you wish to remove the selected table?"), _("Remove table?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) + return; + } + + int sel = lbTables->GetSelection(); + if (sel >= 0) + { + wxString tabname = lbTables->GetStringSelection(); + tableOids.Add(inheritedTableOids.Item(sel)); + inheritedTableOids.RemoveAt(sel); + + lbTables->Delete(sel); + cbTables->Append(tabname); + + size_t row = lstColumns->GetItemCount(); + while (row--) + { + if (tabname == lstColumns->GetText(row, COL_INHERIT)) + { + lstColumns->SetItem(row, COL_INHERIT, wxT("")); + } + } + CheckChange(); + } + btnRemoveTable->Disable(); +} + + +void dlgTable::OnSelChangeTable(wxCommandEvent &ev) +{ + btnRemoveTable->Enable(); +} + + +void dlgTable::OnChangeOfType(wxCommandEvent &ev) +{ + if (cbOfType->GetCurrentSelection() > 0) + { + if (settings->GetConfirmDelete() && lstColumns->GetItemCount() > 0) + { + if (wxMessageBox(_("A typed table only has the type's columns. All other columns will be dropped. Are you sure you want to do this?"), _("Remove all columns?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) == wxYES) + { + lstColumns->DeleteAllItems(); + lstConstraints->DeleteAllItems(); + constraintsDefinition.Clear(); + hasPK = false; + FillConstraint(); + } + else + { + cbOfType->SetSelection(0); + return; + } + } + + pgSet *set = connection->ExecuteSet( + wxT("SELECT a.attname, format_type(atttypid, NULL) AS atttypname ") + wxT("FROM pg_attribute a, pg_class c\n") + wxT("WHERE NOT a.attisdropped AND a.attnum>0 ") + wxT("AND a.attrelid=c.oid AND c.relname='") + qtIdent(cbOfType->GetValue()) + wxT("'")); + if (set) + { + while (!set->Eof()) + { + lstColumns->AppendItem(tableFactory.GetIconId(), + set->GetVal(wxT("attname")), + set->GetVal(wxT("atttypname")), + wxT("")); + set->MoveNext(); + } + delete set; + } + } + else + { + if (settings->GetConfirmDelete() && lstColumns->GetItemCount() > 0) + { + if (wxMessageBox(_("All type's columns will be dropped. Are you sure you want to do this?"), _("Remove all columns?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) == wxYES) + { + lstColumns->DeleteAllItems(); + lstConstraints->DeleteAllItems(); + constraintsDefinition.Clear(); + hasPK = false; + FillConstraint(); + } + } + } + + btnAddCol->Enable(cbOfType->GetCurrentSelection() == 0); + cbTables->Enable(connection->BackendMinimumVersion(8, 2) && cbOfType->GetCurrentSelection() == 0); + btnRemoveCol->Enable(false); + CheckChange(); +} + +void dlgTable::OnChangeCol(wxCommandEvent &ev) +{ + long pos = lstColumns->GetSelection(); + pgColumn *column = (pgColumn *) StrToLong(lstColumns->GetText(pos, COL_PGCOLUMN)); + pgColumn *column2 = (pgColumn *) StrToLong(lstColumns->GetText(pos, COL_CHANGEDCOL)); + + dlgColumn col(&columnFactory, mainForm, column, table); + col.CenterOnParent(); + col.SetDatabase(database); + col.SetChangedCol(column2); + if (col.Go(true) != wxID_CANCEL) + { + if(column2 == NULL) + column2 = new pgColumn(*column); + + col.ApplyChangesToObj(column2); + lstColumns->SetItem(pos, COL_NAME, col.GetName()); + lstColumns->SetItem(pos, COL_DEFINITION, col.GetDefinition()); + lstColumns->SetItem(pos, COL_SQLCHANGE, col.GetSql()); + lstColumns->SetItem(pos, COL_STATISTICS, col.GetStatistics()); + lstColumns->SetItem(pos, COL_COMMENTS, col.GetComment()); + lstColumns->SetItem(pos, COL_CHANGEDCOL, NumToStr((long)column2)); + } + CheckChange(); +} + +// Cache datatypes to avoid multiple calls to server when adding multiple columns to a table. +void dlgTable::PopulateDatatypeCache() +{ + DatatypeReader tr(database, true, true); + while (tr.HasMore()) + { + pgDatatype dt = tr.GetDatatype(); + + dataType *dType = new dataType(); + dType->SetOid(tr.GetOid()); + dType->SetTypename(dt.GetQuotedSchemaPrefix(database) + dt.QuotedFullName()); + dtCache.Add(dType); + + tr.MoveNext(); + } +} + + +void dlgTable::OnAddCol(wxCommandEvent &ev) +{ + dlgColumn col(&columnFactory, mainForm, NULL, table); + col.CenterOnParent(); + col.SetDatabase(database); + col.SetDatatypeCache(dtCache); + if (col.Go(true) != wxID_CANCEL) + { + long pos = lstColumns->AppendItem(columnFactory.GetIconId(), col.GetName(), col.GetDefinition()); + if (table && !connection->BackendMinimumVersion(8, 0)) + lstColumns->SetItem(pos, COL_SQLCHANGE, col.GetSql()); + lstColumns->SetItem(pos, COL_STATISTICS, col.GetStatistics()); + lstColumns->SetItem(pos, COL_COMMENTS, col.GetComment()); + lstColumns->SetItem(pos, COL_TYPEOID, col.GetTypeOid()); + + wxString perColumnListString = wxEmptyString; + + //getting the variable list for each column + wxArrayString perColumnList; + col.GetVariableList(perColumnList); + for(size_t index = 0; index < perColumnList.GetCount(); index++) + { + if (index == 0) + perColumnListString = perColumnList.Item(index); + else + perColumnListString += wxT(",") + perColumnList.Item(index); + } + lstColumns->SetItem(pos, COL_VARIABLE_LIST, perColumnListString); + + //getting the security labels list for each column + if(connection->BackendMinimumVersion(9, 1)) + { + wxString secLabelListString = wxEmptyString; + wxArrayString secLabelList; + col.GetSecLabelList(secLabelList); + for(size_t index = 0; index < secLabelList.GetCount(); index++) + { + if (index == 0) + secLabelListString = secLabelList.Item(index); + else + secLabelListString += wxT(",") + secLabelList.Item(index); + } + lstColumns->SetItem(pos, COL_SECLABEL_LIST, secLabelListString); + } + } + + CheckChange(); +} + + +void dlgTable::OnRemoveCol(wxCommandEvent &ev) +{ + if (settings->GetConfirmDelete()) + { + if (wxMessageBox(_("Are you sure you wish to remove the selected column?"), _("Remove column?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) + return; + } + + lstColumns->DeleteCurrentItem(); + + btnChangeCol->Disable(); + btnRemoveCol->Disable(); + + CheckChange(); +} + + +void dlgTable::OnSelChangeCol(wxListEvent &ev) +{ + long pos = lstColumns->GetSelection(); + wxString inheritedFromTable = lstColumns->GetText(pos, COL_INHERIT); + + btnAddCol->Enable(!(cbOfType->GetCurrentSelection() > 0 && cbOfType->GetOIDKey() > 0)); + btnRemoveCol->Enable(inheritedFromTable.IsEmpty() && !(cbOfType->GetCurrentSelection() > 0 && cbOfType->GetOIDKey() > 0)); + btnChangeCol->Enable(table != 0 && !lstColumns->GetText(pos, COL_PGCOLUMN).IsEmpty() && inheritedFromTable.IsEmpty()); +} + + +void dlgTable::OnAddConstr(wxCommandEvent &ev) +{ + int sel = cbConstrType->GetCurrentSelection(); + if (hasPK) + sel++; + + switch (sel) + { + case 0: // Primary Key + { + dlgPrimaryKey pk(&primaryKeyFactory, mainForm, lstColumns); + pk.CenterOnParent(); + pk.SetDatabase(database); + if (pk.Go(true) != wxID_CANCEL) + { + wxString tmpDef = pk.GetDefinition(); + tmpDef.Replace(wxT("\n"), wxT(" ")); + + lstConstraints->AppendItem(primaryKeyFactory.GetIconId(), pk.GetName(), tmpDef); + constraintsDefinition.Add(tmpDef); + hasPK = true; + FillConstraint(); + } + break; + } + case 1: // Foreign Key + { + dlgForeignKey fk(&foreignKeyFactory, mainForm, lstColumns); + fk.CenterOnParent(); + fk.SetDatabase(database); + if (fk.Go(true) != wxID_CANCEL) + { + wxString tmpDef = fk.GetDefinition(); + tmpDef.Replace(wxT("\n"), wxT(" ")); + while (tmpDef.Contains(wxT(" "))) + tmpDef.Replace(wxT(" "), wxT(" ")); + + lstConstraints->AppendItem(foreignKeyFactory.GetIconId(), fk.GetName(), tmpDef); + constraintsDefinition.Add(tmpDef); + } + break; + } + case 2: // Exclusion Constraint + { + dlgExclude ec(&excludeFactory, mainForm, lstColumns); + ec.CenterOnParent(); + ec.SetDatabase(database); + if (ec.Go(true) != wxID_CANCEL) + { + wxString tmpDef = ec.GetDefinition(); + tmpDef.Replace(wxT("\n"), wxT(" ")); + while (tmpDef.Contains(wxT(" "))) + tmpDef.Replace(wxT(" "), wxT(" ")); + + lstConstraints->AppendItem(excludeFactory.GetIconId(), ec.GetName(), tmpDef); + constraintsDefinition.Add(tmpDef); + } + break; + } + case 3: // Unique + { + dlgUnique unq(&uniqueFactory, mainForm, lstColumns); + unq.CenterOnParent(); + unq.SetDatabase(database); + if (unq.Go(true) != wxID_CANCEL) + { + wxString tmpDef = unq.GetDefinition(); + tmpDef.Replace(wxT("\n"), wxT(" ")); + + lstConstraints->AppendItem(uniqueFactory.GetIconId(), unq.GetName(), tmpDef); + constraintsDefinition.Add(tmpDef); + } + break; + } + case 4: // Check + { + dlgCheck chk(&checkFactory, mainForm); + chk.CenterOnParent(); + chk.SetDatabase(database); + if (chk.Go(true) != wxID_CANCEL) + { + wxString tmpDef = chk.GetDefinition(); + tmpDef.Replace(wxT("\n"), wxT(" ")); + + lstConstraints->AppendItem(checkFactory.GetIconId(), chk.GetName(), tmpDef); + constraintsDefinition.Add(tmpDef); + } + break; + } + } + CheckChange(); +} + + +void dlgTable::OnRemoveConstr(wxCommandEvent &ev) +{ + if (settings->GetConfirmDelete()) + { + if (wxMessageBox(_("Are you sure you wish to remove the selected constraint?"), _("Remove constraint?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) + return; + } + + int pos = lstConstraints->GetSelection(); + if (pos < 0) + return; + + wxListItem item; + item.SetId(pos); + item.SetColumn(0); + item.SetMask(wxLIST_MASK_IMAGE); + lstConstraints->GetItem(item); + if (item.GetImage() == primaryKeyFactory.GetIconId()) + { + hasPK = false; + FillConstraint(); + } + + lstConstraints->DeleteItem(pos); + constraintsDefinition.RemoveAt(pos); + btnRemoveConstr->Disable(); + + CheckChange(); +} + + +void dlgTable::OnSelChangeConstr(wxListEvent &ev) +{ + btnRemoveConstr->Enable(); +} + + +void dlgTable::FillAutoVacuumParameters(wxString &setStr, wxString &resetStr, + const wxString ¶meter, const wxString &val) +{ + if (val == wxT("-1")) + { + if (resetStr.IsEmpty()) + resetStr = wxT(" RESET ("); + else + resetStr += wxT(","); + resetStr += wxT("\n ") + parameter; + } + else + { + if (setStr.IsEmpty()) + setStr = wxT(" SET ("); + else + setStr += wxT(","); + setStr += wxT("\n ") + parameter + wxT(" = ") + val; + } +} + + +void dlgTable::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} diff --git a/dlg/dlgTablespace.cpp b/dlg/dlgTablespace.cpp new file mode 100644 index 0000000..81cc85e --- /dev/null +++ b/dlg/dlgTablespace.cpp @@ -0,0 +1,384 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgTablespace.cpp - Tablespace property +// +////////////////////////////////////////////////////////////////////////// + + + +#include "pgAdmin3.h" + +// wxWindows headers +#include + + +// App headers +#include "utils/misc.h" +#include "dlg/dlgTablespace.h" +#include "schema/pgTablespace.h" +#include "ctl/ctlSeclabelPanel.h" + +// pointer to controls +#define txtLocation CTRL_TEXT("txtLocation") +#define lstVariables CTRL_LISTVIEW("lstVariables") +#define cbVarname CTRL_COMBOBOX2("cbVarname") +#define txtValue CTRL_TEXT("txtValue") +#define chkValue CTRL_CHECKBOX("chkValue") +#define btnAdd CTRL_BUTTON("wxID_ADD") +#define btnRemove CTRL_BUTTON("wxID_REMOVE") + +dlgProperty *pgTablespaceFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgTablespace(this, frame, (pgTablespace *)node); +} + + +BEGIN_EVENT_TABLE(dlgTablespace, dlgSecurityProperty) + EVT_TEXT(XRCID("txtLocation"), dlgProperty::OnChange) + EVT_LIST_ITEM_SELECTED(XRCID("lstVariables"), dlgTablespace::OnVarSelChange) + EVT_BUTTON(wxID_ADD, dlgTablespace::OnVarAdd) + EVT_BUTTON(wxID_REMOVE, dlgTablespace::OnVarRemove) + EVT_TEXT(XRCID("cbVarname"), dlgTablespace::OnVarnameSelChange) + EVT_COMBOBOX(XRCID("cbVarname"), dlgTablespace::OnVarnameSelChange) +END_EVENT_TABLE(); + + + +dlgTablespace::dlgTablespace(pgaFactory *f, frmMain *frame, pgTablespace *node) + : dlgSecurityProperty(f, frame, node, wxT("dlgTablespace"), wxT("CREATE"), "C") +{ + tablespace = node; + lstVariables->CreateColumns(0, _("Variable"), _("Value")); + chkValue->Hide(); + btnOK->Disable(); + + seclabelPage = new ctlSeclabelPanel(nbNotebook); +} + + +pgObject *dlgTablespace::GetObject() +{ + return tablespace; +} + + +wxString dlgTablespace::GetHelpPage() const +{ + if (nbNotebook->GetSelection() == 1) + return wxT("pg/runtime-config"); + return dlgSecurityProperty::GetHelpPage(); +} + + +int dlgTablespace::Go(bool modal) +{ + if (connection->BackendMinimumVersion(9, 2)) + { + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(tablespace); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgTablespace::OnChange)); + } + else + seclabelPage->Disable(); + + pgSet *set; + if (connection->BackendMinimumVersion(8, 5)) + { + set = connection->ExecuteSet(wxT("SELECT name, vartype, min_val, max_val\n") + wxT(" FROM pg_settings WHERE name IN ('seq_page_cost', 'random_page_cost')")); + if (set) + { + while (!set->Eof()) + { + cbVarname->Append(set->GetVal(0)); + varInfo.Add(set->GetVal(wxT("vartype")) + wxT(" ") + + set->GetVal(wxT("min_val")) + wxT(" ") + + set->GetVal(wxT("max_val"))); + set->MoveNext(); + } + delete set; + + cbVarname->SetSelection(0); + SetupVarEditor(0); + } + } + else + { + lstVariables->Enable(false); + btnAdd->Enable(false); + btnRemove->Enable(false); + cbVarname->Enable(false); + txtValue->Enable(false); + chkValue->Enable(false); + } + + if (tablespace) + { + // Edit Mode + txtName->SetValue(tablespace->GetIdentifier()); + txtLocation->SetValue(tablespace->GetLocation()); + txtComment->SetValue(tablespace->GetComment()); + + txtLocation->Disable(); + + size_t i; + for (i = 0 ; i < tablespace->GetVariables().GetCount() ; i++) + { + wxString item = tablespace->GetVariables().Item(i); + lstVariables->AppendItem(0, item.BeforeFirst('='), item.AfterFirst('=')); + } + } + else + { + } + + // Tablespace comments are only appropriate in 8.2+ + if (!connection->BackendMinimumVersion(8, 2)) + txtComment->Disable(); + + return dlgSecurityProperty::Go(modal); +} + + +#ifdef __WXMAC__ +void dlgTablespace::OnChangeSize(wxSizeEvent &ev) +{ + SetPrivilegesLayout(); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + + +void dlgTablespace::CheckChange() +{ + bool enable = true; + if (tablespace) + { + enable = txtComment->GetValue() != tablespace->GetComment() + || GetName() != tablespace->GetName() + || cbOwner->GetValue() != tablespace->GetOwner() + || dirtyVars; + if (seclabelPage && connection->BackendMinimumVersion(9, 2)) + enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); + } + else + { + CheckValid(enable, !GetName().IsEmpty(), _("Please specify name.")); + CheckValid(enable, !txtLocation->GetValue().IsEmpty(), _("Please specify location.")); + } + EnableOK(enable); +} + + +pgObject *dlgTablespace::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + pgObject *obj = tablespaceFactory.CreateObjects(collection, 0, wxT("\n WHERE spcname=") + qtDbString(name)); + return obj; +} + + +wxString dlgTablespace::GetSql() +{ + wxString sql; + wxString name = GetName(); + + if (tablespace) + { + // Edit Mode + + AppendNameChange(sql); + AppendOwnerChange(sql, wxT("TABLESPACE ") + qtIdent(name)); + + sql += GetGrant(wxT("C"), wxT("TABLESPACE ") + qtIdent(name)); + AppendComment(sql, wxT("TABLESPACE"), 0, tablespace); + + wxArrayString vars; + + size_t index; + + for (index = 0 ; index < tablespace->GetVariables().GetCount() ; index++) + vars.Add(tablespace->GetVariables().Item(index)); + + int cnt = lstVariables->GetItemCount(); + int pos; + + // check for changed or added vars + for (pos = 0 ; pos < cnt ; pos++) + { + wxString newVar = lstVariables->GetText(pos); + wxString newVal = lstVariables->GetText(pos, 1); + + wxString oldVal; + + for (index = 0 ; index < vars.GetCount() ; index++) + { + wxString var = vars.Item(index); + if (var.BeforeFirst('=').IsSameAs(newVar, false)) + { + oldVal = var.Mid(newVar.Length() + 1); + vars.RemoveAt(index); + break; + } + } + if (oldVal != newVal) + { + sql += wxT("ALTER TABLESPACE ") + qtIdent(name) + + wxT("\n SET (") + newVar + + wxT("=") + newVal + + wxT(");\n"); + } + } + + // check for removed vars + for (pos = 0 ; pos < (int)vars.GetCount() ; pos++) + { + sql += wxT("ALTER TABLESPACE ") + qtIdent(name) + + wxT("\n RESET (") + vars.Item(pos).BeforeFirst('=') + + wxT(");\n"); + } + } + else + { + // Create Mode + sql = wxT("CREATE TABLESPACE ") + qtIdent(name); + AppendIfFilled(sql, wxT("\n OWNER "), qtIdent(cbOwner->GetValue())); + sql += wxT("\n LOCATION ") + qtDbString(txtLocation->GetValue()) + + wxT(";\n"); + } + + if (seclabelPage && connection->BackendMinimumVersion(9, 2)) + sql += seclabelPage->GetSqlForSecLabels(wxT("TABLESPACE"), qtIdent(name)); + + + return sql; +} + +wxString dlgTablespace::GetSql2() +{ + wxString sql; + wxString name = GetName(); + + if (!tablespace) + { + sql += GetGrant(wxT("C"), wxT("TABLESPACE ") + qtIdent(name)); + AppendComment(sql, wxT("TABLESPACE"), 0, tablespace); + + // check for changed or added vars + for (int pos = 0 ; pos < lstVariables->GetItemCount() ; pos++) + { + sql += wxT("ALTER TABLESPACE ") + qtIdent(name) + + wxT("\n SET (") + lstVariables->GetText(pos) + + wxT("=") + lstVariables->GetText(pos, 1) + + wxT(");\n"); + } + } + + return sql; +} + +void dlgTablespace::OnVarnameSelChange(wxCommandEvent &ev) +{ + int sel = cbVarname->GuessSelection(ev); + + SetupVarEditor(sel); +} + +void dlgTablespace::SetupVarEditor(int var) +{ + if (var >= 0 && varInfo.Count() > 0) + { + wxStringTokenizer vals(varInfo.Item(var)); + wxString typ = vals.GetNextToken(); + + if (typ == wxT("bool")) + { + txtValue->Hide(); + chkValue->Show(); + chkValue->SetSize(wxDefaultCoord, wxDefaultCoord, + cbVarname->GetSize().GetWidth(), cbVarname->GetSize().GetHeight()); + } + else + { + chkValue->Hide(); + txtValue->Show(); + if (typ == wxT("string") || typ == wxT("enum")) + txtValue->SetValidator(wxTextValidator()); + else + txtValue->SetValidator(numericValidator); + txtValue->SetSize(wxDefaultCoord, wxDefaultCoord, + cbVarname->GetSize().GetWidth(), cbVarname->GetSize().GetHeight()); + } + } +} + +void dlgTablespace::OnVarSelChange(wxListEvent &ev) +{ + long pos = lstVariables->GetSelection(); + if (pos >= 0) + { + wxString value = lstVariables->GetText(pos, 1); + cbVarname->SetValue(lstVariables->GetText(pos)); + + // We used to raise an OnVarnameSelChange() event here, but + // at this point the combo box hasn't necessarily updated. + int sel = cbVarname->FindString(lstVariables->GetText(pos)); + SetupVarEditor(sel); + + txtValue->SetValue(value); + chkValue->SetValue(value == wxT("on")); + } +} + + +void dlgTablespace::OnVarAdd(wxCommandEvent &ev) +{ + wxString name = cbVarname->GetValue(); + wxString value; + if (chkValue->IsShown()) + value = chkValue->GetValue() ? wxT("on") : wxT("off"); + else + value = txtValue->GetValue().Strip(wxString::both); + + if (value.IsEmpty()) + value = wxT("DEFAULT"); + + if (!name.IsEmpty()) + { + long pos = lstVariables->FindItem(-1, name); + if (pos < 0) + { + pos = lstVariables->GetItemCount(); + lstVariables->InsertItem(pos, name, 0); + } + lstVariables->SetItem(pos, 1, value); + } + dirtyVars = true; + CheckChange(); +} + + +void dlgTablespace::OnVarRemove(wxCommandEvent &ev) +{ + if (lstVariables->GetSelection() >= 0) + { + lstVariables->DeleteCurrentItem(); + dirtyVars = true; + CheckChange(); + } +} + + +void dlgTablespace::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} diff --git a/dlg/dlgTextSearchConfiguration.cpp b/dlg/dlgTextSearchConfiguration.cpp new file mode 100644 index 0000000..2d7c001 --- /dev/null +++ b/dlg/dlgTextSearchConfiguration.cpp @@ -0,0 +1,444 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgTextSearchConfiguration.cpp - PostgreSQL Text Search Configuration Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgTextSearchConfiguration.h" +#include "schema/pgSchema.h" +#include "schema/pgTextSearchConfiguration.h" +#include "schema/pgDatatype.h" + + +// pointer to controls +#define cbParser CTRL_COMBOBOX2("cbParser") +#define cbCopy CTRL_COMBOBOX2("cbCopy") +#define lstTokens CTRL_LISTVIEW("lstTokens") +#define cbToken CTRL_COMBOBOX2("cbToken") +#define txtDictionary CTRL_TEXT("txtDictionary") +#define cbDictionary CTRL_CHOICE("cbDictionary") +#define btnAdd CTRL_BUTTON("wxID_ADD") +#define btnRemove CTRL_BUTTON("wxID_REMOVE") + + +BEGIN_EVENT_TABLE(dlgTextSearchConfiguration, dlgTypeProperty) + EVT_TEXT(XRCID("cbParser"), dlgTextSearchConfiguration::OnChange) + EVT_COMBOBOX(XRCID("cbParser"), dlgTextSearchConfiguration::OnChange) + EVT_TEXT(XRCID("cbCopy"), dlgTextSearchConfiguration::OnChange) + EVT_COMBOBOX(XRCID("cbCopy"), dlgTextSearchConfiguration::OnChange) + EVT_LIST_ITEM_SELECTED(XRCID("lstTokens"), dlgTextSearchConfiguration::OnSelChangeToken) + EVT_TEXT(XRCID("cbToken"), dlgTextSearchConfiguration::OnChangeCbToken) + EVT_COMBOBOX(XRCID("cbToken"), dlgTextSearchConfiguration::OnChangeCbToken) + EVT_TEXT(XRCID("txtDictionary"), dlgTextSearchConfiguration::OnChangeTxtDictionary) + EVT_CHOICE(XRCID("cbDictionary"), dlgTextSearchConfiguration::OnChangeCbDictionary) + EVT_BUTTON(wxID_ADD, dlgTextSearchConfiguration::OnAddToken) + EVT_BUTTON(wxID_REMOVE, dlgTextSearchConfiguration::OnRemoveToken) +#ifdef __WXMAC__ + EVT_SIZE( dlgTextSearchConfiguration::OnChangeSize) +#endif +END_EVENT_TABLE(); + + + +dlgProperty *pgTextSearchConfigurationFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgTextSearchConfiguration(this, frame, (pgTextSearchConfiguration *)node, (pgSchema *)parent); +} + +dlgTextSearchConfiguration::dlgTextSearchConfiguration(pgaFactory *f, frmMain *frame, pgTextSearchConfiguration *node, pgSchema *sch) + : dlgTypeProperty(f, frame, wxT("dlgTextSearchConfiguration")) +{ + schema = sch; + config = node; + dirtyTokens = false; + + lstTokens->CreateColumns(0, _("Token"), _("Dictionaries")); + + cbCopy->Disable(); +} + + +pgObject *dlgTextSearchConfiguration::GetObject() +{ + return config; +} + + +int dlgTextSearchConfiguration::Go(bool modal) +{ + wxString qry; + pgSet *set; + + cbParser->Append(wxT("")); + + qry = wxT("SELECT prsname, nspname\n") + wxT(" FROM pg_ts_parser\n") + wxT(" JOIN pg_namespace n ON n.oid=prsnamespace\n") + wxT(" ORDER BY prsname\n"); + + set = connection->ExecuteSet(qry); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("prsname")); + cbParser->Append(procname); + set->MoveNext(); + } + delete set; + } + + cbCopy->Append(wxT("")); + + qry = wxT("SELECT cfgname, nspname\n") + wxT(" FROM pg_ts_config\n") + wxT(" JOIN pg_namespace n ON n.oid=cfgnamespace\n") + wxT(" ORDER BY nspname, cfgname\n"); + + set = connection->ExecuteSet(qry); + if (set) + { + cbCopy->Enable(); + while (!set->Eof()) + { + wxString configname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("cfgname")); + cbCopy->Append(configname); + set->MoveNext(); + } + delete set; + } + + if (config) + { + // edit mode + cbSchema->Enable(connection->BackendMinimumVersion(9, 1)); + cbParser->SetValue(config->GetParser()); + cbCopy->Disable(); + + // second tab handling + size_t i; + for (i = 0 ; i < config->GetTokens().GetCount() ; i++) + { + wxString token = config->GetTokens().Item(i); + lstTokens->AppendItem(token.BeforeFirst('/'), token.AfterFirst('/')); + } + + pgSet *tokens; + tokens = connection->ExecuteSet( + wxT("SELECT alias FROM ts_token_type(") + + config->GetParserOidStr() + + wxT(") ORDER BY alias")); + + if (tokens) + { + while (!tokens->Eof()) + { + cbToken->Append(tokens->GetVal(wxT("alias"))); + tokens->MoveNext(); + } + delete tokens; + } + + pgSet *dictionaries; + dictionaries = connection->ExecuteSet( + wxT("SELECT dictname FROM pg_ts_dict ORDER BY dictname")); + + if (dictionaries) + { + while (!dictionaries->Eof()) + { + cbDictionary->Append(dictionaries->GetVal(wxT("dictname"))); + dictionaries->MoveNext(); + } + delete dictionaries; + } + + if (!connection->BackendMinimumVersion(8, 0)) + cbOwner->Disable(); + } + else + { + // create mode + } + + btnAdd->Disable(); + btnRemove->Disable(); + + return dlgProperty::Go(modal); +} + + +pgObject *dlgTextSearchConfiguration::CreateObject(pgCollection *collection) +{ + pgObject *obj = textSearchConfigurationFactory.CreateObjects(collection, 0, + wxT("\n AND cfg.cfgname=") + qtDbString(GetName()) + + wxT("\n AND cfg.cfgnamespace=") + schema->GetOidStr()); + + return obj; +} + + +#ifdef __WXMAC__ +void dlgTextSearchConfiguration::OnChangeSize(wxSizeEvent &ev) +{ + lstTokens->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + + +void dlgTextSearchConfiguration::CheckChange() +{ + if (config) + { + EnableOK(txtName->GetValue() != config->GetName() + || cbSchema->GetValue() != config->GetSchema()->GetName() + || txtComment->GetValue() != config->GetComment() + || cbOwner->GetValue() != config->GetOwner() + || dirtyTokens); + } + else + { + wxString name = GetName(); + bool enable = true; + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, cbParser->GetGuessedSelection() > 0 || cbCopy->GetGuessedSelection() > 0 , _("Please select a parser or a configuration to copy.")); + + EnableOK(enable); + } +} + + +void dlgTextSearchConfiguration::OnChange(wxCommandEvent &ev) +{ + cbParser->Enable(cbCopy->GetValue().Length() == 0); + cbCopy->Enable(cbParser->GetValue().Length() == 0); + + CheckChange(); +} + +void dlgTextSearchConfiguration::OnChangeCbToken(wxCommandEvent &ev) +{ + bool found = false; + + for (int pos = 0 ; pos < lstTokens->GetItemCount() ; pos++) + { + if (lstTokens->GetText(pos).IsSameAs(cbToken->GetValue(), false)) + { + lstTokens->Select(pos); + found = true; + break; + } + } + + btnAdd->Enable(cbToken->GetValue().Length() > 0); +} + + +void dlgTextSearchConfiguration::OnChangeCbDictionary(wxCommandEvent &ev) +{ + if (!txtDictionary->GetValue().Matches(wxT("*") + cbDictionary->GetStringSelection() + wxT("*"))) + { + wxString dicts = txtDictionary->GetValue(); + if (dicts.Length() > 0) + dicts += wxT(","); + dicts += cbDictionary->GetStringSelection(); + + txtDictionary->SetValue(dicts); + } + btnAdd->Enable(cbToken->GetValue().Length() > 0); +} + + +void dlgTextSearchConfiguration::OnChangeTxtDictionary(wxCommandEvent &ev) +{ + btnAdd->Enable(cbToken->GetValue().Length() > 0); +} + + +void dlgTextSearchConfiguration::OnSelChangeToken(wxListEvent &ev) +{ + int row = lstTokens->GetSelection(); + if (row >= 0) + { + cbToken->SetValue(lstTokens->GetText(row, 0)); + txtDictionary->SetValue(lstTokens->GetText(row, 1)); + } + + btnAdd->Enable(cbToken->GetValue().Length() > 0); + btnRemove->Enable(row >= 0); +} + + +void dlgTextSearchConfiguration::OnAddToken(wxCommandEvent &ev) +{ + bool found = false; + + for (int pos = 0 ; pos < lstTokens->GetItemCount() ; pos++) + { + if (lstTokens->GetText(pos).IsSameAs(cbToken->GetValue(), false)) + { + lstTokens->SetItem(pos, 1, txtDictionary->GetValue()); + found = true; + break; + } + } + + if (!found) + { + lstTokens->AppendItem(cbToken->GetValue(), txtDictionary->GetValue()); + } + + btnAdd->Disable(); + + dirtyTokens = true; + + CheckChange(); +} + + +void dlgTextSearchConfiguration::OnRemoveToken(wxCommandEvent &ev) +{ + for (int pos = 0 ; pos < lstTokens->GetItemCount() ; pos++) + { + if (lstTokens->GetText(pos).IsSameAs(cbToken->GetValue(), false)) + { + lstTokens->DeleteItem(pos); + break; + } + } + + cbToken->SetValue(wxT("")); + txtDictionary->SetValue(wxT("")); + + btnRemove->Disable(); + + dirtyTokens = true; + + CheckChange(); +} + + +wxString dlgTextSearchConfiguration::GetSql() +{ + wxString sql; + wxString objname; + + if (config) + { + objname = schema->GetQuotedPrefix() + qtIdent(config->GetName()); + } + else + { + objname = schema->GetQuotedPrefix() + qtIdent(GetName()); + } + + if (cbParser->GetValue().Length() > 0) + { + wxArrayString toks; + size_t index; + + if (config) + { + for (index = 0 ; index < config->GetTokens().GetCount() ; index++) + toks.Add(config->GetTokens().Item(index)); + } + + int cnt = lstTokens->GetItemCount(); + int pos; + + // check for changed or added tokens + for (pos = 0 ; pos < cnt ; pos++) + { + wxString newTok = lstTokens->GetText(pos); + wxString newVal = lstTokens->GetText(pos, 1); + + wxString oldVal; + + for (index = 0 ; index < toks.GetCount() ; index++) + { + wxString tok = toks.Item(index); + if (tok.BeforeFirst('/').IsSameAs(newTok, false)) + { + oldVal = tok.Mid(newTok.Length() + 1); + toks.RemoveAt(index); + break; + } + } + if (oldVal != newVal) + { + if (oldVal.Length() == 0) + { + sql += wxT("ALTER TEXT SEARCH CONFIGURATION ") + objname + + wxT("\n ADD MAPPING FOR ") + newTok + + wxT("\n WITH ") + newVal + + wxT(";\n"); + } + else + { + sql += wxT("ALTER TEXT SEARCH CONFIGURATION ") + objname + + wxT("\n ALTER MAPPING FOR ") + newTok + + wxT("\n WITH ") + newVal + + wxT(";\n"); + } + } + } + + // check for removed tokens + wxString oldTok; + for (pos = 0 ; pos < (int)toks.GetCount() ; pos++) + { + if (!toks.Item(pos).BeforeFirst('/').IsSameAs(oldTok, false)) + { + oldTok = toks.Item(pos).BeforeFirst('/'); + sql += wxT("ALTER TEXT SEARCH CONFIGURATION ") + objname + + wxT(" DROP MAPPING FOR ") + oldTok + + wxT(";\n"); + } + } + } + + if (config) + { + // edit mode + objname = schema->GetQuotedPrefix() + qtIdent(GetName()); + AppendNameChange(sql, wxT("TEXT SEARCH CONFIGURATION ") + config->GetQuotedFullIdentifier()); + AppendOwnerChange(sql, wxT("TEXT SEARCH CONFIGURATION ") + objname); + AppendSchemaChange(sql, wxT("TEXT SEARCH CONFIGURATION ") + objname); + } + else + { + // create mode + objname = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()); + sql = wxT("CREATE TEXT SEARCH CONFIGURATION ") + + objname + + wxT(" ("); + + AppendIfFilled(sql, wxT("\n PARSER="), cbParser->GetValue()); + AppendIfFilled(sql, wxT("\n COPY="), cbCopy->GetValue()); + + sql += wxT("\n);\n"); + + } + + AppendComment(sql, wxT("TEXT SEARCH CONFIGURATION ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), config); + + return sql; +} diff --git a/dlg/dlgTextSearchDictionary.cpp b/dlg/dlgTextSearchDictionary.cpp new file mode 100644 index 0000000..83cffbd --- /dev/null +++ b/dlg/dlgTextSearchDictionary.cpp @@ -0,0 +1,350 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgTextSearchDictionary.cpp - PostgreSQL Text Search Dictionary Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgTextSearchDictionary.h" +#include "schema/pgSchema.h" +#include "schema/pgTextSearchDictionary.h" +#include "schema/pgDatatype.h" + + +// pointer to controls +#define cbTemplate CTRL_COMBOBOX2("cbTemplate") +#define lstOptions CTRL_LISTVIEW("lstOptions") +#define txtOption CTRL_TEXT("txtOption") +#define txtValue CTRL_TEXT("txtValue") +#define btnAdd CTRL_BUTTON("wxID_ADD") +#define btnRemove CTRL_BUTTON("wxID_REMOVE") + + +BEGIN_EVENT_TABLE(dlgTextSearchDictionary, dlgTypeProperty) + EVT_TEXT(XRCID("cbTemplate"), dlgTextSearchDictionary::OnChange) + EVT_COMBOBOX(XRCID("cbTemplate"), dlgTextSearchDictionary::OnChange) + EVT_LIST_ITEM_SELECTED(XRCID("lstOptions"), dlgTextSearchDictionary::OnSelChangeOption) + EVT_TEXT(XRCID("txtOption"), dlgTextSearchDictionary::OnChangeOptionName) + EVT_BUTTON(wxID_ADD, dlgTextSearchDictionary::OnAddOption) + EVT_BUTTON(wxID_REMOVE, dlgTextSearchDictionary::OnRemoveOption) +#ifdef __WXMAC__ + EVT_SIZE( dlgTextSearchDictionary::OnChangeSize) +#endif +END_EVENT_TABLE(); + + + +dlgProperty *pgTextSearchDictionaryFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgTextSearchDictionary(this, frame, (pgTextSearchDictionary *)node, (pgSchema *)parent); +} + +dlgTextSearchDictionary::dlgTextSearchDictionary(pgaFactory *f, frmMain *frame, pgTextSearchDictionary *node, pgSchema *sch) + : dlgTypeProperty(f, frame, wxT("dlgTextSearchDictionary")) +{ + schema = sch; + dict = node; +} + + +pgObject *dlgTextSearchDictionary::GetObject() +{ + return dict; +} + + +int dlgTextSearchDictionary::Go(bool modal) +{ + wxString qry; + pgSet *set; + + qry = wxT("SELECT tmplname, nspname\n") + wxT(" FROM pg_ts_template\n") + wxT(" JOIN pg_namespace n ON n.oid=tmplnamespace\n") + wxT(" ORDER BY tmplname\n"); + + set = connection->ExecuteSet(qry); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("tmplname")); + cbTemplate->Append(procname); + set->MoveNext(); + } + delete set; + } + + lstOptions->AddColumn(_("Option"), 80); + lstOptions->AddColumn(_("Value"), 40); + + if (dict) + { + // edit mode + cbSchema->Enable(connection->BackendMinimumVersion(9, 1)); + cbTemplate->SetValue(dict->GetTemplate()); + cbTemplate->Disable(); + + wxString options = dict->GetOptions(); + wxString option, optionname, optionvalue; + while (options.Length() > 0) + { + option = options.BeforeFirst(','); + optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim(); + optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim(); + lstOptions->AppendItem(optionname, optionvalue); + options = options.AfterFirst(','); + } + + if (!connection->BackendMinimumVersion(8, 0)) + cbOwner->Disable(); + } + else + { + // create mode + } + + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnAdd->Disable(); + btnRemove->Disable(); + + return dlgProperty::Go(modal); +} + + +pgObject *dlgTextSearchDictionary::CreateObject(pgCollection *collection) +{ + pgObject *obj = textSearchDictionaryFactory.CreateObjects(collection, 0, + wxT("\n AND dict.dictname=") + qtDbString(GetName()) + + wxT("\n AND dict.dictnamespace=") + schema->GetOidStr()); + + return obj; +} + + +#ifdef __WXMAC__ +void dlgTextSearchDictionary::OnChangeSize(wxSizeEvent &ev) +{ + lstOptions->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + + +void dlgTextSearchDictionary::CheckChange() +{ + if (dict) + { + EnableOK(txtName->GetValue() != dict->GetName() + || cbSchema->GetValue() != dict->GetSchema()->GetName() + || txtComment->GetValue() != dict->GetComment() + || cbOwner->GetValue() != dict->GetOwner() + || GetOptionsSql().Length() > 0); + } + else + { + wxString name = GetName(); + bool enable = true; + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, cbTemplate->GetValue().Length() > 0 , _("Please select a template.")); + + EnableOK(enable); + } +} + + +void dlgTextSearchDictionary::OnChange(wxCommandEvent &ev) +{ + CheckChange(); +} + + +void dlgTextSearchDictionary::OnChangeOptionName(wxCommandEvent &ev) +{ + btnAdd->Enable(txtOption->GetValue().Length() > 0); +} + + +void dlgTextSearchDictionary::OnSelChangeOption(wxListEvent &ev) +{ + int row = lstOptions->GetSelection(); + if (row >= 0) + { + txtOption->SetValue(lstOptions->GetText(row, 0)); + txtValue->SetValue(lstOptions->GetText(row, 1)); + } + + btnRemove->Enable(row >= 0); +} + + +void dlgTextSearchDictionary::OnAddOption(wxCommandEvent &ev) +{ + bool found = false; + + for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + if (lstOptions->GetText(pos).IsSameAs(txtOption->GetValue(), false)) + { + lstOptions->SetItem(pos, 1, txtValue->GetValue()); + found = true; + break; + } + } + + if (!found) + { + lstOptions->AppendItem(txtOption->GetValue(), txtValue->GetValue()); + } + + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnAdd->Disable(); + + CheckChange(); +} + + +void dlgTextSearchDictionary::OnRemoveOption(wxCommandEvent &ev) +{ + int sel = lstOptions->GetSelection(); + lstOptions->DeleteItem(sel); + + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnRemove->Disable(); + + CheckChange(); +} + + +wxString dlgTextSearchDictionary::GetOptionsSql() +{ + wxString options = dict->GetOptions(); + wxString option, optionname, optionvalue, sqloptions; + bool found; + int pos; + + while (options.Length() > 0) + { + option = options.BeforeFirst(','); + optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim(); + optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim(); + + // check for options + found = false; + for (pos = 0 ; pos < lstOptions->GetItemCount() && !found; pos++) + { + found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0; + if (found) break; + } + + if (found) + { + if (lstOptions->GetText(pos, 1).Cmp(optionvalue) != 0) + { + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += optionname + wxT("=") + lstOptions->GetText(pos, 1); + } + } + else + { + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += optionname; + } + + options = options.AfterFirst(','); + } + + for (pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + options = dict->GetOptions(); + found = false; + + while (options.Length() > 0 && !found) + { + option = options.BeforeFirst(','); + optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim(); + found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0; + options = options.AfterFirst(','); + } + + if (!found) + { + optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim(); + + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += lstOptions->GetText(pos, 0) + wxT("=") + lstOptions->GetText(pos, 1); + } + } + + return sqloptions; +} + + +wxString dlgTextSearchDictionary::GetSql() +{ + wxString sql; + wxString objname; + + if (dict) + { + // edit mode + objname = schema->GetQuotedPrefix() + qtIdent(GetName()); + AppendNameChange(sql, wxT("TEXT SEARCH DICTIONARY ") + dict->GetQuotedFullIdentifier()); + + wxString sqloptions = GetOptionsSql(); + if (sqloptions.Length() > 0) + { + sql += wxT("ALTER TEXT SEARCH DICTIONARY ") + objname + + wxT("\n (") + sqloptions + wxT(");\n"); + } + AppendOwnerChange(sql, wxT("TEXT SEARCH DICTIONARY ") + objname); + + AppendSchemaChange(sql, wxT("TEXT SEARCH DICTIONARY ") + objname); + } + else + { + // create mode + objname = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()); + sql = wxT("CREATE TEXT SEARCH DICTIONARY ") + + objname + + wxT("\n (") + + wxT("\n TEMPLATE = ") + cbTemplate->GetValue(); + + // check for options + for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + sql += wxT(", ") + lstOptions->GetText(pos, 0) + + wxT("=") + lstOptions->GetText(pos, 1); + } + + sql += wxT("\n);\n"); + + AppendOwnerNew(sql, wxT("TEXT SEARCH DICTIONARY ") + objname); + } + + AppendComment(sql, wxT("TEXT SEARCH DICTIONARY ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), dict); + + return sql; +} diff --git a/dlg/dlgTextSearchParser.cpp b/dlg/dlgTextSearchParser.cpp new file mode 100644 index 0000000..ecb667f --- /dev/null +++ b/dlg/dlgTextSearchParser.cpp @@ -0,0 +1,262 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgTextSearchParser.cpp - PostgreSQL Text Search Parser Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgTextSearchParser.h" +#include "schema/pgSchema.h" +#include "schema/pgTextSearchParser.h" +#include "schema/pgDatatype.h" + + +// pointer to controls +#define cbStart CTRL_COMBOBOX2("cbStart") +#define cbGetToken CTRL_COMBOBOX2("cbGetToken") +#define cbEnd CTRL_COMBOBOX2("cbEnd") +#define cbLextypes CTRL_COMBOBOX2("cbLextypes") +#define cbHeadline CTRL_COMBOBOX2("cbHeadline") + + +BEGIN_EVENT_TABLE(dlgTextSearchParser, dlgTypeProperty) + EVT_TEXT(XRCID("cbStart"), dlgTextSearchParser::OnChange) + EVT_COMBOBOX(XRCID("cbStart"), dlgTextSearchParser::OnChange) + EVT_TEXT(XRCID("cbGetToken"), dlgTextSearchParser::OnChange) + EVT_COMBOBOX(XRCID("cbGetToken"), dlgTextSearchParser::OnChange) + EVT_TEXT(XRCID("cbEnd"), dlgTextSearchParser::OnChange) + EVT_COMBOBOX(XRCID("cbEnd"), dlgTextSearchParser::OnChange) + EVT_TEXT(XRCID("cbLextypes"), dlgTextSearchParser::OnChange) + EVT_COMBOBOX(XRCID("cbLextypes"), dlgTextSearchParser::OnChange) + EVT_TEXT(XRCID("cbHeadline"), dlgTextSearchParser::OnChange) + EVT_COMBOBOX(XRCID("cbHeadline"), dlgTextSearchParser::OnChange) +END_EVENT_TABLE(); + + + +dlgProperty *pgTextSearchParserFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgTextSearchParser(this, frame, (pgTextSearchParser *)node, (pgSchema *)parent); +} + +dlgTextSearchParser::dlgTextSearchParser(pgaFactory *f, frmMain *frame, pgTextSearchParser *node, pgSchema *sch) + : dlgTypeProperty(f, frame, wxT("dlgTextSearchParser")) +{ + schema = sch; + parser = node; +} + + +pgObject *dlgTextSearchParser::GetObject() +{ + return parser; +} + + +int dlgTextSearchParser::Go(bool modal) +{ + wxString qry; + pgSet *set; + + qry = wxT("SELECT proname, nspname\n") + wxT(" FROM pg_proc\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE proargtypes='2281 23'\n") + wxT(" ORDER BY proname\n"); + + set = connection->ExecuteSet(qry); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + cbStart->Append(procname); + set->MoveNext(); + } + delete set; + } + + qry = wxT("SELECT proname, nspname\n") + wxT(" FROM pg_proc\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE proargtypes='2281 2281 2281'\n") + wxT(" ORDER BY proname\n"); + + set = connection->ExecuteSet(qry); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + cbGetToken->Append(procname); + set->MoveNext(); + } + delete set; + } + + qry = wxT("SELECT proname, nspname, prorettype\n") + wxT(" FROM pg_proc\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE prorettype=2278 AND proargtypes='2281'\n") + wxT(" ORDER BY proname\n"); + + set = connection->ExecuteSet(qry); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + cbEnd->Append(procname); + set->MoveNext(); + } + delete set; + } + + qry = wxT("SELECT proname, nspname, prorettype\n") + wxT(" FROM pg_proc\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE prorettype=2281 AND proargtypes='2281'\n") + wxT(" ORDER BY proname\n"); + + set = connection->ExecuteSet(qry); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + cbLextypes->Append(procname); + set->MoveNext(); + } + delete set; + } + + cbHeadline->Append(wxT("")); + + qry = wxT("SELECT proname, nspname\n") + wxT(" FROM pg_proc\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE proargtypes='2281 2281 3615'\n") + wxT(" ORDER BY proname\n"); + + set = connection->ExecuteSet(qry); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + cbHeadline->Append(procname); + set->MoveNext(); + } + delete set; + } + + if (parser) + { + // edit mode + cbSchema->Enable(connection->BackendMinimumVersion(9, 1)); + cbStart->SetValue(parser->GetStart()); + cbStart->Disable(); + cbGetToken->SetValue(parser->GetGettoken()); + cbGetToken->Disable(); + cbEnd->SetValue(parser->GetEnd()); + cbEnd->Disable(); + cbLextypes->SetValue(parser->GetLextypes()); + cbLextypes->Disable(); + cbHeadline->SetValue(parser->GetHeadline()); + cbHeadline->Disable(); + } + else + { + // create mode + } + + cbOwner->Disable(); + + return dlgProperty::Go(modal); +} + + +pgObject *dlgTextSearchParser::CreateObject(pgCollection *collection) +{ + pgObject *obj = textSearchParserFactory.CreateObjects(collection, 0, + wxT("\n AND prs.prsname=") + qtDbString(GetName()) + + wxT("\n AND prs.prsnamespace=") + schema->GetOidStr()); + + return obj; +} + + +void dlgTextSearchParser::CheckChange() +{ + if (parser) + { + EnableOK(txtName->GetValue() != parser->GetName() + || cbSchema->GetValue() != parser->GetSchema()->GetName() + || txtComment->GetValue() != parser->GetComment()); + } + else + { + wxString name = GetName(); + bool enable = true; + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, cbStart->GetValue().Length() > 0 , _("Please select a start function.")); + CheckValid(enable, cbGetToken->GetValue().Length() > 0 , _("Please select a gettoken function.")); + CheckValid(enable, cbEnd->GetValue().Length() > 0 , _("Please select an end function.")); + CheckValid(enable, cbLextypes->GetValue().Length() > 0 , _("Please select a lextypes function.")); + + EnableOK(enable); + } +} + + +void dlgTextSearchParser::OnChange(wxCommandEvent &ev) +{ + CheckChange(); +} + + +wxString dlgTextSearchParser::GetSql() +{ + wxString sql; + wxString objname; + + if (parser) + { + // edit mode + objname = schema->GetQuotedPrefix() + qtIdent(GetName()); + AppendNameChange(sql, wxT("TEXT SEARCH PARSER ") + parser->GetQuotedFullIdentifier()); + AppendSchemaChange(sql, wxT("TEXT SEARCH PARSER ") + objname); + } + else + { + // create mode + objname = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()); + sql = wxT("CREATE TEXT SEARCH PARSER ") + + objname + + wxT(" (") + + wxT("\n START = ") + cbStart->GetValue() + + wxT(",\n GETTOKEN = ") + cbGetToken->GetValue() + + wxT(",\n END = ") + cbEnd->GetValue() + + wxT(",\n LEXTYPES = ") + cbLextypes->GetValue(); + + AppendIfFilled(sql, wxT(",\n HEADLINE="), cbHeadline->GetValue()); + + sql += wxT("\n);\n"); + + } + AppendComment(sql, wxT("TEXT SEARCH PARSER ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), parser); + + return sql; +} diff --git a/dlg/dlgTextSearchTemplate.cpp b/dlg/dlgTextSearchTemplate.cpp new file mode 100644 index 0000000..3c5f6c7 --- /dev/null +++ b/dlg/dlgTextSearchTemplate.cpp @@ -0,0 +1,190 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgTextSearchTemplate.cpp - PostgreSQL Text Search Template Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgTextSearchTemplate.h" +#include "schema/pgSchema.h" +#include "schema/pgTextSearchTemplate.h" +#include "schema/pgDatatype.h" + + +// pointer to controls +#define cbInit CTRL_COMBOBOX2("cbInit") +#define cbLexize CTRL_COMBOBOX2("cbLexize") + + +BEGIN_EVENT_TABLE(dlgTextSearchTemplate, dlgTypeProperty) + EVT_TEXT(XRCID("cbInit"), dlgTextSearchTemplate::OnChange) + EVT_COMBOBOX(XRCID("cbInit"), dlgTextSearchTemplate::OnChange) + EVT_TEXT(XRCID("cbLexize"), dlgTextSearchTemplate::OnChange) + EVT_COMBOBOX(XRCID("cbLexize"), dlgTextSearchTemplate::OnChange) +END_EVENT_TABLE(); + + + +dlgProperty *pgTextSearchTemplateFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgTextSearchTemplate(this, frame, (pgTextSearchTemplate *)node, (pgSchema *)parent); +} + +dlgTextSearchTemplate::dlgTextSearchTemplate(pgaFactory *f, frmMain *frame, pgTextSearchTemplate *node, pgSchema *sch) + : dlgTypeProperty(f, frame, wxT("dlgTextSearchTemplate")) +{ + schema = sch; + tmpl = node; +} + + +pgObject *dlgTextSearchTemplate::GetObject() +{ + return tmpl; +} + + +int dlgTextSearchTemplate::Go(bool modal) +{ + wxString qry; + pgSet *set; + + cbInit->Append(wxT("")); + + qry = wxT("SELECT proname, nspname\n") + wxT(" FROM pg_proc\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE prorettype=2281 and proargtypes='2281'\n") + wxT(" ORDER BY proname\n"); + + set = connection->ExecuteSet(qry); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + cbInit->Append(procname); + set->MoveNext(); + } + delete set; + } + + qry = wxT("SELECT proname, nspname\n") + wxT(" FROM pg_proc\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE prorettype=2281 and proargtypes='2281 2281 2281 2281'\n") + wxT(" ORDER BY proname\n"); + + set = connection->ExecuteSet(qry); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + cbLexize->Append(procname); + set->MoveNext(); + } + delete set; + } + + if (tmpl) + { + // edit mode + cbSchema->Enable(connection->BackendMinimumVersion(9, 1)); + cbInit->SetValue(tmpl->GetInit()); + cbInit->Disable(); + cbLexize->SetValue(tmpl->GetLexize()); + cbLexize->Disable(); + } + else + { + // create mode + } + + cbOwner->Disable(); + + return dlgProperty::Go(modal); +} + + +pgObject *dlgTextSearchTemplate::CreateObject(pgCollection *collection) +{ + pgObject *obj = textSearchTemplateFactory.CreateObjects(collection, 0, + wxT("\n AND tmpl.tmplname=") + qtDbString(GetName()) + + wxT("\n AND tmpl.tmplnamespace=") + schema->GetOidStr()); + + return obj; +} + + +void dlgTextSearchTemplate::CheckChange() +{ + if (tmpl) + { + EnableOK(txtName->GetValue() != tmpl->GetName() + || cbSchema->GetValue() != tmpl->GetSchema()->GetName() + || txtComment->GetValue() != tmpl->GetComment()); + } + else + { + wxString name = GetName(); + bool enable = true; + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, cbLexize->GetGuessedSelection() > 0 , _("Please select a lexize function.")); + + EnableOK(enable); + } +} + + +void dlgTextSearchTemplate::OnChange(wxCommandEvent &ev) +{ + CheckChange(); +} + + +wxString dlgTextSearchTemplate::GetSql() +{ + wxString sql; + wxString objname; + + if (tmpl) + { + // edit mode + objname = schema->GetQuotedPrefix() + qtIdent(GetName()); + AppendNameChange(sql, wxT("TEXT SEARCH TEMPLATE ") + tmpl->GetQuotedFullIdentifier()); + AppendSchemaChange(sql, wxT("TEXT SEARCH TEMPLATE ") + objname); + } + else + { + // create mode + objname = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()); + sql = wxT("CREATE TEXT SEARCH TEMPLATE ") + + objname + + wxT(" ("); + + AppendIfFilled(sql, wxT("\n INIT="), cbInit->GetValue()); + if (cbInit->GetValue().Length() > 0) + sql += wxT(","); + AppendIfFilled(sql, wxT("\n LEXIZE="), cbLexize->GetValue()); + + sql += wxT("\n);\n"); + + } + + AppendComment(sql, wxT("TEXT SEARCH TEMPLATE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), tmpl); + + return sql; +} diff --git a/dlg/dlgTrigger.cpp b/dlg/dlgTrigger.cpp new file mode 100644 index 0000000..c6dbc74 --- /dev/null +++ b/dlg/dlgTrigger.cpp @@ -0,0 +1,551 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgTrigger.cpp - PostgreSQL Trigger Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "frm/frmMain.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgTrigger.h" +#include "schema/pgTrigger.h" +#include "schema/pgTable.h" +#include "schema/pgSchema.h" + + +// pointer to controls +#define chkRow CTRL_CHECKBOX("chkRow") +#define chkConstraint CTRL_CHECKBOX("chkConstraint") +#define chkDeferrable CTRL_CHECKBOX("chkDeferrable") +#define chkDeferred CTRL_CHECKBOX("chkDeferred") +#define cbFunction CTRL_COMBOBOX2("cbFunction") +#define txtArguments CTRL_TEXT("txtArguments") +#define rdbFires CTRL_RADIOBOX("rdbFires") +#define chkInsert CTRL_CHECKBOX("chkInsert") +#define chkUpdate CTRL_CHECKBOX("chkUpdate") +#define chkDelete CTRL_CHECKBOX("chkDelete") +#define chkTruncate CTRL_CHECKBOX("chkTruncate") +#define txtWhen CTRL_TEXT("txtWhen") +#define txtBody CTRL_SQLBOX("txtBody") +#define btnAddCol CTRL_BUTTON("btnAddCol") +#define btnRemoveCol CTRL_BUTTON("btnRemoveCol") +#define lstColumns CTRL_LISTVIEW("lstColumns") + + +BEGIN_EVENT_TABLE(dlgTrigger, dlgCollistProperty) + EVT_RADIOBOX(XRCID("rdbFires"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkConstraint"), dlgTrigger::OnChangeConstraint) + EVT_CHECKBOX(XRCID("chkDeferrable"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkRow"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkInsert"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkUpdate"), dlgTrigger::OnChange) + EVT_CHECKBOX(XRCID("chkDelete"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkTruncate"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbFunction"), dlgTrigger::OnChangeFunc) + EVT_COMBOBOX(XRCID("cbFunction"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtArguments"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtWhen"), dlgProperty::OnChange) + EVT_STC_MODIFIED(XRCID("txtBody"), dlgProperty::OnChangeStc) + EVT_LIST_ITEM_SELECTED(XRCID("lstColumns"), dlgTrigger::OnSelectListCol) + EVT_COMBOBOX(XRCID("cbColumns"), dlgTrigger::OnSelectComboCol) + EVT_BUTTON(XRCID("btnAddCol"), dlgTrigger::OnAddCol) + EVT_BUTTON(XRCID("btnRemoveCol"), dlgTrigger::OnRemoveCol) +END_EVENT_TABLE(); + + +dlgProperty *pgTriggerFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgTrigger(this, frame, (pgTrigger *)node, (pgTable *)parent); +} + + +dlgTrigger::dlgTrigger(pgaFactory *f, frmMain *frame, pgTrigger *node, pgTable *parentNode) + : dlgCollistProperty(f, frame, wxT("dlgTrigger"), parentNode) +{ + trigger = node; + table = parentNode; + wxASSERT(!table || table->GetMetaType() == PGM_TABLE || table->GetMetaType() == PGM_VIEW + || table->GetMetaType() == GP_PARTITION); + + bool bVal; + settings->Read(wxT("frmQuery/ShowLineNumber"), &bVal, false); + if (!bVal) + { + txtBody->SetMarginType(1, wxSTC_MARGIN_NUMBER); + txtBody->SetMarginWidth(1, ConvertDialogToPixels(wxPoint(16, 0)).x); + } + + lstColumns->AddColumn(_("Column name")); +} + + +pgObject *dlgTrigger::GetObject() +{ + return trigger; +} + + +wxString dlgTrigger::GetColumns() +{ + wxString sql; + + int pos; + // iterate cols + for (pos = 0 ; pos < lstColumns->GetItemCount() ; pos++) + { + if (pos) + sql += wxT(", "); + + sql += qtIdent(lstColumns->GetItemText(pos)); + } + return sql; +} + + +int dlgTrigger::Go(bool modal) +{ + if (trigger) + { + // edit mode + chkRow->SetValue((trigger->GetTriggerType() & TRIGGER_TYPE_ROW) != 0); + chkInsert->SetValue((trigger->GetTriggerType() & TRIGGER_TYPE_INSERT) != 0); + chkUpdate->SetValue((trigger->GetTriggerType() & TRIGGER_TYPE_UPDATE) != 0); + chkDelete->SetValue((trigger->GetTriggerType() & TRIGGER_TYPE_DELETE) != 0); + chkTruncate->SetValue((trigger->GetTriggerType() & TRIGGER_TYPE_TRUNCATE) != 0); + if (trigger->GetTriggerType() & TRIGGER_TYPE_BEFORE) + rdbFires->SetSelection(0); + else if (trigger->GetTriggerType() & TRIGGER_TYPE_INSTEAD) + rdbFires->SetSelection(2); + else + rdbFires->SetSelection(1); + txtArguments->SetValue(trigger->GetArguments()); + txtWhen->SetValue(trigger->GetWhen()); + if (!connection->BackendMinimumVersion(7, 4)) + txtName->Disable(); + + if (trigger->GetLanguage() == wxT("edbspl")) + { + cbFunction->Append(wxString::Format(wxT("<%s>"), _("Inline EDB-SPL"))); + txtBody->SetText(trigger->GetSource()); + } + else + { + cbFunction->Append(trigger->GetFunction()); + txtBody->Disable(); + } + + cbFunction->SetSelection(0); + txtArguments->Disable(); + cbFunction->Disable(); + + if (!connection->EdbMinimumVersion(8, 0)) + { + chkRow->Disable(); + rdbFires->Disable(); + chkInsert->Disable(); + chkUpdate->Disable(); + chkDelete->Disable(); + chkTruncate->Disable(); + } + else if (!connection->BackendMinimumVersion(8, 4)) + chkTruncate->Disable(); + else if (!connection->BackendMinimumVersion(8, 5)) + txtWhen->Disable(); + + wxArrayString colsArr = trigger->GetColumnList(); + for (int colIdx = 0, colsCount = colsArr.Count(); colIdx < colsCount; colIdx++) + { + lstColumns->InsertItem(colIdx, colsArr.Item(colIdx)); + } + + if (connection->BackendMinimumVersion(8, 2)) + { + chkConstraint->SetValue(trigger->GetIsConstraint()); + chkDeferrable->SetValue(trigger->GetDeferrable()); + chkDeferred->SetValue(trigger->GetDeferred()); + } + chkConstraint->Enable(false); + chkDeferrable->Enable(false); + chkDeferred->Enable(false); + } + else + { + // create mode + if (connection->EdbMinimumVersion(8, 0)) + cbFunction->Append(wxString::Format(wxT("<%s>"), _("Inline EDB-SPL"))); + + wxString sysRestr; + if (!settings->GetShowSystemObjects()) + sysRestr = wxT(" AND ") + connection->SystemNamespaceRestriction(wxT("nspname")); + + pgSet *set = connection->ExecuteSet( + wxT("SELECT quote_ident(nspname) || '.' || quote_ident(proname)\n") + wxT(" FROM pg_proc p, pg_namespace n, pg_language l\n") + wxT(" WHERE p.pronamespace = n.oid AND p.prolang = l.oid AND l.lanname != 'edbspl' AND prorettype=") + NumToStr(PGOID_TYPE_TRIGGER) + sysRestr + + wxT(" ORDER BY nspname ASC, proname ASC ")); + if (set) + { + while (!set->Eof()) + { + cbFunction->Append(set->GetVal(0)); + set->MoveNext(); + } + delete set; + } + if (!connection->BackendMinimumVersion(7, 4)) + { + chkRow->SetValue(true); + chkRow->Disable(); + } + + txtBody->Disable(); + + if (!connection->BackendMinimumVersion(8, 4)) + chkTruncate->Disable(); + + if (!connection->BackendMinimumVersion(9, 1) || table->GetMetaType() != PGM_VIEW) + rdbFires->Enable(2, false); + + chkConstraint->Enable(connection->BackendMinimumVersion(8, 2)); + chkDeferrable->Disable(); + chkDeferred->Disable(); + } + + cbColumns->Disable(); + btnAddCol->Disable(); + btnRemoveCol->Disable(); + + // Reset the radio box rbxEvent item values with the keywords to resolve the locale issues. + rdbFires->SetString(0, wxT("BEFORE")); + rdbFires->SetString(1, wxT("AFTER")); + rdbFires->SetString(2, wxT("INSTEAD OF")); + + chkTruncate->SetLabel(wxT("TRUNCATE")); + chkDelete->SetLabel(wxT("DELETE")); + chkInsert->SetLabel(wxT("INSERT")); + chkUpdate->SetLabel(wxT("UPDATE")); + + return dlgCollistProperty::Go(modal); +} + + +void dlgTrigger::OnAddCol(wxCommandEvent &ev) +{ + wxString colName = cbColumns->GetValue(); + + if (!colName.IsEmpty()) + { + lstColumns->InsertItem(lstColumns->GetItemCount(), colName); + + cbColumns->Delete(cbColumns->GetCurrentSelection()); + if (cbColumns->GetCount()) + cbColumns->SetSelection(0); + + CheckChange(); + if (!cbColumns->GetCount()) + btnAddCol->Disable(); + } +} + + +void dlgTrigger::OnRemoveCol(wxCommandEvent &ev) +{ + long pos = lstColumns->GetSelection(); + if (pos >= 0) + { + wxString colName = lstColumns->GetItemText(pos); + + lstColumns->DeleteItem(pos); + cbColumns->Append(colName); + + CheckChange(); + btnRemoveCol->Disable(); + } +} + +wxString dlgTrigger::GetSql() +{ + wxString sql; + wxString name = GetName(); + + if (trigger) + { + if (name != trigger->GetName()) + sql = wxT("ALTER TRIGGER ") + trigger->GetQuotedIdentifier() + wxT(" ON ") + table->GetQuotedFullIdentifier() + + wxT("\n RENAME TO ") + qtIdent(name) + wxT(";\n\n"); + } + + if (!trigger || + (cbFunction->GetValue() == wxString::Format(wxT("<%s>"), _("Inline EDB-SPL")) + && ( + txtBody->GetText() != trigger->GetSource() || + chkRow->GetValue() != (trigger->GetTriggerType() & TRIGGER_TYPE_ROW) || + chkInsert->GetValue() != (trigger->GetTriggerType() & TRIGGER_TYPE_INSERT ? true : false) || + chkUpdate->GetValue() != (trigger->GetTriggerType() & TRIGGER_TYPE_UPDATE ? true : false) || + chkDelete->GetValue() != (trigger->GetTriggerType() & TRIGGER_TYPE_DELETE ? true : false) || + chkTruncate->GetValue() != (trigger->GetTriggerType() & TRIGGER_TYPE_TRUNCATE ? true : false) || + rdbFires->GetSelection() != (trigger->GetTriggerType() & TRIGGER_TYPE_BEFORE ? 0 : TRIGGER_TYPE_INSTEAD ? 2 : 1) + ) + ) + ) + { + if (cbFunction->GetValue() == wxString::Format(wxT("<%s>"), _("Inline EDB-SPL"))) + sql += wxT("CREATE OR REPLACE TRIGGER "); + else if (chkConstraint->GetValue()) + sql += wxT("CREATE CONSTRAINT TRIGGER "); + else + sql += wxT("CREATE TRIGGER "); + sql += qtIdent(name); + + if (rdbFires->GetSelection() == 1) + sql += wxT(" AFTER"); + else if (rdbFires->GetSelection() == 2) + sql += wxT(" INSTEAD OF"); + else + sql += wxT(" BEFORE"); + int actionCount = 0; + if (chkInsert->GetValue()) + { + if (actionCount++) + sql += wxT(" OR"); + sql += wxT(" INSERT"); + } + if (chkUpdate->GetValue()) + { + if (actionCount++) + sql += wxT(" OR"); + sql += wxT(" UPDATE"); + if (lstColumns->GetItemCount() > 0) + sql += wxT(" OF ") + GetColumns(); + } + if (chkDelete->GetValue()) + { + if (actionCount++) + sql += wxT(" OR"); + sql += wxT(" DELETE"); + } + if (chkTruncate->GetValue()) + { + if (actionCount++) + sql += wxT(" OR"); + sql += wxT(" TRUNCATE"); + } + sql += wxT("\n ON ") + table->GetQuotedFullIdentifier(); + if (chkDeferrable->GetValue()) + { + sql += wxT(" DEFERRABLE"); + if (chkDeferred->GetValue()) + sql += wxT(" INITIALLY DEFERRED"); + } + sql += wxT(" FOR EACH "); + if (chkRow->GetValue()) + sql += wxT("ROW"); + else + sql += wxT("STATEMENT"); + + if (connection->BackendMinimumVersion(8, 5) && !txtWhen->GetValue().IsEmpty()) + sql += wxT("\n WHEN (") + txtWhen->GetValue() + wxT(")"); + + if (cbFunction->GetValue() != wxString::Format(wxT("<%s>"), _("Inline EDB-SPL"))) + { + sql += wxT("\n EXECUTE PROCEDURE ") + cbFunction->GetValue() + + wxT("(") + txtArguments->GetValue() + + wxT(");\n"); + } + else + { + sql += wxT("\n") + txtBody->GetText(); + if (!sql.Trim().EndsWith(wxT(";"))) + sql = sql.Trim() + wxT(";"); + sql += wxT("\n"); + } + } + AppendComment(sql, wxT("TRIGGER ") + qtIdent(GetName()) + + wxT(" ON ") + table->GetQuotedFullIdentifier(), trigger); + + return sql; +} + + +pgObject *dlgTrigger::CreateObject(pgCollection *collection) +{ + pgObject *obj = triggerFactory.CreateObjects(collection, 0, + wxT("\n AND tgname=") + qtDbString(GetName()) + + wxT("\n AND tgrelid=") + table->GetOidStr() + + wxT("\n AND relnamespace=") + table->GetSchema()->GetOidStr()); + return obj; +} + + +void dlgTrigger::OnChange(wxCommandEvent &ev) +{ + if (chkUpdate->GetValue()) + { + cbColumns->Enable(); + } + else + { + if (lstColumns->GetItemCount() > 0) + { + if (wxMessageBox(_("Removing the UPDATE event will cause the column list to be cleared. Do you wish to continue?"), _("Remove UPDATE event?"), wxYES_NO) != wxYES) + { + chkUpdate->SetValue(true); + return; + } + + // Move all the columns back to the combo + for (int pos = lstColumns->GetItemCount(); pos > 0; pos--) + { + wxString colName = lstColumns->GetItemText(pos - 1); + + lstColumns->DeleteItem(pos - 1); + cbColumns->Append(colName); + } + } + + cbColumns->Disable(); + btnAddCol->Disable(); + btnRemoveCol->Disable(); + } + + CheckChange(); +} + + +void dlgTrigger::OnChangeFunc(wxCommandEvent &ev) +{ + cbFunction->GuessSelection(ev); + + if (cbFunction->GetValue() == wxString::Format(wxT("<%s>"), _("Inline EDB-SPL"))) + { + txtArguments->Disable(); + txtBody->Enable(); + } + else + { + txtArguments->Enable(); + txtBody->Disable(); + } + + CheckChange(); +} + + +void dlgTrigger::OnChangeConstraint(wxCommandEvent &ev) +{ + if (chkConstraint->GetValue()) + { + rdbFires->SetSelection(1); + rdbFires->Disable(); + chkRow->SetValue(true); + chkRow->Disable(); + chkDeferrable->Enable(); + chkDeferred->Enable(); + } + else + { + rdbFires->Enable(); + chkRow->Enable(); + chkDeferrable->Disable(); + chkDeferred->Disable(); + } + + CheckChange(); +} + + +void dlgTrigger::CheckChange() +{ + bool enable = true; + + wxString function = cbFunction->GetValue(); + wxString name = GetName(); + + // We can only have per-statement TRUNCATE triggers + if (trigger || connection->BackendMinimumVersion(8, 4)) + { + if (chkRow->GetValue()) + { + chkTruncate->Disable(); + chkTruncate->SetValue(false); + } + else if (connection->EdbMinimumVersion(8, 0)) + chkTruncate->Enable(); + } + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, !function.IsEmpty(), _("Please specify trigger function.")); + + CheckValid(enable, chkInsert->GetValue() || chkUpdate->GetValue() || chkDelete->GetValue() || chkTruncate->GetValue(), + _("Please specify at least one action.")); + + if (cbFunction->GetValue() == wxString::Format(wxT("<%s>"), _("Inline EDB-SPL"))) + CheckValid(enable, !txtBody->GetText().IsEmpty(), _("Please specify trigger body.")); + + if (trigger) + { + EnableOK(enable && + (txtComment->GetValue() != trigger->GetComment() || + txtName->GetValue() != trigger->GetName() || + (txtBody->GetText() != trigger->GetSource() && cbFunction->GetValue() == wxString::Format(wxT("<%s>"), _("Inline EDB-SPL"))) || + txtWhen->GetValue() != trigger->GetWhen() || + chkRow->GetValue() != (trigger->GetTriggerType() & TRIGGER_TYPE_ROW ? true : false) || + chkInsert->GetValue() != (trigger->GetTriggerType() & TRIGGER_TYPE_INSERT ? true : false) || + chkUpdate->GetValue() != (trigger->GetTriggerType() & TRIGGER_TYPE_UPDATE ? true : false) || + chkDelete->GetValue() != (trigger->GetTriggerType() & TRIGGER_TYPE_DELETE ? true : false) || + chkTruncate->GetValue() != (trigger->GetTriggerType() & TRIGGER_TYPE_TRUNCATE ? true : false) || + rdbFires->GetSelection() != (trigger->GetTriggerType() & TRIGGER_TYPE_BEFORE ? 0 : (trigger->GetTriggerType() & TRIGGER_TYPE_INSTEAD ? 2 : 1)))); + } + else + { + EnableOK(enable); + } +} + +bool dlgTrigger::IsUpToDate() +{ + if (trigger && !trigger->IsUpToDate()) + return false; + else + return true; +} + +void dlgTrigger::OnSelectListCol(wxListEvent &ev) +{ + OnSelectCol(); +} + +void dlgTrigger::OnSelectComboCol(wxCommandEvent &ev) +{ + OnSelectCol(); +} + +void dlgTrigger::OnSelectCol() +{ + // Can't change the columns on an existing index. + if (trigger) + return; + + if (lstColumns->GetSelection() != wxNOT_FOUND) + btnRemoveCol->Enable(true); + else + btnRemoveCol->Enable(false); + + if (cbColumns->GetSelection() != wxNOT_FOUND && !cbColumns->GetValue().IsEmpty()) + btnAddCol->Enable(true); + else + btnAddCol->Enable(false); +} + + diff --git a/dlg/dlgType.cpp b/dlg/dlgType.cpp new file mode 100644 index 0000000..e9f72f8 --- /dev/null +++ b/dlg/dlgType.cpp @@ -0,0 +1,1432 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgType.cpp - PostgreSQL TYPE Property +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + + +// App headers +#include "utils/misc.h" +#include "dlg/dlgType.h" +#include "schema/pgSchema.h" +#include "schema/pgType.h" +#include "schema/pgDatatype.h" +#include "ctl/ctlSeclabelPanel.h" +#include "frm/frmMain.h" +#include "schema/pgUser.h" +#include "schema/pgGroup.h" + + +// pointer to controls +#define rdbType CTRL_RADIOBOX("rdbType") + +#define cbInput CTRL_COMBOBOX("cbInput") +#define cbOutput CTRL_COMBOBOX("cbOutput") +#define cbReceive CTRL_COMBOBOX("cbReceive") +#define cbSend CTRL_COMBOBOX("cbSend") +#define cbTypmodin CTRL_COMBOBOX("cbTypmodin") +#define cbTypmodout CTRL_COMBOBOX("cbTypmodout") +#define cbAnalyze CTRL_COMBOBOX("cbAnalyze") +#define cbCategory CTRL_COMBOBOX("cbCategory") +#define chkPrefered CTRL_CHECKBOX("chkPrefered") +#define chkVariable CTRL_CHECKBOX("chkVariable") +#define txtIntLength CTRL_TEXT("txtIntLength") +#define txtDefault CTRL_TEXT("txtDefault") +#define cbElement CTRL_COMBOBOX2("cbElement") +#define txtDelimiter CTRL_TEXT("txtDelimiter") +#define chkByValue CTRL_CHECKBOX("chkByValue") +#define cbAlignment CTRL_COMBOBOX("cbAlignment") +#define cbStorage CTRL_COMBOBOX("cbStorage") +#define lstMembers CTRL_LISTVIEW("lstMembers") +#define txtMembername CTRL_TEXT("txtMembername") +#define lstLabels CTRL_LISTVIEW("lstLabels") +#define txtLabel CTRL_TEXT("txtLabel") +#define btnAddMember CTRL_BUTTON("btnAddMember") +#define btnChangeMember CTRL_BUTTON("btnChangeMember") +#define btnRemoveMember CTRL_BUTTON("btnRemoveMember") +#define btnAddAfterLabel CTRL_BUTTON("btnAddAfterLabel") +#define btnAddBeforeLabel CTRL_BUTTON("btnAddBeforeLabel") +#define btnRemoveLabel CTRL_BUTTON("btnRemoveLabel") +#define pnlDefinition CTRL_PANEL("pnlDefinition") +#define pnlDefinitionExtern CTRL_PANEL("pnlDefinitionExtern") +#define pnlDefinitionComposite CTRL_PANEL("pnlDefinitionComposite") +#define pnlDefinitionEnum CTRL_PANEL("pnlDefinitionEnum") +#define pnlDefinitionRange CTRL_PANEL("pnlDefinitionRange") +#define chkCollatable CTRL_CHECKBOX("chkCollatable") +#define cbCollation CTRL_COMBOBOX("cbCollation") +#define cbSubtype CTRL_COMBOBOX("cbSubtype") +#define cbSubtypeOpclass CTRL_COMBOBOX("cbSubtypeOpclass") +#define cbRngCollation CTRL_COMBOBOX("cbRngCollation") +#define cbCanonical CTRL_COMBOBOX("cbCanonical") +#define cbSubtypeDiff CTRL_COMBOBOX("cbSubtypeDiff") + + +BEGIN_EVENT_TABLE(dlgType, dlgTypeProperty) + EVT_RADIOBOX(XRCID("rdbType"), dlgType::OnTypeChange) + + EVT_TEXT(XRCID("cbInput"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbInput"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbOutput"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbOutput"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtIntLength"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkVariable"), dlgProperty::OnChange) + + EVT_BUTTON(XRCID("btnAddMember"), dlgType::OnMemberAdd) + EVT_BUTTON(XRCID("btnChangeMember"), dlgType::OnMemberChange) + EVT_BUTTON(XRCID("btnRemoveMember"), dlgType::OnMemberRemove) + EVT_BUTTON(XRCID("btnAddBeforeLabel"), dlgType::OnLabelAddBefore) + EVT_BUTTON(XRCID("btnAddAfterLabel"), dlgType::OnLabelAddAfter) + EVT_BUTTON(XRCID("btnRemoveLabel"), dlgType::OnLabelRemove) + EVT_LIST_ITEM_SELECTED(XRCID("lstMembers"), dlgType::OnMemberSelChange) + EVT_LIST_ITEM_SELECTED(XRCID("lstLabels"), dlgType::OnLabelSelChange) + EVT_TEXT(XRCID("cbDatatype"), dlgType::OnSelChangeTyp) + EVT_COMBOBOX(XRCID("cbDatatype"), dlgType::OnSelChangeTyp) + EVT_TEXT(XRCID("txtMembername"), dlgType::OnChangeMember) + EVT_TEXT(XRCID("txtLength"), dlgType::OnSelChangeTypOrLen) + EVT_TEXT(XRCID("txtPrecision"), dlgType::OnSelChangeTypOrLen) + EVT_BUTTON(CTL_ADDPRIV, dlgType::OnAddPriv) + EVT_BUTTON(CTL_DELPRIV, dlgType::OnDelPriv) + EVT_TEXT(XRCID("cbSubtype"), dlgType::OnSubtypeChange) + EVT_COMBOBOX(XRCID("cbSubtype"), dlgType::OnSubtypeChange) + EVT_TEXT(XRCID("txtName"), dlgType::OnNameChange) +#ifdef __WXMAC__ + EVT_SIZE( dlgType::OnChangeSize) +#endif +END_EVENT_TABLE(); + + +dlgProperty *pgTypeFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgType(this, frame, (pgType *)node, (pgSchema *)parent); +} + + +dlgType::dlgType(pgaFactory *f, frmMain *frame, pgType *node, pgSchema *sch) + : dlgTypeProperty(f, frame, wxT("dlgType")) +{ + type = node; + schema = sch; + + seclabelPage = new ctlSeclabelPanel(nbNotebook); + + lstMembers->CreateColumns(0, _("Member"), _("Data type"), _("Collation"), -1); + lstLabels->InsertColumn(0, _("Label"), wxLIST_FORMAT_LEFT, GetClientSize().GetWidth()); + + cbStorage->Append(wxT("PLAIN")); + cbStorage->Append(wxT("MAIN")); + cbStorage->Append(wxT("EXTERNAL")); + cbStorage->Append(wxT("EXTENDED")); + + queriesToBeSplitted = false; + + /* Type Privileges */ + securityChanged = false; + if (node) + connection = node->GetConnection(); + securityPage = new ctlSecurityPanel(nbNotebook, wxT("USAGE"), "U", frame->GetImageList()); + if (connection && connection->BackendMinimumVersion(9, 2) && (!node || node->CanCreate())) + { + // Fetch Groups Information + pgSet *setGrp = connection->ExecuteSet(wxT("SELECT groname FROM pg_group ORDER BY groname")); + + if (setGrp) + { + while (!setGrp->Eof()) + { + groups.Add(setGrp->GetVal(0)); + setGrp->MoveNext(); + } + delete setGrp; + } + + if (node) + { + wxString strAcl = node->GetAcl(); + if (!strAcl.IsEmpty()) + { + wxArrayString aclArray; + strAcl = strAcl.Mid(1, strAcl.Length() - 2); + getArrayFromCommaSeparatedList(strAcl, aclArray); + wxString roleName; + for (unsigned int index = 0; index < aclArray.Count(); index++) + { + wxString strCurrAcl = aclArray[index]; + + /* + * In rare case, we can have ',' (comma) in the user name. + * But, we need to handle them also + */ + if (strCurrAcl.Find(wxChar('=')) == wxNOT_FOUND) + { + // Check it is start of the ACL + if (strCurrAcl[0U] == (wxChar)'"') + roleName = strCurrAcl + wxT(","); + continue; + } + else + strCurrAcl = roleName + strCurrAcl; + + if (strCurrAcl[0U] == (wxChar)'"') + strCurrAcl = strCurrAcl.Mid(1, strCurrAcl.Length() - 1); + roleName = strCurrAcl.BeforeLast('='); + + wxString value = strCurrAcl.Mid(roleName.Length() + 1).BeforeLast('/'); + + int icon = userFactory.GetIconId(); + + if (roleName.Left(6).IsSameAs(wxT("group "), false)) + { + icon = groupFactory.GetIconId(); + roleName = wxT("group ") + qtStrip(roleName.Mid(6)); + } + else if (roleName.IsEmpty()) + { + icon = PGICON_PUBLIC; + roleName = wxT("public"); + } + else + { + roleName = qtStrip(roleName); + for (unsigned int index = 0; index < groups.Count(); index++) + if (roleName == groups[index]) + { + roleName = wxT("group ") + roleName; + icon = groupFactory.GetIconId(); + break; + } + } + + securityPage->lbPrivileges->AppendItem(icon, roleName, value); + currentAcl.Add(roleName + wxT("=") + value); + + // Reset roleName + roleName.Empty(); + } + } + } + } + else + securityPage->Disable(); + +} + + +#ifdef __WXMAC__ +void dlgType::OnChangeSize(wxSizeEvent &ev) +{ + securityPage->lbPrivileges->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 550); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + + +void dlgType::OnChangeMember(wxCommandEvent &ev) +{ + wxString name = txtMembername->GetValue().Strip(wxString::both); + + btnAddMember->Enable( + ((type && connection->BackendMinimumVersion(9, 1)) || !type) + && !name.IsEmpty() + && lstMembers->FindItem(-1, name, false) == -1 + && cbDatatype->GetGuessedSelection() >= 0); + btnChangeMember->Enable( + lstMembers->FindItem(-1, name, false) == lstMembers->GetFirstSelected() + || lstMembers->FindItem(-1, name, false) == -1); +} + +void dlgType::showDefinition(int panel) +{ + pnlDefinitionExtern->Show(false); + pnlDefinitionComposite->Show(false); + pnlDefinitionEnum->Show(false); + pnlDefinitionRange->Show(false); + + switch (panel) + { + case 0: + pnlDefinitionComposite->Show(true); + break; + case 1: + pnlDefinitionEnum->Show(true); + break; + case 2: + pnlDefinitionExtern->Show(true); + break; + case 3: + pnlDefinitionRange->Show(true); + break; + } + + pnlDefinitionComposite->GetParent()->Layout(); + // we don't need to call GetParent()->Layout() for all four panels + // because they all share the same parent +} + + +void dlgType::OnTypeChange(wxCommandEvent &ev) +{ + showDefinition(rdbType->GetSelection()); + + CheckChange(); +} + + +pgObject *dlgType::GetObject() +{ + return type; +} + + +int dlgType::Go(bool modal) +{ + pgSet *set; + + cbRngCollation->Enable(false); + if (connection->BackendMinimumVersion(9, 2)) + { + securityPage->SetConnection(connection); + + if (securityPage->cbGroups) + { + // Fetch Groups Information + for ( unsigned int index = 0; index < groups.Count();) + securityPage->cbGroups->Append(wxT("group ") + groups[index++]); + + // Fetch Users Information + if (settings->GetShowUsersForPrivileges()) + { + securityPage->stGroup->SetLabel(_("Group/User")); + dlgProperty::AddUsers(securityPage->cbGroups); + } + } + securityPage->lbPrivileges->GetParent()->Layout(); + + // Load the range combox (the 403 opcmethod is btree) + set = connection->ExecuteSet( + wxT("SELECT DISTINCT typ.typname\n") + wxT(" FROM pg_opclass opc\n") + wxT(" JOIN pg_type typ ON opc.opcintype=typ.oid\n") + wxT(" WHERE opc.opcmethod=403\n") + wxT(" ORDER BY typname")); + if (set) + { + while (!set->Eof()) + { + wxString name = qtTypeIdent(set->GetVal(wxT("typname"))); + cbSubtype->Append(name); + set->MoveNext(); + } + delete set; + } + cbSubtype->SetSelection(0); + } + else + { + rdbType->Enable(3, false); + } + + if (connection->BackendMinimumVersion(9, 1)) + { + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(type); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgType::OnChange)); + } + else + seclabelPage->Disable(); + + FillDatatype(cbDatatype, cbElement); + + if (connection->BackendMinimumVersion(9, 1)) + { + // fill collation combobox + cbCollation->Append(wxEmptyString); + cbRngCollation->Append(wxEmptyString); + set = connection->ExecuteSet( + wxT("SELECT nspname, collname\n") + wxT(" FROM pg_collation c, pg_namespace n\n") + wxT(" WHERE c.collnamespace=n.oid\n") + wxT(" ORDER BY nspname, collname")); + if (set) + { + while (!set->Eof()) + { + wxString name = qtIdent(set->GetVal(wxT("nspname"))) + wxT(".") + qtIdent(set->GetVal(wxT("collname"))); + cbCollation->Append(name); + cbRngCollation->Append(name); + set->MoveNext(); + } + delete set; + } + cbCollation->SetSelection(0); + cbRngCollation->SetSelection(0); + } + + if (type) + { + // Edit Mode + cbSchema->Enable(connection->BackendMinimumVersion(8, 1)); + txtName->Enable(connection->BackendMinimumVersion(8, 4)); + rdbType->SetSelection(type->GetTypeClass()); + rdbType->Disable(); + + showDefinition(type->GetTypeClass()); + + cbInput->Append(type->GetInputFunction()); + cbInput->SetSelection(0); + cbInput->Disable(); + cbOutput->Append(type->GetOutputFunction()); + cbOutput->SetSelection(0); + cbOutput->Disable(); + cbReceive->Append(type->GetReceiveFunction()); + cbReceive->SetSelection(0); + cbReceive->Disable(); + cbSend->Append(type->GetSendFunction()); + cbSend->SetSelection(0); + cbSend->Disable(); + cbTypmodin->Append(type->GetTypmodinFunction()); + cbTypmodin->SetSelection(0); + cbTypmodin->Disable(); + cbTypmodout->Append(type->GetTypmodoutFunction()); + cbTypmodout->SetSelection(0); + cbTypmodout->Disable(); + cbAnalyze->Append(type->GetAnalyzeFunction()); + cbAnalyze->SetSelection(0); + cbAnalyze->Disable(); + cbCategory->Append(catGetText(type->GetCategory())); + cbCategory->SetSelection(0); + cbCategory->Disable(); + chkPrefered->SetValue(type->GetPrefered()); + chkPrefered->Disable(); + + chkVariable->SetValue(type->GetInternalLength() < 0); + chkVariable->Disable(); + if (type->GetInternalLength() > 0) + txtIntLength->SetValue(NumToStr(type->GetInternalLength())); + txtIntLength->Disable(); + txtDefault->SetValue(type->GetDefault()); + txtDefault->Disable(); + cbElement->Append(type->GetElement()); + cbElement->SetSelection(0); + cbElement->Disable(); + txtDelimiter->SetValue(type->GetDelimiter()); + txtDelimiter->Disable(); + chkByValue->SetValue(type->GetPassedByValue()); + chkByValue->Disable(); + cbAlignment->SetValue(type->GetAlignment()); + cbAlignment->Disable(); + cbStorage->SetValue(type->GetStorage()); + cbStorage->Disable(); + chkCollatable->SetValue(type->GetCollatable()); + chkCollatable->Disable(); + + bool changeok = connection->BackendMinimumVersion(9, 1); + txtMembername->Enable(changeok); + cbCollation->Enable(changeok); + btnAddMember->Enable(false); + btnChangeMember->Enable(false); + btnRemoveMember->Enable(false); + + txtLabel->Enable(connection->BackendMinimumVersion(9, 1)); + btnAddBeforeLabel->Enable(connection->BackendMinimumVersion(9, 1)); + btnAddAfterLabel->Enable(connection->BackendMinimumVersion(9, 1)); + btnRemoveLabel->Disable(); + + wxArrayString elements = type->GetTypesArray(); + wxString fullType, typeName, typeLength, typePrecision; + size_t pos; + size_t i; + for (i = 0 ; i < elements.GetCount() ; i += 3) + { + lstMembers->AppendItem(0, elements.Item(i), elements.Item(i + 1), elements.Item(i + 2)); + + fullType = elements.Item(i + 1); + typeName = fullType; + typeLength = wxEmptyString; + typePrecision = wxEmptyString; + + if (fullType.Find(wxT("(")) > 0) + { + // there is at least a length + typeName = fullType.BeforeFirst('('); + if (fullType.Find(wxT(",")) > 0) + { + // there is also a precision + typeLength = fullType.AfterFirst('(').BeforeFirst(','); + typePrecision = fullType.AfterFirst(',').BeforeFirst(')'); + } + else + typeLength = fullType.AfterFirst('(').BeforeFirst(')'); + } + + for (pos = 0; pos < cbDatatype->GetCount() - 1; pos++) + { + if (cbDatatype->GetString(pos) == typeName) + { + memberTypes.Add(GetTypeInfo(pos)); + break; + } + } + memberLengths.Add(typeLength); + memberPrecisions.Add(typePrecision); + memberCollations.Add(elements.Item(i + 2)); + memberOriginalNames.Add(elements.Item(i)); + } + + cbDatatype->Enable(changeok); + txtLength->Enable(changeok); + + // Load the enum labels + elements = type->GetLabelArray(); + for (i = 0 ; i < elements.GetCount() ; i++) + lstLabels->AppendItem(0, elements.Item(i)); + + // Load the RANGE informations + cbSubtype->SetValue(type->GetSubtypeFunctionStr()); + cbSubtype->Disable(); + cbSubtypeOpclass->Append(type->GetSubtypeOpClassFunctionStr()); + cbSubtypeOpclass->SetSelection(0); + cbSubtypeOpclass->Disable(); + cbRngCollation->Append(type->GetCollationFunctionStr()); + cbRngCollation->SetSelection(0); + cbRngCollation->Disable(); + cbCanonical->Append(type->GetCanonical()); + cbCanonical->SetSelection(0); + cbCanonical->Disable(); + cbSubtypeDiff->Append(type->GetSubtypeDiff()); + cbSubtypeDiff->SetSelection(0); + cbSubtypeDiff->Disable(); + + if (!connection->BackendMinimumVersion(7, 5)) + cbOwner->Disable(); + } + else + { + // Create mode + cbOwner->Disable(); + + bool hasSendRcv = connection->BackendMinimumVersion(7, 4); + bool hasTypmod = connection->BackendMinimumVersion(8, 3); + + cbCategory->Enable(connection->BackendMinimumVersion(8, 4)); + chkPrefered->Enable(connection->BackendMinimumVersion(8, 4)); + + if (hasSendRcv) + { + cbReceive->Append(wxEmptyString); + cbSend->Append(wxEmptyString); + cbAnalyze->Append(wxEmptyString); + } + else + { + cbReceive->Disable(); + cbSend->Disable(); + cbAnalyze->Disable(); + } + + if (hasTypmod) + { + cbTypmodin->Append(wxEmptyString); + cbTypmodout->Append(wxEmptyString); + } + else + { + cbTypmodin->Disable(); + cbTypmodout->Disable(); + } + + if (!connection->BackendMinimumVersion(8, 3)) + rdbType->Enable(TYPE_ENUM, false); + + chkCollatable->Enable(connection->BackendMinimumVersion(9, 1)); + cbCollation->Enable(connection->BackendMinimumVersion(9, 1)); + + set = connection->ExecuteSet( + wxT("SELECT proname, nspname\n") + wxT(" FROM (\n") + wxT(" SELECT proname, nspname, max(proargtypes[0]) AS arg0, max(proargtypes[1]) AS arg1\n") + wxT(" FROM pg_proc p\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" GROUP BY proname, nspname\n") + wxT(" HAVING count(proname) = 1 ) AS uniquefunc\n") + wxT(" WHERE arg0 <> 0 AND arg1 = 0")); + + if (set) + { + while (!set->Eof()) + { + wxString pn = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + + cbInput->Append(pn); + cbOutput->Append(pn); + if (hasSendRcv) + { + cbReceive->Append(pn); + cbSend->Append(pn); + cbAnalyze->Append(pn); + } + if (hasTypmod) + { + cbTypmodin->Append(pn); + cbTypmodout->Append(pn); + } + set->MoveNext(); + } + delete set; + } + + if (hasTypmod) + { + set = connection->ExecuteSet( + wxT("SELECT proname, nspname\n") + wxT(" FROM pg_proc p\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE prorettype=(SELECT oid FROM pg_type WHERE typname='int4')") + wxT(" AND proargtypes[0]=(SELECT oid FROM pg_type WHERE typname='_cstring')") + wxT(" AND proargtypes[1] IS NULL") + wxT(" ORDER BY nspname, proname")); + + if (set) + { + while (!set->Eof()) + { + wxString pn = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + + cbTypmodin->Append(pn); + set->MoveNext(); + } + delete set; + } + + set = connection->ExecuteSet( + wxT("SELECT proname, nspname\n") + wxT(" FROM pg_proc p\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE prorettype=(SELECT oid FROM pg_type WHERE typname='cstring')") + wxT(" AND proargtypes[0]=(SELECT oid FROM pg_type WHERE typname='int4')") + wxT(" AND proargtypes[1] IS NULL") + wxT(" ORDER BY nspname, proname")); + + if (set) + { + while (!set->Eof()) + { + wxString pn = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + + cbTypmodout->Append(pn); + set->MoveNext(); + } + delete set; + } + } + } + + txtLength->SetValidator(numericValidator); + + return dlgTypeProperty::Go(modal); +} + + +void dlgType::OnSelChangeTyp(wxCommandEvent &ev) +{ + txtLength->SetValue(wxEmptyString); + txtPrecision->SetValue(wxEmptyString); + cbDatatype->GuessSelection(ev); + cbCollation->SetValue(wxEmptyString); + OnSelChangeTypOrLen(ev); +} + + + +void dlgType::OnNameChange(wxCommandEvent &ev) +{ + wxString qry; + wxString shelltype; + pgSet *set; + + cbCanonical->Clear(); + if (!txtName->GetValue().IsEmpty()) + { + // Grab the shelltype + qry = wxT("SELECT oid FROM pg_type WHERE typname='") + qtIdent(txtName->GetValue()) + wxT("'"); + set = connection->ExecuteSet(qry); + if (set) + { + if (!set->Eof()) + { + shelltype = set->GetVal(wxT("oid")); + } + delete set; + } + + if (!shelltype.IsEmpty()) + { + // Load the canonical functions + qry = wxT("SELECT proname, nspname\n") + wxT(" FROM pg_proc\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE prorettype=") + shelltype + + wxT(" AND proargtypes='") + shelltype + wxT("'\n") + wxT(" ORDER BY proname\n"); + + cbCanonical->Append(wxEmptyString); + set = connection->ExecuteSet(qry); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + cbCanonical->Append(procname); + set->MoveNext(); + } + delete set; + } + cbCanonical->SetSelection(0); + } + } + CheckChange(); +} + + +void dlgType::OnSubtypeChange(wxCommandEvent &ev) +{ + wxString subtypeoid; + cbSubtypeOpclass->Clear(); + cbSubtypeDiff->Clear(); + + if (!cbSubtype->GetValue().IsEmpty()) + { + cbSubtypeOpclass->Append(wxEmptyString); + pgSet *set = connection->ExecuteSet( + wxT("SELECT opc.opcname, opc.opcintype\n") + wxT(" FROM pg_opclass opc\n") + wxT(" JOIN pg_type typ ON opc.opcintype=typ.oid ") + wxT(" AND typ.typname='") + cbSubtype->GetValue() + wxT("'\n") + wxT(" WHERE opc.opcmethod=403\n") + wxT(" ORDER BY opcname")); + if (set) + { + while (!set->Eof()) + { + wxString name = qtIdent(set->GetVal(wxT("opcname"))); + subtypeoid = set->GetVal(wxT("opcintype")); + cbSubtypeOpclass->Append(name); + set->MoveNext(); + } + delete set; + } + cbSubtypeOpclass->SetSelection(0); + + set = connection->ExecuteSet( + wxT("SELECT typcollation FROM pg_type WHERE typname='") + cbSubtype->GetValue() + wxT("'\n")); + if (set) + { + if (!set->Eof()) + { + cbRngCollation->Enable(set->GetLong(wxT("typcollation")) > 0); + } + delete set; + } + else + { + cbRngCollation->Enable(false); + } + + // Load the subtypediff functions (701 is double precision type) + + set = connection->ExecuteSet( + wxT("SELECT proname, nspname\n") + wxT(" FROM pg_proc\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE prorettype=701 ") + wxT(" AND proargtypes='") + subtypeoid + wxT(" ") + subtypeoid + wxT("'\n") + wxT(" ORDER BY proname\n")); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + cbSubtypeDiff->Append(procname); + set->MoveNext(); + } + delete set; + } + } +} + + +void dlgType::OnSelChangeTypOrLen(wxCommandEvent &ev) +{ + if ((type && connection->BackendMinimumVersion(9, 1)) || !type) + { + CheckLenEnable(); + txtLength->Enable(isVarLen); + txtPrecision->Enable(isVarPrec); + cbCollation->Enable(connection->BackendMinimumVersion(9, 1)); + CheckChange(); + OnChangeMember(ev); + } +} + + +void dlgType::CheckChange() +{ + bool enable = true; + + if (rdbType->GetSelection() == TYPE_COMPOSITE) + { + CheckValid(enable, lstMembers->GetItemCount() > 1, _("Please specify at least two members.")); + } + else if (rdbType->GetSelection() == TYPE_ENUM) + { + CheckValid(enable, lstLabels->GetItemCount() >= 1, _("Please specify at least one label.")); + } + else if (rdbType->GetSelection() == TYPE_EXTERNAL) + { + txtLength->Enable(!chkVariable->GetValue()); + CheckValid(enable, cbInput->GetCurrentSelection() >= 0, _("Please specify input conversion function.")); + CheckValid(enable, cbOutput->GetCurrentSelection() >= 0, _("Please specify output conversion function.")); + CheckValid(enable, chkVariable->GetValue() || StrToLong(txtLength->GetValue()) > 0, _("Please specify internal storage length.")); + } + else + { + CheckValid(enable, cbSubtype->GetCurrentSelection() >= 0, _("Please specify subtype function.")); + } + + if (type) + { + enable = enable && (GetName() != type->GetName() + || txtComment->GetValue() != type->GetComment() + || cbSchema->GetValue() != type->GetSchema()->GetName() + || cbOwner->GetValue() != type->GetOwner() + || (rdbType->GetSelection() == TYPE_COMPOSITE && GetSqlForTypes() != wxEmptyString) + || (GetSql().Length() > 0 && connection->BackendMinimumVersion(9, 1))); + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); + } + else + { + wxString name = GetName(); + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, !name.StartsWith(wxT("_")), _("Name may not start with '_'.")); + } + + EnableOK(enable || securityChanged); +} + + +void dlgType::OnMemberSelChange(wxListEvent &ev) +{ + long pos = lstMembers->GetSelection(); + if (pos >= 0) + { + txtMembername->SetValue(lstMembers->GetText(pos)); + cbDatatype->SetValue(memberTypes.Item(pos).AfterFirst(':')); + txtLength->SetValue(memberLengths.Item(pos)); + txtLength->Enable(((type && connection->BackendMinimumVersion(9, 1)) || !type) && !txtLength->GetValue().IsEmpty()); + txtPrecision->SetValue(memberPrecisions.Item(pos)); + txtPrecision->Enable(((type && connection->BackendMinimumVersion(9, 1)) || !type) && !txtPrecision->GetValue().IsEmpty()); + cbCollation->SetValue(memberCollations.Item(pos)); + cbCollation->Enable(connection->BackendMinimumVersion(9, 1)); + btnChangeMember->Enable((type && connection->BackendMinimumVersion(9, 1)) || !type); + btnRemoveMember->Enable((type && connection->BackendMinimumVersion(9, 1)) || !type); + } +} + + +void dlgType::OnMemberAdd(wxCommandEvent &ev) +{ + wxString name = txtMembername->GetValue().Strip(wxString::both); + wxString type = cbDatatype->GetValue(); + wxString length = wxEmptyString; + wxString precision = wxEmptyString; + wxString collation = wxEmptyString; + + if (txtLength->GetValue() != wxT("") && txtLength->IsEnabled()) + length = txtLength->GetValue(); + if (txtPrecision->GetValue() != wxT("") && txtPrecision->IsEnabled()) + precision = txtPrecision->GetValue(); + if (cbCollation->GetValue() != wxT("") && cbCollation->IsEnabled()) + collation = cbCollation->GetValue(); + + if (!length.IsEmpty()) + { + type += wxT("(") + length; + if (!precision.IsEmpty()) + type += wxT(",") + precision; + type += wxT(")"); + } + + if (!name.IsEmpty()) + { + size_t pos = lstMembers->GetItemCount(); + lstMembers->InsertItem(pos, name, 0); + lstMembers->SetItem(pos, 1, type); + lstMembers->SetItem(pos, 2, collation); + memberTypes.Add(GetTypeInfo(cbDatatype->GetGuessedSelection())); + memberLengths.Add(length); + memberPrecisions.Add(precision); + memberCollations.Add(collation); + memberOriginalNames.Add(wxEmptyString); + } + + CheckChange(); +} + + +void dlgType::OnMemberChange(wxCommandEvent &ev) +{ + wxString name = txtMembername->GetValue().Strip(wxString::both); + wxString type = cbDatatype->GetValue(); + wxString length = wxEmptyString; + wxString precision = wxEmptyString; + wxString collation = wxEmptyString; + + if (txtLength->GetValue() != wxT("") && txtLength->IsEnabled()) + length = txtLength->GetValue(); + if (txtPrecision->GetValue() != wxT("") && txtPrecision->IsEnabled()) + precision = txtPrecision->GetValue(); + if (cbCollation->GetValue() != wxT("") && cbCollation->IsEnabled()) + collation = cbCollation->GetValue(); + + if (!length.IsEmpty()) + { + type += wxT("(") + length; + if (!precision.IsEmpty()) + type += wxT(",") + precision; + type += wxT(")"); + } + + if (!name.IsEmpty()) + { + long pos = lstMembers->GetFirstSelected(); + if (pos >= 0) + { + lstMembers->SetItem(pos, 0, name); + lstMembers->SetItem(pos, 1, type); + lstMembers->SetItem(pos, 2, collation); + memberTypes.Insert(GetTypeInfo(cbDatatype->GetGuessedSelection()), pos); + memberLengths.Insert(length, pos); + memberPrecisions.Insert(precision, pos); + memberCollations.Insert(collation, pos); + memberTypes.RemoveAt(pos + 1); + memberLengths.RemoveAt(pos + 1); + memberPrecisions.RemoveAt(pos + 1); + memberCollations.RemoveAt(pos + 1); + } + } + + CheckChange(); +} + + +void dlgType::OnMemberRemove(wxCommandEvent &ev) +{ + long pos = lstMembers->GetSelection(); + + if (pos >= 0) + { + lstMembers->DeleteItem(pos); + memberTypes.RemoveAt(pos); + memberLengths.RemoveAt(pos); + memberPrecisions.RemoveAt(pos); + memberCollations.RemoveAt(pos); + memberOriginalNames.RemoveAt(pos); + } + CheckChange(); +} + + +void dlgType::OnLabelSelChange(wxListEvent &ev) +{ + long pos = lstLabels->GetSelection(); + if (pos >= 0) + { + txtLabel->SetValue(lstLabels->GetText(pos)); + } +} + + +void dlgType::OnLabelAddBefore(wxCommandEvent &ev) +{ + wxString label = txtLabel->GetValue().Strip(wxString::both); + + if (!label.IsEmpty()) + { + long pos = lstLabels->FindItem(-1, label); + if (pos < 0) + { + if (lstLabels->GetFirstSelected() >= 0) + pos = lstLabels->GetFirstSelected(); + else + pos = 0; + lstLabels->InsertItem(pos, label, 0); + } + } + txtLabel->SetValue(wxEmptyString); + CheckChange(); +} + + +void dlgType::OnLabelAddAfter(wxCommandEvent &ev) +{ + wxString label = txtLabel->GetValue().Strip(wxString::both); + + if (!label.IsEmpty()) + { + long pos = lstLabels->FindItem(-1, label); + if (pos < 0) + { + if (lstLabels->GetFirstSelected() >= 0) + pos = lstLabels->GetFirstSelected() + 1; + else + pos = lstLabels->GetItemCount(); + lstLabels->InsertItem(pos, label, 0); + } + } + txtLabel->SetValue(wxEmptyString); + CheckChange(); +} + + +void dlgType::OnLabelRemove(wxCommandEvent &ev) +{ + long pos = lstLabels->GetSelection(); + + if (pos >= 0) + lstLabels->DeleteItem(pos); + + CheckChange(); +} + + +pgObject *dlgType::CreateObject(pgCollection *collection) +{ + pgObject *obj = 0; //pgType::ReadObjects(collection, 0, wxT("\n WHERE usename=") + qtDbString(name)); + return obj; +} + + +wxString dlgType::GetSql() +{ + wxString sql, direction, objname; + size_t existingitems_index, listitems_index, offset; + + if (type) + { + // Edit Mode + objname = schema->GetQuotedPrefix() + qtIdent(GetName()); + AppendNameChange(sql, wxT("TYPE ") + type->GetQuotedFullIdentifier()); + AppendOwnerChange(sql, wxT("TYPE ") + objname); + + sql += GetSqlForTypes(); + if (rdbType->GetSelection() == TYPE_ENUM && connection->BackendMinimumVersion(9, 1)) + { + wxArrayString elements = type->GetLabelArray(); + existingitems_index = 0; + for (listitems_index = 0 ; listitems_index < (size_t)lstLabels->GetItemCount() ; listitems_index++) + { + if (existingitems_index >= elements.GetCount() || lstLabels->GetItemText(listitems_index) != elements.Item(existingitems_index)) + { + queriesToBeSplitted = true; + if (listitems_index == 0) + { + direction = wxT("BEFORE"); + offset = 0; + } + else + { + direction = wxT("AFTER"); + offset = -1; + } + + sql += wxT("ALTER TYPE ") + objname + + wxT("\n ADD VALUE ") + connection->qtDbString(lstLabels->GetItemText(listitems_index)) + + wxT(" ") + direction + wxT(" ") + + connection->qtDbString(elements.Item(existingitems_index + offset)) + + wxT(";\n"); + } + else + existingitems_index++; + } + } + AppendSchemaChange(sql, wxT("TYPE ") + objname); + } + else + { + // Create Mode + sql = wxT("CREATE TYPE ") + schema->GetQuotedPrefix() + qtIdent(GetName()); + + if (rdbType->GetSelection() == TYPE_COMPOSITE) + { + sql += wxT(" AS\n ("); + + int i; + for (i = 0 ; i < lstMembers->GetItemCount() ; i++) + { + if (i) + sql += wxT(",\n "); + sql += qtIdent(lstMembers->GetItemText(i)) + wxT(" ") + + GetFullTypeName(i); + } + } + else if (rdbType->GetSelection() == TYPE_ENUM) + { + sql += wxT(" AS ENUM\n ("); + + int i; + for (i = 0 ; i < lstLabels->GetItemCount() ; i++) + { + if (i) + sql += wxT(",\n "); + sql += connection->qtDbString(lstLabels->GetItemText(i)); + } + } + else if (rdbType->GetSelection() == TYPE_EXTERNAL) + { + sql += wxT("\n (INPUT="); + AppendQuoted(sql, cbInput->GetValue()); + sql += wxT(", OUTPUT="); + AppendQuoted(sql, cbOutput->GetValue()); + + if (connection->BackendMinimumVersion(7, 4)) + { + if (cbReceive->GetCurrentSelection() > 0 || cbSend->GetCurrentSelection() > 0) + { + if (cbReceive->GetCurrentSelection() > 0) + { + sql += wxT(",\n RECEIVE="); + AppendQuoted(sql, cbReceive->GetValue()); + if (cbSend->GetCurrentSelection() > 0) + { + sql += wxT(", SEND="); + AppendQuoted(sql, cbSend->GetValue()); + } + } + else + { + sql += wxT(",\n SEND="); + AppendQuoted(sql, cbSend->GetValue()); + } + } + if (cbAnalyze->GetCurrentSelection() > 0) + { + sql += wxT(",\n ANALYZE="); + AppendQuoted(sql, cbAnalyze->GetValue()); + } + + } + if (connection->BackendMinimumVersion(8, 3)) + { + if (cbTypmodin->GetCurrentSelection() > 0 || cbTypmodout->GetCurrentSelection() > 0) + { + if (cbTypmodin->GetCurrentSelection() > 0) + { + sql += wxT(",\n TYPMOD_IN="); + AppendQuoted(sql, cbTypmodin->GetValue()); + if (cbTypmodout->GetCurrentSelection() > 0) + { + sql += wxT(", TYPMOD_OUT="); + AppendQuoted(sql, cbTypmodout->GetValue()); + } + } + else + { + sql += wxT(",\n TYPMOD_OUT="); + AppendQuoted(sql, cbTypmodout->GetValue()); + } + } + + } + if (connection->BackendMinimumVersion(8, 4)) + { + sql += wxT(",\n CATEGORY=") + qtDbString(cbCategory->GetValue()); + if (chkPrefered->GetValue()) + sql += wxT(",\n PREFERRED=true"); + } + sql += wxT(",\n INTERNALLENGTH="); + if (chkVariable->GetValue()) + sql += wxT("VARIABLE"); + else + sql += txtLength->GetValue(); + AppendIfFilled(sql, wxT(",\n DEFAULT="), txtDefault->GetValue()); + if (!cbElement->GetValue().IsEmpty()) + { + sql += wxT(",\n ELEMENT="); + AppendQuoted(sql, cbElement->GetValue()); + AppendIfFilled(sql, wxT(", DELIMITER="), qtDbString(txtDelimiter->GetValue().Strip(wxString::both))); + } + if (chkByValue->GetValue()) + sql += wxT(",\n PASSEDBYVALUE"); + AppendIfFilled(sql, wxT(",\n ALIGNMENT="), cbAlignment->GetValue()); + AppendIfFilled(sql, wxT(",\n STORAGE="), cbStorage->GetValue()); + if (connection->BackendMinimumVersion(9, 1) && chkCollatable->GetValue()) + sql += wxT(",\n COLLATABLE=true"); + } + else + { + sql += wxT(" AS RANGE\n (SUBTYPE="); + AppendQuoted(sql, cbSubtype->GetValue()); + if (!cbSubtypeOpclass->GetValue().IsEmpty()) + { + sql += wxT(", SUBTYPE_OPCLASS="); + AppendQuoted(sql, cbSubtypeOpclass->GetValue()); + } + if (!cbRngCollation->GetValue().IsEmpty()) + { + sql += wxT(", COLLATION=") + cbRngCollation->GetValue(); + } + if (!cbCanonical->GetValue().IsEmpty()) + { + sql += wxT(", CANONICAL="); + AppendQuoted(sql, cbCanonical->GetValue()); + } + if (!cbSubtypeDiff->GetValue().IsEmpty()) + { + sql += wxT(", SUBTYPE_DIFF="); + AppendQuoted(sql, cbSubtypeDiff->GetValue()); + } + } + + sql += wxT(");\n"); + } + AppendComment(sql, wxT("TYPE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), type); + + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + sql += seclabelPage->GetSqlForSecLabels(wxT("TYPE"), qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName())); + + // securityPage will exists only for PG 9.2 and later + if (connection->BackendMinimumVersion(9, 2)) + sql += securityPage->GetGrant(wxT("U"), wxT("TYPE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), ¤tAcl); + return sql; +} + +wxString dlgType::GetFullTypeName(int type) +{ + wxString typname = memberTypes.Item(type).AfterFirst(':'); + + if (!memberLengths.Item(type).IsEmpty()) + { + typname += wxT("(") + memberLengths.Item(type); + if (!memberPrecisions.Item(type).IsEmpty()) + typname += wxT(",") + memberPrecisions.Item(type); + typname += wxT(")"); + } + if (!memberCollations.Item(type).IsEmpty() && memberCollations.Item(type) != wxT("pg_catalog.\"default\"")) + typname += wxT(" COLLATE ") + memberCollations.Item(type); + + return typname; +} + +wxString dlgType::GetSqlForTypes() +{ + wxString sql = wxEmptyString; + wxString objname, old_name, old_type, old_collation, new_name, new_type, new_full_type, new_collation, original_name; + wxArrayString elements = type->GetTypesArray(); + int newindex; + unsigned int oldindex = 0; + int hold = 0; + objname = schema->GetQuotedPrefix() + qtIdent(GetName()); + + for (newindex = 0 ; newindex < lstMembers->GetItemCount() ; newindex = newindex + 1 - hold) + { + // this will decide whether we progress to the next new item, + // or whether we need to continue checking the old list first + hold = 0; + + // these are a copy of the list before any changes + if (elements.GetCount() >= (oldindex * 3) + 3) + { + old_name = elements.Item(oldindex * 3); + old_type = elements.Item(oldindex * 3 + 1); + old_collation = elements.Item(oldindex * 3 + 2); + } + else + { + // we've now used up all the old attributes + old_name = wxEmptyString; + old_type = wxEmptyString; + old_collation = wxEmptyString; + } + + // this is the original name of the type before editing + original_name = memberOriginalNames.Item(newindex); + + new_name = lstMembers->GetItemText(newindex); + new_type = memberTypes.Item(newindex).AfterFirst(':'); + new_full_type = GetFullTypeName(newindex); + new_collation = memberCollations.Item(newindex); + + if (!original_name.IsEmpty() && original_name == old_name && (new_name != old_name + || new_type != old_type || new_collation != old_collation)) + { + // if this was originally in the list and the name has changed then rename it + + if (new_name != old_name) + { + sql += wxT("ALTER TYPE ") + objname + wxT("\n RENAME ATTRIBUTE ") + + qtIdent(original_name) + wxT(" TO ") + qtIdent(new_name) + wxT(";\n"); + } + + if (new_type != old_type || new_collation != old_collation) + { + sql += wxT("ALTER TYPE ") + objname + wxT("\n ALTER ATTRIBUTE ") + + qtIdent(new_name); + + // the syntax for alter attribute requires that we always specify the type + sql += wxT(" SET DATA TYPE ") + new_type; + + if (new_collation != old_collation) + sql += wxT(" COLLATE ") + new_collation; + + sql += wxT(";\n"); + } + } + else if (!original_name.IsEmpty() && original_name != old_name) + { + // the old attribute isn't in the new list so drop it + + // don't move through new list yet + hold = 1; + + sql += wxT("ALTER TYPE ") + objname + wxT("\n DROP ATTRIBUTE ") + + qtIdent(old_name) + wxT(";\n"); + } + else if (original_name.IsEmpty()) + { + if (!old_name.IsEmpty()) + { + sql += wxT("ALTER TYPE ") + objname + wxT("\n DROP ATTRIBUTE ") + + qtIdent(old_name) + wxT(";\n"); + } + + sql += wxT("ALTER TYPE ") + objname + wxT("\n ADD ATTRIBUTE ") + + qtIdent(new_name) + wxT(" ") + new_full_type + wxT(";\n"); + } + else + { + // do nothing + } + + oldindex++; + + if (newindex + 1 - hold == lstMembers->GetItemCount() && elements.GetCount() >= (oldindex * 3) + 3) + { + // remove remaining old attributes + for (; elements.GetCount() >= (oldindex * 3) + 3; oldindex++) + { + old_name = elements.Item(oldindex * 3); + old_type = elements.Item(oldindex * 3 + 1); + old_collation = elements.Item(oldindex * 3 + 2); + + sql += wxT("ALTER TYPE ") + objname + wxT("\n DROP ATTRIBUTE ") + + qtIdent(old_name) + wxT(";\n"); + } + break; + } + } + + return sql; +} + + +void dlgType::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} + + +void dlgType::OnAddPriv(wxCommandEvent &ev) +{ + securityChanged = true; + CheckChange(); +} + + +void dlgType::OnDelPriv(wxCommandEvent &ev) +{ + securityChanged = true; + CheckChange(); +} + + +wxString dlgType::catGetText(wxString c) +{ + if (c == wxT("A")) + return wxT("Array types"); + if (c == wxT("B")) + return wxT("Boolean types"); + if (c == wxT("C")) + return wxT("Composite types"); + if (c == wxT("D")) + return wxT("Date/time types"); + if (c == wxT("E")) + return wxT("Enum types"); + if (c == wxT("G")) + return wxT("Geometric types"); + if (c == wxT("I")) + return wxT("Network address types"); + if (c == wxT("N")) + return wxT("Numeric types"); + if (c == wxT("P")) + return wxT("Pseudo-types"); + if (c == wxT("S")) + return wxT("String types"); + if (c == wxT("T")) + return wxT("Timespan types"); + if (c == wxT("U")) + return wxT("User-defined types"); + if (c == wxT("V")) + return wxT("Bit-string types"); + if (c == wxT("X")) + return wxT("unknown type"); + return wxEmptyString; +} + + +wxString dlgType::catGetChar(wxString t) +{ + if (t == wxT("Array types")) + return wxT("A"); + if (t == wxT("Boolean types")) + return wxT("B"); + if (t == wxT("Composite types")) + return wxT("C"); + if (t == wxT("Date/time types")) + return wxT("D"); + if (t == wxT("Enum types")) + return wxT("E"); + if (t == wxT("Geometric types")) + return wxT("G"); + if (t == wxT("Network address types")) + return wxT("I"); + if (t == wxT("Numeric types")) + return wxT("N"); + if (t == wxT("Pseudo-types")) + return wxT("P"); + if (t == wxT("String types")) + return wxT("S"); + if (t == wxT("Timespan types")) + return wxT("T"); + if (t == wxT("User-defined types")) + return wxT("U"); + if (t == wxT("Bit-string types")) + return wxT("V"); + if (t == wxT("unknown type")) + return wxT("X"); + return wxEmptyString; +} diff --git a/dlg/dlgUser.cpp b/dlg/dlgUser.cpp new file mode 100644 index 0000000..d70922d --- /dev/null +++ b/dlg/dlgUser.cpp @@ -0,0 +1,571 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgUser.cpp - PostgreSQL User Property +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "utils/misc.h" +#include "dlg/dlgUser.h" +#include "schema/pgUser.h" + + +// pointer to controls +#define txtID CTRL_TEXT("txtID") +#define txtPasswd CTRL_TEXT("txtPasswd") +#define txtRePasswd CTRL_TEXT("txtRePasswd") +#define datValidUntil CTRL_CALENDAR("datValidUntil") +#define timValidUntil CTRL_TIME("timValidUntil") +#define chkCreateDB CTRL_CHECKBOX("chkCreateDB") +#define chkCreateUser CTRL_CHECKBOX("chkCreateUser") + +#define lbGroupsNotIn CTRL_LISTBOX("lbGroupsNotIn") +#define lbGroupsIn CTRL_LISTBOX("lbGroupsIn") +#define btnAddGroup CTRL_BUTTON("btnAddGroup") +#define btnDelGroup CTRL_BUTTON("btnDelGroup") + +#define lstVariables CTRL_LISTVIEW("lstVariables") +#define btnAdd CTRL_BUTTON("wxID_ADD") +#define btnRemove CTRL_BUTTON("wxID_REMOVE") +#define cbVarname CTRL_COMBOBOX2("cbVarname") +#define txtValue CTRL_TEXT("txtValue") +#define chkValue CTRL_CHECKBOX("chkValue") + + + +dlgProperty *pgUserFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgUser(this, frame, (pgUser *)node); +} + + +BEGIN_EVENT_TABLE(dlgUser, dlgProperty) + EVT_CALENDAR_SEL_CHANGED(XRCID("datValidUntil"), dlgUser::OnChangeCal) + EVT_DATE_CHANGED(XRCID("datValidUntil"), dlgUser::OnChangeDate) + EVT_SPIN(XRCID("timValidUntil"), dlgUser::OnChangeSpin) + + EVT_LISTBOX_DCLICK(XRCID("lbGroupsNotIn"), dlgUser::OnGroupAdd) + EVT_LISTBOX_DCLICK(XRCID("lbGroupsIn"), dlgUser::OnGroupRemove) + EVT_TEXT(XRCID("txtPasswd"), dlgUser::OnChangePasswd) + EVT_TEXT(XRCID("txtRePasswd"), dlgUser::OnChangePasswd) + EVT_CHECKBOX(XRCID("chkCreateDB"), dlgUser::OnChange) + EVT_CHECKBOX(XRCID("chkCreateUser"), dlgUser::OnChangeSuperuser) + + EVT_BUTTON(XRCID("btnAddGroup"), dlgUser::OnGroupAdd) + EVT_BUTTON(XRCID("btnDelGroup"), dlgUser::OnGroupRemove) + + EVT_LIST_ITEM_SELECTED(XRCID("lstVariables"), dlgUser::OnVarSelChange) + EVT_BUTTON(wxID_ADD, dlgUser::OnVarAdd) + EVT_BUTTON(wxID_REMOVE, dlgUser::OnVarRemove) + EVT_TEXT(XRCID("cbVarname"), dlgUser::OnVarnameSelChange) + EVT_COMBOBOX(XRCID("cbVarname"), dlgUser::OnVarnameSelChange) +END_EVENT_TABLE(); + + + +dlgUser::dlgUser(pgaFactory *f, frmMain *frame, pgUser *node) + : dlgProperty(f, frame, wxT("dlgUser")) +{ + user = node; + lstVariables->CreateColumns(0, _("Variable"), _("Value"), -1); + btnOK->Disable(); + chkValue->Hide(); +} + + +pgObject *dlgUser::GetObject() +{ + return user; +} + + +int dlgUser::Go(bool modal) +{ + pgSet *set = connection->ExecuteSet(wxT("SELECT groname FROM pg_group")); + if (set) + { + while (!set->Eof()) + { + wxString groupName = set->GetVal(wxT("groname")); + if (user && user->GetGroupsIn().Index(groupName) >= 0) + lbGroupsIn->Append(groupName); + else + lbGroupsNotIn->Append(groupName); + + set->MoveNext(); + } + delete set; + } + + if (connection->BackendMinimumVersion(7, 4)) + set = connection->ExecuteSet(wxT("SELECT name, vartype, min_val, max_val\n") + wxT(" FROM pg_settings WHERE context in ('user', 'superuser')")); + else + set = connection->ExecuteSet(wxT("SELECT name, 'string' as vartype, '' as min_val, '' as max_val FROM pg_settings")); + if (set) + { + while (!set->Eof()) + { + cbVarname->Append(set->GetVal(0)); + varInfo.Add(set->GetVal(wxT("vartype")) + wxT(" ") + + set->GetVal(wxT("min_val")) + wxT(" ") + + set->GetVal(wxT("max_val"))); + set->MoveNext(); + } + delete set; + + cbVarname->SetSelection(0); + SetupVarEditor(0); + } + + if (user) + { + // Edit Mode + readOnly = !user->GetServer()->GetSuperUser(); + + txtID->SetValue(NumToStr(user->GetUserId())); + chkCreateDB->SetValue(user->GetCreateDatabase()); + chkCreateUser->SetValue(user->GetSuperuser()); + if (user->GetAccountExpires().IsValid()) + { + datValidUntil->SetValue(user->GetAccountExpires().GetDateOnly()); + timValidUntil->SetTime(user->GetAccountExpires()); + } + if (!connection->BackendMinimumVersion(7, 4)) + txtName->Disable(); + txtID->Disable(); + + size_t index; + for (index = 0 ; index < user->GetConfigList().GetCount() ; index++) + { + wxString item = user->GetConfigList().Item(index); + lstVariables->AppendItem(0, item.BeforeFirst('='), item.AfterFirst('=')); + } + + timValidUntil->Enable(!readOnly && user->GetAccountExpires().IsValid()); + + if (readOnly) + { + chkCreateDB->Disable(); + chkCreateUser->Disable(); + datValidUntil->Disable(); + timValidUntil->Disable(); + btnAddGroup->Disable(); + btnDelGroup->Disable(); + cbVarname->Disable(); + txtValue->Disable(); + btnRemove->Disable(); + if (connection->GetUser() != user->GetName()) + { + txtPasswd->Disable(); + txtRePasswd->Disable(); + btnAdd->Disable(); + } + else + { + txtPasswd->Enable(); + txtRePasswd->Enable(); + btnAdd->Enable(); + } + } + } + else + { + wxDateTime empty; + datValidUntil->SetValue(empty); + txtID->SetValidator(numericValidator); + timValidUntil->Disable(); + } + + return dlgProperty::Go(modal); +} + + +wxString dlgUser::GetHelpPage() const +{ + if (nbNotebook->GetSelection() == 2) + return wxT("pg/runtime-config"); + return dlgProperty::GetHelpPage(); +} + + +void dlgUser::OnChangeCal(wxCalendarEvent &ev) +{ + bool timEn = ev.GetDate().IsValid(); + timValidUntil->Enable(timEn); + if (!timEn) + timValidUntil->SetTime(wxDefaultDateTime); + else + timValidUntil->SetTime(wxDateTime::Today()); + + CheckChange(); +} + + +void dlgUser::OnChangeDate(wxDateEvent &ev) +{ + bool timEn = ev.GetDate().IsValid(); + timValidUntil->Enable(timEn); + if (!timEn) + timValidUntil->SetTime(wxDefaultDateTime); + else + timValidUntil->SetTime(wxDateTime::Today()); + + CheckChange(); +} + +void dlgUser::OnChangeSpin(wxSpinEvent &ev) +{ + CheckChange(); +} + + +void dlgUser::OnChangeSuperuser(wxCommandEvent &ev) +{ + if (user && user->GetSuperuser() && !chkCreateUser->GetValue()) + { + wxMessageDialog dlg(this, + _("Deleting a superuser might result in unwanted behaviour (e.g. when restoring the database).\nAre you sure?"), + _("Confirm superuser deletion"), + wxICON_EXCLAMATION | wxYES_NO | wxNO_DEFAULT); + if (dlg.ShowModal() != wxID_YES) + { + chkCreateUser->SetValue(true); + return; + } + } + CheckChange(); +} + +void dlgUser::OnChangePasswd(wxCommandEvent &ev) +{ + CheckChange(); +} + +void dlgUser::CheckChange() +{ + bool timEn = datValidUntil->GetValue().IsValid(); + timValidUntil->Enable(timEn); + if (!timEn) + timValidUntil->SetTime(wxDefaultDateTime); + + // Check the passwords match + if (txtPasswd->GetValue() != txtRePasswd->GetValue()) + { + bool enable = true; + CheckValid(enable, false, _("The passwords entered do not match!")); + EnableOK(enable); + return; + } + + if (!user) + { + wxString name = GetName(); + + bool enable = true; + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + EnableOK(enable); + } + else + { + EnableOK(!GetSql().IsEmpty()); + } +} + + +void dlgUser::OnGroupAdd(wxCommandEvent &ev) +{ + if (!readOnly) + { + int pos = lbGroupsNotIn->GetSelection(); + if (pos >= 0) + { + lbGroupsIn->Append(lbGroupsNotIn->GetString(pos)); + lbGroupsNotIn->Delete(pos); + } + CheckChange(); + } +} + + +void dlgUser::OnGroupRemove(wxCommandEvent &ev) +{ + if (!readOnly) + { + int pos = lbGroupsIn->GetSelection(); + if (pos >= 0) + { + lbGroupsNotIn->Append(lbGroupsIn->GetString(pos)); + lbGroupsIn->Delete(pos); + } + CheckChange(); + } +} + + +void dlgUser::OnVarnameSelChange(wxCommandEvent &ev) +{ + int sel = cbVarname->GuessSelection(ev); + + SetupVarEditor(sel); +} + +void dlgUser::SetupVarEditor(int var) +{ + if (var >= 0 && varInfo.Count() > 0) + { + wxStringTokenizer vals(varInfo.Item(var)); + wxString typ = vals.GetNextToken(); + + if (typ == wxT("bool")) + { + txtValue->Hide(); + chkValue->Show(); + } + else + { + chkValue->Hide(); + txtValue->Show(); + if (typ == wxT("string") || typ == wxT("enum")) + txtValue->SetValidator(wxTextValidator()); + else + txtValue->SetValidator(numericValidator); + } + } +} + +void dlgUser::OnVarSelChange(wxListEvent &ev) +{ + long pos = lstVariables->GetSelection(); + if (pos >= 0) + { + wxString value = lstVariables->GetText(pos, 1); + cbVarname->SetValue(lstVariables->GetText(pos)); + + + // We used to raise an OnVarnameSelChange() event here, but + // at this point the combo box hasn't necessarily updated. + int sel = cbVarname->FindString(lstVariables->GetText(pos)); + SetupVarEditor(sel); + + txtValue->SetValue(value); + chkValue->SetValue(value == wxT("on")); + } +} + + + +void dlgUser::OnVarAdd(wxCommandEvent &ev) +{ + wxString name = cbVarname->GetValue(); + wxString value; + if (chkValue->IsShown()) + value = chkValue->GetValue() ? wxT("on") : wxT("off"); + else + value = txtValue->GetValue().Strip(wxString::both); + + if (value.IsEmpty()) + value = wxT("DEFAULT"); + + if (!name.IsEmpty()) + { + long pos = lstVariables->FindItem(-1, name); + if (pos < 0) + { + pos = lstVariables->GetItemCount(); + lstVariables->InsertItem(pos, name, 0); + } + lstVariables->SetItem(pos, 1, value); + } + CheckChange(); +} + + +void dlgUser::OnVarRemove(wxCommandEvent &ev) +{ + if (lstVariables->GetSelection() == wxNOT_FOUND) + return; + lstVariables->DeleteCurrentItem(); + CheckChange(); +} + + +pgObject *dlgUser::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + pgObject *obj = userFactory.CreateObjects(collection, 0, wxT("\n WHERE usename=") + qtDbString(name)); + return obj; +} + + +wxString dlgUser::GetSql() +{ + int pos; + wxString sql; + wxString name = GetName(); + + wxString passwd = txtPasswd->GetValue(); + bool createDB = chkCreateDB->GetValue(), + createUser = chkCreateUser->GetValue(); + + if (user) + { + // Edit Mode + + AppendNameChange(sql); + + + wxString options; + if (!passwd.IsEmpty()) + options += wxT(" ENCRYPTED PASSWORD ") + qtDbString(connection->EncryptPassword(name, passwd)); + + if (createDB != user->GetCreateDatabase() || createUser != user->GetSuperuser()) + options += wxT("\n "); + + if (createDB != user->GetCreateDatabase()) + { + if (createDB) + options += wxT(" CREATEDB"); + else + options += wxT(" NOCREATEDB"); + } + if (createUser != user->GetSuperuser()) + { + if (createUser) + options += wxT(" CREATEUSER"); + else + options += wxT(" NOCREATEUSER"); + } + + if (!datValidUntil->GetValue().IsValid() || DateToStr(datValidUntil->GetValue()) != DateToStr(user->GetAccountExpires())) + { + if (datValidUntil->GetValue().IsValid()) + options += wxT("\n VALID UNTIL ") + qtDbString(DateToAnsiStr(datValidUntil->GetValue() + timValidUntil->GetValue())); + else + options += wxT("\n VALID UNTIL 'infinity'"); + } + + if (!options.IsNull()) + sql += wxT("ALTER USER ") + qtIdent(name) + options + wxT(";\n"); + + int cnt = lbGroupsIn->GetCount(); + wxArrayString tmpGroups = user->GetGroupsIn(); + + // check for added groups + for (pos = 0 ; pos < cnt ; pos++) + { + wxString groupName = lbGroupsIn->GetString(pos); + + int index = tmpGroups.Index(groupName); + if (index >= 0) + tmpGroups.RemoveAt(index); + else + sql += wxT("ALTER GROUP ") + qtIdent(groupName) + + wxT("\n ADD USER ") + qtIdent(name) + wxT(";\n"); + } + + // check for removed groups + for (pos = 0 ; pos < (int)tmpGroups.GetCount() ; pos++) + { + sql += wxT("ALTER GROUP ") + qtIdent(tmpGroups.Item(pos)) + + wxT("\n DROP USER ") + qtIdent(name) + wxT(";\n"); + } + } + else + { + // Create Mode + + long id = StrToLong(txtID->GetValue()); + + sql = wxT( + "CREATE USER ") + qtIdent(name); + if (id) + sql += wxT("\n WITH SYSID ") + NumToStr(id); + if (!passwd.IsEmpty()) + sql += wxT(" ENCRYPTED PASSWORD ") + qtDbString(connection->EncryptPassword(name, passwd)); + + if (createDB || createUser) + sql += wxT("\n "); + if (createDB) + sql += wxT(" CREATEDB"); + if (createUser) + sql += wxT(" CREATEUSER"); + if (datValidUntil->GetValue().IsValid()) + sql += wxT("\n VALID UNTIL ") + qtDbString(DateToAnsiStr(datValidUntil->GetValue() + timValidUntil->GetValue())); + else + sql += wxT("\n VALID UNTIL 'infinity'"); + sql += wxT(";\n"); + + int cnt = lbGroupsIn->GetCount(); + for (pos = 0 ; pos < cnt ; pos++) + sql += wxT("ALTER GROUP ") + qtIdent(lbGroupsIn->GetString(pos)) + + wxT("\n ADD USER ") + qtIdent(name) + wxT(";\n"); + } + + wxArrayString vars; + size_t index; + + if (user) + { + for (index = 0 ; index < user->GetConfigList().GetCount() ; index++) + vars.Add(user->GetConfigList().Item(index)); + } + + int cnt = lstVariables->GetItemCount(); + + // check for changed or added vars + for (pos = 0 ; pos < cnt ; pos++) + { + wxString newVar = lstVariables->GetText(pos); + wxString newVal = lstVariables->GetText(pos, 1); + + wxString oldVal; + + for (index = 0 ; index < vars.GetCount() ; index++) + { + wxString var = vars.Item(index); + if (var.BeforeFirst('=').IsSameAs(newVar, false)) + { + oldVal = var.Mid(newVar.Length() + 1); + vars.RemoveAt(index); + break; + } + } + if (oldVal != newVal) + { + if (newVar != wxT("search_path") && newVar != wxT("temp_tablespaces")) + sql += wxT("ALTER USER ") + qtIdent(name) + + wxT("\n SET ") + newVar + + wxT("='") + newVal + + wxT("';\n"); + else + sql += wxT("ALTER USER ") + qtIdent(name) + + wxT("\n SET ") + newVar + + wxT("=") + newVal + + wxT(";\n"); + } + } + + // check for removed vars + for (pos = 0 ; pos < (int)vars.GetCount() ; pos++) + { + sql += wxT("ALTER USER ") + qtIdent(name) + + wxT("\n RESET ") + vars.Item(pos).BeforeFirst('=') + + wxT(";\n"); + } + + return sql; +} + + diff --git a/dlg/dlgUserMapping.cpp b/dlg/dlgUserMapping.cpp new file mode 100644 index 0000000..ccd90e9 --- /dev/null +++ b/dlg/dlgUserMapping.cpp @@ -0,0 +1,319 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgUserMapping.cpp - PostgreSQL User Mapping Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgUserMapping.h" +#include "schema/pgUserMapping.h" + + +// pointer to controls +#define cbUser CTRL_COMBOBOX("cbUser") +#define lstOptions CTRL_LISTVIEW("lstOptions") +#define txtOption CTRL_TEXT("txtOption") +#define txtValue CTRL_TEXT("txtValue") +#define btnAdd CTRL_BUTTON("wxID_ADD") +#define btnRemove CTRL_BUTTON("wxID_REMOVE") + + +dlgProperty *pgUserMappingFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgUserMapping(this, frame, (pgUserMapping *)node, (pgForeignServer *)parent); +} + + +BEGIN_EVENT_TABLE(dlgUserMapping, dlgProperty) + EVT_TEXT(XRCID("cbUser"), dlgUserMapping::OnChange) + EVT_COMBOBOX(XRCID("cbUser"), dlgUserMapping::OnChange) + EVT_LIST_ITEM_SELECTED(XRCID("lstOptions"), dlgUserMapping::OnSelChangeOption) + EVT_TEXT(XRCID("txtOption"), dlgUserMapping::OnChangeOptionName) + EVT_BUTTON(wxID_ADD, dlgUserMapping::OnAddOption) + EVT_BUTTON(wxID_REMOVE, dlgUserMapping::OnRemoveOption) +END_EVENT_TABLE(); + + +dlgUserMapping::dlgUserMapping(pgaFactory *f, frmMain *frame, pgUserMapping *node, pgForeignServer *parent) + : dlgProperty(f, frame, wxT("dlgUserMapping")) +{ + foreignserver = parent; + usermapping = node; +} + + +pgObject *dlgUserMapping::GetObject() +{ + return usermapping; +} + + +int dlgUserMapping::Go(bool modal) +{ + // Fill user combobox + cbUser->Append(wxT("CURRENT_USER")); + cbUser->Append(wxT("PUBLIC")); + pgSet *set = connection->ExecuteSet( + wxT("SELECT rolname\n") + wxT(" FROM pg_roles\n") + wxT(" ORDER BY rolname")); + if (set) + { + while (!set->Eof()) + { + wxString rolname = set->GetVal(wxT("rolname")); + cbUser->Append(rolname); + set->MoveNext(); + } + delete set; + } + cbUser->SetSelection(0); + + // Initialize options listview and buttons + lstOptions->AddColumn(_("Option"), 80); + lstOptions->AddColumn(_("Value"), 40); + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnAdd->Disable(); + btnRemove->Disable(); + + if (usermapping) + { + // edit mode + cbUser->SetValue(usermapping->GetUsr()); + cbUser->Disable(); + + wxString options = usermapping->GetOptions(); + wxString option, optionname, optionvalue; + while (options.Length() > 0) + { + option = options.BeforeFirst(','); + optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim(); + optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim(); + lstOptions->AppendItem(optionname, optionvalue); + options = options.AfterFirst(','); + } + } + else + { + // create mode + } + + txtComment->Disable(); + + return dlgProperty::Go(modal); +} + + +pgObject *dlgUserMapping::CreateObject(pgCollection *collection) +{ + pgObject *obj = userMappingFactory.CreateObjects(collection, 0, wxT("\n AND true")); //srvname ILIKE ") + qtDbString(name)); + return obj; +} + + +void dlgUserMapping::CheckChange() +{ + bool didChange = true; + if (usermapping) + { + didChange = GetOptionsSql().Length() > 0; + EnableOK(didChange); + } + else + { + bool enable = true; + + CheckValid(enable, !cbUser->GetValue().IsEmpty(), _("Please specify user.")); + EnableOK(enable); + } +} + + + +void dlgUserMapping::OnChange(wxCommandEvent &ev) +{ + CheckChange(); +} + + +void dlgUserMapping::OnChangeOptionName(wxCommandEvent &ev) +{ + btnAdd->Enable(txtOption->GetValue().Length() > 0); +} + + +void dlgUserMapping::OnSelChangeOption(wxListEvent &ev) +{ + int row = lstOptions->GetSelection(); + if (row >= 0) + { + txtOption->SetValue(lstOptions->GetText(row, 0)); + txtValue->SetValue(lstOptions->GetText(row, 1)); + } + + btnRemove->Enable(row >= 0); +} + + +void dlgUserMapping::OnAddOption(wxCommandEvent &ev) +{ + bool found = false; + + for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + if (lstOptions->GetText(pos).IsSameAs(txtOption->GetValue(), false)) + { + lstOptions->SetItem(pos, 1, txtValue->GetValue()); + found = true; + break; + } + } + + if (!found) + { + lstOptions->AppendItem(txtOption->GetValue(), txtValue->GetValue()); + } + + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnAdd->Disable(); + + CheckChange(); +} + + +void dlgUserMapping::OnRemoveOption(wxCommandEvent &ev) +{ + int sel = lstOptions->GetSelection(); + lstOptions->DeleteItem(sel); + + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnRemove->Disable(); + + CheckChange(); +} + + +wxString dlgUserMapping::GetOptionsSql() +{ + wxString options = usermapping->GetOptions(); + wxString option, optionname, optionvalue, sqloptions; + bool found; + int pos; + + while (options.Length() > 0) + { + option = options.BeforeFirst(','); + optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim(); + optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim(); + + // check for options + found = false; + for (pos = 0 ; pos < lstOptions->GetItemCount() && !found; pos++) + { + found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0; + if (found) break; + } + + if (found) + { + if (lstOptions->GetText(pos, 1).Cmp(optionvalue) != 0) + { + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += wxT("SET ") + optionname + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("'"); + } + } + else + { + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += wxT("DROP ") + optionname; + } + + options = options.AfterFirst(','); + } + + for (pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + options = usermapping->GetOptions(); + found = false; + + while (options.Length() > 0 && !found) + { + option = options.BeforeFirst(','); + optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim(); + found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0; + options = options.AfterFirst(','); + } + + if (!found) + { + optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim(); + + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += wxT("ADD ") + lstOptions->GetText(pos, 0) + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("'"); + } + } + + return sqloptions; +} + + +wxString dlgUserMapping::GetSql() +{ + wxString sql; + + if (usermapping) + { + // edit mode + wxString sqloptions = GetOptionsSql(); + if (sqloptions.Length() > 0) + { + sql += wxT("ALTER USER MAPPING FOR ") + usermapping->GetUsr() + wxT(" SERVER ") + qtIdent(foreignserver->GetName()) + + wxT("\n OPTIONS (") + sqloptions + wxT(");\n"); + } + } + else + { + // create mode + sql = wxT("CREATE USER MAPPING FOR ") + cbUser->GetValue() + wxT(" SERVER ") + qtIdent(foreignserver->GetName()); + + // check for options + if (lstOptions->GetItemCount() > 0) + { + wxString options = wxEmptyString; + for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + if (options.Length() > 0) + options += wxT(", "); + + options += lstOptions->GetText(pos, 0) + + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("' "); + } + sql += wxT("\n OPTIONS (") + options + wxT(")"); + } + + sql += wxT(";\n"); + } + + return sql; +} + + + diff --git a/dlg/dlgView.cpp b/dlg/dlgView.cpp new file mode 100644 index 0000000..6d1664a --- /dev/null +++ b/dlg/dlgView.cpp @@ -0,0 +1,1233 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgView.cpp - PostgreSQL View Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "ctl/ctlSQLBox.h" +#include "dlg/dlgView.h" +#include "schema/pgView.h" +#include "schema/pgSchema.h" +#include "ctl/ctlSeclabelPanel.h" + + +// pointer to controls +#define pnlDefinition CTRL_PANEL("pnlDefinition") +#define txtSqlBox CTRL_SQLBOX("txtSqlBox") +#define chkSecurityBarrier CTRL_CHECKBOX("chkSecurityBarrier") + +/* AutoVacuum Settings */ +#define nbVaccum CTRL_NOTEBOOK("nbVacuum") +#define chkCustomVac CTRL_CHECKBOX("chkCustomVac") +#define chkVacEnabled CTRL_CHECKBOX("chkVacEnabled") +#define txtBaseVac CTRL_TEXT("txtBaseVac") +#define stBaseVacCurr CTRL_STATIC("stBaseVacCurr") +#define txtBaseAn CTRL_TEXT("txtBaseAn") +#define stBaseAnCurr CTRL_STATIC("stBaseAnCurr") +#define txtFactorVac CTRL_TEXT("txtFactorVac") +#define stFactorVacCurr CTRL_STATIC("stFactorVacCurr") +#define txtFactorAn CTRL_TEXT("txtFactorAn") +#define stFactorAnCurr CTRL_STATIC("stFactorAnCurr") +#define txtVacDelay CTRL_TEXT("txtVacDelay") +#define stVacDelayCurr CTRL_STATIC("stVacDelayCurr") +#define txtVacLimit CTRL_TEXT("txtVacLimit") +#define stVacLimitCurr CTRL_STATIC("stVacLimitCurr") +#define txtFreezeMinAge CTRL_TEXT("txtFreezeMinAge") +#define stFreezeMinAgeCurr CTRL_STATIC("stFreezeMinAgeCurr") +#define txtFreezeMaxAge CTRL_TEXT("txtFreezeMaxAge") +#define stFreezeMaxAgeCurr CTRL_STATIC("stFreezeMaxAgeCurr") +#define txtFreezeTableAge CTRL_TEXT("txtFreezeTableAge") +#define stFreezeTableAgeCurr CTRL_STATIC("stFreezeTableAgeCurr") + +/* TOAST TABLE AutoVacuum Settings */ +#define chkCustomToastVac CTRL_CHECKBOX("chkCustomToastVac") +#define chkToastVacEnabled CTRL_CHECKBOX("chkToastVacEnabled") +#define txtBaseToastVac CTRL_TEXT("txtBaseToastVac") +#define stBaseToastVacCurr CTRL_STATIC("stBaseToastVacCurr") +#define txtFactorToastVac CTRL_TEXT("txtFactorToastVac") +#define stFactorToastVacCurr CTRL_STATIC("stFactorToastVacCurr") +#define txtToastVacDelay CTRL_TEXT("txtToastVacDelay") +#define stToastVacDelayCurr CTRL_STATIC("stToastVacDelayCurr") +#define txtToastVacLimit CTRL_TEXT("txtToastVacLimit") +#define stToastVacLimitCurr CTRL_STATIC("stToastVacLimitCurr") +#define txtToastFreezeMinAge CTRL_TEXT("txtToastFreezeMinAge") +#define stToastFreezeMinAgeCurr CTRL_STATIC("stToastFreezeMinAgeCurr") +#define txtToastFreezeMaxAge CTRL_TEXT("txtToastFreezeMaxAge") +#define stToastFreezeMaxAgeCurr CTRL_STATIC("stToastFreezeMaxAgeCurr") +#define txtToastFreezeTableAge CTRL_TEXT("txtToastFreezeTableAge") +#define stToastFreezeTableAgeCurr CTRL_STATIC("stToastFreezeTableAgeCurr") + +/* Materialized view Settings */ +#define stMaterializedView CTRL_STATIC("stMaterializedView") +#define chkMaterializedView CTRL_CHECKBOX("chkMaterializedView") +#define stTableSpace CTRL_STATIC("stTableSpace") +#define cboTablespace CTRL_COMBOBOX("cboTablespace") +#define stFillFactor CTRL_STATIC("stFillFactor") +#define txtFillFactor CTRL_TEXT("txtFillFactor") +#define stMatViewWithData CTRL_STATIC("stMatViewWithData") +#define chkMatViewWithData CTRL_CHECKBOX("chkMatViewWithData") +#define stCheckOption CTRL_STATIC("stCheckOption") +#define cbCheckOption CTRL_COMBOBOX("cbCheckOption") + +BEGIN_EVENT_TABLE(dlgView, dlgSecurityProperty) + EVT_STC_MODIFIED(XRCID("txtSqlBox"), dlgProperty::OnChangeStc) + EVT_CHECKBOX(XRCID("chkSecurityBarrier"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbCheckOption"), dlgProperty::OnChange) + + /* Materialized view setting */ + EVT_CHECKBOX(XRCID("chkMaterializedView"), dlgView::OnCheckMaterializedView) + EVT_TEXT(XRCID("txtFillFactor"), dlgView::OnChangeVacuum) + + EVT_COMBOBOX(XRCID("cboTablespace"), dlgView::OnChangeVacuum) + + EVT_CHECKBOX(XRCID("chkMatViewWithData"), dlgProperty::OnChange) + + /* AutoVacuum Settings */ + EVT_CHECKBOX(XRCID("chkCustomVac"), dlgView::OnChangeVacuum) + EVT_CHECKBOX(XRCID("chkVacEnabled"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtBaseVac"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtBaseAn"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtFactorVac"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtFactorAn"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtVacDelay"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtVacLimit"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtFreezeMinAge"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtFreezeMaxAge"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtFreezeTableAge"), dlgView::OnChangeVacuum) + + /* TOAST TABLE AutoVacuum Settings */ + EVT_CHECKBOX(XRCID("chkCustomToastVac"), dlgView::OnChangeVacuum) + EVT_CHECKBOX(XRCID("chkToastVacEnabled"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtBaseToastVac"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtFactorToastVac"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtToastVacDelay"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtToastVacLimit"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtToastFreezeMinAge"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtToastFreezeMaxAge"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtToastFreezeTableAge"), dlgView::OnChangeVacuum) + +END_EVENT_TABLE(); + + +dlgProperty *pgViewFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgView(this, frame, (pgView *)node, (pgSchema *)parent); +} + +dlgView::dlgView(pgaFactory *f, frmMain *frame, pgView *node, pgSchema *sch) + : dlgSecurityProperty(f, frame, node, wxT("dlgView"), wxT("INSERT,SELECT,UPDATE,DELETE,RULE,REFERENCE,TRIGGER"), "arwdRxt") +{ + schema = sch; + view = node; + forceSecurityBarrierChanged = false; + + seclabelPage = new ctlSeclabelPanel(nbNotebook); +} + + +pgObject *dlgView::GetObject() +{ + return view; +} + + +int dlgView::Go(bool modal) +{ + if (connection->BackendMinimumVersion(9, 1)) + { + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(view); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgView::OnChange)); + } + else + seclabelPage->Disable(); + + chkSecurityBarrier->Enable(connection->BackendMinimumVersion(9, 2)); + cbCheckOption->Enable(connection->BackendMinimumVersion(9, 4)); + + if (connection->BackendMinimumVersion(9, 3)) + { + PrepareTablespace(cboTablespace); + } + + if (view) + { + // edit mode + cbSchema->Enable(connection->BackendMinimumVersion(8, 1)); + oldDefinition = view->GetFormattedDefinition(); + txtSqlBox->SetText(oldDefinition); + chkSecurityBarrier->SetValue(view->GetSecurityBarrier() == wxT("true")); + + if ((connection->BackendMinimumVersion(9, 3) && view)) + { + // If it is materialized view than edit it + if (view->GetMaterializedView()) + { + // Checked the view as user is in edit materialized view mode + chkMaterializedView->SetValue(true); + + // Disable the security barrier as user is editing the materailized view + chkSecurityBarrier->Disable(); + + // Disable the check-option as user is editing the materailized view + cbCheckOption->Disable(); + + // Disable the materialized view as user is editing it and not allowed to switch to other view + chkMaterializedView->Disable(); + + if (view->GetTablespaceOid() != 0) + cboTablespace->SetKey(view->GetTablespaceOid()); + + txtFillFactor->SetValue(view->GetFillFactor()); + + if (view->GetIsPopulated().Cmp(wxT("t")) == 0) + chkMatViewWithData->SetValue(true); + else + chkMatViewWithData->SetValue(false); + + settingAutoVacuum = false; + + pgSetIterator avSet(connection, + wxT("SELECT name, setting FROM pg_settings WHERE name like '%vacuum%' ORDER BY name")); + while (avSet.RowsLeft()) + { + wxString name = avSet.GetVal(wxT("name")); + wxString setting = avSet.GetVal(wxT("setting")); + + if (name == wxT("autovacuum_vacuum_cost_delay")) + settingCostDelay = setting; + else if (name == wxT("vacuum_cost_delay")) + { + if (StrToLong(settingCostDelay) < 0) + settingCostDelay = setting; + } + else if (name == wxT("autovacuum_vacuum_cost_limit")) + settingCostLimit = setting; + else if (name == wxT("vacuum_cost_limit")) + { + if (StrToLong(settingCostLimit) < 0) + settingCostLimit = setting; + } + else if (name == wxT("autovacuum_vacuum_scale_factor")) + settingVacFactor = setting; + else if (name == wxT("autovacuum_analyze_scale_factor")) + settingAnlFactor = setting; + else if (name == wxT("autovacuum_vacuum_threshold")) + settingVacBaseThr = setting; + else if (name == wxT("autovacuum_analyze_threshold")) + settingAnlBaseThr = setting; + else if (name == wxT("vacuum_freeze_min_age")) + settingFreezeMinAge = setting; + else if (name == wxT("autovacuum_freeze_max_age")) + settingFreezeMaxAge = setting; + else if (name == wxT("vacuum_freeze_table_age")) + settingFreezeTableAge = setting; + else + settingAutoVacuum = avSet.GetBool(wxT("setting")); + } + + tableVacBaseThr = wxT("-1"); + tableAnlBaseThr = wxT("-1"); + tableCostDelay = wxT("-1"); + tableCostLimit = wxT("-1"); + tableFreezeMinAge = wxT("-1"); + tableFreezeMaxAge = wxT("-1"); + tableVacFactor = wxT("-1"); + tableAnlFactor = wxT("-1"); + tableFreezeTableAge = wxT("-1"); + + toastTableVacBaseThr = wxT("-1"); + toastTableCostDelay = wxT("-1"); + toastTableCostLimit = wxT("-1"); + toastTableFreezeMinAge = wxT("-1"); + toastTableFreezeMaxAge = wxT("-1"); + toastTableVacFactor = wxT("-1"); + toastTableFreezeTableAge = wxT("-1"); + + toastTableHasVacuum = false; + toastTableVacEnabled = false; + + if (view) + { + if (view->GetAutoVacuumEnabled() == 2) + tableVacEnabled = settingAutoVacuum; + else + tableVacEnabled = view->GetAutoVacuumEnabled() == 1; + if (!view->GetAutoVacuumVacuumThreshold().IsEmpty()) + tableVacBaseThr = view->GetAutoVacuumVacuumThreshold(); + if (!view->GetAutoVacuumAnalyzeThreshold().IsEmpty()) + tableAnlBaseThr = view->GetAutoVacuumAnalyzeThreshold(); + if (!view->GetAutoVacuumVacuumScaleFactor().IsEmpty()) + tableVacFactor = view->GetAutoVacuumVacuumScaleFactor(); + if (!view->GetAutoVacuumAnalyzeScaleFactor().IsEmpty()) + tableAnlFactor = view->GetAutoVacuumAnalyzeScaleFactor(); + if (!view->GetAutoVacuumVacuumCostDelay().IsEmpty()) + tableCostDelay = view->GetAutoVacuumVacuumCostDelay(); + if (!view->GetAutoVacuumVacuumCostLimit().IsEmpty()) + tableCostLimit = view->GetAutoVacuumVacuumCostLimit(); + if (!view->GetAutoVacuumFreezeMinAge().IsEmpty()) + tableFreezeMinAge = view->GetAutoVacuumFreezeMinAge(); + if (!view->GetAutoVacuumFreezeMaxAge().IsEmpty()) + tableFreezeMaxAge = view->GetAutoVacuumFreezeMaxAge(); + if (!view->GetAutoVacuumFreezeTableAge().IsEmpty()) + tableFreezeTableAge = view->GetAutoVacuumFreezeTableAge(); + + hasVacuum = view->GetCustomAutoVacuumEnabled(); + chkVacEnabled->SetValue(hasVacuum ? tableVacEnabled : settingAutoVacuum); + + toastTableVacEnabled = false; + + if (!view->GetHasToastTable()) + { + nbVaccum->GetPage(2)->Enable(false); + } + else + { + toastTableHasVacuum = view->GetToastCustomAutoVacuumEnabled(); + if (toastTableHasVacuum) + { + if (view->GetToastAutoVacuumEnabled() == 2) + toastTableVacEnabled = settingAutoVacuum; + else + toastTableVacEnabled = view->GetToastAutoVacuumEnabled() == 1; + if (!view->GetToastAutoVacuumVacuumThreshold().IsEmpty()) + toastTableVacBaseThr = view->GetToastAutoVacuumVacuumThreshold(); + if (!view->GetToastAutoVacuumVacuumScaleFactor().IsEmpty()) + toastTableVacFactor = view->GetToastAutoVacuumVacuumScaleFactor(); + if (!view->GetToastAutoVacuumVacuumCostDelay().IsEmpty()) + toastTableCostDelay = view->GetToastAutoVacuumVacuumCostDelay(); + if (!view->GetToastAutoVacuumVacuumCostLimit().IsEmpty()) + toastTableCostLimit = view->GetToastAutoVacuumVacuumCostLimit(); + if (!view->GetToastAutoVacuumFreezeMinAge().IsEmpty()) + toastTableFreezeMinAge = view->GetToastAutoVacuumFreezeMinAge(); + if (!view->GetToastAutoVacuumFreezeMaxAge().IsEmpty()) + toastTableFreezeMaxAge = view->GetToastAutoVacuumFreezeMaxAge(); + if (!view->GetToastAutoVacuumFreezeTableAge().IsEmpty()) + toastTableFreezeTableAge = view->GetToastAutoVacuumFreezeTableAge(); + } + chkToastVacEnabled->SetValue(toastTableHasVacuum ? toastTableVacEnabled : settingAutoVacuum); + } + } + else + { + hasVacuum = false; + chkVacEnabled->SetValue(settingAutoVacuum); + } + + txtBaseVac->SetValue(tableVacBaseThr); + txtBaseAn->SetValue(tableAnlBaseThr); + txtFactorVac->SetValue(tableVacFactor); + txtFactorAn->SetValue(tableAnlFactor); + txtVacDelay->SetValue(tableCostDelay); + txtVacLimit->SetValue(tableCostLimit); + txtFreezeMinAge->SetValue(tableFreezeMinAge); + txtFreezeMaxAge->SetValue(tableFreezeMaxAge); + + txtFreezeTableAge->SetValue(tableFreezeTableAge); + txtBaseToastVac->SetValue(toastTableVacBaseThr); + txtFactorToastVac->SetValue(toastTableVacFactor); + txtToastVacDelay->SetValue(toastTableCostDelay); + txtToastVacLimit->SetValue(toastTableCostLimit); + txtToastFreezeMinAge->SetValue(toastTableFreezeMinAge); + txtToastFreezeMaxAge->SetValue(toastTableFreezeMaxAge); + txtToastFreezeTableAge->SetValue(toastTableFreezeTableAge); + + chkCustomToastVac->SetValue(toastTableHasVacuum); + chkToastVacEnabled->SetValue(toastTableHasVacuum ? toastTableVacEnabled : settingAutoVacuum); + + chkCustomVac->SetValue(hasVacuum); + wxCommandEvent ev; + OnChangeVacuum(ev); + } + else + { + // It is not materialized view so disabling all the controls + DisableMaterializedView(); + } + + cbCheckOption->SetSelection(GetIndexCheckOption(view->GetCheckOption())); + } + } + else + { + // create mode + cboTablespace->Insert(_(""), 0, (void *)0); + cboTablespace->SetSelection(0); + cbCheckOption->SetSelection(0); + wxCommandEvent ev; + OnChangeVacuum(ev); + } + + // Find, and disable the RULE ACL option if we're 8.2 + if (connection->BackendMinimumVersion(8, 2)) + { + // Disable the checkbox + if (!DisablePrivilege(wxT("RULE"))) + { + wxLogError(_("Failed to disable the RULE privilege checkbox!")); + } + } + + return dlgSecurityProperty::Go(modal); +} + + +pgObject *dlgView::CreateObject(pgCollection *collection) +{ + pgObject *obj = viewFactory.CreateObjects(collection, 0, + wxT("\n AND c.relname=") + qtDbString(txtName->GetValue()) + + wxT("\n AND c.relnamespace=") + schema->GetOidStr()); + return obj; +} + + +void dlgView::CheckChange() +{ + bool enable = true; + wxString name = GetName(); + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, txtSqlBox->GetText().Trim(true).Trim(false).Length() > 0 , _("Please enter function definition.")); + + if (!connection->BackendMinimumVersion(9, 3)) + { + DisableMaterializedView(); + } + + if(enable) + { + if (view) + enable = txtComment->GetValue() != view->GetComment() + || txtSqlBox->GetText().Trim(true).Trim(false) != oldDefinition.Trim(true).Trim(false) + || cbOwner->GetValue() != view->GetOwner() + || cbSchema->GetValue() != view->GetSchema()->GetName() + || name != view->GetName(); + + if (connection->BackendMinimumVersion(9, 3)) + { + enable = !GetSql().IsEmpty(); + } + + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); + + if (connection->BackendMinimumVersion(9, 2)) + { + if (view) + { + if (chkSecurityBarrier->GetValue()) + enable = enable || !(view->GetSecurityBarrier() == wxT("true")); + else + enable = enable || (view->GetSecurityBarrier() == wxT("true")); + } + else + { + enable = enable || (chkSecurityBarrier->GetValue()); + } + } + + if (connection->BackendMinimumVersion(9, 4) && view) + { + enable = enable || (cbCheckOption->GetSelection() != GetIndexCheckOption(view->GetCheckOption())); + } + } + + EnableOK(enable); +} + + +wxString dlgView::GetSql() +{ + wxString sql; + wxString name; + wxString withoptions = wxEmptyString; + bool editQuery = false; + + if (view) + { + // edit mode + name = GetName(); + + if (name != view->GetName()) + { + if (connection->BackendMinimumVersion(8, 3)) + { + if (connection->BackendMinimumVersion(9, 3)) + { + if (view->GetMaterializedView()) + { + AppendNameChange(sql, wxT("MATERIALIZED VIEW ") + view->GetQuotedFullIdentifier()); + editQuery = true; + } + else + AppendNameChange(sql, wxT("VIEW ") + view->GetQuotedFullIdentifier()); + } + else + AppendNameChange(sql, wxT("VIEW ") + view->GetQuotedFullIdentifier()); + } + else + AppendNameChange(sql, wxT("TABLE ") + view->GetQuotedFullIdentifier()); + } + + if (connection->BackendMinimumVersion(8, 4) && cbSchema->GetName() != view->GetSchema()->GetName()) + { + if (connection->BackendMinimumVersion(9, 3)) + { + if (view->GetMaterializedView()) + { + AppendSchemaChange(sql, wxT("MATERIALIZED VIEW " + qtIdent(view->GetSchema()->GetName()) + wxT(".") + qtIdent(name))); + editQuery = true; + } + else + AppendSchemaChange(sql, wxT("VIEW " + qtIdent(view->GetSchema()->GetName()) + wxT(".") + qtIdent(name))); + } + else + AppendSchemaChange(sql, wxT("VIEW " + qtIdent(view->GetSchema()->GetName()) + wxT(".") + qtIdent(name))); + } + else + AppendSchemaChange(sql, wxT("TABLE " + qtIdent(view->GetSchema()->GetName()) + wxT(".") + qtIdent(name))); + } + + name = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()); + if (!view || txtSqlBox->GetText().Trim(true).Trim(false) != oldDefinition.Trim(true).Trim(false)) + { + if (editQuery) + { + // Delete the materialized view query + sql += wxT("DROP MATERIALIZED VIEW ") + name + wxT(";"); + } + + // Check if user creates the materialized view + if (!chkMaterializedView->GetValue()) + { + sql += wxT("CREATE OR REPLACE VIEW ") + name; + + if (connection->BackendMinimumVersion(9, 2) && chkSecurityBarrier->GetValue()) + withoptions += wxT("security_barrier=true"); + if (connection->BackendMinimumVersion(9, 4) && cbCheckOption->GetSelection() > 0) + { + if (withoptions.Length() > 0) + withoptions += wxT(", "); + if (cbCheckOption->GetSelection() == 1) + withoptions += wxT("check_option=local"); + if (cbCheckOption->GetSelection() == 2) + withoptions += wxT("check_option=cascaded"); + } + + if (withoptions.Length() > 0) + sql += wxT(" WITH (") + withoptions + wxT(")"); + + sql += wxT(" AS\n") + + txtSqlBox->GetText().Trim(true).Trim(false) + + wxT(";\n"); + } + else if (connection->BackendMinimumVersion(9, 3) && chkMaterializedView->GetValue()) + { + sql += wxT("CREATE MATERIALIZED VIEW ") + name; + + // Add the parameter of tablespace and storage parameter to create the materilized view + if (txtFillFactor->GetValue().Trim().Length() > 0 || chkVacEnabled->GetValue() == true || chkToastVacEnabled->GetValue() == true) + { + bool fillFactorFlag, toastTableFlag; + fillFactorFlag = false; + toastTableFlag = false; + + sql += wxT("\nWITH ("); + + if (txtFillFactor->GetValue().Trim().Length() > 0) + { + sql += wxT("\n FILLFACTOR = ") + txtFillFactor->GetValue(); + fillFactorFlag = true; + } + + bool valChanged = false; + wxString newVal; + wxString resetStr; + + if (connection->BackendMinimumVersion(9, 3) && chkCustomVac->GetValue()) + { + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_enabled"), BoolToStr(chkVacEnabled->GetValue())); + + if (!fillFactorFlag) + { + int position = sql.Find(',', true); + if (position != wxNOT_FOUND) + sql.Remove(position, 1); + toastTableFlag = true; + } + + newVal = AppendNum(valChanged, txtBaseVac, tableVacBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_vacuum_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtBaseAn, tableAnlBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_analyze_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorVac, tableVacFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_vacuum_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorAn, tableAnlFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_analyze_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtVacDelay, tableCostDelay); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_vacuum_cost_delay"), newVal); + } + + newVal = AppendNum(valChanged, txtVacLimit, tableCostLimit); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_vacuum_cost_limit"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeMinAge, tableFreezeMinAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_freeze_min_age"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeMaxAge, tableFreezeMaxAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_freeze_max_age"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeTableAge, tableFreezeTableAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_freeze_table_age"), newVal); + } + } + + if (connection->BackendMinimumVersion(9, 3) && chkCustomToastVac->GetValue()) + { + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_enabled"), BoolToStr(chkToastVacEnabled->GetValue())); + + if (!fillFactorFlag && !toastTableFlag) + { + int position = sql.Find(',', true); + if (position != wxNOT_FOUND) + sql.Remove(position, 1); + } + + newVal = AppendNum(valChanged, txtBaseToastVac, toastTableVacBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_vacuum_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorToastVac, toastTableVacFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_vacuum_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtToastVacDelay, toastTableCostDelay); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_vacuum_cost_delay"), newVal); + } + + newVal = AppendNum(valChanged, txtToastVacLimit, toastTableCostLimit); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_vacuum_cost_limit"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeMinAge, toastTableFreezeMinAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_freeze_min_age"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeMaxAge, toastTableFreezeMaxAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_freeze_max_age"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeTableAge, toastTableFreezeTableAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_freeze_table_age"), newVal); + } + } + + sql += wxT("\n)\n"); + } + + if (cboTablespace->GetCurrentSelection() > 0 && cboTablespace->GetOIDKey() > 0) + sql += wxT("\nTABLESPACE ") + qtIdent(cboTablespace->GetValue()); + + wxString sqlDefinition; + bool tmpLoopFlag = true; + sqlDefinition = txtSqlBox->GetText().Trim(true).Trim(false); + + // Remove semicolon from the end of the string + while(tmpLoopFlag) + { + int length = sqlDefinition.Len(); + int position = sqlDefinition.Find(';', true); + if ((position != wxNOT_FOUND) && (position = (length - 1))) + sqlDefinition.Remove(position, 1); + else + tmpLoopFlag = false; + } + + sql += wxT(" AS\n") + + sqlDefinition; + + if (chkMatViewWithData->GetValue()) + sql += wxT("\n WITH DATA;\n"); + else + sql += wxT("\n WITH NO DATA;\n"); + } + } + else if (view) + { + if (!chkMaterializedView->GetValue()) + { + if (connection->BackendMinimumVersion(9, 2)) + { + if (chkSecurityBarrier->GetValue() && view->GetSecurityBarrier() != wxT("true")) + sql += wxT("ALTER VIEW ") + name + wxT("\n SET (security_barrier=true);\n"); + else if (!chkSecurityBarrier->GetValue() && view->GetSecurityBarrier() == wxT("true")) + sql += wxT("ALTER VIEW ") + name + wxT("\n SET (security_barrier=false);\n"); + } + + if (connection->BackendMinimumVersion(9, 4) + && cbCheckOption->GetSelection() != GetIndexCheckOption(view->GetCheckOption()) ) + { + if ((cbCheckOption->GetSelection()) == 0) + sql += wxT("ALTER VIEW ") + name + wxT(" RESET (check_option);\n"); + else + { + if (cbCheckOption->GetSelection() == 1) + sql += wxT("ALTER VIEW ") + name + wxT("\n SET (check_option=local") + wxT(");\n"); + if (cbCheckOption->GetSelection() == 2) + sql += wxT("ALTER VIEW ") + name + wxT("\n SET (check_option=cascaded") + wxT(");\n"); + } + } + + if (withoptions.Length() > 0) + sql += wxT(" WITH (") + withoptions + wxT(")"); + } + else if (connection->BackendMinimumVersion(9, 3) && chkMaterializedView->GetValue()) + { + if (txtFillFactor->GetValue() != view->GetFillFactor()) + { + // If fill factor value get changed then set the new value + if (txtFillFactor->GetValue().Trim().Length() > 0) + { + sql += wxT("ALTER MATERIALIZED VIEW ") + name + + wxT("\n SET (FILLFACTOR=") + + txtFillFactor->GetValue() + wxT(");\n"); + } + else + { + // If fill factor value get changed and value is not blank then do the reset + sql += wxT("ALTER MATERIALIZED VIEW ") + name + + wxT(" RESET(\n") + wxT(" FILLFACTOR\n") + wxT(");\n"); + } + } + + bool isPopulatedFlag = false; + + if (view->GetIsPopulated().Cmp(wxT("t")) == 0) + isPopulatedFlag = true; + + if (chkMatViewWithData->GetValue() != isPopulatedFlag) + { + // If checkbox is checked then set WITH NO DATA + if (isPopulatedFlag) + { + sql += wxT("REFRESH MATERIALIZED VIEW ") + name + + wxT(" WITH NO DATA;\n"); + } + else + { + sql += wxT("REFRESH MATERIALIZED VIEW ") + name + + wxT(" WITH DATA;\n"); + } + } + + // Altered the storage parameters for the materialized view? + if (!chkCustomVac->GetValue()) + { + if (hasVacuum) + { + sql += wxT("ALTER MATERIALIZED VIEW ") + name + + wxT(" RESET(\n") + wxT(" autovacuum_enabled,\n") + wxT(" autovacuum_vacuum_threshold,\n") + wxT(" autovacuum_analyze_threshold,\n") + wxT(" autovacuum_vacuum_scale_factor,\n") + wxT(" autovacuum_analyze_scale_factor,\n") + wxT(" autovacuum_vacuum_cost_delay,\n") + wxT(" autovacuum_vacuum_cost_limit,\n") + wxT(" autovacuum_freeze_min_age,\n") + wxT(" autovacuum_freeze_max_age,\n") + wxT(" autovacuum_freeze_table_age\n") + wxT(");\n"); + } + } + else + { + wxString vacStr; + bool changed = (chkVacEnabled->GetValue() != tableVacEnabled); + + bool valChanged = false; + wxString newVal; + wxString setStr; + wxString resetStr; + + if (changed) + { + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_enabled"), BoolToStr(chkVacEnabled->GetValue())); + } + newVal = AppendNum(valChanged, txtBaseVac, tableVacBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_vacuum_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtBaseAn, tableAnlBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_analyze_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorVac, tableVacFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_vacuum_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorAn, tableAnlFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_analyze_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtVacDelay, tableCostDelay); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_vacuum_cost_delay"), newVal); + } + + newVal = AppendNum(valChanged, txtVacLimit, tableCostLimit); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_vacuum_cost_limit"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeMinAge, tableFreezeMinAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_freeze_min_age"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeMaxAge, tableFreezeMaxAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_freeze_max_age"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeTableAge, tableFreezeTableAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_freeze_table_age"), newVal); + } + + if (!setStr.IsEmpty()) + { + vacStr = wxT("ALTER MATERIALIZED VIEW ") + name + setStr + wxT("\n);\n");; + changed = true; + } + if (!resetStr.IsEmpty()) + { + vacStr += wxT("ALTER MATERIALIZED VIEW ") + name + resetStr + wxT("\n);\n");; + changed = true; + } + if (changed) + sql += vacStr; + } + + if (!chkCustomToastVac->GetValue()) + { + if (toastTableHasVacuum) + { + sql += wxT("ALTER MATERIALIZED VIEW ") + name + + wxT(" RESET(\n") + wxT(" toast.autovacuum_enabled,\n") + wxT(" toast.autovacuum_vacuum_threshold,\n") + wxT(" toast.autovacuum_analyze_threshold,\n") + wxT(" toast.autovacuum_vacuum_scale_factor,\n") + wxT(" toast.autovacuum_analyze_scale_factor,\n") + wxT(" toast.autovacuum_vacuum_cost_delay,\n") + wxT(" toast.autovacuum_vacuum_cost_limit,\n") + wxT(" toast.autovacuum_freeze_min_age,\n") + wxT(" toast.autovacuum_freeze_max_age,\n") + wxT(" toast.autovacuum_freeze_table_age\n") + wxT(");\n"); + } + } + else + { + wxString vacStr; + bool changed = (chkToastVacEnabled->GetValue() != toastTableVacEnabled); + bool valChanged = false; + wxString newVal; + wxString setStr; + wxString resetStr; + if (changed) + { + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_enabled"), BoolToStr(chkToastVacEnabled->GetValue())); + } + newVal = AppendNum(valChanged, txtBaseToastVac, toastTableVacBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_vacuum_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorToastVac, toastTableVacFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_vacuum_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtToastVacDelay, toastTableCostDelay); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_vacuum_cost_delay"), newVal); + } + + newVal = AppendNum(valChanged, txtToastVacLimit, toastTableCostLimit); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_vacuum_cost_limit"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeMinAge, toastTableFreezeMinAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_freeze_min_age"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeMaxAge, toastTableFreezeMaxAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_freeze_max_age"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeTableAge, toastTableFreezeTableAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_freeze_table_age"), newVal); + } + + if (!setStr.IsEmpty()) + { + vacStr = wxT("ALTER MATERIALIZED VIEW ") + name + setStr + wxT("\n);\n"); + changed = true; + } + if (!resetStr.IsEmpty()) + { + vacStr += wxT("ALTER MATERIALIZED VIEW ") + name + resetStr + wxT("\n);\n"); + changed = true; + } + if (changed) + sql += vacStr; + } + + if (cboTablespace->GetOIDKey() != view->GetTablespaceOid()) + { + sql += wxT("ALTER MATERIALIZED VIEW ") + name + + wxT("\n SET TABLESPACE ") + qtIdent(cboTablespace->GetValue()) + + wxT(";\n"); + } + } + } + + if (view) + AppendOwnerChange(sql, wxT("TABLE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName())); + else + AppendOwnerNew(sql, wxT("TABLE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName())); + + + sql += GetGrant(wxT("arwdRxt"), wxT("TABLE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName())); + + if (connection->BackendMinimumVersion(9, 3) && chkMaterializedView->GetValue()) + AppendComment(sql, wxT("MATERIALIZED VIEW ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), view); + else + AppendComment(sql, wxT("VIEW ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), view); + + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + sql += seclabelPage->GetSqlForSecLabels(wxT("VIEW"), qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName())); + + return sql; +} + +bool dlgView::IsUpToDate() +{ + if (view && !view->IsUpToDate()) + return false; + else + return true; +} + +void dlgView::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} + +void dlgView::OnCheckMaterializedView(wxCommandEvent &ev) +{ + if (chkMaterializedView->GetValue()) + { + // Security barrier and Check-option, are not applicable to the materialized view + cbCheckOption->Disable(); + if (chkSecurityBarrier->GetValue()) + { + wxMessageBox(_("The security barrier option is not applicable to materialized views and has been turned off."), _("View"), wxICON_EXCLAMATION | wxOK, this); + chkSecurityBarrier->SetValue(false); + chkSecurityBarrier->Disable(); + forceSecurityBarrierChanged = true; + } + else + { + chkSecurityBarrier->Disable(); + } + + cboTablespace->Enable(); + txtFillFactor->Enable(); + chkMatViewWithData->Enable(); + chkCustomVac->Enable(); + chkCustomToastVac->Enable(); + } + else + { + chkSecurityBarrier->Enable(); + cbCheckOption->Enable(); + chkSecurityBarrier->SetValue(forceSecurityBarrierChanged); + forceSecurityBarrierChanged = false; + + DisableStorageParameters(); + } +} + +void dlgView::FillAutoVacuumParameters(wxString &setStr, wxString &resetStr, + const wxString ¶meter, const wxString &val) +{ + if (val == wxT("-1")) + { + if (resetStr.IsEmpty()) + resetStr = wxT(" RESET ("); + else + resetStr += wxT(","); + resetStr += wxT("\n ") + parameter; + } + else + { + if (setStr.IsEmpty()) + setStr = wxT(" SET ("); + else + setStr += wxT(","); + setStr += wxT("\n ") + parameter + wxT(" = ") + val; + } +} + +wxString dlgView::AppendNum(bool &changed, wxTextCtrl *ctl, wxString val) +{ + wxString str = ctl->GetValue(); + if (str.IsEmpty() || str.StartsWith(wxT("-"))) + str = wxT("-1"); + + changed |= (str != val); + return str; +} + +void dlgView::OnChangeVacuum(wxCommandEvent &ev) +{ + if (connection->BackendMinimumVersion(9, 3)) + { + bool vacEn = chkCustomVac->GetValue() && chkVacEnabled->GetValue(); + chkCustomVac->Enable(chkMaterializedView->GetValue()); + chkVacEnabled->Enable(chkCustomVac->GetValue()); + cboTablespace->Enable(chkMaterializedView->GetValue()); + txtFillFactor->Enable(chkMaterializedView->GetValue()); + chkMatViewWithData->Enable(chkMaterializedView->GetValue()); + + txtBaseVac->Enable(vacEn); + txtBaseAn->Enable(vacEn); + txtFactorVac->Enable(vacEn); + txtFactorAn->Enable(vacEn); + txtVacDelay->Enable(vacEn); + txtVacLimit->Enable(vacEn); + txtFreezeMinAge->Enable(vacEn); + txtFreezeMaxAge->Enable(vacEn); + + stBaseVacCurr->SetLabel(tableVacBaseThr == wxT("-1") ? settingVacBaseThr : tableVacBaseThr); + stBaseAnCurr->SetLabel(tableAnlBaseThr == wxT("-1") ? settingAnlBaseThr : tableAnlBaseThr); + stFactorVacCurr->SetLabel(tableVacFactor == wxT("-1") ? settingVacFactor : tableVacFactor); + stFactorAnCurr->SetLabel(tableAnlFactor == wxT("-1") ? settingAnlFactor : tableAnlFactor); + stVacDelayCurr->SetLabel(tableCostDelay == wxT("-1") ? settingCostDelay : tableCostDelay); + stVacLimitCurr->SetLabel(tableCostLimit == wxT("-1") ? settingCostLimit : tableCostLimit); + + stFreezeMinAgeCurr->SetLabel(tableFreezeMinAge == wxT("-1") ? settingFreezeMinAge : tableFreezeMinAge); + stFreezeMaxAgeCurr->SetLabel(tableFreezeMaxAge == wxT("-1") ? settingFreezeMaxAge : tableFreezeMaxAge); + + txtFreezeTableAge->Enable(vacEn); + stFreezeTableAgeCurr->SetLabel(tableFreezeTableAge == wxT("-1") ? settingFreezeTableAge : tableFreezeTableAge); + /* Toast Table Vacuum Settings */ + bool toastVacEn = chkCustomToastVac->GetValue() && chkToastVacEnabled->GetValue(); + chkCustomToastVac->Enable(chkMaterializedView->GetValue()); + chkToastVacEnabled->Enable(chkCustomToastVac->GetValue()); + + txtBaseToastVac->Enable(toastVacEn); + txtFactorToastVac->Enable(toastVacEn); + txtToastVacDelay->Enable(toastVacEn); + txtToastVacLimit->Enable(toastVacEn); + txtToastFreezeMinAge->Enable(toastVacEn); + txtToastFreezeMaxAge->Enable(toastVacEn); + txtToastFreezeTableAge->Enable(toastVacEn); + + stBaseToastVacCurr->SetLabel(toastTableVacBaseThr == wxT("-1") ? settingVacBaseThr : toastTableVacBaseThr); + stFactorToastVacCurr->SetLabel(toastTableVacFactor == wxT("-1") ? settingVacFactor : toastTableVacFactor); + stToastVacDelayCurr->SetLabel(toastTableCostDelay == wxT("-1") ? settingCostDelay : toastTableCostDelay); + stToastVacLimitCurr->SetLabel(toastTableCostLimit == wxT("-1") ? settingCostLimit : toastTableCostLimit); + stToastFreezeMinAgeCurr->SetLabel(toastTableFreezeMinAge == wxT("-1") ? settingFreezeMinAge : toastTableFreezeMinAge); + stToastFreezeMaxAgeCurr->SetLabel(toastTableFreezeMaxAge == wxT("-1") ? settingFreezeMaxAge : toastTableFreezeMaxAge); + txtToastFreezeTableAge->Enable(toastVacEn); + stToastFreezeTableAgeCurr->SetLabel(toastTableFreezeTableAge == wxT("-1") ? settingFreezeTableAge : toastTableFreezeTableAge); + } + OnChange(ev); +} + +void dlgView::DisableMaterializedView() +{ + chkMaterializedView->Disable(); + cboTablespace->Disable(); + txtFillFactor->Disable(); + chkMatViewWithData->Disable(); + + chkCustomVac->Disable(); + chkVacEnabled->Disable(); + txtBaseVac->Disable(); + txtBaseAn->Disable(); + txtFactorVac->Disable(); + txtFactorAn->Disable(); + txtVacDelay->Disable(); + txtVacLimit->Disable(); + txtFreezeMinAge->Disable(); + txtFreezeMaxAge->Disable(); + txtFreezeTableAge->Disable(); + + chkToastVacEnabled->Disable(); + chkCustomToastVac->Disable(); + txtBaseToastVac->Disable(); + txtFactorToastVac->Disable(); + txtToastVacDelay->Disable(); + txtToastVacLimit->Disable(); + txtToastFreezeMinAge->Disable(); + txtToastFreezeMaxAge->Disable(); + txtToastFreezeTableAge->Disable(); +} + +void dlgView::DisableStorageParameters() +{ + cboTablespace->Disable(); + txtFillFactor->Disable(); + chkMatViewWithData->Disable(); + + chkCustomVac->Disable(); + chkVacEnabled->Disable(); + txtBaseVac->Disable(); + txtBaseAn->Disable(); + txtFactorVac->Disable(); + txtFactorAn->Disable(); + txtVacDelay->Disable(); + txtVacLimit->Disable(); + txtFreezeMinAge->Disable(); + txtFreezeMaxAge->Disable(); + txtFreezeTableAge->Disable(); + + chkToastVacEnabled->Disable(); + chkCustomToastVac->Disable(); + txtBaseToastVac->Disable(); + txtFactorToastVac->Disable(); + txtToastVacDelay->Disable(); + txtToastVacLimit->Disable(); + txtToastFreezeMinAge->Disable(); + txtToastFreezeMaxAge->Disable(); + txtToastFreezeTableAge->Disable(); +} + +int dlgView::GetIndexCheckOption(const wxString &str) const +{ + if (str.Cmp(wxT("local")) == 0) + return 1; + if (str.Cmp(wxT("cascaded")) == 0) + return 2; + + return 0; +} diff --git a/dlg/module.mk b/dlg/module.mk new file mode 100644 index 0000000..c1a4e33 --- /dev/null +++ b/dlg/module.mk @@ -0,0 +1,72 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/dlg/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + dlg/dlgAddFavourite.cpp \ + dlg/dlgAggregate.cpp \ + dlg/dlgCast.cpp \ + dlg/dlgClasses.cpp \ + dlg/dlgCheck.cpp \ + dlg/dlgCollation.cpp \ + dlg/dlgColumn.cpp \ + dlg/dlgConnect.cpp \ + dlg/dlgConversion.cpp \ + dlg/dlgDatabase.cpp \ + dlg/dlgDomain.cpp \ + dlg/dlgEventTrigger.cpp \ + dlg/dlgExtension.cpp \ + dlg/dlgEditGridOptions.cpp \ + dlg/dlgFindReplace.cpp \ + dlg/dlgForeignDataWrapper.cpp \ + dlg/dlgForeignKey.cpp \ + dlg/dlgForeignServer.cpp \ + dlg/dlgForeignTable.cpp \ + dlg/dlgFunction.cpp \ + dlg/dlgGroup.cpp \ + dlg/dlgHbaConfig.cpp \ + dlg/dlgIndex.cpp \ + dlg/dlgIndexConstraint.cpp \ + dlg/dlgLanguage.cpp \ + dlg/dlgMainConfig.cpp \ + dlg/dlgManageFavourites.cpp \ + dlg/dlgMoveTablespace.cpp \ + dlg/dlgOperator.cpp \ + dlg/dlgPackage.cpp \ + dlg/dlgPgpassConfig.cpp \ + dlg/dlgProperty.cpp \ + dlg/dlgReassignDropOwned.cpp \ + dlg/dlgRole.cpp \ + dlg/dlgRule.cpp \ + dlg/dlgSchema.cpp \ + dlg/dlgSearchObject.cpp \ + dlg/dlgSelectConnection.cpp \ + dlg/dlgSequence.cpp \ + dlg/dlgServer.cpp \ + dlg/dlgSynonym.cpp \ + dlg/dlgTable.cpp \ + dlg/dlgTablespace.cpp \ + dlg/dlgTextSearchConfiguration.cpp \ + dlg/dlgTextSearchDictionary.cpp \ + dlg/dlgTextSearchParser.cpp \ + dlg/dlgTextSearchTemplate.cpp \ + dlg/dlgTrigger.cpp \ + dlg/dlgType.cpp \ + dlg/dlgUser.cpp \ + dlg/dlgUserMapping.cpp \ + dlg/dlgView.cpp \ + dlg/dlgManageMacros.cpp \ + dlg/dlgExtTable.cpp \ + dlg/dlgSelectDatabase.cpp \ + dlg/dlgResourceGroup.cpp + +EXTRA_DIST += \ + dlg/module.mk + diff --git a/frm/events.cpp b/frm/events.cpp new file mode 100644 index 0000000..3c6973a --- /dev/null +++ b/frm/events.cpp @@ -0,0 +1,1179 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// events.cpp - Event handlers for frmMain +// +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include +#include +#include +#include +#include + +// App headers +#include "utils/misc.h" +#include "frm/menu.h" +#include "frm/frmMain.h" +#include "frm/frmOptions.h" +#include "ctl/ctlSQLBox.h" +#include "ctl/ctlMenuToolbar.h" +#include "db/pgConn.h" +#include "schema/pgDatabase.h" +#include "db/pgSet.h" +#include "schema/pgServer.h" +#include "schema/pgObject.h" +#include "schema/pgCollection.h" +#include "schema/pgTable.h" +#include "schema/edbPrivateSynonym.h" +#include "dlg/dlgProperty.h" + +// Mutex to protect the "currentObject" from race conditions. +// +static wxMutex s_currentObjectMutex; + +// Event table +BEGIN_EVENT_TABLE(frmMain, pgFrame) + EVT_CHILD_FOCUS( frmMain::OnChildFocus) + EVT_ERASE_BACKGROUND( frmMain::OnEraseBackground) + EVT_SIZE( frmMain::OnSize) + EVT_MENU(MNU_ACTION, frmMain::OnAction) + + EVT_MENU(MNU_COPY, frmMain::OnCopy) + EVT_MENU(MNU_DELETE, frmMain::OnDelete) + EVT_MENU(MNU_SAVEDEFINITION, frmMain::OnSaveDefinition) + EVT_MENU(MNU_SQLPANE, frmMain::OnToggleSqlPane) + EVT_MENU(MNU_OBJECTBROWSER, frmMain::OnToggleObjectBrowser) + EVT_MENU(MNU_TOOLBAR, frmMain::OnToggleToolBar) + EVT_MENU(MNU_DEFAULTVIEW, frmMain::OnDefaultView) + EVT_MENU(MNU_CHECKALIVE, frmMain::OnCheckAlive) + EVT_MENU(MNU_CONTEXTMENU, frmMain::OnContextMenu) + + EVT_AUINOTEBOOK_PAGE_CHANGED(wxID_ANY, frmMain::OnPageChange) + EVT_LIST_ITEM_SELECTED(CTL_PROPVIEW, frmMain::OnPropSelChanged) + EVT_LIST_ITEM_ACTIVATED(CTL_PROPVIEW, frmMain::OnPropSelActivated) + EVT_LIST_ITEM_RIGHT_CLICK(CTL_PROPVIEW, frmMain::OnPropRightClick) + EVT_LIST_ITEM_SELECTED(CTL_STATVIEW, frmMain::OnSelectItem) + EVT_LIST_ITEM_SELECTED(CTL_DEPVIEW, frmMain::OnSelectItem) + EVT_LIST_ITEM_SELECTED(CTL_REFVIEW, frmMain::OnSelectItem) + EVT_TREE_SEL_CHANGED(CTL_BROWSER, frmMain::OnTreeSelChanged) + EVT_TREE_ITEM_EXPANDING(CTL_BROWSER, frmMain::OnExpand) + EVT_TREE_ITEM_COLLAPSING(CTL_BROWSER, frmMain::OnCollapse) + EVT_TREE_ITEM_ACTIVATED(CTL_BROWSER, frmMain::OnSelActivated) + EVT_TREE_ITEM_RIGHT_CLICK(CTL_BROWSER, frmMain::OnSelRightClick) + EVT_STC_UPDATEUI(CTL_SQLPANE, frmMain::OnPositionStc) + EVT_CLOSE( frmMain::OnClose) + + EVT_AUI_PANE_CLOSE( frmMain::OnAuiUpdate) + EVT_AUINOTEBOOK_PAGE_CLOSE(wxID_ANY, frmMain::OnAuiNotebookPageClose) + +#ifdef __WXGTK__ + EVT_TREE_KEY_DOWN(CTL_BROWSER, frmMain::OnTreeKeyDown) +#endif + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + EVT_COMMAND (wxID_ANY, SSH_TUNNEL_ERROR_EVENT, frmMain::OnSSHTunnelEvent) +#endif + +END_EVENT_TABLE() + +void frmMain::OnChildFocus(wxChildFocusEvent &event) +{ + // Grab the focussed control and stash it away for later use + currentControl = dynamic_cast(event.GetEventObject()); + + // Setup the menu controls according to the control that's selected + // and it's status. + + // Defaults. + editMenu->Enable(MNU_COPY, false); + + // ctlSQLBox? + ctlSQLBox *sb = dynamic_cast(event.GetEventObject()); + if (sb) + { + // Copy + editMenu->Enable(MNU_COPY, !sb->GetSelectedText().IsEmpty()); + } + + // Listview? + ctlListView *lv = dynamic_cast(event.GetEventObject()); + if (lv) + { + // Copy + editMenu->Enable(MNU_COPY, lv->GetSelectedItemCount() > 0); + } +} + +void frmMain::OnEraseBackground(wxEraseEvent &event) +{ + event.Skip(); +} + +void frmMain::OnSize(wxSizeEvent &event) +{ + event.Skip(); +} + +// unfortunately, under GTK we won't get the original wxKeyEvent +// to reset m_metaDown +void frmMain::OnTreeKeyDown(wxTreeEvent &event) +{ + int keyCode = event.GetKeyCode(); + switch (keyCode) + { + case WXK_F1: + OnHelp(event); + break; + case WXK_F5: + Refresh(currentObject); + break; + case WXK_DELETE: + OnDelete(event); + break; + // Is tempting to write all cases(this handler) in tree control itself + case WXK_LEFT: + case WXK_RIGHT: + browser->NavigateTree(keyCode); + break; + default: + event.Skip(); + break; + } +} + +void frmMain::OnExit(wxCommandEvent &event) +{ + Close(false); // Allow sub windows to stop us + event.Skip(); +} + + + +void frmMain::OnClose(wxCloseEvent &event) +{ + wxWindow *fr; + windowList::Node *node; + while ((node = frames.GetFirst()) != NULL) + { + fr = node->GetData(); + + // if crashes occur here when closing the app, + // some actionFactory::StartDialog returned a wxWindow* (which is registered in frames) + // without code to handle OnClose (esp. removing itself with RemoveFrame) + + if (!fr->Close(!event.CanVeto())) + { + if (event.CanVeto()) + { + event.Veto(); + return; + } + } + delete node; + fr->Destroy(); + } + Destroy(); +} + + +void frmMain::UpdateAllRecentFiles() +{ + wxWindow *fr; + windowList::Node *node; + node = frames.GetFirst(); + while (node) + { + fr = node->GetData(); + ((frmQuery *)fr)->UpdateRecentFiles(false); + node = node->GetNext(); + } +} + + +void frmMain::UpdateAllFavouritesList() +{ + wxWindow *fr; + windowList::Node *node; + node = frames.GetFirst(); + while (node) + { + fr = node->GetData(); + ((frmQuery *)fr)->UpdateFavouritesList(); + node = node->GetNext(); + } +} + +void frmMain::UpdateAllMacrosList() +{ + wxWindow *fr; + windowList::Node *node; + node = frames.GetFirst(); + while (node) + { + fr = node->GetData(); + ((frmQuery *)fr)->UpdateMacrosList(); + node = node->GetNext(); + } +} + + +void frmMain::OnAction(wxCommandEvent &ev) +{ + if (currentObject) { + actionFactory *af = menuFactories->GetFactory(ev.GetId()); + if (af) + { + wxWindow *wnd = af->StartDialog(this, currentObject); + if (wnd) + AddFrame(wnd); + } + } +} + +wxString frmMain::GetHelpPage() const +{ + wxString page; + + if (currentObject) + page = currentObject->GetHelpPage(true); + + if (page.IsEmpty()) + page = wxT("pg/sql-commands"); + + return page; +} + +void frmMain::OnCollapse(wxTreeEvent &event) +{ +#ifdef WIN32 + // This is weird stuff, but somewhere comes a collapse after we have done + // connecting the server and expanding the tree. + // Possibly not necessary + if (event.GetItem() == denyCollapseItem) + event.Veto(); +#endif + denyCollapseItem = wxTreeItemId(); +} + + +void frmMain::OnExpand(wxTreeEvent &event) +{ + wxCookieType cookie; + wxTreeItemId item = browser->GetFirstChild(event.GetItem(), cookie); + if (item && !browser->GetItemData(item)) + { + // the expanding node has a dummy item. + // delete dummy item, and expand kids. + execSelChange(event.GetItem(), browser->GetSelection() == item); + + // we don't have any kids, so don't expand + if (!browser->GetChildrenCount(event.GetItem())) + event.Veto(); + } +} + + +void frmMain::OnCheckAlive(wxCommandEvent &event) +{ + CheckAlive(); +} + + + +void frmMain::OnPropSelChanged(wxListEvent &event) +{ + if (properties->GetSelectedItemCount() == 1) + { + wxTreeItemId item = browser->GetSelection(); + if (item) + { + pgObject *data = browser->GetObject(item); + if (data && data->IsCollection()) + { + currentObject = ((pgCollection *)data)->FindChild(browser, event.GetIndex()); + if (currentObject) + { + setDisplay(currentObject); + sqlPane->SetReadOnly(false); + sqlPane->SetText(currentObject->GetSql(browser)); + sqlPane->SetReadOnly(true); + } + } + } + } + + editMenu->Enable(MNU_COPY, properties->GetSelectedItemCount() > 0); + +// The generic list view control on the Mac doesn't fire focus events +// as it should, so we set currentControl here instead of relying on +// the ChildFocusEvent. The native list view does fire the events, but +// does weird things with multi-select items so we currently disable +// it (see the creation of the listviews in frmMain.cpp). +#ifdef __WXMAC__ + currentControl = properties; +#endif +} + + +void frmMain::OnSelectItem(wxListEvent &event) +{ + ctlListView *list; + + switch(listViews->GetSelection()) + { + case NBP_STATISTICS: + list = statistics; + break; + case NBP_DEPENDENCIES: + list = dependencies; + break; + case NBP_DEPENDENTS: + list = dependents; + break; + default: + // This shouldn't happen. + // If it does, it's no big deal, we just need to get out. + return; + break; + } + + editMenu->Enable(MNU_COPY, list->GetSelectedItemCount() > 0); + +// The generic list view control on the Mac doesn't fire focus events +// as it should, so we set currentControl here instead of relying on +// the ChildFocusEvent. The native list view does fire the events, but +// does weird things with multi-select items so we currently disable +// it (see the creation of the listviews in frmMain.cpp). +#ifdef __WXMAC__ + currentControl = list; +#endif +} + +void frmMain::OnPropSelActivated(wxListEvent &event) +{ + if (propFactory->CheckEnable(currentObject)) + propFactory->StartDialog(this, currentObject); +} + + +void frmMain::OnPropRightClick(wxListEvent &event) +{ + OnPropSelChanged(event); + + if (currentObject) + doPopup(properties, event.GetPoint(), currentObject); +} + + +void frmMain::OnTreeSelChanged(wxTreeEvent &event) +{ + /* + * Do not honour the tree selection change, while a property dialog is + * closed and refresh is in progress + */ + if (m_refreshing) + return; + + denyCollapseItem = wxTreeItemId(); + // Reset the listviews/SQL pane + if (event.GetItem()) + execSelChange(event.GetItem(), true); +} + + +// Reset the list controls +void frmMain::ResetLists() +{ + properties->ClearAll(); + properties->AddColumn(_("Properties"), properties->GetSize().GetWidth() - 10); + properties->InsertItem(0, _("No properties are available for the current selection"), PGICON_PROPERTY); + statistics->ClearAll(); + statistics->AddColumn(_("Statistics"), properties->GetSize().GetWidth() - 10); + statistics->InsertItem(0, _("No statistics are available for the current selection"), PGICON_PROPERTY); + dependencies->ClearAll(); + dependencies->AddColumn(_("Dependencies"), properties->GetSize().GetWidth() - 10); + dependencies->InsertItem(0, _("No dependency information is available for the current selection"), PGICON_PROPERTY); + dependents->ClearAll(); + dependents->AddColumn(_("Dependents"), properties->GetSize().GetWidth() - 10); + dependents->InsertItem(0, _("No dependent information is available for the current selection"), PGICON_PROPERTY); +} + + +void frmMain::execSelChange(wxTreeItemId item, bool currentNode) +{ + static bool refresh = true; + + if (currentNode) + { + ResetLists(); + sqlPane->Clear(); + } + + // Get the item data, and feed it to the relevant handler, + // cast as required. + // + // Lock the assignment to prevent the race conditions between onSelRightClick and execSelChange. + // + s_currentObjectMutex.Lock(); + currentObject = browser->GetObject(item); + s_currentObjectMutex.Unlock(); + + // If we didn't get an object, then we may have a right click, or + // invalid click, so ignore. + if (!currentObject) + { + menuFactories->CheckMenu(currentObject, menuBar, toolBar); + } + else + { + int settingRefreshOnClick = settings->GetRefreshOnClick(); + + if (settingRefreshOnClick != REFRESH_OBJECT_NONE + && refresh + && currentObject->GetTypeName() != wxT("Server") + && currentObject->GetTypeName() != wxT("Servers") + && currentObject->GetTypeName() != wxT("Database") + && !currentObject->IsCollection()) + { + refresh = false; + + if (settingRefreshOnClick == REFRESH_OBJECT_ONLY ) + { + // We can not update the schema, because it would cause an update to the entire tree. + if (currentObject->GetTypeName() != wxT("Schema")) + { + wxTreeItemId currentItem = currentObject->GetId(); + + // Do not refresh and instead bail out if dialog of the currently selected + // node or it's child node is open, as refresh would delete this node's object + // and could cause a crash + pgObject *obj = NULL; + if (currentItem) + obj = browser->GetObject(currentItem); + + if (obj && obj->CheckOpenDialogs(browser, currentItem)) + { + properties->Freeze(); + setDisplay(currentObject, properties, sqlPane); + properties->Thaw(); + refresh = true; + return; + } + + pgObject *newData = currentObject->Refresh(browser, currentItem); + + if (newData != 0) + { + wxLogInfo(wxT("Replacing with new node %s %s for refresh"), newData->GetTypeName().c_str(), newData->GetQuotedFullIdentifier().c_str()); + + browser->DeleteChildren(currentItem); + newData->SetId(currentItem); // not done automatically + browser->SetItemData(currentItem, newData); + + // Update the node text if this is an object, as it may have been renamed + if (!newData->IsCollection()) + browser->SetItemText(currentItem, newData->GetDisplayName()); + + delete currentObject; + currentObject = newData; + } + else + { + // OK, we failed to refresh, so select the parent and delete the child. + browser->SelectItem(browser->GetItemParent(currentItem)); + browser->Delete(currentItem); + } + } + } + else + Refresh(currentObject); + + refresh = true; + } + + + if (currentNode) + { + properties->Freeze(); + setDisplay(currentObject, properties, sqlPane); + properties->Thaw(); + } + else + setDisplay(currentObject, 0, 0); + } +} + + +void frmMain::setDisplay(pgObject *data, ctlListView *props, ctlSQLBox *sqlbox) +{ + pgServer *server = 0; + + + bool showTree = false; + + pgaFactory *factory = data->GetFactory(); + if (factory) + { + if (factory == &serverFactory) + { + server = (pgServer *)data; + + data->ShowTree(this, browser, props, sqlbox); + showTree = false; + } + else + showTree = true; + } + else + showTree = false; + + if (showTree) + data->ShowTree(this, browser, props, sqlbox); + + if (sqlbox) + { + sqlbox->SetReadOnly(false); + sqlbox->SetText(data->GetSql(browser)); + sqlbox->SetReadOnly(true); + } + + pgConn *conn = data->GetConnection(); + if (conn && (conn->GetStatus() == PGCONN_BROKEN || conn->GetStatus() == PGCONN_BAD)) + { + CheckAlive(); + return; + } + + unsigned int i; + wxMenuItem *menuItem; + i = newMenu->GetMenuItemCount(); + while (i--) + { + menuItem = newMenu->GetMenuItems().Item(i)->GetData(); + if (menuItem) + delete newMenu->Remove(menuItem); + } + + i = newContextMenu->GetMenuItemCount(); + while (i--) + { + menuItem = newContextMenu->GetMenuItems().Item(i)->GetData(); + if (menuItem) + delete newContextMenu->Remove(menuItem); + } + + editMenu->Enable(newMenuFactory->GetId(), false); + + wxMenu *indivMenu = data->GetNewMenu(); + if (indivMenu) + { + if (indivMenu->GetMenuItemCount()) + { + editMenu->Enable(newMenuFactory->GetId(), true); + + for (i = 0 ; i < indivMenu->GetMenuItemCount() ; i++) + { + menuItem = indivMenu->GetMenuItems().Item(i)->GetData(); +#if wxCHECK_VERSION(2, 9, 0) + wxString lab = menuItem->GetItemLabelText(); +#else + wxString lab = menuItem->GetLabel(); // deprecated +#endif + + newMenu->Append(menuItem->GetId(), lab, menuItem->GetHelp()); + newContextMenu->Append(menuItem->GetId(), lab, menuItem->GetHelp()); + } + } + delete indivMenu; + } + + menuFactories->CheckMenu(data, menuBar, toolBar); + + menuFactories->EnableSubmenu(menuBar, MNU_CONFIGSUBMENU); + menuFactories->EnableSubmenu(menuBar, MNU_SLONY_SUBMENU); +} + + +void frmMain::OnSelActivated(wxTreeEvent &event) +{ + // This handler will primarily deal with displaying item + // properties in seperate windows and 'Add xxx...' clicks + + // Get the item data, and feed it to the relevant handler, + // cast as required. + + wxTreeItemId item = event.GetItem(); + pgObject *data = browser->GetObject(item); + if (!data) + return; + pgServer *server; + wxCommandEvent nullEvent; + + if (data->IsCreatedBy(serverFactory)) + { + server = (pgServer *)data; + if (!server->GetConnected()) + { + if (ReconnectServer(server) == PGCONN_OK) + { + // prevent from being collapsed immediately + + denyCollapseItem = item; + } + } + } + else + { + if (settings->GetDoubleClickProperties() && propFactory->CheckEnable(data)) + { + propFactory->StartDialog(this, data); + event.Skip(); + return; + } + } + + browser->Expand(item); +} + +void frmMain::doPopup(wxWindow *win, wxPoint point, pgObject *object) +{ + if (treeContextMenu) + delete treeContextMenu; + + treeContextMenu = new wxMenu(); + + menuFactories->AppendEnabledMenus(menuBar, treeContextMenu); + + wxMenuItem *newItem = treeContextMenu->FindItem(newMenuFactory->GetId()); + + if (newItem) + { + size_t newItemPos; + + wxMenuItemList mil = treeContextMenu->GetMenuItems(); + for (newItemPos = 0 ; newItemPos < mil.GetCount() ; newItemPos++) + { + if (mil.Item(newItemPos)->GetData()->GetId() == newItem->GetId()) + break; + } + + if (object) + { + wxMenu *indivMenu = object->GetNewMenu(); + if (indivMenu) + { + + if (indivMenu->GetMenuItemCount() > 1) + { + wxMenuItem *menuItem = menuBar->FindItem(newMenuFactory->GetId()); +#if wxCHECK_VERSION(2, 9, 0) + wxString lab = menuItem->GetItemLabelText(); +#else + wxString lab = menuItem->GetLabel(); // deprecated +#endif + + treeContextMenu->Insert(newItemPos, newMenuFactory->GetId(), lab, indivMenu, menuItem->GetHelp()); + } + else + { + if (indivMenu->GetMenuItemCount() == 1) + { + wxMenuItem *menuItem = indivMenu->GetMenuItems().Item(0)->GetData(); +#if wxCHECK_VERSION(2, 9, 0) + wxString lab = menuItem->GetItemLabelText(); +#else + wxString lab = menuItem->GetLabel(); // deprecated +#endif + treeContextMenu->Insert(newItemPos, menuItem->GetId(), lab, menuItem->GetHelp()); + } + delete indivMenu; + } + } + } + treeContextMenu->Remove(newItem); + delete newItem; + } + + if (treeContextMenu->GetMenuItemCount()) + win->PopupMenu(treeContextMenu, point); +} + +//////////////////////////////////////////////////////////////////////////////// +// This handler will display a popup menu for the currently selected item +//////////////////////////////////////////////////////////////////////////////// +void frmMain::OnContextMenu(wxCommandEvent &event) +{ + wxPoint point; + + if (FindFocus() == browser) + { + wxRect rect; + wxTreeItemId item = browser->GetSelection(); + + browser->GetBoundingRect(item, rect); + point = rect.GetPosition(); + wxPoint origin = GetClientAreaOrigin(); + + // Because this Tree is inside a vertical splitter, we + // must compensate for the size of the other elements + point.x += origin.x; + point.y += origin.y; + + doPopup(this, point, browser->GetObject(item)); + } + +} + + +//////////////////////////////////////////////////////////////////////////////// +// This handler will display a popup menu for the item at the mouse position +//////////////////////////////////////////////////////////////////////////////// +void frmMain::OnSelRightClick(wxTreeEvent &event) +{ + wxTreeItemId item = event.GetItem(); + if (item != browser->GetSelection()) + { + browser->SelectItem(item); + + // Prevent changes to "currentObject" by "execSelchange" function by another + // thread. Will hold the lock until we have the actual object in hand. + s_currentObjectMutex.Lock(); + currentObject = browser->GetObject(item); + s_currentObjectMutex.Unlock(); + } + + if (currentObject) + doPopup(browser, event.GetPoint(), currentObject); +} + + +void frmMain::OnDelete(wxCommandEvent &ev) +{ + if (currentObject->CanDrop()) + ExecDrop(false); +} + + +void frmMain::ExecDrop(bool cascaded) +{ + wxTreeItemId item = browser->GetSelection(); + pgCollection *collection = (pgCollection *)browser->GetObject(item); + + // Get any table object for later update + wxTreeItemId owneritem; + pgObject *node = (pgObject *)browser->GetObject(item); + + int metatype = node->GetMetaType(); + + switch (metatype) + { + case PGM_COLUMN: + owneritem = node->GetTable()->GetId(); + break; + + case PGM_CHECK: + case PGM_CONSTRAINT: + case PGM_EXCLUDE: + case PGM_FOREIGNKEY: + case PGM_INDEX: + case PGM_PRIMARYKEY: + case PGM_UNIQUE: + case PGM_TRIGGER: + case PGM_RULE: // Rules are technically table objects! Yeuch + case EDB_PACKAGEFUNCTION: + case EDB_PACKAGEVARIABLE: + case PGM_SCHEDULE: + case PGM_STEP: + if (node->IsCollection()) + owneritem = browser->GetParentObject(node->GetId())->GetId(); + else + owneritem = browser->GetParentObject(browser->GetParentObject(node->GetId())->GetId())->GetId(); + break; + + default: + break; + } + + // Grab the parent item to re-focus on. + wxString parent = GetNodePath(item).BeforeLast('/'); + + bool success = false; + if (collection == currentObject) + success = dropSingleObject(currentObject, true, cascaded); + else + { + if (collection && collection->IsCollection()) + { + long index = properties->GetFirstSelected(); + + if (index >= 0) + { + pgObject *data = collection->FindChild(browser, index); + + if (!data || !data->CanDrop()) + return; + + if (properties->GetSelectedItemCount() == 1) + { + success = dropSingleObject(data, true, cascaded); + } + else + { + if (cascaded || data->RequireDropConfirm() || settings->GetConfirmDelete()) + { + wxString text, caption; + if (cascaded) + { + text = _("Are you sure you wish to drop multiple objects including all objects that depend on them?"); + caption = _("Drop multiple objects cascaded?"); + } + else + { + text = _("Are you sure you wish to drop multiple objects?"); + caption = _("Drop multiple objects?"); + } + wxMessageDialog msg(this, text, caption, wxYES_NO | wxICON_QUESTION | wxNO_DEFAULT); + if (msg.ShowModal() != wxID_YES) + { + return; + } + } + + bool done = true; + long count = 0; + while (done && data && index >= 0) + { + if (data->GetSystemObject()) + { + wxMessageDialog msg(this, + data->GetTranslatedMessage(CANNOTDROPSYSTEM), + _("Trying to drop system object"), wxICON_EXCLAMATION); + msg.ShowModal(); + return; + } + + done = dropSingleObject(data, false, cascaded); + + if (done) + { + properties->DeleteItem(index); + count++; + index = properties->GetFirstSelected(); + + if (index >= 0) + data = collection->FindChild(browser, index); + + success = true; + } + } + } + } + } + } + + if (success) + { + // If the collection has a table, refresh that as well. + if (owneritem) + { + ObjectBrowserRefreshing(true); + Refresh(browser->GetObject(owneritem)); + ObjectBrowserRefreshing(false); + } + + // Now re-focus on the parent of the deleted node + if (!parent.IsEmpty()) + SetCurrentNode(browser->GetRootItem(), parent); + } +} + + +bool frmMain::dropSingleObject(pgObject *data, bool updateFinal, bool cascaded) +{ + if (updateFinal) + { + // accelerator can bypass disabled menu, so we need to check + if (!data || !data->CanDrop()) + return false; + + if (data->CheckOpenDialogs(browser, browser->GetSelection())) + { + wxString msg = _("There are properties dialogues open for one or more objects that would be dropped. Please close the properties dialogues and try again."); + wxMessageBox(msg, _("Cannot drop object"), wxICON_WARNING | wxOK); + return false; + } + + if (data->GetSystemObject()) + { + wxMessageDialog msg(this, data->GetTranslatedMessage(CANNOTDROPSYSTEM), + _("Trying to drop system object"), wxICON_EXCLAMATION); + msg.ShowModal(); + return false; + } + + if (cascaded || data->RequireDropConfirm() || settings->GetConfirmDelete()) + { + wxString text, caption; + if (cascaded) + { + text = data->GetTranslatedMessage(DROPINCLUDINGDEPS); + caption = data->GetTranslatedMessage(DROPCASCADETITLE); + } + else + { + /* + * currentObject is set using the following command. + * i.e. currentObject = browser->GetObject(item); + * While fetching this object using this code, somehow it looses its virtual table pointer. + * Hence, it is not able to call the GetFullIdentifier - virtual function from the + * particular class, but it will always call this functions from pgObject class always. + * To rectify this problem, we need to explicitly check the meta data type and call the + * function from the particular class. + */ + if (data->GetMetaType() == PGM_SERVER) + text = wxString::Format(_("Are you sure you wish to drop server \"%s\"?"), + ((pgServer *)data)->GetFullIdentifier().c_str()); + else if (data->GetMetaType() == EDB_SYNONYM) + text = ((edbPrivateSynonym *)data)->GetTranslatedMessage(DROPEXCLUDINGDEPS); + else + text = data->GetTranslatedMessage(DROPEXCLUDINGDEPS); + caption = data->GetTranslatedMessage(DROPTITLE); + } + wxMessageDialog msg(this, text, caption, wxYES_NO | wxICON_QUESTION | wxNO_DEFAULT); + if (msg.ShowModal() != wxID_YES) + { + return false; + } + } + } + bool done = data->DropObject(this, browser, cascaded); + + if (done) + { + wxLogInfo(wxT("Dropping %s %s"), data->GetTypeName().c_str(), data->GetIdentifier().c_str()); + + wxTreeItemId parentItem = browser->GetItemParent(data->GetId()); + + if (updateFinal) + { + wxTreeItemId nextItem; + if (browser->IsVisible(data->GetId())) + nextItem = browser->GetNextVisible(data->GetId()); + + if (nextItem) + { + pgObject *nextData = browser->GetObject(nextItem); + if (!nextData || nextData->GetType() != data->GetType()) + nextItem = browser->GetPrevSibling(data->GetId()); + } + else + nextItem = browser->GetPrevSibling(data->GetId()); + + if (nextItem) + browser->SelectItem(nextItem); + } + pgaFactory *droppedCollFactory = data->GetFactory()->GetCollectionFactory(); + + wxTreeItemId oldgroupitem; + wxString oldgroupname; + if (data->IsCreatedBy(serverFactory)) + { + oldgroupname = ((pgServer *)data)->GetGroup(); + oldgroupitem = browser->GetItemParent(data->GetId()); + } + + browser->Delete(data->GetId()); + // data is invalid now + + if (updateFinal) + { + if (!oldgroupname.IsEmpty()) + { + int total = browser->GetChildrenCount(oldgroupitem, false); + if (total == 0) + browser->Delete(oldgroupitem); + else + { + wxString label = oldgroupname + wxT(" (") + NumToStr((long)total) + wxT(")"); + browser->SetItemText(oldgroupitem, label); + } + } + else + { + pgCollection *collection = 0; + + while (parentItem) + { + collection = (pgCollection *)browser->GetObject(parentItem); + if (collection && collection->IsCollection() && collection->GetFactory() == droppedCollFactory) + { + collection->UpdateChildCount(browser); + break; + } + parentItem = browser->GetItemParent(parentItem); + } + } + } + + // Update the server list, if we dropped a server + StoreServers(); + } + return done; +} + + +void frmMain::OnNew(wxCommandEvent &ev) +{ + pgaFactory *factory = pgaFactory::GetFactory(ev.GetId() - MNU_NEW); + + if (factory == &serverFactory) + { + if (currentObject && currentObject->IsCreatedBy(serverFactory)) + { + pgServer *server = (pgServer *)currentObject; + if (!server->GetConnected()) + ReconnectServer(server); + } + return; + } + + if (currentObject) + { + if (!dlgProperty::CreateObjectDialog(this, currentObject, factory)) + CheckAlive(); + } +} + + +void frmMain::OnSaveDefinition(wxCommandEvent &event) +{ + + wxLogInfo(wxT("Saving object definition")); + + if (sqlPane->GetText().IsNull()) + { + wxLogError(__("There is nothing in the SQL pane to save!")); + return; + } + + wxString file; + settings->Read(wxT("frmMain/LastFile"), &file, wxEmptyString); + +#ifdef __WXMSW__ + wxFileDialog filename(this, _("Select output file"), ::wxPathOnly(file), file, _("SQL Scripts (*.sql)|*.sql|All files (*.*)|*.*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); +#else + wxFileDialog filename(this, _("Select output file"), ::wxPathOnly(file), file, _("SQL Scripts (*.sql)|*.sql|All files (*)|*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); +#endif + + // Show the dialogue + if (filename.ShowModal() == wxID_OK) + { + // Write the file + if (!FileWrite(filename.GetPath(), sqlPane->GetText())) + { + wxLogError(__("Could not write the file %s: Errcode=%d."), filename.GetPath().c_str(), wxSysErrorCode()); + } + } + else + { + wxLogInfo(wxT("User cancelled")); + } + + settings->Write(wxT("frmMain/LastFile"), filename.GetPath()); +} + +void frmMain::OnToggleSqlPane(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_SQLPANE)) + manager.GetPane(wxT("sqlPane")).Show(true); + else + manager.GetPane(wxT("sqlPane")).Show(false); + manager.Update(); +} + +void frmMain::OnToggleObjectBrowser(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_OBJECTBROWSER)) + manager.GetPane(wxT("objectBrowser")).Show(true); + else + manager.GetPane(wxT("objectBrowser")).Show(false); + manager.Update(); +} + +void frmMain::OnToggleToolBar(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_TOOLBAR)) + manager.GetPane(wxT("toolBar")).Show(true); + else + manager.GetPane(wxT("toolBar")).Show(false); + manager.Update(); +} + +void frmMain::OnAuiUpdate(wxAuiManagerEvent &event) +{ + if(event.pane->name == wxT("objectBrowser")) + { + viewMenu->Check(MNU_OBJECTBROWSER, false); + } + else if(event.pane->name == wxT("sqlPane")) + { + viewMenu->Check(MNU_SQLPANE, false); + } + else if(event.pane->name == wxT("toolBar")) + { + viewMenu->Check(MNU_TOOLBAR, false); + } + event.Skip(); +} + +void frmMain::OnAuiNotebookPageClose(wxAuiNotebookEvent &event) +{ + // Prevent the user closing the four main tabs. + if (event.GetSelection() < 4) + { + wxMessageBox(_("This tab cannot be closed."), _("Close tab"), wxICON_INFORMATION | wxOK); + event.Veto(); + return; + } + + event.Skip(); +} + +void frmMain::OnDefaultView(wxCommandEvent &event) +{ + manager.LoadPerspective(FRMMAIN_DEFAULT_PERSPECTIVE, true); + + // Reset the captions for the current language + manager.GetPane(wxT("objectBrowser")).Caption(_("Object browser")); + manager.GetPane(wxT("listViews")).Caption(_("Info pane")); + manager.GetPane(wxT("sqlPane")).Caption(_("SQL pane")); + manager.GetPane(wxT("toolBar")).Caption(_("Tool bar")); + + // tell the manager to "commit" all the changes just made + manager.Update(); + + // Sync the View menu options + viewMenu->Check(MNU_SQLPANE, manager.GetPane(wxT("sqlPane")).IsShown()); + viewMenu->Check(MNU_OBJECTBROWSER, manager.GetPane(wxT("objectBrowser")).IsShown()); + viewMenu->Check(MNU_TOOLBAR, manager.GetPane(wxT("toolBar")).IsShown()); +} + +void frmMain::OnPositionStc(wxStyledTextEvent &event) +{ + if (sqlPane->GetSelectedText().IsNull()) + editMenu->Enable(MNU_COPY, false); + else + editMenu->Enable(MNU_COPY, true); +} diff --git a/frm/frmAbout.cpp b/frm/frmAbout.cpp new file mode 100644 index 0000000..0e88b6a --- /dev/null +++ b/frm/frmAbout.cpp @@ -0,0 +1,108 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmAbout.cpp - About Box +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include + +// App headers +#include "pgAdmin3.h" +#include "frm/frmAbout.h" + +// Copyright text +#include "copyright.h" +#include "version.h" +#include "svnversion.h" + +#define VERSION_WITH_DATE_AND_SVN wxT("Version ") VERSION_STR wxT(" (") __TDATE__ wxT(", rev: ") wxT(VERSION_SVN) wxT(")") + + +BEGIN_EVENT_TABLE(frmAbout, wxFrame) + EVT_PAINT(frmAbout::OnPaint) + + EVT_KEY_UP(frmAbout::OnKeyUp) + EVT_LEFT_DOWN(frmAbout::OnLeftDown) +#ifdef __WXGTK__ + EVT_WINDOW_CREATE(frmAbout::OnWindowCreate) +#endif +END_EVENT_TABLE() + +frmAbout::frmAbout(wxFrame *parent) + : wxFrame(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(100, 100), 0 | wxFRAME_SHAPED | wxSIMPLE_BORDER | wxFRAME_NO_TASKBAR | wxSTAY_ON_TOP) +{ + appearanceFactory->SetIcons(this); + about = appearanceFactory->GetSplashImage(); + + SetClientSize(about.GetWidth(), about.GetHeight()); + +#ifndef __WXGTK__ + SetWindowShape(); +#endif + + CenterOnParent(); +} + +void frmAbout::OnLeftDown(wxMouseEvent &WXUNUSED(evt)) +{ + this->Close(); +} + +void frmAbout::OnKeyUp(wxKeyEvent &evt) +{ + if (evt.GetKeyCode() == WXK_ESCAPE) + this->Close(); +} + + +void frmAbout::SetWindowShape() +{ + wxRegion region(about); + SetShape(region); +} + +void frmAbout::OnPaint(wxPaintEvent &WXUNUSED(event)) +{ + wxPoint pos = appearanceFactory->GetSplashTextPos(); + + wxPaintDC dc(this); + dc.DrawBitmap(about, 0, 0, true); + dc.SetTextForeground(appearanceFactory->GetSplashTextColour()); + dc.SetFont(appearanceFactory->GetSplashTextFont()); + + if (appearanceFactory->IsBranded()) + { + dc.DrawText(_("This program is based on pgAdmin III"), pos); + pos.y += appearanceFactory->GetSplashTextOffset(); + } + dc.DrawText(VERSION_WITH_DATE_AND_SVN, pos); + pos.y += appearanceFactory->GetSplashTextOffset(); + dc.DrawText(COPYRIGHT, pos); + pos.y += appearanceFactory->GetSplashTextOffset(); + dc.DrawText(LICENSE, pos); +} + +void frmAbout::OnWindowCreate(wxWindowCreateEvent &WXUNUSED(evt)) +{ + SetWindowShape(); +} + +aboutFactory::aboutFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, _("&About"), _("Show about dialog.")); +} + + +wxWindow *aboutFactory::StartDialog(frmMain *form, pgObject *obj) +{ + frmAbout *frm = new frmAbout((wxFrame *)form); + frm->Show(); + return 0; +} diff --git a/frm/frmBackup.cpp b/frm/frmBackup.cpp new file mode 100644 index 0000000..ca946f3 --- /dev/null +++ b/frm/frmBackup.cpp @@ -0,0 +1,636 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmBackup.cpp - Backup database dialogue +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include + + +// App headers +#include "pgAdmin3.h" +#include "frm/frmMain.h" +#include "frm/frmBackup.h" +#include "utils/sysLogger.h" +#include "schema/pgSchema.h" +#include "schema/pgTable.h" +#include "ctl/ctlCheckTreeView.h" + +// Icons +#include "images/backup.pngc" + + +#define nbNotebook CTRL_NOTEBOOK("nbNotebook") +#define txtFilename CTRL_TEXT("txtFilename") +#define btnFilename CTRL_BUTTON("btnFilename") +#define txtCompressRatio CTRL_TEXT("txtCompressRatio") +#define cbEncoding CTRL_COMBOBOX("cbEncoding") +#define cbFormat CTRL_COMBOBOX("cbFormat") +#define txtNumberOfJobs CTRL_TEXT("txtNumberOfJobs") +#define cbRolename CTRL_COMBOBOX("cbRolename") +#define chkBlobs CTRL_CHECKBOX("chkBlobs") +#define chkOid CTRL_CHECKBOX("chkOid") +#define chkInsert CTRL_CHECKBOX("chkInsert") +#define chkDisableDollar CTRL_CHECKBOX("chkDisableDollar") +#define chkOnlyData CTRL_CHECKBOX("chkOnlyData") +#define chkOnlySchema CTRL_CHECKBOX("chkOnlySchema") +#define chkNoOwner CTRL_CHECKBOX("chkNoOwner") +#define chkCreateDb CTRL_CHECKBOX("chkCreateDb") +#define chkDropDb CTRL_CHECKBOX("chkDropDb") +#define chkDisableTrigger CTRL_CHECKBOX("chkDisableTrigger") +#define chkVerbose CTRL_CHECKBOX("chkVerbose") +#define chkColumnInserts CTRL_CHECKBOX("chkColumnInserts") +#define chkNoPrivileges CTRL_CHECKBOX("chkNoPrivileges") +#define chkNoTablespaces CTRL_CHECKBOX("chkNoTablespaces") +#define chkUseSetSession CTRL_CHECKBOX("chkUseSetSession") +#define chkForceQuoteForIdent CTRL_CHECKBOX("chkForceQuoteForIdent") +#define ctvObjects CTRL_CHECKTREEVIEW("ctvObjects") +#define chkNoUnloggedTableData CTRL_CHECKBOX("chkNoUnloggedTableData") +#define chkSectionPreData CTRL_CHECKBOX("chkSectionPreData") +#define chkSectionData CTRL_CHECKBOX("chkSectionData") +#define chkSectionPostData CTRL_CHECKBOX("chkSectionPostData") + + +BEGIN_EVENT_TABLE(frmBackup, ExternProcessDialog) + EVT_TEXT(XRCID("txtFilename"), frmBackup::OnChange) + EVT_BUTTON(XRCID("btnFilename"), frmBackup::OnSelectFilename) + EVT_BUTTON(wxID_OK, frmBackup::OnOK) + EVT_COMBOBOX(XRCID("cbFormat"), frmBackup::OnChangePlain) + EVT_CHECKBOX(XRCID("chkOnlyData"), frmBackup::OnChangePlain) + EVT_CHECKBOX(XRCID("chkOnlySchema"), frmBackup::OnChangePlain) + EVT_CHECKBOX(XRCID("chkNoUnloggedTableData"), frmBackup::OnChangePlain) + EVT_CHECKBOX(XRCID("chkSectionPreData"), frmBackup::OnChangePlain) + EVT_CHECKBOX(XRCID("chkSectionData"), frmBackup::OnChangePlain) + EVT_CHECKBOX(XRCID("chkSectionPostData"), frmBackup::OnChangePlain) + EVT_CLOSE( ExternProcessDialog::OnClose) +END_EVENT_TABLE() + + + +frmBackup::frmBackup(frmMain *form, pgObject *obj) : ExternProcessDialog(form) +{ + object = obj; + + SetFont(settings->GetSystemFont()); + LoadResource(form, wxT("frmBackup")); + RestorePosition(); + + SetTitle(object->GetTranslatedMessage(BACKUPTITLE)); + + if (object->GetConnection()->EdbMinimumVersion(8, 0)) + backupExecutable = edbBackupExecutable; + else if (object->GetConnection()->GetIsGreenplum()) + backupExecutable = gpBackupExecutable; + else + backupExecutable = pgBackupExecutable; + + canBlob = (obj->GetMetaType() == PGM_DATABASE); + chkBlobs->SetValue(canBlob); + chkDisableDollar->Enable(obj->GetConnection()->BackendMinimumVersion(7, 5)); + + wxString val; + settings->Read(wxT("frmBackup/LastFile"), &val, wxEmptyString); + txtFilename->SetValue(val); + + pgServer *server = object->GetServer(); + + if (!server->GetPasswordIsStored()) + environment.Add(wxT("PGPASSWORD=") + object->GetServer()->GetPassword()); + + // Pass the SSL mode via the environment + environment.Add(wxT("PGSSLMODE=") + server->GetConnection()->GetSslModeName()); + + if (server->GetSSLRootCert() != wxEmptyString) + environment.Add(wxT("PGSSLROOTCERT=") + server->GetSSLRootCert()); + + if (server->GetSSLCert() != wxEmptyString) + environment.Add(wxT("PGSSLCERT=") + server->GetSSLCert()); + + if (server->GetSSLKey() != wxEmptyString) + environment.Add(wxT("PGSSLKEY=") + server->GetSSLKey()); + + if (server->GetSSLCrl() != wxEmptyString) + environment.Add(wxT("PGSSLCRL=") + server->GetSSLCrl()); + + // Icon + SetIcon(*backup_png_ico); + + // fix translation problem + wxString dollarLabel = wxGetTranslation(_("$$ quoting")); + dollarLabel.Replace(wxT("$$"), wxT("$")); + chkDisableDollar->SetLabel(dollarLabel); + chkDisableDollar->SetSize(chkDisableDollar->GetBestSize()); + + txtMessages = CTRL_TEXT("txtMessages"); + // Note that under GTK+, SetMaxLength() function may only be used with single line text controls. + // (see http://docs.wxwidgets.org/2.8/wx_wxtextctrl.html#wxtextctrlsetmaxlength) +#ifndef __WXGTK__ + txtMessages->SetMaxLength(0L); +#endif + btnOK->Disable(); + + long encNo = 0; + wxString encStr; + cbEncoding->Append(wxT("")); + do + { + encStr = object->GetConnection()->ExecuteScalar( + wxT("SELECT pg_encoding_to_char(") + NumToStr(encNo) + wxT(")")); + if (pgConn::IsValidServerEncoding(encNo) && !encStr.IsEmpty()) + cbEncoding->Append(encStr); + + encNo++; + } + while (!encStr.IsEmpty()); + + cbEncoding->SetSelection(0); + + wxString i18ndb = _("Database"); + wxTreeItemId db = ctvObjects->AddRoot(i18ndb + wxT(" ") + object->GetDatabase()->GetName(), 1); + bool checked; + + wxString query = wxT("SELECT nspname, relname ") + wxT("FROM pg_namespace n ") + wxT("LEFT JOIN pg_class c ON n.oid=c.relnamespace AND relkind='r' ") + wxT("WHERE nspname NOT LIKE E'pg\\\\_%' AND nspname <> 'information_schema' "); + if (!object->GetDatabase()->GetSchemaRestriction().IsEmpty()) + query += wxT("AND nspname IN (") + object->GetDatabase()->GetSchemaRestriction() + wxT(")"); + query += wxT("ORDER BY nspname, relname"); + + pgSet *objects = object->GetDatabase()->ExecuteSet(query); + + if (objects) + { + wxString currentSchema = wxT(""); + wxTreeItemId currentSchemaNode; + while (!objects->Eof()) + { + if (currentSchema != objects->GetVal(wxT("nspname"))) + { + currentSchema = objects->GetVal(wxT("nspname")); + if (object->GetMetaType() == PGM_SCHEMA) + { + checked = ((pgSchema *)object)->GetIdentifier() == currentSchema; + } + else + { + if (object->GetMetaType() == PGM_TABLE || object->GetMetaType() == GP_PARTITION) + { + checked = ((pgTable *)object)->GetSchema()->GetIdentifier() == currentSchema + || (object->GetMetaType() != PGM_TABLE && object->GetMetaType() != GP_PARTITION); + } + else + { + checked = object->GetMetaType() != PGM_TABLE && object->GetMetaType() != GP_PARTITION; + } + } + currentSchemaNode = ctvObjects->AppendItem(db, currentSchema, checked ? 1 : 0); + } + if (!objects->GetVal(wxT("relname")).IsNull()) + { + if (object->GetMetaType() == PGM_TABLE || object->GetMetaType() == GP_PARTITION) + { + checked = ((pgTable *)object)->GetSchema()->GetIdentifier() == currentSchema + && ((pgTable *)object)->GetIdentifier() == objects->GetVal(wxT("relname")); + } + else + { + if (object->GetMetaType() == PGM_SCHEMA) + { + checked = ((pgSchema *)object)->GetIdentifier() == currentSchema; + } + else + { + if (object->GetMetaType() == PGM_TABLE || object->GetMetaType() == GP_PARTITION) + { + checked = ((pgTable *)object)->GetSchema()->GetIdentifier() == currentSchema + || (object->GetMetaType() != PGM_TABLE && object->GetMetaType() != GP_PARTITION); + } + else + { + checked = object->GetMetaType() != PGM_TABLE && object->GetMetaType() != GP_PARTITION; + } + } + } + ctvObjects->AppendItem(currentSchemaNode, objects->GetVal(wxT("relname")), checked ? 1 : 0); + } + objects->MoveNext(); + } + ctvObjects->ExpandAll(); + + delete objects; + } + + if (!pgAppMinimumVersion(backupExecutable, 9, 3)) + { + txtNumberOfJobs->Disable(); + } + if (!pgAppMinimumVersion(backupExecutable, 9, 2)) + { + chkSectionPreData->Disable(); + chkSectionData->Disable(); + chkSectionPostData->Disable(); + } + if (!pgAppMinimumVersion(backupExecutable, 9, 1)) + { + chkForceQuoteForIdent->Disable(); + chkNoUnloggedTableData->Disable(); + } + if (!pgAppMinimumVersion(backupExecutable, 8, 4)) + { + chkNoTablespaces->Disable(); + cbRolename->Disable(); + } + else + { + // Available rolenames + if (object->GetServer()->GetConnection()->BackendMinimumVersion(8, 1)) + { + pgSetIterator set(object->GetServer()->GetConnection(), + wxT("SELECT DISTINCT rolname\n") + wxT("FROM pg_roles db\n") + wxT("ORDER BY rolname")); + + cbRolename->Append(wxEmptyString); + + while(set.RowsLeft()) + cbRolename->Append(set.GetVal(wxT("rolname"))); + + cbRolename->SetValue(object->GetServer()->GetRolename()); + cbRolename->Enable(true); + } + else + cbRolename->Disable(); + } + if (!pgAppMinimumVersion(backupExecutable, 8, 1)) + { + cbEncoding->Disable(); + } + + cbFormat->Append(_("Custom")); + cbFormat->Append(_("Tar")); + cbFormat->Append(_("Plain")); + cbFormat->SetSelection(0); + + if (pgAppMinimumVersion(backupExecutable, 9, 1)) + cbFormat->Append(_("Directory")); + + wxCommandEvent ev; + OnChangePlain(ev); +} + + +frmBackup::~frmBackup() +{ + SavePosition(); +} + + +wxString frmBackup::GetHelpPage() const +{ + wxString page; + page = wxT("pg/app-pgdump"); + return page; +} + + +void frmBackup::OnSelectFilename(wxCommandEvent &ev) +{ + wxString title, prompt, FilenameOnly; + + if (cbFormat->GetSelection() == 2) // plain + { + title = _("Select output file"); +#ifdef __WXMSW__ + prompt = _("Query files (*.sql)|*.sql|All files (*.*)|*.*"); +#else + prompt = _("Query files (*.sql)|*.sql|All files (*)|*"); +#endif + } + else + { + title = _("Select backup filename"); +#ifdef __WXMSW__ + prompt = _("Backup files (*.backup)|*.backup|All files (*.*)|*.*"); +#else + prompt = _("Backup files (*.backup)|*.backup|All files (*)|*"); +#endif + } + + wxFileName::SplitPath(txtFilename->GetValue(), NULL, NULL, &FilenameOnly, NULL); + wxFileDialog file(this, title, ::wxPathOnly(txtFilename->GetValue()), FilenameOnly, prompt, wxFD_SAVE); + + if (file.ShowModal() == wxID_OK) + { + txtFilename->SetValue(file.GetPath()); + OnChange(ev); + } +} + + +void frmBackup::OnChange(wxCommandEvent &ev) +{ + if (!process && !done) + btnOK->Enable(!txtFilename->GetValue().IsEmpty()); +} + + +void frmBackup::OnChangePlain(wxCommandEvent &ev) +{ + bool isDirectory = (cbFormat->GetSelection() == 3); + bool isSection = chkSectionPreData->GetValue() || chkSectionData->GetValue() || chkSectionPostData->GetValue(); + + chkOnlyData->Enable(!chkOnlySchema->GetValue() && !isSection); + chkOnlySchema->Enable(!chkOnlyData->GetValue() && !isSection); + + chkSectionPreData->Enable(!chkOnlyData->GetValue() && !chkOnlySchema->GetValue()); + chkSectionData->Enable(!chkOnlyData->GetValue() && !chkOnlySchema->GetValue()); + chkSectionPostData->Enable(!chkOnlyData->GetValue() && !chkOnlySchema->GetValue()); + + chkDisableTrigger->Enable(chkOnlyData->GetValue()); + + btnFilename->Enable(!isDirectory); + + txtNumberOfJobs->Enable(isDirectory && pgAppMinimumVersion(backupExecutable, 9, 3)); + if (!txtNumberOfJobs->IsEnabled()) + txtNumberOfJobs->SetValue(wxEmptyString); + + wxCommandEvent nullEvent; + OnChange(nullEvent); +} + + +wxString frmBackup::GetCmd(int step) +{ + wxString cmd = getCmdPart1(); + + return cmd + getCmdPart2(); +} + + +wxString frmBackup::GetDisplayCmd(int step) +{ + wxString cmd = getCmdPart1(); + + return cmd + getCmdPart2(); +} + + +wxString frmBackup::getCmdPart1() +{ + pgServer *server = object->GetDatabase()->GetServer(); + + wxString cmd = backupExecutable; + + if (!server->GetName().IsEmpty()) + cmd += wxT(" --host ") + server->GetName(); + + cmd += wxT(" --port ") + NumToStr((long)server->GetPort()) + + wxT(" --username ") + commandLineCleanOption(qtIdent(server->GetUsername())); + + if (!cbRolename->GetValue().IsEmpty()) + cmd += wxT(" --role ") + commandLineCleanOption(qtIdent(cbRolename->GetValue())); + + if (pgAppMinimumVersion(backupExecutable, 8, 4)) + cmd += wxT(" --no-password "); + + if (object->GetConnection()->GetIsGreenplum()) + cmd += wxT(" --gp-syntax "); + return cmd; +} + + +wxString frmBackup::getCmdPart2() +{ + wxString cmd; + + switch (cbFormat->GetSelection()) + { + case 0: // compressed + { + cmd.Append(wxT(" --format custom")); + if (chkBlobs->GetValue()) + cmd.Append(wxT(" --blobs")); + if (!txtCompressRatio->GetValue().IsEmpty()) + cmd.Append(wxT(" --compress ") + txtCompressRatio->GetValue()); + break; + } + case 1: // tar + { + cmd.Append(wxT(" --format tar")); + if (chkBlobs->GetValue()) + cmd.Append(wxT(" --blobs")); + break; + } + case 2: // plain + { + cmd.Append(wxT(" --format plain")); + if (chkOnlyData->GetValue()) + { + cmd.Append(wxT(" --data-only")); + if (chkDisableTrigger->GetValue()) + cmd.Append(wxT(" --disable-triggers")); + } + else + { + if (chkOnlySchema->GetValue()) + cmd.Append(wxT(" --schema-only")); + if (chkNoOwner->GetValue()) + cmd.Append(wxT(" --no-owner")); + if (chkCreateDb->GetValue()) + cmd.Append(wxT(" --create")); + if (chkDropDb->GetValue()) + cmd.Append(wxT(" --clean")); + } + break; + } + case 3: // directory + { + cmd.Append(wxT(" --format directory")); + break; + } + } + + // Section + if (pgAppMinimumVersion(backupExecutable, 9, 2)) + { + if (chkSectionPreData->GetValue()) + cmd.Append(wxT(" --section pre-data")); + if (chkSectionData->GetValue()) + cmd.Append(wxT(" --section data")); + if (chkSectionPostData->GetValue()) + cmd.Append(wxT(" --section post-data")); + } + + if (!cbEncoding->GetValue().IsEmpty()) + cmd.Append(wxT(" --encoding ") + cbEncoding->GetValue()); + if (chkOid->GetValue()) + cmd.Append(wxT(" --oids")); + if (chkInsert->GetValue()) + cmd.Append(wxT(" --inserts")); + if (chkColumnInserts->GetValue()) + cmd.Append(wxT(" --column-inserts")); + if (chkNoPrivileges->GetValue()) + cmd.Append(wxT(" --no-privileges")); + if (chkNoTablespaces->GetValue()) + cmd.Append(wxT(" --no-tablespaces")); + if (chkUseSetSession->GetValue()) + cmd.Append(wxT(" --use-set-session-authorization")); + if (chkDisableDollar->GetValue()) + cmd.Append(wxT(" --disable-dollar-quoting")); + if (settings->GetIgnoreVersion()) + cmd.Append(wxT(" --ignore-version")); + if (chkVerbose->GetValue()) + cmd.Append(wxT(" --verbose")); + if (chkForceQuoteForIdent->GetValue()) + cmd.Append(wxT(" --quote-all-identifiers")); + if (chkNoUnloggedTableData->GetValue()) + cmd.Append(wxT(" --no-unlogged-table-data")); + + cmd.Append(wxT(" --file \"") + txtFilename->GetValue() + wxT("\"")); + + if (!txtNumberOfJobs->GetValue().IsEmpty()) + cmd.Append(wxT(" --jobs ") + txtNumberOfJobs->GetValue()); + + // Process selected items + wxTreeItemId root, schema, table; + wxTreeItemIdValue schemaData, tableData; + wxString cmdSchemas, cmdTables, tmpTables; + bool partialDump; + bool partialSchema; + + root = ctvObjects->GetRootItem(); + schema = ctvObjects->GetFirstChild(root, schemaData); + cmdSchemas = wxT(""); + cmdTables = wxT(""); + partialDump = false; + while (schema.IsOk()) + { + if (ctvObjects->IsChecked(schema)) + { + partialSchema = false; + tmpTables = wxT(""); + table = ctvObjects->GetFirstChild(schema, tableData); + while (table.IsOk()) + { + if (ctvObjects->IsChecked(table)) + { + // The syntax changed in 8.2 :-( + if (pgAppMinimumVersion(backupExecutable, 8, 2)) + { + tmpTables.Append(wxT(" --table \"") + + commandLineCleanOption(qtIdent(ctvObjects->GetItemText(schema)), true) + + wxT(".") + + commandLineCleanOption(qtIdent(ctvObjects->GetItemText(table)), true) + + wxT("\"")); + } + else + { + tmpTables.Append(wxT(" --table \"") + commandLineCleanOption(qtIdent(ctvObjects->GetItemText(table)), true) + wxT("\"")); + tmpTables.Append(wxT(" --schema \"") + commandLineCleanOption(qtIdent(ctvObjects->GetItemText(schema)), true) + wxT("\"")); + } + } + else + { + partialDump = true; + partialSchema = true; + } + table = ctvObjects->GetNextChild(schema, tableData); + } + + if (partialSchema) + { + cmdTables += tmpTables; + } + else + { + cmdSchemas.Append(wxT(" --schema \"") + commandLineCleanOption(qtIdent(ctvObjects->GetItemText(schema)), true) + wxT("\"")); + } + } + else + { + partialDump = true; + } + + schema = ctvObjects->GetNextChild(root, schemaData); + } + + if (partialDump) + { + if (!cmdTables.IsEmpty()) + cmd.Append(cmdTables); + if (!cmdSchemas.IsEmpty()) + cmd.Append(cmdSchemas); + } + + cmd.Append(wxT(" ") + commandLineCleanOption(object->GetDatabase()->GetQuotedIdentifier())); + + return cmd; +} + + +void frmBackup::Go() +{ + txtFilename->SetFocus(); + Show(true); +} + +void frmBackup::OnOK(wxCommandEvent &ev) +{ + if (!done) + { + if (processedFile == txtFilename->GetValue()) + { + if (wxMessageBox(_("Are you sure you wish to run a backup to this file again?"), _("Repeat backup?"), wxICON_QUESTION | wxYES_NO) != wxYES) + return; + } + else if (wxFile::Exists(txtFilename->GetValue())) + { + wxString msg; + msg.Printf(_("The file: \n\n%s\n\nalready exists. Do you want to overwrite it?"), txtFilename->GetValue().c_str()); + if (wxMessageBox(msg, _("Overwrite file?"), wxICON_WARNING | wxYES_NO) != wxYES) + return; + } + processedFile = txtFilename->GetValue(); + } + + settings->Write(wxT("frmBackup/LastFile"), txtFilename->GetValue()); + ExternProcessDialog::OnOK(ev); +} + +backupFactory::backupFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Backup..."), _("Creates a backup of the current database to a local file")); +} + + +wxWindow *backupFactory::StartDialog(frmMain *form, pgObject *obj) +{ + frmBackup *frm = new frmBackup(form, obj); + frm->Go(); + return 0; +} + + +bool backupFactory::CheckEnable(pgObject *obj) +{ + if (!obj) + return false; + + if (obj->GetConnection() && obj->GetConnection()->EdbMinimumVersion(8, 0)) + return obj->CanBackup() && !edbBackupExecutable.IsEmpty(); + else if (obj->GetConnection() && obj->GetConnection()->GetIsGreenplum()) + return obj->CanBackup() && !gpBackupExecutable.IsEmpty(); + else + return obj->CanBackup() && !pgBackupExecutable.IsEmpty(); + +} + + diff --git a/frm/frmBackupGlobals.cpp b/frm/frmBackupGlobals.cpp new file mode 100644 index 0000000..38e9a33 --- /dev/null +++ b/frm/frmBackupGlobals.cpp @@ -0,0 +1,295 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmBackupGlobals.cpp - Backup globals dialogue +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include + + +// App headers +#include "pgAdmin3.h" +#include "frm/frmMain.h" +#include "frm/frmBackupGlobals.h" +#include "utils/sysLogger.h" +#include "schema/pgSchema.h" +#include "schema/pgTable.h" + +// Icons +#include "images/backup.pngc" + + +#define nbNotebook CTRL_NOTEBOOK("nbNotebook") +#define txtFilename CTRL_TEXT("txtFilename") +#define btnFilename CTRL_BUTTON("btnFilename") +#define cbRolename CTRL_COMBOBOX("cbRolename") +#define chkVerbose CTRL_CHECKBOX("chkVerbose") +#define chkForceQuoteForIdent CTRL_CHECKBOX("chkForceQuoteForIdent") + + +BEGIN_EVENT_TABLE(frmBackupGlobals, ExternProcessDialog) + EVT_TEXT(XRCID("txtFilename"), frmBackupGlobals::OnChange) + EVT_BUTTON(XRCID("btnFilename"), frmBackupGlobals::OnSelectFilename) + EVT_BUTTON(wxID_OK, frmBackupGlobals::OnOK) + EVT_CLOSE( ExternProcessDialog::OnClose) +END_EVENT_TABLE() + + + +frmBackupGlobals::frmBackupGlobals(frmMain *form, pgObject *obj) : ExternProcessDialog(form) +{ + object = obj; + + SetFont(settings->GetSystemFont()); + LoadResource(form, wxT("frmBackupGlobals")); + RestorePosition(); + + SetTitle(object->GetTranslatedMessage(BACKUPGLOBALS)); + + if (object->GetConnection()->EdbMinimumVersion(8, 0)) + backupExecutable = edbBackupAllExecutable; + else if (object->GetConnection()->GetIsGreenplum()) + backupExecutable = gpBackupAllExecutable; + else + backupExecutable = pgBackupAllExecutable; + + wxString val; + settings->Read(wxT("frmBackupGlobals/LastFile"), &val, wxEmptyString); + txtFilename->SetValue(val); + + pgServer *server; + if (object->GetMetaType() == PGM_SERVER) + server = (pgServer *)object; + else + server = object->GetDatabase()->GetServer(); + + bool roles_supported = pgAppMinimumVersion(backupExecutable, 8, 4) && server->GetConnection()->BackendMinimumVersion(8, 1); + cbRolename->Enable(roles_supported); + + if (roles_supported) + { + // Collect the available rolenames + pgSetIterator set(server->GetConnection(), + wxT("SELECT DISTINCT rolname\n") + wxT("FROM pg_roles db\n") + wxT("ORDER BY rolname")); + + cbRolename->Append(wxEmptyString); + + while(set.RowsLeft()) + cbRolename->Append(set.GetVal(wxT("rolname"))); + + cbRolename->SetValue(server->GetRolename()); + } + + if (!server->GetPasswordIsStored()) + environment.Add(wxT("PGPASSWORD=") + server->GetPassword()); + + // Pass the SSL mode via the environment + environment.Add(wxT("PGSSLMODE=") + server->GetConnection()->GetSslModeName()); + + if (server->GetSSLRootCert() != wxEmptyString) + environment.Add(wxT("PGSSLROOTCERT=") + server->GetSSLRootCert()); + + if (server->GetSSLCert() != wxEmptyString) + environment.Add(wxT("PGSSLCERT=") + server->GetSSLCert()); + + if (server->GetSSLKey() != wxEmptyString) + environment.Add(wxT("PGSSLKEY=") + server->GetSSLKey()); + + if (server->GetSSLCrl() != wxEmptyString) + environment.Add(wxT("PGSSLCRL=") + server->GetSSLCrl()); + + // Icon + SetIcon(*backup_png_ico); + + txtMessages = CTRL_TEXT("txtMessages"); + // Note that under GTK+, SetMaxLength() function may only be used with single line text controls. + // (see http://docs.wxwidgets.org/2.8/wx_wxtextctrl.html#wxtextctrlsetmaxlength) +#ifndef __WXGTK__ + txtMessages->SetMaxLength(0L); +#endif + btnOK->Disable(); + + if (!pgAppMinimumVersion(backupExecutable, 9, 1)) + { + chkForceQuoteForIdent->Disable(); + } + + wxCommandEvent ev; + OnChange(ev); +} + + +frmBackupGlobals::~frmBackupGlobals() +{ + SavePosition(); +} + + +wxString frmBackupGlobals::GetHelpPage() const +{ + wxString page; + page = wxT("pg/app-pg-dumpall"); + return page; +} + + +void frmBackupGlobals::OnSelectFilename(wxCommandEvent &ev) +{ + wxString title, prompt, FilenameOnly; + + title = _("Select output file"); +#ifdef __WXMSW__ + prompt = _("Query files (*.sql)|*.sql|All files (*.*)|*.*"); +#else + prompt = _("Query files (*.sql)|*.sql|All files (*)|*"); +#endif + + wxFileName::SplitPath(txtFilename->GetValue(), NULL, NULL, &FilenameOnly, NULL); + wxFileDialog file(this, title, ::wxPathOnly(txtFilename->GetValue()), FilenameOnly, prompt, wxFD_SAVE); + + if (file.ShowModal() == wxID_OK) + { + txtFilename->SetValue(file.GetPath()); + OnChange(ev); + } +} + + +void frmBackupGlobals::OnChange(wxCommandEvent &ev) +{ + if (!process && !done) + btnOK->Enable(!txtFilename->GetValue().IsEmpty()); +} + +wxString frmBackupGlobals::GetCmd(int step) +{ + wxString cmd = getCmdPart1(); + + return cmd + getCmdPart2(); +} + + +wxString frmBackupGlobals::GetDisplayCmd(int step) +{ + wxString cmd = getCmdPart1(); + + return cmd + getCmdPart2(); +} + + +wxString frmBackupGlobals::getCmdPart1() +{ + pgServer *server; + if (object->GetMetaType() == PGM_SERVER) + server = (pgServer *)object; + else + server = object->GetDatabase()->GetServer(); + + wxString cmd = backupExecutable; + + if (!server->GetName().IsEmpty()) + cmd += wxT(" --host ") + server->GetName(); + + cmd += wxT(" --port ") + NumToStr((long)server->GetPort()) + + wxT(" --username ") + commandLineCleanOption(qtIdent(server->GetUsername())) + + wxT(" --database ") + commandLineCleanOption(qtIdent(server->GetDatabaseName())); + + if (!cbRolename->GetValue().IsEmpty()) + cmd += wxT(" --role ") + commandLineCleanOption(qtIdent(cbRolename->GetValue())); + + if (pgAppMinimumVersion(backupExecutable, 8, 4)) + cmd += wxT(" --no-password "); + + return cmd; +} + + +wxString frmBackupGlobals::getCmdPart2() +{ + wxString cmd; + + if (settings->GetIgnoreVersion()) + cmd.Append(wxT(" --ignore-version")); + if (chkVerbose->GetValue()) + cmd.Append(wxT(" --verbose")); + if (chkForceQuoteForIdent->GetValue()) + cmd.Append(wxT(" --quote-all-identifiers")); + + cmd.Append(wxT(" --file \"") + txtFilename->GetValue() + wxT("\"")); + + cmd.Append(wxT(" --globals-only")); + + return cmd; +} + + +void frmBackupGlobals::Go() +{ + txtFilename->SetFocus(); + Show(true); +} + +void frmBackupGlobals::OnOK(wxCommandEvent &ev) +{ + if (!done) + { + if (processedFile == txtFilename->GetValue()) + { + if (wxMessageBox(_("Are you sure you wish to run a backup to this file again?"), _("Repeat backup?"), wxICON_QUESTION | wxYES_NO) != wxYES) + return; + } + else if (wxFile::Exists(txtFilename->GetValue())) + { + wxString msg; + msg.Printf(_("The file: \n\n%s\n\nalready exists. Do you want to overwrite it?"), txtFilename->GetValue().c_str()); + if (wxMessageBox(msg, _("Overwrite file?"), wxICON_WARNING | wxYES_NO) != wxYES) + return; + } + + processedFile = txtFilename->GetValue(); + } + + settings->Write(wxT("frmBackupGlobals/LastFile"), txtFilename->GetValue()); + ExternProcessDialog::OnOK(ev); +} + +backupGlobalsFactory::backupGlobalsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Backup globals..."), _("Creates a backup of the global database objects")); +} + + +wxWindow *backupGlobalsFactory::StartDialog(frmMain *form, pgObject *obj) +{ + frmBackupGlobals *frm = new frmBackupGlobals(form, obj); + frm->Go(); + return 0; +} + + +bool backupGlobalsFactory::CheckEnable(pgObject *obj) +{ + if (!obj) + return false; + + if (obj->GetMetaType() == PGM_SERVER) + if (!((pgServer *)obj)->GetConnected()) + return false; + + if (obj->GetConnection() && obj->GetConnection()->EdbMinimumVersion(8, 0)) + return obj->CanBackupGlobals() && !edbBackupAllExecutable.IsEmpty() && pgAppMinimumVersion(edbBackupAllExecutable, 8, 3); + else if (obj->GetConnection() && obj->GetConnection()->GetIsGreenplum()) + return obj->CanBackupGlobals() && !gpBackupAllExecutable.IsEmpty() && pgAppMinimumVersion(gpBackupAllExecutable, 8, 3); + else + return obj->CanBackupGlobals() && !pgBackupAllExecutable.IsEmpty() && pgAppMinimumVersion(pgBackupAllExecutable, 8, 3); +} + diff --git a/frm/frmBackupServer.cpp b/frm/frmBackupServer.cpp new file mode 100644 index 0000000..b4cf110 --- /dev/null +++ b/frm/frmBackupServer.cpp @@ -0,0 +1,270 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmBackupServer.cpp - Backup server dialogue +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include + + +// App headers +#include "pgAdmin3.h" +#include "frm/frmMain.h" +#include "frm/frmBackupServer.h" +#include "utils/sysLogger.h" +#include "schema/pgSchema.h" +#include "schema/pgTable.h" + +// Icons +#include "images/backup.pngc" + + +#define nbNotebook CTRL_NOTEBOOK("nbNotebook") +#define txtFilename CTRL_TEXT("txtFilename") +#define btnFilename CTRL_BUTTON("btnFilename") +#define cbRolename CTRL_COMBOBOX("cbRolename") +#define chkVerbose CTRL_CHECKBOX("chkVerbose") +#define chkForceQuoteForIdent CTRL_CHECKBOX("chkForceQuoteForIdent") + + +BEGIN_EVENT_TABLE(frmBackupServer, ExternProcessDialog) + EVT_TEXT(XRCID("txtFilename"), frmBackupServer::OnChange) + EVT_BUTTON(XRCID("btnFilename"), frmBackupServer::OnSelectFilename) + EVT_BUTTON(wxID_OK, frmBackupServer::OnOK) + EVT_CLOSE( ExternProcessDialog::OnClose) +END_EVENT_TABLE() + + + +frmBackupServer::frmBackupServer(frmMain *form, pgObject *obj) : ExternProcessDialog(form) +{ + object = obj; + + SetFont(settings->GetSystemFont()); + LoadResource(form, wxT("frmBackupServer")); + RestorePosition(); + + SetTitle(object->GetTranslatedMessage(BACKUPSERVERTITLE)); + + pgServer *server = (pgServer *)object; + if (server->GetConnection()->EdbMinimumVersion(8, 0)) + backupExecutable = edbBackupAllExecutable; + else if (server->GetConnection()->GetIsGreenplum()) + backupExecutable = gpBackupAllExecutable; + else + backupExecutable = pgBackupAllExecutable; + + wxString val; + settings->Read(wxT("frmBackupServer/LastFile"), &val, wxEmptyString); + txtFilename->SetValue(val); + + bool roles_supported = pgAppMinimumVersion(backupExecutable, 8, 4) && server->GetConnection()->BackendMinimumVersion(8, 1); + cbRolename->Enable(roles_supported); + + if (roles_supported) + { + // Collect the available rolenames + pgSetIterator set(server->GetConnection(), + wxT("SELECT DISTINCT rolname\n") + wxT("FROM pg_roles db\n") + wxT("ORDER BY rolname")); + + cbRolename->Append(wxEmptyString); + + while(set.RowsLeft()) + cbRolename->Append(set.GetVal(wxT("rolname"))); + + cbRolename->SetValue(server->GetRolename()); + } + + if (!server->GetPasswordIsStored()) + environment.Add(wxT("PGPASSWORD=") + server->GetPassword()); + + // Pass the SSL mode via the environment + environment.Add(wxT("PGSSLMODE=") + server->GetConnection()->GetSslModeName()); + + // Icon + SetIcon(*backup_png_ico); + + txtMessages = CTRL_TEXT("txtMessages"); + // Note that under GTK+, SetMaxLength() function may only be used with single line text controls. + // (see http://docs.wxwidgets.org/2.8/wx_wxtextctrl.html#wxtextctrlsetmaxlength) +#ifndef __WXGTK__ + txtMessages->SetMaxLength(0L); +#endif + btnOK->Disable(); + + if (!pgAppMinimumVersion(backupExecutable, 9, 1)) + { + chkForceQuoteForIdent->Disable(); + } + + wxCommandEvent ev; + OnChange(ev); +} + + +frmBackupServer::~frmBackupServer() +{ + SavePosition(); +} + + +wxString frmBackupServer::GetHelpPage() const +{ + wxString page; + page = wxT("pg/app-pg-dumpall"); + return page; +} + + +void frmBackupServer::OnSelectFilename(wxCommandEvent &ev) +{ + wxString title, prompt, FilenameOnly; + + title = _("Select output file"); +#ifdef __WXMSW__ + prompt = _("Query files (*.sql)|*.sql|All files (*.*)|*.*"); +#else + prompt = _("Query files (*.sql)|*.sql|All files (*)|*"); +#endif + + wxFileName::SplitPath(txtFilename->GetValue(), NULL, NULL, &FilenameOnly, NULL); + wxFileDialog file(this, title, ::wxPathOnly(txtFilename->GetValue()), FilenameOnly, prompt, wxFD_SAVE); + + if (file.ShowModal() == wxID_OK) + { + txtFilename->SetValue(file.GetPath()); + OnChange(ev); + } +} + + +void frmBackupServer::OnChange(wxCommandEvent &ev) +{ + if (!process && !done) + btnOK->Enable(!txtFilename->GetValue().IsEmpty()); +} + +wxString frmBackupServer::GetCmd(int step) +{ + wxString cmd = getCmdPart1(); + + return cmd + getCmdPart2(); +} + + +wxString frmBackupServer::GetDisplayCmd(int step) +{ + wxString cmd = getCmdPart1(); + + return cmd + getCmdPart2(); +} + + +wxString frmBackupServer::getCmdPart1() +{ + pgServer *server = (pgServer *)object; + + wxString cmd = backupExecutable; + + if (!server->GetName().IsEmpty()) + cmd += wxT(" --host ") + server->GetName(); + + cmd += wxT(" --port ") + NumToStr((long)server->GetPort()) + + wxT(" --username ") + commandLineCleanOption(qtIdent(server->GetUsername())); + + if (!cbRolename->GetValue().IsEmpty()) + cmd += wxT(" --role ") + commandLineCleanOption(qtIdent(cbRolename->GetValue())); + + if (pgAppMinimumVersion(backupExecutable, 8, 4)) + cmd += wxT(" --no-password "); + + return cmd; +} + + +wxString frmBackupServer::getCmdPart2() +{ + wxString cmd; + + if (settings->GetIgnoreVersion()) + cmd.Append(wxT(" --ignore-version")); + if (chkVerbose->GetValue()) + cmd.Append(wxT(" --verbose")); + if (chkForceQuoteForIdent->GetValue()) + cmd.Append(wxT(" --quote-all-identifiers")); + + cmd.Append(wxT(" --file \"") + txtFilename->GetValue() + wxT("\"")); + + return cmd; +} + + +void frmBackupServer::Go() +{ + txtFilename->SetFocus(); + Show(true); +} + +void frmBackupServer::OnOK(wxCommandEvent &ev) +{ + if (!done) + { + if (processedFile == txtFilename->GetValue()) + { + if (wxMessageBox(_("Are you sure you wish to run a backup to this file again?"), _("Repeat backup?"), wxICON_QUESTION | wxYES_NO) != wxYES) + return; + } + else if (wxFile::Exists(txtFilename->GetValue())) + { + wxString msg; + msg.Printf(_("The file: \n\n%s\n\nalready exists. Do you want to overwrite it?"), txtFilename->GetValue().c_str()); + if (wxMessageBox(msg, _("Overwrite file?"), wxICON_WARNING | wxYES_NO) != wxYES) + return; + } + + processedFile = txtFilename->GetValue(); + } + + settings->Write(wxT("frmBackupServer/LastFile"), txtFilename->GetValue()); + ExternProcessDialog::OnOK(ev); +} + +backupServerFactory::backupServerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Backup server..."), _("Creates a backup of the entire server")); +} + + +wxWindow *backupServerFactory::StartDialog(frmMain *form, pgObject *obj) +{ + frmBackupServer *frm = new frmBackupServer(form, obj); + frm->Go(); + return 0; +} + + +bool backupServerFactory::CheckEnable(pgObject *obj) +{ + if (!obj) + return false; + + if (!((pgServer *)obj)->GetConnected() || obj->GetMetaType() != PGM_SERVER) + return false; + + if (obj->GetConnection()->EdbMinimumVersion(8, 0)) + return !edbBackupAllExecutable.IsEmpty() && pgAppMinimumVersion(edbBackupAllExecutable, 8, 3); + else if (obj->GetConnection()->GetIsGreenplum()) + return !gpBackupAllExecutable.IsEmpty() && pgAppMinimumVersion(gpBackupAllExecutable, 8, 3); + else + return !pgBackupAllExecutable.IsEmpty() && pgAppMinimumVersion(pgBackupAllExecutable, 8, 3); +} + diff --git a/frm/frmConfig.cpp b/frm/frmConfig.cpp new file mode 100644 index 0000000..d14dfe3 --- /dev/null +++ b/frm/frmConfig.cpp @@ -0,0 +1,448 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmConfig.cpp - Configuration tool +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#ifdef __WXMSW__ +#include +#include +#endif + +#include + +#include "ctl/ctlMenuToolbar.h" +#include "frm/frmConfig.h" +#include "frm/frmHint.h" +#include "frm/frmMainConfig.h" +#include "frm/frmHbaConfig.h" +#include "frm/frmPgpassConfig.h" +#include "frm/frmMain.h" +#include "frm/frmAbout.h" +#include "utils/utffile.h" +#include "db/pgConn.h" +#include "db/pgSet.h" +#include "frm/menu.h" +#include "utils/pgfeatures.h" + +#include "images/file_open.pngc" +#include "images/file_save.pngc" +#include "images/edit_undo.pngc" +#include "images/delete.pngc" +#include "images/help.pngc" +#include "images/hint2.pngc" +#include "images/checked.pngc" +#include "images/unchecked.pngc" +#include "images/query_execute.pngc" + + +BEGIN_EVENT_TABLE(frmConfig, pgFrame) + EVT_CLOSE( frmConfig::OnClose) + EVT_MENU(MNU_OPEN, frmConfig::OnOpen) + EVT_MENU(MNU_SAVE, frmConfig::OnSave) + EVT_MENU(MNU_SAVEAS, frmConfig::OnSaveAs) + EVT_MENU(MNU_EXECUTE, frmConfig::OnExecute) + EVT_MENU(MNU_HELP, frmConfig::OnHelp) + EVT_MENU(MNU_HINT, frmConfig::OnHint) +END_EVENT_TABLE() + + +wxImageList *configImageList = 0; + +frmConfig::frmConfig(frmMain *parent, const wxString &title, pgConn *_conn) + : pgFrame(parent, title) +{ + mainForm = parent; + conn = _conn; + SetStatusBarPane(-1); +} + + +frmConfig::frmConfig(const wxString &title, const wxString &configFile) + : pgFrame(NULL, title) +{ + mainForm = 0; + conn = 0; + + lastPath = configFile; + SetStatusBarPane(-1); +} + + +frmConfig::~frmConfig() +{ + if (conn) + delete conn; + if (mainForm) + mainForm->RemoveFrame(this); +} + + +void frmConfig::InitFrame(const wxChar *frameName) +{ + dlgName = frameName; + + if (!configImageList) + { + configImageList = new wxImageList(16, 16, true, 2); + configImageList->Add(*unchecked_png_ico); + configImageList->Add(*checked_png_ico); + } + + menuFactories = new menuFactoryList(); + + SetFont(settings->GetSystemFont()); + + toolBar = new ctlMenuToolbar(this, -1, wxDefaultPosition, wxDefaultSize, wxTB_FLAT | wxTB_NODIVIDER); + toolBar->SetToolBitmapSize(wxSize(16, 16)); + + fileMenu = new wxMenu(); + editMenu = new wxMenu(); + helpMenu = new wxMenu(); + recentFileMenu = new wxMenu(); + + fileMenu->Append(MNU_OPEN, _("&Open...\tCtrl-O"), _("Open a query file")); + toolBar->AddTool(MNU_OPEN, wxEmptyString, *file_open_png_bmp, _("Open file"), wxITEM_NORMAL); + + fileMenu->Append(MNU_SAVE, _("&Save\tCtrl-S"), _("Save current file")); + toolBar->AddTool(MNU_SAVE, wxEmptyString, *file_save_png_bmp, _("Save file"), wxITEM_NORMAL); + + fileMenu->Append(MNU_SAVEAS, _("Save &as..."), _("Save file under new name")); + + fileMenu->AppendSeparator(); + toolBar->AddSeparator(); + + // File Menu + + fileMenu->Append(MNU_EXECUTE, _("Reload server"), _("Reload Server to apply configuration changes.")); + toolBar->AddTool(MNU_EXECUTE, wxEmptyString, *query_execute_png_bmp, _("Reload Server to apply configuration changes."), wxITEM_NORMAL); + + fileMenu->AppendSeparator(); + toolBar->AddSeparator(); + + fileMenu->Append(MNU_RECENT, _("&Recent files"), recentFileMenu); + fileMenu->Append(MNU_EXIT, _("E&xit\tCtrl-W"), _("Exit configuration tool")); + + editMenu->Append(MNU_UNDO, _("&Undo\tCtrl-Z"), _("Undo last action"), wxITEM_NORMAL); + toolBar->AddTool(MNU_UNDO, wxEmptyString, *edit_undo_png_bmp, _("Undo last action"), wxITEM_NORMAL); + editMenu->AppendSeparator(); + editMenu->Append(MNU_DELETE, _("&Delete\tDEL"), _("Delete current row"), wxITEM_NORMAL); + toolBar->AddTool(MNU_DELETE, wxEmptyString, *delete_png_bmp, _("Delete current row"), wxITEM_NORMAL); + + toolBar->AddSeparator(); + + + helpMenu->Append(MNU_CONTENTS, _("&Help"), _("Open the helpfile.")); + + helpMenu->Append(MNU_HINT, _("Hints"), _("Display helpful hints on current object.")); + toolBar->AddTool(MNU_HINT, wxEmptyString, *hint2_png_bmp, _("Display helpful hints on current object.")); + helpMenu->Append(MNU_HELP, _("&Configuration Help\tF1"), _("Display help on configuration options.")); + helpMenu->AppendSeparator(); + + new bugReportFactory(menuFactories, helpMenu, 0); + aboutFactory *af = new aboutFactory(menuFactories, helpMenu, 0); + + menuBar = new wxMenuBar(); + menuBar->Append(fileMenu, _("&File")); + menuBar->Append(editMenu, _("&Edit")); + menuBar->Append(helpMenu, _("&Help")); + SetMenuBar(menuBar); + +#ifdef __WXMAC__ + wxApp::s_macAboutMenuItemId = af->GetId(); +#else + (void)af; +#endif + + menuFactories->RegisterMenu(this, wxCommandEventHandler(pgFrame::OnAction)); + menuFactories->CheckMenu(0, menuBar, toolBar); + + wxAcceleratorEntry entries[3]; + + entries[0].Set(wxACCEL_CTRL, (int)'O', MNU_OPEN); + entries[1].Set(wxACCEL_CTRL, (int)'S', MNU_SAVE); + entries[2].Set(wxACCEL_NORMAL, WXK_F1, MNU_HELP); + + wxAcceleratorTable accel(3, entries); + SetAcceleratorTable(accel); + + toolBar->AddTool(MNU_HELP, wxEmptyString, *help_png_bmp, _("Display help on configuration options."), wxITEM_NORMAL); + toolBar->Realize(); + + UpdateRecentFiles(); + + fileMenu->Enable(MNU_SAVE, false); + editMenu->Enable(MNU_UNDO, false); + toolBar->EnableTool(MNU_SAVE, false); + toolBar->EnableTool(MNU_UNDO, false); + + if (conn) + { + toolBar->EnableTool(MNU_OPEN, false); + if (!conn->HasFeature(FEATURE_RELOAD_CONF)) + { + fileMenu->Enable(MNU_EXECUTE, false); + toolBar->EnableTool(MNU_EXECUTE, false); + } + } + else + { + fileMenu->Enable(MNU_EXECUTE, false); + toolBar->EnableTool(MNU_EXECUTE, false); + } + + SetToolBar(toolBar); + statusBar = CreateStatusBar(); +} + + +void frmConfig::Go() +{ + Show(); +} + +void frmConfig::DoOpen(const wxString &fn) +{ + wxCommandEvent ev; + OnOpen(ev); +} + + +void frmConfig::OnClose(wxCloseEvent &event) +{ + if (CheckChanged(event.CanVeto()) && event.CanVeto()) + { + event.Veto(); + return; + } + Destroy(); +} + +void frmConfig::OnHelp(wxCommandEvent &event) +{ + DisplayHelp(GetHelpPage(), HELP_POSTGRESQL); +} + +void frmConfig::OnHint(wxCommandEvent &event) +{ + DisplayHint(true); +} + + +void frmConfig::OnBugreport(wxCommandEvent &event) +{ + DisplayHelp(wxT("bugreport"), HELP_PGADMIN); +} + + +void frmConfig::OnExecute(wxCommandEvent &event) +{ + wxMessageDialog dlg(this, _("Are you sure you want trigger the server to reload its configuration?"), + _("Reload server configuration"), wxICON_EXCLAMATION | wxYES_NO | wxNO_DEFAULT); + if (dlg.ShowModal() == wxID_YES) + { + if (conn->ExecuteVoid(wxT("SELECT pg_reload_conf()"))) + { + } + } +} + + +void frmConfig::OnOpen(wxCommandEvent &event) +{ + if (CheckChanged(true)) + return; + +#ifdef __WXMSW__ + wxFileDialog dlg(this, _("Open configuration file"), lastDir, wxT(""), + _("Configuration files (*.conf)|*.conf|All files (*.*)|*.*"), wxFD_OPEN); +#else + wxFileDialog dlg(this, _("Open configuration file"), lastDir, wxT(""), + _("Configuration files (*.conf)|*.conf|All files (*)|*"), wxFD_OPEN); +#endif + + if (dlg.ShowModal() == wxID_OK) + { + lastFilename = dlg.GetFilename(); + lastDir = dlg.GetDirectory(); + lastPath = dlg.GetPath(); + OpenLastFile(); + UpdateRecentFiles(); + } +} + + + +void frmConfig::OnSave(wxCommandEvent &event) +{ + if (!fileMenu->IsEnabled(MNU_SAVE)) + return; + + if (conn) + { + wxMessageDialog msg(this, _("If a malformed configuration is written to the server, it might show problems when restarting or reloading.\nAre you sure the configuration is correct?"), + _("Writing configuration file to server"), wxICON_EXCLAMATION | wxYES_NO | wxNO_DEFAULT); + + if (msg.ShowModal() != wxID_YES) + return; + } + WriteFile(conn); +} + + +void frmConfig::OnSaveAs(wxCommandEvent &event) +{ +#ifdef __WXMSW__ + wxFileDialog *dlg = new wxFileDialog(this, _("Save configuration file as"), lastDir, lastFilename, + _("Configuration files (*.conf)|*.conf|All files (*.*)|*.*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); +#else + wxFileDialog *dlg = new wxFileDialog(this, _("Save configuration file as"), lastDir, lastFilename, + _("Configuration files (*.conf)|*.conf|All files (*)|*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); +#endif + if (dlg->ShowModal() == wxID_OK) + { + lastFilename = dlg->GetFilename(); + lastDir = dlg->GetDirectory(); + lastPath = dlg->GetPath(); + + WriteFile(); + if (!changed) + UpdateRecentFiles(); + } + delete dlg; +} + + +void frmConfig::OpenLastFile() +{ + wxUtfFile file(lastPath, wxFile::read, wxFONTENCODING_SYSTEM); + if (file.IsOpened()) + { + wxString buffer; + file.Read(buffer); + file.Close(); + + DisplayFile(buffer); + + statusBar->SetStatusText(wxString::Format(_(" Configuration read from %s"), lastPath.c_str())); + + fileMenu->Enable(MNU_SAVE, false); + editMenu->Enable(MNU_UNDO, false); + toolBar->EnableTool(MNU_SAVE, false); + toolBar->EnableTool(MNU_UNDO, false); + } +} + + +bool frmConfig::CheckChanged(bool canVeto) +{ + if (changed && settings->GetAskSaveConfirmation()) + { + wxMessageDialog msg(this, _("The configuration is modified.\nDo you want to save changes?"), + GetTitle(), + wxYES_NO | wxNO_DEFAULT | wxICON_EXCLAMATION | + (canVeto ? wxCANCEL : 0)); + + switch (msg.ShowModal()) + { + case wxID_YES: + WriteFile(conn); + return changed; + + case wxID_CANCEL: + return true; + } + } + return false; +} + + +bool frmConfig::DoWriteFile(const wxChar *str, pgConn *conn) +{ + bool done = false; + + wxString buffer; + if (filetype != wxTextFileType_Unix) + { + buffer = wxTextBuffer::Translate(str, filetype); + str = buffer; + } + if (conn) + { + done = conn->ExecuteVoid( + wxT("SELECT pg_file_unlink('") + serverFileName + wxT(".bak');\n") + wxT("SELECT pg_file_write('") + serverFileName + wxT(".tmp', ") + + conn->qtDbString(str) + wxT(", false);\n") + wxT("SELECT pg_file_rename('") + serverFileName + wxT(".tmp', '") + + serverFileName + wxT("', '") + + serverFileName + wxT(".bak');")); + if (!done) + conn->ExecuteVoid( + wxT("SELECT pg_file_unlink('") + serverFileName + wxT(".tmp')")); + } + else + { + wxUtfFile file(lastPath, wxFile::write, wxFONTENCODING_SYSTEM); + if (file.IsOpened()) + { +#ifdef __WXMSW__ + _setmode(file.fd(), _O_BINARY); +#endif + file.Write(str); + file.Close(); + done = true; + } + } + + if (done) + { + if (conn) + statusBar->SetStatusText(wxString::Format(_(" Configuration written to %s"), conn->GetHost().c_str())); + else + statusBar->SetStatusText(wxString::Format(_(" Configuration written to %s"), lastPath.c_str())); + } + return done; +} + + +void frmConfig::DisplayHint(bool force) +{ + wxString str = GetHintString(); + if (str.IsEmpty()) + { + if (!force) + return; + str = _("No configuration setting detected that appears doubtful."); + } + + wxMessageBox(str, _("Backend Configuration Hints"), wxICON_EXCLAMATION | wxOK); +} + + +frmConfig *frmConfig ::Create(const wxString &title, const wxString &configFile, tryMode mode) +{ + frmConfig *frm = 0; + if (wxFile::Exists(configFile)) + { + if (mode == HBAFILE || configFile.Right(11) == wxT("pg_hba.conf")) + frm = new frmHbaConfig(title, configFile); + else if (mode == MAINFILE || configFile.Right(15) == wxT("postgresql.conf")) + frm = new frmMainConfig(title, configFile); + else if (mode == PGPASSFILE || configFile.Right(11) == wxT("pgpass.conf") || configFile.Right(7) == wxT(".pgpass")) + frm = new frmPgpassConfig(title, configFile); + + // unknown config file! + } + + if (frm) + frm->Go(); + + return frm; +} diff --git a/frm/frmDatabaseDesigner.cpp b/frm/frmDatabaseDesigner.cpp new file mode 100644 index 0000000..06cd55b --- /dev/null +++ b/frm/frmDatabaseDesigner.cpp @@ -0,0 +1,929 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmDatabaseDesigner.cpp - The database designer form +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include +#include + +// App headers +#include "frm/frmMain.h" +#include "frm/frmDatabaseDesigner.h" +#include "ctl/ctlMenuToolbar.h" +#include "schema/pgObject.h" +#include "schema/pgDatabase.h" +#include "ctl/ctlSQLBox.h" +#include "dlg/dlgSelectConnection.h" +#include "utils/sysSettings.h" + +// Designer headers +#include "dd/dditems/figures/ddColumnKindIcon.h" +#include "hotdraw/figures/hdPolyLineFigure.h" +#include "hotdraw/figures/hdSimpleTextFigure.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "hotdraw/figures/hdRectangleFigure.h" +#include "hotdraw/figures/hdBitmapFigure.h" +#include "hotdraw/tools/hdConnectionCreationTool.h" +#include "dd/ddmodel/ddModelBrowser.h" +#include "dd/ddmodel/ddDBReverseEngineering.h" +#include "dd/ddmodel/ddGenerationWizard.h" + +#include "dd/ddmodel/ddDatabaseDesign.h" +#include "dd/ddmodel/ddDrawingView.h" + +#include "dd/dditems/figures/ddTextTableItemFigure.h" +#include "dd/dditems/figures/ddColumnFigure.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/dditems/utilities/ddTableNameDialog.h" + +#include "dd/dditems/figures/xml/ddXmlStorage.h" + +// Icons +#include "images/ddmodel-32.pngc" +#include "images/file_new.pngc" +#include "images/table.pngc" +#include "images/ddRemoveTable2.pngc" +#include "images/continue.pngc" +#include "images/ddnewdiagram.pngc" +#include "images/ddgendiagram.pngc" +#include "images/help.pngc" +#include "images/file_save.pngc" +#include "images/file_open.pngc" +#include "images/conversion.pngc" + +BEGIN_EVENT_TABLE(frmDatabaseDesigner, pgFrame) + EVT_COMBOBOX(CTL_DDCONNECTION, frmDatabaseDesigner::OnChangeConnection) + EVT_MENU(MNU_NEW, frmDatabaseDesigner::OnNewModel) + EVT_MENU(MNU_ADDTABLE, frmDatabaseDesigner::OnAddTable) + EVT_MENU(MNU_DELETETABLE, frmDatabaseDesigner::OnDeleteTable) + EVT_MENU(MNU_ADDCOLUMN, frmDatabaseDesigner::OnAddColumn) + EVT_MENU(MNU_GENERATEDIAGRAM, frmDatabaseDesigner::OnDiagramGeneration) + EVT_MENU(MNU_GENERATEMODEL, frmDatabaseDesigner::OnModelGeneration) + EVT_MENU(MNU_SAVEMODEL, frmDatabaseDesigner::OnModelSave) + EVT_MENU(MNU_SAVEMODELAS, frmDatabaseDesigner::OnModelSaveAs) + EVT_MENU(MNU_LOADMODEL, frmDatabaseDesigner::OnModelLoad) + EVT_MENU(MNU_NEWDIAGRAM, frmDatabaseDesigner::OnAddDiagram) + EVT_MENU(MNU_DELDIAGRAM, frmDatabaseDesigner::OnDeleteDiagram) + EVT_MENU(MNU_RENDIAGRAM, frmDatabaseDesigner::OnRenameDiagram) + EVT_MENU(MNU_TOGGLEDDSQL, frmDatabaseDesigner::OnToggleSQLWindow) + EVT_MENU(MNU_TOGGLEMBROWSER, frmDatabaseDesigner::OnToggleModelBrowser) + EVT_MENU(CTL_IMPSCHEMA, frmDatabaseDesigner::OnImportSchema) + EVT_AUINOTEBOOK_PAGE_CLOSE(CTL_DDNOTEBOOK, frmDatabaseDesigner::OnDeleteDiagramTab) + EVT_AUINOTEBOOK_PAGE_CLOSED(CTL_DDNOTEBOOK, frmDatabaseDesigner::OnDeletedDiagramTab) + EVT_AUINOTEBOOK_BUTTON(CTL_DDNOTEBOOK, frmDatabaseDesigner::OnClickDiagramTab) + EVT_AUINOTEBOOK_BG_DCLICK(CTL_DDNOTEBOOK, frmDatabaseDesigner::OnAddDiagram2) + EVT_CLOSE( frmDatabaseDesigner::OnClose) +END_EVENT_TABLE() + +frmDatabaseDesigner::frmDatabaseDesigner(frmMain *form, const wxString &_title, pgConn *conn) + : pgFrame(NULL, _title) +{ + mainForm = form; + SetTitle(wxT("Database Designer")); + SetIcon(wxIcon(*ddmodel_32_png_ico)); + loading = true; + closing = false; + + RestorePosition(100, 100, 600, 500, 450, 300); + SetMinSize(wxSize(450, 300)); + + // connection + connection = conn; + + // notify wxAUI which frame to use + manager.SetManagedWindow(this); + manager.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_TRANSPARENT_DRAG); + + SetFont(settings->GetSystemFont()); + + // Set File menu + fileMenu = new wxMenu(); + fileMenu->Append(MNU_NEW, _("&New database design\tCtrl-N"), _("Create a new database design")); + fileMenu->AppendSeparator(); + fileMenu->Append(MNU_LOADMODEL, _("&Open Model..."), _("Open an existing database design from a file")); + fileMenu->Append(MNU_SAVEMODEL, _("&Save Model"), _("Save changes at database design")); + fileMenu->Append(MNU_SAVEMODELAS, _("&Save Model As..."), _("Save database design at new file")); + fileMenu->AppendSeparator(); + fileMenu->Append(CTL_IMPSCHEMA, _("&Import Tables..."), _("Import tables from database schema to database designer model")); + fileMenu->AppendSeparator(); + fileMenu->Append(MNU_EXIT, _("E&xit\tCtrl-W"), _("Exit database designer window")); + + // Set Diagram menu + diagramMenu = new wxMenu(); + diagramMenu->Append(MNU_NEWDIAGRAM, _("&New model diagram"), _("Create a new diagram")); + diagramMenu->Append(MNU_DELDIAGRAM, _("&Delete selected model diagram..."), _("Delete selected diagram")); + diagramMenu->Append(MNU_RENDIAGRAM, _("&Rename selected model diagram..."), _("Rename selected diagram")); + + // Set View menu + viewMenu = new wxMenu(); + viewMenu->AppendCheckItem(MNU_TOGGLEMBROWSER, _("&Model Browser"), _("Show / Hide Model Browser Window")); + viewMenu->AppendCheckItem(MNU_TOGGLEDDSQL, _("&SQL Window"), _("Show / Hide SQL Window")); + viewMenu->Check(MNU_TOGGLEDDSQL, true); + viewMenu->Check(MNU_TOGGLEMBROWSER, true); + + // Set Help menu + helpMenu = new wxMenu(); + helpMenu->Append(MNU_CONTENTS, _("&Help"), _("Open the helpfile.")); + helpMenu->Append(MNU_HELP, _("&SQL Help\tF1"), _("Display help on SQL commands.")); + + // Set menu bar + menuBar = new wxMenuBar(); + menuBar->Append(fileMenu, _("&File")); + menuBar->Append(diagramMenu, _("&Diagram")); + menuBar->Append(viewMenu, _("&View")); + menuBar->Append(helpMenu, _("&Help")); + SetMenuBar(menuBar); + + // Set status bar + int iWidths[6] = {0, -1, 40, 150, 80, 80}; + CreateStatusBar(6); + SetStatusBarPane(-1); + SetStatusWidths(6, iWidths); + + // Set toolbar + toolBar = new ctlMenuToolbar(this, -1, wxDefaultPosition, wxDefaultSize, wxTB_FLAT | wxTB_NODIVIDER); + toolBar->SetToolBitmapSize(wxSize(16, 16)); + toolBar->AddTool(MNU_NEW, _("New Model"), *file_new_png_bmp, _("Create new model"), wxITEM_NORMAL); + toolBar->AddTool(MNU_NEWDIAGRAM, _("New Diagram"), *ddnewdiagram_png_bmp, _("Add new diagram"), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_LOADMODEL, _("Open Model"), *file_open_png_bmp, _("Open existing model"), wxITEM_NORMAL); + toolBar->AddTool(MNU_SAVEMODEL, _("Save Model"), *file_save_png_bmp, _("Save current model"), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_ADDTABLE, _("Add Table"), *table_png_bmp, _("Add empty table to the current model"), wxITEM_NORMAL); + toolBar->AddTool(MNU_DELETETABLE, _("Delete Table"), wxBitmap(*ddRemoveTable2_png_img), _("Delete selected table"), wxITEM_NORMAL); + toolBar->AddTool(MNU_ADDCOLUMN, _("Add Column"), *table_png_bmp, _("Add new column to the selected table"), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_GENERATEMODEL, _("Generate Model"), *continue_png_bmp, _("Generate SQL for the current model"), wxITEM_NORMAL); + toolBar->AddTool(MNU_GENERATEDIAGRAM, _("Generate Diagram"), *ddgendiagram_png_bmp, _("Generate SQL for the current diagram"), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(CTL_IMPSCHEMA, _("Import Tables from database..."), *conversion_png_ico, _("Import tables from database schema to database designer model"), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_HELP, _("Help"), *help_png_bmp, _("Display help"), wxITEM_NORMAL); + toolBar->Realize(); + + // Create notebook for diagrams + diagrams = new ctlAuiNotebook(this, CTL_DDNOTEBOOK, wxDefaultPosition, wxDefaultSize, wxAUI_NB_TOP | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS | wxAUI_NB_WINDOWLIST_BUTTON | wxAUI_NB_CLOSE_ON_ALL_TABS); + + // Now, the scratchpad + sqltext = new ctlSQLBox(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxSIMPLE_BORDER | wxTE_RICH2); + + //Now, the Objects Browser + wxSizer *browserSizer = new wxBoxSizer(wxHORIZONTAL); + browserPanel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize); + + // Add the database designer + design = new ddDatabaseDesign(diagrams, this); + + // Create database model browser + modelBrowser = new ddModelBrowser(browserPanel, DD_BROWSER, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS | wxSIMPLE_BORDER, design); + design->registerBrowser(modelBrowser); + + // Set browser Sizers + browserSizer->Add(modelBrowser, 1, wxEXPAND); + browserPanel->SetSizer(browserSizer); + browserSizer->SetSizeHints(browserPanel); + + // Add view to notebook + diagrams->AddPage(design->createDiagram(diagrams, _("unnamed"), false)->getView(), _("unnamed")); + + + // Add the database selection bar and schema selector + wxSizer *connectionSizer = new wxBoxSizer(wxHORIZONTAL); + connectionPanel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, -1)); + cbConnection = new wxBitmapComboBox(connectionPanel, CTL_DDCONNECTION, wxEmptyString, wxDefaultPosition, wxSize(-1, -1), wxArrayString(), wxCB_READONLY | wxCB_DROPDOWN); + if(conn) + cbConnection->Append(conn->GetName(), CreateBitmap(GetServerColour(conn)), (void *)conn); + cbConnection->Append(_(""), wxNullBitmap, (void *) NULL); + + connectionSizer->Add(cbConnection, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 1); + connectionSizer->AddSpacer(5); + connectionPanel->SetSizer(connectionSizer); + connectionSizer->SetSizeHints(connectionPanel); + + + // Add the panes + manager.AddPane(diagrams, + wxAuiPaneInfo().Center(). + Name(wxT("sqlQuery")).Caption(_("Database Designer")). + CaptionVisible(true).CloseButton(false).MaximizeButton(true). + Dockable(true).Movable(true)); + manager.AddPane(browserPanel, + wxAuiPaneInfo().Left(). + Name(wxT("ModelBrowser")).Caption(_("Model Browser")). + CaptionVisible(true).CloseButton(true).MinimizeButton(true). + MinSize(wxSize(140, 100)).BestSize(wxSize(200, 200))); + manager.AddPane(sqltext, + wxAuiPaneInfo().Bottom(). + Name(wxT("sqlText")).Caption(_("SQL query")). + CaptionVisible(true).CloseButton(true).MaximizeButton(true).MinimizeButton(true). + MinSize(wxSize(200, 100)).BestSize(wxSize(350, 150))); + manager.AddPane(toolBar, + wxAuiPaneInfo().Top(). + Name(wxT("toolBar")).Caption(_("Tool bar")). + ToolbarPane(). + LeftDockable(false).RightDockable(false)); + manager.AddPane(connectionPanel, wxAuiPaneInfo().Name(wxT("databaseBar")) + .Caption(_("Connection bar")).ToolbarPane().Top(). + LeftDockable(false).RightDockable(false)); + + // Update the AUI manager + manager.Update(); + + //Update browser info + modelBrowser->SetSize(browserPanel->GetSize()); + + previousChanged = true; + setModelChanged(false); + SetStatusText(wxString(wxT("Ready")), 1); +} + + +frmDatabaseDesigner::~frmDatabaseDesigner() +{ + closing = true; + + // Save form's position + SavePosition(); + + // Uninitialize wxAUIManager + manager.UnInit(); + + if (mainForm) + mainForm->RemoveFrame(this); + + if(modelBrowser) + delete modelBrowser; + + if(browserPanel) + delete browserPanel; + + if(diagrams) + delete diagrams; + + if(design) + delete design; + + if (connection) + { + if (connection->IsAlive()) + delete connection; + } +} + + +void frmDatabaseDesigner::Go() +{ + cbConnection->SetSelection(0L); + + if (connection) + { + wxCommandEvent event; + OnChangeConnection(event); + } + + loading = false; + Show(true); +} + +void frmDatabaseDesigner::setModelChanged(bool value) +{ + previousChanged = changed; + changed = value; + + // optimization to avoid unneeded operations + // false changed for false don't trigger it, but false changed to true trigger it. + if (previousChanged != changed) + { + wxMenuItem *itemMenu = fileMenu->FindItem(MNU_SAVEMODEL); + + if (value) + { + itemMenu->Enable(true); + toolBar->EnableTool(MNU_SAVEMODEL, true); + setExtendedTitle(); + } + else + { + itemMenu->Enable(false); + toolBar->EnableTool(MNU_SAVEMODEL, false); + setExtendedTitle(); + } + } +} + + +void frmDatabaseDesigner::OnClose(wxCloseEvent &event) +{ + closing = true; + + // Ask what to do with old model + if (changed) + { + int answer = wxMessageBox(_("Save model changes?"), _("Confirm"), wxYES_NO | wxCANCEL); + + if (answer == wxYES) + { + if (lastFile.IsEmpty()) + { + wxFileDialog openFileDialog( this, _("Save model"), wxT(""), wxT(""), wxT("*.pgd"), + wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition); + + if (openFileDialog.ShowModal() == wxID_OK) + { + wxString path; + path.append(openFileDialog.GetDirectory()); + path.append(wxFileName::GetPathSeparator()); + path.append(openFileDialog.GetFilename()); + if(!path.Lower().Matches(wxT("*.pgd"))) + path.append(wxT(".pgd")); + lastFile = path; + } + } + + if (!lastFile.IsEmpty()) + { + design->writeXmlModel(lastFile); + setModelChanged(false); + setExtendedTitle(); + } + } + else if (answer == wxCANCEL) + { + event.Veto(); + return; + } + } + + Hide(); + Destroy(); +} + +void frmDatabaseDesigner::setExtendedTitle() +{ + wxString title = wxT("Database Design"); + wxString chgStr; + if (changed) + chgStr = wxT(" *"); + + if (lastFile.IsEmpty()) + SetTitle(title + chgStr); + else + SetTitle(title + wxT(" - [") + lastFile + wxT("]") + chgStr); +} + +void frmDatabaseDesigner::OnAddTable(wxCommandEvent &event) +{ + if (diagrams->GetPageCount() > 0) + { + hdDrawingView *view = (hdDrawingView *) diagrams->GetPage(diagrams->GetSelection()); + + ddTableNameDialog *newTableDialog = new ddTableNameDialog( + this, + wxEmptyString, + wxEmptyString, + NULL + ); + + bool done = false, existsTable; + int answer; + + do + { + answer = newTableDialog->ShowModal(); + existsTable = design->getTable(newTableDialog->GetValue1()) != NULL; + + if (answer == wxID_OK && !newTableDialog->GetValue1().IsEmpty() && !existsTable) + { + ddTableFigure *newTable = new ddTableFigure(newTableDialog->GetValue1(), + view->getIdx(), + rand() % 90 + 200, + rand() % 90 + 140); + design->addTableToView(view->getIdx(), newTable); + design->refreshDraw(view->getIdx()); + setModelChanged(true); + setExtendedTitle(); + done = true; + } + else if(existsTable && answer == wxID_OK) + { + wxMessageBox(_("You have to change the table name because there is already a table with that name in this model."), _("Table already existing"), wxICON_EXCLAMATION | wxOK); + } + } + while (answer != wxID_CANCEL && !done); + + delete newTableDialog; + } +} + +void frmDatabaseDesigner::OnDeleteTable(wxCommandEvent &event) +{ + if (diagrams->GetPageCount() > 0) + { + hdDrawingView *view = (hdDrawingView *) diagrams->GetPage(diagrams->GetSelection()); + view->getDrawing()->deleteSelectedFigures(); + setModelChanged(true); + setExtendedTitle(); + } +} + +void frmDatabaseDesigner::OnAddColumn(wxCommandEvent &event) +{ + if (diagrams->GetPageCount() > 0) + { + hdDrawingView *view = (hdDrawingView *) diagrams->GetPage(diagrams->GetSelection()); + ddTableFigure *table = design->getSelectedTable(view->getIdx()); + wxTextEntryDialog nameDialog (this, wxT("New column name"), wxT("Add a column"), wxT("NewColumn")); + int answer; + wxString tmpString; + + if (table) + { + bool again; + do + { + again = false; + answer = nameDialog.ShowModal(); + if (answer == wxID_OK) + { + tmpString = nameDialog.GetValue(); + if(table->getColByName(tmpString) == NULL) + { + table->addColumn(view->getIdx(), new ddColumnFigure(tmpString, table)); + setModelChanged(true); + setExtendedTitle(); + } + else + { + wxString msg(wxT("Error trying to add new column '")); + msg.Append(tmpString); + msg.Append(wxT("' column name already in use")); + wxMessageDialog info( this, msg , + wxT("Column name already in use"), + wxNO_DEFAULT | wxOK | wxICON_EXCLAMATION); + again = true; + info.ShowModal(); + } + + } + } + while(again); + } + view->Refresh(); + } + else + { + wxMessageBox(_("Warning about adding a column to a table without a diagram"), _("Please create a model diagram first"), wxICON_EXCLAMATION | wxOK); + } +} + + +void frmDatabaseDesigner::OnNewModel(wxCommandEvent &event) +{ + hdDrawingView *view = (hdDrawingView *) diagrams->GetPage(diagrams->GetSelection()); + + if (changed) + { + // Ask what to do with old model + int answer = wxMessageBox(_("Save model changes?"), _("Confirm"), wxYES_NO | wxCANCEL); + + if (answer == wxYES) + { + if (!lastFile.IsEmpty()) + OnModelSave(event); + else + OnModelSaveAs(event); + } + else if (answer == wxCANCEL) + return; + } + + // Clean treeview, notebook, and sql pane + design->emptyModel(); + while (diagrams->GetPageCount() > 0) + { + diagrams->RemovePage(0); + design->deleteDiagram(0); + } + sqltext->SetText(wxEmptyString); + + // Add new diagram + diagrams->AddPage(design->createDiagram(diagrams, _("unnamed"), false)->getView(), _("unnamed")); + + // Misc + lastFile = wxEmptyString; + setModelChanged(false); + setExtendedTitle(); + UpdateToolbar(); +} + +void frmDatabaseDesigner::OnDiagramGeneration(wxCommandEvent &event) +{ + wxString errors; + if(!design->validateModel(errors)) + { + wxMessageDialog dialog(this, errors , wxT("Errors detected in the database model"), wxOK | wxICON_EXCLAMATION | wxSTAY_ON_TOP); + dialog.ShowModal(); + } + else + { + hdDrawingView *view = (hdDrawingView *) diagrams->GetPage(diagrams->GetSelection()); + ddGenerationWizard *generationWizard = new ddGenerationWizard(this, design, connection); + //Set pre-select tables [diagram] + generationWizard->preSelTables = design->getDiagramTables(view->getIdx()); + //Call generation wizard + generationWizard->RunWizard(generationWizard->GetFirstPage()); + sqltext->SetText(generationWizard->DDL); + delete generationWizard; + } +} + +void frmDatabaseDesigner::OnModelGeneration(wxCommandEvent &event) +{ + wxString errors; + if(!design->validateModel(errors)) + { + wxMessageDialog dialog(this, errors , wxT("Errors detected in the database model"), wxOK | wxICON_EXCLAMATION | wxSTAY_ON_TOP); + dialog.ShowModal(); + } + else + { + ddGenerationWizard *generationWizard = new ddGenerationWizard(this, design, connection); + //Set pre-select tables [model] disable + //generationWizard->preSelTables = design->getModelTables(); + //Call generation wizard + generationWizard->RunWizard(generationWizard->GetFirstPage()); + sqltext->SetText(generationWizard->DDL); + delete generationWizard; + } +} + +void frmDatabaseDesigner::OnModelSaveAs(wxCommandEvent &event) +{ + wxFileDialog openFileDialog( this, _("Save model"), wxT(""), wxT(""), wxT("*.pgd"), + wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition); + + if (openFileDialog.ShowModal() == wxID_OK) + { + wxString path; + path.append( openFileDialog.GetDirectory() ); + path.append( wxFileName::GetPathSeparator() ); + path.append( openFileDialog.GetFilename() ); + if(!path.Lower().Matches(wxT("*.pgd"))) + path.append(wxT(".pgd")); + lastFile = path; + setModelChanged(false); + setExtendedTitle(); + design->writeXmlModel(path); + } +} + +void frmDatabaseDesigner::OnModelSave(wxCommandEvent &event) +{ + if (lastFile != wxEmptyString) + { + design->writeXmlModel(lastFile); + setModelChanged(false); + setExtendedTitle(); + } + else + { + OnModelSaveAs(event); + } +} + +void frmDatabaseDesigner::OnModelLoad(wxCommandEvent &event) +{ + if(changed) + { + // Ask what to do with old model + int answer = wxMessageBox(_("Save model changes?"), _("Confirm"), wxYES_NO | wxCANCEL); + if (answer == wxYES) + { + if (lastFile != wxEmptyString) + OnModelSave(event); + else + OnModelSaveAs(event); + } + + if(answer == wxCANCEL) + return; + } + + //Open Model + wxFileDialog openFileDialog(this, _("Open model"), wxT(""), wxT(""), wxT("*.pgd"), + wxFD_OPEN | wxFD_FILE_MUST_EXIST, wxDefaultPosition); + + if (openFileDialog.ShowModal() == wxID_OK) + { + wxString path; + path.append(openFileDialog.GetDirectory()); + path.append(wxFileName::GetPathSeparator()); + path.append(openFileDialog.GetFilename()); + if(!path.Lower().Matches(wxT("*.pgd"))) + path.append(wxT(".pgd")); + lastFile = path; + + // Clean treeview, notebook, and sql pane + design->emptyModel(); + while(diagrams->GetPageCount() > 0) + { + diagrams->RemovePage(0); + design->deleteDiagram(0); + } + sqltext->SetText(wxEmptyString); + + // Read model from xml file + design->readXmlModel(path, diagrams); + setModelChanged(false); + setExtendedTitle(); + } +} + +void frmDatabaseDesigner::OnAddDiagram(wxCommandEvent &event) +{ + wxString newName = wxGetTextFromUser(_("New Diagram Name"), _("Diagram Name"), _("unnamed"), this); + + if (!newName.IsEmpty()) + { + diagrams->AddPage(design->createDiagram(diagrams, newName, false)->getView(), newName); + setModelChanged(true); + } + + UpdateToolbar(); +} + +void frmDatabaseDesigner::OnAddDiagram2(wxAuiNotebookEvent &event) +{ + wxCommandEvent evt; + OnAddDiagram(evt); +} + +void frmDatabaseDesigner::OnDeleteDiagram(wxCommandEvent &event) +{ + hdDrawingView *view = (hdDrawingView *) diagrams->GetPage(diagrams->GetSelection()); + int diagramIndex = view->getIdx(); + diagrams->RemovePage(diagrams->GetSelection()); + design->deleteDiagram(diagramIndex); + setModelChanged(true); + + UpdateToolbar(); +} + +void frmDatabaseDesigner::OnRenameDiagram(wxCommandEvent &event) +{ + hdDrawingView *view = (hdDrawingView *) diagrams->GetPage(diagrams->GetSelection()); + int diagramIndex = view->getIdx(); + wxString msg; + msg.Printf(_("Rename diagram %s to:"), diagrams->GetPageText(diagramIndex).c_str()); + wxString name = wxGetTextFromUser(msg, _("Rename diagram..."), diagrams->GetPageText(diagramIndex), this); + if(!name.IsEmpty() && !name.IsSameAs(diagrams->GetPageText(diagramIndex), false)) + { + view->getDrawing()->setName(name); + diagrams->SetPageText(diagramIndex, name); + setModelChanged(true); + } +} + +void frmDatabaseDesigner::OnDeleteDiagramTab(wxAuiNotebookEvent &event) +{ + deletedTab = event.GetSelection(); + wxAuiNotebook *ctrl = (wxAuiNotebook *)event.GetEventObject(); + hdDrawingView *view = (hdDrawingView *) ctrl->GetPage(event.GetSelection()); + + wxString msg; + msg.Printf(_("Are you sure you want to delete diagram \"%s\" from model?"), view->getDrawing()->getName().c_str()); + int res = wxMessageBox(msg, + wxT("Delete diagram?"), + wxYES_NO | wxNO_DEFAULT, + this); + if (res != wxYES) + { + event.Veto(); + } + else + { + setModelChanged(true); + } + + UpdateToolbar(); +} + +void frmDatabaseDesigner::OnDeletedDiagramTab(wxAuiNotebookEvent &event) +{ + //don't delete view when deleting diagram because it was deleted before by EVT_AUINOTEBOOK_PAGE_CLOSE event + //option possible will be wxAuiPaneInfo().DestroyOnClose(false) but should be tried in a future + design->deleteDiagram(deletedTab, false); + UpdateToolbar(); +} + +void frmDatabaseDesigner::OnClickDiagramTab(wxAuiNotebookEvent &event) +{ +//This event is not working by unknown reason right now. + wxLogError(wxT("WTF?")); +} + +void frmDatabaseDesigner::UpdateToolbar() +{ + toolBar->EnableTool(MNU_ADDTABLE, diagrams->GetPageCount() > 0); + toolBar->EnableTool(MNU_DELETETABLE, diagrams->GetPageCount() > 0); + + if (diagrams->GetPageCount() > 0) + { + hdDrawingView *view = (hdDrawingView *) diagrams->GetPage(diagrams->GetSelection()); + ddTableFigure *table = design->getSelectedTable(view->getIdx()); + toolBar->EnableTool(MNU_ADDCOLUMN, table != NULL); + } + + toolBar->EnableTool(MNU_GENERATEMODEL, diagrams->GetPageCount() > 0); + toolBar->EnableTool(MNU_GENERATEDIAGRAM, diagrams->GetPageCount() > 0); +} + + +wxColour frmDatabaseDesigner::GetServerColour(pgConn *connection) +{ + wxColour tmp = wxNullColour; + if (mainForm != NULL) + { + ctlTree *browser = mainForm->GetBrowser(); + wxTreeItemIdValue foldercookie, servercookie; + wxTreeItemId folderitem, serveritem; + pgObject *object; + pgServer *server; + + folderitem = browser->GetFirstChild(browser->GetRootItem(), foldercookie); + while (folderitem) + { + if (browser->ItemHasChildren(folderitem)) + { + serveritem = browser->GetFirstChild(folderitem, servercookie); + while (serveritem) + { + object = browser->GetObject(serveritem); + if (object && object->IsCreatedBy(serverFactory)) + { + server = (pgServer *)object; + if (server->GetConnected() && + server->GetConnection()->GetHost() == connection->GetHost() && + server->GetConnection()->GetPort() == connection->GetPort()) + { + tmp = wxColour(server->GetColour()); + } + } + serveritem = browser->GetNextChild(folderitem, servercookie); + } + } + folderitem = browser->GetNextChild(browser->GetRootItem(), foldercookie); + } + } + return tmp; +} + +wxBitmap frmDatabaseDesigner::CreateBitmap(const wxColour &colour) +{ + const int w = 10, h = 10; + + wxMemoryDC dc; + wxBitmap bmp(w, h); + dc.SelectObject(bmp); + if (colour == wxNullColour) + dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW))); + else + dc.SetBrush(wxBrush(colour)); + dc.DrawRectangle(0, 0, w, h); + + return bmp; +} + +void frmDatabaseDesigner::OnChangeConnection(wxCommandEvent &event) +{ + // On Solaris, this event seems to get fired when the form closes(!!) + if(!IsVisible() && !loading) + return; + + unsigned int sel = cbConnection->GetSelection(); + if (sel == cbConnection->GetCount() - 1) + { + // new Connection + dlgSelectConnection dlg(this, mainForm); + int rc = dlg.Go(connection, cbConnection); + if (rc == wxID_OK) + { + bool createdNewConn; + wxString applicationname = appearanceFactory->GetLongAppName() + _(" - Database Designer"); + pgConn *newconn = dlg.CreateConn(applicationname, createdNewConn); + if (newconn && createdNewConn) + { + cbConnection->Insert(newconn->GetName(), CreateBitmap(GetServerColour(newconn)), sel); + cbConnection->SetClientData(sel, (void *)newconn); + cbConnection->SetSelection(sel); + OnChangeConnection(event); + } + else + rc = wxID_CANCEL; + } + if (rc != wxID_OK) + { + unsigned int i; + for (i = 0 ; i < sel ; i++) + { + if (cbConnection->GetClientData(i) == connection) + { + cbConnection->SetSelection(i); + break; + } + } + } + } + else + { + connection = (pgConn *)cbConnection->GetClientData(sel); + setExtendedTitle(); + } +} + +void frmDatabaseDesigner::OnImportSchema(wxCommandEvent &WXUNUSED(event)) +{ + ddDBReverseEngineering *importTableWizard = new ddDBReverseEngineering(this, design, connection); + importTableWizard->RunWizard(importTableWizard->GetFirstPage()); + delete importTableWizard; +} + +void frmDatabaseDesigner::OnToggleModelBrowser(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_TOGGLEMBROWSER)) + manager.GetPane(wxT("ModelBrowser")).Show(true); + else + manager.GetPane(wxT("ModelBrowser")).Show(false); + manager.Update(); +} + +void frmDatabaseDesigner::OnToggleSQLWindow(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_TOGGLEDDSQL)) + manager.GetPane(wxT("sqlText")).Show(true); + else + manager.GetPane(wxT("sqlText")).Show(false); + manager.Update(); +} + +/////////////////////////////////////////////////////// + + +bool databaseDesignerBaseFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->GetDatabase() && obj->GetDatabase()->GetConnected(); +} + + +wxWindow *databaseDesignerBaseFactory::StartDialogDesigner(frmMain *form, pgObject *obj, const wxString &sql) +{ + if(obj) + { + pgDatabase *db = obj->GetDatabase(); + wxString applicationname = appearanceFactory->GetLongAppName() + _(" - Database designer"); + pgConn *conn = NULL; + if(db) + { + conn = db->CreateConn(applicationname); + if (conn) + { + frmDatabaseDesigner *fd = new frmDatabaseDesigner(form, wxEmptyString, conn); + fd->Go(); + return fd; + } + } + + } + + frmDatabaseDesigner *fd = new frmDatabaseDesigner(form, wxEmptyString, NULL); + fd->Go(); + return fd; +} + + +databaseDesignerFactory::databaseDesignerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : databaseDesignerBaseFactory(list) +{ + mnu->Append(id, _("&Database Designer\tCtrl-F"), _("Create database designs")); + toolbar->AddTool(id, _("Database Designer\tCtrl-F"), wxBitmap(*ddmodel_32_png_img), _("Create database designs."), wxITEM_NORMAL); +} + + +wxWindow *databaseDesignerFactory::StartDialog(frmMain *form, pgObject *obj) +{ + wxString qry; + if (settings->GetStickySql()) + qry = obj->GetSql(form->GetBrowser()); + return StartDialogDesigner(form, obj, qry); +} diff --git a/frm/frmEditGrid.cpp b/frm/frmEditGrid.cpp new file mode 100644 index 0000000..f9a7043 --- /dev/null +++ b/frm/frmEditGrid.cpp @@ -0,0 +1,3385 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmEditGrid.cpp - Edit Grid Box +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/pgDefs.h" +#include "frm/frmMain.h" +#include "frm/menu.h" +#include "db/pgQueryThread.h" + +#include +#include + +#include "frm/frmAbout.h" +#include "frm/frmEditGrid.h" +#include "ctl/ctlMenuToolbar.h" +#include "dlg/dlgEditGridOptions.h" +#include "frm/frmHint.h" +#include "schema/pgCatalogObject.h" +#include "schema/pgTable.h" +#include "schema/pgForeignTable.h" +#include "schema/pgView.h" +#include "schema/gpExtTable.h" +#include "schema/pgPartition.h" + +// wxAUI +#include + +// Icons +#include "images/viewdata.pngc" +#include "images/storedata.pngc" +#include "images/readdata.pngc" +#include "images/delete.pngc" +#include "images/edit_undo.pngc" +#include "images/sortfilter.pngc" +#include "images/help.pngc" +#include "images/clip_copy.pngc" +#include "images/clip_paste.pngc" + +#define CTRLID_LIMITCOMBO 4226 + + +BEGIN_EVENT_TABLE(frmEditGrid, pgFrame) + EVT_ERASE_BACKGROUND( frmEditGrid::OnEraseBackground) + EVT_SIZE( frmEditGrid::OnSize) + EVT_MENU(MNU_REFRESH, frmEditGrid::OnRefresh) + EVT_MENU(MNU_DELETE, frmEditGrid::OnDelete) + EVT_MENU(MNU_SAVE, frmEditGrid::OnSave) + EVT_MENU(MNU_INCLUDEFILTER, frmEditGrid::OnIncludeFilter) + EVT_MENU(MNU_EXCLUDEFILTER, frmEditGrid::OnExcludeFilter) + EVT_MENU(MNU_REMOVEFILTERS, frmEditGrid::OnRemoveFilters) + EVT_MENU(MNU_ASCSORT, frmEditGrid::OnAscSort) + EVT_MENU(MNU_DESCSORT, frmEditGrid::OnDescSort) + EVT_MENU(MNU_REMOVESORT, frmEditGrid::OnRemoveSort) + EVT_MENU(MNU_UNDO, frmEditGrid::OnUndo) + EVT_MENU(MNU_OPTIONS, frmEditGrid::OnOptions) + EVT_MENU(MNU_HELP, frmEditGrid::OnHelp) + EVT_MENU(MNU_CONTENTS, frmEditGrid::OnContents) + EVT_MENU(MNU_COPY, frmEditGrid::OnCopy) + EVT_MENU(MNU_PASTE, frmEditGrid::OnPaste) + EVT_MENU(MNU_LIMITBAR, frmEditGrid::OnToggleLimitBar) + EVT_MENU(MNU_TOOLBAR, frmEditGrid::OnToggleToolBar) + EVT_MENU(MNU_SCRATCHPAD, frmEditGrid::OnToggleScratchPad) + EVT_MENU(MNU_DEFAULTVIEW, frmEditGrid::OnDefaultView) + EVT_MENU(MNU_CLOSE, frmEditGrid::OnClose) + EVT_CLOSE( frmEditGrid::OnCloseWindow) + EVT_KEY_DOWN( frmEditGrid::OnKey) + EVT_GRID_RANGE_SELECT( frmEditGrid::OnGridSelectCells) + EVT_GRID_SELECT_CELL( frmEditGrid::OnCellChange) + EVT_GRID_EDITOR_SHOWN( frmEditGrid::OnEditorShown) + EVT_GRID_EDITOR_HIDDEN( frmEditGrid::OnEditorHidden) + EVT_GRID_CELL_RIGHT_CLICK( frmEditGrid::OnCellRightClick) + EVT_GRID_LABEL_RIGHT_CLICK( frmEditGrid::OnLabelRightClick) + EVT_AUI_PANE_BUTTON( frmEditGrid::OnAuiUpdate) +END_EVENT_TABLE() + + +frmEditGrid::frmEditGrid(frmMain *form, const wxString &_title, pgConn *_conn, pgSchemaObject *obj, bool pkAscending) + : pgFrame(NULL, _title) +{ + closing = false; + + SetIcon(*viewdata_png_ico); + SetFont(settings->GetSystemFont()); + dlgName = wxT("frmEditGrid"); + RestorePosition(-1, -1, 600, 500, 300, 350); + connection = _conn; + mainForm = form; + thread = 0; + relkind = 0; + limit = 0; + relid = (Oid)obj->GetOid(); + editorCell = new sqlCell(); + + // notify wxAUI which frame to use + manager.SetManagedWindow(this); + manager.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_TRANSPARENT_DRAG); + + SetMinSize(wxSize(300, 350)); + + CreateStatusBar(); + SetStatusBarPane(-1); + + sqlGrid = new ctlSQLEditGrid(this, CTL_EDITGRID, wxDefaultPosition, wxDefaultSize); + sqlGrid->SetTable(0); +#ifdef __WXMSW__ + sqlGrid->SetDefaultRowSize(sqlGrid->GetDefaultRowSize() + 2, true); +#endif + + // Set up toolbar + toolBar = new ctlMenuToolbar(this, -1, wxDefaultPosition, wxDefaultSize, wxTB_FLAT | wxTB_NODIVIDER); + toolBar->SetToolBitmapSize(wxSize(16, 16)); + + toolBar->AddTool(MNU_SAVE, wxEmptyString, *storedata_png_bmp, _("Save the changed row."), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_REFRESH, wxEmptyString, *readdata_png_bmp, _("Refresh."), wxITEM_NORMAL); + toolBar->AddTool(MNU_UNDO, wxEmptyString, *edit_undo_png_bmp, _("Undo change of data."), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_COPY, wxEmptyString, *clip_copy_png_bmp, _("Copy selected lines to clipboard."), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_PASTE, wxEmptyString, *clip_paste_png_bmp, _("Paste data from the clipboard."), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_DELETE, wxEmptyString, *delete_png_bmp, _("Delete selected rows."), wxITEM_NORMAL); + toolBar->AddSeparator(); + + toolBar->AddTool(MNU_OPTIONS, wxEmptyString, *sortfilter_png_bmp, _("Sort/filter options."), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_HELP, wxEmptyString, *help_png_bmp, _("Display help on this window.")); + + toolBar->Realize(); + toolBar->EnableTool(MNU_SAVE, false); + toolBar->EnableTool(MNU_UNDO, false); + toolBar->EnableTool(MNU_DELETE, false); + + // Setup the limit bar +#ifndef __WXMAC__ + cbLimit = new wxComboBox(this, CTRLID_LIMITCOMBO, wxEmptyString, wxPoint(0, 0), wxSize(GetCharWidth() * 12, -1), wxArrayString(), wxCB_DROPDOWN); +#else + cbLimit = new wxComboBox(this, CTRLID_LIMITCOMBO, wxEmptyString, wxPoint(0, 0), wxSize(GetCharWidth() * 24, -1), wxArrayString(), wxCB_DROPDOWN); +#endif + cbLimit->Append(_("No limit")); + cbLimit->Append(_("1000 rows")); + cbLimit->Append(_("500 rows")); + cbLimit->Append(_("100 rows")); + cbLimit->SetValue(_("No limit")); + + // Finally, the scratchpad + scratchPad = new wxTextCtrl(this, -1, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxHSCROLL); + + // Menus + + // File menu + fileMenu = new wxMenu(); + fileMenu->Append(MNU_SAVE, _("&Save\tCtrl-S"), _("Save the changed row.")); + fileMenu->AppendSeparator(); + fileMenu->Append(MNU_CLOSE, _("&Close\tCtrl-W"), _("Close this window.")); + fileMenu->Enable(MNU_SAVE, false); + + // Edit menu + editMenu = new wxMenu(); + editMenu->Append(MNU_UNDO, _("&Undo\tCtrl-Z"), _("Undo change of data.")); + editMenu->AppendSeparator(); + editMenu->Append(MNU_COPY, _("&Copy\tCtrl-C"), _("Copy selected cells to clipboard.")); + editMenu->Append(MNU_PASTE, _("&Paste\tCtrl-V"), _("Paste data from the clipboard.")); + editMenu->Append(MNU_DELETE, _("&Delete"), _("Delete selected rows.")); + editMenu->Enable(MNU_UNDO, false); + editMenu->Enable(MNU_DELETE, false); + + + // View menu + viewMenu = new wxMenu(); + viewMenu->Append(MNU_REFRESH, _("&Refresh\tF5"), _("Refresh.")); + viewMenu->AppendSeparator(); + viewMenu->Append(MNU_LIMITBAR, _("&Limit bar\tCtrl-Alt-L"), _("Show or hide the row limit options bar."), wxITEM_CHECK); + viewMenu->Append(MNU_SCRATCHPAD, _("S&cratch pad\tCtrl-Alt-S"), _("Show or hide the scratch pad."), wxITEM_CHECK); + viewMenu->Append(MNU_TOOLBAR, _("&Tool bar\tCtrl-Alt-T"), _("Show or hide the tool bar."), wxITEM_CHECK); + viewMenu->AppendSeparator(); + viewMenu->Append(MNU_DEFAULTVIEW, _("&Default view\tCtrl-Alt-V"), _("Restore the default view.")); + + + // Tools menu + toolsMenu = new wxMenu(); + toolsMenu->Append(MNU_OPTIONS, _("&Sort / Filter ..."), _("Sort / Filter options.")); + toolsMenu->AppendSeparator(); + toolsMenu->Append(MNU_INCLUDEFILTER, _("Filter By &Selection"), _("Display only those rows that have this value in this column.")); + toolsMenu->Append(MNU_EXCLUDEFILTER, _("Filter E&xcluding Selection"), _("Display only those rows that do not have this value in this column.")); + toolsMenu->Append(MNU_REMOVEFILTERS, _("&Remove Filter"), _("Remove all filters on this table")); + toolsMenu->AppendSeparator(); + toolsMenu->Append(MNU_ASCSORT, _("Sort &Ascending"), _("Append an ASCENDING sort condition based on this column")); + toolsMenu->Append(MNU_DESCSORT, _("Sort &Descending"), _("Append a DESCENDING sort condition based on this column")); + toolsMenu->Append(MNU_REMOVESORT, _("&Remove Sort"), _("Remove all sort conditions")); + + // Help menu + helpMenu = new wxMenu(); + helpMenu->Append(MNU_CONTENTS, _("&Help contents"), _("Open the helpfile.")); + helpMenu->Append(MNU_HELP, _("&Edit grid help"), _("Display help on this window.")); + +#ifdef __WXMAC__ + menuFactories = new menuFactoryList(); + aboutFactory *af = new aboutFactory(menuFactories, helpMenu, 0); + wxApp::s_macAboutMenuItemId = af->GetId(); + menuFactories->RegisterMenu(this, wxCommandEventHandler(pgFrame::OnAction)); +#endif + + menuBar = new wxMenuBar(); + menuBar->Append(fileMenu, _("&File")); + menuBar->Append(editMenu, _("&Edit")); + menuBar->Append(viewMenu, _("&View")); + menuBar->Append(toolsMenu, _("&Tools")); + menuBar->Append(helpMenu, _("&Help")); + SetMenuBar(menuBar); + + // Accelerators + wxAcceleratorEntry entries[8]; + + entries[0].Set(wxACCEL_CTRL, (int)'S', MNU_SAVE); + entries[1].Set(wxACCEL_NORMAL, WXK_F5, MNU_REFRESH); + entries[2].Set(wxACCEL_CTRL, (int)'Z', MNU_UNDO); + entries[3].Set(wxACCEL_NORMAL, WXK_F1, MNU_HELP); + entries[4].Set(wxACCEL_CTRL, (int)'C', MNU_COPY); + entries[5].Set(wxACCEL_CTRL, (int)'V', MNU_PASTE); + entries[6].Set(wxACCEL_NORMAL, WXK_DELETE, MNU_DELETE); + entries[7].Set(wxACCEL_CTRL, (int)'W', MNU_CLOSE); + + wxAcceleratorTable accel(8, entries); + SetAcceleratorTable(accel); + sqlGrid->SetAcceleratorTable(accel); + + // Kickstart wxAUI + manager.AddPane(toolBar, wxAuiPaneInfo().Name(wxT("toolBar")).Caption(_("Tool bar")).ToolbarPane().Top().LeftDockable(false).RightDockable(false)); + manager.AddPane(cbLimit, wxAuiPaneInfo().Name(wxT("limitBar")).Caption(_("Limit bar")).ToolbarPane().Top().LeftDockable(false).RightDockable(false)); + manager.AddPane(sqlGrid, wxAuiPaneInfo().Name(wxT("sqlGrid")).Caption(_("Data grid")).Center().CaptionVisible(false).CloseButton(false).MinSize(wxSize(200, 100)).BestSize(wxSize(300, 200))); + manager.AddPane(scratchPad, wxAuiPaneInfo().Name(wxT("scratchPad")).Caption(_("Scratch pad")).Bottom().MinSize(wxSize(200, 100)).BestSize(wxSize(300, 150))); + + // Now load the layout + wxString perspective; + settings->Read(wxT("frmEditGrid/Perspective-") + wxString(FRMEDITGRID_PERSPECTIVE_VER), &perspective, FRMEDITGRID_DEFAULT_PERSPECTIVE); + manager.LoadPerspective(perspective, true); + + // and reset the captions for the current language + manager.GetPane(wxT("toolBar")).Caption(_("Tool bar")); + manager.GetPane(wxT("limitBar")).Caption(_("Limit bar")); + manager.GetPane(wxT("sqlGrid")).Caption(_("Data grid")); + manager.GetPane(wxT("scratchPad")).Caption(_("Scratch pad")); + + // Sync the View menu options + viewMenu->Check(MNU_LIMITBAR, manager.GetPane(wxT("limitBar")).IsShown()); + viewMenu->Check(MNU_TOOLBAR, manager.GetPane(wxT("toolBar")).IsShown()); + viewMenu->Check(MNU_SCRATCHPAD, manager.GetPane(wxT("scratchPad")).IsShown()); + + // tell the manager to "commit" all the changes just made + manager.Update(); + + autoOrderBy = false; + if (obj->GetMetaType() == PGM_TABLE || obj->GetMetaType() == GP_PARTITION) + { + pgTable *table = (pgTable *)obj; + + relkind = 'r'; + hasOids = table->GetHasOids(); + tableName = table->GetSchema()->GetQuotedFullIdentifier() + wxT(".") + table->GetQuotedIdentifier(); + primaryKeyColNumbers = table->GetPrimaryKeyColNumbers(); + autoOrderBy = true; // default order by PK/OID will be discarded when a user defines his order + orderBy = table->GetQuotedPrimaryKey(); + if (orderBy.IsEmpty() && hasOids) + orderBy = wxT("oid"); + if (!orderBy.IsEmpty()) + { + if (pkAscending) + { + orderBy.Replace(wxT(","), wxT(" ASC,")); + orderBy += wxT(" ASC"); + } + else + { + orderBy.Replace(wxT(","), wxT(" DESC,")); + orderBy += wxT(" DESC"); + } + } + } + else if (obj->GetMetaType() == PGM_VIEW) + { + pgView *view = (pgView *)obj; + + relkind = 'v'; + hasOids = false; + tableName = view->GetSchema()->GetQuotedFullIdentifier() + wxT(".") + view->GetQuotedIdentifier(); + } + else if (obj->GetMetaType() == PGM_FOREIGNTABLE) + { + pgForeignTable *foreigntable = (pgForeignTable *)obj; + + relkind = 'f'; + hasOids = false; + tableName = foreigntable->GetSchema()->GetQuotedFullIdentifier() + wxT(".") + foreigntable->GetQuotedIdentifier(); + } + else if (obj->GetMetaType() == GP_EXTTABLE) + { + gpExtTable *exttable = (gpExtTable *)obj; + + relkind = 'x'; + hasOids = false; + tableName = exttable->GetSchema()->GetQuotedFullIdentifier() + wxT(".") + exttable->GetQuotedIdentifier(); + } + else if (obj->GetMetaType() == PGM_CATALOGOBJECT) + { + pgCatalogObject *catobj = (pgCatalogObject *)obj; + + relkind = 'v'; + hasOids = false; + tableName = catobj->GetSchema()->GetQuotedFullIdentifier() + wxT(".") + catobj->GetQuotedIdentifier(); + } +} + +void frmEditGrid::OnEraseBackground(wxEraseEvent &event) +{ + event.Skip(); +} + +void frmEditGrid::OnSize(wxSizeEvent &event) +{ + event.Skip(); +} + +void frmEditGrid::OnToggleLimitBar(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_LIMITBAR)) + manager.GetPane(wxT("limitBar")).Show(true); + else + manager.GetPane(wxT("limitBar")).Show(false); + manager.Update(); +} + +void frmEditGrid::OnToggleToolBar(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_TOOLBAR)) + manager.GetPane(wxT("toolBar")).Show(true); + else + manager.GetPane(wxT("toolBar")).Show(false); + manager.Update(); +} + +void frmEditGrid::OnToggleScratchPad(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_SCRATCHPAD)) + manager.GetPane(wxT("scratchPad")).Show(true); + else + manager.GetPane(wxT("scratchPad")).Show(false); + manager.Update(); +} + +void frmEditGrid::OnAuiUpdate(wxAuiManagerEvent &event) +{ + if(event.pane->name == wxT("limitBar")) + { + viewMenu->Check(MNU_LIMITBAR, false); + } + else if(event.pane->name == wxT("toolBar")) + { + viewMenu->Check(MNU_TOOLBAR, false); + } + else if(event.pane->name == wxT("scratchPad")) + { + viewMenu->Check(MNU_SCRATCHPAD, false); + } + event.Skip(); +} + +void frmEditGrid::OnDefaultView(wxCommandEvent &event) +{ + manager.LoadPerspective(FRMEDITGRID_DEFAULT_PERSPECTIVE, true); + + // Reset the captions for the current language + manager.GetPane(wxT("toolBar")).Caption(_("Tool bar")); + manager.GetPane(wxT("limitBar")).Caption(_("Limit bar")); + manager.GetPane(wxT("sqlGrid")).Caption(_("Data grid")); + manager.GetPane(wxT("scratchPad")).Caption(_("Scratch pad")); + + // tell the manager to "commit" all the changes just made + manager.Update(); + + // Sync the View menu options + viewMenu->Check(MNU_LIMITBAR, manager.GetPane(wxT("limitBar")).IsShown()); + viewMenu->Check(MNU_TOOLBAR, manager.GetPane(wxT("toolBar")).IsShown()); + viewMenu->Check(MNU_SCRATCHPAD, manager.GetPane(wxT("scratchPad")).IsShown()); +} + +void frmEditGrid::SetSortCols(const wxString &cols) +{ + if (orderBy != cols) + { + orderBy = cols; + } +} + +void frmEditGrid::SetFilter(const wxString &filter) +{ + if (rowFilter != filter) + { + rowFilter = filter; + } +} + +void frmEditGrid::SetLimit(const int rowlimit) +{ + if (rowlimit != limit) + { + limit = rowlimit; + + if (limit <= 0) + cbLimit->SetValue(_("No limit")); + else + cbLimit->SetValue(wxString::Format(wxPLURAL("%i row", "%i rows", limit), limit)); + } +} + +void frmEditGrid::OnLabelRightClick(wxGridEvent &event) +{ + wxMenu *xmenu = new wxMenu(); + wxArrayInt rows = sqlGrid->GetSelectedRows(); + xmenu->Append(MNU_COPY, _("&Copy"), _("Copy selected cells to clipboard.")); + xmenu->Append(MNU_PASTE, _("&Paste"), _("Paste data from the clipboard.")); + xmenu->Append(MNU_DELETE, _("&Delete"), _("Delete selected rows.")); + + if ((rows.GetCount()) && (!sqlGrid->IsCurrentCellReadOnly())) + { + xmenu->Enable(MNU_COPY, true); + xmenu->Enable(MNU_DELETE, true); + xmenu->Enable(MNU_PASTE, true); + } + else + { + xmenu->Enable(MNU_COPY, false); + xmenu->Enable(MNU_DELETE, false); + xmenu->Enable(MNU_PASTE, false); + } + sqlGrid->PopupMenu(xmenu); +} + + +void frmEditGrid::OnCellRightClick(wxGridEvent &event) +{ + wxMenu *xmenu = new wxMenu(); + + // If we cannot refresh, assume there is a data thread running. We cannot + // check thread->IsRunning() as it can crash if the thread is in some + // states :-( + if (!toolBar->GetToolEnabled(MNU_REFRESH)) + return; + + sqlGrid->SetGridCursor(event.GetRow(), event.GetCol()); + + xmenu->Append(MNU_INCLUDEFILTER, _("Filter By &Selection"), _("Display only those rows that have this value in this column.")); + xmenu->Append(MNU_EXCLUDEFILTER, _("Filter E&xcluding Selection"), _("Display only those rows that do not have this value in this column.")); + xmenu->Append(MNU_REMOVEFILTERS, _("&Remove Filter"), _("Remove all filters on this table")); + xmenu->InsertSeparator(3); + xmenu->Append(MNU_ASCSORT, _("Sort &Ascending"), _("Append an ASCENDING sort condition based on this column")); + xmenu->Append(MNU_DESCSORT, _("Sort &Descending"), _("Append a DESCENDING sort condition based on this column")); + xmenu->Append(MNU_REMOVESORT, _("&Remove Sort"), _("Remove all sort conditions")); + + xmenu->Enable(MNU_INCLUDEFILTER, true); + xmenu->Enable(MNU_EXCLUDEFILTER, true); + xmenu->Enable(MNU_REMOVEFILTERS, true); + xmenu->Enable(MNU_ASCSORT, true); + xmenu->Enable(MNU_DESCSORT, true); + xmenu->Enable(MNU_REMOVESORT, true); + + sqlGrid->PopupMenu(xmenu); +} + + +void frmEditGrid::OnCellChange(wxGridEvent &event) +{ + sqlTable *table = sqlGrid->GetTable(); + bool doSkip = true; + + if (table) + { + if (table->LastRow() >= 0) + { + if (table->LastRow() != event.GetRow()) + { + doSkip = DoSave(); + } + } + else if (sqlGrid->GetGridCursorRow() != event.GetRow()) + { + toolBar->EnableTool(MNU_SAVE, false); + toolBar->EnableTool(MNU_UNDO, false); + fileMenu->Enable(MNU_SAVE, false); + editMenu->Enable(MNU_UNDO, false); + } + } + + if (doSkip) + event.Skip(); +} + + +void frmEditGrid::OnIncludeFilter(wxCommandEvent &event) +{ + int curcol = sqlGrid->GetGridCursorCol(); + int currow = sqlGrid->GetGridCursorRow(); + + if (curcol == -1 || currow == -1) + return; + + sqlTable *table = sqlGrid->GetTable(); + wxString column_label = qtIdent(table->GetColLabelValueUnformatted(curcol)); + wxString new_filter_string; + + size_t old_filter_string_length = GetFilter().Trim().Len(); + + if (old_filter_string_length > 0) + { + new_filter_string = GetFilter().Trim() + wxT(" \n AND "); + } + + if (table->IsColText(curcol)) + { + + if (sqlGrid->GetCellValue(currow, curcol).IsNull()) + { + new_filter_string += column_label + wxT(" IS NULL "); + } + else + { + + if (sqlGrid->GetCellValue(currow, curcol) == wxT("\'\'")) + { + new_filter_string += column_label + wxT(" = ''"); + } + else + { + new_filter_string += column_label + wxT(" = ") + connection->qtDbString(sqlGrid->GetCellValue(currow, curcol)) + wxT(" "); + } + } + } + else + { + + if (sqlGrid->GetCellValue(currow, curcol).IsNull()) + { + new_filter_string += column_label + wxT(" IS NULL "); + } + else + { + new_filter_string += column_label + wxT(" = ") + sqlGrid->GetCellValue(currow, curcol); + } + } + + SetFilter(new_filter_string); + + Go(); +} + + +void frmEditGrid::OnExcludeFilter(wxCommandEvent &event) +{ + int curcol = sqlGrid->GetGridCursorCol(); + int currow = sqlGrid->GetGridCursorRow(); + + if (curcol == -1 || currow == -1) + return; + + sqlTable *table = sqlGrid->GetTable(); + wxString column_label = qtIdent(table->GetColLabelValueUnformatted(curcol)); + wxString new_filter_string; + + size_t old_filter_string_length = GetFilter().Trim().Len(); + + if (old_filter_string_length > 0) + { + new_filter_string = GetFilter().Trim() + wxT(" \n AND "); + } + + if (table->IsColText(curcol)) + { + if (sqlGrid->GetCellValue(currow, curcol).IsNull()) + { + new_filter_string += column_label + wxT(" IS NOT NULL "); + } + else + { + + if (sqlGrid->GetCellValue(currow, curcol) == wxT("\'\'")) + { + new_filter_string += column_label + wxString::Format(wxT(" IS DISTINCT FROM '' ")) ; + } + else + { + new_filter_string += column_label + wxT(" IS DISTINCT FROM ") + connection->qtDbString(sqlGrid->GetCellValue(currow, curcol)) + wxT(" "); + } + } + } + else + { + + if (sqlGrid->GetCellValue(currow, curcol).IsNull()) + { + new_filter_string += column_label + wxT(" IS NOT NULL ") ; + } + else + { + new_filter_string += column_label + wxT(" IS DISTINCT FROM ") + sqlGrid->GetCellValue(currow, curcol); + } + } + + SetFilter(new_filter_string); + + Go(); +} + + +void frmEditGrid::OnRemoveFilters(wxCommandEvent &event) +{ + SetFilter(wxT("")); + + Go(); +} + + +void frmEditGrid::OnAscSort(wxCommandEvent &ev) +{ + int curcol = sqlGrid->GetGridCursorCol(); + + if (curcol == -1) + return; + + sqlTable *table = sqlGrid->GetTable(); + wxString column_label = qtIdent(table->GetColLabelValueUnformatted(curcol)); + wxString old_sort_string, new_sort_string; + + if (autoOrderBy) + { + autoOrderBy = false; + old_sort_string = wxT(""); + } + else + old_sort_string = GetSortCols().Trim(); + + if (old_sort_string.Find(column_label) == wxNOT_FOUND) + { + if (old_sort_string.Len() > 0) + new_sort_string = old_sort_string + wxT(" , "); + + new_sort_string += column_label + wxT(" ASC "); + } + else + { + if (old_sort_string.Find(column_label + wxT(" ASC")) == wxNOT_FOUND) + { + // Previous occurrence was for DESCENDING sort + new_sort_string = old_sort_string; + new_sort_string.Replace(column_label + wxT(" DESC"), column_label + wxT(" ASC")); + } + else + { + // Previous occurrence was for ASCENDING sort. Nothing to do + new_sort_string = old_sort_string; + } + } + + SetSortCols(new_sort_string); + + Go(); +} + + +void frmEditGrid::OnDescSort(wxCommandEvent &ev) +{ + int curcol = sqlGrid->GetGridCursorCol(); + + if (curcol == -1) + return; + + sqlTable *table = sqlGrid->GetTable(); + wxString column_label = qtIdent(table->GetColLabelValueUnformatted(curcol)); + wxString old_sort_string, new_sort_string; + + if (autoOrderBy) + { + autoOrderBy = false; + old_sort_string = wxT(""); + } + else + old_sort_string = GetSortCols().Trim(); + + if (old_sort_string.Find(column_label) == wxNOT_FOUND) + { + if (old_sort_string.Len() > 0) + new_sort_string = old_sort_string + wxT(" , "); + + new_sort_string += column_label + wxT(" DESC "); + } + else + { + if (old_sort_string.Find(column_label + wxT(" DESC")) == wxNOT_FOUND) + { + // Previous occurrence was for ASCENDING sort + new_sort_string = old_sort_string; + new_sort_string.Replace(column_label + wxT(" ASC"), column_label + wxT(" DESC")); + } + else + { + // Previous occurrence was for DESCENDING sort. Nothing to do + new_sort_string = old_sort_string; + } + } + + SetSortCols(new_sort_string); + + Go(); +} + + +void frmEditGrid::OnRemoveSort(wxCommandEvent &ev) +{ + SetSortCols(wxT("")); + + Go(); +} + + +void frmEditGrid::OnCopy(wxCommandEvent &ev) +{ + wxWindow *wnd = FindFocus(); + if (wnd == scratchPad) + { + scratchPad->Copy(); + } + else + { + if (editorCell->IsSet()) + { + if (wxTheClipboard->Open()) + { + if (sqlGrid->GetTable()->IsColText(sqlGrid->GetGridCursorCol())) + { + wxStyledTextCtrl *text = (wxStyledTextCtrl *)sqlGrid->GetCellEditor(sqlGrid->GetGridCursorRow(), sqlGrid->GetGridCursorCol())->GetControl(); + if (text && !text->GetSelectedText().IsEmpty()) + { + wxTheClipboard->SetData(new wxTextDataObject(text->GetSelectedText())); + SetStatusText(_("Data from one cell copied to clipboard.")); + } + } + else + { + wxTextCtrl *text = (wxTextCtrl *)sqlGrid->GetCellEditor(sqlGrid->GetGridCursorRow(), sqlGrid->GetGridCursorCol())->GetControl(); + if (text && !text->GetStringSelection().IsEmpty()) + { + wxTheClipboard->SetData(new wxTextDataObject(text->GetStringSelection())); + SetStatusText(_("Data from one cell copied to clipboard.")); + } + } + + wxTheClipboard->Close(); + } + } + else if(sqlGrid->GetNumberRows() > 0) + { + int copied; + copied = sqlGrid->Copy(); + SetStatusText(wxString::Format( + wxPLURAL("Data from %d row copied to clipboard.", "Data from %d rows copied to clipboard.", copied), + copied)); + } + } +} + + +void frmEditGrid::OnPaste(wxCommandEvent &ev) +{ + wxWindow *wnd = FindFocus(); + if (wnd == scratchPad) + { + scratchPad->Paste(); + } + else if (editorCell->IsSet()) + { + if (wxTheClipboard->Open()) + { + if (wxTheClipboard->IsSupported(wxDF_TEXT)) + { + wxTextDataObject data; + wxTheClipboard->GetData(data); + wxControl *ed = sqlGrid->GetCellEditor(editorCell->GetRow(), editorCell->GetCol())->GetControl(); + if (ed->IsKindOf(CLASSINFO(wxStyledTextCtrl))) + { + wxStyledTextCtrl *txtEd = (wxStyledTextCtrl *)ed; + txtEd->ReplaceSelection(data.GetText()); + } + else if (ed->IsKindOf(CLASSINFO(wxCheckBox))) + { + wxCheckBox *boolEd = (wxCheckBox *)ed; + + if (data.GetText().Lower() == wxT("true")) + boolEd->Set3StateValue(wxCHK_CHECKED); + else if (data.GetText().Lower() == wxT("false")) + boolEd->Set3StateValue(wxCHK_UNCHECKED); + else + boolEd->Set3StateValue(wxCHK_UNDETERMINED); + } + else if (ed->IsKindOf(CLASSINFO(wxTextCtrl))) + { + wxTextCtrl *txtEd = (wxTextCtrl *)ed; + long x, y; + txtEd->GetSelection(&x, &y); + txtEd->Replace(x, y, data.GetText()); + //txtEd->SetValue(data.GetText()); + } + } + wxTheClipboard->Close(); + } + } + else if(sqlGrid->GetNumberRows() > 0) + { + if (toolBar->GetToolEnabled(MNU_SAVE)) + { + wxMessageDialog msg(this, _("There is unsaved data in a row.\nDo you want to store to the database?"), _("Unsaved data"), + wxYES_NO | wxICON_QUESTION | wxCANCEL); + switch (msg.ShowModal()) + { + case wxID_YES: + if (!DoSave()) + return; + break; + + case wxID_CANCEL: + return; + break; + + case wxID_NO: + CancelChange(); + break; + } + } + + if (sqlGrid->GetTable()->Paste()) + { + toolBar->EnableTool(MNU_SAVE, true); + toolBar->EnableTool(MNU_UNDO, true); + fileMenu->Enable(MNU_SAVE, true); + editMenu->Enable(MNU_UNDO, true); + } + } +} + +void frmEditGrid::OnHelp(wxCommandEvent &ev) +{ + DisplayHelp(wxT("editgrid"), HELP_PGADMIN); +} + +void frmEditGrid::OnContents(wxCommandEvent &ev) +{ + DisplayHelp(wxT("index"), HELP_PGADMIN); +} + +void frmEditGrid::OnKey(wxKeyEvent &event) +{ + int curcol = sqlGrid->GetGridCursorCol(); + int currow = sqlGrid->GetGridCursorRow(); + + if (curcol == -1 || currow == -1) + return; + + int keycode = event.GetKeyCode(); + wxCommandEvent ev; + + switch (keycode) + { + case WXK_DELETE: + { + if (editorCell->IsSet() || !toolBar->GetToolEnabled(MNU_DELETE)) + { + if (!sqlGrid->IsCurrentCellReadOnly()) + { + sqlGrid->EnableCellEditControl(); + sqlGrid->ShowCellEditControl(); + + wxGridCellEditor *edit = sqlGrid->GetCellEditor(currow, curcol); + if (edit) + { + wxControl *ctl = edit->GetControl(); + if (ctl) + { + wxStyledTextCtrl *txt = wxDynamicCast(ctl, wxStyledTextCtrl); + if (txt) + txt->SetText(wxEmptyString); + } + edit->DecRef(); + } + } + } + else + { + OnDelete(ev); + } + return; + } + case WXK_RETURN: + case WXK_NUMPAD_ENTER: + // check for shift etc. + if (event.ControlDown() || event.ShiftDown()) + { + // Inject a RETURN into the control + wxGridCellEditor *edit = sqlGrid->GetCellEditor(currow, curcol); + if (edit) + { + wxControl *ctl = edit->GetControl(); + if (ctl) + { + wxStyledTextCtrl *txt = wxDynamicCast(ctl, wxStyledTextCtrl); + if (txt) + txt->ReplaceSelection(END_OF_LINE); + } + edit->DecRef(); + } + return; + } + else + { + if( keycode != WXK_NUMPAD_ENTER ) + { + // if we are at the end of the row + if (curcol == sqlGrid->GetNumberCols() - 1) + { + // we first get to the first column of the next row + curcol = 0; + currow++; + + // * if the displayed object is a table, + // we first need to make sure that the new selected + // cell is read/write, otherwise we need to select + // the next one + // * if the displayed object is not a table (for + // example, a view), all cells are readonly, so + // we skip that part + if (relkind == 'r') + { + // locate first editable column + while (curcol < sqlGrid->GetNumberCols() && sqlGrid->IsReadOnly(currow, curcol)) + curcol++; + // next line is completely read-only + if (curcol == sqlGrid->GetNumberCols()) + return; + } + } + else + curcol++; + } + else // ( keycode==WXK_NUMPAD_ENTER ) + { + currow++; + } + + OnSave(ev); + sqlGrid->SetGridCursor(currow, curcol); + + return; + } + + case WXK_TAB: + if (event.ControlDown()) + { + wxStyledTextCtrl *text = (wxStyledTextCtrl *)sqlGrid->GetCellEditor(sqlGrid->GetGridCursorRow(), sqlGrid->GetGridCursorCol())->GetControl(); + if (text) + text->SetText(wxT("\t")); + return; + } + + break; + + case WXK_ESCAPE: + CancelChange(); + break; + + default: + if (sqlGrid->IsEditable() && keycode >= WXK_SPACE && keycode < WXK_START) + { + if (sqlGrid->IsCurrentCellReadOnly()) + return; + + toolBar->EnableTool(MNU_SAVE, true); + toolBar->EnableTool(MNU_UNDO, true); + fileMenu->Enable(MNU_SAVE, true); + editMenu->Enable(MNU_UNDO, true); + } + break; + } + event.Skip(); +} + +void frmEditGrid::OnClose(wxCommandEvent &event) +{ + this->Close(); +} + +void frmEditGrid::OnCloseWindow(wxCloseEvent &event) +{ + // We need to call OnCellChange to check if some cells for the row have been changed + wxGridEvent evt; + OnCellChange(evt); + + // If MNU_SAVE item is still enabled, we need to ask about the unsaved data + if (toolBar->GetToolEnabled(MNU_SAVE)) + { + int flag = wxYES_NO | wxICON_QUESTION; + if (event.CanVeto()) + flag |= wxCANCEL; + + wxMessageDialog msg(this, _("There is unsaved data in a row.\nDo you want to store to the database?"), _("Unsaved data"), + flag); + switch (msg.ShowModal()) + { + case wxID_YES: + { + if (!DoSave()) + { + event.Veto(); + return; + } + break; + } + case wxID_CANCEL: + event.Veto(); + return; + } + } + Abort(); + Destroy(); +} + + +void frmEditGrid::OnUndo(wxCommandEvent &event) +{ + sqlGrid->DisableCellEditControl(); + sqlGrid->GetTable()->UndoLine(sqlGrid->GetGridCursorRow()); + sqlGrid->ForceRefresh(); + + toolBar->EnableTool(MNU_SAVE, false); + toolBar->EnableTool(MNU_UNDO, false); + fileMenu->Enable(MNU_SAVE, false); + editMenu->Enable(MNU_UNDO, false); +} + + +void frmEditGrid::OnRefresh(wxCommandEvent &event) +{ + if (!toolBar->GetToolEnabled(MNU_REFRESH)) + return; + + if (toolBar->GetToolEnabled(MNU_SAVE)) + { + wxMessageDialog msg(this, _("There is unsaved data in a row.\nDo you want to store to the database?"), _("Unsaved data"), + wxYES_NO | wxICON_QUESTION | wxCANCEL); + switch (msg.ShowModal()) + { + case wxID_YES: + { + if (!DoSave()) + return; + break; + } + case wxID_CANCEL: + return; + } + } + + sqlGrid->DisableCellEditControl(); + Go(); +} + + +void frmEditGrid::OnSave(wxCommandEvent &event) +{ + if (sqlGrid->GetBatchCount() == 0) + DoSave(); +} + +bool frmEditGrid::DoSave() +{ + sqlGrid->HideCellEditControl(); + sqlGrid->SaveEditControlValue(); + sqlGrid->DisableCellEditControl(); + + if (!sqlGrid->GetTable()->StoreLine()) + return false; + + toolBar->EnableTool(MNU_SAVE, false); + toolBar->EnableTool(MNU_UNDO, false); + fileMenu->Enable(MNU_SAVE, false); + editMenu->Enable(MNU_UNDO, false); + + return true; +} + +void frmEditGrid::CancelChange() +{ + sqlGrid->HideCellEditControl(); + sqlGrid->SaveEditControlValue(); + sqlGrid->DisableCellEditControl(); + + toolBar->EnableTool(MNU_SAVE, false); + toolBar->EnableTool(MNU_UNDO, false); + fileMenu->Enable(MNU_SAVE, false); + editMenu->Enable(MNU_UNDO, false); + + sqlGrid->GetTable()->UndoLine(sqlGrid->GetGridCursorRow()); + sqlGrid->ForceRefresh(); +} + + +void frmEditGrid::OnOptions(wxCommandEvent &event) +{ + if (toolBar->GetToolEnabled(MNU_SAVE)) + { + wxMessageDialog msg(this, _("There is unsaved data in a row.\nDo you want to store to the database?"), _("Unsaved data"), + wxYES_NO | wxICON_QUESTION | wxCANCEL); + switch (msg.ShowModal()) + { + case wxID_YES: + { + if (!DoSave()) + return; + break; + } + case wxID_CANCEL: + return; + case wxID_NO: + CancelChange(); + } + } + + dlgEditGridOptions *winOptions = new dlgEditGridOptions(this, connection, tableName, sqlGrid); + if (winOptions->ShowModal()) + Go(); +} + + +template < class T > +int ArrayCmp(T *a, T *b) +{ + if (*a == *b) + return 0; + + if (*a > *b) + return 1; + else + return -1; +} + +void frmEditGrid::OnDelete(wxCommandEvent &event) +{ + // Don't bugger about with keypresses to the scratch pad. + if (FindFocus() == scratchPad) + { + event.Skip(); + return; + } + + if (editorCell->IsSet()) + { + if (sqlGrid->GetTable()->IsColBoolean(sqlGrid->GetGridCursorCol())) + return; + + if (sqlGrid->GetTable()->IsColText(sqlGrid->GetGridCursorCol())) + { + wxStyledTextCtrl *text = (wxStyledTextCtrl *)sqlGrid->GetCellEditor(sqlGrid->GetGridCursorRow(), sqlGrid->GetGridCursorCol())->GetControl(); + if (text && text->GetCurrentPos() <= text->GetTextLength()) + { + if (text->GetSelectionStart() == text->GetSelectionEnd()) + text->SetSelection(text->GetSelectionStart(), text->GetSelectionStart() + 1); + text->Clear(); + } + } + else + { + wxTextCtrl *text = (wxTextCtrl *)sqlGrid->GetCellEditor(sqlGrid->GetGridCursorRow(), sqlGrid->GetGridCursorCol())->GetControl(); + if (text) + { + long x, y; + text->GetSelection(&x, &y); + if (x != y) + text->Remove(x, x + y + 1); + else + text->Remove(x, x + 1); + } + } + return; + } + + // If the delete button is disabled, don't try to delete anything + if (!toolBar->GetToolEnabled(MNU_DELETE)) + return; + + wxArrayInt delrows = sqlGrid->GetSelectedRows(); + int i = delrows.GetCount(); + + if (i == 0) + return; + + wxString prompt; + if (i == 1) + prompt = _("Are you sure you wish to delete the selected row?"); + else + prompt.Printf(_("Are you sure you wish to delete the %d selected rows?"), i); + + wxMessageDialog msg(this, prompt, _("Delete rows?"), wxYES_NO | wxICON_QUESTION); + if (msg.ShowModal() != wxID_YES) + return; + + sqlGrid->BeginBatch(); + + // Sort the grid so we always delete last->first, otherwise we + // could end up deleting anything because the array returned by + // GetSelectedRows is in the order that rows were selected by + // the user. + delrows.Sort(ArrayCmp); + + // don't care a lot about optimizing here; doing it line by line + // just as sqlTable::DeleteRows does + bool show_continue_message = true; + while (i--) + { + if (!sqlGrid->DeleteRows(delrows.Item(i), 1) && + i > 0 && + show_continue_message) + { + wxMessageDialog msg(this, wxString::Format(wxPLURAL( + "There was an error deleting the previous record.\nAre you sure you wish to delete the remaining %d row?", + "There was an error deleting the previous record.\nAre you sure you wish to delete the remaining %d rows?", + i), i), _("Delete more records ?"), wxYES_NO | wxICON_QUESTION); + if (msg.ShowModal() != wxID_YES) + break; + else + show_continue_message = false; + } + } + + + sqlGrid->EndBatch(); + + SetStatusText(wxString::Format(wxPLURAL("%d row.", "%d rows.", sqlGrid->GetTable()->GetNumberStoredRows()), sqlGrid->GetTable()->GetNumberStoredRows()), 0); +} + + +void frmEditGrid::OnEditorShown(wxGridEvent &event) +{ + toolBar->EnableTool(MNU_SAVE, true); + toolBar->EnableTool(MNU_UNDO, true); + fileMenu->Enable(MNU_SAVE, true); + editMenu->Enable(MNU_UNDO, true); + editorCell->SetCell(event.GetRow(), event.GetCol()); + + event.Skip(); +} + + +void frmEditGrid::OnEditorHidden(wxGridEvent &event) +{ + editorCell->ClearCell(); +} + + +void frmEditGrid::OnGridSelectCells(wxGridRangeSelectEvent &event) +{ + if (sqlGrid->GetEditable()) + { + wxArrayInt rows = sqlGrid->GetSelectedRows(); + + bool enable = rows.GetCount() > 0; + if (enable) + { + wxCommandEvent nullEvent; + OnSave(event); + + // check if a readonly line is selected + int row, col; + size_t i; + + for (i = 0 ; i < rows.GetCount() ; i++) + { + row = rows.Item(i); + bool lineEnabled = false; + + if (row == sqlGrid->GetNumberRows() - 1) + { + // the (*) line may not be deleted/copied + enable = false; + break; + } + for (col = 0 ; col < sqlGrid->GetNumberCols() ; col++) + { + if (!sqlGrid->IsReadOnly(row, col)) + { + lineEnabled = true; + break; + } + } + + if (!lineEnabled) + { + enable = false; + break; + } + } + } + toolBar->EnableTool(MNU_DELETE, enable); + editMenu->Enable(MNU_DELETE, enable); + } + event.Skip(); +} + + +void frmEditGrid::ShowForm(bool filter) +{ + bool abort = false; + + if (relkind == 'r' || relkind == 'v' || relkind == 'x' || relkind == 'f') + { + if (filter) + { + dlgEditGridOptions *winOptions = new dlgEditGridOptions(this, connection, tableName, sqlGrid); + abort = !(winOptions->ShowModal()); + } + if (abort) + { + // Hack to ensure there's a table for ~wxGrid() to delete + sqlGrid->CreateGrid(0, 0); + sqlGrid->SetTable(0); + Close(); + Destroy(); + } + else + { + Show(true); + Go(); + } + } + else + { + wxLogError(__("No Table or view.")); + // Hack to ensure there's a table for ~wxGrid() to delete + sqlGrid->CreateGrid(0, 0); + Close(); + Destroy(); + } +} + +void frmEditGrid::Go() +{ + long templong; + + if (cbLimit->GetValue() != wxT("") && + cbLimit->GetValue() != _("No limit") && + !cbLimit->GetValue().BeforeFirst(' ').ToLong(&templong)) + { + wxLogError(_("The row limit must be an integer number or 'No limit'")); + return; + } + + if (cbLimit->GetValue() == _("No limit")) + SetLimit(0); + else + { + cbLimit->GetValue().BeforeFirst(' ').ToLong(&templong); + SetLimit(templong); + } + + // Check we have access + if (connection->ExecuteScalar(wxT("SELECT count(*) FROM ") + tableName + wxT(" WHERE false")) == wxT("")) + return; + + SetStatusText(_("Refreshing data, please wait."), 0); + + toolBar->EnableTool(MNU_REFRESH, false); + viewMenu->Enable(MNU_REFRESH, false); + toolBar->EnableTool(MNU_OPTIONS, false); + toolsMenu->Enable(MNU_OPTIONS, false); + toolsMenu->Enable(MNU_INCLUDEFILTER, false); + toolsMenu->Enable(MNU_EXCLUDEFILTER, false); + toolsMenu->Enable(MNU_REMOVEFILTERS, false); + toolsMenu->Enable(MNU_ASCSORT, false); + toolsMenu->Enable(MNU_DESCSORT, false); + toolsMenu->Enable(MNU_REMOVESORT, false); + + wxString qry = wxT("SELECT "); + if (hasOids) + qry += wxT("oid, "); + qry += wxT("* FROM ") + tableName; + if (!rowFilter.IsEmpty()) + { + qry += wxT(" WHERE ") + rowFilter; + } + if (!orderBy.IsEmpty()) + { + qry += wxT("\n ORDER BY ") + orderBy; + } + if (limit > 0) + qry += wxT(" LIMIT ") + wxString::Format(wxT("%i"), limit); + + thread = new pgQueryThread(connection, qry); + if (thread->Create() != wxTHREAD_NO_ERROR) + { + Abort(); + toolBar->EnableTool(MNU_REFRESH, true); + viewMenu->Enable(MNU_REFRESH, true); + toolBar->EnableTool(MNU_OPTIONS, true); + toolsMenu->Enable(MNU_OPTIONS, true); + toolsMenu->Enable(MNU_INCLUDEFILTER, true); + toolsMenu->Enable(MNU_EXCLUDEFILTER, true); + toolsMenu->Enable(MNU_REMOVEFILTERS, true); + toolsMenu->Enable(MNU_ASCSORT, true); + toolsMenu->Enable(MNU_DESCSORT, true); + toolsMenu->Enable(MNU_REMOVESORT, true); + + return; + } + + thread->Run(); + + while (thread && thread->IsRunning()) + { + wxTheApp->Yield(true); + wxMilliSleep(10); + } + + // Brute force check to ensure the user didn't get bored and close the window + if (closing) + return; + + if (!thread) + { + toolBar->EnableTool(MNU_REFRESH, true); + viewMenu->Enable(MNU_REFRESH, true); + toolBar->EnableTool(MNU_OPTIONS, true); + toolsMenu->Enable(MNU_OPTIONS, true); + toolsMenu->Enable(MNU_INCLUDEFILTER, true); + toolsMenu->Enable(MNU_EXCLUDEFILTER, true); + toolsMenu->Enable(MNU_REMOVEFILTERS, true); + toolsMenu->Enable(MNU_ASCSORT, true); + toolsMenu->Enable(MNU_DESCSORT, true); + toolsMenu->Enable(MNU_REMOVESORT, true); + return; + } + + if (!thread->DataValid()) + { + Abort(); + toolBar->EnableTool(MNU_REFRESH, true); + viewMenu->Enable(MNU_REFRESH, true); + toolBar->EnableTool(MNU_OPTIONS, true); + toolsMenu->Enable(MNU_OPTIONS, true); + toolsMenu->Enable(MNU_INCLUDEFILTER, true); + toolsMenu->Enable(MNU_EXCLUDEFILTER, true); + toolsMenu->Enable(MNU_REMOVEFILTERS, true); + toolsMenu->Enable(MNU_ASCSORT, true); + toolsMenu->Enable(MNU_DESCSORT, true); + toolsMenu->Enable(MNU_REMOVESORT, true); + return; + } + + SetStatusText(wxString::Format(wxPLURAL("%d row.", "%d rows.", (int)thread->DataSet()->NumRows()), (int)thread->DataSet()->NumRows()), 0); + + sqlGrid->BeginBatch(); + + // to force the grid to create scrollbars, we make sure the size so small that scrollbars are needed + // later, we will resize the grid's parent to force the correct size (now including scrollbars, even if + // they are suppressed initially. Win32 won't need this. + // !!! This hack breaks columns auto-sizing ( GetClientSize().GetWidth() is used in ctlSQLGrid::AutoSizeColumns() ) + // !!! Is it still required? + //sqlGrid->SetSize(10, 10); + + sqlGrid->SetTable(new sqlTable(connection, thread, tableName, relid, hasOids, primaryKeyColNumbers, relkind), true); + sqlGrid->AutoSizeColumns(false); + + sqlGrid->EndBatch(); + + toolBar->EnableTool(MNU_REFRESH, true); + viewMenu->Enable(MNU_REFRESH, true); + toolBar->EnableTool(MNU_OPTIONS, true); + toolsMenu->Enable(MNU_OPTIONS, true); + toolsMenu->Enable(MNU_INCLUDEFILTER, true); + toolsMenu->Enable(MNU_EXCLUDEFILTER, true); + toolsMenu->Enable(MNU_REMOVEFILTERS, true); + toolsMenu->Enable(MNU_ASCSORT, true); + toolsMenu->Enable(MNU_DESCSORT, true); + toolsMenu->Enable(MNU_REMOVESORT, true); + + manager.Update(); + + if (!hasOids && primaryKeyColNumbers.IsEmpty() && relkind == 'r') + frmHint::ShowHint(this, HINT_READONLY_NOPK, tableName); + + // Set the thread variable to zero so we don't try to + // abort it if the user cancels now. + thread = 0; +} + + +frmEditGrid::~frmEditGrid() +{ + closing = true; + + mainForm->RemoveFrame(this); + + settings->Write(wxT("frmEditGrid/Perspective-") + wxString(FRMEDITGRID_PERSPECTIVE_VER), manager.SavePerspective()); + manager.UnInit(); + + if (connection) + delete connection; +} + + +void frmEditGrid::Abort() +{ + if (sqlGrid->GetTable()) + { + sqlGrid->HideCellEditControl(); + sqlGrid->SetTable(0); + } + + if (thread) + { + SetStatusText(_("aborting."), 0); + if (thread->IsRunning()) + { + thread->CancelExecution(); + thread->Wait(); + } + delete thread; + thread = 0; + } +} + + +ctlSQLEditGrid::ctlSQLEditGrid(wxFrame *parent, wxWindowID id, const wxPoint &pos, const wxSize &size) + : ctlSQLGrid(parent, id, pos, size) +{ +} + +bool ctlSQLEditGrid::CheckRowPresent(int row) +{ + return GetTable()->CheckInCache(row); +} + +void ctlSQLEditGrid::ResizeEditor(int row, int col) +{ + + if (GetTable()->needsResizing(col)) + { + wxGridCellAttr *attr = GetCellAttr(row, col); + wxGridCellRenderer *renderer = attr->GetRenderer(this, row, col); + if ( renderer ) + { + wxClientDC dc(GetGridWindow()); + wxSize size = renderer->GetBestSize(*this, *attr, dc, row, col); + renderer->DecRef(); + + int w = wxMax(size.GetWidth(), 15) + 20; + int h = wxMax(size.GetHeight(), 15) + 20; + + + wxGridCellEditor *editor = attr->GetEditor(this, row, col); + if (editor) + { + wxRect cellRect = CellToRect(m_currentCellCoords); + wxRect rect = cellRect; + rect.SetWidth(w); + rect.SetHeight(h); + + // we might have scrolled + CalcUnscrolledPosition(0, 0, &w, &h); + rect.SetLeft(rect.GetLeft() - w); + rect.SetTop(rect.GetTop() - h); + + // Clip rect to client size + GetClientSize(&w, &h); + rect.SetRight(wxMin(rect.GetRight(), w)); + rect.SetBottom(wxMin(rect.GetBottom(), h)); + + // but not smaller than original cell + rect.SetWidth(wxMax(cellRect.GetWidth(), rect.GetWidth())); + rect.SetHeight(wxMax(cellRect.GetHeight(), rect.GetHeight())); + + editor->SetSize(rect); + editor->DecRef(); + } + } + + attr->DecRef(); + } +} + +wxArrayInt ctlSQLEditGrid::GetSelectedRows() const +{ + wxArrayInt rows, rows2; + + wxGridCellCoordsArray tl = GetSelectionBlockTopLeft(), br = GetSelectionBlockBottomRight(); + + int maxCol = ((ctlSQLEditGrid *)this)->GetNumberCols() - 1; + size_t i; + for (i = 0 ; i < tl.GetCount() ; i++) + { + wxGridCellCoords c1 = tl.Item(i), c2 = br.Item(i); + if (c1.GetCol() != 0 || c2.GetCol() != maxCol) + return rows2; + + int j; + for (j = c1.GetRow() ; j <= c2.GetRow() ; j++) + rows.Add(j); + } + + rows2 = wxGrid::GetSelectedRows(); + + rows.Sort(ArrayCmp); + rows2.Sort(ArrayCmp); + + size_t i2 = 0, cellRowMax = rows.GetCount(); + + for (i = 0 ; i < rows2.GetCount() ; i++) + { + int row = rows2.Item(i); + while (i2 < cellRowMax && rows.Item(i2) < row) + i2++; + if (i2 == cellRowMax || row != rows.Item(i2)) + rows.Add(row); + } + + return rows; +} + + +class sqlGridTextEditor : public wxGridCellTextEditor +{ +public: + virtual wxGridCellEditor *Clone() const + { + return new sqlGridTextEditor(); + } + void Create(wxWindow *parent, wxWindowID id, wxEvtHandler *evtHandler); + void BeginEdit(int row, int col, wxGrid *grid); + + +#if wxCHECK_VERSION(2, 9, 0) + void ApplyEdit(int row, int col, wxGrid *grid); + bool EndEdit(int row, int col, const wxGrid *grid, const wxString &, wxString *); +#else + bool EndEdit(int row, int col, wxGrid *grid); +#endif + wxString GetValue() const; + virtual void Reset() + { + DoReset(m_startValue); + } + void StartingKey(wxKeyEvent &event); + +protected: + void DoBeginEdit(const wxString &startValue); + wxStyledTextCtrl *Text() const + { + return (wxStyledTextCtrl *)m_control; + } + void DoReset(const wxString &startValue); + + wxString m_startValue; +}; + + + + +void sqlGridTextEditor::Create(wxWindow *parent, wxWindowID id, wxEvtHandler *evtHandler) +{ + int flags = wxSTC_WRAP_NONE; + + m_control = new wxStyledTextCtrl(parent, id, + wxDefaultPosition, wxDefaultSize, flags + ); + + wxGridCellEditor::Create(parent, id, evtHandler); +} + + +void sqlGridTextEditor::BeginEdit(int row, int col, wxGrid *grid) +{ + m_startValue = grid->GetTable()->GetValue(row, col); + DoBeginEdit(m_startValue); + ((ctlSQLEditGrid *)grid)->ResizeEditor(row, col); +} + +void sqlGridTextEditor::DoBeginEdit(const wxString &startValue) +{ + Text()->SetMarginWidth(1, 0); + Text()->SetText(startValue); + Text()->SetCurrentPos(Text()->GetTextLength()); + Text()->SetUseHorizontalScrollBar(false); + Text()->SetUseVerticalScrollBar(false); + Text()->SetSelection(0, -1); + Text()->SetFocus(); +} + +#if wxCHECK_VERSION(2, 9, 0) +void sqlGridTextEditor::ApplyEdit(int row, int col, wxGrid *grid) +{ + wxString value = Text()->GetText(); + grid->GetTable()->SetValue(row, col, value); +} +#endif + +#if wxCHECK_VERSION(2, 9, 0) +bool sqlGridTextEditor::EndEdit(int row, int col, const wxGrid *grid, const wxString &, wxString *) +#else +bool sqlGridTextEditor::EndEdit(int row, int col, wxGrid *grid) +#endif +{ + bool changed = false; + wxString value = Text()->GetText(); + + if (value != m_startValue) + changed = true; + +#if !wxCHECK_VERSION(2, 9, 0) + if (changed) + grid->GetTable()->SetValue(row, col, value); +#endif + + return changed; +} + +wxString sqlGridTextEditor::GetValue() const +{ + return Text()->GetText(); +} + +void sqlGridTextEditor::DoReset(const wxString &startValue) +{ + Text()->SetText(startValue); + Text()->SetSelection(-1, -1); +} + +void sqlGridTextEditor::StartingKey(wxKeyEvent &event) +{ + wxChar ch; + +#if wxUSE_UNICODE + ch = event.GetUnicodeKey(); + if (ch <= 127) + ch = (wxChar)event.GetKeyCode(); +#else + ch = (wxChar)event.GetKeyCode(); +#endif + + if (ch != (wxChar)WXK_BACK) + { + Text()->SetText(ch); + Text()->GotoPos(Text()->GetLength()); + } +} + +class sqlGridNumericEditor : public wxGridCellTextEditor +{ +public: + sqlGridNumericEditor(int len = -1, int prec = -1) + { + numlen = len; + numprec = prec; + } + virtual wxGridCellEditor *Clone() const + { + return new sqlGridNumericEditor(numlen, numprec); + } + virtual void Create(wxWindow *parent, wxWindowID id, wxEvtHandler *evtHandler); + + virtual bool IsAcceptedKey(wxKeyEvent &event); + virtual void BeginEdit(int row, int col, wxGrid *grid); +#if wxCHECK_VERSION(2, 9, 0) + void ApplyEdit(int row, int col, wxGrid *grid); + bool EndEdit(int row, int col, const wxGrid *grid, const wxString &, wxString *); +#else + bool EndEdit(int row, int col, wxGrid *grid); +#endif + + virtual void Reset() + { + DoReset(m_startValue); + } + virtual void StartingKey(wxKeyEvent &event); + virtual void SetParameters(const wxString ¶ms); + +protected: + int numlen, numprec; + wxString m_startValue; + +}; + + + +void sqlGridNumericEditor::StartingKey(wxKeyEvent &event) +{ + int keycode = event.GetKeyCode(); + bool allowed = false; + + switch (keycode) + { + case WXK_DECIMAL: + case WXK_NUMPAD_DECIMAL: + case '.': + if (numprec) + allowed = true; + break; + case '+': + case WXK_ADD: + case WXK_NUMPAD_ADD: + case '-': + case WXK_SUBTRACT: + case WXK_NUMPAD_SUBTRACT: + + case WXK_NUMPAD0: + case WXK_NUMPAD1: + case WXK_NUMPAD2: + case WXK_NUMPAD3: + case WXK_NUMPAD4: + case WXK_NUMPAD5: + case WXK_NUMPAD6: + case WXK_NUMPAD7: + case WXK_NUMPAD8: + case WXK_NUMPAD9: + allowed = true; + break; + default: + if (wxIsdigit(keycode)) + allowed = true; + break; + + } + if (allowed) + wxGridCellTextEditor::StartingKey(event); + else + event.Skip(); +} + + + +bool sqlGridNumericEditor::IsAcceptedKey(wxKeyEvent &event) +{ + if ( wxGridCellEditor::IsAcceptedKey(event) ) + { + int keycode = event.GetKeyCode(); + switch ( keycode ) + { + case WXK_DECIMAL: + case WXK_NUMPAD_DECIMAL: + return (numprec != 0); + + case '+': + case WXK_ADD: + case WXK_NUMPAD_ADD: + case '-': + case WXK_SUBTRACT: + case WXK_NUMPAD_SUBTRACT: + + case WXK_NUMPAD0: + case WXK_NUMPAD1: + case WXK_NUMPAD2: + case WXK_NUMPAD3: + case WXK_NUMPAD4: + case WXK_NUMPAD5: + case WXK_NUMPAD6: + case WXK_NUMPAD7: + case WXK_NUMPAD8: + case WXK_NUMPAD9: + return true; + default: + return wxIsdigit(keycode) != 0; + } + } + + return false; +} + + + +void sqlGridNumericEditor::BeginEdit(int row, int col, wxGrid *grid) +{ + m_startValue = grid->GetTable()->GetValue(row, col); + + + wxString value = m_startValue; + // localize value here + + DoBeginEdit(value); +} + +#if wxCHECK_VERSION(2, 9, 0) +void sqlGridNumericEditor::ApplyEdit(int row, int col, wxGrid *grid) +{ + wxString value = Text()->GetValue(); + grid->GetTable()->SetValue(row, col, value); + m_startValue = wxEmptyString; + Text()->SetValue(m_startValue); +} +#endif + +#if wxCHECK_VERSION(2, 9, 0) +bool sqlGridNumericEditor::EndEdit(int row, int col, const wxGrid *grid, const wxString &, wxString *) +#else +bool sqlGridNumericEditor::EndEdit(int row, int col, wxGrid *grid) +#endif +{ + wxASSERT_MSG(m_control, + wxT("The sqlGridNumericEditor must be Created first!")); + + bool changed = false; + wxString value = Text()->GetValue(); + + // de-localize value here + + if (value != m_startValue) + changed = true; + +#if !wxCHECK_VERSION(2, 9, 0) + if (changed) + grid->GetTable()->SetValue(row, col, value); + + m_startValue = wxEmptyString; + Text()->SetValue(m_startValue); +#endif + return changed; +} + + +void sqlGridNumericEditor::SetParameters(const wxString ¶ms) +{ + if ( !params ) + { + // reset to default + numlen = -1; + numprec = -1; + } + else + { + long tmp; + if ( params.BeforeFirst(wxT(',')).ToLong(&tmp) ) + { + numlen = (int)tmp; + + if ( params.AfterFirst(wxT(',')).ToLong(&tmp) ) + { + numprec = (int)tmp; + + // skip the error message below + return; + } + } + } +} + + +void sqlGridNumericEditor::Create(wxWindow *parent, wxWindowID id, wxEvtHandler *evtHandler) +{ + m_control = new wxTextCtrl(parent, id, wxEmptyString, wxDefaultPosition, wxDefaultSize); + + wxGridCellEditor::Create(parent, id, evtHandler); + Text()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); +} + + +////////////////////////////////////////////////////////////////////// +// Bool editor +////////////////////////////////////////////////////////////////////// + +class sqlGridBoolEditor : public wxGridCellEditor +{ +public: + sqlGridBoolEditor() { } + + virtual void Create(wxWindow *parent, wxWindowID id, wxEvtHandler *evtHandler); + + virtual void SetSize(const wxRect &rect); + virtual void Show(bool show, wxGridCellAttr *attr = (wxGridCellAttr *)NULL); + + virtual bool IsAcceptedKey(wxKeyEvent &event); + virtual void BeginEdit(int row, int col, wxGrid *grid); + +#if wxCHECK_VERSION(2, 9, 0) + virtual void ApplyEdit(int row, int col, wxGrid *grid); // pure virtual in wx 2.9+, doesn't exist in prior versions + virtual bool EndEdit(int row, int col, const wxGrid *grid, const wxString &, wxString *); +#else + virtual bool EndEdit(int row, int col, wxGrid *grid); +#endif + + virtual void Reset(); + virtual void StartingClick(); + virtual void StartingKey(wxKeyEvent &event); + + virtual wxGridCellEditor *Clone() const + { + return new sqlGridBoolEditor; + } + + virtual wxString GetValue() const; + +protected: + wxCheckBox *CBox() const + { + return (wxCheckBox *)m_control; + } + +private: + wxCheckBoxState m_startValue; + + DECLARE_NO_COPY_CLASS(sqlGridBoolEditor) +}; + + +void sqlGridBoolEditor::Create(wxWindow *parent, wxWindowID id, wxEvtHandler *evtHandler) +{ + m_control = new wxCheckBox(parent, id, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxNO_BORDER | wxCHK_3STATE | wxCHK_ALLOW_3RD_STATE_FOR_USER); + + wxGridCellEditor::Create(parent, id, evtHandler); +} + +void sqlGridBoolEditor::SetSize(const wxRect &r) +{ + bool resize = false; + wxSize size = m_control->GetSize(); + wxCoord minSize = wxMin(r.width, r.height); + + // check if the checkbox is not too big/small for this cell + wxSize sizeBest = m_control->GetBestSize(); + if ( !(size == sizeBest) ) + { + // reset to default size if it had been made smaller + size = sizeBest; + + resize = true; + } + + if ( size.x >= minSize || size.y >= minSize ) + { + // leave 1 pixel margin + size.x = size.y = minSize - 2; + + resize = true; + } + + if ( resize ) + { + m_control->SetSize(size); + } + + // position it in the centre of the rectangle (TODO: support alignment?) + +#if defined(__WXGTK__) + // the checkbox without label still has some space to the right in wxGTK, + // so shift it to the right + size.x -= 8; +#elif defined(__WXMSW__) + // here too, but in other way + size.x += 1; + size.y -= 2; +#endif + + int hAlign = wxALIGN_CENTRE; + int vAlign = wxALIGN_CENTRE; + if (GetCellAttr()) + GetCellAttr()->GetAlignment(& hAlign, & vAlign); + + int x = 0, y = 0; + if (hAlign == wxALIGN_LEFT) + { + x = r.x + 2; +#ifdef __WXMSW__ + x += 2; +#endif + y = r.y + r.height / 2 - size.y / 2; + } + else if (hAlign == wxALIGN_RIGHT) + { + x = r.x + r.width - size.x - 2; + y = r.y + r.height / 2 - size.y / 2; + } + else if (hAlign == wxALIGN_CENTRE) + { + x = r.x + r.width / 2 - size.x / 2; + y = r.y + r.height / 2 - size.y / 2; + } + + m_control->Move(x, y); +} + +void sqlGridBoolEditor::Show(bool show, wxGridCellAttr *attr) +{ + m_control->Show(show); + + if ( show ) + { + wxColour colBg = attr ? attr->GetBackgroundColour() : *wxLIGHT_GREY; + CBox()->SetBackgroundColour(colBg); + } +} + +void sqlGridBoolEditor::BeginEdit(int row, int col, wxGrid *grid) +{ + wxASSERT_MSG(m_control, wxT("The sqlGridBoolEditor must be Created first!")); + + wxString value = grid->GetTable()->GetValue(row, col); + if (value == wxT("TRUE")) + m_startValue = wxCHK_CHECKED; + else if (value == wxT("FALSE")) + m_startValue = wxCHK_UNCHECKED; + else + m_startValue = wxCHK_UNDETERMINED; + + CBox()->Set3StateValue(m_startValue); + CBox()->SetFocus(); +} + +#define BOOL_EDIT_SWITCH switch (value) \ +{ \ + case wxCHK_UNCHECKED:\ + grid->GetTable()->SetValue(row, col, wxT("FALSE"));\ + break;\ + case wxCHK_CHECKED:\ + grid->GetTable()->SetValue(row, col, wxT("TRUE"));\ + break;\ + case wxCHK_UNDETERMINED:\ + grid->GetTable()->SetValue(row, col, wxEmptyString);\ + break;\ +}\ + +#if wxCHECK_VERSION(2, 9, 0) +// pure virtual in 2.9+, doesn't exist in prior versions +void sqlGridBoolEditor::ApplyEdit(int row, int col, wxGrid *grid) +{ + wxCheckBoxState value = CBox()->Get3StateValue(); + BOOL_EDIT_SWITCH +} +#endif + +#if wxCHECK_VERSION(2, 9, 0) +bool sqlGridBoolEditor::EndEdit(int row, int col, const wxGrid *grid, const wxString &, wxString *) +#else +bool sqlGridBoolEditor::EndEdit(int row, int col, wxGrid *grid) +#endif +{ + wxASSERT_MSG(m_control, wxT("The sqlGridBoolEditor must be Created first!")); + + bool changed = false; + wxCheckBoxState value = CBox()->Get3StateValue(); + if ( value != m_startValue ) + changed = true; + +#if !wxCHECK_VERSION(2, 9, 0) + if ( changed ) + { + BOOL_EDIT_SWITCH + } +#endif + + return changed; +} + +void sqlGridBoolEditor::Reset() +{ + wxASSERT_MSG(m_control, wxT("The wxGridCellEditor must be Created first!")); + + CBox()->Set3StateValue(m_startValue); +} + +void sqlGridBoolEditor::StartingClick() +{ + // We used to cycle the value on click here but + // that can lead to odd behaviour of the cell. + // Without cycling here, the checkbox is displayed + // but the user must toggle the box itself - she + // cannot just keep clicking the cell. +} + +bool sqlGridBoolEditor::IsAcceptedKey(wxKeyEvent &event) +{ + if ( wxGridCellEditor::IsAcceptedKey(event) ) + { + int keycode = event.GetKeyCode(); + switch ( keycode ) + { + case WXK_SPACE: + case '+': + case '-': + case 'n': + case 'N': + return true; + } + } + + return false; +} + +void sqlGridBoolEditor::StartingKey(wxKeyEvent &event) +{ + int keycode = event.GetKeyCode(); + wxCheckBoxState value = CBox()->Get3StateValue(); + + switch ( keycode ) + { + case WXK_SPACE: + switch (value) + { + case wxCHK_UNCHECKED: + case wxCHK_UNDETERMINED: + CBox()->Set3StateValue(wxCHK_CHECKED); + break; + case wxCHK_CHECKED: + CBox()->Set3StateValue(wxCHK_UNCHECKED); + break; + } + break; + + case '+': + CBox()->Set3StateValue(wxCHK_CHECKED); + break; + + case '-': + CBox()->Set3StateValue(wxCHK_UNCHECKED); + break; + + case 'n': + case 'N': + CBox()->Set3StateValue(wxCHK_UNDETERMINED); + break; + } +} + + +// return the value as "1" for true and the empty string for false +wxString sqlGridBoolEditor::GetValue() const +{ + + wxCheckBoxState value = CBox()->Get3StateValue(); + + switch (value) + { + case wxCHK_UNCHECKED: + return wxT("FALSE"); + break; + case wxCHK_CHECKED: + return wxT("TRUE"); + break; + case wxCHK_UNDETERMINED: + return wxEmptyString; + break; + } + return wxEmptyString; +} + +////////////////////////////////////////////////////////////////////// +// End Bool editor +////////////////////////////////////////////////////////////////////// + + +sqlTable::sqlTable(pgConn *conn, pgQueryThread *_thread, const wxString &tabName, const OID _relid, bool _hasOid, const wxString &_pkCols, char _relkind) +{ + connection = conn; + primaryKeyColNumbers = _pkCols; + relid = _relid; + relkind = _relkind; + tableName = tabName; + hasOids = _hasOid; + thread = _thread; + + rowsCached = 0; + rowsAdded = 0; + rowsStored = 0; + rowsDeleted = 0; + + + dataPool = 0; + addPool = new cacheLinePool(500); // arbitrary initial size + lastRow = -1; + int i; + lineIndex = 0; + + nRows = thread->DataSet()->NumRows(); + nCols = thread->DataSet()->NumCols(); + + columns = new sqlCellAttr[nCols]; + savedLine.cols = new wxString[nCols]; + + // Get the "real" column list, including any dropped columns, as + // key positions etc do not ignore these. + pgSet *allColsSet = connection->ExecuteSet( + wxT("SELECT attisdropped FROM pg_attribute") + wxT(" WHERE attnum > 0 AND attrelid=") + NumToStr(relid) + wxT("::oid\n") + wxT(" ORDER BY attnum")); + + int x = 1; + if (allColsSet) + { + for (i = 0; i < allColsSet->NumRows(); i++) + { + if (allColsSet->GetVal(wxT("attisdropped")) == wxT("t")) + { + colMap.Add(0); + } + else + { + colMap.Add(x); + x++; + } + allColsSet->MoveNext(); + } + delete allColsSet; + } + + pgSet *colSet = connection->ExecuteSet( + wxT("SELECT n.nspname AS nspname, relname, format_type(t.oid,NULL) AS typname, format_type(t.oid, att.atttypmod) AS displaytypname, ") + wxT("nt.nspname AS typnspname, attname, attnum, COALESCE(b.oid, t.oid) AS basetype, atthasdef, adsrc,\n") + wxT(" CASE WHEN t.typbasetype::oid=0 THEN att.atttypmod else t.typtypmod END AS typmod,\n") + wxT(" CASE WHEN t.typbasetype::oid=0 THEN att.attlen else t.typlen END AS typlen\n") + wxT(" FROM pg_attribute att\n") + wxT(" JOIN pg_type t ON t.oid=att.atttypid\n") + wxT(" JOIN pg_namespace nt ON nt.oid=t.typnamespace\n") + wxT(" JOIN pg_class c ON c.oid=attrelid\n") + wxT(" JOIN pg_namespace n ON n.oid=relnamespace\n") + wxT(" LEFT OUTER JOIN pg_type b ON b.oid=t.typbasetype\n") + wxT(" LEFT OUTER JOIN pg_attrdef def ON adrelid=attrelid AND adnum=attnum\n") + wxT(" WHERE attnum > 0 AND NOT attisdropped AND attrelid=") + NumToStr(relid) + wxT("::oid\n") + wxT(" ORDER BY attnum")); + + + + bool canInsert = false; + if (colSet) + { + if (hasOids) + { + columns[0].name = wxT("oid"); + columns[0].numeric = true; + columns[0].attr->SetReadOnly(true); + columns[0].type = PGTYPCLASS_NUMERIC; + } + + for (i = (hasOids ? 1 : 0) ; i < nCols ; i++) + { + wxGridCellEditor *editor = 0; + + columns[i].name = colSet->GetVal(wxT("attname")); + columns[i].typeName = colSet->GetVal(wxT("typname")); + columns[i].displayTypeName = colSet->GetVal(wxT("displaytypname")); + + // Special case for character datatypes. We always cast them to text to avoid + // truncation issues with casts like ::character(3) + if (columns[i].typeName == wxT("character") || columns[i].typeName == wxT("character varying") || columns[i].typeName == wxT("\"char\"")) + columns[i].typeName = wxT("text"); + + columns[i].type = (Oid)colSet->GetOid(wxT("basetype")); + if ((columns[i].type == PGOID_TYPE_INT4 || columns[i].type == PGOID_TYPE_INT8 || columns[i].type == PGOID_TYPE_INT2) + && colSet->GetBool(wxT("atthasdef"))) + { + wxString adsrc = colSet->GetVal(wxT("adsrc")); + if (adsrc == wxT("nextval('") + colSet->GetVal(wxT("relname")) + wxT("_") + columns[i].name + wxT("_seq'::text)") || + adsrc == wxT("nextval('") + colSet->GetVal(wxT("nspname")) + wxT(".") + colSet->GetVal(wxT("relname")) + wxT("_") + columns[i].name + wxT("_seq'::text)") || + adsrc == wxT("nextval('") + colSet->GetVal(wxT("relname")) + wxT("_") + columns[i].name + wxT("_seq'::regclass)") || + adsrc == wxT("nextval('") + colSet->GetVal(wxT("nspname")) + wxT(".") + colSet->GetVal(wxT("relname")) + wxT("_") + columns[i].name + wxT("_seq'::regclass)")) + { + if (columns[i].type == PGOID_TYPE_INT4) + columns[i].type = (Oid)PGOID_TYPE_SERIAL; + else if (columns[i].type == PGOID_TYPE_INT8) + columns[i].type = (Oid)PGOID_TYPE_SERIAL8; + else + columns[i].type = (Oid)PGOID_TYPE_SERIAL2; + } + } + columns[i].typlen = colSet->GetLong(wxT("typlen")); + columns[i].typmod = colSet->GetLong(wxT("typmod")); + + switch (columns[i].type) + { + case PGOID_TYPE_BOOL: + columns[i].numeric = false; + columns[i].attr->SetReadOnly(false); + editor = new sqlGridBoolEditor(); + break; + case PGOID_TYPE_INT8: + case PGOID_TYPE_SERIAL8: + SetNumberEditor(i, 20); + break; + case PGOID_TYPE_INT2: + case PGOID_TYPE_SERIAL2: + SetNumberEditor(i, 5); + break; + case PGOID_TYPE_INT4: + case PGOID_TYPE_SERIAL: + SetNumberEditor(i, 10); + break; + case PGOID_TYPE_OID: + case PGOID_TYPE_TID: + case PGOID_TYPE_XID: + case PGOID_TYPE_CID: + SetNumberEditor(i, 10); + break; + case PGOID_TYPE_FLOAT4: + case PGOID_TYPE_FLOAT8: + columns[i].numeric = true; + columns[i].attr->SetReadOnly(false); + editor = new sqlGridNumericEditor(); + break; + case PGOID_TYPE_MONEY: + columns[i].numeric = false; + columns[i].attr->SetReadOnly(false); + editor = new wxGridCellTextEditor(); + break; + case PGOID_TYPE_NUMERIC: + { + columns[i].numeric = true; + columns[i].attr->SetReadOnly(false); + int len = columns[i].size(); + int prec = columns[i].precision(); + if (prec > 0) + len -= (prec); + editor = new sqlGridNumericEditor(len, prec); + break; + } + case PGOID_TYPE_BYTEA: + columns[i].numeric = false; + columns[i].attr->SetReadOnly(true); + break; + case PGOID_TYPE_DATE: + case PGOID_TYPE_TIME: + case PGOID_TYPE_TIMETZ: + case PGOID_TYPE_TIMESTAMP: + case PGOID_TYPE_TIMESTAMPTZ: + case PGOID_TYPE_INTERVAL: + columns[i].numeric = false; + columns[i].attr->SetReadOnly(false); + editor = new sqlGridTextEditor(); + break; + case PGOID_TYPE_CHAR: + case PGOID_TYPE_NAME: + case PGOID_TYPE_TEXT: + default: + columns[i].numeric = false; + columns[i].attr->SetReadOnly(false); + columns[i].needResize = true; + editor = new sqlGridTextEditor(); + break; + } + if (editor) + columns[i].attr->SetEditor(editor); + + if (relkind != 'r' || (!hasOids && primaryKeyColNumbers.IsNull())) + { + // for security reasons, we need oid or pk to enable updates. If none is available, + // the table definition can be considered faulty. + columns[i].attr->SetReadOnly(true); + } + if (!columns[i].attr->IsReadOnly()) + canInsert = true; + + wxStringTokenizer collist(primaryKeyColNumbers, wxT(",")); + long cn = 0; + long attnum = colSet->GetLong(wxT("attnum")); + + while (cn < attnum && collist.HasMoreTokens()) + { + cn = StrToLong(collist.GetNextToken()); + if (cn == attnum) + columns[i].isPrimaryKey = true; + } + + colSet->MoveNext(); + } + delete colSet; + } + else + { + // um, we never should reach here because this would mean + // that datatypes are unreadable. + // *if* we reach here, namespace info is missing. + for (i = 0 ; i < nCols ; i++) + { + columns[i].typeName = thread->DataSet()->ColType(i); + columns[i].name = thread->DataSet()->ColName(i); + } + } + + if (nRows) + { + dataPool = new cacheLinePool(nRows); + lineIndex = new int[nRows]; + for (i = 0 ; i < nRows ; i++) + lineIndex[i] = i; + } + + if (canInsert) + { + // an empty line waiting for inserts + rowsAdded = 1; + } +} + + +sqlTable::~sqlTable() +{ + if (thread) + delete thread; + if (dataPool) + delete dataPool; + + delete addPool; + + delete[] columns; + + if (lineIndex) + delete[] lineIndex; +} + + +int sqlTable::GetNumberCols() +{ + return nCols; +} + + +int sqlTable::GetNumberRows() +{ + return nRows + rowsAdded - rowsDeleted; +} + + +int sqlTable::GetNumberStoredRows() +{ + return nRows + rowsStored - rowsDeleted; +} + + +bool ctlSQLEditGrid::IsColText(int col) +{ + return GetTable()->IsColText(col); +} + +bool sqlTable::IsColText(int col) +{ + return !columns[col].numeric && !(columns[col].type == PGOID_TYPE_BOOL); +} + +bool sqlTable::IsColBoolean(int col) +{ + return (columns[col].type == PGOID_TYPE_BOOL); +} + +wxString sqlTable::GetColLabelValue(int col) +{ + wxString label = columns[col].name + wxT("\n"); + if (columns[col].isPrimaryKey) + label += wxT("[PK] "); + + switch (columns[col].type) + { + case (Oid)PGOID_TYPE_SERIAL: + label += wxT("serial"); + break; + case (Oid)PGOID_TYPE_SERIAL8: + label += wxT("bigserial"); + break; + case (Oid)PGOID_TYPE_SERIAL2: + label += wxT("smallserial"); + break; + default: + label += columns[col].displayTypeName; + break; + } + return label; +} + + +wxString sqlTable::GetColLabelValueUnformatted(int col) +{ + return columns[col].name; +} + + +wxString sqlTable::GetRowLabelValue(int row) +{ + wxString label; + if (row < nRows - rowsDeleted || GetLine(row)->stored) + label.Printf(wxT("%d"), row + 1); + else + label = wxT("*"); + return label; +} + + + +void sqlTable::SetNumberEditor(int col, int len) +{ + columns[col].numeric = true; + columns[col].attr->SetReadOnly(false); + columns[col].attr->SetEditor(new sqlGridNumericEditor(len, 0)); +} + + +bool sqlTable::CheckInCache(int row) +{ + if (row > nRows - rowsDeleted + rowsAdded) + return false; + if (row >= nRows - rowsDeleted) + return true; + + return dataPool->IsFilled(row); +} + + +cacheLine *sqlTable::GetLine(int row) +{ + cacheLine *line; + if (row < nRows - rowsDeleted) + line = dataPool->Get(lineIndex[row]); + else + line = addPool->Get(row - (nRows - rowsDeleted)); + + return line; +} + + + +wxString sqlTable::MakeKey(cacheLine *line) +{ + wxString whereClause; + if (!primaryKeyColNumbers.IsEmpty()) + { + wxStringTokenizer collist(primaryKeyColNumbers, wxT(",")); + long cn; + int offset; + + if (hasOids) + offset = 0; + else + offset = 1; + + while (collist.HasMoreTokens()) + { + cn = StrToLong(collist.GetNextToken()); + + // Translate the column location to the real location in the actual columns still present + cn = colMap[cn - 1]; + + wxString colval = line->cols[cn - offset]; + if (colval.IsEmpty()) + return wxEmptyString; + + if (colval == wxT("''") && columns[cn - offset].typeName == wxT("text")) + colval = wxEmptyString; + + if (!whereClause.IsEmpty()) + whereClause += wxT(" AND "); + whereClause += qtIdent(columns[cn - offset].name) + wxT(" = ") + connection->qtDbString(colval); + + if (columns[cn - offset].typeName != wxT("")) + { + whereClause += wxT("::"); + whereClause += columns[cn - offset].displayTypeName; + } + } + } + else if (hasOids) + whereClause = wxT("oid = ") + line->cols[0]; + + return whereClause; +} + + + +void sqlTable::UndoLine(int row) +{ + if (lastRow >= 0 && row >= 0) + { + cacheLine *line = GetLine(row); + if (line) + { + int i; + for (i = 0 ; i < nCols ; i++) + line->cols[i] = savedLine.cols[i]; + ctlMenuToolbar *tb = (ctlMenuToolbar *)((wxFrame *)GetView()->GetParent())->GetToolBar(); + if (tb) + { + tb->EnableTool(MNU_SAVE, false); + tb->EnableTool(MNU_UNDO, false); + } + wxMenu *fm = ((frmEditGrid *)GetView()->GetParent())->GetFileMenu(); + if (fm) + fm->Enable(MNU_SAVE, false); + wxMenu *em = ((frmEditGrid *)GetView()->GetParent())->GetEditMenu(); + if (em) + em->Enable(MNU_UNDO, false); + } + } + lastRow = -1; +} + + +bool sqlTable::StoreLine() +{ + bool done = false; + + GetView()->BeginBatch(); + if (lastRow >= 0) + { + cacheLine *line = GetLine(lastRow); + + int i; + wxString colList, valList; + + if (line->stored) + { + // UPDATE + + for (i = (hasOids ? 1 : 0) ; i < nCols ; i++) + { + if (savedLine.cols[i] != line->cols[i]) + { + if (!valList.IsNull()) + valList += wxT(", "); + valList += qtIdent(columns[i].name) + wxT("=") + columns[i].Quote(connection, line->cols[i]); + } + } + + if (valList.IsEmpty()) + done = true; + else + { + wxString key = MakeKey(&savedLine); + wxASSERT(!key.IsEmpty()); + done = connection->ExecuteVoid(wxT( + "UPDATE ") + tableName + wxT( + " SET ") + valList + wxT( + " WHERE ") + key); + } + } + else + { + // INSERT + + for (i = 0 ; i < nCols ; i++) + { + if (!columns[i].attr->IsReadOnly() && !line->cols[i].IsEmpty()) + { + if (!colList.IsNull()) + { + valList += wxT(", "); + colList += wxT(", "); + } + colList += qtIdent(columns[i].name); + + valList += columns[i].Quote(connection, line->cols[i]); + } + } + + if (!valList.IsEmpty()) + { + pgSet *set = connection->ExecuteSet( + wxT("INSERT INTO ") + tableName + + wxT("(") + colList + + wxT(") VALUES (") + valList + + wxT(")")); + if (set) + { + if (set->GetInsertedCount() > 0) + { + if (hasOids) + line->cols[0] = NumToStr((long)set->GetInsertedOid()); + delete set; + + done = true; + rowsStored++; + ((wxFrame *)GetView()->GetParent())->SetStatusText(wxString::Format(wxT("%d rows."), GetNumberStoredRows())); + if (rowsAdded == rowsStored) + GetView()->AppendRows(); + + // Read back what we inserted to get default vals + wxString key = MakeKey(line); + + if (key.IsEmpty()) + { + // That's a problem: obviously, the key generated isn't present + // because it's serial or default or otherwise generated in the backend + // we don't get. + // That's why the whole line is declared readonly. + + line->readOnly = true; + } + else + { + set = connection->ExecuteSet( + wxT("SELECT * FROM ") + tableName + + wxT(" WHERE ") + key); + if (set) + { + for (i = (hasOids ? 1 : 0) ; i < nCols ; i++) + { + line->cols[i] = set->GetVal(columns[i].name); + } + delete set; + } + } + } + } + } + } + if (done) + { + line->stored = true; + lastRow = -1; + } + else + GetView()->SelectRow(lastRow); + } + + GetView()->EndBatch(); + + return done; +} + + +void sqlTable::SetValue(int row, int col, const wxString &value) +{ + cacheLine *line = GetLine(row); + + if (!line) + { + // Bad problem, no line! + return; + } + + + if (row != lastRow) + { + if (lastRow >= 0) + StoreLine(); + + if (!line->cols) + line->cols = new wxString[nCols]; + + // remember line contents for later reference in update ... where + int i; + for (i = 0 ; i < nCols ; i++) + savedLine.cols[i] = line->cols[i]; + lastRow = row; + } + ctlMenuToolbar *tb = (ctlMenuToolbar *)((wxFrame *)GetView()->GetParent())->GetToolBar(); + if (tb) + { + tb->EnableTool(MNU_SAVE, true); + tb->EnableTool(MNU_UNDO, true); + } + wxMenu *fm = ((frmEditGrid *)GetView()->GetParent())->GetFileMenu(); + if (fm) + fm->Enable(MNU_SAVE, true); + wxMenu *em = ((frmEditGrid *)GetView()->GetParent())->GetEditMenu(); + if (em) + em->Enable(MNU_UNDO, true); + line->cols[col] = value; +} + + + +wxString sqlTable::GetValue(int row, int col) +{ + wxString val; + cacheLine *line; + if (row < nRows - rowsDeleted) + line = dataPool->Get(lineIndex[row]); + else + line = addPool->Get(row - (nRows - rowsDeleted)); + + if (!line) + { + // Bad problem, no line! + return val; + } + + if (!line->cols) + { + line->cols = new wxString[nCols]; + if (row < nRows - rowsDeleted) + { + if (!thread) + { + wxLogError(__("Unexpected empty cache line: dataSet already closed.")); + return val; + } + + line->stored = true; + if (lineIndex[row] != thread->DataSet()->CurrentPos() - 1) + thread->DataSet()->Locate(lineIndex[row] + 1); + + int i; + for (i = 0 ; i < nCols ; i++) + { + wxString val; + if (thread->DataSet()->ColType(i) == wxT("bytea")) + val = _(""); + else + { + val = thread->DataSet()->GetVal(i); + if (val.IsEmpty()) + { + if (!thread->DataSet()->IsNull(i)) + val = wxT("''"); + } + else if (val == wxT("''")) + val = wxT("\\'\\'"); + } + line->cols[i] = val; + } + rowsCached++; + + if (rowsCached == nRows) + { + delete thread; + thread = 0; + } + } + } + if (columns[col].type == PGOID_TYPE_BOOL) + { + if (line->cols[col] != wxEmptyString) + line->cols[col] = (StrToBool(line->cols[col]) ? wxT("TRUE") : wxT("FALSE")); + } + + val = line->cols[col]; + return val; +} + +bool sqlTable::AppendRows(size_t rows) +{ + rowsAdded += rows; + GetLine(nRows + rowsAdded - rowsDeleted - 1); + + wxGridTableMessage msg(this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, rows); + GetView()->ProcessTableMessage(msg); + + return true; +} + + +bool sqlTable::DeleteRows(size_t pos, size_t rows) +{ + size_t i = pos; + size_t rowsDone = 0; + + while (i < pos + rows) + { + cacheLine *line = GetLine(pos); + if (!line) + break; + + // If line->cols is null, it probably means we need to force the cacheline to be populated. + if (!line->cols) + { + GetValue(pos, 0); + line = GetLine(pos); + } + + if (line->stored) + { + wxString key = MakeKey(line); + wxASSERT(!key.IsEmpty()); + bool done = connection->ExecuteVoid(wxT( + "DELETE FROM ") + tableName + wxT(" WHERE ") + key); + if (!done) + break; + + if ((int)pos < nRows - rowsDeleted) + { + rowsDeleted++; + if ((int)pos < nRows - rowsDeleted) + memmove(lineIndex + pos, lineIndex + pos + 1, sizeof(*lineIndex) * (nRows - rowsDeleted - pos)); + } + else + { + rowsAdded--; + if (GetLine(pos)->stored) + rowsStored--; + addPool->Delete(pos - (nRows - rowsDeleted)); + } + rowsDone++; + } + else + { + // last empty line won't be deleted, just cleared + int j; + for (j = 0 ; j < nCols ; j++) + line->cols[j] = wxT(""); + } + i++; + } + + if (rowsDone > 0 && GetView()) + { + wxGridTableMessage msg(this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, pos, rowsDone); + GetView()->ProcessTableMessage(msg); + } + return (rowsDone != 0); +} + + +bool sqlTable::Paste() +{ + int row, col; + int start, pos, len; + wxArrayString data; + wxString text, quoteChar, colSep; + bool inQuotes, inData, skipSerial; + + if (!this) + return false; + + if (wxTheClipboard->Open()) + { + if (wxTheClipboard->IsSupported(wxDF_TEXT)) + { + wxTextDataObject textData; + wxTheClipboard->GetData(textData); + text = textData.GetText(); + } + else + { + wxTheClipboard->Close(); + return false; + } + wxTheClipboard->Close(); + } + else + { + return false; + } + + start = pos = 0; + len = text.Len(); + quoteChar = settings->GetCopyQuoteChar(); + colSep = settings->GetCopyColSeparator(); + inQuotes = inData = false; + + while (pos < len && !(text[pos] == '\n' && !inQuotes)) + { + if (!inData) + { + if (text[pos] == quoteChar) + { + inQuotes = inData = true; + pos++; + start++; + continue; + } + else + { + inQuotes = false; + } + inData = true; + } + + if (inQuotes && text[pos] == quoteChar && + (text[pos + 1] == colSep || text[pos + 1] == '\r' || text[pos + 1] == '\n')) + { + data.Add(text.Mid(start, pos - start)); + start = (pos += 2); + inData = false; + } + else if (!inQuotes && text[pos] == colSep) + { + data.Add(text.Mid(start, pos - start)); + start = ++pos; + inData = false; + } + else + { + pos++; + } + } + if (start < pos) + { + if (inQuotes && text[pos - 1] == quoteChar) + data.Add(text.Mid(start, pos - start - 1)); + else + data.Add(text.Mid(start, pos - start)); + } + + row = GetNumberRows() - 1; + skipSerial = false; + + for (col = 0; col < nCols; col++) + { + if (columns[col].type == (unsigned int)PGOID_TYPE_SERIAL || + columns[col].type == (unsigned int)PGOID_TYPE_SERIAL8 || + columns[col].type == (unsigned int)PGOID_TYPE_SERIAL2) + { + wxMessageDialog msg(GetView()->GetParent(), + _("This table contains serial columns. Do you want to use the values in the clipboard for these columns?"), + _("Paste Data"), wxYES_NO | wxICON_QUESTION); + if (msg.ShowModal() != wxID_YES) + { + skipSerial = true; + } + break; + } + } + + bool pasted = false; + for (col = (hasOids ? 1 : 0); col < nCols && col < (int)data.GetCount(); col++) + { + if (!(skipSerial && (columns[col].type == (unsigned int)PGOID_TYPE_SERIAL || + columns[col].type == (unsigned int)PGOID_TYPE_SERIAL8 || + columns[col].type == (unsigned int)PGOID_TYPE_SERIAL2))) + { + SetValue(row, col, data.Item(col)); + GetView()->SetGridCursor(row, col); + GetView()->MakeCellVisible(row, col); + pasted = true; + } + } + GetView()->ForceRefresh(); + + return pasted; +} + + + + +wxGridCellAttr *sqlTable::GetAttr(int row, int col, wxGridCellAttr::wxAttrKind kind) +{ + cacheLine *line = GetLine(row); + if (line && line->readOnly) + { + wxGridCellAttr *attr = new wxGridCellAttr(columns[col].attr); + attr->SetReadOnly(); + return attr; + } + else + { + columns[col].attr->IncRef(); + return columns[col].attr; + } +} + + + +wxString sqlCellAttr::Quote(pgConn *conn, const wxString &value) +{ + wxString str; + if (value.IsEmpty()) + str = wxT("NULL"); + else if (numeric) + str = conn->qtDbString(value); + else if (value == wxT("\\'\\'")) + str = conn->qtDbString(wxT("''")); + else if (value == wxT("''")) + str = wxT("''"); + else if (type == PGOID_TYPE_BOOL) + str = value; + else if (type == PGOID_TYPE_BIT) + // Don't cast this one + return wxT("B'") + value + wxT("'"); + else + str = conn->qtDbString(value); + + return str + wxT("::") + displayTypeName; +} + + + + +int sqlCellAttr::size() +{ + if (typlen == -1 && typmod > 0) + { + return (typmod - 4) >> 16; + } + else + return typlen; +} + + +int sqlCellAttr::precision() +{ + if (typlen == -1 && typmod > 0) + { + return (typmod - 4) & 0x7fff; + } + else + return -1; +} + + +cacheLinePool::cacheLinePool(int initialLines) +{ + ptr = new cacheLine*[initialLines]; + if (ptr) + { + anzLines = initialLines; + memset(ptr, 0, sizeof(cacheLine *)*anzLines); + } + else + { + anzLines = 0; + wxLogError(__("Out of Memory for cacheLinePool")); + } +} + + + +cacheLinePool::~cacheLinePool() +{ + if (ptr) + { + while (anzLines--) + { + if (ptr[anzLines]) + delete ptr[anzLines]; + } + delete[] ptr; + } +} + + + +void cacheLinePool::Delete(int lineNo) +{ + if (ptr && lineNo >= 0 && lineNo < anzLines) + { +#if 1 + if (ptr[lineNo]) + delete ptr[lineNo]; + + if (lineNo < anzLines - 1) + { + // beware: overlapping copy + memmove(ptr + lineNo, ptr + lineNo + 1, sizeof(cacheLine *) * (anzLines - lineNo - 1)); + } +#else + cacheLine *c; + c = ptr[0]; + ptr[0] = ptr[1]; + ptr[1] = c; +#endif + ptr[anzLines - 1] = 0; + } +} + + +cacheLine *cacheLinePool::Get(int lineNo) +{ + if (lineNo < 0) return 0; + + if (lineNo >= anzLines) + { + cacheLine **old = ptr; + int oldAnz = anzLines; + anzLines = lineNo + 100; + ptr = new cacheLine*[anzLines]; + if (!ptr) + { + anzLines = 0; + wxLogError(__("Out of Memory for cacheLinePool")); + } + else + { + if (oldAnz) + { + memcpy(ptr, old, sizeof(cacheLine *)*oldAnz); + delete[] old; + } + memset(ptr + oldAnz, 0, anzLines - oldAnz); + } + } + + if (lineNo < anzLines) + { + if (!ptr[lineNo]) + ptr[lineNo] = new cacheLine(); + return ptr[lineNo]; + } + return 0; +} + + +bool cacheLinePool::IsFilled(int lineNo) +{ + return (lineNo < anzLines && ptr[lineNo]); +} + + +bool editGridFactoryBase::CheckEnable(pgObject *obj) +{ + if (obj) + { + pgaFactory *factory = obj->GetFactory(); + return factory == &pg_partitionFactory || factory == &tableFactory || factory == &foreignTableFactory || factory == &viewFactory || factory == &extTableFactory || factory == &catalogObjectFactory; + } + return false; +} + + +wxWindow *editGridFactoryBase::ViewData(frmMain *form, pgObject *obj, bool filter) +{ + pgDatabase *db = ((pgSchemaObject *)obj)->GetDatabase(); + wxString applicationname = appearanceFactory->GetLongAppName() + _(" - Edit Grid"); + + pgServer *server = db->GetServer(); + pgConn *conn = db->CreateConn(applicationname); + if (conn) + { + wxString txt = _("Edit Data - ") + + server->GetDescription() + + wxT(" (") + server->GetName() + + wxT(":") + NumToStr((long)server->GetPort()) + + wxT(") - ") + db->GetName() + + wxT(" - ") + obj->GetFullIdentifier(); + + frmEditGrid *eg = new frmEditGrid(form, txt, conn, (pgSchemaObject *)obj, pkAscending); + eg->SetLimit(rowlimit); + eg->ShowForm(filter); + return eg; + } + return 0; +} + + +editGridFactory::editGridFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : editGridFactoryBase(list) +{ + mnu->Append(id, _("View &All Rows\tCtrl-D"), _("View the data in the selected object.")); + toolbar->AddTool(id, _("View All Rows\tCtrl-D"), *viewdata_png_bmp, _("View the data in the selected object."), wxITEM_NORMAL); + context = false; +} + + +wxWindow *editGridFactory::StartDialog(frmMain *form, pgObject *obj) +{ + return ViewData(form, obj, false); +} + + +#include "images/viewfiltereddata.pngc" +editGridFilteredFactory::editGridFilteredFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : editGridFactoryBase(list) +{ + mnu->Append(id, _("View F&iltered Rows...\tCtrl-G"), _("Apply a filter and view the data in the selected object.")); + toolbar->AddTool(id, _("View Filtered Rows\tCtrl-G"), *viewfiltereddata_png_bmp, _("Apply a filter and view the data in the selected object."), wxITEM_NORMAL); + context = false; +} + + +wxWindow *editGridFilteredFactory::StartDialog(frmMain *form, pgObject *obj) +{ + return ViewData(form, obj, true); +} + +editGridLimitedFactory::editGridLimitedFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar, int limit, bool ascending) : editGridFactoryBase(list) +{ + if (ascending) + mnu->Append(id, wxString::Format(wxPLURAL("View Top %i Row", "View Top %i Rows", limit), limit), _("View a limited number of rows in the selected object.")); + else + mnu->Append(id, wxString::Format(wxPLURAL("View Last %i Row", "View Last %i Rows", limit), limit), _("View a limited number of rows in the selected object.")); + + pkAscending = ascending; + rowlimit = limit; + context = false; +} + +wxWindow *editGridLimitedFactory::StartDialog(frmMain *form, pgObject *obj) +{ + return ViewData(form, obj, false); +} diff --git a/frm/frmExport.cpp b/frm/frmExport.cpp new file mode 100644 index 0000000..f329943 --- /dev/null +++ b/frm/frmExport.cpp @@ -0,0 +1,588 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmExport.cpp - The export file dialogue +// +////////////////////////////////////////////////////////////////////////// + + + +// App headers +#include "pgAdmin3.h" +#include +#include "frm/frmExport.h" +#include "utils/sysSettings.h" +#include "utils/misc.h" +#include "ctl/ctlSQLResult.h" +#include +#include +#include + +#define txtFilename CTRL_TEXT("txtFilename") +#define btnOK CTRL_BUTTON("wxID_OK") +#define rbUnicode CTRL_RADIOBUTTON("rbUnicode") +#define rbLocal CTRL_RADIOBUTTON("rbLocal") +#define rbCRLF CTRL_RADIOBUTTON("rbCRLF") +#define rbLF CTRL_RADIOBUTTON("rbLF") +#define rbQuoteStrings CTRL_RADIOBUTTON("rbQuoteStrings") +#define rbQuoteAll CTRL_RADIOBUTTON("rbQuoteAll") +#define rbQuoteNone CTRL_RADIOBUTTON("rbQuoteNone") +#define chkColnames CTRL_CHECKBOX("chkColnames") +#define chkXlsCopy CTRL_CHECKBOX("chkXlsCopy") +#define cbColSeparator CTRL_COMBOBOX("cbColSeparator") +#define cbQuoteChar CTRL_COMBOBOX("cbQuoteChar") + + +BEGIN_EVENT_TABLE(frmExport, pgDialog) + EVT_TEXT(XRCID("txtFilename"), frmExport::OnChange) + EVT_RADIOBUTTON(XRCID("rbQuoteNone"), frmExport::OnChange) + EVT_RADIOBUTTON(XRCID("rbQuoteStrings"), frmExport::OnChange) + EVT_RADIOBUTTON(XRCID("rbQuoteAll"), frmExport::OnChange) + EVT_BUTTON(XRCID("btnFilename"), frmExport::OnBrowseFile) + EVT_BUTTON(wxID_HELP, frmExport::OnHelp) + EVT_BUTTON(wxID_OK, frmExport::OnOK) + EVT_BUTTON(wxID_CANCEL, frmExport::OnCancel) +END_EVENT_TABLE() + +class XMLDataFormat : public wxDataFormat +{ +public: + XMLDataFormat() : wxDataFormat(wxT("XML Spreadsheet")) {} +}; +class XMLDataObject : public wxDataObjectSimple +{ + +public: + XMLDataObject(const wxString& xmlstring = wxEmptyString) : wxDataObjectSimple(), m_XMLString(xmlstring) + { + SetFormat(XMLDataFormat()); + } + + + size_t GetLength() const { return m_XMLString.Len()*2 + 1; } + wxString GetXML() const { return m_XMLString; } + void SetXML(const wxString& xml) { m_XMLString = xml; } + + size_t GetDataSize() const + { + return GetLength(); + } + + bool GetDataHere(void *buf) const + { + //char* c = _strdup(m_XMLString.c_str()); not needed as per suggestion + + //memcpy(buf, m_XMLString.c_str(), m_XMLString.Len()*2+1); + + memcpy(buf,m_XMLString.mb_str(wxConvUTF8),m_XMLString.Len()*2+1); + return true; + } + + bool SetData(size_t len, const void* buf) + { + //char* c = new char[len + 1]; not needed as per suggestion + //memcpy(c, buf, len); not needed as per suggestion + m_XMLString = wxString::FromUTF8((const char*)buf); //changed as per suggestion + + //delete c; + + return true; + } + + virtual size_t GetDataSize(const wxDataFormat&) const + { + return GetDataSize(); + } + virtual bool GetDataHere(const wxDataFormat&, void *buf) const + { + return GetDataHere(buf); + } + virtual bool SetData(const wxDataFormat&, size_t len, const void *buf) + { + return SetData(len, buf); + } + + +private: + wxString m_XMLString; +}; + + +frmExport::frmExport(wxWindow *p) +{ + parent = p; + + SetFont(settings->GetSystemFont()); + LoadResource(p, wxT("frmExport")); + RestorePosition(); + + // Icon + appearanceFactory->SetIcons(this); + cbQuoteChar->Disable(); + btnOK->Disable(); + + + bool uc = settings->GetExportUnicode(); + rbUnicode->SetValue(uc); + rbLocal->SetValue(!uc); + + bool isCrLf = settings->GetExportRowSeparator() == wxT("\r\n"); + rbCRLF->SetValue(isCrLf); + rbLF->SetValue(!isCrLf); + + int qt = settings->GetExportQuoting(); + + rbQuoteNone->SetValue(qt == 0); + rbQuoteStrings->SetValue(qt == 1); + rbQuoteAll->SetValue(qt == 2); + + cbColSeparator->SetValue(settings->GetExportColSeparator()); + + + cbQuoteChar->SetValue(settings->GetExportQuoteChar()); + + wxString val; + settings->Read(wxT("Export/LastFile"), &val, wxEmptyString); + txtFilename->SetValue(val); + + wxCommandEvent ev; + OnChange(ev); +} + + +frmExport::~frmExport() +{ + SavePosition(); +} + + +void frmExport::OnHelp(wxCommandEvent &ev) +{ + DisplayHelp(wxT("export"), HELP_PGADMIN); +} + + +void frmExport::OnChange(wxCommandEvent &ev) +{ + cbQuoteChar->Enable(rbQuoteStrings->GetValue() || rbQuoteAll->GetValue()); + btnOK->Enable(!txtFilename->GetValue().IsEmpty() && !cbColSeparator->GetValue().IsEmpty()); +} + + +void frmExport::OnOK(wxCommandEvent &ev) +{ + settings->SetExportUnicode(rbUnicode->GetValue()); + settings->SetExportRowSeparator(rbCRLF->GetValue() ? wxT("\r\n") : wxT("\n")); + settings->SetExportColSeparator(cbColSeparator->GetValue()); + + if (rbQuoteAll->GetValue()) + settings->SetExportQuoting(2); + else if (rbQuoteStrings->GetValue()) + settings->SetExportQuoting(1); + else + settings->SetExportQuoting(0); + + settings->SetExportQuoteChar(cbQuoteChar->GetValue()); + + settings->Write(wxT("Export/LastFile"), txtFilename->GetValue()); + + + if (IsModal()) + EndModal(wxID_OK); + else + Destroy(); +} + +wxString frmExport::InitXml(int cols, int rows) +{ + wxString strc; + wxString strr; + + strc.Printf(wxT("%d"),cols); + strr.Printf(wxT("%d"),rows); + + wxString s= wxT("\n") + wxT("\n") + wxT("\n") + wxT("\n") + wxT("\n") + wxT("\n") + wxT("\n") + wxT("\n") + wxT("\n") + wxT("\n") + wxT("\n") + wxT("\n") + ; + for (int c = 0 ; c < cols ; c++) + { + s+=wxT("\n"); + } + return s; +} +wxString textEscapeXml(wxString &text) +{ + wxString::const_iterator i; + wxString xmltext=wxEmptyString; + for ( i = text.begin(); i != text.end(); ++i ) + { + switch (*i) { + case '&': xmltext+= wxT("&"); break; + case '\'': xmltext+= wxT("'"); break; + case '"': xmltext+= wxT("""); break; + case '<': xmltext+= wxT("<"); break; + case '>': xmltext+= wxT(">"); break; + case 13: break; + case 10: xmltext+= wxT(" "); break; + default: xmltext+= *i; break; + } + } +return xmltext; +} +bool frmExport::ExportXls(ctlSQLResult *grid) +{ + int colCount, rowCount; + int col; + wxString line; + long skipped = 0; + wxWX2MBbuf buf; + colCount = grid->GetNumberCols(); + rowCount = grid->NumRows(); + line=InitXml(colCount,rowCount+1); + wxAutomationObject excelObject; + line += wxT("\n"); + for (col = 0 ; col < colCount ; col++) + { + line += wxT("")+grid->OnGetItemText(-1, col + 1).BeforeFirst('\n')+wxT(""); + //wxString adr(wxT("")); + //adr.Printf(wxT("%s%d"), name,1); + //rng[0] = wxVariant(adr); + //excelObject.GetObject(range, wxT("Range"), 1,rng); + //range.CallMethod(wxT("Activate")); + //excelObject.PutProperty(wxT("ActiveCell.Font.Bold"), true); + //excelObject.PutProperty(wxT("ActiveCell.Value"), grid->OnGetItemText(-1, col + 1).BeforeFirst('\n')); + //name[0]++; + } + line += wxT("\n"); + int row; + wxString text; + wxString type; + OID typOid; + wxString fn=txtFilename->GetValue().BeforeLast('.'); + if (fn.IsEmpty()) fn=txtFilename->GetValue()+wxT(".xml"); + else fn+=wxT(".xml"); + + wxFile file(fn, wxFile::write); + if (!file.IsOpened()) + { + wxLogError(__("Failed to open file %s."), fn.c_str()); + return false; + } + file.Write(line, wxConvUTF8); + wxString xmltext=wxEmptyString; + for (row = 0 ; row < rowCount ; row++) + { + + line = wxT("\n"); + for (col = 0 ; col < colCount ; col++) + { + wxString style(wxT("null")); + //adr.Printf(wxT("%s%d"), name,row+2); + //rng[0] = wxVariant(adr); + //excelObject.GetObject(range, wxT("Range"), 1,rng); + //range.CallMethod(wxT("Activate")); + text=grid->OnGetItemText(row, col + 1); + xmltext=wxEmptyString; + typOid = grid->colTypClasses[col]; + if (!text.IsEmpty()) { + style=wxT("def"); + xmltext=textEscapeXml(text); + // find out if string + switch (typOid) + { + case PGTYPCLASS_NUMERIC: + //type=wxT("0.00"); + xmltext=wxT("")+xmltext+wxT(""); + break; + case PGTYPCLASS_DATE: + //type=wxT("-- ::"); + xmltext=xmltext.BeforeFirst('+'); + xmltext.Replace(wxT(" "),wxT("T")); + style=wxT("dt"); + xmltext=wxT("")+xmltext+wxT(""); + break; + case PGTYPCLASS_BOOL: + default: + //type=wxT("@"); + xmltext=wxT("")+xmltext+wxT(""); + break; + } + + } else xmltext=wxT(""); + // excelObject.PutProperty(wxT("ActiveCell.Borders.LineStyle"), 1); + // excelObject.PutProperty(wxT("ActiveCell.NumberFormat"),type); + // excelObject.PutProperty(wxT("ActiveCell.Value"), text); + // name[0]++; + line += xmltext+wxT("\n"); + } + line += wxT("\n"); + file.Write(line, wxConvUTF8); + } + line = wxT("
    "); + file.Write(line, wxConvUTF8); + text=textEscapeXml(grid->sqlquerytext); + line= wxT("\n") + wxT("\n") + wxT("\n") + wxT("")+text+ + wxT("\n
    ") + wxT("
    \n") + ; + file.Write(line, wxConvUTF8); + file.Close(); + if (excelObject.CreateInstance(wxT("Excel.Application"))) { + //excelObject.GetObject(xlbook,wxT("Workbooks.Add")); + excelObject.CallMethod(wxT("Workbooks.Open"), fn); + excelObject.PutProperty(_T("VISIBLE"), true); + return true; + } + return false; + +} + +bool frmExport::Export(pgSet *set) +{ + ctlSQLResult *grid = 0; + if (!set) + { + wxLogInfo(wxT("Exporting data from the grid")); + grid = (ctlSQLResult *)parent; + if (chkXlsCopy->GetValue()) { + return ExportXls(grid); + } + + } + else + wxLogInfo(wxT("Exporting data from a resultset")); + + wxFile file(txtFilename->GetValue(), wxFile::write); + if (!file.IsOpened()) + { + wxLogError(__("Failed to open file %s."), txtFilename->GetValue().c_str()); + return false; + } + + wxString line; + long skipped = 0; + wxWX2MBbuf buf; + + int colCount, rowCount; + + if (set) + { + colCount = set->NumCols(); + rowCount = set->NumRows(); + } + else + { + colCount = grid->GetNumberCols(); + rowCount = grid->NumRows(); + } + + int col; + if (chkColnames->GetValue()) + { + for (col = 0 ; col < colCount ; col++) + { + if (!col) + line = wxEmptyString; + else + line += cbColSeparator->GetValue(); + + if (rbQuoteStrings->GetValue() || rbQuoteAll->GetValue()) + { + wxString qc = cbQuoteChar->GetValue(); + + wxString hdr; + if (set) + hdr = set->ColName(col); + else + hdr = grid->OnGetItemText(-1, col + 1).BeforeFirst('\n'); + + hdr.Replace(qc, qc + qc); + line += qc + hdr + qc; + } + else + { + if (set) + line += set->ColName(col); + else + line += grid->OnGetItemText(-1, col + 1).BeforeFirst('\n'); + } + } + if (rbCRLF->GetValue()) + line += wxT("\r\n"); + else + line += wxT("\n"); + + if (rbUnicode->GetValue()) + file.Write(line, wxConvUTF8); + else + { + buf = line.mb_str(wxConvLibc); + if (!buf) + skipped++; + else + file.Write(line, wxConvLibc); + } + } + + + wxString text; + OID typOid; + + int row; + for (row = 0 ; row < rowCount ; row++) + { + for (col = 0 ; col < colCount ; col++) + { + if (!col) + line = wxEmptyString; + else + line += cbColSeparator->GetValue(); + + bool needQuote = rbQuoteAll->GetValue(); + + if (set) + { + text = set->GetVal(col); + typOid = set->ColTypClass(col); + } + else + { + text = grid->OnGetItemText(row, col + 1); + typOid = grid->colTypClasses[col]; + } + + if (!needQuote && rbQuoteStrings->GetValue()) + { + // find out if string + switch (typOid) + { + case PGTYPCLASS_NUMERIC: + case PGTYPCLASS_BOOL: + break; + default: + needQuote = true; + break; + } + } + if (needQuote) + { + wxString qc = cbQuoteChar->GetValue(); + text.Replace(qc, qc + qc); + line += qc + text + qc; + } + else + line += text; + } + if (rbCRLF->GetValue()) + line += wxT("\r\n"); + else + line += wxT("\n"); + + if (rbUnicode->GetValue()) + file.Write(line, wxConvUTF8); + else + { + buf = line.mb_str(wxConvLibc); + if (!buf) + skipped++; + else + file.Write(line, wxConvLibc); + } + + if (set) + set->MoveNext(); + } + file.Close(); + + if (skipped) + wxLogError(wxPLURAL( + "Data export incomplete.\n\n%d row contained characters that could not be converted to the local charset.\n\nPlease correct the data or try using UTF8 instead.", + "Data export incomplete.\n\n%d rows contained characters that could not be converted to the local charset.\n\nPlease correct the data or try using UTF8 instead.", + skipped), skipped); + else + wxMessageBox(_("Data export completed successfully."), _("Export data"), wxICON_INFORMATION | wxOK); + + return true; +} + + +void frmExport::OnCancel(wxCommandEvent &ev) +{ + if (IsModal()) + EndModal(wxID_CANCEL); + else + Destroy(); +} + +void frmExport::OnBrowseFile(wxCommandEvent &ev) +{ + wxString directory; + wxString filename; + + if (txtFilename->GetValue().IsEmpty()) + directory = wxGetHomeDir(); + else + { + directory = wxFileName(txtFilename->GetValue()).GetPath(); + filename = wxFileName(txtFilename->GetValue()).GetFullName(); + } + +#ifdef __WXMSW__ + wxFileDialog file(this, _("Select export filename"), directory, filename, + _("CSV files (*.csv)|*.csv|Data files (*.dat)|*.dat|All files (*.*)|*.*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); +#else + wxFileDialog file(this, _("Select export filename"), directory, filename, + _("CSV files (*.csv)|*.csv|Data files (*.dat)|*.dat|All files (*)|*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); +#endif + + if (file.ShowModal() == wxID_OK) + { + txtFilename->SetValue(file.GetPath()); + OnChange(ev); + } +} diff --git a/frm/frmGrantWizard.cpp b/frm/frmGrantWizard.cpp new file mode 100644 index 0000000..f4d70fa --- /dev/null +++ b/frm/frmGrantWizard.cpp @@ -0,0 +1,340 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmGrantWizard.cpp - Grant Wizard dialogue +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include +#include + + +// App headers +#include "pgAdmin3.h" +#include "frm/frmGrantWizard.h" +#include "frm/frmMain.h" +#include "utils/sysLogger.h" +#include "ctl/ctlSecurityPanel.h" +#include "schema/pgFunction.h" +#include "schema/pgSequence.h" +#include "schema/pgTable.h" +#include "schema/pgView.h" +#include "schema/gpExtTable.h" + +// Icons +#include "images/index.pngc" + + +#define chkList CTRL_CHECKLISTBOX("chkList") + + + +BEGIN_EVENT_TABLE(frmGrantWizard, ExecutionDialog) + EVT_NOTEBOOK_PAGE_CHANGED(XRCID("nbNotebook"), frmGrantWizard::OnPageSelect) + EVT_BUTTON(XRCID("btnChkAll"), frmGrantWizard::OnCheckAll) + EVT_BUTTON(XRCID("btnUnchkAll"), frmGrantWizard::OnUncheckAll) + EVT_CHECKLISTBOX(XRCID("chkList"), frmGrantWizard::OnChange) +END_EVENT_TABLE() + + +frmGrantWizard::frmGrantWizard(frmMain *form, pgObject *obj) : ExecutionDialog(form, obj) +{ + nbNotebook = 0; + + SetFont(settings->GetSystemFont()); + LoadResource(form, wxT("frmGrantWizard")); + RestorePosition(); + + SetTitle(object->GetTranslatedMessage(GRANTWIZARDTITLE)); + + // Icon + SetIcon(*index_png_ico); + nbNotebook = CTRL_NOTEBOOK("nbNotebook"); + sqlPane = 0; + + Restore(); + EnableOK(false); +} + + +frmGrantWizard::~frmGrantWizard() +{ + SavePosition(); + Abort(); +} + + +wxString frmGrantWizard::GetHelpPage() const +{ + wxString page = wxT("pg/sql-grant"); + + return page; +} + +void frmGrantWizard::OnChange(wxCommandEvent &event) +{ + sqlPane->SetReadOnly(false); + sqlPane->SetText(GetSql()); + sqlPane->SetReadOnly(true); + + if (sqlPane->GetText().IsEmpty()) + EnableOK(false); + else + EnableOK(true); +} + + +void frmGrantWizard::OnUncheckAll(wxCommandEvent &event) +{ + unsigned int i; + for (i = 0 ; i < chkList->GetCount() ; i++) + chkList->Check(i, false); + + OnChange(event); +} + + + +void frmGrantWizard::OnCheckAll(wxCommandEvent &event) +{ + unsigned int i; + for (i = 0 ; i < chkList->GetCount() ; i++) + chkList->Check(i, true); + + OnChange(event); +} + +void frmGrantWizard::OnPageSelect(wxNotebookEvent &event) +{ + if (nbNotebook && sqlPane && event.GetSelection() == (int)nbNotebook->GetPageCount() - 2) + { + sqlPane->SetReadOnly(false); + sqlPane->SetText(GetSql()); + sqlPane->SetReadOnly(true); + } +} + + +void frmGrantWizard::AddObjects(pgCollection *collection) +{ + bool traverseKids = (!collection->IsCollection() || collection->GetMetaType() == PGM_SCHEMA); + + if (!traverseKids) + { + pgaFactory *factory = collection->GetFactory(); + if (!factory->IsCollectionFor(tableFactory) && + !factory->IsCollectionFor(functionFactory) && + !factory->IsCollectionFor(triggerFunctionFactory) && + !factory->IsCollectionFor(procedureFactory) && + !factory->IsCollectionFor(viewFactory) && + !factory->IsCollectionFor(extTableFactory) && + !factory->IsCollectionFor(sequenceFactory)) + return; + } + + wxCookieType cookie; + wxTreeItemId item = mainForm->GetBrowser()->GetFirstChild(collection->GetId(), cookie); + + while (item) + { + pgObject *obj = mainForm->GetBrowser()->GetObject(item); + if (obj) + { + if (traverseKids) + AddObjects((pgCollection *)obj); + else + { + if (obj->CanEdit()) + { + objectArray.Add(obj); + chkList->Append((wxString)wxGetTranslation(obj->GetTypeName()) + wxT(" ") + obj->GetFullIdentifier()); + } + } + } + item = mainForm->GetBrowser()->GetNextChild(collection->GetId(), cookie); + } +} + +void frmGrantWizard::Go() +{ + chkList->SetFocus(); + + wxString privList = wxT("INSERT,SELECT,UPDATE,DELETE,TRUNCATE,REFERENCES,TRIGGER"); + const char *privChar = "arwdDxt"; + + switch (object->GetMetaType()) + { + case PGM_DATABASE: + case PGM_SCHEMA: + privList.Append(wxT(",EXECUTE,USAGE")); + privChar = "arwdDxtXU"; + break; + case PGM_FUNCTION: + privList = wxT("EXECUTE"); + privChar = "X"; + break; + case PGM_SEQUENCE: + privList = wxT("SELECT,UPDATE,USAGE"); + privChar = "rwU"; + break; + case GP_EXTTABLE: + privList = wxT("SELECT"); + privChar = "r"; + default: + break; + } + + securityPage = new ctlSecurityPanel(nbNotebook, privList, privChar, mainForm->GetImageList()); + securityPage->SetConnection(object->GetConnection()); + this->Connect(EVT_SECURITYPANEL_CHANGE, wxCommandEventHandler(frmGrantWizard::OnChange)); + + sqlPane = new ctlSQLBox(nbNotebook, CTL_PROPSQL, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_READONLY | wxTE_RICH2); + nbNotebook->AddPage(sqlPane, wxT("SQL")); + + txtMessages = new wxTextCtrl(nbNotebook, CTL_MSG, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxHSCROLL); + nbNotebook->AddPage(txtMessages, _("Messages")); + + AddObjects((pgCollection *)object); + + + if (securityPage->cbGroups) + { + pgSet *set = object->GetConnection()->ExecuteSet(wxT("SELECT groname FROM pg_group ORDER BY groname")); + + if (set) + { + while (!set->Eof()) + { + securityPage->cbGroups->Append(wxT("group ") + set->GetVal(0)); + set->MoveNext(); + } + delete set; + } + + if (settings->GetShowUsersForPrivileges()) + { + set = object->GetConnection()->ExecuteSet(wxT("SELECT usename FROM pg_user ORDER BY usename")); + + if (set) + { + securityPage->stGroup->SetLabel(_("Group/User")); + + while (!set->Eof()) + { + securityPage->cbGroups->Append(set->GetVal(0)); + set->MoveNext(); + } + delete set; + Layout(); + } + } + } + + Layout(); + Show(true); + + // Work around a weird display bug in wx2.7 + this->Refresh(); +} + + +wxString frmGrantWizard::GetSql() +{ + wxString sql; + + unsigned int i; + for (i = 0 ; i < chkList->GetCount() ; i++) + { + if (chkList->IsChecked(i)) + { + wxString tmp; + + pgObject *obj = (pgObject *)objectArray.Item(i); + + switch (obj->GetMetaType()) + { + case PGM_FUNCTION: + { + if (((pgFunction *)obj)->GetIsProcedure()) + { + tmp = securityPage->GetGrant(wxT("X"), wxT("PROCEDURE ") + + obj->GetQuotedFullIdentifier() + wxT("(") + + ((pgProcedure *)obj)->GetArgSigList() + wxT(")")); + } + else + { + tmp = securityPage->GetGrant(wxT("X"), wxT("FUNCTION ") + + obj->GetQuotedFullIdentifier() + wxT("(") + + ((pgFunction *)obj)->GetArgSigList() + wxT(")")); + } + break; + } + case PGM_VIEW: + tmp = securityPage->GetGrant(wxT("arwdxt"), wxT("TABLE ") + obj->GetQuotedFullIdentifier()); + break; + case PGM_SEQUENCE: + tmp = securityPage->GetGrant(wxT("rwU"), wxT("SEQUENCE ") + obj->GetQuotedFullIdentifier()); + break; + case GP_EXTTABLE: + tmp = securityPage->GetGrant(wxT("r"), wxT("TABLE ") + obj->GetQuotedFullIdentifier()); + default: + if (obj->GetTypeName().Upper() == wxT("EXTERNAL TABLE")) // somewhat of a hack + { + tmp = securityPage->GetGrant(wxT("r"), wxT("TABLE ") + obj->GetQuotedFullIdentifier()); + } + else + tmp = securityPage->GetGrant(wxT("arwdDxt"), obj->GetTypeName().Upper() + wxT(" ") + obj->GetQuotedFullIdentifier()); + break; + } + + if (!tmp.IsEmpty()) + sql.Append(tmp); + } + } + return sql; +} + + +grantWizardFactory::grantWizardFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Grant Wizard..."), _("Grants rights to multiple objects")); +} + + +wxWindow *grantWizardFactory::StartDialog(frmMain *form, pgObject *obj) +{ + frmGrantWizard *frm = new frmGrantWizard(form, obj); + frm->Go(); + return 0; +} + + +bool grantWizardFactory::CheckEnable(pgObject *obj) +{ + if (obj) + { + switch (obj->GetMetaType()) + { + case PGM_TABLE: + case PGM_FUNCTION: + case PGM_SEQUENCE: + case PGM_VIEW: + case GP_EXTTABLE: + if (obj->IsCollection() && obj->GetSchema()->GetMetaType() != PGM_CATALOG) + return obj->GetSchema()->CanEdit(); + break; + + case PGM_SCHEMA: + return obj->CanEdit(); + default: + break; + } + } + return false; +} diff --git a/frm/frmHbaConfig.cpp b/frm/frmHbaConfig.cpp new file mode 100644 index 0000000..044a7d8 --- /dev/null +++ b/frm/frmHbaConfig.cpp @@ -0,0 +1,394 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmHbaConfig.cpp - Backend access configuration tool +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" + +#ifdef __WXMSW__ +#include +#include +#endif + +#include + +#include "ctl/ctlMenuToolbar.h" +#include "frm/frmHbaConfig.h" +#include "dlg/dlgHbaConfig.h" +#include "frm/frmMain.h" +#include "utils/utffile.h" +#include "schema/pgServer.h" +#include "frm/menu.h" +#include "utils/pgfeatures.h" + +#define CTL_CFGVIEW 345 + +#include +WX_DEFINE_OBJARRAY(pgHbaConfigLineArray); + + +BEGIN_EVENT_TABLE(frmHbaConfig, frmConfig) + EVT_MENU(MNU_UNDO, frmHbaConfig::OnUndo) + EVT_MENU(MNU_DELETE, frmHbaConfig::OnDelete) + EVT_MENU(MNU_CONTENTS, frmHbaConfig::OnContents) + EVT_LIST_ITEM_ACTIVATED(CTL_CFGVIEW, frmHbaConfig::OnEditSetting) + EVT_LIST_ITEM_SELECTED(CTL_CFGVIEW, frmHbaConfig::OnSelectSetting) +END_EVENT_TABLE() + +#define BACE_TITLE _("Backend Access Configuration Editor") + + +frmHbaConfig::frmHbaConfig(frmMain *parent, pgServer *server) + : frmConfig(parent, BACE_TITLE, 0) +{ + wxString applicationname = appearanceFactory->GetLongAppName() + _(" - Configuration Editor"); + if (server) + conn = server->CreateConn(wxEmptyString, 0, applicationname); + Init(); + + if (conn) + { + serverFileName = conn->ExecuteScalar(wxT("SHOW hba_file")); + if (serverFileName == wxT("unset") || serverFileName.IsEmpty()) + serverFileName = wxT("pg_hba.conf"); + + wxString txt; + txt.Printf(_(" - %s on %s (%s:%d)"), + serverFileName.c_str(), server->GetDescription().c_str(), + server->GetName().c_str(), server->GetPort()); + SetTitle(BACE_TITLE + txt); + + wxString str; + str = conn->ExecuteScalar(wxT("SELECT pg_file_read('") + serverFileName + wxT("', 0, ") + wxT("pg_file_length('") + serverFileName + wxT("'))")); + + DisplayFile(str); + + statusBar->SetStatusText(wxString::Format(_(" Configuration read from %s"), conn->GetHost().c_str())); + } +} + + +frmHbaConfig::frmHbaConfig(const wxString &title, const wxString &configFile) + : frmConfig(title + wxT(" - ") + _("Backend Access Configuration Editor"), configFile) +{ + + Init(); + + OpenLastFile(); +} + + +frmHbaConfig::~frmHbaConfig() +{ +} + + +void frmHbaConfig::Init() +{ + appearanceFactory->SetIcons(this); + + InitFrame(wxT("frmHbaConfig")); + RestorePosition(150, 150, 650, 300, 300, 200); + + + listEdit = new ctlListView(this, CTL_CFGVIEW, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER); + listEdit->SetImageList(configImageList, wxIMAGE_LIST_SMALL); + + listEdit->AddColumn(_("Type"), 40); + listEdit->AddColumn(_("Database"), 80); + listEdit->AddColumn(_("User"), 80); + listEdit->AddColumn(_("IP-Address"), 100); + listEdit->AddColumn(_("Method"), 40); + listEdit->AddColumn(_("Option"), 100); + + helpMenu->Enable(MNU_HINT, false); + toolBar->EnableTool(MNU_HINT, false); + + editMenu->Enable(MNU_DELETE, false); + toolBar->EnableTool(MNU_DELETE, false); +} + + +void frmHbaConfig::OnSelectSetting(wxListEvent &event) +{ + // Enable delete because an item has been selected + if (event.GetIndex() != listEdit->GetItemCount() - 1) + { + editMenu->Enable(MNU_DELETE, true); + toolBar->EnableTool(MNU_DELETE, true); + } + else + { + editMenu->Enable(MNU_DELETE, false); + toolBar->EnableTool(MNU_DELETE, false); + } + + // Disable undo because we don't want to undo the wrong line. + editMenu->Enable(MNU_UNDO, false); + toolBar->EnableTool(MNU_UNDO, false); +} + + +void frmHbaConfig::DisplayFile(const wxString &str) +{ + lines.Empty(); + + filetype = wxTextFileType_Unix; + wxStringTokenizer strtok; + + if (str.Find('\r') >= 0) + { + if (str.Find(wxT("\n\r")) >= 0 || str.Find(wxT("\r\n"))) + filetype = wxTextFileType_Dos; + else + filetype = wxTextFileType_Mac; + + strtok.SetString(wxTextBuffer::Translate(str, wxTextFileType_Unix), wxT("\n"), wxTOKEN_RET_EMPTY); + } + else + strtok.SetString(str, wxT("\n"), wxTOKEN_RET_EMPTY); + + while (strtok.HasMoreTokens()) + { + pgHbaConfigLine *line = new pgHbaConfigLine(strtok.GetNextToken()); + lines.Add(line); + } + + listEdit->DeleteAllItems(); + + size_t i = lines.GetCount(); + + // make sure the last line is empty + + for (i = 0 ; i < lines.GetCount() ; i++) + { + pgHbaConfigLine &line = lines.Item(i); + const wxChar *connTypeStr = line.GetConnectType(); + if ((line.isValid || (!line.isValid && !line.isComment)) && !line.GetText().IsEmpty()) + { + int imgIndex = 0; + if (!line.isComment) + imgIndex = 1; + long pos = listEdit->AppendItem(imgIndex, connTypeStr, line.database, line.user); + listEdit->SetItem(pos, 3, line.ipaddress); + listEdit->SetItem(pos, 4, line.GetMethod()); + listEdit->SetItem(pos, 5, line.option); + + line.item = pos; + } + } + if (!i || !lines.Item(i - 1).text.IsEmpty()) + { + pgHbaConfigLine *line = new pgHbaConfigLine(); + lines.Add(line); + line->item = listEdit->AppendItem(0, wxString(wxEmptyString)); + } +} + + +void frmHbaConfig::WriteFile(pgConn *conn) +{ + wxString str; + size_t i; + for (i = 0 ; i < lines.GetCount() - 1 ; i++) + str.Append(lines.Item(i).GetText() + wxT("\n")); + + if (DoWriteFile(str, conn)) + { + changed = false; + fileMenu->Enable(MNU_SAVE, false); + editMenu->Enable(MNU_UNDO, false); + toolBar->EnableTool(MNU_SAVE, false); + toolBar->EnableTool(MNU_UNDO, false); + + // make intermediate change current + for (i = 0 ; i < lines.GetCount() ; i++) + lines.Item(i).Init(lines.Item(i).GetText()); + } +} + + +wxString frmHbaConfig::GetHintString() +{ + wxString hint; + return hint; +} + + +wxString frmHbaConfig::GetHelpPage() const +{ + wxString page = wxT("client-authentication"); + return page; +} + + +void frmHbaConfig::OnContents(wxCommandEvent &event) +{ + DisplayHelp(wxT("index"), HELP_PGADMIN); +} + + +void frmHbaConfig::OnUndo(wxCommandEvent &ev) +{ + int pos = listEdit->GetSelection(); + if (pos >= 0) + { + size_t i; + for (i = 0 ; i < lines.GetCount() ; i++) + { + pgHbaConfigLine &line = lines.Item(i); + + if (line.item == pos) + { + line.Init(line.text); + UpdateDisplay(line); + break; + } + } + } +} + +void frmHbaConfig::OnDelete(wxCommandEvent &event) +{ + bool found = false; + int pos = listEdit->GetSelection(); + if (pos >= 0) + { + listEdit->DeleteCurrentItem(); + size_t i; + for (i = 0; i < lines.GetCount(); i++) + { + if (lines.Item(i).item == pos) + { + lines.RemoveAt(i); + changed = true; + fileMenu->Enable(MNU_SAVE, true); + editMenu->Enable(MNU_UNDO, false); + editMenu->Enable(MNU_DELETE, false); + toolBar->EnableTool(MNU_SAVE, true); + toolBar->EnableTool(MNU_UNDO, false); + toolBar->EnableTool(MNU_DELETE, false); + found = true; + break; + } + } + if (found) + { + /* Renumber all positions */ + for (i = 0; i < lines.GetCount(); i++) + { + if (lines.Item(i).item > pos) + lines.Item(i).item--; + } + } + } +} + + +void frmHbaConfig::UpdateDisplay(pgHbaConfigLine &line) +{ + long pos = line.item; + listEdit->SetItemImage(pos, (line.isComment ? 0 : 1)); + listEdit->SetItem(pos, 0, line.GetConnectType()); + listEdit->SetItem(pos, 1, line.database); + listEdit->SetItem(pos, 2, line.user); + listEdit->SetItem(pos, 3, line.ipaddress); + listEdit->SetItem(pos, 4, line.GetMethod()); + listEdit->SetItem(pos, 5, line.option); +} + + +void frmHbaConfig::OnEditSetting(wxListEvent &event) +{ + long pos = event.GetIndex(); + if (pos < 0) + return; + + size_t i; + + for (i = 0 ; i < lines.GetCount() ; i++) + { + if (lines.Item(i).item == pos) + { + pgHbaConfigLine &line = lines.Item(i); + bool isLastLine = (i == lines.GetCount() - 1 && line.isComment && !line.GetConnectType()); + + dlgHbaConfig dlg(this, &line, conn); + if (dlg.Go() == wxID_OK) + { + UpdateDisplay(line); + + if (isLastLine) + { + long pos = listEdit->AppendItem(0, wxString(wxEmptyString)); + pgHbaConfigLine *line = new pgHbaConfigLine(); + line->item = pos; + lines.Add(line); + } + changed = true; + fileMenu->Enable(MNU_SAVE, true); + editMenu->Enable(MNU_UNDO, true); + toolBar->EnableTool(MNU_SAVE, true); + toolBar->EnableTool(MNU_UNDO, true); + } + break; + } + } +} + + +hbaConfigFactory::hbaConfigFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, wxT("pg_hba.conf"), _("Edit server access configuration file.")); +} + + +wxWindow *hbaConfigFactory::StartDialog(frmMain *form, pgObject *obj) +{ + pgServer *server = obj->GetServer(); + if (server) + { + frmHbaConfig *frm = new frmHbaConfig(form, server); + frm->Go(); + return frm; + } + return 0; +} + + +bool hbaConfigFactory::CheckEnable(pgObject *obj) +{ + if (obj) + { + pgServer *server = obj->GetServer(); + if (server) + { + pgConn *conn = server->GetConnection(); + return conn && server->GetSuperUser() && conn->HasFeature(FEATURE_FILEREAD); + } + } + return false; +} + + +hbaConfigFileFactory::hbaConfigFileFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, _("Open pg_hba.conf..."), _("Open configuration editor with pg_hba.conf.")); +} + + +wxWindow *hbaConfigFileFactory::StartDialog(frmMain *form, pgObject *obj) +{ + frmConfig *dlg = new frmHbaConfig(form); + dlg->Go(); + dlg->DoOpen(); + return dlg; +} diff --git a/frm/frmHint.cpp b/frm/frmHint.cpp new file mode 100644 index 0000000..e8d3a74 --- /dev/null +++ b/frm/frmHint.cpp @@ -0,0 +1,510 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmHint.cpp - PostgreSQL Guru hints +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include "wx/wxhtml.h" +#include + +// App headers +#include "copyright.h" +#include "ctl/ctlMenuToolbar.h" +#include "frm/frmHint.h" +#include "frm/frmMain.h" +#include "schema/pgObject.h" +#include "utils/misc.h" +#include "utils/utffile.h" + +// Icons +#include "images/hint.pngc" +#include "images/hint2.pngc" + + + +#define HINT_CANSUPPRESS 1 +#define HINT_CANABORT 2 +#define HINT_CANFIX 4 +#define HINT_YESNO 8 + + +struct make_dumb_compilers_happy // unnamed structs don't make all compilers happy... +{ + const wxChar *hintPage; + const wxChar *hintCaption; + const wxChar *fixText; + const wxChar *helpItem; + int flags; +} +hintArray[] = +{ + { + HINT_CONNECTSERVER, + __("Server not listening"), + 0, + wxT("pg/runtime-config#runtime-config-connection"), + HINT_CANSUPPRESS + }, + { + HINT_MISSINGHBA, + __("Server denies access"), + 0, + wxT("pg/client-authentication#auth-pg-hba-conf"), + HINT_CANSUPPRESS + }, + { + HINT_MISSINGIDENT, + __("Ident authentication failed"), + 0, + wxT("pg/auth-methods#auth-ident"), + HINT_CANSUPPRESS + }, + { + HINT_PRIMARYKEY, + __("Creation of primary key suggested"), + 0, + wxT("pg/ddl-constraints"), + HINT_CANSUPPRESS | HINT_CANABORT + }, + { + HINT_FKINDEX, + __("Creation of index in referencing table suggested"), + 0, + wxT("pg/ddl-constraints#ddl-constraints-fk"), + HINT_CANSUPPRESS | HINT_CANABORT + }, + { + HINT_VACUUM, + __("Running VACUUM recommended"), + __("VACUUM"), + wxT("pg/maintenance#routine-vacuuming"), + HINT_CANSUPPRESS | HINT_CANFIX + }, + { + HINT_VACUUM_FULL, + __("Running VACUUM FULL not recommended"), + __("VACUUM FULL"), + wxT("pg/sql-vacuum"), + HINT_CANSUPPRESS | HINT_CANABORT + }, + { + HINT_QUERYRUNTIME, + __("Query took a long time to complete"), + 0, + wxT("query"), + HINT_CANSUPPRESS | HINT_CANABORT | HINT_YESNO + }, + { + HINT_INSTRUMENTATION, + __("Server instrumentation not installed"), + 0, + wxEmptyString, + HINT_CANSUPPRESS + }, + { + HINT_INSTRUMENTATION_91_WITH, + __("Server instrumentation not installed"), + 0, + wxEmptyString, + HINT_CANSUPPRESS | HINT_CANFIX + }, + { + HINT_INSTRUMENTATION_91_WITHOUT, + __("Server instrumentation not installed"), + 0, + wxEmptyString, + HINT_CANSUPPRESS + }, + { + HINT_ENCODING_UNICODE, + __("Database encoding is Unicode"), + 0, + wxT("pg/multibyte"), + HINT_CANSUPPRESS + }, + { + HINT_ENCODING_ASCII, + __("Database encoding is SQL_ASCII"), + 0, + wxT("pg/multibyte"), + HINT_CANSUPPRESS + }, + { + HINT_READONLY_NOPK, + __("Can't edit tables without primary key"), + 0, + wxT("editgrid"), + HINT_CANSUPPRESS + }, + { + HINT_AUTOVACUUM, + _("Enabling autovacuum recommended"), + 0, + wxT("pg/maintenance#autovacuum"), + HINT_CANSUPPRESS + }, + { + HINT_OBJECT_EDITING, + _("Editing views, stored procedures or functions"), + 0, + wxT("query"), + HINT_CANSUPPRESS | HINT_CANABORT + }, + { + HINT_SAVING_PASSWORDS, + _("Saving passwords"), + 0, + wxT("pg/libpq-pgpass"), + HINT_CANSUPPRESS | HINT_CANABORT + }, + { 0, 0, 0, 0 } +}; + + +BEGIN_EVENT_TABLE(frmHint, DialogWithHelp) + EVT_BUTTON(XRCID("btnFix"), frmHint::OnFix) +END_EVENT_TABLE(); + + +#define chkSuppress CTRL_CHECKBOX("chkSuppress") +#define htmlHint (XRCCTRL(*this, "htmlHint", wxHtmlWindow)) +#define btnFix CTRL_BUTTON("btnFix") +#define btnYes CTRL_BUTTON("wxID_YES") +#define btnNo CTRL_BUTTON("wxID_NO") +#define btnHelp CTRL_BUTTON("wxID_HELP") + +frmHint::frmHint(wxWindow *fr, bool _force) : DialogWithHelp(0) +{ + force = _force; + SetFont(settings->GetSystemFont()); + LoadResource(fr, wxT("frmHint")); + RestorePosition(); + + if (force) + btnCancel->Disable(); + + SetIcon(*hint_png_ico); +} + + + +wxString frmHint::GetPage(const wxChar *hintPage) +{ + wxString page; + + wxString cn = settings->GetCanonicalLanguageName(); + if (cn.IsEmpty()) + cn = wxT("en_US"); + + wxString filename = docPath + wxT("/") + cn + wxT("/hints/") + hintPage + wxT(".html"); + + if (!wxFile::Exists(filename)) + filename = docPath + wxT("/en_US/hints/") + hintPage + wxT(".html"); + if (wxFile::Exists(filename)) + { + wxUtfFile file(filename, wxFile::read, wxFONTENCODING_UTF8); + file.Read(page); + } + + return page; +} + + +void frmHint::SetHint(int hintno, const wxString &info) +{ + hintnos.Add(hintno); + SetHint(info); +}; + + +void frmHint::SetHint(const wxArrayInt &_hintnos, const wxString &info) +{ + hintnos = _hintnos; + SetHint(info); +} + + +void frmHint::SetHint(const wxString &info) +{ + currentHint = hintnos.Item(0); + + bool canSuppress = false; + if (hintnos.GetCount() == 1) + { + if (hintArray[currentHint].flags & HINT_CANSUPPRESS) + canSuppress = true; + SetTitle(_("Guru Hint") + wxString(wxT(" - ")) + wxGetTranslation(hintArray[currentHint].hintCaption)); + + wxString page = GetPage(hintArray[currentHint].hintPage); + page.Replace(wxT(""), HtmlEntities(info)); + + htmlHint->SetPage(page); + } + else + { + SetTitle(_("Guru Hints")); + + wxString header = GetPage(wxT("multiple")); + wxString pages; + + if (header.IsEmpty()) + { + header = + wxT("\n") + wxT("\n") + wxT("\n") + wxT("Guru Hints\n") + wxT("

    \n"); + } + else + { + int o = header.Find(wxT("")); + if (o > 0) + header = header.Left(o) + wxT("

    "); + } + + size_t i; + for (i = 0 ; i < hintnos.GetCount() ; i++) + { + int hintno = hintnos.Item(i); + if (hintArray[hintno].flags & HINT_CANSUPPRESS) + canSuppress = true; + wxString page = GetPage(hintArray[hintno].hintPage); + int a = page.Find(wxT("")); + int o = page.Find(wxT("")); + if (a < 0) + a = 0; + if (o < 0) + o = wxString::npos; + + + int ha = page.Find(wxT("

    ")); + int ho = page.Find(wxT("

    ")); + if (ha < 0) + ha = page.Find(wxT("

    ")); + if (ho < 0) + ho = page.Find(wxT("

    ")); + + if (ha > a && ho > ha) + { + wxString hintTitle = page.Mid(ha + 4, ho - ha - 4); + + pages += page.Mid(a, ha - a) + + wxT("

    ") + + hintTitle + wxT("") + + page.Mid(ho, o - ho); + header += wxString(wxT("") + + hintTitle + wxT("
    "); + } + else + pages += page.Mid(a, o - a); + } + + pages.Replace(wxT(""), info); + pages.Replace(wxT(""), info); + + htmlHint->SetPage(header + wxT("

    ") + pages + wxT("\n")); + } + + chkSuppress->SetValue(false); + chkSuppress->Enable(!force && canSuppress); + + if (force || !(hintArray[currentHint].flags & HINT_CANABORT)) + btnCancel->Disable(); + if (!(hintArray[currentHint].flags & HINT_CANFIX)) + btnFix->Hide(); + + if (!(hintArray[currentHint].flags & HINT_CANFIX)) + btnFix->Hide(); + else if (hintArray[currentHint].fixText) + btnFix->SetLabel(wxGetTranslation(hintArray[currentHint].fixText)); + + if (hintArray[currentHint].flags & HINT_YESNO) + btnOK->Hide(); + else + { + btnYes->Hide(); + btnNo->Hide(); + } + + if (hintArray[currentHint].helpItem == wxEmptyString) + btnHelp->Disable(); + else + btnHelp->Enable(); +}; + + +frmHint::~frmHint() +{ + if (!force && chkSuppress->GetValue()) + { + size_t i; + for (i = 0 ; i < hintnos.GetCount() ; i++) + { + int hintno = hintnos.Item(i); + if (hintArray[hintno].flags & HINT_CANSUPPRESS) + settings->Write(wxString(wxT("Hints/")) + hintArray[hintno].hintPage, wxT("Suppress")); + } + } + SavePosition(); +} + + +wxString frmHint::GetHelpPage() const +{ + const wxChar *helpItem = hintArray[currentHint].helpItem; + if (helpItem) + return helpItem; + + return wxT("guruhints"); +} + + +void frmHint::ResetHints() +{ + int hintno = 0; + while (hintArray[hintno].hintPage) + { + settings->Write(wxString(wxT("Hints/")) + hintArray[hintno].hintPage, wxString(wxEmptyString)); + hintno++; + } +} + + +int frmHint::GetHintNo(const wxString &hint) +{ + int hintno = 0; + while (hintArray[hintno].hintPage) + { + if (hintArray[hintno].hintPage == hint) + return hintno; + hintno++; + } + return -1; +} + + +bool frmHint::WantHint(const wxString &hint) +{ + int hintno = GetHintNo(hint); + if (hintno < 0) + return false; + + return WantHint(hintno); +} + + +bool frmHint::WantHint(int hintno) +{ + if (hintno < 0) + return false; + + if ((hintArray[hintno].flags & HINT_CANSUPPRESS) && settings->GetSuppressGuruHints()) + return false; + + if (settings->Read(wxString(wxT("Hints/")) + hintArray[hintno].hintPage, wxEmptyString) != wxT("Suppress")) + return true; + + return false; +} + + + +int frmHint::ShowHint(wxWindow *fr, const wxArrayString &hints, const wxString &info, bool force) +{ + wxArrayInt hintnos; + size_t i; + + if(!hints.GetCount()) + return wxID_OK; + for (i = 0 ; i < hints.GetCount() ; i++) + { + int hintNo = GetHintNo(hints.Item(i)); + if (hintNo >= 0 && (force || WantHint(hintNo))) + hintnos.Add(hintNo); + } + + if (!hintnos.GetCount()) + return wxID_OK; + + frmHint *frm = new frmHint(fr, force); + frm->SetHint(hintnos, info); + + frm->CenterOnParent(); + int rc = frm->ShowModal(); + delete frm; + + if ((rc == wxID_CANCEL || rc == -1)) + rc = wxID_OK; + + return rc; +} + + +int frmHint::ShowHint(wxWindow *fr, const wxString &hint, const wxString &info, bool force) +{ + int rc = wxID_OK; + int hintno = GetHintNo(hint); + + if (WantHint(hintno)) + { + frmHint *frm = new frmHint(fr, force); + frm->SetHint(hintno, info); + + frm->CenterOnParent(); + rc = frm->ShowModal(); + delete frm; + + if ((rc == wxID_CANCEL || rc == -1) && !(hintArray[hintno].flags & HINT_CANABORT)) + rc = wxID_OK; + } + return rc; +} + + +void frmHint::OnFix(wxCommandEvent &ev) +{ + EndModal(HINT_RC_FIX); +} + + + +hintFactory::hintFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar, bool bigTool) : actionFactory(list) +{ + mnu->Append(id, _("Hints"), _("Display helpful hints on current object.")); + if (toolbar) + { + const wxBitmap &bmp = (bigTool ? *hint_png_bmp : *hint2_png_bmp); + toolbar->AddTool(id, wxEmptyString, bmp, _("Display helpful hints on current object.")); + } +} + + +wxWindow *hintFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (obj) + obj->ShowHint(form, true); + else + wxLogMessage(_("There are no hints available for the current object.")); + + return 0; +} + + +bool hintFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->GetCanHint(); +} + diff --git a/frm/frmImport.cpp b/frm/frmImport.cpp new file mode 100644 index 0000000..ddaf88f --- /dev/null +++ b/frm/frmImport.cpp @@ -0,0 +1,379 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmImport.cpp - Import database dialogue +// +////////////////////////////////////////////////////////////////////////// + + +// wxWindows headers +#include +#include +#include + + +// App headers +#include "pgAdmin3.h" +#include "db/pgConn.h" +#include "frm/frmMain.h" +#include "frm/frmImport.h" +#include "utils/sysLogger.h" +#include "schema/pgSchema.h" +#include "schema/pgTable.h" +#include "schema/pgColumn.h" +#include "schema/pgPartition.h" + +// Icons +#include "images/reload.pngc" + + +#define nbNotebook CTRL_NOTEBOOK("nbNotebook") +#define pickerImportfile CTRL_FILEPICKER("pickerImportfile") +#define cbFormat CTRL_COMBOBOX("cbFormat") +#define cbEncoding CTRL_COMBOBOX("cbEncoding") +#define chkOids CTRL_CHECKBOX("chkOids") +#define chkHeader CTRL_CHECKBOX("chkHeader") +#define cbDelimiter CTRL_COMBOBOX("cbDelimiter") +#define cbQuote CTRL_COMBOBOX("cbQuote") +#define cbEscape CTRL_COMBOBOX("cbEscape") +#define txtNull CTRL_TEXT("txtNull") +#define gauge CTRL_GAUGE("gauge") +#define lstColumnsToImport CTRL_CHECKLISTBOX("lstColumnsToImport") +#define lstIgnoreForColumns CTRL_CHECKLISTBOX("lstIgnoreForColumns") + + +BEGIN_EVENT_TABLE(frmImport, pgDialog) + EVT_COMBOBOX(XRCID("cbFormat"), frmImport::OnChangeFormat) + EVT_BUTTON(wxID_OK, frmImport::OnOK) + EVT_BUTTON (wxID_HELP, frmImport::OnHelp) +END_EVENT_TABLE() + + +frmImport::frmImport(frmMain *form, pgObject *_object, pgConn *_conn) +{ + // Initialize variables + connection = _conn; + object = _object; + done = false; + + // Set-up window + SetFont(settings->GetSystemFont()); + LoadResource(form, wxT("frmImport")); + RestorePosition(); + SetTitle(wxT("Import data from file into ") + object->GetName()); + SetIcon(*reload_png_ico); + + // Fill the encoding combobox + long encNo = 0; + wxString encStr; + cbEncoding->Append(wxT("")); + do + { + encStr = object->GetConnection()->ExecuteScalar( + wxT("SELECT pg_encoding_to_char(") + NumToStr(encNo) + wxT(")")); + if (pgConn::IsValidServerEncoding(encNo) && !encStr.IsEmpty()) + cbEncoding->Append(encStr); + + encNo++; + } + while (!encStr.IsEmpty()); + cbEncoding->SetSelection(0); + + // Fill the columns checklistboxes + wxCookieType cookie; + pgObject *data = 0; + wxTreeItemId columnsItem; + wxTreeItemId item = form->GetBrowser()->GetFirstChild(object->GetId(), cookie); + while (item) + { + data = form->GetBrowser()->GetObject(item); + pgaFactory *factory = data->GetFactory(); + if (factory == columnFactory.GetCollectionFactory()) + columnsItem = item; + if (data->GetMetaType() == PGM_COLUMN && data->IsCollection()) + columnsItem = item; + if (columnsItem) + break; + + item = form->GetBrowser()->GetNextChild(object->GetId(), cookie); + } + + if (columnsItem) + { + pgCollection *coll = (pgCollection *)data; + coll->ShowTreeDetail(form->GetBrowser()); + item = form->GetBrowser()->GetFirstChild(columnsItem, cookie); + + while (item) + { + data = form->GetBrowser()->GetObject(item); + if (data->IsCreatedBy(columnFactory)) + { + pgColumn *column = (pgColumn *)data; + column->ShowTreeDetail(form->GetBrowser()); + if (column->GetColNumber() > 0) + { + lstColumnsToImport->Append(column->GetName()); + lstIgnoreForColumns->Append(column->GetName()); + } + } + item = form->GetBrowser()->GetNextChild(columnsItem, cookie); + } + + for (unsigned int x = 0; x < lstColumnsToImport->GetCount(); x++) + lstColumnsToImport->Check(x, true); + } + + // Fix some widgets + wxCommandEvent ev; + OnChangeFormat(ev); +} + + +frmImport::~frmImport() +{ + SavePosition(); +} + + +void frmImport::OnHelp(wxCommandEvent &ev) +{ + DisplayHelp(wxT("sql-copy"), HELP_POSTGRESQL); +} + +void frmImport::OnChangeFormat(wxCommandEvent &ev) +{ + bool enabled = cbFormat->GetValue() == wxT("csv"); + chkHeader->Enable(enabled); + cbQuote->Enable(enabled); + cbEscape->Enable(enabled); + lstIgnoreForColumns->Enable(enabled); +} + + +void frmImport::OnOK(wxCommandEvent &ev) +{ + wxString query = wxEmptyString; + wxString columnsToImport = wxEmptyString; + wxString columnsToIgnoreForNulls = wxEmptyString; + bool allColumnsToImport = true; + bool someColumnsToIgnoreForNulls = false; + wxFileName fn; + wxFile *file; + bool copydone = false; + bool goterror = false; + int nCount = 8192; + + if (!done) + { + // Check checklistboxes + for (unsigned int x = 0; x < lstColumnsToImport->GetCount(); x++) + { + if (lstColumnsToImport->IsChecked(x)) + { + if (!columnsToImport.IsEmpty()) + { + columnsToImport.Append(wxT(",")); + } + columnsToImport.Append(qtIdent(lstColumnsToImport->GetString(x))); + } + else + { + allColumnsToImport = false; + } + } + for (unsigned int x = 0; x < lstIgnoreForColumns->GetCount(); x++) + { + if (lstIgnoreForColumns->IsChecked(x)) + { + if (!columnsToIgnoreForNulls.IsEmpty()) + { + columnsToIgnoreForNulls.Append(wxT(",")); + } + columnsToIgnoreForNulls.Append(qtIdent(lstIgnoreForColumns->GetString(x))); + someColumnsToIgnoreForNulls = true; + } + } + + // Check at least one column is selected else raise a warning + if (!allColumnsToImport && columnsToImport.Length() <= 0) + { + wxMessageBox(_("Please select at least one column to import."), _("Import"), wxICON_WARNING | wxOK, this); + return; + } + + // Build COPY query + query = wxT("COPY ") + object->GetSchema()->GetQuotedIdentifier() + wxT(".") + object->GetQuotedIdentifier(); + if (!allColumnsToImport) + { + query += wxT("(") + columnsToImport + wxT(")"); + } + query += wxT(" FROM STDIN "); + if (connection->BackendMinimumVersion(9, 0)) + { + query += wxT("("); + query += wxT("FORMAT '") + cbFormat->GetValue() + wxT("'"); + if (chkOids->GetValue()) + query += wxT(", OIDS"); + if (cbDelimiter->GetValue() == wxT("[tab]")) + query += wxT(", DELIMITER E'\\t'"); + else if (!cbDelimiter->GetValue().IsEmpty()) + query += wxT(", DELIMITER ") + connection->qtDbString(cbDelimiter->GetValue()); + if (!txtNull->GetValue().IsEmpty()) + query += wxT(", NULL ") + connection->qtDbString(txtNull->GetValue()); + if (cbFormat->GetValue() == wxT("csv")) + { + if (chkHeader->GetValue()) + query += wxT(", HEADER"); + if (!cbQuote->GetValue().IsEmpty()) + query += wxT(", QUOTE ") + connection->qtDbString(cbQuote->GetValue()); + if (!cbEscape->GetValue().IsEmpty()) + query += wxT(", ESCAPE ") + connection->qtDbString(cbEscape->GetValue()); + } + if (connection->BackendMinimumVersion(9, 1) && !cbEncoding->GetValue().IsEmpty()) + query += wxT(", ENCODING ") + connection->qtDbString(cbEncoding->GetValue()); + if (cbFormat->GetValue() == wxT("csv")) + { + if (someColumnsToIgnoreForNulls) + query += wxT(", FORCE_NOT_NULL (") + columnsToIgnoreForNulls + wxT(")"); + } + query += wxT(")"); + } + else + { + query += wxT("WITH "); + if (cbFormat->GetValue() == wxT("binary")) + query += wxT("BINARY "); + if (chkOids->GetValue()) + query += wxT("OIDS "); + if (!cbDelimiter->GetValue().IsEmpty()) + query += wxT("DELIMITER ") + connection->qtDbString(cbDelimiter->GetValue()); + if (!txtNull->GetValue().IsEmpty()) + query += wxT("NULL ") + connection->qtDbString(txtNull->GetValue()); + if (cbFormat->GetValue() == wxT("csv")) + { + query += wxT("CSV "); + if (connection->BackendMinimumVersion(8, 0) && chkHeader->GetValue()) + query += wxT("HEADER "); + if (connection->BackendMinimumVersion(8, 0) && !cbQuote->GetValue().IsEmpty()) + query += wxT("QUOTE ") + connection->qtDbString(cbQuote->GetValue()); + if (connection->BackendMinimumVersion(8, 0) && !cbEscape->GetValue().IsEmpty()) + query += wxT("ESCAPE ") + connection->qtDbString(cbEscape->GetValue()); + if (someColumnsToIgnoreForNulls) + query += wxT("FORCE NOT NULL ") + columnsToIgnoreForNulls + wxT(" "); + } + } + + // Check CSV file + if (!wxFileName::FileExists(pickerImportfile->GetPath())) + { + wxString msg; + msg.Printf(_("The file %s doesn't exist.\nPlease select a valid file."), pickerImportfile->GetPath().c_str()); + wxLogError(msg); + return; + } + + // Open CSV file + fn = wxFileName(pickerImportfile->GetPath()); + file = new wxFile(fn.GetFullPath(), wxFile::read); + + // Set range for gauge + gauge->SetRange(file->Length()); + + // Start COPY + if (!connection->StartCopy(query)) + { + goterror = true; + } + + // Send COPY data + while (!copydone && !goterror) + { + // Read a buffer + char *buffer = new char[nCount + 4]; + memset(buffer, 0, nCount + 4); + off_t len = file->Read(buffer, nCount); + + // If we read something, send it to the server + if (len > 0) + { + if (!connection->PutCopyData(buffer, len)) + { + goterror = true; + } + else + { + gauge->SetValue(gauge->GetValue() + len); + Update(); + } + } + + // If we read nothing, we're done + copydone = len == 0; + + // Clean the buffer + delete[] buffer; + } + + // Close CSV file + file->Close(); + + // End COPY + if (goterror) + { + connection->EndPutCopy(_("Copy failed!")); + } + else + { + goterror = !connection->EndPutCopy(wxT("")); + } + + // Get final status of the COPY command + if (!connection->GetCopyFinalStatus()) + { + goterror = true; + } + + if (goterror) + { + wxLogError(_("Copy failed!\n") + connection->GetLastError()); + } + else + { + btnOK->SetLabel(wxT("Done")); + done = true; + } + } + else + { + Close(); + } +} + +importFactory::importFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Import..."), _("Import CSV file into a relation")); +} + + +wxWindow *importFactory::StartDialog(frmMain *form, pgObject *obj) +{ + pgDatabase *db = obj->GetDatabase(); + wxString applicationname = appearanceFactory->GetLongAppName() + _(" - Import Tool"); + pgConn *conn = db->CreateConn(applicationname); + if (conn) + { + frmImport *frm = new frmImport(form, obj, conn); + frm->Show(); + } + return 0; +} + +bool importFactory::CheckEnable(pgObject *obj) +{ + return obj && (obj->IsCreatedBy(tableFactory)||obj->IsCreatedBy(pg_partitionFactory)); +} diff --git a/frm/frmMain.cpp b/frm/frmMain.cpp new file mode 100644 index 0000000..c2bb2ed --- /dev/null +++ b/frm/frmMain.cpp @@ -0,0 +1,1507 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmMain.cpp - The main form +// +// Note: Due to the size of frmMain, event handler, browser and statistics +// functions are in events.cpp. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#ifndef WIN32 +#include +#endif + +// wxWindows headers +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// wxAUI +#include + +// App headers +#include "utils/misc.h" +#include "frm/menu.h" +#include "utils/pgfeatures.h" +#include "debugger/debugger.h" +#include "frm/frmMain.h" +#include "ctl/ctlMenuToolbar.h" +#include "ctl/ctlSQLBox.h" +#include "db/pgConn.h" +#include "db/pgSet.h" +#include "agent/pgaJob.h" +#include "schema/pgDatabase.h" +#include "schema/pgServer.h" +#include "schema/pgObject.h" +#include "schema/pgCollection.h" +#include "frm/frmOptions.h" +#include "frm/frmAbout.h" +#include "frm/frmHint.h" +#include "frm/frmGrantWizard.h" +#include "frm/frmMainConfig.h" +#include "frm/frmHbaConfig.h" +#include "frm/frmPgpassConfig.h" +#include "frm/frmBackup.h" +#include "frm/frmBackupGlobals.h" +#include "frm/frmBackupServer.h" +#include "frm/frmRestore.h" +#include "frm/frmReport.h" +#include "frm/frmMaintenance.h" +#include "frm/frmStatus.h" +#include "frm/frmPassword.h" +#ifdef DATABASEDESIGNER +#include "frm/frmDatabaseDesigner.h" +#endif +#include "frm/frmQuery.h" +#include "frm/frmEditGrid.h" +#include "frm/frmImport.h" +#include "dlg/dlgServer.h" +#include "dlg/dlgDatabase.h" +#include "dlg/dlgSearchObject.h" +#include "schema/pgTable.h" +#include "schema/pgView.h" +#include "schema/pgFunction.h" +#include "schema/pgIndex.h" +#include "schema/pgTrigger.h" +#include "schema/pgRole.h" +#include "schema/pgRule.h" +#include "schema/pgServer.h" +#include "schema/pgTablespace.h" +#include "slony/slCluster.h" +#include "slony/slSet.h" +#include "schema/pgForeignKey.h" +#include "schema/pgCheck.h" +#include "schema/pgDomain.h" +#include "schema/pgEventTrigger.h" + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) +#include "utils/sshTunnel.h" +#endif + +#if wxDIALOG_UNIT_COMPATIBILITY +#error wxWindows must be compiled with wxDIALOG_UNIT_COMPATIBILITY=0! +#endif + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) +DEFINE_EVENT_TYPE(SSH_TUNNEL_ERROR_EVENT); +#endif + +frmMain::frmMain(const wxString &title) + : pgFrame((wxFrame *)NULL, title) +{ + msgLevel = 0; + lastPluginUtility = NULL; + pluginUtilityCount = 0; + m_refreshing = false; + + dlgName = wxT("frmMain"); + SetMinSize(wxSize(600, 450)); + RestorePosition(50, 50, 750, 550, 600, 450); + + SetFont(settings->GetSystemFont()); + + { + wxLogInfo(wxT("Using fontmetrics %d/%d, %d Point"), GetCharWidth(), GetCharHeight(), GetFont().GetPointSize()); + wxLogInfo(wxT("Native Description '%s'"), GetFont().GetNativeFontInfoDesc().c_str()); + wxWindowDC dc(this); + dc.SetFont(GetFont()); + + wxCoord w, h, d, e; + + dc.GetTextExtent(wxT("M"), &w, &h, &d, &e); + wxLogInfo(wxT("Draw size of 'M': w=%d, h=%d, descent %d, external lead %d."), w, h, d, e); + + dc.GetTextExtent(wxT("g"), &w, &h, &d, &e); + wxLogInfo(wxT("Draw size of 'g': w=%d, h=%d, descent %d, external lead %d."), w, h, d, e); + + dc.GetTextExtent(wxT("Mg"), &w, &h, &d, &e); + wxLogInfo(wxT("Draw size of 'Mg': w=%d, h=%d, descent %d, external lead %d."), w, h, d, e); + } + + // Current database + denyCollapseItem = wxTreeItemId(); + currentObject = 0; + + appearanceFactory->SetIcons(this); + + // notify wxAUI which frame to use + manager.SetManagedWindow(this); + manager.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_TRANSPARENT_DRAG | wxAUI_MGR_ALLOW_ACTIVE_PANE); + + // wxGTK needs this deferred + pgaFactory::RealizeImages(); + + CreateMenus(); + + // Setup the object browser + browser = new ctlTree(this, CTL_BROWSER, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS | wxSIMPLE_BORDER); + browser->SetImageList(imageList); + + // Setup the listview + listViews = new ctlAuiNotebook(this, CTL_NOTEBOOK, wxDefaultPosition, wxDefaultSize, wxAUI_NB_TOP | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_TAB_EXTERNAL_MOVE | wxAUI_NB_SCROLL_BUTTONS | wxAUI_NB_WINDOWLIST_BUTTON); + + // Switch to the generic list control. Native doesn't play well with + // multi-row select on Mac. +#ifdef __WXMAC__ + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), true); +#endif + + properties = new ctlListView(listViews, CTL_PROPVIEW, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER); + statistics = new ctlListView(listViews, CTL_STATVIEW, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER); + dependencies = new ctlListView(listViews, CTL_DEPVIEW, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER); + dependents = new ctlListView(listViews, CTL_REFVIEW, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER); + + + + // Switch back to the native list control. +#ifdef __WXMAC__ + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), false); +#endif + + listViews->AddPage(properties, _("Properties")); // NBP_PROPERTIES + listViews->AddPage(statistics, _("Statistics")); // NBP_STATISTICS + listViews->AddPage(dependencies, _("Dependencies")); // NBP_DEPENDENCIES + listViews->AddPage(dependents, _("Dependents")); // NBP_DEPENDENTS + + properties->SetImageList(imageList, wxIMAGE_LIST_SMALL); + statistics->SetImageList(imageList, wxIMAGE_LIST_SMALL); + dependencies->SetImageList(imageList, wxIMAGE_LIST_SMALL); + dependents->SetImageList(imageList, wxIMAGE_LIST_SMALL); + + wxColour background; + background = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE); + statistics->SetBackgroundColour(background); + dependencies->SetBackgroundColour(background); + dependents->SetBackgroundColour(background); + + // Setup the SQL pane + sqlPane = new ctlSQLBox(this, CTL_SQLPANE, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxSIMPLE_BORDER | wxTE_READONLY | wxTE_RICH2); + sqlPane->SetBackgroundColour(background); + + // Setup menus + pgaFactory::RegisterMenu(this, wxCommandEventHandler(frmMain::OnNew)); + menuFactories->RegisterMenu(this, wxCommandEventHandler(frmMain::OnAction)); + menuFactories->CheckMenu(0, menuBar, toolBar); + + // Kickstart wxAUI + manager.AddPane(browser, wxAuiPaneInfo().Name(wxT("objectBrowser")).Caption(_("Object browser")).Left().MinSize(wxSize(100, 200)).BestSize(wxSize(200, 450))); + manager.AddPane(listViews, wxAuiPaneInfo().Name(wxT("listViews")).Caption(_("Info pane")).Center().CaptionVisible(false).CloseButton(false).MinSize(wxSize(200, 100)).BestSize(wxSize(400, 200))); + manager.AddPane(sqlPane, wxAuiPaneInfo().Name(wxT("sqlPane")).Caption(_("SQL pane")).Bottom().MinSize(wxSize(200, 100)).BestSize(wxSize(400, 200))); + manager.AddPane(toolBar, wxAuiPaneInfo().Name(wxT("toolBar")).Caption(_("Tool bar")).ToolbarPane().Top().LeftDockable(false).RightDockable(false)); + + // Now load the layout + wxString perspective; + settings->Read(wxT("frmMain/Perspective-") + wxString(FRMMAIN_PERSPECTIVE_VER), &perspective, FRMMAIN_DEFAULT_PERSPECTIVE); + manager.LoadPerspective(perspective, true); + + // and reset the captions for the current language + manager.GetPane(wxT("objectBrowser")).Caption(_("Object browser")); + manager.GetPane(wxT("listViews")).Caption(_("Info pane")); + manager.GetPane(wxT("sqlPane")).Caption(_("SQL pane")); + manager.GetPane(wxT("toolBar")).Caption(_("Tool bar")); + + // Sync the View menu options + viewMenu->Check(MNU_SQLPANE, manager.GetPane(wxT("sqlPane")).IsShown()); + viewMenu->Check(MNU_OBJECTBROWSER, manager.GetPane(wxT("objectBrowser")).IsShown()); + viewMenu->Check(MNU_TOOLBAR, manager.GetPane(wxT("toolBar")).IsShown()); + + ResetLists(); + + // tell the manager to "commit" all the changes just made + manager.Update(); + + // Add the root node + serversObj = new pgServerCollection(serverFactory.GetCollectionFactory()); + wxTreeItemId root = browser->AddRoot(_("Server Groups"), serversObj->GetIconId(), -1, serversObj); + + // Work around a bug in the generic tree control in wxWidgets, + // Per http://trac.wxwidgets.org/ticket/10085 + browser->SetItemText(root, _("Server Groups")); + + // Load servers + RetrieveServers(); + + browser->Expand(root); + browser->SortChildren(root); + browser->SetFocus(); +} + + +frmMain::~frmMain() +{ + // Store the servers, to ensure we store the last database/schema etc + StoreServers(); + + settings->Write(wxT("frmMain/Perspective-") + wxString(FRMMAIN_PERSPECTIVE_VER), manager.SavePerspective()); + manager.UnInit(); + + // Clear the treeview + browser->DeleteAllItems(); + + if (treeContextMenu) + delete treeContextMenu; + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + if(pgadminTunnelThread && pgadminTunnelThread->IsAlive()) + { + pgadminTunnelThread->Cleanup(); + pgadminTunnelThread = NULL; + } +#endif +} + + + +void frmMain::CreateMenus() +{ + // to add a new menu or context menu to the main window, i.e. define a possible + // action on a pgObject, everything has to go into this method. Doing menu related + // stuff elsewhere is plain wrong! + // Create a proper actionFactory (or contextActionFactory) for each of your new actions + // in the new frmXXX.cpp and register it here. + + fileMenu = new wxMenu(); + pluginsMenu = new wxMenu(); + viewMenu = new wxMenu(); + editMenu = new wxMenu(); + newMenu = new wxMenu(); + toolsMenu = new wxMenu(); + slonyMenu = new wxMenu(); + scriptingMenu = new wxMenu(); + viewDataMenu = new wxMenu(); + debuggingMenu = new wxMenu(); + reportMenu = new wxMenu(); + wxMenu *cfgMenu = new wxMenu(); + helpMenu = new wxMenu(); + newContextMenu = new wxMenu(); + + toolBar = new ctlMenuToolbar(this, -1, wxDefaultPosition, wxDefaultSize, wxTB_FLAT | wxTB_NODIVIDER ); + toolBar->SetToolBitmapSize(wxSize(32, 32)); + menuFactories = new menuFactoryList(); + + // Load plugins - must do this after creating the menus and the factories + LoadPluginUtilities(); + + //-------------------------- + fileMenu->Append(MNU_SAVEDEFINITION, _("&Save Definition..."), _("Save the SQL definition of the selected object.")); + fileMenu->AppendSeparator(); + new addServerFactory(menuFactories, fileMenu, toolBar); + + viewMenu->Append(MNU_OBJECTBROWSER, _("&Object browser\tCtrl-Alt-O"), _("Show or hide the object browser."), wxITEM_CHECK); + viewMenu->Append(MNU_SQLPANE, _("&SQL pane\tCtrl-Alt-S"), _("Show or hide the SQL pane."), wxITEM_CHECK); + viewMenu->Append(MNU_TOOLBAR, _("&Tool bar\tCtrl-Alt-T"), _("Show or hide the tool bar."), wxITEM_CHECK); + viewMenu->AppendSeparator(); + viewMenu->Append(MNU_DEFAULTVIEW, _("&Default view\tCtrl-Alt-V"), _("Restore the default view.")); + viewMenu->AppendSeparator(); + actionFactory *refFact = new refreshFactory(menuFactories, viewMenu, toolBar); + new countRowsFactory(menuFactories, viewMenu, 0); + new refreshMatViewFactory(menuFactories, viewMenu, 0); + new refreshConcurrentlyMatViewFactory(menuFactories, viewMenu, 0); + new executePgstattupleFactory(menuFactories, viewMenu, 0); + new executePgstatindexFactory(menuFactories, viewMenu, 0); + new enabledisableRuleFactory(menuFactories, toolsMenu, 0); + new enabledisableTriggerFactory(menuFactories, toolsMenu, 0); + new enabledisableEventTriggerFactory(menuFactories, toolsMenu, 0); + new disableAllTriggersFactory(menuFactories, toolsMenu, 0); + new enableAllTriggersFactory(menuFactories, toolsMenu, 0); + new validateForeignKeyFactory(menuFactories, toolsMenu, 0); + new validateCheckFactory(menuFactories, toolsMenu, 0); + new validateDomainCheckFactory(menuFactories, toolsMenu, 0); + toolsMenu->AppendSeparator(); + + //-------------------------- + new separatorFactory(menuFactories); + + toolBar->AddSeparator(); + + new passwordFactory(menuFactories, fileMenu, 0); + fileMenu->AppendSeparator(); + optionsFactory *optFact = new optionsFactory(menuFactories, fileMenu, 0); + fileMenu->AppendSeparator(); + new mainConfigFileFactory(menuFactories, fileMenu, 0); + new hbaConfigFileFactory(menuFactories, fileMenu, 0); + new pgpassConfigFileFactory(menuFactories, fileMenu, 0); + + fileMenu->AppendSeparator(); + fileMenu->Append(MNU_EXIT, _("E&xit\tCtrl-Q"), _("Quit this program.")); + + new slonyRestartFactory(menuFactories, slonyMenu, 0); + new slonyUpgradeFactory(menuFactories, slonyMenu, 0); + new slonyFailoverFactory(menuFactories, slonyMenu, 0); + new slonyLockSetFactory(menuFactories, slonyMenu, 0); + new slonyUnlockSetFactory(menuFactories, slonyMenu, 0); + new slonyMergeSetFactory(menuFactories, slonyMenu, 0); + new slonyMoveSetFactory(menuFactories, slonyMenu, 0); + toolsMenu->Append(MNU_SLONY_SUBMENU, _("Slony Replication"), slonyMenu); + + propFactory = new propertyFactory(menuFactories, 0, toolBar); + new separatorFactory(menuFactories); + + + // ------------------------- + + editMenu->Append(MNU_COPY, _("&Copy\tCtrl-C"), _("Copy selected text to clipboard")); + editMenu->AppendSeparator(); + + // ------------------------- + + //-------------------------- + + newMenuFactory = new submenuFactory(menuFactories); // placeholder where "New objects" submenu will be inserted + editMenu->Append(newMenuFactory->GetId(), _("New &Object"), newMenu, _("Create a new object.")); + editMenu->AppendSeparator(); + + + //-------------------------- + + new connectServerFactory(menuFactories, toolsMenu, 0); + new disconnectServerFactory(menuFactories, toolsMenu, 0); + new disconnectDatabaseFactory(menuFactories, toolsMenu, 0); + + new startServiceFactory(menuFactories, toolsMenu, 0); + new stopServiceFactory(menuFactories, toolsMenu, 0); + new reloadconfServiceFactory(menuFactories, toolsMenu, 0); + new pausereplayServiceFactory(menuFactories, toolsMenu, 0); + new resumereplayServiceFactory(menuFactories, toolsMenu, 0); + new addnamedrestorepointServiceFactory(menuFactories, toolsMenu, 0); + + new createFactory(menuFactories, editMenu, toolBar); + new dropFactory(menuFactories, editMenu, toolBar); + new dropCascadedFactory(menuFactories, editMenu, 0); + new truncateFactory(menuFactories, editMenu, 0); + new truncateCascadedFactory(menuFactories, editMenu, 0); + new resetTableStatsFactory(menuFactories, editMenu, 0); + new resetFunctionStatsFactory(menuFactories, editMenu, 0); + new reassignDropOwnedFactory(menuFactories, editMenu, 0); + new moveTablespaceFactory(menuFactories, editMenu, 0); + new searchObjectFactory(menuFactories, editMenu, 0); + editMenu->AppendSeparator(); + + new separatorFactory(menuFactories); + + toolBar->AddSeparator(); + toolsMenu->AppendSeparator(); + + debuggingMenuFactory = new submenuFactory(menuFactories); // placeholder where "Debugging" submenu will be inserted + toolsMenu->Append(debuggingMenuFactory->GetId(), _("&Debugging"), debuggingMenu, _("Debugging options for the selected item.")); + new debuggerFactory(menuFactories, debuggingMenu, 0); + new breakpointFactory(menuFactories, debuggingMenu, 0); + + new queryToolFactory(menuFactories, toolsMenu, toolBar); + scriptingMenuFactory = new submenuFactory(menuFactories); // placeholder where "Query Template" submenu will be inserted + toolsMenu->Append(scriptingMenuFactory->GetId(), _("Scripts"), scriptingMenu, _("Start Query Tool with scripted query.")); + new queryToolSqlFactory(menuFactories, scriptingMenu, 0); + new queryToolCreateCascadeFactory(menuFactories, scriptingMenu, 0); + new queryToolSelectFactory(menuFactories, scriptingMenu, 0); + new queryToolExecFactory(menuFactories, scriptingMenu, 0); + new queryToolInsertFactory(menuFactories, scriptingMenu, 0); + new queryToolUpdateFactory(menuFactories, scriptingMenu, 0); + new queryToolDeleteFactory(menuFactories, scriptingMenu, 0); + +#ifdef DATABASEDESIGNER + new databaseDesignerFactory(menuFactories, toolsMenu, toolBar); +#endif + + viewdataMenuFactory = new submenuFactory(menuFactories); // placeholder where "View data" submenu will be inserted + toolsMenu->Append(viewdataMenuFactory->GetId(), _("View &Data"), viewDataMenu, _("View data.")); + + reportMenuFactory = new submenuFactory(menuFactories); // placeholder where "Reports" submenu will be inserted + toolsMenu->Append(reportMenuFactory->GetId(), _("&Reports"), reportMenu, _("Create reports about the selected item.")); + new reportObjectPropertiesFactory(menuFactories, reportMenu, 0); + new reportObjectDdlFactory(menuFactories, reportMenu, 0); + new reportObjectDataDictionaryFactory(menuFactories, reportMenu, 0); + new reportObjectStatisticsFactory(menuFactories, reportMenu, 0); + new reportObjectDependenciesFactory(menuFactories, reportMenu, 0); + new reportObjectDependentsFactory(menuFactories, reportMenu, 0); + new reportObjectListFactory(menuFactories, reportMenu, 0); + + + toolsMenu->AppendSeparator(); + + new editGridLimitedFactory(menuFactories, viewDataMenu, toolBar, 100, true); + new editGridLimitedFactory(menuFactories, viewDataMenu, toolBar, 100, false); + new editGridFactory(menuFactories, viewDataMenu, toolBar); + new editGridFilteredFactory(menuFactories, viewDataMenu, toolBar); + + new maintenanceFactory(menuFactories, toolsMenu, toolBar); + + new backupFactory(menuFactories, toolsMenu, 0); + new backupGlobalsFactory(menuFactories, toolsMenu, 0); + new backupServerFactory(menuFactories, toolsMenu, 0); + new restoreFactory(menuFactories, toolsMenu, 0); + new importFactory(menuFactories, toolsMenu, 0); + + new grantWizardFactory(menuFactories, toolsMenu, 0); + new mainConfigFactory(menuFactories, cfgMenu, 0); + new hbaConfigFactory(menuFactories, cfgMenu, 0); + toolsMenu->Append(MNU_CONFIGSUBMENU, _("Server Configuration"), cfgMenu); + toolsMenu->AppendSeparator(); + + new runNowFactory(menuFactories, toolsMenu, 0); + toolsMenu->AppendSeparator(); + + new separatorFactory(menuFactories); + + new propertyFactory(menuFactories, editMenu, 0); + new serverStatusFactory(menuFactories, toolsMenu, 0); + + // Add the plugin toolbar button/menu + new pluginButtonMenuFactory(menuFactories, pluginsMenu, toolBar, pluginUtilityCount); + + //-------------------------- + toolBar->AddSeparator(); + + actionFactory *helpFact = new contentsFactory(menuFactories, helpMenu, 0); + new hintFactory(menuFactories, helpMenu, toolBar, true); + new faqFactory(menuFactories, helpMenu, 0); + new bugReportFactory(menuFactories, helpMenu, 0); + + helpMenu->AppendSeparator(); + + new pgsqlHelpFactory(menuFactories, helpMenu, toolBar, true); + if (!appearanceFactory->GetHideEnterprisedbHelp()) + new edbHelpFactory(menuFactories, helpMenu, toolBar, true); + if (!appearanceFactory->GetHideGreenplumHelp()) + new greenplumHelpFactory(menuFactories, helpMenu, toolBar, true); + new slonyHelpFactory(menuFactories, helpMenu, toolBar, true); + + // Don't include this seperator on Mac, because the only option + // under it will be moved to the application menu. +#ifndef __WXMAC__ + helpMenu->AppendSeparator(); +#endif + + actionFactory *abFact = new aboutFactory(menuFactories, helpMenu, 0); + +#ifdef __WXMAC__ + wxApp::s_macPreferencesMenuItemId = optFact->GetId(); + wxApp::s_macExitMenuItemId = MNU_EXIT; + wxApp::s_macAboutMenuItemId = abFact->GetId(); +#else + (void)optFact; + (void)abFact; +#endif + + + menuBar = new wxMenuBar(); + menuBar->Append(fileMenu, _("&File")); + menuBar->Append(editMenu, _("&Edit")); + // Changing the caption of the plugins menu also needs a similar change below + menuBar->Append(pluginsMenu, _("&Plugins")); + menuBar->Append(viewMenu, _("&View")); + menuBar->Append(toolsMenu, _("&Tools")); + menuBar->Append(helpMenu, _("&Help")); + SetMenuBar(menuBar); + + // Disable the plugins menu if there aren't any. + if (!pluginUtilityCount) + { + pluginsMenu->Append(MNU_DUMMY, _("No plugins installed")); + pluginsMenu->Enable(MNU_DUMMY, false); + } + + treeContextMenu = 0; + + // Status bar + statusBar = CreateStatusBar(4); + int iWidths[4] = {0, -1, 400, 100}; + SetStatusWidths(4, iWidths); + SetStatusBarPane(-1); + statusBar->SetStatusText(wxT(""), 0); + statusBar->SetStatusText(_("Ready."), 1); + statusBar->SetStatusText(_("0 Secs"), 3); + + wxAcceleratorEntry entries[4]; + entries[0].Set(wxACCEL_NORMAL, WXK_F5, refFact->GetId()); + entries[1].Set(wxACCEL_NORMAL, WXK_DELETE, MNU_DELETE); + entries[2].Set(wxACCEL_NORMAL, WXK_F1, helpFact->GetId()); + entries[3].Set(wxACCEL_SHIFT, WXK_F10, MNU_CONTEXTMENU); + wxAcceleratorTable accel(4, entries); + + SetAcceleratorTable(accel); + + // Display the bar and configure buttons. + toolBar->Realize(); +} + + +void frmMain::Refresh(pgObject *data) +{ + bool done = false; + pgObject *obj = NULL; + + StartMsg(data->GetTranslatedMessage(REFRESHINGDETAILS)); + browser->Freeze(); + + wxTreeItemId currentItem = data->GetId(); + if (currentItem) + obj = browser->GetObject(currentItem); + + if (obj && obj->CheckOpenDialogs(browser, currentItem)) + { + wxString msg = _("There are properties dialogues open for one or more objects that would be refreshed. Please close the properties dialogues and try again."); + wxMessageBox(msg, _("Cannot refresh browser"), wxICON_WARNING | wxOK); + } + else + { + if (data->GetMetaType() == PGM_SCHEMA && !data->IsCollection() && data->GetConnection()->BackendMinimumVersion(9, 3)) + { + // Event triggers backend functions are at schema level. + // Hence, we can consider that Event Triggers at schema level and partly at database. + // So, if any schema is refreshed, we need to the event trigger collection as well. + // It's a special case, which effects the schema operations on the event triggers as well. + // To solve this, we are navigating to the parent node (database node), and then locating event trigger collections. + // Once we've found the event triggers collection, we refresh it. + // + wxTreeItemId dbItem = browser->GetItemParent(browser->GetItemParent(browser->GetSelection())); + pgCollection *eventTrgCol = browser->FindCollection(eventTriggerFactory, dbItem); + + if(eventTrgCol) + Refresh(eventTrgCol); + } + + // Scan the child nodes and make a list of those that are expanded + // This is not an exact science as node names may change etc. + wxArrayString expandedNodes; + GetExpandedChildNodes(currentItem, expandedNodes); + + browser->DeleteChildren(currentItem); + + // refresh information about the object + data->SetDirty(); + + pgObject *newData = data->Refresh(browser, currentItem); + done = !data->GetConnection() || data->GetConnection()->GetStatus() == PGCONN_OK; + + if (newData != data) + { + wxLogInfo(wxT("Deleting %s %s for refresh"), data->GetTypeName().c_str(), data->GetQuotedFullIdentifier().c_str()); + + if (data == currentObject) + currentObject = newData; + + if (newData) + { + wxLogInfo(wxT("Replacing with new node %s %s for refresh"), newData->GetTypeName().c_str(), newData->GetQuotedFullIdentifier().c_str()); + + newData->SetId(currentItem); // not done automatically + browser->SetItemData(currentItem, newData); + + // Update the node text if this is an object, as it may have been renamed + if (!newData->IsCollection()) + browser->SetItemText(currentItem, newData->GetDisplayName()); + + delete data; + data = NULL; + } + else + { + wxLogInfo(wxT("No object to replace: vanished after refresh.")); + + // If the connection is dead, just return here + if (data->GetConnection()->GetStatus() != PGCONN_OK) + { + CheckAlive(); + browser->Thaw(); + return; + } + + wxTreeItemId delItem = currentItem; + currentItem = browser->GetItemParent(currentItem); + browser->SelectItem(currentItem); + browser->Delete(delItem); + } + } + + if (currentItem) + { + // Select the current node + execSelChange(currentItem, currentItem == browser->GetSelection()); + + // Attempt to expand any child nodes that were previously expanded + ExpandChildNodes(currentItem, expandedNodes); + } + } + + browser->Thaw(); + EndMsg(done); +} + +void frmMain::OnCopy(wxCommandEvent &ev) +{ + wxString text; + + // Attempt to copy from the current object + + // Listview + ctlListView *lv = dynamic_cast(currentControl); + if (lv) + { + int row = lv->GetFirstSelected(); + + while (row >= 0) + { + for (int col = 0; col < lv->GetColumnCount(); col++) + { + text.Append(lv->GetText(row, col) + wxT("\t")); + } + text.Append(wxT("\n")); + row = lv->GetNextSelected(row); + } + text = text.Trim(); + } + + // ctlSQLBox + ctlSQLBox *sb = dynamic_cast(currentControl); + if (sb) + { + text = sb->GetSelectedText(); + } + + // Set the clipboard text + if (text.Length() > 0 && wxTheClipboard->Open()) + { + wxTheClipboard->SetData(new wxTextDataObject(wxTextBuffer::Translate(text))); + wxTheClipboard->Close(); + } +} + +void frmMain::GetExpandedChildNodes(wxTreeItemId node, wxArrayString &expandedNodes) +{ + wxTreeItemIdValue cookie; + wxTreeItemId child = browser->GetFirstChild(node, cookie); + + while (child.IsOk()) + { + if (browser->IsExpanded(child)) + { + GetExpandedChildNodes(child, expandedNodes); + expandedNodes.Add(GetNodePath(child)); + } + + child = browser->GetNextChild(node, cookie); + } +} + +void frmMain::ExpandChildNodes(wxTreeItemId node, wxArrayString &expandedNodes) +{ + wxTreeItemIdValue cookie; + wxTreeItemId child = browser->GetFirstChild(node, cookie); + + while (child.IsOk()) + { + if (expandedNodes.Index(GetNodePath(child)) != wxNOT_FOUND) + { + browser->Expand(child); + ExpandChildNodes(child, expandedNodes); + } + + child = browser->GetNextChild(node, cookie); + } +} + +wxString frmMain::GetNodePath(wxTreeItemId node) +{ + wxString path; + path = browser->GetItemText(node).BeforeFirst('(').Trim(); + + wxTreeItemId parent = browser->GetItemParent(node); + while (parent.IsOk()) + { + path = browser->GetItemText(parent).BeforeFirst('(').Trim() + wxT("/") + path; + parent = browser->GetItemParent(parent); + } + + return path; +} + +// Return the path for the current node +wxString frmMain::GetCurrentNodePath() +{ + return GetNodePath(currentObject->GetId()); +} + +// Attempt to reselect the node with the given path +bool frmMain::SetCurrentNode(wxTreeItemId node, const wxString &origPath) +{ + wxString path = origPath.Lower(); + wxTreeItemIdValue cookie; + wxTreeItemId child = browser->GetFirstChild(node, cookie); + + + while (child.IsOk()) + { + wxString actNodePath = GetNodePath(child).Lower(); + + if(path.StartsWith(actNodePath)) + { + if(!browser->IsExpanded(child)) + { + browser->SelectItem(child, true); + browser->Expand(child); + } + + if (actNodePath == path) + { + browser->SelectItem(child, true); + return true; + } + else if (SetCurrentNode(child, path)) + return true; + } + child = browser->GetNextChild(node, cookie); + + } + + return false; +} + +void frmMain::ShowObjStatistics(pgObject *data, wxWindow *ctrl) +{ + + // Refresh panes if they're currently shown on screen, unless + // they've been specifically requested (eg. a notebook + // event is telling us they're about to become visible). + + if ((!ctrl && statistics->IsShownOnScreen()) || ctrl == statistics) + { + statistics->Freeze(); + data->ShowStatistics(this, statistics); + statistics->Thaw(); + } + + if ((!ctrl && dependencies->IsShownOnScreen()) || ctrl == dependencies) + { + dependencies->Freeze(); + data->ShowDependencies(this, dependencies); + dependencies->Thaw(); + } + + if ((!ctrl && dependents->IsShownOnScreen()) || ctrl == dependents) + { + dependents->Freeze(); + data->ShowDependents(this, dependents); + dependents->Thaw(); + } +} + + +// Ensure we show the data in any tabs that become visible +void frmMain::OnPageChange(wxAuiNotebookEvent &event) +{ + pgObject *data = browser->GetObject(browser->GetSelection()); + + if (!data) + return; + + ShowObjStatistics(data, ((wxAuiNotebook *)event.GetEventObject())->GetPage(event.GetSelection())); +} + + +ctlListView *frmMain::GetStatistics() +{ + return statistics; +} + +ctlListView *frmMain::GetDependencies() +{ + return dependencies; +} + +ctlListView *frmMain::GetReferencedBy() +{ + return dependents; +} + +bool frmMain::CheckAlive() +{ + bool userInformed = false; + bool closeIt = false; + + wxTreeItemIdValue foldercookie; + wxTreeItemId folderitem = browser->GetFirstChild(browser->GetRootItem(), foldercookie); + while (folderitem) + { + if (browser->ItemHasChildren(folderitem)) + { + wxCookieType cookie; + wxTreeItemId serverItem = browser->GetFirstChild(folderitem, cookie); + while (serverItem) + { + pgServer *server = (pgServer *)browser->GetObject(serverItem); + + if (server && server->IsCreatedBy(serverFactory) && server->connection()) + { + if (server->connection()->IsAlive()) + { + wxCookieType cookie2; + wxTreeItemId item = browser->GetFirstChild(serverItem, cookie2); + while (item) + { + pgObject *obj = browser->GetObject(item); + if (obj && obj->IsCreatedBy(databaseFactory.GetCollectionFactory())) + { + wxCookieType cookie3; + item = browser->GetFirstChild(obj->GetId(), cookie3); + while (item) + { + pgDatabase *db = (pgDatabase *)browser->GetObject(item); + if (db && db->IsCreatedBy(databaseFactory)) + { + pgConn *conn = db->GetConnection(); + if (conn) + { + if (!conn->IsAlive() && (conn->GetStatus() == PGCONN_BROKEN || conn->GetStatus() == PGCONN_BAD)) + { + conn->Close(); + if (!userInformed) + { + wxMessageDialog dlg(this, _("Do you want to attempt to reconnect to the database?"), + wxString::Format(_("Connection to database %s lost."), db->GetName().c_str()), + wxICON_EXCLAMATION | wxYES_NO | wxYES_DEFAULT); + + closeIt = (dlg.ShowModal() != wxID_YES); + userInformed = true; + } + if (closeIt) + { + db->Disconnect(); + + browser->DeleteChildren(db->GetId()); + db->UpdateIcon(browser); + } + else + { + // Create a server object and connect it. + wxBusyInfo waiting(wxString::Format(_("Reconnecting to database %s"), + db->GetName().c_str()), this); + + // Give the UI a chance to redraw + wxSafeYield(); + wxMilliSleep(100); + wxSafeYield(); + + if (!conn->Reconnect()) + { + db->Disconnect(); + + browser->DeleteChildren(db->GetId()); + db->UpdateIcon(browser); + } + else + // Indicate things are back to normal + userInformed = false; + } + + } + } + } + item = browser->GetNextChild(obj->GetId(), cookie3); + } + } + item = browser->GetNextChild(serverItem, cookie2); + } + } + else + { + if (server->connection()->GetStatus() == PGCONN_BROKEN || server->connection()->GetStatus() == PGCONN_BAD) + { + server->connection()->Close(); + if (!userInformed) + { + wxMessageDialog dlg(this, _("Do you want to attempt to reconnect to the server?"), + wxString::Format(_("Connection to server %s lost."), server->GetName().c_str()), + wxICON_EXCLAMATION | wxYES_NO | wxYES_DEFAULT); + + closeIt = (dlg.ShowModal() != wxID_YES); + userInformed = true; + } + if (closeIt) + { + server->Disconnect(this); + browser->SelectItem(serverItem); + execSelChange(serverItem, true); + browser->DeleteChildren(serverItem); + } + else + { + // Create a server object and connect it. + wxBusyInfo waiting(wxString::Format(_("Reconnecting to server %s (%s:%d)"), + server->GetDescription().c_str(), server->GetName().c_str(), server->GetPort()), this); + + // Give the UI a chance to redraw + wxSafeYield(); + wxMilliSleep(100); + wxSafeYield(); + + if (!server->connection()->Reconnect()) + { + server->Disconnect(this); + browser->SelectItem(serverItem); + execSelChange(serverItem, true); + browser->DeleteChildren(serverItem); + } + else + // Indicate things are back to normal + userInformed = false; + } + } + } + } + + serverItem = browser->GetNextChild(folderitem, cookie); + } + } + folderitem = browser->GetNextChild(browser->GetRootItem(), foldercookie); + } + return userInformed; +} + + +wxTreeItemId frmMain::RestoreEnvironment(pgServer *server) +{ + wxTreeItemId item, lastItem; + wxString lastDatabase = server->GetLastDatabase(); + if (lastDatabase.IsNull()) + return item; + + wxCookieType cookie; + pgObject *data = 0; + item = browser->GetFirstChild(server->GetId(), cookie); + while (item) + { + data = browser->GetObject(item); + if (data && data->IsCreatedBy(databaseFactory.GetCollectionFactory())) + break; + // Get the next item + item = browser->GetNextChild(server->GetId(), cookie); + } + if (!item) + return item; + + // found DATABASES item + listViews->SetSelection(NBP_PROPERTIES); + data->ShowTree(this, browser, 0, 0); + lastItem = item; + + item = browser->GetFirstChild(lastItem, cookie); + while (item) + { + data = browser->GetObject(item); + if (data && data->IsCreatedBy(databaseFactory) && data->GetName() == lastDatabase) + break; + // Get the next item + item = browser->GetNextChild(lastItem, cookie); + } + if (!item) + return lastItem; + + // found last DATABASE + data->ShowTree(this, browser, 0, 0); + lastItem = item; + + wxString lastSchema = server->GetLastSchema(); + if (lastSchema.IsNull()) + return lastItem; + + item = browser->GetFirstChild(lastItem, cookie); + while (item) + { + data = browser->GetObject(item); + if (data && data->GetMetaType() == PGM_SCHEMA) + break; + // Get the next item + item = browser->GetNextChild(lastItem, cookie); + } + if (!item) + return lastItem; + + // found SCHEMAS item + data->ShowTree(this, browser, 0, 0); + lastItem = item; + + item = browser->GetFirstChild(lastItem, cookie); + while (item) + { + data = browser->GetObject(item); + if (data && data->GetMetaType() == PGM_SCHEMA && data->GetName() == lastSchema) + break; + // Get the next item + item = browser->GetNextChild(lastItem, cookie); + } + + return (item ? item : lastItem); +} + + +int frmMain::ReconnectServer(pgServer *server, bool restore) +{ + // Create a server object and connect it. + wxBusyInfo waiting(wxString::Format(_("Connecting to server %s (%s:%d)"), + server->GetDescription().c_str(), server->GetName().c_str(), server->GetPort()), this); + + // Give the UI a chance to redraw + wxSafeYield(); + wxMilliSleep(100); + wxSafeYield(); + + int res = server->Connect(this, true, wxEmptyString, false, true); + + // Check the result, and handle it as appropriate + wxTreeItemId item; + switch (res) + { + case PGCONN_OK: + { + if (restore && server->GetRestore()) + StartMsg(_("Restoring previous environment")); + else + StartMsg(_("Establishing connection")); + + wxLogInfo(wxT("pgServer object initialised as required.")); + + server->ShowTreeDetail(browser); + + browser->Freeze(); + if (restore && server->GetRestore()) + item = RestoreEnvironment(server); + else + item = server->GetId(); + browser->Thaw(); + + if (item) + { + browser->SelectItem(item); + + wxSafeYield(); + browser->Expand(item); + browser->EnsureVisible(item); + } + + if (item) + EndMsg(true); + else + { + if (restore && server->GetRestore()) + EndMsg(false); + else + EndMsg(true); + } + if (item) + GetMenuFactories()->CheckMenu((pgObject *)browser->GetItemData(item), GetMenuBar(), (ctlMenuToolbar *)GetToolBar()); + else + GetMenuFactories()->CheckMenu(server, GetMenuBar(), (ctlMenuToolbar *)GetToolBar()); + browser->SetFocus(); + return res; + } + case PGCONN_DNSERR: + /* + // looks strange to me. Shouldn_t server be removed from the tree as well? + delete server; + OnAddServer(wxCommandEvent()); + break; + */ + case PGCONN_BAD: + ReportConnError(server); + break; + + default: + wxLogInfo(wxT("pgServer object didn't initialise because the user aborted.")); + break; + } + + server->Disconnect(this); + return res; +} + + +bool frmMain::reportError(const wxString &error, const wxString &msgToIdentify, const wxString &hint) +{ + bool identified = false; + + wxString translated = wxGetTranslation(msgToIdentify); + if (translated != msgToIdentify) + { + identified = (error.Find(translated) >= 0); + } + + if (!identified) + { + if (msgToIdentify.Left(20) == wxT("Translator attention")) + identified = (error.Find(msgToIdentify.Mid(msgToIdentify.Find('!') + 1)) >= 0); + else + identified = (error.Find(msgToIdentify) >= 0); + } + + if (identified) + { + if (frmHint::WantHint(hint)) + frmHint::ShowHint(this, hint, error); + } + return identified; +} + + +void frmMain::ReportConnError(pgServer *server) +{ + wxString error = server->GetLastError(); + bool wantHint = false; + + wantHint = reportError(error, __("Translator attention: must match libpq translation!Is the server running on host"), HINT_CONNECTSERVER); + if (!wantHint) + { + wantHint = reportError(error, __("Translator attention: must match backend translation!no pg_hba.conf entry for"), HINT_MISSINGHBA); + } + if (!wantHint) + { + wantHint = reportError(error, __("Translator attention: must match backend translation!Ident authentication failed"), HINT_MISSINGIDENT); + } + if (!wantHint) + { + wxLogError(__("Error connecting to the server: %s"), error.c_str()); + } +} + + +void frmMain::StoreServers() +{ + wxLogInfo(wxT("Storing listed servers for later...")); + + // Store the currently listed servers for later retrieval. + pgServer *server; + int numServers = 0; + + // Get the hostname for later... + char buf[255]; + gethostname(buf, 255); + wxString hostname = wxString(buf, wxConvUTF8); + + wxTreeItemIdValue foldercookie; + wxTreeItemId folderitem = browser->GetFirstChild(browser->GetRootItem(), foldercookie); + while (folderitem) + { + if (browser->ItemHasChildren(folderitem)) + { + wxTreeItemIdValue servercookie; + wxTreeItemId serveritem = browser->GetFirstChild(folderitem, servercookie); + while (serveritem) + { + server = (pgServer *)browser->GetItemData(serveritem); + if (server != NULL && server->IsCreatedBy(serverFactory)) + { + wxString key; + ++numServers; + + key.Printf(wxT("Servers/%d/"), numServers); + settings->Write(key + wxT("Server"), server->GetName()); + settings->Write(key + wxT("HostAddr"), server->GetHostAddr()); + settings->Write(key + wxT("Description"), server->GetDescription()); + settings->Write(key + wxT("Service"), server->GetService()); + settings->Write(key + wxT("ServiceID"), server->GetServiceID()); + settings->Write(key + wxT("DiscoveryID"), server->GetDiscoveryID()); + settings->WriteInt(key + wxT("Port"), server->GetPort()); + settings->WriteBool(key + wxT("StorePwd"), server->GetStorePwd()); + settings->Write(key + wxT("Rolename"), server->GetRolename()); + settings->WriteBool(key + wxT("Restore"), server->GetRestore()); + settings->Write(key + wxT("Database"), server->GetDatabaseName()); + settings->Write(key + wxT("Username"), server->GetUsername()); + settings->Write(key + wxT("LastDatabase"), server->GetLastDatabase()); + settings->Write(key + wxT("LastSchema"), server->GetLastSchema()); + settings->Write(key + wxT("DbRestriction"), server->GetDbRestriction()); + settings->Write(key + wxT("Colour"), server->GetColour()); + settings->WriteInt(key + wxT("SSL"), server->GetSSL()); + settings->Write(key + wxT("Group"), server->GetGroup()); + settings->Write(key + wxT("SSLCert"), server->GetSSLCert()); + settings->Write(key + wxT("SSLKey"), server->GetSSLKey()); + settings->Write(key + wxT("SSLRootCert"), server->GetSSLRootCert()); + settings->Write(key + wxT("SSLCrl"), server->GetSSLCrl()); + settings->WriteBool(key + wxT("SSLCompression"), server->GetSSLCompression()); +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + settings->WriteBool(key + wxT("SSHTunnel"), server->GetSSHTunnel()); + settings->Write(key + wxT("TunnelHost"), server->GetTunnelHost()); + settings->Write(key + wxT("TunnelUserName"), server->GetTunnelUserName()); + settings->WriteBool(key + wxT("TunnelModePwd"), server->GetAuthModePwd()); + settings->Write(key + wxT("PublicKeyFile"), server->GetPublicKeyFile()); + settings->Write(key + wxT("IdentityFile"), server->GetIdentityFile()); + settings->WriteInt(key + wxT("TunnelPort"), server->GetTunnelPort()); +#endif + pgCollection *coll = browser->FindCollection(databaseFactory, server->GetId()); + if (coll) + { + treeObjectIterator dbs(browser, coll); + pgDatabase *db; + + while ((db = (pgDatabase *)dbs.GetNextObject()) != 0) + settings->Write(key + wxT("Databases/") + db->GetName() + wxT("/SchemaRestriction"), db->GetSchemaRestriction()); + } + } + serveritem = browser->GetNextChild(folderitem, servercookie); + } + } + folderitem = browser->GetNextChild(browser->GetRootItem(), foldercookie); + } + + // Write the server count + settings->WriteInt(wxT("Servers/Count"), numServers); + settings->FlushChanges(); + wxLogInfo(wxT("Stored %d servers."), numServers); +} + + +void frmMain::RetrieveServers() +{ + wxString label; + int total = 0; + wxTreeItemIdValue groupcookie; + wxTreeItemId groupitem; + + // Retrieve previously stored servers + wxLogInfo(wxT("Reloading servers...")); + + // Create all servers' nodes + serverFactory.CreateObjects(serversObj, browser); + + // Count number of servers and groups + groupitem = browser->GetFirstChild(browser->GetRootItem(), groupcookie); + while (groupitem) + { + total = browser->GetChildrenCount(groupitem, false); + label = browser->GetItemText(groupitem) + wxT(" (") + NumToStr((long)total) + wxT(")"); + browser->SetItemText(groupitem, label); + browser->SortChildren(groupitem); + browser->Expand(groupitem); + groupitem = browser->GetNextChild(browser->GetRootItem(), groupcookie); + } +} + +pgServer *frmMain::ConnectToServer(const wxString &servername, bool restore) +{ + wxTreeItemIdValue foldercookie, servercookie; + wxTreeItemId folderitem, serveritem; + pgObject *object; + pgServer *server; + + folderitem = browser->GetFirstChild(browser->GetRootItem(), foldercookie); + while (folderitem) + { + if (browser->ItemHasChildren(folderitem)) + { + serveritem = browser->GetFirstChild(folderitem, servercookie); + while (serveritem) + { + object = browser->GetObject(serveritem); + if (object && object->IsCreatedBy(serverFactory)) + { + server = (pgServer *)object; + if (server->GetDescription() == servername) + { + ReconnectServer(server, restore); + return server; + } + } + serveritem = browser->GetNextChild(folderitem, servercookie); + } + } + folderitem = browser->GetNextChild(browser->GetRootItem(), foldercookie); + } + + return 0; +} + +void frmMain::StartMsg(const wxString &msg) +{ + if (msgLevel++) + return; + + timermsg.Printf(wxT("%s..."), msg.c_str()); + wxBeginBusyCursor(); + stopwatch.Start(0); + + // Create a copy of the message, with %'s escaped for wxLogStatus + wxString logmsg = timermsg; + logmsg.Replace(wxT("%"), wxT("%%")); + wxLogStatus(logmsg); + + statusBar->SetStatusText(timermsg, 1); + statusBar->SetStatusText(wxT(""), 2); +} + + +void frmMain::EndMsg(bool done) +{ + msgLevel--; + + if (!msgLevel) + { + // Get the execution time & display it + float timeval = stopwatch.Time(); + statusBar->SetStatusText(ElapsedTimeToStr(timeval), 3); + + // Display the name of the connection for currently selected object + wxString connection; + if (currentObject) + { + pgConn *conn = currentObject->GetConnection(); + + if (conn) + connection = conn->GetName(); + } + statusBar->SetStatusText(connection, 2); + + // Display the 'Done' message + if (done) + statusBar->SetStatusText(timermsg + _(" Done."), 1); + else + statusBar->SetStatusText(timermsg + _(" Failed."), 1); + + wxLogStatus( + wxT("%s (%s)"), timermsg.c_str(), + ElapsedTimeToStr(timeval).c_str() + ); + wxEndBusyCursor(); + } +} + + +void frmMain::SetStatusText(const wxString &msg) +{ + statusBar->SetStatusText(msg, 1); + statusBar->SetStatusText(wxEmptyString, 2); +} + +void frmMain::SetItemBackgroundColour(wxTreeItemId item, wxColour colour) +{ + wxTreeItemIdValue cookie; + + browser->SetItemBackgroundColour(item, wxColour(colour)); + if (browser->ItemHasChildren(item)) + { + wxTreeItemId childitem = browser->GetFirstChild(item, cookie); + while (childitem) + { + SetItemBackgroundColour(childitem, colour); + childitem = browser->GetNextChild(item, cookie); + } + } +} + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) +void frmMain::OnSSHTunnelEvent(wxCommandEvent &event) +{ + wxLogError(event.GetString()); +} +#endif + +///////////////////////////////////////// + + +contentsFactory::contentsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, _("&Help contents"), _("Open the helpfile.")); +} + + +wxWindow *contentsFactory::StartDialog(frmMain *form, pgObject *obj) +{ + DisplayHelp(wxT("index"), HELP_PGADMIN); + return 0; +} + + +faqFactory::faqFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, _("&FAQ"), _("Frequently asked questions.")); +} + + +wxWindow *faqFactory::StartDialog(frmMain *form, pgObject *obj) +{ + wxLaunchDefaultBrowser(wxT("http://www.pgadmin.org/support/faq.php")); + + return 0; +} + +#include "images/help.pngc" +#include "images/help2.pngc" +pgsqlHelpFactory::pgsqlHelpFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar, bool bigIcon) : actionFactory(list) +{ + mnu->Append(id, _("&PostgreSQL Help"), _("Display help on the PostgreSQL database system.")); + if (toolbar) + { + if (bigIcon) + toolbar->AddTool(id, wxEmptyString, *help2_png_bmp, _("Display help on SQL commands.")); + else + toolbar->AddTool(id, wxEmptyString, *help_png_bmp, _("Display help on SQL commands.")); + } +} + + +wxWindow *pgsqlHelpFactory::StartDialog(frmMain *form, pgObject *obj) +{ + DisplayHelp(wxT("index"), HELP_POSTGRESQL); + return 0; +} + +edbHelpFactory::edbHelpFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar, bool bigIcon) : actionFactory(list) +{ + mnu->Append(id, _("&EnterpriseDB Help"), _("Display help on the EnterpriseDB database system.")); +} + + +wxWindow *edbHelpFactory::StartDialog(frmMain *form, pgObject *obj) +{ + DisplayHelp(wxT("index"), HELP_ENTERPRISEDB); + return 0; +} + +greenplumHelpFactory::greenplumHelpFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar, bool bigIcon) : actionFactory(list) +{ + mnu->Append(id, _("&Greenplum Database Help"), _("Display help on the Greenplum Database system.")); +} + + +wxWindow *greenplumHelpFactory::StartDialog(frmMain *form, pgObject *obj) +{ + DisplayHelp(wxT("index"), HELP_GREENPLUM); + return 0; +} + + +slonyHelpFactory::slonyHelpFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar, bool bigIcon) : actionFactory(list) +{ + mnu->Append(id, _("&Slony Help"), _("Display help on the Slony replication system.")); +} + + +wxWindow *slonyHelpFactory::StartDialog(frmMain *form, pgObject *obj) +{ + DisplayHelp(wxT("index"), HELP_SLONY); + return 0; +} + +bugReportFactory::bugReportFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, _("&Bug Report"), _("How to send a bugreport to the pgAdmin Development Team.")); +} + + +wxWindow *bugReportFactory::StartDialog(frmMain *form, pgObject *obj) +{ + DisplayHelp(wxT("bugreport"), HELP_PGADMIN); + return 0; +} diff --git a/frm/frmMainConfig.cpp b/frm/frmMainConfig.cpp new file mode 100644 index 0000000..c5e4773 --- /dev/null +++ b/frm/frmMainConfig.cpp @@ -0,0 +1,717 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmMainConfig.cpp - Backend configuration tool +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#ifdef __WXMSW__ +#include +#include +#endif + +#include + +#include "ctl/ctlMenuToolbar.h" +#include "frm/frmMainConfig.h" +#include "frm/frmMain.h" +#include "dlg/dlgMainConfig.h" +#include "utils/utffile.h" +#include "schema/pgServer.h" +#include "frm/menu.h" +#include "utils/pgfeatures.h" + +#include +WX_DEFINE_OBJARRAY(pgConfigOrgLineArray); + +#define CTL_CFGVIEW 345 + + +BEGIN_EVENT_TABLE(frmMainConfig, frmConfig) + EVT_MENU(MNU_UNDO, frmMainConfig::OnUndo) + EVT_MENU(MNU_CONTENTS, frmMainConfig::OnContents) + EVT_LIST_ITEM_ACTIVATED(CTL_CFGVIEW, frmMainConfig::OnEditSetting) + EVT_LIST_ITEM_SELECTED(CTL_CFGVIEW, frmMainConfig::OnSelectSetting) +END_EVENT_TABLE() + + +#define BCE_TITLE _("Backend Configuration Editor") + + +frmMainConfig::frmMainConfig(frmMain *parent, pgServer *server) + : frmConfig(parent, BCE_TITLE, 0) +{ + wxString applicationname = appearanceFactory->GetLongAppName() + _(" - Configuration Editor"); + if (server) + { + conn = server->CreateConn(wxEmptyString, 0, applicationname); + serverVersionNumber = server->GetVersionNumber(); + } + else + serverVersionNumber = wxEmptyString; + + InitForm(); + Init(); + + if (conn) + { + if (serverFileName.IsEmpty()) + serverFileName = wxT("postgresql.conf"); + + + wxString txt; + txt.Printf(_(" - %s on %s (%s:%d)"), + serverFileName.c_str(), server->GetDescription().c_str(), + server->GetName().c_str(), server->GetPort()); + SetTitle(BCE_TITLE + txt); + + wxString str; + str = conn->ExecuteScalar(wxT("SELECT pg_file_read('") + serverFileName + wxT("', 0, ") + wxT("pg_file_length('") + serverFileName + wxT("'))")); + + DisplayFile(str); + + statusBar->SetStatusText(wxString::Format(_(" Configuration read from %s"), conn->GetHost().c_str())); + } +} + + +frmMainConfig::frmMainConfig(const wxString &title, const wxString &configFile) + : frmConfig(title + wxT(" - ") + _("Backend Configuration Editor"), configFile) +{ + InitForm(); + Init(); + OpenLastFile(); +} + + +frmMainConfig::~frmMainConfig() +{ + options.clear(); + categories.clear(); + lines.Clear(); +} + + +void frmMainConfig::Init(pgSettingReader *reader) +{ + pgSettingItem *item; + do + { + item = reader->GetNextItem(); + if (item) + { + if (item->context == pgSettingItem::PGC_INTERNAL) + delete item; + else + { + if (options[item->name]) + delete item; + else + { + options[item->name] = item; + + wxArrayString *category = categories[item->category]; + if (!category) + { + category = new wxArrayString; + categories[item->category] = category; + } + category->Add(item->name); + } + } + } + } + while (item); + + editMenu->Enable(MNU_DELETE, false); + toolBar->EnableTool(MNU_DELETE, false); +} + + +void frmMainConfig::Init() +{ + // Cleanup first, in case we're re-initing + options.clear(); + categories.clear(); + lines.Clear(); + + pgSettingReader *reader; + if (conn) + { + // read settings from server + reader = new pgSettingDbReader(conn); + } + else + { + // read settings from file. First, use localized file... + reader = new pgSettingFileReader(true); + + if (reader->IsValid()) + Init(reader); + delete reader; + + // ... then add default file + reader = new pgSettingFileReader(false); + } + + if (reader->IsValid()) + Init(reader); + + delete reader; +} + +void frmMainConfig::InitForm() +{ + appearanceFactory->SetIcons(this); + + InitFrame(wxT("frmMainConfig")); + RestorePosition(50, 50, 600, 600, 300, 200); + + cfgList = new ctlListView(this, CTL_CFGVIEW, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER); + + cfgList->SetImageList(configImageList, wxIMAGE_LIST_SMALL); + + cfgList->AddColumn(_("Setting name"), 120); + cfgList->AddColumn(_("Value"), 80); + if (conn) + cfgList->AddColumn(_("Current value"), 80); + cfgList->AddColumn(_("Comment"), 400); +} + +void frmMainConfig::OnSelectSetting(wxListEvent &event) +{ + + // Disable undo because we don't want to undo the wrong line. + editMenu->Enable(MNU_UNDO, false); + toolBar->EnableTool(MNU_UNDO, false); +} + +void frmMainConfig::OnEditSetting(wxListEvent &event) +{ + wxString name = cfgList->GetText(event.GetIndex()); + if (!name.IsEmpty()) + { + pgSettingItem *item = options[name]; + wxASSERT(item); + dlgMainConfig dlg(this, item); + dlg.Go(); + + if (item->orgLine && !item->newLine->Differs(item->orgLine)) + { + delete item->newLine; + item->newLine = 0; + } + else + { + changed = true; + fileMenu->Enable(MNU_SAVE, true); + editMenu->Enable(MNU_UNDO, true); + toolBar->EnableTool(MNU_SAVE, true); + toolBar->EnableTool(MNU_UNDO, true); + + + } + UpdateLine(event.GetIndex()); + } +} + + +void frmMainConfig::OnContents(wxCommandEvent &event) +{ + DisplayHelp(wxT("index"), HELP_PGADMIN); +} + + +wxString frmMainConfig::GetHelpPage() const +{ + wxString page; + if (page.IsEmpty()) + page = wxT("runtime-config"); + + return page; +} + + +void frmMainConfig::OnUndo(wxCommandEvent &ev) +{ + wxString name = cfgList->GetText(cfgList->GetSelection()); + if (!name.IsEmpty()) + { + pgSettingItem *item = options[name]; + if (item->newLine) + { + delete item->newLine; + item->newLine = 0; + UpdateLine(cfgList->GetSelection()); + } + } +} + + + +void frmMainConfig::UpdateLine(int pos) +{ + wxString name = cfgList->GetText(pos); + if (!name.IsEmpty()) + { + pgSettingItem *item = options[name]; + + pgConfigLine *line = item->newLine; + if (!line) + line = item->orgLine; + + wxString value, comment; + int imgIndex = 0; + if (line) + { + value = line->value; + comment = line->comment; + if (!line->isComment) + imgIndex = 1; + } + cfgList->SetItem(pos, 1, value); + + if (conn) + cfgList->SetItem(pos, 3, comment); + else + cfgList->SetItem(pos, 2, comment); + + cfgList->SetItemImage(pos, imgIndex, imgIndex); + } +} + + +void frmMainConfig::WriteFile(pgConn *conn) +{ + + size_t i; + + wxString str; + for (i = 0 ; i < lines.GetCount() ; i++) + str.Append(lines.Item(i).GetNewText() + wxT("\n")); + + for (i = 0 ; i < (size_t)cfgList->GetItemCount() ; i++) + { + pgSettingItem *item = options[cfgList->GetText(i)]; + + if (item && item->newLine && item->newLine->item && !item->orgLine) + str.Append(item->newLine->GetNewText() + wxT("\n")); + } + + + if (DoWriteFile(str, conn)) + { + changed = false; + fileMenu->Enable(MNU_SAVE, false); + editMenu->Enable(MNU_UNDO, false); + toolBar->EnableTool(MNU_SAVE, false); + toolBar->EnableTool(MNU_UNDO, false); + + size_t i; + for (i = 0 ; i < (size_t)cfgList->GetItemCount() ; i++) + { + pgSettingItem *item = options[cfgList->GetText(i)]; + + if (item && item->newLine) + { + if (!item->orgLine) + { + item->orgLine = new pgConfigOrgLine(item->newLine); + lines.Add(item->orgLine); + item->orgLine->item = item; + } + else + { + item->orgLine->comment = item->newLine->comment; + item->orgLine->isComment = item->newLine->isComment; + item->orgLine->value = item->newLine->value; + item->orgLine->text = item->orgLine->GetNewText(); + } + } + } + + + for (i = 0 ; i < lines.GetCount() ; i++) + { + pgConfigOrgLine &line = lines.Item(i); + if (line.item && line.item->newLine) + { + line.text = line.GetNewText(); + delete line.item->newLine; + line.item->newLine = 0; + } + } + } +} + + + +void frmMainConfig::DisplayFile(const wxString &str) +{ + Init(); + + filetype = wxTextFileType_Unix; + wxStringTokenizer strtok; + wxArrayString *unknownCategory = 0; + + if (str.Find('\r') >= 0) + { + if (str.Find(wxT("\n\r")) >= 0 || str.Find(wxT("\r\n"))) + filetype = wxTextFileType_Dos; + else + filetype = wxTextFileType_Mac; + + strtok.SetString(wxTextBuffer::Translate(str, wxTextFileType_Unix), wxT("\n"), wxTOKEN_RET_EMPTY); + } + else + strtok.SetString(str, wxT("\n"), wxTOKEN_RET_EMPTY); + + while (strtok.HasMoreTokens()) + { + pgConfigOrgLine *line = new pgConfigOrgLine(strtok.GetNextToken()); + lines.Add(line); + + // identify option + bool isComment = false; + const wxChar *p = line->text.c_str(); + + // identify keywords + while (*p && wxStrchr(wxT("# \n"), *p)) + { + if (*p == '#') + isComment = true; + p++; + } + + if (!*p) + isComment = true; + + line->isComment = isComment; + + const wxChar *p2 = p; + while (*p2 && *p2 != '#' && *p2 != ' ' && *p2 != '\t' && *p2 != '=') + p2++; + + if (p2 != p) + { + wxString keyword = line->text.Mid(p - line->text.c_str(), p2 - p); + + pgSettingItemHashmap::iterator it = options.find(keyword); + + pgSettingItem *item; + if (it == options.end()) + { + if (isComment) + continue; + + item = new pgSettingItem; + item->name = keyword; + item->category = _("Unknown"); + item->short_desc = _("Unknown option"); + item->extra_desc = _("This option is present in the configuration file, but not known to the configuration tool."); + item->SetType(wxT("string")); + + options[item->name] = item; + + if (!unknownCategory) + { + unknownCategory = new wxArrayString; + categories[item->category] = unknownCategory; + } + unknownCategory->Add(item->name); + } + else + item = it->second; + + + if (!isComment || !item->orgLine || item->orgLine->isComment) + { + line->item = item; + if (item->orgLine) + item->orgLine->item = 0; + item->orgLine = line; + } + while (*p2 && *p2 != '=') + p2++; + + p2++; // skip = + while (*p2 && wxStrchr(wxT(" \t"), *p2)) + p2++; + + wxChar quoteChar = 0; + if (wxStrchr(wxT("'\""), *p2)) + quoteChar = *p2++; + + const wxChar *p3 = p2; + while (*p3) + { + if (*p3 == quoteChar || (!quoteChar && wxStrchr(wxT(" \t#"), *p3))) + break; + p3++; + } + if (p2 != p3) + { + line->value = line->text.Mid(p2 - line->text.c_str(), p3 - p2); + if (quoteChar) + p3++; + + const wxChar *p4 = p3; + while (*p4 && wxStrchr(wxT(" \t#"), *p4)) + p4++; + + line->commentIndent = line->text.Mid(p3 - line->text.c_str(), p4 - p3); + line->comment = p4; + } + } + } + + cfgList->DeleteAllItems(); + + double versionNum; + bool versionRetVal = serverVersionNumber.ToDouble(&versionNum); + + // we want to show options ordered by category/name + // category might be localized, and we want a distinct category ordering + + FillList(wxT("listen_addresses")); // Connections and Authentication / Connection Settings + FillList(wxT("authentication_timeout")); // Connections and Authentication / Security and Authentication + FillList(wxT("check_function_bodies")); // Client Connection Defaults / Statement Behaviour + FillList(wxT("lc_messages")); // Client Connection Defaults / Locale and Formatting + if (versionRetVal && versionNum < 8.4) + FillList(wxT("explain_pretty_print")); // Client Connection Defaults / Other Defaults + FillList(wxT("enable_hashjoin")); // Query Tuning / Planner Method Configuration + FillList(wxT("cpu_operator_cost")); // Query Tuning / Planner Cost Constants + if (!conn || !conn->GetIsGreenplum()) // Greenplum doesn't have the Genetic Query Optimizer + FillList(wxT("geqo")); // Query Tuning / Genetic Query Optimizer + FillList(wxT("default_statistics_target")); // Query Tuning / Other Planner Options + FillList(wxT("deadlock_timeout")); // Lock Management + FillList(wxT("shared_buffers")); // Resource Usage / Memory + if (versionRetVal && versionNum < 8.4) + FillList(wxT("max_fsm_pages")); // Resource Usage / Free Space Map + FillList(wxT("bgwriter_delay")); // Resource Usage + FillList(wxT("max_files_per_process")); // Resource Usage / Kernel Resources + FillList(wxT("log_connections")); // Reporting and Logging / What to Log + FillList(wxT("client_min_messages")); // Reporting and Logging / When to Log + FillList(wxT("log_destination")); // Reporting and Logging / Where to Log + FillList(wxT("stats_command_string"), wxT("track_activities")); // Statistics / Query and Index Statistics Collector + FillList(wxT("log_executor_stats")); // Statistics / Monitoring + FillList(wxT("fsync")); // Write-Ahead Log / Settings + FillList(wxT("checkpoint_segments")); // Write-Ahead Log / Checkpoints + if (versionRetVal && versionNum <= 8.4) + FillList(wxT("add_missing_from")); // Version and Platform Compatibility / Previous PostgreSQL Version + FillList(wxT("transform_null_equals")); // Version and Platform Compatibility / Other Platforms and Clients + if (!conn || !conn->GetIsGreenplum()) // Greenplum doesn't have trace_notify visible + FillList(wxT("trace_notify")); // Developer Options + FillList(wxT("hba_file")); // Ungrouped + + + // for all we didn't get + while (!categories.empty()) + { + pgCategoryHashmap::iterator it = categories.begin(); + wxString missed = it->first; + FillList(it->second); + categories.erase(it); + } +} + + +void frmMainConfig::FillList(const wxString &categoryMember, const wxString &altCategoryMember) +{ + pgSettingItem *categoryItem = options[categoryMember]; + + if (!categoryItem && !altCategoryMember.IsEmpty()) + categoryItem = options[altCategoryMember]; + + wxASSERT_MSG(categoryItem, wxString::Format(wxT("%s/%s"), categoryMember.c_str(), altCategoryMember.c_str())); + + if (categoryItem) + { + FillList(categories[categoryItem->category]); + categories.erase(categoryItem->category); + } +} + + +void frmMainConfig::FillList(wxArrayString *category) +{ + if (category) + { + size_t i; + for (i = 0 ; i < category->GetCount() ; i++) + { + pgSettingItem *item = options[category->Item(i)]; + wxASSERT(item); + + wxString value; + wxString comment; + int imgIndex = 0; + if (item->orgLine) + { + if (!item->orgLine->isComment) + imgIndex = 1; + value = item->orgLine->value; + comment = item->orgLine->comment; + comment.Replace(wxT("\t"), wxT(" ")); + } + long pos = cfgList->AppendItem(imgIndex, item->name, value); + if (conn) + { + cfgList->SetItem(pos, 2, item->value); + cfgList->SetItem(pos, 3, comment); + } + else + cfgList->SetItem(pos, 2, comment); + } + delete category; + } +} + + + +enum +{ + HINT_LISTEN_ADDRESSES, + HINT_AUTOVACUUM_CFG +}; + + +const wxChar *hintString[] = +{ + _("The PostgreSQL server engine is currently configured to listen for local connections only.\nYou might want to check \"listen_addresses\" to enable accessing the server over the network too."), + _("The autovacuum backend process is not running.\nIt is recommended to enable it by setting 'track_counts' and 'autovacuum' to 'on' in PostgreSQL 8.3 and above or 'stats_start_collector', 'stats_row_level' and 'autovacuum' to 'on' in earlier versions.") +}; + + +wxString frmMainConfig::GetHintString() +{ + wxArrayInt hints; + size_t i; + int autovacuum = 0; + bool autovacuumPresent = false; + + for (i = 0 ; i < (size_t)cfgList->GetItemCount() ; i++) + { + pgSettingItem *item = options[cfgList->GetText(i)]; + + if (item) + { + wxString name = item->name; + wxString value = item->GetActiveValue(); + if (name == wxT("listen_addresses")) + { + if (value.IsEmpty() || value == wxT("localhost")) + hints.Add(HINT_LISTEN_ADDRESSES); + } + else if (name == wxT("autovacuum")) + { + autovacuumPresent = true; + if (StrToBool(value)) + autovacuum++; + } + else if (name == wxT("stats_start_collector") || name == wxT("stats_row_level")) + { + if (StrToBool(value)) + autovacuum++; + } + else if (name == wxT("track_counts")) + { + // Double increment, because track_counts in 8.3 is worth both previous options. + if (StrToBool(value)) + autovacuum = autovacuum + 2; + } + } + } + + if (autovacuumPresent && autovacuum < 3) + hints.Add(HINT_AUTOVACUUM_CFG); + + wxString str; + for (i = 0 ; i < hints.GetCount() ; i++) + { + if (i) + str.Append(wxT("\n\n")); + str.Append(hintString[hints.Item(i)]); + } + + return str; +} + +void frmMainConfig::OnOpen(wxCommandEvent &event) +{ + if (CheckChanged(true)) + return; + +#ifdef __WXMSW__ + wxFileDialog dlg(this, _("Open configuration file"), lastDir, wxT(""), + _("Configuration files (*.conf)|*.conf|All files (*.*)|*.*"), wxFD_OPEN); +#else + wxFileDialog dlg(this, _("Open configuration file"), lastDir, wxT(""), + _("Configuration files (*.conf)|*.conf|All files (*)|*"), wxFD_OPEN); +#endif + if (dlg.ShowModal() == wxID_OK) + { + Init(); + + lastFilename = dlg.GetFilename(); + lastDir = dlg.GetDirectory(); + lastPath = dlg.GetPath(); + OpenLastFile(); + UpdateRecentFiles(); + } +} + +mainConfigFactory::mainConfigFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, wxT("postgresql.conf"), _("Edit general server configuration file.")); +} + + +wxWindow *mainConfigFactory::StartDialog(frmMain *form, pgObject *obj) +{ + pgServer *server = obj->GetServer(); + if (server) + { + frmConfig *frm = new frmMainConfig(form, server); + frm->Go(); + return frm; + } + return 0; +} + + +bool mainConfigFactory::CheckEnable(pgObject *obj) +{ + if (obj) + { + pgServer *server = obj->GetServer(); + if (server) + { + pgConn *conn = server->GetConnection(); + return conn && server->GetSuperUser() && conn->HasFeature(FEATURE_FILEREAD); + } + } + return false; +} + + +mainConfigFileFactory::mainConfigFileFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, _("Open postgresql.conf..."), _("Open configuration editor with postgresql.conf.")); +} + + +wxWindow *mainConfigFileFactory::StartDialog(frmMain *form, pgObject *obj) +{ + frmConfig *dlg = new frmMainConfig(form); + dlg->Go(); + dlg->DoOpen(); + return dlg; +} diff --git a/frm/frmMaintenance.cpp b/frm/frmMaintenance.cpp new file mode 100644 index 0000000..d90bca0 --- /dev/null +++ b/frm/frmMaintenance.cpp @@ -0,0 +1,239 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmMaintenance.cpp - Maintenance options selection dialogue +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include +#include + + +// App headers +#include "pgAdmin3.h" +#include "ctl/ctlMenuToolbar.h" +#include "frm/frmHint.h" +#include "frm/frmMaintenance.h" +#include "frm/frmMain.h" +#include "utils/sysLogger.h" +#include "schema/pgIndex.h" + +// Icons +#include "images/vacuum.pngc" + + +BEGIN_EVENT_TABLE(frmMaintenance, ExecutionDialog) + EVT_RADIOBOX(XRCID("rbxAction"), frmMaintenance::OnAction) +END_EVENT_TABLE() + +#define nbNotebook CTRL_NOTEBOOK("nbNotebook") +#define rbxAction CTRL_RADIOBOX("rbxAction") +#define chkFull CTRL_CHECKBOX("chkFull") +#define chkFreeze CTRL_CHECKBOX("chkFreeze") +#define chkAnalyze CTRL_CHECKBOX("chkAnalyze") +#define chkVerbose CTRL_CHECKBOX("chkVerbose") + +#define stBitmap CTRL("stBitmap", wxStaticBitmap) + + + +frmMaintenance::frmMaintenance(frmMain *form, pgObject *obj) : ExecutionDialog(form, obj) +{ + SetFont(settings->GetSystemFont()); + LoadResource(form, wxT("frmMaintenance")); + RestorePosition(); + + SetTitle(object->GetTranslatedMessage(MAINTENANCEDIALOGTITLE)); + + txtMessages = CTRL_TEXT("txtMessages"); + + // Icon + SetIcon(*vacuum_png_ico); + + // Note that under GTK+, SetMaxLength() function may only be used with single line text controls. + // (see http://docs.wxwidgets.org/2.8/wx_wxtextctrl.html#wxtextctrlsetmaxlength) +#ifndef __WXGTK__ + txtMessages->SetMaxLength(0L); +#endif + + if (object->GetMetaType() == PGM_INDEX || object->GetMetaType() == PGM_PRIMARYKEY || object->GetMetaType() == PGM_UNIQUE) + { + rbxAction->SetSelection(2); + rbxAction->Enable(0, false); + rbxAction->Enable(1, false); + } + wxCommandEvent ev; + OnAction(ev); +} + + +frmMaintenance::~frmMaintenance() +{ + SavePosition(); + Abort(); +} + + +wxString frmMaintenance::GetHelpPage() const +{ + wxString page; + switch ((XRCCTRL(*(frmMaintenance *)this, "rbxAction", wxRadioBox))->GetSelection()) + { + case 0: + page = wxT("pg/sql-vacuum"); + break; + case 1: + page = wxT("pg/sql-analyze"); + break; + case 2: + page = wxT("pg/sql-reindex"); + break; + case 3: + page = wxT("pg/sql-cluster"); + break; + } + return page; +} + + + +void frmMaintenance::OnAction(wxCommandEvent &ev) +{ + bool isVacuum = (rbxAction->GetSelection() == 0); + chkFull->Enable(isVacuum); + chkFreeze->Enable(isVacuum); + chkAnalyze->Enable(isVacuum); + + bool isReindex = (rbxAction->GetSelection() == 2); + bool isCluster = (rbxAction->GetSelection() == 3); + if (isReindex || (isCluster && !conn->BackendMinimumVersion(8, 4))) + { + chkVerbose->SetValue(false); + chkVerbose->Enable(false); + } + else + { + chkVerbose->SetValue(true); + chkVerbose->Enable(true); + } +} + + + +wxString frmMaintenance::GetSql() +{ + wxString sql; + + switch (rbxAction->GetSelection()) + { + case 0: + { + /* Warn about VACUUM FULL on < 9.0 */ + if (chkFull->GetValue() && + !conn->BackendMinimumVersion(9, 0)) + { + if (frmHint::ShowHint(this, HINT_VACUUM_FULL) == wxID_CANCEL) + return wxEmptyString; + } + sql = wxT("VACUUM "); + + if (chkFull->GetValue()) + sql += wxT("FULL "); + if (chkFreeze->GetValue()) + sql += wxT("FREEZE "); + if (chkVerbose->GetValue()) + sql += wxT("VERBOSE "); + if (chkAnalyze->GetValue()) + sql += wxT("ANALYZE "); + + if (object->GetMetaType() != PGM_DATABASE) + sql += object->GetQuotedFullIdentifier(); + + break; + } + case 1: + { + sql = wxT("ANALYZE "); + if (chkVerbose->GetValue()) + sql += wxT("VERBOSE "); + + if (object->GetMetaType() != PGM_DATABASE) + sql += object->GetQuotedFullIdentifier(); + + break; + } + case 2: + { + if (object->GetMetaType() == PGM_UNIQUE || object->GetMetaType() == PGM_PRIMARYKEY) + { + sql = wxT("REINDEX INDEX ") + object->GetQuotedFullIdentifier(); + } + else // Database, Tables, and Index (but not Constraintes ones) + { + sql = wxT("REINDEX ") + object->GetTypeName().Upper() + + wxT(" ") + object->GetQuotedFullIdentifier(); + } + break; + } + case 3: + { + sql = wxT("CLUSTER "); + + if (chkVerbose->GetValue()) + sql += wxT("VERBOSE "); + if (object->GetMetaType() == PGM_TABLE) + sql += object->GetQuotedFullIdentifier(); + if (object->GetMetaType() == PGM_INDEX || object->GetMetaType() == PGM_UNIQUE + || object->GetMetaType() == PGM_PRIMARYKEY) + { + sql += object->GetSchema()->GetQuotedFullIdentifier(); + if (conn->BackendMinimumVersion(8, 4)) + { + sql += wxT(" USING ") + object->GetQuotedIdentifier(); + } + else + { + sql += wxT(" ON ") + object->GetQuotedIdentifier(); + } + } + } + } + + return sql; +} + + + +void frmMaintenance::Go() +{ + chkFull->SetFocus(); + Show(true); +} + + + +maintenanceFactory::maintenanceFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Maintenance..."), _("Maintain the current database or table.")); + toolbar->AddTool(id, wxEmptyString, *vacuum_png_bmp, _("Maintain the current database or table."), wxITEM_NORMAL); +} + + +wxWindow *maintenanceFactory::StartDialog(frmMain *form, pgObject *obj) +{ + frmMaintenance *frm = new frmMaintenance(form, obj); + frm->Go(); + return 0; +} + + +bool maintenanceFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->CanMaintenance(); +} diff --git a/frm/frmOptions.cpp b/frm/frmOptions.cpp new file mode 100644 index 0000000..96b3567 --- /dev/null +++ b/frm/frmOptions.cpp @@ -0,0 +1,1056 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmOptions.cpp - The main options dialogue +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// App headers +#include "frm/frmOptions.h" +#include "frm/frmMain.h" +#include "frm/frmHint.h" +#include "utils/sysSettings.h" +#include "utils/sysLogger.h" +#include "utils/misc.h" +#include "frm/menu.h" +#include "ctl/ctlColourPicker.h" + +// Must be after pgAdmin3.h or MSVC++ complains +#include + +#include "images/properties.pngc" + +#define BROWSER_ITEM _("Browser") +#define BROWSER_DISPLAY_ITEM _("Display") +#define BROWSER_PROPERTIES_ITEM _("Properties") +#define BROWSER_BINPATH_ITEM _("Binary paths") +#define BROWSER_MISC_ITEM _("UI Miscellaneous") +#define QUERYTOOL_ITEM _("Query tool") +#define QUERYTOOL_EDITOR_ITEM _("Query editor") +#define QUERYTOOL_COLOURS_ITEM _("Colours") +#define QUERYTOOL_RESULTS_ITEM _("Results grid") +#define QUERYTOOL_FILES_ITEM _("Query file") +#define QUERYTOOL_FAVOURITES_ITEM _("Favourites") +#define QUERYTOOL_MACROS_ITEM _("Macros") +#define QUERYTOOL_HISTORYFILE_ITEM _("History file") +#define DATABASEDESIGNER_ITEM _("Database Designer") +#define SERVERSTATUS_ITEM _("Server status") +#define MISC_ITEM _("Miscellaneous") +#define MISC_UI_ITEM _("User Interface") +#define MISC_HELPPATH_ITEM _("Help paths") +#define MISC_GURUHINTS_ITEM _("Guru hints") +#define MISC_LOGGING_ITEM _("Logging") + +#define txtPgHelpPath CTRL_TEXT("txtPgHelpPath") +#define txtEdbHelpPath CTRL_TEXT("txtEdbHelpPath") +#define txtGpHelpPath CTRL_TEXT("txtGpHelpPath") +#define txtSlonyHelpPath CTRL_TEXT("txtSlonyHelpPath") +#define pickerSlonyPath CTRL_DIRPICKER("pickerSlonyPath") +#define pickerPostgresqlPath CTRL_DIRPICKER("pickerPostgresqlPath") +#define pickerEnterprisedbPath CTRL_DIRPICKER("pickerEnterprisedbPath") +#define pickerGPDBPath CTRL_DIRPICKER("pickerGPDBPath") +#define txtSystemSchemas CTRL_TEXT("txtSystemSchemas") +#define pickerLogfile CTRL_FILEPICKER("pickerLogfile") +#define radLoglevel CTRL_RADIOBOX("radLoglevel") +#define txtMaxRows CTRL_TEXT("txtMaxRows") +#define txtMaxColSize CTRL_TEXT("txtMaxColSize") +#define pickerFont CTRL_FONTPICKER("pickerFont") +#define chkUnicodeFile CTRL_CHECKBOX("chkUnicodeFile") +#define chkWriteBOM CTRL_CHECKBOX("chkWriteBOM") +#define chkAskSaveConfirm CTRL_CHECKBOX("chkAskSaveConfirm") +#define chkAskDelete CTRL_CHECKBOX("chkAskDelete") +#define chkShowUsersForPrivileges CTRL_CHECKBOX("chkShowUsersForPrivileges") +#define txtAutoRowCount CTRL_TEXT("txtAutoRowCount") +#define txtIndent CTRL_TEXT("txtIndent") +#define chkSpacesForTabs CTRL_CHECKBOX("chkSpacesForTabs") +#define cbCopyQuote CTRL_COMBOBOX("cbCopyQuote") +#define cbCopyQuoteChar CTRL_COMBOBOX("cbCopyQuoteChar") +#define cbCopySeparator CTRL_COMBOBOX("cbCopySeparator") +#define chkStickySql CTRL_CHECKBOX("chkStickySql") +#define chkIndicateNull CTRL_CHECKBOX("chkIndicateNull") +#define txtDecimalMark CTRL_TEXT("txtDecimalMark") +#define chkColumnNames CTRL_CHECKBOX("chkColumnNames") +#define txtThousandsSeparator CTRL_TEXT("txtThousandsSeparator") +#define chkAutoRollback CTRL_CHECKBOX("chkAutoRollback") +#define chkAutoCommit CTRL_CHECKBOX("chkAutoCommit") +#define chkDoubleClickProperties CTRL_CHECKBOX("chkDoubleClickProperties") +#define chkShowNotices CTRL_CHECKBOX("chkShowNotices") +#define cbLanguage CTRL_COMBOBOX("cbLanguage") +#define pickerSqlFont CTRL_FONTPICKER("pickerSqlFont") +#define chkSuppressHints CTRL_CHECKBOX("chkSuppressHints") +#define chkResetHints CTRL_CHECKBOX("chkResetHints") +#define lstDisplay CTRL_CHECKLISTBOX("lstDisplay") +#define chkSystemObjects CTRL_CHECKBOX("chkSystemObjects") +#define chkIgnoreVersion CTRL_CHECKBOX("chkIgnoreVersion") +#define pickerIdleProcessColour CTRL_COLOURPICKER("pickerIdleProcessColour") +#define pickerActiveProcessColour CTRL_COLOURPICKER("pickerActiveProcessColour") +#define pickerSlowProcessColour CTRL_COLOURPICKER("pickerSlowProcessColour") +#define pickerBlockedProcessColour CTRL_COLOURPICKER("pickerBlockedProcessColour") +#define pickerFavouritesFile CTRL_FILEPICKER("pickerFavouritesFile") +#define pickerMacrosFile CTRL_FILEPICKER("pickerMacrosFile") +#define pickerHistoryFile CTRL_FILEPICKER("pickerHistoryFile") +#define pickerExtFormatCmd CTRL_FILEPICKER("pickerExtFormatCmd") +#define txtHistoryMaxQueries CTRL_TEXT("txtHistoryMaxQueries") +#define txtHistoryMaxQuerySize CTRL_TEXT("txtHistoryMaxQuerySize") +#define chkSQLUseSystemBackgroundColour CTRL_CHECKBOX("chkSQLUseSystemBackgroundColour") +#define chkSQLUseSystemForegroundColour CTRL_CHECKBOX("chkSQLUseSystemForegroundColour") +#define pickerSQLBackgroundColour CTRL_COLOURPICKER("pickerSQLBackgroundColour") +#define pickerSQLForegroundColour CTRL_COLOURPICKER("pickerSQLForegroundColour") +#define stSQLCustomBackgroundColour CTRL_STATIC("stSQLCustomBackgroundColour") +#define stSQLCustomForegroundColour CTRL_STATIC("stSQLCustomForegroundColour") +#define pickerSQLMarginBackgroundColour CTRL_COLOURPICKER("pickerSQLMarginBackgroundColour") +#define pickerSQLColour1 CTRL_COLOURPICKER("pickerSQLColour1") +#define pickerSQLColour2 CTRL_COLOURPICKER("pickerSQLColour2") +#define pickerSQLColour3 CTRL_COLOURPICKER("pickerSQLColour3") +#define pickerSQLColour4 CTRL_COLOURPICKER("pickerSQLColour4") +#define pickerSQLColour5 CTRL_COLOURPICKER("pickerSQLColour5") +#define pickerSQLColour6 CTRL_COLOURPICKER("pickerSQLColour6") +#define pickerSQLColour7 CTRL_COLOURPICKER("pickerSQLColour7") +#define pickerSQLColour10 CTRL_COLOURPICKER("pickerSQLColour10") +#define pickerSQLColour11 CTRL_COLOURPICKER("pickerSQLColour11") +#define pickerSQLCaretColour CTRL_COLOURPICKER("pickerSQLCaretColour") +#define chkKeywordsInUppercase CTRL_CHECKBOX("chkKeywordsInUppercase") +#define menus CTRL_TREE("menus") +#define pnlBrowserDisplay CTRL_PANEL("pnlBrowserDisplay") +#define pnlBrowserProperties CTRL_PANEL("pnlBrowserProperties") +#define pnlBrowserBinPath CTRL_PANEL("pnlBrowserBinPath") +#define pnlBrowserMisc CTRL_PANEL("pnlBrowserMisc") +#define pnlQueryToolEditor CTRL_PANEL("pnlQueryToolEditor") +#define pnlQueryToolColours CTRL_PANEL("pnlQueryToolColours") +#define pnlQueryToolResults CTRL_PANEL("pnlQueryToolResults") +#define pnlQueryToolFiles CTRL_PANEL("pnlQueryToolFiles") +#define pnlQueryToolFavourites CTRL_PANEL("pnlQueryToolFavourites") +#define pnlQueryToolMacros CTRL_PANEL("pnlQueryToolMacros") +#define pnlQueryToolHistoryFile CTRL_PANEL("pnlQueryToolHistoryFile") +#define pnlDatabaseDesigner CTRL_PANEL("pnlDatabaseDesigner") +#define pnlServerStatus CTRL_PANEL("pnlServerStatus") +#define pnlMiscUI CTRL_PANEL("pnlMiscUI") +#define pnlMiscHelpPath CTRL_PANEL("pnlMiscHelpPath") +#define pnlMiscGuruHints CTRL_PANEL("pnlMiscGuruHints") +#define pnlMiscLogging CTRL_PANEL("pnlMiscLogging") +#define cbRefreshOnClick CTRL_COMBOBOX("cbRefreshOnClick") +#define pickerFontDD CTRL_FONTPICKER("pickerFontDD") + + +BEGIN_EVENT_TABLE(frmOptions, pgDialog) + EVT_MENU(MNU_HELP, frmOptions::OnHelp) + EVT_BUTTON (XRCID("btnDefault"), frmOptions::OnDefault) + EVT_CHECKBOX(XRCID("chkSuppressHints"), frmOptions::OnSuppressHints) + EVT_CHECKBOX(XRCID("chkResetHints"), frmOptions::OnResetHints) + EVT_CHECKBOX(XRCID("chkSQLUseSystemBackgroundColour"), frmOptions::OnChangeSQLUseCustomColour) + EVT_CHECKBOX(XRCID("chkSQLUseSystemForegroundColour"), frmOptions::OnChangeSQLUseCustomColour) + EVT_BUTTON (wxID_OK, frmOptions::OnOK) + EVT_BUTTON (wxID_HELP, frmOptions::OnHelp) + EVT_BUTTON (wxID_CANCEL, frmOptions::OnCancel) + EVT_COMBOBOX(XRCID("cbCopyQuote"), frmOptions::OnChangeCopyQuote) + EVT_TREE_SEL_CHANGED(XRCID("menus"), frmOptions::OnTreeSelChanged) +END_EVENT_TABLE() + + +//---------------------------------------------------------------------------- +// wxRichTextFontDialog: a substitute for wxFontDialog, which is broken on +// Mac OS X Snow Leopard +//---------------------------------------------------------------------------- + +#ifdef __WXMAC__ +#if !wxCHECK_VERSION(2, 9, 0) + +#include +#include +#include + +class wxRichTextFontDialog: public wxFontDialogBase +{ +public: + wxRichTextFontDialog() : wxFontDialogBase() + { + Init(); /* must be + Create()d later */ + } + wxRichTextFontDialog(wxWindow *parent) + : wxFontDialogBase(parent) + { + Init(); + Create(parent); + } + wxRichTextFontDialog(wxWindow *parent, const wxFontData &data) + : wxFontDialogBase(parent, data) + { + Init(); + Create(parent, data); + } + + void Init() + { + m_title = _("Font"); + } + + virtual int ShowModal(); + + virtual void SetTitle( const wxString &title) + { + m_title = title; + } + virtual wxString GetTitle() const + { + return m_title; + } + +protected: + wxString m_title; + + DECLARE_DYNAMIC_CLASS_NO_COPY(wxRichTextFontDialog) + +}; + +IMPLEMENT_DYNAMIC_CLASS(wxRichTextFontDialog, wxDialog) + +int wxRichTextFontDialog::ShowModal() +{ + wxTextAttrEx attr; + if (m_fontData.GetInitialFont().Ok()) + attr.SetFont(m_fontData.GetInitialFont()); + + if (m_fontData.GetColour().Ok()) + attr.SetTextColour(m_fontData.GetColour()); + + wxRichTextFormattingDialog formatDlg(wxRICHTEXT_FORMAT_FONT, + GetParent(), GetTitle()); + formatDlg.SetAttributes(attr); + + if (formatDlg.ShowModal() == wxID_OK) + { + wxTextAttrEx attr(formatDlg.GetAttributes()); + + m_fontData.SetChosenFont(attr.GetFont()); + m_fontData.SetColour(attr.GetTextColour()); + + return wxID_OK; + } + else + return wxID_CANCEL; + +} + +#endif +#endif + +//---------------------------------------------------------------------------- + +frmOptions::frmOptions(frmMain *parent) +{ + wxTreeItemId root, node; + wxTreeItemIdValue cookie; + + mainForm = parent; + SetFont(settings->GetSystemFont()); + LoadResource(parent, wxT("frmOptions")); + + // Icon + SetIcon(*properties_png_ico); + RestorePosition(); + + wxAcceleratorEntry entries[1]; + + entries[0].Set(wxACCEL_NORMAL, WXK_F1, MNU_HELP); + + wxAcceleratorTable accel(1, entries); + SetAcceleratorTable(accel); + + wxTextValidator numval(wxFILTER_NUMERIC); + txtMaxRows->SetValidator(numval); + txtMaxColSize->SetValidator(numval); + txtAutoRowCount->SetValidator(numval); + txtIndent->SetValidator(numval); + txtHistoryMaxQueries->SetValidator(numval); + txtHistoryMaxQuerySize->SetValidator(numval); + + pickerLogfile->SetPath(settings->GetLogFile()); + radLoglevel->SetSelection(settings->GetLogLevel()); + txtMaxRows->SetValue(NumToStr(settings->GetMaxRows())); + txtMaxColSize->SetValue(NumToStr(settings->GetMaxColSize())); + chkAskSaveConfirm->SetValue(!settings->GetAskSaveConfirmation()); + chkAskDelete->SetValue(settings->GetConfirmDelete()); + chkShowUsersForPrivileges->SetValue(settings->GetShowUsersForPrivileges()); + txtAutoRowCount->SetValue(NumToStr(settings->GetAutoRowCountThreshold())); + txtIndent->SetValue(NumToStr(settings->GetIndentSpaces())); + chkSpacesForTabs->SetValue(settings->GetSpacesForTabs()); + cbCopyQuote->SetSelection(settings->GetCopyQuoting()); + cbCopyQuoteChar->SetValue(settings->GetCopyQuoteChar()); + cbRefreshOnClick->SetSelection(settings->GetRefreshOnClick()); + + wxString copySeparator = settings->GetCopyColSeparator(); + if (copySeparator == wxT("\t")) + copySeparator = _("Tab"); + cbCopySeparator->SetValue(copySeparator); + + chkStickySql->SetValue(settings->GetStickySql()); + chkIndicateNull->SetValue(settings->GetIndicateNull()); + txtThousandsSeparator->SetValue(settings->GetThousandsSeparator()); + chkAutoRollback->SetValue(settings->GetAutoRollback()); + chkAutoCommit->SetValue(settings->GetAutoCommit()); + chkDoubleClickProperties->SetValue(settings->GetDoubleClickProperties()); + txtDecimalMark->SetValue(settings->GetDecimalMark()); + chkColumnNames->SetValue(settings->GetColumnNames()); + chkShowNotices->SetValue(settings->GetShowNotices()); + + txtPgHelpPath->SetValue(settings->GetPgHelpPath()); + txtEdbHelpPath->SetValue(settings->GetEdbHelpPath()); + txtGpHelpPath->SetValue(settings->GetGpHelpPath()); + txtSlonyHelpPath->SetValue(settings->GetSlonyHelpPath()); + + txtSystemSchemas->SetValue(settings->GetSystemSchemas()); + chkUnicodeFile->SetValue(settings->GetUnicodeFile()); + chkWriteBOM->SetValue(settings->GetWriteBOM()); + chkSuppressHints->SetValue(settings->GetSuppressGuruHints()); + pickerSlonyPath->SetPath(settings->GetSlonyPath()); + pickerPostgresqlPath->SetPath(settings->GetPostgresqlPath()); + pickerEnterprisedbPath->SetPath(settings->GetEnterprisedbPath()); + pickerGPDBPath->SetPath(settings->GetGPDBPath()); + chkIgnoreVersion->SetValue(settings->GetIgnoreVersion()); + + // Get back the colours + pickerIdleProcessColour->SetColour(settings->GetIdleProcessColour()); + pickerActiveProcessColour->SetColour(settings->GetActiveProcessColour()); + pickerSlowProcessColour->SetColour(settings->GetSlowProcessColour()); + pickerBlockedProcessColour->SetColour(settings->GetBlockedProcessColour()); + + pickerFavouritesFile->SetPath(settings->GetFavouritesFile()); + pickerMacrosFile->SetPath(settings->GetMacrosFile()); + pickerHistoryFile->SetPath(settings->GetHistoryFile()); + pickerExtFormatCmd->SetPath(settings->GetExtFormatCmd()); + + txtHistoryMaxQueries->SetValue(NumToStr(settings->GetHistoryMaxQueries())); + txtHistoryMaxQuerySize->SetValue(NumToStr(settings->GetHistoryMaxQuerySize())); + + chkSQLUseSystemBackgroundColour->SetValue(settings->GetSQLBoxUseSystemBackground()); + chkSQLUseSystemForegroundColour->SetValue(settings->GetSQLBoxUseSystemForeground()); + UpdateColourControls(); + + pickerSQLColour1->SetColour(settings->GetSQLBoxColour(1)); + pickerSQLColour2->SetColour(settings->GetSQLBoxColour(2)); + pickerSQLColour3->SetColour(settings->GetSQLBoxColour(3)); + pickerSQLColour4->SetColour(settings->GetSQLBoxColour(4)); + pickerSQLColour5->SetColour(settings->GetSQLBoxColour(5)); + pickerSQLColour6->SetColour(settings->GetSQLBoxColour(6)); + pickerSQLColour7->SetColour(settings->GetSQLBoxColour(7)); + pickerSQLColour10->SetColour(settings->GetSQLBoxColour(10)); + pickerSQLColour11->SetColour(settings->GetSQLBoxColour(11)); + + chkKeywordsInUppercase->SetValue(settings->GetSQLKeywordsInUppercase()); + + cbLanguage->Append(_("Default")); + int sel = 0; + wxLanguage langId = settings->GetCanonicalLanguage(); + + int langCount = existingLangs.GetCount(); + if (langCount) + { + int langNo; + const wxLanguageInfo *langInfo; + for (langNo = 0; langNo < langCount ; langNo++) + { + langInfo = wxLocale::GetLanguageInfo(existingLangs.Item(langNo)); + cbLanguage->Append(wxT("(") + langInfo->CanonicalName + wxT(") ") + + existingLangNames.Item(langNo)); + if (langId == langInfo->Language) + sel = langNo + 1; + } + } + cbLanguage->SetSelection(sel); + + pickerFont->SetSelectedFont(settings->GetSystemFont()); + pickerSqlFont->SetSelectedFont(settings->GetSQLFont()); + pickerFontDD->SetSelectedFont(settings->GetDDFont()); + + // Load the display options + lstDisplay->Append(_("Databases")); + lstDisplay->Append(_("Tablespaces")); + lstDisplay->Append(_("pgAgent Jobs")); + lstDisplay->Append(_("Groups/group Roles")); + lstDisplay->Append(_("Users/login Roles")); + lstDisplay->Append(_("Resource Queues")); + lstDisplay->Append(_("Resource Groups")); + lstDisplay->Append(_("Catalogs")); + lstDisplay->Append(_("Casts")); + lstDisplay->Append(_("Event Triggers")); + lstDisplay->Append(_("Extensions")); + lstDisplay->Append(_("Foreign Data Wrappers")); + lstDisplay->Append(_("Foreign Servers")); + lstDisplay->Append(_("User Mappings")); + lstDisplay->Append(_("Languages")); + lstDisplay->Append(_("Schemas")); + lstDisplay->Append(_("Synonyms")); + lstDisplay->Append(_("Slony-I Clusters")); + lstDisplay->Append(_("Aggregates")); + lstDisplay->Append(_("Collations")); + lstDisplay->Append(_("Conversions")); + lstDisplay->Append(_("Domains")); + lstDisplay->Append(_("External Tables")); + lstDisplay->Append(_("Foreign Tables")); + lstDisplay->Append(_("FTS Configurations")); + lstDisplay->Append(_("FTS Dictionaries")); + lstDisplay->Append(_("FTS Parsers")); + lstDisplay->Append(_("FTS Templates")); + lstDisplay->Append(_("Functions")); + lstDisplay->Append(_("Operators")); + lstDisplay->Append(_("Operator Classes")); + lstDisplay->Append(_("Operator Families")); + lstDisplay->Append(_("Packages")); + lstDisplay->Append(_("Procedures")); + lstDisplay->Append(_("Sequences")); + lstDisplay->Append(_("Tables")); + lstDisplay->Append(_("Trigger Functions")); + lstDisplay->Append(_("Types")); + lstDisplay->Append(_("Views")); + + for (unsigned int x = 0; x < lstDisplay->GetCount(); x++) + lstDisplay->Check(x, settings->GetDisplayOption(lstDisplay->GetString(x))); + + chkSystemObjects->SetValue(settings->GetShowSystemObjects()); + + wxCommandEvent e; + OnChangeCopyQuote(e); + + // Fill the treeview + root = menus->AddRoot(_("Options")); + + node = menus->AppendItem(root, BROWSER_ITEM); + menus->AppendItem(node, BROWSER_DISPLAY_ITEM); + menus->AppendItem(node, BROWSER_PROPERTIES_ITEM); + menus->AppendItem(node, BROWSER_BINPATH_ITEM); + menus->AppendItem(node, BROWSER_MISC_ITEM); + + node = menus->AppendItem(root, QUERYTOOL_ITEM); + menus->AppendItem(node, QUERYTOOL_EDITOR_ITEM); + menus->AppendItem(node, QUERYTOOL_COLOURS_ITEM); + menus->AppendItem(node, QUERYTOOL_RESULTS_ITEM); + menus->AppendItem(node, QUERYTOOL_FILES_ITEM); + menus->AppendItem(node, QUERYTOOL_FAVOURITES_ITEM); + menus->AppendItem(node, QUERYTOOL_MACROS_ITEM); + menus->AppendItem(node, QUERYTOOL_HISTORYFILE_ITEM); + + node = menus->AppendItem(root, DATABASEDESIGNER_ITEM); + + node = menus->AppendItem(root, SERVERSTATUS_ITEM); + + node = menus->AppendItem(root, MISC_ITEM); + menus->AppendItem(node, MISC_UI_ITEM); + menus->AppendItem(node, MISC_HELPPATH_ITEM); + menus->AppendItem(node, MISC_GURUHINTS_ITEM); + menus->AppendItem(node, MISC_LOGGING_ITEM); + + menus->ExpandAllChildren(root); + + menuSelection = settings->GetOptionsLastTreeItem(); + wxTreeItemId menuItem = GetTreeItemByLabel(root, menuSelection); + if (!menuItem.IsOk()) + menuItem = menus->GetFirstChild(root, cookie); + + menus->SelectItem(menuItem); + ShowPanel(menuItem); +} + + +frmOptions::~frmOptions() +{ + SavePosition(); +} + +void frmOptions::OnHelp(wxCommandEvent &ev) +{ + DisplayHelp(wxT("options"), HELP_PGADMIN); +} + +void frmOptions::OnDefault(wxCommandEvent &ev) +{ + // Reset the display options to the defaults. + // Clear them all first + for (unsigned int x = 0; x < lstDisplay->GetCount(); x++) + lstDisplay->Check(x, settings->GetDisplayOption(lstDisplay->GetString(x), true)); +} + +void frmOptions::OnSuppressHints(wxCommandEvent &ev) +{ + if (chkSuppressHints->GetValue()) + chkResetHints->SetValue(false); +} + + +void frmOptions::OnResetHints(wxCommandEvent &ev) +{ + if (chkResetHints->GetValue()) + chkSuppressHints->SetValue(false); +} + +void frmOptions::UpdateColourControls() +{ + if (chkSQLUseSystemBackgroundColour->GetValue()) + { + pickerSQLBackgroundColour->Enable(false); + pickerSQLBackgroundColour->SetColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + stSQLCustomBackgroundColour->Enable(false); + } + else + { + pickerSQLBackgroundColour->Enable(true); + pickerSQLBackgroundColour->SetColour(settings->GetSQLBoxColourBackground()); + stSQLCustomBackgroundColour->Enable(true); + } + + if (chkSQLUseSystemForegroundColour->GetValue()) + { + pickerSQLForegroundColour->Enable(false); + pickerSQLForegroundColour->SetColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); + stSQLCustomForegroundColour->Enable(false); + } + else + { + pickerSQLForegroundColour->Enable(true); + pickerSQLForegroundColour->SetColour(settings->GetSQLBoxColourForeground()); + stSQLCustomForegroundColour->Enable(true); + } + + pickerSQLCaretColour->SetColour(settings->GetSQLColourCaret()); + + pickerSQLMarginBackgroundColour->SetColour(settings->GetSQLMarginBackgroundColour()); +} + +void frmOptions::OnChangeSQLUseCustomColour(wxCommandEvent &ev) +{ + UpdateColourControls(); +} + +void frmOptions::OnOK(wxCommandEvent &ev) +{ + // Check the PostgreSQL and EnterpriseDB paths +#ifdef __WXMSW__ + if (!pickerPostgresqlPath->GetPath().IsEmpty() && !isPgApp(pickerPostgresqlPath->GetPath() + wxT("\\pg_dump.exe"))) +#else + if (!pickerPostgresqlPath->GetPath().IsEmpty() && !isPgApp(pickerPostgresqlPath->GetPath() + wxT("/pg_dump"))) +#endif + { + wxMessageBox(_("The PostgreSQL bin path specified is not valid or does not contain a PostgreSQL pg_dump executable.\n\nPlease select another directory, or leave the path blank."), _("Error"), wxICON_ERROR | wxOK); + return; + } + +#ifdef __WXMSW__ + if (!pickerEnterprisedbPath->GetPath().IsEmpty() && !isEdbApp(pickerEnterprisedbPath->GetPath() + wxT("\\pg_dump.exe"))) +#else + if (!pickerEnterprisedbPath->GetPath().IsEmpty() && !isEdbApp(pickerEnterprisedbPath->GetPath() + wxT("/pg_dump"))) +#endif + { + wxMessageBox(_("The EnterpriseDB bin path specified is not valid or does not contain an EnterpriseDB pg_dump executable.\n\nPlease select another directory, or leave the path blank."), _("Error"), wxICON_ERROR | wxOK); + return; + } + +#ifdef __WXMSW__ + if (!pickerGPDBPath->GetPath().IsEmpty() && !isGpApp(pickerGPDBPath->GetPath() + wxT("\\pg_dump.exe"))) +#else + if (!pickerGPDBPath->GetPath().IsEmpty() && !isGpApp(pickerGPDBPath->GetPath() + wxT("/pg_dump"))) +#endif + { + wxMessageBox(_("The Greenplum bin path specified is not valid or does not contain a Greenplum pg_dump executable.\n\nPlease select another directory, or leave the path blank."), _("Error"), wxICON_ERROR | wxOK); + return; + } + + + if (txtDecimalMark->GetValue() != wxEmptyString) + { + // Check decimal mark <> thousands separator + if (txtDecimalMark->GetValue() == txtThousandsSeparator->GetValue()) + { + wxMessageBox(_("The decimal mark and thousands separator must not be equal."), _("Error"), wxICON_ERROR | wxOK); + return; + } + } + + // Clean and check the help paths + txtPgHelpPath->SetValue(CleanHelpPath(txtPgHelpPath->GetValue())); + if (!HelpPathValid(txtPgHelpPath->GetValue())) + { + wxMessageBox(_("An invalid PostgreSQL help path was specified.\n\nPlease enter another filename, directory or URL, or leave the path blank."), _("Error"), wxICON_ERROR | wxOK); + txtPgHelpPath->SetFocus(); + return; + } + + txtEdbHelpPath->SetValue(CleanHelpPath(txtEdbHelpPath->GetValue())); + if (!HelpPathValid(txtEdbHelpPath->GetValue())) + { + wxMessageBox(_("An invalid EnterpriseDB help path was specified.\n\nPlease enter another filename, directory or URL, or leave the path blank."), _("Error"), wxICON_ERROR | wxOK); + txtEdbHelpPath->SetFocus(); + return; + } + + txtGpHelpPath->SetValue(CleanHelpPath(txtGpHelpPath->GetValue())); + if (!HelpPathValid(txtGpHelpPath->GetValue())) + { + wxMessageBox(_("An invalid GreenplumDB help path was specified.\n\nPlease enter another filename, directory or URL, or leave the path blank."), _("Error"), wxICON_ERROR | wxOK); + txtGpHelpPath->SetFocus(); + return; + } + + txtSlonyHelpPath->SetValue(CleanHelpPath(txtSlonyHelpPath->GetValue())); + if (!HelpPathValid(txtSlonyHelpPath->GetValue())) + { + wxMessageBox(_("An invalid Slony help path was specified.\n\nPlease enter another filename, directory or URL, or leave the path blank."), _("Error"), wxICON_ERROR | wxOK); + txtSlonyHelpPath->SetFocus(); + return; + } + + // Logfile + wxString logFile = pickerLogfile->GetPath(); + wxLogInfo(wxT("Setting logfile to: %s"), logFile.c_str()); + settings->SetLogFile(logFile); + + // Loglevel + wxString logInfo = radLoglevel->GetStringSelection(); + wxLogInfo(wxT("Setting loglevel to: %s"), logInfo.c_str()); + int sel = radLoglevel->GetSelection(); + + switch(sel) + { + case(0): + settings->SetLogLevel(LOG_NONE); + break; + case(1): + settings->SetLogLevel(LOG_ERRORS); + break; + case(2): + settings->SetLogLevel(LOG_NOTICE); + break; + case(3): + settings->SetLogLevel(LOG_SQL); + break; + case(4): + settings->SetLogLevel(LOG_DEBUG); + break; + default: + settings->SetLogLevel(LOG_ERRORS); + break; + } + + // Query parameter + settings->SetMaxRows(StrToLong(txtMaxRows->GetValue())); + settings->SetMaxColSize(StrToLong(txtMaxColSize->GetValue())); + + settings->SetAskSaveConfirmation(!chkAskSaveConfirm->GetValue()); + settings->SetConfirmDelete(chkAskDelete->GetValue()); + settings->SetShowUsersForPrivileges(chkShowUsersForPrivileges->GetValue()); + settings->SetAutoRowCountThreshold(StrToLong(txtAutoRowCount->GetValue())); + settings->SetIndentSpaces(StrToLong(txtIndent->GetValue())); + settings->SetSpacesForTabs(chkSpacesForTabs->GetValue()); + settings->SetCopyQuoting(cbCopyQuote->GetCurrentSelection()); + settings->SetCopyQuoteChar(cbCopyQuoteChar->GetValue()); + settings->SetHistoryMaxQueries(StrToLong(txtHistoryMaxQueries->GetValue())); + settings->SetHistoryMaxQuerySize(StrToLong(txtHistoryMaxQuerySize->GetValue())); + settings->SetRefreshOnClick(cbRefreshOnClick->GetSelection()); + + wxString copySeparator = cbCopySeparator->GetValue(); + if (copySeparator == _("Tab")) + copySeparator = wxT("\t"); + settings->SetCopyColSeparator(copySeparator); + + settings->SetStickySql(chkStickySql->GetValue()); + settings->SetIndicateNull(chkIndicateNull->GetValue()); + settings->SetDecimalMark(txtDecimalMark->GetValue()); + settings->SetColumnNames(chkColumnNames->GetValue()); + settings->SetThousandsSeparator(txtThousandsSeparator->GetValue()); + settings->SetAutoRollback(chkAutoRollback->GetValue()); + settings->SetAutoCommit(chkAutoCommit->GetValue()); + settings->SetDoubleClickProperties(chkDoubleClickProperties->GetValue()); + settings->SetShowNotices(chkShowNotices->GetValue()); + + settings->SetUnicodeFile(chkUnicodeFile->GetValue()); + settings->SetWriteBOM(chkWriteBOM->GetValue()); + settings->SetSystemFont(pickerFont->GetSelectedFont()); + settings->SetSQLFont(pickerSqlFont->GetSelectedFont()); + settings->SetDDFont(pickerFontDD->GetSelectedFont()); + settings->SetSuppressGuruHints(chkSuppressHints->GetValue()); + settings->SetSlonyPath(pickerSlonyPath->GetPath()); + settings->SetPostgresqlPath(pickerPostgresqlPath->GetPath()); + settings->SetEnterprisedbPath(pickerEnterprisedbPath->GetPath()); + settings->SetGPDBPath(pickerGPDBPath->GetPath()); + + // Setup PostgreSQL/EnterpriseDB working paths +#if defined(__WXMSW__) + pgBackupExecutable = settings->GetPostgresqlPath() + wxT("\\pg_dump.exe"); + pgBackupAllExecutable = settings->GetPostgresqlPath() + wxT("\\pg_dumpall.exe"); + pgRestoreExecutable = settings->GetPostgresqlPath() + wxT("\\pg_restore.exe"); + + edbBackupExecutable = settings->GetEnterprisedbPath() + wxT("\\pg_dump.exe"); + edbBackupAllExecutable = settings->GetEnterprisedbPath() + wxT("\\pg_dumpall.exe"); + edbRestoreExecutable = settings->GetEnterprisedbPath() + wxT("\\pg_restore.exe"); + + gpBackupExecutable = settings->GetGPDBPath() + wxT("\\pg_dump.exe"); + gpBackupAllExecutable = settings->GetGPDBPath() + wxT("\\pg_dumpall.exe"); + gpRestoreExecutable = settings->GetGPDBPath() + wxT("\\pg_restore.exe"); +#else + pgBackupExecutable = settings->GetPostgresqlPath() + wxT("/pg_dump"); + pgBackupAllExecutable = settings->GetPostgresqlPath() + wxT("/pg_dumpall"); + pgRestoreExecutable = settings->GetPostgresqlPath() + wxT("/pg_restore"); + + edbBackupExecutable = settings->GetEnterprisedbPath() + wxT("/pg_dump"); + edbBackupAllExecutable = settings->GetEnterprisedbPath() + wxT("/pg_dumpall"); + edbRestoreExecutable = settings->GetEnterprisedbPath() + wxT("/pg_restore"); + + gpBackupExecutable = settings->GetGPDBPath() + wxT("/pg_dump"); + gpBackupAllExecutable = settings->GetGPDBPath() + wxT("/pg_dumpall"); + gpRestoreExecutable = settings->GetGPDBPath() + wxT("/pg_restore"); +#endif + + if (!wxFile::Exists(pgBackupExecutable)) + pgBackupExecutable = wxEmptyString; + if (!wxFile::Exists(pgBackupAllExecutable)) + pgBackupAllExecutable = wxEmptyString; + if (!wxFile::Exists(pgRestoreExecutable)) + pgRestoreExecutable = wxEmptyString; + + if (!wxFile::Exists(edbBackupExecutable)) + edbBackupExecutable = wxEmptyString; + if (!wxFile::Exists(edbBackupAllExecutable)) + edbBackupAllExecutable = wxEmptyString; + if (!wxFile::Exists(edbRestoreExecutable)) + edbRestoreExecutable = wxEmptyString; + + if (!wxFile::Exists(gpBackupExecutable)) + gpBackupExecutable = wxEmptyString; + if (!wxFile::Exists(gpBackupAllExecutable)) + gpBackupAllExecutable = wxEmptyString; + if (!wxFile::Exists(gpRestoreExecutable)) + gpRestoreExecutable = wxEmptyString; + + + settings->SetIgnoreVersion(chkIgnoreVersion->GetValue()); + + if (chkResetHints->GetValue()) + frmHint::ResetHints(); + + // Set the help paths + settings->SetPgHelpPath(txtPgHelpPath->GetValue()); + settings->SetEdbHelpPath(txtEdbHelpPath->GetValue()); + settings->SetGpHelpPath(txtGpHelpPath->GetValue()); + settings->SetSlonyHelpPath(txtSlonyHelpPath->GetValue()); + + settings->SetSystemSchemas(txtSystemSchemas->GetValue()); + + // Save the display options + bool changed = false; + for (unsigned int x = 0; x < lstDisplay->GetCount(); x++) + { + if (lstDisplay->IsChecked(x) != settings->GetDisplayOption(lstDisplay->GetString(x))) + { + changed = true; + settings->SetDisplayOption(lstDisplay->GetString(x), lstDisplay->IsChecked(x)); + } + } + + if (chkSystemObjects->GetValue() != settings->GetShowSystemObjects()) + { + changed = true; + settings->SetShowSystemObjects(chkSystemObjects->GetValue()); + } + + // Change the status colours + if (pickerIdleProcessColour->GetColourString() != settings->GetIdleProcessColour()) + changed = true; + settings->SetIdleProcessColour(pickerIdleProcessColour->GetColourString()); + + if (pickerActiveProcessColour->GetColourString() != settings->GetActiveProcessColour()) + changed = true; + settings->SetActiveProcessColour(pickerActiveProcessColour->GetColourString()); + + if (pickerSlowProcessColour->GetColourString() != settings->GetSlowProcessColour()) + changed = true; + settings->SetSlowProcessColour(pickerSlowProcessColour->GetColourString()); + + if (pickerBlockedProcessColour->GetColourString() != settings->GetBlockedProcessColour()) + changed = true; + settings->SetBlockedProcessColour(pickerBlockedProcessColour->GetColourString()); + + // Change files' location + settings->SetFavouritesFile(pickerFavouritesFile->GetPath()); + settings->SetMacrosFile(pickerMacrosFile->GetPath()); + settings->SetHistoryFile(pickerHistoryFile->GetPath()); + settings->SetExtFormatCmd(pickerExtFormatCmd->GetPath()); + + // Change SQL Syntax colours + if (settings->GetSQLBoxUseSystemBackground() != chkSQLUseSystemBackgroundColour->GetValue()) + { + changed = true; + settings->SetSQLBoxUseSystemBackground(chkSQLUseSystemBackgroundColour->GetValue()); + } + + if (settings->GetSQLBoxUseSystemForeground() != chkSQLUseSystemForegroundColour->GetValue()) + { + changed = true; + settings->SetSQLBoxUseSystemForeground(chkSQLUseSystemForegroundColour->GetValue()); + } + + if (!settings->GetSQLBoxUseSystemBackground()) + { + if (pickerSQLBackgroundColour->GetColourString() != settings->GetSQLBoxColourBackground()) + changed = true; + settings->SetSQLBoxColourBackground(pickerSQLBackgroundColour->GetColourString()); + } + + if (!settings->GetSQLBoxUseSystemForeground()) + { + if (pickerSQLForegroundColour->GetColourString() != settings->GetSQLBoxColourForeground()) + changed = true; + settings->SetSQLBoxColourForeground(pickerSQLForegroundColour->GetColourString()); + } + + if (pickerSQLMarginBackgroundColour->GetColourString() != settings->GetSQLMarginBackgroundColour()) + changed = true; + settings->SetSQLMarginBackgroundColour(pickerSQLMarginBackgroundColour->GetColourString()); + + if (pickerSQLCaretColour->GetColourString() != settings->GetSQLColourCaret()) + changed = true; + settings->SetSQLColourCaret(pickerSQLCaretColour->GetColourString()); + + if (pickerSQLColour1->GetColourString() != settings->GetSQLBoxColour(1)) + changed = true; + settings->SetSQLBoxColour(1, pickerSQLColour1->GetColourString()); + if (pickerSQLColour2->GetColourString() != settings->GetSQLBoxColour(2)) + changed = true; + settings->SetSQLBoxColour(2, pickerSQLColour2->GetColourString()); + if (pickerSQLColour3->GetColourString() != settings->GetSQLBoxColour(3)) + changed = true; + settings->SetSQLBoxColour(3, pickerSQLColour3->GetColourString()); + if (pickerSQLColour4->GetColourString() != settings->GetSQLBoxColour(4)) + changed = true; + settings->SetSQLBoxColour(4, pickerSQLColour4->GetColourString()); + if (pickerSQLColour5->GetColourString() != settings->GetSQLBoxColour(5)) + changed = true; + settings->SetSQLBoxColour(5, pickerSQLColour5->GetColourString()); + if (pickerSQLColour6->GetColourString() != settings->GetSQLBoxColour(6)) + changed = true; + settings->SetSQLBoxColour(6, pickerSQLColour6->GetColourString()); + if (pickerSQLColour7->GetColourString() != settings->GetSQLBoxColour(7)) + changed = true; + settings->SetSQLBoxColour(7, pickerSQLColour7->GetColourString()); + if (pickerSQLColour10->GetColourString() != settings->GetSQLBoxColour(10)) + changed = true; + settings->SetSQLBoxColour(10, pickerSQLColour10->GetColourString()); + if (pickerSQLColour11->GetColourString() != settings->GetSQLBoxColour(11)) + changed = true; + settings->SetSQLBoxColour(11, pickerSQLColour11->GetColourString()); + + if (settings->GetSQLKeywordsInUppercase() != chkKeywordsInUppercase->GetValue()) + { + changed = true; + settings->SetSQLKeywordsInUppercase(chkKeywordsInUppercase->GetValue()); + } + + // Change the language last, as it will affect our tests for changes + // in the display object types. + int langNo = cbLanguage->GetCurrentSelection(); + if (langNo >= 0) + { + wxLanguage langId; + if (langNo == 0) + langId = wxLANGUAGE_DEFAULT; + else + { + const wxLanguageInfo *langInfo = wxLocale::GetLanguageInfo(existingLangs.Item(langNo - 1)); + langId = (wxLanguage) langInfo->Language; + } + + settings->SetCanonicalLanguage(langId); + } + + settings->SetOptionsLastTreeItem(menuSelection); + + // Did any display options change? Display this message last, so it's + // in the selected language. + if (changed) + wxMessageBox(_("Changes to the display options may not be visible until the browser tree is refreshed."), _("Display options"), wxICON_INFORMATION | wxOK); + + Destroy(); +} + + +void frmOptions::OnCancel(wxCommandEvent &ev) +{ + Destroy(); +} + + +optionsFactory::optionsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, _("&Options..."), _("Show options dialog.")); +} + + +wxWindow *optionsFactory::StartDialog(frmMain *form, pgObject *obj) +{ + frmOptions *frm = new frmOptions(form); + frm->Show(); + return 0; +} + +// Enable/disable the copy quote option as required. +void frmOptions::OnChangeCopyQuote(wxCommandEvent &WXUNUSED(ev)) +{ + if (cbCopyQuote->GetValue() == _("None")) + cbCopyQuoteChar->Disable(); + else + cbCopyQuoteChar->Enable(); +} + + +wxString frmOptions::CheckColour(wxString oldColour) +{ + wxString newColour = wxEmptyString; + + if (oldColour != wxEmptyString) + { + wxColour colour; + + if (colour.Set(oldColour)) + newColour = colour.GetAsString(wxC2S_HTML_SYNTAX); + else + wxLogError(_("The colour specified is not valid.")); + } + + return newColour; +} + +void frmOptions::OnTreeSelChanged(wxTreeEvent &event) +{ + wxTreeItemId sel = event.GetItem(); + + if (sel) + ShowPanel(sel); +} + +void frmOptions::ShowPanel(const wxTreeItemId &menuItem) +{ + // Hide everything + pnlBrowserDisplay->Show(false); + pnlBrowserProperties->Show(false); + pnlBrowserBinPath->Show(false); + pnlBrowserMisc->Show(false); + pnlQueryToolEditor->Show(false); + pnlQueryToolColours->Show(false); + pnlQueryToolResults->Show(false); + pnlQueryToolFiles->Show(false); + pnlQueryToolFavourites->Show(false); + pnlQueryToolMacros->Show(false); + pnlQueryToolHistoryFile->Show(false); + pnlDatabaseDesigner->Show(false); + pnlServerStatus->Show(false); + pnlMiscUI->Show(false); + pnlMiscHelpPath->Show(false); + pnlMiscGuruHints->Show(false); + pnlMiscLogging->Show(false); + + // Find the one to show + menuSelection = menus->GetItemText(menuItem); + if (menuSelection == BROWSER_ITEM || menuSelection == BROWSER_DISPLAY_ITEM) + pnlBrowserDisplay->Show(true); + else if (menuSelection == BROWSER_PROPERTIES_ITEM) + pnlBrowserProperties->Show(true); + else if (menuSelection == BROWSER_BINPATH_ITEM) + pnlBrowserBinPath->Show(true); + else if (menuSelection == BROWSER_MISC_ITEM) + pnlBrowserMisc->Show(true); + + else if (menuSelection == QUERYTOOL_ITEM || menuSelection == QUERYTOOL_EDITOR_ITEM) + pnlQueryToolEditor->Show(true); + else if (menuSelection == QUERYTOOL_COLOURS_ITEM) + { + pnlQueryToolColours->Show(true); + pickerSQLBackgroundColour->UpdateColour(); + pickerSQLForegroundColour->UpdateColour(); + pickerSQLMarginBackgroundColour->UpdateColour(); + pickerSQLColour1->UpdateColour(); + pickerSQLColour2->UpdateColour(); + pickerSQLColour3->UpdateColour(); + pickerSQLColour4->UpdateColour(); + pickerSQLColour5->UpdateColour(); + pickerSQLColour6->UpdateColour(); + pickerSQLColour7->UpdateColour(); + pickerSQLColour10->UpdateColour(); + pickerSQLColour11->UpdateColour(); + pickerSQLCaretColour->UpdateColour(); + } + else if (menuSelection == QUERYTOOL_RESULTS_ITEM) + pnlQueryToolResults->Show(true); + else if (menuSelection == QUERYTOOL_FILES_ITEM) + pnlQueryToolFiles->Show(true); + else if (menuSelection == QUERYTOOL_FAVOURITES_ITEM) + pnlQueryToolFavourites->Show(true); + else if (menuSelection == QUERYTOOL_MACROS_ITEM) + pnlQueryToolMacros->Show(true); + else if (menuSelection == QUERYTOOL_HISTORYFILE_ITEM) + pnlQueryToolHistoryFile->Show(true); + + else if (menuSelection == DATABASEDESIGNER_ITEM) + pnlDatabaseDesigner->Show(true); + + else if (menuSelection == SERVERSTATUS_ITEM) + { + pnlServerStatus->Show(true); + pickerIdleProcessColour->UpdateColour(); + pickerActiveProcessColour->UpdateColour(); + pickerSlowProcessColour->UpdateColour(); + pickerBlockedProcessColour->UpdateColour(); + } + + else if (menuSelection == MISC_ITEM || menuSelection == MISC_UI_ITEM) + pnlMiscUI->Show(true); + else if (menuSelection == MISC_HELPPATH_ITEM) + pnlMiscHelpPath->Show(true); + else if (menuSelection == MISC_GURUHINTS_ITEM) + pnlMiscGuruHints->Show(true); + else if (menuSelection == MISC_LOGGING_ITEM) + pnlMiscLogging->Show(true); + + pnlBrowserDisplay->GetParent()->Layout(); + // we don't need to call GetParent()->Layout() for all panels + // because they all share the same parent +} + +wxTreeItemId frmOptions::GetTreeItemByLabel(const wxTreeItemId &root, const wxString &label) +{ + wxTreeItemIdValue cookie; + wxTreeItemId child; + wxTreeItemId notfound; + + if (!root.IsOk()) + return notfound; + if (label.CompareTo(menus->GetItemText(root)) == 0) + return root; + if (!menus->ItemHasChildren(root)) + return notfound; + + child = menus->GetFirstChild(root, cookie); + while (child.IsOk()) + { + child = GetTreeItemByLabel(child, label); + if (child.IsOk()) + return child; + child = menus->GetNextChild(root, cookie); + } + return child; +} + diff --git a/frm/frmPassword.cpp b/frm/frmPassword.cpp new file mode 100644 index 0000000..6c7e561 --- /dev/null +++ b/frm/frmPassword.cpp @@ -0,0 +1,117 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmPassword.cpp - Change password +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include + + +// App headers +#include "pgAdmin3.h" +#include "frm/frmPassword.h" +#include "schema/pgServer.h" + +#include "images/connect.pngc" + +#define txtCurrent CTRL_TEXT("txtCurrent") +#define txtNew CTRL_TEXT("txtNew") +#define txtConfirm CTRL_TEXT("txtConfirm") + + +BEGIN_EVENT_TABLE(frmPassword, pgDialog) + EVT_BUTTON (wxID_HELP, frmPassword::OnHelp) + EVT_BUTTON (wxID_OK, frmPassword::OnOK) + EVT_BUTTON (wxID_CANCEL, frmPassword::OnCancel) +END_EVENT_TABLE() + + +frmPassword::frmPassword(wxFrame *parent, pgObject *obj) +{ + SetFont(settings->GetSystemFont()); + LoadResource(parent, wxT("frmPassword")); + RestorePosition(); + + server = obj->GetServer(); + // Icon + SetIcon(*connect_png_ico); +} + +frmPassword::~frmPassword() +{ + SavePosition(); +} + + +void frmPassword::OnHelp(wxCommandEvent &ev) +{ + DisplayHelp(wxT("password"), HELP_PGADMIN); +} + + +void frmPassword::OnOK(wxCommandEvent &event) +{ + + // Is the old password right? + if (txtCurrent->GetValue() != server->GetPassword()) + { + wxLogError(__("Incorrect password!")); + return; + } + + // Did we confirm the password OK? + if (txtNew->GetValue() != txtConfirm->GetValue()) + { + wxLogError(__("Passwords do not match!")); + return; + } + + // Set the new password + if (!server->SetPassword(txtNew->GetValue())) + { + wxLogError(__("The password could not be changed!")); + return; + } + + // All must have gone well! + wxLogMessage(__("Password successfully changed!")); + this->Destroy(); +} + + +void frmPassword::OnCancel(wxCommandEvent &event) +{ + Destroy(); +} + + +passwordFactory::passwordFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, _("C&hange Password..."), _("Change your password.")); +} + + +wxWindow *passwordFactory::StartDialog(frmMain *form, pgObject *obj) +{ + frmPassword *frm = new frmPassword((pgFrame *)form, obj); + frm->Show(); + return 0; +} + + +bool passwordFactory::CheckEnable(pgObject *obj) +{ + if (obj) + { + pgServer *server = obj->GetServer(); + return server && server->GetConnected(); + } + return false; +} diff --git a/frm/frmPgpassConfig.cpp b/frm/frmPgpassConfig.cpp new file mode 100644 index 0000000..b940bfd --- /dev/null +++ b/frm/frmPgpassConfig.cpp @@ -0,0 +1,353 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmPgpassConfig.cpp - Client access configuration tool +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#ifdef __WXMSW__ +#include +#include +#endif + +#include + +#include "ctl/ctlMenuToolbar.h" +#include "frm/frmPgpassConfig.h" +#include "dlg/dlgPgpassConfig.h" +#include "frm/frmMain.h" +#include "utils/utffile.h" +#include "schema/pgServer.h" +#include "frm/menu.h" +#include "utils/pgfeatures.h" + +#define CTL_CFGVIEW 345 + +#include +WX_DEFINE_OBJARRAY(pgPassConfigLineArray); + + +BEGIN_EVENT_TABLE(frmPgpassConfig, frmConfig) + EVT_MENU(MNU_UNDO, frmPgpassConfig::OnUndo) + EVT_MENU(MNU_DELETE, frmPgpassConfig::OnDelete) + EVT_MENU(MNU_CONTENTS, frmPgpassConfig::OnContents) + EVT_LIST_ITEM_ACTIVATED(CTL_CFGVIEW, frmPgpassConfig::OnEditSetting) + EVT_LIST_ITEM_SELECTED(CTL_CFGVIEW, frmPgpassConfig::OnSelectSetting) +END_EVENT_TABLE() + +#define CACE_TITLE _("Client Access Configuration Editor") + +frmPgpassConfig::frmPgpassConfig(const wxString &title, const wxString &configFile) + : frmConfig(title + wxT(" - ") + _("Client Access Configuration Editor"), configFile) +{ + Init(); + + OpenLastFile(); + + helpMenu->Enable(MNU_HINT, false); + toolBar->EnableTool(MNU_HINT, false); +} + +frmPgpassConfig::frmPgpassConfig(frmMain *parent) + : frmConfig(parent, CACE_TITLE, 0) +{ + Init(); + + lastPath = sysSettings::GetConfigFile(sysSettings::PGPASS); + wxFile f; + if (f.Exists(lastPath)) + { + OpenLastFile(); + } + + helpMenu->Enable(MNU_HINT, false); + toolBar->EnableTool(MNU_HINT, false); +} + +frmPgpassConfig::~frmPgpassConfig() +{ +} + + +void frmPgpassConfig::Init() +{ + appearanceFactory->SetIcons(this); + + InitFrame(wxT("frmPgpassConfig")); + RestorePosition(150, 150, 650, 300, 300, 200); + + + listEdit = new ctlListView(this, CTL_CFGVIEW, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER); + listEdit->SetImageList(configImageList, wxIMAGE_LIST_SMALL); + + listEdit->AddColumn(_("Host"), 50); + listEdit->AddColumn(_("Port"), 30); + listEdit->AddColumn(_("Database"), 80); + listEdit->AddColumn(_("Username"), 80); + listEdit->AddColumn(_("Password"), 80); + + editMenu->Enable(MNU_DELETE, false); + toolBar->EnableTool(MNU_DELETE, false); +} + +void frmPgpassConfig::OnSelectSetting(wxListEvent &event) +{ + // Enable delete because an item has been selected + if (event.GetIndex() != listEdit->GetItemCount() - 1) + { + editMenu->Enable(MNU_DELETE, true); + toolBar->EnableTool(MNU_DELETE, true); + } + else + { + editMenu->Enable(MNU_DELETE, false); + toolBar->EnableTool(MNU_DELETE, false); + } + + // Disable undo because we don't want to undo the wrong line. + editMenu->Enable(MNU_UNDO, false); + toolBar->EnableTool(MNU_UNDO, false); +} + +void frmPgpassConfig::DisplayFile(const wxString &str) +{ + lines.Empty(); + + filetype = wxTextFileType_Unix; + wxStringTokenizer strtok; + + if (str.Find('\r') >= 0) + { + if (str.Find(wxT("\n\r")) >= 0 || str.Find(wxT("\r\n"))) + filetype = wxTextFileType_Dos; + else + filetype = wxTextFileType_Mac; + + strtok.SetString(wxTextBuffer::Translate(str, wxTextFileType_Unix), wxT("\n"), wxTOKEN_RET_EMPTY); + } + else + strtok.SetString(str, wxT("\n"), wxTOKEN_RET_EMPTY); + + while (strtok.HasMoreTokens()) + { + pgPassConfigLine *line = new pgPassConfigLine(strtok.GetNextToken()); + lines.Add(line); + } + + listEdit->DeleteAllItems(); + + size_t i; + + for (i = 0 ; i < lines.GetCount() ; i++) + { + pgPassConfigLine &line = lines.Item(i); + int imgIndex = 0; + if (!line.isComment) + imgIndex = 1; + long pos = listEdit->AppendItem(imgIndex, line.hostname); + + listEdit->SetItem(pos, 1, line.port); + listEdit->SetItem(pos, 2, line.database); + listEdit->SetItem(pos, 3, line.username); + listEdit->SetItem(pos, 4, line.password.IsEmpty() ? wxT("") : wxT("*********")); + line.item = pos; + } + if (!i || !lines.Item(i - 1).text.IsEmpty()) + { + pgPassConfigLine *line = new pgPassConfigLine(); + lines.Add(line); + line->item = listEdit->AppendItem(0, wxString(wxEmptyString)); + } +} + + +void frmPgpassConfig::WriteFile(pgConn *conn) +{ + wxString str; + size_t i; + for (i = 0 ; i < lines.GetCount() - 1 ; i++) + { + // Before writing it into the file we need to escape "\" and ":" + pgPassConfigLine line = lines.Item(i); + line.hostname.Replace(wxT("\\"), wxT("\\\\")); + line.hostname.Replace(wxT(":") , wxT("\\:")); + line.port.Replace(wxT("\\"), wxT("\\\\")); + line.port.Replace(wxT(":") , wxT("\\:")); + line.database.Replace(wxT("\\"), wxT("\\\\")); + line.database.Replace(wxT(":") , wxT("\\:")); + line.username.Replace(wxT("\\"), wxT("\\\\")); + line.username.Replace(wxT(":") , wxT("\\:")); + line.password.Replace(wxT("\\"), wxT("\\\\")); + line.password.Replace(wxT(":") , wxT("\\:")); + + wxString strLine = line.hostname + wxT(":") + line.port + wxT(":") + + line.database + wxT(":") + line.username + wxT(":") + line.password + wxT("\n"); + + str.Append(strLine); + } + + if (DoWriteFile(str, NULL)) + { + changed = false; + fileMenu->Enable(MNU_SAVE, false); + editMenu->Enable(MNU_UNDO, false); + toolBar->EnableTool(MNU_SAVE, false); + toolBar->EnableTool(MNU_UNDO, false); + + // make intermediate change current + for (i = 0 ; i < lines.GetCount() ; i++) + lines.Item(i).Init(lines.Item(i).GetText()); + } +} + + +wxString frmPgpassConfig::GetHintString() +{ + wxString hint; + return hint; +} + + +wxString frmPgpassConfig::GetHelpPage() const +{ + wxString page = wxT("libpq-pgpass"); + ; + return page; +} + + +void frmPgpassConfig::OnContents(wxCommandEvent &event) +{ + DisplayHelp(wxT("index"), HELP_PGADMIN); +} + + +void frmPgpassConfig::OnUndo(wxCommandEvent &ev) +{ + int pos = listEdit->GetSelection(); + if (pos >= 0) + { + size_t i; + for (i = 0 ; i < lines.GetCount() ; i++) + { + pgPassConfigLine &line = lines.Item(i); + + if (line.item == pos) + { + line.Init(line.text); + UpdateDisplay(line); + break; + } + } + } +} + +void frmPgpassConfig::OnDelete(wxCommandEvent &event) +{ + bool found = false; + int pos = listEdit->GetSelection(); + if (pos >= 0) + { + listEdit->DeleteCurrentItem(); + size_t i; + for (i = 0; i < lines.GetCount(); i++) + { + if (lines.Item(i).item == pos) + { + lines.RemoveAt(i); + changed = true; + fileMenu->Enable(MNU_SAVE, true); + editMenu->Enable(MNU_UNDO, false); + editMenu->Enable(MNU_DELETE, false); + toolBar->EnableTool(MNU_SAVE, true); + toolBar->EnableTool(MNU_UNDO, false); + toolBar->EnableTool(MNU_DELETE, false); + found = true; + break; + } + } + if (found) + { + /* Renumber all positions */ + for (i = 0; i < lines.GetCount(); i++) + { + if (lines.Item(i).item > pos) + lines.Item(i).item--; + } + } + } +} + +void frmPgpassConfig::UpdateDisplay(pgPassConfigLine &line) +{ + long pos = line.item; + listEdit->SetItemImage(pos, (line.isComment ? 0 : 1)); + listEdit->SetItem(pos, 0, line.hostname); + listEdit->SetItem(pos, 1, line.port); + listEdit->SetItem(pos, 2, line.database); + listEdit->SetItem(pos, 3, line.username); + listEdit->SetItem(pos, 4, line.password.IsEmpty() ? wxT("") : wxT("*********")); +} + + +void frmPgpassConfig::OnEditSetting(wxListEvent &event) +{ + long pos = event.GetIndex(); + if (pos < 0) + return; + + size_t i; + + for (i = 0 ; i < lines.GetCount() ; i++) + { + if (lines.Item(i).item == pos) + { + pgPassConfigLine &line = lines.Item(i); + bool isLastLine = (i == lines.GetCount() - 1 && line.isComment && line.text.IsEmpty()); + + dlgPgpassConfig dlg(this, &line); + if (dlg.Go() == wxID_OK) + { + UpdateDisplay(line); + + if (isLastLine) + { + long pos = listEdit->AppendItem(0, wxString(wxEmptyString)); + pgPassConfigLine *line = new pgPassConfigLine(); + line->item = pos; + lines.Add(line); + } + changed = true; + fileMenu->Enable(MNU_SAVE, true); + editMenu->Enable(MNU_UNDO, true); + toolBar->EnableTool(MNU_SAVE, true); + toolBar->EnableTool(MNU_UNDO, true); + } + break; + } + } +} + + +pgpassConfigFileFactory::pgpassConfigFileFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ +#ifdef WIN32 + mnu->Append(id, _("Open pgpass.conf"), _("Open configuration editor with pgpass.conf.")); +#else + mnu->Append(id, _("Open .pgpass"), _("Open configuration editor with .pgpass")); +#endif +} + + +wxWindow *pgpassConfigFileFactory::StartDialog(frmMain *form, pgObject *obj) +{ + frmConfig *dlg = new frmPgpassConfig(form); + dlg->Go(); + return dlg; +} diff --git a/frm/frmQuery.cpp b/frm/frmQuery.cpp new file mode 100644 index 0000000..9d74648 --- /dev/null +++ b/frm/frmQuery.cpp @@ -0,0 +1,4461 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmQuery.cpp - SQL Query Box +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// App headers +#include "frm/frmAbout.h" +#include "frm/frmMain.h" +#include "frm/frmQuery.h" +#include "frm/menu.h" +#include "ctl/explainCanvas.h" +#include "db/pgConn.h" + +#include "ctl/ctlMenuToolbar.h" +#include "ctl/ctlSQLResult.h" +#include "dlg/dlgSelectConnection.h" +#include "dlg/dlgAddFavourite.h" +#include "dlg/dlgManageFavourites.h" +#include "dlg/dlgManageMacros.h" +#include "frm/frmReport.h" +#include "gqb/gqbViewController.h" +#include "gqb/gqbModel.h" +#include "gqb/gqbViewPanels.h" +#include "gqb/gqbEvents.h" +#include "schema/pgDatabase.h" +#include "schema/pgFunction.h" +#include "schema/pgTable.h" +#include "schema/pgForeignTable.h" +#include "schema/pgView.h" +#include "schema/gpExtTable.h" +#include "schema/pgServer.h" +#include "utils/favourites.h" +#include "utils/sysLogger.h" +#include "utils/sysSettings.h" +#include "utils/utffile.h" +#include "utils/misc.h" +#include "pgscript/pgsApplication.h" +#include "schema/pgPartition.h" + +// Icons +#include "images/sql-32.pngc" + +// Bitmaps +#include "images/file_new.pngc" +#include "images/file_open.pngc" +#include "images/file_save.pngc" +#include "images/clip_cut.pngc" +#include "images/clip_copy.pngc" +#include "images/clip_paste.pngc" +#include "images/edit_clear.pngc" +#include "images/edit_find.pngc" +#include "images/edit_undo.pngc" +#include "images/edit_redo.pngc" +#include "images/query_execute.pngc" +#include "images/query_pgscript.pngc" +#include "images/query_execfile.pngc" +#include "images/query_explain.pngc" +#include "images/query_cancel.pngc" +#include "images/query_commit.pngc" +#include "images/query_rollback.pngc" +#include "images/help.pngc" +#include "images/gqbJoin.pngc" + +#define CTRLID_CONNECTION 4200 +#define CTRLID_DATABASELABEL 4201 +#define CTL_SQLQUERYBOOK 4202 + +#define XML_FROM_WXSTRING(s) ((const xmlChar *)(const char *)s.mb_str(wxConvUTF8)) +#define WXSTRING_FROM_XML(s) wxString((char *)s, wxConvUTF8) +#define XML_STR(s) ((const xmlChar *)s) + +// Initialize execution 'mutex'. As this will always run in the +// main thread, there aren't any real concurrency issues, so +// a simple flag will suffice. +// Required because the pgScript parser isn't currently thread-safe :-( +bool frmQuery::ms_pgScriptRunning = false; + +BEGIN_EVENT_TABLE(frmQuery, pgFrame) + EVT_ERASE_BACKGROUND( frmQuery::OnEraseBackground) + EVT_SIZE( frmQuery::OnSize) + EVT_COMBOBOX(CTRLID_CONNECTION, frmQuery::OnChangeConnection) + EVT_COMBOBOX(CTL_SQLQUERYCBOX, frmQuery::OnChangeQuery) + EVT_CLOSE( frmQuery::OnClose) + EVT_SET_FOCUS( frmQuery::OnSetFocus) + EVT_MENU(MNU_NEW, frmQuery::OnNew) + EVT_MENU(MNU_OPEN, frmQuery::OnOpen) + EVT_MENU(MNU_SAVE, frmQuery::OnSave) + EVT_MENU(MNU_SAVEAS, frmQuery::OnSaveAs) + EVT_MENU(MNU_NEWSQLTAB, frmQuery::OnSqlBookAddPage) + EVT_MENU(MNU_EXPORT, frmQuery::OnExport) + EVT_MENU(MNU_SAVEAS_IMAGE_GQB, frmQuery::SaveExplainAsImage) + EVT_MENU(MNU_SAVEAS_IMAGE_EXPLAIN, frmQuery::SaveExplainAsImage) + EVT_MENU(MNU_EXIT, frmQuery::OnExit) + EVT_MENU(MNU_CUT, frmQuery::OnCut) + EVT_MENU(MNU_COPY, frmQuery::OnCopy) + EVT_MENU(MNU_PASTE, frmQuery::OnPaste) + EVT_MENU(MNU_CLEAR, frmQuery::OnClear) + EVT_MENU(MNU_SUMMARY_COL, frmQuery::OnSummary_Column) + EVT_MENU(MNU_FIND, frmQuery::OnSearchReplace) + EVT_MENU(MNU_UNDO, frmQuery::OnUndo) + EVT_MENU(MNU_REDO, frmQuery::OnRedo) + EVT_MENU(MNU_EXECUTE, frmQuery::OnExecute) + EVT_MENU(MNU_EXECPGS, frmQuery::OnExecScript) + EVT_MENU(MNU_EXECFILE, frmQuery::OnExecFile) + EVT_MENU(MNU_EXPLAIN, frmQuery::OnExplain) + EVT_MENU(MNU_EXPLAINANALYZE, frmQuery::OnExplain) + EVT_MENU(MNU_DOCOMMIT, frmQuery::OnCommit) + EVT_MENU(MNU_DOROLLBACK, frmQuery::OnRollback) + EVT_MENU(MNU_CANCEL, frmQuery::OnCancel) + EVT_MENU(MNU_AUTOSELECTQUERY, frmQuery::OnAutoSelectQuery) + EVT_MENU(MNU_AUTOROLLBACK, frmQuery::OnAutoRollback) + EVT_MENU(MNU_AUTOCOMMIT, frmQuery::OnAutoCommit) + EVT_MENU(MNU_CONTENTS, frmQuery::OnContents) + EVT_MENU(MNU_HELP, frmQuery::OnHelp) + EVT_MENU(MNU_CLEARHISTORY, frmQuery::OnClearHistory) + EVT_MENU(MNU_SAVEHISTORY, frmQuery::OnSaveHistory) + EVT_MENU(MNU_SELECTALL, frmQuery::OnSelectAll) + EVT_MENU(MNU_QUICKREPORT, frmQuery::OnQuickReport) + EVT_MENU(MNU_AUTOINDENT, frmQuery::OnAutoIndent) + EVT_MENU(MNU_WORDWRAP, frmQuery::OnWordWrap) + EVT_MENU(MNU_SHOWINDENTGUIDES, frmQuery::OnShowIndentGuides) + EVT_MENU(MNU_SHOWWHITESPACE, frmQuery::OnShowWhitespace) + EVT_MENU(MNU_SHOWLINEENDS, frmQuery::OnShowLineEnds) + EVT_MENU(MNU_SHOWLINENUMBER, frmQuery::OnShowLineNumber) + EVT_MENU(MNU_FAVOURITES_ADD, frmQuery::OnAddFavourite) + EVT_MENU(MNU_FAVOURITES_INJECT, frmQuery::OnInjectFavourite) + EVT_MENU(MNU_FAVOURITES_MANAGE, frmQuery::OnManageFavourites) + EVT_MENU(MNU_MACROS_MANAGE, frmQuery::OnMacroManage) + EVT_MENU(MNU_AUTOREPLACE_MANAGE,frmQuery::OnAutoReplaceManage) + EVT_MENU(MNU_DATABASEBAR, frmQuery::OnToggleDatabaseBar) + EVT_MENU(MNU_TOOLBAR, frmQuery::OnToggleToolBar) + EVT_MENU(MNU_SCRATCHPAD, frmQuery::OnToggleScratchPad) + EVT_MENU(MNU_OUTPUTPANE, frmQuery::OnToggleOutputPane) + EVT_MENU(MNU_DEFAULTVIEW, frmQuery::OnDefaultView) + EVT_MENU(MNU_BLOCK_INDENT, frmQuery::OnBlockIndent) + EVT_MENU(MNU_BLOCK_OUTDENT, frmQuery::OnBlockOutDent) + EVT_MENU(MNU_UPPER_CASE, frmQuery::OnChangeToUpperCase) + EVT_MENU(MNU_LOWER_CASE, frmQuery::OnChangeToLowerCase) + EVT_MENU(MNU_COMMENT_TEXT, frmQuery::OnCommentText) + EVT_MENU(MNU_UNCOMMENT_TEXT, frmQuery::OnUncommentText) + EVT_MENU(MNU_EXTERNALFORMAT, frmQuery::OnExternalFormat) + EVT_MENU(MNU_LF, frmQuery::OnSetEOLMode) + EVT_MENU(MNU_CRLF, frmQuery::OnSetEOLMode) + EVT_MENU(MNU_CR, frmQuery::OnSetEOLMode) + EVT_MENU_RANGE(MNU_FAVOURITES_MANAGE + 1, MNU_FAVOURITES_MANAGE + 999, frmQuery::OnSelectFavourite) + EVT_MENU_RANGE(MNU_MACROS_MANAGE + 1, MNU_MACROS_MANAGE + 99, frmQuery::OnMacroInvoke) + EVT_ACTIVATE( frmQuery::OnActivate) + EVT_STC_MODIFIED(CTL_SQLQUERY, frmQuery::OnChangeStc) + EVT_STC_UPDATEUI(CTL_SQLQUERY, frmQuery::OnPositionStc) + EVT_GRID_LABEL_RIGHT_CLICK( frmQuery::OnLabelRightClick) + EVT_AUI_PANE_CLOSE( frmQuery::OnAuiUpdate) + EVT_TIMER(CTL_TIMERSIZES, frmQuery::OnAdjustSizesTimer) + EVT_TIMER(CTL_TIMERFRM, frmQuery::OnTimer) +// These fire when the queries complete + EVT_PGQUERYRESULT(QUERY_COMPLETE, frmQuery::OnQueryComplete) + EVT_MENU(PGSCRIPT_COMPLETE, frmQuery::OnScriptComplete) + EVT_AUINOTEBOOK_PAGE_CHANGED(CTL_NTBKCENTER, frmQuery::OnChangeNotebook) + EVT_AUINOTEBOOK_PAGE_CHANGED(CTL_SQLQUERYBOOK, frmQuery::OnSqlBookPageChanged) + EVT_AUINOTEBOOK_PAGE_CHANGING(CTL_SQLQUERYBOOK, frmQuery::OnSqlBookPageChanging) + EVT_AUINOTEBOOK_PAGE_CLOSE(CTL_SQLQUERYBOOK, frmQuery::OnSqlBookPageClose) + EVT_AUINOTEBOOK_TAB_RIGHT_DOWN(CTL_SQLQUERYBOOK, frmQuery::OnSqlBookTabRDown) + EVT_AUINOTEBOOK_PAGE_CLOSED(CTL_SQLQUERYBOOK, frmQuery::OnSqlBookPageClosed) + EVT_SPLITTER_SASH_POS_CHANGED(GQB_HORZ_SASH, frmQuery::OnResizeHorizontally) + EVT_BUTTON(CTL_DELETECURRENTBTN, frmQuery::OnDeleteCurrent) + EVT_BUTTON(CTL_DELETEALLBTN, frmQuery::OnDeleteAll) +END_EVENT_TABLE() + +class DnDFile : public wxFileDropTarget +{ +public: + DnDFile(frmQuery *fquery) + { + m_fquery = fquery; + } + + virtual bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &filenames) + { + size_t nFiles = filenames.GetCount(); + if ((int) nFiles > 1) + wxLogError(_("Drag one file at a time")); + else if ((int) nFiles == 1) + { + wxString str; + bool modeUnicode = settings->GetUnicodeFile(); + wxUtfFile file(filenames[0], wxFile::read, modeUnicode ? wxFONTENCODING_UTF8 : wxFONTENCODING_DEFAULT); + + if (file.IsOpened()) + file.Read(str); + + if (!str.IsEmpty() && !m_fquery->CheckChanged(true)) + { + m_fquery->SetLastPath(filenames[0]); + m_fquery->SetQueryText(str); + m_fquery->ColouriseQuery(0, str.Length()); + wxSafeYield(); // needed to process sqlQuery modify event + m_fquery->SetChanged(false); + m_fquery->SetOrigin(ORIGIN_FILE); + m_fquery->setExtendedTitle(); + m_fquery->SetLineEndingStyle(); + m_fquery->UpdateRecentFiles(true); + m_fquery->UpdateAllRecentFiles(); + } + } + return true; + } + +private: + frmQuery *m_fquery; +}; + + +frmQuery::frmQuery(frmMain *form, const wxString &_title, pgConn *_conn, const wxString &query, const wxString &file) + : pgFrame(NULL, _title), + timer(this, CTL_TIMERFRM), + pgScript(new pgsApplication(_conn)), + pgsStringOutput(&pgsOutputString), + pgsOutput(pgsStringOutput, wxEOL_UNIX), + pgsTimer(new pgScriptTimer(this)), + m_loadingfile(false) +{ + pgScript->SetCaller(this, PGSCRIPT_COMPLETE); + + mainForm = form; + conn = _conn; + + loading = true; + closing = false; + + dlgName = wxT("frmQuery"); + recentKey = wxT("RecentFiles"); + RestorePosition(100, 100, 600, 500, 450, 300); + + explainCanvas = NULL; + + // notify wxAUI which frame to use + manager.SetManagedWindow(this); + manager.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_TRANSPARENT_DRAG); + + SetMinSize(wxSize(450, 300)); + + SetIcon(*sql_32_png_ico); + SetFont(settings->GetSystemFont()); + menuBar = new wxMenuBar(); + + fileMenu = new wxMenu(); + recentFileMenu = new wxMenu(); + fileMenu->Append(MNU_NEW, _("&New window\tCtrl-N"), _("Open a new query window")); + fileMenu->Append(MNU_OPEN, _("&Open...\tCtrl-O"), _("Open a query file")); + fileMenu->Append(MNU_SAVE, _("&Save\tCtrl-S"), _("Save current file")); + saveasImageMenu = new wxMenu(); + saveasImageMenu->Append(MNU_SAVEAS, _("Query (text)"), _("Save file under new name")); + saveasImageMenu->Append(MNU_SAVEAS_IMAGE_GQB, _("Graphical Query (image)"), _("Save Graphical Query as an image")); + saveasImageMenu->Append(MNU_SAVEAS_IMAGE_EXPLAIN, _("Explain (image)"), _("Save output of Explain as an image")); + fileMenu->Append(wxID_ANY, _("Save as"), saveasImageMenu); + + // SQL tabs related menu items + fileMenu->AppendSeparator(); + fileMenu->Append(MNU_NEWSQLTAB, _("New SQL &tab\tCtrl-T"), _("Open a new query tab")); + + fileMenu->AppendSeparator(); + fileMenu->Append(MNU_EXPORT, _("&Export..."), _("Export data to file")); + fileMenu->Append(MNU_QUICKREPORT, _("&Quick report..."), _("Run a quick report...")); + fileMenu->AppendSeparator(); + fileMenu->Append(MNU_RECENT, _("&Recent files"), recentFileMenu); + fileMenu->Append(MNU_EXIT, _("E&xit\tCtrl-W"), _("Exit query window")); + + menuBar->Append(fileMenu, _("&File")); + + lineEndMenu = new wxMenu(); + lineEndMenu->AppendRadioItem(MNU_LF, _("Unix (LF)"), _("Use Unix style line endings")); + lineEndMenu->AppendRadioItem(MNU_CRLF, _("DOS (CRLF)"), _("Use DOS style line endings")); + lineEndMenu->AppendRadioItem(MNU_CR, _("Mac (CR)"), _("Use Mac style line endings")); + + editMenu = new wxMenu(); + editMenu->Append(MNU_UNDO, _("&Undo\tCtrl-Z"), _("Undo last action"), wxITEM_NORMAL); + editMenu->Append(MNU_REDO, _("&Redo\tCtrl-Y"), _("Redo last action"), wxITEM_NORMAL); + editMenu->AppendSeparator(); + editMenu->Append(MNU_CUT, _("Cu&t\tCtrl-X"), _("Cut selected text to clipboard"), wxITEM_NORMAL); + editMenu->Append(MNU_COPY, _("&Copy\tCtrl-C"), _("Copy selected text to clipboard"), wxITEM_NORMAL); + editMenu->Append(MNU_PASTE, _("&Paste\tCtrl-V"), _("Paste selected text from clipboard"), wxITEM_NORMAL); + editMenu->Append(MNU_CLEAR, _("C&lear window"), _("Clear edit window"), wxITEM_NORMAL); + editMenu->AppendSeparator(); + editMenu->Append(MNU_FIND, _("&Find and Replace\tCtrl-F"), _("Find and replace text"), wxITEM_NORMAL); + editMenu->AppendSeparator(); + editMenu->Append(MNU_AUTOINDENT, _("&Auto indent"), _("Automatically indent text to the same level as the preceding line"), wxITEM_CHECK); + + // editMenu->AppendSeparator(); + formatMenu = new wxMenu(); + formatMenu->Append(MNU_UPPER_CASE, _("&Upper case\tCtrl-U"), _("Change the selected text to upper case")); + formatMenu->Append(MNU_LOWER_CASE, _("&Lower case\tCtrl-Shift-U"), _("Change the selected text to lower case")); + formatMenu->AppendSeparator(); + formatMenu->Append(MNU_BLOCK_INDENT, _("Block &Indent\tTab"), _("Indent the selected block")); + formatMenu->Append(MNU_BLOCK_OUTDENT, _("Block &Outdent\tShift-Tab"), _("Outdent the selected block")); + formatMenu->Append(MNU_COMMENT_TEXT, _("Co&mment Text\tCtrl-K"), _("Comment out the selected text")); + formatMenu->Append(MNU_UNCOMMENT_TEXT, _("Uncomme&nt Text\tCtrl-Shift-K"), _("Uncomment the selected text")); + formatMenu->AppendSeparator(); + formatMenu->Append(MNU_EXTERNALFORMAT, _("External Format\tCtrl-Shift-F"), _("Call external formatting command")); + editMenu->AppendSubMenu(formatMenu, _("F&ormat")); + editMenu->Append(MNU_LINEENDS, _("&Line ends"), lineEndMenu); + editMenu->Append(MNU_AUTOREPLACE_MANAGE, _("Manage autoreplace..."), _("Edit and delete autoreplace strings")); + + autoreplace = queryMacroFileProvider::LoadAutoReplace(true); + + menuBar->Append(editMenu, _("&Edit")); + + queryMenu = new wxMenu(); + queryMenu->Append(MNU_EXECUTE, _("&Execute\tF8"), _("Execute query")); + queryMenu->Append(MNU_EXECPGS, _("Execute &pgScript\tF6"), _("Execute pgScript")); + queryMenu->Append(MNU_EXECFILE, _("Execute to file\tF5"), _("Execute query, write result to file")); + queryMenu->Append(MNU_EXPLAIN, _("E&xplain\tF7"), _("Explain query")); + queryMenu->Append(MNU_EXPLAINANALYZE, _("Explain analyze\tShift-F7"), _("Explain and analyze query")); + + + wxMenu *eo = new wxMenu(); + eo->Append(MNU_VERBOSE, _("Verbose"), _("Explain verbose query"), wxITEM_CHECK); + eo->Append(MNU_COSTS, _("Costs"), _("Explain analyze query with (or without) costs"), wxITEM_CHECK); + eo->Append(MNU_BUFFERS, _("Buffers"), _("Explain analyze query with (or without) buffers"), wxITEM_CHECK); + eo->Append(MNU_TIMING, _("Timing"), _("Explain analyze query with (or without) timing"), wxITEM_CHECK); + queryMenu->Append(MNU_EXPLAINOPTIONS, _("Explain &options"), eo, _("Options modifying Explain output")); + queryMenu->AppendSeparator(); + queryMenu->Append(MNU_SAVEHISTORY, _("Save history"), _("Save history of executed commands.")); + queryMenu->Append(MNU_CLEARHISTORY, _("Clear history"), _("Clear history window.")); + queryMenu->AppendSeparator(); + queryMenu->Append(MNU_AUTOSELECTQUERY, _("&Auto-Select"), _("Auto select query"), wxITEM_CHECK); + queryMenu->Append(MNU_AUTOROLLBACK, _("&Auto-Rollback"), _("Rollback the current transaction if an error is detected"), wxITEM_CHECK); + queryMenu->Append(MNU_AUTOCOMMIT, _("&Auto-Commit"), _("Auto commit the cuurent transaction"), wxITEM_CHECK); + queryMenu->AppendSeparator(); + queryMenu->Append(MNU_CANCEL, _("&Cancel\tAlt-Break"), _("Cancel query")); + queryMenu->AppendSeparator(); + queryMenu->Append(MNU_DOCOMMIT, _("Commit\tCtrl-Shift-C"), _("Commit")); + queryMenu->Append(MNU_DOROLLBACK, _("Rollback\tCtrl-Shift-R"), _("Rollback")); + menuBar->Append(queryMenu, _("&Query")); + + favouritesMenu = new wxMenu(); + favouritesMenu->Append(MNU_FAVOURITES_ADD, _("Add favourite..."), _("Add current query to favourites")); + favouritesMenu->Append(MNU_FAVOURITES_INJECT, _("Inject\tF2"), _("Replace a word under cursor with a favourite with same name")); + favouritesMenu->Append(MNU_FAVOURITES_MANAGE, _("Manage favourites..."), _("Edit and delete favourites")); + favouritesMenu->AppendSeparator(); + favourites = 0L; + UpdateFavouritesList(); + menuBar->Append(favouritesMenu, _("Fav&ourites")); + + macrosMenu = new wxMenu(); + macrosMenu->Append(MNU_MACROS_MANAGE, _("Manage macros..."), _("Edit and delete macros")); + macrosMenu->AppendSeparator(); + macros = 0L; + UpdateMacrosList(); + menuBar->Append(macrosMenu, _("&Macros")); + + // View menu + viewMenu = new wxMenu(); + viewMenu->Append(MNU_DATABASEBAR, _("&Connection bar\tCtrl-Alt-B"), _("Show or hide the database selection bar."), wxITEM_CHECK); + viewMenu->Append(MNU_OUTPUTPANE, _("&Output pane\tCtrl-Alt-O"), _("Show or hide the output pane."), wxITEM_CHECK); + viewMenu->Append(MNU_SCRATCHPAD, _("S&cratch pad\tCtrl-Alt-S"), _("Show or hide the scratch pad."), wxITEM_CHECK); + viewMenu->Append(MNU_TOOLBAR, _("&Tool bar\tCtrl-Alt-T"), _("Show or hide the tool bar."), wxITEM_CHECK); + viewMenu->AppendSeparator(); + viewMenu->Append(MNU_SHOWINDENTGUIDES, _("&Indent guides"), _("Enable or disable display of indent guides"), wxITEM_CHECK); + viewMenu->Append(MNU_SHOWLINEENDS, _("&Line ends"), _("Enable or disable display of line ends"), wxITEM_CHECK); + viewMenu->Append(MNU_SHOWWHITESPACE, _("&Whitespace"), _("Enable or disable display of whitespaces"), wxITEM_CHECK); + viewMenu->Append(MNU_WORDWRAP, _("&Word wrap"), _("Enable or disable word wrapping"), wxITEM_CHECK); + viewMenu->Append(MNU_SHOWLINENUMBER, _("&Line number"), _("Enable or disable display of line number"), wxITEM_CHECK); + viewMenu->AppendSeparator(); + viewMenu->Append(MNU_DEFAULTVIEW, _("&Default view\tCtrl-Alt-V"), _("Restore the default view.")); + + menuBar->Append(viewMenu, _("&View")); + + wxMenu *helpMenu = new wxMenu(); + helpMenu->Append(MNU_CONTENTS, _("&Help"), _("Open the helpfile.")); + helpMenu->Append(MNU_HELP, _("&SQL Help\tF1"), _("Display help on SQL commands.")); + +#ifdef __WXMAC__ + menuFactories = new menuFactoryList(); + aboutFactory *af = new aboutFactory(menuFactories, helpMenu, 0); + wxApp::s_macAboutMenuItemId = af->GetId(); + menuFactories->RegisterMenu(this, wxCommandEventHandler(pgFrame::OnAction)); +#endif + + menuBar->Append(helpMenu, _("&Help")); + + SetMenuBar(menuBar); + + queryMenu->Check(MNU_VERBOSE, settings->GetExplainVerbose()); + queryMenu->Check(MNU_COSTS, settings->GetExplainCosts()); + queryMenu->Check(MNU_BUFFERS, settings->GetExplainBuffers()); + queryMenu->Check(MNU_TIMING, settings->GetExplainTiming()); + + UpdateRecentFiles(); + + wxAcceleratorEntry entries[16]; + + entries[0].Set(wxACCEL_CTRL, (int)'E', MNU_EXECUTE); + entries[1].Set(wxACCEL_CTRL, (int)'O', MNU_OPEN); + entries[2].Set(wxACCEL_CTRL, (int)'S', MNU_SAVE); + entries[3].Set(wxACCEL_CMD, (int)'S', MNU_SAVE); + entries[4].Set(wxACCEL_CTRL, (int)'F', MNU_FIND); + entries[5].Set(wxACCEL_CTRL, (int)'R', MNU_REPLACE); + entries[6].Set(wxACCEL_NORMAL, WXK_F8, MNU_EXECUTE); + entries[7].Set(wxACCEL_NORMAL, WXK_F7, MNU_EXPLAIN); + entries[8].Set(wxACCEL_ALT, WXK_PAUSE, MNU_CANCEL); + entries[9].Set(wxACCEL_CTRL, (int)'A', MNU_SELECTALL); + entries[10].Set(wxACCEL_CMD, (int)'A', MNU_SELECTALL); + entries[11].Set(wxACCEL_NORMAL, WXK_F1, MNU_HELP); + entries[12].Set(wxACCEL_CTRL, (int)'N', MNU_NEW); + entries[13].Set(wxACCEL_NORMAL, WXK_F6, MNU_EXECPGS); + entries[14].Set(wxACCEL_NORMAL, WXK_F5, MNU_EXECFILE); + entries[15].Set(wxACCEL_CTRL, (int)'T', MNU_NEWSQLTAB); + + wxAcceleratorTable accel(16, entries); + SetAcceleratorTable(accel); + + queryMenu->Enable(MNU_CANCEL, false); + + int iWidths[7] = {0, -1, 40, 200, 80, 80, 80}; + statusBar = CreateStatusBar(7); + SetStatusBarPane(-1); + SetStatusWidths(7, iWidths); + SetStatusText(_("ready"), STATUSPOS_MSGS); + + toolBar = new ctlMenuToolbar(this, -1, wxDefaultPosition, wxDefaultSize, wxTB_FLAT | wxTB_NODIVIDER); + + toolBar->SetToolBitmapSize(wxSize(16, 16)); + + toolBar->AddTool(MNU_NEWSQLTAB, wxEmptyString, *file_new_png_bmp, _("New SQL tab"), wxITEM_NORMAL); + toolBar->AddTool(MNU_OPEN, wxEmptyString, *file_open_png_bmp, _("Open file"), wxITEM_NORMAL); + toolBar->AddTool(MNU_SAVE, wxEmptyString, *file_save_png_bmp, _("Save file"), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_CUT, wxEmptyString, *clip_cut_png_bmp, _("Cut selected text to clipboard"), wxITEM_NORMAL); + toolBar->AddTool(MNU_COPY, wxEmptyString, *clip_copy_png_bmp, _("Copy selected text to clipboard"), wxITEM_NORMAL); + toolBar->AddTool(MNU_PASTE, wxEmptyString, *clip_paste_png_bmp, _("Paste selected text from clipboard"), wxITEM_NORMAL); + toolBar->AddTool(MNU_CLEAR, wxEmptyString, *edit_clear_png_bmp, _("Clear edit window"), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_UNDO, wxEmptyString, *edit_undo_png_bmp, _("Undo last action"), wxITEM_NORMAL); + toolBar->AddTool(MNU_REDO, wxEmptyString, *edit_redo_png_bmp, _("Redo last action"), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_FIND, wxEmptyString, *edit_find_png_bmp, _("Find and replace text"), wxITEM_NORMAL); + toolBar->AddSeparator(); + + toolBar->AddTool(MNU_EXECUTE, wxEmptyString, *query_execute_png_bmp, _("Execute query"), wxITEM_NORMAL); + toolBar->AddTool(MNU_EXECPGS, wxEmptyString, *query_pgscript_png_bmp, _("Execute pgScript"), wxITEM_NORMAL); + toolBar->AddTool(MNU_EXECFILE, wxEmptyString, *query_execfile_png_bmp, _("Execute query, write result to file"), wxITEM_NORMAL); + toolBar->AddTool(MNU_EXPLAIN, wxEmptyString, *query_explain_png_bmp, _("Explain query"), wxITEM_NORMAL); + toolBar->AddTool(MNU_CANCEL, wxEmptyString, *query_cancel_png_bmp, _("Cancel query"), wxITEM_NORMAL); + toolBar->AddSeparator(); + + toolBar->AddTool(MNU_DOCOMMIT, wxEmptyString, *query_commit_png_bmp, _("Commit"), wxITEM_NORMAL); + toolBar->AddTool(MNU_DOROLLBACK, wxEmptyString, *query_rollback_png_bmp, _("Rollback"), wxITEM_NORMAL); + toolBar->AddSeparator(); + + toolBar->AddTool(MNU_HELP, wxEmptyString, *help_png_bmp, _("Display help on SQL commands."), wxITEM_NORMAL); + toolBar->Realize(); + + // Add the database selection bar + cbConnection = new wxBitmapComboBox(this, CTRLID_CONNECTION, wxEmptyString, wxDefaultPosition, wxSize(-1, -1), wxArrayString(), wxCB_READONLY | wxCB_DROPDOWN); + cbConnection->Append(conn->GetName(), CreateBitmap(GetServerColour(conn)), (void *)conn); + cbConnection->Append(_(""), wxNullBitmap, (void *) NULL); + + //Create SQL editor notebook + sqlNotebook = new ctlAuiNotebook(this, CTL_NTBKCENTER, wxDefaultPosition, wxDefaultSize, wxAUI_NB_TOP | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS | wxAUI_NB_WINDOWLIST_BUTTON); + + // Create panel for query + wxPanel *pnlQuery = new wxPanel(sqlNotebook); + + // Create the outer box sizer + wxBoxSizer *boxQuery = new wxBoxSizer(wxVERTICAL); + + // Create the inner box sizer + // This one will contain the label, the combobox, and the two buttons + wxBoxSizer *boxHistory = new wxBoxSizer(wxHORIZONTAL); + + // Label + wxStaticText *label = new wxStaticText(pnlQuery, 0, _("Previous queries")); + boxHistory->Add(label, 0, wxALL | wxALIGN_CENTER_VERTICAL, 1); + + // Query combobox + sqlQueries = new wxComboBox(pnlQuery, CTL_SQLQUERYCBOX, wxT(""), wxDefaultPosition, wxDefaultSize, wxArrayString(), wxCB_DROPDOWN | wxCB_READONLY); + sqlQueries->SetToolTip(_("Previous queries")); + LoadQueries(); + boxHistory->Add(sqlQueries, 1, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, 1); + + // Delete Current button + btnDeleteCurrent = new wxButton(pnlQuery, CTL_DELETECURRENTBTN, _("Delete")); + btnDeleteCurrent->Enable(false); + boxHistory->Add(btnDeleteCurrent, 0, wxALL | wxALIGN_CENTER_VERTICAL, 1); + + // Delete All button + btnDeleteAll = new wxButton(pnlQuery, CTL_DELETEALLBTN, _("Delete All")); + btnDeleteAll->Enable(sqlQueries->GetCount() > 0); + boxHistory->Add(btnDeleteAll, 0, wxALL | wxALIGN_CENTER_VERTICAL, 1); + + boxQuery->Add(boxHistory, 0, wxEXPAND | wxALL, 1); + + // Create the other inner box sizer + // This one will contain the SQL box + wxBoxSizer *boxSQL = new wxBoxSizer(wxHORIZONTAL); + + // Use sqlQueryBook instead of sqlQuery and put the book inside boxSQL sizer. + // We don't add any SQL tabs until all menu items are initialized from settings. + sqlQueryBook = new ctlAuiNotebook(pnlQuery, CTL_SQLQUERYBOOK, wxDefaultPosition, wxDefaultSize, wxAUI_NB_TOP | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS | wxAUI_NB_CLOSE_ON_ACTIVE_TAB | wxAUI_NB_WINDOWLIST_BUTTON); + sqlQueryCounter = 0; + sqlQueryExec = NULL; + sqlQueryExecLast = NULL; + + boxSQL->Add(sqlQueryBook, 1, wxEXPAND | wxRIGHT | wxLEFT | wxBOTTOM, 1); + + boxQuery->Add(boxSQL, 1, wxEXPAND | wxRIGHT | wxLEFT | wxBOTTOM, 1); + + // Auto-sizing + pnlQuery->SetSizer(boxQuery); + boxQuery->Fit(pnlQuery); + + // Results pane + outputPane = new ctlAuiNotebook(this, CTL_NTBKGQB, wxDefaultPosition, wxSize(500, 300), wxAUI_NB_TOP | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS | wxAUI_NB_WINDOWLIST_BUTTON); + sqlResult = new ctlSQLResult(outputPane, conn, CTL_SQLRESULT, wxDefaultPosition, wxDefaultSize); + ctlSQL[0] = sqlResult; + explainCanvas = new ExplainCanvas(outputPane); + msgResult = new wxTextCtrl(outputPane, CTL_MSGRESULT, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_DONTWRAP); + msgResult->SetFont(settings->GetSQLFont()); + msgHistory = new wxTextCtrl(outputPane, CTL_MSGHISTORY, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_DONTWRAP); + msgHistory->SetFont(settings->GetSQLFont()); + + // Graphical Canvas + // initialize values + model = new gqbModel(); + controller = new gqbController(model, sqlNotebook, outputPane, wxSize(GQB_MIN_WIDTH, GQB_MIN_HEIGHT)); + firstTime = true; // Inform to GQB that the tree of table haven't filled. + gqbUpdateRunning = false; // Are we already updating the SQL query - event recursion protection. + adjustSizesTimer = NULL; // Timer used to avoid a bug when close outputPane + + // Setup SQL editor notebook NBP_SQLEDTR + sqlNotebook->AddPage(pnlQuery, _("SQL Editor")); + sqlNotebook->AddPage(controller->getViewContainer(), _("Graphical Query Builder")); + sqlNotebook->SetSelection(0); + + outputPane->AddPage(sqlResult, _("Data Output")); + outputPane->AddPage(explainCanvas, _("Explain")); + outputPane->AddPage(msgResult, _("Messages")); + outputPane->AddPage(msgHistory, _("History")); + + sqlResult->Connect(wxID_ANY, wxEVT_SET_FOCUS, wxFocusEventHandler(frmQuery::OnFocus)); + msgResult->Connect(wxID_ANY, wxEVT_SET_FOCUS, wxFocusEventHandler(frmQuery::OnFocus)); + msgHistory->Connect(wxID_ANY, wxEVT_SET_FOCUS, wxFocusEventHandler(frmQuery::OnFocus)); + + // Now, the scratchpad + scratchPad = new wxTextCtrl(this, CTL_SCRATCHPAD, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxHSCROLL); + + // Kickstart wxAUI + manager.AddPane(toolBar, wxAuiPaneInfo().Name(wxT("toolBar")).Caption(_("Tool bar")).ToolbarPane().Top().LeftDockable(false).RightDockable(false)); + manager.AddPane(cbConnection, wxAuiPaneInfo().Name(wxT("databaseBar")).Caption(_("Connection bar")).ToolbarPane().Top().LeftDockable(false).RightDockable(false)); + manager.AddPane(outputPane, wxAuiPaneInfo().Name(wxT("outputPane")).Caption(_("Output pane")).Bottom().MinSize(wxSize(200, 100)).BestSize(wxSize(550, 300))); + manager.AddPane(scratchPad, wxAuiPaneInfo().Name(wxT("scratchPad")).Caption(_("Scratch pad")).Right().MinSize(wxSize(100, 100)).BestSize(wxSize(250, 200))); + manager.AddPane(sqlNotebook, wxAuiPaneInfo().Name(wxT("sqlQuery")).Caption(_("SQL query")).Center().CaptionVisible(false).CloseButton(false).MinSize(wxSize(200, 100)).BestSize(wxSize(350, 200))); + + // Now load the layout + wxString perspective; + settings->Read(wxT("frmQuery/Perspective-") + wxString(FRMQUERY_PERSPECTIVE_VER), &perspective, FRMQUERY_DEFAULT_PERSPECTIVE); + manager.LoadPerspective(perspective, true); + + // and reset the captions for the current language + manager.GetPane(wxT("toolBar")).Caption(_("Tool bar")); + manager.GetPane(wxT("databaseBar")).Caption(_("Connection bar")); + manager.GetPane(wxT("sqlQuery")).Caption(_("SQL query")); + manager.GetPane(wxT("outputPane")).Caption(_("Output pane")); + manager.GetPane(wxT("scratchPad")).Caption(_("Scratch pad")); + + + // Sync the View menu options + viewMenu->Check(MNU_DATABASEBAR, manager.GetPane(wxT("databaseBar")).IsShown()); + viewMenu->Check(MNU_TOOLBAR, manager.GetPane(wxT("toolBar")).IsShown()); + viewMenu->Check(MNU_OUTPUTPANE, manager.GetPane(wxT("outputPane")).IsShown()); + viewMenu->Check(MNU_SCRATCHPAD, manager.GetPane(wxT("scratchPad")).IsShown()); + + // tell the manager to "commit" all the changes just made + manager.Update(); + + bool bVal; + + + // Auto-Select + bVal = settings->GetAutoSelectQuery(); + queryMenu->Check(MNU_AUTOSELECTQUERY, bVal); + + // Auto-rollback + bVal = settings->GetAutoRollback(); + queryMenu->Check(MNU_AUTOROLLBACK, bVal); + + // Auto-commit + bVal = settings->GetAutoCommit(); + queryMenu->Check(MNU_AUTOCOMMIT, bVal); + + // Auto indent + settings->Read(wxT("frmQuery/AutoIndent"), &bVal, true); + editMenu->Check(MNU_AUTOINDENT, bVal); + + // Word wrap + settings->Read(wxT("frmQuery/WordWrap"), &bVal, false); + viewMenu->Check(MNU_WORDWRAP, bVal); + + // Indent Guides + settings->Read(wxT("frmQuery/ShowIndentGuides"), &bVal, false); + viewMenu->Check(MNU_SHOWINDENTGUIDES, bVal); + + // Whitespace + settings->Read(wxT("frmQuery/ShowWhitespace"), &bVal, false); + viewMenu->Check(MNU_SHOWWHITESPACE, bVal); + + // Line ends + settings->Read(wxT("frmQuery/ShowLineEnds"), &bVal, false); + viewMenu->Check(MNU_SHOWLINEENDS, bVal); + + // Line number + settings->Read(wxT("frmQuery/ShowLineNumber"), &bVal, false); + viewMenu->Check(MNU_SHOWLINENUMBER, bVal); + + // Create the SQL box. After this, sqlQuery variable can be used. + SqlBookAddPage(); + + if (!file.IsEmpty() && wxFileName::FileExists(file)) + { + wxFileName fn = file; + lastFilename = fn.GetFullName(); + lastDir = fn.GetPath(); + lastPath = fn.GetFullPath(); + OpenLastFile(); + sqlQuery->Colourise(0, query.Length()); + } + else if (!query.IsNull()) + { + sqlQuery->SetText(query); + sqlQuery->Colourise(0, query.Length()); + wxSafeYield(); // needed to process sqlQuery modify event + sqlQuery->SetChanged(false); + sqlQuery->SetOrigin(ORIGIN_INITIAL); + /* _title if not empty should contain displayName of base object for the query. + It's pretty good for a proposed filename if the user chooses to Save As. */ + lastFilename = _title; + setExtendedTitle(); + SqlBookUpdatePageTitle(); + } else + { + // load temp file + wxString str; + wxString filename; + + wxString tempDir=wxStandardPaths::Get().GetTempDir()+wxT("\\"); + + wxString pref=_conn->GetDbname(); + + bool modeUnicode = settings->GetUnicodeFile(); + wxString f = wxFindFirstFile(tempDir+wxT("*.a")); + while ( !f.empty() ) + { + if (f.AfterLast('\\').StartsWith(wxT("Query"))||f.AfterLast('\\').StartsWith(pref)) { + wxUtfFile file(f, wxFile::read, modeUnicode ? wxFONTENCODING_UTF8 : wxFONTENCODING_DEFAULT); + if (file.IsOpened()) + { file.Read(str); file.Close(); } + if (!str.IsEmpty()) + { + sqlQuery->SetText(str); + sqlQuery->Colourise(0, str.Length()); + sqlQuery->EmptyUndoBuffer(); + wxSafeYield(); // needed to process sqlQuery modify event + //sqlQuery->SetFilename(lastPath); + sqlQuery->SetChanged(true); + //sqlQuery->SetOrigin(ORIGIN_INITIAL); + filename=f.AfterLast('\\').BeforeLast('.'); + sqlQuery->SetTitle(filename); + setExtendedTitle(); + SqlBookUpdatePageTitle(); + //SetLineEndingStyle(); + SaveTempFile(); + SqlBookAddPage(); + + } + + } + f = wxFindNextFile(); + } + //for (int i=1;i<15;i++) + //{ + //filename=wxString::Format(_("Query %i"), i); + + //if (!wxFileName::FileExists(tempDir+filename)) continue; + //wxUtfFile file(tempDir+filename, wxFile::read, modeUnicode ? wxFONTENCODING_UTF8 : wxFONTENCODING_DEFAULT); + + //if (file.IsOpened()) + //{ file.Read(str); file.Close(); } + ////QFile::remove(tempDir+wxT("\\")+filename); + //wxRemoveFile(tempDir+filename); + //if (!str.IsEmpty()) + //{ + // sqlQuery->SetText(str); + // sqlQuery->Colourise(0, str.Length()); + // sqlQuery->EmptyUndoBuffer(); + // wxSafeYield(); // needed to process sqlQuery modify event + // //sqlQuery->SetFilename(lastPath); + // sqlQuery->SetChanged(true); + // //sqlQuery->SetOrigin(ORIGIN_INITIAL); + // setExtendedTitle(); + // SqlBookUpdatePageTitle(); + // //SetLineEndingStyle(); + // SaveTempFile(); + // SqlBookAddPage(); + + //} + //// for end + //} + + } + //sqlQuery->SetAutoReplaceList(autoreplace); + updateMenu(); + queryMenu->Enable(MNU_SAVEHISTORY, false); + queryMenu->Enable(MNU_CLEARHISTORY, false); + setTools(false); + lastFileFormat = settings->GetUnicodeFile(); + + // Note that under GTK+, SetMaxLength() function may only be used with single line text controls. + // (see http://docs.wxwidgets.org/2.8/wx_wxtextctrl.html#wxtextctrlsetmaxlength) +#ifndef __WXGTK__ + msgResult->SetMaxLength(0L); + msgHistory->SetMaxLength(0L); +#endif +} + + +frmQuery::~frmQuery() +{ + closing = true; + + // Save frmQuery Perspective + settings->Write(wxT("frmQuery/Perspective-") + wxString(FRMQUERY_PERSPECTIVE_VER), manager.SavePerspective()); + + // Uninitialize wxAUIManager + manager.UnInit(); + + if(sqlNotebook) + { + delete sqlNotebook; + sqlNotebook = NULL; + } + if(controller) + { + delete controller; + controller = NULL; + } + if(model) + { + delete model; + model = NULL; + } + if(adjustSizesTimer) + { + delete adjustSizesTimer; + adjustSizesTimer = NULL; + } + + while (cbConnection->GetCount() > 1) + { + delete (pgConn *)cbConnection->GetClientData(0); + cbConnection->Delete(0); + } + + if (favourites) + { + delete favourites; + favourites = NULL; + } + + if (pgsTimer) + { + delete pgsTimer; + pgsTimer = NULL; + } + + if (pgScript) + { + delete pgScript; + pgScript = NULL; + } + + if (mainForm) + mainForm->RemoveFrame(this); + + if (macros) + delete macros; + if (autoreplace) + delete autoreplace; +} + + +void frmQuery::OnExit(wxCommandEvent &event) +{ + closing = true; + Close(); +} + + +void frmQuery::OnEraseBackground(wxEraseEvent &event) +{ + event.Skip(); +} + + +void frmQuery::OnSize(wxSizeEvent &event) +{ + event.Skip(); +} + + +void frmQuery::OnToggleScratchPad(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_SCRATCHPAD)) + manager.GetPane(wxT("scratchPad")).Show(true); + else + manager.GetPane(wxT("scratchPad")).Show(false); + manager.Update(); +} + + +void frmQuery::OnToggleDatabaseBar(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_DATABASEBAR)) + manager.GetPane(wxT("databaseBar")).Show(true); + else + manager.GetPane(wxT("databaseBar")).Show(false); + manager.Update(); +} + + +void frmQuery::OnToggleToolBar(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_TOOLBAR)) + manager.GetPane(wxT("toolBar")).Show(true); + else + manager.GetPane(wxT("toolBar")).Show(false); + manager.Update(); +} + + +void frmQuery::OnToggleOutputPane(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_OUTPUTPANE)) + { + manager.GetPane(wxT("outputPane")).Show(true); + } + else + { + manager.GetPane(wxT("outputPane")).Show(false); + } + manager.Update(); + adjustGQBSizes(); +} + + +void frmQuery::OnAuiUpdate(wxAuiManagerEvent &event) +{ + if(event.pane->name == wxT("databaseBar")) + { + viewMenu->Check(MNU_DATABASEBAR, false); + } + else if(event.pane->name == wxT("toolBar")) + { + viewMenu->Check(MNU_TOOLBAR, false); + } + else if(event.pane->name == wxT("outputPane")) + { + viewMenu->Check(MNU_OUTPUTPANE, false); + if(!adjustSizesTimer) + adjustSizesTimer = new wxTimer(this, CTL_TIMERSIZES); + adjustSizesTimer->Start(500); + } + else if(event.pane->name == wxT("scratchPad")) + { + viewMenu->Check(MNU_SCRATCHPAD, false); + } + event.Skip(); +} + + +void frmQuery::OnDefaultView(wxCommandEvent &event) +{ + // Reset captions to whatever AuiManager expects in perspective + BeginPerspectiveChange(); + + manager.LoadPerspective(FRMQUERY_DEFAULT_PERSPECTIVE, true); + + // Reset the captions for the current language + manager.GetPane(wxT("toolBar")).Caption(_("Tool bar")); + manager.GetPane(wxT("databaseBar")).Caption(_("Connection bar")); + manager.GetPane(wxT("sqlQuery")).Caption(_("SQL query")); + manager.GetPane(wxT("outputPane")).Caption(_("Output pane")); + manager.GetPane(wxT("scratchPad")).Caption(_("Scratch pad")); + + EndPerspectiveChange(false); + + manager.Update(); + + // Sync the View menu options + viewMenu->Check(MNU_DATABASEBAR, manager.GetPane(wxT("databaseBar")).IsShown()); + viewMenu->Check(MNU_TOOLBAR, manager.GetPane(wxT("toolBar")).IsShown()); + viewMenu->Check(MNU_OUTPUTPANE, manager.GetPane(wxT("outputPane")).IsShown()); + viewMenu->Check(MNU_SCRATCHPAD, manager.GetPane(wxT("scratchPad")).IsShown()); +} + +void frmQuery::OnAutoSelectQuery(wxCommandEvent &event) +{ + queryMenu->Check(MNU_AUTOSELECTQUERY, event.IsChecked()); + + settings->WriteBool(wxT("frmQuery/AutoSelectQuery"), queryMenu->IsChecked(MNU_AUTOSELECTQUERY)); +} + +void frmQuery::OnAutoRollback(wxCommandEvent &event) +{ + queryMenu->Check(MNU_AUTOROLLBACK, event.IsChecked()); + + settings->WriteBool(wxT("frmQuery/AutoRollback"), queryMenu->IsChecked(MNU_AUTOROLLBACK)); +} + +void frmQuery::OnAutoCommit(wxCommandEvent &event) +{ + queryMenu->Check(MNU_AUTOCOMMIT, event.IsChecked()); + if(event.IsChecked() && conn->GetTxStatus() != PQTRANS_IDLE) + wxMessageBox( + _("The current transaction is still in progess.\n\nIn order to take the effect of AUTOCOMMIT mode, please complete the transaction by executing COMMIT, or ROLLBACK statement."), + _("Warning - Transaction in progress"), wxICON_INFORMATION | wxOK, this); + settings->WriteBool(wxT("frmQuery/AutoCommit"), queryMenu->IsChecked(MNU_AUTOCOMMIT)); +} + +void frmQuery::OnAutoIndent(wxCommandEvent &event) +{ + editMenu->Check(MNU_AUTOINDENT, event.IsChecked()); + + settings->WriteBool(wxT("frmQuery/AutoIndent"), editMenu->IsChecked(MNU_AUTOINDENT)); + + SqlBookSetAutoIndent(event.IsChecked()); +} + + +void frmQuery::OnWordWrap(wxCommandEvent &event) +{ + viewMenu->Check(MNU_WORDWRAP, event.IsChecked()); + + settings->WriteBool(wxT("frmQuery/WordWrap"), viewMenu->IsChecked(MNU_WORDWRAP)); + + SqlBookSetWrapMode(event.IsChecked()); +} + + +void frmQuery::OnShowIndentGuides(wxCommandEvent &event) +{ + viewMenu->Check(MNU_SHOWINDENTGUIDES, event.IsChecked()); + + settings->WriteBool(wxT("frmQuery/ShowIndentGuides"), viewMenu->IsChecked(MNU_SHOWINDENTGUIDES)); + + SqlBookSetIndentGuides(event.IsChecked()); +} + + +void frmQuery::OnShowWhitespace(wxCommandEvent &event) +{ + viewMenu->Check(MNU_SHOWWHITESPACE, event.IsChecked()); + + settings->WriteBool(wxT("frmQuery/ShowWhitespace"), viewMenu->IsChecked(MNU_SHOWWHITESPACE)); + + SqlBookSetViewWhiteSpace(event.IsChecked()); +} + + +void frmQuery::OnShowLineEnds(wxCommandEvent &event) +{ + viewMenu->Check(MNU_SHOWLINEENDS, event.IsChecked()); + + settings->WriteBool(wxT("frmQuery/ShowLineEnds"), viewMenu->IsChecked(MNU_SHOWLINEENDS)); + + SqlBookSetViewEOL(event.IsChecked()); +} + + +void frmQuery::OnShowLineNumber(wxCommandEvent &event) +{ + viewMenu->Check(MNU_SHOWLINENUMBER, event.IsChecked()); + + settings->WriteBool(wxT("frmQuery/ShowLineNumber"), viewMenu->IsChecked(MNU_SHOWLINENUMBER)); + + SqlBookSetViewLineNumbers(event.IsChecked()); +} + +void frmQuery::OnActivate(wxActivateEvent &event) +{ + if (event.GetActive()) + updateMenu(); + event.Skip(); +} + + +void frmQuery::OnExport(wxCommandEvent &ev) +{ + sqlResult->Export(); +} + + +void frmQuery::Go() +{ + cbConnection->SetSelection(0L); + wxCommandEvent ev; + OnChangeConnection(ev); + + Show(true); + sqlQuery->SetFocus(); + loading = false; +} + + +typedef struct __sqltokenhelp +{ + const wxChar *token; + const wxChar *page; + int type; +} SqlTokenHelp; + +SqlTokenHelp sqlTokenHelp[] = +{ + { wxT("ABORT"), 0, 0}, + { wxT("ALTER"), 0, 2}, + { wxT("ANALYZE"), 0, 0}, + { wxT("BEGIN"), 0, 0}, + { wxT("CHECKPOINT"), 0, 0}, + { wxT("CLOSE"), 0, 0}, + { wxT("CLUSTER"), 0, 0}, + { wxT("COMMENT"), 0, 0}, + { wxT("COMMIT"), 0, 0}, + { wxT("COPY"), 0, 0}, + { wxT("CREATE"), 0, 1}, + { wxT("DEALLOCATE"), 0, 0}, + { wxT("DECLARE"), 0, 0}, + { wxT("DELETE"), 0, 0}, + { wxT("DROP"), 0, 1}, + { wxT("END"), 0, 0}, + { wxT("EXECUTE"), 0, 0}, + { wxT("EXPLAIN"), 0, 0}, + { wxT("FETCH"), 0, 0}, + { wxT("GRANT"), 0, 0}, + { wxT("INSERT"), 0, 0}, + { wxT("LISTEN"), 0, 0}, + { wxT("LOAD"), 0, 0}, + { wxT("LOCK"), 0, 0}, + { wxT("MOVE"), 0, 0}, + { wxT("NOTIFY"), 0, 0}, + { wxT("END"), 0, 0}, + // { wxT("PREPARE"), 0, 0}, handled individually + { wxT("REINDEX"), 0, 0}, + { wxT("RELEASE"), wxT("pg/sql-release-savepoint"), 0}, + { wxT("RESET"), 0, 0}, + { wxT("REVOKE"), 0, 0}, + // { wxT("ROLLBACK"), 0, 0}, handled individually + { wxT("SAVEPOINT"), 0, 0}, + { wxT("SELECT"), 0, 0}, + { wxT("SET"), 0, 0}, + { wxT("SHOW"), 0, 0}, + { wxT("START"), wxT("pg/sql-start-transaction"), 0}, + { wxT("TRUNCATE"), 0, 0}, + { wxT("UNLISTEN"), 0, 0}, + { wxT("UPDATE"), 0, 0}, + { wxT("VACUUM"), 0, 0}, + + { wxT("AGGREGATE"), 0, 11}, + { wxT("CAST"), 0, 11}, + { wxT("CONSTRAINT"), 0, 11}, + { wxT("CONVERSION"), 0, 11}, + { wxT("DATABASE"), 0, 12}, + { wxT("DOMAIN"), 0, 11}, + { wxT("FUNCTION"), 0, 11}, + { wxT("GROUP"), 0, 12}, + { wxT("INDEX"), 0, 11}, + { wxT("LANGUAGE"), 0, 11}, + { wxT("OPERATOR"), 0, 11}, + { wxT("ROLE"), 0, 11}, + { wxT("RULE"), 0, 11}, + { wxT("SCHEMA"), 0, 11}, + { wxT("SEQUENCE"), 0, 11}, + { wxT("TABLE"), 0, 12}, + { wxT("TABLESPACE"), 0, 12}, + { wxT("TRIGGER"), 0, 12}, + { wxT("TYPE"), 0, 11}, + { wxT("USER"), 0, 12}, + { wxT("VIEW"), 0, 11}, + { wxT("EXTTABLE"), 0, 12}, + { 0, 0 } +}; + +void frmQuery::OnContents(wxCommandEvent &event) +{ + DisplayHelp(wxT("query"), HELP_PGADMIN); +} + + +void frmQuery::OnChangeConnection(wxCommandEvent &ev) +{ + // On Solaris, this event seems to get fired when the form closes(!!) + if(!IsVisible() && !loading) + return; + + unsigned int sel = cbConnection->GetSelection(); + if (sel == cbConnection->GetCount() - 1) + { + // new Connection + dlgSelectConnection dlg(this, mainForm); + int rc = dlg.Go(conn, cbConnection); + if (rc == wxID_OK) + { + bool createdNewConn; + wxString usr=wxEmptyString; + wxGetEnv(wxT("USERNAME"),&usr); + + wxString applicationname = appearanceFactory->GetLongAppName() + wxT(" - query ")+usr; + pgConn *newconn = dlg.CreateConn(applicationname, createdNewConn); + if (newconn && createdNewConn) + { + cbConnection->Insert(newconn->GetName(), CreateBitmap(GetServerColour(newconn)), sel); + cbConnection->SetClientData(sel, (void *)newconn); + cbConnection->SetSelection(sel); + OnChangeConnection(ev); + } + else + rc = wxID_CANCEL; + } + if (rc != wxID_OK) + { + unsigned int i; + for (i = 0 ; i < sel ; i++) + { + if (cbConnection->GetClientData(i) == conn) + { + cbConnection->SetSelection(i); + break; + } + } + } + } + else + { + conn = (pgConn *)cbConnection->GetClientData(sel); + SqlBookSetDatabase(conn); + sqlResult->SetConnection(conn); + pgScript->SetConnection(conn); + title = wxT("Query - ") + cbConnection->GetValue(); + setExtendedTitle(); + + //Refresh GQB Tree if used + if(conn && !firstTime) + { + controller->getTablesBrowser()->refreshTables(conn); + controller->getView()->Refresh(); + } + } +} + + +void frmQuery::OnHelp(wxCommandEvent &event) +{ + wxString page; + wxString query = sqlQuery->GetSelectedText(); + if (query.IsNull()) + query = sqlQuery->GetText(); + + query.Trim(false); + + if (!query.IsEmpty()) + { + wxStringTokenizer tokens(query); + query = tokens.GetNextToken(); + + if (query.IsSameAs(wxT("PREPARE"), false)) + { + if (tokens.GetNextToken().IsSameAs(wxT("TRANSACTION"), false)) + page = wxT("sql-prepare-transaction"); + else + page = wxT("sql-prepare"); + } + else if (query.IsSameAs(wxT("ROLLBACK"), false)) + { + if (tokens.GetNextToken().IsSameAs(wxT("PREPARED"), false)) + page = wxT("sql-rollback-prepared"); + else + page = wxT("sql-rollback"); + } + else + { + SqlTokenHelp *sth = sqlTokenHelp; + while (sth->token) + { + if (sth->type < 10 && query.IsSameAs(sth->token, false)) + { + if (sth->page) + page = sth->page; + else + page = wxT("sql-") + query.Lower(); + + if (sth->type) + { + int type = sth->type + 10; + + query = tokens.GetNextToken(); + sth = sqlTokenHelp; + while (sth->token) + { + if (sth->type >= type && query.IsSameAs(sth->token, false)) + { + if (sth->page) + page += sth->page; + else + page += query.Lower(); + break; + } + sth++; + } + if (!sth->token) + page = wxT("sql-commands"); + } + break; + } + sth++; + } + } + } + if (page.IsEmpty()) + page = wxT("sql-commands"); + + if (conn->GetIsEdb()) + DisplayHelp(page, HELP_ENTERPRISEDB); + else if (conn->GetIsGreenplum()) + DisplayHelp(page, HELP_GREENPLUM); + else + DisplayHelp(page, HELP_POSTGRESQL); +} + + +void frmQuery::OnSaveHistory(wxCommandEvent &event) +{ +#ifdef __WXMSW__ + wxFileDialog *dlg = new wxFileDialog(this, _("Save history"), lastDir, wxEmptyString, + _("Log files (*.log)|*.log|All files (*.*)|*.*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); +#else + wxFileDialog *dlg = new wxFileDialog(this, _("Save history"), lastDir, wxEmptyString, + _("Log files (*.log)|*.log|All files (*)|*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); +#endif + if (dlg->ShowModal() == wxID_OK) + { + if (!FileWrite(dlg->GetPath(), msgHistory->GetValue(), false)) + { + wxLogError(__("Could not write the file %s: Errcode=%d."), dlg->GetPath().c_str(), wxSysErrorCode()); + } + } + delete dlg; + +} + +void frmQuery::OnChangeNotebook(wxAuiNotebookEvent &event) +{ + // A bug in wxGTK prevents us to show a modal dialog within a + // EVT_AUINOTEBOOK_PAGE_CHANGED event + // So, we need these three lines of code to work-around it + wxWindow *win = wxWindow::GetCapture(); + if (win) + win->ReleaseMouse(); + + if(sqlNotebook && sqlNotebook->GetPageCount() >= 2) + { + + if (event.GetSelection() == 0) + { + queryMenu->SetHelpString(MNU_EXECUTE, _("Execute query")); + queryMenu->SetHelpString(MNU_EXECFILE, _("Execute query, write result to file")); + toolBar->SetToolShortHelp(MNU_EXECUTE, _("Execute query")); + toolBar->SetToolShortHelp(MNU_EXECFILE, _("Execute query, write result to file")); + viewMenu->Enable(MNU_OUTPUTPANE, true); + viewMenu->Enable(MNU_SCRATCHPAD, true); + + // Reset the panes + if (viewMenu->IsChecked(MNU_OUTPUTPANE)) + manager.GetPane(wxT("outputPane")).Show(true); + if (viewMenu->IsChecked(MNU_SCRATCHPAD)) + manager.GetPane(wxT("scratchPad")).Show(true); + manager.Update(); + + updateFromGqb(false); + } + else + { + manager.GetPane(wxT("outputPane")).Show(false); + manager.GetPane(wxT("scratchPad")).Show(false); + manager.Update(); + viewMenu->Enable(MNU_OUTPUTPANE, false); + viewMenu->Enable(MNU_SCRATCHPAD, false); + + if(firstTime) //Things that should be done on first click on GQB + { + // Menu + queryMenu->Append(MNU_EXECUTE, _("Generate SQL from Graphical Query Builder Model")); + queryMenu->SetHelpString(MNU_EXECFILE, _("Generate SQL from Graphical Query Builder Model")); + toolBar->SetToolShortHelp(MNU_EXECUTE, _("Generate SQL from Graphical Query Builder Model")); + toolBar->SetToolShortHelp(MNU_EXECFILE, _("Generate SQL from Graphical Query Builder Model")); + + // Size, and pause to allow the window to draw + adjustGQBSizes(); + wxTheApp->Yield(true); + + // Database related Stuffs. + // Create a server object and connect it. + controller->getTablesBrowser()->refreshTables(conn); + firstTime = false; + } + } + } +} + + +void frmQuery::OnSetFocus(wxFocusEvent &event) +{ + sqlQuery->SetFocus(); + event.Skip(); +} + + +void frmQuery::OnClearHistory(wxCommandEvent &event) +{ + queryMenu->Enable(MNU_SAVEHISTORY, false); + queryMenu->Enable(MNU_CLEARHISTORY, false); + msgHistory->Clear(); + msgHistory->SetFont(settings->GetSQLFont()); +} + + +void frmQuery::OnFocus(wxFocusEvent &ev) +{ + if (wxDynamicCast(this, wxFrame)) + updateMenu(); + else + { + frmQuery *wnd = (frmQuery *)GetParent(); + + if (wnd) + wnd->OnFocus(ev); + } + ev.Skip(); +} + + +void frmQuery::OnCut(wxCommandEvent &ev) +{ + if (currentControl() == sqlQuery) + { + sqlQuery->Cut(); + updateMenu(); + } +} + + +wxWindow *frmQuery::currentControl() +{ + wxWindow *wnd = FindFocus(); + if (wnd == outputPane) + { + switch (outputPane->GetSelection()) + { + case 0: + wnd = sqlResult; + break; + case 1: + wnd = explainCanvas; + break; + case 2: + wnd = msgResult; + break; + case 3: + wnd = msgHistory; + break; + } + } + return wnd; + +} + + +void frmQuery::OnCopy(wxCommandEvent &ev) +{ + wxWindow *wnd = currentControl(); + + if (wnd == sqlQuery) + sqlQuery->Copy(); + else if (wnd == msgResult) + msgResult->Copy(); + else if (wnd == msgHistory) + msgHistory->Copy(); + else if (wnd == scratchPad) + scratchPad->Copy(); + else + { + wxWindow *obj = wnd; + + while (obj != NULL) + { + if (obj == sqlResult) + { + sqlResult->Copy(); + break; + } + obj = obj->GetParent(); + } + } + updateMenu(); +} + + +void frmQuery::OnPaste(wxCommandEvent &ev) +{ + if (currentControl() == sqlQuery) + sqlQuery->Paste(); + else if (currentControl() == scratchPad) + scratchPad->Paste(); +} + + +void frmQuery::OnClear(wxCommandEvent &ev) +{ + wxWindow *wnd = currentControl(); + + if (wnd == sqlQuery) + sqlQuery->ClearAll(); + else if (wnd == msgResult) + { + msgResult->Clear(); + msgResult->SetFont(settings->GetSQLFont()); + } + else if (wnd == msgHistory) + { + msgHistory->Clear(); + msgHistory->SetFont(settings->GetSQLFont()); + } + else if (wnd == scratchPad) + scratchPad->Clear(); +} + + +void frmQuery::OnSelectAll(wxCommandEvent &ev) +{ + wxWindow *wnd = currentControl(); + + if (wnd == sqlQuery) + sqlQuery->SelectAll(); + else if (wnd == msgResult) + msgResult->SelectAll(); + else if (wnd == msgHistory) + msgHistory->SelectAll(); + else if (wnd == sqlResult) + sqlResult->SelectAll(); + else if (wnd == scratchPad) + scratchPad->SelectAll(); + else if (wnd->GetParent() == sqlResult) + sqlResult->SelectAll(); +} + + +void frmQuery::OnSearchReplace(wxCommandEvent &ev) +{ + sqlQuery->OnSearchReplace(ev); +} + + +void frmQuery::OnUndo(wxCommandEvent &ev) +{ + sqlQuery->Undo(); +} + + +void frmQuery::OnRedo(wxCommandEvent &ev) +{ + sqlQuery->Redo(); +} + + +void frmQuery::setExtendedTitle() +{ + wxString chgStr; + if (sqlQuery->IsChanged()) + chgStr = wxT(" *"); + + wxString filename = sqlQuery->GetFilename(); + if (filename.IsNull()) + SetTitle(title + chgStr); + else + { + SetTitle(title + wxT(" - [") + filename + wxT("]") + chgStr); + } + // Allow to save initial queries though they are not changed + bool enableSave = sqlQuery->IsChanged() || (sqlQuery->GetOrigin() == ORIGIN_INITIAL); + toolBar->EnableTool(MNU_SAVE, enableSave); + fileMenu->Enable(MNU_SAVE, enableSave); +} + +bool frmQuery::relatesToWindow(wxWindow *which, wxWindow *related) +{ + while (which != NULL) + { + if (which == related) + return true; + else + which = which->GetParent(); + } + return false; +} + +void frmQuery::updateMenu(bool allowUpdateModelSize) +{ + bool canCut = false; + bool canCopy = false; + bool canPaste = false; + bool canUndo = false; + bool canRedo = false; + bool canClear = false; + bool canFind = false; + bool canAddFavourite = false; + bool canManageFavourite = false; + bool canSaveExplain = false; + bool canSaveGQB = false; + + wxAuiFloatingFrame *fp = wxDynamicCastThis(wxAuiFloatingFrame); + if (fp) + return; + + if (closing) + return; + + canSaveExplain = explainCanvas->GetDiagram()->GetCount() > 0; + + if (allowUpdateModelSize) + { + canSaveGQB = controller->getView() != NULL && controller->getView()->canSaveAsImage(); + } + + saveasImageMenu->Enable(MNU_SAVEAS_IMAGE_GQB, canSaveGQB); + saveasImageMenu->Enable(MNU_SAVEAS_IMAGE_EXPLAIN, canSaveExplain); + + wxWindow *wnd = currentControl(); + if (wnd == NULL) + return; + + if (relatesToWindow(wnd, sqlQuery) + || relatesToWindow(wnd, sqlResult) + || relatesToWindow(wnd, msgResult) + || relatesToWindow(wnd, msgHistory) + || relatesToWindow(wnd, scratchPad)) + { + if (relatesToWindow(wnd, sqlQuery)) + { + canUndo = sqlQuery->CanUndo(); + canRedo = sqlQuery->CanRedo(); + canPaste = sqlQuery->CanPaste(); + canFind = true; + canAddFavourite = (sqlQuery->GetLength() > 0) && (settings->GetFavouritesFile().Length() > 0); + canManageFavourite = (settings->GetFavouritesFile().Length() > 0); + } + else if (relatesToWindow(wnd, scratchPad)) + { + canPaste = true; + } + canCopy = true; + canCut = true; + canClear = true; + } + + toolBar->EnableTool(MNU_UNDO, canUndo); + editMenu->Enable(MNU_UNDO, canUndo); + + toolBar->EnableTool(MNU_REDO, canRedo); + editMenu->Enable(MNU_REDO, canRedo); + + toolBar->EnableTool(MNU_COPY, canCopy); + editMenu->Enable(MNU_COPY, canCopy); + + toolBar->EnableTool(MNU_PASTE, canPaste); + editMenu->Enable(MNU_PASTE, canPaste); + + toolBar->EnableTool(MNU_CUT, canCut); + editMenu->Enable(MNU_CUT, canCut); + + toolBar->EnableTool(MNU_CLEAR, canClear); + editMenu->Enable(MNU_CLEAR, canClear); + + toolBar->EnableTool(MNU_FIND, canFind); + editMenu->Enable(MNU_FIND, canFind); + + favouritesMenu->Enable(MNU_FAVOURITES_ADD, canAddFavourite); + favouritesMenu->Enable(MNU_FAVOURITES_INJECT, canAddFavourite); // these two use the same criteria + favouritesMenu->Enable(MNU_FAVOURITES_MANAGE, canManageFavourite); +} + + +void frmQuery::UpdateFavouritesList() +{ + if (IsVisible() && menuBar->FindMenu(_("Fav&ourites")) == wxNOT_FOUND) + return; + + if (favourites) + delete favourites; + + favourites = queryFavouriteFileProvider::LoadFavourites(true); + + while (favouritesMenu->GetMenuItemCount() > 4) // there are 3 static items + separator above + { + favouritesMenu->Destroy(favouritesMenu->GetMenuItems()[4]); + } + + favourites->AppendAllToMenu(favouritesMenu, MNU_FAVOURITES_MANAGE + 1); +} + + +void frmQuery::UpdateMacrosList() +{ + if (IsVisible() && menuBar->FindMenu(_("&Macros")) == wxNOT_FOUND) + return; + + if (macros) + delete macros; + + macros = queryMacroFileProvider::LoadMacros(true); + + while (macrosMenu->GetMenuItemCount() > 2) + { + macrosMenu->Destroy(macrosMenu->GetMenuItems()[2]); + } + + macros->AppendAllToMenu(macrosMenu, MNU_MACROS_MANAGE + 1); +} + + +void frmQuery::OnAddFavourite(wxCommandEvent &event) +{ + if (sqlQuery->GetText().Trim().IsEmpty()) + return; + int r = dlgAddFavourite(this, favourites).AddFavourite(sqlQuery->GetText()); + if (r == 1) + { + // Added a favourite, so save + queryFavouriteFileProvider::SaveFavourites(favourites); + } + if (r == 1 || r == -1) + { + // Changed something requiring rollback + mainForm->UpdateAllFavouritesList(); + } +} + + +void frmQuery::OnInjectFavourite(wxCommandEvent &event) +{ + queryFavouriteItem *fav; + bool selected = true; + int startPos, endPos; + wxString name = sqlQuery->GetSelectedText(); + + if (name.IsEmpty()) + { + // get the word under cursor: + int curPos = sqlQuery->GetCurrentPos(); + startPos = sqlQuery->WordStartPosition(curPos, true); + endPos = sqlQuery->WordEndPosition(curPos, true); + name = sqlQuery->GetTextRange(startPos, endPos); + selected = false; + } + name.Trim(false).Trim(true); + if (name.IsEmpty()) + return; + + // search for favourite with this name + fav = favourites->FindFavourite(name); + if (!fav) + return; + + // replace selection (or current word) with it's contents + //wxLogInfo(wxT("frmQuery::OnReplaceFavourite(): name=[%s] contents=[%s]"), name, fav->GetContents()); + sqlQuery->BeginUndoAction(); + if (!selected) + sqlQuery->SetSelection(startPos, endPos); + sqlQuery->ReplaceSelection(fav->GetContents()); + sqlQuery->EndUndoAction(); +} + + +void frmQuery::OnManageFavourites(wxCommandEvent &event) +{ + int r = dlgManageFavourites(this, favourites).ManageFavourites(); + if (r == 1) + { + // Changed something, so save + queryFavouriteFileProvider::SaveFavourites(favourites); + } + if (r == 1 || r == -1) + { + // Changed something requiring rollback + mainForm->UpdateAllFavouritesList(); + } +} + + +void frmQuery::OnSelectFavourite(wxCommandEvent &event) +{ + queryFavouriteItem *fav; + + fav = favourites->FindFavourite(event.GetId()); + if (!fav) + return; + + if (!sqlQuery->GetText().Trim().IsEmpty()) + { + int r = wxMessageDialog(this, _("Replace current query?"), _("Confirm replace"), wxYES_NO | wxCANCEL | wxICON_QUESTION).ShowModal(); + if (r == wxID_CANCEL) + return; + else if (r == wxID_YES) + sqlQuery->ClearAll(); + else + { + if (sqlQuery->GetText().Last() != '\n') + sqlQuery->AddText(wxT("\n")); // Add a newline after the last query + } + } + sqlQuery->AddText(fav->GetContents()); +} + + +bool frmQuery::CheckChanged(bool canVeto) +{ + if (sqlQuery->IsChanged() && settings->GetAskSaveConfirmation()) + { + wxString fn, filename; + filename = sqlQuery->GetFilename(); + if (!filename.IsNull()) + fn = wxString::Format(_("The text in file %s has changed.\nDo you want to save changes?"), filename.c_str()); + else + fn = _("The text has changed.\nDo you want to save changes?"); + wxMessageDialog msg(this, fn, _("Query"), + wxYES_NO | wxICON_EXCLAMATION | + (canVeto ? wxCANCEL : 0)); + + wxCommandEvent noEvent; + switch (msg.ShowModal()) + { + case wxID_YES: + if (filename.IsNull()) + OnSaveAs(noEvent); + else + OnSave(noEvent); + + return sqlQuery->IsChanged(); + + case wxID_CANCEL: + return true; + } + + } + return false; +} + + +void frmQuery::OnClose(wxCloseEvent &event) +{ + if (queryMenu->IsEnabled(MNU_CANCEL)) + { + if (event.CanVeto()) + { + wxMessageDialog msg(this, _("A query is running. Do you wish to cancel it?"), _("Query"), + wxYES_NO | wxNO_DEFAULT | wxICON_EXCLAMATION); + + if (msg.ShowModal() != wxID_YES) + { + event.Veto(); + return; + } + } + + wxCommandEvent ev; + OnCancel(ev); + } + + while (sqlResult->RunStatus() == CTLSQL_RUNNING) + { + wxLogInfo(wxT("SQL Query box: Waiting for query to abort")); + wxSleep(1); + } + + if (m_loadingfile && event.CanVeto()) + { + wxMessageBox(_("The query tool cannot be closed whilst a file is loading."), _("Warning"), wxICON_INFORMATION | wxOK); + event.Veto(); + + return; + } + + if (SqlBookClose(event.CanVeto()) && event.CanVeto()) + { + event.Veto(); + return; + } + + closing = true; + + // Reset the panes + if (viewMenu->IsChecked(MNU_OUTPUTPANE)) + manager.GetPane(wxT("outputPane")).Show(true); + if (viewMenu->IsChecked(MNU_SCRATCHPAD)) + manager.GetPane(wxT("scratchPad")).Show(true); + manager.Update(); + + Hide(); + + sqlResult->Disconnect(wxID_ANY, wxEVT_SET_FOCUS, wxFocusEventHandler(frmQuery::OnFocus)); + msgResult->Disconnect(wxID_ANY, wxEVT_SET_FOCUS, wxFocusEventHandler(frmQuery::OnFocus)); + msgHistory->Disconnect(wxID_ANY, wxEVT_SET_FOCUS, wxFocusEventHandler(frmQuery::OnFocus)); + + controller->nullView(); //to avoid bug on *nix when deleting controller + + settings->SetExplainVerbose(queryMenu->IsChecked(MNU_VERBOSE)); + settings->SetExplainCosts(queryMenu->IsChecked(MNU_COSTS)); + settings->SetExplainBuffers(queryMenu->IsChecked(MNU_BUFFERS)); + settings->SetExplainTiming(queryMenu->IsChecked(MNU_TIMING)); + + sqlResult->Abort(); // to make sure conn is unused + + Destroy(); + +} + + +void frmQuery::OnChangeStc(wxStyledTextEvent &event) +{ + // The STC seems to fire this event even if it loses focus. Fortunately, + // that seems to be m_modificationType == 512. + if (event.m_modificationType != 512 && + // Sometimes there come events 20 and 520 AFTER the initial query was set by constructor. + // Their occurrence is related to query's size and possibly international characters in it (??) + // Filter them out to keep "initial" origin of query text. + (sqlQuery->GetOrigin() != ORIGIN_INITIAL || (event.m_modificationType != 20 && event.m_modificationType != 520))) + { + // This is the default change origin. + // In other cases the changer function will reset it after this event. + sqlQuery->SetOrigin(ORIGIN_MANUAL); + if (!sqlQuery->IsChanged()) + { + sqlQuery->SetChanged(true); + setExtendedTitle(); + SqlBookUpdatePageTitle(); + } + } + // do not allow update of model size of GQB on input (key press) of each + // character of the query in Query Tool + updateMenu(false); +} +void frmQuery::OnLabelRightClick(wxGridEvent &event) +{ + wxMenu *xmenu = new wxMenu(); + wxArrayInt rows = sqlResult->GetSelectedRows(); + xmenu->Append(MNU_COPY, _("&Copy"), _("Copy selected cells to clipboard.")); + xmenu->Append(MNU_PASTE, _("&Paste"), _("Paste data from the clipboard.")); + xmenu->Append(MNU_DELETE, _("&Delete"), _("Delete selected rows.")); + xmenu->Append(MNU_SUMMARY_COL, _("Summary"), _("Summary selected cells.")); + + if ((rows.GetCount())) + { + xmenu->Enable(MNU_COPY, true); + xmenu->Enable(MNU_DELETE, true); + xmenu->Enable(MNU_PASTE, true); + } + else + { + xmenu->Enable(MNU_COPY, false); + xmenu->Enable(MNU_DELETE, false); + xmenu->Enable(MNU_PASTE, false); + } + sqlResult->PopupMenu(xmenu); +} + +void frmQuery::OnSummary_Column(wxCommandEvent &ev) +{ +// if (currentControl() == sqlResult) + { + wxString s=sqlResult->SummaryColumn(); + SetStatusText(s, STATUSPOS_POS); + } +} + +void frmQuery::OnPositionStc(wxStyledTextEvent &event) +{ + int selFrom, selTo, selCount; + sqlQuery->GetSelection(&selFrom, &selTo); + selCount = selTo - selFrom; + + wxString pos; + pos.Printf(_("Ln %d, Col %d, Ch %d"), sqlQuery->LineFromPosition(sqlQuery->GetCurrentPos()) + 1, sqlQuery->GetColumn(sqlQuery->GetCurrentPos()) + 1, sqlQuery->GetCurrentPos() + 1); + SetStatusText(pos, STATUSPOS_POS); + if (selCount < 1) + pos = wxEmptyString; + else + pos.Printf(wxPLURAL("%d char", "%d chars", selCount), selCount); + SetStatusText(pos, STATUSPOS_SEL); +} + + +void frmQuery::OpenLastFile() +{ + wxString str; + bool modeUnicode = settings->GetUnicodeFile(); + wxUtfFile file(lastPath, wxFile::read, modeUnicode ? wxFONTENCODING_UTF8 : wxFONTENCODING_DEFAULT); + + m_loadingfile = true; + if (file.IsOpened()) + file.Read(str); + + if (!str.IsEmpty()) + { + sqlQuery->SetText(str); + sqlQuery->Colourise(0, str.Length()); + sqlQuery->EmptyUndoBuffer(); + wxSafeYield(); // needed to process sqlQuery modify event + sqlQuery->SetFilename(lastPath); + sqlQuery->SetChanged(false); + sqlQuery->SetOrigin(ORIGIN_FILE); + setExtendedTitle(); + SqlBookUpdatePageTitle(); + SetLineEndingStyle(); + UpdateRecentFiles(true); + if(mainForm != NULL) + { + mainForm->UpdateAllRecentFiles(); + } + } + sqlQuery->SetFocus(); + m_loadingfile = false; +} + + +void frmQuery::UpdateAllRecentFiles() +{ + mainForm->UpdateAllRecentFiles(); +} + +void frmQuery::OnNew(wxCommandEvent &event) +{ + frmQuery *fq = new frmQuery(mainForm, wxEmptyString, conn->Duplicate(), wxEmptyString); + if (mainForm) + mainForm->AddFrame(fq); + fq->Go(); +} + + +void frmQuery::OnOpen(wxCommandEvent &event) +{ + if (CheckChanged(true)) + return; + +#ifdef __WXMSW__ + wxFileDialog dlg(this, _("Open query file"), lastDir, wxT(""), + _("Query files (*.sql)|*.sql|pgScript files (*.pgs)|*.pgs|All files (*.*)|*.*"), wxFD_OPEN); +#else + wxFileDialog dlg(this, _("Open query file"), lastDir, wxT(""), + _("Query files (*.sql)|*.sql|pgScript files (*.pgs)|*.pgs|All files (*)|*"), wxFD_OPEN); +#endif + + if (dlg.ShowModal() == wxID_OK) + { + lastFilename = dlg.GetFilename(); + lastDir = dlg.GetDirectory(); + lastPath = dlg.GetPath(); + OpenLastFile(); + } +} + +void frmQuery::SaveTempFile() +{ + bool modeUnicode = settings->GetUnicodeFile(); + wxString filename = sqlQuery->GetFilename(); + if (!filename.IsNull()) + { + return; + } + filename=sqlQuery->GetTitle(false); + wxString pref=conn->GetDbname(); + //if (filename.StartsWith(pref)) + filename+=wxT(".a"); + wxString tempDir=wxStandardPaths::Get().GetTempDir(); + wxUtfFile file(tempDir+wxT("\\")+filename, wxFile::write, modeUnicode ? wxFONTENCODING_UTF8 : wxFONTENCODING_DEFAULT); + if (file.IsOpened()) + { + if ((file.Write(sqlQuery->GetText()) == 0) && (!modeUnicode)) + wxMessageBox(_("Query text incomplete.\nQuery contained characters that could not be converted to the local charset.\nPlease correct the data or try using UTF8 instead.")); + file.Close(); + sqlQuery->SetChanged(false); + SqlBookUpdatePageTitle(); + } + else + { + wxLogError(__("Could not write the file %s: Errcode=%d."), filename.c_str(), wxSysErrorCode()); + } + + +} + +void frmQuery::OnSave(wxCommandEvent &event) +{ + bool modeUnicode = settings->GetUnicodeFile(); + wxString filename = sqlQuery->GetFilename(); + + if (filename.IsNull()) + { + OnSaveAs(event); + return; + } + + wxUtfFile file(filename, wxFile::write, modeUnicode ? wxFONTENCODING_UTF8 : wxFONTENCODING_DEFAULT); + if (file.IsOpened()) + { + if ((file.Write(sqlQuery->GetText()) == 0) && (!modeUnicode)) + wxMessageBox(_("Query text incomplete.\nQuery contained characters that could not be converted to the local charset.\nPlease correct the data or try using UTF8 instead.")); + file.Close(); + sqlQuery->SetChanged(false); + setExtendedTitle(); + UpdateRecentFiles(); + SqlBookUpdatePageTitle(); + } + else + { + wxLogError(__("Could not write the file %s: Errcode=%d."), filename.c_str(), wxSysErrorCode()); + } +} + + +// Set the line ending style based on the current document. +void frmQuery::SetLineEndingStyle() +{ + // Detect the file mode + wxRegEx *reLF = new wxRegEx(wxT("[^\r]\n"), wxRE_NEWLINE); + wxRegEx *reCRLF = new wxRegEx(wxT("\r\n"), wxRE_NEWLINE); + wxRegEx *reCR = new wxRegEx(wxT("\r[^\n]"), wxRE_NEWLINE); + + bool haveLF = reLF->Matches(sqlQuery->GetText()); + bool haveCRLF = reCRLF->Matches(sqlQuery->GetText()); + bool haveCR = reCR->Matches(sqlQuery->GetText()); + int mode = GetLineEndingStyle(); + + if ((haveLF && haveCR) || + (haveLF && haveCRLF) || + (haveCR && haveCRLF)) + { + wxMessageBox(_("This file contains mixed line endings. They will be converted to the current setting."), _("Warning"), wxICON_INFORMATION | wxOK); + sqlQuery->ConvertEOLs(mode); + sqlQuery->SetChanged(true); + setExtendedTitle(); + updateMenu(); + } + else + { + if (haveLF) + mode = wxSTC_EOL_LF; + else if (haveCRLF) + mode = wxSTC_EOL_CRLF; + else if (haveCR) + mode = wxSTC_EOL_CR; + } + + // Now set the status text, menu options, and the mode + sqlQuery->SetEOLMode(mode); + SetEOLModeDisplay(mode); + + delete reCRLF; + delete reCR; + delete reLF; +} + + +// Get the line ending style +int frmQuery::GetLineEndingStyle() +{ + if (lineEndMenu->IsChecked(MNU_LF)) + return wxSTC_EOL_LF; + else if (lineEndMenu->IsChecked(MNU_CRLF)) + return wxSTC_EOL_CRLF; + else if (lineEndMenu->IsChecked(MNU_CR)) + return wxSTC_EOL_CR; + else + return sqlQuery->GetEOLMode(); +} + + +// User-set the current EOL mode for the form +void frmQuery::OnSetEOLMode(wxCommandEvent &event) +{ + int mode = GetLineEndingStyle(); + sqlQuery->ConvertEOLs(mode); + sqlQuery->SetEOLMode(mode); + settings->SetLineEndingType(mode); + + SetEOLModeDisplay(mode); + + if (!sqlQuery->IsChanged()) + { + sqlQuery->SetChanged(true); + setExtendedTitle(); + } + setExtendedTitle(); + + // TODO: Figure out why this is here? + pgScript->SetConnection(conn); +} + + +// Display the EOL mode settings on the form +void frmQuery::SetEOLModeDisplay(int mode) +{ + switch(mode) + { + + case wxSTC_EOL_LF: + lineEndMenu->Check(MNU_LF, true); + SetStatusText(_("Unix"), STATUSPOS_FORMAT); + break; + + case wxSTC_EOL_CRLF: + lineEndMenu->Check(MNU_CRLF, true); + SetStatusText(_("DOS"), STATUSPOS_FORMAT); + break; + + case wxSTC_EOL_CR: + lineEndMenu->Check(MNU_CR, true); + SetStatusText(_("Mac"), STATUSPOS_FORMAT); + break; + + default: + wxLogError(wxT("Someone created a new line ending style! Run, run for your lives!!")); + } +} + + +void frmQuery::OnSaveAs(wxCommandEvent &event) +{ + wxString filename; + filename = sqlQuery->GetFilename(); + if (filename.IsNull()) + filename = lastFilename; + +#ifdef __WXMSW__ + wxFileDialog *dlg = new wxFileDialog(this, _("Save query file as"), lastDir, filename, /*lastFilename,*/ + _("Query files (*.sql)|*.sql|All files (*.*)|*.*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); +#else + wxFileDialog *dlg = new wxFileDialog(this, _("Save query file as"), lastDir, filename, /*lastFilename,*/ + _("Query files (*.sql)|*.sql|All files (*)|*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); +#endif + if (dlg->ShowModal() == wxID_OK) + { + lastFilename = dlg->GetFilename(); + lastDir = dlg->GetDirectory(); + lastPath = dlg->GetPath(); + switch (dlg->GetFilterIndex()) + { + case 0: +#ifdef __WXMAC__ + if (!lastPath.Contains(wxT("."))) + lastPath += wxT(".sql"); +#endif + break; + case 1: +#ifdef __WXMAC__ + if (!lastPath.Contains(wxT("."))) + lastPath += wxT(".sql"); +#endif + break; + default: + break; + } + + lastFileFormat = settings->GetUnicodeFile(); + + wxUtfFile file(lastPath, wxFile::write, lastFileFormat ? wxFONTENCODING_UTF8 : wxFONTENCODING_DEFAULT); + if (file.IsOpened()) + { + if ((file.Write(sqlQuery->GetText()) == 0) && (!lastFileFormat)) + wxMessageBox(_("Query text incomplete.\nQuery contained characters that could not be converted to the local charset.\nPlease correct the data or try using UTF8 instead.")); + file.Close(); + sqlQuery->SetChanged(false); + sqlQuery->SetFilename(lastPath); + + // Forget about Initial origin thus making "Save" button behave as usual + // (be enabled/disabled according to dirty flag only). + if (sqlQuery->GetOrigin() == ORIGIN_INITIAL) + sqlQuery->SetOrigin(ORIGIN_FILE); + + setExtendedTitle(); + SqlBookUpdatePageTitle(); + SetOutputPaneCaption(true); + UpdateRecentFiles(); + fileMenu->Enable(MNU_RECENT, (recentFileMenu->GetMenuItemCount() > 0)); + } + else + { + wxLogError(__("Could not write the file %s: Errcode=%d."), lastPath.c_str(), wxSysErrorCode()); + } + } + delete dlg; +} + + +void frmQuery::OnQuickReport(wxCommandEvent &event) +{ + wxDateTime now = wxDateTime::Now(); + + frmReport *rep = new frmReport(this); + + rep->XmlAddHeaderValue(wxT("generated"), now.Format(wxT("%c"))); + rep->XmlAddHeaderValue(wxT("database"), conn->GetName()); + + rep->SetReportTitle(_("Quick report")); + + int section = rep->XmlCreateSection(_("Query results")); + + rep->XmlAddSectionTableFromGrid(section, sqlResult); + + wxString stats; + stats.Printf(wxT("%ld rows with %d columns retrieved."), sqlResult->NumRows(), sqlResult->GetNumberCols()); + + rep->XmlSetSectionTableInfo(section, stats); + + wxString query = sqlQuery->GetSelectedText(); + if (query.IsNull()) + query = sqlQuery->GetText(); + + rep->XmlSetSectionSql(section, query); + + rep->ShowModal(); +} + + +void frmQuery::OnCancel(wxCommandEvent &event) +{ + toolBar->EnableTool(MNU_CANCEL, false); + queryMenu->Enable(MNU_CANCEL, false); + SetStatusText(_("Cancelling."), STATUSPOS_MSGS); + + if (sqlResult->RunStatus() == CTLSQL_RUNNING) + sqlResult->Abort(); + else if (pgScript->IsRunning()) + pgScript->Terminate(); + + QueryExecInfo *qi = (QueryExecInfo *)event.GetClientData(); + if (qi) + delete qi; + + aborted = true; +} + + +void frmQuery::OnExplain(wxCommandEvent &event) +{ + if(sqlNotebook->GetSelection() == 1) + { + if (!updateFromGqb(true)) + return; + } + + wxString query = sqlQuery->GetSelectedText(); + if (query.IsNull()) + if (queryMenu->IsChecked(MNU_AUTOSELECTQUERY)) { + // Auto-select + SelectQuery(); + query = sqlQuery->GetSelectedText(); + } else query = sqlQuery->GetText(); + + if (query.IsNull()) + return; + wxString sql; + int resultToRetrieve = 1; + bool verbose = queryMenu->IsChecked(MNU_VERBOSE); + bool analyze = event.GetId() == MNU_EXPLAINANALYZE; + + if (analyze) + { + sql += wxT("\nBEGIN;\n"); + resultToRetrieve++; + } + sql += wxT("EXPLAIN "); + if (conn->BackendMinimumVersion(9, 0)) + { + bool costs = queryMenu->IsChecked(MNU_COSTS); + bool buffers = queryMenu->IsChecked(MNU_BUFFERS) && analyze; + bool timing = queryMenu->IsChecked(MNU_TIMING) && analyze; + + sql += wxT("("); + if (analyze) + sql += wxT("ANALYZE on, "); + else + sql += wxT("ANALYZE off, "); + if (verbose) + sql += wxT("VERBOSE on, "); + else + sql += wxT("VERBOSE off, "); + if (costs) + sql += wxT("COSTS on, "); + else + sql += wxT("COSTS off, "); + if (buffers) + sql += wxT("BUFFERS on"); + else + sql += wxT("BUFFERS off"); + if (conn->BackendMinimumVersion(9, 2)) + { + if (timing) + sql += wxT(", TIMING on "); + else + sql += wxT(", TIMING off "); + } + sql += wxT(")"); + } + else + { + if (analyze) + sql += wxT("ANALYZE "); + if (verbose) + sql += wxT("VERBOSE "); + } + + int offset = sql.Length(); + + sql += query; + + if (analyze) + { + // Bizarre bug fix - if we append a rollback directly after -- it'll crash!! + // Add a \n first. + sql += wxT("\n;\nROLLBACK;"); + } + + execQuery(sql, resultToRetrieve, true, offset, false, true, verbose); +} + +void frmQuery::OnCommit(wxCommandEvent &event) +{ + execQuery(wxT("COMMIT;")); +} + +void frmQuery::OnRollback(wxCommandEvent &event) +{ + execQuery(wxT("ROLLBACK;")); +} + +// Update the main SQL query from the GQB if desired +bool frmQuery::updateFromGqb(bool executing) +{ + if (closing) + return false; + + // Make sure this doesn't get call recursively through an event + if (gqbUpdateRunning) + return false; + updateMenu(); + + gqbUpdateRunning = true; + + // Execute Generation of SQL sentence from GQB + bool canGenerate = false; + wxString newQuery = controller->generateSQL(); + + // If the new query is empty, don't do anything + if (newQuery.IsEmpty()) + { + if (controller->getTableCount() > 0) + { + wxMessageBox(_("No SQL query was generated."), _("Graphical Query Builder"), wxICON_INFORMATION | wxOK); + } + gqbUpdateRunning = false; + return false; + } + + // Only prompt the user if the dirty flag is set, and last modification wasn't from GQB, + // and the textbox is not empty, and the new query is different. + if (sqlQuery->IsChanged() && sqlQuery->GetOrigin() != ORIGIN_GQB && + !sqlQuery->GetText().Trim().IsEmpty() && sqlQuery->GetText() != newQuery + wxT("\n")) + { + wxString fn; + if (executing) + fn = _("The generated SQL query has changed.\nDo you want to update it and execute the query?"); + else + fn = _("The generated SQL query has changed.\nDo you want to update it?"); + + wxMessageDialog msg(this, fn, _("Query"), wxYES_NO | wxICON_EXCLAMATION); + if(msg.ShowModal() == wxID_YES && sqlQuery->IsChanged()) + { + canGenerate = true; + } + else + { + gqbUpdateRunning = false; + } + } + else + { + canGenerate = true; + } + + if(canGenerate) + { + sqlQuery->SetText(newQuery + wxT("\n")); + sqlQuery->Colourise(0, sqlQuery->GetText().Length()); + wxSafeYield(); // needed to process sqlQuery modify event + sqlNotebook->SetSelection(0); + sqlQuery->SetChanged(true); + sqlQuery->SetOrigin(ORIGIN_GQB); + setExtendedTitle(); + + gqbUpdateRunning = false; + return true; + } + + return false; +} +void frmQuery::SelectQuery() { + long p; + bool selected = false; + //sqlQuery->GetSelection(); + wxString name = sqlQuery->GetSelectedText(); + wxString *q=new wxString[30]; + int s,e,i=0; + if (!name.IsEmpty()) + { + // get the word under cursor: + int endDoc = sqlQuery->GetLength(); + int endPos = sqlQuery->GetSelectionEnd(); + int startPos = sqlQuery->GetSelectionStart(); + while(endPosSelectQuery(startPos); + s=p>>16; + e=p & 65535; + q[i++]=sqlQuery->GetTextRange(s, e); + startPos=e+1; + } + querys=new wxString[i]; + for (int j = 0; j < i; j++) { + querys[j]=q[j]; + } + //name = sqlQuery->GetTextRange(startPos, endPos); + //selected = false; + } else { + int curPos = sqlQuery->GetCurrentPos(); + p=sqlQuery->SelectQuery(curPos); + s=p>>16; + e=p & 65535; + querys=new wxString[1]; + querys[0]=sqlQuery->GetTextRange(s, e); + // + sqlQuery->SetSelection(s,e); + } + delete [] q; + +} +void frmQuery::OnExecute(wxCommandEvent &event) +{ + if(sqlNotebook->GetSelection() == 1) + { + if (!updateFromGqb(true)) + return; + } + SaveTempFile(); + wxString query = sqlQuery->GetSelectedText(); + if (query.IsNull()) + if (queryMenu->IsChecked(MNU_AUTOSELECTQUERY)) { + // Auto-select + SelectQuery(); + //query = sqlQuery->GetSelectedText(); + query = querys[0]; + } else query = sqlQuery->GetText(); + + if (query.IsNull()) + return; + + execQuery(query); + sqlQuery->SetFocus(); +} + + +void frmQuery::OnExecScript(wxCommandEvent &event) +{ + // Get the script + wxString query = sqlQuery->GetSelectedText(); + if (query.IsNull()) + query = sqlQuery->GetText(); + if (query.IsNull()) + return; + + // Make sure pgScript is not already running + // Required because the pgScript parser isn't currently thread-safe :-( + if (frmQuery::ms_pgScriptRunning == true) + { + wxMessageBox(_("pgScript already running."), _("Concurrent execution of pgScripts is not supported at this time."), wxICON_WARNING | wxOK); + return; + } + frmQuery::ms_pgScriptRunning = true; + + // Clear markers and indicators + sqlQuery->MarkerDeleteAll(0); + sqlQuery->StartStyling(0, wxSTC_INDICS_MASK); + sqlQuery->SetStyling(sqlQuery->GetText().Length(), 0); + + // Menu stuff to initialize + setTools(true); + queryMenu->Enable(MNU_SAVEHISTORY, true); + queryMenu->Enable(MNU_CLEARHISTORY, true); + + // Window stuff + explainCanvas->Clear(); + msgResult->Clear(); + msgResult->SetFont(settings->GetSQLFont()); + outputPane->SetSelection(2); + + // Status text + SetStatusText(wxT(""), STATUSPOS_SECS); + SetStatusText(_("pgScript is running."), STATUSPOS_MSGS); + SetStatusText(wxT(""), STATUSPOS_ROWS); + + // History + msgHistory->AppendText(_("-- Executing pgScript\n")); + Update(); + wxTheApp->Yield(true); + + // Timer + startTimeQuery = wxGetLocalTimeMillis(); + timer.Start(10); + + // Delete previous variables + pgScript->ClearSymbols(); + + // Parse script. Note that we add \n so the parse can correctly identify + // a comment on the last line of the query. + pgScript->ParseString(query + wxT("\n"), pgsOutput); + pgsTimer->Start(20); + aborted = false; +} + + + +void frmQuery::OnExecFile(wxCommandEvent &event) +{ + if(sqlNotebook->GetSelection() == 1) + { + if (!updateFromGqb(true)) + return; + } + + wxString query = sqlQuery->GetSelectedText(); + if (query.IsNull()) + query = sqlQuery->GetText(); + + if (query.IsNull()) + return; + + execQuery(query, 0, false, 0, true); + sqlQuery->SetFocus(); +} +void frmQuery::OnAutoReplaceManage(wxCommandEvent &event) +{ + //if (autoreplace) delete + //macros = queryMacroFileProvider::LoadMacros(true); + int r = dlgManageMacros(this, mainForm, autoreplace).ManageMacros(); + if (r == 1) + { + // Changed something, so save + queryMacroFileProvider::SaveAutoReplace(autoreplace); + } + +} + +void frmQuery::OnMacroManage(wxCommandEvent &event) +{ + int r = dlgManageMacros(this, mainForm, macros).ManageMacros(); + if (r == 1) + { + // Changed something, so save + queryMacroFileProvider::SaveMacros(macros); + } + if (r == -1 || r == 1) + { + // Changed something requiring rollback + mainForm->UpdateAllMacrosList(); + } + +} + + +void frmQuery::OnMacroInvoke(wxCommandEvent &event) +{ + queryMacroItem *mac; + + mac = macros->FindMacro(event.GetId()); + if (!mac) + return; + + wxString query = mac->GetQuery(); + if (query.IsEmpty()) + return; // do not execute empty query + + if (query.Find(wxT("$SELECTION$")) != wxNOT_FOUND) + { + wxString selection = sqlQuery->GetSelectedText(); + if (selection.IsEmpty()) + { + wxMessageBox(_("This macro includes a text substitution. Please select some text in the SQL pane and re-run the macro."), _("Execute macro"), wxICON_EXCLAMATION | wxOK); + return; + } + query.Replace(wxT("$SELECTION$"), selection); + } + + execQuery(query); + sqlQuery->SetFocus(); +} + + +void frmQuery::setTools(const bool running) +{ + bool canEndTransaction = (!running && conn->GetTxStatus() != PQTRANS_IDLE); + + toolBar->EnableTool(MNU_EXECUTE, !running); + toolBar->EnableTool(MNU_EXECPGS, !running); + toolBar->EnableTool(MNU_EXECFILE, !running); + toolBar->EnableTool(MNU_EXPLAIN, !running); + toolBar->EnableTool(MNU_CANCEL, running); + toolBar->EnableTool(MNU_DOCOMMIT, canEndTransaction); + toolBar->EnableTool(MNU_DOROLLBACK, canEndTransaction); + queryMenu->Enable(MNU_EXECUTE, !running); + queryMenu->Enable(MNU_EXECPGS, !running); + queryMenu->Enable(MNU_EXECFILE, !running); + queryMenu->Enable(MNU_EXPLAIN, !running); + queryMenu->Enable(MNU_EXPLAINANALYZE, !running); + queryMenu->Enable(MNU_CANCEL, running); + queryMenu->Enable(MNU_DOCOMMIT, canEndTransaction); + queryMenu->Enable(MNU_DOROLLBACK, canEndTransaction); + fileMenu->Enable(MNU_EXPORT, sqlResult->CanExport()); + fileMenu->Enable(MNU_QUICKREPORT, sqlResult->CanExport()); + fileMenu->Enable(MNU_RECENT, (recentFileMenu->GetMenuItemCount() > 0)); + sqlQuery->EnableAutoComp(running); +} + + +void frmQuery::showMessage(const wxString &msg, const wxString &msgShort) +{ + msgResult->AppendText(msg + wxT("\n")); + msgHistory->AppendText(msg + wxT("\n")); + wxString str; + if (msgShort.IsNull()) + str = msg; + else + str = msgShort; + str.Replace(wxT("\n"), wxT(" ")); + SetStatusText(str, STATUSPOS_MSGS); +} + + +void frmQuery::execQuery(const wxString &query, int resultToRetrieve, bool singleResult, const int queryOffset, bool toFile, bool explain, bool verbose) +{ + setTools(true); + queryMenu->Enable(MNU_SAVEHISTORY, true); + queryMenu->Enable(MNU_CLEARHISTORY, true); + + explainCanvas->Clear(); + + // Clear markers and indicators + sqlQuery->MarkerDeleteAll(0); + sqlQuery->StartStyling(0, wxSTC_INDICS_MASK); + sqlQuery->SetStyling(sqlQuery->GetText().Length(), 0); + + if (!sqlQuery->IsChanged()) + setExtendedTitle(); + + aborted = false; + + QueryExecInfo *qi = new QueryExecInfo(); + qi->queryOffset = queryOffset; + qi->toFileExportForm = NULL; + qi->singleResult = singleResult; + qi->explain = explain; + qi->verbose = verbose; + + if (toFile) + { + qi->toFileExportForm = new frmExport(this); + if (qi->toFileExportForm->ShowModal() != wxID_OK) + { + delete qi; + setTools(false); + aborted = true; + return; + } + } + + // Remember the tab from which execute was called. By the time query completes, SQL tab selection may change. + sqlQueryExec = sqlQuery; + // Because the output pane is clear during query execution, we clear the result source title on Output Pane. + sqlQueryExecLast = NULL; + SetOutputPaneCaption(true); + + // We must do this lot before the query starts, otherwise + // it might not happen once the main thread gets busy with + // other stuff. + SetStatusText(wxT(""), STATUSPOS_SECS); + SetStatusText(_("Query is running."), STATUSPOS_MSGS); + SetStatusText(wxT(""), STATUSPOS_ROWS); + msgResult->Clear(); + msgResult->SetFont(settings->GetSQLFont()); + + msgHistory->AppendText(wxString::Format(_("-- Executing query [%s]:\n"), sqlQueryExec->GetTitle(false).c_str())); + msgHistory->AppendText(query); + msgHistory->AppendText(wxT("\n")); + Update(); + wxTheApp->Yield(true); + + startTimeQuery = wxGetLocalTimeMillis(); + timer.Start(10); + + if (!queryMenu->IsChecked(MNU_AUTOCOMMIT) && conn->GetTxStatus() == PQTRANS_IDLE && !isBeginNotRequired(query)) + conn->ExecuteVoid(wxT("BEGIN;")); + + if (sqlResult->Execute(query, resultToRetrieve, this, QUERY_COMPLETE, qi) >= 0) + { + // Return and wait for the result + return; + } + + completeQuery(false, false, false); +} + +bool frmQuery::isBeginNotRequired(wxString query) +{ + int wordlen = 0; + + query = query.Trim(false); + size_t queryLen = query.Len(); + + /* + * Check word length (since "beginx" is not "begin"). + */ + while((size_t)wordlen < queryLen && wxIsalpha(query.GetChar(wordlen))) + wordlen++; + + /* + * Transaction control commands. These should include every keyword that + * gives rise to a TransactionStmt in the backend grammar, except for the + * savepoint-related commands. + * + * (We assume that START must be START TRANSACTION, since there is + * presently no other "START foo" command.) + */ + wxString keyword = query.SubString(0, wordlen - 1); + + if (wordlen == 5 && keyword.CmpNoCase(wxT("abort")) == 0) + return true; + if (wordlen == 5 && keyword.CmpNoCase(wxT("begin")) == 0) + return true; + if (wordlen == 5 && keyword.CmpNoCase(wxT("start")) == 0) + return true; + if (wordlen == 6 && keyword.CmpNoCase(wxT("commit")) == 0) + return true; + if (wordlen == 3 && keyword.CmpNoCase(wxT("end")) == 0) + return true; + if (wordlen == 8 && keyword.CmpNoCase(wxT("rollback")) == 0) + return true; + if (wordlen == 7 && keyword.CmpNoCase(wxT("prepare")) == 0) + { + /* PREPARE TRANSACTION is a TC command, PREPARE foo is not */ + query = query.SubString(wordlen, queryLen - 1); + query = query.Trim(false); + queryLen = query.Len(); + wordlen = 0; + + while((size_t)wordlen < queryLen && wxIsalpha(query.GetChar(wordlen))) + wordlen++; + keyword = query.SubString(0, wordlen - 1); + + if (wordlen == 11 && keyword.CmpNoCase(wxT("transaction")) == 0) + return true; + return false; + } + + /* + * Commands not allowed within transactions. The statements checked for + * here should be exactly those that call PreventTransactionChain() in the + * backend. + */ + if (wordlen == 6 && keyword.CmpNoCase(wxT("vacuum")) == 0) + return true; + if (wordlen == 7 && keyword.CmpNoCase(wxT("cluster")) == 0) + { + /* CLUSTER with any arguments is allowed in transactions */ + query = query.SubString(wordlen, queryLen - 1); + query = query.Trim(false); + queryLen = query.Len(); + + if(wxIsalpha(((wxChar)query.at(0)))) + return false; /* has additional words */ + return true; /* it's CLUSTER without arguments */ + } + + if (wordlen == 6 && keyword.CmpNoCase(wxT("create")) == 0) + { + query = query.SubString(wordlen, queryLen - 1); + query = query.Trim(false); + queryLen = query.Len(); + wordlen = 0; + + while((size_t)wordlen < queryLen && wxIsalpha(query.GetChar(wordlen))) + wordlen++; + + keyword = query.SubString(0, wordlen - 1); + + if (wordlen == 8 && keyword.CmpNoCase(wxT("database")) == 0) + return true; + if (wordlen == 10 && keyword.CmpNoCase(wxT("tablespace")) == 0) + return true; + + /* CREATE [UNIQUE] INDEX CONCURRENTLY isn't allowed in xacts */ + if (wordlen == 6 && keyword.CmpNoCase(wxT("cluster")) == 0) + { + query = query.SubString(wordlen, queryLen - 1); + query = query.Trim(false); + queryLen = query.Len(); + wordlen = 0; + + while((size_t)wordlen < queryLen && wxIsalpha(query.GetChar(wordlen))) + wordlen++; + keyword = query.SubString(0, wordlen - 1); + } + + if (wordlen == 5 && keyword.CmpNoCase(wxT("index")) == 0) + { + query = query.SubString(wordlen, queryLen - 1); + query = query.Trim(false); + queryLen = query.Len(); + wordlen = 0; + + while((size_t)wordlen < queryLen && wxIsalpha(query.GetChar(wordlen))) + wordlen++; + keyword = query.SubString(0, wordlen - 1); + + if (wordlen == 12 && keyword.CmpNoCase(wxT("concurrently")) == 0) + return true; + } + + return false; + } + + if (wordlen == 5 && keyword.CmpNoCase(wxT("alter")) == 0) + { + query = query.SubString(wordlen, queryLen - 1); + query = query.Trim(false); + queryLen = query.Len(); + wordlen = 0; + + while((size_t)wordlen < queryLen && wxIsalpha(query.GetChar(wordlen))) + wordlen++; + keyword = query.SubString(0, wordlen - 1); + + /* ALTER SYSTEM isn't allowed in xacts */ + if (wordlen == 6 && keyword.CmpNoCase(wxT("system")) == 0) + return true; + + return false; + } + + /* + * Note: these tests will match DROP SYSTEM and REINDEX TABLESPACE, which + * aren't really valid commands so we don't care much. The other four + * possible matches are correct. + */ + if ((wordlen == 4 && keyword.CmpNoCase(wxT("drop")) == 0) || + (wordlen == 7 && keyword.CmpNoCase(wxT("reindex")) == 0)) + { + query = query.SubString(wordlen , queryLen - 1); + query = query.Trim(false); + queryLen = query.Len(); + wordlen = 0; + + while((size_t)wordlen < queryLen && wxIsalpha(query.GetChar(wordlen))) + wordlen++; + keyword = query.SubString(0, wordlen - 1); + + if (wordlen == 8 && keyword.CmpNoCase(wxT("database")) == 0) + return true; + if (wordlen == 6 && keyword.CmpNoCase(wxT("system")) == 0) + return true; + if (wordlen == 10 && keyword.CmpNoCase(wxT("tablespace")) == 0) + return true; + return false; + } + + /* DISCARD ALL isn't allowed in xacts, but other variants are allowed. */ + if (wordlen == 7 && keyword.CmpNoCase(wxT("discard")) == 0) + { + query = query.SubString(wordlen, queryLen - 1); + query = query.Trim(false); + queryLen = query.Len(); + wordlen = 0; + + while((size_t)wordlen < queryLen && wxIsalpha(query.GetChar(wordlen))) + wordlen++; + keyword = query.SubString(0, wordlen - 1); + + if (wordlen == 3 && keyword.CmpNoCase(wxT("all")) == 0) + return true; + return false; + } + + return false; +} + +// When the query completes, it raises an event which we process here. +void frmQuery::OnQueryComplete(pgQueryResultEvent &ev) +{ + QueryExecInfo *qi = (QueryExecInfo *)ev.GetClientData(); + + bool done = false; + + while (sqlResult->RunStatus() == CTLSQL_RUNNING) + { + wxTheApp->Yield(true); + } + + while (pgScript->IsRunning()) + { + wxLogInfo(wxT("SQL Query box: Waiting for script to abort")); + wxSleep(1); + } + + timer.Stop(); + + wxString str; + str = sqlResult->GetMessagesAndClear(); + //if (!str.IsEmpty()) + //{ + // wxString msg; + // msgHistory->AppendText(str + wxT("\n")); + // wxRegEx multilf(wxT("(CONTEXT:.*$)")); + // multilf.ReplaceAll(&str, wxT("")); + // + //} + + msgResult->AppendText(str); + msgHistory->AppendText(str); + + elapsedQuery = wxGetLocalTimeMillis() - startTimeQuery; + SetStatusText(ElapsedTimeToStr(elapsedQuery), STATUSPOS_SECS); + + if (sqlResult->RunStatus() != PGRES_TUPLES_OK) + { + outputPane->SetSelection(2); + if (sqlResult->RunStatus() == PGRES_COMMAND_OK) + { + done = true; + + int insertedCount = sqlResult->InsertedCount(); + OID insertedOid = sqlResult->InsertedOid(); + if (insertedCount < 0) + { + showMessage( + wxString::Format( + _("Query returned successfully with no result in %s."), + ElapsedTimeToStr(elapsedQuery).c_str() + ), + _("OK.") + ); + } + else if (insertedCount == 1) + { + if (insertedOid) + { + showMessage( + wxString::Format( + _("Query returned successfully: one row with OID %ld inserted, %s execution time."), + (long)insertedOid, + ElapsedTimeToStr(elapsedQuery).c_str()), + wxString::Format( + _("One row with OID %ld inserted."), + (long)insertedOid + ) + ); + } + else + { + showMessage( + wxString::Format( + _("Query returned successfully: one row affected, %s execution time."), + ElapsedTimeToStr(elapsedQuery).c_str()), + wxString::Format(_("One row affected.")) + ); + } + } + else + { + showMessage( + wxString::Format( + _("Query returned successfully: %d rows affected, %s execution time."), + insertedCount, + ElapsedTimeToStr(elapsedQuery).c_str() + ), + wxString::Format( + _("%d rows affected."), insertedCount + ) + ); + } + } + else if (sqlResult->RunStatus() == PGRES_EMPTY_QUERY) + { + showMessage(_("Empty query, no results.")); + } + else if (ev.GetInt() == pgQueryResultEvent::PGQ_EXECUTION_CANCELLED) + { + showMessage(_("Execution Cancelled!")); + } + else + { + wxString errMsg, errMsg2; + long errPos; + + pgError err = sqlResult->GetResultError(); + errMsg = err.formatted_msg; + wxLogQuietError(wxT("%s"), conn->GetLastError().Trim().c_str()); + err.statement_pos.ToLong(&errPos); + + if (err.sql_state.IsEmpty()) + { + if (wxMessageBox(_("Do you want to attempt to reconnect to the database?"), + wxString::Format(_("Connection to database %s lost."), conn->GetDbname().c_str()), + wxICON_EXCLAMATION | wxYES_NO) == wxYES) + { + conn->Reset(); + errMsg2 = _("Connection reset."); + } + } + + showMessage(wxString::Format(wxT("********** %s **********\n"), _("Error"))); + showMessage(errMsg); + if (!errMsg2.IsEmpty()) + showMessage(errMsg2); + + if (errPos > 0 && sqlQueryExec != NULL) + { + int selStart = sqlQueryExec->GetSelectionStart(), selEnd = sqlQueryExec->GetSelectionEnd(); + if (selStart == selEnd) + selStart = 0; + + errPos -= qi->queryOffset; // do not count EXPLAIN or similar + + // Set an indicator on the error word (break on any kind of bracket, a space or full stop) + int sPos = errPos + selStart - 1, wEnd = 1; + sqlQueryExec->StartStyling(sPos, wxSTC_INDICS_MASK); + int c = sqlQueryExec->GetCharAt(sPos + wEnd); + size_t len = sqlQueryExec->GetText().Length(); + while(c != ' ' && c != '(' && c != '{' && c != '[' && c != '.' && + (unsigned int)(sPos + wEnd) < len) + { + wEnd++; + c = sqlQueryExec->GetCharAt(sPos + wEnd); + } + sqlQueryExec->SetStyling(wEnd, wxSTC_INDIC0_MASK); + + int line = 0, maxLine = sqlQueryExec->GetLineCount(); + while (line < maxLine && sqlQueryExec->GetLineEndPosition(line) < errPos + selStart + 1) + line++; + if (line < maxLine) + { + sqlQueryExec->GotoPos(sPos); + sqlQueryExec->MarkerAdd(line, 0); + + if (!sqlQueryExec->IsChanged()) + setExtendedTitle(); + + sqlQueryExec->EnsureVisible(line); + } + } + } + } + else + { + done = true; + outputPane->SetSelection(0); + long rowsTotal = sqlResult->NumRows(); + + if (qi->toFileExportForm) + { + SetStatusText(wxString::Format(wxPLURAL("%d row.", "%d rows.", rowsTotal), rowsTotal), STATUSPOS_ROWS); + + if (rowsTotal) + { + SetStatusText(_("Writing data."), STATUSPOS_MSGS); + + toolBar->EnableTool(MNU_CANCEL, false); + queryMenu->Enable(MNU_CANCEL, false); + SetCursor(*wxHOURGLASS_CURSOR); + + if (sqlResult->ToFile(qi->toFileExportForm)) + SetStatusText(_("Data written to file."), STATUSPOS_MSGS); + else + SetStatusText(_("Data export aborted."), STATUSPOS_MSGS); + SetCursor(wxNullCursor); + } + else + SetStatusText(_("No data to export."), STATUSPOS_MSGS); + } + else + { + if (qi->singleResult) + { + sqlResult->DisplayData(true); + + showMessage(wxString::Format( + wxPLURAL("%ld row retrieved.", "%ld rows retrieved.", + sqlResult->NumRows()), sqlResult->NumRows()), + _("OK.")); + } + else + { + SetStatusText( + wxString::Format( + wxPLURAL( + "Retrieving data: %d row.", + "Retrieving data: %d rows.", + (int)rowsTotal), (int)rowsTotal), + STATUSPOS_MSGS); + wxTheApp->Yield(true); + + sqlResult->DisplayData(); + + SetStatusText( + ElapsedTimeToStr(elapsedQuery), + STATUSPOS_SECS + ); + + str = wxString::Format( + _("Total query runtime: %s\n"), + ElapsedTimeToStr(elapsedQuery).c_str() + ); + msgResult->AppendText(str); + msgHistory->AppendText(str); + + showMessage( + wxString::Format( + wxPLURAL( + "%d row retrieved.", + "%d rows retrieved.", + (int)sqlResult->NumRows() + ), + (int)sqlResult->NumRows() + ), + _("OK.") + ); + } + SetStatusText( + wxString::Format( + wxPLURAL( + "%ld row.", + "%ld rows.", + rowsTotal + ), + rowsTotal + ), + STATUSPOS_ROWS + ); + } + } + + if (sqlResult->RunStatus() == PGRES_TUPLES_OK || sqlResult->RunStatus() == PGRES_COMMAND_OK) + { + // Get the executed query + wxString executedQuery = sqlQueryExec->GetSelectedText(); + if (executedQuery.IsNull()) + executedQuery = sqlQueryExec->GetText(); + + // Same query, but without return feeds and carriage returns + wxString executedQueryWithoutReturns = executedQuery; + executedQueryWithoutReturns.Replace(wxT("\n"), wxT(" ")); + executedQueryWithoutReturns.Replace(wxT("\r"), wxT(" ")); + executedQueryWithoutReturns = executedQueryWithoutReturns.Trim(); + + if (executedQuery.Len() < (unsigned int)settings->GetHistoryMaxQuerySize()) + { + // We put in the combo box the query without returns... + sqlQueries->Append(executedQueryWithoutReturns); + + // .. but we save the query with returns in the array + // (so that we have the real query in the file) + histoQueries.Add(executedQuery); + + // Finally, we save the queries + SaveQueries(); + } + + // Search a matching old query + unsigned int index = 0; + bool found = false; + while (!found && index < sqlQueries->GetCount()) + { + found = sqlQueries->GetString(index) == executedQueryWithoutReturns; + if (!found) + index++; + } + + // If we found one, delete it from the combobox and the array + if (found && index < (unsigned int)sqlQueries->GetCount() - 1) + { + histoQueries.RemoveAt(index); + sqlQueries->Delete(index); + } + } + + // Make sure only the maximum query number is enforced + while (sqlQueries->GetCount() > (unsigned int)settings->GetHistoryMaxQueries()) + { + histoQueries.RemoveAt(0); + sqlQueries->Delete(0); + } + + SaveQueries(); + + completeQuery(done, qi->explain, qi->verbose); + delete qi; +} + + +void frmQuery::OnScriptComplete(wxCommandEvent &ev) +{ + // Stop timers + timer.Stop(); + pgsTimer->Stop(); + + // Write output + writeScriptOutput(); + + // Reset tools + setTools(false); + + // Unlock our pseudo-mutex thingy + frmQuery::ms_pgScriptRunning = false; + + // Manage timer + elapsedQuery = wxGetLocalTimeMillis() - startTimeQuery; + wxString fmtExecTime = ElapsedTimeToStr(elapsedQuery); + SetStatusText(fmtExecTime, STATUSPOS_SECS); + SetStatusText(_("pgScript completed."), STATUSPOS_MSGS); + msgHistory->AppendText( + wxString::Format( + _("Total pgScript runtime: %s\n\n"), + fmtExecTime.c_str() + ) + ); + // Check whether there was an error/exception + if (pgScript->errorOccurred() && pgScript->errorLine() >= 1) + { + // Find out what the line number is + int selStart = sqlQuery->GetSelectionStart(), selEnd = sqlQuery->GetSelectionEnd(); + if (selStart == selEnd) + selStart = 0; + int line = 0, maxLine = sqlQuery->GetLineCount(); + while (line < maxLine && sqlQuery->GetLineEndPosition(line) < selStart) + line++; + line += pgScript->errorLine() - 1; + + // Mark the line where the error occurred + sqlQuery->MarkerAdd(line, 0); + + // Go to that line + sqlQuery->GotoPos(sqlQuery->GetLineEndPosition(line)); + } +} + +void frmQuery::writeScriptOutput() +{ + pgScript->LockOutput(); + + wxString output(pgsOutputString); + pgsOutputString.Clear(); + msgResult->AppendText(output); + + pgScript->UnlockOutput(); +} + +// Complete the processing of a query +void frmQuery::completeQuery(bool done, bool explain, bool verbose) +{ + // Display async notifications + pgNotification *notify; + int notifies = 0; + notify = conn->GetNotification(); + while (notify) + { + wxString notifyStr; + notifies++; + + if (notify->data.IsEmpty()) + notifyStr.Printf(_("\nAsynchronous notification of '%s' received from backend pid %d"), notify->name.c_str(), notify->pid); + else + notifyStr.Printf(_("\nAsynchronous notification of '%s' received from backend pid %d\n Data: %s"), notify->name.c_str(), notify->pid, notify->data.c_str()); + + msgResult->AppendText(notifyStr); + msgHistory->AppendText(notifyStr); + + notify = conn->GetNotification(); + } + + if (notifies) + { + wxString statusMsg = statusBar->GetStatusText(STATUSPOS_MSGS); + if (statusMsg.Last() == '.') + statusMsg = statusMsg.Left(statusMsg.Length() - 1); + + SetStatusText(wxString::Format( + wxPLURAL("%s (%d asynchronous notification received).", "%s (%d asynchronous notifications received).", notifies), + statusMsg.c_str(), notifies), STATUSPOS_MSGS); + } + + msgResult->AppendText(wxT("\n")); + msgResult->ShowPosition(0); + msgHistory->AppendText(wxT("\n")); + msgHistory->ShowPosition(0); + + // If the transaction aborted for some reason, issue a rollback to cleanup. + if (queryMenu->IsChecked(MNU_AUTOROLLBACK) && conn->GetTxStatus() == PGCONN_TXSTATUS_INERROR) + conn->ExecuteVoid(wxT("ROLLBACK;")); + + setTools(false); + fileMenu->Enable(MNU_EXPORT, sqlResult->CanExport()); + + if (!IsActive() || IsIconized()) + RequestUserAttention(); + + if (!viewMenu->IsChecked(MNU_OUTPUTPANE)) + { + viewMenu->Check(MNU_OUTPUTPANE, true); + manager.GetPane(wxT("outputPane")).Show(true); + manager.Update(); + } + + // If this was an EXPLAIN query, process the results + if (done && explain) + { + if (!verbose || conn->BackendMinimumVersion(8, 4)) + { + int i; + wxString str; + if (sqlResult->NumRows() == 1) + { + // Avoid shared storage issues with strings + str.Append(sqlResult->OnGetItemText(0, 0).c_str()); + } + else + { + for (i = 0 ; i < sqlResult->NumRows() ; i++) + { + if (i) + str.Append(wxT("\n")); + str.Append(sqlResult->OnGetItemText(i, 0)); + } + } + explainCanvas->SetExplainString(str); + outputPane->SetSelection(1); + } + updateMenu(); + } + + // Change the output pane caption so the user knows which tab the result came from + sqlQueryExecLast = sqlQueryExec; + SetOutputPaneCaption(true); + + sqlQueryExec = NULL; + sqlQuery->SetFocus(); +} + + +void frmQuery::OnTimer(wxTimerEvent &event) +{ + elapsedQuery = wxGetLocalTimeMillis() - startTimeQuery; + SetStatusText(ElapsedTimeToStr(elapsedQuery), STATUSPOS_SECS); + + wxString str = sqlResult->GetMessagesAndClear(); + if (!str.IsEmpty()) + { + // wxString msg; + // msgHistory->AppendText(str + wxT("\n")); + // wxRegEx multilf(wxT("(CONTEXT:.*$)")); + // multilf.ReplaceAll(&str, wxT("")); + // msgResult->AppendText(str + wxT("\n")); + // + msgHistory->AppendText(str + wxT("\n")); + msgResult->AppendText(str + wxT("\n")); + } + + // Increase the granularity for longer running queries + if (timer.IsRunning()) + { + // Set timer to fire every 100 ms if >200 ms elapsed + if (elapsedQuery > 200 && timer.GetInterval() < 100) + { + timer.Stop(); + timer.Start(100); + } + // Set timer to fire every 1000 ms if >60 seconds elapsed + else if (elapsedQuery > 60 * 1000 && timer.GetInterval() < 1000) + { + timer.Stop(); + timer.Start(1000); + } + } +} + + +// Adjust sizes of GQB components, Located here because need to +// avoid some issues when implementing inside controller/view Classes +void frmQuery::adjustGQBSizes() +{ + // Get Size (only height) from main Tab with GQB and SQL Editor and adjust the width + // to desiree, then set [Sash of tablesBrowser | GQB_Canvas] + manager.Update(); + sqlNotebook->Refresh(); + wxSize s = sqlNotebook->GetSize(); + s.SetWidth(200); + s.SetHeight(s.GetHeight() - 180); //re-adjust weight eliminating Horz Sash Position + controller->getTablesBrowser()->SetSize(s); + controller->setSashVertPosition(controller->getTablesBrowser()->GetSize().GetWidth()); + + // Now Adjust Sash Horizontal + s = sqlNotebook->GetSize(); + controller->setSashHorizPosition(s.GetHeight() - 150); + + // Adjust GQB grids internal columns sizes + controller->calcGridColsSizes(); +} + + +// Adjust sizes of GQB components after vertical sash adjustment, +// Located here because need to avoid some issues when implementing +// inside controller/view Classes +void frmQuery::OnResizeHorizontally(wxSplitterEvent &event) +{ + int y = event.GetSashPosition(); + wxSize s = controller->getTablesBrowser()->GetSize(); + s.SetHeight(y); // re-adjust weight eliminating Horz Sash Position + controller->getTablesBrowser()->SetSize(s); +} + + + +// This function adjust the GQB Components after an event on the wxAui +// event, it's a workaround because need event finish to work properly +void frmQuery::OnAdjustSizesTimer(wxTimerEvent &event) +{ + adjustGQBSizes(); + adjustSizesTimer->Stop(); +} + +void frmQuery::OnBlockIndent(wxCommandEvent &event) +{ + if (FindFocus()->GetId() == CTL_SQLQUERY) + sqlQuery->CmdKeyExecute(wxSTC_CMD_TAB); + else if (FindFocus()->GetId() == CTL_SCRATCHPAD) + scratchPad->WriteText(wxT("\t")); +} + +void frmQuery::OnBlockOutDent(wxCommandEvent &event) +{ + if (FindFocus()->GetId() == CTL_SQLQUERY) + sqlQuery->CmdKeyExecute(wxSTC_CMD_BACKTAB); +} + +void frmQuery::OnChangeToUpperCase(wxCommandEvent &event) +{ + if (FindFocus()->GetId() == CTL_SQLQUERY) + sqlQuery->UpperCase(); +} + +void frmQuery::OnChangeToLowerCase(wxCommandEvent &event) +{ + if (FindFocus()->GetId() == CTL_SQLQUERY) + sqlQuery->LowerCase(); +} + +void frmQuery::OnCommentText(wxCommandEvent &event) +{ + if (FindFocus()->GetId() == CTL_SQLQUERY) + sqlQuery->BlockComment(false); +} + +void frmQuery::OnUncommentText(wxCommandEvent &event) +{ + if (FindFocus()->GetId() == CTL_SQLQUERY) + sqlQuery->BlockComment(true); +} + +void frmQuery::OnExternalFormat(wxCommandEvent &event) +{ + if (FindFocus()->GetId() == CTL_SQLQUERY) + { + wxBusyCursor wait; + SetStatusText(_("Running formatting command..."), STATUSPOS_MSGS); + SetStatusText(sqlQuery->ExternalFormat(), STATUSPOS_MSGS); + sqlQuery->SetFocus(); // could loose focus after running formatting process + } +} + +wxBitmap frmQuery::CreateBitmap(const wxColour &colour) +{ + const int w = 10, h = 10; + + wxMemoryDC dc; + wxBitmap bmp(w, h); + dc.SelectObject(bmp); + if (colour == wxNullColour) + dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW))); + else + dc.SetBrush(wxBrush(colour)); + dc.DrawRectangle(0, 0, w, h); + + return bmp; +} + +wxColour frmQuery::GetServerColour(pgConn *connection) +{ + wxColour tmp = wxNullColour; + if (mainForm != NULL) + { + ctlTree *browser = mainForm->GetBrowser(); + wxTreeItemIdValue foldercookie, servercookie; + wxTreeItemId folderitem, serveritem; + pgObject *object; + pgServer *server; + + folderitem = browser->GetFirstChild(browser->GetRootItem(), foldercookie); + while (folderitem) + { + if (browser->ItemHasChildren(folderitem)) + { + serveritem = browser->GetFirstChild(folderitem, servercookie); + while (serveritem) + { + object = browser->GetObject(serveritem); + if (object && object->IsCreatedBy(serverFactory)) + { + server = (pgServer *)object; + if (server->GetConnected() && + server->GetConnection()->GetHost() == connection->GetHost() && + server->GetConnection()->GetPort() == connection->GetPort()) + { + tmp = wxColour(server->GetColour()); + } + } + serveritem = browser->GetNextChild(folderitem, servercookie); + } + } + folderitem = browser->GetNextChild(browser->GetRootItem(), foldercookie); + } + } + return tmp; +} + +void frmQuery::LoadQueries() +{ + xmlDocPtr doc; + xmlNodePtr cur; + xmlChar *key; + + if (!wxFile::Access(settings->GetHistoryFile(), wxFile::read)) + return; + + doc = xmlParseFile((const char *)settings->GetHistoryFile().mb_str(wxConvUTF8)); + if (doc == NULL) + { + wxMessageBox(_("Failed to load the history file!")); + ::wxRemoveFile(settings->GetHistoryFile()); + return; + } + + cur = xmlDocGetRootElement(doc); + if (cur == NULL) + { + xmlFreeDoc(doc); + return; + } + + if (xmlStrcmp(cur->name, (const xmlChar *) "histoqueries")) + { + wxMessageBox(_("Failed to load the history file!")); + xmlFreeDoc(doc); + ::wxRemoveFile(settings->GetHistoryFile()); + return; + } + + cur = cur->xmlChildrenNode; + while (cur != NULL) + { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"histoquery"))) + { + key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); + + if (key) + { + if (WXSTRING_FROM_XML(key) != wxT("")) + { + wxString query = WXSTRING_FROM_XML(key); + wxString tmp = query; + tmp.Replace(wxT("\n"), wxT(" ")); + tmp.Replace(wxT("\r"), wxT(" ")); + sqlQueries->Append(tmp); + histoQueries.Add(query); + } + xmlFree(key); + } + } + + cur = cur->next; + } + + xmlFreeDoc(doc); + + // Make sure only the maximum query number is enforced + if (sqlQueries->GetCount() > (unsigned int)settings->GetHistoryMaxQueries()) + { + while (sqlQueries->GetCount() > (unsigned int)settings->GetHistoryMaxQueries()) + { + histoQueries.RemoveAt(0); + sqlQueries->Delete(0); + } + SaveQueries(); + } + + return; +} + + +void frmQuery::SaveQueries() +{ + size_t i; + xmlTextWriterPtr writer; + + writer = xmlNewTextWriterFilename((const char *)settings->GetHistoryFile().mb_str(wxConvUTF8), 0); + if (!writer) + { + wxMessageBox(_("Failed to write to history file!")); + return; + } + xmlTextWriterSetIndent(writer, 1); + + if ((xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL) < 0) || + (xmlTextWriterStartElement(writer, XML_STR("histoqueries")) < 0)) + { + wxMessageBox(_("Failed to write to history file!")); + xmlFreeTextWriter(writer); + return; + } + + for (i = 0; i < histoQueries.GetCount(); i++) + { + xmlTextWriterStartElement(writer, XML_STR("histoquery")); + xmlTextWriterWriteString(writer, XML_FROM_WXSTRING(histoQueries.Item(i))); + xmlTextWriterEndElement(writer); + } + + if (xmlTextWriterEndDocument(writer) < 0) + { + wxMessageBox(_("Failed to write to history file!")); + } + + xmlFreeTextWriter(writer); +} + + +void frmQuery::OnChangeQuery(wxCommandEvent &event) +{ + wxString query = histoQueries.Item(sqlQueries->GetSelection()); + if (query.Length() > 0) + { + sqlQuery->SetText(query); + sqlQuery->Colourise(0, query.Length()); + wxSafeYield(); // needed to process sqlQuery modify event + sqlQuery->SetChanged(true); + sqlQuery->SetOrigin(ORIGIN_HISTORY); + setExtendedTitle(); + SetLineEndingStyle(); + btnDeleteCurrent->Enable(true); + } + btnDeleteAll->Enable(sqlQueries->GetCount() > 0); +} + + +void frmQuery::OnDeleteCurrent(wxCommandEvent &event) +{ + + if ( wxMessageDialog(this, + _("Delete current query from history?"), + _("Confirm deletion"), + wxYES_NO | wxNO_DEFAULT | wxICON_EXCLAMATION).ShowModal() == wxID_YES ) + { + histoQueries.RemoveAt(sqlQueries->GetSelection()); + sqlQueries->Delete(sqlQueries->GetSelection()); + sqlQueries->SetValue(wxT("")); + btnDeleteCurrent->Enable(false); + btnDeleteAll->Enable(sqlQueries->GetCount() > 0); + SaveQueries(); + } +} + + +void frmQuery::OnDeleteAll(wxCommandEvent &event) +{ + + if ( wxMessageDialog(this, + _("Delete all queries from history?"), + _("Confirm deletion"), + wxYES_NO | wxNO_DEFAULT | wxICON_EXCLAMATION).ShowModal() == wxID_YES ) + { + histoQueries.Clear(); + sqlQueries->Clear(); + sqlQueries->SetValue(wxT("")); + btnDeleteCurrent->Enable(false); + btnDeleteAll->Enable(false); + SaveQueries(); + } +} + +void frmQuery::BeginPerspectiveChange() +{ + manager.GetPane(_("outputPane")).Caption(_("Output pane")); +} + +void frmQuery::EndPerspectiveChange(bool update) +{ + SetOutputPaneCaption(update); +} + +void frmQuery::SetOutputPaneCaption(bool update) +{ + wxString caption; + wxString title; + + if (sqlQueryExecLast == NULL) + caption = _("Output pane"); + else + { + // We don't want to make it look like Output Pane has been changed, + // so request the title without the change indicator + title = sqlQueryExecLast->GetTitle(false); + caption = wxString::Format(_("Output pane [%s]"), title.c_str()); + } + + manager.GetPane(wxT("outputPane")).Caption(caption); + + if (update) + manager.Update(); +} + +// Methods related to SQL tabs // + +void frmQuery::OnSqlBookPageChanged(wxAuiNotebookEvent &event) +{ + // Try to always keep sqlQuery variable pointing to the currently selected SQLBox. + // When closing and removing all tabs, page count may be zero. + if (sqlQueryBook->GetPageCount() > 0) + { + size_t curpage = sqlQueryBook->GetSelection(); + sqlQuery = wxDynamicCast(sqlQueryBook->GetPage(curpage), ctlSQLBox); + if (sqlQuery != NULL) + { + // Update UI with chosen query's info + SetEOLModeDisplay(sqlQuery->GetEOLMode()); + setExtendedTitle(); + + sqlQuery->SetFocus(); + //wxMessageBox(wxT("OnSqlBookPageChanged ")); + wxTheApp->Yield(true); + } + } + else + { + // This should help us find bugs (such as using sqlQuery after closing all tabs) much faster. + sqlQuery = NULL; + } +} + +void frmQuery::OnSqlBookPageChanging(wxAuiNotebookEvent &event) +{ + // Veto event while page change is prohibited. + if (!SqlBookCanChangePage()) + { + event.Veto(); + wxMessageBox(_("Cannot change to selected SQL tab now. Try again a bit later.")); + } +} + +void frmQuery::OnSqlBookAddPage(wxCommandEvent &event) +{ + if (SqlBookCanChangePage()) + SqlBookAddPage(); + else + wxMessageBox(_("Cannot add a new SQL tab now. Try again a bit later.")); +} +void frmQuery::OnSqlBookPageClosed(wxAuiNotebookEvent &event) +{ + //OnSqlBookPageChanged(event); + + //wxSleep(5); +// wxMessageBox(wxT("OnSqlBookPageClosed end")); +} +void frmQuery::OnSqlBookTabRDown (wxAuiNotebookEvent &event) { + size_t curpage = sqlQueryBook->GetSelection(); + ctlSQLBox *sqlQuery = wxDynamicCast(sqlQueryBook->GetPage(curpage), ctlSQLBox); + wxString pref=conn->GetDbname()+wxT(".nametab"); + + wxTextEntryDialog dialog(this, + wxT("Please enter name string with prefix dbname or 'Query'\n") + , + wxT("Name autosave tab window."), + pref, + wxOK | wxCANCEL); //setName( dlg.GetValue().wc_str() ); + if (dialog.ShowModal() == wxID_OK) { + wxString tempDir=wxStandardPaths::Get().GetTempDir()+wxT("\\"); + wxString filename=sqlQuery->GetTitle(false); + wxRemoveFile(tempDir+filename+wxT(".a")); + wxString nt=dialog.GetValue(); + sqlQuery->SetTitle(nt); + SqlBookUpdatePageTitle(); + //sqlQueryBook->GetPage(curpage)-> + SaveTempFile(); + } + +} +void frmQuery::OnSqlBookPageClose(wxAuiNotebookEvent &event) +{ + // Don't allow removal of the last SQL box via user generated event + size_t pagecnt = sqlQueryBook->GetPageCount(); + if (pagecnt == 1) + { + event.Veto(); + wxMessageBox(_("Cannot remove the last SQL tab")); + return; + } + + // Prevent removing the page that is currently being executed + if (sqlQueryExec != NULL && sqlQueryExec == sqlQuery) + { + event.Veto(); + wxMessageBox(_("The query on this SQL tab is still running.\nWait for it to finish or cancel it before closing the tab.")); + return; + } + + if (CheckChanged(true)) + { + event.Veto(); + return; + } + + // If removing the tab for which results are displayed, reset the output pane's caption + if (sqlQuery == sqlQueryExecLast) + { + sqlQueryExecLast = NULL; + SetOutputPaneCaption(true); + } + + SqlBookDisconnectPage(); + //drop temp file + wxString tempDir=wxStandardPaths::Get().GetTempDir()+wxT("\\"); + wxString filename=sqlQuery->GetTitle(false)+wxT(".a"); + if (wxFileName::FileExists(tempDir+filename)) wxRemoveFile(tempDir+filename); + +} + +bool frmQuery::SqlBookCanChangePage() +{ + return !(m_loadingfile || ms_pgScriptRunning); +} + +void frmQuery::SqlBookAddPage() +{ + ctlSQLBox *box; + wxString caption; + bool bVal; + + // All SQL boxes use the same wxID, CTL_SQLQUERY. + // This should probably be changed, but it works for now and has minimal impact on existing code. + box = new ctlSQLBox(sqlQueryBook, CTL_SQLQUERY, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxSIMPLE_BORDER | wxTE_RICH2); + box->SetDatabase(conn); + box->SetMarginWidth(1, 16); + box->SetDropTarget(new DnDFile(this)); + box->SetChanged(false); + box->SetOrigin(ORIGIN_MANUAL); + + bVal = editMenu->IsChecked(MNU_AUTOINDENT); + box->SetAutoIndent(bVal); + + bVal = viewMenu->IsChecked(MNU_WORDWRAP); + box->SetWrapMode(bVal ? wxSTC_WRAP_WORD : wxSTC_WRAP_NONE); + + bVal = viewMenu->IsChecked(MNU_SHOWINDENTGUIDES); + box->SetIndentationGuides(bVal); + + bVal = viewMenu->IsChecked(MNU_SHOWWHITESPACE); + box->SetViewWhiteSpace(bVal ? wxSTC_WS_VISIBLEALWAYS : wxSTC_WS_INVISIBLE); + + bVal = viewMenu->IsChecked(MNU_SHOWLINEENDS); + box->SetViewEOL(bVal ? 1 : 0); + + box->Connect(wxID_ANY, wxEVT_SET_FOCUS, wxFocusEventHandler(frmQuery::OnFocus)); + box->Connect(wxID_ANY, wxEVT_KILL_FOCUS, wxFocusEventHandler(frmQuery::OnFocus)); + + sqlQueryCounter ++; + caption = wxString::Format(_("Query %i"), sqlQueryCounter); + box->SetTitle(caption); + sqlQueryBook->AddPage(box, caption, true); + + // Probably not needed, as the line above should trigger the PageChange event + sqlQuery = box; + sqlQuery->SetAutoReplaceList(autoreplace); +} + +void frmQuery::SqlBookDisconnectPage(ctlSQLBox *box) +{ + if (box == NULL) + box = sqlQuery; + + if (box != NULL) + { + box->Disconnect(wxID_ANY, wxEVT_SET_FOCUS, wxFocusEventHandler(frmQuery::OnFocus)); + box->Disconnect(wxID_ANY, wxEVT_KILL_FOCUS, wxFocusEventHandler(frmQuery::OnFocus)); + } +} + +bool frmQuery::SqlBookRemovePage() +{ + size_t pageidx; + if (sqlQueryBook->GetPageCount() > 0) + { + // If removing the tab for which results are displayed, reset the output pane's caption + if (sqlQuery == sqlQueryExecLast) + { + sqlQueryExecLast = NULL; + SetOutputPaneCaption(true); + } + + SqlBookDisconnectPage(); + pageidx = sqlQueryBook->GetSelection(); + wxString tempDir=wxStandardPaths::Get().GetTempDir()+wxT("\\"); + ctlSQLBox *box; + box = wxDynamicCast(sqlQueryBook->GetPage(pageidx), ctlSQLBox); + wxString filename=box->GetTitle(false); + wxRemoveFile(tempDir+filename+wxT(".a")); + return sqlQueryBook->DeletePage(pageidx); + } + return false; +} + +void frmQuery::SqlBookSetAutoIndent(bool b) +{ + size_t i, cnt; + ctlSQLBox *box; + + for (i = 0, cnt = sqlQueryBook->GetPageCount(); i < cnt; ++i) + { + box = wxDynamicCast(sqlQueryBook->GetPage(i), ctlSQLBox); + if (box != NULL) + box->SetAutoIndent(b); + } +} + +void frmQuery::SqlBookSetWrapMode(bool b) +{ + size_t i, cnt; + ctlSQLBox *box; + + for (i = 0, cnt = sqlQueryBook->GetPageCount(); i < cnt; ++i) + { + box = wxDynamicCast(sqlQueryBook->GetPage(i), ctlSQLBox); + if (box != NULL) + box->SetWrapMode(b ? wxSTC_WRAP_WORD : wxSTC_WRAP_NONE); + } +} + +void frmQuery::SqlBookSetIndentGuides(bool b) +{ + size_t i, cnt; + ctlSQLBox *box; + + for (i = 0, cnt = sqlQueryBook->GetPageCount(); i < cnt; ++i) + { + box = wxDynamicCast(sqlQueryBook->GetPage(i), ctlSQLBox); + if (box != NULL) + box->SetIndentationGuides(b); + } +} + +void frmQuery::SqlBookSetViewWhiteSpace(bool b) +{ + size_t i, cnt; + ctlSQLBox *box; + + for (i = 0, cnt = sqlQueryBook->GetPageCount(); i < cnt; ++i) + { + box = wxDynamicCast(sqlQueryBook->GetPage(i), ctlSQLBox); + if (box != NULL) + box->SetViewWhiteSpace(b ? wxSTC_WS_VISIBLEALWAYS : wxSTC_WS_INVISIBLE); + } +} + +void frmQuery::SqlBookSetViewEOL(bool b) +{ + size_t i, cnt; + ctlSQLBox *box; + + for (i = 0, cnt = sqlQueryBook->GetPageCount(); i < cnt; ++i) + { + box = wxDynamicCast(sqlQueryBook->GetPage(i), ctlSQLBox); + if (box != NULL) + box->SetViewEOL(b ? 1 : 0); + } +} + +void frmQuery::SqlBookSetViewLineNumbers(bool b) +{ + size_t i, cnt; + ctlSQLBox *box; + + for (i = 0, cnt = sqlQueryBook->GetPageCount(); i < cnt; ++i) + { + box = wxDynamicCast(sqlQueryBook->GetPage(i), ctlSQLBox); + if (box != NULL) + box->UpdateLineNumber(); + } +} + +void frmQuery::SqlBookSetDatabase(pgConn *con) +{ + size_t i, cnt; + ctlSQLBox *box; + + for (i = 0, cnt = sqlQueryBook->GetPageCount(); i < cnt; ++i) + { + box = wxDynamicCast(sqlQueryBook->GetPage(i), ctlSQLBox); + if (box != NULL) + box->SetDatabase(con); + } +} + +void frmQuery::SqlBookUpdatePageTitle() +{ + size_t index; + wxString title; + + if (sqlQueryBook->GetPageCount() > 0 && sqlQuery != NULL) + { + index = sqlQueryBook->GetPageIndex(sqlQuery); + if (index == wxNOT_FOUND) + return; + + title = sqlQuery->GetTitle(); + if (sqlQueryBook->GetPageText(index) != title) + sqlQueryBook->SetPageText(index, title); + } +} + +// Returns true if any SQL tab attempts to veto the closing, false otherwise. +bool frmQuery::SqlBookClose(bool canVeto) +{ + size_t i = 0; + size_t cnt = sqlQueryBook->GetPageCount(); + ctlSQLBox *box; + + // See if we have any unsaved changes and prompt to save them + for (i = 0; i < cnt; ++i) + { + box = wxDynamicCast(sqlQueryBook->GetPage(i), ctlSQLBox); + if (box != NULL && box->IsChanged()) + { + sqlQueryBook->SetSelection(i); + if (CheckChanged(canVeto)) + return true; + } + } + + // If we got here, the window will be closed + for (i = 0; i < cnt; ++i) + { + box = wxDynamicCast(sqlQueryBook->GetPage(i), ctlSQLBox); + if (box != NULL) + SqlBookDisconnectPage(box); + } + + return false; +} + + +/////////////////////////////////////////////////////// + +wxWindow *queryToolBaseFactory::StartDialogSql(frmMain *form, pgObject *obj, const wxString &sql) +{ + pgDatabase *db = obj->GetDatabase(); + wxString usr=wxEmptyString; + wxGetEnv(wxT("USERNAME"),&usr); + wxString applicationname = appearanceFactory->GetLongAppName() + wxT(" - query ")+usr; + pgConn *conn = db->CreateConn(applicationname); + if (conn) + { + frmQuery *fq = new frmQuery(form, obj->GetDisplayName(), conn, sql); + fq->Go(); + return fq; + } + return 0; +} + + +bool queryToolBaseFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->GetDatabase() && obj->GetDatabase()->GetConnected(); +} + + +bool queryToolDataFactory::CheckEnable(pgObject *obj) +{ + return queryToolBaseFactory::CheckEnable(obj) && !obj->IsCollection() && + (obj->IsCreatedBy(tableFactory) || obj->IsCreatedBy(pg_partitionFactory) || obj->IsCreatedBy(viewFactory)); +} + + +queryToolFactory::queryToolFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : queryToolBaseFactory(list) +{ + mnu->Append(id, _("&Query tool\tCtrl-E"), _("Execute arbitrary SQL queries.")); + toolbar->AddTool(id, wxEmptyString, *sql_32_png_bmp, _("Execute arbitrary SQL queries."), wxITEM_NORMAL); +} + + +wxWindow *queryToolFactory::StartDialog(frmMain *form, pgObject *obj) +{ + wxString qry; + if (settings->GetStickySql()) + qry = obj->GetSql(form->GetBrowser()); + return StartDialogSql(form, obj, qry); +} + + +queryToolSqlFactory::queryToolSqlFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : queryToolBaseFactory(list) +{ + mnu->Append(id, _("CREATE Script"), _("Start Query tool with CREATE script.")); + if (toolbar) + toolbar->AddTool(id, wxEmptyString, *sql_32_png_bmp, _("Start query tool with CREATE script."), wxITEM_NORMAL); +} + + +wxWindow *queryToolSqlFactory::StartDialog(frmMain *form, pgObject *obj) +{ + return StartDialogSql(form, obj, obj->GetSql(form->GetBrowser())); +} + + +bool queryToolSqlFactory::CheckEnable(pgObject *obj) +{ + return queryToolBaseFactory::CheckEnable(obj) && obj->CanCreate() && !obj->IsCollection(); +} + + +queryToolSelectFactory::queryToolSelectFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : queryToolDataFactory(list) +{ + mnu->Append(id, _("SELECT Script"), _("Start query tool with SELECT script.")); +} + +bool queryToolSelectFactory::CheckEnable(pgObject *obj) +{ + return queryToolBaseFactory::CheckEnable(obj) && !obj->IsCollection() && + (obj->IsCreatedBy(tableFactory) || obj->IsCreatedBy(foreignTableFactory) || obj->IsCreatedBy(viewFactory) || obj->IsCreatedBy(functionFactory) || obj->IsCreatedBy(pg_partitionFactory)); +} + +wxWindow *queryToolSelectFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (obj->IsCreatedBy(tableFactory)||(obj->IsCreatedBy(pg_partitionFactory))) + { + pgTable *table = (pgTable *)obj; + return StartDialogSql(form, obj, table->GetSelectSql(form->GetBrowser())); + } + else if (obj->IsCreatedBy(viewFactory)) + { + pgView *view = (pgView *)obj; + return StartDialogSql(form, obj, view->GetSelectSql(form->GetBrowser())); + } + else if (obj->IsCreatedBy(extTableFactory)) + { + gpExtTable *exttable = (gpExtTable *)obj; + return StartDialogSql(form, obj, exttable->GetSelectSql(form->GetBrowser())); + } + else if (obj->IsCreatedBy(functionFactory)) + { + pgFunction *function = (pgFunction *)obj; + return StartDialogSql(form, obj, function->GetSelectSql(form->GetBrowser())); + } + else if (obj->IsCreatedBy(foreignTableFactory)) + { + pgForeignTable *foreigntable = (pgForeignTable *)obj; + return StartDialogSql(form, obj, foreigntable->GetSelectSql(form->GetBrowser())); + } + return 0; +} + +queryToolExecFactory::queryToolExecFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : queryToolDataFactory(list) +{ + mnu->Append(id, _("EXEC Script"), _("Start query tool with EXEC script.")); +} + +bool queryToolExecFactory::CheckEnable(pgObject *obj) +{ + return queryToolBaseFactory::CheckEnable(obj) && !obj->IsCollection() && obj->IsCreatedBy(procedureFactory); +} + +wxWindow *queryToolExecFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (obj->IsCreatedBy(procedureFactory)) + { + pgProcedure *procedure = (pgProcedure *)obj; + return StartDialogSql(form, obj, procedure->GetExecSql(form->GetBrowser())); + } + return 0; +} + +queryToolDeleteFactory::queryToolDeleteFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : queryToolDataFactory(list) +{ + mnu->Append(id, _("DELETE Script"), _("Start query tool with DELETE script.")); +} + + +bool queryToolDeleteFactory::CheckEnable(pgObject *obj) +{ + if (!queryToolDataFactory::CheckEnable(obj)) + return false; + if (obj->IsCreatedBy(tableFactory)||obj->IsCreatedBy(pg_partitionFactory)) + return true; + return false; +} + + +wxWindow *queryToolDeleteFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (obj->IsCreatedBy(tableFactory)) + { + pgTable *table = (pgTable *)obj; + return StartDialogSql(form, obj, table->GetDeleteSql(form->GetBrowser())); + } + return 0; +} + + +queryToolCreateCascadeFactory::queryToolCreateCascadeFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : queryToolDataFactory(list) +{ + mnu->Append(id, _("Script Recreate Cascade"), _("Start query tool with recreate cascade script.")); +} + +//wxArrayString queryToolCreateCascadeFactory::GetArrayList(wxString *strobj) +//{ +// wxString *databasePath=new wxString(strobj); +// pgSet *set; +// set = connection->ExecuteSet( +// wxT("SELECT relname FROM pg_class, pg_index WHERE pg_class.oid=indexrelid AND indrelid=") + table->GetOidStr()); +// if (set) +// { +// while (!set->Eof()) +// { +// cbIndex->Append(set->GetVal(0)); +// set->MoveNext(); +// } +// delete set; +// } +// +// wxStringTokenizer tkz(databasePath, wxT("/")); +// while(tkz.HasMoreTokens()) +// { +// wxString token = tkz.GetNextToken(); +// if(token == _("Databases")) +// break; +// //ItemPath += token + wxT("/"); +// } +// +// return 0; +//} +wxWindow *queryToolCreateCascadeFactory::StartDialog(frmMain *form, pgObject *obj) +{ + + if (obj->IsCreatedBy(tableFactory)||obj->IsCreatedBy(pg_partitionFactory)) + { + pgTable *table = (pgTable *)obj; + return StartDialogSql(form, obj, table->GetSqlReCreate(form,obj)); + } + else if (obj->IsCreatedBy(viewFactory)) + { + pgView *view = (pgView *)obj; + return StartDialogSql(form, obj, view->GetSqlReCreate(form,obj)); + } + + return 0; +} + + +bool queryToolCreateCascadeFactory::CheckEnable(pgObject *obj) +{ + if (!queryToolDataFactory::CheckEnable(obj)) + return false; + if (obj->IsCreatedBy(tableFactory)||obj->IsCreatedBy(pg_partitionFactory)) + return true; + pgView *view = (pgView *)obj; + + return true; +} + +queryToolUpdateFactory::queryToolUpdateFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : queryToolDataFactory(list) +{ + mnu->Append(id, _("UPDATE Script"), _("Start query tool with UPDATE script.")); +} + + +wxWindow *queryToolUpdateFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (obj->IsCreatedBy(tableFactory)||obj->IsCreatedBy(pg_partitionFactory)) + { + pgTable *table = (pgTable *)obj; + return StartDialogSql(form, obj, table->GetUpdateSql(form->GetBrowser())); + } + else if (obj->IsCreatedBy(viewFactory)) + { + pgView *view = (pgView *)obj; + return StartDialogSql(form, obj, view->GetUpdateSql(form->GetBrowser())); + } + + return 0; +} + + +bool queryToolUpdateFactory::CheckEnable(pgObject *obj) +{ + if (!queryToolDataFactory::CheckEnable(obj)) + return false; + if (obj->IsCreatedBy(tableFactory)||obj->IsCreatedBy(pg_partitionFactory)) + return true; + pgView *view = (pgView *)obj; + + return view->HasUpdateRule(); +} + + +queryToolInsertFactory::queryToolInsertFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : queryToolDataFactory(list) +{ + mnu->Append(id, _("INSERT Script"), _("Start query tool with INSERT script.")); +} + + +wxWindow *queryToolInsertFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (obj->IsCreatedBy(tableFactory)||obj->IsCreatedBy(pg_partitionFactory)) + { + pgTable *table = (pgTable *)obj; + return StartDialogSql(form, obj, table->GetInsertSql(form->GetBrowser())); + } + else if (obj->IsCreatedBy(viewFactory)) + { + pgView *view = (pgView *)obj; + return StartDialogSql(form, obj, view->GetInsertSql(form->GetBrowser())); + } + return 0; +} + +bool queryToolInsertFactory::CheckEnable(pgObject *obj) +{ + if (!queryToolDataFactory::CheckEnable(obj)) + return false; + if (obj->IsCreatedBy(tableFactory)||obj->IsCreatedBy(pg_partitionFactory)) + return true; + pgView *view = (pgView *)obj; + + return view->HasInsertRule(); +} + +void frmQuery::SaveExplainAsImage(wxCommandEvent &ev) +{ + wxFileDialog *dlg = new wxFileDialog(this, _("Save Explain As image file"), lastDir, lastFilename, + wxT("Bitmap files (*.bmp)|*.bmp|JPEG files (*.jpeg)|*.jpeg|PNG files (*.png)|*.png"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); + if (dlg->ShowModal() == wxID_OK) + { + lastFilename = dlg->GetFilename(); + lastDir = dlg->GetDirectory(); + lastPath = dlg->GetPath(); + int index = dlg->GetFilterIndex(); + + wxString strType; + wxBitmapType imgType; + switch (index) + { + // bmp + case 0: + strType = wxT(".bmp"); + imgType = wxBITMAP_TYPE_BMP; + break; + // jpeg + case 1: + strType = wxT(".jpeg"); + imgType = wxBITMAP_TYPE_JPEG; + break; + // default (png) + default: + // png + case 2: + strType = wxT(".png"); + imgType = wxBITMAP_TYPE_PNG; + break; + } + + if (!lastPath.Contains(wxT("."))) + lastPath += strType; + + if (ev.GetId() == MNU_SAVEAS_IMAGE_GQB) + controller->getView()->SaveAsImage(lastPath, imgType); + else if (ev.GetId() == MNU_SAVEAS_IMAGE_EXPLAIN) + explainCanvas->SaveAsImage(lastPath, imgType); + } +} + +/////////////////////////////////////////////////////// + +pgScriptTimer::pgScriptTimer(frmQuery *parent) : + m_parent(parent) +{ + +} + +void pgScriptTimer::Notify() +{ + // Write script output + m_parent->writeScriptOutput(); +} + diff --git a/frm/frmReport.cpp b/frm/frmReport.cpp new file mode 100644 index 0000000..9245537 --- /dev/null +++ b/frm/frmReport.cpp @@ -0,0 +1,1557 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmReport.cpp - The report file dialogue +// +////////////////////////////////////////////////////////////////////////// + + + +// App headers +#include "pgAdmin3.h" +#include + +#include "frm/frmMain.h" +#include "frm/frmReport.h" +#include "utils/sysSettings.h" +#include "utils/misc.h" +#include "ctl/ctlListView.h" +#include "schema/pgObject.h" +#include "schema/pgCollection.h" +#include "schema/pgServer.h" +#include "schema/pgDatabase.h" +#include "schema/pgSchema.h" +#include "schema/pgTable.h" +#include "schema/pgColumn.h" +#include "schema/pgConstraints.h" +#include "agent/pgaJob.h" +#include "schema/pgForeignKey.h" +#include "schema/pgIndexConstraint.h" +#include "schema/pgCheck.h" + +// XML2/XSLT headers +#include +#include + +#define txtTitle CTRL_TEXT("txtTitle") +#define txtNotes CTRL_TEXT("txtNotes") +#define txtHtmlFile CTRL_TEXT("txtHtmlFile") +#define txtXmlFile CTRL_TEXT("txtXmlFile") +#define txtHtmlStylesheet CTRL_TEXT("txtHtmlStylesheet") +#define txtXmlStylesheet CTRL_TEXT("txtXmlStylesheet") +#define btnOK CTRL_BUTTON("wxID_OK") +#define btnFile CTRL_BUTTON("btnFile") +#define btnStylesheet CTRL_BUTTON("btnStylesheet") +#define rbHtml CTRL_RADIOBUTTON("rbHtml") +#define rbXml CTRL_RADIOBUTTON("rbXml") +#define rbHtmlBuiltin CTRL_RADIOBUTTON("rbHtmlBuiltin") +#define rbHtmlEmbed CTRL_RADIOBUTTON("rbHtmlEmbed") +#define rbHtmlLink CTRL_RADIOBUTTON("rbHtmlLink") +#define rbXmlPlain CTRL_RADIOBUTTON("rbXmlPlain") +#define rbXmlLink CTRL_RADIOBUTTON("rbXmlLink") +#define rbXmlProcess CTRL_RADIOBUTTON("rbXmlProcess") +#define chkSql CTRL_CHECKBOX("chkSql") +#define chkBrowser CTRL_CHECKBOX("chkBrowser") + +BEGIN_EVENT_TABLE(frmReport, pgDialog) + EVT_RADIOBUTTON(XRCID("rbHtml"), frmReport::OnChange) + EVT_RADIOBUTTON(XRCID("rbXml"), frmReport::OnChange) + EVT_RADIOBUTTON(XRCID("rbHtmlBuiltin"), frmReport::OnChange) + EVT_RADIOBUTTON(XRCID("rbHtmlEmbed"), frmReport::OnChange) + EVT_RADIOBUTTON(XRCID("rbHtmlLink"), frmReport::OnChange) + EVT_RADIOBUTTON(XRCID("rbXmlPlain"), frmReport::OnChange) + EVT_RADIOBUTTON(XRCID("rbXmlLink"), frmReport::OnChange) + EVT_RADIOBUTTON(XRCID("rbXmlProcess"), frmReport::OnChange) + EVT_TEXT(XRCID("txtHtmlFile"), frmReport::OnChange) + EVT_TEXT(XRCID("txtXmlFile"), frmReport::OnChange) + EVT_TEXT(XRCID("txtHtmlStylesheet"), frmReport::OnChange) + EVT_TEXT(XRCID("txtXmlStylesheet"), frmReport::OnChange) + EVT_BUTTON(XRCID("btnFile"), frmReport::OnBrowseFile) + EVT_BUTTON(XRCID("btnStylesheet"), frmReport::OnBrowseStylesheet) + EVT_BUTTON(wxID_HELP, frmReport::OnHelp) + EVT_BUTTON(wxID_OK, frmReport::OnOK) + EVT_BUTTON(wxID_CANCEL, frmReport::OnCancel) +END_EVENT_TABLE() + +frmReport::frmReport(wxWindow *p) +{ + parent = p; + header = wxT(""); + + SetFont(settings->GetSystemFont()); + LoadResource(p, wxT("frmReport")); + + // Icon + appearanceFactory->SetIcons(this); + RestorePosition(); + btnOK->Disable(); + + wxString val; + bool bVal; + + // Output format + settings->Read(wxT("Reports/ReportFormat"), &val, wxT("h")); + if (val == wxT("x")) + { + rbHtml->SetValue(false); + rbXml->SetValue(true); + } + else + { + rbHtml->SetValue(true); + rbXml->SetValue(false); + } + + // HTML Stylesheet + settings->Read(wxT("Reports/HtmlStylesheetMode"), &val, wxT("b")); + if (val == wxT("e")) + { + rbHtmlBuiltin->SetValue(false); + rbHtmlEmbed->SetValue(true); + rbHtmlLink->SetValue(false); + } + else if (val == wxT("l")) + { + rbHtmlBuiltin->SetValue(false); + rbHtmlEmbed->SetValue(false); + rbHtmlLink->SetValue(true); + } + else + { + rbHtmlBuiltin->SetValue(true); + rbHtmlEmbed->SetValue(false); + rbHtmlLink->SetValue(false); + } + + // XML Stylesheet + settings->Read(wxT("Reports/XmlStylesheetMode"), &val, wxT("p")); + if (val == wxT("l")) + { + rbXmlPlain->SetValue(false); + rbXmlLink->SetValue(true); + rbXmlProcess->SetValue(false); + } + else if (val == wxT("r")) + { + rbXmlPlain->SetValue(false); + rbXmlLink->SetValue(false); + rbXmlProcess->SetValue(true); + } + else + { + rbXmlPlain->SetValue(true); + rbXmlLink->SetValue(false); + rbXmlProcess->SetValue(false); + } + + // Default values + settings->Read(wxT("Reports/LastNotes"), &val, wxT("")); + txtNotes->SetValue(val); + + settings->Read(wxT("Reports/LastHtmlStylesheet"), &val, wxEmptyString); + txtHtmlStylesheet->SetValue(val); + + settings->Read(wxT("Reports/LastXmlStylesheet"), &val, wxEmptyString); + txtXmlStylesheet->SetValue(val); + + settings->Read(wxT("Reports/LastHtmlFile"), &val, wxEmptyString); + txtHtmlFile->SetValue(val); + + settings->Read(wxT("Reports/LastXmlFile"), &val, wxEmptyString); + txtXmlFile->SetValue(val); + + settings->Read(wxT("Reports/IncludeSQL"), &bVal, true); + chkSql->SetValue(bVal); + chkSql->Disable(); + + settings->Read(wxT("Reports/OpenInBrowser"), &bVal, true); + chkBrowser->SetValue(bVal); + + wxCommandEvent ev; + OnChange(ev); + + txtTitle->SetFocus(); +} + + +frmReport::~frmReport() +{ + SavePosition(); +} + + +void frmReport::OnHelp(wxCommandEvent &ev) +{ + DisplayHelp(wxT("reports"), HELP_PGADMIN); +} + + +void frmReport::OnChange(wxCommandEvent &ev) +{ + bool enable = true; + + if (rbHtml->GetValue()) + { + // Show/hide the appropriate controls + rbHtmlBuiltin->Show(true); + rbHtmlEmbed->Show(true); + rbHtmlLink->Show(true); + txtHtmlStylesheet->Show(true); + txtHtmlFile->Show(true); + + rbXmlPlain->Show(false); + rbXmlLink->Show(false); + rbXmlProcess->Show(false); + txtXmlStylesheet->Show(false); + txtXmlFile->Show(false); + + // Enable/disable as appropriate + if (txtHtmlFile->GetValue().IsEmpty()) + enable = false; + + if (rbHtmlBuiltin->GetValue()) + { + txtHtmlStylesheet->Disable(); + btnStylesheet->Disable(); + } + else + { + txtHtmlStylesheet->Enable(); + btnStylesheet->Enable(); + } + + if (rbHtmlEmbed->GetValue()) + { + if (!wxFile::Exists(txtHtmlStylesheet->GetValue())) + enable = false; + } + } + else + { + // Show/hide the appropriate controls + rbHtmlBuiltin->Show(false); + rbHtmlEmbed->Show(false); + rbHtmlLink->Show(false); + txtHtmlStylesheet->Show(false); + txtHtmlFile->Show(false); + + rbXmlPlain->Show(true); + rbXmlLink->Show(true); + rbXmlProcess->Show(true); + txtXmlStylesheet->Show(true); + txtXmlFile->Show(true); + + // Enable/disable as appropriate + if (txtXmlFile->GetValue().IsEmpty()) + enable = false; + + if (rbXmlPlain->GetValue()) + { + txtXmlStylesheet->Disable(); + btnStylesheet->Disable(); + } + else + { + txtXmlStylesheet->Enable(); + btnStylesheet->Enable(); + } + + if (rbXmlProcess->GetValue()) + { + if (!wxFile::Exists(txtXmlStylesheet->GetValue())) + enable = false; + } + } + + btnOK->Enable(enable); +} + + +void frmReport::OnOK(wxCommandEvent &ev) +{ + wxString filename; + if (rbHtml->GetValue()) + filename = txtHtmlFile->GetValue(); + else + filename = txtXmlFile->GetValue(); + + wxFileName fn(filename); + fn.MakeAbsolute(); + + // Check if the file exsits, and if so, whether to overwrite it + if (wxFileExists(fn.GetFullPath())) + { + wxString msg; + msg.Printf(_("The file: \n\n%s\n\nalready exists. Do you want to overwrite it?"), fn.GetFullPath().c_str()); + + if (wxMessageBox(msg, _("Overwrite file?"), wxYES_NO | wxICON_QUESTION) != wxYES) + { + if (rbHtml->GetValue()) + txtHtmlFile->SetFocus(); + else + txtXmlFile->SetFocus(); + return; + } + } + + // Yield, to allow the messagebox to go + wxTheApp->Yield(true); + + // Add the title, notes and SQL + if (txtTitle->GetValue() != wxT("")) + XmlAddHeaderValue(wxT("title"), txtTitle->GetValue()); + + if (txtNotes->GetValue() != wxT("")) + XmlAddHeaderValue(wxT("notes"), txtNotes->GetValue()); + + // Generate the report data + wxString report; + + if (rbHtml->GetValue()) + { + if (rbHtmlBuiltin->GetValue()) + { + wxString xml = GetXmlReport(wxEmptyString); + wxString xsl = GetDefaultXsl(GetEmbeddedCss(GetDefaultCss())); + report = XslProcessReport(xml, xsl); + } + else if (rbHtmlEmbed->GetValue()) + { + wxString xml = GetXmlReport(wxEmptyString); + wxString css = FileRead(txtHtmlStylesheet->GetValue()); + if (css.IsEmpty()) + { + wxLogError(_("No stylesheet data could be read from the file %s: Errcode=%d."), txtHtmlStylesheet->GetValue().c_str(), wxSysErrorCode()); + return; + } + wxString xsl = GetDefaultXsl(GetEmbeddedCss(css)); + report = XslProcessReport(xml, xsl); + } + else + { + wxString xml = GetXmlReport(wxEmptyString); + wxString xsl = GetDefaultXsl(GetCssLink(txtHtmlStylesheet->GetValue())); + report = XslProcessReport(xml, xsl); + } + } + else + { + if (rbXmlPlain->GetValue()) + { + report = GetXmlReport(wxEmptyString); + } + else if (rbXmlLink->GetValue()) + { + report = GetXmlReport(txtXmlStylesheet->GetValue()); + } + else + { + wxString xml = GetXmlReport(wxEmptyString); + wxString xsl = FileRead(txtXmlStylesheet->GetValue()); + if (xsl.IsEmpty()) + { + wxLogError(_("No stylesheet data could be read from the file %s: Errcode=%d."), txtXmlStylesheet->GetValue().c_str(), wxSysErrorCode()); + return; + } + report = XslProcessReport(xml, xsl); + } + } + + // If report is empty, an error must have occurred + if (report.IsEmpty()) + return; + + // Save it to disk + wxFile file(fn.GetFullPath(), wxFile::write); + if (!file.IsOpened()) + { + wxLogError(_("Failed to open file %s."), fn.GetFullPath().c_str()); + return; + } + file.Write(report, wxConvUTF8); + file.Close(); + + // Open the file in the default browser if required + if (chkBrowser->GetValue()) +#ifdef __WXMSW__ + wxLaunchDefaultBrowser(fn.GetFullPath()); +#else + wxLaunchDefaultBrowser(wxT("file://") + fn.GetFullPath()); +#endif + + // Save the settings for next time round + settings->Write(wxT("Reports/LastNotes"), txtNotes->GetValue()); + + if (rbHtml->GetValue()) + settings->Write(wxT("Reports/ReportFormat"), wxT("h")); + else + settings->Write(wxT("Reports/ReportFormat"), wxT("x")); + + if (rbHtmlBuiltin->GetValue()) + settings->Write(wxT("Reports/HtmlStylesheetMode"), wxT("b")); + else if (rbHtmlEmbed->GetValue()) + settings->Write(wxT("Reports/HtmlStylesheetMode"), wxT("e")); + else + settings->Write(wxT("Reports/HtmlStylesheetMode"), wxT("l")); + + if (rbXmlPlain->GetValue()) + settings->Write(wxT("Reports/XmlStylesheetMode"), wxT("p")); + else if (rbXmlLink->GetValue()) + settings->Write(wxT("Reports/XmlStylesheetMode"), wxT("l")); + else + settings->Write(wxT("Reports/XmlStylesheetMode"), wxT("r")); + + settings->Write(wxT("Reports/LastHtmlStylesheet"), txtHtmlStylesheet->GetValue()); + settings->Write(wxT("Reports/LastXmlStylesheet"), txtXmlStylesheet->GetValue()); + + + settings->Write(wxT("Reports/LastHtmlFile"), txtHtmlFile->GetValue()); + settings->Write(wxT("Reports/LastXmlFile"), txtXmlFile->GetValue()); + + settings->WriteBool(wxT("Reports/IncludeSQL"), chkSql->GetValue()); + + settings->WriteBool(wxT("Reports/OpenInBrowser"), chkBrowser->GetValue()); + + // Now go away + if (IsModal()) + EndModal(wxID_OK); + else + Destroy(); +} + +void frmReport::OnCancel(wxCommandEvent &ev) +{ + if (IsModal()) + EndModal(wxID_CANCEL); + else + Destroy(); +} + +void frmReport::OnBrowseStylesheet(wxCommandEvent &ev) +{ + if (rbHtml->GetValue()) + { + wxString def = txtHtmlStylesheet->GetValue(); + + if (!wxFile::Exists(def)) + def.Empty(); + +#ifdef __WXMSW__ + wxFileDialog file(this, _("Select stylesheet filename"), wxGetHomeDir(), def, _("HTML Stylesheet files (*.css)|*.css|All files (*.*)|*.*"), wxFD_OPEN); +#else + wxFileDialog file(this, _("Select stylesheet filename"), wxGetHomeDir(), def, _("HTML Stylesheet files (*.css)|*.css|All files (*)|*"), wxFD_OPEN); +#endif + + if (file.ShowModal() == wxID_OK) + { + txtHtmlStylesheet->SetValue(file.GetPath()); + OnChange(ev); + } + } + else + { + wxString def = txtXmlStylesheet->GetValue(); + + if (!wxFile::Exists(def)) + def.Empty(); + +#ifdef __WXMSW__ + wxFileDialog file(this, _("Select stylesheet filename"), wxGetHomeDir(), def, _("XML Stylesheet files (*.xsl)|*.xsl|All files (*.*)|*.*"), wxFD_OPEN); +#else + wxFileDialog file(this, _("Select stylesheet filename"), wxGetHomeDir(), def, _("XML Stylesheet files (*.xsl)|*.xsl|All files (*)|*"), wxFD_OPEN); +#endif + + if (file.ShowModal() == wxID_OK) + { + txtXmlStylesheet->SetValue(file.GetPath()); + OnChange(ev); + } + } +} + +void frmReport::OnBrowseFile(wxCommandEvent &ev) +{ + if (rbHtml->GetValue()) + { +#ifdef __WXMSW__ + wxFileDialog file(this, _("Select output filename"), wxGetHomeDir(), txtHtmlFile->GetValue(), + _("HTML files (*.html)|*.html|All files (*.*)|*.*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); +#else + wxFileDialog file(this, _("Select output filename"), wxGetHomeDir(), txtHtmlFile->GetValue(), + _("HTML files (*.html)|*.html|All files (*)|*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); +#endif + + if (file.ShowModal() == wxID_OK) + { + txtHtmlFile->SetValue(file.GetPath()); + OnChange(ev); + } + } + else + { +#ifdef __WXMSW__ + wxFileDialog file(this, _("Select output filename"), wxGetHomeDir(), txtXmlFile->GetValue(), + _("XML files (*.xml)|*.xml|All files (*.*)|*.*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); +#else + wxFileDialog file(this, _("Select output filename"), wxGetHomeDir(), txtXmlFile->GetValue(), + _("XML files (*.xml)|*.xml|All files (*)|*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); +#endif + + if (file.ShowModal() == wxID_OK) + { + txtXmlFile->SetValue(file.GetPath()); + OnChange(ev); + } + } +} + +void frmReport::SetReportTitle(const wxString &t) +{ + txtTitle->SetValue(t); +} + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// START STYLESHEET FUNCTIONS +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +wxString frmReport::GetCssLink(const wxString &file) +{ + wxString data; + + data = wxT(" \n"); + + return data; +} + +wxString frmReport::GetEmbeddedCss(const wxString &css) +{ + wxString data; + + data = wxT(" \n"); + + return data; +} + +const wxString frmReport::GetDefaultCss() +{ + wxString data; + + data = wxT(" body { font-family: verdana, helvetica, sans-serif; margin: 0px; padding: 0; }\n") + wxT(" h1 { font-weight: bold; font-size: 150%; border-bottom-style: solid; border-bottom-width: 2px; margin-top: 0px; padding-bottom: 0.5ex; color: #eeeeee; overflow: hidden; text-overflow: ellipsis; }\n") + wxT(" h2 { font-size: 130%; padding-bottom: 0.5ex; color: ") + appearanceFactory->GetReportKeyColour().GetAsString(wxC2S_HTML_SYNTAX) + wxT("; border-bottom-style: solid; border-bottom-width: 2px; }\n") + wxT(" h3 { font-size: 110%; padding-bottom: 0.5ex; color: #000000; }\n") + wxT(" th { text-align: left; background-color: ") + appearanceFactory->GetReportKeyColour().GetAsString(wxC2S_HTML_SYNTAX) + wxT("; color: #eeeeee; }\n") + wxT(" #ReportHeader { padding: 10px; background-color: ") + appearanceFactory->GetReportKeyColour().GetAsString(wxC2S_HTML_SYNTAX) + wxT("; color: #eeeeee; border-bottom-style: solid; border-bottom-width: 2px; border-color: #999999; }\n") + wxT(" #ReportHeader th { width: 25%; white-space: nowrap; vertical-align: top; }\n") + wxT(" #ReportHeader td { vertical-align: top; color: #eeeeee; }\n") + wxT(" #ReportNotes { padding: 10px; background-color: #eeeeee; font-size: 80%; border-bottom-style: solid; border-bottom-width: 2px; border-color: #999999; }\n") + wxT(" .ReportSQL { margin-bottom: 10px; padding: 10px; display: block; background-color: #eeeeee; font-family: monospace; }\n") + wxT(" #ReportDetails { margin-left: 10px; margin-right: 10px; margin-bottom: 10px; }\n") + wxT(" #ReportDetails td, th { font-size: 80%; margin-left: 2px; margin-right: 2px; }\n") + wxT(" #ReportDetails th { border-bottom-color: #777777; border-bottom-style: solid; border-bottom-width: 2px; }\n") + wxT(" .ReportDetailsOddDataRow { background-color: #dddddd; }\n") + wxT(" .ReportDetailsEvenDataRow { background-color: #eeeeee; }\n") + wxT(" .ReportTableHeaderCell { background-color: #dddddd; color: ") + appearanceFactory->GetReportKeyColour().GetAsString(wxC2S_HTML_SYNTAX) + wxT("; vertical-align: top; font-size: 80%; white-space: nowrap; }\n") + wxT(" .ReportTableValueCell { vertical-align: top; font-size: 80%; white-space: nowrap; }\n") + wxT(" .ReportTableInfo { font-size: 80%; font-style: italic; }\n") + wxT(" #ReportFooter { font-weight: bold; font-size: 80%; text-align: right; background-color: ") + appearanceFactory->GetReportKeyColour().GetAsString(wxC2S_HTML_SYNTAX) + wxT("; color: #eeeeee; margin-top: 10px; padding: 2px; border-bottom-style: solid; border-bottom-width: 2px; border-top-style: solid; border-top-width: 2px; border-color: #999999; }\n") + wxT(" #ReportFooter a { color: #ffffff; text-decoration: none; }\n"); + + return data; +} + +wxString frmReport::GetDefaultXsl(const wxString &css) +{ + wxString data; + + data = wxT("\n") + wxT("\n") + wxT("\n") + wxT("\n") + wxT("\n") + wxT("\n") + wxT(" \n") + wxT(" \n") + wxT(" <xsl:value-of select=\"header/title\" />\n") + wxT(" \n") + wxT(" \n"); + data += css; + data += wxT(" \n") + wxT("\n") + wxT(" \n") + wxT("
    \n") + wxT("\n") + wxT(" \n") + wxT("

    \n") + wxT("
    \n") + wxT("\n") + wxT(" \n") + wxT(" "); + data += _("Generated"); + data += wxT(":
    \n") + wxT("
    \n") + wxT("\n") + wxT(" \n") + wxT(" "); + data += _("Server"); + data += wxT(":
    \n") + wxT("
    \n") + wxT("\n") + wxT(" \n") + wxT(" "); + data += _("Database"); + data += wxT(":
    \n") + wxT("
    \n") + wxT("\n") + wxT(" \n") + wxT(" "); + data += _("Catalog"); + data += wxT(":
    \n") + wxT("
    \n") + wxT("\n") + wxT(" \n") + wxT(" "); + data += _("Schema"); + data += wxT(":
    \n") + wxT("
    \n") + wxT("\n") + wxT(" \n") + wxT(" "); + data += _("Table"); + data += wxT(":
    \n") + wxT("
    \n") + wxT("\n") + wxT(" \n") + wxT(" "); + data += _("Job"); + data += wxT(":
    \n") + wxT("
    \n") + wxT("\n") + wxT("
    \n") + wxT("\n") + wxT(" \n") + wxT("
    \n") + wxT(" "); + data += _("Notes"); + data += wxT(":

    \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT("
    \n") + wxT("
    \n") + wxT("\n") + wxT("
    \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT("
    \n") + wxT("\n") + wxT(" \n") + wxT("\n") + wxT("
    \n") + wxT(" \n") + wxT("\n") + wxT("\n") + wxT("
    \n") + wxT("\n") + wxT("\n") + wxT(" \n") + wxT("

    \n") + wxT("
    \n") + wxT("\n") + wxT(" 0\">\n") + wxT("
    \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT("
    \n") + wxT("
    \n") + wxT("
    \n") + wxT(" \n") + wxT("

    \n") + wxT("
    \n") + wxT("
    \n") + wxT("\n") + wxT(" \n") + wxT("
    \n")
    +	        wxT("      \n")
    +	        wxT("         \n")
    +	        wxT("      \n")
    +	        wxT("    
    \n") + wxT("
    \n") + wxT("
    \n") + wxT("\n") + wxT("\n") + wxT(" \n") + wxT(" \n") + wxT(" %\n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT("\n") + wxT("\n") + wxT("\n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" ReportDetailsOddDataRow\n") + wxT(" \n") + wxT(" \n") + wxT(" ReportDetailsEvenDataRow\n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT("\n") + wxT("\n") + wxT("\n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT("\n") + wxT("\n") + wxT("\n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT("
    \n") + wxT("
    \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT("
    \n") + wxT("\n") + wxT("
    \n"); + + return data; +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// END STYLESHEET FUNCTIONS +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// START XML FUNCTIONS +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void frmReport::XmlAddHeaderValue(const wxString &name, const wxString &value) +{ + header += wxT(" <") + HtmlEntities(name) + wxT(">") + HtmlEntities(value) + wxT("\n"); +} + +int frmReport::XmlCreateSection(const wxString &name) +{ + int ind = sectionName.Add(HtmlEntities(name)); + sectionData.Add(wxT("")); + sectionTableHeader.Add(wxT("")); + sectionTableRows.Add(wxT("")); + sectionTableInfo.Add(wxT("")); + sectionSql.Add(wxT("")); + return ind + 1; +} + +void frmReport::XmlSetSectionTableHeader(const int section, int columns, const wxChar *name, ...) +{ + va_list ap; + const wxChar *p = name; + wxString data; + + va_start(ap, name); + + for (int x = 0; x < columns; x++) + { + data += wxT(" \n"); + p = va_arg(ap, wxChar *); + } + + va_end(ap); + + sectionTableHeader[section - 1] = data; +} + +void frmReport::XmlAddSectionTableRow(const int section, int number, int columns, const wxChar *value, ...) +{ + va_list ap; + const wxChar *p = value; + wxString data; + + va_start(ap, value); + + data = wxT(" \n"); + + va_end(ap); + + sectionTableRows[section - 1] += data; +} + +void frmReport::XmlAddSectionTableFromListView(const int section, ctlListView *list) +{ + // Get the column headers + int cols = list->GetColumnCount(); + + wxString data; + wxListItem itm; + + // Build the columns + for (int x = 0; x < cols; x++) + { + itm.SetMask(wxLIST_MASK_TEXT); + list->GetColumn(x, itm); + wxString label = itm.GetText(); + data += wxT(" \n"); + } + sectionTableHeader[section - 1] = data; + + // Build the rows + int rows = list->GetItemCount(); + + for (int y = 0; y < rows; y++) + { + data = wxT(" GetText(y, x)); + data += wxT("\""); + } + data += wxT(" />\n"); + sectionTableRows[section - 1] += data; + } +} + +void frmReport::XmlAddSectionTableFromGrid(const int section, ctlSQLResult *grid) +{ + // Get the column headers + int cols = grid->GetNumberCols(); + int shift = 0; + + wxString data; + wxListItem itm; + + if (grid->GetRowCountSuppressed()) + shift = 1; + + for (int x = 1; x <= cols; x++) + { + wxString label = grid->OnGetItemText(-1, x - shift); + data += wxT(" \n"); + } + sectionTableHeader[section - 1] = data; + + // Build the rows + int rows = grid->NumRows(); + + for (int y = 0; y < rows; y++) + { + data = wxT(" OnGetItemText(y, x - shift)); + data += wxT("\""); + } + data += wxT(" />\n"); + sectionTableRows[section - 1] += data; + } +} + +void frmReport::XmlSetSectionSql(int section, const wxString &sql) +{ + sectionSql[section - 1] = HtmlEntities(sql); + + if (!sectionSql[section - 1].IsEmpty()) + chkSql->Enable(); + else + chkSql->Disable(); +} + +void frmReport::XmlAddSectionValue(const int section, const wxString &name, const wxString &value) +{ + sectionData[section - 1] += wxT(" <") + HtmlEntities(name) + wxT(">") + HtmlEntities(value) + wxT("\n"); +} + +wxString frmReport::GetSectionTableColumns(const int section) +{ + wxString data; + + data = wxT(" \n"); + data += sectionTableHeader[section - 1]; + data += wxT(" \n"); + + return data; +} + +wxString frmReport::GetSectionTableRows(const int section) +{ + wxString data; + + data = wxT(" \n"); + data += sectionTableRows[section - 1]; + data += wxT(" \n"); + + return data; +} + +wxString frmReport::GetSectionTable(const int section) +{ + wxString data; + + data = wxT(" \n"); + data += GetSectionTableColumns(section); + data += GetSectionTableRows(section); + + if (!sectionTableInfo[section - 1].IsEmpty()) + { + data += wxT(" "); + data += sectionTableInfo[section - 1]; + data += wxT("\n"); + } + + data += wxT("
    \n"); + + return data; +} + +wxString frmReport::GetSection(const int section) +{ + wxString data; + + data = wxT("
    \n"); + data += GetSectionTable(section); + + + if (chkSql->GetValue() && !sectionSql[section - 1].IsEmpty()) + { + data += wxT(" "); + data += sectionSql[section - 1]; + data += wxT("\n"); + } + + data += sectionData[section - 1]; + data += wxT("
    \n"); + + return data; +} + +wxString frmReport::GetXmlReport(const wxString &stylesheet = wxT("")) +{ + wxString data; + + data = wxT("\n"); + + if (!stylesheet.IsEmpty()) + { + data += wxT("\n"); + } + + data += wxT("\n"); + data += wxT("\n\n"); + + data += wxT("
    \n"); + data += header; + data += wxT("
    \n\n"); + + for (unsigned int x = 1; x <= sectionName.GetCount(); x++ ) + { + data += GetSection(x); + data += wxT("\n"); + } + + data += wxT("
    \n"); + + return data; +} + +// +// libxml convenience macros +// +#define XML_FROM_WXSTRING(s) ((xmlChar *)(const char *)s.mb_str(wxConvUTF8)) +#define WXSTRING_FROM_XML(s) wxString((char *)s, wxConvUTF8) + +wxString frmReport::XslProcessReport(const wxString &xml, const wxString &xsl) +{ + xmlChar *output = 0; + xmlDocPtr ssDoc = 0, xmlDoc = 0, resDoc = 0; + xsltStylesheetPtr ssPtr = 0; + int length; + + wxBeginBusyCursor(); + + // Apply the stylesheet + xmlSubstituteEntitiesDefault (1); // Substitute entities + xmlLoadExtDtdDefaultValue = 1; // Load external entities + + // Parse the stylesheet + ssDoc = xmlParseDoc(XML_FROM_WXSTRING(xsl)); + if (!ssDoc) + { + wxEndBusyCursor(); + wxLogError(_("Failed to parse the XML stylesheet!")); + goto cleanup; + } + + ssPtr = xsltParseStylesheetDoc(ssDoc); + if (!ssPtr) + { + wxEndBusyCursor(); + wxLogError(_("Failed to parse the XSL stylesheet!")); + goto cleanup; + } + + // Parse the data + xmlDoc = xmlParseDoc(XML_FROM_WXSTRING(xml)); + if (!xmlDoc) + { + wxEndBusyCursor(); + wxLogError(_("Failed to parse the XML document!")); + goto cleanup; + } + + // Apply the stylesheet + resDoc = xsltApplyStylesheet(ssPtr, xmlDoc, NULL); + if (!resDoc) + { + wxEndBusyCursor(); + wxLogError(_("Failed to apply the XSL stylesheet to the XML document!")); + goto cleanup; + } + + // Get the result + xsltSaveResultToString (&output, &length, resDoc, ssPtr); + if (!resDoc) + { + wxEndBusyCursor(); + wxLogError(_("Failed to read the processed document!")); + goto cleanup; + } + +cleanup: + + // Cleanup + if (resDoc) + xmlFreeDoc(resDoc); + + if (xmlDoc) + xmlFreeDoc(xmlDoc); + + if (ssPtr) + xsltFreeStylesheet(ssPtr); + + // This crashes - dunno why :-( + // if (ssDoc) + // xmlFreeDoc(ssDoc); + + xsltCleanupGlobals(); + + wxEndBusyCursor(); + + if (output) + return WXSTRING_FROM_XML(output); + else + return wxEmptyString; +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// END XML FUNCTIONS +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////// +// Report base +/////////////////////////////////////////////////////// +wxWindow *reportBaseFactory::StartDialog(frmMain *form, pgObject *obj) +{ + parent = form; + + wxBeginBusyCursor(); + frmReport *report = new frmReport(GetFrmMain()); + + // Generate the report header + wxDateTime now = wxDateTime::Now(); + report->XmlAddHeaderValue(wxT("generated"), now.Format(wxT("%c"))); + if (obj->GetServer()) + report->XmlAddHeaderValue(wxT("server"), obj->GetServer()->GetFullIdentifier()); + if (obj->GetDatabase()) + report->XmlAddHeaderValue(wxT("database"), obj->GetDatabase()->GetName()); + if (obj->GetSchema()) + { + if (obj->GetSchema()->GetMetaType() == PGM_CATALOG) + report->XmlAddHeaderValue(wxT("catalog"), obj->GetSchema()->GetDisplayName()); + else + report->XmlAddHeaderValue(wxT("schema"), obj->GetSchema()->GetName()); + } + if (obj->GetJob()) + report->XmlAddHeaderValue(wxT("job"), obj->GetJob()->GetName()); + if (obj->GetTable()) + report->XmlAddHeaderValue(wxT("table"), obj->GetTable()->GetName()); + + GenerateReport(report, obj); + wxEndBusyCursor(); + + report->ShowModal(); + return 0; +} + +/////////////////////////////////////////////////////// +// Properties report +/////////////////////////////////////////////////////// +reportObjectPropertiesFactory::reportObjectPropertiesFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) + : reportBaseFactory(list) +{ + mnu->Append(id, _("&Properties Report"), _("Generate a Properties report for this object.")); +} + +bool reportObjectPropertiesFactory::CheckEnable(pgObject *obj) +{ + if (obj) + { + if (obj->IsCollection()) + return false; + else + return true; + } + return false; +} + +void reportObjectPropertiesFactory::GenerateReport(frmReport *report, pgObject *object) +{ + report->SetReportTitle(object->GetTranslatedMessage(PROPERTIESREPORT)); + + int section = report->XmlCreateSection(object->GetTranslatedMessage(PROPERTIES)); + + ctlListView *list = GetFrmMain()->GetProperties(); + object->ShowProperties(); + + report->XmlAddSectionTableFromListView(section, list); + + report->XmlSetSectionSql(section, object->GetSql(NULL)); +} + +/////////////////////////////////////////////////////// +// DDL report +/////////////////////////////////////////////////////// +reportObjectDdlFactory::reportObjectDdlFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) + : reportBaseFactory(list) +{ + mnu->Append(id, _("&DDL Report"), _("Generate a DDL report for this object.")); +} + +bool reportObjectDdlFactory::CheckEnable(pgObject *obj) +{ + if (obj) + { + if (obj->GetMetaType() == PGM_SERVER || obj->GetMetaType() == PGM_CATALOGOBJECT || obj->IsCollection()) + return false; + else + return true; + } + return false; +} + +void reportObjectDdlFactory::GenerateReport(frmReport *report, pgObject *object) +{ + report->SetReportTitle(object->GetTranslatedMessage(DDLREPORT)); + + int section = report->XmlCreateSection(object->GetTranslatedMessage(DDL)); + + report->XmlSetSectionSql(section, object->GetSql(NULL)); +} + +/////////////////////////////////////////////////////// +// Data dictionary report +/////////////////////////////////////////////////////// +reportObjectDataDictionaryFactory::reportObjectDataDictionaryFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) + : reportBaseFactory(list) +{ + mnu->Append(id, _("&Data Dictionary Report"), _("Generate a Data Dictionary report for this object.")); +} + +bool reportObjectDataDictionaryFactory::CheckEnable(pgObject *obj) +{ + if (obj) + { + if ((obj->GetMetaType() == PGM_TABLE || obj->GetMetaType() == GP_PARTITION) && !obj->IsCollection()) + return true; + else + return false; + } + return false; +} + +void reportObjectDataDictionaryFactory::GenerateReport(frmReport *report, pgObject *object) +{ + + pgTable *table = (pgTable *)object; + + report->SetReportTitle(object->GetTranslatedMessage(DATADICTIONNARYREPORT)); + + // Columns + int section = report->XmlCreateSection(_("Columns")); + + report->XmlSetSectionTableHeader(section, 6, (const wxChar *) _("Name"), (const wxChar *) _("Data type"), (const wxChar *) _("Not Null?"), (const wxChar *) _("Primary key?"), (const wxChar *) _("Default"), (const wxChar *) _("Comment")); + + ctlTree *browser = GetFrmMain()->GetBrowser(); + pgCollection *columns = table->GetColumnCollection(browser); + + treeObjectIterator colIt(browser, columns); + + pgColumn *column; + bool haveInherit = false; + wxString colName; + while ((column = (pgColumn *)colIt.GetNextObject()) != 0) + { + column->ShowTreeDetail(browser); + if (column->GetColNumber() > 0) + { + colName = column->GetName(); + if (column->GetInheritedCount() > 0) + { + colName += _("*"); + haveInherit = true; + } + + report->XmlAddSectionTableRow(section, + column->GetColNumber(), + 6, + (const wxChar *) colName, + (const wxChar *) column->GetVarTypename(), + (const wxChar *) BoolToYesNo(column->GetNotNull()), + (const wxChar *) BoolToYesNo(column->GetIsPK()), + (const wxChar *) column->GetDefault(), + (const wxChar *) column->GetComment()); + } + } + if (haveInherit) + { + wxString info; + info.Printf(_("* Inherited columns from %s."), table->GetInheritedTables().c_str()); + report->XmlSetSectionTableInfo(section, info); + } + + // Constraints + pgCollection *constraints = table->GetConstraintCollection(browser); + + treeObjectIterator conIt(browser, constraints); + + pgObject *constraint; + long x = 1; + wxString definition, type; + while ((constraint = (pgObject *)conIt.GetNextObject()) != 0) + { + if (x == 1) + { + section = report->XmlCreateSection(_("Constraints")); + report->XmlSetSectionTableHeader(section, 4, (const wxChar *) _("Name"), (const wxChar *) _("Type"), (const wxChar *) _("Definition"), (const wxChar *) _("Comment")); + } + + constraint->ShowTreeDetail(browser); + + switch (constraint->GetMetaType()) + { + case PGM_PRIMARYKEY: + type = _("Primary key"); + definition = ((pgIndexConstraint *)constraint)->GetDefinition(); + break; + case PGM_UNIQUE: + type = _("Unique"); + definition = ((pgIndexConstraint *)constraint)->GetDefinition(); + break; + case PGM_FOREIGNKEY: + type = _("Foreign key"); + definition = ((pgForeignKey *)constraint)->GetDefinition(); + break; + case PGM_EXCLUDE: + type = _("Exclude"); + definition = ((pgIndexConstraint *)constraint)->GetDefinition(); + break; + case PGM_CHECK: + type = _("Check"); + definition = wxT("(") + ((pgCheck *)constraint)->GetDefinition() + wxT(")"); + break; + } + + report->XmlAddSectionTableRow(section, + x, + 4, + (const wxChar *) constraint->GetName(), + (const wxChar *) type, + (const wxChar *) definition, + (const wxChar *) constraint->GetComment()); + x++; + } +} + +/////////////////////////////////////////////////////// +// Statistics report +/////////////////////////////////////////////////////// +reportObjectStatisticsFactory::reportObjectStatisticsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) + : reportBaseFactory(list) +{ + mnu->Append(id, _("&Statistics Report"), _("Generate a Statistics report for this object.")); +} + +bool reportObjectStatisticsFactory::CheckEnable(pgObject *obj) +{ + if (obj) + { + if (!obj->HasStats()) + { + if (obj->IsCollection()) + { + pgaFactory *f = obj->GetFactory(); + + if (f) + { + if (f->GetMetaType() == PGM_TABLE || + f->GetMetaType() == GP_PARTITION || + f->GetMetaType() == PGM_TABLESPACE || + f->GetMetaType() == PGM_DATABASE) + return true; + } + else + { + return false; + } + } + else + { + return false; + } + + } + else + { + return true; + } + } + + return false; +} + +void reportObjectStatisticsFactory::GenerateReport(frmReport *report, pgObject *object) +{ + report->SetReportTitle(object->GetTranslatedMessage(STATISTICSREPORT)); + + int section = report->XmlCreateSection(object->GetTranslatedMessage(OBJSTATISTICS)); + + ctlListView *list = GetFrmMain()->GetStatistics(); + object->ShowStatistics(GetFrmMain(), list); + + report->XmlAddSectionTableFromListView(section, list); +} + +/////////////////////////////////////////////////////// +// Dependencies report +/////////////////////////////////////////////////////// +reportObjectDependenciesFactory::reportObjectDependenciesFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) + : reportBaseFactory(list) +{ + mnu->Append(id, _("&Dependencies Report"), _("Generate a Dependencies report for this object.")); +} + +bool reportObjectDependenciesFactory::CheckEnable(pgObject *obj) +{ + if (obj) + { + if (!obj->HasDepends()) + return false; + else + return true; + } + return false; +} + +void reportObjectDependenciesFactory::GenerateReport(frmReport *report, pgObject *object) +{ + report->SetReportTitle(object->GetTranslatedMessage(DEPENDENCIESREPORT)); + + int section = report->XmlCreateSection(object->GetTranslatedMessage(DEPENDENCIES)); + + ctlListView *list = GetFrmMain()->GetDependencies(); + object->ShowDependencies(parent, list); + + report->XmlAddSectionTableFromListView(section, list); +} + +/////////////////////////////////////////////////////// +// Dependents report +/////////////////////////////////////////////////////// +reportObjectDependentsFactory::reportObjectDependentsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) + : reportBaseFactory(list) +{ + mnu->Append(id, _("&Dependents Report"), _("Generate a Dependents report for this object.")); +} + +bool reportObjectDependentsFactory::CheckEnable(pgObject *obj) +{ + if (obj) + { + if (!obj->HasReferences()) + return false; + else + return true; + } + return false; +} + +void reportObjectDependentsFactory::GenerateReport(frmReport *report, pgObject *object) +{ + report->SetReportTitle(object->GetTranslatedMessage(DEPENDENTSREPORT)); + + int section = report->XmlCreateSection(object->GetTranslatedMessage(DEPENDENTS)); + + ctlListView *list = GetFrmMain()->GetReferencedBy(); + object->ShowDependents(parent, list); + + report->XmlAddSectionTableFromListView(section, list); +} + +/////////////////////////////////////////////////////// +// Object list report +/////////////////////////////////////////////////////// +reportObjectListFactory::reportObjectListFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) + : reportBaseFactory(list) +{ + mnu->Append(id, _("&Object List Report"), _("Generate an Object List report for this collection.")); +} + +bool reportObjectListFactory::CheckEnable(pgObject *obj) +{ + if (obj) + { + if (!obj->IsCollection()) + { + return false; + } + else + { + pgaFactory *f = obj->GetFactory(); + if (obj) + { + if (f->GetMetaType() == PGM_SERVER) + return false; + } + else + return false; + + return true; + } + } + return false; +} + +void reportObjectListFactory::GenerateReport(frmReport *report, pgObject *object) +{ + report->SetReportTitle(object->GetTranslatedMessage(OBJECTSLISTREPORT)); + + int section = report->XmlCreateSection(object->GetFullIdentifier()); + + ctlListView *list = GetFrmMain()->GetProperties(); + object->ShowProperties(); + + report->XmlAddSectionTableFromListView(section, list); +} + + diff --git a/frm/frmRestore.cpp b/frm/frmRestore.cpp new file mode 100644 index 0000000..769c273 --- /dev/null +++ b/frm/frmRestore.cpp @@ -0,0 +1,896 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmRestore.cpp - Restore database dialogue +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include +#include +#include +#include + + +// App headers +#include "frm/frmRestore.h" +#include "frm/frmMain.h" +#include "utils/sysLogger.h" +#include "schema/pgTable.h" +#include "schema/pgFunction.h" +#include "schema/pgLanguage.h" +#include "schema/pgConstraints.h" +#include "schema/pgForeignKey.h" +#include "ctl/ctlCheckTreeView.h" + +// Icons +#include "images/restore.pngc" + + +#define nbNotebook CTRL_NOTEBOOK("nbNotebook") +#define txtFilename CTRL_TEXT("txtFilename") +#define btnFilename CTRL_BUTTON("btnFilename") +#define cbFormat CTRL_COMBOBOX("cbFormat") +#define cbRolename CTRL_COMBOBOX("cbRolename") +#define chkOnlyData CTRL_CHECKBOX("chkOnlyData") +#define chkOnlySchema CTRL_CHECKBOX("chkOnlySchema") +#define chkNoOwner CTRL_CHECKBOX("chkNoOwner") +#define chkNoPrivileges CTRL_CHECKBOX("chkNoPrivileges") +#define chkNoTablespaces CTRL_CHECKBOX("chkNoTablespaces") +#define chkCreateDb CTRL_CHECKBOX("chkCreateDb") +#define chkClean CTRL_CHECKBOX("chkClean") +#define chkSingleXact CTRL_CHECKBOX("chkSingleXact") +#define chkDisableTrigger CTRL_CHECKBOX("chkDisableTrigger") +#define chkNoDataForFailedTables CTRL_CHECKBOX("chkNoDataForFailedTables") +#define chkUseSetSession CTRL_CHECKBOX("chkUseSetSession") +#define chkExitOnError CTRL_CHECKBOX("chkExitOnError") +#define txtNumberOfJobs CTRL_TEXT("txtNumberOfJobs") +#define chkVerbose CTRL_CHECKBOX("chkVerbose") +#define stSingleObject CTRL_STATIC("stSingleObject") +#define chkSectionPreData CTRL_CHECKBOX("chkSectionPreData") +#define chkSectionData CTRL_CHECKBOX("chkSectionData") +#define chkSectionPostData CTRL_CHECKBOX("chkSectionPostData") +#define ctvObjects CTRL_CHECKTREEVIEW("ctvObjects") +#define btnView CTRL_BUTTON("btnView") + + +BEGIN_EVENT_TABLE(frmRestore, ExternProcessDialog) + EVT_TEXT(XRCID("txtFilename"), frmRestore::OnChangeName) + EVT_COMBOBOX(XRCID("cbFormat"), frmRestore::OnChangeFormat) + EVT_CHECKBOX(XRCID("chkOnlyData"), frmRestore::OnChangeData) + EVT_CHECKBOX(XRCID("chkOnlySchema"), frmRestore::OnChangeSchema) + EVT_BUTTON(XRCID("btnFilename"), frmRestore::OnSelectFilename) + EVT_BUTTON(wxID_OK, frmRestore::OnOK) + EVT_BUTTON(XRCID("btnView"), frmRestore::OnView) + EVT_END_PROCESS(-1, frmRestore::OnEndProcess) + EVT_CLOSE( ExternProcessDialog::OnClose) + EVT_CHECKBOX(XRCID("chkSectionPreData"), frmRestore::OnChangeSection) + EVT_CHECKBOX(XRCID("chkSectionData"), frmRestore::OnChangeSection) + EVT_CHECKBOX(XRCID("chkSectionPostData"), frmRestore::OnChangeSection) +END_EVENT_TABLE() + + + +frmRestore::frmRestore(frmMain *form, pgObject *obj) : ExternProcessDialog(form) +{ + object = obj; + + if (object->GetMetaType() == PGM_SERVER) + server = (pgServer *)object; + else + server = object->GetDatabase()->GetServer(); + + SetFont(settings->GetSystemFont()); + LoadResource(form, wxT("frmRestore")); + RestorePosition(); + + SetTitle(object->GetTranslatedMessage(RESTORETITLE)); + + if (object->GetConnection()->EdbMinimumVersion(8, 0)) + restoreExecutable = edbRestoreExecutable; + else if (object->GetConnection()->GetIsGreenplum()) + restoreExecutable = gpRestoreExecutable; + else + restoreExecutable = pgRestoreExecutable; + + if (object->GetMetaType() != PGM_DATABASE) + { + chkOnlySchema->SetValue(object->GetMetaType() == PGM_FUNCTION + || object->GetMetaType() == PGM_INDEX + || object->GetMetaType() == PGM_TRIGGER); + chkOnlyData->SetValue(object->GetMetaType() == PGM_TABLE + || object->GetMetaType() == GP_PARTITION); + if (object->GetMetaType() != PGM_SCHEMA) + { + chkOnlyData->Disable(); + chkOnlySchema->Disable(); + } + if (object->GetMetaType() == PGM_FUNCTION) + { + chkClean->SetValue(true); + chkClean->Disable(); + } + btnView->Disable(); + } + + wxString val; + settings->Read(wxT("frmRestore/LastFile"), &val, wxEmptyString); + txtFilename->SetValue(val); + + // Icon + SetIcon(*restore_png_ico); + + txtMessages = CTRL_TEXT("txtMessages"); + // Note that under GTK+, SetMaxLength() function may only be used with single line text controls. + // (see http://docs.wxwidgets.org/2.8/wx_wxtextctrl.html#wxtextctrlsetmaxlength) +#ifndef __WXGTK__ + txtMessages->SetMaxLength(0L); +#endif + btnOK->Disable(); + filenameValid = false; + + if (!server->GetPasswordIsStored()) + environment.Add(wxT("PGPASSWORD=") + server->GetPassword()); + + // Pass the SSL mode via the environment + environment.Add(wxT("PGSSLMODE=") + server->GetConnection()->GetSslModeName()); + + if (server->GetSSLRootCert() != wxEmptyString) + environment.Add(wxT("PGSSLROOTCERT=") + server->GetSSLRootCert()); + + if (server->GetSSLCert() != wxEmptyString) + environment.Add(wxT("PGSSLCERT=") + server->GetSSLCert()); + + if (server->GetSSLKey() != wxEmptyString) + environment.Add(wxT("PGSSLKEY=") + server->GetSSLKey()); + + if (server->GetSSLCrl() != wxEmptyString) + environment.Add(wxT("PGSSLCRL=") + server->GetSSLCrl()); + + if (!pgAppMinimumVersion(restoreExecutable, 8, 4)) + { + chkNoTablespaces->Disable(); + chkSingleXact->Disable(); + txtNumberOfJobs->Disable(); + cbRolename->Disable(); + } + else + { + // Available rolenames + if (server->GetConnection()->BackendMinimumVersion(8, 1)) + { + pgSetIterator set(server->GetConnection(), + wxT("SELECT DISTINCT rolname\n") + wxT("FROM pg_roles db\n") + wxT("ORDER BY rolname")); + + cbRolename->Append(wxEmptyString); + + while(set.RowsLeft()) + cbRolename->Append(set.GetVal(wxT("rolname"))); + + cbRolename->SetValue(server->GetRolename()); + cbRolename->Enable(true); + } + else + cbRolename->Disable(); + } + if (!pgAppMinimumVersion(restoreExecutable, 8, 2)) + { + chkNoDataForFailedTables->Disable(); + } + if (!pgAppMinimumVersion(restoreExecutable, 8, 0)) + { + chkExitOnError->Disable(); + } + + cbFormat->Append(_("Custom or tar")); + if (pgAppMinimumVersion(restoreExecutable, 9, 1)) + cbFormat->Append(_("Directory")); + cbFormat->SetSelection(0); + + if (!pgAppMinimumVersion(restoreExecutable, 9, 2)) + { + chkSectionPreData->Disable(); + chkSectionData->Disable(); + chkSectionPostData->Disable(); + } + + wxCommandEvent ev; + OnChangeName(ev); +} + + +frmRestore::~frmRestore() +{ + SavePosition(); +} + + +wxString frmRestore::GetHelpPage() const +{ + wxString page; + page = wxT("pg/app-pgrestore"); + return page; +} + + +void frmRestore::OnSelectFilename(wxCommandEvent &ev) +{ + if (cbFormat->GetSelection() == 0) // custom or tar + { + wxString FilenameOnly; + wxFileName::SplitPath(txtFilename->GetValue(), NULL, NULL, &FilenameOnly, NULL); + +#ifdef __WXMSW__ + wxFileDialog file(this, _("Select backup filename"), ::wxPathOnly(txtFilename->GetValue()), FilenameOnly, + _("Backup files (*.backup)|*.backup|All files (*.*)|*.*")); +#else + wxFileDialog file(this, _("Select backup filename"), ::wxPathOnly(txtFilename->GetValue()), FilenameOnly, + _("Backup files (*.backup)|*.backup|All files (*)|*")); +#endif + + if (file.ShowModal() == wxID_OK) + { + txtFilename->SetValue(file.GetPath()); + OnChange(ev); + } + } + else + { + wxDirDialog dir(this, _("Select the backup directory"), txtFilename->GetValue()); + if (dir.ShowModal() == wxID_OK) + { + txtFilename->SetValue(dir.GetPath()); + OnChange(ev); + } + } +} + + +void frmRestore::OnChangeFormat(wxCommandEvent &ev) +{ + btnView->Enable(cbFormat->GetSelection() == 0); +} + + +void frmRestore::OnChangeData(wxCommandEvent &ev) +{ + chkOnlySchema->Enable(!chkOnlyData->GetValue()); + chkSectionPreData->Enable(!chkOnlyData->GetValue()); + chkSectionData->Enable(!chkOnlyData->GetValue()); + chkSectionPostData->Enable(!chkOnlyData->GetValue()); + + OnChange(ev); +} + + +void frmRestore::OnChangeSchema(wxCommandEvent &ev) +{ + chkOnlyData->Enable(!chkOnlySchema->GetValue()); + chkSectionPreData->Enable(!chkOnlySchema->GetValue()); + chkSectionData->Enable(!chkOnlySchema->GetValue()); + chkSectionPostData->Enable(!chkOnlySchema->GetValue()); + + OnChange(ev); +} + + +void frmRestore::OnChangeSection(wxCommandEvent &ev) +{ + bool isSection = chkSectionPreData->GetValue() || chkSectionData->GetValue() || chkSectionPostData->GetValue(); + + chkOnlySchema->Enable(!isSection); + chkOnlyData->Enable(!isSection); + + OnChange(ev); +} + + +void frmRestore::OnChangeName(wxCommandEvent &ev) +{ + wxString name = txtFilename->GetValue(); + if (cbFormat->GetSelection() == 0) + { + if (name.IsEmpty() || !wxFile::Exists(name)) + filenameValid = false; + else + { + wxFile file(name, wxFile::read); + if (file.IsOpened()) + { + char buffer[8]; + off_t size = file.Read(buffer, 8); + if (size == 8) + { + if (memcmp(buffer, "PGDMP", 5) && !memcmp(buffer, "toc.dat", 8)) + { + // tar format? + file.Seek(512); + size = file.Read(buffer, 8); + } + if (size == 8 && !memcmp(buffer, "PGDMP", 5)) + { + // check version here? + filenameValid = true; + } + } + } + } + } + else + { + filenameValid = wxDir::Exists(name); + } + OnChange(ev); +} + + +void frmRestore::OnChange(wxCommandEvent &ev) +{ + btnOK->Enable(filenameValid); + btnView->Enable(filenameValid && object->GetMetaType() == PGM_DATABASE); +} + + +wxString frmRestore::GetCmd(int step) +{ + wxString cmd = getCmdPart1(); + + return cmd + getCmdPart2(step); +} + + +wxString frmRestore::GetDisplayCmd(int step) +{ + wxString cmd = getCmdPart1(); + + return cmd + getCmdPart2(step); +} + + +wxString frmRestore::getCmdPart1() +{ + wxString cmd; + + cmd = restoreExecutable; + + if (!server->GetName().IsEmpty()) + cmd += wxT(" --host ") + server->GetName(); + + cmd += wxT(" --port ") + NumToStr((long)server->GetPort()) + + wxT(" --username ") + commandLineCleanOption(qtIdent(server->GetUsername())) + + wxT(" --dbname ") + commandLineCleanOption(object->GetDatabase()->GetQuotedIdentifier()); + + if (!cbRolename->GetValue().IsEmpty()) + cmd += wxT(" --role ") + commandLineCleanOption(qtIdent(cbRolename->GetValue())); + + if (pgAppMinimumVersion(restoreExecutable, 8, 4)) + cmd += wxT(" --no-password "); + + return cmd; +} + + +wxString frmRestore::getCmdPart2(int step) +{ + wxString cmd; + + wxString restoreExecutable; + if (object->GetConnection()->EdbMinimumVersion(8, 0)) + restoreExecutable = edbBackupExecutable; + else if (object->GetConnection()->GetIsGreenplum()) + restoreExecutable = gpBackupExecutable; + else + restoreExecutable = pgBackupExecutable; + + if (step) + { + cmd.Append(wxT(" --list")); + } + else + { + if (cbFormat->GetSelection() == 1) // directory + { + cmd.Append(wxT(" --format directory")); + } + + // Section + if (pgAppMinimumVersion(restoreExecutable, 9, 2)) + { + if (chkSectionPreData->GetValue()) + cmd.Append(wxT(" --section pre-data")); + if (chkSectionData->GetValue()) + cmd.Append(wxT(" --section data")); + if (chkSectionPostData->GetValue()) + cmd.Append(wxT(" --section post-data")); + } + + if (chkOnlyData->GetValue()) + { + cmd.Append(wxT(" --data-only")); + } + else + { + if (chkNoOwner->GetValue()) + cmd.Append(wxT(" --no-owner")); + if (chkNoPrivileges->GetValue()) + cmd.Append(wxT(" --no-privileges")); + if (chkNoTablespaces->GetValue()) + cmd.Append(wxT(" --no-tablespaces")); + } + + if (chkOnlySchema->GetValue()) + { + cmd.Append(wxT(" --schema-only")); + } + else + { + if (chkDisableTrigger->GetValue()) + cmd.Append(wxT(" --disable-triggers")); + } + if (chkCreateDb->GetValue()) + cmd.Append(wxT(" --create")); + if (chkClean->GetValue()) + cmd.Append(wxT(" --clean")); + if (chkSingleXact->GetValue()) + cmd.Append(wxT(" --single-transaction")); + if (chkNoDataForFailedTables->GetValue()) + cmd.Append(wxT(" --no-data-for-failed-tables")); + if (chkUseSetSession->GetValue()) + cmd.Append(wxT(" --use-set-session-authorization")); + if (chkExitOnError->GetValue()) + cmd.Append(wxT(" --exit-on-error")); + + if (!txtNumberOfJobs->GetValue().IsEmpty()) + cmd.Append(wxT(" --jobs ") + txtNumberOfJobs->GetValue()); + + // Process selected items + wxTreeItemId root, firstLevelObject, secondLevelObject; + wxTreeItemIdValue firstLevelObjectData, secondLevelObjectData; + bool partialDump = false; + + // Get root object + root = ctvObjects->GetRootItem(); + + if (root && object->GetMetaType() == PGM_DATABASE) + { + // Prepare the array + wxArrayString restoreStrings; + restoreStrings.Add(wxEmptyString, numberOfTOCItems); + restoreTreeItemData *data; + + // Loop through first level objects + firstLevelObject = ctvObjects->GetFirstChild(root, firstLevelObjectData); + while (firstLevelObject.IsOk()) + { + if (ctvObjects->IsChecked(firstLevelObject)) + { + // Write the file + data = (restoreTreeItemData *)ctvObjects->GetItemData(firstLevelObject); + restoreStrings[data->GetId()] = data->GetDesc(); + + // Loop through second level objects + secondLevelObject = ctvObjects->GetFirstChild(firstLevelObject, secondLevelObjectData); + while (secondLevelObject.IsOk()) + { + if (ctvObjects->IsChecked(secondLevelObject)) + { + // Write the file + data = (restoreTreeItemData *)ctvObjects->GetItemData(secondLevelObject); + restoreStrings[data->GetId()] = data->GetDesc(); + } + else + partialDump = true; + secondLevelObject = ctvObjects->GetNextChild(firstLevelObject, secondLevelObjectData); + } + } + else + partialDump = true; + firstLevelObject = ctvObjects->GetNextChild(root, firstLevelObjectData); + } + + // Open a temporary file to store the TOC + restoreTOCFilename = wxFileName::CreateTempFileName(wxT("restore")); + wxFile tocFile; + tocFile.Open(restoreTOCFilename.c_str(), wxFile::write); + + // Write all selected items in it + for (int i = 0; i < numberOfTOCItems; i++) + { + if (restoreStrings[i] != wxEmptyString) + { + if (!tocFile.Write(restoreStrings[i] + wxT("\n"))) + { + wxLogError(_("Error writing to the temporary file ") + restoreTOCFilename); + } + } + } + + // If some items were not checked and if the file still contains something, we have to use the list + if (partialDump && tocFile.Length() > 0) + cmd.Append(wxT(" --use-list \"") + restoreTOCFilename + wxT("\"")); + tocFile.Close(); + } + else if (object->GetMetaType() != PGM_DATABASE) + { + switch (object->GetMetaType()) + { + case PGM_FUNCTION: + cmd.Append(wxT(" --function ") + commandLineCleanOption(qtIdent(object->GetFullName()), true)); + break; + case PGM_INDEX: + cmd.Append(wxT(" --index ") + commandLineCleanOption(object->GetQuotedIdentifier(), true)); + break; + case PGM_TABLE: + cmd.Append(wxT(" --table ") + commandLineCleanOption(object->GetQuotedIdentifier(), true)); + break; + case PGM_TRIGGER: + cmd.Append(wxT(" --trigger ") + commandLineCleanOption(object->GetQuotedIdentifier(), true)); + break; + default: + break; + } + if (object->GetMetaType() == PGM_SCHEMA) + cmd.Append(wxT(" --schema ") + commandLineCleanOption(object->GetQuotedIdentifier(), true)); + else if (pgAppMinimumVersion(restoreExecutable, 8, 2)) + cmd.Append(wxT(" --schema ") + commandLineCleanOption(object->GetSchema()->GetQuotedIdentifier(), true)); + } + + if (settings->GetIgnoreVersion()) + cmd.Append(wxT(" --ignore-version")); + if (chkVerbose->GetValue()) + cmd.Append(wxT(" --verbose")); + } + + + cmd.Append(wxT(" \"") + txtFilename->GetValue() + wxT("\"")); + + return cmd; +} + + +void frmRestore::OnView(wxCommandEvent &ev) +{ + btnView->Disable(); + btnOK->Disable(); + viewRunning = true; + Execute(1, false); + btnOK->SetLabel(_("OK")); + done = 0; +} + + +void frmRestore::OnOK(wxCommandEvent &ev) +{ + if (!done) + { + if (processedFile == txtFilename->GetValue()) + { + if (wxMessageBox(_("Are you sure you wish to run a restore from this file again?"), _("Repeat restore?"), wxICON_QUESTION | wxYES_NO) != wxYES) + return; + } + + processedFile = txtFilename->GetValue(); + } + + settings->Write(wxT("frmRestore/LastFile"), txtFilename->GetValue()); + viewRunning = false; + btnView->Disable(); + + ExternProcessDialog::OnOK(ev); + +} + + +void frmRestore::OnEndProcess(wxProcessEvent &ev) +{ + ExternProcessDialog::OnEndProcess(ev); + + if (done && viewRunning && !ev.GetExitCode()) + { + done = false; + + wxString str = wxTextBuffer::Translate(txtMessages->GetValue(), wxTextFileType_Unix); + + wxStringTokenizer line(str, wxT("\n")); + line.GetNextToken(); + + wxBeginBusyCursor(); + + wxString i18nbackup = _("Backup"); + wxTreeItemId root = ctvObjects->AddRoot(i18nbackup + wxT(" ") + txtFilename->GetValue()); + wxString currentSchema = wxT(""); + wxTreeItemId currentSchemaNode; + wxTreeItemId schemaNode, lastItem, extensionNode; + wxTreeItemIdValue schemaNodeData, extensionNodeData; + numberOfTOCItems = 0; + + while (line.HasMoreTokens()) + { + // Read the next line + str = line.GetNextToken(); + + // If this is the last line, it contains process information - skip it! + if (!line.HasMoreTokens()) + continue; + + // Skip the few lines of comments + if (str.Left(1) == wxT(";") || str.Left(1) == wxT("P")) + continue; + + // Split the line according to spaces + wxStringTokenizer col(str, wxT(" ")); + + // Column 1 (dumpId) + col.GetNextToken(); + + // Column 2 (tableOid) + col.GetNextToken(); + + // Column 3 (oid) + col.GetNextToken(); + + // Column 4 (desc) + // First interesting information: object's type + wxString type = col.GetNextToken(); + + if (type == wxT("DATABASE")) + { + // We are restoring a database, not creating one. So ignore + // this line as there is no valid schema info and move on + // to the next object + continue; + } + else if (type == wxT("PROCEDURAL")) + { + // type for a PL is PROCEDURAL LANGUAGE + // we'll keep the next column for the object's type + type = col.GetNextToken(); + } + else if (type == wxT("SHELL")) + { + // type for a SHELL is SHELL TYPE + // we'll keep both columns for the object's type + type += col.GetNextToken(); + } + else if (type == wxT("OPERATOR")) + { + // type for an operator class is OPERATOR CLASS + // we'll keep the two columns for the object's type + wxString tmp = str.Mid(str.Find(type) + type.Length() + 1, 5); + if (tmp == wxT("CLASS")) + type += wxT(" ") + col.GetNextToken(); + } + else if (type == wxT("SEQUENCE")) + { + // type for a sequence can be SEQUENCE, SEQUENCE OWNED BY or SEQUENCE SET + // we'll keep all these columns for the object's type + wxString tmp = str.Mid(str.Find(type) + type.Length() + 1, 3); + if (tmp == wxT("OWN") || tmp == wxT("SET")) + { + type += wxT(" ") + col.GetNextToken(); + if (type == wxT("SEQUENCE OWNED")) + type += wxT(" ") + col.GetNextToken(); + } + } + else if (type == wxT("FK")) + { + // type for a FK is FK CONSTRAINT + // we'll keep the next column for the object's type + type = col.GetNextToken(); + } + else if (type == wxT("TABLE")) + { + if (col.CountTokens() == 4) + { + // TABLE DATA detected + type += wxT(" ") + col.GetNextToken(); + } + } + // In case of statements like DEFAULT ACL DEFAULT PRIVILEGES FOR TABLES + else if (type == wxT("DEFAULT")) + { + // We do not expect the 'DEFAULT ' pattern here. + if (col.CountTokens() != 3) + { + type += wxT(" ") + col.GetNextToken(); + if (type != wxT("DEFAULT ACL")) + { + wxLogError(wxString::Format(_("Unexpected DEFAULT statement found: '%s'!"), str.c_str())); + continue; + } + } + } + + // Column 5 (namespace) + // Second interesting information: object's schema + wxString schema = col.GetNextToken(); + + // Column 6 (tag) + // Third interesting information: object's qualified name + //wxString name=col.GetNextToken(); + wxString name = str.Mid(str.Find(schema) + schema.Length() + 1).BeforeLast(' '); + + // Column 7 (owner) + // Fourth interesting information: object's owner + wxString owner = str.Mid(str.Find(name) + name.Length() + 1); + + // New method + if (type == wxT("LANGUAGE")) + { + lastItem = ctvObjects->AppendItem(root, wxT("Language ") + name + wxT(" [") + _("owner") + wxT(": ") + owner + wxT("]"), 1); + } + else if (type == wxT("ACL") && schema == wxT("-")) + { + lastItem = ctvObjects->AppendItem(root, type + wxT(" ") + name, 1); + } + else if (type == wxT("CAST")) + { + lastItem = ctvObjects->AppendItem(root, name, 1); + } + else if (type == wxT("SCHEMA")) + { + currentSchema = name; + lastItem = currentSchemaNode = ctvObjects->AppendItem(root, wxT("Schema ") + name, 1); + } + else if (type == wxT("EXTENSION") && (schema == wxT("-") || schema.IsEmpty())) + { + lastItem = ctvObjects->AppendItem(root, + owner.IsEmpty() ? wxT("Extension ") + name : + wxT("Extension ") + name + wxT("[") + _("owner") + wxT(": ") + owner + wxT("]"), 1); + } + else if (type == wxT("COMMENT") && name.StartsWith(wxT("EXTENSION "))) + { + wxString extension = name.SubString(10, name.Length()); + + if (ctvObjects->GetItemText(lastItem) == wxT("Extension ") + extension) + { + extensionNode = lastItem; + } + else + { + wxTreeItemId searchStartNode = root; + + if (schema != wxT("-")) + { + searchStartNode = currentSchemaNode; + if (schema != currentSchema) + { + searchStartNode = ctvObjects->GetFirstChild(root, schemaNodeData); + bool found = false; + while (searchStartNode.IsOk() && !found) + { + if (ctvObjects->GetItemText(searchStartNode) == wxT("Schema ") + schema) + found = true; + else + searchStartNode = ctvObjects->GetNextChild(root, schemaNodeData); + } + + // Found it? + if (!searchStartNode.IsOk()) + { + searchStartNode = schemaNode; + } + else + { + searchStartNode = root; + } + } + } + + extensionNode = ctvObjects->GetFirstChild(searchStartNode, extensionNodeData); + bool found = false; + + while (extensionNode.IsOk() && !found) + { + if (ctvObjects->GetItemText(extensionNode) == wxT("Extension ") + extension) + found = true; + else + extensionNode = ctvObjects->GetNextChild(searchStartNode, schemaNodeData); + } + } + + if (extensionNode.IsOk()) + { + lastItem = ctvObjects->AppendItem(extensionNode, + owner.IsEmpty() ? type + wxT(" Extension ") + extension : + type + wxT(" Extension ") + extension + wxT(" [") + _("owner") + wxT(": ") + owner + wxT("]"), 1); + } + } + else + { + if (schema != currentSchema) + { + // Loop through the nodes to find the schema + schemaNode = ctvObjects->GetFirstChild(root, schemaNodeData); + bool found = false; + while (schemaNode.IsOk() && !found) + { + if (ctvObjects->GetItemText(schemaNode) == wxT("Schema ") + schema) + found = true; + else + schemaNode = ctvObjects->GetNextChild(root, schemaNodeData); + } + + // Found it? + if (schemaNode.IsOk()) + { + currentSchema = schema; + currentSchemaNode = schemaNode; + } + // if we are treating a comment, we use the schema of its + // object (ie, the previous line) + else if (type != wxT("COMMENT")) + { + wxLogError(_("Schema node not found for object ") + type + wxT(" ") + name + wxT(" [") + _("owner") + wxT(": ") + owner + wxT("]")); + } + } + lastItem = ctvObjects->AppendItem(currentSchemaNode, + owner.IsEmpty() ? type + wxT(" ") + name : + type + wxT(" ") + name + wxT(" [") + _("owner") + wxT(": ") + owner + wxT("]"), 1); + } + ctvObjects->SetItemData(lastItem, new restoreTreeItemData(numberOfTOCItems, str)); + numberOfTOCItems++; + } + + wxEndBusyCursor(); + nbNotebook->SetSelection(3); + } + else + { + wxRemoveFile(restoreTOCFilename); + } +} + + +void frmRestore::Go() +{ + txtFilename->SetFocus(); + Show(true); +} + + + +restoreFactory::restoreFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Restore..."), _("Restores a backup from a local file")); +} + + +wxWindow *restoreFactory::StartDialog(frmMain *form, pgObject *obj) +{ + frmRestore *frm = new frmRestore(form, obj); + frm->Go(); + return 0; +} + + +bool restoreFactory::CheckEnable(pgObject *obj) +{ + if (!obj) + return false; + + if (obj->GetConnection() && obj->GetConnection()->EdbMinimumVersion(8, 0)) + return obj->CanCreate() && obj->CanRestore() && !edbRestoreExecutable.IsEmpty(); + else if (obj->GetConnection() && obj->GetConnection()->GetIsGreenplum()) + return obj->CanCreate() && obj->CanRestore() && !gpRestoreExecutable.IsEmpty(); + else + return obj->CanCreate() && obj->CanRestore() && !pgRestoreExecutable.IsEmpty(); +} + + +restoreTreeItemData::restoreTreeItemData(int id, const wxString &desc) +{ + restoreId = id; + restoreDesc = desc; +} diff --git a/frm/frmSplash.cpp b/frm/frmSplash.cpp new file mode 100644 index 0000000..5bf7998 --- /dev/null +++ b/frm/frmSplash.cpp @@ -0,0 +1,83 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmSplash.cpp - Splash Screen +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include + +// App headers +#include "pgAdmin3.h" +#include "frm/frmSplash.h" + + +// Copyright text +#include "copyright.h" +#include "version.h" + +BEGIN_EVENT_TABLE(frmSplash, wxFrame) + EVT_PAINT(frmSplash::OnPaint) + +#ifdef __WXGTK__ + EVT_WINDOW_CREATE(frmSplash::OnWindowCreate) +#endif +END_EVENT_TABLE() + +frmSplash::frmSplash(wxFrame *parent) +#ifndef __WXDEBUG__ + : wxFrame((wxFrame *)NULL, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(100, 100), 0 | wxFRAME_SHAPED | wxSIMPLE_BORDER | wxFRAME_NO_TASKBAR | wxSTAY_ON_TOP) +#else + : wxFrame((wxFrame *)NULL, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(100, 100), 0 | wxFRAME_SHAPED | wxSIMPLE_BORDER | wxFRAME_NO_TASKBAR) +#endif +{ + appearanceFactory->SetIcons(this); + splash = appearanceFactory->GetSplashImage(); + + SetClientSize(splash.GetWidth(), splash.GetHeight()); + +#ifndef __WXGTK__ + SetWindowShape(); +#endif + + CenterOnScreen(); +} + +void frmSplash::SetWindowShape() +{ + wxRegion region(splash); + SetShape(region); +} + +void frmSplash::OnPaint(wxPaintEvent &WXUNUSED(event)) +{ + wxPoint pos = appearanceFactory->GetSplashTextPos(); + + wxPaintDC dc(this); + dc.DrawBitmap(splash, 0, 0, true); + + dc.SetTextForeground(appearanceFactory->GetSplashTextColour()); + dc.SetFont(appearanceFactory->GetSplashTextFont()); + + if (appearanceFactory->IsBranded()) + { + dc.DrawText(_("This program is based on pgAdmin III"), pos); + pos.y += appearanceFactory->GetSplashTextOffset(); + } + dc.DrawText(VERSION_WITHOUT_DATE, pos); + pos.y += appearanceFactory->GetSplashTextOffset(); + dc.DrawText(COPYRIGHT, pos); + pos.y += appearanceFactory->GetSplashTextOffset(); + dc.DrawText(LICENSE, pos); +} + +void frmSplash::OnWindowCreate(wxWindowCreateEvent &WXUNUSED(evt)) +{ + SetWindowShape(); +} diff --git a/frm/frmStatus.cpp b/frm/frmStatus.cpp new file mode 100644 index 0000000..a87ee5a --- /dev/null +++ b/frm/frmStatus.cpp @@ -0,0 +1,3657 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmStatus.cpp - Status Screen +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include +#include +#include +#include + +// wxAUI +#include + +// App headers +#include "frm/frmAbout.h" +#include "frm/frmStatus.h" +#include "frm/frmHint.h" +#include "frm/frmMain.h" +#include "db/pgConn.h" +#include "frm/frmQuery.h" +#include "utils/pgfeatures.h" +#include "schema/pgServer.h" +#include "schema/pgUser.h" +#include "ctl/ctlMenuToolbar.h" +#include "ctl/ctlAuiNotebook.h" +#include "utils/csvfiles.h" + +// Icons +#include "images/clip_copy.pngc" +#include "images/readdata.pngc" +#include "images/query_cancel.pngc" +#include "images/terminate_backend.pngc" +#include "images/delete.pngc" +#include "images/storedata.pngc" +#include "images/down.pngc" +#include "images/up.pngc" + + +#include "db/pgConn.h" + + +#define CTRLID_DATABASE 4200 + + +BEGIN_EVENT_TABLE(frmStatus, pgFrame) + EVT_MENU(MNU_EXIT, frmStatus::OnExit) + + EVT_MENU(MNU_COPY, frmStatus::OnCopy) + EVT_MENU(MNU_COPY_QUERY, frmStatus::OnCopyQuery) + + EVT_MENU(MNU_HELP, frmStatus::OnHelp) + EVT_MENU(MNU_CONTENTS, frmStatus::OnContents) + EVT_MENU(MNU_STATUSPAGE, frmStatus::OnToggleStatusPane) + EVT_MENU(MNU_LOCKPAGE, frmStatus::OnToggleLockPane) + EVT_MENU(MNU_XACTPAGE, frmStatus::OnToggleXactPane) + EVT_MENU(MNU_LOGPAGE, frmStatus::OnToggleLogPane) + EVT_MENU(MNU_QUERYSTATEPAGE, frmStatus::OnToggleQuerystatePane) + EVT_MENU(MNU_QUERYSTATEVERBOSE, frmStatus::OnEmptyAction) + EVT_MENU(MNU_QUERYSTATETIME, frmStatus::OnEmptyAction) + EVT_MENU(MNU_QUERYSTATEBUFFER, frmStatus::OnEmptyAction) + EVT_MENU(MNU_QUERYSTATETRIGGER, frmStatus::OnEmptyAction) + + EVT_MENU(MNU_TOOLBAR, frmStatus::OnToggleToolBar) + EVT_MENU(MNU_DEFAULTVIEW, frmStatus::OnDefaultView) + EVT_MENU(MNU_HIGHLIGHTSTATUS, frmStatus::OnHighlightStatus) + + EVT_AUI_PANE_CLOSE( frmStatus::OnPaneClose) + + EVT_COMBOBOX(CTL_RATECBO, frmStatus::OnRateChange) + EVT_MENU(MNU_REFRESH, frmStatus::OnRefresh) + EVT_MENU(MNU_CANCEL, frmStatus::OnCancelBtn) + EVT_MENU(MNU_TERMINATE, frmStatus::OnTerminateBtn) + EVT_MENU(MNU_COMMIT, frmStatus::OnCommit) + EVT_MENU(MNU_ROLLBACK, frmStatus::OnRollback) + EVT_COMBOBOX(CTL_LOGCBO, frmStatus::OnLoadLogfile) + EVT_BUTTON(CTL_ROTATEBTN, frmStatus::OnRotateLogfile) + + EVT_TIMER(TIMER_REFRESHUI_ID, frmStatus::OnRefreshUITimer) + + EVT_TIMER(TIMER_STATUS_ID, frmStatus::OnRefreshStatusTimer) + EVT_LIST_ITEM_SELECTED(CTL_STATUSLIST, frmStatus::OnSelStatusItem) + EVT_LIST_ITEM_DESELECTED(CTL_STATUSLIST, frmStatus::OnSelStatusItem) + EVT_LIST_COL_CLICK(CTL_STATUSLIST, frmStatus::OnSortStatusGrid) + EVT_LIST_COL_RIGHT_CLICK(CTL_STATUSLIST, frmStatus::OnRightClickStatusGrid) + EVT_LIST_COL_END_DRAG(CTL_STATUSLIST, frmStatus::OnChgColSizeStatusGrid) + + EVT_TIMER(TIMER_LOCKS_ID, frmStatus::OnRefreshLocksTimer) + EVT_LIST_ITEM_SELECTED(CTL_LOCKLIST, frmStatus::OnSelLockItem) + EVT_LIST_ITEM_DESELECTED(CTL_LOCKLIST, frmStatus::OnSelLockItem) + EVT_LIST_COL_CLICK(CTL_LOCKLIST, frmStatus::OnSortLockGrid) + EVT_LIST_COL_RIGHT_CLICK(CTL_LOCKLIST, frmStatus::OnRightClickLockGrid) + EVT_LIST_COL_END_DRAG(CTL_LOCKLIST, frmStatus::OnChgColSizeLockGrid) + + EVT_TIMER(TIMER_XACT_ID, frmStatus::OnRefreshXactTimer) + EVT_LIST_ITEM_SELECTED(CTL_XACTLIST, frmStatus::OnSelXactItem) + EVT_LIST_ITEM_DESELECTED(CTL_XACTLIST, frmStatus::OnSelXactItem) + EVT_LIST_COL_CLICK(CTL_XACTLIST, frmStatus::OnSortXactGrid) + EVT_LIST_COL_RIGHT_CLICK(CTL_XACTLIST, frmStatus::OnRightClickXactGrid) + EVT_LIST_COL_END_DRAG(CTL_XACTLIST, frmStatus::OnChgColSizeXactGrid) + + + + + EVT_TIMER(TIMER_LOG_ID, frmStatus::OnRefreshLogTimer) + EVT_LIST_ITEM_SELECTED(CTL_LOGLIST, frmStatus::OnSelLogItem) + EVT_LIST_ITEM_DESELECTED(CTL_LOGLIST, frmStatus::OnSelLogItem) + + EVT_TIMER(TIMER_QUERYSTATE_ID, frmStatus::OnRefreshQuerystateTimer) + EVT_LIST_COL_RIGHT_CLICK(CTL_QUERYSTATELIST, frmStatus::OnRightClickQuerystateGrid) + EVT_LIST_ITEM_SELECTED(CTL_QUERYSTATELIST, frmStatus::OnSelQuerystateItem) + EVT_LIST_ITEM_DESELECTED(CTL_QUERYSTATELIST, frmStatus::OnSelQuerystateItem) + EVT_LIST_COL_END_DRAG(CTL_QUERYSTATELIST, frmStatus::OnChgColSizeQuerystateGrid) + EVT_COMBOBOX(CTRLID_DATABASE, frmStatus::OnChangeDatabase) + + EVT_CLOSE( frmStatus::OnClose) +END_EVENT_TABLE(); + + +int frmStatus::cboToRate() +{ + int rate = 0; + + if (cbRate->GetValue() == _("Don't refresh")) + rate = 0; + if (cbRate->GetValue() == _("1 second")) + rate = 1; + if (cbRate->GetValue() == _("5 seconds")) + rate = 5; + if (cbRate->GetValue() == _("10 seconds")) + rate = 10; + if (cbRate->GetValue() == _("30 seconds")) + rate = 30; + if (cbRate->GetValue() == _("1 minute")) + rate = 60; + if (cbRate->GetValue() == _("5 minutes")) + rate = 300; + if (cbRate->GetValue() == _("10 minutes")) + rate = 600; + if (cbRate->GetValue() == _("30 minutes")) + rate = 1800; + if (cbRate->GetValue() == _("1 hour")) + rate = 3600; + + return rate; +} + + +wxString frmStatus::rateToCboString(int rate) +{ + wxString rateStr; + + if (rate == 0) + rateStr = _("Don't refresh"); + if (rate == 1) + rateStr = _("1 second"); + if (rate == 5) + rateStr = _("5 seconds"); + if (rate == 10) + rateStr = _("10 seconds"); + if (rate == 30) + rateStr = _("30 seconds"); + if (rate == 60) + rateStr = _("1 minute"); + if (rate == 300) + rateStr = _("5 minutes"); + if (rate == 600) + rateStr = _("10 minutes"); + if (rate == 1800) + rateStr = _("30 minutes"); + if (rate == 3600) + rateStr = _("1 hour"); + + return rateStr; +} + + +frmStatus::frmStatus(frmMain *form, const wxString &_title, pgConn *conn) : pgFrame(NULL, _title) +{ + wxString initquery; + bool highlight = false; + + dlgName = wxT("frmStatus"); + + loaded = false; + + mainForm = form; + connection = conn; + locks_connection = conn; + + statusTimer = 0; + locksTimer = 0; + xactTimer = 0; + logTimer = 0; + + logHasTimestamp = false; + logFormatKnown = false; + + // Only superusers can set these parameters... + pgUser *user = new pgUser(connection->GetUser()); + if (user) + { + if (user->GetSuperuser()) + { + // Make the connection quiet on the logs + if (connection->BackendMinimumVersion(8, 0)) + initquery = wxT("SET log_statement='none';SET log_duration='off';SET log_min_duration_statement=-1;"); + else + initquery = wxT("SET log_statement='off';SET log_duration='off';SET log_min_duration_statement=-1;"); + connection->ExecuteVoid(initquery, false); + } + delete user; + } + + // Notify wxAUI which frame to use + manager.SetManagedWindow(this); + manager.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_TRANSPARENT_DRAG | wxAUI_MGR_ALLOW_ACTIVE_PANE); + + // Set different window's attributes + SetTitle(_title); + appearanceFactory->SetIcons(this); + RestorePosition(-1, -1, 700, 500, 700, 500); + SetMinSize(wxSize(700, 500)); + SetFont(settings->GetSystemFont()); + + // Build menu bar + menuBar = new wxMenuBar(); + + fileMenu = new wxMenu(); + fileMenu->Append(MNU_EXIT, _("E&xit\tCtrl-W"), _("Exit query window")); + + menuBar->Append(fileMenu, _("&File")); + + editMenu = new wxMenu(); + editMenu->Append(MNU_COPY, _("&Copy\tCtrl-C"), _("Copy selected text to clipboard"), wxITEM_NORMAL); + + menuBar->Append(editMenu, _("&Edit")); + + actionMenu = new wxMenu(); + actionMenu->Append(MNU_REFRESH, _("Refresh\tCtrl-R"), _("Refresh the selected panel"), wxITEM_NORMAL); + actionMenu->AppendSeparator(); + actionMenu->Append(MNU_COPY_QUERY, _("Copy to query tool\tCtrl-Shift-C"), _("Open the query tool with the selected query"), wxITEM_NORMAL); + actionMenu->Append(MNU_CANCEL, _("Cancel query\tDel"), _("Cancel the selected query"), wxITEM_NORMAL); + actionMenu->Append(MNU_TERMINATE, _("Terminate backend\tShift-Del"), _("Terminate the selected backend"), wxITEM_NORMAL); + actionMenu->AppendSeparator(); + actionMenu->Append(MNU_COMMIT, _("Commit prepared transaction"), _("Commit the selected prepared transaction"), wxITEM_NORMAL); + actionMenu->Append(MNU_ROLLBACK, _("Rollback prepared transaction"), _("Rollback the selected prepared transaction"), wxITEM_NORMAL); + + menuBar->Append(actionMenu, _("&Action")); + + viewMenu = new wxMenu(); + viewMenu->Append(MNU_STATUSPAGE, _("&Activity\tCtrl-Alt-A"), _("Show or hide the activity tab."), wxITEM_CHECK); + viewMenu->Append(MNU_LOCKPAGE, _("&Locks\tCtrl-Alt-L"), _("Show or hide the locks tab."), wxITEM_CHECK); + viewMenu->Append(MNU_XACTPAGE, _("Prepared &Transactions\tCtrl-Alt-T"), _("Show or hide the prepared transactions tab."), wxITEM_CHECK); + viewMenu->Append(MNU_LOGPAGE, _("Log&file\tCtrl-Alt-F"), _("Show or hide the logfile tab."), wxITEM_CHECK); + viewMenu->AppendSeparator(); + viewMenu->Append(MNU_QUERYSTATEPAGE, _("&Query state\tCtrl-Alt-Q"), _("Show or hide the query state tab."), wxITEM_CHECK); + viewMenu->Append(MNU_QUERYSTATEVERBOSE, _("Append verbose"), _("Append verbose."), wxITEM_CHECK); + viewMenu->Append(MNU_QUERYSTATEBUFFER, _("Append use buffers"), _("Append use buffers."), wxITEM_CHECK); + viewMenu->Append(MNU_QUERYSTATETIME, _("Append real timing"), _("Append real timing."), wxITEM_CHECK); + viewMenu->Append(MNU_QUERYSTATETRIGGER, _("Append triggers"), _("Append triggers."), wxITEM_CHECK); + + viewMenu->AppendSeparator(); + viewMenu->Append(MNU_TOOLBAR, _("Tool&bar\tCtrl-Alt-B"), _("Show or hide the toolbar."), wxITEM_CHECK); + viewMenu->Append(MNU_HIGHLIGHTSTATUS, _("Highlight items of the activity list"), _("Highlight or not the items of the activity list."), wxITEM_CHECK); + viewMenu->AppendSeparator(); + viewMenu->Append(MNU_DEFAULTVIEW, _("&Default view\tCtrl-Alt-V"), _("Restore the default view.")); + + menuBar->Append(viewMenu, _("&View")); + + wxMenu *helpMenu = new wxMenu(); + helpMenu->Append(MNU_CONTENTS, _("&Help contents"), _("Open the helpfile.")); + helpMenu->Append(MNU_HELP, _("&Server status help"), _("Display help on this window.")); + +#ifdef __WXMAC__ + menuFactories = new menuFactoryList(); + aboutFactory *af = new aboutFactory(menuFactories, helpMenu, 0); + wxApp::s_macAboutMenuItemId = af->GetId(); + menuFactories->RegisterMenu(this, wxCommandEventHandler(pgFrame::OnAction)); +#endif + + menuBar->Append(helpMenu, _("&Help")); + + // Setup edit menu + editMenu->Enable(MNU_COPY, false); + + // Finish menu bar + SetMenuBar(menuBar); + + // Set statusBar + statusBar = CreateStatusBar(1); + SetStatusBarPane(-1); + + // Set up toolbar + toolBar = new ctlMenuToolbar(this, -1, wxDefaultPosition, wxDefaultSize, wxTB_FLAT | wxTB_NODIVIDER); + toolBar->SetToolBitmapSize(wxSize(16, 16)); + toolBar->AddTool(MNU_REFRESH, wxEmptyString, *readdata_png_bmp, _("Refresh"), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_COPY, wxEmptyString, *clip_copy_png_bmp, _("Copy selected text to clipboard"), wxITEM_NORMAL); + toolBar->AddTool(MNU_COPY_QUERY, wxEmptyString, *clip_copy_png_bmp, _("Open the query tool with the selected query"), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_CANCEL, wxEmptyString, *query_cancel_png_bmp, _("Cancel query"), wxITEM_NORMAL); + toolBar->AddTool(MNU_TERMINATE, wxEmptyString, *terminate_backend_png_bmp, _("Terminate backend"), wxITEM_NORMAL); + toolBar->AddTool(MNU_COMMIT, wxEmptyString, *storedata_png_bmp, _("Commit transaction"), wxITEM_NORMAL); + toolBar->AddTool(MNU_ROLLBACK, wxEmptyString, *delete_png_bmp, _("Rollback transaction"), wxITEM_NORMAL); + toolBar->AddSeparator(); + cbLogfiles = new wxComboBox(toolBar, CTL_LOGCBO, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, + wxCB_READONLY | wxCB_DROPDOWN); + toolBar->AddControl(cbLogfiles); + btnRotateLog = new wxButton(toolBar, CTL_ROTATEBTN, _("Rotate")); + toolBar->AddControl(btnRotateLog); + toolBar->AddSeparator(); + cbRate = new wxComboBox(toolBar, CTL_RATECBO, wxEmptyString, wxDefaultPosition, wxSize(-1, -1), wxArrayString(), wxCB_READONLY | wxCB_DROPDOWN); + toolBar->AddControl(cbRate); + toolBar->AddSeparator(); + cbDatabase = new ctlComboBoxFix(toolBar, CTRLID_DATABASE, wxDefaultPosition, wxSize(-1, -1), wxCB_READONLY | wxCB_DROPDOWN); + toolBar->AddControl(cbDatabase); + toolBar->Realize(); + + // Append items to cbo + cbRate->Append(_("Don't refresh")); + cbRate->Append(_("1 second")); + cbRate->Append(_("5 seconds")); + cbRate->Append(_("10 seconds")); + cbRate->Append(_("30 seconds")); + cbRate->Append(_("1 minute")); + cbRate->Append(_("5 minutes")); + cbRate->Append(_("10 minutes")); + cbRate->Append(_("30 minutes")); + cbRate->Append(_("1 hour")); + + // Disable toolbar's items + toolBar->EnableTool(MNU_CANCEL, false); + toolBar->EnableTool(MNU_TERMINATE, false); + toolBar->EnableTool(MNU_COMMIT, false); + toolBar->EnableTool(MNU_ROLLBACK, false); + actionMenu->Enable(MNU_CANCEL, false); + actionMenu->Enable(MNU_TERMINATE, false); + actionMenu->Enable(MNU_COMMIT, false); + actionMenu->Enable(MNU_ROLLBACK, false); + cbLogfiles->Enable(false); + btnRotateLog->Enable(false); + + // Add the database combobox + pgSet *dataSet1 = connection->ExecuteSet(wxT("SELECT datname FROM pg_database WHERE datallowconn ORDER BY datname")); + while (!dataSet1->Eof()) + { + cbDatabase->Append(dataSet1->GetVal(wxT("datname"))); + dataSet1->MoveNext(); + } + delete dataSet1; + + // Image list for all listviews + listimages = new wxImageList(13, 8, true, 2); + listimages->Add(*down_png_ico); + listimages->Add(*up_png_ico); + + // Create panel + AddStatusPane(); + AddLockPane(); + AddXactPane(); + AddQuerystatePane(); + AddLogPane(); + + manager.AddPane(toolBar, wxAuiPaneInfo().Name(wxT("toolBar")).Caption(_("Tool bar")).ToolbarPane().Top().LeftDockable(false).RightDockable(false)); + + // Now load the layout + wxString perspective; + settings->Read(wxT("frmStatus/Perspective-") + wxString(FRMSTATUS_PERSPECTIVE_VER), &perspective, FRMSTATUS_DEFAULT_PERSPECTIVE); + manager.LoadPerspective(perspective, true); + + // Reset the captions for the current language + manager.GetPane(wxT("toolBar")).Caption(_("Tool bar")); + manager.GetPane(wxT("Activity")).Caption(_("Activity")); + manager.GetPane(wxT("Locks")).Caption(_("Locks")); + manager.GetPane(wxT("Transactions")).Caption(_("Prepared Transactions")); + manager.GetPane(wxT("Logfile")).Caption(_("Logfile")); + manager.GetPane(wxT("Querystate")).Caption(_("QueryState")); + + // Tell the manager to "commit" all the changes just made + manager.Update(); + + // Sync the View menu options + viewMenu->Check(MNU_STATUSPAGE, manager.GetPane(wxT("Activity")).IsShown()); + viewMenu->Check(MNU_LOCKPAGE, manager.GetPane(wxT("Locks")).IsShown()); + viewMenu->Check(MNU_XACTPAGE, manager.GetPane(wxT("Transactions")).IsShown()); + viewMenu->Check(MNU_LOGPAGE, manager.GetPane(wxT("Logfile")).IsShown()); + pgSet *set = connection->ExecuteSet(wxT("SELECT 1 FROM pg_available_extensions WHERE name='pg_query_state'")); + viewMenu->Enable(MNU_QUERYSTATEPAGE,set->NumRows() == 1); + delete set; + + viewMenu->Check(MNU_TOOLBAR, manager.GetPane(wxT("toolBar")).IsShown()); + + viewMenu->Check(MNU_QUERYSTATEPAGE, manager.GetPane(wxT("Querystate")).IsShown()); + // Read the highlight status checkbox + settings->Read(wxT("frmStatus/HighlightStatus"), &highlight, true); + viewMenu->Check(MNU_HIGHLIGHTSTATUS, highlight); + bool qu_status; + settings->Read(wxT("frmStatus/QuerystateVerboseStatus"), &qu_status, false); + viewMenu->Check(MNU_QUERYSTATEVERBOSE, qu_status); + settings->Read(wxT("frmStatus/QuerystateTimeStatus"), &qu_status, true); + viewMenu->Check(MNU_QUERYSTATETIME, qu_status); + settings->Read(wxT("frmStatus/QuerystateBufferStatus"), &qu_status, true); + viewMenu->Check(MNU_QUERYSTATEBUFFER, qu_status); + settings->Read(wxT("frmStatus/QuerystateTriggerStatus"), &qu_status, true); + viewMenu->Check(MNU_QUERYSTATETRIGGER, qu_status); + + + // Get our PID + backend_pid = connection->GetBackendPID(); + + // Create the refresh timer (quarter of a second) + // This is a horrible hack to get around the lack of a + // PANE_ACTIVATED event in wxAUI. + refreshUITimer = new wxTimer(this, TIMER_REFRESHUI_ID); + refreshUITimer->Start(250); + + // The selected pane is the log pane by default + // so enable/disable the widgets according to this + wxListEvent nullevent; + OnSelLogItem(nullevent); + + // We're good now + loaded = true; +} + + +frmStatus::~frmStatus() +{ + // Delete the refresh timer + delete refreshUITimer; + + // If the status window wasn't launched in standalone mode... + if (mainForm) + mainForm->RemoveFrame(this); + + // Save the window's position + settings->Write(wxT("frmStatus/Perspective-") + wxString(FRMSTATUS_PERSPECTIVE_VER), manager.SavePerspective()); + manager.UnInit(); + SavePosition(); + + // Save the highlight status checkbox + settings->WriteBool(wxT("frmStatus/HighlightStatus"), viewMenu->IsChecked(MNU_HIGHLIGHTSTATUS)); + settings->WriteBool(wxT("frmStatus/QuerystateVerboseStatus"), viewMenu->IsChecked(MNU_QUERYSTATEVERBOSE)); + settings->WriteBool(wxT("frmStatus/QuerystateTimeStatus"), viewMenu->IsChecked(MNU_QUERYSTATETIME)); + settings->WriteBool(wxT("frmStatus/QuerystateBufferStatus"), viewMenu->IsChecked(MNU_QUERYSTATEBUFFER)); + settings->WriteBool(wxT("frmStatus/QuerystateTriggerStatus"), viewMenu->IsChecked(MNU_QUERYSTATETRIGGER)); + + + + // For each current page, save the slider's position and delete the timer + settings->WriteInt(wxT("frmStatus/RefreshStatusRate"), statusRate); + delete statusTimer; + settings->WriteInt(wxT("frmStatus/RefreshLockRate"), locksRate); + delete locksTimer; + if (viewMenu->IsEnabled(MNU_XACTPAGE)) + { + settings->WriteInt(wxT("frmStatus/RefreshXactRate"), xactRate); + if (xactTimer) + { + delete xactTimer; + xactTimer = NULL; + } + } + if (viewMenu->IsEnabled(MNU_LOGPAGE)) + { + settings->WriteInt(wxT("frmStatus/RefreshLogRate"), logRate); + emptyLogfileCombo(); + if (logTimer) + { + delete logTimer; + logTimer = NULL; + } + } + if (viewMenu->IsEnabled(MNU_QUERYSTATEPAGE)) + { + settings->WriteInt(wxT("frmStatus/RefreshQuerystateRate"), querystateRate); + if (querystateTimer) + { + delete querystateTimer; + querystateTimer = NULL; + } + } + + // If connection is still available, delete it + if (locks_connection && locks_connection != connection) + { + if (locks_connection->IsAlive()) + delete locks_connection; + } + if (connection) + { + if (connection->IsAlive()) + delete connection; + } +} + + +void frmStatus::Go() +{ + // Show the window + Show(true); + + // Send RateChange event to launch each timer + wxScrollEvent nullScrollEvent; + if (viewMenu->IsChecked(MNU_STATUSPAGE)) + { + currentPane = PANE_STATUS; + cbRate->SetValue(rateToCboString(statusRate)); + OnRateChange(nullScrollEvent); + } + if (viewMenu->IsChecked(MNU_LOCKPAGE)) + { + currentPane = PANE_LOCKS; + cbRate->SetValue(rateToCboString(locksRate)); + OnRateChange(nullScrollEvent); + } + if (viewMenu->IsEnabled(MNU_XACTPAGE) && viewMenu->IsChecked(MNU_XACTPAGE)) + { + currentPane = PANE_XACT; + cbRate->SetValue(rateToCboString(xactRate)); + OnRateChange(nullScrollEvent); + } + if (viewMenu->IsEnabled(MNU_LOGPAGE) && viewMenu->IsChecked(MNU_LOGPAGE)) + { + currentPane = PANE_LOG; + cbRate->SetValue(rateToCboString(logRate)); + OnRateChange(nullScrollEvent); + } + if (viewMenu->IsEnabled(MNU_QUERYSTATEPAGE) && viewMenu->IsChecked(MNU_QUERYSTATEPAGE)) + { + currentPane = PANE_QUERYSTATE; + cbRate->SetValue(rateToCboString(querystateRate)); + OnRateChange(nullScrollEvent); + } + + // Refresh all pages + wxCommandEvent nullEvent; + OnRefresh(nullEvent); +} + + +void frmStatus::OnClose(wxCloseEvent &event) +{ + Destroy(); +} + + +void frmStatus::OnExit(wxCommandEvent &event) +{ + Destroy(); +} + + +void frmStatus::OnChangeDatabase(wxCommandEvent &ev) +{ + wxString initquery; + + if (locks_connection != connection) + { + delete locks_connection; + } + + locks_connection = new pgConn(connection->GetHostName(), connection->GetService(), connection->GetHostAddr(), cbDatabase->GetValue(), + connection->GetUser(), connection->GetPassword(), connection->GetPort(), connection->GetRole(), connection->GetSslMode(), + 0, connection->GetApplicationName(), connection->GetSSLCert(), connection->GetSSLKey(), connection->GetSSLRootCert(), connection->GetSSLCrl(), + connection->GetSSLCompression()); + + pgUser *user = new pgUser(locks_connection->GetUser()); + if (user) + { + if (user->GetSuperuser()) + { + if (locks_connection->BackendMinimumVersion(8, 0)) + initquery = wxT("SET log_statement='none';SET log_duration='off';SET log_min_duration_statement=-1;"); + else + initquery = wxT("SET log_statement='off';SET log_duration='off';SET log_min_duration_statement=-1;"); + locks_connection->ExecuteVoid(initquery, false); + } + delete user; + } +} + + +void frmStatus::AddStatusPane() +{ + // Create panel + wxPanel *pnlActivity = new wxPanel(this); + + // Create flex grid + wxFlexGridSizer *grdActivity = new wxFlexGridSizer(1, 1, 5, 5); + grdActivity->AddGrowableCol(0); + grdActivity->AddGrowableRow(0); + + // Add the list control +#ifdef __WXMAC__ + // Switch to the generic list control. + // Disable sort on Mac. + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), true); +#endif + wxListCtrl *lstStatus = new wxListCtrl(pnlActivity, CTL_STATUSLIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxSUNKEN_BORDER); + // Now switch back +#ifdef __WXMAC__ + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), false); +#endif + grdActivity->Add(lstStatus, 0, wxGROW, 3); + + // Add the panel to the notebook + manager.AddPane(pnlActivity, + wxAuiPaneInfo(). + Name(wxT("Activity")).Caption(_("Activity")). + CaptionVisible(true).CloseButton(true).MaximizeButton(true). + Dockable(true).Movable(true)); + + // Auto-sizing + pnlActivity->SetSizer(grdActivity); + grdActivity->Fit(pnlActivity); + + // Add each column to the list control + statusList = (ctlListView *)lstStatus; + statusList->AddColumn(_("PID"), 35); + if (connection->BackendMinimumVersion(8, 5)) + statusList->AddColumn(_("Application name"), 70); + statusList->AddColumn(_("Database"), 70); + statusList->AddColumn(_("User"), 70); + if (connection->BackendMinimumVersion(8, 1)) + { + statusList->AddColumn(_("Client"), 70); + statusList->AddColumn(_("Client start"), 80); + } + if (connection->BackendMinimumVersion(7, 4)) + statusList->AddColumn(_("Query start"), 50); + if (connection->BackendMinimumVersion(8, 3)) + statusList->AddColumn(_("TX start"), 50); + if (connection->BackendMinimumVersion(9, 2)) + { + statusList->AddColumn(_("State"), 35); + statusList->AddColumn(_("State change"), 35); + } + if (connection->BackendMinimumVersion(9, 4)) + { + statusList->AddColumn(_("Backend XID"), 35); + statusList->AddColumn(_("Backend XMin"), 35); + } + if (connection->BackendMinimumVersion(9, 6)) + { + statusList->AddColumn(_("W_Event_T"), 35); + statusList->AddColumn(_("W_Event"), 35); + } + statusList->AddColumn(_("Blocked by"), 35); + statusList->AddColumn(_("Query"), 500); + + // Get through the list of columns to build the popup menu + // and reinitialize column's width if we find a saved width + statusPopupMenu = new wxMenu(); + wxListItem item; + item.SetMask(wxLIST_MASK_TEXT); + int savedwidth; + for (int col = 0; col < statusList->GetColumnCount(); col++) + { + // Get column + statusList->GetColumn(col, item); + + // Reinitialize column's width + settings->Read(wxT("frmStatus/StatusPane_") + item.GetText() + wxT("_Width"), &savedwidth, item.GetWidth()); + if (savedwidth > 0) + statusList->SetColumnWidth(col, savedwidth); + else + statusList->SetColumnWidth(col, 0); + statusColWidth[col] = savedwidth; + + // Add new check item on the popup menu + statusPopupMenu->AppendCheckItem(1000 + col, item.GetText()); + statusPopupMenu->Check(1000 + col, statusList->GetColumnWidth(col) > 0); + this->Connect(1000 + col, wxEVT_COMMAND_MENU_SELECTED, + wxCommandEventHandler(frmStatus::OnStatusMenu)); + } + + // Build image list + statusList->SetImageList(listimages, wxIMAGE_LIST_SMALL); + + // Read statusRate configuration + settings->Read(wxT("frmStatus/RefreshStatusRate"), &statusRate, 10); + + // Initialize sort order + statusSortColumn = 1; + statusSortOrder = wxT("ASC"); + + // Create the timer + statusTimer = new wxTimer(this, TIMER_STATUS_ID); +} + + +void frmStatus::AddLockPane() +{ + // Create panel + wxPanel *pnlLock = new wxPanel(this); + + // Create flex grid + wxFlexGridSizer *grdLock = new wxFlexGridSizer(1, 1, 5, 5); + grdLock->AddGrowableCol(0); + grdLock->AddGrowableRow(0); + + // Add the list control +#ifdef __WXMAC__ + // Switch to the generic list control. + // Disable sort on Mac. + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), true); +#endif + wxListCtrl *lstLocks = new wxListCtrl(pnlLock, CTL_LOCKLIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxSUNKEN_BORDER); + // Now switch back +#ifdef __WXMAC__ + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), false); +#endif + grdLock->Add(lstLocks, 0, wxGROW, 3); + + // Add the panel to the notebook + manager.AddPane(pnlLock, + wxAuiPaneInfo(). + Name(wxT("Locks")).Caption(_("Locks")). + CaptionVisible(true).CloseButton(true).MaximizeButton(true). + Dockable(true).Movable(true)); + + // Auto-sizing + pnlLock->SetSizer(grdLock); + grdLock->Fit(pnlLock); + + // Add each column to the list control + lockList = (ctlListView *)lstLocks; + lockList->AddColumn(wxT("PID"), 35); + lockList->AddColumn(_("Database"), 50); + lockList->AddColumn(_("Relation"), 50); + lockList->AddColumn(_("User"), 50); + if (locks_connection->BackendMinimumVersion(8, 3)) + lockList->AddColumn(_("XID"), 50); + lockList->AddColumn(_("TX"), 50); + lockList->AddColumn(_("Mode"), 50); + lockList->AddColumn(_("Granted"), 50); + if (locks_connection->BackendMinimumVersion(7, 4)) + lockList->AddColumn(_("Start"), 50); + lockList->AddColumn(_("Query"), 500); + + // Get through the list of columns to build the popup menu + lockPopupMenu = new wxMenu(); + wxListItem item; + item.SetMask(wxLIST_MASK_TEXT); + int savedwidth; + for (int col = 0; col < lockList->GetColumnCount(); col++) + { + // Get column + lockList->GetColumn(col, item); + + // Reinitialize column's width + settings->Read(wxT("frmStatus/LockPane_") + item.GetText() + wxT("_Width"), &savedwidth, item.GetWidth()); + if (savedwidth > 0) + lockList->SetColumnWidth(col, savedwidth); + else + lockList->SetColumnWidth(col, 0); + lockColWidth[col] = savedwidth; + + // Add new check item on the popup menu + lockPopupMenu->AppendCheckItem(2000 + col, item.GetText()); + lockPopupMenu->Check(2000 + col, lockList->GetColumnWidth(col) > 0); + this->Connect(2000 + col, wxEVT_COMMAND_MENU_SELECTED, + wxCommandEventHandler(frmStatus::OnLockMenu)); + } + + // Build image list + lockList->SetImageList(listimages, wxIMAGE_LIST_SMALL); + + // Read locksRate configuration + settings->Read(wxT("frmStatus/RefreshLockRate"), &locksRate, 10); + + // Initialize sort order + lockSortColumn = 1; + lockSortOrder = wxT("ASC"); + + // Create the timer + locksTimer = new wxTimer(this, TIMER_LOCKS_ID); +} + + +void frmStatus::AddXactPane() +{ + // Create panel + wxPanel *pnlXacts = new wxPanel(this); + + // Create flex grid + wxFlexGridSizer *grdXacts = new wxFlexGridSizer(1, 1, 5, 5); + grdXacts->AddGrowableCol(0); + grdXacts->AddGrowableRow(0); + + // Add the list control +#ifdef __WXMAC__ + // Switch to the generic list control. + // Disable sort on Mac. + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), true); +#endif + wxListCtrl *lstXacts = new wxListCtrl(pnlXacts, CTL_XACTLIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxSUNKEN_BORDER); + // Now switch back +#ifdef __WXMAC__ + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), false); +#endif + grdXacts->Add(lstXacts, 0, wxGROW, 3); + + // Add the panel to the notebook + manager.AddPane(pnlXacts, + wxAuiPaneInfo(). + Name(wxT("Transactions")).Caption(_("Transactions")). + CaptionVisible(true).CloseButton(true).MaximizeButton(true). + Dockable(true).Movable(true)); + + // Auto-sizing + pnlXacts->SetSizer(grdXacts); + grdXacts->Fit(pnlXacts); + + // Add the xact list + xactList = (ctlListView *)lstXacts; + + // We don't need this report if server release is less than 8.1 + // GPDB doesn't have external global transactions. + // Perhaps we should use this display to show our + // global xid to local xid mappings? + if (!connection->BackendMinimumVersion(8, 1) || connection->GetIsGreenplum()) + { + // manager.GetPane(wxT("Transactions")).Show(false); + lstXacts->InsertColumn(lstXacts->GetColumnCount(), _("Message"), wxLIST_FORMAT_LEFT, 800); + lstXacts->InsertItem(lstXacts->GetItemCount(), _("Prepared transactions not available on this server."), -1); + lstXacts->Enable(false); + xactTimer = NULL; + + // We're done + return; + } + + // Add each column to the list control + xactList->AddColumn(wxT("XID"), 50); + xactList->AddColumn(_("Global ID"), 200); + xactList->AddColumn(_("Time"), 100); + xactList->AddColumn(_("Owner"), 50); + xactList->AddColumn(_("Database"), 50); + + // Get through the list of columns to build the popup menu + xactPopupMenu = new wxMenu(); + wxListItem item; + item.SetMask(wxLIST_MASK_TEXT); + int savedwidth; + for (int col = 0; col < xactList->GetColumnCount(); col++) + { + // Get column + xactList->GetColumn(col, item); + + // Reinitialize column's width + settings->Read(wxT("frmStatus/XactPane_") + item.GetText() + wxT("_Width"), &savedwidth, item.GetWidth()); + if (savedwidth > 0) + xactList->SetColumnWidth(col, savedwidth); + else + xactList->SetColumnWidth(col, 0); + xactColWidth[col] = savedwidth; + + // Add new check item on the popup menu + xactPopupMenu->AppendCheckItem(3000 + col, item.GetText()); + xactPopupMenu->Check(3000 + col, xactList->GetColumnWidth(col) > 0); + this->Connect(3000 + col, wxEVT_COMMAND_MENU_SELECTED, + wxCommandEventHandler(frmStatus::OnXactMenu)); + } + + // Build image list + xactList->SetImageList(listimages, wxIMAGE_LIST_SMALL); + + // Read xactRate configuration + settings->Read(wxT("frmStatus/RefreshXactRate"), &xactRate, 10); + + // Initialize sort order + xactSortColumn = 2; + xactSortOrder = wxT("ASC"); + + // Create the timer + xactTimer = new wxTimer(this, TIMER_XACT_ID); +} +void frmStatus::AddQuerystatePane() +{ + // Create panel + wxPanel *pnlQuerystate = new wxPanel(this); + + // Create flex grid + wxFlexGridSizer *grdQuerystate = new wxFlexGridSizer(1, 1, 5, 5); + grdQuerystate->AddGrowableCol(0); + grdQuerystate->AddGrowableRow(0); + + // Add the list control +#ifdef __WXMAC__ + // Switch to the generic list control. + // Disable sort on Mac. + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), true); +#endif + wxListCtrl *lstQuerystate = new wxListCtrl(pnlQuerystate, CTL_QUERYSTATELIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxSUNKEN_BORDER); + // Now switch back +#ifdef __WXMAC__ + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), false); +#endif + grdQuerystate->Add(lstQuerystate, 0, wxGROW, 3); + + // Add the panel to the notebook + manager.AddPane(pnlQuerystate, + wxAuiPaneInfo().Center(). + Name(wxT("Querystate")).Caption(_("Query State")). + CaptionVisible(true).CloseButton(true).MaximizeButton(true). + Dockable(true).Movable(true)); + + // Auto-sizing + pnlQuerystate->SetSizer(grdQuerystate); + grdQuerystate->Fit(pnlQuerystate); + + // Add the xact list + querystateList = (ctlListView *)lstQuerystate; + + // Add each column to the list control + querystateList->AddColumn(wxT("Pid"), 20); + querystateList->AddColumn(wxT("Fn"), 20); + querystateList->AddColumn(_("Query Text"), 200); + querystateList->AddColumn(_("Plan"), 300); + querystateList->AddColumn(wxT("Leader_pid"), 20); + + + // Get through the list of columns to build the popup menu + querystatePopupMenu = new wxMenu(); + wxListItem item; + item.SetMask(wxLIST_MASK_TEXT); + int savedwidth; + for (int col = 0; col < querystateList->GetColumnCount(); col++) + { + // Get column + querystateList->GetColumn(col, item); + + // Reinitialize column's width + settings->Read(wxT("frmStatus/QuerystatePane_") + item.GetText() + wxT("_Width"), &savedwidth, item.GetWidth()); + if (savedwidth > 0) + querystateList->SetColumnWidth(col, savedwidth); + else + querystateList->SetColumnWidth(col, 0); + querystateColWidth[col] = savedwidth; + + // Add new check item on the popup menu + querystatePopupMenu->AppendCheckItem(4000 + col, item.GetText()); + querystatePopupMenu->Check(4000 + col, querystateList->GetColumnWidth(col) > 0); + this->Connect(4000 + col, wxEVT_COMMAND_MENU_SELECTED, + wxCommandEventHandler(frmStatus::OnQuerystateMenu)); + } + + // Build image list + querystateList->SetImageList(listimages, wxIMAGE_LIST_SMALL); + + // Read querystateRate configuration + settings->Read(wxT("frmStatus/RefreshQuerystateRate"), &querystateRate, 10); + + // Initialize sort order + //QuerystateortColumn = 2; + //QuerystateortOrder = wxT("ASC"); + + // Create the timer + querystateTimer = new wxTimer(this, TIMER_QUERYSTATE_ID); + + pgSet *set = connection->ExecuteSet(wxT("SELECT 1 FROM pg_available_extensions WHERE name='pg_query_state'")); + if (set->NumRows() == 1) + viewMenu->Check(MNU_QUERYSTATEPAGE,true); + else + viewMenu->Check(MNU_QUERYSTATEPAGE,false); + delete set; + +} + + +void frmStatus::AddLogPane() +{ + int rc = -1; + wxString hint = HINT_INSTRUMENTATION; + + // Create panel + wxPanel *pnlLog = new wxPanel(this); + + // Create flex grid + wxFlexGridSizer *grdLog = new wxFlexGridSizer(1, 1, 5, 5); + grdLog->AddGrowableCol(0); + grdLog->AddGrowableRow(0); + + // Add the list control +#ifdef __WXMAC__ + // Switch to the generic list control. + // Disable sort on Mac. + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), true); +#endif + wxListCtrl *lstLog = new wxListCtrl(pnlLog, CTL_LOGLIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxSUNKEN_BORDER); + // Now switch back +#ifdef __WXMAC__ + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), false); +#endif + grdLog->Add(lstLog, 0, wxGROW, 3); + + // Add the panel to the notebook + manager.AddPane(pnlLog, + wxAuiPaneInfo().Center(). + Name(wxT("Logfile")).Caption(_("Logfile")). + CaptionVisible(true).CloseButton(true).MaximizeButton(true). + Dockable(true).Movable(true)); + + // Auto-sizing + pnlLog->SetSizer(grdLog); + grdLog->Fit(pnlLog); + + // Add the log list + logList = (ctlListView *)lstLog; + + // We don't need this report (but we need the pane) + // if server release is less than 8.0 or if server has no adminpack + if (!(connection->BackendMinimumVersion(8, 0) && + connection->HasFeature(FEATURE_FILEREAD))) + { + // if the server release is 9.1 or more and the server has no adminpack + if (connection->BackendMinimumVersion(9, 1)) + { + // Search the adminpack extension + pgSet *set = connection->ExecuteSet(wxT("SELECT 1 FROM pg_available_extensions WHERE name='adminpack'")); + if (set->NumRows() == 1) + hint = HINT_INSTRUMENTATION_91_WITH; + else + hint = HINT_INSTRUMENTATION_91_WITHOUT; + delete set; + } + + if (connection->BackendMinimumVersion(8, 0)) + rc = frmHint::ShowHint(this, hint); + + if (rc == HINT_RC_FIX) + connection->ExecuteVoid(wxT("CREATE EXTENSION adminpack"), true); + + if (!connection->HasFeature(FEATURE_FILEREAD, true)) + { + logList->InsertColumn(logList->GetColumnCount(), _("Message"), wxLIST_FORMAT_LEFT, 800); + logList->InsertItem(logList->GetItemCount(), _("Logs are not available for this server."), -1); + logList->Enable(false); + logTimer = NULL; + // We're done + return; + } + } + + // Add each column to the list control + logFormat = connection->ExecuteScalar(wxT("SHOW log_line_prefix")); + if (logFormat == wxT("unset")) + logFormat = wxEmptyString; + logFmtPos = logFormat.Find('%', true); + + if (logFmtPos < 0) + logFormatKnown = true; // log_line_prefix not specified. + else if (!logFmtPos && logFormat.Mid(logFmtPos, 2) == wxT("%t") && logFormat.Length() > 2) // Timestamp at end of log_line_prefix? + { + logFormatKnown = true; + logHasTimestamp = true; + } + else if (connection->GetIsGreenplum()) + { + // Always %m|%u|%d|%p|%I|%X|:- (timestamp w/ millisec) for 3.2.x + // Usually CSV formatted for 3.3 + logFormatKnown = true; + logHasTimestamp = true; + } + + + if (connection->GetIsGreenplum() && connection->BackendMinimumVersion(8, 2, 13)) + { + // Be ready for GPDB CSV format log file + logList->AddColumn(_("Timestamp"), 120); // Room for millisecs + logList->AddColumn(_("Level"), 35); + logList->AddColumn(_("Log entry"), 400); + logList->AddColumn(_("Connection"), 45); + logList->AddColumn(_("Cmd number"), 48); + logList->AddColumn(_("Dbname"), 48); + logList->AddColumn(_("Segment"), 45); + } + else // Non-GPDB or non-CSV format log + { + if (logHasTimestamp) + logList->AddColumn(_("Timestamp"), 100); + + if (logFormatKnown) + logList->AddColumn(_("Level"), 35); + + logList->AddColumn(_("Log entry"), 800); + } + + if (!connection->HasFeature(FEATURE_ROTATELOG)) + btnRotateLog->Disable(); + + // Re-initialize variables + logfileLength = 0; + + // Read logRate configuration + settings->Read(wxT("frmStatus/RefreshLogRate"), &logRate, 10); + + // Create the timer + logTimer = new wxTimer(this, TIMER_LOG_ID); +} + + +void frmStatus::OnCopy(wxCommandEvent &ev) +{ + ctlListView *list; + int row, col; + wxString text; + + switch(currentPane) + { + case PANE_STATUS: + list = statusList; + break; + case PANE_LOCKS: + list = lockList; + break; + case PANE_XACT: + list = xactList; + break; + case PANE_LOG: + list = logList; + break; + case PANE_QUERYSTATE: + list = querystateList; + break; + default: + // This shouldn't happen. + // If it does, it's no big deal, we just need to get out. + return; + break; + } + if (currentPane==PANE_QUERYSTATE) { + for (row = 0; row < list->GetItemCount(); row++) + { + text.Append(list->GetText(row, 3)); + #ifdef __WXMSW__ + text.Append(wxT("\r\n")); + #else + text.Append(wxT("\n")); + #endif + } +// list->GetText(row,3); + } else + { + row = list->GetFirstSelected(); + + while (row >= 0) + { + for (col = 0; col < list->GetColumnCount(); col++) + { + text.Append(list->GetText(row, col) + wxT("\t")); + } + #ifdef __WXMSW__ + text.Append(wxT("\r\n")); + #else + text.Append(wxT("\n")); + #endif + row = list->GetNextSelected(row); + } + } + if (text.Length() > 0 && wxTheClipboard->Open()) + { + wxTheClipboard->SetData(new wxTextDataObject(text)); + wxTheClipboard->Close(); + } +} + + +void frmStatus::OnCopyQuery(wxCommandEvent &ev) +{ + ctlListView *list; + int row, col; + wxString text = wxT(""); + wxString dbname = wxT(""); + unsigned int maxlength; + + // Only the status list shows the query + list = statusList; + + // Get the database + row = list->GetFirstSelected(); + col = connection->BackendMinimumVersion(9, 0) ? 2 : 1; + dbname.Append(list->GetText(row, col)); + + // Get the actual query + row = list->GetFirstSelected(); + text.Append(queries.Item(row)); + + // Check if we have a query whose length is maximum + maxlength = 1024; + if (connection->BackendMinimumVersion(8, 4)) + { + pgSet *set; + set = connection->ExecuteSet(wxT("SELECT setting FROM pg_settings\n") + wxT(" WHERE name='track_activity_query_size'")); + if (set) + { + maxlength = set->GetLong(0); + delete set; + } + } + + if (text.Length() == maxlength) + { + wxLogError(_("The query you copied is at the maximum length.\nIt may have been truncated.")); + } + + // If we have some real query, launch the query tool + if (text.Length() > 0 && dbname.Length() > 0 + && text.Trim() != wxT("") && text.Trim() != wxT("")) + { + pgConn *conn = new pgConn(connection->GetHostName(), connection->GetService(), connection->GetHostAddr(), dbname, + connection->GetUser(), connection->GetPassword(), + connection->GetPort(), connection->GetRole(), connection->GetSslMode(), connection->GetDbOid(), + connection->GetApplicationName(), + connection->GetSSLCert(), connection->GetSSLKey(), connection->GetSSLRootCert(), connection->GetSSLCrl(), + connection->GetSSLCompression()); + if (conn) + { + frmQuery *fq = new frmQuery(mainForm, wxEmptyString, conn, text); + fq->Go(); + mainForm->AddFrame(fq); + } + } +} + + +void frmStatus::OnPaneClose(wxAuiManagerEvent &evt) +{ + if (evt.pane->name == wxT("Activity")) + { + viewMenu->Check(MNU_STATUSPAGE, false); + statusTimer->Stop(); + } + if (evt.pane->name == wxT("Locks")) + { + viewMenu->Check(MNU_LOCKPAGE, false); + locksTimer->Stop(); + } + if (evt.pane->name == wxT("Transactions")) + { + viewMenu->Check(MNU_XACTPAGE, false); + if (xactTimer) + xactTimer->Stop(); + } + if (evt.pane->name == wxT("Logfile")) + { + viewMenu->Check(MNU_LOGPAGE, false); + if (logTimer) + logTimer->Stop(); + } + if (evt.pane->name == wxT("Querystate")) + { + viewMenu->Check(MNU_QUERYSTATEPAGE, false); + if (querystateTimer) + querystateTimer->Stop(); + } +} + + +void frmStatus::OnToggleStatusPane(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_STATUSPAGE)) + { + manager.GetPane(wxT("Activity")).Show(true); + cbRate->SetValue(rateToCboString(statusRate)); + if (statusRate > 0) + statusTimer->Start(statusRate * 1000L); + } + else + { + manager.GetPane(wxT("Activity")).Show(false); + statusTimer->Stop(); + } + + // Tell the manager to "commit" all the changes just made + manager.Update(); +} + + +void frmStatus::OnToggleLockPane(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_LOCKPAGE)) + { + manager.GetPane(wxT("Locks")).Show(true); + cbRate->SetValue(rateToCboString(locksRate)); + if (locksRate > 0) + locksTimer->Start(locksRate * 1000L); + } + else + { + manager.GetPane(wxT("Locks")).Show(false); + locksTimer->Stop(); + } + + // Tell the manager to "commit" all the changes just made + manager.Update(); +} + + +void frmStatus::OnToggleXactPane(wxCommandEvent &event) +{ + if (viewMenu->IsEnabled(MNU_XACTPAGE) && viewMenu->IsChecked(MNU_XACTPAGE)) + { + manager.GetPane(wxT("Transactions")).Show(true); + cbRate->SetValue(rateToCboString(xactRate)); + if (xactRate > 0 && xactTimer) + xactTimer->Start(xactRate * 1000L); + } + else + { + manager.GetPane(wxT("Transactions")).Show(false); + if (xactTimer) + xactTimer->Stop(); + } + + // Tell the manager to "commit" all the changes just made + manager.Update(); +} + + +void frmStatus::OnToggleLogPane(wxCommandEvent &event) +{ + if (viewMenu->IsEnabled(MNU_LOGPAGE) && viewMenu->IsChecked(MNU_LOGPAGE)) + { + manager.GetPane(wxT("Logfile")).Show(true); + cbRate->SetValue(rateToCboString(logRate)); + if (logRate > 0 && logTimer) + logTimer->Start(logRate * 1000L); + } + else + { + manager.GetPane(wxT("Logfile")).Show(false); + if (logTimer) + logTimer->Stop(); + } + + // Tell the manager to "commit" all the changes just made + manager.Update(); +} +void frmStatus::OnToggleQuerystatePane(wxCommandEvent &event) +{ + if (viewMenu->IsEnabled(MNU_QUERYSTATEPAGE) && viewMenu->IsChecked(MNU_QUERYSTATEPAGE)) + { + manager.GetPane(wxT("Querystate")).Show(true); + cbRate->SetValue(rateToCboString(querystateRate)); + if (querystateRate > 0 && querystateTimer) + querystateTimer->Start(querystateRate * 1000L); + } + else + { + manager.GetPane(wxT("Querystate")).Show(false); + if (querystateTimer) + querystateTimer->Stop(); + } + + // Tell the manager to "commit" all the changes just made + manager.Update(); +} + + +void frmStatus::OnToggleToolBar(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_TOOLBAR)) + { + manager.GetPane(wxT("toolBar")).Show(true); + } + else + { + manager.GetPane(wxT("toolBar")).Show(false); + } + + // Tell the manager to "commit" all the changes just made + manager.Update(); +} + + +void frmStatus::OnDefaultView(wxCommandEvent &event) +{ + manager.LoadPerspective(FRMSTATUS_DEFAULT_PERSPECTIVE, true); + + // Reset the captions for the current language + manager.GetPane(wxT("toolBar")).Caption(_("Tool bar")); + manager.GetPane(wxT("Activity")).Caption(_("Activity")); + manager.GetPane(wxT("Locks")).Caption(_("Locks")); + manager.GetPane(wxT("Transactions")).Caption(_("Prepared Transactions")); + manager.GetPane(wxT("Logfile")).Caption(_("Logfile")); + manager.GetPane(wxT("Querystate")).Caption(_("Query State")); + + // tell the manager to "commit" all the changes just made + manager.Update(); + + // Sync the View menu options + viewMenu->Check(MNU_TOOLBAR, manager.GetPane(wxT("toolBar")).IsShown()); + viewMenu->Check(MNU_STATUSPAGE, manager.GetPane(wxT("Activity")).IsShown()); + viewMenu->Check(MNU_LOCKPAGE, manager.GetPane(wxT("Locks")).IsShown()); + viewMenu->Check(MNU_XACTPAGE, manager.GetPane(wxT("Transactions")).IsShown()); + viewMenu->Check(MNU_LOGPAGE, manager.GetPane(wxT("Logfile")).IsShown()); + viewMenu->Check(MNU_QUERYSTATEPAGE, manager.GetPane(wxT("Querystate")).IsShown()); +} + + +void frmStatus::OnHighlightStatus(wxCommandEvent &event) +{ + wxTimerEvent evt; + + OnRefreshStatusTimer(evt); +} +void frmStatus::OnEmptyAction(wxCommandEvent &event) +{ +} + + +void frmStatus::OnHelp(wxCommandEvent &ev) +{ + DisplayHelp(wxT("status"), HELP_PGADMIN); +} + + +void frmStatus::OnContents(wxCommandEvent &ev) +{ + DisplayHelp(wxT("index"), HELP_PGADMIN); +} + +void frmStatus::OnRateChange(wxCommandEvent &event) +{ + wxTimer *timer; + int rate; + + switch(currentPane) + { + case PANE_STATUS: + timer = statusTimer; + rate = cboToRate(); + statusRate = rate; + break; + case PANE_LOCKS: + timer = locksTimer; + rate = cboToRate(); + locksRate = rate; + break; + case PANE_XACT: + timer = xactTimer; + rate = cboToRate(); + xactRate = rate; + break; + case PANE_LOG: + timer = logTimer; + rate = cboToRate(); + logRate = rate; + break; + case PANE_QUERYSTATE: + timer = querystateTimer; + rate = cboToRate(); + querystateRate = rate; + break; + default: + // This shouldn't happen. + // If it does, it's no big deal, we just need to get out. + return; + break; + } + + if (timer) + { + timer->Stop(); + if (rate > 0) + timer->Start(rate * 1000L); + } + OnRefresh(event); +} + + +void frmStatus::OnRefreshUITimer(wxTimerEvent &event) +{ + wxListEvent evt; + + refreshUITimer->Stop(); + + for (unsigned int i = 0; i < manager.GetAllPanes().GetCount(); i++) + { + wxAuiPaneInfo &pane = manager.GetAllPanes()[i]; + + if (pane.HasFlag(wxAuiPaneInfo::optionActive)) + { + if (pane.name == wxT("Activity") && currentPane != PANE_STATUS) + { + OnSelStatusItem(evt); + } + if (pane.name == wxT("Locks") && currentPane != PANE_LOCKS) + { + OnSelLockItem(evt); + } + if (pane.name == wxT("Transactions") && currentPane != PANE_XACT) + { + OnSelXactItem(evt); + } + if (pane.name == wxT("Logfile") && currentPane != PANE_LOG) + { + OnSelLogItem(evt); + } + if (pane.name == wxT("Querystate") && currentPane != PANE_QUERYSTATE) + { + OnSelQuerystateItem(evt); + } + } + } + + refreshUITimer->Start(250); +} + + +void frmStatus::OnRefreshStatusTimer(wxTimerEvent &event) +{ + long pid = 0; + wxString pidcol = connection->BackendMinimumVersion(9, 2) ? wxT("p.pid") : wxT("p.procpid"); + wxString querycol = connection->BackendMinimumVersion(9, 2) ? wxT("query") : wxT("current_query"); + + if (! viewMenu->IsChecked(MNU_STATUSPAGE)) + return; + + checkConnection(); + if (!connection) + { + statusTimer->Stop(); + locksTimer->Stop(); + if (xactTimer) + xactTimer->Stop(); + if (logTimer) + logTimer->Stop(); + if (querystateTimer) + querystateTimer->Stop(); + return; + } + + wxCriticalSectionLocker lock(gs_critsect); + + long row = 0; + wxString q = wxT("SELECT "); + + // PID + q += pidcol + wxT(" AS pid, "); + + // Application name (when available) + if (connection->BackendMinimumVersion(8, 5)) + q += wxT("application_name, "); + + // Database, and user name + q += wxT("p.datname, usename,\n"); + + // Client connection method + if (connection->BackendMinimumVersion(8, 1)) + { + q += wxT("CASE WHEN client_port=-1 THEN 'local pipe' "); + if (connection->BackendMinimumVersion(9, 1)) + q += wxT("WHEN length(client_hostname)>0 THEN client_hostname||':'||client_port "); + q += wxT("ELSE textin(inet_out(client_addr))||':'||client_port END AS client,\n"); + } + + // Backend start timestamp + if (connection->BackendMinimumVersion(8, 1)) + q += wxT("date_trunc('second', backend_start) AS backend_start, "); + + // Query start timestamp (when available) + if (connection->BackendMinimumVersion(9, 2)) + { + q += wxT("CASE WHEN state='active' THEN date_trunc('second', query_start)::text ELSE '' END "); + } + else if (connection->BackendMinimumVersion(7, 4)) + { + q += wxT("CASE WHEN ") + querycol + wxT("='' OR ") + querycol + wxT("='' THEN '' ") + wxT(" ELSE date_trunc('second', query_start)::text END "); + } + else + { + q += wxT("'' "); + } + q += wxT("AS query_start,\n"); + + // Transaction start timestamp + if (connection->BackendMinimumVersion(8, 3)) + q += wxT("date_trunc('second', xact_start) AS xact_start, "); + + // State + if (connection->BackendMinimumVersion(9, 2)) + q += wxT("state, date_trunc('second', state_change) AS state_change, "); + + // Xmin and XID + if (connection->BackendMinimumVersion(9, 4)) + q += wxT("backend_xid::text, backend_xmin::text, "); + + // Blocked by... + q += wxT("(SELECT min(l1.pid) FROM pg_locks l1 WHERE GRANTED AND (") + wxT("relation IN (SELECT relation FROM pg_locks l2 WHERE l2.pid=") + pidcol + wxT(" AND NOT granted)") + wxT(" OR ") + wxT("transactionid IN (SELECT transactionid FROM pg_locks l3 WHERE l3.pid=") + pidcol + wxT(" AND NOT granted)") + wxT(")) AS blockedby,\n"); + + // Query + q += querycol + wxT(" AS query,\n"); + + // Slow query? + if (connection->BackendMinimumVersion(9, 2)) + { + q += wxT("CASE WHEN query_start IS NULL OR state<>'active' THEN false ELSE query_start < now() - '10 seconds'::interval END "); + } + else if (connection->BackendMinimumVersion(7, 4)) + { + q += wxT("CASE WHEN query_start IS NULL OR ") + querycol + wxT(" LIKE '%' THEN false ELSE query_start < now() - '10 seconds'::interval END "); + } + else + { + q += wxT("false"); + } + q += wxT("AS slowquery\n"); + if (connection->BackendMinimumVersion(9, 6)) + { + q += wxT(",wait_event_type,wait_event,v.heap_blks_total,v.heap_blks_vacuumed,v.heap_blks_scanned,v.phase\n"); + q += wxT("FROM pg_stat_activity p LEFT JOIN pg_stat_progress_vacuum v ON p.pid=v.pid "); + } else + { + q += wxT("FROM pg_stat_activity p "); + } + + // And the rest of the query... + + q += wxT("ORDER BY ") + NumToStr((long)statusSortColumn) + wxT(" ") + statusSortOrder; + + pgSet *dataSet1 = connection->ExecuteSet(q); + if (dataSet1) + { + statusBar->SetStatusText(_("Refreshing status list.")); + statusList->Freeze(); + + // Clear the queries array content + queries.Clear(); + + while (!dataSet1->Eof()) + { + pid = dataSet1->GetLong(wxT("pid")); + + // Update the UI + if (pid != backend_pid) + { + // Add the query content to the queries array + queries.Add(dataSet1->GetVal(wxT("query"))); + + if (row >= statusList->GetItemCount()) + { + statusList->InsertItem(row, NumToStr(pid), -1); + row = statusList->GetItemCount() - 1; + } + else + { + statusList->SetItem(row, 0, NumToStr(pid)); + } + + wxString qry = dataSet1->GetVal(wxT("query")); + wxString app_name = dataSet1->GetVal(wxT("application_name")); + if (connection->BackendMinimumVersion(9, 6)) + { + wxString heap_blks_total = dataSet1->GetVal(wxT("heap_blks_total")); + if (!heap_blks_total.IsEmpty()) { + wxString heap_blks_vacuumed = dataSet1->GetVal(wxT("heap_blks_vacuumed")); + wxString heap_blks_scanned = dataSet1->GetVal(wxT("heap_blks_scanned")); + wxString phase = dataSet1->GetVal(wxT("phase")); + double total; + double vac=0; + double proc; + heap_blks_vacuumed.ToDouble(&vac); + if (!phase.CmpNoCase(wxT("scanning heap"))) { + heap_blks_scanned.ToDouble(&vac); + } + heap_blks_total.ToDouble(&total); + proc=vac*100/total; + wxString str; + str.Printf(wxT("%s %5.2f%%"), phase, proc); + app_name=str; + } + + } + int colpos = 1; + if (connection->BackendMinimumVersion(8, 5)) + statusList->SetItem(row, colpos++, app_name); + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("datname"))); + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("usename"))); + + if (connection->BackendMinimumVersion(8, 1)) + { + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("client"))); + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("backend_start"))); + } + if (connection->BackendMinimumVersion(7, 4)) + { + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("query_start"))); + } + + if (connection->BackendMinimumVersion(8, 3)) + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("xact_start"))); + + if (connection->BackendMinimumVersion(9, 2)) + { + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("state"))); + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("state_change"))); + } + + if (connection->BackendMinimumVersion(9, 4)) + { + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("backend_xid"))); + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("backend_xmin"))); + } + if (connection->BackendMinimumVersion(9, 6)) + { + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("wait_event_type"))); + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("wait_event"))); + } + + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("blockedby"))); + statusList->SetItem(row, colpos, qry); + + // Colorize the new line + if (viewMenu->IsChecked(MNU_HIGHLIGHTSTATUS)) + { + statusList->SetItemBackgroundColour(row, + wxColour(settings->GetActiveProcessColour())); + if (qry == wxT("") || qry == wxT(" in transaction0")) + statusList->SetItemBackgroundColour(row, + wxColour(settings->GetIdleProcessColour())); + if (connection->BackendMinimumVersion(9, 2)) + { + if (dataSet1->GetVal(wxT("state")) != wxT("active")) + statusList->SetItemBackgroundColour(row, + wxColour(settings->GetIdleProcessColour())); + } + + if (dataSet1->GetVal(wxT("blockedby")).Length() > 0) + statusList->SetItemBackgroundColour(row, + wxColour(settings->GetBlockedProcessColour())); + if (dataSet1->GetBool(wxT("slowquery"))) + statusList->SetItemBackgroundColour(row, + wxColour(settings->GetSlowProcessColour())); + } + else + statusList->SetItemBackgroundColour(row, *wxWHITE); + + row++; + } + dataSet1->MoveNext(); + } + delete dataSet1; + + while (row < statusList->GetItemCount()) + statusList->DeleteItem(row); + + statusList->Thaw(); + wxListEvent ev; + //OnSelStatusItem(ev); + statusBar->SetStatusText(_("Done.")); + } + else + checkConnection(); +} + + +void frmStatus::OnRefreshLocksTimer(wxTimerEvent &event) +{ + long pid = 0; + + if (! viewMenu->IsChecked(MNU_LOCKPAGE)) + return; + + checkConnection(); + if (!locks_connection) + { + statusTimer->Stop(); + locksTimer->Stop(); + if (xactTimer) + xactTimer->Stop(); + if (logTimer) + logTimer->Stop(); + if (querystateTimer) + querystateTimer->Stop(); + return; + } + + wxCriticalSectionLocker lock(gs_critsect); + + // There are no sort operator for xid before 8.3 + if (!connection->BackendMinimumVersion(8, 3) && lockSortColumn == 5) + { + wxLogError(_("You cannot sort by transaction id on your PostgreSQL release. You need at least 8.3.")); + lockSortColumn = 1; + } + + long row = 0; + wxString sql; + if (locks_connection->BackendMinimumVersion(8, 3)) + { + sql = wxT("SELECT pg_stat_get_backend_pid(svrid) AS pid, ") + wxT("(SELECT datname FROM pg_database WHERE oid = pgl.database) AS dbname, ") + wxT("coalesce(pgc.relname, pgl.relation::text) AS class, ") + wxT("pg_get_userbyid(pg_stat_get_backend_userid(svrid)) as user, ") + wxT("pgl.virtualxid::text, pgl.virtualtransaction::text AS transaction, pgl.mode, pgl.granted, ") + wxT("date_trunc('second', pg_stat_get_backend_activity_start(svrid)) AS query_start, ") + wxT("pg_stat_get_backend_activity(svrid) AS query ") + wxT("FROM pg_stat_get_backend_idset() svrid, pg_locks pgl ") + wxT("LEFT JOIN pg_class pgc ON pgl.relation=pgc.oid ") + wxT("WHERE pgl.pid = pg_stat_get_backend_pid(svrid) ") + wxT("ORDER BY ") + NumToStr((long)lockSortColumn) + wxT(" ") + lockSortOrder; + } + else if (locks_connection->BackendMinimumVersion(7, 4)) + { + sql = wxT("SELECT pg_stat_get_backend_pid(svrid) AS pid, ") + wxT("(SELECT datname FROM pg_database WHERE oid = pgl.database) AS dbname, ") + wxT("coalesce(pgc.relname, pgl.relation::text) AS class, ") + wxT("pg_get_userbyid(pg_stat_get_backend_userid(svrid)) as user, ") + wxT("pgl.transaction, pgl.mode, pgl.granted, ") + wxT("date_trunc('second', pg_stat_get_backend_activity_start(svrid)) AS query_start, ") + wxT("pg_stat_get_backend_activity(svrid) AS query ") + wxT("FROM pg_stat_get_backend_idset() svrid, pg_locks pgl ") + wxT("LEFT JOIN pg_class pgc ON pgl.relation=pgc.oid ") + wxT("WHERE pgl.pid = pg_stat_get_backend_pid(svrid) ") + wxT("ORDER BY ") + NumToStr((long)lockSortColumn) + wxT(" ") + lockSortOrder; + } + else + { + sql = wxT("SELECT pg_stat_get_backend_pid(svrid) AS pid, ") + wxT("(SELECT datname FROM pg_database WHERE oid = pgl.database) AS dbname, ") + wxT("coalesce(pgc.relname, pgl.relation::text) AS class, ") + wxT("pg_get_userbyid(pg_stat_get_backend_userid(svrid)) as user, ") + wxT("pgl.transaction, pgl.mode, pgl.granted, ") + wxT("pg_stat_get_backend_activity(svrid) AS query ") + wxT("FROM pg_stat_get_backend_idset() svrid, pg_locks pgl ") + wxT("LEFT JOIN pg_class pgc ON pgl.relation=pgc.oid ") + wxT("WHERE pgl.pid = pg_stat_get_backend_pid(svrid) ") + wxT("ORDER BY ") + NumToStr((long)lockSortColumn) + wxT(" ") + lockSortOrder; + } + + pgSet *dataSet2 = locks_connection->ExecuteSet(sql); + if (dataSet2) + { + statusBar->SetStatusText(_("Refreshing locks list.")); + lockList->Freeze(); + + while (!dataSet2->Eof()) + { + pid = dataSet2->GetLong(wxT("pid")); + + if (pid != backend_pid) + { + if (row >= lockList->GetItemCount()) + { + lockList->InsertItem(row, NumToStr(pid), -1); + row = lockList->GetItemCount() - 1; + } + else + { + lockList->SetItem(row, 0, NumToStr(pid)); + } + + int colpos = 1; + lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("dbname"))); + lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("class"))); + lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("user"))); + if (locks_connection->BackendMinimumVersion(8, 3)) + lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("virtualxid"))); + lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("transaction"))); + lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("mode"))); + + if (dataSet2->GetVal(wxT("granted")) == wxT("t")) + lockList->SetItem(row, colpos++, _("Yes")); + else + lockList->SetItem(row, colpos++, _("No")); + + wxString qry = dataSet2->GetVal(wxT("query")); + + if (locks_connection->BackendMinimumVersion(7, 4)) + { + if (qry.IsEmpty() || qry == wxT("")) + lockList->SetItem(row, colpos++, wxEmptyString); + else + lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("query_start"))); + } + lockList->SetItem(row, colpos++, qry.Left(250)); + + row++; + } + dataSet2->MoveNext(); + } + + delete dataSet2; + + while (row < lockList->GetItemCount()) + lockList->DeleteItem(row); + + lockList->Thaw(); + wxListEvent ev; + //OnSelLockItem(ev); + statusBar->SetStatusText(_("Done.")); + } + else + checkConnection(); +} + + +void frmStatus::OnRefreshXactTimer(wxTimerEvent &event) +{ + if (! viewMenu->IsEnabled(MNU_XACTPAGE) || ! viewMenu->IsChecked(MNU_XACTPAGE) || !xactTimer) + return; + + checkConnection(); + if (!connection) + { + statusTimer->Stop(); + locksTimer->Stop(); + xactTimer->Stop(); + querystateTimer->Stop(); + if (logTimer) + logTimer->Stop(); + return; + } + + wxCriticalSectionLocker lock(gs_critsect); + + // There are no sort operator for xid before 8.3 + if (!connection->BackendMinimumVersion(8, 3) && xactSortColumn == 1) + { + wxLogError(_("You cannot sort by transaction id on your PostgreSQL release. You need at least 8.3.")); + xactSortColumn = 2; + } + + long row = 0; + wxString sql; + if (connection->BackendMinimumVersion(8, 3)) + sql = wxT("SELECT transaction::text, gid, prepared, owner, database ") + wxT("FROM pg_prepared_xacts ") + wxT("ORDER BY ") + NumToStr((long)xactSortColumn) + wxT(" ") + xactSortOrder; + else + sql = wxT("SELECT transaction, gid, prepared, owner, database ") + wxT("FROM pg_prepared_xacts ") + wxT("ORDER BY ") + NumToStr((long)xactSortColumn) + wxT(" ") + xactSortOrder; + + pgSet *dataSet3 = connection->ExecuteSet(sql); + if (dataSet3) + { + statusBar->SetStatusText(_("Refreshing transactions list.")); + xactList->Freeze(); + + while (!dataSet3->Eof()) + { + long xid = dataSet3->GetLong(wxT("transaction")); + + if (row >= xactList->GetItemCount()) + { + xactList->InsertItem(row, NumToStr(xid), -1); + row = xactList->GetItemCount() - 1; + } + else + { + xactList->SetItem(row, 0, NumToStr(xid)); + } + + int colpos = 1; + xactList->SetItem(row, colpos++, dataSet3->GetVal(wxT("gid"))); + xactList->SetItem(row, colpos++, dataSet3->GetVal(wxT("prepared"))); + xactList->SetItem(row, colpos++, dataSet3->GetVal(wxT("owner"))); + xactList->SetItem(row, colpos++, dataSet3->GetVal(wxT("database"))); + + row++; + dataSet3->MoveNext(); + } + delete dataSet3; + + while (row < xactList->GetItemCount()) + xactList->DeleteItem(row); + + xactList->Thaw(); + wxListEvent ev; + //OnSelXactItem(ev); + statusBar->SetStatusText(_("Done.")); + } + else + checkConnection(); +} +long frmStatus::getlongvalue(wxString source,wxString match_str) { + long aa=0; + wxRegEx foundstr(match_str); + if (foundstr.Matches(source)) { + wxString v=foundstr.GetMatch(source,1); + v.ToLong(&aa); + } + return aa; +} + + +void frmStatus::OnRefreshQuerystateTimer(wxTimerEvent &event) +{ + if (! viewMenu->IsEnabled(MNU_QUERYSTATEPAGE) || ! viewMenu->IsChecked(MNU_QUERYSTATEPAGE) || !querystateTimer) + return; + + checkConnection(); + if (!connection) + { + statusTimer->Stop(); + locksTimer->Stop(); + xactTimer->Stop(); + if (querystateTimer) + querystateTimer->Stop(); + if (logTimer) + logTimer->Stop(); + return; + } + int row = statusList->GetFirstSelected(); + if (row<0) + return; + wxString pid=statusList->GetText(row, 0); + wxString dbname=statusList->GetText(row, 2); // dbname + if (dbname.IsEmpty()) return; + + wxString flags=wxT(""); + if (viewMenu->IsChecked(MNU_QUERYSTATEVERBOSE)) + flags += wxT(",true,false"); + else + flags += wxT(",false,false"); + if (viewMenu->IsChecked(MNU_QUERYSTATETIME)) + flags += wxT(",true"); + else + flags += wxT(",false"); + if (viewMenu->IsChecked(MNU_QUERYSTATEBUFFER)) + flags += wxT(",true"); + else + flags += wxT(",false"); + if (viewMenu->IsChecked(MNU_QUERYSTATETRIGGER)) + flags += wxT(",true"); + else + flags += wxT(",false"); + + flags += wxT(",'text'::text"); + wxCriticalSectionLocker lock(gs_critsect); + + row = 0; + wxString sql; + sql = wxT("select pid,frame_number,query_text,unnest(string_to_array(plan, E'\n')) pln,leader_pid from pg_query_state(") + +pid+flags+wxT(") s"); + + pgSet *dataSet3 = connection->ExecuteSet(sql); + if (dataSet3) + { + statusBar->SetStatusText(_("Refreshing query state list.")); + querystateList->Freeze(); + long prev_fn=100000000; + while (!dataSet3->Eof()&&dataSet3->NumCols()>0) + { + long pid = dataSet3->GetLong(wxT("pid")); + + if (row >= querystateList->GetItemCount()) + { + querystateList->InsertItem(row, NumToStr(pid), -1); + row = querystateList->GetItemCount() - 1; + } + else + { + querystateList->SetItem(row, 0, NumToStr(pid)); + } + + int colpos = 1; + long fn=dataSet3->GetLong(wxT("frame_number")); + querystateList->SetItem(row, colpos++, NumToStr(fn)); + querystateList->SetItem(row, colpos++, dataSet3->GetVal(wxT("query_text"))); + wxString p=dataSet3->GetVal(wxT("pln")); + querystateList->SetItem(row, colpos++, p); + querystateList->SetItem(row, colpos++, dataSet3->GetVal(wxT("leader_pid"))); + if (prev_fn==fn) { + querystateList->SetItem(row, 1, wxT("")); + querystateList->SetItem(row, 2, wxT("")); + } + wxColour wc; + if (p.Find(wxT("->"))<0) { + wc=*wxWHITE; + if (getlongvalue(p,wxT("Rows Removed by Join Filter: ([0-9]+)"))>1000000) { + wc=wxColour(201,83,2); + //querystateList->SetItemBackgroundColour(row, wxColour(201,83,2)); + } + + querystateList->SetItemBackgroundColour(row, wc); + //querystateList->SetItemBackgroundColour(row, ); + } else + { + if (getlongvalue(p,wxT("actual rows=([0-9]+)"))>1000000) { + querystateList->SetItemBackgroundColour(row, wxColour(255,174,200)); // red + } else + querystateList->SetItemBackgroundColour(row, wxColour(224,255,224)); // gren + } + + row++; + prev_fn=fn; + dataSet3->MoveNext(); + } + delete dataSet3; + + while (row < querystateList->GetItemCount()) + querystateList->DeleteItem(row); + + querystateList->Thaw(); + wxListEvent ev; + //OnSelQuerystateItem(ev); + statusBar->SetStatusText(_("Done.")); + } + else + checkConnection(); +} + + +void frmStatus::OnRefreshLogTimer(wxTimerEvent &event) +{ + if (! viewMenu->IsEnabled(MNU_LOGPAGE) || ! viewMenu->IsChecked(MNU_LOGPAGE) || !logTimer) + return; + + checkConnection(); + if (!connection) + { + statusTimer->Stop(); + locksTimer->Stop(); + if (xactTimer) + xactTimer->Stop(); + logTimer->Stop(); + return; + } + + wxCriticalSectionLocker lock(gs_critsect); + + if (connection->GetLastResultError().sql_state == wxT("42501")) + { + // Don't have superuser privileges, so can't do anything with the log display + logTimer->Stop(); + cbLogfiles->Disable(); + btnRotateLog->Disable(); + manager.GetPane(wxT("Logfile")).Show(false); + manager.Update(); + return; + } + + long newlen = 0; + + if (logDirectory.IsEmpty()) + { + // freshly started + logDirectory = connection->ExecuteScalar(wxT("SHOW log_directory")); + if (connection->GetLastResultError().sql_state == wxT("42501")) + { + // Don't have superuser privileges, so can't do anything with the log display + logTimer->Stop(); + cbLogfiles->Disable(); + btnRotateLog->Disable(); + manager.GetPane(wxT("Logfile")).Show(false); + manager.Update(); + return; + } + if (fillLogfileCombo()) + { + savedPartialLine.Clear(); + cbLogfiles->SetSelection(0); + wxCommandEvent ev; + OnLoadLogfile(ev); + return; + } + else + { + logDirectory = wxT("-"); + if (connection->BackendMinimumVersion(8, 3)) + logList->AppendItem(-1, wxString(_("logging_collector not enabled or log_filename misconfigured"))); + else + logList->AppendItem(-1, wxString(_("redirect_stderr not enabled or log_filename misconfigured"))); + cbLogfiles->Disable(); + btnRotateLog->Disable(); + } + } + + if (logDirectory == wxT("-")) + return; + + if (isCurrent) + { + // check if the current logfile changed + pgSet *set = connection->ExecuteSet(wxT("SELECT pg_file_length(") + connection->qtDbString(logfileName) + wxT(") AS len")); + if (set) + { + newlen = set->GetLong(wxT("len")); + delete set; + } + else + { + checkConnection(); + return; + } + if (newlen > logfileLength) + { + statusBar->SetStatusText(_("Refreshing log list.")); + addLogFile(logfileName, logfileTimestamp, newlen, logfileLength, false); + statusBar->SetStatusText(_("Done.")); + + // as long as there was new data, the logfile is probably the current + // one so we don't need to check for rotation + return; + } + } + + // + wxString newDirectory = connection->ExecuteScalar(wxT("SHOW log_directory")); + + int newfiles = 0; + if (newDirectory != logDirectory) + cbLogfiles->Clear(); + + newfiles = fillLogfileCombo(); + + if (newfiles) + { + if (!showCurrent) + isCurrent = false; + + if (isCurrent) + { + int pos = cbLogfiles->GetCount() - newfiles; + bool skipFirst = true; + + while (newfiles--) + { + addLogLine(_("pgadmin:Logfile rotated."), false); + wxDateTime *ts = (wxDateTime *)cbLogfiles->wxItemContainer::GetClientData(pos++); + wxASSERT(ts != 0); + + addLogFile(ts, skipFirst); + skipFirst = false; + + pos++; + } + } + } +} + + +void frmStatus::OnRefresh(wxCommandEvent &event) +{ + wxTimerEvent evt; + + OnRefreshStatusTimer(evt); + OnRefreshLocksTimer(evt); + OnRefreshXactTimer(evt); + OnRefreshLogTimer(evt); + OnRefreshQuerystateTimer(evt); +} + + +void frmStatus::checkConnection() +{ + if (!locks_connection->IsAlive()) + { + locks_connection = connection; + } + if (!connection->IsAlive()) + { + delete connection; + connection = 0; + statusTimer->Stop(); + locksTimer->Stop(); + if (xactTimer) + xactTimer->Stop(); + if (logTimer) + logTimer->Stop(); + if (querystateTimer) + querystateTimer->Stop(); + actionMenu->Enable(MNU_REFRESH, false); + toolBar->EnableTool(MNU_REFRESH, false); + statusBar->SetStatusText(_("Connection broken.")); + } +} + + +void frmStatus::addLogFile(wxDateTime *dt, bool skipFirst) +{ + pgSet *set = connection->ExecuteSet( + wxT("SELECT filetime, filename, pg_file_length(filename) AS len ") + wxT(" FROM pg_logdir_ls() AS A(filetime timestamp, filename text) ") + wxT(" WHERE filetime = '") + DateToAnsiStr(*dt) + wxT("'::timestamp")); + if (set) + { + logfileName = set->GetVal(wxT("filename")); + logfileTimestamp = set->GetDateTime(wxT("filetime")); + long len = set->GetLong(wxT("len")); + + logfileLength = 0; + addLogFile(logfileName, logfileTimestamp, len, logfileLength, skipFirst); + + delete set; + } +} + + +void frmStatus::addLogFile(const wxString &filename, const wxDateTime timestamp, long len, long &read, bool skipFirst) +{ + wxString line; + + if (skipFirst) + { + long maxServerLogSize = settings->GetMaxServerLogSize(); + + if (!logfileLength && maxServerLogSize && logfileLength > maxServerLogSize) + { + long maxServerLogSize = settings->GetMaxServerLogSize(); + len = read - maxServerLogSize; + } + else + skipFirst = false; + } + + // If GPDB 3.3 and later, log is normally in CSV format. Let's get a whole log line before calling addLogLine, + // so we can do things smarter. + + // PostgreSQL can log in CSV format, as well as regular format. Normally, we'd only see + // the regular format logs here, because pg_logdir_ls only returns those. But if pg_logdir_ls is + // changed to return the csv format log files, we should handle it. + + bool csv_log_format = filename.Right(4) == wxT(".csv"); + + if (csv_log_format && savedPartialLine.length() > 0) + { + if (read == 0) // Starting at beginning of log file + savedPartialLine.clear(); + else + line = savedPartialLine; + } + + while (len > read) + { + statusBar->SetStatusText(_("Reading log from server...")); + pgSet *set = connection->ExecuteSet(wxT("SELECT pg_file_read(") + + connection->qtDbString(filename) + wxT(", ") + NumToStr(read) + wxT(", 50000)")); + if (!set) + { + connection->IsAlive(); + return; + } + char *raw = set->GetCharPtr(0); + + if (!raw || !*raw) + { + delete set; + break; + } + + read += strlen(raw); + + wxString str; + if (wxString(wxString(raw, wxConvLibc).wx_str(), wxConvUTF8).Len() > 0) + str = line + wxString(wxString(raw, wxConvLibc).wx_str(), wxConvUTF8); + else + str = line + wxTextBuffer::Translate(wxString(raw, set->GetConversion()), wxTextFileType_Unix); + + delete set; + + if (str.Len() == 0) + { + wxString msgstr = _("The server log contains entries in multiple encodings and cannot be displayed by pgAdmin."); + wxMessageBox(msgstr); + return; + } + + if (csv_log_format) + { + // This will work for any DB using CSV format logs + + if (logHasTimestamp) + { + // Right now, csv format logs from GPDB and PostgreSQL always start with a timestamp, so we count on that. + + // And the only reason we need to do that is to make sure we are in sync. + + // Bad things happen if we start in the middle of a + // double-quoted string, as we would never find a correct line terminator! + + // In CSV logs, the first field must be a Timestamp, so must start with "2009" or "201" or "202" (at least for the next 20 years). + if (str.length() > 4 && str.Left(4) != wxT("2009") && str.Left(3) != wxT("201") && str.Left(3) != wxT("202")) + { + wxLogNotice(wxT("Log line does not start with timestamp: %s \n"), str.Mid(0, 100).c_str()); + // Something isn't right, as we are not at the beginning of a csv log record. + // We should never get here, but if we do, try to handle it in a smart way. + str = str.Mid(str.Find(wxT("\n20")) + 1); // Try to re-sync. + } + } + + CSVLineTokenizer tk(str); + + logList->Freeze(); + + while (tk.HasMoreLines()) + { + line.Clear(); + + bool partial; + str = tk.GetNextLine(partial); + if (partial) + { + line = str; // Start of a log line, but not complete. Loop back, Read more data. + break; + } + + // Some extra debug checking, assuming csv logs line start with timestamps. + // Not really necessary, but it is good for debugging if something isn't right. + if (logHasTimestamp) + { + // The first field must be a Timestamp, so must start with "2009" or "201" or "202" (at least for the next 20 years). + // This is just an extra check to make sure we haven't gotten out of sync with the log. + if (str.length() > 5 && str.Left(4) != wxT("2009") && str.Left(3) != wxT("201") && str.Left(3) != wxT("202")) + { + // BUG: We are out of sync on the log + wxLogNotice(wxT("Log line does not start with timestamp: %s\n"), str.c_str()); + } + else if (str.length() < 20) + { + // BUG: We are out of sync on the log, or the log is garbled + wxLogNotice(wxT("Log line too short: %s\n"), str.c_str()); + } + } + + // Looks like we have a good complete CSV log record. + addLogLine(str.Trim(), true, true); + } + + logList->Thaw(); + } + else + { + // Non-csv format log file + + bool hasCr = (str.Right(1) == wxT("\n")); + + wxStringTokenizer tk(str, wxT("\n")); + + logList->Freeze(); + + while (tk.HasMoreTokens()) + { + str = tk.GetNextToken(); + if (skipFirst) + { + // could be truncated + skipFirst = false; + continue; + } + + if (tk.HasMoreTokens() || hasCr) + addLogLine(str.Trim()); + else + line = str; + } + + logList->Thaw(); + } + } + + savedPartialLine.clear(); + + if (!line.IsEmpty()) + { + // We finished reading to the end of the log file, but still have some data left + if (csv_log_format) + { + savedPartialLine = line; // Save partial log line for next read of the data file. + line.Clear(); + } + else + addLogLine(line.Trim()); + } + +} + + +void frmStatus::addLogLine(const wxString &str, bool formatted, bool csv_log_format) +{ + int row = logList->GetItemCount(); + + int idxTimeStampCol = -1, idxLevelCol = -1; + int idxLogEntryCol = 0; + + if (logFormatKnown) + { + // Known Format first will be level, then Log entry + // idxLevelCol : 0, idxLogEntryCol : 1, idxTimeStampCol : -1 + idxLevelCol++; + idxLogEntryCol++; + if (logHasTimestamp) + { + // idxLevelCol : 1, idxLogEntryCol : 2, idxTimeStampCol : 0 + idxTimeStampCol++; + idxLevelCol++; + idxLogEntryCol++; + } + } + + if (!logFormatKnown) + logList->AppendItem(-1, str); + else if ((!csv_log_format) && str.Find(':') < 0) + { + // Must be a continuation of a previous line. + logList->InsertItem(row, wxEmptyString, -1); + logList->SetItem(row, idxLogEntryCol, str); + } + else if (!formatted) + { + // Not from a log, from pgAdmin itself. + if (logHasTimestamp) + { + logList->InsertItem(row, wxEmptyString, -1); + logList->SetItem(row, idxLevelCol, str.BeforeFirst(':')); + } + else + { + logList->InsertItem(row, str.BeforeFirst(':'), -1); + } + logList->SetItem(row, idxLogEntryCol, str.AfterFirst(':')); + } + else // formatted log + { + if (csv_log_format) + { + // Log is in CSV format (GPDB 3.3 and later, or Postgres if only csv log enabled) + // In this case, we are always supposed to have a complete log line in csv format in str when called. + + if (logHasTimestamp && (str.Length() < 20 || (logHasTimestamp && (str[0] != wxT('2') || str[1] != wxT('0'))))) + { + // Log line too short or does not start with an expected timestamp... + // Must be a continuation of the previous line or garbage, + // or we are out of sync in our CSV handling. + // We shouldn't ever get here. + logList->InsertItem(row, wxEmptyString, -1); + logList->SetItem(row, 2, str); + } + else + { + CSVTokenizer tk(str); + + bool gpdb = connection->GetIsGreenplum(); + + // Get the fields from the CSV log. + wxString logTime = tk.GetNextToken(); + wxString logUser = tk.GetNextToken(); + wxString logDatabase = tk.GetNextToken(); + wxString logPid = tk.GetNextToken(); + + wxString logSession; + wxString logCmdcount; + wxString logSegment; + + if (gpdb) + { + wxString logThread = tk.GetNextToken(); // GPDB specific + wxString logHost = tk.GetNextToken(); + wxString logPort = tk.GetNextToken(); // GPDB (Postgres puts port with Host) + wxString logSessiontime = tk.GetNextToken(); + wxString logTransaction = tk.GetNextToken(); + logSession = tk.GetNextToken(); + logCmdcount = tk.GetNextToken(); + logSegment = tk.GetNextToken(); + wxString logSlice = tk.GetNextToken(); + wxString logDistxact = tk.GetNextToken(); + wxString logLocalxact = tk.GetNextToken(); + wxString logSubxact = tk.GetNextToken(); + } + else + { + wxString logHost = tk.GetNextToken(); // Postgres puts port with Hostname + logSession = tk.GetNextToken(); + wxString logLineNumber = tk.GetNextToken(); + wxString logPsDisplay = tk.GetNextToken(); + wxString logSessiontime = tk.GetNextToken(); + wxString logVXid = tk.GetNextToken(); + wxString logTransaction = tk.GetNextToken(); + } + + wxString logSeverity = tk.GetNextToken(); + wxString logState = tk.GetNextToken(); + wxString logMessage = tk.GetNextToken(); + wxString logDetail = tk.GetNextToken(); + wxString logHint = tk.GetNextToken(); + wxString logQuery = tk.GetNextToken(); + wxString logQuerypos = tk.GetNextToken(); + wxString logContext = tk.GetNextToken(); + wxString logDebug = tk.GetNextToken(); + wxString logCursorpos = tk.GetNextToken(); + + wxString logStack; + if (gpdb) + { + wxString logFunction = tk.GetNextToken(); // GPDB. Postgres puts func, file, and line together + wxString logFile = tk.GetNextToken(); + wxString logLine = tk.GetNextToken(); + logStack = tk.GetNextToken(); // GPDB only. + } + else + wxString logFuncFileLine = tk.GetNextToken(); + + logList->InsertItem(row, logTime, -1); // Insert timestamp (with time zone) + + logList->SetItem(row, 1, logSeverity); + + // Display the logMessage, breaking it into lines + wxStringTokenizer lm(logMessage, wxT("\n")); + logList->SetItem(row, 2, lm.GetNextToken()); + + logList->SetItem(row, 3, logSession); + logList->SetItem(row, 4, logCmdcount); + logList->SetItem(row, 5, logDatabase); + if ((!gpdb) || (logSegment.length() > 0 && logSegment != wxT("seg-1"))) + { + logList->SetItem(row, 6, logSegment); + } + else + { + // If we are reading the masterDB log only, the logSegment won't + // have anything useful in it. Look in the logMessage, and see if the + // segment info exists in there. It will always be at the end. + if (logMessage.length() > 0 && logMessage[logMessage.length() - 1] == wxT(')')) + { + int segpos = -1; + segpos = logMessage.Find(wxT("(seg")); + if (segpos <= 0) + segpos = logMessage.Find(wxT("(mir")); + if (segpos > 0) + { + logSegment = logMessage.Mid(segpos + 1); + if (logSegment.Find(wxT(' ')) > 0) + logSegment = logSegment.Mid(0, logSegment.Find(wxT(' '))); + logList->SetItem(row, 6, logSegment); + } + } + } + + // The rest of the lines from the logMessage + while (lm.HasMoreTokens()) + { + int controw = logList->GetItemCount(); + logList->InsertItem(controw, wxEmptyString, -1); + logList->SetItem(controw, 2, lm.GetNextToken()); + } + + // Add the detail + wxStringTokenizer ld(logDetail, wxT("\n")); + while (ld.HasMoreTokens()) + { + int controw = logList->GetItemCount(); + logList->InsertItem(controw, wxEmptyString, -1); + logList->SetItem(controw, 2, ld.GetNextToken()); + } + + // And the hint + wxStringTokenizer lh(logHint, wxT("\n")); + while (lh.HasMoreTokens()) + { + int controw = logList->GetItemCount(); + logList->InsertItem(controw, wxEmptyString, -1); + logList->SetItem(controw, 2, lh.GetNextToken()); + } + + if (logDebug.length() > 0) + { + wxString logState3 = logState.Mid(0, 3); + if (logState3 == wxT("426") || logState3 == wxT("22P") || logState3 == wxT("427") + || logState3 == wxT("42P") || logState3 == wxT("458") + || logMessage.Mid(0, 9) == wxT("duration:") || logSeverity == wxT("FATAL") || logSeverity == wxT("PANIC")) + { + // If not redundant, add the statement from the debug_string + wxStringTokenizer lh(logDebug, wxT("\n")); + if (lh.HasMoreTokens()) + { + int controw = logList->GetItemCount(); + logList->InsertItem(controw, wxEmptyString, -1); + logList->SetItem(controw, 2, wxT("statement: ") + lh.GetNextToken()); + } + while (lh.HasMoreTokens()) + { + int controw = logList->GetItemCount(); + logList->InsertItem(controw, wxEmptyString, -1); + logList->SetItem(controw, 2, lh.GetNextToken()); + } + } + } + + if (gpdb) + if (logSeverity == wxT("PANIC") || + (logSeverity == wxT("FATAL") && logState != wxT("57P03") && logState != wxT("53300"))) + { + // If this is a severe error, add the stack trace. + wxStringTokenizer ls(logStack, wxT("\n")); + if (ls.HasMoreTokens()) + { + int controw = logList->GetItemCount(); + logList->InsertItem(controw, wxEmptyString, -1); + logList->SetItem(controw, 1, wxT("STACK")); + logList->SetItem(controw, 2, ls.GetNextToken()); + } + while (ls.HasMoreTokens()) + { + int controw = logList->GetItemCount(); + logList->InsertItem(controw, wxEmptyString, -1); + logList->SetItem(controw, 2, ls.GetNextToken()); + } + } + } + } + else if (connection->GetIsGreenplum()) + { + // Greenplum 3.2 and before. log_line_prefix = "%m|%u|%d|%p|%I|%X|:-" + + wxString logSeverity; + // Skip prefix, get message. In GPDB, always follows ":-". + wxString rest = str.Mid(str.Find(wxT(":-")) + 1) ; + if (rest.Length() > 0 && rest[0] == wxT('-')) + rest = rest.Mid(1); + + // Separate loglevel from message + + if (rest.Length() > 1 && rest[0] != wxT(' ') && rest.Find(':') > 0) + { + logSeverity = rest.BeforeFirst(':'); + rest = rest.AfterFirst(':').Mid(2); + } + + wxString ts = str.BeforeFirst(logFormat.c_str()[logFmtPos + 2]); + if (ts.Length() < 20 || (logHasTimestamp && (ts.Left(2) != wxT("20") || str.Find(':') < 0))) + { + // No Timestamp? Must be a continuation of a previous line? + // Not sure if it is possible to get here. + logList->InsertItem(row, wxEmptyString, -1); + logList->SetItem(row, 2, rest); + } + else if (logSeverity.Length() > 1) + { + // Normal case: Start of a new log record. + logList->InsertItem(row, ts, -1); + logList->SetItem(row, 1, logSeverity); + logList->SetItem(row, 2, rest); + } + else + { + // Continuation of previous line + logList->InsertItem(row, wxEmptyString, -1); + logList->SetItem(row, 2, rest); + } + } + else + { + // All Non-csv-format non-GPDB PostgreSQL systems. + + wxString rest; + + if (logHasTimestamp) + { + if (formatted) + { + rest = str.Mid(logFmtPos + 22).AfterFirst(':'); + wxString ts = str.Mid(logFmtPos, str.Length() - rest.Length() - logFmtPos - 1); + + int pos = ts.Find(logFormat.c_str()[logFmtPos + 2], true); + logList->InsertItem(row, ts.Left(pos), -1); + logList->SetItem(row, idxLevelCol, ts.Mid(pos + logFormat.Length() - logFmtPos - 2)); + logList->SetItem(row, idxLogEntryCol, rest.Mid(2)); + } + else + { + logList->InsertItem(row, wxEmptyString, -1); + logList->SetItem(row, idxLevelCol, str.BeforeFirst(':')); + logList->SetItem(row, idxLogEntryCol, str.AfterFirst(':').Mid(2)); + } + } + else + { + if (formatted) + rest = str.Mid(logFormat.Length()); + else + rest = str; + + int pos = rest.Find(':'); + + if (pos < 0) + logList->InsertItem(row, rest, -1); + else + { + logList->InsertItem(row, rest.BeforeFirst(':'), -1); + logList->SetItem(row, idxLogEntryCol, rest.AfterFirst(':').Mid(2)); + } + } + } + } +} + + +void frmStatus::emptyLogfileCombo() +{ + if (cbLogfiles->GetCount()) // first entry has no client data + cbLogfiles->Delete(0); + + while (cbLogfiles->GetCount()) + { + wxDateTime *dt = (wxDateTime *)cbLogfiles->wxItemContainer::GetClientData(0); + if (dt) + delete dt; + cbLogfiles->Delete(0); + } +} + + +int frmStatus::fillLogfileCombo() +{ + int count = cbLogfiles->GetCount(); + if (!count) + cbLogfiles->Append(_("Current log")); + else + count--; + + pgSet *set = connection->ExecuteSet( + wxT("SELECT filename, filetime\n") + wxT(" FROM pg_logdir_ls() AS A(filetime timestamp, filename text)\n") + wxT(" ORDER BY filetime DESC")); + if (set) + { + if (set->NumRows() <= count) + { + delete set; + return 0; + } + + set->Locate(count + 1); + count = 0; + + while (!set->Eof()) + { + count++; + wxString fn = set->GetVal(wxT("filename")); + wxDateTime ts = set->GetDateTime(wxT("filetime")); + + cbLogfiles->Append(DateToAnsiStr(ts), (void *)new wxDateTime(ts)); + + set->MoveNext(); + } + + delete set; + } + + return count; +} + + +void frmStatus::OnLoadLogfile(wxCommandEvent &event) +{ + int pos = cbLogfiles->GetCurrentSelection(); + if (pos >= 0) + { + showCurrent = (pos == 0); + isCurrent = showCurrent || (pos == 1); + + wxDateTime *ts = (wxDateTime *)cbLogfiles->wxItemContainer::GetClientData(showCurrent ? 1 : pos); + wxASSERT(ts != 0); + + if (ts != NULL && (!logfileTimestamp.IsValid() || *ts != logfileTimestamp)) + { + logList->DeleteAllItems(); + addLogFile(ts, true); + } + } +} + + +void frmStatus::OnRotateLogfile(wxCommandEvent &event) +{ + if (wxMessageBox(_("Are you sure the logfile should be rotated?"), _("Logfile rotation"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) == wxYES) + connection->ExecuteVoid(wxT("select pg_logfile_rotate()")); +} + + +void frmStatus::OnCancelBtn(wxCommandEvent &event) +{ + switch(currentPane) + { + case PANE_STATUS: + OnStatusCancelBtn(event); + break; + case PANE_LOCKS: + OnLocksCancelBtn(event); + break; + default: + // This shouldn't happen. If it does, it's no big deal + break; + } +} + + +void frmStatus::OnStatusCancelBtn(wxCommandEvent &event) +{ + long item = statusList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item < 0) + return; + + if (wxMessageBox(_("Are you sure you wish to cancel the selected query(s)?"), _("Cancel query?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) + return; + + while (item >= 0) + { + wxString pid = statusList->GetItemText(item); + wxString sql = wxT("SELECT pg_cancel_backend(") + pid + wxT(");"); + connection->ExecuteScalar(sql); + + item = statusList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + } + + wxMessageBox(_("A cancel signal was sent to the selected server process(es)."), _("Cancel query"), wxOK | wxICON_INFORMATION); + OnRefresh(event); + wxListEvent ev; + OnSelStatusItem(ev); +} + + +void frmStatus::OnLocksCancelBtn(wxCommandEvent &event) +{ + long item = lockList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item < 0) + return; + + if (wxMessageBox(_("Are you sure you wish to cancel the selected query(s)?"), _("Cancel query?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) + return; + + while (item >= 0) + { + wxString pid = lockList->GetItemText(item); + wxString sql = wxT("SELECT pg_cancel_backend(") + pid + wxT(");"); + connection->ExecuteScalar(sql); + + item = lockList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + } + + wxMessageBox(_("A cancel signal was sent to the selected server process(es)."), _("Cancel query"), wxOK | wxICON_INFORMATION); + OnRefresh(event); + wxListEvent ev; + OnSelLockItem(ev); +} + + +void frmStatus::OnTerminateBtn(wxCommandEvent &event) +{ + switch(currentPane) + { + case PANE_STATUS: + OnStatusTerminateBtn(event); + break; + case PANE_LOCKS: + OnLocksTerminateBtn(event); + break; + default: + // This shouldn't happen. If it does, it's no big deal + break; + } +} + + +void frmStatus::OnStatusTerminateBtn(wxCommandEvent &event) +{ + long item = statusList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item < 0) + return; + + if (wxMessageBox(_("Are you sure you wish to terminate the selected server process(es)?"), _("Terminate process?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) + return; + + while (item >= 0) + { + wxString pid = statusList->GetItemText(item); + wxString sql = wxT("SELECT pg_terminate_backend(") + pid + wxT(");"); + connection->ExecuteScalar(sql); + + item = statusList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + } + + wxMessageBox(_("A terminate signal was sent to the selected server process(es)."), _("Terminate process"), wxOK | wxICON_INFORMATION); + OnRefresh(event); + wxListEvent ev; + OnSelStatusItem(ev); +} + + +void frmStatus::OnLocksTerminateBtn(wxCommandEvent &event) +{ + long item = lockList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item < 0) + return; + + if (wxMessageBox(_("Are you sure you wish to terminate the selected server process(es)?"), _("Terminate process?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) + return; + + while (item >= 0) + { + wxString pid = lockList->GetItemText(item); + wxString sql = wxT("SELECT pg_terminate_backend(") + pid + wxT(");"); + connection->ExecuteScalar(sql); + + item = lockList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + } + + wxMessageBox(_("A terminate signal was sent to the selected server process(es)."), _("Terminate process"), wxOK | wxICON_INFORMATION); + OnRefresh(event); + wxListEvent ev; + OnSelLockItem(ev); +} + + +void frmStatus::OnStatusMenu(wxCommandEvent &event) +{ + wxListItem column; + column.SetMask(wxLIST_MASK_TEXT); + + for (unsigned int i = 0; i < statusPopupMenu->GetMenuItemCount(); i++) + { + // Save column's width in a variable so that we can restore the old width + // if we make this column "invisible" + if (statusList->GetColumnWidth(i) > 0) + statusColWidth[i] = statusList->GetColumnWidth(i); + + wxMenuItem *menu = statusPopupMenu->FindItemByPosition(i); + if (menu && menu->IsChecked()) + statusList->SetColumnWidth(i, statusColWidth[i]); + else if (statusList->GetColumnWidth(i) > 0) + statusList->SetColumnWidth(i, 0); + + // Save current width to restore it at next launch + statusList->GetColumn(i, column); + if (column.GetWidth() > 0) + settings->WriteInt(wxT("frmStatus/StatusPane_") + column.GetText() + wxT("_Width"), + statusColWidth[i]); + else + settings->WriteInt(wxT("frmStatus/StatusPane_") + column.GetText() + wxT("_Width"), + -statusColWidth[i]); + } +} + + +void frmStatus::OnLockMenu(wxCommandEvent &event) +{ + wxListItem column; + column.SetMask(wxLIST_MASK_TEXT); + + for (unsigned int i = 0; i < lockPopupMenu->GetMenuItemCount(); i++) + { + // Save column's width in a variable so that we can restore the old width + // if we make this column "invisible" + if (lockList->GetColumnWidth(i) > 0) + lockColWidth[i] = lockList->GetColumnWidth(i); + + wxMenuItem *menu = lockPopupMenu->FindItemByPosition(i); + if (menu && menu->IsChecked()) + lockList->SetColumnWidth(i, lockColWidth[i]); + else if (lockList->GetColumnWidth(i) > 0) + lockList->SetColumnWidth(i, 0); + + // Save current width to restore it at next launch + lockList->GetColumn(i, column); + if (column.GetWidth() > 0) + settings->WriteInt(wxT("frmStatus/LockPane_") + column.GetText() + wxT("_Width"), + lockColWidth[i]); + else + settings->WriteInt(wxT("frmStatus/LockPane_") + column.GetText() + wxT("_Width"), + -lockColWidth[i]); + } +} + + +void frmStatus::OnXactMenu(wxCommandEvent &event) +{ + wxListItem column; + column.SetMask(wxLIST_MASK_TEXT); + + for (unsigned int i = 0; i < xactPopupMenu->GetMenuItemCount(); i++) + { + // Save column's width in a variable so that we can restore the old width + // if we make this column "invisible" + if (xactList->GetColumnWidth(i) > 0) + xactColWidth[i] = xactList->GetColumnWidth(i); + + wxMenuItem *menu = xactPopupMenu->FindItemByPosition(i); + if (menu && menu->IsChecked()) + xactList->SetColumnWidth(i, xactColWidth[i]); + else if (xactList->GetColumnWidth(i) > 0) + xactList->SetColumnWidth(i, 0); + + // Save current width to restore it at next launch + xactList->GetColumn(i, column); + if (column.GetWidth() > 0) + settings->WriteInt(wxT("frmStatus/XactPane_") + column.GetText() + wxT("_Width"), + xactColWidth[i]); + else + settings->WriteInt(wxT("frmStatus/XactPane_") + column.GetText() + wxT("_Width"), + -xactColWidth[i]); + } +} +void frmStatus::OnQuerystateMenu(wxCommandEvent &event) +{ + wxListItem column; + column.SetMask(wxLIST_MASK_TEXT); + + for (unsigned int i = 0; i < querystatePopupMenu->GetMenuItemCount(); i++) + { + // Save column's width in a variable so that we can restore the old width + // if we make this column "invisible" + if (querystateList->GetColumnWidth(i) > 0) + querystateColWidth[i] = querystateList->GetColumnWidth(i); + + wxMenuItem *menu = querystatePopupMenu->FindItemByPosition(i); + if (menu && menu->IsChecked()) + querystateList->SetColumnWidth(i, querystateColWidth[i]); + else if (querystateList->GetColumnWidth(i) > 0) + querystateList->SetColumnWidth(i, 0); + + // Save current width to restore it at next launch + querystateList->GetColumn(i, column); + if (column.GetWidth() > 0) + settings->WriteInt(wxT("frmStatus/QuerystatePane_") + column.GetText() + wxT("_Width"), + querystateColWidth[i]); + else + settings->WriteInt(wxT("frmStatus/QuerystatePane_") + column.GetText() + wxT("_Width"), + -querystateColWidth[i]); + } +} + + +void frmStatus::OnCommit(wxCommandEvent &event) +{ + long item = xactList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item < 0) + return; + + if (wxMessageBox(_("Are you sure you wish to commit the selected prepared transactions?"), _("Commit transaction?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) + return; + + while (item >= 0) + { + wxString xid = xactList->GetText(item, 1); + wxString sql = wxT("COMMIT PREPARED ") + connection->qtDbString(xid); + + // We must execute this in the database in which the prepared transaction originated. + if (connection->GetDbname() != xactList->GetText(item, 4)) + { + pgConn *tmpConn = new pgConn(connection->GetHost(), + connection->GetService(), + connection->GetHostAddr(), + xactList->GetText(item, 4), + connection->GetUser(), + connection->GetPassword(), + connection->GetPort(), + connection->GetRole(), + connection->GetSslMode(), + 0, + connection->GetApplicationName(), + connection->GetSSLCert(), + connection->GetSSLKey(), + connection->GetSSLRootCert(), + connection->GetSSLCrl(), + connection->GetSSLCompression()); + if (tmpConn) + { + if (tmpConn->GetStatus() != PGCONN_OK) + { + wxMessageBox(wxT("Connection failed: ") + tmpConn->GetLastError()); + return ; + } + tmpConn->ExecuteScalar(sql); + + tmpConn->Close(); + delete tmpConn; + } + } + else + connection->ExecuteScalar(sql); + + item = xactList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + } + + OnRefresh(event); + wxListEvent ev; + OnSelXactItem(ev); +} + + +void frmStatus::OnRollback(wxCommandEvent &event) +{ + long item = xactList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item < 0) + return; + + if (wxMessageBox(_("Are you sure you wish to rollback the selected prepared transactions?"), _("Rollback transaction?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) + return; + + while (item >= 0) + { + wxString xid = xactList->GetText(item, 1); + wxString sql = wxT("ROLLBACK PREPARED ") + connection->qtDbString(xid); + + // We must execute this in the database in which the prepared transaction originated. + if (connection->GetDbname() != xactList->GetText(item, 4)) + { + pgConn *tmpConn = new pgConn(connection->GetHost(), + connection->GetService(), + connection->GetHostAddr(), + xactList->GetText(item, 4), + connection->GetUser(), + connection->GetPassword(), + connection->GetPort(), + connection->GetRole(), + connection->GetSslMode(), + 0, + connection->GetApplicationName(), + connection->GetSSLCert(), + connection->GetSSLKey(), + connection->GetSSLRootCert(), + connection->GetSSLCrl(), + connection->GetSSLCompression()); + if (tmpConn) + { + if (tmpConn->GetStatus() != PGCONN_OK) + { + wxMessageBox(wxT("Connection failed: ") + tmpConn->GetLastError()); + return ; + } + tmpConn->ExecuteScalar(sql); + + tmpConn->Close(); + delete tmpConn; + } + } + else + connection->ExecuteScalar(sql); + + item = xactList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + } + + OnRefresh(event); + wxListEvent ev; + OnSelXactItem(ev); +} + + +void frmStatus::OnSelStatusItem(wxListEvent &event) +{ +#ifdef __WXGTK__ + manager.GetPane(wxT("Activity")).SetFlag(wxAuiPaneInfo::optionActive, true); + manager.GetPane(wxT("Locks")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Transactions")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Logfile")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Querystate")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.Update(); +#endif + currentPane = PANE_STATUS; + cbRate->SetValue(rateToCboString(statusRate)); + if (connection && connection->BackendMinimumVersion(8, 0)) + { + if(statusList->GetSelectedItemCount() > 0) + { + toolBar->EnableTool(MNU_CANCEL, true); + actionMenu->Enable(MNU_CANCEL, true); + if (connection->HasFeature(FEATURE_TERMINATE_BACKEND)) + { + toolBar->EnableTool(MNU_TERMINATE, true); + actionMenu->Enable(MNU_TERMINATE, true); + } + } + else + { + toolBar->EnableTool(MNU_CANCEL, false); + actionMenu->Enable(MNU_CANCEL, false); + toolBar->EnableTool(MNU_TERMINATE, false); + actionMenu->Enable(MNU_TERMINATE, false); + } + } + toolBar->EnableTool(MNU_COMMIT, false); + actionMenu->Enable(MNU_COMMIT, false); + toolBar->EnableTool(MNU_ROLLBACK, false); + actionMenu->Enable(MNU_ROLLBACK, false); + cbLogfiles->Enable(false); + btnRotateLog->Enable(false); + + editMenu->Enable(MNU_COPY, statusList->GetFirstSelected() >= 0); + actionMenu->Enable(MNU_COPY_QUERY, statusList->GetFirstSelected() >= 0); + toolBar->EnableTool(MNU_COPY_QUERY, statusList->GetFirstSelected() >= 0); + OnRefresh(event); +} + + +void frmStatus::OnSelLockItem(wxListEvent &event) +{ +#ifdef __WXGTK__ + manager.GetPane(wxT("Activity")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Locks")).SetFlag(wxAuiPaneInfo::optionActive, true); + manager.GetPane(wxT("Transactions")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Logfile")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Querystate")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.Update(); +#endif + currentPane = PANE_LOCKS; + cbRate->SetValue(rateToCboString(locksRate)); + if (connection && connection->BackendMinimumVersion(8, 0)) + { + if(lockList->GetSelectedItemCount() > 0) + { + toolBar->EnableTool(MNU_CANCEL, true); + actionMenu->Enable(MNU_CANCEL, true); + if (connection->HasFeature(FEATURE_TERMINATE_BACKEND)) + { + toolBar->EnableTool(MNU_TERMINATE, true); + actionMenu->Enable(MNU_TERMINATE, true); + } + } + else + { + toolBar->EnableTool(MNU_CANCEL, false); + actionMenu->Enable(MNU_CANCEL, false); + toolBar->EnableTool(MNU_TERMINATE, false); + actionMenu->Enable(MNU_TERMINATE, false); + } + } + toolBar->EnableTool(MNU_COMMIT, false); + actionMenu->Enable(MNU_COMMIT, false); + toolBar->EnableTool(MNU_ROLLBACK, false); + actionMenu->Enable(MNU_ROLLBACK, false); + cbLogfiles->Enable(false); + btnRotateLog->Enable(false); + + editMenu->Enable(MNU_COPY, lockList->GetFirstSelected() >= 0); + actionMenu->Enable(MNU_COPY_QUERY, false); + toolBar->EnableTool(MNU_COPY_QUERY, false); +} + + +void frmStatus::OnSelXactItem(wxListEvent &event) +{ +#ifdef __WXGTK__ + manager.GetPane(wxT("Activity")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Locks")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Transactions")).SetFlag(wxAuiPaneInfo::optionActive, true); + manager.GetPane(wxT("Logfile")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Querystate")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.Update(); +#endif + currentPane = PANE_XACT; + cbRate->SetValue(rateToCboString(xactRate)); + if(xactList->GetSelectedItemCount() > 0) + { + toolBar->EnableTool(MNU_COMMIT, true); + actionMenu->Enable(MNU_COMMIT, true); + toolBar->EnableTool(MNU_ROLLBACK, true); + actionMenu->Enable(MNU_ROLLBACK, true); + } + else + { + toolBar->EnableTool(MNU_COMMIT, false); + actionMenu->Enable(MNU_COMMIT, false); + toolBar->EnableTool(MNU_ROLLBACK, false); + actionMenu->Enable(MNU_ROLLBACK, false); + } + toolBar->EnableTool(MNU_CANCEL, false); + actionMenu->Enable(MNU_CANCEL, false); + toolBar->EnableTool(MNU_TERMINATE, false); + actionMenu->Enable(MNU_TERMINATE, false); + cbLogfiles->Enable(false); + btnRotateLog->Enable(false); + + editMenu->Enable(MNU_COPY, xactList->GetFirstSelected() >= 0); + actionMenu->Enable(MNU_COPY_QUERY, false); + toolBar->EnableTool(MNU_COPY_QUERY, false); +} + +void frmStatus::OnSelQuerystateItem(wxListEvent &event) +{ +#ifdef __WXGTK__ + manager.GetPane(wxT("Activity")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Locks")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Transactions")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Logfile")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Querystate")).SetFlag(wxAuiPaneInfo::optionActive, true); + manager.Update(); +#endif + currentPane = PANE_QUERYSTATE; + cbRate->SetValue(rateToCboString(querystateRate)); + { + toolBar->EnableTool(MNU_COMMIT, false); + actionMenu->Enable(MNU_COMMIT, false); + toolBar->EnableTool(MNU_ROLLBACK, false); + actionMenu->Enable(MNU_ROLLBACK, false); + } + toolBar->EnableTool(MNU_CANCEL, false); + actionMenu->Enable(MNU_CANCEL, false); + toolBar->EnableTool(MNU_TERMINATE, false); + actionMenu->Enable(MNU_TERMINATE, false); + cbLogfiles->Enable(false); + btnRotateLog->Enable(false); + + editMenu->Enable(MNU_COPY, querystateList->GetFirstSelected() >= 0); + actionMenu->Enable(MNU_COPY_QUERY, false); + toolBar->EnableTool(MNU_COPY_QUERY, false); +} + + +void frmStatus::OnSelLogItem(wxListEvent &event) +{ +#ifdef __WXGTK__ + manager.GetPane(wxT("Activity")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Locks")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Transactions")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Logfile")).SetFlag(wxAuiPaneInfo::optionActive, true); + manager.GetPane(wxT("Querystate")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.Update(); +#endif + currentPane = PANE_LOG; + cbRate->SetValue(rateToCboString(logRate)); + + // if there's no log, don't enable items + if (logDirectory != wxT("-")) + { + cbLogfiles->Enable(true); + btnRotateLog->Enable(true); + toolBar->EnableTool(MNU_CANCEL, false); + toolBar->EnableTool(MNU_TERMINATE, false); + toolBar->EnableTool(MNU_COMMIT, false); + toolBar->EnableTool(MNU_ROLLBACK, false); + actionMenu->Enable(MNU_CANCEL, false); + actionMenu->Enable(MNU_TERMINATE, false); + actionMenu->Enable(MNU_COMMIT, false); + actionMenu->Enable(MNU_ROLLBACK, false); + } + + editMenu->Enable(MNU_COPY, logList->GetFirstSelected() >= 0); + actionMenu->Enable(MNU_COPY_QUERY, false); + toolBar->EnableTool(MNU_COPY_QUERY, false); +} + + +void frmStatus::SetColumnImage(ctlListView *list, int col, int image) +{ + wxListItem item; + item.SetMask(wxLIST_MASK_IMAGE); + item.SetImage(image); + list->SetColumn(col, item); +} + + +void frmStatus::OnSortStatusGrid(wxListEvent &event) +{ + // Get the information for the SQL ORDER BY + if (statusSortColumn == event.GetColumn() + 1) + { + if (statusSortOrder == wxT("ASC")) + statusSortOrder = wxT("DESC"); + else + statusSortOrder = wxT("ASC"); + } + else + { + statusSortColumn = event.GetColumn() + 1; + statusSortOrder = wxT("ASC"); + } + + + // Re-initialize all columns' image + for (int i = 0; i < statusList->GetColumnCount(); i++) + { + SetColumnImage(statusList, i, -1); + } + + // Set the up/down image + if (statusSortOrder == wxT("ASC")) + SetColumnImage(statusList, statusSortColumn - 1, 0); + else + SetColumnImage(statusList, statusSortColumn - 1, 1); + + // Refresh grid + wxTimerEvent evt; + OnRefreshStatusTimer(evt); +} + + +void frmStatus::OnSortLockGrid(wxListEvent &event) +{ + // Get the information for the SQL ORDER BY + if (lockSortColumn == event.GetColumn() + 1) + { + if (lockSortOrder == wxT("ASC")) + lockSortOrder = wxT("DESC"); + else + lockSortOrder = wxT("ASC"); + } + else + { + lockSortColumn = event.GetColumn() + 1; + lockSortOrder = wxT("ASC"); + } + + // There are no sort operator for xid before 8.3 + if (!connection->BackendMinimumVersion(8, 3) && lockSortColumn == 5) + { + wxLogError(_("You cannot sort by transaction id on your PostgreSQL release. You need at least 8.3.")); + lockSortColumn = 1; + } + + // Re-initialize all columns' image + for (int i = 0; i < lockList->GetColumnCount(); i++) + { + SetColumnImage(lockList, i, -1); + } + + // Set the up/down image + if (lockSortOrder == wxT("ASC")) + SetColumnImage(lockList, lockSortColumn - 1, 0); + else + SetColumnImage(lockList, lockSortColumn - 1, 1); + + // Refresh grid + wxTimerEvent evt; + OnRefreshLocksTimer(evt); +} + + +void frmStatus::OnSortXactGrid(wxListEvent &event) +{ + // Get the information for the SQL ORDER BY + if (xactSortColumn == event.GetColumn() + 1) + { + if (xactSortOrder == wxT("ASC")) + xactSortOrder = wxT("DESC"); + else + xactSortOrder = wxT("ASC"); + } + else + { + xactSortColumn = event.GetColumn() + 1; + xactSortOrder = wxT("ASC"); + } + + // There are no sort operator for xid before 8.3 + if (!connection->BackendMinimumVersion(8, 3) && xactSortColumn == 1) + { + wxLogError(_("You cannot sort by transaction id on your PostgreSQL release. You need at least 8.3.")); + xactSortColumn = 2; + } + + // Re-initialize all columns' image + for (int i = 0; i < xactList->GetColumnCount(); i++) + { + SetColumnImage(xactList, i, -1); + } + + // Set the up/down image + if (xactSortOrder == wxT("ASC")) + SetColumnImage(xactList, xactSortColumn - 1, 0); + else + SetColumnImage(xactList, xactSortColumn - 1, 1); + + // Refresh grid + wxTimerEvent evt; + OnRefreshXactTimer(evt); +} + + +void frmStatus::OnRightClickStatusGrid(wxListEvent &event) +{ + statusList->PopupMenu(statusPopupMenu, event.GetPoint()); +} + +void frmStatus::OnRightClickLockGrid(wxListEvent &event) +{ + lockList->PopupMenu(lockPopupMenu, event.GetPoint()); +} + +void frmStatus::OnRightClickXactGrid(wxListEvent &event) +{ + xactList->PopupMenu(xactPopupMenu, event.GetPoint()); +} +void frmStatus::OnRightClickQuerystateGrid(wxListEvent &event) +{ + querystateList->PopupMenu(querystatePopupMenu, event.GetPoint()); +} + + +void frmStatus::OnChgColSizeStatusGrid(wxListEvent &event) +{ + wxCommandEvent ev; + OnStatusMenu(ev); +} + +void frmStatus::OnChgColSizeLockGrid(wxListEvent &event) +{ + wxCommandEvent ev; + OnLockMenu(ev); +} + +void frmStatus::OnChgColSizeXactGrid(wxListEvent &event) +{ + wxCommandEvent ev; + OnXactMenu(ev); +} + +void frmStatus::OnChgColSizeQuerystateGrid(wxListEvent &event) +{ + wxCommandEvent ev; + OnQuerystateMenu(ev); +} + + +serverStatusFactory::serverStatusFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, _("&Server Status"), _("Displays the current database status.")); +} + + +wxWindow *serverStatusFactory::StartDialog(frmMain *form, pgObject *obj) +{ + + pgServer *server = obj->GetServer(); + wxString applicationname = appearanceFactory->GetLongAppName() + wxT(" - Server Status"); + + pgConn *conn = server->CreateConn(wxEmptyString, 0, applicationname); + if (conn) + { + wxString txt = _("Server Status - ") + server->GetDescription() + + wxT(" (") + server->GetName() + wxT(":") + NumToStr((long)server->GetPort()) + wxT(")"); + + frmStatus *status = new frmStatus(form, txt, conn); + status->Go(); + return status; + } + return 0; +} + + +bool serverStatusFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->GetServer() != 0; +} diff --git a/frm/module.mk b/frm/module.mk new file mode 100644 index 0000000..58e2402 --- /dev/null +++ b/frm/module.mk @@ -0,0 +1,40 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/frm/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + frm/events.cpp \ + frm/frmAbout.cpp \ + frm/frmBackup.cpp \ + frm/frmBackupGlobals.cpp \ + frm/frmBackupServer.cpp \ + frm/frmConfig.cpp \ + frm/frmDatabaseDesigner.cpp \ + frm/frmEditGrid.cpp \ + frm/frmExport.cpp \ + frm/frmGrantWizard.cpp \ + frm/frmHbaConfig.cpp \ + frm/frmHint.cpp \ + frm/frmImport.cpp \ + frm/frmMain.cpp \ + frm/frmMainConfig.cpp \ + frm/frmMaintenance.cpp \ + frm/frmOptions.cpp \ + frm/frmPassword.cpp \ + frm/frmPgpassConfig.cpp \ + frm/frmQuery.cpp \ + frm/frmReport.cpp \ + frm/frmRestore.cpp \ + frm/frmSplash.cpp \ + frm/frmStatus.cpp \ + frm/plugins.cpp + +EXTRA_DIST += \ + frm/module.mk diff --git a/frm/plugins.cpp b/frm/plugins.cpp new file mode 100644 index 0000000..d7016eb --- /dev/null +++ b/frm/plugins.cpp @@ -0,0 +1,464 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// plugins.cpp - Plugin management for frmMain +// +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// Application headers +#include "frm/frmMain.h" +#include "db/pgConn.h" +#include "ctl/ctlMenuToolbar.h" +#include "schema/pgObject.h" +#include "schema/pgDatabase.h" +#include "schema/pgSchema.h" +#include "schema/pgTable.h" +#include "utils/sysSettings.h" + +void frmMain::LoadPluginUtilities() +{ + if (pluginsDir.IsEmpty()) + return; + + PluginUtility *util = new PluginUtility; + ClearPluginUtility(util); + + // Loop through all the ini files we find in the directory. + wxString iniFile; + wxDir iniDir(pluginsDir); + + if (!iniDir.IsOpened()) + return; + + wxLogInfo(wxT("Loading plugin ini files from %s"), pluginsDir.c_str()); + + bool cont = iniDir.GetFirst(&iniFile, wxT("*.ini"), wxDIR_FILES); + + while(cont) + { + // Load the config file + wxFileName utilIni(pluginsDir + wxT("/") + iniFile); + if (!utilIni.FileExists()) + { + cont = iniDir.GetNext(&iniFile); + continue; + } + + wxLogInfo(wxT("Loading plugin utilities from %s"), utilIni.GetFullPath().c_str()); + wxString brCfg = FileRead(utilIni.GetFullPath()); + + wxStringTokenizer tkz(brCfg, wxT("\r\n")); + + // Loop round the lines in the file. Everytime we find a new 'Title' value + // we create the current plugin and start a new one + while(tkz.HasMoreTokens()) + { + wxString token = tkz.GetNextToken(); + + if (token.Trim() == wxEmptyString || token.StartsWith(wxT(";"))) + continue; + + // Separator + if (token.Lower().StartsWith(wxT("[separator]"))) + { + // Add the previous app if required. + AddPluginUtility(util); + pluginsMenu->AppendSeparator(); + } + + // Title + if (token.Lower().StartsWith(wxT("title="))) + { + // Add the previous app if required. + AddPluginUtility(util); + util->title = token.AfterFirst('=').Trim(); + } + + // Command + if (token.Lower().StartsWith(wxT("command="))) + util->command = token.AfterFirst('=').Trim(); + + // Description + if (token.Lower().StartsWith(wxT("description="))) + util->description = token.AfterFirst('=').Trim(); + + // KeyFile + if (token.Lower().StartsWith(wxT("keyfile="))) + { + wxString keyfile = token.AfterFirst('=').Trim(); + + // Substitute path placeholders + keyfile.Replace(wxT("$$BINDIR"), loadPath); + keyfile.Replace(wxT("$$WORKINGDIR"), wxGetCwd()); + keyfile.Replace(wxT("$$PGBINDIR"), settings->GetPostgresqlPath()); + keyfile.Replace(wxT("$$EDBBINDIR"), settings->GetEnterprisedbPath()); + keyfile.Replace(wxT("$$SLONYBINDIR"), settings->GetSlonyPath()); + + util->keyfile = keyfile; + } + + // Platform + if (token.Lower().StartsWith(wxT("platform="))) + util->platform = token.AfterFirst('=').Trim(); + + // Server types + if (token.Lower().StartsWith(wxT("servertype="))) + { + util->server_types.Clear(); + + // This is a comma delimited list of values going into an array. + wxStringTokenizer valueTkz(token.AfterFirst('='), wxT(",")); + + while(valueTkz.HasMoreTokens()) + util->server_types.Add(valueTkz.GetNextToken()); + } + + // Database + if (token.Lower().StartsWith(wxT("database="))) + { + if (token.AfterFirst('=').Trim().Lower() == wxT("yes")) + util->database = true; + else + util->database = false; + } + + // Applies to + if (token.Lower().StartsWith(wxT("appliesto="))) + { + util->applies_to.Clear(); + + // This is a comma delimited list of values going into an array. + wxStringTokenizer valueTkz(token.AfterFirst('='), wxT(",")); + + while(valueTkz.HasMoreTokens()) + util->applies_to.Add(valueTkz.GetNextToken()); + } + + // Set password + if (token.Lower().StartsWith(wxT("setpassword="))) + { + if (token.AfterFirst('=').Trim().Lower() == wxT("yes")) + util->set_password = true; + else + util->set_password = false; + } + // Environment + if (token.Lower().StartsWith(wxT("environment="))) + { + util->set_env.Clear(); + + // This is a comma delimited list of values going into an array. + wxStringTokenizer valueTkz(token.AfterFirst('='), wxT(",")); + + while(valueTkz.HasMoreTokens()) + util->set_env.Add(valueTkz.GetNextToken()); + } + } + + // Add the last app if required. + AddPluginUtility(util); + + // Get the next file + cont = iniDir.GetNext(&iniFile); + } + + if (util) + delete util; +} + +// Add a new plugin to the collection. +void frmMain::AddPluginUtility(PluginUtility *util) +{ + // Platform name +#ifdef __WXMSW__ + wxString thisPlatform = wxT("windows"); +#else +#ifdef __WXGTK__ + wxString thisPlatform = wxT("unix"); +#else + wxString thisPlatform = wxT("osx"); +#endif +#endif + + // Only add apps targeted to this, or any platform + if (util->platform.Lower() == thisPlatform || util->platform == wxEmptyString) + { + // Only add an app with a title and command + if (!util->title.IsEmpty() && !util->command.IsEmpty()) + { + // We're only going to add this if the keyfile exists or isn't specified + if (util->keyfile.IsEmpty() || wxFileExists(util->keyfile)) + { + CreatePluginUtility(util); + ClearPluginUtility(util); + pluginUtilityCount++; + } + } + } +} + +// Create a new Plugin utility factory +void frmMain::CreatePluginUtility(PluginUtility *util) +{ + wxLogInfo(wxT("Adding plugin utility: %s"), util->title.c_str()); + wxLogInfo(wxT(" Command: %s"), util->command.c_str()); + wxLogInfo(wxT(" Description: %s"), util->description.c_str()); + wxLogInfo(wxT(" Database?: %s"), util->database ? wxT("Yes") : wxT("No")); + wxLogInfo(wxT(" Set Password?: %s"), util->set_password ? wxT("Yes") : wxT("No")); + + new pluginUtilityFactory(menuFactories, pluginsMenu, util); +} + +// Clear a PluginUtility struct +void frmMain::ClearPluginUtility(PluginUtility *util) +{ + util->title = wxEmptyString; + util->command = wxEmptyString; + util->description = wxEmptyString; + util->keyfile = wxEmptyString; + util->platform = wxEmptyString; + util->server_types.Clear(); + util->database = false; + util->applies_to.Clear(); + util->set_password = false; + util->set_env.Clear(); +} + +// The actionFactory for the plugin utilities +pluginUtilityFactory::pluginUtilityFactory(menuFactoryList *list, wxMenu *menu, PluginUtility *util) : actionFactory(list) +{ + title = util->title; + command = util->command; + description = util->description; + server_types = util->server_types; + database = util->database; + applies_to = util->applies_to; + set_password = util->set_password; + set_env = util->set_env; + + menu->Append(id, title, description); +} + + +wxWindow *pluginUtilityFactory::StartDialog(frmMain *form, pgObject *obj) +{ + wxString execCmd = command; + wxArrayString environment = set_env; + + // Remember this as the last plugin used + form->SetLastPluginUtility(this); + + // Replace all the place holders with appropriate values + if (HaveDatabase(obj)) + { + execCmd.Replace(wxT("$$HOSTNAME"), obj->GetConnection()->GetHostName()); + execCmd.Replace(wxT("$$HOSTADDR"), obj->GetConnection()->GetHostName()); + execCmd.Replace(wxT("$$PORT"), NumToStr((long)obj->GetConnection()->GetPort())); + execCmd.Replace(wxT("$$SSLMODE"), obj->GetConnection()->GetSslModeName()); + execCmd.Replace(wxT("$$DATABASE"), obj->GetConnection()->GetDbname()); + execCmd.Replace(wxT("$$USERNAME"), obj->GetConnection()->GetUser()); + execCmd.Replace(wxT("$$PASSWORD"), obj->GetConnection()->GetPassword()); + + // Set the PGPASSWORD variable if required. + if (set_password && !obj->GetConnection()->GetPassword().IsEmpty()) + wxSetEnv(wxT("PGPASSWORD"), obj->GetConnection()->GetPassword()); + + // Pass the SSL settings via the environment + switch (obj->GetConnection()->GetSslMode()) + { + case 1: + wxSetEnv(wxT("PGREQUIRESSL"), wxT("1")); + break; + case 2: + wxSetEnv(wxT("PGREQUIRESSL"), wxT("0")); + break; + } + + wxSetEnv(wxT("PGSSLMODE"), obj->GetConnection()->GetSslModeName()); + wxSetEnv(wxT("PGSSLCERT"), obj->GetConnection()->GetSSLCert()); + wxSetEnv(wxT("PGSSLKEY"), obj->GetConnection()->GetSSLKey()); + wxSetEnv(wxT("PGSSLROOTCERT"), obj->GetConnection()->GetSSLRootCert()); + wxSetEnv(wxT("PGSSLCRL"), obj->GetConnection()->GetSSLCrl()); + } + else + { + // Blank the rest + execCmd.Replace(wxT("$$HOSTNAME"), wxEmptyString); + execCmd.Replace(wxT("$$HOSTADDR"), wxEmptyString); + execCmd.Replace(wxT("$$PORT"), wxEmptyString); + execCmd.Replace(wxT("$$SSLMODE"), wxEmptyString); + execCmd.Replace(wxT("$$DATABASE"), wxEmptyString); + execCmd.Replace(wxT("$$USERNAME"), wxEmptyString); + execCmd.Replace(wxT("$$PASSWORD"), wxEmptyString); + } + + // Name + if (obj && obj->IsCollection()) + execCmd.Replace(wxT("$$OBJECTNAME"), wxT("*")); + else if (obj) + execCmd.Replace(wxT("$$OBJECTNAME"), obj->GetName()); + else + execCmd.Replace(wxT("$$OBJECTNAME"), wxEmptyString); + + // Object type + if (obj && obj->GetFactory()) + execCmd.Replace(wxT("$$OBJECTTYPE"), wxString(obj->GetFactory()->GetTypeName()).Upper()); + else + execCmd.Replace(wxT("$$OBJECTTYPE"), wxEmptyString); + + // Schema + if (obj) + { + if (obj->GetMetaType() == PGM_SCHEMA) + execCmd.Replace(wxT("$$SCHEMA"), obj->GetName()); + else if (obj->GetSchema()) + execCmd.Replace(wxT("$$SCHEMA"), obj->GetSchema()->GetName()); + } + else + execCmd.Replace(wxT("$$SCHEMA"), wxEmptyString); + + // Table + if (obj) + { + if (obj->GetMetaType() == PGM_TABLE || obj->GetMetaType() == GP_PARTITION) + execCmd.Replace(wxT("$$TABLE"), obj->GetName()); + else if (obj->GetTable()) + execCmd.Replace(wxT("$$TABLE"), obj->GetTable()->GetName()); + } + else + execCmd.Replace(wxT("$$TABLE"), wxEmptyString); + + // Directory substitutions + execCmd.Replace(wxT("$$BINDIR"), loadPath); + execCmd.Replace(wxT("$$WORKINGDIR"), wxGetCwd()); + execCmd.Replace(wxT("$$PGBINDIR"), settings->GetPostgresqlPath()); + execCmd.Replace(wxT("$$EDBBINDIR"), settings->GetEnterprisedbPath()); + execCmd.Replace(wxT("$$SLONYBINDIR"), settings->GetSlonyPath()); + + // set Environment variable. + for (size_t i = 0 ; i < environment.GetCount() ; i++) + { + wxString str = environment.Item(i); + wxSetEnv(str.BeforeFirst('='), str.AfterFirst('=')); + } + + // Let's go!! + if (wxExecute(execCmd) == 0) + { + wxLogError(_("Failed to execute plugin %s (%s)"), title.c_str(), command.c_str()); + } + + // Reset the environment variables set by us + wxUnsetEnv(wxT("PGPASSWORD")); + wxUnsetEnv(wxT("PGSSLMODE")); + wxUnsetEnv(wxT("PGREQUIRESSL")); + wxUnsetEnv(wxT("PGSSLCERT")); + wxUnsetEnv(wxT("PGSSLKEY")); + wxUnsetEnv(wxT("PGSSLROOTCERT")); + wxUnsetEnv(wxT("PGSSLCRL")); + + return 0; +} + +bool pluginUtilityFactory::CheckEnable(pgObject *obj) +{ + // First check that this is one of the supported server types + // for this plugin. If none are specified, then anything goes + if (database && server_types.Count() > 0) + { + // If we need a specific server type, we can't enable unless + // we have a connection. + if (!obj || !(obj->GetConnection()->GetStatus() == PGCONN_OK)) + return false; + + // Get the server type. + wxString serverType = wxT("postgresql"); + if (obj->GetConnection()->GetIsEdb()) + serverType = wxT("enterprisedb"); + + // Check if it's in the list. + if (server_types.Index(serverType) == wxNOT_FOUND) + return false; + } + + // Now check that this is one of the supported object types + // for this plugin. If none are specified, then anything goes + if (obj && applies_to.Count() > 0) + { + if (applies_to.Index(wxString(obj->GetFactory()->GetTypeName()).Lower()) == wxNOT_FOUND) + return false; + } + + // If we don't need a database, we're always OK. + if (!database) + return true; + + return HaveDatabase(obj); +} + +bool pluginUtilityFactory::HaveDatabase(pgObject *obj) +{ + // We need a good connection and database. + if (!obj) + return false; + + if (!obj->GetDatabase()) + return false; + + if (!obj->GetDatabase()->GetConnection()) + return false; + + if (!(obj->GetDatabase()->GetConnection()->GetStatus() == PGCONN_OK)) + return false; + + return true; +} + +// The pluginButtonMenuFactory class manages the toolbar menu button +// for the plugins. + +#include "images/plugins.pngc" +pluginButtonMenuFactory::pluginButtonMenuFactory(menuFactoryList *list, wxMenu *popupmenu, ctlMenuToolbar *toolbar, int pluginCount) : actionFactory(list) +{ + if (pluginCount) + enableButton = true; + else + enableButton = false; + + if (toolbar) + { + toolbar->AddTool(id, wxEmptyString, *plugins_png_bmp, _("Execute the last used plugin.")); + pulldownButton = toolbar->AddMenuPulldownTool(MNU_PLUGINBUTTONLIST, wxT("Execute Plugin"), wxT("Select a plugin."), popupmenu); + } +} + +// Call the last plugin used, or popup the menu if this is the first time +wxWindow *pluginButtonMenuFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (form->GetLastPluginUtility() && form->GetLastPluginUtility()->CheckEnable(obj)) + return form->GetLastPluginUtility()->StartDialog(form, obj); + else + { + wxMouseEvent evt; + pulldownButton->DoProcessLeftClick(evt); + } + + return 0; +} + +bool pluginButtonMenuFactory::CheckEnable(pgObject *obj) +{ + return enableButton; +} diff --git a/gqb/gqbArrayCollection.cpp b/gqb/gqbArrayCollection.cpp new file mode 100644 index 0000000..9936147 --- /dev/null +++ b/gqb/gqbArrayCollection.cpp @@ -0,0 +1,190 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbArrayCollection.cpp - Implementation of Collection Using Arrays +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "gqb/gqbArrayCollection.h" +#include "gqb/gqbObject.h" + +// Destructor +gqbArrayCollection::~gqbArrayCollection() +{ + WX_CLEAR_ARRAY(gqbArray); +} + + +// Add item to array +void gqbArrayCollection::addItem(gqbObject *item) +{ + gqbArray.Add(item); +} + + +// Remove item from array but don't delete it. +void gqbArrayCollection::removeItem(gqbObject *item) +{ + gqbArray.Remove(item); +} + + +// Create an iterator for the objects inside the array +gqbIteratorBase *gqbArrayCollection::createIterator() +{ + return (new gqbArrayIterator(&gqbArray)); +} + +// Create a Down to iterator for the objects inside the array +gqbIteratorBase *gqbArrayCollection::createDownIterator() +{ + return (new gqbArrayDownIterator(&gqbArray)); +} + +// Return the number of elements inside the array +int gqbArrayCollection::count() +{ + return gqbArray.Count(); +} + + +// Return true if an element pointer is found inside array +bool gqbArrayCollection::existsObject(gqbObject *item) +{ + gqbObject *found = NULL; + int size = gqbArray.GetCount(); + for(int i = 0; i < size; i++) + { + if (gqbArray.Item(i) == item) + { + found = gqbArray.Item(i); + break; + } + } + if(found) + return true; + else + return false; +} + + +// Delete all elements inside array +void gqbArrayCollection::deleteAll() +{ + WX_CLEAR_ARRAY(gqbArray); +} + + +// Removes all elements inside array without deleting +void gqbArrayCollection::removeAll() +{ + gqbArray.Empty(); +} + +// Get Item at certain position at Collection +gqbObject *gqbArrayCollection::getItemAt(int index) +{ + if(!gqbArray.IsEmpty()) + return gqbArray.Item(index); + else + return NULL; +} + + +int gqbArrayCollection::getIndex(gqbObject *item) +{ + return gqbArray.Index(item); +} + + +// Insert item into the array before the index +void gqbArrayCollection:: insertAtIndex(gqbObject *item, int index) +{ + gqbArray.Insert(item, index); +} + + +// +// gqbArrayIterator - Manages iterator for the array collection concrete class, from first to last element +// + +// Constructor +gqbArrayIterator::gqbArrayIterator(gqbObjsArray *gqbPtrsArray) +{ + position = 0; + internalArray = gqbPtrsArray; +} + + +// Get next item in the array for the iterator +gqbObject *gqbArrayIterator::Next() +{ + gqbObject *obj = internalArray->Item(position); + position++; + return obj; +} + + +// Return true if the array has more elements to return +bool gqbArrayIterator::HasNext() +{ + int size = internalArray->GetCount(); + if( (size > 0) && (position <= (size - 1)) ) + return true; + else + return false; +} + + +void gqbArrayIterator::ResetIterator() +{ + position = 0; +} + + +// +// gqbArrayDownIterator - Manages iterator for the array collection concrete class from last to first element +// + +// Constructor +gqbArrayDownIterator::gqbArrayDownIterator(gqbObjsArray *gqbPtrsArray) +{ + internalArray = gqbPtrsArray; + position = internalArray->GetCount() - 1; +} + + +// Get next item in the array for the iterator +gqbObject *gqbArrayDownIterator::Next() +{ + gqbObject *obj = internalArray->Item(position); + position--; + return obj; +} + + +// Return true if the array has more elements to return +bool gqbArrayDownIterator::HasNext() +{ + int size = internalArray->GetCount(); + if( (size > 0) && (position <= (size - 1) && position >= 0) ) + return true; + else + return false; +} + + +void gqbArrayDownIterator::ResetIterator() +{ + position = internalArray->GetCount() - 1; +} diff --git a/gqb/gqbBrowser.cpp b/gqb/gqbBrowser.cpp new file mode 100644 index 0000000..dfc60fb --- /dev/null +++ b/gqb/gqbBrowser.cpp @@ -0,0 +1,139 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbBrowser.cpp - Tables Tree of GQB. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "gqb/gqbBrowser.h" +#include "gqb/gqbEvents.h" +#include "gqb/gqbSchema.h" +#include "gqb/gqbDatabase.h" +#include "gqb/gqbViewController.h" + +// Images +#include "images/table-sm.pngc" +#include "images/view-sm.pngc" +#include "images/namespace-sm.pngc" +#include "images/namespaces.pngc" +#include "images/database-sm.pngc" +#include "images/catalog-sm.pngc" +#include "images/catalogs.pngc" +#include "images/catalogobject-sm.pngc" +#include "images/exttable-sm.pngc" // Greenplum external tables + +BEGIN_EVENT_TABLE(gqbBrowser, wxTreeCtrl) + EVT_TREE_ITEM_ACTIVATED(GQB_BROWSER, gqbBrowser::OnItemActivated) + EVT_TREE_BEGIN_DRAG(GQB_BROWSER, gqbBrowser::OnBeginDrag) +END_EVENT_TABLE() + +gqbBrowser::gqbBrowser(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, gqbController *_controller) + : wxTreeCtrl(parent, id, pos, size, style) +{ + controller = _controller; + rootNode = (wxTreeItemId *)NULL; + + // Create normal images list of browser + // Remember to update enum gqbImages in gqbBrowser.h if changing the images!! + imageList = new wxImageList(16, 16); + imageList->Add(*database_sm_png_ico); + imageList->Add(*namespace_sm_png_ico); + imageList->Add(*table_sm_png_ico); + imageList->Add(*namespaces_png_ico); + imageList->Add(*catalogs_png_ico); + imageList->Add(*catalog_sm_png_ico); + imageList->Add(*catalogobject_sm_png_ico); + imageList->Add(*view_sm_png_ico); + imageList->Add(*exttable_sm_png_ico); + this->AssignImageList(imageList); +} + + +// Destructor +gqbBrowser::~gqbBrowser() +{ + this->DeleteAllItems(); // This remove and delete data inside tree's node +} + + +// Create root node +wxTreeItemId &gqbBrowser::createRoot(wxString &Name) +{ + rootNode = this->AddRoot(Name, 0, 0); + catalogsNode = this->AppendItem(rootNode, _("Catalogs"), GQB_IMG_CATALOGS, GQB_IMG_CATALOGS, NULL); + schemasNode = this->AppendItem(rootNode, _("Schemas"), GQB_IMG_NAMESPACES, GQB_IMG_NAMESPACES, NULL); + return rootNode; +} + + +// Event activated when user double click on a item of tree +void gqbBrowser::OnItemActivated(wxTreeEvent &event) +{ + wxTreeItemId itemId = event.GetItem(); + gqbObject *object = (gqbObject *) GetItemData(itemId); + if(object) + { + if (object->getType() == GQB_TABLE || object->getType() == GQB_VIEW) + { + gqbTable *item = (gqbTable *) object; + controller->addTableToModel(item, wxPoint(10, 10)); + controller->getView()->Refresh(); + } + else if (GetChildrenCount(itemId) == 0 && object->getType() == GQB_SCHEMA) + { + gqbSchema *schema = (gqbSchema *)object; + schema->createObjects(this, schema->getOid(), itemId, GQB_IMG_TABLE, GQB_IMG_VIEW, GQB_IMG_EXTTABLE); + } + } + +} + +void gqbBrowser::refreshTables(pgConn *connection) +{ + controller->emptyModel(); + this->DeleteAllItems(); + gqbDatabase *Data = new gqbDatabase(wxEmptyString, connection); + Data->createObjects(this); + this->Expand(rootNode); +} + + +void gqbBrowser::OnBeginDrag(wxTreeEvent &event) +{ + wxTreeItemId itemId = event.GetItem(); + + // Simplest solution, simulate DnD but actually don't do it + gqbObject *object = (gqbObject *) GetItemData(itemId); + if(object != NULL && (object->getType() == GQB_TABLE || object->getType() == GQB_VIEW)) + { + gqbTable *item = (gqbTable *) object; + wxString tableName = item->getName(); + wxTextDataObject textData(tableName); + wxDropSource dragSource(this); + dragSource.SetData(textData); + wxDragResult result = dragSource.DoDragDrop(wxDrag_CopyOnly); + if(result == wxDragCopy) + { + controller->getView()->CalcUnscrolledPosition(xx, yy, &xx, &yy); + gqbQueryObject *queryObj = controller->addTableToModel(item, wxPoint(xx, yy)); + controller->getView()->Refresh(); + if (queryObj) + { + controller->getView()->Update(); + controller->getView()->updateModelSize(queryObj, false); + } + } + } +} diff --git a/gqb/gqbCollection.cpp b/gqb/gqbCollection.cpp new file mode 100644 index 0000000..a743663 --- /dev/null +++ b/gqb/gqbCollection.cpp @@ -0,0 +1,98 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbCollection.cpp - Generic implementation of a Collection used by GQB. +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "gqb/gqbCollection.h" +#include "gqb/gqbObject.h" + +gqbCollection::gqbCollection(gqbCollectionBase *collectionBase) +{ + collection = collectionBase; +} + + +gqbCollection::~gqbCollection() +{ + if(collection) + delete collection; +} + + +void gqbCollection::addItem(gqbObject *item) +{ + collection->addItem(item); +} + + +void gqbCollection::removeItem(gqbObject *item) +{ + collection->removeItem(item); +} + + +gqbIteratorBase *gqbCollection::createIterator() +{ + return collection->createIterator(); +} + +gqbIteratorBase *gqbCollection::createDownIterator() +{ + return collection->createDownIterator(); +} + + +int gqbCollection::count() +{ + return collection->count(); +} + + +bool gqbCollection::existsObject(gqbObject *item) +{ + return collection->existsObject(item); +} + + +gqbObject *gqbCollection::getItemAt(int index) +{ + return collection->getItemAt(index); +} + + +// Remove all items from collection without deleting each one. +void gqbCollection::removeAll() +{ + collection->removeAll(); +} + + +void gqbCollection::deleteAll() +{ + collection->deleteAll(); +} + + +int gqbCollection::getIndex(gqbObject *item) +{ + return collection->getIndex(item); +} + + +void gqbCollection::insertAtIndex(gqbObject *item, int index) +{ + collection->insertAtIndex(item, index); +} diff --git a/gqb/gqbColumn.cpp b/gqb/gqbColumn.cpp new file mode 100644 index 0000000..2c2e847 --- /dev/null +++ b/gqb/gqbColumn.cpp @@ -0,0 +1,29 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbColumn.cpp - Column Object for GQB +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "gqb/gqbColumn.h" +#include "gqb/gqbObject.h" +#include "gqb/gqbSchema.h" +#include "gqb/gqbTable.h" +#include "gqb/gqbArrayCollection.h" + +gqbColumn::gqbColumn(gqbObject *parent, wxString name, pgConn *connection): + gqbObject(name, parent, connection) +{ + setType(GQB_COLUMN); +} diff --git a/gqb/gqbController.cpp b/gqb/gqbController.cpp new file mode 100644 index 0000000..de4927c --- /dev/null +++ b/gqb/gqbController.cpp @@ -0,0 +1,606 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbController.cpp - Controller part of MVC Software Pattern used by GQB +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include + +// App headers +#include "frm/frmQuery.h" +#include "gqb/gqbViewController.h" +#include "gqb/gqbModel.h" +#include "gqb/gqbSchema.h" +#include "gqb/gqbQueryObjs.h" +#include "gqb/gqbBrowser.h" +#include "gqb/gqbEvents.h" +#include "gqb/gqbViewPanels.h" + +wxWindowID CTL_NTBKPANELS = ::wxNewId(); + +gqbController::gqbController(gqbModel *_model, wxWindow *gqbParent, ctlAuiNotebook *gridParent, wxSize size = wxSize(GQB_MIN_WIDTH, GQB_MIN_HEIGHT)) + : wxObject() +{ + pparent = gqbParent; + model = _model; + wxSize tablesBrowserSize = wxSize(200, 800); //Initial Size + + // Initialize Main Splitter + gqbMainContainer = new wxSplitterWindow(gqbParent, GQB_HORZ_SASH, wxDefaultPosition, wxDefaultSize, wxSP_3D); + tabs = new wxNotebook(gqbMainContainer, CTL_NTBKPANELS, wxDefaultPosition, wxDefaultSize); + + // Initialize view container with tables browser + // GQB-TODO: change 976 with a enum value of events.h + gqbContainer = new gqbSplitter(gqbMainContainer, 976, wxDefaultPosition, wxDefaultSize, wxSP_3D); + + // Initialize view canvas and tables tree + browserPanel = new wxPanel(gqbContainer, wxID_ANY, wxDefaultPosition, tablesBrowserSize); + tablesBrowser = new gqbBrowser(browserPanel, GQB_BROWSER, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS | wxSIMPLE_BORDER, this); + view = new gqbView(gqbContainer, gridParent, size, this, model); + + // Set Drag Target + view->SetDropTarget(new DnDText(tablesBrowser)); + + // Set Scroll Bar & split + view->SetScrollbars( 10, 10, 127, 80 ); + gqbContainer->SplitVertically(browserPanel, view); + + tabs->InsertPage(ti_colsGridPanel, view->getColsGridPanel(), _("Columns")); + tabs->InsertPage(ti_criteriaPanel, view->getCriteriaPanel(), _("Criteria")); + tabs->InsertPage(ti_orderPanel, view->getOrderPanel(), _("Ordering")); + tabs->InsertPage(ti_joinsPanel, view->getJoinsPanel(), _("Joins")); + gqbMainContainer->SplitHorizontally(gqbContainer, tabs); + + // Fix Sash resize bug + gqbContainer->setTablesBrowser(tablesBrowser); + gqbContainer->setBrowserPanel(browserPanel); +} + + +// Destructor +gqbController::~gqbController() +{ + if(view) + { + delete view; + view = NULL; + } +} + + +// Add a table to the model +gqbQueryObject *gqbController::addTableToModel(gqbTable *table, wxPoint p) +{ + gqbQueryObject *added = model->addTable(table, p); + view->newTableAdded(added); + return added; +} + + +// Remove a table from the model +void gqbController::removeTableFromModel(gqbQueryObject *mtable, gqbGridProjTable *gridTable = NULL, gqbGridOrderTable *orderLTable = NULL, gqbGridOrderTable *orderRTable = NULL) +{ + model->deleteTable(mtable); + gridTable->removeAllRows(mtable); // GQB-TODO: move this functions to model?? + orderLTable->emptyTableData(mtable); + orderRTable->emptyTableData(mtable); +} + + +// Add (Select to be use in projection) a column for table in a model +void gqbController::processColumnInModel(gqbQueryObject *table, gqbColumn *column, gqbGridProjTable *gridTable = NULL) +{ + if(!table->existsColumn(column)) + { + table->addColumn(column); + if(gridTable) + { + gridTable->AppendItem(0, table); + gridTable->AppendItem(1, column); + gridTable->AppendItem(2, NULL); + } + } + else + { + // Removes but don't delete because we needed the column at table [this is just a pointer to it] + table->removeColumn(column); + if(gridTable) + { + gridTable->removeRow(table, column); + } + } +} + + +// Get selected item at position pt, marks item as selected and if there is a previous selected then unselect it +gqbObject *gqbController::getModelSelected(wxPoint &pt, gqbQueryObject *lastSelected, gqbQueryJoin *lastJoinSelected, bool mark) +{ + gqbQueryObject *sel = NULL; + gqbQueryJoin *jSel = NULL; + gqbIteratorBase *iterator = model->createDownQueryIterator(); + bool found = false; + + while(!found && iterator->HasNext()) + { + // Try to find if click over a table + sel = (gqbQueryObject *)iterator->Next(); + if( ((pt.x - sel->position.x > 0 ) && (sel->position.x + sel->getWidth() > pt.x)) && ((pt.y - sel->position.y > 0) && (sel->position.y + sel->getHeight() > pt.y)) ) + { + // GQB-TODO: this function should be move to the view to allow to + // recalculate it if the graphBehavior changes + if(mark) + sel->setSelected(true); + + jSel = NULL; + found = true; + break; + } + + // Try to find if user click over a Join + if(sel->getHaveJoins()) + { + gqbIteratorBase *joinsIterator = sel->createJoinsIterator(); + while(joinsIterator->HasNext()) + { + // GQB-TODO: don't pass anchor because join it's passed as parameter yet. + jSel = (gqbQueryJoin *) joinsIterator->Next(); + wxPoint o = jSel->getSourceAnchor(); + wxPoint d = jSel->getDestAnchor(); + + if(view->clickOnJoin(jSel, pt, o, d)) + { + if(mark) + jSel->setSelected(true); + found = true; + sel = NULL; + break; + } + + } + delete joinsIterator; + } + } + + delete iterator; + + if(found) + { + if(mark) + { + if(lastSelected && lastSelected != sel) // Unselect previous table selected if exists + lastSelected->setSelected(false); + // Unselect previous join selected if exists + if(lastJoinSelected && lastJoinSelected != jSel) + lastJoinSelected->setSelected(false); + } + if(sel) + return sel; + else if(jSel) + return jSel; + } + + return NULL; +} + + +// Unselect any previously selected item in the model +void gqbController::unsetModelSelected(bool queryTable = true) +{ + gqbQueryObject *sel = NULL; + gqbQueryJoin *jSel = NULL; + + if(queryTable) // QueryTable + { + gqbIteratorBase *iterator = model->createQueryIterator(); + while(iterator->HasNext()) + { + sel = (gqbQueryObject *)iterator->Next(); + if(sel->getSelected()) + { + sel->setSelected(false); + } + } + delete iterator; + } + + if(!queryTable) // QueryJoin + { + gqbIteratorBase *iterator = model->createQueryIterator(); + gqbQueryObject *sel = NULL; + while(iterator->HasNext()) + { + sel = (gqbQueryObject *)iterator->Next(); + if(sel->getHaveJoins()) + { + gqbIteratorBase *joinsIterator = sel->createJoinsIterator(); + while(joinsIterator->HasNext()) + { + // GQB-TODO: don't pass anchor because join it's passed as parameter yet. + jSel = (gqbQueryJoin *) joinsIterator->Next(); + if(jSel->getSelected()) + { + jSel->setSelected(false); + } + } + + delete joinsIterator; + } + } + delete iterator; + } +} + + +// GQB-TODO: Create a less complex & simpler generation function +// Generate the SQL Sentence from the model +wxString gqbController::generateSQL() +{ + wxString sentence = wxT(""); + if(model->tablesCount() > 0) + { + sentence += wxT("SELECT \n"); + + // Add selected columns for Query + gqbQueryObject *sel = NULL; + gqbIteratorBase *iteratorRestrictions = NULL; + gqbIteratorBase *iteratorModel = NULL; + gqbIteratorBase *iteratorJoins = NULL; + + // Projection Part [Select x,x,x...] + gqbObjsArray *cols = model->getOrderedColumns(); + gqbObjsArray *tables = model->getColumnsParents(); + wxArrayString *alias = model->getColumnsAlias(); + + int i, size = cols->GetCount(); + + for(i = 0; i < size; i++) + { + if(alias->Item(i).length() > 0) + { + if(((gqbQueryObject *)tables->Item(i))->getAlias().length() > 0) + { + sentence += wxT(" ") + + qtIdent(((gqbQueryObject *)tables->Item(i))->getAlias()) + + wxT(".") + + qtIdent(((gqbColumn *)cols->Item(i))->getName()) + + wxT(" AS ") + + qtIdent(alias->Item(i)) + + wxT(", \n"); + } + else + { + sentence += wxT(" ") + + qtIdent(((gqbQueryObject *)tables->Item(i))->getName()) + + wxT(".") + + qtIdent(((gqbColumn *)cols->Item(i))->getName()) + + wxT(" AS ") + + qtIdent(alias->Item(i)) + + wxT(", \n"); + } + } + else + { + if(((gqbQueryObject *)tables->Item(i))->getAlias().length() > 0) + { + sentence += wxT(" ") + + qtIdent(((gqbQueryObject *)tables->Item(i))->getAlias()) + + wxT(".") + + qtIdent(((gqbColumn *)cols->Item(i))->getName()) + + wxT(", \n"); + } + else + { + sentence += wxT(" ") + + qtIdent(((gqbQueryObject *)tables->Item(i))->getName()) + + wxT(".") + + qtIdent(((gqbColumn *)cols->Item(i))->getName()) + + wxT(", \n"); + } + } + } + + if(!size) + sentence += wxT(" * \n"); + else + { + // remove last ", " + sentence.Truncate(sentence.Length() - 3); + sentence += wxT("\n"); + } + + sentence += wxT("FROM \n"); + + iteratorModel = model->createQueryIterator(); + while(iteratorModel->HasNext()) + { + sel = (gqbQueryObject *)iteratorModel->Next(); + gqbSchema *schema = (gqbSchema *)sel->parent->getOwner(); + if(sel->getAlias().length() > 0) + { + sentence += wxT(" ") + + qtIdent(schema->getName()) + + wxT(".") + + qtIdent(sel->getName()) + + wxT(" ") + + qtIdent(sel->getAlias()) + + wxT(", \n"); + } + else + { + sentence += wxT(" ") + + qtIdent(schema->getName()) + + wxT(".") + + qtIdent(sel->getName()) + + wxT(", \n"); + } + + } + sentence.Truncate(sentence.Length() - 3); // remove last ", " + + // WHERE PART + // [Joins] + bool first = true, truncAnd = false; + gqbQueryJoin *tmp; + iteratorModel->ResetIterator(); + while(iteratorModel->HasNext()) + { + sel = (gqbQueryObject *)iteratorModel->Next(); + if(sel->getHaveJoins()) + { + truncAnd = true; + iteratorJoins = sel->createJoinsIterator(); + while(iteratorJoins->HasNext()) + { + if(first) + { + first = false; + sentence += wxT("\nWHERE \n"); + } + tmp = (gqbQueryJoin *)iteratorJoins->Next(); + + if(tmp->getSourceQTable()->getAlias().length() > 0) + sentence += wxT(" ") + + qtIdent(tmp->getSourceQTable()->getAlias()) + + wxT(".") + + qtIdent(tmp->getSourceCol()); + else + sentence += wxT(" ") + + qtIdent(tmp->getSourceQTable()->getName()) + + wxT(".") + + qtIdent(tmp->getSourceCol()); + + switch(tmp->getKindofJoin()) + { + case _equally: + sentence += wxT(" = "); + break; + case _greater: + sentence += wxT(" > "); + break; + case _lesser: + sentence += wxT(" < "); + break; + case _equgreater: + sentence += wxT(" >= "); + break; + case _equlesser: + sentence += wxT(" <= "); + break; + + } + + if(tmp->getDestQTable()->getAlias().length() > 0) + sentence += qtIdent(tmp->getDestQTable()->getAlias()) + + wxT(".") + + qtIdent(tmp->getDestCol()) + + wxT(" AND\n"); + else + sentence += qtIdent(tmp->getDestQTable()->getName()) + + wxT(".") + + qtIdent(tmp->getDestCol()) + + wxT(" AND\n"); + } + delete iteratorJoins; + } + } + delete iteratorModel; + + gqbRestrictions *restrictions = model->getRestrictions(); + + // Remove last " AND " from joins if there isn't restrictions, only left white space + if(truncAnd && (restrictions->restrictionsCount() <= 0)) + sentence.Truncate(sentence.Length() - 5); + + // Never found a join + if (!truncAnd && (restrictions->restrictionsCount() > 0)) + sentence += wxT("\nWHERE \n"); + + //GQB-TODO: VALIDATE RESTRICTIONS + iteratorRestrictions = restrictions->createRestrictionsIterator(); + gqbQueryRestriction *r = NULL; + + while(iteratorRestrictions->HasNext()) + { + r = (gqbQueryRestriction *)iteratorRestrictions->Next(); + sentence += wxT(" ") + + r->getLeft() + + wxT(" ") + + r->getRestriction() + + wxT(" ") + + r->getValue_s() + + wxT(" ") + + r->getConnector() + + wxT(" \n"); + } + delete iteratorRestrictions; + + if(restrictions->restrictionsCount() > 0) + { + if(r->getConnector().Contains(wxT("AND"))) + { + sentence.Truncate(sentence.Length() - 6); + } + else + { + sentence.Truncate(sentence.Length() - 5); + } + } + // ORDER BY PART + gqbObjsArray *orderByColumns = model->getOrdByColumns(); + gqbObjsArray *orderByParents = model->getOrdByParents(); + charArray *typeOfOrder = model->getOrdByKind(); + + size = orderByColumns->GetCount(); + if(size > 0) + { + sentence += wxT("\nORDER BY\n"); + } + wxString typeOrder = wxT(""); + for(i = 0; i < size; i++) + { + switch(typeOfOrder->Item(i)) + { + case 'A': + typeOrder = wxT(" ASC"); + break; + case 'D': + typeOrder = wxT(" DESC"); + break; + }; + if(((gqbQueryObject *)orderByParents->Item(i))->getAlias().length() > 0) + sentence += wxT(" ") + + qtIdent(((gqbQueryObject *)orderByParents->Item(i))->getAlias()) + + wxT(".") + + qtIdent(((gqbColumn *)orderByColumns->Item(i))->getName()) + + typeOrder + + wxT(", \n"); + else + sentence += wxT(" ") + + qtIdent(((gqbQueryObject *)orderByParents->Item(i))->getName()) + + wxT(".") + + qtIdent(((gqbColumn *)orderByColumns->Item(i))->getName()) + + typeOrder + + wxT(", \n"); + } + + if(size > 0) + sentence.Truncate(sentence.Length() - 3); + + sentence += wxT(";"); + } // Close Tables Count > 0 on model + return sentence; +} + + +gqbQueryRestriction *gqbController::addRestriction() +{ + return model->addRestriction(); +} + + +gqbQueryJoin *gqbController::addJoin(gqbQueryObject *sTable, gqbColumn *sColumn, gqbQueryObject *dTable, gqbColumn *dColumn, type_Join kind) +{ + return sTable->addJoin(sTable, dTable, sColumn, dColumn, kind); +} + + +void gqbController::removeJoin(gqbQueryJoin *join) +{ + join->getSourceQTable()->removeJoin(join, true); +} + + +void gqbController::setPointerMode(pointerMode pm) +{ + view->setPointerMode(pm); +} + + +void gqbController::emptyModel() +{ + view->emptyPanelsData(); + model->emptyAll(); +} + + +void gqbController::calcGridColsSizes() +{ + // Recalculate best internals sizes for all columns inside grids. + ((gqbGridPanel *)view->getColsGridPanel())->SetGridColsSize(); + ((gqbCriteriaPanel *)view->getCriteriaPanel())->SetGridColsSize(); + ((gqbOrderPanel *)view->getOrderPanel())->SetGridColsSize(); + ((gqbJoinsPanel *)view->getJoinsPanel())->SetGridColsSize(); +} + + +void gqbController::setSashVertPosition(int pos) +{ + gqbContainer->UpdateSize(); + gqbContainer->SetSashPosition(pos, true); + gqbContainer->SetMinimumPaneSize(pos); + gqbContainer->UpdateSize(); +} + +int gqbController::getSashHorizPosition() +{ + return gqbMainContainer->GetSashPosition(); +} + + +void gqbController::setSashHorizPosition(int pos) +{ + gqbMainContainer->UpdateSize(); + gqbMainContainer->SetSashPosition(pos, true); + + if(pos >= 150 && pos <= 200) + { + gqbMainContainer->SetMinimumPaneSize(pos); + } + else + { + gqbMainContainer->SetMinimumPaneSize(150); + } + gqbMainContainer->UpdateSize(); +} + + +// +// Utility Class to avoid a bug when the event sash resize is called [onVerticalSashResize] +// + +// GQB-TODO: fix 976 for real one value here and above + +BEGIN_EVENT_TABLE(gqbSplitter, wxSplitterWindow) + EVT_SPLITTER_SASH_POS_CHANGED(976, gqbSplitter::onVerticalSashResize) +END_EVENT_TABLE() + +gqbSplitter::gqbSplitter(wxWindow *parent, wxWindowID id, const wxPoint &point, const wxSize &size, long style) + : wxSplitterWindow(parent, id, point, size, style), + tablesBrowser(NULL), + browserPanel(NULL) +{ +} + + +void gqbSplitter::onVerticalSashResize(wxSplitterEvent &event) +{ + if(tablesBrowser != NULL && browserPanel != NULL) + { + wxSize s = tablesBrowser->GetSize(); + s.SetWidth(event.GetSashPosition()); + browserPanel->SetSize(s); + tablesBrowser->SetSize(s); + // GQB-TODO: Set a minimun value + } +} diff --git a/gqb/gqbDatabase.cpp b/gqb/gqbDatabase.cpp new file mode 100644 index 0000000..50fbded --- /dev/null +++ b/gqb/gqbDatabase.cpp @@ -0,0 +1,157 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbDatabase.cpp - Database object for GQB. +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "gqb/gqbDatabase.h" +#include "gqb/gqbObject.h" +#include "gqb/gqbSchema.h" +#include "schema/pgSchema.h" + +gqbDatabase::gqbDatabase(wxString name, pgConn *connection) + : gqbObject(name, NULL, connection) +{ + setType(GQB_DATABASE); +} + + +void gqbDatabase::createObjects(gqbBrowser *_tablesBrowser) +{ + + wxString rootNodeString = wxString(conn->GetDbname()); + // Create Root Node + _tablesBrowser->createRoot(rootNodeString); + + // FillBrowser + createSchemas(_tablesBrowser, _tablesBrowser->getCatalogRootNode(), GQB_CATALOG, GQB_IMG_CATALOG); + createSchemas(_tablesBrowser, _tablesBrowser->getTablesRootNode(), GQB_OTHER, GQB_IMG_NAMESPACE); +} + + +// Use database connection to create all objects inside tree +void gqbDatabase::createSchemas(gqbBrowser *tablesBrowser, wxTreeItemId parentNode, typeSchema MetaType, int indexImage) +{ + + // Search Schemas and insert it + wxString restr = wxT(" WHERE "); + + if (MetaType != GQB_CATALOG) + { + restr += wxT("NOT "); + } + restr += wxT("((nspname = 'pg_catalog' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'pg_class' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname = 'pgagent' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'pga_job' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname = 'information_schema' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'tables' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname LIKE '_%' AND EXISTS (SELECT 1 FROM pg_proc WHERE proname='slonyversion' AND pronamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname = 'dbo' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'systables' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname = 'sys' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'all_tables' AND relnamespace = nsp.oid LIMIT 1)))\n"); + + if (conn->EdbMinimumVersion(8, 2)) + { + restr += wxT(" AND nsp.nspparent = 0\n"); + // Do not show dbms_job_procedure in schemas + if (!settings->GetShowSystemObjects()) + restr += wxT("AND NOT (nspname = 'dbms_job_procedure' AND EXISTS(SELECT 1 FROM pg_proc WHERE pronamespace = nsp.oid and proname = 'run_job' LIMIT 1))\n"); + } + + wxString sql; + + if (MetaType == GQB_CATALOG) + { + sql = wxT("SELECT 2 AS nsptyp, nspname, nsp.oid") + wxT(" FROM pg_namespace nsp\n") + + restr + + wxT(" ORDER BY 1, nspname"); + } + else + { + if (conn->BackendMinimumVersion(8, 1)) + { + sql = wxT("SELECT CASE WHEN nspname LIKE E'pg\\\\_temp\\\\_%' THEN 1\n") + wxT(" WHEN (nspname LIKE E'pg\\\\_%') THEN 0\n"); + } + else + { + sql = wxT("SELECT CASE WHEN nspname LIKE 'pg\\\\_temp\\\\_%' THEN 1\n") + wxT(" WHEN (nspname LIKE 'pg\\\\_%') THEN 0\n"); + } + sql += wxT(" ELSE 3 END AS nsptyp, nspname, nsp.oid\n") + wxT(" FROM pg_namespace nsp\n") + + restr + + wxT(" ORDER BY 1, nspname"); + } + + pgSet *schemas = conn->ExecuteSet(sql); + wxTreeItemId parent; + + if (schemas) + { + while (!schemas->Eof()) + { + wxString name = schemas->GetVal(wxT("nspname")); + long nsptyp = schemas->GetLong(wxT("nsptyp")); + + wxStringTokenizer tokens(settings->GetSystemSchemas(), wxT(",")); + while (tokens.HasMoreTokens()) + { + wxRegEx regex(tokens.GetNextToken()); + if (regex.Matches(name)) + { + nsptyp = SCHEMATYP_USERSYS; + break; + } + } + + if (nsptyp <= SCHEMATYP_USERSYS && MetaType != GQB_CATALOG && !settings->GetShowSystemObjects()) + { + schemas->MoveNext(); + continue; + } + + int tableImage = GQB_IMG_TABLE, viewImage = GQB_IMG_VIEW; + gqbSchema *schema; + + if (MetaType == GQB_CATALOG) + { + + // Create Schema Object + schema = new gqbSchema(this, name, conn, schemas->GetOid(wxT("oid"))); + parent = tablesBrowser->AppendItem(parentNode, name, indexImage, indexImage, schema); + schema->createObjects(tablesBrowser, schema->getOid(), parent, GQB_IMG_TABLE, GQB_IMG_VIEW, GQB_IMG_EXTTABLE); + + if(name != wxT("pg_catalog") && name != wxT("pgagent")) + { + tableImage = GQB_IMG_CATALOG_OBJ; + viewImage = GQB_IMG_CATALOG_OBJ; + } + } + else + { + + // Create Schema Object + // Note that the schema will be populated when the node is expanded. + schema = new gqbSchema(this, name, conn, schemas->GetOid(wxT("oid"))); + parent = tablesBrowser->AppendItem(parentNode, name , indexImage, indexImage, schema); + schema->createObjects(tablesBrowser, schema->getOid(), parent, GQB_IMG_TABLE, GQB_IMG_VIEW, GQB_IMG_EXTTABLE); + } + + schemas->MoveNext(); + } + + delete schemas; + } +} diff --git a/gqb/gqbGraphSimple.cpp b/gqb/gqbGraphSimple.cpp new file mode 100644 index 0000000..979486a --- /dev/null +++ b/gqb/gqbGraphSimple.cpp @@ -0,0 +1,494 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbGraphsimple.cpp - A simple Implementation of the Graphic Interface for GQB +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "utils/sysSettings.h" +#include "gqb/gqbGraphSimple.h" +#include "gqb/gqbQueryObjs.h" +// GQB Images +#include "images/gqbColNotSel.pngc" +#include "images/gqbColSel.pngc" + +gqbGraphSimple::gqbGraphSimple() +{ + normalFont = settings->GetSystemFont(); + TableTitleFont = settings->GetSystemFont(); + TableTitleFont.SetWeight(wxFONTWEIGHT_BOLD); + BackgroundLayer1 = wxBrush(wxColour(112, 112, 112), wxSOLID); + BackgroundLayer2 = wxBrush (wxColour(208, 208, 208), wxSOLID); + BackgroundTitle = wxBrush (wxColour(245, 245, 245), wxSOLID); + minTableWidth = 80; + minTableHeight = 54; + rowHeight = 0; //By default but this it's replaced by font metrics value + rowLeftMargin = 14; + rowRightMargin = 5; + rowTopMargin = 1; + lineClickThreshold = 7; + selectedPen = wxPen(wxColour(0, 146, 195), 2, wxSOLID); + selectedBrush = wxBrush(wxColour(0, 146, 195), wxSOLID); + imgSelBoxEmpty = *gqbColNotSel_png_bmp; + imgSelBoxSelected = *gqbColSel_png_bmp; + +} + + +// NOTES:(1) store values of width & height at queryTable. +// (2)Need to set a font for the device context before get font metrics with GetTextExtent +void gqbGraphSimple::drawTable(wxMemoryDC &bdc, wxPoint *origin, gqbQueryObject *queryTable) +{ + +#if wxCHECK_VERSION(2, 9, 0) + wxCoord w = 0, h = 0, height = 0, width = 0, margin = 5; +#else + long w = 0, h = 0, height = 0, width = 0, margin = 5; +#endif + + // Get Value for row Height + if(!rowHeight) + { + bdc.SetFont(TableTitleFont); + bdc.GetTextExtent(wxT("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxtz"), &w, &h); + rowHeight = h; + } + + // Get Title Metrics + bdc.SetFont(TableTitleFont); + height += rowHeight + rowTopMargin; + + // Calculate font metrics for table title with/without alias + if(queryTable->getAlias().length() > 0) + bdc.GetTextExtent(queryTable->getName() + wxT(" (") + queryTable->getAlias() + wxT(")"), &w, &h); + else + bdc.GetTextExtent(queryTable->getName(), &w, &h); + width = rowLeftMargin + w + rowRightMargin; + + // Get Columns Metrics + bdc.SetFont(normalFont); + + // Don't use h value from font metrics to get consistency between columns vertical separation (height) + height += rowHeight * queryTable->parent->countCols() + rowTopMargin * queryTable->parent->countCols(); + gqbIteratorBase *iterator = queryTable->parent->createColumnsIterator(); + while(iterator->HasNext()) + { + gqbColumn *tmp = (gqbColumn *)iterator->Next(); + bdc.GetTextExtent(tmp->getName(), &w, &h); + if((rowLeftMargin + w + rowRightMargin) > width) + width = rowLeftMargin + w + rowRightMargin; + } + + //Don't delete iterator because will be use below; + + // Set table Size in ObjectModel (Temporary Values for object representation, + // and for this reason the view can modified model without using the controller + // because this values are used by controller when use object's size in internal operations) + if( (height + 2) < minTableHeight) // +2 from BackgroundLayers addition + { + queryTable->setHeight(minTableHeight); + height = minTableHeight; + } + else + queryTable->setHeight(height + 2); + + if( (width + 2) < minTableWidth) + { + queryTable->setWidth(minTableWidth); + width = minTableWidth; + } + else + queryTable->setWidth(width + 2); + + //Decorate Table + bdc.SetPen(*wxTRANSPARENT_PEN); + + //draw second Layer + bdc.SetBrush(BackgroundLayer2); + bdc.DrawRectangle(wxRect(wxPoint(origin->x, origin->y), wxSize(width + 2, height + 2))); + + //draw third Layer + bdc.SetBrush(BackgroundLayer1); + bdc.DrawRectangle(wxRect(wxPoint(origin->x, origin->y), wxSize(width + 1, height + 1))); + + //draw real frame layer + bdc.SetBrush(*wxWHITE_BRUSH); + if(queryTable->getSelected()) + { + bdc.SetPen(selectedPen); + } + else + { + bdc.SetPen(*wxBLACK_PEN); + } + bdc.DrawRectangle(wxRect(wxPoint(origin->x, origin->y), wxSize(width, height))); + + //draw title layer + bdc.SetBrush(BackgroundTitle); + bdc.DrawRectangle(wxRect(wxPoint(origin->x, origin->y), wxSize(width, rowHeight + rowTopMargin))); + bdc.SetFont(TableTitleFont); + if(queryTable->getAlias().length() > 0) + bdc.DrawText(queryTable->getName() + wxT(" (") + queryTable->getAlias() + wxT(")"), origin->x + margin, origin->y + rowTopMargin); + else + bdc.DrawText(queryTable->getName(), origin->x + margin, origin->y + rowTopMargin); + bdc.SetFont(normalFont); + + // GQB-TODO: in a future reuse a little more the iterator creating it inside the Query or Table Object + // and only delete it when delete the query object. + + // Draw Columns + height = rowHeight + rowTopMargin; + iterator->ResetIterator(); + while(iterator->HasNext()) + { + gqbColumn *tmp = (gqbColumn *)iterator->Next(); + if(queryTable->existsColumn(tmp)) + { + bdc.SetTextForeground(* wxRED); + bdc.SetFont(normalFont); + bdc.DrawBitmap(imgSelBoxSelected, origin->x + 3, origin->y + height, true); + } + else + { + bdc.SetFont(normalFont); + bdc.DrawBitmap(imgSelBoxEmpty, origin->x + 3, origin->y + height, true); + } + bdc.DrawText(tmp->getName(), origin->x + rowLeftMargin, origin->y + height); + bdc.SetTextForeground( *wxBLACK); + height += rowHeight + rowTopMargin; + } + delete iterator; //now if delete because it's not needed anymore + +} + + +// return a column when a user click on a checkbox [0->16] x point +gqbColumn *gqbGraphSimple::getColumnAtPosition(wxPoint *clickPoint, gqbQueryObject *queryTable, int sensibility) +{ + int countCols = queryTable->parent->countCols(), colPos = -1; + if(countCols > 0) //exists any column + { + colPos = (clickPoint->y - queryTable->position.y) / (rowHeight + rowTopMargin); + } + + int x = clickPoint->x - queryTable->position.x; + if( (x > 0 && x < sensibility) && colPos > 0) + + // Because 0 is title + return queryTable->parent->getColumnAtIndex(colPos - 1); + else + return NULL; +} + + +void gqbGraphSimple::drawTempJoinLine(wxMemoryDC &bdc, wxPoint &origin, wxPoint &end) +{ + wxPoint anchorsUsed = wxPoint(0, 0); + + if(origin.x < end.x) + { + anchorsUsed.x = 1; + anchorsUsed.y = -1; + } + else + { + anchorsUsed.x = -1; + anchorsUsed.y = 1; + } + + drawJoin(bdc, origin, end, anchorsUsed, true, _equally); +} + + +void gqbGraphSimple::drawJoin(wxMemoryDC &bdc, wxPoint &origin, wxPoint &dest, wxPoint &anchorUsed, bool selected = false, type_Join joinKind = _equally) +{ + wxPoint origin2 = origin; + wxPoint dest2 = dest; + + if(selected) + { + bdc.SetPen(selectedPen); + bdc.SetBrush(selectedBrush); + } + else + { + bdc.SetPen(*wxBLACK_PEN); + bdc.SetBrush(*wxBLACK_BRUSH); + } + + // GQB-TODO: optimize this if possible, I know one other can be the same? + + // getAnchorsUsed() [-1==left] [1==right] x->origin y->destination + if(anchorUsed.x == 1) + { + bdc.DrawRectangle(origin.x, origin.y - 4, 8, 8); + origin2.x += 20; + } + else + { + bdc.DrawRectangle(origin.x - 8, origin.y - 4, 8, 8); + origin2.x -= 20; + } + + if(anchorUsed.y == 1) + { + bdc.DrawRectangle(dest.x, dest.y - 4, 8, 8); + dest2.x += 20; + } + else + { + bdc.DrawRectangle(dest.x - 8, dest.y - 4, 8, 8); + dest2.x -= 20; + } + + bdc.DrawLine(origin, origin2); + bdc.DrawLine(dest, dest2); + bdc.DrawLine(origin2, dest2); + + // Draw type of join + switch(joinKind) + { + case _equally: + bdc.DrawText(wxT("="), findLineMiddle(origin2, dest2)); + break; + case _lesser: + bdc.DrawText(wxT("<"), findLineMiddle(origin2, dest2)); + break; + case _greater: + bdc.DrawText(wxT(">"), findLineMiddle(origin2, dest2)); + break; + case _equlesser: + bdc.DrawText(wxT("<="), findLineMiddle(origin2, dest2)); + break; + case _equgreater: + bdc.DrawText(wxT(">="), findLineMiddle(origin2, dest2)); + break; + }; +} + + +// Return true if pt click over a threshold of the join, false if not +bool gqbGraphSimple::clickOnJoin(gqbQueryJoin *join, wxPoint &pt, wxPoint &origin, wxPoint &dest) +{ + + wxPoint origin2 = origin; + wxPoint dest2 = dest; + + if(join->getAnchorsUsed().x == 1) + { + origin2.x += 20; + } + else + { + origin2.x -= 20; + } + + if(join->getAnchorsUsed().y == 1) + { + dest2.x += 20; + } + else + { + dest2.x -= 20; + } + + // Check origin anchor + bool value1 = insideLine(pt, origin, origin2, lineClickThreshold); + + // Check dest anchor + bool value2 = insideLine(pt, dest, dest2, lineClickThreshold); + + // Check line between both tables + bool value3 = insideLine(pt, origin2, dest2, lineClickThreshold); + + if(value1 || value2 || value3) + return true; + else + return false; +} + + +bool gqbGraphSimple::insideLine(wxPoint &pt, wxPoint &p1, wxPoint &p2, int threshold = 7) +{ + bool value = false; + if(distanceToLine(pt, p1, p2) < threshold) + { + value = true; + } + return value; +} + + +wxPoint gqbGraphSimple::findLineMiddle(wxPoint p1, wxPoint p2) +{ + int middleX = -1, middleY = -1; + + int dx = p2.x - p1.x; + if(dx > 0) // p1 at left + { + middleX = dx / 2 + p1.x; + } // p1 at right + else + { + middleX = p1.x + dx / 2; + } + + int dy = p2.y - p1.y; + if(dy > 0) // p1 is above + { + middleY = dy / 2 + p1.y; + } // p1 is below + else + { + middleY = p1.y + dy / 2; + } + + if(dy == 0) + middleY = p1.y; + if(dx == 0) + middleX = p1.x; + + return wxPoint(middleX, middleY); +} + + +double gqbGraphSimple::distanceToLine(wxPoint pt, wxPoint p1, wxPoint p2) +{ + p2.x -= p1.x; + p2.y -= p1.y; + + pt.x -= p1.x; + pt.y -= p1.y; + + double dprod = pt.x * p2.x + pt.y * p2.y; + double pLenSq; + + if(dprod <= 0.0) + { + pLenSq = 0.0; + } + else + { + pt.x = p2.x - pt.x; + pt.y = p2.y - pt.y; + dprod = pt.x * p2.x + pt.y * p2.y; + if(dprod <= 0.0) + { + pLenSq = 0.0; + } + else + { + pLenSq = dprod * dprod / (p2.x * p2.x + p2.y * p2.y); + } + } + + double lengthSq = pt.x * pt.x + pt.y * pt.y - pLenSq; + + if(lengthSq < 0) + { + lengthSq = 0; + } + + double length = sqrt(lengthSq); + + return length; +} + + +// Set the anchors points [source, destination] for a join +void gqbGraphSimple::calcAnchorPoint(gqbQueryJoin *join) +{ + int index, x, y; + wxPoint use; // [-1==left] [1==right] x->origin y->destination + int sx = join->getSourceQTable()->position.x; + int sy = join->getSourceQTable()->position.y; + int dx = join->getDestQTable()->position.x; + int dy = join->getDestQTable()->position.y; + + // Source + index = join->getSourceQTable()->getColumnIndex(join->getSCol()) + 1; + if(sx < dx) + { + x = sx + join->getSourceQTable()->getWidth(); + use.x = 1; + } + else + { + x = sx; + use.x = -1; + } + y = sy + index * (rowHeight + rowTopMargin) + ((rowHeight + rowTopMargin) / 2); + join->setSourceAnchor(wxPoint(x, y)); + + // Destination + index = join->getDestQTable()->getColumnIndex(join->getDCol()) + 1; + if(dx < sx) + { + x = dx + join->getDestQTable()->getWidth(); + use.y = 1; + } + else + { + x = dx; + use.y = -1; + } + y = dy + index * (rowHeight + rowTopMargin) + ((rowHeight + rowTopMargin) / 2); + join->setDestAnchor(wxPoint(x, y)); + + join->setAnchorsUsed(use); +} + + +// Update position of Object in the query if move table & adjust all other items like joins (own & registered) +void gqbGraphSimple::UpdatePosObject(gqbQueryObject *queryTable, int x, int y, int cursorAdjustment) +{ + x -= cursorAdjustment; // Move Pointer to a better Position; + y -= rowHeight / 2; + + // Update position of table + // Do not allow table/view moved/repositioned less than (0, 0) cordinates + queryTable->position.x = x > 0 ? x : 0; + queryTable->position.y = y > 0 ? y : 0; + + // Update position of anchor points of Joins that origin from this table + if(queryTable->getHaveJoins()) + { + gqbIteratorBase *j = queryTable->createJoinsIterator(); + while(j->HasNext()) + { + gqbQueryJoin *tmp = (gqbQueryJoin *)j->Next(); + calcAnchorPoint(tmp); + } + delete j; + } + + // Update position of anchor points of Joins that come from others tables + if(queryTable->getHaveRegJoins()) + { + gqbIteratorBase *r = queryTable->createRegJoinsIterator(); + while(r->HasNext()) + { + gqbQueryJoin *tmp = (gqbQueryJoin *)r->Next(); + calcAnchorPoint(tmp); + } + delete r; + } +} + + +int gqbGraphSimple::getTitleRowHeight() +{ + return rowHeight; +} diff --git a/gqb/gqbGridJoinTable.cpp b/gqb/gqbGridJoinTable.cpp new file mode 100644 index 0000000..6318566 --- /dev/null +++ b/gqb/gqbGridJoinTable.cpp @@ -0,0 +1,287 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbGridJoinTable.cpp - Table implementation for Joins Panel Grid +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include +#include + +// App headers +#include "gqb/gqbGridJoinTable.h" +#include "gqb/gqbGridRestTable.h" +#include "gqb/gqbColumn.h" +#include "gqb/gqbQueryObjs.h" +#include "gqb/gqbViewController.h" + +gqbGridJoinTable::gqbGridJoinTable(gqbController *_controller): + wxGridTableBase() +{ + controller = _controller; +} + + +gqbGridJoinTable::~gqbGridJoinTable() +{ + emptyTableData(); +} + + +int gqbGridJoinTable::GetNumberRows() +{ + return joins.count(); +} + + +int gqbGridJoinTable::GetNumberCols() +{ + return 3; +} + + +bool gqbGridJoinTable::IsEmptyCell( int row, int col ) +{ + if (joins.count() == 0) + return true; + return false; +} + + +wxString gqbGridJoinTable::GetValue( int row, int col ) +{ + if (row >= joins.count()) + return wxEmptyString; + gqbQueryJoin *obj = (gqbQueryJoin *)joins.getItemAt(row); + + switch(col) + { + case 0: + { + gqbQueryObject *srcTbl = obj->getSourceQTable(); + wxString sStr = srcTbl ? (srcTbl->getAlias().IsEmpty() ? qtIdent(srcTbl->getName()) : qtIdent(srcTbl->getAlias())) : wxString(wxEmptyString); + if ( !sStr.IsEmpty() ) + sStr += wxT(".") + qtIdent(obj->getSourceCol()); + return sStr; + } + case 1: + switch(obj->getKindofJoin()) + { + case _equally: + return wxT("="); + case _lesser: + return wxT("<"); + case _greater: + return wxT(">"); + case _equlesser: + return wxT("<="); + case _equgreater: + return wxT(">="); + } + return wxEmptyString; + case 2: + { + gqbQueryObject *destTbl = obj->getDestQTable(); + wxString dStr = destTbl ? (destTbl->getAlias().IsEmpty() ? qtIdent(destTbl->getName()) : qtIdent(destTbl->getAlias())) : wxString(wxEmptyString); + if ( !dStr.IsEmpty() ) + dStr += wxT(".") + obj->getDestCol(); + return dStr; + } + break; + }; + return wxT(""); +} + + +void gqbGridJoinTable::SetValue( int row, int col, const wxString &value ) +{ + if (col == 1) + { + gqbQueryJoin *join = (gqbQueryJoin *)joins.getItemAt(row); + if (value == wxT("=")) + join->setKindofJoin(_equally); + else if (value == wxT("<")) + join->setKindofJoin(_lesser); + else if (value == wxT(">")) + join->setKindofJoin(_greater); + else if (value == wxT("<=")) + join->setKindofJoin(_equlesser); + else if (value == wxT(">=")) + join->setKindofJoin(_equgreater); + controller->getView()->Refresh(); + } +} + +bool gqbGridJoinTable::ReplaceJoin( gqbQueryJoin *orig, gqbQueryJoin *newVal ) +{ + int rowCount = joins.count(); + for ( int index = 0; index < rowCount; index++ ) + { + if ( joins[ index ] == orig ) + { + joins[ index ] = newVal; + return true; + } + } + return false; +} + +gqbQueryJoin *gqbGridJoinTable::GetJoin( int row ) +{ + if (row >= joins.count()) + return NULL; + return (gqbQueryJoin *)joins.getItemAt(row); +} + + +void gqbGridJoinTable::removeJoin(gqbQueryJoin *item) +{ + if (item == NULL || this->joins.count() == 0) + return; + int index = joins.getIndex( item ); + if (index == -1) + return; + joins.removeItem( item ); + if (GetView()) + { + wxGridTableMessage msg( this, + wxGRIDTABLE_NOTIFY_ROWS_DELETED, + index + 1, + 1 ); + GetView()->ProcessTableMessage( msg ); + } +} + +void gqbGridJoinTable::removeJoins(gqbQueryObject *obj) +{ + if (!obj) + return; + + if (obj->getHaveJoins()) + { + gqbIteratorBase *itrJoins = obj->createJoinsIterator(); + if (itrJoins) + { + while (itrJoins->HasNext()) + { + gqbQueryJoin *tmp = (gqbQueryJoin *)itrJoins->Next(); + removeJoin(tmp); + } + } + } + + if (obj->getHaveRegJoins()) + { + gqbIteratorBase *itrRegJoins = obj->createRegJoinsIterator(); + if (itrRegJoins) + { + while (itrRegJoins->HasNext()) + { + gqbQueryJoin *tmp = (gqbQueryJoin *)itrRegJoins->Next(); + removeJoin(tmp); + } + } + } +} + +void gqbGridJoinTable::AppendJoin(gqbQueryJoin *item) +{ + bool notify = true; + if ( item == NULL ) + { + item = new gqbQueryJoin(NULL, NULL, NULL, NULL, _equally); + } + joins.addItem( item ); + if (notify && GetView() ) + { + wxGridTableMessage msg( this, + wxGRIDTABLE_NOTIFY_ROWS_INSERTED, + joins.count(), + 1 ); + GetView()->ProcessTableMessage( msg ); + + int row = GetView()->GetNumberRows() - 1; + + wxString strChoices[] = {wxT("="), wxT("<"), wxT("<="), wxT(">"), wxT(">=")}; + + GetView()->SetCellRenderer(row, 0, new wxGridCellButtonRenderer); + GetView()->SetCellRenderer(row, 1, new wxGridCellComboBoxRenderer); + GetView()->SetCellEditor(row, 1, new dxGridCellSizedChoiceEditor(WXSIZEOF(strChoices), strChoices)); + GetView()->SetCellRenderer(row, 2, new wxGridCellButtonRenderer); + + GetView()->SetReadOnly( row, 0 ); + GetView()->SetReadOnly( row, 2 ); + } +} + + +// Removes all items from gqbGridJoinTable +void gqbGridJoinTable::emptyTableData() +{ + for (int index = joins.count() - 1; index >= 0; index--) + { + gqbQueryJoin *join = (gqbQueryJoin *)joins[index]; + joins.removeItem(join); + + // Join with either source or destination not present needs to be removed here + if (!(join->getSourceQTable() && join->getDestQTable())) + { + delete join; + join = NULL; + } + } +} + +gqbQueryObject *gqbGridJoinTable::DeleteRow(size_t pos) +{ + gqbQueryJoin *join = (gqbQueryJoin *)joins.getItemAt(pos); + gqbQueryObject *srcTbl = NULL; + if (join) + { + this->removeJoin(join); + if (join->getSourceQTable() && join->getDestQTable()) + { + srcTbl = join->getSourceQTable(); + srcTbl->removeJoin(join, true); + } + } + + return srcTbl; +} + +wxString gqbGridJoinTable::GetColLabelValue(int col) +{ + switch(col) + { + case 0: + return _("Source Column"); + case 1: + return _("Join Type"); + case 2: + return _("Destination Column"); + } + return wxEmptyString; +} + + +void gqbGridJoinTable::selectJoin(gqbQueryJoin *join) +{ + int indexRow = joins.getIndex(join); + if (indexRow != -1 && GetView()) + { + GetView()->ClearSelection(); + GetView()->SelectRow(indexRow); + } +} + diff --git a/gqb/gqbGridOrderTable.cpp b/gqb/gqbGridOrderTable.cpp new file mode 100644 index 0000000..1252cec --- /dev/null +++ b/gqb/gqbGridOrderTable.cpp @@ -0,0 +1,293 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbGridOrderTable.cpp - Table implementation for Order By Panel Grid +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "gqb/gqbGridOrderTable.h" +#include "gqb/gqbColumn.h" +#include "gqb/gqbArrayCollection.h" +#include "gqb/gqbModel.h" + +gqbGridOrderTable::gqbGridOrderTable(int numColumns, gqbObjsArray *cols, gqbObjsArray *parent, charArray *orderBy) +{ + numberColumns = numColumns; + columns = cols; + colsParents = parent; + kindOfOrder = orderBy; +} + + +gqbGridOrderTable::~gqbGridOrderTable() +{ +} + + +int gqbGridOrderTable::GetNumberRows() +{ + return (columns->GetCount()); +} + + +int gqbGridOrderTable::GetNumberCols() +{ + return numberColumns; +} + + +bool gqbGridOrderTable::IsEmptyCell( int row, int col ) +{ + int count = columns->GetCount(); + if(row + 1 <= count) + return false; + else + return true; +} + + +wxString gqbGridOrderTable::GetValue( int row, int col ) +{ + if(col == 0) + { + wxString col = wxT(""); + if(((gqbQueryObject *)colsParents->Item(row))->getAlias().length() > 0) + { + col += ((gqbQueryObject *)colsParents->Item(row))->getAlias() + wxT("."); + } + else + { + col += ((gqbQueryObject *)colsParents->Item(row))->getName() + wxT("."); + } + col += ((gqbColumn *)columns->Item(row))->getName(); + return col; + } + + if(numberColumns == 2) + { + if(col == 1) + { + wxString ord = wxT(""); + if(kindOfOrder->Item(row) == 'A') + ord += wxT("ASC"); + else + ord += wxT("DESC"); + + return ord; + } + } + return wxT(""); +} + + +wxString gqbGridOrderTable::GetColLabelValue(int col) +{ + switch(col) + { + case 0: + if(numberColumns == 2) + { + return _("Column"); + } + else + { + return _("Available Columns"); + } + break; + case 1: + return _("Order"); + break; + }; + return wxT(""); +} + + +void gqbGridOrderTable::SetValue( int row, int col, const wxString &value ) +{ + if(col == 1 && numberColumns == 2) + { + if(value.Contains(wxT("ASC"))) + { + kindOfOrder->Item(row) = 'A'; + } + else + { + kindOfOrder->Item(row) = 'D'; + } + } +} + + +void gqbGridOrderTable::AppendItem(gqbColumn *column, gqbQueryObject *parent, char kindOrder) +{ + columns->Add(column); + colsParents->Add(parent); + if(numberColumns == 2) + { + kindOfOrder->Add(kindOrder); + } + + if (GetView() ) + { + wxGridTableMessage msg( this, + wxGRIDTABLE_NOTIFY_ROWS_INSERTED, + (columns->GetCount() - 1), + 1 ); + GetView()->ProcessTableMessage( msg ); + } +} + + +bool gqbGridOrderTable::removeFirstRow(gqbObject *itemTable) +{ + bool found = false; + int i, size = colsParents->GetCount(); + + for(i = 0; i < size; i++) + { + if (colsParents->Item(i) == itemTable) + { + found = true; + break; + } + } + + if(found) + { + columns->RemoveAt(i); + colsParents->RemoveAt(i); + if(numberColumns == 2) + { + kindOfOrder->RemoveAt(i); + } + if ( GetView() ) // Notify Grid about the change + { + wxGridTableMessage msg( this, + wxGRIDTABLE_NOTIFY_ROWS_DELETED, + i + 1, + 1 ); + GetView()->ProcessTableMessage( msg ); + } + } + + return found; +} + + +void gqbGridOrderTable::emptyTableData(gqbQueryObject *object) +{ + // Because items positions on array changes when I delete one, I have to do the remove in this way + while(removeFirstRow(object)); +} + + +void gqbGridOrderTable::removeRowAt(int i) +{ + columns->RemoveAt(i); + colsParents->RemoveAt(i); + if(numberColumns == 2) + { + kindOfOrder->RemoveAt(i); + } + // Notify Grid about the change + if ( GetView() ) + { + wxGridTableMessage msg( this, + wxGRIDTABLE_NOTIFY_ROWS_DELETED, + i + 1, + 1 ); + GetView()->ProcessTableMessage( msg ); + } +} + + +gqbObject *gqbGridOrderTable::getObjectAt(int pos, int col) +{ + gqbObject *value = NULL; + switch(col) + { + case 0: + value = columns->Item(pos); + break; + case 1: + value = colsParents->Item(pos); + break; + }; + return value; +} + + +void gqbGridOrderTable::changesPositions(int sPos, int dPos) +{ + + int size = columns->GetCount(); + gqbObject *tmpTable = NULL, *tmpColumn = NULL; + char tmpKind = 'N'; + + if( (sPos >= 0 && sPos < size) && (dPos >= 0 && dPos < size) ) + { + tmpTable = colsParents->Item(sPos); + tmpColumn = columns->Item(sPos); + tmpKind = kindOfOrder->Item(sPos); + + colsParents->Item(sPos) = colsParents->Item(dPos); + columns->Item(sPos) = columns->Item(dPos); + kindOfOrder->Item(sPos) = kindOfOrder->Item(dPos); + colsParents->Item(dPos) = tmpTable; + columns->Item(dPos) = tmpColumn; + kindOfOrder->Item(dPos) = tmpKind; + } + + wxGridTableMessage msg( this, + wxGRIDTABLE_REQUEST_VIEW_GET_VALUES, + sPos, + 1 ); + GetView()->ProcessTableMessage( msg ); + +} + + +// GQB-TODO: optimize this functions & related buttons events at gqbView because works but are a mess. +// Change a single row or a range to one pos up or down (but no more than one position) +void gqbGridOrderTable::changesRangeOnePos(int topPos, int bottomPos, int newTop) +{ + // Eliminate side effect of zero base array on calculations, but careful newTop still it's zero based + topPos++; + bottomPos++; + int sizeRange = bottomPos - (topPos - 1), size = GetNumberRows(); + if(topPos > newTop) // Go Down + { + // Only if the movement don't create an overflow + if( (topPos > 1) && ((newTop + sizeRange) < size) ) + { + for(int i = newTop ; i < (newTop + sizeRange) ; i++) + { + changesPositions(i, i + 1); + } + } + + } // Go Up + else + { + // Only if the movement don't create an overflow + if( (bottomPos < size) && ((newTop + sizeRange) <= size) ) + { + // Go Up Down + for(int i = (newTop + sizeRange - 1) ; i >= newTop ; i--) + { + changesPositions(i - 1, i); + } + } + } +} diff --git a/gqb/gqbGridProjTable.cpp b/gqb/gqbGridProjTable.cpp new file mode 100644 index 0000000..46e332b --- /dev/null +++ b/gqb/gqbGridProjTable.cpp @@ -0,0 +1,327 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbGridProjTable.cpp - Table implementation for Projection Panel Grid +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include +#include + +// App headers +#include "gqb/gqbGridProjTable.h" +#include "gqb/gqbColumn.h" +#include "gqb/gqbQueryObjs.h" + +gqbGridProjTable::gqbGridProjTable(gqbObjsArray *position, gqbObjsArray *parent, wxArrayString *alias): + wxGridTableBase() +{ + colsPosition = position; + colsParents = parent; + columnsAlias = alias; + // GQB-TODO: replace above pointers array with local variable if possible or research what it's causing bug in destructor??? +} + + +gqbGridProjTable::~gqbGridProjTable() +{ +} + + +int gqbGridProjTable::GetNumberRows() +{ + return (colsPosition->GetCount()); +} + + +int gqbGridProjTable::GetNumberCols() +{ + + return 3; +} + + +bool gqbGridProjTable::IsEmptyCell( int row, int col ) +{ + + int count = colsParents->GetCount(); + if(row + 1 <= count) + return false; + else + return true; +} + + +wxString gqbGridProjTable::GetValue( int row, int col ) +{ + switch(col) + { + case 0: + if(((gqbQueryObject *)colsParents->Item(row))->getAlias().length() > 0) + { + return ((gqbQueryObject *)colsParents->Item(row))->getAlias(); + } + else + { + return ((gqbQueryObject *)colsParents->Item(row))->getName(); + } + break; + case 1: + return ((gqbColumn *)colsPosition->Item(row))->getName(); + break; + case 2: + return columnsAlias->Item(row); + break; + }; + return wxT(""); +} + + +wxString gqbGridProjTable::GetColLabelValue( int col) +{ + switch(col) + { + case 0: + return _("Relation"); + break; + case 1: + return _("Column"); + break; + case 2: + return _("Alias"); + break; + }; + return wxT(""); +} + + +void gqbGridProjTable::SetValue( int row, int col, const wxString &value ) +{ + // Do nothing on values that cannot be edited on this model [Column & Relation Name] + switch(col) + { + case 2: + columnsAlias->Item(row) = value; + break; + }; +} + +void *gqbGridProjTable::GetValueAsCustom( int row, int col, const wxString &typeName ) +{ + switch(col) + { + case 0: + return (void *)&colsParents->Item(row); + break; + case 1: + return (void *)&colsPosition->Item(row); + break; + case 2: + break; + }; + return NULL; +} + + +void gqbGridProjTable::SetValueAsCustom( int row, int col, const wxString &typeName, void *value ) +{ + switch(col) + { + case 0: + colsParents->Add(((gqbQueryObject *)value)); + break; + case 1: + colsPosition->Add(((gqbColumn *)value)); + }; +} + + +void gqbGridProjTable::AppendItem(int col, gqbObject *item) +{ + bool notify = false; + switch(col) + { + case 0: + colsParents->Add(item); + break; + case 1: + colsPosition->Add(item); + notify = true; + break; + case 2: + columnsAlias->Add(wxT("")); + break; + }; + + if (notify && GetView() ) + { + wxGridTableMessage msg( this, + wxGRIDTABLE_NOTIFY_ROWS_INSERTED, + (colsParents->GetCount() - 1), + 1 ); + GetView()->ProcessTableMessage( msg ); + + // Set the cells read-only + GetView()->SetReadOnly(GetView()->GetNumberRows() - 1, 0); + GetView()->SetReadOnly(GetView()->GetNumberRows() - 1, 1); + } + +} + +// Remove a column at the grid +bool gqbGridProjTable::removeRow(gqbObject *itemTable, gqbObject *itemColumn) +{ + bool found = false; + int i, size = colsPosition->GetCount(); + + for(i = 0; i < size; i++) + { + if (colsParents->Item(i) == itemTable && colsPosition->Item(i) == itemColumn) + { + found = true; + break; + } + } + + if(found) + { + colsParents->RemoveAt(i); + colsPosition->RemoveAt(i); + columnsAlias->RemoveAt(i); + + if ( GetView() ) // Notify Grid about the change + { + wxGridTableMessage msg( this, + wxGRIDTABLE_NOTIFY_ROWS_DELETED, + i + 1, + 1 ); + GetView()->ProcessTableMessage( msg ); + } + } + + return found; +} + + +void gqbGridProjTable::removeAllRows(gqbObject *itemTable) +{ + + int size = colsParents->GetCount(); + for(int i = (size - 1); i >= 0; i--) + { + if (colsParents->Item(i) == itemTable) + { + colsParents->RemoveAt(i); + colsPosition->RemoveAt(i); + columnsAlias->RemoveAt(i); + + // Notify Grid about the change + if ( GetView() ) + { + wxGridTableMessage msg( this, + wxGRIDTABLE_NOTIFY_ROWS_DELETED, + i + 1, + 1 ); + GetView()->ProcessTableMessage( msg ); + } + } + } +} + + +void gqbGridProjTable::changesPositions(int sPos, int dPos) +{ + + int size = colsPosition->GetCount(); + gqbObject *tmpTable = NULL, *tmpColumn = NULL; + wxString tmpAlias = wxT(""); + + if( (sPos >= 0 && sPos < size) && (dPos >= 0 && dPos < size) ) + { + tmpTable = colsParents->Item(sPos); + tmpColumn = colsPosition->Item(sPos); + tmpAlias = columnsAlias->Item(sPos); + + colsParents->Item(sPos) = colsParents->Item(dPos); + colsPosition->Item(sPos) = colsPosition->Item(dPos); + columnsAlias->Item(sPos) = columnsAlias->Item(dPos); + colsParents->Item(dPos) = tmpTable; + colsPosition->Item(dPos) = tmpColumn; + columnsAlias->Item(dPos) = tmpAlias; + } + + wxGridTableMessage msg( this, + wxGRIDTABLE_REQUEST_VIEW_GET_VALUES, + sPos, + 1 ); + GetView()->ProcessTableMessage( msg ); + +} + + +// GQB-TODO: optimize this functions & related buttons events at gqbView because works but are a mess. +// Change a single row or a range to one pos up or down (but no more than one position) +void gqbGridProjTable::changesRangeOnePos(int topPos, int bottomPos, int newTop) +{ + // Eliminate side effect of zero base array on calculations, but careful newTop still it's zero based + topPos++; + bottomPos++; + int sizeRange = bottomPos - (topPos - 1), size = GetNumberRows(); + if(topPos > newTop) // Go Down + { + // Only if the movement don't create an overflow + if( (topPos > 1) && ((newTop + sizeRange) < size) ) + { + for(int i = newTop ; i < (newTop + sizeRange) ; i++) + { + changesPositions(i, i + 1); + } + } + + } // Go Up + else + { + // Only if the movement don't create an overflow + if( (bottomPos < size) && ((newTop + sizeRange) <= size) ) + { + // Go Up Down + for(int i = (newTop + sizeRange - 1) ; i >= newTop ; i--) + { + changesPositions(i - 1, i); + } + } + } +} + + +// Removes all items from gqbGridProjTable +void gqbGridProjTable::emptyTableData() +{ + + int count = colsPosition->GetCount(); + colsPosition->Empty(); + colsParents->Empty(); + columnsAlias->Empty(); + + // Notify Grid about the change + if ( GetView() ) + { + wxGridTableMessage msg( this, + wxGRIDTABLE_NOTIFY_ROWS_DELETED, + 1, + count); + GetView()->ProcessTableMessage( msg ); + } +} + diff --git a/gqb/gqbGridRestTable.cpp b/gqb/gqbGridRestTable.cpp new file mode 100644 index 0000000..f086a55 --- /dev/null +++ b/gqb/gqbGridRestTable.cpp @@ -0,0 +1,372 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbGridRestTable.cpp - Table implementation for Restrictions Panel Grid +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include + +// App headers +#include "gqb/gqbGridRestTable.h" +#include "gqb/gqbColumn.h" +#include "gqb/gqbQueryObjs.h" +#include "gqb/gqbViewPanels.h" + +gqbGridRestTable::gqbGridRestTable(gqbRestrictions *_restrictions): + wxGridTableBase() +{ + restrictions = _restrictions; +} + + +gqbGridRestTable::~gqbGridRestTable() +{ +} + + +int gqbGridRestTable::GetNumberRows() +{ + return (restrictions->restrictionsCount()); +} + + +int gqbGridRestTable::GetNumberCols() +{ + return 4; +} + + +bool gqbGridRestTable::IsEmptyCell( int row, int col ) +{ + + int count = restrictions->restrictionsCount(); + if(row + 1 <= count) + return false; + else + return true; +} + + +wxString gqbGridRestTable::GetValue( int row, int col ) +{ + switch(col) + { + case 0: + return ((gqbQueryRestriction *)restrictions->getRestrictionAt(row))->getLeft(); + break; + case 1: + return ((gqbQueryRestriction *)restrictions->getRestrictionAt(row))->getRestriction(); + break; + case 2: + return ((gqbQueryRestriction *)restrictions->getRestrictionAt(row))->getValue_s(); + break; + case 3: + return ((gqbQueryRestriction *)restrictions->getRestrictionAt(row))->getConnector(); + break; + }; + + return wxT(""); +} + + +wxString gqbGridRestTable::GetColLabelValue( int col) +{ + switch(col) + { + case 0: + return _("Restricted Value"); + break; + case 1: + return _("Operator"); + break; + case 2: + return _("Value"); + break; + case 3: + return _("Connector"); + break; + }; + return wxT(""); +} + + +void gqbGridRestTable::SetValue( int row, int col, const wxString &value ) +{ + switch(col) + { + case 0: + ((gqbQueryRestriction *)restrictions->getRestrictionAt(row))->setLeft(value); + break; + case 1: + ((gqbQueryRestriction *)restrictions->getRestrictionAt(row))->setRestriction(value); + break; + case 2: + ((gqbQueryRestriction *)restrictions->getRestrictionAt(row))->setValue_s(value); + break; + case 3: + ((gqbQueryRestriction *)restrictions->getRestrictionAt(row))->setConnector(value); + break; + } +} + + +void gqbGridRestTable::AppendItem(gqbQueryRestriction *item) +{ + bool notify = true; + + restrictions->addRestriction(item); + + if (notify && GetView() ) + { + wxGridTableMessage msg( this, + wxGRIDTABLE_NOTIFY_ROWS_INSERTED, + (restrictions->restrictionsCount() - 1), + 1 ); + GetView()->ProcessTableMessage( msg ); + } + +} + + +bool gqbGridRestTable::DeleteRows(size_t pos = 0, size_t numRows = 1) +{ + if((pos < (size_t)GetNumberRows()) && numRows == 1) + { + gqbQueryRestriction *r = restrictions->getRestrictionAt(pos); + restrictions->removeRestriction(r); + + // Notify Grid about the change + if ( GetView() ) + { + wxGridTableMessage msg( this, + wxGRIDTABLE_NOTIFY_ROWS_DELETED, + pos, + 1 ); + GetView()->ProcessTableMessage( msg ); + } + + delete r; + return true; + } + else + return false; +} + + +// Removes all items from gqbGridTable +void gqbGridRestTable::emptyTableData() +{ + + int count = restrictions->restrictionsCount(); + restrictions->deleteAllRestrictions(); + + if ( GetView() ) //Notify Grid about the change + { + wxGridTableMessage msg( this, + wxGRIDTABLE_NOTIFY_ROWS_DELETED, + 1, + count); + GetView()->ProcessTableMessage( msg ); + } +} + + +// +// Cell rendering utilities classes +// + +void wxGridCellComboBoxRenderer::Draw(wxGrid &grid, wxGridCellAttr &attr, wxDC &dc, + const wxRect &rectCell, int row, int col, bool isSelected) +{ + wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected); + + // first calculate button size + // don't draw outside the cell + int nButtonWidth = 17; + if (rectCell.height < 2) return; + wxRect rectButton; + rectButton.x = rectCell.x + rectCell.width - nButtonWidth; + rectButton.y = rectCell.y + 1; + int cell_rows, cell_cols; + attr.GetSize(&cell_rows, &cell_cols); + rectButton.width = nButtonWidth; + if (cell_rows == 1) + rectButton.height = rectCell.height - 2; + else + rectButton.height = nButtonWidth; + + SetTextColoursAndFont(grid, attr, dc, isSelected); + int hAlign, vAlign; + attr.GetAlignment(&hAlign, &vAlign); + + // Leave room for button + wxRect rect = rectCell; + rect.SetWidth(rectCell.GetWidth() - rectButton.GetWidth() - 2); + rect.Inflate(-1); + grid.DrawTextRectangle(dc, grid.GetCellValue(row, col), rect, hAlign, vAlign); + + // Don't bother drawing if the cell is too small + if (rectButton.height < 4 || rectButton.width < 4) + return; + + // Draw 3-d button + wxColour colourBackGround = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE); + dc.SetBrush(wxBrush(colourBackGround, wxSOLID)); + dc.SetPen(wxPen(colourBackGround, 1, wxSOLID)); + dc.DrawRectangle(rectButton); + dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT), 1, wxSOLID)); + dc.DrawLine(rectButton.GetLeft(), rectButton.GetBottom(), + rectButton.GetRight(), rectButton.GetBottom()); + dc.DrawLine(rectButton.GetRight(), rectButton.GetBottom(), + rectButton.GetRight(), rectButton.GetTop() - 1); + dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW), + 1, wxSOLID)); + dc.DrawLine(rectButton.GetLeft() + 1, rectButton.GetBottom() - 1, + rectButton.GetRight() - 1, rectButton.GetBottom() - 1); + dc.DrawLine(rectButton.GetRight() - 1, rectButton.GetBottom() - 1, + rectButton.GetRight() - 1, rectButton.GetTop()); + dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNHIGHLIGHT), + 1, wxSOLID)); + dc.DrawLine(rectButton.GetRight() - 2, rectButton.GetTop() + 1, + rectButton.GetLeft() + 1, rectButton.GetTop() + 1); + dc.DrawLine(rectButton.GetLeft() + 1, rectButton.GetTop() + 1, + rectButton.GetLeft() + 1, rectButton.GetBottom() - 1); + + // Draw little triangle + int nTriWidth = 7; + int nTriHeight = 4; + wxPoint point[3]; + point[0] = wxPoint(rectButton.GetLeft() + (rectButton.GetWidth() - nTriWidth) / 2, + rectButton.GetTop() + (rectButton.GetHeight() - nTriHeight) / 2); + point[1] = wxPoint(point[0].x + nTriWidth - 1, point[0].y); + point[2] = wxPoint(point[0].x + 3, point[0].y + nTriHeight - 1); + dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT), wxSOLID)); + dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT), 1, wxSOLID)); + dc.DrawPolygon(3, point); + if (m_border == wxLAYOUT_TOP) + { + dc.SetPen(wxPen(*wxBLACK, 1, wxDOT)); + dc.DrawLine(rectCell.GetRight(), rectCell.GetTop(), + rectCell.GetLeft(), rectCell.GetTop()); + } +} + + +void wxGridCellButtonRenderer::Draw(wxGrid &grid, wxGridCellAttr &attr, wxDC &dc, + const wxRect &rectCell, int row, int col, bool isSelected) +{ + wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected); + + // First calculate button size + // don't draw outside the cell + int nButtonWidth = 17; + if (rectCell.height < 2) return; + wxRect rectButton; + rectButton.x = rectCell.x + rectCell.width - nButtonWidth; + rectButton.y = rectCell.y + 1; + int cell_rows, cell_cols; + attr.GetSize(&cell_rows, &cell_cols); + rectButton.width = nButtonWidth; + if (cell_rows == 1) + rectButton.height = rectCell.height - 2; + else + rectButton.height = nButtonWidth; + + SetTextColoursAndFont(grid, attr, dc, isSelected); + int hAlign, vAlign; + attr.GetAlignment(&hAlign, &vAlign); + + // Leave room for button + wxRect rect = rectCell; + rect.SetWidth(rectCell.GetWidth() - rectButton.GetWidth() - 2); + rect.Inflate(-1); + grid.DrawTextRectangle(dc, grid.GetCellValue(row, col), rect, hAlign, vAlign); + + + // Don't bother drawing if the cell is too small draw 3-d button + if (rectButton.height < 4 || rectButton.width < 4) + return; + + wxColour colourBackGround = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE); + dc.SetBrush(wxBrush(colourBackGround, wxSOLID)); + dc.SetPen(wxPen(colourBackGround, 1, wxSOLID)); + dc.DrawRectangle(rectButton); + dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT), 1, wxSOLID)); + dc.DrawLine(rectButton.GetLeft(), rectButton.GetBottom(), + rectButton.GetRight(), rectButton.GetBottom()); + dc.DrawLine(rectButton.GetRight(), rectButton.GetBottom(), + rectButton.GetRight(), rectButton.GetTop() - 1); + dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW), + 1, wxSOLID)); + dc.DrawLine(rectButton.GetLeft() + 1, rectButton.GetBottom() - 1, + rectButton.GetRight() - 1, rectButton.GetBottom() - 1); + dc.DrawLine(rectButton.GetRight() - 1, rectButton.GetBottom() - 1, + rectButton.GetRight() - 1, rectButton.GetTop()); + dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNHIGHLIGHT), + 1, wxSOLID)); + dc.DrawLine(rectButton.GetRight() - 2, rectButton.GetTop() + 1, + rectButton.GetLeft() + 1, rectButton.GetTop() + 1); + dc.DrawLine(rectButton.GetLeft() + 1, rectButton.GetTop() + 1, + rectButton.GetLeft() + 1, rectButton.GetBottom() - 1); + + // Draw little plus symbol + dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT), wxSOLID)); + dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT), 1, wxSOLID)); + int nPlusWidth = 7; + int nPlusHeight = 7; + wxPoint point[4]; + point[0] = wxPoint(rectButton.GetLeft() + (rectButton.GetWidth() - nPlusWidth) / 2, rectButton.GetTop() + (rectButton.GetHeight() / 2) - 1); + point[1] = wxPoint(point[0].x + nPlusWidth, point[0].y); + point[2] = wxPoint(rectButton.GetLeft() + (rectButton.GetWidth()) / 2, rectButton.GetTop() + (rectButton.GetHeight() - nPlusHeight) / 2); + point[3] = wxPoint(point[2].x, point[2].y + nPlusHeight); + dc.DrawLine(point[0], point[1]); + dc.DrawLine(point[2], point[3]); + + if (m_border == wxLAYOUT_TOP) + { + dc.SetPen(wxPen(*wxBLACK, 1, wxDOT)); + dc.DrawLine(rectCell.GetRight(), rectCell.GetTop(), + rectCell.GetLeft(), rectCell.GetTop()); + } +} + + +// +// Cell editing utilities classes +// +dxGridCellSizedChoiceEditor::dxGridCellSizedChoiceEditor(const wxArrayString &choices, bool allowOthers) + : wxGridCellChoiceEditor(choices, allowOthers) +{ +} + + +dxGridCellSizedChoiceEditor::dxGridCellSizedChoiceEditor(size_t count, const wxString choices[], bool allowOthers) + : wxGridCellChoiceEditor(count, choices, allowOthers) +{ +} + + +wxGridCellEditor *dxGridCellSizedChoiceEditor::Clone() const +{ + dxGridCellSizedChoiceEditor *editor = new + dxGridCellSizedChoiceEditor(); + return editor; +} + + +void dxGridCellSizedChoiceEditor::Show(bool show, wxGridCellAttr *attr) +{ + wxGridCellEditor::Show(show, attr); +} diff --git a/gqb/gqbModel.cpp b/gqb/gqbModel.cpp new file mode 100644 index 0000000..fa4d13d --- /dev/null +++ b/gqb/gqbModel.cpp @@ -0,0 +1,114 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbModel.cpp - Model of MVC Pattern for GQB +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "gqb/gqbModel.h" +#include "gqb/gqbQueryObjs.h" + +gqbModel::gqbModel(): + wxObject() +{ +// here store all queryObjects +// GQB-TODO: allow different names for each model + queryCollection = new gqbQueryObjs(); + restrictions = new gqbRestrictions(); + columnsAlias = new wxArrayString(); +} + + +// GQB-TODO: check this destructor is not complete +gqbModel::~gqbModel() +{ + if(queryCollection) + delete queryCollection; + + // Don't owns objects only remove then in both + colsPosition.Empty(); + colsParents.Empty(); + if(columnsAlias) + delete columnsAlias; + + //GQB-TODO: delete restrictions + if(restrictions) + delete restrictions; +} + + +gqbQueryObject *gqbModel::addTable(gqbTable *table, wxPoint p) +{ + // Get a table but introduce a QueryObject + gqbQueryObject *tmp = new gqbQueryObject(table); + tmp->position = p; + + // Now use insert the new object in the collection of the model + queryCollection->addTable(tmp); + + // Columns of added table should be possible to use on Order By Clause + gqbIteratorBase *iterator = tmp->parent->createColumnsIterator(); + while(iterator->HasNext()) + { + gqbColumn *col = (gqbColumn *)iterator->Next(); + AvailableColumns.Add(col); + ColumnAvailParent.Add(tmp); + } + delete iterator; + + return tmp; +} + + +gqbIteratorBase *gqbModel::createQueryIterator() +{ + return queryCollection->createQueryIterator(); +} + +gqbIteratorBase *gqbModel::createDownQueryIterator() +{ + return queryCollection->createDownQueryIterator(); +} + +void gqbModel::deleteTable(gqbQueryObject *modelTable) +{ + if(modelTable) + { + queryCollection->removeTable(modelTable); + delete modelTable; + modelTable = NULL; + } +} + + +int gqbModel::tablesCount() +{ + return queryCollection->tablesCount(); +} + + +void gqbModel::emptyAll() +{ + colsPosition.Empty(); + colsParents.Empty(); + queryCollection->removeAllQueryObjs(); + +} + + +gqbQueryRestriction *gqbModel::addRestriction() +{ + gqbQueryRestriction *r = new gqbQueryRestriction(); + restrictions->addRestriction(r); + return r; +} diff --git a/gqb/gqbObject.cpp b/gqb/gqbObject.cpp new file mode 100644 index 0000000..e5180dc --- /dev/null +++ b/gqb/gqbObject.cpp @@ -0,0 +1,32 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbObject.cpp - Main basic object used by GQB +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "gqb/gqbObject.h" + +gqbObject::gqbObject(wxString name, wxTreeItemData *owner, pgConn *connection, OID oid) +{ + Name = name; + Owner = owner; + conn = connection; + Oid = oid; +} + + +gqbObject::~gqbObject() +{ +} diff --git a/gqb/gqbObjectCollection.cpp b/gqb/gqbObjectCollection.cpp new file mode 100644 index 0000000..492cefb --- /dev/null +++ b/gqb/gqbObjectCollection.cpp @@ -0,0 +1,112 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbObjectCollection.cpp - A Collection of simple GQB objects +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "gqb/gqbObject.h" +#include "gqb/gqbObjectCollection.h" +#include "gqb/gqbCollection.h" +#include "gqb/gqbArrayCollection.h" + +gqbObjectCollection::gqbObjectCollection(wxString name, wxTreeItemData *owner, pgConn *connection, OID oid) + : gqbObject(name, owner, connection, oid) +{ + // Create the concrete implementation of the Collection, right now only one implementation not need parameter + implementation = new gqbArrayCollection(); + + // Create the collection using the concrete implementation + // use the array implementation of the collection + objectsCollection = new gqbCollection(implementation); +} + + +gqbObjectCollection::~gqbObjectCollection() +{ + if(objectsCollection) // Implementation is deleted when delete the collection & shouldn't be deleted again + delete objectsCollection; +} + + +void gqbObjectCollection::addObject(gqbObject *object) +{ + objectsCollection->addItem(object); +} + + +void gqbObjectCollection::removeObject(gqbObject *object) +{ + objectsCollection->removeItem(object); +} + + +gqbIteratorBase *gqbObjectCollection::createIterator() +{ + return objectsCollection->createIterator(); +} + +gqbIteratorBase *gqbObjectCollection::createDownIterator() +{ + return objectsCollection->createDownIterator(); +} + +int gqbObjectCollection::countObjects() +{ + return objectsCollection->count(); +} + + +gqbObject *gqbObjectCollection::getObjectAtIndex(int index) +{ + return objectsCollection->getItemAt(index); +} + + +bool gqbObjectCollection::existsObject(gqbObject *object) +{ + return objectsCollection->existsObject(object); +} + + +// Remove all objects from collection without deleting each one. +void gqbObjectCollection::removeAll() +{ + objectsCollection->removeAll(); +} + + +int gqbObjectCollection::indexObject(gqbObject *object) +{ + return objectsCollection->getIndex(object); +} + + +void gqbObjectCollection::insertObjectAt(gqbObject *object, int index) +{ + objectsCollection->insertAtIndex(object, index); +} + + +int gqbObjectCollection::getCount() +{ + return objectsCollection->count(); +} + + +// Remove & delete all objects +void gqbObjectCollection::deleteAll() +{ + objectsCollection->deleteAll(); +} diff --git a/gqb/gqbQueryObjs.cpp b/gqb/gqbQueryObjs.cpp new file mode 100644 index 0000000..34076a5 --- /dev/null +++ b/gqb/gqbQueryObjs.cpp @@ -0,0 +1,513 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbQueryObjs.cpp - All objects used by a model of a query in the MVC Pattern model. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "gqb/gqbTable.h" +#include "gqb/gqbColumn.h" +#include "gqb/gqbQueryObjs.h" +#include "gqb/gqbObjectCollection.h" +#include "gqb/gqbViewPanels.h" + +// +// Collections of Tables inside a Query, data structured used for query storage & later generation of SQL sentence +// + +gqbQueryObjs::gqbQueryObjs() + : gqbObjectCollection(wxT(""), NULL, NULL) +{ + setType(GQB_QUERY); +} + + +void gqbQueryObjs::addTable(gqbQueryObject *mtable) +{ + this->addObject(mtable); +} + + +void gqbQueryObjs::removeTable(gqbQueryObject *mtable) +{ + this->removeObject(mtable); +} + + +gqbIteratorBase *gqbQueryObjs::createQueryIterator() +{ + return this->createIterator(); +} + +gqbIteratorBase *gqbQueryObjs::createDownQueryIterator() +{ + return this->createDownIterator(); +} + + +int gqbQueryObjs::tablesCount() +{ + return this->countObjects(); +} + + +void gqbQueryObjs::removeAllQueryObjs() +{ + this->removeAll(); +} + + +// +// An Object inside a query (A table object in the query), not equal to gqbTable +// Reason: Sometimes a table can be used twice or more times in a query with different columns selected +// Because this we can not use directly the base table object + +gqbQueryObject::gqbQueryObject(gqbTable *table) + : gqbObjectCollection(table->getName(), table, table->getConnection()) +{ + selected = false; + parent = table; + + //GQB-TODO: Calculate a good initial position + position.x = 20; + position.y = 20; + haveJoins = false; + haveRegisteredJoins = false; + registeredCollection = NULL; + joinsCollection = NULL; + setType(GQB_QUERYOBJ); +} + + +// Destructor must empty collection to don't allow deleting of column items from tree +// because this collection doesn't owns it, and then shouldn't destroy it. +gqbQueryObject::~gqbQueryObject() +{ + this->removeAll(); + + // Remove item registered at this Query Object + gqbQueryJoin *tmp; + if(registeredCollection) + { + gqbIteratorBase *r = createRegJoinsIterator(); + while(r->HasNext()) + { + tmp = (gqbQueryJoin *)r->Next(); + this->unregisterJoin(tmp, true); // remove and unregister every join in every query object + // which have registered at this query object + + // On each iteration the structure of iterator change because + // modified his own collection & should be reset + r->ResetIterator(); + } + delete r; + } + + if(joinsCollection) + { + gqbIteratorBase *j = createJoinsIterator(); + while(j->HasNext()) + { + tmp = (gqbQueryJoin *)j->Next(); + this->removeJoin(tmp, true); // removes & unregister Join which have like origin this + // query object + // On each iteration the structure of iterator change because + // modified his own collection & should be reset + j->ResetIterator(); + } + delete j; + + } + + // removeJoin & unregisterJoin delete the collections where there aren't any items inside. +} + + +void gqbQueryObject::setSelected(bool value) +{ + this->selected = value; +} + + +bool gqbQueryObject::getSelected() +{ + return this->selected; +} + + +void gqbQueryObject::setWidth(int value) +{ + width = value; +} + + +int gqbQueryObject::getWidth() +{ + return width; +} + + +void gqbQueryObject::setHeight(int value) +{ + height = value; +} + + +int gqbQueryObject::getHeight() +{ + return height; +} + + +void gqbQueryObject::addColumn(gqbColumn *column) +{ + this->addObject(column); +} + + +void gqbQueryObject::removeColumn(gqbColumn *column) +{ + this->removeObject(column); +} + + +bool gqbQueryObject::existsColumn(gqbColumn *column) +{ + return this->existsObject(column); +} + + +gqbIteratorBase *gqbQueryObject::createQueryTableIterator() +{ + return this->createIterator(); +} + + +gqbIteratorBase *gqbQueryObject::createJoinsIterator() +{ + return joinsCollection->createIterator(); +} + + +gqbIteratorBase *gqbQueryObject::createRegJoinsIterator() +{ + return registeredCollection->createIterator(); +} + + +// Create a Join from this table [owner] column to other table [observable] column +gqbQueryJoin *gqbQueryObject::addJoin(gqbQueryObject *owner, gqbQueryObject *observable, gqbColumn *source, gqbColumn *destination, type_Join kind) +{ + if(!haveJoins) + { + implementationj = new gqbArrayCollection(); + joinsCollection = new gqbCollection(implementationj); + haveJoins = true; + } + + gqbQueryJoin *join = new gqbQueryJoin(owner, observable, source, destination, kind); + joinsCollection->addItem(join); + observable->registerJoin(join); + return join; +} + + +// Remove the join from this query object [source table] +void gqbQueryObject::removeJoin(gqbQueryJoin *join, bool unRegister = false) +{ + // Notify to observable that the join this object owns will be removed & then remove the join + if(unRegister) + join->getDestQTable()->unregisterJoin(join, false); + joinsCollection->removeItem(join); + if(join) + delete join; // Join can be only delete Here by his owner + + if(joinsCollection->count() <= 0) + { + delete joinsCollection; // implementation it's delete too inside collection. + haveJoins = false; + joinsCollection = NULL; + } +} + + +// Register a Join created from other table [source] to this table [destination] +void gqbQueryObject::registerJoin(gqbQueryJoin *join) +{ + if(!haveRegisteredJoins) + { + implementationr = new gqbArrayCollection(); + registeredCollection = new gqbCollection(implementationr); + haveRegisteredJoins = true; + } + registeredCollection->addItem(join); +} + + +// Unregister a Join create from other table [source] to this table [destination] delete the join if need it.. +void gqbQueryObject::unregisterJoin(gqbQueryJoin *join, bool removeIt = false) +{ + // Notify to source/owner object of join about join removing & then remove + registeredCollection->removeItem(join); + if(removeIt) + join->getSourceQTable()->removeJoin(join, false); + if(registeredCollection->count() <= 0) + { + delete registeredCollection; //implementation it's delete too inside collection. + haveRegisteredJoins = false; + registeredCollection = NULL; + } +} + + +int gqbQueryObject::getColumnIndex(gqbColumn *column) +{ + return parent->indexColumn(column); +} + + +bool gqbQueryObject::getHaveJoins() +{ + return haveJoins; +} + + +bool gqbQueryObject::getHaveRegJoins() +{ + return haveRegisteredJoins; +} + +// GQB-TODO if last join it's delete I MUST delete implementation & collection & put haveJoins in false; +// Same for registered joins + +// +// A Join inside a query Object like Table or view [Stored at source, registered at destination] +// I need to store the owner, destination because columns it's share between multiple joins +gqbQueryJoin::gqbQueryJoin(gqbQueryObject *_owner, gqbQueryObject *_destination, gqbColumn *sourceCol, gqbColumn *destCol, type_Join joinKind) + : gqbObject(wxT(""), _owner, NULL) +{ + kindofJoin = joinKind; + sCol = sourceCol; + dCol = destCol; + owner = _owner; + selected = false; + destination = _destination; + setType(GQB_JOIN); +} + + +void gqbQueryJoin::setKindofJoin(type_Join kind) +{ + kindofJoin = kind; +} + + +type_Join gqbQueryJoin::getKindofJoin() +{ + return kindofJoin; +} + + +// Return the object where the join is stored +gqbQueryObject *gqbQueryJoin::getSourceQTable() +{ + return owner; +} + + +// Return the object where the join point to. +gqbQueryObject *gqbQueryJoin::getDestQTable() +{ + return destination; +} + + +// Return the gqbObject of Destination Column +gqbColumn *gqbQueryJoin::getDCol() +{ + return dCol; +} + + +// Return the gqbObject of Source Column +gqbColumn *gqbQueryJoin::getSCol() +{ + return sCol; +} + + +wxString gqbQueryJoin::getSourceTable() +{ + if (!owner) + return wxEmptyString; + + gqbTable *s = (gqbTable *)sCol->getOwner(); + return s->getName(); +} + + +wxString gqbQueryJoin::getDestTable() +{ + if (!destination) + return wxEmptyString; + + gqbTable *d = (gqbTable *)dCol->getOwner(); + return d->getName(); +} + + +wxString gqbQueryJoin::getSourceCol() +{ + if (!sCol) + return wxEmptyString; + + return sCol->getName(); +} + + +wxString gqbQueryJoin::getDestCol() +{ + if (!dCol) + return wxEmptyString; + + return dCol->getName(); +} + + +void gqbQueryJoin::setSourceAnchor(wxPoint pt) +{ + sAnchor = pt; +} + + +void gqbQueryJoin::setDestAnchor(wxPoint pt) +{ + dAnchor = pt; +} + + +wxPoint &gqbQueryJoin::getSourceAnchor() +{ + return sAnchor; +} + + +wxPoint &gqbQueryJoin::getDestAnchor() +{ + return dAnchor; +} + + +void gqbQueryJoin::setSelected(bool value) +{ + this->selected = value; +} + + +bool gqbQueryJoin::getSelected() +{ + return this->selected; +} + + +void gqbQueryJoin::setAnchorsUsed(wxPoint pt) +{ + anchorsUsed = pt; +} + + +wxPoint &gqbQueryJoin::getAnchorsUsed() +{ + return anchorsUsed; +} + + +// +// A query restriction +// + +enum +{ + QRButton = 9000, + QRValue, + QRConnector, + QRtype +}; + +gqbQueryRestriction::gqbQueryRestriction() + : gqbObject(wxT(""), NULL, NULL) +{ + leftPart = wxT(""); + value_s = wxT(""); + connector = wxT("AND"); + restriction = wxT("="); + setType(GQB_RESTRICTION); +} + + +gqbRestrictions::gqbRestrictions() + : gqbObjectCollection(wxT(""), NULL, NULL) +{ + setType(GQB_RESTRICTION); +} + + +gqbRestrictions::~gqbRestrictions() +{ + this->removeAll(); +} + + +void gqbRestrictions::addRestriction(gqbQueryRestriction *r) +{ + this->addObject(r); +} + + +void gqbRestrictions::addRestrictionAt(gqbQueryRestriction *r, int index) +{ + this->insertObjectAt(r, index); +} + + +// Remove but don't delete restriction +void gqbRestrictions::removeRestriction(gqbQueryRestriction *r) +{ + this->removeObject(r); +} + + +void gqbRestrictions::deleteAllRestrictions() +{ + this->deleteAll(); +} + + +gqbIteratorBase *gqbRestrictions::createRestrictionsIterator() +{ + return this->createIterator(); +} + + +int gqbRestrictions::restrictionsCount() +{ + return this->getCount(); +} + + +gqbQueryRestriction *gqbRestrictions::getRestrictionAt(int index) +{ + return (gqbQueryRestriction *)this->getObjectAtIndex(index); +} diff --git a/gqb/gqbSchema.cpp b/gqb/gqbSchema.cpp new file mode 100644 index 0000000..aa73397 --- /dev/null +++ b/gqb/gqbSchema.cpp @@ -0,0 +1,84 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbSchema.cpp - Schema object for GQB +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "gqb/gqbSchema.h" +#include "gqb/gqbObject.h" +#include "gqb/gqbTable.h" +#include "gqb/gqbBrowser.h" + +gqbSchema::gqbSchema(gqbObject *parent, wxString name, pgConn *connection, OID oid) + : gqbObject(name, parent, connection, oid) +{ + setType(GQB_SCHEMA); +} + + +// GQB-TODO: don't declare OID inside gqbBrowsear instead use the pgadmin one +void gqbSchema::createObjects(gqbBrowser *tablesBrowser, OID oidVal, wxTreeItemId parentNode, int tableImage, int viewImage, int xTableImage) +{ + createTables(tablesBrowser, parentNode, oidVal, tableImage, viewImage, xTableImage); +} + +void gqbSchema::createTables(gqbBrowser *tablesBrowser, wxTreeItemId parentNode, OID oidVal, int tableImage, int viewImage, int xTableImage) +{ + wxString query; + + // Get the child objects. + query = wxT("SELECT oid, relname, relkind\n") + wxT(" FROM pg_class\n") + wxT(" WHERE relkind IN ('r','v','x','m') AND relnamespace = ") + NumToStr(oidVal) + wxT(";"); + + pgSet *tables = conn->ExecuteSet(query); + wxTreeItemId parent; + + if (tables) + { + while (!tables->Eof()) + { + gqbTable *table = 0; + wxString tmpname = tables->GetVal(wxT("relname")); + wxString relkind = tables->GetVal(wxT("relkind")); + + if (relkind == wxT("r")) // Table + { + table = new gqbTable(this, tmpname, conn, GQB_TABLE, tables->GetOid(wxT("oid"))); + parent = tablesBrowser->AppendItem(parentNode, tables->GetVal(wxT("relname")) , tableImage, tableImage, table); + } + else if (relkind == wxT("v") || relkind == wxT("m")) + { + table = new gqbTable(this, tmpname, conn, GQB_VIEW, tables->GetOid(wxT("oid"))); + parent = tablesBrowser->AppendItem(parentNode, tables->GetVal(wxT("relname")) , viewImage, viewImage, table); + } + else if (relkind == wxT("x")) // Greenplum external table + { + table = new gqbTable(this, tmpname, conn, GQB_TABLE, tables->GetOid(wxT("oid"))); + parent = tablesBrowser->AppendItem(parentNode, tables->GetVal(wxT("relname")), xTableImage, xTableImage, table); + } + + // Create columns inside this table. + if (table) + table->createObjects(tablesBrowser, conn, tables->GetOid(wxT("oid")), parent); + + tables->MoveNext(); + } + + delete tables; + } + + tablesBrowser->SortChildren(parentNode); +} diff --git a/gqb/gqbTable.cpp b/gqb/gqbTable.cpp new file mode 100644 index 0000000..8b8f957 --- /dev/null +++ b/gqb/gqbTable.cpp @@ -0,0 +1,102 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbTable.cpp - Table object for GQB +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "gqb/gqbObject.h" +#include "gqb/gqbTable.h" +#include "gqb/gqbColumn.h" +#include "gqb/gqbArrayCollection.h" + +gqbTable::gqbTable(gqbObject *parent, wxString name, pgConn *connection, type_gqbObject type, OID oid) + : gqbObjectCollection(name, parent, connection, oid) +{ + setType(type); +} + + +gqbIteratorBase *gqbTable::createColumnsIterator() +{ + return createIterator(); +} + + +void gqbTable::addColumn(gqbColumn *column) +{ + this->addObject(column); +} + + +void gqbTable::createObjects(gqbBrowser *_tablesBrowser, pgConn *_conn, OID oidVal, wxTreeItemId parentNode) +{ + createColumns(_conn, _tablesBrowser, parentNode, oidVal); +} + +void gqbTable::createColumns(pgConn *conn, gqbBrowser *tablesBrowser, wxTreeItemId parentNode, OID oidVal) +{ + + wxString systemRestriction; + if (!settings->GetShowSystemObjects()) + systemRestriction = wxT("\n AND attnum > 0"); + + wxString sql = + wxT("SELECT attname FROM pg_attribute att\n") + wxT(" WHERE attrelid = ") + + NumToStr(oidVal) + + systemRestriction + wxT("\n") + wxT(" AND attisdropped IS FALSE\n") + wxT(" ORDER BY attnum"); + + pgSet *columns = conn->ExecuteSet(sql); + if (columns) + { + while (!columns->Eof()) + { + if (tablesBrowser) + { + //Disable, Column SHOULDN'T be added to tree only use for debug purposes tablesBrowser->AppendItem(parentNode, columns->GetVal(wxT("attname")) , -1, -1); + wxString tmpname = wxString(columns->GetVal(wxT("attname"))); + gqbColumn *column = new gqbColumn(this, tmpname, conn); + this->addColumn(column); + columns->MoveNext(); + } + else + break; + } + + delete columns; + } +} + + +//work as a synonym for function +int gqbTable::countCols() +{ + return this->countObjects(); +} + + +//work as a synonym for function & return correct type +gqbColumn *gqbTable::getColumnAtIndex(int index) +{ + return (gqbColumn *)this->getObjectAtIndex(index); +} + + +int gqbTable::indexColumn(gqbColumn *col) +{ + return this->indexObject(col); +} diff --git a/gqb/gqbView.cpp b/gqb/gqbView.cpp new file mode 100644 index 0000000..ac06089 --- /dev/null +++ b/gqb/gqbView.cpp @@ -0,0 +1,844 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbView.cpp - View implementation for MVC Pattern of GQB +// +////////////////////////////////////////////////////////////////////////// + + +// 1. READ MODEL STATE FROM gqbModel TO CREATE THE GRAPHIC REPRESENTATION OF THE QUERY +// 2. USE THE CONTROLLER TO CHANGE THE MODEL WITH THE USER INPUT + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include +#include + +// App headers +#include "gqb/gqbModel.h" +#include "gqb/gqbEvents.h" +#include "gqb/gqbViewController.h" +#include "gqb/gqbQueryObjs.h" +#include "gqb/gqbGraphSimple.h" +#include "gqb/gqbViewPanels.h" +#include "gqb/gqbObject.h" +#include "gqb/gqbObjectCollection.h" + +// Image +#include "images/gqbJoinCursor.pngc" + +BEGIN_EVENT_TABLE(gqbView, wxScrolledWindow) + EVT_SIZE(gqbView::OnSize) + EVT_PAINT(gqbView::onPaint) + EVT_MOTION(gqbView::onMotion) + EVT_LEFT_DOWN(gqbView::onMotion) + EVT_RIGHT_DOWN(gqbView::onRightClick) + EVT_LEFT_UP(gqbView::onMotion) + EVT_LEFT_DCLICK(gqbView::onDoubleClick) + EVT_ERASE_BACKGROUND(gqbView::onEraseBackGround) //This erase flicker create by wxStaticText when erasing background but this is not needed + EVT_KEY_DOWN(gqbView::OnKeyDown) + EVT_MENU(GQB_RMJ_DELETE, gqbView::OnMenuJoinDelete) + EVT_MENU(GQB_RMT_DELETE, gqbView::OnMenuTableDelete) + EVT_MENU(GQB_RMT_SETALIAS, gqbView::OnMenuTableSetAlias) + EVT_MENU(GQB_REFRESH, gqbView::OnRefresh) +END_EVENT_TABLE() + +gqbView::gqbView(wxWindow *gqbParent, ctlAuiNotebook *gridParent, wxSize size, gqbController *controller, gqbModel *model) + : wxScrolledWindow(gqbParent, wxID_ANY, wxPoint(201, 0), size, + wxHSCROLL | wxVSCROLL | wxBORDER | wxRETAINED) +{ + this->controller = controller; + this->model = model; + pressed = -1; + selected = -1; + changeTOpressed = false; + canvasSize = size; + collectionSelected = NULL; + joinSelected = NULL; + joinSource = NULL; + joinDest = NULL; + joinSCol = NULL; + joinDCol = NULL; + refreshRate = 3; + iterator = NULL; + mode = pt_normal; + joinCursorImage = *gqbJoinCursor_png_img; + joinCursor = wxCursor(joinCursorImage); + m_rightJoins = NULL; + m_rightTables = NULL; + m_gqbPopup = NULL; + jTempSelected = NULL; + cTempSelected = NULL; + + // Assing kind of join Options + joinTypeChoices.Add(wxString(wxT(" = "))); + joinTypeChoices.Add(wxString(wxT(" > "))); + joinTypeChoices.Add(wxString(wxT(" < "))); + joinTypeChoices.Add(wxString(wxT(" >= "))); + joinTypeChoices.Add(wxString(wxT(" <= "))); + + // Assign default graphic behavior [skin of forms inside model] + this->graphBehavior = new gqbGraphSimple(); + + // Create Projection Panel + // GQB-TODO: move model to grid panel constructor + this->gridTable = new gqbGridProjTable(this->model->getOrderedColumns(), this->model->getColumnsParents(), this->model->getColumnsAlias()); + this->projectionPanel = new gqbGridPanel(controller->getTabs(), -1, gridTable); + + // Create Restrictions Panel + this->restrictionsGridTable = new gqbGridRestTable(model->getRestrictions()); + this->criteriaPanel = new gqbCriteriaPanel(controller->getTabs(), model, restrictionsGridTable); + + // Create Joins Panel + this->joinsGridTable = new gqbGridJoinTable(this->controller); + this->joinsPanel = new gqbJoinsPanel(controller->getTabs(), model, joinsGridTable, controller); + + // Create Order by Panel + this->orderByLGridTable = new gqbGridOrderTable(1, model->getOrdByAvailColumns(), model->getOrdByAvailParents(), NULL); + this->orderByRGridTable = new gqbGridOrderTable(2, model->getOrdByColumns(), model->getOrdByParents(), model->getOrdByKind()); + this->orderPanel = new gqbOrderPanel(controller->getTabs(), orderByLGridTable, orderByRGridTable); + +#if !wxCHECK_VERSION(2, 9, 0) + // does nothing in 2.9+ + SetVirtualSizeHints(size); +#endif + +} + + +gqbView::~gqbView() +{ + if(graphBehavior) + delete graphBehavior; + if(iterator) + delete iterator; + + if(m_rightTables) + delete m_rightTables; + + if(m_rightJoins) + delete m_rightJoins; + + if (m_gqbPopup) + delete m_gqbPopup; + + if(orderByRGridTable) + delete orderByRGridTable; + + if(orderByLGridTable) + delete orderByLGridTable; +} + + +// Overwrite and disable onEraseBackground Event to avoid Flicker +void gqbView::onEraseBackGround(wxEraseEvent &event) +{ +} + + +// Detect when should be drawn the canvas with the model information +void gqbView::onPaint(wxPaintEvent &event) +{ + wxPaintDC dcc(this); // Prepare Context for Buffered Draw + wxBufferedDC dc(&dcc, canvasSize); + drawAll(dc, true); // Call Function to draw all +} + + +// GQB-TODO: remove all possible modification to model from here to controller. +void gqbView::onRightClick(wxMouseEvent &event) +{ + // GQB-TODO: Validate Alias + gqbObject *anySelected = NULL; + wxPoint pdc = event.GetPosition(); + pdc.x = event.GetPosition().x; + pdc.y = event.GetPosition().y; + this->CalcUnscrolledPosition(pdc.x, pdc.y, &pdc.x, &pdc.y); + anySelected = controller->getModelSelected(pdc, cTempSelected, jTempSelected, false); + if(anySelected) + { + if(anySelected->getType() == GQB_QUERYOBJ) + { + if(!m_rightTables) + { + m_rightTables = new wxMenu; + m_rightTables->Append(GQB_RMT_SETALIAS, _("&Set Alias for table")); + m_rightTables->Append(GQB_RMT_DELETE, _("&Delete Table")); + m_rightTables->AppendSeparator(); + m_rightTables->Append(GQB_REFRESH, _("&Refresh")); + + } + cTempSelected = (gqbQueryObject *) (gqbObjectCollection *) anySelected; + jTempSelected = NULL; + PopupMenu(m_rightTables, event.GetPosition()); + } + + if(anySelected->getType() == GQB_JOIN) + { + if(!m_rightJoins) + { + m_rightJoins = new wxMenu; + m_rightJoins->Append(GQB_RMJ_DELETE, _("&Delete Join")); + m_rightJoins->AppendSeparator(); + m_rightJoins->Append(GQB_REFRESH, _("&Refresh")); + } + cTempSelected = NULL; + jTempSelected = (gqbQueryJoin *) anySelected;; + PopupMenu(m_rightJoins, event.GetPosition()); + } + } + else + { + if(!m_gqbPopup) + { + m_gqbPopup = new wxMenu; + m_gqbPopup->Append(GQB_REFRESH, _("&Refresh")); + } + PopupMenu(m_gqbPopup, event.GetPosition()); + } +} + + +void gqbView::OnMenuJoinDelete(wxCommandEvent &WXUNUSED(event)) +{ + if(jTempSelected) + { + this->joinsGridTable->removeJoin(jTempSelected); + controller->removeJoin(jTempSelected); + jTempSelected = NULL; + this->Refresh(); + } +} + + +void gqbView::OnMenuTableDelete(wxCommandEvent &WXUNUSED(event)) +{ + if(cTempSelected) + { + joinsGridTable->removeJoins(cTempSelected); + controller->removeTableFromModel(cTempSelected, gridTable, orderByLGridTable, orderByRGridTable); + cTempSelected = NULL; + this->Refresh(); + } +} + + +void gqbView::OnMenuTableSetAlias(wxCommandEvent &event) +{ + if(cTempSelected) + { + // Because a bug that scrolled automatically the panel of the view if this dialog is called, then assign + // as his parent the main container of the view, and void the bug + wxTextEntryDialog dialog(controller->getDialogParent(), + wxString::Format(_("Enter an alias for table %s"), cTempSelected->getName().c_str()), + _("Please enter an alias for the table."), + wxT(""), + wxOK | wxCANCEL | wxCENTRE); + dialog.SetValue(cTempSelected->getAlias()); + if (dialog.ShowModal() == wxID_OK) + { + cTempSelected->setAlias(dialog.GetValue()); + joinsPanel->Refresh(); + } + cTempSelected = NULL; + this->Refresh(); + } +} + + +void gqbView::onDoubleClick(wxMouseEvent &event) +{ + // GQB-TODO: Validate Alias + gqbObject *anySelected = NULL; + wxPoint pdc = event.GetPosition(); + pdc.x = event.GetPosition().x; + pdc.y = event.GetPosition().y; + this->CalcUnscrolledPosition(pdc.x, pdc.y, &pdc.x, &pdc.y); + + anySelected = controller->getModelSelected(pdc, cTempSelected, jTempSelected, false); + if(anySelected) + { + if(anySelected->getType() == GQB_QUERYOBJ) + { + gqbQueryObject *t = (gqbQueryObject *) (gqbObjectCollection *) anySelected; + + // Because a bug that scrolled automatically the panel of the view if this dialog is called, then assign + // as his parent the main container of the view, and void the bug + wxTextEntryDialog dialog(controller->getDialogParent(), + wxString::Format(_("Enter an alias for table %s"), t->getName().c_str()), + _("Please enter an alias for the table."), + wxT(""), + wxOK | wxCANCEL | wxCENTRE); + dialog.SetValue(t->getAlias()); + if (dialog.ShowModal() == wxID_OK) + { + t->setAlias(dialog.GetValue()); + joinsPanel->Refresh(); + + // hack to avoid misplaced joins anchors after insert an alias that trigger a table graph resize (bigger) + this->Refresh(); + this->Update(); //force refresh + graphBehavior->UpdatePosObject(t, t->position.x, t->position.y, 0); + } + } + else if(anySelected->getType() == GQB_JOIN) + { + gqbQueryJoin *j = (gqbQueryJoin *) anySelected; + + controller->getTabs()->ChangeSelection(ti_joinsPanel); + gqbJoinsPanel *jPanel = wxDynamicCast( joinsPanel, gqbJoinsPanel ); + jPanel->selectJoin(j); + } + } + this->Refresh(); +} + + +// Manages user input [Mouse click, drag & drop] over the Canvas +void gqbView::onMotion(wxMouseEvent &event) +{ + static int refresh = 1; // refresh counter, everytime this values reaches + // "refreshRate" value then Refresh while dragging + // Discover area where event ocurrs + pos.x = event.GetPosition().x; + pos.y = event.GetPosition().y; + this->CalcUnscrolledPosition(pos.x, pos.y, &pos.x, &pos.y); + gqbObject *anySelected = NULL; + + // Button Down Event is triggered + if(event.ButtonDown() && !changeTOpressed) + { + this->SetFocus(); + + // Which kind of button down was? join creation [click on any column at the + // right of checkbox and drag & drop] or table moving [click on title and drag & drop] + anySelected = controller->getModelSelected(pos, collectionSelected, joinSelected, false); + if(anySelected) + { + // Anything before just forget about it + changeTOpressed = false; + joinSource = NULL; + joinSCol = NULL; + joinDCol = NULL; + joinDest = NULL; + jpos.x = 0; + jpos.y = 0; + + if(anySelected->getType() == GQB_QUERYOBJ) + { + gqbQueryObject *t = (gqbQueryObject *) (gqbObjectCollection *) anySelected; + + // If click on the title area AND don't click on the columns selection checkbox + if( (pos.y - t->position.y <= graphBehavior->getTitleRowHeight())) + controller->setPointerMode(pt_normal); + else if(pos.x - t->position.x <= 17) + controller->setPointerMode(pt_normal); + else + controller->setPointerMode(pt_join); + } + } + else + { + anySelected = NULL; + mode = pt_normal; + } + + if(mode == pt_normal) // pointer is used to move tables & select/unselect columns + { + // getSelected Item [Mark it as selected if possible] + anySelected = controller->getModelSelected(pos, collectionSelected, joinSelected, true); + changeTOpressed = true; + + // Do conversion of type object if any found + if(anySelected) + { + if(anySelected->getType() == GQB_QUERYOBJ) + { + collectionSelected = (gqbQueryObject *) (gqbObjectCollection *) anySelected; + joinSelected = NULL; + } + else if(anySelected->getType() == GQB_JOIN) + { + joinSelected = (gqbQueryJoin *) anySelected; + collectionSelected = NULL; + } + } + else + { + collectionSelected = NULL; + joinSelected = NULL; + } + + if(!collectionSelected) + { + // none selected temp unselect all items + controller->unsetModelSelected(true); + } + else + { + gqbColumn *col = graphBehavior->getColumnAtPosition(&pos, collectionSelected); + if(col) + { + // Add or remove column from model & observers (ex: Grid) (projection part of SQL sentence) + controller->processColumnInModel(collectionSelected, col, gridTable); + } + } + + if(!joinSelected) + { + controller->unsetModelSelected(false); + } + + } + // Pointer is used to add joins + else if(mode == pt_join) + { + anySelected = controller->getModelSelected(pos, collectionSelected, joinSelected, false); + + // Even if I get an object check that it isn't a join + if( (anySelected) && anySelected->getType() == GQB_QUERYOBJ) + joinSource = (gqbQueryObject *)(gqbObjectCollection *) anySelected; + else + joinSource = NULL; + + if(!joinSource) + { + // creation of join starts + joinSCol = NULL; + joinDCol = NULL; + jpos.x = 0; + jpos.y = 0; + } + else + { + joinSCol = graphBehavior->getColumnAtPosition(&pos, joinSource, joinSource->getWidth()); + jpos = pos; + + // GQB-TODO then draw line between column & pointer + } + } + + this->Refresh(); + } + + // Button Up Event is triggered + if(event.ButtonUp()) + { + // Pointer is used to move tables & select/unselect columns + if(mode == pt_normal) + { + changeTOpressed = false; + anySelected = controller->getModelSelected(pos, collectionSelected, joinSelected, false); + if (anySelected && anySelected->getType() == GQB_JOIN) + { + gqbJoinsPanel *jPanel = wxDynamicCast( joinsPanel, gqbJoinsPanel ); + jPanel->selectJoin((gqbQueryJoin *)anySelected); + } + } + // Pointer is used to add joins + else if(mode == pt_join) + { + anySelected = controller->getModelSelected(pos, collectionSelected, joinSelected, false); + + // Even if I get an object check that it isn't a join + if( (anySelected) && anySelected->getType() == GQB_QUERYOBJ) + { + joinDest = (gqbQueryObject *)(gqbObjectCollection *) anySelected; + // Validate not self joins [in this version tables can be duplicated to create same effect] + if(joinDest == joinSource) + { + joinDest = NULL; + } + } + else + joinDest = NULL; + + // Creation of join starts + if(!joinDest) + { + joinSource = NULL; + joinSCol = NULL; + joinDCol = NULL; + joinDest = NULL; + jpos.x = 0; + jpos.y = 0; + } + else + { + joinDCol = graphBehavior->getColumnAtPosition(&pos, joinDest, joinDest->getWidth()); + if(joinDCol) + { + // GQB-TODO: Allow other type of joins + gqbQueryJoin *qj = controller->addJoin(joinSource, joinSCol, joinDest, joinDCol, _equally); + graphBehavior->calcAnchorPoint(qj); + this->joinsGridTable->AppendJoin(qj); + } + // Let the temporary join line to be draw again [Don't destroy anything because all object where own by other objects this are just pointers] + joinSource = NULL; + joinSCol = NULL; + joinDest = NULL; + joinDCol = NULL; + jpos.x = 0; + jpos.y = 0; + } + } + + controller->setPointerMode(pt_normal); //when button is up, pointer mode should be only normal + this->Refresh(); + } + + // Mouse is Dragged while mouse button is down + if (event.Dragging() && pressed) + { + if(mode == pt_normal) + { + if(collectionSelected) + { + // GQB-TODO: same as gqbGraphBehavior.h [find a way to not hard code the 17 default value] + if((pos.x > collectionSelected->position.x + 17) || (pos.x < collectionSelected->position.x) ) + { + graphBehavior->UpdatePosObject(collectionSelected, pos.x, pos.y, 40); + } + + // Don't draw too much when dragging table around canvas [lower cpu use] + if(refresh % refreshRate == 0) + { + this->Refresh(); + refresh = 1; + } + else + refresh++; + + } + } + else if(mode == pt_join) + { + if(joinSource && !joinDest) + { + this->Refresh(); + } + + } + } +} + + +void gqbView::OnKeyDown(wxKeyEvent &event) +{ + if(event.GetKeyCode() == WXK_DELETE) + { + if(collectionSelected) + { + this->joinsGridTable->removeJoins(collectionSelected); + controller->removeTableFromModel(collectionSelected, gridTable, orderByLGridTable, orderByRGridTable); + collectionSelected = NULL; + this->Refresh(); + } + + if(joinSelected) + { + this->joinsGridTable->removeJoin(joinSelected); + controller->removeJoin(joinSelected); + joinSelected = NULL; + this->Refresh(); + } + } +} + + +void gqbView::drawAll(wxMemoryDC &bdc, bool adjustScrolling) +{ + bdc.Clear(); + if(!iterator) + // Get an iterator for the objects (tables/views) in the model. + iterator = this->model->createQueryIterator(); + else + iterator->ResetIterator(); + + // First Draw Tables + while(iterator->HasNext()) + { + gqbQueryObject *tmp = (gqbQueryObject *)iterator->Next(); + wxPoint pt = wxPoint(tmp->position); // Use a copy because I don't want to store the modified + // version of point after CalcScrolledPosition was called + + if (adjustScrolling) + { + // adjust coordinates + this->CalcScrolledPosition(pt.x, pt.y, &pt.x, &pt.y); + } + graphBehavior->drawTable(bdc, &pt, tmp); // graph table + } + + // Later Draw Joins over Tables + iterator->ResetIterator(); + while(iterator->HasNext()) + { + gqbQueryObject *tmp = (gqbQueryObject *)iterator->Next(); + + if(tmp->getHaveJoins()) + { + gqbIteratorBase *joinsIterator = tmp->createJoinsIterator(); + while(joinsIterator->HasNext()) + { + gqbQueryJoin *join = (gqbQueryJoin *) joinsIterator->Next(); + wxPoint o = join->getSourceAnchor(); + wxPoint d = join->getDestAnchor(); + + if (adjustScrolling) + { + // adjust coordinates origin + this->CalcScrolledPosition(o.x, o.y, &o.x, &o.y); + + // adjust coordinates destination + this->CalcScrolledPosition(d.x, d.y, &d.x, &d.y); + } + graphBehavior->drawJoin(bdc, o, d, join->getAnchorsUsed(), join->getSelected(), join->getKindofJoin()); + } + delete joinsIterator; + } + + } + + // This iterator is delete at destroyer for reuse purposes + if(joinSource) + { + // Draw temporary line while creating a join + wxPoint source = jpos; + wxPoint destination = pos; + if(adjustScrolling) + { + this->CalcScrolledPosition(source.x, source.y, &source.x, &source.y); + this->CalcScrolledPosition(destination.x, destination.y, &destination.x, &destination.y); + } + graphBehavior->drawTempJoinLine(bdc, source, destination); + } +} + + +void gqbView::setPointerMode(pointerMode pm) +{ + mode = pm; + if(mode == pt_join) + this->SetCursor(joinCursor); + else + this->SetCursor(wxNullCursor); +} + + +bool gqbView::clickOnJoin (gqbQueryJoin *join, wxPoint &pt, wxPoint &origin, wxPoint &dest) +{ + return graphBehavior->clickOnJoin(join, pt, origin, dest); +} + + +void gqbView::emptyPanelsData() +{ + gridTable->emptyTableData(); + this->joinsGridTable->emptyTableData(); +} + + +void gqbView::newTableAdded(gqbQueryObject *item) +{ + // Refresh Order By Panel's Left Grid + if (orderByLGridTable->GetView() ) + { + wxGridTableMessage msg( orderByLGridTable, + wxGRIDTABLE_NOTIFY_ROWS_INSERTED, + orderByLGridTable->GetNumberRows() - 1, + item->parent->countCols() ); + orderByLGridTable->GetView()->ProcessTableMessage( msg ); + } +} + +void gqbView::updateTable(gqbQueryObject *queryTable) +{ + if (queryTable->getHaveJoins()) + { + gqbIteratorBase *j = queryTable->createJoinsIterator(); + while (j->HasNext()) + { + gqbQueryJoin *tmp = (gqbQueryJoin *)j->Next(); + graphBehavior->calcAnchorPoint(tmp); + } + delete j; + } + + // Update position of anchor points of Joins that come from others tables + if (queryTable->getHaveRegJoins()) + { + gqbIteratorBase *r = queryTable->createRegJoinsIterator(); + while (r->HasNext()) + { + gqbQueryJoin *tmp = (gqbQueryJoin *)r->Next(); + graphBehavior->calcAnchorPoint(tmp); + } + delete r; + } + this->Refresh(); +} + + +void gqbView::OnRefresh(wxCommandEvent &ev) +{ + updateModelSize(NULL, true); + this->Update(); +} + + +/* +* updateModelSize +* - Update the model size. +* - Calculate the maximum width and maximum height of the model +* * When removed a table/view from model, the obj parameter must be null, +* and update parameter should be true, otherwise update parameter should +* be false (Dragging event) +*/ +void gqbView::updateModelSize(gqbQueryObject *obj, bool updateAnyWay) +{ + static int callCount = 0; + callCount++; + if (!obj) + { + // Do not update model size, everytime it gets called + // Update the size once in 10 times + // Update the size only if update flag is true + if (callCount < 10 && !updateAnyWay) + return; + callCount = 0; + // Figure out the actual model size. + // Remove table + int w = 0, h = 0, maxW = 0, maxH = 0; + if(!iterator) + // Get an iterator for the objects (tables/views) in the model. + iterator = this->model->createQueryIterator(); + else + iterator->ResetIterator(); + + while (iterator->HasNext()) + { + gqbQueryObject *tmp = (gqbQueryObject *)iterator->Next();; + w = tmp->position.x + tmp->getWidth(); + h = tmp->position.y + tmp->getHeight(); + + if (maxW < w) + maxW = w; + if (maxH < h) + maxH = h; + } + + // Reset Model size + modelSize.Set(maxW, maxH); + } + else + { + int w = 0, h = 0; + w = obj->position.x + obj->getWidth(); + h = obj->position.y + obj->getHeight(); + + if (w > modelSize.GetWidth()) + modelSize.SetWidth(w); + if (h > modelSize.GetHeight()) + modelSize.SetHeight(h); + } + bool updateView = false; + int viewW, viewH; + GetSize(&viewW, &viewH); + + if (viewW < GQB_MIN_WIDTH) + viewW = GQB_MIN_WIDTH; + + if (viewH < GQB_MIN_HEIGHT) + viewH = GQB_MIN_HEIGHT; + + if ((modelSize.GetWidth() > viewW || canvasSize.GetWidth() > viewW) && + modelSize.GetWidth() != canvasSize.GetWidth()) + { + canvasSize.SetWidth((modelSize.GetWidth() > viewW ? modelSize.GetWidth() : viewW)); + updateView = true; + } + if ((modelSize.GetHeight() > viewH || canvasSize.GetHeight() > viewH ) && + modelSize.GetHeight() != canvasSize.GetHeight()) + { + canvasSize.SetHeight((modelSize.GetHeight() > viewH ? modelSize.GetHeight() : viewH)); + updateView = true; + } + + if (canvasSize.GetWidth() < viewW) + { + canvasSize.SetWidth(viewW); + updateView = true; + } + + if (canvasSize.GetHeight() < viewH) + { + canvasSize.SetHeight(viewH); + updateView = true; + } + + if (updateView) + { + SetVirtualSize(canvasSize); + } + + FitInside(); + Refresh(); +} + +void gqbView::OnSize(wxSizeEvent &event) +{ + updateModelSize(NULL, true); +} + + +bool gqbView::canSaveAsImage() +{ + updateModelSize(NULL, true); + return !(modelSize.GetWidth() == 0 || modelSize.GetHeight() == 0); +} + +void gqbView::SaveAsImage(const wxString &fileName, wxBitmapType imgType) +{ + + updateModelSize(NULL, true); + + if (modelSize.GetWidth() == 0 || modelSize.GetHeight() == 0) + { + wxMessageBox(_("Nothing to be saved!"), _("Save As an image"), wxOK | wxICON_INFORMATION); + return; + } + + int width = 0, height = 0; + GetVirtualSize(&width, &height); + + /* + * Create the bitmap from the Explain window + */ + wxMemoryDC memDC; + wxBitmap tempBitmap(width, height); + + memDC.SelectObject(tempBitmap); + memDC.Clear(); + + // Draw the diagram on the bitmap (Memory Device Context) + drawAll(memDC, false); + + memDC.SelectObject(wxNullBitmap); + + if (!tempBitmap.SaveFile(fileName, imgType)) + { + wxLogError(_("Could not write the file %s: Errcode=%d."), fileName.c_str(), wxSysErrorCode()); + } +} + + + diff --git a/gqb/gqbViewPanels.cpp b/gqb/gqbViewPanels.cpp new file mode 100644 index 0000000..2af302a --- /dev/null +++ b/gqb/gqbViewPanels.cpp @@ -0,0 +1,1646 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbViewPanels.cpp - All panels used by GQB +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include +#include +#include + +// App headers +#include "gqb/gqbViewPanels.h" +#include "gqb/gqbGridProjTable.h" +#include "gqb/gqbGridRestTable.h" +#include "gqb/gqbGridOrderTable.h" +#include "gqb/gqbGridJoinTable.h" + +// Images +#include "images/gqbUp.pngc" +#include "images/gqbUpTop.pngc" +#include "images/gqbDown.pngc" +#include "images/gqbDownBottom.pngc" +#include "images/gqbOrderAddAll.pngc" +#include "images/gqbOrderRemoveAll.pngc" +#include "images/gqbOrderRemove.pngc" +#include "images/gqbOrderAdd.pngc" +#include "images/gqbAddRest.pngc" +#include "images/gqbRemoveRest.pngc" +#include "images/tables.pngc" +#include "images/table-sm.pngc" +#include "images/column-sm.pngc" +#include "images/view-sm.pngc" +#include "images/gqbAdd.pngc" +#include "images/gqbRemove.pngc" + +// Get available ID for Criteria & Joins Panel +long CRITERIA_PANEL_RESTRICTION_GRID_ID = ::wxNewId(); +long JOINS_PANEL_GRID_ID = ::wxNewId(); + +// +// View Columns Grid Panel Class. +// + +BEGIN_EVENT_TABLE(gqbGridPanel, wxPanel) + EVT_GRID_SELECT_CELL(gqbGridPanel::OnGridSelectCell) + EVT_GRID_RANGE_SELECT(gqbGridPanel::OnGridRangeSelected) + EVT_BUTTON(GQB_COLS_UP_BUTTON_ID, gqbGridPanel::OnButtonUp) + EVT_BUTTON(GQB_COLS_UP_TOP_BUTTON_ID, gqbGridPanel::OnButtonUpTop) + EVT_BUTTON(GQB_COLS_DOWN_BUTTON_ID, gqbGridPanel::OnButtonDown) + EVT_BUTTON(GQB_COLS_DOWN_BOTTOM_BUTTON_ID, gqbGridPanel::OnButtonDownBottom) +END_EVENT_TABLE() + +gqbGridPanel::gqbGridPanel(wxWindow *parent, wxWindowID id = wxID_ANY, gqbGridProjTable *gridModel = NULL): + wxPanel(parent, -1) +{ + gModel = gridModel; + allowSelCells = true; + selTop = -1; + selBottom = -1; + upBitmap = *gqbUp_png_bmp; + upTopBitmap = *gqbUpTop_png_bmp; + downBitmap = *gqbDown_png_bmp; + downBottomBitmap = *gqbDownBottom_png_bmp; + + buttonUp = new wxBitmapButton( this, GQB_COLS_UP_BUTTON_ID, upBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Up") ); + buttonUp->SetToolTip(_("Move the selected column up")); + buttonUpTop = new wxBitmapButton( this, GQB_COLS_UP_TOP_BUTTON_ID, upTopBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Top") ); + buttonUpTop->SetToolTip(_("Move the selected column to the top")); + buttonDown = new wxBitmapButton( this, GQB_COLS_DOWN_BUTTON_ID, downBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Down") ); + buttonDown->SetToolTip(_("Move the selected column down")); + buttonDownBottom = new wxBitmapButton( this, GQB_COLS_DOWN_BOTTOM_BUTTON_ID, downBottomBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Bottom") ); + buttonDownBottom->SetToolTip(_("Move the selected column to the bottom")); + + this->colsGrid = new wxGrid(this, -1, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_BESTWRAP , wxT("")); + colsGrid->SetTable(gModel, true, wxGrid::wxGridSelectCells); + + // Adjust the default row height to be more compact + wxFont font = colsGrid->GetLabelFont(); + int nWidth = 0; + int nHeight = 18; + colsGrid->GetTextExtent(wxT("W"), &nWidth, &nHeight, NULL, NULL, &font); + colsGrid->SetColLabelSize(nHeight + 6); + colsGrid->SetRowLabelSize(35); +#ifdef __WXGTK__ + colsGrid->SetDefaultRowSize(nHeight + 8, TRUE); +#else + colsGrid->SetDefaultRowSize(nHeight + 4, TRUE); +#endif + + wxBoxSizer *horizontalSizer = new wxBoxSizer( wxHORIZONTAL ); + horizontalSizer->Add(colsGrid, + 1, // make vertically stretchable + wxEXPAND | // make horizontally stretchable + wxALL, // and make border all around + 3 ); // set border width to 10 + + wxBoxSizer *buttonsSizer = new wxBoxSizer( wxVERTICAL ); + + buttonsSizer->Add( + this->buttonUpTop, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 10 + + buttonsSizer->Add( + this->buttonUp, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 10 + + buttonsSizer->Add( + this->buttonDown, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 10 + + buttonsSizer->Add( + this->buttonDownBottom, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 10 + + horizontalSizer->Add( + buttonsSizer, + 0, // make vertically unstretchable + wxALIGN_CENTER ); // no border and centre horizontally + + this->SetSizer(horizontalSizer); +} + + +gqbGridPanel::~gqbGridPanel() +{ + if (buttonUp) + delete buttonUp; + if(buttonDown) + delete buttonDown; + if(buttonUpTop) + delete buttonUpTop; + if(buttonDownBottom) + delete buttonDownBottom; +} + + +void gqbGridPanel::SetGridColsSize() +{ + // After sizers determine the width of Grid then calculate the % space for each column about 33% each one + int size = (int)((colsGrid->GetSize().GetWidth() - colsGrid->GetRowLabelSize()) * 0.30); + colsGrid->SetColSize(0, size); + colsGrid->SetColSize(1, size); + colsGrid->SetColSize(2, size); +} + + +void gqbGridPanel::OnGridSelectCell( wxGridEvent &ev ) +{ + if(allowSelCells) + { + if ( ev.Selecting() ) + { + selTop = ev.GetRow(); + selBottom = -1; + } + else + { + selTop = -1; + selBottom = -1; + } + } + ev.Skip(); +} + + +void gqbGridPanel::OnGridRangeSelected( wxGridRangeSelectEvent &ev ) +{ + if(allowSelCells) + { + if ( ev.Selecting() ) + { + selTop = ev.GetTopRow(); + selBottom = ev.GetBottomRow(); + } + else + { + selTop = -1; + selBottom = -1; + } + } + ev.Skip(); +} + + +void gqbGridPanel::OnButtonUp(wxCommandEvent &) +{ + // A single row is selected + allowSelCells = false; + if((selTop >= 0 && selBottom == -1) || (selTop == selBottom)) + { + --selTop; + gModel->changesPositions(selTop, selTop + 1); + if(selTop < 0) + { + selTop = 0; + } + colsGrid->SelectBlock(selTop, 0, selTop, 1, false); + colsGrid->SetGridCursor(selTop, 0); + selBottom = -1; + } + else + { + // A range of rows is selected + if (selTop >= 0 && selBottom >= 0) + { + int newTop = selTop - 1; + gModel->changesRangeOnePos(selTop, selBottom, newTop); + if(selTop > 0) // recalculate new selection area & avoid bad selection area + { + selTop--; + selBottom--; + } + colsGrid->SelectBlock(selTop, 0, selBottom, 1, false); + colsGrid->SetGridCursor(selTop, 0); + } + } + allowSelCells = true; +} + + +void gqbGridPanel::OnButtonUpTop(wxCommandEvent &) +{ + allowSelCells = false; + + // A Single Row is selected + if((selTop >= 0 && selBottom == -1) || (selTop == selBottom)) + { + selBottom = selTop - 1; + selTop = 0; + gModel->changesRangeOnePos(selTop, selBottom, 1); + colsGrid->SelectBlock(0, 0, 0, 1, false); + colsGrid->SetGridCursor(0, 0); + + // Put variables in correct values now. + selTop = 0; + selBottom = -1; + } + // A range of rows is selected + else + { + int newTop = 0; + if (selTop >= 0 && selBottom >= 0) + { + // Move all range only one pos the require times to get the top + for(int i = selTop; i > 0; i--) + { + newTop = selTop - 1; + gModel->changesRangeOnePos(selTop, selBottom, newTop); + + // Recalculate new selection area & avoid bad selection area + if(selTop > 0) + { + selTop--; + selBottom--; + } + colsGrid->SelectBlock(selTop, 0, selBottom, 1, false); + colsGrid->SetGridCursor(selTop, 0); + } + } + } + allowSelCells = true; +} + + +void gqbGridPanel::OnButtonDown(wxCommandEvent &) +{ + + allowSelCells = false; + + // A single row is selected + if((selTop >= 0 && selBottom == -1) || (selTop == selBottom)) + { + ++selTop; + gModel->changesPositions(selTop, selTop - 1); + + // Adjust selection when selected item it's last item. + if(selTop == gModel->GetNumberRows()) + { + selTop--; + } + colsGrid->SelectBlock(selTop, 0, selTop, 1, false); + colsGrid->SetGridCursor(selTop, 0); + selBottom = -1; + } + // A range of rows is selected + else + { + if (selTop >= 0 && selBottom >= 0) + { + int newTop = selTop + 1; + gModel->changesRangeOnePos(selTop, selBottom, newTop); + + // Recalculate new selection area & avoid bad selection area + if(selBottom < gModel->GetNumberRows() - 1) + { + selTop++; + selBottom++; + } + colsGrid->SelectBlock(selTop, 0, selBottom, 1, false); + colsGrid->SetGridCursor(selTop, 0); + } + } + allowSelCells = true; +} + + +void gqbGridPanel::OnButtonDownBottom(wxCommandEvent &) +{ + allowSelCells = false; + + // A Single Row is selected + if((selTop >= 0 && selBottom == -1) || (selTop == selBottom)) + { + selBottom = gModel->GetNumberRows() - 1; + selTop = selTop + 1; + int newBottom = gModel->GetNumberRows() - 1; + gModel->changesRangeOnePos(selTop, selBottom, selTop - 1); + colsGrid->SelectBlock(newBottom, 0, newBottom, 1, false); + colsGrid->SetGridCursor(newBottom, 0); + + // Put variables in correct values now. + selTop = newBottom; + selBottom = -1; + } + // A range of rows is selected + else + { + int newTop = 0, size = gModel->GetNumberRows(); + + if (selTop >= 0 && selBottom >= 0) + { + for(int i = selBottom; i < size; i++) + { + newTop = selTop + 1; + gModel->changesRangeOnePos(selTop, selBottom, newTop); + + // Recalculate new selection area & avoid bad selection area + if(selBottom < gModel->GetNumberRows() - 1) + { + selTop++; + selBottom++; + } + colsGrid->SelectBlock(selTop, 0, selBottom, 1, false); + colsGrid->SetGridCursor(selTop, 0); + } + } + } + allowSelCells = true; +} + + +// +// Tree with Columns & tables inside a query model +// + +gqbColsTree::gqbColsTree(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style) + : wxTreeCtrl(parent, id, pos, size, style) +{ + wxImageList *imageList = new wxImageList(16, 16); + imageList->Add(*tables_png_ico); + imageList->Add(*table_sm_png_ico); + imageList->Add(*column_sm_png_ico); + imageList->Add(*view_sm_png_ico); + this->AssignImageList(imageList); + wxString a = _("Select column"); + createRoot(a); + this->Expand(rootNode); +} + + +// Create root node +wxTreeItemId &gqbColsTree::createRoot(wxString &Name) +{ + rootNode = this->AddRoot(Name, 0, 0); + return rootNode; +} + + +// Override the DeleteAllItems virtual function +// Needs to set null as item-data, otherwise they will delete +// the gqbQueryObject(s) and gqbColumn(s), while deleting these +// items +void gqbColsTree::DeleteAllItems() +{ + wxTreeItemId tableId; + wxTreeItemIdValue tableCookie; + wxTreeItemId rootId = this->GetRootItem(); + + if ( this->GetChildrenCount(rootId, false) != 0 ) + { + wxTreeItemId lastTableId = this->GetLastChild(rootId); + tableId = this->GetFirstChild(rootId, tableCookie); + while ( true ) + { + this->SetItemData(tableId, NULL); + wxTreeItemIdValue colCookie; + wxTreeItemId colId = this->GetFirstChild(tableId, colCookie); + wxTreeItemId lastColId = this->GetLastChild(tableId); + if ( this->GetChildrenCount(tableId, false) != 0 ) + { + while ( true ) + { + this->SetItemData(colId, NULL); + if ( colId != lastColId ) + colId = this->GetNextSibling(colId); + else + break; + } + } + if ( lastTableId != tableId ) + tableId = this->GetNextSibling(tableId); + else + break; + } + } + wxTreeCtrl::DeleteAllItems(); +} + +void gqbColsTree::refreshTree(gqbModel *model, gqbQueryObject *doNotInclude) +{ + // This remove and delete data inside tree's node + this->DeleteAllItems(); + wxString a = _("Select column"); + createRoot(a); + this->Expand(rootNode); + + wxTreeItemId parent; + gqbIteratorBase *iterator = model->createQueryIterator(); + while(iterator->HasNext()) + { + gqbQueryObject *tmpTable = (gqbQueryObject *)iterator->Next(); + + if (doNotInclude && tmpTable == doNotInclude) + continue; + + int iconIndex; + if (tmpTable->parent->getType() == GQB_TABLE) + iconIndex = 1; + else // Must be a view + iconIndex = 3; + + if(tmpTable->getAlias().length() > 0) + { + parent = this->AppendItem(rootNode, tmpTable->getAlias() , iconIndex, iconIndex, tmpTable); + } + else + { + parent = this->AppendItem(rootNode, tmpTable->getName() , iconIndex, iconIndex, tmpTable); + } + gqbIteratorBase *colsIterator = tmpTable->parent->createColumnsIterator(); + while(colsIterator->HasNext()) + { + gqbColumn *tmpColumn = (gqbColumn *)colsIterator->Next(); + this->AppendItem(parent, tmpColumn->getName() , 2, 2, tmpColumn); + } + delete colsIterator; + } + delete iterator; + + if (rootNode) + { + this->SortChildren(rootNode); + this->Expand(rootNode); + } +} + + +// +// Popup Window for gqbColsTree +// + +gqbColsPopUp::gqbColsPopUp(wxWindow *parent, wxWindowID id, wxString title, wxPoint pos, const wxSize size): + wxDialog(parent, id, title, pos, size, wxRESIZE_BORDER | wxCAPTION) +{ + this->SetSize(wxSize(243, 165)); + wxBoxSizer *hSizer = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer *vSizer = new wxBoxSizer(wxVERTICAL); + + editTree = new wxTextCtrl(this, QR_TREE, wxT(""), wxPoint(5, 5), wxSize(193, 22)); + editTree->AcceptsFocus(); + editTree->SetFocus(); + editTree->SetEditable(true); + + hSizer->Add(editTree, 1, wxEXPAND | wxRIGHT, 3); + + buttonTree = new wxButton(this, QR_TREE_OK, _("OK") , wxPoint(199, 5), wxDefaultSize, wxBU_EXACTFIT); + this->Connect(QR_TREE_OK, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) &gqbColsPopUp::OnPopUpOKClick); + + hSizer->Add(buttonTree); + vSizer->Add(hSizer, 0, wxEXPAND | wxALL, 3); + + colsTree = new gqbColsTree(this, QR_TREE, wxPoint(5, 31), wxSize(224, 104), wxTR_HAS_BUTTONS | wxSIMPLE_BORDER | wxTR_SINGLE); + this->Connect(QR_TREE, wxEVT_COMMAND_TREE_ITEM_ACTIVATED, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) &gqbColsPopUp::OnPopUpTreeDoubleClick); + this->Connect(QR_TREE, wxEVT_COMMAND_TREE_SEL_CHANGED, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) &gqbColsPopUp::OnPopUpTreeClick); + + vSizer->Add(colsTree, 1, wxEXPAND | wxALL, 3); + SetSizer(vSizer); +} + + +void gqbColsPopUp::refreshTree(gqbModel *_model) +{ + model = _model; + if(colsTree && _model) + { + colsTree->refreshTree(model); + } + +} + + +void gqbColsPopUp::OnPopUpOKClick(wxCommandEvent &event) +{ + this->usedGrid->SetCellValue(_row, _col, this->getEditText()); + this->MakeModal(false); + this->Hide(); + this->GetParent()->Refresh(); +} + + +void gqbColsPopUp::OnPopUpTreeDoubleClick(wxTreeEvent &event) +{ + if(colsTree) + { + wxTreeItemId itemId = event.GetItem(); + wxTreeItemId itemIdParent = colsTree->GetItemParent(itemId); + if(!colsTree->ItemHasChildren(itemId) && (colsTree->GetRootItem() != itemId)) + { + this->usedGrid->SetCellValue(_row, _col, this->getEditText()); + if(this->usedGrid->GetCellValue(_row, _col).length() <= 0) + { + this->usedGrid->SetCellValue(_row, _col, _("Set value")); + } + this->MakeModal(false); + this->Hide(); + this->GetParent()->Refresh(); + } + } +} + +void gqbColsPopUp::OnPopUpTreeClick(wxTreeEvent &event) +{ + if(colsTree) + { + wxTreeItemId itemId = event.GetItem(); + wxTreeItemId itemIdParent = colsTree->GetItemParent(itemId); + + if(!colsTree->ItemHasChildren(itemId) && (colsTree->GetRootItem() != itemId)) + { + this->editTree->SetValue(qtIdent(colsTree->GetItemText(itemIdParent)) + wxT(".") + qtIdent(colsTree->GetItemText(itemId))); + } + } +} + + +void gqbColsPopUp::setEditText(wxString text) +{ + this->editTree->SetValue(text); +} + + +void gqbColsPopUp::focus() +{ + this->editTree->SetFocus(); + this->editTree->SetSelection(-1, -1); +} + + +// +// View Selection Criteria Panel Class. +// + +BEGIN_EVENT_TABLE(gqbCriteriaPanel, wxPanel) + EVT_BUTTON(GQB_COLS_ADD_BUTTON_ID, gqbCriteriaPanel::OnButtonAdd) + EVT_BUTTON(GQB_COLS_DROP_BUTTON_ID, gqbCriteriaPanel::OnButtonDrop) +END_EVENT_TABLE() + +gqbCriteriaPanel::gqbCriteriaPanel(wxWindow *parent, gqbModel *_model, gqbGridRestTable *gridModel): + wxPanel(parent, -1) +{ + model = _model; + gModel = gridModel; + colsPopUp = NULL; + + this->restrictionsGrid = new gqbCustomGrid(this, CRITERIA_PANEL_RESTRICTION_GRID_ID); + restrictionsGrid->SetTable(gModel, true, wxGrid::wxGridSelectCells); + this->restrictionsGrid->SetSelectionMode(wxGrid::wxGridSelectRows); + + this->Connect(CRITERIA_PANEL_RESTRICTION_GRID_ID, wxEVT_GRID_CELL_LEFT_CLICK, (wxObjectEventFunction) (wxEventFunction) (wxGridEventFunction) &gqbCriteriaPanel::OnCellLeftClick); + // GQB-TODO: in a future implement OnMouseWheel + + addBitmap = *gqbAddRest_png_bmp; + dropBitmap = *gqbRemoveRest_png_bmp; + buttonAdd = new wxBitmapButton( this, GQB_COLS_ADD_BUTTON_ID, addBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Add")); + buttonAdd->SetToolTip(_("Add a new criteria line")); + buttonDrop = new wxBitmapButton( this, GQB_COLS_DROP_BUTTON_ID, dropBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Remove")); + buttonDrop->SetToolTip(_("Remove the selected criteria line")); + + wxBoxSizer *horizontalSizer = new wxBoxSizer( wxHORIZONTAL ); + horizontalSizer->Add(restrictionsGrid, + 1, // make vertically stretchable + wxEXPAND | // make horizontally stretchable + wxALL, // and make border all around + 3 ); // set border width to 10 + + wxBoxSizer *buttonsSizer = new wxBoxSizer( wxVERTICAL ); + + buttonsSizer->Add( + this->buttonAdd, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 10 ); // set border width to 10 + + buttonsSizer->Add( + this->buttonDrop, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 10 ); // set border width to 10 + + horizontalSizer->Add( + buttonsSizer, + 0, // make vertically unstretchable + wxALIGN_CENTER ); // no border and centre horizontally + + this->SetSizer(horizontalSizer); +} + + +void gqbCriteriaPanel::showColsPopUp(int row, int col, wxPoint pos) +{ + if(!colsPopUp) + { + colsPopUp = new gqbColsPopUp(this, -1, wxT("Set Value"), wxDefaultPosition, wxDefaultSize); + } + + refreshTree(model); + + // Set initial Value + colsPopUp->setEditText(restrictionsGrid->GetCellValue(row, col)); + + // Set Position for Pop Up Tree + // Position of wxNotebook + wxPoint p = this->GetParent()->GetPosition(); + p.x += pos.x; + p.y += pos.y; + wxPoint p2 = this->GetPosition(); + + // Position of panel inside wxNotebook + p.x += p2.x; + p.y += p2.y + 40; + colsPopUp->SetPosition(p); + colsPopUp->Show(); + colsPopUp->MakeModal(true); + colsPopUp->focus(); + colsPopUp->setUsedCell(restrictionsGrid, row, col); +} + + +void gqbCriteriaPanel::refreshTree(gqbModel *_model) +{ + // GQB-TODO: Do this through controller... + model = _model; + if(colsPopUp && model) + colsPopUp->refreshTree(model); + +} + + +void gqbCriteriaPanel::OnCellLeftClick(wxGridEvent &event) +{ + wxObject *object = event.GetEventObject(); + gqbCustomGrid *grid = wxDynamicCast( object, gqbCustomGrid ); + + // Only show editor y case of column 1 + if(event.GetCol() == 1) + { + grid->ComboBoxEvent(event); + } + else if(event.GetCol() == 0 || event.GetCol() == 2) + { + // Allow mini browser frame to be visible to user + wxRect cellSize = grid->CellToRect(event.GetRow(), event.GetCol()); + wxPoint p = event.GetPosition(); + restrictionsGrid->CalcUnscrolledPosition(p.x, p.y, &p.x, &p.y); + + // Number 17 is button's width at cellRender function [nButtonWidth] + if((grid->GetRowLabelSize() + cellSize.GetRight()) - (p.x) <= 17 ) + { + p = event.GetPosition(); + showColsPopUp(event.GetRow(), event.GetCol(), p); + } + } //GQB-TODO 1,2 can be integrate with 3 + else if(event.GetCol() == 3) + { + // Change connector of the Restriction between AND/OR + wxRect cellSize = restrictionsGrid->CellToRect(event.GetRow(), event.GetCol()); + wxPoint p = event.GetPosition(); + restrictionsGrid->CalcUnscrolledPosition(p.x, p.y, &p.x, &p.y); + + // Number 17 is button's width at cellRender function [nButtonWidth] + if((restrictionsGrid->GetRowLabelSize() + cellSize.GetRight()) - (p.x) <= 17 ) + { + p = event.GetPosition(); + if( gModel->GetValue(event.GetRow(), 3).Contains(wxT("AND")) ) + { + gModel->SetValue(event.GetRow(), 3, wxT("OR")); + } + else + { + gModel->SetValue(event.GetRow(), 3, wxT("AND")); + } + restrictionsGrid->Refresh(); + } + } + event.Skip(); +} + + +void gqbCriteriaPanel::OnButtonAdd(wxCommandEvent &) +{ + // GQB-TODO: use controller one + gqbQueryRestriction *r = new gqbQueryRestriction(); + gModel->AppendItem(r); + int row = model->getRestrictions()->restrictionsCount() - 1; + + wxString strChoices[16] = {wxT("="), wxT("!="), wxT("<"), wxT("<="), wxT(">"), wxT(">="), wxT("BETWEEN"), wxT("LIKE"), wxT("NOT LIKE"), wxT("ILIKE"), wxT("NOT ILIKE"), wxT("IN"), wxT("NOT IN"), wxT("NOT BETWEEN"), wxT("IS NULL"), wxT("IS NOT NULL")}; + restrictionsGrid->SetCellRenderer(row, 1, new wxGridCellComboBoxRenderer); + restrictionsGrid->SetCellRenderer(row, 0, new wxGridCellButtonRenderer); + restrictionsGrid->SetCellEditor(row, 1, new dxGridCellSizedChoiceEditor(WXSIZEOF(strChoices), strChoices)); + restrictionsGrid->SetCellRenderer(row, 2, new wxGridCellButtonRenderer); + restrictionsGrid->SetCellRenderer(row, 3, new wxGridCellButtonRenderer); + restrictionsGrid->SetReadOnly(row, 3, true); +} + + +void gqbCriteriaPanel::OnButtonDrop(wxCommandEvent &) +{ + if(restrictionsGrid->GetGridCursorRow() >= 0) + gModel->DeleteRows(restrictionsGrid->GetGridCursorRow(), 1); + restrictionsGrid->Refresh(); +} + + +void gqbCriteriaPanel::SetGridColsSize() +{ + // After sizers determine the width of Grid then calculate the % space for each column about 33% each one + int size = (int)((restrictionsGrid->GetSize().GetWidth() - restrictionsGrid->GetRowLabelSize()) * 0.225); + restrictionsGrid->SetColSize(0, size); + restrictionsGrid->SetColSize(1, size); + restrictionsGrid->SetColSize(2, size); + restrictionsGrid->SetColSize(3, size); +} + + +// +// View Selection Criteria Panel Class's Grid. +// +gqbCustomGrid::gqbCustomGrid(wxWindow *parent, wxWindowID id): + wxGrid(parent, id, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_BESTWRAP, wxT("")), + m_selTemp(NULL) +{ + // Adjust the default row height to be more compact + wxFont font = GetLabelFont(); + int nWidth = 0; + int nHeight = 18; + GetTextExtent(wxT("W"), &nWidth, &nHeight, NULL, NULL, &font); + SetColLabelSize(nHeight + 6); + SetRowLabelSize(35); +#ifdef __WXGTK__ + SetDefaultRowSize(nHeight + 8, TRUE); +#else + SetDefaultRowSize(nHeight + 4, TRUE); +#endif +} + + +void gqbCustomGrid::RevertSel() +{ + if (m_selTemp) + { + wxASSERT(m_selection == NULL); + m_selection = m_selTemp; + m_selTemp = NULL; + } +} + + +void gqbCustomGrid::ComboBoxEvent(wxGridEvent &event) +{ + + // This forces the cell to go into edit mode directly + this->m_waitForSlowClick = TRUE; + int row = event.GetRow(); + int col = event.GetCol(); + + this->SetGridCursor(row, col); + + // Store the click co-ordinates in the editor if possible + // if an editor has created a ClientData area, we presume it's + // a wxPoint and we store the click co-ordinates + wxGridCellEditor *pEditor = this->GetCellEditor(event.GetRow(), event.GetCol()); + wxPoint *pClickPoint = (wxPoint *)pEditor->GetClientData(); + if (pClickPoint) + { + *pClickPoint = this->ClientToScreen(event.GetPosition()); +#ifndef __WINDOWS__ + EnableCellEditControl(true); +#endif + } + + // hack to prevent selection from being lost when click combobox + if (this->IsInSelection(event.GetRow(), event.GetCol())) + { + this->m_selTemp = this->m_selection; + this->m_selection = NULL; + } + pEditor->DecRef(); +} + + +// +// +// Order by Panel +// +// + +BEGIN_EVENT_TABLE(gqbOrderPanel, wxPanel) + EVT_BUTTON(GQB_ORDER_DROP_BUTTON_ID, gqbOrderPanel::OnButtonRemove) + EVT_BUTTON(GQB_ORDER_DROP_ALL_BUTTON_ID, gqbOrderPanel::OnButtonRemoveAll) + EVT_BUTTON(GQB_ORDER_ADD_BUTTON_ID, gqbOrderPanel::OnButtonAdd) + EVT_BUTTON(GQB_ORDER_ADD_ALL_BUTTON_ID, gqbOrderPanel::OnButtonAddAll) + EVT_GRID_SELECT_CELL(gqbOrderPanel::OnGridSelectCell) + EVT_GRID_RANGE_SELECT(gqbOrderPanel::OnGridRangeSelected) + EVT_BUTTON(GQB_ORDER_UP_BUTTON_ID, gqbOrderPanel::OnButtonUp) + EVT_BUTTON(GQB_ORDER_UP_TOP_BUTTON_ID, gqbOrderPanel::OnButtonUpTop) + EVT_BUTTON(GQB_ORDER_DOWN_BUTTON_ID, gqbOrderPanel::OnButtonDown) + EVT_BUTTON(GQB_ORDER_DOWN_BOTTOM_BUTTON_ID, gqbOrderPanel::OnButtonDownBottom) +END_EVENT_TABLE() + +gqbOrderPanel::gqbOrderPanel(wxWindow *parent, gqbGridOrderTable *gridTableLeft, gqbGridOrderTable *gridTableRight): + wxPanel(parent, -1) +{ + + // GQB-TODO: change bitmap buttons + selLeft = -1; + selRightTop = -1; + selRightBottom = -1; + tableLeft = gridTableLeft; + tableRight = gridTableRight; + allowSelCells = true; + + addBitmap = *gqbOrderAdd_png_bmp; + addAllBitmap = *gqbOrderAddAll_png_bmp; + removeBitmap = *gqbOrderRemove_png_bmp; + removeAllBitmap = *gqbOrderRemoveAll_png_bmp; + + buttonAdd = new wxBitmapButton( this, GQB_ORDER_ADD_BUTTON_ID, addBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Add Column") ); + buttonAdd->SetToolTip(_("Add the selected column")); + buttonAddAll = new wxBitmapButton( this, GQB_ORDER_ADD_ALL_BUTTON_ID, addAllBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Add All Columns") ); + buttonAddAll->SetToolTip(_("Add all columns")); + buttonRemove = new wxBitmapButton( this, GQB_ORDER_DROP_BUTTON_ID, removeBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Remove Column") ); + buttonRemove->SetToolTip(_("Remove the selected column")); + buttonRemoveAll = new wxBitmapButton( this, GQB_ORDER_DROP_ALL_BUTTON_ID, removeAllBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Remove All Columns") ); + buttonRemoveAll->SetToolTip(_("Remove all columns")); + + upBitmap = *gqbUp_png_bmp; + upTopBitmap = *gqbUpTop_png_bmp; + downBitmap = *gqbDown_png_bmp; + downBottomBitmap = *gqbDownBottom_png_bmp; + + buttonUp = new wxBitmapButton( this, GQB_ORDER_UP_BUTTON_ID, upBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Up") ); + buttonUp->SetToolTip(_("Move the selected column up")); + buttonDown = new wxBitmapButton( this, GQB_ORDER_DOWN_BUTTON_ID, downBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Down") ); + buttonDown->SetToolTip(_("Move the selected column down")); + buttonUpTop = new wxBitmapButton( this, GQB_ORDER_UP_TOP_BUTTON_ID, upTopBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Top") ); + buttonUpTop->SetToolTip(_("Move the selected column to the top")); + buttonDownBottom = new wxBitmapButton( this, GQB_ORDER_DOWN_BOTTOM_BUTTON_ID, downBottomBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Bottom") ); + buttonDownBottom->SetToolTip(_("Move the selected column to the bottom")); + + availableColumns = new wxGrid(this, -1, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_BESTWRAP , wxT("Available Columns")); + availableColumns->SetTable(gridTableLeft); + availableColumns->EnableEditing(false); + + // Adjust the default row height to be more compact + wxFont font = availableColumns->GetLabelFont(); + int nWidth = 0; + int nHeight = 18; + availableColumns->GetTextExtent(wxT("W"), &nWidth, &nHeight, NULL, NULL, &font); + availableColumns->SetColLabelSize(nHeight + 6); + availableColumns->SetRowLabelSize(35); +#ifdef __WXGTK__ + availableColumns->SetDefaultRowSize(nHeight + 8, TRUE); +#else + availableColumns->SetDefaultRowSize(nHeight + 4, TRUE); +#endif + + + wxBoxSizer *horizontalSizer = new wxBoxSizer( wxHORIZONTAL ); + + horizontalSizer->Add(availableColumns, + 1, // make vertically stretchable + wxEXPAND | // make horizontally stretchable + wxALL, // and make border all around + 3 ); // set border width to 10 + + wxBoxSizer *buttonsSizer1 = new wxBoxSizer( wxVERTICAL ); + + buttonsSizer1->Add( + this->buttonAdd, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 10 + + buttonsSizer1->Add( + this->buttonAddAll, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 10 + + buttonsSizer1->Add( + this->buttonRemove, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 10 + + buttonsSizer1->Add( + this->buttonRemoveAll, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 10 + + horizontalSizer->Add( + buttonsSizer1, + 0, // make vertically unstretchable + wxALIGN_CENTER ); // no border and centre horizontally + + // GQB-TODO: change 333 for a new and better one. + usedColumns = new wxGrid(this, 333, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_BESTWRAP , wxT("Columns Order")); + usedColumns->SetTable(gridTableRight); + usedColumns->EnableEditing(false); + + // Adjust the default row height to be more compact + font = usedColumns->GetLabelFont(); + nWidth = 0; + nHeight = 18; + usedColumns->GetTextExtent(wxT("W"), &nWidth, &nHeight, NULL, NULL, &font); + usedColumns->SetColLabelSize(nHeight + 6); + usedColumns->SetRowLabelSize(35); +#ifdef __WXGTK__ + usedColumns->SetDefaultRowSize(nHeight + 8, TRUE); +#else + usedColumns->SetDefaultRowSize(nHeight + 4, TRUE); +#endif + + this->Connect(333, wxEVT_GRID_CELL_LEFT_CLICK, (wxObjectEventFunction) (wxEventFunction) (wxGridEventFunction) &gqbOrderPanel::OnCellLeftClick); + + horizontalSizer->Add(usedColumns, + 1, // make vertically stretchable + wxEXPAND | // make horizontally stretchable + wxALL, // and make border all around + 3 ); // set border width to 10 + + wxBoxSizer *buttonsSizer2 = new wxBoxSizer( wxVERTICAL ); + + buttonsSizer2->Add( + this->buttonUpTop, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 10 + + buttonsSizer2->Add( + this->buttonUp, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 10 + + buttonsSizer2->Add( + this->buttonDown, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 10 + + buttonsSizer2->Add( + this->buttonDownBottom, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 10 + + horizontalSizer->Add( + buttonsSizer2, + 0, // make vertically unstretchable + wxALIGN_CENTER ); // no border and centre horizontally + + this->SetSizer(horizontalSizer); +} + + +void gqbOrderPanel::OnButtonRemove(wxCommandEvent &) +{ + if(usedColumns->GetRows() > 0) + { + if(selRightTop != -1) + { + gqbColumn *col = (gqbColumn *) tableRight->getObjectAt(selRightTop, 0); + gqbQueryObject *colParent = (gqbQueryObject *) tableRight->getObjectAt(selRightTop, 1); + tableLeft->AppendItem(col, colParent, 'N'); + tableRight->removeRowAt(selRightTop); + } + } +} + + +void gqbOrderPanel::OnButtonRemoveAll(wxCommandEvent &) +{ + if(usedColumns->GetRows() > 0) + { + for(int i = usedColumns->GetRows() - 1; i >= 0; i--) + { + gqbColumn *col = (gqbColumn *) tableRight->getObjectAt(i, 0); + gqbQueryObject *colParent = (gqbQueryObject *) tableRight->getObjectAt(i, 1); + tableLeft->AppendItem(col, colParent, 'N'); + tableRight->removeRowAt(i); + } + } +} + + +void gqbOrderPanel::OnButtonAdd(wxCommandEvent &) +{ + if(availableColumns->GetRows() > 0) + { + if(selLeft != -1) + { + gqbColumn *col = (gqbColumn *) tableLeft->getObjectAt(selLeft, 0); + gqbQueryObject *colParent = (gqbQueryObject *) tableLeft->getObjectAt(selLeft, 1); + tableRight->AppendItem(col, colParent, 'A'); + usedColumns->SetCellRenderer((usedColumns->GetRows() - 1), 1, new wxGridCellButtonRenderer); + tableLeft->removeRowAt(selLeft); + } + } +} + + +void gqbOrderPanel::OnButtonAddAll(wxCommandEvent &) +{ + if(availableColumns->GetRows() > 0) + { + for(int i = availableColumns->GetRows() - 1; i >= 0; i--) + { + gqbColumn *col = (gqbColumn *) tableLeft->getObjectAt(i, 0); + gqbQueryObject *colParent = (gqbQueryObject *) tableLeft->getObjectAt(i, 1); + tableRight->AppendItem(col, colParent, 'A'); + usedColumns->SetCellRenderer((usedColumns->GetRows() - 1), 1, new wxGridCellButtonRenderer); + tableLeft->removeRowAt(i); + } + } +} + + +void gqbOrderPanel::OnGridSelectCell( wxGridEvent &ev ) +{ + if(allowSelCells) + { + if ( ev.Selecting() ) + { + wxObject *object = ev.GetEventObject(); + wxGrid *grid = wxDynamicCast( object, wxGrid ); + if(grid->GetCols() == 1) // Left Grid + { + selLeft = ev.GetRow(); + } + else + { + // Right Grid + selRightTop = ev.GetRow(); + selRightBottom = -1; + } + } + else + { + selRightTop = -1; // GQB-TODO: this is correct?? + selRightBottom = -1; + selLeft = -1; + } + } + ev.Skip(); +} + + +void gqbOrderPanel::OnGridRangeSelected( wxGridRangeSelectEvent &ev ) +{ + if(allowSelCells) + { + if ( ev.Selecting() ) + { + selRightTop = ev.GetTopRow(); + selRightBottom = ev.GetBottomRow(); + } + else + { + selRightTop = -1; + selRightBottom = -1; + } + } + ev.Skip(); +} + + +void gqbOrderPanel::OnButtonUp(wxCommandEvent &) +{ + // A single row is selected + allowSelCells = false; + if((selRightTop >= 0 && selRightBottom == -1) || (selRightTop == selRightBottom)) + { + --selRightTop; + tableRight->changesPositions(selRightTop, selRightTop + 1); + if(selRightTop < 0) + { + selRightTop = 0; + } + usedColumns->SelectBlock(selRightTop, 0, selRightTop, 1, false); + usedColumns->SetGridCursor(selRightTop, 0); + selRightBottom = -1; + } + else + { + // A range of rows is selected + if (selRightTop >= 0 && selRightBottom >= 0) + { + int newTop = selRightTop - 1; + tableRight->changesRangeOnePos(selRightTop, selRightBottom, newTop); + if(selRightTop > 0) // Recalculate new selection area & avoid bad selection area + { + selRightTop--; + selRightBottom--; + } + usedColumns->SelectBlock(selRightTop, 0, selRightBottom, 1, false); + usedColumns->SetGridCursor(selRightTop, 0); + } + } + allowSelCells = true; +} + + +void gqbOrderPanel::OnButtonUpTop(wxCommandEvent &) +{ + allowSelCells = false; + + // A Single Row is selected + if((selRightTop >= 0 && selRightBottom == -1) || (selRightTop == selRightBottom)) + { + selRightBottom = selRightTop - 1; + selRightTop = 0; + tableRight->changesRangeOnePos(selRightTop, selRightBottom, 1); + usedColumns->SelectBlock(0, 0, 0, 1, false); + usedColumns->SetGridCursor(0, 0); + + // Put variables in correct values now. + selRightTop = 0; + selRightBottom = -1; + } + // A range of rows is selected + else + { + int newTop = 0; + if (selRightTop >= 0 && selRightBottom >= 0) + { + // Move all range only one pos the require times to get the top + for(int i = selRightTop; i > 0; i--) + { + newTop = selRightTop - 1; + tableRight->changesRangeOnePos(selRightTop, selRightBottom, newTop); + + // Recalculate new selection area & avoid bad selection area + if(selRightTop > 0) + { + selRightTop--; + selRightBottom--; + } + usedColumns->SelectBlock(selRightTop, 0, selRightBottom, 1, false); + usedColumns->SetGridCursor(selRightTop, 0); + } + } + } + allowSelCells = true; +} + + +void gqbOrderPanel::OnButtonDown(wxCommandEvent &) +{ + + allowSelCells = false; + + // A single row is selected + if((selRightTop >= 0 && selRightBottom == -1) || (selRightTop == selRightBottom)) + { + ++selRightTop; + tableRight->changesPositions(selRightTop, selRightTop - 1); + + // Adjust selection when selected item it's last item. + if(selRightTop == tableRight->GetNumberRows()) + { + selRightTop--; + } + usedColumns->SelectBlock(selRightTop, 0, selRightTop, 1, false); + usedColumns->SetGridCursor(selRightTop, 0); + selRightBottom = -1; + } + // A range of rows is selected + else + { + if (selRightTop >= 0 && selRightBottom >= 0) + { + int newTop = selRightTop + 1; + tableRight->changesRangeOnePos(selRightTop, selRightBottom, newTop); + + // Recalculate new selection area & avoid bad selection area + if(selRightBottom < tableRight->GetNumberRows() - 1) + { + selRightTop++; + selRightBottom++; + } + usedColumns->SelectBlock(selRightTop, 0, selRightBottom, 1, false); + usedColumns->SetGridCursor(selRightTop, 0); + } + } + allowSelCells = true; +} + + +void gqbOrderPanel::OnButtonDownBottom(wxCommandEvent &) +{ + allowSelCells = false; + + // A Single Row is selected + if((selRightTop >= 0 && selRightBottom == -1) || (selRightTop == selRightBottom)) + { + selRightBottom = tableRight->GetNumberRows() - 1; + selRightTop = selRightTop + 1; + int newBottom = tableRight->GetNumberRows() - 1; + tableRight->changesRangeOnePos(selRightTop, selRightBottom, selRightTop - 1); + usedColumns->SelectBlock(newBottom, 0, newBottom, 1, false); + usedColumns->SetGridCursor(newBottom, 0); + + // Put variables in correct values now. + selRightTop = newBottom; + selRightBottom = -1; + } + // A range of rows is selected + else + { + int newTop = 0, size = tableRight->GetNumberRows(); + + if (selRightTop >= 0 && selRightBottom >= 0) + { + for(int i = selRightBottom; i < size; i++) + { + newTop = selRightTop + 1; + tableRight->changesRangeOnePos(selRightTop, selRightBottom, newTop); + + // Recalculate new selection area & avoid bad selection area + if(selRightBottom < tableRight->GetNumberRows() - 1) + { + selRightTop++; + selRightBottom++; + } + usedColumns->SelectBlock(selRightTop, 0, selRightBottom, 1, false); + usedColumns->SetGridCursor(selRightTop, 0); + } + } + } + allowSelCells = true; +} + + +void gqbOrderPanel::SetGridColsSize() +{ + // After sizers determine the width of Grid then calculate the % space for each column + int size = (int)((availableColumns->GetSize().GetWidth() - availableColumns->GetRowLabelSize()) * 0.90); + availableColumns->SetColSize(0, size); + + size = (int)((usedColumns->GetSize().GetWidth() - usedColumns->GetRowLabelSize()) * 0.65); + int size2 = (int)((usedColumns->GetSize().GetWidth() - usedColumns->GetRowLabelSize()) * 0.25); + usedColumns->SetColSize(0, size); + usedColumns->SetColSize(1, size2); +} + + +void gqbOrderPanel::OnCellLeftClick(wxGridEvent &event) +{ + + // Only show editor y case of column 1 + if(event.GetCol() == 1) + { + // Change kind of order of the columns between ASC and DESC + wxRect cellSize = usedColumns->CellToRect(event.GetRow(), event.GetCol()); + wxPoint p = event.GetPosition(); + usedColumns->CalcUnscrolledPosition(p.x, p.y, &p.x, &p.y); + + // Number 17 is button's width at cellRender function [nButtonWidth] + if((usedColumns->GetRowLabelSize() + cellSize.GetRight()) - (p.x) <= 17 ) + { + p = event.GetPosition(); + if( tableRight->GetValue(event.GetRow(), 1).Contains(wxT("ASC")) ) + { + tableRight->SetValue(event.GetRow(), 1, wxT("DESC")); + } + else + { + tableRight->SetValue(event.GetRow(), 1, wxT("ASC")); + } + usedColumns->Refresh(); + } + } + event.Skip(); +} + +// Popup window for gqbJoinsPanel +// +gqbJoinsPopUp::gqbJoinsPopUp( + gqbJoinsPanel *parent, wxWindowID id, wxString title, + wxPoint pos, const wxSize size, gqbQueryJoin *_join, + bool isSource, gqbGridJoinTable *_gmodel) + : gqbColsPopUp(parent, id, title, pos, size) +{ + this->editTree->SetEditable(false); + + // Handles different events for Ok button, single mouse click, double mouse click + this->Connect(QR_TREE_OK, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) &gqbJoinsPopUp::OnPopUpOKClick); + this->Connect(QR_TREE, wxEVT_COMMAND_TREE_ITEM_ACTIVATED, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) &gqbJoinsPopUp::OnPopUpTreeDoubleClick); + this->Connect(QR_TREE, wxEVT_COMMAND_TREE_SEL_CHANGED, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) &gqbJoinsPopUp::OnPopUpTreeClick); + + this->selectedTbl = NULL; + this->selectedCol = NULL; + this->join = _join; + this->isSource = isSource; + this->gModel = _gmodel; +} + +void gqbJoinsPopUp::refreshTree(gqbModel *_model) +{ + model = _model; + if(colsTree && _model) + { + // Do not include already included Table + // For self join, other entity for the same table should be used with alias + if ( join ) + colsTree->refreshTree(model, isSource ? join->getDestQTable() : join->getSourceQTable()); + else + colsTree->refreshTree(model); + } +} + +// single mouse click on tree +void gqbJoinsPopUp::OnPopUpTreeClick(wxTreeEvent &event) +{ + if( colsTree ) + { + wxTreeItemId itemId = event.GetItem(); + wxTreeItemId itemIdParent = colsTree->GetItemParent(itemId); + + if(!colsTree->ItemHasChildren(itemId) && (colsTree->GetRootItem() != itemId)) + { + selectedCol = (gqbColumn *)colsTree->GetItemData(itemId); + selectedTbl = (gqbQueryObject *)colsTree->GetItemData(itemIdParent); + this->editTree->SetValue(qtIdent(colsTree->GetItemText(itemIdParent)) + wxT(".") + qtIdent(colsTree->GetItemText(itemId))); + } + else + { + selectedCol = NULL; + selectedTbl = NULL; + } + } +} + + +void gqbJoinsPopUp::OnPopUpOKClick(wxCommandEvent &event) +{ + if( colsTree && selectedCol && selectedTbl ) + { + // This should update the selected Join with the new values. + updateJoin(); + } + + this->MakeModal(false); + this->Hide(); + this->GetParent()->Refresh(); + this->join = NULL; + this->selectedCol = NULL; + this->selectedTbl = NULL; +} + + +// Update the view fo this query table, involved in +// the whole operation +void gqbJoinsPanel::updateView(gqbQueryObject *table) +{ + if (table) + controller->getView()->updateTable(table); +} + +void gqbJoinsPopUp::updateJoin() +{ + if ((isSource ? join->getSCol() : join->getDCol()) != selectedCol) + { + // Create a new join with the existing data + // Replace it in the gqbJoinTable with the existing one + // Unregister the join, if exists + gqbQueryObject *srcTbl = ( isSource ? selectedTbl : join->getSourceQTable() ); + gqbQueryObject *destTbl = ( isSource ? join->getDestQTable() : selectedTbl ); + gqbColumn *srcCol = ( isSource ? selectedCol : join->getSCol() ); + gqbColumn *destCol = ( isSource ? join->getDCol() : selectedCol ); + type_Join joinType = join->getKindofJoin(); + + gqbQueryJoin *newJoin = NULL; + if( srcTbl && destTbl ) + { + newJoin = srcTbl->addJoin(srcTbl, destTbl, srcCol, destCol, joinType); + ((gqbJoinsPanel *)GetParent())->updateView(newJoin->getSourceQTable()); + } + else + newJoin = new gqbQueryJoin(srcTbl, destTbl, srcCol, destCol, joinType); + + gModel->ReplaceJoin(join, newJoin); + + if (join->getSourceQTable() && join->getDestQTable()) + { + // This will remove the join object too + gqbQueryObject *srcObj = join->getSourceQTable(); + srcObj->removeJoin(join, true); + } + else + { + delete join; + } + join = newJoin; + } +} + + +void gqbJoinsPopUp::OnPopUpTreeDoubleClick(wxTreeEvent &event) +{ + if(colsTree) + { + wxTreeItemId itemId = event.GetItem(); + wxTreeItemId itemIdParent = colsTree->GetItemParent(itemId); + if(!colsTree->ItemHasChildren(itemId) && (colsTree->GetRootItem() != itemId)) + { + selectedCol = (gqbColumn *)colsTree->GetItemData(itemId); + selectedTbl = (gqbQueryObject *)colsTree->GetItemData(itemIdParent); + + updateJoin(); + + this->MakeModal(false); + this->Hide(); + this->GetParent()->Refresh(); + this->join = NULL; + this->selectedCol = NULL; + this->selectedTbl = NULL; + } + } +} + +// +// View Selection Joins Panel Class. +// + +BEGIN_EVENT_TABLE(gqbJoinsPanel, wxPanel) + EVT_BUTTON(GQB_JOIN_COLS_ADD_BUTTON_ID, gqbJoinsPanel::OnButtonAdd) + EVT_BUTTON(GQB_JOIN_COLS_DELETE_BUTTON_ID, gqbJoinsPanel::OnButtonDrop) +END_EVENT_TABLE() + +gqbJoinsPanel::gqbJoinsPanel(wxWindow *parent, gqbModel *_model, gqbGridJoinTable *_gmodel, gqbController *_controller): + wxPanel(parent, wxID_ANY) +{ + model = _model; + gModel = _gmodel; + controller = _controller; + joinsPopUp = NULL; + + this->joinsGrid = new gqbCustomGrid(this, JOINS_PANEL_GRID_ID); + joinsGrid->CreateGrid(0, 5, wxGrid::wxGridSelectRows); + joinsGrid->SetTable(gModel, true, wxGrid::wxGridSelectCells); + this->joinsGrid->SetSelectionMode(wxGrid::wxGridSelectRows); + + this->Connect(JOINS_PANEL_GRID_ID, wxEVT_GRID_CELL_LEFT_CLICK, (wxObjectEventFunction) (wxEventFunction) (wxGridEventFunction) &gqbJoinsPanel::OnCellLeftClick); + // GQB-TODO: in a future implement OnMouseWheel + + addBitmap = *gqbAdd_png_bmp; + dropBitmap = *gqbRemove_png_bmp; + buttonAdd = new wxBitmapButton( this, GQB_JOIN_COLS_ADD_BUTTON_ID, addBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Add")); + buttonAdd->SetToolTip(_("Add a new join")); + buttonDrop = new wxBitmapButton( this, GQB_JOIN_COLS_DELETE_BUTTON_ID, dropBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Remove")); + buttonDrop->SetToolTip(_("Remove the selected join")); + + wxBoxSizer *horizontalSizer = new wxBoxSizer( wxHORIZONTAL ); + horizontalSizer->Add(joinsGrid, + 1, // make vertically stretchable + wxEXPAND | // make horizontally stretchable + wxALL, // and make border all around + 3 ); // set border width to 10 + + wxBoxSizer *buttonsSizer = new wxBoxSizer( wxVERTICAL ); + + buttonsSizer->Add( + this->buttonAdd, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 10 ); // set border width to 10 + + buttonsSizer->Add( + this->buttonDrop, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 10 ); // set border width to 10 + + horizontalSizer->Add( + buttonsSizer, + 0, // make vertically unstretchable + wxALIGN_CENTER ); // no border and centre horizontally + + this->SetSizer(horizontalSizer); +} + + +void gqbJoinsPanel::showColsPopUp(int row, int col, wxPoint pos) +{ + if( joinsPopUp ) + { + joinsPopUp->Destroy(); + joinsPopUp = NULL; + } + joinsPopUp = new gqbJoinsPopUp(this, -1, wxT("Select Column"), wxDefaultPosition, wxDefaultSize, this->gModel->GetJoin(row), ( col == 0 ? true : false ), this->gModel); + + refreshTree(model); + + // Set initial Value + joinsPopUp->setEditText(joinsGrid->GetCellValue(row, col)); + + // Set Position for Pop Up Tree + // Position of wxNotebook + wxPoint p = this->GetParent()->GetPosition(); + p.x += pos.x; + p.y += pos.y; + wxPoint p2 = this->GetPosition(); + + // Position of panel inside wxNotebook + p.x += p2.x; + p.y += p2.y + 40; + joinsPopUp->SetPosition(p); + joinsPopUp->Show(); + joinsPopUp->MakeModal(true); + joinsPopUp->focus(); + joinsPopUp->setUsedCell(joinsGrid, row, col); +} + + +void gqbJoinsPanel::refreshTree(gqbModel *_model) +{ + model = _model; + if(joinsPopUp && model) + joinsPopUp->refreshTree(model); +} + + +void gqbJoinsPanel::OnCellLeftClick(wxGridEvent &event) +{ + wxObject *object = event.GetEventObject(); + gqbCustomGrid *grid = wxDynamicCast( object, gqbCustomGrid ); + + // Only show editor y case of column 1 + if(event.GetCol() == 1) + { + grid->ComboBoxEvent(event); + } + else if(event.GetCol() == 0 || event.GetCol() == 2) + { + // Allow mini browser frame to be visible to user + wxRect cellSize = grid->CellToRect(event.GetRow(), event.GetCol()); + wxPoint p = event.GetPosition(); + joinsGrid->CalcUnscrolledPosition(p.x, p.y, &p.x, &p.y); + + // Number 17 is button's width at cellRender function [nButtonWidth] + if((grid->GetRowLabelSize() + cellSize.GetRight()) - (p.x) <= 17 ) + { + p = event.GetPosition(); + showColsPopUp(event.GetRow(), event.GetCol(), p); + } + } + event.Skip(); +} + + +void gqbJoinsPanel::OnButtonAdd(wxCommandEvent &) +{ + this->gModel->AppendJoin( NULL ); +} + + +void gqbJoinsPanel::OnButtonDrop(wxCommandEvent &) +{ + if(joinsGrid->GetGridCursorRow() >= 0) + { + gqbQueryObject *updateTbl = gModel->DeleteRow(joinsGrid->GetGridCursorRow()); + if (updateTbl) + controller->getView()->updateTable(updateTbl); + } + joinsGrid->Refresh(); +} + + +void gqbJoinsPanel::SetGridColsSize() +{ + // After sizers determine the width of Grid then calculate the % space for each column about 33% each one + int size = (int)((joinsGrid->GetSize().GetWidth() - joinsGrid->GetRowLabelSize()) * 0.3); + joinsGrid->SetColSize(0, size); + joinsGrid->SetColSize(1, size); + joinsGrid->SetColSize(2, size); +} + +void gqbJoinsPanel::selectJoin(gqbQueryJoin *join) +{ + joinsGrid->RevertSel(); + gModel->selectJoin(join); +} + diff --git a/gqb/module.mk b/gqb/module.mk new file mode 100644 index 0000000..674daa0 --- /dev/null +++ b/gqb/module.mk @@ -0,0 +1,36 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/gqb/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + gqb/gqbArrayCollection.cpp \ + gqb/gqbBrowser.cpp \ + gqb/gqbCollection.cpp \ + gqb/gqbColumn.cpp \ + gqb/gqbController.cpp \ + gqb/gqbDatabase.cpp \ + gqb/gqbGraphSimple.cpp \ + gqb/gqbGridOrderTable.cpp \ + gqb/gqbGridProjTable.cpp \ + gqb/gqbGridRestTable.cpp \ + gqb/gqbGridJoinTable.cpp \ + gqb/gqbModel.cpp \ + gqb/gqbObject.cpp \ + gqb/gqbObjectCollection.cpp \ + gqb/gqbQueryObjs.cpp \ + gqb/gqbSchema.cpp \ + gqb/gqbTable.cpp \ + gqb/gqbViewPanels.cpp \ + gqb/gqbView.cpp + +EXTRA_DIST += \ + gqb/module.mk + + diff --git a/hotdraw/connectors/hdChopBoxConnector.cpp b/hotdraw/connectors/hdChopBoxConnector.cpp new file mode 100644 index 0000000..0611216 --- /dev/null +++ b/hotdraw/connectors/hdChopBoxConnector.cpp @@ -0,0 +1,82 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdChopBoxConnector.cpp - Connector for center of figure to line crossing one limit line of rect +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/connectors/hdChopBoxConnector.h" +#include "hotdraw/utilities/hdGeometry.h" + +hdChopBoxConnector::hdChopBoxConnector(hdIFigure *owner): + hdIConnector(owner) +{ +} + +hdChopBoxConnector::~hdChopBoxConnector() +{ +} + + +hdPoint hdChopBoxConnector::chop(int posIdx, hdIFigure *target, hdPoint point) +{ + if(target && target->containsPoint(posIdx, point.x, point.y)) + { + point = target->displayBox().center(posIdx); + return point; + } + else if(!target) + { + point = hdPoint(0, 0); + return point; + } + + hdGeometry g; + + rect = getDisplayBox().gethdRect(posIdx); //hack to avoid linux bug + double angle = g.angleFromPoint(rect, point); + point = g.edgePointFromAngle(rect, angle); + return point; +} + +hdPoint hdChopBoxConnector::findStart(int posIdx, hdLineConnection *connFigure) +{ + if(!connFigure) + { + point = getDisplayBox().center(posIdx); + return point; + } + + if(connFigure->pointCount(posIdx) < 2) + { + point = getDisplayBox().center(posIdx); + return point; + } + + hdIFigure *start = connFigure->getStartConnector()->getOwner(); + point = connFigure->pointAt(posIdx, 1); + point = chop(posIdx, start, point); + return point; +} + +hdPoint hdChopBoxConnector::findEnd(int posIdx, hdLineConnection *connFigure) +{ + if(!connFigure) + { + return getDisplayBox().center(posIdx); + } + hdIFigure *end = connFigure->getEndConnector()->getOwner(); + point = connFigure->pointAt(posIdx, connFigure->pointCount(posIdx) - 2); + point = chop(posIdx, end, point); + return point; +} diff --git a/hotdraw/connectors/hdIConnector.cpp b/hotdraw/connectors/hdIConnector.cpp new file mode 100644 index 0000000..e6cc29a --- /dev/null +++ b/hotdraw/connectors/hdIConnector.cpp @@ -0,0 +1,66 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdIConnector.cpp - Base class for all connectors +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/connectors/hdIConnector.h" + +class hdLineConnection; +class hdIFigure; + +hdIConnector::hdIConnector(hdIFigure *owner): + hdObject() +{ + figureOwner = owner; +} + +hdIConnector::~hdIConnector() +{ +} + +hdIFigure *hdIConnector::getOwner() +{ + return figureOwner; + +} + +void hdIConnector::setOwner(hdIFigure *owner) +{ + figureOwner = owner; +} + +void hdIConnector::draw(wxBufferedDC &context) +{ +} + +hdMultiPosRect &hdIConnector::getDisplayBox() +{ + return figureOwner->displayBox(); +} + +bool hdIConnector::containsPoint(int posIdx, int x, int y) +{ + return figureOwner->containsPoint(posIdx, x, y); +} + +hdPoint hdIConnector::findStart(int posIdx, hdLineConnection *connection) +{ + return getDisplayBox().center(posIdx); +} + +hdPoint hdIConnector::findEnd(int posIdx, hdLineConnection *connection) +{ + return getDisplayBox().center(posIdx); +} diff --git a/hotdraw/connectors/hdLocatorConnector.cpp b/hotdraw/connectors/hdLocatorConnector.cpp new file mode 100644 index 0000000..9a2325f --- /dev/null +++ b/hotdraw/connectors/hdLocatorConnector.cpp @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdLocatorConnector.cpp - class that puts connects at locator position +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/connectors/hdLocatorConnector.h" +hdLocatorConnector::hdLocatorConnector(hdIFigure *owner, hdILocator *locator): + hdIConnector(owner) +{ + figureOwner = owner; + figureLocator = locator; + size = 8; +} + +hdLocatorConnector::~hdLocatorConnector() +{ +} + +hdPoint hdLocatorConnector::locate(int posIdx) +{ + return figureLocator->locate(posIdx, getOwner()); +} + +void hdLocatorConnector::draw(wxBufferedDC &context) +{ +} + +hdRect &hdLocatorConnector::getDisplayBox(int posIdx) +{ + hdPoint p = figureLocator->locate(posIdx, getOwner()); + displayBox = hdRect(p.x - (size / 2), p.y - (size / 2), size, size); + return displayBox; +} + +bool hdLocatorConnector::containsPoint(int posIdx, int x, int y) +{ + return getDisplayBox(posIdx).Contains(x, y); +} + +hdPoint hdLocatorConnector::findStart(int posIdx, hdLineConnection *connection) +{ + return getDisplayBox(posIdx).center(); +} + +hdPoint hdLocatorConnector::findEnd(int posIdx, hdLineConnection *connection) +{ + return getDisplayBox(posIdx).center(); +} diff --git a/hotdraw/connectors/hdStickyRectangleConnector.cpp b/hotdraw/connectors/hdStickyRectangleConnector.cpp new file mode 100644 index 0000000..ab7072c --- /dev/null +++ b/hotdraw/connectors/hdStickyRectangleConnector.cpp @@ -0,0 +1,73 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdStickyRectangleConnector.cpp - A StickyRectangleConnector locates connection points by choping +// the connection between the centers of the two figures at the display box. The location +// of the connection point is computed once, when the user connects the figure. +// Moving the figure around will not change the location. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/connectors/hdStickyRectangleConnector.h" +#include "hotdraw/figures/hdLineConnection.h" +#include "hotdraw/connectors/hdChopBoxConnector.h" +#include "hotdraw/utilities/hdGeometry.h" + +class hdLineConnection; +class hdIFigure; + +hdStickyRectangleConnector::hdStickyRectangleConnector(hdIFigure *owner, hdPoint p): + hdChopBoxConnector(owner) +{ + hdGeometry g; + updateAnchor(0, p); +} + +hdStickyRectangleConnector::~hdStickyRectangleConnector() +{ +} + +void hdStickyRectangleConnector::setAngle(float newAngle) +{ + angle = newAngle; +} + +void hdStickyRectangleConnector::updateAnchor(int posIdx, hdPoint p) +{ + hdGeometry g; + + hdRect rect = getDisplayBox().gethdRect(posIdx); //hack to avoid linux bug + angle = g.angleFromPoint(rect, p); +} + +hdPoint hdStickyRectangleConnector::getAnchor(int posIdx) +{ + hdGeometry g; + + hdRect rect = getDisplayBox().gethdRect(posIdx); //hack to avoid linux bug + return g.edgePointFromAngle(rect, angle); +} + +hdPoint hdStickyRectangleConnector::chop(int posIdx, hdIFigure *target, hdPoint point) +{ + + hdGeometry g; + + hdRect rect = target->displayBox().gethdRect(posIdx); //hack to avoid linux bug + point = g.edgePointFromAngle(rect, angle); + return point; +} + +void hdStickyRectangleConnector::draw(wxBufferedDC &context) +{ +} diff --git a/hotdraw/connectors/module.mk b/hotdraw/connectors/module.mk new file mode 100644 index 0000000..245f019 --- /dev/null +++ b/hotdraw/connectors/module.mk @@ -0,0 +1,19 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/hotdraw/connectors/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + hotdraw/connectors/hdChopBoxConnector.cpp \ + hotdraw/connectors/hdIConnector.cpp \ + hotdraw/connectors/hdLocatorConnector.cpp \ + hotdraw/connectors/hdStickyRectangleConnector.cpp + +EXTRA_DIST += \ + hotdraw/connectors/module.mk diff --git a/hotdraw/figures/defaultAttributes/hdFillAttribute.cpp b/hotdraw/figures/defaultAttributes/hdFillAttribute.cpp new file mode 100644 index 0000000..1990cee --- /dev/null +++ b/hotdraw/figures/defaultAttributes/hdFillAttribute.cpp @@ -0,0 +1,45 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdFillAttribute.cpp - Default attribute for fill color of figure +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include + +// App headers +#include "hotdraw/figures/defaultAttributes/hdFillAttribute.h" +#include "hotdraw/figures/hdAttribute.h" + +hdFillAttribute::hdFillAttribute(): + hdAttribute() +{ + fillAttributes = wxBrush(*wxWHITE); +} + +void hdFillAttribute::apply(wxBufferedDC &context) +{ + context.SetBrush(fillAttributes); +} + +void hdFillAttribute::callDefaultChangeDialog(wxWindow *owner) +{ + //create brush dialog + wxColour color = wxGetColourFromUser(owner, fillAttributes.GetColour(), wxT("Select a color for fill color...")); + fillAttributes = wxBrush(color); +} + +wxBrush &hdFillAttribute::brush() +{ + return fillAttributes; +} diff --git a/hotdraw/figures/defaultAttributes/hdFontAttribute.cpp b/hotdraw/figures/defaultAttributes/hdFontAttribute.cpp new file mode 100644 index 0000000..d8395df --- /dev/null +++ b/hotdraw/figures/defaultAttributes/hdFontAttribute.cpp @@ -0,0 +1,50 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdFontAttribute.cpp - Default attribute for attributes of fonts +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include + +// App headers +#include "hotdraw/figures/defaultAttributes/hdFontAttribute.h" +#include "hotdraw/figures/hdAttribute.h" + +wxFont *hdFontAttribute::defaultFont = NULL; + +hdFontAttribute::hdFontAttribute(): + hdAttribute() +{ + fontAttributes = *defaultFont; +} + +void hdFontAttribute::apply(wxBufferedDC &context) +{ + context.SetFont(fontAttributes); +} + +void hdFontAttribute::callDefaultChangeDialog(wxWindow *owner) +{ + fontAttributes = wxGetFontFromUser(owner, fontAttributes, wxT("Select a font...")); +} + +wxFont &hdFontAttribute::font() +{ + return fontAttributes; +} + +void hdFontAttribute::InitFont() +{ + defaultFont = new wxFont(10, wxSWISS, wxNORMAL, wxNORMAL); +} diff --git a/hotdraw/figures/defaultAttributes/hdFontColorAttribute.cpp b/hotdraw/figures/defaultAttributes/hdFontColorAttribute.cpp new file mode 100644 index 0000000..2a5be91 --- /dev/null +++ b/hotdraw/figures/defaultAttributes/hdFontColorAttribute.cpp @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdFontAttribute.cpp - Default attribute for color of fonts +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include + +// App headers +#include "hotdraw/figures/defaultAttributes/hdFontColorAttribute.h" +#include "hotdraw/figures/hdAttribute.h" + +hdFontColorAttribute::hdFontColorAttribute(): + hdAttribute() +{ + fontColor = wxColour(*wxBLACK); +} + +void hdFontColorAttribute::apply(wxBufferedDC &context) +{ + context.SetTextForeground(fontColor); +} + +void hdFontColorAttribute::callDefaultChangeDialog(wxWindow *owner) +{ + fontColor = wxGetColourFromUser(owner, fontColor, wxT("Select a color for font...")); +} diff --git a/hotdraw/figures/defaultAttributes/hdLineAttribute.cpp b/hotdraw/figures/defaultAttributes/hdLineAttribute.cpp new file mode 100644 index 0000000..62e014d --- /dev/null +++ b/hotdraw/figures/defaultAttributes/hdLineAttribute.cpp @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdLineAttribute.cpp - Default Attribute for lines style, color an others at figure +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include + +// App headers +#include "hotdraw/figures/defaultAttributes/hdLineAttribute.h" +#include "hotdraw/figures/hdAttribute.h" + +hdLineAttribute::hdLineAttribute(): + hdAttribute() +{ + penAttributes = *wxBLACK_PEN; +} + +void hdLineAttribute::apply(wxBufferedDC &context) +{ + context.SetPen(penAttributes); +} + +void hdLineAttribute::callDefaultChangeDialog(wxWindow *owner) +{ + //create line dialog +} + +wxPen &hdLineAttribute::pen() +{ + return penAttributes; +} diff --git a/hotdraw/figures/defaultAttributes/module.mk b/hotdraw/figures/defaultAttributes/module.mk new file mode 100644 index 0000000..23b81f6 --- /dev/null +++ b/hotdraw/figures/defaultAttributes/module.mk @@ -0,0 +1,19 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/hotdraw/figures/defaultAttributes/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + hotdraw/figures/defaultAttributes/hdFillAttribute.cpp \ + hotdraw/figures/defaultAttributes/hdFontAttribute.cpp \ + hotdraw/figures/defaultAttributes/hdFontColorAttribute.cpp \ + hotdraw/figures/defaultAttributes/hdLineAttribute.cpp + +EXTRA_DIST += \ + hotdraw/figures/defaultAttributes/module.mk diff --git a/hotdraw/figures/hdAbstractFigure.cpp b/hotdraw/figures/hdAbstractFigure.cpp new file mode 100644 index 0000000..6d35066 --- /dev/null +++ b/hotdraw/figures/hdAbstractFigure.cpp @@ -0,0 +1,130 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdAbstractFigure.cpp - Base class for all figures +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "hotdraw/figures/hdAbstractFigure.h" +#include "hotdraw/figures/hdIFigure.h" +#include "hotdraw/utilities/hdArrayCollection.h" +#include "hotdraw/main/hdDrawingView.h" + +hdAbstractFigure::hdAbstractFigure() +{ + spaceForMovement.SetHeight(0); + spaceForMovement.SetWidth(0); +} + +hdAbstractFigure::~hdAbstractFigure() +{ +} + +bool hdAbstractFigure::canConnect () +{ + return true; +} + +bool hdAbstractFigure::includes(hdIFigure *figure) +{ + return (this == figure); +} + +void hdAbstractFigure::draw(wxBufferedDC &context, hdDrawingView *view) +{ + //Hack to Allow creations of limits for figures movements, but what to do should be defined at derivated classes + spaceForMovement = view->canvasSize; + hdIFigure::draw(context, view); + basicDraw(context, view); +} + +void hdAbstractFigure::basicDraw(wxBufferedDC &context, hdDrawingView *view) +{ + hdRect copy = displayBox().gethdRect(view->getIdx()); + view->CalcScrolledPosition(copy.x, copy.y, ©.x, ©.y); + + context.SetPen(*wxGREEN_PEN); + context.SetBrush(wxBrush (wxColour(208, 208, 208), wxSOLID)); + context.DrawRectangle(copy); +} + +void hdAbstractFigure::drawSelected(wxBufferedDC &context, hdDrawingView *view) +{ + hdIFigure::drawSelected(context, view); + basicDrawSelected(context, view); +} + +void hdAbstractFigure::basicDrawSelected(wxBufferedDC &context, hdDrawingView *view) +{ + hdRect copy = displayBox().gethdRect(view->getIdx()); + view->CalcScrolledPosition(copy.x, copy.y, ©.x, ©.y); + + context.SetPen(*wxRED_PEN); + context.SetBrush(wxBrush (wxColour(133, 133, 133), wxSOLID)); + context.DrawRectangle(copy); +} + + +hdITool *hdAbstractFigure::CreateFigureTool(hdDrawingView *view, hdITool *defaultTool) +{ + return defaultTool; +} + +void hdAbstractFigure::moveBy(int posIdx, int x, int y) +{ + willChange(); + basicMoveBy(posIdx, x, y); + changed(posIdx); +} + +void hdAbstractFigure::basicMoveBy(int posIdx, int x, int y) +{ + basicDisplayBox.x[posIdx] += x; + basicDisplayBox.y[posIdx] += y; +} + + +void hdAbstractFigure::moveTo(int posIdx, int x, int y) +{ + basicDisplayBox.x[posIdx] = x; + basicDisplayBox.y[posIdx] = y; +} + +void hdAbstractFigure::willChange() +{ + invalidate(); +} + +void hdAbstractFigure::changed(int posIdx) +{ + invalidate(); + onFigureChanged(posIdx, this); +} + +void hdAbstractFigure::invalidate() +{ + +} + +bool hdAbstractFigure::containsPoint(int posIdx, int x, int y) +{ + return basicDisplayBox.Contains(posIdx, x, y); +} + +void hdAbstractFigure::onFigureChanged(int posIdx, hdIFigure *figure) +{ + //go to figure procedure to alert observers of changes on this figure + hdIFigure::onFigureChanged(posIdx, figure); +} diff --git a/hotdraw/figures/hdAbstractMenuFigure.cpp b/hotdraw/figures/hdAbstractMenuFigure.cpp new file mode 100644 index 0000000..5964d63 --- /dev/null +++ b/hotdraw/figures/hdAbstractMenuFigure.cpp @@ -0,0 +1,59 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdAbstractMenuFigure.cpp - Base class for figures that show a menu with right click +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "hotdraw/figures/hdAbstractMenuFigure.h" +#include "hotdraw/figures/hdIFigure.h" +#include "hotdraw/utilities/hdArrayCollection.h" +#include "hotdraw/main/hdDrawingView.h" +#include "hotdraw/tools/hdMenuTool.h" + +hdAbstractMenuFigure::hdAbstractMenuFigure() +{ +} + +hdAbstractMenuFigure::~hdAbstractMenuFigure() +{ +} + + +hdITool *hdAbstractMenuFigure::CreateFigureTool(hdDrawingView *view, hdITool *defaultTool) +{ + return new hdMenuTool(view, this, defaultTool); +} + +void hdAbstractMenuFigure::enablePopUp() +{ + showMenu = true; +} + +void hdAbstractMenuFigure::disablePopUp() +{ + showMenu = false; +} + +bool hdAbstractMenuFigure::menuEnabled() +{ + return showMenu; +} + +void hdAbstractMenuFigure::OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view) +{ + //Action on popup goes here + //strings[event.GetId()] +} diff --git a/hotdraw/figures/hdAttribute.cpp b/hotdraw/figures/hdAttribute.cpp new file mode 100644 index 0000000..e2334eb --- /dev/null +++ b/hotdraw/figures/hdAttribute.cpp @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdAttributeFigure.cpp - Base class for all figure attributes +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "hotdraw/figures/hdAttribute.h" + +hdAttribute::hdAttribute(): + hdObject() +{ +} + +void hdAttribute::apply(wxBufferedDC &context) +{ +} + +void hdAttribute::callDefaultChangeDialog(wxWindow *owner) +{ +} + diff --git a/hotdraw/figures/hdAttributeFigure.cpp b/hotdraw/figures/hdAttributeFigure.cpp new file mode 100644 index 0000000..ea8e448 --- /dev/null +++ b/hotdraw/figures/hdAttributeFigure.cpp @@ -0,0 +1,95 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdAttributeFigure.cpp - Base class for all figures with attributes (line size, fonts and others) +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "hotdraw/figures/hdAttributeFigure.h" +#include "hotdraw/figures/hdAttribute.h" +#include "hotdraw/figures/defaultAttributes/hdFillAttribute.h" +#include "hotdraw/figures/defaultAttributes/hdFontAttribute.h" +#include "hotdraw/figures/defaultAttributes/hdFontColorAttribute.h" +#include "hotdraw/figures/defaultAttributes/hdLineAttribute.h" + +hdAttributeFigure::hdAttributeFigure() +{ + initializeDefaultAttributes(); +} + +hdAttributeFigure::~hdAttributeFigure() +{ + delete fillAttribute; + delete lineAttribute; + delete fontAttribute; + delete fontColorAttribute; + delete fillSelAttribute; + delete lineSelAttribute; + delete fontSelAttribute; + delete fontSelColorAttribute; +} + +void hdAttributeFigure::draw(wxBufferedDC &context, hdDrawingView *view) +{ + //find a way to allow user to use custom attributes without affecting performance + fillAttribute->apply(context); + lineAttribute->apply(context); + fontAttribute->apply(context); + fontColorAttribute->apply(context); + + hdAbstractFigure::draw(context, view); +} + +void hdAttributeFigure::drawSelected(wxBufferedDC &context, hdDrawingView *view) +{ + //find a way to allow user to use custom attributes without affecting performance + fillSelAttribute->apply(context); + lineSelAttribute->apply(context); + fontSelAttribute->apply(context); + fontSelColorAttribute->apply(context); + + hdAbstractFigure::drawSelected(context, view); +} + +void hdAttributeFigure::initializeDefaultAttributes() +{ + + fontAttribute = new hdFontAttribute(); + fontColorAttribute = new hdFontColorAttribute(); + fillAttribute = new hdFillAttribute(); + lineAttribute = new hdLineAttribute(); + + fontSelAttribute = new hdFontAttribute(); + fontSelColorAttribute = new hdFontColorAttribute(); + fillSelAttribute = new hdFillAttribute(); + lineSelAttribute = new hdLineAttribute(); + +} + +void hdAttributeFigure::reapplyAttributes(wxBufferedDC &context, hdDrawingView *view) +{ + fillAttribute->apply(context); + lineAttribute->apply(context); + fontAttribute->apply(context); + fontColorAttribute->apply(context); +} + +void hdAttributeFigure::reapplySelAttributes(wxBufferedDC &context, hdDrawingView *view) +{ + fillSelAttribute->apply(context); + lineSelAttribute->apply(context); + fontSelAttribute->apply(context); + fontSelColorAttribute->apply(context); +} diff --git a/hotdraw/figures/hdBitmapFigure.cpp b/hotdraw/figures/hdBitmapFigure.cpp new file mode 100644 index 0000000..6d6b550 --- /dev/null +++ b/hotdraw/figures/hdBitmapFigure.cpp @@ -0,0 +1,62 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdCompositeFigure.cpp - Figure that draw a bitmap +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "hotdraw/figures/hdBitmapFigure.h" +#include "hotdraw/main/hdDrawingView.h" + + +hdBitmapFigure::hdBitmapFigure(wxBitmap image) +{ + imageToDraw = image; + this->getBasicDisplayBox().width = imageToDraw.GetWidth(); + this->getBasicDisplayBox().height = imageToDraw.GetHeight(); +} + +hdBitmapFigure::~hdBitmapFigure() +{ +} + +void hdBitmapFigure::basicDraw(wxBufferedDC &context, hdDrawingView *view) +{ + hdRect copy = displayBox().gethdRect(view->getIdx()); + view->CalcScrolledPosition(copy.x, copy.y, ©.x, ©.y); + context.DrawBitmap(imageToDraw, copy.GetPosition(), true); +} + +void hdBitmapFigure::basicDrawSelected(wxBufferedDC &context, hdDrawingView *view) +{ + basicDraw(context, view); +} + +void hdBitmapFigure::changeBitmap(wxBitmap image) +{ + imageToDraw = image; + //Index doesn't care because width and height are shared in a MultiPosRect + this->getBasicDisplayBox().width = imageToDraw.GetWidth(); + this->getBasicDisplayBox().height = imageToDraw.GetHeight(); +} + +int hdBitmapFigure::getWidth() +{ + return imageToDraw.GetWidth(); +} + +int hdBitmapFigure::getHeight() +{ + return imageToDraw.GetHeight(); +} diff --git a/hotdraw/figures/hdCompositeFigure.cpp b/hotdraw/figures/hdCompositeFigure.cpp new file mode 100644 index 0000000..5e95cf2 --- /dev/null +++ b/hotdraw/figures/hdCompositeFigure.cpp @@ -0,0 +1,271 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdCompositeFigure.cpp - Base class for all figures composite with figures +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "hotdraw/figures/hdCompositeFigure.h" +#include "hotdraw/figures/hdIFigure.h" +#include "hotdraw/utilities/hdArrayCollection.h" +#include "hotdraw/tools/hdCompositeFigureTool.h" + +hdCompositeFigure::hdCompositeFigure() +{ + figureFigures = new hdCollection(new hdArrayCollection()); + figureHandles = new hdCollection(new hdArrayCollection()); +} + +void hdCompositeFigure::AddPosForNewDiagram() +{ + //Add position for new displaybox at new diagram + hdAttributeFigure::AddPosForNewDiagram(); + //Add position to each figure inside this composite figure + hdIteratorBase *iterator = figuresEnumerator(); + while(iterator->HasNext()) + { + hdIFigure *f = (hdIFigure *) iterator->Next(); + f->AddPosForNewDiagram(); + } + delete iterator; +} + +void hdCompositeFigure::RemovePosOfDiagram(int posIdx) +{ + hdAttributeFigure::RemovePosOfDiagram(posIdx); + hdIteratorBase *iterator = figuresEnumerator(); + while(iterator->HasNext()) + { + hdIFigure *f = (hdIFigure *) iterator->Next(); + f->RemovePosOfDiagram(posIdx); + } + delete iterator; +} + +hdCompositeFigure::~hdCompositeFigure() +{ + hdIHandle *tmpH; + //Handles should be delete by their owner (figure) + while(figureHandles->count() > 0) + { + tmpH = (hdIHandle *) figureHandles->getItemAt(0); + figureHandles->removeItemAt(0); + delete tmpH; + } + if(figureHandles) + delete figureHandles; + + hdIFigure *tmp; + while(figureFigures->count() > 0) + { + tmp = (hdIFigure *) figureFigures->getItemAt(0); + figureFigures->removeItemAt(0); + delete tmp; + } + if(figureFigures) + delete figureFigures; +} + +void hdCompositeFigure::basicMoveBy(int posIdx, int x, int y) +{ + hdIteratorBase *iterator = figuresEnumerator(); + while(iterator->HasNext()) + { + hdIFigure *f = (hdIFigure *) iterator->Next(); + f->moveBy(posIdx, x, y); + } + + basicDisplayBox.x[posIdx] += x; + basicDisplayBox.y[posIdx] += y; + delete iterator; +} + +bool hdCompositeFigure::containsPoint(int posIdx, int x, int y) +{ + bool out = false; + hdIteratorBase *iterator = figuresEnumerator(); + while(iterator->HasNext()) + { + hdIFigure *f = (hdIFigure *) iterator->Next(); + if(f->containsPoint(posIdx, x, y)) + { + out = true; //avoid memory leak + } + } + delete iterator; + return out; +} + +hdIteratorBase *hdCompositeFigure::figuresEnumerator() +{ + return figureFigures->createIterator(); +} + +hdIteratorBase *hdCompositeFigure::figuresInverseEnumerator() +{ + return figureFigures->createDownIterator(); +} + +//Ignore figures at negative positions +hdMultiPosRect &hdCompositeFigure::getBasicDisplayBox() +{ + basicDisplayBox.SetSize(wxSize(0, 0)); + + int posIdx; + hdIteratorBase *iterator = figuresEnumerator(); + for(posIdx = 0; posIdx < basicDisplayBox.CountPositions(); posIdx++) + { + basicDisplayBox.SetPosition(posIdx, wxPoint(0, 0)); + bool firstFigure = true; + + while(iterator->HasNext()) + { + hdIFigure *f = (hdIFigure *) iterator->Next(); + if(firstFigure) + { + basicDisplayBox.SetPosition(posIdx, f->displayBox().GetPosition(posIdx)); + basicDisplayBox.SetSize( f->displayBox().GetSize()); + if(f->displayBox().GetPosition(posIdx).x > 0 && f->displayBox().GetPosition(posIdx).y > 0) + firstFigure = false; + } + else + { + if(f->displayBox().GetPosition(posIdx).x > 0 && f->displayBox().GetPosition(posIdx).y > 0) + basicDisplayBox.add(posIdx, f->displayBox().gethdRect(posIdx) ); + } + } + iterator->ResetIterator(); + } + delete iterator; + return basicDisplayBox; + +} + +hdCollection *hdCompositeFigure::handlesEnumerator() +{ + return figureHandles; +} + +void hdCompositeFigure::add(hdIFigure *figure) +{ + if(includes(figure)) + return; + + //Add figure + figureFigures->addItem(figure); + //Check figure available positions for diagrams. + int i, start; + start = figure->displayBox().CountPositions(); + for(i = start; i < basicDisplayBox.CountPositions(); i++) + { + figure->AddPosForNewDiagram(); + } + //Add figure handles + hdIteratorBase *handlesIterator = figure->handlesEnumerator()->createIterator(); + while(handlesIterator->HasNext()) + { + hdIHandle *h = (hdIHandle *) handlesIterator->Next(); + figureHandles->addItem(h); + } + delete handlesIterator; +} + +void hdCompositeFigure::remove(hdIFigure *figure) +{ + if(!includes(figure)) + return; + + //Remove figure handles + hdIteratorBase *handlesIterator = figure->handlesEnumerator()->createIterator(); + while(handlesIterator->HasNext()) + { + hdIHandle *h = (hdIHandle *) handlesIterator->Next(); + figureHandles->removeItem(h); + } + delete handlesIterator; + //Remove figure + figureFigures->removeItem(figure); +} + +bool hdCompositeFigure::includes(hdIFigure *figure) +{ + if(hdAbstractFigure::includes(figure)) + return true; + + bool out = false; + + hdIteratorBase *iterator = figuresEnumerator(); + while(iterator->HasNext()) + { + hdIFigure *f = (hdIFigure *) iterator->Next(); + if(f->includes(figure)) + out = true; + } + delete iterator; + return out; +} + +void hdCompositeFigure::basicDraw(wxBufferedDC &context, hdDrawingView *view) +{ + hdIteratorBase *iterator = figuresEnumerator(); + hdIFigure *f = NULL; + while(iterator->HasNext()) + { + f = (hdIFigure *) iterator->Next(); + f->draw(context, view); + } + delete iterator; +} + +void hdCompositeFigure::basicDrawSelected(wxBufferedDC &context, hdDrawingView *view) +{ + hdIteratorBase *iterator = figuresEnumerator(); + hdIFigure *f = NULL; + while(iterator->HasNext()) + { + f = (hdIFigure *) iterator->Next(); + f->drawSelected(context, view); + } + delete iterator; +} + +hdIFigure *hdCompositeFigure::findFigure(int posIdx, int x, int y) +{ + hdIFigure *tmp = NULL, *out = NULL; + hdIteratorBase *iterator = figuresInverseEnumerator(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->containsPoint(posIdx, x, y)) + { + out = tmp; + break; + } + } + + delete iterator; + + return out; +} + +hdITool *hdCompositeFigure::CreateFigureTool(hdDrawingView *view, hdITool *defaultTool) +{ + return new hdCompositeFigureTool(view, this, defaultTool); +} + +hdIFigure *hdCompositeFigure::getFigureAt(int indexOfCollection) +{ + return (hdIFigure *) figureFigures->getItemAt(indexOfCollection); +} diff --git a/hotdraw/figures/hdIConnectionFigure.cpp b/hotdraw/figures/hdIConnectionFigure.cpp new file mode 100644 index 0000000..eaa0bf5 --- /dev/null +++ b/hotdraw/figures/hdIConnectionFigure.cpp @@ -0,0 +1,23 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdIConnectionFigure.cpp - Base class for all connection figures +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "hotdraw/figures/hdIConnectionFigure.h" + +// All functions abstract prototypes inside hdIConnectionFigure.h +// this is just a base class diff --git a/hotdraw/figures/hdIFigure.cpp b/hotdraw/figures/hdIFigure.cpp new file mode 100644 index 0000000..6b98dbc --- /dev/null +++ b/hotdraw/figures/hdIFigure.cpp @@ -0,0 +1,175 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdIFigure.cpp - Base class for all figures +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "hotdraw/figures/hdIFigure.h" +#include "hotdraw/handles/hdIHandle.h" +#include "hotdraw/utilities/hdArrayCollection.h" +#include "hotdraw/tools/hdITool.h" +#include "hotdraw/connectors/hdIConnector.h" +#include "hotdraw/connectors/hdChopBoxConnector.h" + +hdIFigure::hdIFigure() +{ + handles = new hdCollection(new hdArrayCollection()); + observers = new hdCollection(new hdArrayCollection()); + unsigned int i; + for(i = 0; i < MAXPOS; i++) + { + selected.Add(false); + } + connector = NULL; + basicDisplayBox.SetSize(wxSize(0, 0)); +} + +hdIFigure::~hdIFigure() +{ + if(connector) + delete connector; + if(handles) + delete handles; + if(observers) + { + observers->removeAll(); + delete observers; + } +} + +void hdIFigure::AddPosForNewDiagram() +{ + basicDisplayBox.addNewXYPosition(); + selected.Add(false); +} + +void hdIFigure::RemovePosOfDiagram(int posIdx) +{ + basicDisplayBox.removeXYPosition(posIdx); +} + +hdMultiPosRect &hdIFigure::displayBox() +{ + return getBasicDisplayBox(); +} + +hdMultiPosRect &hdIFigure::getBasicDisplayBox() +{ + return basicDisplayBox; +} + +void hdIFigure::draw (wxBufferedDC &context, hdDrawingView *view) +{ + +} + +void hdIFigure::drawSelected (wxBufferedDC &context, hdDrawingView *view) +{ + +} + +hdCollection *hdIFigure::handlesEnumerator() +{ + return handles; +} + +void hdIFigure::addHandle (hdIHandle *handle) +{ + if(!handles) + { + handles = new hdCollection(new hdArrayCollection()); + } + handles->addItem(handle); +} + +void hdIFigure::removeHandle (hdIHandle *handle) +{ + if(handles) + { + handles->removeItem(handle); + } +} + +hdITool *hdIFigure::CreateFigureTool(hdDrawingView *view, hdITool *defaultTool) +{ + return defaultTool; +} + +bool hdIFigure::isSelected(int posIdx) +{ + return selected[posIdx]; +} + +void hdIFigure::setSelected(int posIdx, bool value) +{ + selected[posIdx] = value; +} + +hdIConnector *hdIFigure::connectorAt (int posIdx, int x, int y) +{ + if(!connector) + connector = new hdChopBoxConnector(this); + return connector; +} + +bool hdIFigure::includes(hdIFigure *figure) +{ + return (this == figure); +} + +void hdIFigure::onFigureChanged(int posIdx, hdIFigure *figure) +{ + + hdIteratorBase *iterator = observers->createIterator(); + while(iterator->HasNext()) + { + hdIFigure *o = (hdIFigure *) iterator->Next(); + o->onFigureChanged(posIdx, this); + } + delete iterator; +} + +void hdIFigure::addObserver(hdIFigure *observer) +{ + if(!observers) + { + observers = new hdCollection(new hdArrayCollection()); + } + observers->addItem(observer); +} + +void hdIFigure::removeObserver(hdIFigure *observer) +{ + if(observers) + { + observers->removeItem(observer); + } +} + +hdIteratorBase *hdIFigure::observersEnumerator() +{ + return observers->createIterator(); +} + +void hdIFigure::setKindId(int hiddenId) +{ + kindHiddenId = hiddenId; +} + +//Hack because is kindof in not powerful as it should be +int hdIFigure::getKindId() +{ + return kindHiddenId; +} diff --git a/hotdraw/figures/hdLineConnection.cpp b/hotdraw/figures/hdLineConnection.cpp new file mode 100644 index 0000000..4197f82 --- /dev/null +++ b/hotdraw/figures/hdLineConnection.cpp @@ -0,0 +1,293 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdLineConnection.cpp - Base class for line connection figure +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "hotdraw/figures/hdLineConnection.h" +#include "hotdraw/handles/hdChangeConnectionStartHandle.h" +#include "hotdraw/handles/hdChangeConnectionEndHandle.h" +#include "hotdraw/handles/hdLineConnectionHandle.h" +#include "hotdraw/locators/hdPolyLineLocator.h" +#include "hotdraw/utilities/hdArrayCollection.h" + +hdLineConnection::hdLineConnection(): + hdPolyLineFigure() +{ + startConnector = NULL; + endConnector = NULL; + changeConnStartHandle = NULL; + changeConnEndHandle = NULL; +} + +hdLineConnection::hdLineConnection(int posIdx, hdIFigure *figure1, hdIFigure *figure2): + hdPolyLineFigure() +{ + //Check figure available positions for diagrams, add at least needed to allow initialization of the class + int i, start; + start = basicDisplayBox.CountPositions(); + for(i = start; i < (posIdx + 1); i++) + { + AddPosForNewDiagram(); + } + + startConnector = NULL; + endConnector = NULL; + + if(figure1) + { + connectStart(figure1->connectorAt(posIdx, 0, 0)); + } + + if(figure2) + { + connectEnd(figure2->connectorAt(posIdx, 0, 0)); + } +} + +hdLineConnection::~hdLineConnection() +{ +} + +hdIConnector *hdLineConnection::getStartConnector() +{ + return startConnector; +} + +hdIConnector *hdLineConnection::getEndConnector() +{ + return endConnector; +} + +void hdLineConnection::setStartConnector(hdIConnector *connector) +{ + startConnector = connector; +} + +void hdLineConnection::setEndConnector(hdIConnector *connector) +{ + endConnector = connector; +} + +void hdLineConnection::connectStart(hdIConnector *start, hdDrawingView *view) +{ + if(startConnector == start) + { + return; + } + + disconnectStart(); + startConnector = start; + connectFigure(startConnector); +} + +void hdLineConnection::connectEnd(hdIConnector *end, hdDrawingView *view) +{ + if(endConnector == end) + { + return; + } + + disconnectEnd(); + endConnector = end; + connectFigure(endConnector); +} + +void hdLineConnection::disconnectStart(hdDrawingView *view) +{ + disconnectFigure (startConnector); + startConnector = NULL; +} + +void hdLineConnection::disconnectEnd(hdDrawingView *view) +{ + disconnectFigure (endConnector); + endConnector = NULL; +} + +bool hdLineConnection::canConnectStart(hdIFigure *figure) +{ + return true; +} + +bool hdLineConnection::canConnectEnd(hdIFigure *figure) +{ + return true; +} + +hdIFigure *hdLineConnection::getStartFigure() +{ + if(startConnector) + { + return startConnector->getOwner(); + } + + return NULL; +} + +hdIFigure *hdLineConnection::getEndFigure() +{ + if(endConnector) + { + return endConnector->getOwner(); + } + + return NULL; +} + +void hdLineConnection::updateConnection(int posIdx) +{ + if(startConnector) + { + setStartPoint(posIdx, startConnector->findStart(posIdx, this)); + } + if(endConnector) + { + setEndPoint(posIdx, endConnector->findEnd(posIdx, this)); + } +} + +hdIHandle *hdLineConnection::getStartHandle() +{ + if(!changeConnStartHandle) + { + changeConnStartHandle = new hdChangeConnectionStartHandle(this); + } + return changeConnStartHandle; +} + +hdIHandle *hdLineConnection::getEndHandle() +{ + if(!changeConnEndHandle) + { + changeConnEndHandle = new hdChangeConnectionEndHandle(this); + } + return changeConnEndHandle; +} + +void hdLineConnection::basicMoveBy(int posIdx, int x, int y) +{ + hdPolyLineFigure::basicMoveBy(posIdx, x, y); + updateConnection(posIdx); +} + +bool hdLineConnection::canConnect() +{ + return false; +} + +void hdLineConnection::setPointAt (int posIdx, int index, int x, int y) +{ + hdPolyLineFigure::setPointAt(posIdx, index, x, y); + updateConnection(posIdx); +} + +hdCollection *hdLineConnection::handlesEnumerator() +{ + return handles; +} + + +void hdLineConnection::connectFigure (hdIConnector *connector) +{ + if(connector) + { + connector->getOwner()->addObserver(this); + } +} + +void hdLineConnection::disconnectFigure (hdIConnector *connector) +{ + if(connector) + { + connector->getOwner()->removeObserver(this); + } +} + +void hdLineConnection::onFigureChanged(int posIdx, hdIFigure *figure) +{ + updateConnection(posIdx); +} + +void hdLineConnection::addPoint (int posIdx, int x, int y) +{ + willChange(); + points[posIdx]->addItem((hdObject *) new hdPoint(x, y) ); + //Update handles + if(points[posIdx]->count() == 1) + { + //first point add start handle + if(handles->count() == 0) + handles->addItem(getStartHandle()); + } + else if(points[posIdx]->count() == 2) + { + //second point add end handle + if(handles->count() == 1) + handles->addItem(getEndHandle()); + } + else if(points[posIdx]->count() > 2) + { + //Locate maximum index if there is need for one new handle then added it + if( getMaximunIndex() > handles->count() ) + { + //third and above point, add a polylinehandle before end handle + handles->insertAtIndex(new hdPolyLineHandle(this, new hdPolyLineLocator(0), 0), handles->count() - 1); + } + } + updateHandlesIndexes(); + changed(posIdx); +} + +void hdLineConnection::insertPointAt (int posIdx, int index, int x, int y) +{ + willChange(); + points[posIdx]->insertAtIndex((hdObject *) new hdPoint(x, y), index); + //Update handles + //Is there need of a new handle if is first point + if(index == 0 && handles->count() == 0 ) + { + //add a new handle "normal" for a point in next position 0,1 in 1... in 0 startHandle is not moved + handles->insertAtIndex(new hdPolyLineHandle(this, new hdPolyLineLocator(index), index), 1); + } + else if(index == (points[posIdx]->count() - 1) && handles->count() < getMaximunIndex() ) //last point + { + //add a new handle "normal" for a point in before last item position + handles->insertAtIndex(new hdPolyLineHandle(this, new hdPolyLineLocator(index), index), (points[posIdx]->count() - 1)); + } + else if(handles->count() < getMaximunIndex()) + { + //add handle at index + handles->insertAtIndex(new hdPolyLineHandle(this, new hdPolyLineLocator(index), index), index); + } + updateHandlesIndexes(); + changed(posIdx); +} + +//Update points between start and end, because start and end don't have index (is other kind of handle) +void hdLineConnection::updateHandlesIndexes() +{ + hdPolyLineHandle *h = NULL; + + //Get maximun point position in a collection of points + int maxPosition = getMaximunIndex(); + + //Update Handles indexes + for(int i = 1; i < maxPosition - 1; i++) + { + h = (hdPolyLineHandle *) handles->getItemAt(i); + h->setIndex(i); + } +} diff --git a/hotdraw/figures/hdLineTerminal.cpp b/hotdraw/figures/hdLineTerminal.cpp new file mode 100644 index 0000000..689892a --- /dev/null +++ b/hotdraw/figures/hdLineTerminal.cpp @@ -0,0 +1,59 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdLineTerminal.cpp - Base class for line terminal figure +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "hotdraw/figures/hdLineTerminal.h" +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/utilities/hdGeometry.h" +#include "hotdraw/main/hdDrawingView.h" + +hdLineTerminal::hdLineTerminal() +{ + middle = hdPoint(0, 0); + terminalLinePen = wxPen(wxString(wxT("BLACK")), 1, wxSOLID); +} + +hdLineTerminal::~hdLineTerminal() +{ +} + +void hdLineTerminal::setLinePen(wxPen pen) +{ + terminalLinePen = pen; +} + +hdPoint &hdLineTerminal::draw (wxBufferedDC &context, hdPoint &a, hdPoint &b, hdDrawingView *view) +{ + hdGeometry g; + context.SetPen(terminalLinePen); + + hdPoint copyA = hdPoint (a); + view->CalcScrolledPosition(copyA.x, copyA.y, ©A.x, ©A.y); + hdPoint copyB = hdPoint (b); + view->CalcScrolledPosition(copyB.x, copyB.y, ©B.x, ©B.y); + context.DrawLine(copyA, copyB); + + context.SetPen(wxPen(wxString(wxT("BLACK")), 1, wxSOLID)); + int x = copyA.x + g.ddabs(copyA.x - copyB.x); + int y = copyA.y + g.ddabs(copyA.y - copyB.y); + middle = hdPoint(x, y); + + context.DrawRectangle(wxRect(copyA.x, copyA.y, 5, 5)); + context.DrawCircle(copyA, 10); + return middle; +} diff --git a/hotdraw/figures/hdPolyLineFigure.cpp b/hotdraw/figures/hdPolyLineFigure.cpp new file mode 100644 index 0000000..079644d --- /dev/null +++ b/hotdraw/figures/hdPolyLineFigure.cpp @@ -0,0 +1,446 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdPolyLineFigure.cpp - A simple line figure that can be split on several lines joined by flexibility points +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "hotdraw/figures/hdPolyLineFigure.h" +#include "hotdraw/utilities/hdArrayCollection.h" +#include "hotdraw/locators/hdILocator.h" +#include "hotdraw/handles/hdPolyLineHandle.h" +#include "hotdraw/figures/hdLineTerminal.h" +#include "hotdraw/locators/hdPolyLineLocator.h" +#include "hotdraw/utilities/hdGeometry.h" +#include "hotdraw/tools/hdPolyLineFigureTool.h" +#include "hotdraw/tools/hdMenuTool.h" + +hdPolyLineFigure::hdPolyLineFigure() +{ + unsigned int i; + + for(i = 0; i < MAXPOS ; i++) + { + points.Add(new hdArrayCollection()); + } + + startTerminal = NULL; + endTerminal = NULL; + handlesChanged = false; + startPoint = hdPoint(0, 0); + endPoint = hdPoint(0, 0); + pointAtPos = hdPoint(0, 0); + linePen = wxPen(wxString(wxT("BLACK")), 1, wxSOLID); +} + +hdPolyLineFigure::~hdPolyLineFigure() +{ + hdPoint *tmp; //Hack: If just delete points collection an error is raised. + hdArrayCollection *tmpCollection; + + unsigned int i; + for(i = 0; i < points.Count(); i++) + { + while(points[i]->count() > 0) + { + tmp = (hdPoint *) points[i]->getItemAt(0); + points[i]->removeItemAt(0); + delete tmp; + } + if(points[i]) + { + tmpCollection = points[i]; + points.RemoveAt(i); + delete tmpCollection; + } + } + if(startTerminal) + delete startTerminal; + if(endTerminal) + delete endTerminal; +} + +void hdPolyLineFigure::AddPosForNewDiagram() +{ + //Add position for new displaybox at new diagram + hdIFigure::AddPosForNewDiagram(); + //Add new array of point for polylinefigure + points.Add(new hdArrayCollection()); +} + +void hdPolyLineFigure::RemovePosOfDiagram(int posIdx) +{ + hdIFigure::RemovePosOfDiagram(posIdx); + + //Hack: If just delete points collection an error is raised. + hdPoint *tmp; + hdArrayCollection *tmpCollection; + while(points[posIdx]->count() > 0) + { + tmp = (hdPoint *) points[posIdx]->getItemAt(0); + points[posIdx]->removeItemAt(0); + delete tmp; + } + + if(points[posIdx]) + { + tmpCollection = points[posIdx]; + points.RemoveAt(posIdx); + delete tmpCollection; + } +} + +int hdPolyLineFigure::getMaximunIndex() +{ + unsigned int i; + int max = points[0]->count(); + + for(i = 1; i < points.Count(); i++) + { + if(points[i]->count() > max) + { + max = points[i]->count(); + } + + } + return max; +} + + +hdMultiPosRect &hdPolyLineFigure::getBasicDisplayBox() +{ + basicDisplayBox.height = 0; + basicDisplayBox.width = 0; + + int posIdx; + //optimize this if needed in a future, because right now calculate displaybox for all posIdx + hdIteratorBase *iterator; + for(posIdx = 0; posIdx < basicDisplayBox.CountPositions(); posIdx++) + { + if(points[posIdx]->count() >= 1) + { + basicDisplayBox.SetPosition(posIdx, pointAt(posIdx, 0)); + } + else + { + basicDisplayBox.SetPosition(posIdx, wxPoint(0, 0)); + } + + iterator = points[posIdx]->createIterator(); + while(iterator->HasNext()) + { + hdPoint *p = (hdPoint *) iterator->Next(); + hdRect r = hdRect(p->x, p->y, 0, 0); + basicDisplayBox.add(posIdx, r); + } + + delete iterator; + } + return basicDisplayBox; +} + +int hdPolyLineFigure::pointLinesCount() +{ + return points.Count(); +} +int hdPolyLineFigure::pointCount(int posIdx) +{ + return points[posIdx]->count(); +} + +hdPoint &hdPolyLineFigure::getStartPoint(int posIdx) +{ + startPoint.x = ((hdPoint *)points[posIdx]->getItemAt(0))->x; + startPoint.y = ((hdPoint *)points[posIdx]->getItemAt(0))->y; + return startPoint; +} + +void hdPolyLineFigure::setStartPoint(int posIdx, hdPoint point) +{ + willChange(); + if(points[posIdx]->count() == 0) + addPoint(posIdx, point.x, point.y); + else + { + hdPoint *p = (hdPoint *) points[posIdx]->getItemAt(0); + p->x = point.x; + p->y = point.y; + } + changed(posIdx); +} + +hdPoint &hdPolyLineFigure::getEndPoint(int posIdx) +{ + endPoint.x = ((hdPoint *)points[posIdx]->getItemAt(points[posIdx]->count() - 1))->x; + endPoint.y = ((hdPoint *)points[posIdx]->getItemAt(points[posIdx]->count() - 1))->y; + return endPoint; +} + +void hdPolyLineFigure::setEndPoint(int posIdx, hdPoint point) +{ + willChange(); + if(points[posIdx]->count() < 2) + addPoint(posIdx, point.x, point.y); + else + { + hdPoint *p = (hdPoint *) points[posIdx]->getItemAt(points[posIdx]->count() - 1); + p->x = point.x; + p->y = point.y; + } + changed(posIdx); +} + +void hdPolyLineFigure::setStartTerminal(hdLineTerminal *terminal) +{ + startTerminal = terminal; +} + +hdLineTerminal *hdPolyLineFigure::getStartTerminal() +{ + return startTerminal; +} + +void hdPolyLineFigure::setEndTerminal(hdLineTerminal *terminal) +{ + endTerminal = terminal; +} + +hdLineTerminal *hdPolyLineFigure::getEndTerminal() +{ + return endTerminal; +} + +hdCollection *hdPolyLineFigure::handlesEnumerator() +{ + return handles; +} + +void hdPolyLineFigure::addPoint (int posIdx, int x, int y) +{ + willChange(); + points[posIdx]->addItem((hdObject *) new hdPoint(x, y) ); + + if( handles->count() < getMaximunIndex() ) + { + //Update handles + handles->addItem(new hdPolyLineHandle(this, new hdPolyLineLocator(0), 0)); + updateHandlesIndexes(); + } + changed(posIdx); +} + +void hdPolyLineFigure::changed(int posIdx) +{ + handlesChanged = true; +} + +void hdPolyLineFigure::removePointAt (int posIdx, int index) +{ + willChange(); + hdPoint *p = (hdPoint *) points[posIdx]->getItemAt(index); + points[posIdx]->removeItemAt(index); + delete p; + //Update handles [If there are more handles than maximum points of a line in a view] + if( handles->count() > getMaximunIndex() ) + { + handles->removeItemAt(index); + updateHandlesIndexes(); + } + changed(posIdx); +} + +void hdPolyLineFigure::basicDrawSelected(wxBufferedDC &context, hdDrawingView *view) +{ + basicDraw(context, view); +} + +void hdPolyLineFigure::basicDraw(wxBufferedDC &context, hdDrawingView *view) +{ + int posIdx = view->getIdx(); + if(points[posIdx]->count() < 2) + { + return; + } + hdPoint start, end; + + if(startTerminal) + { + startTerminal->setLinePen(linePen); + start = startTerminal->draw(context, getStartPoint(posIdx), pointAt(posIdx, 1), view); + } + else + { + start = getStartPoint(posIdx); + } + + if(endTerminal) + { + endTerminal->setLinePen(linePen); + end = endTerminal->draw(context, getEndPoint(posIdx), pointAt(posIdx, pointCount(posIdx) - 2), view); + } + else + { + end = getEndPoint(posIdx); + } + + context.SetPen(linePen); + for(int i = 0; i < points[posIdx]->count() - 1; i++) + { + hdPoint *p1 = (hdPoint *) points[posIdx]->getItemAt(i); + hdPoint *p2 = (hdPoint *) points[posIdx]->getItemAt(i + 1); + + hdPoint copyP1 = hdPoint (*p1); + view->CalcScrolledPosition(copyP1.x, copyP1.y, ©P1.x, ©P1.y); + hdPoint copyP2 = hdPoint (*p2); + view->CalcScrolledPosition(copyP2.x, copyP2.y, ©P2.x, ©P2.y); + + context.DrawLine(copyP1, copyP2); + } +} + +void hdPolyLineFigure::basicMoveBy(int posIdx, int x, int y) +{ + hdPoint *movPoint; + for(int i = 0 ; i < points[posIdx]->count() ; i++) + { + movPoint = (hdPoint *) points[posIdx]->getItemAt(i); + movPoint->x += x; + movPoint->y += y; + } +} + +hdITool *hdPolyLineFigure::CreateFigureTool(hdDrawingView *view, hdITool *defaultTool) +{ + return new hdPolyLineFigureTool(view, this, new hdMenuTool(view, this, defaultTool)); +} + + +int hdPolyLineFigure::findSegment (int posIdx, int x, int y) +{ + for(int i = 0 ; i < points[posIdx]->count() - 1 ; i++) + { + hdPoint p1 = pointAt(posIdx, i); + hdPoint p2 = pointAt(posIdx, i + 1); + hdGeometry g; + if(g.lineContainsPoint(p1.x, p1.y, p2.x, p2.y, x, y)) + { + return i + 1; + } + } + return -1; +} + +hdPoint &hdPolyLineFigure::pointAt(int posIdx, int index) +{ + //hack to avoid error with bad indexes calls + if(index < 0) + { + pointAtPos.x = 0; + pointAtPos.y = 0; + } + else + { + pointAtPos.x = ((hdPoint *)points[posIdx]->getItemAt(index))->x; + pointAtPos.y = ((hdPoint *)points[posIdx]->getItemAt(index))->y; + } + return pointAtPos; +} + +bool hdPolyLineFigure::containsPoint (int posIdx, int x, int y) +{ + hdRect rect = this->displayBox().gethdRect(posIdx); + rect.Inflate(4, 4); + if(!rect.Contains(x, y)) + { + return false; + } + + for(int i = 0 ; i < points[posIdx]->count() - 1 ; i++) + { + hdPoint p1 = pointAt(posIdx, i); + hdPoint p2 = pointAt(posIdx, i + 1); + hdGeometry g; + if(g.lineContainsPoint(p1.x, p1.y, p2.x, p2.y, x, y)) + { + return true; + } + } + return false; +} + +void hdPolyLineFigure::clearPoints(int posIdx) +{ + points[posIdx]->deleteAll(); +} + +void hdPolyLineFigure::insertPointAt (int posIdx, int index, int x, int y) +{ + willChange(); + points[posIdx]->insertAtIndex((hdObject *) new hdPoint(x, y), index); + + if( handles->count() < getMaximunIndex() ) + { + //Update handles + handles->insertAtIndex(new hdPolyLineHandle(this, new hdPolyLineLocator(index), index), index); + updateHandlesIndexes(); + } + + changed(posIdx); +} + +void hdPolyLineFigure::setPointAt (int posIdx, int index, int x, int y) +{ + willChange(); + hdPoint *p = (hdPoint *) points[posIdx]->getItemAt(index); + p->x = x; + p->y = y; + changed(posIdx); +} + +void hdPolyLineFigure::splitSegment(int posIdx, int x, int y) +{ + int index = findSegment(posIdx, x, y); + + if(index != -1) + { + insertPointAt(posIdx, index, x, y); + } +} + +void hdPolyLineFigure::updateHandlesIndexes() +{ + hdPolyLineHandle *h = NULL; + + //Get maximun point position in a collection of points + int i, maxPosition = getMaximunIndex(); + + //Update Handles indexes + for(i = 0; i < maxPosition; i++) + { + h = (hdPolyLineHandle *) handles->getItemAt(i); + h->setIndex(i); + } + +} + +void hdPolyLineFigure::setLinePen(wxPen pen) +{ + linePen = pen; +} + +int hdPolyLineFigure::countPointsAt(int posIdx) +{ + return points[posIdx]->count(); +} diff --git a/hotdraw/figures/hdRectangleFigure.cpp b/hotdraw/figures/hdRectangleFigure.cpp new file mode 100644 index 0000000..8d730eb --- /dev/null +++ b/hotdraw/figures/hdRectangleFigure.cpp @@ -0,0 +1,52 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdRectangleFigure.cpp - A simple rectangle figure +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "hotdraw/figures/hdRectangleFigure.h" +#include "hotdraw/main/hdDrawingView.h" + +hdRectangleFigure::hdRectangleFigure() +{ +} + +hdRectangleFigure::~hdRectangleFigure() +{ +} + +void hdRectangleFigure::basicDraw(wxBufferedDC &context, hdDrawingView *view) +{ + hdRect copy = displayBox().gethdRect(view->getIdx()); + view->CalcScrolledPosition(copy.x, copy.y, ©.x, ©.y); + context.DrawRectangle(copy); +} + +void hdRectangleFigure::basicDrawSelected(wxBufferedDC &context, hdDrawingView *view) +{ + hdRect copy = displayBox().gethdRect(view->getIdx()); + view->CalcScrolledPosition(copy.x, copy.y, ©.x, ©.y); + context.DrawRectangle(copy); +} + +void hdRectangleFigure::setRectangle(hdMultiPosRect &rect) +{ + basicDisplayBox = rect; +} + +void hdRectangleFigure::setSize(wxSize &size) +{ + basicDisplayBox.SetSize(size); +} diff --git a/hotdraw/figures/hdSimpleTextFigure.cpp b/hotdraw/figures/hdSimpleTextFigure.cpp new file mode 100644 index 0000000..394178b --- /dev/null +++ b/hotdraw/figures/hdSimpleTextFigure.cpp @@ -0,0 +1,139 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdSimpleTextFigure.cpp - A simple rectangle figure with text inside it +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "hotdraw/figures/hdSimpleTextFigure.h" +#include "hotdraw/tools/hdSimpleTextTool.h" +#include "hotdraw/utilities/hdGeometry.h" +#include "hotdraw/figures/defaultAttributes/hdFontAttribute.h" + +// dummy image +#include "images/ddnull.pngc" + +hdSimpleTextFigure::hdSimpleTextFigure(wxString textString) +{ + textEditable = false; + font = *hdFontAttribute::defaultFont; + padding = 2; + setText(textString); + showMenu = false; +} + +hdSimpleTextFigure::~hdSimpleTextFigure() +{ +} + +void hdSimpleTextFigure::setText(wxString textString) +{ + text = textString; + recalculateDisplayBox(); +} + +//extended is flag that inform about returning an extended version of text stored at figure +wxString &hdSimpleTextFigure::getText(bool extended) +{ + return text; +} + +void hdSimpleTextFigure::setFont(wxFont textFont) +{ + font = textFont; + recalculateDisplayBox(); +} + +void hdSimpleTextFigure::getFontMetrics(int &width, int &height) +{ + wxBitmap emptyBitmap(*ddnull_png_img); + wxMemoryDC temp_dc; + temp_dc.SelectObject(emptyBitmap); + temp_dc.SetFont(font); + if(getText(true).length() > 5) + temp_dc.GetTextExtent(getText(true), &width, &height); + else + temp_dc.GetTextExtent(wxT("EMPTY"), &width, &height); +} + +void hdSimpleTextFigure::recalculateDisplayBox() +{ + int w, h; + + getFontMetrics(w, h); + + hdGeometry g; + displayBox().width = g.max(w, 10) + padding; + displayBox().height = g.max(h, 10) + padding; +} + +void hdSimpleTextFigure::basicDraw(wxBufferedDC &context, hdDrawingView *view) +{ + hdRect copy = displayBox().gethdRect(view->getIdx()); + view->CalcScrolledPosition(copy.x, copy.y, ©.x, ©.y); + context.DrawText(getText(true), copy.GetPosition()); +} + +void hdSimpleTextFigure::basicDrawSelected(wxBufferedDC &context, hdDrawingView *view) +{ + hdRect copy = displayBox().gethdRect(view->getIdx()); + view->CalcScrolledPosition(copy.x, copy.y, ©.x, ©.y); + context.DrawText(getText(true), copy.GetPosition()); +} + +void hdSimpleTextFigure::basicMoveBy(int posIdx, int x, int y) +{ + displayBox().x[posIdx] += x; + displayBox().y[posIdx] += y; +} + +hdITool *hdSimpleTextFigure::CreateFigureTool(hdDrawingView *view, hdITool *defaultTool) +{ + return textEditable ? new hdSimpleTextTool(view, this, defaultTool) : defaultTool; +} + +void hdSimpleTextFigure::setEditable(bool value) +{ + textEditable = value; +} + +bool hdSimpleTextFigure::getEditable() +{ + return textEditable; +} + +int hdSimpleTextFigure::getPadding() +{ + return padding; +} + +void hdSimpleTextFigure::enablePopUp() +{ + showMenu = true; +} + +void hdSimpleTextFigure::disablePopUp() +{ + showMenu = false; +} + +bool hdSimpleTextFigure::menuEnabled() +{ + return showMenu; +} + +void hdSimpleTextFigure::OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view) +{ + setText(strings[event.GetId()]); +} diff --git a/hotdraw/figures/module.mk b/hotdraw/figures/module.mk new file mode 100644 index 0000000..ed01f04 --- /dev/null +++ b/hotdraw/figures/module.mk @@ -0,0 +1,31 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/hotdraw/figures/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + hotdraw/figures/hdAbstractFigure.cpp \ + hotdraw/figures/hdAbstractMenuFigure.cpp \ + hotdraw/figures/hdAttribute.cpp \ + hotdraw/figures/hdAttributeFigure.cpp \ + hotdraw/figures/hdBitmapFigure.cpp \ + hotdraw/figures/hdCompositeFigure.cpp \ + hotdraw/figures/hdIConnectionFigure.cpp \ + hotdraw/figures/hdIFigure.cpp \ + hotdraw/figures/hdLineConnection.cpp \ + hotdraw/figures/hdLineTerminal.cpp \ + hotdraw/figures/hdPolyLineFigure.cpp \ + hotdraw/figures/hdRectangleFigure.cpp \ + hotdraw/figures/hdSimpleTextFigure.cpp + +EXTRA_DIST += \ + hotdraw/figures/module.mk + +include hotdraw/figures/defaultAttributes/module.mk +include hotdraw/figures/xml/module.mk diff --git a/hotdraw/figures/xml/hdStorage.cpp b/hotdraw/figures/xml/hdStorage.cpp new file mode 100644 index 0000000..4050d4c --- /dev/null +++ b/hotdraw/figures/xml/hdStorage.cpp @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdStorage.cpp - Base class for managing all figures persistence +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// libxml2 headers +#include +#include + +// App headers +#include "hotdraw/figures/xml/hdStorage.h" + +hdStorage::hdStorage(): + hdObject() +{ +} + +bool hdStorage::Read(xmlTextReaderPtr reader) +{ + return false; +} + +bool hdStorage::Write(xmlTextWriterPtr writer, hdIFigure *figure) +{ + return false; +} diff --git a/hotdraw/figures/xml/module.mk b/hotdraw/figures/xml/module.mk new file mode 100644 index 0000000..3f6dad7 --- /dev/null +++ b/hotdraw/figures/xml/module.mk @@ -0,0 +1,16 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/hotdraw/figures/xml/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + hotdraw/figures/xml/hdStorage.cpp + +EXTRA_DIST += \ + hotdraw/figures/xml/module.mk diff --git a/hotdraw/handles/hdButtonHandle.cpp b/hotdraw/handles/hdButtonHandle.cpp new file mode 100644 index 0000000..1467b13 --- /dev/null +++ b/hotdraw/handles/hdButtonHandle.cpp @@ -0,0 +1,72 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdButtonHandle.cpp - Handle to allow creation of buttons at figures +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/handles/hdButtonHandle.h" +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/main/hdDrawingView.h" + + + +hdButtonHandle::hdButtonHandle(hdIFigure *owner, hdILocator *buttonLocator , wxBitmap &buttonImage, wxSize &size): + hdIHandle(owner) +{ + buttonIcon = buttonImage; + clicked = false; + bLocator = buttonLocator; + displayBox.SetSize(size); +} + +hdButtonHandle::~hdButtonHandle() +{ + if(bLocator) + delete bLocator; +} + +wxCursor hdButtonHandle::createCursor() +{ + return wxCursor(wxCURSOR_ARROW); +} + +hdRect &hdButtonHandle::getDisplayBox(int posIdx) +{ + hdPoint p = locate(posIdx); + displayBox.SetPosition(p); + return displayBox; +} + +void hdButtonHandle::draw(wxBufferedDC &context, hdDrawingView *view) +{ + wxPoint copy = getDisplayBox(view->getIdx()).GetPosition(); + view->CalcScrolledPosition(copy.x, copy.y, ©.x, ©.y); + if(buttonIcon.IsOk()) + context.DrawBitmap(buttonIcon, copy.x, copy.y, true); +} + + +hdPoint &hdButtonHandle::locate(int posIdx) +{ + if(bLocator) + { + pointLocate = bLocator->locate(posIdx, getOwner()); + return pointLocate; + } + else + { + pointLocate = hdPoint(0, 0); + return pointLocate; + } +} diff --git a/hotdraw/handles/hdChangeConnectionEndHandle.cpp b/hotdraw/handles/hdChangeConnectionEndHandle.cpp new file mode 100644 index 0000000..ade1d14 --- /dev/null +++ b/hotdraw/handles/hdChangeConnectionEndHandle.cpp @@ -0,0 +1,65 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdChangeConnectionEndHandle.cpp - Handle to allow change connected figure at end of connection figure +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/handles/hdChangeConnectionEndHandle.h" +#include "hotdraw/utilities/hdPoint.h" + +hdChangeConnectionEndHandle::hdChangeConnectionEndHandle(hdLineConnection *owner): + hdChangeConnectionHandle(owner) +{ +} + +hdChangeConnectionEndHandle::~hdChangeConnectionEndHandle() +{ +} + +hdPoint &hdChangeConnectionEndHandle::locate(int posIdx) +{ + return connection->getEndPoint(posIdx); +} + +hdIConnector *hdChangeConnectionEndHandle::target() +{ + return connection->getEndConnector(); +} + +void hdChangeConnectionEndHandle::connect(hdIConnector *connector, hdDrawingView *view) +{ + connection->connectEnd(connector, view); +} + +void hdChangeConnectionEndHandle::disconnect(hdDrawingView *view) +{ + connection->disconnectEnd(view); +} + +bool hdChangeConnectionEndHandle::isConnectionPossible(hdIFigure *figure) +{ + if(!figure->includes(connection) && figure->canConnect() && connection->canConnectEnd(figure)) + { + return true; + } + else + { + return false; + } +} + +void hdChangeConnectionEndHandle::setPoint(int posIdx, hdPoint p) +{ + connection->setEndPoint(posIdx, p); +} diff --git a/hotdraw/handles/hdChangeConnectionHandle.cpp b/hotdraw/handles/hdChangeConnectionHandle.cpp new file mode 100644 index 0000000..54e3fff --- /dev/null +++ b/hotdraw/handles/hdChangeConnectionHandle.cpp @@ -0,0 +1,116 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdChangeConnectionHandle.cpp - Base Handle to allow change connected figures at connection figures +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "hotdraw/handles/hdChangeConnectionHandle.h" +#include "hotdraw/figures/hdLineConnection.h" +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/main/hdDrawingView.h" + + +hdChangeConnectionHandle::hdChangeConnectionHandle(hdLineConnection *owner): + hdIHandle(owner) +{ + connection = owner; + targetFigure = NULL; + originalTarget = NULL; +} + +hdChangeConnectionHandle::~hdChangeConnectionHandle() +{ + +} + +void hdChangeConnectionHandle::draw(wxBufferedDC &context, hdDrawingView *view) +{ + + hdRect copy = getDisplayBox(view->getIdx()); + view->CalcScrolledPosition(copy.x, copy.y, ©.x, ©.y); + + copy.Deflate(2, 2); + context.SetPen(*wxGREEN_PEN); + context.SetBrush(*wxGREEN_BRUSH); + context.DrawRectangle(copy); +} + +wxCursor hdChangeConnectionHandle::createCursor() +{ + return wxCursor(wxCURSOR_CROSS); +} + +void hdChangeConnectionHandle::invokeStart(hdMouseEvent &event, hdDrawingView *view) +{ + originalTarget = target(); + disconnect(view); +} + +void hdChangeConnectionHandle::invokeStep(hdMouseEvent &event, hdDrawingView *view) +{ + int x = event.GetPosition().x, y = event.GetPosition().y; + hdPoint p = hdPoint(x, y); + hdIFigure *figure = findConnectableFigure(view->getIdx(), x, y, view->getDrawing()); + targetFigure = figure; + hdIConnector *target = findConnectionTarget(view->getIdx(), x, y, view->getDrawing()); + if(target) + { + p = target->getDisplayBox().center(view->getIdx()); + } + setPoint(view->getIdx(), p); + connection->updateConnection(view->getIdx()); + if(view) + view->Refresh(); +} + +void hdChangeConnectionHandle::invokeEnd(hdMouseEvent &event, hdDrawingView *view) +{ + int x = event.GetPosition().x, y = event.GetPosition().y; + hdIConnector *target = findConnectionTarget(view->getIdx(), x, y, view->getDrawing()); + if(!target) + { + target = originalTarget; + } + connect(target, view); + connection->updateConnection(view->getIdx()); + if(view) + view->Refresh(); +} + + +hdIFigure *hdChangeConnectionHandle::findConnectableFigure (int posIdx, int x, int y, hdDrawing *drawing) +{ + hdIFigure *out = NULL; + hdIteratorBase *iterator = drawing->figuresInverseEnumerator(); + while(iterator->HasNext()) + { + hdIFigure *figure = (hdIFigure *) iterator->Next(); + if(figure->containsPoint(posIdx, x, y) && isConnectionPossible(figure)) + { + out = figure; + break; + } + } + delete iterator; + return out; +} +hdIConnector *hdChangeConnectionHandle::findConnectionTarget(int posIdx, int x, int y, hdDrawing *drawing) +{ + hdIFigure *target = findConnectableFigure(posIdx, x, y, drawing); + if(target) + return target->connectorAt(posIdx, x, y); + else + return NULL; +} diff --git a/hotdraw/handles/hdChangeConnectionStartHandle.cpp b/hotdraw/handles/hdChangeConnectionStartHandle.cpp new file mode 100644 index 0000000..2d09a3f --- /dev/null +++ b/hotdraw/handles/hdChangeConnectionStartHandle.cpp @@ -0,0 +1,65 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdChangeConnectionStartHandle.cpp - Handle to allow change connected figure at start of connection figure +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/handles/hdChangeConnectionStartHandle.h" +#include "hotdraw/utilities/hdPoint.h" + +hdChangeConnectionStartHandle::hdChangeConnectionStartHandle(hdLineConnection *owner): + hdChangeConnectionHandle(owner) +{ +} + +hdChangeConnectionStartHandle::~hdChangeConnectionStartHandle() +{ +} + +hdPoint &hdChangeConnectionStartHandle::locate(int posIdx) +{ + return connection->getStartPoint(posIdx); +} + +hdIConnector *hdChangeConnectionStartHandle::target() +{ + return connection->getStartConnector(); +} + +void hdChangeConnectionStartHandle::connect(hdIConnector *connector, hdDrawingView *view) +{ + connection->connectStart(connector, view); +} + +void hdChangeConnectionStartHandle::disconnect(hdDrawingView *view) +{ + connection->disconnectStart(view); +} + +bool hdChangeConnectionStartHandle::isConnectionPossible(hdIFigure *figure) +{ + if(!figure->includes(connection) && figure->canConnect() && connection->canConnectStart(figure)) + { + return true; + } + else + { + return false; + } +} + +void hdChangeConnectionStartHandle::setPoint(int posIdx, hdPoint p) +{ + connection->setStartPoint(posIdx, p); +} diff --git a/hotdraw/handles/hdIHandle.cpp b/hotdraw/handles/hdIHandle.cpp new file mode 100644 index 0000000..337b0bc --- /dev/null +++ b/hotdraw/handles/hdIHandle.cpp @@ -0,0 +1,47 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdIHandle.cpp - Base class for all Handles +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/handles/hdIHandle.h" +#include "hotdraw/utilities/hdPoint.h" + +hdIHandle::hdIHandle(hdIFigure *owner) +{ + figureOwner = owner; +} +hdIHandle::~hdIHandle() +{ +} + +hdIFigure *hdIHandle::getOwner() +{ + return figureOwner; +} + +hdRect &hdIHandle::getDisplayBox(int posIdx) +{ + hdPoint p = locate(posIdx); + displayBox.width = 0; + displayBox.height = 0; + displayBox.SetPosition(p); + displayBox.Inflate(size, size); + return displayBox; +} + +bool hdIHandle::containsPoint(int posIdx, int x, int y) +{ + return getDisplayBox(posIdx).Contains(x, y); +} diff --git a/hotdraw/handles/hdLineConnectionHandle.cpp b/hotdraw/handles/hdLineConnectionHandle.cpp new file mode 100644 index 0000000..cae86ea --- /dev/null +++ b/hotdraw/handles/hdLineConnectionHandle.cpp @@ -0,0 +1,46 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdLineConnectionHandle.cpp - Base class for Handles that are located at locator position +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "hotdraw/handles/hdLineConnectionHandle.h" +#include "hotdraw/figures/hdPolyLineFigure.h" +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/utilities/hdGeometry.h" +#include "hotdraw/main/hdDrawingView.h" + +hdLineConnectionHandle::hdLineConnectionHandle(hdPolyLineFigure *figure, hdILocator *loc, int index): + hdPolyLineHandle(figure, loc, index) +{ +} + +void hdLineConnectionHandle::invokeEnd(hdMouseEvent &event, hdDrawingView *view) +{ + int x = event.GetPosition().x, y = event.GetPosition().y; + hdPolyLineFigure *figure = (hdPolyLineFigure *) getOwner(); + //eliminate all handles in the middle of a straight line + + if( figure->pointCount(view->getIdx()) > 2 && getIndex() != 0 && getIndex() != (figure->pointCount(view->getIdx()) - 1) ) + { + hdPoint p1 = figure->pointAt(view->getIdx(), getIndex() - 1); + hdPoint p2 = figure->pointAt(view->getIdx(), getIndex() + 1); + hdGeometry g; + if(g.lineContainsPoint(p1.x, p1.y, p2.x, p2.y, x, y)) + { + figure->removePointAt(view->getIdx(), getIndex()); + } + } +} diff --git a/hotdraw/handles/hdLocatorHandle.cpp b/hotdraw/handles/hdLocatorHandle.cpp new file mode 100644 index 0000000..40f1362 --- /dev/null +++ b/hotdraw/handles/hdLocatorHandle.cpp @@ -0,0 +1,53 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdLocatorHandle.cpp - Base class for Handles that are located at locator position +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/handles/hdLocatorHandle.h" + +hdLocatorHandle::hdLocatorHandle(hdIFigure *owner, hdILocator *locator): + hdIHandle(owner) +{ + loc = locator; +} + +hdLocatorHandle::~hdLocatorHandle() +{ + if(loc) + delete loc; +} + +hdPoint &hdLocatorHandle::locate(int posIdx) +{ + p = hdPoint(0, 0); + return loc == NULL ? p : loc->locate(posIdx, getOwner()); +} + +hdILocator *hdLocatorHandle::locator() +{ + return loc; +} + +void hdLocatorHandle::invokeStart(hdMouseEvent &event, hdDrawingView *view) +{ +} + +void hdLocatorHandle::invokeStep(hdMouseEvent &event, hdDrawingView *view) +{ +} + +void hdLocatorHandle::invokeEnd(hdMouseEvent &event, hdDrawingView *view) +{ +} diff --git a/hotdraw/handles/hdPolyLineHandle.cpp b/hotdraw/handles/hdPolyLineHandle.cpp new file mode 100644 index 0000000..bba2f15 --- /dev/null +++ b/hotdraw/handles/hdPolyLineHandle.cpp @@ -0,0 +1,90 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdPolyLineHandle.cpp - Handle for manipulation of multiple flexibility points lines. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "hotdraw/handles/hdPolyLineHandle.h" +#include "hotdraw/figures/hdPolyLineFigure.h" +#include "hotdraw/locators/hdPolyLineLocator.h" +#include "hotdraw/main/hdDrawingView.h" + + +hdPolyLineHandle::hdPolyLineHandle(hdPolyLineFigure *figure, hdILocator *loc, int index): + hdLocatorHandle((hdIFigure *)figure, loc) +{ + indx = index; +} + +hdPolyLineHandle::~hdPolyLineHandle() +{ +} + +void hdPolyLineHandle::draw(wxBufferedDC &context, hdDrawingView *view) +{ + //A Handle at polyline figure without a respetive flexibility point at line + //Hack to allow handles of polylines reuse between different versions of same line. + if(getOwner() && indx < (((hdPolyLineFigure *) getOwner())->countPointsAt(view->getIdx()) - 1) ) //indx 0 is first, count first is 1 + { + hdRect copy = getDisplayBox(view->getIdx()); + view->CalcScrolledPosition(copy.x, copy.y, ©.x, ©.y); + + /* Uncomment this for testing purposes of handles in a polyline figure + wxString pos = wxString::Format(_("%d"),indx); + double middle2 = copy.width / 2; + context.DrawText(pos,copy.x + middle2+3, copy.y + middle2); + */ + + double middle = copy.width / 2; + context.DrawCircle( + wxPoint(copy.x + middle, copy.y + middle), + wxCoord(middle) + ); + } +} + +void hdPolyLineHandle::invokeStep(hdMouseEvent &event, hdDrawingView *view) +{ + int x = event.GetPosition().x, y = event.GetPosition().y; + ((hdPolyLineFigure *) getOwner())->setPointAt(view->getIdx(), indx, x, y); + view->notifyChanged(); + +} + +void hdPolyLineHandle::invokeStart(hdMouseEvent &event, hdDrawingView *view) +{ + if(event.RightDown()) + { + ((hdPolyLineFigure *) getOwner())->removePointAt(view->getIdx(), indx); + view->notifyChanged(); + } +} +wxCursor hdPolyLineHandle::createCursor() +{ + return wxCursor(wxCURSOR_CROSS); + +} + +int hdPolyLineHandle::getIndex() +{ + return indx; +} + +void hdPolyLineHandle::setIndex(int index) +{ + indx = index; + hdPolyLineLocator *l = (hdPolyLineLocator *) locator(); + l->setIndex(index); +} diff --git a/hotdraw/handles/module.mk b/hotdraw/handles/module.mk new file mode 100644 index 0000000..7f0d240 --- /dev/null +++ b/hotdraw/handles/module.mk @@ -0,0 +1,23 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/hotdraw/handles/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + hotdraw/handles/hdButtonHandle.cpp \ + hotdraw/handles/hdChangeConnectionEndHandle.cpp \ + hotdraw/handles/hdChangeConnectionHandle.cpp \ + hotdraw/handles/hdChangeConnectionStartHandle.cpp \ + hotdraw/handles/hdIHandle.cpp \ + hotdraw/handles/hdLineConnectionHandle.cpp \ + hotdraw/handles/hdLocatorHandle.cpp \ + hotdraw/handles/hdPolyLineHandle.cpp + +EXTRA_DIST += \ + hotdraw/handles/module.mk diff --git a/hotdraw/locators/hdILocator.cpp b/hotdraw/locators/hdILocator.cpp new file mode 100644 index 0000000..c89b578 --- /dev/null +++ b/hotdraw/locators/hdILocator.cpp @@ -0,0 +1,27 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdILocator.cpp - Base class for creation of a location for a ddHandle +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/locators/hdILocator.h" + +hdILocator::hdILocator() +{ + locatePoint = hdPoint(0, 0); +} + +hdILocator::~hdILocator() +{ +} diff --git a/hotdraw/locators/hdPolyLineLocator.cpp b/hotdraw/locators/hdPolyLineLocator.cpp new file mode 100644 index 0000000..53daeb7 --- /dev/null +++ b/hotdraw/locators/hdPolyLineLocator.cpp @@ -0,0 +1,59 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdPolyLineLocator.cpp - Return multiple location at same time for a PolyLine +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/locators/hdPolyLineLocator.h" +#include "hotdraw/figures/hdIFigure.h" +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/figures/hdPolyLineFigure.h" + +hdPolyLineLocator::~hdPolyLineLocator() +{ +} + +//This index refers to point index inside collection not the diagram index +hdPolyLineLocator::hdPolyLineLocator(int index) +{ + indx = index; +} + +hdPoint &hdPolyLineLocator::locate(int posIdx, hdIFigure *owner) +{ + hdPolyLineFigure *figure = (hdPolyLineFigure *) owner; + + //A Handle at polyline figure without a respetive flexibility point at line + //Hack to allow handles of polylines reuse between different versions of same line. + if(figure && indx >= (figure->countPointsAt(posIdx) - 1) ) //indx 0 is first, count first is 1 + { + locatePoint.x = -100; //Any negative number that don't allow to the mouse to reach this locator + locatePoint.y = -100; + return locatePoint; + } + else if(figure) + { + locatePoint = figure->pointAt(posIdx, indx); + return locatePoint; + } + else + { + return locatePoint; + } +} + +void hdPolyLineLocator::setIndex(int index) +{ + indx = index; +} diff --git a/hotdraw/locators/module.mk b/hotdraw/locators/module.mk new file mode 100644 index 0000000..1defbd3 --- /dev/null +++ b/hotdraw/locators/module.mk @@ -0,0 +1,17 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/hotdraw/locator/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + hotdraw/locators/hdILocator.cpp \ + hotdraw/locators/hdPolyLineLocator.cpp + +EXTRA_DIST += \ + hotdraw/locators/module.mk diff --git a/hotdraw/main/hdDrawing.cpp b/hotdraw/main/hdDrawing.cpp new file mode 100644 index 0000000..ba0f947 --- /dev/null +++ b/hotdraw/main/hdDrawing.cpp @@ -0,0 +1,245 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdDrawing.cpp - Main storage class for all objects of the diagram, +// their functions are used by model and shouldn't be called directly +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/main/hdDrawing.h" +#include "hotdraw/main/hdDrawingView.h" +#include "hotdraw/main/hdDrawingEditor.h" +#include "hotdraw/utilities/hdArrayCollection.h" +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/figures/hdIFigure.h" + + +hdDrawing::hdDrawing(hdDrawingEditor *owner) +{ + figures = new hdCollection(new hdArrayCollection()); + selection = new hdCollection(new hdArrayCollection()); + usedView = NULL; + ownerEditor = owner; + drawingName = wxEmptyString; +} + +hdDrawing::~hdDrawing() +{ + //clear selection + if(selection) + { + selection->removeAll(); + delete selection; + } + + //Cannot delete figures, because they belong to model not to diagram + hdIFigure *tmp; + while(figures->count() > 0) + { + tmp = (hdIFigure *) figures->getItemAt(0); + figures->removeItemAt(0); + } + + if(figures) + delete figures; +} + +void hdDrawing::add(hdIFigure *figure) +{ + if(figures) + figures->addItem(figure); +} + +void hdDrawing::remove(hdIFigure *figure) +{ + if(figures) + { + figures->removeItem(figure); + if(usedView) + figure->moveTo(usedView->getIdx(), -1, -1); + } +} + +bool hdDrawing::includes(hdIFigure *figure) +{ + if(figures) + return figures->existsObject(figure); + return false; +} + +hdIFigure *hdDrawing::findFigure(int posIdx, int x, int y) +{ + hdIFigure *tmp = NULL, *out = NULL; + hdIteratorBase *iterator = figures->createIterator(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->containsPoint(posIdx, x, y)) + { + out = tmp; + break; + } + } + + delete iterator;; + + return out; +} + +void hdDrawing::recalculateDisplayBox(int posIdx) +{ + bool first = true; + hdIFigure *figure = NULL; + + hdIteratorBase *iterator = figures->createIterator(); + while(iterator->HasNext()) + { + figure = (hdIFigure *)iterator->Next(); + if(first) + { + displayBox = figure->displayBox().gethdRect(posIdx); + first = false; + } + else + { + displayBox.add(figure->displayBox().gethdRect(posIdx)); + } + } + + delete iterator; +} + +void hdDrawing::bringToFront(hdIFigure *figure) +{ + //To bring to front this figure need to be at last position when is draw + //because this reason sendToBack (last position) is used. + figures->sendToBack(figure); +} + +void hdDrawing::sendToBack(hdIFigure *figure) +{ + //To send to back this figure need to be at first position when is draw + //because this reason bringToFront (1st position) is used. + figures->bringToFront(figure); +} + +hdRect &hdDrawing::DisplayBox() +{ + return displayBox; +} + +hdIteratorBase *hdDrawing::figuresEnumerator() +{ + return figures->createIterator(); +} + +hdIteratorBase *hdDrawing::figuresInverseEnumerator() +{ + return figures->createDownIterator(); +} + +void hdDrawing::deleteAllFigures() +{ + selection->removeAll(); + + hdIFigure *tmp; + while(figures->count() > 0) + { + tmp = (hdIFigure *) figures->getItemAt(0); + figures->removeItemAt(0); + delete tmp; + } + //handles delete it together with figures +} + +void hdDrawing::removeAllFigures() +{ + selection->removeAll(); + + hdIFigure *tmp; + while(figures->count() > 0) + { + tmp = (hdIFigure *) figures->getItemAt(0); + figures->removeItemAt(0); + if(usedView) + tmp->moveTo(usedView->getIdx(), -1, -1); + } +} + +void hdDrawing::deleteSelectedFigures() +{ + //Allow to customize delete dialog at Editor + ownerEditor->remOrDelSelFigures(usedView->getIdx()); +} + +void hdDrawing::addToSelection(hdIFigure *figure) +{ + if(!selection) + { + selection = new hdCollection(new hdArrayCollection()); + } + if(figure) + { + figure->setSelected(usedView->getIdx(), true); + selection->addItem(figure); + } +} + +void hdDrawing::addToSelection(hdCollection *figures) +{ +} + +void hdDrawing::removeFromSelection(hdIFigure *figure) +{ + figure->setSelected(usedView->getIdx(), false); + if(selection) + selection->removeItem(figure); +} + + +void hdDrawing::toggleSelection(hdIFigure *figure) +{ + if(figure->isSelected(usedView->getIdx()) && selection->existsObject(figure)) + selection->removeItem(figure); + else if(!figure->isSelected(usedView->getIdx()) && this->includes(figure)) + selection->addItem(figure); + + figure->setSelected(usedView->getIdx(), !figure->isSelected(usedView->getIdx())); +} + +void hdDrawing::clearSelection() +{ + hdIFigure *tmp = NULL; + hdIteratorBase *iterator = selection->createIterator(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + tmp->setSelected(usedView->getIdx(), false); + } + selection->removeAll(); + delete iterator; +} + +bool hdDrawing::isFigureSelected(hdIFigure *figure) +{ + return selection->existsObject(figure); +} + +hdIteratorBase *hdDrawing::selectionFigures() +{ + return selection->createIterator(); +} + +int hdDrawing::countSelectedFigures() +{ + return selection->count(); +} diff --git a/hotdraw/main/hdDrawingEditor.cpp b/hotdraw/main/hdDrawingEditor.cpp new file mode 100644 index 0000000..e1b7ef3 --- /dev/null +++ b/hotdraw/main/hdDrawingEditor.cpp @@ -0,0 +1,303 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdDrawingEditor.cpp - Main class that manages all other classes +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "hotdraw/main/hdDrawingEditor.h" +#include "hotdraw/main/hdDrawingView.h" +#include "hotdraw/tools/hdITool.h" +#include "hotdraw/figures/defaultAttributes/hdFontAttribute.h" + +hdDrawingEditor::hdDrawingEditor(wxWindow *owner, bool defaultView) +{ + _diagrams = new hdArrayCollection(); + _model = new hdArrayCollection(); + editorOwner = owner; + modelChanged = false; + + changeDefaultFiguresFont(); +} + +hdDrawingEditor::~hdDrawingEditor() +{ + //Hack: If just delete _diagrams collection an error is raised. + hdDrawing *diagram; + while(_diagrams->count() > 0) + { + diagram = (hdDrawing *) _diagrams->getItemAt(0); + _diagrams->removeItemAt(0); + delete diagram; + } + + //Hack: If just delete _model collection an error is raised. + hdIFigure *tmp; + while(_model->count() > 0) + { + tmp = (hdIFigure *) _model->getItemAt(0); + _model->removeItemAt(0); + delete tmp; + } + + if(_model) + delete _model; + + if(_diagrams) + delete _diagrams; +} + +//Hack to allow create different kind of custom _views inside custom editor +hdDrawing *hdDrawingEditor::createDiagram(wxWindow *owner, bool fromXml) +{ + hdDrawing *_tmpModel = new hdDrawing(this); + + hdDrawingView *_viewTmp = new hdDrawingView(_diagrams->count(), owner, this, wxSize(1200, 1200), _tmpModel); + + // Set Scroll Bar & split + _viewTmp->SetScrollbars( 10, 10, 127, 80 ); + _viewTmp->EnableScrolling(true, true); + _viewTmp->AdjustScrollbars(); + + _tmpModel->registerView(_viewTmp); + + //Add a new position inside each figure to allow use of this new diagram existing figures. + int i; + hdIFigure *tmp; + if(!fromXml) + { + for(i = 0; i < _model->count(); i++) + { + tmp = (hdIFigure *) _model->getItemAt(i); + tmp->AddPosForNewDiagram(); + } + } + + //Add Diagram + _diagrams->addItem((hdObject *) _tmpModel); + modelChanged = true; + return _tmpModel; +} + +void hdDrawingEditor::deleteDiagram(int diagramIndex, bool deleteView) +{ + hdDrawing *_tmpModel = (hdDrawing *) _diagrams->getItemAt(diagramIndex); + _diagrams->removeItemAt(diagramIndex); + hdDrawingView *_viewTmp = _tmpModel->getView(); + _tmpModel->registerView(NULL); + if(_tmpModel) + delete _tmpModel; + if(_viewTmp && deleteView) + delete _viewTmp; + + // Fix other diagrams positions + int i; + for(i = diagramIndex; i < _diagrams->count(); i++) + { + getExistingDiagram(i)->getView()->syncIdx(i); + } + + //Remove this position inside each figure to allow delete that diagram related info from figures. + hdIFigure *tmp; + for(i = 0; i < _model->count(); i++) + { + tmp = (hdIFigure *) _model->getItemAt(i); + tmp->RemovePosOfDiagram(diagramIndex); + } + modelChanged = true; +} + +hdDrawingView *hdDrawingEditor::getExistingView(int diagramIndex) +{ + if(diagramIndex >= _diagrams->count() || diagramIndex < 0) + { + return NULL; + } + + hdDrawing *diagram = (hdDrawing *) _diagrams->getItemAt(diagramIndex); + return diagram->getView(); +} + +hdDrawing *hdDrawingEditor::getExistingDiagram(int diagramIndex) +{ + if(diagramIndex >= _diagrams->count() || diagramIndex < 0) + { + return NULL; + } + + return (hdDrawing *) _diagrams->getItemAt(diagramIndex); +} + +void hdDrawingEditor::addModelFigure(hdIFigure *figure) +{ + if(_model) + _model->addItem(figure); + modelChanged = true; +} + +void hdDrawingEditor::removeFromAllSelections(hdIFigure *figure) +{ + if(_model) + { + if(_diagrams) + { + int i; + for(i = 0; i < _diagrams->count(); i++) + { + if(getExistingDiagram(i)->isFigureSelected(figure)) + getExistingDiagram(i)->removeFromSelection(figure); + } + } + } +} + +void hdDrawingEditor::deleteModelFigure(hdIFigure *figure) +{ + if(_model) + { + if(_diagrams) + { + int i; + for(i = 0; i < _diagrams->count(); i++) + { + if(getExistingDiagram(i)->includes(figure)) + getExistingDiagram(i)->remove(figure); + } + } + _model->removeItem(figure); + delete figure; + figure = NULL; + } + modelChanged = true; +} + +void hdDrawingEditor::addDiagramFigure(int diagramIndex, hdIFigure *figure) +{ + //first time figure is used at a diagram then add to it + if(!modelIncludes(figure)) + { + //Add figure to model + addModelFigure(figure); + //Add needed position(s) to figure to allow their use at new diagram(s). + int i, start; + start = figure->displayBox().CountPositions(); + for(i = start; i < _diagrams->count(); i++) + { + figure->AddPosForNewDiagram(); + } + } + getExistingDiagram(diagramIndex)->add(figure); + modelChanged = true; +} + +void hdDrawingEditor::removeDiagramFigure(int diagramIndex, hdIFigure *figure) +{ + getExistingDiagram(diagramIndex)->remove(figure); + modelChanged = true; +} + +bool hdDrawingEditor::modelIncludes(hdIFigure *figure) +{ + if(_model) + return _model->existsObject(figure); + return false; +} + +int hdDrawingEditor::modelCount() +{ + if(_model) + return _diagrams->count(); + return 0; +} + +hdIteratorBase *hdDrawingEditor::modelFiguresEnumerator() +{ + return _model->createIterator(); +} + +hdIteratorBase *hdDrawingEditor::diagramsEnumerator() +{ + return _diagrams->createIterator(); +} + +void hdDrawingEditor::removeAllDiagramsFigures() +{ + int i, size = modelCount(); + + for(i = 0; i < size ; i++) + { + getExistingDiagram(i)->removeAllFigures(); + } + modelChanged = true; +} + +void hdDrawingEditor::deleteAllModelFigures() +{ + removeAllDiagramsFigures(); + hdIFigure *tmp; + while(_model->count() > 0) + { + tmp = (hdIFigure *) _model->getItemAt(0); + _model->removeItemAt(0); + delete tmp; + } + modelChanged = true; +} + +void hdDrawingEditor::remOrDelSelFigures(int diagramIndex) +{ + int answer; + hdIFigure *tmp; + + if (getExistingDiagram(diagramIndex)->countSelectedFigures() == 1) + { + tmp = (hdIFigure *) getExistingDiagram(diagramIndex)->selectedFigures()->getItemAt(0); + answer = wxMessageBox(_("Are you sure you wish to delete figure ?"), _("Delete figures?"), wxYES_NO | wxNO_DEFAULT); + } + else if (getExistingDiagram(diagramIndex)->countSelectedFigures() > 1) + { + answer = wxMessageBox( + wxString::Format(_("Are you sure you wish to delete %d figures?"), getExistingDiagram(diagramIndex)->countSelectedFigures()), + _("Delete figures?"), wxYES_NO | wxNO_DEFAULT); + } + + if (answer == wxYES) + { + while(getExistingDiagram(diagramIndex)->countSelectedFigures() > 0) + { + getExistingDiagram(diagramIndex)->removeFromSelection(tmp); + getExistingDiagram(diagramIndex)->remove(tmp); + if(tmp) + delete tmp; + } + getExistingDiagram(diagramIndex)->clearSelection(); //reset selection to zero items + modelChanged = true; + } +} + +void hdDrawingEditor::changeDefaultFiguresFont() +{ + *hdFontAttribute::defaultFont = settings->GetDDFont(); +} + +bool hdDrawingEditor::modelHasChanged() +{ + return modelChanged; +} + +void hdDrawingEditor::notifyChanged() +{ + modelChanged = true; +} diff --git a/hotdraw/main/hdDrawingView.cpp b/hotdraw/main/hdDrawingView.cpp new file mode 100644 index 0000000..921fd6a --- /dev/null +++ b/hotdraw/main/hdDrawingView.cpp @@ -0,0 +1,473 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdDrawingView.cpp - Main canvas where all figures are drawn +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "hotdraw/main/hdDrawingView.h" +#include "hotdraw/utilities/hdArrayCollection.h" +#include "hotdraw/main/hdDrawingEditor.h" +#include "hotdraw/utilities/hdGeometry.h" +#include "hotdraw/utilities/hdMouseEvent.h" +#include "hotdraw/tools/hdCanvasMenuTool.h" +#include "hotdraw/figures/defaultAttributes/hdFontAttribute.h" +#include "hotdraw/tools/hdSelectionTool.h" + +// Images +#include "images/check.pngc" +#include "images/ddcancel.pngc" + +BEGIN_EVENT_TABLE(hdDrawingView, wxScrolledWindow) + EVT_PAINT( hdDrawingView::onPaint) + EVT_MOTION( hdDrawingView::onMotion) + EVT_RIGHT_DOWN( hdDrawingView::onMouseDown) + EVT_RIGHT_UP( hdDrawingView::onMouseUp) + EVT_LEFT_DOWN( hdDrawingView::onMouseDown) + EVT_LEFT_DCLICK( hdDrawingView::onMouseDown) + EVT_LEFT_UP( hdDrawingView::onMouseUp) + EVT_ERASE_BACKGROUND( hdDrawingView::onEraseBackGround) //This erase flicker + EVT_TEXT(CTL_TEXTTOOLID, hdDrawingView::simpleTextToolChangeHandler) + EVT_BUTTON(CTL_OKBUTTONID, hdDrawingView::OnOkTxtButton) + EVT_BUTTON(CTL_CANCELBUTTONID, hdDrawingView::OnCancelTxtButton) + EVT_KEY_DOWN( hdDrawingView::onKeyDown) + EVT_KEY_UP( hdDrawingView::onKeyUp) +END_EVENT_TABLE() + + +hdDrawingView::hdDrawingView(int diagram, wxWindow *ddParent, hdDrawingEditor *editor, wxSize size, hdDrawing *initialDrawing)// gqbController *controller, gqbModel *model) + : wxScrolledWindow(ddParent, wxID_ANY, wxPoint(0, 0), size, + wxHSCROLL | wxVSCROLL | wxBORDER | wxRETAINED) +{ + diagramIndex = diagram; + drawing = initialDrawing; + drawingEditor = editor; + canvasSize = size; + +#if wxCHECK_VERSION(2, 9, 0) + FitInside(); +#else + SetVirtualSizeHints(canvasSize); +#endif + + // Hack to avoid selection rectangle drawing bug + drawSelRect = false; + // Hack to avoid event problem with simpleTextTool wxTextCrtl at EVT_TEXT event + simpleTextToolEdit = new wxTextCtrl(this, CTL_TEXTTOOLID, wxT(""), wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); + simpleTextToolEdit->Hide(); + simpleTextFigure = NULL; + menuFigure = NULL; + okTxtButton = new wxBitmapButton(this, CTL_OKBUTTONID, *check_png_bmp, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); + okTxtButton->Hide(); + cancelTxtButton = new wxBitmapButton(this, 1981, wxBitmap(*ddcancel_png_img), wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); + cancelTxtButton->Hide(); + canvasMenu = NULL; + _tool = NULL; + _tool = new hdSelectionTool(this); +} + +hdDrawingView::~hdDrawingView() +{ + if(simpleTextToolEdit) + delete simpleTextToolEdit; + if(okTxtButton) + delete okTxtButton; + if(cancelTxtButton) + delete cancelTxtButton; + if(_tool) + delete _tool; +} + +void hdDrawingView::onPaint(wxPaintEvent &event) +{ + // Prepare Context for Buffered Draw + wxPaintDC dcc(this); + wxBufferedDC dc(&dcc, canvasSize); + dc.Clear(); + hdIFigure *toDraw = NULL; + hdIteratorBase *iterator = drawing->figuresEnumerator(); + + while(iterator->HasNext()) + { + toDraw = (hdIFigure *)iterator->Next(); + if(toDraw->isSelected(diagramIndex)) + toDraw->drawSelected(dc, this); + else + toDraw->draw(dc, this); + } + + delete iterator; + + hdIHandle *tmpHandle = NULL; + hdIteratorBase *selectionIterator = drawing->selectionFigures();//selection->createIterator(); + while(selectionIterator->HasNext()) + { + toDraw = (hdIFigure *)selectionIterator->Next(); + hdIteratorBase *handlesIterator = toDraw->handlesEnumerator()->createIterator(); + while(handlesIterator->HasNext()) + { + tmpHandle = (hdIHandle *)handlesIterator->Next(); + tmpHandle->draw(dc, this); + } + delete handlesIterator; + } + + delete selectionIterator; + + //Hack to avoid selection rectangle drawing bug + if (drawSelRect) + { + wxPen *pen = wxThePenList->FindOrCreatePen(*wxRED, 1, wxDOT); + dc.SetPen(*pen); + wxBrush *brush = wxTheBrushList->FindOrCreateBrush(*wxRED, wxTRANSPARENT); + dc.SetBackground(*brush); + dc.SetBackgroundMode(wxTRANSPARENT); + //Adjust points before drawing + wxPoint selAjustedPoints[5]; + CalcScrolledPosition(selPoints[0].x, selPoints[0].y, &selAjustedPoints[0].x, &selAjustedPoints[0].y); + CalcScrolledPosition(selPoints[1].x, selPoints[1].y, &selAjustedPoints[1].x, &selAjustedPoints[1].y); + CalcScrolledPosition(selPoints[2].x, selPoints[2].y, &selAjustedPoints[2].x, &selAjustedPoints[2].y); + CalcScrolledPosition(selPoints[3].x, selPoints[3].y, &selAjustedPoints[3].x, &selAjustedPoints[3].y); + CalcScrolledPosition(selPoints[4].x, selPoints[4].y, &selAjustedPoints[4].x, &selAjustedPoints[4].y); + //Draw + dc.DrawLines(5, selAjustedPoints, 0, 0); + drawSelRect = false; + } +} + +//Hack to avoid selection rectangle drawing bug +void hdDrawingView::disableSelRectDraw() +{ + drawSelRect = false; +} + +//Hack to avoid selection rectangle drawing bug +void hdDrawingView::setSelRect(hdRect &selectionRect) +{ + //Create rectangle lines to avoid non transparent brush for filling bug in wxwidgets + selPoints[0].x = selectionRect.x; + selPoints[0].y = selectionRect.y; + selPoints[1].x = selectionRect.x + selectionRect.width; + selPoints[1].y = selectionRect.y; + selPoints[2].x = selectionRect.x + selectionRect.width; + selPoints[2].y = selectionRect.y + selectionRect.height; + selPoints[3].x = selectionRect.x; + selPoints[3].y = selectionRect.y + selectionRect.height; + selPoints[4].x = selectionRect.x; + selPoints[4].y = selectionRect.y; + drawSelRect = true; +} + +// Overwrite and disable onEraseBackground Event to avoid Flicker +void hdDrawingView::onEraseBackGround(wxEraseEvent &event) +{ +} + +hdMultiPosRect hdDrawingView::getVisibleArea() +{ + int x, y, w, h; + GetViewStart(&x, &y); + GetClientSize(&w, &h); + hdMultiPosRect visibleArea(x, y, w, h); + return visibleArea; +} + +hdMultiPosRect hdDrawingView::getVirtualSize() +{ + int w, h; + GetVirtualSize(&w, &h); + hdMultiPosRect virtualSize(0, 0, w, h); + return virtualSize; +} + +void hdDrawingView::ScrollToMakeVisible(hdPoint p) +{ + //implement this function +} + +void hdDrawingView::ScrollToMakeVisible (hdRect r) +{ + //implement this function +} + +hdIHandle *hdDrawingView::findHandle(int posIdx, double x, double y) +{ + hdIFigure *tmpFigure = NULL; + hdIHandle *tmpHandle = NULL, *out = NULL; + + + //Look for handles at each figure in SelectionEnumerator + hdIteratorBase *selectionIterator = drawing->selectionFigures(); //selection->createIterator(); + while(selectionIterator->HasNext()) + { + tmpFigure = (hdIFigure *)selectionIterator->Next(); + hdIteratorBase *handlesIterator = tmpFigure->handlesEnumerator()->createIterator(); + while(handlesIterator->HasNext()) + { + tmpHandle = (hdIHandle *)handlesIterator->Next(); + if(tmpHandle->containsPoint(posIdx, x, y)) + { + out = tmpHandle; + break; + } + } + delete handlesIterator; + } + delete selectionIterator; + return out; +} + +hdDrawing *hdDrawingView::getDrawing() +{ + return drawing; +} + +void hdDrawingView::onMotion(wxMouseEvent &event) +{ +// simple hack to don't update so frequently the canvas and mouse events +// Should be changed for a better one using time intervals not a simple counter + static int simpleOptimization = 0; + simpleOptimization++; + if(simpleOptimization > 0) + { + simpleOptimization = 0; + + hdMouseEvent ddEvent = hdMouseEvent(event, this); + if(event.Dragging()) + { + _tool->mouseDrag(ddEvent); + this->Refresh(); //only a dragging event on montion will change model + } + else + { + _tool->mouseMove(ddEvent); + } + } +} + +void hdDrawingView::onMouseDown(wxMouseEvent &event) +{ + this->AcceptsFocus(); + this->SetFocus(); + startDrag = event.GetPosition(); + hdMouseEvent ddEvent = hdMouseEvent(event, this); + _tool->mouseDown(ddEvent); + this->Refresh(); +} + +void hdDrawingView::onMouseUp(wxMouseEvent &event) +{ + this->AcceptsFocus(); + this->SetFocus(); + hdMouseEvent ddEvent = hdMouseEvent(event, this); + _tool->mouseUp(ddEvent); + this->Refresh(); +} + +void hdDrawingView::onKeyDown(wxKeyEvent &event) +{ + hdKeyEvent ddEvent = hdKeyEvent(event, this); + _tool->keyDown(ddEvent); + this->Refresh(); +} + +void hdDrawingView::onKeyUp(wxKeyEvent &event) +{ + hdKeyEvent ddEvent = hdKeyEvent(event, this); + _tool->keyUp(ddEvent); + this->Refresh(); +} + +//Hack to avoid event problem with simpleTextTool wxTextCrtl at EVT_TEXT event +void hdDrawingView::setSimpleTextToolFigure(hdSimpleTextFigure *figure, bool onlySetFigure) +{ + simpleTextFigure = figure; + menuFigure = NULL; + if(simpleTextFigure && !onlySetFigure) + { + oldText = simpleTextFigure->getText(); + simpleTextToolEdit->SetValue(simpleTextFigure->getText()); + simpleTextToolEdit->SelectAll(); + } +} + +//Hack to allow use (events) of wxmenu inside a tool Generic Way +void hdDrawingView::setMenuToolFigure(hdAbstractMenuFigure *figure) +{ + menuFigure = figure; + simpleTextFigure = NULL; +} + +//Hack to avoid event problem with simpleTextTool wxTextCrtl at EVT_TEXT event +void hdDrawingView::OnOkTxtButton(wxCommandEvent &event) +{ + _tool->deactivate(this); + simpleTextToolEdit->Hide(); + okTxtButton->Hide(); + cancelTxtButton->Hide(); + setSimpleTextToolFigure(NULL); +} + +//Hack to avoid event problem with simpleTextTool wxTextCrtl at EVT_TEXT event +void hdDrawingView::OnCancelTxtButton(wxCommandEvent &event) +{ + simpleTextToolEdit->SetValue(oldText); + _tool->deactivate(this); + simpleTextToolEdit->Hide(); + okTxtButton->Hide(); + cancelTxtButton->Hide(); + setSimpleTextToolFigure(NULL); +} + +//Hack to avoid event problem with simpleTextTool wxTextCrtl at EVT_TEXT event (when text is set at edit it generate this event not sure ????) +void hdDrawingView::simpleTextToolChangeHandler(wxCommandEvent &event) +{ + if(!simpleTextToolEdit->IsModified() && simpleTextFigure) + { + simpleTextFigure->setText(simpleTextToolEdit->GetValue()); + //getFontMetrics + int width, height; + wxWindowDC dc(this); + dc.SetFont(*hdFontAttribute::defaultFont); + if(simpleTextFigure->getText(true).length() > 5) + dc.GetTextExtent(simpleTextFigure->getText(true), &width, &height); + else + dc.GetTextExtent(wxT("EMPTY"), &width, &height); + //recalculateDisplayBox + hdGeometry g; + simpleTextFigure->displayBox().width = g.max(width, 10) + simpleTextFigure->getPadding(); + simpleTextFigure->displayBox().height = g.max(height, 10) + simpleTextFigure->getPadding(); + //calculateSizeEntry + hdPoint p = simpleTextFigure->displayBox().GetPosition(this->diagramIndex); + CalcScrolledPosition(p.x, p.y, &p.x, &p.y); + simpleTextToolEdit->SetPosition(p); + simpleTextToolEdit->SetSize(simpleTextFigure->displayBox().GetSize()); + okTxtButton->SetPosition(wxPoint(p.x + simpleTextToolEdit->GetSize().GetWidth() + 4, p.y)); + cancelTxtButton->SetPosition(wxPoint(okTxtButton->GetPosition().x + okTxtButton->GetSize().GetWidth() + 4, p.y)); + } + else if(!simpleTextFigure) + { + wxMessageDialog *error = new wxMessageDialog(NULL, wxT("Error locating hdSimpleTextTool figure"), wxT("Error!"), wxOK | wxICON_ERROR); + error->ShowModal(); + delete error; + } + event.Skip(); +} + +//Hack to avoid event problem with simpleTextTool wxTextCrtl at EVT_TEXT event +wxTextCtrl *hdDrawingView::getSimpleTextToolEdit() +{ + return simpleTextToolEdit; +} + +//Hack to avoid event problem with simpleTextTool wxTextCrtl at EVT_TEXT event +wxBitmapButton *hdDrawingView::getOkTxt() +{ + return okTxtButton; +} + +//Hack to avoid event problem with simpleTextTool wxTextCrtl at EVT_TEXT event +wxBitmapButton *hdDrawingView::getCancelTxt() +{ + return cancelTxtButton; +} + +//Hack to allow use (events) of wxmenu inside a tool like simpletexttool +void hdDrawingView::OnGenericPopupClick(wxCommandEvent &event) +{ + + if(canvasMenu) + canvasMenu->OnGenericPopupClick(event, this); + else if(menuFigure) + menuFigure->OnGenericPopupClick(event, this); + else if(simpleTextFigure) + simpleTextFigure->OnGenericPopupClick(event, this); + + simpleTextFigure = NULL; + menuFigure = NULL; + canvasMenu = NULL; + + event.Skip(); +} + +//Hack to allow use (events) of wxmenu inside a tool like simpletexttool +void hdDrawingView::connectPopUpMenu(wxMenu &mnu) +{ + // Connect the main menu + mnu.Connect(wxEVT_COMMAND_MENU_SELECTED, + (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) &hdDrawingView::OnGenericPopupClick, + NULL, + this); + + // Connect all submenus + wxMenuItem *item; + wxMenuItemList list = mnu.GetMenuItems(); + for (unsigned int index = 0; index < list.GetCount(); index++) + { + wxMenuItemList::compatibility_iterator node = list.Item(index); + item = (wxMenuItem *) node->GetData(); + if (item->IsSubMenu()) + { + wxMenu *submenu = item->GetSubMenu(); + submenu->Connect(wxEVT_COMMAND_MENU_SELECTED, + (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) &hdDrawingView::OnGenericPopupClick, + NULL, + this); + } + } +} + +//Hack to allow use (events) of wxmenu inside a tool without a figure, Generic Way +void hdDrawingView::setCanvasMenuTool(hdCanvasMenuTool *menuTool) +{ + canvasMenu = menuTool; +} + +hdDrawingEditor *hdDrawingView::editor() +{ + return drawingEditor; +} + +bool hdDrawingView::AcceptsFocus() const +{ + return true; +} + +void hdDrawingView::setTool(hdITool *tool) +{ + if(_tool) + delete _tool; + _tool = tool; +} + +void hdDrawingView::createViewMenu(wxMenu &mnu) +{ + wxMenuItem *item; + item = mnu.AppendCheckItem(1000, _("Sample Item")); + item->Check(true); +} + +void hdDrawingView::OnGenericViewPopupClick(wxCommandEvent &event) +{ + switch(event.GetId()) + { + case 1000: + wxMessageBox(_("Sample menu item"), _("Sample"), wxOK, this); + } +} + +void hdDrawingView::notifyChanged() +{ + drawingEditor->notifyChanged(); +} diff --git a/hotdraw/main/module.mk b/hotdraw/main/module.mk new file mode 100644 index 0000000..40de330 --- /dev/null +++ b/hotdraw/main/module.mk @@ -0,0 +1,18 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/hotdraw/main/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + hotdraw/main/hdDrawing.cpp \ + hotdraw/main/hdDrawingEditor.cpp \ + hotdraw/main/hdDrawingView.cpp + +EXTRA_DIST += \ + hotdraw/main/module.mk diff --git a/hotdraw/module.mk b/hotdraw/module.mk new file mode 100644 index 0000000..bcf99f6 --- /dev/null +++ b/hotdraw/module.mk @@ -0,0 +1,21 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/hotdraw/ Makefile fragment +# +####################################################################### + +include hotdraw/connectors/module.mk +include hotdraw/figures/module.mk +include hotdraw/handles/module.mk +include hotdraw/locators/module.mk +include hotdraw/main/module.mk +include hotdraw/tools/module.mk +include hotdraw/utilities/module.mk + +EXTRA_DIST += \ + hotdraw/module.mk diff --git a/hotdraw/tools/hdAbstractTool.cpp b/hotdraw/tools/hdAbstractTool.cpp new file mode 100644 index 0000000..c6a89e0 --- /dev/null +++ b/hotdraw/tools/hdAbstractTool.cpp @@ -0,0 +1,67 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdAbstractTool.cpp - An abstract tool to allow creation of all tools +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/tools/hdAbstractTool.h" + +hdAbstractTool::hdAbstractTool(hdDrawingView *view) +{ + anchorX = 0; + anchorY = 0; + ownerView = view; +} + +hdAbstractTool::~hdAbstractTool() +{ +} + +void hdAbstractTool::mouseDown(hdMouseEvent &event) +{ + setAnchorCoords(event.GetPosition().x, event.GetPosition().y); +} + +void hdAbstractTool::mouseUp(hdMouseEvent &event) +{ +} + +void hdAbstractTool::mouseMove(hdMouseEvent &event) +{ +} + +void hdAbstractTool::mouseDrag(hdMouseEvent &event) +{ +} + +void hdAbstractTool::keyDown(hdKeyEvent &event) +{ +// setAnchorCoords(event.GetPosition().x,event.GetPosition().y); +} + +void hdAbstractTool::keyUp(hdKeyEvent &event) +{ +} + +void hdAbstractTool::setAnchorCoords(int x, int y) +{ + anchorX = x; + anchorY = y; +} + +hdDrawingView *hdAbstractTool::getDrawingView() +{ + return ownerView; +} + diff --git a/hotdraw/tools/hdCanvasMenuTool.cpp b/hotdraw/tools/hdCanvasMenuTool.cpp new file mode 100644 index 0000000..826ef8b --- /dev/null +++ b/hotdraw/tools/hdCanvasMenuTool.cpp @@ -0,0 +1,82 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdCanvasMenuTool.cpp - Allow to set up a menu at main canvas in case of not finding a tool or handle that manages an event +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "hotdraw/tools/hdCanvasMenuTool.h" + +class hdDrawingEditor; + +hdCanvasMenuTool::hdCanvasMenuTool(hdDrawingView *view, hdITool *dt): + hdAbstractTool(view) +{ + defaultTool = dt; + ownerView->setCanvasMenuTool(NULL); +} + +hdCanvasMenuTool::~hdCanvasMenuTool() +{ + ownerView->setCanvasMenuTool(NULL); + if(defaultTool) + delete defaultTool; +} + +void hdCanvasMenuTool::mouseDown(hdMouseEvent &event) +{ + //Linux hack for bug + int x = event.GetPosition().x, y = event.GetPosition().y; + setAnchorCoords(x, y); + + if(event.RightDown()) + { + wxMenu menu; + event.getView()->setCanvasMenuTool(this); + createViewMenu(event.getView(), menu); + event.getView()->connectPopUpMenu(menu); + hdPoint p = event.GetPosition(); + event.getView()->CalcScrolledPosition(p.x, p.y, &p.x, &p.y); + event.getView()->PopupMenu(&menu, p); + return; + } + + defaultTool->mouseDown(event); +} + +void hdCanvasMenuTool::mouseDrag(hdMouseEvent &event) +{ + defaultTool->mouseDrag(event); +} + +void hdCanvasMenuTool::mouseUp(hdMouseEvent &event) +{ + defaultTool->mouseUp(event); +} + +void hdCanvasMenuTool::mouseMove(hdMouseEvent &event) +{ + defaultTool->mouseMove(event); +} + +void hdCanvasMenuTool::createViewMenu(hdDrawingView *view, wxMenu &mnu) +{ + view->createViewMenu(mnu); +} + +void hdCanvasMenuTool::OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view) +{ + view->OnGenericViewPopupClick(event); +} diff --git a/hotdraw/tools/hdCompositeFigureTool.cpp b/hotdraw/tools/hdCompositeFigureTool.cpp new file mode 100644 index 0000000..3c39b59 --- /dev/null +++ b/hotdraw/tools/hdCompositeFigureTool.cpp @@ -0,0 +1,121 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdCompositeFigureTool.cpp - A Tool that allow to change between all tools in a composite figure +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/tools/hdCompositeFigureTool.h" +#include "hotdraw/figures/hdCompositeFigure.h" + + +hdCompositeFigureTool::hdCompositeFigureTool(hdDrawingView *view, hdIFigure *fig, hdITool *dt): + hdFigureTool(view, fig, dt) +{ + delegateTool = NULL; +} + +hdCompositeFigureTool::~hdCompositeFigureTool() +{ + hdITool *tmpDefault = hdFigureTool::getDefaultTool(); + hdFigureTool *tmpDelegateDefault; + + if(delegateTool->ms_classInfo.IsKindOf(&hdFigureTool::ms_classInfo)) + tmpDelegateDefault = (hdFigureTool *)delegateTool; + else + tmpDelegateDefault = NULL; + + if(delegateTool && delegateTool != tmpDefault) + { + // Hack to avoid delete defaultTool (Delegate->defaultTool) of delegate tool + // if this is the same as defaultTool (this->defaultTool) of this Object. + if(tmpDelegateDefault && tmpDelegateDefault->getDefaultTool() == tmpDefault) + tmpDelegateDefault->setDefaultTool(NULL); + delete delegateTool; + } +} + +void hdCompositeFigureTool::setDefaultTool(hdITool *dt) +{ + hdFigureTool::setDefaultTool(dt); +} + +hdITool *hdCompositeFigureTool::getDefaultTool() +{ + if(delegateTool) + { + return delegateTool; + } + else + { + return hdFigureTool::getDefaultTool(); + } +} + +void hdCompositeFigureTool::mouseDown(hdMouseEvent &event) +{ + int x = event.GetPosition().x, y = event.GetPosition().y; + hdCompositeFigure *cfigure = (hdCompositeFigure *) getFigure(); + hdIFigure *figure = cfigure->findFigure(event.getView()->getIdx(), x, y); + + if(figure) + { + setDelegateTool(event.getView(), figure->CreateFigureTool(event.getView(), getDefaultTool())); + } + else + { + setDelegateTool(event.getView(), getDefaultTool()); + } + + if(delegateTool) + { + delegateTool->mouseDown(event); + } +} + +void hdCompositeFigureTool::activate(hdDrawingView *view) +{ + if(delegateTool) + { + delegateTool->activate(view); + } +} + +void hdCompositeFigureTool::deactivate(hdDrawingView *view) +{ + if(delegateTool) + { + delegateTool->deactivate(view); + } +} + +void hdCompositeFigureTool::setDelegateTool(hdDrawingView *view, hdITool *tool) +{ + if(delegateTool) + { + delegateTool->deactivate(view); + delete delegateTool; + delegateTool = NULL; + } + + delegateTool = tool; + if(delegateTool) + { + delegateTool->activate(view); + } +} + +hdITool *hdCompositeFigureTool::getDelegateTool() +{ + return delegateTool; +} diff --git a/hotdraw/tools/hdConnectionCreationTool.cpp b/hotdraw/tools/hdConnectionCreationTool.cpp new file mode 100644 index 0000000..ceb749f --- /dev/null +++ b/hotdraw/tools/hdConnectionCreationTool.cpp @@ -0,0 +1,140 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdConnectionCreationTool.cpp - A Tool that allow to create a connection figure between two figures +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/tools/hdConnectionCreationTool.h" +#include "hotdraw/tools/hdSelectionTool.h" +#include "hotdraw/main/hdDrawingView.h" + +hdConnectionCreationTool::hdConnectionCreationTool(hdDrawingView *view, hdLineConnection *figure): + hdAbstractTool(view) +{ + toolConnection = figure; + toolConnection->disconnectStart(); + toolConnection->disconnectEnd(); + handle = NULL; + numClicks = 0; + dragged = false; +} + +hdConnectionCreationTool::~hdConnectionCreationTool() +{ +} + +void hdConnectionCreationTool::mouseDrag(hdMouseEvent &event) +{ + if(handle && event.LeftIsDown()) + { + dragged = true; + handle->invokeStep(event, event.getView()); + } +} + +void hdConnectionCreationTool::mouseDown(hdMouseEvent &event) +{ + hdAbstractTool::mouseDown(event); + if(event.LeftDown()) + { + numClicks++; + int x = event.getScrolledPosX(), y = event.getScrolledPosY(); + hdDrawingView *view = event.getView(); + hdIFigure *figure = view->getDrawing()->findFigure(view->getIdx(), x, y); + + if(figure) + { + if(numClicks == 1) //first mouse click to select start/end figure + { + toolConnection->setEndPoint(view->getIdx(), hdPoint(x, y)); + toolConnection->setStartPoint(view->getIdx(), hdPoint(x, y)); + toolConnection->connectStart(figure->connectorAt(view->getIdx(), x, y)); + toolConnection->updateConnection(view->getIdx()); + view->editor()->addDiagramFigure(view->getIdx(), toolConnection); + view->getDrawing()->clearSelection(); + view->getDrawing()->addToSelection(toolConnection); + handle = toolConnection->getEndHandle(); + } + else if(numClicks > 1) //second mouse click to select end figure only + { + toolConnection->setEndPoint(view->getIdx(), hdPoint(x, y)); + toolConnection->updateConnection(event.getView()->getIdx()); + } + } + else + { + event.getView()->setTool(new hdSelectionTool(event.getView())); + } + } +} + +void hdConnectionCreationTool::mouseUp(hdMouseEvent &event) +{ + if(event.LeftUp()) + { + //Hack to allow one click and drag creation of connections + if(handle) + { + if(!dragged && numClicks == 1) //mouse haven't be dragged and is first click of mouse at this tool + { + toolConnection->setEndPoint(event.getView()->getIdx(), event.GetPosition()); + toolConnection->updateConnection(event.getView()->getIdx()); + } + else + { + handle->invokeEnd(event, event.getView()); + } + } + + if((toolConnection->getEndConnector() == NULL && numClicks > 1) || (toolConnection->getEndConnector() == NULL && dragged)) //Delete connection only if a second click a connection figures isn't found + { + //check if exists at drawing because automatically integrity check + if(event.getView()->getDrawing()->includes(toolConnection)) + event.getView()->getDrawing()->remove(toolConnection); + event.getView()->getDrawing()->clearSelection(); + toolConnection->disconnectStart(); + toolConnection->disconnectEnd(); + event.getView()->editor()->deleteModelFigure(toolConnection); + } + } + if(dragged || numClicks > 1) //if drag to select a figure or is second or higher click (to select end figure) then this tool ends. + { + event.getView()->setTool(new hdSelectionTool(event.getView())); + } + else if(!dragged && numClicks == 1) //if not dragged before and is first click then allow to select end, disconnecting it + { + toolConnection->disconnectEnd(); + } + +} + +void hdConnectionCreationTool::mouseMove(hdMouseEvent &event) +{ + int x = event.GetPosition().x, y = event.GetPosition().y; + hdDrawingView *view = event.getView(); + hdIFigure *figure = view->getDrawing()->findFigure(view->getIdx(), x, y); + if(figure) + { + view->SetCursor(wxCursor(wxCURSOR_PENCIL)); + } + else + { + view->SetCursor(wxCursor(wxCURSOR_CROSS)); + } + + if(toolConnection && handle && numClicks > 0) + { + handle->invokeStep(event, view); + } +} diff --git a/hotdraw/tools/hdCreationTool.cpp b/hotdraw/tools/hdCreationTool.cpp new file mode 100644 index 0000000..31f5020 --- /dev/null +++ b/hotdraw/tools/hdCreationTool.cpp @@ -0,0 +1,70 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdCreationTool.cpp - A Tool that create a figure by just click on view +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/tools/hdCreationTool.h" +#include "hotdraw/tools/hdSelectionTool.h" + +hdCreationTool::hdCreationTool(hdDrawingView *view, hdIFigure *prototype): + hdAbstractTool(view) +{ + figurePrototype = prototype; +} + +hdCreationTool::~hdCreationTool() +{ +} + +void hdCreationTool::mouseDown(hdMouseEvent &event) +{ + hdAbstractTool::mouseDown(event); + if(event.LeftDown()) + { + event.getView()->getDrawing()->add(figurePrototype); + int x = event.GetPosition().x, y = event.GetPosition().y; + figurePrototype->moveTo(event.getView()->getIdx(), x, y); + event.getView()->getDrawing()->clearSelection(); + event.getView()->getDrawing()->addToSelection(figurePrototype); + } +} + +void hdCreationTool::mouseUp(hdMouseEvent &event) +{ + hdAbstractTool::mouseUp(event); + event.getView()->setTool(new hdSelectionTool(event.getView())); +} + +void hdCreationTool::activate(hdDrawingView *view) +{ + hdAbstractTool::activate(view); + view->SetCursor(wxCursor(wxCURSOR_CROSS)); +} + +void hdCreationTool::deactivate(hdDrawingView *view) +{ + hdAbstractTool::deactivate(view); + view->SetCursor(wxCursor(wxCURSOR_ARROW)); +} + +void hdCreationTool::setPrototype(hdIFigure *prototype) +{ + figurePrototype = prototype; +} + +hdIFigure *hdCreationTool::getPrototype() +{ + return figurePrototype; +} diff --git a/hotdraw/tools/hdDragCreationTool.cpp b/hotdraw/tools/hdDragCreationTool.cpp new file mode 100644 index 0000000..c15afe3 --- /dev/null +++ b/hotdraw/tools/hdDragCreationTool.cpp @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdDragCreationTool.cpp - A Tool that allow to move figure around view +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/tools/hdDragCreationTool.h" + +hdDragCreationTool::hdDragCreationTool(hdDrawingView *view, hdIFigure *prototype): + hdCreationTool(view, prototype) +{ +} + +hdDragCreationTool::~hdDragCreationTool() +{ +} + + +void hdDragCreationTool::mouseDrag(hdMouseEvent &event) +{ + if(event.LeftIsDown()) + { + figurePrototype->displayBox().SetPosition(event.getView()->getIdx(), event.GetPosition()); + } +} diff --git a/hotdraw/tools/hdDragTrackerTool.cpp b/hotdraw/tools/hdDragTrackerTool.cpp new file mode 100644 index 0000000..b8c3722 --- /dev/null +++ b/hotdraw/tools/hdDragTrackerTool.cpp @@ -0,0 +1,101 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdDragTrackerTool.cpp - A Tool that allow to drag and drop figures at the view +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/tools/hdDragTrackerTool.h" +#include "hotdraw/tools/hdAbstractTool.h" + +hdDragTrackerTool::hdDragTrackerTool(hdDrawingView *view, hdIFigure *anchor) + : hdAbstractTool(view) +{ + hasMovedValue = false; + anchorFigure = anchor; +} + +hdDragTrackerTool::~hdDragTrackerTool() +{ +} + +void hdDragTrackerTool::setLastCoords(int x, int y) +{ + lastX = x; + lastY = y; +} + +void hdDragTrackerTool::mouseDown(hdMouseEvent &event) +{ + hdAbstractTool::mouseDown(event); + + if(event.LeftDown()) + { + int x = event.GetPosition().x, y = event.GetPosition().y; + + setLastCoords(x, y); + + if(event.m_shiftDown) + { + event.getView()->getDrawing()->toggleSelection(anchorFigure); + } + else if(!event.getView()->getDrawing()->isFigureSelected(anchorFigure)) + { + event.getView()->getDrawing()->clearSelection(); + event.getView()->getDrawing()->addToSelection(anchorFigure); + } + } +} + +void hdDragTrackerTool::mouseUp(hdMouseEvent &event) +{ + hdAbstractTool::mouseUp(event); +} + +void hdDragTrackerTool::mouseDrag(hdMouseEvent &event) +{ + hdAbstractTool::mouseDrag(event); + + if(event.LeftIsDown()) + { + int x = event.GetPosition().x, y = event.GetPosition().y; + + //Hack to avoid a weird bug that ocurrs when use double click very fast over figure and drag a same time, lastX + //and lastY values becomes big negatives numbers, if this happens, then reset it to click point + if(lastX < 0) + lastX = x; + if(lastY < 0) + lastY = y; + + hasMovedValue = (abs (x - anchorX) > 4 || abs (y - anchorX) > 4); + + if (hasMoved()) + { + hdIFigure *tmp = NULL; + hdIteratorBase *iterator = event.getView()->getDrawing()->selectionFigures(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + tmp->moveBy(event.getView()->getIdx(), x - lastX, y - lastY); + event.getView()->notifyChanged(); + } + delete iterator; + } + setLastCoords (x, y); + } +} + +bool hdDragTrackerTool::hasMoved() +{ + return hasMovedValue; +} diff --git a/hotdraw/tools/hdFigureTool.cpp b/hotdraw/tools/hdFigureTool.cpp new file mode 100644 index 0000000..73c0adf --- /dev/null +++ b/hotdraw/tools/hdFigureTool.cpp @@ -0,0 +1,101 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdFigureTool.cpp - Base class for all figure tools +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/tools/hdFigureTool.h" + +hdFigureTool::hdFigureTool(hdDrawingView *view, hdIFigure *fig, hdITool *dt): + hdAbstractTool(view) +{ + defaultTool = dt; + figure = fig; +} + +hdFigureTool::~hdFigureTool() +{ + if(defaultTool) + { + delete defaultTool; + } +} + +void hdFigureTool::setDefaultTool(hdITool *dt) +{ + defaultTool = dt; +} + +hdITool *hdFigureTool::getDefaultTool() +{ + return defaultTool; +} + +void hdFigureTool::setFigure(hdIFigure *fig) +{ + figure = fig; +} + +hdIFigure *hdFigureTool::getFigure() +{ + return figure; +} + +void hdFigureTool::mouseDown(hdMouseEvent &event) +{ + if(defaultTool) + { + defaultTool->mouseDown(event); + } +} + +void hdFigureTool::mouseUp(hdMouseEvent &event) +{ + if(defaultTool) + { + defaultTool->mouseUp(event); + } +} + +void hdFigureTool::mouseMove(hdMouseEvent &event) +{ + if(defaultTool) + { + defaultTool->mouseMove(event); + } +} + +void hdFigureTool::mouseDrag(hdMouseEvent &event) +{ + if(defaultTool) + { + defaultTool->mouseDrag(event); + } +} + +void hdFigureTool::keyDown(hdKeyEvent &event) +{ + if(defaultTool) + { + defaultTool->keyDown(event); + } +} + +void hdFigureTool::keyUp(hdKeyEvent &event) +{ + if(defaultTool) + { + defaultTool->keyUp(event); + } +} diff --git a/hotdraw/tools/hdHandleTrackerTool.cpp b/hotdraw/tools/hdHandleTrackerTool.cpp new file mode 100644 index 0000000..62d46d3 --- /dev/null +++ b/hotdraw/tools/hdHandleTrackerTool.cpp @@ -0,0 +1,45 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdHandleTrackerTool.cpp - A Tool that allow to use multiple handles +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/tools/hdHandleTrackerTool.h" +#include "hotdraw/tools/hdAbstractTool.h" + +hdHandleTrackerTool::hdHandleTrackerTool(hdDrawingView *view, hdIHandle *anchor) + : hdAbstractTool(view) +{ + anchorHandle = anchor; +} + +hdHandleTrackerTool::~hdHandleTrackerTool() +{ +} + +void hdHandleTrackerTool::mouseDown(hdMouseEvent &event) +{ + hdAbstractTool::mouseDown(event); + anchorHandle->invokeStart(event, event.getView()); +} + +void hdHandleTrackerTool::mouseUp(hdMouseEvent &event) +{ + anchorHandle->invokeEnd(event, event.getView()); +} + +void hdHandleTrackerTool::mouseDrag(hdMouseEvent &event) +{ + anchorHandle->invokeStep(event, event.getView()); +} diff --git a/hotdraw/tools/hdITool.cpp b/hotdraw/tools/hdITool.cpp new file mode 100644 index 0000000..75fff6c --- /dev/null +++ b/hotdraw/tools/hdITool.cpp @@ -0,0 +1,94 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdITool.cpp - Base class for all tools +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/tools/hdITool.h" +#include "hotdraw/utilities/hdMouseEvent.h" + +hdITool::hdITool() +{ + activatedValue = false; + undoableValue = false; +} + +hdITool::~hdITool() +{ +} + +void hdITool::mouseDown(hdMouseEvent &event) +{ + /* + EVT_LEFT_DOWN(func) + EVT_MIDDLE_DOWN(func) + EVT_RIGHT_DOWN(func) + EVT_LEFT_DCLICK(func) + */ +} + +void hdITool::mouseUp(hdMouseEvent &event) +{ + /* + EVT_LEFT_UP(func) + EVT_MIDDLE_UP(func) + EVT_RIGHT_UP(func) + EVT_RIGHT_DCLICK(func) + */ +} + +void hdITool::mouseMove(hdMouseEvent &event) +{ + /* + EVT_MOTION(func) + */ +} + +void hdITool::mouseDrag(hdMouseEvent &event) +{ + /* + When a mouse is dragged this returns true: event.Dragging() + */ +} + +void hdITool::keyDown(hdKeyEvent &event) +{ + /* + setAnchorCoords(event.GetPosition().x,event.GetPosition().y); + */ +} + +void hdITool::keyUp(hdKeyEvent &event) +{ +} + +void hdITool::activate(hdDrawingView *view) +{ + activatedValue = true; +} + +void hdITool::deactivate(hdDrawingView *view) +{ + activatedValue = false; +} + +bool hdITool::activated() +{ + return activatedValue; +} + +bool hdITool::undoable() +{ + return undoableValue; +} diff --git a/hotdraw/tools/hdMenuTool.cpp b/hotdraw/tools/hdMenuTool.cpp new file mode 100644 index 0000000..b139d38 --- /dev/null +++ b/hotdraw/tools/hdMenuTool.cpp @@ -0,0 +1,75 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdMenuTool.cpp - Allow Edition of textTool (double click) or show a menu to modifiy in someway text (right click) a figure. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "hotdraw/tools/hdMenuTool.h" +#include "hotdraw/figures/hdIFigure.h" + +class hdDrawingEditor; + +hdMenuTool::hdMenuTool(hdDrawingView *view, hdIFigure *fig, hdITool *dt): + hdFigureTool(view, fig, dt) +{ + menuFigure = (hdAbstractMenuFigure *) this->getFigure(); + ownerView->setMenuToolFigure(NULL); +} + +hdMenuTool::~hdMenuTool() +{ +} + +void hdMenuTool::mouseDown(hdMouseEvent &event) +{ + //Linux hack for bug + int x = event.GetPosition().x, y = event.GetPosition().y; + setAnchorCoords(x, y); + + if(menuFigure->menuEnabled() && event.RightDown()) + { + wxMenu menu; + event.getView()->setMenuToolFigure(menuFigure); + menuFigure->createMenu(menu); + event.getView()->connectPopUpMenu(menu); + hdPoint p = event.GetPosition(); + event.getView()->CalcScrolledPosition(p.x, p.y, &p.x, &p.y); + event.getView()->PopupMenu(&menu, p); + return; + } + + getDefaultTool()->mouseDown(event); +} + +void hdMenuTool::activate(hdDrawingView *view) +{ + hdFigureTool::activate(view); +} + +void hdMenuTool::deactivate(hdDrawingView *view) +{ + hdFigureTool::deactivate(view); +} + +void hdMenuTool::mouseDrag(hdMouseEvent &event) +{ + getDefaultTool()->mouseDrag(event); +} + +void hdMenuTool::OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view) +{ + menuFigure->OnGenericPopupClick(event, view); +} diff --git a/hotdraw/tools/hdPolyLineFigureTool.cpp b/hotdraw/tools/hdPolyLineFigureTool.cpp new file mode 100644 index 0000000..5f698e9 --- /dev/null +++ b/hotdraw/tools/hdPolyLineFigureTool.cpp @@ -0,0 +1,54 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdPolyLineFigureTool.cpp - Tool to allow creation of flexibility points at polylines figures +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/tools/hdPolyLineFigureTool.h" +#include "hotdraw/tools/hdFigureTool.h" +#include "hotdraw/tools/hdHandleTrackerTool.h" +#include "hotdraw/figures/hdPolyLineFigure.h" +#include "hotdraw/handles/hdIHandle.h" +#include "hotdraw/tools/hdMenuTool.h" + +hdPolyLineFigureTool::hdPolyLineFigureTool(hdDrawingView *view, hdIFigure *fig, hdITool *dt): + hdFigureTool(view, fig, dt) +{ +} + +hdPolyLineFigureTool::~hdPolyLineFigureTool() +{ +} + +void hdPolyLineFigureTool::mouseDown(hdMouseEvent &event) +{ + int x = event.GetPosition().x, y = event.GetPosition().y; + setAnchorCoords(x, y); + //Other events like other mouse button click (no left double click) should be done at handle + //because this tool only add flexibility points to polylines. + if(event.LeftDClick()) + { + hdPolyLineFigure *connection = (hdPolyLineFigure *) figure; + connection->splitSegment(event.getView()->getIdx(), x, y); + event.getView()->getDrawing()->clearSelection(); + event.getView()->getDrawing()->addToSelection(figure); + hdIHandle *handle = event.getView()->findHandle(event.getView()->getIdx(), x, y); + event.getView()->SetCursor(handle->createCursor()); + if(defaultTool) + delete defaultTool; + defaultTool = new hdHandleTrackerTool(event.getView(), handle); + event.getView()->notifyChanged(); + } + defaultTool->mouseDown(event); +} diff --git a/hotdraw/tools/hdSelectAreaTool.cpp b/hotdraw/tools/hdSelectAreaTool.cpp new file mode 100644 index 0000000..c3263cd --- /dev/null +++ b/hotdraw/tools/hdSelectAreaTool.cpp @@ -0,0 +1,123 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdSelectAreaTool.cpp - Tool to allow selection of figures inside a rectangle +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "hotdraw/tools/hdSelectAreaTool.h" +#include "hotdraw/tools/hdAbstractTool.h" +#include "hotdraw/utilities/hdGeometry.h" + + +hdSelectAreaTool::hdSelectAreaTool(hdDrawingView *view) + : hdAbstractTool(view) +{ +} + +hdSelectAreaTool::~hdSelectAreaTool() +{ +} + +void hdSelectAreaTool::mouseDown(hdMouseEvent &event) +{ + hdAbstractTool::mouseDown(event); + if(!event.ShiftDown()) + { + event.getView()->getDrawing()->clearSelection(); + } + if(event.LeftDown()) + { + int x = event.GetPosition().x, y = event.GetPosition().y; + selectionRect.x = x; + selectionRect.y = y; + selectionRect.width = 0; + selectionRect.height = 0; + drawSelectionRect(event.getView()); + } +} + +void hdSelectAreaTool::mouseUp(hdMouseEvent &event) +{ + hdAbstractTool::mouseUp(event); + hdGeometry g; + //hack-fix for bug when selecting figures from right to left + if(event.LeftUp()) + { + if( selectionRect.width < 0 ) + { + int tmp; + tmp = selectionRect.width; + selectionRect.x += tmp; + selectionRect.width = g.ddabs(tmp); + + } + if( selectionRect.height < 0 ) + { + int tmp; + tmp = selectionRect.height; + selectionRect.y += tmp; + selectionRect.height = g.ddabs(tmp); + } + //end hack-fix + drawSelectionRect(event.getView()); + selectFiguresOnRect(event.ShiftDown(), event.getView()); + event.getView()->disableSelRectDraw(); + } +} + +void hdSelectAreaTool::mouseDrag(hdMouseEvent &event) +{ + hdAbstractTool::mouseDrag(event); + if(event.LeftIsDown()) + { + drawSelectionRect(event.getView()); + int x = event.GetPosition().x, y = event.GetPosition().y; + selectionRect.x = anchorX; + selectionRect.y = anchorY; + selectionRect.SetBottomRight(wxPoint(x, y)); + drawSelectionRect(event.getView()); + event.getView()->ScrollToMakeVisible(event.GetPosition()); + } +} + +void hdSelectAreaTool::selectFiguresOnRect(bool shiftPressed, hdDrawingView *view) +{ + hdIFigure *figure; + hdIteratorBase *iterator = view->getDrawing()->figuresInverseEnumerator(); + while(iterator->HasNext()) + { + figure = (hdIFigure *)iterator->Next(); + if(selectionRect.Contains(figure->displayBox().gethdRect(view->getIdx()))) + { + if(shiftPressed) + { + view->getDrawing()->toggleSelection(figure); + } + else + { + view->getDrawing()->addToSelection(figure); + } + } + } + delete iterator; +} + +void hdSelectAreaTool::drawSelectionRect(hdDrawingView *view) +{ + view->setSelRect(selectionRect); +} + diff --git a/hotdraw/tools/hdSelectionTool.cpp b/hotdraw/tools/hdSelectionTool.cpp new file mode 100644 index 0000000..862e164 --- /dev/null +++ b/hotdraw/tools/hdSelectionTool.cpp @@ -0,0 +1,161 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdSelectionTool.cpp - Tool to allow selection of figures +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/tools/hdSelectionTool.h" +#include "hotdraw/tools/hdITool.h" +#include "hotdraw/main/hdDrawingView.h" +#include "hotdraw/main/hdDrawingEditor.h" +#include "hotdraw/tools/hdHandleTrackerTool.h" +#include "hotdraw/tools/hdDragTrackerTool.h" +#include "hotdraw/tools/hdSelectAreaTool.h" +#include "hotdraw/tools/hdCanvasMenuTool.h" + + +class hdDrawingView; +class hdDrawingEditor; + +hdSelectionTool::hdSelectionTool(hdDrawingView *owner): + hdAbstractTool(owner) +{ + _delegateTool = NULL; +} + +hdSelectionTool::~hdSelectionTool() +{ + if(_delegateTool) + delete _delegateTool; +} + +void hdSelectionTool::mouseDown(hdMouseEvent &event) +{ + hdITool::mouseDown(event); + + hdDrawingView *view = event.getView(); + int x = event.GetPosition().x, y = event.GetPosition().y; + + hdIHandle *handle = view->findHandle(view->getIdx(), x, y); + if(handle) + { + setDelegateTool(view, new hdHandleTrackerTool(view, handle)); + } + else + { + hdIFigure *figure = view->getDrawing()->findFigure(view->getIdx(), x, y); + if(figure) + { + view->getDrawing()->bringToFront(figure); + setDelegateTool(event.getView(), figure->CreateFigureTool(view, new hdDragTrackerTool(view, figure))); + } + else + { + setDelegateTool(event.getView(), new hdCanvasMenuTool(view, new hdSelectAreaTool(view)) ); + } + } + + hdITool *delegateTool = getDelegateTool(); + if (delegateTool) + delegateTool->mouseDown(event); +} + +void hdSelectionTool::mouseUp(hdMouseEvent &event) +{ + hdAbstractTool::mouseUp(event); + hdITool *delegateTool = getDelegateTool(); + if (delegateTool) + delegateTool->mouseUp(event); +} + +void hdSelectionTool::mouseMove(hdMouseEvent &event) +{ + hdAbstractTool::mouseMove(event); + hdDrawingView *view = event.getView(); + int x = event.GetPosition().x, y = event.GetPosition().y; + hdIHandle *handle = view->findHandle(view->getIdx(), x, y); + + if(handle) + { + view->SetCursor(handle->createCursor()); + } + else + { + hdIFigure *figure = view->getDrawing()->findFigure(view->getIdx(), x, y); + if(figure) + { + view->SetCursor(wxCursor(wxCURSOR_HAND)); + } + else + { + view->SetCursor(wxCursor(wxCURSOR_ARROW)); + } + } +} + +void hdSelectionTool::mouseDrag(hdMouseEvent &event) +{ + hdAbstractTool::mouseDrag(event); + hdITool *delegateTool = getDelegateTool(); + if (delegateTool) + delegateTool->mouseDrag(event); +} + +void hdSelectionTool::keyDown(hdKeyEvent &event) +{ + if(getDelegateTool()) + { + getDelegateTool()->keyDown(event); + } + if(event.GetKeyCode() == WXK_DELETE) + { + event.getView()->getDrawing()->deleteSelectedFigures(); + } +} + +void hdSelectionTool::keyUp(hdKeyEvent &event) +{ + if(getDelegateTool()) + { + getDelegateTool()->keyUp(event); + } +} + +void hdSelectionTool::setDelegateTool(hdDrawingView *view, hdITool *tool) +{ + if(_delegateTool) + { + _delegateTool->deactivate(view); + delete _delegateTool; + } + + _delegateTool = tool; + + if(_delegateTool) + { + _delegateTool->activate(view); + } +} + +hdITool *hdSelectionTool::getDelegateTool() +{ + return _delegateTool; +} + +void hdSelectionTool::deleteAllFigures(hdDrawingView *view) +{ + view->getDrawing()->clearSelection(); + view->getDrawing()->deleteAllFigures(); +} + diff --git a/hotdraw/tools/hdSimpleTextTool.cpp b/hotdraw/tools/hdSimpleTextTool.cpp new file mode 100644 index 0000000..51256c7 --- /dev/null +++ b/hotdraw/tools/hdSimpleTextTool.cpp @@ -0,0 +1,139 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdSimpleTextTool.cpp - Tool to allow edition of textTool with a double click or show a menu with a right click. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "hotdraw/tools/hdSimpleTextTool.h" +#include "hotdraw/figures/hdSimpleTextFigure.h" + +class hdDrawingEditor; + +hdSimpleTextTool::hdSimpleTextTool(hdDrawingView *view, hdIFigure *fig, hdITool *dt, bool fastEdit , wxString dialogCaption, wxString dialogMessage): + hdFigureTool(view, fig, dt) +{ + dlgMessage = dialogMessage; + dlgCaption = dialogCaption; + withoutDialog = fastEdit; + showEdit = false; + txtFigure = ((hdSimpleTextFigure *)this->getFigure()); + ownerView->setSimpleTextToolFigure(NULL); + + calculateSizeEntry(ownerView); +} + +hdSimpleTextTool::~hdSimpleTextTool() +{ +} + +void hdSimpleTextTool::calculateSizeEntry(hdDrawingView *view) +{ + if(view->getSimpleTextToolEdit()) + { + hdPoint p = txtFigure->displayBox().GetPosition(view->getIdx()); + view->CalcScrolledPosition(p.x, p.y, &p.x, &p.y); + view->getSimpleTextToolEdit()->SetPosition(p); + view->getSimpleTextToolEdit()->SetSize(txtFigure->displayBox().GetSize()); + view->getOkTxt()->SetPosition(wxPoint(p.x + view->getSimpleTextToolEdit()->GetSize().GetWidth() + 4, p.y)); + view->getCancelTxt()->SetPosition(wxPoint(view->getOkTxt()->GetPosition().x + view->getOkTxt()->GetSize().GetWidth() + 4, p.y)); + //Right now implemented with a hack (function at main view), but source of bug, probably can be tracked. + } +} + +void hdSimpleTextTool::mouseDown(hdMouseEvent &event) +{ + setAnchorCoords(event.GetPosition().x, event.GetPosition().y); + + // Right click to get the contextual menu + if(txtFigure->menuEnabled() && event.RightDown()) + { + wxMenu menu; + event.getView()->setSimpleTextToolFigure(txtFigure, true); + txtFigure->createMenu(menu); + event.getView()->connectPopUpMenu(menu); + hdPoint p = event.GetPosition(); + event.getView()->CalcScrolledPosition(p.x, p.y, &p.x, &p.y); + event.getView()->PopupMenu(&menu, p); + return; + } + + // Double click to rename an object + if(event.LeftDClick()) + { + if(withoutDialog) + { + event.getView()->setSimpleTextToolFigure(txtFigure); + showEdit = true; + event.getView()->getSimpleTextToolEdit()->ChangeValue(txtFigure->getText()); //Same as SetValue but don't generated wxEVT_COMMAND_TEXT_UPDATED event + calculateSizeEntry(event.getView()); + event.getView()->getSimpleTextToolEdit()->SetFocus(); + event.getView()->getSimpleTextToolEdit()->Show(); + event.getView()->getOkTxt()->Show(); + event.getView()->getCancelTxt()->Show(); + } + else + { + callDialog(event.getView()); + } + return; + } + getDefaultTool()->mouseDown(event); +} + +void hdSimpleTextTool::activate(hdDrawingView *view) +{ + showEdit = false; + hdFigureTool::activate(view); +} + +void hdSimpleTextTool::deactivate(hdDrawingView *view) +{ + if(view->getSimpleTextToolEdit()) + { + // Can't delete this objects because view is the owner of this objects + view->getSimpleTextToolEdit()->Hide(); + view->getOkTxt()->Hide(); + view->getCancelTxt()->Hide(); + view->setSimpleTextToolFigure(NULL); + } + hdFigureTool::deactivate(view); +} + +void hdSimpleTextTool::mouseDrag(hdMouseEvent &event) +{ + if(!showEdit) + { + getDefaultTool()->mouseDrag(event); + } +} + +void hdSimpleTextTool::OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view) +{ + txtFigure->OnGenericPopupClick(event, view); +} + +bool hdSimpleTextTool::callDialog(hdDrawingView *view) +{ + wxString sNewValue = wxGetTextFromUser(dlgMessage, dlgCaption, txtFigure->getText(), view); + if (!sNewValue.IsEmpty()) + { + txtFigure->setText(sNewValue); + view->notifyChanged(); + return true; + } + else + return false; +} diff --git a/hotdraw/tools/module.mk b/hotdraw/tools/module.mk new file mode 100644 index 0000000..a17914d --- /dev/null +++ b/hotdraw/tools/module.mk @@ -0,0 +1,30 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/hotdraw/tools/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + hotdraw/tools/hdAbstractTool.cpp \ + hotdraw/tools/hdCanvasMenuTool.cpp \ + hotdraw/tools/hdCompositeFigureTool.cpp \ + hotdraw/tools/hdConnectionCreationTool.cpp \ + hotdraw/tools/hdCreationTool.cpp \ + hotdraw/tools/hdDragCreationTool.cpp \ + hotdraw/tools/hdDragTrackerTool.cpp \ + hotdraw/tools/hdFigureTool.cpp \ + hotdraw/tools/hdHandleTrackerTool.cpp \ + hotdraw/tools/hdITool.cpp \ + hotdraw/tools/hdMenuTool.cpp \ + hotdraw/tools/hdPolyLineFigureTool.cpp \ + hotdraw/tools/hdSelectAreaTool.cpp \ + hotdraw/tools/hdSelectionTool.cpp \ + hotdraw/tools/hdSimpleTextTool.cpp + +EXTRA_DIST += \ + hotdraw/tools/module.mk diff --git a/hotdraw/utilities/hdArrayCollection.cpp b/hotdraw/utilities/hdArrayCollection.cpp new file mode 100644 index 0000000..0156a9c --- /dev/null +++ b/hotdraw/utilities/hdArrayCollection.cpp @@ -0,0 +1,221 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdArrayCollection.cpp - Implementation of Collection Using Arrays +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/utilities/hdArrayCollection.h" +#include "hotdraw/main/hdObject.h" + +// Destructor +hdArrayCollection::~hdArrayCollection() +{ + WX_CLEAR_ARRAY(ddArray); +} + +// Add item to array +void hdArrayCollection::addItem(hdObject *item) +{ + ddArray.Add(item); +} + +// Remove item from array but don't delete it. +void hdArrayCollection::removeItem(hdObject *item) +{ + ddArray.Remove(item); +} + +void hdArrayCollection::removeItemAt(int index) +{ + ddArray.RemoveAt(index); +} + +// Create an iterator for the objects inside the array +hdIteratorBase *hdArrayCollection::createIterator() +{ + return (new hdArrayIterator(&ddArray)); +} + +// Create a Down to iterator for the objects inside the array +hdIteratorBase *hdArrayCollection::createDownIterator() +{ + return (new hdArrayDownIterator(&ddArray)); +} + +// Return the number of elements inside the array +int hdArrayCollection::count() +{ + return ddArray.Count(); +} + +// Return true if an element pointer is found inside array +bool hdArrayCollection::existsObject(hdObject *item) +{ + hdObject *found = NULL; + int size = ddArray.GetCount(); + for(int i = 0; i < size; i++) + { + if (ddArray.Item(i) == item) + { + found = ddArray.Item(i); + break; + } + } + return (found != NULL); +} + +// Delete all elements inside array +void hdArrayCollection::deleteAll() +{ + WX_CLEAR_ARRAY(ddArray); +} + +// Removes all elements inside array without deleting +void hdArrayCollection::removeAll() +{ + ddArray.Empty(); +} + +// Get Item at certain position at Collection +hdObject *hdArrayCollection::getItemAt(int index) +{ + if(!ddArray.IsEmpty()) + return ddArray[index]; + else + return NULL; +} + +//Bring item to start of array +void hdArrayCollection::bringToFront(hdObject *item) +{ + hdObject *tmp = ddArray[0]; + int index = getIndex(item); + ddArray[0] = ddArray[index]; + ddArray[index] = tmp; +} + +//Bring item to end of array +void hdArrayCollection::sendToBack(hdObject *item) +{ + int end = count() - 1; + hdObject *tmp = ddArray[end]; + int index = getIndex(item); + ddArray[end] = ddArray[index]; + ddArray[index] = tmp; +} + + +int hdArrayCollection::getIndex(hdObject *item) +{ + return ddArray.Index(item); +} + +// Insert item into the array before the index +void hdArrayCollection::insertAtIndex(hdObject *item, int index) +{ + ddArray.Insert(item, index); +} + +// Replace item into the array at index (if overwrite user should delete manually previous object at index) +void hdArrayCollection::replaceAtIndex(hdObject *item, int index) +{ + ddArray.RemoveAt(index); + ddArray.Insert(item, index); +} + + +// +// hdArrayIterator - Manages iterator for the array collection concrete class, from first to last element +// + + +// Constructor +hdArrayIterator::hdArrayIterator(ddObjsArray *ddPtrsArray) +{ + position = 0; + internalArray = ddPtrsArray; +} + +// Get current item in the array for the iterator +hdObject *hdArrayIterator::Current() +{ + hdObject *obj = internalArray->Item(position); + return obj; +} + +// Get next item in the array for the iterator +hdObject *hdArrayIterator::Next() +{ + hdObject *obj = internalArray->Item(position); + position++; + return obj; +} + +// Return true if the array has more elements to return +bool hdArrayIterator::HasNext() +{ + int size = internalArray->GetCount(); + if( (size > 0) && (position <= (size - 1)) ) + return true; + else + return false; +} + +void hdArrayIterator::ResetIterator() +{ + position = 0; +} + + +// +// hdArrayDownIterator - Manages iterator for the array collection concrete class from last to first element +// + + +// Constructor +hdArrayDownIterator::hdArrayDownIterator(ddObjsArray *ddPtrsArray) +{ + internalArray = ddPtrsArray; + position = internalArray->GetCount() - 1; +} + +// Get current item in the array for the iterator +hdObject *hdArrayDownIterator::Current() +{ + hdObject *obj = internalArray->Item(position); + return obj; +} + +// Get next item in the array for the iterator +hdObject *hdArrayDownIterator::Next() +{ + hdObject *obj = internalArray->Item(position); + position--; + return obj; +} + +// Return true if the array has more elements to return +bool hdArrayDownIterator::HasNext() +{ + int size = internalArray->GetCount(); + if( (size > 0) && (position <= (size - 1) && position >= 0) ) + return true; + else + return false; +} + +void hdArrayDownIterator::ResetIterator() +{ + position = internalArray->GetCount() - 1; +} diff --git a/hotdraw/utilities/hdCollection.cpp b/hotdraw/utilities/hdCollection.cpp new file mode 100644 index 0000000..c6b5bed --- /dev/null +++ b/hotdraw/utilities/hdCollection.cpp @@ -0,0 +1,112 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdCollection.cpp - Generic implementation of a Collection used by dd +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/utilities/hdCollection.h" +#include "hotdraw/main/hdObject.h" + +hdCollection::hdCollection(hdCollectionBase *collectionBase) +{ + collection = collectionBase; +} + +hdCollection::~hdCollection() +{ + if(collection) + delete collection; +} + +void hdCollection::addItem(hdObject *item) +{ + collection->addItem(item); +} + +void hdCollection::removeItem(hdObject *item) +{ + collection->removeItem(item); +} + + +hdIteratorBase *hdCollection::createIterator() +{ + if(collection) + return collection->createIterator(); + return NULL; +} + +hdIteratorBase *hdCollection::createDownIterator() +{ + if(collection) + return collection->createDownIterator(); + return NULL; +} + +int hdCollection::count() +{ + return collection->count(); +} + +bool hdCollection::existsObject(hdObject *item) +{ + return collection->existsObject(item); +} + +hdObject *hdCollection::getItemAt(int index) +{ + return collection->getItemAt(index); +} + +void hdCollection::removeItemAt(int index) +{ + collection->removeItemAt(index); +} + +// Remove all items from collection without deleting each one. +void hdCollection::removeAll() +{ + collection->removeAll(); +} + +void hdCollection::deleteAll() +{ + collection->deleteAll(); +} + +int hdCollection::getIndex(hdObject *item) +{ + return collection->getIndex(item); +} + +void hdCollection::insertAtIndex(hdObject *item, int index) +{ + collection->insertAtIndex(item, index); +} + +void hdCollection::replaceAtIndex(hdObject *item, int index) +{ + collection->replaceAtIndex(item, index); +} + +void hdCollection::bringToFront(hdObject *item) +{ + collection->bringToFront(item); +} + +void hdCollection::sendToBack(hdObject *item) +{ + collection->sendToBack(item); +} diff --git a/hotdraw/utilities/hdGeometry.cpp b/hotdraw/utilities/hdGeometry.cpp new file mode 100644 index 0000000..663b36b --- /dev/null +++ b/hotdraw/utilities/hdGeometry.cpp @@ -0,0 +1,190 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdGeometry.cpp - Utility Geometric Functions Shared between classes +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/utilities/hdGeometry.h" +#include "hotdraw/utilities/hdMultiPosRect.h" +#include "hotdraw/utilities/hdPoint.h" + +// +// Warning when using it: typecasting to avoid miscalculations functions need double values not int +// + +bool hdGeometry::lineContainsPoint(double x1, double y1, double x2, double y2, double px, double py) +{ + hdPoint p = hdPoint(x1, y1); + hdRect r = hdRect(p); + r.add(x2, y2); + r.Inflate(2, 2); + if(!r.Contains(px, py)) + { + return false; + } + + double a, b, x, y; + double val1, val2; + + val1 = px - x1; + if( x1 == x2 ) + { + return (ddabs(val1) < 3); + } + + val2 = py - y1; + if( y1 == y2 ) + { + return (ddabs(val2) < 3); + } + + a = (y1 - y2) / (x1 - x2); + b = y1 - a * x1; + x = (py - b) / a; + y = a * px + b; + + val1 = x - px; + val2 = y - py; + bool out = (min( ddabs(val1), ddabs(val2)) < 4); + return out; +} + +int hdGeometry::min(double a, double b) +{ + return(a <= b) ? a : b; +} + +int hdGeometry::max(double a, double b) +{ + return(a >= b) ? a : b; +} + + +int hdGeometry::min(int a, int b) +{ + return(a <= b) ? a : b; +} + +int hdGeometry::max(int a, int b) +{ + return(a >= b) ? a : b; +} + +//Gets the angle of a point relative to a rectangle. +double hdGeometry::angleFromPoint(int posIdx, hdMultiPosRect r, hdPoint point) +{ + return angleFromPoint(r.gethdRect(posIdx), point); +} + +double hdGeometry::angleFromPoint(hdRect r, hdPoint point) +{ + double rx = point.x - r.center().x; + double ry = point.y - r.center().y; + return atan2 (ry * r.width, rx * r.height); +} + +hdPoint hdGeometry::edgePointFromAngle(int posIdx, hdMultiPosRect r, double angle) +{ + return edgePointFromAngle(r.gethdRect(posIdx), angle); +} + +//Gets the point on a rectangle that corresponds to the given angle. +hdPoint hdGeometry::edgePointFromAngle(hdRect r, double angle) +{ + static hdPoint locationPoint; //Hack to allow bug in linux & ddabs + double sinv = sin(angle); + double cosv = cos(angle); + double e = 0.0001; + double x = 0.0; + double y = 0.0; + double width = r.width; + double height = r.height; + + + if( ddabs(sinv) > e ) + { + x = (1.0 + cosv / ddabs (sinv)) / 2.0 * width; + x = range(0.0, width, x); + } + else if ( cosv >= 0.0 ) + { + x = width; + } + + if ( ddabs(cosv) > e ) + { + y = (1.0 + sinv / ddabs (cosv)) / 2.0 * height; + y = range (0.0, height, y); + } + else if ( sinv >= 0.0 ) + { + y = height; + } + int xx = r.x + x; + int yy = r.y + y; + locationPoint = hdPoint(xx, yy); + return locationPoint; +} + +double hdGeometry::range(double min, double max, double num) +{ + return num < min ? min : (num > max ? max : num); +} + +double hdGeometry::ddabs(double value) +{ + return value < 0 ? (value * -1) : value; +} + +int hdGeometry::ddabs(int value) +{ + return value < 0 ? (value * -1) : value; +} + +double hdGeometry::lineSize (hdPoint p1, hdPoint p2) +{ + int w = p1.x - p2.x; + int h = p1.y - p2.y; + + double perimeter = w * w + h * h; + return sqrt (perimeter); +} + +// source: http://vision.dai.ed.ac.uk/andrewfg/c-g-a-faq.html +// Standard line intersection algorithm, Return true intersection if it exists, else false. +bool hdGeometry::intersection(hdPoint p1, hdPoint p2, hdPoint p3, hdPoint p4) +{ + // Store the values for fast access and easy + // equations-to-code conversion + float x1 = p1.x, x2 = p2.x, x3 = p3.x, x4 = p4.x; + float y1 = p1.y, y2 = p2.y, y3 = p3.y, y4 = p4.y; + + float d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4); + // If d is zero, there is no intersection + if (d == 0) return false; + + // Get the x and y + float pre = (x1 * y2 - y1 * x2), post = (x3 * y4 - y3 * x4); + // point of intersection + float x = ( pre * (x3 - x4) - (x1 - x2) * post ) / d; + float y = ( pre * (y3 - y4) - (y1 - y2) * post ) / d; + + // Check if the x and y coordinates are within both lines + if ( x < min(x1, x2) || x > max(x1, x2) || x < min(x3, x4) || x > max(x3, x4) ) + return false; + if ( y < min(y1, y2) || y > max(y1, y2) || y < min(y3, y4) || y > max(y3, y4) ) + return false; + + return true; +} diff --git a/hotdraw/utilities/hdKeyEvent.cpp b/hotdraw/utilities/hdKeyEvent.cpp new file mode 100644 index 0000000..bd63d0a --- /dev/null +++ b/hotdraw/utilities/hdKeyEvent.cpp @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdKeyEvent.h - Wrapper Class to integrate wxKeyEvent inside library. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/utilities/hdKeyEvent.h" +#include "hotdraw/main/hdDrawingView.h" + +hdKeyEvent::hdKeyEvent(wxKeyEvent &event, hdDrawingView *owner): + keyEvent(event) +{ + view = owner; + keyCode = event.GetKeyCode(); +} + +int hdKeyEvent::GetKeyCode() +{ + return keyCode; +} + +hdDrawingView *hdKeyEvent::getView() +{ + return view; +} diff --git a/hotdraw/utilities/hdMouseEvent.cpp b/hotdraw/utilities/hdMouseEvent.cpp new file mode 100644 index 0000000..1552b5d --- /dev/null +++ b/hotdraw/utilities/hdMouseEvent.cpp @@ -0,0 +1,99 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdMouseEvent.cpp - Wrapper Class to integrate conversion CalcUnscrolledPosition in a mouse event. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/utilities/hdMouseEvent.h" +#include "hotdraw/main/hdDrawingView.h" + +hdMouseEvent::hdMouseEvent(wxMouseEvent &event, hdDrawingView *owner): + mouseEvent(event) +{ + view = owner; + m_shiftDown = event.m_shiftDown; +} + +hdPoint &hdMouseEvent::GetPosition() +{ + return getUnScrolledPosition(); +} + +hdPoint &hdMouseEvent::getUnScrolledPosition() +{ + unScrolled = mouseEvent.GetPosition(); + view->CalcUnscrolledPosition(unScrolled.x, unScrolled.y, &unScrolled.x, &unScrolled.y); + return unScrolled; +} + +hdPoint &hdMouseEvent::getScrolledPosition() +{ + scrolled = mouseEvent.GetPosition(); + return scrolled; +} + +int hdMouseEvent::getScrolledPosX() +{ + return getScrolledPosition().x; +} + +int hdMouseEvent::getScrolledPosY() +{ + return getScrolledPosition().y; +} + +int hdMouseEvent::getUnScrolledPosX() +{ + return getUnScrolledPosition().x; +} + +int hdMouseEvent::getUnScrolledPosY() +{ + return getUnScrolledPosition().y; +} + +bool hdMouseEvent::LeftDClick() +{ + return mouseEvent.LeftDClick(); +} + +bool hdMouseEvent::ShiftDown() +{ + return mouseEvent.ShiftDown(); +} + +bool hdMouseEvent::RightDown() +{ + return mouseEvent.RightDown(); +} + +bool hdMouseEvent::LeftDown() +{ + return mouseEvent.LeftDown(); +} + +bool hdMouseEvent::LeftUp() +{ + return mouseEvent.LeftUp(); +} + +bool hdMouseEvent::LeftIsDown() +{ + return mouseEvent.LeftIsDown(); +} + +hdDrawingView *hdMouseEvent::getView() +{ + return view; +} diff --git a/hotdraw/utilities/hdMultiPosRect.cpp b/hotdraw/utilities/hdMultiPosRect.cpp new file mode 100644 index 0000000..0178e80 --- /dev/null +++ b/hotdraw/utilities/hdMultiPosRect.cpp @@ -0,0 +1,215 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdMultiRect.cpp - hdMultiPosRect improved class with new needed functionalities for allowing multiple displaybox for same figure +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/utilities/hdMultiPosRect.h" +#include "hotdraw/utilities/hdGeometry.h" + +void hdMultiPosRect::init(int valX, int valY) +{ + int i; + for(i = 0; i < MAXPOS; i++) + { + x.Add(valX); + y.Add(valY); + } +} + +hdMultiPosRect::hdMultiPosRect(int posIdx, const wxPoint &topLeft, const wxPoint &bottomRight) +{ + x[posIdx] = topLeft.x; + y[posIdx] = topLeft.y; + width = bottomRight.x - topLeft.x; + height = bottomRight.y - topLeft.y; + + if (width < 0) + { + width = -width; + x[posIdx] = bottomRight.x; + } + width++; + + if (height < 0) + { + height = -height; + y[posIdx] = bottomRight.y; + } + height++; +} + +//simplify this function with SetCount() in a future +void hdMultiPosRect::addNewXYPosition() +{ + x.Add(-1); + y.Add(-1); +} + +void hdMultiPosRect::removeXYPosition(int posIdx) +{ + x.RemoveAt(posIdx); + y.RemoveAt(posIdx); +} + +hdMultiPosRect &hdMultiPosRect::Union(int posIdx, const hdMultiPosRect &rect) +{ + // ignore empty rectangles: union with an empty rectangle shouldn't extend + // this one to (0, 0) + if ( !width || !height ) + { + *this = rect; + } + else if ( rect.width && rect.height ) + { + int x1 = wxMin(x[posIdx], rect.x[posIdx]); + int y1 = wxMin(y[posIdx], rect.y[posIdx]); + int y2 = wxMax(y[posIdx] + height, rect.height + rect.y[posIdx]); + int x2 = wxMax(x[posIdx] + width, rect.width + rect.x[posIdx]); + + x[posIdx] = x1; + y[posIdx] = y1; + width = x2 - x1; + height = y2 - y1; + } + //else: we're not empty and rect is empty + + return *this; +} + +hdMultiPosRect &hdMultiPosRect::Inflate(int posIdx, wxCoord dx, wxCoord dy) +{ + if (-2 * dx > width) + { + // Don't allow deflate to eat more width than we have, + // a well-defined rectangle cannot have negative width. + x[posIdx] += width / 2; + width = 0; + } + else + { + // The inflate is valid. + x[posIdx] -= dx; + width += 2 * dx; + } + + if (-2 * dy > height) + { + // Don't allow deflate to eat more height than we have, + // a well-defined rectangle cannot have negative height. + y[posIdx] += height / 2; + height = 0; + } + else + { + // The inflate is valid. + y[posIdx] -= dy; + height += 2 * dy; + } + + return *this; +} + +bool hdMultiPosRect::Contains(int posIdx, int cx, int cy) const +{ + return ( (cx >= x[posIdx]) && (cy >= y[posIdx]) + && ((cy - y[posIdx]) < height) + && ((cx - x[posIdx]) < width) + ); +} + +bool hdMultiPosRect::Contains(int posIdx, const hdRect &rect) const +{ + return Contains(posIdx, rect.GetTopLeft()) && Contains(posIdx, rect.GetBottomRight()); +} + +hdMultiPosRect &hdMultiPosRect::Intersect(int posIdx, const hdMultiPosRect &rect) +{ + int x2 = GetRight(posIdx), + y2 = GetBottom(posIdx); + + if ( x[posIdx] < rect.x[posIdx] ) + x[posIdx] = rect.x[posIdx]; + if ( y[posIdx] < rect.y[posIdx] ) + y[posIdx] = rect.y[posIdx]; + if ( x2 > rect.GetRight(posIdx) ) + x2 = rect.GetRight(posIdx); + if ( y2 > rect.GetBottom(posIdx) ) + y2 = rect.GetBottom(posIdx); + + width = x2 - x[posIdx] + 1; + height = y2 - y[posIdx] + 1; + + if ( width <= 0 || height <= 0 ) + { + width = + height = 0; + } + + return *this; +} + +bool hdMultiPosRect::Intersects(int posIdx, const hdMultiPosRect &rect) const +{ + hdMultiPosRect r = Intersect(posIdx, rect); + + // if there is no intersection, both width and height are 0 + return r.width != 0; +} + +void hdMultiPosRect::add (int posIdx, int newX, int newY) +{ + int x1 = hdGeometry::min(x[posIdx] , newX); + int x2 = hdGeometry::max(x[posIdx] + width , newX); + int y1 = hdGeometry::min(y[posIdx] , newY); + int y2 = hdGeometry::max(y[posIdx] + height , newY); + + SetX(posIdx, x1); + SetWidth(x2 - x1); + SetY(posIdx, y1); + SetHeight(y2 - y1); +} + + +void hdMultiPosRect::add (int posIdx, hdRect *newRect) +{ + add(posIdx, newRect->GetTopLeft().x , newRect->GetTopLeft().y); + add(posIdx, newRect->GetBottomRight().x , newRect->GetBottomRight().y); +} + +void hdMultiPosRect::add (int posIdx, hdRect newRect) +{ + add(posIdx, newRect.GetTopLeft().x , newRect.GetTopLeft().y); + add(posIdx, newRect.GetBottomRight().x , newRect.GetBottomRight().y); +} + +void hdMultiPosRect::add(int posIdx, hdPoint *p) +{ + add(posIdx, p->x, p->y); +} + + + +hdPoint hdMultiPosRect::center(int posIdx) +{ + point = hdPoint(x[posIdx] + (width / 2) , y[posIdx] + (height / 2)); + return point; +} + +int hdMultiPosRect::CountPositions() +{ + return x.Count(); +} diff --git a/hotdraw/utilities/hdPoint.cpp b/hotdraw/utilities/hdPoint.cpp new file mode 100644 index 0000000..dcfaa4e --- /dev/null +++ b/hotdraw/utilities/hdPoint.cpp @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdPoint.cpp - wxPoint class to be used as wrapper and allow independence of point class +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/utilities/hdPoint.h" + +hdPoint::hdPoint(): + wxPoint() +{ +} + +hdPoint::hdPoint(int x, int y): + wxPoint(x, y) +{ +} + +hdPoint::hdPoint(const hdPoint &p): + wxPoint(p.x, p.y) +{ +} + +hdPoint::hdPoint(const wxPoint &p): + wxPoint(p.x, p.y) +{ +} diff --git a/hotdraw/utilities/hdRect.cpp b/hotdraw/utilities/hdRect.cpp new file mode 100644 index 0000000..c469bab --- /dev/null +++ b/hotdraw/utilities/hdRect.cpp @@ -0,0 +1,83 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdRect.cpp - wxRect improved class with new needed functionalities +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/utilities/hdGeometry.h" + +hdRect::hdRect() +{ +} + +hdRect::hdRect(int xx, int yy, int ww, int hh): + wxRect(xx, yy, ww, hh) +{ +} + +hdRect::hdRect(hdPoint *topLeft, hdPoint *bottomRight): + wxRect(*topLeft, *bottomRight) +{ +} + +hdRect::hdRect(hdPoint *point): + wxRect(point->x, point->y, 0, 0) +{ +} + +hdRect::hdRect(hdPoint &point): + wxRect(point.x, point.y, 0, 0) +{ +} + +void hdRect::add (int newX, int newY) +{ + int x1 = hdGeometry::min(x , newX); + int x2 = hdGeometry::max(x + width , newX); + int y1 = hdGeometry::min(y , newY); + int y2 = hdGeometry::max(y + height , newY); + + SetX(x1); + SetWidth(x2 - x1); + SetY(y1); + SetHeight(y2 - y1); +} + + +void hdRect::add (hdRect *newRect) +{ + add(newRect->GetTopLeft().x , newRect->GetTopLeft().y); + add(newRect->GetBottomRight().x , newRect->GetBottomRight().y); +} + +void hdRect::add (hdRect newRect) +{ + add(newRect.GetTopLeft().x , newRect.GetTopLeft().y); + add(newRect.GetBottomRight().x , newRect.GetBottomRight().y); +} + +void hdRect::add(hdPoint *p) +{ + add(p->x, p->y); +} + + + +hdPoint hdRect::center() +{ + point = hdPoint(x + (width / 2) , y + (height / 2)); + return point; +} + diff --git a/hotdraw/utilities/hdRemoveDeleteDialog.cpp b/hotdraw/utilities/hdRemoveDeleteDialog.cpp new file mode 100644 index 0000000..9bf3c22 --- /dev/null +++ b/hotdraw/utilities/hdRemoveDeleteDialog.cpp @@ -0,0 +1,169 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdRemoveDeleteDialog.cpp - Utility dialog class to allow user to select between delete / remove a figure +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "hotdraw/utilities/hdRemoveDeleteDialog.h" + +IMPLEMENT_CLASS( hdRemoveDeleteDialog, wxDialog ) + +BEGIN_EVENT_TABLE(hdRemoveDeleteDialog, wxDialog) + EVT_BUTTON(DD_REMOVE, hdRemoveDeleteDialog::OnRemove) + EVT_BUTTON(DD_DELETE, hdRemoveDeleteDialog::OnDelete) + EVT_BUTTON(wxID_CANCEL, hdRemoveDeleteDialog::OnCancel) +END_EVENT_TABLE() + +hdRemoveDeleteDialog::hdRemoveDeleteDialog( const wxString &message, + const wxString &caption, + wxWindow *parent, bool allowRemove + ) +{ + allowRemoveButton = allowRemove; + SetFont(settings->GetSystemFont()); + Init(); + Create(parent, wxID_ANY, message, caption); + cancelButton->SetFocus(); +} + +hdRemoveDeleteDialog::~hdRemoveDeleteDialog() +{ + if(staticText) + delete staticText; + if(staticText2) + delete staticText2; + if(staticText3) + delete staticText3; + if(line) + delete line; + if(removeButton) + delete removeButton; + if(deleteButton) + delete deleteButton; + if(cancelButton) + delete cancelButton; +} + +hdRemoveDeleteDialog::hdRemoveDeleteDialog() +{ + Init(); +} + + +void hdRemoveDeleteDialog::Init( ) +{ +} + +// Creation +bool hdRemoveDeleteDialog::Create( wxWindow *parent, + wxWindowID id, + const wxString &caption, + const wxString &message + ) +{ + SetFont(settings->GetSystemFont()); + + if (!wxDialog::Create( parent, id, message, wxDefaultPosition, wxDefaultSize, wxCAPTION)) + return false; + + CreateControls(caption); + + // This fits the dialog to the minimum size dictated by + // the sizers + GetSizer()->Fit(this); + + // This ensures that the dialog cannot be sized smaller + // than the minimum size + GetSizer()->SetSizeHints(this); + + // Centre the dialog on the parent or (if none) screen + + Centre(); + + return true; +} + + +// Creates the controls and sizers +void hdRemoveDeleteDialog::CreateControls(const wxString &message) +{ + // A top-level sizer + topSizer = new wxBoxSizer(wxVERTICAL ); + this->SetSizer(topSizer); + topSizer->AddSpacer(10); + //Message Sizer + messageSizer = new wxBoxSizer(wxHORIZONTAL ); + topSizer->Add(messageSizer); + messageSizer->AddSpacer(25); + + staticText = new wxStaticText(this, wxID_STATIC, message, wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER); + messageSizer->Add(staticText, 0, wxALIGN_CENTER, 5); + + messageSizer->AddSpacer(45); + + // Add important user info + wxString info = _(" Choose Remove from Diagram to remove only from current diagram. "); + wxString info2 = _(" Choose Remove from Model to delete permanently. "); + + this->SetForegroundColour(wxColour(wxT("GREY"))); + staticText2 = new wxStaticText(this, wxID_STATIC, info, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); + topSizer->Add(staticText2, 0, wxALIGN_LEFT, 5); + + staticText3 = new wxStaticText(this, wxID_STATIC, info2, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); + topSizer->Add(staticText3, 0, wxALIGN_LEFT, 5); + + // A space and a dividing line before the Remove Delete and Cancel buttons + topSizer->AddSpacer(10); + line = new wxStaticLine ( this, wxID_STATIC, + wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + topSizer->Add(line, 0, wxGROW | wxALL, 5); + + //Buttons Sizer + buttonsSizer = new wxBoxSizer(wxHORIZONTAL ); + + topSizer->Add(buttonsSizer, 0, wxALIGN_CENTER, 5); + + removeButton = new wxButton ( this, DD_REMOVE, wxT("&Remove from Diagram"), + wxDefaultPosition, wxDefaultSize, 0 ); + + if(!allowRemoveButton) + removeButton->Enable(false); + + buttonsSizer->Add(removeButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); + + deleteButton = new wxButton ( this, DD_DELETE, wxT("&Remove from Model"), + wxDefaultPosition, wxDefaultSize, 0 ); + buttonsSizer->Add(deleteButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); + + cancelButton = new wxButton ( this, wxID_CANCEL, wxT("&Cancel"), + wxDefaultPosition, wxDefaultSize, 0 ); + buttonsSizer->Add(cancelButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); + topSizer->AddSpacer(10); +} + +void hdRemoveDeleteDialog::OnRemove(wxCommandEvent &WXUNUSED(event)) +{ + EndModal( DD_REMOVE ); +} + +void hdRemoveDeleteDialog::OnDelete(wxCommandEvent &WXUNUSED(event)) +{ + EndModal( DD_DELETE ); +} + +void hdRemoveDeleteDialog::OnCancel(wxCommandEvent &WXUNUSED(event)) +{ + EndModal( wxID_CANCEL ); +} diff --git a/hotdraw/utilities/module.mk b/hotdraw/utilities/module.mk new file mode 100644 index 0000000..04244bc --- /dev/null +++ b/hotdraw/utilities/module.mk @@ -0,0 +1,24 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/hotdraw/utilities/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + hotdraw/utilities/hdArrayCollection.cpp \ + hotdraw/utilities/hdCollection.cpp \ + hotdraw/utilities/hdGeometry.cpp \ + hotdraw/utilities/hdKeyEvent.cpp \ + hotdraw/utilities/hdMouseEvent.cpp \ + hotdraw/utilities/hdMultiPosRect.cpp \ + hotdraw/utilities/hdPoint.cpp \ + hotdraw/utilities/hdRect.cpp \ + hotdraw/utilities/hdRemoveDeleteDialog.cpp + +EXTRA_DIST += \ + hotdraw/utilities/module.mk diff --git a/include/.gitignore b/include/.gitignore new file mode 100644 index 0000000..0db0f54 --- /dev/null +++ b/include/.gitignore @@ -0,0 +1,2 @@ +# Global excludes across all subdirectories +svnversion.h diff --git a/include/agent/dlgJob.h b/include/agent/dlgJob.h new file mode 100644 index 0000000..4a9c974 --- /dev/null +++ b/include/agent/dlgJob.h @@ -0,0 +1,61 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgJob.h - Job property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_JOBPROP +#define __DLG_JOBPROP + +#include "dlg/dlgProperty.h" + +class pgaJob; + +class dlgJob : public dlgAgentProperty +{ +public: + dlgJob(pgaFactory *factory, frmMain *frame, pgaJob *j); + + void CheckChange(); + int Go(bool modal); + + wxString GetUpdateSql(); + wxString GetInsertSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pgagent-jobs"); + } + +private: + pgaJob *job; + + wxArrayString previousSteps, previousSchedules; + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnSelChangeStep(wxListEvent &ev); + void OnChangeStep(wxCommandEvent &ev); + void OnAddStep(wxCommandEvent &ev); + void OnRemoveStep(wxCommandEvent &ev); + + void OnSelChangeSchedule(wxListEvent &ev); + void OnChangeSchedule(wxCommandEvent &ev); + void OnAddSchedule(wxCommandEvent &ev); + void OnRemoveSchedule(wxCommandEvent &ev); + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/agent/dlgSchedule.h b/include/agent/dlgSchedule.h new file mode 100644 index 0000000..23b2c98 --- /dev/null +++ b/include/agent/dlgSchedule.h @@ -0,0 +1,92 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgSchedule.h - Job property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_SCHEDULEPROP +#define __DLG_SCHEDULEPROP + +#include "dlg/dlgProperty.h" +#include "ctl/timespin.h" +#include "ctl/calbox.h" + +class pgaSchedule; +class pgaJob; + +class dlgSchedule : public dlgAgentProperty +{ +public: + dlgSchedule(pgaFactory *factory, frmMain *frame, pgaSchedule *s, pgaJob *j); + + void CheckChange(); + int Go(bool modal); + + wxString GetComment(); + wxString GetUpdateSql(); + wxString GetInsertSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + void SetJobId(long id) + { + jobId = id; + } + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pgagent-schedules"); + } + +private: + long jobId; + pgaSchedule *schedule; + pgaJob *job; + + wxArrayString deleteExceptions; + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnChangeCom(wxCommandEvent &ev); + void OnChangeCal(wxCalendarEvent &ev); + void OnSelChangeException(wxListEvent &ev); + void OnAddException(wxCommandEvent &ev); + void OnChangeException(wxCommandEvent &ev); + void OnRemoveException(wxCommandEvent &ev); + const wxString ChkListBox2PgArray(wxCheckListBox *lb); + const wxString ChkListBox2StrArray(wxCheckListBox *lb); + void OnSelectAll(wxCommandEvent &ev, int origin); + void OnSelectAllWeekdays(wxCommandEvent &ev) + { + OnSelectAll(ev, 1); + }; + void OnSelectAllMonthdays(wxCommandEvent &ev) + { + OnSelectAll(ev, 2); + }; + void OnSelectAllMonths(wxCommandEvent &ev) + { + OnSelectAll(ev, 3); + }; + void OnSelectAllHours(wxCommandEvent &ev) + { + OnSelectAll(ev, 4); + }; + void OnSelectAllMinutes(wxCommandEvent &ev) + { + OnSelectAll(ev, 5); + }; + void InitSelectAll(); + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/agent/dlgStep.h b/include/agent/dlgStep.h new file mode 100644 index 0000000..7f0f000 --- /dev/null +++ b/include/agent/dlgStep.h @@ -0,0 +1,67 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgStep.h - Job property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_STEPPROP +#define __DLG_STEPPROP + +#include "dlg/dlgProperty.h" + +class pgaStep; +class pgaJob; + +class dlgStep : public dlgAgentProperty +{ +public: + dlgStep(pgaFactory *factory, frmMain *frame, pgaStep *s, pgaJob *j); + + void CheckChange(); + int Go(bool modal); + + wxString GetUpdateSql(); + wxString GetInsertSql(); + wxString GetComment(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + + void SetObject(pgObject *obj) + { + step = (pgaStep *)obj; + } + + void SetJobId(long id) + { + jobId = id; + } + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pgagent-steps"); + } + +private: + void OnSelRemoteConn(wxCommandEvent &ev); + void OnSelLocalConn(wxCommandEvent &ev); + void OnSelectDatabase(wxCommandEvent &ev); + + virtual bool IsUpToDate(); + + long jobId; + ctlSQLBox *sqlBox; + pgaStep *step; + pgaJob *job; + bool hasConnStrSupport; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/agent/module.mk b/include/agent/module.mk new file mode 100644 index 0000000..4742e46 --- /dev/null +++ b/include/agent/module.mk @@ -0,0 +1,22 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/agent Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/agent/dlgJob.h \ + include/agent/dlgSchedule.h \ + include/agent/dlgStep.h \ + include/agent/pgaJob.h \ + include/agent/pgaSchedule.h \ + include/agent/pgaStep.h + +EXTRA_DIST += \ + include/agent/module.mk + diff --git a/include/agent/pgaJob.h b/include/agent/pgaJob.h new file mode 100644 index 0000000..e561d0b --- /dev/null +++ b/include/agent/pgaJob.h @@ -0,0 +1,226 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgaJob.h - PostgreSQL Agent Job +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGAJOB_H +#define PGAJOB_H + +#include "schema/pgServer.h" + + +class pgaJobFactory : public pgServerObjFactory +{ +public: + pgaJobFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + int GetDisabledId() + { + return disabledId; + } + +protected: + int disabledId; +}; +extern pgaJobFactory jobFactory; + +class pgaJob : public pgServerObject +{ +public: + pgaJob(const wxString &newName = wxT("")); + + int GetIconId(); + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + void ShowStatistics(frmMain *form, ctlListView *statistics); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + + wxString GetTranslatedMessage(int kindOfMessage) const; + wxString GetJobclass() const + { + return jobclass; + } + void iSetJobclass(const wxString &s) + { + jobclass = s; + } + bool GetEnabled() const + { + return enabled; + } + void iSetEnabled(const bool b) + { + enabled = b; + } + wxDateTime GetCreated() const + { + return created; + } + void iSetCreated(const wxDateTime &d) + { + created = d; + } + wxDateTime GetChanged() const + { + return changed; + } + void iSetChanged(const wxDateTime &d) + { + changed = d; + } + wxDateTime GetNextrun() const + { + return nextrun; + } + void iSetNextrun(const wxDateTime &d) + { + nextrun = d; + } + wxDateTime GetLastrun() const + { + return lastrun; + } + void iSetLastrun(const wxDateTime &d) + { + lastrun = d; + } + wxString GetLastresult() const + { + return lastresult; + } + void iSetLastresult(const wxString &s) + { + lastresult = s; + } + wxString GetCurrentAgent() const + { + return currentAgent; + } + void iSetCurrentAgent(const wxString &s) + { + currentAgent = s; + } + wxString GetHostAgent() const + { + return hostAgent; + } + void iSetHostAgent(const wxString &s) + { + hostAgent = s; + } + long GetRecId() const + { + return recId; + } + void iSetRecId(const long l) + { + recId = l; + } + bool RunNow(); + + wxMenu *GetNewMenu(); + bool CanCreate() + { + return true; + } + bool CanView() + { + return false; + } + bool CanEdit() + { + return true; + } + bool CanDrop() + { + return true; + } + bool WantDummyChild() + { + return true; + } + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pgagent-jobs"); + } + +private: + bool enabled; + wxDateTime created, changed, nextrun, lastrun; + wxString lastresult, jobclass, currentAgent, hostAgent; + long recId; +}; + + +class pgaJobObject : public pgServerObject +{ +public: + pgaJobObject(pgaJob *job, pgaFactory &factory, const wxString &newName); + virtual pgaJob *GetJob() + { + return job; + } + + bool CanCreate() + { + return job->CanCreate(); + } + bool CanView() + { + return false; + } + bool CanEdit() + { + return job->CanEdit(); + } + bool CanDrop() + { + return job->CanDrop(); + } + +protected: + pgaJob *job; +}; + + +class pgaJobCollection : public pgServerObjCollection +{ +public: + pgaJobCollection(pgaFactory *factory, pgServer *sv); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + + +class pgaJobObjCollection : public pgServerObjCollection +{ +public: + pgaJobObjCollection(pgaFactory *factory, pgaJob *job); + bool CanCreate(); +}; + +class pgaJobObjFactory : public pgServerObjFactory +{ +public: + pgaJobObjFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm = 0) + : pgServerObjFactory(tn, ns, nls, img, imgSm) {} + virtual pgCollection *CreateCollection(pgObject *obj); +}; + +class runNowFactory : public contextActionFactory +{ +public: + runNowFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif diff --git a/include/agent/pgaSchedule.h b/include/agent/pgaSchedule.h new file mode 100644 index 0000000..20df7b1 --- /dev/null +++ b/include/agent/pgaSchedule.h @@ -0,0 +1,151 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgaSchedule.h - PostgreSQL Agent Job Schedule +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGASCHEDULE_H +#define PGASCHEDULE_H + +#include "agent/pgaJob.h" + + +class pgaScheduleFactory : public pgaJobObjFactory +{ +public: + pgaScheduleFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgaScheduleFactory scheduleFactory; + + +class pgaSchedule : public pgaJobObject +{ +public: + pgaSchedule(pgCollection *collection, const wxString &newName = wxT("")); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + + bool GetEnabled() const + { + return enabled; + } + void iSetEnabled(const bool b) + { + enabled = b; + } + wxDateTime GetStart() const + { + return start; + } + void iSetStart(const wxDateTime &d) + { + start = d; + } + wxDateTime GetEnd() const + { + return end; + } + void iSetEnd(const wxDateTime &d) + { + end = d; + } + long GetRecId() const + { + return recId; + } + void iSetRecId(const long l) + { + recId = l; + } + + wxString GetMinutes() const + { + return minutes; + } + wxString GetMinutesString(); + void iSetMinutes(const wxString &s) + { + minutes = s; + } + + wxString GetHours() const + { + return hours; + } + wxString GetHoursString(); + void iSetHours(const wxString &s) + { + hours = s; + } + + wxString GetWeekdays() const + { + return weekdays; + } + wxString GetWeekdaysString(); + void iSetWeekdays(const wxString &s) + { + weekdays = s; + } + + wxString GetMonthdays() const + { + return monthdays; + } + wxString GetMonthdaysString(); + void iSetMonthdays(const wxString &s) + { + monthdays = s; + } + + wxString GetMonths() const + { + return months; + } + wxString GetMonthsString(); + void iSetMonths(const wxString &s) + { + months = s; + } + + wxString GetExceptions() const + { + return exceptions; + } + wxString GetExceptionsString(); + void iSetExceptions(const wxString &s) + { + exceptions = s; + } + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pgagent-schedules"); + } + +private: + bool enabled; + wxDateTime start, end; + long recId; + wxString minutes, hours, weekdays, monthdays, months, exceptions; +}; + +class pgaScheduleCollection : public pgaJobObjCollection +{ +public: + pgaScheduleCollection(pgaFactory *factory, pgaJob *job); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/agent/pgaStep.h b/include/agent/pgaStep.h new file mode 100644 index 0000000..1369f58 --- /dev/null +++ b/include/agent/pgaStep.h @@ -0,0 +1,140 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgaStep.h - PostgreSQL Agent Job Step +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGASTEP_H +#define PGASTEP_H + +#include "agent/pgaJob.h" + + + +class pgaStepFactory : public pgaJobObjFactory +{ +public: + pgaStepFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgaStepFactory stepFactory; + + +class pgaStep : public pgaJobObject +{ +public: + pgaStep(pgCollection *collection, const wxString &newName = wxT("")); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + void ShowStatistics(frmMain *form, ctlListView *statistics); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + + bool GetEnabled() const + { + return enabled; + } + void iSetEnabled(const bool b) + { + enabled = b; + } + wxChar GetKindChar() const + { + return kindChar; + } + void iSetKindChar(const wxChar c) + { + kindChar = c; + } + wxString GetKind() const + { + return kind; + } + void iSetKind(const wxString &s) + { + kind = s; + } + wxString GetCode() const + { + return code; + } + void iSetCode(const wxString &s) + { + code = s; + } + wxString GetDbname() const + { + return dbname; + } + void iSetDbname(const wxString &s) + { + dbname = s; + } + wxString GetConnStr() const + { + return connstr; + } + void iSetConnStr(const wxString &s) + { + connstr = s; + } + wxString GetOnError() const + { + return onError; + } + void iSetOnError(const wxString &s) + { + onError = s; + } + wxChar GetOnErrorChar() const + { + return onErrorChar; + } + void iSetOnErrorChar(const wxChar c) + { + onErrorChar = c; + } + long GetRecId() const + { + return recId; + } + void iSetRecId(const long l) + { + recId = l; + } + + bool HasConnectionString() const + { + return !connstr.IsEmpty(); + } + + bool IsUpToDate(); + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pgagent-steps"); + } + +private: + bool enabled; + wxString kind, code, dbname, connstr, onError; + wxChar kindChar, onErrorChar; + long recId; +}; + +class pgaStepCollection : public pgaJobObjCollection +{ +public: + pgaStepCollection(pgaFactory *factory, pgaJob *job); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/copyright.h b/include/copyright.h new file mode 100644 index 0000000..1e9cdc5 --- /dev/null +++ b/include/copyright.h @@ -0,0 +1,19 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// copyright.h - pgAdmin copyright messages +// +////////////////////////////////////////////////////////////////////////// + +#ifndef COPYRIGHT_H +#define COPYRIGHT_H + +#define COPYRIGHT wxT("Copyright 2002 - 2016, The pgAdmin Development Team") +#define COPYRIGHT_WIN32 "\251 2002 - 2016, The pgAdmin Development Team" +#define LICENSE _("This software is released under the PostgreSQL Licence.") + +#endif diff --git a/include/ctl/calbox.h b/include/ctl/calbox.h new file mode 100644 index 0000000..c5785d0 --- /dev/null +++ b/include/ctl/calbox.h @@ -0,0 +1,136 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// calbox.h - Date-picker control box +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_CALBOX_H_ +#define _WX_CALBOX_H_ + +#include "wx/calctrl.h" + +#if defined(wxUSE_DATEPICKCTRL) && wxUSE_DATEPICKCTRL +#include "wx/datectrl.h" +#if wxUSE_DATEPICKCTRL_GENERIC +#include "wx/generic/datectrl.h" +#endif // wxUSE_DATEPICKCTRL_GENERIC +typedef wxDatePickerCtrl wxCalendarBox; +#else + +// pgCompatCalendarCtrl is a typedef for either wxGenericCalendarCtrl or wxCalendarCtrl +#if wxCHECK_VERSION(2, 9, 0) +#include "wx/generic/calctrlg.h" +typedef wxGenericCalendarCtrl pgCompatCalendarCtrl; +#else +typedef wxCalendarCtrl pgCompatCalendarCtrl; +#endif + +class wxCalendarBox : public wxControl +{ +public: + wxCalendarBox() + { + Init(); + } + wxCalendarBox(wxWindow *parent, + wxWindowID id, + const wxDateTime &date = wxDefaultDateTime, + const wxPoint &pos = wxDefaultPosition, + const wxSize &size = wxDefaultSize, + long style = wxCAL_SHOW_HOLIDAYS | wxWANTS_CHARS, const wxString &name = wxCalendarNameStr); + + bool Destroy(); + + bool Create(wxWindow *parent, + wxWindowID id, + const wxDateTime &date, + const wxPoint &pos, + const wxSize &size, + long style, + const wxString &name); + + bool SetValue(const wxDateTime &date); + wxDateTime GetValue(); + + bool SetLowerDateLimit(const wxDateTime &date = wxDefaultDateTime) + { + return m_cal->SetLowerDateLimit(date); + } + const wxDateTime &GetLowerDateLimit() const + { + return m_cal->GetLowerDateLimit(); + } + bool SetUpperDateLimit(const wxDateTime &date = wxDefaultDateTime) + { + return m_cal->SetUpperDateLimit(date); + } + const wxDateTime &GetUpperDateLimit() const + { + return m_cal->GetUpperDateLimit(); + } + + bool SetDateRange(const wxDateTime &lowerdate = wxDefaultDateTime, const wxDateTime &upperdate = wxDefaultDateTime) + { + return m_cal->SetDateRange(lowerdate, upperdate); + } + + wxCalendarDateAttr *GetAttr(size_t day) const + { + return m_cal->GetAttr(day); + } + void SetAttr(size_t day, wxCalendarDateAttr *attr) + { + m_cal->SetAttr(day, attr); + } + void SetHoliday(size_t day) + { + m_cal->SetHoliday(day); + } + void ResetAttr(size_t day) + { + m_cal->ResetAttr(day); + } + bool SetFormat(const wxChar *fmt); + + virtual bool Enable(bool enable = true); + virtual bool Show(bool show = true); + virtual void DoMoveWindow(int x, int y, int width, int height); + +private: + wxDialog *m_dlg; + wxTextCtrl *m_txt; + pgCompatCalendarCtrl *m_cal; + wxButton *m_btn; + wxString m_format; + + bool m_dropped, m_ignoreDrop; + + void Init(); + void DropDown(bool down = true); + + wxSize DoGetBestSize() const; + void OnSize(wxSizeEvent &event); + + void OnText(wxCommandEvent &ev); + void OnEditKey(wxKeyEvent &event); + void OnCalKey(wxKeyEvent &event); + void OnClick(wxCommandEvent &ev); + void OnSelChange(wxCalendarEvent &ev); + void OnSetFocus(wxFocusEvent &ev); + void OnKillFocus(wxFocusEvent &ev); + void OnChildSetFocus(wxChildFocusEvent &ev); + + DECLARE_DYNAMIC_CLASS(wxCalendarBox) + DECLARE_EVENT_TABLE() + DECLARE_NO_COPY_CLASS(wxCalendarBox) +}; + +#endif // wxUSE_DATEPICKCTRL + +#endif // _WX_CALBOX_H_ + diff --git a/include/ctl/ctlAuiNotebook.h b/include/ctl/ctlAuiNotebook.h new file mode 100644 index 0000000..9f2684d --- /dev/null +++ b/include/ctl/ctlAuiNotebook.h @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlAuiNotebook.cpp - Custom AUI Notebook class +// +////////////////////////////////////////////////////////////////////////// + +// The primary purpose of this class is to pass child focus events from +// the notebook to the parent window. This is the only way we can grab +// focus events from the page controls. + +#ifndef CTLAUINOTEBOOK_H +#define CTLAUINOTEBOOK_H + +// wxWindows headers +#include +#include + +class ctlAuiNotebook : public wxAuiNotebook +{ +public: + ctlAuiNotebook(wxWindow *parent, wxWindowID id = wxID_ANY, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = wxAUI_NB_DEFAULT_STYLE) : + wxAuiNotebook(parent, id, pos, size, style) { } + +protected: + void OnChildFocus(wxChildFocusEvent &evt); + + DECLARE_EVENT_TABLE() +}; + +#endif + diff --git a/include/ctl/ctlCheckTreeView.h b/include/ctl/ctlCheckTreeView.h new file mode 100644 index 0000000..117f592 --- /dev/null +++ b/include/ctl/ctlCheckTreeView.h @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlCheckTreeView.cpp - TreeView with Checkboxes +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _CTLCHECKTREEVIEW_H +#define _CTLCHECKTREEVIEW_H + + +// wxWindows headers +#include +#include +#include +#include + +class ctlCheckTreeView : public wxTreeCtrl +{ +public: + ctlCheckTreeView(wxWindow *parent, wxWindowID id, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = wxTR_HAS_BUTTONS); + bool IsChecked(const wxTreeItemId &node); + +private: + void OnLeftClick(wxMouseEvent &evt); + void SetParentAndChildImage(wxTreeItemId node, int newimage); + void SetParentImage(wxTreeItemId node, int newimage); + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/ctl/ctlColourPicker.h b/include/ctl/ctlColourPicker.h new file mode 100644 index 0000000..ba3d644 --- /dev/null +++ b/include/ctl/ctlColourPicker.h @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the BSD Licence +// +// ctlColourPicker.cpp - TreeView with Checkboxes +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef _CTLCOLOURPICKER_H +#define _CTLCOLOURPICKER_H + +// wxWindows headers +#include +#include "utils/misc.h" + + + +class ctlColourPicker : public wxBitmapButton +{ +public: + ctlColourPicker(wxWindow *parent, wxWindowID id, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize) + { + Create(parent, id, pos, size); + } + + void DoProcessLeftClick(wxMouseEvent &event); + + wxColour GetColour(); + wxString GetColourString(); + + void SetColour(const wxColour &colour); + void SetColour(const wxString &colour); + + void SetTitle(const wxString &title); + void UpdateColour(); + +private: + wxString m_title; + wxColour m_colour_clr; + + void Create(wxWindow *parent, wxWindowID id, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize); +}; + +#endif diff --git a/include/ctl/ctlComboBox.h b/include/ctl/ctlComboBox.h new file mode 100644 index 0000000..75749f1 --- /dev/null +++ b/include/ctl/ctlComboBox.h @@ -0,0 +1,61 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlComboBox.h - enhanced combobox control +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __COMBOBOX_H +#define __COMBOBOX_H + +// wxWindows headers +#include +#include "utils/misc.h" + + + +class pgConn; +class ctlComboBoxFix : public wxComboBox +{ +public: + ctlComboBoxFix(wxWindow *wnd, int id, wxPoint pos, wxSize siz, long attr); + + int FillLongKey(pgConn *conn, const wxChar *qry); + int FillOidKey(pgConn *conn, const wxChar *qry); + int FillStringKey(pgConn *conn, const wxChar *qry); + long GetLongKey(int sel = -1); + OID GetOIDKey(int sel = -1); + wxString GetStringKey(int sel = -1); + bool SetKey(long val); + bool SetKey(OID val); + bool SetKey(const wxString &val); + + int Append(const wxString &item) + { + return wxComboBox::Append(item); + } + int Append(const wxString &item, void *data) + { + return wxComboBox::Append(item, data); + } + int Append(const wxString &item, const wxString &str); + int Append(const wxString &item, long l); + int Append(const wxString &item, OID oid); +}; + +class ctlComboBox : public ctlComboBoxFix +{ +public: + ctlComboBox(wxWindow *wnd, int id, wxPoint pos, wxSize siz, long attr = 0); + int GuessSelection(wxCommandEvent &ev); + int GetGuessedSelection() const; + wxString GetGuessedStringSelection() const; + int GetSelection() const; +}; + +#endif diff --git a/include/ctl/ctlDefaultSecurityPanel.h b/include/ctl/ctlDefaultSecurityPanel.h new file mode 100644 index 0000000..6571588 --- /dev/null +++ b/include/ctl/ctlDefaultSecurityPanel.h @@ -0,0 +1,131 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlDefaultSecurityPanel.h - Panel with default security information +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef CTL_DEFDEFSECPANEL_H +#define CTL_DEFDEFSECPANEL_H + +#include +#include +#include + +enum +{ + CTL_DEFPROPSQL = 500, + CTL_DEFMSG, + CTL_DEFLBPRIV, + CTL_DEFSTATICGROUP, + CTL_DEFCBGROUP, + CTL_DEFADDPRIV, + CTL_DEFDELPRIV, + CTL_DEFALLPRIV, + CTL_DEFALLPRIVGRANT, + CTL_DEFPRIVCB // base for all privilege checkboxes, must be last +}; + +class defaultPrivilegesOn +{ +public: + defaultPrivilegesOn(const wxChar, const wxString &, const wxString &); + + wxChar m_privilegeType; + wxString m_privilegesOn; + wxString m_privileges; + wxArrayString m_privilegesList; +}; + + +DECLARE_LOCAL_EVENT_TYPE(EVT_DEFAULTSECURITYPANEL_CHANGE, -1) + +class pgConn; +class ctlDefaultPrivilegesPanel; +class dlgDefaultSecurityProperty; + +class ctlDefaultSecurityPanel : public wxPanel +{ + +public: + ctlDefaultSecurityPanel(pgConn *, wxNotebook *, wxImageList *); + + wxString GetDefaultPrivileges(const wxString &schemaName); + void UpdatePrivilegePages(bool createDefPrivs, const wxString &defPrivsOnTables, + const wxString &defPrivsOnSeqs, const wxString &defPrivsOnFuncs, + const wxString &defPrivsOnTypes); + +protected: + wxNotebook *nbNotebook; + wxArrayString m_groups; + wxArrayString m_namespaces; + + ctlDefaultPrivilegesPanel *m_defPrivOnTablesPanel, *m_defPrivOnSeqsPanel, *m_defPrivOnFuncsPanel, *m_defPrivOnTypesPanel; + + friend class ctlDefaultPrivilegesPanel; + friend class dlgDefaultSecurityProperty; + +}; + +class ctlDefaultPrivilegesPanel : public wxPanel +{ + +public: + + ctlDefaultPrivilegesPanel(ctlDefaultSecurityPanel *, wxNotebook *, defaultPrivilegesOn &, wxImageList *); + ~ctlDefaultPrivilegesPanel(); + + void Update(wxString privs); + wxString GetDefaultPrivileges(const wxString &schemaName); + +protected: + + typedef struct + { + wxString m_username; + wxString m_origPriv; + wxString m_newPriv; + bool m_modified; + } defPrivilege; + +public: + WX_DECLARE_STRING_HASH_MAP(defPrivilege, defPrivHash); + +protected: + + bool m_defPrivChanged; + int privilegeCount; + defaultPrivilegesOn m_privilegeType; + defPrivHash m_privileges; + defPrivilege *m_currentSelectedPriv; + + ctlDefaultSecurityPanel *m_defSecurityPanel; + wxButton *btnAddPriv, *btnDelPriv; + wxCheckBox **privCheckboxes; + wxCheckBox *allPrivileges, *allPrivilegesGrant; + ctlListView *lbPrivileges; + ctlComboBox *cbGroups; + wxStaticText *stGroup; + + void OnPrivSelChange(wxListEvent &ev); + void OnAddPriv(wxCommandEvent &ev); + void OnGroupChange(wxCommandEvent &ev); + void OnDelPriv(wxCommandEvent &ev); + void OnPrivCheck(wxCommandEvent &ev); + void OnPrivCheckAll(wxCommandEvent &ev); + void OnPrivCheckAllGrant(wxCommandEvent &ev); + + bool PrivCheckBoxUpdate(wxString &strUser); + void CheckGrantOpt(int index); + bool CanGrant(); + + DECLARE_EVENT_TABLE() +}; + +#endif + diff --git a/include/ctl/ctlListView.h b/include/ctl/ctlListView.h new file mode 100644 index 0000000..d2a9e4e --- /dev/null +++ b/include/ctl/ctlListView.h @@ -0,0 +1,75 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlListView.h - enhanced listview control +// +////////////////////////////////////////////////////////////////////////// + +#ifndef CTLLISTVIEW_H +#define CTLLISTVIEW_H + +// wxWindows headers +#include +#include +#include "utils/misc.h" + +class frmMain; + +class ctlListView : public wxListView +{ +public: + ctlListView(wxWindow *p, int id, wxPoint pos, wxSize siz, long attr = 0); + long GetSelection(); + wxString GetText(long row, long col = 0); + + void CreateColumns(wxImageList *images, const wxString &left, const wxString &right, int leftSize = 60); + void CreateColumns(wxImageList *images, const wxString &str1, const wxString &str2, const wxString &str3, int leftSize = 60); + + void AddColumn(const wxString &text, int size = wxLIST_AUTOSIZE_USEHEADER, int format = wxLIST_FORMAT_LEFT); + + long AppendItem(int icon, const wxString &val, const wxString &val2 = wxString(), const wxString &val3 = wxString(), const wxString &val4 = wxString()); + long AppendItem(const wxString &val, const wxString &val2 = wxString(), const wxString &val3 = wxString()) + { + return AppendItem(PGICON_PROPERTY, val, val2, val3); + } + void AppendItem(const wxString &str, long l) + { + AppendItem(str, NumToStr(l)); + } + void AppendItem(const wxString &str, double d) + { + AppendItem(str, NumToStr(d)); + } + void AppendItem(const wxString &str, OID o) + { + AppendItem(str, NumToStr(o)); + } + void AppendItem(const wxString &str, const wxDateTime &d) + { + AppendItem(str, DateToStr(d)); + } + void AppendItem(const wxString &str, const wxLongLong &l) + { + AppendItem(str, l.ToString()); + } + void AppendItem(const wxString &str, const wxULongLong &l) + { + AppendItem(str, l.ToString()); + } + void AppendYesNoItem(const wxString &str, bool b) + { + AppendItem(str, BoolToYesNo(b)); + } + + void DeleteCurrentItem() + { + DeleteItem(GetSelection()); + } +}; + + +#endif diff --git a/include/ctl/ctlMenuToolbar.h b/include/ctl/ctlMenuToolbar.h new file mode 100644 index 0000000..786f4c2 --- /dev/null +++ b/include/ctl/ctlMenuToolbar.h @@ -0,0 +1,91 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlMenuToolbar.h - Menu tool bar +// +// This code is essentially stolen (with the authors permission) from +// Paul Nelson (http://www.pnelsoncomposer.com/) +// +////////////////////////////////////////////////////////////////////////// + +#ifndef CTLMENUTOOLBAR_H +#define CTLMENUTOOLBAR_H + +#include "wx/frame.h" + +// ctlMenuButton - Can be used wherever you can use a standard wxBitmapButton +// +// Implements a small pull-down triangle (v), which, when clicked, will display +// a pop-up menu. + +class ctlMenuButton : public wxBitmapButton +{ +public: + ctlMenuButton(wxToolBar *toolBar, int ID, wxMenu *menu) + { + Create(toolBar, toolBar, ID, menu); + } + void DoProcessLeftClick(wxMouseEvent &event); + + wxMenu *m_menu; + + void FillMenu(); + +private: + void Create(wxWindow *window, wxToolBar *toolBar, int ID, wxMenu *menu); + wxToolBar *m_toolBar; +}; + + +// ctlMenuTool - is only used internal to the implementation of ctlMenuToolbar. +// +// You should never have to use it yourself + +class ctlMenuTool +{ +public: + ctlMenuTool(wxToolBarToolBase *new_tool, int toolId); + wxToolBarToolBase *m_tool; + wxMenu *m_menu; + +private: + int m_toolId; + ctlMenuButton *m_button; +}; + +WX_DECLARE_LIST(ctlMenuTool, ctlMenuToolList); + + +// *** ctlMenuToolbar - A replacement for wxToolBar which implements menu buttons +// and pull-down buttons +// +// A menu button is a standard looking toolbar tool which, when clicked, pops up a +// menu which can be selected. +// +// A pull-down button presents a small black triangle which, when clicked, pops up +// a menu which can be selected. These buttons are typically used for a list of previous +// actions (for example, previous web pages visited). + +class ctlMenuToolbar : public wxToolBar +{ +public: + ctlMenuToolbar(); + ctlMenuToolbar(wxFrame *parent, wxWindowID id, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = wxTB_HORIZONTAL | wxNO_BORDER, const wxString &name = wxPanelNameStr); + ~ctlMenuToolbar(); + + // NOTE: label, shortHelpString, are not implemented on all platforms and are only + // included for possible future upgrades + ctlMenuButton *AddMenuPulldownTool(int toolId, const wxString &label, const wxString &shortHelpString = wxEmptyString, wxMenu *popupmenu = 0); + void DoProcessLeftClick(wxMouseEvent &event); + +private: + wxFrame *m_frame; + ctlMenuToolList *m_menuTools; +}; + +#endif + diff --git a/include/ctl/ctlProgressStatusBar.h b/include/ctl/ctlProgressStatusBar.h new file mode 100644 index 0000000..de54bc5 --- /dev/null +++ b/include/ctl/ctlProgressStatusBar.h @@ -0,0 +1,61 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlProgressStatusBar.h - Status bar indicating the current progress +// +////////////////////////////////////////////////////////////////////////// +// +#ifndef CTLPROGRESS_STATUSBAR_H +#define CTLPROGRESS_STATUSBAR_H + +// wxWindows headers +#include +#include +#include + +class ctlProgressStatusBar : public wxStatusBar +{ +public: + ctlProgressStatusBar(wxWindow *parent, bool showProgressInitially = true, bool autoProgressive = true, int max = -1); + virtual ~ctlProgressStatusBar(); + + void ShowProgress(bool restart = true); + void StopProgress(); + void SetProgress(int val); + virtual void SetFieldsCount(int number = 1, const int *widths = NULL); + virtual void SetStatusWidths(int n, const int widths_field[]); + + static const unsigned short ms_increment, + ms_progressbar_width, + ms_progressstatus_width; + +protected: + void OnTimer(wxTimerEvent &WXUNUSED(event)); + void OnSize(wxSizeEvent &ev); + + wxGauge *m_progress; + wxTimer m_timer; + + bool m_progressStopped; + bool m_autoProgressive; + bool m_autoValIncrementing; + + int m_hr, m_min, m_sec, m_mil; + int m_val; + + enum + { + Status_field, + ProgressBar_field, + ProgressStatus_field, + Max_Field + }; + + DECLARE_EVENT_TABLE() +}; + +#endif // CTLPROGRESS_STATUSBAR_H diff --git a/include/ctl/ctlSQLBox.h b/include/ctl/ctlSQLBox.h new file mode 100644 index 0000000..4ddc79d --- /dev/null +++ b/include/ctl/ctlSQLBox.h @@ -0,0 +1,121 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlSQLBox.h - SQL syntax highlighting textbox +// +////////////////////////////////////////////////////////////////////////// + +#ifndef CTLSQLBOX_H +#define CTLSQLBOX_H + +// wxWindows headers +#include +#include +#include +#include "utils/macros.h" + +#include "db/pgConn.h" +#include "dlg/dlgFindReplace.h" + +// These structs are from Scintilla.h which isn't easily #included :-( +struct CharacterRange +{ + long cpMin; + long cpMax; +}; + +struct TextToFind +{ + struct CharacterRange chrg; + char *lpstrText; + struct CharacterRange chrgText; +}; + +class sysProcess; + +// Class declarations +class ctlSQLBox : public wxStyledTextCtrl +{ + static wxString sqlKeywords; + +public: + ctlSQLBox(wxWindow *parent, wxWindowID id = -1, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = 0); + ctlSQLBox(); + ~ctlSQLBox(); + + void Create(wxWindow *parent, wxWindowID id = -1, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = 0); + + void SetDatabase(pgConn *db); + + void OnKeyDown(wxKeyEvent &event); + void OnAutoComplete(wxCommandEvent &event); + void OnSearchReplace(wxCommandEvent &event); + void OnKillFocus(wxFocusEvent &event); + + bool Find(const wxString &find, bool wholeWord, bool matchCase, bool useRegexps, bool startAtTop, bool reverse); + bool Replace(const wxString &find, const wxString &replace, bool wholeWord, bool matchCase, bool useRegexps, bool startAtTop, bool reverse); + bool ReplaceAll(const wxString &find, const wxString &replace, bool wholeWord, bool matchCase, bool useRegexps); + bool DoFind(const wxString &find, const wxString &replace, bool doReplace, bool wholeWord, bool matchCase, bool useRegexps, bool startAtTop, bool reverse); + void SetAutoReplaceList(queryMacroList *autorep); + void SetAutoIndent(bool on) + { + m_autoIndent = on; + } + void EnableAutoComp(bool on) + { + m_autocompDisabled = on; + } + bool BlockComment(bool uncomment = false); + void UpdateLineNumber(); + wxString ExternalFormat(); + void AbortProcess(); + + CharacterRange RegexFindText(int minPos, int maxPos, const wxString &text); + + // Having multiple SQL tabs warrants the following properties to be tracked per tab + void SetChanged(bool b); + bool IsChanged(); + void SetOrigin(int origin); + int GetOrigin(); + void SetFilename(wxString &filename); + wxString GetFilename(); + void SetTitle(wxString &title); + wxString GetTitle(bool withChangeInd = true); + wxString GetChangeIndicator(); + long SelectQuery(int startposition); + DECLARE_DYNAMIC_CLASS(ctlSQLBox) + DECLARE_EVENT_TABLE() + +protected: + void OnEndProcess(wxProcessEvent &ev); + void UpdateTitle(); + + sysProcess *process; + long processID; + wxString processOutput, processErrorOutput; + int processExitCode; + +private: + void OnPositionStc(wxStyledTextEvent &event); + void OnMarginClick(wxStyledTextEvent &event); + queryMacroList *autoreplace; + dlgFindReplace *m_dlgFindReplace; + pgConn *m_database; + bool m_autoIndent, m_autocompDisabled; + + // Variables to track info per SQL box + wxString m_filename; + wxString m_title; + wxString m_changestr; + bool m_changed; + int m_origin; + + friend class QueryPrintout; +}; + +#endif + diff --git a/include/ctl/ctlSQLGrid.h b/include/ctl/ctlSQLGrid.h new file mode 100644 index 0000000..011472e --- /dev/null +++ b/include/ctl/ctlSQLGrid.h @@ -0,0 +1,65 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlSQLGrid.h - SQL Data Display Grid +// +////////////////////////////////////////////////////////////////////////// + +#ifndef CTLSQLGRID_H +#define CTLSQLGRID_H + +// wxWindows headers +#include + + +class ctlSQLGrid : public wxGrid +{ +public: + ctlSQLGrid(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size); + ctlSQLGrid(); + + wxString GetExportLine(int row); + wxString GetExportLine(int row, wxArrayInt cols); + wxString GetExportLine(int row, int col1, int col2); + virtual bool IsColText(int col) + { + return false; + } + int Copy(); + + virtual bool CheckRowPresent(int row) + { + return true; + } + wxSize GetBestSize(int row, int col); + void OnLabelDoubleClick(wxGridEvent &event); + void OnLabelClick(wxGridEvent &event); + + void AutoSizeColumn(int col, bool setAsMin = false, bool doLimit = true); + void AutoSizeColumns(bool setAsMin); + + WX_DECLARE_STRING_HASH_MAP( int, ColKeySizeHashMap ); + + DECLARE_DYNAMIC_CLASS(ctlSQLGrid) + DECLARE_EVENT_TABLE() + +private: + void OnCopy(wxCommandEvent &event); + void OnMouseWheel(wxMouseEvent &event); + void OnGridColSize(wxGridSizeEvent &event); + wxString GetColumnName(int colNum); + wxString GetColKeyValue(int col); + void AppendColumnHeader(wxString &str, int start, int end); + void AppendColumnHeader(wxString &str, wxArrayInt columns); + + // Stores sizes of colums explicitly resized by user + ColKeySizeHashMap colSizes; + // Max size for each column + wxArrayInt colMaxSizes; +}; + +#endif diff --git a/include/ctl/ctlSQLResult.h b/include/ctl/ctlSQLResult.h new file mode 100644 index 0000000..c25c3cf --- /dev/null +++ b/include/ctl/ctlSQLResult.h @@ -0,0 +1,115 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlSQLResult.h - SQL Query result window +// +////////////////////////////////////////////////////////////////////////// + +#ifndef CTLSQLRESULT_H +#define CTLSQLRESULT_H + +// wxWindows headers +#include + +#include "db/pgSet.h" +#include "db/pgConn.h" +#include "ctlSQLGrid.h" +#include "frm/frmExport.h" + +#define CTLSQL_RUNNING 100 // must be greater than ExecStatusType PGRES_xxx values + +class ctlSQLResult : public ctlSQLGrid +{ +public: + ctlSQLResult(wxWindow *parent, pgConn *conn, wxWindowID id, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize); + ~ctlSQLResult(); + + + int Execute(const wxString &query, int resultToDisplay = 0, wxWindow *caller = 0, long eventId = 0, void *data = 0); // > 0: resultset to display, <=0: last result + void SetConnection(pgConn *conn); + long NumRows() const; + long InsertedCount() const; + OID InsertedOid() const; + + int Abort(); + + bool Export(); + bool ToFile(); + bool ToFile(frmExport *frm); + bool CanExport() + { + return NumRows() > 0 && colNames.GetCount() > 0; + } + + wxString OnGetItemText(long item, long col) const; + wxString SummaryColumn(); + bool IsColText(int col); + bool hasRowNumber() + { + return !rowcountSuppressed; + } + + int RunStatus(); + wxString GetMessagesAndClear(); + wxString GetErrorMessage(); + pgError GetResultError(); + + void DisplayData(bool single = false); + + bool GetRowCountSuppressed() + { + return rowcountSuppressed; + }; + + void SetMaxRows(int rows); + void ResultsFinished(); + void OnGridSelect(wxGridRangeSelectEvent &event); + + wxArrayString colNames; + wxArrayString colTypes; + wxArrayLong colTypClasses; + wxString sqlquerytext; +private: + pgQueryThread *thread; + pgConn *conn; + bool rowcountSuppressed; +}; + +class sqlResultTable : public wxGridTableBase +{ +public: + sqlResultTable(); + wxString GetValue(int row, int col); + int GetNumberRows(); + int GetNumberCols(); + bool IsEmptyCell(int row, int col) + { + return false; + } + wxString GetColLabelValue(int col); + void SetValue(int row, int col, const wxString &value) + { + return; + } + void SetThread(pgQueryThread *t) + { + thread = t; + } + bool DeleteRows(size_t pos = 0, size_t numRows = 1) + { + return true; + } + bool DeleteCols(size_t pos = 0, size_t numCols = 1) + { + return true; + } + +private: + pgQueryThread *thread; +}; + +#endif diff --git a/include/ctl/ctlSeclabelPanel.h b/include/ctl/ctlSeclabelPanel.h new file mode 100644 index 0000000..15321d3 --- /dev/null +++ b/include/ctl/ctlSeclabelPanel.h @@ -0,0 +1,63 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlSeclabelPanel.h - Panel with security label information +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef CTL_SECLBLPANEL_H +#define CTL_SECLBLPANEL_H + +#include +#include + +enum +{ + CTL_LBSECLABEL = 250, + CTL_ADDSECLABEL, + CTL_DELSECLABEL, + CTL_PROVIDER, + CTL_SECLABEL +}; + +DECLARE_LOCAL_EVENT_TYPE(EVT_SECLABELPANEL_CHANGE, -1) + +class pgConn; + +class ctlSeclabelPanel : public wxPanel +{ + +public: + + ctlSeclabelPanel(wxNotebook *nb); + ~ctlSeclabelPanel(); + + ctlListView *lbSeclabels; + void SetConnection(pgConn *conn); + void SetObject(pgObject *obj); + void Disable(); + wxString GetSqlForSecLabels(wxString objecttype = wxEmptyString, wxString objectname = wxEmptyString); + void GetCurrentProviderLabelArray(wxArrayString &secLabels); +protected: + wxNotebook *nbNotebook; + pgConn *connection; + pgObject *object; + + wxButton *btnAddSeclabel, *btnDelSeclabel; + wxTextCtrl *txtProvider, *txtSeclabel; + + void OnSeclabelSelChange(wxListEvent &ev); + void OnAddSeclabel(wxCommandEvent &ev); + void OnDelSeclabel(wxCommandEvent &ev); + void OnProviderChange(wxCommandEvent &ev); + void OnSeclabelChange(wxCommandEvent &ev); + void OnChange(wxCommandEvent &ev); + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/ctl/ctlSecurityPanel.h b/include/ctl/ctlSecurityPanel.h new file mode 100644 index 0000000..2ac7aa8 --- /dev/null +++ b/include/ctl/ctlSecurityPanel.h @@ -0,0 +1,83 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlSecurityPanel.h - Panel with security information +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef CTL_SECPANEL_H +#define CTL_SECPANEL_H + +#include +#include + +enum +{ + CTL_PROPSQL = 250, + CTL_MSG, + CTL_LBPRIV, + CTL_STATICGROUP, + CTL_CBGROUP, + CTL_ADDPRIV, + CTL_DELPRIV, + CTL_ALLPRIV, + CTL_ALLPRIVGRANT, + CTL_PRIVCB // base for all privilege checkboxes, must be last +}; + +DECLARE_LOCAL_EVENT_TYPE(EVT_SECURITYPANEL_CHANGE, -1) + +class pgConn; + +class ctlSecurityPanel : public wxPanel +{ + +public: + + ctlSecurityPanel(wxNotebook *nb, const wxString &privList, const char *privChars, wxImageList *imgList); + ~ctlSecurityPanel(); + + ctlListView *lbPrivileges; + ctlComboBox *cbGroups; + wxStaticText *stGroup; + void SetConnection(pgConn *conn); + + /* + * Except column level privileges, column will be always an empty string in any case + */ + wxString GetGrant(const wxString &allPattern, const wxString &grantObject, wxArrayString *currentAcl = 0, wxString column = wxEmptyString); + wxString GetUserPrivileges(); + bool DisablePrivilege(const wxString &priv); +protected: + wxNotebook *nbNotebook; + pgConn *connection; + + wxButton *btnAddPriv, *btnDelPriv; + int privilegeCount; + const char *privilegeChars; + wxCheckBox **privCheckboxes; + wxCheckBox *allPrivileges, *allPrivilegesGrant; + + void OnPrivSelChange(wxListEvent &ev); + void OnAddPriv(wxCommandEvent &ev); + void OnGroupChange(wxCommandEvent &ev); + void OnDelPriv(wxCommandEvent &ev); + void OnPrivCheck(wxCommandEvent &ev); + void OnPrivCheckAll(wxCommandEvent &ev); + void OnPrivCheckAllGrant(wxCommandEvent &ev); + + void CheckGrantOpt(int index); + bool GrantAllowed() const; + + + DECLARE_EVENT_TABLE() +}; + + + +#endif diff --git a/include/ctl/ctlTree.h b/include/ctl/ctlTree.h new file mode 100644 index 0000000..b7700e8 --- /dev/null +++ b/include/ctl/ctlTree.h @@ -0,0 +1,97 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlTree.h - wxTreeCtrl containing pgObjects +// +////////////////////////////////////////////////////////////////////////// + +#ifndef CTLTREE_H +#define CTLTREE_H + +// wxWindows headers +#include +#include +#include + +class pgObject; +class pgCollection; +class pgaFactory; +class ctlTreeFindTimer; + +class ctlTree : public wxTreeCtrl +{ +public: + ctlTree(wxWindow *parent, wxWindowID id, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = wxTR_HAS_BUTTONS); + void SetItemImage(const wxTreeItemId &item, int image, wxTreeItemIcon which = wxTreeItemIcon_Normal); + wxTreeItemId AppendItem(const wxTreeItemId &parent, const wxString &text, int image = -1, int selImage = -1, wxTreeItemData *data = NULL); + wxTreeItemId AppendObject(pgObject *parent, pgObject *object); + void RemoveDummyChild(pgObject *obj); + pgCollection *AppendCollection(pgObject *parent, pgaFactory &factory); + pgObject *GetObject(wxTreeItemId id); + pgObject *GetParentObject(wxTreeItemId id) + { + return GetObject(GetItemParent(id)); + } + pgCollection *GetParentCollection(wxTreeItemId id); + pgObject *FindObject(pgaFactory &factory, wxTreeItemId parent); + pgCollection *FindCollection(pgaFactory &factory, wxTreeItemId parent); + wxTreeItemId FindItem(const wxTreeItemId &item, const wxString &str); + void NavigateTree(int keyCode); + virtual ~ctlTree(); + + DECLARE_EVENT_TABLE() + +private: + void OnChar(wxKeyEvent &event); + wxString m_findPrefix; + ctlTreeFindTimer *m_findTimer; + + friend class ctlTreeFindTimer; +}; + + +// timer used to clear ctlTreeCtrl::m_findPrefix if no key was pressed +// for a sufficiently long time +class ctlTreeFindTimer : public wxTimer +{ +public: + // reset the current prefix after half a second of inactivity + enum { CTLTREE_DELAY = 500 }; + + ctlTreeFindTimer( ctlTree *owner ) + { + m_owner = owner; + } + + virtual void Notify() + { + m_owner->m_findPrefix.clear(); + } + +private: + ctlTree *m_owner; + + DECLARE_NO_COPY_CLASS(ctlTreeFindTimer) +}; + + +class treeObjectIterator +{ +public: + treeObjectIterator(ctlTree *browser, pgObject *obj); + pgObject *GetNextObject(); + +private: + wxTreeItemId lastItem; + ctlTree *browser; + pgObject *object; + wxCookieType cookie; +}; + + + +#endif diff --git a/include/ctl/explainCanvas.h b/include/ctl/explainCanvas.h new file mode 100644 index 0000000..a89bda3 --- /dev/null +++ b/include/ctl/explainCanvas.h @@ -0,0 +1,159 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// explainCanvas.h - Explain Canvas +// +////////////////////////////////////////////////////////////////////////// + +#ifndef EXPLAINCANVAS_H +#define EXPLAINCANVAS_H + +#if wxUSE_POPUPWIN +#include "wx/popupwin.h" + +#define pgTipWindowBase wxPopupTransientWindow +#else +#include "wx/frame.h" + +#define pgTipWindowBase wxFrame +#endif + +#include + + +#if wxUSE_DEPRECATED +#error wxUSE_DEPRECATED should be 0! +#endif + + +class ExplainShape; +class ExplainPopup; +class ExplainText; + +class ExplainCanvas : public wxShapeCanvas +{ +public: + ExplainCanvas(wxWindow *parent); + ~ExplainCanvas(); + + void ShowPopup(ExplainShape *s); + void SetExplainString(const wxString &str); + void Clear(); + void SaveAsImage(const wxString &fileName, wxBitmapType imageType); + +private: + void OnMouseMotion(wxMouseEvent &ev); + + ExplainShape *rootShape; + ExplainPopup *popup; + + DECLARE_EVENT_TABLE() +}; + + +class ExplainShape : public wxBitmapShape +{ +public: + ExplainShape(const wxImage &bmp, const wxString &description, long tokenNo = -1, long detailNo = -1); + static ExplainShape *Create(long level, ExplainShape *last, const wxString &str); + + void SetCondition(const wxString &str) + { + if (condition.Length() == 0) condition = str; + else condition += wxT(" ") + str; + } + long GetLevel() + { + return level; + } + wxRealPoint GetStartPoint(); + wxRealPoint GetEndPoint(int kidNo); + int GetKidno() + { + return kidNo; + } + + ExplainShape *GetUpper() + { + return upperShape; + } + double GetAverageCost() + { + return (costHigh - costLow) / 2 + costLow; + } + +protected: + void OnDraw(wxDC &dc); + void OnLeftClick(double x, double y, int keys = 0, int attachment = 0); + + ExplainShape *upperShape; + + void SetLabel(const wxString &str, int tokenNo = -1, int detailNo = -1); + + long level; + wxString description, detail, condition, label; + wxString cost, actual; + double costLow, costHigh; + long rows, width; + int kidCount, kidNo; + int totalShapes; // horizontal space usage by shape and its kids + int usedShapes; + bool m_rootShape; + + friend class ExplainCanvas; + friend class ExplainText; +}; + + +class ExplainLine : public wxLineShape +{ +public: + ExplainLine(ExplainShape *from, ExplainShape *to, double weight = 0); + +private: + int width; + void OnDraw(wxDC &dc); +}; + + +class ExplainPopup : public pgTipWindowBase +{ +public: + ExplainPopup(ExplainCanvas *parent, ExplainShape *shape, ExplainPopup **popup = NULL); + void Close(); + ~ExplainPopup(); + +protected: + // event handlers + void OnMouseClick(wxMouseEvent &event); + void OnMouseMove(wxMouseEvent &ev); + +#if !wxUSE_POPUPWIN + void OnActivate(wxActivateEvent &event); + void OnKillFocus(wxFocusEvent &event); + +#else // wxUSE_POPUPWIN + virtual void OnDismiss(); + void OnMouseLost(wxMouseCaptureLostEvent &ev); +#endif // wxUSE_POPUPWIN/!wxUSE_POPUPWIN + + ExplainPopup **m_ptr; + wxRect m_rectBound; + + ExplainText *m_explainText; + +#if !wxUSE_POPUPWIN + long m_creationTime; +#endif // !wxUSE_POPUPWIN + + friend class ExplainText; + + DECLARE_EVENT_TABLE() +}; + +#endif + diff --git a/include/ctl/module.mk b/include/ctl/module.mk new file mode 100644 index 0000000..579a728 --- /dev/null +++ b/include/ctl/module.mk @@ -0,0 +1,42 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/ctl/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/ctl/calbox.h \ + include/ctl/ctlAuiNotebook.h \ + include/ctl/ctlCheckTreeView.h \ + include/ctl/ctlColourPicker.h \ + include/ctl/ctlComboBox.h \ + include/ctl/ctlListView.h \ + include/ctl/ctlMenuToolbar.h \ + include/ctl/ctlDefaultSecurityPanel.h \ + include/ctl/ctlSeclabelPanel.h \ + include/ctl/ctlSecurityPanel.h \ + include/ctl/ctlSQLBox.h \ + include/ctl/ctlSQLGrid.h \ + include/ctl/ctlSQLResult.h \ + include/ctl/ctlProgressStatusBar.h \ + include/ctl/ctlTree.h \ + include/ctl/explainCanvas.h \ + include/ctl/timespin.h \ + include/ctl/wxgridsel.h \ + include/ctl/xh_calb.h \ + include/ctl/xh_ctlcombo.h \ + include/ctl/xh_ctlcolourpicker.h \ + include/ctl/xh_ctlchecktreeview.h \ + include/ctl/xh_ctltree.h \ + include/ctl/xh_sqlbox.h \ + include/ctl/xh_timespin.h + +EXTRA_DIST += \ + include/ctl/module.mk + + diff --git a/include/ctl/timespin.h b/include/ctl/timespin.h new file mode 100644 index 0000000..312af2c --- /dev/null +++ b/include/ctl/timespin.h @@ -0,0 +1,135 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// timespin.h - timeSpan SpinCtrl +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_TIMESPIN_H_ +#define _WX_TIMESPIN_H_ + +#include "wx/datetime.h" +#include "wx/spinbutt.h" + + +class wxTimeSpinCtrl : public wxControl +{ +public: + wxTimeSpinCtrl() + { + Init(); + } + wxTimeSpinCtrl(wxWindow *parent, + wxWindowID id, + const wxPoint &pos = wxDefaultPosition, + const wxSize &size = wxDefaultSize, + long style = wxWANTS_CHARS, const wxString &name = wxT("wxTimeSpinCtrl")); + + bool Create(wxWindow *parent, + wxWindowID id, + const wxPoint &pos = wxDefaultPosition, + const wxSize &size = wxDefaultSize, + long style = wxWANTS_CHARS, const wxString &name = wxT("wxTimeSpinCtrl")); + + bool Destroy(); + bool Enable(bool enable = true); + + void SetMax(long seconds, bool useDay = false); + bool SetValue(const wxTimeSpan &span); + bool SetTime(const wxDateTime &time); + wxTimeSpan GetValue(); + +private: + void Init(); + + void OnSpinUp(wxSpinEvent &ev); + void OnSpinDown(wxSpinEvent &ev); + void OnSpin(wxSpinEvent &ev); + void OnText(wxCommandEvent &ev); + void OnSetFocus(wxFocusEvent &ev); + void OnKillFocus(wxFocusEvent &ev); + void OnEditKey(wxKeyEvent &ev); + void OnNavigate(wxNavigationKeyEvent &ev); + + long GetTextTime(); + int GetTimePart(); + void DoSpin(int diff); + void Highlight(int tp); + + wxTextCtrl *m_txt; + wxSpinButton *m_spn; + wxString m_format; + long spinValue, maxSpinValue; + bool canWrap, hasDay; + + wxSize DoGetBestSize() const; + void OnSize(wxSizeEvent &event); + + DECLARE_DYNAMIC_CLASS(wxTimeSpinCtrl) + DECLARE_EVENT_TABLE() + DECLARE_NO_COPY_CLASS(wxTimeSpinCtrl) +}; + + +#if 0 +class wxTimeSpinCtrl : public wxSpinCtrl //wxControl +{ +public: + wxTimeSpinCtrl() { } + wxTimeSpinCtrl(wxWindow *parent, + wxWindowID id, + const wxDateTime &date = wxDefaultDateTime, + const wxPoint &pos = wxDefaultPosition, + const wxSize &size = wxDefaultSize, + long style = wxWANTS_CHARS, const wxString &name = wxT("wxTimeSpinCtrl")); + + bool Destroy(); + + + bool Create(wxWindow *parent, + wxWindowID id, + const wxDateTime &date, + const wxPoint &pos, + const wxSize &size, + long style, + const wxString &name); + + bool SetValue(const wxTimeSpan &span); + wxTimeSpan GetValue(); + + virtual bool Enable(bool enable = true); + virtual bool Show(bool show = true); + virtual void DoMoveWindow(int x, int y, int width, int height); + +private: + wxTextCtrl *m_txt; + wxSpinCtrl *m_spn; + wxButton *m_btn; + wxString m_format; + + bool m_dropped, m_processing; + + void Init(); + void DropDown(bool down = true); + + void OnEditKey(wxKeyEvent &event); + void OnCalKey(wxKeyEvent &event); + void OnClick(wxMouseEvent &ev); + void OnSelChange(wxCalendarEvent &ev); + void OnActivate(wxActivateEvent &ev); + void OnSetFocus(wxFocusEvent &ev); + void OnKillFocus(wxFocusEvent &ev); + + DECLARE_DYNAMIC_CLASS(wxTimeSpinCtrl) + DECLARE_EVENT_TABLE() + DECLARE_NO_COPY_CLASS(wxTimeSpinCtrl) +}; +#endif + + +#endif // _WX_TIMESPIN_H_ + diff --git a/include/ctl/wxgridsel.h b/include/ctl/wxgridsel.h new file mode 100644 index 0000000..a5593cc --- /dev/null +++ b/include/ctl/wxgridsel.h @@ -0,0 +1,26 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// wxgridsel.h - replacement for wx/generic/gridsel.h +// if binary wxWindows 2.4.0 distribution is used. +// This file is necessary until wxGrid supports multiple wxGrid::SetTable() calls +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __WXGRIDSEL_H +#define __WXGRIDSEL_H + + +class wxGridSelection +{ + wxGridCellCoordsArray dummy1[3]; + wxArrayInt dummy2[2]; + void *dummy3; + wxGrid::wxGridSelectionModes dummy4; +}; + +#endif diff --git a/include/ctl/xh_calb.h b/include/ctl/xh_calb.h new file mode 100644 index 0000000..bded110 --- /dev/null +++ b/include/ctl/xh_calb.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// xh_calb.h - wxCalendarBox handler +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef _WX_XH_CALB_H_ +#define _WX_XH_CALB_H_ + + +#include "wx/xrc/xmlres.h" + +//class WXDLLIMPEXP_XRC +class wxCalendarBoxXmlHandler : public wxXmlResourceHandler +{ + DECLARE_DYNAMIC_CLASS(wxCalendarBoxXmlHandler) +public: + wxCalendarBoxXmlHandler(); + virtual wxObject *DoCreateResource(); + virtual bool CanHandle(wxXmlNode *node); +}; + + +#endif // _WX_XH_CALB_H_ diff --git a/include/ctl/xh_ctlchecktreeview.h b/include/ctl/xh_ctlchecktreeview.h new file mode 100644 index 0000000..f96ce47 --- /dev/null +++ b/include/ctl/xh_ctlchecktreeview.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// xh_ctlchecktreeview.h - ctlCheckTreeView handler +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef _WX_XH_CTLCHECKTREEVIEW_H_ +#define _WX_XH_CTLCHECKTREEVIEW_H_ + +#include "wx/xrc/xmlres.h" +#include "wx/xrc/xh_tree.h" + +//class WXDLLIMPEXP_XRC +class ctlCheckTreeViewXmlHandler : public wxTreeCtrlXmlHandler +{ + DECLARE_DYNAMIC_CLASS(ctlCheckTreeViewXmlHandler) +public: + ctlCheckTreeViewXmlHandler() : wxTreeCtrlXmlHandler() {} + virtual wxObject *DoCreateResource(); + virtual bool CanHandle(wxXmlNode *node); +}; + + +#endif diff --git a/include/ctl/xh_ctlcolourpicker.h b/include/ctl/xh_ctlcolourpicker.h new file mode 100644 index 0000000..0d584d7 --- /dev/null +++ b/include/ctl/xh_ctlcolourpicker.h @@ -0,0 +1,31 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the BSD Licence +// +// xh_ctlcolourpicker.h - ctlColourPicker handler +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef _WX_XH_CTLCOLOURPICKER_H_ +#define _WX_XH_CTLCOLOURPICKER_H_ + + +#include "wx/xrc/xmlres.h" +#include "wx/xrc/xh_bmpbt.h" + +//class WXDLLIMPEXP_XRC +class ctlColourPickerXmlHandler : public wxBitmapButtonXmlHandler +{ + DECLARE_DYNAMIC_CLASS(ctlColourPickerXmlHandler) +public: + ctlColourPickerXmlHandler() : wxBitmapButtonXmlHandler() {} + virtual wxObject *DoCreateResource(); + virtual bool CanHandle(wxXmlNode *node); +}; + + +#endif diff --git a/include/ctl/xh_ctlcombo.h b/include/ctl/xh_ctlcombo.h new file mode 100644 index 0000000..a117260 --- /dev/null +++ b/include/ctl/xh_ctlcombo.h @@ -0,0 +1,31 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// xh_ctlcombo.h - ctlComboBox handler +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef _WX_XH_CTLCOMBO_H_ +#define _WX_XH_CTLCOMBO_H_ + + +#include "wx/xrc/xmlres.h" +#include "wx/xrc/xh_combo.h" + +//class WXDLLIMPEXP_XRC +class ctlComboBoxXmlHandler : public wxComboBoxXmlHandler +{ + DECLARE_DYNAMIC_CLASS(ctlComboBoxXmlHandler) +public: + ctlComboBoxXmlHandler() : wxComboBoxXmlHandler() {} + virtual wxObject *DoCreateResource(); + virtual bool CanHandle(wxXmlNode *node); +}; + + +#endif diff --git a/include/ctl/xh_ctltree.h b/include/ctl/xh_ctltree.h new file mode 100644 index 0000000..a9e7adc --- /dev/null +++ b/include/ctl/xh_ctltree.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// xh_ctltree.h - ctlTree handler +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef _WX_XH_CTLTREE_H_ +#define _WX_XH_CTLTREE_H_ + +#include "wx/xrc/xmlres.h" +#include "wx/xrc/xh_tree.h" + +//class WXDLLIMPEXP_XRC +class ctlTreeXmlHandler : public wxTreeCtrlXmlHandler +{ + DECLARE_DYNAMIC_CLASS(ctlTreeXmlHandler) +public: + ctlTreeXmlHandler() : wxTreeCtrlXmlHandler() {} + virtual wxObject *DoCreateResource(); + virtual bool CanHandle(wxXmlNode *node); +}; + + +#endif diff --git a/include/ctl/xh_sqlbox.h b/include/ctl/xh_sqlbox.h new file mode 100644 index 0000000..f744b0b --- /dev/null +++ b/include/ctl/xh_sqlbox.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// xh_sqlbox.h - wxSqlBox handler +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef _WX_XH_SQLBOX_H_ +#define _WX_XH_SQLBOX_H_ + + +#include "wx/xrc/xmlres.h" + +//class WXDLLIMPEXP_XRC +class ctlSQLBoxXmlHandler : public wxXmlResourceHandler +{ + DECLARE_DYNAMIC_CLASS(ctlSQLBoxXmlHandler) +public: + ctlSQLBoxXmlHandler(); + virtual wxObject *DoCreateResource(); + virtual bool CanHandle(wxXmlNode *node); +}; + + +#endif // _WX_XH_SQLBOX_H_ diff --git a/include/ctl/xh_timespin.h b/include/ctl/xh_timespin.h new file mode 100644 index 0000000..d1a8f63 --- /dev/null +++ b/include/ctl/xh_timespin.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// xh_timespin.h - wxTimeSpinCtrl handler +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef _WX_XH_TIMESPIN_H_ +#define _WX_XH_TIMESPIN_H_ + + +#include "wx/xrc/xmlres.h" + +//class WXDLLIMPEXP_XRC +class wxTimeSpinXmlHandler : public wxXmlResourceHandler +{ + DECLARE_DYNAMIC_CLASS(wxTimeSpinXmlHandler) +public: + wxTimeSpinXmlHandler(); + virtual wxObject *DoCreateResource(); + virtual bool CanHandle(wxXmlNode *node); +}; + + +#endif // _WX_XH_TIMESPIN_H_ diff --git a/include/db/module.mk b/include/db/module.mk new file mode 100644 index 0000000..fe82643 --- /dev/null +++ b/include/db/module.mk @@ -0,0 +1,20 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/db/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/db/pgConn.h \ + include/db/pgQueryThread.h \ + include/db/pgQueryResultEvent.h \ + include/db/pgSet.h + +EXTRA_DIST += \ + include/db/module.mk + diff --git a/include/db/pgConn.h b/include/db/pgConn.h new file mode 100644 index 0000000..19d9d5c --- /dev/null +++ b/include/db/pgConn.h @@ -0,0 +1,313 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgConn.h - PostgreSQL Connection class +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGCONN_H +#define PGCONN_H + +// wxWindows headers +#include + +// PostgreSQL headers +#include + +// App headers +#include "pgSet.h" + +// status enums +enum +{ + PGCONN_OK = CONNECTION_OK, + PGCONN_BAD = CONNECTION_BAD, + PGCONN_REFUSED, + PGCONN_DNSERR, + PGCONN_ABORTED, // connect user aborted + PGCONN_BROKEN, // tcp/pipe broken + PGCONN_SSHTUNNEL_ERROR +}; + +enum +{ + PGCONN_EMPTY_QUERY = PGRES_EMPTY_QUERY, + PGCONN_COMMAND_OK = PGRES_COMMAND_OK, + PGCONN_TUPLES_OK = PGRES_TUPLES_OK, + PGCONN_COPY_OUT = PGRES_COPY_OUT, + PGCONN_COPY_IN = PGRES_COPY_IN, + PGCONN_BAD_RESPONSE = PGRES_BAD_RESPONSE, + PGCONN_NONFATAL_ERROR = PGRES_NONFATAL_ERROR, + PGCONN_FATAL_ERROR = PGRES_FATAL_ERROR +}; + +enum +{ + PGCONN_TXSTATUS_IDLE = PQTRANS_IDLE, + PGCONN_TXSTATUS_ACTIVE = PQTRANS_ACTIVE, + PGCONN_TXSTATUS_INTRANS = PQTRANS_INTRANS, + PGCONN_TXSTATUS_INERROR = PQTRANS_INERROR, + PGCONN_TXSTATUS_UNKNOWN = PQTRANS_UNKNOWN +}; + +// Our version of a pgNotify +typedef struct pgNotification +{ + wxString name; + int pid; + wxString data; +} pgNotification; + +// An error record +typedef struct pgError +{ + wxString severity; + wxString sql_state; + wxString msg_primary; + wxString msg_detail; + wxString msg_hint; + wxString statement_pos; + wxString internal_pos; + wxString internal_query; + wxString context; + wxString source_file; + wxString source_line; + wxString source_function; + wxString formatted_msg; + + void SetError(PGresult *_res = NULL, wxMBConv *_conv = NULL); +} pgError; + +class pgConn +{ +public: + pgConn(const wxString &server = wxT(""), const wxString &service = wxT(""), const wxString &hostaddr = wxT(""), + const wxString &database = wxT(""), const wxString &username = wxT(""), const wxString &password = wxT(""), + int port = 5432, const wxString &rolename = wxT(""), int sslmode = 0, OID oid = 0, + const wxString &applicationname = wxT("pgAdmin"), + const wxString &sslcert = wxT(""), const wxString &sslkey = wxT(""), const wxString &sslrootcert = wxT(""), const wxString &sslcrl = wxT(""), + const bool sslcompression = true); + ~pgConn(); + + bool IsSuperuser(); + bool HasPrivilege(const wxString &objTyp, const wxString &objName, const wxString &priv); + bool HasFeature(int feature = 0, bool forceCheck = false); + bool BackendMinimumVersion(int major, int minor); + bool BackendMinimumVersion(int major, int minor, int patch); + bool EdbMinimumVersion(int major, int minor); + wxString SystemNamespaceRestriction(const wxString &nsp); + int GetMajorVersion() const + { + return majorVersion; + } + int GetMinorVersion() const + { + return minorVersion; + } + bool GetIsEdb(); + bool GetIsGreenplum(); + bool GetIsHawq(); + wxString EncryptPassword(const wxString &user, const wxString &password); + wxString qtDbString(const wxString &value); + pgConn *Duplicate(const wxString &_appName = wxT("")); + + static void ExamineLibpqVersion(); + static double GetLibpqVersion() + { + return libpqVersion; + } + + static bool IsValidServerEncoding(int encid) + { + return pg_valid_server_encoding_id(encid) == 0 ? false : true; + } + + void Close(); + bool Reconnect(); + bool ExecuteVoid(const wxString &sql, bool reportError = true); + wxString ExecuteScalar(const wxString &sql, bool reportError = true); + pgSet *ExecuteSet(const wxString &sql, bool reportError = true); + void CancelExecution(void); + + wxString GetHostAddr() const + { + return save_hostaddr; + } + wxString GetService() const + { + return save_service; + } + wxString GetUser() const + { + return conn ? wxString(PQuser(conn), *conv) : wxT(""); + } + wxString GetPassword() const + { + return conn ? wxString(PQpass(conn), *conv) : wxT(""); + } + wxString GetRole() const + { + return dbRole; + } + wxString GetHost() const + { + return dbHost; + } + wxString GetHostName() const + { + return dbHostName; + } + wxString GetDbname() const + { + return save_database; + } + wxString GetApplicationName() const + { + return save_applicationname; + } + wxString GetSSLCert() const + { + return save_sslcert; + } + wxString GetSSLKey() const + { + return save_sslkey; + } + wxString GetSSLRootCert() const + { + return save_sslrootcert; + } + wxString GetSSLCrl() const + { + return save_sslcrl; + } + bool GetSSLCompression() const + { + return save_sslcompression; + } + wxString GetName() const; + bool GetNeedUtfConnectString() + { + return utfConnectString; + } + int GetPort() const + { + return conn ? atoi(PQport(conn)) : 0; + }; + wxString GetTTY() const + { + return conn ? wxString(PQtty(conn), *conv) : wxT(""); + } + wxString GetOptions() const + { + return conn ? wxString(PQoptions(conn), *conv) : wxT(""); + } + int GetSslMode() const + { + return save_sslmode; + } + wxString GetSslModeName(); + int GetBackendPID() const + { + return conn ? PQbackendPID(conn) : 0; + } + int GetStatus() const; + int GetLastResultStatus() const + { + return lastResultStatus; + } + bool IsAlive(); + wxString GetLastError() const; + pgError GetLastResultError() const + { + return lastResultError; + } + wxString GetVersionString(); + OID GetLastSystemOID() const + { + return lastSystemOID; + } + OID GetDbOid() const + { + return dbOid; + } + void RegisterNoticeProcessor(PQnoticeProcessor proc, void *arg); + wxMBConv *GetConv() + { + return conv; + }; + + void LogError(const bool quiet = false); + + bool IsSSLconnected(); + PGconn *connection() + { + return conn; + } + void Notice(const char *msg); + pgNotification *GetNotification(); + int GetTxStatus(); + + void Reset(); + + bool StartCopy(const wxString query); + bool PutCopyData(const char *data, long count); + bool EndPutCopy(const wxString errormsg); + bool GetCopyFinalStatus(void); + + bool TableHasColumn(wxString schemaname, wxString tblname, const wxString &colname); + +protected: + PGconn *conn; + PGcancel *m_cancelConn; + wxMutex m_cancelConnMutex; + int lastResultStatus; + + int connStatus; + + void SetLastResultError(PGresult *res, const wxString &msg = wxEmptyString); + void SetConnCancel(void); + void ResetConnCancel(void); + pgError lastResultError; + + wxMBConv *conv; + bool needColQuoting, utfConnectString; + wxString dbRole, dbHost, dbHostName; + OID lastSystemOID; + OID dbOid; + + void *noticeArg; + PQnoticeProcessor noticeProc; + static double libpqVersion; + + friend class pgQueryThread; + +private: + bool DoConnect(); + bool Initialize(); + + wxString qtString(const wxString &value); + + bool features[32]; + int minorVersion, majorVersion, patchVersion; + bool isEdb; + bool isGreenplum; + bool isHawq; + + wxString reservedNamespaces; + wxString connstr; + + wxString save_server, save_service, save_hostaddr, save_database, save_username, save_password, save_rolename, save_applicationname; + wxString save_sslcert, save_sslkey, save_sslrootcert, save_sslcrl; + int save_port, save_sslmode; + bool save_sslcompression; + OID save_oid; +}; + +#endif + + diff --git a/include/db/pgQueryResultEvent.h b/include/db/pgQueryResultEvent.h new file mode 100644 index 0000000..f47ce66 --- /dev/null +++ b/include/db/pgQueryResultEvent.h @@ -0,0 +1,79 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgQueryResultEvent.h - Query Result Event from the pgQueryThread +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGQUERYRESULTEVENT_H +#define PGQUERYRESULTEVENT_H + +#include "wx/wx.h" +#include "wx/event.h" + +class pgBatchQuery; + +extern const wxEventType PGQueryResultEvent; + + +class pgQueryResultEvent : public wxCommandEvent +{ +public: + pgQueryResultEvent(unsigned long _thrdId, pgBatchQuery *_qry, int _id = 0); + pgQueryResultEvent(const pgQueryResultEvent &_ev); + + // Required for sending with wxPostEvent() + wxEvent *Clone() const + { + return new pgQueryResultEvent(*this); + } + + pgBatchQuery *GetQuery() + { + return m_query; + } + unsigned long GetThreadID() + { + return m_thrdId; + } + + enum + { + PGQ_RESULT_ERROR = -8, + PGQ_EXECUTION_CANCELLED = -7, + PGQ_ERROR_CONSUME_INPUT = -6, + PGQ_ERROR_SEND_QUERY = -5, + PGQ_ERROR_EXECUTE_CALLABLE = -4, + PGQ_ERROR_PREPARE_CALLABLE = -3, + PGQ_STRING_INVALID = -2, + PGQ_CONN_LOST = -1, + }; + +private: + pgBatchQuery *m_query; + // Thread Id (pgQueryThread) + unsigned long m_thrdId; +}; + +typedef void (wxEvtHandler::*pgQueryResultEventFunc)(pgQueryResultEvent &); + +// This #define simplifies the one below, and makes the syntax less +// ugly if you want to use Connect() instead of an event table. +#define pgQueryResultEventHandler(func) \ + (wxObjectEventFunction)(wxEventFunction)(wxCommandEventFunction) \ + wxStaticCastEvent(pgQueryResultEventFunc, &func) + +// Define the event table entry. Yes, it really *does* end in a comma. +#define EVT_PGQUERYRESULT(id, fn) \ + DECLARE_EVENT_TABLE_ENTRY(PGQueryResultEvent, id, wxID_ANY, \ + pgQueryResultEventHandler(fn), (wxObject*) NULL), + +#define EVT_PGQUERYRESULT_RANGE(id1, id2, fn) \ + DECLARE_EVENT_TABLE_ENTRY(PGQueryResultEvent, id1, id2, \ + pgQueryResultEventHandler(fn), (wxObject*) NULL), + +#endif // PGQUERYRESULTEVENT_H diff --git a/include/db/pgQueryThread.h b/include/db/pgQueryThread.h new file mode 100644 index 0000000..0946836 --- /dev/null +++ b/include/db/pgQueryThread.h @@ -0,0 +1,290 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgQueryThread.h - PostgreSQL threaded query class header +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGQUERYTHREAD_H +#define PGQUERYTHREAD_H + +#include "wx/wx.h" +#include "wx/event.h" +#include "db/pgConn.h" + +// Forward declaration +class pgSet; +class pgQueryThread; +class pgBatchQuery; + +// Support for the IN & INOUT parameters type +class pgParam : public wxObject +{ +public: + enum + { + PG_PARAM_IN = 1, + PG_PARAM_OUT = 2, + PG_PARAM_INOUT = 3, + PG_PARAM_VARIADIC = 4, + PG_PARAM_TABLE = 5 + }; + + // Any data + // + // This constructor won't call the functions - 'htonl' or 'htons' + // It will be the responsibility of the caller to take care + // to call 'htonl' or 'htons' depending on requirements. + // + // NOTE: + // This data will be owned by pgParam object and will be released. + pgParam(Oid _type, void *_val, int _len, short mode = PG_PARAM_IN); + + // wxString data + pgParam(Oid _type, wxString *_val, wxMBConv *_conv = NULL, + short mode = PG_PARAM_IN); + + ~pgParam(); + + // Returns 0 for text type and 1 for otherwise + int GetFormat(); + + Oid GetType() + { + return m_type; + } + short GetMode() + { + return m_mode; + } + +protected: + Oid m_type; + void *m_val; + int m_len; + short m_format; + // Modes are required by EnterpriseDB's callable statement + short m_mode; + + // Do not allow copy construction and shadow-copy + // to avoid ownership + // Force to use an pointer + pgParam(const pgParam &) + { + wxASSERT(0); + } + pgParam &operator= (const pgParam &) + { + wxASSERT(0); + return *this; + } + + friend class pgConn; + friend class pgQueryThread; +}; + +WX_DEFINE_ARRAY_PTR(pgParam *, pgParamsArray); + +class pgBatchQuery : public wxObject +{ +public: + pgBatchQuery(const wxString &_query, pgParamsArray *_params = NULL, + long _eventId = -1, void *_data = NULL, bool _useCallable = false, + int _resultToRetrieve = 0) + : m_query(_query), m_params(_params), m_eventID(_eventId), m_data(_data), + m_useCallable(_useCallable), m_resToRetrieve(_resultToRetrieve), + m_returnCode(-1), m_resultSet(NULL), m_rowsInserted(-1), m_insertedOid(-1) + { + // Do not honour the empty query string + wxASSERT(!_query.IsEmpty()); + } + ~pgBatchQuery(); + + bool Release(); + + pgSet *ResultSet() + { + return m_resultSet; + } + + int ReturnCode() + { + return m_returnCode; + } + + const wxString &GetMessage() + { + return m_message; + } + + long RowInserted() + { + return m_rowsInserted; + } + + const wxString &GetErrorMessage(); + +protected: + wxString m_query; // Query + pgParamsArray *m_params; // parameters + long m_eventID; // Event ID + void *m_data; // Data to be send with event + bool m_useCallable; // Use EnterpriseDB callable statement if possible + int m_resToRetrieve; // Which result to be retrieved + int m_returnCode; // Return code + pgSet *m_resultSet; // Result-Set + long m_rowsInserted; // No of rows inserted + Oid m_insertedOid; // Inserted Oid + wxString m_message; // Message generated during query execution + pgError m_err; // Error + +private: + // Do not allow copy construction and '=' operator (shadow copying) + // to avoid ownership of parameters and result-set + // + // This will force this class to be used as an pointer only. + pgBatchQuery(const pgBatchQuery &) + { + wxASSERT(0); + } + pgBatchQuery &operator= (const pgBatchQuery &) + { + wxASSERT(0); + return *this; + } + + friend class pgQueryThread; +}; +WX_DEFINE_ARRAY_PTR(pgBatchQuery *, pgBatchQueryArray); + +class pgQueryThread : public wxThread +{ +public: + // For running a single query (Used by few components) + pgQueryThread(pgConn *_conn, const wxString &qry, int resultToRetrieve = -1, + wxWindow *_caller = 0, long eventId = 0, void *_data = 0); + + // Support for multiple queries support + pgQueryThread(pgConn *_conn, wxEvtHandler *_caller = NULL, + PQnoticeProcessor _processor = NULL, void *_noticeHandler = NULL); + + ~pgQueryThread(); + + bool HasMultipleQueriesSupport() + { + return m_multiQueries; + } + + bool SupportCallableStatement() + { + return m_useCallable; + } + + void SetEventOnCancellation(bool eventOnCancelled); + + void AddQuery( + const wxString &_qry, pgParamsArray *_params = NULL, + long _eventId = 0, void *_data = NULL, bool _useCallable = false, + int _resultToRetrieve = -1); + + virtual void *Entry(); + bool DataValid(int _idx = -1) const + { + if (_idx == -1) + _idx = m_currIndex; + return (_idx >= 0 && _idx > m_currIndex ? false : (m_queries[_idx]->m_resultSet != NULL)); + } + + pgConn *GetConn() + { + return m_conn; + } + + pgSet *DataSet(int _idx = -1) + { + if (_idx == -1) + _idx = m_currIndex; + return (_idx >= 0 && _idx > m_currIndex ? NULL : m_queries[_idx]->m_resultSet); + } + + int ReturnCode(int _idx = -1) const + { + if (_idx == -1) + _idx = m_currIndex; + return (_idx >= 0 && _idx > m_currIndex ? -1 : m_queries[_idx]->m_returnCode); + } + + long RowsInserted(int _idx = -1) const + { + if (_idx == -1) + _idx = m_currIndex; + return (_idx >= 0 && _idx > m_currIndex ? -1L : m_queries[_idx]->m_rowsInserted); + } + + Oid InsertedOid(int _idx = -1) const + { + if (_idx == -1) + _idx = m_currIndex; + return (_idx >= 0 && _idx > m_currIndex ? -1L : m_queries[_idx]->m_insertedOid); + } + + inline void CancelExecution() + { + m_cancelled = true; + } + + inline size_t GetNumberQueries() + { + return m_queries.GetCount(); + } + + size_t QueriesExecuted() + { + return m_currIndex + 1; + } + + wxString GetMessagesAndClear(int _idx = -1); + void AppendMessage(const wxString &_str); + + int DeleteReleasedQueries(); + + pgError GetResultError(int idx = -1); + +private: + int Execute(); + int RaiseEvent(int _retval = 0); + + // Queries to be executed + pgBatchQueryArray m_queries; + // Current running query index + int m_currIndex; + // Connection object + pgConn *m_conn; + // Execution cancelled? + bool m_cancelled; + // Raise events even when cancelled the execution + bool m_eventOnCancellation; + // Does this thread support multiple queries + bool m_multiQueries; + // Use EDB callable statement (if available and require) + bool m_useCallable; + // Is executing a query + bool m_executing; + // Queries are being accessed at this time + wxMutex m_queriesLock; + // When one thread is accesing messages, other should not be able to access it + wxCriticalSection m_criticalSection; + // Event Handler + wxEvtHandler *m_caller; + // Database server notice-processor + PQnoticeProcessor m_processor; + // Notice Handler + void *m_noticeHandler; + +}; + +#endif diff --git a/include/db/pgSet.h b/include/db/pgSet.h new file mode 100644 index 0000000..daf951c --- /dev/null +++ b/include/db/pgSet.h @@ -0,0 +1,244 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgSet.h - PostgreSQL ResultSet class +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGSET_H +#define PGSET_H + +// wxWindows headers +#include +#include + +// PostgreSQL headers +#include + +#include "utils/misc.h" + +typedef enum +{ + PGTYPCLASS_NUMERIC = 1, + PGTYPCLASS_BOOL, + PGTYPCLASS_STRING, + PGTYPCLASS_DATE, + PGTYPCLASS_OTHER +} pgTypClass; + +class pgConn; + +// Class declarations +class pgSet +{ +public: + pgSet(); + pgSet(PGresult *newRes, pgConn *newConn, wxMBConv &cnv, bool needColQt); + ~pgSet(); + long NumRows() const + { + return nRows; + } + long NumCols() const + { + return nCols; + } + + void MoveNext() + { + if (pos <= nRows) pos++; + } + void MovePrevious() + { + if (pos > 0) pos--; + } + void MoveFirst() + { + if (nRows) pos = 1; + else pos = 0; + } + void MoveLast() + { + pos = nRows; + } + void Locate(long l) + { + pos = l; + } + long CurrentPos() const + { + return pos; + } + bool Bof() const + { + return (!nRows || pos < 1); + } + bool Eof() const + { + return (!nRows || pos > nRows); + } + wxString ColName(const int col) const; + OID ColTypeOid(const int col) const; + long ColTypeMod(const int col) const; + wxString ColType(const int col) const; + wxString ColFullType(const int col) const; + pgTypClass ColTypClass(const int col) const; + + OID GetInsertedOid() const + { + return PQoidValue(res); + } + long GetInsertedCount() const; + int ColSize(const int col) const + { + return PQfsize(res, col); + } + bool IsNull(const int col) const + { + return (PQgetisnull(res, pos - 1, col) != 0); + } + int ColScale(const int col) const; + int ColNumber(const wxString &colName) const; + bool HasColumn(const wxString &colname) const; + + + wxString GetVal(const int col) const; + wxString GetVal(const wxString &col) const; + long GetLong(const int col) const; + long GetLong(const wxString &col) const; + bool GetBool(const int col) const; + bool GetBool(const wxString &col) const; + double GetDouble(const int col) const; + double GetDouble(const wxString &col) const; + wxDateTime GetDateTime(const int col) const; + wxDateTime GetDateTime(const wxString &col) const; + wxDateTime GetDate(const int col) const; + wxDateTime GetDate(const wxString &col) const; + wxULongLong GetLongLong(const int col) const; + wxULongLong GetLongLong(const wxString &col) const; + OID GetOid(const int col) const; + OID GetOid(const wxString &col) const; + + char *GetCharPtr(const int col) const; + char *GetCharPtr(const wxString &col) const; + + wxMBConv &GetConversion() const + { + return conv; + } + + wxString GetCommandStatus() const + { + if (res) + { + return wxString(PQcmdStatus(res), conv); + } + return wxEmptyString; + } + +protected: + pgConn *conn; + PGresult *res; + long pos, nRows, nCols; + wxString ExecuteScalar(const wxString &sql) const; + wxMBConv &conv; + bool needColQuoting; + mutable wxArrayString colTypes, colFullTypes; + wxArrayInt colClasses; +}; + + + +class pgSetIterator +{ +public: + pgSetIterator(pgSet *s); + pgSetIterator(pgConn *conn, const wxString &sql); + ~pgSetIterator(); + + bool RowsLeft(); + bool MovePrev(); + bool IsValid() + { + return set != 0; + } + pgSet *Set() + { + return set; + } + + wxString GetVal(const int col) const + { + return set->GetVal(col); + } + wxString GetVal(const wxString &col) const + { + return set->GetVal(col); + } + long GetLong(const int col) const + { + return set->GetLong(col); + } + long GetLong(const wxString &col) const + { + return set->GetLong(col); + } + bool GetBool(const int col) const + { + return set->GetBool(col); + } + bool GetBool(const wxString &col) const + { + return set->GetBool(col); + } + double GetDouble(const int col) const + { + return set->GetDouble(col); + } + double GetDouble(const wxString &col) const + { + return set->GetDouble(col); + } + wxDateTime GetDateTime(const int col) const + { + return set->GetDateTime(col); + } + wxDateTime GetDateTime(const wxString &col) const + { + return set->GetDateTime(col); + } + wxDateTime GetDate(const int col) const + { + return set->GetDate(col); + } + wxDateTime GetDate(const wxString &col) const + { + return set->GetDate(col); + } + wxULongLong GetLongLong(const int col) const + { + return set->GetLongLong(col); + } + wxULongLong GetLongLong(const wxString &col) const + { + return set->GetLongLong(col); + } + OID GetOid(const int col) const + { + return set->GetOid(col); + } + OID GetOid(const wxString &col) const + { + return set->GetOid(col); + } + +protected: + pgSet *set; + bool first; +}; + +#endif diff --git a/include/dd/dditems/figures/ddColumnFigure.h b/include/dd/dditems/figures/ddColumnFigure.h new file mode 100644 index 0000000..4cc05d3 --- /dev/null +++ b/include/dd/dditems/figures/ddColumnFigure.h @@ -0,0 +1,115 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddColumnFigure.h - Minimal Composite Figure for a column of a table +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDCOLUMNFIGURE_H +#define DDCOLUMNFIGURE_H +#include "hotdraw/figures/hdAttributeFigure.h" +#include "dd/dditems/figures/ddColumnKindIcon.h" +#include "dd/dditems/figures/ddColumnOptionIcon.h" +#include "dd/dditems/figures/ddTextTableItemFigure.h" + +class ddTableFigure; +class ddRelationshipItem; + +//Minimal overhead composite figure +class ddColumnFigure : public hdAttributeFigure +{ +public: + ddColumnFigure(wxString &columnName, ddTableFigure *owner, ddRelationshipItem *sourceFk = NULL); + ddColumnFigure(wxString &columnName, ddTableFigure *owner, ddColumnOptionType option, bool isGenFk, bool isPkColumn, wxString colDataType, int p = -1, int s = -1, int ukIdx = -1, ddRelationshipItem *sourceFk = NULL, ddRelationshipItem *usedAsFkDestFor = NULL ); + void Init(wxString &columnName, ddTableFigure *owner, ddRelationshipItem *sourceFk = NULL); + ~ddColumnFigure(); + virtual void AddPosForNewDiagram(); + virtual void RemovePosOfDiagram(int posIdx); + virtual void basicMoveBy(int posIdx, int x, int y); + virtual void moveTo(int posIdx, int x, int y); + virtual void setOwnerTable(ddTableFigure *table); + virtual bool containsPoint(int posIdx, int x, int y); + virtual hdMultiPosRect &getBasicDisplayBox(); + virtual void basicDraw(wxBufferedDC &context, hdDrawingView *view); + virtual void basicDrawSelected(wxBufferedDC &context, hdDrawingView *view); + virtual hdIFigure *findFigure(int posIdx, int x, int y); + virtual hdIFigure *getFigureAt(int pos); + virtual hdITool *CreateFigureTool(hdDrawingView *view, hdITool *defaultTool); + virtual ddTableFigure *getOwnerTable(); + void displayBoxUpdate(); + bool isNull(); + bool isNotNull(); + bool isNone(); + bool isPrimaryKey(); + void disablePrimaryKey(); + void enablePrimaryKey(); + bool isUniqueKey(); + bool isUniqueKey(int uniqueIndex); + int getUniqueConstraintIndex(); + void setUniqueConstraintIndex(int i); + bool isPlain(); + void setColumnKindToNone(); + void toggleColumnKind(ddColumnType type, hdDrawingView *view = NULL); + void setColumnOption(ddColumnOptionType type); + void setRightIconForColumn(); + ddColumnOptionType getColumnOption(); + ddDataType getDataType(); + void setDataType(ddDataType type); + wxString &getColumnName(bool datatype = false); + void setColumnName(wxString name); + bool isForeignKey(); + bool isGeneratedForeignKey(); + bool isUserCreatedForeignKey(); + bool isForeignKeyFromPk(); + wxString generateSQL(bool forAlterColumn = false); + bool isFkNameGenerated(); + void activateGenFkName(); + void deactivateGenFkName(); + ddRelationshipItem *getFkSource(); + void setFkSource(ddRelationshipItem *newColumn); + int getPrecision(); + void setPrecision(int n); + int getScale(); + void setScale(int n); + void setAsUserCreatedFk(ddRelationshipItem *relatedFkItem); + ddRelationshipItem *getRelatedFkItem(); + bool validateColumn(wxString &errors); + void setTextColour(wxColour colour); + ddColumnKindIcon *getKindImage() + { + return kindImage; + }; + ddColumnOptionIcon *getOptionImage() + { + return optionImage; + }; + ddTextTableItemFigure *getColumnText() + { + return columnText; + }; + + /* Disable right now, it can be useful at the future when db designer will be improved again + int getPgAttNumCol() { return pgAttNumColNumber;}; + void setPgAttNumCol(int attnum) { pgAttNumColNumber = attnum; }; + */ + wxString getRawDataType(); + +protected: + ddColumnKindIcon *kindImage; + ddColumnOptionIcon *optionImage; + ddTextTableItemFigure *columnText; + ddTableFigure *ownerTable; + ddRelationshipItem *usedAsFkDestFor; + bool generateFkName; + int pgAttNumColNumber; + +private: + ddRelationshipItem *fkSource; + + +}; +#endif diff --git a/include/dd/dditems/figures/ddColumnKindIcon.h b/include/dd/dditems/figures/ddColumnKindIcon.h new file mode 100644 index 0000000..a7db41d --- /dev/null +++ b/include/dd/dditems/figures/ddColumnKindIcon.h @@ -0,0 +1,72 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddColumnKindIcon.h - Figure container for kind of Column Images +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDCOLUMNKINDICON_H +#define DDCOLUMNKINDICON_H + +#include "hotdraw/figures/hdAbstractMenuFigure.h" + +class ddColumnFigure; + +enum ddColumnType +{ + pk = 321, + uk, + none, + noaction //no action kind means column type don't have right now a useful value +}; + +enum +{ + MNU_DDCTPKEY = 321, + MNU_DDCTUKEY +}; + +class ddColumnKindIcon : public hdAbstractMenuFigure +{ +public: + ddColumnKindIcon(ddColumnFigure *owner); + ~ddColumnKindIcon(); + virtual void OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view = NULL); + virtual void createMenu(wxMenu &mnu); + virtual void basicDraw(wxBufferedDC &context, hdDrawingView *view); + virtual void basicDrawSelected(wxBufferedDC &context, hdDrawingView *view); + virtual void toggleColumnKind(ddColumnType type, hdDrawingView *view = NULL, bool interaction = true); + virtual int getWidth(); + virtual int getHeight(); + bool isNone(); + bool isPrimaryKey(); + bool isForeignKey(); + void disableUniqueKey(); + void disablePrimaryKey(); + void enablePrimaryKey(); + ddColumnFigure *getOwnerColumn(); + bool isUniqueKey(); + bool isUniqueKey(int uniqueIndex); + int getUniqueConstraintIndex(); + void setUniqueConstraintIndex(int i); + void setRightIconForColumn(); + void setPrimaryKey(bool value); + void setUkIndex(int ukIdx); +protected: + +private: + ddColumnFigure *ownerColumn; + wxBitmap *iconToDraw; + wxBitmap icon; + int ukIndex; + bool isPk; + + //multiple Uk management at table + void syncUkIndexes(); + bool uniqueConstraintManager(bool ukCol, hdDrawingView *view = NULL, bool interaction = true); +}; +#endif diff --git a/include/dd/dditems/figures/ddColumnOptionIcon.h b/include/dd/dditems/figures/ddColumnOptionIcon.h new file mode 100644 index 0000000..f4046e9 --- /dev/null +++ b/include/dd/dditems/figures/ddColumnOptionIcon.h @@ -0,0 +1,54 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddColumnOptionIcon.h - +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDCOLUMNOPTIONICON_H +#define DDCOLUMNOPTIONICON_H + +#include "hotdraw/figures/hdAbstractMenuFigure.h" + +class ddColumnFigure; + +enum ddColumnOptionType +{ + null = 321, + notnull +}; + +enum +{ + MNU_COLNULL = 321, + MNU_COLNOTNULL +}; + +class ddColumnOptionIcon : public hdAbstractMenuFigure +{ +public: + ddColumnOptionIcon(ddColumnFigure *owner); + ~ddColumnOptionIcon(); + virtual void OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view = NULL); + virtual void createMenu(wxMenu &mnu); + virtual void basicDraw(wxBufferedDC &context, hdDrawingView *view); + virtual void basicDrawSelected(wxBufferedDC &context, hdDrawingView *view); + virtual void changeIcon(ddColumnOptionType type); + virtual int getWidth(); + virtual int getHeight(); + ddColumnOptionType getOption(); + ddColumnFigure *getOwnerColumn(); + +protected: + +private: + ddColumnOptionType colOption; + ddColumnFigure *ownerColumn; + wxBitmap *iconToDraw; + wxBitmap icon; +}; +#endif diff --git a/include/dd/dditems/figures/ddRelationshipFigure.h b/include/dd/dditems/figures/ddRelationshipFigure.h new file mode 100644 index 0000000..b9c1202 --- /dev/null +++ b/include/dd/dditems/figures/ddRelationshipFigure.h @@ -0,0 +1,113 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddRelationshipFigure.h - Figure to draw foreign keys between tables. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDRELATIONSHIPFIGURE_H +#define DDRELATIONSHIPFIGURE_H +#include "hotdraw/figures/hdLineConnection.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/dditems/figures/ddColumnFigure.h" + +enum +{ + MNU_MANDATORYRELATIONSHIP = 321, + MNU_IDENTIFYINGRELATIONSHIP, + MNU_1MRELATIONSHIP, + MNU_DELETERELATIONSHIP, + MNU_FKCONSTRAINTNAME, + MNU_FKMATCHTYPESIMPLE, + MNU_FKMATCHTYPEFULL, + MNU_FKONDELETENOACTION, + MNU_FKONDELETERESTRICT, + MNU_FKONDELETECASCADE, + MNU_FKONDELETESETNULL, + MNU_FKONDELETESETDEFAULT, + MNU_FKONUPDATENOACTION, + MNU_FKONUPDATERESTRICT, + MNU_FKONUPDATECASCADE, + MNU_FKONUPDATESETNULL, + MNU_FKONUPDATESETDEFAULT, + MNU_FKEYFROMPKEY, + MNU_FKEYCUSTOMMAPPING, + MNU_FKEYFROMUKEYBASE //This constant should be always the last one to allow hack of multiple uk selection in submenu +}; + +enum actionKind +{ + FK_ACTION_NO = 600, + FK_RESTRICT, + FK_CASCADE, + FK_SETNULL, + FK_SETDEFAULT +}; +class ddRelationshipItem; + +WX_DECLARE_STRING_HASH_MAP( ddRelationshipItem *, columnsHashMap ); + + +class ddRelationshipFigure : public hdLineConnection +{ +public: + ddRelationshipFigure(); + ddRelationshipFigure(int posIdx, hdIFigure *figure1, hdIFigure *figure2); + ~ddRelationshipFigure(); + virtual void createMenu(wxMenu &mnu); + + void prepareFkForDelete(ddColumnFigure *column); + void updateForeignKey(); + void removeForeignKeys(); + void addExistingColumnFk(ddColumnFigure *startTablesourceCol, wxString destColumn); + bool getIdentifying(); + bool getOneToMany(); + bool getMandatory(); + void setOptionAtForeignKeys(ddColumnOptionType type); + void updatePkAtFkCols(); + bool isForeignKeyFromPk(); + virtual void connectEnd(hdIConnector *end, hdDrawingView *view = NULL); + virtual void connectStart(hdIConnector *start, hdDrawingView *view = NULL); + void disconnectStart(hdDrawingView *view = NULL); + void disconnectEnd(hdDrawingView *view = NULL); + void setFkFrom(bool primaryKey, int useUkIndex = -1, bool issueUpdateFk = false); + wxString generateSQL(wxString schemaName); + wxString getConstraintName(); + ddTableFigure *getStartTable(); + ddTableFigure *getEndTable(); + void changeFkOSTextColor(wxColour originalColour, wxColour fkColour, bool reset = false); + int getUkIndex(); + actionKind getOnUpdateAction(); + actionKind getOnDeleteAction(); + bool getMatchSimple(); + columnsHashMap &getItemsHashMap() + { + return chm; + }; + void initRelationValues(ddTableFigure *source, ddTableFigure *destination, int ukIdx, wxString constraint, actionKind onUpdate, actionKind onDelete, bool simpleMatch, bool identifying, bool oneToMany, bool mandatory, bool fromPk); + +protected: + virtual void basicDrawSelected(wxBufferedDC &context, hdDrawingView *view); + virtual void basicDraw(wxBufferedDC &context, hdDrawingView *view); + +private: + virtual void OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view); + bool fkFromPk; + bool fkMandatory; + bool fkOneToMany; + bool fkIdentifying; + bool matchSimple; + bool paintingFkColumns; + actionKind onUpdateAction, onDeleteAction; + wxString constraintName; + + int ukIndex; + columnsHashMap chm; + ddTableFigure *disconnectedEndTable; +}; + +#endif diff --git a/include/dd/dditems/figures/ddRelationshipItem.h b/include/dd/dditems/figures/ddRelationshipItem.h new file mode 100644 index 0000000..d9fd4ea --- /dev/null +++ b/include/dd/dditems/figures/ddRelationshipItem.h @@ -0,0 +1,52 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddRelationshipFigure.h - Item to keep track of foreign keys between tables in a relationship. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDRELATIONSHIPITEM_H +#define DDRELATIONSHIPITEM_H +#include "hotdraw/figures/hdLineConnection.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/dditems/figures/ddColumnFigure.h" + +class ddRelationshipItem : public hdObject +{ +public: + ddRelationshipItem(); + ddRelationshipItem(ddRelationshipFigure *owner, ddColumnFigure *originalColumn, ddTableFigure *destination, ddColumnOptionType type, ddColumnType colType, ddColumnFigure *existingColumn = NULL); + ~ddRelationshipItem(); + void initRelationshipItemValues(ddRelationshipFigure *owner, ddTableFigure *destination, bool fromExistingColumn, ddColumnFigure *fkCol, ddColumnFigure *sourceCol, wxString initialColName); + wxString originalStartColName; + ddColumnFigure *original; + ddColumnFigure *fkColumn; + + + wxString autoGenerateNameForFk(); + void syncAutoFkName(); + + ddTableFigure *getDestinationTable() + { + return destinationTable; + }; + bool isAutomaticallyGenerated(); + bool relationIsIdentifying(); + bool relationIsMandatory(); + bool isForeignKeyFromPk(); + wxString sourceTableName(); + wxString destTableName(); + + +private: + bool fkIsAutoGenerated; + ddTableFigure *destinationTable; + ddRelationshipFigure *ownerRel; + wxString generatedName; //avoid linux bug +}; + +#endif diff --git a/include/dd/dditems/figures/ddRelationshipTerminal.h b/include/dd/dditems/figures/ddRelationshipTerminal.h new file mode 100644 index 0000000..5f704af --- /dev/null +++ b/include/dd/dditems/figures/ddRelationshipTerminal.h @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddRelationshipTerminal.h - Draw inverse arrows at fk terminal based on kind of relationship. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDRELATIONSHIPTERMINAL_H +#define DDRELATIONSHIPTERMINAL_H +#include "hotdraw/figures/hdLineTerminal.h" +#include "hotdraw/utilities/hdPoint.h" +#include "dd/dditems/figures/ddRelationshipFigure.h" + + + +class ddRelationshipTerminal : public hdLineTerminal +{ +public: + ddRelationshipTerminal(ddRelationshipFigure *owner, bool endFigureTerminal); + ~ddRelationshipTerminal(); + virtual hdPoint &draw (wxBufferedDC &context, hdPoint &a, hdPoint &b, hdDrawingView *view); +protected: + +private: + double lastFactor; + ddRelationshipFigure *ownerFigure; + bool endTerminal; + hdPoint value; +}; +#endif diff --git a/include/dd/dditems/figures/ddTableFigure.h b/include/dd/dditems/figures/ddTableFigure.h new file mode 100644 index 0000000..129d82b --- /dev/null +++ b/include/dd/dditems/figures/ddTableFigure.h @@ -0,0 +1,191 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddTableFigure.h - Draw table figure of a model +// +//////////////////////////////////////////////////////////////////////////// + +#ifndef DDTABLEFIGURE_H +#define DDTABLEFIGURE_H +#include "hotdraw/figures/hdCompositeFigure.h" +#include "hotdraw/figures/hdRectangleFigure.h" +#include "hotdraw/figures/hdSimpleTextFigure.h" +#include "dd/dditems/figures/ddTextTableItemFigure.h" +#include "dd/dditems/figures/ddColumnFigure.h" +#include "dd/ddmodel/ddDatabaseDesign.h" + +class ddScrollBarHandle; +class ddRelationshipFigure; +class hdDrawing; + +class ddTableFigure : public hdCompositeFigure +{ +public: + ddTableFigure(wxString tableName, int x, int y); + ddTableFigure(wxString tableName, int posIdx, int x, int y); + void InitTableValues(wxArrayString UniqueKeysName, wxString primaryKeyName, int bdc, int bdi, int maxcolsi, int minidxsi, int maxidxsi, int colsrs, int colsw, int idxsrs, int idxsw); + void Init(wxString tableName, int x, int y); + hdMultiPosRect &getBasicDisplayBox(); + ~ddTableFigure(); + + //Diagrams related functions + virtual void AddPosForNewDiagram(); + virtual void RemovePosOfDiagram(int posIdx); + + //add remove items + ddColumnFigure *getColByName(wxString name); + void addColumn(int posIdx, ddColumnFigure *column); + void addColumnFromStorage(ddColumnFigure *column); + void syncInternalsPosAt(int posIdx, int x, int y); + void syncInternalsPosAt(wxArrayInt &x, wxArrayInt &y); + void removeColumn(int posIdx, ddColumnFigure *column); + + //movement + void manuallyNotifyChange(int posIdx) + { + changed(posIdx); + }; + virtual void basicMoveBy(int posIdx, int x, int y); + + //show messages to set fk destination + void setSelectFkDestMode(bool value); + + //delete hack tables + void processDeleteAlert(hdDrawing *drawing); + + //columns scrolls + void updateTableSize(bool notifyChange = true); + void recalculateColsPos(int posIdx); + void setColsRowsWindow(int num); + hdMultiPosRect &getColsSpace(); + hdMultiPosRect &getFullSpace(); + hdMultiPosRect &getTitleRect(); + int getTotalColumns(); + int getColumnsWindow(); + int getTopColWindowIndex(); + void setColumnsWindow(int posIdx, int value, bool maximize = false); + void columnsWindowUp(int posIdx); + void columnsWindowDown(int posIdx); + int getFiguresMaxWidth(); + int getColDefaultHeight(wxFont font); + + //metadata + wxString getTableName(); + wxString getShortTableName(); + wxString generateSQLCreate(wxString schemaName); + wxString generateSQLAlterPks(wxString schemaName); + wxString generateSQLAlterFks(wxString schemaName); + wxString generateSQLAlterUks(wxString schemaName); + wxString generateAltersTable(pgConn *connection, wxString schemaName, ddDatabaseDesign *design); + wxArrayString getAllColumnsNames(); + wxArrayString getAllFkSourceColsNames(bool pk, int ukIndex = -1); + ddColumnFigure *getColumnByName(wxString name); + bool validateTable(wxString &errors); + + //uk pk constraints + void setPkConstraintName(wxString name); + wxString getPkConstraintName(); + wxArrayString &getUkConstraintsNames(); + bool disablePrimaryKey(); + bool enablePrimaryKey(); + + //fk related + void updateFkObservers(); + void updateSizeOfObservers(); + void prepareForDeleteFkColumn(ddColumnFigure *column); + + //ScrollBar persistence related + int getBeginDrawCols() + { + return beginDrawCols; + }; + int getBeginDrawIdxs() + { + return beginDrawIdxs; + }; + int getMaxColIndex() + { + return maxColIndex; + }; + int getMinIdxIndex() + { + return minIdxIndex; + }; + int getMaxIdxIndex() + { + return maxIdxIndex; + }; + int getColsRowsSize() + { + return colsRowsSize; + }; + int getColsWindow() + { + return colsWindow; + }; + int getIdxsRowsSize() + { + return idxsRowsSize; + }; + int getIdxsWindow() + { + return idxsWindow; + }; + + //Temporary alter table instead of create Helper + bool getBelongsToSchema() + { + return belongsToSchema; + }; + void setBelongsToSchema(bool value) + { + belongsToSchema = value; + }; + +protected: + //drawing + virtual void basicDraw(wxBufferedDC &context, hdDrawingView *view); + virtual void basicDrawSelected(wxBufferedDC &context, hdDrawingView *view); + +private: + //Temporary alter table instead of create Helper + bool belongsToSchema; + + //Main Rectangle Sizes + hdMultiPosRect fullSizeRect, titleRect, titleColsRect, colsRect, titleIndxsRect, indxsRect; + hdMultiPosRect unScrolledColsRect, unScrolledFullSizeRect, unScrolledTitleRect; + + //Rectangle item counters + int colsRowsSize, colsWindow, idxsRowsSize, idxsWindow; + + //vector indexes + int maxColIndex, minIdxIndex, maxIdxIndex; + + //position + int beginDrawCols, beginDrawIdxs; + + //Default Figures + hdRectangleFigure *rectangleFigure; + ddTextTableItemFigure *tableTitle; + + //helper variables + bool selectingFkDestination; + int internalPadding, externalPadding; + bool calcScrolled; + + //specials handles + ddScrollBarHandle *scrollbar; + + //methods + int getHeightFontMetric(wxString text, wxFont font); + void calcInternalSubAreas(int posIdx); + + //pk uk(s) + wxString pkName; + wxArrayString ukNames; +}; +#endif diff --git a/include/dd/dditems/figures/ddTextTableItemFigure.h b/include/dd/dditems/figures/ddTextTableItemFigure.h new file mode 100644 index 0000000..df79c6a --- /dev/null +++ b/include/dd/dditems/figures/ddTextTableItemFigure.h @@ -0,0 +1,89 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddTextTableItemFigure.h - +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDTEXTTABLEITEMFIGURE_H +#define DDTEXTTABLEITEMFIGURE_H + + +#include + +#include "hotdraw/figures/hdSimpleTextFigure.h" +#include "dd/dditems/utilities/ddDataType.h" + +enum +{ + MNU_DDADDCOLUMN = 321, + MNU_DELCOLUMN, + MNU_RENAMECOLUMN, + MNU_AUTONAMCOLUMN, + MNU_NOTNULL, + MNU_PKEY, + MNU_UKEY, + MNU_TYPESERIAL, + MNU_TYPEBOOLEAN, + MNU_TYPEINTEGER, + MNU_TYPEMONEY, + MNU_TYPEVARCHAR, + MNU_TYPEOTHER, + MNU_TYPEPKEY_CONSTRAINTNAME, + MNU_TYPEUKEY_CONSTRAINTNAME, + MNU_DELTABLE +}; + +class ddColumnFigure; +class ddTableFigure; + +class ddTextTableItemFigure : public hdSimpleTextFigure +{ +public: + ddTextTableItemFigure(wxString &columnName, ddDataType dataType, ddColumnFigure *owner); + ~ddTextTableItemFigure(); + virtual wxString &getText(bool extended = false); + wxString getType(bool raw = false); + virtual void setAlias(wxString alias); + virtual wxString getAlias(); + virtual void setOneTimeNoAlias(); + virtual void createMenu(wxMenu &mnu); + virtual const wxArrayString dataTypes(); + virtual void OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view); + virtual void setText(wxString textString); + virtual ddColumnFigure *getOwnerColumn(); + virtual void setOwnerColumn(ddColumnFigure *column); + virtual void setShowDataType(bool value); + virtual bool getShowDataType() + { + return showDataType; + }; + hdITool *CreateFigureTool(hdDrawingView *view, hdITool *defaultTool); + virtual void displayBoxUpdate(); + void recalculateDisplayBox(); + int getTextWidth(); + int getTextHeight(); + ddDataType getDataType(); + void setDataType(ddDataType type); + void setOwnerTable(ddTableFigure *table); //only used by columns working as table title figure for setAlias method + int getPrecision(); + int getScale(); + void setPrecision(int value); + void setScale(int value); +protected: + ddColumnFigure *ownerColumn; + ddTableFigure *ownerTable; + wxString colAlias; +private: + ddDataType columnType; + wxString out; + bool showDataType; + bool showAlias; + bool oneTimeNoAlias; + int precision; + int scale; +}; +#endif diff --git a/include/dd/dditems/figures/module.mk b/include/dd/dditems/figures/module.mk new file mode 100644 index 0000000..1e5ae29 --- /dev/null +++ b/include/dd/dditems/figures/module.mk @@ -0,0 +1,25 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/dd/dditems/figures/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/dd/dditems/figures/ddColumnFigure.h \ + include/dd/dditems/figures/ddColumnKindIcon.h \ + include/dd/dditems/figures/ddColumnOptionIcon.h \ + include/dd/dditems/figures/ddRelationshipFigure.h \ + include/dd/dditems/figures/ddRelationshipItem.h \ + include/dd/dditems/figures/ddRelationshipTerminal.h \ + include/dd/dditems/figures/ddTableFigure.h \ + include/dd/dditems/figures/ddTextTableItemFigure.h + +EXTRA_DIST += \ + include/dd/dditems/figures/module.mk + +include include/dd/dditems/figures/xml/module.mk diff --git a/include/dd/dditems/figures/xml/ddXmlStorage.h b/include/dd/dditems/figures/xml/ddXmlStorage.h new file mode 100644 index 0000000..b2794f8 --- /dev/null +++ b/include/dd/dditems/figures/xml/ddXmlStorage.h @@ -0,0 +1,66 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdAbstractFigure.h - Base class for all figures with attributes (line size, fonts and others) +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDXMLSTORAGE_H +#define DDXMLSTORAGE_H + +#include "hotdraw/figures/xml/hdStorage.h" +#include "dd/ddmodel/ddDatabaseDesign.h" +#include + +class ddXmlStorage : public hdStorage +{ +public: + ddXmlStorage(); + + //Generic part + static bool Read(xmlTextReaderPtr reader); + static bool Write(xmlTextWriterPtr writer, hdIFigure *figure); + static void setModel(ddDatabaseDesign *sourceDesign); + static void setNotebook(ctlAuiNotebook *notebook); + static wxString getModelDTD(); + + //Write xml info Database Designer Related + static void WriteLocal( xmlTextWriterPtr writer, ddColumnOptionIcon *figure); + static void WriteLocal( xmlTextWriterPtr writer, ddColumnKindIcon *figure); + static void WriteLocal( xmlTextWriterPtr writer, ddTextTableItemFigure *figure); + static void WriteLocal( xmlTextWriterPtr writer, ddColumnFigure *figure); + static void WriteLocal( xmlTextWriterPtr writer, ddTableFigure *figure); + static void WriteLocal( xmlTextWriterPtr writer, ddRelationshipFigure *figure); + static void WriteLocal( xmlTextWriterPtr writer, ddRelationshipItem *item); + static void WriteLocal( xmlTextWriterPtr writer, hdDrawing *diagram); + static void StarDiagrams( xmlTextWriterPtr writer); + static void EndDiagrams( xmlTextWriterPtr writer); + static void StartModel( xmlTextWriterPtr writer, ddDatabaseDesign *design); + static void EndModel( xmlTextWriterPtr writer); + static bool processResult(int value); + + //Generic node processing functions + static wxString getNodeName(xmlTextReaderPtr reader); + static int getNodeType(xmlTextReaderPtr reader); + static wxString getNodeValue(xmlTextReaderPtr reader); + + //Read xml info Database Designer Related + static void selectReader(xmlTextReaderPtr reader); + static void checkVersion(xmlTextReaderPtr reader); + static ddTableFigure *getTable(xmlTextReaderPtr reader); + static ddColumnFigure *getColumn(xmlTextReaderPtr reader, ddTableFigure *colOwner); + static ddRelationshipFigure *getRelationship(xmlTextReaderPtr reader); + static ddRelationshipItem *getRelationshipItem(xmlTextReaderPtr reader, ddRelationshipFigure *itemOwner, ddTableFigure *source, ddTableFigure *destination); + static void initDiagrams(xmlTextReaderPtr reader); + static void initialModelParse(xmlTextReaderPtr reader); + +private: + + static ddDatabaseDesign *design; + static ctlAuiNotebook *tabs; +}; +#endif diff --git a/include/dd/dditems/figures/xml/module.mk b/include/dd/dditems/figures/xml/module.mk new file mode 100644 index 0000000..6c4f3b6 --- /dev/null +++ b/include/dd/dditems/figures/xml/module.mk @@ -0,0 +1,16 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/dd/dditems/figures/xml Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/dd/dditems/figures/xml/ddXmlStorage.h + +EXTRA_DIST += \ + include/dd/dditems/figures/xml/module.mk diff --git a/include/dd/dditems/handles/ddAddColButtonHandle.h b/include/dd/dditems/handles/ddAddColButtonHandle.h new file mode 100644 index 0000000..e085829 --- /dev/null +++ b/include/dd/dditems/handles/ddAddColButtonHandle.h @@ -0,0 +1,32 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddAddColButtonHandle.h - A handle for a table figure that allow to graphically add columns +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDADDCOLBUTTONHANDLE_H +#define DDADDCOLBUTTONHANDLE_H + +#include "hotdraw/handles/hdButtonHandle.h" + +class ddAddColButtonHandle : public hdButtonHandle +{ +public: + ddAddColButtonHandle(hdIFigure *owner, hdILocator *buttonLocator , wxBitmap &buttonImage, wxSize &size); + ~ddAddColButtonHandle(); + + virtual void invokeStart(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeStep(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeEnd(hdMouseEvent &event, hdDrawingView *view); +protected: + +private: + wxImage handleCursorImage; + wxCursor handleCursor; +}; +#endif diff --git a/include/dd/dditems/handles/ddAddFkButtonHandle.h b/include/dd/dditems/handles/ddAddFkButtonHandle.h new file mode 100644 index 0000000..c51f666 --- /dev/null +++ b/include/dd/dditems/handles/ddAddFkButtonHandle.h @@ -0,0 +1,32 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddAddFkButtonHandle.h - A handle for a table figure that allow to graphically add relationships (fk) +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDADDFKBUTTONHANDLE_H +#define DDADDFKBUTTONHANDLE_H + +#include "hotdraw/handles/hdButtonHandle.h" + +class ddAddFkButtonHandle : public hdButtonHandle +{ +public: + ddAddFkButtonHandle(hdIFigure *owner, hdILocator *buttonLocator , wxBitmap &buttonImage, wxSize &size); + ~ddAddFkButtonHandle(); + + virtual void invokeStart(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeStep(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeEnd(hdMouseEvent &event, hdDrawingView *view); +protected: + +private: + wxImage handleCursorImage; + wxCursor handleCursor; +}; +#endif diff --git a/include/dd/dditems/handles/ddMinMaxTableButtonHandle.h b/include/dd/dditems/handles/ddMinMaxTableButtonHandle.h new file mode 100644 index 0000000..74a403f --- /dev/null +++ b/include/dd/dditems/handles/ddMinMaxTableButtonHandle.h @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddMinMaxTableButtonHandle.h - A handle for a table figure that allow to graphically minimize or maximize table window size +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDMINMAXTABLEBUTTONHANDLE_H +#define DDMINMAXTABLEBUTTONHANDLE_H + +#include "hotdraw/handles/hdButtonHandle.h" + +class ddMinMaxTableButtonHandle : public hdButtonHandle +{ +public: + ddMinMaxTableButtonHandle(hdIFigure *owner, hdILocator *buttonLocator , wxBitmap &buttonImage, wxBitmap &buttonSecondImage, wxSize &size); + ~ddMinMaxTableButtonHandle(); + + virtual void invokeStart(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeStep(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeEnd(hdMouseEvent &event, hdDrawingView *view); +protected: + +private: + wxImage handleCursorImage; + wxCursor handleCursor; + wxBitmap buttonMaximizeImage, tmpImage; + bool showFirst; +}; +#endif diff --git a/include/dd/dditems/handles/ddRemoveTableButtonHandle.h b/include/dd/dditems/handles/ddRemoveTableButtonHandle.h new file mode 100644 index 0000000..7041d84 --- /dev/null +++ b/include/dd/dditems/handles/ddRemoveTableButtonHandle.h @@ -0,0 +1,32 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddRemoveTableButtonHandle.h - A handle for a table figure that allow to delete it +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDREMOVETABLEBUTTONHANDLE_H +#define DDREMOVETABLEBUTTONHANDLE_H + +#include "hotdraw/handles/hdButtonHandle.h" + +class ddRemoveTableButtonHandle : public hdButtonHandle +{ +public: + ddRemoveTableButtonHandle(hdIFigure *owner, hdILocator *buttonLocator , wxBitmap &buttonImage, wxSize &size); + ~ddRemoveTableButtonHandle(); + + virtual void invokeStart(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeStep(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeEnd(hdMouseEvent &event, hdDrawingView *view); +protected: + +private: + wxImage handleCursorImage; + wxCursor handleCursor; +}; +#endif diff --git a/include/dd/dditems/handles/ddScrollBarHandle.h b/include/dd/dditems/handles/ddScrollBarHandle.h new file mode 100644 index 0000000..4f084f8 --- /dev/null +++ b/include/dd/dditems/handles/ddScrollBarHandle.h @@ -0,0 +1,46 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddScrollBarHandle.h - A handle for a table figure that allow to scroll it when table is not in full size +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDSCROLLBARHANDLE_H +#define DDSCROLLBARHANDLE_H + +#include "hotdraw/handles/hdIHandle.h" +#include "hotdraw/handles/hdLocatorHandle.h" +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/utilities/hdPoint.h" +#include "dd/dditems/figures/ddTableFigure.h" + + +class ddScrollBarHandle : public hdLocatorHandle +{ +public: + ddScrollBarHandle(ddTableFigure *owner, hdILocator *scrollBarLocator , wxSize &size); + ~ddScrollBarHandle(); + + + virtual void draw(wxBufferedDC &context, hdDrawingView *view); + virtual hdPoint &locate(int posIdx); + virtual wxCursor createCursor(); + virtual void invokeStart(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeStep(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeEnd(hdMouseEvent &event, hdDrawingView *view); + virtual hdRect &getDisplayBox(int posIdx); +protected: +private: + hdPoint pointLocate; + hdILocator *scrollLocator; + ddTableFigure *table; + wxBitmap upBitmap, downBitmap; + wxSize barSize; + int anchorY; + +}; +#endif diff --git a/include/dd/dditems/handles/ddSouthTableSizeHandle.h b/include/dd/dditems/handles/ddSouthTableSizeHandle.h new file mode 100644 index 0000000..e64d069 --- /dev/null +++ b/include/dd/dditems/handles/ddSouthTableSizeHandle.h @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddSouthTableSizeHandle.h - Allow to change table size by using drag and drop from south side of table rectangle +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDSOUTHTABLESIZEHANDLE_H +#define DDSOUTHTABLESIZEHANDLE_H + +#include "hotdraw/handles/hdLocatorHandle.h" + +class ddTableFigure; + +class ddSouthTableSizeHandle : public hdLocatorHandle +{ +public: + ddSouthTableSizeHandle(ddTableFigure *owner, hdILocator *locator); + ~ddSouthTableSizeHandle(); + virtual wxCursor createCursor(); + virtual void draw(wxBufferedDC &context, hdDrawingView *view); + virtual hdRect &getDisplayBox(int posIdx); + virtual void invokeStart(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeStep(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeEnd(hdMouseEvent &event, hdDrawingView *view); +protected: + +private: + int anchorY; + +}; +#endif diff --git a/include/dd/dditems/handles/module.mk b/include/dd/dditems/handles/module.mk new file mode 100644 index 0000000..39fdd76 --- /dev/null +++ b/include/dd/dditems/handles/module.mk @@ -0,0 +1,21 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/dd/dditems/handles/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/dd/dditems/handles/ddAddColButtonHandle.h \ + include/dd/dditems/handles/ddAddFkButtonHandle.h \ + include/dd/dditems/handles/ddMinMaxTableButtonHandle.h \ + include/dd/dditems/handles/ddRemoveTableButtonHandle.h \ + include/dd/dditems/handles/ddScrollBarHandle.h \ + include/dd/dditems/handles/ddSouthTableSizeHandle.h + +EXTRA_DIST += \ + include/dd/dditems/handles/module.mk diff --git a/include/dd/dditems/locators/ddAddColLocator.h b/include/dd/dditems/locators/ddAddColLocator.h new file mode 100644 index 0000000..aaac8f9 --- /dev/null +++ b/include/dd/dditems/locators/ddAddColLocator.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddAddColLocator.h - Locate table add column button inside a table. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDADDCOLLOCATOR_H +#define DDADDCOLLOCATOR_H + +#include "hotdraw/locators/hdILocator.h" +#include "hotdraw/figures/hdIFigure.h" + +class ddAddColLocator : public hdILocator +{ +public: + ddAddColLocator(); + ~ddAddColLocator(); + + virtual hdPoint &locate(int posIdx, hdIFigure *owner); + +protected: + +private: +}; +#endif diff --git a/include/dd/dditems/locators/ddAddFkLocator.h b/include/dd/dditems/locators/ddAddFkLocator.h new file mode 100644 index 0000000..5c8afe7 --- /dev/null +++ b/include/dd/dditems/locators/ddAddFkLocator.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddAddFkLocator.h - Locate table add fk relationship button inside a table. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDADDFKLOCATOR_H +#define DDADDFKLOCATOR_H + +#include "hotdraw/locators/hdILocator.h" +#include "hotdraw/figures/hdIFigure.h" + +class ddAddFkLocator : public hdILocator +{ +public: + ddAddFkLocator(); + ~ddAddFkLocator(); + + virtual hdPoint &locate(int posIdx, hdIFigure *owner); + +protected: + +private: +}; +#endif diff --git a/include/dd/dditems/locators/ddMinMaxTableLocator.h b/include/dd/dditems/locators/ddMinMaxTableLocator.h new file mode 100644 index 0000000..04a43b9 --- /dev/null +++ b/include/dd/dditems/locators/ddMinMaxTableLocator.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddMinMaxTableLocator.h - Locate table minimize/maximize button inside a table. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDMINMAXTABLELOCATOR_H +#define DDMINMAXTABLELOCATOR_H + +#include "hotdraw/locators/hdILocator.h" +#include "hotdraw/figures/hdIFigure.h" + +class ddMinMaxTableLocator : public hdILocator +{ +public: + ddMinMaxTableLocator(); + ~ddMinMaxTableLocator(); + + virtual hdPoint &locate(int posIdx, hdIFigure *owner); + +protected: + +private: +}; +#endif diff --git a/include/dd/dditems/locators/ddRemoveTableLocator.h b/include/dd/dditems/locators/ddRemoveTableLocator.h new file mode 100644 index 0000000..f54fa21 --- /dev/null +++ b/include/dd/dditems/locators/ddRemoveTableLocator.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddRemoveColLocator.cpp - Locate table delete button inside a table. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDREMOVETABLELOCATOR_H +#define DDREMOVETABLELOCATOR_H + +#include "hotdraw/locators/hdILocator.h" +#include "hotdraw/figures/hdIFigure.h" + +class ddRemoveTableLocator : public hdILocator +{ +public: + ddRemoveTableLocator(); + ~ddRemoveTableLocator(); + + virtual hdPoint &locate(int posIdx, hdIFigure *owner); + +protected: + +private: +}; +#endif diff --git a/include/dd/dditems/locators/ddScrollBarTableLocator.h b/include/dd/dditems/locators/ddScrollBarTableLocator.h new file mode 100644 index 0000000..f6283f5 --- /dev/null +++ b/include/dd/dditems/locators/ddScrollBarTableLocator.h @@ -0,0 +1,31 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddScrollBarTableLocator.h - Locate table scrollbar inside a table. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDSCROLLBARTABLELOCATOR_H +#define DDSCROLLBARTABLELOCATOR_H + +#include "hotdraw/locators/hdILocator.h" +#include "hotdraw/figures/hdIFigure.h" + +class ddScrollBarTableLocator : public hdILocator +{ +public: + ddScrollBarTableLocator(); + ~ddScrollBarTableLocator(); + + virtual hdPoint &locate(int posIdx, hdIFigure *owner); + +protected: + +private: + +}; +#endif diff --git a/include/dd/dditems/locators/ddTableBottomLocator.h b/include/dd/dditems/locators/ddTableBottomLocator.h new file mode 100644 index 0000000..d93e54a --- /dev/null +++ b/include/dd/dditems/locators/ddTableBottomLocator.h @@ -0,0 +1,31 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddTableBottomLocator.h - Locate bottom (south) of table for use of south table size handle. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDTABLEBOTTOMLOCATOR_H +#define DDTABLEBOTTOMLOCATOR_H + +#include "hotdraw/locators/hdILocator.h" +#include "hotdraw/figures/hdIFigure.h" + +class ddTableBottomLocator : public hdILocator +{ +public: + ddTableBottomLocator(); + ~ddTableBottomLocator(); + + virtual hdPoint &locate(int posIdx, hdIFigure *owner); + +protected: + +private: + +}; +#endif diff --git a/include/dd/dditems/locators/module.mk b/include/dd/dditems/locators/module.mk new file mode 100644 index 0000000..ed83939 --- /dev/null +++ b/include/dd/dditems/locators/module.mk @@ -0,0 +1,21 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/dd/dditems/locators/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/dd/dditems/locators/ddAddColLocator.h \ + include/dd/dditems/locators/ddAddFkLocator.h \ + include/dd/dditems/locators/ddMinMaxTableLocator.h \ + include/dd/dditems/locators/ddRemoveTableLocator.h \ + include/dd/dditems/locators/ddScrollBarTableLocator.h \ + include/dd/dditems/locators/ddTableBottomLocator.h + +EXTRA_DIST += \ + include/dd/dditems/locators/module.mk diff --git a/include/dd/dditems/module.mk b/include/dd/dditems/module.mk new file mode 100644 index 0000000..a68461a --- /dev/null +++ b/include/dd/dditems/module.mk @@ -0,0 +1,19 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/dd/dditems/ Makefile fragment +# +####################################################################### + +include include/dd/dditems/figures/module.mk +include include/dd/dditems/handles/module.mk +include include/dd/dditems/locators/module.mk +include include/dd/dditems/tools/module.mk +include include/dd/dditems/utilities/module.mk + +EXTRA_DIST += \ + include/dd/dditems/module.mk diff --git a/include/dd/dditems/tools/ddColumnFigureTool.h b/include/dd/dditems/tools/ddColumnFigureTool.h new file mode 100644 index 0000000..dbb9019 --- /dev/null +++ b/include/dd/dditems/tools/ddColumnFigureTool.h @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddColumnFigureTool.h - Improvement to hdFigureTool to work with composite table figures +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDCOLUMNFIGURETOOL_H +#define DDCOLUMNFIGURETOOL_H + +#include "hotdraw/tools/hdFigureTool.h" + + +class ddColumnFigureTool : public hdFigureTool +{ +public: + ddColumnFigureTool(hdDrawingView *view, hdIFigure *fig, hdITool *dt); + ~ddColumnFigureTool(); + virtual void setDefaultTool(hdITool *dt); + virtual hdITool *getDefaultTool(); + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual void activate(hdDrawingView *view); + virtual void deactivate(hdDrawingView *view); + virtual void setDelegateTool(hdDrawingView *view, hdITool *tool); + virtual hdITool *getDelegateTool(); +protected: + hdITool *delegateTool; +private: +}; +#endif diff --git a/include/dd/dditems/tools/ddColumnTextTool.h b/include/dd/dditems/tools/ddColumnTextTool.h new file mode 100644 index 0000000..f4c095d --- /dev/null +++ b/include/dd/dditems/tools/ddColumnTextTool.h @@ -0,0 +1,33 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddColumnTextTool.h - Modification of simple text tool for editing composite figure columns +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDCOLUMNTEXTTOOL_H +#define DDCOLUMNTEXTTOOL_H + +#include "hotdraw/tools/hdSimpleTextTool.h" +#include "dd/dditems/figures/ddTextTableItemFigure.h" + + +class ddColumnTextTool : public hdSimpleTextTool +{ + +public: + ddColumnTextTool(hdDrawingView *view, hdIFigure *fig, hdITool *dt, bool fastEdit = true, wxString dialogCaption = wxEmptyString, wxString dialogMessage = wxEmptyString); + ~ddColumnTextTool(); + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual bool callDialog(hdDrawingView *view); + // some events functions are needed but because a bug it were move to main View class as a hack. +protected: +private: + ddTextTableItemFigure *colTextFigure; + //Because a bug in the way wxwidgets connect events I can't declare it here, wxTextCtrl, instead I do it on the view. +}; +#endif diff --git a/include/dd/dditems/tools/module.mk b/include/dd/dditems/tools/module.mk new file mode 100644 index 0000000..707fbb4 --- /dev/null +++ b/include/dd/dditems/tools/module.mk @@ -0,0 +1,17 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/dd/dditems/tools/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/dd/dditems/tools/ddColumnFigureTool.h \ + include/dd/dditems/tools/ddColumnTextTool.h + +EXTRA_DIST += \ + include/dd/dditems/tools/module.mk diff --git a/include/dd/dditems/utilities/ddDataType.h b/include/dd/dditems/utilities/ddDataType.h new file mode 100644 index 0000000..450e02a --- /dev/null +++ b/include/dd/dditems/utilities/ddDataType.h @@ -0,0 +1,68 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddDataType.h - data types related info for table use +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDDATATYPES_H +#define DDDATATYPES_H + +enum ddMenuColumn +{ + add_column = 321, + del_column, + ren_column, + change_datatype +}; + +enum ddHiddenTypes +{ + DDTABLEFIGURE = 100, + DDRELATIONSHIPFIGURE = 200, + DDCOLUMNFIGURE = 300, + DDCOLUMNOPTIONICON = 400, + DDCOLUMNKINDICON = 500, + DDTEXTTABLEITEMFIGURE = 600 +}; + +enum ddDataType +{ + dt_null = 0, + dt_serial, + dt_boolean, + dt_integer, + dt_money, + dt_varchar, //(n) + dt_bigint, + dt_bit, //(n) + dt_bytea, + dt_char, //(n) + dt_cidr, + dt_circle, + dt_date, + dt_doubleprec, + dt_inet, + dt_interval, //(n) + dt_line, + dt_Lseg, + dt_macaddr, + dt_numeric, //(p,s) + dt_path, + dt_point, + dt_polygon, + dt_real, + dt_smallint, + dt_text, + dt_time, + dt_timestamp, + dt_varbit //(n) +}; + +static wxArrayString ddDatatypes; + +#endif diff --git a/include/dd/dditems/utilities/ddPrecisionScaleDialog.h b/include/dd/dditems/utilities/ddPrecisionScaleDialog.h new file mode 100644 index 0000000..5426a79 --- /dev/null +++ b/include/dd/dditems/utilities/ddPrecisionScaleDialog.h @@ -0,0 +1,68 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddPrecisionScaleDialog.h - Utility dialog class to allow user input of precision and scale +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDPRECISIONSCALEDIALOG_H +#define DDPRECISIONSCALEDIALOG_H + +class ddPrecisionScaleDialog : public pgDialog +{ +public: + ddPrecisionScaleDialog(); + ~ddPrecisionScaleDialog(); + ddPrecisionScaleDialog( wxWindow *parent, + const wxString &defaultValue1 = wxT("0"), + const wxString &defaultValue2 = wxT("0") + ); + + // Member initialization + void Init(); + + // Sets the validators for the dialog controls + //void SetDialogValidators(); + bool TransferDataToWindow(); + bool TransferDataFromWindow(); + + // Sets the help text for the dialog controls + void SetDialogHelp(); + + // Value1 accessors + void SetValue1(wxString value) + { + m_value1 = value; + } + wxString GetValue1() + { + return m_value1; + } + + // Value1 accessors + void SetValue2(wxString value) + { + m_value2 = value; + } + wxString GetValue2() + { + return m_value2; + } + + //wxEVT_COMMAND_TEXT_ENTER event_handle for DDVALUE1 + void OnEnterPressed( wxCommandEvent &event ); + + +protected: + // Data members + wxString m_value1, m_value2; + + DECLARE_EVENT_TABLE() + +}; +#endif + diff --git a/include/dd/dditems/utilities/ddSelectKindFksDialog.h b/include/dd/dditems/utilities/ddSelectKindFksDialog.h new file mode 100644 index 0000000..527808e --- /dev/null +++ b/include/dd/dditems/utilities/ddSelectKindFksDialog.h @@ -0,0 +1,102 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddTableNameDialog.h - Utility dialog class to allow user input of table name and short name +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDSELECTKINDFKSDIALOG_H +#define DDSELECTKINDFKSDIALOG_H + +#include +#include "dd/dditems/figures/ddRelationshipFigure.h" + +class hdDrawingView; + +enum +{ + DDSELECTKINDFKSDIALOG = 10000, + DDSELECTKINDFK = 10001, + DDCHOICESELECTBASE = 30000 +}; + +class ddSelectFkKindLine : public hdObject +{ +public: + wxStaticText *sourceCtrl; + wxChoice *destinationCtrl; + + ddSelectFkKindLine(wxWindow *parent, wxString sourceColumn, wxArrayString possibleTargets, wxWindowID eventId); + ddSelectFkKindLine(); + ~ddSelectFkKindLine(); +}; + + +WX_DECLARE_STRING_HASH_MAP( ddSelectFkKindLine *, choicesControlsHashMap ); + +class ddSelectKindFksDialog : public wxDialog +{ + DECLARE_CLASS( ddSelectKindFksDialog ) + DECLARE_EVENT_TABLE() +public: + ddSelectKindFksDialog(); + ~ddSelectKindFksDialog(); + ddSelectKindFksDialog( wxWindow *parent, + ddRelationshipFigure *relation, + wxWindowID id = DDSELECTKINDFKSDIALOG, + const wxPoint &pos = wxDefaultPosition, + const wxSize &size = wxDefaultSize, + long style = wxCAPTION + ); + + // Member initialization + void Init(); + // Creation + bool Create( wxWindow *parent, + wxWindowID id, + const wxPoint &pos, + const wxSize &size, + long style); + + + // Creates the controls and sizers + void CreateControls(); + + // Sets the validators for the dialog controls + bool TransferDataToWindow(); + bool TransferDataFromWindow(); + + // Sets the help text for the dialog controls + void SetDialogHelp(); + + //wxEVT_COMMAND_TEXT_ENTER event_handle for DDVALUE1 + void OnEnterPressed( wxCommandEvent &event ); + void OnOkButtonClicked( wxCommandEvent &event ); + void OnCancelButtonClicked( wxCommandEvent &event ); + + +protected: + //methods + void populateColumnsControls(bool primaryKey, int useUkIndex); + void deleteColsControls(); + void OnChoiceFkKind(wxCommandEvent &event); + + // Data members + ddRelationshipFigure *tablesRelation; + + // Dialog controls + choicesControlsHashMap choices; + wxBoxSizer *topSizer, *linesSizer, *okCancelBox, *colsTopSizer; + wxChoice *kindFkCtrl; + wxButton *ok, *cancel; + wxStaticLine *line; + +private: + +}; +#endif + diff --git a/include/dd/dditems/utilities/ddTableNameDialog.h b/include/dd/dditems/utilities/ddTableNameDialog.h new file mode 100644 index 0000000..925371e --- /dev/null +++ b/include/dd/dditems/utilities/ddTableNameDialog.h @@ -0,0 +1,87 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddTableNameDialog.h - Utility dialog class to allow user input of table name and short name +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDTABLENAMEDIALOGS_H +#define DDTABLENAMEDIALOGS_H + +#include "dlg/dlgClasses.h" +#include "dd/dditems/figures/ddTextTableItemFigure.h" + +class ddTableNameDialog : public pgDialog +{ +public: + ddTableNameDialog(); + ~ddTableNameDialog(); + ddTableNameDialog(wxWindow *parent, + const wxString &defaultValue1 = wxEmptyString, + const wxString &defaultValue2 = wxEmptyString, + ddTextTableItemFigure *tableItem = NULL + ); + + // Member initialization + void Init(); + + // Sets the validators for the dialog controls + //void SetDialogValidators(); + bool TransferDataToWindow(); + bool TransferDataFromWindow(); + + // Sets the help text for the dialog controls + void SetDialogHelp(); + + // Value1 accessors + void SetValue1(wxString value) + { + m_value1 = value; + } + wxString GetValue1() + { + return m_value1; + } + + // Value1 accessors + void SetValue2(wxString value) + { + m_value2 = value; + } + wxString GetValue2() + { + return m_value2; + } + + // CheckBox accessors + void SetValueGenerate(bool value) + { + checkGenerate = value; + } + bool GetValueGenerate() + { + return checkGenerate; + } + + //wxEVT_COMMAND_BUTTON_CLICKED event_handler for DDGENBUTTON + void OnGenButtonClicked( wxCommandEvent &event ); + + +protected: + // Data members + wxString m_value1, m_value2; + wxString label1, label2; + bool checkGenerate; + ddTextTableItemFigure *tabItem; + + DECLARE_EVENT_TABLE() + +private: + +}; +#endif + diff --git a/include/dd/dditems/utilities/module.mk b/include/dd/dditems/utilities/module.mk new file mode 100644 index 0000000..c43f2dd --- /dev/null +++ b/include/dd/dditems/utilities/module.mk @@ -0,0 +1,19 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/dd/dditems/utilities/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/dd/dditems/utilities/ddDataType.h \ + include/dd/dditems/utilities/ddPrecisionScaleDialog.h \ + include/dd/dditems/utilities/ddSelectKindFksDialog.h \ + include/dd/dditems/utilities/ddTableNameDialog.h + +EXTRA_DIST += \ + include/dd/dditems/utilities/module.mk diff --git a/include/dd/ddmodel/ddBrowserDataContainer.h b/include/dd/ddmodel/ddBrowserDataContainer.h new file mode 100644 index 0000000..72c0927 --- /dev/null +++ b/include/dd/ddmodel/ddBrowserDataContainer.h @@ -0,0 +1,28 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddBrowserDataContainer.h - Item to contain data for each treview child. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDBROWSERDATACONTAINER_H +#define DDBROWSERDATACONTAINER_H + +#include "hotdraw/figures/hdIFigure.h" + +class ddBrowserDataContainer : public wxTreeItemData +{ +public: + ddBrowserDataContainer(hdIFigure *data); + ~ddBrowserDataContainer(); + int getFigureKindId(); + hdIFigure *getFigure(); + +private: + hdIFigure *figure; +}; +#endif diff --git a/include/dd/ddmodel/ddDBReverseEngineering.h b/include/dd/ddmodel/ddDBReverseEngineering.h new file mode 100644 index 0000000..b58620c --- /dev/null +++ b/include/dd/ddmodel/ddDBReverseEngineering.h @@ -0,0 +1,249 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddDBReverseEngineering.h - Reverse engineering database functions for database designer. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDDBREVERSEENGINEERING_H +#define DDDBREVERSEENGINEERING_H +#include "wx/wizard.h" +#include "hotdraw/main/hdObject.h" +#include "dd/dditems/utilities/ddDataType.h" +#include "schema/pgDatatype.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/ddmodel/ddDatabaseDesign.h" + +class SelSchemaPage; +class SelTablesPage; +class ReportPage; +class ddStubTable; + +enum +{ + DDALLSCHEMAS = 7001, + DDALLTABS, + DDSELTABS, + DDADD, + DDADDALL, + DDREMOVE, + DDREMOVEALL +}; + +WX_DECLARE_STRING_HASH_MAP( ddStubTable *, stubTablesHashMap); +WX_DEFINE_SORTED_ARRAY_INT(int, wxSortedArrayInt); + +// Stub tables related classes +class ddImportDBUtils : public hdObject +{ +public: + // Implement and replace at this and other dd related classes as Generation Wizard static wxArrayString getSchemasNames(...); + static wxArrayString getTablesNames(pgConn *connection, wxString schemaName); + static ddStubTable *getTable(pgConn *connection, wxString tableName, OID tableOid); + static ddTableFigure *getTableFigure(ddStubTable *table); + static void getAllRelationships(pgConn *connection, stubTablesHashMap &tables, ddDatabaseDesign *design); + static int getPgColumnNum(pgConn *connection, wxString schemaName, wxString tableName, wxString columnName); + static OID getTableOID(pgConn *connection, wxString schemaName, wxString tableName); + static OID getSchemaOID(pgConn *connection, wxString schemaName); + static bool existsFk(pgConn *connection, OID destTableOid, wxString schemaName, wxString fkName, wxString sourceTableName); + static wxArrayString getFkAtDbNotInModel(pgConn *connection, OID destTableOid, wxString schemaName, wxArrayString existingFkList, ddDatabaseDesign *design); + static bool isModelSameDbFk(pgConn *connection, OID destTableOid, wxString schemaName, wxString fkName, wxString sourceTableName, wxString destTableName, ddStubTable *destStubTable, ddRelationshipFigure *relation); + +private: + static bool setUniqueConstraints(pgConn *connection, ddStubTable *table); + static bool setPkName(pgConn *connection, ddStubTable *table); + static int sortFunc(int n1, int n2) + { + return n1 - n2; + } +}; + +class ddStubColumn : public hdObject +{ +public: + ddStubColumn(); + ddStubColumn(const ddStubColumn ©); + ddStubColumn(wxString name, OID oidSource, bool notNull, bool pk, pgDatatype *type, int ukIndex = -1); + ddStubColumn(wxString name, OID oidSource); + ~ddStubColumn(); + wxString columnName; + bool isNotNull; + bool isPrimaryKey; + bool isUniqueKey(); + int uniqueKeyIndex; + OID OIDTable; + pgDatatype *typeColumn; + int pgColNumber; +}; + +WX_DECLARE_STRING_HASH_MAP( ddStubColumn *, stubColsHashMap); + +class ddStubTable : public hdObject +{ +public: + ddStubTable(); + ddStubTable(wxString name, OID tableOID); + ddStubColumn *getColumnByNumber(int pgColNumber); + ~ddStubTable(); + wxString tableName; + OID OIDTable; + stubColsHashMap cols; + wxString PrimaryKeyName; + wxArrayString UniqueKeysNames; +}; + +// +// +// Wizard related classes +// +// +// + +WX_DECLARE_STRING_HASH_MAP( OID, oidsHashMap); + +class ddDBReverseEngineering : public wxWizard +{ +public: + ddDBReverseEngineering(wxFrame *frame, ddDatabaseDesign *design, pgConn *connection, bool useSizer = true); + ~ddDBReverseEngineering(); + + //Wizard related functions + wxWizardPage *GetFirstPage() const + { + return initialPage; + } + + // Reverse Enginnering related functions + wxArrayString getTables(); + pgConn *getConnection() + { + return conn; + }; + + //transfer data between pages + OID OIDSelectedSchema; + wxString schemaName; + oidsHashMap tablesOIDHM; + stubTablesHashMap stubsHM; + SelSchemaPage *page2; + SelTablesPage *page3; + ReportPage *page4; + ddDatabaseDesign *getDesign() + { + return figuresDesign; + }; + +private: + void OnFinishPressed(wxWizardEvent &event); + pgConn *conn; + wxWizardPageSimple *initialPage; + wxStaticText *frontText; + ddDatabaseDesign *figuresDesign; + DECLARE_EVENT_TABLE() +}; + +class SelSchemaPage : public wxWizardPage +{ +public: + SelSchemaPage(wxWizard *parent, wxWizardPage *prev); + ~SelSchemaPage(); + virtual wxWizardPage *GetPrev() const + { + return m_prev; + }; + virtual wxWizardPage *GetNext() const + { + return m_next; + }; + void SetPrev(wxWizardPage *prev) + { + m_prev = prev; + } + void SetNext(wxWizardPage *next) + { + m_next = next; + } +private: + void OnWizardPageChanging(wxWizardEvent &event); + void refreshSchemas(pgConn *connection); + wxStaticText *message; + wxWizardPage *m_prev, *m_next; + wxListBox *m_allSchemas; + wxArrayString schemasNames; + oidsHashMap schemasHM; + ddDBReverseEngineering *wparent; + DECLARE_EVENT_TABLE() +}; + + +class SelTablesPage : public wxWizardPage +{ +public: + SelTablesPage(wxWizard *parent, wxWizardPage *prev); + ~SelTablesPage(); + virtual wxWizardPage *GetPrev() const + { + return m_prev; + }; + virtual wxWizardPage *GetNext() const + { + return m_next; + }; + void SetPrev(wxWizardPage *prev) + { + m_prev = prev; + } + void SetNext(wxWizardPage *next) + { + m_next = next; + } + void RefreshTablesList(); + void OnButtonAdd(wxCommandEvent &); + void OnButtonAddAll(wxCommandEvent &); + void OnButtonRemove(wxCommandEvent &); + void OnButtonRemoveAll(wxCommandEvent &); +private: + void OnWizardPageChanging(wxWizardEvent &event); + wxStaticText *leftText, *rightText, *centerText; + wxWizardPage *m_prev, *m_next; + wxListBox *m_allTables, *m_selTables; + ddDBReverseEngineering *wparent; + wxArrayString tablesNames; + wxBitmapButton *buttonAdd, *buttonAddAll, *buttonRemove, *buttonRemoveAll; + wxBitmap addBitmap, addAllBitmap, removeBitmap, removeAllBitmap; + DECLARE_EVENT_TABLE() +}; + +class ReportPage : public wxWizardPage +{ +public: + ReportPage(wxWizard *parent, wxWizardPage *prev); + ~ReportPage(); + virtual wxWizardPage *GetPrev() const + { + return m_prev; + }; + virtual wxWizardPage *GetNext() const + { + return m_next; + }; + void SetPrev(wxWizardPage *prev) + { + m_prev = prev; + } + void SetNext(wxWizardPage *next) + { + m_next = next; + } + wxTextCtrl *results; +private: + void OnWizardPageChanging(wxWizardEvent &event); + wxWizardPage *m_prev, *m_next; + ddDBReverseEngineering *wparent; + DECLARE_EVENT_TABLE() +}; +#endif diff --git a/include/dd/ddmodel/ddDatabaseDesign.h b/include/dd/ddmodel/ddDatabaseDesign.h new file mode 100644 index 0000000..bd23eac --- /dev/null +++ b/include/dd/ddmodel/ddDatabaseDesign.h @@ -0,0 +1,80 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddDatabaseDesign.h - Manages all design related info and contains all model(s) and tables. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDDATABASEDESIGN_H +#define DDDATABASEDESIGN_H + +#include +#include + +#include "dd/ddmodel/ddDrawingEditor.h" +#include "hotdraw/tools/hdITool.h" +#include "dd/dditems/figures/ddTableFigure.h" + +class ddModelBrowser; + +enum +{ + DDGENCREATE = 6000, + DDGENALTER, + DDGENDROPCRE, + DDGENNOTHING +}; + +WX_DECLARE_STRING_HASH_MAP( wxString , tablesMappingHashMap ); + +class ddDatabaseDesign : public wxObject +{ +public: + ddDatabaseDesign(wxWindow *parent, wxWindow *frmOwner); + ~ddDatabaseDesign(); + hdDrawingView *getView(int diagramIndex); + ddDrawingEditor *getEditor(); + void addTableToModel(hdIFigure *figure); + void addTableToView(int diagramIndex, hdIFigure *figure); + void removeTable(int diagramIndex, hdIFigure *figure); + hdDrawing *createDiagram(wxWindow *owner, wxString name, bool fromXml); + void deleteDiagram(int diagramIndex, bool deleteView = true); + void refreshDraw(int diagramIndex); + void eraseDiagram(int diagramIndex); + void emptyModel(); + wxArrayString getDiagramTables(int diagramIndex); + wxString generateDiagram(int diagramIndex, wxString schemaName); + wxArrayString getModelTables(); + wxString generateModel(wxString schemaName); + wxString generateList(wxArrayString tables, wxArrayInt options, pgConn *connection = NULL, wxString schemaName = wxEmptyString); + bool validateModel(wxString &errors); + ddTableFigure *getSelectedTable(int diagramIndex); + ddTableFigure *getTable(wxString tableName); + bool writeXmlModel(wxString file); + bool readXmlModel(wxString file, ctlAuiNotebook *notebook); + + wxString getTableId(wxString tableName); + void addTableToMapping(wxString IdKey, wxString tableName); + wxString getTableName(wxString Id); + void registerBrowser(ddModelBrowser *browser); + void refreshBrowser(); + static wxString getVersionXML(); + void markSchemaOn(wxArrayString tables); + void unMarkSchemaOnAll(); + +protected: + tablesMappingHashMap mappingNameToId; + tablesMappingHashMap mappingIdToName; +private: + ddModelBrowser *attachedBrowser; + int diagramCounter; + ddDrawingEditor *editor; + hdITool *tool; + xmlTextWriterPtr xmlWriter; + +}; +#endif diff --git a/include/dd/ddmodel/ddDrawingEditor.h b/include/dd/ddmodel/ddDrawingEditor.h new file mode 100644 index 0000000..7d0af43 --- /dev/null +++ b/include/dd/ddmodel/ddDrawingEditor.h @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdDrawingEditor.h - Main class that manages all other classes +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDDRAWINGEDITOR_H +#define DDDRAWINGEDITOR_H + +#include "hotdraw/main/hdDrawingEditor.h" +class frmDatabaseDesigner; + +enum +{ + MNU_NEWTABLE = 321 +}; + +class ddDatabaseDesign; + +class ddDrawingEditor : public hdDrawingEditor +{ +public: + ddDrawingEditor(wxWindow *owner, wxWindow *frmOwner, ddDatabaseDesign *design); + virtual hdDrawing *createDiagram(wxWindow *owner, bool fromXml); + virtual void remOrDelSelFigures(int diagramIndex); + void checkRelationshipsConsistency(int diagramIndex); + void checkAllDigramsRelConsistency(); + ddDatabaseDesign *getDesign() + { + return databaseDesign; + }; + virtual void notifyChanged(); + +protected: +private: + ddDatabaseDesign *databaseDesign; + frmDatabaseDesigner *frm; +}; +#endif diff --git a/include/dd/ddmodel/ddDrawingView.h b/include/dd/ddmodel/ddDrawingView.h new file mode 100644 index 0000000..f2ee5dc --- /dev/null +++ b/include/dd/ddmodel/ddDrawingView.h @@ -0,0 +1,40 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdDrawingEditor.h - Main class that manages all other classes +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDDRAWINGVIEW_H +#define DDDRAWINGVIEW_H + +#include "hotdraw/main/hdDrawingView.h" +#include "dd/ddmodel/ddDrawingEditor.h" +#include "dd/ddmodel/ddDatabaseDesign.h" + +class ddDrawingView : public hdDrawingView +{ +public: + ddDrawingView(int diagram, wxWindow *ddParent, ddDrawingEditor *editor , wxSize size, hdDrawing *drawing); + //Hack To allow right click menu at canvas without a figure + virtual void createViewMenu(wxMenu &mnu); + virtual void OnGenericViewPopupClick(wxCommandEvent &event); +protected: +private: +}; + +// A drop target that do nothing only accept text, if accept then tree add table to model +class ddDropTarget : public wxTextDropTarget +{ +public: + ddDropTarget(ddDatabaseDesign *sourceDesign, hdDrawing *targetDrawing); + virtual bool OnDropText(wxCoord x, wxCoord y, const wxString &text); +private: + hdDrawing *target; + ddDatabaseDesign *source; +}; +#endif diff --git a/include/dd/ddmodel/ddGenerationWizard.h b/include/dd/ddmodel/ddGenerationWizard.h new file mode 100644 index 0000000..30d2a67 --- /dev/null +++ b/include/dd/ddmodel/ddGenerationWizard.h @@ -0,0 +1,224 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddBrowserDataContainer.h - Item to contain data for each treview child. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDGENERATIONWIZARD_H +#define DDGENERATIONWIZARD_H + +#include "hotdraw/figures/hdIFigure.h" +#include "dd/ddmodel/ddDatabaseDesign.h" +#include "dd/ddmodel/ddDBReverseEngineering.h" +#include + +class SelGenTablesPage; +class SelGenSchemaPage; +class ReportGridPage; + +enum +{ + DDTABSGRID = 7100 +}; + +class ddGenerationWizard : public wxWizard +{ +public: + ddGenerationWizard(wxFrame *frame, ddDatabaseDesign *design, pgConn *connection, bool useSizer = true); + ~ddGenerationWizard(); + + // Wizard related functions + wxWizardPage *GetFirstPage() const + { + return initialPage; + } + ddDatabaseDesign *getDesign() + { + return figuresDesign; + }; + pgConn *getConnection() + { + return conn; + }; + // Transfer data between pages + OID OIDSelectedSchema; + wxString schemaName; + SelGenTablesPage *page2; + SelGenSchemaPage *page3; + ReportGridPage *page4; + wxString DDL; + wxArrayString preSelTables; + +private: + + void OnWizardPageChanging(wxWizardEvent &event); + + // Page 4 - Report and Finish + void OnFinishPressed(wxWizardEvent &event); + + pgConn *conn; + wxWizardPageSimple *initialPage; + wxStaticText *frontText; + ddDatabaseDesign *figuresDesign; + DECLARE_EVENT_TABLE() +}; + +class SelGenTablesPage : public wxWizardPage +{ +public: + SelGenTablesPage(wxWizard *parent, wxWizardPage *prev); + ~SelGenTablesPage(); + virtual wxWizardPage *GetPrev() const + { + return m_prev; + }; + virtual wxWizardPage *GetNext() const + { + return m_next; + }; + void SetPrev(wxWizardPage *prev) + { + m_prev = prev; + } + void SetNext(wxWizardPage *next) + { + m_next = next; + } + void OnButtonAdd(wxCommandEvent &); + void OnButtonAddAll(wxCommandEvent &); + void OnButtonRemove(wxCommandEvent &); + void OnButtonRemoveAll(wxCommandEvent &); + void RefreshTablesList(); + int countSelTables() + { + return m_selTables->GetCount(); + }; + wxString getSelTableName(int index) + { + return m_selTables->GetString(index); + }; +private: + void moveToSelectList(wxString tableName); + void OnWizardPageChanging(wxWizardEvent &event); + wxStaticText *leftText, *rightText, *centerText; + wxWizardPage *m_prev, *m_next; + wxListBox *m_allTables, *m_selTables; + ddGenerationWizard *wparent; + wxArrayString tablesNames; + wxBitmapButton *buttonAdd, *buttonAddAll, *buttonRemove, *buttonRemoveAll; + wxBitmap addBitmap, addAllBitmap, removeBitmap, removeAllBitmap; + DECLARE_EVENT_TABLE() +}; + +class SelGenSchemaPage : public wxWizardPage +{ +public: + SelGenSchemaPage(wxWizard *parent, wxWizardPage *prev); + ~SelGenSchemaPage(); + virtual wxWizardPage *GetPrev() const + { + return m_prev; + }; + virtual wxWizardPage *GetNext() const + { + return m_next; + }; + void SetPrev(wxWizardPage *prev) + { + m_prev = prev; + } + void SetNext(wxWizardPage *next) + { + m_next = next; + } +private: + void OnWizardPageChanging(wxWizardEvent &event); + void refreshSchemas(pgConn *connection); + wxStaticText *message; + wxWizardPage *m_prev, *m_next; + wxListBox *m_allSchemas; + wxArrayString schemasNames; + oidsHashMap schemasHM; + ddGenerationWizard *wparent; + DECLARE_EVENT_TABLE() +}; + +// Special version of wxGrid to allow use of fast comboboxes and grid columns auto fit +// some snippets from http://forums.wxwidgets.org/viewtopic.php?t=27568 under same wxwidgets license +// others from pgAdming gqb +class wxDDGrid: public wxGrid +{ +public: + wxDDGrid(wxWindow *parent, wxWindowID id); + void ComboBoxEvent(wxGridEvent &event); + void RevertSel(); + + int sf[10]; + + void OnSizeEvt( wxSizeEvent &ev ); + int StretchIt(); + int keepFit; + +public: + void SetColStretch ( unsigned i, int factor ) + { + if( i < 10 ) sf[i] = factor; + } + int GetColStretch ( unsigned i ) const + { + return (i < 10) ? sf[i] : 1; + } + void ReLayout() + { + StretchIt(); + } + void SetFit( int fit_style ) + { + keepFit = fit_style; + } +private: + wxGridSelection *m_selTemp; +}; + +class ReportGridPage : public wxWizardPage +{ +public: + ReportGridPage(wxWizard *parent, wxWizardPage *prev); + ~ReportGridPage(); + virtual wxWizardPage *GetPrev() const + { + return m_prev; + }; + virtual wxWizardPage *GetNext() const + { + return m_next; + }; + void SetPrev(wxWizardPage *prev) + { + m_prev = prev; + } + void SetNext(wxWizardPage *next) + { + m_next = next; + } + void populateGrid(); + wxDDGrid *getGrid() + { + return reportGrid; + }; +private: + void OnWizardPageChanging(wxWizardEvent &event); + void OnCellLeftClick(wxGridEvent &ev); + + wxStaticText *message; + wxWizardPage *m_prev, *m_next; + wxDDGrid *reportGrid; + ddGenerationWizard *wparent; + DECLARE_EVENT_TABLE() +}; +#endif diff --git a/include/dd/ddmodel/ddModelBrowser.h b/include/dd/ddmodel/ddModelBrowser.h new file mode 100644 index 0000000..54c6d4e --- /dev/null +++ b/include/dd/ddmodel/ddModelBrowser.h @@ -0,0 +1,46 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddModelBrowser.h - Tables Tree of Database Designer. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDMODELBROWSER_H +#define DDMODELBROWSER_H + +#include "dd/ddmodel/ddDatabaseDesign.h" + +enum ddBrowser +{ + DD_BROWSER = 13000 +}; + +enum ddBrowserImages +{ + DD_IMG_FIG_DATABASE = 0, + DD_IMG_FIG_TABLE = 1 +}; + +class ddModelBrowser : public wxTreeCtrl +{ +public: + ddModelBrowser(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, ddDatabaseDesign *design); + ~ddModelBrowser(); + wxTreeItemId &createRoot(wxString Name); + void refreshFromModel(); + +private: + void OnItemActivated(wxTreeEvent &event); + void OnBeginDrag(wxTreeEvent &event); + + wxTreeItemId rootNode; + ddDatabaseDesign *ownerDesign; + wxImageList *imageList; + + DECLARE_EVENT_TABLE() +}; +#endif diff --git a/include/dd/ddmodel/module.mk b/include/dd/ddmodel/module.mk new file mode 100644 index 0000000..07d6030 --- /dev/null +++ b/include/dd/ddmodel/module.mk @@ -0,0 +1,22 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/dd/ddmodel/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/dd/ddmodel/ddBrowserDataContainer.h \ + include/dd/ddmodel/ddDatabaseDesign.h \ + include/dd/ddmodel/ddDrawingEditor.h \ + include/dd/ddmodel/ddDBReverseEngineering.h \ + include/dd/ddmodel/ddDrawingView.h \ + include/dd/ddmodel/ddGenerationWizard.h \ + include/dd/ddmodel/ddModelBrowser.h + +EXTRA_DIST += \ + include/dd/ddmodel/module.mk diff --git a/include/dd/module.mk b/include/dd/module.mk new file mode 100644 index 0000000..426ff07 --- /dev/null +++ b/include/dd/module.mk @@ -0,0 +1,17 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/dd/ Makefile fragment +# +####################################################################### + +include include/dd/dditems/module.mk +include include/dd/ddmodel/module.mk + + +EXTRA_DIST += \ + include/dd/module.mk diff --git a/include/debugger/ctlMessageWindow.h b/include/debugger/ctlMessageWindow.h new file mode 100644 index 0000000..d1882bf --- /dev/null +++ b/include/debugger/ctlMessageWindow.h @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlMessageWindow.h - debugger +// +////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// class ctlMessageWindow +// +// This class implements the window that displays DBMS messages at the +// bottom of the debugger window. When we create a ctlMessageWindow, the parent +// is a ctlTabWindow (the ctlMessageWindow becomes a tab in a tab control). +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef CTLMESSAGEWINDOW_H +#define CTLMESSAGEWINDOW_H + +class ctlMessageWindow : public wxTextCtrl +{ + DECLARE_CLASS(ctlMessageWindow) + DECLARE_EVENT_TABLE() + +public: + ctlMessageWindow(wxWindow *parent, wxWindowID id); + + void AddMessage(wxString message); // Add a message to the window + void DelMessage(const char *name = NULL); // Remove a message from the window + wxString GetMessage(int row); + +protected: + wxString m_currMsg; + wxTimer m_timer; + wxMutex m_mutex; + + void OnTimer(wxTimerEvent &); +}; + +#endif diff --git a/include/debugger/ctlResultGrid.h b/include/debugger/ctlResultGrid.h new file mode 100644 index 0000000..b4844bb --- /dev/null +++ b/include/debugger/ctlResultGrid.h @@ -0,0 +1,37 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlResultGrid.h - debugger +// +////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// class ctlResultGrid +// +// A ctlResultGrid is a grid control that knows how to display that result set +// generated by a PostgreSQL query. In the workstation application, a ctlResultGrid +// is a child of the notebook owned by a ctlTabWindow. +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef CTLRESULTGRID_H +#define CTLRESULTGRID_H + +#include + +class ctlResultGrid : public wxGrid +{ + DECLARE_CLASS(ctlResultGrid) + +public: + ctlResultGrid(wxWindow *parent, wxWindowID id); + + // Copy a result set into the grid + void FillResult(pgSet *set); +}; + +#endif diff --git a/include/debugger/ctlStackWindow.h b/include/debugger/ctlStackWindow.h new file mode 100644 index 0000000..95f6d92 --- /dev/null +++ b/include/debugger/ctlStackWindow.h @@ -0,0 +1,84 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlStackWindow.h - debugger +// +////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// class ctlStackWindow +// +// This class implements the window that displays the current call stack at +// bottom of the debugger window. When we create a ctlStackWindow, the parent +// is a ctlTabWindow (the ctlStackWindow becomes a tab in a tab control). +// +// It is a simple grid control - the grid contains two columns: +// the RowLabel column displays the stack level +// column 0 displays the function name, line number and argument list +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef CTLSTACKWINDOW_H +#define CTLSTACKWINDOW_H + +#include +#include +#include +#include + +class dbgStackFrame : public wxClientData +{ +public: + dbgStackFrame(const wxString &_level, const wxString &_pkg, + const wxString &_func, const wxString &_desc) + : m_level(_level), m_func(_func), m_pkg(_pkg), m_desc(_desc) {} + + dbgStackFrame(const dbgStackFrame &s) + : m_level(s.m_level), m_func(s.m_func), m_pkg(s.m_pkg), m_desc(s.m_pkg) {} + + const wxString &GetLevel() const + { + return m_level; + } + const wxString &GetFunction() const + { + return m_func; + } + const wxString &GetPackage() const + { + return m_pkg; + } + const wxString &GetDescription() const + { + return m_desc; + } + +private: + wxString m_level, m_func, m_pkg, m_desc; +}; + +WX_DECLARE_LIST(dbgStackFrame, dbgStackFrameList); + + +class ctlStackWindow : public wxListBox +{ + DECLARE_CLASS( ctlVarWindow ) + +public: + ctlStackWindow(wxWindow *parent, wxWindowID id, + const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, + long style = wxCLIP_CHILDREN | wxSW_3D, + const wxString &name = wxT("stackWindow")); + + // Remove all frames from the stack trace + void ClearStack(); + // Add an array of frames to the stack trace + void SetStack(const dbgStackFrameList &stacks, int selected = -1); + void SelectFrame(const wxString &pkg, const wxString &frm); +}; + +#endif diff --git a/include/debugger/ctlTabWindow.h b/include/debugger/ctlTabWindow.h new file mode 100644 index 0000000..619f9bb --- /dev/null +++ b/include/debugger/ctlTabWindow.h @@ -0,0 +1,68 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// RCS-ID: +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlTabWindow.h - debugger +// +////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// class ctlTabWindow +// +// The ctlTabWindow class implements the tab control that displays at the +// bottom of the debugger window. +// +// A ctlTabWindow object holds a notebook control, a result window (a window +// that displays the result set generated by a query), and a varWindow (a +// window that displays the local variables when debugging a PL function). +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef CTLTABWINDOW_H +#define CTLTABWINDOW_H + +#include +#include + +#include "debugger/ctlVarWindow.h" +#include "debugger/ctlMessageWindow.h" +#include "debugger/ctlStackWindow.h" +#include "debugger/ctlResultGrid.h" + +WX_DECLARE_HASH_MAP(int, int, wxIntegerHash, wxIntegerEqual, wsTabHash); + +class ctlTabWindow : public ctlAuiNotebook +{ + DECLARE_CLASS(ctlTabWindow) + +public: + + ctlTabWindow(wxWindow *parent, wxWindowID id, + const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, + long style = wxCLIP_CHILDREN | wxSW_3D, + const wxString &name = wxT("layoutWindow")); + + ctlVarWindow *GetVarWindow(bool create = true); // Returns a pointer to the local-variables window (creates it if requested) + ctlVarWindow *GetPkgVarWindow(bool create = true); // Returns a pointer to the package-variables window (creates it if requested) + ctlVarWindow *GetParamWindow(bool create = true); // Returns a pointer to the parameters window (creates it if requested) + + ctlResultGrid *GetResultWindow(); // Returns a pointer to the result window (creates it if necessary) + ctlStackWindow *GetStackWindow(); // Returns a pointer to the stack-trace window (creates it if necessary) + ctlMessageWindow *GetMessageWindow(); // Returns a pointer to the DBMS messages window (creates it if necessary) + void SelectTab(wxWindowID id); + +private: + ctlResultGrid *m_resultWindow; // Displays the result set from a query + ctlVarWindow *m_varWindow; // Displays the local variables when debugging a PL function + ctlVarWindow *m_pkgVarWindow; // Displays the package variables when debugging a PL function + ctlStackWindow *m_stackWindow; // Displays the current call stack + ctlVarWindow *m_paramWindow; // Displays the parameters when debugging a PL function + ctlMessageWindow *m_messageWindow; // Displays the DBMS messages when debugging a PL function + + wsTabHash *m_tabMap; // Map window ID's to tab numbers; +}; + +#endif diff --git a/include/debugger/ctlVarWindow.h b/include/debugger/ctlVarWindow.h new file mode 100644 index 0000000..5713e99 --- /dev/null +++ b/include/debugger/ctlVarWindow.h @@ -0,0 +1,80 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlVarWindow.h - debugger +// +////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// class ctlVarWindow +// +// This class implements the window that displays PL variable values at the +// bottom of the debugger window. When we create a ctlVarWindow, the parent +// is a ctlTabWindow (the ctlVarWindow becomes a tab in a tab control). +// +// It is a simple grid control - the grid contains three columns: +// the RowLabel column displays the name of each variable +// column 0 displays the value of each variable +// column 1 displays the data type of each variable +// +// Each ctlVarWindow contains a hash map that can locate a grid cell given a +// variable name +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef CTLVARWINDOW_H +#define CTLVARWINDOW_H + +#include +#include +#include + +class ctlVarWindow : public wxGrid +{ + DECLARE_CLASS(ctlVarWindow) + +public: + ctlVarWindow(wxWindow *parent, wxWindowID id); + + // Add a variable to the window + void AddVar(wxString name, wxString value, wxString type, bool readOnly); + // Remove a variable from the window + void DelVar(wxString name = wxEmptyString); + + wxString GetVarName(int row); + wxString GetVarValue(int row); + +private: + + // The content of a grid cell is defined by the gridCell structure + typedef struct + { + int m_row; // Row number for this variable/grid cell + wxString m_value; // Variable value + wxString m_type; // Variable type + } gridCell; + + enum + { + COL_NAME = 0, // Column 0 contains the variable name + COL_TYPE, // This column contains the variable type + COL_VALUE // This column contains the variable value + }; + + // The m_cells hash translates variable names into gridCell references +public: + WX_DECLARE_STRING_HASH_MAP(gridCell, wsCellHash); + WX_DECLARE_HASH_SET(wxString, wxStringHash, wxStringEqual, wsStringSet); + +private: + wsStringSet m_hiddenNames; // List of hidden variable names + wsStringSet m_hiddenTypes; // List of hidden variable types + wsCellHash *m_cells; // name-to-gridCell map + wxFont m_nameFont; // Font used to display field names +}; + +#endif diff --git a/include/debugger/dbgBreakPoint.h b/include/debugger/dbgBreakPoint.h new file mode 100644 index 0000000..1cda8f1 --- /dev/null +++ b/include/debugger/dbgBreakPoint.h @@ -0,0 +1,49 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dbgBreakPoint.h - debugger +// +////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// class dbgBreakPoint +// +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef DBGBREAKPOINT_H +#define DBGBREAKPOINT_H + +class dbgBreakPoint +{ +public: + dbgBreakPoint(const wxString &_funcOid, const wxString &_pkgOid = wxT("-1"), + const int &_lineNo = -1) + : m_func(_funcOid), m_pkg(_pkgOid), m_lineNo(_lineNo) {} + + wxString &GetFunctionOid() + { + return m_func; + } + wxString &GetPackageOid() + { + return m_pkg; + } + int &GetLineNo() + { + return m_lineNo; + } + +private: + wxString m_func; + wxString m_pkg; + int m_lineNo; +}; + +WX_DECLARE_LIST(dbgBreakPoint, dbgBreakPointList); + +#endif diff --git a/include/debugger/dbgConst.h b/include/debugger/dbgConst.h new file mode 100644 index 0000000..7e434ef --- /dev/null +++ b/include/debugger/dbgConst.h @@ -0,0 +1,80 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dbgConst.h - debugger +// +////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// +// Constants and enumerator Identifiers for the entire debugger +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef DBGCONST_H +#define DBGCONST_H + +const int ID_BTNNEXT = 1800; +const int ID_GRDFUNCARGS = 1810; +const int ID_TXTMESSAGE = 1820; +const int ID_TIMER = 1830; +const int ID_BTNCANCEL = 1840; + +const int ID_PARAMGRID = 1000; +const int ID_VARGRID = 1001; +const int ID_MSG_PAGE = 1002; +const int ID_PKGVARGRID = 1003; + +enum +{ + MENU_ID_EXECUTE = 10001, // Execute command entered by user + + MENU_ID_TOGGLE_BREAK, // Set/Unset breakpoint + MENU_ID_CLEAR_ALL_BREAK, // Clear all breakpoints + MENU_ID_CONTINUE, // Continue + MENU_ID_STEP_OVER, // Step over + MENU_ID_STEP_INTO, // Step into + MENU_ID_STOP, // Stop debugging + + MENU_ID_START_DEBUGGING, // Spawn a separate debugger process + MENU_ID_NOTICE_RECEIVED, // NOTICE received from server + WINDOW_ID_STACK, // Tree-control window + WINDOW_ID_CONSOLE, // Console window + WINDOW_ID_TABS, // Tab window + WINDOW_ID_BREAKPOINTS, // Breakpoints window + WINDOW_ID_RESULT_GRID, // Results window + WINDOW_ID_COMMAND, // Command window + SOCKET_ID_DEBUG, // Debugger Socket ID + + MENU_ID_VIEW_TOOLBAR, // View menu options + MENU_ID_VIEW_STACKPANE, + MENU_ID_VIEW_OUTPUTPANE, + MENU_ID_VIEW_DEFAULTVIEW, + + RESULT_ID_ATTACH_TO_PORT, // Debugger - attach to port completed + RESULT_ID_BREAKPOINT, // Debugger - breakpoint reached + RESULT_ID_GET_VARS, // Debugger - variable list complete + RESULT_ID_GET_STACK, // Debugger - stack trace complete + RESULT_ID_GET_BREAKPOINTS, // Debugger - breakpoint list complete + RESULT_ID_NEW_BREAKPOINT, // Debugger - set breakpoint complete + RESULT_ID_NEW_BREAKPOINT_WAIT, // Debugger - set breakpoint complete, wait for target progress + RESULT_ID_DEL_BREAKPOINT, // Debugger - drop breakpoint complete + RESULT_ID_DEPOSIT_VALUE, // Debugger - deposit value complete + RESULT_ID_ADD_BREAKPOINT, // Debugger - target info received, now set a breakpoint + RESULT_ID_LISTENER_CREATED, // Debugger - global listener created + RESULT_ID_TARGET_READY, // Debugger - target session attached + RESULT_ID_LAST_BREAKPOINT, // Debugger - last breakpoint created + RESULT_ID_ARGS_UPDATED, // Debugger - Values are evaluated and been updated in the arguments + RESULT_ID_ARGS_UPDATE_ERROR, // Debugger - Error while evaluateling the value for the arguments + + RESULT_ID_DIRECT_TARGET_COMPLETE, // DirectDebug - target function complete + + ID_DEBUG_INITIALIZER // Debugger - debug package initializer? checkbox + +}; + +#endif diff --git a/include/debugger/dbgController.h b/include/debugger/dbgController.h new file mode 100644 index 0000000..19fe1b3 --- /dev/null +++ b/include/debugger/dbgController.h @@ -0,0 +1,183 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dbgController.h - Debugger controller +// +////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// class dbgController +// +// A dbgController object controls the behaviour of the debugger. It stays +// in the central of the whole debugger mechanism. It controls the flow of +// execution and also, asks the view to update the user presentation (when +// needed), also execute commands based on the user inputs. +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef DBGCONTROLLER_H +#define DBGCONTROLLER_H + +#include +#include + +#include "db/pgQueryResultEvent.h" +#include "debugger/dbgTargetInfo.h" +#include "debugger/dbgModel.h" + +class frmMain; +class frmDebugger; + +typedef enum +{ + DBG_SESSION_TYPE_UNKNOWN, // Session could be in-context or direct + DBG_SESSION_TYPE_INCONTEXT, // Session is configured for in-context debugging + DBG_SESSION_TYPE_DIRECT // Session is configured for direct debugging +} DebuggerSessionType; + + +typedef enum +{ + DEBUGGER_UNKNOWN_API = 0, + DEBUGGER_V1_API = 1, + DEBUGGER_V2_API = 2, + DEBUGGER_V3_API = 3 +} DebuggerApiVersion; + + +class dbgController : public wxEvtHandler +{ +public: + dbgController(frmMain *_main, pgObject *_obj, bool _directDebugging = false); + ~dbgController(); + + dbgTargetInfo *GetTargetInfo(); + dbgModel *GetModel() + { + return m_model; + } + + bool CanRestart() + { + return (m_dbgConn && (m_dbgConn->GetStatus() != PGCONN_OK)); + } + + // Debugging actions (called from the frmDebugger) + bool Start(); + void ClearBreakpoint(int _lineNo); + void SetBreakpoint(int _lineNo); + void Countinue(); + void StepOver(); + void StepInto(); + bool Stop(); + void DepositValue(const wxString &_name, const wxString &_val); + bool SelectFrame(int _frameNo); + void UpdateBreakpoints(); + + bool HandleQuery(pgBatchQuery *_qry, const wxString &_err); + + // Closing Debugger + bool CloseDebugger(); + bool ExecuteTarget(); + bool IsTerminated() + { + return m_terminated; + } + + // Event functions + void OnNoticeReceived(wxCommandEvent &); + void OnStartDebugging(wxCommandEvent &); + + void ResultTargetComplete(pgQueryResultEvent &); + void ResultPortAttach(pgQueryResultEvent &); + void ResultBreakpoint(pgQueryResultEvent &); + void ResultVarList(pgQueryResultEvent &); + void ResultStack(pgQueryResultEvent &); + void ResultBreakpoints(pgQueryResultEvent &); + void ResultNewBreakpoint(pgQueryResultEvent &); + void ResultNewBreakpointWait(pgQueryResultEvent &); + void ResultDeletedBreakpoint(pgQueryResultEvent &); + void ResultDepositValue(pgQueryResultEvent &); + void ResultListenerCreated(pgQueryResultEvent &); + void ResultTargetReady(pgQueryResultEvent &); + +private: + static void NoticeHandler(void *arg, const char *message); + +private: + const static wxString ms_cmdDebugSPLV1; + const static wxString ms_cmdDebugSPLV2; + const static wxString ms_cmdDebugPLPGSQLV1; + const static wxString ms_cmdDebugPLPGSQLV2; + const static wxString ms_cmdAttachToPort; + const static wxString ms_cmdWaitForBreakpointV1; + const static wxString ms_cmdWaitForBreakpointV2; + const static wxString ms_cmdGetVars; + const static wxString ms_cmdGetStack; + const static wxString ms_cmdGetBreakpoints; + const static wxString ms_cmdStepOverV1; + const static wxString ms_cmdStepOverV2; + const static wxString ms_cmdStepIntoV1; + const static wxString ms_cmdStepIntoV2; + const static wxString ms_cmdContinueV1; + const static wxString ms_cmdContinueV2; + const static wxString ms_cmdSetBreakpointV1; + const static wxString ms_cmdSetBreakpointV2; + const static wxString ms_cmdClearBreakpointV1; + const static wxString ms_cmdClearBreakpointV2; + const static wxString ms_cmdSelectFrameV1; + const static wxString ms_cmdSelectFrameV2; + const static wxString ms_cmdDepositValue; + const static wxString ms_cmdAbortTarget; + const static wxString ms_cmdAddBreakpointEDB; + const static wxString ms_cmdAddBreakpointPG; + const static wxString ms_cmdGetTargetInfo; + const static wxString ms_cmdCreateListener; + const static wxString ms_cmdWaitForTarget; + const static wxString ms_cmdIsBackendRunning; + +private: + // Debugger Version for the current server + DebuggerApiVersion m_ver; + + // Session type + DebuggerSessionType m_sessionType; + + // Line actually shown from this offset + int m_lineOffset; + + // Debugging Terminated + bool m_terminated; + bool m_isStopping; + + // Main Window for the debugger + frmDebugger *m_frm; + + // Connection for collecting the current debugging information + pgConn *m_dbgConn; + // Connetion Thread for fetching the debugging information in background + pgQueryThread *m_dbgThread; + // Connection to execute the function/procedure for the direct debugging + pgConn *m_execConn; + // Connection-thread to run the function in background for debugging + pgQueryThread *m_execConnThread; + // Mutex for debugger thread + wxMutex m_dbgThreadLock; + + // Debugger Data Model + dbgModel *m_model; + + // In-direct Debugging on which target-pid + wxString m_currTargetPid; + + DECLARE_EVENT_TABLE() + +}; + +#define MARKERINDEX_TO_MARKERMASK( MI ) ( 1 << MI ) + +#endif diff --git a/include/debugger/dbgModel.h b/include/debugger/dbgModel.h new file mode 100644 index 0000000..5379b6f --- /dev/null +++ b/include/debugger/dbgModel.h @@ -0,0 +1,142 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dbgModel.h - Debugger Model +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DBGMODEL_H +#define DBGMODEL_H + +#include + +#include "debugger/dbgBreakPoint.h" +#include "debugger/dbgTargetInfo.h" + +class dbgCachedStack +{ +public: + dbgCachedStack() {} + dbgCachedStack(const wxString &_pkg, const wxString &_func, + const wxString &_target, const wxString &_arg, const wxString &_src) + : m_func(_func), m_pkg(_pkg), m_source(_src), + m_target(_target), m_arg(_arg) {} + + dbgCachedStack(const dbgCachedStack &_src) + : m_func(_src.m_func), m_pkg(_src.m_pkg), m_source(_src.m_source), + m_target(_src.m_target), m_arg(_src.m_arg) {} + + dbgCachedStack &operator =(const dbgCachedStack &_src) + { + m_func = _src.m_func; + m_pkg = _src.m_pkg; + m_source = _src.m_source; + m_target = _src.m_target; + m_arg = _src.m_arg; + + return *this; + } + +private: + wxString m_pkg; // Package OID + wxString m_func; // Function OID + wxString m_target; // Target Name + wxString m_arg; // Argument passed to the target + wxString m_source; // Source code for this function + + friend class frmDebugger; +}; + +WX_DECLARE_STRING_HASH_MAP(dbgCachedStack, dbgSourceHash); + +class dbgModel +{ +public: + dbgModel(Oid _target, pgConn *_conn); + + dbgTargetInfo *GetTarget() + { + return m_target; + } + dbgBreakPointList &GetBreakPoints() + { + return m_breakpoints; + } + + wxString &GetPort() + { + return m_port; + } + wxString &GetSession() + { + return m_session; + } + wxString &GetTargetPid() + { + return m_targetPid; + } + + bool GetSource(const wxString &_funcOid, dbgCachedStack *_cached = NULL); + void ClearCachedSource(); + void AddSource(const wxString &_funcOid, const dbgCachedStack &cached); + + bool RequireDisplayUpdate() + { + return (m_focusedFuncOid != m_displayedFuncOid || + m_displayedPkgOid != m_focusedPkgOid); + } + + wxString &GetFocusedPackage() + { + return m_focusedPkgOid; + } + wxString &GetDisplayedPackage() + { + return m_displayedPkgOid; + } + wxString &GetFocusedFunction() + { + return m_focusedFuncOid; + } + wxString &GetDisplayedFunction() + { + return m_displayedFuncOid; + } + + int &GetCurrLineNo() + { + return m_currLineNo; + } + +private: + // Target Information + dbgTargetInfo *m_target; + + // Break-Points + dbgBreakPointList m_breakpoints; + + // Debugging Port, session-handle & target-backend pid + wxString m_port; + wxString m_session; + wxString m_targetPid; + + // Cached source-code for the stacked functions + dbgSourceHash m_sourceMap; + + // Current focused function-information + wxString m_focusedFuncOid; + wxString m_focusedPkgOid; + + // Current displayed function-information + wxString m_displayedFuncOid; + wxString m_displayedPkgOid; + + // Current Line number + int m_currLineNo; +}; + +#endif diff --git a/include/debugger/dbgTargetInfo.h b/include/debugger/dbgTargetInfo.h new file mode 100644 index 0000000..9ea7c9e --- /dev/null +++ b/include/debugger/dbgTargetInfo.h @@ -0,0 +1,248 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dbgTargetInfo.h - debugger +// +////////////////////////////////////////////////////////////////////////// +#ifndef DBGTARGETINFO_H +#define DBGTARGETINFO_H + +#include +#include "db/pgConn.h" +#include "db/pgQueryThread.h" + + +//////////////////////////////////////////////////////////////////////////////// +// class dbgArgInfo +// +// A dbgArgInfo object contains information about a function (or procedure) +// argument. Inside of each wsArgInfo object, we store the name of the argument, +// the argument type, and the argument mode (IN (i), OUT (o), or INOUT (b)). +// +// Once the user has had a chance to enter values for each of the IN and INOUT +// arguments, we store those values inside of the corresponding wsArgInfo objects +class dbgArgInfo +{ +public: + dbgArgInfo(const wxString &_name, const wxString &_type, Oid _typeOid, + short _mode = pgParam::PG_PARAM_IN); + + Oid GetType() + { + return m_typeOid; + } + const wxString &GetTypeName() + { + return m_type; + } + wxString &GetName() + { + return m_name; + } + short GetMode() + { + return m_mode; + } + bool IsArray() + { + return !(m_baseType.IsEmpty()); + } + const wxString &GetBaseType() + { + return m_baseType; + } + bool &Null() + { + return m_null; + } + wxString &Value() + { + return m_val; + } + + void SetDefault(const wxString &val) + { + m_hasDefault = true; + m_defValue = val; + } + wxString &Default() + { + return m_defValue; + } + bool HasDefault() + { + return m_hasDefault; + } + bool &UseDefault() + { + return m_useDefault; + } + + pgParam *GetParam(wxMBConv *_conv = NULL); + +private: + dbgArgInfo(const dbgArgInfo &_arg) + { + wxASSERT(0); + } + + dbgArgInfo &operator= (const dbgArgInfo &) + { + wxASSERT(0); + return *this; + } + + wxString m_name; /* Name of the argument */ + wxString m_type; /* Type of the argument */ + wxString m_baseType; /* Base type of an array type */ + wxString m_defValue; /* Default Value */ + Oid m_typeOid; /* OID of Type */ + short m_mode; /* IN, IN OUT, OUT, or VARAIDIC */ + bool m_hasDefault; /* Has the default value? */ + bool m_useDefault; /* Use the default value? */ + bool m_null; /* Is Value NULL */ + wxString m_val; /* Value */ +}; + +WX_DEFINE_ARRAY_PTR(dbgArgInfo *, pgDbgArgs); + +//////////////////////////////////////////////////////////////////////////////// +// class dbgTargetInfo +// +// This class implements a container that holds information necessary to invoke +// a debugger target (a function or procedure). +// +// When the constructor is called, it sends a query to the server to retreive: +// the OID of the target, +// the name of the target, +// the name of the schema in which the target is defined +// the name of the language in which the target is defined +// the number of arguments expected by the target +// the argument names +// the argument types +// the argument modes (IN, OUT, or INOUT) +// the target type (function or procedure) +// +// This class offers a number of (inline) member functions that you can call +// to extract the above information after it's been queried from the server. +// +class dbgTargetInfo +{ +public: + dbgTargetInfo(Oid _target, pgConn *_conn); + + const wxString &GetQualifiedName() + { + return m_fqName; + } + + const wxString &GetLanguage() + { + return m_language; + } + + const wxString &GetPackageName() + { + return m_package; + } + const wxString &GetSchemaName() + { + return m_schema; + } + + const wxString &GetName() + { + return m_name; + } + + const wxString &GetReturnType() + { + return m_returnType; + } + + long GetOid() + { + return m_oid; + } + + long GetPkgOid() + { + return m_pkgOid; + } + + long GetSchemaOid() + { + return m_schemaOid; + } + + long GetPkgInitOid() + { + return m_pkgInitOid; + } + + bool GetIsFunction() + { + return m_isFunction; + } + + bool GetReturnsSet() + { + return m_returnsSet; + } + + bool RequireUserInput() + { + return ((m_pkgOid != 0 && m_pkgInitOid != 0) || m_inputParamCnt != 0); + } + + bool &DebugPackageConstructor() + { + return m_debugPkgCon; + } + + dbgArgInfo *operator[](int index); + + pgDbgArgs *GetArgs() + { + return m_args; + } + + bool HasVariadic() + { + return m_hasVariadic; + } + + bool AddForExecution(pgQueryThread *_thread); + +private: + wxString m_name; // Target name (function or procedure) + wxString m_schema; // Schema in which target resides + wxString m_package; // Package in which target resides + wxString m_language; // Language in which target is defined + + wxString m_returnType; // Return type + wxString m_funcSignature; // Function Signature + + wxString m_fqName; // Function qualified name + + bool m_isFunction; // true->target is a function, false->target is a procedure + bool m_returnsSet; // Returns a set? + bool m_hasVariadic; // Has the variadic argument + + bool m_debugPkgCon; // Debug Package Constructor + + long m_oid; // Target function/procedure OID + long m_pkgOid; // Package in which target defined (if non-zero) + long m_pkgInitOid; // OID of the package initializer function. + long m_schemaOid; // OID of the schema + + size_t m_inputParamCnt; // IN/IN OUT parameter count + + pgDbgArgs *m_args; // Function arguments +}; + +#endif diff --git a/include/debugger/debugger.h b/include/debugger/debugger.h new file mode 100644 index 0000000..2574908 --- /dev/null +++ b/include/debugger/debugger.h @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// debugger.h - Debugger factories +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DEBUGGER_H +#define DEBUGGER_H + +// wxWindows headers +#include + +/////////////////////////////////////////////////// +// Debugger factory +/////////////////////////////////////////////////// +class debuggerFactory : public actionFactory +{ +public: + debuggerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +/////////////////////////////////////////////////// +// Breakpoint factory +/////////////////////////////////////////////////// +class breakpointFactory : public actionFactory +{ +public: + breakpointFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif + + diff --git a/include/debugger/dlgDirectDbg.h b/include/debugger/dlgDirectDbg.h new file mode 100644 index 0000000..11594b4 --- /dev/null +++ b/include/debugger/dlgDirectDbg.h @@ -0,0 +1,126 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgDirectDbg.h - debugger +// +////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// class dlgDirectDbg +// +// This class implements 'direct-debugging'. In direct-debugging, the user +// provides a function signature, procedure signature, or OID on the command +// line (this identifies the debug target). We query the server for the +// names, types, and in/out modes for each target parameter and then prompt +// the user to enter a value for each of the IN (and IN/OUT) parameters. +// +// When the user fills in the parameter values and clicks OK, we set a +// breakpoint at the target and then execute a SELECT statement or an +// EXEC statement that invokes the target (with the parameter values +// provided by the user). +// +// A dlgDirectDbg object is typically a child of the frmDebugger object +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef DLGDIRECTDBG_H +#define DLGDIRECTDBG_H + +#include +#include +#include + +#include "dlg/dlgClasses.h" + +class dbgArgInfo; +class frmDebugger; +class dbgController; + +class ctlGridCellBoolEditor : public wxGridCellBoolEditor +{ +public: + ctlGridCellBoolEditor(dbgArgInfo *_arg = NULL); + void BeginEdit (int _row, int _col, wxGrid *_grid); + wxGridCellEditor *Clone() const; + + dbgArgInfo *GetArg() + { + return m_arg; + } + +private: + dbgArgInfo *m_arg; +}; + +class dlgDirectDbg; + +class dbgArgValueEvaluator : public wxThread +{ +public: + dbgArgValueEvaluator(pgConn *, dlgDirectDbg *); + + void *Entry(); + void CancelEval(); + static void NoticeHandler(void *, const char *); + +private: + pgConn *m_conn; + dlgDirectDbg *m_dlg; + + bool m_cancelled; +}; + + +class dlgDirectDbg : public pgDialog +{ + DECLARE_CLASS(dlgDirectDbg) + +public: + dlgDirectDbg(frmDebugger *_parent, dbgController *_controller, + pgConn *_conn); + + enum + { + COL_NAME = 0, // Column 0 contains the variable name + COL_TYPE, // Type of column + COL_NULL, // Value Set to NULL (yes/no) + COL_EXPR, // Value is an expression (yes/no) + COL_VALUE, // Value (constant ,or an expression) + COL_USE_DEF, // Use the default value + COL_DEF_VAL // Default value for the column + }; + +private: + + void PopulateParamGrid(); + + void OnOk(wxCommandEvent &event); + void OnCancel(wxCommandEvent &event); + void OnClickGridLabel(wxGridEvent &event); + + void ResultArgsUpdated(wxCommandEvent &); + void ResultArgsUpdateError(wxCommandEvent &); + + void SaveSettings(); + void LoadSettings(); + // Function to retrive last cell value if the provieded parameter value is an invalid. + void LoadLastCellSetting(int row_number, int array_row_number, + int index_number, bool isArray); + + wxGrid *GetParamsGrid(); + bool DebugPkgConstructor(); + + dbgController *m_controller; + pgConn *m_conn; + dbgArgValueEvaluator *m_thread; + + friend class dbgArgValueEvaluator; + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/debugger/frmDebugger.h b/include/debugger/frmDebugger.h new file mode 100644 index 0000000..666f97a --- /dev/null +++ b/include/debugger/frmDebugger.h @@ -0,0 +1,176 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmDebugger.h - debugger +// +////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// class frmDebugger +// +// frmDebugger manages the user interface for the workstation. This class +// manages the toolbar, menu, status bar, and top-level windows. +// +// This class also defines event handlers for a number of high-level events +// (such as window sizing and layout, and creation of new windows). +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef FRMDEBUGGER_H +#define FRMDEBUGGER_H + +#include +#include + +#include "ctl/ctlProgressStatusBar.h" + +// +// This number MUST be incremented if changing any of the default perspectives +// +#define FRMDEBUGGER_PERSPECTIVE_VER wxT("8189") + +#ifdef __WXMAC__ +#define FRMDEBUGGER_DEFAULT_PERSPECTIVE wxT("layout2|name=toolBar;caption=Toolbar;state=2108144;dir=1;layer=10;row=0;pos=1;prop=100000;bestw=154;besth=23;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=sourcePane;caption=Source pane;state=1020;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=350;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=stackPane;caption=Stack pane;state=2099196;dir=2;layer=0;row=0;pos=0;prop=100000;bestw=250;besth=200;minw=100;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=outputPane;caption=Output pane;state=2099196;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=550;besth=300;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(1,10,0)=25|dock_size(5,0,0)=237|dock_size(2,0,0)=237|dock_size(3,0,0)=156|") +#else +#ifdef __WXGTK__ +#define FRMDEBUGGER_DEFAULT_PERSPECTIVE wxT("layout2|name=toolBar;caption=Toolbar;state=2108144;dir=1;layer=10;row=0;pos=1;prop=100000;bestw=205;besth=30;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=sourcePane;caption=Source pane;state=1020;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=350;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=stackPane;caption=Stack pane;state=2099196;dir=2;layer=0;row=0;pos=0;prop=100000;bestw=250;besth=200;minw=100;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=outputPane;caption=Output pane;state=2099196;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=550;besth=300;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(1,10,0)=25|dock_size(5,0,0)=237|dock_size(2,0,0)=237|dock_size(3,0,0)=156|") +#else +#define FRMDEBUGGER_DEFAULT_PERSPECTIVE wxT("layout2|name=toolBar;caption=Toolbar;state=2108144;dir=1;layer=10;row=0;pos=1;prop=100000;bestw=154;besth=23;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=sourcePane;caption=Source pane;state=1020;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=350;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=stackPane;caption=Stack pane;state=2099196;dir=2;layer=0;row=0;pos=0;prop=100000;bestw=250;besth=200;minw=100;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=outputPane;caption=Output pane;state=2099196;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=550;besth=300;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(1,10,0)=25|dock_size(5,0,0)=237|dock_size(2,0,0)=237|dock_size(3,0,0)=156|") +#endif +#endif + +// Debugger Controller +class dbgController; +class frmMain; +class ctlTabWindow; +class ctlResultGrid; +class ctlVarWindow; +class ctlSQLBox; +class dbgCachedStack; + +class frmDebugger : public pgFrame +{ + DECLARE_CLASS(frmDebugger) + +public: + frmDebugger(frmMain *_parent, dbgController *_controller, + const wxString &_title); + virtual ~frmDebugger(); + + void SetupDebugger(); + + void SetStatusText(const wxString &_status); + + ctlTabWindow *GetTabWindow() + { + return m_tabWindow; + } + ctlStackWindow *GetStackWindow() + { + return m_stackWindow; + } + ctlMessageWindow *GetMessageWindow() + { + return m_tabWindow->GetMessageWindow(); + } + + ctlVarWindow *GetVarWindow(bool create) + { + return m_tabWindow->GetVarWindow(create); + } + ctlVarWindow *GetParamWindow(bool create) + { + return m_tabWindow->GetParamWindow(create); + } + ctlVarWindow *GetPkgVarWindow(bool create) + { + return m_tabWindow->GetPkgVarWindow(create); + } + ctlResultGrid *GetResultWindow() + { + return m_tabWindow->GetResultWindow(); + } + + void DisplaySource(dbgCachedStack &); + + void EnableToolsAndMenus(bool enable = true); + void UnhilightCurrentLine(); + void HighlightLine(int _lineNo); + void ClearBreakpointMarkers(); + void MarkBreakpoint(int lineNo); + void CloseProgressBar(); + void LaunchWaitingDialog(const wxString &msg = wxEmptyString); + +private: + + int GetLineNo(); + bool IsBreakpoint(int _lineNo); + void ClearAllBreakpoints(); + + wxMenuBar *SetupMenuBar( void ); + ctlMenuToolbar *SetupToolBar( void ); + ctlProgressStatusBar *SetupStatusBar( void ); + + enum + { + MARKER_CURRENT = 0x02, // Current line marker + MARKER_CURRENT_BG = 0x04, // Current line marker - background hilight + MARKER_BREAKPOINT = 0x01, // Breakpoint marker + }; + +private: + // Menu bar + wxMenuBar *m_menuBar; + // Frames' toolbar + ctlMenuToolbar *m_toolBar; + // View menu (can be modified by wxCodeWindow) + wxMenu *m_viewMenu; + // Debug menu (can be modified by wxCodeWindow) + wxMenu *m_debugMenu; + + wxAuiManager m_manager; + // Frame's status bar + ctlProgressStatusBar *m_statusBar; + // Main Frame + frmMain *m_parent; + // Debugger Controller + dbgController *m_controller; + + // Stack Window + ctlStackWindow *m_stackWindow; + // Tab Window + ctlTabWindow *m_tabWindow; + // Function Code Viewer + ctlSQLBox *m_codeViewer; + + // Operation Status + wxString m_statusTxt; + + DECLARE_EVENT_TABLE() + + void OnExecute(wxCommandEvent &_ev); + void OnDebugCommand(wxCommandEvent &_ev); + void OnSelectFrame(wxCommandEvent &_ev); + // Toggle break-point on margin click + void OnMarginClick(wxStyledTextEvent &_ev); + void OnPositionStc(wxStyledTextEvent &_ev); + void OnVarChange(wxGridEvent &_ev); + void OnClose(wxCloseEvent &_ev); + void OnExit(wxCommandEvent &_ev); + void OnSize(wxSizeEvent &_ev); + void OnEraseBackground(wxEraseEvent &_ev); + void OnHelp(wxCommandEvent &_ev); + void OnContents(wxCommandEvent &_ev); + + void OnToggleToolBar(wxCommandEvent &_ev); + void OnToggleStackPane(wxCommandEvent &_ev); + void OnToggleOutputPane(wxCommandEvent &_ev); + void OnAuiUpdate(wxAuiManagerEvent &_ev); + void OnDefaultView(wxCommandEvent &_ev); +}; + +#endif diff --git a/include/debugger/module.mk b/include/debugger/module.mk new file mode 100644 index 0000000..b8b421d --- /dev/null +++ b/include/debugger/module.mk @@ -0,0 +1,30 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/debugger/include/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/debugger/dbgController.h \ + include/debugger/dbgModel.h \ + include/debugger/ctlMessageWindow.h \ + include/debugger/ctlResultGrid.h \ + include/debugger/ctlStackWindow.h \ + include/debugger/ctlTabWindow.h \ + include/debugger/ctlVarWindow.h \ + include/debugger/dbgBreakPoint.h \ + include/debugger/dbgConst.h \ + include/debugger/dbgTargetInfo.h \ + include/debugger/debugger.h \ + include/debugger/dlgDirectDbg.h \ + include/debugger/frmDebugger.h + +EXTRA_DIST += \ + include/debugger/module.mk + + diff --git a/include/dlg/dlgAddFavourite.h b/include/dlg/dlgAddFavourite.h new file mode 100644 index 0000000..3ceb2eb --- /dev/null +++ b/include/dlg/dlgAddFavourite.h @@ -0,0 +1,39 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgAddFavourite.h - Add a favourite +// +////////////////////////////////////////////////////////////////////////// + +#ifndef dlgAddFavourite_H +#define dlgAddFavourite_H + +#include "dlg/dlgClasses.h" +#include "utils/favourites.h" + +// Class declarations +class dlgAddFavourite : public pgDialog +{ +public: + dlgAddFavourite(wxWindow *parent, queryFavouriteFolder *favourites); + ~dlgAddFavourite(); + int AddFavourite(wxString newtext); + +private: + queryFavouriteFolder *favourites; + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnChange(wxCommandEvent &ev); + void OnTreeChange(wxTreeEvent &ev); + void OnNewFolder(wxCommandEvent &ev); + + bool anythingChanged; + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgAggregate.h b/include/dlg/dlgAggregate.h new file mode 100644 index 0000000..8bafb41 --- /dev/null +++ b/include/dlg/dlgAggregate.h @@ -0,0 +1,79 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgAggregate.h - Aggregate properties dialog +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __DLG_AGGREGATEPROP +#define __DLG_AGGREGATEPROP + +#include "dlg/dlgProperty.h" +#include "ctl/ctlSeclabelPanel.h" + +class pgSchema; +class pgAggregate; + +class dlgAggregate : public dlgTypeProperty +{ +public: + dlgAggregate(pgaFactory *factory, frmMain *frame, pgAggregate *agg, pgSchema *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +protected: + /* + * Aggregate Privileges: + * - Did not inherit dlgTypeProperty & dlgSecurityProperty as it will + * lead to a lot of problem later + **/ + + ctlSecurityPanel *securityPage; + wxArrayString currentAcl; + wxArrayString groups; + bool securityChanged; + + wxString GetGrant(const wxString &allPattern, const wxString &grantObject); + + void OnAddPriv(wxCommandEvent &ev); + void OnDelPriv(wxCommandEvent &ev); + +private: + pgSchema *schema; + pgAggregate *aggregate; + ctlSeclabelPanel *seclabelPage; + + virtual wxString GetDisplayName() + { + return GetName() + wxT("(") + GetInputTypesList() + wxT(")"); + }; + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnChange(wxCommandEvent &event); + void OnChangeType(wxCommandEvent &ev); + void OnChangeTypeBase(wxCommandEvent &ev); + void OnChangeTypeState(wxCommandEvent &ev); + + void OnAddInputType(wxCommandEvent &ev); + void OnRemoveInputType(wxCommandEvent &ev); + void OnSelectInputType(wxListEvent &ev); + + long GetInputTypeOid(int param); + wxString GetInputTypesList(); + wxString GetInputTypesOidList(); + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgCast.h b/include/dlg/dlgCast.h new file mode 100644 index 0000000..31ab176 --- /dev/null +++ b/include/dlg/dlgCast.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgCast.h - Cast property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_CASTPROP +#define __DLG_CASTPROP + +#include "dlg/dlgProperty.h" + +class pgCast; + +class dlgCast : public dlgTypeProperty +{ +public: + dlgCast(pgaFactory *factory, frmMain *frame, pgCast *ca); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + void OnChangeType(wxCommandEvent &ev); + void OnChangeTypeSrc(wxCommandEvent &ev); + void OnChangeTypeTrg(wxCommandEvent &ev); + + pgCast *cast; + wxArrayString functions; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgCheck.h b/include/dlg/dlgCheck.h new file mode 100644 index 0000000..3a4dea3 --- /dev/null +++ b/include/dlg/dlgCheck.h @@ -0,0 +1,47 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgCheck.h - Check property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_CHECKPROP +#define __DLG_CHECKPROP + +#include "dlg/dlgProperty.h" + +class pgCheck; +class pgObject; + +class dlgCheck : public dlgProperty +{ +public: + dlgCheck(pgaFactory *factory, frmMain *frame, pgCheck *node = 0, pgObject *parentNode = 0); + + void CheckChange(); + wxString GetSql(); + wxString GetDefinition(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + wxString GetHelpPage() const + { + return wxT("pg/sql-altertable"); + } + + int Go(bool modal); + +private: + pgCheck *check; + pgObject *object; + + void OnChangeValidate(wxCommandEvent &ev); + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgClasses.h b/include/dlg/dlgClasses.h new file mode 100644 index 0000000..c8b44b1 --- /dev/null +++ b/include/dlg/dlgClasses.h @@ -0,0 +1,189 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgClasses.h - Some dialogue base classes +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DLGCLASSES_H +#define DLGCLASSES_H + +#include + +WX_DECLARE_LIST(wxWindow, windowList); + +#define btnOK CTRL_BUTTON("wxID_OK") +#define btnCancel CTRL_BUTTON("wxID_CANCEL") + + +class frmMain; +class pgObject; +class pgQueryThread; +class ctlMenuToolbar; + +class pgDialog : public wxDialog +{ +public: + pgDialog() + { + statusBar = 0; + } + void RestorePosition(int defaultX = -1, int defaultY = -1, int defaultW = -1, int defaultH = -1, int minW = -1, int minH = -1); + void SavePosition(); + void LoadResource(wxWindow *parent, const wxChar *name = 0); + +protected: + void OnCancel(wxCommandEvent &ev); + void OnClose(wxCloseEvent &event); + void AddStatusBar(); + + void PostCreation(); + wxString dlgName; + wxStatusBar *statusBar; + + DECLARE_EVENT_TABLE() +}; + + +class menuFactoryList; + +class pgFrame : public wxFrame +{ +public: + pgFrame(wxFrame *parent, const wxString &title, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long flags = wxDEFAULT_FRAME_STYLE) ; + ~pgFrame(); + void RemoveFrame(wxWindow *frame); + void AddFrame(wxWindow *wnd) + { + frames.Append(wnd); + } + void RestorePosition(int defaultX = -1, int defaultY = -1, int defaultW = -1, int defaultH = -1, int minW = 100, int minH = 70); + void SavePosition(); + void OnAction(wxCommandEvent &event); + + void UpdateRecentFiles(bool updatefile = true); + + menuFactoryList *GetMenuFactories() + { + return menuFactories; + } + +protected: + + void OnKeyDown(wxKeyEvent &event); + void OnExit(wxCommandEvent &event); + void OnRecent(wxCommandEvent &event); + void OnHelp(wxCommandEvent &event); + + virtual void OpenLastFile() {} + virtual bool CheckChanged(bool canVeto) + { + return false; + } + virtual wxString GetHelpPage() const + { + return wxEmptyString; + } + + windowList frames; + menuFactoryList *menuFactories; + wxString dlgName; + wxString lastFilename, lastDir, lastPath; + wxString recentKey; + wxMenu *fileMenu, *editMenu, *viewMenu, *recentFileMenu, *helpMenu; + wxStatusBar *statusBar; + wxMenuBar *menuBar; + ctlMenuToolbar *toolBar; + bool changed; + + DECLARE_EVENT_TABLE() +}; + + +class DialogWithHelp : public pgDialog +{ +public: + DialogWithHelp(frmMain *frame); + +protected: + frmMain *mainForm; + void OnHelp(wxCommandEvent &ev); + +private: + virtual wxString GetHelpPage() const = 0; + DECLARE_EVENT_TABLE() +}; + +class ExecutionDialog : public DialogWithHelp +{ +public: + ExecutionDialog(frmMain *frame, pgObject *_object); + virtual wxString GetSql() = 0; + + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnClose(wxCloseEvent &event); + + void Abort(); + +protected: + + void EnableOK(const bool enable); + + pgConn *conn; + pgObject *object; + pgQueryThread *thread; + wxTextCtrl *txtMessages; + +private: + bool bIsAborted; + bool bIsExecutionStarted; + bool bIsExecutionCompleted; + + DECLARE_EVENT_TABLE() +}; + + + +class sysProcess; +class wxProcessEvent; +class wxTimer; +class wxTimerEvent; +class ExternProcessDialog : public DialogWithHelp +{ +public: + ExternProcessDialog(frmMain *frame); + ~ExternProcessDialog(); + virtual wxString GetDisplayCmd(int version) = 0; + virtual wxString GetCmd(int step) = 0; + bool Execute(int step = 0, bool finalStep = true); + void Abort(); + +protected: + wxTextCtrl *txtMessages; + sysProcess *process; + bool done, final; + long processID; + wxArrayString environment; + +#if __GNUC__ >= 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +public: +#endif + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnClose(wxCloseEvent &event); +protected: + + void OnEndProcess(wxProcessEvent &event); + void OnPollProcess(wxTimerEvent &event); + void checkStreams(); + + wxTimer *timer; + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgCollation.h b/include/dlg/dlgCollation.h new file mode 100644 index 0000000..7981dab --- /dev/null +++ b/include/dlg/dlgCollation.h @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgCollation.h - Collation property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_COLLATIONPROP +#define __DLG_COLLATIONPROP + +#include "dlg/dlgProperty.h" + +class pgSchema; +class pgCollation; + +class dlgCollation : public dlgTypeProperty +{ +public: + dlgCollation(pgaFactory *factory, frmMain *frame, pgCollation *coll, pgSchema *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + void OnSelChangeTyp(wxCommandEvent &ev); + + pgSchema *schema; + pgCollation *collation; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgColumn.h b/include/dlg/dlgColumn.h new file mode 100644 index 0000000..aada503 --- /dev/null +++ b/include/dlg/dlgColumn.h @@ -0,0 +1,104 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgColumn.h - Column property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_COLUMNPROP +#define __DLG_COLUMNPROP + +#include "dlg/dlgProperty.h" +#include "ctl/ctlSeclabelPanel.h" + +class pgColumn; +class pgTable; + +class dlgColumn : public dlgTypeProperty +{ +public: + dlgColumn(pgaFactory *factory, frmMain *frame, pgColumn *column, pgTable *parentNode); + void SetSecurityPage(const pgColumn *node); + void CheckChange(); + void SetChangedCol(pgColumn *changedCol); + void ApplyChangesToObj(pgColumn *changedCol); + void ApplyChangesToDlg(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + wxString GetDefinition(); + void GetVariableList(wxArrayString &); + void GetSecLabelList(wxArrayString &); + wxString GetPreviousDefinition() + { + return previousDefinition; + } + wxString GetComment() + { + return txtComment->GetValue(); + } + wxString GetStatistics() + { + return CTRL_TEXT("txtAttstattarget")->GetValue(); + } + wxString GetTypeOid(); + + int Go(bool modal); + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createtable"); + } + +protected: + /* + * Column Level Privileges: + * - Did not inherit dlgTypeProperty & dlgSecurityProperty as, it will + * lead to a lot of problem later + **/ + + ctlSecurityPanel *securityPage; + wxArrayString currentAcl; + wxArrayString groups; + bool securityChanged; + ctlSeclabelPanel *seclabelPage; + + void OnChange(wxCommandEvent &event); + + wxString GetGrant(const wxString &allPattern, const wxString &grantObject); + + void OnAddPriv(wxCommandEvent &ev); + void OnDelPriv(wxCommandEvent &ev); + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnVarAdd(wxCommandEvent &ev); + void OnVarRemove(wxCommandEvent &ev); + void OnVarSelChange(wxListEvent &ev); + void OnVarnameSelChange(wxCommandEvent &ev); + void SetupVarEditor(int var); + +private: + pgColumn *column; + pgTable *table; + pgColumn *changedColumn; + wxArrayString varInfo; + bool dirtyVars; + + void OnSelChangeTyp(wxCommandEvent &ev); + + wxString previousDefinition; + wxArrayString sequences; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgConnect.h b/include/dlg/dlgConnect.h new file mode 100644 index 0000000..89c1b0d --- /dev/null +++ b/include/dlg/dlgConnect.h @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgConnect.h - Connect to a database +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DLGCONNECT_H +#define DLGCONNECT_H + +#include "dlg/dlgClasses.h" + +// Class declarations +class dlgConnect : public DialogWithHelp +{ +public: + dlgConnect(frmMain *form, const wxString &description, bool needPwd); + ~dlgConnect(); + wxString GetHelpPage() const; + + + wxString GetPassword(); + bool GetStorePwd(); + int Go(); + +private: + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgConversion.h b/include/dlg/dlgConversion.h new file mode 100644 index 0000000..584d8ed --- /dev/null +++ b/include/dlg/dlgConversion.h @@ -0,0 +1,41 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgConversion.h - Conversion property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_CONVERSIONPROP +#define __DLG_CONVERSIONPROP + +#include "dlg/dlgProperty.h" + +class pgSchema; +class pgConversion; + +class dlgConversion : public dlgProperty +{ +public: + dlgConversion(pgaFactory *factory, frmMain *frame, pgConversion *cc, pgSchema *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + pgConversion *conversion; + pgSchema *schema; + wxArrayString functions; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgDatabase.h b/include/dlg/dlgDatabase.h new file mode 100644 index 0000000..9773fa8 --- /dev/null +++ b/include/dlg/dlgDatabase.h @@ -0,0 +1,71 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgDatabase.h - Database property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_DATABASEPROP +#define __DLG_DATABASEPROP + +#include "dlg/dlgProperty.h" +#include "ctl/ctlSeclabelPanel.h" + +class pgDatabase; + +class dlgDatabase : public dlgDefaultSecurityProperty +{ +public: + dlgDatabase(pgaFactory *factory, frmMain *frame, pgDatabase *db); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + wxString GetSql2(); + bool GetDisconnectFirst(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + wxString GetHelpPage() const; + +private: + pgDatabase *database; + wxArrayString varInfo; + bool schemaRestrictionOk; + ctlSeclabelPanel *seclabelPage; + + void OnChange(wxCommandEvent &event); + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + void OnChangeRestr(wxCommandEvent &ev); + void OnGroupAdd(wxCommandEvent &ev); + void OnGroupRemove(wxCommandEvent &ev); + + void OnVarAdd(wxCommandEvent &ev); + void OnVarRemove(wxCommandEvent &ev); + void OnVarSelChange(wxListEvent &ev); + void OnCollateSelChange(wxCommandEvent &ev); + void OnCTypeSelChange(wxCommandEvent &ev); + void OnConnLimitChange(wxCommandEvent &ev); + + void OnVarnameSelChange(wxCommandEvent &ev); + void OnOK(wxCommandEvent &ev); + + void SetupVarEditor(int var); + bool executeDDLSql(const wxString &strSql); + + bool dirtyVars; + + DECLARE_EVENT_TABLE() + + friend class pgDatabaseFactory; +}; + + +#endif diff --git a/include/dlg/dlgDomain.h b/include/dlg/dlgDomain.h new file mode 100644 index 0000000..07f7418 --- /dev/null +++ b/include/dlg/dlgDomain.h @@ -0,0 +1,53 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgDomain.h - Domain property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_DOMAINPROP +#define __DLG_DOMAINPROP + +#include "dlg/dlgProperty.h" +#include "ctl/ctlSeclabelPanel.h" + +class pgSchema; +class pgDomain; + +class dlgDomain : public dlgTypeProperty +{ +public: + dlgDomain(pgaFactory *factory, frmMain *frame, pgDomain *dom, pgSchema *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + void OnSelChangeTyp(wxCommandEvent &ev); + void OnChangeValidate(wxCommandEvent &ev); + + void OnAddConstr(wxCommandEvent &ev); + void OnRemoveConstr(wxCommandEvent &ev); + void OnSelChangeConstr(wxListEvent &ev); + + pgSchema *schema; + pgDomain *domain; + ctlSeclabelPanel *seclabelPage; + wxArrayString previousConstraints, constraintsDefinition; + wxTreeItemId constraintsItem; + + void OnChange(wxCommandEvent &event); + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgEditGridOptions.h b/include/dlg/dlgEditGridOptions.h new file mode 100644 index 0000000..eb07b2e --- /dev/null +++ b/include/dlg/dlgEditGridOptions.h @@ -0,0 +1,72 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgEditGridOptions.h - Edit grid options +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __DLGEDITGRIDOPTIONS_H +#define __DLGEDITGRIDOPTIONS_H + +// wxWindows headers +#include +#include + +#ifdef __WX_FULLSOURCE +#include "wx/generic/gridsel.h" +#else +#include "ctl/wxgridsel.h" +#endif + +#include + +#include "dlg/dlgClasses.h" +class ctlSQLEditGrid; +class ctlSQLBox; +class pgConn; +class frmEditGrid; +//////////////////////////////////////////////////////////////////////////////// +// Class declaration +//////////////////////////////////////////////////////////////////////////////// + +class dlgEditGridOptions : public pgDialog +{ +public: + + // Construction + dlgEditGridOptions(frmEditGrid *parent, pgConn *conn, const wxString &rel, ctlSQLEditGrid *grid); + ~dlgEditGridOptions(); + +private: + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnFilterChange(wxStyledTextEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnClose(wxCloseEvent &ev); + void OnOK(wxCommandEvent &ev); + void OnRemove(wxCommandEvent &ev); + void OnAsc(wxCommandEvent &ev); + void OnDesc(wxCommandEvent &ev); + void OnValidate(wxCommandEvent &ev); + void OnCboColumnsChange(wxCommandEvent &ev); + void OnLstSortColsChange(wxListEvent &ev); + bool Validate(); + frmEditGrid *parent; + pgConn *connection; + wxString relation; + ctlSQLEditGrid *editGrid; + ctlSQLBox *filter; + wxMBConv *conv; + + // Macros + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgEventTrigger.h b/include/dlg/dlgEventTrigger.h new file mode 100644 index 0000000..829150d --- /dev/null +++ b/include/dlg/dlgEventTrigger.h @@ -0,0 +1,50 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgEventTrigger.h - Event trigger property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_EVENTTRIGGERPROP +#define __DLG_EVENTTRIGGERPROP + +#include "dlg/dlgProperty.h" +#include "ctl/ctlSeclabelPanel.h" + +class pgEventTrigger; + +class dlgEventTrigger : public dlgProperty +{ +public: + dlgEventTrigger(pgaFactory *factory, frmMain *frame, pgEventTrigger *evntrig, pgObject *parent); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + bool CanDropCascaded() + { + return true; + } + +private: + pgEventTrigger *eventTrigger; + ctlSeclabelPanel *seclabelPage; + void OnChange(wxCommandEvent &ev); + void OnChangeEnable(wxCommandEvent &ev); + virtual bool IsUpToDate(); + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + DECLARE_EVENT_TABLE() +}; + + +#endif \ No newline at end of file diff --git a/include/dlg/dlgExtTable.h b/include/dlg/dlgExtTable.h new file mode 100644 index 0000000..d1f6fac --- /dev/null +++ b/include/dlg/dlgExtTable.h @@ -0,0 +1,50 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgExtTable.h - Greenplum External Table property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_EXTTABLEPROP +#define __DLG_EXTTABLEPROP + +#include "dlg/dlgProperty.h" + +class pgSchema; +class gpExtTable; +class ctlSQLBox; + +class dlgExtTable : public dlgSecurityProperty +{ +public: + dlgExtTable(pgaFactory *factory, frmMain *frame, gpExtTable *v, pgSchema *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + + void SetObject(pgObject *obj) + { + extTable = (gpExtTable *)obj; + } + +private: + + virtual bool IsUpToDate(); + + pgSchema *schema; + gpExtTable *extTable; + wxString oldDefinition; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgExtension.h b/include/dlg/dlgExtension.h new file mode 100644 index 0000000..3092cd0 --- /dev/null +++ b/include/dlg/dlgExtension.h @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgExtension.h - Extension property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_EXTENSIONPROP +#define __DLG_EXTENSIONPROP + +#include "dlg/dlgProperty.h" + +class pgExtension; + +class dlgExtension : public dlgProperty +{ +public: + dlgExtension(pgaFactory *factory, frmMain *frame, pgExtension *ext); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + pgExtension *extension; + void OnChangeName(wxCommandEvent &ev); +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgFindReplace.h b/include/dlg/dlgFindReplace.h new file mode 100644 index 0000000..3025020 --- /dev/null +++ b/include/dlg/dlgFindReplace.h @@ -0,0 +1,45 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgFindReplace.h - Search and replace +// +////////////////////////////////////////////////////////////////////////// + +#ifndef dlgFindReplace_H +#define dlgFindReplace_H + +#include "dlg/dlgClasses.h" + +class ctlSQLBox; + +// Class declarations +class dlgFindReplace : public pgDialog +{ +public: + dlgFindReplace(ctlSQLBox *parent); + ~dlgFindReplace(); + void FocusSearch(); + void FindNext(); + void SetFindString(const wxString &val); + +private: + + void OnClose(wxCloseEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnChange(wxCommandEvent &ev); + void OnFind(wxCommandEvent &ev); + void OnReplace(wxCommandEvent &ev); + void OnReplaceAll(wxCommandEvent &ev); + void ResetTabOrder(); + void SaveSettings(); + + ctlSQLBox *sqlbox; + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgForeignDataWrapper.h b/include/dlg/dlgForeignDataWrapper.h new file mode 100644 index 0000000..34c787c --- /dev/null +++ b/include/dlg/dlgForeignDataWrapper.h @@ -0,0 +1,51 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgForeignDataWrapper.h - Foreign Data Wrapper property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_FOREIGNDATAWRAPPERPROP +#define __DLG_FOREIGNDATAWRAPPERPROP + +#include "dlg/dlgProperty.h" + +class pgForeignDataWrapper; + +class dlgForeignDataWrapper : public dlgSecurityProperty +{ +public: + dlgForeignDataWrapper(pgaFactory *factory, frmMain *frame, pgForeignDataWrapper *db); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + pgForeignDataWrapper *fdw; + + void OnChange(wxCommandEvent &ev); +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnSelChangeOption(wxListEvent &ev); + void OnChangeOptionName(wxCommandEvent &ev); + void OnAddOption(wxCommandEvent &ev); + void OnChangeOption(wxCommandEvent &ev); + void OnRemoveOption(wxCommandEvent &ev); + + wxString GetOptionsSql(); + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgForeignKey.h b/include/dlg/dlgForeignKey.h new file mode 100644 index 0000000..ebac707 --- /dev/null +++ b/include/dlg/dlgForeignKey.h @@ -0,0 +1,61 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgForeignKey.h - ForeignKey property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_FOREIGNKEYPROP +#define __DLG_FOREIGNKEYPROP + +#include "dlg/dlgProperty.h" + + +class pgForeignKey; +class pgTable; + +class dlgForeignKey : public dlgCollistProperty +{ +public: + dlgForeignKey(pgaFactory *factory, frmMain *frame, pgForeignKey *node, pgTable *parentNode); + dlgForeignKey(pgaFactory *factory, frmMain *frame, ctlListView *colList); + + void CheckChange(); + wxString GetSql(); + wxString GetDefinition(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + wxString GetHelpPage() const + { + return wxT("pg/sql-altertable"); + } + + int Go(bool modal); + +private: + pgForeignKey *foreignKey; + wxString savedIndexName, savedFKName; + + wxString DefaultIndexName(const wxString &name); + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + void OnChangeValidate(wxCommandEvent &ev); + void OnSelChangeCol(wxListEvent &ev); + void OnSelChangeRef(wxCommandEvent &ev); + void OnSelChangeRefCol(wxCommandEvent &ev); + void OnAddRef(wxCommandEvent &ev); + void OnRemoveRef(wxCommandEvent &ev); + void OnOK(wxCommandEvent &ev); + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgForeignServer.h b/include/dlg/dlgForeignServer.h new file mode 100644 index 0000000..5a82e31 --- /dev/null +++ b/include/dlg/dlgForeignServer.h @@ -0,0 +1,53 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgForeignServer.h - Foreign Server property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_FOREIGNSERVERPROP +#define __DLG_FOREIGNSERVERPROP + +#include "dlg/dlgProperty.h" + +class pgForeignDataWrapper; +class pgForeignServer; + +class dlgForeignServer : public dlgSecurityProperty +{ +public: + dlgForeignServer(pgaFactory *factory, frmMain *frame, pgForeignServer *node, pgForeignDataWrapper *parent); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + pgForeignDataWrapper *foreigndatawrapper; + pgForeignServer *foreignserver; + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnSelChangeOption(wxListEvent &ev); + void OnChange(wxCommandEvent &ev); + void OnChangeOptionName(wxCommandEvent &ev); + void OnAddOption(wxCommandEvent &ev); + void OnChangeOption(wxCommandEvent &ev); + void OnRemoveOption(wxCommandEvent &ev); + + wxString GetOptionsSql(); + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgForeignTable.h b/include/dlg/dlgForeignTable.h new file mode 100644 index 0000000..75494b8 --- /dev/null +++ b/include/dlg/dlgForeignTable.h @@ -0,0 +1,71 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgForeignTable.h - Foreign Table property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_FOREIGNTABLEPROP +#define __DLG_FOREIGNTABLEPROP + +#include "dlg/dlgProperty.h" +#include "ctl/ctlSeclabelPanel.h" + +class pgForeignTable; + +class dlgForeignTable : public dlgTypeProperty +{ +public: + dlgForeignTable(pgaFactory *factory, frmMain *frame, pgForeignTable *node, pgSchema *schema); + + void CheckChange(); + wxString GetSql(); + wxString GetSqlForTypes(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + + bool WannaSplitQueries() + { + return queriesToBeSplitted; + } + + int Go(bool modal); + +private: + pgSchema *schema; + pgForeignTable *foreigntable; + ctlSeclabelPanel *seclabelPage; + + void OnMemberAdd(wxCommandEvent &ev); + void OnMemberChange(wxCommandEvent &ev); + void OnMemberRemove(wxCommandEvent &ev); + void OnMemberSelChange(wxListEvent &ev); + void OnSelChangeTyp(wxCommandEvent &ev); + void OnSelChangeTypOrLen(wxCommandEvent &ev); + void OnChangeMember(wxCommandEvent &ev); + + void OnChange(wxCommandEvent &event); + void OnSelChangeOption(wxListEvent &ev); + void OnChangeOptionName(wxCommandEvent &ev); + void OnAddOption(wxCommandEvent &ev); + void OnChangeOption(wxCommandEvent &ev); + void OnRemoveOption(wxCommandEvent &ev); + + wxString GetOptionsSql(); + + void showDefinition(int panel); + wxString GetFullTypeName(int type); + + wxArrayString memberTypes, memberLengths, memberPrecisions, memberNotNulls; + bool queriesToBeSplitted; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgFunction.h b/include/dlg/dlgFunction.h new file mode 100644 index 0000000..819c594 --- /dev/null +++ b/include/dlg/dlgFunction.h @@ -0,0 +1,105 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgFunction.h - Function property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_FUNCTIONPROP +#define __DLG_FUNCTIONPROP + +#include "dlg/dlgProperty.h" +#include "ctl/ctlSeclabelPanel.h" + +class pgSchema; +class pgFunction; + +class dlgFunction : public dlgSecurityProperty +{ +public: + dlgFunction(pgaFactory *factory, frmMain *frame, pgFunction *func, pgSchema *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + void SetObject(pgObject *obj) + { + function = (pgFunction *)obj; + } + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createfunction"); + } + +private: + pgSchema *schema; + pgFunction *function; + ctlSeclabelPanel *seclabelPage; + wxArrayString varInfo; + + void OnChange(wxCommandEvent &event); + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnChangeArgName(wxCommandEvent &ev); + void OnChangeReturn(wxCommandEvent &ev); + void OnChangeSetof(wxCommandEvent &ev); + void OnSelChangeLanguage(wxCommandEvent &ev); + void OnSelChangeArg(wxListEvent &ev); + void OnSelChangeType(wxCommandEvent &ev); + void OnAddArg(wxCommandEvent &ev); + void OnChangeArg(wxCommandEvent &ev); + void OnChangeArgMode(wxCommandEvent &ev); + void OnRemoveArg(wxCommandEvent &ev); + + void OnVarAdd(wxCommandEvent &ev); + void OnVarRemove(wxCommandEvent &ev); + void OnVarSelChange(wxListEvent &ev); + void OnVarnameSelChange(wxCommandEvent &ev); + void OnChangeWindow(wxCommandEvent &ev); + void SetupVarEditor(int var); + + wxString GetSelectedDirection(); + wxString GetArgs(const bool withNames = true, const bool inOnly = false); + void ReplaceSizer(wxWindow *w, bool isC, int border); + + virtual bool IsUpToDate(); + + wxArrayString typOids; + wxArrayString types; + wxArrayString argOids; + + int typeColNo; + +protected: + bool isProcedure; + bool isBackendMinVer84; + bool isEdbWrapped; + + DECLARE_EVENT_TABLE() +}; + + +class dlgProcedure : public dlgFunction +{ +public: + dlgProcedure(pgaFactory *factory, frmMain *frame, pgFunction *node, pgSchema *sch); + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createprocedure"); + } +}; + + +#endif diff --git a/include/dlg/dlgGroup.h b/include/dlg/dlgGroup.h new file mode 100644 index 0000000..b21bf28 --- /dev/null +++ b/include/dlg/dlgGroup.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgGroup.h - Group property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_GROUPPROP +#define __DLG_GROUPPROP + +#include "dlg/dlgProperty.h" + +class pgGroup; + +class dlgGroup : public dlgProperty +{ +public: + dlgGroup(pgaFactory *factory, frmMain *frame, pgGroup *node = 0); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + + void CheckChange(); + int Go(bool modal); + +private: + pgGroup *group; + + void OnUserAdd(wxCommandEvent &ev); + void OnUserRemove(wxCommandEvent &ev); + + wxArrayString usersIn; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgHbaConfig.h b/include/dlg/dlgHbaConfig.h new file mode 100644 index 0000000..165dda9 --- /dev/null +++ b/include/dlg/dlgHbaConfig.h @@ -0,0 +1,47 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgHbaConfig.h - Configure setting +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __DLGHBACONFIG_H +#define __DLGHBACONFIG_H + +#include "dlg/dlgClasses.h" +#include "utils/pgconfig.h" + +// Class declarations +class dlgHbaConfig : public DialogWithHelp +{ +public: + dlgHbaConfig(pgFrame *parent, pgHbaConfigLine *line, pgConn *_conn); + ~dlgHbaConfig(); + wxString GetHelpPage() const; + + int Go(); + +private: + pgHbaConfigLine *line; + + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnChange(wxCommandEvent &ev); + void OnAddDatabase(wxCommandEvent &ev); + void OnAddUser(wxCommandEvent &ev); + void OnAddValue(wxCommandEvent &ev); + + wxString database, user; + + bool databaseAdding, userAdding; + + pgConn *conn; + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgIndex.h b/include/dlg/dlgIndex.h new file mode 100644 index 0000000..66f4fa2 --- /dev/null +++ b/include/dlg/dlgIndex.h @@ -0,0 +1,73 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgIndex.h - Index property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_INDEXPROP +#define __DLG_INDEXPROP + +#include "dlg/dlgProperty.h" + + +class pgIndex; +class pgIndexBase; + +#define btnAddCol CTRL_BUTTON("btnAddCol") +#define btnRemoveCol CTRL_BUTTON("btnRemoveCol") + +class dlgIndexBase : public dlgCollistProperty +{ +public: + dlgIndexBase(pgaFactory *factory, frmMain *frame, const wxString &resName, pgIndexBase *index, pgTable *parentNode); + dlgIndexBase(pgaFactory *factory, frmMain *frame, const wxString &resName, ctlListView *colList); + + void OnSelectComboCol(wxCommandEvent &ev); + void OnSelectListCol(wxListEvent &ev); + void OnSelectCol(); + void CheckChange(); + pgObject *GetObject(); + int Go(bool modal); + +protected: + pgIndexBase *index; + +private: + DECLARE_EVENT_TABLE() +}; + + +class dlgIndex : public dlgIndexBase +{ +public: + dlgIndex(pgaFactory *factory, frmMain *frame, pgIndex *index, pgTable *parentNode); + + int Go(bool modal); + void CheckChange(); + wxString GetColumns(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + +private: +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnSelectType(wxCommandEvent &ev); + void OnDescChange(wxCommandEvent &ev); + void OnAddCol(wxCommandEvent &ev); + void OnRemoveCol(wxCommandEvent &ev); + + wxString m_previousType; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgIndexConstraint.h b/include/dlg/dlgIndexConstraint.h new file mode 100644 index 0000000..d69e382 --- /dev/null +++ b/include/dlg/dlgIndexConstraint.h @@ -0,0 +1,93 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgIndexConstraint.h - IndexConstraint property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_INDEXCONSTRAINTPROP +#define __DLG_INDEXCONSTRAINTPROP + + +#include "dlg/dlgIndex.h" + + +class pgTable; +class pgIndexBase; +class pgPrimaryKey; +class pgUnique; +class pgExclude; + +class dlgIndexConstraint : public dlgIndexBase +{ +protected: + dlgIndexConstraint(pgaFactory *factory, frmMain *frame, const wxString &resName, pgIndexBase *index, pgTable *parentNode); + dlgIndexConstraint(pgaFactory *factory, frmMain *frame, const wxString &resName, ctlListView *colList); + +public: + ctlListView *columns; + + + int Go(bool modal); + void CheckChange(); + wxString GetDefinition(); + wxString GetColumns(); + wxString GetSql(); + wxString GetHelpPage() const + { + return wxT("pg/sql-altertable"); + } + +private: +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnAddCol(wxCommandEvent &ev); + void OnRemoveCol(wxCommandEvent &ev); + void OnSelectType(wxCommandEvent &ev); + void OnSelectComboCol(wxCommandEvent &ev); + void OnChangeIndex(wxCommandEvent &ev); + + wxString m_previousType; + + DECLARE_EVENT_TABLE() +}; + + +class dlgPrimaryKey : public dlgIndexConstraint +{ +public: + dlgPrimaryKey(pgaFactory *factory, frmMain *frame, pgPrimaryKey *index, pgTable *parentNode); + dlgPrimaryKey(pgaFactory *factory, frmMain *frame, ctlListView *colList); + + pgObject *CreateObject(pgCollection *collection); +}; + + +class dlgUnique : public dlgIndexConstraint +{ +public: + dlgUnique(pgaFactory *factory, frmMain *frame, pgUnique *index, pgTable *parentNode); + dlgUnique(pgaFactory *factory, frmMain *frame, ctlListView *colList); + + pgObject *CreateObject(pgCollection *collection); +}; + + +class dlgExclude : public dlgIndexConstraint +{ +public: + dlgExclude(pgaFactory *factory, frmMain *frame, pgExclude *index, pgTable *parentNode); + dlgExclude(pgaFactory *factory, frmMain *frame, ctlListView *colList); + + pgObject *CreateObject(pgCollection *collection); +}; + + +#endif diff --git a/include/dlg/dlgLanguage.h b/include/dlg/dlgLanguage.h new file mode 100644 index 0000000..11b71a4 --- /dev/null +++ b/include/dlg/dlgLanguage.h @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgLanguage.h - Language properties dialog +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __DLG_LANGUAGEPROP +#define __DLG_LANGUAGEPROP + +#include "dlg/dlgProperty.h" +#include "ctl/ctlSeclabelPanel.h" + +class pgLanguage; + +class dlgLanguage : public dlgSecurityProperty +{ +public: + dlgLanguage(pgaFactory *factory, frmMain *frame, pgLanguage *node, pgObject *parent); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + pgLanguage *language; + ctlSeclabelPanel *seclabelPage; + + void OnChange(wxCommandEvent &event); + void OnChangeName(wxCommandEvent &ev); +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgMainConfig.h b/include/dlg/dlgMainConfig.h new file mode 100644 index 0000000..565f76d --- /dev/null +++ b/include/dlg/dlgMainConfig.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgMainConfig.h - Configure setting +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __DLGMAINCONFIG_H +#define __DLGMAINCONFIG_H + +#include "dlg/dlgClasses.h" +#include "utils/pgconfig.h" + +// Class declarations +class dlgMainConfig : public DialogWithHelp +{ +public: + dlgMainConfig(pgFrame *parent, pgSettingItem *item); + ~dlgMainConfig(); + wxString GetHelpPage() const; + + int Go(); + +private: + pgSettingItem *item; + wxString GetValue(); + + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnChange(wxCommandEvent &ev); + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgManageFavourites.h b/include/dlg/dlgManageFavourites.h new file mode 100644 index 0000000..3c11a6d --- /dev/null +++ b/include/dlg/dlgManageFavourites.h @@ -0,0 +1,40 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgManageFavourites.h - Manage favourites +// +////////////////////////////////////////////////////////////////////////// + +#ifndef dlgManageFavourites_H +#define dlgManageFavourites_H + +#include "dlg/dlgClasses.h" +#include "utils/favourites.h" + +// Class declarations +class dlgManageFavourites : public pgDialog +{ +public: + dlgManageFavourites(wxWindow *parent, queryFavouriteFolder *favourites); + ~dlgManageFavourites(); + int ManageFavourites(); // returns: 0=no changes, 1=changes to save, -1=changes to rollback + +private: + queryFavouriteFolder *favourites; + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnTreeChange(wxTreeEvent &ev); + void OnRename(wxCommandEvent &ev); + void OnDelete(wxCommandEvent &ev); + void OnNewFolder(wxCommandEvent &ev); + + bool anythingChanged; + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgManageMacros.h b/include/dlg/dlgManageMacros.h new file mode 100644 index 0000000..98a4dd9 --- /dev/null +++ b/include/dlg/dlgManageMacros.h @@ -0,0 +1,49 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgManageMacros.h - Manage macros +// +////////////////////////////////////////////////////////////////////////// + +#ifndef dlgManageMacros_H +#define dlgManageMacros_H + +#include "dlg/dlgClasses.h" +#include "utils/macros.h" + +class dlgManageMacros : public DialogWithHelp +{ +public: + dlgManageMacros(wxWindow *parent, frmMain *form, queryMacroList *macros); + ~dlgManageMacros(); + int ManageMacros(); // returns: 0=no changes, 1=changes to save, -1=changes to rollback + + +private: + queryMacroList *macros; + wxString GetHelpPage() const; + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnClear(wxCommandEvent &ev); + void OnSave (wxCommandEvent &ev); + void OnKeySelect(wxListEvent &ev); + void OnNameChange(wxCommandEvent &ev); + void OnQueryChange(wxStyledTextEvent &ev); + + // Helper methods + void AddKeyToList(int position, const wxString &key); + void DeleteMacro(int listItem); + void SetMacro(bool silent); + + bool anythingChanged; + bool thisMacroChanged; + + DECLARE_EVENT_TABLE() +}; + +#endif /*dlgManageMacros_H*/ + diff --git a/include/dlg/dlgMoveTablespace.h b/include/dlg/dlgMoveTablespace.h new file mode 100644 index 0000000..5354af6 --- /dev/null +++ b/include/dlg/dlgMoveTablespace.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgMoveTablespace.h - Reassign or drop owned objects +// +////////////////////////////////////////////////////////////////////////// + +#ifndef dlgMoveTablespace_H +#define dlgMoveTablespace_H + +// wxWindows headers +#include +#include + + +#include "dlg/dlgClasses.h" +class pgConn; +class pgTablespace; + +// Class declarations +class dlgMoveTablespace : public pgDialog +{ +public: + dlgMoveTablespace(frmMain *win, pgConn *conn, pgTablespace *tblspc); + ~dlgMoveTablespace(); + wxString GetTablespace(); + wxArrayString GetKind(); + wxString GetOwner(); +private: + pgConn *connection; + frmMain *parent; + + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnChange(wxCommandEvent &ev); + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgOperator.h b/include/dlg/dlgOperator.h new file mode 100644 index 0000000..edf86c5 --- /dev/null +++ b/include/dlg/dlgOperator.h @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgOperator.h - Operator property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_OPERATORPROP +#define __DLG_OPERATORPROP + +#include "dlg/dlgProperty.h" + +class pgSchema; +class pgOperator; + +class dlgOperator : public dlgTypeProperty +{ +public: + dlgOperator(pgaFactory *factory, frmMain *frame, pgOperator *op, pgSchema *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + void CheckChangeType(); + void OnChangeTypeLeft(wxCommandEvent &ev); + void OnChangeTypeRight(wxCommandEvent &ev); + void OnChangeJoin(wxCommandEvent &ev); + + void AppendFilledOperator(wxString &sql, const wxChar *txt, ctlComboBoxFix *cb); + + pgSchema *schema; + pgOperator *oper; + wxArrayString procedures; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgPackage.h b/include/dlg/dlgPackage.h new file mode 100644 index 0000000..a0fea18 --- /dev/null +++ b/include/dlg/dlgPackage.h @@ -0,0 +1,53 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgPackage.h - EnterpriseDB Package property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_PACKAGEPROP +#define __DLG_PACKAGEPROP + +#include "dlg/dlgProperty.h" + +class edbPackage; + +class dlgPackage : public dlgSecurityProperty +{ +public: + dlgPackage(pgaFactory *f, frmMain *frame, edbPackage *node, pgSchema *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + void SetObject(pgObject *obj) + { + package = (edbPackage *)obj; + } + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/packages-create"); + } + +private: + edbPackage *package; + pgSchema *schema; + + virtual bool IsUpToDate(); +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgPgpassConfig.h b/include/dlg/dlgPgpassConfig.h new file mode 100644 index 0000000..112de95 --- /dev/null +++ b/include/dlg/dlgPgpassConfig.h @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgPgpassConfig.h - Configure setting +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __DLGPGPASSCONFIG_H +#define __DLGPGPASSCONFIG_H + +#include "dlg/dlgClasses.h" +#include "utils/pgconfig.h" + +// Class declarations +class dlgPgpassConfig : public DialogWithHelp +{ +public: + dlgPgpassConfig(pgFrame *parent, pgPassConfigLine *line); + ~dlgPgpassConfig(); + wxString GetHelpPage() const; + + int Go(); + +private: + pgPassConfigLine *line; + + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnChange(wxCommandEvent &ev); + + wxString database, user; + + bool databaseAdding, userAdding; + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgProperty.h b/include/dlg/dlgProperty.h new file mode 100644 index 0000000..12504c4 --- /dev/null +++ b/include/dlg/dlgProperty.h @@ -0,0 +1,383 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgProperty.h - common property dialog class +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_PROP +#define __DLG_PROP + + +#include +#include +#include "schema/pgObject.h" +#include "db/pgConn.h" +#include "ctl/ctlSecurityPanel.h" + +class pgSchema; +class pgTable; +class frmMain; +class pgaFactory; + +#define stComment CTRL_STATIC("stComment") +#define lstColumns CTRL_LISTVIEW("lstColumns") +#define cbColumns CTRL_COMBOBOX("cbColumns") + +class dataType +{ +public: + void SetTypename(wxString name); + wxString GetTypename(); + + void SetOid(OID id); + OID GetOid(); + +private: + wxString typeName; + OID oid; + +}; + + +/* + * We need the definition of replClientData in dlgDatabase too, to hack + * the execution of default privileges statements (sqls) before getting + * disconnected. + */ +class replClientData : public wxClientData +{ +public: + replClientData(const wxString &c, long s, long ma, long mi) + { + cluster = c; + setId = s; + majorVer = ma; + minorVer = mi; + } + wxString cluster; + long setId; + long majorVer; + long minorVer; +}; + + +WX_DEFINE_ARRAY(dataType *, dataTypeCache); + +class dlgProperty : public DialogWithHelp +{ +public: + static bool CreateObjectDialog(frmMain *frame, pgObject *node, pgaFactory *factory = 0); + static bool EditObjectDialog(frmMain *frame, ctlSQLBox *sqlbox, pgObject *node); + void InitDialog(frmMain *frame, pgObject *node); + + wxString GetName(); + virtual wxString GetDisplayName() + { + return GetName(); + }; + + virtual wxString GetSql() = 0; + virtual wxString GetSql2() + { + return wxEmptyString; + }; + virtual bool GetDisconnectFirst() + { + return false; + }; + virtual pgObject *CreateObject(pgCollection *collection) = 0; + virtual pgObject *GetObject() = 0; + virtual void SetObject(pgObject *obj) {} // only necessary if apply is implemented + + virtual void CreateAdditionalPages(); + virtual wxString GetHelpPage() const; + virtual wxString GetHelpPage(bool forCreate) const + { + return wxEmptyString; + } + virtual void SetConnection(pgConn *conn) + { + connection = conn; + } + void SetDatabase(pgDatabase *db); + void SetDatatypeCache(dataTypeCache cache); + virtual int Go(bool modal = false); + virtual void CheckChange() = 0; + + virtual bool WannaSplitQueries() + { + return false; + } + +protected: + dlgProperty(pgaFactory *factory, frmMain *frame, const wxString &resName); + ~dlgProperty(); + + void EnableOK(bool enable); + void SetSqlReadOnly(bool readonly); + virtual bool IsUpToDate() + { + return true; + }; + void ShowObject(); + + void FillSQLTextfield(); + + void CheckValid(bool &enable, const bool condition, const wxString &msg); + static dlgProperty *CreateDlg(frmMain *frame, pgObject *node, bool asNew, pgaFactory *factory = 0); + void AppendNameChange(wxString &sql, const wxString &objname = wxEmptyString); + void AppendOwnerChange(wxString &sql, const wxString &objName = wxEmptyString); + void AppendOwnerNew(wxString &sql, const wxString &objname); + void AppendSchemaChange(wxString &sql, const wxString &objname = wxEmptyString); + void AppendComment(wxString &sql, const wxString &objType, pgSchema *schema, pgObject *obj); + void AppendComment(wxString &sql, const wxString &objName, pgObject *obj); + void AppendQuoted(wxString &sql, const wxString &name); + void AppendQuotedType(wxString &sql, const wxString &name); + wxString qtDbString(const wxString &str); + +#if __GNUC__ >= 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) + // ANSI spec 11.5 is quite brain dead about pointers of protected members: In order to access + // them using the base class name, they can't be protected. + // apparently, only gcc 3.4 knows that; other compilers take protected as protected. +public: + +#endif + + void OnPageSelect(wxNotebookEvent &event); + void OnOK(wxCommandEvent &ev); + void OnChange(wxCommandEvent &ev); + void OnChangeOwner(wxCommandEvent &ev); + void OnChangeStc(wxStyledTextEvent &event); + void OnChangeReadOnly(wxCommandEvent &event); + +protected: + void AddDatabases(ctlComboBoxFix *cb = 0); + void AddGroups(ctlComboBoxFix *comboBox = 0); + void AddUsers(ctlComboBoxFix *cb1, ctlComboBoxFix *cb2 = 0); + void AddSchemas(ctlComboBoxFix *comboBox = 0); + void FillCombobox(const wxString &query, ctlComboBoxFix *cb1, ctlComboBoxFix *cb2 = 0); + void PrepareTablespace(ctlComboBoxFix *cb, const OID current = 0); + void OnHelp(wxCommandEvent &ev); + + pgConn *connection; + pgDatabase *database; + pgObject *obj; + + frmMain *mainForm; + wxPanel *sqlPane; + + wxTextValidator numericValidator; + + wxNotebook *nbNotebook; + wxTextCtrl *txtName, *txtOid, *txtComment; + ctlComboBox *cbOwner; + ctlComboBox *cbSchema; + wxComboBox *cbClusterSet; + wxCheckBox *chkReadOnly; + ctlSQLBox *sqlTextField1; + ctlSQLBox *sqlTextField2; + bool enableSQL2; + + int width, height; + wxTreeItemId item, owneritem; + bool readOnly; + bool processing; + pgaFactory *factory; + dataTypeCache dtCache; + +private: + bool tryUpdate(wxTreeItemId collectionItem); + bool apply(const wxString &sql, const wxString &sql2); + wxString BuildSql(const wxString &sql); + wxArrayString SplitQueries(const wxString &sql); + + DECLARE_EVENT_TABLE() +}; + + +#define cbDatatype CTRL_COMBOBOX2("cbDatatype") + + +class dlgTypeProperty : public dlgProperty +{ +public: + wxString GetQuotedTypename(int sel); + wxString GetTypeOid(int sel); + wxString GetTypeInfo(int sel); + void AddType(const wxString &typ, const OID oid, const wxString quotedName = wxEmptyString); + + + int Go(bool modal); + +protected: + dlgTypeProperty(pgaFactory *factory, frmMain *frame, const wxString &resName); + void CheckLenEnable(); + void FillDatatype(ctlComboBox *cb, bool withDomains = true, bool addSerials = false); + void FillDatatype(ctlComboBox *cb, ctlComboBox *cb2, bool withDomains = true, bool addSerials = false); + + bool isVarLen, isVarPrec; + long minVarLen, maxVarLen; + wxTextCtrl *txtLength, *txtPrecision; + +private: + wxArrayString types; +}; + + +class dlgCollistProperty : public dlgProperty +{ +public: + int Go(bool modal); + +protected: + dlgCollistProperty(pgaFactory *factory, frmMain *frame, const wxString &resName, pgTable *table); + dlgCollistProperty(pgaFactory *factory, frmMain *frame, const wxString &resName, ctlListView *colList); + + ctlListView *columns; + pgTable *table; +}; + + +class dlgSecurityProperty : public dlgProperty +{ +protected: + dlgSecurityProperty(pgaFactory *factory, frmMain *frame, pgObject *obj, const wxString &resName, const wxString &privilegeList, const char *privilegeChar); + ~dlgSecurityProperty(); + void AddGroups(ctlComboBox *comboBox = 0); + void AddUsers(ctlComboBox *comboBox = 0); + + wxString GetGrant(const wxString &allPattern, const wxString &grantObject); + void EnableOK(bool enable, bool ignoreSql = false); + virtual wxString GetHelpPage() const; + virtual int Go(bool modal = false); + bool DisablePrivilege(const wxString &priv); + void SetPrivilegesLayout(); + void AppendCurrentAcl(const wxString &name, const wxString &value); + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + ctlSecurityPanel *securityPage; + +private: + + void OnAddPriv(wxCommandEvent &ev); + void OnDelPriv(wxCommandEvent &ev); + bool securityChanged; + + wxArrayString currentAcl; + + DECLARE_EVENT_TABLE() +}; + +class ctlDefaultSecurityPanel; + +class dlgDefaultSecurityProperty : public dlgSecurityProperty +{ + +protected: + dlgDefaultSecurityProperty(pgaFactory *factory, frmMain *frame, pgObject *obj, const wxString &resName, + const wxString &privilegeList, const char *privilegeChar, bool createDefPrivPanel = true); + + virtual int Go(bool modal = false, bool createDefPrivs = false, + const wxString &defPrivsOnTables = wxT(""), + const wxString &defPrivsOnSeqs = wxT(""), + const wxString &defPrivsOnFuncs = wxT(""), + const wxString &defPrivsOnTypes = wxT("")); + + virtual wxString GetHelpPage() const; + + void EnableOK(bool enable, bool ignoreSql = false); + wxString GetDefaultPrivileges(const wxString &schemaName = wxT("")); + void AddGroups(ctlComboBox *comboBox = 0); + void AddUsers(ctlComboBox *comboBox = 0); +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + bool defaultSecurityChanged; + +private: + void OnAddPriv(wxCommandEvent &ev); + void OnDelPriv(wxCommandEvent &ev); + + ctlDefaultSecurityPanel *defaultSecurityPage; + + DECLARE_EVENT_TABLE() +}; + + + +class dlgAgentProperty : public dlgProperty +{ +public: + +protected: + dlgAgentProperty(pgaFactory *factory, frmMain *frame, const wxString &resName); + void OnOK(wxCommandEvent &ev); + bool executeSql(); + virtual wxString GetInsertSql() = 0; + virtual wxString GetUpdateSql() = 0; + wxString GetSql(); + long GetRecId() + { + return recId; + } + + DECLARE_EVENT_TABLE() + + long recId; +}; + + +class propertyFactory : public contextActionFactory +{ +public: + propertyFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +class createFactory : public actionFactory +{ +public: + createFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class dropFactory : public contextActionFactory +{ +public: + dropFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +class dropCascadedFactory : public contextActionFactory +{ +public: + dropCascadedFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class refreshFactory : public contextActionFactory +{ +public: + refreshFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +#endif diff --git a/include/dlg/dlgReassignDropOwned.h b/include/dlg/dlgReassignDropOwned.h new file mode 100644 index 0000000..ed5eb11 --- /dev/null +++ b/include/dlg/dlgReassignDropOwned.h @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgReassignDropOwned.h - Reassign or drop owned objects +// +////////////////////////////////////////////////////////////////////////// + +#ifndef dlgReassignDropOwned_H +#define dlgReassignDropOwned_H + +// wxWindows headers +#include +#include + + +#include "dlg/dlgClasses.h" +class pgConn; +class pgRole; + +// Class declarations +class dlgReassignDropOwned : public pgDialog +{ +public: + dlgReassignDropOwned(frmMain *win, pgConn *conn, pgRole *role, wxString dbrestriction); + ~dlgReassignDropOwned(); + wxString GetDatabase(); + wxString GetRole(); + bool IsReassign(); + +private: + pgConn *connection; + frmMain *parent; + + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnChange(wxCommandEvent &ev); + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgResourceGroup.h b/include/dlg/dlgResourceGroup.h new file mode 100644 index 0000000..6608c44 --- /dev/null +++ b/include/dlg/dlgResourceGroup.h @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgResourceGroup.h - Resource Group property +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __DLG_RESOURCEGROUPPROP +#define __DLG_RESOURCEGROUPPROP + +#include "dlg/dlgProperty.h" + +class edbResourceGroup; + +class dlgResourceGroup : public dlgProperty +{ +public: + dlgResourceGroup(pgaFactory *factory, frmMain *frame, edbResourceGroup *node = 0); + wxString GetSql(); + wxString GetSql2(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + + void CheckChange(); + int Go(bool modal); + +private: + void OnChange(wxCommandEvent &event); + void OnOK(wxCommandEvent &ev); + +private: + edbResourceGroup *resourceGroup; + wxString m_cpuRate; + wxString m_dirtyRate; + bool m_isNameChange; + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgRole.h b/include/dlg/dlgRole.h new file mode 100644 index 0000000..a6a65e9 --- /dev/null +++ b/include/dlg/dlgRole.h @@ -0,0 +1,70 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRole.h - Role property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_ROLEPROP +#define __DLG_ROLEPROP + +#include "dlg/dlgProperty.h" +#include "ctl/calbox.h" +#include "ctl/timespin.h" +#include "ctl/ctlSeclabelPanel.h" + +class pgRole; + +class dlgRole : public dlgProperty +{ +public: + dlgRole(pgaFactory *factory, frmMain *frame, pgRole *node = 0, bool chkLogin = false); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + wxString GetHelpPage() const; + + int Go(bool modal); + +private: + pgRole *role; + wxArrayString varInfo; + ctlSeclabelPanel *seclabelPage; + + void OnChange(wxCommandEvent &event); + + void OnOK(wxCommandEvent &ev); + void OnChangeSuperuser(wxCommandEvent &ev); + void OnChangeSpin(wxSpinEvent &ev); + void OnChangeCal(wxCalendarEvent &ev); + void OnChangeDate(wxDateEvent &ev); + void OnRoleAdd(wxCommandEvent &ev); + void OnRoleRemove(wxCommandEvent &ev); + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnVarAdd(wxCommandEvent &ev); + void OnVarRemove(wxCommandEvent &ev); + void OnVarSelChange(wxListEvent &ev); + + void OnVarnameSelChange(wxCommandEvent &ev); + void OnChangePasswd(wxCommandEvent &ev); + + void SetupVarEditor(int var); + + wxArrayString groupsIn; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgRule.h b/include/dlg/dlgRule.h new file mode 100644 index 0000000..8d42e3e --- /dev/null +++ b/include/dlg/dlgRule.h @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRule.h - Rule property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_RULEPROP +#define __DLG_RULEPROP + +#include "dlg/dlgProperty.h" + +class pgTable; +class pgRule; +class ctlSQLBox; + +class dlgRule : public dlgProperty +{ +public: + dlgRule(pgaFactory *factory, frmMain *frame, pgRule *r, pgTable *tab); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + pgTable *table; + pgRule *rule; + wxString oldDefinition; + + bool didChange(); + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgSchema.h b/include/dlg/dlgSchema.h new file mode 100644 index 0000000..a0c10fc --- /dev/null +++ b/include/dlg/dlgSchema.h @@ -0,0 +1,45 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgSchema.h - Schemaproperty +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_SCHEMAPROP +#define __DLG_SCHEMAPROP + +#include "dlg/dlgProperty.h" +#include "ctl/ctlSeclabelPanel.h" + +class pgSchema; + +class dlgSchema : public dlgDefaultSecurityProperty +{ +public: + dlgSchema(pgaFactory *factory, frmMain *frame, pgSchema *node, pgObject *parent); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + pgSchema *schema; + ctlSeclabelPanel *seclabelPage; + + void OnChange(wxCommandEvent &event); +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgSearchObject.h b/include/dlg/dlgSearchObject.h new file mode 100644 index 0000000..5aea40a --- /dev/null +++ b/include/dlg/dlgSearchObject.h @@ -0,0 +1,82 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgSearchObject.h - Search dialogue +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DLGSEARCHOBJECT_H +#define DLGSEARCHOBJECT_H + +#include "dlg/dlgClasses.h" +#include "ctl/ctlListView.h" +#include "schema/pgDatabase.h" +#include "utils/sysSettings.h" +#include "schema/pgSchema.h" + +// Class declarations +class dlgSearchObject : public pgDialog +{ +public: + dlgSearchObject(frmMain *p, pgDatabase *db, pgObject *obj); + ~dlgSearchObject(); + +private: + void OnHelp(wxCommandEvent &ev); + void OnSearch(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnChange(wxCommandEvent &ev); + void OnSelSearchResult(wxListEvent &ev); + void SaveSettings(); + void RestoreSettings(); + wxString TranslatePath(wxString &path); + wxString getMapKeyByValue(wxString); + void ToggleBtnSearch(bool enable); + WX_DECLARE_STRING_HASH_MAP(wxString, LngMapping); + LngMapping aMap; + + pgDatabase *currentdb; + frmMain *parent; + wxString header; + wxArrayString sectionName, sectionData, sectionTableHeader, sectionTableRows, sectionTableInfo, sectionSql; + wxString currentSchema; + int cbSchemaIdxCurrent; + + DECLARE_EVENT_TABLE() +}; + +/////////////////////////////////////////////////////// +// Search Object Factory base class +/////////////////////////////////////////////////////// +class searchObjectBaseFactory : public actionFactory +{ +private: + searchObjectBaseFactory(menuFactoryList *list) : actionFactory(list) {} + frmMain *GetFrmMain() + { + return parent; + }; + + frmMain *parent; +public: + bool CheckEnable(pgObject *obj) + { + return false; + }; +}; + + +class searchObjectFactory : public contextActionFactory +{ +public: + searchObjectFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); + +}; + +#endif diff --git a/include/dlg/dlgSelectConnection.h b/include/dlg/dlgSelectConnection.h new file mode 100644 index 0000000..3077ade --- /dev/null +++ b/include/dlg/dlgSelectConnection.h @@ -0,0 +1,52 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgSelectConnection.h - Connect to a database +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DLGSELECTCONNECTION_H +#define DLGSELECTCONNECTION_H + +#include +#include "dlg/dlgClasses.h" + +class pgServer; +// Class declarations +class dlgSelectConnection : public DialogWithHelp +{ +public: + dlgSelectConnection(wxWindow *parent, frmMain *form); + ~dlgSelectConnection(); + wxString GetHelpPage() const; + pgServer *GetServer() + { + return remoteServer; + } + pgConn *CreateConn(wxString &applicationame, bool &createdNew); + pgConn *CreateConn(wxString &server, wxString &dbname, wxString &username, int port, wxString &rolename, int sslmode, wxString &applicationame, bool writeMRU = false); + wxString GetServerName(); + wxString GetDatabase(); + + int Go(pgConn *conn, wxBitmapComboBox *cb); + +private: + void OnChangeServer(wxCommandEvent &ev); + void OnChangeDatabase(wxCommandEvent &ev); + void OnTextChange(wxCommandEvent &ev); + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + + pgServer *remoteServer; + wxBitmapComboBox *cbConnection; + ctlComboBoxFix *cbServer; + wxComboBox *cbDatabase, *cbUsername, *cbRolename; + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgSelectDatabase.h b/include/dlg/dlgSelectDatabase.h new file mode 100644 index 0000000..a5dddca --- /dev/null +++ b/include/dlg/dlgSelectDatabase.h @@ -0,0 +1,66 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgSelectDatabase.h - Connect to a database +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DLGSELECTDATABASE_H +#define DLGSELECTDATABASE_H + +#include +#include +#include + + +class pgServer; + + +class dlgSelDBNode : public wxTreeItemData +{ + +public: + dlgSelDBNode(pgServer *server, const wxString &dbname = wxEmptyString); + dlgSelDBNode *createChild(const wxString &dbName); + + wxString getDatabase() + { + return dbname; + } + wxString getConnectionString(); + +private: + pgServer *server; // Do not remove it, not owned by this + wxString dbname; + + friend class dlgSelectDatabase; + +}; + + +class dlgSelectDatabase: public wxDialog +{ + +public: + dlgSelectDatabase(wxWindow *parent, int id, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = wxCLOSE_BOX); + + wxString getConnInfo(); + static bool getValidConnectionString(wxString connStr, wxString &resultStr); + +protected: + void Initialize(); + void OnSelect(wxTreeEvent &ev); + void OnSelActivate(wxTreeEvent &ev); + + wxTreeCtrl *tcServers; + dlgSelDBNode *selectedConn; + + DECLARE_EVENT_TABLE() +}; + +#endif + diff --git a/include/dlg/dlgSequence.h b/include/dlg/dlgSequence.h new file mode 100644 index 0000000..1d58e4f --- /dev/null +++ b/include/dlg/dlgSequence.h @@ -0,0 +1,50 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgSequence.h - Sequence property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_SEQUENCEPROP +#define __DLG_SEQUENCEPROP + +#include "dlg/dlgProperty.h" +#include "ctl/ctlSeclabelPanel.h" + +class pgSchema; +class pgSequence; + +class dlgSequence : public dlgSecurityProperty +{ +public: + dlgSequence(pgaFactory *factory, frmMain *frame, pgSequence *seq, pgSchema *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + bool doesOverflowBigInt(const wxString &str, bool emptyAllowed); + + pgSchema *schema; + pgSequence *sequence; + ctlSeclabelPanel *seclabelPage; + + void OnChange(wxCommandEvent &event); + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgServer.h b/include/dlg/dlgServer.h new file mode 100644 index 0000000..49acaf7 --- /dev/null +++ b/include/dlg/dlgServer.h @@ -0,0 +1,59 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgServer.h - Server property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_SERVERPROP +#define __DLG_SERVERPROP + +#include "dlg/dlgProperty.h" +#include +#include + +class pgServer; + +class dlgServer : public dlgProperty +{ +public: + dlgServer(pgaFactory *factory, frmMain *frame, pgServer *s); + ~dlgServer(); + int Go(bool modal); + int GoNew(); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + wxString GetHelpPage() const; + + wxString GetPassword(); + bool GetTryConnect(); + +private: + pgServer *server; + bool dbRestrictionOk; + + void OnOK(wxCommandEvent &ev); + void OnChangeRestr(wxCommandEvent &ev); + void OnChangeTryConnect(wxCommandEvent &ev); + void OnPageSelect(wxNotebookEvent &event); + void OnChangeColour(wxColourPickerEvent &ev); + void OnChangeFile(wxFileDirPickerEvent &ev); + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + void OnCheckSSHTunnel(wxCommandEvent &ev); + void OnChangeAuthOption(wxCommandEvent &ev); + void EnableSSHTunnelControls(const bool &bEnable); + void EnableAuthenticationOptions(); +#endif + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgSynonym.h b/include/dlg/dlgSynonym.h new file mode 100644 index 0000000..6bc2d1c --- /dev/null +++ b/include/dlg/dlgSynonym.h @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgSynonym.h - EnterpriseDB Synonym property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_SYNONYMPROP +#define __DLG_SYNONYMPROP + +#include "dlg/dlgProperty.h" + +class edbSynonym; +class edbPrivateSynonymFactory; +class edbPrivateSynonym; +class pgSchema; + +class dlgSynonym : public dlgProperty +{ +public: + dlgSynonym(pgaFactory *factory, frmMain *frame, edbSynonym *sy); + dlgSynonym(edbPrivateSynonymFactory *factory, frmMain *frame, edbPrivateSynonym *syn, pgSchema *schema); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createpubsynonym"); + } + +private: + void OnChangeTargetType(wxCommandEvent &ev) + { + ProcessTypeChange(); + }; + void OnChangeTargetSchema(wxCommandEvent &ev) + { + ProcessSchemaChange(); + }; + void ProcessTypeChange(); + void ProcessSchemaChange(); + + edbSynonym *synonym; + edbPrivateSynonym *privSynonym; + pgSchema *synonymSchema; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgTable.h b/include/dlg/dlgTable.h new file mode 100644 index 0000000..1b82fe0 --- /dev/null +++ b/include/dlg/dlgTable.h @@ -0,0 +1,131 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgTable.h - Table property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_TABLEPROP +#define __DLG_TABLEPROP + +#include "dlg/dlgProperty.h" +#include "ctl/ctlSeclabelPanel.h" + +enum +{ + COL_NAME = 0, + COL_DEFINITION, + COL_INHERIT, + COL_SQLCHANGE, + COL_COMMENTS, + COL_STATISTICS, + COL_PGCOLUMN, + COL_TYPEOID, + COL_CHANGEDCOL, + COL_VARIABLE_LIST, + COL_SECLABEL_LIST +}; + +enum +{ + TAB_PROPERTIES = 0, + TAB_DEFINITION, + TAB_INHERITS, + TAB_LIKE, + TAB_COLUMNS, + TAB_CONSTRAINTS, + TAB_AUTOVACUUM, + TAB_PRIVILEGES, + TAB_SECLABEL, + TAB_SQL +}; + +class pgSchema; +class pgTable; +class pgColumn; + +class dlgTable : public dlgSecurityProperty +{ +public: + dlgTable(pgaFactory *factory, frmMain *frame, pgTable *db, pgSchema *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + bool Destroy(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + ~dlgTable(); + +private: + pgSchema *schema; + pgTable *table; + ctlSeclabelPanel *seclabelPage; + dataTypeCache dtCache; + + void OnChange(wxCommandEvent &event); + + void OnOK(wxCommandEvent &ev); + void OnChangeTable(wxCommandEvent &ev); +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnChangeOfType(wxCommandEvent &ev); + + void OnAddTable(wxCommandEvent &ev); + void OnRemoveTable(wxCommandEvent &ev); + void OnSelChangeTable(wxCommandEvent &ev); + + void OnAddCol(wxCommandEvent &ev); + void OnChangeCol(wxCommandEvent &ev); + void OnRemoveCol(wxCommandEvent &ev); + void OnSelChangeCol(wxListEvent &ev); + + void OnAddConstr(wxCommandEvent &ev); + void OnRemoveConstr(wxCommandEvent &ev); + void OnSelChangeConstr(wxListEvent &ev); + + void OnChangeVacuum(wxCommandEvent &ev); + + void FillConstraint(); + void FillAutoVacuumParameters(wxString &setString, wxString &resetStr, + const wxString ¶meter, const wxString &val); + void PopulateDatatypeCache(); + wxString GetItemConstraintType(ctlListView *list, long pos); + bool hasPK; + + wxArrayString previousColumns, previousConstraints, previousTables, constraintsDefinition; + wxArrayString tableOids, inheritedTableOids; + wxTreeItemId columnsItem, constraintsItem; + + wxString GetNumString(wxTextCtrl *ctl, bool enabled, const wxString &val); + wxString AppendNum(bool &changed, wxTextCtrl *ctl, wxString val); + + bool tableVacEnabled, hasVacuum, settingAutoVacuum; + wxString settingVacBaseThr, settingAnlBaseThr, settingCostDelay, + settingCostLimit, settingFreezeMinAge, settingFreezeMaxAge, + settingFreezeTableAge; + wxString tableVacBaseThr, tableAnlBaseThr, tableCostDelay, + tableCostLimit, tableFreezeMinAge, tableFreezeMaxAge, + tableFreezeTableAge; + wxString settingVacFactor, settingAnlFactor; + wxString tableVacFactor, tableAnlFactor; + + /* Toast Table */ + bool toastTableVacEnabled, toastTableHasVacuum; + wxString toastTableVacBaseThr, + toastTableCostDelay, toastTableCostLimit, + toastTableFreezeMinAge, toastTableFreezeMaxAge, + toastTableFreezeTableAge; + wxString toastTableVacFactor; + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgTablespace.h b/include/dlg/dlgTablespace.h new file mode 100644 index 0000000..83b7dad --- /dev/null +++ b/include/dlg/dlgTablespace.h @@ -0,0 +1,57 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgTablespace.h - Tablespace property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_TABLESPACEPROP +#define __DLG_TABLESPACEPROP + +#include "dlg/dlgProperty.h" +#include "ctl/ctlSeclabelPanel.h" + +class pgTablespace; + +class dlgTablespace : public dlgSecurityProperty +{ +public: + dlgTablespace(pgaFactory *factory, frmMain *frame, pgTablespace *node = 0); + + void CheckChange(); + wxString GetSql(); + wxString GetSql2(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + wxString GetHelpPage() const; + + int Go(bool modal); + +private: + pgTablespace *tablespace; + wxArrayString varInfo; + bool dirtyVars; + ctlSeclabelPanel *seclabelPage; + + void OnChange(wxCommandEvent &event); + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnVarAdd(wxCommandEvent &ev); + void OnVarRemove(wxCommandEvent &ev); + void OnVarSelChange(wxListEvent &ev); + void OnVarnameSelChange(wxCommandEvent &ev); + void SetupVarEditor(int var); + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgTextSearchConfiguration.h b/include/dlg/dlgTextSearchConfiguration.h new file mode 100644 index 0000000..e8ea8c6 --- /dev/null +++ b/include/dlg/dlgTextSearchConfiguration.h @@ -0,0 +1,59 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgTextSearchConfiguration.h - Text Search Configuration property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_TSCONFIGURATIONPROP +#define __DLG_TSCONFIGURATIONPROP + +#include "dlg/dlgProperty.h" + +class pgSchema; +class pgTextSearchConfiguration; + +class dlgTextSearchConfiguration : public dlgTypeProperty +{ +public: + dlgTextSearchConfiguration(pgaFactory *factory, frmMain *frame, pgTextSearchConfiguration *cfg, pgSchema *sch); + int Go(bool modal); + + virtual wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createtsconfig"); + } + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + void OnChange(wxCommandEvent &ev); + + pgSchema *schema; + pgTextSearchConfiguration *config; + bool dirtyTokens; + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnSelChangeToken(wxListEvent &ev); + void OnChangeCbToken(wxCommandEvent &ev); + void OnChangeTxtDictionary(wxCommandEvent &ev); + void OnChangeCbDictionary(wxCommandEvent &ev); + void OnAddToken(wxCommandEvent &ev); + void OnChangeToken(wxCommandEvent &ev); + void OnRemoveToken(wxCommandEvent &ev); + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgTextSearchDictionary.h b/include/dlg/dlgTextSearchDictionary.h new file mode 100644 index 0000000..69fd77b --- /dev/null +++ b/include/dlg/dlgTextSearchDictionary.h @@ -0,0 +1,58 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgTextSearchDictionary.h - Text Search Dictionary property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_TSDICTIONARYPROP +#define __DLG_TSDICTIONARYPROP + +#include "dlg/dlgProperty.h" + +class pgSchema; +class pgTextSearchDictionary; + +class dlgTextSearchDictionary : public dlgTypeProperty +{ +public: + dlgTextSearchDictionary(pgaFactory *factory, frmMain *frame, pgTextSearchDictionary *cfg, pgSchema *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + virtual wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createtsdictionary"); + } + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + void OnChange(wxCommandEvent &ev); + + pgSchema *schema; + pgTextSearchDictionary *dict; + + wxString GetOptionsSql(); + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnSelChangeOption(wxListEvent &ev); + void OnChangeOptionName(wxCommandEvent &ev); + void OnAddOption(wxCommandEvent &ev); + void OnChangeOption(wxCommandEvent &ev); + void OnRemoveOption(wxCommandEvent &ev); + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgTextSearchParser.h b/include/dlg/dlgTextSearchParser.h new file mode 100644 index 0000000..2ed256d --- /dev/null +++ b/include/dlg/dlgTextSearchParser.h @@ -0,0 +1,46 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgTextSearchParser.h - Text Search Parser property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_TSPARSERPROP +#define __DLG_TSPARSERPROP + +#include "dlg/dlgProperty.h" + +class pgSchema; +class pgTextSearchParser; + +class dlgTextSearchParser : public dlgTypeProperty +{ +public: + dlgTextSearchParser(pgaFactory *factory, frmMain *frame, pgTextSearchParser *cfg, pgSchema *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + virtual wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createtsparser"); + } + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + void OnChange(wxCommandEvent &ev); + + pgSchema *schema; + pgTextSearchParser *parser; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgTextSearchTemplate.h b/include/dlg/dlgTextSearchTemplate.h new file mode 100644 index 0000000..d5e4a45 --- /dev/null +++ b/include/dlg/dlgTextSearchTemplate.h @@ -0,0 +1,46 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgTextSearchTemplate.h - Text Search Template property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_TSTEMPLATEPROP +#define __DLG_TSTEMPLATEPROP + +#include "dlg/dlgProperty.h" + +class pgSchema; +class pgTextSearchTemplate; + +class dlgTextSearchTemplate : public dlgTypeProperty +{ +public: + dlgTextSearchTemplate(pgaFactory *factory, frmMain *frame, pgTextSearchTemplate *cfg, pgSchema *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + virtual wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createtstemplate"); + } + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + void OnChange(wxCommandEvent &ev); + + pgSchema *schema; + pgTextSearchTemplate *tmpl; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgTrigger.h b/include/dlg/dlgTrigger.h new file mode 100644 index 0000000..5d9f56f --- /dev/null +++ b/include/dlg/dlgTrigger.h @@ -0,0 +1,56 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgTrigger.h - Trigger property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_TRIGGERPROP +#define __DLG_TRIGGERPROP + +#include "dlg/dlgProperty.h" + +class pgTrigger; +class pgTable; + +class dlgTrigger : public dlgCollistProperty +{ +public: + dlgTrigger(pgaFactory *factory, frmMain *frame, pgTrigger *trg, pgTable *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + void SetObject(pgObject *obj) + { + trigger = (pgTrigger *)obj; + } + wxString GetColumns(); + + +private: + pgTable *table; + pgTrigger *trigger; + + void OnChange(wxCommandEvent &ev); + void OnChangeFunc(wxCommandEvent &ev); + void OnChangeConstraint(wxCommandEvent &ev); + void OnSelectComboCol(wxCommandEvent &ev); + void OnSelectListCol(wxListEvent &ev); + void OnSelectCol(); + void OnAddCol(wxCommandEvent &ev); + void OnRemoveCol(wxCommandEvent &ev); + + virtual bool IsUpToDate(); + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgType.h b/include/dlg/dlgType.h new file mode 100644 index 0000000..69f153c --- /dev/null +++ b/include/dlg/dlgType.h @@ -0,0 +1,94 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgType.h - Typeproperty +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_TYPEPROP +#define __DLG_TYPEPROP + +#include "dlg/dlgProperty.h" +#include "ctl/ctlSeclabelPanel.h" + +class pgType; + +class dlgType : public dlgTypeProperty +{ +public: + dlgType(pgaFactory *factory, frmMain *frame, pgType *node, pgSchema *schema); + + void CheckChange(); + wxString GetSql(); + wxString GetSqlForTypes(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + + bool WannaSplitQueries() + { + return queriesToBeSplitted; + } + + int Go(bool modal); + +protected: + /* + * Type Privileges: + * - Did not inherit dlgTypeProperty & dlgSecurityProperty as it will + * lead to a lot of problem later + **/ + + ctlSecurityPanel *securityPage; + wxArrayString currentAcl; + wxArrayString groups; + bool securityChanged; + + wxString GetGrant(const wxString &allPattern, const wxString &grantObject); + + void OnAddPriv(wxCommandEvent &ev); + void OnDelPriv(wxCommandEvent &ev); + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + +private: + pgSchema *schema; + pgType *type; + ctlSeclabelPanel *seclabelPage; + + void OnChange(wxCommandEvent &event); + void OnTypeChange(wxCommandEvent &ev); + void OnMemberAdd(wxCommandEvent &ev); + void OnMemberChange(wxCommandEvent &ev); + void OnMemberRemove(wxCommandEvent &ev); + void OnMemberSelChange(wxListEvent &ev); + void OnLabelAddBefore(wxCommandEvent &ev); + void OnLabelAddAfter(wxCommandEvent &ev); + void OnLabelRemove(wxCommandEvent &ev); + void OnLabelSelChange(wxListEvent &ev); + void OnSelChangeTyp(wxCommandEvent &ev); + void OnSelChangeTypOrLen(wxCommandEvent &ev); + void OnChangeMember(wxCommandEvent &ev); + void OnNameChange(wxCommandEvent &ev); + void OnSubtypeChange(wxCommandEvent &ev); + + void showDefinition(int panel); + wxString GetFullTypeName(int type); + + wxString catGetText(wxString c); + wxString catGetChar(wxString t); + + wxArrayString memberTypes, memberLengths, memberPrecisions, memberCollations, memberOriginalNames; + bool queriesToBeSplitted; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgUser.h b/include/dlg/dlgUser.h new file mode 100644 index 0000000..56a4b76 --- /dev/null +++ b/include/dlg/dlgUser.h @@ -0,0 +1,61 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgUser.h - User property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_USERPROP +#define __DLG_USERPROP + +#include "dlg/dlgProperty.h" +#include "ctl/calbox.h" +#include "ctl/timespin.h" + +class pgUser; + +class dlgUser : public dlgProperty +{ +public: + dlgUser(pgaFactory *factory, frmMain *frame, pgUser *node = 0); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + wxString GetHelpPage() const; + + int Go(bool modal); + +private: + pgUser *user; + wxArrayString varInfo; + + void OnChangeSuperuser(wxCommandEvent &ev); + void OnChangeSpin(wxSpinEvent &ev); + void OnChangeCal(wxCalendarEvent &ev); + void OnChangeDate(wxDateEvent &ev); + void OnGroupAdd(wxCommandEvent &ev); + void OnGroupRemove(wxCommandEvent &ev); + + void OnVarAdd(wxCommandEvent &ev); + void OnVarRemove(wxCommandEvent &ev); + void OnVarSelChange(wxListEvent &ev); + + void OnVarnameSelChange(wxCommandEvent &ev); + void OnChangePasswd(wxCommandEvent &ev); + + void SetupVarEditor(int var); + + wxArrayString groupsIn; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgUserMapping.h b/include/dlg/dlgUserMapping.h new file mode 100644 index 0000000..cd819dc --- /dev/null +++ b/include/dlg/dlgUserMapping.h @@ -0,0 +1,53 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgUserMapping.h - User Mapping property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_USERMAPPINGPROP +#define __DLG_USERMAPPINGPROP + +#include "dlg/dlgProperty.h" + +class pgForeignServer; +class pgUserMapping; + +class dlgUserMapping : public dlgProperty +{ +public: + dlgUserMapping(pgaFactory *factory, frmMain *frame, pgUserMapping *node, pgForeignServer *parent); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + pgForeignServer *foreignserver; + pgUserMapping *usermapping; + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnSelChangeOption(wxListEvent &ev); + void OnChange(wxCommandEvent &ev); + void OnChangeOptionName(wxCommandEvent &ev); + void OnAddOption(wxCommandEvent &ev); + void OnChangeOption(wxCommandEvent &ev); + void OnRemoveOption(wxCommandEvent &ev); + + wxString GetOptionsSql(); + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgView.h b/include/dlg/dlgView.h new file mode 100644 index 0000000..6c4b79a --- /dev/null +++ b/include/dlg/dlgView.h @@ -0,0 +1,82 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgView.h - View property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_VIEWPROP +#define __DLG_VIEWPROP + +#include "dlg/dlgProperty.h" +#include "ctl/ctlSeclabelPanel.h" + +class pgSchema; +class pgView; +class ctlSQLBox; + +class dlgView : public dlgSecurityProperty +{ +public: + dlgView(pgaFactory *factory, frmMain *frame, pgView *v, pgSchema *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + + void SetObject(pgObject *obj) + { + view = (pgView *)obj; + } + +private: + + virtual bool IsUpToDate(); + void OnChangeVacuum(wxCommandEvent &ev); + void OnCheckMaterializedView(wxCommandEvent &ev); + void FillAutoVacuumParameters(wxString &setStr, wxString &resetStr, const wxString ¶meter, const wxString &val); + wxString AppendNum(bool &changed, wxTextCtrl *ctl, wxString val); + void DisableMaterializedView(); + void DisableStorageParameters(); + int GetIndexCheckOption(const wxString &str) const; + + pgSchema *schema; + pgView *view; + ctlSeclabelPanel *seclabelPage; + wxString oldDefinition; + wxTextValidator mviewNumericValidator; + + void OnChange(wxCommandEvent &event); + + bool tableVacEnabled, hasVacuum, settingAutoVacuum; + wxString settingVacBaseThr, settingAnlBaseThr, settingCostDelay, + settingCostLimit, settingFreezeMinAge, settingFreezeMaxAge, + settingFreezeTableAge; + wxString tableVacBaseThr, tableAnlBaseThr, tableCostDelay, + tableCostLimit, tableFreezeMinAge, tableFreezeMaxAge, + tableFreezeTableAge; + wxString settingVacFactor, settingAnlFactor; + wxString tableVacFactor, tableAnlFactor; + + /* Toast Table */ + bool toastTableVacEnabled, toastTableHasVacuum; + wxString toastTableVacBaseThr, + toastTableCostDelay, toastTableCostLimit, + toastTableFreezeMinAge, toastTableFreezeMaxAge, + toastTableFreezeTableAge; + wxString toastTableVacFactor; + + bool forceSecurityBarrierChanged; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/module.mk b/include/dlg/module.mk new file mode 100644 index 0000000..8fed68d --- /dev/null +++ b/include/dlg/module.mk @@ -0,0 +1,72 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/dlg/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/dlg/dlgAddFavourite.h \ + include/dlg/dlgAggregate.h \ + include/dlg/dlgCast.h \ + include/dlg/dlgCheck.h \ + include/dlg/dlgClasses.h \ + include/dlg/dlgCollation.h \ + include/dlg/dlgColumn.h \ + include/dlg/dlgConnect.h \ + include/dlg/dlgConversion.h \ + include/dlg/dlgDatabase.h \ + include/dlg/dlgDomain.h \ + include/dlg/dlgEventTrigger.h \ + include/dlg/dlgExtension.h \ + include/dlg/dlgEditGridOptions.h \ + include/dlg/dlgFindReplace.h \ + include/dlg/dlgForeignDataWrapper.h \ + include/dlg/dlgForeignKey.h \ + include/dlg/dlgForeignServer.h \ + include/dlg/dlgForeignTable.h \ + include/dlg/dlgFunction.h \ + include/dlg/dlgGroup.h \ + include/dlg/dlgHbaConfig.h \ + include/dlg/dlgIndex.h \ + include/dlg/dlgIndexConstraint.h \ + include/dlg/dlgLanguage.h \ + include/dlg/dlgMainConfig.h \ + include/dlg/dlgManageFavourites.h \ + include/dlg/dlgMoveTablespace.h \ + include/dlg/dlgOperator.h \ + include/dlg/dlgPackage.h \ + include/dlg/dlgPgpassConfig.h \ + include/dlg/dlgProperty.h \ + include/dlg/dlgReassignDropOwned.h \ + include/dlg/dlgRole.h \ + include/dlg/dlgRule.h \ + include/dlg/dlgSchema.h \ + include/dlg/dlgSearchObject.h \ + include/dlg/dlgSelectConnection.h \ + include/dlg/dlgSequence.h \ + include/dlg/dlgServer.h \ + include/dlg/dlgSynonym.h \ + include/dlg/dlgTable.h \ + include/dlg/dlgTablespace.h \ + include/dlg/dlgTextSearchConfiguration.h \ + include/dlg/dlgTextSearchDictionary.h \ + include/dlg/dlgTextSearchParser.h \ + include/dlg/dlgTextSearchTemplate.h \ + include/dlg/dlgTrigger.h \ + include/dlg/dlgType.h \ + include/dlg/dlgUser.h \ + include/dlg/dlgUserMapping.h \ + include/dlg/dlgView.h \ + include/dlg/dlgManageMacros.h \ + include/dlg/dlgExtTable.h \ + include/dlg/dlgSelectDatabase.h \ + include/dlg/dlgResourceGroup.h + +EXTRA_DIST += \ + include/dlg/module.mk + diff --git a/include/frm/frmAbout.h b/include/frm/frmAbout.h new file mode 100644 index 0000000..82217e0 --- /dev/null +++ b/include/frm/frmAbout.h @@ -0,0 +1,41 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmAbout.h - About Box +// +////////////////////////////////////////////////////////////////////////// + +#ifndef FRMABOUT_H +#define FRMABOUT_H + +// Class declarations +class frmAbout : public wxFrame +{ +public: + frmAbout(wxFrame *parent); + + void OnPaint(wxPaintEvent &); + +private: + void SetWindowShape(); + void OnWindowCreate(wxWindowCreateEvent &WXUNUSED(evt)); + void OnLeftDown(wxMouseEvent &WXUNUSED(evt)); + void OnKeyUp(wxKeyEvent &evt); + + wxBitmap about; + DECLARE_EVENT_TABLE() +}; + +class aboutFactory : public actionFactory +{ +public: + aboutFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + + +#endif diff --git a/include/frm/frmBackup.h b/include/frm/frmBackup.h new file mode 100644 index 0000000..94e3978 --- /dev/null +++ b/include/frm/frmBackup.h @@ -0,0 +1,58 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmBackup.h - Backup database dialogue +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef FRMBACKUP_H +#define FRMBACKUP_H + +#include "dlg/dlgClasses.h" +#include "utils/factory.h" + +class frmMain; + +class frmBackup : public ExternProcessDialog +{ +public: + frmBackup(frmMain *form, pgObject *_object); + ~frmBackup(); + + void Go(); + wxString GetDisplayCmd(int step); + wxString GetCmd(int step); + +private: + wxString GetHelpPage() const; + void OnChange(wxCommandEvent &ev); + void OnSelectFilename(wxCommandEvent &ev); + void OnChangePlain(wxCommandEvent &ev); + wxString getCmdPart1(); + wxString getCmdPart2(); + void OnOK(wxCommandEvent &ev); + + pgObject *object; + + wxString backupExecutable; + bool canBlob; + wxString processedFile; + + DECLARE_EVENT_TABLE() +}; + + +class backupFactory : public contextActionFactory +{ +public: + backupFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif diff --git a/include/frm/frmBackupGlobals.h b/include/frm/frmBackupGlobals.h new file mode 100644 index 0000000..7e9f6ae --- /dev/null +++ b/include/frm/frmBackupGlobals.h @@ -0,0 +1,55 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmBackupGlobals.h - Backup globals dialogue +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef FRMBACKUPGLOBALS_H +#define FRMBACKUPGLOBALS_H + +#include "dlg/dlgClasses.h" +#include "utils/factory.h" + +class frmMain; + +class frmBackupGlobals : public ExternProcessDialog +{ +public: + frmBackupGlobals(frmMain *form, pgObject *_object); + ~frmBackupGlobals(); + + void Go(); + wxString GetDisplayCmd(int step); + wxString GetCmd(int step); + +private: + wxString GetHelpPage() const; + void OnChange(wxCommandEvent &ev); + void OnSelectFilename(wxCommandEvent &ev); + wxString getCmdPart1(); + wxString getCmdPart2(); + void OnOK(wxCommandEvent &ev); + + pgObject *object; + wxString processedFile; + wxString backupExecutable; + + DECLARE_EVENT_TABLE() +}; + + +class backupGlobalsFactory : public contextActionFactory +{ +public: + backupGlobalsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif diff --git a/include/frm/frmBackupServer.h b/include/frm/frmBackupServer.h new file mode 100644 index 0000000..697bf3e --- /dev/null +++ b/include/frm/frmBackupServer.h @@ -0,0 +1,55 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmBackupServer.h - Backup server dialogue +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef FRMBACKUPSERVER_H +#define FRMBACKUPSERVER_H + +#include "dlg/dlgClasses.h" +#include "utils/factory.h" + +class frmMain; + +class frmBackupServer : public ExternProcessDialog +{ +public: + frmBackupServer(frmMain *form, pgObject *_object); + ~frmBackupServer(); + + void Go(); + wxString GetDisplayCmd(int step); + wxString GetCmd(int step); + +private: + wxString GetHelpPage() const; + void OnChange(wxCommandEvent &ev); + void OnSelectFilename(wxCommandEvent &ev); + wxString getCmdPart1(); + wxString getCmdPart2(); + void OnOK(wxCommandEvent &ev); + + pgObject *object; + wxString processedFile; + wxString backupExecutable; + + DECLARE_EVENT_TABLE() +}; + + +class backupServerFactory : public contextActionFactory +{ +public: + backupServerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif diff --git a/include/frm/frmConfig.h b/include/frm/frmConfig.h new file mode 100644 index 0000000..01a9312 --- /dev/null +++ b/include/frm/frmConfig.h @@ -0,0 +1,85 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmConfig.h - Configuration tool +// +////////////////////////////////////////////////////////////////////////// + +#ifndef FRMCONFIG_H +#define FRMCONFIG_H + +#include + +class pgConn; +class ctlListView; +class frmMain; + + +extern wxImageList *configImageList; + +class frmConfig : public pgFrame +{ +public: + + enum tryMode + { + NONE = 0, + ANYFILE, + HBAFILE, + MAINFILE, + PGPASSFILE + }; + + static frmConfig *Create(const wxString &title, const wxString &configFile, tryMode mode); + void Go(); + void DoOpen(const wxString &fn = wxEmptyString); + + +protected: + frmConfig(const wxString &title, const wxString &configFile); + frmConfig(frmMain *parent, const wxString &title, pgConn *conn); + ~frmConfig(); + + virtual void DisplayFile(const wxString &str) = 0; + virtual void WriteFile(pgConn *conn = 0) = 0; + virtual wxString GetHintString() + { + return wxEmptyString; + } + + void OpenLastFile(); + void InitFrame(const wxChar *frameName); + bool DoWriteFile(const wxChar *str, pgConn *conn); + bool CheckChanged(bool canVeto); + +private: + + virtual void OnOpen(wxCommandEvent &event); + void OnSave(wxCommandEvent &event); + void OnSaveAs(wxCommandEvent &event); + + void OnClose(wxCloseEvent &event); + void OnExecute(wxCommandEvent &event); + void OnHelp(wxCommandEvent &event); + void OnHint(wxCommandEvent &event); + void OnBugreport(wxCommandEvent &event); + + void DisplayHint(bool force); + +protected: + pgConn *conn; + frmMain *mainForm; + wxString serverFileName; + + wxTextFileType filetype; + + DECLARE_EVENT_TABLE() +}; + + + +#endif diff --git a/include/frm/frmDatabaseDesigner.h b/include/frm/frmDatabaseDesigner.h new file mode 100644 index 0000000..1ee5d71 --- /dev/null +++ b/include/frm/frmDatabaseDesigner.h @@ -0,0 +1,103 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmDatabaseDesigner.h - The database designer form +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __FRM_DATABASEDESIGNER_H +#define __FRM_DATABASEDESIGNER_H + +// Designer headers +#include "hotdraw/figures/hdAbstractFigure.h" +#include "hotdraw/figures/hdPolyLineFigure.h" +#include "hotdraw/figures/hdLineConnection.h" +#include "dd/ddmodel/ddDatabaseDesign.h" +#include "ctl/ctlSQLBox.h" +#include +#include "dlg/dlgSelectConnection.h" + +enum +{ + CTL_DDNOTEBOOK = 1001, + CTL_DDCONNECTION, + CTL_IMPSCHEMA +}; + +class frmDatabaseDesigner : public pgFrame +{ +public: + frmDatabaseDesigner(frmMain *form, const wxString &_title, pgConn *conn); + ~frmDatabaseDesigner(); + void Go(); + void setModelChanged(bool value); +private: + int deletedTab; + bool changed, previousChanged; + wxBitmapComboBox *cbConnection; + wxMenu *diagramMenu, *preferencesMenu, *viewMenu; + wxString lastFile; + frmMain *mainForm; + pgConn *connection; + + // These status flags are required to work round some wierdness on wxGTK, + // particularly on Solaris. + bool closing, loading; + + ddDatabaseDesign *design; + wxPanel *browserPanel, *connectionPanel; + ddModelBrowser *modelBrowser; + ctlAuiNotebook *diagrams; + ctlSQLBox *sqltext; + void setExtendedTitle(); + void OnClose(wxCloseEvent &event); + void OnAddDiagram(wxCommandEvent &event); + void OnAddDiagram2(wxAuiNotebookEvent &event); + void OnDeleteDiagram(wxCommandEvent &event); + void OnRenameDiagram(wxCommandEvent &event); + void OnClickDiagramTab(wxAuiNotebookEvent &event); + void OnDeleteDiagramTab(wxAuiNotebookEvent &event); + void OnDeletedDiagramTab(wxAuiNotebookEvent &event); + void OnAddTable(wxCommandEvent &event); + void OnDeleteTable(wxCommandEvent &event); + void OnAddColumn(wxCommandEvent &event); + void OnNewModel(wxCommandEvent &event); + void OnModelGeneration(wxCommandEvent &event); + void OnModelSaveAs(wxCommandEvent &event); + void OnDiagramGeneration(wxCommandEvent &event); + void OnModelSave(wxCommandEvent &event); + void OnModelLoad(wxCommandEvent &event); + void OnToggleModelBrowser(wxCommandEvent &event); + void OnToggleSQLWindow(wxCommandEvent &event); + void OnChangeConnection(wxCommandEvent &event); + void OnImportSchema(wxCommandEvent &WXUNUSED(event)); + wxBitmap CreateBitmap(const wxColour &colour); + wxColour GetServerColour(pgConn *connection); + void UpdateToolbar(); + wxAuiManager manager; + DECLARE_EVENT_TABLE() +}; + +/////////////////////////////////////////////////////// + +class databaseDesignerBaseFactory : public actionFactory +{ +protected: + databaseDesignerBaseFactory(menuFactoryList *list) : actionFactory(list) {} + wxWindow *StartDialogDesigner(frmMain *form, pgObject *obj, const wxString &sql); +public: + bool CheckEnable(pgObject *obj); +}; + +class databaseDesignerFactory : public databaseDesignerBaseFactory +{ +public: + databaseDesignerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + +#endif // __FRM_DATABASEDESIGNER_H diff --git a/include/frm/frmEditGrid.h b/include/frm/frmEditGrid.h new file mode 100644 index 0000000..5042458 --- /dev/null +++ b/include/frm/frmEditGrid.h @@ -0,0 +1,376 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmEditGrid.h - The SQL Edit Grid form +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __FRMEDITGRID_H +#define __FRMEDITGRID_H + +#include +#include +// wxAUI +#include + +#define CTL_EDITGRID 357 +#include "dlg/dlgClasses.h" +#include "ctl/ctlSQLGrid.h" + +// +// This number MUST be incremented if changing any of the default perspectives +// +#define FRMEDITGRID_PERSPECTIVE_VER wxT("8189") + +#ifdef __WXMAC__ +#define FRMEDITGRID_DEFAULT_PERSPECTIVE wxT("layout2|name=toolBar;caption=Tool bar;state=16788208;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=240;besth=23;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=limitBar;caption=Limit bar;state=16788208;dir=1;layer=10;row=0;pos=243;prop=100000;bestw=120;besth=21;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=415;floaty=793;floatw=-1;floath=-1|name=sqlGrid;caption=Data grid;state=1020;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=300;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=scratchPad;caption=Scratch pad;state=16779260;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=300;besth=150;minw=200;minh=100;maxw=-1;maxh=-1;floatx=347;floaty=725;floatw=-1;floath=-1|dock_size(1,10,0)=25|dock_size(5,0,0)=84|dock_size(3,0,0)=173|") +#else +#ifdef __WXGTK__ +#define FRMEDITGRID_DEFAULT_PERSPECTIVE wxT("layout2|name=toolBar;caption=Tool bar;state=16788208;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=305;besth=30;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=limitBar;caption=Limit bar;state=16788208;dir=1;layer=10;row=0;pos=243;prop=100000;bestw=120;besth=30;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=415;floaty=793;floatw=-1;floath=-1|name=sqlGrid;caption=Data grid;state=1020;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=300;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=scratchPad;caption=Scratch pad;state=16779260;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=300;besth=150;minw=200;minh=100;maxw=-1;maxh=-1;floatx=347;floaty=725;floatw=-1;floath=-1|dock_size(1,10,0)=25|dock_size(5,0,0)=84|dock_size(3,0,0)=173|") +#else +#define FRMEDITGRID_DEFAULT_PERSPECTIVE wxT("layout2|name=toolBar;caption=Tool bar;state=16788208;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=232;besth=23;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=limitBar;caption=Limit bar;state=16788208;dir=1;layer=10;row=0;pos=243;prop=100000;bestw=100;besth=21;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=415;floaty=793;floatw=-1;floath=-1|name=sqlGrid;caption=Data grid;state=1020;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=300;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=scratchPad;caption=Scratch pad;state=16779260;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=300;besth=150;minw=200;minh=100;maxw=-1;maxh=-1;floatx=347;floaty=725;floatw=-1;floath=-1|dock_size(1,10,0)=25|dock_size(5,0,0)=84|dock_size(3,0,0)=173|") +#endif +#endif + +class cacheLine +{ +public: + cacheLine() + { + cols = 0; + stored = false; + readOnly = false; + } + ~cacheLine() + { + if (cols) delete[] cols; + } + + wxString *cols; + bool stored, readOnly; +}; + + +class cacheLinePool +{ +public: + cacheLinePool(int initialLines); + ~cacheLinePool(); + cacheLine *operator[] (int line) + { + return Get(line); + } + cacheLine *Get(int lineNo); + bool IsFilled(int lineNo); + void Delete(int lineNo); + +private: + cacheLine **ptr; + int anzLines; +}; + + +class sqlCell +{ +public: + sqlCell() + { + ClearCell(); + } + + void SetCell(long r, long c) + { + row = r; + col = c; + } + void ClearCell() + { + row = -1; + col = -1; + } + bool IsSet() + { + return row != -1 && col != -1; + } + + long GetRow() + { + return row; + } + long GetCol() + { + return col; + } + +private: + long row; + long col; +}; + +// we cannot derive from wxGridCellAttr because destructor is private but not virtual +class sqlCellAttr +{ +public: + sqlCellAttr() + { + attr = new wxGridCellAttr; + isPrimaryKey = false; + needResize = false; + } + ~sqlCellAttr() + { + attr->DecRef(); + } + int size(); + int precision(); + + wxGridCellAttr *attr; + wxString Quote(pgConn *conn, const wxString &value); + OID type; + long typlen, typmod; + wxString name, typeName, displayTypeName; + bool numeric, isPrimaryKey, needResize; +}; + + +class sqlTable; + +class ctlSQLEditGrid : public ctlSQLGrid +{ +public: + ctlSQLEditGrid(wxFrame *parent, wxWindowID id, const wxPoint &pos, const wxSize &size); + + sqlTable *GetTable() + { + return (sqlTable *)wxGrid::GetTable(); + } + //wxSize GetBestSize(int row, int col); + void ResizeEditor(int row, int col); + wxArrayInt GetSelectedRows() const; + bool CheckRowPresent(int row); + virtual bool IsColText(int col); +}; + +class sqlTable : public wxGridTableBase +{ +public: + sqlTable(pgConn *conn, pgQueryThread *thread, const wxString &tabName, const OID relid, bool _hasOid, const wxString &_pkCols, char _relkind); + ~sqlTable(); + bool StoreLine(); + void UndoLine(int row); + + int GetNumberRows(); + int GetNumberStoredRows(); + int GetNumberCols(); + wxString GetColLabelValue(int col); + wxString GetColLabelValueUnformatted(int col); + wxString GetRowLabelValue(int row); + wxGridCellAttr *GetAttr(int row, int col, wxGridCellAttr::wxAttrKind kind); + + wxString GetValue(int row, int col); + void SetValue(int row, int col, const wxString &value); + + bool IsEmptyCell(int row, int col) + { + return false; + } + bool needsResizing(int col) + { + return columns[col].needResize; + } + bool AppendRows(size_t rows); + bool DeleteRows(size_t pos, size_t rows); + int LastRow() + { + return lastRow; + } + bool IsColText(int col); + bool IsColBoolean(int col); + + bool CheckInCache(int row); + bool IsLineSaved(int row) + { + return GetLine(row)->stored; + } + + bool Paste(); + +private: + pgQueryThread *thread; + pgConn *connection; + bool hasOids; + char relkind; + wxString tableName; + OID relid; + wxString primaryKeyColNumbers; + + cacheLine *GetLine(int row); + wxString MakeKey(cacheLine *line); + void SetNumberEditor(int col, int len); + + cacheLinePool *dataPool, *addPool; + cacheLine savedLine; + int lastRow; + + int *lineIndex; // reindex of lines in dataSet to handle deleted rows + + int nCols; // columns from dataSet + int nRows; // rows initially returned by dataSet + int rowsCached; // rows read from dataset; if nRows=rowsCached, dataSet can be deleted + int rowsAdded; // rows added (never been in dataSet) + int rowsStored; // rows added and stored to db + int rowsDeleted; // rows deleted from initial dataSet + sqlCellAttr *columns; + + wxArrayInt colMap; + + friend class ctlSQLEditGrid; +}; + + +class frmMain; +class pgSchemaObject; + +class frmEditGrid : public pgFrame +{ +public: + frmEditGrid(frmMain *form, const wxString &_title, pgConn *conn, pgSchemaObject *obj, bool ascending = true); + ~frmEditGrid(); + + void ShowForm(bool filter = false); + void Go(); + wxString GetSortCols() const + { + return orderBy; + } ; + void SetSortCols(const wxString &cols); + wxString GetFilter() const + { + return rowFilter; + } ; + void SetFilter(const wxString &filter); + int GetLimit() const + { + return limit; + } ; + void SetLimit(const int rowlimit); + wxMenu *GetFileMenu() + { + return fileMenu; + }; + wxMenu *GetEditMenu() + { + return editMenu; + }; + +private: + void OnEraseBackground(wxEraseEvent &event); + void OnSize(wxSizeEvent &event); + + void OnCloseWindow(wxCloseEvent &event); + void OnClose(wxCommandEvent &event); + void OnHelp(wxCommandEvent &event); + void OnContents(wxCommandEvent &event); + void OnRefresh(wxCommandEvent &event); + void OnDelete(wxCommandEvent &event); + void OnOptions(wxCommandEvent &event); + void OnSave(wxCommandEvent &event); + bool DoSave(); + void CancelChange(); + void OnUndo(wxCommandEvent &event); + void OnCellChange(wxGridEvent &event); + void OnGridSelectCells(wxGridRangeSelectEvent &event); + void OnEditorShown(wxGridEvent &event); + void OnEditorHidden(wxGridEvent &event); + void OnKey(wxKeyEvent &event); + void OnCopy(wxCommandEvent &event); + void OnIncludeFilter(wxCommandEvent &event); + void OnExcludeFilter(wxCommandEvent &event); + void OnRemoveFilters(wxCommandEvent &event); + void OnAscSort(wxCommandEvent &event); + void OnDescSort(wxCommandEvent &event); + void OnRemoveSort(wxCommandEvent &event); + void OnPaste(wxCommandEvent &event); + void OnLabelDoubleClick(wxGridEvent &event); + void OnLabelRightClick(wxGridEvent &event); + void OnCellRightClick(wxGridEvent &event); + void Abort(); + void OnToggleScratchPad(wxCommandEvent &event); + void OnToggleLimitBar(wxCommandEvent &event); + void OnToggleToolBar(wxCommandEvent &event); + void OnAuiUpdate(wxAuiManagerEvent &event); + void OnDefaultView(wxCommandEvent &event); + + wxAuiManager manager; + ctlSQLEditGrid *sqlGrid; + + frmMain *mainForm; + pgConn *connection; + pgQueryThread *thread; + wxMenu *fileMenu, *editMenu, *viewMenu, *toolsMenu, *helpMenu; + ctlMenuToolbar *toolBar; + wxComboBox *cbLimit; + wxTextCtrl *scratchPad; + + char relkind; + OID relid; + bool hasOids; + wxString tableName; + wxString primaryKeyColNumbers; + wxString orderBy; + bool autoOrderBy; + wxString rowFilter; + int limit; + sqlCell *editorCell; + bool closing; + + DECLARE_EVENT_TABLE() +}; + + +class editGridFactoryBase : public contextActionFactory +{ +public: + bool CheckEnable(pgObject *obj); + +protected: + editGridFactoryBase(menuFactoryList *list) : contextActionFactory(list) + { + pkAscending = true; + rowlimit = 0; + } + wxWindow *ViewData(frmMain *form, pgObject *obj, bool filter); + int rowlimit; + bool pkAscending; +}; + + +class editGridFactory : public editGridFactoryBase +{ +public: + editGridFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + + +class editGridFilteredFactory : public editGridFactoryBase +{ +public: + editGridFilteredFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + +class editGridLimitedFactory : public editGridFactoryBase +{ +public: + editGridLimitedFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar, int limit, bool ascending); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + +#endif + + diff --git a/include/frm/frmExport.h b/include/frm/frmExport.h new file mode 100644 index 0000000..f17c5a5 --- /dev/null +++ b/include/frm/frmExport.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmExport.h - The export file dialogue +// +////////////////////////////////////////////////////////////////////////// + +#ifndef FRMEXPORT_H +#define FRMEXPORT_H + + +class ctlSQLResult; +class pgSet; + +#include "dlg/dlgClasses.h" + +// Class declarations +class frmExport : public pgDialog +{ +public: + frmExport(wxWindow *parent); + ~frmExport(); + + bool Export(pgSet *set); + +private: + void OnChange(wxCommandEvent &ev); + void OnHelp(wxCommandEvent &ev); + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnBrowseFile(wxCommandEvent &ev); + wxString InitXml(int cols, int rows); + bool ExportXls(ctlSQLResult *grid); + wxWindow *parent; + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/frm/frmGrantWizard.h b/include/frm/frmGrantWizard.h new file mode 100644 index 0000000..ac3be7b --- /dev/null +++ b/include/frm/frmGrantWizard.h @@ -0,0 +1,58 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmGrantWizard.h - Grant Wizard Dialogue +// +////////////////////////////////////////////////////////////////////////// + +#ifndef FRMGRANTWIZARD_H +#define FRMGRANTWIZARD_H + +#include +#include "dlg/dlgClasses.h" +#include "utils/factory.h" + +class ctlSecurityPanel; + +DECLARE_LOCAL_EVENT_TYPE(EVT_SECURITYPANEL_CHANGE, -1) + +class frmGrantWizard : public ExecutionDialog +{ +public: + frmGrantWizard(frmMain *form, pgObject *_object); + ~frmGrantWizard(); + + void Go(); + wxString GetSql(); + wxString GetHelpPage() const; + +private: + + void OnPageSelect(wxNotebookEvent &event); + void OnCheckAll(wxCommandEvent &event); + void OnUncheckAll(wxCommandEvent &event); + void OnChange(wxCommandEvent &event); + + void AddObjects(pgCollection *collection); + + wxArrayPtrVoid objectArray; + ctlSQLBox *sqlPane; + wxNotebook *nbNotebook; + ctlSecurityPanel *securityPage; + + DECLARE_EVENT_TABLE() +}; + +class grantWizardFactory : public contextActionFactory +{ +public: + grantWizardFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif diff --git a/include/frm/frmHbaConfig.h b/include/frm/frmHbaConfig.h new file mode 100644 index 0000000..5c66cab --- /dev/null +++ b/include/frm/frmHbaConfig.h @@ -0,0 +1,71 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmHbaConfig.h - Backend access configuration tool +// +////////////////////////////////////////////////////////////////////////// + +#ifndef FRMHBACONFIG_H +#define FRMHBACONFIG_H + +#include "frm/frmConfig.h" +#include "utils/pgconfig.h" + +class pgConn; +class pgServer; +class ctlListView; + + +WX_DECLARE_OBJARRAY(pgHbaConfigLine, pgHbaConfigLineArray); + +class frmHbaConfig : public frmConfig +{ +public: + frmHbaConfig(const wxString &title, const wxString &configFile); + frmHbaConfig(frmMain *parent, pgServer *server = 0); + ~frmHbaConfig(); + +protected: + void DisplayFile(const wxString &str); + void WriteFile(pgConn *conn = 0); + wxString GetHintString(); + wxString GetHelpPage() const; + +private: + void Init(); + void UpdateDisplay(pgHbaConfigLine &line); + + void OnContents(wxCommandEvent &event); + void OnUndo(wxCommandEvent &event); + void OnDelete(wxCommandEvent &event); + void OnEditSetting(wxListEvent &event); + void OnSelectSetting(wxListEvent &event); + + ctlListView *listEdit; + pgHbaConfigLineArray lines; + + + DECLARE_EVENT_TABLE() +}; + +class hbaConfigFactory : public actionFactory +{ +public: + hbaConfigFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +class hbaConfigFileFactory : public actionFactory +{ +public: + hbaConfigFileFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + +#endif diff --git a/include/frm/frmHint.h b/include/frm/frmHint.h new file mode 100644 index 0000000..c9fb24b --- /dev/null +++ b/include/frm/frmHint.h @@ -0,0 +1,79 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmHint.h - PostgreSQL Guru hints +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __FRMHINT +#define __FRMHINT + + +#define HINT_CONNECTSERVER wxT("conn-listen") +#define HINT_MISSINGHBA wxT("conn-hba") +#define HINT_MISSINGIDENT wxT("conn-ident") +#define HINT_PRIMARYKEY wxT("pk") +#define HINT_FKINDEX wxT("fki") +#define HINT_VACUUM wxT("vacuum") +#define HINT_VACUUM_FULL wxT("vacuum-full") +#define HINT_QUERYRUNTIME wxT("query-runtime") +#define HINT_INSTRUMENTATION wxT("instrumentation") +#define HINT_INSTRUMENTATION_91_WITH wxT("instrumentation91_with") +#define HINT_INSTRUMENTATION_91_WITHOUT wxT("instrumentation91_without") +#define HINT_ENCODING_ASCII wxT("encoding-ascii") +#define HINT_ENCODING_UNICODE wxT("encoding-unicode") +#define HINT_READONLY_NOPK wxT("view-without-pk") +#define HINT_AUTOVACUUM wxT("autovacuum") +#define HINT_OBJECT_EDITING wxT("object-editing") +#define HINT_SAVING_PASSWORDS wxT("saving-passwords") + +#define HINT_RC_FIX 42 + +#include "dlg/dlgClasses.h" +#include "utils/factory.h" + +class frmMain; +class frmHint : public DialogWithHelp +{ +public: + static int ShowHint(wxWindow *fr, const wxString &hint, const wxString &info = wxEmptyString, bool force = false); + static int ShowHint(wxWindow *fr, const wxArrayString &hints, const wxString &info = wxEmptyString, bool force = false); + static bool WantHint(const wxString &hint); + static void ResetHints(); + + void SetHint(int hint, const wxString &info); + void SetHint(const wxArrayInt &hintnos, const wxString &info); + +private: + frmHint(wxWindow *fr, bool force); + ~frmHint(); + + void SetHint(const wxString &info); + void OnFix(wxCommandEvent &ev); + static int GetHintNo(const wxString &hint); + static bool WantHint(int hintno); + wxString GetPage(const wxChar *hintpage); + wxString GetHelpPage() const; + + DECLARE_EVENT_TABLE() + + wxArrayInt hintnos; + int currentHint; + bool force; +}; + + +class hintFactory : public actionFactory +{ +public: + hintFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar, bool bigTool); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +#endif diff --git a/include/frm/frmImport.h b/include/frm/frmImport.h new file mode 100644 index 0000000..b83069b --- /dev/null +++ b/include/frm/frmImport.h @@ -0,0 +1,49 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmBackup.h - Backup database dialogue +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef FRMIMPORT_H +#define FRMIMPORT_H + +#include "dlg/dlgClasses.h" +#include "utils/factory.h" + +class frmMain; + +class frmImport : public pgDialog +{ +public: + frmImport(frmMain *form, pgObject *_object, pgConn *_conn); + ~frmImport(); + +private: + void OnHelp(wxCommandEvent &ev); + void OnSelectFilename(wxCommandEvent &ev); + void OnChangeFormat(wxCommandEvent &ev); + void OnOK(wxCommandEvent &ev); + + pgConn *connection; + pgObject *object; + bool done; + + DECLARE_EVENT_TABLE() +}; + + +class importFactory : public contextActionFactory +{ +public: + importFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif diff --git a/include/frm/frmMain.h b/include/frm/frmMain.h new file mode 100644 index 0000000..90cea9a --- /dev/null +++ b/include/frm/frmMain.h @@ -0,0 +1,363 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmMain.h - The main form +// +////////////////////////////////////////////////////////////////////////// + +#ifndef FRMMAIN_H +#define FRMMAIN_H + + +// wxWindows headers +#include +#include +#include + +// wxAUI +#include + +#include "frm/frmQuery.h" +#include "dlg/dlgClasses.h" +#include "utils/factory.h" + +// +// This number MUST be incremented if changing any of the default perspectives +// +#define FRMMAIN_PERSPECTIVE_VER wxT("8418") + +#ifdef __WXMAC__ +#define FRMMAIN_DEFAULT_PERSPECTIVE wxT("layout2|name=objectBrowser;caption=Object browser;state=16779260;dir=4;layer=1;row=0;pos=0;prop=100000;bestw=200;besth=450;minw=100;minh=200;maxw=-1;maxh=-1;floatx=236;floaty=222;floatw=-1;floath=-1|name=listViews;caption=Info pane;state=1020;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=400;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=sqlPane;caption=SQL pane;state=16779260;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=400;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=toolBar;caption=Tool bar;state=16788208;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=520;besth=39;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(5,0,0)=18|dock_size(3,0,0)=228|dock_size(1,10,0)=41|dock_size(4,1,0)=233|") +#else +#ifdef __WXGTK__ +#define FRMMAIN_DEFAULT_PERSPECTIVE wxT("layout2|name=objectBrowser;caption=Object browser;state=16779260;dir=4;layer=1;row=0;pos=0;prop=100000;bestw=200;besth=450;minw=100;minh=200;maxw=-1;maxh=-1;floatx=236;floaty=222;floatw=-1;floath=-1|name=listViews;caption=Info pane;state=1020;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=400;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=sqlPane;caption=SQL pane;state=16779260;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=400;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=toolBar;caption=Tool bar;state=16788208;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=586;besth=44;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(5,0,0)=18|dock_size(3,0,0)=228|dock_size(1,10,0)=41|dock_size(4,1,0)=233|") +#else +#define FRMMAIN_DEFAULT_PERSPECTIVE wxT("layout2|name=objectBrowser;caption=Object browser;state=16779260;dir=4;layer=1;row=0;pos=0;prop=100000;bestw=200;besth=450;minw=100;minh=200;maxw=-1;maxh=-1;floatx=236;floaty=222;floatw=-1;floath=-1|name=listViews;caption=Info pane;state=1020;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=400;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=sqlPane;caption=SQL pane;state=16779260;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=400;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=toolBar;caption=Tool bar;state=16788208;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=506;besth=39;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(5,0,0)=18|dock_size(3,0,0)=228|dock_size(1,10,0)=41|dock_size(4,1,0)=233|") + +#endif +#endif +class pgServer; +class pgServerCollection; +class ctlSQLBox; +class ctlTree; +class dlgProperty; +class serverCollection; + +class propertyFactory; +class pluginUtilityFactory; +class ctlMenuButton; + +// A plugin utility +typedef struct PluginUtility +{ + wxString title; + wxString command; + wxString description; + wxString keyfile; + wxString platform; + wxArrayString server_types; + bool database; + wxArrayString applies_to; + bool set_password; + wxArrayString set_env; +} PluginUtility; + + +enum +{ + NBP_PROPERTIES = 0, + NBP_STATISTICS, + NBP_DEPENDENCIES, + NBP_DEPENDENTS +}; + +enum +{ + REFRESH_OBJECT_NONE = 0, + REFRESH_OBJECT_ONLY, + REFRESH_OBJECT_AND_CHILDREN +}; + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) +BEGIN_DECLARE_EVENT_TYPES() +extern const wxEventType SSH_TUNNEL_ERROR_EVENT; +END_DECLARE_EVENT_TYPES() +#endif + +// Class declarations +class frmMain : public pgFrame +{ +public: + frmMain(const wxString &title); + ~frmMain(); + + void OnAction(wxCommandEvent &ev); + void OnReport(wxCommandEvent &ev); + wxString GetHelpPage() const; + + void StartMsg(const wxString &msg); + void EndMsg(bool done = true); + void SetStatusText(const wxString &msg); + void SetCurrentObject(pgObject *data) + { + currentObject = data; + } + bool CheckAlive(); + + void execSelChange(wxTreeItemId item, bool currentNode); + void Refresh(pgObject *data); + void ExecDrop(bool cascaded); + void ShowObjStatistics(pgObject *data, wxWindow *ctrl = NULL); + + wxImageList *GetImageList() + { + return imageList; + } + ctlTree *GetBrowser() + { + return browser; + } + ctlSQLBox *GetSqlPane() + { + return sqlPane; + } + ctlListView *GetProperties() + { + return properties; + } + ctlListView *GetStatistics(); + ctlListView *GetDependencies(); + ctlListView *GetReferencedBy(); + void SelectStatisticsTab() + { + listViews->SetSelection(1); + }; + void StoreServers(); + int ReconnectServer(pgServer *server, bool restore = true); + void ReportConnError(pgServer *server); + pgServerCollection *GetServerCollection() + { + return serversObj; + } + pgServer *ConnectToServer(const wxString &servername, bool restore = false); + + void SetLastPluginUtility(pluginUtilityFactory *pluginFactory) + { + lastPluginUtility = pluginFactory; + } + pluginUtilityFactory *GetLastPluginUtility() + { + return lastPluginUtility; + } + wxMenu *GetPluginsMenu() + { + return pluginsMenu; + } + + wxString GetCurrentNodePath(); + bool SetCurrentNode(wxTreeItemId node, const wxString &path); + + void UpdateAllRecentFiles(); + void UpdateAllFavouritesList(); + void UpdateAllMacrosList(); + + void SetItemBackgroundColour(wxTreeItemId item, wxColour colour); + wxString GetNodePath(wxTreeItemId node); + void ObjectBrowserRefreshing(bool refresh) + { + m_refreshing = refresh; + } + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + void OnSSHTunnelEvent(wxCommandEvent &event); +#endif + +private: + wxAuiManager manager; + ctlTree *browser; + ctlListView *properties; + ctlListView *statistics; + ctlListView *dependents, *dependencies; + ctlAuiNotebook *listViews; + ctlSQLBox *sqlPane; + wxMenu *newMenu, *debuggingMenu, *reportMenu, *toolsMenu, *pluginsMenu, *viewMenu, + *treeContextMenu, *newContextMenu, *slonyMenu, *scriptingMenu, *viewDataMenu; + pgServerCollection *serversObj; + + pluginUtilityFactory *lastPluginUtility; + int pluginUtilityCount; + + propertyFactory *propFactory; + actionFactory *newMenuFactory; + actionFactory *debuggingMenuFactory; + actionFactory *reportMenuFactory; + actionFactory *scriptingMenuFactory; + actionFactory *viewdataMenuFactory; + + wxStopWatch stopwatch; + wxString timermsg; + long msgLevel; + + bool m_refreshing; + + wxTreeItemId denyCollapseItem; + pgObject *currentObject; + wxControl *currentControl; + + void OnChildFocus(wxChildFocusEvent &event); + void OnEraseBackground(wxEraseEvent &event); + void OnSize(wxSizeEvent &event); + void OnSelectItem(wxListEvent &event); + + void CreateMenus(); + void OnContents(wxCommandEvent &event); + void OnExit(wxCommandEvent &event); + void ViewData(bool filter = false); + void OnSaveDefinition(wxCommandEvent &event); + void OnToggleSqlPane(wxCommandEvent &event); + void OnToggleObjectBrowser(wxCommandEvent &event); + void OnToggleToolBar(wxCommandEvent &event); + void OnDefaultView(wxCommandEvent &event); + void OnAuiUpdate(wxAuiManagerEvent &event); + void OnAuiNotebookPageClose(wxAuiNotebookEvent &event); + void OnContextMenu(wxCommandEvent &event); + + void OnPageChange(wxAuiNotebookEvent &event); + void OnPropSelChanged(wxListEvent &event); + void OnPropSelActivated(wxListEvent &event); + void OnPropRightClick(wxListEvent &event); + void OnTreeSelChanged(wxTreeEvent &event); + void OnTreeKeyDown(wxTreeEvent &event); + void OnSelActivated(wxTreeEvent &event); + void OnSelRightClick(wxTreeEvent &event); + void OnCollapse(wxTreeEvent &event); + void OnExpand(wxTreeEvent &event); + void OnClose(wxCloseEvent &event); + + void OnNew(wxCommandEvent &event); + void OnDelete(wxCommandEvent &ev); + void OnCopy(wxCommandEvent &ev); + + void OnCheckAlive(wxCommandEvent &event); + + void OnPositionStc(wxStyledTextEvent &event); + + void ResetLists(); + bool dropSingleObject(pgObject *data, bool updateFinal, bool cascaded); + void doPopup(wxWindow *win, wxPoint point, pgObject *object); + void setDisplay(pgObject *data, ctlListView *props = 0, ctlSQLBox *sqlbox = 0); + void RetrieveServers(); + bool reportError(const wxString &error, const wxString &msgToIdentify, const wxString &hint); + wxTreeItemId RestoreEnvironment(pgServer *server); + + void GetExpandedChildNodes(wxTreeItemId node, wxArrayString &expandedNodes); + void ExpandChildNodes(wxTreeItemId node, wxArrayString &expandedNodes); + + + void PopulatePluginButtonMenu(wxCommandEvent &event); + + // In plugins.cpp + void LoadPluginUtilities(); + void AddPluginUtility(PluginUtility *util); + void CreatePluginUtility(PluginUtility *util); + void ClearPluginUtility(PluginUtility *util); + + DECLARE_EVENT_TABLE() +}; + +enum +{ + CTL_BROWSER = 301, + CTL_NOTEBOOK, + CTL_PROPVIEW, + CTL_STATVIEW, + CTL_DEPVIEW, + CTL_REFVIEW, + CTL_SQLPANE +}; + +class contentsFactory : public actionFactory +{ +public: + contentsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + + +class pgsqlHelpFactory : public actionFactory +{ +public: + pgsqlHelpFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar, bool bigTool); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + + +class edbHelpFactory : public actionFactory +{ +public: + edbHelpFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar, bool bigTool); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + +class greenplumHelpFactory : public actionFactory +{ +public: + greenplumHelpFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar, bool bigTool); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + +class slonyHelpFactory : public actionFactory +{ +public: + slonyHelpFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar, bool bigTool); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + + +class faqFactory : public actionFactory +{ +public: + faqFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + + +class bugReportFactory : public actionFactory +{ +public: + bugReportFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + +class pluginUtilityFactory : public actionFactory +{ +public: + pluginUtilityFactory(menuFactoryList *list, wxMenu *menu, PluginUtility *util); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); + +private: + bool HaveDatabase(pgObject *obj); + + wxString title, command, description; + bool database, set_password; + wxArrayString applies_to, server_types, set_env; +}; + +class pluginButtonMenuFactory : public actionFactory +{ +public: + pluginButtonMenuFactory(menuFactoryList *list, wxMenu *popupmenu, ctlMenuToolbar *toolbar, int pluginCount); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); + +private: + ctlMenuButton *pulldownButton; + bool enableButton; +}; + +#endif diff --git a/include/frm/frmMainConfig.h b/include/frm/frmMainConfig.h new file mode 100644 index 0000000..1635f46 --- /dev/null +++ b/include/frm/frmMainConfig.h @@ -0,0 +1,84 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmMainConfig.h - Backend configuration tool +// +////////////////////////////////////////////////////////////////////////// + +#ifndef FRMMAINCONFIG_H +#define FRMMAINCONFIG_H + +#include "utils/pgconfig.h" +#include "frm/frmConfig.h" +#include "dlg/dlgClasses.h" +#include "utils/factory.h" + +class ctlListView; +class pgServer; + +WX_DECLARE_OBJARRAY(pgConfigOrgLine, pgConfigOrgLineArray); + +class frmMainConfig : public frmConfig +{ +public: + frmMainConfig(const wxString &title, const wxString &configFile); + frmMainConfig(frmMain *parent, pgServer *server = 0); + + ~frmMainConfig(); + +protected: + void DisplayFile(const wxString &str); + void WriteFile(pgConn *conn = 0); + wxString GetHintString(); + wxString GetHelpPage() const; + +private: + void Init(); + void Init(pgSettingReader *reader); + void InitForm(); + + void FillList(const wxString &categoryMember, const wxString &altCategoryMember = wxEmptyString); + void FillList(wxArrayString *category); + + void OnContents(wxCommandEvent &event); + void OnUndo(wxCommandEvent &event); + void OnEditSetting(wxListEvent &event); + void OnSelectSetting(wxListEvent &event); + + void UpdateLine(int line); + + void OnOpen(wxCommandEvent &event); + + + ctlListView *cfgList; + + pgSettingItemHashmap options; + pgCategoryHashmap categories; + pgConfigOrgLineArray lines; + wxString serverVersionNumber; + + DECLARE_EVENT_TABLE() +}; + + +class mainConfigFactory : public actionFactory +{ +public: + mainConfigFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +class mainConfigFileFactory : public actionFactory +{ +public: + mainConfigFileFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + +#endif diff --git a/include/frm/frmMaintenance.h b/include/frm/frmMaintenance.h new file mode 100644 index 0000000..32cafba --- /dev/null +++ b/include/frm/frmMaintenance.h @@ -0,0 +1,45 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmMaintenance.h - Maintenance options selection dialogue +// +////////////////////////////////////////////////////////////////////////// + +#ifndef FRMMAINTENANCE_H +#define FRMMAINTENANCE_H + +#include "dlg/dlgClasses.h" +#include "utils/factory.h" + +// Class declarations +class frmMaintenance : public ExecutionDialog +{ +public: + frmMaintenance(frmMain *form, pgObject *_object); + ~frmMaintenance(); + wxString GetSql(); + + void Go(); + +private: + wxString GetHelpPage() const; + void OnAction(wxCommandEvent &ev); + + DECLARE_EVENT_TABLE() +}; + + +class maintenanceFactory : public contextActionFactory +{ +public: + maintenanceFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +#endif diff --git a/include/frm/frmOptions.h b/include/frm/frmOptions.h new file mode 100644 index 0000000..e3e6c5a --- /dev/null +++ b/include/frm/frmOptions.h @@ -0,0 +1,62 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmOptions.h - The main options dialogue +// +////////////////////////////////////////////////////////////////////////// + +#ifndef FRMOPTIONS_H +#define FRMOPTIONS_H + +#include "dlg/dlgClasses.h" +#include "utils/factory.h" + +class frmMain; + +class ItemWithString : public wxClientData +{ +public: + wxString data; +}; + +// Class declarations +class frmOptions : public pgDialog +{ +public: + frmOptions(frmMain *parent); + ~frmOptions(); + +private: + frmMain *mainForm; + wxString menuSelection; + + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnHelp(wxCommandEvent &ev); + void OnDefault(wxCommandEvent &ev); + void OnSuppressHints(wxCommandEvent &ev); + void OnResetHints(wxCommandEvent &ev); + void OnChangeCopyQuote(wxCommandEvent &ev); + void OnChangeSQLUseCustomColour(wxCommandEvent &ev); + void OnTreeSelChanged(wxTreeEvent &event); + wxString CheckColour(wxString colour); + void UpdateColourControls(); + wxTreeItemId GetTreeItemByLabel(const wxTreeItemId &root, const wxString &label); + void ShowPanel(const wxTreeItemId &menuItem); + DECLARE_EVENT_TABLE() +}; + + +class optionsFactory : public actionFactory +{ +public: + optionsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + + +#endif diff --git a/include/frm/frmPassword.h b/include/frm/frmPassword.h new file mode 100644 index 0000000..c9b8f79 --- /dev/null +++ b/include/frm/frmPassword.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmPassword.h - Change password +// +////////////////////////////////////////////////////////////////////////// + +#ifndef FRMPASSWORD_H +#define FRMPASSWORD_H + +#include "dlg/dlgClasses.h" +#include "utils/factory.h" + +class pgServer; +// Class declarations +class frmPassword : public pgDialog +{ +public: + frmPassword(wxFrame *parent, pgObject *obj); + ~frmPassword(); + +private: + pgServer *server; + void OnHelp(wxCommandEvent &ev); + void OnOK(wxCommandEvent &event); + void OnCancel(wxCommandEvent &event); + DECLARE_EVENT_TABLE() +}; + + +class passwordFactory : public actionFactory +{ +public: + passwordFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif diff --git a/include/frm/frmPgpassConfig.h b/include/frm/frmPgpassConfig.h new file mode 100644 index 0000000..ac91003 --- /dev/null +++ b/include/frm/frmPgpassConfig.h @@ -0,0 +1,62 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmPgpassConfig.h - Pgpass.conf editor +// +////////////////////////////////////////////////////////////////////////// + +#ifndef frmPgpassConfig_H +#define frmPgpassConfig_H + +#include "frm/frmConfig.h" +#include "utils/pgconfig.h" + +class pgConn; +class pgServer; +class ctlListView; + + +WX_DECLARE_OBJARRAY(pgPassConfigLine, pgPassConfigLineArray); + +class frmPgpassConfig : public frmConfig +{ +public: + frmPgpassConfig(const wxString &title, const wxString &configFile); + frmPgpassConfig(frmMain *parent); + ~frmPgpassConfig(); + +protected: + void DisplayFile(const wxString &str); + void WriteFile(pgConn *conn = 0); + wxString GetHintString(); + wxString GetHelpPage() const; + +private: + void Init(); + void UpdateDisplay(pgPassConfigLine &line); + + void OnContents(wxCommandEvent &event); + void OnUndo(wxCommandEvent &event); + void OnDelete(wxCommandEvent &event); + void OnEditSetting(wxListEvent &event); + void OnSelectSetting(wxListEvent &event); + + ctlListView *listEdit; + pgPassConfigLineArray lines; + + + DECLARE_EVENT_TABLE() +}; + +class pgpassConfigFileFactory : public actionFactory +{ +public: + pgpassConfigFileFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + +#endif diff --git a/include/frm/frmQuery.h b/include/frm/frmQuery.h new file mode 100644 index 0000000..667d092 --- /dev/null +++ b/include/frm/frmQuery.h @@ -0,0 +1,448 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmQuery.h - The SQL Query form +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __FRM_QUERY_H +#define __FRM_QUERY_H + +#include "ctl/ctlAuiNotebook.h" +#include "db/pgQueryResultEvent.h" +#include "dlg/dlgClasses.h" +#include "gqb/gqbViewController.h" +#include "gqb/gqbModel.h" +#include "frm/frmExport.h" +#include "utils/factory.h" +#include "utils/favourites.h" +#include "utils/macros.h" +#include +#include +#include +#include + +// wxAUI +#include +#include +#include +#include + +// +// This number MUST be incremented if changing any of the default perspectives +// +#define FRMQUERY_PERSPECTIVE_VER wxT("8320") +#ifdef __WXMAC__ +#define FRMQUERY_DEFAULT_PERSPECTIVE wxT("layout2|name=toolBar;caption=Tool bar;state=16788208;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=465;besth=23;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=databaseBar;caption=Database bar;state=16788208;dir=1;layer=10;row=0;pos=396;prop=100000;bestw=300;besth=21;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=sqlQuery;caption=SQL query;state=17404;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=350;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=outputPane;caption=Output pane;state=16779260;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=550;besth=300;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=scratchPad;caption=Scratch pad;state=16779260;dir=2;layer=0;row=0;pos=0;prop=100000;bestw=250;besth=200;minw=100;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(1,10,0)=25|dock_size(5,0,0)=200|dock_size(3,0,0)=290|dock_size(2,0,0)=255|") +#else +#ifdef __WXGTK__ +#define FRMQUERY_DEFAULT_PERSPECTIVE wxT("layout2|name=toolBar;caption=Tool bar;state=16788208;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=590;besth=30;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=databaseBar;caption=Database bar;state=16788208;dir=1;layer=10;row=0;pos=396;prop=100000;bestw=300;besth=30;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=sqlQuery;caption=SQL query;state=17404;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=350;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=outputPane;caption=Output pane;state=16779260;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=550;besth=300;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=scratchPad;caption=Scratch pad;state=16779260;dir=2;layer=0;row=0;pos=0;prop=100000;bestw=250;besth=200;minw=100;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(1,10,0)=25|dock_size(5,0,0)=200|dock_size(3,0,0)=290|dock_size(2,0,0)=255|") +#else +#define FRMQUERY_DEFAULT_PERSPECTIVE wxT("layout2|name=toolBar;caption=Tool bar;state=16788208;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=465;besth=23;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=databaseBar;caption=Database bar;state=16788208;dir=1;layer=10;row=0;pos=396;prop=100000;bestw=300;besth=21;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=sqlQuery;caption=SQL query;state=17404;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=350;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=outputPane;caption=Output pane;state=16779260;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=550;besth=300;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=scratchPad;caption=Scratch pad;state=16779260;dir=2;layer=0;row=0;pos=0;prop=100000;bestw=250;besth=200;minw=100;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(1,10,0)=25|dock_size(5,0,0)=200|dock_size(3,0,0)=290|dock_size(2,0,0)=255|") +#endif +#endif + +class ExplainCanvas; +class ctlSQLResult; +class pgsApplication; +class pgScriptTimer; + +class QueryExecInfo +{ +public: + QueryExecInfo() + { + toFileExportForm = NULL; + } + ~QueryExecInfo() + { + if (toFileExportForm) + delete toFileExportForm; + } + + int queryOffset; + frmExport *toFileExportForm; + bool singleResult; + bool explain; + bool verbose; +}; + +enum +{ + ORIGIN_MANUAL, + ORIGIN_FILE, + ORIGIN_INITIAL, + ORIGIN_HISTORY, + ORIGIN_GQB +}; + +class frmQuery : public pgFrame +{ +public: + frmQuery(frmMain *form, const wxString &_title, pgConn *conn, const wxString &qry, const wxString &file = wxEmptyString); + ~frmQuery(); + void Go(); + + void writeScriptOutput(); + void setExtendedTitle(); + void SetLineEndingStyle(); + + void SetQueryText(wxString str) + { + sqlQuery->SetText(str); + } + void ColouriseQuery(int start, int stop) + { + sqlQuery->Colourise(start, stop); + } + void SetChanged(bool p_changed) + { + sqlQuery->SetChanged(p_changed); + } + void SetOrigin(int p_origin) + { + sqlQuery->SetOrigin(p_origin); + } + void SetLastPath(wxString p_lastpath) + { + lastPath = p_lastpath; + } + bool CheckChanged(bool canVeto); + + void UpdateFavouritesList(); + void UpdateMacrosList(); + + void UpdateAllRecentFiles(); + void UpdateAllFavouritesList(); + void UpdateAllMacrosList(); + +private: + frmMain *mainForm; + wxAuiManager manager; + ctlSQLBox *sqlQuery; + ctlAuiNotebook *outputPane; + ctlSQLResult *sqlResult; + ctlSQLResult *ctlSQL[10]; + ExplainCanvas *explainCanvas; + wxTextCtrl *msgResult, *msgHistory; + wxBitmapComboBox *cbConnection; + wxTextCtrl *scratchPad; + wxComboBox *sqlQueries; + wxButton *btnDeleteCurrent; + wxButton *btnDeleteAll; + wxArrayString histoQueries; + + ctlAuiNotebook *sqlQueryBook; //container for all SQL tabs + size_t sqlQueryCounter; //for initial tab names + ctlSQLBox *sqlQueryExec; //currently executing SQL tab + ctlSQLBox *sqlQueryExecLast; //output pane shows results for this SQL tab + + // Query timing/status update + wxTimer timer; + wxLongLong elapsedQuery, startTimeQuery; + + // pgScript interface + pgsApplication *pgScript; + wxString pgsOutputString; + wxStringOutputStream pgsStringOutput; + wxTextOutputStream pgsOutput; + pgScriptTimer *pgsTimer; + wxString *querys; + //GQB related + void OnChangeNotebook(wxAuiNotebookEvent &event); + void OnAdjustSizesTimer(wxTimerEvent &event); + void OnResizeHorizontally(wxSplitterEvent &event); + void adjustGQBSizes(); + bool updateFromGqb(bool executing); + ctlAuiNotebook *sqlNotebook; + gqbModel *model; + gqbController *controller; + bool firstTime; + bool gqbUpdateRunning; + wxTimer *adjustSizesTimer; + + // Our connection + pgConn *conn; + + // These status flags are required to work round some wierdness on wxGTK, + // particularly on Solaris. + bool closing, loading; + + void OnEraseBackground(wxEraseEvent &event); + void OnSize(wxSizeEvent &event); + + void OnChangeStc(wxStyledTextEvent &event); + void OnPositionStc(wxStyledTextEvent &event); + void OnLabelRightClick(wxGridEvent &event); + void OnClose(wxCloseEvent &event); + void OnSetFocus(wxFocusEvent &event); + void OnContents(wxCommandEvent &event); + void OnHelp(wxCommandEvent &event); + void OnCancel(wxCommandEvent &event); + void OnExecute(wxCommandEvent &event); + void OnExecScript(wxCommandEvent &event); + void OnExecFile(wxCommandEvent &event); + void OnExplain(wxCommandEvent &event); + void OnCommit(wxCommandEvent &event); + void OnRollback(wxCommandEvent &event); + void OnBuffers(wxCommandEvent &event); + void OnTiming(wxCommandEvent &event); + void OnNew(wxCommandEvent &event); + void OnOpen(wxCommandEvent &event); + void OnSave(wxCommandEvent &event); + void OnSaveAs(wxCommandEvent &event); + void SaveExplainAsImage(wxCommandEvent &event); + void OnExport(wxCommandEvent &event); + void OnExit(wxCommandEvent &event); + void OnCut(wxCommandEvent &event); + void OnCopy(wxCommandEvent &event); + void OnPaste(wxCommandEvent &event); + void OnClear(wxCommandEvent &event); + void OnSummary_Column(wxCommandEvent &event); + void OnSearchReplace(wxCommandEvent &event); + void OnUndo(wxCommandEvent &event); + void OnRedo(wxCommandEvent &event); + void OnSaveHistory(wxCommandEvent &event); + void OnAutoSelectQuery(wxCommandEvent &event); + void SelectQuery(); + void OnAutoRollback(wxCommandEvent &event); + void OnAutoCommit(wxCommandEvent &event); + void OnChangeConnection(wxCommandEvent &ev); + void OnClearHistory(wxCommandEvent &event); + void OnActivate(wxActivateEvent &event); + void OnFocus(wxFocusEvent &event); + void OnSelectAll(wxCommandEvent &event); + void OnAddFavourite(wxCommandEvent &event); + void OnInjectFavourite(wxCommandEvent &event); + void OnManageFavourites(wxCommandEvent &event); + void OnSelectFavourite(wxCommandEvent &event); + void OnQuickReport(wxCommandEvent &event); + void OnAutoIndent(wxCommandEvent &event); + void OnWordWrap(wxCommandEvent &event); + void OnShowIndentGuides(wxCommandEvent &event); + void OnShowWhitespace(wxCommandEvent &event); + void OnShowLineEnds(wxCommandEvent &event); + void OnShowLineNumber(wxCommandEvent &event); + + void OnToggleScratchPad(wxCommandEvent &event); + void OnToggleDatabaseBar(wxCommandEvent &event); + void OnToggleToolBar(wxCommandEvent &event); + void OnToggleOutputPane(wxCommandEvent &event); + void OnAuiUpdate(wxAuiManagerEvent &event); + void OnDefaultView(wxCommandEvent &event); + void OnBlockIndent(wxCommandEvent &event); + void OnBlockOutDent(wxCommandEvent &event); + void OnChangeToUpperCase(wxCommandEvent &event); + void OnChangeToLowerCase(wxCommandEvent &event); + void OnCommentText(wxCommandEvent &event); + void OnUncommentText(wxCommandEvent &event); + void OnExternalFormat(wxCommandEvent &event); + + void OnDeleteCurrent(wxCommandEvent &event); + void OnDeleteAll(wxCommandEvent &event); + + void OnTimer(wxTimerEvent &event); + + void OpenLastFile(); + void SaveTempFile(); + void updateMenu(bool allowUpdateModelSize = true); + void execQuery(const wxString &query, int resultToRetrieve = 0, bool singleResult = false, const int queryOffset = 0, bool toFile = false, bool explain = false, bool verbose = false); + void OnQueryComplete(pgQueryResultEvent &ev); + void completeQuery(bool done, bool explain, bool verbose); + bool isBeginNotRequired(wxString query); + void OnScriptComplete(wxCommandEvent &ev); + void setTools(const bool running); + void showMessage(const wxString &msg, const wxString &msgShort = wxT("")); + int GetLineEndingStyle(); + void OnSetEOLMode(wxCommandEvent &event); + void SetEOLModeDisplay(int mode); + void OnMacroInvoke(wxCommandEvent &event); + void OnMacroManage(wxCommandEvent &event); + void OnAutoReplaceManage(wxCommandEvent &event); + void LoadQueries(); + void SaveQueries(); + void OnChangeQuery(wxCommandEvent &event); + + wxBitmap CreateBitmap(const wxColour &colour); + wxColour GetServerColour(pgConn *connection); + + bool relatesToWindow(wxWindow *which, wxWindow *related); + + // Methods related to SQL tabs + void SqlBookAddPage(); + bool SqlBookRemovePage(); + bool SqlBookCanChangePage(); + void SqlBookSetAutoIndent(bool b); + void SqlBookSetWrapMode(bool b); + void SqlBookSetIndentGuides(bool b); + void SqlBookSetViewWhiteSpace(bool b); + void SqlBookSetViewEOL(bool b); + void SqlBookSetViewLineNumbers(bool b); + void SqlBookSetDatabase(pgConn *con); + void SqlBookUpdatePageTitle(); + void SqlBookDisconnectPage(ctlSQLBox *box = NULL); + bool SqlBookClose(bool canVeto); + // SQL tabs event handlers + void OnSqlBookAddPage(wxCommandEvent &event); + void OnSqlBookPageClose(wxAuiNotebookEvent &event); + void OnSqlBookPageClosed(wxAuiNotebookEvent &event); + void OnSqlBookPageChanged(wxAuiNotebookEvent &event); + void OnSqlBookPageChanging(wxAuiNotebookEvent &event); + void OnSqlBookTabRDown(wxAuiNotebookEvent &event); + void BeginPerspectiveChange(); + void EndPerspectiveChange(bool update = false); + void SetOutputPaneCaption(bool update = false); + + wxWindow *currentControl(); + wxMenu *queryMenu; + wxMenu *favouritesMenu; + wxMenu *macrosMenu; + wxMenu *lineEndMenu; + wxMenu *formatMenu; + wxMenu *saveasImageMenu; + + wxString title; + wxString lastFilename, lastDir; + + queryFavouriteFolder *favourites; + queryMacroList *macros; + queryMacroList *autoreplace; + + bool aborted; + bool lastFileFormat; + bool m_loadingfile; + + // A simple mutex-like flag to prevent concurrent script execution. + // Required because the pgScript parser isn't currently thread-safe :-( + static bool ms_pgScriptRunning; + + DECLARE_EVENT_TABLE() +}; + +// Position of status line fields +enum +{ + STATUSPOS_MSGS = 1, + STATUSPOS_FORMAT, + STATUSPOS_POS, + STATUSPOS_SEL, + STATUSPOS_ROWS, + STATUSPOS_SECS +}; + +enum +{ + CTL_SQLQUERY = 331, + CTL_SQLRESULT, + CTL_MSGRESULT, + CTL_MSGHISTORY, + CTL_NTBKCENTER, + CTL_COLSGRID, + CTL_TIMERSIZES, + CTL_TIMERFRM, + CTL_NTBKGQB, + CTL_SQLQUERYCBOX, + CTL_DELETECURRENTBTN, + CTL_DELETEALLBTN, + CTL_SCRATCHPAD +}; + +/////////////////////////////////////////////////////// + +class queryToolBaseFactory : public actionFactory +{ +protected: + queryToolBaseFactory(menuFactoryList *list) : actionFactory(list) {} + wxWindow *StartDialogSql(frmMain *form, pgObject *obj, const wxString &sql); +public: + bool CheckEnable(pgObject *obj); +}; + +class queryToolDataFactory : public queryToolBaseFactory +{ +protected: + queryToolDataFactory(menuFactoryList *list) : queryToolBaseFactory(list) {} +public: + bool CheckEnable(pgObject *obj); +}; + +class queryToolFactory : public queryToolBaseFactory +{ +public: + queryToolFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + +class queryToolSqlFactory : public queryToolBaseFactory +{ +public: + queryToolSqlFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class queryToolSelectFactory : public queryToolDataFactory +{ +public: + queryToolSelectFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class queryToolExecFactory : public queryToolDataFactory +{ +public: + queryToolExecFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class queryToolDeleteFactory : public queryToolDataFactory +{ +public: + queryToolDeleteFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class queryToolInsertFactory : public queryToolDataFactory +{ +public: + queryToolInsertFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class queryToolUpdateFactory : public queryToolDataFactory +{ +public: + queryToolUpdateFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class queryToolCreateCascadeFactory : public queryToolDataFactory +{ +public: + queryToolCreateCascadeFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); + wxArrayString GetArrayList(wxString *strobj); +}; + +/////////////////////////////////////////////////////// +class pgScriptTimer : public wxTimer +{ +private: + frmQuery *m_parent; + +public: + pgScriptTimer(frmQuery *parent); + void Notify(); +}; + +#endif // __FRM_QUERY_H diff --git a/include/frm/frmReport.h b/include/frm/frmReport.h new file mode 100644 index 0000000..8096d9c --- /dev/null +++ b/include/frm/frmReport.h @@ -0,0 +1,168 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmReport.h - The report file dialogue +// +////////////////////////////////////////////////////////////////////////// + +#ifndef FRMREPORT_H +#define FRMREPORT_H + +#include "dlg/dlgClasses.h" +#include "ctl/ctlListView.h" +#include "ctl/ctlSQLResult.h" + +// Class declarations +class frmReport : public pgDialog +{ +public: + frmReport(wxWindow *p); + ~frmReport(); + + void SetReportTitle(const wxString &t); + + void XmlAddHeaderValue(const wxString &name, const wxString &value); + int XmlCreateSection(const wxString &name); + void XmlSetSectionTableHeader(const int section, const int columns, const wxChar *name, ...); + void XmlAddSectionTableRow(const int section, const int number, const int columns, const wxChar *value, ...); + void XmlAddSectionTableFromListView(const int section, ctlListView *list); + void XmlAddSectionTableFromGrid(const int section, ctlSQLResult *grid); + void XmlSetSectionTableInfo(const int section, const wxString &info) + { + sectionTableInfo[section - 1] = info; + }; + void XmlSetSectionSql(int section, const wxString &sql); + void XmlAddSectionValue(const int section, const wxString &name, const wxString &value); + +private: + void OnChange(wxCommandEvent &ev); + void OnHelp(wxCommandEvent &ev); + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnBrowseFile(wxCommandEvent &ev); + void OnBrowseStylesheet(wxCommandEvent &ev); + + wxString GetSectionTableColumns(const int section); + wxString GetSectionTableRows(const int section); + wxString GetSectionTable(const int section); + wxString GetSection(const int section); + wxString GetXmlReport(const wxString &stylesheet); + wxString XslProcessReport(const wxString &xml, const wxString &xsl); + + wxString GetCssLink(const wxString &file); + wxString GetEmbeddedCss(const wxString &css); + const wxString GetDefaultCss(); + wxString GetDefaultXsl(const wxString &css); + + wxWindow *parent; + wxString header; + wxArrayString sectionName, sectionData, sectionTableHeader, sectionTableRows, sectionTableInfo, sectionSql; + + DECLARE_EVENT_TABLE() +}; + +/////////////////////////////////////////////////////// +// Report Factory base class +/////////////////////////////////////////////////////// +class reportBaseFactory : public actionFactory +{ +protected: + reportBaseFactory(menuFactoryList *list) : actionFactory(list) {} + wxWindow *StartDialog(frmMain *form, pgObject *obj); + frmMain *GetFrmMain() + { + return parent; + }; + virtual void GenerateReport(frmReport *report, pgObject *object) {}; + + frmMain *parent; +public: + bool CheckEnable(pgObject *obj) + { + return false; + }; +}; + + +/////////////////////////////////////////////////////// +// Object properties report +/////////////////////////////////////////////////////// +class reportObjectPropertiesFactory : public reportBaseFactory +{ +public: + reportObjectPropertiesFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + bool CheckEnable(pgObject *obj); + void GenerateReport(frmReport *report, pgObject *object); +}; + +/////////////////////////////////////////////////////// +// Object DDL report +/////////////////////////////////////////////////////// +class reportObjectDdlFactory : public reportBaseFactory +{ +public: + reportObjectDdlFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + bool CheckEnable(pgObject *obj); + void GenerateReport(frmReport *report, pgObject *object); +}; + +/////////////////////////////////////////////////////// +// Object Data dictionary report +/////////////////////////////////////////////////////// +class reportObjectDataDictionaryFactory : public reportBaseFactory +{ +public: + reportObjectDataDictionaryFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + bool CheckEnable(pgObject *obj); + void GenerateReport(frmReport *report, pgObject *object); +}; + +/////////////////////////////////////////////////////// +// Object statistics report +/////////////////////////////////////////////////////// +class reportObjectStatisticsFactory : public reportBaseFactory +{ +public: + reportObjectStatisticsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + bool CheckEnable(pgObject *obj); + void GenerateReport(frmReport *report, pgObject *object); +}; + +/////////////////////////////////////////////////////// +// Object dependencies report +/////////////////////////////////////////////////////// +class reportObjectDependenciesFactory : public reportBaseFactory +{ +public: + reportObjectDependenciesFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + bool CheckEnable(pgObject *obj); + void GenerateReport(frmReport *report, pgObject *object); +}; + +/////////////////////////////////////////////////////// +// Object Dependents report +/////////////////////////////////////////////////////// +class reportObjectDependentsFactory : public reportBaseFactory +{ +public: + reportObjectDependentsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + bool CheckEnable(pgObject *obj); + void GenerateReport(frmReport *report, pgObject *object); +}; + +/////////////////////////////////////////////////////// +// Object list report +/////////////////////////////////////////////////////// +class reportObjectListFactory : public reportBaseFactory +{ +public: + reportObjectListFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + bool CheckEnable(pgObject *obj); + void GenerateReport(frmReport *report, pgObject *object); +}; + +#endif diff --git a/include/frm/frmRestore.h b/include/frm/frmRestore.h new file mode 100644 index 0000000..3d6c6f6 --- /dev/null +++ b/include/frm/frmRestore.h @@ -0,0 +1,90 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmRestore.h - Restore database dialogue +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef FRMRESTORE_H +#define FRMRESTORE_H + +#include "dlg/dlgClasses.h" +#include "utils/factory.h" + +class pgServer; +class frmRestore : public ExternProcessDialog +{ +public: + frmRestore(frmMain *_form, pgObject *_object); + ~frmRestore(); + + void Go(); + wxString GetDisplayCmd(int step); + wxString GetCmd(int step); + +private: + wxString GetHelpPage() const; + void OnChangeName(wxCommandEvent &ev); + void OnChange(wxCommandEvent &ev); + void OnSelectFilename(wxCommandEvent &ev); + void OnView(wxCommandEvent &ev); + void OnOK(wxCommandEvent &ev); + void OnChangeFormat(wxCommandEvent &ev); + void OnChangeData(wxCommandEvent &ev); + void OnChangeSchema(wxCommandEvent &ev); + void OnChangeSection(wxCommandEvent &ev); + void OnChangeList(wxListEvent &ev); + void OnEndProcess(wxProcessEvent &event); + + wxString getCmdPart1(); + wxString getCmdPart2(int step); + + frmMain *form; + pgObject *object; + pgServer *server; + bool viewRunning, filenameValid; + wxString processedFile; + wxString restoreExecutable; + wxString restoreTOCFilename; + int numberOfTOCItems; + + DECLARE_EVENT_TABLE() +}; + + +class restoreFactory : public contextActionFactory +{ +public: + restoreFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +class restoreTreeItemData : public wxTreeItemData +{ +public: + restoreTreeItemData(int id, const wxString &desc); + + int GetId() + { + return restoreId; + } + wxString GetDesc() + { + return restoreDesc; + } + +private: + int restoreId; + wxString restoreDesc; +}; + + + +#endif diff --git a/include/frm/frmSplash.h b/include/frm/frmSplash.h new file mode 100644 index 0000000..83875e5 --- /dev/null +++ b/include/frm/frmSplash.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmSplash.h - Splash Screen +// +////////////////////////////////////////////////////////////////////////// + +#ifndef SPLASH_H +#define SPLASH_H + +// Class declarations +class frmSplash : public wxFrame +{ +public: + frmSplash(wxFrame *parent); + void OnPaint(wxPaintEvent &); + +private: + void SetWindowShape(); + void OnWindowCreate(wxWindowCreateEvent &WXUNUSED(evt)); + + wxBitmap splash; + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/frm/frmStatus.h b/include/frm/frmStatus.h new file mode 100644 index 0000000..a41dbc4 --- /dev/null +++ b/include/frm/frmStatus.h @@ -0,0 +1,262 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmStatus.h - Status Screen +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __FRMSTATUS_H +#define __FRMSTATUS_H + +// wxWindows headers +#include +#include +#include +#include +#include + +// wxAUI +#include + +#include "dlg/dlgClasses.h" +#include "utils/factory.h" +#include "ctl/ctlAuiNotebook.h" + +enum +{ + CTL_RATECBO = 250, + CTL_REFRESHBTN, + CTL_CANCELBTN, + CTL_TERMINATEBTN, + CTL_COMMITBTN, + CTL_ROLLBACKBTN, + CTL_LOGCBO, + CTL_ROTATEBTN, + CTL_STATUSLIST, + CTL_LOCKLIST, + CTL_XACTLIST, + CTL_LOGLIST, + CTL_QUERYSTATELIST, + MNU_STATUSPAGE, + MNU_LOCKPAGE, + MNU_XACTPAGE, + MNU_LOGPAGE, + MNU_QUERYSTATEPAGE, + MNU_TERMINATE, + MNU_COMMIT, + MNU_ROLLBACK, + MNU_COPY_QUERY, + MNU_HIGHLIGHTSTATUS, + MNU_QUERYSTATEVERBOSE, + MNU_QUERYSTATETIME, + MNU_QUERYSTATEBUFFER, + MNU_QUERYSTATETRIGGER, + TIMER_REFRESHUI_ID, + TIMER_STATUS_ID, + TIMER_LOCKS_ID, + TIMER_XACT_ID, + TIMER_LOG_ID, + TIMER_QUERYSTATE_ID +}; + + +enum +{ + PANE_STATUS = 1, + PANE_LOCKS, + PANE_XACT, + PANE_LOG, + PANE_QUERYSTATE +}; + + +// +// This number MUST be incremented if changing any of the default perspectives +// +#define FRMSTATUS_PERSPECTIVE_VER wxT("8274") + +#ifdef __WXMAC__ +#define FRMSTATUS_DEFAULT_PERSPECTIVE wxT("layout2|name=Activity;caption=Activity;state=6293500;dir=4;layer=0;row=0;pos=0;prop=100000;bestw=321;besth=244;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=462;floaty=165;floatw=595;floath=282|name=Locks;caption=Locks;state=6293500;dir=4;layer=0;row=0;pos=1;prop=100000;bestw=321;besth=244;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-231;floaty=235;floatw=595;floath=282|name=Transactions;caption=Transactions;state=6293500;dir=4;layer=0;row=0;pos=2;prop=100000;bestw=0;besth=0;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=461;floaty=527;floatw=595;floath=282|name=Logfile;caption=Logfile;state=6293500;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=0;besth=0;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-103;floaty=351;floatw=595;floath=282|name=toolBar;caption=Tool bar;state=2124528;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=808;besth=33;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=888;floaty=829;floatw=558;floath=49|dock_size(4,0,0)=583|dock_size(5,0,0)=10|dock_size(1,10,0)=35|") +#else +#ifdef __WXGTK__ +#define FRMSTATUS_DEFAULT_PERSPECTIVE wxT("layout2|name=Activity;caption=Activity;state=6293500;dir=4;layer=0;row=1;pos=0;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=174;floaty=216;floatw=578;floath=282|name=Locks;caption=Locks;state=6293500;dir=4;layer=0;row=1;pos=2;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=136;floaty=339;floatw=576;floath=283|name=Transactions;caption=Transactions;state=6293500;dir=4;layer=0;row=1;pos=3;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=133;floaty=645;floatw=577;floath=283|name=Querystate;caption=Query State;state=6309884;dir=4;layer=0;row=1;pos=1;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=154;floaty=255;floatw=1360;floath=751|name=Logfile;caption=Logfile;state=6293500;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=toolBar;caption=toolBar;state=2108144;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=716;besth=23;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=586;floaty=525;floatw=483;floath=49|dock_size(1,10,0)=25|dock_size(4,0,1)=1115|dock_size(5,0,0)=22|") +#else +#define FRMSTATUS_DEFAULT_PERSPECTIVE wxT("layout2|name=Activity;caption=Activity;state=6293500;dir=4;layer=0;row=1;pos=0;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=174;floaty=216;floatw=578;floath=282|name=Locks;caption=Locks;state=6293500;dir=4;layer=0;row=1;pos=2;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=136;floaty=339;floatw=576;floath=283|name=Transactions;caption=Transactions;state=6293500;dir=4;layer=0;row=1;pos=3;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=133;floaty=645;floatw=577;floath=283|name=Querystate;caption=Query State;state=6309884;dir=4;layer=0;row=1;pos=1;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=154;floaty=255;floatw=1360;floath=751|name=Logfile;caption=Logfile;state=6293500;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=toolBar;caption=toolBar;state=2108144;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=716;besth=23;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=586;floaty=525;floatw=483;floath=49|dock_size(1,10,0)=25|dock_size(4,0,1)=1115|dock_size(5,0,0)=22|") +#endif +#endif + + +static wxCriticalSection gs_critsect; + + +// Class declarations + +class frmStatus : public pgFrame +{ +public: + frmStatus(frmMain *form, const wxString &_title, pgConn *conn); + ~frmStatus(); + void Go(); + +private: + wxAuiManager manager; + + frmMain *mainForm; + pgConn *connection, *locks_connection; + + wxString logFormat; + bool logHasTimestamp, logFormatKnown; + int logFmtPos; + + wxDateTime logfileTimestamp, latestTimestamp; + wxString logDirectory, logfileName; + + wxString savedPartialLine; + + bool showCurrent, isCurrent; + + long backend_pid; + + bool loaded; + long logfileLength; + + int currentPane; + + int statusSortColumn; + wxString statusSortOrder; + int lockSortColumn; + wxString lockSortOrder; + int xactSortColumn; + wxString xactSortOrder; + + wxComboBox *cbRate; + wxComboBox *cbLogfiles; + wxButton *btnRotateLog; + ctlComboBoxFix *cbDatabase; + + wxTimer *refreshUITimer; + wxTimer *statusTimer, *locksTimer, *xactTimer, *logTimer, *querystateTimer; + int statusRate, locksRate, xactRate, logRate, querystateRate; + + ctlListView *statusList; + ctlListView *lockList; + ctlListView *xactList; + ctlListView *logList; + ctlListView *querystateList; + + wxMenu *actionMenu; + wxMenu *statusPopupMenu; + wxMenu *lockPopupMenu; + wxMenu *xactPopupMenu; + wxMenu *querystatePopupMenu; + + wxArrayString queries; + + int statusColWidth[12], lockColWidth[10], xactColWidth[5], querystateColWidth[5]; + + int cboToRate(); + wxString rateToCboString(int rate); + + wxImageList *listimages; + long getlongvalue(wxString source,wxString match_str); + void AddStatusPane(); + void AddLockPane(); + void AddXactPane(); + void AddLogPane(); + void AddQuerystatePane(); + + void OnHelp(wxCommandEvent &ev); + void OnContents(wxCommandEvent &ev); + void OnExit(wxCommandEvent &event); + + void OnCopy(wxCommandEvent &ev); + void OnCopyQuery(wxCommandEvent &ev); + + void OnToggleStatusPane(wxCommandEvent &event); + void OnToggleLockPane(wxCommandEvent &event); + void OnToggleXactPane(wxCommandEvent &event); + void OnToggleLogPane(wxCommandEvent &event); + void OnToggleQuerystatePane(wxCommandEvent &event); + void OnEmptyAction(wxCommandEvent &event); + + void OnToggleToolBar(wxCommandEvent &event); + void OnDefaultView(wxCommandEvent &event); + void OnHighlightStatus(wxCommandEvent &event); + + void OnRefreshUITimer(wxTimerEvent &event); + void OnRefreshStatusTimer(wxTimerEvent &event); + void OnRefreshLocksTimer(wxTimerEvent &event); + void OnRefreshXactTimer(wxTimerEvent &event); + void OnRefreshLogTimer(wxTimerEvent &event); + void OnRefreshQuerystateTimer(wxTimerEvent &event); + + void SetColumnImage(ctlListView *list, int col, int image); + void OnSortStatusGrid(wxListEvent &event); + void OnSortLockGrid(wxListEvent &event); + void OnSortXactGrid(wxListEvent &event); + + void OnRightClickStatusGrid(wxListEvent &event); + void OnRightClickLockGrid(wxListEvent &event); + void OnRightClickXactGrid(wxListEvent &event); + void OnRightClickQuerystateGrid(wxListEvent &event); + + void OnStatusMenu(wxCommandEvent &event); + void OnLockMenu(wxCommandEvent &event); + void OnXactMenu(wxCommandEvent &event); + void OnQuerystateMenu(wxCommandEvent &event); + + void OnChgColSizeStatusGrid(wxListEvent &event); + void OnChgColSizeLockGrid(wxListEvent &event); + void OnChgColSizeXactGrid(wxListEvent &event); + void OnChgColSizeQuerystateGrid(wxListEvent &event); + + void OnRateChange(wxCommandEvent &event); + + void OnPaneClose(wxAuiManagerEvent &evt); + + void OnClose(wxCloseEvent &event); + void OnRefresh(wxCommandEvent &event); + void OnCancelBtn(wxCommandEvent &event); + void OnStatusCancelBtn(wxCommandEvent &event); + void OnLocksCancelBtn(wxCommandEvent &event); + void OnTerminateBtn(wxCommandEvent &event); + void OnStatusTerminateBtn(wxCommandEvent &event); + void OnLocksTerminateBtn(wxCommandEvent &event); + void OnSelStatusItem(wxListEvent &event); + void OnSelLockItem(wxListEvent &event); + void OnSelXactItem(wxListEvent &event); + void OnSelLogItem(wxListEvent &event); + void OnSelQuerystateItem(wxListEvent &event); + void OnLoadLogfile(wxCommandEvent &event); + void OnRotateLogfile(wxCommandEvent &event); + void OnCommit(wxCommandEvent &event); + void OnRollback(wxCommandEvent &event); + + void OnChangeDatabase(wxCommandEvent &ev); + + int fillLogfileCombo(); + void emptyLogfileCombo(); + + void addLogFile(wxDateTime *dt, bool skipFirst); + void addLogFile(const wxString &filename, const wxDateTime timestamp, long len, long &read, bool skipFirst); + void addLogLine(const wxString &str, bool formatted = true, bool csv_log_format = false); + + void checkConnection(); + + DECLARE_EVENT_TABLE() +}; + + +class serverStatusFactory : public actionFactory +{ +public: + serverStatusFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif diff --git a/include/frm/lib.txt b/include/frm/lib.txt new file mode 100644 index 0000000..19cdf49 --- /dev/null +++ b/include/frm/lib.txt @@ -0,0 +1 @@ +layout2|name=Activity;caption=Activity;state=6293500;dir=4;layer=0;row=1;pos=0;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=174;floaty=216;floatw=578;floath=282|name=Locks;caption=Locks;state=6293500;dir=4;layer=0;row=1;pos=2;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=136;floaty=339;floatw=576;floath=283|name=Transactions;caption=Transactions;state=6293500;dir=4;layer=0;row=1;pos=3;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=133;floaty=645;floatw=577;floath=283|name=Querystate;caption=Query State;state=6309884;dir=4;layer=0;row=1;pos=1;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=154;floaty=255;floatw=1360;floath=751|name=Logfile;caption=Logfile;state=6293500;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=toolBar;caption=toolBar;state=2108144;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=716;besth=23;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=586;floaty=525;floatw=483;floath=49|dock_size(1,10,0)=25|dock_size(4,0,1)=1115|dock_size(5,0,0)=22| \ No newline at end of file diff --git a/include/frm/menu.h b/include/frm/menu.h new file mode 100644 index 0000000..d0f3adb --- /dev/null +++ b/include/frm/menu.h @@ -0,0 +1,155 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// misc.h - Miscellaneous Utilties +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __MENU_H +#define __MENU_H + +// Menu options +enum +{ + MNU_ADDSERVER = 101, + MNU_SAVEDEFINITION, + MNU_EXIT, + MNU_SAVEAS_IMAGE_GQB, + MNU_SAVEAS_IMAGE_EXPLAIN, + MNU_CONTEXTMENU, + MNU_SQLPANE, + MNU_OBJECTBROWSER, + MNU_TOOLBAR, + MNU_LIMITBAR, + MNU_DATABASEBAR, + MNU_SCRATCHPAD, + MNU_OUTPUTPANE, + MNU_DEFAULTVIEW, + MNU_BACK, + MNU_FORWARD, + MNU_REFRESH, + + MNU_ADDCOLUMN, + MNU_CLOSE, + MNU_MIN, + MNU_RECORD, + MNU_STOP, + MNU_APPEND, + MNU_DELETE, + MNU_OPEN, + MNU_SAVE, + MNU_SAVEAS, + MNU_NEWSQLTAB, + MNU_EXPORT, + MNU_OPTIONS, + MNU_CUT, + MNU_COPY, + MNU_INCLUDEFILTER, + MNU_EXCLUDEFILTER, + MNU_REMOVEFILTERS, + MNU_ASCSORT, + MNU_DESCSORT, + MNU_REMOVESORT, + MNU_PASTE, + MNU_CLEAR, + MNU_FIND, + MNU_REPLACE, + MNU_UNDO, + MNU_REDO, + MNU_CANCEL, + MNU_EXECUTE, + MNU_EXECFILE, + MNU_EXPLAIN, + MNU_EXPLAINANALYZE, + MNU_EXPLAINOPTIONS, + MNU_DOCOMMIT, + MNU_DOROLLBACK, + MNU_VERBOSE, + MNU_COSTS, + MNU_BUFFERS, + MNU_TIMING, + MNU_AUTOSELECTQUERY, + MNU_SUMMARY_COL, + MNU_AUTOROLLBACK, + MNU_AUTOCOMMIT, + MNU_CLEARHISTORY, + MNU_SAVEHISTORY, + MNU_CHECKALIVE, + MNU_SELECTALL, + MNU_EXECPGS, + + MNU_CONTENTS, + MNU_HELP, + MNU_HINT, + + MNU_CONFIGSUBMENU, + MNU_SLONY_SUBMENU, + + MNU_ONLINEUPDATE_NEWDATA, + + MNU_AUTOCOMPLETE, + MNU_AUTOINDENT, + MNU_WORDWRAP, + MNU_SHOWWHITESPACE, + MNU_SHOWLINEENDS, + MNU_SHOWLINENUMBER, + MNU_SHOWINDENTGUIDES, + MNU_QUICKREPORT, + + MNU_UPPER_CASE, + MNU_LOWER_CASE, + MNU_BLOCK_INDENT, + MNU_BLOCK_OUTDENT, + MNU_COMMENT_TEXT, + MNU_UNCOMMENT_TEXT, + MNU_EXTERNALFORMAT, + + MNU_PLUGINBUTTONLIST, + + MNU_LINEENDS, + MNU_CR, + MNU_CRLF, + MNU_LF, + + MNU_ADDTABLE, + MNU_DELETETABLE, + MNU_GENERATEDIAGRAM, + MNU_GENERATEMODEL, + MNU_SAVEMODEL, + MNU_SAVEMODELAS, + MNU_LOADMODEL, + MNU_NEWDIAGRAM, + MNU_DELDIAGRAM, + MNU_RENDIAGRAM, + MNU_CHGFONT, + MNU_TOGGLEDDSQL, + MNU_TOGGLEMBROWSER, + MNU_AUTOREPLACE_MANAGE, + MNU_RECENT, + MNU_NEW = MNU_RECENT + 15, // leave space for recent file entries + + MNU_ACTION = MNU_NEW + 1000, // leave space for objects + + MNU_FAVOURITES_ADD = MNU_ACTION + 1000, // leave space for actions + MNU_FAVOURITES_INJECT, + MNU_FAVOURITES_MANAGE, + + MNU_MACROS_MANAGE = MNU_FAVOURITES_MANAGE + 1000, //leave space for favourites + + // This is used by the Query Tool - the event is fired when the query completes + QUERY_COMPLETE = MNU_MACROS_MANAGE + 100, + PGSCRIPT_COMPLETE, + + // This is a dummy menu item + MNU_DUMMY = QUERY_COMPLETE + 1000, + + //Menu Test + MNU_GENERATESQL +}; + +#endif diff --git a/include/frm/module.mk b/include/frm/module.mk new file mode 100644 index 0000000..7ea5fd0 --- /dev/null +++ b/include/frm/module.mk @@ -0,0 +1,40 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/frm/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/frm/frmAbout.h \ + include/frm/frmBackup.h \ + include/frm/frmBackupGlobals.h \ + include/frm/frmBackupServer.h \ + include/frm/frmConfig.h \ + include/frm/frmDatabaseDesigner.h \ + include/frm/frmEditGrid.h \ + include/frm/frmExport.h \ + include/frm/frmGrantWizard.h \ + include/frm/frmHbaConfig.h \ + include/frm/frmHint.h \ + include/frm/frmImport.h \ + include/frm/frmMain.h \ + include/frm/frmMainConfig.h \ + include/frm/frmMaintenance.h \ + include/frm/frmOptions.h \ + include/frm/frmPassword.h \ + include/frm/frmPgpassConfig.h \ + include/frm/frmQuery.h \ + include/frm/frmReport.h \ + include/frm/frmRestore.h \ + include/frm/frmSplash.h \ + include/frm/frmStatus.h \ + include/frm/menu.h + +EXTRA_DIST += \ + include/frm/module.mk + diff --git a/include/gqb/gqbArrayCollection.h b/include/gqb/gqbArrayCollection.h new file mode 100644 index 0000000..1298e85 --- /dev/null +++ b/include/gqb/gqbArrayCollection.h @@ -0,0 +1,70 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbArrayCollection.h - Implementation of Collection Using Arrays +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBARRAYCOLLECTION_H +#define GQBARRAYCOLLECTION_H + +// App headers +#include "gqb/gqbCollectionBase.h" + +WX_DEFINE_ARRAY_PTR(gqbObject *, gqbObjsArray); + +class gqbArrayIterator : public gqbIteratorBase +{ +public: + gqbArrayIterator(gqbObjsArray *gqbPtrsArray); + gqbObject *Next(); + bool HasNext(); + void ResetIterator(); + +private: + int position; + gqbObjsArray *internalArray; +}; + +class gqbArrayDownIterator : public gqbIteratorBase +{ +public: + gqbArrayDownIterator(gqbObjsArray *gqbPtrsArray); + gqbObject *Next(); + bool HasNext(); + void ResetIterator(); + +private: + int position; + gqbObjsArray *internalArray; +}; + +//Create Array Objects used as base for gqbCollections +class gqbArrayCollection : public gqbCollectionBase +{ +public: + ~gqbArrayCollection(); + void addItem(gqbObject *item); + void removeItem(gqbObject *item); + gqbIteratorBase *createIterator(); + gqbIteratorBase *createDownIterator(); + gqbObject *getItemAt(int index); + int count(); + bool existsObject(gqbObject *item); + int getIndex(gqbObject *item); + void insertAtIndex(gqbObject *item, int index); + void deleteAll(); + void removeAll(); + gqbObject *&operator[](size_t index) + { + return gqbArray[index]; + } + +private: + gqbObjsArray gqbArray; +}; +#endif diff --git a/include/gqb/gqbBrowser.h b/include/gqb/gqbBrowser.h new file mode 100644 index 0000000..b19ff39 --- /dev/null +++ b/include/gqb/gqbBrowser.h @@ -0,0 +1,68 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbBrowser.h - Tables Tree of GQB. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBBROWSER_H +#define GQBBROWSER_H + +enum gqbImages +{ + GQB_IMG_DATABASE = 0, + GQB_IMG_NAMESPACE = 1, + GQB_IMG_TABLE = 2, + GQB_IMG_NAMESPACES = 3, + GQB_IMG_CATALOGS = 4, + GQB_IMG_CATALOG = 5, + GQB_IMG_CATALOG_OBJ = 6, + GQB_IMG_VIEW = 7, + GQB_IMG_EXTTABLE = 8 +}; + +class gqbController; + +class gqbBrowser : public wxTreeCtrl +{ +public: + gqbBrowser(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, gqbController *_controller); + ~gqbBrowser(); + wxTreeItemId &createRoot(wxString &Name); + wxTreeItemId &getCatalogRootNode() + { + return catalogsNode; + } + wxTreeItemId &getTablesRootNode() + { + return schemasNode; + } + void refreshTables(pgConn *connection); + void setDnDPoint(int x, int y) + { + xx = x; + yy = y; + }; + +private: + enum typeSchema // GQB-TODO: DELETE from here should be locate at gqbDatabase + { + GQB_CATALOG, + GQB_OTHER + }; + + wxTreeItemId rootNode, catalogsNode, schemasNode; + void OnItemActivated(wxTreeEvent &event); + void OnBeginDrag(wxTreeEvent &event); + wxString NumToStr(OID value); + gqbController *controller; //Allow access to controller functions like add table to model + wxImageList *imageList; + int xx, yy; + + DECLARE_EVENT_TABLE() +}; +#endif diff --git a/include/gqb/gqbCollection.h b/include/gqb/gqbCollection.h new file mode 100644 index 0000000..d73fad2 --- /dev/null +++ b/include/gqb/gqbCollection.h @@ -0,0 +1,39 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbCollection.h - Generic implementation of a Collection used by GQB. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBCOLLECTION_H +#define GQBCOLLECTION_H + +// App headers +#include "gqb/gqbObject.h" +#include "gqb/gqbCollectionBase.h" + +class gqbCollection : public wxObject +{ +public: + gqbCollection(gqbCollectionBase *collectionBase); + virtual ~gqbCollection(); + void addItem(gqbObject *item); + void removeItem(gqbObject *item); + void deleteAll(); + void removeAll(); + int count(); + bool existsObject(gqbObject *item); + int getIndex(gqbObject *item); + gqbObject *getItemAt(int index); + void insertAtIndex(gqbObject *item, int index); + gqbIteratorBase *createIterator(); + gqbIteratorBase *createDownIterator(); + +private: + gqbCollectionBase *collection; +}; +#endif diff --git a/include/gqb/gqbCollectionBase.h b/include/gqb/gqbCollectionBase.h new file mode 100644 index 0000000..f76d604 --- /dev/null +++ b/include/gqb/gqbCollectionBase.h @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbCollectionBase.h - A Collection Interface for GQB +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBCOLLECTIONFACTORY_H +#define GQBCOLLECTIONFACTORY_H + +// App headers +#include "gqb/gqbObject.h" + +// This class it's like an interface (but with not all advantages of this at runtime) +// If in a future I just don't want to use an array, simple implement this abstract class again +// with the new data structure. + +class gqbIteratorBase : wxObject +{ +public: + gqbIteratorBase() {}; + virtual gqbObject *Next() = 0; + virtual bool HasNext() = 0; + virtual void ResetIterator() = 0; +}; +// OR probably let to this class to +class gqbCollectionBase : wxObject // GQB-TODO: Change to the class because probably it's not adapted to the actual use of this class +{ +public: + gqbCollectionBase() {}; + virtual ~gqbCollectionBase() {}; + virtual void addItem(gqbObject *item) = 0; + virtual void removeItem(gqbObject *item) = 0; + virtual gqbObject *getItemAt(int index) = 0; + virtual gqbIteratorBase *createIterator() = 0; + virtual gqbIteratorBase *createDownIterator() = 0; + virtual int count() = 0; + virtual bool existsObject(gqbObject *item) = 0; + virtual int getIndex(gqbObject *item) = 0; + virtual void insertAtIndex(gqbObject *item, int index) = 0; + virtual void deleteAll() = 0; + virtual void removeAll() = 0; //remove all items from collection without deleting. +}; +#endif diff --git a/include/gqb/gqbColumn.h b/include/gqb/gqbColumn.h new file mode 100644 index 0000000..82a1e24 --- /dev/null +++ b/include/gqb/gqbColumn.h @@ -0,0 +1,25 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbColumn.h - Column Object for GQB +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBCOLUMN_H +#define GQBCOLUMN_H + +// App headers +#include "gqb/gqbObject.h" +#include "gqb/gqbTable.h" + +// Create Array Objects used as base for gqbCollections +class gqbColumn : public gqbObject +{ +public: + gqbColumn(gqbObject *parent, wxString name, pgConn *connection); +}; +#endif diff --git a/include/gqb/gqbDatabase.h b/include/gqb/gqbDatabase.h new file mode 100644 index 0000000..7af4742 --- /dev/null +++ b/include/gqb/gqbDatabase.h @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbDatabase.h - Database object for GQB. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBDATABASE_H +#define GQBDATABASE_H + +// App headers +#include "gqb/gqbObject.h" +#include "gqb/gqbSchema.h" +#include "gqb/gqbBrowser.h" + +class gqbDatabase : public gqbObject +{ +public: + gqbDatabase(wxString name, pgConn *connection); + void createObjects(gqbBrowser *_tablesBrowser); + +private: + enum typeSchema + { + GQB_CATALOG, + GQB_OTHER + }; + void createSchemas(gqbBrowser *tablesBrowser, wxTreeItemId parentNode, typeSchema MetaType, int indexImage); +}; +#endif diff --git a/include/gqb/gqbEvents.h b/include/gqb/gqbEvents.h new file mode 100644 index 0000000..1084ff9 --- /dev/null +++ b/include/gqb/gqbEvents.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// Events.h - IDs for GQB Events +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBEVENTS_H +#define GQBEVENTS_H + +enum gqb_Events +{ + GQB_COLSTREE = 1000, + GQB_BROWSER, + GQB_HORZ_SASH +}; + +enum gqb_rMenus +{ + GQB_RMJ_DELETE = 2000, + GQB_RMJ_SETTYPE, + GQB_RMT_DELETE, + GQB_RMT_SETALIAS, + GQB_REFRESH +}; +#endif diff --git a/include/gqb/gqbGraphBehavior.h b/include/gqb/gqbGraphBehavior.h new file mode 100644 index 0000000..83f60f8 --- /dev/null +++ b/include/gqb/gqbGraphBehavior.h @@ -0,0 +1,39 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbGraphsimple.h - A simple Graphic Interface for GQB +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBGRAPHBEHAVIOR_H +#define GQBGRAPHBEHAVIOR_H + +#include + +// App headers +#include "gqb/gqbQueryObjs.h" + +// Interface class for drawing of objects in canvas +class gqbGraphBehavior : public wxObject +{ +public: + // Important: The drawTable function always should store the width & height of the graphic + // representation of the table inside the gqbQueryObject for use of controller. + virtual void drawTable(wxMemoryDC &bdc, wxPoint *origin, gqbQueryObject *queryTable) = 0; + virtual void drawTempJoinLine(wxMemoryDC &bdc, wxPoint &origin, wxPoint &end) = 0; + virtual void drawJoin(wxMemoryDC &bdc, wxPoint &origin, wxPoint &dest, wxPoint &anchorUsed, bool selected, type_Join joinKind) = 0; + virtual void calcAnchorPoint(gqbQueryJoin *join) = 0; + virtual void UpdatePosObject(gqbQueryObject *queryTable, int x, int y, int cursorAdjustment) = 0; + + // GQB-TODO find a way to not hard code the 17 default value + virtual gqbColumn *getColumnAtPosition(wxPoint *clickPoint, gqbQueryObject *queryTable, int sensibility = 17) = 0; + virtual bool clickOnJoin(gqbQueryJoin *join, wxPoint &pt, wxPoint &origin, wxPoint &dest) = 0; + virtual int getTitleRowHeight() = 0; +private: + +}; +#endif diff --git a/include/gqb/gqbGraphSimple.h b/include/gqb/gqbGraphSimple.h new file mode 100644 index 0000000..0a05744 --- /dev/null +++ b/include/gqb/gqbGraphSimple.h @@ -0,0 +1,46 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbGraphsimple.h - A simple Implementation of the Graphic Interface for GQB +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBGRAPHSIMPLE_H +#define GQBGRAPHSIMPLE_H + +#include + +// App headers +#include "gqb/gqbQueryObjs.h" +#include "gqb/gqbGraphBehavior.h" + +// Create Array Objects used as base for gqbCollections +class gqbGraphSimple : public gqbGraphBehavior +{ +public: + gqbGraphSimple(); + void drawTable(wxMemoryDC &bdc, wxPoint *origin, gqbQueryObject *queryTable); + void drawTempJoinLine(wxMemoryDC &bdc, wxPoint &origin, wxPoint &end); + void calcAnchorPoint(gqbQueryJoin *join); + void drawJoin(wxMemoryDC &bdc, wxPoint &origin, wxPoint &dest, wxPoint &anchorUsed, bool selected, type_Join joinKind); + void UpdatePosObject(gqbQueryObject *queryTable, int x, int y, int cursorAdjustment); + gqbColumn *getColumnAtPosition(wxPoint *clickPoint, gqbQueryObject *queryTable, int sensibility = 17); + bool clickOnJoin(gqbQueryJoin *join, wxPoint &pt, wxPoint &origin, wxPoint &dest); + int getTitleRowHeight(); + +private: + wxFont normalFont, TableTitleFont; + wxBrush BackgroundLayer1, BackgroundLayer2, BackgroundTitle, selectedBrush; + int minTableWidth, minTableHeight; + int rowHeight, rowLeftMargin, rowRightMargin, rowTopMargin, lineClickThreshold; + wxPen selectedPen; + wxBitmap imgSelBoxEmpty, imgSelBoxSelected; + bool insideLine(wxPoint &pt, wxPoint &p1, wxPoint &p2, int threshold); + double distanceToLine(wxPoint pt, wxPoint p1, wxPoint p2); + wxPoint findLineMiddle(wxPoint p1, wxPoint p2); +}; +#endif diff --git a/include/gqb/gqbGridJoinTable.h b/include/gqb/gqbGridJoinTable.h new file mode 100644 index 0000000..8a45337 --- /dev/null +++ b/include/gqb/gqbGridJoinTable.h @@ -0,0 +1,50 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbGridJoinTable.h - Table implementation for Join Panel Grid +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBGRIDJOINTABLE_H +#define GQBGRIDJOINTABLE_H + +#include +#include + +// App headers +#include "gqb/gqbQueryObjs.h" +#include "gqb/gqbArrayCollection.h" + +class gqbController; + +class gqbGridJoinTable : public wxGridTableBase +{ +public: + gqbGridJoinTable(gqbController *_controller); + ~gqbGridJoinTable(); + int GetNumberRows(); + int GetNumberCols(); + bool IsEmptyCell(int row, int col); + wxString GetValue(int row, int col); + wxString GetColLabelValue( int col); + void SetValue(int row, int col, const wxString &value); + void AppendJoin(gqbQueryJoin *item); + void removeJoin(gqbQueryJoin *item); + void removeJoins(gqbQueryObject *obj); + void emptyTableData(); + gqbQueryObject *DeleteRow(size_t pos); + bool ReplaceJoin(gqbQueryJoin *orig, gqbQueryJoin *newVal); + gqbQueryJoin *GetJoin(int row); + void selectJoin(gqbQueryJoin *join); + +private: + gqbController *controller; + gqbArrayCollection joins; +}; + +#endif + diff --git a/include/gqb/gqbGridOrderTable.h b/include/gqb/gqbGridOrderTable.h new file mode 100644 index 0000000..c58808e --- /dev/null +++ b/include/gqb/gqbGridOrderTable.h @@ -0,0 +1,51 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbGridOrderTable.h - Table implementation for Order By Panel Grid +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBGRIDORDERTABLE_H +#define GQBGRIDORDERTABLE_H + +#include + +// App headers +#include "gqb/gqbArrayCollection.h" +#include "gqb/gqbColumn.h" +#include "gqb/gqbQueryObjs.h" +#include "gqb/gqbModel.h" + +class gqbGridOrderTable : public wxGridTableBase +{ +public: + gqbGridOrderTable(int numColumns, gqbObjsArray *cols, gqbObjsArray *parent, charArray *orderBy); + ~gqbGridOrderTable(); + int GetNumberRows(); + int GetNumberCols(); + bool IsEmptyCell( int row, int col ); + wxString GetValue( int row, int col ); + wxString GetColLabelValue( int col); + void SetValue( int row, int col, const wxString &value ); + void AppendItem(gqbColumn *column, gqbQueryObject *parent, char kindOrder); + void emptyTableData(gqbQueryObject *object); + gqbObject *getObjectAt(int pos, int col); + bool removeFirstRow(gqbObject *itemTable); + void removeRowAt(int i); + void changesRangeOnePos(int topPos, int bottomPos, int newTop); + void changesPositions(int sPos, int dPos); + +private: + int numberColumns; // GQB-TODO: replace this with grid cols number function if possible + gqbObjsArray *columns; // Here store position of the columns at Select projection clause + // [Select c1,c2,c3...,cn from...] + gqbObjsArray *colsParents; // Because above array only store a column object cannot be recovered + // the object that store it (gqbQueryObject) [remember can be use same + // table twice on a query]. + charArray *kindOfOrder; // A [Asc] D [Desc] +}; +#endif diff --git a/include/gqb/gqbGridProjTable.h b/include/gqb/gqbGridProjTable.h new file mode 100644 index 0000000..afd5926 --- /dev/null +++ b/include/gqb/gqbGridProjTable.h @@ -0,0 +1,55 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbGridProjTable.h - Table implementation for Projection Panel Grid +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBGRIDPROJTABLE_H +#define GQBGRIDPROJTABLE_H + +#include + +// App headers +#include "gqb/gqbModel.h" +#include "gqb/gqbArrayCollection.h" + +// GQB-TODO: don't use gqbObjsArray, use a new one in the model because violating MVC Pattern + +// GQB-TODO: this is not needed the one in gqbArrayCollections works her ????? +// WX_DEFINE_ARRAY_PTR(gqbObject *, gqbObjsArray); this is not + +// Create the Data Model that will be used by wxGrid Component +class gqbGridProjTable : public wxGridTableBase +{ +public: + gqbGridProjTable(gqbObjsArray *position, gqbObjsArray *parent, wxArrayString *alias); + virtual ~gqbGridProjTable(); + int GetNumberRows(); + int GetNumberCols(); + bool IsEmptyCell( int row, int col ); + wxString GetValue( int row, int col ); + void SetValue( int row, int col, const wxString &value ); + void *GetValueAsCustom( int row, int col, const wxString &typeName ); + void SetValueAsCustom( int row, int col, const wxString &typeName, void *value ); + wxString GetColLabelValue( int col); + bool removeRow(gqbObject *itemTable, gqbObject *itemColumn); + void removeAllRows(gqbObject *itemTable); + void changesPositions(int spos, int dpos); + void changesRangeOnePos(int topPos, int bottomPos, int newTop); + void AppendItem(int col, gqbObject *item); + void emptyTableData(); + +private: + gqbObjsArray *colsPosition; // Here store position of the columns at Select projection clause + // [Select c1,c2,c3...,cn from...] + gqbObjsArray *colsParents; // Because above array only store a column object cannot be recovered + // the object that store it (gqbQueryObject) [remember can be use + // same table twice on a query]. + wxArrayString *columnsAlias; // GQB-TODO: find a better solution than this +}; +#endif diff --git a/include/gqb/gqbGridRestTable.h b/include/gqb/gqbGridRestTable.h new file mode 100644 index 0000000..f930783 --- /dev/null +++ b/include/gqb/gqbGridRestTable.h @@ -0,0 +1,101 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbGridRestTable.h - Table implementation for Restrictions Panel Grid +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBGRIDRESTTABLE_H +#define GQBGRIDRESTTABLE_H + +#include +#include + +// App headers +#include "gqb/gqbModel.h" +#include "gqb/gqbArrayCollection.h" + +class gqbGridRestTable : public wxGridTableBase +{ +public: + gqbGridRestTable(gqbRestrictions *_restrictions); + ~gqbGridRestTable(); + int GetNumberRows(); + int GetNumberCols(); + bool IsEmptyCell( int row, int col ); + wxString GetValue( int row, int col ); + wxString GetColLabelValue( int col); + void SetValue( int row, int col, const wxString &value ); + void AppendItem(gqbQueryRestriction *item); + void emptyTableData(); + bool DeleteRows(size_t pos, size_t numRows); + +private: + gqbRestrictions *restrictions; +}; + +// +// Cell rendering utilities classes +// + +class wxGridCellComboBoxRenderer : public wxGridCellStringRenderer +{ +public: + wxGridCellComboBoxRenderer(wxLayoutAlignment border = wxLAYOUT_NONE) : + m_border(border) {} + virtual void Draw(wxGrid &grid, wxGridCellAttr &attr, wxDC &dc, const wxRect &rect, int row, int col, bool isSelected); + virtual wxGridCellRenderer *Clone() const + { + return new wxGridCellComboBoxRenderer; + } + +private: + wxLayoutAlignment m_border; +}; + +class wxGridCellButtonRenderer : public wxGridCellStringRenderer +{ +public: + wxGridCellButtonRenderer(wxLayoutAlignment border = wxLAYOUT_NONE) : + m_border(border) {} + virtual void Draw(wxGrid &grid, wxGridCellAttr &attr, wxDC &dc, const wxRect &rect, int row, int col, bool isSelected); + virtual wxGridCellRenderer *Clone() const + { + return new wxGridCellComboBoxRenderer; + } + +private: + wxLayoutAlignment m_border; +}; + +// Shows a wxGridCellChoiceEditor of cell's wide +class dxGridCellSizedChoiceEditor : public wxGridCellChoiceEditor +{ +public: + dxGridCellSizedChoiceEditor(const wxArrayString &choices, bool allowOthers = false); + dxGridCellSizedChoiceEditor(size_t count = 0, const wxString choices[] = NULL, bool allowOthers = false); + + ~dxGridCellSizedChoiceEditor() {} + + virtual wxGridCellEditor *Clone() const; + virtual void Show(bool show, wxGridCellAttr *attr = (wxGridCellAttr *)NULL); + +protected: + int m_maxWide; + + DECLARE_NO_COPY_CLASS(dxGridCellSizedChoiceEditor) + +}; + +// GQB-TODO: don't use gqbObjsArray, use a new one in the model because violating MVC Pattern + +// GQB-TODO: this is not needed the one in gqbArrayCollections works her ????? +// WX_DEFINE_ARRAY_PTR(gqbObject *, gqbObjsArray); this is not + +// Create the Data Model that will be used by wxGrid Component + +#endif diff --git a/include/gqb/gqbModel.h b/include/gqb/gqbModel.h new file mode 100644 index 0000000..f716000 --- /dev/null +++ b/include/gqb/gqbModel.h @@ -0,0 +1,104 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbModel.h - Model of MVC Pattern for GQB +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBMODEL_H +#define GQBMODEL_H + +// App headers +#include "gqb/gqbQueryObjs.h" + +#define MAXRECTANGLES 10 + +WX_DEFINE_ARRAY_CHAR(char, charArray); + +class gqbModel : public wxObject +{ +public: + gqbModel(); + ~gqbModel(); + void emptyAll(); + + // Tables + gqbQueryObject *addTable(gqbTable *table, wxPoint p); + void deleteTable(gqbQueryObject *table); + gqbIteratorBase *createQueryIterator(); + gqbIteratorBase *createDownQueryIterator(); + int tablesCount(); + + // Projection Panel + gqbObjsArray *getOrderedColumns() + { + return &colsPosition; + }; + gqbObjsArray *getColumnsParents() + { + return &colsParents; + }; + wxArrayString *getColumnsAlias() + { + return columnsAlias; + }; + + // Restrictions Panel + gqbQueryRestriction *addRestriction(); // GQB-TODO: delete if not use this function + gqbRestrictions *getRestrictions() + { + return restrictions; + }; + + // Order By Panel + gqbObjsArray *getOrdByAvailColumns() + { + return &AvailableColumns; + }; + gqbObjsArray *getOrdByAvailParents() + { + return &ColumnAvailParent; + }; + gqbObjsArray *getOrdByColumns() + { + return &OrderedColumns; + }; + gqbObjsArray *getOrdByParents() + { + return &ColumnOrdParent; + }; + charArray *getOrdByKind() + { + return &orderBy; + }; + +private: + // query objects [tables] with joins inside + gqbQueryObjs *queryCollection; + + // projection Panel + gqbObjsArray colsPosition; // Here store position of the columns at Select projection clause + // [Select c1,c2,c3...,cn from...] + gqbObjsArray colsParents; // Because above array only store a column object cannot be recovered + // the object that store it (gqbQueryObject) [remember can be use same + // table twice on a query]. + wxArrayString *columnsAlias; + + // restrictions Panel + gqbRestrictions *restrictions; + + // order by Panel + // For left grid [available columns to order clause] + gqbObjsArray AvailableColumns; + gqbObjsArray ColumnAvailParent; + + // For right grid [used columns on order clause] + gqbObjsArray OrderedColumns; + gqbObjsArray ColumnOrdParent; + charArray orderBy; // D or A +}; +#endif diff --git a/include/gqb/gqbObject.h b/include/gqb/gqbObject.h new file mode 100644 index 0000000..fc143c3 --- /dev/null +++ b/include/gqb/gqbObject.h @@ -0,0 +1,68 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbObject.h - Main basic object used by GQB +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBOBJECT_H +#define GQBOBJECT_H + +enum type_gqbObject +{ + GQB_DATABASE, + GQB_SCHEMA, + GQB_TABLE, + GQB_VIEW, + GQB_COLUMN, + GQB_QUERYOBJ, + GQB_QUERY, + GQB_JOIN, + GQB_RESTRICTION +}; + +// Create Array Objects used as base for gqbCollections +class gqbObject : public wxTreeItemData +{ +public: + gqbObject(wxString name, wxTreeItemData *owner, pgConn *connection, OID oid = 0); + virtual ~gqbObject(); + const wxString &getName() + { + return Name; + } + wxTreeItemData *getOwner() + { + return Owner; + } + const type_gqbObject getType() + { + return Type; + } + void setType(const type_gqbObject type) + { + Type = type; + } + pgConn *getConnection() + { + return conn; + } + OID getOid() + { + return Oid; + } + +protected: + pgConn *conn; + +private: + wxString Name; + wxTreeItemData *Owner; + type_gqbObject Type; + OID Oid; +}; +#endif diff --git a/include/gqb/gqbObjectCollection.h b/include/gqb/gqbObjectCollection.h new file mode 100644 index 0000000..6617543 --- /dev/null +++ b/include/gqb/gqbObjectCollection.h @@ -0,0 +1,45 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbObjectCollection.h - A Collection of simple GQB objects +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBOBJECTCOLLECTION_H +#define GQBOBJECTCOLLECTION_H + +// App headers +#include "gqb/gqbObject.h" +#include "gqb/gqbCollection.h" +#include "gqb/gqbArrayCollection.h" + +// Create Collections of gqbObjects +class gqbObjectCollection : public gqbObject +{ +public: + gqbObjectCollection(wxString name, wxTreeItemData *owner, pgConn *connection, OID oid = 0); + virtual ~gqbObjectCollection(); + +protected: + void addObject(gqbObject *object); + void removeObject(gqbObject *object); + gqbIteratorBase *createIterator(); + gqbIteratorBase *createDownIterator(); + int countObjects(); + gqbObject *getObjectAtIndex(int index); + bool existsObject(gqbObject *object); + int indexObject(gqbObject *object); + void insertObjectAt(gqbObject *object, int index); + int getCount(); + void removeAll(); // Remove all objects from collection without deleting each one. + void deleteAll(); // Remove and Delete all objects from collection. + +private: + gqbCollection *objectsCollection; + gqbArrayCollection *implementation; // GQB-TODO: DEBO Eliminar esto (que gqbArrayCollection este dentro de la clase) pero como? +}; +#endif diff --git a/include/gqb/gqbQueryObjs.h b/include/gqb/gqbQueryObjs.h new file mode 100644 index 0000000..4116ab6 --- /dev/null +++ b/include/gqb/gqbQueryObjs.h @@ -0,0 +1,195 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbQueryObjs.h - All objects used by a model of a query in the MVC Pattern model. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBQUERYOBJS_H +#define GQBQUERYOBJS_H + +// wxWindows headers +#include +#include + +// App headers +#include "gqb/gqbTable.h" +#include "gqb/gqbColumn.h" +#include "gqb/gqbObjectCollection.h" + +#define MAXRECTANGLES 10 + +class gqbQueryObject; +class gqbQueryJoin; + +// GQB-TODO: Add all kinds of joins +enum type_Join +{ + _equally, + _lesser, + _greater, + _equlesser, + _equgreater + +}; + +// Collection of main Query Objects [Tables] +class gqbQueryObjs : public gqbObjectCollection +{ +public: + gqbQueryObjs(); // No destructor, the base destructor destroy collection + // the unique dynamic object in this class + void addTable(gqbQueryObject *mtable); // Uses alias to only allow operations I want to do it. + void removeTable(gqbQueryObject *mtable); + gqbIteratorBase *createQueryIterator(); + gqbIteratorBase *createDownQueryIterator(); + int tablesCount(); + void removeAllQueryObjs(); +}; + +// Collection of main Table Objects [Columns] have joins too but in a new variable +class gqbQueryObject : public gqbObjectCollection +{ +public: + gqbQueryObject(gqbTable *table); + ~gqbQueryObject(); + gqbTable *parent; + wxPoint position; + void setSelected(bool value); + bool getSelected(); + void setWidth(int value); + int getWidth(); + void setHeight(int value); + int getHeight(); + void removeColumn(gqbColumn *column); // Used only as synonym for gqbObjectCollection removeObject + void addColumn(gqbColumn *column); // Used only as synonym for gqbObjectCollection addObject + int getColumnIndex(gqbColumn *column); + bool existsColumn(gqbColumn *column); + gqbIteratorBase *createQueryTableIterator(); + gqbIteratorBase *createJoinsIterator(); + gqbIteratorBase *createRegJoinsIterator(); + gqbQueryJoin *addJoin(gqbQueryObject *owner, gqbQueryObject *observable, gqbColumn *source, gqbColumn *destination, type_Join kind); + void removeJoin(gqbQueryJoin *join, bool unRegister); + void registerJoin(gqbQueryJoin *join); + void unregisterJoin(gqbQueryJoin *join, bool removeIt); + bool getHaveJoins(); + bool getHaveRegJoins(); + void setAlias(wxString name) + { + alias = name; + }; + wxString getAlias() + { + return alias; + }; + +private: + bool selected; + wxString alias; + int width; + int height; + bool haveJoins, haveRegisteredJoins; + gqbCollection *joinsCollection, *registeredCollection; + gqbArrayCollection *implementationj, *implementationr ; + +}; + +// A Join Object +class gqbQueryJoin : public gqbObject +{ +public: + gqbQueryJoin(gqbQueryObject *_owner, gqbQueryObject *_destination, gqbColumn *sourceCol, gqbColumn *destCol, type_Join joinKind); + void setKindofJoin(type_Join join); + type_Join getKindofJoin(); + gqbQueryObject *getSourceQTable(); + gqbQueryObject *getDestQTable(); + gqbColumn *getDCol(); + gqbColumn *getSCol(); + wxString getSourceTable(); + wxString getDestTable(); + wxString getSourceCol(); + wxString getDestCol(); + void setSourceAnchor(wxPoint pt); + void setDestAnchor(wxPoint pt); + wxPoint &getSourceAnchor(); + wxPoint &getDestAnchor(); + void setSelected(bool value); + bool getSelected(); + void setAnchorsUsed(wxPoint pt); + wxPoint &getAnchorsUsed(); + +private: + bool selected; + type_Join kindofJoin; + gqbColumn *sCol, *dCol; + gqbQueryObject *owner, *destination; + wxPoint sAnchor, dAnchor; // The source/destination anchor points of the join (for same join) + wxPoint anchorsUsed; +}; + +// A Restriction Object +class gqbQueryRestriction : public gqbObject +{ +public: + gqbQueryRestriction(); + wxString &getLeft() + { + return leftPart; + }; + wxString &getRestriction() + { + return restriction; + }; + wxString &getValue_s() + { + return value_s; + }; + wxString &getConnector() + { + return connector; + }; + void setLeft(const wxString &value) + { + leftPart = value; + }; + void setRestriction(const wxString &value) + { + restriction = value; + }; + void setValue_s(const wxString &value) + { + value_s = value; + }; + void setConnector(const wxString &value) + { + connector = value; + }; + +private: + wxString leftPart; + wxString restriction; + wxString value_s; + wxString connector; +}; + +// Collection of restrictions for a where clause +class gqbRestrictions : public gqbObjectCollection +{ +public: + gqbRestrictions(); + ~gqbRestrictions(); + + void addRestriction(gqbQueryRestriction *r); + void removeRestriction(gqbQueryRestriction *r); + void deleteAllRestrictions(); + gqbIteratorBase *createRestrictionsIterator(); + void addRestrictionAt(gqbQueryRestriction *r, int index); + int restrictionsCount(); + gqbQueryRestriction *getRestrictionAt(int index); + +}; +#endif diff --git a/include/gqb/gqbSchema.h b/include/gqb/gqbSchema.h new file mode 100644 index 0000000..6e91b3d --- /dev/null +++ b/include/gqb/gqbSchema.h @@ -0,0 +1,28 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbSchema.h - Schema object for GQB +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBSCHEMA_H +#define GQBSCHEMA_H + +// App headers +#include "gqb/gqbObject.h" +#include "gqb/gqbTable.h" + +class gqbSchema : public gqbObject +{ +public: + gqbSchema(gqbObject *parent, wxString name, pgConn *connection, OID oid); + void createObjects(gqbBrowser *tablesBrowser, OID oidVal, wxTreeItemId parentNode, int tableImage, int viewImage, int xTableImage); + +private: + void createTables(gqbBrowser *tablesBrowser, wxTreeItemId parentNode, OID oidVal, int tableImage, int viewImage, int xTableImage); +}; +#endif diff --git a/include/gqb/gqbTable.h b/include/gqb/gqbTable.h new file mode 100644 index 0000000..a7e9342 --- /dev/null +++ b/include/gqb/gqbTable.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbTable.h - Table object for GQB +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBTABLE_H +#define GQBTABLE_H + +// App headers +#include "gqb/gqbObject.h" +#include "gqb/gqbBrowser.h" +#include "gqb/gqbObjectCollection.h" + +class gqbColumn; + +// Create Array Objects used as base for gqbCollections +class gqbTable : public gqbObjectCollection +{ +public: + gqbTable(gqbObject *parent, wxString name, pgConn *connection, type_gqbObject type, OID oid); + void createObjects(gqbBrowser *_tablesBrowser, pgConn *_conn, OID oidVal, wxTreeItemId parentNode); + gqbIteratorBase *createColumnsIterator(); + int countCols(); + gqbColumn *getColumnAtIndex(int index); + int indexColumn(gqbColumn *col); + +private: + void addColumn(gqbColumn *column); // Used only as synonym for gqbObjectCollection addObject + void createColumns(pgConn *conn, gqbBrowser *tablesBrowser, wxTreeItemId parentNode, OID oidVal); + +}; +#endif diff --git a/include/gqb/gqbViewController.h b/include/gqb/gqbViewController.h new file mode 100644 index 0000000..18734d0 --- /dev/null +++ b/include/gqb/gqbViewController.h @@ -0,0 +1,241 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbViewController.h - View and Controller implementation for MVC Pattern of GQB +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBCONTROLLER_H +#define GQBCONTROLLER_H + +#include +#include +#include +#include +#include +#include + +// App headers +#include "ctl/ctlAuiNotebook.h" +#include "gqb/gqbObject.h" +#include "gqb/gqbModel.h" +#include "gqb/gqbQueryObjs.h" +#include "gqb/gqbGraphBehavior.h" +#include "gqb/gqbColumn.h" +#include "gqb/gqbGridProjTable.h" +#include "gqb/gqbGridRestTable.h" +#include "gqb/gqbGridOrderTable.h" +#include "gqb/gqbGridJoinTable.h" +#include "gqb/gqbBrowser.h" + +#define GQB_MIN_WIDTH 1280 +#define GQB_MIN_HEIGHT 800 + +class gqbView; + +enum pointerMode +{ + pt_normal, + pt_join +}; + +// Utility Class to avoid a bug when the event sash resize is called +class gqbSplitter: public wxSplitterWindow +{ +public: + gqbSplitter(wxWindow *parent, wxWindowID id, const wxPoint &point, const wxSize &size, long style); + void setTablesBrowser(gqbBrowser *b) + { + tablesBrowser = b; + }; + void setBrowserPanel(wxPanel *p) + { + browserPanel = p; + }; + +private: + void onVerticalSashResize(wxSplitterEvent &event); + gqbBrowser *tablesBrowser; // tables Browser Tree + wxPanel *browserPanel; // Container of tables Browser Tree + DECLARE_EVENT_TABLE() +}; + +// This enum is useful to select particular page from the tabs +enum tabsIndex +{ + ti_colsGridPanel = 0, + ti_criteriaPanel, + ti_orderPanel, + ti_joinsPanel +}; + +class gqbController: public wxObject +{ +public: + gqbController(gqbModel *_model, wxWindow *gqbParent, ctlAuiNotebook *gridParent, wxSize size); + ~gqbController(); + gqbQueryObject *addTableToModel(gqbTable *table, wxPoint p); + gqbQueryJoin *addJoin(gqbQueryObject *sTable, gqbColumn *sColumn, gqbQueryObject *dTable, gqbColumn *dColumn, type_Join kind); + void removeJoin(gqbQueryJoin *join); + void removeTableFromModel(gqbQueryObject *table, gqbGridProjTable *gridTable, gqbGridOrderTable *orderLTable, gqbGridOrderTable *orderRTable); + void unsetModelSelected(bool queryTable); + void processColumnInModel(gqbQueryObject *table, gqbColumn *column, gqbGridProjTable *gridTable); + void setPointerMode(pointerMode pm); // Find selected table with their coordinates point + gqbView *getView() + { + return view; + }; + void nullView() + { + view = NULL; + }; + gqbObject *getModelSelected(wxPoint &pt, gqbQueryObject *lastSelected, gqbQueryJoin *lastJoinSelected, bool mark); + wxString generateSQL(); + wxSplitterWindow *getViewContainer() + { + return gqbMainContainer; + }; + wxSplitterWindow *getDialogParent() + { + return (wxSplitterWindow *) gqbContainer; + }; + void setSashVertPosition(int pos); + void setSashHorizPosition(int pos); + int getSashHorizPosition(); + gqbBrowser *getTablesBrowser() + { + return tablesBrowser; + }; + wxNotebook *getTabs() + { + return tabs; + }; + void emptyModel(); + void calcGridColsSizes(); + gqbQueryRestriction *addRestriction(); + int getTableCount() + { + return model->tablesCount(); + }; + +protected: + gqbView *view; // owned by caller application shouldn't be destroy by this class + wxWindow *pparent; // GQB-TODO: deberia ser privada no se porque no funciona [la estoy usando?] + gqbModel *model; // owned by caller application shouldn't be destroy by this class + wxNotebook *tabs; + gqbSplitter *gqbContainer; // container of canvas & tables browser. + wxSplitterWindow *gqbMainContainer; + gqbBrowser *tablesBrowser; // tables Browser Tree + wxPanel *browserPanel; // Container of tables Browser Tree +}; + +class gqbView: public wxScrolledWindow +{ +public: + gqbView(wxWindow *gqbParent, ctlAuiNotebook *gridParent, wxSize size, gqbController *controller, gqbModel *model); + ~gqbView(); + void SaveAsImage(const wxString &path, wxBitmapType imgType); + bool canSaveAsImage(); + void drawAll(wxMemoryDC &bdc, bool adjustScrolling); + void setPointerMode(pointerMode pm); + + // Events for wxScrolledWindow + void onPaint(wxPaintEvent &event); + void onMotion(wxMouseEvent &event); + void onDoubleClick(wxMouseEvent &event); + void onRightClick(wxMouseEvent &event); + void onErase(wxEraseEvent &event); + void onEraseBackGround(wxEraseEvent &event); + void OnKeyDown(wxKeyEvent &event); + void OnSize(wxSizeEvent &event); + wxPanel *getColsGridPanel() + { + return (wxPanel *)projectionPanel; + }; + wxPanel *getCriteriaPanel() + { + return (wxPanel *)criteriaPanel; + }; + wxPanel *getOrderPanel() + { + return (wxPanel *)orderPanel; + }; + wxPanel *getJoinsPanel() + { + return joinsPanel; + } + void newTableAdded(gqbQueryObject *item); + bool clickOnJoin (gqbQueryJoin *join, wxPoint &pt, wxPoint &origin, wxPoint &dest); + void updateTable(gqbQueryObject *table); + const wxSize &getModelSize() + { + return modelSize; + } + + // Functions for all gqb extra Panels (projection, criteria..) + void emptyPanelsData(); + + void updateModelSize(gqbQueryObject *obj, bool updateAnyWay); + +private: + gqbController *controller; // owned by caller application shouldn't be destroy + // by this class + gqbModel *model; // owned by caller application shouldn't be destroy + // by this class + gqbGraphBehavior *graphBehavior; // This points to the Graph behavior for objects, + // if change the way objects were draw changes too. + gqbIteratorBase *iterator; //include here for reuse of iterator, should be + // delete when class destroy + wxPanel *projectionPanel, *criteriaPanel, *orderPanel, *joinsPanel; + gqbGridProjTable *gridTable; // Data model for the columns grid internals + gqbGridRestTable *restrictionsGridTable; // Data model for restricions grid internals + gqbGridJoinTable *joinsGridTable; // Data model for joins grid internals + + gqbGridOrderTable *orderByLGridTable, *orderByRGridTable; // Data model for order by grid internals + wxSize canvasSize, modelSize; + bool changeTOpressed; + + // just a point to the selected item on the collection, shouldn't be destroy inside this class + gqbQueryObject *collectionSelected, *joinSource, *joinDest, *cTempSelected; + gqbQueryJoin *joinSelected, *jTempSelected; + gqbColumn *joinSCol, *joinDCol; + int pressed, selected, refreshRate; + wxPoint pos, jpos; // Position of the last event of the mouse & the first event of a join event + pointerMode mode; // pointer is used as normally or as in joins by example + wxImage joinCursorImage; + wxCursor joinCursor; + wxMenu *m_rightJoins, *m_rightTables, *m_gqbPopup; + void OnMenuJoinDelete(wxCommandEvent &event); + void OnMenuTableDelete(wxCommandEvent &event); + void OnMenuTableSetAlias(wxCommandEvent &event); + void OnRefresh(wxCommandEvent &ev); + + wxArrayString joinTypeChoices; + + DECLARE_EVENT_TABLE() +}; + +// A drop target that do nothing only accept text, if accept then tree add table to model +class DnDText : public wxTextDropTarget +{ +public: + DnDText(gqbBrowser *tablesBrowser) + { + tree = tablesBrowser; + } + virtual bool OnDropText(wxCoord x, wxCoord y, const wxString &text) + { + tree->setDnDPoint(x, y); + return true; + } + +private: + gqbBrowser *tree; +}; + +#endif + diff --git a/include/gqb/gqbViewPanels.h b/include/gqb/gqbViewPanels.h new file mode 100644 index 0000000..b54da72 --- /dev/null +++ b/include/gqb/gqbViewPanels.h @@ -0,0 +1,258 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbViewPanels.h - All panels used by GQB +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBVIEWPANELS_H +#define GQBVIEWPANELS_H + +#include + +// App headers +#include "gqb/gqbViewController.h" +#include "gqb/gqbGridProjTable.h" +#include "gqb/gqbGridRestTable.h" +#include "gqb/gqbGridOrderTable.h" +#include "gqb/gqbGridJoinTable.h" + +enum gridButtons +{ + GQB_COLS_UP_BUTTON_ID, + GQB_COLS_UP_TOP_BUTTON_ID, + GQB_COLS_DOWN_BUTTON_ID, + GQB_COLS_DOWN_BOTTOM_BUTTON_ID, + GQB_COLS_ADD_BUTTON_ID, + GQB_COLS_DROP_BUTTON_ID, + + GQB_JOIN_COLS_ADD_BUTTON_ID, + GQB_JOIN_COLS_DELETE_BUTTON_ID, + + GQB_ORDER_DROP_BUTTON_ID, + GQB_ORDER_DROP_ALL_BUTTON_ID, + GQB_ORDER_ADD_ALL_BUTTON_ID, + GQB_ORDER_ADD_BUTTON_ID, + GQB_ORDER_UP_BUTTON_ID, + GQB_ORDER_UP_TOP_BUTTON_ID, + GQB_ORDER_DOWN_BUTTON_ID, + GQB_ORDER_DOWN_BOTTOM_BUTTON_ID +}; + +// +// Projection Panel +// + +class gqbGridPanel: public wxPanel +{ +public: + gqbGridPanel(wxWindow *parent, wxWindowID id, gqbGridProjTable *gridModel); + ~gqbGridPanel(); + wxBitmapButton *buttonUp, *buttonDown, *buttonUpTop, *buttonDownBottom; + wxBitmap upBitmap, upTopBitmap, downBitmap, downBottomBitmap; + void SetGridColsSize(); + + // Events for wxGrid + void OnGridSelectCell( wxGridEvent &ev ); + void OnGridRangeSelected( wxGridRangeSelectEvent &ev ); + void OnButtonUp(wxCommandEvent &); + void OnButtonUpTop(wxCommandEvent &); + void OnButtonDown(wxCommandEvent &); + void OnButtonDownBottom(wxCommandEvent &); + +private: + bool allowSelCells; + int selTop, selBottom; // Range Selection of wxGrid, -1 it's value not set. + wxGrid *colsGrid; // Columns Grid used for order of columns in sentence & single row functions + gqbGridProjTable *gModel; + DECLARE_EVENT_TABLE() +}; + +// +// Panels reusable components +// + +class gqbColsTree : public wxTreeCtrl +{ +public: + gqbColsTree(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style); + wxTreeItemId &createRoot(wxString &Name); + wxTreeItemId &getRootNode() + { + return rootNode; + } + void refreshTree(gqbModel *model, gqbQueryObject *doNotInclude = NULL); + virtual void DeleteAllItems(); + ~gqbColsTree() + { + DeleteAllItems(); + } + +private: + wxTreeItemId rootNode; +}; + +enum +{ + QR_TREE_OK = 9100, + QR_TREE +}; + +class gqbColsPopUp: public wxDialog +{ +public: + gqbColsPopUp(wxWindow *parent, wxWindowID id, wxString title, wxPoint pos, const wxSize size); + virtual void refreshTree(gqbModel *_model); + void OnPopUpOKClick(wxCommandEvent &event); + void OnPopUpTreeClick(wxTreeEvent &event); + void OnPopUpTreeDoubleClick(wxTreeEvent &event); + void setEditText(wxString text); + wxString getEditText() + { + return editTree->GetValue(); + }; + void setUsedCell(wxGrid *grid, int row, int col) + { + usedGrid = grid; + _row = row; + _col = col; + }; + void focus(); + +protected: + int _row, _col; + wxGrid *usedGrid; + gqbColsTree *colsTree; + wxTextCtrl *editTree; + wxButton *buttonTree; + gqbModel *model; // Not owned shouldn't be deleted at this class + +}; + +class gqbJoinsPanel; + +class gqbJoinsPopUp: public gqbColsPopUp +{ +public: + gqbJoinsPopUp( + gqbJoinsPanel *parent, wxWindowID id, wxString title, wxPoint pos, + const wxSize size, gqbQueryJoin *_join, bool isSource, + gqbGridJoinTable *_gmodel); + void OnPopUpOKClick(wxCommandEvent &event); + void OnPopUpTreeClick(wxTreeEvent &event); + void OnPopUpTreeDoubleClick(wxTreeEvent &event); + + // This should be called through OnPopUpOKClick & OnPopUpTreeDoubleClick + void updateJoin(); + + virtual void refreshTree(gqbModel *_model); + +private: + gqbQueryJoin *join; // Not owned, shouldn't be deletedat this class + gqbQueryObject *selectedTbl; //Not owned, shouldn't be deletedat this class + gqbColumn *selectedCol; //Not owned, shouldn't be deletedat this class + bool isSource; + gqbGridJoinTable *gModel; //Not owned, shouldn't be deletedat this class +}; + +// +// Criterias Panel +// + +class gqbCustomGrid: public wxGrid +{ +public: + gqbCustomGrid(wxWindow *parent, wxWindowID id); + void ComboBoxEvent(wxGridEvent &event); + void RevertSel(); + +private: + wxGridSelection *m_selTemp; + +}; + +class gqbCriteriaPanel: public wxPanel +{ +public: + gqbCriteriaPanel(wxWindow *parent, gqbModel *_model, gqbGridRestTable *gridModel); + void OnCellLeftClick(wxGridEvent &ev); + void refreshTree(gqbModel *_model); + void OnButtonAdd(wxCommandEvent &); + void OnButtonDrop(wxCommandEvent &); + void SetGridColsSize(); + +private: + wxBitmapButton *buttonAdd, *buttonDrop; + wxBitmap addBitmap, dropBitmap; + void showColsPopUp(int row, int col, wxPoint pos); + gqbGridRestTable *gModel; + wxGrid *restrictionsGrid; // Columns Grid used for order of columns in sentence & single row functions + gqbModel *model; // Not owned shouldn't be deleted at this class + gqbColsPopUp *colsPopUp; + DECLARE_EVENT_TABLE() + +}; + +class gqbJoinsPanel: public wxPanel +{ +public: + gqbJoinsPanel(wxWindow *parent, gqbModel *_model, gqbGridJoinTable *_gmodel, gqbController *_controller); + void OnCellLeftClick(wxGridEvent &ev); + void refreshTree(gqbModel *_model); + void OnButtonAdd(wxCommandEvent &); + void OnButtonDrop(wxCommandEvent &); + void SetGridColsSize(); + void updateView(gqbQueryObject *tbl); + void selectJoin(gqbQueryJoin *join); + +private: + wxBitmapButton *buttonAdd, *buttonDrop; + wxBitmap addBitmap, dropBitmap; + void showColsPopUp(int row, int col, wxPoint pos); + gqbCustomGrid *joinsGrid; + gqbModel *model; // Not owned shouldn't be deleted at this class + gqbJoinsPopUp *joinsPopUp; // It will be automatically deleted + gqbGridJoinTable *gModel; // Not owned shouldn't be deleted at this class + gqbController *controller; // Not owned shouldn't be deleted at this class + DECLARE_EVENT_TABLE() + +}; + +// +// Order by Panel +// + +class gqbOrderPanel: public wxPanel +{ +public: + gqbOrderPanel(wxWindow *parent, gqbGridOrderTable *gridTableLeft, gqbGridOrderTable *gridTableRight); + void SetGridColsSize(); + +private: + bool allowSelCells; + void OnButtonUp(wxCommandEvent &); + void OnButtonUpTop(wxCommandEvent &); + void OnButtonDown(wxCommandEvent &); + void OnButtonDownBottom(wxCommandEvent &); + void OnButtonRemove(wxCommandEvent &); + void OnButtonRemoveAll(wxCommandEvent &); + void OnButtonAdd(wxCommandEvent &); + void OnButtonAddAll(wxCommandEvent &); + void OnGridSelectCell( wxGridEvent &ev ); + void OnGridRangeSelected( wxGridRangeSelectEvent &ev ); + void OnCellLeftClick(wxGridEvent &ev); + int selLeft, selRightTop, selRightBottom; + gqbGridOrderTable *tableLeft, *tableRight; + wxGrid *availableColumns, *usedColumns; + wxBitmapButton *buttonAdd, *buttonAddAll, *buttonRemove, *buttonRemoveAll; + wxBitmap addBitmap, addAllBitmap, removeBitmap, removeAllBitmap; + wxBitmapButton *buttonUp, *buttonDown, *buttonUpTop, *buttonDownBottom; + wxBitmap upBitmap, upTopBitmap, downBitmap, downBottomBitmap; + DECLARE_EVENT_TABLE() +}; +#endif + diff --git a/include/gqb/module.mk b/include/gqb/module.mk new file mode 100644 index 0000000..97e72ed --- /dev/null +++ b/include/gqb/module.mk @@ -0,0 +1,37 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/gqb/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/gqb/gqbArrayCollection.h \ + include/gqb/gqbBrowser.h \ + include/gqb/gqbCollection.h \ + include/gqb/gqbCollectionBase.h \ + include/gqb/gqbColumn.h \ + include/gqb/gqbDatabase.h \ + include/gqb/gqbEvents.h \ + include/gqb/gqbGraphBehavior.h \ + include/gqb/gqbGraphSimple.h \ + include/gqb/gqbGridOrderTable.h \ + include/gqb/gqbGridProjTable.h \ + include/gqb/gqbGridRestTable.h \ + include/gqb/gqbGridJoinTable.h \ + include/gqb/gqbModel.h \ + include/gqb/gqbObject.h \ + include/gqb/gqbObjectCollection.h \ + include/gqb/gqbQueryObjs.h \ + include/gqb/gqbSchema.h \ + include/gqb/gqbTable.h \ + include/gqb/gqbViewController.h \ + include/gqb/gqbViewPanels.h + +EXTRA_DIST += \ + include/gqb/module.mk + diff --git a/include/hotdraw/connectors/hdChopBoxConnector.h b/include/hotdraw/connectors/hdChopBoxConnector.h new file mode 100644 index 0000000..c4749a3 --- /dev/null +++ b/include/hotdraw/connectors/hdChopBoxConnector.h @@ -0,0 +1,33 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdChopBoxConnector.h - Connector for center of figure to line crossing one limit line of rect +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDCHOPBOXCONNECTOR_H +#define HDCHOPBOXCONNECTOR_H + + +#include "hotdraw/connectors/hdIConnector.h" +#include "hotdraw/figures/hdIFigure.h" + +class hdChopBoxConnector : public hdIConnector +{ +public: + hdChopBoxConnector(hdIFigure *owner); + ~hdChopBoxConnector(); + virtual hdPoint findStart(int posIdx, hdLineConnection *connFigure); + virtual hdPoint findEnd(int posIdx, hdLineConnection *connFigure); +protected: + virtual hdPoint chop(int posIdx, hdIFigure *target, hdPoint point); +private: + hdPoint point; + hdRect rect; + +}; +#endif diff --git a/include/hotdraw/connectors/hdIConnector.h b/include/hotdraw/connectors/hdIConnector.h new file mode 100644 index 0000000..49b36b9 --- /dev/null +++ b/include/hotdraw/connectors/hdIConnector.h @@ -0,0 +1,40 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdIConnector.cpp - Base class for all connectors +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDICONNECTOR_H +#define HDICONNECTOR_H + +#include "hotdraw/main/hdObject.h" +#include "hotdraw/figures/hdLineConnection.h" +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/utilities/hdRect.h" + +class hdLineConnection; +class hdIFigure; + +class hdIConnector : public hdObject +{ +public: + hdIConnector(hdIFigure *owner); + ~hdIConnector(); + virtual hdPoint findStart(int posIdx, hdLineConnection *connection); + virtual hdPoint findEnd(int posIdx, hdLineConnection *connection); + virtual bool containsPoint(int posIdx, int x, int y); + virtual void draw(wxBufferedDC &context); + virtual hdIFigure *getOwner(); + virtual hdMultiPosRect &getDisplayBox(); +protected: + virtual void setOwner(hdIFigure *owner); +private: + hdIFigure *figureOwner; + +}; +#endif diff --git a/include/hotdraw/connectors/hdLocatorConnector.h b/include/hotdraw/connectors/hdLocatorConnector.h new file mode 100644 index 0000000..1693725 --- /dev/null +++ b/include/hotdraw/connectors/hdLocatorConnector.h @@ -0,0 +1,40 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdLocatorConnector.h - class that puts connects at locator position +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDLOCATORCONNECTOR_H +#define HDLOCATORCONNECTOR_H + +#include "hotdraw/main/hdObject.h" +#include "hotdraw/figures/hdLineConnection.h" +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/locators/hdILocator.h" + +class hdLocatorConnector : public hdIConnector +{ +public: + hdLocatorConnector(hdIFigure *owner, hdILocator *locator); + ~hdLocatorConnector(); + virtual hdPoint findStart(int posIdx, hdLineConnection *connection); + virtual hdPoint findEnd(int posIdx, hdLineConnection *connection); + virtual bool containsPoint(int posIdx, int x, int y); + virtual void draw(wxBufferedDC &context); + virtual hdPoint locate(int posIdx); + virtual hdRect &getDisplayBox(int posIdx); +protected: + int size; //standard size connector + hdRect displayBox; +private: + hdILocator *figureLocator; + hdIFigure *figureOwner; + +}; +#endif diff --git a/include/hotdraw/connectors/hdStickyRectangleConnector.h b/include/hotdraw/connectors/hdStickyRectangleConnector.h new file mode 100644 index 0000000..378fff4 --- /dev/null +++ b/include/hotdraw/connectors/hdStickyRectangleConnector.h @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdAbstractFigure.h - A StickyRectangleConnector locates connection points by choping +// the connection between the centers of the two figures at the display box. The location +// of the connection point is computed once, when the user connects the figure. +// Moving the figure around will not change the location. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDSTICKYRECTANGLECONNECTOR_H +#define HDSTICKYRECTANGLECONNECTOR_H + +#include "hotdraw/main/hdObject.h" +#include "hotdraw/figures/hdLineConnection.h" +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/connectors/hdChopBoxConnector.h" + +class hdLineConnection; +class hdIFigure; + +class hdStickyRectangleConnector : public hdChopBoxConnector +{ +public: + hdStickyRectangleConnector(hdIFigure *owner, hdPoint p); + ~hdStickyRectangleConnector(); + virtual void setAngle(float newAngle); + virtual void updateAnchor(int posIdx, hdPoint p); + virtual hdPoint getAnchor(int posIdx); + virtual hdPoint chop(int posIdx, hdIFigure *target, hdPoint point); + virtual void draw(wxBufferedDC &context); +protected: + float angle; +private: + +}; +#endif diff --git a/include/hotdraw/connectors/module.mk b/include/hotdraw/connectors/module.mk new file mode 100644 index 0000000..c4d3ac0 --- /dev/null +++ b/include/hotdraw/connectors/module.mk @@ -0,0 +1,19 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/hotdraw/connectors/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/hotdraw/connectors/hdChopBoxConnector.h \ + include/hotdraw/connectors/hdIConnector.h \ + include/hotdraw/connectors/hdLocatorConnector.h \ + include/hotdraw/connectors/hdStickyRectangleConnector.h + +EXTRA_DIST += \ + include/hotdraw/connectors/module.mk diff --git a/include/hotdraw/figures/defaultAttributes/hdFillAttribute.h b/include/hotdraw/figures/defaultAttributes/hdFillAttribute.h new file mode 100644 index 0000000..e6e8db1 --- /dev/null +++ b/include/hotdraw/figures/defaultAttributes/hdFillAttribute.h @@ -0,0 +1,27 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdFillAttribute.h - Default attribute for fill color of figure +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDFILLCOLORATTRIBUTE_H +#define HDFILLCOLORATTRIBUTE_H + +#include "hotdraw/figures/hdAttribute.h" + +class hdFillAttribute : public hdAttribute +{ +public: + hdFillAttribute(); + virtual void callDefaultChangeDialog(wxWindow *owner = NULL); + virtual void apply(wxBufferedDC &context); + wxBrush &brush(); +protected: + wxBrush fillAttributes; +}; +#endif diff --git a/include/hotdraw/figures/defaultAttributes/hdFontAttribute.h b/include/hotdraw/figures/defaultAttributes/hdFontAttribute.h new file mode 100644 index 0000000..053240c --- /dev/null +++ b/include/hotdraw/figures/defaultAttributes/hdFontAttribute.h @@ -0,0 +1,29 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdFontAttribute.h - Default attribute for attributes of fonts +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDFONTATTRIBUTE_H +#define HDFONTATTRIBUTE_H + +#include "hotdraw/figures/hdAttribute.h" + +class hdFontAttribute : public hdAttribute +{ +public: + hdFontAttribute(); + virtual void callDefaultChangeDialog(wxWindow *owner = NULL); + virtual void apply(wxBufferedDC &context); + wxFont &font(); + static wxFont *defaultFont; + static void InitFont(); +protected: + wxFont fontAttributes; +}; +#endif diff --git a/include/hotdraw/figures/defaultAttributes/hdFontColorAttribute.h b/include/hotdraw/figures/defaultAttributes/hdFontColorAttribute.h new file mode 100644 index 0000000..74fc35d --- /dev/null +++ b/include/hotdraw/figures/defaultAttributes/hdFontColorAttribute.h @@ -0,0 +1,29 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdFontAttribute.cpp - Default attribute for color of fonts +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDFONTCOLORATTRIBUTE_H +#define HDFONTCOLORATTRIBUTE_H + +#include "hotdraw/figures/hdAttribute.h" + +class hdFontColorAttribute : public hdAttribute +{ +public: + hdFontColorAttribute(); + virtual void callDefaultChangeDialog(wxWindow *owner = NULL); + virtual void apply(wxBufferedDC &context); +// void setFontColorAttribute(wxColour color); + wxColour fontColor; +protected: + + +}; +#endif diff --git a/include/hotdraw/figures/defaultAttributes/hdLineAttribute.h b/include/hotdraw/figures/defaultAttributes/hdLineAttribute.h new file mode 100644 index 0000000..f339c24 --- /dev/null +++ b/include/hotdraw/figures/defaultAttributes/hdLineAttribute.h @@ -0,0 +1,27 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdLineAttribute.h - Default Attribute for lines style, color an others at figure +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDLINECOLORATTRIBUTE_H +#define HDLINECOLORATTRIBUTE_H + +#include "hotdraw/figures/hdAttribute.h" + +class hdLineAttribute : public hdAttribute +{ +public: + hdLineAttribute(); + virtual void callDefaultChangeDialog(wxWindow *owner = NULL); + virtual void apply(wxBufferedDC &context); + wxPen &pen(); +protected: + wxPen penAttributes; +}; +#endif diff --git a/include/hotdraw/figures/defaultAttributes/module.mk b/include/hotdraw/figures/defaultAttributes/module.mk new file mode 100644 index 0000000..6ede488 --- /dev/null +++ b/include/hotdraw/figures/defaultAttributes/module.mk @@ -0,0 +1,19 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/hotdraw/figures/defaultAttributes Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/hotdraw/figures/defaultAttributes/hdFillAttribute.h \ + include/hotdraw/figures/defaultAttributes/hdFontAttribute.h \ + include/hotdraw/figures/defaultAttributes/hdFontColorAttribute.h \ + include/hotdraw/figures/defaultAttributes/hdLineAttribute.h + +EXTRA_DIST += \ + include/hotdraw/figures/defaultAttributes/module.mk diff --git a/include/hotdraw/figures/hdAbstractFigure.h b/include/hotdraw/figures/hdAbstractFigure.h new file mode 100644 index 0000000..dac9502 --- /dev/null +++ b/include/hotdraw/figures/hdAbstractFigure.h @@ -0,0 +1,50 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdAbstractFigure.h - Base class for all figures +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDABSTRACTFIGURE_H +#define HDABSTRACTFIGURE_H +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/figures/hdIFigure.h" +#include "hotdraw/tools/hdITool.h" +#include "hotdraw/handles/hdIHandle.h" +#include "hotdraw/utilities/hdCollection.h" + +class hdAbstractFigure : public hdIFigure +{ +public: + hdAbstractFigure(); + ~hdAbstractFigure(); + + virtual bool canConnect (); + virtual void draw(wxBufferedDC &context, hdDrawingView *view); + virtual void drawSelected(wxBufferedDC &context, hdDrawingView *view); + virtual bool includes(hdIFigure *figure); + virtual hdITool *CreateFigureTool(hdDrawingView *view, hdITool *defaultTool); + virtual void moveBy(int posIdx, int x, int y); + virtual void basicMoveBy(int posIdx, int x, int y); + virtual void moveTo(int posIdx, int x, int y); + virtual bool containsPoint(int posIdx, int x, int y); + virtual void onFigureChanged(int posIdx, hdIFigure *figure); + +protected: + virtual void basicDraw(wxBufferedDC &context, hdDrawingView *view); + virtual void basicDrawSelected(wxBufferedDC &context, hdDrawingView *view); + void willChange(); + void changed(int posIdx); + void invalidate(); + wxColour fillColor, lineColor; + double lineWidth; + wxSize spaceForMovement; + +private: + +}; +#endif diff --git a/include/hotdraw/figures/hdAbstractMenuFigure.h b/include/hotdraw/figures/hdAbstractMenuFigure.h new file mode 100644 index 0000000..24ebe65 --- /dev/null +++ b/include/hotdraw/figures/hdAbstractMenuFigure.h @@ -0,0 +1,37 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdAbstractMenuFigure.h - Base class for figures that show a menu with right click +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDABSTRACTMENUFIGURE_H +#define HDABSTRACTMENUFIGURE_H +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/figures/hdAttributeFigure.h" +#include "hotdraw/tools/hdITool.h" +#include "hotdraw/handles/hdIHandle.h" +#include "hotdraw/utilities/hdCollection.h" + +class hdAbstractMenuFigure : public hdAttributeFigure +{ +public: + hdAbstractMenuFigure(); + ~hdAbstractMenuFigure(); + virtual hdITool *CreateFigureTool(hdDrawingView *view, hdITool *defaultTool); + virtual void createMenu(wxMenu &mnu) {} + virtual void enablePopUp(); + virtual void disablePopUp(); + virtual bool menuEnabled(); + virtual void OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view = NULL); +protected: + wxArrayString strings; + bool showMenu; +private: + +}; +#endif diff --git a/include/hotdraw/figures/hdAttribute.h b/include/hotdraw/figures/hdAttribute.h new file mode 100644 index 0000000..374c468 --- /dev/null +++ b/include/hotdraw/figures/hdAttribute.h @@ -0,0 +1,23 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdAbstractFigure.h - Base class for all figures with attributes (line size, fonts and others) +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDATTRIBUTE_H +#define HDATTRIBUTE_H +#include "hotdraw/main/hdObject.h" + +class hdAttribute : public hdObject +{ +public: + hdAttribute(); + virtual void callDefaultChangeDialog(wxWindow *owner = NULL); + virtual void apply(wxBufferedDC &context); +}; +#endif diff --git a/include/hotdraw/figures/hdAttributeFigure.h b/include/hotdraw/figures/hdAttributeFigure.h new file mode 100644 index 0000000..ff37ff1 --- /dev/null +++ b/include/hotdraw/figures/hdAttributeFigure.h @@ -0,0 +1,55 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdAbstractFigure.h - Base class for all figures with attributes (line size, fonts and others) +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDATTRIBUTEFIGURE_H +#define HDATTRIBUTEFIGURE_H + +// wxWindows headers +#include "hotdraw/figures/hdAbstractFigure.h" +#include "hotdraw/figures/hdAttribute.h" +#include "hotdraw/main/hdObject.h" +#include + +// App headers +#include "hotdraw/figures/defaultAttributes/hdFillAttribute.h" +#include "hotdraw/figures/defaultAttributes/hdFontAttribute.h" +#include "hotdraw/figures/defaultAttributes/hdFontColorAttribute.h" +#include "hotdraw/figures/defaultAttributes/hdLineAttribute.h" + +class hdAttributeFigure : public hdAbstractFigure +{ +public: + hdAttributeFigure(); + ~hdAttributeFigure(); + + void draw(wxBufferedDC &context, hdDrawingView *view); + void drawSelected(wxBufferedDC &context, hdDrawingView *view); + void reapplyAttributes(wxBufferedDC &context, hdDrawingView *view); + void reapplySelAttributes(wxBufferedDC &context, hdDrawingView *view); + + void initializeDefaultAttributes(); + + //Draw attributes + hdFontAttribute *fontAttribute; + hdFontColorAttribute *fontColorAttribute; + hdFillAttribute *fillAttribute; + hdLineAttribute *lineAttribute; + //Draw selected attributes + hdFontAttribute *fontSelAttribute; + hdFontColorAttribute *fontSelColorAttribute; + hdFillAttribute *fillSelAttribute; + hdLineAttribute *lineSelAttribute; +protected: + +private: + +}; +#endif diff --git a/include/hotdraw/figures/hdBitmapFigure.h b/include/hotdraw/figures/hdBitmapFigure.h new file mode 100644 index 0000000..9d0e3a4 --- /dev/null +++ b/include/hotdraw/figures/hdBitmapFigure.h @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdCompositeFigure.h - Figure that draw a bitmap +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDBITMAPFIGURE_H +#define HDBITMAPFIGURE_H + +#include "hotdraw/figures/hdAbstractFigure.h" + +class hdBitmapFigure : public hdAbstractFigure +{ +public: + hdBitmapFigure(wxBitmap image); + ~hdBitmapFigure(); + + virtual void basicDraw(wxBufferedDC &context, hdDrawingView *view); + virtual void basicDrawSelected(wxBufferedDC &context, hdDrawingView *view); + virtual void changeBitmap(wxBitmap image); + virtual int getWidth(); + virtual int getHeight(); + +protected: + +private: + wxBitmap imageToDraw; +}; +#endif diff --git a/include/hotdraw/figures/hdCompositeFigure.h b/include/hotdraw/figures/hdCompositeFigure.h new file mode 100644 index 0000000..874d65d --- /dev/null +++ b/include/hotdraw/figures/hdCompositeFigure.h @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdCompositeFigure.h - Base class for all figures composite with figures +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDCOMPOSITEFIGURE_H +#define HDCOMPOSITEFIGURE_H +#include "hotdraw/figures/hdAttributeFigure.h" + +class hdCompositeFigure : public hdAttributeFigure +{ +public: + hdCompositeFigure(); + ~hdCompositeFigure(); + virtual void AddPosForNewDiagram(); + virtual void RemovePosOfDiagram(int posIdx); + virtual void basicMoveBy(int posIdx, int x, int y); + virtual bool containsPoint(int posIdx, int x, int y); + virtual hdIteratorBase *figuresEnumerator(); + virtual hdIteratorBase *figuresInverseEnumerator(); + virtual hdMultiPosRect &getBasicDisplayBox(); + virtual hdCollection *handlesEnumerator(); + virtual void add(hdIFigure *figure); + virtual void remove(hdIFigure *figure); + virtual bool includes(hdIFigure *figure); + virtual hdIFigure *findFigure(int posIdx, int x, int y); + virtual hdIFigure *getFigureAt(int indexOfCollection); + virtual hdITool *CreateFigureTool(hdDrawingView *view, hdITool *defaultTool); +protected: + virtual void basicDraw(wxBufferedDC &context, hdDrawingView *view); + virtual void basicDrawSelected(wxBufferedDC &context, hdDrawingView *view); + hdCollection *figureFigures; + hdCollection *figureHandles; + +private: + +}; +#endif diff --git a/include/hotdraw/figures/hdIConnectionFigure.h b/include/hotdraw/figures/hdIConnectionFigure.h new file mode 100644 index 0000000..9081029 --- /dev/null +++ b/include/hotdraw/figures/hdIConnectionFigure.h @@ -0,0 +1,55 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdIConnectionFigure.h - Base class for all connection figures +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDICONNECTIONFIGURE_H +#define HDICONNECTIONFIGURE_H +#include "hotdraw/figures/hdIFigure.h" +#include "hotdraw/connectors/hdIConnector.h" +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/handles/hdIHandle.h" + + +class hdIConnector; + +class hdIConnectionFigure : public hdIFigure +{ +public: + + virtual void connectStart(hdIConnector *start) = 0; + virtual void connectEnd(hdIConnector *end) = 0; + virtual void updateConnection() = 0; + virtual void disconnectStart() = 0; + virtual void disconnectEnd() = 0; + virtual bool canConnectStart(hdIFigure *figure) = 0; + virtual bool canConnectEnd(hdIFigure *figure) = 0; + virtual hdPoint *pointAt(int index) = 0; + virtual void splitSegment(int x, int y) = 0; + + virtual int pointCount() = 0; + virtual hdIConnector *getStartConnector() = 0; + virtual hdIConnector *getEndConnector() = 0; + virtual void setStartConnector(hdIConnector *connector) = 0; + virtual void setEndConnector(hdIConnector *connector) = 0; + virtual hdPoint *getStartPoint() = 0; + virtual void setStartPoint(hdPoint *point) = 0; + virtual hdPoint *getEndPoint() = 0; + virtual void setEndPoint(hdPoint *point) = 0; + virtual hdIFigure *getStartFigure() = 0; + virtual hdIFigure *getEndFigure() = 0; + virtual hdIHandle *getStartHandle() = 0; + virtual hdIHandle *getEndHandle() = 0; + +protected: + +private: + +}; +#endif diff --git a/include/hotdraw/figures/hdIFigure.h b/include/hotdraw/figures/hdIFigure.h new file mode 100644 index 0000000..aae6ddb --- /dev/null +++ b/include/hotdraw/figures/hdIFigure.h @@ -0,0 +1,69 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdIFigure.h - Base class for all figures +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDIFIGURE_H +#define HDIFIGURE_H +#include "hotdraw/utilities/hdMultiPosRect.h" +#include "hotdraw/main/hdObject.h" +#include "hotdraw/utilities/hdCollection.h" +#include "hotdraw/handles/hdIHandle.h" +#include "hotdraw/utilities/hdMultiPosRect.h" + +class hdITool; +class hdDrawingEditor; +class hdIConnector; +class hdITool; + +WX_DEFINE_ARRAY_INT(bool, wxArrayBool); + +class hdIFigure : public hdObject +{ +public: + hdIFigure(); + ~hdIFigure(); + + virtual hdMultiPosRect &displayBox(); + virtual hdMultiPosRect &getBasicDisplayBox(); + virtual void AddPosForNewDiagram(); + virtual void RemovePosOfDiagram(int posIdx); + virtual void draw (wxBufferedDC &context, hdDrawingView *view); + virtual void drawSelected (wxBufferedDC &context, hdDrawingView *view); + virtual hdCollection *handlesEnumerator(); + virtual void addHandle (hdIHandle *handle); + virtual void removeHandle (hdIHandle *handle); + virtual hdIConnector *connectorAt (int posIdx, int x, int y); + virtual void moveBy(int posIdx, int x, int y) = 0; + virtual void moveTo(int posIdx, int x, int y) = 0; + virtual bool containsPoint(int posIdx, int x, int y) = 0; + virtual bool isSelected(int posIdx); + virtual void setSelected(int posIdx, bool value); + virtual bool includes(hdIFigure *figure); + virtual bool canConnect() = 0; + virtual void onFigureChanged(int posIdx, hdIFigure *figure) = 0; + virtual void addObserver (hdIFigure *observer); + virtual void removeObserver (hdIFigure *observer); + virtual hdIteratorBase *observersEnumerator(); + virtual void setKindId(int objectId = -1); + virtual int getKindId(); + virtual hdITool *CreateFigureTool(hdDrawingView *view, hdITool *defaultTool); + +protected: + hdMultiPosRect basicDisplayBox; + hdCollection *handles; + hdCollection *observers; + hdIConnector *connector; +private: + //bool selected; + wxArrayBool selected; + int kindHiddenId; + +}; +#endif diff --git a/include/hotdraw/figures/hdLineConnection.h b/include/hotdraw/figures/hdLineConnection.h new file mode 100644 index 0000000..b974f0f --- /dev/null +++ b/include/hotdraw/figures/hdLineConnection.h @@ -0,0 +1,62 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdLineConnection.h - Base class for line connection figure +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDLINECONNECTION_H +#define HDLINECONNECTION_H +#include "hotdraw/figures/hdPolyLineFigure.h" +#include "hotdraw/connectors/hdIConnector.h" +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/handles/hdIHandle.h" + +class hdLineConnection : public hdPolyLineFigure +{ +public: + hdLineConnection(); + hdLineConnection(int posIdx, hdIFigure *figure1, hdIFigure *figure2); + ~hdLineConnection(); + + virtual void connectStart(hdIConnector *start, hdDrawingView *view = NULL); + virtual void connectEnd(hdIConnector *end, hdDrawingView *view = NULL); + virtual void disconnectStart(hdDrawingView *view = NULL); + virtual void disconnectEnd(hdDrawingView *view = NULL); + virtual void updateConnection(int posIdx); + virtual bool canConnectStart(hdIFigure *figure); + virtual bool canConnectEnd(hdIFigure *figure); + virtual bool canConnect(); + virtual void setPointAt (int posIdx, int index, int x, int y); + virtual hdCollection *handlesEnumerator(); + virtual void basicMoveBy(int posIdx, int x, int y); + + virtual void onFigureChanged(int posIdx, hdIFigure *figure); + + virtual hdIConnector *getStartConnector(); + virtual hdIConnector *getEndConnector(); + virtual void setStartConnector(hdIConnector *connector); + virtual void setEndConnector(hdIConnector *connector); + virtual hdIFigure *getStartFigure(); + virtual hdIFigure *getEndFigure(); + virtual hdIHandle *getStartHandle(); + virtual hdIHandle *getEndHandle(); + virtual void addPoint (int posIdx, int x, int y); + virtual void insertPointAt (int posIdx, int index, int x, int y); + +protected: + virtual void updateHandlesIndexes(); + virtual void connectFigure (hdIConnector *connector); + virtual void disconnectFigure (hdIConnector *connector); + hdIConnector *startConnector; + hdIConnector *endConnector; + +private: + hdIHandle *changeConnStartHandle; + hdIHandle *changeConnEndHandle; +}; +#endif diff --git a/include/hotdraw/figures/hdLineTerminal.h b/include/hotdraw/figures/hdLineTerminal.h new file mode 100644 index 0000000..fb45918 --- /dev/null +++ b/include/hotdraw/figures/hdLineTerminal.h @@ -0,0 +1,31 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdLineTerminal.h - Base class for line terminal figure +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDLINETERMINAL_H +#define HDLINETERMINAL_H +#include "hotdraw/figures/hdIFigure.h" +#include "hotdraw/utilities/hdPoint.h" + +class hdLineTerminal : public hdObject +{ +public: + hdLineTerminal(); + ~hdLineTerminal(); + + virtual hdPoint &draw (wxBufferedDC &context, hdPoint &a, hdPoint &b, hdDrawingView *view); + virtual void setLinePen(wxPen pen); +protected: + wxPen terminalLinePen; +private: + hdPoint middle; + +}; +#endif diff --git a/include/hotdraw/figures/hdPolyLineFigure.h b/include/hotdraw/figures/hdPolyLineFigure.h new file mode 100644 index 0000000..3c5f14a --- /dev/null +++ b/include/hotdraw/figures/hdPolyLineFigure.h @@ -0,0 +1,75 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdPolyLineFigure.h - A simple line figure that can be split on several lines joined by flexibility points +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDPOLYLINEFIGURE_H +#define HDPOLYLINEFIGURE_H + +#include "hotdraw/figures/hdAbstractMenuFigure.h" +#include "hotdraw/figures/hdLineTerminal.h" +#include "hotdraw/utilities/hdArrayCollection.h" +#include "hotdraw/utilities/hdPoint.h" + + +WX_DEFINE_ARRAY(hdArrayCollection *, pointsCollections); + +class hdPolyLineFigure : public hdAbstractMenuFigure +{ +public: + hdPolyLineFigure(); + ~hdPolyLineFigure(); + + virtual hdMultiPosRect &getBasicDisplayBox(); + virtual int pointCount(int posIdx); + virtual int pointLinesCount(); + virtual void AddPosForNewDiagram(); + virtual void RemovePosOfDiagram(int posIdx); + virtual hdPoint &getStartPoint(int posIdx); + virtual void setStartPoint(int posIdx, hdPoint point); + virtual hdPoint &getEndPoint(int posIdx); + virtual void setEndPoint(int posIdx, hdPoint point); + virtual void setStartTerminal(hdLineTerminal *terminal); + virtual hdLineTerminal *getStartTerminal(); + virtual void setEndTerminal(hdLineTerminal *terminal); + virtual hdLineTerminal *getEndTerminal(); + hdCollection *handlesEnumerator(); + virtual int findSegment (int posIdx, int x, int y); + virtual void splitSegment(int posIdx, int x, int y); + virtual void changed(int posIdx); + + virtual void addPoint (int posIdx, int x, int y); + virtual void clearPoints (int posIdx); + virtual void insertPointAt (int posIdx, int index, int x, int y); + virtual void setPointAt (int posIdx, int index, int x, int y); + virtual void removePointAt (int posIdx, int index); + virtual void basicMoveBy(int posIdx, int x, int y); + virtual hdITool *CreateFigureTool(hdDrawingView *view, hdITool *defaultTool); + + virtual hdPoint &pointAt(int posIdx, int index); + virtual bool containsPoint (int posIdx, int x, int y); + virtual void setLinePen(wxPen pen); + int countPointsAt(int posIdx); + +protected: + virtual void basicDraw (wxBufferedDC &context, hdDrawingView *view); + virtual void basicDrawSelected(wxBufferedDC &context, hdDrawingView *view); + + int getMaximunIndex(); + virtual void updateHandlesIndexes(); + pointsCollections points; + hdPoint endPoint, startPoint, pointAtPos; + +private: + hdLineTerminal *startTerminal, *endTerminal; + bool handlesChanged; + wxPen linePen; + +}; +#endif diff --git a/include/hotdraw/figures/hdRectangleFigure.h b/include/hotdraw/figures/hdRectangleFigure.h new file mode 100644 index 0000000..3272d0d --- /dev/null +++ b/include/hotdraw/figures/hdRectangleFigure.h @@ -0,0 +1,35 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdRectangleFigure.h - A simple rectangle figure +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDRECTANGLEFIGURE_H +#define HDRECTANGLEFIGURE_H + +#include + +#include "hotdraw/figures/hdAbstractFigure.h" + + +class hdDrawingView; + +class hdRectangleFigure : public hdAbstractFigure +{ +public: + hdRectangleFigure(); + ~hdRectangleFigure(); + void basicDraw(wxBufferedDC &context, hdDrawingView *view); + void basicDrawSelected(wxBufferedDC &context, hdDrawingView *view); + void setRectangle(hdMultiPosRect &rect); + void setSize(wxSize &size); + +protected: +private: +}; +#endif diff --git a/include/hotdraw/figures/hdSimpleTextFigure.h b/include/hotdraw/figures/hdSimpleTextFigure.h new file mode 100644 index 0000000..0a9a3dd --- /dev/null +++ b/include/hotdraw/figures/hdSimpleTextFigure.h @@ -0,0 +1,50 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdSimpleTextFigure.h - A simple rectangle figure with text inside it +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDSIMPLETEXTFIGURE_H +#define HDSIMPLETEXTFIGURE_H +#include "hotdraw/figures/hdAttributeFigure.h" + +class hdDrawingView; + +class hdSimpleTextFigure : public hdAttributeFigure +{ +public: + hdSimpleTextFigure(wxString textString); + ~hdSimpleTextFigure(); + virtual void setText(wxString textString); + virtual wxString &getText(bool extended = false); + virtual void setEditable(bool value); + virtual bool getEditable(); + virtual void setFont(wxFont textFont); + virtual int getPadding(); + void basicMoveBy(int posIdx, int x, int y); + virtual void basicDraw(wxBufferedDC &context, hdDrawingView *view); + virtual void basicDrawSelected(wxBufferedDC &context, hdDrawingView *view); + virtual hdITool *CreateFigureTool(hdDrawingView *view, hdITool *defaultTool); + virtual void createMenu(wxMenu &mnu) {} + virtual void enablePopUp(); + virtual void disablePopUp(); + virtual bool menuEnabled(); + virtual void OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view); +protected: + virtual void getFontMetrics(int &width, int &height); + virtual void recalculateDisplayBox(); + wxArrayString strings; + bool showMenu; + bool textEditable; +private: + int padding; + wxString text; + wxFont font; + +}; +#endif diff --git a/include/hotdraw/figures/module.mk b/include/hotdraw/figures/module.mk new file mode 100644 index 0000000..bc1d840 --- /dev/null +++ b/include/hotdraw/figures/module.mk @@ -0,0 +1,31 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/hotdraw/figures/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/hotdraw/figures/hdAbstractFigure.h \ + include/hotdraw/figures/hdAbstractMenuFigure.h \ + include/hotdraw/figures/hdAttribute.h \ + include/hotdraw/figures/hdAttributeFigure.h \ + include/hotdraw/figures/hdBitmapFigure.h \ + include/hotdraw/figures/hdCompositeFigure.h \ + include/hotdraw/figures/hdIConnectionFigure.h \ + include/hotdraw/figures/hdIFigure.h \ + include/hotdraw/figures/hdLineConnection.h \ + include/hotdraw/figures/hdLineTerminal.h \ + include/hotdraw/figures/hdPolyLineFigure.h \ + include/hotdraw/figures/hdRectangleFigure.h \ + include/hotdraw/figures/hdSimpleTextFigure.h + +EXTRA_DIST += \ + include/hotdraw/figures/module.mk + +include include/hotdraw/figures/defaultAttributes/module.mk +include include/hotdraw/figures/xml/module.mk diff --git a/include/hotdraw/figures/xml/hdStorage.h b/include/hotdraw/figures/xml/hdStorage.h new file mode 100644 index 0000000..8593ab9 --- /dev/null +++ b/include/hotdraw/figures/xml/hdStorage.h @@ -0,0 +1,25 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdAbstractFigure.h - Base class for all figures with attributes (line size, fonts and others) +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDSTORAGE_H +#define HDSTORAGE_H + +#include "hotdraw/main/hdObject.h" +#include "hotdraw/figures/hdIFigure.h" + +class hdStorage : public hdObject +{ +public: + hdStorage(); + static bool Read(xmlTextReaderPtr reader); + static bool Write(xmlTextWriterPtr writer, hdIFigure *figure); +}; +#endif diff --git a/include/hotdraw/figures/xml/module.mk b/include/hotdraw/figures/xml/module.mk new file mode 100644 index 0000000..d21f8f8 --- /dev/null +++ b/include/hotdraw/figures/xml/module.mk @@ -0,0 +1,16 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/hotdraw/figures/xml Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/hotdraw/figures/xml/hdStorage.h + +EXTRA_DIST += \ + include/hotdraw/figures/xml/module.mk diff --git a/include/hotdraw/handles/hdButtonHandle.h b/include/hotdraw/handles/hdButtonHandle.h new file mode 100644 index 0000000..417b3a3 --- /dev/null +++ b/include/hotdraw/handles/hdButtonHandle.h @@ -0,0 +1,41 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdButtonHandle.h - Handle to allow creation of buttons at figures +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDBUTTONHANDLE_H +#define HDBUTTONHANDLE_H + +#include "hotdraw/handles/hdIHandle.h" +#include "hotdraw/handles/hdLocatorHandle.h" +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/utilities/hdPoint.h" + +class hdButtonHandle : public hdIHandle +{ +public: + hdButtonHandle(hdIFigure *owner, hdILocator *buttonLocator , wxBitmap &buttonImage, wxSize &size); + ~hdButtonHandle(); + + virtual wxCursor createCursor(); + virtual hdRect &getDisplayBox(int posIdx); + virtual void draw(wxBufferedDC &context, hdDrawingView *view); + virtual hdPoint &locate(int posIdx); + virtual void invokeStart(hdMouseEvent &event, hdDrawingView *view) = 0; + virtual void invokeStep(hdMouseEvent &event, hdDrawingView *view) = 0; + virtual void invokeEnd(hdMouseEvent &event, hdDrawingView *view) = 0; +protected: + wxBitmap buttonIcon; +private: + bool clicked; + hdILocator *bLocator; + hdPoint pointLocate; + +}; +#endif diff --git a/include/hotdraw/handles/hdChangeConnectionEndHandle.h b/include/hotdraw/handles/hdChangeConnectionEndHandle.h new file mode 100644 index 0000000..099375d --- /dev/null +++ b/include/hotdraw/handles/hdChangeConnectionEndHandle.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdChangeConnectionEndHandle.h - Handle to allow change connected figure at end of connection figure +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDCHANGECONNECTIONENDHANDLE_H +#define HDCHANGECONNECTIONENDHANDLE_H + +#include "hotdraw/handles/hdChangeConnectionHandle.h" +#include "hotdraw/figures/hdLineConnection.h" + +class hdChangeConnectionEndHandle : public hdChangeConnectionHandle +{ +public: + hdChangeConnectionEndHandle(hdLineConnection *owner); + ~hdChangeConnectionEndHandle(); + virtual hdPoint &locate(int posIdx); + virtual hdIConnector *target(); + virtual void disconnect(hdDrawingView *view = NULL); + virtual void connect(hdIConnector *connector, hdDrawingView *view = NULL); + virtual bool isConnectionPossible(hdIFigure *figure); + virtual void setPoint(int posIdx, hdPoint p); +}; +#endif diff --git a/include/hotdraw/handles/hdChangeConnectionHandle.h b/include/hotdraw/handles/hdChangeConnectionHandle.h new file mode 100644 index 0000000..aa1f2d8 --- /dev/null +++ b/include/hotdraw/handles/hdChangeConnectionHandle.h @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdChangeConnectionHandle.h - Base Handle to allow change connected figures at connection figures +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDCHANGECONNECTIONHANDLE_H +#define HDCHANGECONNECTIONHANDLE_H + +#include "hotdraw/handles/hdIHandle.h" +#include "hotdraw/figures/hdLineConnection.h" +#include "hotdraw/connectors/hdIConnector.h" +#include "hotdraw/main/hdDrawing.h" + +class hdChangeConnectionHandle : public hdIHandle +{ +public: + hdChangeConnectionHandle(hdLineConnection *owner); + ~hdChangeConnectionHandle(); + + virtual void draw(wxBufferedDC &context, hdDrawingView *view); + virtual wxCursor createCursor(); + virtual void invokeStart(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeStep(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeEnd(hdMouseEvent &event, hdDrawingView *view); + virtual hdIConnector *target() = 0; + virtual void disconnect(hdDrawingView *view = NULL) = 0; + virtual void connect(hdIConnector *connector, hdDrawingView *view = NULL) = 0; + virtual void setPoint(int posIdx, hdPoint p) = 0; + virtual bool isConnectionPossible(hdIFigure *figure) = 0; + hdIFigure *findConnectableFigure(int posIdx, int x, int y, hdDrawing *drawing); + hdIConnector *findConnectionTarget(int posIdx, int x, int y, hdDrawing *drawing); +protected: + hdLineConnection *connection; + hdIFigure *targetFigure; +private: + hdIConnector *originalTarget; +}; +#endif diff --git a/include/hotdraw/handles/hdChangeConnectionStartHandle.h b/include/hotdraw/handles/hdChangeConnectionStartHandle.h new file mode 100644 index 0000000..7bbd0f5 --- /dev/null +++ b/include/hotdraw/handles/hdChangeConnectionStartHandle.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdChangeConnectionStartHandle.h - Handle to allow change connected figure at start of connection figure +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDCHANGECONNECTIONSTARTHANDLE_H +#define HDCHANGECONNECTIONSTARTHANDLE_H + +#include "hotdraw/handles/hdChangeConnectionHandle.h" +#include "hotdraw/figures/hdLineConnection.h" + +class hdChangeConnectionStartHandle : public hdChangeConnectionHandle +{ +public: + hdChangeConnectionStartHandle(hdLineConnection *owner); + ~hdChangeConnectionStartHandle(); + virtual hdPoint &locate(int posIdx); + virtual hdIConnector *target(); + virtual void disconnect(hdDrawingView *view = NULL); + virtual void connect(hdIConnector *connector, hdDrawingView *view = NULL); + virtual bool isConnectionPossible(hdIFigure *figure); + virtual void setPoint(int posIdx, hdPoint p); +}; +#endif diff --git a/include/hotdraw/handles/hdIHandle.h b/include/hotdraw/handles/hdIHandle.h new file mode 100644 index 0000000..6058962 --- /dev/null +++ b/include/hotdraw/handles/hdIHandle.h @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdIHandle.cpp - Base class for all Handles +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDIHANDLE_H +#define HDIHANDLE_H + +#include "wx/dcbuffer.h" +#include "hotdraw/main/hdObject.h" +#include "hotdraw/utilities/hdMultiPosRect.h" +#include "hotdraw/utilities/hdPoint.h" + +class hdDrawingView; +class hdIFigure; +class hdMouseEvent; + +class hdIHandle : public hdObject +{ +public: + hdIHandle(hdIFigure *owner); + ~hdIHandle(); + + static const int size = 4; + + virtual bool containsPoint(int posIdx, int x, int y); + virtual void draw(wxBufferedDC &context, hdDrawingView *view) = 0; + virtual hdPoint &locate(int posIdx) = 0; + virtual void invokeStart(hdMouseEvent &event, hdDrawingView *view) = 0; + virtual void invokeStep(hdMouseEvent &event, hdDrawingView *view) = 0; + virtual void invokeEnd(hdMouseEvent &event, hdDrawingView *view) = 0; + virtual wxCursor createCursor() = 0; + virtual hdRect &getDisplayBox(int posIdx); +protected: + virtual hdIFigure *getOwner(); + hdRect displayBox; +private: + hdIFigure *figureOwner; + double lineWidth; + +}; +#endif diff --git a/include/hotdraw/handles/hdLineConnectionHandle.h b/include/hotdraw/handles/hdLineConnectionHandle.h new file mode 100644 index 0000000..453b8f9 --- /dev/null +++ b/include/hotdraw/handles/hdLineConnectionHandle.h @@ -0,0 +1,25 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdLineConnectionHandle.h - Base class for Handles that are located at locator position +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDLINECONNECTIONHANDLE +#define HDLINECONNECTIONHANDLE + +#include "hotdraw/handles/hdPolyLineHandle.h" + +class hdLineConnectionHandle : public hdPolyLineHandle +{ +public: + hdLineConnectionHandle(hdPolyLineFigure *figure, hdILocator *loc, int index); + virtual void invokeEnd(hdMouseEvent &event, hdDrawingView *view); +private: + +}; +#endif diff --git a/include/hotdraw/handles/hdLocatorHandle.h b/include/hotdraw/handles/hdLocatorHandle.h new file mode 100644 index 0000000..0ffbba7 --- /dev/null +++ b/include/hotdraw/handles/hdLocatorHandle.h @@ -0,0 +1,39 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdLocatorHandle.h - Base class for Handles that are located at locator position +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDLOCATORHANDLE_H +#define HDLOCATORHANDLE_H + +#include "hotdraw/handles/hdIHandle.h" +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/locators/hdILocator.h" + +class hdDrawingView; + +class hdLocatorHandle : public hdIHandle +{ +public: + hdLocatorHandle(hdIFigure *owner, hdILocator *locator); + ~hdLocatorHandle(); + + virtual hdPoint &locate(int posIdx); + virtual hdILocator *locator(); + virtual void invokeStart(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeStep(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeEnd(hdMouseEvent &event, hdDrawingView *view); +protected: + +private: + hdILocator *loc; + hdPoint p; + +}; +#endif diff --git a/include/hotdraw/handles/hdPolyLineHandle.h b/include/hotdraw/handles/hdPolyLineHandle.h new file mode 100644 index 0000000..8c31b11 --- /dev/null +++ b/include/hotdraw/handles/hdPolyLineHandle.h @@ -0,0 +1,40 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdPolyLineHandle.h - Handle for manipulation of multiple flexibility points lines. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDPOLYLINEHANDLE +#define HDPOLYLINEHANDLE + +#include "hotdraw/handles/hdLocatorHandle.h" +#include "hotdraw/utilities/hdRect.h" + +class hdDrawingView; +class hdPolyLineFigure; + +class hdPolyLineHandle : public hdLocatorHandle +{ +public: + hdPolyLineHandle(hdPolyLineFigure *figure, hdILocator *loc, int index); + ~hdPolyLineHandle(); + + virtual void draw(wxBufferedDC &context, hdDrawingView *view); + virtual void invokeStart(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeStep(hdMouseEvent &event, hdDrawingView *view); + virtual wxCursor createCursor(); + virtual int getIndex(); + virtual void setIndex(int index); +protected: + +private: + int indx; + + +}; +#endif diff --git a/include/hotdraw/handles/module.mk b/include/hotdraw/handles/module.mk new file mode 100644 index 0000000..2b43776 --- /dev/null +++ b/include/hotdraw/handles/module.mk @@ -0,0 +1,23 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/hotdraw/handles/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/hotdraw/handles/hdButtonHandle.h \ + include/hotdraw/handles/hdChangeConnectionEndHandle.h \ + include/hotdraw/handles/hdChangeConnectionHandle.h \ + include/hotdraw/handles/hdChangeConnectionStartHandle.h \ + include/hotdraw/handles/hdIHandle.h \ + include/hotdraw/handles/hdLineConnectionHandle.h \ + include/hotdraw/handles/hdLocatorHandle.h \ + include/hotdraw/handles/hdPolyLineHandle.h + +EXTRA_DIST += \ + include/hotdraw/handles/module.mk diff --git a/include/hotdraw/locators/hdILocator.h b/include/hotdraw/locators/hdILocator.h new file mode 100644 index 0000000..772bc4e --- /dev/null +++ b/include/hotdraw/locators/hdILocator.h @@ -0,0 +1,32 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdILocator.h - Base class for creation of a location for a ddHandle +// +////////////////////////////////////////////////////////////////////////// + +#ifndef hdILocator_H +#define hdILocator_H + +#include "hotdraw/main/hdObject.h" +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/figures/hdIFigure.h" + +class hdILocator : public hdObject +{ +public: + hdILocator(); + ~hdILocator(); + + virtual hdPoint &locate(int posIdx, hdIFigure *owner) = 0; + +protected: + hdPoint locatePoint; +private: + +}; +#endif diff --git a/include/hotdraw/locators/hdPolyLineLocator.h b/include/hotdraw/locators/hdPolyLineLocator.h new file mode 100644 index 0000000..8e862d0 --- /dev/null +++ b/include/hotdraw/locators/hdPolyLineLocator.h @@ -0,0 +1,31 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdPolyLineLocator.h - Return multiple location at same time for a PolyLine +// +////////////////////////////////////////////////////////////////////////// + +#ifndef XWHDPOLYLINELOCATOR_H +#define XWHDPOLYLINELOCATOR_H + +#include "hotdraw/locators/hdILocator.h" + +class hdPolyLineLocator : public hdILocator +{ +public: + hdPolyLineLocator(int index); + ~hdPolyLineLocator(); + + virtual hdPoint &locate(int posIdx, hdIFigure *owner); + virtual void setIndex(int index); + +protected: + +private: + int indx; +}; +#endif diff --git a/include/hotdraw/locators/module.mk b/include/hotdraw/locators/module.mk new file mode 100644 index 0000000..9b1ec8a --- /dev/null +++ b/include/hotdraw/locators/module.mk @@ -0,0 +1,17 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/hotdraw/locator/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/hotdraw/locators/hdILocator.h \ + include/hotdraw/locators/hdPolyLineLocator.h + +EXTRA_DIST += \ + include/hotdraw/locators/module.mk diff --git a/include/hotdraw/main/hdDrawing.h b/include/hotdraw/main/hdDrawing.h new file mode 100644 index 0000000..b6488d9 --- /dev/null +++ b/include/hotdraw/main/hdDrawing.h @@ -0,0 +1,85 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdDrawing.h - Main storage class for all objects of the model +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDDRAWING_H +#define HDDRAWING_H + +#include "hotdraw/figures/hdIFigure.h" +#include "hotdraw/utilities/hdRect.h" + + +// Main model of drawing +class hdDrawing : public wxObject +{ +public: + hdDrawing(hdDrawingEditor *owner); + virtual ~hdDrawing(); + virtual void add(hdIFigure *figure); + virtual void remove(hdIFigure *figure); + virtual bool includes(hdIFigure *figure); + virtual hdIFigure *findFigure(int posIdx, int x, int y); + virtual void recalculateDisplayBox(int posIdx); + virtual void bringToFront(hdIFigure *figure); + virtual void sendToBack(hdIFigure *figure); + virtual hdRect &DisplayBox(); + virtual hdIteratorBase *figuresEnumerator(); + virtual hdIteratorBase *figuresInverseEnumerator(); + virtual void removeAllFigures(); + virtual void deleteAllFigures(); + virtual void registerView(hdDrawingView *view) + { + usedView = view; + }; + virtual hdDrawingView *getView() + { + return usedView; + }; + virtual void addToSelection(hdIFigure *figure); + virtual void addToSelection(hdCollection *figures); + virtual void removeFromSelection(hdIFigure *figure); + virtual void deleteSelectedFigures(); + virtual void toggleSelection(hdIFigure *figure); + virtual void clearSelection(); + virtual bool isFigureSelected(hdIFigure *figure); + virtual hdIteratorBase *selectionFigures(); + virtual int countSelectedFigures(); + hdCollection *selectedFigures() + { + return selection; + }; + hdCollection *getFiguresCollection() + { + return figures; + }; + hdDrawingEditor *getOwnerEditor() + { + return ownerEditor; + }; + void setName(wxString name) + { + drawingName = name; + }; + wxString getName() + { + return drawingName; + }; +protected: + +private: + hdDrawingEditor *ownerEditor; + hdDrawingView *usedView; + hdCollection *selection; + hdCollection *figures; + hdCollection *handles; + hdRect displayBox; + wxString drawingName; +}; +#endif diff --git a/include/hotdraw/main/hdDrawingEditor.h b/include/hotdraw/main/hdDrawingEditor.h new file mode 100644 index 0000000..2752bb7 --- /dev/null +++ b/include/hotdraw/main/hdDrawingEditor.h @@ -0,0 +1,52 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdDrawingEditor.h - Main class that manages all other classes +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDDRAWINGEDITOR_H +#define HDDRAWINGEDITOR_H + +#include "hotdraw/main/hdDrawingView.h" +#include "hotdraw/tools/hdITool.h" +#include "hotdraw/utilities/hdArrayCollection.h" + +class hdDrawingEditor : public hdObject +{ +public: + hdDrawingEditor(wxWindow *owner, bool defaultView = true ); + ~hdDrawingEditor(); + hdDrawingView *getExistingView(int diagramIndex); + hdDrawing *getExistingDiagram(int diagramIndex); + virtual hdDrawing *createDiagram(wxWindow *owner, bool fromXml); + virtual void deleteDiagram(int diagramIndex, bool deleteView = true); + virtual void addDiagramFigure(int diagramIndex, hdIFigure *figure); + virtual void removeDiagramFigure(int diagramIndex, hdIFigure *figure); + virtual void addModelFigure(hdIFigure *figure); + virtual void deleteModelFigure(hdIFigure *figure); + virtual void removeFromAllSelections(hdIFigure *figure); + virtual void removeAllDiagramsFigures(); + virtual void deleteAllModelFigures(); + virtual bool modelIncludes(hdIFigure *figure); + virtual void remOrDelSelFigures(int diagramIndex); + virtual void changeDefaultFiguresFont(); + int modelCount(); + hdIteratorBase *modelFiguresEnumerator(); + hdIteratorBase *diagramsEnumerator(); + bool modelHasChanged(); + virtual void notifyChanged(); + +protected: + hdArrayCollection *_diagrams; + hdArrayCollection *_model; + wxWindow *editorOwner; + bool modelChanged; + +private: +}; +#endif diff --git a/include/hotdraw/main/hdDrawingView.h b/include/hotdraw/main/hdDrawingView.h new file mode 100644 index 0000000..051d55e --- /dev/null +++ b/include/hotdraw/main/hdDrawingView.h @@ -0,0 +1,123 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdDrawingView.h - Main canvas where all figures are drawn +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDDRAWINGVIEW_H +#define HDDRAWINGVIEW_H + +#include "hotdraw/figures/hdIFigure.h" +#include "hotdraw/main/hdDrawing.h" +#include "hotdraw/handles/hdIHandle.h" +#include "hotdraw/figures/hdSimpleTextFigure.h" +#include "hotdraw/figures/hdAbstractMenuFigure.h" + +class hdCanvasMenuTool; + +// Create View Class for MVC pattern of graphic library of pgAdmin +enum +{ + CTL_TEXTTOOLID = 1979, + CTL_OKBUTTONID, + CTL_CANCELBUTTONID +}; + +class hdDrawingView : public wxScrolledWindow +{ +public: + hdDrawingView(int diagram, wxWindow *ddParent, hdDrawingEditor *editor , wxSize size, hdDrawing *drawing); + ~hdDrawingView(); + + virtual void ScrollToMakeVisible(hdPoint p); + virtual void ScrollToMakeVisible (hdRect r); + virtual hdIHandle *findHandle(int posIdx, double x, double y); + virtual hdDrawing *getDrawing(); + + void onPaint(wxPaintEvent &event); + void onEraseBackGround(wxEraseEvent &event); + virtual void onMouseDown(wxMouseEvent &event); + virtual void onMouseUp(wxMouseEvent &event); + virtual void onMotion(wxMouseEvent &event); + virtual void onKeyDown(wxKeyEvent &event); + virtual void onKeyUp(wxKeyEvent &event); + virtual hdMultiPosRect getVisibleArea(); + virtual hdMultiPosRect getVirtualSize(); + virtual bool AcceptsFocus () const; + hdDrawingEditor *editor(); + wxSize canvasSize; + + //Hack To allow right click menu at canvas without a figure + virtual void createViewMenu(wxMenu &mnu); + virtual void OnGenericViewPopupClick(wxCommandEvent &event); + //Hack to allow a different tool for each view + hdITool *tool(); + void setTool(hdITool *tool); + //Hack to avoid selection rectangle drawing bug + void setSelRect(hdRect &selectionRect); + void disableSelRectDraw(); + //Hack to avoid event problem with simpleTextTool wxTextCrtl at EVT_TEXT event + void simpleTextToolChangeHandler(wxCommandEvent &event); + void setSimpleTextToolFigure(hdSimpleTextFigure *figure, bool onlySetFigure = false); + wxTextCtrl *getSimpleTextToolEdit(); + wxBitmapButton *getOkTxt(); + wxBitmapButton *getCancelTxt(); + //Hack to allow use (events) of wxmenu inside a tool Generic Way + void setMenuToolFigure(hdAbstractMenuFigure *figure); + //Hack to allow use (events) of wxmenu inside a tool like simpletexttool + void OnGenericPopupClick(wxCommandEvent &event); + void OnOkTxtButton(wxCommandEvent &event); + void OnCancelTxtButton(wxCommandEvent &event); + void connectPopUpMenu(wxMenu &mnu); + //Hack to allow use (events) of wxmenu inside a tool without a figure, Generic Way + void setCanvasMenuTool(hdCanvasMenuTool *menuTool); + //Hack to allow use of a figure into multiple diagrams. + int getIdx() + { + return diagramIndex; + } + void syncIdx(int newDiagramIndex) + { + diagramIndex = newDiagramIndex; + }; + void notifyChanged(); +protected: + int diagramIndex; +private: + DECLARE_EVENT_TABLE() + hdDrawing *drawing; + hdDrawingEditor *drawingEditor; + + //Hack to allow a different tool for each view + hdITool *_tool; + + //Hack to allow auto scrolling when dragging mouse. + hdPoint startDrag; + + //Hack to avoid selection rectangle drawing bug + hdRect selRect; + wxPoint selPoints[5]; + bool drawSelRect; + //End Hack to avoid selection rectangle drawing bug + + //Hack to allow use (events) of wxmenu inside a tool with a figure, Generic Way + hdAbstractMenuFigure *menuFigure; + //End hack to allow use (events) of wxmenu inside a tool with a figure, Generic Way + + //Hack to avoid event problem with simpleTextTool wxTextCrtl at EVT_TEXT event && POPUP EVENT + wxTextCtrl *simpleTextToolEdit; + wxBitmapButton *okTxtButton, *cancelTxtButton; + hdSimpleTextFigure *simpleTextFigure; + wxString oldText; + //End Hack to avoid event problem with simpleTextTool wxTextCrtl at EVT_TEXT event && POPUP EVENT + + //Hack to allow use (events) of wxmenu inside a tool without a figure, Generic Way + hdCanvasMenuTool *canvasMenu; + //Hack to allow use (events) of wxmenu inside a tool without a figure, Generic Way +}; +#endif diff --git a/include/hotdraw/main/hdObject.h b/include/hotdraw/main/hdObject.h new file mode 100644 index 0000000..aa6b9ae --- /dev/null +++ b/include/hotdraw/main/hdObject.h @@ -0,0 +1,19 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbObject.h - +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDOBJECT_H +#define HDOBJECT_H + +class hdObject : public wxObject +{ +public: + hdObject() {}; +}; +#endif diff --git a/include/hotdraw/main/module.mk b/include/hotdraw/main/module.mk new file mode 100644 index 0000000..74cf02b --- /dev/null +++ b/include/hotdraw/main/module.mk @@ -0,0 +1,19 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/hotdraw/main/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/hotdraw/main/hdDrawing.h \ + include/hotdraw/main/hdDrawingEditor.h \ + include/hotdraw/main/hdDrawingView.h \ + include/hotdraw/main/hdObject.h + +EXTRA_DIST += \ + include/hotdraw/main/module.mk diff --git a/include/hotdraw/module.mk b/include/hotdraw/module.mk new file mode 100644 index 0000000..3e6c98f --- /dev/null +++ b/include/hotdraw/module.mk @@ -0,0 +1,21 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/hotdraw/ Makefile fragment +# +####################################################################### + +include include/hotdraw/connectors/module.mk +include include/hotdraw/figures/module.mk +include include/hotdraw/handles/module.mk +include include/hotdraw/locators/module.mk +include include/hotdraw/main/module.mk +include include/hotdraw/tools/module.mk +include include/hotdraw/utilities/module.mk + +EXTRA_DIST += \ + include/hotdraw/module.mk diff --git a/include/hotdraw/tools/hdAbstractTool.h b/include/hotdraw/tools/hdAbstractTool.h new file mode 100644 index 0000000..8a6e756 --- /dev/null +++ b/include/hotdraw/tools/hdAbstractTool.h @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdAbstractTool.h - An abstract tool to allow creation of all tools +// +////////////////////////////////////////////////////////////////////////// + +#ifndef hdAbstractTool_H +#define hdAbstractTool_H + +#include "hotdraw/main/hdObject.h" +#include "hotdraw/tools/hdITool.h" +#include "hotdraw/main/hdDrawingEditor.h" + + +class hdAbstractTool : public hdITool +{ +public: + hdAbstractTool(hdDrawingView *view); + ~hdAbstractTool(); + + void setAnchorCoords(int x, int y); + + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual void mouseUp(hdMouseEvent &event); + virtual void mouseMove(hdMouseEvent &event); + virtual void mouseDrag(hdMouseEvent &event); + virtual void keyDown(hdKeyEvent &event); + virtual void keyUp(hdKeyEvent &event); + hdDrawingView *getDrawingView(); + +protected: + int anchorX, anchorY; + hdDrawingView *ownerView; +private: + +}; +#endif diff --git a/include/hotdraw/tools/hdCanvasMenuTool.h b/include/hotdraw/tools/hdCanvasMenuTool.h new file mode 100644 index 0000000..4dade19 --- /dev/null +++ b/include/hotdraw/tools/hdCanvasMenuTool.h @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdMenuTool.h - Allow Edition of textTool (double click) or show a menu to modifiy in someway text (right click). +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDCANVASMENUTOOL_H +#define HDCANVASMENUTOOL_H + +#include "hotdraw/tools/hdAbstractTool.h" + +class hdCanvasMenuTool : public hdAbstractTool +{ + +public: + hdCanvasMenuTool(hdDrawingView *view, hdITool *dt); + ~hdCanvasMenuTool(); + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual void mouseDrag(hdMouseEvent &event); + virtual void mouseUp(hdMouseEvent &event); + virtual void mouseMove(hdMouseEvent &event); + virtual void createViewMenu(hdDrawingView *view, wxMenu &mnu); + virtual void OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view); + //Because a bug it was move to main View class as a hack. virtual void changeHandler(wxCommandEvent& event); +protected: + hdITool *defaultTool; +private: +}; +#endif diff --git a/include/hotdraw/tools/hdCompositeFigureTool.h b/include/hotdraw/tools/hdCompositeFigureTool.h new file mode 100644 index 0000000..f40398b --- /dev/null +++ b/include/hotdraw/tools/hdCompositeFigureTool.h @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdCompositeFigureTool.h - A Tool that allow to change between all tools in a composite figure +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDCOMPOSITEFIGURETOOL_H +#define HDCOMPOSITEFIGURETOOL_H + +#include "hotdraw/tools/hdFigureTool.h" + + +class hdCompositeFigureTool : public hdFigureTool +{ +public: + hdCompositeFigureTool(hdDrawingView *view, hdIFigure *fig, hdITool *dt); + ~hdCompositeFigureTool(); + virtual void setDefaultTool(hdITool *dt); + virtual hdITool *getDefaultTool(); + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual void activate(hdDrawingView *view); + virtual void deactivate(hdDrawingView *view); + virtual void setDelegateTool(hdDrawingView *view, hdITool *tool); + virtual hdITool *getDelegateTool(); +protected: + hdITool *delegateTool; +private: +}; +#endif diff --git a/include/hotdraw/tools/hdConnectionCreationTool.h b/include/hotdraw/tools/hdConnectionCreationTool.h new file mode 100644 index 0000000..e8deec1 --- /dev/null +++ b/include/hotdraw/tools/hdConnectionCreationTool.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdConnectionCreationTool.h - A Tool that allow to create a connection figure between two figures +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDCONNECTIONCREATIONTOOL_H +#define HDCONNECTIONCREATIONTOOL_H + +#include "hotdraw/tools/hdAbstractTool.h" +#include "hotdraw/main/hdDrawingEditor.h" +#include "hotdraw/figures/hdLineConnection.h" + +class hdConnectionCreationTool : public hdAbstractTool +{ +public: + hdConnectionCreationTool(hdDrawingView *view, hdLineConnection *figure); + ~hdConnectionCreationTool(); + + virtual void mouseDrag(hdMouseEvent &event); + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual void mouseUp(hdMouseEvent &event); + virtual void mouseMove(hdMouseEvent &event); +protected: + +private: + hdLineConnection *toolConnection; + hdIHandle *handle; + int numClicks; + bool dragged; + +}; +#endif diff --git a/include/hotdraw/tools/hdCreationTool.h b/include/hotdraw/tools/hdCreationTool.h new file mode 100644 index 0000000..c0ea8ca --- /dev/null +++ b/include/hotdraw/tools/hdCreationTool.h @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdCreationTool.h - A Tool that create a figure by just click on view +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDCREATIONTOOL_H +#define HDCREATIONTOOL_H + +#include "hotdraw/tools/hdAbstractTool.h" +#include "hotdraw/figures/hdIFigure.h" + + +class hdCreationTool : public hdAbstractTool +{ +public: + hdCreationTool(hdDrawingView *view, hdIFigure *prototype); + ~hdCreationTool(); + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual void mouseUp(hdMouseEvent &event); + virtual void activate(hdDrawingView *view); + virtual void deactivate(hdDrawingView *view); + virtual void setPrototype(hdIFigure *prototype); + virtual hdIFigure *getPrototype(); + +protected: + hdIFigure *figurePrototype; + + +}; +#endif diff --git a/include/hotdraw/tools/hdDragCreationTool.h b/include/hotdraw/tools/hdDragCreationTool.h new file mode 100644 index 0000000..46c0db3 --- /dev/null +++ b/include/hotdraw/tools/hdDragCreationTool.h @@ -0,0 +1,26 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdDragCreationTool.h - A Tool that allow to move figure around view +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDDRAGCREATIONTOOL_H +#define HDDRAGCREATIONTOOL_H + +#include "hotdraw/tools/hdCreationTool.h" +#include "hotdraw/main/hdDrawingEditor.h" + + +class hdDragCreationTool : public hdCreationTool +{ +public: + hdDragCreationTool(hdDrawingView *view, hdIFigure *prototype); + ~hdDragCreationTool(); + virtual void mouseDrag(hdMouseEvent &event); +}; +#endif diff --git a/include/hotdraw/tools/hdDragTrackerTool.h b/include/hotdraw/tools/hdDragTrackerTool.h new file mode 100644 index 0000000..93eeb84 --- /dev/null +++ b/include/hotdraw/tools/hdDragTrackerTool.h @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdDragTrackerTool.h - A Tool that allow to drag and drop figures at the view +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDDRAGTRACKERTOOL_H +#define HDDRAGTRACKERTOOL_H + +#include "hotdraw/main/hdObject.h" +#include "hotdraw/tools/hdITool.h" +#include "hotdraw/figures/hdIFigure.h" +#include "hotdraw/main/hdDrawingEditor.h" +#include "hotdraw/tools/hdAbstractTool.h" + + +class hdDragTrackerTool : public hdAbstractTool +{ +public: + hdDragTrackerTool(hdDrawingView *view, hdIFigure *anchor); + ~hdDragTrackerTool(); + + void setLastCoords(int x, int y); + bool hasMoved(); + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual void mouseUp(hdMouseEvent &event); + virtual void mouseDrag(hdMouseEvent &event); + +protected: + hdIFigure *anchorFigure; + bool hasMovedValue; + +private: + int lastX, lastY; + +}; +#endif diff --git a/include/hotdraw/tools/hdFigureTool.h b/include/hotdraw/tools/hdFigureTool.h new file mode 100644 index 0000000..2c7f2b2 --- /dev/null +++ b/include/hotdraw/tools/hdFigureTool.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdFigureTool.h - Base class for all figure tools +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDFIGURETOOL_H +#define HDFIGURETOOL_H + +#include "hotdraw/tools/hdAbstractTool.h" + + +class hdFigureTool : public hdAbstractTool +{ +public: + hdFigureTool(hdDrawingView *view, hdIFigure *fig, hdITool *dt); + ~hdFigureTool(); + void setDefaultTool(hdITool *dt); + hdITool *getDefaultTool(); + void setFigure(hdIFigure *fig); + hdIFigure *getFigure(); + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual void mouseUp(hdMouseEvent &event); + virtual void mouseMove(hdMouseEvent &event); + virtual void mouseDrag(hdMouseEvent &event); + virtual void keyDown(hdKeyEvent &event); + virtual void keyUp(hdKeyEvent &event); +protected: + hdITool *defaultTool; + hdIFigure *figure; +private: +}; +#endif diff --git a/include/hotdraw/tools/hdHandleTrackerTool.h b/include/hotdraw/tools/hdHandleTrackerTool.h new file mode 100644 index 0000000..0f3d10a --- /dev/null +++ b/include/hotdraw/tools/hdHandleTrackerTool.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdHandleTrackerTool.h - A Tool that allow to use multiple handles +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDHANDLETRACKERTOOL_H +#define HDHANDLETRACKERTOOL_H + +#include "hotdraw/main/hdObject.h" +#include "hotdraw/tools/hdITool.h" +#include "hotdraw/handles/hdIHandle.h" +#include "hotdraw/main/hdDrawingEditor.h" +#include "hotdraw/tools/hdAbstractTool.h" + + +class hdHandleTrackerTool : public hdAbstractTool +{ +public: + hdHandleTrackerTool(hdDrawingView *view, hdIHandle *anchor); + ~hdHandleTrackerTool(); + + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual void mouseUp(hdMouseEvent &event); + virtual void mouseDrag(hdMouseEvent &event); + +protected: + hdIHandle *anchorHandle; + +private: + +}; +#endif diff --git a/include/hotdraw/tools/hdITool.h b/include/hotdraw/tools/hdITool.h new file mode 100644 index 0000000..ed3a144 --- /dev/null +++ b/include/hotdraw/tools/hdITool.h @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdITool.h - Base class for all tools +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDITOOL_H +#define HDITOOL_H + +#include "hotdraw/main/hdObject.h" +#include "hotdraw/utilities/hdMouseEvent.h" +#include "hotdraw/utilities/hdKeyEvent.h" + + +class hdITool : public hdObject +{ +public: + hdITool(); + ~hdITool(); + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual void mouseUp(hdMouseEvent &event); + virtual void mouseMove(hdMouseEvent &event); + virtual void mouseDrag(hdMouseEvent &event); + virtual void keyDown(hdKeyEvent &event); + virtual void keyUp(hdKeyEvent &event); + virtual void activate(hdDrawingView *view); + virtual void deactivate(hdDrawingView *view); + virtual bool activated(); + virtual bool undoable(); + +protected: + + bool activatedValue; + bool undoableValue; + +}; +#endif diff --git a/include/hotdraw/tools/hdMenuTool.h b/include/hotdraw/tools/hdMenuTool.h new file mode 100644 index 0000000..abcca6a --- /dev/null +++ b/include/hotdraw/tools/hdMenuTool.h @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdMenuTool.h - Allow Edition of textTool (double click) or show a menu to modifiy in someway text (right click). +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDMENUTOOL_H +#define HDMENUTOOL_H + +#include "hotdraw/tools/hdFigureTool.h" +#include "hotdraw/figures/hdSimpleTextFigure.h" + + +class hdMenuTool : public hdFigureTool +{ + +public: + hdMenuTool(hdDrawingView *view, hdIFigure *fig, hdITool *dt); + ~hdMenuTool(); + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual void activate(hdDrawingView *view); + virtual void deactivate(hdDrawingView *view); + virtual void mouseDrag(hdMouseEvent &event); + virtual void OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view); + //Because a bug it was move to main View class as a hack. virtual void changeHandler(wxCommandEvent& event); +protected: +private: + hdAbstractMenuFigure *menuFigure; + //Because a bug in the way wxwidgets connect events I can't declare it here, wxTextCtrl *edit, instead I do it on the view. +}; +#endif diff --git a/include/hotdraw/tools/hdPolyLineFigureTool.h b/include/hotdraw/tools/hdPolyLineFigureTool.h new file mode 100644 index 0000000..b9a808e --- /dev/null +++ b/include/hotdraw/tools/hdPolyLineFigureTool.h @@ -0,0 +1,27 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdPolyLineFigureTool.h - Tool to allow creation of flexibility points at polylines figures +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDPOLYLINEFIGURETOOL_H +#define HDPOLYLINEFIGURETOOL_H + +#include "hotdraw/tools/hdFigureTool.h" + + +class hdPolyLineFigureTool : public hdFigureTool +{ +public: + hdPolyLineFigureTool(hdDrawingView *view, hdIFigure *fig, hdITool *dt); + ~hdPolyLineFigureTool(); + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click +protected: +private: +}; +#endif diff --git a/include/hotdraw/tools/hdSelectAreaTool.h b/include/hotdraw/tools/hdSelectAreaTool.h new file mode 100644 index 0000000..1a4bd82 --- /dev/null +++ b/include/hotdraw/tools/hdSelectAreaTool.h @@ -0,0 +1,37 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdSelectAreaTool.h - Tool to allow selection of figures inside a rectangle +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDSELECTAREATOOL_H +#define HDSELECTAREATOOL_H + +#include "hotdraw/main/hdObject.h" +#include "hotdraw/tools/hdITool.h" +#include "hotdraw/figures/hdIFigure.h" +#include "hotdraw/main/hdDrawingEditor.h" +#include "hotdraw/tools/hdAbstractTool.h" + + +class hdSelectAreaTool : public hdAbstractTool +{ +public: + hdSelectAreaTool(hdDrawingView *view); + ~hdSelectAreaTool(); + + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual void mouseUp(hdMouseEvent &event); + virtual void mouseDrag(hdMouseEvent &event); + void selectFiguresOnRect(bool shiftPressed, hdDrawingView *view); +protected: + void drawSelectionRect(hdDrawingView *view); +private: + hdRect selectionRect; +}; +#endif diff --git a/include/hotdraw/tools/hdSelectionTool.h b/include/hotdraw/tools/hdSelectionTool.h new file mode 100644 index 0000000..a589df5 --- /dev/null +++ b/include/hotdraw/tools/hdSelectionTool.h @@ -0,0 +1,37 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdSelectionTool.h - Tool to allow selection of figures +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDSELECTIONTOOL_H +#define HDSELECTIONTOOL_H + +#include "hotdraw/tools/hdITool.h" +#include "hotdraw/tools/hdAbstractTool.h" + +class hdSelectionTool : public hdAbstractTool +{ +public: + hdSelectionTool(hdDrawingView *view); + ~hdSelectionTool(); + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual void mouseUp(hdMouseEvent &event); + virtual void mouseMove(hdMouseEvent &event); + virtual void mouseDrag(hdMouseEvent &event); + virtual void keyDown(hdKeyEvent &event); + virtual void keyUp(hdKeyEvent &event); + void setDelegateTool(hdDrawingView *view, hdITool *tool); + hdITool *getDelegateTool(); + +protected: + hdITool *_delegateTool; +private: + void deleteAllFigures(hdDrawingView *view); +}; +#endif diff --git a/include/hotdraw/tools/hdSimpleTextTool.h b/include/hotdraw/tools/hdSimpleTextTool.h new file mode 100644 index 0000000..22a59a9 --- /dev/null +++ b/include/hotdraw/tools/hdSimpleTextTool.h @@ -0,0 +1,41 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdSimpleTextTool.h - Tool to allow edition of textTool with a double click or show a menu with a right click. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDSIMPLETEXTTOOL_H +#define HDSIMPLETEXTTOOL_H + +#include "hotdraw/tools/hdFigureTool.h" +#include "hotdraw/figures/hdSimpleTextFigure.h" + +class hdSimpleTextTool : public hdFigureTool +{ + +public: + hdSimpleTextTool(hdDrawingView *view, hdIFigure *fig, hdITool *dt, bool fastEdit = true, wxString dialogCaption = wxEmptyString, wxString dialogMessage = wxEmptyString); + ~hdSimpleTextTool(); + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual void activate(hdDrawingView *view); + virtual void deactivate(hdDrawingView *view); + virtual void mouseDrag(hdMouseEvent &event); + virtual void OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view); + virtual bool callDialog(hdDrawingView *view); + //Because a bug it was move to main View class instance as a hack. virtual void changeHandler(wxCommandEvent& event); +protected: + bool withoutDialog; + wxString dlgMessage, dlgCaption; +private: + hdSimpleTextFigure *txtFigure; + void calculateSizeEntry(hdDrawingView *view); + bool showEdit; + //Because a bug in the way wxwidgets connect events I can't declare it here, wxTextCtrl *edit, instead I do it on the view instance. +}; + +#endif diff --git a/include/hotdraw/tools/module.mk b/include/hotdraw/tools/module.mk new file mode 100644 index 0000000..163c287 --- /dev/null +++ b/include/hotdraw/tools/module.mk @@ -0,0 +1,30 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/hotdraw/tools/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/hotdraw/tools/hdAbstractTool.h \ + include/hotdraw/tools/hdCanvasMenuTool.h \ + include/hotdraw/tools/hdCompositeFigureTool.h \ + include/hotdraw/tools/hdConnectionCreationTool.h \ + include/hotdraw/tools/hdCreationTool.h \ + include/hotdraw/tools/hdDragCreationTool.h \ + include/hotdraw/tools/hdDragTrackerTool.h \ + include/hotdraw/tools/hdFigureTool.h \ + include/hotdraw/tools/hdHandleTrackerTool.h \ + include/hotdraw/tools/hdITool.h \ + include/hotdraw/tools/hdMenuTool.h \ + include/hotdraw/tools/hdPolyLineFigureTool.h \ + include/hotdraw/tools/hdSelectAreaTool.h \ + include/hotdraw/tools/hdSelectionTool.h \ + include/hotdraw/tools/hdSimpleTextTool.h + +EXTRA_DIST += \ + include/hotdraw/tools/module.mk diff --git a/include/hotdraw/utilities/hdArrayCollection.h b/include/hotdraw/utilities/hdArrayCollection.h new file mode 100644 index 0000000..3a99485 --- /dev/null +++ b/include/hotdraw/utilities/hdArrayCollection.h @@ -0,0 +1,77 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdArrayCollection.h - Implementation of Collection Using Arrays +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDARRAYCOLLECTION_H +#define HDARRAYCOLLECTION_H + +// App headers +#include "hotdraw/utilities/hdCollectionBase.h" +#include "hotdraw/main/hdObject.h" + + +WX_DEFINE_ARRAY_PTR(hdObject *, ddObjsArray); + +class hdArrayIterator : public hdIteratorBase +{ +public: + hdArrayIterator(ddObjsArray *ddPtrsArray); + hdObject *Next(); + hdObject *Current(); + bool HasNext(); + void ResetIterator(); + +private: + int position; + ddObjsArray *internalArray; +}; + +class hdArrayDownIterator : public hdIteratorBase +{ +public: + hdArrayDownIterator(ddObjsArray *ddPtrsArray); + hdObject *Next(); + hdObject *Current(); + bool HasNext(); + void ResetIterator(); + +private: + int position; + ddObjsArray *internalArray; +}; + +//Create Array Objects used as base for hdCollections +class hdArrayCollection : public hdCollectionBase +{ +public: + ~hdArrayCollection(); + void addItem(hdObject *item); + void removeItem(hdObject *item); + virtual void removeItemAt(int index); + hdIteratorBase *createIterator(); + hdIteratorBase *createDownIterator(); + hdObject *getItemAt(int index); + void bringToFront(hdObject *item); + void sendToBack(hdObject *item); + int count(); + bool existsObject(hdObject *item); + int getIndex(hdObject *item); + void insertAtIndex(hdObject *item, int index); + void replaceAtIndex(hdObject *item, int index); + void deleteAll(); + void removeAll(); + hdObject *&operator[](size_t index) + { + return ddArray[index]; + } +private: + ddObjsArray ddArray; +}; +#endif diff --git a/include/hotdraw/utilities/hdCollection.h b/include/hotdraw/utilities/hdCollection.h new file mode 100644 index 0000000..9dbed4a --- /dev/null +++ b/include/hotdraw/utilities/hdCollection.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdCollection.h - Generic implementation of a Collection used by dd +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDCOLLECTION_H +#define HDCOLLECTION_H + +// App headers +#include "hotdraw/main/hdObject.h" +#include "hotdraw/utilities/hdCollectionBase.h" + +class hdCollection : public wxObject +{ +public: + hdCollection(hdCollectionBase *collectionBase); + virtual ~hdCollection(); + void addItem(hdObject *item); + void removeItem(hdObject *item); + void removeItemAt(int index); + void deleteAll(); + void removeAll(); + int count(); + bool existsObject(hdObject *item); + int getIndex(hdObject *item); + hdObject *getItemAt(int index); + void insertAtIndex(hdObject *item, int index); + void replaceAtIndex(hdObject *item, int index); + void bringToFront(hdObject *item); + void sendToBack(hdObject *item); + hdIteratorBase *createIterator(); + hdIteratorBase *createDownIterator(); + +private: + hdCollectionBase *collection; +}; +#endif diff --git a/include/hotdraw/utilities/hdCollectionBase.h b/include/hotdraw/utilities/hdCollectionBase.h new file mode 100644 index 0000000..264ac87 --- /dev/null +++ b/include/hotdraw/utilities/hdCollectionBase.h @@ -0,0 +1,54 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdCollectionBase.h - A Collection Interface for ERD +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDCOLLECTIONBASE_H +#define HDCOLLECTIONBASE_H + +// App headers +#include "hotdraw/main/hdObject.h" + +// This class it's like an interface (but with not all advantages of this at runtime) +// If in a future I just don't want to use an array, simple implement this abstract class again +// with the new data structure. + +class hdIteratorBase : wxObject +{ +public: + hdIteratorBase() {}; + virtual hdObject *Current() = 0; + virtual hdObject *Next() = 0; + virtual bool HasNext() = 0; + virtual void ResetIterator() = 0; +}; + + +class hdCollectionBase : wxObject +{ +public: + hdCollectionBase() {}; + virtual ~hdCollectionBase() {}; + virtual void addItem(hdObject *item) = 0; + virtual void removeItem(hdObject *item) = 0; + virtual void removeItemAt(int index) = 0; + virtual hdObject *getItemAt(int index) = 0; + virtual hdIteratorBase *createIterator() = 0; + virtual hdIteratorBase *createDownIterator() = 0; + virtual int count() = 0; + virtual bool existsObject(hdObject *item) = 0; + virtual int getIndex(hdObject *item) = 0; + virtual void insertAtIndex(hdObject *item, int index) = 0; + virtual void replaceAtIndex(hdObject *item, int index) = 0; + virtual void bringToFront(hdObject *item) = 0; + virtual void sendToBack(hdObject *item) = 0; + virtual void deleteAll() = 0; + virtual void removeAll() = 0; //remove all items from collection without deleting. +}; +#endif diff --git a/include/hotdraw/utilities/hdGeometry.h b/include/hotdraw/utilities/hdGeometry.h new file mode 100644 index 0000000..3a6dc45 --- /dev/null +++ b/include/hotdraw/utilities/hdGeometry.h @@ -0,0 +1,40 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdGeometry.h - Utility Geometric Functions Shared between classes +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDGEOMETRY_H +#define HDGEOMETRY_H +#include "hotdraw/main/hdObject.h" +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/utilities/hdMultiPosRect.h" + +class hdGeometry : public hdObject +{ +public: + static bool lineContainsPoint(double x1, double y1, double x2, double y2, double px, double py); + static int min(int a, int b); + static int max(int a, int b); + static int min(double a, double b); + static int max(double a, double b); + static double angleFromPoint(hdRect r, hdPoint point); + static double angleFromPoint(int posIdx, hdMultiPosRect r, hdPoint point); + static hdPoint edgePointFromAngle(hdRect r, double angle); + static hdPoint edgePointFromAngle(int posIdx, hdMultiPosRect r, double angle); + static double range(double min, double max, double num); + static double lineSize (hdPoint p1, hdPoint p2); + static bool intersection(hdPoint p1, hdPoint p2, hdPoint p3, hdPoint p4); + static double ddabs(double value); + static int ddabs(int value); + +private: + +}; +#endif diff --git a/include/hotdraw/utilities/hdKeyEvent.h b/include/hotdraw/utilities/hdKeyEvent.h new file mode 100644 index 0000000..787055f --- /dev/null +++ b/include/hotdraw/utilities/hdKeyEvent.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdKeyEvent.h - Wrapper Class to integrate wxKeyEvent inside library. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDKEYEVENT_H +#define HDKEYEVENT_H +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/main/hdObject.h" + +class hdDrawingView; + +class hdKeyEvent : public hdObject +{ +public: + hdKeyEvent(wxKeyEvent &event, hdDrawingView *owner); + hdDrawingView *getView(); + int GetKeyCode(); +private: + hdDrawingView *view; + wxKeyEvent &keyEvent; + int keyCode; +}; +#endif diff --git a/include/hotdraw/utilities/hdMouseEvent.h b/include/hotdraw/utilities/hdMouseEvent.h new file mode 100644 index 0000000..7f8eaaf --- /dev/null +++ b/include/hotdraw/utilities/hdMouseEvent.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdMouseEvent.h - Wrapper Class to integrate conversion CalcUnscrolledPosition in a mouse event. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDMOUSEEVENT_H +#define HDMOUSEEVENT_H +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/main/hdObject.h" + +class hdDrawingView; + +class hdMouseEvent : public hdObject +{ +public: + hdMouseEvent(wxMouseEvent &event, hdDrawingView *owner); + hdPoint &getUnScrolledPosition(); + hdPoint &getScrolledPosition(); + hdPoint &GetPosition(); + int getUnScrolledPosX(); + int getUnScrolledPosY(); + int getScrolledPosX(); + int getScrolledPosY(); + bool LeftDClick(); + bool LeftDown(); + bool LeftIsDown(); + bool LeftUp(); + bool ShiftDown(); + bool RightDown(); + bool m_shiftDown; + hdDrawingView *getView(); +private: + hdDrawingView *view; + wxMouseEvent &mouseEvent; + hdPoint unScrolled, scrolled; +}; +#endif diff --git a/include/hotdraw/utilities/hdMultiPosRect.h b/include/hotdraw/utilities/hdMultiPosRect.h new file mode 100644 index 0000000..149f5cf --- /dev/null +++ b/include/hotdraw/utilities/hdMultiPosRect.h @@ -0,0 +1,342 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdMultiRect.h - hdRect improved class with new needed functionalities for allowing multiple displaybox for same figure +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDMULTIPOSRECT_H +#define HDMULTIPOSRECT_H +#include "hotdraw/main/hdObject.h" +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/utilities/hdRect.h" + +#define MAXPOS 1 + +class hdMultiPosRect : public hdObject +{ +public: + hdMultiPosRect() + : width(0), height(0) + { + init(); + } + + hdMultiPosRect(int xx, int yy, int ww, int hh) + : width(ww), height(hh) + { + init(xx, yy); + } + + hdMultiPosRect(int posIdx, const wxPoint &topLeft, const wxPoint &bottomRight); + + hdMultiPosRect(hdPoint *point) + : width(0), height(0) + { + init(point->x, point->y); + } + + hdMultiPosRect(hdPoint &point) + : width(0), height(0) + { + init(point.x, point.y); + } + + hdMultiPosRect(const wxPoint &pt, const wxSize &size) + : width(size.x), height(size.y) + { + init(pt.x, pt.y); + } + + hdMultiPosRect(const wxSize &size) + : width(size.x), height(size.y) + { + init(0, 0); + } + // default copy ctor and assignment operators ok + + int GetX(int posIdx) const + { + return x[posIdx]; + } + void SetX(int posIdx, int xx) + { + x[posIdx] = xx; + } + + int GetY(int posIdx) const + { + return y[posIdx]; + } + void SetY(int posIdx, int yy) + { + y[posIdx] = yy; + } + + int GetWidth() const + { + return width; + } + void SetWidth(int w) + { + width = w; + } + + int GetHeight() const + { + return height; + } + void SetHeight(int h) + { + height = h; + } + + wxPoint GetPosition(int posIdx) const + { + return wxPoint(x[posIdx], y[posIdx]); + } + void SetPosition( int posIdx, const wxPoint &p ) + { + x[posIdx] = p.x; + y[posIdx] = p.y; + } + + wxSize GetSize() const + { + return wxSize(width, height); + } + void SetSize( const wxSize &s ) + { + width = s.GetWidth(); + height = s.GetHeight(); + } + + bool IsEmpty() const + { + return (width <= 0) || (height <= 0); + } + + int GetLeft(int posIdx) const + { + return x[posIdx]; + } + int GetTop(int posIdx) const + { + return y[posIdx]; + } + int GetBottom(int posIdx) const + { + return y[posIdx] + height - 1; + } + int GetRight(int posIdx) const + { + return x[posIdx] + width - 1; + } + + void SetLeft(int posIdx, int left) + { + x[posIdx] = left; + } + void SetRight(int posIdx, int right) + { + width = right - x[posIdx] + 1; + } + void SetTop(int posIdx, int top) + { + y[posIdx] = top; + } + void SetBottom(int posIdx, int bottom) + { + height = bottom - y[posIdx] + 1; + } + + wxPoint GetTopLeft(int posIdx) const + { + return GetPosition(posIdx); + } + wxPoint GetLeftTop(int posIdx) const + { + return GetTopLeft(posIdx); + } + void SetTopLeft(int posIdx, const wxPoint &p) + { + SetPosition(posIdx, p); + } + void SetLeftTop(int posIdx, const wxPoint &p) + { + SetTopLeft(posIdx, p); + } + + wxPoint GetBottomRight(int posIdx) const + { + return wxPoint(GetRight(posIdx), GetBottom(posIdx)); + } + wxPoint GetRightBottom(int posIdx) const + { + return GetBottomRight(posIdx); + } + void SetBottomRight(int posIdx, const wxPoint &p) + { + SetRight(posIdx, p.x); + SetBottom(posIdx, p.y); + } + void SetRightBottom(int posIdx, const wxPoint &p) + { + SetBottomRight(posIdx, p); + } + + wxPoint GetTopRight(int posIdx) const + { + return wxPoint(GetRight(posIdx), GetTop(posIdx)); + } + wxPoint GetRightTop(int posIdx) const + { + return GetTopRight(posIdx); + } + void SetTopRight(int posIdx, const wxPoint &p) + { + SetRight(posIdx, p.x); + SetTop(posIdx, p.y); + } + void SetRightTop(int posIdx, const wxPoint &p) + { + SetTopLeft(posIdx, p); + } + + wxPoint GetBottomLeft(int posIdx) const + { + return wxPoint(GetLeft(posIdx), GetBottom(posIdx)); + } + wxPoint GetLeftBottom(int posIdx) const + { + return GetBottomLeft(posIdx); + } + void SetBottomLeft(int posIdx, const wxPoint &p) + { + SetLeft(posIdx, p.x); + SetBottom(posIdx, p.y); + } + void SetLeftBottom(int posIdx, const wxPoint &p) + { + SetBottomLeft(posIdx, p); + } + + // operations with rect + hdMultiPosRect &Inflate(int posIdx, wxCoord dx, wxCoord dy); + hdMultiPosRect &Inflate(int posIdx, const wxSize &d) + { + return Inflate(posIdx, d.x, d.y); + } + hdMultiPosRect &Inflate(int posIdx, wxCoord d) + { + return Inflate(posIdx, d, d); + } + + hdMultiPosRect Inflate(int posIdx, wxCoord dx, wxCoord dy) const + { + hdMultiPosRect r = *this; + r.Inflate(posIdx, dx, dy); + return r; + } + + hdMultiPosRect &Deflate(int posIdx, wxCoord dx, wxCoord dy) + { + return Inflate(posIdx, -dx, -dy); + } + hdMultiPosRect &Deflate(int posIdx, const wxSize &d) + { + return Inflate(posIdx, -d.x, -d.y); + } + hdMultiPosRect &Deflate(int posIdx, wxCoord d) + { + return Inflate(posIdx, -d); + } + + hdMultiPosRect Deflate(int posIdx, wxCoord dx, wxCoord dy) const + { + hdMultiPosRect r = *this; + r.Deflate(posIdx, dx, dy); + return r; + } + + + void Offset(int posIdx, wxCoord dx, wxCoord dy) + { + x[posIdx] += dx; + y[posIdx] += dy; + } + void Offset(int posIdx, const wxPoint &pt) + { + Offset(posIdx, pt.x, pt.y); + } + + hdMultiPosRect &Intersect(int posIdx, const hdMultiPosRect &rect); + + hdMultiPosRect Intersect(int posIdx, const hdMultiPosRect &rect) const + { + hdMultiPosRect r = *this; + r.Intersect(posIdx, rect); + return r; + } + + hdMultiPosRect &Union(int posIdx, const hdMultiPosRect &rect); + + + hdMultiPosRect Union(int posIdx, const hdMultiPosRect &rect) const + { + hdMultiPosRect r = *this; + r.Union(posIdx, rect); + return r; + } + + // return true if the point is (not strcitly) inside the rect + bool Contains(int posIdx, int x, int y) const; + bool Contains(int posIdx, const wxPoint &pt) const + { + return Contains(posIdx, pt.x, pt.y); + } + // return true if the rectangle is (not strcitly) inside the rect + bool Contains(int posIdx, const hdRect &rect) const; + + // return true if the rectangles have a non empty intersection + bool Intersects(int posIdx, const hdMultiPosRect &rect) const; + + // centre this rectangle in the given (usually, but not necessarily, + // larger) one + hdMultiPosRect CentreIn(int posIdxThis, const hdMultiPosRect &r, int posIdxr, int dir = wxBOTH) const + { + return hdMultiPosRect(dir & wxHORIZONTAL ? r.x[posIdxr] + (r.width - width) / 2 : x[posIdxThis], + dir & wxVERTICAL ? r.y[posIdxr] + (r.height - height) / 2 : y[posIdxThis], + width, height); + } + + hdMultiPosRect CenterIn(int posIdxThis, const hdMultiPosRect &r, int posIdxr, int dir = wxBOTH) const + { + return CentreIn(posIdxThis, r, posIdxr, dir); + } + + void add (int posIdx, int newX, int netY); + void add (int posIdx, hdRect *newRect); + void add (int posIdx, hdRect newRect); + void add (int posIdx, hdPoint *p); + hdPoint center(int posIdx); + hdRect gethdRect(int posIdx) + { + return hdRect(x[posIdx], y[posIdx], width, height); + } + int CountPositions(); + void addNewXYPosition(); + void removeXYPosition(int posIdx); + wxArrayInt x, y; + int width, height; + +private: + void init(int valX = 0, int valY = 0); + hdPoint point; +}; +#endif + diff --git a/include/hotdraw/utilities/hdPoint.h b/include/hotdraw/utilities/hdPoint.h new file mode 100644 index 0000000..632fd0c --- /dev/null +++ b/include/hotdraw/utilities/hdPoint.h @@ -0,0 +1,24 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdPoint.h - wxPoint class to be used as wrapper and allow independence of point class +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDPOINT_H +#define HDPOINT_H + +class hdPoint : public wxPoint +{ +public: + hdPoint(); + hdPoint(int x, int y); + hdPoint(const hdPoint &p); + hdPoint(const wxPoint &p); +}; + +#endif diff --git a/include/hotdraw/utilities/hdRect.h b/include/hotdraw/utilities/hdRect.h new file mode 100644 index 0000000..2679943 --- /dev/null +++ b/include/hotdraw/utilities/hdRect.h @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdRect.h - wxRect improved class with new needed functionalities +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDRECT_H +#define HDRECT_H +#include "hotdraw/utilities/hdPoint.h" + +class hdRect : public wxRect +{ +public: + hdRect(); + hdRect(int xx, int yy, int ww, int hh); + hdRect(hdPoint *topLeft, hdPoint *bottomRight); + hdRect(hdPoint *point); + hdRect(hdPoint &point); + void add (int newX, int netY); + void add (hdRect *newRect); + void add (hdRect newRect); + void add (hdPoint *p); + hdPoint center(); +protected: + +private: + hdPoint point; +}; +#endif diff --git a/include/hotdraw/utilities/hdRemoveDeleteDialog.h b/include/hotdraw/utilities/hdRemoveDeleteDialog.h new file mode 100644 index 0000000..74a0b98 --- /dev/null +++ b/include/hotdraw/utilities/hdRemoveDeleteDialog.h @@ -0,0 +1,64 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddPrecisionScaleDialog.h - Utility dialog class to allow user input of precision and scale +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDREMOVEDELETEDIALOG_H +#define HDREMOVEDELETEDIALOG_H + +#include +#include + +enum ddRemoveDeleteButtons +{ + DD_REMOVE = 31000, + DD_DELETE = 32000 +}; + +class hdRemoveDeleteDialog : public wxDialog +{ + DECLARE_CLASS( hdRemoveDeleteDialog ) + DECLARE_EVENT_TABLE() +public: + hdRemoveDeleteDialog(); + hdRemoveDeleteDialog( const wxString &message, + const wxString &caption = _("Title"), + wxWindow *parent = NULL, + bool allowRemove = true + ); + ~hdRemoveDeleteDialog(); + + // Member initialization + void Init(); + + // Creation + bool Create( wxWindow *parent, + wxWindowID id, + const wxString &message, + const wxString &caption + ); + + // Creates the controls and sizers + void CreateControls(const wxString &message); + + //Buttons Events + void OnRemove(wxCommandEvent &WXUNUSED(event)); + void OnDelete(wxCommandEvent &WXUNUSED(event)); + void OnCancel(wxCommandEvent &WXUNUSED(event)); + +private: + bool allowRemoveButton; + wxBoxSizer *topSizer, *messageSizer, *buttonsSizer; + wxStaticText *staticText, *staticText2, *staticText3; + wxStaticLine *line; + wxButton *removeButton, *deleteButton, *cancelButton; + +}; +#endif + diff --git a/include/hotdraw/utilities/module.mk b/include/hotdraw/utilities/module.mk new file mode 100644 index 0000000..877f8e2 --- /dev/null +++ b/include/hotdraw/utilities/module.mk @@ -0,0 +1,25 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/hotdraw/utilities/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/hotdraw/utilities/hdArrayCollection.h \ + include/hotdraw/utilities/hdCollection.h \ + include/hotdraw/utilities/hdCollectionBase.h \ + include/hotdraw/utilities/hdGeometry.h \ + include/hotdraw/utilities/hdKeyEvent.h \ + include/hotdraw/utilities/hdMultiPosRect.h \ + include/hotdraw/utilities/hdMouseEvent.h \ + include/hotdraw/utilities/hdPoint.h \ + include/hotdraw/utilities/hdRect.h \ + include/hotdraw/utilities/hdRemoveDeleteDialog.h + +EXTRA_DIST += \ + include/hotdraw/utilities/module.mk diff --git a/include/images/aggregate-sm.png b/include/images/aggregate-sm.png new file mode 100644 index 0000000000000000000000000000000000000000..d4638196db2b44b40381d0866c46dec6ef3ec0ec GIT binary patch literal 351 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!O@L2`E0E65&tJ7_)yexGPv8G| z_QA*V4?kUc^y%v3&vW*<+<5Z&_S4Vzo`31+=y>?z%afO1pS}9}^7XgZufM%{^G*4^ zQ3X&xV@Z%-FoVOh8)-leXMsm#F_88EW4Dvpc0fjyr;B5V#O2;|o_q}o0xp5GA{Wfq z^FNl=q~y_|2vwo=E7$E&e?~DkHaDD!{+CQ42qbv zoagM_#;$Vl1nY~MjaByMC%#|bU(VR^npyvY*5cJbTU1M2BT7;dOH!?pi&B9UgOP!u zfv%yEu7P2Qk%5(ov6YF5wt=aYfq}(LRXG$5x%nxXX_XKS29{tAAk|g|W)KahriZQp PYGCkm^>bP0l+XkKG`EPw literal 0 HcmV?d00001 diff --git a/include/images/aggregate-sm.pngc b/include/images/aggregate-sm.pngc new file mode 100644 index 0000000..6a05b9a --- /dev/null +++ b/include/images/aggregate-sm.pngc @@ -0,0 +1,88 @@ +#ifndef AGGREGATE_SM_PNG_H +#define AGGREGATE_SM_PNG_H + +static const unsigned char aggregate_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x3c, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x6f, 0x6f, 0x6f, 0xaa, +0xaa, 0xaa, 0xc9, 0xdf, 0xf1, 0xcb, 0xdf, 0xf1, +0xcd, 0xe0, 0xf1, 0xcf, 0xe1, 0xf2, 0xd2, 0xe2, +0xf2, 0xd5, 0xe3, 0xf3, 0x9c, 0xbe, 0x44, 0xd8, +0xe4, 0xf3, 0xdb, 0xe5, 0xf3, 0xde, 0xe7, 0xf4, +0x88, 0x88, 0x88, 0xe1, 0xe8, 0xf4, 0xe4, 0xe9, +0xf5, 0xe6, 0xea, 0xf5, 0xe9, 0xeb, 0xf6, 0xeb, +0xeb, 0xf6, 0xec, 0xec, 0xf6, 0x23, 0xef, 0x32, +0x78, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x5a, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x8d, 0xce, 0x49, +0x0e, 0x80, 0x20, 0x10, 0x44, 0x51, 0x9a, 0x59, +0xa0, 0x98, 0xbc, 0xff, 0x5d, 0x05, 0x34, 0x74, +0xe2, 0xc2, 0x58, 0x3b, 0xde, 0xef, 0x05, 0x42, +0xfc, 0x1a, 0xdd, 0x93, 0xfb, 0xad, 0x94, 0x36, +0xd6, 0x79, 0xda, 0xa0, 0x8f, 0xb9, 0xc0, 0x60, +0x16, 0x44, 0x06, 0x3b, 0xee, 0x43, 0x4c, 0x0c, +0x0e, 0x08, 0x40, 0x66, 0xf0, 0xb3, 0xe7, 0xc2, +0x30, 0x72, 0x02, 0x2a, 0x43, 0x9c, 0xbd, 0xb6, +0x07, 0x24, 0xd1, 0xc8, 0x05, 0xe8, 0x7c, 0xb1, +0x7a, 0x3f, 0x37, 0xc8, 0xf7, 0xd7, 0xbf, 0x77, +0x01, 0x88, 0xeb, 0x03, 0x2f, 0xf0, 0x2a, 0xa3, +0xab, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, +0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *aggregate_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_aggregate_sm_png = new wxImage(); + if (!img_aggregate_sm_png || !img_aggregate_sm_png->IsOk()) + { + wxMemoryInputStream img_aggregate_sm_pngIS(aggregate_sm_png_data, sizeof(aggregate_sm_png_data)); + img_aggregate_sm_png->LoadFile(img_aggregate_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_aggregate_sm_png; +} +#define aggregate_sm_png_img aggregate_sm_png_img() + +static wxBitmap *aggregate_sm_png_bmp() +{ + static wxBitmap *bmp_aggregate_sm_png; + if (!bmp_aggregate_sm_png || !bmp_aggregate_sm_png->IsOk()) + bmp_aggregate_sm_png = new wxBitmap(*aggregate_sm_png_img); + return bmp_aggregate_sm_png; +} +#define aggregate_sm_png_bmp aggregate_sm_png_bmp() + +static wxIcon *aggregate_sm_png_ico() +{ + static wxIcon *ico_aggregate_sm_png; + if (!ico_aggregate_sm_png || !ico_aggregate_sm_png->IsOk()) + { + ico_aggregate_sm_png = new wxIcon(); + ico_aggregate_sm_png->CopyFromBitmap(*aggregate_sm_png_bmp); + } + return ico_aggregate_sm_png; +} +#define aggregate_sm_png_ico aggregate_sm_png_ico() + +#endif // AGGREGATE_SM_PNG_H diff --git a/include/images/aggregate.png b/include/images/aggregate.png new file mode 100644 index 0000000000000000000000000000000000000000..3145a3c2cb017abe29751d897a5dabdb1927e3fe GIT binary patch literal 374 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!cYsfbE0E65&p&zpo?!ty!lq*a_}6`IL4A7zhDN3XE)M-9L@rd$YLPv0mg18v+aP4Bu^K| z5Q)pN=RNrj8Hli4eBaV@Bjj1Z|H(=VxrAOm4bHVvQu-@)f9a}K^1ipf9-h&%{IpZ8 zqu`t3N>1J{6B31@Bo-Xdx#9m=>BeEL8;8|ytiP>ynC}Q!>*kAsP%U!5ToStqjZ{8ct0QT?5p>;OXk;vd$@?2>>(+pN;?k literal 0 HcmV?d00001 diff --git a/include/images/aggregate.pngc b/include/images/aggregate.pngc new file mode 100644 index 0000000..d66632c --- /dev/null +++ b/include/images/aggregate.pngc @@ -0,0 +1,91 @@ +#ifndef AGGREGATE_PNG_H +#define AGGREGATE_PNG_H + +static const unsigned char aggregate_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x4b, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x6f, 0x6f, 0x6f, 0xc9, +0xdf, 0xf1, 0xca, 0xdf, 0xf1, 0xcc, 0xe0, 0xf1, +0xcd, 0xe0, 0xf2, 0xcf, 0xe1, 0xf2, 0xd0, 0xe1, +0xf2, 0xd2, 0xe2, 0xf2, 0xd4, 0xe3, 0xf3, 0xd6, +0xe4, 0xf3, 0x9c, 0xbe, 0x44, 0xd8, 0xe5, 0xf3, +0xdb, 0xe5, 0xf3, 0xdd, 0xe6, 0xf4, 0x88, 0x88, +0x88, 0xdf, 0xe7, 0xf4, 0xe1, 0xe8, 0xf4, 0xe3, +0xe9, 0xf5, 0xe5, 0xe9, 0xf5, 0xe7, 0xea, 0xf5, +0xe8, 0xeb, 0xf5, 0xea, 0xeb, 0xf6, 0xeb, 0xec, +0xf6, 0xec, 0xec, 0xf6, 0x74, 0x44, 0xc1, 0xce, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x62, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x5d, 0xcf, 0x49, 0x0e, +0xc2, 0x30, 0x14, 0x04, 0xd1, 0xef, 0x84, 0x8c, +0xd8, 0x54, 0xe6, 0x70, 0xff, 0x93, 0x22, 0xa1, +0x0a, 0x12, 0xe9, 0xe5, 0x53, 0x6d, 0x3a, 0x22, +0x22, 0xfd, 0x16, 0xdf, 0xa5, 0xaa, 0xaa, 0x1f, +0x4d, 0xdb, 0xf5, 0xc3, 0x98, 0x84, 0xa7, 0xcb, +0x42, 0x7d, 0x41, 0x11, 0xec, 0x73, 0x79, 0x09, +0x0d, 0xf4, 0x90, 0x61, 0x12, 0x5a, 0x18, 0xa0, +0xc0, 0x2c, 0xd8, 0x4f, 0xf3, 0x22, 0xd8, 0xc3, +0x2a, 0xd8, 0xc3, 0x26, 0xd8, 0xaf, 0xdb, 0x2e, +0xd8, 0xc3, 0x21, 0xd8, 0xc3, 0x29, 0xd8, 0x1f, +0xe7, 0xfb, 0x7a, 0x77, 0x7b, 0xfb, 0xbf, 0x0f, +0x71, 0xc3, 0x06, 0xdd, 0x5a, 0xcc, 0x5e, 0xff, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, +0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *aggregate_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_aggregate_png = new wxImage(); + if (!img_aggregate_png || !img_aggregate_png->IsOk()) + { + wxMemoryInputStream img_aggregate_pngIS(aggregate_png_data, sizeof(aggregate_png_data)); + img_aggregate_png->LoadFile(img_aggregate_pngIS, wxBITMAP_TYPE_PNG); + } + return img_aggregate_png; +} +#define aggregate_png_img aggregate_png_img() + +static wxBitmap *aggregate_png_bmp() +{ + static wxBitmap *bmp_aggregate_png; + if (!bmp_aggregate_png || !bmp_aggregate_png->IsOk()) + bmp_aggregate_png = new wxBitmap(*aggregate_png_img); + return bmp_aggregate_png; +} +#define aggregate_png_bmp aggregate_png_bmp() + +static wxIcon *aggregate_png_ico() +{ + static wxIcon *ico_aggregate_png; + if (!ico_aggregate_png || !ico_aggregate_png->IsOk()) + { + ico_aggregate_png = new wxIcon(); + ico_aggregate_png->CopyFromBitmap(*aggregate_png_bmp); + } + return ico_aggregate_png; +} +#define aggregate_png_ico aggregate_png_ico() + +#endif // AGGREGATE_PNG_H diff --git a/include/images/aggregates.png b/include/images/aggregates.png new file mode 100644 index 0000000000000000000000000000000000000000..c75fa9a6aef0b002eae526bc8c255d2d342758fb GIT binary patch literal 373 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!eSlAhE0E65&tJ7_)yexGPv8G| z_QA*V4?kUc^y%v3&rK6z=j?O2@#OREr=RaV|I*RX@$ki$CojJ~d-e6@>u;}Le|z)h z+Z&6GN>3p^r=fwTu0yPeFo12S?wT^vIsF2|nt6l+l6adB)C z<}z7y@Bf-hE>AtD*>CmeFk(_C*%zgIQM=2R!UdQI; zn)ljQC|+QY^N>>F{hqo0AQ!Jd^&g-+?Xx#ia`1|v(thfF4Gv0d3lJWd^ zoGj2{)e_f;l9a@fRIB8oR3OD*WMF8ZYiOivU>IU#U}a)#Wn!XjU}|MxU@=ow4n;$5 meoAIqB}9XPC0GMUwUvPxM8m1+p=*E|7(8A5T-G@yGywqY%#nHk literal 0 HcmV?d00001 diff --git a/include/images/aggregates.pngc b/include/images/aggregates.pngc new file mode 100644 index 0000000..d594f85 --- /dev/null +++ b/include/images/aggregates.pngc @@ -0,0 +1,91 @@ +#ifndef AGGREGATES_PNG_H +#define AGGREGATES_PNG_H + +static const unsigned char aggregates_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x3f, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x6f, 0x6f, 0x6f, 0xaa, +0xaa, 0xaa, 0xc9, 0xdf, 0xf1, 0xcb, 0xdf, 0xf1, +0xcd, 0xe0, 0xf1, 0xcf, 0xe1, 0xf2, 0xd2, 0xe2, +0xf2, 0xd5, 0xe3, 0xf3, 0x82, 0x90, 0x5d, 0x9c, +0xbe, 0x44, 0xd8, 0xe4, 0xf3, 0xdb, 0xe5, 0xf3, +0xde, 0xe7, 0xf4, 0x88, 0x88, 0x88, 0xe1, 0xe8, +0xf4, 0xe4, 0xe9, 0xf5, 0xe6, 0xea, 0xf5, 0xe9, +0xeb, 0xf6, 0xeb, 0xeb, 0xf6, 0xec, 0xec, 0xf6, +0xec, 0x38, 0xb1, 0x22, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x6d, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x5d, 0xcf, 0x49, 0x16, 0x80, 0x20, 0x0c, 0x44, +0x41, 0x82, 0x13, 0x0a, 0x34, 0xa2, 0xde, 0xff, +0xac, 0xd2, 0x44, 0xe5, 0x49, 0x96, 0x3f, 0xb5, +0x48, 0x8c, 0x31, 0xa2, 0x63, 0xcd, 0x33, 0x32, +0x0c, 0xe3, 0x34, 0x2f, 0x4e, 0x5a, 0x58, 0xff, +0x46, 0xc6, 0xce, 0xc8, 0xd4, 0x19, 0x99, 0x3b, +0x23, 0x0b, 0xcd, 0xc6, 0xf1, 0x1a, 0x1c, 0x4d, +0x0d, 0x41, 0x83, 0xa7, 0x29, 0xde, 0x87, 0xa8, +0x21, 0xd0, 0x00, 0x1e, 0x48, 0x1a, 0x22, 0x0d, +0xf7, 0x69, 0xaf, 0xc1, 0x0a, 0x0d, 0x10, 0x81, +0xfc, 0x5e, 0x52, 0x0c, 0xf7, 0xf9, 0x78, 0xcf, +0x2f, 0x06, 0xd8, 0x81, 0xb3, 0xfd, 0x53, 0xf7, +0xe7, 0xf5, 0x05, 0xdb, 0x4e, 0xbf, 0x01, 0xda, +0xed, 0x04, 0x68, 0xe7, 0xfb, 0x5e, 0x1d, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *aggregates_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_aggregates_png = new wxImage(); + if (!img_aggregates_png || !img_aggregates_png->IsOk()) + { + wxMemoryInputStream img_aggregates_pngIS(aggregates_png_data, sizeof(aggregates_png_data)); + img_aggregates_png->LoadFile(img_aggregates_pngIS, wxBITMAP_TYPE_PNG); + } + return img_aggregates_png; +} +#define aggregates_png_img aggregates_png_img() + +static wxBitmap *aggregates_png_bmp() +{ + static wxBitmap *bmp_aggregates_png; + if (!bmp_aggregates_png || !bmp_aggregates_png->IsOk()) + bmp_aggregates_png = new wxBitmap(*aggregates_png_img); + return bmp_aggregates_png; +} +#define aggregates_png_bmp aggregates_png_bmp() + +static wxIcon *aggregates_png_ico() +{ + static wxIcon *ico_aggregates_png; + if (!ico_aggregates_png || !ico_aggregates_png->IsOk()) + { + ico_aggregates_png = new wxIcon(); + ico_aggregates_png->CopyFromBitmap(*aggregates_png_bmp); + } + return ico_aggregates_png; +} +#define aggregates_png_ico aggregates_png_ico() + +#endif // AGGREGATES_PNG_H diff --git a/include/images/back.png b/include/images/back.png new file mode 100644 index 0000000000000000000000000000000000000000..7fd33c39f5158295dd67feaeda6fc369d54c0b71 GIT binary patch literal 353 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaN3?zjj6;1;wxd5LK*K3#08UCNs($vDx)N=0p ze}*OohW`ujc?PRtckkRhx;us=vIXOXrp=H92 zoI2Jem~OGFN+-nnz<%tVzSs{=A-j*f;3 z4FwWP=}ivSEr+d2UtPHnpwX^qWMpEpWd@_3s1#SZQ%Z)5JM)yaORP-y-0|Ri#HP0N z)CVP1Rn-oW$-hbz*q^B`Et+A$$G~u^RqlFBU4tUfNvb8T5hW>!C8<`)MX5lF!N|bS zK-bVn*T68u$iT|P*viC2+rZSyz`$arsvL@j-29Zxv`UBu152<5kZLOfGl+&$(?iz) PH86O(`njxgN@xNAsu^zW literal 0 HcmV?d00001 diff --git a/include/images/back.pngc b/include/images/back.pngc new file mode 100644 index 0000000..96ca1c6 --- /dev/null +++ b/include/images/back.pngc @@ -0,0 +1,89 @@ +#ifndef BACK_PNG_H +#define BACK_PNG_H + +static const unsigned char back_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, +0x04, 0x03, 0x00, 0x00, 0x00, 0x12, 0x59, 0x20, +0xcb, 0x00, 0x00, 0x00, 0x1e, 0x50, 0x4c, 0x54, +0x45, 0xd6, 0xd3, 0xce, 0x31, 0xff, 0x9c, 0x84, +0x82, 0x84, 0x00, 0x82, 0x84, 0xce, 0xcf, 0xff, +0x00, 0x82, 0x00, 0x00, 0xff, 0x00, 0x00, 0x34, +0x39, 0x21, 0x20, 0x21, 0x42, 0x9a, 0xa5, 0xdd, +0x01, 0x71, 0xcc, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x87, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0x60, 0x20, 0x00, 0x84, 0x90, +0xd8, 0x8c, 0xc2, 0x48, 0x1c, 0x41, 0x57, 0x05, +0x84, 0x84, 0x48, 0x6a, 0x01, 0x42, 0xc2, 0xd1, +0xb5, 0x08, 0x21, 0x21, 0x92, 0xda, 0x8c, 0x90, +0x70, 0x74, 0xed, 0x50, 0x80, 0x4b, 0x88, 0xa4, +0xa4, 0x14, 0xc0, 0x25, 0xdc, 0xdc, 0xdc, 0xcc, +0x91, 0x24, 0x52, 0x3a, 0xc0, 0x1c, 0x36, 0x41, +0x41, 0x31, 0x20, 0x80, 0x70, 0x18, 0x22, 0x67, +0x82, 0x40, 0x3b, 0x84, 0xc3, 0x3a, 0x75, 0xea, +0xd4, 0xd0, 0x50, 0x28, 0x87, 0x21, 0x32, 0x32, +0x34, 0x34, 0xb4, 0x98, 0x01, 0x2e, 0x15, 0x1a, +0x0a, 0x77, 0x42, 0x64, 0x68, 0x44, 0x47, 0x03, +0x94, 0xad, 0xa4, 0x3a, 0x35, 0xbc, 0xdc, 0x48, +0x09, 0xe2, 0x06, 0x26, 0xa5, 0xca, 0xf0, 0x22, +0x25, 0x25, 0x25, 0x88, 0x14, 0x93, 0xfa, 0x74, +0x20, 0x07, 0xe6, 0x25, 0xa5, 0x72, 0x98, 0x38, +0x0e, 0x00, 0x00, 0xca, 0x85, 0x1e, 0xd7, 0x5c, +0x7e, 0x80, 0x21, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *back_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_back_png = new wxImage(); + if (!img_back_png || !img_back_png->IsOk()) + { + wxMemoryInputStream img_back_pngIS(back_png_data, sizeof(back_png_data)); + img_back_png->LoadFile(img_back_pngIS, wxBITMAP_TYPE_PNG); + } + return img_back_png; +} +#define back_png_img back_png_img() + +static wxBitmap *back_png_bmp() +{ + static wxBitmap *bmp_back_png; + if (!bmp_back_png || !bmp_back_png->IsOk()) + bmp_back_png = new wxBitmap(*back_png_img); + return bmp_back_png; +} +#define back_png_bmp back_png_bmp() + +static wxIcon *back_png_ico() +{ + static wxIcon *ico_back_png; + if (!ico_back_png || !ico_back_png->IsOk()) + { + ico_back_png = new wxIcon(); + ico_back_png->CopyFromBitmap(*back_png_bmp); + } + return ico_back_png; +} +#define back_png_ico back_png_ico() + +#endif // BACK_PNG_H diff --git a/include/images/backup.png b/include/images/backup.png new file mode 100644 index 0000000000000000000000000000000000000000..c5f0e424dd76a4ba20006c0f6b44dbde6e5d39b8 GIT binary patch literal 811 zcmV+`1JwM9P)dc!L4K6(3$`J?*IMc{`uJX`O)?8#qsXE?CG-Q<*Vf3px@t{$GmE=m^f*ZP-NN+h*#G$R|M%|x^wae0wd>)SDqsu zxh!VAgQeK==-L1J@0-x!^7;JZ^ZDEH_~iBboyg|@`t<+#?*H@CdcW7Pv9ZYO_kOhC zd%oD}_WRQA_}cRNf3o3xyxKc|#5{Y*fUx8K^wE5}+fkv=QlHXOoYYgA)l`?)Rh8L* zuH*9R*?qa(JblJJdC69i+kmX)%e;dB`0|s(9*s^+knIl``G+s2gb-L>=P zzJ8sz?DzcK^ZKB^?P7X{o80qM00001bW%=J06^y0W&i*H32;bRa{vGUNB{r;NB~C3 zYd!z~0OCnRK~xyiV_;-rW?^Lm0#+7gCPoGZ26hfkE^Z!PK7Ii~Az^l)fQYD=xP+vX zw2Z8ryn+Z&Kv79dTvD@Bzym1YY3*g}?(Od5>*wzt;0_W93<`D+arX@k4Ra5N3fQ_wxJO2XMZ3qi z!?eW4flP=`013DTdL_CiC8wmOrDtS<1hPO{vU7k6a`W#GdeIcIy5vZFg7|cFhtZnng9R*C3HntbYx+4WjbwdWNBu305UK! pFfA}SEif@uGBY|fG&(RgD=;-WFfhuORjdF2002ovPDHLkV1kn7y)^&; literal 0 HcmV?d00001 diff --git a/include/images/backup.pngc b/include/images/backup.pngc new file mode 100644 index 0000000..330a04c --- /dev/null +++ b/include/images/backup.pngc @@ -0,0 +1,146 @@ +#ifndef BACKUP_PNG_H +#define BACKUP_PNG_H + +static const unsigned char backup_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xfa, 0xf9, 0xf4, 0xe6, +0xde, 0xc0, 0xd3, 0xc5, 0x91, 0xc3, 0xb0, 0x6a, +0xb7, 0xa0, 0x4b, 0xaf, 0x96, 0x37, 0xd1, 0xc3, +0x8d, 0xb2, 0x9b, 0x3b, 0xc6, 0xb4, 0x69, 0xda, +0xcb, 0x8e, 0xe6, 0xdc, 0xa9, 0xed, 0xe8, 0xbd, +0xf2, 0xf2, 0xc2, 0xef, 0xec, 0xb7, 0xe4, 0xdf, +0xa2, 0xd6, 0xce, 0x88, 0xca, 0xbd, 0x6d, 0xbc, +0xad, 0x52, 0xaf, 0x98, 0x36, 0xc1, 0xad, 0x63, +0xdd, 0xd0, 0x99, 0xff, 0xfd, 0xee, 0xff, 0xfd, +0xe3, 0xfe, 0xf9, 0xd8, 0xf9, 0xf9, 0xd1, 0xf5, +0xf0, 0xc5, 0xf1, 0xee, 0xbc, 0xec, 0xe9, 0xb2, +0xe5, 0xe5, 0xab, 0xe4, 0xe1, 0xa0, 0xdf, 0xdf, +0x9b, 0xc7, 0xbc, 0x6a, 0xb0, 0x98, 0x3b, 0xe9, +0xe1, 0xb7, 0xfc, 0xf9, 0xd9, 0xfa, 0xf7, 0xcf, +0xf4, 0xf4, 0xc7, 0xee, 0xee, 0xbe, 0xed, 0xed, +0xbb, 0xec, 0xe9, 0xbf, 0xed, 0xed, 0xca, 0xf4, +0xf4, 0xdb, 0xfc, 0xf9, 0xf2, 0xb8, 0xa2, 0x4e, +0xac, 0x92, 0x30, 0xe3, 0xdb, 0xbd, 0xe9, 0xdc, +0xb9, 0xed, 0xe3, 0xbb, 0xf5, 0xf0, 0xd4, 0xf5, +0xf2, 0xd9, 0xfb, 0xfb, 0xf1, 0xfe, 0xfe, 0xfb, +0xf7, 0xf4, 0xe8, 0xf0, 0xed, 0xd2, 0xec, 0xe9, +0xc4, 0xea, 0xe2, 0xba, 0xe5, 0xdd, 0xc2, 0xf4, +0xea, 0xd8, 0xff, 0xf8, 0xf3, 0xff, 0xf7, 0xee, +0xfe, 0xf4, 0xd3, 0xf4, 0xec, 0xb5, 0xeb, 0xe1, +0x98, 0xe3, 0xd8, 0x83, 0xe0, 0xda, 0x7b, 0xdf, +0xda, 0x84, 0xe4, 0xe1, 0x96, 0xe8, 0xe3, 0xab, +0xf3, 0xe9, 0xda, 0x7f, 0x9e, 0xb9, 0x2c, 0x66, +0xbd, 0x83, 0xa5, 0xd8, 0xf2, 0xe8, 0xd9, 0xff, +0xfa, 0xef, 0x9b, 0xd0, 0xe1, 0xf2, 0xf9, 0xfc, +0xe3, 0xf3, 0xf9, 0xdb, 0xf1, 0xf8, 0xe4, 0xf5, +0xfb, 0x9d, 0xc8, 0xe6, 0xff, 0xfa, 0xf4, 0xff, +0xf9, 0xee, 0xff, 0xf3, 0xd3, 0x7a, 0xbf, 0xd7, +0xb1, 0xb1, 0xb1, 0xc8, 0xeb, 0xf7, 0x7e, 0xb4, +0xe0, 0x7b, 0xbe, 0xd8, 0xea, 0xf6, 0xfb, 0xd2, +0xee, 0xf8, 0xda, 0xf2, 0xfa, 0x7f, 0xb2, 0xe1, +0x7c, 0xbc, 0xda, 0x3b, 0x7f, 0xc4, 0x3c, 0x7b, +0xc8, 0x80, 0xb0, 0xe3, 0xfe, 0xf4, 0xd1, 0x7c, +0xba, 0xdb, 0x51, 0xa1, 0xd0, 0x52, 0x9f, 0xd2, +0x53, 0x9c, 0xd4, 0x53, 0x9a, 0xd5, 0x54, 0x97, +0xd7, 0x55, 0x95, 0xd9, 0x80, 0xae, 0xe3, 0xf2, +0xea, 0xd9, 0x7d, 0xb9, 0xdc, 0x3c, 0x7d, 0xc6, +0x3d, 0x79, 0xc9, 0x56, 0x92, 0xdb, 0x80, 0xac, +0xe5, 0xcb, 0xbc, 0x82, 0xff, 0xf8, 0xf2, 0x93, +0xc3, 0xe3, 0xe0, 0xf2, 0xf9, 0x56, 0x90, 0xdc, +0x81, 0xaa, 0xe6, 0xb0, 0x99, 0x39, 0xc2, 0xae, +0x65, 0xdb, 0xc6, 0x94, 0xed, 0xdd, 0xb5, 0xf3, +0xe6, 0xbe, 0x7e, 0x9d, 0xb7, 0xec, 0xf7, 0xfc, +0xdc, 0xf3, 0xfa, 0xa0, 0xbe, 0xed, 0x62, 0x7a, +0x86, 0x9b, 0xdc, 0xf3, 0x54, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0xe2, 0x49, 0x44, 0x41, 0x54, 0x18, +0xd3, 0x63, 0x60, 0x64, 0x62, 0x66, 0x61, 0x65, +0x03, 0x02, 0x56, 0x16, 0x66, 0x26, 0x46, 0x06, +0x06, 0x06, 0x76, 0x0e, 0x4e, 0x2e, 0x6e, 0x1e, +0x5e, 0x3e, 0x7e, 0x01, 0x41, 0x21, 0x61, 0x76, +0xa0, 0x80, 0x88, 0xa8, 0x98, 0xb8, 0x84, 0xa4, +0x94, 0xb4, 0x8c, 0xac, 0x9c, 0xbc, 0x82, 0x08, +0x50, 0x40, 0x51, 0x49, 0x4c, 0x5c, 0x59, 0x45, +0x55, 0x4d, 0x5d, 0x43, 0x53, 0x4b, 0x5b, 0x07, +0x28, 0xa0, 0xab, 0xa7, 0x6f, 0x60, 0x68, 0x64, +0x6c, 0x6c, 0x62, 0x6a, 0x66, 0x6e, 0xa1, 0x0b, +0x12, 0xb0, 0xb4, 0xb2, 0xb6, 0xb1, 0xb5, 0xb3, +0x77, 0x70, 0x74, 0x72, 0x76, 0x81, 0x08, 0xb8, +0x02, 0x05, 0xdc, 0xdc, 0xa1, 0xc0, 0x03, 0x28, +0xe0, 0x69, 0xed, 0x65, 0xeb, 0xee, 0xed, 0xee, +0xe3, 0xeb, 0xe7, 0xef, 0x1e, 0xe0, 0x0e, 0x12, +0x08, 0x0c, 0x0a, 0x76, 0x0f, 0x71, 0xf7, 0x0d, +0x0d, 0x0d, 0x73, 0x0f, 0x87, 0x0a, 0xd8, 0xba, +0x47, 0xb8, 0x47, 0x46, 0x85, 0x45, 0xbb, 0xc7, +0xb8, 0xc3, 0xb4, 0xc4, 0xc6, 0x81, 0x4c, 0x88, +0x4f, 0x00, 0x09, 0xb8, 0x06, 0x7a, 0x25, 0xba, +0x27, 0x25, 0xa7, 0xa4, 0xa6, 0xa5, 0x67, 0x64, +0x82, 0x04, 0xb2, 0x40, 0x5a, 0xb2, 0x73, 0x80, +0x0a, 0x72, 0xf3, 0xf2, 0x81, 0x02, 0x05, 0x56, +0x85, 0x40, 0x81, 0x22, 0x77, 0x9f, 0x62, 0x7f, +0xf7, 0x92, 0x52, 0x77, 0x06, 0xf6, 0xb2, 0xf2, +0x8a, 0xca, 0xaa, 0x6a, 0x77, 0xf7, 0x9a, 0xa8, +0x5a, 0xf7, 0xd2, 0x3a, 0x77, 0x06, 0xa8, 0xf7, +0xeb, 0x61, 0x0e, 0x03, 0x00, 0xab, 0xbd, 0x39, +0xe2, 0xd9, 0x12, 0x90, 0xf4, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x31, 0x2d, 0x30, 0x31, +0x2d, 0x32, 0x33, 0x54, 0x30, 0x33, 0x3a, 0x30, +0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x36, 0x3a, +0x30, 0x30, 0x44, 0xd4, 0x3d, 0x9a, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *backup_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_backup_png = new wxImage(); + if (!img_backup_png || !img_backup_png->IsOk()) + { + wxMemoryInputStream img_backup_pngIS(backup_png_data, sizeof(backup_png_data)); + img_backup_png->LoadFile(img_backup_pngIS, wxBITMAP_TYPE_PNG); + } + return img_backup_png; +} +#define backup_png_img backup_png_img() + +static wxBitmap *backup_png_bmp() +{ + static wxBitmap *bmp_backup_png; + if (!bmp_backup_png || !bmp_backup_png->IsOk()) + bmp_backup_png = new wxBitmap(*backup_png_img); + return bmp_backup_png; +} +#define backup_png_bmp backup_png_bmp() + +static wxIcon *backup_png_ico() +{ + static wxIcon *ico_backup_png; + if (!ico_backup_png || !ico_backup_png->IsOk()) + { + ico_backup_png = new wxIcon(); + ico_backup_png->CopyFromBitmap(*backup_png_bmp); + } + return ico_backup_png; +} +#define backup_png_ico backup_png_ico() + +#endif // BACKUP_PNG_H diff --git a/include/images/baddatabase.png b/include/images/baddatabase.png new file mode 100644 index 0000000000000000000000000000000000000000..159ddc786ea35fedb00e9257d852fd18b41aa437 GIT binary patch literal 788 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl481n*rLR^8|!yB@;FYsPJ&HUJw z%o}IBpWRvc_T|1$pANl$v;E2aMW^=W?pYhOeumk_!@URBraZea=l|b#|NlPz`}5|{ zpBKM=IQsG3o;NQyJ$<_R$-@Qr@6SHICu`$Ot5=V9{`!9Y%a`Nt-tBw)cK6%2r@nl- z{paVW9gFDA58FSosUKJAQ^;(0Hl2dnB&?`e9Zt^LZ_ifBA6o z169?R+B&zy#J8oX9@G{&YMh%=T1`2{mLJiCzwvL>2>S4={E+nQaGT z-1T&E43W5;oWQ{3rk19Vkd)HEBo<~?#^6%!p9tpu%vd{IF`Nl{tm%Sq{S zuLY$bP0l+XkKXn=Y> literal 0 HcmV?d00001 diff --git a/include/images/baddatabase.pngc b/include/images/baddatabase.pngc new file mode 100644 index 0000000..6d997e3 --- /dev/null +++ b/include/images/baddatabase.pngc @@ -0,0 +1,143 @@ +#ifndef BADDATABASE_PNG_H +#define BADDATABASE_PNG_H + +static const unsigned char baddatabase_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x6e, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc3, 0xb0, 0x6a, 0xb7, +0xa0, 0x4b, 0xaf, 0x96, 0x37, 0xc6, 0xb4, 0x69, +0xd8, 0xcd, 0x8b, 0xe6, 0xdc, 0xa9, 0xed, 0xe9, +0xbe, 0xf2, 0xf2, 0xc2, 0xef, 0xec, 0xb7, 0xe4, +0xdf, 0xa2, 0xca, 0xbd, 0x6d, 0xbc, 0xad, 0x52, +0xaf, 0x98, 0x36, 0xd1, 0xc3, 0x8d, 0xc1, 0xad, +0x64, 0xe6, 0xd0, 0x9c, 0xff, 0xfd, 0xee, 0xff, +0xfd, 0xe3, 0xfd, 0xf9, 0xd9, 0xf9, 0xf9, 0xd1, +0xf5, 0xf0, 0xc5, 0xf1, 0xee, 0xbc, 0xec, 0xe9, +0xb2, 0xe5, 0xe5, 0xab, 0xe4, 0xe1, 0xa0, 0xdf, +0xdf, 0x9b, 0xc7, 0xbc, 0x6a, 0xb1, 0x99, 0x3a, +0xea, 0xe2, 0xb9, 0xfa, 0xf7, 0xcf, 0xf4, 0xf4, +0xc7, 0xee, 0xee, 0xbe, 0xed, 0xed, 0xbb, 0xed, +0xed, 0xca, 0xf4, 0xf4, 0xdb, 0xfc, 0xf9, 0xf2, +0xb8, 0xa2, 0x4e, 0xac, 0x92, 0x30, 0xe3, 0xdb, +0xbd, 0xe9, 0xdc, 0xb9, 0xed, 0xe3, 0xbb, 0xf5, +0xf0, 0xd4, 0xf5, 0xf2, 0xd9, 0xfb, 0xfb, 0xf1, +0xfe, 0xfe, 0xfb, 0xf7, 0xf4, 0xe8, 0xf0, 0xed, +0xd2, 0xec, 0xe9, 0xc4, 0xe5, 0xdd, 0xc2, 0xf4, +0xea, 0xd8, 0xff, 0xf8, 0xf3, 0xff, 0xf7, 0xee, +0xfe, 0xf4, 0xd3, 0xf4, 0xec, 0xb5, 0xeb, 0xe1, +0x98, 0xd3, 0x67, 0x3f, 0xc8, 0x0b, 0x07, 0xc5, +0x00, 0x00, 0xd3, 0x5b, 0x44, 0xb1, 0x77, 0x27, +0xf3, 0xe9, 0xda, 0xf6, 0xee, 0xb4, 0xd5, 0x5d, +0x3f, 0xd5, 0x27, 0x27, 0xf4, 0x6b, 0x6b, 0xf5, +0x6c, 0x6d, 0xf3, 0x66, 0x66, 0xe0, 0x3a, 0x3a, +0xf2, 0xe8, 0xd9, 0xff, 0xfa, 0xef, 0xe9, 0xaf, +0x84, 0xd3, 0x1e, 0x1e, 0xf5, 0x71, 0x71, 0xf2, +0x5f, 0x5f, 0xf1, 0x57, 0x58, 0xe2, 0x35, 0x35, +0xd8, 0x55, 0x55, 0xff, 0xfa, 0xf4, 0xff, 0xf9, +0xee, 0xff, 0xf4, 0xd2, 0xda, 0x6d, 0x55, 0xdf, +0x3c, 0x3c, 0xed, 0x57, 0x58, 0xdd, 0x2e, 0x2e, +0xef, 0x4e, 0x4e, 0xe9, 0x3e, 0x3e, 0xcd, 0x22, +0x22, 0xcd, 0x1a, 0x14, 0xec, 0x49, 0x49, 0xee, +0x45, 0x45, 0xda, 0x22, 0x22, 0xe0, 0x77, 0x77, +0xd9, 0x96, 0x57, 0xbc, 0x3d, 0x15, 0xeb, 0xe3, +0x98, 0xd1, 0x58, 0x34, 0xdf, 0x28, 0x29, 0xd1, +0x4c, 0x39, 0xaf, 0x80, 0x2a, 0xf2, 0xea, 0xd9, +0xf3, 0xe9, 0xb6, 0xec, 0xe7, 0x96, 0xcc, 0x3a, +0x21, 0xcf, 0x4a, 0x32, 0xe0, 0xaa, 0x7f, 0xcb, +0xbc, 0x82, 0xe2, 0x2b, 0x2b, 0xea, 0x33, 0x34, +0xdb, 0x1a, 0x1b, 0xc8, 0x4d, 0x2f, 0xdb, 0xc6, +0x94, 0xed, 0xdd, 0xb5, 0xf3, 0xe6, 0xbe, 0xf3, +0xeb, 0xaf, 0xe9, 0xe1, 0x93, 0xe0, 0x25, 0x25, +0xe9, 0x2b, 0x2c, 0xda, 0x16, 0x17, 0xb6, 0x66, +0x25, 0xc1, 0x2b, 0x14, 0xca, 0x4f, 0x3b, 0xc6, +0xe4, 0x7e, 0xce, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0xdd, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, +0x60, 0x00, 0x02, 0x46, 0x26, 0x66, 0x20, 0x60, +0x62, 0x64, 0x80, 0x02, 0x16, 0x56, 0x36, 0x76, +0x0e, 0x4e, 0x2e, 0x56, 0x6e, 0x1e, 0x5e, 0x3e, +0x20, 0x97, 0x5f, 0x40, 0x50, 0x48, 0x58, 0x44, +0x54, 0x4c, 0x5c, 0x42, 0x52, 0x4a, 0x9a, 0x1f, +0x28, 0x20, 0x23, 0x0b, 0x14, 0x90, 0x93, 0x57, +0x50, 0x64, 0x57, 0x52, 0x56, 0x51, 0x05, 0x0a, +0xa8, 0xa9, 0x6b, 0x68, 0x6a, 0x69, 0xeb, 0xe8, +0xe8, 0xea, 0xe9, 0x1b, 0xc8, 0xaa, 0x81, 0x04, +0x0c, 0x8d, 0x8c, 0x4d, 0x4c, 0xcd, 0xcc, 0x2d, +0x2c, 0xad, 0xac, 0xac, 0x6d, 0xc0, 0x02, 0xb6, +0x40, 0x01, 0x3b, 0x7b, 0x07, 0x47, 0x27, 0x67, +0x17, 0x4b, 0xb0, 0x80, 0xab, 0xb1, 0x9b, 0xa9, +0xbb, 0x87, 0xa7, 0x93, 0xb3, 0x97, 0xb7, 0x8f, +0x2f, 0x58, 0xc0, 0xcf, 0x3f, 0x20, 0x30, 0xc8, +0x31, 0xd8, 0x2a, 0x24, 0x34, 0x2c, 0x1c, 0x2a, +0x60, 0x2a, 0x60, 0x6f, 0x15, 0x11, 0x11, 0x19, +0x15, 0x1d, 0x03, 0xd3, 0x62, 0x67, 0x1e, 0xeb, +0x11, 0x1a, 0x15, 0x1d, 0x07, 0x31, 0xd4, 0xcf, +0x2d, 0xc0, 0x2c, 0x3e, 0x21, 0x24, 0x2a, 0x31, +0x29, 0x19, 0x2c, 0x90, 0x02, 0xd4, 0x92, 0x9a, +0x16, 0x9b, 0x6e, 0x95, 0x91, 0x09, 0x76, 0x47, +0x96, 0x91, 0xb1, 0xbf, 0xa9, 0x59, 0x7c, 0x7a, +0x76, 0x4e, 0x6e, 0x1e, 0x48, 0x80, 0x41, 0x86, +0x3f, 0xbf, 0xa0, 0xb0, 0xa8, 0x38, 0xbd, 0xa4, +0xb4, 0x2c, 0x0e, 0xea, 0x5d, 0xb0, 0xf7, 0xcb, +0x2b, 0xac, 0x2a, 0x81, 0x6c, 0x00, 0x52, 0x67, +0x2e, 0x92, 0x9a, 0x81, 0x8a, 0xbb, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *baddatabase_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_baddatabase_png = new wxImage(); + if (!img_baddatabase_png || !img_baddatabase_png->IsOk()) + { + wxMemoryInputStream img_baddatabase_pngIS(baddatabase_png_data, sizeof(baddatabase_png_data)); + img_baddatabase_png->LoadFile(img_baddatabase_pngIS, wxBITMAP_TYPE_PNG); + } + return img_baddatabase_png; +} +#define baddatabase_png_img baddatabase_png_img() + +static wxBitmap *baddatabase_png_bmp() +{ + static wxBitmap *bmp_baddatabase_png; + if (!bmp_baddatabase_png || !bmp_baddatabase_png->IsOk()) + bmp_baddatabase_png = new wxBitmap(*baddatabase_png_img); + return bmp_baddatabase_png; +} +#define baddatabase_png_bmp baddatabase_png_bmp() + +static wxIcon *baddatabase_png_ico() +{ + static wxIcon *ico_baddatabase_png; + if (!ico_baddatabase_png || !ico_baddatabase_png->IsOk()) + { + ico_baddatabase_png = new wxIcon(); + ico_baddatabase_png->CopyFromBitmap(*baddatabase_png_bmp); + } + return ico_baddatabase_png; +} +#define baddatabase_png_ico baddatabase_png_ico() + +#endif // BADDATABASE_PNG_H diff --git a/include/images/cast-sm.png b/include/images/cast-sm.png new file mode 100644 index 0000000000000000000000000000000000000000..52b775538d0fa24e280d595b8d08eccad868fc9f GIT binary patch literal 385 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}Y=BRQE0Es3wsvWsO@89kNdH}P zr(Zj=J^k)|iTb?irAz-G-&J<+f#RxF|M#vbc=$+vQ&0wv;W_|ExmT_|A+T&_wWDz^l9?5Xa7&_?Wrr6y|pSR3}^vkNswPKgTu2MX+REV zfk$L9koEv$x0Bg+Kt{Bui(`ny<*9wA#T*O-oVD2&UYWh>`2YH4>$a5LxjT3A$!C8<`)MX5lF!N|bSK-bVn*T68u$iT|P*viC2 z+rZSyz`$arsvL@j-29Zxv`UBu152<5kZLOfGl+&$(?iz)H86O(`njxgN@xNAxrdn& literal 0 HcmV?d00001 diff --git a/include/images/cast-sm.pngc b/include/images/cast-sm.pngc new file mode 100644 index 0000000..3ff57a4 --- /dev/null +++ b/include/images/cast-sm.pngc @@ -0,0 +1,93 @@ +#ifndef CAST_SM_PNG_H +#define CAST_SM_PNG_H + +static const unsigned char cast_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x5d, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xbb, 0xad, 0x7d, 0xa5, +0x8e, 0x3c, 0x6f, 0x61, 0x95, 0x59, 0x4f, 0xba, +0x9d, 0x97, 0xd6, 0xc4, 0xb7, 0x67, 0xdd, 0xdf, +0x18, 0x7f, 0x6e, 0x7b, 0xa5, 0xa5, 0xff, 0xc7, +0xba, 0x76, 0xde, 0xe0, 0x21, 0xaa, 0xaa, 0xff, +0xbd, 0xac, 0x70, 0xe1, 0xe2, 0x2f, 0xb1, 0xb1, +0xff, 0xe4, 0xe5, 0x3f, 0xba, 0xba, 0xff, 0xc5, +0xb7, 0x60, 0xe7, 0xe8, 0x51, 0xc3, 0xc3, 0xff, +0xea, 0xea, 0x64, 0xcd, 0xcd, 0xff, 0xed, 0xed, +0x75, 0xd6, 0xd6, 0xff, 0xf0, 0xef, 0x86, 0xdf, +0xdf, 0xff, 0xf2, 0xf2, 0x93, 0xe6, 0xe6, 0xff, +0xca, 0xbd, 0x8c, 0x7e, 0x70, 0x9b, 0xb5, 0x7a, +0x52, 0x56, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x5b, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x95, 0x8e, +0xcb, 0x16, 0x40, 0x30, 0x10, 0x43, 0x2b, 0x06, +0xa1, 0xd4, 0x9b, 0xaa, 0xc7, 0xff, 0x7f, 0xa6, +0xae, 0xb4, 0x76, 0xdc, 0xdd, 0x9d, 0x93, 0xc9, +0x89, 0x52, 0xdf, 0x48, 0x90, 0x4a, 0x16, 0x79, +0x8e, 0x82, 0xa5, 0x04, 0xaf, 0xa0, 0x35, 0xeb, +0x70, 0x68, 0x60, 0x8c, 0x61, 0x1b, 0x7e, 0xd0, +0x79, 0xd8, 0xcb, 0x13, 0x19, 0x00, 0x8c, 0x9c, +0x44, 0xa2, 0x5e, 0xcc, 0x5c, 0x3c, 0xa1, 0x06, +0x2b, 0xad, 0xb5, 0x71, 0x62, 0xa3, 0x73, 0xf1, +0x12, 0xec, 0x3c, 0x5e, 0xcb, 0x4e, 0x5c, 0x2f, +0xff, 0xc7, 0x0d, 0xc0, 0x41, 0x03, 0x5f, 0xb6, +0xeb, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *cast_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_cast_sm_png = new wxImage(); + if (!img_cast_sm_png || !img_cast_sm_png->IsOk()) + { + wxMemoryInputStream img_cast_sm_pngIS(cast_sm_png_data, sizeof(cast_sm_png_data)); + img_cast_sm_png->LoadFile(img_cast_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_cast_sm_png; +} +#define cast_sm_png_img cast_sm_png_img() + +static wxBitmap *cast_sm_png_bmp() +{ + static wxBitmap *bmp_cast_sm_png; + if (!bmp_cast_sm_png || !bmp_cast_sm_png->IsOk()) + bmp_cast_sm_png = new wxBitmap(*cast_sm_png_img); + return bmp_cast_sm_png; +} +#define cast_sm_png_bmp cast_sm_png_bmp() + +static wxIcon *cast_sm_png_ico() +{ + static wxIcon *ico_cast_sm_png; + if (!ico_cast_sm_png || !ico_cast_sm_png->IsOk()) + { + ico_cast_sm_png = new wxIcon(); + ico_cast_sm_png->CopyFromBitmap(*cast_sm_png_bmp); + } + return ico_cast_sm_png; +} +#define cast_sm_png_ico cast_sm_png_ico() + +#endif // CAST_SM_PNG_H diff --git a/include/images/cast.png b/include/images/cast.png new file mode 100644 index 0000000000000000000000000000000000000000..2be7f3742a760faa7709052669f444ba8949c330 GIT binary patch literal 426 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}a)3{WE0A8=XLIY~`bhs>bEjXs zdtc(<#)_V{^GlchKee~#-UGQ6EB@bqsIhL{|A&u_H*fy`d-wi-{Mh^W@&C`CroDLaf6w;E(Q{(sfz~jV1o;Is zI6S+N2IO!SctjQhX%8@VJDF_ zw)Vt7;XUhu?aCg8-q)T#djsp?1vQn0(#HZ{&avK>G;7M|Kezi*1J|9@wM@A8GIu5a z7k@SvKA%lLfi6)kag8WRNi0dVN-jzTQVd20h6cKZM!E)uAw~vPCdO7KCfWw3Rt5$Z sGgakKH00)|WTsU@G#FTdHGouG8JIydoSGiG2B?9-)78&qol`;+06z@3hyVZp literal 0 HcmV?d00001 diff --git a/include/images/cast.pngc b/include/images/cast.pngc new file mode 100644 index 0000000..2f43834 --- /dev/null +++ b/include/images/cast.pngc @@ -0,0 +1,98 @@ +#ifndef CAST_PNG_H +#define CAST_PNG_H + +static const unsigned char cast_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xa5, 0x8e, 0x3c, 0xda, +0xd1, 0xaf, 0x59, 0x4f, 0xba, 0x9d, 0x97, 0xd6, +0xdd, 0xdf, 0x18, 0xc1, 0xb1, 0x78, 0x8c, 0x86, +0xcf, 0xa5, 0xa5, 0xff, 0xca, 0xbd, 0x8c, 0xde, +0xe0, 0x1e, 0xa8, 0xa8, 0xff, 0xdf, 0xe1, 0x28, +0xae, 0xae, 0xff, 0xe1, 0xe3, 0x33, 0xb3, 0xb3, +0xff, 0xe4, 0xe5, 0x3f, 0xba, 0xba, 0xff, 0xe6, +0xe7, 0x4c, 0xc1, 0xc1, 0xff, 0xe8, 0xe9, 0x5a, +0xc8, 0xc8, 0xff, 0xeb, 0xeb, 0x68, 0xd0, 0xd0, +0xff, 0xed, 0xed, 0x75, 0xd6, 0xd6, 0xff, 0xef, +0xef, 0x82, 0xde, 0xde, 0xff, 0xf1, 0xf1, 0x8d, +0xe3, 0xe3, 0xff, 0xf3, 0xf2, 0x96, 0xe8, 0xe8, +0xff, 0xbc, 0xb7, 0xe3, 0x5b, 0x9c, 0x5d, 0x5f, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x7e, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x6d, 0xcf, 0xdb, 0x12, +0x82, 0x30, 0x10, 0x03, 0xd0, 0xc6, 0xd5, 0x0d, +0x97, 0x22, 0x22, 0x88, 0x48, 0xb9, 0xf8, 0xff, +0x5f, 0x69, 0xc1, 0x16, 0xfb, 0xe0, 0x79, 0x4b, +0xa6, 0x33, 0xcd, 0x1a, 0xf3, 0x1f, 0x4e, 0x46, +0xe4, 0x9c, 0xe4, 0x8b, 0x32, 0xcb, 0x24, 0xc6, +0x1c, 0x45, 0xa1, 0x2c, 0x4b, 0x39, 0xb2, 0xb5, +0x56, 0x59, 0x55, 0xb1, 0xc0, 0xd5, 0x53, 0xd6, +0x75, 0x28, 0x70, 0xdb, 0x28, 0x9b, 0xe6, 0x5b, +0xe0, 0xbe, 0x53, 0xb6, 0xad, 0xc8, 0xfe, 0x13, +0xbc, 0xae, 0x53, 0x3e, 0x76, 0xe1, 0x55, 0xdf, +0x2b, 0x9f, 0x9b, 0xb0, 0x05, 0xc3, 0xa0, 0x7c, +0x79, 0x71, 0x1b, 0xc6, 0x51, 0xe9, 0x9c, 0x3b, +0xb6, 0x62, 0x9a, 0x94, 0xf3, 0xfc, 0xdb, 0x8e, +0x65, 0x51, 0xae, 0xc9, 0x2d, 0x39, 0x60, 0xde, +0xe9, 0x6d, 0xa9, 0x0f, 0xf4, 0x4f, 0x06, 0x44, +0x0e, 0x4c, 0xb2, 0xf9, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *cast_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_cast_png = new wxImage(); + if (!img_cast_png || !img_cast_png->IsOk()) + { + wxMemoryInputStream img_cast_pngIS(cast_png_data, sizeof(cast_png_data)); + img_cast_png->LoadFile(img_cast_pngIS, wxBITMAP_TYPE_PNG); + } + return img_cast_png; +} +#define cast_png_img cast_png_img() + +static wxBitmap *cast_png_bmp() +{ + static wxBitmap *bmp_cast_png; + if (!bmp_cast_png || !bmp_cast_png->IsOk()) + bmp_cast_png = new wxBitmap(*cast_png_img); + return bmp_cast_png; +} +#define cast_png_bmp cast_png_bmp() + +static wxIcon *cast_png_ico() +{ + static wxIcon *ico_cast_png; + if (!ico_cast_png || !ico_cast_png->IsOk()) + { + ico_cast_png = new wxIcon(); + ico_cast_png->CopyFromBitmap(*cast_png_bmp); + } + return ico_cast_png; +} +#define cast_png_ico cast_png_ico() + +#endif // CAST_PNG_H diff --git a/include/images/casts.png b/include/images/casts.png new file mode 100644 index 0000000000000000000000000000000000000000..09eb65af02c66bd64ab3405c592efe4d90d41c98 GIT binary patch literal 402 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}RDe&2E08|5w`XaeOt_Z}!tZ4Ap#oci#Q{=SXoPoCQE-(e zAO8R0ecP*7DQD0A|MY3{+qb3HuKmA%|NpaR|1ZhRj0c*|SQ6wH%;50sMjDXAS>O>_ z45U54*zIJt9gval>Eak7ak=#TZN6p&0hSA?yGp&5X6Q%he*0e^ToZZWNTsr+b)t)l zj9%4Lq4qZOwfFDczc{Oq<6)rmksEJ&nEiOFw@y3DVz*ZO=8+TAZ=JQC&Ch=IlJ%q0 zn#a%d$On5}eQ!_{`O0<1PkWs^`g)O!!JAm-u{;Xg4zyae#5JNMC9x#cD!C{XNHG{0 z7#ipr8tEDsh8P)GnHXD{m}ncAS{WEv%v6;_(U6;;l9^Ts(O_T+)&Np%Wnc!;aB6z! Q8lVOSPgg&ebxsLQ09Xf~fdBvi literal 0 HcmV?d00001 diff --git a/include/images/casts.pngc b/include/images/casts.pngc new file mode 100644 index 0000000..9ce78a7 --- /dev/null +++ b/include/images/casts.pngc @@ -0,0 +1,95 @@ +#ifndef CASTS_PNG_H +#define CASTS_PNG_H + +static const unsigned char casts_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x5a, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xca, 0xbd, 0x8c, 0xa5, +0x8e, 0x3c, 0x7e, 0x70, 0x9b, 0x59, 0x4f, 0xba, +0x9d, 0x97, 0xd6, 0xdd, 0xdf, 0x18, 0x7f, 0x6e, +0x7b, 0xa5, 0xa5, 0xff, 0xde, 0xe0, 0x21, 0x95, +0x81, 0x56, 0x6f, 0x61, 0x95, 0xe1, 0xe2, 0x2f, +0xbe, 0xb1, 0x37, 0xe4, 0xe5, 0x3f, 0xbf, 0xb2, +0x3d, 0xaa, 0xaa, 0xff, 0xb1, 0xb1, 0xff, 0xba, +0xba, 0xff, 0xc5, 0xb7, 0x60, 0xe7, 0xe8, 0x51, +0xc3, 0xc3, 0xff, 0xf0, 0xef, 0x86, 0xea, 0xea, +0x64, 0xcd, 0xcd, 0xff, 0xf2, 0xf2, 0x93, 0xed, +0xed, 0x75, 0xd6, 0xd6, 0xff, 0xdf, 0xdf, 0xff, +0xe6, 0xe6, 0xff, 0xd2, 0x1c, 0x99, 0x5f, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x6f, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x75, 0xcf, 0xdb, 0x0e, 0x83, +0x20, 0x10, 0x04, 0xd0, 0x65, 0xba, 0x75, 0x4a, +0xa5, 0x68, 0x2f, 0x5a, 0x2d, 0xf6, 0xff, 0x7f, +0x53, 0x7c, 0x59, 0xd0, 0xc4, 0x79, 0x23, 0x39, +0x3b, 0x61, 0x44, 0x44, 0x1c, 0x2e, 0x7a, 0x95, +0x12, 0x87, 0x86, 0x37, 0xad, 0xdf, 0xde, 0xdf, +0xd1, 0x9a, 0x71, 0x08, 0xe1, 0x51, 0x1b, 0xc4, +0xd8, 0xed, 0x8c, 0x03, 0x4e, 0x0c, 0x7b, 0xb5, +0x96, 0xcd, 0x04, 0x3e, 0xad, 0x17, 0xd9, 0xc4, +0xc8, 0x97, 0xda, 0xcd, 0x3b, 0x9b, 0x0f, 0x07, +0xd5, 0xd2, 0x3b, 0xe2, 0xcb, 0x29, 0xc7, 0xcc, +0x8c, 0x1f, 0x53, 0x4a, 0xd5, 0xef, 0x30, 0x72, +0x59, 0xea, 0x45, 0x98, 0xf9, 0x3f, 0x2c, 0xdc, +0x2f, 0x2e, 0x59, 0x01, 0x53, 0xb2, 0x04, 0x9e, +0x04, 0xe2, 0x51, 0xb7, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *casts_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_casts_png = new wxImage(); + if (!img_casts_png || !img_casts_png->IsOk()) + { + wxMemoryInputStream img_casts_pngIS(casts_png_data, sizeof(casts_png_data)); + img_casts_png->LoadFile(img_casts_pngIS, wxBITMAP_TYPE_PNG); + } + return img_casts_png; +} +#define casts_png_img casts_png_img() + +static wxBitmap *casts_png_bmp() +{ + static wxBitmap *bmp_casts_png; + if (!bmp_casts_png || !bmp_casts_png->IsOk()) + bmp_casts_png = new wxBitmap(*casts_png_img); + return bmp_casts_png; +} +#define casts_png_bmp casts_png_bmp() + +static wxIcon *casts_png_ico() +{ + static wxIcon *ico_casts_png; + if (!ico_casts_png || !ico_casts_png->IsOk()) + { + ico_casts_png = new wxIcon(); + ico_casts_png->CopyFromBitmap(*casts_png_bmp); + } + return ico_casts_png; +} +#define casts_png_ico casts_png_ico() + +#endif // CASTS_PNG_H diff --git a/include/images/catalog-sm.png b/include/images/catalog-sm.png new file mode 100644 index 0000000000000000000000000000000000000000..b6f742f61d75d43845cf2b3bbe9885f981e33fde GIT binary patch literal 328 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPHF4e$wZ1=8!M+$i_lySw-Qj?VvE zoBspB#=3uh|NE`0`1kMstd#}-mS+81ko0d}+&})e^0hz>j3q&S!3+-1Zlr-YN#5=* zY>8<*Kr);K9+AaB+5?Q;PG;Ky8Lpl#jv*Y^lM@bbONcJyQB-E^Xz1c{@zBuFgI1*bQWl! zYKdz^NlIc#s#S7PDv)9@GB7mIH8j#SFbpv=ure{WGBMFMFtsu;u$ZYThoT`jKP5A* h5~9Jt608BF+RDHTqT$r^&^15}44$rjF6*2UngA=|YX|@U literal 0 HcmV?d00001 diff --git a/include/images/catalog-sm.pngc b/include/images/catalog-sm.pngc new file mode 100644 index 0000000..78da4ad --- /dev/null +++ b/include/images/catalog-sm.pngc @@ -0,0 +1,85 @@ +#ifndef CATALOG_SM_PNG_H +#define CATALOG_SM_PNG_H + +static const unsigned char catalog_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x2d, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xaf, 0x94, 0xd8, 0x77, +0x49, 0xbd, 0xbb, 0x8d, 0xff, 0xb8, 0x89, 0xff, +0xb5, 0x83, 0xff, 0xff, 0xff, 0xff, 0xb1, 0x7e, +0xfe, 0xfd, 0xff, 0x4e, 0xae, 0x78, 0xfe, 0xfe, +0xff, 0x9a, 0xa9, 0x70, 0xfe, 0xa5, 0x6a, 0xfe, +0xa0, 0x62, 0xfe, 0x9e, 0x5e, 0xfe, 0x0f, 0xed, +0x1f, 0x7d, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, 0x06, +0x61, 0x66, 0xb8, 0x7d, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x45, 0x49, 0x44, 0x41, +0x54, 0x08, 0xd7, 0x63, 0x60, 0xc0, 0x0b, 0x18, +0x15, 0xa1, 0x0c, 0x21, 0x23, 0x01, 0x88, 0x80, +0x8a, 0x0a, 0x44, 0x48, 0x28, 0x28, 0x29, 0x08, +0x24, 0xc4, 0xa8, 0xae, 0xd6, 0xa6, 0x0e, 0x12, +0x62, 0x9a, 0x94, 0xb1, 0x22, 0x69, 0x12, 0x48, +0x44, 0x5b, 0xad, 0x4d, 0x1b, 0xac, 0x48, 0xe8, +0x50, 0xd2, 0x21, 0xb0, 0x36, 0x46, 0x5d, 0x5d, +0xa8, 0x41, 0x42, 0x8f, 0x04, 0xd0, 0x4c, 0x46, +0x05, 0x00, 0x98, 0x6b, 0x0a, 0x8b, 0x0f, 0x84, +0xa2, 0xcd, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, +0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *catalog_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_catalog_sm_png = new wxImage(); + if (!img_catalog_sm_png || !img_catalog_sm_png->IsOk()) + { + wxMemoryInputStream img_catalog_sm_pngIS(catalog_sm_png_data, sizeof(catalog_sm_png_data)); + img_catalog_sm_png->LoadFile(img_catalog_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_catalog_sm_png; +} +#define catalog_sm_png_img catalog_sm_png_img() + +static wxBitmap *catalog_sm_png_bmp() +{ + static wxBitmap *bmp_catalog_sm_png; + if (!bmp_catalog_sm_png || !bmp_catalog_sm_png->IsOk()) + bmp_catalog_sm_png = new wxBitmap(*catalog_sm_png_img); + return bmp_catalog_sm_png; +} +#define catalog_sm_png_bmp catalog_sm_png_bmp() + +static wxIcon *catalog_sm_png_ico() +{ + static wxIcon *ico_catalog_sm_png; + if (!ico_catalog_sm_png || !ico_catalog_sm_png->IsOk()) + { + ico_catalog_sm_png = new wxIcon(); + ico_catalog_sm_png->CopyFromBitmap(*catalog_sm_png_bmp); + } + return ico_catalog_sm_png; +} +#define catalog_sm_png_ico catalog_sm_png_ico() + +#endif // CATALOG_SM_PNG_H diff --git a/include/images/catalog.png b/include/images/catalog.png new file mode 100644 index 0000000000000000000000000000000000000000..7c0ef24ff5843867fb64d97cc419a7150da5f441 GIT binary patch literal 387 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!eSlAhE0A74wh5F-1vWE-M=SKm;e3mx31#fzyGsVm;76i_it&|zr|_)79{jfG@u3-kbFB3rR7tE)c>e0@4eiyB zLKAaZn>`A?dUi-nuND6*>}cWk(81HwR&}e=a#7p0XRqFhtDUf>`Dx)5>7(|iZO+%n zJ{F&HpV>2Gt>-78&8j7?5hW>!C8<`)MX5lF!N|bSK-bVn*T68u$iT|P*viC2+rZSy vz`$arsvL@j-29Zxv`UBu152<5kZLOfGl+&$(?iz)H86O(`njxgN@xNA6A6=n literal 0 HcmV?d00001 diff --git a/include/images/catalog.pngc b/include/images/catalog.pngc new file mode 100644 index 0000000..99832d0 --- /dev/null +++ b/include/images/catalog.pngc @@ -0,0 +1,93 @@ +#ifndef CATALOG_PNG_H +#define CATALOG_PNG_H + +static const unsigned char catalog_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x3f, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xaf, 0x94, 0xd8, 0x77, +0x49, 0xbd, 0xbb, 0x8d, 0xff, 0xb9, 0x8b, 0xff, +0xb8, 0x89, 0xff, 0xb6, 0x85, 0xff, 0xff, 0xff, +0xff, 0xb3, 0x81, 0xff, 0xb1, 0x7e, 0xfe, 0xe4, +0xe5, 0xa7, 0xfd, 0xff, 0x4e, 0xae, 0x78, 0xfe, +0xfe, 0xff, 0x9a, 0xab, 0x74, 0xfe, 0xa8, 0x6e, +0xfe, 0xa5, 0x6a, 0xfe, 0xa3, 0x66, 0xfe, 0xa0, +0x62, 0xfe, 0x9f, 0x60, 0xfe, 0x9c, 0x5a, 0xfe, +0xbc, 0xcb, 0xef, 0x88, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, +0x44, 0x07, 0x16, 0x61, 0x88, 0xeb, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x6e, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x5d, 0x8f, 0x09, +0x12, 0x80, 0x20, 0x08, 0x45, 0xe1, 0xb7, 0x68, +0x62, 0x59, 0xd6, 0xfd, 0xcf, 0x9a, 0xe8, 0x30, +0x5a, 0x0c, 0xa3, 0xbe, 0x8f, 0x6c, 0x44, 0xd5, +0x18, 0x60, 0x1a, 0x8c, 0x31, 0x4d, 0xa3, 0xc2, +0x98, 0x51, 0x9c, 0x3b, 0x2f, 0xe0, 0x7a, 0x18, +0xaf, 0x60, 0xe7, 0xea, 0xd5, 0xd8, 0x2b, 0xab, +0xe2, 0x55, 0x61, 0x6c, 0x85, 0x83, 0x48, 0x70, +0xf5, 0x49, 0x88, 0x1a, 0x97, 0x7d, 0x17, 0xfd, +0x13, 0x41, 0x38, 0x46, 0xe1, 0x40, 0x49, 0x49, +0x3d, 0x25, 0xb5, 0x22, 0xa7, 0x15, 0x3d, 0xad, +0xcd, 0xd5, 0xda, 0x5e, 0x7d, 0x90, 0xac, 0x83, +0xe5, 0x71, 0xd4, 0x1b, 0xc5, 0x3f, 0xcb, 0x3c, +0xcf, 0x7f, 0x5d, 0xe3, 0x17, 0x94, 0xdf, 0x03, +0x49, 0x68, 0xad, 0x49, 0xf2, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *catalog_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_catalog_png = new wxImage(); + if (!img_catalog_png || !img_catalog_png->IsOk()) + { + wxMemoryInputStream img_catalog_pngIS(catalog_png_data, sizeof(catalog_png_data)); + img_catalog_png->LoadFile(img_catalog_pngIS, wxBITMAP_TYPE_PNG); + } + return img_catalog_png; +} +#define catalog_png_img catalog_png_img() + +static wxBitmap *catalog_png_bmp() +{ + static wxBitmap *bmp_catalog_png; + if (!bmp_catalog_png || !bmp_catalog_png->IsOk()) + bmp_catalog_png = new wxBitmap(*catalog_png_img); + return bmp_catalog_png; +} +#define catalog_png_bmp catalog_png_bmp() + +static wxIcon *catalog_png_ico() +{ + static wxIcon *ico_catalog_png; + if (!ico_catalog_png || !ico_catalog_png->IsOk()) + { + ico_catalog_png = new wxIcon(); + ico_catalog_png->CopyFromBitmap(*catalog_png_bmp); + } + return ico_catalog_png; +} +#define catalog_png_ico catalog_png_ico() + +#endif // CATALOG_PNG_H diff --git a/include/images/catalogobject-sm.png b/include/images/catalogobject-sm.png new file mode 100644 index 0000000000000000000000000000000000000000..7a058c34beb8ccc82d6c9ec37686ee1a188a4408 GIT binary patch literal 386 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}a)3{WE09*4`n>DhzbWT`uD$x{ z)SXxN9zTEf{Q0wI&yL=BR<`qn!JHQzXa6;y{#SMEcm9E&$veM=ZTjrF`h)G#w}$gx ztIvGdeEP2!kh|oq#>|(SufF~HZCd+*=eLg7SA*35(3ttcF*;`j&>F^)AirP+hi5m^ zfE>;OkH}&m?E%JaC$sH7i?Y8W=oX{an^LB{Ts5AVZJE literal 0 HcmV?d00001 diff --git a/include/images/catalogobject-sm.pngc b/include/images/catalogobject-sm.pngc new file mode 100644 index 0000000..17031b8 --- /dev/null +++ b/include/images/catalogobject-sm.pngc @@ -0,0 +1,93 @@ +#ifndef CATALOGOBJECT_SM_PNG_H +#define CATALOGOBJECT_SM_PNG_H + +static const unsigned char catalogobject_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x21, 0x95, 0xe7, 0x8a, +0xce, 0xfe, 0x94, 0xcf, 0xf9, 0xad, 0xd5, 0xf2, +0xca, 0xdc, 0xea, 0xde, 0xe3, 0xe7, 0xe6, 0xe7, +0xe7, 0xe6, 0xe6, 0xe6, 0xc5, 0xd8, 0xe6, 0x76, +0xb9, 0xe8, 0x30, 0x9c, 0xe8, 0x88, 0xcd, 0xfe, +0x83, 0xcb, 0xfe, 0x7a, 0xc6, 0xfb, 0x6f, 0xc0, +0xf9, 0x63, 0xb9, 0xf6, 0x56, 0xb2, 0xf3, 0x49, +0xab, 0xf0, 0x3d, 0xa5, 0xed, 0x31, 0x9e, 0xeb, +0x27, 0x99, 0xe9, 0x83, 0xcb, 0xfd, 0x4a, 0xab, +0xf0, 0x3d, 0xa4, 0xed, 0x28, 0x99, 0xe9, 0xb3, +0xd5, 0xed, 0xf9, 0xf6, 0x96, 0x87, 0xc0, 0xe7, +0xda, 0xc4, 0x3f, 0x7b, 0xc6, 0xfb, 0x6f, 0xc0, +0xf8, 0x28, 0x99, 0xe8, 0x41, 0x5b, 0x6c, 0xa8, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x56, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0x20, 0x02, +0x30, 0x22, 0x01, 0x88, 0x00, 0x13, 0x33, 0x0b, +0x2b, 0x1b, 0x3b, 0x07, 0x07, 0x27, 0x17, 0x37, +0x44, 0x80, 0x87, 0x97, 0x8f, 0x5f, 0x40, 0x50, +0x48, 0x58, 0x44, 0x14, 0xaa, 0x82, 0x47, 0x0c, +0x24, 0x20, 0x2e, 0x21, 0x22, 0x09, 0x15, 0x90, +0x92, 0x86, 0x02, 0x19, 0xa8, 0x00, 0x90, 0x29, +0x0b, 0x46, 0xd2, 0x30, 0x01, 0x59, 0x59, 0x90, +0x00, 0x90, 0x40, 0xa8, 0x80, 0x02, 0xf2, 0xb5, +0xf0, 0xf0, 0xca, 0xc9, 0x83, 0xdd, 0xa1, 0xc0, +0x48, 0x8c, 0x57, 0x01, 0xb3, 0x99, 0x0a, 0x28, +0xe4, 0x61, 0x60, 0x17, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *catalogobject_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_catalogobject_sm_png = new wxImage(); + if (!img_catalogobject_sm_png || !img_catalogobject_sm_png->IsOk()) + { + wxMemoryInputStream img_catalogobject_sm_pngIS(catalogobject_sm_png_data, sizeof(catalogobject_sm_png_data)); + img_catalogobject_sm_png->LoadFile(img_catalogobject_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_catalogobject_sm_png; +} +#define catalogobject_sm_png_img catalogobject_sm_png_img() + +static wxBitmap *catalogobject_sm_png_bmp() +{ + static wxBitmap *bmp_catalogobject_sm_png; + if (!bmp_catalogobject_sm_png || !bmp_catalogobject_sm_png->IsOk()) + bmp_catalogobject_sm_png = new wxBitmap(*catalogobject_sm_png_img); + return bmp_catalogobject_sm_png; +} +#define catalogobject_sm_png_bmp catalogobject_sm_png_bmp() + +static wxIcon *catalogobject_sm_png_ico() +{ + static wxIcon *ico_catalogobject_sm_png; + if (!ico_catalogobject_sm_png || !ico_catalogobject_sm_png->IsOk()) + { + ico_catalogobject_sm_png = new wxIcon(); + ico_catalogobject_sm_png->CopyFromBitmap(*catalogobject_sm_png_bmp); + } + return ico_catalogobject_sm_png; +} +#define catalogobject_sm_png_ico catalogobject_sm_png_ico() + +#endif // CATALOGOBJECT_SM_PNG_H diff --git a/include/images/catalogobject.png b/include/images/catalogobject.png new file mode 100644 index 0000000000000000000000000000000000000000..54ed7389c128fdcdcd86bc504311b9ed62e890ff GIT binary patch literal 409 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}QGic~E09*4`n>nT|4HY6FS`77 z*NwLq@4vkN`1#Xk&!0VecI)BOHRqluZ+xLQ`$hNp|E*{K)t&fLdiYn)z8{G@zJ+c2 z?7ilL!}53L3*P9?d8IbvW$T&0+53JtE_-LT@QvP_S6i;V`}u8J`~K&*j@bWvKj-(& zo4+qyn4y_82WTr}NswPKgTu2MX+REVfk$L9koEv$x0Bg+Kt`OWi(`ny<>Z6}7e*c) zo*thwI%{&?$jq4&bH`?n0;63WqoZP?V4z_kr{@MPJ55H%%mocSYh+v;;u!fv4l;3h zFz78{aWi04RS0O9aOL`IsOk()) + { + wxMemoryInputStream img_catalogobject_pngIS(catalogobject_png_data, sizeof(catalogobject_png_data)); + img_catalogobject_png->LoadFile(img_catalogobject_pngIS, wxBITMAP_TYPE_PNG); + } + return img_catalogobject_png; +} +#define catalogobject_png_img catalogobject_png_img() + +static wxBitmap *catalogobject_png_bmp() +{ + static wxBitmap *bmp_catalogobject_png; + if (!bmp_catalogobject_png || !bmp_catalogobject_png->IsOk()) + bmp_catalogobject_png = new wxBitmap(*catalogobject_png_img); + return bmp_catalogobject_png; +} +#define catalogobject_png_bmp catalogobject_png_bmp() + +static wxIcon *catalogobject_png_ico() +{ + static wxIcon *ico_catalogobject_png; + if (!ico_catalogobject_png || !ico_catalogobject_png->IsOk()) + { + ico_catalogobject_png = new wxIcon(); + ico_catalogobject_png->CopyFromBitmap(*catalogobject_png_bmp); + } + return ico_catalogobject_png; +} +#define catalogobject_png_ico catalogobject_png_ico() + +#endif // CATALOGOBJECT_PNG_H diff --git a/include/images/catalogobjects.png b/include/images/catalogobjects.png new file mode 100644 index 0000000000000000000000000000000000000000..85b89f1e75c3ba919e0f3f63235d14fb7bc58940 GIT binary patch literal 419 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}W`IwKE09*4`n>DhzbWT`uD$x{ z)SXxN9zTEf{Q0wI&yL=BR<`qn!JHQzXa5Cl__X=z+n?X2HJ|=hb?kTkfuG4czlCl3 z?78}b?b5e~^IogZeA#^ZuNRQJDm=t0E5ucyF7nz8Xt`>M zYeY#(Vo9o1a#1RfVlXl=G|)9P(lsy)F*2|+F}5->(Kax(GBB{1sVaw}AvZrIGp!P$ f!N3x%0i@c>zzm|{)b!9bKn)C@u6{1-oD!MIsOk()) + { + wxMemoryInputStream img_catalogobjects_pngIS(catalogobjects_png_data, sizeof(catalogobjects_png_data)); + img_catalogobjects_png->LoadFile(img_catalogobjects_pngIS, wxBITMAP_TYPE_PNG); + } + return img_catalogobjects_png; +} +#define catalogobjects_png_img catalogobjects_png_img() + +static wxBitmap *catalogobjects_png_bmp() +{ + static wxBitmap *bmp_catalogobjects_png; + if (!bmp_catalogobjects_png || !bmp_catalogobjects_png->IsOk()) + bmp_catalogobjects_png = new wxBitmap(*catalogobjects_png_img); + return bmp_catalogobjects_png; +} +#define catalogobjects_png_bmp catalogobjects_png_bmp() + +static wxIcon *catalogobjects_png_ico() +{ + static wxIcon *ico_catalogobjects_png; + if (!ico_catalogobjects_png || !ico_catalogobjects_png->IsOk()) + { + ico_catalogobjects_png = new wxIcon(); + ico_catalogobjects_png->CopyFromBitmap(*catalogobjects_png_bmp); + } + return ico_catalogobjects_png; +} +#define catalogobjects_png_ico catalogobjects_png_ico() + +#endif // CATALOGOBJECTS_PNG_H diff --git a/include/images/catalogs.png b/include/images/catalogs.png new file mode 100644 index 0000000000000000000000000000000000000000..caa6d3d40d55d990351465cebacbffde95eeb63d GIT binary patch literal 371 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!aez;VE0A74_W~_vF9f0-!d=k|4ie28U-i z(md1_d7H%+Qbz<^L~7 z1qs|Sn)G$;X%0t5r5;8ckg4n7vtRmMKl%{UE#@beKLBl2Epd$~ zNl7e8wMs5Z1yT$~28IT@hDN#uh9O1IsOk()) + { + wxMemoryInputStream img_catalogs_pngIS(catalogs_png_data, sizeof(catalogs_png_data)); + img_catalogs_png->LoadFile(img_catalogs_pngIS, wxBITMAP_TYPE_PNG); + } + return img_catalogs_png; +} +#define catalogs_png_img catalogs_png_img() + +static wxBitmap *catalogs_png_bmp() +{ + static wxBitmap *bmp_catalogs_png; + if (!bmp_catalogs_png || !bmp_catalogs_png->IsOk()) + bmp_catalogs_png = new wxBitmap(*catalogs_png_img); + return bmp_catalogs_png; +} +#define catalogs_png_bmp catalogs_png_bmp() + +static wxIcon *catalogs_png_ico() +{ + static wxIcon *ico_catalogs_png; + if (!ico_catalogs_png || !ico_catalogs_png->IsOk()) + { + ico_catalogs_png = new wxIcon(); + ico_catalogs_png->CopyFromBitmap(*catalogs_png_bmp); + } + return ico_catalogs_png; +} +#define catalogs_png_ico catalogs_png_ico() + +#endif // CATALOGS_PNG_H diff --git a/include/images/check.png b/include/images/check.png new file mode 100644 index 0000000000000000000000000000000000000000..9d1d2a061c7948168d7b1c2474d769b31709f1cf GIT binary patch literal 406 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}X@F0NE08{VY2nhHc^eMaU%j`d zaI$#+HuEKC{pKEZKYn>h(+aIMH^MjGjcs3}f9Cqyt&fvx7AT*)xv^`L;hf{Hi_iP4 zxgK%&V?q65_4c*;8}G%;JMMY(Kax(GBB{1sVaw}AvZrIGp!P$!N3x%0i@c>zzm|{ T)b!9bKn)C@u6{1-oD!M<=4O^k literal 0 HcmV?d00001 diff --git a/include/images/check.pngc b/include/images/check.pngc new file mode 100644 index 0000000..736de8d --- /dev/null +++ b/include/images/check.pngc @@ -0,0 +1,95 @@ +#ifndef CHECK_PNG_H +#define CHECK_PNG_H + +static const unsigned char check_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x75, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc5, 0xd2, 0xa1, 0xa5, +0xb9, 0x6e, 0xb0, 0xc1, 0x7f, 0xd5, 0xde, 0xbc, +0x71, 0x93, 0x17, 0x8f, 0xb6, 0x37, 0xa4, 0xcd, +0x4e, 0x9d, 0xc5, 0x47, 0xc7, 0xd3, 0xa4, 0x82, +0xa8, 0x2a, 0xac, 0xd8, 0x57, 0xb1, 0xdd, 0x5d, +0x87, 0xac, 0x2f, 0xcc, 0xd7, 0xad, 0xb5, 0xe3, +0x62, 0x7c, 0xa0, 0x23, 0xce, 0xd9, 0xb1, 0x8a, +0xb2, 0x31, 0x9c, 0xc7, 0x45, 0xa3, 0xcf, 0x4c, +0xac, 0xd7, 0x58, 0xc3, 0xf1, 0x70, 0x7f, 0xa3, +0x27, 0x87, 0xad, 0x2f, 0xb1, 0xde, 0x5c, 0x9e, +0xc7, 0x49, 0xcb, 0xfa, 0x79, 0x95, 0xbc, 0x3f, +0xb3, 0xc4, 0x85, 0xc4, 0xf1, 0x71, 0xc4, 0xf1, +0x72, 0xc6, 0xf3, 0x74, 0xa2, 0xca, 0x4e, 0xa7, +0xbb, 0x72, 0xaf, 0xc1, 0x7e, 0x80, 0xa3, 0x27, +0x70, 0x92, 0x16, 0xdc, 0xe4, 0xc7, 0x0a, 0xaa, +0xa9, 0x3b, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x58, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, +0xa0, 0x08, 0x30, 0x32, 0x31, 0x23, 0x73, 0x59, +0x58, 0xd9, 0xd8, 0x39, 0x90, 0x44, 0x38, 0xb9, +0xb8, 0x79, 0x78, 0x21, 0x7c, 0x3e, 0x66, 0x26, +0x46, 0x06, 0x16, 0x2e, 0x7e, 0x1e, 0x01, 0x41, +0x88, 0x9c, 0x90, 0xb0, 0x08, 0x1b, 0x2b, 0xab, +0xa8, 0x98, 0x38, 0x94, 0x0f, 0x54, 0x21, 0x21, +0xc9, 0x2d, 0x25, 0x2d, 0x23, 0x8b, 0xd0, 0x2f, +0x28, 0xc0, 0x23, 0x27, 0xcf, 0x8a, 0x62, 0xa3, +0xb8, 0x82, 0xa2, 0x12, 0x8a, 0x80, 0xb2, 0x8a, +0x2a, 0x9a, 0xa3, 0xd4, 0x28, 0xf0, 0x10, 0x00, +0xbd, 0xd5, 0x03, 0x92, 0xa5, 0xe9, 0x59, 0x63, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, +0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *check_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_check_png = new wxImage(); + if (!img_check_png || !img_check_png->IsOk()) + { + wxMemoryInputStream img_check_pngIS(check_png_data, sizeof(check_png_data)); + img_check_png->LoadFile(img_check_pngIS, wxBITMAP_TYPE_PNG); + } + return img_check_png; +} +#define check_png_img check_png_img() + +static wxBitmap *check_png_bmp() +{ + static wxBitmap *bmp_check_png; + if (!bmp_check_png || !bmp_check_png->IsOk()) + bmp_check_png = new wxBitmap(*check_png_img); + return bmp_check_png; +} +#define check_png_bmp check_png_bmp() + +static wxIcon *check_png_ico() +{ + static wxIcon *ico_check_png; + if (!ico_check_png || !ico_check_png->IsOk()) + { + ico_check_png = new wxIcon(); + ico_check_png->CopyFromBitmap(*check_png_bmp); + } + return ico_check_png; +} +#define check_png_ico check_png_ico() + +#endif // CHECK_PNG_H diff --git a/include/images/checkbad.png b/include/images/checkbad.png new file mode 100644 index 0000000000000000000000000000000000000000..32a045b8fafdc08640d53b2a86b1dcabcb0fe0fd GIT binary patch literal 579 zcmV-J0=)f+P)Px$AW%$HMR1Z9#Q*@REHmdHAm<<;=p`lTDl6$LE15$|nM6yxJ3#6&F}^)Qx|oNbX2U?n+AUOH1!e zOz%xi?@dncPEXKRS?^Cz#amtQQBm+xQt(q#@KaRqR8;U)Rq<9<@mE*YVq(`~V)0vB z+GS<)VPW%PV%=$Jag!JHXlV6qZS`($_HuH3pdDu=8uhpjJ) zvN4agH<6_L$tcPam4X*+~mi`^K{Glc|xhhkN@C%g?4vVBM R$bbL<002ovPDHLkV1min0OSAw literal 0 HcmV?d00001 diff --git a/include/images/checkbad.pngc b/include/images/checkbad.pngc new file mode 100644 index 0000000..49922f3 --- /dev/null +++ b/include/images/checkbad.pngc @@ -0,0 +1,117 @@ +#ifndef CHECKBAD_PNG_H +#define CHECKBAD_PNG_H + +static const unsigned char checkbad_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x01, 0x20, 0x50, 0x4c, 0x54, 0x45, 0x70, 0x92, +0x16, 0xc5, 0x00, 0x00, 0xaa, 0x2c, 0x33, 0xe7, +0x1f, 0x20, 0xe7, 0x20, 0x20, 0xe8, 0x25, 0x25, +0xe9, 0x2a, 0x2b, 0xe9, 0x2b, 0x2b, 0x99, 0x43, +0x4a, 0x99, 0x44, 0x4b, 0xbc, 0x3b, 0x40, 0xea, +0x31, 0x31, 0xbe, 0x3d, 0x42, 0xba, 0x44, 0x46, +0xeb, 0x37, 0x37, 0xeb, 0x38, 0x38, 0xc4, 0x46, +0x4a, 0xc4, 0x47, 0x4b, 0xc5, 0x47, 0x4b, 0xec, +0x3e, 0x3f, 0xed, 0x42, 0x43, 0xed, 0x43, 0x44, +0xed, 0x44, 0x45, 0xee, 0x45, 0x45, 0xee, 0x46, +0x46, 0xee, 0x47, 0x47, 0xca, 0x51, 0x54, 0xee, +0x48, 0x48, 0xee, 0x48, 0x49, 0xee, 0x4a, 0x4a, +0xef, 0x4b, 0x4b, 0xef, 0x4c, 0x4c, 0xef, 0x4d, +0x4d, 0xef, 0x4d, 0x4e, 0xef, 0x4e, 0x4f, 0xd0, +0x57, 0x59, 0xef, 0x4f, 0x4f, 0xc5, 0x5b, 0x5d, +0xf0, 0x51, 0x51, 0xf0, 0x52, 0x52, 0xf0, 0x53, +0x53, 0xf0, 0x53, 0x54, 0xf0, 0x54, 0x54, 0xf0, +0x55, 0x55, 0xf1, 0x56, 0x56, 0xf1, 0x57, 0x57, +0xd6, 0x62, 0x62, 0xd7, 0x62, 0x62, 0xf1, 0x5b, +0x5b, 0xda, 0x65, 0x65, 0xf3, 0x61, 0x61, 0xf3, +0x62, 0x62, 0xdd, 0x69, 0x69, 0x71, 0x93, 0x17, +0xf4, 0x68, 0x68, 0xf5, 0x6d, 0x6d, 0xf5, 0x6e, +0x6e, 0xf6, 0x72, 0x72, 0x7c, 0xa0, 0x23, 0xf6, +0x76, 0x76, 0xf6, 0x77, 0x77, 0x7f, 0xa3, 0x27, +0x80, 0xa3, 0x27, 0x82, 0xa8, 0x2a, 0x87, 0xac, +0x2f, 0x87, 0xad, 0x2f, 0x8a, 0xb2, 0x31, 0x8f, +0xb6, 0x37, 0x95, 0xbc, 0x3f, 0xa5, 0xb9, 0x6e, +0xa7, 0xbb, 0x72, 0x9d, 0xc5, 0x47, 0x9c, 0xc7, +0x45, 0x9e, 0xc7, 0x49, 0xaf, 0xc1, 0x7e, 0xa2, +0xca, 0x4e, 0xb0, 0xc1, 0x7f, 0xa4, 0xcd, 0x4e, +0xb3, 0xc4, 0x85, 0xa3, 0xcf, 0x4c, 0xac, 0xd7, +0x58, 0xac, 0xd8, 0x57, 0xb1, 0xdd, 0x5d, 0xb1, +0xde, 0x5c, 0xc5, 0xd2, 0xa1, 0xc7, 0xd3, 0xa4, +0xb5, 0xe3, 0x62, 0xcc, 0xd7, 0xad, 0xce, 0xd9, +0xb1, 0xd5, 0xde, 0xbc, 0xc3, 0xf1, 0x70, 0xc4, +0xf1, 0x71, 0xc4, 0xf1, 0x72, 0xdc, 0xe4, 0xc7, +0xc6, 0xf3, 0x74, 0xcb, 0xfa, 0x79, 0x42, 0xa9, +0xe3, 0x49, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, 0x00, +0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, +0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, +0x18, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, +0x45, 0x07, 0xdb, 0x07, 0x19, 0x0f, 0x21, 0x26, +0x7e, 0xd2, 0x55, 0x6a, 0x00, 0x00, 0x00, 0x8f, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0xa5, 0x8c, +0xc7, 0x0a, 0xc2, 0x50, 0x00, 0x04, 0xdf, 0xc4, +0xde, 0x7b, 0x8b, 0x25, 0xf6, 0xae, 0xb1, 0x17, +0x14, 0x04, 0x45, 0xf4, 0x10, 0x0f, 0x82, 0xf5, +0xff, 0x7f, 0x44, 0x4d, 0x4c, 0xf0, 0xee, 0xde, +0x66, 0xd8, 0x5d, 0x21, 0xfe, 0xca, 0x65, 0xaf, +0xfd, 0xe2, 0x73, 0xba, 0x3b, 0x1d, 0x4c, 0xa3, +0x52, 0xb9, 0x6e, 0xce, 0x51, 0x26, 0x3a, 0xdd, +0xb5, 0x1a, 0x6b, 0x22, 0x37, 0x3f, 0x3d, 0xc3, +0x6c, 0x8f, 0xac, 0x96, 0x0b, 0xbc, 0x74, 0xab, +0x39, 0x8c, 0x86, 0xcc, 0x7c, 0x36, 0xa6, 0x53, +0xce, 0x7e, 0x37, 0xe2, 0xa1, 0x32, 0x1a, 0xb4, +0x4b, 0x19, 0x93, 0xdf, 0x19, 0xd2, 0x2a, 0xa6, +0x91, 0x2c, 0xee, 0xd3, 0x54, 0x52, 0xb1, 0x90, +0xd5, 0x08, 0xd0, 0x28, 0x24, 0x09, 0xfa, 0x5c, +0xa6, 0xa1, 0x9e, 0x4f, 0xe0, 0xc6, 0xe9, 0xb0, +0x63, 0x08, 0x99, 0x38, 0x61, 0xe1, 0xc1, 0x66, +0x6d, 0x24, 0xfd, 0x4f, 0xfa, 0xf0, 0x0b, 0x95, +0x10, 0x0e, 0x8b, 0xa4, 0x2d, 0xc8, 0x80, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *checkbad_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_checkbad_png = new wxImage(); + if (!img_checkbad_png || !img_checkbad_png->IsOk()) + { + wxMemoryInputStream img_checkbad_pngIS(checkbad_png_data, sizeof(checkbad_png_data)); + img_checkbad_png->LoadFile(img_checkbad_pngIS, wxBITMAP_TYPE_PNG); + } + return img_checkbad_png; +} +#define checkbad_png_img checkbad_png_img() + +static wxBitmap *checkbad_png_bmp() +{ + static wxBitmap *bmp_checkbad_png; + if (!bmp_checkbad_png || !bmp_checkbad_png->IsOk()) + bmp_checkbad_png = new wxBitmap(*checkbad_png_img); + return bmp_checkbad_png; +} +#define checkbad_png_bmp checkbad_png_bmp() + +static wxIcon *checkbad_png_ico() +{ + static wxIcon *ico_checkbad_png; + if (!ico_checkbad_png || !ico_checkbad_png->IsOk()) + { + ico_checkbad_png = new wxIcon(); + ico_checkbad_png->CopyFromBitmap(*checkbad_png_bmp); + } + return ico_checkbad_png; +} +#define checkbad_png_ico checkbad_png_ico() + +#endif // CHECKBAD_PNG_H diff --git a/include/images/checked.png b/include/images/checked.png new file mode 100644 index 0000000000000000000000000000000000000000..8ccaa5f433b46f3e0ac5f8f234df4bac9e6ab4c7 GIT binary patch literal 299 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPE^3h)VW1=0--4gdfDcW`jHa^VD! z>rn2h3#1rJg8YIR9G=}s196hP-CdZ{xNA~?9L@rd$YLPv0mg18v+aNkXHOT$5RU7~ z2?rQ@niLdRQY4xigeN2}VPP?F6PU7)E0IOB)k$LEs)Yik3l};Humv!z(&ktwd!~Sq zQK8wBlSg10GsENm`~jH{M4Eucsg}4#l%ynIsOk()) + { + wxMemoryInputStream img_checked_pngIS(checked_png_data, sizeof(checked_png_data)); + img_checked_png->LoadFile(img_checked_pngIS, wxBITMAP_TYPE_PNG); + } + return img_checked_png; +} +#define checked_png_img checked_png_img() + +static wxBitmap *checked_png_bmp() +{ + static wxBitmap *bmp_checked_png; + if (!bmp_checked_png || !bmp_checked_png->IsOk()) + bmp_checked_png = new wxBitmap(*checked_png_img); + return bmp_checked_png; +} +#define checked_png_bmp checked_png_bmp() + +static wxIcon *checked_png_ico() +{ + static wxIcon *ico_checked_png; + if (!ico_checked_png || !ico_checked_png->IsOk()) + { + ico_checked_png = new wxIcon(); + ico_checked_png->CopyFromBitmap(*checked_png_bmp); + } + return ico_checked_png; +} +#define checked_png_ico checked_png_ico() + +#endif // CHECKED_PNG_H diff --git a/include/images/clearAll.png b/include/images/clearAll.png new file mode 100644 index 0000000000000000000000000000000000000000..2ec90c00d03f4889ce2ca6072d4e0ad233628912 GIT binary patch literal 318 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPE^4e$wZ1=2up;J|@~hKBzP3=Ito z4GawXIU#U}a)#Wn!XjU}|MxU@=ow4n;$5eoAIqB}9XPC0GMU awUvPxM8m1+p=*E|7(8A5T-G@yGywoT(P8ue literal 0 HcmV?d00001 diff --git a/include/images/clearAll.pngc b/include/images/clearAll.pngc new file mode 100644 index 0000000..9829956 --- /dev/null +++ b/include/images/clearAll.pngc @@ -0,0 +1,84 @@ +#ifndef CLEARALL_PNG_H +#define CLEARALL_PNG_H + +static const unsigned char clearAll_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x15, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, +0xc0, 0xc0, 0x80, 0x80, 0x80, 0xff, 0x00, 0x00, +0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0xbf, 0x5f, +0xc7, 0x32, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x60, +0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x3d, 0x8d, +0xd1, 0x0d, 0x80, 0x20, 0x0c, 0x44, 0x0f, 0x27, +0xe0, 0x0c, 0xe1, 0x5b, 0x70, 0x03, 0xe3, 0x02, +0x24, 0x95, 0x3d, 0x88, 0xb1, 0xfb, 0x8f, 0x60, +0xc1, 0xe0, 0x7d, 0x34, 0x2f, 0xbd, 0x5e, 0x0f, +0x98, 0x72, 0x1e, 0x39, 0xf7, 0xe9, 0xb8, 0xcb, +0x75, 0xd0, 0x03, 0x0c, 0x52, 0x1b, 0xcd, 0x4b, +0x94, 0xca, 0xd5, 0xe0, 0x64, 0x28, 0x7c, 0x80, +0x45, 0x12, 0x19, 0x75, 0x33, 0xc8, 0xa4, 0x0e, +0x90, 0x09, 0xe5, 0xb3, 0xec, 0x38, 0x36, 0xde, +0x23, 0xae, 0x3a, 0xe2, 0xb6, 0xd7, 0xfe, 0xd0, +0x2a, 0x54, 0x7b, 0xc5, 0x5f, 0x3a, 0xf5, 0x02, +0x2d, 0x5a, 0x0f, 0x70, 0x6e, 0x25, 0x18, 0x4b, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, +0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *clearAll_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_clearAll_png = new wxImage(); + if (!img_clearAll_png || !img_clearAll_png->IsOk()) + { + wxMemoryInputStream img_clearAll_pngIS(clearAll_png_data, sizeof(clearAll_png_data)); + img_clearAll_png->LoadFile(img_clearAll_pngIS, wxBITMAP_TYPE_PNG); + } + return img_clearAll_png; +} +#define clearAll_png_img clearAll_png_img() + +static wxBitmap *clearAll_png_bmp() +{ + static wxBitmap *bmp_clearAll_png; + if (!bmp_clearAll_png || !bmp_clearAll_png->IsOk()) + bmp_clearAll_png = new wxBitmap(*clearAll_png_img); + return bmp_clearAll_png; +} +#define clearAll_png_bmp clearAll_png_bmp() + +static wxIcon *clearAll_png_ico() +{ + static wxIcon *ico_clearAll_png; + if (!ico_clearAll_png || !ico_clearAll_png->IsOk()) + { + ico_clearAll_png = new wxIcon(); + ico_clearAll_png->CopyFromBitmap(*clearAll_png_bmp); + } + return ico_clearAll_png; +} +#define clearAll_png_ico clearAll_png_ico() + +#endif // CLEARALL_PNG_H diff --git a/include/images/clip_copy.png b/include/images/clip_copy.png new file mode 100644 index 0000000000000000000000000000000000000000..6b98c9210c854c73c3d354fa6c5d383970270a98 GIT binary patch literal 489 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf%mAMdS0LTj*O!ox@agBD7oUGV z`~2g{$M26ne0%=+$BoxtuD<-#KV$aOkKc9D_C9+5_59O!XCA+~^!&qvcc1US{e0@- z>pQPM9=-SC;O(a;9=tkw@A=*vk1jrWee>n}bB|tJefDi)Cicb+_a`|_!@p!&%@FSq!8-z}W3%wjGes?&;zfB5^tO{7t?l1A*2=i*+kR z#aT9L>}XQhvFHC`Lt~bpM?3#~Hk}!D?S9UQH+l&MGQH|<2d~UL>)YBIWZSxQchc6f zjT4)6IfG6;4wosbJCG&M#;&WV2OC7#SEE=o%X7 z8W@Hc8CaPZTbY<>8<<)d7+B0yl|#{xo1c=IRteEyUIsOk()) + { + wxMemoryInputStream img_clip_copy_pngIS(clip_copy_png_data, sizeof(clip_copy_png_data)); + img_clip_copy_png->LoadFile(img_clip_copy_pngIS, wxBITMAP_TYPE_PNG); + } + return img_clip_copy_png; +} +#define clip_copy_png_img clip_copy_png_img() + +static wxBitmap *clip_copy_png_bmp() +{ + static wxBitmap *bmp_clip_copy_png; + if (!bmp_clip_copy_png || !bmp_clip_copy_png->IsOk()) + bmp_clip_copy_png = new wxBitmap(*clip_copy_png_img); + return bmp_clip_copy_png; +} +#define clip_copy_png_bmp clip_copy_png_bmp() + +static wxIcon *clip_copy_png_ico() +{ + static wxIcon *ico_clip_copy_png; + if (!ico_clip_copy_png || !ico_clip_copy_png->IsOk()) + { + ico_clip_copy_png = new wxIcon(); + ico_clip_copy_png->CopyFromBitmap(*clip_copy_png_bmp); + } + return ico_clip_copy_png; +} +#define clip_copy_png_ico clip_copy_png_ico() + +#endif // CLIP_COPY_PNG_H diff --git a/include/images/clip_cut.png b/include/images/clip_cut.png new file mode 100644 index 0000000000000000000000000000000000000000..88e6ce7efe57f4aded58241d5a8758bd667a7907 GIT binary patch literal 563 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMfjR2nzS0FuY+O*u<+#@GXpEz;i z^QTWI&YoYke8v3v^EYqa{P^*ct2b|*J%6FSz5VFXqnEE-dGhS}uiw8rJ3AjdcyRp0 z$==@H&Yc%7UR<$a#kOtRy1Kf)fB$~>?%iX@k2f?l96WgN+`02BR;;{v z>(-H@$IhKUzk2oR(`U{sTD0iiy?Z}^;OEaN)21z4xbWKb>qm|refRF&tl6^Q?^Yk(RUJYD@<);T3K0RU9!6U_hs literal 0 HcmV?d00001 diff --git a/include/images/clip_cut.pngc b/include/images/clip_cut.pngc new file mode 100644 index 0000000..b8303b9 --- /dev/null +++ b/include/images/clip_cut.pngc @@ -0,0 +1,115 @@ +#ifndef CLIP_CUT_PNG_H +#define CLIP_CUT_PNG_H + +static const unsigned char clip_cut_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xd8, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x96, 0x96, 0x96, 0x6d, +0x6d, 0x6d, 0xc4, 0xc9, 0xcb, 0xc8, 0xc8, 0xc8, +0xf3, 0xf2, 0xf2, 0xc8, 0xcd, 0xcf, 0xa6, 0xa7, +0xa8, 0x9f, 0x9f, 0x9f, 0xb3, 0xb3, 0xb3, 0xe3, +0xe3, 0xe4, 0xd5, 0xd9, 0xda, 0xcd, 0xcf, 0xd0, +0x87, 0x87, 0x87, 0xc5, 0xc5, 0xc5, 0xd3, 0xd4, +0xd4, 0xe4, 0xe6, 0xe7, 0xfa, 0xfb, 0xfb, 0x89, +0x89, 0x89, 0xe0, 0xe0, 0xe0, 0xc7, 0xc8, 0xc9, +0x8d, 0x8d, 0x8d, 0xc7, 0xc7, 0xc8, 0xfe, 0xfe, +0xfe, 0xb9, 0xb9, 0xb9, 0xd0, 0xd1, 0xd1, 0xa8, +0xa8, 0xa8, 0xb6, 0xb6, 0xb6, 0x8a, 0x8a, 0x8a, +0xf7, 0xf7, 0xf7, 0xdd, 0xdd, 0xdd, 0xc6, 0xc7, +0xc7, 0x80, 0x80, 0x80, 0xc1, 0xc1, 0xc1, 0xce, +0xce, 0xcf, 0xa8, 0xa8, 0xa9, 0xd9, 0xda, 0xda, +0xc4, 0xc5, 0xc6, 0xce, 0xcf, 0xcf, 0xab, 0xab, +0xab, 0xcb, 0xcc, 0xcc, 0xa2, 0xa2, 0xa2, 0xde, +0xde, 0xde, 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, +0x94, 0x96, 0x96, 0xa1, 0xa1, 0xa1, 0xd6, 0xd7, +0xd7, 0xc4, 0xc5, 0xc5, 0xee, 0xee, 0xee, 0x9a, +0x9b, 0x9b, 0xc2, 0xcb, 0xce, 0xfb, 0xfb, 0xfb, +0x98, 0x98, 0x98, 0x8e, 0x8f, 0x8f, 0xfa, 0xfa, +0xfa, 0xaf, 0xba, 0xbe, 0xf0, 0xf0, 0xf0, 0xd4, +0xd4, 0xd5, 0xfd, 0xfd, 0xfd, 0x98, 0x9a, 0x9a, +0x8a, 0x8d, 0x8f, 0xa6, 0xb2, 0xb6, 0x8d, 0x8e, +0x8e, 0xe5, 0xe4, 0xe4, 0x9d, 0x9e, 0x9e, 0xcf, +0xd6, 0xd8, 0xac, 0xb7, 0xbc, 0x82, 0x86, 0x87, +0x91, 0x91, 0x91, 0xd7, 0xd7, 0xd7, 0x9e, 0x9d, +0x9d, 0x5e, 0x66, 0x2b, 0x65, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0x92, 0x49, 0x44, 0x41, 0x54, 0x18, +0xd3, 0x4d, 0xcf, 0xd7, 0x0e, 0xc2, 0x30, 0x0c, +0x05, 0xd0, 0xe4, 0xd2, 0xb2, 0x77, 0x1b, 0x56, +0x81, 0xb2, 0x37, 0xa5, 0xac, 0xb2, 0xf7, 0xfa, +0xff, 0x3f, 0xa2, 0x42, 0x0d, 0xb1, 0x25, 0xbf, +0x1c, 0x59, 0xd7, 0x36, 0x63, 0x7e, 0x71, 0xf0, +0x5f, 0xff, 0x0b, 0x21, 0x68, 0xd0, 0x41, 0x20, +0x1c, 0x89, 0xc6, 0xe2, 0x14, 0x12, 0xc9, 0x54, +0x3a, 0x43, 0x21, 0x9b, 0xcb, 0x1b, 0x26, 0x01, +0x51, 0x28, 0x96, 0xca, 0x15, 0xa1, 0xc0, 0xaa, +0xd6, 0xea, 0x76, 0xc3, 0x62, 0x64, 0xa4, 0xd9, +0x6a, 0x0b, 0x8d, 0x00, 0x3a, 0xdd, 0x5e, 0x5f, +0x1d, 0xc2, 0x81, 0xc1, 0x70, 0x34, 0x9e, 0x4c, +0x03, 0xe1, 0x8e, 0x3e, 0x73, 0x31, 0x77, 0x16, +0xcb, 0x60, 0x0f, 0x56, 0x6b, 0xcf, 0xc4, 0x06, +0xd8, 0x4a, 0xd8, 0x01, 0x7b, 0x1c, 0x8e, 0xa7, +0xb3, 0x04, 0xe3, 0xe2, 0x5d, 0x71, 0xbb, 0x3f, +0x9e, 0x32, 0xe3, 0xe5, 0xbe, 0x3f, 0xdc, 0x4f, +0xa6, 0x5b, 0xd4, 0xeb, 0x5f, 0x63, 0x0b, 0x0b, +0x6b, 0xf2, 0xd8, 0x63, 0x55, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *clip_cut_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_clip_cut_png = new wxImage(); + if (!img_clip_cut_png || !img_clip_cut_png->IsOk()) + { + wxMemoryInputStream img_clip_cut_pngIS(clip_cut_png_data, sizeof(clip_cut_png_data)); + img_clip_cut_png->LoadFile(img_clip_cut_pngIS, wxBITMAP_TYPE_PNG); + } + return img_clip_cut_png; +} +#define clip_cut_png_img clip_cut_png_img() + +static wxBitmap *clip_cut_png_bmp() +{ + static wxBitmap *bmp_clip_cut_png; + if (!bmp_clip_cut_png || !bmp_clip_cut_png->IsOk()) + bmp_clip_cut_png = new wxBitmap(*clip_cut_png_img); + return bmp_clip_cut_png; +} +#define clip_cut_png_bmp clip_cut_png_bmp() + +static wxIcon *clip_cut_png_ico() +{ + static wxIcon *ico_clip_cut_png; + if (!ico_clip_cut_png || !ico_clip_cut_png->IsOk()) + { + ico_clip_cut_png = new wxIcon(); + ico_clip_cut_png->CopyFromBitmap(*clip_cut_png_bmp); + } + return ico_clip_cut_png; +} +#define clip_cut_png_ico clip_cut_png_ico() + +#endif // CLIP_CUT_PNG_H diff --git a/include/images/clip_paste.png b/include/images/clip_paste.png new file mode 100644 index 0000000000000000000000000000000000000000..e09ebc51800bf6be0f77609b334e8e50955e6dbe GIT binary patch literal 646 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47?}cmLR^8|zP`SMgoMR2l9~%d z^U@uU9656Gk@Ari#WU4{PaePlj|&xueLh6!urq>n*$5&_RX{3J_vpRn*AM5O+ZK0rOZ=&g36I`?J@@48$%n6w+yVFM9n;iHT;?&Yao%KQzlaGky8Sf16nvm70{eq=Y6ey!?`P zLg$h+<&372Jly6-xMtr?DYJ;x+rcR;r*BeIr^j?Kz(T0^sPM^Y5%R5BYwtNsmb#R6xw=He_2nk*U5l^F^B79`FWdYxiE~>|)6_$e&bRx| zmTk9}@qfO5$BN$9@psG?)Nj92z0q>iEBhjN@7W>RdP`( zkYX@0Ff`CLG}1LN3^6jWGBLI?G0`?KwK6cUn5imzopr07bArZ~y=R literal 0 HcmV?d00001 diff --git a/include/images/clip_paste.pngc b/include/images/clip_paste.pngc new file mode 100644 index 0000000..8a69886 --- /dev/null +++ b/include/images/clip_paste.pngc @@ -0,0 +1,125 @@ +#ifndef CLIP_PASTE_PNG_H +#define CLIP_PASTE_PNG_H + +static const unsigned char clip_paste_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x02, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8e, 0x8e, 0x8e, 0x60, +0x60, 0x60, 0xa3, 0x98, 0x62, 0x83, 0x70, 0x15, +0x6e, 0x67, 0x41, 0xc4, 0xc4, 0xc4, 0xc9, 0xc9, +0xc9, 0xcf, 0xcf, 0xcf, 0x95, 0x8f, 0x63, 0xe8, +0xe8, 0xe8, 0xf0, 0xf0, 0xf0, 0x90, 0x88, 0x66, +0xe1, 0xd1, 0x67, 0xd7, 0xd7, 0xd7, 0xdf, 0xdf, +0xdf, 0xf7, 0xf7, 0xf7, 0xfd, 0xfd, 0xfd, 0xff, +0xff, 0xff, 0xd2, 0xbc, 0x70, 0xdb, 0xc7, 0x57, +0x8e, 0x83, 0x4f, 0x85, 0x78, 0x53, 0xc9, 0xae, +0x61, 0xda, 0xc6, 0x58, 0xcd, 0xb3, 0x37, 0xcb, +0xb1, 0x38, 0xc9, 0xae, 0x39, 0xc7, 0xab, 0x3a, +0xc5, 0xa8, 0x3b, 0xc2, 0xa4, 0x3c, 0xc0, 0xa1, +0x3e, 0xbe, 0x9e, 0x3f, 0xbb, 0x9a, 0x40, 0xb9, +0x97, 0x41, 0xc7, 0xac, 0x62, 0xd8, 0xc4, 0x58, +0x88, 0x7c, 0x51, 0xd7, 0xc2, 0x59, 0xf2, 0xf9, +0xfc, 0xe7, 0xf3, 0xf8, 0xe5, 0xf2, 0xf7, 0xe3, +0xf0, 0xf6, 0xe0, 0xee, 0xf4, 0xd5, 0xc0, 0x5a, +0xd7, 0xea, 0xf3, 0xd3, 0xe8, 0xf1, 0xcf, 0xe5, +0xee, 0xca, 0xe2, 0xeb, 0xdc, 0xeb, 0xf0, 0xda, +0xc7, 0x6c, 0xc8, 0xad, 0x43, 0xe4, 0xf1, 0xf7, +0x2c, 0x66, 0xbd, 0xc5, 0xde, 0xe7, 0xd7, 0xc3, +0x6d, 0xce, 0xb6, 0x5e, 0xcd, 0xb4, 0x5f, 0xca, +0xb1, 0x60, 0xe2, 0xef, 0xf5, 0xce, 0xe4, 0xed, +0xc9, 0xe1, 0xea, 0xc4, 0xdd, 0xe7, 0xbf, 0xda, +0xe4, 0xba, 0xd6, 0xe0, 0xb5, 0xd2, 0xdd, 0xcc, +0xe0, 0xe7, 0xde, 0xed, 0xf3, 0xc8, 0xdd, 0xe4, +0xdb, 0xeb, 0xf1, 0xc3, 0xdc, 0xe6, 0xbd, 0xd9, +0xe3, 0xb8, 0xd5, 0xdf, 0xb3, 0xd1, 0xdc, 0xae, +0xce, 0xd9, 0xaa, 0xcb, 0xd6, 0xc4, 0xdb, 0xe2, +0xd7, 0xe8, 0xef, 0xc2, 0xd9, 0xe0, 0xe5, 0xef, +0xf4, 0xd0, 0xe3, 0xea, 0xcd, 0xe0, 0xe8, 0xca, +0xde, 0xe6, 0xc6, 0xdc, 0xe4, 0xc1, 0xd9, 0xe0, +0xd9, 0xe7, 0xec, 0x18, 0xe5, 0x5d, 0x69, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, +0x62, 0x4b, 0x47, 0x44, 0x12, 0x7b, 0xbc, 0x6c, +0x00, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0xae, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x3d, 0x8e, 0x45, 0x16, 0xc3, 0x30, 0x14, 0x03, +0x13, 0xc5, 0x29, 0x33, 0x33, 0x33, 0x53, 0xca, +0xcc, 0xcc, 0xbd, 0xff, 0x55, 0x6a, 0x3b, 0x69, +0x67, 0xa7, 0xb1, 0xfe, 0xb3, 0x04, 0x81, 0x22, +0x82, 0x22, 0x0a, 0x1a, 0x12, 0x91, 0xa1, 0xd3, +0xe9, 0x0d, 0x90, 0x89, 0xa4, 0x66, 0x23, 0x68, +0x82, 0xc9, 0x0c, 0x0b, 0x37, 0xc4, 0x0a, 0x9b, +0xdd, 0x64, 0x76, 0x38, 0x5d, 0x2e, 0xb8, 0x09, +0x13, 0x1e, 0x2f, 0x34, 0x7c, 0x7e, 0x2e, 0x02, +0xc1, 0x50, 0x38, 0x12, 0x8d, 0xc5, 0x13, 0xc9, +0x54, 0x9a, 0x8b, 0x0c, 0xcb, 0x59, 0xb5, 0x23, +0x33, 0x91, 0x63, 0xef, 0xc8, 0x17, 0x8a, 0xa5, +0x32, 0xff, 0x9b, 0x54, 0x58, 0x1f, 0x85, 0x6a, +0xad, 0xde, 0x40, 0x93, 0x1a, 0xd2, 0x6a, 0xd3, +0x7b, 0x74, 0x14, 0x45, 0xe9, 0xb2, 0x2b, 0xba, +0xa3, 0xd7, 0x1f, 0x0c, 0x31, 0x1a, 0x4f, 0xa6, +0xb3, 0xf9, 0x62, 0x09, 0xb6, 0x8c, 0x82, 0x95, +0xc2, 0x59, 0x43, 0xdb, 0x8f, 0xcd, 0x76, 0xb7, +0x3f, 0x1c, 0x4f, 0xe7, 0xbf, 0xb8, 0xa8, 0x8d, +0xeb, 0x5f, 0xdc, 0xee, 0x8f, 0xe7, 0xeb, 0xfc, +0xfe, 0xfc, 0x84, 0xf8, 0x9b, 0x2f, 0x7e, 0x01, +0xfb, 0xda, 0x14, 0x63, 0x8f, 0x4e, 0x34, 0x91, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, +0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *clip_paste_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_clip_paste_png = new wxImage(); + if (!img_clip_paste_png || !img_clip_paste_png->IsOk()) + { + wxMemoryInputStream img_clip_paste_pngIS(clip_paste_png_data, sizeof(clip_paste_png_data)); + img_clip_paste_png->LoadFile(img_clip_paste_pngIS, wxBITMAP_TYPE_PNG); + } + return img_clip_paste_png; +} +#define clip_paste_png_img clip_paste_png_img() + +static wxBitmap *clip_paste_png_bmp() +{ + static wxBitmap *bmp_clip_paste_png; + if (!bmp_clip_paste_png || !bmp_clip_paste_png->IsOk()) + bmp_clip_paste_png = new wxBitmap(*clip_paste_png_img); + return bmp_clip_paste_png; +} +#define clip_paste_png_bmp clip_paste_png_bmp() + +static wxIcon *clip_paste_png_ico() +{ + static wxIcon *ico_clip_paste_png; + if (!ico_clip_paste_png || !ico_clip_paste_png->IsOk()) + { + ico_clip_paste_png = new wxIcon(); + ico_clip_paste_png->CopyFromBitmap(*clip_paste_png_bmp); + } + return ico_clip_paste_png; +} +#define clip_paste_png_ico clip_paste_png_ico() + +#endif // CLIP_PASTE_PNG_H diff --git a/include/images/closeddatabase-sm.png b/include/images/closeddatabase-sm.png new file mode 100644 index 0000000000000000000000000000000000000000..0bf4b6d95535ad518761daf021a7cf733c44255e GIT binary patch literal 853 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47*7QFgt!8^w=XO^wX%%+quAFW@wmW^> zVz<+K>JP3>eEn$8|GzK({<`z)$HgxnkG_Aq`_;=W&!295_H5(bYYX*d3P zpWmGO{^`>9FIT>QzxVa)t*>8he|UH4{o8XN-(1{0$7$<4_ZRn%etmQ6_m^kS=k#25 zvVSnSnZPZ1l_U@UMl1@8aW6D~O)alX+xi_1@qArGw*fZtnNn)?YBvd*-*5i=)AVlmSn}(%ch)B zl6nj@$H(Wbi_2qu{c{RZ+rngDK0Nv3m}iHV&O6Fa%1V%O5p-Tn$k7#VhXN$*)6dA!)? zr~vn^*t25l7TWj^I?5x+X zq@`xhI_MP@b^DgJ)$U!@Rlj2t_r08NPIsOk()) + { + wxMemoryInputStream img_closeddatabase_sm_pngIS(closeddatabase_sm_png_data, sizeof(closeddatabase_sm_png_data)); + img_closeddatabase_sm_png->LoadFile(img_closeddatabase_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_closeddatabase_sm_png; +} +#define closeddatabase_sm_png_img closeddatabase_sm_png_img() + +static wxBitmap *closeddatabase_sm_png_bmp() +{ + static wxBitmap *bmp_closeddatabase_sm_png; + if (!bmp_closeddatabase_sm_png || !bmp_closeddatabase_sm_png->IsOk()) + bmp_closeddatabase_sm_png = new wxBitmap(*closeddatabase_sm_png_img); + return bmp_closeddatabase_sm_png; +} +#define closeddatabase_sm_png_bmp closeddatabase_sm_png_bmp() + +static wxIcon *closeddatabase_sm_png_ico() +{ + static wxIcon *ico_closeddatabase_sm_png; + if (!ico_closeddatabase_sm_png || !ico_closeddatabase_sm_png->IsOk()) + { + ico_closeddatabase_sm_png = new wxIcon(); + ico_closeddatabase_sm_png->CopyFromBitmap(*closeddatabase_sm_png_bmp); + } + return ico_closeddatabase_sm_png; +} +#define closeddatabase_sm_png_ico closeddatabase_sm_png_ico() + +#endif // CLOSEDDATABASE_SM_PNG_H diff --git a/include/images/closeddatabase.png b/include/images/closeddatabase.png new file mode 100644 index 0000000000000000000000000000000000000000..96832908714ed515d594bd898486b8b925c7331f GIT binary patch literal 814 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47;6K3LR^8|%SR_3-jKC@f%p1p z=FjdOxOljC(`@TwTQYB*?t6A;<=Yo~KYcp%{>}C$_ZM9|*KulZ?w++l>t~o9T$_CN z!p#4F-~Ipl_}|YPKYw2Q`r+uucYEHv-1PM6>L(8u+`m8j_@1l{Gpt`e-2Uh1&0pWo zfBAC!-Mf8n-|l|%a{t@6r@nl-{paVW9gFPxY9yKO{1 zzr1xfE$Lf%`Ne3nkKy5WGc!NExcRND>|0UM*Sx$7QO586{oi?b{{QvmZhF$!+}tl2 z8K0AqK7@w;|M~87V&cc>=nugm?|uE=xx4@W_5RXUUZ|=*S5Vk6 z)AG=|)Z53VT#fdA>*Rd-MB3>fo#*ljd+fwd1=`$BPkH-fS2-{O7)yfuf*Bm1-ADs+ zI14-?i-EKU7`vU!wgWO=c)B=-NL)@%0D_dHG)AU0HMcN@{>I+9&6B%lw@>encL?B6 zQP5G+Qqxn^RMl11R@dhd2?!7o4Gszm3=O`1;mRd8t`{#}y_A-al9Zf1W7f>q4J2Zsf@0Rf1qITQrR4-AMR`pRU)EAHJ7;EOcgu`1sk_*rr#Ck#sK`qz#8v7-&zByb+iTv) zY>?bJt#aE>)>en;qOPvSZ3a`OOq+T;?8dLKu$y7cAq{)ulcSlx)UC~xWoD@JF#fK# zIy4LDXVntdh?11Vl2ohYqEsNoU}RuuplfKPYhV~+WME}tY-M7iZD49;U|=y*RSrc% nZhlH;S|vn-fhAZ2NVS!L8AQXW>7i?Y8W=oX{an^LB{Ts5xrU7; literal 0 HcmV?d00001 diff --git a/include/images/closeddatabase.pngc b/include/images/closeddatabase.pngc new file mode 100644 index 0000000..0777f0e --- /dev/null +++ b/include/images/closeddatabase.pngc @@ -0,0 +1,146 @@ +#ifndef CLOSEDDATABASE_PNG_H +#define CLOSEDDATABASE_PNG_H + +static const unsigned char closeddatabase_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x7d, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xd3, 0xc5, 0x91, 0xc3, +0xb0, 0x6a, 0xb7, 0xa0, 0x4b, 0xaf, 0x96, 0x37, +0xe6, 0xde, 0xc0, 0xd1, 0xc3, 0x8d, 0xb2, 0x9b, +0x3b, 0xc6, 0xb4, 0x69, 0xda, 0xcb, 0x8e, 0xe6, +0xdc, 0xa9, 0xed, 0xe8, 0xbd, 0xf2, 0xf2, 0xc2, +0xef, 0xec, 0xb7, 0xe4, 0xdf, 0xa2, 0xd6, 0xce, +0x88, 0xca, 0xbd, 0x6d, 0xbc, 0xad, 0x52, 0xaf, +0x98, 0x36, 0xc1, 0xad, 0x63, 0xdd, 0xd0, 0x99, +0xff, 0xfd, 0xee, 0xff, 0xfd, 0xe3, 0xfe, 0xf9, +0xd8, 0xf9, 0xf9, 0xd1, 0xf5, 0xf0, 0xc5, 0xf1, +0xee, 0xbc, 0xec, 0xe9, 0xb2, 0xe5, 0xe5, 0xab, +0xe4, 0xe1, 0xa0, 0xdf, 0xdf, 0x9b, 0xc7, 0xbc, +0x6a, 0xb0, 0x98, 0x3b, 0xe9, 0xe1, 0xb7, 0xfc, +0xf9, 0xd9, 0xfa, 0xf7, 0xcf, 0xf4, 0xf4, 0xc7, +0xee, 0xee, 0xbe, 0xed, 0xed, 0xbb, 0xec, 0xe9, +0xbf, 0xed, 0xed, 0xca, 0xf4, 0xf4, 0xdb, 0xfc, +0xf9, 0xf2, 0xb8, 0xa2, 0x4e, 0xac, 0x92, 0x30, +0xe3, 0xdb, 0xbd, 0xe9, 0xdc, 0xb9, 0xed, 0xe3, +0xbb, 0xf5, 0xf0, 0xd4, 0xf5, 0xf2, 0xd9, 0xfb, +0xfb, 0xf1, 0xfe, 0xfe, 0xfb, 0xf7, 0xf4, 0xe8, +0xf0, 0xed, 0xd2, 0xec, 0xe9, 0xc4, 0xea, 0xe2, +0xba, 0xe5, 0xdd, 0xc2, 0xf4, 0xea, 0xd8, 0xff, +0xf8, 0xf3, 0xff, 0xf7, 0xee, 0xdc, 0x64, 0x57, +0xc5, 0x00, 0x00, 0xd5, 0x5d, 0x3f, 0xe1, 0xd9, +0x84, 0xe0, 0xda, 0x7b, 0xd2, 0x5d, 0x3e, 0xbb, +0x3c, 0x14, 0xf3, 0xe9, 0xda, 0xdd, 0x66, 0x62, +0xf6, 0x77, 0x77, 0xd1, 0x5b, 0x36, 0xf1, 0x57, +0x57, 0xdd, 0x69, 0x69, 0xf2, 0xe8, 0xd9, 0xf6, +0x76, 0x76, 0xf6, 0x72, 0x72, 0xf5, 0x6e, 0x6e, +0xd0, 0x5a, 0x33, 0xef, 0x4f, 0x4f, 0xee, 0x48, +0x49, 0xff, 0xfa, 0xf4, 0xdd, 0x67, 0x62, 0xf5, +0x6d, 0x6d, 0xf4, 0x68, 0x68, 0xf3, 0x62, 0x62, +0xf0, 0x55, 0x55, 0xff, 0xf9, 0xee, 0xf3, 0x61, +0x61, 0xf1, 0x5b, 0x5b, 0xf0, 0x53, 0x54, 0xef, +0x4d, 0x4e, 0xee, 0x47, 0x47, 0xff, 0xfa, 0xef, +0xfe, 0xf4, 0xd3, 0xd9, 0x62, 0x4a, 0xef, 0x4d, +0x4d, 0xd4, 0x5e, 0x46, 0xf0, 0x53, 0x53, 0xef, +0x4c, 0x4c, 0xee, 0x45, 0x45, 0xec, 0x3e, 0x3f, +0xeb, 0x38, 0x38, 0xf2, 0xea, 0xd9, 0xf0, 0x52, +0x52, 0xef, 0x4b, 0x4b, 0xed, 0x44, 0x45, 0xeb, +0x37, 0x37, 0xea, 0x31, 0x31, 0xe9, 0x2b, 0x2b, +0xcb, 0xbc, 0x82, 0xff, 0xf8, 0xf2, 0xf0, 0x51, +0x51, 0xee, 0x4a, 0x4a, 0xed, 0x43, 0x44, 0xe8, +0x25, 0x25, 0xe7, 0x20, 0x20, 0xb0, 0x99, 0x39, +0xc2, 0xae, 0x65, 0xdb, 0xc6, 0x94, 0xd5, 0x5b, +0x4b, 0xed, 0x42, 0x43, 0xd3, 0xc8, 0x66, 0xcb, +0x52, 0x2c, 0xe7, 0x1f, 0x20, 0xbc, 0x3e, 0x17, +0xca, 0x51, 0x3c, 0xdb, 0x67, 0x64, 0xed, 0xe4, +0xba, 0x77, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0xe8, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, +0x60, 0x60, 0x60, 0x64, 0x62, 0x66, 0x01, 0x02, +0x66, 0x26, 0x46, 0x56, 0x20, 0x8f, 0x81, 0x8d, +0x9d, 0x83, 0x93, 0x8b, 0x9b, 0x87, 0x97, 0x8f, +0x5f, 0x40, 0x50, 0x08, 0x24, 0x20, 0x2c, 0x22, +0x2a, 0x26, 0x2e, 0x21, 0x29, 0x25, 0x2d, 0x23, +0x2b, 0x27, 0x2f, 0x0c, 0x14, 0x50, 0x50, 0x14, +0x15, 0x53, 0x52, 0x56, 0x51, 0x55, 0x53, 0xd7, +0xd0, 0xd4, 0xd2, 0x06, 0x0a, 0xe8, 0xe8, 0xea, +0xe9, 0x1b, 0x18, 0x1a, 0x19, 0x19, 0x9b, 0x98, +0x9a, 0x99, 0xeb, 0x80, 0x04, 0x2c, 0x2c, 0xad, +0xac, 0x6d, 0x6c, 0xed, 0xec, 0x1d, 0xec, 0x1d, +0x6d, 0x9d, 0xc0, 0x02, 0xce, 0x56, 0x2e, 0xb6, +0xae, 0xb6, 0x6e, 0x0e, 0x6e, 0xb6, 0xee, 0xb6, +0x1e, 0x20, 0x01, 0x4f, 0x2b, 0x5b, 0x2f, 0x6f, +0x1f, 0x5b, 0x5f, 0x5b, 0x77, 0x3f, 0x7f, 0x5b, +0xb0, 0x40, 0x40, 0xa0, 0x6d, 0x50, 0x70, 0x88, +0x6d, 0x28, 0x90, 0x0f, 0x51, 0x11, 0x10, 0x66, +0x63, 0x1b, 0x1e, 0x11, 0x19, 0x15, 0x0d, 0x35, +0xc3, 0xd3, 0x2a, 0x26, 0x36, 0xce, 0x36, 0x32, +0x3e, 0xda, 0x36, 0x01, 0x62, 0x8b, 0x73, 0x40, +0x8c, 0x8d, 0x6d, 0x62, 0x52, 0x72, 0x4a, 0x2a, +0x54, 0x45, 0x1a, 0xd0, 0x8c, 0xf4, 0x8c, 0x4c, +0xdb, 0xac, 0xec, 0x1c, 0xb0, 0x19, 0xb9, 0x96, +0x79, 0xb6, 0xf9, 0x05, 0x85, 0x40, 0x5b, 0x72, +0x8a, 0x8a, 0x81, 0xb6, 0x30, 0x94, 0x94, 0x96, +0x95, 0xdb, 0x56, 0xd8, 0xfa, 0x56, 0x56, 0xd9, +0x56, 0x83, 0x54, 0x80, 0xbd, 0x5f, 0x63, 0x5b, +0x03, 0xf4, 0x7e, 0xad, 0x6d, 0x1d, 0x03, 0x00, +0x7e, 0x48, 0x33, 0xf7, 0x26, 0xab, 0x55, 0x6a, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, +0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *closeddatabase_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_closeddatabase_png = new wxImage(); + if (!img_closeddatabase_png || !img_closeddatabase_png->IsOk()) + { + wxMemoryInputStream img_closeddatabase_pngIS(closeddatabase_png_data, sizeof(closeddatabase_png_data)); + img_closeddatabase_png->LoadFile(img_closeddatabase_pngIS, wxBITMAP_TYPE_PNG); + } + return img_closeddatabase_png; +} +#define closeddatabase_png_img closeddatabase_png_img() + +static wxBitmap *closeddatabase_png_bmp() +{ + static wxBitmap *bmp_closeddatabase_png; + if (!bmp_closeddatabase_png || !bmp_closeddatabase_png->IsOk()) + bmp_closeddatabase_png = new wxBitmap(*closeddatabase_png_img); + return bmp_closeddatabase_png; +} +#define closeddatabase_png_bmp closeddatabase_png_bmp() + +static wxIcon *closeddatabase_png_ico() +{ + static wxIcon *ico_closeddatabase_png; + if (!ico_closeddatabase_png || !ico_closeddatabase_png->IsOk()) + { + ico_closeddatabase_png = new wxIcon(); + ico_closeddatabase_png->CopyFromBitmap(*closeddatabase_png_bmp); + } + return ico_closeddatabase_png; +} +#define closeddatabase_png_ico closeddatabase_png_ico() + +#endif // CLOSEDDATABASE_PNG_H diff --git a/include/images/collation-sm.png b/include/images/collation-sm.png new file mode 100644 index 0000000000000000000000000000000000000000..0bc8ff7d260f82c275ba5df3252d23b441714413 GIT binary patch literal 233 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|I14-?iy0WW zg+Z8+Vb&Z8pdfpRr>`sfZ5B>`Y1Vg3uj>JYBuiW)N}Tg^b5rw57@Uhz6H8K46v{J8 zG8EiBeFMT9`NV;W!aQ9ZLp07O|M~ylo>{Y@v(e>%QT@M~OC|;e1{JY;xgK_W{{m$0 z(a}7(v}*P?vy*;{_Oi8Aetz~>UFyti^ZqXhu6$xm3y&CRICmD_+f%tDb3tVmE5nZC WPAwi!3pN04VDNPHb6Mw<&;$TuGEA%h literal 0 HcmV?d00001 diff --git a/include/images/collation-sm.pngc b/include/images/collation-sm.pngc new file mode 100644 index 0000000..e054f7c --- /dev/null +++ b/include/images/collation-sm.pngc @@ -0,0 +1,74 @@ +#ifndef COLLATION_SM_PNG_H +#define COLLATION_SM_PNG_H + +static const unsigned char collation_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x02, 0x00, 0x00, 0x00, 0x90, 0x91, 0x68, +0x36, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, +0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74, +0x49, 0x4d, 0x45, 0x07, 0xdb, 0x04, 0x09, 0x0f, +0x1b, 0x05, 0xee, 0xa5, 0xd7, 0x2e, 0x00, 0x00, +0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, +0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x43, 0x72, +0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, +0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, +0x81, 0x0e, 0x17, 0x00, 0x00, 0x00, 0x56, 0x49, +0x44, 0x41, 0x54, 0x28, 0xcf, 0x63, 0xfc, 0xff, +0xff, 0x3f, 0x03, 0x29, 0x80, 0x89, 0x81, 0x44, +0xc0, 0x32, 0x7f, 0xfe, 0x7c, 0xd2, 0x34, 0x30, +0x30, 0x30, 0x78, 0x5d, 0xbd, 0x0a, 0xe1, 0x88, +0xf7, 0xf4, 0x30, 0x30, 0x30, 0xbc, 0x2c, 0x29, +0xc1, 0xa5, 0x7a, 0x9b, 0xb6, 0x36, 0xc9, 0x4e, +0xa2, 0xbd, 0x06, 0x86, 0x79, 0xf3, 0xe6, 0xfd, +0x27, 0x1a, 0xcc, 0x9b, 0x37, 0x8f, 0xf4, 0x60, +0x45, 0x0e, 0x16, 0x82, 0xa1, 0xc4, 0x30, 0x28, +0x43, 0x89, 0x71, 0xde, 0xbc, 0x79, 0xa4, 0x69, +0xa0, 0x79, 0x6a, 0x05, 0x00, 0xb8, 0xc7, 0x42, +0x84, 0x48, 0xe5, 0x70, 0xb0, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *collation_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_collation_sm_png = new wxImage(); + if (!img_collation_sm_png || !img_collation_sm_png->IsOk()) + { + wxMemoryInputStream img_collation_sm_pngIS(collation_sm_png_data, sizeof(collation_sm_png_data)); + img_collation_sm_png->LoadFile(img_collation_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_collation_sm_png; +} +#define collation_sm_png_img collation_sm_png_img() + +static wxBitmap *collation_sm_png_bmp() +{ + static wxBitmap *bmp_collation_sm_png; + if (!bmp_collation_sm_png || !bmp_collation_sm_png->IsOk()) + bmp_collation_sm_png = new wxBitmap(*collation_sm_png_img); + return bmp_collation_sm_png; +} +#define collation_sm_png_bmp collation_sm_png_bmp() + +static wxIcon *collation_sm_png_ico() +{ + static wxIcon *ico_collation_sm_png; + if (!ico_collation_sm_png || !ico_collation_sm_png->IsOk()) + { + ico_collation_sm_png = new wxIcon(); + ico_collation_sm_png->CopyFromBitmap(*collation_sm_png_bmp); + } + return ico_collation_sm_png; +} +#define collation_sm_png_ico collation_sm_png_ico() + +#endif // COLLATION_SM_PNG_H diff --git a/include/images/collation.png b/include/images/collation.png new file mode 100644 index 0000000000000000000000000000000000000000..0bc8ff7d260f82c275ba5df3252d23b441714413 GIT binary patch literal 233 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|I14-?iy0WW zg+Z8+Vb&Z8pdfpRr>`sfZ5B>`Y1Vg3uj>JYBuiW)N}Tg^b5rw57@Uhz6H8K46v{J8 zG8EiBeFMT9`NV;W!aQ9ZLp07O|M~ylo>{Y@v(e>%QT@M~OC|;e1{JY;xgK_W{{m$0 z(a}7(v}*P?vy*;{_Oi8Aetz~>UFyti^ZqXhu6$xm3y&CRICmD_+f%tDb3tVmE5nZC WPAwi!3pN04VDNPHb6Mw<&;$TuGEA%h literal 0 HcmV?d00001 diff --git a/include/images/collation.pngc b/include/images/collation.pngc new file mode 100644 index 0000000..ada945e --- /dev/null +++ b/include/images/collation.pngc @@ -0,0 +1,74 @@ +#ifndef COLLATION_PNG_H +#define COLLATION_PNG_H + +static const unsigned char collation_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x02, 0x00, 0x00, 0x00, 0x90, 0x91, 0x68, +0x36, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, +0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74, +0x49, 0x4d, 0x45, 0x07, 0xdb, 0x04, 0x09, 0x0f, +0x1b, 0x05, 0xee, 0xa5, 0xd7, 0x2e, 0x00, 0x00, +0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, +0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x43, 0x72, +0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, +0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, +0x81, 0x0e, 0x17, 0x00, 0x00, 0x00, 0x56, 0x49, +0x44, 0x41, 0x54, 0x28, 0xcf, 0x63, 0xfc, 0xff, +0xff, 0x3f, 0x03, 0x29, 0x80, 0x89, 0x81, 0x44, +0xc0, 0x32, 0x7f, 0xfe, 0x7c, 0xd2, 0x34, 0x30, +0x30, 0x30, 0x78, 0x5d, 0xbd, 0x0a, 0xe1, 0x88, +0xf7, 0xf4, 0x30, 0x30, 0x30, 0xbc, 0x2c, 0x29, +0xc1, 0xa5, 0x7a, 0x9b, 0xb6, 0x36, 0xc9, 0x4e, +0xa2, 0xbd, 0x06, 0x86, 0x79, 0xf3, 0xe6, 0xfd, +0x27, 0x1a, 0xcc, 0x9b, 0x37, 0x8f, 0xf4, 0x60, +0x45, 0x0e, 0x16, 0x82, 0xa1, 0xc4, 0x30, 0x28, +0x43, 0x89, 0x71, 0xde, 0xbc, 0x79, 0xa4, 0x69, +0xa0, 0x79, 0x6a, 0x05, 0x00, 0xb8, 0xc7, 0x42, +0x84, 0x48, 0xe5, 0x70, 0xb0, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *collation_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_collation_png = new wxImage(); + if (!img_collation_png || !img_collation_png->IsOk()) + { + wxMemoryInputStream img_collation_pngIS(collation_png_data, sizeof(collation_png_data)); + img_collation_png->LoadFile(img_collation_pngIS, wxBITMAP_TYPE_PNG); + } + return img_collation_png; +} +#define collation_png_img collation_png_img() + +static wxBitmap *collation_png_bmp() +{ + static wxBitmap *bmp_collation_png; + if (!bmp_collation_png || !bmp_collation_png->IsOk()) + bmp_collation_png = new wxBitmap(*collation_png_img); + return bmp_collation_png; +} +#define collation_png_bmp collation_png_bmp() + +static wxIcon *collation_png_ico() +{ + static wxIcon *ico_collation_png; + if (!ico_collation_png || !ico_collation_png->IsOk()) + { + ico_collation_png = new wxIcon(); + ico_collation_png->CopyFromBitmap(*collation_png_bmp); + } + return ico_collation_png; +} +#define collation_png_ico collation_png_ico() + +#endif // COLLATION_PNG_H diff --git a/include/images/collations.png b/include/images/collations.png new file mode 100644 index 0000000000000000000000000000000000000000..fa46a49b36bd910f1aab83a0d82576f5e1fb74c5 GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9GG!XV7ZFl&wkP%y>Q z#WBR<^xjE$lBKJZ&qE)`;EOW5#Oc%8;RXl53*~!-2V< zH~d^R_2AruX-C=}CjGnPrgEEQ;e5Nv4expPX-b^5WV(FH{>PFFJ3p3QzQizT8&}^; Z#<$nB^!IGkwF275;OXk;vd$@?2>?$7Ktuol literal 0 HcmV?d00001 diff --git a/include/images/collations.pngc b/include/images/collations.pngc new file mode 100644 index 0000000..feb15ac --- /dev/null +++ b/include/images/collations.pngc @@ -0,0 +1,67 @@ +#ifndef COLLATIONS_PNG_H +#define COLLATIONS_PNG_H + +static const unsigned char collations_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff, +0x61, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, +0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, +0x00, 0x64, 0x49, 0x44, 0x41, 0x54, 0x38, 0xcb, +0xbd, 0x92, 0x51, 0x0a, 0xc0, 0x20, 0x0c, 0x43, +0x13, 0xf0, 0x0e, 0xee, 0x9e, 0x7a, 0x0c, 0xbd, +0xa7, 0x3b, 0x45, 0xf6, 0xb3, 0x82, 0x0c, 0x86, +0xa8, 0xc5, 0x7c, 0x16, 0xda, 0xbc, 0x36, 0x05, +0x36, 0x45, 0x00, 0x68, 0x29, 0xc9, 0x0a, 0xb1, +0x14, 0x00, 0xc0, 0x9d, 0xf3, 0xb0, 0xf9, 0xaa, +0x95, 0xc1, 0x9d, 0x60, 0x96, 0xc4, 0x87, 0x40, +0x92, 0xfe, 0xdc, 0x46, 0x24, 0xdb, 0x04, 0xa1, +0x9f, 0x3e, 0x93, 0x80, 0xef, 0x0d, 0xbe, 0x29, +0x18, 0xc9, 0x39, 0x02, 0xd3, 0xca, 0x3f, 0xf8, +0xa4, 0xd0, 0xb9, 0xf1, 0x75, 0xd3, 0xd2, 0x00, +0x92, 0xb6, 0x0a, 0x8e, 0xe9, 0x01, 0xed, 0xd6, +0x2a, 0x2f, 0xbc, 0xb1, 0x2d, 0x3a, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *collations_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_collations_png = new wxImage(); + if (!img_collations_png || !img_collations_png->IsOk()) + { + wxMemoryInputStream img_collations_pngIS(collations_png_data, sizeof(collations_png_data)); + img_collations_png->LoadFile(img_collations_pngIS, wxBITMAP_TYPE_PNG); + } + return img_collations_png; +} +#define collations_png_img collations_png_img() + +static wxBitmap *collations_png_bmp() +{ + static wxBitmap *bmp_collations_png; + if (!bmp_collations_png || !bmp_collations_png->IsOk()) + bmp_collations_png = new wxBitmap(*collations_png_img); + return bmp_collations_png; +} +#define collations_png_bmp collations_png_bmp() + +static wxIcon *collations_png_ico() +{ + static wxIcon *ico_collations_png; + if (!ico_collations_png || !ico_collations_png->IsOk()) + { + ico_collations_png = new wxIcon(); + ico_collations_png->CopyFromBitmap(*collations_png_bmp); + } + return ico_collations_png; +} +#define collations_png_ico collations_png_ico() + +#endif // COLLATIONS_PNG_H diff --git a/include/images/column-sm.png b/include/images/column-sm.png new file mode 100644 index 0000000000000000000000000000000000000000..edbb7b01304ad05d1d972760bb6815b056f79371 GIT binary patch literal 371 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}NPtg>E08W)b4_vT^DWoj-MxGF z>C>mro;_>d|9si9WpCcRS+{Q8%a<=#u3Wix?b`M0*S~u8>fXJ34<0;t`0(NL=g&WU z`0(x9w;elnY}l}2IX5CfXaSQ6wH%;50sMjDXAS>O>_45U54 z*zIJt9gq>`>Eak7ak=;0K`{pf0f&nzE^0>&1poh^KgY~htZ)0C)yuD}mzt}+AiCk) z7grOWV|@{gvugwl^jln*PAKk@nx}PwGve>DiL4Lmj?7@0^X<`;C$F;qZk9fjz`QTH z|1}HH2GtVRh?11Vl2ohYqEsNoU}RuuplfKPYhV~+WME}tY-M7iZD49;U|=y*RSrc% nZhlH;S|vn-fhAZ2NVS!L8AQXW>7i?Y8W=oX{an^LB{Ts53`v=> literal 0 HcmV?d00001 diff --git a/include/images/column-sm.pngc b/include/images/column-sm.pngc new file mode 100644 index 0000000..73499c6 --- /dev/null +++ b/include/images/column-sm.pngc @@ -0,0 +1,91 @@ +#ifndef COLUMN_SM_PNG_H +#define COLUMN_SM_PNG_H + +static const unsigned char column_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x54, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x72, 0xac, 0xd6, 0x21, +0x95, 0xe7, 0xb4, 0xd6, 0xee, 0xdd, 0xdd, 0xdd, +0xe5, 0xe5, 0xe5, 0xe6, 0xe6, 0xe6, 0x87, 0xbf, +0xe7, 0xa6, 0xa6, 0xa6, 0xec, 0xec, 0xec, 0xae, +0xae, 0xae, 0xe9, 0xe9, 0xe9, 0xa9, 0xa9, 0xa9, +0xad, 0xad, 0xad, 0xaf, 0xaf, 0xaf, 0xea, 0xea, +0xea, 0xde, 0xde, 0xde, 0xe0, 0xe0, 0xe0, 0xe1, +0xe1, 0xe1, 0xe7, 0xe7, 0xe7, 0xf0, 0xf0, 0xf0, +0xf6, 0xf6, 0xf6, 0xb8, 0xb8, 0xb8, 0xb0, 0xb0, +0xb0, 0xb1, 0xb1, 0xb1, 0xf7, 0xf7, 0xf7, 0xeb, +0xeb, 0xeb, 0xed, 0xed, 0xed, 0xca, 0x15, 0xa0, +0x16, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x56, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x8d, 0xce, 0xc1, +0x16, 0x40, 0x20, 0x10, 0x40, 0xd1, 0x64, 0x44, +0x26, 0xc5, 0x30, 0x11, 0xff, 0xff, 0x9f, 0x9c, +0x36, 0x4d, 0x16, 0x8e, 0xb7, 0xbc, 0xab, 0xa7, +0xd4, 0xaf, 0x1a, 0x9d, 0x2b, 0xa0, 0x5b, 0x80, +0xce, 0xf4, 0x45, 0x34, 0x0c, 0xc6, 0x8e, 0x58, +0x81, 0x9b, 0x7c, 0x10, 0x30, 0x2f, 0x84, 0x44, +0x02, 0xc8, 0x21, 0xba, 0x1a, 0x9e, 0x2a, 0xc8, +0x09, 0x58, 0xfd, 0xc6, 0x91, 0x05, 0xe0, 0x7e, +0xc4, 0x98, 0x04, 0x9c, 0xf6, 0xe2, 0x94, 0xe4, +0xea, 0x6b, 0xfd, 0xb3, 0x1b, 0xc2, 0x60, 0x03, +0xbe, 0x63, 0x8f, 0xeb, 0x04, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *column_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_column_sm_png = new wxImage(); + if (!img_column_sm_png || !img_column_sm_png->IsOk()) + { + wxMemoryInputStream img_column_sm_pngIS(column_sm_png_data, sizeof(column_sm_png_data)); + img_column_sm_png->LoadFile(img_column_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_column_sm_png; +} +#define column_sm_png_img column_sm_png_img() + +static wxBitmap *column_sm_png_bmp() +{ + static wxBitmap *bmp_column_sm_png; + if (!bmp_column_sm_png || !bmp_column_sm_png->IsOk()) + bmp_column_sm_png = new wxBitmap(*column_sm_png_img); + return bmp_column_sm_png; +} +#define column_sm_png_bmp column_sm_png_bmp() + +static wxIcon *column_sm_png_ico() +{ + static wxIcon *ico_column_sm_png; + if (!ico_column_sm_png || !ico_column_sm_png->IsOk()) + { + ico_column_sm_png = new wxIcon(); + ico_column_sm_png->CopyFromBitmap(*column_sm_png_bmp); + } + return ico_column_sm_png; +} +#define column_sm_png_ico column_sm_png_ico() + +#endif // COLUMN_SM_PNG_H diff --git a/include/images/column.png b/include/images/column.png new file mode 100644 index 0000000000000000000000000000000000000000..bd9f81df98fe27d81ade5144d66b3b09b96123c1 GIT binary patch literal 435 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}X@F0NE09*4`h3Ev&s(m&yLCXv$t$X?M<;s;SSFBjEcJ12r>({?} z_3FWc2M-@UeDvti>eZ{)tXZ>Z)20s}KD>VY`qQURpFe;8`t|F#Z{K$8*s)>5hK(CH ze*gac?c2BS-o49eKe!ZVF=I)PUoeBivm0qZ4rhT!WHFHT0Ash4*>*risi%u$h{WaE z^B0Ah6a-om4Rm-iuV3+XfEpM)UHx3vIVCg! E0NRqnZ~y=R literal 0 HcmV?d00001 diff --git a/include/images/column.pngc b/include/images/column.pngc new file mode 100644 index 0000000..337b467 --- /dev/null +++ b/include/images/column.pngc @@ -0,0 +1,99 @@ +#ifndef COLUMN_PNG_H +#define COLUMN_PNG_H + +static const unsigned char column_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x75, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x21, 0x95, 0xe7, 0x90, +0xca, 0xf3, 0xb4, 0xd6, 0xee, 0xdd, 0xdd, 0xdd, +0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xe5, 0xe5, +0xe5, 0xe6, 0xe6, 0xe6, 0x87, 0xbf, 0xe7, 0xa6, +0xa6, 0xa6, 0xe7, 0xe7, 0xe7, 0xe8, 0xe8, 0xe8, +0xec, 0xec, 0xec, 0xae, 0xae, 0xae, 0xe9, 0xe9, +0xe9, 0xa9, 0xa9, 0xa9, 0xa8, 0xa8, 0xa8, 0xad, +0xad, 0xad, 0xaf, 0xaf, 0xaf, 0xea, 0xea, 0xea, +0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, +0xe2, 0xab, 0xab, 0xab, 0xac, 0xac, 0xac, 0xb2, +0xb2, 0xb2, 0xf0, 0xf0, 0xf0, 0xeb, 0xeb, 0xeb, +0xf2, 0xf2, 0xf2, 0xf3, 0xf3, 0xf3, 0xf5, 0xf5, +0xf5, 0xf6, 0xf6, 0xf6, 0xb8, 0xb8, 0xb8, 0xb0, +0xb0, 0xb0, 0xb1, 0xb1, 0xb1, 0xf7, 0xf7, 0xf7, +0xed, 0xed, 0xed, 0xee, 0xee, 0xee, 0x6a, 0x87, +0xc1, 0xa5, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x75, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x7d, 0xcf, +0xd1, 0x12, 0x82, 0x20, 0x10, 0x85, 0x61, 0x30, +0x2c, 0x0c, 0x69, 0xd7, 0xd4, 0x4d, 0x41, 0x0b, +0x4a, 0x7b, 0xff, 0x47, 0xcc, 0x29, 0xdd, 0xe1, +0xa2, 0xf1, 0xbf, 0xfc, 0x66, 0xce, 0xc5, 0x11, +0x62, 0x49, 0xae, 0x65, 0xe2, 0x97, 0x3c, 0x28, +0x95, 0x1f, 0x4f, 0xba, 0x90, 0x1b, 0xa8, 0xb3, +0x36, 0xa5, 0xbd, 0x40, 0x02, 0x58, 0xe1, 0xb5, +0x6e, 0x18, 0xf2, 0x96, 0xe8, 0x06, 0x44, 0x0c, +0x84, 0xb0, 0x84, 0x29, 0x7c, 0x4b, 0x60, 0x6d, +0x6f, 0xd2, 0xf5, 0x3d, 0x3a, 0xcf, 0xa0, 0x0d, +0x0c, 0x76, 0xbc, 0x3f, 0x18, 0x4c, 0xed, 0xfd, +0x18, 0x62, 0x60, 0x80, 0xe7, 0xcb, 0xb9, 0x18, +0x27, 0x86, 0xc1, 0xce, 0x6f, 0x1f, 0x26, 0x06, +0x7e, 0x2b, 0xfe, 0xf5, 0x01, 0xf2, 0x14, 0x08, +0x1f, 0x7b, 0x89, 0xff, 0x76, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *column_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_column_png = new wxImage(); + if (!img_column_png || !img_column_png->IsOk()) + { + wxMemoryInputStream img_column_pngIS(column_png_data, sizeof(column_png_data)); + img_column_png->LoadFile(img_column_pngIS, wxBITMAP_TYPE_PNG); + } + return img_column_png; +} +#define column_png_img column_png_img() + +static wxBitmap *column_png_bmp() +{ + static wxBitmap *bmp_column_png; + if (!bmp_column_png || !bmp_column_png->IsOk()) + bmp_column_png = new wxBitmap(*column_png_img); + return bmp_column_png; +} +#define column_png_bmp column_png_bmp() + +static wxIcon *column_png_ico() +{ + static wxIcon *ico_column_png; + if (!ico_column_png || !ico_column_png->IsOk()) + { + ico_column_png = new wxIcon(); + ico_column_png->CopyFromBitmap(*column_png_bmp); + } + return ico_column_png; +} +#define column_png_ico column_png_ico() + +#endif // COLUMN_PNG_H diff --git a/include/images/columns.png b/include/images/columns.png new file mode 100644 index 0000000000000000000000000000000000000000..89d758834d4176c1df2548db10b46b1f6b2e4ec5 GIT binary patch literal 400 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}cz{ocE09*4`h3Ev&s(m&yL({S;_3G90=g%KJ zc<}o5>kl73eEaro$BrEvHf-3qapU*z-`~D{TatgM6KFJJNswPKgTu2MX+REVfk$L9 zkoEv$x0Bg+Kt_S5i(`ny<=FG?VhsvBt`}W4E@ZQg__p6qm@nby;qrG1j0_I@c^(;r zuhP)2X?)FK#IZ0 zz|cU~&`8(7FvQ5f%EZ{p#6;V`)XKoXVy3DbiiX_$l+3hBhz0{oum+H7D+4o#hEvl+ R*8nvzc)I$ztaD0e0s#BYr!@co literal 0 HcmV?d00001 diff --git a/include/images/columns.pngc b/include/images/columns.pngc new file mode 100644 index 0000000..ce488b6 --- /dev/null +++ b/include/images/columns.pngc @@ -0,0 +1,94 @@ +#ifndef COLUMNS_PNG_H +#define COLUMNS_PNG_H + +static const unsigned char columns_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x57, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x21, 0x95, 0xe7, 0x90, +0xca, 0xf3, 0xb4, 0xd6, 0xee, 0xdd, 0xdd, 0xdd, +0xe5, 0xe5, 0xe5, 0xe6, 0xe6, 0xe6, 0x87, 0xbf, +0xe7, 0x63, 0x9d, 0xc7, 0xde, 0xde, 0xde, 0xe1, +0xe1, 0xe1, 0xa6, 0xa6, 0xa6, 0xec, 0xec, 0xec, +0xae, 0xae, 0xae, 0xe9, 0xe9, 0xe9, 0xa9, 0xa9, +0xa9, 0xad, 0xad, 0xad, 0xaf, 0xaf, 0xaf, 0xea, +0xea, 0xea, 0xe7, 0xe7, 0xe7, 0xe0, 0xe0, 0xe0, +0xeb, 0xeb, 0xeb, 0xf0, 0xf0, 0xf0, 0xf6, 0xf6, +0xf6, 0xb8, 0xb8, 0xb8, 0xb0, 0xb0, 0xb0, 0xb1, +0xb1, 0xb1, 0xf7, 0xf7, 0xf7, 0xed, 0xed, 0xed, +0x74, 0x6f, 0xc2, 0x89, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x70, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x5d, 0xcf, 0x47, 0x16, 0x80, 0x20, 0x0c, 0x45, +0xd1, 0x44, 0xb1, 0xa1, 0x06, 0x3b, 0x58, 0xf6, +0xbf, 0x4e, 0x13, 0x0e, 0x60, 0xf9, 0xc3, 0x77, +0xee, 0x20, 0x01, 0x00, 0x40, 0xbf, 0x0c, 0xe2, +0x30, 0x57, 0xaa, 0x28, 0x2b, 0x7c, 0x82, 0xaa, +0xbf, 0x06, 0xd5, 0xcf, 0x60, 0x93, 0x4c, 0x08, +0xfa, 0x67, 0x38, 0xb0, 0x69, 0xcb, 0xae, 0xa7, +0x14, 0xd8, 0xb4, 0x66, 0x18, 0xa7, 0x10, 0x66, +0x31, 0x8b, 0x26, 0xad, 0x43, 0x20, 0x31, 0x86, +0xc8, 0xc4, 0xb0, 0x8a, 0x31, 0xbc, 0x10, 0x32, +0x14, 0xe3, 0x97, 0x2e, 0x61, 0x33, 0x6e, 0xd6, +0xd9, 0x18, 0xc4, 0xec, 0x87, 0x73, 0xe7, 0xeb, +0x9f, 0xb5, 0xbb, 0xec, 0xf9, 0x0a, 0x90, 0x4e, +0xbf, 0x01, 0xeb, 0x8f, 0x04, 0xc4, 0x21, 0x83, +0x70, 0xec, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, +0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *columns_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_columns_png = new wxImage(); + if (!img_columns_png || !img_columns_png->IsOk()) + { + wxMemoryInputStream img_columns_pngIS(columns_png_data, sizeof(columns_png_data)); + img_columns_png->LoadFile(img_columns_pngIS, wxBITMAP_TYPE_PNG); + } + return img_columns_png; +} +#define columns_png_img columns_png_img() + +static wxBitmap *columns_png_bmp() +{ + static wxBitmap *bmp_columns_png; + if (!bmp_columns_png || !bmp_columns_png->IsOk()) + bmp_columns_png = new wxBitmap(*columns_png_img); + return bmp_columns_png; +} +#define columns_png_bmp columns_png_bmp() + +static wxIcon *columns_png_ico() +{ + static wxIcon *ico_columns_png; + if (!ico_columns_png || !ico_columns_png->IsOk()) + { + ico_columns_png = new wxIcon(); + ico_columns_png->CopyFromBitmap(*columns_png_bmp); + } + return ico_columns_png; +} +#define columns_png_ico columns_png_ico() + +#endif // COLUMNS_PNG_H diff --git a/include/images/configuration.png b/include/images/configuration.png new file mode 100644 index 0000000000000000000000000000000000000000..0a5caf5373670cc684605d42c9eb21724fd75523 GIT binary patch literal 346 zcmeAS@N?(olHy`uVBq!ia0vp^0wBx*Bp9q_EZ7UAm`Z~Df*BafCZDwc@shmVT^JZv z^(q?yd7K3vk;OpT1B~5HX4?T7eV#6kArhC96ArLWyRPcz_RN1y<+t?5ekwm_`v3pt zpXShUW$y3)=KnrDaoe%($o&2Lz8?Sn->2o%@1(l@)iv**{hVA{@b9+t^71?jt76M3 z|6d>7dilAY%nVDxQ~!THIdrkwu(MR)r>SB6yt#Ml)tB+7IbQubmD}%*%Lhj$?|Vug zC9j3V?(aLp-Wjqs@c=Kwu}j{!7{ZG80bQnA;u=wsl30>zm0Xkxq!^403=MP*jdTqR zLyQcpOpL8eOtcM5tqcq-W~$1eXvob^$xN$+XfUt@YXGUXGBAT^I5jmdK II;Vst0AK%q4gdfE literal 0 HcmV?d00001 diff --git a/include/images/configuration.pngc b/include/images/configuration.pngc new file mode 100644 index 0000000..238c219 --- /dev/null +++ b/include/images/configuration.pngc @@ -0,0 +1,88 @@ +#ifndef CONFIGURATION_PNG_H +#define CONFIGURATION_PNG_H + +static const unsigned char configuration_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x98, 0xa0, +0xbd, 0x00, 0x00, 0x00, 0x02, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x00, 0x76, 0x93, 0xcd, 0x38, 0x00, +0x00, 0x00, 0x02, 0x62, 0x4b, 0x47, 0x44, 0x00, +0x00, 0xaa, 0x8d, 0x23, 0x32, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x8e, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0xc0, 0x05, +0x96, 0xd7, 0x25, 0x4e, 0x46, 0xe6, 0x4f, 0x9c, +0x79, 0xf6, 0x67, 0xe3, 0x4e, 0x24, 0xf9, 0x99, +0x4f, 0xff, 0xf6, 0x4f, 0x66, 0x40, 0x88, 0xd4, +0x9d, 0xfb, 0xff, 0x37, 0xfe, 0xf2, 0xe4, 0x46, +0xb8, 0xae, 0xc4, 0x9f, 0xbf, 0xbe, 0xf5, 0xc7, +0xf7, 0xff, 0x4c, 0x84, 0xf2, 0xfb, 0x62, 0x7e, +0xbf, 0x7b, 0x7c, 0xef, 0xe6, 0xf9, 0x93, 0x75, +0x70, 0xfe, 0xdb, 0x1b, 0xa7, 0x77, 0x6e, 0x38, +0x3a, 0x73, 0x39, 0x94, 0xff, 0xeb, 0xc5, 0xb5, +0xd3, 0xe7, 0x2e, 0x1c, 0x98, 0x39, 0x11, 0xca, +0xff, 0xf9, 0xe4, 0xc2, 0xd1, 0x7b, 0x31, 0x89, +0x75, 0x10, 0xf9, 0x35, 0x31, 0x7f, 0x9e, 0x9d, +0xdd, 0x7f, 0x27, 0xa6, 0x0f, 0x66, 0x41, 0xd5, +0xf5, 0x95, 0x0b, 0x4e, 0xdc, 0x44, 0xf0, 0x41, +0x02, 0x4b, 0xde, 0x22, 0xf1, 0x19, 0xd6, 0x54, +0x5d, 0xbf, 0x8e, 0xcc, 0x07, 0x89, 0x54, 0xad, +0x61, 0xc0, 0x0d, 0x00, 0xc6, 0xd2, 0x4b, 0xda, +0x00, 0x56, 0x73, 0xbe, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *configuration_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_configuration_png = new wxImage(); + if (!img_configuration_png || !img_configuration_png->IsOk()) + { + wxMemoryInputStream img_configuration_pngIS(configuration_png_data, sizeof(configuration_png_data)); + img_configuration_png->LoadFile(img_configuration_pngIS, wxBITMAP_TYPE_PNG); + } + return img_configuration_png; +} +#define configuration_png_img configuration_png_img() + +static wxBitmap *configuration_png_bmp() +{ + static wxBitmap *bmp_configuration_png; + if (!bmp_configuration_png || !bmp_configuration_png->IsOk()) + bmp_configuration_png = new wxBitmap(*configuration_png_img); + return bmp_configuration_png; +} +#define configuration_png_bmp configuration_png_bmp() + +static wxIcon *configuration_png_ico() +{ + static wxIcon *ico_configuration_png; + if (!ico_configuration_png || !ico_configuration_png->IsOk()) + { + ico_configuration_png = new wxIcon(); + ico_configuration_png->CopyFromBitmap(*configuration_png_bmp); + } + return ico_configuration_png; +} +#define configuration_png_ico configuration_png_ico() + +#endif // CONFIGURATION_PNG_H diff --git a/include/images/configurations.png b/include/images/configurations.png new file mode 100644 index 0000000000000000000000000000000000000000..01bf4ee5bbcc3f7c8598a4fa9d9a76e061bf60e0 GIT binary patch literal 369 zcmeAS@N?(olHy`uVBq!ia0vp^0wBx*Bp9q_EZ7UAm`Z~Df*BafCZDwc@shmVT^JZv z^(q?yd7K3vk;OpT1B~5HX4?T7OFdm2LnJOIConW}78-sOmJ~?%c}Bax{^>As$>q&(poX=^>V-YH|>j=m=Dhq*)Xe{ zJ^#4MHC^^d=CI8letex_H{)fEpM)UHx3vIVCg!0N_P|FaQ7m literal 0 HcmV?d00001 diff --git a/include/images/configurations.pngc b/include/images/configurations.pngc new file mode 100644 index 0000000..8e30d1f --- /dev/null +++ b/include/images/configurations.pngc @@ -0,0 +1,91 @@ +#ifndef CONFIGURATIONS_PNG_H +#define CONFIGURATIONS_PNG_H + +static const unsigned char configurations_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x98, 0xa0, +0xbd, 0x00, 0x00, 0x00, 0x02, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x00, 0x76, 0x93, 0xcd, 0x38, 0x00, +0x00, 0x00, 0x02, 0x62, 0x4b, 0x47, 0x44, 0x00, +0x00, 0xaa, 0x8d, 0x23, 0x32, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0xa5, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0x00, 0x81, +0x09, 0x71, 0x31, 0xf1, 0x13, 0x19, 0x10, 0x60, +0xf9, 0xcc, 0x2b, 0x8f, 0x7f, 0xc7, 0x23, 0x09, +0xd4, 0x1d, 0xbc, 0xbd, 0x28, 0x26, 0x26, 0xa6, +0x18, 0x2e, 0x90, 0xf8, 0xe9, 0x10, 0x48, 0x4d, +0x0c, 0x8c, 0xdf, 0x17, 0xf3, 0xaf, 0x1d, 0x59, +0x4d, 0x5f, 0xcc, 0xdf, 0x8f, 0xc8, 0x6a, 0xfa, +0x62, 0xfe, 0xbc, 0xe9, 0x07, 0xab, 0xf9, 0x1f, +0x0f, 0xb2, 0x6b, 0x4d, 0xcc, 0xdf, 0xd7, 0x3d, +0x60, 0x35, 0xff, 0x7f, 0xf7, 0xc7, 0x03, 0xed, +0xaa, 0xba, 0xbe, 0xb2, 0x02, 0xa2, 0xe6, 0xeb, +0xcb, 0x87, 0x57, 0xee, 0xc5, 0x00, 0x05, 0xfa, +0xa1, 0x6a, 0x6e, 0x9f, 0xd9, 0xbe, 0xfa, 0x7a, +0x1c, 0xc3, 0x9a, 0x2a, 0xa8, 0x9a, 0xeb, 0xa7, +0x4e, 0x9f, 0xd9, 0x3f, 0x73, 0x02, 0x03, 0xc3, +0x9a, 0x14, 0xb0, 0x9a, 0x8b, 0x07, 0x6f, 0xc7, +0x24, 0xd6, 0x2d, 0x07, 0x59, 0x03, 0x56, 0xb3, +0xf0, 0xf8, 0xf5, 0x98, 0x3e, 0x98, 0xc3, 0x80, +0x6a, 0x56, 0x2e, 0x7e, 0x83, 0xe0, 0x83, 0xd4, +0x5c, 0xbf, 0x8e, 0xcc, 0x07, 0xeb, 0x5a, 0x03, +0x65, 0x02, 0x00, 0x3c, 0xaa, 0x70, 0x3b, 0x00, +0xf1, 0x5f, 0x61, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *configurations_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_configurations_png = new wxImage(); + if (!img_configurations_png || !img_configurations_png->IsOk()) + { + wxMemoryInputStream img_configurations_pngIS(configurations_png_data, sizeof(configurations_png_data)); + img_configurations_png->LoadFile(img_configurations_pngIS, wxBITMAP_TYPE_PNG); + } + return img_configurations_png; +} +#define configurations_png_img configurations_png_img() + +static wxBitmap *configurations_png_bmp() +{ + static wxBitmap *bmp_configurations_png; + if (!bmp_configurations_png || !bmp_configurations_png->IsOk()) + bmp_configurations_png = new wxBitmap(*configurations_png_img); + return bmp_configurations_png; +} +#define configurations_png_bmp configurations_png_bmp() + +static wxIcon *configurations_png_ico() +{ + static wxIcon *ico_configurations_png; + if (!ico_configurations_png || !ico_configurations_png->IsOk()) + { + ico_configurations_png = new wxIcon(); + ico_configurations_png->CopyFromBitmap(*configurations_png_bmp); + } + return ico_configurations_png; +} +#define configurations_png_ico configurations_png_ico() + +#endif // CONFIGURATIONS_PNG_H diff --git a/include/images/connect.png b/include/images/connect.png new file mode 100644 index 0000000000000000000000000000000000000000..d999e1af459ab5ac2c48a428877ed2bb76ce6757 GIT binary patch literal 675 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dy_X2!ET!HlB9^qGaeV&|>o;h=B zetv#mZ{Lz7OLi>~-MMquv17;PPw_c&IL5X=$#numAn~_y7O@>+0&dySqzDO48HQPaNO>@#Dwq*RNMsS65Y4#m2^lhlej& zJb&}%%}<{`-M4RFMMXt+c6MZB8FE5`xYkF5# zS8s3c!i5W`PoF+%(j>)wJ&r&hGL{7S1v5B2yO9RsBze2LNWRJ2+5zNn7I;J!18EO1 zb~~AE2V}hWba4!^IKA{@W_Xi>1nUFI2c|`efeN~g!W-_0=LDWwdg0ao{|oQ2*q5|P z+Enhh`+nw*rSpk;Cr#1aDwlbtTd=Y^2v)yi>hlZT)>=2S-RaGwHJez!Bynn#x3h&G z4T^mJE?_~B>8V|rjK|k!e?4_}ZKmm)l;ig;UTjT!z3%RYSpJ}UFUv2ykLJHS?{#JE zor5|ue|{C1%=6j%?+n{AfiwL7etfa1oOzRb+XCHW{=?x8>FYn-7m7b96*MPj+xw06 zOBB?&%I@y{_;c&yU*#J<&&58Yq10lltT;u=wsl30>zm0Xkxq!^403=MP*jdTqRLyQcpOpL8eOtcM5tqcq- sW~$1eXvob^$xN$+XfUt@YXGUXGBAT^I5jmdKI;Vst0I&@+Jpcdz literal 0 HcmV?d00001 diff --git a/include/images/connect.pngc b/include/images/connect.pngc new file mode 100644 index 0000000..e256f43 --- /dev/null +++ b/include/images/connect.pngc @@ -0,0 +1,129 @@ +#ifndef CONNECT_PNG_H +#define CONNECT_PNG_H + +static const unsigned char connect_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x08, 0x03, 0x00, 0x00, 0x00, 0x44, 0xa4, 0x8a, +0xc6, 0x00, 0x00, 0x00, 0xde, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xa3, 0x8c, 0x13, 0xea, +0xdd, 0x4c, 0xe4, 0xca, 0x1b, 0x99, 0x99, 0x95, +0x6f, 0x6f, 0x6f, 0x8e, 0x8d, 0x8e, 0xa4, 0xa4, +0xa4, 0xba, 0xa0, 0x15, 0xb9, 0xb9, 0xba, 0xc6, +0xc6, 0xc6, 0x9f, 0x94, 0x4c, 0xc4, 0xc4, 0xc4, +0xbd, 0xbd, 0xbd, 0x86, 0x86, 0x84, 0x9e, 0x9e, +0x9e, 0xb2, 0xb2, 0xb2, 0xa4, 0xa4, 0xa3, 0xe9, +0xe9, 0xe9, 0x80, 0x80, 0x80, 0x99, 0x99, 0x99, +0x94, 0x94, 0x94, 0x84, 0x84, 0x83, 0x7f, 0x7f, +0x7f, 0xfb, 0xfb, 0xfb, 0xff, 0xff, 0xff, 0x7e, +0x7e, 0x7e, 0x8b, 0x8b, 0x8b, 0x74, 0x74, 0x74, +0x67, 0x67, 0x67, 0xc8, 0xc7, 0xbf, 0xf1, 0xf1, +0xf1, 0xd7, 0xd7, 0xd7, 0x7b, 0x7b, 0x7b, 0x7a, +0x7a, 0x7a, 0x5d, 0x5d, 0x5d, 0x57, 0x57, 0x57, +0xa4, 0xa3, 0x9f, 0xb3, 0xb3, 0xb3, 0xe5, 0xe5, +0xe5, 0xbe, 0xbe, 0xbe, 0x78, 0x78, 0x78, 0x6b, +0x6b, 0x6b, 0x59, 0x59, 0x59, 0xdf, 0xdf, 0xdf, +0xc8, 0xc8, 0xc8, 0xba, 0xba, 0xba, 0xa7, 0xa7, +0xa7, 0x75, 0x75, 0x75, 0x62, 0x62, 0x62, 0x5f, +0x5f, 0x5f, 0x72, 0x72, 0x72, 0xf7, 0xf7, 0xf7, +0xae, 0xae, 0xae, 0xa5, 0xa5, 0xa5, 0x9c, 0x9c, +0x9c, 0x63, 0x63, 0x63, 0x70, 0x70, 0x70, 0xd4, +0xd4, 0xd4, 0xa2, 0xa2, 0xa2, 0xa0, 0xa0, 0xa0, +0xa8, 0xa8, 0xa8, 0xa6, 0xa6, 0xa6, 0x85, 0x85, +0x83, 0x95, 0x95, 0x91, 0x7c, 0x7c, 0x7c, 0xa9, +0xa9, 0xa9, 0x77, 0x77, 0x77, 0x9b, 0x9a, 0x97, +0x8a, 0x8a, 0x8a, 0x8d, 0x8d, 0x8d, 0xa1, 0xa1, +0xa1, 0x97, 0x97, 0x97, 0x92, 0x92, 0x92, 0x21, +0xbe, 0x8c, 0x41, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, +0x19, 0xec, 0x6e, 0xb5, 0x88, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0xef, 0x49, 0x44, +0x41, 0x54, 0x38, 0xcb, 0xa5, 0xd1, 0x69, 0x57, +0x82, 0x40, 0x18, 0x05, 0xe0, 0x19, 0xe0, 0x35, +0x72, 0x21, 0x51, 0x20, 0x2d, 0x41, 0x13, 0xb0, +0xdc, 0x17, 0x6c, 0x51, 0xca, 0xa5, 0xd0, 0xea, +0xff, 0xff, 0xa1, 0xde, 0x04, 0x3f, 0x74, 0x86, +0x19, 0x3c, 0x79, 0xbf, 0x3e, 0xf7, 0xcc, 0xdc, +0x39, 0x43, 0xc8, 0x7f, 0x42, 0x29, 0x15, 0xbb, +0x24, 0xd3, 0x0c, 0x97, 0x38, 0x05, 0x05, 0x40, +0x11, 0x7b, 0xee, 0x02, 0x8e, 0x4e, 0x55, 0xb6, +0x85, 0x7e, 0x99, 0x87, 0x42, 0xec, 0x92, 0xac, +0xb2, 0x05, 0xf4, 0x62, 0x09, 0x28, 0x77, 0x87, +0x06, 0x57, 0xc5, 0x52, 0x59, 0xe7, 0xee, 0x50, +0xa0, 0x52, 0x35, 0xca, 0xba, 0x69, 0x01, 0xc7, +0xaf, 0x6b, 0xf5, 0xca, 0xcd, 0xad, 0x69, 0x35, +0xec, 0x64, 0xc7, 0xdf, 0x38, 0xe8, 0xb5, 0x66, +0xeb, 0xae, 0xdd, 0xb0, 0x5d, 0x0f, 0x52, 0xde, +0xe9, 0x77, 0xd0, 0xef, 0x5b, 0x0f, 0xdd, 0x9e, +0xeb, 0x79, 0x7d, 0xdc, 0xc1, 0x2c, 0x1c, 0xfc, +0xfa, 0x70, 0x34, 0x9e, 0x4c, 0xbd, 0xfe, 0xcc, +0x06, 0xa6, 0x10, 0xcc, 0x0f, 0xfe, 0xf8, 0xf4, +0x3c, 0x79, 0x99, 0xd9, 0x0b, 0xb6, 0xa0, 0x2d, +0x63, 0x0f, 0xc3, 0x57, 0x40, 0x67, 0xaf, 0xf0, +0xdf, 0x12, 0x5f, 0xc1, 0x1a, 0x52, 0x9c, 0x6c, +0xb6, 0xef, 0xb1, 0x7f, 0xa4, 0x20, 0x26, 0x0a, +0x76, 0xdd, 0xbd, 0xf1, 0xf9, 0xb5, 0xe3, 0xfa, +0x77, 0xb0, 0xf1, 0xb5, 0x40, 0xf3, 0x9d, 0xf4, +0x9f, 0x46, 0x8f, 0x88, 0x28, 0x58, 0x20, 0x59, +0x05, 0xf1, 0x09, 0xd1, 0x29, 0x47, 0x9c, 0x57, +0xc8, 0xba, 0x22, 0xca, 0x1a, 0x79, 0xc2, 0x23, +0xc4, 0x7e, 0x56, 0x7e, 0x00, 0x2d, 0x10, 0x1f, +0x97, 0xe1, 0x47, 0xe8, 0x86, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *connect_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_connect_png = new wxImage(); + if (!img_connect_png || !img_connect_png->IsOk()) + { + wxMemoryInputStream img_connect_pngIS(connect_png_data, sizeof(connect_png_data)); + img_connect_png->LoadFile(img_connect_pngIS, wxBITMAP_TYPE_PNG); + } + return img_connect_png; +} +#define connect_png_img connect_png_img() + +static wxBitmap *connect_png_bmp() +{ + static wxBitmap *bmp_connect_png; + if (!bmp_connect_png || !bmp_connect_png->IsOk()) + bmp_connect_png = new wxBitmap(*connect_png_img); + return bmp_connect_png; +} +#define connect_png_bmp connect_png_bmp() + +static wxIcon *connect_png_ico() +{ + static wxIcon *ico_connect_png; + if (!ico_connect_png || !ico_connect_png->IsOk()) + { + ico_connect_png = new wxIcon(); + ico_connect_png->CopyFromBitmap(*connect_png_bmp); + } + return ico_connect_png; +} +#define connect_png_ico connect_png_ico() + +#endif // CONNECT_PNG_H diff --git a/include/images/constraints.png b/include/images/constraints.png new file mode 100644 index 0000000000000000000000000000000000000000..d62e13705c50e6c0cf8f19d680053e8643e28751 GIT binary patch literal 314 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFv3GfMV1=2TrO847{Jl`|t`Qpas znRGPqvlydizRJ&>B`Om#V}R-yOM?7@862M7NCR>>3p^r=fwTu0yPeFo z12TL)T^vI=t|uoPU||ZF@;Gg7=uums=9bIK=Egd~(us-3g@Iv02gfsK^JP^)gH=mhBT7;dOH!?p zi&B9UgOP!ufv%yEu7P2Qk%5(ov6YF5wt=aYfq}(LRXG$5x%nxXX_XKS29{tAAk|g| XW)KahriZQpYGCkm^>bP0l+XkKyyRU} literal 0 HcmV?d00001 diff --git a/include/images/constraints.pngc b/include/images/constraints.pngc new file mode 100644 index 0000000..8d6ef67 --- /dev/null +++ b/include/images/constraints.pngc @@ -0,0 +1,84 @@ +#ifndef CONSTRAINTS_PNG_H +#define CONSTRAINTS_PNG_H + +static const unsigned char constraints_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x24, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xd9, 0x8c, 0x75, 0xbf, +0x3c, 0x14, 0xe7, 0xbc, 0x9c, 0xe7, 0xa3, 0x81, +0xe7, 0xb2, 0x91, 0xe6, 0x92, 0x6e, 0xe6, 0x7f, +0x5a, 0xe6, 0x6d, 0x45, 0xe6, 0x5c, 0x32, 0xe6, +0x4d, 0x23, 0xe6, 0x43, 0x18, 0x79, 0x60, 0x69, +0x5c, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x4d, 0x49, +0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0x60, 0xc0, +0x04, 0x02, 0x50, 0x9a, 0x49, 0x11, 0x4c, 0x02, +0x91, 0x11, 0x48, 0x48, 0x45, 0x81, 0x81, 0xc9, +0x14, 0x28, 0xc4, 0xe4, 0x06, 0x64, 0x84, 0x24, +0x09, 0x30, 0xa8, 0xa4, 0x03, 0x19, 0x6e, 0x15, +0x0a, 0x20, 0xcc, 0xc0, 0x94, 0xde, 0xc4, 0xc0, +0xa8, 0xde, 0x09, 0x64, 0x00, 0x39, 0x0c, 0x42, +0xb3, 0x80, 0x8c, 0x26, 0xa0, 0x26, 0x46, 0x6d, +0x05, 0x06, 0x46, 0x05, 0x90, 0x39, 0x42, 0x02, +0x0c, 0x44, 0x00, 0x00, 0x90, 0x88, 0x08, 0xe6, +0x43, 0x37, 0xa6, 0x7a, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *constraints_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_constraints_png = new wxImage(); + if (!img_constraints_png || !img_constraints_png->IsOk()) + { + wxMemoryInputStream img_constraints_pngIS(constraints_png_data, sizeof(constraints_png_data)); + img_constraints_png->LoadFile(img_constraints_pngIS, wxBITMAP_TYPE_PNG); + } + return img_constraints_png; +} +#define constraints_png_img constraints_png_img() + +static wxBitmap *constraints_png_bmp() +{ + static wxBitmap *bmp_constraints_png; + if (!bmp_constraints_png || !bmp_constraints_png->IsOk()) + bmp_constraints_png = new wxBitmap(*constraints_png_img); + return bmp_constraints_png; +} +#define constraints_png_bmp constraints_png_bmp() + +static wxIcon *constraints_png_ico() +{ + static wxIcon *ico_constraints_png; + if (!ico_constraints_png || !ico_constraints_png->IsOk()) + { + ico_constraints_png = new wxIcon(); + ico_constraints_png->CopyFromBitmap(*constraints_png_bmp); + } + return ico_constraints_png; +} +#define constraints_png_ico constraints_png_ico() + +#endif // CONSTRAINTS_PNG_H diff --git a/include/images/continue.png b/include/images/continue.png new file mode 100644 index 0000000000000000000000000000000000000000..2421546c4887849ea04be5482cabc8c3691b82ae GIT binary patch literal 402 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}QGic~E0FHqm>4x%_~@e!&b5&u*jvIh+L^k;OpT1B~5HX4?T7;hrvzArhC96ArLR%#;XZ zoiXF0%Z!MKK-U>JZdeAm%&^$GqjG}ljEbK>SXm~z%xGzGbvb%urT~-Bq@YViC$v(Y zJ`oK#6A%*Qw$;^*^{niw485ZtxZ@ZYI%}B4S^L(4>{TssjVMV;EJ?LWE=mPb3`Pcq z2D*kux(0?JMg~?U##SaK+6Jap1_l;0Rpn4LIsOk()) + { + wxMemoryInputStream img_continue_pngIS(continue_png_data, sizeof(continue_png_data)); + img_continue_png->LoadFile(img_continue_pngIS, wxBITMAP_TYPE_PNG); + } + return img_continue_png; +} +#define continue_png_img continue_png_img() + +static wxBitmap *continue_png_bmp() +{ + static wxBitmap *bmp_continue_png; + if (!bmp_continue_png || !bmp_continue_png->IsOk()) + bmp_continue_png = new wxBitmap(*continue_png_img); + return bmp_continue_png; +} +#define continue_png_bmp continue_png_bmp() + +static wxIcon *continue_png_ico() +{ + static wxIcon *ico_continue_png; + if (!ico_continue_png || !ico_continue_png->IsOk()) + { + ico_continue_png = new wxIcon(); + ico_continue_png->CopyFromBitmap(*continue_png_bmp); + } + return ico_continue_png; +} +#define continue_png_ico continue_png_ico() + +#endif // CONTINUE_PNG_H diff --git a/include/images/conversion.png b/include/images/conversion.png new file mode 100644 index 0000000000000000000000000000000000000000..3dee54c968728f8a94da9a9a94b2dffc12099dc2 GIT binary patch literal 356 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!eSlAhE0ErFs;6eD&8*YDi!O(* zy_c}_RnD>Rl~?}vpSrbv>A{Md+aK?5JHN<(*Y)oIC#GM!J?;O4W&fY;`2Y6Q|4+C6 z|9|=VGtdaek|4ie28U-i(tsS!0*}aIAngIhZYQ(tfQ%SV7sn8Z%dzJig&GuioC8-Z zP`aj7@qe>aqh$1dtz<#q7WTDYD6l4=r?6xBwVquUK3#1I6J@-#%&TF~YNG~z zQRbHO>%|qsA5Gh#w^Zbsd26;Q!%kg?lr`+>Z&+9Tk%-y|v`4kXHKHUXu_V9nN|tWU|08(vbUIsOk()) + { + wxMemoryInputStream img_conversion_pngIS(conversion_png_data, sizeof(conversion_png_data)); + img_conversion_png->LoadFile(img_conversion_pngIS, wxBITMAP_TYPE_PNG); + } + return img_conversion_png; +} +#define conversion_png_img conversion_png_img() + +static wxBitmap *conversion_png_bmp() +{ + static wxBitmap *bmp_conversion_png; + if (!bmp_conversion_png || !bmp_conversion_png->IsOk()) + bmp_conversion_png = new wxBitmap(*conversion_png_img); + return bmp_conversion_png; +} +#define conversion_png_bmp conversion_png_bmp() + +static wxIcon *conversion_png_ico() +{ + static wxIcon *ico_conversion_png; + if (!ico_conversion_png || !ico_conversion_png->IsOk()) + { + ico_conversion_png = new wxIcon(); + ico_conversion_png->CopyFromBitmap(*conversion_png_bmp); + } + return ico_conversion_png; +} +#define conversion_png_ico conversion_png_ico() + +#endif // CONVERSION_PNG_H diff --git a/include/images/conversions.png b/include/images/conversions.png new file mode 100644 index 0000000000000000000000000000000000000000..29b94d8eb89ba46008dfbe031779b0a435c06950 GIT binary patch literal 356 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!O@L2`E0ErFs;6eD&8*YD%Wp*W z?edtkC3feloU{KLCQUBvuc~gD9Ja`R*Y)oIC#GNP?=IYwd+hGK|Ic>(|8VvHluVKJ zK>ds*L4Lsu4$p3+0Xdun9+AaB+5?Q;PG;Ky8S$Pjjv*44bNepxH7IZ}Ow`%jap~Xx zc;RNLwbe=6n;8{Ycpe;hm~7Bz@lqzhV{Kq_@$=kIn|`%zTi*HC=yIN~SJs+|KGXWH zNl4~xmSoBD(o`{+v2yC2_dd(T&l>zGW@N5miCJLraxu^<)e_f;l9a@fRIB8oR3OD* zWMF8ZYiOivU>IU#U}a)#Wn!XjU}|MxU@=ow4n;$5eoAIqB}9XPC0GMUwUvPxM8m1+ Sp=*E|7(8A5T-G@yGywqBh<^(J literal 0 HcmV?d00001 diff --git a/include/images/conversions.pngc b/include/images/conversions.pngc new file mode 100644 index 0000000..7ce4981 --- /dev/null +++ b/include/images/conversions.pngc @@ -0,0 +1,89 @@ +#ifndef CONVERSIONS_PNG_H +#define CONVERSIONS_PNG_H + +static const unsigned char conversions_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x3c, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xb2, 0xca, 0x8c, 0x7c, +0xa5, 0x3c, 0x9a, 0xcb, 0x4d, 0xa7, 0xd8, 0x5a, +0x8e, 0xba, 0x48, 0x92, 0xb4, 0x5d, 0xb9, 0xea, +0x6c, 0xcd, 0xfe, 0x80, 0x92, 0x93, 0x71, 0x8f, +0x7a, 0x7b, 0x84, 0x93, 0x56, 0xa2, 0x4f, 0xba, +0xd7, 0x8b, 0xff, 0xc8, 0x97, 0xd6, 0x8f, 0x8b, +0x71, 0xb2, 0x6d, 0xc6, 0xdd, 0x9e, 0xff, 0xe6, +0xb8, 0xff, 0xf0, 0xd5, 0xff, 0x94, 0x69, 0x14, +0xaf, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x5f, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x6d, 0x8e, 0xd1, +0x0e, 0x80, 0x20, 0x08, 0x00, 0x91, 0x2c, 0xb3, +0x88, 0xd2, 0xfe, 0xff, 0x5f, 0x13, 0x83, 0x1a, +0xad, 0x7b, 0x62, 0xb7, 0x83, 0x01, 0x20, 0x04, +0x0c, 0xe0, 0xc0, 0xe1, 0x63, 0x30, 0x8e, 0x38, +0xe9, 0x1c, 0x50, 0x48, 0xad, 0x51, 0x83, 0x73, +0xe7, 0x6d, 0xf2, 0xb2, 0xfa, 0x86, 0xb6, 0xa7, +0x89, 0xfd, 0x32, 0xd3, 0x6e, 0x4d, 0x4a, 0x6a, +0xac, 0x91, 0x4c, 0x96, 0x8e, 0xd6, 0x18, 0x19, +0x6e, 0xb3, 0x19, 0x04, 0x6a, 0x4a, 0x29, 0x24, +0x30, 0x98, 0xa9, 0x95, 0xdc, 0xef, 0x4c, 0xa7, +0x17, 0xcd, 0x30, 0xfc, 0x73, 0x01, 0x03, 0x7c, +0x04, 0x5c, 0xa0, 0x38, 0xe9, 0xa3, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *conversions_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_conversions_png = new wxImage(); + if (!img_conversions_png || !img_conversions_png->IsOk()) + { + wxMemoryInputStream img_conversions_pngIS(conversions_png_data, sizeof(conversions_png_data)); + img_conversions_png->LoadFile(img_conversions_pngIS, wxBITMAP_TYPE_PNG); + } + return img_conversions_png; +} +#define conversions_png_img conversions_png_img() + +static wxBitmap *conversions_png_bmp() +{ + static wxBitmap *bmp_conversions_png; + if (!bmp_conversions_png || !bmp_conversions_png->IsOk()) + bmp_conversions_png = new wxBitmap(*conversions_png_img); + return bmp_conversions_png; +} +#define conversions_png_bmp conversions_png_bmp() + +static wxIcon *conversions_png_ico() +{ + static wxIcon *ico_conversions_png; + if (!ico_conversions_png || !ico_conversions_png->IsOk()) + { + ico_conversions_png = new wxIcon(); + ico_conversions_png->CopyFromBitmap(*conversions_png_bmp); + } + return ico_conversions_png; +} +#define conversions_png_ico conversions_png_ico() + +#endif // CONVERSIONS_PNG_H diff --git a/include/images/create.png b/include/images/create.png new file mode 100644 index 0000000000000000000000000000000000000000..7621d221e0f0ac76d032d08b8bba37968b469056 GIT binary patch literal 1021 zcmVGJgI^7QNT_3ZTZ?)CQX_4oVz{m$a%(BtRQDK1z*y!uq>FnL>?%(Y1;_mSA_xRA`>GSyceznjvi?@Kb(DeBEcd^W5r^xR0`m)pE z_4)eK=J($0`Kis`_xk(R>G^uI&n$7D+&dETMyyNfnyV&G5jkvDW^vvh@wA${<==ZYK=b+N@hR5!y+VOeD>aN}L zf5Yr{!0UU$>ZR84T)O4b(#x~k^l`uHY`*Dp!Rn6A?TpLpRk-D;z{O>}=wiF(Qn%!# z+wgp=zrf(~g~{t#x#do_M1M%XapeF2010qN zS#tmY07w7;07w8v$!k6U00E~-L_t(I%Y~EqHv&-<$5Yd2Op`5?kWmy_vsJI6vSb;A zsW1r9V$Igj;$QcsIYQlYx<9_p=Pmbq?^7rmR+I8?HPs7B6`@v>%^IqO)-pOJAP}vs zZS5VM`mXLCgAo$cGVjHlFo8ma_w^4L2+|A*q{Ii=A=W}tR!C^B@Zk~GVx#SlpsDat zcFZw8HUSBgesXGB;xnVpK1gWknsv-!KEJT&a(e)Q?(VT68|Gf0pIus(R|CO7RnX%8 z4dbB|uWyxIbF7CqB)+*7tO^Y7pW5d9J1)#ayH0EbHuoZ^D(H+Rv(@hArZL|?IOLsS z%%icY@RO#;;lVt9bbR8*T;NgNYfq;_XYr%+#Kq-RR7mouKK*OXb#;+Q+@w-MGMzy{ z`dRMw4s+o?nSRJ1DE%z=7?t@`4uR=sm+oZ#oI_ChxW5;fzrG=&K7FZwA^9%xyogAu zHhq~__UAuDMA3}uzYyGt#CSfF$>rWe@e|REu~2hD5dEn^#%L-+<3UT)jqk_YT7m@a zFSmpLi23EkG9<|9s|v-EuKWcE4gYd&eFN@pVESqJTfP7Q03~!qSaf7zbY(hYa%Ew3 zWdJfTF)%GLGA%GMR5CC+G&4FhG%GMQIxsLenI#?o001R)MObuXVRU6WZEs|0W_bWI rFflMKFgYzSF;p@$Iy5voFg7bNH99ab%9mBF00000NkvXXu0mjfAM`&f literal 0 HcmV?d00001 diff --git a/include/images/create.pngc b/include/images/create.pngc new file mode 100644 index 0000000..67ac2da --- /dev/null +++ b/include/images/create.pngc @@ -0,0 +1,172 @@ +#ifndef CREATE_PNG_H +#define CREATE_PNG_H + +static const unsigned char create_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x08, 0x03, 0x00, 0x00, 0x00, 0x44, 0xa4, 0x8a, +0xc6, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x93, 0xb2, 0xbf, 0x64, +0x9b, 0xb7, 0xf8, 0xfb, 0xfb, 0xe5, 0xef, 0xf1, +0xe6, 0xf0, 0xf2, 0xe7, 0xf1, 0xf3, 0xe8, 0xf1, +0xf3, 0xe9, 0xf2, 0xf4, 0xea, 0xf2, 0xf4, 0xeb, +0xf3, 0xf5, 0xec, 0xf4, 0xf5, 0xee, 0xf5, 0xf6, +0xef, 0xf5, 0xf7, 0xfb, 0xfd, 0xfd, 0xce, 0xe2, +0xe6, 0xd0, 0xe3, 0xe7, 0xd2, 0xe4, 0xe8, 0xd4, +0xe5, 0xe9, 0xd6, 0xe6, 0xea, 0xd8, 0xe8, 0xeb, +0xdb, 0xe9, 0xec, 0xdd, 0xeb, 0xee, 0xdf, 0xec, +0xef, 0xe2, 0xee, 0xf0, 0xf1, 0xf7, 0xf8, 0xd0, +0xe3, 0xe9, 0xf3, 0xf8, 0xf9, 0x7e, 0xb5, 0xd0, +0x34, 0x8b, 0xb7, 0x80, 0xb6, 0xd0, 0xf4, 0xf8, +0xf9, 0x77, 0xb1, 0xcc, 0x64, 0xa7, 0xc8, 0xee, +0xf5, 0xfa, 0xb2, 0xd3, 0xe1, 0xf5, 0xf9, 0xfa, +0xd3, 0xe6, 0xf7, 0xde, 0xec, 0xf9, 0xa9, 0xcd, +0xde, 0xf7, 0xfa, 0xfb, 0xd6, 0xe9, 0xf9, 0x7a, +0xb3, 0xcf, 0x2c, 0x87, 0xb5, 0x6b, 0xab, 0xcb, +0xe8, 0xf2, 0xf6, 0xb3, 0xd2, 0xdf, 0x5e, 0x9d, +0xbd, 0xe5, 0xf1, 0xf8, 0xb9, 0xd7, 0xe8, 0x90, +0xc0, 0xd8, 0xd7, 0xe7, 0xec, 0xc5, 0xde, 0xeb, +0xb6, 0xd6, 0xe8, 0xb3, 0xd6, 0xf5, 0xa0, 0xcd, +0xf2, 0xc5, 0xe2, 0xf5, 0x8c, 0xbe, 0xd7, 0x46, +0x90, 0xb5, 0x27, 0x84, 0xb3, 0x99, 0xca, 0xf1, +0x9d, 0xcd, 0xf2, 0xcd, 0xe5, 0xf5, 0x50, 0x97, +0xbb, 0x98, 0xb8, 0xc3, 0x85, 0xaf, 0xc0, 0x3e, +0x8e, 0xb6, 0xb6, 0xd6, 0xe6, 0xc2, 0xdf, 0xf7, +0xc3, 0xe0, 0xf5, 0x83, 0xb9, 0xd3, 0x72, 0xaf, +0xce, 0x6f, 0xa5, 0xbd, 0xc8, 0xce, 0xc9, 0x40, +0x92, 0xbc, 0xe3, 0xef, 0xf5, 0xbb, 0xd8, 0xe4, +0x36, 0x8d, 0xb8, 0xae, 0xd5, 0xf4, 0xcc, 0xe7, +0xf8, 0xb4, 0xda, 0xee, 0xca, 0xe8, 0xf7, 0xb2, +0xd5, 0xe7, 0xa0, 0xd2, 0xf1, 0x86, 0xc7, 0xee, +0xa9, 0xda, 0xf1, 0x79, 0xc6, 0xea, 0xae, 0xdd, +0xf2, 0x7f, 0xc3, 0xec, 0x76, 0xc0, 0xeb, 0x7b, +0xc2, 0xea, 0xa5, 0xd6, 0xf1, 0x5c, 0xba, 0xe5, +0xd2, 0xd2, 0xcb, 0xb3, 0xdb, 0xf4, 0x71, 0xbf, +0xea, 0x6c, 0xbe, 0xe9, 0x73, 0xc1, 0xea, 0x8e, +0xce, 0xed, 0x8c, 0xcb, 0xec, 0x55, 0xb8, 0xe5, +0xa9, 0xc0, 0xc5, 0x65, 0xbc, 0xe8, 0x62, 0xbb, +0xe6, 0x52, 0xb7, 0xe4, 0xa5, 0xdb, 0xf0, 0x7c, +0xab, 0xbf, 0xc0, 0xe0, 0xf2, 0x85, 0xc9, 0xeb, +0x59, 0xb9, 0xe5, 0x4e, 0xb6, 0xe3, 0xba, 0xde, +0xf1, 0x4a, 0xb5, 0xe2, 0xa2, 0xd9, 0xf0, 0x47, +0xb5, 0xe1, 0x75, 0xc4, 0xe9, 0x44, 0xb3, 0xe1, +0xa0, 0xd9, 0xef, 0x51, 0xb8, 0xe3, 0x41, 0xb3, +0xe0, 0x9e, 0xd8, 0xef, 0x3e, 0xb2, 0xe0, 0xe5, +0xf5, 0xfb, 0xf9, 0xfb, 0xfc, 0xf9, 0xfc, 0xfc, +0xfb, 0xfc, 0xfd, 0xfd, 0xfe, 0xfe, 0xff, 0xff, +0xff, 0xcd, 0x71, 0x5a, 0x78, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, +0x47, 0x44, 0x7f, 0x48, 0xbf, 0x71, 0xe5, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x01, 0xa7, +0x49, 0x44, 0x41, 0x54, 0x38, 0xcb, 0x85, 0x93, +0xf9, 0x37, 0x02, 0x51, 0x14, 0xc7, 0x53, 0xd3, +0x68, 0x4c, 0x93, 0x2d, 0x94, 0x90, 0x51, 0x14, +0x59, 0xb3, 0x55, 0xaf, 0xa2, 0xb2, 0x64, 0x19, +0x84, 0xa9, 0x30, 0x08, 0xd1, 0x62, 0xcd, 0xd6, +0xd0, 0xe2, 0x5f, 0xf7, 0xa6, 0x39, 0x42, 0xdd, +0x73, 0xba, 0x3f, 0xbe, 0xcf, 0xe7, 0x2d, 0xf7, +0x7c, 0xef, 0x53, 0x28, 0x1a, 0x56, 0x93, 0xf2, +0x6f, 0x35, 0xd5, 0x0b, 0x4a, 0x15, 0xa1, 0x56, +0x93, 0xcd, 0x1a, 0xaa, 0x85, 0xd6, 0x32, 0x3a, +0x25, 0x20, 0x10, 0xad, 0xad, 0x6d, 0xed, 0x1d, +0x9d, 0xfa, 0xae, 0xee, 0x1e, 0x83, 0x11, 0x12, +0xd4, 0x32, 0xef, 0xc5, 0x9c, 0x30, 0x81, 0x42, +0x85, 0xf7, 0xf5, 0x0f, 0x18, 0x08, 0xd2, 0x0c, +0x09, 0xa4, 0xc4, 0x07, 0xd9, 0x21, 0xd6, 0x42, +0x52, 0x56, 0x48, 0x68, 0xae, 0xf0, 0xe1, 0x11, +0xd6, 0x62, 0xa3, 0xed, 0x90, 0xa0, 0xa9, 0xf0, +0x51, 0x76, 0xcc, 0x31, 0x3e, 0x36, 0x01, 0x09, +0x94, 0x7e, 0x72, 0x6a, 0x5a, 0xe2, 0x33, 0xa3, +0xce, 0x3e, 0x48, 0x68, 0xe9, 0x9a, 0x75, 0xcc, +0x61, 0x3e, 0xbf, 0xb0, 0xe8, 0x72, 0x7b, 0x00, +0x81, 0xee, 0xee, 0xb1, 0x21, 0x1b, 0xe6, 0x5e, +0x9f, 0x9f, 0x5d, 0x5a, 0x96, 0x57, 0x03, 0xc1, +0x40, 0x55, 0xd0, 0xe2, 0xfe, 0x0d, 0xe3, 0xa1, +0x15, 0xaf, 0x6f, 0x95, 0x5d, 0x73, 0xac, 0x87, +0x37, 0x24, 0xbe, 0xb9, 0x15, 0xac, 0x0a, 0x0c, +0xee, 0x9f, 0xda, 0xe6, 0xfc, 0x3b, 0x2e, 0xcc, +0x43, 0xbb, 0x4e, 0x6c, 0x04, 0x36, 0xf7, 0x22, +0xa8, 0x2a, 0xe8, 0x8c, 0x26, 0xb3, 0xd5, 0xee, +0xe6, 0xa6, 0x31, 0xdf, 0x3f, 0x38, 0xe4, 0x9d, +0x61, 0xcc, 0xa3, 0xb1, 0xaa, 0xf0, 0x93, 0xa6, +0xc7, 0xe1, 0xc1, 0x3c, 0x7e, 0x74, 0x7c, 0xe2, +0xc6, 0x5c, 0xe0, 0x51, 0xdd, 0x6b, 0x4f, 0xa7, +0x42, 0x67, 0xf1, 0xa3, 0xf3, 0xc4, 0xc5, 0xe5, +0x55, 0x54, 0x48, 0xf2, 0xa8, 0x3e, 0xfd, 0x6b, +0xce, 0x75, 0x75, 0x91, 0x48, 0xdc, 0xa4, 0x52, +0x42, 0x32, 0x9d, 0x41, 0x40, 0xfa, 0x59, 0xee, +0xf6, 0x0e, 0x73, 0xe1, 0x3e, 0x99, 0x7e, 0xc8, +0x20, 0x28, 0xfd, 0x2c, 0xf7, 0x18, 0x95, 0xf9, +0x53, 0x0e, 0x81, 0xe9, 0x67, 0x97, 0xee, 0x64, +0xfe, 0x9c, 0x43, 0x50, 0xfa, 0xb8, 0xbf, 0x17, +0x99, 0xbf, 0xbe, 0x21, 0xa2, 0x3e, 0x7d, 0xa9, +0x7f, 0x21, 0xf9, 0x2e, 0xf1, 0xbc, 0x88, 0x48, +0xaa, 0x36, 0x7d, 0x99, 0x57, 0xf6, 0xe7, 0x3f, +0x44, 0x44, 0xd1, 0x8c, 0xea, 0xbf, 0x10, 0xdc, +0x8a, 0xc4, 0x78, 0x3e, 0x93, 0xc9, 0xe5, 0xde, +0x44, 0xf1, 0x13, 0xd1, 0x8c, 0xb1, 0x50, 0x73, +0x42, 0x10, 0xfd, 0xa9, 0x41, 0xc6, 0x68, 0x2a, +0x42, 0xe3, 0x41, 0x4b, 0xd3, 0x8d, 0xef, 0xc7, +0xdc, 0x5a, 0x82, 0x04, 0xed, 0x2f, 0xb7, 0x83, +0xff, 0x88, 0xf9, 0xe5, 0xc5, 0x32, 0x24, 0xc8, +0xe9, 0xab, 0x0a, 0xc5, 0x92, 0xae, 0xfc, 0x05, +0x08, 0x0d, 0xff, 0x72, 0x6d, 0x7d, 0x03, 0xee, +0x6e, 0x60, 0xfa, 0x69, 0xf8, 0x5b, 0xbe, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *create_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_create_png = new wxImage(); + if (!img_create_png || !img_create_png->IsOk()) + { + wxMemoryInputStream img_create_pngIS(create_png_data, sizeof(create_png_data)); + img_create_png->LoadFile(img_create_pngIS, wxBITMAP_TYPE_PNG); + } + return img_create_png; +} +#define create_png_img create_png_img() + +static wxBitmap *create_png_bmp() +{ + static wxBitmap *bmp_create_png; + if (!bmp_create_png || !bmp_create_png->IsOk()) + bmp_create_png = new wxBitmap(*create_png_img); + return bmp_create_png; +} +#define create_png_bmp create_png_bmp() + +static wxIcon *create_png_ico() +{ + static wxIcon *ico_create_png; + if (!ico_create_png || !ico_create_png->IsOk()) + { + ico_create_png = new wxIcon(); + ico_create_png->CopyFromBitmap(*create_png_bmp); + } + return ico_create_png; +} +#define create_png_ico create_png_ico() + +#endif // CREATE_PNG_H diff --git a/include/images/database-sm.png b/include/images/database-sm.png new file mode 100644 index 0000000000000000000000000000000000000000..347d2b4e7559e1993b0be7923b14032c2b17ab71 GIT binary patch literal 688 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47##zALR^8|lRK(*E)HBj&3yB0 zrvqz}4y{kPd3xfDdu!gkI`Hwsf!8lK+`BRT!m;W@+u}FRb2zj<<;~Lr|NlP!`}5Y% z9~VA6j-2e%p@-<@{<+Vp>4E~=ES4#-&M>Eak7aXC5R0Gq_j88c@_Mm(%BE93Li%ae<3i6WD zQBc-aU%z0*k~ND~E#niraN)|OYZtFxHa9RaYU7wOW7f>*h^WZhHx9A9d2?1*MrQ5Y zIf+bq-`3^5lbh!k$H7>fFYg|2U*F=;u)TW0a$z3@jT`rDR75h|BwQ41l#EWIsOk()) + { + wxMemoryInputStream img_database_sm_pngIS(database_sm_png_data, sizeof(database_sm_png_data)); + img_database_sm_png->LoadFile(img_database_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_database_sm_png; +} +#define database_sm_png_img database_sm_png_img() + +static wxBitmap *database_sm_png_bmp() +{ + static wxBitmap *bmp_database_sm_png; + if (!bmp_database_sm_png || !bmp_database_sm_png->IsOk()) + bmp_database_sm_png = new wxBitmap(*database_sm_png_img); + return bmp_database_sm_png; +} +#define database_sm_png_bmp database_sm_png_bmp() + +static wxIcon *database_sm_png_ico() +{ + static wxIcon *ico_database_sm_png; + if (!ico_database_sm_png || !ico_database_sm_png->IsOk()) + { + ico_database_sm_png = new wxIcon(); + ico_database_sm_png->CopyFromBitmap(*database_sm_png_bmp); + } + return ico_database_sm_png; +} +#define database_sm_png_ico database_sm_png_ico() + +#endif // DATABASE_SM_PNG_H diff --git a/include/images/database.png b/include/images/database.png new file mode 100644 index 0000000000000000000000000000000000000000..1a743d7a37e5781872a37dedc5a03bb9df931973 GIT binary patch literal 706 zcmV;z0zLhSP))s|Y1+$<=G>|6=)Lmt!td<2~gub4K$tz+HL zng9Ln|NZ0s`PljS(e?1f@$S6r>9XbJtK{LJ-`|_ZylSwRJL%!K{Q24X_s{h7$L{XF z?d`kl>A&sm%JlTx{Q2^@qE4)mFyq_3>D;;Pdz=I&_wN4m)Aa1M>*1K=*n{BOd*9lG*JW=+=S@h ztMcgC|N8Ia-ht%bmjC+n|M~9!^V9R`w&dKH>gB8c^wHznf%59v?B|y0dwe#k_^Xsqa;gj6dchksb$+=v;sZg(&I9k(EZvX%Q z0d!JMQvg8b*k%9#010qNS#tmY07w7;07w8v$!k6U006{EL_t&-(_>&@U|?ioW&r|b zCI$##Wn<^yMCs@dbs1MMTBKB_yS!Wn=|`0&?=gA_|I1$||aA>Kd9r0WEDE zT|IpR14AQY6H_gafSI|4rIodft)0DtBSgRnDB$ekYUk?U1`%+#@Bj*U+PQi`Rk(Zm z`1-j3wRpL~1+1(=D*PRhwAgq8RRll{_4Wv~b_oIsKve_-wfKdA3=IVfgqeqf%!shF zkBkBdFhs}1#>FQjCMBn&ra}FS?0o>+m?|%1vwO+_001R)MObuXVRU6WV{&C-bY%cC zFflMKF)}SMF;p@zIy5snG&CzPH99abIGH6L0000bbVXQnWMOn=I&E)cX=ZrIsOk()) + { + wxMemoryInputStream img_database_pngIS(database_png_data, sizeof(database_png_data)); + img_database_png->LoadFile(img_database_pngIS, wxBITMAP_TYPE_PNG); + } + return img_database_png; +} +#define database_png_img database_png_img() + +static wxBitmap *database_png_bmp() +{ + static wxBitmap *bmp_database_png; + if (!bmp_database_png || !bmp_database_png->IsOk()) + bmp_database_png = new wxBitmap(*database_png_img); + return bmp_database_png; +} +#define database_png_bmp database_png_bmp() + +static wxIcon *database_png_ico() +{ + static wxIcon *ico_database_png; + if (!ico_database_png || !ico_database_png->IsOk()) + { + ico_database_png = new wxIcon(); + ico_database_png->CopyFromBitmap(*database_png_bmp); + } + return ico_database_png; +} +#define database_png_ico database_png_ico() + +#endif // DATABASE_PNG_H diff --git a/include/images/databases.png b/include/images/databases.png new file mode 100644 index 0000000000000000000000000000000000000000..bfc0966c24b062675a6d2923e6670b238bd5b5e4 GIT binary patch literal 771 zcmV+e1N{7nP)6KqSnrc%Drv8tx~U;H^HrB-O!o;{qFz$ zB`T5cH@Wt`&yzJ?+<>jm7;h^8&o5#Fru$VjP;kW$x+4}d-^z_H>?!N8qyX@(| z?d{6+^xORT^0=Z-tdcO}*}Li7x$We=_3+g7^4a_Q@&5k%_w?xS?b7V&#OmO<+tIG{ z>e&DI^Z)nm{`AxI?6vFRnB&=l;M#lN+Jxlbm*3Z&(Zre1zLDkAv-0G}_Uy*=?6T_N zm)z8W*v)v+#CyuSeAB~>ViB>*JW?-htuVgyh_q&b*P| z*MHN-jOE?J^6J_C`Q`ok`0nYx&A@fAnK|3Wl#ynIlibvI)5vDYxm?r5 zk;P-HF8}}l0d!JMQvg8b*k%9#010qNS#tmY07w7;07w8v$!k6U007BJL_t&-(_>%& z0!AigAYfu-fC3g)Hg*n9E^Z!PJ`k5*Ku}0nL{v;%LQ+baA1ELrD<~u z4iwPP)Y8_`)zi~AFf=mO0123wnweWzT3OrJ+S!8z92}jTU0mJVJv_a+)Gmse|cNBmG7z+7|ic3n%$}1}Q`5?ZnLiRoYZDKCz4W-Rk0000bbVXQn zWMOn=I%9HWVRU5xGB7bPEip1JFfmjzFgi3dIy5vZFf}?bFgTed9smFUC3HntbYx+4 zWjbwdWNBu305UK!FfA}SEif@uGBY|fG&(RgD=;-WFfhuORjdF2002ovPDHLkV1g|G BtCs)( literal 0 HcmV?d00001 diff --git a/include/images/databases.pngc b/include/images/databases.pngc new file mode 100644 index 0000000..868891e --- /dev/null +++ b/include/images/databases.pngc @@ -0,0 +1,141 @@ +#ifndef DATABASES_PNG_H +#define DATABASES_PNG_H + +static const unsigned char databases_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x71, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc3, 0xb0, 0x6a, 0xb7, +0xa0, 0x4b, 0xaf, 0x96, 0x37, 0xc6, 0xb4, 0x69, +0xda, 0xcb, 0x8e, 0xe6, 0xdc, 0xa9, 0xed, 0xe8, +0xbd, 0xf2, 0xf2, 0xc2, 0xef, 0xec, 0xb7, 0xe4, +0xdf, 0xa2, 0xd6, 0xce, 0x88, 0xca, 0xbd, 0x6d, +0xbc, 0xad, 0x52, 0xaf, 0x98, 0x37, 0xc1, 0xad, +0x64, 0xdd, 0xd0, 0x99, 0xff, 0xfd, 0xee, 0xff, +0xfd, 0xe3, 0xfe, 0xf9, 0xd8, 0xf9, 0xf9, 0xd1, +0xf5, 0xf0, 0xc5, 0xf1, 0xee, 0xbc, 0xec, 0xe9, +0xb2, 0xe5, 0xe5, 0xab, 0xe4, 0xe1, 0xa0, 0xdf, +0xdf, 0x9b, 0xc7, 0xbc, 0x6a, 0xb0, 0x98, 0x3b, +0xe9, 0xe1, 0xb7, 0xfc, 0xf9, 0xd9, 0xfa, 0xf7, +0xcf, 0xf4, 0xf4, 0xc7, 0xee, 0xee, 0xbe, 0xed, +0xed, 0xbb, 0xec, 0xe9, 0xbf, 0xed, 0xed, 0xca, +0xf4, 0xf4, 0xdb, 0xfc, 0xf9, 0xf2, 0xb8, 0xa2, +0x4e, 0xac, 0x92, 0x30, 0xe3, 0xd9, 0xbb, 0xe9, +0xdc, 0xb9, 0xed, 0xe4, 0xbd, 0xf5, 0xf0, 0xd4, +0xf5, 0xf2, 0xd9, 0xfb, 0xfb, 0xf1, 0xfe, 0xfe, +0xfb, 0xf7, 0xf4, 0xe8, 0xf0, 0xed, 0xd2, 0xec, +0xe9, 0xc4, 0xea, 0xe0, 0xb8, 0xdb, 0xd1, 0xae, +0xf4, 0xea, 0xd8, 0xff, 0xf8, 0xf3, 0xff, 0xf7, +0xee, 0xfe, 0xf4, 0xd3, 0xf4, 0xec, 0xb5, 0xeb, +0xe1, 0x98, 0xe3, 0xd9, 0x83, 0xe0, 0xda, 0x7b, +0xdf, 0xda, 0x84, 0xe4, 0xe0, 0x97, 0xdf, 0xd7, +0x9d, 0xd1, 0xc4, 0x99, 0xd0, 0xbe, 0x91, 0xe5, +0xd3, 0xb3, 0xf2, 0xe4, 0xc7, 0xf6, 0xec, 0xc6, +0xf4, 0xec, 0xb2, 0xea, 0xe1, 0x97, 0xdc, 0xd4, +0x81, 0xd8, 0xcd, 0x78, 0xd1, 0xc4, 0x7b, 0xca, +0xbb, 0x7c, 0xd3, 0xc3, 0x8c, 0xe3, 0xd9, 0xbd, +0xe4, 0xd7, 0xba, 0xe0, 0xce, 0xab, 0xd4, 0xc2, +0x92, 0xc7, 0xb3, 0x7e, 0xc1, 0xad, 0x73, 0xc0, +0xac, 0x72, 0xcb, 0xbc, 0x82, 0xd7, 0xca, 0x98, +0xe3, 0xdb, 0xb2, 0xf0, 0xed, 0xd7, 0xfc, 0xfc, +0xf7, 0xb3, 0x9c, 0x44, 0xe5, 0xdb, 0xbf, 0xf2, +0xe8, 0xd9, 0xff, 0xfa, 0xf4, 0xff, 0xfc, 0xf5, +0xfe, 0xf6, 0xe5, 0xfc, 0xf9, 0xed, 0xfb, 0xf8, +0xe9, 0xf9, 0xf9, 0xe5, 0xf5, 0xf2, 0xd3, 0xf2, +0xef, 0xcc, 0xff, 0xf9, 0xee, 0xeb, 0xe3, 0x98, +0xe3, 0xde, 0x81, 0xe1, 0xdc, 0x84, 0xe4, 0xdc, +0x98, 0xce, 0xbc, 0x91, 0xdf, 0xd7, 0x7f, 0xd3, +0xc6, 0x8c, 0xe5, 0xdd, 0xc2, 0xf2, 0xea, 0xd9, +0xfe, 0xf9, 0xe5, 0xfd, 0xfa, 0xf8, 0xee, 0xe9, +0xbe, 0xcd, 0xc0, 0x75, 0xb0, 0x99, 0x39, 0xdb, +0xc6, 0x94, 0xed, 0xdd, 0xb5, 0xf3, 0xe6, 0xbe, +0xf3, 0xeb, 0xaf, 0xe9, 0xe1, 0x93, 0xdc, 0xd4, +0x77, 0xd3, 0xc8, 0x66, 0xc9, 0xb9, 0x5c, 0xd3, +0xc5, 0x91, 0xc5, 0x63, 0xab, 0x2f, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0xc9, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0x60, 0x00, 0x02, 0x46, 0x26, +0x66, 0x20, 0x60, 0x62, 0x64, 0x80, 0x02, 0x16, +0x56, 0x36, 0x76, 0x0e, 0x4e, 0x2e, 0x6e, 0x1e, +0x5e, 0x3e, 0x10, 0x97, 0x5f, 0x40, 0x50, 0x48, +0x58, 0x44, 0x54, 0x4c, 0x5c, 0x42, 0x52, 0x4a, +0x9a, 0x1f, 0x28, 0x20, 0x23, 0x2b, 0x28, 0x24, +0x27, 0xaf, 0xa0, 0xa8, 0xa4, 0xac, 0xa2, 0xaa, +0xa6, 0x0e, 0x14, 0xd0, 0xd0, 0xd4, 0xd2, 0xd6, +0xd1, 0xd5, 0xd3, 0xd3, 0x37, 0x30, 0x34, 0x32, +0xd6, 0x00, 0x09, 0x98, 0x98, 0x9a, 0x99, 0x5b, +0x58, 0x5a, 0x59, 0xdb, 0xd8, 0xda, 0xd9, 0x83, +0x05, 0x1c, 0x1c, 0x9d, 0x9c, 0x5d, 0x5c, 0xdd, +0xdc, 0x3d, 0x3c, 0xbd, 0xbc, 0xc1, 0x02, 0x3e, +0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1, 0x21, +0xa1, 0x61, 0xe1, 0x11, 0x20, 0x81, 0xc8, 0xa8, +0xe8, 0x98, 0xd8, 0xb8, 0x78, 0xfd, 0x84, 0xc4, +0x24, 0x6d, 0x88, 0x19, 0x51, 0xd1, 0xc9, 0x16, +0x96, 0x29, 0xa9, 0x36, 0x69, 0xe9, 0x50, 0x33, +0x32, 0xc0, 0x66, 0x64, 0x02, 0xcd, 0xc8, 0xc2, +0x6e, 0x46, 0x76, 0x4e, 0x74, 0x4c, 0x6e, 0x5c, +0x7c, 0x1e, 0xd0, 0x8c, 0x7c, 0xb0, 0x8a, 0x60, +0x53, 0x33, 0x90, 0x19, 0x20, 0x77, 0x14, 0x80, +0x04, 0x18, 0x0a, 0xf9, 0x8b, 0x8a, 0x4b, 0x4a, +0xcb, 0xca, 0x2b, 0x2a, 0xf9, 0xf9, 0x20, 0xbe, +0xad, 0x42, 0xf6, 0x3e, 0x00, 0x6d, 0x62, 0x2e, +0xe9, 0x0d, 0xa5, 0xcd, 0x58, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *databases_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_databases_png = new wxImage(); + if (!img_databases_png || !img_databases_png->IsOk()) + { + wxMemoryInputStream img_databases_pngIS(databases_png_data, sizeof(databases_png_data)); + img_databases_png->LoadFile(img_databases_pngIS, wxBITMAP_TYPE_PNG); + } + return img_databases_png; +} +#define databases_png_img databases_png_img() + +static wxBitmap *databases_png_bmp() +{ + static wxBitmap *bmp_databases_png; + if (!bmp_databases_png || !bmp_databases_png->IsOk()) + bmp_databases_png = new wxBitmap(*databases_png_img); + return bmp_databases_png; +} +#define databases_png_bmp databases_png_bmp() + +static wxIcon *databases_png_ico() +{ + static wxIcon *ico_databases_png; + if (!ico_databases_png || !ico_databases_png->IsOk()) + { + ico_databases_png = new wxIcon(); + ico_databases_png->CopyFromBitmap(*databases_png_bmp); + } + return ico_databases_png; +} +#define databases_png_ico databases_png_ico() + +#endif // DATABASES_PNG_H diff --git a/include/images/ddAddColumn.png b/include/images/ddAddColumn.png new file mode 100644 index 0000000000000000000000000000000000000000..85942d9956e7ae1a1824822dd1ed88e900e099d0 GIT binary patch literal 165 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPgg)Hc4I;eV4gULV-f6o-U3d5|@(` z9GKz^`~O!TwfWbtbL@x%gFwiEjy#oIsOk()) + { + wxMemoryInputStream img_ddAddColumn_pngIS(ddAddColumn_png_data, sizeof(ddAddColumn_png_data)); + img_ddAddColumn_png->LoadFile(img_ddAddColumn_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddAddColumn_png; +} +#define ddAddColumn_png_img ddAddColumn_png_img() + +static wxBitmap *ddAddColumn_png_bmp() +{ + static wxBitmap *bmp_ddAddColumn_png; + if (!bmp_ddAddColumn_png || !bmp_ddAddColumn_png->IsOk()) + bmp_ddAddColumn_png = new wxBitmap(*ddAddColumn_png_img); + return bmp_ddAddColumn_png; +} +#define ddAddColumn_png_bmp ddAddColumn_png_bmp() + +static wxIcon *ddAddColumn_png_ico() +{ + static wxIcon *ico_ddAddColumn_png; + if (!ico_ddAddColumn_png || !ico_ddAddColumn_png->IsOk()) + { + ico_ddAddColumn_png = new wxIcon(); + ico_ddAddColumn_png->CopyFromBitmap(*ddAddColumn_png_bmp); + } + return ico_ddAddColumn_png; +} +#define ddAddColumn_png_ico ddAddColumn_png_ico() + +#endif // DDADDCOLUMN_PNG_H diff --git a/include/images/ddAddColumnCursor.png b/include/images/ddAddColumnCursor.png new file mode 100644 index 0000000000000000000000000000000000000000..0ce824dd6c6795d1374ce1a80382b0365e8a76a0 GIT binary patch literal 612 zcmV-q0-ODbP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2ipc2 z4J0E?E2w?|00HDlL_t(o!|j&6irYXGg}*!g83__xrAV1_({C`gF}O;zqzSlL*dlET z`32l>I-9T$urCnu0s{ZUAdx3Xnv^NG3D~faCPh4o<&QUw@eN)urnC{2V)Uz8z2ZQeMxh-&&mL^4_cIhueqxs*|erpz|94(z@1XII~M ziuFz(F?jJ<@(9R9{=TO<(KktKB0{}hM?|>(B8)%(DAoo4!il~i3`1PkO%AO!K@jlf zxhmELc`%>PF~%SwRI62#Qkz|L7y%+etJO-#L#l$QIAB#Jnl%mt= zB>RBx`&-Fl;tcsM@peb^3fSBY-#wZCRqb}=p9UW?_s8S06n5a-+oze2^ta4_IQ4t6 yjkNF_*az_)mLEmHuFQ`D&+|;W{T}duUHAo~nWLbYI$>u300005; literal 0 HcmV?d00001 diff --git a/include/images/ddAddColumnCursor.pngc b/include/images/ddAddColumnCursor.pngc new file mode 100644 index 0000000..be8882b --- /dev/null +++ b/include/images/ddAddColumnCursor.pngc @@ -0,0 +1,121 @@ +#ifndef DDADDCOLUMNCURSOR_PNG_H +#define DDADDCOLUMNCURSOR_PNG_H + +static const unsigned char ddAddColumnCursor_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x08, 0x06, 0x00, 0x00, 0x00, 0x73, 0x7a, 0x7a, +0xf4, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x24, 0x23, 0x4d, 0x2b, 0xa8, 0x7e, +0x00, 0x00, 0x01, 0xe4, 0x49, 0x44, 0x41, 0x54, +0x58, 0xc3, 0xed, 0x96, 0xbd, 0x8a, 0xdb, 0x40, +0x14, 0x85, 0xbf, 0x3b, 0xfe, 0x19, 0x09, 0x12, +0x5c, 0xa5, 0x48, 0x99, 0x72, 0xd3, 0x6f, 0x30, +0xb6, 0x31, 0xb8, 0x4a, 0xb3, 0xa4, 0x09, 0xb8, +0x59, 0xd8, 0x22, 0x6d, 0x0a, 0xf9, 0x05, 0xdc, +0x6f, 0x3a, 0x9b, 0xb0, 0x0f, 0xb0, 0x2f, 0x10, +0xf2, 0x02, 0x02, 0xff, 0xc4, 0x20, 0x91, 0x27, +0x48, 0x9a, 0x94, 0x29, 0xb7, 0x09, 0xd8, 0xb0, +0x91, 0x26, 0x45, 0x3c, 0x8a, 0xe4, 0x78, 0x1d, +0x2b, 0x5a, 0x5b, 0xcd, 0x1e, 0x10, 0x42, 0x3f, +0xe8, 0x9c, 0x39, 0xe7, 0xde, 0x3b, 0x02, 0x30, +0x94, 0x08, 0xb5, 0x3e, 0x9b, 0x52, 0x05, 0x18, +0x63, 0x4a, 0x13, 0x61, 0x1d, 0x28, 0x4d, 0x84, +0x4a, 0x5f, 0x94, 0x21, 0x42, 0x6d, 0xde, 0x38, +0xb6, 0x88, 0x6a, 0xfa, 0x42, 0x44, 0x32, 0x5a, +0x00, 0x39, 0x9a, 0x80, 0x35, 0xb9, 0x94, 0x51, +0x88, 0xa6, 0xcc, 0x36, 0xb4, 0x0e, 0xec, 0xbd, +0xf2, 0x67, 0x57, 0xdf, 0x77, 0x8a, 0xf5, 0x4e, +0x1f, 0x31, 0x78, 0xf1, 0x58, 0xf2, 0x08, 0xc8, +0x45, 0xfe, 0xbe, 0xa7, 0x39, 0xd1, 0x37, 0x49, +0x6c, 0x22, 0x42, 0xbd, 0x5e, 0x47, 0x44, 0xb8, +0xfe, 0x22, 0x8c, 0x3f, 0xff, 0x28, 0xd6, 0x05, +0xff, 0xc2, 0x89, 0xbe, 0x21, 0x0c, 0x43, 0x5c, +0xd7, 0x4d, 0x0e, 0xad, 0x35, 0x41, 0x10, 0xf0, +0xe6, 0xb9, 0x2a, 0xd6, 0x05, 0x79, 0x30, 0x9f, +0xcf, 0x31, 0xc6, 0x20, 0x22, 0x54, 0xab, 0x55, +0x94, 0x52, 0x9b, 0x5d, 0x74, 0x18, 0x01, 0x22, +0x42, 0xab, 0xd5, 0x4a, 0xc8, 0x44, 0x04, 0xad, +0x35, 0xab, 0xd5, 0x8a, 0xe5, 0x72, 0x09, 0xd4, +0x0f, 0x1b, 0x41, 0xa5, 0x52, 0x21, 0x0c, 0x43, +0x1c, 0xc7, 0xc1, 0x71, 0x1c, 0xb4, 0xd6, 0x00, +0x04, 0x41, 0x50, 0x7c, 0x10, 0xe5, 0xc1, 0x64, +0x32, 0xb9, 0xff, 0x49, 0xb8, 0x2f, 0x9a, 0xcd, +0xe6, 0xce, 0xe7, 0x9e, 0xe7, 0x19, 0x80, 0x76, +0xbb, 0x4d, 0xbf, 0xdf, 0x97, 0x7b, 0x8d, 0xc0, +0xda, 0x6d, 0x23, 0xb0, 0x87, 0x8d, 0xe0, 0xd5, +0xd7, 0x4b, 0xce, 0x46, 0x17, 0xbc, 0x1c, 0x9d, +0xb3, 0x58, 0x2c, 0x0e, 0x17, 0xc1, 0x6c, 0x36, +0x4b, 0x0a, 0x31, 0x8a, 0x22, 0x5c, 0xd7, 0xa5, +0xd1, 0x68, 0x00, 0x70, 0x4b, 0x74, 0xb8, 0x08, +0x6a, 0xb5, 0x1a, 0xdd, 0x6e, 0x17, 0xa5, 0x54, +0xd2, 0x7a, 0x76, 0x10, 0x29, 0xf5, 0xc7, 0xd0, +0x9f, 0x7b, 0x8a, 0xf8, 0xaf, 0x36, 0x0c, 0x82, +0x80, 0x5e, 0xaf, 0xf7, 0x3b, 0x43, 0xa5, 0x18, +0x0e, 0x87, 0x99, 0x77, 0xd2, 0xe4, 0xb6, 0x1e, +0xee, 0xaa, 0x89, 0xdc, 0x02, 0xec, 0xaa, 0xa7, +0xd3, 0x29, 0x22, 0x82, 0xef, 0xfb, 0x9c, 0x8d, +0x2e, 0x12, 0xdb, 0x2d, 0x79, 0x44, 0x44, 0x77, +0xf4, 0x9a, 0x78, 0xbd, 0xcf, 0xc5, 0xc4, 0x2c, +0x06, 0x1f, 0x8b, 0x3b, 0xa0, 0x94, 0xa2, 0xd3, +0xe9, 0x24, 0xfb, 0x80, 0xef, 0xfb, 0x5b, 0xc9, +0x63, 0xe2, 0x0c, 0xf9, 0x2d, 0xf1, 0x76, 0x47, +0xf3, 0x0a, 0xd8, 0xdc, 0x0d, 0xdf, 0x3d, 0x99, +0xff, 0x55, 0xed, 0x76, 0xe5, 0x9f, 0x06, 0x1f, +0x32, 0xf7, 0xc7, 0xe3, 0xb1, 0x14, 0x76, 0xe0, +0xdb, 0xdb, 0xa7, 0x99, 0x8f, 0xf4, 0xb7, 0xcc, +0x80, 0x38, 0xf5, 0x7b, 0xb1, 0x8d, 0xb4, 0xf0, +0x1c, 0xd8, 0x07, 0xf1, 0x1d, 0x96, 0x1f, 0x45, +0xc0, 0xae, 0xcc, 0x8f, 0x02, 0xcf, 0xf3, 0x4c, +0xba, 0xfd, 0x1e, 0xf0, 0x80, 0x5d, 0xf8, 0x05, +0xa3, 0x99, 0xa3, 0xa0, 0x99, 0x3a, 0x61, 0x67, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddAddColumnCursor_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddAddColumnCursor_png = new wxImage(); + if (!img_ddAddColumnCursor_png || !img_ddAddColumnCursor_png->IsOk()) + { + wxMemoryInputStream img_ddAddColumnCursor_pngIS(ddAddColumnCursor_png_data, sizeof(ddAddColumnCursor_png_data)); + img_ddAddColumnCursor_png->LoadFile(img_ddAddColumnCursor_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddAddColumnCursor_png; +} +#define ddAddColumnCursor_png_img ddAddColumnCursor_png_img() + +static wxBitmap *ddAddColumnCursor_png_bmp() +{ + static wxBitmap *bmp_ddAddColumnCursor_png; + if (!bmp_ddAddColumnCursor_png || !bmp_ddAddColumnCursor_png->IsOk()) + bmp_ddAddColumnCursor_png = new wxBitmap(*ddAddColumnCursor_png_img); + return bmp_ddAddColumnCursor_png; +} +#define ddAddColumnCursor_png_bmp ddAddColumnCursor_png_bmp() + +static wxIcon *ddAddColumnCursor_png_ico() +{ + static wxIcon *ico_ddAddColumnCursor_png; + if (!ico_ddAddColumnCursor_png || !ico_ddAddColumnCursor_png->IsOk()) + { + ico_ddAddColumnCursor_png = new wxIcon(); + ico_ddAddColumnCursor_png->CopyFromBitmap(*ddAddColumnCursor_png_bmp); + } + return ico_ddAddColumnCursor_png; +} +#define ddAddColumnCursor_png_ico ddAddColumnCursor_png_ico() + +#endif // DDADDCOLUMNCURSOR_PNG_H diff --git a/include/images/ddAddForeignKey.png b/include/images/ddAddForeignKey.png new file mode 100644 index 0000000000000000000000000000000000000000..f94315a5a7cf7871abf9b8b6fcbb55314750f77c GIT binary patch literal 173 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPgg)Hc4I;$!_(+Ge99-PZ!4!iOb0! zx+?$7XXH;fvMk}YP^6m$dn}`(u%U>7p#XzVi%+sj3ajIH28PIAqWigoegatx44$rj JF6*2UngFb?EkghR literal 0 HcmV?d00001 diff --git a/include/images/ddAddForeignKey.pngc b/include/images/ddAddForeignKey.pngc new file mode 100644 index 0000000..e633d53 --- /dev/null +++ b/include/images/ddAddForeignKey.pngc @@ -0,0 +1,66 @@ +#ifndef DDADDFOREIGNKEY_PNG_H +#define DDADDFOREIGNKEY_PNG_H + +static const unsigned char ddAddForeignKey_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, +0x08, 0x06, 0x00, 0x00, 0x00, 0xc4, 0x0f, 0xbe, +0x8b, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x24, 0x19, 0x8b, 0x27, 0x71, 0xcc, +0x00, 0x00, 0x00, 0x2d, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0xf0, 0x8a, 0x79, 0xfc, 0x9f, +0x01, 0x0f, 0x60, 0xc4, 0xa6, 0x60, 0xdb, 0x12, +0x59, 0x46, 0x38, 0x07, 0x5d, 0x01, 0x21, 0x13, +0x31, 0x14, 0x30, 0x31, 0x10, 0x00, 0x4c, 0x84, +0x4c, 0x63, 0x24, 0x64, 0x05, 0x41, 0xf7, 0x00, +0x00, 0x59, 0xfa, 0x15, 0xbf, 0x0a, 0x12, 0xf9, +0xf7, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddAddForeignKey_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddAddForeignKey_png = new wxImage(); + if (!img_ddAddForeignKey_png || !img_ddAddForeignKey_png->IsOk()) + { + wxMemoryInputStream img_ddAddForeignKey_pngIS(ddAddForeignKey_png_data, sizeof(ddAddForeignKey_png_data)); + img_ddAddForeignKey_png->LoadFile(img_ddAddForeignKey_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddAddForeignKey_png; +} +#define ddAddForeignKey_png_img ddAddForeignKey_png_img() + +static wxBitmap *ddAddForeignKey_png_bmp() +{ + static wxBitmap *bmp_ddAddForeignKey_png; + if (!bmp_ddAddForeignKey_png || !bmp_ddAddForeignKey_png->IsOk()) + bmp_ddAddForeignKey_png = new wxBitmap(*ddAddForeignKey_png_img); + return bmp_ddAddForeignKey_png; +} +#define ddAddForeignKey_png_bmp ddAddForeignKey_png_bmp() + +static wxIcon *ddAddForeignKey_png_ico() +{ + static wxIcon *ico_ddAddForeignKey_png; + if (!ico_ddAddForeignKey_png || !ico_ddAddForeignKey_png->IsOk()) + { + ico_ddAddForeignKey_png = new wxIcon(); + ico_ddAddForeignKey_png->CopyFromBitmap(*ddAddForeignKey_png_bmp); + } + return ico_ddAddForeignKey_png; +} +#define ddAddForeignKey_png_ico ddAddForeignKey_png_ico() + +#endif // DDADDFOREIGNKEY_PNG_H diff --git a/include/images/ddDeleteTableCursor.png b/include/images/ddDeleteTableCursor.png new file mode 100644 index 0000000000000000000000000000000000000000..1cd860fd3004f60b5a9a6bbc0399cf959dd6ebfb GIT binary patch literal 937 zcmV;a16KTrP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2ipc2 z4I~F~C`_*a00SvWL_t(o!|j$&XjE4e#((!_#(4v!h#N=R4j6)JpfX#B89U2S+5MYk|w)Gr|!EJkEMOi`Ua_Uf^-|scD|7utOR<$LEz` zV|!QB4M(CL_|*T$Z)Zq~&(ee?lPt14<@0JHU`Ye0^0Em}`1Nm1PeF0x&+2o+NF<_U zJU}4u?_>jinG|=tB+tBnr#9fJoh+Fb@XQ4K=LZ;H@FoLdCt>~g351kRB_Jx?o3MOH zM2+X_)Du>xo>bkITGLvil;ZRQ#fkgOUxC@!Mg`Ye)3HWJRzb(f>U26?vEkui{`vec zg>06`pMFLvm8#gpp+lVAw}P>~Zrw8z(JPx`U|^u)asJ>*UVqrfh64wPpqvInIyUidB*qvRO9l-w(cz_&&cJKhER_ zAJTB9o3-uj1jZo7lJD(dvxJvu9Y=w5I*sEvIF7@Wm0P)e^eEzah_$Ti=%C?DH@TfV z35o_WhJ0@i8P}~_2_q?R?LEuT&`>4W0A9P)OYluM>-Ov+uofwME!L3l>m%dNl)qMi zMA%DKOCp&}(%RaJ*1AGMZP~(?0|hvBid@_Kh%I}5`En%i*h%O(PR0Ad!9kY(aFKT& z_K|CALrf7dhQL@>ZQ8_d5fX4t0<|h=t*dUqtxvu#f$!LX6pIALGSYvARU0=V*3y*A zF*=Pz*ju2YJg1GFIsOk()) + { + wxMemoryInputStream img_ddDeleteTableCursor_pngIS(ddDeleteTableCursor_png_data, sizeof(ddDeleteTableCursor_png_data)); + img_ddDeleteTableCursor_png->LoadFile(img_ddDeleteTableCursor_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddDeleteTableCursor_png; +} +#define ddDeleteTableCursor_png_img ddDeleteTableCursor_png_img() + +static wxBitmap *ddDeleteTableCursor_png_bmp() +{ + static wxBitmap *bmp_ddDeleteTableCursor_png; + if (!bmp_ddDeleteTableCursor_png || !bmp_ddDeleteTableCursor_png->IsOk()) + bmp_ddDeleteTableCursor_png = new wxBitmap(*ddDeleteTableCursor_png_img); + return bmp_ddDeleteTableCursor_png; +} +#define ddDeleteTableCursor_png_bmp ddDeleteTableCursor_png_bmp() + +static wxIcon *ddDeleteTableCursor_png_ico() +{ + static wxIcon *ico_ddDeleteTableCursor_png; + if (!ico_ddDeleteTableCursor_png || !ico_ddDeleteTableCursor_png->IsOk()) + { + ico_ddDeleteTableCursor_png = new wxIcon(); + ico_ddDeleteTableCursor_png->CopyFromBitmap(*ddDeleteTableCursor_png_bmp); + } + return ico_ddDeleteTableCursor_png; +} +#define ddDeleteTableCursor_png_ico ddDeleteTableCursor_png_ico() + +#endif // DDDELETETABLECURSOR_PNG_H diff --git a/include/images/ddDown.png b/include/images/ddDown.png new file mode 100644 index 0000000000000000000000000000000000000000..87d32a0b039f859e72921a8ecf566a958a763584 GIT binary patch literal 291 zcmeAS@N?(olHy`uVBq!ia0vp^oIuRR!3HD+k8e2&q!^2X+?^QKos)S9l1cJ*cVYMs zf(!O8p9~b?EbxddW?E_Q)UK&GpAU( zZQ8ES&okoqbiz=_(scI0fHVCIuhiQq-+A}0xAXtvH17ZQ#q}Tmuef>W|88@&f5%^W d%y24UWiTsrw_r$r%mZ{TgQu&X%Q~loCIFtOa{B-P literal 0 HcmV?d00001 diff --git a/include/images/ddDown.pngc b/include/images/ddDown.pngc new file mode 100644 index 0000000..044276f --- /dev/null +++ b/include/images/ddDown.pngc @@ -0,0 +1,81 @@ +#ifndef DDDOWN_PNG_H +#define DDDOWN_PNG_H + +static const unsigned char ddDown_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x06, +0x08, 0x06, 0x00, 0x00, 0x00, 0x11, 0xc7, 0xb4, +0xc5, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x23, 0x37, 0x18, 0xb0, 0xea, 0xc4, +0x00, 0x00, 0x00, 0xa3, 0x49, 0x44, 0x41, 0x54, +0x08, 0xd7, 0x63, 0xec, 0xde, 0x98, 0xf8, 0xff, +0xfc, 0xab, 0x4d, 0x0c, 0xb8, 0x80, 0xa1, 0x98, +0x1f, 0x03, 0xcb, 0xf9, 0x57, 0x9b, 0x18, 0x4a, +0x5c, 0xa7, 0x30, 0x3c, 0x7a, 0x7b, 0x94, 0xe1, +0xdf, 0xbf, 0xdf, 0x0c, 0xff, 0x19, 0x7e, 0x33, +0xfc, 0xfb, 0xf7, 0x87, 0xe1, 0xff, 0xff, 0x3f, +0x0c, 0xd2, 0x42, 0xc6, 0x0c, 0x53, 0x0f, 0xb6, +0x31, 0x30, 0x19, 0x8a, 0xf9, 0x31, 0xf4, 0xec, +0xce, 0x61, 0xe0, 0x62, 0x13, 0x67, 0xf8, 0xf0, +0xfd, 0x05, 0xc3, 0xcb, 0x8f, 0xb7, 0x19, 0x3e, +0x7c, 0x7b, 0xca, 0xc0, 0xc5, 0x2e, 0xc6, 0x30, +0xf5, 0x60, 0x1b, 0x83, 0xa1, 0x98, 0x1f, 0x03, +0x23, 0x03, 0x03, 0x03, 0x03, 0xcc, 0xca, 0x04, +0x8b, 0x3c, 0x86, 0xd7, 0x9f, 0x6e, 0x32, 0x08, +0xf2, 0xc8, 0x31, 0x2c, 0x39, 0x35, 0x9b, 0xc1, +0x50, 0xcc, 0x8f, 0xa1, 0xd4, 0x7f, 0x3e, 0x23, +0xdc, 0xee, 0xee, 0x8d, 0x89, 0xff, 0xa3, 0x66, +0x0b, 0xff, 0x3f, 0x73, 0x7f, 0xf1, 0xff, 0xa8, +0xd9, 0xc2, 0xff, 0xbb, 0x37, 0x26, 0xfe, 0xc7, +0xea, 0x48, 0x98, 0x42, 0x74, 0x05, 0x00, 0x36, +0x71, 0x47, 0x38, 0x00, 0x67, 0xe3, 0x0c, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddDown_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddDown_png = new wxImage(); + if (!img_ddDown_png || !img_ddDown_png->IsOk()) + { + wxMemoryInputStream img_ddDown_pngIS(ddDown_png_data, sizeof(ddDown_png_data)); + img_ddDown_png->LoadFile(img_ddDown_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddDown_png; +} +#define ddDown_png_img ddDown_png_img() + +static wxBitmap *ddDown_png_bmp() +{ + static wxBitmap *bmp_ddDown_png; + if (!bmp_ddDown_png || !bmp_ddDown_png->IsOk()) + bmp_ddDown_png = new wxBitmap(*ddDown_png_img); + return bmp_ddDown_png; +} +#define ddDown_png_bmp ddDown_png_bmp() + +static wxIcon *ddDown_png_ico() +{ + static wxIcon *ico_ddDown_png; + if (!ico_ddDown_png || !ico_ddDown_png->IsOk()) + { + ico_ddDown_png = new wxIcon(); + ico_ddDown_png->CopyFromBitmap(*ddDown_png_bmp); + } + return ico_ddDown_png; +} +#define ddDown_png_ico ddDown_png_ico() + +#endif // DDDOWN_PNG_H diff --git a/include/images/ddMaximizeTable.png b/include/images/ddMaximizeTable.png new file mode 100644 index 0000000000000000000000000000000000000000..bab6188532dc1916b73b4261ac50ba21880782dc GIT binary patch literal 162 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPgg)Hc4J(E{7Y-t^$RWJY5_^BrYf4 zIeO&(d`A9+Bn6faGdFa1{FVdQ&MBb@0CHk3 A(EtDd literal 0 HcmV?d00001 diff --git a/include/images/ddMaximizeTable.pngc b/include/images/ddMaximizeTable.pngc new file mode 100644 index 0000000..de7ca09 --- /dev/null +++ b/include/images/ddMaximizeTable.pngc @@ -0,0 +1,65 @@ +#ifndef DDMAXIMIZETABLE_PNG_H +#define DDMAXIMIZETABLE_PNG_H + +static const unsigned char ddMaximizeTable_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, +0x08, 0x06, 0x00, 0x00, 0x00, 0xc4, 0x0f, 0xbe, +0x8b, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x23, 0x0a, 0x40, 0xd8, 0xa6, 0xd5, +0x00, 0x00, 0x00, 0x22, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0xdc, 0xc5, 0xc4, 0xff, 0x9f, +0x01, 0x0f, 0x60, 0x62, 0x20, 0x04, 0xf0, 0x99, +0xb0, 0x8b, 0x89, 0xff, 0x3f, 0x41, 0x13, 0xe8, +0xa0, 0x80, 0x91, 0x90, 0x37, 0x01, 0x99, 0xf5, +0x07, 0x35, 0xe9, 0xaf, 0xad, 0x0f, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddMaximizeTable_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddMaximizeTable_png = new wxImage(); + if (!img_ddMaximizeTable_png || !img_ddMaximizeTable_png->IsOk()) + { + wxMemoryInputStream img_ddMaximizeTable_pngIS(ddMaximizeTable_png_data, sizeof(ddMaximizeTable_png_data)); + img_ddMaximizeTable_png->LoadFile(img_ddMaximizeTable_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddMaximizeTable_png; +} +#define ddMaximizeTable_png_img ddMaximizeTable_png_img() + +static wxBitmap *ddMaximizeTable_png_bmp() +{ + static wxBitmap *bmp_ddMaximizeTable_png; + if (!bmp_ddMaximizeTable_png || !bmp_ddMaximizeTable_png->IsOk()) + bmp_ddMaximizeTable_png = new wxBitmap(*ddMaximizeTable_png_img); + return bmp_ddMaximizeTable_png; +} +#define ddMaximizeTable_png_bmp ddMaximizeTable_png_bmp() + +static wxIcon *ddMaximizeTable_png_ico() +{ + static wxIcon *ico_ddMaximizeTable_png; + if (!ico_ddMaximizeTable_png || !ico_ddMaximizeTable_png->IsOk()) + { + ico_ddMaximizeTable_png = new wxIcon(); + ico_ddMaximizeTable_png->CopyFromBitmap(*ddMaximizeTable_png_bmp); + } + return ico_ddMaximizeTable_png; +} +#define ddMaximizeTable_png_ico ddMaximizeTable_png_ico() + +#endif // DDMAXIMIZETABLE_PNG_H diff --git a/include/images/ddMinMaxCursor.png b/include/images/ddMinMaxCursor.png new file mode 100644 index 0000000000000000000000000000000000000000..692ad4c1e64108fb517a22473a7101aab4a5a230 GIT binary patch literal 1569 zcmV++2HyFJP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2ipc2 z4I(me!7mB`00p5*L_t(o!>yNJY*Y6Y$3MT{y*KyX*iOJCq@hb8)G28gX}5OGA3{hw zHmy>tN?o;X(x|3Znl`Nud)Uh!wn=^I$Cmw9QI z%}-z4T@wfipp>ErNJTq%&N~^9$U$zDO#%gwg0jHu-TH8_2e|5u6FvPQkqhth^AS zjE;jxPN^faI@=!WBPY0zEjG!XaFEO@o|QRhR`$( z$8qTSM-ILH?MO|PYxWndYl8k^=mGxyY>MIGVWgCW1kWoh|9)U#;0qbPzWV_Tm8H{; z(PC!Tlub2eSr$V>L+H9*68?Sr_7!MY0T){V;3|mcG>+f&k#gKMWm8po6#~n$5JE6A zGQz;X08&cE#>NU1xURdp5Gg8kq}8&is>9vmK2JeD8H*{{yLayw03J0z=TY->gkRiO zHq`>i-?~@{gM))b;inWpak8wIjg*pCy95WOtD_(midf&n%+@UpQuHK6*KGie;ZZ* zniCkiI!R7UF|b*&yTi+O2cHy`I_1%84$nSh@WyLHqW$fNI{gE^B-E8u1<>_wv~(gW z9zZue@l6~}Lp|Qbf5H*YotWdz_eRvOUl}ZbI5#n=esyS$i9kDzGqZ)?SBhv=BN@Q& z-Z`nx$1VKcdQ#aO3JulPN@BC0;JFJWd*jPF99_o*>NHVRv#R*Npyc+KlXUbvj;Tp3 zO~c6M5OWc<|6Qg(;4RsEA)F%C=*3nFyH2jFeV0X`W$S~aZbey~i{Nc-MwgQ2=nbBK zvXK|R(^I(J==fRn?&xh28@ABkIJ9ms)&-yp_CV8J+{^#v+bv0!uFm7})D!n_Ve(pv z!^cAE%-IQb_*h6CpNcbWZbVupP0<)V+db<7uqIzW|HBF8Ztp@_Cea(Wh~HQw6OAJp zykz|wNcucD$z^)u5&rngec~&LKZL}@xo4%t7k8gjVGwLO>9HQwoHs<3ggo&{HVL0{m=ESd$#;PY>Qb0 T{rO(I00000NkvXXu0mjf><0U~ literal 0 HcmV?d00001 diff --git a/include/images/ddMinMaxCursor.pngc b/include/images/ddMinMaxCursor.pngc new file mode 100644 index 0000000..dcb1dd2 --- /dev/null +++ b/include/images/ddMinMaxCursor.pngc @@ -0,0 +1,241 @@ +#ifndef DDMINMAXCURSOR_PNG_H +#define DDMINMAXCURSOR_PNG_H + +static const unsigned char ddMinMaxCursor_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x08, 0x06, 0x00, 0x00, 0x00, 0x73, 0x7a, 0x7a, +0xf4, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x22, 0x32, 0x71, 0xc1, 0x2f, 0x0a, +0x00, 0x00, 0x05, 0xa1, 0x49, 0x44, 0x41, 0x54, +0x58, 0xc3, 0xad, 0x97, 0x5f, 0x6c, 0x53, 0xf7, +0x15, 0xc7, 0x3f, 0xbf, 0xdf, 0xbd, 0x37, 0xf7, +0xde, 0xd8, 0x4e, 0xc0, 0x24, 0xa4, 0xa1, 0x4b, +0x21, 0xd4, 0x29, 0x69, 0x18, 0x69, 0xb7, 0x76, +0xcd, 0x1f, 0x42, 0x48, 0x3b, 0x36, 0xad, 0x52, +0xab, 0x4a, 0x5d, 0xb5, 0x6e, 0xd2, 0xa8, 0xa6, +0x56, 0x9a, 0x36, 0xad, 0x0f, 0x7b, 0xd8, 0xcb, +0x1e, 0xb6, 0x49, 0x7d, 0xe9, 0xe3, 0xa6, 0x4a, +0xd5, 0x24, 0xb6, 0x56, 0x5a, 0x99, 0x34, 0xb1, +0xa1, 0x3e, 0xb4, 0x48, 0x6c, 0xc0, 0x2a, 0x92, +0x2c, 0x26, 0x86, 0x42, 0x02, 0x2c, 0x59, 0x69, +0x03, 0x11, 0x38, 0xc4, 0x24, 0xfc, 0xa9, 0x63, +0x63, 0x3b, 0xf6, 0xb5, 0xef, 0x6f, 0x0f, 0xc1, +0xae, 0x1d, 0xbb, 0xc1, 0x8e, 0x7a, 0xa4, 0x9f, +0x74, 0x75, 0xef, 0xcf, 0xbf, 0xf3, 0xfd, 0x9d, +0xef, 0xf9, 0x9e, 0x73, 0x2c, 0x00, 0x05, 0x08, +0xaa, 0xb4, 0x43, 0xff, 0x1c, 0x57, 0xc1, 0x99, +0x04, 0x33, 0x0b, 0x69, 0x96, 0x1d, 0x17, 0xcb, +0x90, 0x04, 0x5a, 0x4c, 0xfa, 0x03, 0x1e, 0x5e, +0xfe, 0x5e, 0x6f, 0xd5, 0xe7, 0xe4, 0x4d, 0xdc, +0x03, 0x40, 0x35, 0x20, 0x0e, 0xbc, 0x3f, 0xa6, +0x3e, 0x98, 0x4a, 0xd3, 0xde, 0xbd, 0x03, 0x7b, +0xd3, 0x46, 0xb2, 0x52, 0x92, 0x4c, 0xa7, 0x89, +0x2e, 0xde, 0xe1, 0xce, 0x27, 0x97, 0x79, 0x69, +0x97, 0xcd, 0x4f, 0x5f, 0xdc, 0x5d, 0x13, 0x08, +0x09, 0xa0, 0x94, 0xa2, 0x08, 0x48, 0x45, 0x3b, +0x78, 0xe4, 0x94, 0xfa, 0x60, 0x3a, 0x4d, 0x67, +0xef, 0x63, 0x98, 0x8d, 0x3e, 0x92, 0xa9, 0x65, +0x96, 0x33, 0x0e, 0xc9, 0x54, 0x1a, 0xe5, 0xad, +0xc7, 0xdc, 0xd9, 0xc1, 0xa1, 0x8b, 0x29, 0x0e, +0x1e, 0x39, 0xa5, 0x6a, 0x01, 0xa0, 0xe7, 0x1f, +0x94, 0x52, 0x08, 0x21, 0xbe, 0x94, 0x8e, 0xe0, +0x4c, 0x82, 0xc0, 0x37, 0x76, 0xa1, 0x74, 0x8d, +0x5b, 0xf3, 0x0b, 0xdc, 0xb9, 0xbe, 0x48, 0x2a, +0xba, 0x84, 0xd1, 0xe8, 0x43, 0x36, 0xf9, 0x71, +0x1a, 0x1b, 0xc8, 0xb6, 0xb7, 0x11, 0x9c, 0x09, +0xd7, 0x4e, 0xc1, 0xbd, 0x08, 0xac, 0xbc, 0x10, +0xa2, 0x8c, 0x8e, 0x83, 0x47, 0x4e, 0xa9, 0x23, +0xb3, 0x3a, 0xdb, 0x1e, 0xeb, 0xe4, 0xfa, 0x95, +0x30, 0xdb, 0x73, 0x8b, 0x74, 0xb7, 0xd9, 0x6c, +0xdd, 0x54, 0xc7, 0xd5, 0xdb, 0x19, 0x2e, 0x84, +0x53, 0x8c, 0xa6, 0x1b, 0x48, 0x34, 0xf9, 0xa9, +0xbb, 0x12, 0x66, 0xff, 0x23, 0x92, 0xf3, 0xd7, +0x52, 0x74, 0xb7, 0xd9, 0xfc, 0xec, 0xfb, 0x6b, +0x53, 0x52, 0x06, 0xa0, 0x12, 0x88, 0xd7, 0xdf, +0x3a, 0xa1, 0xd4, 0xb6, 0x2e, 0x94, 0xae, 0x93, +0x9a, 0x9a, 0xe4, 0xd5, 0x3d, 0x9b, 0xd8, 0xd3, +0xfb, 0x44, 0xe1, 0xfb, 0xfb, 0xc7, 0x43, 0xea, +0xc3, 0xc9, 0x25, 0xce, 0x6f, 0x7e, 0x88, 0x4c, +0x26, 0x8b, 0x75, 0x27, 0xca, 0x6d, 0x9f, 0x17, +0x5f, 0x2c, 0x46, 0xdc, 0xd7, 0x51, 0x1d, 0x05, +0x45, 0x8e, 0x0b, 0xac, 0xe4, 0x41, 0x44, 0xa2, +0x0e, 0x6d, 0x3e, 0x0f, 0xf3, 0x9f, 0xce, 0xb2, +0x67, 0x6b, 0x7d, 0x89, 0xf3, 0x37, 0xdf, 0x1b, +0x51, 0x6f, 0x9d, 0x4e, 0xb1, 0xdc, 0xe0, 0x27, +0xa9, 0xe9, 0x24, 0x3c, 0x06, 0x0b, 0x56, 0x1d, +0x99, 0x9c, 0xcb, 0xb6, 0xf0, 0x75, 0x0e, 0xbe, +0x2c, 0x69, 0xd0, 0x5d, 0xea, 0x34, 0x10, 0xf7, +0xd2, 0x2c, 0x78, 0x43, 0x70, 0x34, 0x2c, 0x38, +0xb3, 0x58, 0x04, 0xa0, 0x52, 0xe8, 0xf3, 0x96, +0xca, 0xb8, 0xe4, 0xa4, 0xc6, 0x52, 0xe4, 0x26, +0xdd, 0xdd, 0xfe, 0x55, 0xb9, 0x71, 0x97, 0xe8, +0xce, 0x2e, 0x92, 0x40, 0x2a, 0x97, 0x23, 0x9d, +0x73, 0x49, 0xe7, 0x5c, 0x1e, 0x9e, 0x8b, 0x30, +0x18, 0xf0, 0xf0, 0xa7, 0xd9, 0x46, 0x12, 0x19, +0x97, 0x44, 0x26, 0xb7, 0xb2, 0x1c, 0x97, 0xdb, +0x89, 0x2c, 0xe9, 0xac, 0xc2, 0xc9, 0xb9, 0x2b, +0x2a, 0x58, 0xcb, 0x39, 0x40, 0x26, 0xa7, 0x70, +0x50, 0x64, 0xd3, 0x19, 0x7c, 0x96, 0x56, 0xf2, +0xad, 0x3f, 0xe0, 0xa5, 0x6d, 0x6a, 0x1a, 0x6b, +0xe1, 0x26, 0x99, 0xec, 0x8a, 0x73, 0x99, 0x76, +0x08, 0xa8, 0x34, 0xc9, 0x47, 0xfa, 0xcb, 0xa4, +0x25, 0x54, 0xa9, 0x23, 0x51, 0x4d, 0x21, 0xfa, +0xed, 0x3b, 0x27, 0xd5, 0x99, 0x05, 0xc1, 0xb7, +0x5a, 0x14, 0x6f, 0xbc, 0x36, 0x54, 0xb6, 0xf7, +0xd8, 0xc8, 0xc7, 0x6a, 0xec, 0xb3, 0xbb, 0x1c, +0xbd, 0x9e, 0xe3, 0xe2, 0xd7, 0xb6, 0xd0, 0x39, +0x37, 0xcf, 0x2b, 0x1d, 0x75, 0xbc, 0xd0, 0xf3, +0x20, 0x42, 0x88, 0xb2, 0xa5, 0x69, 0x1a, 0x7f, +0xb9, 0x24, 0x38, 0x30, 0x5d, 0x43, 0x05, 0xfc, +0xf0, 0xa3, 0xd3, 0xea, 0xf9, 0x67, 0x9e, 0x5a, +0x73, 0xff, 0x6f, 0xfe, 0x7c, 0x52, 0x8d, 0x5e, +0x49, 0xb2, 0x67, 0x7b, 0x3d, 0x3f, 0x79, 0xba, +0x0d, 0x29, 0x65, 0x99, 0x73, 0x29, 0x25, 0x9a, +0xa6, 0x21, 0x84, 0xa0, 0xf7, 0xb0, 0x4b, 0xcd, +0xa5, 0xf3, 0x7e, 0x16, 0xfa, 0x78, 0x42, 0x35, +0x6d, 0x6c, 0xc0, 0xb6, 0x6d, 0xa4, 0x94, 0x0c, +0x0f, 0x0f, 0xd3, 0xd7, 0xd7, 0x87, 0x94, 0x92, +0xf1, 0xf1, 0x71, 0x86, 0x86, 0x86, 0xd0, 0x34, +0x0d, 0xc7, 0x71, 0xe8, 0xf9, 0x47, 0x0e, 0xbd, +0xfd, 0xed, 0x48, 0x4d, 0x95, 0x6b, 0xf6, 0x17, +0xad, 0x6b, 0x82, 0xfe, 0x61, 0xe8, 0x01, 0xfe, +0xfd, 0x6c, 0x8a, 0xe1, 0xe1, 0x61, 0xa4, 0x94, +0x85, 0x04, 0xcf, 0x2b, 0x2c, 0xff, 0x7e, 0x60, +0x60, 0xe0, 0x0b, 0x19, 0xbe, 0xbe, 0xfb, 0x01, +0x0c, 0x95, 0xa5, 0xd3, 0x8e, 0xd1, 0x62, 0x66, +0xd7, 0x94, 0x4d, 0x35, 0x66, 0x59, 0x16, 0x43, +0x43, 0x43, 0xe8, 0xba, 0x5e, 0x12, 0xfe, 0x7d, +0xfb, 0xf6, 0x15, 0x68, 0x58, 0x01, 0x17, 0x5b, +0x01, 0xe0, 0x2a, 0x88, 0xe7, 0x34, 0x8e, 0xdf, +0xf4, 0x91, 0x72, 0xdc, 0x35, 0x65, 0x53, 0x55, +0x79, 0x15, 0x02, 0xcb, 0xb2, 0x10, 0x42, 0x30, +0x32, 0x32, 0xc2, 0xc0, 0xc0, 0x00, 0x52, 0x4a, +0xc6, 0xc6, 0xc6, 0x0a, 0x14, 0xb8, 0xae, 0xbb, +0xba, 0x10, 0x29, 0x2a, 0x75, 0xa4, 0xd5, 0xb2, +0xa9, 0xaa, 0xc3, 0xdd, 0xe3, 0x3e, 0x4f, 0x41, +0x3e, 0x19, 0x8b, 0x29, 0xd8, 0xbb, 0x77, 0xef, +0x17, 0x00, 0x1e, 0x35, 0x3f, 0xe7, 0x51, 0xf3, +0x73, 0x84, 0x5f, 0xdc, 0x57, 0x36, 0xd5, 0x02, +0xc8, 0xdf, 0xba, 0x58, 0x09, 0x83, 0x83, 0x83, +0x45, 0xe1, 0xa7, 0x14, 0x40, 0x71, 0xb2, 0xac, +0x96, 0x8d, 0x94, 0x92, 0x57, 0xbb, 0x04, 0x07, +0xa6, 0xab, 0xa3, 0x20, 0x16, 0x8b, 0x95, 0xdc, +0xfc, 0xcb, 0x64, 0x58, 0x98, 0x07, 0x00, 0x6c, +0xdb, 0xc6, 0xb6, 0x6d, 0x42, 0xa1, 0x50, 0x61, +0x63, 0x28, 0x14, 0xc2, 0x34, 0x4d, 0x4c, 0xd3, +0x5c, 0xdd, 0x27, 0xee, 0x6b, 0xd5, 0x9e, 0xa7, +0xe7, 0x6f, 0x5e, 0xad, 0x6c, 0xaa, 0x4d, 0xc2, +0x9a, 0x64, 0x58, 0x8b, 0x6c, 0xbe, 0x6a, 0x19, +0x4a, 0x00, 0xc3, 0x30, 0x30, 0x0c, 0x03, 0x4d, +0xd3, 0xd0, 0x75, 0xbd, 0xb0, 0x2e, 0xcd, 0xcc, +0x16, 0x9e, 0x8b, 0x13, 0xa7, 0x5a, 0x19, 0x1a, +0x86, 0x41, 0x30, 0x18, 0x2c, 0x38, 0x1d, 0x1b, +0x1b, 0x43, 0xd7, 0x75, 0x0c, 0xc3, 0x28, 0xa5, +0xe0, 0xa9, 0xbf, 0x67, 0xcb, 0x0e, 0xf9, 0xb1, +0x79, 0x89, 0xe0, 0x6c, 0x92, 0xfe, 0xc9, 0x25, +0xfe, 0x9a, 0xde, 0x51, 0x53, 0x9f, 0xa8, 0x45, +0x86, 0x15, 0x33, 0xeb, 0xf7, 0x7f, 0x1b, 0x55, +0xff, 0x9a, 0x13, 0x18, 0xbb, 0x3a, 0x49, 0x4e, +0x4c, 0x31, 0xb0, 0x59, 0xb1, 0xbb, 0xc3, 0xcb, +0x77, 0x07, 0x9f, 0x14, 0x95, 0x3a, 0xe5, 0xd1, +0x6b, 0x0e, 0xcf, 0x3e, 0x64, 0xf0, 0xc6, 0x6b, +0x43, 0xa2, 0xfd, 0xed, 0x88, 0x3a, 0xfd, 0x03, +0xbd, 0x24, 0xd4, 0x95, 0x54, 0x05, 0xd0, 0xf5, +0x6e, 0xb4, 0x74, 0x22, 0x2a, 0x1e, 0x40, 0x37, +0x3d, 0xf1, 0x4d, 0x1c, 0x4d, 0x43, 0x3d, 0xde, +0xc5, 0x7f, 0xc2, 0x11, 0xce, 0x9d, 0x98, 0xe3, +0xcd, 0xf7, 0x46, 0xd4, 0xaf, 0x5f, 0x19, 0x2c, +0x80, 0x38, 0x37, 0x31, 0xa9, 0x7e, 0x75, 0x68, +0x8e, 0x89, 0x40, 0x3b, 0x8d, 0x33, 0xb3, 0x85, +0xdf, 0x57, 0x8a, 0x68, 0x55, 0x23, 0x19, 0xc0, +0xef, 0xde, 0x39, 0xa9, 0xce, 0xc7, 0x2d, 0xfc, +0xde, 0x7a, 0x52, 0xd9, 0x1c, 0x0a, 0x0d, 0xd5, +0xd6, 0x4a, 0x62, 0xb3, 0x9f, 0xe0, 0xb9, 0x0b, +0x25, 0x7b, 0xe3, 0xcb, 0x39, 0x1c, 0x5d, 0xc7, +0x04, 0xea, 0x34, 0x51, 0x55, 0xb3, 0xaa, 0xf8, +0xbf, 0xa0, 0xe4, 0xf6, 0x97, 0x93, 0x74, 0xf4, +0x3c, 0x8e, 0xa9, 0x49, 0x2c, 0x4d, 0xc3, 0xc8, +0xe6, 0x10, 0x73, 0x11, 0xb4, 0xff, 0x5d, 0xa6, +0x3f, 0xe0, 0x2d, 0xd9, 0x7b, 0x21, 0x9c, 0x22, +0xd6, 0xe8, 0xc5, 0x56, 0x0a, 0xbb, 0x4e, 0xae, +0xab, 0x7d, 0x97, 0x45, 0xa0, 0x65, 0xeb, 0x83, +0xa4, 0x6e, 0x45, 0x59, 0x9c, 0x8b, 0xe0, 0x6d, +0x6d, 0x46, 0x97, 0x92, 0xe6, 0xe8, 0x0d, 0x9e, +0x7f, 0xb2, 0x91, 0x17, 0xbf, 0xd3, 0x53, 0xb8, +0xdd, 0xe8, 0xf8, 0x59, 0xf5, 0xee, 0xe8, 0x6d, +0x12, 0x1b, 0xb6, 0xd0, 0xe0, 0x38, 0xb4, 0x6e, +0x30, 0xd6, 0x05, 0xa0, 0x0c, 0xf6, 0x40, 0xd3, +0x5d, 0xdc, 0xcb, 0xff, 0xe5, 0xdb, 0x2d, 0x49, +0x96, 0xae, 0xce, 0xe3, 0xf1, 0xd4, 0x13, 0xf7, +0x6f, 0x61, 0xf2, 0x5a, 0x8a, 0xc3, 0xc7, 0x42, +0xea, 0xcc, 0xd9, 0x09, 0x75, 0xf8, 0x58, 0x48, +0x1d, 0x9f, 0x8a, 0x33, 0x6d, 0x6e, 0x44, 0x5a, +0x26, 0x4d, 0xd1, 0x18, 0x3d, 0xdb, 0x3d, 0xeb, +0x02, 0xb0, 0x26, 0x5f, 0x3f, 0xff, 0xc3, 0x09, +0xe5, 0x6e, 0xef, 0x42, 0x59, 0x26, 0xd1, 0x1b, +0xb7, 0x88, 0xdf, 0x58, 0x24, 0x13, 0x8d, 0x23, +0x1a, 0xbc, 0x64, 0xfd, 0x1b, 0x48, 0xfa, 0x3c, +0x38, 0xc9, 0x65, 0x7a, 0xe3, 0x11, 0xfe, 0xf8, +0xcb, 0x7d, 0xe2, 0x2b, 0x89, 0x40, 0xe9, 0xc4, +0xeb, 0x61, 0xee, 0xfc, 0x27, 0x68, 0xd9, 0x1c, +0x1b, 0x5b, 0x9b, 0x69, 0xfe, 0xfa, 0x0e, 0x9a, +0x9f, 0xee, 0xa5, 0xbe, 0xf3, 0x61, 0xea, 0x9a, +0xfd, 0x58, 0x0a, 0x36, 0x84, 0xe7, 0xe9, 0x0f, +0xac, 0xef, 0xf6, 0xf7, 0x05, 0xb0, 0xff, 0xb9, +0x3e, 0xf1, 0xc2, 0x4e, 0x93, 0xab, 0x67, 0x2f, +0x92, 0x8d, 0x27, 0xa8, 0xb7, 0x4d, 0x6c, 0x43, +0xc7, 0xb6, 0x4c, 0x8c, 0x64, 0x0a, 0xe3, 0xd3, +0x2b, 0xfc, 0xa8, 0xbb, 0x9e, 0xfd, 0xcf, 0xf5, +0xad, 0x7b, 0xb6, 0xfc, 0x3f, 0x6c, 0x8b, 0x59, +0x04, 0xfd, 0xf9, 0x5e, 0xbb, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddMinMaxCursor_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddMinMaxCursor_png = new wxImage(); + if (!img_ddMinMaxCursor_png || !img_ddMinMaxCursor_png->IsOk()) + { + wxMemoryInputStream img_ddMinMaxCursor_pngIS(ddMinMaxCursor_png_data, sizeof(ddMinMaxCursor_png_data)); + img_ddMinMaxCursor_png->LoadFile(img_ddMinMaxCursor_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddMinMaxCursor_png; +} +#define ddMinMaxCursor_png_img ddMinMaxCursor_png_img() + +static wxBitmap *ddMinMaxCursor_png_bmp() +{ + static wxBitmap *bmp_ddMinMaxCursor_png; + if (!bmp_ddMinMaxCursor_png || !bmp_ddMinMaxCursor_png->IsOk()) + bmp_ddMinMaxCursor_png = new wxBitmap(*ddMinMaxCursor_png_img); + return bmp_ddMinMaxCursor_png; +} +#define ddMinMaxCursor_png_bmp ddMinMaxCursor_png_bmp() + +static wxIcon *ddMinMaxCursor_png_ico() +{ + static wxIcon *ico_ddMinMaxCursor_png; + if (!ico_ddMinMaxCursor_png || !ico_ddMinMaxCursor_png->IsOk()) + { + ico_ddMinMaxCursor_png = new wxIcon(); + ico_ddMinMaxCursor_png->CopyFromBitmap(*ddMinMaxCursor_png_bmp); + } + return ico_ddMinMaxCursor_png; +} +#define ddMinMaxCursor_png_ico ddMinMaxCursor_png_ico() + +#endif // DDMINMAXCURSOR_PNG_H diff --git a/include/images/ddMinimizeTable.png b/include/images/ddMinimizeTable.png new file mode 100644 index 0000000000000000000000000000000000000000..650264ca8448697f5c481bda5357e6f896ae8729 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPgg)Hc4J3YYy4z>wrS?o-U3d5|@(` vB={O8Ha0dUiVOd*&zY3>-_FQL(1?*?R}BjbOYf>_K&1?xu6{1-oD!MIsOk()) + { + wxMemoryInputStream img_ddMinimizeTable_pngIS(ddMinimizeTable_png_data, sizeof(ddMinimizeTable_png_data)); + img_ddMinimizeTable_png->LoadFile(img_ddMinimizeTable_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddMinimizeTable_png; +} +#define ddMinimizeTable_png_img ddMinimizeTable_png_img() + +static wxBitmap *ddMinimizeTable_png_bmp() +{ + static wxBitmap *bmp_ddMinimizeTable_png; + if (!bmp_ddMinimizeTable_png || !bmp_ddMinimizeTable_png->IsOk()) + bmp_ddMinimizeTable_png = new wxBitmap(*ddMinimizeTable_png_img); + return bmp_ddMinimizeTable_png; +} +#define ddMinimizeTable_png_bmp ddMinimizeTable_png_bmp() + +static wxIcon *ddMinimizeTable_png_ico() +{ + static wxIcon *ico_ddMinimizeTable_png; + if (!ico_ddMinimizeTable_png || !ico_ddMinimizeTable_png->IsOk()) + { + ico_ddMinimizeTable_png = new wxIcon(); + ico_ddMinimizeTable_png->CopyFromBitmap(*ddMinimizeTable_png_bmp); + } + return ico_ddMinimizeTable_png; +} +#define ddMinimizeTable_png_ico ddMinimizeTable_png_ico() + +#endif // DDMINIMIZETABLE_PNG_H diff --git a/include/images/ddRelationshipCursor.png b/include/images/ddRelationshipCursor.png new file mode 100644 index 0000000000000000000000000000000000000000..73a0078e795355ddbc9064e971112ed9e76025dc GIT binary patch literal 611 zcmV-p0-XJcP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2ipc2 z4IvnTSG6Ai00HAkL_t(o!|j%_Zrd;rhW|TJr8J~Nmo{UzrVmiSh+%8+lXPugCrh@h zd4UXBECDhsWDk%jLxvVDiU28$qLEByu*6U@po)!S0fi4BBnl$=^Z#@_0f0u2!R1x= zDnM)9n~2JR-bAq7=|coJA8cEMuscLl(*l6DCZJrLw*3u|W%ouFKREuX|HXlg?)=Nq zJNUZ5`|uubWr5d1;gttax!2h@!uc)X^7~4_#%)&`__g$K@na9abA`o&!s21MYPrJC zMS(wsM!r<*S@6uz&D$mq()Aq+S7tY#_o;nh;85P-P~L&w5Qx^B=Xp52CY)TA-+&9V zwuNm0Rc19CGlQA&=>y^9O05LAF#Ag;nFzxW%#1jWF>M%$U#Th@uFd=ONGY=0Vhr zSxY*b;Y5Tuj={_|Cjgk|!{P8rfD5xO=SmO+h@uEWh}t}p$)tt>xL;*KH)d>GrQ7NS z5g`Zy_`Z+XY-Z+3(-cAo_`Yu(VVhYPhRCwa49Kz!Qc6fE?K(k?wqD^%_DPbMzKviy zotnOIW!9<0mhV^YRr8HTBg=m4D0X4iB|e@NZndCdMnp)G#Hdfx)TE74>Ny8hyMT&W xWlfVAGh;j+zufIsOk()) + { + wxMemoryInputStream img_ddRelationshipCursor_pngIS(ddRelationshipCursor_png_data, sizeof(ddRelationshipCursor_png_data)); + img_ddRelationshipCursor_png->LoadFile(img_ddRelationshipCursor_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddRelationshipCursor_png; +} +#define ddRelationshipCursor_png_img ddRelationshipCursor_png_img() + +static wxBitmap *ddRelationshipCursor_png_bmp() +{ + static wxBitmap *bmp_ddRelationshipCursor_png; + if (!bmp_ddRelationshipCursor_png || !bmp_ddRelationshipCursor_png->IsOk()) + bmp_ddRelationshipCursor_png = new wxBitmap(*ddRelationshipCursor_png_img); + return bmp_ddRelationshipCursor_png; +} +#define ddRelationshipCursor_png_bmp ddRelationshipCursor_png_bmp() + +static wxIcon *ddRelationshipCursor_png_ico() +{ + static wxIcon *ico_ddRelationshipCursor_png; + if (!ico_ddRelationshipCursor_png || !ico_ddRelationshipCursor_png->IsOk()) + { + ico_ddRelationshipCursor_png = new wxIcon(); + ico_ddRelationshipCursor_png->CopyFromBitmap(*ddRelationshipCursor_png_bmp); + } + return ico_ddRelationshipCursor_png; +} +#define ddRelationshipCursor_png_ico ddRelationshipCursor_png_ico() + +#endif // DDRELATIONSHIPCURSOR_PNG_H diff --git a/include/images/ddRemoveColumn.png b/include/images/ddRemoveColumn.png new file mode 100644 index 0000000000000000000000000000000000000000..eaf3e3bfe3e8121ea005962516aa97ef27357f10 GIT binary patch literal 151 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPgg)Hc4JZrW#Y9RG^T!r;B5V#O36K n1(pe4x+?$3&u3C=Yh-7bbCjv)Mv44(pb`d8S3j3^P6IsOk()) + { + wxMemoryInputStream img_ddRemoveColumn_pngIS(ddRemoveColumn_png_data, sizeof(ddRemoveColumn_png_data)); + img_ddRemoveColumn_png->LoadFile(img_ddRemoveColumn_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddRemoveColumn_png; +} +#define ddRemoveColumn_png_img ddRemoveColumn_png_img() + +static wxBitmap *ddRemoveColumn_png_bmp() +{ + static wxBitmap *bmp_ddRemoveColumn_png; + if (!bmp_ddRemoveColumn_png || !bmp_ddRemoveColumn_png->IsOk()) + bmp_ddRemoveColumn_png = new wxBitmap(*ddRemoveColumn_png_img); + return bmp_ddRemoveColumn_png; +} +#define ddRemoveColumn_png_bmp ddRemoveColumn_png_bmp() + +static wxIcon *ddRemoveColumn_png_ico() +{ + static wxIcon *ico_ddRemoveColumn_png; + if (!ico_ddRemoveColumn_png || !ico_ddRemoveColumn_png->IsOk()) + { + ico_ddRemoveColumn_png = new wxIcon(); + ico_ddRemoveColumn_png->CopyFromBitmap(*ddRemoveColumn_png_bmp); + } + return ico_ddRemoveColumn_png; +} +#define ddRemoveColumn_png_ico ddRemoveColumn_png_ico() + +#endif // DDREMOVECOLUMN_PNG_H diff --git a/include/images/ddRemoveColumnCursor.png b/include/images/ddRemoveColumnCursor.png new file mode 100644 index 0000000000000000000000000000000000000000..166ac7bc8c6a9ed055b1a8e3db14524a66dcc5b3 GIT binary patch literal 751 zcmVPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2ipc2 z4IvHeic$0c00M7GL_t(o!|jy8OOtUJ$3MS!WA6kzYY@~(0$m7!hM1R%7*rP(-604Z zU0#Cn5K0*4Svr(qyGWK4_#db&VIqTfbTGWEAkDW!b_oe2-}l|x)4^@12ixZ6Ao{|~ z%kO;;-_P?rzwZMe)KFUPEj0xYk(xo|J5VzSZSSEL5Zb{H#|`1#dr(U4V*%8$0p!e8 zEiR(eGKTpM6kT~>a`RBw`|b4%UOb^n0Vv7*`DLAEeXB4wr4&A&52X~ZKPjHQ-#%Ij z{-$Pqi)1oMU0q$_(RCfuG>NomM@vB|T3%j8L{LiM^?K1X?O=+k1E7?mv$L~crj$b0 zb!^*aXJ-fSRd)m)kB4M3iQn(X@AsqYIsm3=R%R0xt9U%lw~L$ zW~K=C^^vt5#BoT?&(UZYRI~$$?%n8Vn#TI@2-#OtvIsOk()) + { + wxMemoryInputStream img_ddRemoveColumnCursor_pngIS(ddRemoveColumnCursor_png_data, sizeof(ddRemoveColumnCursor_png_data)); + img_ddRemoveColumnCursor_png->LoadFile(img_ddRemoveColumnCursor_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddRemoveColumnCursor_png; +} +#define ddRemoveColumnCursor_png_img ddRemoveColumnCursor_png_img() + +static wxBitmap *ddRemoveColumnCursor_png_bmp() +{ + static wxBitmap *bmp_ddRemoveColumnCursor_png; + if (!bmp_ddRemoveColumnCursor_png || !bmp_ddRemoveColumnCursor_png->IsOk()) + bmp_ddRemoveColumnCursor_png = new wxBitmap(*ddRemoveColumnCursor_png_img); + return bmp_ddRemoveColumnCursor_png; +} +#define ddRemoveColumnCursor_png_bmp ddRemoveColumnCursor_png_bmp() + +static wxIcon *ddRemoveColumnCursor_png_ico() +{ + static wxIcon *ico_ddRemoveColumnCursor_png; + if (!ico_ddRemoveColumnCursor_png || !ico_ddRemoveColumnCursor_png->IsOk()) + { + ico_ddRemoveColumnCursor_png = new wxIcon(); + ico_ddRemoveColumnCursor_png->CopyFromBitmap(*ddRemoveColumnCursor_png_bmp); + } + return ico_ddRemoveColumnCursor_png; +} +#define ddRemoveColumnCursor_png_ico ddRemoveColumnCursor_png_ico() + +#endif // DDREMOVECOLUMNCURSOR_PNG_H diff --git a/include/images/ddRemoveTable.png b/include/images/ddRemoveTable.png new file mode 100644 index 0000000000000000000000000000000000000000..8d6aedb7937d4c66a2ec207a9e0997930881b856 GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPgg)Hc4IumF>zuZUTjjJY5_^BrYc> z0Ktu;NB-A~3;(ZY({Olxn04buLy?8vMuq|mETRG>%))x^4@)$x7#O_2h}QqymeC2+ O&EVIsOk()) + { + wxMemoryInputStream img_ddRemoveTable_pngIS(ddRemoveTable_png_data, sizeof(ddRemoveTable_png_data)); + img_ddRemoveTable_png->LoadFile(img_ddRemoveTable_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddRemoveTable_png; +} +#define ddRemoveTable_png_img ddRemoveTable_png_img() + +static wxBitmap *ddRemoveTable_png_bmp() +{ + static wxBitmap *bmp_ddRemoveTable_png; + if (!bmp_ddRemoveTable_png || !bmp_ddRemoveTable_png->IsOk()) + bmp_ddRemoveTable_png = new wxBitmap(*ddRemoveTable_png_img); + return bmp_ddRemoveTable_png; +} +#define ddRemoveTable_png_bmp ddRemoveTable_png_bmp() + +static wxIcon *ddRemoveTable_png_ico() +{ + static wxIcon *ico_ddRemoveTable_png; + if (!ico_ddRemoveTable_png || !ico_ddRemoveTable_png->IsOk()) + { + ico_ddRemoveTable_png = new wxIcon(); + ico_ddRemoveTable_png->CopyFromBitmap(*ddRemoveTable_png_bmp); + } + return ico_ddRemoveTable_png; +} +#define ddRemoveTable_png_ico ddRemoveTable_png_ico() + +#endif // DDREMOVETABLE_PNG_H diff --git a/include/images/ddRemoveTable2.png b/include/images/ddRemoveTable2.png new file mode 100644 index 0000000000000000000000000000000000000000..fe9bc97f0345fb233af5957a04b0594f5251dd69 GIT binary patch literal 759 zcmVPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2ipc2 z4InVB`7ERW00MVOL_t(I%bk-=NK{c6hM#k1ZubsEgqudHDN7_BF$7H^Ff1alHfri3 z2$U9G45E#;ONtC#w6H`7(URJznX;-m5Vgz{>(is#;y%0L?66x z&f$FT_r2eHj!0`=l>A4`*QN>pKftAvqAwdcd zn@I5kWNOP~YRiesLTm~}Q4m7#;FI9q6v-X@YqFv!)MP119eBGyAmCwqe4HOQ8i|HN zEM2>frfD8l8X9<5o64+VNKb+gf{~FCuVUnC2YcrG$gQtuvZ;x?&%bc^_C?H_jqH6r zL3ULYAKKcOH4G`zS{LPTNi3=5XedN(T^%?M(s6j((n9?F1$57+?a_pO(MNL1Pud`*19NPoUs@i z8}o(*u=`0b?)`Rhs;hA=3%OoZS|*XcK7xk9!L~Nx2T)a&qM{-cMe#^PaWQvBqR`n% zxcn^ATCd#S?!w`jcFUq@)loE%l~7Jv7M5xf-@V z>L5KUjI=GJZ8Nv9km%sZV<+i#-O9^{?rshpKf(0y5YfDRrqV+kD>==~v!@)`x1YJs p3j_^g>;FD$81f~^KU%js{|$p#B}$xg literal 0 HcmV?d00001 diff --git a/include/images/ddRemoveTable2.pngc b/include/images/ddRemoveTable2.pngc new file mode 100644 index 0000000..775e9e9 --- /dev/null +++ b/include/images/ddRemoveTable2.pngc @@ -0,0 +1,139 @@ +#ifndef DDREMOVETABLE2_PNG_H +#define DDREMOVETABLE2_PNG_H + +static const unsigned char ddRemoveTable2_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, +0x08, 0x06, 0x00, 0x00, 0x00, 0xd4, 0xaf, 0x2c, +0xc4, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x20, 0x30, 0xad, 0xf9, 0x2c, 0xa4, +0x00, 0x00, 0x02, 0x77, 0x49, 0x44, 0x41, 0x54, +0x38, 0xcb, 0x9d, 0x93, 0x4d, 0x48, 0x54, 0x51, +0x18, 0x86, 0x9f, 0x73, 0x67, 0x6e, 0xf7, 0x0e, +0x44, 0x84, 0x9b, 0x46, 0xaa, 0x29, 0x4b, 0x24, +0x1d, 0x31, 0x04, 0x4d, 0x21, 0x30, 0x2c, 0x22, +0xb0, 0x36, 0x6a, 0xea, 0x22, 0x08, 0x94, 0x16, +0x5d, 0x0c, 0xa2, 0x8d, 0xb6, 0x4b, 0x8a, 0x0c, +0x5d, 0xb4, 0xb0, 0x44, 0x08, 0xd1, 0x92, 0xda, +0xb4, 0x71, 0x53, 0xf9, 0x6f, 0xb9, 0x48, 0x34, +0x23, 0xa3, 0x1f, 0xc7, 0xc0, 0xbf, 0x9a, 0x85, +0x12, 0x95, 0x8b, 0x34, 0xe7, 0xfe, 0xcc, 0x3d, +0x2d, 0xc6, 0xae, 0x0d, 0x28, 0x44, 0x1f, 0xbc, +0x70, 0xce, 0xe1, 0x7c, 0xef, 0xf7, 0xbd, 0xdf, +0x7b, 0x8e, 0x48, 0x6b, 0x5d, 0x94, 0xfc, 0x47, +0xcc, 0xd7, 0xa6, 0x0a, 0x00, 0x3f, 0xc0, 0xa5, +0xa3, 0x41, 0x54, 0xe9, 0xb0, 0xd3, 0x6f, 0x11, +0x54, 0x63, 0xec, 0xd2, 0x1c, 0x76, 0xf8, 0x5d, +0xb6, 0xf9, 0x40, 0x90, 0xe0, 0x5f, 0xb1, 0x25, +0xef, 0xbe, 0x2b, 0xf4, 0x44, 0x05, 0x13, 0x5f, +0x37, 0x88, 0xfc, 0x00, 0xae, 0x84, 0x9f, 0x71, +0x1f, 0xdf, 0x4c, 0x8d, 0xf7, 0xb6, 0xca, 0x9a, +0xed, 0xb2, 0x6a, 0xb9, 0xac, 0x5a, 0xf1, 0x04, +0x6c, 0x97, 0x35, 0xd3, 0xe5, 0x97, 0xe3, 0x62, +0x3a, 0x12, 0x3b, 0xee, 0x7a, 0x04, 0xca, 0x06, +0x97, 0xdc, 0x64, 0x95, 0x08, 0x21, 0x41, 0x0a, +0x10, 0x9b, 0x48, 0xf1, 0x03, 0x64, 0x6a, 0xcb, +0x64, 0x6a, 0xcb, 0x89, 0xcb, 0x42, 0x6c, 0x0a, +0x45, 0x51, 0x10, 0x42, 0xf0, 0xe0, 0x93, 0xe0, +0xde, 0x14, 0xc9, 0x1d, 0xfc, 0x6b, 0xb2, 0xa2, +0x28, 0xd4, 0x64, 0x29, 0x49, 0x1d, 0x78, 0xbb, +0x40, 0x20, 0xe0, 0x61, 0x7c, 0x7c, 0x9c, 0x1f, +0x37, 0x1a, 0x89, 0x86, 0x42, 0x2c, 0x5d, 0xbb, +0x8e, 0xa6, 0x69, 0x1e, 0x56, 0x1a, 0x1a, 0x78, +0x58, 0x9b, 0xca, 0xac, 0x61, 0x48, 0x4f, 0x82, +0x10, 0x82, 0x91, 0x91, 0x11, 0xaf, 0x62, 0xe4, +0x6a, 0x07, 0x7b, 0xe6, 0xfb, 0xc8, 0xad, 0xaf, +0x67, 0xb2, 0xa9, 0x89, 0xbb, 0xcf, 0xbf, 0x70, +0xf8, 0xf6, 0x45, 0xcc, 0x9b, 0x8d, 0xec, 0x7d, +0x3d, 0x41, 0x76, 0x55, 0x15, 0x1f, 0xda, 0xda, +0x98, 0x35, 0x0c, 0x29, 0xd2, 0x5a, 0x17, 0xe5, +0x70, 0x49, 0x2c, 0xa9, 0xe5, 0x68, 0x28, 0x44, +0x6e, 0x5d, 0x1d, 0x38, 0x0e, 0xd2, 0x71, 0x78, +0xdb, 0xd2, 0x42, 0xfc, 0xfc, 0x05, 0x7c, 0x5d, +0xed, 0x64, 0x57, 0x56, 0xe2, 0x9a, 0x26, 0xd2, +0xb4, 0x88, 0xf4, 0xf6, 0x24, 0x24, 0x08, 0x21, +0x08, 0x04, 0x02, 0xe8, 0xba, 0x8e, 0xae, 0xeb, +0x0c, 0xa4, 0x9d, 0x62, 0xb2, 0xb9, 0x19, 0x69, +0xdb, 0x48, 0xcb, 0x22, 0xa7, 0xa6, 0x06, 0x5f, +0x57, 0x3b, 0xe1, 0x8a, 0x0a, 0xdc, 0x98, 0x89, +0x34, 0x4d, 0x22, 0xbd, 0x3d, 0x04, 0x0d, 0x03, +0x91, 0xd6, 0xba, 0x28, 0x5f, 0x9c, 0xb1, 0x18, +0x1b, 0x1b, 0xf3, 0x86, 0x05, 0xb0, 0xfb, 0x49, +0x2f, 0xee, 0xfd, 0x76, 0x72, 0xaa, 0xab, 0x71, +0x2d, 0x0b, 0xb9, 0x5e, 0x55, 0x5a, 0x26, 0x91, +0xbe, 0x3e, 0x82, 0x86, 0xc1, 0xc1, 0xb6, 0x36, +0xe1, 0x07, 0x50, 0x55, 0x95, 0xa2, 0xa2, 0x22, +0x14, 0x45, 0xf1, 0x48, 0x44, 0x71, 0x31, 0x77, +0x46, 0xa2, 0xd0, 0xd9, 0x49, 0xb8, 0xfc, 0x2c, +0xd2, 0x5a, 0xaf, 0xdc, 0xdf, 0xef, 0x25, 0x7b, +0x2e, 0x08, 0x21, 0xd0, 0x75, 0x1d, 0x4d, 0xd3, +0x50, 0x55, 0x95, 0xd1, 0xd1, 0x51, 0x3e, 0x5e, +0xa9, 0xe7, 0xe4, 0x7c, 0x1f, 0xe1, 0xf2, 0x72, +0xa4, 0x19, 0x43, 0xc6, 0x62, 0xb8, 0x31, 0x93, +0x8c, 0xc2, 0x42, 0x96, 0xd6, 0x07, 0xe8, 0xb9, +0xa0, 0x28, 0x4a, 0x92, 0x0b, 0x6f, 0x2e, 0xb7, +0x26, 0x92, 0xcb, 0xca, 0x12, 0x89, 0xa6, 0xc5, +0xf4, 0xe0, 0x00, 0x19, 0x05, 0x05, 0x48, 0xcb, +0x22, 0x3d, 0x1c, 0x66, 0xe6, 0x6f, 0x17, 0x5e, +0x55, 0xfa, 0x93, 0x5c, 0x88, 0xa4, 0xa4, 0x10, +0x2e, 0x2d, 0xf5, 0xa6, 0x3d, 0x3d, 0x34, 0xc8, +0xca, 0xb9, 0x1a, 0xb6, 0x3f, 0xea, 0x20, 0x3d, +0x2b, 0x8c, 0xb4, 0x2d, 0xa4, 0x6d, 0x33, 0xb7, +0xb0, 0x90, 0xe8, 0xe0, 0xc8, 0x63, 0x27, 0xe9, +0x75, 0xdd, 0xca, 0xcb, 0x87, 0xee, 0x6e, 0x0e, +0x1d, 0x3f, 0xc1, 0xf4, 0xf0, 0x10, 0xd1, 0xbc, +0x7c, 0xa6, 0xd2, 0x43, 0x1c, 0x2b, 0x39, 0xcd, +0xcc, 0xb3, 0xa7, 0x1c, 0xd8, 0xb7, 0x9f, 0xb9, +0xcf, 0x0b, 0x04, 0x0d, 0x63, 0xeb, 0xff, 0x3e, +0x6b, 0x18, 0xf2, 0x25, 0xc8, 0x3f, 0x5a, 0xb7, +0x3a, 0xff, 0x0d, 0x83, 0x59, 0x25, 0x4a, 0xa1, +0x2d, 0x84, 0x28, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddRemoveTable2_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddRemoveTable2_png = new wxImage(); + if (!img_ddRemoveTable2_png || !img_ddRemoveTable2_png->IsOk()) + { + wxMemoryInputStream img_ddRemoveTable2_pngIS(ddRemoveTable2_png_data, sizeof(ddRemoveTable2_png_data)); + img_ddRemoveTable2_png->LoadFile(img_ddRemoveTable2_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddRemoveTable2_png; +} +#define ddRemoveTable2_png_img ddRemoveTable2_png_img() + +static wxBitmap *ddRemoveTable2_png_bmp() +{ + static wxBitmap *bmp_ddRemoveTable2_png; + if (!bmp_ddRemoveTable2_png || !bmp_ddRemoveTable2_png->IsOk()) + bmp_ddRemoveTable2_png = new wxBitmap(*ddRemoveTable2_png_img); + return bmp_ddRemoveTable2_png; +} +#define ddRemoveTable2_png_bmp ddRemoveTable2_png_bmp() + +static wxIcon *ddRemoveTable2_png_ico() +{ + static wxIcon *ico_ddRemoveTable2_png; + if (!ico_ddRemoveTable2_png || !ico_ddRemoveTable2_png->IsOk()) + { + ico_ddRemoveTable2_png = new wxIcon(); + ico_ddRemoveTable2_png->CopyFromBitmap(*ddRemoveTable2_png_bmp); + } + return ico_ddRemoveTable2_png; +} +#define ddRemoveTable2_png_ico ddRemoveTable2_png_ico() + +#endif // DDREMOVETABLE2_PNG_H diff --git a/include/images/ddUp.png b/include/images/ddUp.png new file mode 100644 index 0000000000000000000000000000000000000000..7ae6e4408bb3b84da6f4fc799d5f00c1da4266f1 GIT binary patch literal 278 zcmeAS@N?(olHy`uVBq!ia0vp^oIuRR!3HD+k8e2&q!^2X+?^QKos)S9l1cJ*cVYMs zf(!O8p9~b?EbxddW?FS+Rfj_Zoh*-((@Ysp<22GeeP`J_#28vxJ#9Ik}~*thc|LBJgBl zazs&ZQzdvvA=f~H+#;G%V9fKUEC*GWSl&3AJj;AMZbL;=< zJNyzWzI@X-yuW_GIsOk()) + { + wxMemoryInputStream img_ddUp_pngIS(ddUp_png_data, sizeof(ddUp_png_data)); + img_ddUp_png->LoadFile(img_ddUp_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddUp_png; +} +#define ddUp_png_img ddUp_png_img() + +static wxBitmap *ddUp_png_bmp() +{ + static wxBitmap *bmp_ddUp_png; + if (!bmp_ddUp_png || !bmp_ddUp_png->IsOk()) + bmp_ddUp_png = new wxBitmap(*ddUp_png_img); + return bmp_ddUp_png; +} +#define ddUp_png_bmp ddUp_png_bmp() + +static wxIcon *ddUp_png_ico() +{ + static wxIcon *ico_ddUp_png; + if (!ico_ddUp_png || !ico_ddUp_png->IsOk()) + { + ico_ddUp_png = new wxIcon(); + ico_ddUp_png->CopyFromBitmap(*ddUp_png_bmp); + } + return ico_ddUp_png; +} +#define ddUp_png_ico ddUp_png_ico() + +#endif // DDUP_PNG_H diff --git a/include/images/ddcancel.png b/include/images/ddcancel.png new file mode 100644 index 0000000000000000000000000000000000000000..2aa07fc4ef75cfcbb6e27940f9dd511304312dd4 GIT binary patch literal 485 zcmVPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2ipc2 z4I~iq`^jhk00Cu5L_t(I%iWSaOG0rJ#((MB2XG1`Y3PO!CFBylH5a@QF+kq(c`-l=-iQDk2ZCaNyd;xjkeOkC0kWLSLBEgm`&{nt z^PbA$u9R6yByf~MltugWgq2UPYZy@XMraj_h;1X5g+G(QT`8l*<2a^5l%jolf=Abx zcmcrqPF9@5GX8WL$Fh*mtzs$KwHh8>XTDUL`7y|^ES_Uq^0cubkKypt09~Vlvs6}A z?`vqW7@|zXG;vJDLMX&Tsl+J6HM-edDWh#}ejD5M`T(R9K1~~gjJ2Requ*)YG#k8b zXP7-Yz_+L&wuRU>ciryf7J7joSJf(FDsGw$dVwH@Zw_;9o!jdx#2T1~TNu-{kNedp b{)s*S9n9Ho4xelP00000NkvXXu0mjfu~O7~ literal 0 HcmV?d00001 diff --git a/include/images/ddcancel.pngc b/include/images/ddcancel.pngc new file mode 100644 index 0000000..732f0c4 --- /dev/null +++ b/include/images/ddcancel.pngc @@ -0,0 +1,105 @@ +#ifndef DDCANCEL_PNG_H +#define DDCANCEL_PNG_H + +static const unsigned char ddcancel_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff, +0x61, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x24, 0x10, 0xf2, 0xfb, 0xc9, 0x68, +0x00, 0x00, 0x01, 0x65, 0x49, 0x44, 0x41, 0x54, +0x38, 0xcb, 0xdd, 0x92, 0x3d, 0x4b, 0x42, 0x71, +0x14, 0xc6, 0x7f, 0xe9, 0xda, 0x07, 0x70, 0x0a, +0x24, 0x69, 0xe8, 0x86, 0x10, 0x28, 0x08, 0xcd, +0x29, 0x14, 0x0d, 0x66, 0xea, 0x10, 0x48, 0x8a, +0x11, 0xf7, 0x0b, 0xe8, 0xea, 0xec, 0xd8, 0xe2, +0x22, 0x11, 0x42, 0xd0, 0xe6, 0x58, 0xa2, 0x2e, +0xc1, 0xa5, 0xa1, 0xc1, 0x96, 0xb2, 0x21, 0x4b, +0x70, 0x69, 0xea, 0x05, 0x22, 0xee, 0xff, 0x5e, +0xbb, 0xa7, 0xc1, 0x0a, 0xf1, 0x25, 0xda, 0x82, +0x9e, 0xf1, 0xc0, 0xf3, 0x3b, 0x87, 0xe7, 0x39, +0xf0, 0xff, 0xd4, 0xca, 0xee, 0x89, 0x01, 0x72, +0x91, 0xd9, 0x95, 0xe1, 0x79, 0x47, 0xd7, 0xc5, +0x00, 0xe9, 0xe8, 0xba, 0x4c, 0x35, 0x17, 0xbc, +0x11, 0x31, 0x40, 0xde, 0xf2, 0x79, 0x31, 0x40, +0x0a, 0xde, 0x88, 0x00, 0x1c, 0x07, 0x82, 0x62, +0x80, 0xbc, 0x24, 0x93, 0x63, 0x90, 0x99, 0x61, +0x80, 0x01, 0xb2, 0x9c, 0xcb, 0x41, 0xbf, 0x8f, +0xf4, 0xfb, 0x5c, 0xee, 0xef, 0xf3, 0x9e, 0xca, +0xe2, 0xae, 0x94, 0x59, 0x4a, 0x24, 0x70, 0x94, +0x42, 0x94, 0x45, 0xfb, 0xf4, 0x84, 0x95, 0x4f, +0xaf, 0x6b, 0x18, 0x50, 0xf7, 0x46, 0x68, 0x15, +0x8b, 0x88, 0x6d, 0x23, 0x96, 0x85, 0x3f, 0x93, +0xc1, 0x5d, 0x29, 0xa3, 0xc5, 0xe3, 0x38, 0xa6, +0x42, 0x94, 0xa2, 0x7d, 0x7a, 0x82, 0x47, 0xd7, +0x99, 0x78, 0x01, 0xc0, 0xf9, 0x4e, 0x56, 0x9c, +0xc3, 0x32, 0xfe, 0x74, 0x1a, 0xc7, 0xb2, 0x90, +0xcf, 0xad, 0x62, 0x29, 0xda, 0xb5, 0x1a, 0x1e, +0x5d, 0x67, 0xbe, 0x54, 0x9a, 0xf9, 0x31, 0xc8, +0xaf, 0x2c, 0x9e, 0x63, 0x5b, 0xf2, 0xb4, 0xb1, +0x21, 0x8f, 0xe1, 0xf0, 0xd4, 0x00, 0x5d, 0xa3, +0x83, 0xb3, 0x54, 0x56, 0x56, 0xef, 0x6b, 0x68, +0xb1, 0x18, 0xa2, 0x4c, 0xc4, 0x34, 0x71, 0x4c, +0xc5, 0x42, 0x28, 0xc4, 0x43, 0xa9, 0xc4, 0x28, +0xc4, 0x35, 0xba, 0xd9, 0x5d, 0x29, 0xa3, 0x6d, +0x6e, 0x7e, 0x1b, 0xdb, 0xf5, 0xfa, 0x00, 0xa4, +0x14, 0x3e, 0x4d, 0x1b, 0x83, 0x8c, 0xb5, 0xa0, +0x45, 0xa3, 0xdf, 0x69, 0xdf, 0x34, 0x1b, 0xbc, +0x6e, 0x67, 0x98, 0x3d, 0x3a, 0xc0, 0xb7, 0xa8, +0x21, 0xb6, 0x85, 0xd8, 0x36, 0x77, 0xdd, 0xee, +0xe4, 0x16, 0x7a, 0x81, 0x20, 0x57, 0xd5, 0x2a, +0x62, 0x2a, 0x6e, 0x9a, 0x0d, 0x7a, 0x81, 0x20, +0x86, 0x6f, 0x0e, 0x73, 0x6d, 0x9d, 0xdb, 0xeb, +0x2b, 0xc4, 0x1a, 0x98, 0x87, 0x5b, 0x18, 0xd3, +0xb4, 0x8f, 0xfb, 0xd5, 0x27, 0xfe, 0x89, 0x3e, +0x00, 0x1d, 0xcc, 0xd9, 0x6e, 0x0e, 0x9f, 0x6b, +0xff, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddcancel_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddcancel_png = new wxImage(); + if (!img_ddcancel_png || !img_ddcancel_png->IsOk()) + { + wxMemoryInputStream img_ddcancel_pngIS(ddcancel_png_data, sizeof(ddcancel_png_data)); + img_ddcancel_png->LoadFile(img_ddcancel_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddcancel_png; +} +#define ddcancel_png_img ddcancel_png_img() + +static wxBitmap *ddcancel_png_bmp() +{ + static wxBitmap *bmp_ddcancel_png; + if (!bmp_ddcancel_png || !bmp_ddcancel_png->IsOk()) + bmp_ddcancel_png = new wxBitmap(*ddcancel_png_img); + return bmp_ddcancel_png; +} +#define ddcancel_png_bmp ddcancel_png_bmp() + +static wxIcon *ddcancel_png_ico() +{ + static wxIcon *ico_ddcancel_png; + if (!ico_ddcancel_png || !ico_ddcancel_png->IsOk()) + { + ico_ddcancel_png = new wxIcon(); + ico_ddcancel_png->CopyFromBitmap(*ddcancel_png_bmp); + } + return ico_ddcancel_png; +} +#define ddcancel_png_ico ddcancel_png_ico() + +#endif // DDCANCEL_PNG_H diff --git a/include/images/ddforeignkey.png b/include/images/ddforeignkey.png new file mode 100644 index 0000000000000000000000000000000000000000..40b70a181e9f3f03bcea5dc02656ae27bbfaf2e0 GIT binary patch literal 329 zcmeAS@N?(olHy`uVBq!ia0vp^96-#)!3HEdkIOdzDaPU;cPEB*=VV?2Ic!PZ?k)`f zL2$v|<&%LToCO|{#S9GG!XV7ZFl&wkP>{XE)7O>#Hk%}`vQY3AyJn!!NlzEY5Q)pV zeH%O593))sFPGNfn5NLQ@TXZqMuPRUMKfh3ByKgVlzx$vAi8P6!MK9&&GvUvK3DK4 z|4E&tHvhRL!}H3Z>suL4*qpy-=^iUU{a5ZEfcoiXU?kQjQ?fPR~IR^<(i4FGK2j)=b$%d T)voISJ;mVZ>gTe~DWM4fiXeJO literal 0 HcmV?d00001 diff --git a/include/images/ddforeignkey.pngc b/include/images/ddforeignkey.pngc new file mode 100644 index 0000000..0b5c086 --- /dev/null +++ b/include/images/ddforeignkey.pngc @@ -0,0 +1,86 @@ +#ifndef DDFOREIGNKEY_PNG_H +#define DDFOREIGNKEY_PNG_H + +static const unsigned char ddforeignkey_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, +0x08, 0x06, 0x00, 0x00, 0x00, 0x89, 0xc7, 0x1f, +0x80, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x23, 0x12, 0x53, 0xb4, 0x3e, 0x83, +0x00, 0x00, 0x00, 0xc9, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x6d, 0x8e, 0xb1, 0x89, 0x86, 0x40, +0x18, 0x44, 0xdf, 0xa7, 0x1b, 0x28, 0x08, 0x96, +0x20, 0x82, 0xa1, 0xf9, 0x36, 0x60, 0x68, 0x60, +0x3b, 0x96, 0xa2, 0x99, 0x1d, 0x18, 0x18, 0xda, +0x80, 0xa9, 0x1b, 0xe8, 0x62, 0x60, 0x15, 0xb2, +0xa0, 0xc1, 0x5e, 0x70, 0xf7, 0x83, 0x3f, 0xdc, +0x64, 0xf3, 0x78, 0x0c, 0x23, 0xfc, 0x65, 0x9a, +0x26, 0x9f, 0xe7, 0x39, 0x00, 0xe7, 0x79, 0x52, +0xd7, 0xb5, 0x00, 0xc8, 0x3c, 0xcf, 0xde, 0x39, +0x47, 0x59, 0x96, 0x00, 0x88, 0x08, 0x22, 0x82, +0x31, 0x86, 0x28, 0x8a, 0x08, 0x8c, 0x31, 0x64, +0x59, 0xc6, 0x7d, 0xdf, 0xf4, 0x7d, 0x4f, 0xd7, +0x75, 0x3c, 0xcf, 0x43, 0x9e, 0xe7, 0x18, 0x63, +0x7e, 0x17, 0xae, 0xeb, 0xa2, 0x28, 0x0a, 0x9c, +0x73, 0x04, 0x41, 0x40, 0x92, 0x24, 0x58, 0x6b, +0x89, 0xe3, 0x98, 0xa0, 0xaa, 0x2a, 0x31, 0xc6, +0x70, 0x1c, 0x07, 0x4a, 0x29, 0xc2, 0x30, 0x64, +0xdb, 0x36, 0xd6, 0x75, 0xa5, 0xaa, 0x2a, 0xf9, +0x7c, 0xa4, 0x6d, 0x5b, 0x6f, 0xad, 0xf5, 0xfb, +0xbe, 0xfb, 0xb6, 0x6d, 0xfd, 0x87, 0x2b, 0x5e, +0x79, 0x9e, 0x07, 0xef, 0xfd, 0x1b, 0x11, 0xbc, +0x8b, 0x52, 0x0a, 0x11, 0xf9, 0x5f, 0xd0, 0x5a, +0x33, 0x0c, 0x03, 0x69, 0x9a, 0x7e, 0x09, 0x5f, +0xfa, 0x38, 0x8e, 0x7e, 0x59, 0x16, 0xb4, 0xd6, +0x34, 0x4d, 0x23, 0x00, 0x3f, 0xee, 0x43, 0x52, +0xec, 0xcd, 0x26, 0xd7, 0x2e, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddforeignkey_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddforeignkey_png = new wxImage(); + if (!img_ddforeignkey_png || !img_ddforeignkey_png->IsOk()) + { + wxMemoryInputStream img_ddforeignkey_pngIS(ddforeignkey_png_data, sizeof(ddforeignkey_png_data)); + img_ddforeignkey_png->LoadFile(img_ddforeignkey_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddforeignkey_png; +} +#define ddforeignkey_png_img ddforeignkey_png_img() + +static wxBitmap *ddforeignkey_png_bmp() +{ + static wxBitmap *bmp_ddforeignkey_png; + if (!bmp_ddforeignkey_png || !bmp_ddforeignkey_png->IsOk()) + bmp_ddforeignkey_png = new wxBitmap(*ddforeignkey_png_img); + return bmp_ddforeignkey_png; +} +#define ddforeignkey_png_bmp ddforeignkey_png_bmp() + +static wxIcon *ddforeignkey_png_ico() +{ + static wxIcon *ico_ddforeignkey_png; + if (!ico_ddforeignkey_png || !ico_ddforeignkey_png->IsOk()) + { + ico_ddforeignkey_png = new wxIcon(); + ico_ddforeignkey_png->CopyFromBitmap(*ddforeignkey_png_bmp); + } + return ico_ddforeignkey_png; +} +#define ddforeignkey_png_ico ddforeignkey_png_ico() + +#endif // DDFOREIGNKEY_PNG_H diff --git a/include/images/ddforeignkeyfromuk.png b/include/images/ddforeignkeyfromuk.png new file mode 100644 index 0000000000000000000000000000000000000000..c32918ac6d802fb79bad79e8bc5c15a7ddbf97ad GIT binary patch literal 355 zcmeAS@N?(olHy`uVBq!ia0vp^96-#)!3HEdkIOdzDaPU;cPEB*=VV?2Ic!PZ?k)`f zL2$v|<&%LToCO|{#S9GG!XV7ZFl&wkP>{XE)7O>#Hk%}`vOf2nqDerZ$DS^ZArhBM z`}TVsE)Z$mKYL3nir-Dx zAFc?xlx1l$`_S3ilc`Y`-j^=@H&Nr9>0aYmDQ=4`uHVYvaOih?(%N-V`9`wV0JD^4v=1Y~8yW#&vf>C(p_82L&O6r>mdKI;Vst0GbSv=Kufz literal 0 HcmV?d00001 diff --git a/include/images/ddforeignkeyfromuk.pngc b/include/images/ddforeignkeyfromuk.pngc new file mode 100644 index 0000000..8270047 --- /dev/null +++ b/include/images/ddforeignkeyfromuk.pngc @@ -0,0 +1,89 @@ +#ifndef DDFOREIGNKEYFROMUK_PNG_H +#define DDFOREIGNKEYFROMUK_PNG_H + +static const unsigned char ddforeignkeyfromuk_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, +0x08, 0x06, 0x00, 0x00, 0x00, 0x89, 0xc7, 0x1f, +0x80, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x23, 0x2f, 0x0b, 0xdc, 0x72, 0x92, +0x00, 0x00, 0x00, 0xe3, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x75, 0x8e, 0xbf, 0x4a, 0xc3, 0x70, +0x14, 0x85, 0xbf, 0x9b, 0xb4, 0x85, 0x04, 0x4a, +0x45, 0x28, 0xf8, 0x00, 0x42, 0x20, 0x83, 0x8b, +0x83, 0xa3, 0x93, 0x2f, 0xd0, 0x6c, 0x75, 0x8b, +0xcf, 0x21, 0xce, 0x75, 0x75, 0xe9, 0xe2, 0xd0, +0x41, 0x47, 0x1f, 0x43, 0x31, 0x44, 0x63, 0x85, +0x4a, 0x9c, 0x8b, 0x54, 0x70, 0xfc, 0x25, 0x6d, +0xfd, 0xf3, 0xf3, 0x3a, 0xc4, 0x48, 0x15, 0xfc, +0xa6, 0xc3, 0xe1, 0x9c, 0x73, 0xaf, 0xf0, 0xcd, +0xe9, 0xd9, 0xb3, 0x86, 0x81, 0x0f, 0xc0, 0xc3, +0xe3, 0x9c, 0x83, 0xfd, 0x0d, 0x01, 0x90, 0xf3, +0x8b, 0x17, 0x5d, 0x2c, 0x2c, 0x3b, 0xdb, 0x6d, +0x00, 0x1c, 0xa9, 0x0a, 0x57, 0xa9, 0xc1, 0xf3, +0x5c, 0x9c, 0x24, 0x2b, 0x08, 0x36, 0x3d, 0x96, +0xcb, 0x4f, 0x8e, 0x8e, 0xa7, 0x1c, 0x0e, 0xa6, +0xbc, 0xbe, 0x29, 0x61, 0xe0, 0x93, 0x64, 0x45, +0xb5, 0x60, 0x0a, 0xcb, 0x56, 0xe8, 0x53, 0xce, +0x2d, 0x22, 0x42, 0xa7, 0xed, 0x32, 0x9e, 0x94, +0xd5, 0x42, 0xbf, 0xd7, 0x95, 0xeb, 0x5b, 0xc3, +0x78, 0x52, 0xd2, 0x6a, 0x39, 0x34, 0x9b, 0xc2, +0xcd, 0x7d, 0xc9, 0x65, 0x5a, 0xd0, 0xef, 0x75, +0xa5, 0xfe, 0x91, 0x28, 0xce, 0x35, 0xbd, 0x33, +0x9a, 0x64, 0x46, 0xa3, 0x38, 0xd7, 0xda, 0x6f, +0xb0, 0xc2, 0xfb, 0x87, 0x62, 0xad, 0xae, 0x5a, +0xbf, 0x03, 0xae, 0x2b, 0xfc, 0xc5, 0xa9, 0xc5, +0xde, 0x6e, 0x87, 0xc1, 0xc9, 0x13, 0xeb, 0x6b, +0x0d, 0xfe, 0x65, 0x38, 0x9a, 0x69, 0x14, 0xe7, +0x3a, 0x1c, 0xcd, 0x7e, 0xee, 0x7c, 0x01, 0xae, +0xdc, 0x55, 0x93, 0x9c, 0x6c, 0x4f, 0x08, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddforeignkeyfromuk_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddforeignkeyfromuk_png = new wxImage(); + if (!img_ddforeignkeyfromuk_png || !img_ddforeignkeyfromuk_png->IsOk()) + { + wxMemoryInputStream img_ddforeignkeyfromuk_pngIS(ddforeignkeyfromuk_png_data, sizeof(ddforeignkeyfromuk_png_data)); + img_ddforeignkeyfromuk_png->LoadFile(img_ddforeignkeyfromuk_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddforeignkeyfromuk_png; +} +#define ddforeignkeyfromuk_png_img ddforeignkeyfromuk_png_img() + +static wxBitmap *ddforeignkeyfromuk_png_bmp() +{ + static wxBitmap *bmp_ddforeignkeyfromuk_png; + if (!bmp_ddforeignkeyfromuk_png || !bmp_ddforeignkeyfromuk_png->IsOk()) + bmp_ddforeignkeyfromuk_png = new wxBitmap(*ddforeignkeyfromuk_png_img); + return bmp_ddforeignkeyfromuk_png; +} +#define ddforeignkeyfromuk_png_bmp ddforeignkeyfromuk_png_bmp() + +static wxIcon *ddforeignkeyfromuk_png_ico() +{ + static wxIcon *ico_ddforeignkeyfromuk_png; + if (!ico_ddforeignkeyfromuk_png || !ico_ddforeignkeyfromuk_png->IsOk()) + { + ico_ddforeignkeyfromuk_png = new wxIcon(); + ico_ddforeignkeyfromuk_png->CopyFromBitmap(*ddforeignkeyfromuk_png_bmp); + } + return ico_ddforeignkeyfromuk_png; +} +#define ddforeignkeyfromuk_png_ico ddforeignkeyfromuk_png_ico() + +#endif // DDFOREIGNKEYFROMUK_PNG_H diff --git a/include/images/ddforeignkeyuniquekey.png b/include/images/ddforeignkeyuniquekey.png new file mode 100644 index 0000000000000000000000000000000000000000..b4232ad78fe414c76b084ebdac39de0b739c15fa GIT binary patch literal 361 zcmeAS@N?(olHy`uVBq!ia0vp^96-#)!3HEdkIOdzDaPU;cPEB*=VV?2Ic!PZ?k)`f zL2$v|<&%LToCO|{#S9GG!XV7ZFl&wkP>{XE)7O>#Hk%}`vdk79;TE9KOHUWa5Q)pV zeS5u*I7qmjH+P8$_{bdOLp!Hy*93-Meev6l;hg0p6+woTudCkd>Qmrg5D;`>$=02G zlI47qx6JV`wf=!33_50QI#wy`YaKGz7M?TYVa}Yj>4t>g`Sdf>v$tH+NbZTq&b&RX zd$;&Hz5WS-3mJ1J+rRk6qcNw)@w6 z@rpdor#3zL_;Tj;?e{0;=*Qe&f9z+`-^rUZPN_c)@X=j+{Rt>A89ZJ6T-G@yGywo8 C+m00g literal 0 HcmV?d00001 diff --git a/include/images/ddforeignkeyuniquekey.pngc b/include/images/ddforeignkeyuniquekey.pngc new file mode 100644 index 0000000..f2f0bbf --- /dev/null +++ b/include/images/ddforeignkeyuniquekey.pngc @@ -0,0 +1,90 @@ +#ifndef DDFOREIGNKEYUNIQUEKEY_PNG_H +#define DDFOREIGNKEYUNIQUEKEY_PNG_H + +static const unsigned char ddforeignkeyuniquekey_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, +0x08, 0x06, 0x00, 0x00, 0x00, 0x89, 0xc7, 0x1f, +0x80, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x23, 0x1c, 0xb4, 0x0c, 0x13, 0x84, +0x00, 0x00, 0x00, 0xe9, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x6d, 0x8e, 0xbd, 0x4a, 0xc4, 0x40, +0x18, 0x45, 0xcf, 0x37, 0x44, 0x58, 0x50, 0xf1, +0x01, 0x16, 0x16, 0x02, 0x16, 0x0a, 0x19, 0x2c, +0x53, 0xa6, 0xc8, 0x94, 0x29, 0x94, 0x08, 0x69, +0x7d, 0x02, 0x5f, 0xc0, 0x74, 0xe2, 0x0b, 0x58, +0x5a, 0x25, 0x85, 0xc5, 0xd6, 0x1b, 0xb0, 0x49, +0xb3, 0x9d, 0xa9, 0xa7, 0x70, 0x21, 0xc5, 0x54, +0x5b, 0xae, 0x60, 0x63, 0x24, 0x44, 0x63, 0xe3, +0xcf, 0x82, 0x9e, 0xee, 0xc2, 0xb9, 0x97, 0x2b, +0x7c, 0x51, 0x55, 0xd5, 0xe8, 0xfb, 0x3e, 0x00, +0xce, 0x39, 0x92, 0x24, 0x11, 0x00, 0xa9, 0xeb, +0x7a, 0xec, 0xba, 0x8e, 0x20, 0x08, 0x00, 0x10, +0x11, 0x44, 0x04, 0x6b, 0x2d, 0x93, 0xc9, 0x04, +0xcf, 0x5a, 0x4b, 0x1c, 0xc7, 0xf4, 0x7d, 0x4f, +0x51, 0x14, 0x00, 0x2c, 0x36, 0x86, 0x2c, 0x3a, +0x64, 0xaf, 0x7d, 0x40, 0x69, 0xad, 0x71, 0xce, +0x31, 0x0c, 0x03, 0x69, 0x9a, 0xb2, 0xd8, 0x18, +0x4e, 0xcf, 0x67, 0xcc, 0x97, 0x6b, 0xb4, 0xd6, +0x28, 0x63, 0x8c, 0x58, 0x6b, 0x69, 0xdb, 0x96, +0x8b, 0xbb, 0x17, 0xae, 0x2e, 0x8f, 0x90, 0x51, +0x00, 0x30, 0xc6, 0x88, 0x02, 0xc8, 0xf3, 0x5c, +0x9a, 0xa6, 0x21, 0x8b, 0xa6, 0xdc, 0xdc, 0xae, +0xe0, 0x5d, 0xbe, 0xbf, 0xa3, 0xd8, 0xe2, 0xec, +0x64, 0xe0, 0x60, 0x77, 0x07, 0xf9, 0x50, 0xff, +0x0b, 0x9e, 0xe7, 0x71, 0x3c, 0xdb, 0x47, 0xf5, +0xde, 0x5f, 0x21, 0x0c, 0x43, 0xca, 0xb2, 0xe4, +0xf1, 0xe9, 0x99, 0xd7, 0xb7, 0xdf, 0x92, 0x6c, +0x2f, 0x5c, 0xdf, 0xaf, 0xc6, 0xf9, 0x72, 0xfd, +0x93, 0xb3, 0x68, 0xca, 0x27, 0xe5, 0x50, 0x4c, +0x2d, 0xad, 0xd7, 0xe4, 0x52, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddforeignkeyuniquekey_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddforeignkeyuniquekey_png = new wxImage(); + if (!img_ddforeignkeyuniquekey_png || !img_ddforeignkeyuniquekey_png->IsOk()) + { + wxMemoryInputStream img_ddforeignkeyuniquekey_pngIS(ddforeignkeyuniquekey_png_data, sizeof(ddforeignkeyuniquekey_png_data)); + img_ddforeignkeyuniquekey_png->LoadFile(img_ddforeignkeyuniquekey_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddforeignkeyuniquekey_png; +} +#define ddforeignkeyuniquekey_png_img ddforeignkeyuniquekey_png_img() + +static wxBitmap *ddforeignkeyuniquekey_png_bmp() +{ + static wxBitmap *bmp_ddforeignkeyuniquekey_png; + if (!bmp_ddforeignkeyuniquekey_png || !bmp_ddforeignkeyuniquekey_png->IsOk()) + bmp_ddforeignkeyuniquekey_png = new wxBitmap(*ddforeignkeyuniquekey_png_img); + return bmp_ddforeignkeyuniquekey_png; +} +#define ddforeignkeyuniquekey_png_bmp ddforeignkeyuniquekey_png_bmp() + +static wxIcon *ddforeignkeyuniquekey_png_ico() +{ + static wxIcon *ico_ddforeignkeyuniquekey_png; + if (!ico_ddforeignkeyuniquekey_png || !ico_ddforeignkeyuniquekey_png->IsOk()) + { + ico_ddforeignkeyuniquekey_png = new wxIcon(); + ico_ddforeignkeyuniquekey_png->CopyFromBitmap(*ddforeignkeyuniquekey_png_bmp); + } + return ico_ddforeignkeyuniquekey_png; +} +#define ddforeignkeyuniquekey_png_ico ddforeignkeyuniquekey_png_ico() + +#endif // DDFOREIGNKEYUNIQUEKEY_PNG_H diff --git a/include/images/ddforeignkeyuniquekeyfromuk.png b/include/images/ddforeignkeyuniquekeyfromuk.png new file mode 100644 index 0000000000000000000000000000000000000000..0ea52f99c2071e45340f0149379688837887192d GIT binary patch literal 377 zcmeAS@N?(olHy`uVBq!ia0vp^96-#)!3HEdkIOdzDaPU;cPEB*=VV?2Ic!PZ?k)`f zL2$v|<&%LToCO|{#S9GG!XV7ZFl&wkP>{XE)7O>#Hk%}`vg&Kj**!p^pPnv`ArhB! z`__6NDUfNO|Ni{k)UK#7Hug=e#++S;E~OkyFyi>lZW3dt*_0$S`E6Hy6_G;%M2B~cBqN=Gvzs!DbW#RhyuP=!qziy7< z=9Vv4|F>P5khIFC>s0UlwxyZV-%eIL`?`8we7&>LjSb~fUQ|u_`{Kg(pA2>xJ{;=X SPo4(`0)wZkpUXO@geCx*sFx!E literal 0 HcmV?d00001 diff --git a/include/images/ddforeignkeyuniquekeyfromuk.pngc b/include/images/ddforeignkeyuniquekeyfromuk.pngc new file mode 100644 index 0000000..746c13d --- /dev/null +++ b/include/images/ddforeignkeyuniquekeyfromuk.pngc @@ -0,0 +1,92 @@ +#ifndef DDFOREIGNKEYUNIQUEKEYFROMUK_PNG_H +#define DDFOREIGNKEYUNIQUEKEYFROMUK_PNG_H + +static const unsigned char ddforeignkeyuniquekeyfromuk_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, +0x08, 0x06, 0x00, 0x00, 0x00, 0x89, 0xc7, 0x1f, +0x80, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x23, 0x25, 0xeb, 0x09, 0x9b, 0x8c, +0x00, 0x00, 0x00, 0xf9, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x6d, 0x8e, 0xad, 0x4b, 0xc4, 0x70, +0x1c, 0x87, 0x9f, 0xef, 0xcf, 0x9d, 0x65, 0x8a, +0x5a, 0x56, 0x06, 0x07, 0xb2, 0x85, 0x33, 0x09, +0x8a, 0xc2, 0xd2, 0x64, 0xc1, 0x60, 0x32, 0x08, +0xfb, 0x07, 0x34, 0x5c, 0x31, 0x29, 0x82, 0x62, +0x12, 0x93, 0xed, 0x8a, 0x7f, 0x81, 0xe1, 0x92, +0x26, 0xd3, 0x29, 0x2c, 0xed, 0x10, 0x3c, 0x30, +0x39, 0x61, 0x17, 0x0c, 0x0b, 0x77, 0xe0, 0xcb, +0x81, 0xa8, 0x4c, 0x77, 0x3f, 0x83, 0x6f, 0x07, +0xfa, 0xb4, 0x0f, 0x7c, 0xde, 0x84, 0x2f, 0x0e, +0xa2, 0x44, 0xcf, 0xda, 0x13, 0x00, 0x5c, 0x66, +0x0f, 0x6c, 0xfa, 0x15, 0x01, 0x90, 0xc3, 0x38, +0xd5, 0x4f, 0xf9, 0x3b, 0x81, 0x63, 0x01, 0xa0, +0x44, 0x00, 0x68, 0xa4, 0x1d, 0x46, 0x86, 0x0d, +0x8c, 0xf3, 0x76, 0x97, 0xd5, 0xb9, 0x49, 0x5e, +0xde, 0x0a, 0xb6, 0x8e, 0x63, 0x00, 0x7a, 0x89, +0x49, 0xe8, 0xdb, 0x5c, 0xe8, 0x2e, 0x2a, 0x70, +0x2c, 0x5a, 0xd9, 0x23, 0x79, 0xd1, 0x67, 0x63, +0x71, 0x86, 0x5e, 0x62, 0xb2, 0xbc, 0x52, 0xa6, +0x1e, 0x65, 0x04, 0x8e, 0x85, 0xaa, 0x7a, 0xae, +0x9c, 0xb5, 0x3b, 0xc4, 0xb7, 0x77, 0xec, 0xd6, +0x6e, 0xd8, 0x59, 0xaf, 0x20, 0xfa, 0x73, 0xa6, +0xea, 0xb9, 0xa2, 0x00, 0x1a, 0x6b, 0x0b, 0x72, +0x7a, 0x95, 0x12, 0xfa, 0x36, 0xfb, 0xb5, 0x04, +0x0a, 0xf9, 0xfe, 0x8e, 0x62, 0x00, 0x6f, 0x7e, +0x9c, 0x31, 0xb3, 0x84, 0xf4, 0xd5, 0xff, 0x86, +0xd2, 0x90, 0x62, 0xaa, 0x3c, 0x8a, 0xca, 0x8d, +0xbf, 0x86, 0xa5, 0x69, 0x97, 0xed, 0x93, 0x26, +0xcd, 0xeb, 0x7b, 0x9e, 0x5f, 0x7f, 0x43, 0x32, +0xd8, 0xb0, 0x77, 0x94, 0xe8, 0x7a, 0x94, 0xfd, +0xe8, 0xd0, 0xb7, 0xf9, 0x00, 0x3e, 0x68, 0x4c, +0x08, 0x27, 0xb7, 0xc9, 0xcf, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddforeignkeyuniquekeyfromuk_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddforeignkeyuniquekeyfromuk_png = new wxImage(); + if (!img_ddforeignkeyuniquekeyfromuk_png || !img_ddforeignkeyuniquekeyfromuk_png->IsOk()) + { + wxMemoryInputStream img_ddforeignkeyuniquekeyfromuk_pngIS(ddforeignkeyuniquekeyfromuk_png_data, sizeof(ddforeignkeyuniquekeyfromuk_png_data)); + img_ddforeignkeyuniquekeyfromuk_png->LoadFile(img_ddforeignkeyuniquekeyfromuk_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddforeignkeyuniquekeyfromuk_png; +} +#define ddforeignkeyuniquekeyfromuk_png_img ddforeignkeyuniquekeyfromuk_png_img() + +static wxBitmap *ddforeignkeyuniquekeyfromuk_png_bmp() +{ + static wxBitmap *bmp_ddforeignkeyuniquekeyfromuk_png; + if (!bmp_ddforeignkeyuniquekeyfromuk_png || !bmp_ddforeignkeyuniquekeyfromuk_png->IsOk()) + bmp_ddforeignkeyuniquekeyfromuk_png = new wxBitmap(*ddforeignkeyuniquekeyfromuk_png_img); + return bmp_ddforeignkeyuniquekeyfromuk_png; +} +#define ddforeignkeyuniquekeyfromuk_png_bmp ddforeignkeyuniquekeyfromuk_png_bmp() + +static wxIcon *ddforeignkeyuniquekeyfromuk_png_ico() +{ + static wxIcon *ico_ddforeignkeyuniquekeyfromuk_png; + if (!ico_ddforeignkeyuniquekeyfromuk_png || !ico_ddforeignkeyuniquekeyfromuk_png->IsOk()) + { + ico_ddforeignkeyuniquekeyfromuk_png = new wxIcon(); + ico_ddforeignkeyuniquekeyfromuk_png->CopyFromBitmap(*ddforeignkeyuniquekeyfromuk_png_bmp); + } + return ico_ddforeignkeyuniquekeyfromuk_png; +} +#define ddforeignkeyuniquekeyfromuk_png_ico ddforeignkeyuniquekeyfromuk_png_ico() + +#endif // DDFOREIGNKEYUNIQUEKEYFROMUK_PNG_H diff --git a/include/images/ddgendiagram.png b/include/images/ddgendiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..eae876ce318a7ccdbe3cec97ecb90aad8a5b2914 GIT binary patch literal 332 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPgg)4i07!LH3O~bAUo;JY5_^EKVmU zED$g-GB7as^Z);U`z{4#W#x@*1`j7Wm`_m=KXBw?jO!%sf69p|;SbFgqz4N*e~}Sv zo9FAfV{Z3R(E{dk`)?hYkQ;xr;NMlXHElp6T^5)jwfqPMXso7@hIhLwt#9>Lep!#RmQOfHzDGdDl8W U32yXI0{V-=)78&qol`;+0Jh6|rT_o{ literal 0 HcmV?d00001 diff --git a/include/images/ddgendiagram.pngc b/include/images/ddgendiagram.pngc new file mode 100644 index 0000000..51353f2 --- /dev/null +++ b/include/images/ddgendiagram.pngc @@ -0,0 +1,86 @@ +#ifndef DDGENDIAGRAM_PNG_H +#define DDGENDIAGRAM_PNG_H + +static const unsigned char ddgendiagram_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff, +0x61, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x08, +0x08, 0x03, 0x14, 0x11, 0x07, 0xb1, 0x6c, 0x9c, +0x00, 0x00, 0x00, 0xcc, 0x49, 0x44, 0x41, 0x54, +0x38, 0xcb, 0x63, 0x60, 0xa0, 0x10, 0x30, 0x32, +0x30, 0x30, 0x30, 0xfc, 0xff, 0xff, 0xff, 0x3f, +0x8a, 0x20, 0x23, 0x23, 0x23, 0xb1, 0x06, 0x30, +0xe1, 0x92, 0x40, 0x37, 0x94, 0x24, 0x17, 0xc0, +0xc4, 0xd1, 0x5c, 0x45, 0x92, 0x0b, 0xfe, 0x23, +0x61, 0x64, 0x57, 0xe1, 0x36, 0xa0, 0x67, 0x53, +0x12, 0x43, 0xf4, 0x1c, 0x11, 0x86, 0x9e, 0x4d, +0x49, 0xb8, 0x9d, 0x8b, 0xc5, 0x15, 0x70, 0x03, +0xce, 0xbf, 0xda, 0xc4, 0x90, 0x6d, 0x5f, 0xc5, +0x70, 0xfe, 0xd5, 0x26, 0xac, 0x86, 0xfc, 0xff, +0xff, 0x1f, 0x8e, 0x71, 0x7a, 0xe1, 0xe9, 0xbb, +0xb3, 0x0c, 0x51, 0x26, 0xb1, 0xd8, 0x0c, 0xf9, +0x8f, 0xcb, 0x5b, 0x4c, 0xa8, 0x4e, 0x64, 0x61, +0x78, 0xfe, 0xe1, 0x32, 0x43, 0x8c, 0x59, 0x2a, +0x4e, 0x97, 0xa0, 0xc7, 0x12, 0x0b, 0xb2, 0x20, +0x2b, 0x0b, 0x1f, 0x83, 0xbc, 0x88, 0x2a, 0xc3, +0x82, 0x13, 0x13, 0x18, 0x0c, 0xc5, 0xfc, 0x18, +0x4a, 0xfc, 0xe6, 0xe1, 0x0b, 0x0f, 0x46, 0xb8, +0x0b, 0x60, 0x1c, 0x39, 0x61, 0x6b, 0x64, 0xcd, +0x8c, 0xd8, 0xa2, 0x13, 0x66, 0x3b, 0x0c, 0xc0, +0x05, 0xbb, 0x37, 0x26, 0xfe, 0x8f, 0x9a, 0x2d, +0xfc, 0xbf, 0x7b, 0x63, 0xe2, 0x7f, 0xe4, 0x00, +0x83, 0x62, 0x9c, 0x80, 0x11, 0x5b, 0x68, 0xe3, +0x48, 0x17, 0xa4, 0x25, 0x65, 0x92, 0x32, 0x13, +0x21, 0x80, 0x2f, 0x5f, 0x50, 0xec, 0x02, 0x00, +0x6e, 0xd6, 0x89, 0xf2, 0x11, 0xb1, 0x48, 0x22, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddgendiagram_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddgendiagram_png = new wxImage(); + if (!img_ddgendiagram_png || !img_ddgendiagram_png->IsOk()) + { + wxMemoryInputStream img_ddgendiagram_pngIS(ddgendiagram_png_data, sizeof(ddgendiagram_png_data)); + img_ddgendiagram_png->LoadFile(img_ddgendiagram_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddgendiagram_png; +} +#define ddgendiagram_png_img ddgendiagram_png_img() + +static wxBitmap *ddgendiagram_png_bmp() +{ + static wxBitmap *bmp_ddgendiagram_png; + if (!bmp_ddgendiagram_png || !bmp_ddgendiagram_png->IsOk()) + bmp_ddgendiagram_png = new wxBitmap(*ddgendiagram_png_img); + return bmp_ddgendiagram_png; +} +#define ddgendiagram_png_bmp ddgendiagram_png_bmp() + +static wxIcon *ddgendiagram_png_ico() +{ + static wxIcon *ico_ddgendiagram_png; + if (!ico_ddgendiagram_png || !ico_ddgendiagram_png->IsOk()) + { + ico_ddgendiagram_png = new wxIcon(); + ico_ddgendiagram_png->CopyFromBitmap(*ddgendiagram_png_bmp); + } + return ico_ddgendiagram_png; +} +#define ddgendiagram_png_ico ddgendiagram_png_ico() + +#endif // DDGENDIAGRAM_PNG_H diff --git a/include/images/ddmodel-32.png b/include/images/ddmodel-32.png new file mode 100644 index 0000000000000000000000000000000000000000..869c56481cc658ba179d8f7636addc29e02caabd GIT binary patch literal 640 zcmV-`0)PF9P)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2ipc2 z4I(A-5~|Gr00IC>L_t(o!{wH-Zrd;vMeluPO|f%FoUheF;#z#k<){JZFZ3=>~`T7B6&;KmjQ4wVnL}zMKobUii&GC7>vQ%lsL>-w3{? z8tYAt>pydy=2&kE{LTub+rp~=X+D z#K)5kr33C-Zw8KnD;Q&7j6sqlm53xsptVL21bF*e>KhK7!!iH>Q502ycP9scIF2DA z2*c1d!)5K4y#h#LHk&mBkVF`URS8Ir364Gy4FSd&kVF(kn9t`R32QA@s})29+wHbD z;sBnM4|&oM5XW(~7LmOYEEbDLkL}8ny%N;ZEh1PhmwR`jZ@BWL67c!wA+iFv&Hlc4 zy~(Q$)@hELEFD??Zl0)JEsooFab}MrPawX@=E##K2VDHyH(Yq4#`?FDxsE(hEnXgW zt2%lESDq*zUVbRRg(u2~m)lA(lqbrEm+QloC(4JH>-XWf|3rMGBO2#rFCEc8c)5Nu zXKpATULFgq&JygrY>a`mwhCyi#dJD_*1GM>Sf^*(bj!eq-hkdq;Lsb;>m_vbGJObn ay5kPQPg?UM*TT>M0000IsOk()) + { + wxMemoryInputStream img_ddmodel_32_pngIS(ddmodel_32_png_data, sizeof(ddmodel_32_png_data)); + img_ddmodel_32_png->LoadFile(img_ddmodel_32_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddmodel_32_png; +} +#define ddmodel_32_png_img ddmodel_32_png_img() + +static wxBitmap *ddmodel_32_png_bmp() +{ + static wxBitmap *bmp_ddmodel_32_png; + if (!bmp_ddmodel_32_png || !bmp_ddmodel_32_png->IsOk()) + bmp_ddmodel_32_png = new wxBitmap(*ddmodel_32_png_img); + return bmp_ddmodel_32_png; +} +#define ddmodel_32_png_bmp ddmodel_32_png_bmp() + +static wxIcon *ddmodel_32_png_ico() +{ + static wxIcon *ico_ddmodel_32_png; + if (!ico_ddmodel_32_png || !ico_ddmodel_32_png->IsOk()) + { + ico_ddmodel_32_png = new wxIcon(); + ico_ddmodel_32_png->CopyFromBitmap(*ddmodel_32_png_bmp); + } + return ico_ddmodel_32_png; +} +#define ddmodel_32_png_ico ddmodel_32_png_ico() + +#endif // DDMODEL_32_PNG_H diff --git a/include/images/ddnewdiagram.png b/include/images/ddnewdiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..fde994754b7c185d5946b62df653e90a1dc47da5 GIT binary patch literal 355 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPgg)4h|-3q29Fo8lcc)PZ!4!i_=#p zZOmeF6lmMeZPyznR-_bcUcdgu#)P!6TN18;k$+d7-D31Pj4d_V#BGJqt1G6udMaFrTFG^&;0M2&$n|PcfR&V@bXou_qGg5O&tsm_NMQPh|)b&x~XHqsulr@ zUg54q4PRDEHm$m+*DjFvygD?`prc*JK8<0{G0s(9-;0?Y*318wn^tZ4{Eg-PTN&ST u&skRgdFB@z@vM7k?9A%FJB%*XUtIsOk()) + { + wxMemoryInputStream img_ddnewdiagram_pngIS(ddnewdiagram_png_data, sizeof(ddnewdiagram_png_data)); + img_ddnewdiagram_png->LoadFile(img_ddnewdiagram_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddnewdiagram_png; +} +#define ddnewdiagram_png_img ddnewdiagram_png_img() + +static wxBitmap *ddnewdiagram_png_bmp() +{ + static wxBitmap *bmp_ddnewdiagram_png; + if (!bmp_ddnewdiagram_png || !bmp_ddnewdiagram_png->IsOk()) + bmp_ddnewdiagram_png = new wxBitmap(*ddnewdiagram_png_img); + return bmp_ddnewdiagram_png; +} +#define ddnewdiagram_png_bmp ddnewdiagram_png_bmp() + +static wxIcon *ddnewdiagram_png_ico() +{ + static wxIcon *ico_ddnewdiagram_png; + if (!ico_ddnewdiagram_png || !ico_ddnewdiagram_png->IsOk()) + { + ico_ddnewdiagram_png = new wxIcon(); + ico_ddnewdiagram_png->CopyFromBitmap(*ddnewdiagram_png_bmp); + } + return ico_ddnewdiagram_png; +} +#define ddnewdiagram_png_ico ddnewdiagram_png_ico() + +#endif // DDNEWDIAGRAM_PNG_H diff --git a/include/images/ddnotnull.png b/include/images/ddnotnull.png new file mode 100644 index 0000000000000000000000000000000000000000..b58fccf392059a0e2200d93713d300b5ec40c8aa GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^96-#)!3HEdkIOdzDaPU;cPEB*=VV?2Ic!PZ?k)`f zL2$v|<&%LToCO|{#S9GG!XV7ZFl&wkP>{XE)7O>#Hk%}`l9WqH`v;(qfv1aOh{WaO z1P9jt3nlnwTwvXh;gI;pJ=xeGDVUeF$3VM-$zrX8`7e7hySn@!J_d%RLSN3D{x1&H O%i!ti=d#Wzp$Py$J}+nh literal 0 HcmV?d00001 diff --git a/include/images/ddnotnull.pngc b/include/images/ddnotnull.pngc new file mode 100644 index 0000000..e1ad57a --- /dev/null +++ b/include/images/ddnotnull.pngc @@ -0,0 +1,66 @@ +#ifndef DDNOTNULL_PNG_H +#define DDNOTNULL_PNG_H + +static const unsigned char ddnotnull_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, +0x08, 0x06, 0x00, 0x00, 0x00, 0x89, 0xc7, 0x1f, +0x80, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x22, 0x1a, 0x44, 0x74, 0x87, 0xf0, +0x00, 0x00, 0x00, 0x30, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0x60, 0x40, 0x05, 0xff, 0xa1, +0x18, 0x0e, 0x98, 0xd0, 0x05, 0xb0, 0x68, 0x40, +0x61, 0xfc, 0x47, 0x63, 0x33, 0x30, 0x62, 0x53, +0x0d, 0x05, 0x8c, 0x30, 0x2b, 0x88, 0x02, 0x38, +0xad, 0x40, 0x37, 0xfa, 0x3f, 0x16, 0x3e, 0x7e, +0x6f, 0x52, 0x0e, 0x00, 0x00, 0xa5, 0x12, 0xf4, +0xcc, 0xcb, 0xff, 0x17, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddnotnull_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddnotnull_png = new wxImage(); + if (!img_ddnotnull_png || !img_ddnotnull_png->IsOk()) + { + wxMemoryInputStream img_ddnotnull_pngIS(ddnotnull_png_data, sizeof(ddnotnull_png_data)); + img_ddnotnull_png->LoadFile(img_ddnotnull_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddnotnull_png; +} +#define ddnotnull_png_img ddnotnull_png_img() + +static wxBitmap *ddnotnull_png_bmp() +{ + static wxBitmap *bmp_ddnotnull_png; + if (!bmp_ddnotnull_png || !bmp_ddnotnull_png->IsOk()) + bmp_ddnotnull_png = new wxBitmap(*ddnotnull_png_img); + return bmp_ddnotnull_png; +} +#define ddnotnull_png_bmp ddnotnull_png_bmp() + +static wxIcon *ddnotnull_png_ico() +{ + static wxIcon *ico_ddnotnull_png; + if (!ico_ddnotnull_png || !ico_ddnotnull_png->IsOk()) + { + ico_ddnotnull_png = new wxIcon(); + ico_ddnotnull_png->CopyFromBitmap(*ddnotnull_png_bmp); + } + return ico_ddnotnull_png; +} +#define ddnotnull_png_ico ddnotnull_png_ico() + +#endif // DDNOTNULL_PNG_H diff --git a/include/images/ddnull.png b/include/images/ddnull.png new file mode 100644 index 0000000000000000000000000000000000000000..a2c030dc233217f1ca0faf70e1b44cfd0b925c81 GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^96-#)!3HEdkIOdzDaPU;cPEB*=VV?2Ic!PZ?k)`f zL2$v|<&%LToCO|{#S9GG!XV7ZFl&wkP>{XE)7O>#Hk%}`lE9LMdGCNinw~C>ArhC9 z6BHOECf@k}@r2IsOk()) + { + wxMemoryInputStream img_ddnull_pngIS(ddnull_png_data, sizeof(ddnull_png_data)); + img_ddnull_png->LoadFile(img_ddnull_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddnull_png; +} +#define ddnull_png_img ddnull_png_img() + +static wxBitmap *ddnull_png_bmp() +{ + static wxBitmap *bmp_ddnull_png; + if (!bmp_ddnull_png || !bmp_ddnull_png->IsOk()) + bmp_ddnull_png = new wxBitmap(*ddnull_png_img); + return bmp_ddnull_png; +} +#define ddnull_png_bmp ddnull_png_bmp() + +static wxIcon *ddnull_png_ico() +{ + static wxIcon *ico_ddnull_png; + if (!ico_ddnull_png || !ico_ddnull_png->IsOk()) + { + ico_ddnull_png = new wxIcon(); + ico_ddnull_png->CopyFromBitmap(*ddnull_png_bmp); + } + return ico_ddnull_png; +} +#define ddnull_png_ico ddnull_png_ico() + +#endif // DDNULL_PNG_H diff --git a/include/images/ddprimaryforeignkey.png b/include/images/ddprimaryforeignkey.png new file mode 100644 index 0000000000000000000000000000000000000000..6ec5a7eb89ca7a23613734387d746b251c6ed106 GIT binary patch literal 367 zcmeAS@N?(olHy`uVBq!ia0vp^96-#)!3HEdkIOdzDaPU;cPEB*=VV?2Ic!PZ?k)`f zL2$v|<&%LToCO|{#S9GG!XV7ZFl&wkP>{XE)7O>#Hk%}`qUBk;rH(+M_nt0}ArhBM z&usK=31DdW_+Im&&58KIH}M2R_us zKdJ1?oTYO_Qoh^$SE%dXqT_AWM;J0@v7O#@VpGr0&#KR69scvO>232wgMIr;VvooF zWl%iw|G;OPoZD;(#owo}m;Q@xOI-2T;u=G$)ioeun7`vxoCB}b(e*&DGkCiCxvXIsOk()) + { + wxMemoryInputStream img_ddprimaryforeignkey_pngIS(ddprimaryforeignkey_png_data, sizeof(ddprimaryforeignkey_png_data)); + img_ddprimaryforeignkey_png->LoadFile(img_ddprimaryforeignkey_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddprimaryforeignkey_png; +} +#define ddprimaryforeignkey_png_img ddprimaryforeignkey_png_img() + +static wxBitmap *ddprimaryforeignkey_png_bmp() +{ + static wxBitmap *bmp_ddprimaryforeignkey_png; + if (!bmp_ddprimaryforeignkey_png || !bmp_ddprimaryforeignkey_png->IsOk()) + bmp_ddprimaryforeignkey_png = new wxBitmap(*ddprimaryforeignkey_png_img); + return bmp_ddprimaryforeignkey_png; +} +#define ddprimaryforeignkey_png_bmp ddprimaryforeignkey_png_bmp() + +static wxIcon *ddprimaryforeignkey_png_ico() +{ + static wxIcon *ico_ddprimaryforeignkey_png; + if (!ico_ddprimaryforeignkey_png || !ico_ddprimaryforeignkey_png->IsOk()) + { + ico_ddprimaryforeignkey_png = new wxIcon(); + ico_ddprimaryforeignkey_png->CopyFromBitmap(*ddprimaryforeignkey_png_bmp); + } + return ico_ddprimaryforeignkey_png; +} +#define ddprimaryforeignkey_png_ico ddprimaryforeignkey_png_ico() + +#endif // DDPRIMARYFOREIGNKEY_PNG_H diff --git a/include/images/ddprimaryforeignkeyfromuk.png b/include/images/ddprimaryforeignkeyfromuk.png new file mode 100644 index 0000000000000000000000000000000000000000..18c79b81c4c442e1a545d9acb4068f3b41e5fca5 GIT binary patch literal 386 zcmeAS@N?(olHy`uVBq!ia0vp^96-#)!3HEdkIOdzDaPU;cPEB*=VV?2Ic!PZ?k)`f zL2$v|<&%LToCO|{#S9GG!XV7ZFl&wkP>{XE)7O>#Hk%}`61#fQYfYdjOr9=|ArhBM z&p2u~7s?#?`2KUf)X`I$nQd<-W}Q4Jpm&Np!kXv3LnWtIFyAfd2d55tuH3mmvs&*| zl&y8fTZQS%)oMv){UUcyLpO@SY`|eDd^xAvh9iiP5CLOo-esidWAtO4} zf0v_&nq=~e#CC%(hVJ4!%FhKv-EL}iR;kVMUvz&{Ov1a z)sY3YTaTakGHcns{d@M-e+ajC2*33|p-`()@-1URMb6AyFMs9FytQva@8>oKi!whM cYjuYC5BcIMenxP#00W4@)78&qol`;+02Mo$DF6Tf literal 0 HcmV?d00001 diff --git a/include/images/ddprimaryforeignkeyfromuk.pngc b/include/images/ddprimaryforeignkeyfromuk.pngc new file mode 100644 index 0000000..6ff5252 --- /dev/null +++ b/include/images/ddprimaryforeignkeyfromuk.pngc @@ -0,0 +1,93 @@ +#ifndef DDPRIMARYFOREIGNKEYFROMUK_PNG_H +#define DDPRIMARYFOREIGNKEYFROMUK_PNG_H + +static const unsigned char ddprimaryforeignkeyfromuk_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, +0x08, 0x06, 0x00, 0x00, 0x00, 0x89, 0xc7, 0x1f, +0x80, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x22, 0x07, 0x27, 0x72, 0xeb, 0x29, +0x00, 0x00, 0x01, 0x02, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x75, 0xcc, 0x41, 0x2b, 0x83, 0x71, +0x1c, 0xc0, 0xf1, 0xef, 0xf3, 0x7f, 0x1a, 0xc5, +0xca, 0xb3, 0x03, 0x3d, 0xd9, 0x61, 0x6a, 0xc9, +0xc1, 0x10, 0x2e, 0xca, 0x0b, 0x58, 0x3b, 0x0c, +0xef, 0x40, 0x79, 0x09, 0x4a, 0x53, 0x0e, 0xda, +0x1b, 0xe0, 0xca, 0xc1, 0x49, 0xa9, 0xb9, 0xa0, +0x29, 0x7b, 0x2e, 0xca, 0x5a, 0x3d, 0x3b, 0x68, +0xed, 0x20, 0x97, 0xa7, 0x27, 0xdb, 0xda, 0x43, +0xac, 0x3c, 0x34, 0x45, 0x4f, 0x1e, 0x3f, 0x07, +0x72, 0xc1, 0xf7, 0xfc, 0xe9, 0x0b, 0x40, 0xbe, +0xdc, 0x92, 0x92, 0xeb, 0x4b, 0xbe, 0xdc, 0x12, +0xbb, 0x90, 0x92, 0xc7, 0x3b, 0x4b, 0xec, 0xc2, +0x84, 0x00, 0x68, 0x5b, 0x55, 0x4f, 0xba, 0x41, +0x48, 0x26, 0x19, 0x63, 0xe8, 0x61, 0x87, 0x30, +0xf4, 0x31, 0x47, 0x17, 0xb8, 0x77, 0xce, 0x50, +0x7a, 0x14, 0x65, 0xb9, 0x3e, 0xb3, 0x66, 0x3f, +0x2b, 0x87, 0x35, 0x3a, 0xcd, 0x22, 0x86, 0x39, +0xc9, 0xe5, 0xd1, 0x12, 0x46, 0x7c, 0x9e, 0x4e, +0xb3, 0x88, 0x4a, 0x27, 0x63, 0x54, 0xbd, 0x17, +0x36, 0xd3, 0xe3, 0x7c, 0x15, 0x30, 0x93, 0xdd, +0x05, 0x42, 0x00, 0xd4, 0xea, 0x5c, 0x5c, 0xb3, +0x5c, 0x9f, 0x5e, 0x5d, 0xe3, 0x64, 0x60, 0x9f, +0xa7, 0xdb, 0x3a, 0x61, 0x70, 0x83, 0xef, 0x55, +0x18, 0x4c, 0x64, 0x51, 0x00, 0xaf, 0xdd, 0x67, +0xfa, 0x22, 0x8a, 0xe3, 0x7a, 0x83, 0xf6, 0xf5, +0x01, 0x7a, 0xc4, 0xa0, 0x7d, 0xb5, 0xc7, 0xc8, +0xf4, 0x9a, 0xa6, 0xbe, 0xbf, 0xbc, 0xbd, 0x7f, +0xf0, 0x57, 0x3f, 0x40, 0x57, 0xda, 0xff, 0x60, +0x71, 0x2a, 0x81, 0x19, 0xed, 0x01, 0x60, 0x78, +0x6c, 0x99, 0xda, 0xe9, 0xfa, 0x6f, 0x99, 0xda, +0xbe, 0x90, 0x8d, 0xf3, 0x86, 0x00, 0x38, 0x76, +0x4e, 0x1c, 0x3b, 0x27, 0x00, 0x9f, 0xe1, 0x0e, +0x5e, 0x78, 0xf9, 0x58, 0x08, 0x84, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddprimaryforeignkeyfromuk_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddprimaryforeignkeyfromuk_png = new wxImage(); + if (!img_ddprimaryforeignkeyfromuk_png || !img_ddprimaryforeignkeyfromuk_png->IsOk()) + { + wxMemoryInputStream img_ddprimaryforeignkeyfromuk_pngIS(ddprimaryforeignkeyfromuk_png_data, sizeof(ddprimaryforeignkeyfromuk_png_data)); + img_ddprimaryforeignkeyfromuk_png->LoadFile(img_ddprimaryforeignkeyfromuk_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddprimaryforeignkeyfromuk_png; +} +#define ddprimaryforeignkeyfromuk_png_img ddprimaryforeignkeyfromuk_png_img() + +static wxBitmap *ddprimaryforeignkeyfromuk_png_bmp() +{ + static wxBitmap *bmp_ddprimaryforeignkeyfromuk_png; + if (!bmp_ddprimaryforeignkeyfromuk_png || !bmp_ddprimaryforeignkeyfromuk_png->IsOk()) + bmp_ddprimaryforeignkeyfromuk_png = new wxBitmap(*ddprimaryforeignkeyfromuk_png_img); + return bmp_ddprimaryforeignkeyfromuk_png; +} +#define ddprimaryforeignkeyfromuk_png_bmp ddprimaryforeignkeyfromuk_png_bmp() + +static wxIcon *ddprimaryforeignkeyfromuk_png_ico() +{ + static wxIcon *ico_ddprimaryforeignkeyfromuk_png; + if (!ico_ddprimaryforeignkeyfromuk_png || !ico_ddprimaryforeignkeyfromuk_png->IsOk()) + { + ico_ddprimaryforeignkeyfromuk_png = new wxIcon(); + ico_ddprimaryforeignkeyfromuk_png->CopyFromBitmap(*ddprimaryforeignkeyfromuk_png_bmp); + } + return ico_ddprimaryforeignkeyfromuk_png; +} +#define ddprimaryforeignkeyfromuk_png_ico ddprimaryforeignkeyfromuk_png_ico() + +#endif // DDPRIMARYFOREIGNKEYFROMUK_PNG_H diff --git a/include/images/ddprimarykey.png b/include/images/ddprimarykey.png new file mode 100644 index 0000000000000000000000000000000000000000..568dc770ddc4af10fb647473b7df541a0a757e05 GIT binary patch literal 344 zcmeAS@N?(olHy`uVBq!ia0vp^96-#)!3HEdkIOdzDaPU;cPEB*=VV?2Ic!PZ?k)`f zL2$v|<&%LToCO|{#S9GG!XV7ZFl&wkP>{XE)7O>#Hk%}`qLO=b&RU?*4Nn)x5Q)pZ zeH*=;0wo&u7oVHzAoWg2c9W}9)RKj|uXtTnth`uWaIyRY=Pf;pt#_<%aNlv%Yq@bj zWYG%&m993YmWp%lr$k>dud6w{oMF@PO)~TE3X0`19DQCr{iVUPSN}p+e)RU96P@HO zdZ6Ld!YL0Q>pISM{*rS^af^7x_65`LTYp-JEB^`BsaCI&d``?W*|ce%`=)u@ReRU`sW>bD$KJwn{l)q$A(o%_ lUpro#V6w^Rgw*eLS#Lq_Cq->n=K%f4;OXk;vd$@?2>@PMiirRK literal 0 HcmV?d00001 diff --git a/include/images/ddprimarykey.pngc b/include/images/ddprimarykey.pngc new file mode 100644 index 0000000..150f179 --- /dev/null +++ b/include/images/ddprimarykey.pngc @@ -0,0 +1,87 @@ +#ifndef DDPRIMARYKEY_PNG_H +#define DDPRIMARYKEY_PNG_H + +static const unsigned char ddprimarykey_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, +0x08, 0x06, 0x00, 0x00, 0x00, 0x89, 0xc7, 0x1f, +0x80, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x21, 0x22, 0x47, 0x5b, 0x6c, 0xad, +0x00, 0x00, 0x00, 0xd8, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x8d, 0x8e, 0xb1, 0x4a, 0x42, 0x51, +0x18, 0x80, 0xbf, 0x73, 0xce, 0x95, 0x40, 0x1a, +0xee, 0x12, 0x1d, 0xb2, 0x45, 0x42, 0x5a, 0xa4, +0xa1, 0x2d, 0xea, 0x0d, 0x44, 0xa8, 0xa9, 0xd1, +0x77, 0x70, 0xd1, 0x77, 0xf0, 0x09, 0xda, 0x2e, +0x38, 0xb5, 0xdc, 0x3b, 0xd8, 0x0b, 0xdc, 0x41, +0x2e, 0x84, 0xd8, 0xd0, 0x14, 0xa2, 0xe8, 0x10, +0x24, 0x8a, 0x86, 0x42, 0x84, 0x78, 0xce, 0xef, +0x94, 0x5b, 0xd4, 0x37, 0x7e, 0x7c, 0xc3, 0xa7, +0x00, 0xb2, 0xc7, 0xb2, 0x1c, 0x9f, 0xdd, 0x11, +0x16, 0x6e, 0x00, 0xc5, 0xe7, 0x7b, 0x97, 0xe9, +0x30, 0xe6, 0xea, 0xfe, 0x55, 0xa9, 0xf1, 0x4b, +0x4b, 0x9c, 0x5b, 0x62, 0x4b, 0x15, 0xc0, 0x80, +0xca, 0xa1, 0x94, 0xe1, 0xe3, 0x2d, 0x41, 0x9b, +0x43, 0xf4, 0x6c, 0xd2, 0x21, 0xb4, 0x17, 0x78, +0xb7, 0xa0, 0x97, 0xdc, 0xd2, 0x8b, 0x2b, 0x78, +0xf7, 0x45, 0x58, 0xb8, 0x66, 0x36, 0xe9, 0x10, +0x00, 0xc0, 0x06, 0xef, 0xbe, 0xb9, 0xac, 0x3e, +0x80, 0x3e, 0xc0, 0xfb, 0x15, 0x20, 0x00, 0x28, +0x80, 0xe1, 0x73, 0x5d, 0x8e, 0x8a, 0x65, 0xfc, +0x76, 0x05, 0x3a, 0x4f, 0x90, 0x3b, 0x65, 0x3a, +0xea, 0x62, 0x4c, 0xc8, 0x9e, 0x34, 0xb2, 0xb2, +0x9e, 0x47, 0xb2, 0x9e, 0xb7, 0x25, 0x8d, 0xac, +0xfc, 0x78, 0xcd, 0x1f, 0xfc, 0x3f, 0x38, 0x39, +0xaf, 0xd1, 0x7f, 0x6a, 0x12, 0x04, 0xf9, 0xdf, +0xeb, 0x41, 0xd6, 0x90, 0x34, 0xb2, 0x32, 0xc8, +0x1a, 0xfb, 0x87, 0x1d, 0x4b, 0x11, 0x4b, 0xe4, +0x72, 0x86, 0xd5, 0x9c, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddprimarykey_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddprimarykey_png = new wxImage(); + if (!img_ddprimarykey_png || !img_ddprimarykey_png->IsOk()) + { + wxMemoryInputStream img_ddprimarykey_pngIS(ddprimarykey_png_data, sizeof(ddprimarykey_png_data)); + img_ddprimarykey_png->LoadFile(img_ddprimarykey_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddprimarykey_png; +} +#define ddprimarykey_png_img ddprimarykey_png_img() + +static wxBitmap *ddprimarykey_png_bmp() +{ + static wxBitmap *bmp_ddprimarykey_png; + if (!bmp_ddprimarykey_png || !bmp_ddprimarykey_png->IsOk()) + bmp_ddprimarykey_png = new wxBitmap(*ddprimarykey_png_img); + return bmp_ddprimarykey_png; +} +#define ddprimarykey_png_bmp ddprimarykey_png_bmp() + +static wxIcon *ddprimarykey_png_ico() +{ + static wxIcon *ico_ddprimarykey_png; + if (!ico_ddprimarykey_png || !ico_ddprimarykey_png->IsOk()) + { + ico_ddprimarykey_png = new wxIcon(); + ico_ddprimarykey_png->CopyFromBitmap(*ddprimarykey_png_bmp); + } + return ico_ddprimarykey_png; +} +#define ddprimarykey_png_ico ddprimarykey_png_ico() + +#endif // DDPRIMARYKEY_PNG_H diff --git a/include/images/ddprimarykeyuniquekey.png b/include/images/ddprimarykeyuniquekey.png new file mode 100644 index 0000000000000000000000000000000000000000..7f3fcc24de6d8416257ba5efce42e40731ad20be GIT binary patch literal 361 zcmeAS@N?(olHy`uVBq!ia0vp^96-#)!3HEdkIOdzDaPU;cPEB*=VV?2Ic!PZ?k)`f zL2$v|<&%LToCO|{#S9GG!XV7ZFl&wkP>{XE)7O>#Hk%}`qVDx4g*HH;m!2+;ArhC9 z6M(>CU(oaayPsSCmycihdp;wtfvv^;zwtgd`y1zW&v%Tm?09(aXP$_w&wBa1G=T{h zk}WpdH8?uln)UGO;j=tenbrTz_4j_9-v|Vpi{6PhPkisg#@4ocPZyW?_ixwvgz)pn0_HA1c;Lr;!9-SOX6D0_vrkLRh-8&G^meIal=|I- zgdg3@7}(y_SsQ#P-fU#>FZs~A2B7(l!F|&kUy5_DV$%Ft(N-L-B>@6{G4;nkyk&P{ uzO(7}@zej;@0iX}ZVNQkdBIsOk()) + { + wxMemoryInputStream img_ddprimarykeyuniquekey_pngIS(ddprimarykeyuniquekey_png_data, sizeof(ddprimarykeyuniquekey_png_data)); + img_ddprimarykeyuniquekey_png->LoadFile(img_ddprimarykeyuniquekey_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddprimarykeyuniquekey_png; +} +#define ddprimarykeyuniquekey_png_img ddprimarykeyuniquekey_png_img() + +static wxBitmap *ddprimarykeyuniquekey_png_bmp() +{ + static wxBitmap *bmp_ddprimarykeyuniquekey_png; + if (!bmp_ddprimarykeyuniquekey_png || !bmp_ddprimarykeyuniquekey_png->IsOk()) + bmp_ddprimarykeyuniquekey_png = new wxBitmap(*ddprimarykeyuniquekey_png_img); + return bmp_ddprimarykeyuniquekey_png; +} +#define ddprimarykeyuniquekey_png_bmp ddprimarykeyuniquekey_png_bmp() + +static wxIcon *ddprimarykeyuniquekey_png_ico() +{ + static wxIcon *ico_ddprimarykeyuniquekey_png; + if (!ico_ddprimarykeyuniquekey_png || !ico_ddprimarykeyuniquekey_png->IsOk()) + { + ico_ddprimarykeyuniquekey_png = new wxIcon(); + ico_ddprimarykeyuniquekey_png->CopyFromBitmap(*ddprimarykeyuniquekey_png_bmp); + } + return ico_ddprimarykeyuniquekey_png; +} +#define ddprimarykeyuniquekey_png_ico ddprimarykeyuniquekey_png_ico() + +#endif // DDPRIMARYKEYUNIQUEKEY_PNG_H diff --git a/include/images/ddunique.png b/include/images/ddunique.png new file mode 100644 index 0000000000000000000000000000000000000000..9a25e42fc04726585fb39d203987acd72f633bcb GIT binary patch literal 241 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqjKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPgg)Hc4IusWPXhML?lKPZ!4!iOb0e z4NP;l?EOD``n@0L8`x$fOkz|l;?d@}OFa;<`>vE?*q-ie#Fu=Ely zTibpMkt=T52A_&I8yWmdKD4f(v9ZxHxNmynOL6WzR`qrJlYe|`X57s*S@O1TaS?83{1OPguRE+=t literal 0 HcmV?d00001 diff --git a/include/images/ddunique.pngc b/include/images/ddunique.pngc new file mode 100644 index 0000000..427c5c7 --- /dev/null +++ b/include/images/ddunique.pngc @@ -0,0 +1,75 @@ +#ifndef DDUNIQUE_PNG_H +#define DDUNIQUE_PNG_H + +static const unsigned char ddunique_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, +0x08, 0x06, 0x00, 0x00, 0x00, 0xc4, 0x0f, 0xbe, +0x8b, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x20, 0x1a, 0x76, 0x42, 0xe5, 0x72, +0x00, 0x00, 0x00, 0x71, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0x60, 0x80, 0x02, 0x9d, 0xb4, +0xbd, 0xff, 0x9b, 0x97, 0xde, 0xf8, 0xcf, 0x80, +0x06, 0x98, 0x60, 0x92, 0x01, 0x21, 0x72, 0x0c, +0x2b, 0x0f, 0x3e, 0x65, 0xc0, 0x50, 0xa0, 0x93, +0xb6, 0xf7, 0x7f, 0x75, 0x9e, 0x06, 0x03, 0xe3, +0x7f, 0x46, 0x06, 0x6c, 0x80, 0x29, 0xdc, 0x5e, +0x9a, 0xa1, 0x75, 0xd2, 0x0d, 0x06, 0x86, 0xbf, +0x38, 0x14, 0xd4, 0x46, 0x6b, 0x30, 0xf2, 0x73, +0xb3, 0x32, 0x30, 0xfe, 0x63, 0xc2, 0xae, 0x80, +0x81, 0x81, 0x81, 0x41, 0x53, 0x8e, 0x97, 0x81, +0xe9, 0x17, 0x0b, 0x6e, 0x05, 0x27, 0xae, 0xbf, +0x63, 0xf8, 0xf6, 0x83, 0x01, 0xbb, 0x02, 0x98, +0xd7, 0xb6, 0x1d, 0xb8, 0xc5, 0xc0, 0xc0, 0xc0, +0xc0, 0x80, 0xee, 0x55, 0x00, 0xa8, 0x66, 0x22, +0xf7, 0x68, 0xd9, 0x19, 0x56, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddunique_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddunique_png = new wxImage(); + if (!img_ddunique_png || !img_ddunique_png->IsOk()) + { + wxMemoryInputStream img_ddunique_pngIS(ddunique_png_data, sizeof(ddunique_png_data)); + img_ddunique_png->LoadFile(img_ddunique_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddunique_png; +} +#define ddunique_png_img ddunique_png_img() + +static wxBitmap *ddunique_png_bmp() +{ + static wxBitmap *bmp_ddunique_png; + if (!bmp_ddunique_png || !bmp_ddunique_png->IsOk()) + bmp_ddunique_png = new wxBitmap(*ddunique_png_img); + return bmp_ddunique_png; +} +#define ddunique_png_bmp ddunique_png_bmp() + +static wxIcon *ddunique_png_ico() +{ + static wxIcon *ico_ddunique_png; + if (!ico_ddunique_png || !ico_ddunique_png->IsOk()) + { + ico_ddunique_png = new wxIcon(); + ico_ddunique_png->CopyFromBitmap(*ddunique_png_bmp); + } + return ico_ddunique_png; +} +#define ddunique_png_ico ddunique_png_ico() + +#endif // DDUNIQUE_PNG_H diff --git a/include/images/debugger.png b/include/images/debugger.png new file mode 100644 index 0000000000000000000000000000000000000000..4430e86c00272532ae3b8b5514568dc0d1ca3427 GIT binary patch literal 350 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFv3GfMV1=0r&9B620VEF%^fuRA& zWnlQv(9i(nf%pv|q4#x1{{n>>OM?7@862M7NCR>>3p^r=fwTu0yPeFo12PIdT^vI= zt|uojFe$QW2s8xvFm)wFdE7iW@u1)lE?@o>Ar`|!vCguNJgq|I;qDWP76z107bsTf z-gxEcQP-<;6+2cQQ9a@sII%G>;L1|tkU)VG0fmt}MRHPtJiezm0Xkxq!^403=MP*jdTqRLyQcpOpL8e zOtcM5tqcq-W~$1eXvob^$xN$+XfUt@YXGUXGBAT^I5jmdKI;Vst00yLJ AxBvhE literal 0 HcmV?d00001 diff --git a/include/images/debugger.pngc b/include/images/debugger.pngc new file mode 100644 index 0000000..917d52c --- /dev/null +++ b/include/images/debugger.pngc @@ -0,0 +1,88 @@ +#ifndef DEBUGGER_PNG_H +#define DEBUGGER_PNG_H + +static const unsigned char debugger_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x24, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0x80, +0x80, 0x80, 0x00, 0xff, 0xff, 0x00, 0x00, 0x80, +0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x80, +0x80, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x80, +0x80, 0x00, 0x80, 0x00, 0x00, 0xef, 0x7e, 0xc5, +0xfd, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x71, 0x49, +0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0x60, 0x00, +0x02, 0x21, 0x06, 0x28, 0x10, 0x80, 0x50, 0x4c, +0x02, 0x8a, 0x60, 0x5a, 0x48, 0xd9, 0xc1, 0x91, +0xc1, 0x11, 0xc4, 0x0a, 0x4d, 0x0f, 0x64, 0x12, +0x04, 0x31, 0xc2, 0x5d, 0x43, 0x1d, 0x41, 0x0c, +0x85, 0x12, 0x77, 0x57, 0x47, 0x90, 0x72, 0xa1, +0x50, 0x77, 0x97, 0x10, 0x73, 0x20, 0x8b, 0xb1, +0xd4, 0xc5, 0xc5, 0x45, 0xd5, 0x9d, 0x21, 0x88, +0xa9, 0xc4, 0x25, 0xc4, 0x45, 0x51, 0x91, 0x81, +0x51, 0x50, 0xd4, 0xa5, 0x33, 0x54, 0x51, 0x10, +0xc8, 0x50, 0x71, 0x59, 0xb9, 0x14, 0x6c, 0x64, +0x52, 0x48, 0xf7, 0x26, 0x30, 0xa3, 0x48, 0x35, +0x34, 0x08, 0x6c, 0x9b, 0x93, 0xa0, 0x92, 0x12, +0x98, 0x11, 0x24, 0x20, 0x08, 0x34, 0x18, 0x00, +0x52, 0xf1, 0x12, 0x33, 0x97, 0xb8, 0x21, 0x59, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, +0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *debugger_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_debugger_png = new wxImage(); + if (!img_debugger_png || !img_debugger_png->IsOk()) + { + wxMemoryInputStream img_debugger_pngIS(debugger_png_data, sizeof(debugger_png_data)); + img_debugger_png->LoadFile(img_debugger_pngIS, wxBITMAP_TYPE_PNG); + } + return img_debugger_png; +} +#define debugger_png_img debugger_png_img() + +static wxBitmap *debugger_png_bmp() +{ + static wxBitmap *bmp_debugger_png; + if (!bmp_debugger_png || !bmp_debugger_png->IsOk()) + bmp_debugger_png = new wxBitmap(*debugger_png_img); + return bmp_debugger_png; +} +#define debugger_png_bmp debugger_png_bmp() + +static wxIcon *debugger_png_ico() +{ + static wxIcon *ico_debugger_png; + if (!ico_debugger_png || !ico_debugger_png->IsOk()) + { + ico_debugger_png = new wxIcon(); + ico_debugger_png->CopyFromBitmap(*debugger_png_bmp); + } + return ico_debugger_png; +} +#define debugger_png_ico debugger_png_ico() + +#endif // DEBUGGER_PNG_H diff --git a/include/images/delete.png b/include/images/delete.png new file mode 100644 index 0000000000000000000000000000000000000000..daa6a7c3e871306c085741c98aba98929cd4eba1 GIT binary patch literal 608 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf-T5xo6ItS-g1h-o1OTUcLJA<;$;Mzkd4k>B*BP7cXAixpU|2*|YE6ySHY| znyFK#c6N3iI&`SIy86V46Bi$yK7aq@gBN$-y?b}}*{$Hk7SW4c-Dm6Uxw!4&!-pF; zZmi#))4rp^dV=!Iof9^mS#kURtz%aXZ9cm0)~#DR&um$GXs%(mbl?p8lUI+$&-Ztq zVw|!xsBukMe}Dhcqel;)I&|mGol|E|?K!;b+_`fF1qDk@{(A#Gz*rLG7tG-B>_!@p z!&%@FSq!8-z}W3%wjGdh%hSa%MB=jUxz|C>1_G=PCUC1TGEEZd*viGq92&GbXr=hC zfBjbvRMfq#D=tf8WRP>2@x$&Qf1ok?Hx6s|CylkiVf3f_0p_>IHGrj?iG zY8=~IG~u;H-_gI{62)Cz-!(WY%FSQ3>z=viX&DE#vh!OFWA&w3WHVH^v48%w%iMYK z7H035hZ;|Bzl;^yZS%-|*{==Pe#@-g|7HOXe`u*)-(zvz@ELla?)3g$`TN;rt~Gyu z%Cg=4e^z=MlZ)?+b5qWlHETB{WR<>%y`{7i?Y8W=oX{an^LB{Ts575o*m literal 0 HcmV?d00001 diff --git a/include/images/delete.pngc b/include/images/delete.pngc new file mode 100644 index 0000000..10aab57 --- /dev/null +++ b/include/images/delete.pngc @@ -0,0 +1,120 @@ +#ifndef DELETE_PNG_H +#define DELETE_PNG_H + +static const unsigned char delete_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xbd, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xd3, 0xd4, 0xd3, 0xb5, +0xb5, 0xb5, 0x9f, 0x9f, 0x9f, 0x85, 0x85, 0x85, +0x77, 0x77, 0x77, 0x6c, 0x6c, 0x6c, 0x9d, 0x9d, +0x9d, 0xcc, 0xcc, 0xcc, 0xa3, 0xa3, 0xa3, 0xbd, +0xbd, 0xbd, 0xd5, 0xd5, 0xd5, 0xe9, 0xe9, 0xe9, +0xf5, 0xf5, 0xf5, 0xf2, 0xf2, 0xf2, 0xe4, 0xe4, +0xe4, 0xd1, 0xd1, 0xd1, 0xb9, 0xb9, 0xb9, 0x9b, +0x9b, 0x9b, 0xde, 0xde, 0xde, 0xac, 0xac, 0xac, +0x95, 0x95, 0x95, 0x89, 0x89, 0x89, 0xc2, 0xc2, +0xc2, 0x7b, 0x7b, 0x7b, 0xc8, 0xc8, 0xc8, 0xd1, +0xe2, 0xcb, 0xcf, 0xdf, 0xc9, 0xe0, 0xe8, 0xdd, +0xee, 0xee, 0xee, 0xdd, 0xe6, 0xda, 0x53, 0xa3, +0x38, 0x5b, 0xa3, 0x45, 0x47, 0x9b, 0x2c, 0xbc, +0xd1, 0xb6, 0xe1, 0xe1, 0xe1, 0xb1, 0xb1, 0xb1, +0x7f, 0xb7, 0x6c, 0x87, 0xb8, 0x78, 0x3b, 0x90, +0x23, 0x99, 0xb9, 0x90, 0xb1, 0xcc, 0xa8, 0xdb, +0xdf, 0xda, 0xc6, 0xd4, 0xc2, 0xb3, 0xc5, 0xae, +0xda, 0xda, 0xda, 0xb9, 0xcc, 0xb4, 0xa5, 0xc2, +0x9d, 0x31, 0x8b, 0x1b, 0x51, 0x98, 0x3f, 0xc9, +0xd5, 0xc6, 0x5f, 0x9f, 0x4f, 0x47, 0x94, 0x33, +0x64, 0xa5, 0x52, 0x81, 0xac, 0x76, 0x8f, 0x8f, +0x8f, 0xc5, 0xc5, 0xc5, 0xc3, 0xca, 0xc2, 0xdc, +0xdc, 0xdc, 0xca, 0xcd, 0xca, 0xbc, 0xc3, 0xba, +0xce, 0xce, 0xce, 0x70, 0x70, 0x70, 0xa5, 0x34, +0xff, 0x4b, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0xda, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x2d, 0xce, +0xeb, 0x52, 0x83, 0x30, 0x10, 0x05, 0xe0, 0x90, +0x0b, 0x24, 0x01, 0x02, 0x92, 0x12, 0x88, 0xb5, +0x0a, 0x05, 0x03, 0x55, 0x52, 0xab, 0x52, 0xa9, +0x17, 0xfa, 0xfe, 0x8f, 0xd5, 0xc0, 0x78, 0x7e, +0xed, 0x7e, 0x73, 0x76, 0x66, 0x01, 0x00, 0x1e, +0x44, 0x98, 0xf8, 0x3e, 0xc1, 0x01, 0xf4, 0x80, +0x0b, 0x25, 0x8c, 0x87, 0x51, 0x2c, 0x92, 0xf4, +0x2e, 0x20, 0xd4, 0x01, 0xce, 0x18, 0x4f, 0x65, +0x22, 0x53, 0xbe, 0xc9, 0x33, 0xec, 0x40, 0xd1, +0x82, 0xa9, 0xd2, 0x9d, 0x28, 0xc6, 0xb5, 0x72, +0x90, 0xeb, 0x38, 0x8e, 0xc5, 0xfd, 0xf6, 0x61, +0x17, 0x45, 0x45, 0xee, 0x80, 0x41, 0x21, 0x1e, +0x9f, 0xaa, 0xba, 0xde, 0x37, 0x49, 0xcb, 0x1c, +0x40, 0x26, 0x76, 0xcf, 0xb5, 0x31, 0x5d, 0x2f, +0x1b, 0x04, 0x1d, 0x68, 0x25, 0xb6, 0x07, 0xf3, +0xf2, 0xba, 0x37, 0x43, 0xa3, 0xb4, 0x03, 0x4b, +0x5c, 0xe1, 0x28, 0xe5, 0xdb, 0xe9, 0x5d, 0x12, +0xbb, 0x3c, 0xe2, 0x47, 0xa6, 0xfa, 0xb0, 0xd6, +0xfb, 0x1c, 0xad, 0xbf, 0xec, 0xa0, 0x0c, 0x0f, +0x55, 0x75, 0x3e, 0x8e, 0xe3, 0x17, 0x2d, 0x57, +0x98, 0x2e, 0xf2, 0xdc, 0x8d, 0xfd, 0xa9, 0xfb, +0xe6, 0xd3, 0x0a, 0xac, 0xfd, 0xf9, 0x1d, 0x06, +0xdd, 0xff, 0xcd, 0x1b, 0xb6, 0x02, 0x44, 0x4d, +0x98, 0xce, 0x94, 0xce, 0x36, 0x83, 0x2b, 0x80, +0x60, 0x6a, 0x75, 0xe8, 0x5d, 0xda, 0x29, 0x00, +0xff, 0x29, 0x10, 0xbe, 0x5e, 0x31, 0x2a, 0x96, +0xf9, 0x06, 0x23, 0xaa, 0x13, 0x7e, 0xcd, 0x94, +0xab, 0xc9, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, +0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *delete_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_delete_png = new wxImage(); + if (!img_delete_png || !img_delete_png->IsOk()) + { + wxMemoryInputStream img_delete_pngIS(delete_png_data, sizeof(delete_png_data)); + img_delete_png->LoadFile(img_delete_pngIS, wxBITMAP_TYPE_PNG); + } + return img_delete_png; +} +#define delete_png_img delete_png_img() + +static wxBitmap *delete_png_bmp() +{ + static wxBitmap *bmp_delete_png; + if (!bmp_delete_png || !bmp_delete_png->IsOk()) + bmp_delete_png = new wxBitmap(*delete_png_img); + return bmp_delete_png; +} +#define delete_png_bmp delete_png_bmp() + +static wxIcon *delete_png_ico() +{ + static wxIcon *ico_delete_png; + if (!ico_delete_png || !ico_delete_png->IsOk()) + { + ico_delete_png = new wxIcon(); + ico_delete_png->CopyFromBitmap(*delete_png_bmp); + } + return ico_delete_png; +} +#define delete_png_ico delete_png_ico() + +#endif // DELETE_PNG_H diff --git a/include/images/dictionaries.png b/include/images/dictionaries.png new file mode 100644 index 0000000000000000000000000000000000000000..a97eb49af2861ce712def8db538f583301361c79 GIT binary patch literal 362 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!Q-Dv1E0CVF<)~EUstZR-?YlSk zEKWVU+dg9Y4y(?Mfk(f(?)hlD{k_k@&n6q*Xs>*!wD_6ioX3LGA978)FObyF+IKg7 z{+^#%+eLt;FqQ=Q1v5B2yO9Rua29w(76WMyFm^kcZ3kq;d%8G=NL)@m@6Fesz~dUI zVb91Ic;kQA)}wo7-1y>mZbj%T^I1KW)0EF9%>DjEHC>WPFgL%kG0EpeYme9)R$UKK z-4nc=Z=O0Ztt?ZSaJ!S`l<5SAx6FoT&cFQpfA=oN`TJORtT57g541|P#5JNMC9x#c zD!C{XNHG{07#ipr8tEDsh8P)GnHXD{m}ncAS{WEv%v6;_(U6;;l9^Ts(O_T+)&Np% YWnc!;aB6z!8lVOSPgg&ebxsLQ0H%k2tN;K2 literal 0 HcmV?d00001 diff --git a/include/images/dictionaries.pngc b/include/images/dictionaries.pngc new file mode 100644 index 0000000..fc627ca --- /dev/null +++ b/include/images/dictionaries.pngc @@ -0,0 +1,90 @@ +#ifndef DICTIONARIES_PNG_H +#define DICTIONARIES_PNG_H + +static const unsigned char dictionaries_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x42, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x92, 0xb4, 0xc5, 0x1a, +0x79, 0xaa, 0xd0, 0xc4, 0x75, 0x3f, 0x8b, 0xb3, +0x8c, 0xa3, 0x65, 0xcd, 0xbb, 0x3f, 0x58, 0x97, +0xb8, 0x3a, 0x89, 0xb1, 0x51, 0xc5, 0xf5, 0x45, +0xbc, 0xf1, 0x3d, 0xb7, 0xef, 0x4c, 0xc1, 0xf3, +0x34, 0xb0, 0xec, 0x2b, 0xa9, 0xe9, 0x22, 0xa3, +0xe6, 0x19, 0x9c, 0xe3, 0x11, 0x97, 0xe1, 0x0a, +0x92, 0xdf, 0x10, 0x62, 0x8f, 0x05, 0x8e, 0xdd, +0x67, 0x9f, 0xbc, 0xf9, 0x6a, 0xb7, 0x14, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x5f, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x65, 0xcf, 0x4b, 0x0e, 0x80, +0x20, 0x0c, 0x45, 0x51, 0x28, 0x3f, 0x01, 0x01, +0x51, 0xd8, 0xff, 0x56, 0xb5, 0xc5, 0xbc, 0x98, +0xd8, 0xf4, 0x4e, 0xce, 0xa8, 0x55, 0xea, 0x37, +0x9a, 0x8c, 0x79, 0x96, 0x23, 0xcd, 0x60, 0x9d, +0xf7, 0xe4, 0x25, 0x67, 0x19, 0x02, 0x11, 0x6d, +0x6f, 0x81, 0x81, 0x62, 0x4c, 0xe8, 0x85, 0x8c, +0x16, 0xec, 0x05, 0x2d, 0x48, 0x15, 0x2d, 0xc8, +0x0d, 0x09, 0xec, 0xe5, 0x40, 0x02, 0xa9, 0x76, +0x24, 0x90, 0xdb, 0x89, 0x04, 0xca, 0x35, 0x90, +0x40, 0xed, 0x03, 0x31, 0xcc, 0xcf, 0xe9, 0xf3, +0xff, 0xbb, 0xba, 0x01, 0x9f, 0xbe, 0x05, 0xb8, +0xa8, 0x32, 0x2a, 0xef, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *dictionaries_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_dictionaries_png = new wxImage(); + if (!img_dictionaries_png || !img_dictionaries_png->IsOk()) + { + wxMemoryInputStream img_dictionaries_pngIS(dictionaries_png_data, sizeof(dictionaries_png_data)); + img_dictionaries_png->LoadFile(img_dictionaries_pngIS, wxBITMAP_TYPE_PNG); + } + return img_dictionaries_png; +} +#define dictionaries_png_img dictionaries_png_img() + +static wxBitmap *dictionaries_png_bmp() +{ + static wxBitmap *bmp_dictionaries_png; + if (!bmp_dictionaries_png || !bmp_dictionaries_png->IsOk()) + bmp_dictionaries_png = new wxBitmap(*dictionaries_png_img); + return bmp_dictionaries_png; +} +#define dictionaries_png_bmp dictionaries_png_bmp() + +static wxIcon *dictionaries_png_ico() +{ + static wxIcon *ico_dictionaries_png; + if (!ico_dictionaries_png || !ico_dictionaries_png->IsOk()) + { + ico_dictionaries_png = new wxIcon(); + ico_dictionaries_png->CopyFromBitmap(*dictionaries_png_bmp); + } + return ico_dictionaries_png; +} +#define dictionaries_png_ico dictionaries_png_ico() + +#endif // DICTIONARIES_PNG_H diff --git a/include/images/dictionary.png b/include/images/dictionary.png new file mode 100644 index 0000000000000000000000000000000000000000..55a880b7a0e14db1433b90f559beefdd1d3071fb GIT binary patch literal 634 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47zG1-LR^8|wsnW4DpxJsebRK% zRpW(MZPwg(+xy9R_eYDR*Nm3jwq1MQbN?sTy&o;+ol(u}SI+I%pL1S&!A<8iH$C=! za^CS;J%56B`zD2~KG}?3o#juICZCzLmI{%_lcAwUi6FRG3YAk=D zvgEnk^s8E(+l(geHCueuV)I+Qxt9&rzS3UxQhoUgDZw*?Sksk=ZcG-$u4**Irp*n z#7mRsq{}sIl4;r|JMo;%{3nu=E>E15b$pZCh5go&)$2rSw}`bJ>Ytu-be-4P-S&$% zg@{(IKef$i{<`qSHHYS|iJEjwaUU>H7)yfuf*Bm1-ADs+I14-?i-EKU7`vU!wgWO2 zc)B=-NL7i?Y8W=oX{an^L HB{Ts5+LaYu literal 0 HcmV?d00001 diff --git a/include/images/dictionary.pngc b/include/images/dictionary.pngc new file mode 100644 index 0000000..7d00baa --- /dev/null +++ b/include/images/dictionary.pngc @@ -0,0 +1,124 @@ +#ifndef DICTIONARY_PNG_H +#define DICTIONARY_PNG_H + +static const unsigned char dictionary_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x11, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x86, 0xae, 0xc3, 0x1a, +0x79, 0xaa, 0xa1, 0xbb, 0xc9, 0x35, 0xa2, 0xd5, +0x33, 0xa1, 0xd5, 0x3c, 0xac, 0xdf, 0x46, 0xbd, +0xf2, 0x43, 0xbb, 0xf1, 0x38, 0xa5, 0xd6, 0x32, +0xa4, 0xdb, 0x3d, 0xad, 0xdf, 0x49, 0xbf, 0xf2, +0x45, 0xbd, 0xf1, 0x38, 0x9e, 0xcc, 0x25, 0x6e, +0x8f, 0x23, 0x6d, 0x8f, 0x2f, 0x9c, 0xcf, 0x2b, +0xa0, 0xd9, 0x43, 0xac, 0xd9, 0x48, 0xbe, 0xf2, +0x43, 0xb8, 0xeb, 0x27, 0x6f, 0x90, 0x2b, 0x87, +0xb2, 0x20, 0x6a, 0x8e, 0x1d, 0x68, 0x8d, 0x2c, +0xa7, 0xe4, 0x22, 0x93, 0xcc, 0x9a, 0xb8, 0xc8, +0x38, 0x96, 0xbf, 0x3d, 0xa7, 0xd7, 0x40, 0xb9, +0xf0, 0x35, 0x9f, 0xd1, 0x22, 0x6b, 0x8e, 0x2a, +0x94, 0xc8, 0x2c, 0xab, 0xe9, 0x28, 0xa7, 0xe8, +0x24, 0xa4, 0xe7, 0x1e, 0x97, 0xd5, 0x2a, 0x89, +0xb6, 0x32, 0x91, 0xbd, 0x36, 0xa3, 0xd5, 0x38, +0xb3, 0xed, 0x2e, 0x9d, 0xd3, 0x30, 0xad, 0xea, +0x2b, 0xaa, 0xe9, 0x27, 0xa7, 0xe8, 0x23, 0xa4, +0xe6, 0x1f, 0xa1, 0xe5, 0x1b, 0x9e, 0xe4, 0x18, +0x92, 0xd3, 0x27, 0x86, 0xb5, 0x2b, 0x8c, 0xbb, +0x2e, 0x9c, 0xd3, 0x2f, 0xac, 0xea, 0x2a, 0xa9, +0xe9, 0x26, 0xa6, 0xe8, 0x22, 0xa3, 0xe6, 0x1e, +0xa0, 0xe5, 0x1a, 0x9d, 0xe4, 0x16, 0x9b, 0xe2, +0x15, 0x8f, 0xd2, 0x22, 0x83, 0xb3, 0x24, 0x88, +0xb8, 0x26, 0x96, 0xd0, 0x25, 0xa5, 0xe7, 0x21, +0xa2, 0xe6, 0x1d, 0xa0, 0xe5, 0x19, 0x9d, 0xe3, +0x17, 0x91, 0xd2, 0x93, 0x9c, 0x67, 0x1e, 0x80, +0xb2, 0x1c, 0x82, 0xb6, 0x1d, 0x91, 0xce, 0x1c, +0x9f, 0xe4, 0x19, 0x92, 0xd3, 0x91, 0x9a, 0x6a, +0xc7, 0xb2, 0x46, 0xd0, 0xbf, 0x3b, 0x19, 0x7b, +0xae, 0x15, 0x7d, 0xb4, 0x16, 0x86, 0xc2, 0x8f, +0x97, 0x6c, 0xc5, 0xae, 0x4a, 0xcd, 0xbb, 0x3f, +0xa2, 0xb2, 0x54, 0x15, 0x7a, 0xaf, 0xca, 0xb6, +0x42, 0x9f, 0xae, 0x57, 0x81, 0xac, 0xc2, 0x9d, +0xac, 0x5a, 0x92, 0xc6, 0x21, 0xbe, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0xa0, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x6d, 0xce, 0xd5, 0x0e, 0xc2, 0x50, +0x10, 0x04, 0xd0, 0xdb, 0x29, 0x6e, 0xc5, 0xdd, +0xdd, 0xdd, 0x5d, 0x8b, 0xbb, 0xf3, 0xff, 0x1f, +0x02, 0xdc, 0xd0, 0x40, 0x13, 0xf6, 0x6d, 0x4e, +0x66, 0x37, 0x4b, 0xc8, 0xdf, 0x61, 0x00, 0x56, +0x1c, 0x25, 0xd2, 0xaf, 0xbc, 0xa2, 0x4c, 0xae, +0x50, 0xaa, 0x04, 0x01, 0xd4, 0x1a, 0xad, 0x8e, +0xd3, 0x1b, 0x8c, 0x1f, 0x81, 0xc9, 0x6c, 0xb1, +0x72, 0x36, 0xbb, 0xc3, 0xe9, 0x82, 0x9b, 0x82, +0xc7, 0xeb, 0xf3, 0x07, 0xec, 0xc1, 0x50, 0x38, +0x12, 0xa5, 0x1d, 0xc4, 0xe2, 0x89, 0x64, 0x2a, +0x9d, 0xc9, 0xe6, 0xf2, 0x85, 0xe2, 0x5b, 0x58, +0x94, 0xca, 0x95, 0x6a, 0xad, 0xde, 0x68, 0xb6, +0xda, 0x1d, 0x80, 0xbc, 0xa5, 0xdb, 0xeb, 0x0f, +0x86, 0xa3, 0xf1, 0x04, 0xe0, 0xe9, 0x59, 0x16, +0xd3, 0xd9, 0x7c, 0xb1, 0x04, 0x56, 0xeb, 0x0d, +0xf9, 0xc8, 0x76, 0xb7, 0xc7, 0xe1, 0x78, 0x3a, +0xd3, 0x15, 0x2a, 0x17, 0xf0, 0xd7, 0x1b, 0xc0, +0x08, 0xdf, 0xde, 0x81, 0xc7, 0x4f, 0xa4, 0x1d, +0x51, 0xfc, 0x9d, 0x27, 0xa5, 0x5a, 0x10, 0xe1, +0x70, 0x44, 0xf1, 0x23, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *dictionary_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_dictionary_png = new wxImage(); + if (!img_dictionary_png || !img_dictionary_png->IsOk()) + { + wxMemoryInputStream img_dictionary_pngIS(dictionary_png_data, sizeof(dictionary_png_data)); + img_dictionary_png->LoadFile(img_dictionary_pngIS, wxBITMAP_TYPE_PNG); + } + return img_dictionary_png; +} +#define dictionary_png_img dictionary_png_img() + +static wxBitmap *dictionary_png_bmp() +{ + static wxBitmap *bmp_dictionary_png; + if (!bmp_dictionary_png || !bmp_dictionary_png->IsOk()) + bmp_dictionary_png = new wxBitmap(*dictionary_png_img); + return bmp_dictionary_png; +} +#define dictionary_png_bmp dictionary_png_bmp() + +static wxIcon *dictionary_png_ico() +{ + static wxIcon *ico_dictionary_png; + if (!ico_dictionary_png || !ico_dictionary_png->IsOk()) + { + ico_dictionary_png = new wxIcon(); + ico_dictionary_png->CopyFromBitmap(*dictionary_png_bmp); + } + return ico_dictionary_png; +} +#define dictionary_png_ico dictionary_png_ico() + +#endif // DICTIONARY_PNG_H diff --git a/include/images/disabled.png b/include/images/disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..53128fd9b8ac21a12d7de10273e7e3e48ff9af30 GIT binary patch literal 267 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPHV5AX?b1=0--4gdfDcW`jHa^ZyF z@;B^2A;yv*zhDN3XE)M7oFs2|7p64sniL?1v%n*=7)X17vD?XPJ0L^N)5S4_<9c$! z0fwF?1qGHAiRK3335gs+3)K#@vNZ6hsTw#$@G&e*IsOk()) + { + wxMemoryInputStream img_disabled_pngIS(disabled_png_data, sizeof(disabled_png_data)); + img_disabled_png->LoadFile(img_disabled_pngIS, wxBITMAP_TYPE_PNG); + } + return img_disabled_png; +} +#define disabled_png_img disabled_png_img() + +static wxBitmap *disabled_png_bmp() +{ + static wxBitmap *bmp_disabled_png; + if (!bmp_disabled_png || !bmp_disabled_png->IsOk()) + bmp_disabled_png = new wxBitmap(*disabled_png_img); + return bmp_disabled_png; +} +#define disabled_png_bmp disabled_png_bmp() + +static wxIcon *disabled_png_ico() +{ + static wxIcon *ico_disabled_png; + if (!ico_disabled_png || !ico_disabled_png->IsOk()) + { + ico_disabled_png = new wxIcon(); + ico_disabled_png->CopyFromBitmap(*disabled_png_bmp); + } + return ico_disabled_png; +} +#define disabled_png_ico disabled_png_ico() + +#endif // DISABLED_PNG_H diff --git a/include/images/dnd_copy.png b/include/images/dnd_copy.png new file mode 100644 index 0000000000000000000000000000000000000000..a65dc6f8b5b096d1ea0061154918cd67ee605861 GIT binary patch literal 312 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfvp#Yx{S0D`p{}~v*-rIa>OHbO& z|5x^`u>%S*mIV0)GdMiEkp|>&7I;J!18EO1b~~93QW5Lv;uxZFJ~<&lpoNi)G20}Gz7Qb3DTOI#yLQW8s2t&)pUffR$0 zfuVt}p^>hEVTh4|m5H&HiHWv>sg;3&#Y|N>6b-rgDVb@N5Df;FU=1MERt9De4X37u Rt^sOb@O1TaS?83{1OUFbQnUa7 literal 0 HcmV?d00001 diff --git a/include/images/dnd_copy.pngc b/include/images/dnd_copy.pngc new file mode 100644 index 0000000..fc8d766 --- /dev/null +++ b/include/images/dnd_copy.pngc @@ -0,0 +1,83 @@ +#ifndef DND_COPY_PNG_H +#define DND_COPY_PNG_H + +static const unsigned char dnd_copy_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x04, 0x03, 0x00, 0x00, 0x00, 0x81, 0x54, 0x67, +0xc7, 0x00, 0x00, 0x00, 0x12, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, +0x00, 0x00, 0xf5, 0xde, 0xb3, 0xd2, 0xb4, 0x8c, +0x66, 0x99, 0xff, 0xd4, 0xbc, 0xac, 0x3e, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x5d, 0x49, 0x44, 0x41, +0x54, 0x28, 0xcf, 0x63, 0x60, 0x60, 0x10, 0x84, +0x01, 0x01, 0x06, 0x06, 0x05, 0x06, 0x20, 0x10, +0x36, 0x86, 0x02, 0x41, 0x74, 0x01, 0x11, 0x21, +0x25, 0x25, 0x25, 0x14, 0x01, 0x47, 0x74, 0x15, +0x2e, 0x02, 0xe8, 0x02, 0x8e, 0x0c, 0xa8, 0x86, +0x82, 0x2d, 0x02, 0x0b, 0x84, 0x82, 0x80, 0xb1, +0x89, 0x8b, 0x8b, 0x00, 0x8a, 0x0a, 0x24, 0x01, +0x88, 0x0a, 0x20, 0x40, 0x55, 0x81, 0x2c, 0x00, +0x52, 0x11, 0x8c, 0x4f, 0x85, 0x29, 0x41, 0x15, +0x83, 0xc5, 0x16, 0xa2, 0xcc, 0x08, 0x36, 0xc6, +0x6b, 0x06, 0xc5, 0x02, 0x82, 0x48, 0x40, 0x80, +0x01, 0x00, 0x68, 0xd0, 0x4c, 0xe0, 0x38, 0x0c, +0xf5, 0x1a, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, +0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *dnd_copy_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_dnd_copy_png = new wxImage(); + if (!img_dnd_copy_png || !img_dnd_copy_png->IsOk()) + { + wxMemoryInputStream img_dnd_copy_pngIS(dnd_copy_png_data, sizeof(dnd_copy_png_data)); + img_dnd_copy_png->LoadFile(img_dnd_copy_pngIS, wxBITMAP_TYPE_PNG); + } + return img_dnd_copy_png; +} +#define dnd_copy_png_img dnd_copy_png_img() + +static wxBitmap *dnd_copy_png_bmp() +{ + static wxBitmap *bmp_dnd_copy_png; + if (!bmp_dnd_copy_png || !bmp_dnd_copy_png->IsOk()) + bmp_dnd_copy_png = new wxBitmap(*dnd_copy_png_img); + return bmp_dnd_copy_png; +} +#define dnd_copy_png_bmp dnd_copy_png_bmp() + +static wxIcon *dnd_copy_png_ico() +{ + static wxIcon *ico_dnd_copy_png; + if (!ico_dnd_copy_png || !ico_dnd_copy_png->IsOk()) + { + ico_dnd_copy_png = new wxIcon(); + ico_dnd_copy_png->CopyFromBitmap(*dnd_copy_png_bmp); + } + return ico_dnd_copy_png; +} +#define dnd_copy_png_ico dnd_copy_png_ico() + +#endif // DND_COPY_PNG_H diff --git a/include/images/dnd_move.png b/include/images/dnd_move.png new file mode 100644 index 0000000000000000000000000000000000000000..ca09dcff2fb451906a04b44f0a0aec04c0f6939c GIT binary patch literal 302 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv{s5m4S0D`pU+-)5S4F<9u>Lf!~4F8sx-BA!rIRmsowZt`|BqgyV)hf9t6-Y4{85kPq8XD;u7={=b zSeY1GnV4uBm|7VaSj<$FL(!0%pOTqY3DIC+3Dy8oZDn8v(Qs;d=o+8~22WQ%mvv4F FO#o!>P)7g& literal 0 HcmV?d00001 diff --git a/include/images/dnd_move.pngc b/include/images/dnd_move.pngc new file mode 100644 index 0000000..9aee9fe --- /dev/null +++ b/include/images/dnd_move.pngc @@ -0,0 +1,82 @@ +#ifndef DND_MOVE_PNG_H +#define DND_MOVE_PNG_H + +static const unsigned char dnd_move_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x04, 0x03, 0x00, 0x00, 0x00, 0x81, 0x54, 0x67, +0xc7, 0x00, 0x00, 0x00, 0x0f, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, +0xde, 0xb3, 0xd2, 0xb4, 0x8c, 0x66, 0x99, 0xff, +0x4d, 0x80, 0x23, 0x74, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x56, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, +0x63, 0x60, 0x60, 0x10, 0x84, 0x01, 0x01, 0x06, +0x08, 0x10, 0x52, 0x82, 0x02, 0x41, 0x74, 0x01, +0x61, 0x01, 0x74, 0x01, 0x43, 0x74, 0x01, 0x63, +0x01, 0x74, 0x01, 0x43, 0x34, 0x43, 0xa1, 0x16, +0x01, 0x05, 0x5c, 0x40, 0x40, 0x49, 0xd9, 0xd8, +0x58, 0x00, 0x45, 0x05, 0x92, 0x00, 0x44, 0x05, +0x10, 0xa0, 0xaa, 0x40, 0x16, 0x00, 0xa9, 0x70, +0xc2, 0xa7, 0x42, 0x85, 0xa0, 0x8a, 0xc1, 0x62, +0x0b, 0x51, 0x66, 0x38, 0x29, 0xe1, 0x35, 0x83, +0x62, 0x01, 0x41, 0x24, 0x20, 0xc0, 0x00, 0x00, +0xfe, 0xa4, 0x36, 0xdc, 0x20, 0x16, 0x64, 0xcc, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, +0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *dnd_move_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_dnd_move_png = new wxImage(); + if (!img_dnd_move_png || !img_dnd_move_png->IsOk()) + { + wxMemoryInputStream img_dnd_move_pngIS(dnd_move_png_data, sizeof(dnd_move_png_data)); + img_dnd_move_png->LoadFile(img_dnd_move_pngIS, wxBITMAP_TYPE_PNG); + } + return img_dnd_move_png; +} +#define dnd_move_png_img dnd_move_png_img() + +static wxBitmap *dnd_move_png_bmp() +{ + static wxBitmap *bmp_dnd_move_png; + if (!bmp_dnd_move_png || !bmp_dnd_move_png->IsOk()) + bmp_dnd_move_png = new wxBitmap(*dnd_move_png_img); + return bmp_dnd_move_png; +} +#define dnd_move_png_bmp dnd_move_png_bmp() + +static wxIcon *dnd_move_png_ico() +{ + static wxIcon *ico_dnd_move_png; + if (!ico_dnd_move_png || !ico_dnd_move_png->IsOk()) + { + ico_dnd_move_png = new wxIcon(); + ico_dnd_move_png->CopyFromBitmap(*dnd_move_png_bmp); + } + return ico_dnd_move_png; +} +#define dnd_move_png_ico dnd_move_png_ico() + +#endif // DND_MOVE_PNG_H diff --git a/include/images/dnd_none.png b/include/images/dnd_none.png new file mode 100644 index 0000000000000000000000000000000000000000..c7345e241b38ad2d9cbd78ffff3df52e25093e93 GIT binary patch literal 367 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfvp#Yx{S0D`pU+-@c_t~CsM`$_AFQ#>0Y<52kidznJpK6I~L`h0w zNvc(HQ7VvPFfuSS&^0vDH82b@GO#i+wlXo%HZZj^FtC`ZDu<#WH$NpatrDWaz!Izh aq}s~B45H!G^w2dx4Gf;HelF{r5}E+Nxp~R} literal 0 HcmV?d00001 diff --git a/include/images/dnd_none.pngc b/include/images/dnd_none.pngc new file mode 100644 index 0000000..629cf04 --- /dev/null +++ b/include/images/dnd_none.pngc @@ -0,0 +1,90 @@ +#ifndef DND_NONE_PNG_H +#define DND_NONE_PNG_H + +static const unsigned char dnd_none_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x04, 0x03, 0x00, 0x00, 0x00, 0x81, 0x54, 0x67, +0xc7, 0x00, 0x00, 0x00, 0x12, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, +0xde, 0xb3, 0xd2, 0xb4, 0x8c, 0xff, 0x00, 0x00, +0x66, 0x99, 0xff, 0x06, 0x09, 0x80, 0xc5, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x94, 0x49, 0x44, 0x41, +0x54, 0x28, 0xcf, 0x75, 0x90, 0xd1, 0x0d, 0xc3, +0x20, 0x0c, 0x44, 0x3d, 0x02, 0xa4, 0x9d, 0xe0, +0xe2, 0x0e, 0x10, 0xd1, 0x09, 0xe8, 0x06, 0x08, +0xf6, 0x5f, 0xa5, 0x21, 0xb6, 0x0b, 0x31, 0xea, +0x7d, 0x3e, 0x9e, 0x6c, 0x7c, 0x44, 0x14, 0x2d, +0x81, 0x24, 0x1b, 0x34, 0xd1, 0x83, 0x47, 0xf0, +0xe0, 0xf0, 0x20, 0x05, 0x0f, 0x0e, 0x37, 0x54, +0x17, 0x3d, 0x81, 0xd6, 0x83, 0x3d, 0xbd, 0x2f, +0xb0, 0x65, 0x35, 0xf6, 0xf4, 0x11, 0xc0, 0x6a, +0x80, 0x21, 0x00, 0xa6, 0x64, 0x03, 0xa2, 0x14, +0x86, 0x01, 0x55, 0xf2, 0x00, 0xdc, 0x8d, 0x8a, +0x01, 0x2e, 0x25, 0x4f, 0xa0, 0x55, 0x11, 0x86, +0x71, 0x3e, 0xe7, 0x1b, 0x68, 0xb5, 0xb6, 0x72, +0x33, 0x74, 0x91, 0x81, 0xd7, 0x6a, 0xb8, 0x19, +0xeb, 0x16, 0xff, 0x8f, 0xe5, 0xa7, 0xfe, 0x96, +0x2e, 0x94, 0x5e, 0xc7, 0xbf, 0x3e, 0xd8, 0x5a, +0xb6, 0xc6, 0x4c, 0x38, 0x15, 0x6b, 0xfd, 0xa7, +0x4c, 0xb7, 0x60, 0xdc, 0x12, 0xa7, 0x04, 0xfa, +0x02, 0xae, 0xf4, 0x3c, 0xbb, 0xe1, 0x52, 0x5e, +0xa7, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, +0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *dnd_none_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_dnd_none_png = new wxImage(); + if (!img_dnd_none_png || !img_dnd_none_png->IsOk()) + { + wxMemoryInputStream img_dnd_none_pngIS(dnd_none_png_data, sizeof(dnd_none_png_data)); + img_dnd_none_png->LoadFile(img_dnd_none_pngIS, wxBITMAP_TYPE_PNG); + } + return img_dnd_none_png; +} +#define dnd_none_png_img dnd_none_png_img() + +static wxBitmap *dnd_none_png_bmp() +{ + static wxBitmap *bmp_dnd_none_png; + if (!bmp_dnd_none_png || !bmp_dnd_none_png->IsOk()) + bmp_dnd_none_png = new wxBitmap(*dnd_none_png_img); + return bmp_dnd_none_png; +} +#define dnd_none_png_bmp dnd_none_png_bmp() + +static wxIcon *dnd_none_png_ico() +{ + static wxIcon *ico_dnd_none_png; + if (!ico_dnd_none_png || !ico_dnd_none_png->IsOk()) + { + ico_dnd_none_png = new wxIcon(); + ico_dnd_none_png->CopyFromBitmap(*dnd_none_png_bmp); + } + return ico_dnd_none_png; +} +#define dnd_none_png_ico dnd_none_png_ico() + +#endif // DND_NONE_PNG_H diff --git a/include/images/domain-sm.png b/include/images/domain-sm.png new file mode 100644 index 0000000000000000000000000000000000000000..7521cddeaaaf0ee4e3c60e948078d70e17e06893 GIT binary patch literal 401 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}T7XZ8E0Deu9eu*V;gF{0K`pIg zc6K`r4IeIAc}Q3HxV`=3y+@xudUJpGkt2F~PoI5!^78A$Cm(L@JbcYR=;4bm_nv>b z{pkI*?T7D#gyiSvKYR7{_S4Tdo_xOg_;X`|_N7Ok&OiKg_QA)~_dlLo85{w$iLoTe zFPOpM*^M+HhqJ&VvKUBvfU(=jY&#$$$38<+e>KaN2{%0Jd@sMbY$+13Z&%Z<%!P+*SNu+#({Rr={_KxUhswHdID0QWTCBvD z)^ky;@gu`E#RAC#l`JcnelS0rxkKN7b1B>H56gX)0&P<*ag8WRNi0dVN-jzTQVd20 zh6cKZM!E)uAw~vPCdO7KCfWw3Rt5$ZGgakKH00)|WTsU@G#FTdHGouG8JIydoSGiG Q2B?9-)78&qol`;+03_q3ga7~l literal 0 HcmV?d00001 diff --git a/include/images/domain-sm.pngc b/include/images/domain-sm.pngc new file mode 100644 index 0000000..19f4ca1 --- /dev/null +++ b/include/images/domain-sm.pngc @@ -0,0 +1,95 @@ +#ifndef DOMAIN_SM_PNG_H +#define DOMAIN_SM_PNG_H + +static const unsigned char domain_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x66, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xdc, 0x5b, 0x5b, 0xc8, +0x40, 0x40, 0xc2, 0x29, 0x29, 0xc1, 0x2a, 0x2a, +0xc6, 0x3e, 0x3e, 0xb9, 0x31, 0x31, 0xe1, 0xa2, +0xa9, 0xc2, 0x2d, 0x2d, 0xc7, 0x3f, 0x3f, 0xe3, +0xbd, 0xc5, 0xe5, 0xe2, 0xec, 0xdf, 0xbb, 0xc4, +0xc4, 0x2e, 0x2e, 0xe5, 0xe6, 0xf1, 0xe4, 0xe9, +0xf5, 0xe1, 0xe4, 0xf0, 0xda, 0xb9, 0xc3, 0xd6, +0x4f, 0x52, 0xe1, 0xe8, 0xf4, 0xde, 0xe7, 0xf4, +0xdb, 0xe2, 0xef, 0xd6, 0xb7, 0xc3, 0xdc, 0x54, +0x54, 0x6f, 0x6f, 0x6f, 0xe6, 0xea, 0xf5, 0xdb, +0xe5, 0xf3, 0xd8, 0xe4, 0xf3, 0xd5, 0xe3, 0xf3, +0x81, 0x60, 0x2b, 0xd2, 0xe2, 0xf2, 0xcf, 0xe1, +0xf2, 0xcd, 0xe0, 0xf1, 0xcb, 0xdf, 0xf1, 0xc9, +0xa9, 0x53, 0x58, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x62, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x8d, +0xcf, 0xc9, 0x12, 0x40, 0x30, 0x0c, 0x80, 0xe1, +0x2a, 0x62, 0x5f, 0x5b, 0x54, 0x77, 0xef, 0xff, +0x92, 0x6a, 0x86, 0x09, 0x4e, 0xcd, 0xed, 0xff, +0x26, 0x39, 0x84, 0x90, 0xd8, 0x49, 0x7e, 0x4d, +0xd3, 0xec, 0xd3, 0x39, 0x14, 0x50, 0xbe, 0xba, +0x82, 0xba, 0x69, 0xa1, 0xc3, 0x7d, 0xa8, 0xfb, +0x61, 0x9c, 0x80, 0xde, 0x3d, 0x5f, 0xcd, 0xf8, +0xb2, 0xc2, 0x76, 0x8b, 0xd8, 0x43, 0x4b, 0xa5, +0xc5, 0x73, 0x22, 0x06, 0x66, 0x8c, 0xd1, 0x16, +0x81, 0xf1, 0x00, 0xd6, 0x21, 0x70, 0x19, 0xc0, +0x79, 0x04, 0xa9, 0x02, 0xf8, 0x03, 0xe1, 0x99, +0xb8, 0x2f, 0x4f, 0xb3, 0x75, 0x06, 0xdb, 0xf0, +0xa7, 0x4c, 0xa5, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *domain_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_domain_sm_png = new wxImage(); + if (!img_domain_sm_png || !img_domain_sm_png->IsOk()) + { + wxMemoryInputStream img_domain_sm_pngIS(domain_sm_png_data, sizeof(domain_sm_png_data)); + img_domain_sm_png->LoadFile(img_domain_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_domain_sm_png; +} +#define domain_sm_png_img domain_sm_png_img() + +static wxBitmap *domain_sm_png_bmp() +{ + static wxBitmap *bmp_domain_sm_png; + if (!bmp_domain_sm_png || !bmp_domain_sm_png->IsOk()) + bmp_domain_sm_png = new wxBitmap(*domain_sm_png_img); + return bmp_domain_sm_png; +} +#define domain_sm_png_bmp domain_sm_png_bmp() + +static wxIcon *domain_sm_png_ico() +{ + static wxIcon *ico_domain_sm_png; + if (!ico_domain_sm_png || !ico_domain_sm_png->IsOk()) + { + ico_domain_sm_png = new wxIcon(); + ico_domain_sm_png->CopyFromBitmap(*domain_sm_png_bmp); + } + return ico_domain_sm_png; +} +#define domain_sm_png_ico domain_sm_png_ico() + +#endif // DOMAIN_SM_PNG_H diff --git a/include/images/domain.png b/include/images/domain.png new file mode 100644 index 0000000000000000000000000000000000000000..42ca929325854b8f34787425e8094d08c75983bc GIT binary patch literal 424 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}PJmB{E0BJeoqfW=;gF{0PD8^7 zi&s6`bL8oxH}`iRdHU?*lb2r~J^6Th=ix^$zTSWSoH+CHUa^}pVf`aWvMt7fm zx&8F>jfd~AY(HF`mUiRG=W9@QLHo+%PZuA3I{)y~*$1D_JotF({zvHt zo%ulf7)yfuf*Bm1-ADs+I14-?i-EKU7`vU!wgWPXJzX3_Brcbpe=XFcAmSFNeC3q& zl!Z+(RsYN12&-NW{P*^#z0IjbZrS5ICD*275*_bAo)r8t#Vg4A*Lz);xc4JKq03 zXXC}zd)YwiRZCnWN>UO_QmvAUQh^kMk%6IsuAz~xfnkV|ft87|m5GVAfvJ^&fyGQ! qITQ`K`6-!cl@JXEmS7Da)m8>(5DllMhpqu?VDNPHb6Mw<&;$VOR=Fqu literal 0 HcmV?d00001 diff --git a/include/images/domain.pngc b/include/images/domain.pngc new file mode 100644 index 0000000..8ff545c --- /dev/null +++ b/include/images/domain.pngc @@ -0,0 +1,97 @@ +#ifndef DOMAIN_PNG_H +#define DOMAIN_PNG_H + +static const unsigned char domain_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x6c, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xe1, 0x6b, 0x6b, 0xc8, +0x40, 0x40, 0xc2, 0x29, 0x29, 0xb9, 0x31, 0x31, +0xe0, 0xa3, 0xaa, 0xe2, 0xbc, 0xc4, 0xe5, 0xe2, +0xec, 0xdf, 0xbb, 0xc4, 0xe5, 0xe6, 0xf1, 0xe4, +0xe9, 0xf5, 0xe2, 0xe4, 0xf1, 0xdb, 0xb9, 0xc3, +0xe2, 0xe8, 0xf5, 0xdf, 0xe7, 0xf4, 0xdd, 0xe2, +0xf0, 0xd8, 0xb8, 0xc3, 0xf4, 0xcc, 0xcc, 0xe2, +0x70, 0x70, 0xb7, 0x32, 0x32, 0xdd, 0xe6, 0xf4, +0xdb, 0xe5, 0xf3, 0xd8, 0xe1, 0xef, 0xd4, 0xb7, +0xc3, 0x7b, 0x66, 0x66, 0xd8, 0xe4, 0xf3, 0xd6, +0xe4, 0xf3, 0xd4, 0xe0, 0xee, 0x6f, 0x6f, 0x6f, +0x81, 0x60, 0x2b, 0xd4, 0xe3, 0xf2, 0xd1, 0xe2, +0xf2, 0xcf, 0xe1, 0xf2, 0xcd, 0xe0, 0xf2, 0xcc, +0xe0, 0xf1, 0xca, 0xdf, 0xf1, 0x1b, 0xe0, 0x89, +0x6f, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x73, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x75, 0xcf, 0xeb, +0x12, 0x82, 0x20, 0x14, 0x46, 0x51, 0x23, 0xd4, +0xca, 0x3b, 0x94, 0xa1, 0x82, 0x5c, 0x7a, 0xff, +0x77, 0xec, 0x13, 0x25, 0xd3, 0x51, 0xfe, 0xed, +0xc5, 0x39, 0xcc, 0x10, 0x45, 0x27, 0xe7, 0xb2, +0x6b, 0x72, 0x25, 0xdb, 0xa6, 0x31, 0x25, 0x9b, +0x4e, 0xd2, 0xdb, 0x9f, 0xa0, 0xef, 0x8f, 0x2c, +0xff, 0x89, 0xef, 0xa2, 0xac, 0x6a, 0x4a, 0x9a, +0xa9, 0x19, 0xf7, 0xfd, 0x7c, 0xb5, 0x6f, 0xce, +0xfc, 0x84, 0x98, 0xbb, 0xeb, 0x07, 0x31, 0xaf, +0x48, 0xb4, 0x52, 0xaa, 0x1f, 0xb5, 0x5c, 0x00, +0xf7, 0x80, 0x51, 0x9b, 0x00, 0x98, 0x07, 0x68, +0x63, 0x03, 0x60, 0x1f, 0x60, 0xac, 0x0b, 0x80, +0xf7, 0x00, 0xd6, 0x7d, 0x02, 0xac, 0xe7, 0xe8, +0xdb, 0x5f, 0x4f, 0xdf, 0x09, 0x81, 0xd1, 0x85, +0xde, 0x6b, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, +0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *domain_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_domain_png = new wxImage(); + if (!img_domain_png || !img_domain_png->IsOk()) + { + wxMemoryInputStream img_domain_pngIS(domain_png_data, sizeof(domain_png_data)); + img_domain_png->LoadFile(img_domain_pngIS, wxBITMAP_TYPE_PNG); + } + return img_domain_png; +} +#define domain_png_img domain_png_img() + +static wxBitmap *domain_png_bmp() +{ + static wxBitmap *bmp_domain_png; + if (!bmp_domain_png || !bmp_domain_png->IsOk()) + bmp_domain_png = new wxBitmap(*domain_png_img); + return bmp_domain_png; +} +#define domain_png_bmp domain_png_bmp() + +static wxIcon *domain_png_ico() +{ + static wxIcon *ico_domain_png; + if (!ico_domain_png || !ico_domain_png->IsOk()) + { + ico_domain_png = new wxIcon(); + ico_domain_png->CopyFromBitmap(*domain_png_bmp); + } + return ico_domain_png; +} +#define domain_png_ico domain_png_ico() + +#endif // DOMAIN_PNG_H diff --git a/include/images/domains.png b/include/images/domains.png new file mode 100644 index 0000000000000000000000000000000000000000..55621528a1dba4928538fe5557b9b988ed78d6ab GIT binary patch literal 462 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}U4T!BE0BJeoqfW=;gF{0PD8_o zi&pN_(K)B7`FPi%2ix`@v9LU(tNUQ*!K1czXOxuggoGT_(#p@zf4Jw!!zHV)`3F7T zd-Um}H}`iRIijcc@Wq#>&ptkR`SszG54Uz6zW4mg?MLsgZ9jbb>E~y!zTSB9`Re1( zjS1S99(_9h@YC4`A5Y)^_^>@J3+MvIk|4ie28U-i(tsS!0*}aIAngIhZYQ(tfQ)ue z7sn8Z%b|U@#hMgESUvs4wKoSxO>~{O=-Yq$8_!r)-^e%4-l6f-Jox1%8}FIVx>FCW zPMVwluQGbkP1bcSwVV0d_?PZbZVis%HeYTWyU*$OvYp$uTc3QLbD?2trOnDuhZa>f z=3d_{(zER9xt(yDRyg$uoE8Qx}bo1D0qw;t#u)e_f; zl9a@fRIB8oR3OD*WMF8ZYiOivU>IU#U}a)#Wn!XjU}|MxU@=ow4n;$5eoAIqB}9XP eC0GMUwUvPxM8m1+p=*E|7(8A5T-G@yGywoRCC2Lj literal 0 HcmV?d00001 diff --git a/include/images/domains.pngc b/include/images/domains.pngc new file mode 100644 index 0000000..777d8f1 --- /dev/null +++ b/include/images/domains.pngc @@ -0,0 +1,102 @@ +#ifndef DOMAINS_PNG_H +#define DOMAINS_PNG_H + +static const unsigned char domains_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x7e, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xe1, 0x6b, 0x6b, 0xc8, +0x40, 0x40, 0xc2, 0x29, 0x29, 0xb9, 0x31, 0x31, +0xe1, 0xa2, 0xa9, 0xbe, 0x2c, 0x2c, 0xce, 0x29, +0x29, 0xe3, 0xba, 0xc2, 0xe0, 0xb6, 0xbd, 0xc4, +0x38, 0x39, 0xc2, 0x2d, 0x2d, 0xe0, 0xb9, 0xc1, +0xc5, 0x3d, 0x3e, 0xcc, 0x22, 0x22, 0xdc, 0x54, +0x54, 0xc1, 0x2a, 0x2a, 0x6f, 0x6f, 0x6f, 0xe1, +0xbc, 0xc4, 0xe1, 0xa4, 0xab, 0xd6, 0x4f, 0x52, +0xe3, 0xbd, 0xc5, 0xe5, 0xe2, 0xec, 0xdf, 0xbb, +0xc4, 0xc4, 0x2e, 0x2e, 0xe1, 0xe8, 0xf4, 0xe5, +0xe6, 0xf1, 0xe4, 0xe9, 0xf5, 0xe1, 0xe4, 0xf0, +0xda, 0xb9, 0xc3, 0xde, 0xe7, 0xf4, 0xdb, 0xe2, +0xef, 0xd6, 0xb7, 0xc3, 0xdb, 0xe5, 0xf3, 0xe6, +0xea, 0xf5, 0xd8, 0xe4, 0xf3, 0xd5, 0xe3, 0xf3, +0x81, 0x60, 0x2b, 0xd2, 0xe2, 0xf2, 0xcf, 0xe1, +0xf2, 0xcd, 0xe0, 0xf1, 0xcb, 0xdf, 0xf1, 0xe1, +0x87, 0x56, 0x6a, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x87, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x55, +0x8e, 0xdb, 0x16, 0x82, 0x20, 0x14, 0x05, 0x49, +0x4f, 0x17, 0x2b, 0xb3, 0x53, 0x5a, 0x91, 0x45, +0x91, 0xa2, 0xf6, 0xff, 0x3f, 0xd8, 0xe6, 0x04, +0xab, 0xd8, 0x6f, 0x33, 0x6b, 0xb8, 0x28, 0xe5, +0x37, 0x53, 0xe9, 0xb2, 0x3c, 0x4b, 0x99, 0xe6, +0x8b, 0x65, 0xc2, 0xab, 0x62, 0x9d, 0x6f, 0xfe, +0x79, 0x5b, 0xa2, 0xd9, 0x05, 0xae, 0x84, 0x7d, +0xb3, 0x0f, 0x86, 0x0f, 0xa5, 0xb8, 0x23, 0x85, +0x53, 0x5c, 0x0b, 0x37, 0xa7, 0x33, 0x5d, 0xbe, +0x42, 0xfb, 0xa6, 0xb9, 0xb6, 0xb7, 0x3b, 0xc9, +0xeb, 0x6c, 0xd0, 0x80, 0xb5, 0x79, 0x3c, 0xa9, +0xf2, 0xc2, 0xa2, 0x79, 0x81, 0x6d, 0xd7, 0xb3, +0x14, 0x8c, 0xa6, 0xd5, 0xce, 0xb9, 0x7e, 0xe0, +0x70, 0x2d, 0x1a, 0x03, 0x31, 0x8c, 0x51, 0xa0, +0xb1, 0x10, 0xe3, 0xc4, 0xf1, 0xb7, 0x6c, 0x3b, +0x88, 0xe9, 0xfd, 0x13, 0x71, 0x4a, 0x7d, 0x00, +0xed, 0x6a, 0x0b, 0x34, 0xc8, 0xd1, 0x6e, 0xaf, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, +0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *domains_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_domains_png = new wxImage(); + if (!img_domains_png || !img_domains_png->IsOk()) + { + wxMemoryInputStream img_domains_pngIS(domains_png_data, sizeof(domains_png_data)); + img_domains_png->LoadFile(img_domains_pngIS, wxBITMAP_TYPE_PNG); + } + return img_domains_png; +} +#define domains_png_img domains_png_img() + +static wxBitmap *domains_png_bmp() +{ + static wxBitmap *bmp_domains_png; + if (!bmp_domains_png || !bmp_domains_png->IsOk()) + bmp_domains_png = new wxBitmap(*domains_png_img); + return bmp_domains_png; +} +#define domains_png_bmp domains_png_bmp() + +static wxIcon *domains_png_ico() +{ + static wxIcon *ico_domains_png; + if (!ico_domains_png || !ico_domains_png->IsOk()) + { + ico_domains_png = new wxIcon(); + ico_domains_png->CopyFromBitmap(*domains_png_bmp); + } + return ico_domains_png; +} +#define domains_png_ico domains_png_ico() + +#endif // DOMAINS_PNG_H diff --git a/include/images/down.png b/include/images/down.png new file mode 100644 index 0000000000000000000000000000000000000000..4850c67698c0228a82247d37067a95ed76641233 GIT binary patch literal 388 zcmeAS@N?(olHy`uVBq!ia0vp@K+M6x3?xN=wEhKBMFBn`u0XnbV`9{7;d2j`@4DQ$ z>0IH4vpMTdr>{MowEAS+suNKwPlT;MlYI16@2)GY^A874-|H}Sx8e!&b5&u*jvIh+L^k;OpT1B~5HX4?T7o}Mm_Asp9TPrCCp81S$L z-fp>9{l4J8_N4V3sb&7oI%aBxQ(pgclsM|Cb!5_0*T}2Bw_h&5$^Y0yUz;KCcVQgc zf?f0FA7nF1)$9ym`d{^K<`kfzswJ)wB`Jv|saDBFsX&Us$iUE0*T7KM$TY;z)XKoz z%GgZXz|6|PV4vKj`6wE4^HVa@DnS|ybPX(Z4J<+o46O`|txPQ;8ZwSe<^gJ8@O1Ta JS?83{1OP(|l$8Jg literal 0 HcmV?d00001 diff --git a/include/images/down.pngc b/include/images/down.pngc new file mode 100644 index 0000000..3da1e4e --- /dev/null +++ b/include/images/down.pngc @@ -0,0 +1,93 @@ +#ifndef DOWN_PNG_H +#define DOWN_PNG_H + +static const unsigned char down_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x08, +0x08, 0x03, 0x00, 0x00, 0x00, 0x15, 0xf8, 0x85, +0xfd, 0x00, 0x00, 0x00, 0x72, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x61, 0x5a, +0x9b, 0x13, 0xce, 0xe0, 0xa7, 0xba, 0xd3, 0x81, +0xb2, 0xce, 0x71, 0xb0, 0xcd, 0x6c, 0xae, 0xcb, +0x67, 0xad, 0xcb, 0x62, 0xab, 0xc9, 0x5e, 0xaa, +0xc8, 0x5a, 0xa9, 0xc8, 0x56, 0xaf, 0xcc, 0x63, +0xc5, 0xda, 0x8d, 0xba, 0xd4, 0x85, 0x9f, 0xc3, +0x53, 0x97, 0xbd, 0x40, 0x95, 0xbb, 0x39, 0x92, +0xba, 0x33, 0x90, 0xb8, 0x2c, 0x8e, 0xb7, 0x26, +0x94, 0xbb, 0x2f, 0xaf, 0xcc, 0x64, 0xba, 0xd4, +0x83, 0x9f, 0xc2, 0x51, 0x96, 0xbd, 0x3e, 0x94, +0xbb, 0x38, 0x92, 0xb9, 0x31, 0x97, 0xbc, 0x38, +0xb1, 0xcd, 0x69, 0xba, 0xd3, 0x83, 0x9e, 0xc2, +0x4f, 0x96, 0xbc, 0x3d, 0x9b, 0xbf, 0x43, 0xb4, +0xcf, 0x70, 0xa5, 0xc5, 0x5a, 0xb6, 0xd1, 0x78, +0xcc, 0xdf, 0xa3, 0x6d, 0x2e, 0x72, 0xd0, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x49, 0x49, 0x44, 0x41, +0x54, 0x08, 0xd7, 0x45, 0xc9, 0x47, 0x0e, 0x80, +0x30, 0x0c, 0x05, 0x51, 0xdb, 0x84, 0xde, 0x7b, +0xef, 0x70, 0xff, 0x2b, 0x92, 0xaf, 0x08, 0x65, +0x76, 0x4f, 0x43, 0x2c, 0x36, 0x26, 0x71, 0x94, +0xeb, 0xf9, 0x41, 0x18, 0xc5, 0x49, 0x2a, 0xc4, +0x92, 0xe5, 0x45, 0x59, 0xd5, 0x4d, 0xdb, 0xe9, +0xa7, 0xd9, 0x0f, 0xe3, 0x34, 0x2f, 0x2b, 0x00, +0x6e, 0xfb, 0x71, 0x5e, 0x06, 0xa0, 0xba, 0x9f, +0x1f, 0xe0, 0x6b, 0x01, 0x1a, 0x7c, 0xb9, 0x54, +0x02, 0xff, 0x7a, 0xee, 0x99, 0x94, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x31, 0x2d, 0x30, +0x31, 0x2d, 0x32, 0x35, 0x54, 0x31, 0x35, 0x3a, +0x30, 0x37, 0x3a, 0x33, 0x36, 0x2b, 0x30, 0x36, +0x3a, 0x30, 0x30, 0xbe, 0x1e, 0xd2, 0x9f, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x38, 0x54, 0x30, 0x31, +0x3a, 0x30, 0x33, 0x3a, 0x35, 0x39, 0x2b, 0x30, +0x36, 0x3a, 0x30, 0x30, 0x68, 0xc6, 0x93, 0x0c, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *down_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_down_png = new wxImage(); + if (!img_down_png || !img_down_png->IsOk()) + { + wxMemoryInputStream img_down_pngIS(down_png_data, sizeof(down_png_data)); + img_down_png->LoadFile(img_down_pngIS, wxBITMAP_TYPE_PNG); + } + return img_down_png; +} +#define down_png_img down_png_img() + +static wxBitmap *down_png_bmp() +{ + static wxBitmap *bmp_down_png; + if (!bmp_down_png || !bmp_down_png->IsOk()) + bmp_down_png = new wxBitmap(*down_png_img); + return bmp_down_png; +} +#define down_png_bmp down_png_bmp() + +static wxIcon *down_png_ico() +{ + static wxIcon *ico_down_png; + if (!ico_down_png || !ico_down_png->IsOk()) + { + ico_down_png = new wxIcon(); + ico_down_png->CopyFromBitmap(*down_png_bmp); + } + return ico_down_png; +} +#define down_png_ico down_png_ico() + +#endif // DOWN_PNG_H diff --git a/include/images/drop.png b/include/images/drop.png new file mode 100644 index 0000000000000000000000000000000000000000..45bd85b1bc4a19d1fc9be9621643662d0cb74306 GIT binary patch literal 919 zcmV;I18Dq-P)gw?D@b&fe?d|R3(M!HrIyHN(}tMwK$w+SH}QoRPVOcC2Q)%eBVWz%PjzjIo2T z#j2~orpeF8&eF}v&d5}lM8V3wwZXGvpH-#2pTNexg40x|00001bW%=J06^y0W&i*H z32;bRa{vGUNB{r;NB~C3Yd!z~0uD(;K~y-)jg#3{qd*izQ!_&aQZwKXAu(c%f}OP5 z4(%|_;U2~&kolK3HP5UA1xt#E>rN|i#1#-yUGC@`Xf zP^I})s$?t~g_2rvJ5|*nXq_LE`OIds>6sBm>qE&Z&-P$Xrk)uigtewRlyvMHpI=;D z&IfFPDcm5K_<%33uCD63Su6tvK*Z*-hyv{S*`ltm7j@IDZa_#|jGLq|3lG0td*RNH zXl{XDmQ3j=;3V_i=APF#V%0R8`@p5fqku>jx<6dkE4%Dgediwiwk1KMP_pdo{PNG; zyt}txxs(r^P3u~~%25#U%!t0OyU-oTe!Jc7+7`s(`+G;$oQDQ;86N)E3k_^tbUX-J zin-_gL+IvQ81cl9FEN=AWWcIk5BT}z-)8&z#uIWB5^O-%FZxyAKezpE*T43qBgx6l zQ6cB+#;>S(d)kJ)Lr39JkdcwHYeF7B0{?)}Me^jTV=LXu+Vk!E|6xGt;?uKdP`dW5 z>$=@1{MhY0hbcQ1DkQm2=>tDi>H|@ADrgM$7={F%a;#4UOR)4af{+G>b4=`yf6ro8 zX#}~Gu1t}x3jCA%aD=P<-AAm#i2v@N{#CvJ&{Q}~4R2uc0000bbVXQnWMOn=I%9HW zVRU5xGB7bPEip1JFfmjzFgi3dIy5vZFf}?bFgTed9smFUC3HntbYx+4WjbwdWNBu3 t05UK!FfA}SEif@uGBY|fG&(RgD=;-WFfhuORjdF2002ovPDHLkV1m%x!F~V$ literal 0 HcmV?d00001 diff --git a/include/images/drop.pngc b/include/images/drop.pngc new file mode 100644 index 0000000..f884583 --- /dev/null +++ b/include/images/drop.pngc @@ -0,0 +1,159 @@ +#ifndef DROP_PNG_H +#define DROP_PNG_H + +static const unsigned char drop_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x08, 0x03, 0x00, 0x00, 0x00, 0x44, 0xa4, 0x8a, +0xc6, 0x00, 0x00, 0x00, 0xc0, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xdd, 0xdd, 0xdd, 0xc9, +0xc9, 0xc9, 0xb9, 0xb9, 0xb9, 0xa5, 0xa5, 0xa5, +0x9d, 0x9d, 0x9d, 0x8b, 0x8b, 0x8b, 0x83, 0x83, +0x83, 0x76, 0x76, 0x76, 0x6c, 0x6c, 0x6c, 0xb2, +0xb2, 0xb2, 0xc5, 0xc5, 0xc5, 0xd1, 0xd1, 0xd1, +0xea, 0xea, 0xea, 0xf0, 0xf0, 0xf0, 0xf5, 0xf5, +0xf5, 0xed, 0xed, 0xed, 0xe3, 0xe4, 0xe3, 0xd9, +0xd9, 0xd9, 0xc0, 0xc0, 0xc0, 0xac, 0xac, 0xac, +0xe6, 0xe6, 0xe6, 0xe1, 0xe1, 0xe1, 0xd5, 0xd5, +0xd5, 0x7d, 0x7d, 0x7d, 0xcd, 0xcd, 0xcd, 0x95, +0x95, 0x95, 0xe8, 0xe8, 0xe8, 0xda, 0xe1, 0xd8, +0xc9, 0xdb, 0xc4, 0xc7, 0xd9, 0xc1, 0xcf, 0xda, +0xcc, 0x6b, 0xad, 0x54, 0x46, 0x9b, 0x2b, 0x3b, +0x92, 0x22, 0x5e, 0xa6, 0x48, 0xdb, 0xde, 0xda, +0x53, 0xa2, 0x39, 0x82, 0xb3, 0x74, 0xb2, 0xcb, +0xaa, 0xd3, 0xd3, 0xd3, 0x9a, 0xc1, 0x8d, 0x4e, +0x9e, 0x35, 0xc3, 0xd5, 0xbd, 0x46, 0x95, 0x32, +0xd6, 0xda, 0xd4, 0xa5, 0xc4, 0x9c, 0x91, 0xb9, +0x85, 0x76, 0xac, 0x66, 0xba, 0xcb, 0xb5, 0xc6, +0xd7, 0xc0, 0x2f, 0x89, 0x19, 0x8c, 0xb1, 0x83, +0xb0, 0xc5, 0xaa, 0xab, 0xc0, 0xa6, 0xc9, 0xcf, +0xc7, 0xce, 0xd2, 0xcd, 0xc9, 0xce, 0xc8, 0x54, +0x98, 0x44, 0xc1, 0xca, 0xbe, 0xb5, 0xc1, 0xb3, +0x63, 0x9f, 0x55, 0xa5, 0xbc, 0x9f, 0xc0, 0xc6, +0xbe, 0x82, 0xd3, 0x54, 0xa7, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0x0e, 0x49, 0x44, 0x41, 0x54, 0x38, +0xcb, 0x8d, 0x93, 0xd9, 0x56, 0xa3, 0x40, 0x14, +0x45, 0x53, 0x33, 0x43, 0x05, 0x52, 0x33, 0xe0, +0x10, 0x21, 0x31, 0x62, 0x8c, 0x82, 0x9d, 0xb4, +0xda, 0x0e, 0xed, 0xff, 0xff, 0x95, 0x55, 0x21, +0x98, 0xf8, 0xe6, 0x79, 0xdd, 0x7b, 0x5d, 0x0e, +0x97, 0xcb, 0x64, 0xf2, 0xab, 0x00, 0x88, 0x30, +0xa1, 0x2c, 0x8a, 0x43, 0x22, 0x46, 0x09, 0x46, +0x10, 0x1c, 0x31, 0x24, 0x11, 0x25, 0x49, 0xca, +0xc1, 0x34, 0xcb, 0xf3, 0x7c, 0x26, 0x24, 0x54, +0x9a, 0xd0, 0x08, 0xc3, 0x03, 0x57, 0x0c, 0x89, +0x7c, 0x9f, 0x6c, 0x36, 0x35, 0xc2, 0x02, 0x29, +0x9d, 0xe3, 0x3c, 0xd5, 0x85, 0x1a, 0x04, 0x46, +0x91, 0xcd, 0x46, 0xe6, 0x78, 0x09, 0x53, 0x85, +0x50, 0x92, 0xf8, 0x21, 0x6c, 0x10, 0xa8, 0xd2, +0x05, 0xad, 0x70, 0x82, 0x94, 0x4a, 0x95, 0x42, +0x89, 0xc6, 0xa4, 0xa2, 0xac, 0x28, 0x30, 0xa2, +0x83, 0x50, 0xa5, 0xf9, 0x54, 0xaa, 0x64, 0x2c, +0x19, 0x85, 0x92, 0x5a, 0x71, 0x3b, 0x55, 0xd5, +0x20, 0x68, 0x9d, 0x1f, 0x93, 0xf9, 0xcc, 0x66, +0xb3, 0xe9, 0x99, 0x11, 0x46, 0xeb, 0x43, 0xc9, +0x2a, 0xcf, 0xf6, 0x60, 0x4f, 0xa6, 0x9e, 0x19, +0x23, 0x84, 0xb5, 0xa6, 0x3a, 0x94, 0x74, 0xec, +0x1b, 0x9f, 0x5f, 0x5c, 0x5c, 0xce, 0x07, 0x6c, +0x81, 0x29, 0xdc, 0x20, 0x98, 0xf8, 0x80, 0x2f, +0xaf, 0xae, 0xae, 0xea, 0xba, 0x59, 0x2c, 0x03, +0x06, 0x40, 0xc4, 0xe6, 0xb0, 0x88, 0x02, 0xec, +0xf9, 0xd9, 0xa2, 0xae, 0xaf, 0x17, 0x75, 0xd3, +0xac, 0x6e, 0x40, 0x48, 0x5b, 0x8c, 0x9b, 0xa4, +0x30, 0x0b, 0x0f, 0xbf, 0x5d, 0x7b, 0xe1, 0xce, +0x8f, 0x68, 0x6e, 0x81, 0x5f, 0x96, 0x4c, 0xe9, +0x28, 0xe0, 0x24, 0xf3, 0xdd, 0xe6, 0x9e, 0xd7, +0x37, 0x62, 0xd5, 0x34, 0x9b, 0xfb, 0xc0, 0xa5, +0xc6, 0xa3, 0x80, 0x48, 0x16, 0xba, 0x3f, 0x5c, +0xd7, 0x2b, 0xbb, 0xec, 0x56, 0x7d, 0xe7, 0x1e, +0xfd, 0xb6, 0x25, 0x41, 0xa3, 0x50, 0xb2, 0xec, +0xec, 0xfc, 0xf2, 0xcf, 0xdd, 0xbc, 0xbb, 0xb7, +0x60, 0xb9, 0x94, 0x0f, 0x9b, 0x4d, 0xeb, 0x5a, +0xc0, 0xca, 0x51, 0x10, 0xf1, 0xcc, 0x88, 0xbe, +0xae, 0xbb, 0xd0, 0x1d, 0xc8, 0x7e, 0xbb, 0xdd, +0xee, 0xda, 0x16, 0xc4, 0xe2, 0xfb, 0x7b, 0x47, +0xd6, 0x9c, 0x87, 0x06, 0x73, 0x19, 0x1e, 0xfe, +0xd7, 0x0b, 0x0d, 0x6c, 0x5d, 0x74, 0x3c, 0x08, +0x5a, 0x8a, 0xb9, 0xe7, 0xfd, 0x43, 0xe8, 0xe6, +0x5c, 0x18, 0xf1, 0xc4, 0x8f, 0x2f, 0x31, 0x99, +0x10, 0x64, 0xc0, 0xaa, 0x5e, 0x0f, 0xf8, 0xf9, +0xe5, 0xdf, 0x66, 0xfb, 0xfa, 0xc6, 0x13, 0x72, +0x14, 0x12, 0x6c, 0x40, 0xd7, 0x2f, 0xfa, 0x55, +0xdf, 0x3f, 0xb7, 0xfd, 0x6e, 0xd7, 0xbf, 0xf6, +0xa5, 0x23, 0xc9, 0xc9, 0xcd, 0x51, 0x21, 0xe7, +0xeb, 0xc6, 0xaf, 0xa8, 0x79, 0x7b, 0xda, 0x86, +0xbc, 0x43, 0x47, 0xe1, 0x51, 0x90, 0x91, 0x91, +0xb2, 0x6b, 0x42, 0x1e, 0x3f, 0x02, 0xff, 0x80, +0xd0, 0x45, 0xf2, 0xe4, 0xaa, 0x63, 0x2b, 0xdd, +0xcb, 0xda, 0xf3, 0xed, 0xfb, 0xff, 0x61, 0x40, +0xea, 0xe2, 0xd3, 0xb3, 0x67, 0x50, 0xba, 0xf6, +0xad, 0xeb, 0xba, 0xdd, 0x27, 0xfc, 0xd8, 0xed, +0x3c, 0x87, 0x29, 0x3b, 0x15, 0x2a, 0x24, 0xb9, +0x4f, 0xe9, 0x03, 0x3f, 0x55, 0xea, 0x03, 0x51, +0x75, 0x2a, 0x68, 0x0c, 0xf6, 0x18, 0x86, 0x04, +0x9e, 0x72, 0xac, 0x4f, 0x05, 0x4b, 0xb0, 0xf4, +0x33, 0x82, 0x90, 0x06, 0x87, 0x73, 0x4c, 0xec, +0x8f, 0x7f, 0xcf, 0x62, 0x56, 0x69, 0x04, 0xb9, +0x93, 0xae, 0x4c, 0x91, 0xae, 0x0a, 0xfc, 0x93, +0xfb, 0x70, 0x84, 0xab, 0xfd, 0xdd, 0x47, 0xac, +0xc2, 0x88, 0xff, 0xee, 0x9f, 0xfe, 0x55, 0xbe, +0x00, 0xd0, 0x54, 0x38, 0x4c, 0x0d, 0x6f, 0x60, +0xf3, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, +0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *drop_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_drop_png = new wxImage(); + if (!img_drop_png || !img_drop_png->IsOk()) + { + wxMemoryInputStream img_drop_pngIS(drop_png_data, sizeof(drop_png_data)); + img_drop_png->LoadFile(img_drop_pngIS, wxBITMAP_TYPE_PNG); + } + return img_drop_png; +} +#define drop_png_img drop_png_img() + +static wxBitmap *drop_png_bmp() +{ + static wxBitmap *bmp_drop_png; + if (!bmp_drop_png || !bmp_drop_png->IsOk()) + bmp_drop_png = new wxBitmap(*drop_png_img); + return bmp_drop_png; +} +#define drop_png_bmp drop_png_bmp() + +static wxIcon *drop_png_ico() +{ + static wxIcon *ico_drop_png; + if (!ico_drop_png || !ico_drop_png->IsOk()) + { + ico_drop_png = new wxIcon(); + ico_drop_png->CopyFromBitmap(*drop_png_bmp); + } + return ico_drop_png; +} +#define drop_png_ico drop_png_ico() + +#endif // DROP_PNG_H diff --git a/include/images/edit_clear.png b/include/images/edit_clear.png new file mode 100644 index 0000000000000000000000000000000000000000..7dae00b2f09914a1b06a3bf1cbe5a12d11e6409e GIT binary patch literal 621 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47&!ubLR^8|y1KeuyLQc-Idj&m znah_iKX&Zcf&~jEOqg)-;`ujkUbeTlH#IdKII!>I#}BVwy?pud`M!O->+9<`ZQ8Vc z{kqq$U%q?y_Qi`Aj~_pN`0&A#Cl4n~=-<0{@0>Yv=FXja@7~?luU|iZ{`~&^`*-f# zxqJ7{nKQ>{%$Tuo;lkeD-t*_ref|37{rh*XUcI^j0@s1YtXsG4$B%EHKYzM;^XBc_ zHy=H^w`eUN# z=FFNsd-k3^dp2y?uwcRbCr_R{c<|uSqlXV4-d($P)y9n*&!0c@{Q1)tFP`q(x2w6i z>B5CG6DLkMdi3bdojXr+s*3}|g0UpXFPOpM*^M+HhqJ&VvKUBvfU(=jY&#%hj;D)b zh{WaOgagbHfjfQ9=&bRGF)QQq)5|lnm_N0BdVjn_0LLlOX99wv!qX>AnUuyIsOk()) + { + wxMemoryInputStream img_edit_clear_pngIS(edit_clear_png_data, sizeof(edit_clear_png_data)); + img_edit_clear_png->LoadFile(img_edit_clear_pngIS, wxBITMAP_TYPE_PNG); + } + return img_edit_clear_png; +} +#define edit_clear_png_img edit_clear_png_img() + +static wxBitmap *edit_clear_png_bmp() +{ + static wxBitmap *bmp_edit_clear_png; + if (!bmp_edit_clear_png || !bmp_edit_clear_png->IsOk()) + bmp_edit_clear_png = new wxBitmap(*edit_clear_png_img); + return bmp_edit_clear_png; +} +#define edit_clear_png_bmp edit_clear_png_bmp() + +static wxIcon *edit_clear_png_ico() +{ + static wxIcon *ico_edit_clear_png; + if (!ico_edit_clear_png || !ico_edit_clear_png->IsOk()) + { + ico_edit_clear_png = new wxIcon(); + ico_edit_clear_png->CopyFromBitmap(*edit_clear_png_bmp); + } + return ico_edit_clear_png; +} +#define edit_clear_png_ico edit_clear_png_ico() + +#endif // EDIT_CLEAR_PNG_H diff --git a/include/images/edit_find.png b/include/images/edit_find.png new file mode 100644 index 0000000000000000000000000000000000000000..1c3b4fce485fe9df64ee6cea7007b97358673861 GIT binary patch literal 657 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47^MPyLR^8|g9i`Jm@%WYv@|X* zZp)S}dHMNESFAj9`TFCJ-%eh>zIge{L&r~k`0?lGpMO98{Cn~3_pJ{*Zo^5-pEvFrS`6ED7OKX+};(iP1GqCE}4 z=Pn#Oy2ARHx-#gcSj-uptVCXQG1o;IsI6S+N z2IO!SctjQhX%8@VJDF_W)6?wr_|y9c)IsII80{QcwCPxc*+cOS}0 zJQ2)E=PF-Wo#2r%qh0sT#dnPl1t&JXE3k7;2r1z)l3$@D*2*vB_>h@l<3@=N-Ka}a zK$okQxJHzuB$lLFB^RXvDF!10LjzqyBV7Z-5F-OC6JskA6Kw-iD+2?InW}Oq8glbf kGSey{8VoGK8bGS849p-JPE8M81JuCa>FVdQ&MBb@0LF|;K>z>% literal 0 HcmV?d00001 diff --git a/include/images/edit_find.pngc b/include/images/edit_find.pngc new file mode 100644 index 0000000..e184cd9 --- /dev/null +++ b/include/images/edit_find.pngc @@ -0,0 +1,127 @@ +#ifndef EDIT_FIND_PNG_H +#define EDIT_FIND_PNG_H + +static const unsigned char edit_find_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x1a, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc1, 0xc1, 0xc1, 0x98, +0x98, 0x98, 0x75, 0x75, 0x75, 0x5e, 0x5e, 0x5e, +0xb4, 0xb4, 0xb4, 0x6e, 0x6f, 0x6f, 0xa5, 0xa8, +0xa9, 0xcc, 0xd3, 0xd7, 0xe3, 0xf1, 0xf6, 0xc9, +0xd3, 0xd7, 0xa3, 0xa7, 0xa9, 0xc2, 0xc7, 0xc9, +0xf0, 0xf8, 0xfc, 0xf9, 0xfc, 0xfe, 0xf8, 0xfc, +0xfe, 0xe8, 0xf6, 0xfb, 0xda, 0xf0, 0xf8, 0xb6, +0xbf, 0xc3, 0x6d, 0x6f, 0x6f, 0xa4, 0xa8, 0xa9, +0xef, 0xf8, 0xfc, 0xfb, 0xfd, 0xfe, 0xe6, 0xf4, +0xfa, 0xd3, 0xed, 0xf7, 0xcf, 0xec, 0xf7, 0xd2, +0xee, 0xf8, 0xcd, 0xec, 0xf7, 0xa0, 0xa6, 0xa9, +0xca, 0xd3, 0xd7, 0xe5, 0xf4, 0xfa, 0xc8, 0xe9, +0xf5, 0xc4, 0xe8, 0xf5, 0xbf, 0xe6, 0xf4, 0xbb, +0xe5, 0xf4, 0xbc, 0xe6, 0xf5, 0xbe, 0xcf, 0xd6, +0xe0, 0xef, 0xf6, 0xf7, 0xfc, 0xfd, 0xc1, 0xe7, +0xf5, 0xbd, 0xe6, 0xf4, 0xb8, 0xe4, 0xf4, 0xb4, +0xe3, 0xf4, 0xb2, 0xe3, 0xf4, 0xcd, 0xea, 0xf4, +0xc6, 0xd2, 0xd6, 0xe4, 0xf5, 0xfb, 0xca, 0xea, +0xf6, 0xb6, 0xe4, 0xf4, 0xb2, 0xe2, 0xf3, 0xad, +0xe1, 0xf3, 0xb0, 0xe3, 0xf4, 0xb9, 0xcf, 0xd6, +0x6c, 0x6b, 0x5f, 0xa1, 0xa7, 0xa9, 0xcb, 0xec, +0xf7, 0xaf, 0xe2, 0xf3, 0xab, 0xe1, 0xf3, 0xaa, +0xe0, 0xf2, 0xba, 0xe6, 0xf5, 0x9d, 0xa5, 0xa8, +0x90, 0x90, 0x90, 0x63, 0x63, 0x63, 0xb2, 0xbe, +0xc3, 0xc5, 0xe9, 0xf6, 0xb4, 0xe4, 0xf4, 0xad, +0xe1, 0xf4, 0xad, 0xe2, 0xf3, 0xb8, 0xe6, 0xf5, +0xad, 0xbd, 0xc2, 0x6c, 0x6e, 0x6f, 0xa3, 0x98, +0x62, 0x64, 0x64, 0x64, 0xa1, 0xa5, 0x94, 0x76, +0x7a, 0x77, 0x6d, 0x6e, 0x6f, 0x9e, 0xa6, 0xa8, +0xba, 0xcf, 0xd6, 0xc8, 0xe8, 0xf4, 0xb7, 0xce, +0xd6, 0x9c, 0xa5, 0xa8, 0x83, 0x70, 0x15, 0x8c, +0x80, 0x53, 0xce, 0xd0, 0xc6, 0xc5, 0xa8, 0x3b, +0xc2, 0xa3, 0x3d, 0x89, 0x7c, 0x54, 0xc4, 0xa7, +0x3b, 0xc1, 0xa3, 0x3d, 0xbe, 0x9f, 0x3f, 0xc4, +0xa6, 0x3c, 0xc1, 0xa2, 0x3d, 0xbe, 0x9e, 0x3f, +0xbd, 0x9d, 0x3f, 0x9c, 0x21, 0x19, 0xb7, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0xae, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x63, 0x60, 0x80, 0x00, 0x46, +0x26, 0x66, 0x16, 0x66, 0x26, 0x46, 0x06, 0x18, +0x60, 0x65, 0x63, 0xe7, 0xe0, 0xe4, 0xe2, 0x66, +0x63, 0x85, 0xc9, 0xb3, 0xf1, 0xf0, 0xf2, 0xf1, +0x0b, 0x08, 0x0a, 0x09, 0x43, 0xd5, 0x30, 0x89, +0x88, 0x8a, 0x89, 0x4b, 0x48, 0x4a, 0x49, 0xcb, +0x30, 0x41, 0x04, 0x98, 0x65, 0xf9, 0xe5, 0xe4, +0x15, 0x14, 0x95, 0x94, 0x55, 0x98, 0x21, 0x02, +0x2c, 0xaa, 0x6a, 0x92, 0xea, 0x1a, 0x9a, 0x5a, +0xda, 0x3a, 0x2c, 0x50, 0x15, 0xba, 0x7a, 0xfa, +0x4a, 0x06, 0x86, 0x46, 0xc6, 0x26, 0x50, 0x15, +0xa6, 0x66, 0x52, 0xe6, 0x5a, 0x16, 0x96, 0x56, +0xd6, 0x36, 0x10, 0x33, 0x6c, 0xed, 0x84, 0xed, +0x1d, 0x1c, 0x9d, 0x9c, 0x5d, 0x5c, 0xdd, 0xc0, +0xb6, 0xb8, 0x7b, 0x78, 0x7a, 0x79, 0xfb, 0xf8, +0xfa, 0xf9, 0x07, 0xb8, 0x81, 0xdd, 0xe1, 0x1e, +0x18, 0xe4, 0x11, 0x6c, 0x67, 0x0a, 0x77, 0xa9, +0x7b, 0x60, 0x48, 0x68, 0x98, 0x87, 0x2d, 0xdc, +0xd1, 0xee, 0x81, 0xe1, 0x11, 0x91, 0x81, 0xee, +0x70, 0x3e, 0x43, 0x60, 0x54, 0x74, 0x0c, 0x32, +0x1f, 0xa8, 0x22, 0x16, 0x85, 0x0f, 0x12, 0x41, +0xe1, 0x03, 0x00, 0xb1, 0xb1, 0x18, 0x88, 0x2d, +0x5a, 0xd2, 0x1a, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *edit_find_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_edit_find_png = new wxImage(); + if (!img_edit_find_png || !img_edit_find_png->IsOk()) + { + wxMemoryInputStream img_edit_find_pngIS(edit_find_png_data, sizeof(edit_find_png_data)); + img_edit_find_png->LoadFile(img_edit_find_pngIS, wxBITMAP_TYPE_PNG); + } + return img_edit_find_png; +} +#define edit_find_png_img edit_find_png_img() + +static wxBitmap *edit_find_png_bmp() +{ + static wxBitmap *bmp_edit_find_png; + if (!bmp_edit_find_png || !bmp_edit_find_png->IsOk()) + bmp_edit_find_png = new wxBitmap(*edit_find_png_img); + return bmp_edit_find_png; +} +#define edit_find_png_bmp edit_find_png_bmp() + +static wxIcon *edit_find_png_ico() +{ + static wxIcon *ico_edit_find_png; + if (!ico_edit_find_png || !ico_edit_find_png->IsOk()) + { + ico_edit_find_png = new wxIcon(); + ico_edit_find_png->CopyFromBitmap(*edit_find_png_bmp); + } + return ico_edit_find_png; +} +#define edit_find_png_ico edit_find_png_ico() + +#endif // EDIT_FIND_PNG_H diff --git a/include/images/edit_redo.png b/include/images/edit_redo.png new file mode 100644 index 0000000000000000000000000000000000000000..f45c6d2abc1a6353b7700b0157af396a6518fa1f GIT binary patch literal 654 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47}WxNLR^8|l{-%4Puc5TyUn>` z%dB-reVX^>ZhTsHjEztZd3@9In(%&^J7MwhsvqN4D-Z98Q4>{E&@7LwZt`|BqgyV z)hf9t6-Y4{85kPq8XD;u7={=bSeY1GnV4uBm|7VaSj<$FL(!0%pOTqY3DIC+3Dy8o ZZDn8v(Qs;d=o+8~22WQ%mvv4FO#q)e9y$O3 literal 0 HcmV?d00001 diff --git a/include/images/edit_redo.pngc b/include/images/edit_redo.pngc new file mode 100644 index 0000000..ec2bf1e --- /dev/null +++ b/include/images/edit_redo.pngc @@ -0,0 +1,126 @@ +#ifndef EDIT_REDO_PNG_H +#define EDIT_REDO_PNG_H + +static const unsigned char edit_redo_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x26, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xa9, 0xb8, 0xc8, 0x6f, +0x94, 0xbd, 0x4b, 0x7d, 0xb6, 0x43, 0x78, 0xb4, +0x9a, 0xae, 0xc5, 0x4c, 0x83, 0xbe, 0x6d, 0xb1, +0xe5, 0x76, 0xc4, 0xf6, 0x72, 0xc6, 0xf8, 0x68, +0xbf, 0xf1, 0x58, 0xa9, 0xdf, 0x46, 0x81, 0xbc, +0xa3, 0xb4, 0xc7, 0x4c, 0x84, 0xbe, 0x74, 0xbb, +0xed, 0x74, 0xc0, 0xf2, 0x6c, 0xbb, 0xee, 0x6a, +0xc0, 0xf3, 0x5e, 0xb6, 0xea, 0x57, 0xb5, 0xe9, +0x4d, 0xac, 0xe1, 0x43, 0x81, 0xbc, 0x69, 0x90, +0xbc, 0x70, 0xb5, 0xe9, 0x73, 0xbf, 0xf0, 0x5f, +0xa6, 0xdb, 0x4d, 0x8b, 0xc5, 0x44, 0x7b, 0xb6, +0x49, 0x8a, 0xc3, 0x4b, 0x9e, 0xd5, 0x46, 0xad, +0xe3, 0x3f, 0xa2, 0xd9, 0x57, 0x93, 0xcb, 0x77, +0xc2, 0xf3, 0x5c, 0xa0, 0xd6, 0x7e, 0x9d, 0xc0, +0xac, 0xba, 0xc9, 0xcb, 0xcd, 0xcf, 0x41, 0x96, +0xce, 0x36, 0xaa, 0xe0, 0x3c, 0x88, 0xc3, 0x99, +0xae, 0xc5, 0x6a, 0x90, 0xbc, 0x98, 0xad, 0xc5, +0x6c, 0x92, 0xbc, 0x6b, 0xb2, 0xe6, 0x6a, 0xb6, +0xea, 0x61, 0x8b, 0xba, 0xc3, 0xc8, 0xcd, 0xae, +0xbb, 0xc9, 0x32, 0xa1, 0xd8, 0x2c, 0x9b, 0xd4, +0x34, 0x89, 0xc4, 0x21, 0x96, 0xd0, 0x2e, 0x88, +0xc2, 0x53, 0x82, 0xb7, 0x70, 0xbf, 0xf1, 0x56, +0x99, 0xd0, 0x93, 0xaa, 0xc4, 0x87, 0xa2, 0xc2, +0x40, 0x85, 0xc0, 0x38, 0x93, 0xcc, 0x28, 0xa4, +0xdc, 0x1d, 0xa6, 0xdd, 0x15, 0xa3, 0xda, 0x0f, +0xa0, 0xd8, 0x41, 0x79, 0xb5, 0x4a, 0x7c, 0xb5, +0x6d, 0xc1, 0xf4, 0x47, 0x80, 0xbb, 0xc1, 0xc7, +0xcd, 0x4d, 0x7e, 0xb6, 0x30, 0xa9, 0xe0, 0x26, +0xa9, 0xe0, 0x16, 0xa3, 0xdb, 0x0e, 0xa0, 0xd8, +0x31, 0x84, 0xbf, 0x7f, 0x9d, 0xc0, 0x44, 0x79, +0xb4, 0x68, 0xc1, 0xf3, 0x43, 0x79, 0xb5, 0xce, +0xcf, 0xd0, 0x2e, 0x92, 0xcb, 0x17, 0xa2, 0xdb, +0x0f, 0xa0, 0xd9, 0x10, 0x99, 0xd3, 0x55, 0x83, +0xb8, 0x49, 0x86, 0xc1, 0xba, 0xc2, 0xcc, 0x36, +0x82, 0xbd, 0x09, 0x9e, 0xd7, 0x31, 0x82, 0xbd, +0x8f, 0xa7, 0xc3, 0xb3, 0xbe, 0xca, 0x7d, 0x9c, +0xc0, 0x40, 0x7a, 0xb6, 0xc9, 0xcc, 0xcf, 0xec, +0x73, 0x71, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x9f, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, +0x60, 0x20, 0x0a, 0x30, 0x32, 0x31, 0xb3, 0x30, +0x33, 0x31, 0xc2, 0xf9, 0xac, 0x6c, 0xec, 0x1c, +0x9c, 0x5c, 0xdc, 0x3c, 0xac, 0x50, 0x3e, 0x2f, +0x1f, 0xbf, 0x80, 0xa0, 0x90, 0xb0, 0x88, 0xa8, +0x18, 0x2f, 0x44, 0x40, 0x5c, 0x42, 0x52, 0x4a, +0x5a, 0x46, 0x56, 0x4e, 0x5e, 0x41, 0x1c, 0xa2, +0x40, 0x51, 0x49, 0x59, 0x45, 0x55, 0x4d, 0x55, +0x45, 0x5d, 0x43, 0x53, 0x4b, 0x5b, 0x87, 0x81, +0x41, 0x57, 0x4f, 0xdf, 0xc0, 0x10, 0x28, 0x61, +0x64, 0x60, 0x6c, 0x62, 0x6a, 0x66, 0xce, 0xc0, +0x60, 0x61, 0x69, 0x65, 0x0d, 0xe4, 0xdb, 0xd8, +0xda, 0xd9, 0x3b, 0x38, 0x3a, 0x39, 0x33, 0x30, +0xb8, 0xb8, 0xba, 0xb9, 0x03, 0x05, 0x3c, 0x3c, +0xbd, 0x1c, 0xbc, 0x7d, 0x7c, 0xfd, 0x18, 0x18, +0xfc, 0x03, 0x02, 0x83, 0x40, 0x2a, 0x3c, 0x82, +0x43, 0x42, 0xc3, 0xc2, 0x81, 0x2c, 0x95, 0x08, +0x15, 0xb0, 0xe1, 0x91, 0x7e, 0x51, 0xd1, 0x31, +0xb1, 0x20, 0x56, 0x1c, 0xcc, 0x81, 0xf1, 0x09, +0xf1, 0x68, 0x5e, 0x48, 0x24, 0xca, 0xa3, 0x00, +0x9e, 0x16, 0x15, 0x00, 0x07, 0x64, 0xb5, 0xa2, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, +0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *edit_redo_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_edit_redo_png = new wxImage(); + if (!img_edit_redo_png || !img_edit_redo_png->IsOk()) + { + wxMemoryInputStream img_edit_redo_pngIS(edit_redo_png_data, sizeof(edit_redo_png_data)); + img_edit_redo_png->LoadFile(img_edit_redo_pngIS, wxBITMAP_TYPE_PNG); + } + return img_edit_redo_png; +} +#define edit_redo_png_img edit_redo_png_img() + +static wxBitmap *edit_redo_png_bmp() +{ + static wxBitmap *bmp_edit_redo_png; + if (!bmp_edit_redo_png || !bmp_edit_redo_png->IsOk()) + bmp_edit_redo_png = new wxBitmap(*edit_redo_png_img); + return bmp_edit_redo_png; +} +#define edit_redo_png_bmp edit_redo_png_bmp() + +static wxIcon *edit_redo_png_ico() +{ + static wxIcon *ico_edit_redo_png; + if (!ico_edit_redo_png || !ico_edit_redo_png->IsOk()) + { + ico_edit_redo_png = new wxIcon(); + ico_edit_redo_png->CopyFromBitmap(*edit_redo_png_bmp); + } + return ico_edit_redo_png; +} +#define edit_redo_png_ico edit_redo_png_ico() + +#endif // EDIT_REDO_PNG_H diff --git a/include/images/edit_undo.png b/include/images/edit_undo.png new file mode 100644 index 0000000000000000000000000000000000000000..23ff22d467652cb0c95d43b756a790e863094477 GIT binary patch literal 657 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47&QZYLR^8|l{-%4Puc5TyUn>` z%dB-ry_)wXuX~)a|6}5TPvJY>crU%}+^~D`mgC;d`!ct^O5go1ZriJf-S7N1Jat?D z#BSML$A;aR6ZWKUdX~29ZP=olo?VBXtG2mx9CDa-$!z&u!?{;ytUa1FVb9EUM}sGx z%G~=QWbT!^xd+zlI(ho+dGkr9)fV42YdaV-^J32C7h%)SCvA8Vx9M48_pWujPaZyT zR%P}TrD^ALChc*p+E#k}N8ZtIX$QYVZGY`E`;u$>!S+RmCa*f8-+e@6_LbnK?e%jH z1WY)Qe&|cwzK@~1-+6C;?X=;EZ{4T?Gaf zV@Z%-FoVOh8)-leXMsm#F_88EW4Dvpc0k5_PZ!4!iOb0e3Va4ehMNtH4G;ZXlk-Mq zPRt#fH34?|^7|VWOxVz|LPFogA;u}lE6Od*FV0csL~uw@SYT-I^$S-5u3x&wsCDt` zWpe`)BQ~#@5;JGbG&YEch>E;@ zBhpKhOmu9RJY3yekMB6rv^Kaum_6_#=SKr^HK!FSO12!V4A&z>by8jB3V}{lEpd$~ zNl7e8wMs5Z1yT$~28M>Z28OyurXhx=Rt6SU#unNJW>y9U@>-w#Q8eV{r(~v8f;1TD m8dw7LgcuoHnV47^m}wgTbsC(S9=Zmofx*+&&t;ucLK6ULdmtJB literal 0 HcmV?d00001 diff --git a/include/images/edit_undo.pngc b/include/images/edit_undo.pngc new file mode 100644 index 0000000..02277af --- /dev/null +++ b/include/images/edit_undo.pngc @@ -0,0 +1,127 @@ +#ifndef EDIT_UNDO_PNG_H +#define EDIT_UNDO_PNG_H + +static const unsigned char edit_undo_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x29, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xa9, 0xb8, 0xc8, 0x6f, +0x94, 0xbd, 0x4b, 0x7d, 0xb6, 0x43, 0x78, 0xb4, +0x9a, 0xae, 0xc5, 0x4a, 0x83, 0xbd, 0x63, 0xae, +0xe3, 0x68, 0xbf, 0xf1, 0x61, 0xc0, 0xf2, 0x57, +0xb8, 0xec, 0x4b, 0xa5, 0xdb, 0x43, 0x80, 0xbb, +0xa3, 0xb4, 0xc7, 0x4b, 0x83, 0xbe, 0x69, 0xb6, +0xea, 0x67, 0xbb, 0xee, 0x5e, 0xb6, 0xea, 0x58, +0xbb, 0xee, 0x4e, 0xb0, 0xe5, 0x46, 0xaf, 0xe4, +0x3e, 0xa6, 0xdd, 0x41, 0x80, 0xbb, 0x69, 0x90, +0xbc, 0x67, 0xb2, 0xe6, 0x66, 0xba, 0xed, 0x56, +0xa2, 0xd9, 0x49, 0x8a, 0xc3, 0x43, 0x7a, 0xb6, +0x44, 0x88, 0xc2, 0x40, 0x9a, 0xd2, 0x36, 0xa7, +0xdd, 0x31, 0x9d, 0xd5, 0x98, 0xad, 0xc5, 0x6a, +0x90, 0xbc, 0x99, 0xae, 0xc5, 0x53, 0x91, 0xca, +0x69, 0xbd, 0xf0, 0x54, 0x9d, 0xd4, 0x7e, 0x9d, +0xc0, 0xac, 0xba, 0xc9, 0xcb, 0xcd, 0xcf, 0x37, +0x92, 0xcb, 0x26, 0xa3, 0xdb, 0x36, 0x86, 0xc1, +0x5c, 0x99, 0xd1, 0x6c, 0xb3, 0xe8, 0x56, 0x97, +0xcf, 0x62, 0xb0, 0xe4, 0x5e, 0xb2, 0xe6, 0x61, +0x8b, 0xba, 0xae, 0xbb, 0xc9, 0xc3, 0xc8, 0xcd, +0x24, 0x9b, 0xd4, 0x22, 0x96, 0xcf, 0x6c, 0x92, +0xbc, 0x45, 0x7a, 0xb6, 0x75, 0xc7, 0xf8, 0x6e, +0xc5, 0xf6, 0x66, 0xc1, 0xf4, 0x5a, 0xb7, 0xeb, +0x4c, 0x9b, 0xd2, 0x45, 0x87, 0xc1, 0x87, 0xa2, +0xc2, 0x93, 0xaa, 0xc4, 0x2f, 0x8b, 0xc4, 0x14, +0x9b, 0xd4, 0x53, 0x82, 0xb7, 0x7f, 0x9d, 0xc0, +0x50, 0x90, 0xc8, 0x67, 0xc2, 0xf4, 0x5e, 0xbe, +0xf1, 0x55, 0xbb, 0xee, 0x4b, 0xb7, 0xeb, 0x42, +0xb0, 0xe4, 0x4d, 0x7e, 0xb6, 0xc1, 0xc7, 0xcd, +0x3d, 0x7c, 0xb8, 0x0b, 0x9c, 0xd5, 0x4a, 0x7c, +0xb5, 0x55, 0x83, 0xb8, 0x5b, 0xb6, 0xea, 0x56, +0xbb, 0xef, 0x4c, 0xb7, 0xeb, 0x43, 0x9a, 0xd2, +0xce, 0xcf, 0xd0, 0x42, 0x78, 0xb4, 0x04, 0x9c, +0xd5, 0x44, 0x79, 0xb4, 0x8f, 0xa7, 0xc3, 0x48, +0x8b, 0xc4, 0x4d, 0xb8, 0xec, 0x43, 0x87, 0xc1, +0xba, 0xc2, 0xcc, 0x35, 0x7f, 0xbb, 0x7d, 0x9c, +0xc0, 0x43, 0x7b, 0xb6, 0xb3, 0xbe, 0xca, 0xc9, +0xcc, 0xcf, 0x0e, 0x00, 0x96, 0xd5, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x9f, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0x60, 0x20, 0x0e, 0x30, 0x32, +0x31, 0xb3, 0x30, 0x33, 0x31, 0xc2, 0xf9, 0xac, +0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xac, +0x50, 0x3e, 0x2f, 0x1f, 0xbf, 0x80, 0xa0, 0x90, +0xb0, 0x88, 0xa8, 0x18, 0x2f, 0x44, 0x40, 0x5c, +0x42, 0x52, 0x4a, 0x5a, 0x46, 0x56, 0x4e, 0x5e, +0x41, 0x1c, 0xc8, 0x53, 0x54, 0x52, 0x56, 0x51, +0x55, 0x53, 0xd7, 0xd0, 0xd4, 0x50, 0xd7, 0xd2, +0xd6, 0x01, 0x2a, 0xd1, 0xd5, 0xd3, 0x37, 0x30, +0x34, 0x32, 0x06, 0x4a, 0x99, 0x18, 0x99, 0x9a, +0x99, 0x33, 0x30, 0x58, 0x58, 0x5a, 0x59, 0xdb, +0xd8, 0xda, 0xd9, 0x03, 0x45, 0x1c, 0x1c, 0x9d, +0x9c, 0x19, 0x18, 0x5c, 0x5c, 0xdd, 0xdc, 0x3d, +0x3c, 0xbd, 0xbc, 0x81, 0x02, 0x3e, 0xbe, 0x7e, +0xfe, 0x40, 0x2a, 0x20, 0x30, 0x28, 0x38, 0xc4, +0x1b, 0xa4, 0x22, 0x34, 0x2c, 0x3c, 0x02, 0x48, +0x45, 0x46, 0x45, 0xc7, 0xb8, 0xc4, 0x82, 0xad, +0x53, 0x8f, 0x53, 0x07, 0x51, 0xf1, 0x09, 0xf1, +0x30, 0x17, 0x26, 0x42, 0xa8, 0x24, 0x22, 0x3d, +0x08, 0x05, 0x00, 0xd7, 0x58, 0x15, 0x2c, 0x65, +0x45, 0x1e, 0x71, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x31, 0x2d, 0x30, 0x31, 0x2d, 0x32, +0x35, 0x54, 0x31, 0x35, 0x3a, 0x30, 0x38, 0x3a, +0x33, 0x38, 0x2b, 0x30, 0x36, 0x3a, 0x30, 0x30, +0x1f, 0x2a, 0xf2, 0x4f, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *edit_undo_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_edit_undo_png = new wxImage(); + if (!img_edit_undo_png || !img_edit_undo_png->IsOk()) + { + wxMemoryInputStream img_edit_undo_pngIS(edit_undo_png_data, sizeof(edit_undo_png_data)); + img_edit_undo_png->LoadFile(img_edit_undo_pngIS, wxBITMAP_TYPE_PNG); + } + return img_edit_undo_png; +} +#define edit_undo_png_img edit_undo_png_img() + +static wxBitmap *edit_undo_png_bmp() +{ + static wxBitmap *bmp_edit_undo_png; + if (!bmp_edit_undo_png || !bmp_edit_undo_png->IsOk()) + bmp_edit_undo_png = new wxBitmap(*edit_undo_png_img); + return bmp_edit_undo_png; +} +#define edit_undo_png_bmp edit_undo_png_bmp() + +static wxIcon *edit_undo_png_ico() +{ + static wxIcon *ico_edit_undo_png; + if (!ico_edit_undo_png || !ico_edit_undo_png->IsOk()) + { + ico_edit_undo_png = new wxIcon(); + ico_edit_undo_png->CopyFromBitmap(*edit_undo_png_bmp); + } + return ico_edit_undo_png; +} +#define edit_undo_png_ico edit_undo_png_ico() + +#endif // EDIT_UNDO_PNG_H diff --git a/include/images/enumeration.png b/include/images/enumeration.png new file mode 100644 index 0000000000000000000000000000000000000000..0b5ff02218c60d930bc4c3c6036c98a5263d649b GIT binary patch literal 623 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47-a)|LR^8|{zKPHCv8>hT7UfE zE4x{{cE0_z=j-=fU%&17_I=Oy@B4oIIP~+!zE58q=j=Xm|7GsRlRf9|t$F)7prqWt zw0!CNPl09SLFE;}I?P2!%6UGy_EPMQR*3)+rp1hs-^xfp= z@29=|Fyr-y*>6A2efMephtG>XeO~|d>#k2<3?^(|`s988z1L1T#ZI}!T@T*4=9jn? zlzJ4FdKQ&>6_(qnzUh1X zcJkAA3txTQ@cL83vD=exy>iSfa>y)dx&Fc_tH?RK*d?dfHK*7;x5P8QWXban)-!g_ zyY*_;?bp+8y`FLV^^7}jX5D==``+8R_utNc_;$s^x6x}#UjqY(u_VYZn8D%MjWi&K zv%n*=7)X17vD?XPJ0PRe)5S4F;&O6=0<(dU;b8`0WU&OM50ZE$obg z=ryx#W#9Pv{LbmE%X{Y_S|m3w?w;Mgx_^v~jt83@jDI*g9X_P2w0Kc+($_~3KR51Z z21a*9oY4NKER*wqj#4dgjVMV;EJ?LWE=mPb3`Pcq2D*kux(0?JMg~?U##SaK+6Jap v1_l;0Rpn4LIsOk()) + { + wxMemoryInputStream img_enumeration_pngIS(enumeration_png_data, sizeof(enumeration_png_data)); + img_enumeration_png->LoadFile(img_enumeration_pngIS, wxBITMAP_TYPE_PNG); + } + return img_enumeration_png; +} +#define enumeration_png_img enumeration_png_img() + +static wxBitmap *enumeration_png_bmp() +{ + static wxBitmap *bmp_enumeration_png; + if (!bmp_enumeration_png || !bmp_enumeration_png->IsOk()) + bmp_enumeration_png = new wxBitmap(*enumeration_png_img); + return bmp_enumeration_png; +} +#define enumeration_png_bmp enumeration_png_bmp() + +static wxIcon *enumeration_png_ico() +{ + static wxIcon *ico_enumeration_png; + if (!ico_enumeration_png || !ico_enumeration_png->IsOk()) + { + ico_enumeration_png = new wxIcon(); + ico_enumeration_png->CopyFromBitmap(*enumeration_png_bmp); + } + return ico_enumeration_png; +} +#define enumeration_png_ico enumeration_png_ico() + +#endif // ENUMERATION_PNG_H diff --git a/include/images/enumerations.png b/include/images/enumerations.png new file mode 100644 index 0000000000000000000000000000000000000000..6acde4cbc127935842e619530eb52ae98e866ab1 GIT binary patch literal 502 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf_5hy{S0LSg=$h%It!iEC@4fwO zH+$Ef_n-HF|Gww@_kBNp9QyfV-={B*b9Uc;^Qr5=m5PH`H@yFB-7rOe;uhV$O(k2- zG@ZEBbNy-O{>z1XF2!y-V>4rC(2660rR9s?e+nuq4=%3=tEkxh{d@iK>+_zzpYZ5y z@8h={QcCI@8`bxxaPx`?sIqNK6vYvQ`~*$wOekndtQl0eu;NM>8e+s7T$R^ z@7|kPci+su_jd06xAPvnUHbU_%7<_5X6-7vqX_Z>V@Z%-FoVOh8)-leXMsm#F_88E zW4Dvpc0fj%r;B5V#O34!1s;i+GY&R%3LZ*NOih0N;K`FGkDfhb<^J%In}f^o3P?gc3PrV{L1h zot2a83O8Kc6Qs5*?U~rLuxn;}Zp3;^F)%#U=1Q4+GNuve0@V`Nh?11Vl2ohYqEsNo zU}RuuplfKPYhV~+WME}tY-M7iZD49;U|=y*RSrc%ZhlH;S|vn-fhAZ2NVS!L8AQXW T>7i?Y8W=oX{an^LB{Ts5v@6{6 literal 0 HcmV?d00001 diff --git a/include/images/enumerations.pngc b/include/images/enumerations.pngc new file mode 100644 index 0000000..5f98662 --- /dev/null +++ b/include/images/enumerations.pngc @@ -0,0 +1,107 @@ +#ifndef ENUMERATIONS_PNG_H +#define ENUMERATIONS_PNG_H + +static const unsigned char enumerations_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xb7, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8f, 0xc2, 0xd6, 0x35, +0x92, 0xb5, 0x26, 0x8a, 0xaf, 0xde, 0xed, 0xf3, +0x3e, 0x9b, 0xba, 0xbc, 0xef, 0xf3, 0xbf, 0xf7, +0xf7, 0xbc, 0xf7, 0xf7, 0xbe, 0xf8, 0xf8, 0xc2, +0xf9, 0xf8, 0xbe, 0xf2, 0xf4, 0x41, 0x9c, 0xbb, +0xdb, 0xec, 0xf2, 0x8a, 0xc0, 0xd4, 0x78, 0xc1, +0xd5, 0xb0, 0xef, 0xf3, 0x3b, 0x80, 0x94, 0x2f, +0x91, 0xb4, 0x2d, 0x8e, 0xb2, 0x74, 0xb4, 0xcc, +0x82, 0xc8, 0xda, 0x8c, 0xd7, 0xe5, 0x89, 0xbf, +0xd3, 0x71, 0xbc, 0xd2, 0x5d, 0xb2, 0xcc, 0x3c, +0x98, 0xb9, 0x52, 0xa8, 0xc4, 0x51, 0x75, 0x77, +0xa3, 0xef, 0xf2, 0x52, 0x76, 0x77, 0x53, 0x77, +0x78, 0x56, 0x78, 0x78, 0xbb, 0xf7, 0xf7, 0x7f, +0xc7, 0xd7, 0x9e, 0xe5, 0xef, 0x90, 0xe2, 0xed, +0x8d, 0xe3, 0xed, 0x90, 0xe5, 0xee, 0x93, 0xe7, +0xef, 0x95, 0xe9, 0xef, 0x9d, 0xec, 0xf1, 0xac, +0xf0, 0xf4, 0x8b, 0xce, 0xdd, 0x9d, 0xe0, 0xed, +0x46, 0x6c, 0x73, 0x8b, 0xdc, 0xeb, 0x46, 0x6d, +0x73, 0x47, 0x6e, 0x74, 0x48, 0x6f, 0x74, 0x4b, +0x70, 0x75, 0xaa, 0xea, 0xf2, 0xa1, 0xdc, 0xea, +0x9e, 0xde, 0xec, 0x9a, 0xdd, 0xec, 0x9b, 0xde, +0xed, 0x9d, 0xdf, 0xed, 0x9e, 0xe0, 0xed, 0xa5, +0xe3, 0xef, 0xa9, 0xe1, 0xed, 0x3e, 0x9a, 0xba, +0x72, 0xdc, 0x21, 0x53, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x76, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x63, 0x60, 0x20, 0x0c, 0x18, 0x99, 0x98, 0xc1, +0x80, 0x89, 0x11, 0xc2, 0x67, 0x61, 0x65, 0x63, +0xe7, 0xe0, 0xe4, 0xe4, 0xe4, 0xe2, 0xe6, 0xe1, +0x05, 0x0b, 0xf0, 0xf1, 0x0b, 0x08, 0x0a, 0x41, +0xd4, 0x08, 0x83, 0xd5, 0x88, 0x88, 0x8a, 0xa1, +0xaa, 0x11, 0x97, 0x90, 0x44, 0x55, 0xc3, 0x2b, +0x25, 0x8d, 0xa6, 0x86, 0x51, 0x18, 0xa4, 0x46, +0x46, 0x56, 0x46, 0x4e, 0x5e, 0x41, 0x51, 0x49, +0x9c, 0x01, 0xa2, 0x46, 0x59, 0x45, 0x55, 0x4d, +0x5d, 0x43, 0x53, 0x4b, 0x5b, 0x04, 0xec, 0x12, +0x61, 0x09, 0x1d, 0x5d, 0x3d, 0x7d, 0x03, 0x43, +0x23, 0x63, 0x7e, 0x71, 0xb0, 0xd5, 0xbc, 0x52, +0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, +0x36, 0xbc, 0xd8, 0x5d, 0x4b, 0x1a, 0x00, 0x00, +0xe5, 0x2b, 0x0a, 0x64, 0x9d, 0xc9, 0x5c, 0x81, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, +0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *enumerations_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_enumerations_png = new wxImage(); + if (!img_enumerations_png || !img_enumerations_png->IsOk()) + { + wxMemoryInputStream img_enumerations_pngIS(enumerations_png_data, sizeof(enumerations_png_data)); + img_enumerations_png->LoadFile(img_enumerations_pngIS, wxBITMAP_TYPE_PNG); + } + return img_enumerations_png; +} +#define enumerations_png_img enumerations_png_img() + +static wxBitmap *enumerations_png_bmp() +{ + static wxBitmap *bmp_enumerations_png; + if (!bmp_enumerations_png || !bmp_enumerations_png->IsOk()) + bmp_enumerations_png = new wxBitmap(*enumerations_png_img); + return bmp_enumerations_png; +} +#define enumerations_png_bmp enumerations_png_bmp() + +static wxIcon *enumerations_png_ico() +{ + static wxIcon *ico_enumerations_png; + if (!ico_enumerations_png || !ico_enumerations_png->IsOk()) + { + ico_enumerations_png = new wxIcon(); + ico_enumerations_png->CopyFromBitmap(*enumerations_png_bmp); + } + return ico_enumerations_png; +} +#define enumerations_png_ico enumerations_png_ico() + +#endif // ENUMERATIONS_PNG_H diff --git a/include/images/ex_aggregate.png b/include/images/ex_aggregate.png new file mode 100644 index 0000000000000000000000000000000000000000..fac0c0286df966f79b823480f499551ee205322f GIT binary patch literal 1066 zcmV+_1l9YAP)te_2XUXhp$?R>) z>~YKNbj<8`&h2~7?0(PffYI%Q(d~!Q?uygyj@0g++30I=ozl$ z4XWZ1tKt=`;u)>uE41Z+(C&K8>~hNMYR2ei#prp=>yFCkeXh}twb5Fl(^kam9Ixa$ zx#wxE*@D62iO}qI%j%QN>2#~nAh6`J#L$k;>wwPdC9&ikuj4MX^HdPaLnw#$S@U9UBu~$ z#O0dM>bSe(67SKhtche((PZS)@`ub9kAqY$mwmz>0Za|SHb67!slPZ z=wrm_nAh(wui_J|a7KXNVqtW!C!`x}H+CI{D=2MrWyQjCW ze_+r#Gz=uJ5oYxBn0tI;(xf7uscG-b?A$!~7?z`a3o`L*a#~#a5(q2@;ni4H!DCPe%DfQf*S{uP7p$ErHMY zvuZ9By)CfG z=E_oa56?J?QqA0tXY!R=eg6Q@l&bZ{A^H+unIp_o6oOZalGrg;$CUCdSofkd*<8XD z*^WG>NLCz}f+=QoBGp3Jb4i^b(tLHFsIe6HzY?dMb9o*v zY-d|~;W}?dVi!V%l+Orap)A$vjq0!8_kU)*cYi5}cz7HGlK^n^lax;u5Hbr~Fw~RJ z1Y3NAPGFA_%T?L0!0O-QZSf3`>0N4*UyeNh001R)MObuXVRU6WV{&C-bY%cCFflMK zF)}SMF;p@zIy5snG&CzPH99abIGH6L0000bbVXQnWMOn=I&E)cX=ZrIsOk()) + { + wxMemoryInputStream img_ex_aggregate_pngIS(ex_aggregate_png_data, sizeof(ex_aggregate_png_data)); + img_ex_aggregate_png->LoadFile(img_ex_aggregate_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_aggregate_png; +} +#define ex_aggregate_png_img ex_aggregate_png_img() + +static wxBitmap *ex_aggregate_png_bmp() +{ + static wxBitmap *bmp_ex_aggregate_png; + if (!bmp_ex_aggregate_png || !bmp_ex_aggregate_png->IsOk()) + bmp_ex_aggregate_png = new wxBitmap(*ex_aggregate_png_img); + return bmp_ex_aggregate_png; +} +#define ex_aggregate_png_bmp ex_aggregate_png_bmp() + +static wxIcon *ex_aggregate_png_ico() +{ + static wxIcon *ico_ex_aggregate_png; + if (!ico_ex_aggregate_png || !ico_ex_aggregate_png->IsOk()) + { + ico_ex_aggregate_png = new wxIcon(); + ico_ex_aggregate_png->CopyFromBitmap(*ex_aggregate_png_bmp); + } + return ico_ex_aggregate_png; +} +#define ex_aggregate_png_ico ex_aggregate_png_ico() + +#endif // EX_AGGREGATE_PNG_H diff --git a/include/images/ex_append.png b/include/images/ex_append.png new file mode 100644 index 0000000000000000000000000000000000000000..017a2068b735f13cb89a3bcb2832e5880d17df56 GIT binary patch literal 1162 zcmV;51a}tvEZ_4YI+3|bM?Sj$mrrz?7)b5hj z@2}zW1*hRn!RZ^W<6Fh+V#n(^x8+d2=WEC4a+aaNk2du1$nfm9@9MSh>9q3g#qH&> z?c}iR?B>));G-mL1~tMBB$>*k;D>$d6On&{t|?&h=S+m`0ol<@94Ab;k?JHb@1lE=hUR;)1&O& zx!}r)-o=I9!-U^3l=q!NTst z#P8G8^VQY#$jI=?$??j|@!8t--ro1u*Y)Ay_q@IAr>W+ss^`DI?yaxsud(UH#qY<+ z@3pq;x47%Lx$M-`^vB2WiI(>{00001bW%=J06^y0W&i*H32;bRa{vGUNB{r;NB~C3 zYd!z~0zpYcK~zY`?U3tJ5>Xh&?SzGeqJ$LLD=fGO%SB*ek((>YO)i2W3vOk#CSYi4 znRfSIZ+9mfuyZIJXZldjhj-?kd4K0Q&oeUeU#e~(MZ}3i&`phI^cK3U)oRDk*qyt& zaWp=m*H5C!DTCo2!Xg@@(Kw2xO(xTQ^uTO3>(InQtyYhwW@dB-G{|N8&s`p=eFxKwPp z(r9dgKt_How%TaO#{-achU4Ux__UIuSXNThl@v8W5U#DUt7}W#B5ow&NzYaPMkJm- z`+3#B5v1H~KNqnZ(M8-Adt7=qvQOWu;_p1vqZcA^BYthzl84euNfB}45NYSt?ruwJ zclP#POWpm0H;2+;tKB}5j=J6Bw-Oe4cXIOnRO+0aefTJS`uyeVj?_BsblTFl^ZkS4 zzljW=IsOk()) + { + wxMemoryInputStream img_ex_append_pngIS(ex_append_png_data, sizeof(ex_append_png_data)); + img_ex_append_png->LoadFile(img_ex_append_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_append_png; +} +#define ex_append_png_img ex_append_png_img() + +static wxBitmap *ex_append_png_bmp() +{ + static wxBitmap *bmp_ex_append_png; + if (!bmp_ex_append_png || !bmp_ex_append_png->IsOk()) + bmp_ex_append_png = new wxBitmap(*ex_append_png_img); + return bmp_ex_append_png; +} +#define ex_append_png_bmp ex_append_png_bmp() + +static wxIcon *ex_append_png_ico() +{ + static wxIcon *ico_ex_append_png; + if (!ico_ex_append_png || !ico_ex_append_png->IsOk()) + { + ico_ex_append_png = new wxIcon(); + ico_ex_append_png->CopyFromBitmap(*ex_append_png_bmp); + } + return ico_ex_append_png; +} +#define ex_append_png_ico ex_append_png_ico() + +#endif // EX_APPEND_PNG_H diff --git a/include/images/ex_bmp_and.png b/include/images/ex_bmp_and.png new file mode 100644 index 0000000000000000000000000000000000000000..64d5869dcfcf9d94d031fa068cff93ea929180b2 GIT binary patch literal 1006 zcmVD86a;T`NPQK>5s&lKWtGldpyRCMut*u(Y=dP}(Y-ty(vljhW<)z#JK)upZ9^VHPy=+~y`*Qe^(w&~ia>DsB<+S=*ds_NXT>)W{8 z+}z#W-Rs`0?A^KE-rnrst?b~g?cclJ-uCR`ui@e0?BlTF;^Ob*zvboS@aDkq=fUUa z=jrL`@$1Cu>gw?D@bU5S^78WY^Yiuf_4fAm`1ttw`T70*{r~^}C9&%N00001bW%=J z06^y0W&i*H32;bRa{vGf6951U69E94oEQKA0q;pfK~zY`?UY$l6G0S(b8}-Di3kcP z+Oo)^h$4bwltoqvL?DD{Mjf_nBqD~O2?A~ymixDzo*9a*Gm})MC?7Zv{c`K8Gv{>Q zvDq$ko~o9(s?QF(wL!N4k*52GJqwax@WJEtiUu~Rr}eShD?&VOcaK*pj!Vugb=sg# zfY{%@e)DeKes;iqrqk&yCPD_D!r-C^Nk4PwuJ zQ#!=9lF84TBBa*NRjVOi9LP1IA^nW2-@@fKw*1L<;8opaGaip`h_l>+MlB1G6SG9S z=+u$;BX}4UBk&RoE`h+(O1ZE*><Ht zNXoo1qP+&hYdgl>ef9pot6A9mcrN5H3(-xi$?R{pAeQfQB&8_Is%c|H zG5v{QDc(Jx{2HTgO)iJ4;r-tV>{PR?%CelW*cUn`^~2;*7z$c$rLkbz!Q>%$6)bF# zgDMhW1^r9W&i*H07*qoM6N<$f literal 0 HcmV?d00001 diff --git a/include/images/ex_bmp_and.pngc b/include/images/ex_bmp_and.pngc new file mode 100644 index 0000000..a9d1faf --- /dev/null +++ b/include/images/ex_bmp_and.pngc @@ -0,0 +1,170 @@ +#ifndef EX_BMP_AND_PNG_H +#define EX_BMP_AND_PNG_H + +static const unsigned char ex_bmp_and_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x98, 0x50, 0x4c, 0x54, +0x45, 0x95, 0xd2, 0xfb, 0x00, 0x00, 0x00, 0x66, +0x6b, 0xd1, 0x74, 0x74, 0x74, 0x75, 0x75, 0x75, +0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x7a, 0x7a, +0x7a, 0x36, 0x88, 0xc1, 0x7b, 0x7b, 0x7b, 0x7c, +0x7c, 0x7c, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, +0x82, 0x82, 0x82, 0x83, 0x83, 0x83, 0x84, 0x84, +0x84, 0x87, 0x87, 0x87, 0x88, 0x88, 0x88, 0x8b, +0x8b, 0x8b, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8e, +0x64, 0x95, 0xd0, 0x8f, 0x8f, 0x8f, 0x90, 0x90, +0x90, 0x91, 0x91, 0x91, 0x8d, 0x8e, 0xbf, 0x92, +0x92, 0x92, 0xc1, 0x8f, 0x36, 0x95, 0x95, 0x95, +0x8f, 0x92, 0xdd, 0x7a, 0x9e, 0xa9, 0x99, 0x99, +0x99, 0x9c, 0x9c, 0x9c, 0x9e, 0x9e, 0x9e, 0x9b, +0x9c, 0xc4, 0x9f, 0x9f, 0x9f, 0xa6, 0xa6, 0xa6, +0xa7, 0xa7, 0xa7, 0xb9, 0xa7, 0x72, 0xa8, 0xa8, +0xa8, 0x4e, 0xbe, 0xe6, 0xbb, 0xaa, 0x73, 0xab, +0xab, 0xab, 0xbb, 0xac, 0x74, 0xbb, 0xad, 0x76, +0xad, 0xad, 0xad, 0x5a, 0xc1, 0xe7, 0xae, 0xae, +0xae, 0xbc, 0xb0, 0x77, 0xaf, 0xaf, 0xaf, 0xbd, +0xb1, 0x79, 0xab, 0xac, 0xe8, 0xbe, 0xb2, 0x7a, +0x89, 0xb9, 0xdb, 0xb2, 0xb2, 0xb2, 0x64, 0xc5, +0xe8, 0xb7, 0xb7, 0xb7, 0xb3, 0xb4, 0xea, 0x71, +0xcb, 0xec, 0xda, 0xbb, 0x7e, 0x7a, 0xce, 0xec, +0xdb, 0xbd, 0x89, 0xdc, 0xbe, 0x80, 0xbc, 0xbd, +0xec, 0xbc, 0xbd, 0xed, 0xdd, 0xc1, 0x82, 0x83, +0xd1, 0xed, 0xc3, 0xc3, 0xc3, 0xdd, 0xc2, 0x83, +0xc0, 0xc1, 0xee, 0xc6, 0xc6, 0xc6, 0x8b, 0xd4, +0xee, 0xdf, 0xc6, 0x86, 0xdf, 0xc8, 0x87, 0x92, +0xd5, 0xef, 0xc6, 0xc7, 0xef, 0xe0, 0xca, 0x89, +0xca, 0xca, 0xca, 0x94, 0xd8, 0xf0, 0xe3, 0xcb, +0x9e, 0xe3, 0xcc, 0x9e, 0xe4, 0xcd, 0x9e, 0xe2, +0xd0, 0x8d, 0xe4, 0xce, 0x9f, 0xcc, 0xcd, 0xf1, +0xcd, 0xce, 0xf2, 0xe5, 0xd0, 0xa1, 0xe6, 0xd1, +0xa2, 0xd3, 0xd3, 0xd3, 0xa6, 0xde, 0xf2, 0xe5, +0xd6, 0x93, 0xe6, 0xd4, 0xa4, 0xd5, 0xd5, 0xd5, +0xe7, 0xd5, 0xa5, 0xad, 0xdf, 0xf3, 0xd4, 0xd4, +0xf3, 0xe8, 0xd7, 0xa6, 0xe8, 0xd7, 0xa7, 0xea, +0xd8, 0xb6, 0xe9, 0xda, 0xa8, 0xe9, 0xda, 0xa9, +0xda, 0xda, 0xda, 0xe9, 0xdc, 0xaa, 0xea, 0xdc, +0xaa, 0xeb, 0xdb, 0xb8, 0xdc, 0xdc, 0xdc, 0xdd, +0xdd, 0xdd, 0xeb, 0xde, 0xac, 0xec, 0xdd, 0xb9, +0xde, 0xde, 0xde, 0xec, 0xe0, 0xad, 0xec, 0xe0, +0xae, 0xed, 0xdf, 0xbb, 0xde, 0xde, 0xf6, 0xec, +0xe2, 0xaf, 0xe1, 0xe1, 0xe1, 0xec, 0xe3, 0xb0, +0xe2, 0xe2, 0xe2, 0xef, 0xe4, 0xbf, 0xe5, 0xe5, +0xe5, 0xf0, 0xe6, 0xc0, 0xf0, 0xe7, 0xc1, 0xe7, +0xe7, 0xe7, 0xe9, 0xe9, 0xe9, 0xf1, 0xeb, 0xc4, +0xea, 0xea, 0xea, 0xf0, 0xf0, 0xf0, 0xf1, 0xf1, +0xf1, 0xf2, 0xf2, 0xf2, 0xf3, 0xf3, 0xf3, 0xf5, +0xf5, 0xf5, 0xf6, 0xf6, 0xf6, 0xf8, 0xf8, 0xf8, +0xf9, 0xf9, 0xf9, 0xfd, 0xfd, 0xfd, 0xff, 0xff, +0xff, 0x25, 0xb1, 0xea, 0xff, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, +0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, +0x00, 0x01, 0xef, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xed, 0x94, 0x59, 0x53, 0x13, 0x41, 0x14, +0x85, 0x73, 0x73, 0x63, 0x18, 0x89, 0x08, 0x0a, +0x28, 0xda, 0xb2, 0xc8, 0xa2, 0x88, 0x22, 0x82, +0x62, 0x94, 0x45, 0x56, 0x09, 0x44, 0x20, 0x84, +0x68, 0x46, 0x1d, 0xb6, 0x6c, 0x24, 0x22, 0x86, +0xa0, 0x09, 0x02, 0x6e, 0x18, 0x96, 0xfb, 0xb7, +0x9d, 0x9e, 0x19, 0x8a, 0xad, 0x33, 0x93, 0x54, +0xa5, 0x28, 0x1f, 0x38, 0x0f, 0xfd, 0x72, 0xeb, +0xab, 0x33, 0xe7, 0x74, 0xdf, 0xb1, 0xd9, 0x2e, +0x74, 0x9e, 0xaa, 0x96, 0xb8, 0xaa, 0xcf, 0x0e, +0xba, 0xb5, 0x41, 0xb7, 0x00, 0x91, 0xa6, 0xfb, +0x86, 0x3d, 0x0b, 0x92, 0x60, 0xf0, 0xc1, 0xe3, +0xf5, 0x8a, 0x06, 0x36, 0xa9, 0xa7, 0xf5, 0xb1, +0xdb, 0x2b, 0x42, 0x3c, 0x6e, 0x77, 0x8f, 0x57, +0x2a, 0x8e, 0x4b, 0xce, 0x2c, 0x75, 0xda, 0xa0, +0x4e, 0x80, 0xd8, 0xdf, 0xbe, 0x7e, 0xf3, 0x6e, +0xdd, 0x7e, 0x76, 0xc0, 0x7e, 0xa6, 0xd3, 0xe9, +0x2d, 0x26, 0x42, 0x06, 0x9e, 0xc2, 0xe0, 0xa2, +0x08, 0x49, 0x3f, 0x83, 0xae, 0x64, 0x61, 0xc8, +0x57, 0xf8, 0x08, 0x96, 0x08, 0xe9, 0x32, 0x90, +0xb5, 0x2e, 0x78, 0x22, 0x46, 0x8e, 0xb2, 0x10, +0x65, 0xea, 0x4b, 0x9c, 0x95, 0x53, 0x3a, 0xc4, +0xb6, 0x92, 0xc9, 0xcf, 0x9b, 0x22, 0xa4, 0xd6, +0xce, 0x55, 0xab, 0x21, 0x5f, 0x1c, 0xc8, 0x35, +0xa2, 0x21, 0xfd, 0x8c, 0xab, 0xdf, 0xc2, 0xe5, +0x36, 0xb6, 0xfc, 0xc9, 0x76, 0xe0, 0x55, 0xdd, +0x65, 0x33, 0x1e, 0x8f, 0x6f, 0x88, 0xb3, 0xdc, +0x82, 0x46, 0x2d, 0x0b, 0x91, 0x13, 0xb3, 0x44, +0xbb, 0xe8, 0xd4, 0x91, 0xf8, 0x23, 0x78, 0x18, +0x15, 0x23, 0xf0, 0x12, 0x0c, 0xe4, 0x0a, 0xfe, +0x20, 0xfa, 0x84, 0x37, 0x0c, 0x04, 0x66, 0x21, +0x6a, 0xe5, 0xd2, 0x86, 0xcd, 0xb4, 0x52, 0x86, +0x2b, 0x3a, 0xb2, 0xfc, 0x00, 0xee, 0x45, 0xac, +0x1a, 0xfb, 0xed, 0xc2, 0xeb, 0x58, 0x3a, 0xa7, +0xb7, 0xcc, 0x36, 0xa2, 0x91, 0x48, 0xca, 0xbc, +0x31, 0xa2, 0xbd, 0x06, 0xc4, 0x6b, 0x3b, 0xc6, +0xdd, 0xe4, 0xd3, 0x18, 0x65, 0xab, 0xf0, 0x8e, +0x03, 0xa7, 0x28, 0xab, 0x16, 0x40, 0x36, 0x96, +0x0a, 0x85, 0x96, 0x52, 0x16, 0x59, 0xda, 0xf1, +0x39, 0x8d, 0xe1, 0xa5, 0x58, 0x0c, 0x2b, 0x38, +0x12, 0x9a, 0x84, 0x09, 0xc5, 0xb4, 0x31, 0xa2, +0x32, 0xde, 0xf1, 0x0b, 0xbc, 0x5c, 0x85, 0x6d, +0x1c, 0x59, 0x9a, 0x80, 0x71, 0xc5, 0xd4, 0x85, +0x5f, 0xcb, 0x2f, 0x35, 0xc5, 0x7d, 0xf5, 0xfe, +0xbf, 0xab, 0x59, 0xd8, 0xfc, 0x78, 0x2e, 0xe4, +0x30, 0x0b, 0xd1, 0x4d, 0xac, 0xc9, 0xec, 0x6f, +0xb7, 0x20, 0x96, 0xef, 0x73, 0x24, 0xa5, 0x28, +0xca, 0xaa, 0x69, 0x63, 0x44, 0x31, 0xfd, 0x89, +0x61, 0x29, 0xde, 0x3d, 0xa0, 0xfc, 0x1a, 0xa3, +0x6f, 0x4d, 0x2e, 0x87, 0xab, 0xe1, 0xfd, 0xdf, +0x0a, 0xec, 0x54, 0xb3, 0xac, 0xca, 0xb2, 0x9c, +0xb0, 0xd8, 0x17, 0x3a, 0x26, 0xf5, 0xc3, 0xe4, +0x51, 0x18, 0x0a, 0x5a, 0x6e, 0xa5, 0xb1, 0x60, +0xda, 0xc1, 0xe4, 0x21, 0x78, 0x15, 0x2c, 0x6c, +0x91, 0x83, 0x2a, 0x12, 0x60, 0x05, 0xfd, 0x61, +0x12, 0xc1, 0x40, 0x20, 0x61, 0xb1, 0x95, 0x27, +0x95, 0xd7, 0x56, 0x9e, 0x76, 0x09, 0xf8, 0xfd, +0x61, 0xf3, 0x37, 0x76, 0x1a, 0xf1, 0xf7, 0x42, +0xef, 0x8c, 0xf9, 0x56, 0x8a, 0x10, 0x5f, 0x61, +0x2e, 0x33, 0x39, 0x91, 0x9c, 0x59, 0xc2, 0x3e, +0x9f, 0x2f, 0x5c, 0xa4, 0xc6, 0x2e, 0xf4, 0x1f, +0xe9, 0x1f, 0x25, 0xa9, 0x9b, 0x39, 0xad, 0x49, +0x83, 0x66, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_bmp_and_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_bmp_and_png = new wxImage(); + if (!img_ex_bmp_and_png || !img_ex_bmp_and_png->IsOk()) + { + wxMemoryInputStream img_ex_bmp_and_pngIS(ex_bmp_and_png_data, sizeof(ex_bmp_and_png_data)); + img_ex_bmp_and_png->LoadFile(img_ex_bmp_and_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_bmp_and_png; +} +#define ex_bmp_and_png_img ex_bmp_and_png_img() + +static wxBitmap *ex_bmp_and_png_bmp() +{ + static wxBitmap *bmp_ex_bmp_and_png; + if (!bmp_ex_bmp_and_png || !bmp_ex_bmp_and_png->IsOk()) + bmp_ex_bmp_and_png = new wxBitmap(*ex_bmp_and_png_img); + return bmp_ex_bmp_and_png; +} +#define ex_bmp_and_png_bmp ex_bmp_and_png_bmp() + +static wxIcon *ex_bmp_and_png_ico() +{ + static wxIcon *ico_ex_bmp_and_png; + if (!ico_ex_bmp_and_png || !ico_ex_bmp_and_png->IsOk()) + { + ico_ex_bmp_and_png = new wxIcon(); + ico_ex_bmp_and_png->CopyFromBitmap(*ex_bmp_and_png_bmp); + } + return ico_ex_bmp_and_png; +} +#define ex_bmp_and_png_ico ex_bmp_and_png_ico() + +#endif // EX_BMP_AND_PNG_H diff --git a/include/images/ex_bmp_heap.png b/include/images/ex_bmp_heap.png new file mode 100644 index 0000000000000000000000000000000000000000..2657d8c39328bfc80751c60db9d3ab4341c0de35 GIT binary patch literal 1106 zcmV-Y1g-mtP)iMiWk#pq(j>Y>D5 zYsctl$n2uVV6(L9Zp-X(%j|E>?xxITcFpXi!Q^_*?AyJGyuIvu(eH!N?S#?pz`^c> z)9|d;ZHv_Ik=5>!)$gv_amL5*l-Tf>+3~XAcCFUw%+2wj+wtexE9lxP&Cc@b+bZna zD(>4V@7yZ!+$!?iD)ihcx!dfw=Y00vDy`r1`Q0h{-6_=6^RD3Y``#)1-YNdxDZbwA zx$A$x-|oWT?z`@S?c-qY<6p($@9^YbyzqqbGRa-^z`e8*6H;2>xcO3 zhu7-$`s|1O?1ujAhT-q`mEcQQ00001bW%=J06^y0W&i*H32;bRa{vGf6951U69E94 zoEQKA0&7V`K~zY`?Ud_N(?Ar(NfQ+@uBZsUQR*A(3k7^uiA_xlwb7^&(-vmu3&*C`D7%v}T}UXUKCdvcCQ&74!AQMsP2b2D)EWk&C8PTM^wqM7$}qY%Zrq%-GtR zg(zuUST%!@YA%<95iYB%7Gn28&1ADxp!<=IEX&Il;!V+l5Vj&_Y-#D(Gq$jB=z@FE z)OFo(Y@0AyyV$hfa#N zVHoX*8Jn9s_Kewxb3cRzb}`MpuD9%WyOJ=2@Tu2_G^GagZ~6a9ZW Y0Mz-{B6#`Cr~m)}07*qoM6N<$f){{JGynhq literal 0 HcmV?d00001 diff --git a/include/images/ex_bmp_heap.pngc b/include/images/ex_bmp_heap.pngc new file mode 100644 index 0000000..51f2884 --- /dev/null +++ b/include/images/ex_bmp_heap.pngc @@ -0,0 +1,183 @@ +#ifndef EX_BMP_HEAP_PNG_H +#define EX_BMP_HEAP_PNG_H + +static const unsigned char ex_bmp_heap_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, +0x6b, 0xd1, 0x52, 0x8d, 0x19, 0x36, 0x88, 0xc1, +0x5c, 0x95, 0x22, 0x5a, 0x90, 0x65, 0x64, 0x96, +0x39, 0x09, 0xa9, 0xe2, 0x12, 0xab, 0xe2, 0x64, +0x95, 0xd0, 0x71, 0xa2, 0x39, 0x66, 0x96, 0xd1, +0x8d, 0x8e, 0xbf, 0xc1, 0x8f, 0x36, 0x7e, 0xa1, +0x70, 0x8f, 0x92, 0xdd, 0x7a, 0x9e, 0xa9, 0x2d, +0xb4, 0xe4, 0x9b, 0x9c, 0xc4, 0x3a, 0xb8, 0xe5, +0x8c, 0xae, 0x74, 0x96, 0xb2, 0x36, 0x42, 0xbd, +0xe9, 0x47, 0xbf, 0xe9, 0x4e, 0xbe, 0xe6, 0x4b, +0xbf, 0xe9, 0x4e, 0xc1, 0xe9, 0x5a, 0xc1, 0xe7, +0x99, 0xbc, 0x78, 0xab, 0xac, 0xe8, 0x5d, 0xc4, +0xea, 0x89, 0xb9, 0xdb, 0x64, 0xc5, 0xe8, 0x62, +0xc6, 0xea, 0xa1, 0xc4, 0x5e, 0x6b, 0xc7, 0xe8, +0x68, 0xc8, 0xec, 0xa2, 0xc6, 0x60, 0xb3, 0xb4, +0xea, 0x6e, 0xcb, 0xec, 0x71, 0xcb, 0xec, 0x6f, +0xcd, 0xee, 0xa6, 0xcc, 0x65, 0x76, 0xcd, 0xec, +0xa5, 0xc1, 0xe4, 0x7a, 0xce, 0xec, 0xdb, 0xbd, +0x89, 0xbc, 0xbd, 0xec, 0x7b, 0xd1, 0xef, 0x83, +0xd1, 0xed, 0x84, 0xd1, 0xee, 0xc0, 0xc1, 0xee, +0x84, 0xd3, 0xf0, 0xac, 0xd6, 0x6d, 0x8b, 0xd4, +0xee, 0x91, 0xd5, 0xee, 0x92, 0xd5, 0xef, 0xae, +0xda, 0x71, 0xc6, 0xc7, 0xef, 0x94, 0xd8, 0xf0, +0x97, 0xd9, 0xf1, 0xb2, 0xe0, 0x76, 0xad, 0xd6, +0xe9, 0xcc, 0xcd, 0xf1, 0xa0, 0xdb, 0xf1, 0xe7, +0xda, 0x2b, 0xe8, 0xda, 0x2a, 0xcd, 0xce, 0xf2, +0xea, 0xdb, 0x2a, 0xec, 0xdb, 0x2a, 0xee, 0xdb, +0x2a, 0xef, 0xdc, 0x2a, 0xf1, 0xdc, 0x2a, 0xf2, +0xdc, 0x2a, 0xf4, 0xdc, 0x2a, 0xb9, 0xdb, 0xec, +0xb7, 0xe7, 0x7c, 0xf6, 0xdd, 0x2a, 0xad, 0xdf, +0xf3, 0xf9, 0xdd, 0x29, 0xfa, 0xdd, 0x29, 0xd4, +0xd4, 0xf3, 0xae, 0xe0, 0xf3, 0xfb, 0xde, 0x29, +0xfc, 0xde, 0x29, 0xfe, 0xde, 0x29, 0xbe, 0xde, +0xed, 0xb9, 0xeb, 0x7f, 0xc0, 0xdf, 0xee, 0xc2, +0xe0, 0xee, 0xbb, 0xee, 0x82, 0xed, 0xe3, 0x60, +0xef, 0xe3, 0x5f, 0xc5, 0xe1, 0xef, 0xf0, 0xe4, +0x5f, 0xbc, 0xf0, 0x84, 0xf2, 0xe4, 0x5f, 0xf3, +0xe4, 0x5f, 0xc7, 0xe3, 0xf0, 0xc8, 0xe3, 0xf0, +0xf3, 0xe5, 0x5f, 0xf4, 0xe5, 0x5f, 0xca, 0xe3, +0xf0, 0xf5, 0xe5, 0x5f, 0xf7, 0xe5, 0x5f, 0xf8, +0xe5, 0x5f, 0xcb, 0xe4, 0xf1, 0xde, 0xde, 0xf6, +0xf8, 0xe6, 0x5f, 0xfa, 0xe6, 0x5f, 0xcd, 0xe5, +0xf2, 0xfc, 0xe6, 0x5f, 0xfe, 0xe6, 0x5f, 0xd1, +0xe7, 0xf2, 0xd3, 0xe8, 0xf3, 0xf2, 0xea, 0x87, +0xd4, 0xe9, 0xf3, 0xd4, 0xe9, 0xf4, 0xf4, 0xeb, +0x87, 0xd6, 0xe9, 0xf4, 0xf6, 0xeb, 0x87, 0xf8, +0xeb, 0x87, 0xd7, 0xea, 0xf5, 0xfa, 0xec, 0x87, +0xfd, 0xec, 0x86, 0xfe, 0xec, 0x86, 0xe1, 0xef, +0xf7, 0x95, 0xe0, 0x4b, 0x58, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, +0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, +0x00, 0x02, 0x6b, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xed, 0x94, 0xeb, 0x53, 0xd3, 0x40, 0x14, +0xc5, 0x49, 0x13, 0x15, 0x31, 0xae, 0xa8, 0x08, +0xbe, 0x51, 0xea, 0x1b, 0xeb, 0x0b, 0x05, 0x7c, +0x56, 0x89, 0x4d, 0x4d, 0x0b, 0xb5, 0xd1, 0xa6, +0x48, 0x69, 0x08, 0x09, 0x50, 0x92, 0x62, 0x96, +0x04, 0x0a, 0xa5, 0xa5, 0x85, 0x7f, 0x9d, 0xdd, +0x84, 0x84, 0x24, 0x6d, 0x32, 0x32, 0xce, 0x38, +0x7e, 0xe0, 0x7c, 0xd8, 0xcc, 0xec, 0xe6, 0xb7, +0x67, 0xce, 0xbd, 0x77, 0xb6, 0xa7, 0xe7, 0x44, +0xff, 0x44, 0x7d, 0x14, 0x56, 0x5f, 0xc7, 0xfe, +0x1d, 0x6b, 0xdf, 0xb7, 0x3a, 0x47, 0xd4, 0x87, +0x67, 0xaf, 0x26, 0xbe, 0x53, 0x1d, 0x08, 0xf5, +0x64, 0xe8, 0xea, 0xf5, 0x97, 0xd4, 0x9b, 0x91, +0xfb, 0x8f, 0x3e, 0x52, 0x5f, 0xc6, 0x26, 0x26, +0x7f, 0xba, 0xff, 0x50, 0x8f, 0xaf, 0xdd, 0xbc, +0xfb, 0xb6, 0x0b, 0x32, 0xd4, 0xdb, 0x7b, 0xf6, +0x06, 0x35, 0x7c, 0x69, 0x60, 0xe0, 0x29, 0x35, +0x36, 0x3c, 0x72, 0x6f, 0x92, 0xfa, 0x0b, 0x97, +0xb0, 0x2c, 0x17, 0xad, 0x7d, 0xdf, 0xea, 0x1c, +0xc5, 0x3e, 0xbf, 0x7e, 0xff, 0xf5, 0x77, 0xec, +0xe8, 0xdf, 0x04, 0x4d, 0x27, 0xd0, 0x07, 0xd4, +0xca, 0xe5, 0x72, 0x0d, 0xd4, 0x44, 0x51, 0xac, +0x83, 0xba, 0x24, 0x49, 0x75, 0xe0, 0x22, 0x2f, +0xce, 0x13, 0x97, 0x7f, 0x78, 0x10, 0x7a, 0x7f, +0x9f, 0xc6, 0x48, 0x79, 0x6a, 0x8a, 0x29, 0x03, +0x91, 0x61, 0x52, 0x12, 0x90, 0x58, 0x96, 0x95, +0x3d, 0x08, 0xf1, 0x90, 0xf0, 0x21, 0xbb, 0xbb, +0x36, 0xc2, 0x30, 0x8c, 0x08, 0xc4, 0x54, 0xaa, +0x0b, 0x12, 0x74, 0xd9, 0xd9, 0xf1, 0x20, 0x52, +0x8a, 0x65, 0x2d, 0x24, 0xed, 0x41, 0x82, 0x59, +0x1c, 0xc4, 0x9b, 0xa2, 0x2e, 0xcb, 0x72, 0xc3, +0x45, 0xfa, 0x63, 0x58, 0xa7, 0xc9, 0x5b, 0x01, +0xe4, 0x39, 0xc0, 0xf2, 0xad, 0x3e, 0x97, 0x2b, +0x64, 0x9c, 0x74, 0x91, 0xed, 0x6d, 0xdb, 0xc5, +0xbe, 0x5f, 0x92, 0x65, 0xb4, 0x2a, 0x2b, 0x95, +0xa6, 0x27, 0xcb, 0x6d, 0xe2, 0x02, 0x19, 0x8f, +0x93, 0x8e, 0xe8, 0xcd, 0x4d, 0x1a, 0x7f, 0x07, +0x09, 0x96, 0x70, 0x52, 0xac, 0x70, 0x1c, 0xa7, +0xfa, 0x10, 0x44, 0x60, 0x3d, 0x18, 0x1d, 0x1d, +0x7f, 0xf7, 0x89, 0xde, 0xd8, 0xa0, 0x17, 0x91, +0x48, 0x96, 0x40, 0xc1, 0xe5, 0x74, 0x3a, 0xad, +0x80, 0x0a, 0xc7, 0x65, 0xd4, 0x08, 0x17, 0x84, +0x38, 0x2e, 0x32, 0x46, 0xbe, 0x55, 0x80, 0xca, +0x65, 0x32, 0x1a, 0x08, 0xcf, 0x82, 0x10, 0x9c, +0xc5, 0x4e, 0xd1, 0x50, 0x2a, 0x28, 0x45, 0x53, +0xd5, 0xb4, 0x66, 0xa0, 0x62, 0x67, 0xc8, 0x73, +0x2e, 0xb2, 0xbe, 0xfe, 0x27, 0x15, 0xf3, 0xf5, +0xc5, 0x46, 0x70, 0x2f, 0x94, 0x06, 0xba, 0x5f, +0x55, 0x91, 0x8b, 0xa6, 0x55, 0x5b, 0x11, 0xdd, +0x3f, 0x44, 0xbc, 0x29, 0xb4, 0x6c, 0x2e, 0xa7, +0x47, 0xcc, 0xd8, 0xda, 0x9a, 0x85, 0x28, 0x69, +0x5c, 0x58, 0x35, 0x83, 0x91, 0x6a, 0x2e, 0x97, +0x83, 0x11, 0x2e, 0xab, 0xab, 0x16, 0x62, 0xf7, +0x42, 0xcd, 0x64, 0xb3, 0x55, 0xa0, 0xfb, 0x91, +0x8e, 0x2c, 0xcb, 0xcb, 0x16, 0xe2, 0x4d, 0xd1, +0x82, 0x10, 0xb6, 0x22, 0x66, 0x6c, 0x69, 0xe9, +0xd8, 0x33, 0xb6, 0xb0, 0x70, 0xe8, 0x82, 0x7b, +0xd1, 0xd4, 0x75, 0xdd, 0x76, 0x69, 0x87, 0x76, +0xff, 0x14, 0x46, 0xc8, 0x80, 0x06, 0x09, 0x9e, +0x30, 0x42, 0x67, 0x6c, 0x1c, 0x23, 0x33, 0x33, +0xbf, 0xe6, 0xe7, 0x17, 0x8f, 0x44, 0xf2, 0x44, +0xc1, 0x88, 0x98, 0xb1, 0x52, 0xa9, 0x8b, 0x4b, +0xc1, 0xeb, 0xd2, 0x91, 0x05, 0x21, 0x56, 0x16, +0x5d, 0x87, 0x4e, 0x8a, 0xb6, 0x61, 0x18, 0xed, +0x88, 0x19, 0x9b, 0x9b, 0x3b, 0xf6, 0x8c, 0xd9, +0x88, 0x73, 0x3f, 0x84, 0x06, 0x76, 0x31, 0xcd, +0xbd, 0xb0, 0xee, 0xa3, 0x87, 0x6f, 0x7a, 0x1a, +0x3f, 0x7e, 0x00, 0xe6, 0xf3, 0x79, 0x08, 0x20, +0x5f, 0x40, 0xc1, 0x4d, 0x41, 0x28, 0x9a, 0x61, +0x33, 0x46, 0x6f, 0xcd, 0x26, 0x93, 0xb3, 0x5b, +0xb4, 0x85, 0xf0, 0x10, 0x18, 0x05, 0x41, 0x40, +0x48, 0xb1, 0xe8, 0x43, 0x02, 0x2e, 0xa5, 0x64, +0xb2, 0x64, 0xbb, 0xf0, 0xbc, 0x01, 0x0c, 0x41, +0x10, 0xcc, 0x20, 0x12, 0xc8, 0x92, 0xc0, 0x33, +0x86, 0x1e, 0x65, 0x5f, 0x8a, 0x3d, 0xd3, 0x9b, +0xc5, 0xae, 0x58, 0x7f, 0xc7, 0x33, 0x1e, 0x51, +0xb1, 0x13, 0xfd, 0x7f, 0x3a, 0x00, 0xd4, 0xf9, +0xd7, 0x22, 0x78, 0xf9, 0xcc, 0xa8, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_bmp_heap_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_bmp_heap_png = new wxImage(); + if (!img_ex_bmp_heap_png || !img_ex_bmp_heap_png->IsOk()) + { + wxMemoryInputStream img_ex_bmp_heap_pngIS(ex_bmp_heap_png_data, sizeof(ex_bmp_heap_png_data)); + img_ex_bmp_heap_png->LoadFile(img_ex_bmp_heap_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_bmp_heap_png; +} +#define ex_bmp_heap_png_img ex_bmp_heap_png_img() + +static wxBitmap *ex_bmp_heap_png_bmp() +{ + static wxBitmap *bmp_ex_bmp_heap_png; + if (!bmp_ex_bmp_heap_png || !bmp_ex_bmp_heap_png->IsOk()) + bmp_ex_bmp_heap_png = new wxBitmap(*ex_bmp_heap_png_img); + return bmp_ex_bmp_heap_png; +} +#define ex_bmp_heap_png_bmp ex_bmp_heap_png_bmp() + +static wxIcon *ex_bmp_heap_png_ico() +{ + static wxIcon *ico_ex_bmp_heap_png; + if (!ico_ex_bmp_heap_png || !ico_ex_bmp_heap_png->IsOk()) + { + ico_ex_bmp_heap_png = new wxIcon(); + ico_ex_bmp_heap_png->CopyFromBitmap(*ex_bmp_heap_png_bmp); + } + return ico_ex_bmp_heap_png; +} +#define ex_bmp_heap_png_ico ex_bmp_heap_png_ico() + +#endif // EX_BMP_HEAP_PNG_H diff --git a/include/images/ex_bmp_index.png b/include/images/ex_bmp_index.png new file mode 100644 index 0000000000000000000000000000000000000000..23b9733b56792533e4db25ca9890a0a0140c6ff9 GIT binary patch literal 1172 zcmV;F1Z(?=P)iMiWk#pq(j>Y>D5 zYsctl$n2uVV6(L9Zp-X(%j|E>?xxITcFpXi!Q|V#etORA+r5d~zJR>F?0eDg-NAx` z(d~rM?%l(Kz`^c>)9|d;ZQjL&i`4Gl$A^*C?%>FXlGX37+HuCm@8HUbl-Tg$%!-%U z@#4;mCDaX<<6kv(T?ZZE6vXG=Fy>}-SXtrk>=B+^4u!t)TFuF?6>E9 zt>5$1)bp<3^XA!==+~zI-YMzWr@r3px$A%D+?T-L?&;d7!r<=c-k9s!x9Z%g?c-qY z<6p($@9N#GyzqqcGRa-^w#P0@aMtr>9p7C_3`P${_KYG?Z)Bn_g>Mo zbpQYW0d!JMQvg8b*k%9#010qNS#tmY3ljhU3ljkVnw%H_00N9jL_t(Y$L*BsQxZ`a zhh26nvhB^vO1oLo-JmFv5|N5XBA|_nRxB8D7XcMR7F@v#0{+$QVK1_a?Bq1l^uhPT z*_pHZ%x|7^ezOAuC-YBckU%rovwx?vFI&Y|#D{0EroRzA2=QcObo3?hX8iu6kHpu> z>6stWH^k%XH}AeZ0vXY2wKs^dOT)uYiOI3?do#per1Wz++u7&Wi~K6S(tLjX{>v}T z;kSB{)N>E0r_<>=v>S~^8`><(wn0K(oX0MI??T9f0}>%=uh*M~Mn0c!0Gmiet6d28 z5R)PM`wD~wHX4nVRZ@0$Wk@2yLNyu+bsbiox#sZ z$i~K>oS5uhcm(RXT&@m##cZ|)wNxxtQMr8q$pr#|oL~`iI2^P}$JW;+qy$+HkJ#1GLR%4T9fnRv_|@#p7Km zwAE@sh{;5$bc{nfE(~(vEeaGxB~?1MxOnW2@ran>r>FuX-EMcX-|cfhzPUN{^8+Rv z=Ja_Bx6xp5_UjnAz2I^!Y?C5FnM@`(xD9edkrH>g;)f}e$!P3B6fSzyF}>u%TO^%M mr}D&xdVb?7Cw4Ob-~0w&gyX$CR{j?N0000IsOk()) + { + wxMemoryInputStream img_ex_bmp_index_pngIS(ex_bmp_index_png_data, sizeof(ex_bmp_index_png_data)); + img_ex_bmp_index_png->LoadFile(img_ex_bmp_index_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_bmp_index_png; +} +#define ex_bmp_index_png_img ex_bmp_index_png_img() + +static wxBitmap *ex_bmp_index_png_bmp() +{ + static wxBitmap *bmp_ex_bmp_index_png; + if (!bmp_ex_bmp_index_png || !bmp_ex_bmp_index_png->IsOk()) + bmp_ex_bmp_index_png = new wxBitmap(*ex_bmp_index_png_img); + return bmp_ex_bmp_index_png; +} +#define ex_bmp_index_png_bmp ex_bmp_index_png_bmp() + +static wxIcon *ex_bmp_index_png_ico() +{ + static wxIcon *ico_ex_bmp_index_png; + if (!ico_ex_bmp_index_png || !ico_ex_bmp_index_png->IsOk()) + { + ico_ex_bmp_index_png = new wxIcon(); + ico_ex_bmp_index_png->CopyFromBitmap(*ex_bmp_index_png_bmp); + } + return ico_ex_bmp_index_png; +} +#define ex_bmp_index_png_ico ex_bmp_index_png_ico() + +#endif // EX_BMP_INDEX_PNG_H diff --git a/include/images/ex_bmp_or.png b/include/images/ex_bmp_or.png new file mode 100644 index 0000000000000000000000000000000000000000..c22fc31eee32e53abf634278f9d57751181f15c0 GIT binary patch literal 685 zcmV;e0#f~nP)DsC3+^Xu_s_Wah>)x#F-MQ@G zt?b~g?cclJ-uCR`uk7Qn@8rMa^SK@x>8z5V~+lCW40^I>$hY<=+l#CCS=?A!_rGtXZp&xOfP4=T~1 zLLuDg&VhK#Q3h9{B+&*8S6f~eBpML~p(b&^vn6@U$0T2m#b{8Z5cd4&_~MEE7O~-9 zf*=_4G_tn|`*$&UE0u;Z3AUi@Ws_kpcNvpsxCSJ7EW-w!ByJ(e*z+DnG*V#06sAdo z57R(x899zKpx?3pi_}}3HCVOj1h#=r;0$csmirZ0vT%(JY|HXz-k5KiT_1Ogc>-+% z*I2g=Ed#gZrjMO1> z^3%t=s-pBVfBn$JPrOoxdMEQgMkXTi54I4blS&e|kfbNeaxb$nGU<)Y^N;cg@O4qi TF88uo00000NkvXXu0mjfLbGwY literal 0 HcmV?d00001 diff --git a/include/images/ex_bmp_or.pngc b/include/images/ex_bmp_or.pngc new file mode 100644 index 0000000..63ab5cc --- /dev/null +++ b/include/images/ex_bmp_or.pngc @@ -0,0 +1,130 @@ +#ifndef EX_BMP_OR_PNG_H +#define EX_BMP_OR_PNG_H + +static const unsigned char ex_bmp_or_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x00, 0xff, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, +0x58, 0x58, 0x66, 0x6b, 0xd1, 0x36, 0x88, 0xc1, +0x64, 0x95, 0xd0, 0x8d, 0x8e, 0xbf, 0xc1, 0x8f, +0x36, 0x8f, 0x92, 0xdd, 0x7a, 0x9e, 0xa9, 0x9a, +0x9a, 0x9a, 0x9b, 0x9c, 0xc4, 0xb9, 0xa7, 0x72, +0x4e, 0xbe, 0xe6, 0xbb, 0xaa, 0x73, 0xbb, 0xac, +0x74, 0xbb, 0xad, 0x76, 0x5a, 0xc1, 0xe7, 0xbc, +0xb0, 0x77, 0xbd, 0xb1, 0x79, 0xab, 0xac, 0xe8, +0xbe, 0xb2, 0x7a, 0x89, 0xb9, 0xdb, 0x64, 0xc5, +0xe8, 0xb3, 0xb4, 0xea, 0xba, 0xba, 0xba, 0x71, +0xcb, 0xec, 0xda, 0xbb, 0x7e, 0x7a, 0xce, 0xec, +0xdb, 0xbd, 0x89, 0xdc, 0xbe, 0x80, 0xbc, 0xbd, +0xec, 0xbc, 0xbd, 0xed, 0xdd, 0xc1, 0x82, 0x83, +0xd1, 0xed, 0xdd, 0xc2, 0x83, 0xc0, 0xc1, 0xee, +0x8b, 0xd4, 0xee, 0xdf, 0xc6, 0x86, 0xdf, 0xc8, +0x87, 0x92, 0xd5, 0xef, 0xc6, 0xc7, 0xef, 0xe0, +0xca, 0x89, 0x94, 0xd8, 0xf0, 0xe3, 0xcb, 0x9e, +0xe3, 0xcc, 0x9e, 0xe4, 0xcd, 0x9e, 0xe2, 0xd0, +0x8d, 0xe4, 0xce, 0x9f, 0xcc, 0xcd, 0xf1, 0xcd, +0xce, 0xf2, 0xd1, 0xd1, 0xd1, 0xe5, 0xd0, 0xa1, +0xe6, 0xd1, 0xa2, 0xa6, 0xde, 0xf2, 0xe5, 0xd6, +0x93, 0xe6, 0xd4, 0xa4, 0xe7, 0xd5, 0xa5, 0xad, +0xdf, 0xf3, 0xd4, 0xd4, 0xf3, 0xe8, 0xd7, 0xa6, +0xe8, 0xd7, 0xa7, 0xea, 0xd8, 0xb6, 0xe9, 0xda, +0xa8, 0xe9, 0xda, 0xa9, 0xe9, 0xdc, 0xaa, 0xea, +0xdc, 0xaa, 0xeb, 0xdb, 0xb8, 0xeb, 0xde, 0xac, +0xec, 0xdd, 0xb9, 0xec, 0xe0, 0xad, 0xec, 0xe0, +0xae, 0xed, 0xdf, 0xbb, 0xde, 0xde, 0xf6, 0xec, +0xe2, 0xaf, 0xec, 0xe3, 0xb0, 0xef, 0xe4, 0xbf, +0xe4, 0xe4, 0xe4, 0xf0, 0xe6, 0xc0, 0xf0, 0xe7, +0xc1, 0xf1, 0xeb, 0xc4, 0xec, 0xec, 0xec, 0xef, +0xef, 0xef, 0xf4, 0xf4, 0xf4, 0xff, 0xff, 0xff, +0x89, 0xb7, 0xf1, 0xf7, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, +0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, +0x01, 0x47, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, +0xed, 0xd4, 0x6d, 0x4f, 0x82, 0x60, 0x14, 0x06, +0x60, 0x8e, 0x60, 0xa8, 0xbd, 0x67, 0x49, 0x6a, +0x56, 0x56, 0x28, 0x15, 0x12, 0x15, 0x14, 0x95, +0x08, 0x41, 0x12, 0x85, 0x2f, 0xbd, 0xfd, 0xff, +0xdf, 0x92, 0xb0, 0x58, 0x0f, 0xf3, 0x61, 0x74, +0xb6, 0x6c, 0x7d, 0xf0, 0xfe, 0xc4, 0x76, 0x76, +0xed, 0xec, 0xdc, 0x0a, 0x0c, 0x33, 0xcf, 0x5f, +0x26, 0xcf, 0x85, 0xc9, 0x4f, 0x0f, 0x2a, 0xd1, +0xa0, 0x42, 0x21, 0xdc, 0xe9, 0xce, 0x81, 0x78, +0xcb, 0x51, 0x06, 0x57, 0xa2, 0x24, 0xd1, 0x06, +0x0c, 0x57, 0x5b, 0x5e, 0x17, 0x24, 0x1a, 0x11, +0x05, 0xa1, 0x26, 0x71, 0xbf, 0xb3, 0x25, 0x79, +0xcb, 0xc7, 0x24, 0x5f, 0x8f, 0xc5, 0x68, 0x50, +0xa4, 0x10, 0xf6, 0xfc, 0xe8, 0xf8, 0xe2, 0x89, +0xfd, 0x16, 0xb1, 0xe1, 0x5f, 0x82, 0x20, 0x18, +0xf3, 0x34, 0xb2, 0xb7, 0x09, 0xfb, 0x77, 0x31, +0x79, 0x2b, 0x95, 0x86, 0x31, 0x09, 0xb6, 0xa0, +0xec, 0x65, 0x93, 0x61, 0x2e, 0x77, 0x19, 0x93, +0x67, 0xb8, 0x06, 0x24, 0x79, 0x2c, 0xc3, 0x06, +0x9d, 0x24, 0x6e, 0x21, 0xc9, 0xd8, 0xf3, 0x1e, +0x46, 0x34, 0x52, 0x60, 0xc3, 0x14, 0xa6, 0x49, +0x83, 0x0f, 0xd3, 0x40, 0x6d, 0x19, 0x39, 0x8e, +0x33, 0xa0, 0xdf, 0xb2, 0x00, 0x8b, 0xd4, 0x5b, +0x9c, 0x35, 0x58, 0xb5, 0xe9, 0x04, 0xb6, 0x81, +0x4e, 0xe0, 0x0c, 0x6c, 0xdc, 0x96, 0xfb, 0x15, +0x58, 0xb2, 0x70, 0x8d, 0x0d, 0x6c, 0xcb, 0xf2, +0x67, 0xde, 0x98, 0x6f, 0x9a, 0x5d, 0x1f, 0x77, +0x8b, 0x79, 0x02, 0x6d, 0x03, 0xd7, 0x58, 0xb7, +0x0d, 0x2d, 0x03, 0xb7, 0xe5, 0xa6, 0x95, 0x46, +0xd2, 0x6f, 0x31, 0x0c, 0xa3, 0x3f, 0xf3, 0xc6, +0xfa, 0xba, 0xae, 0xbb, 0xb8, 0xf7, 0x45, 0x3f, +0x84, 0xa6, 0x86, 0x24, 0x4d, 0xd8, 0x45, 0x12, +0x6d, 0x42, 0x54, 0x5c, 0x63, 0xae, 0xa6, 0xaa, +0x6e, 0x76, 0x63, 0xef, 0xd5, 0xea, 0x2b, 0xae, +0x31, 0xf2, 0xd3, 0xc7, 0xbb, 0xaa, 0xa2, 0xf4, +0x32, 0x7f, 0xfd, 0xd0, 0xc4, 0x4f, 0xbc, 0x52, +0x87, 0x7a, 0x27, 0xf3, 0x3f, 0x46, 0x26, 0x22, +0xf2, 0x0f, 0xb6, 0x10, 0xa4, 0x93, 0x4a, 0x12, +0xb7, 0x90, 0xa4, 0x27, 0xcb, 0x72, 0x2f, 0xb3, +0x31, 0x32, 0xe9, 0x8d, 0xcd, 0xf3, 0x8f, 0xf2, +0x09, 0xf0, 0x75, 0x51, 0xc9, 0x2e, 0xf7, 0xb2, +0x59, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_bmp_or_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_bmp_or_png = new wxImage(); + if (!img_ex_bmp_or_png || !img_ex_bmp_or_png->IsOk()) + { + wxMemoryInputStream img_ex_bmp_or_pngIS(ex_bmp_or_png_data, sizeof(ex_bmp_or_png_data)); + img_ex_bmp_or_png->LoadFile(img_ex_bmp_or_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_bmp_or_png; +} +#define ex_bmp_or_png_img ex_bmp_or_png_img() + +static wxBitmap *ex_bmp_or_png_bmp() +{ + static wxBitmap *bmp_ex_bmp_or_png; + if (!bmp_ex_bmp_or_png || !bmp_ex_bmp_or_png->IsOk()) + bmp_ex_bmp_or_png = new wxBitmap(*ex_bmp_or_png_img); + return bmp_ex_bmp_or_png; +} +#define ex_bmp_or_png_bmp ex_bmp_or_png_bmp() + +static wxIcon *ex_bmp_or_png_ico() +{ + static wxIcon *ico_ex_bmp_or_png; + if (!ico_ex_bmp_or_png || !ico_ex_bmp_or_png->IsOk()) + { + ico_ex_bmp_or_png = new wxIcon(); + ico_ex_bmp_or_png->CopyFromBitmap(*ex_bmp_or_png_bmp); + } + return ico_ex_bmp_or_png; +} +#define ex_bmp_or_png_ico ex_bmp_or_png_ico() + +#endif // EX_BMP_OR_PNG_H diff --git a/include/images/ex_broadcast_motion.png b/include/images/ex_broadcast_motion.png new file mode 100644 index 0000000000000000000000000000000000000000..e99f57478842f61cf0582433b659d37f0c532d5c GIT binary patch literal 334 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_@3?!2S6O@1yXMj(LE06{PXIHn!e64$cEXI-` zzhDN3XE)M-9L@rd$YLPv0mg18v+aP48c!F;5RLO&CtC9zP~dS+JaMn}cL58V&ewnH znS#1o7niJ>^>*TX*`QzgMdD7POzPaTo+w<9uwpLL)1F%W#!IqdhoMSxhwp~0@cf02 zhkMjmROfZc`EZ)w`S;|i<*e@Qr8gQ^@9R11|6Rc8|AQ9IRLjSmUOFeWtM)%%ZozPh zRpl$&!*g?h?ocgpjVMV;EJ?LWE=mPb3`Pcq2D*kux(0?JMg~?U##SaK+6Jap1_l;0 rRpn4LIsOk()) + { + wxMemoryInputStream img_ex_broadcast_motion_pngIS(ex_broadcast_motion_png_data, sizeof(ex_broadcast_motion_png_data)); + img_ex_broadcast_motion_png->LoadFile(img_ex_broadcast_motion_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_broadcast_motion_png; +} +#define ex_broadcast_motion_png_img ex_broadcast_motion_png_img() + +static wxBitmap *ex_broadcast_motion_png_bmp() +{ + static wxBitmap *bmp_ex_broadcast_motion_png; + if (!bmp_ex_broadcast_motion_png || !bmp_ex_broadcast_motion_png->IsOk()) + bmp_ex_broadcast_motion_png = new wxBitmap(*ex_broadcast_motion_png_img); + return bmp_ex_broadcast_motion_png; +} +#define ex_broadcast_motion_png_bmp ex_broadcast_motion_png_bmp() + +static wxIcon *ex_broadcast_motion_png_ico() +{ + static wxIcon *ico_ex_broadcast_motion_png; + if (!ico_ex_broadcast_motion_png || !ico_ex_broadcast_motion_png->IsOk()) + { + ico_ex_broadcast_motion_png = new wxIcon(); + ico_ex_broadcast_motion_png->CopyFromBitmap(*ex_broadcast_motion_png_bmp); + } + return ico_ex_broadcast_motion_png; +} +#define ex_broadcast_motion_png_ico ex_broadcast_motion_png_ico() + +#endif // EX_BROADCAST_MOTION_PNG_H diff --git a/include/images/ex_cte_scan.png b/include/images/ex_cte_scan.png new file mode 100644 index 0000000000000000000000000000000000000000..7e1d779372f7fd212d2096e7701b0f1af05a5297 GIT binary patch literal 1955 zcmV;U2VD4xP)VwnpiPi9C$n0v#>~6~Jl-Ti^+VOnO z?SRnjgVF7z-SMd2@{ZK*k=5>#*6*+3^8}~i2&m#nzv)fE=@+fz9k1hC#p`0n>oc|G zIJf0JxaD!n?0C-XP`>9?z~@=P=Z4YkYscts$mx~W?^vpv&`|v;qUjj>z}pi zp2zRDvgw_%>7B#xwXNu!tLL1m=bOLnw5H~orRJKX<(j(ev)AhNwCbL->YcCYov-Me zspp%c<(i`9nYrw<*6H-b@3yY!oT%oTr{();xa+gX z@5PDRjnwJ%!|t`d?X=DD$I0-;w(7FA>aw)zvc>Pj)9CZV@3yDrnw;a9n&X(6;+L}N zvC`-Bp5&OC;+L1=m$2!vuj!nPsD)8oPC7a|R9;dzayvalJ#K?+tlz4Z;g+xIu+Zl6 ze0+S^*x3L7|CW}P^78VdqoaeGgs|zb!R^D&=JGd|Ja2Dr%F4=NVPRT)TsFEr&gJrA zYhZqvd#l!@evf-NgFLLvsa9TAIC(q6?!>L=u&n5?!0p4#lqP?83+6@HtF6IaNDqoNPFaJb%Z6#^Ud@>9NG_#IESDs^_r1 z?8Ch5!=~o0rRJ`r=B~T!!o}h5vFWjr;FgHplZM@sh1`;(<*mcu?up)$h1`>b+>)Z@ zt-|2%w(GK#;g+Q3t%BT=q2#T?;O?&Ju)6EQxa+~d-|npEu&d{=zU;%N=B}XRt)Jwr zw(7yT+w6ebk$&2dp5v|5>GQtc?XA}7jo+1w-;{mYk;vok=7Bya00001bW%=J06^y0 zW&i*H0b)x>M2><5vu^+Z010qNS#tmY07w7;07w8v$!k6U00YfQL_t(Y$L-W-R8wad z2XMU3+PbUOs&(&~2LeQcLX^Y^21QXIq7WBos|+>9t=FhQNW|d4jU(WSL0d;0i32wU z%aDMeq5>+43_}!)zV`(@$vxqN=XiSh!RN!9FZrE+{?C1LZEU{Je?9dGYU(_#5u$#B zh7B7LjhpD#aW0HXcCfrADU-za4W{>^os7T+DpU<^ecU~6Y*XA8DWro96=II>v7U^tuYGy+CC zyKqK<1!0UH&7g>#tE(#$m|QNG2dpuC{#anUxsMZoi^up0o-{IXq8YL0PV#aD7Ju>- zHaNMD^L7T#1Rq}^jZB?dOStyHo8&cy1%6YexjBKrd%8ad0(^W$GprL^ru~-|GuckF zPzx6hXEw|U44e^UmCOZd>O3vUym>gqfyZ-1DSp4RXTk`9;E(w*D!@}X2Nnc}goe>l z7B0ku=S8(xG_9t^Vh(uvicpJS@e;{W8diK(4~sdWKB-BdkyEEI5qO{W{}ZMBb>?jBxf(*H z#A!6=wKQ_!LN%Gb*yCbEb(g(nLwrht_CEZRnwFkH zOL_1B6LdX9_3e4$3Y5ik(!nLFo#BRb1?}NEfvtA{}yYi&CSp!emYu?>|&let6HY0p)XpK?TJh|HX^V%Fc(pf&ybHlvPwz znJiOsD=TxUlw^ZiT?`4Ab-EHr%YKX&TWB;I%fM7sWl50v^oe>YLv&nmN<7@xm!xLE ztC|*Ns71NSWGc7ZSj}tvYc}?M{$KMM@J07H8ln{50000bbVXQnWMOn=I%9HWVRU5x zGB7bPEip1JFfmjzFgi3dIy5vZFf}?bFgTed9smFUC3HntbYx+4WjbwdWNBu305UK! pFfA}SEif@uGBY|fG&(RgD=;-WFfhuORjdF2002ovPDHLkV1ib?C5Zq4 literal 0 HcmV?d00001 diff --git a/include/images/ex_cte_scan.pngc b/include/images/ex_cte_scan.pngc new file mode 100644 index 0000000..1e551d0 --- /dev/null +++ b/include/images/ex_cte_scan.pngc @@ -0,0 +1,289 @@ +#ifndef EX_CTE_SCAN_PNG_H +#define EX_CTE_SCAN_PNG_H + +static const unsigned char ex_cte_scan_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x03, 0x00, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x89, 0xb9, 0xdb, 0x36, +0x88, 0xc1, 0x6f, 0xcd, 0xee, 0x41, 0xbd, 0xe9, +0x45, 0xbe, 0xe9, 0x75, 0xce, 0xef, 0x79, 0xd0, +0xef, 0x51, 0xc2, 0xea, 0x54, 0xc2, 0xea, 0x57, +0xc3, 0xea, 0x83, 0xd3, 0xf0, 0x89, 0xd5, 0xf0, +0x66, 0xc8, 0xec, 0x6a, 0xc9, 0xec, 0x6e, 0xca, +0xec, 0x94, 0xd8, 0xf1, 0x99, 0xda, 0xf1, 0x7c, +0xce, 0xed, 0x80, 0xd0, 0xed, 0x83, 0xd1, 0xed, +0xa4, 0xdd, 0xf1, 0xa8, 0xde, 0xf2, 0x8e, 0xd4, +0xee, 0x91, 0xd5, 0xee, 0x93, 0xd6, 0xef, 0xaf, +0xe1, 0xf3, 0x04, 0xa7, 0xe1, 0x08, 0xa8, 0xe2, +0x48, 0xbf, 0xe9, 0x4d, 0xc1, 0xe9, 0x17, 0xad, +0xe3, 0x1d, 0xaf, 0xe3, 0x5b, 0xc5, 0xeb, 0x62, +0xc7, 0xeb, 0x33, 0xb5, 0xe5, 0x38, 0xb7, 0xe5, +0x3d, 0xb8, 0xe5, 0x71, 0xcb, 0xec, 0x78, 0xce, +0xec, 0x50, 0xbe, 0xe7, 0x55, 0xc0, 0xe7, 0x59, +0xc1, 0xe7, 0x86, 0xd1, 0xed, 0x6b, 0xc7, 0xe8, +0x6f, 0xc8, 0xe9, 0x95, 0xd7, 0xef, 0x58, 0xaa, +0xab, 0xa5, 0xc1, 0xe4, 0x66, 0x96, 0xd1, 0x36, +0xc1, 0x3d, 0xd7, 0xf4, 0xc9, 0xca, 0xf0, 0xb7, +0xc9, 0xf0, 0xb6, 0xc8, 0xef, 0xb6, 0xd4, 0xf3, +0xc8, 0xc6, 0xef, 0xb6, 0xc5, 0xef, 0xb6, 0xd2, +0xf3, 0xc8, 0xd2, 0xf2, 0xc7, 0xc2, 0xee, 0xb5, +0xc1, 0xee, 0xb5, 0xd0, 0xf1, 0xc7, 0xce, 0xf1, +0xc7, 0xbe, 0xec, 0xb4, 0xbd, 0xec, 0xb4, 0xbc, +0xec, 0xb3, 0xcc, 0xf1, 0xc6, 0xe1, 0xef, 0xf7, +0xb8, 0xeb, 0x9f, 0xb5, 0xea, 0x9e, 0xc7, 0xef, +0xb6, 0xb2, 0xe9, 0x9d, 0xb1, 0xe9, 0x9d, 0xc3, +0xef, 0xb5, 0xad, 0xe8, 0x9c, 0xab, 0xe7, 0x9c, +0xaa, 0xe7, 0x9b, 0xbf, 0xed, 0xb4, 0xa6, 0xe6, +0x9a, 0xa5, 0xe6, 0x9a, 0xa4, 0xe5, 0x9a, 0xba, +0xec, 0xb3, 0xd7, 0xea, 0xf5, 0xb4, 0xea, 0x9e, +0xb3, 0xea, 0x9d, 0xaf, 0xe9, 0x9d, 0xaf, 0xe8, +0x9c, 0xa9, 0xe7, 0x9b, 0xa3, 0xe5, 0x9a, 0xa2, +0xe5, 0x99, 0xb9, 0xec, 0xb3, 0xd6, 0xe9, 0xf4, +0xc4, 0xef, 0xb6, 0xae, 0xe8, 0x9c, 0xa8, 0xe6, +0x9b, 0xa7, 0xe6, 0x9b, 0xbb, 0xec, 0xb3, 0xa0, +0xe4, 0x99, 0xb7, 0xeb, 0xb3, 0xd1, 0xf2, 0xc7, +0xc0, 0xed, 0xb5, 0xcc, 0xf0, 0xc6, 0xca, 0xf0, +0xc5, 0xb8, 0xeb, 0xb3, 0xc8, 0xef, 0xc5, 0x89, +0xdb, 0x8d, 0xd4, 0xe9, 0xf4, 0xc3, 0xee, 0xb5, +0xbe, 0xed, 0xb4, 0xcd, 0xf1, 0xc7, 0xc9, 0xf0, +0xc5, 0xb6, 0xea, 0xb2, 0xb5, 0xea, 0xb2, 0xb4, +0xea, 0xb2, 0xc5, 0xef, 0xc4, 0xd3, 0xe8, 0xf3, +0xc3, 0xef, 0xb6, 0xa7, 0xe6, 0x9a, 0x9c, 0xe3, +0x98, 0x9a, 0xe3, 0x98, 0x99, 0xe2, 0x97, 0xb2, +0xe9, 0xb1, 0xd2, 0xe7, 0xf3, 0x9e, 0xe4, 0x98, +0x9a, 0xe2, 0x97, 0x97, 0xe2, 0x97, 0xb0, 0xe9, +0xb1, 0xaf, 0xe9, 0x9c, 0x8d, 0xa8, 0x85, 0x51, +0x5d, 0x4e, 0x3a, 0x3a, 0x3a, 0x54, 0x5e, 0x52, +0x38, 0x72, 0x3b, 0x3d, 0x44, 0x3d, 0x6e, 0x83, +0x6c, 0xac, 0xdf, 0xaa, 0x96, 0xe1, 0x96, 0xaf, +0xe9, 0xb0, 0xd0, 0xe6, 0xf2, 0x7c, 0x7c, 0x7c, +0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xff, 0x96, 0x96, +0x96, 0xf2, 0xf2, 0xf2, 0xa3, 0xa3, 0xa3, 0x83, +0x9a, 0x84, 0xb0, 0xe9, 0xb0, 0xc1, 0xed, 0xc3, +0xce, 0xe6, 0xf2, 0x37, 0x96, 0x3c, 0x6f, 0x6f, +0x6f, 0xca, 0xca, 0xca, 0x61, 0x61, 0x61, 0x5a, +0x7c, 0x5c, 0x36, 0xba, 0x3d, 0xce, 0xe5, 0xf2, +0x62, 0x6b, 0x60, 0x7e, 0x99, 0x7b, 0xab, 0xd6, +0xa4, 0x7e, 0x8f, 0x7b, 0x38, 0x83, 0x3c, 0xac, +0xcc, 0xa9, 0x56, 0x5e, 0x56, 0x38, 0x79, 0x3b, +0xc3, 0xee, 0xc4, 0xad, 0xe8, 0xb0, 0xac, 0xe8, +0xb0, 0xc0, 0xed, 0xc3, 0xcc, 0xe5, 0xf1, 0x81, +0xac, 0x7a, 0x9e, 0xc8, 0x9b, 0x52, 0x5d, 0x52, +0x96, 0xc5, 0x98, 0x91, 0xe0, 0x95, 0x90, 0xdf, +0x95, 0x8f, 0xdf, 0x95, 0xaa, 0xe7, 0xaf, 0xcb, +0xe4, 0xf1, 0xa8, 0xe7, 0x9b, 0x5d, 0x69, 0x5a, +0x71, 0x95, 0x6d, 0x94, 0xcf, 0x8d, 0x75, 0x8d, +0x72, 0x9d, 0xc7, 0x9a, 0x8d, 0xdf, 0x94, 0xa9, +0xe6, 0xaf, 0xca, 0xe3, 0xf0, 0x91, 0xb1, 0x8b, +0xa4, 0xde, 0xaa, 0x8c, 0xde, 0x94, 0x8b, 0xde, +0x94, 0xa7, 0xe6, 0xaf, 0xc8, 0xe3, 0xf0, 0xcb, +0xf0, 0xc6, 0x89, 0x89, 0x89, 0xe5, 0xe5, 0xe5, +0xbc, 0xec, 0xc2, 0xc7, 0xe3, 0xf0, 0x39, 0x4c, +0x3a, 0x39, 0x55, 0x3b, 0x6a, 0x9c, 0x6c, 0x38, +0x8d, 0x3c, 0x7f, 0xc7, 0x82, 0xc6, 0xe2, 0xef, +0xb3, 0xe9, 0xb1, 0xc4, 0xee, 0xc4, 0xae, 0xe8, +0xb0, 0xaa, 0xe7, 0xb0, 0xbd, 0xec, 0xc3, 0xbc, +0xec, 0xc3, 0xa6, 0xe6, 0xae, 0xa5, 0xe6, 0xae, +0xa4, 0xe6, 0xae, 0xbb, 0xec, 0xc2, 0xc5, 0xe1, +0xef, 0xb1, 0xe9, 0xb1, 0x92, 0xe0, 0x96, 0x88, +0xdd, 0x93, 0x86, 0xdd, 0x93, 0x85, 0xdc, 0x92, +0xa3, 0xe5, 0xad, 0xc3, 0xe0, 0xee, 0x89, 0xde, +0x93, 0x85, 0xdc, 0x93, 0x84, 0xdc, 0x92, 0xa2, +0xe5, 0xad, 0xc2, 0xe0, 0xef, 0xb6, 0xeb, 0xb2, +0x94, 0xe1, 0x96, 0xa4, 0xe5, 0xad, 0x82, 0xdc, +0x92, 0xa1, 0xe4, 0xad, 0xc2, 0xe0, 0xee, 0xae, +0xe9, 0xb0, 0xba, 0xeb, 0xc2, 0xb8, 0xeb, 0xc1, +0xc0, 0xdf, 0xee, 0xac, 0xe7, 0xb0, 0xab, 0xe7, +0xb0, 0xbe, 0xec, 0xc3, 0xa7, 0xe6, 0xae, 0xa0, +0xe4, 0xad, 0x9f, 0xe4, 0xad, 0xb6, 0xea, 0xc1, +0xb9, 0xdb, 0xec, 0x80, 0xdb, 0x91, 0x7e, 0xda, +0x91, 0x9e, 0xe3, 0xad, 0xd4, 0xe9, 0xf3, 0xbe, +0xde, 0xed, 0xad, 0xd6, 0xe9, 0x8d, 0xdf, 0x95, +0x8c, 0xdf, 0x94, 0x7d, 0xda, 0x91, 0xc8, 0xe3, +0xef, 0xe6, 0x81, 0x3e, 0x28, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, +0x47, 0x44, 0x8e, 0x82, 0x05, 0xb3, 0x6f, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x03, 0xcd, +0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xed, 0xd4, +0x67, 0x54, 0x53, 0x67, 0x18, 0x07, 0x70, 0xbc, +0xce, 0xda, 0xba, 0xab, 0xd6, 0xaa, 0x75, 0xef, +0x99, 0x07, 0x02, 0x44, 0x83, 0x42, 0x94, 0xc4, +0x08, 0x06, 0x45, 0x51, 0x20, 0xa2, 0x10, 0x17, +0x68, 0xab, 0x0c, 0x35, 0xc6, 0xad, 0xd7, 0xa8, +0x41, 0x48, 0xc4, 0xe0, 0xc0, 0x8d, 0x23, 0xe0, +0x8a, 0x41, 0x5b, 0x47, 0x1c, 0x89, 0x03, 0x37, +0x05, 0xcb, 0x90, 0x80, 0xa0, 0xa2, 0x02, 0x2a, +0x8a, 0x0c, 0x43, 0x14, 0x8b, 0xbe, 0xf7, 0x05, +0x3c, 0xc9, 0x3d, 0xe1, 0x83, 0xe7, 0x78, 0x7a, +0xfa, 0xc1, 0xe7, 0xc3, 0x9b, 0x2f, 0xf9, 0x9d, +0x7f, 0xfe, 0xcf, 0x7d, 0x73, 0x6d, 0x6c, 0xbe, +0xcf, 0x7f, 0x3d, 0xf5, 0x08, 0x6a, 0xea, 0x3c, +0xad, 0x11, 0xa2, 0x7e, 0x83, 0x86, 0x0d, 0x1b, +0x11, 0x8d, 0x9b, 0xfc, 0xd0, 0xf4, 0x47, 0xe2, +0xa7, 0x66, 0xcd, 0x5b, 0xb4, 0x24, 0x5a, 0xb5, +0x6e, 0xf3, 0x73, 0x5b, 0xa2, 0x5d, 0xfb, 0x5f, +0x3a, 0xfc, 0x4a, 0x58, 0x25, 0x0d, 0x3a, 0x76, +0xec, 0xd4, 0x99, 0xf8, 0xad, 0x4b, 0xd7, 0xae, +0xdd, 0x88, 0xee, 0x3d, 0x7a, 0xf6, 0xea, 0x4d, +0xf4, 0xe9, 0xdb, 0xaf, 0xff, 0x00, 0xa2, 0xfd, +0xc0, 0x81, 0x83, 0x06, 0x13, 0xdf, 0x28, 0x65, +0x08, 0xfe, 0xcd, 0x75, 0x9e, 0x16, 0xdf, 0x1d, +0xca, 0x60, 0x0c, 0x45, 0x1f, 0x60, 0x6b, 0x67, +0x67, 0x67, 0x0b, 0xb6, 0x4c, 0xa6, 0xbd, 0x03, +0x38, 0x38, 0xb2, 0x58, 0xc3, 0x60, 0x38, 0x9b, +0xed, 0x34, 0x02, 0x46, 0x3a, 0xbb, 0x70, 0x46, +0x81, 0x05, 0x61, 0x8c, 0x1e, 0xcd, 0xa0, 0x88, +0x9d, 0xab, 0xab, 0x2b, 0x13, 0x98, 0x5c, 0x2e, +0x97, 0x07, 0xac, 0x31, 0x7c, 0xfe, 0x58, 0x60, +0xbb, 0xb9, 0x8f, 0x13, 0x80, 0x8b, 0xc7, 0xf8, +0x09, 0x9e, 0x34, 0x32, 0x71, 0xa2, 0x19, 0xb1, +0xe7, 0x4e, 0xf2, 0x72, 0x04, 0x16, 0x7f, 0xf2, +0x14, 0x36, 0x38, 0xb9, 0x8f, 0xf3, 0x76, 0x06, +0xce, 0x04, 0x1f, 0x5f, 0x21, 0x8d, 0x4c, 0x9d, +0x5a, 0x4b, 0xb8, 0xf6, 0xc0, 0x9b, 0xe4, 0x35, +0x86, 0x05, 0x7e, 0x53, 0xa6, 0xb9, 0x39, 0x81, +0xc0, 0x7b, 0xba, 0x3f, 0x07, 0x02, 0x7c, 0x7c, +0x45, 0x33, 0xac, 0x13, 0x5b, 0xa6, 0xfd, 0x97, +0x16, 0x33, 0xd9, 0x4e, 0xb3, 0x50, 0x0b, 0x17, +0x0e, 0x67, 0x36, 0xcc, 0x09, 0x0c, 0x9c, 0x11, +0x64, 0x95, 0xcc, 0x05, 0x6a, 0xea, 0x3c, 0x2d, +0xc9, 0xbc, 0x79, 0x38, 0xc5, 0x81, 0xc7, 0x73, +0x44, 0x29, 0x7e, 0xbf, 0xb3, 0x67, 0xc2, 0x08, +0x81, 0xe0, 0x8f, 0xf9, 0x30, 0x2a, 0xc0, 0x53, +0x38, 0x07, 0x16, 0x04, 0x87, 0x84, 0x86, 0xd1, +0x52, 0x16, 0x2e, 0xc4, 0x84, 0xe7, 0x45, 0xb5, +0x58, 0x34, 0xad, 0xa6, 0xc5, 0x62, 0x0e, 0x78, +0xfa, 0x8a, 0x50, 0x8b, 0x60, 0xf1, 0x12, 0xc9, +0x52, 0x1a, 0x59, 0xb6, 0x0c, 0x13, 0x47, 0xb4, +0x58, 0x3f, 0xb4, 0x58, 0x37, 0x77, 0x01, 0x38, +0xfb, 0x7b, 0x8c, 0x0f, 0x00, 0xa1, 0x48, 0xb4, +0x3c, 0x18, 0x42, 0x57, 0x48, 0x56, 0xae, 0xb2, +0x4e, 0x58, 0x7c, 0xfe, 0x6a, 0x36, 0xac, 0x59, +0x4b, 0x92, 0xeb, 0xa4, 0x24, 0x35, 0xeb, 0x37, +0x50, 0xa7, 0x74, 0xa3, 0x44, 0x26, 0x0b, 0xa7, +0x91, 0x4d, 0x9b, 0x30, 0x19, 0x46, 0xb5, 0x90, +0x46, 0x44, 0xca, 0xe5, 0x91, 0x0a, 0x39, 0x35, +0x9b, 0xa3, 0xa8, 0x53, 0xb1, 0x65, 0x95, 0x32, +0x3c, 0x9a, 0x46, 0xb6, 0x6e, 0xfd, 0xb2, 0xb1, +0x6d, 0xdb, 0xe5, 0x3b, 0x48, 0x32, 0x4a, 0x41, +0xc6, 0xc8, 0x23, 0xc9, 0xf5, 0x51, 0x72, 0x05, +0x49, 0xee, 0xdc, 0x65, 0x65, 0x63, 0xbb, 0x77, +0xe3, 0x14, 0xea, 0x59, 0xec, 0xd9, 0x21, 0x57, +0xec, 0xdd, 0xb7, 0x3f, 0xf6, 0x00, 0x22, 0x07, +0x0f, 0x61, 0x22, 0x3d, 0xac, 0x52, 0xc5, 0xc5, +0xd3, 0x52, 0x8e, 0x1c, 0xc1, 0x84, 0xba, 0x1e, +0xeb, 0x22, 0xe5, 0x11, 0x47, 0x7d, 0x84, 0x70, +0x0c, 0x91, 0xe3, 0x87, 0xf0, 0x0f, 0x8b, 0x39, +0xa1, 0x3e, 0xa9, 0x49, 0xa0, 0x91, 0x53, 0xa7, +0x30, 0x11, 0x78, 0x9f, 0xf6, 0xff, 0x13, 0xa5, +0xfc, 0x75, 0xe6, 0x6c, 0xec, 0xb9, 0x1a, 0x42, +0xa5, 0xc4, 0x69, 0x34, 0xe7, 0xb5, 0x34, 0x72, +0xe1, 0x42, 0x35, 0x99, 0xbe, 0xd8, 0xe3, 0x62, +0x44, 0x75, 0x97, 0xbd, 0x66, 0xe4, 0xd2, 0xf9, +0xcb, 0x3a, 0x3d, 0x8d, 0x5c, 0xb9, 0x82, 0xc9, +0x7c, 0x0e, 0x27, 0xe0, 0xaa, 0xf4, 0xda, 0x75, +0xb4, 0xb1, 0x98, 0xda, 0x2e, 0x78, 0x63, 0x5a, +0xad, 0x3e, 0x91, 0x46, 0x6e, 0xdc, 0x30, 0xbb, +0x63, 0xb1, 0x37, 0x49, 0xf2, 0xd6, 0x6d, 0x90, +0x92, 0xb7, 0xee, 0xdc, 0xc5, 0x8f, 0xc7, 0xea, +0xc6, 0xee, 0xdd, 0xc3, 0x29, 0xb3, 0x3d, 0x85, +0x81, 0x0b, 0x20, 0x28, 0x24, 0x34, 0x29, 0x0c, +0xfe, 0x56, 0x86, 0x27, 0x47, 0x43, 0x7c, 0x4a, +0x82, 0xf6, 0x3e, 0xfc, 0x93, 0x9a, 0x96, 0x9e, +0x41, 0x4b, 0x79, 0xf0, 0x00, 0x13, 0x74, 0x3d, +0x44, 0xf8, 0x7a, 0x48, 0x32, 0x21, 0xdc, 0x60, +0x50, 0xc7, 0x41, 0x0a, 0x6e, 0x91, 0x9a, 0x95, +0xfd, 0x30, 0x87, 0x46, 0x72, 0x73, 0x31, 0x09, +0x14, 0x2d, 0x17, 0x87, 0x40, 0x92, 0x64, 0xa5, +0x4c, 0x09, 0xc9, 0x6a, 0xb5, 0x26, 0x05, 0xb4, +0x3a, 0xdd, 0xa3, 0x54, 0x48, 0x7f, 0xfc, 0xf0, +0x49, 0x1e, 0x8d, 0x3c, 0x7d, 0x8a, 0xc9, 0x33, +0xb1, 0x58, 0x9c, 0x04, 0x99, 0x32, 0xd9, 0xf3, +0x64, 0x50, 0x9d, 0xd4, 0xa0, 0x67, 0xa1, 0x7f, +0x94, 0x95, 0x95, 0x06, 0xf9, 0x4f, 0x0a, 0x0a, +0x0a, 0x69, 0xe4, 0xc5, 0x0b, 0x4c, 0x82, 0x42, +0x93, 0x70, 0x8b, 0x97, 0xaa, 0xda, 0x16, 0x89, +0xa8, 0xc5, 0x2b, 0x28, 0xca, 0x2b, 0x2c, 0x2c, +0xa2, 0x91, 0xd7, 0xaf, 0xbf, 0xfa, 0x5f, 0x59, +0x4d, 0x20, 0x6c, 0x69, 0xa6, 0xf2, 0x30, 0x44, +0xab, 0xde, 0x14, 0xc7, 0xc3, 0x5b, 0xad, 0xbe, +0x24, 0x11, 0x32, 0xf2, 0x73, 0xf2, 0x8a, 0xa0, +0xa8, 0xb4, 0xb4, 0xac, 0xdc, 0x3c, 0x05, 0xbd, +0xf8, 0xde, 0xbd, 0xa3, 0x5e, 0x7e, 0xb8, 0x85, +0x0a, 0xaa, 0xaf, 0x07, 0xd5, 0x22, 0x1d, 0x72, +0x70, 0x8b, 0x52, 0xa3, 0xb1, 0xc2, 0x64, 0x4e, +0x18, 0xef, 0x3f, 0x54, 0x56, 0x7e, 0x78, 0xcf, +0xb0, 0x01, 0xe5, 0x73, 0x83, 0x41, 0x05, 0xc5, +0x1f, 0xff, 0xc5, 0x8b, 0xcd, 0xca, 0xce, 0x87, +0xbc, 0x82, 0x02, 0x63, 0x29, 0x94, 0x55, 0x54, +0x54, 0x99, 0x2c, 0x53, 0x72, 0x2b, 0x2b, 0x73, +0xa9, 0x94, 0x64, 0x83, 0x5a, 0x5d, 0x0c, 0x09, +0x97, 0x75, 0xba, 0x12, 0x48, 0xcb, 0x7e, 0x8c, +0x16, 0x5b, 0x68, 0x34, 0x1a, 0xcb, 0xc0, 0x54, +0x55, 0x65, 0x49, 0x90, 0xf9, 0xf4, 0x89, 0x7a, +0x29, 0x43, 0x74, 0x5c, 0x71, 0x4a, 0x3c, 0xdc, +0xd7, 0x97, 0xa4, 0x66, 0xc0, 0xab, 0x9a, 0x16, +0x65, 0xa8, 0x45, 0xb9, 0xc9, 0x64, 0x2a, 0xb7, +0xdc, 0x58, 0xcd, 0x6b, 0xfc, 0x6b, 0x36, 0xf6, +0x7d, 0xfe, 0x5f, 0xf3, 0x19, 0xf0, 0x45, 0xf7, +0x38, 0x1a, 0xa2, 0x14, 0xde, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_cte_scan_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_cte_scan_png = new wxImage(); + if (!img_ex_cte_scan_png || !img_ex_cte_scan_png->IsOk()) + { + wxMemoryInputStream img_ex_cte_scan_pngIS(ex_cte_scan_png_data, sizeof(ex_cte_scan_png_data)); + img_ex_cte_scan_png->LoadFile(img_ex_cte_scan_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_cte_scan_png; +} +#define ex_cte_scan_png_img ex_cte_scan_png_img() + +static wxBitmap *ex_cte_scan_png_bmp() +{ + static wxBitmap *bmp_ex_cte_scan_png; + if (!bmp_ex_cte_scan_png || !bmp_ex_cte_scan_png->IsOk()) + bmp_ex_cte_scan_png = new wxBitmap(*ex_cte_scan_png_img); + return bmp_ex_cte_scan_png; +} +#define ex_cte_scan_png_bmp ex_cte_scan_png_bmp() + +static wxIcon *ex_cte_scan_png_ico() +{ + static wxIcon *ico_ex_cte_scan_png; + if (!ico_ex_cte_scan_png || !ico_ex_cte_scan_png->IsOk()) + { + ico_ex_cte_scan_png = new wxIcon(); + ico_ex_cte_scan_png->CopyFromBitmap(*ex_cte_scan_png_bmp); + } + return ico_ex_cte_scan_png; +} +#define ex_cte_scan_png_ico ex_cte_scan_png_ico() + +#endif // EX_CTE_SCAN_PNG_H diff --git a/include/images/ex_delete.png b/include/images/ex_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..ca051cd5d01ee2f3ac17779b362999d82a9285b5 GIT binary patch literal 1129 zcmV-v1eW`WP) zTU+Qs2lh=8Hi*I5b0^MyED5RN(19;b8qFCae zX-dH9$EtPXqi$Wq>SM<0Ysctl$n0**>~+oT+Pi++y?@)iiQK+`+`oW((eK>Bf`rlT z-NS=~)9~KJgxz0>DZ^~*{J8-m+9K6>e;sG+p6o@x9HxP>fNgB+_>rBn(N-I?A^NS->vN4y6oVs z>f@a4-@EMLuI=Ev>g1j5;;-%DyzJw!?d7rWB8{rw(;x4^6ka*?Z)%)$Yy(c-~a#s0d!JMQvg8b*k%9#010qNS#tmY3ljhU3ljkV znw%H_00Om1L_t(Y$L*8bdl^v_#f8bG-PLL%nhMc~q#`mQ2qBD7)FomPgc62MQMdg6 zk3DnFFeXNthkjrCko~Zp{O0Vn_M*|e%s-g7lsHRO4WY~igJFl-+ccRDsDn>t^C@+@ zx4(Z*ogcZ~Uny0@u)e--pf-`3sE>NR-c0Qve4jen-Zs0bzx2v0yz^33L*QXJ96n67 z-|vrMEC|8~Mm*0Cfcyr)IFAhP?`wTY`?t5ZJrIhyTpRdgGF}BjOnw=S3Z#aS8bOKz z2)SI2hh{Q9MZQla-3-V`zlMK|wO1@6q@DYgkiFpjXD)tV7tH|- zs+Ce#@?tf9p@%c(J&3b~b$3yv?^az?FosdP&5vMEuU5Ozn$=YC2mx@aL6sYC-BEW?yl5z?^_b4}Y?mYDns#}ztj z_&TfPMvVl^-a$DU3E!wMhWB5?9atqzKrRj$h&b%_kUD~kp+H#Yp(6@myWO?~!I3Hu z=Fs5?L&$Ek1=NvFHk)oKyp$u6@HJeA0)gu%65GN}d$-s()mK`n1iAvzJBEpt;U*Lc zp;rPv-gQ2XIsOk()) + { + wxMemoryInputStream img_ex_delete_pngIS(ex_delete_png_data, sizeof(ex_delete_png_data)); + img_ex_delete_png->LoadFile(img_ex_delete_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_delete_png; +} +#define ex_delete_png_img ex_delete_png_img() + +static wxBitmap *ex_delete_png_bmp() +{ + static wxBitmap *bmp_ex_delete_png; + if (!bmp_ex_delete_png || !bmp_ex_delete_png->IsOk()) + bmp_ex_delete_png = new wxBitmap(*ex_delete_png_img); + return bmp_ex_delete_png; +} +#define ex_delete_png_bmp ex_delete_png_bmp() + +static wxIcon *ex_delete_png_ico() +{ + static wxIcon *ico_ex_delete_png; + if (!ico_ex_delete_png || !ico_ex_delete_png->IsOk()) + { + ico_ex_delete_png = new wxIcon(); + ico_ex_delete_png->CopyFromBitmap(*ex_delete_png_bmp); + } + return ico_ex_delete_png; +} +#define ex_delete_png_ico ex_delete_png_ico() + +#endif // EX_DELETE_PNG_H diff --git a/include/images/ex_foreign_scan.png b/include/images/ex_foreign_scan.png new file mode 100644 index 0000000000000000000000000000000000000000..acba49c4fbfd9b871444c9e8d528deda3a37dda4 GIT binary patch literal 1607 zcmV-N2Dtf&P)f0Mn*qMOEFGSGEh=NO-@KmPBl_hNli~gPftZq zP)koyMp05tQdB!wTT50~PFY$|TU$Y2VNhILLSSN1U0qaQU`J$UR$*dSVq;iiWJzag zS!88eWoBDuXIy7!VrOYyX=+bxa9?U`N^o*kZE#JkCT>(m6nQ@mx7s{gPNXfp{9hJpNE^8j+&cS zs;iQopNycNF}3BKo|}xLs5H0djijkIxapRrteK{!prxpqr>9E1=S;omo~x`)zUio{ zr$EB&TEON}!tH~&y<5TOt*@+H!sxEBt+2ALpSHV;x!GUE>anx0VaM!Z$nIpx@3ptI zYslzq$?2uN!EMUwZp-VczrLuz#c<8-qr=8>&hDkb=5)~Uea`TO(Cop(zlPE6!o<)Rfrov(wg=+VQm1 z*R|Eys@Lnz(9E{h+0W6=x7XUx($Bcq+rrn@r`_<<)X}Kk@w(gI)78?t+v~gB-@M)6 ztKsy$-r>aD;lb-k<;M3^m)93Ws=jYVu_1oy_Gs^| z>gDI;-RkSs>-XO4?BDF|;O*|=?(gdC>EH17@A2;O^YHZd^Y{7o`uzF)|NH*``~qhH zPXGV_0d!JMQvg8b*k%9#010qNS#tmY3ljhU3ljkVnw%H_00Rd}L_t(Y$L*BaPZLoT z#&O?J6r$p;DDH~8qEXZl6<5H-4YlIFiyMf_bypH`m%5;WOI&KDg)~)+G`53GhY*HR zXIO`XSSW}nIe&q()Y=)^2NGj^;5?jpxxf3}@60*J%c~{+bzH>w@R;2p*zMT3xMb{Z zLc-Zc*we(s>u<2P_wJ{>$3CPzfB6Y>i^N7oM#f_&*G5HM!V>o#Jahv~jz4ue1xrgx zy80UXODemCH+#&Ivr2_R$$d~A%d&Msu0^%ZY)5vhm9`@ZqNuM|@Ca+MSXji8B^q*kaWa{$1FuE zD+QHW7Zp3hFq{fa(>7$IC`zv4K-gX3n^yE+e0X(qc;6{gFYFB*dhmc~snJeFC!=lMeDkdU=N{IJJe}E%PA|S&z2tGpaJjepSTV%ORrKm{s(gPqG(E|aN zFL(j7Ms)lN(4jj(+4NMM+)H7hfG`69)+1V|*n^;zF}_D3!@o}!?BAx-5i+EpKt$%W zY8!y)9qn3oYCmD)HQh3weuKBJ8s-z0nwjYVsp0;$1+iRqHYY*g4A-1E!MH`5)nobj zP8AzsDazUW<=niK2qPd@$;%TEel93P>GgUNk$OE>B~r(`AT*kET!xs<4#a4n_`^J+ z({TuqDIn?To)C+{U?63PMnfRnGs04&TNhRw$E`9XH@Ddp6A_n1QI1N4`x)VWPDQ#d zxW$*9%`ZO}7lgzGu2!pzNHWGbT5S$D%6|~Cuo|34)HpJ!R8mB#Fl)7DQH8G(DHc}a zxL<8TMmfSUT*D|GUgR$LrDri3jk49}SmVv9SWEn0@e4;h=nHVhTAcs@002ovPDHLk FV1m**ONRge literal 0 HcmV?d00001 diff --git a/include/images/ex_foreign_scan.pngc b/include/images/ex_foreign_scan.pngc new file mode 100644 index 0000000..44c1005 --- /dev/null +++ b/include/images/ex_foreign_scan.pngc @@ -0,0 +1,245 @@ +#ifndef EX_FOREIGN_SCAN_PNG_H +#define EX_FOREIGN_SCAN_PNG_H + +static const unsigned char ex_foreign_scan_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x02, 0xd9, 0x50, 0x4c, 0x54, +0x45, 0x34, 0x51, 0x54, 0x2f, 0x33, 0x35, 0x32, +0x3d, 0x3d, 0x2b, 0x40, 0x44, 0x34, 0x3e, 0x3f, +0x35, 0x3f, 0x40, 0x2e, 0x43, 0x47, 0x3f, 0x43, +0x45, 0x3a, 0x45, 0x45, 0x3b, 0x46, 0x46, 0x3f, +0x4a, 0x4b, 0x31, 0x4e, 0x51, 0x32, 0x50, 0x52, +0x42, 0x4d, 0x4e, 0x48, 0x4c, 0x4e, 0x35, 0x52, +0x55, 0x49, 0x4d, 0x4f, 0x44, 0x4f, 0x4f, 0x45, +0x50, 0x50, 0x4b, 0x4f, 0x51, 0x46, 0x51, 0x52, +0x4d, 0x52, 0x54, 0x3b, 0x58, 0x5b, 0x4b, 0x56, +0x57, 0x4e, 0x59, 0x5a, 0x50, 0x5b, 0x5b, 0x41, +0x5f, 0x61, 0x50, 0x5c, 0x5c, 0x42, 0x60, 0x62, +0x51, 0x5d, 0x5d, 0x54, 0x60, 0x60, 0x47, 0x64, +0x67, 0x56, 0x61, 0x62, 0x57, 0x62, 0x63, 0x58, +0x63, 0x64, 0x49, 0x67, 0x6a, 0x59, 0x64, 0x65, +0x5a, 0x65, 0x66, 0x5b, 0x66, 0x67, 0x5c, 0x67, +0x68, 0x62, 0x67, 0x69, 0x5e, 0x69, 0x6a, 0x4f, +0x6d, 0x70, 0x5f, 0x6a, 0x6b, 0x4a, 0x70, 0x72, +0x56, 0x6d, 0x71, 0x66, 0x6b, 0x6d, 0x67, 0x6b, +0x6e, 0x61, 0x6d, 0x6e, 0x53, 0x71, 0x74, 0x62, +0x6e, 0x6f, 0x4e, 0x74, 0x76, 0x63, 0x6f, 0x70, +0x64, 0x70, 0x71, 0x65, 0x71, 0x72, 0x60, 0x73, +0x72, 0x66, 0x72, 0x73, 0x6d, 0x71, 0x74, 0x53, +0x79, 0x7b, 0x6e, 0x72, 0x75, 0x68, 0x74, 0x75, +0x6f, 0x73, 0x76, 0x69, 0x75, 0x75, 0x6b, 0x77, +0x77, 0x74, 0x78, 0x7b, 0x77, 0x79, 0x76, 0x6f, +0x7b, 0x7b, 0x2c, 0x88, 0xc1, 0x60, 0x7f, 0x82, +0x76, 0x7b, 0x7e, 0x58, 0x83, 0x8a, 0x7d, 0x7f, +0x7c, 0x75, 0x81, 0x81, 0x77, 0x83, 0x83, 0x5e, +0x8a, 0x90, 0x78, 0x84, 0x84, 0x7a, 0x86, 0x86, +0x7b, 0x87, 0x87, 0x7c, 0x88, 0x88, 0x78, 0x8b, +0x8a, 0x7e, 0x8a, 0x8a, 0x84, 0x89, 0x8c, 0x00, +0xa8, 0xe3, 0x77, 0x8e, 0x92, 0x00, 0xa9, 0xe5, +0x80, 0x8c, 0x8d, 0x82, 0x8e, 0x8f, 0x88, 0x8d, +0x90, 0x00, 0xae, 0xe3, 0x89, 0x8e, 0x91, 0x84, +0x90, 0x91, 0x00, 0xb0, 0xe5, 0x85, 0x91, 0x92, +0x7d, 0x94, 0x98, 0x87, 0x93, 0x94, 0x6d, 0x96, +0xcf, 0x8f, 0x93, 0x96, 0x89, 0x95, 0x96, 0x8a, +0x96, 0x97, 0x82, 0x99, 0x9d, 0x83, 0x9a, 0x9e, +0x6c, 0xa1, 0xa6, 0x84, 0x9b, 0x9f, 0x87, 0x9b, +0x9a, 0x8e, 0x9a, 0x9b, 0x57, 0xaa, 0xab, 0x92, +0x9e, 0x9f, 0x8c, 0xa0, 0x9f, 0x31, 0xb5, 0xe5, +0x9c, 0x9e, 0x9b, 0x8c, 0xa3, 0xa8, 0x34, 0xb7, +0xe7, 0x8d, 0xa4, 0xa9, 0x36, 0xb8, 0xe9, 0x96, +0xa6, 0xac, 0x99, 0xa6, 0xa6, 0xa0, 0xa5, 0xa8, +0x9a, 0xa7, 0xa7, 0x4a, 0xbc, 0xe7, 0x4c, 0xbd, +0xe8, 0x9e, 0xab, 0xac, 0x4d, 0xbe, 0xe9, 0xa8, +0xaa, 0xa7, 0x40, 0xc2, 0xec, 0x5a, 0xc0, 0xe6, +0x51, 0xc2, 0xed, 0x83, 0xb8, 0xbd, 0x5b, 0xc1, +0xe7, 0xad, 0xaf, 0xac, 0x5c, 0xc2, 0xe8, 0xae, +0xb0, 0xad, 0xb0, 0xb2, 0xae, 0x9f, 0xb6, 0xbb, +0x8b, 0xb9, 0xd9, 0x5f, 0xc5, 0xea, 0xb1, 0xb3, +0xaf, 0x61, 0xc7, 0xec, 0x62, 0xc8, 0xee, 0x64, +0xc9, 0xef, 0xb5, 0xb7, 0xb4, 0x6b, 0xc8, 0xe8, +0x6c, 0xc9, 0xe9, 0xa5, 0xbd, 0xc1, 0x6d, 0xca, +0xea, 0x6e, 0xcb, 0xeb, 0xaa, 0xbf, 0xbe, 0xa8, +0xc0, 0xc5, 0x70, 0xcd, 0xed, 0xa3, 0xc3, 0xc6, +0x72, 0xce, 0xee, 0xa5, 0xc1, 0xe6, 0x74, 0xd0, +0xf1, 0x7d, 0xce, 0xf0, 0x85, 0xd0, 0xec, 0xc1, +0xc3, 0xbf, 0x86, 0xd1, 0xed, 0xc2, 0xc4, 0xc1, +0x87, 0xd2, 0xee, 0xc0, 0xc5, 0xc8, 0xac, 0xcc, +0xcf, 0x8a, 0xd4, 0xf0, 0xc5, 0xc7, 0xc4, 0x8b, +0xd5, 0xf1, 0xc6, 0xc8, 0xc5, 0x90, 0xd5, 0xec, +0xae, 0xcf, 0xd2, 0xc7, 0xc9, 0xc6, 0x91, 0xd6, +0xed, 0xc5, 0xca, 0xcd, 0x92, 0xd7, 0xee, 0xb0, +0xd1, 0xd4, 0x94, 0xd8, 0xef, 0xb3, 0xd3, 0xd6, +0x96, 0xda, 0xf1, 0xb4, 0xd4, 0xd7, 0xb5, 0xd5, +0xd8, 0xaa, 0xd7, 0xeb, 0xce, 0xd0, 0xcc, 0xb6, +0xd6, 0xd9, 0xcf, 0xd1, 0xce, 0xb7, 0xd7, 0xda, +0xd0, 0xd2, 0xcf, 0xb8, 0xd8, 0xdb, 0xc2, 0xd7, +0xd6, 0xa7, 0xdd, 0xf0, 0xd2, 0xd4, 0xd1, 0xa8, +0xde, 0xf1, 0xba, 0xdb, 0xde, 0xd3, 0xd5, 0xd2, +0xba, 0xdb, 0xeb, 0xbb, 0xdc, 0xdf, 0xbc, 0xdd, +0xe0, 0xab, 0xe1, 0xf4, 0xbd, 0xde, 0xe1, 0xc4, +0xdc, 0xe1, 0xc5, 0xdd, 0xe2, 0xbe, 0xde, 0xee, +0xd8, 0xda, 0xd6, 0xbf, 0xdf, 0xef, 0xc6, 0xdf, +0xe3, 0xc0, 0xe0, 0xf1, 0xc7, 0xe0, 0xe4, 0xc1, +0xe1, 0xf2, 0xc8, 0xe1, 0xe6, 0xc6, 0xe2, 0xed, +0xc9, 0xe2, 0xe7, 0xc7, 0xe3, 0xee, 0xca, 0xe3, +0xe8, 0xc8, 0xe4, 0xef, 0xcf, 0xe4, 0xe3, 0xc9, +0xe5, 0xf0, 0xcd, 0xe5, 0xea, 0xdf, 0xe1, 0xde, +0xd0, 0xe5, 0xe4, 0xd1, 0xe6, 0xe5, 0xd1, 0xe5, +0xf1, 0xd2, 0xe7, 0xe6, 0xd2, 0xe6, 0xf2, 0xe1, +0xe4, 0xe0, 0xd3, 0xe8, 0xe7, 0xd3, 0xe7, 0xf4, +0xda, 0xe7, 0xe7, 0xd4, 0xe8, 0xf5, 0xdb, 0xe8, +0xe9, 0xe4, 0xe6, 0xe3, 0xd5, 0xe9, 0xf6, 0xdc, +0xe9, 0xea, 0xe5, 0xe7, 0xe4, 0xdd, 0xea, 0xeb, +0xd6, 0xeb, 0xf7, 0xde, 0xeb, 0xec, 0xdf, 0xec, +0xed, 0xe0, 0xed, 0xee, 0xe1, 0xee, 0xef, 0xea, +0xec, 0xe9, 0xdf, 0xf0, 0xf6, 0xef, 0xf1, 0xee, +0xf1, 0xf3, 0xf0, 0xf4, 0xf7, 0xf3, 0xf7, 0xf9, +0xf6, 0xfa, 0xfc, 0xf9, 0xfc, 0xff, 0xfb, 0xfe, +0xff, 0xfc, 0x02, 0x67, 0x00, 0x4f, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, +0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, +0x00, 0x00, 0x03, 0x07, 0x49, 0x44, 0x41, 0x54, +0x48, 0xc7, 0xed, 0x94, 0xd9, 0x4f, 0x13, 0x51, +0x14, 0xc6, 0x71, 0xdf, 0x50, 0x14, 0xa2, 0xe2, +0xae, 0x28, 0xee, 0x8a, 0xbb, 0xa2, 0x51, 0xd4, +0x11, 0x15, 0x57, 0xc0, 0xc4, 0x0d, 0xb5, 0xe2, +0xbe, 0x8b, 0x1b, 0x88, 0xca, 0x75, 0x57, 0x12, +0x71, 0x97, 0xba, 0xa0, 0x82, 0x4b, 0x5c, 0x6a, +0xa5, 0x85, 0x34, 0x55, 0x8c, 0x34, 0xb6, 0x83, +0x4c, 0x87, 0x10, 0x86, 0x52, 0x67, 0x58, 0x87, +0x84, 0x58, 0x28, 0x88, 0x28, 0x39, 0x7f, 0x81, +0xb3, 0xd4, 0xda, 0x19, 0xda, 0x07, 0x12, 0x63, +0x7c, 0xe0, 0x3c, 0x9c, 0x79, 0xb9, 0xbf, 0xfb, +0xdd, 0xef, 0xcc, 0x39, 0xc7, 0xcb, 0xab, 0x25, +0xfe, 0x75, 0x5c, 0xc4, 0xf8, 0xf0, 0x98, 0xdd, +0x21, 0xd8, 0xed, 0xd8, 0xb8, 0xb8, 0x64, 0xec, +0x6e, 0x42, 0xc2, 0xd9, 0x47, 0xd8, 0xd3, 0xc4, +0xc4, 0xeb, 0x6f, 0xb0, 0xb7, 0xf7, 0xee, 0xa7, +0xbc, 0xc7, 0x3e, 0xa4, 0x3d, 0x7f, 0xf9, 0x09, +0x73, 0x8b, 0xc4, 0x46, 0x46, 0x46, 0xc6, 0x63, +0x27, 0xd7, 0x46, 0x45, 0x5d, 0xc2, 0x12, 0xf7, +0x1d, 0x3c, 0x74, 0x03, 0x4b, 0x8e, 0x3f, 0x75, +0x3a, 0x05, 0x4b, 0x4b, 0x4a, 0xba, 0xfa, 0x1a, +0xfb, 0x4b, 0x2a, 0xbb, 0x85, 0x37, 0x7b, 0xcc, +0x92, 0xb3, 0x4a, 0x85, 0x42, 0xc9, 0x7d, 0x50, +0x1d, 0xcb, 0xb2, 0x75, 0x42, 0xae, 0x45, 0xb5, +0xce, 0x6c, 0x47, 0x76, 0xab, 0x95, 0xb6, 0x23, +0x09, 0xa2, 0xa8, 0xaf, 0x57, 0xf0, 0x08, 0x6b, +0xb1, 0x58, 0x58, 0xc4, 0x92, 0x24, 0xe9, 0x9a, +0x19, 0x64, 0x25, 0x08, 0x13, 0x2d, 0x43, 0xaa, +0xab, 0x3d, 0x23, 0x84, 0x15, 0xd1, 0x26, 0x53, +0x13, 0xa4, 0xaa, 0xea, 0x37, 0x42, 0x4a, 0x11, +0x86, 0x20, 0x08, 0x5a, 0x40, 0x2c, 0xee, 0x11, +0x99, 0x8b, 0x12, 0xde, 0x05, 0x4d, 0xd7, 0x20, +0x1b, 0x4d, 0x73, 0xea, 0xee, 0x90, 0x74, 0xc4, +0x87, 0xc7, 0x2c, 0x45, 0x2a, 0x2b, 0x05, 0x95, +0x5a, 0x17, 0x15, 0x3b, 0xc3, 0x30, 0x9c, 0x0a, +0x4d, 0xd3, 0x36, 0x64, 0xa3, 0x28, 0x4a, 0xae, +0xe2, 0x40, 0xd8, 0x5d, 0xe1, 0x9b, 0x56, 0xf4, +0x5f, 0x7c, 0x78, 0x75, 0x74, 0x78, 0xdf, 0x29, +0x53, 0x2f, 0xec, 0x0d, 0x1c, 0x7a, 0xf3, 0x40, +0xe0, 0xa4, 0xe3, 0xdb, 0x8f, 0xed, 0x8c, 0x51, +0x93, 0x32, 0xa4, 0xa2, 0x42, 0x44, 0x7a, 0x03, +0x17, 0x8f, 0x43, 0xb8, 0xd4, 0xf0, 0x24, 0x74, +0xe9, 0x16, 0x38, 0x31, 0x6d, 0x38, 0xc0, 0x98, +0xd1, 0x97, 0x61, 0x7c, 0xaa, 0x27, 0xa4, 0x1b, +0xc0, 0x86, 0x41, 0xf3, 0x47, 0x01, 0xcc, 0x1d, +0xf7, 0x0c, 0xd6, 0xcc, 0x68, 0x2c, 0x0b, 0x09, +0x05, 0x88, 0xe8, 0xf5, 0xa5, 0xb1, 0xab, 0x4a, +0x8e, 0x94, 0x96, 0x8a, 0x5e, 0xfc, 0x00, 0xf6, +0x8c, 0x0d, 0x0b, 0x00, 0x08, 0x5f, 0xb8, 0x19, +0x3e, 0xcf, 0x79, 0x05, 0x3d, 0xcf, 0x37, 0xfc, +0x38, 0xd7, 0x19, 0x1e, 0x0e, 0x79, 0x27, 0xf7, +0x52, 0x5c, 0x2c, 0x56, 0xac, 0x0d, 0xff, 0xb0, +0x8c, 0x2e, 0x00, 0x33, 0xef, 0x4c, 0x84, 0x9f, +0xde, 0xeb, 0x20, 0xf8, 0xdb, 0x99, 0x2b, 0xdf, +0x67, 0xc3, 0xa2, 0xc9, 0x4d, 0x2a, 0x26, 0x22, +0x82, 0x4a, 0x88, 0xf7, 0x48, 0x7f, 0x80, 0x23, +0x4b, 0x22, 0x20, 0xc3, 0x37, 0x08, 0x3e, 0x42, +0xf0, 0x3c, 0xc8, 0x02, 0xbf, 0x5b, 0x64, 0xb9, +0x4c, 0xa5, 0xa8, 0x48, 0xf4, 0xd2, 0x03, 0x20, +0x1a, 0xd1, 0x03, 0x01, 0x96, 0x2f, 0x78, 0x01, +0xb3, 0x46, 0x74, 0xfc, 0x0a, 0xd0, 0xa1, 0x3b, +0x40, 0xd9, 0xf4, 0x54, 0x9d, 0xdc, 0x4b, 0x61, +0xa1, 0x80, 0x30, 0x03, 0x00, 0xd6, 0x23, 0x5a, +0xa8, 0xd8, 0x83, 0xa0, 0x95, 0x31, 0xbe, 0x47, +0x21, 0xc3, 0xbf, 0x4f, 0x16, 0xec, 0xdf, 0xa6, +0xd3, 0x11, 0x32, 0xa4, 0xa0, 0x40, 0x44, 0xe6, +0xb4, 0x6a, 0x1b, 0x80, 0xe8, 0x1d, 0xed, 0x5a, +0x77, 0x6a, 0x3f, 0x61, 0xe3, 0x35, 0xdd, 0x32, +0x9f, 0x7e, 0x83, 0xb7, 0xae, 0x1a, 0xe6, 0x13, +0x96, 0x9a, 0x99, 0xe9, 0x01, 0xa9, 0xe1, 0xfe, +0xb5, 0x05, 0xb1, 0x5c, 0x76, 0x36, 0x27, 0x41, +0xe0, 0x0c, 0xd7, 0x9c, 0x38, 0xc1, 0xb8, 0x45, +0x9a, 0xd5, 0x63, 0xf9, 0xf9, 0x4e, 0x15, 0x1b, +0x62, 0x29, 0xca, 0xd9, 0xfc, 0xe5, 0xdc, 0xbc, +0x94, 0x08, 0x23, 0x20, 0x57, 0xc9, 0xcb, 0x13, +0x10, 0x7e, 0x2e, 0x28, 0x44, 0xe9, 0xf5, 0x7a, +0x12, 0x91, 0x7a, 0x3d, 0x57, 0x25, 0x52, 0xc7, +0xbb, 0x20, 0x34, 0x9a, 0x74, 0x5c, 0x86, 0x98, +0xcd, 0x0e, 0xc4, 0x68, 0xa0, 0xf8, 0xc3, 0x3c, +0xa2, 0xd3, 0x71, 0x08, 0x91, 0x29, 0x20, 0xe9, +0xe9, 0x9e, 0x10, 0x8b, 0xc1, 0x60, 0x20, 0x65, +0x88, 0x46, 0x43, 0x20, 0xdc, 0x33, 0xc2, 0x52, +0xa4, 0x5b, 0x17, 0x56, 0x1c, 0xc7, 0xad, 0x32, +0x24, 0x37, 0xb7, 0xd9, 0x15, 0x13, 0x11, 0x97, +0x45, 0x51, 0x8e, 0x4a, 0x84, 0xfb, 0x19, 0xe1, +0x7e, 0x4e, 0x45, 0xba, 0x2e, 0xb8, 0xc5, 0x97, +0x9d, 0xcd, 0x2f, 0x3f, 0x17, 0x17, 0x84, 0xc4, +0x05, 0xae, 0x56, 0xab, 0x8c, 0x48, 0x32, 0xc6, +0x39, 0x5a, 0x6d, 0x0e, 0x37, 0xca, 0x7f, 0x10, +0xb1, 0xb0, 0x1a, 0x9c, 0x47, 0xd4, 0x38, 0x32, +0xa9, 0x54, 0x52, 0x44, 0xa9, 0x30, 0x6b, 0xb5, +0x66, 0x51, 0x85, 0xaf, 0x12, 0x29, 0x16, 0x56, +0xe3, 0xb8, 0x5f, 0x6d, 0x42, 0x46, 0x39, 0xc2, +0x31, 0x5c, 0xc3, 0x28, 0x1d, 0x5e, 0xe4, 0x2e, +0xf8, 0xa5, 0x67, 0x31, 0x1a, 0x8d, 0xb2, 0xd5, +0xe7, 0x58, 0xe3, 0xcd, 0xa9, 0x58, 0x4b, 0xfc, +0x5f, 0xf1, 0x0b, 0x47, 0x3c, 0xe8, 0x0b, 0x70, +0xc6, 0x5a, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_foreign_scan_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_foreign_scan_png = new wxImage(); + if (!img_ex_foreign_scan_png || !img_ex_foreign_scan_png->IsOk()) + { + wxMemoryInputStream img_ex_foreign_scan_pngIS(ex_foreign_scan_png_data, sizeof(ex_foreign_scan_png_data)); + img_ex_foreign_scan_png->LoadFile(img_ex_foreign_scan_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_foreign_scan_png; +} +#define ex_foreign_scan_png_img ex_foreign_scan_png_img() + +static wxBitmap *ex_foreign_scan_png_bmp() +{ + static wxBitmap *bmp_ex_foreign_scan_png; + if (!bmp_ex_foreign_scan_png || !bmp_ex_foreign_scan_png->IsOk()) + bmp_ex_foreign_scan_png = new wxBitmap(*ex_foreign_scan_png_img); + return bmp_ex_foreign_scan_png; +} +#define ex_foreign_scan_png_bmp ex_foreign_scan_png_bmp() + +static wxIcon *ex_foreign_scan_png_ico() +{ + static wxIcon *ico_ex_foreign_scan_png; + if (!ico_ex_foreign_scan_png || !ico_ex_foreign_scan_png->IsOk()) + { + ico_ex_foreign_scan_png = new wxIcon(); + ico_ex_foreign_scan_png->CopyFromBitmap(*ex_foreign_scan_png_bmp); + } + return ico_ex_foreign_scan_png; +} +#define ex_foreign_scan_png_ico ex_foreign_scan_png_ico() + +#endif // EX_FOREIGN_SCAN_PNG_H diff --git a/include/images/ex_gatcher.png b/include/images/ex_gatcher.png new file mode 100644 index 0000000000000000000000000000000000000000..1d7d7018a1083683a088bb58095fea51ffcd7807 GIT binary patch literal 1056 zcmV+*1mF9KP)d*_(JfBK~W?^1Qdh@L?aIo!mFi~08*X` z1zHN1M{j9?5SQcqrc86OrH>nGYrT_vIbqtI^Zm};nOkyl%rL`@|0hbzoOJPWq>SX# zdLEJ^qubQgtx`{~pXGFJ^Oq+kcgXGtXbRHM&=$?j?Q$L~K7*!bcFE)U#rZ@)Qg$8^ z*tG7wLJgKxR$u=nf6-RVZk)=Sl8VZVZk`^SXW&yX?5-eOZB#7 zAc*&M1jyRLE0%zu3II@kma){O4~Gv@YtJ(Vq5+5m1jYqoZN8iVkVgeV5YK64<{7E( zrldh)`ZNj>uNMHI?**)=g6eK&h~Qd(`a#k)wc>)*4PQvUBHGQP5;BRTB7F1OW5m)b zAUBWIx7ftma5Yk3r8nt{#Pn$tB-{&HA7C2o?}bnw=z9SG-tm%<#-7mnY(ok_#x5BH z*@MuJQ&d49mZwS?0C`ja03t&mv3wc@k#Q;`RmLfr833$_rwpJ6@r*oTr3Az>m7g?7 z!o9HE6MDaBE6lTg)YIltchVp+eHsBt*VKyXGq3Czmn^sZDD^oyDUqMfa`W;|!0iW> z&=kTnLM7z(<>s-j&D672r{9r(@oPjy4m?lu1%L1fzfnQ1RGy-Wp|fM#uxe?I@;2dl5^Se7g@sAmltf1bo3Ce8O*3kcXCh zD(*T>m1F1VM$1Vi$3`M-+!egL4@Sl*0A!p-fM^g90FXx&0I*;yWGNH1VGx19IRYYr zANYbl_=Ml6AU*bW(!*F5u2P4ufHxEfk=#^x3hhDY$0>to0Pb)1SpYyD6<`Q!AX>?Fz@QQ$(rjfpykmwNxcwL2EyZX4?;gqQ3U|7`ff9T9t04O zcepAuKxCZCNR@Gl3J3&@3kWJ85E%s$s~4mX^u2%;=0(wZ60{ literal 0 HcmV?d00001 diff --git a/include/images/ex_gatcher.pngc b/include/images/ex_gatcher.pngc new file mode 100644 index 0000000..4cf4bd9 --- /dev/null +++ b/include/images/ex_gatcher.pngc @@ -0,0 +1,176 @@ +#ifndef EX_GATCHER_PNG_H +#define EX_GATCHER_PNG_H + +static const unsigned char ex_gatcher_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x06, 0x00, 0x00, 0x00, 0x1e, 0x3f, 0x88, +0xb1, 0x00, 0x00, 0x03, 0xe7, 0x49, 0x44, 0x41, +0x54, 0x78, 0xda, 0xed, 0x97, 0xcb, 0x4f, 0x53, +0x51, 0x10, 0xc6, 0xf9, 0x37, 0xfc, 0x03, 0x5c, +0xbb, 0x73, 0x69, 0xdc, 0xb8, 0x74, 0xe3, 0x5e, +0x12, 0xe2, 0x6b, 0x21, 0x0b, 0x5d, 0x98, 0x18, +0x37, 0xf8, 0x42, 0xf0, 0x89, 0x41, 0x51, 0x24, +0x42, 0x04, 0x14, 0x84, 0x06, 0x44, 0x23, 0x0f, +0x11, 0xc2, 0xab, 0xa5, 0x95, 0x00, 0x52, 0x9e, +0x0a, 0x05, 0x5a, 0x0a, 0x97, 0x47, 0x6f, 0x69, +0x81, 0x10, 0x97, 0xe3, 0xfd, 0xa6, 0x4c, 0x73, +0xb1, 0xa5, 0x8f, 0x1b, 0x6a, 0x6b, 0xbd, 0x93, +0x7c, 0x39, 0x61, 0xda, 0x9c, 0xf3, 0xfd, 0xce, +0xdc, 0x99, 0x5b, 0x72, 0x72, 0xcc, 0x30, 0xc3, +0x8c, 0xff, 0x27, 0x4a, 0xcb, 0x9c, 0x74, 0xf1, +0x72, 0xa4, 0x8c, 0xe4, 0xd3, 0x7a, 0x1e, 0x92, +0x23, 0xa3, 0xdb, 0xd4, 0xd5, 0xad, 0x52, 0x4f, +0xaf, 0x9f, 0xe5, 0x74, 0x6e, 0xf3, 0x97, 0x27, +0x26, 0x77, 0xc8, 0xee, 0x08, 0x68, 0x0a, 0xd2, +0xd0, 0xd0, 0x16, 0xcd, 0xcd, 0xed, 0x72, 0x1e, +0x2b, 0x3e, 0x83, 0xa6, 0x67, 0x76, 0xc9, 0xe3, +0xf9, 0xc5, 0xf9, 0x44, 0x40, 0x52, 0x76, 0x1e, +0x12, 0xd8, 0xb4, 0xee, 0xbd, 0x42, 0x0d, 0x96, +0x55, 0x56, 0x5f, 0xff, 0x26, 0x7f, 0xd1, 0x66, +0x0b, 0x50, 0x6b, 0x9b, 0x8f, 0xf5, 0xa5, 0x53, +0x65, 0x03, 0xc8, 0xe3, 0xe0, 0x01, 0x6b, 0x80, +0x6c, 0x83, 0x41, 0x3e, 0x14, 0x9b, 0x27, 0x03, +0x92, 0x92, 0xf3, 0x4c, 0x90, 0x4c, 0x04, 0xc9, +0x8a, 0x1e, 0xc9, 0x9a, 0xa9, 0x95, 0x75, 0x71, +0xaf, 0xe1, 0x3c, 0x9d, 0x79, 0x7c, 0x84, 0xb0, +0xfe, 0xd3, 0x3e, 0xf1, 0x61, 0xb5, 0x35, 0x97, +0xbf, 0x94, 0xc9, 0x20, 0x71, 0x7d, 0x1a, 0x01, +0xb1, 0x37, 0x5e, 0xa3, 0xbe, 0x92, 0xe3, 0x11, +0x32, 0x92, 0x4f, 0x2b, 0x08, 0x4c, 0xec, 0x04, +0x1d, 0x14, 0x54, 0xdb, 0xc2, 0xc2, 0xdf, 0x92, +0x0f, 0xac, 0x7f, 0x0e, 0x6b, 0xc7, 0x3f, 0x18, +0xca, 0x6b, 0xeb, 0xa6, 0xf2, 0x89, 0xe5, 0x5f, +0xf9, 0x48, 0x5b, 0x3e, 0x2b, 0xe7, 0xd3, 0x0e, +0x02, 0xf3, 0x1b, 0xcb, 0x95, 0x61, 0xc1, 0x34, +0xf2, 0x58, 0xd7, 0xdd, 0x15, 0x61, 0xc1, 0x38, +0xf2, 0x58, 0x57, 0x5d, 0x2f, 0x69, 0x75, 0xee, +0x05, 0x4b, 0xf5, 0xb6, 0x64, 0x20, 0x88, 0xf7, +0x75, 0x04, 0xc8, 0xda, 0xc2, 0x2b, 0x96, 0x80, +0xa0, 0x0a, 0x00, 0x50, 0x7e, 0x96, 0xb1, 0xd4, +0xa5, 0x0f, 0x87, 0x0f, 0x52, 0x6b, 0xcf, 0x33, +0x06, 0xa2, 0x01, 0x88, 0x04, 0x04, 0xc6, 0x05, +0x62, 0x6d, 0xbe, 0x9c, 0x01, 0x90, 0x47, 0x05, +0x42, 0x10, 0xcf, 0x69, 0x65, 0xe6, 0x19, 0xa9, +0xee, 0xa6, 0xa4, 0x41, 0x62, 0xfa, 0x34, 0x0a, +0x12, 0xaf, 0x17, 0x00, 0xa0, 0xef, 0x05, 0xac, +0xa8, 0x82, 0xea, 0x6e, 0x66, 0x88, 0xe0, 0x5a, +0x7f, 0xfa, 0x41, 0xd2, 0x35, 0xb5, 0xe2, 0x82, +0xd4, 0x0d, 0x5f, 0x48, 0xbe, 0x22, 0xda, 0xcd, +0xa3, 0x12, 0x32, 0x89, 0xa4, 0x22, 0x7c, 0xf3, +0xda, 0x63, 0xc4, 0xd2, 0x2a, 0x20, 0x37, 0x8f, +0xd5, 0xb7, 0xd8, 0xc4, 0xda, 0x70, 0x35, 0x52, +0x60, 0xa5, 0x37, 0xe9, 0x8a, 0xc4, 0xf4, 0x69, +0x14, 0x24, 0xdc, 0x0b, 0x5a, 0x1f, 0x60, 0x1a, +0xed, 0xef, 0x85, 0x50, 0x1f, 0xe8, 0x7b, 0x01, +0x00, 0xde, 0xf1, 0x92, 0x90, 0xc6, 0x9e, 0xd0, +0xfa, 0x6c, 0x43, 0x0a, 0x40, 0xc6, 0x2e, 0x19, +0x03, 0xd9, 0x83, 0xd0, 0x8f, 0x53, 0x54, 0x41, +0x20, 0x96, 0xa7, 0x4a, 0x19, 0x00, 0x79, 0x54, +0x01, 0x00, 0x22, 0x43, 0x20, 0xb1, 0x7c, 0x1a, +0x05, 0x91, 0x71, 0x2a, 0x23, 0x55, 0xc6, 0x29, +0x9a, 0x19, 0x00, 0xac, 0x89, 0xa7, 0x0c, 0xa0, +0x07, 0xf1, 0x8c, 0x3c, 0x62, 0xa5, 0x04, 0xc4, +0x32, 0x95, 0x9f, 0x34, 0x48, 0xc2, 0xbd, 0xb0, +0xdc, 0x13, 0x7a, 0xbf, 0x68, 0x2b, 0xcc, 0xb3, +0x7e, 0xd4, 0xd3, 0xe6, 0x52, 0x77, 0xd2, 0x20, +0x31, 0x7d, 0x1a, 0x01, 0x49, 0xd7, 0xd4, 0x8a, +0xe9, 0x33, 0xaf, 0xec, 0x18, 0x97, 0x2c, 0xb7, +0xfc, 0x28, 0xf5, 0x39, 0x3a, 0x29, 0x91, 0x9f, +0xce, 0x72, 0xf3, 0xf2, 0x4e, 0xc0, 0xed, 0x07, +0x95, 0xd0, 0x14, 0xc2, 0x34, 0x42, 0x25, 0xe4, +0xf6, 0xe5, 0xe6, 0xb1, 0xae, 0xcd, 0xd4, 0xb3, +0x56, 0xa7, 0xdf, 0x91, 0x7f, 0xf1, 0x6b, 0x44, +0x45, 0x0e, 0x3c, 0x4f, 0xf3, 0x05, 0x7f, 0xf0, +0x09, 0xbf, 0x51, 0x41, 0xae, 0x54, 0x9e, 0xa2, +0x8a, 0xa1, 0xb3, 0x74, 0xbd, 0xf9, 0x04, 0x55, +0xb5, 0x16, 0xed, 0x83, 0xc1, 0xa6, 0x9d, 0xfe, +0x5b, 0x11, 0x9b, 0x87, 0x7a, 0xa1, 0x29, 0x6a, +0x2f, 0xc0, 0xbc, 0xf4, 0x81, 0x67, 0xf8, 0x01, +0x3f, 0x46, 0xc8, 0x03, 0xc0, 0xed, 0x28, 0xa6, +0x45, 0x7b, 0x11, 0x4b, 0x99, 0x7c, 0xbb, 0x0f, +0x44, 0x20, 0xe4, 0x3c, 0x3d, 0x04, 0x7c, 0xc1, +0x1f, 0x7c, 0xc2, 0x6f, 0x54, 0x90, 0x87, 0x96, +0x7c, 0x2a, 0xee, 0x3a, 0x4d, 0x95, 0x63, 0xe7, +0xe8, 0x46, 0xcb, 0x49, 0x26, 0xc7, 0x46, 0x22, +0x6c, 0xdc, 0x15, 0xbc, 0xbb, 0x0f, 0x46, 0xc6, +0x29, 0x00, 0x64, 0x9c, 0x46, 0x80, 0x68, 0x10, +0x10, 0x00, 0x90, 0x47, 0x15, 0x00, 0xb0, 0x60, +0x2b, 0x64, 0x29, 0x13, 0xb5, 0x61, 0x10, 0x81, +0xc0, 0x39, 0x02, 0x22, 0x82, 0x1f, 0xf8, 0x82, +0x3f, 0xf8, 0x84, 0xdf, 0xa8, 0x20, 0x3d, 0xf6, +0x76, 0xd2, 0xc3, 0x58, 0x16, 0xae, 0x52, 0x87, +0xaf, 0x80, 0x37, 0x14, 0x08, 0x91, 0xdc, 0x54, +0x78, 0x0a, 0xed, 0x41, 0xe8, 0xc7, 0x29, 0x83, +0x68, 0x00, 0xee, 0x6f, 0xf7, 0x59, 0x00, 0x40, +0x1e, 0x15, 0x60, 0x08, 0x6b, 0x21, 0xcd, 0x0f, +0xdc, 0x21, 0xc5, 0x59, 0x13, 0x06, 0x11, 0x08, +0x91, 0x9c, 0x0d, 0x1f, 0xf0, 0xa3, 0x87, 0x80, +0xdf, 0x03, 0x1b, 0x49, 0x60, 0x50, 0x36, 0x3c, +0x83, 0xfa, 0x1b, 0xd1, 0x43, 0xe8, 0x2b, 0x12, +0xaf, 0x17, 0x00, 0xa0, 0xef, 0x05, 0x75, 0xbe, +0x93, 0xab, 0xa0, 0x8c, 0xd7, 0x30, 0x84, 0xea, +0xea, 0x88, 0x5a, 0x11, 0x39, 0x4b, 0x04, 0x3f, +0xf0, 0x15, 0x17, 0x22, 0xde, 0xa4, 0xf8, 0x13, +0x22, 0x55, 0x53, 0x4b, 0x0f, 0x73, 0xe8, 0xff, +0x76, 0xc7, 0x9a, 0x5a, 0xb8, 0x79, 0x79, 0x27, +0xa0, 0x02, 0x52, 0x11, 0x54, 0x00, 0x8f, 0x11, +0x4b, 0xab, 0x00, 0x2a, 0xc1, 0x15, 0xd1, 0x2a, +0xa0, 0x38, 0xab, 0x69, 0xe5, 0x7b, 0x48, 0xbe, +0xd9, 0xf6, 0x84, 0xa7, 0x56, 0xca, 0x82, 0x7b, +0x41, 0x03, 0x90, 0x3e, 0xc0, 0x34, 0x8a, 0xd7, +0x0b, 0x30, 0xef, 0xea, 0xb9, 0xc9, 0x9a, 0xeb, +0x2e, 0xa0, 0xe5, 0xd1, 0x37, 0x49, 0xbd, 0x10, +0x53, 0x06, 0xc2, 0xe3, 0x74, 0x0f, 0x42, 0x3f, +0x4e, 0x51, 0x05, 0x00, 0xb0, 0xfa, 0x6e, 0x33, +0x80, 0x1e, 0x04, 0x10, 0x90, 0x77, 0xb8, 0x2a, +0x33, 0x40, 0x64, 0x9c, 0xca, 0x48, 0x95, 0x71, +0x8a, 0x0a, 0x08, 0x04, 0x8c, 0x0b, 0x08, 0x2a, +0x20, 0x10, 0x19, 0x05, 0x12, 0xab, 0x17, 0xa4, +0x0f, 0xf4, 0xbd, 0x80, 0x15, 0xe6, 0x45, 0xd1, +0x7a, 0xe4, 0xaf, 0x47, 0x3a, 0x7e, 0x6b, 0x99, +0x61, 0x86, 0x19, 0x66, 0x98, 0x61, 0x86, 0x19, +0xd9, 0x1e, 0xbf, 0x01, 0x5b, 0x58, 0xee, 0x4f, +0xa7, 0x3d, 0xf0, 0xa2, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_gatcher_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_gatcher_png = new wxImage(); + if (!img_ex_gatcher_png || !img_ex_gatcher_png->IsOk()) + { + wxMemoryInputStream img_ex_gatcher_pngIS(ex_gatcher_png_data, sizeof(ex_gatcher_png_data)); + img_ex_gatcher_png->LoadFile(img_ex_gatcher_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_gatcher_png; +} +#define ex_gatcher_png_img ex_gatcher_png_img() + +static wxBitmap *ex_gatcher_png_bmp() +{ + static wxBitmap *bmp_ex_gatcher_png; + if (!bmp_ex_gatcher_png || !bmp_ex_gatcher_png->IsOk()) + bmp_ex_gatcher_png = new wxBitmap(*ex_gatcher_png_img); + return bmp_ex_gatcher_png; +} +#define ex_gatcher_png_bmp ex_gatcher_png_bmp() + +static wxIcon *ex_gatcher_png_ico() +{ + static wxIcon *ico_ex_gatcher_png; + if (!ico_ex_gatcher_png || !ico_ex_gatcher_png->IsOk()) + { + ico_ex_gatcher_png = new wxIcon(); + ico_ex_gatcher_png->CopyFromBitmap(*ex_gatcher_png_bmp); + } + return ico_ex_gatcher_png; +} +#define ex_gatcher_png_ico ex_gatcher_png_ico() + +#endif // EX_GATCHER_PNG_H diff --git a/include/images/ex_gather.png b/include/images/ex_gather.png new file mode 100644 index 0000000000000000000000000000000000000000..381d00d41274a5ed331efd901f2b8b1d235b5f0f GIT binary patch literal 9757 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYV2a>i1B%QlYbpRzEa{HEjtmSN`?>!lvI6;> z1s;*b3=DjSK$uZf!>a)(C|TkfQ4*Y=R#Ki=l*$m0n3-3i=jR%tP-d)Ws%K$t-4M&b zpgPOb#WAEJ?(KC$UIqr9!y7)T-`#lPso;u~w7+;P3~g8Kizxel&bW)5mE3fEOvF<-=(CI9h*zE7#HbakPCf z+CCa>AC0z;M%zcD?IUQfakPCn+CCg@AC9&UfrC$@?c>q*@o4*aw0%6IsOk()) + { + wxMemoryInputStream img_ex_gather_pngIS(ex_gather_png_data, sizeof(ex_gather_png_data)); + img_ex_gather_png->LoadFile(img_ex_gather_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_gather_png; +} +#define ex_gather_png_img ex_gather_png_img() + +static wxBitmap *ex_gather_png_bmp() +{ + static wxBitmap *bmp_ex_gather_png; + if (!bmp_ex_gather_png || !bmp_ex_gather_png->IsOk()) + bmp_ex_gather_png = new wxBitmap(*ex_gather_png_img); + return bmp_ex_gather_png; +} +#define ex_gather_png_bmp ex_gather_png_bmp() + +static wxIcon *ex_gather_png_ico() +{ + static wxIcon *ico_ex_gather_png; + if (!ico_ex_gather_png || !ico_ex_gather_png->IsOk()) + { + ico_ex_gather_png = new wxIcon(); + ico_ex_gather_png->CopyFromBitmap(*ex_gather_png_bmp); + } + return ico_ex_gather_png; +} +#define ex_gather_png_ico ex_gather_png_ico() + +#endif // EX_GATHER_PNG_H diff --git a/include/images/ex_gather_motion.png b/include/images/ex_gather_motion.png new file mode 100644 index 0000000000000000000000000000000000000000..06b72826862098966412a9ed9320ed4514fe3e5a GIT binary patch literal 218 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*@xBpA$Gw#oo0rjj7PUIsOk()) + { + wxMemoryInputStream img_ex_gather_motion_pngIS(ex_gather_motion_png_data, sizeof(ex_gather_motion_png_data)); + img_ex_gather_motion_png->LoadFile(img_ex_gather_motion_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_gather_motion_png; +} +#define ex_gather_motion_png_img ex_gather_motion_png_img() + +static wxBitmap *ex_gather_motion_png_bmp() +{ + static wxBitmap *bmp_ex_gather_motion_png; + if (!bmp_ex_gather_motion_png || !bmp_ex_gather_motion_png->IsOk()) + bmp_ex_gather_motion_png = new wxBitmap(*ex_gather_motion_png_img); + return bmp_ex_gather_motion_png; +} +#define ex_gather_motion_png_bmp ex_gather_motion_png_bmp() + +static wxIcon *ex_gather_motion_png_ico() +{ + static wxIcon *ico_ex_gather_motion_png; + if (!ico_ex_gather_motion_png || !ico_ex_gather_motion_png->IsOk()) + { + ico_ex_gather_motion_png = new wxIcon(); + ico_ex_gather_motion_png->CopyFromBitmap(*ex_gather_motion_png_bmp); + } + return ico_ex_gather_motion_png; +} +#define ex_gather_motion_png_ico ex_gather_motion_png_ico() + +#endif // EX_GATHER_MOTION_PNG_H diff --git a/include/images/ex_group.png b/include/images/ex_group.png new file mode 100644 index 0000000000000000000000000000000000000000..8d5de31bc129a9abcf4a73e19a48739139f66271 GIT binary patch literal 1228 zcmV;-1T*`IP)9z9h#qH&> z?c}iR?B?BK2I-mL1~tMBB$bEG!w=AY@{n&{q`?&h=R*_GtekmAse>DsC4 zDi~^&Wz~SrlQAS@94Ab;k>5IWyh*@@aDkh)THLqqwL+ecBwj^wTIx! ziQdJ9-ou35!Gh+|q2I`d<zxTpNrZFE={Y_9;C#4z;o;8n<_!#Ueg5^if#~TvJ0ZwowOV^nZ(o1^02;Vy zu?(WYUYl(Q4Gr7vw@^pKIx;e1MSTv3<2Jf8Iy!1WJp{L*;juA`9sTu|@d=i7GIzB* zcbx`ea%zfYVA|z!O*g08?e>7jJHz>4miG$*&>@5fk}cqxo11erraKf0N5CtJA`kxg zXjIZ8>{QT6K3YgD<|aru>;+DY$NeBgqlu&uVVO20Mv+K3EONldUfRE$& zSy&MSDF7*1R><$?^J*E&rLBr_%XS^%;`MqgXclXlMUhx+RjbvC5!ul?)~H8Yuxhbb zEkWfnGVy48hc@|gu%#mXatCCbFywBqAxIKQNmeuqm0E03i*lu6bQyolvg{M)DW<3E zG`wPq%cPn3+4J4qJzU%0fAJC@93H(o#>acL+6g{6I5>Tc4doBgcOSnwJ9~SM-(6h1 z|A0S!`uyc9{&xO-zlMMOJUluzB3ffiAkFe$9ch*S>MpJF|I(7_Iy;r$L}JbIn@VhR z$7Es@G5cI-#kS2oefq~wwp=~2>+`>z-(ue+J2o$;LI3~&C3HntbYx+4WjbSWWnpw> z05UK!FfB1MEif@uGB7$cGdeUhD=;-WFfcfoB_03(03~!qSaf7zbY(hiZ)9m^c>ppn qF)%GKIV~_TR5CLIsOk()) + { + wxMemoryInputStream img_ex_group_pngIS(ex_group_png_data, sizeof(ex_group_png_data)); + img_ex_group_png->LoadFile(img_ex_group_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_group_png; +} +#define ex_group_png_img ex_group_png_img() + +static wxBitmap *ex_group_png_bmp() +{ + static wxBitmap *bmp_ex_group_png; + if (!bmp_ex_group_png || !bmp_ex_group_png->IsOk()) + bmp_ex_group_png = new wxBitmap(*ex_group_png_img); + return bmp_ex_group_png; +} +#define ex_group_png_bmp ex_group_png_bmp() + +static wxIcon *ex_group_png_ico() +{ + static wxIcon *ico_ex_group_png; + if (!ico_ex_group_png || !ico_ex_group_png->IsOk()) + { + ico_ex_group_png = new wxIcon(); + ico_ex_group_png->CopyFromBitmap(*ex_group_png_bmp); + } + return ico_ex_group_png; +} +#define ex_group_png_ico ex_group_png_ico() + +#endif // EX_GROUP_PNG_H diff --git a/include/images/ex_hash.png b/include/images/ex_hash.png new file mode 100644 index 0000000000000000000000000000000000000000..9f35c76538c3a41920a7b93b94bdf97443df7aa7 GIT binary patch literal 1169 zcmV;C1aA9@P)el?&hp;g_M^vPyuIzKtmw0}>eSTprp#qVzv+I_?y1pfi`DRv*YI-8?0nAc zpxg0|)b5kj@2}wVOTX!?)@^0T>qEQdP`>AE$LX%xagvqMa+aa8;C8`}HuUky@a(s= z%{EiufNlm?Sban zmF(iLDs94;H~fF!0zF_pG#z^7Z=B>b%2f~b#^4RQ$FKkW936b z-9bUQ>wu4ZIPc`Y=+~#`)}`#;yM|jA(>_1o$cW#@hUV0yu-$XX5E0BgJmJiW-o%9F z(xSc&4#hh=;K_*H!-U#3ciXMG^ue5lb*` zBLBL(BnC@M_{lzaKFl*S`~03W=gh1~bf??Z7>o&i8z-E`2MDn+LnITE(kU`Ph=my< zli!=3;UOHsGB!NW(76$6NJ2r~EN>D;qxHI?ZTyx!j(ABM$Jw28;N7n`m*n{ee-CEij_l=W|)m#q9t^g?o`5n$u2q89~HPuuHQD{TVq$evdr}9gW5IqV% zY=p)*2{p#QmtU5UXB!g~#e{J`Q!Sk0S*=#954-)4+s{4^DqlQEV)eLGs$i|rXr2#4 zu8J*k#g!thd|kzAU`IGSb`9 zXpM~`UY7p|xp@{|V|TiBT>>)4pzcQhBc}iW03~!qSaf7zbY(hYa%Ew3WdJfTF)%GL zGA%GMR5CC+G&4FhG%GMQIxsLenI#?o001R)MObuXVRU6WZEs|0W_bWIFflMKFgYzS jF;p@$Iy5voFg7bNH99ab%9mBF00000NkvXXu0mjfr*~9W literal 0 HcmV?d00001 diff --git a/include/images/ex_hash.pngc b/include/images/ex_hash.pngc new file mode 100644 index 0000000..8f3584c --- /dev/null +++ b/include/images/ex_hash.pngc @@ -0,0 +1,191 @@ +#ifndef EX_HASH_PNG_H +#define EX_HASH_PNG_H + +static const unsigned char ex_hash_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x86, 0xa9, 0x64, 0x52, +0x8d, 0x19, 0x75, 0xa6, 0xc7, 0x36, 0x88, 0xc1, +0xa1, 0xc4, 0x5e, 0x6f, 0xcd, 0xee, 0x4f, 0xc1, +0xe9, 0x62, 0xc6, 0xea, 0x77, 0xce, 0xed, 0xa6, +0xde, 0xf2, 0x41, 0xbd, 0xe9, 0x09, 0xa9, 0xe2, +0x2c, 0xb3, 0xe4, 0x49, 0xbc, 0xe6, 0x89, 0xd3, +0xee, 0x6c, 0x84, 0xcd, 0x66, 0x6b, 0xd1, 0xcc, +0xcd, 0xf1, 0xc0, 0xc1, 0xee, 0xc6, 0xc7, 0xef, +0xcd, 0xce, 0xf2, 0xde, 0xde, 0xf6, 0xa3, 0xc7, +0x61, 0xbc, 0xbd, 0xed, 0xab, 0xac, 0xe8, 0xb3, +0xb4, 0xea, 0xd4, 0xd4, 0xf3, 0xa6, 0xcc, 0x65, +0x46, 0xbf, 0xe9, 0x7e, 0xd1, 0xee, 0xa9, 0xd1, +0x69, 0x8b, 0xd5, 0xf0, 0x91, 0xd7, 0xf0, 0x72, +0xcc, 0xec, 0x7c, 0xce, 0xed, 0xa0, 0xdb, 0xf1, +0x8e, 0xd4, 0xee, 0x93, 0xd5, 0xef, 0xaf, 0xe0, +0xf3, 0x4b, 0xbf, 0xe9, 0xac, 0xd6, 0x6d, 0x65, +0xc8, 0xeb, 0x43, 0xbb, 0xe6, 0x50, 0xbe, 0xe7, +0x6c, 0xc7, 0xe9, 0xae, 0xda, 0x71, 0x92, 0x95, +0xd1, 0x72, 0x96, 0xa1, 0xb2, 0xe0, 0x76, 0xc1, +0x8f, 0x36, 0xf4, 0xf1, 0xc9, 0xf0, 0xec, 0xb7, +0xb4, 0xe4, 0x79, 0xf3, 0xee, 0xc7, 0xef, 0xe8, +0xb3, 0xee, 0xe6, 0xb2, 0xf1, 0xeb, 0xc4, 0xec, +0xe3, 0xb0, 0xec, 0xe1, 0xae, 0xec, 0xe0, 0xad, +0xf0, 0xe7, 0xc1, 0xeb, 0xe6, 0x9e, 0xb7, 0xe8, +0x7d, 0xef, 0xe9, 0xb5, 0xe8, 0xdd, 0x98, 0xe5, +0xd5, 0x92, 0xe4, 0xd3, 0x90, 0xea, 0xdd, 0xac, +0xba, 0xed, 0x81, 0xe6, 0xda, 0x95, 0xec, 0xe2, +0xaf, 0xe3, 0xd1, 0x8e, 0xe9, 0xdc, 0xaa, 0xbc, +0xf0, 0x84, 0xe2, 0xcf, 0x8d, 0xe9, 0xda, 0xa8, +0xeb, 0xe0, 0xad, 0xef, 0xe5, 0xc0, 0xee, 0xe1, +0xbd, 0x9f, 0x4b, 0x64, 0xa9, 0x17, 0x17, 0xc7, +0xaa, 0x75, 0x80, 0x8e, 0x25, 0x75, 0x76, 0x24, +0xb5, 0x53, 0x3e, 0xe3, 0x63, 0x63, 0xe5, 0x43, +0x43, 0xdd, 0x41, 0x41, 0xb9, 0xeb, 0x80, 0x8f, +0x7c, 0x38, 0xef, 0xe4, 0xbf, 0xe8, 0xd7, 0xa7, +0xe7, 0xd6, 0xa5, 0xec, 0xde, 0xbb, 0x86, 0x5b, +0x17, 0xd3, 0x3e, 0x3f, 0xe0, 0xc8, 0x88, 0xdf, +0xc6, 0x86, 0xe6, 0xd4, 0xa4, 0xb0, 0xdd, 0x73, +0xc9, 0x10, 0x11, 0xcc, 0x3c, 0x3c, 0xe1, 0xcc, +0x8a, 0xde, 0xc4, 0x84, 0xe6, 0xd2, 0xa2, 0xbe, +0x0e, 0x0e, 0xc5, 0x3b, 0x3b, 0xe0, 0xc9, 0x88, +0xdd, 0xc3, 0x84, 0xdd, 0xc1, 0x82, 0xe6, 0xd1, +0xa1, 0xcc, 0x5d, 0x5d, 0xe8, 0xd6, 0xa6, 0xec, +0xdd, 0xb9, 0xe6, 0xd1, 0xa2, 0xe5, 0xd0, 0xa1, +0xeb, 0xdb, 0xb7, 0xf0, 0xe8, 0xc2, 0xe6, 0xd3, +0xa4, 0xe4, 0xce, 0xa0, 0xea, 0xd9, 0xb6, 0xdb, +0xbd, 0x7f, 0xda, 0xba, 0x7d, 0xe3, 0xcc, 0x9e, +0xdc, 0xbf, 0x81, 0xe4, 0xcd, 0x9e, 0xe3, 0xcb, +0x9e, 0xde, 0x8c, 0x45, 0xb8, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0x48, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xed, 0x93, 0xeb, 0x5b, 0x12, 0x41, 0x18, +0xc5, 0xf1, 0x75, 0x40, 0x11, 0x52, 0xe9, 0x86, +0x15, 0x4a, 0x37, 0x2d, 0x2a, 0x6f, 0x2f, 0x17, +0x81, 0xb8, 0xdf, 0x04, 0x59, 0xc4, 0x25, 0x03, +0x89, 0x45, 0x12, 0x02, 0x24, 0x11, 0x4b, 0x30, +0x6e, 0x22, 0xff, 0xba, 0xbb, 0x24, 0x06, 0x4b, +0x4b, 0xf8, 0xc9, 0x3e, 0x78, 0x3e, 0xcc, 0x33, +0x33, 0xfb, 0xfc, 0x9e, 0x33, 0xe7, 0xcc, 0xac, +0x48, 0x74, 0xa7, 0xdb, 0xd5, 0x18, 0x8c, 0x09, +0x7e, 0x1b, 0x27, 0x9c, 0xc6, 0x07, 0x08, 0xb1, +0x30, 0x43, 0x24, 0x13, 0x93, 0xd2, 0x29, 0x32, +0x40, 0x88, 0x85, 0x19, 0x22, 0x93, 0xdf, 0x9b, +0x9e, 0xe1, 0x21, 0x1c, 0xc1, 0x32, 0x37, 0x73, +0x61, 0x0f, 0x26, 0xe8, 0x32, 0xab, 0xe0, 0x34, +0xcb, 0xdf, 0x06, 0x41, 0x0f, 0x91, 0x48, 0x71, +0xff, 0xc1, 0xc3, 0x47, 0x8f, 0x15, 0x03, 0x88, +0x72, 0x08, 0x32, 0xf7, 0xe4, 0xe9, 0xdc, 0xb3, +0x6b, 0xe4, 0xaa, 0x40, 0x02, 0x2a, 0x20, 0xdd, +0x39, 0xbf, 0x52, 0x1e, 0x42, 0x24, 0xb2, 0xf9, +0x79, 0x29, 0x59, 0x00, 0x35, 0x3c, 0x27, 0x2f, +0x5e, 0x4a, 0x5f, 0xbd, 0x26, 0x53, 0x8b, 0x8b, +0x4b, 0x6f, 0xc8, 0x10, 0x44, 0x26, 0x97, 0xcb, +0xdf, 0x92, 0x09, 0xd0, 0xc0, 0x3b, 0x22, 0x79, +0x3f, 0xfd, 0x61, 0x81, 0xcc, 0x4c, 0x2e, 0x2f, +0x2f, 0xf5, 0x21, 0xfd, 0x59, 0x58, 0x17, 0x59, +0xc7, 0x65, 0x45, 0xd8, 0x65, 0xb5, 0xd3, 0xd8, +0x6a, 0x77, 0xb9, 0xd6, 0x39, 0xf9, 0x1a, 0x81, +0x75, 0x20, 0xdd, 0x79, 0x67, 0x14, 0x76, 0x41, +0xad, 0x4e, 0xa7, 0xd3, 0xa2, 0x16, 0xf4, 0x60, +0x40, 0xc3, 0x86, 0xd1, 0x68, 0x42, 0x93, 0xf9, +0xa3, 0xc5, 0x8a, 0xc2, 0x59, 0x50, 0x67, 0xb3, +0xd9, 0x74, 0xa8, 0x03, 0x3b, 0x38, 0xd0, 0xe8, +0x74, 0x3a, 0xcd, 0x68, 0x76, 0xb9, 0xdc, 0x9e, +0x7f, 0x23, 0x0e, 0xf0, 0xc2, 0x06, 0x8b, 0xf8, +0x7c, 0x9b, 0x68, 0x71, 0xbb, 0xfd, 0x81, 0x51, +0x90, 0x2d, 0x30, 0xa2, 0xd9, 0xe7, 0x73, 0x59, +0xd0, 0xe3, 0xf7, 0x07, 0x29, 0x1c, 0x9e, 0xc5, +0xc1, 0xa6, 0x60, 0x11, 0x36, 0xc5, 0xa6, 0x25, +0x64, 0xc5, 0xed, 0x00, 0x45, 0x85, 0x7b, 0x91, +0x1d, 0x9a, 0xd3, 0x4e, 0x77, 0x19, 0x41, 0xc4, +0x4f, 0xb0, 0x4b, 0xb3, 0x08, 0xfd, 0x19, 0x39, +0x45, 0x7e, 0x8f, 0x3d, 0x08, 0x1d, 0x8d, 0xc5, +0xf6, 0xa2, 0xf4, 0xb5, 0x8b, 0xc1, 0xe1, 0x80, +0x38, 0x7c, 0x61, 0x91, 0x28, 0x6d, 0xf5, 0x78, +0x02, 0x09, 0x0c, 0x33, 0x4c, 0x72, 0xbf, 0xd7, +0x85, 0x8e, 0xa5, 0x80, 0xaf, 0xb8, 0x17, 0x76, +0x21, 0xf5, 0x95, 0xf6, 0xf8, 0x83, 0x6c, 0x0a, +0xe6, 0x20, 0x9d, 0xce, 0xf4, 0x23, 0x20, 0x56, +0x2a, 0x95, 0x2a, 0x95, 0x5a, 0xad, 0xd1, 0xac, +0x7c, 0x5b, 0xd7, 0xeb, 0xed, 0xf6, 0xb8, 0x77, +0x0b, 0xb2, 0xd9, 0x1c, 0x1d, 0x08, 0xe6, 0xf3, +0x0c, 0x26, 0xd3, 0x87, 0x87, 0x85, 0x3e, 0x64, +0xef, 0xaf, 0x2e, 0xa9, 0xec, 0xf7, 0x23, 0x9a, +0xca, 0xe7, 0x8b, 0x49, 0xcc, 0x1c, 0x1e, 0x97, +0x4e, 0xfa, 0x90, 0x68, 0x2e, 0x77, 0xf4, 0xe3, +0x4f, 0x16, 0x93, 0xd9, 0xcc, 0x65, 0xe9, 0x6c, +0x86, 0x99, 0x9f, 0x6c, 0x8a, 0xd3, 0xf2, 0x49, +0xe5, 0x6c, 0x84, 0xc6, 0x38, 0x09, 0x35, 0xc6, +0xbf, 0x97, 0x5f, 0x96, 0x90, 0x67, 0x1b, 0x13, +0x14, 0xc5, 0x84, 0x71, 0x3f, 0x53, 0x2d, 0x9c, +0xe2, 0x59, 0xad, 0x56, 0xab, 0x0f, 0xbb, 0xfd, +0x90, 0xdb, 0xcf, 0x3e, 0x0f, 0x2a, 0x5f, 0x3c, +0x48, 0x62, 0xf5, 0xb8, 0x54, 0xaa, 0x60, 0xad, +0xd1, 0x68, 0x9e, 0x0f, 0x43, 0xae, 0x8a, 0x2d, +0x72, 0xc5, 0x96, 0x4b, 0xad, 0x56, 0x0d, 0x2f, +0x1a, 0xcd, 0x66, 0x7b, 0x18, 0xd2, 0x5b, 0x6c, +0xa5, 0xd5, 0x6a, 0xd4, 0xf0, 0xbc, 0xc9, 0x47, +0x78, 0x59, 0x12, 0x14, 0xc3, 0xa5, 0xa8, 0x16, +0xca, 0x9d, 0x14, 0x17, 0x75, 0xac, 0xb7, 0xdb, +0xed, 0xbe, 0x2c, 0xbc, 0xbf, 0x32, 0xd2, 0xdb, +0xd2, 0x68, 0x8d, 0x8d, 0x22, 0x5e, 0x96, 0xff, +0x08, 0xb9, 0x79, 0x16, 0x5e, 0x63, 0x77, 0xba, +0x75, 0x5d, 0x02, 0x32, 0xc7, 0xa0, 0xee, 0x46, +0xff, 0x23, 0xa7, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_hash_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_hash_png = new wxImage(); + if (!img_ex_hash_png || !img_ex_hash_png->IsOk()) + { + wxMemoryInputStream img_ex_hash_pngIS(ex_hash_png_data, sizeof(ex_hash_png_data)); + img_ex_hash_png->LoadFile(img_ex_hash_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_hash_png; +} +#define ex_hash_png_img ex_hash_png_img() + +static wxBitmap *ex_hash_png_bmp() +{ + static wxBitmap *bmp_ex_hash_png; + if (!bmp_ex_hash_png || !bmp_ex_hash_png->IsOk()) + bmp_ex_hash_png = new wxBitmap(*ex_hash_png_img); + return bmp_ex_hash_png; +} +#define ex_hash_png_bmp ex_hash_png_bmp() + +static wxIcon *ex_hash_png_ico() +{ + static wxIcon *ico_ex_hash_png; + if (!ico_ex_hash_png || !ico_ex_hash_png->IsOk()) + { + ico_ex_hash_png = new wxIcon(); + ico_ex_hash_png->CopyFromBitmap(*ex_hash_png_bmp); + } + return ico_ex_hash_png; +} +#define ex_hash_png_ico ex_hash_png_ico() + +#endif // EX_HASH_PNG_H diff --git a/include/images/ex_hash_anti_join.png b/include/images/ex_hash_anti_join.png new file mode 100644 index 0000000000000000000000000000000000000000..a2a4e9369fa78c6fa19bf5c7814f8a586aed5565 GIT binary patch literal 1571 zcmV+;2Hg3HP)el?&hp;g_M^vPyuIwJtmw0}>b$+})YS8(%Vb!b%R{~CN5APyzv+9??}XFv zsL*Ja+3}#;@rKgwjMVOs)$Xp~^8}~i38~@_s^U<>>RiR^tJQ3E&Fq2D?Owy^WyR=g z$LN&S@2=W$rKse3o~g3nc4CU7!H+id@yYP)xAgGH^YF;E<$Ck&#`5gN?dGxV*k;9<(}{Bw(se+xaofG=CkePvFF;B=Gm3z*p%$yuJG)(>g1j3f@a0;+*d1v%K(xBI2n!RpnIz8rM-G;Z!G=R8sZm;ipqDj2iYBa-eL+3+8i(D9Kc^QRT7SldI;mwQT%ZlL2iL*-)v`iG?LPDa(U!=)mr_E-n z(rT^OZ?N5Sv*LKR=X|^GgU%8X#}E+AJUr>yr{Kwm-^ho)XD{18K!jQr#Saj^4i3gU zJLuP@-^YgD#f8m}Tijt`&pkcLJUqoaJIq~O@aV$q;H~T6t&4j%?cclR)THLqq~_A2 z<;tVAk8q1xa-mN-ut*Z8oXPO!!0Ozp?&H4g;k@V8rRUY8?B2TU-MQw`qUF({<^D z9AXwQt|i#zmMlzGOe_$#HAax4*I#(9iE+I;|$c2Ym*n9lwVL-R9sSAR9c46QeFW9FwZL(qPkY27ro~H^ zRxF#ge8tM*dXOFzTUM>cX3Od|Yu8n*U$J51rXrA6Q2nxb%hqk%5q{aRa~IGryTO8c z_U_w%fankd0dR=f96WUR$l*gr@x;rqq~l#DY)-B}b^46W*>mSFTqK;vj$gWb<*LoK z>o;!hx4Cuu&fR;26AUO|*W29R_~79!n+uN~KY2=63n*ak+dO;z;^hUKdyk*IdW}U3 znqN*{d$Skli(7BsU9@@s;lt~Xn0`Uam6hO7LMA_7)~85T1fYc1xA33 zf&m5qP2%gmFInOH0000bbVXQnWMOn=I%9HWVRU5xGB7bPEip1JFfmjzFgi3dIy5vZ zFf}?bFgTed9smFUC3HntbYx+4WjbwdWNBu305UK!FfA}SEif@uGBY|fG&(RgD=;-W VFfhuORjdF2002ovPDHLkV1kgxQ(pi8 literal 0 HcmV?d00001 diff --git a/include/images/ex_hash_anti_join.pngc b/include/images/ex_hash_anti_join.pngc new file mode 100644 index 0000000..78a70c5 --- /dev/null +++ b/include/images/ex_hash_anti_join.pngc @@ -0,0 +1,241 @@ +#ifndef EX_HASH_ANTI_JOIN_PNG_H +#define EX_HASH_ANTI_JOIN_PNG_H + +static const unsigned char ex_hash_anti_join_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x02, 0xd9, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x99, 0xbc, 0x78, 0x52, +0x8d, 0x19, 0x89, 0xb9, 0xdb, 0x36, 0x88, 0xc1, +0xa1, 0xc4, 0x5e, 0x6f, 0xcd, 0xee, 0x4d, 0xc0, +0xe9, 0x61, 0xc6, 0xeb, 0x76, 0xcd, 0xec, 0xa6, +0xde, 0xf2, 0x40, 0xbc, 0xe9, 0x12, 0xab, 0xe2, +0x2c, 0xb3, 0xe4, 0x48, 0xbc, 0xe6, 0x89, 0xd3, +0xee, 0x74, 0x8b, 0xd5, 0x66, 0x6b, 0xd1, 0xcc, +0xcd, 0xf1, 0xc0, 0xc1, 0xee, 0xc6, 0xc7, 0xef, +0xcd, 0xce, 0xf2, 0xde, 0xde, 0xf6, 0xa3, 0xc7, +0x61, 0xbc, 0xbd, 0xec, 0xab, 0xac, 0xe8, 0xb3, +0xb4, 0xea, 0xbc, 0xbd, 0xed, 0xd4, 0xd4, 0xf3, +0xa5, 0xcb, 0x64, 0x58, 0x9c, 0xcb, 0x43, 0xbd, +0xe9, 0x47, 0xbf, 0xe9, 0x4b, 0xbf, 0xe9, 0x7b, +0xd1, 0xef, 0x84, 0xd3, 0xf0, 0xa8, 0xd0, 0x68, +0x97, 0xd9, 0xf1, 0xa0, 0xdb, 0xf1, 0x86, 0xd2, +0xee, 0x8c, 0xd4, 0xee, 0x90, 0xd5, 0xee, 0xae, +0xe0, 0xf3, 0x04, 0xa7, 0xe1, 0x09, 0xa9, 0xe2, +0x0f, 0xaa, 0xe2, 0x50, 0xc2, 0xea, 0x5c, 0xc5, +0xeb, 0xab, 0xd5, 0x6c, 0x75, 0xcd, 0xec, 0x81, +0xd0, 0xed, 0x5e, 0xc3, 0xe8, 0x65, 0xc5, 0xe8, +0x6b, 0xc7, 0xe8, 0x94, 0xd6, 0xef, 0xae, 0xda, +0x71, 0xa5, 0xa8, 0xe4, 0x7a, 0x9e, 0xa9, 0xb2, +0xe0, 0x76, 0x62, 0x8a, 0xa3, 0xc1, 0x8f, 0x36, +0xf4, 0xf1, 0xc9, 0xf0, 0xec, 0xb7, 0xf4, 0xf0, +0xc8, 0xf3, 0xf0, 0xc8, 0xb5, 0xe5, 0x7a, 0xf3, +0xed, 0xc6, 0xf2, 0xec, 0xc5, 0xed, 0xe6, 0xb1, +0xed, 0xe4, 0xb0, 0xec, 0xe3, 0xb0, 0xf1, 0xea, +0xc3, 0xeb, 0xe6, 0x9f, 0xeb, 0xe5, 0x9e, 0xef, +0xeb, 0xb6, 0xef, 0xe9, 0xb5, 0xb8, 0xe9, 0x7e, +0xee, 0xe6, 0xb3, 0xed, 0xe5, 0xb1, 0xe7, 0xda, +0x96, 0xe6, 0xd9, 0x95, 0xe6, 0xd8, 0x94, 0xec, +0xe1, 0xae, 0xf0, 0xec, 0xb6, 0xea, 0xe4, 0x9d, +0xea, 0xe3, 0x9d, 0xef, 0xea, 0xb5, 0xef, 0xe9, +0xb4, 0xba, 0xed, 0x81, 0xe5, 0xd7, 0x93, 0xe5, +0xd6, 0x92, 0xeb, 0xdf, 0xad, 0xea, 0xe3, 0x9c, +0xe9, 0xe2, 0x9c, 0xee, 0xe7, 0xb3, 0xbc, 0xf0, +0x84, 0xe4, 0xd5, 0x91, 0xe4, 0xd3, 0x90, 0xea, +0xdd, 0xab, 0xbf, 0x86, 0x31, 0xb7, 0x84, 0x80, +0xb0, 0x5e, 0x3e, 0xb2, 0x4a, 0x13, 0xb4, 0x61, +0x3f, 0xc4, 0x90, 0x84, 0x70, 0x66, 0xb8, 0xf3, +0xef, 0xc7, 0xef, 0xe8, 0xb3, 0xf2, 0xed, 0xc5, +0xf1, 0xe9, 0xc3, 0xf0, 0xe7, 0xc1, 0xea, 0xdd, +0xaa, 0xe7, 0xd0, 0xa9, 0xb7, 0x60, 0x1b, 0xc9, +0x4d, 0x1a, 0xd7, 0x51, 0x22, 0xe1, 0x54, 0x27, +0x97, 0x54, 0x52, 0xf5, 0xe8, 0xe1, 0xa7, 0x53, +0x6c, 0xa9, 0x17, 0x17, 0xdb, 0xbd, 0x89, 0x80, +0x8e, 0x25, 0x7f, 0x78, 0x2c, 0xbd, 0x5b, 0x46, +0xba, 0x6c, 0x22, 0xe2, 0x54, 0x28, 0xff, 0xff, +0xff, 0xda, 0xa6, 0x8a, 0xee, 0x66, 0x66, 0xe8, +0x44, 0x44, 0xe4, 0x42, 0x43, 0xdf, 0x41, 0x42, +0xe1, 0x62, 0x63, 0xee, 0xe6, 0xb2, 0xb9, 0xeb, +0x80, 0x92, 0x7d, 0x39, 0xef, 0xe4, 0xbf, 0xe9, +0xdb, 0xaa, 0xe9, 0xda, 0xa9, 0xe9, 0xd9, 0xa8, +0xbf, 0x6a, 0x34, 0xc3, 0x70, 0x43, 0xe7, 0x43, +0x44, 0x8b, 0x5c, 0x18, 0x69, 0x79, 0x19, 0x85, +0x5a, 0x16, 0xd3, 0x3e, 0x3f, 0xe1, 0xcd, 0x8b, +0xe1, 0xcb, 0x8a, 0xe0, 0xca, 0x89, 0xb3, 0x4b, +0x11, 0xb4, 0x4c, 0x14, 0xe1, 0x42, 0x42, 0xa2, +0xc6, 0x5f, 0xa4, 0xc9, 0x62, 0xa7, 0xcd, 0x66, +0xaa, 0xd2, 0x6a, 0xad, 0xd7, 0x6f, 0xb0, 0xdd, +0x73, 0xb3, 0xe2, 0x78, 0xb6, 0xe7, 0x7c, 0xbb, +0xef, 0x83, 0xce, 0x12, 0x12, 0xc7, 0x10, 0x10, +0xcc, 0x3c, 0x3c, 0xe9, 0xd9, 0xa7, 0xe0, 0xc9, +0x88, 0xdf, 0xc8, 0x87, 0xbe, 0x67, 0x2f, 0xdb, +0x40, 0x40, 0x84, 0x5a, 0x16, 0xc5, 0x0f, 0x10, +0xbe, 0x0e, 0x0e, 0xc6, 0x3b, 0x3b, 0xe8, 0xd7, +0xa6, 0xdf, 0xc7, 0x86, 0xde, 0xc5, 0x85, 0xcd, +0x8f, 0x5b, 0xdc, 0x61, 0x61, 0xcf, 0x3d, 0x3d, +0xca, 0x3c, 0x3c, 0xc5, 0x3b, 0x3b, 0xcc, 0x5d, +0x5d, 0xf0, 0xe8, 0xc2, 0xec, 0xe0, 0xad, 0xeb, +0xe0, 0xad, 0x8b, 0x7b, 0x37, 0xed, 0xdf, 0xbb, +0xe6, 0xd4, 0xa4, 0xe6, 0xd3, 0xa4, 0xe6, 0xd2, +0xa3, 0xe5, 0xca, 0xa3, 0xb5, 0x8f, 0x70, 0x8b, +0x5a, 0x72, 0xa1, 0x4f, 0x39, 0xb0, 0x48, 0x12, +0xa7, 0x9c, 0xc9, 0xf0, 0xe6, 0xc0, 0xea, 0xdc, +0xaa, 0xee, 0xe3, 0xbe, 0xed, 0xe1, 0xbc, 0xe7, +0xd6, 0xa5, 0xe7, 0xd5, 0xa4, 0xec, 0xde, 0xba, +0xec, 0xdd, 0xb9, 0xe6, 0xd1, 0xa2, 0xe5, 0xd1, +0xa1, 0xe5, 0xcf, 0xa1, 0xeb, 0xda, 0xb7, 0xe2, +0xcf, 0x8d, 0xe2, 0xce, 0x8c, 0xe1, 0xcc, 0x8b, +0xe9, 0xd8, 0xa7, 0xe7, 0xd6, 0xa6, 0xdf, 0xc7, +0x87, 0xde, 0xc6, 0x86, 0xde, 0xc4, 0x85, 0xe6, +0xd1, 0xa1, 0xdc, 0xc0, 0x81, 0xdc, 0xbf, 0x80, +0xdb, 0xbe, 0x80, 0xe4, 0xce, 0x9f, 0xe7, 0xd4, +0xa4, 0xde, 0xc3, 0x84, 0xdd, 0xc2, 0x83, 0xdc, +0xbe, 0x80, 0xdb, 0xbd, 0x7f, 0xdb, 0xbc, 0x7e, +0xe4, 0xcd, 0x9e, 0xe6, 0xd3, 0xa3, 0xdd, 0xc3, +0x83, 0xdd, 0xc2, 0x82, 0xdc, 0xc0, 0x82, 0xda, +0xbb, 0x7d, 0xe3, 0xcb, 0x9e, 0xe7, 0xd5, 0xa5, +0xe5, 0xd0, 0xa1, 0xe5, 0xcf, 0xa0, 0xeb, 0xd9, +0xb6, 0xe3, 0xcc, 0x9e, 0xea, 0xd8, 0xb6, 0xb5, +0x99, 0x7e, 0x60, 0x30, 0x24, 0x3b, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, 0x62, +0x4b, 0x47, 0x44, 0x7f, 0x48, 0xbf, 0x71, 0xe5, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x02, +0x74, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0x63, +0x60, 0x18, 0x05, 0x03, 0x0a, 0x18, 0x99, 0x18, +0x71, 0xca, 0x31, 0xb3, 0x80, 0x00, 0x33, 0x86, +0x0e, 0x56, 0xdc, 0x7a, 0x58, 0xd8, 0xd8, 0x39, +0x38, 0xb9, 0x58, 0x30, 0x74, 0xb0, 0xe2, 0xd6, +0xc3, 0xc2, 0xcd, 0xc3, 0xcb, 0xc7, 0x8f, 0xa6, +0x05, 0xa4, 0x03, 0xa8, 0x87, 0x34, 0x5b, 0x80, +0x0e, 0xc3, 0x69, 0x8b, 0x80, 0x20, 0x08, 0x08, +0xa0, 0x0b, 0x33, 0xe1, 0xb4, 0x83, 0x81, 0x41, +0x50, 0x48, 0x58, 0x44, 0x54, 0x4c, 0x10, 0x43, +0x8b, 0x38, 0x1e, 0x2d, 0x12, 0x92, 0x52, 0xd2, +0x32, 0x70, 0x2d, 0xd0, 0x00, 0x64, 0x61, 0x92, +0x65, 0x62, 0x81, 0xb0, 0xe5, 0x30, 0x82, 0x14, +0x4d, 0x0b, 0x0b, 0x9b, 0xbc, 0x82, 0xa2, 0x12, +0x8b, 0x32, 0x93, 0x0a, 0x93, 0x2a, 0x8b, 0x9a, +0xba, 0x86, 0xa6, 0x16, 0xa6, 0x67, 0xd1, 0xb5, +0x70, 0x6b, 0xeb, 0xe8, 0xea, 0xb1, 0xe8, 0x33, +0x19, 0x30, 0x19, 0xb2, 0x18, 0x19, 0x9b, 0x98, +0x9a, 0x61, 0x06, 0x29, 0x9a, 0x5f, 0xe0, 0xb6, +0x98, 0xe3, 0xb6, 0xc5, 0x02, 0x1c, 0x62, 0x16, +0x30, 0xae, 0x25, 0xd8, 0xe5, 0x96, 0x2c, 0x4c, +0x56, 0x4c, 0x2c, 0x10, 0xb6, 0x35, 0x46, 0x90, +0xa2, 0xd9, 0x62, 0x63, 0x6b, 0x67, 0x67, 0x67, +0x6f, 0xe3, 0xc0, 0xe4, 0xc8, 0xe4, 0x64, 0xe3, +0xec, 0xe2, 0xea, 0xe6, 0x6e, 0x83, 0x11, 0xa4, +0x68, 0x7e, 0xb1, 0xb1, 0xf3, 0xf0, 0xf4, 0xf4, +0xb2, 0xf1, 0x66, 0xf2, 0x61, 0xf2, 0xb5, 0xf1, +0xf3, 0x0f, 0x08, 0x0c, 0xb2, 0x41, 0x55, 0x80, +0x45, 0x4b, 0xb0, 0x67, 0x48, 0x68, 0x98, 0x4d, +0x38, 0x53, 0x04, 0x93, 0x9f, 0x8d, 0x5b, 0x60, +0x64, 0x54, 0x34, 0x61, 0x2d, 0x5e, 0x21, 0x31, +0xb1, 0xe1, 0x36, 0x71, 0x4c, 0xf1, 0x4c, 0x6e, +0x36, 0x41, 0x51, 0x09, 0x89, 0x49, 0xc9, 0x29, +0xa9, 0x69, 0xe9, 0x19, 0x99, 0x78, 0xfc, 0x92, +0xe5, 0x1d, 0x9e, 0x9d, 0x63, 0xe3, 0x0c, 0xd4, +0x92, 0x6b, 0x93, 0x17, 0x9d, 0x94, 0x5f, 0x50, +0x58, 0x54, 0x5c, 0x52, 0x5c, 0x54, 0x5a, 0x86, +0xd0, 0x52, 0x5e, 0x01, 0x02, 0xe5, 0x30, 0x6e, +0xa5, 0x8d, 0x8d, 0x4d, 0x15, 0x53, 0x75, 0x05, +0x50, 0x4b, 0x45, 0x0d, 0x90, 0x6d, 0x53, 0x5b, +0x54, 0x57, 0x57, 0x5f, 0x5f, 0x57, 0xd4, 0x80, +0xd0, 0x52, 0xd1, 0xd8, 0xd4, 0xdc, 0xd2, 0x5a, +0x01, 0xb7, 0xc5, 0x29, 0xae, 0x8d, 0xa9, 0x9d, +0xa9, 0x03, 0xa8, 0xa5, 0xb5, 0xa2, 0xb3, 0xab, +0xbb, 0xa7, 0xb7, 0xb8, 0x0e, 0xa4, 0xa7, 0xb8, +0x0f, 0x49, 0x4b, 0xff, 0x04, 0x26, 0x74, 0xd0, +0x1e, 0xc1, 0x34, 0x91, 0x69, 0xd2, 0xe4, 0x8a, +0xee, 0x29, 0x53, 0xa7, 0x4d, 0x2f, 0xa9, 0x07, +0xe9, 0x29, 0x99, 0x81, 0xa4, 0x65, 0x26, 0x13, +0xeb, 0x2c, 0xf1, 0xd9, 0xb2, 0x73, 0x54, 0xe6, +0x1a, 0xcc, 0x33, 0x9f, 0x6f, 0xb5, 0xc0, 0x71, +0xa1, 0x4f, 0x7b, 0xc4, 0x22, 0xa6, 0xc5, 0x4b, +0x96, 0x56, 0x2c, 0x9b, 0xb6, 0x7c, 0xc5, 0xca, +0xe2, 0x7a, 0x90, 0x1e, 0x14, 0x5b, 0x56, 0xad, +0xc6, 0x66, 0xcb, 0xea, 0x35, 0x6b, 0xd7, 0x55, +0xac, 0x5f, 0xb1, 0x61, 0xe3, 0xa6, 0x22, 0x90, +0x57, 0x50, 0xfd, 0xb2, 0x79, 0xcb, 0xd6, 0x6d, +0xdb, 0x11, 0x7e, 0xd9, 0xb1, 0x73, 0x17, 0xd0, +0x2f, 0xbb, 0xc1, 0x82, 0x7b, 0xf6, 0xee, 0xdb, +0x7f, 0x80, 0xe8, 0x10, 0x03, 0x01, 0x70, 0x88, +0xd9, 0x1c, 0x3c, 0x74, 0xf8, 0xc8, 0xe1, 0x43, +0x47, 0xf1, 0xc4, 0xcb, 0xb1, 0xa4, 0xe3, 0x5d, +0x27, 0x6c, 0x4e, 0xae, 0x3f, 0x75, 0xfa, 0x8c, +0xcd, 0xd9, 0x73, 0xe7, 0x2f, 0x5c, 0x24, 0x9c, +0xc6, 0x8e, 0x5f, 0xba, 0x7c, 0xe5, 0xaa, 0xcd, +0xb5, 0xeb, 0x37, 0x6e, 0xee, 0xb7, 0xb9, 0x75, +0xfb, 0xce, 0xdd, 0x7b, 0x84, 0x13, 0x0c, 0x28, +0x60, 0xd7, 0xdb, 0xdc, 0xdf, 0xf8, 0xe0, 0xe1, +0x2d, 0x9b, 0x0b, 0x8f, 0x1e, 0x3f, 0x79, 0x4a, +0x58, 0x0b, 0x28, 0x60, 0xef, 0xdb, 0x3c, 0x7b, +0xfe, 0xe2, 0xe5, 0x05, 0x9b, 0x7b, 0x8f, 0x9f, +0xbc, 0x7a, 0x8d, 0x45, 0x0b, 0x9a, 0x5f, 0x4e, +0x5e, 0x7b, 0xb3, 0x17, 0xe8, 0x8b, 0x5b, 0x6f, +0xdf, 0x5d, 0xb4, 0x79, 0xff, 0xe1, 0xc3, 0xeb, +0x8f, 0x98, 0x7e, 0x41, 0xcb, 0x95, 0x95, 0xe0, +0x50, 0x42, 0x26, 0x3f, 0xa1, 0x2a, 0x60, 0xc0, +0x59, 0x8e, 0xe1, 0x03, 0x82, 0x18, 0x4e, 0x1d, +0x2c, 0x5a, 0x48, 0xf7, 0x8b, 0x05, 0x46, 0x80, +0x8c, 0x82, 0x01, 0x06, 0x00, 0x4d, 0xe2, 0xeb, +0xbe, 0x2f, 0x59, 0xe1, 0xfb, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_hash_anti_join_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_hash_anti_join_png = new wxImage(); + if (!img_ex_hash_anti_join_png || !img_ex_hash_anti_join_png->IsOk()) + { + wxMemoryInputStream img_ex_hash_anti_join_pngIS(ex_hash_anti_join_png_data, sizeof(ex_hash_anti_join_png_data)); + img_ex_hash_anti_join_png->LoadFile(img_ex_hash_anti_join_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_hash_anti_join_png; +} +#define ex_hash_anti_join_png_img ex_hash_anti_join_png_img() + +static wxBitmap *ex_hash_anti_join_png_bmp() +{ + static wxBitmap *bmp_ex_hash_anti_join_png; + if (!bmp_ex_hash_anti_join_png || !bmp_ex_hash_anti_join_png->IsOk()) + bmp_ex_hash_anti_join_png = new wxBitmap(*ex_hash_anti_join_png_img); + return bmp_ex_hash_anti_join_png; +} +#define ex_hash_anti_join_png_bmp ex_hash_anti_join_png_bmp() + +static wxIcon *ex_hash_anti_join_png_ico() +{ + static wxIcon *ico_ex_hash_anti_join_png; + if (!ico_ex_hash_anti_join_png || !ico_ex_hash_anti_join_png->IsOk()) + { + ico_ex_hash_anti_join_png = new wxIcon(); + ico_ex_hash_anti_join_png->CopyFromBitmap(*ex_hash_anti_join_png_bmp); + } + return ico_ex_hash_anti_join_png; +} +#define ex_hash_anti_join_png_ico ex_hash_anti_join_png_ico() + +#endif // EX_HASH_ANTI_JOIN_PNG_H diff --git a/include/images/ex_hash_semi_join.png b/include/images/ex_hash_semi_join.png new file mode 100644 index 0000000000000000000000000000000000000000..0051f996783873a4a27db4b971135e95cac8d744 GIT binary patch literal 1452 zcmY+CSx}P)6on&VE_dIWsf2%OOQ>VP^3a>#ezbi zQ$WfpN-;oW2^b&=k^l*WB?JiB_w`TyKVY?Ov`?Km=bn3K?)P@ef&wq>vfO70gTZ$B z`}qW$(($7$%uVxaUUo4IW>yn~4)ryiwS?^8pZAsxthkhpJ|kUEnO0vS%3>*s%xPsS z2k<7yY&!WTdW3!iaT!ycQNDmlo}HT35l7XO3C;8jz~MlDOvDm~m7Oo7J-u?muxfr@ zpW4Z+8|Svr5=g76*J7xhadTK|9F-Zn1z?W=#EU?ha)Ykg7?VO|88jh>7B!m@6$+o03~@7;%^vuMm@JJGmnsy zuG1*Xb4;BYgOU392vO(P&!Kp6@p=_SEyk&Y-2;lk%6vCay@A6~WuE;;C#7g56s?$SP%?QaR1+n-c`~kT8uNVa*2|@o?lo)=KN~N}8`2cd*w{>1 zTTgjgh@L@R+)G zO(PhQvf3nzE#>#mKw1u{SyOTb#j{N!#xvnegJKyEY1bgl8X%hmqzq8Kx;j$0LMUJl zz`VsQjOo~s>UR}uO21G3b~5>_sl;f1pL3yp6Y(*2 zTg|QPYVFdf4n2i1ryt-~R&&EyEH~GIaAZa|e{p<(Ym$Sy#1kbWFdS!sl4#8 zg+-&46R)?p=vdx>DZULg*TK_Nrt5 z-2iOB@sKY=Jc0s3a*{6G2s_h?5P1!wrHzP^j*5=&P&pEke^pz|yOz9TpDUboGQjBx zMo!1otB@1eyV;Rc&(=*V+v==K^@N)awupf0xSm8APIR0a))g^~LD(V`iz%%B9lV<9 zNW9qx+^!S-`8sx=M=9LFn)pSWRENVZslD!B8wv}&N}w0~Q)Iq<_h*6eL%R>T0alj*U0b~~`wx_Vx`_n~Y1o};*=weXmz#wPa!-WHU)K7MW;+k{KB^hrTOISzk zQem*}7uv?l*3EgQg4t*IhG!(iW+b}Drze^M=7@AaA{-nMNQY2Iq`R||yR-9g#41KY&_u`GpC9`TGX?bfIFt{})E(L^%Ke literal 0 HcmV?d00001 diff --git a/include/images/ex_hash_semi_join.pngc b/include/images/ex_hash_semi_join.pngc new file mode 100644 index 0000000..502e1c2 --- /dev/null +++ b/include/images/ex_hash_semi_join.pngc @@ -0,0 +1,226 @@ +#ifndef EX_HASH_SEMI_JOIN_PNG_H +#define EX_HASH_SEMI_JOIN_PNG_H + +static const unsigned char ex_hash_semi_join_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x02, 0x97, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x99, 0xbc, 0x78, 0x52, +0x8d, 0x19, 0x89, 0xb9, 0xdb, 0x36, 0x88, 0xc1, +0xa1, 0xc4, 0x5e, 0x6f, 0xcd, 0xee, 0x4d, 0xc0, +0xe9, 0x61, 0xc6, 0xeb, 0x76, 0xcd, 0xec, 0xa6, +0xde, 0xf2, 0x40, 0xbc, 0xe9, 0x12, 0xab, 0xe2, +0x2c, 0xb3, 0xe4, 0x48, 0xbc, 0xe6, 0x89, 0xd3, +0xee, 0x74, 0x8b, 0xd5, 0x66, 0x6b, 0xd1, 0xcc, +0xcd, 0xf1, 0xc0, 0xc1, 0xee, 0xc6, 0xc7, 0xef, +0xcd, 0xce, 0xf2, 0xde, 0xde, 0xf6, 0xa3, 0xc7, +0x61, 0xbc, 0xbd, 0xec, 0xab, 0xac, 0xe8, 0xb3, +0xb4, 0xea, 0xbc, 0xbd, 0xed, 0xd4, 0xd4, 0xf3, +0x70, 0xab, 0xd3, 0x9a, 0xc3, 0xe0, 0xa5, 0xcb, +0x64, 0xc4, 0xdc, 0xed, 0xb7, 0xe6, 0xf6, 0xa8, +0xd0, 0x68, 0xbd, 0xe8, 0xf7, 0xc1, 0xe9, 0xf7, +0xb0, 0xe3, 0xf5, 0xb3, 0xe3, 0xf5, 0xb6, 0xe5, +0xf5, 0xcb, 0xec, 0xf8, 0xcf, 0xed, 0xf8, 0xc2, +0xe8, 0xf6, 0xc5, 0xe9, 0xf6, 0xc7, 0xea, 0xf6, +0xd6, 0xef, 0xf9, 0x9f, 0xdd, 0xf4, 0xab, 0xd5, +0x6c, 0xa7, 0xe0, 0xf4, 0xad, 0xe2, 0xf5, 0x96, +0xd9, 0xf1, 0x9a, 0xda, 0xf2, 0x9e, 0xdc, 0xf2, +0xba, 0xe6, 0xf5, 0xc0, 0xe7, 0xf6, 0xae, 0xe1, +0xf3, 0xb2, 0xe2, 0xf3, 0xb5, 0xe3, 0xf3, 0xc9, +0xea, 0xf7, 0xae, 0xda, 0x71, 0xa5, 0xa8, 0xe4, +0x7a, 0x9e, 0xa9, 0x72, 0x95, 0x9e, 0xe0, 0xc7, +0x9a, 0xb2, 0xe0, 0x76, 0xd4, 0xd0, 0xbc, 0xc0, +0xc0, 0xd6, 0xb2, 0xb5, 0xe8, 0xba, 0xc5, 0xea, +0xc1, 0x8f, 0x36, 0xf4, 0xf1, 0xc9, 0xf0, 0xec, +0xb7, 0xf9, 0xf8, 0xe4, 0xb5, 0xe5, 0x7a, 0xf9, +0xf7, 0xe3, 0xf9, 0xf6, 0xe3, 0xf7, 0xf3, 0xd9, +0xf6, 0xf3, 0xd9, 0xf6, 0xf2, 0xd8, 0xf8, 0xf5, +0xe1, 0xe5, 0xe6, 0xf8, 0xdf, 0xe0, 0xf6, 0xe2, +0xe3, 0xf7, 0xe6, 0xe6, 0xf8, 0xee, 0xee, 0xfa, +0xeb, 0xe6, 0x9f, 0xf7, 0xf5, 0xda, 0xb8, 0xe9, +0x7e, 0xf7, 0xf4, 0xd9, 0xf3, 0xee, 0xcc, 0xf3, +0xee, 0xcb, 0xf3, 0xed, 0xcb, 0xf6, 0xf1, 0xd7, +0xdd, 0xde, 0xf5, 0xd5, 0xd5, 0xf3, 0xd9, 0xd9, +0xf4, 0xdd, 0xde, 0xf6, 0xe9, 0xe9, 0xf9, 0xf0, +0xec, 0xb6, 0xf7, 0xf4, 0xda, 0xba, 0xed, 0x81, +0xf3, 0xed, 0xca, 0xf2, 0xec, 0xca, 0xf5, 0xf0, +0xd7, 0xeb, 0xe5, 0x9e, 0xea, 0xe4, 0x9d, 0xef, +0xe9, 0xb4, 0xbc, 0xf0, 0x84, 0xf2, 0xec, 0xc9, +0xf2, 0xeb, 0xc9, 0xf5, 0xef, 0xd6, 0xef, 0xeb, +0xb6, 0xef, 0xea, 0xb5, 0xef, 0xe8, 0xb3, 0xf2, +0xec, 0xc5, 0xf9, 0xf6, 0xe2, 0xf8, 0xf4, 0xe1, +0xf7, 0xf3, 0xe0, 0xa7, 0x53, 0x6c, 0xa9, 0x17, +0x17, 0xdb, 0xbd, 0x89, 0x80, 0x8e, 0x25, 0x7d, +0x76, 0x27, 0xc5, 0x69, 0x5e, 0xcb, 0xc6, 0xd9, +0xd2, 0xd3, 0xf1, 0xee, 0x66, 0x66, 0xe8, 0x44, +0x44, 0xe4, 0x42, 0x43, 0xdf, 0x41, 0x42, 0xe1, +0x62, 0x63, 0xf3, 0xed, 0xc6, 0xee, 0xe6, 0xb2, +0xed, 0xe4, 0xb0, 0xb9, 0xeb, 0x80, 0x92, 0x7d, +0x39, 0xf5, 0xee, 0xd5, 0xf4, 0xee, 0xd5, 0xf4, +0xed, 0xd4, 0xf7, 0xf1, 0xdf, 0xe7, 0x43, 0x44, +0x8b, 0x5c, 0x18, 0x69, 0x79, 0x19, 0x85, 0x5a, +0x16, 0xd3, 0x3e, 0x3f, 0xf1, 0xe8, 0xc6, 0xf0, +0xe7, 0xc6, 0xf0, 0xe6, 0xc5, 0xf4, 0xec, 0xd3, +0xe1, 0x42, 0x42, 0xa2, 0xc6, 0x5f, 0xa4, 0xc9, +0x62, 0xa7, 0xcd, 0x66, 0xaa, 0xd2, 0x6a, 0xad, +0xd7, 0x6f, 0xb0, 0xdd, 0x73, 0xb3, 0xe2, 0x78, +0xb6, 0xe7, 0x7c, 0xbb, 0xef, 0x83, 0xce, 0x12, +0x12, 0xc7, 0x10, 0x10, 0xcc, 0x3c, 0x3c, 0xf0, +0xe5, 0xc4, 0xf3, 0xeb, 0xd3, 0xdb, 0x40, 0x40, +0x84, 0x5a, 0x16, 0xc5, 0x0f, 0x10, 0xbe, 0x0e, +0x0e, 0xc6, 0x3b, 0x3b, 0xf4, 0xec, 0xd4, 0xf0, +0xe5, 0xc5, 0xef, 0xe5, 0xc4, 0xef, 0xe4, 0xc3, +0xf3, 0xea, 0xd2, 0xdc, 0x61, 0x61, 0xcf, 0x3d, +0x3d, 0xca, 0x3c, 0x3c, 0xc5, 0x3b, 0x3b, 0xcc, +0x5d, 0x5d, 0xef, 0xe3, 0xbe, 0xe8, 0xd8, 0xa7, +0xe7, 0xd6, 0xa5, 0x8b, 0x7b, 0x37, 0xf6, 0xf0, +0xde, 0xf5, 0xef, 0xdd, 0xec, 0xde, 0xba, 0xe6, +0xd1, 0xa2, 0xe5, 0xd0, 0xa1, 0xe4, 0xce, 0x9f, +0xeb, 0xd9, 0xb6, 0xf6, 0xf0, 0xdd, 0xf6, 0xef, +0xdd, 0xf2, 0xe9, 0xd1, 0xf2, 0xe8, 0xd0, 0xf5, +0xee, 0xdc, 0xdc, 0xbe, 0x80, 0xdb, 0xbc, 0x7e, +0xda, 0xbb, 0x7d, 0xe3, 0xcb, 0x9e, 0xef, 0xe4, +0xc4, 0xef, 0xe3, 0xc3, 0xee, 0xe1, 0xc1, 0xee, +0xe0, 0xc1, 0xee, 0xe0, 0xc0, 0xf2, 0xe7, 0xd0, +0xda, 0xbb, 0x7e, 0xda, 0xba, 0x7d, 0xef, 0xe2, +0xc2, 0xed, 0xdf, 0xc0, 0xf2, 0xe6, 0xcf, 0xee, +0xe2, 0xc2, 0xed, 0xde, 0xbf, 0xf1, 0xe6, 0xcf, +0xea, 0xd8, 0xb6, 0xf5, 0xee, 0xdd, 0xf2, 0xe8, +0xd1, 0xf5, 0xed, 0xdb, 0xf1, 0xe6, 0xce, 0xf4, +0xec, 0xda, 0xd3, 0xb0, 0x70, 0xed, 0xde, 0xc4, +0x28, 0xc8, 0x42, 0x88, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x02, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, +0x63, 0x60, 0x18, 0x05, 0x03, 0x0b, 0x18, 0x99, +0x18, 0x71, 0xca, 0x31, 0xb3, 0x80, 0x00, 0x33, +0x86, 0x0e, 0x56, 0xdc, 0x7a, 0x58, 0xd8, 0xd8, +0x39, 0x38, 0xb9, 0x58, 0x30, 0x74, 0xb0, 0xe2, +0xd6, 0xc3, 0xc2, 0xcd, 0xc3, 0xcb, 0xc7, 0x8f, +0xa6, 0x05, 0xa4, 0x03, 0xa8, 0x87, 0x34, 0x5b, +0x80, 0x0e, 0xc3, 0x69, 0x8b, 0x80, 0x20, 0x08, +0x08, 0xa0, 0x0b, 0x33, 0xe1, 0xb4, 0x83, 0x81, +0x41, 0x50, 0x48, 0x58, 0x44, 0x54, 0x4c, 0x10, +0x43, 0x8b, 0x38, 0x1e, 0x2d, 0x12, 0x92, 0x52, +0xd2, 0x32, 0x70, 0x2d, 0x90, 0x00, 0x94, 0x95, +0x63, 0x92, 0x67, 0x92, 0x53, 0x90, 0x03, 0x01, +0x28, 0x89, 0x5b, 0x0b, 0xd4, 0x6b, 0x8a, 0x4c, +0x4a, 0x4c, 0xca, 0x72, 0x2a, 0xaa, 0x6a, 0xea, +0x1a, 0x72, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x72, +0x78, 0xb4, 0x40, 0x02, 0x50, 0x8f, 0x49, 0x9f, +0xc9, 0x40, 0xce, 0xd0, 0xc8, 0xd8, 0xc4, 0x54, +0xce, 0xcc, 0xdc, 0xc2, 0xd2, 0x0a, 0x45, 0x0b, +0xaa, 0x5f, 0xe0, 0xb6, 0x58, 0xe3, 0xb6, 0xc5, +0x06, 0x1c, 0x62, 0x36, 0x30, 0xae, 0x2d, 0xd8, +0x2f, 0x76, 0xf6, 0x4c, 0x0e, 0x4c, 0xf6, 0x8e, +0xf6, 0x20, 0xe0, 0xe4, 0x0c, 0x02, 0x2e, 0xb8, +0x6d, 0x71, 0x75, 0x73, 0x77, 0x77, 0x77, 0x73, +0xf5, 0x60, 0xf2, 0x64, 0xf2, 0xb2, 0xf7, 0xf6, +0xf1, 0xf5, 0xf3, 0x77, 0x0e, 0x08, 0x0c, 0x0a, +0x0e, 0x71, 0xc6, 0xed, 0x17, 0x57, 0xf7, 0xd0, +0xd0, 0x50, 0x77, 0xd7, 0x30, 0xa6, 0x70, 0xa6, +0x08, 0x7b, 0xdf, 0xc8, 0xa8, 0xe8, 0x18, 0xe7, +0xd8, 0xb8, 0xf8, 0x84, 0x44, 0x42, 0x5a, 0x92, +0x5c, 0x93, 0x99, 0x52, 0x98, 0x7c, 0xec, 0xfd, +0xa2, 0x53, 0xd3, 0xd2, 0x89, 0xd1, 0x92, 0x91, +0x99, 0x05, 0xd4, 0x92, 0xcd, 0xe4, 0x67, 0x1f, +0x93, 0x96, 0x93, 0x9b, 0x87, 0x45, 0x0b, 0xba, +0x5f, 0xf2, 0x0b, 0x0a, 0x8b, 0x5c, 0x8b, 0x81, +0x5a, 0xfc, 0xed, 0x4b, 0xd2, 0xf3, 0xf2, 0x4a, +0x31, 0xfd, 0x52, 0x56, 0x0e, 0x02, 0x65, 0x30, +0x6e, 0x85, 0xab, 0xab, 0x6b, 0x25, 0x53, 0x55, +0x39, 0x50, 0x4b, 0x79, 0x35, 0x38, 0xc4, 0x6a, +0xc0, 0x21, 0x56, 0x8b, 0xa4, 0xa5, 0xbc, 0xae, +0xbe, 0xa1, 0xb1, 0xa9, 0x1c, 0x6e, 0x4b, 0x73, +0x4b, 0x2b, 0x53, 0x1b, 0x53, 0x3b, 0x50, 0x4b, +0x53, 0x79, 0x69, 0x47, 0x67, 0x57, 0x37, 0xa6, +0x2d, 0xe5, 0x3d, 0xbd, 0x4c, 0xe8, 0xa0, 0x2d, +0x85, 0xa9, 0x8f, 0xa9, 0x7f, 0x42, 0x79, 0xe7, +0xc4, 0x49, 0x93, 0xa7, 0x60, 0xfa, 0xa5, 0x7c, +0x2a, 0x13, 0xeb, 0x34, 0xf1, 0xe9, 0xf2, 0x33, +0x94, 0x66, 0xea, 0xcf, 0xb2, 0x9e, 0xed, 0x30, +0xc7, 0x73, 0x6e, 0x78, 0x5b, 0xca, 0x3c, 0xa6, +0xf9, 0x0b, 0x16, 0x96, 0x77, 0x4d, 0x9e, 0xbc, +0x68, 0x31, 0x16, 0x2d, 0x4b, 0x96, 0x62, 0xb3, +0x65, 0xe9, 0xb2, 0xe5, 0x2b, 0xca, 0x57, 0xae, +0x5a, 0xbd, 0x66, 0x2d, 0x16, 0x2d, 0xeb, 0xd6, +0x6f, 0xd8, 0xb8, 0x09, 0xe1, 0x97, 0xcd, 0x5b, +0xb6, 0x02, 0xfd, 0xb2, 0x0d, 0x2c, 0xb8, 0x7d, +0xf1, 0xda, 0xb5, 0x3b, 0x88, 0x0e, 0x31, 0x10, +0xc0, 0x15, 0x62, 0xe8, 0xf1, 0xb2, 0x73, 0xd7, +0xee, 0x3d, 0x7b, 0x5d, 0xbb, 0x57, 0x4e, 0x59, +0xbc, 0xcf, 0x7e, 0xff, 0x81, 0x03, 0x07, 0x0f, +0x11, 0x4e, 0x63, 0xbb, 0x0f, 0x1f, 0x39, 0x7a, +0xcc, 0x75, 0xca, 0xa2, 0xe3, 0x27, 0xd6, 0xda, +0x1f, 0x38, 0x79, 0xea, 0xf4, 0x19, 0xc2, 0x09, +0x66, 0xcf, 0xd9, 0x73, 0xe7, 0x8e, 0xb9, 0x2e, +0x5e, 0x73, 0xe2, 0xfc, 0x01, 0xfb, 0x83, 0xa7, +0x2f, 0x5c, 0xb8, 0x48, 0x58, 0xcb, 0xb1, 0x73, +0x20, 0x2d, 0x6b, 0xcf, 0x5f, 0x3a, 0x79, 0xd0, +0xfe, 0xcc, 0x85, 0xcb, 0x97, 0xaf, 0x10, 0x4e, +0x63, 0x57, 0x8f, 0x1d, 0x3b, 0x76, 0xd5, 0xf5, +0xda, 0x81, 0xeb, 0x07, 0x6f, 0xd8, 0xdf, 0xb8, +0x72, 0xe5, 0xe6, 0x2d, 0x4c, 0xbf, 0xa0, 0xe5, +0x4a, 0x50, 0x88, 0xb9, 0xba, 0xde, 0x06, 0x87, +0xd5, 0x1d, 0xe2, 0x42, 0x8c, 0x18, 0x80, 0xe6, +0x97, 0x41, 0xa4, 0x85, 0x74, 0xbf, 0xa0, 0x85, +0xd8, 0x28, 0x18, 0x70, 0x00, 0x00, 0xb0, 0xac, +0xf0, 0xa0, 0x55, 0x10, 0xa4, 0x7c, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_hash_semi_join_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_hash_semi_join_png = new wxImage(); + if (!img_ex_hash_semi_join_png || !img_ex_hash_semi_join_png->IsOk()) + { + wxMemoryInputStream img_ex_hash_semi_join_pngIS(ex_hash_semi_join_png_data, sizeof(ex_hash_semi_join_png_data)); + img_ex_hash_semi_join_png->LoadFile(img_ex_hash_semi_join_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_hash_semi_join_png; +} +#define ex_hash_semi_join_png_img ex_hash_semi_join_png_img() + +static wxBitmap *ex_hash_semi_join_png_bmp() +{ + static wxBitmap *bmp_ex_hash_semi_join_png; + if (!bmp_ex_hash_semi_join_png || !bmp_ex_hash_semi_join_png->IsOk()) + bmp_ex_hash_semi_join_png = new wxBitmap(*ex_hash_semi_join_png_img); + return bmp_ex_hash_semi_join_png; +} +#define ex_hash_semi_join_png_bmp ex_hash_semi_join_png_bmp() + +static wxIcon *ex_hash_semi_join_png_ico() +{ + static wxIcon *ico_ex_hash_semi_join_png; + if (!ico_ex_hash_semi_join_png || !ico_ex_hash_semi_join_png->IsOk()) + { + ico_ex_hash_semi_join_png = new wxIcon(); + ico_ex_hash_semi_join_png->CopyFromBitmap(*ex_hash_semi_join_png_bmp); + } + return ico_ex_hash_semi_join_png; +} +#define ex_hash_semi_join_png_ico ex_hash_semi_join_png_ico() + +#endif // EX_HASH_SEMI_JOIN_PNG_H diff --git a/include/images/ex_hash_setop_except.png b/include/images/ex_hash_setop_except.png new file mode 100644 index 0000000000000000000000000000000000000000..76c546a4dadd7fdae310dafcec2ecdef9649d4c5 GIT binary patch literal 1377 zcmV-n1)lneP)P)t-s0001q zx!X2~!Eep(O~C14#_M*??55uGK)mS^tKuxP9z`^du$M4O~ z^4{L|yuIwJtmw0}>b$+})YS8(sN_Yy=}f@sQ^M+n)bNzp@OsYdgVF7a)b6d{^O?MO zQjHmqwrtqt%Ll095Ub)EuH#+B>v7BMPQK<^!RKVf=#tg%p~PN$dan$D+qz>g1j3n(pSaq{?IO>bB|Oo9N$}=iQg=Uu0GqniM5%2 zwBvd3=D_LPs_ELO=+~$1-@AITLFwA5;LD2N$cNs=h33(sjloms*QVdbhTg-3-NAz8 z&!D#FeCE`o-NJ+1z=7Mnf8@=cx$A%H+qmVe#lr?t*-@L%i^Wmdsu2=AY~3 zp6}_j^61v!$C}WqXvLRA$F!xasnm>++;Mf(vbE^o;r8$9wesx6=F+awtZJydFPPaY zjqWG6vC4&kzm|uj!nL^a^ZV4*@~N!lj*;EL!|c+nY?{_9i1sFWzH5(?-O$nT?A*cg z?Z)orvhC!s?BcKR=fQ#6N$usa=Gm3y)|2GZkm}s3cd&fiz>e(VuH@B`)E#4zJS}je%iZz zOV0d!JMQvg8b*k%9#010qNS#tmY07w7;07w8v$!k6U00K`* zL_t(Y$75h18!$3~03#_{n3!2u+1Qy#(!#;X#mz&S7Se6u1^b1U6fJ!G0)j%qd?aZR z5fu}c7>rs-_lqPS2uKbKd9_ zOxilSdivP3!2P0PU|jav({i+z0kltEhjT>}Dx zaQX!$jRpIKgaY-1nSww#aj8!^Gy>=})5xgkm{?PyQeSXrL>$l-)A)qMq-30aK}mc* zDRE%Gq^6~3Wa896poFAkiJr!&3jm~}-@X0I9(w=)03~!qSaf7zbY(hYa%Ew3WdJfTF)%GL zGA%GMR5CC+G&4FhG%GMQIxsLenI#?o001R)MObuXVRU6WZEs|0W_bWIFflMKFgYzS jF;p@$Iy5voFg7bNH99ab%9mBF00000NkvXXu0mjfh#BXQ literal 0 HcmV?d00001 diff --git a/include/images/ex_hash_setop_except.pngc b/include/images/ex_hash_setop_except.pngc new file mode 100644 index 0000000..f56be8e --- /dev/null +++ b/include/images/ex_hash_setop_except.pngc @@ -0,0 +1,217 @@ +#ifndef EX_HASH_SETOP_EXCEPT_PNG_H +#define EX_HASH_SETOP_EXCEPT_PNG_H + +static const unsigned char ex_hash_setop_except_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x02, 0x49, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x89, 0xb9, 0xdb, 0x36, +0x88, 0xc1, 0x6f, 0xcd, 0xee, 0x4d, 0xc0, 0xe9, +0x61, 0xc6, 0xeb, 0x76, 0xcd, 0xec, 0xa6, 0xde, +0xf2, 0x40, 0xbc, 0xe9, 0x12, 0xab, 0xe2, 0x2c, +0xb3, 0xe4, 0x48, 0xbc, 0xe6, 0x89, 0xd3, 0xee, +0x64, 0x95, 0xd0, 0x66, 0x6b, 0xd1, 0xcc, 0xcd, +0xf1, 0xc0, 0xc1, 0xee, 0xc6, 0xc7, 0xef, 0xcd, +0xce, 0xf2, 0xde, 0xde, 0xf6, 0xbc, 0xbd, 0xec, +0xab, 0xac, 0xe8, 0xb3, 0xb4, 0xea, 0xbc, 0xbd, +0xed, 0xd4, 0xd4, 0xf3, 0xa5, 0xa8, 0xe4, 0x45, +0xbe, 0xe9, 0x4c, 0xc0, 0xe9, 0x53, 0xc2, 0xea, +0x85, 0xd4, 0xf0, 0x94, 0xd8, 0xf0, 0x7a, 0xce, +0xec, 0x83, 0xd1, 0xed, 0x8b, 0xd4, 0xee, 0xad, +0xdf, 0xf3, 0x99, 0xbc, 0x78, 0x52, 0x8d, 0x19, +0x90, 0xb6, 0x6c, 0xd8, 0xe5, 0xcb, 0x07, 0xa8, +0xe2, 0x10, 0xab, 0xe2, 0x1a, 0xae, 0xe3, 0x5d, +0xc5, 0xeb, 0x71, 0xcb, 0xec, 0x4e, 0xbe, 0xe6, +0x5a, 0xc1, 0xe7, 0x64, 0xc5, 0xe8, 0x92, 0xd5, +0xef, 0xa1, 0xc4, 0x5e, 0x84, 0xb0, 0x45, 0x72, +0xa3, 0x35, 0x7a, 0x9e, 0xa9, 0x6a, 0x8f, 0xa6, +0xc1, 0x8f, 0x36, 0xf4, 0xf1, 0xc9, 0xf0, 0xec, +0xb7, 0xf0, 0xec, 0xb6, 0xef, 0xeb, 0xb6, 0xf3, +0xef, 0xc7, 0xa2, 0xc7, 0x60, 0xea, 0xe4, 0x9d, +0xea, 0xe3, 0x9c, 0xe9, 0xe0, 0x9a, 0xee, 0xe6, +0xb3, 0xa4, 0xca, 0x63, 0xef, 0xea, 0xb6, 0xe9, +0xe1, 0x9b, 0xe8, 0xdf, 0x99, 0xe7, 0xdd, 0x97, +0xec, 0xe3, 0xb0, 0xa7, 0xcd, 0x66, 0xef, 0xe8, +0xb3, 0xe8, 0xde, 0x98, 0xe7, 0xdb, 0x96, 0xe6, +0xd8, 0x94, 0xec, 0xe0, 0xad, 0x97, 0xbb, 0x75, +0x86, 0xb6, 0x49, 0x76, 0xaa, 0x3b, 0xf1, 0xeb, +0xc4, 0xec, 0xe0, 0xae, 0xeb, 0xde, 0xac, 0xef, +0xe4, 0xbf, 0xba, 0xd1, 0xa3, 0xae, 0xda, 0x71, +0x78, 0xae, 0x3e, 0xdb, 0xbd, 0x89, 0xb5, 0x99, +0x7e, 0xb4, 0xe3, 0x79, 0xf0, 0xe6, 0xc0, 0xe9, +0xdc, 0xaa, 0xe9, 0xda, 0xa8, 0xe8, 0xd7, 0xa7, +0xed, 0xdf, 0xbb, 0x7a, 0xb1, 0x41, 0xe9, 0xda, +0xa9, 0xe0, 0xcb, 0x8a, 0xdf, 0xc8, 0x87, 0xde, +0xc5, 0x85, 0xe6, 0xd1, 0xa2, 0x8d, 0xc1, 0x53, +0xe8, 0xd7, 0xa6, 0xdf, 0xc6, 0x86, 0xde, 0xc3, +0x84, 0xdd, 0xc1, 0x82, 0xe5, 0xcf, 0xa0, 0xb6, +0xe7, 0x7c, 0xe6, 0xd4, 0xa4, 0xdd, 0xc2, 0x83, +0xdc, 0xc0, 0x81, 0xdb, 0xbd, 0x7f, 0xe4, 0xcd, +0x9e, 0xb9, 0xeb, 0x7f, 0xeb, 0xdb, 0xb8, 0xe5, +0xce, 0xa0, 0xe3, 0xcc, 0x9e, 0xea, 0xd8, 0xb6, +0xba, 0xee, 0x82, 0x7c, 0xb4, 0x43, 0xbc, 0xf0, +0x84, 0x96, 0xcc, 0x5d, 0xeb, 0xe6, 0x9f, 0xeb, +0xe5, 0x9e, 0xef, 0xe9, 0xb4, 0xf2, 0xe8, 0xd6, +0xe0, 0xc7, 0x9a, 0xd0, 0xab, 0x68, 0xc5, 0x97, +0x44, 0xc7, 0xb4, 0xa5, 0xac, 0xa9, 0xd4, 0x8c, +0x90, 0xdc, 0x71, 0x75, 0xd4, 0xb2, 0xb5, 0xe8, +0xe0, 0xe1, 0xf6, 0xef, 0xea, 0xb5, 0xf2, 0xec, +0xc5, 0xe6, 0xd2, 0xae, 0xd1, 0xac, 0x6a, 0xa8, +0xbc, 0x2f, 0x98, 0xd9, 0x2b, 0x8d, 0xee, 0x27, +0xb7, 0xb1, 0xca, 0x85, 0x81, 0xbf, 0x96, 0x87, +0xa4, 0xc2, 0xb5, 0xb8, 0xf2, 0xf3, 0xfb, 0xd4, +0xd5, 0xf2, 0xa9, 0xac, 0xe5, 0x8e, 0x91, 0xdd, +0xc1, 0xc3, 0xec, 0xd2, 0xad, 0x6c, 0x9a, 0xd6, +0x2b, 0x88, 0xf6, 0x26, 0x7a, 0xbe, 0x6b, 0x8f, +0x92, 0xdd, 0xd0, 0xd1, 0xf1, 0xec, 0xdc, 0xc1, +0xf3, 0xed, 0xc6, 0xee, 0xe6, 0xb2, 0xed, 0xe4, +0xb0, 0xec, 0xe2, 0xaf, 0xf0, 0xe7, 0xc1, 0x81, +0xda, 0x49, 0xed, 0xe5, 0xb1, 0xe6, 0xd9, 0x95, +0xe5, 0xd6, 0x93, 0xe4, 0xd3, 0x90, 0xea, 0xdc, +0xaa, 0x77, 0xb0, 0x7c, 0xdc, 0xc0, 0x8e, 0xec, +0xe2, 0xae, 0xe4, 0xd5, 0x91, 0xe3, 0xd2, 0x8f, +0xe2, 0xce, 0x8c, 0xe9, 0xd8, 0xa7, 0xed, 0xdf, +0xc6, 0xe2, 0xd0, 0x8d, 0xe1, 0xcd, 0x8b, 0xe0, +0xca, 0x89, 0xe7, 0xd5, 0xa5, 0xfa, 0xf6, 0xee, +0xef, 0xe3, 0xbe, 0xe8, 0xd8, 0xa7, 0xe7, 0xd6, +0xa5, 0xec, 0xdd, 0xb9, 0xec, 0xde, 0xba, 0xe5, +0xd0, 0xa1, 0xe4, 0xce, 0x9f, 0xeb, 0xd9, 0xb6, +0xdc, 0xbe, 0x80, 0xdb, 0xbc, 0x7e, 0xda, 0xbb, +0x7d, 0xe3, 0xcb, 0x9e, 0xda, 0xbb, 0x7e, 0xda, +0xba, 0x7d, 0x6b, 0x60, 0x9e, 0x1f, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x02, 0x4f, 0x49, 0x44, 0x41, 0x54, +0x48, 0xc7, 0x63, 0x60, 0x20, 0x1b, 0x30, 0x32, +0x81, 0x00, 0x23, 0x29, 0x5a, 0x98, 0x98, 0x59, +0x58, 0xd9, 0xd8, 0x99, 0x48, 0xd2, 0xc2, 0xc1, +0xc9, 0xc5, 0xcd, 0x43, 0x9a, 0x16, 0xd2, 0x6d, +0xe1, 0x05, 0xfb, 0x85, 0x97, 0x14, 0x2d, 0x7c, +0xfc, 0x02, 0x82, 0x42, 0xc2, 0x7c, 0x24, 0x69, +0x11, 0x11, 0x15, 0x13, 0x97, 0x18, 0x8c, 0x5a, +0x48, 0xf7, 0x8b, 0x24, 0x1f, 0x08, 0x48, 0x0e, +0x40, 0x88, 0x41, 0xd3, 0x1d, 0xae, 0xd4, 0x87, +0x4d, 0x0b, 0x13, 0xb3, 0x94, 0xb4, 0x8c, 0x2c, +0x93, 0x9c, 0xbc, 0x82, 0xa2, 0x12, 0x13, 0x3e, +0x2d, 0xca, 0x2a, 0x2a, 0xaa, 0x6a, 0x10, 0x2d, +0x1c, 0xea, 0x1a, 0x9a, 0x5a, 0x4c, 0xda, 0x3a, +0xba, 0x7a, 0xfa, 0xd8, 0xb4, 0xc0, 0xfd, 0xa2, +0x62, 0x60, 0x60, 0x08, 0xd1, 0x43, 0xc0, 0x16, +0x44, 0x88, 0x29, 0xab, 0x18, 0x01, 0xf5, 0x80, +0xc4, 0x8c, 0xc1, 0xbe, 0x30, 0xc1, 0x95, 0xfa, +0x90, 0x43, 0x4c, 0xd9, 0xc8, 0x40, 0x05, 0x44, +0x9b, 0x9a, 0x99, 0x5b, 0x58, 0x5a, 0x99, 0xe2, +0x0a, 0x4b, 0x14, 0xef, 0xab, 0x58, 0x43, 0xb4, +0x98, 0xdb, 0xd8, 0xda, 0xd9, 0x9b, 0xe2, 0x4a, +0x17, 0xa8, 0x5a, 0x1c, 0x20, 0x5a, 0x1c, 0x9d, +0x9c, 0x5d, 0x5c, 0x89, 0xd4, 0xe2, 0x06, 0xd1, +0xe2, 0xee, 0xe1, 0xe9, 0xe5, 0x8d, 0x5b, 0x0b, +0xb2, 0x8b, 0x7d, 0x7c, 0xfd, 0x94, 0x41, 0x5a, +0xfc, 0x5d, 0x03, 0x02, 0x83, 0x70, 0xfa, 0x05, +0x25, 0x8d, 0x05, 0xfb, 0x85, 0x84, 0x02, 0xf5, +0x84, 0x99, 0x82, 0x40, 0x38, 0x71, 0xa9, 0x4f, +0x39, 0x34, 0x02, 0xe8, 0x34, 0xd3, 0xc8, 0xa8, +0xe8, 0x98, 0x58, 0x53, 0xa2, 0x52, 0x5f, 0x70, +0x68, 0x44, 0x1c, 0xd0, 0x16, 0xd3, 0xf8, 0x84, +0xc4, 0xa4, 0x64, 0x9c, 0x7e, 0x41, 0x49, 0x7c, +0x3e, 0x29, 0x71, 0x60, 0xbf, 0xa4, 0xa6, 0xa5, +0x67, 0x64, 0xe2, 0xd4, 0x82, 0x52, 0x28, 0xa9, +0x64, 0x41, 0x42, 0x2c, 0x3b, 0x27, 0x37, 0x2f, +0x1f, 0xb7, 0x16, 0xe4, 0xa2, 0x4f, 0xa5, 0x00, +0xa2, 0xa5, 0xb0, 0x28, 0xbf, 0xb8, 0x04, 0xa7, +0x5f, 0x50, 0x6d, 0x29, 0x05, 0x6b, 0x21, 0x10, +0x62, 0x90, 0x24, 0x68, 0x0c, 0x09, 0xaf, 0xb2, +0x72, 0x15, 0x42, 0x61, 0xca, 0x00, 0x4e, 0x82, +0xe6, 0xe6, 0x66, 0xa6, 0x20, 0x0d, 0x2a, 0x65, +0xe5, 0x15, 0xaa, 0xc4, 0x68, 0x31, 0xaf, 0xac, +0xac, 0x34, 0x37, 0x05, 0xbb, 0x0a, 0xa8, 0x43, +0x8d, 0x58, 0x2d, 0x16, 0x10, 0x5b, 0x54, 0x88, +0xd2, 0x01, 0xd2, 0x52, 0x65, 0x53, 0x6d, 0x8a, +0x24, 0x52, 0x53, 0x5b, 0x57, 0x5f, 0x5f, 0xd7, +0xd0, 0xd8, 0xd4, 0xdc, 0xdc, 0xd4, 0xd2, 0x8a, +0xd5, 0x2f, 0x96, 0x6d, 0xee, 0xed, 0x48, 0x5a, +0x3a, 0x3a, 0xbb, 0xba, 0x7b, 0x7a, 0x7a, 0xfb, +0xfa, 0x27, 0x4c, 0x9c, 0x38, 0x69, 0xf2, 0x94, +0xa9, 0x98, 0x5a, 0x20, 0x01, 0x1a, 0x86, 0xd0, +0x31, 0x6d, 0xfa, 0x8c, 0x19, 0x33, 0x66, 0xce, +0x9a, 0x3d, 0x67, 0x5a, 0x07, 0x90, 0x3b, 0x7b, +0x16, 0xa6, 0x1e, 0xd3, 0xb9, 0xf3, 0xe6, 0x2f, +0x58, 0x08, 0xb7, 0xa5, 0xa6, 0x13, 0xa4, 0x63, +0xd1, 0x94, 0xd9, 0x0c, 0x0c, 0x73, 0x3a, 0x6b, +0x40, 0x7a, 0xa6, 0x60, 0xb8, 0xcd, 0x74, 0xf1, +0x92, 0xa5, 0xcb, 0x96, 0xc3, 0xb5, 0xd4, 0x76, +0x01, 0x75, 0xcc, 0x58, 0x31, 0x19, 0xc4, 0x5e, +0x59, 0x0b, 0x22, 0x27, 0xb7, 0x60, 0x68, 0x59, +0xb5, 0x7a, 0xcd, 0xda, 0x75, 0x70, 0x2d, 0x75, +0xdd, 0x20, 0x2d, 0x4d, 0x93, 0x40, 0xec, 0xf5, +0x75, 0x20, 0x72, 0x52, 0x13, 0x86, 0x96, 0xc0, +0x0d, 0x1b, 0x37, 0x6d, 0x86, 0x6b, 0xa9, 0xef, +0x01, 0x69, 0x69, 0x9e, 0x08, 0x62, 0x6f, 0xa9, +0x07, 0x91, 0x13, 0x9b, 0x31, 0xb4, 0x6c, 0xdd, +0xb6, 0x3d, 0x7b, 0x07, 0x49, 0x5a, 0xd0, 0x42, +0x8c, 0x28, 0x87, 0xed, 0x4c, 0xde, 0xb5, 0x7b, +0x0f, 0x69, 0xde, 0xdf, 0xb5, 0x77, 0xdf, 0xfe, +0x03, 0xa4, 0x05, 0xf2, 0xee, 0x83, 0x87, 0x0e, +0x21, 0xb4, 0x10, 0x15, 0x95, 0x07, 0x0e, 0xa1, +0x68, 0x21, 0x22, 0xc1, 0x98, 0x96, 0x1c, 0x38, +0x70, 0xa0, 0x84, 0xa4, 0x64, 0x89, 0x9e, 0xc6, +0xa8, 0x0b, 0x00, 0xa4, 0xa3, 0xdf, 0xbd, 0xfd, +0xcb, 0x1e, 0x7b, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_hash_setop_except_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_hash_setop_except_png = new wxImage(); + if (!img_ex_hash_setop_except_png || !img_ex_hash_setop_except_png->IsOk()) + { + wxMemoryInputStream img_ex_hash_setop_except_pngIS(ex_hash_setop_except_png_data, sizeof(ex_hash_setop_except_png_data)); + img_ex_hash_setop_except_png->LoadFile(img_ex_hash_setop_except_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_hash_setop_except_png; +} +#define ex_hash_setop_except_png_img ex_hash_setop_except_png_img() + +static wxBitmap *ex_hash_setop_except_png_bmp() +{ + static wxBitmap *bmp_ex_hash_setop_except_png; + if (!bmp_ex_hash_setop_except_png || !bmp_ex_hash_setop_except_png->IsOk()) + bmp_ex_hash_setop_except_png = new wxBitmap(*ex_hash_setop_except_png_img); + return bmp_ex_hash_setop_except_png; +} +#define ex_hash_setop_except_png_bmp ex_hash_setop_except_png_bmp() + +static wxIcon *ex_hash_setop_except_png_ico() +{ + static wxIcon *ico_ex_hash_setop_except_png; + if (!ico_ex_hash_setop_except_png || !ico_ex_hash_setop_except_png->IsOk()) + { + ico_ex_hash_setop_except_png = new wxIcon(); + ico_ex_hash_setop_except_png->CopyFromBitmap(*ex_hash_setop_except_png_bmp); + } + return ico_ex_hash_setop_except_png; +} +#define ex_hash_setop_except_png_ico ex_hash_setop_except_png_ico() + +#endif // EX_HASH_SETOP_EXCEPT_PNG_H diff --git a/include/images/ex_hash_setop_except_all.png b/include/images/ex_hash_setop_except_all.png new file mode 100644 index 0000000000000000000000000000000000000000..ba24ed16aeb0d93bd133902b0b2218e674f84528 GIT binary patch literal 1402 zcmV-=1%>*FP)9z`^du$M4O~ z^4{L|yuIwJtmw0}>b$+})YS6;005<^<8@RZo_dd}>F(d~=W?ycYR znY?&XjTw-(Y}nDs91*Qf2@yLz!f>DsB_%ZlH~hu+17=Fy^!!Bgnhrr*Yf-ou35 z!Gh(_ptk3H=G3I!!h_tvf!n=*woLpxaH2EfEY#uzcLWj_l&D*ucm(h}en7!-`tFNhEWf)M}EFrc1rGZ2VCmcb2F!XklAGmDCj ziH$QOD!+z=MaBbdF-u5HN>0J)7nH>3n;H-HOImtHW)@B@D20-0HYCJya`W;FaBD#> z`cw-cT8fGbN=kA11=W@^uoeO#21$Y@knk$6P$d+m4B#YaVPS3t(x6&iQK?3Z7K^H? zDho5PtAIMxiPd5Wu|<_A9Uv{$wl!u*BDHn(4Gr~;P0cMW&8=-%{bJSb(Sf9;v#YzO zx3{lOka_Rtznx*Q{N)9pF literal 0 HcmV?d00001 diff --git a/include/images/ex_hash_setop_except_all.pngc b/include/images/ex_hash_setop_except_all.pngc new file mode 100644 index 0000000..c2e1369 --- /dev/null +++ b/include/images/ex_hash_setop_except_all.pngc @@ -0,0 +1,220 @@ +#ifndef EX_HASH_SETOP_EXCEPT_ALL_PNG_H +#define EX_HASH_SETOP_EXCEPT_ALL_PNG_H + +static const unsigned char ex_hash_setop_except_all_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x02, 0x4c, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x89, 0xb9, 0xdb, 0x36, +0x88, 0xc1, 0x6f, 0xcd, 0xee, 0x4d, 0xc0, 0xe9, +0x61, 0xc6, 0xeb, 0x76, 0xcd, 0xec, 0xa6, 0xde, +0xf2, 0x40, 0xbc, 0xe9, 0x12, 0xab, 0xe2, 0x2c, +0xb3, 0xe4, 0x48, 0xbc, 0xe6, 0x89, 0xd3, 0xee, +0x64, 0x95, 0xd0, 0x66, 0x6b, 0xd1, 0xcc, 0xcd, +0xf1, 0xc0, 0xc1, 0xee, 0xc6, 0xc7, 0xef, 0xcd, +0xce, 0xf2, 0xde, 0xde, 0xf6, 0xbc, 0xbd, 0xec, +0xab, 0xac, 0xe8, 0xb3, 0xb4, 0xea, 0xbc, 0xbd, +0xed, 0xd4, 0xd4, 0xf3, 0x00, 0x00, 0x00, 0xa5, +0xa8, 0xe4, 0x45, 0xbe, 0xe9, 0x4c, 0xc0, 0xe9, +0x53, 0xc2, 0xea, 0x85, 0xd4, 0xf0, 0x94, 0xd8, +0xf0, 0x7a, 0xce, 0xec, 0x83, 0xd1, 0xed, 0x8b, +0xd4, 0xee, 0xad, 0xdf, 0xf3, 0x99, 0xbc, 0x78, +0x52, 0x8d, 0x19, 0x90, 0xb6, 0x6c, 0xd8, 0xe5, +0xcb, 0x07, 0xa8, 0xe2, 0x10, 0xab, 0xe2, 0x1a, +0xae, 0xe3, 0x5d, 0xc5, 0xeb, 0x71, 0xcb, 0xec, +0x4e, 0xbe, 0xe6, 0x5a, 0xc1, 0xe7, 0x64, 0xc5, +0xe8, 0x92, 0xd5, 0xef, 0xa1, 0xc4, 0x5e, 0x84, +0xb0, 0x45, 0x72, 0xa3, 0x35, 0x7a, 0x9e, 0xa9, +0x6a, 0x8f, 0xa6, 0xc1, 0x8f, 0x36, 0xf4, 0xf1, +0xc9, 0xf0, 0xec, 0xb7, 0xf0, 0xec, 0xb6, 0xef, +0xeb, 0xb6, 0xf3, 0xef, 0xc7, 0xa2, 0xc7, 0x60, +0xea, 0xe4, 0x9d, 0xea, 0xe3, 0x9c, 0xe9, 0xe0, +0x9a, 0xee, 0xe6, 0xb3, 0xa4, 0xca, 0x63, 0xef, +0xea, 0xb6, 0xe9, 0xe1, 0x9b, 0xe8, 0xdf, 0x99, +0xe7, 0xdd, 0x97, 0xec, 0xe3, 0xb0, 0xa7, 0xcd, +0x66, 0xef, 0xe8, 0xb3, 0xe8, 0xde, 0x98, 0xe7, +0xdb, 0x96, 0xe6, 0xd8, 0x94, 0xec, 0xe0, 0xad, +0x97, 0xbb, 0x75, 0x86, 0xb6, 0x49, 0x76, 0xaa, +0x3b, 0xf1, 0xeb, 0xc4, 0xec, 0xe0, 0xae, 0xeb, +0xde, 0xac, 0xef, 0xe4, 0xbf, 0xba, 0xd1, 0xa3, +0xae, 0xda, 0x71, 0x78, 0xae, 0x3e, 0xdb, 0xbd, +0x89, 0xb5, 0x99, 0x7e, 0xb4, 0xe3, 0x79, 0xf0, +0xe6, 0xc0, 0xe9, 0xdc, 0xaa, 0xe9, 0xda, 0xa8, +0xe8, 0xd7, 0xa7, 0xed, 0xdf, 0xbb, 0x7a, 0xb1, +0x41, 0xe9, 0xda, 0xa9, 0xe0, 0xcb, 0x8a, 0xdf, +0xc8, 0x87, 0xde, 0xc5, 0x85, 0xe6, 0xd1, 0xa2, +0x8d, 0xc1, 0x53, 0xe8, 0xd7, 0xa6, 0xdf, 0xc6, +0x86, 0xde, 0xc3, 0x84, 0xdd, 0xc1, 0x82, 0xe5, +0xcf, 0xa0, 0xb6, 0xe7, 0x7c, 0xe6, 0xd4, 0xa4, +0xdd, 0xc2, 0x83, 0xdc, 0xc0, 0x81, 0xdb, 0xbd, +0x7f, 0xe4, 0xcd, 0x9e, 0xb9, 0xeb, 0x7f, 0xeb, +0xdb, 0xb8, 0xe5, 0xce, 0xa0, 0xe3, 0xcc, 0x9e, +0xea, 0xd8, 0xb6, 0xba, 0xee, 0x82, 0x7c, 0xb4, +0x43, 0xbc, 0xf0, 0x84, 0x96, 0xcc, 0x5d, 0xeb, +0xe6, 0x9f, 0xeb, 0xe5, 0x9e, 0xef, 0xe9, 0xb4, +0xf2, 0xe8, 0xd6, 0xe0, 0xc7, 0x9a, 0xd0, 0xab, +0x68, 0xc5, 0x97, 0x44, 0xc7, 0xb4, 0xa5, 0xac, +0xa9, 0xd4, 0x8c, 0x90, 0xdc, 0x71, 0x75, 0xd4, +0xb2, 0xb5, 0xe8, 0xe0, 0xe1, 0xf6, 0xef, 0xea, +0xb5, 0xf2, 0xec, 0xc5, 0xe6, 0xd2, 0xae, 0xd1, +0xac, 0x6a, 0xa8, 0xbc, 0x2f, 0x98, 0xd9, 0x2b, +0x8d, 0xee, 0x27, 0xb7, 0xb1, 0xca, 0x85, 0x81, +0xbf, 0x96, 0x87, 0xa4, 0xc2, 0xb5, 0xb8, 0xf2, +0xf3, 0xfb, 0xd4, 0xd5, 0xf2, 0xa9, 0xac, 0xe5, +0x8e, 0x91, 0xdd, 0xc1, 0xc3, 0xec, 0xd2, 0xad, +0x6c, 0x9a, 0xd6, 0x2b, 0x88, 0xf6, 0x26, 0x7a, +0xbe, 0x6b, 0x8f, 0x92, 0xdd, 0xd0, 0xd1, 0xf1, +0xec, 0xdc, 0xc1, 0xf3, 0xed, 0xc6, 0xee, 0xe6, +0xb2, 0xed, 0xe4, 0xb0, 0xec, 0xe2, 0xaf, 0xf0, +0xe7, 0xc1, 0x81, 0xda, 0x49, 0xed, 0xe5, 0xb1, +0xe6, 0xd9, 0x95, 0xe5, 0xd6, 0x93, 0xe4, 0xd3, +0x90, 0xea, 0xdc, 0xaa, 0x77, 0xb0, 0x7c, 0xdc, +0xc0, 0x8e, 0xec, 0xe2, 0xae, 0xe4, 0xd5, 0x91, +0xe3, 0xd2, 0x8f, 0xe2, 0xce, 0x8c, 0xe9, 0xd8, +0xa7, 0xed, 0xdf, 0xc6, 0xe2, 0xd0, 0x8d, 0xe1, +0xcd, 0x8b, 0xe0, 0xca, 0x89, 0xe7, 0xd5, 0xa5, +0xfa, 0xf6, 0xee, 0xef, 0xe3, 0xbe, 0xe8, 0xd8, +0xa7, 0xe7, 0xd6, 0xa5, 0xec, 0xdd, 0xb9, 0xec, +0xde, 0xba, 0xe5, 0xd0, 0xa1, 0xe4, 0xce, 0x9f, +0xeb, 0xd9, 0xb6, 0xdc, 0xbe, 0x80, 0xdb, 0xbc, +0x7e, 0xda, 0xbb, 0x7d, 0xe3, 0xcb, 0x9e, 0xda, +0xbb, 0x7e, 0xda, 0xba, 0x7d, 0x36, 0x98, 0x2a, +0xe2, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x02, 0x65, 0x49, +0x44, 0x41, 0x54, 0x48, 0xc7, 0x63, 0x60, 0x20, +0x1b, 0x30, 0x32, 0x81, 0x00, 0x23, 0x29, 0x5a, +0x98, 0x98, 0x59, 0x58, 0xd9, 0xd8, 0x99, 0x48, +0xd2, 0xc2, 0xc1, 0xc9, 0xc5, 0xcd, 0x43, 0x9a, +0x16, 0xd2, 0x6d, 0xe1, 0x05, 0xfb, 0x85, 0x97, +0x14, 0x2d, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, +0x7c, 0x24, 0x69, 0x11, 0x11, 0x15, 0x13, 0x97, +0x18, 0x8c, 0x5a, 0x60, 0x7e, 0x91, 0x94, 0x94, +0x64, 0x90, 0x64, 0x00, 0x21, 0x42, 0x40, 0x8a, +0x0f, 0x04, 0xa4, 0x40, 0x6a, 0x89, 0xd5, 0x42, +0x86, 0x2d, 0x70, 0xbf, 0x80, 0x6d, 0x01, 0x23, +0x58, 0xba, 0xc3, 0x95, 0xfa, 0xb0, 0x79, 0x9f, +0x89, 0x59, 0x5a, 0x46, 0x56, 0x8e, 0x49, 0x5e, +0x41, 0x51, 0x49, 0x99, 0x09, 0x9f, 0x16, 0x15, +0x55, 0x55, 0x35, 0x75, 0x88, 0x16, 0x0e, 0x0d, +0x4d, 0x2d, 0x6d, 0x26, 0x1d, 0x5d, 0x3d, 0x7d, +0x03, 0x6c, 0x5a, 0xe0, 0xb1, 0xaf, 0x6a, 0x68, +0x68, 0x04, 0xd1, 0x43, 0xc0, 0x16, 0x78, 0x88, +0x01, 0x6d, 0x31, 0x06, 0xea, 0x01, 0x89, 0x99, +0x80, 0x7d, 0x61, 0x8a, 0x2b, 0xf5, 0x21, 0xa7, +0x31, 0x15, 0x63, 0x43, 0x55, 0x10, 0x6d, 0x66, +0x6e, 0x61, 0x69, 0x65, 0x6d, 0x86, 0x2b, 0xf5, +0xa1, 0x78, 0x5f, 0xd5, 0x06, 0xa2, 0xc5, 0xc2, +0xd6, 0xce, 0xde, 0xc1, 0x0c, 0x57, 0xba, 0x40, +0xd5, 0xe2, 0x08, 0xd1, 0xe2, 0xe4, 0xec, 0xe2, +0xea, 0x46, 0xa4, 0x16, 0x77, 0x88, 0x16, 0x0f, +0x4f, 0x2f, 0x6f, 0x1f, 0xdc, 0x5a, 0x90, 0x5d, +0xec, 0xeb, 0xe7, 0xaf, 0x02, 0xd2, 0x12, 0xe0, +0x16, 0x18, 0x14, 0x8c, 0xd3, 0x2f, 0x88, 0x10, +0x03, 0x82, 0x10, 0xff, 0xd0, 0x30, 0xa0, 0x9e, +0x70, 0x33, 0x10, 0x88, 0x40, 0x96, 0xc1, 0x0d, +0x54, 0xc2, 0x22, 0x81, 0x4e, 0x33, 0x8b, 0x8a, +0x8e, 0x89, 0x8d, 0x33, 0x23, 0x2a, 0xbf, 0x86, +0x84, 0x45, 0xc6, 0x03, 0x6d, 0x31, 0x4b, 0x48, +0x4c, 0x4a, 0x4e, 0xc1, 0xe9, 0x17, 0x94, 0xc4, +0xe7, 0x9b, 0x1a, 0x0f, 0xf6, 0x4b, 0x5a, 0x7a, +0x46, 0x66, 0x16, 0x4e, 0x2d, 0x28, 0x85, 0x92, +0x6a, 0x36, 0x24, 0xc4, 0x72, 0x72, 0xf3, 0xf2, +0x0b, 0x70, 0x6b, 0x41, 0x2e, 0xfa, 0x54, 0x0b, +0x21, 0x5a, 0x8a, 0x8a, 0x0b, 0x4a, 0x4a, 0x71, +0xfa, 0x05, 0xd5, 0x96, 0x32, 0xb0, 0x16, 0x02, +0x21, 0x06, 0x49, 0x82, 0x26, 0x90, 0xf0, 0x2a, +0xaf, 0x50, 0x25, 0x14, 0xa6, 0x0c, 0xe0, 0x24, +0x68, 0x61, 0x61, 0x6e, 0x06, 0xd2, 0xa0, 0x5a, +0x5e, 0x51, 0xa9, 0x46, 0x8c, 0x16, 0x8b, 0xaa, +0xaa, 0x2a, 0x0b, 0x33, 0xb0, 0xab, 0x80, 0x3a, +0xd4, 0x89, 0xd5, 0x62, 0x09, 0xb1, 0x45, 0x95, +0x28, 0x1d, 0x20, 0x2d, 0xd5, 0xb6, 0x35, 0x66, +0x48, 0x22, 0xb5, 0x75, 0xf5, 0x0d, 0x0d, 0xf5, +0x8d, 0x4d, 0xcd, 0x2d, 0x2d, 0xcd, 0xad, 0x6d, +0x58, 0xfd, 0x62, 0xd5, 0xee, 0xd1, 0x81, 0xa4, +0xa5, 0xb3, 0xab, 0xbb, 0xa7, 0xb7, 0xb7, 0xaf, +0x7f, 0xc2, 0xc4, 0x49, 0x93, 0x26, 0x4f, 0x99, +0x3a, 0x0d, 0x53, 0x0b, 0x24, 0x40, 0xc3, 0x11, +0x3a, 0xa6, 0xcf, 0x98, 0x39, 0x73, 0xe6, 0xac, +0xd9, 0x73, 0xe6, 0x4e, 0xef, 0x04, 0x72, 0xe7, +0xcc, 0xc6, 0xd4, 0x63, 0x36, 0x6f, 0xfe, 0x82, +0x85, 0x8b, 0xe0, 0xb6, 0xd4, 0x76, 0x81, 0x74, +0x2c, 0x9e, 0x3a, 0x87, 0x81, 0x61, 0x6e, 0x57, +0x2d, 0x48, 0xcf, 0x54, 0x0c, 0xb7, 0x99, 0x2d, +0x59, 0xba, 0x6c, 0xf9, 0x0a, 0xb8, 0x96, 0xba, +0x6e, 0xa0, 0x8e, 0x99, 0x2b, 0xa7, 0x80, 0xd8, +0xab, 0xea, 0x40, 0xe4, 0x94, 0x56, 0x0c, 0x2d, +0xab, 0xd7, 0xac, 0x5d, 0xb7, 0x1e, 0xae, 0xa5, +0xbe, 0x07, 0xa4, 0xa5, 0x79, 0x32, 0x88, 0xbd, +0xa1, 0x1e, 0x44, 0x4e, 0x6e, 0xc6, 0xd0, 0x12, +0xb4, 0x71, 0xd3, 0xe6, 0x2d, 0x70, 0x2d, 0x0d, +0xbd, 0x20, 0x2d, 0x2d, 0x93, 0x40, 0xec, 0xad, +0x0d, 0x20, 0x72, 0x52, 0x0b, 0x86, 0x96, 0x6d, +0xdb, 0x77, 0xe4, 0xec, 0x24, 0x49, 0x0b, 0x5a, +0x88, 0x11, 0xe5, 0xb0, 0x5d, 0x29, 0xbb, 0xf7, +0xec, 0x25, 0xcd, 0xfb, 0xbb, 0xf7, 0xed, 0x3f, +0x70, 0x90, 0xb4, 0x40, 0xde, 0x73, 0xe8, 0xf0, +0x61, 0x84, 0x16, 0xa2, 0xa2, 0xf2, 0xe0, 0x61, +0x14, 0x2d, 0x44, 0x24, 0x18, 0xb3, 0xd2, 0x83, +0x07, 0x0f, 0x96, 0x92, 0x94, 0x2c, 0xd1, 0xd3, +0x18, 0x75, 0x01, 0x00, 0x16, 0x1b, 0xe3, 0xbc, +0x97, 0x09, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_hash_setop_except_all_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_hash_setop_except_all_png = new wxImage(); + if (!img_ex_hash_setop_except_all_png || !img_ex_hash_setop_except_all_png->IsOk()) + { + wxMemoryInputStream img_ex_hash_setop_except_all_pngIS(ex_hash_setop_except_all_png_data, sizeof(ex_hash_setop_except_all_png_data)); + img_ex_hash_setop_except_all_png->LoadFile(img_ex_hash_setop_except_all_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_hash_setop_except_all_png; +} +#define ex_hash_setop_except_all_png_img ex_hash_setop_except_all_png_img() + +static wxBitmap *ex_hash_setop_except_all_png_bmp() +{ + static wxBitmap *bmp_ex_hash_setop_except_all_png; + if (!bmp_ex_hash_setop_except_all_png || !bmp_ex_hash_setop_except_all_png->IsOk()) + bmp_ex_hash_setop_except_all_png = new wxBitmap(*ex_hash_setop_except_all_png_img); + return bmp_ex_hash_setop_except_all_png; +} +#define ex_hash_setop_except_all_png_bmp ex_hash_setop_except_all_png_bmp() + +static wxIcon *ex_hash_setop_except_all_png_ico() +{ + static wxIcon *ico_ex_hash_setop_except_all_png; + if (!ico_ex_hash_setop_except_all_png || !ico_ex_hash_setop_except_all_png->IsOk()) + { + ico_ex_hash_setop_except_all_png = new wxIcon(); + ico_ex_hash_setop_except_all_png->CopyFromBitmap(*ex_hash_setop_except_all_png_bmp); + } + return ico_ex_hash_setop_except_all_png; +} +#define ex_hash_setop_except_all_png_ico ex_hash_setop_except_all_png_ico() + +#endif // EX_HASH_SETOP_EXCEPT_ALL_PNG_H diff --git a/include/images/ex_hash_setop_intersect.png b/include/images/ex_hash_setop_intersect.png new file mode 100644 index 0000000000000000000000000000000000000000..fb536b11b68fca6c2feda14a8011003678204d62 GIT binary patch literal 1389 zcmV-z1(N!SP)9z`^du$M4O~ z^4{L|yuIwJtmw0}>b$+})YS8(sN_Yy=}f@sQ^M+n)bNzp@OsYdgVF7a)b6d{^O?MO zQjHmqwrtqt%Ll095Ub)EuH#+B>v7BMPQK<^!RKVf=#tg%p~PN$dan$D+qz>g1j3n(pSaq{?IO>bB|Oo9N$}=iQg=Uu0GqniM5%2 zwBvd3=D_LPs_ELO=+~$1-@AITLFwA5;LD2N$cNs=h33(sjloms*QVdbhTg-3-NAz8 z&!D#FeCE`o-NJ+1z=7Mnf8@=cx$A%H+qmVe#lr?t*-@L%i^Wmdsu2=AY~3 zp6}_j^61v!$C}WqXvLRA$F!xasnm>++;Mf(vbE^o;r8$9wesx6=F+awtZLlAj_u#Z z`u6U(vC4OVr-z4&!nL^a^ZV4*@~N!lj*;EL!|c+nZ0y{@kCNSe%Uhb(E6~yL^Xk>j;?9ie*r$Ha zR+!l<;?RxZ&5Pj5iRaa&h3hnp?kDf#zUbJe=hmg{-MQ@Ey5-QJnikS+;RXAJmlQ30 z`~reP!h9rY5fK#=ml%v%NcW2*9|%YeK!`!p9j?@eO$!sVl(dX2lbpPQq7oB6Ey^k? zs%j7|9O@dHT1?tHx_bK9w7~tMVqjnh(L=x%M2IP?7yJ1{WI;kKJ0~|UAGa3dqEDp&qNT7XzqkaaUr=o+ z1#2M?VvrtTZN}KoH}FXtZ5xU#_SoGdQ9icoi~30+?JY7kdD?VGZ!wL)ma15GX=wKri&IY zS-K3arM3%1wk%%=1S@Jm?8z+{T2`)Fy=E<3OIvc3+)p45b)C2+&WO`G9b z>U%(B^A?bnt@R-G#AXaF+qUn>-bs=cv=Af8VY`xd@7YV5_jm8xf8Zc#fxPF?;ll_m zL`CJn!zfx{3FgRAoC(IXIsOk()) + { + wxMemoryInputStream img_ex_hash_setop_intersect_pngIS(ex_hash_setop_intersect_png_data, sizeof(ex_hash_setop_intersect_png_data)); + img_ex_hash_setop_intersect_png->LoadFile(img_ex_hash_setop_intersect_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_hash_setop_intersect_png; +} +#define ex_hash_setop_intersect_png_img ex_hash_setop_intersect_png_img() + +static wxBitmap *ex_hash_setop_intersect_png_bmp() +{ + static wxBitmap *bmp_ex_hash_setop_intersect_png; + if (!bmp_ex_hash_setop_intersect_png || !bmp_ex_hash_setop_intersect_png->IsOk()) + bmp_ex_hash_setop_intersect_png = new wxBitmap(*ex_hash_setop_intersect_png_img); + return bmp_ex_hash_setop_intersect_png; +} +#define ex_hash_setop_intersect_png_bmp ex_hash_setop_intersect_png_bmp() + +static wxIcon *ex_hash_setop_intersect_png_ico() +{ + static wxIcon *ico_ex_hash_setop_intersect_png; + if (!ico_ex_hash_setop_intersect_png || !ico_ex_hash_setop_intersect_png->IsOk()) + { + ico_ex_hash_setop_intersect_png = new wxIcon(); + ico_ex_hash_setop_intersect_png->CopyFromBitmap(*ex_hash_setop_intersect_png_bmp); + } + return ico_ex_hash_setop_intersect_png; +} +#define ex_hash_setop_intersect_png_ico ex_hash_setop_intersect_png_ico() + +#endif // EX_HASH_SETOP_INTERSECT_PNG_H diff --git a/include/images/ex_hash_setop_intersect_all.png b/include/images/ex_hash_setop_intersect_all.png new file mode 100644 index 0000000000000000000000000000000000000000..0018157f64a5ae601a2db08fb1e4a553385c33b9 GIT binary patch literal 1417 zcmV;41$O$0P)9z`^du$M4O~ z^4{L|yuIwJtmw0}>b$+})YS6;005<^<8@RZo_dd}>F(d~=W?ycYR znY?&XjTw-(Y}nDs91*Qf2@yLz!f>DsB_%ZlH~hu+17=Fy^!!Bgnhrr*Yf-ou35 z!Gh(_ptk3H=G3I!!h_tvf!n=*woLpxaH2Eokq-C-39F=-8*{)}`#-x$NG$<rtAevy=vWRPS4Awock4+Nw@YKhfChAnWvfNcRISh~ZN z`mlMQiCJ1kR*p$tK~YJW37-}fRaG^0h!zeFO)YIE9bG+r18iF0v9D@qXavziz!rFj z0c|k`>H&$FfPG<#EA=6#F%@G&RS<1vZeeLPDm%cZe1bPcLsD+**)b?Ca;R0@4!T78n$a(=Uh+1A-9$&@iB$a5E5yK$gJ` zRKg;GPBV*&j){#kBPzd!ghj>!Z81woOiE6{=@*p5=bIW2_DfoNMrIaHEhvSOYBnUq za&q(X3vg>eF8WjpAzF%x3rb3H`UTaNGO!i`AqGi;CXnzduTUivrVQXDXklS)2GXEf zUQww=j24TkswxXJu&aPN)QQz%39&_$C>!*pr(vv;=M3w0R3$OG7V+Y}pFZvaJEcp45V&W&4huIlD;Gf)-*# zIc#^zp1u39dcPZ&_xJ2SaPSamfxP$dks}B#L`CJHBPd#63FhcAoC(IP^w6P0r6eUw z^fX3Y000U{;7!~3Lt6j<03~!qSaf7zbY(hYa%Ew3WdJfTF)%GLGA%GMR5CC+G&4Fh zG%GMQIxsLenI#?o001R)MObuXVRU6WZEs|0W_bWIFflMKFgYzSF;p@$Iy5voFg7bN XH99ab%9mBF00000NkvXXu0mjfCZzUl literal 0 HcmV?d00001 diff --git a/include/images/ex_hash_setop_intersect_all.pngc b/include/images/ex_hash_setop_intersect_all.pngc new file mode 100644 index 0000000..c16fb98 --- /dev/null +++ b/include/images/ex_hash_setop_intersect_all.pngc @@ -0,0 +1,222 @@ +#ifndef EX_HASH_SETOP_INTERSECT_ALL_PNG_H +#define EX_HASH_SETOP_INTERSECT_ALL_PNG_H + +static const unsigned char ex_hash_setop_intersect_all_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x02, 0x55, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x89, 0xb9, 0xdb, 0x36, +0x88, 0xc1, 0x6f, 0xcd, 0xee, 0x4d, 0xc0, 0xe9, +0x61, 0xc6, 0xeb, 0x76, 0xcd, 0xec, 0xa6, 0xde, +0xf2, 0x40, 0xbc, 0xe9, 0x12, 0xab, 0xe2, 0x2c, +0xb3, 0xe4, 0x48, 0xbc, 0xe6, 0x89, 0xd3, 0xee, +0x64, 0x95, 0xd0, 0x66, 0x6b, 0xd1, 0xcc, 0xcd, +0xf1, 0xc0, 0xc1, 0xee, 0xc6, 0xc7, 0xef, 0xcd, +0xce, 0xf2, 0xde, 0xde, 0xf6, 0xbc, 0xbd, 0xec, +0xab, 0xac, 0xe8, 0xb3, 0xb4, 0xea, 0xbc, 0xbd, +0xed, 0xd4, 0xd4, 0xf3, 0x00, 0x00, 0x00, 0xa5, +0xa8, 0xe4, 0x45, 0xbe, 0xe9, 0x4c, 0xc0, 0xe9, +0x53, 0xc2, 0xea, 0x85, 0xd4, 0xf0, 0x94, 0xd8, +0xf0, 0x7a, 0xce, 0xec, 0x83, 0xd1, 0xed, 0x8b, +0xd4, 0xee, 0xad, 0xdf, 0xf3, 0x99, 0xbc, 0x78, +0x52, 0x8d, 0x19, 0x90, 0xb6, 0x6c, 0xd8, 0xe5, +0xcb, 0x07, 0xa8, 0xe2, 0x10, 0xab, 0xe2, 0x1a, +0xae, 0xe3, 0x5d, 0xc5, 0xeb, 0x71, 0xcb, 0xec, +0x4e, 0xbe, 0xe6, 0x5a, 0xc1, 0xe7, 0x64, 0xc5, +0xe8, 0x92, 0xd5, 0xef, 0xa1, 0xc4, 0x5e, 0x84, +0xb0, 0x45, 0x72, 0xa3, 0x35, 0x7a, 0x9e, 0xa9, +0x6a, 0x8f, 0xa6, 0xc1, 0x8f, 0x36, 0xf4, 0xf1, +0xc9, 0xf0, 0xec, 0xb7, 0xf0, 0xec, 0xb6, 0xef, +0xeb, 0xb6, 0xf3, 0xef, 0xc7, 0xa2, 0xc7, 0x60, +0xea, 0xe4, 0x9d, 0xea, 0xe3, 0x9c, 0xe9, 0xe0, +0x9a, 0xee, 0xe6, 0xb3, 0xa4, 0xca, 0x63, 0xef, +0xea, 0xb6, 0xe9, 0xe1, 0x9b, 0xe8, 0xdf, 0x99, +0xe7, 0xdd, 0x97, 0xec, 0xe3, 0xb0, 0xa7, 0xcd, +0x66, 0xef, 0xe8, 0xb3, 0xe8, 0xde, 0x98, 0xe7, +0xdb, 0x96, 0xe6, 0xd8, 0x94, 0xec, 0xe0, 0xad, +0x97, 0xbb, 0x75, 0x86, 0xb6, 0x49, 0x76, 0xaa, +0x3b, 0xf1, 0xeb, 0xc4, 0xec, 0xe0, 0xae, 0xeb, +0xde, 0xac, 0xef, 0xe4, 0xbf, 0xba, 0xd1, 0xa3, +0xae, 0xda, 0x71, 0x78, 0xae, 0x3e, 0xdb, 0xbd, +0x89, 0xb5, 0x99, 0x7e, 0xb4, 0xe3, 0x79, 0xf0, +0xe6, 0xc0, 0xe9, 0xdc, 0xaa, 0xe9, 0xda, 0xa8, +0xe8, 0xd7, 0xa7, 0xed, 0xdf, 0xbb, 0x7a, 0xb1, +0x41, 0xe9, 0xda, 0xa9, 0xe0, 0xcb, 0x8a, 0xdf, +0xc8, 0x87, 0xde, 0xc5, 0x85, 0xe6, 0xd1, 0xa2, +0x8d, 0xc1, 0x53, 0xe8, 0xd7, 0xa6, 0xdf, 0xc6, +0x86, 0xde, 0xc3, 0x84, 0xdd, 0xc1, 0x82, 0xe5, +0xcf, 0xa0, 0xb6, 0xe7, 0x7c, 0xe6, 0xd4, 0xa4, +0xdd, 0xc2, 0x83, 0xdc, 0xc0, 0x81, 0xdb, 0xbd, +0x7f, 0xe4, 0xcd, 0x9e, 0xb9, 0xeb, 0x7f, 0xeb, +0xdb, 0xb8, 0xe5, 0xce, 0xa0, 0xe3, 0xcc, 0x9e, +0xea, 0xd8, 0xb6, 0xba, 0xee, 0x82, 0x7c, 0xb4, +0x43, 0xbc, 0xf0, 0x84, 0x96, 0xcc, 0x5d, 0xeb, +0xe6, 0x9f, 0xeb, 0xe5, 0x9e, 0xef, 0xe9, 0xb4, +0xf2, 0xe8, 0xd6, 0xe0, 0xc7, 0x9a, 0xd0, 0xab, +0x68, 0xc5, 0x97, 0x44, 0xc7, 0xb4, 0xa5, 0xac, +0xa9, 0xd4, 0x8c, 0x90, 0xdc, 0x71, 0x75, 0xd4, +0xb2, 0xb5, 0xe8, 0xe0, 0xe1, 0xf6, 0xef, 0xea, +0xb5, 0xf2, 0xec, 0xc5, 0xe6, 0xd2, 0xae, 0xd1, +0xac, 0x6a, 0xdc, 0xc0, 0x8e, 0xed, 0xdf, 0xc6, +0xfa, 0xf6, 0xee, 0xb7, 0xb1, 0xca, 0x77, 0x80, +0xa7, 0x87, 0x87, 0x8b, 0xc2, 0xb5, 0xb8, 0xf2, +0xf3, 0xfb, 0xd4, 0xd5, 0xf2, 0xa9, 0xac, 0xe5, +0x8e, 0x91, 0xdd, 0xc1, 0xc3, 0xec, 0xd2, 0xad, +0x6c, 0xec, 0xdc, 0xc1, 0x8f, 0x92, 0xdd, 0x7d, +0xcb, 0x5b, 0x9a, 0xd6, 0x2b, 0xd0, 0xd1, 0xf1, +0xf3, 0xed, 0xc6, 0xee, 0xe6, 0xb2, 0xed, 0xe4, +0xb0, 0xec, 0xe2, 0xaf, 0xf0, 0xe7, 0xc1, 0x88, +0xf6, 0x26, 0xed, 0xe5, 0xb1, 0xe6, 0xd9, 0x95, +0xe5, 0xd6, 0x93, 0xe4, 0xd3, 0x90, 0xea, 0xdc, +0xaa, 0x75, 0xa8, 0x86, 0xa8, 0xbc, 0x2f, 0xec, +0xe2, 0xae, 0xe4, 0xd5, 0x91, 0xe3, 0xd2, 0x8f, +0xe2, 0xce, 0x8c, 0xe9, 0xd8, 0xa7, 0x7e, 0xcf, +0x56, 0x98, 0xd9, 0x2b, 0xe2, 0xd0, 0x8d, 0xe1, +0xcd, 0x8b, 0xe0, 0xca, 0x89, 0xe7, 0xd5, 0xa5, +0x85, 0xeb, 0x34, 0x8d, 0xee, 0x27, 0xef, 0xe3, +0xbe, 0xe8, 0xd8, 0xa7, 0xe7, 0xd6, 0xa5, 0xec, +0xdd, 0xb9, 0xec, 0xde, 0xba, 0xe5, 0xd0, 0xa1, +0xe4, 0xce, 0x9f, 0xeb, 0xd9, 0xb6, 0xdc, 0xbe, +0x80, 0xdb, 0xbc, 0x7e, 0xda, 0xbb, 0x7d, 0xe3, +0xcb, 0x9e, 0xda, 0xbb, 0x7e, 0xda, 0xba, 0x7d, +0x85, 0x81, 0xbf, 0x96, 0x87, 0xa4, 0x03, 0x64, +0x9e, 0xf9, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x02, 0x6b, +0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0x63, 0x60, +0x20, 0x1b, 0x30, 0x32, 0x81, 0x00, 0x23, 0x29, +0x5a, 0x98, 0x98, 0x59, 0x58, 0xd9, 0xd8, 0x99, +0x48, 0xd2, 0xc2, 0xc1, 0xc9, 0xc5, 0xcd, 0x43, +0x9a, 0x16, 0xd2, 0x6d, 0xe1, 0x05, 0xfb, 0x85, +0x97, 0x14, 0x2d, 0x7c, 0xfc, 0x02, 0x82, 0x42, +0xc2, 0x7c, 0x24, 0x69, 0x11, 0x11, 0x15, 0x13, +0x97, 0x18, 0x8c, 0x5a, 0x60, 0x7e, 0x91, 0x94, +0x94, 0x64, 0x90, 0x64, 0x00, 0x21, 0x42, 0x40, +0x8a, 0x0f, 0x04, 0xa4, 0x40, 0x6a, 0x89, 0xd5, +0x42, 0x86, 0x2d, 0x70, 0xbf, 0x80, 0x6d, 0x01, +0x23, 0x58, 0xba, 0xc3, 0x95, 0xfa, 0xb0, 0x79, +0x9f, 0x89, 0x59, 0x5a, 0x46, 0x56, 0x8e, 0x49, +0x5e, 0x41, 0x51, 0x49, 0x99, 0x09, 0x9f, 0x16, +0x15, 0x55, 0x55, 0x35, 0x75, 0x88, 0x16, 0x0e, +0x0d, 0x4d, 0x2d, 0x6d, 0x26, 0x1d, 0x5d, 0x3d, +0x7d, 0x03, 0x6c, 0x5a, 0xe0, 0xb1, 0xaf, 0x6a, +0x68, 0x68, 0x04, 0xd1, 0x43, 0xc0, 0x16, 0x78, +0x88, 0x01, 0x6d, 0x31, 0x06, 0xea, 0x01, 0x89, +0x99, 0x80, 0x7d, 0x61, 0x8a, 0x2b, 0xf5, 0x21, +0xa7, 0x31, 0x15, 0x63, 0x43, 0x55, 0x10, 0x6d, +0x66, 0x6e, 0x61, 0x69, 0x65, 0x6d, 0x86, 0x2b, +0xf5, 0xa1, 0x78, 0x5f, 0xd5, 0x06, 0xa2, 0xc5, +0xc2, 0xd6, 0xce, 0xde, 0xc1, 0x0c, 0x57, 0xba, +0x40, 0xd5, 0xe2, 0x08, 0xd1, 0xe2, 0xe4, 0xec, +0xe2, 0xea, 0x46, 0xa4, 0x16, 0x77, 0x88, 0x16, +0x0f, 0x4f, 0x2f, 0x6f, 0x1f, 0xdc, 0x5a, 0x90, +0x5d, 0xec, 0xeb, 0xe7, 0xaf, 0x02, 0xd2, 0x12, +0xe0, 0x16, 0x18, 0x14, 0x8c, 0xd3, 0x2f, 0x88, +0x10, 0x03, 0x82, 0x10, 0xff, 0xd0, 0x30, 0xa0, +0x9e, 0x70, 0x33, 0x10, 0x88, 0x40, 0x96, 0xc1, +0x0d, 0x54, 0xc2, 0x22, 0x81, 0x4e, 0x33, 0x8b, +0x8a, 0x8e, 0x89, 0x8d, 0x33, 0x23, 0x2a, 0xbf, +0x86, 0x84, 0x45, 0xc6, 0x03, 0x6d, 0x31, 0x4b, +0x48, 0x4c, 0x4a, 0x4e, 0xc1, 0xe9, 0x17, 0x94, +0xc4, 0xe7, 0x9b, 0x1a, 0x0f, 0xf6, 0x4b, 0x5a, +0x7a, 0x46, 0x66, 0x16, 0x4e, 0x2d, 0x28, 0x85, +0x92, 0x6a, 0x36, 0x24, 0xc4, 0x72, 0x72, 0xf3, +0xf2, 0x0b, 0x70, 0x6b, 0x41, 0x2e, 0xfa, 0x54, +0x0b, 0x21, 0x5a, 0x8a, 0x8a, 0x0b, 0x4a, 0x4a, +0x71, 0xfa, 0x05, 0xd5, 0x96, 0x32, 0xb0, 0x16, +0x02, 0x21, 0x06, 0x49, 0x82, 0x26, 0x90, 0xf0, +0x2a, 0xaf, 0x50, 0x25, 0x14, 0xa6, 0x0c, 0xe0, +0x24, 0x68, 0x61, 0x61, 0x6e, 0x06, 0xd2, 0xa0, +0x5a, 0x5e, 0x51, 0xa9, 0x46, 0x8c, 0x16, 0x8b, +0xaa, 0xaa, 0x2a, 0x0b, 0x33, 0xb0, 0xab, 0x80, +0x3a, 0xd4, 0x89, 0xd5, 0x62, 0x09, 0xb1, 0x45, +0x95, 0x28, 0x1d, 0x20, 0x2d, 0xd5, 0xb6, 0x35, +0x66, 0x48, 0x22, 0xb5, 0x75, 0xf5, 0x0d, 0x0d, +0xf5, 0x8d, 0x4d, 0xcd, 0x2d, 0x2d, 0xcd, 0xad, +0x6d, 0x58, 0xfd, 0x62, 0xd5, 0xee, 0xd1, 0x81, +0xa4, 0xa5, 0xb3, 0xab, 0xbb, 0xa7, 0xb7, 0xb7, +0xaf, 0x7f, 0xc2, 0xc4, 0x49, 0x93, 0x26, 0x4f, +0x99, 0x3a, 0x0d, 0x53, 0x0b, 0x24, 0x40, 0xc3, +0x11, 0x3a, 0xa6, 0xcf, 0x00, 0x92, 0xd3, 0x66, +0xce, 0x9a, 0x3d, 0xbd, 0x13, 0xc8, 0x98, 0x33, +0x13, 0x53, 0x8f, 0xd9, 0xdc, 0x79, 0xf3, 0x17, +0x2c, 0x84, 0xdb, 0x52, 0xdb, 0x05, 0xd2, 0xd1, +0x36, 0x75, 0xd6, 0xa2, 0x45, 0xb3, 0xbb, 0x6a, +0x41, 0x7a, 0xa6, 0x62, 0xb8, 0xcd, 0x6c, 0xf1, +0x92, 0xa5, 0xcb, 0x96, 0xc3, 0xb5, 0xd4, 0x75, +0x83, 0xc8, 0xd6, 0x15, 0x8b, 0x80, 0x60, 0x65, +0x1d, 0x88, 0x3d, 0xa5, 0x15, 0x43, 0xcb, 0xaa, +0xd5, 0x6b, 0xd6, 0xae, 0x83, 0x6b, 0xa9, 0xef, +0x01, 0x91, 0xcd, 0xeb, 0x41, 0x5a, 0x36, 0xd4, +0x83, 0xd8, 0x93, 0x9b, 0x31, 0xb4, 0x04, 0x6d, +0xdc, 0xb4, 0x79, 0x0b, 0x5c, 0x4b, 0x43, 0x2f, +0x88, 0x6c, 0xd9, 0x0a, 0xd2, 0xb2, 0xad, 0x01, +0xc4, 0x9e, 0xd4, 0x82, 0xa1, 0x65, 0xfb, 0x8e, +0x9d, 0x39, 0xbb, 0x48, 0xd2, 0x82, 0x16, 0x62, +0x44, 0x39, 0x6c, 0x77, 0xca, 0x9e, 0xbd, 0xfb, +0xb0, 0x7a, 0xbf, 0x1b, 0x97, 0xf7, 0xf7, 0xec, +0x3f, 0x70, 0xf0, 0x10, 0x69, 0x81, 0xbc, 0xf7, +0xf0, 0x91, 0x23, 0x08, 0x2d, 0x44, 0x45, 0xe5, +0xa1, 0x23, 0x28, 0x5a, 0x60, 0x09, 0xe6, 0xe8, +0x31, 0x9c, 0x09, 0xc6, 0xac, 0xf4, 0xd0, 0xa1, +0x43, 0xa5, 0x24, 0x25, 0x4b, 0xf4, 0x34, 0x46, +0x5d, 0x00, 0x00, 0x0a, 0x47, 0xe0, 0x4d, 0xdb, +0xf8, 0x43, 0x5b, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_hash_setop_intersect_all_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_hash_setop_intersect_all_png = new wxImage(); + if (!img_ex_hash_setop_intersect_all_png || !img_ex_hash_setop_intersect_all_png->IsOk()) + { + wxMemoryInputStream img_ex_hash_setop_intersect_all_pngIS(ex_hash_setop_intersect_all_png_data, sizeof(ex_hash_setop_intersect_all_png_data)); + img_ex_hash_setop_intersect_all_png->LoadFile(img_ex_hash_setop_intersect_all_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_hash_setop_intersect_all_png; +} +#define ex_hash_setop_intersect_all_png_img ex_hash_setop_intersect_all_png_img() + +static wxBitmap *ex_hash_setop_intersect_all_png_bmp() +{ + static wxBitmap *bmp_ex_hash_setop_intersect_all_png; + if (!bmp_ex_hash_setop_intersect_all_png || !bmp_ex_hash_setop_intersect_all_png->IsOk()) + bmp_ex_hash_setop_intersect_all_png = new wxBitmap(*ex_hash_setop_intersect_all_png_img); + return bmp_ex_hash_setop_intersect_all_png; +} +#define ex_hash_setop_intersect_all_png_bmp ex_hash_setop_intersect_all_png_bmp() + +static wxIcon *ex_hash_setop_intersect_all_png_ico() +{ + static wxIcon *ico_ex_hash_setop_intersect_all_png; + if (!ico_ex_hash_setop_intersect_all_png || !ico_ex_hash_setop_intersect_all_png->IsOk()) + { + ico_ex_hash_setop_intersect_all_png = new wxIcon(); + ico_ex_hash_setop_intersect_all_png->CopyFromBitmap(*ex_hash_setop_intersect_all_png_bmp); + } + return ico_ex_hash_setop_intersect_all_png; +} +#define ex_hash_setop_intersect_all_png_ico ex_hash_setop_intersect_all_png_ico() + +#endif // EX_HASH_SETOP_INTERSECT_ALL_PNG_H diff --git a/include/images/ex_hash_setop_unknown.png b/include/images/ex_hash_setop_unknown.png new file mode 100644 index 0000000000000000000000000000000000000000..3a78fa6a1d35d8b2666ee3ffa5583db9662a67e4 GIT binary patch literal 1490 zcmV;@1ugoCP)9z`^du$M4O~ z^4{L|yuIwJtmw0}>b$+})YS8(sN_Yy=}f@sQ^M+n)bNzp@OsYdgVF7a)b6d{^O?MO zQjHmqwrtqt%Ll095Ub)EuH#+B>v7BMPQK<^!RKVf=#tg%p~PN$dan$D+qz>g1j3n(pSaq{?IO>bB|Oo9N$}=iQg=Uu0GqniM5%2 zwBvd3=D_LPs_ELO=+~$1-@AITLFwA5;LD2N$cNs=h33(sjloms*QVdbhTg-3-NAz8 z&!D#FeCE`o-NJ+1z=7Mnf8@=cx$A%H+qmVe#lr?t*-@L%i^Wmdsu2=AY~3 zp6}_j_U_>5)wA5djnuJo)yKTSzu&2=<&>D;#mDaG==ksIwesx6?A^lL!H?z8tMcd6 z`}p$9v%Rr~oVtpQ(zUVm_Wa-A^}oUFs;%YG((&EGk@4lw_t?(XP%76v4Bcit{POSI z-Sn%j=JV~w?&h-Xk>j;?9ie*r(rPJ=a7P;?RxZ&5Pj5iRaa&@3EfMdPDEyzUbJe z=hmg{-MRG3zUrWd?4*wR<=^byy5-QJ<<6Fx10|J9^ z`UNG81^b1B0`-KMfUvOwd9MBfi_=LoyWSo9MNqjyj zabUlsrln_O;?#mtD5+#YLM%HcH!mNz7UZH&r2wL(uqeN{1gBq6Z7Bt7ArNAaBxno? zud;F#LSf1PPJ-sEn9udJ*zHwC*2s6&ldEfx@4REW|6(o$tpZHgpP zQ(ISGU)Rvs)ZEIs?Ou znX`ak_8bO=x$`jfn9g6YaM5D8Ej67$9SlomEnT*J)~ppk=G-Y5ZZloEYW146a4of6 zAadP$28KBsX3YYzC%0f|*|=%*maT9tb=@GcX%djwHfuYGJ*f#pOW=;3yLQ91)c1hM z=7|gpduGkr3t~@f#?Z2F|AFj-7+MZ(n>FijJ$5Z*sQF-<} ziWX>sxio9mWn2lywB+pBvn3=YOY}5GT>tIsOk()) + { + wxMemoryInputStream img_ex_hash_setop_unknown_pngIS(ex_hash_setop_unknown_png_data, sizeof(ex_hash_setop_unknown_png_data)); + img_ex_hash_setop_unknown_png->LoadFile(img_ex_hash_setop_unknown_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_hash_setop_unknown_png; +} +#define ex_hash_setop_unknown_png_img ex_hash_setop_unknown_png_img() + +static wxBitmap *ex_hash_setop_unknown_png_bmp() +{ + static wxBitmap *bmp_ex_hash_setop_unknown_png; + if (!bmp_ex_hash_setop_unknown_png || !bmp_ex_hash_setop_unknown_png->IsOk()) + bmp_ex_hash_setop_unknown_png = new wxBitmap(*ex_hash_setop_unknown_png_img); + return bmp_ex_hash_setop_unknown_png; +} +#define ex_hash_setop_unknown_png_bmp ex_hash_setop_unknown_png_bmp() + +static wxIcon *ex_hash_setop_unknown_png_ico() +{ + static wxIcon *ico_ex_hash_setop_unknown_png; + if (!ico_ex_hash_setop_unknown_png || !ico_ex_hash_setop_unknown_png->IsOk()) + { + ico_ex_hash_setop_unknown_png = new wxIcon(); + ico_ex_hash_setop_unknown_png->CopyFromBitmap(*ex_hash_setop_unknown_png_bmp); + } + return ico_ex_hash_setop_unknown_png; +} +#define ex_hash_setop_unknown_png_ico ex_hash_setop_unknown_png_ico() + +#endif // EX_HASH_SETOP_UNKNOWN_PNG_H diff --git a/include/images/ex_index_only_scan.png b/include/images/ex_index_only_scan.png new file mode 100644 index 0000000000000000000000000000000000000000..7764b74f5e5e5af1a205b2ecee9ed184727e1fe0 GIT binary patch literal 498 zcmV4~}9VaDrk&F*&1?7h9crNQLey@{>X>89TD^V}-D-R=M0 zDZt3>xcgAhT-q` z!N@d;00001bW%=J06^y0W&i*H32;bRa{vGf6951U69E94oEQKA0Ut?3K~zY`?bO>2 zf-npQ;7O;V0?Nb_&J(=*s42VGTQwXf%l9@iclL zNdOXeuiySypCM4!;O@y&X{wSOIUXq~XQs-}6QvYS4hKrA@L4=0l~^f9_IpA^Zz9B` z$BhkkJMf8s@sL*VhLWpb4Q#i-2+rIQ+9-eP?noQ0lYBNH*ld8!i7ZVDly=E_-I=Ub z0iwNRxdislWu;A#vn&>!J9Z<@Ox#J(okv2`=*=e-1+Z!K=krEr8ku~;d=B=YX>j2X z3`^5Z>~y=h^w%!z!IsOk()) + { + wxMemoryInputStream img_ex_index_only_scan_pngIS(ex_index_only_scan_png_data, sizeof(ex_index_only_scan_png_data)); + img_ex_index_only_scan_png->LoadFile(img_ex_index_only_scan_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_index_only_scan_png; +} +#define ex_index_only_scan_png_img ex_index_only_scan_png_img() + +static wxBitmap *ex_index_only_scan_png_bmp() +{ + static wxBitmap *bmp_ex_index_only_scan_png; + if (!bmp_ex_index_only_scan_png || !bmp_ex_index_only_scan_png->IsOk()) + bmp_ex_index_only_scan_png = new wxBitmap(*ex_index_only_scan_png_img); + return bmp_ex_index_only_scan_png; +} +#define ex_index_only_scan_png_bmp ex_index_only_scan_png_bmp() + +static wxIcon *ex_index_only_scan_png_ico() +{ + static wxIcon *ico_ex_index_only_scan_png; + if (!ico_ex_index_only_scan_png || !ico_ex_index_only_scan_png->IsOk()) + { + ico_ex_index_only_scan_png = new wxIcon(); + ico_ex_index_only_scan_png->CopyFromBitmap(*ex_index_only_scan_png_bmp); + } + return ico_ex_index_only_scan_png; +} +#define ex_index_only_scan_png_ico ex_index_only_scan_png_ico() + +#endif // EX_INDEX_ONLY_SCAN_PNG_H diff --git a/include/images/ex_index_scan.png b/include/images/ex_index_scan.png new file mode 100644 index 0000000000000000000000000000000000000000..d44eff429fa9a3409776ea88a11421582f6f4598 GIT binary patch literal 1298 zcmV+t1?~EYP)~G5Jmf7)p&h3KH?WW%Hj@0gw*6*+3 z^985jO~L6KuH#$9>te_2IJf0czUOPl=ya2odY-AJ!Q^I^(ZP>4@#=@|<6!gf$nfm8 z@9DMj?Zxiqv+?W1?BlTT>B8af_vhLx>g1j3n(yed=-!#<+?Va;vF6#7<<^tz z;H}o__3YxW=GvC*;jZM>lI!2C?dG!U-mLKEz|`sV%c5A@y@~4Gs_*2!)9CZ$)RE)T zkK)jc>DsB$=kny!kmAma@8e(T+p6Kris{*?_Uni3;k?b|^7G_h=+~#{*QV{@yYAa6 z^V}-n$%)^{h~LMD=G3IiEp|u5BdaA00001bW%=J06^y0W&i*H32;bRa{vGUNB{r;NB~C3 zYd!z~0?A24K~zY`?UdPD5>Xh3ZKAN;Q_C#*KwubLStTT}1_fLIkws7h8A(MzWmN>> zU-!(C!g1n>o1QNGE)F-m&yV-_9Zp~0%lzwkMX>Y7Qw$+qOC*vv#9OIU+E4Vqdp|Hp z3=Rzsj}RlHV`Co(QA9F6K0ZNAOioUIBtA_|O$`u3pQX}aVsv_XV2tRNGV%8*U%21Q zpI@J!9p9ai$!5?8$Q25O9A=eD16kw|9SNjfucyFbG<8Q*i!8FN(;>v5|7N7XYFb^j zi6er`Z;S7og+&Wmv(4_nkhL`y`2pwZnpL3V^W1*wBNU4rq#&NWE@UBJES7PkQfWgTi$%L& zt_y`cl#1nYRUAoYSeFiqTrPhDH>GOz219Oddv1(Jgp@!yg?4elFxgYMER{+qrCO`q zwWpwmuU=;#Kf#5+9!!C=D6y*P&1N0_`voL*$X<^uSL_qg>P)FLo0X@O zINC)Pazz%YmdlMA+~Wvh&>fq3bh%)%n8jVI)w=6!OnAn7Y3ybGuXzBr6b33x=w6}# z001R)MObuXVRU6WV{&C-bY%cCFflMKF)}SMF;p@zIy5snG&CzPH99abIGH6L0000b zbVXQnWMOn=I&E)cX=ZrKSpWb4 literal 0 HcmV?d00001 diff --git a/include/images/ex_index_scan.pngc b/include/images/ex_index_scan.pngc new file mode 100644 index 0000000..5dcd538 --- /dev/null +++ b/include/images/ex_index_scan.pngc @@ -0,0 +1,207 @@ +#ifndef EX_INDEX_SCAN_PNG_H +#define EX_INDEX_SCAN_PNG_H + +static const unsigned char ex_index_scan_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x89, 0xb9, 0xdb, 0x36, +0x88, 0xc1, 0x6f, 0xcd, 0xee, 0x44, 0xbd, 0xe9, +0x75, 0xce, 0xef, 0x79, 0xd0, 0xef, 0x55, 0xc2, +0xe9, 0x86, 0xd4, 0xf0, 0x66, 0xc8, 0xec, 0x6a, +0xc9, 0xec, 0x6f, 0xca, 0xeb, 0x96, 0xd9, 0xf1, +0x7b, 0xce, 0xed, 0x82, 0xd1, 0xed, 0xa6, 0xde, +0xf2, 0x8e, 0xd4, 0xee, 0x92, 0xd6, 0xef, 0xaf, +0xe1, 0xf3, 0x05, 0xa7, 0xe1, 0x4d, 0xc1, 0xe9, +0x1b, 0xae, 0xe3, 0x5b, 0xc5, 0xeb, 0x62, 0xc7, +0xeb, 0x38, 0xb7, 0xe5, 0x50, 0xbe, 0xe7, 0x6b, +0xc7, 0xe8, 0x74, 0x93, 0x96, 0x7a, 0x9e, 0xa9, +0xa5, 0xc1, 0xe4, 0x66, 0x96, 0xd1, 0xc1, 0x8f, +0x36, 0xf1, 0xea, 0x87, 0xed, 0xe3, 0x60, 0xf3, +0xf0, 0xc8, 0xf0, 0xec, 0xb6, 0xef, 0xe9, 0xb5, +0xf2, 0xed, 0xc5, 0xee, 0xe6, 0xb3, 0xf1, 0xeb, +0xc4, 0xec, 0xe3, 0xb0, 0xf0, 0xe9, 0xc2, 0xe1, +0xef, 0xf7, 0xe7, 0xda, 0x2b, 0xea, 0xe4, 0x9d, +0xea, 0xe3, 0x9c, 0xe9, 0xe0, 0x9a, 0xef, 0xe8, +0xb3, 0xe8, 0xde, 0x99, 0xe7, 0xdc, 0x97, 0xed, +0xe5, 0xb1, 0xe6, 0xd9, 0x94, 0xe5, 0xd6, 0x93, +0xec, 0xe0, 0xad, 0xd6, 0xe9, 0xf5, 0xec, 0xe2, +0xaf, 0xe6, 0xda, 0x96, 0xec, 0xe1, 0xae, 0xe4, +0xd5, 0x92, 0xeb, 0xdf, 0xad, 0xed, 0xe6, 0xb2, +0xeb, 0xde, 0xac, 0xf0, 0xe6, 0xc0, 0xd4, 0xe9, +0xf4, 0xcb, 0xa2, 0x58, 0xdb, 0xbd, 0x89, 0xea, +0xdd, 0xaa, 0xef, 0xe4, 0xbe, 0xd3, 0xe8, 0xf3, +0xe4, 0xd4, 0x91, 0xe3, 0xd2, 0x8f, 0xe2, 0xd0, +0x8d, 0xe9, 0xda, 0xa9, 0xd1, 0xe7, 0xf2, 0xe4, +0xd3, 0x90, 0xe2, 0xce, 0x8c, 0xef, 0xe3, 0x5f, +0xe9, 0xdb, 0xaa, 0xe1, 0xcc, 0x8a, 0xe9, 0xd9, +0xa8, 0xf6, 0xeb, 0x87, 0xed, 0xe1, 0xbc, 0xcd, +0xe5, 0xf2, 0xf3, 0xe4, 0x5f, 0xe8, 0xd7, 0xa7, +0xe8, 0xd7, 0xa6, 0xed, 0xe0, 0xbb, 0xee, 0xdb, +0x2a, 0xf3, 0xdc, 0x2a, 0xe0, 0xc9, 0x89, 0xdf, +0xc8, 0x88, 0xdf, 0xc7, 0x87, 0xe6, 0xd4, 0xa4, +0xcb, 0xe4, 0xf1, 0xf9, 0xe6, 0x5f, 0xde, 0xc6, +0x86, 0xca, 0xe3, 0xf0, 0xe7, 0xd5, 0xa5, 0xe6, +0xd3, 0xa3, 0xc8, 0xe3, 0xf0, 0xfe, 0xec, 0x86, +0xef, 0xe5, 0xc0, 0xec, 0xdd, 0xba, 0xc7, 0xe3, +0xf0, 0xc5, 0xe1, 0xef, 0xff, 0xe6, 0x5f, 0xec, +0xde, 0xba, 0xe6, 0xd2, 0xa2, 0xe6, 0xd1, 0xa2, +0xe6, 0xd1, 0xa1, 0xec, 0xdc, 0xb8, 0xff, 0xde, +0x29, 0xde, 0xc4, 0x84, 0xdd, 0xc3, 0x83, 0xdc, +0xc1, 0x82, 0xe5, 0xd0, 0xa1, 0xdc, 0xbe, 0x80, +0xc2, 0xe0, 0xee, 0xe4, 0xce, 0x9f, 0xeb, 0xda, +0xb7, 0xc0, 0xdf, 0xee, 0xe4, 0xcd, 0x9e, 0xea, +0xd9, 0xb6, 0xbc, 0xdd, 0xed, 0xda, 0xbb, 0x7e, +0xe3, 0xcc, 0x9e, 0xad, 0xd6, 0xe9, 0xe3, 0xcb, +0x9e, 0x0f, 0xfa, 0x04, 0x51, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0xc9, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xed, 0x94, 0xd9, 0x5b, 0x12, 0x51, 0x18, +0x87, 0x6d, 0xa2, 0xb0, 0xdc, 0x53, 0xcb, 0x2c, +0xf9, 0x40, 0x60, 0x18, 0x5c, 0x59, 0x25, 0x24, +0xb0, 0x06, 0x05, 0x5c, 0x00, 0x91, 0x45, 0x50, +0x04, 0x19, 0x49, 0x45, 0x40, 0x65, 0x55, 0x04, +0xe1, 0x5f, 0xf7, 0xcc, 0x92, 0xc2, 0x71, 0xe2, +0x89, 0x9b, 0x9e, 0x2e, 0xfc, 0x2e, 0x0e, 0x37, +0xbc, 0xcf, 0x8f, 0xf7, 0xf7, 0x1d, 0x4e, 0x5f, +0xdf, 0xcb, 0xfc, 0xeb, 0x79, 0x45, 0xb0, 0xf3, +0xc7, 0x53, 0x0c, 0x21, 0x5e, 0x4b, 0x24, 0x92, +0x37, 0xc4, 0x5b, 0xa9, 0x54, 0xda, 0x4f, 0xf4, +0xbf, 0x7b, 0x3f, 0x30, 0x48, 0x0c, 0x0e, 0x0d, +0x0f, 0x8f, 0x10, 0x23, 0xa3, 0x63, 0x63, 0x1f, +0x08, 0x51, 0x44, 0x32, 0x3e, 0x3e, 0x3e, 0x41, +0x4c, 0x4c, 0x4e, 0x4e, 0x7e, 0x24, 0x3e, 0x4d, +0x4d, 0x4d, 0x0d, 0x10, 0x43, 0x9f, 0xa5, 0xd2, +0x61, 0x62, 0x74, 0x7a, 0x7a, 0x60, 0x8c, 0xe8, +0x96, 0x32, 0xf1, 0xf7, 0x29, 0x5f, 0xb8, 0xdf, +0xcc, 0x9f, 0x5f, 0x9f, 0x9f, 0x1d, 0xdf, 0x9d, +0x91, 0xc9, 0x66, 0xd0, 0x07, 0xc8, 0x15, 0x0a, +0x85, 0x1c, 0x66, 0x95, 0x4a, 0xe5, 0x2c, 0xcc, +0xaa, 0x54, 0x2a, 0x35, 0xa8, 0x49, 0x92, 0xd4, +0x80, 0x86, 0xa2, 0x28, 0x2d, 0x74, 0x20, 0xb2, +0xb9, 0x39, 0x19, 0x8b, 0x28, 0xe6, 0xe7, 0xe7, +0x15, 0xa0, 0x5c, 0x58, 0x58, 0x54, 0x81, 0x6a, +0x69, 0x69, 0x69, 0x19, 0x48, 0x9d, 0x5e, 0x6f, +0x00, 0xca, 0x68, 0x34, 0x99, 0x31, 0x64, 0x65, +0xa5, 0x03, 0x59, 0xe4, 0x11, 0x1d, 0x09, 0xa4, +0x5e, 0xaf, 0xa7, 0xc0, 0x62, 0x34, 0x75, 0x47, +0x54, 0x8b, 0x2c, 0xb2, 0xac, 0xd3, 0x21, 0xc4, +0xa0, 0xff, 0x66, 0xa4, 0xc0, 0x6a, 0x5a, 0x5d, +0xb5, 0x89, 0x23, 0x82, 0xcb, 0x6f, 0x8b, 0xef, +0x9c, 0x85, 0x45, 0x0b, 0x5a, 0xb3, 0xcd, 0xee, +0xc0, 0x90, 0xb5, 0x35, 0x16, 0xf9, 0x01, 0xec, +0xf0, 0xe7, 0xcf, 0xe7, 0xa7, 0x18, 0x22, 0xa4, +0xa8, 0x97, 0x49, 0x52, 0x0d, 0x1a, 0x83, 0x81, +0xd2, 0x80, 0xd6, 0x6a, 0x36, 0x3b, 0xc0, 0x41, +0xd3, 0xb4, 0x13, 0x4b, 0x59, 0x5f, 0x6f, 0x73, +0x79, 0xb2, 0xb0, 0xb0, 0x16, 0x1b, 0x76, 0xa0, +0x5d, 0x6e, 0xb7, 0x07, 0x43, 0x36, 0x37, 0xdb, +0x10, 0x52, 0xa7, 0xe3, 0x8b, 0x35, 0x5a, 0xc1, +0xbc, 0xba, 0xb1, 0x45, 0x03, 0xed, 0x76, 0x6f, +0x77, 0x41, 0x76, 0x84, 0x62, 0x29, 0xae, 0x58, +0xdb, 0x96, 0xcb, 0x45, 0x83, 0x77, 0x7b, 0xdb, +0xe7, 0x17, 0x47, 0xe4, 0x8a, 0x9d, 0x9d, 0x5d, +0x11, 0x0b, 0xa7, 0xc7, 0xef, 0x0f, 0x60, 0xc8, +0xde, 0x5e, 0xcf, 0x8d, 0xf1, 0x08, 0xc8, 0x83, +0xc1, 0x20, 0x4a, 0xa1, 0x2c, 0x56, 0x2d, 0x38, +0x6c, 0x76, 0xb4, 0x0b, 0xa7, 0xd7, 0xe3, 0x71, +0x42, 0x20, 0x14, 0x0a, 0x47, 0x44, 0x53, 0x20, +0xb8, 0xbf, 0x1f, 0x0d, 0x62, 0x16, 0x3e, 0x64, +0x11, 0x8a, 0x1d, 0x1c, 0xc6, 0x31, 0xe4, 0xe8, +0x48, 0x40, 0xa2, 0xd1, 0x04, 0x2a, 0xd6, 0x84, +0xae, 0x07, 0xed, 0x72, 0xb9, 0xbd, 0xe0, 0xf1, +0xf9, 0x7c, 0x21, 0x08, 0x1f, 0x1c, 0x26, 0x71, +0xe4, 0xf8, 0x98, 0x47, 0xa2, 0x2c, 0xc2, 0x16, +0x6b, 0x17, 0x8a, 0xf5, 0xfb, 0x62, 0xb1, 0x30, +0xa4, 0x92, 0xc9, 0x24, 0x83, 0x21, 0x27, 0x27, +0x1c, 0xb2, 0x9b, 0x48, 0x24, 0xd2, 0xac, 0x05, +0xfd, 0x8b, 0xb3, 0x08, 0x20, 0x8b, 0x70, 0x2a, +0x02, 0x91, 0x38, 0xc3, 0x9c, 0x62, 0xc8, 0xd9, +0x59, 0xcf, 0x8d, 0x9d, 0x9f, 0x73, 0x29, 0xe9, +0x44, 0x26, 0x93, 0x66, 0x77, 0xe1, 0x45, 0xbb, +0xf0, 0xfb, 0x43, 0x01, 0x88, 0xa4, 0xe2, 0xf1, +0x0b, 0x38, 0xcd, 0xe6, 0xf2, 0x97, 0x20, 0x8a, +0x64, 0xae, 0xae, 0xae, 0x32, 0xb8, 0xc5, 0x35, +0x03, 0xb9, 0x42, 0xb1, 0x58, 0xea, 0x86, 0xf0, +0xd7, 0x23, 0x14, 0x8b, 0x1d, 0xa4, 0x20, 0x9e, +0xbc, 0x2e, 0x64, 0x21, 0x5f, 0x2c, 0x96, 0x71, +0xa4, 0x52, 0x69, 0x43, 0x1e, 0x8b, 0x45, 0xbb, +0x60, 0xae, 0x0b, 0x85, 0x3c, 0x94, 0x8a, 0xe5, +0x72, 0x55, 0x1c, 0x49, 0x67, 0x58, 0x97, 0x0e, +0x8b, 0x5c, 0x2e, 0x7f, 0x03, 0x37, 0xa5, 0x6a, +0xf5, 0x06, 0x43, 0x6e, 0x6f, 0x7b, 0x6e, 0x8c, +0x47, 0x84, 0x94, 0x40, 0x38, 0x85, 0x76, 0x71, +0xc1, 0x30, 0xd9, 0x53, 0xb8, 0x2c, 0x95, 0x4a, +0x28, 0xa5, 0x5a, 0xab, 0xdd, 0xb5, 0xa7, 0xa0, +0x87, 0xaf, 0x5e, 0x67, 0x1f, 0x3f, 0xc1, 0x85, +0xbf, 0x1e, 0x4c, 0x81, 0xb3, 0x28, 0xb3, 0x16, +0xb5, 0x46, 0xa3, 0x71, 0xdf, 0x8e, 0xc8, 0xd6, +0xea, 0xcd, 0x66, 0x1d, 0xfd, 0xfb, 0x05, 0x24, +0x75, 0xc8, 0x5e, 0x8f, 0x2c, 0x57, 0xec, 0x13, +0xd2, 0xea, 0x4c, 0xa9, 0x34, 0x9b, 0x95, 0xa7, +0x94, 0x38, 0xda, 0x45, 0x16, 0x72, 0x45, 0x16, +0xa9, 0x96, 0xcb, 0x8d, 0x1a, 0xdc, 0xe3, 0x08, +0x62, 0xd0, 0x1d, 0x9b, 0x79, 0x74, 0xb9, 0x60, +0xb2, 0x98, 0xc5, 0x5d, 0xab, 0xd5, 0xba, 0xeb, +0x6c, 0x4c, 0x78, 0xc6, 0x7b, 0x69, 0xec, 0x65, +0xfe, 0xaf, 0x79, 0x00, 0xb6, 0x14, 0x06, 0x2a, +0x4c, 0xe8, 0x5e, 0xa2, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_index_scan_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_index_scan_png = new wxImage(); + if (!img_ex_index_scan_png || !img_ex_index_scan_png->IsOk()) + { + wxMemoryInputStream img_ex_index_scan_pngIS(ex_index_scan_png_data, sizeof(ex_index_scan_png_data)); + img_ex_index_scan_png->LoadFile(img_ex_index_scan_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_index_scan_png; +} +#define ex_index_scan_png_img ex_index_scan_png_img() + +static wxBitmap *ex_index_scan_png_bmp() +{ + static wxBitmap *bmp_ex_index_scan_png; + if (!bmp_ex_index_scan_png || !bmp_ex_index_scan_png->IsOk()) + bmp_ex_index_scan_png = new wxBitmap(*ex_index_scan_png_img); + return bmp_ex_index_scan_png; +} +#define ex_index_scan_png_bmp ex_index_scan_png_bmp() + +static wxIcon *ex_index_scan_png_ico() +{ + static wxIcon *ico_ex_index_scan_png; + if (!ico_ex_index_scan_png || !ico_ex_index_scan_png->IsOk()) + { + ico_ex_index_scan_png = new wxIcon(); + ico_ex_index_scan_png->CopyFromBitmap(*ex_index_scan_png_bmp); + } + return ico_ex_index_scan_png; +} +#define ex_index_scan_png_ico ex_index_scan_png_ico() + +#endif // EX_INDEX_SCAN_PNG_H diff --git a/include/images/ex_insert.png b/include/images/ex_insert.png new file mode 100644 index 0000000000000000000000000000000000000000..862d837277c99e17d2b66232de79fce010752e7c GIT binary patch literal 1065 zcmV+^1lIeBP)TAd7XvplT#d&Va>__Y%vc!A9!GLwm?AyJ6+r5e0zJT1nfP2yJ+`)o`(eB;DgM`!Y z-o%97#f9F+hK$ti-^YjF$cT~E?%>IZ;mnGc+417ejN;IZDj2~+?VOv zsp;FQ>)N;I-kIv%s_fjj>EN2{-mL81y6fMq?B2TU;H~Q8obBJc?BTBM;JfPNo$TVT z?cu!a9z3a!tm+B@a(qn>%{Wy#q;gP^YF+M z!Lnrl0004WQchCPn51=F&d2) z>IBhBy)v84HtG!NF6!#^)E1!r(pR3TJMW~P0*}+_^l{1Ycsz%>EXy;PNs=@H{0soS zsZ1XpT4Ta-wOSp4TqzX#AZ4@ZCSYUngQhh~OI2D}smLG~3Iz$e+4NHRx>yYJuvW$` z^-VJ@Oxn%n5Qd^C4wf(0IAs5IimsC4t_ET>94@Z+-*8Z+6;vrE zDmL4OX6o)%1Th>A6*p>99W@-O6jM@*ZQMqqB9uZQMgW7>p*i#m+5guRgQ6hxVDr$y zp&Tmg*VxiQ7K(#Tq1&Di4jVOe7K2i;IDj6{=Q^OhkHF`j9~j8~+7t{*!3X_54z}(v zzyVU)=`^|+m|`>IsOk()) + { + wxMemoryInputStream img_ex_insert_pngIS(ex_insert_png_data, sizeof(ex_insert_png_data)); + img_ex_insert_png->LoadFile(img_ex_insert_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_insert_png; +} +#define ex_insert_png_img ex_insert_png_img() + +static wxBitmap *ex_insert_png_bmp() +{ + static wxBitmap *bmp_ex_insert_png; + if (!bmp_ex_insert_png || !bmp_ex_insert_png->IsOk()) + bmp_ex_insert_png = new wxBitmap(*ex_insert_png_img); + return bmp_ex_insert_png; +} +#define ex_insert_png_bmp ex_insert_png_bmp() + +static wxIcon *ex_insert_png_ico() +{ + static wxIcon *ico_ex_insert_png; + if (!ico_ex_insert_png || !ico_ex_insert_png->IsOk()) + { + ico_ex_insert_png = new wxIcon(); + ico_ex_insert_png->CopyFromBitmap(*ex_insert_png_bmp); + } + return ico_ex_insert_png; +} +#define ex_insert_png_ico ex_insert_png_ico() + +#endif // EX_INSERT_PNG_H diff --git a/include/images/ex_join.png b/include/images/ex_join.png new file mode 100644 index 0000000000000000000000000000000000000000..c391233c449bdc5a0d52d50f522bd3e35c649c36 GIT binary patch literal 1090 zcmV-I1ikx-P)V?$sl-Tfk&g_HH?Tggzt>5!Nyy*w1;t;Fi8m{AA#p`j) z>`uPsTEXXJ#psgN?_7<@W^2*R&GEgz?Z3h8!ou#;)brTc^v=)n(b4kM)b!xs_i~n@ zTZg#3z3iu{=c=sduCM9E#_!9_@xH(9#m4Z~*7U)THuUky@a(t1!S2S#@6FEg-rn}> z=AWyq=(DuyyuIzz)bo;+(T1sHQjHmZrCYPXrlG`Mg|bG+s&$Tqt8$|?qQ_wH?6#)N zW$Wdh>g1j8>9p_bw(sb(^6bTgsA6`iJD#Uu0Heb#_r~_?d7rT;;-=M!L{Ui z=GvC!*OTPakm}s3d$U61)sf@UkK)gb>DZ@@!Bgwrtm4p);mwQS%8BRHr0(Lq=+~y~ z-MP8zf4c61<$$61+gq;DJ?Apx>_)8HEF30 z1qvUq@L_ZU6tfBI|y*^ohN&5&~$8Xg&a{sO&x z)%W_19RZglNiNj$_TBprh!c_AZnuPnKYkkfd})N~g^7GY=8#tqWQ@OlJIjk*1$#W> zgqZ+yzW-as^djR)gE?nn@}vi!H!=L<1mfjN3{M>+(=)SYCw3BX`FwNp6fe$M7+;i6 zP0Ts|#ifABKyWz}Ug1&^A* zTTdh_V86<|uIp4UMlA~aa1gDeGGHqKGqL&y^4bu#%6@n+eE^xPqU7uIsOk()) + { + wxMemoryInputStream img_ex_join_pngIS(ex_join_png_data, sizeof(ex_join_png_data)); + img_ex_join_png->LoadFile(img_ex_join_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_join_png; +} +#define ex_join_png_img ex_join_png_img() + +static wxBitmap *ex_join_png_bmp() +{ + static wxBitmap *bmp_ex_join_png; + if (!bmp_ex_join_png || !bmp_ex_join_png->IsOk()) + bmp_ex_join_png = new wxBitmap(*ex_join_png_img); + return bmp_ex_join_png; +} +#define ex_join_png_bmp ex_join_png_bmp() + +static wxIcon *ex_join_png_ico() +{ + static wxIcon *ico_ex_join_png; + if (!ico_ex_join_png || !ico_ex_join_png->IsOk()) + { + ico_ex_join_png = new wxIcon(); + ico_ex_join_png->CopyFromBitmap(*ex_join_png_bmp); + } + return ico_ex_join_png; +} +#define ex_join_png_ico ex_join_png_ico() + +#endif // EX_JOIN_PNG_H diff --git a/include/images/ex_limit.png b/include/images/ex_limit.png new file mode 100644 index 0000000000000000000000000000000000000000..cc3efd59d70436349e5413f8c5d2673200cd74f0 GIT binary patch literal 1237 zcmV;`1S~G5Jmf7)p&h3KH?WW%Hj@0gw*6*+3 z^985jO~L6KuH#$9>te_2IJf0czUNiI=UKt$YscuhV`Hfo7w~d&?QwDGaB$~uaOH1r z;cjl-ZEe|XY}0FNhN)yyjTym@HuUkx@a(tm>$dan$M5O1^X%{Ehuk7Kj?BK2N=)$7LVC&_c>f@a6>b2?Mn&;e?=i8R-))-W%w_1_ zndaG*Ds97;k~rudA8?#xaxo6&Wz#Ai|N>>x$A)A(2n5BiRjm+=hmj@)urv)N;G)1&6m zq2$e;XV!X``@E)R3}Nf|O*B$m)u`ByS4@xQIz9FPadbCWy#_ z5QxIR-d(t0;9^epp=NwO+}WKuzd83g&$%MegZ^zjB6tlvg%IMgSS)@*Je5c!L&VUt z=h9(fctj=}B}T`_$6pYFh*&O{i-`$^Lh+J#H90vcB}QJqnUWD>)6>#%;Y^pJA`vX;bh-upT-1Y}qNpWU zrdJHBuxd1!Er6>!B0rD_(XFkm>CkDl+JLg#?KIF1r;`Dr%kB06uIeHmuaQNo)k-16 z>!rcq^!bcncKg>^z*Rzst%U@<-VFmVK3~uTX8-!;P2>~V_R@9{;9VHHF1A>f4FRs| zBA?OE7vMGU#8sVnk=rDx1^uFp(!)}Krk7!LhhZ#WF?+&W5Q;>jF~C)w9^1QnUrFAD zodO!W2)fMJMPxr7PXMm!blKhehPqHzyFCE(hQql7Owi>vLwGZpj6gIVPo)7@b#KOh z^I4$5t~i`N223uuKMZVge?JO|R4R1K zCEkTm$i;CclRW{Uhm5oEtZyb+ez5U09OO<<^N=|!6gXkT=yIVYXK@xOl*Qp`v6z8u zp;Q`xnA|;CVZ`DIvp*md{nbSlxu|lLN>vc~?IsI!LGL0Gf>IsOk()) + { + wxMemoryInputStream img_ex_limit_pngIS(ex_limit_png_data, sizeof(ex_limit_png_data)); + img_ex_limit_png->LoadFile(img_ex_limit_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_limit_png; +} +#define ex_limit_png_img ex_limit_png_img() + +static wxBitmap *ex_limit_png_bmp() +{ + static wxBitmap *bmp_ex_limit_png; + if (!bmp_ex_limit_png || !bmp_ex_limit_png->IsOk()) + bmp_ex_limit_png = new wxBitmap(*ex_limit_png_img); + return bmp_ex_limit_png; +} +#define ex_limit_png_bmp ex_limit_png_bmp() + +static wxIcon *ex_limit_png_ico() +{ + static wxIcon *ico_ex_limit_png; + if (!ico_ex_limit_png || !ico_ex_limit_png->IsOk()) + { + ico_ex_limit_png = new wxIcon(); + ico_ex_limit_png->CopyFromBitmap(*ex_limit_png_bmp); + } + return ico_ex_limit_png; +} +#define ex_limit_png_ico ex_limit_png_ico() + +#endif // EX_LIMIT_PNG_H diff --git a/include/images/ex_lock_rows.png b/include/images/ex_lock_rows.png new file mode 100644 index 0000000000000000000000000000000000000000..41c1148bb185c87898b3fddaa76be36a15703336 GIT binary patch literal 1520 zcmVDi(jE;5AQ9-=u%c5Axr%}nMQA)t+%BxY=s7}hQQOB=S%&$?Wv9Zju zQmC`DUBv4BtpTdFwW_wZW5(*uwpDA#=xE67&bnBwy1LG~S+BgjZp-YjzP@$M?Ap72 zw8FyMy@}(!bKJgw|GhAK(eJjz#N5GxgwgKZ!-Is=@ZQ9P-o}QE)b8KMhu_GEk=5?t z$%*02ikI2(z0>Dj2~+?VOvsp{Fb>D#L7+PCQ5nd;rD z?A*BN;F{~+tn%Ha?A^NS->vfAr|jOk^xmoL;H~Q8ob=zR?BTBM;JfPNo$TVT?cu!i z;i~N8u=L}t?d7rb`Q@?i=(G0cv-an-@9DMq=dbm&qxbf@6{pz;(?7H&p#rf^N`R>2@?#1))$p7!Z`SHN{@xlA?!~gNV z|MAlO^v(bC)c^F+|MtiK_R0VD+W+?3|M<R3a-OF)@e8xgr!66UABC*%d@ZUSZ)af)^1)L_`RP1gMF` zrP$b5A(0C4Y$7i?Sy)K?L6_Y-qqanbev0AM(=rZcYkf@Xxj4t0ln?*eB=x3yTb~{A6t+$OdaO!GmS~0Te z24{TE!C>SC%|Gtq5pvPx1ztyMQx8I}?^v_?^qCXK;t$OVo);YybP}+Yfi!)xvdGo< zqo2Nf{PF$s@L+%cR@fzzEilx_FhjuC-A(&|*XeNdfF6pX+^Eatcca5>4G#A9K3UHq zNl8hW0WP{&7u8LGQYjQRgq(YWkWm(S7&eYDb~_H%=md_M>PiYw3PmYKPQCUc4?_J2 z3YJE}wpOZC6sRjLm0J*U{FNWMzhd0WWEXCm#o|Ip{0l#FH{`bxJN%qQMiFvnG3?@_ zyPRH5ds>^|S-9(LHaBpY&8802W$)8xFF$%tZzHdW7tW z-nMaVSm>%{Axjp{p9>MEP6rnQE2UB?>VQoymz#m9AYY~jd{+!b+Qcai)*>$|G6923 zCL{R~I6w86Q`UtGx-c0!K!=_rTX>P90f}WyPLIC}Mb){v)4|$d(Cgbki&j(Bz&{wC zAMXHG=pvT{8mUC0=11^i1R{D_u2c)EBogry2#z!mA#5D=9@T#H@>Qkw{d=j~MdV z#lWgX!TOOBenbyXLCdK|!XiqsSX2(mrbgOGEu0@~po`j)l9JkK5=)=%R?gJ_Sib;} WuicyymX%Qe0000IsOk()) + { + wxMemoryInputStream img_ex_lock_rows_pngIS(ex_lock_rows_png_data, sizeof(ex_lock_rows_png_data)); + img_ex_lock_rows_png->LoadFile(img_ex_lock_rows_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_lock_rows_png; +} +#define ex_lock_rows_png_img ex_lock_rows_png_img() + +static wxBitmap *ex_lock_rows_png_bmp() +{ + static wxBitmap *bmp_ex_lock_rows_png; + if (!bmp_ex_lock_rows_png || !bmp_ex_lock_rows_png->IsOk()) + bmp_ex_lock_rows_png = new wxBitmap(*ex_lock_rows_png_img); + return bmp_ex_lock_rows_png; +} +#define ex_lock_rows_png_bmp ex_lock_rows_png_bmp() + +static wxIcon *ex_lock_rows_png_ico() +{ + static wxIcon *ico_ex_lock_rows_png; + if (!ico_ex_lock_rows_png || !ico_ex_lock_rows_png->IsOk()) + { + ico_ex_lock_rows_png = new wxIcon(); + ico_ex_lock_rows_png->CopyFromBitmap(*ex_lock_rows_png_bmp); + } + return ico_ex_lock_rows_png; +} +#define ex_lock_rows_png_ico ex_lock_rows_png_ico() + +#endif // EX_LOCK_ROWS_PNG_H diff --git a/include/images/ex_materialize.png b/include/images/ex_materialize.png new file mode 100644 index 0000000000000000000000000000000000000000..c3bd0bb90dd2ef1cc1baf7f932817d1b6bdf463b GIT binary patch literal 1221 zcmV;$1UmbPP)k?y5Ub*3#pqna>5|p&pRKHao1$`-p~$a;;^52R-owF*k;8G{;;oZva z=CbkX#N5}k+|{$*+Q8@Bm*&}&?BlTA*tOf#vFYHN=--*_;H}=+zU0-B;M>TCsbo@( z8Sv)7tJG}W*1h1`$FJLRv*CB}=)&sVtLfaT?&7`L(XZLhuG!A5qQzgO%VePg78bgs7LkqpPC|yAQ z^~}hc;|y@}z&Sa2@IKs^*>CRt?kg^qjd;+Mrj*-t4Dy|b#6bd*+Pt%5pDQfi=wPQ3IcZn=8g&xp*CKE$u z(db|bx-s`LGP5^kU>L>)TrA6;0C@jxeL01O+O=3LUn!5*>+|C; z#@J8_HgFbX0nh#I{QUU%`{~6GH;+r<4TZxIl0>5{V9$cV*q4`)VekxZimGCKCihQ|TE)WE!sAQ;OwN|U+B$oVjnFob(`Km#XM7mNfQuSJ` z*2GEb@)F)(xVoAknM$=rG_o^ihh=U@(|_V-NMe)o+jt(ePu5AK?H103~!qSaf7zbY(hYa%Ew3WdJfTF)%GL zGA%GMR5CC+G&4FhG%GMQIxsLenI#?o001R)MObuXVRU6WZEs|0W_bWIFflMKFgYzS jF;p@$Iy5voFg7bNH99ab%9mBF00000NkvXXu0mjfVJ3t* literal 0 HcmV?d00001 diff --git a/include/images/ex_materialize.pngc b/include/images/ex_materialize.pngc new file mode 100644 index 0000000..6313c91 --- /dev/null +++ b/include/images/ex_materialize.pngc @@ -0,0 +1,197 @@ +#ifndef EX_MATERIALIZE_PNG_H +#define EX_MATERIALIZE_PNG_H + +static const unsigned char ex_materialize_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xa3, 0xbb, 0xcc, 0x83, +0xac, 0xc8, 0x75, 0xa6, 0xc7, 0x36, 0x88, 0xc1, +0x9e, 0xcd, 0xde, 0x8c, 0xc7, 0xdd, 0x93, 0xc9, +0xdd, 0xaa, 0xd2, 0xe0, 0xb2, 0xd4, 0xe0, 0xa5, +0xcf, 0xde, 0xad, 0xd2, 0xdf, 0xbe, 0xd8, 0xe2, +0x70, 0xcc, 0xed, 0x43, 0xbd, 0xe9, 0x4d, 0xbf, +0xe8, 0x53, 0xc2, 0xea, 0x85, 0xd4, 0xf0, 0x94, +0xd8, 0xf0, 0x7a, 0xce, 0xec, 0x87, 0xd3, 0xee, +0xad, 0xdf, 0xf3, 0x6b, 0xbc, 0xd9, 0x73, 0xbe, +0xda, 0x10, 0xab, 0xe2, 0x64, 0xc5, 0xe8, 0x5c, +0xc3, 0xe9, 0x92, 0xd5, 0xef, 0x9f, 0xad, 0xac, +0x7f, 0x9b, 0xa2, 0x72, 0x96, 0xa1, 0xc8, 0xaf, +0x83, 0xe2, 0xe0, 0xcb, 0xe0, 0xde, 0xc3, 0xc1, +0x8f, 0x36, 0xf4, 0xf0, 0xc8, 0xf0, 0xec, 0xb7, +0xde, 0xdb, 0xb7, 0xdd, 0xda, 0xb6, 0xe0, 0xdd, +0xc2, 0xeb, 0xe6, 0x9f, 0xea, 0xe4, 0x9e, 0xef, +0xe9, 0xb5, 0xea, 0xe3, 0x9d, 0xdd, 0xd9, 0xb5, +0xe9, 0xe1, 0x9b, 0xef, 0xe8, 0xb3, 0xe0, 0xdc, +0xc1, 0xf2, 0xed, 0xc5, 0xcc, 0xbd, 0xa3, 0xc7, +0xaa, 0x75, 0xdf, 0xdb, 0xc1, 0xe1, 0xdd, 0xca, +0xee, 0xe6, 0xb2, 0xf1, 0xea, 0xc4, 0xdc, 0xd7, +0xb4, 0xdc, 0xd5, 0xb3, 0xde, 0xda, 0xc0, 0xe7, +0xdc, 0x97, 0xe6, 0xd9, 0x94, 0xec, 0xe3, 0xb0, +0xdd, 0xd8, 0xb5, 0xdb, 0xd4, 0xb1, 0xe9, 0xe0, +0x9a, 0xe8, 0xdf, 0x99, 0xec, 0xe0, 0xad, 0xde, +0xd8, 0xbe, 0xe4, 0xd5, 0x91, 0xe0, 0xdb, 0xc8, +0x86, 0xa9, 0x64, 0x52, 0x8d, 0x19, 0xf0, 0xe6, +0xc0, 0xab, 0xd4, 0x6c, 0xdd, 0xd6, 0xbd, 0xe0, +0xda, 0xc7, 0xaf, 0xdb, 0x72, 0xb3, 0xe1, 0x77, +0xf0, 0xe8, 0xc2, 0xea, 0xdd, 0xab, 0xe9, 0xdc, +0xaa, 0xee, 0xe2, 0xbd, 0xda, 0xd1, 0xaf, 0xd9, +0xcf, 0xae, 0xd9, 0xce, 0xad, 0xa2, 0xc5, 0x5f, +0xa5, 0xcb, 0x64, 0xb0, 0xdc, 0x73, 0xb7, 0xe7, +0x7c, 0xb8, 0xeb, 0x7f, 0xe3, 0xd1, 0x8f, 0xe2, +0xce, 0x8c, 0xe9, 0xd9, 0xa8, 0xda, 0xd2, 0xb0, +0xdc, 0xd4, 0xbb, 0xba, 0xec, 0x81, 0xe1, 0xcc, +0x8a, 0xe8, 0xd7, 0xa7, 0xd8, 0xcc, 0xac, 0xdc, +0xd3, 0xba, 0xe0, 0xca, 0x89, 0xe7, 0xd6, 0xa6, +0xdf, 0xd8, 0xc5, 0xec, 0xdd, 0xba, 0xdb, 0xd2, +0xba, 0xdb, 0xd1, 0xb8, 0xe6, 0xd4, 0xa4, 0xe6, +0xd3, 0xa3, 0xd7, 0xc9, 0xa9, 0xdf, 0xc8, 0x87, +0xde, 0xc5, 0x85, 0xdd, 0xc1, 0x82, 0xe6, 0xd1, +0xa1, 0xd8, 0xcc, 0xab, 0xd8, 0xcb, 0xab, 0xd6, +0xc7, 0xa8, 0xda, 0xcf, 0xb7, 0xe4, 0xce, 0xa0, +0xdc, 0xbe, 0x80, 0xde, 0xd5, 0xc3, 0xeb, 0xd9, +0xb6, 0xda, 0xce, 0xb7, 0xda, 0xcd, 0xb7, 0xe4, +0xcd, 0x9e, 0xe3, 0xcc, 0x9e, 0xe3, 0xcb, 0x9e, +0xd5, 0xc5, 0xa6, 0xda, 0xba, 0x7d, 0xdb, 0xbd, +0x7f, 0xd0, 0x14, 0x54, 0x5d, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0x7c, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xed, 0xd2, 0xd7, 0x57, 0x1a, 0x41, 0x14, +0x07, 0x60, 0x42, 0x50, 0x4c, 0x8c, 0x9a, 0x62, +0x22, 0xa6, 0x0d, 0xac, 0xf4, 0x22, 0x26, 0x0b, +0xca, 0x4a, 0x51, 0x8a, 0xe0, 0x1a, 0x43, 0x91, +0x18, 0x43, 0x0b, 0xbd, 0xb7, 0x28, 0x5d, 0x40, +0xfe, 0xf5, 0xcc, 0xc8, 0x9a, 0xe3, 0x0c, 0x70, +0xf2, 0xc0, 0x39, 0x39, 0x79, 0xf0, 0x3e, 0xdc, +0x97, 0xd9, 0x6f, 0xee, 0xfe, 0xee, 0x2e, 0x8f, +0xf7, 0x50, 0xff, 0xa8, 0x1e, 0xf1, 0x51, 0x71, +0x1d, 0x3b, 0x79, 0x2c, 0x40, 0xc5, 0xf5, 0xfb, +0x07, 0xfc, 0x85, 0xc5, 0x45, 0xe1, 0x12, 0xff, +0xc9, 0xd3, 0xa5, 0xe5, 0x67, 0x7c, 0x8c, 0x08, +0x56, 0x56, 0xd7, 0x9e, 0xbf, 0x10, 0xbc, 0x7c, +0xb5, 0xbe, 0xfe, 0x5a, 0x80, 0x91, 0xc5, 0x37, +0x1b, 0x1b, 0x42, 0x08, 0x85, 0x0b, 0xcb, 0x04, +0x59, 0x15, 0x89, 0x44, 0x9b, 0x82, 0x95, 0xb5, +0xb7, 0x9b, 0xef, 0x04, 0x73, 0x4e, 0x79, 0xff, +0x01, 0x15, 0xd7, 0x31, 0xf2, 0xf1, 0x36, 0x05, +0xd7, 0xef, 0x1f, 0x00, 0xb1, 0x44, 0x22, 0x11, +0x73, 0x1d, 0x23, 0xd4, 0x96, 0x54, 0x2a, 0xdd, +0xe2, 0x3a, 0x46, 0x24, 0x32, 0x99, 0x4c, 0x82, +0xba, 0x5c, 0x41, 0x10, 0xa9, 0x52, 0xa9, 0x94, +0xa2, 0xae, 0x52, 0x4f, 0x25, 0x72, 0xf9, 0x2c, +0xa2, 0x52, 0x69, 0x66, 0x10, 0xad, 0x76, 0x06, +0xd1, 0x68, 0x74, 0xdb, 0x38, 0xe1, 0xb2, 0x28, +0x14, 0xfa, 0x19, 0x59, 0xd4, 0xea, 0xed, 0x1d, +0x8c, 0x7c, 0x02, 0xa8, 0xb8, 0x8e, 0x91, 0xcf, +0x14, 0x2a, 0xae, 0x13, 0x53, 0x14, 0x0a, 0x38, +0x45, 0x4f, 0xd3, 0x86, 0x89, 0x29, 0x6a, 0xf5, +0x16, 0xb5, 0x63, 0x34, 0x1a, 0x77, 0x89, 0x2c, +0x30, 0x85, 0x1e, 0xd0, 0x7b, 0x26, 0x13, 0x43, +0x66, 0xd1, 0xe8, 0x60, 0x0a, 0xe3, 0xfe, 0xbe, +0xd9, 0x82, 0x13, 0x85, 0xd6, 0x6a, 0xa5, 0x01, +0x6d, 0x32, 0xd9, 0x48, 0xa2, 0xd6, 0x1d, 0x1c, +0x1a, 0x21, 0x31, 0x9b, 0xed, 0x04, 0xb1, 0x5a, +0xf7, 0x68, 0xc0, 0x98, 0x6c, 0x36, 0x07, 0x49, +0x0e, 0x0e, 0x21, 0xb1, 0x98, 0xcd, 0x4e, 0x82, +0x88, 0x69, 0x94, 0xc2, 0xc0, 0x38, 0x1c, 0xae, +0x3b, 0x72, 0xe4, 0x3e, 0x42, 0x64, 0x9c, 0x62, +0xd7, 0x6e, 0xb7, 0x7b, 0xfe, 0xba, 0x31, 0xf7, +0x31, 0x32, 0xb3, 0x37, 0x66, 0x60, 0x18, 0xc6, +0x05, 0x5c, 0x2c, 0xcb, 0x9e, 0x00, 0x78, 0xff, +0x6d, 0x7d, 0x39, 0x85, 0x86, 0xda, 0xb5, 0x58, +0x2c, 0x5f, 0x29, 0x8f, 0xd7, 0xeb, 0xf3, 0xe3, +0x2f, 0xc6, 0xd8, 0x50, 0x0a, 0x36, 0x70, 0x16, +0x64, 0x01, 0xcf, 0xfd, 0xed, 0xfc, 0xfc, 0xf8, +0xf8, 0xfb, 0xe9, 0xc5, 0x0f, 0x37, 0x8f, 0x4b, +0xe1, 0x0d, 0x85, 0xc3, 0x11, 0x92, 0x44, 0xa3, +0x2c, 0x60, 0xcf, 0x82, 0xc1, 0xd8, 0x9f, 0x29, +0x17, 0x3f, 0xd1, 0x14, 0xbb, 0xd3, 0xe9, 0xf4, +0x52, 0xbe, 0x70, 0x3c, 0x9e, 0xc0, 0x89, 0x23, +0x1a, 0x08, 0x40, 0x12, 0x4c, 0x26, 0x53, 0x77, +0xf1, 0xdd, 0x48, 0x20, 0x12, 0x0a, 0xf9, 0xa8, +0x48, 0x3c, 0x9d, 0xce, 0xe0, 0x64, 0x9c, 0x22, +0x1b, 0x4b, 0xa5, 0xb2, 0xc4, 0xc6, 0x3c, 0x5e, +0x1f, 0x4c, 0xe1, 0x4f, 0x64, 0x32, 0xb9, 0xb9, +0xff, 0xb1, 0x13, 0x96, 0x8d, 0x65, 0x41, 0x36, +0x9f, 0x2f, 0x64, 0x89, 0x4f, 0xe9, 0x89, 0x44, +0x12, 0x7e, 0x2a, 0x57, 0x2c, 0x95, 0xf0, 0x29, +0x5c, 0x8a, 0x7c, 0xb9, 0x5c, 0x2e, 0x10, 0x04, +0xa6, 0xa8, 0x64, 0xa8, 0x62, 0xb5, 0x56, 0xab, +0xe3, 0x24, 0x96, 0xfc, 0x75, 0x99, 0x07, 0x85, +0x72, 0xf9, 0xaa, 0x41, 0x90, 0x44, 0xba, 0x52, +0x2d, 0x52, 0xf5, 0x5a, 0xad, 0xd6, 0xc4, 0x49, +0xea, 0xf2, 0x12, 0xde, 0x5f, 0xb8, 0xba, 0x9a, +0x20, 0x99, 0x4a, 0xb5, 0x5a, 0x82, 0xa4, 0xd5, +0x22, 0x08, 0x4a, 0xd1, 0x06, 0xed, 0x46, 0xa3, +0xd1, 0x26, 0x08, 0x4c, 0x51, 0xcf, 0x51, 0x9d, +0x66, 0xb3, 0xd9, 0x99, 0x7b, 0x63, 0xd9, 0x42, +0x01, 0xde, 0xdf, 0xee, 0x76, 0x7b, 0x13, 0x53, +0xea, 0x75, 0x78, 0x7f, 0xe7, 0xba, 0x3f, 0xc0, +0xa7, 0x70, 0x29, 0xba, 0xc3, 0xe1, 0xb0, 0x47, +0x90, 0x7a, 0x0b, 0xa5, 0xe8, 0xdf, 0xdc, 0xdc, +0x0c, 0x70, 0xd2, 0x80, 0xa4, 0x0b, 0x7a, 0x53, +0x48, 0xb3, 0x35, 0x1a, 0x5d, 0x53, 0x83, 0xa9, +0x04, 0x3e, 0x3c, 0x95, 0x8c, 0x46, 0xf0, 0xe1, +0x29, 0x64, 0x9c, 0xa2, 0xdd, 0xeb, 0x4d, 0x64, +0xe9, 0xf4, 0x51, 0x8a, 0xce, 0x60, 0x30, 0x98, +0x7b, 0x63, 0x0f, 0xf5, 0xbf, 0xd5, 0x6f, 0x90, +0x0c, 0xd1, 0xf0, 0x63, 0x89, 0x1f, 0xe1, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_materialize_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_materialize_png = new wxImage(); + if (!img_ex_materialize_png || !img_ex_materialize_png->IsOk()) + { + wxMemoryInputStream img_ex_materialize_pngIS(ex_materialize_png_data, sizeof(ex_materialize_png_data)); + img_ex_materialize_png->LoadFile(img_ex_materialize_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_materialize_png; +} +#define ex_materialize_png_img ex_materialize_png_img() + +static wxBitmap *ex_materialize_png_bmp() +{ + static wxBitmap *bmp_ex_materialize_png; + if (!bmp_ex_materialize_png || !bmp_ex_materialize_png->IsOk()) + bmp_ex_materialize_png = new wxBitmap(*ex_materialize_png_img); + return bmp_ex_materialize_png; +} +#define ex_materialize_png_bmp ex_materialize_png_bmp() + +static wxIcon *ex_materialize_png_ico() +{ + static wxIcon *ico_ex_materialize_png; + if (!ico_ex_materialize_png || !ico_ex_materialize_png->IsOk()) + { + ico_ex_materialize_png = new wxIcon(); + ico_ex_materialize_png->CopyFromBitmap(*ex_materialize_png_bmp); + } + return ico_ex_materialize_png; +} +#define ex_materialize_png_ico ex_materialize_png_ico() + +#endif // EX_MATERIALIZE_PNG_H diff --git a/include/images/ex_merge.png b/include/images/ex_merge.png new file mode 100644 index 0000000000000000000000000000000000000000..3fd8299fdcb72604d0c97816d38ee25ec51699ff GIT binary patch literal 1127 zcmV-t1ep7YP)$$q@!^H2!#_)!zWKxY8p~PNwrpGpj!Eep(LA>Zn!0CI@?}XFvW5()e$n0**?3dZ` zpxg0;(e8}Y?vd5*uHf?tsp4J4>N2(Ebg1j2;F{;$m*?A-?BlSe%w_81oao+}=Gm3(;;-o4nC97(<=2z!;H{?6 zXYAmv@aV$Fs&%W?Z0p~x>fEaD<-p_8kK@pe>DsAbl`meHCBewLqviyiJ|ZV|uVayzqqY?h26u0=Fy_;-MZ$|qU_wb=Fy?$&!Owu zx7@#g+r59}&Y<1Fg5%7dI?;o_00001bW%=J06^y0W&i*H32;bRa{vGUNB{r;NB~C3 zYd!z~0v<_3K~zY`?bGX5(r_3DaGDn~EzQc+f-=ht?ef4F_ZT1uwF%R(Lb^=WWfKN0 zFq@$K>;1-ob697`-_$p~@OkmP`<&wNIZ@R!?LLW#1iZ2j3wDH zWf`OhpcKJmHj~4WH(-ouTamY;SNt@?_#qgJC3BGDIDQkbgke(=lwv)NQgHcvL9ilQ z8{6+3!+!vnR0I{9Os9(+@P&dk*?IrrBQj*kFsRrlDmGgz?(&F~%a-KR=PzHkNs=sy z$c&`egFQj0NLJ(dLSw290sM`GP^JRT&hu(P*AR2H%Cx8^sD$O;e!W_|F99WwM7OgbR)%4uh+w8IY(ocV>y2TWnrZACmaDB0000bbVXQnWMOn=I%9HW zVRU5xGB7bPEip1JFfmjzFgi3dIy5vZFf}?bFgTed9smFUC3HntbYx+4WjbwdWNBu3 t05UK!FfA}SEif@uGBY|fG&(RgD=;-WFfhuORjdF2002ovPDHLkV1n&OPyYY_ literal 0 HcmV?d00001 diff --git a/include/images/ex_merge.pngc b/include/images/ex_merge.pngc new file mode 100644 index 0000000..dbfa8ac --- /dev/null +++ b/include/images/ex_merge.pngc @@ -0,0 +1,185 @@ +#ifndef EX_MERGE_PNG_H +#define EX_MERGE_PNG_H + +static const unsigned char ex_merge_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x92, 0x95, 0xd1, 0x66, +0x6b, 0xd1, 0xcd, 0xce, 0xf2, 0xbc, 0xbd, 0xec, +0xbf, 0xc0, 0xed, 0xd1, 0xd1, 0xf2, 0xd3, 0xd4, +0xf3, 0xc7, 0xc8, 0xef, 0xc7, 0xc8, 0xf0, 0xca, +0xca, 0xf1, 0xdb, 0xdb, 0xf5, 0xd6, 0xd7, 0xf5, +0xe1, 0xe1, 0xf7, 0xa6, 0xa8, 0xe6, 0xa9, 0xab, +0xe7, 0xc1, 0xc2, 0xee, 0xc5, 0xc5, 0xef, 0xb5, +0xb6, 0xeb, 0xb9, 0xba, 0xec, 0xc3, 0xc4, 0xef, +0xc5, 0xc6, 0xf0, 0x86, 0xa9, 0x64, 0x52, 0x8d, +0x19, 0xa1, 0xc4, 0x5e, 0x75, 0xa6, 0xc7, 0x36, +0x88, 0xc1, 0x6f, 0xcd, 0xee, 0x41, 0xbc, 0xe8, +0x4a, 0xc0, 0xe9, 0x7b, 0xd1, 0xef, 0x84, 0xd3, +0xf0, 0x63, 0xc6, 0xea, 0x68, 0xc8, 0xec, 0x6e, +0xcb, 0xec, 0x97, 0xd9, 0xf1, 0xa0, 0xdb, 0xf1, +0x84, 0xd1, 0xee, 0x8c, 0xd4, 0xee, 0x91, 0xd5, +0xee, 0xae, 0xe0, 0xf3, 0x09, 0xa9, 0xe2, 0x5d, +0xc4, 0xea, 0x32, 0xb5, 0xe5, 0x75, 0xcd, 0xec, +0x6b, 0xc7, 0xe8, 0xa3, 0xc7, 0x61, 0x72, 0x96, +0xa1, 0xc1, 0x8f, 0x36, 0xf3, 0xf0, 0xc8, 0xf0, +0xec, 0xb6, 0xef, 0xe9, 0xb4, 0xf3, 0xed, 0xc6, +0xee, 0xe6, 0xb2, 0xed, 0xe5, 0xb1, 0xf1, 0xeb, +0xc4, 0xea, 0xe4, 0x9d, 0xe9, 0xe0, 0x9a, 0xe7, +0xdc, 0x97, 0xe7, 0xdb, 0x96, 0xec, 0xe3, 0xb0, +0xa6, 0xcc, 0x65, 0xea, 0xe3, 0x9c, 0xe8, 0xde, +0x99, 0xe6, 0xd9, 0x95, 0xec, 0xe2, 0xaf, 0xe8, +0xdd, 0x98, 0xe6, 0xd9, 0x94, 0xe5, 0xd7, 0x93, +0xec, 0xe0, 0xad, 0xa6, 0xd0, 0x67, 0xec, 0xe0, +0xae, 0xf0, 0xe8, 0xc2, 0xc7, 0xaa, 0x75, 0xab, +0xd5, 0x6c, 0xeb, 0xdf, 0xad, 0xea, 0xdc, 0xaa, +0xef, 0xe5, 0xc0, 0xe3, 0xd2, 0x8f, 0xe3, 0xd0, +0x8e, 0xe9, 0xda, 0xa9, 0x61, 0x95, 0x2f, 0x5e, +0x98, 0x25, 0xc1, 0xc8, 0xba, 0xe4, 0xd5, 0x92, +0x70, 0x9d, 0x45, 0x9a, 0xca, 0x5d, 0x78, 0xae, +0x3e, 0x9e, 0xb5, 0x87, 0xba, 0xed, 0x81, 0xe4, +0xd3, 0x90, 0xe1, 0xcd, 0x8c, 0x8b, 0xab, 0x6c, +0x88, 0xbc, 0x4d, 0x9d, 0xd0, 0x63, 0x7a, 0xb0, +0x40, 0xbc, 0xf0, 0x84, 0xef, 0xe4, 0xbf, 0xe9, +0xd8, 0xa7, 0xee, 0xe2, 0xbd, 0xbf, 0xc7, 0xb7, +0xab, 0xde, 0x71, 0xb8, 0xeb, 0x7f, 0xf0, 0xe6, +0xc0, 0xe8, 0xd7, 0xa7, 0xe7, 0xd6, 0xa5, 0xed, +0xdf, 0xbb, 0xe1, 0xcc, 0x8a, 0xe0, 0xc8, 0x88, +0xdf, 0xc7, 0x87, 0xe6, 0xd4, 0xa4, 0xde, 0xc5, +0x85, 0xe6, 0xd3, 0xa3, 0xe0, 0xc9, 0x89, 0xde, +0xc4, 0x85, 0xdd, 0xc3, 0x83, 0xe6, 0xd1, 0xa2, +0xec, 0xdd, 0xba, 0xe6, 0xd2, 0xa2, 0xec, 0xdc, +0xb8, 0xe6, 0xd1, 0xa1, 0xe5, 0xcf, 0xa1, 0xeb, +0xda, 0xb7, 0xdc, 0xbf, 0x80, 0xdb, 0xbd, 0x7f, +0xe4, 0xce, 0xa0, 0xdd, 0xc1, 0x82, 0xe3, 0xcc, +0x9e, 0x3a, 0xd1, 0x83, 0xbf, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0x1e, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xed, 0xd3, 0xeb, 0x57, 0xd2, 0x70, 0x18, +0x07, 0x70, 0x9a, 0x17, 0x32, 0x2d, 0xcd, 0xca, +0xd5, 0x82, 0x32, 0xcb, 0x0c, 0xed, 0xf2, 0xc0, +0x18, 0xf7, 0x18, 0x20, 0x08, 0xb5, 0x09, 0xd3, +0xb0, 0x42, 0xba, 0x4c, 0xd6, 0x65, 0x13, 0x06, +0x2c, 0x30, 0x9b, 0xa0, 0xfc, 0xeb, 0xfd, 0xc6, +0x81, 0x73, 0x58, 0x67, 0xc7, 0xdf, 0xd4, 0x37, +0xbd, 0xf0, 0x79, 0xf1, 0xbc, 0xfb, 0x9c, 0xe7, +0xf7, 0xfd, 0xee, 0xcc, 0xe1, 0xb8, 0x1c, 0xc7, +0x15, 0xc2, 0x18, 0xd3, 0xc6, 0x11, 0x62, 0x6c, +0x7c, 0x62, 0x62, 0x92, 0x70, 0x5e, 0x9d, 0xba, +0x36, 0x4d, 0x4c, 0x3b, 0x9d, 0x33, 0xd7, 0x09, +0x2c, 0x19, 0xbf, 0x31, 0x3b, 0x3b, 0x47, 0xdc, +0x9c, 0x9f, 0xbf, 0x35, 0x46, 0x4c, 0xde, 0xbe, +0x33, 0x35, 0xf3, 0xbf, 0x90, 0xb3, 0x67, 0x39, +0x47, 0x63, 0x17, 0x98, 0x05, 0x72, 0xe1, 0xac, +0x84, 0xbc, 0x4b, 0x5e, 0x88, 0xdc, 0xa3, 0x8c, +0x31, 0x6d, 0x1c, 0xa1, 0xee, 0xbb, 0xdc, 0xee, +0x07, 0xd4, 0xc3, 0xc5, 0x47, 0x4b, 0x8f, 0xa9, +0x27, 0xcb, 0x4f, 0x57, 0x9e, 0x51, 0x58, 0xe2, +0xf2, 0x78, 0x3c, 0x6e, 0x6a, 0x75, 0x6d, 0xcd, +0xf5, 0x9c, 0x5a, 0x5e, 0x5d, 0x7c, 0xb1, 0x82, +0x27, 0xf6, 0xae, 0xbc, 0x1c, 0x21, 0xaf, 0xfa, +0xef, 0x37, 0x6d, 0x1c, 0x01, 0xaf, 0xcf, 0xe7, +0xf3, 0x82, 0x97, 0xa6, 0x69, 0x3f, 0xf8, 0x19, +0x26, 0x10, 0x04, 0x2c, 0xf1, 0x85, 0x42, 0x21, +0x1a, 0xe8, 0x70, 0x38, 0xcc, 0x00, 0x13, 0x89, +0x46, 0x63, 0x96, 0xe4, 0xf5, 0x3f, 0x24, 0x6e, +0x10, 0x96, 0x65, 0x20, 0x10, 0x4d, 0x24, 0x92, +0x36, 0x48, 0x3c, 0x8e, 0x08, 0xc3, 0xb2, 0xa9, +0x00, 0xc4, 0x12, 0xeb, 0xe9, 0x8c, 0x25, 0xd9, +0x30, 0x65, 0x19, 0xa4, 0x08, 0xa0, 0x14, 0xc1, +0x64, 0x36, 0x93, 0xc3, 0x92, 0x37, 0x60, 0x8c, +0x69, 0x5b, 0x91, 0xb7, 0xa3, 0x57, 0xfc, 0x34, +0xc3, 0xf8, 0x21, 0x18, 0x8b, 0x25, 0x73, 0x90, +0xe3, 0x38, 0x7e, 0x13, 0xb0, 0x84, 0x61, 0x53, +0x11, 0x94, 0x62, 0x3d, 0x8d, 0x52, 0x70, 0xf9, +0x7c, 0x41, 0xb0, 0x22, 0x5b, 0x1b, 0xdb, 0xef, +0x1c, 0xc3, 0x7f, 0x00, 0x98, 0x54, 0x04, 0x15, +0x9b, 0x4c, 0xa7, 0x8b, 0x1c, 0xf0, 0x85, 0x82, +0x35, 0xd9, 0x79, 0xff, 0xe1, 0x23, 0x32, 0x64, +0xc9, 0x30, 0xa8, 0xd8, 0x28, 0x2a, 0x36, 0x5b, +0x2c, 0xee, 0xf2, 0x88, 0x94, 0xcb, 0x96, 0xe4, +0xd3, 0xe7, 0x2f, 0x5f, 0xb7, 0x49, 0x92, 0x2c, +0x89, 0xc8, 0x8c, 0xa4, 0xd8, 0x83, 0x3d, 0x41, +0xa8, 0x48, 0x56, 0xe4, 0x1b, 0x32, 0xdf, 0x7f, +0x94, 0x4a, 0xa2, 0x28, 0x92, 0x36, 0x1b, 0x43, +0x66, 0x67, 0x0b, 0x5d, 0x11, 0xfb, 0x57, 0x72, +0xd9, 0x0c, 0xf7, 0x13, 0x36, 0x79, 0x41, 0x90, +0x40, 0x92, 0x65, 0x65, 0xdf, 0xea, 0xca, 0xb0, +0x38, 0xb1, 0x9f, 0x25, 0xd3, 0x4f, 0x21, 0x94, +0xcb, 0xd5, 0x0a, 0xc8, 0x35, 0x55, 0xad, 0x9f, +0x42, 0x06, 0x8d, 0x71, 0xbb, 0xf9, 0x82, 0x41, +0xaa, 0x55, 0x19, 0x14, 0xb5, 0xd1, 0x68, 0x9e, +0x42, 0x06, 0xdf, 0x85, 0xcf, 0x1b, 0xc5, 0x0a, +0x55, 0x4d, 0x53, 0xa0, 0xde, 0xf8, 0xd5, 0x6a, +0xe3, 0xc9, 0x30, 0x85, 0x82, 0x52, 0x1c, 0x34, +0x7f, 0xb7, 0x0f, 0xb1, 0xc4, 0x66, 0x63, 0xa6, +0x2b, 0x92, 0x50, 0x91, 0x25, 0xd8, 0xaf, 0xd7, +0x9b, 0x07, 0x70, 0xf8, 0x47, 0xd7, 0x8f, 0xf0, +0x0f, 0xab, 0x68, 0x5a, 0x6d, 0x98, 0x42, 0xef, +0x74, 0xba, 0xc7, 0x78, 0x22, 0x6b, 0x35, 0x54, +0x6c, 0xb3, 0xd5, 0x3a, 0xd1, 0x11, 0xe9, 0x76, +0x7b, 0x78, 0xa2, 0xa8, 0x2a, 0x2a, 0xb6, 0xdd, +0x3a, 0xe9, 0xe8, 0x70, 0xdc, 0xb5, 0x45, 0x06, +0x29, 0x74, 0x23, 0xc5, 0x51, 0xaf, 0xd7, 0xc3, +0x67, 0x39, 0x47, 0x63, 0x97, 0x63, 0x39, 0x7f, +0x01, 0x65, 0x61, 0xa4, 0xf3, 0x27, 0x1c, 0x01, +0x1c, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, +0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_merge_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_merge_png = new wxImage(); + if (!img_ex_merge_png || !img_ex_merge_png->IsOk()) + { + wxMemoryInputStream img_ex_merge_pngIS(ex_merge_png_data, sizeof(ex_merge_png_data)); + img_ex_merge_png->LoadFile(img_ex_merge_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_merge_png; +} +#define ex_merge_png_img ex_merge_png_img() + +static wxBitmap *ex_merge_png_bmp() +{ + static wxBitmap *bmp_ex_merge_png; + if (!bmp_ex_merge_png || !bmp_ex_merge_png->IsOk()) + bmp_ex_merge_png = new wxBitmap(*ex_merge_png_img); + return bmp_ex_merge_png; +} +#define ex_merge_png_bmp ex_merge_png_bmp() + +static wxIcon *ex_merge_png_ico() +{ + static wxIcon *ico_ex_merge_png; + if (!ico_ex_merge_png || !ico_ex_merge_png->IsOk()) + { + ico_ex_merge_png = new wxIcon(); + ico_ex_merge_png->CopyFromBitmap(*ex_merge_png_bmp); + } + return ico_ex_merge_png; +} +#define ex_merge_png_ico ex_merge_png_ico() + +#endif // EX_MERGE_PNG_H diff --git a/include/images/ex_merge_anti_join.png b/include/images/ex_merge_anti_join.png new file mode 100644 index 0000000000000000000000000000000000000000..7a9aa51fce9d775f169f70d115761e9817541c48 GIT binary patch literal 1599 zcmV-F2Eh4=P)9yuR$dzwN)l?a@XO2b+1mBo-1XAa^VHPz)zV?$sl-Tfk&g_HH?Tggzt>5!a!0BPe>vqlTrrz>E zyy*w1;t;Fi8m{AA#p`j)>`uPsTEXXJ#psgN?-HxxEVJZDyyl71?xMzDdY-9bilcOk z)uYE@!H+id@yYP)xAgGH^YF;;>bCFcweRV)^X|sL!S2S#@7~__q{(9I=AY~3p6~0n z@9MSb;+yH=o9W=1?&q_stmw0}>b$+})YS8(%Vg^0o#@}0=-!#`=CY>EX7KE`>f@d2 z;+*g3v*_KJ=iHa=nIz8rM-G;Z!G=R8sZm;b)sQqtRwwm?i4*wmiJfxPg9 zwO1DE-K^@}tMBB$?&H1b*{A5&r|8$F(UxcH-mK!!jp^8@;LC~N$cW#^hv34I>fNg1 z&Wz#BjNizI-^PaC#f9e6qql^BuwFj0N)yD8gyGDK=hda&#fIL*h26u1=Fy_))~4;> zyX@Y&=Fy?++qmuEyyn!T=F_C?-MZ}DxaH8H<M4bk^^05E_010qNS#tmY07w7;07w8v$!k6U00L=AL_t(Y$75g^1&mA} zfIYbTh^QEoxP+vXG?R?1oV>zd(L%ak$OthC zfTEHjsalkjl_=7pq6z{KQVqf;q(xO-LsLszRYzA(-#}H}(8$aY>#=;r%2liT=YaI|uff!^cHR07QO%vvV^i0@+sb%NdUAy<}-M4Ym{{2eGA$FjDE=UhHTY!4zPX^io z)B&`mZu!AOhdquQJ$C#=AIK|M{Q?WP{b0YGoVDuIc8}9%&YnAuJH(&>8e$htUA%PK z0=Kcc|5-M;K@_mX$%Dr zm&Q~MLtL4Gh zU%%gaeE$C9&tGD-Jbm-_-#d^0KmY#yPrDEs1=s-qCgT-R!|=q?0000bbVXQnWMOn= zI%9HWVRU5xGB7bPEip1JFfmjzFgi3dIy5vZFf}?bFgTed9smFUC3HntbYx+4Wjbwd xWNBu305UK!FfA}SEif@uGBY|fG&(RgD=;-WFfhuORjdF2002ovPDHLkV1n5vrF{SZ literal 0 HcmV?d00001 diff --git a/include/images/ex_merge_anti_join.pngc b/include/images/ex_merge_anti_join.pngc new file mode 100644 index 0000000..6bd0c99 --- /dev/null +++ b/include/images/ex_merge_anti_join.pngc @@ -0,0 +1,244 @@ +#ifndef EX_MERGE_ANTI_JOIN_PNG_H +#define EX_MERGE_ANTI_JOIN_PNG_H + +static const unsigned char ex_merge_anti_join_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x03, 0x00, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xa5, 0xa8, 0xe4, 0x66, +0x6b, 0xd1, 0xcc, 0xcd, 0xf1, 0xbc, 0xbe, 0xec, +0xbe, 0xbf, 0xed, 0xbf, 0xc1, 0xed, 0xd0, 0xd1, +0xf2, 0xd3, 0xd4, 0xf3, 0xc7, 0xc8, 0xef, 0xc8, +0xc9, 0xf0, 0xcb, 0xcb, 0xf1, 0xd9, 0xda, 0xf5, +0xdc, 0xdc, 0xf5, 0xd2, 0xd3, 0xf3, 0xd4, 0xd4, +0xf4, 0xd5, 0xd6, 0xf4, 0xe1, 0xe1, 0xf7, 0xbc, +0xbd, 0xec, 0xa6, 0xa8, 0xe6, 0xa8, 0xaa, 0xe7, +0xaa, 0xac, 0xe7, 0xc1, 0xc2, 0xee, 0xc5, 0xc5, +0xef, 0xb4, 0xb5, 0xea, 0xb6, 0xb7, 0xeb, 0xb9, +0xba, 0xec, 0xcd, 0xce, 0xf2, 0xd1, 0xd1, 0xf2, +0xc3, 0xc4, 0xef, 0xc5, 0xc6, 0xf0, 0xc7, 0xc8, +0xf0, 0xd7, 0xd7, 0xf5, 0x99, 0xbc, 0x78, 0x52, +0x8d, 0x19, 0xa1, 0xc4, 0x5e, 0x89, 0xb9, 0xdb, +0x36, 0x88, 0xc1, 0x58, 0x9c, 0xcb, 0x6f, 0xcd, +0xee, 0x45, 0xbe, 0xe9, 0x4c, 0xc0, 0xe9, 0x53, +0xc2, 0xea, 0x85, 0xd4, 0xf0, 0x94, 0xd8, 0xf0, +0x7a, 0xce, 0xec, 0x83, 0xd1, 0xed, 0x8b, 0xd4, +0xee, 0xad, 0xdf, 0xf3, 0x4d, 0xc0, 0xe9, 0x61, +0xc6, 0xeb, 0x76, 0xcd, 0xec, 0xa6, 0xde, 0xf2, +0x40, 0xbc, 0xe9, 0x07, 0xa8, 0xe2, 0x10, 0xab, +0xe2, 0x1a, 0xae, 0xe3, 0x5d, 0xc5, 0xeb, 0x71, +0xcb, 0xec, 0x4e, 0xbe, 0xe6, 0x5a, 0xc1, 0xe7, +0x64, 0xc5, 0xe8, 0x92, 0xd5, 0xef, 0x12, 0xab, +0xe2, 0x2c, 0xb3, 0xe4, 0x48, 0xbc, 0xe6, 0x89, +0xd3, 0xee, 0xa2, 0xc6, 0x5f, 0x7a, 0x9e, 0xa9, +0x62, 0x8a, 0xa3, 0x74, 0x8b, 0xd5, 0xa3, 0xc7, +0x61, 0xc1, 0x8f, 0x36, 0xf4, 0xf1, 0xc9, 0xf0, +0xec, 0xb7, 0xf4, 0xf0, 0xc8, 0xf3, 0xf0, 0xc8, +0xef, 0xea, 0xb6, 0xef, 0xe9, 0xb5, 0xef, 0xe9, +0xb4, 0xf3, 0xee, 0xc6, 0xc0, 0xc1, 0xee, 0xc6, +0xc7, 0xef, 0xde, 0xde, 0xf6, 0xa4, 0xc9, 0x62, +0xeb, 0xe6, 0x9f, 0xeb, 0xe5, 0x9e, 0xef, 0xeb, +0xb6, 0xef, 0xea, 0xb5, 0xe9, 0xe2, 0x9b, 0xe9, +0xe1, 0x9b, 0xe9, 0xe0, 0x9a, 0xee, 0xe7, 0xb3, +0xab, 0xac, 0xe8, 0xb3, 0xb4, 0xea, 0xbc, 0xbd, +0xed, 0xd4, 0xd4, 0xf3, 0xa5, 0xcb, 0x64, 0xea, +0xe4, 0x9d, 0xe8, 0xdf, 0x99, 0xe8, 0xde, 0x99, +0xee, 0xe6, 0xb2, 0xa6, 0xcd, 0x66, 0xf0, 0xec, +0xb6, 0xea, 0xe3, 0x9d, 0xea, 0xe2, 0x9c, 0xef, +0xe8, 0xb3, 0xe8, 0xdd, 0x98, 0xe7, 0xdc, 0x97, +0xed, 0xe4, 0xb0, 0xa8, 0xcf, 0x68, 0xf3, 0xed, +0xc6, 0xf2, 0xec, 0xc5, 0xed, 0xe6, 0xb2, 0xed, +0xe5, 0xb1, 0xed, 0xe3, 0xb0, 0xf1, 0xea, 0xc3, +0xa9, 0xd2, 0x6a, 0xdb, 0xbd, 0x89, 0xb5, 0x99, +0x7e, 0xab, 0xd5, 0x6c, 0xf3, 0xee, 0xc7, 0xf1, +0xeb, 0xc4, 0xec, 0xe3, 0xaf, 0xec, 0xe2, 0xae, +0xec, 0xe0, 0xad, 0xf0, 0xe7, 0xc1, 0xbf, 0x86, +0x31, 0xbf, 0x8c, 0x83, 0xb5, 0x62, 0x3f, 0xb4, +0x4b, 0x13, 0xb8, 0x65, 0x40, 0xc9, 0x95, 0x86, +0x70, 0x66, 0xb8, 0xad, 0xd7, 0x6f, 0xe8, 0xde, +0x98, 0xec, 0xe2, 0xaf, 0xe5, 0xd7, 0x93, 0xe5, +0xd5, 0x92, 0xe4, 0xd4, 0x91, 0xe4, 0xcb, 0x98, +0xb7, 0x60, 0x1b, 0xc9, 0x4d, 0x1a, 0xd7, 0x51, +0x22, 0xe1, 0x54, 0x27, 0x97, 0x54, 0x52, 0xf5, +0xe8, 0xe1, 0x67, 0x9b, 0x35, 0xa3, 0xd1, 0x66, +0x5e, 0x98, 0x25, 0xea, 0xf1, 0xe3, 0xe7, 0xdb, +0x96, 0xe6, 0xda, 0x95, 0xe4, 0xd3, 0x90, 0xe3, +0xd2, 0x8f, 0xcf, 0x95, 0x5e, 0xe2, 0x54, 0x28, +0xff, 0xff, 0xff, 0xda, 0xa6, 0x8a, 0x7b, 0xa8, +0x50, 0x9a, 0xca, 0x5d, 0x78, 0xae, 0x3e, 0xba, +0xd1, 0xa3, 0xb9, 0xec, 0x80, 0xe6, 0xda, 0x96, +0xe6, 0xd9, 0x95, 0xe5, 0xd8, 0x94, 0xeb, 0xdf, +0xad, 0xe3, 0xd2, 0x90, 0xe3, 0xd1, 0x8e, 0xe2, +0xd0, 0x8d, 0xbe, 0x68, 0x30, 0xc3, 0x70, 0x43, +0xa0, 0xc0, 0x81, 0x87, 0xba, 0x4c, 0x9c, 0xce, +0x61, 0x7a, 0xb0, 0x40, 0xba, 0xee, 0x82, 0xbb, +0xef, 0x83, 0xec, 0xe1, 0xae, 0xef, 0xe6, 0xc0, +0xea, 0xdc, 0xaa, 0xe9, 0xdb, 0xaa, 0xe9, 0xda, +0xa9, 0xb4, 0x4c, 0x14, 0xe7, 0xef, 0xdf, 0x88, +0xbd, 0x4e, 0x9e, 0xd1, 0x64, 0xab, 0xde, 0x71, +0xb8, 0xeb, 0x7f, 0xba, 0xec, 0x81, 0xbc, 0xf0, +0x84, 0xb5, 0x57, 0x16, 0xea, 0xdd, 0xac, 0xea, +0xdd, 0xab, 0xef, 0xe4, 0xbf, 0xee, 0xe3, 0xbd, +0xe9, 0xd9, 0xa7, 0xe8, 0xd7, 0xa7, 0xe8, 0xd7, +0xa6, 0xd1, 0x96, 0x67, 0xeb, 0xde, 0xac, 0xe2, +0xcf, 0x8d, 0xe9, 0xd8, 0xa7, 0xe0, 0xcb, 0x89, +0xe0, 0xc8, 0x88, 0xdf, 0xc7, 0x87, 0xe0, 0xc2, +0x91, 0xea, 0xdd, 0xaa, 0xe2, 0xce, 0x8c, 0xe1, +0xcd, 0x8c, 0xdf, 0xc8, 0x87, 0xdf, 0xc6, 0x86, +0xde, 0xc5, 0x85, 0xe6, 0xd3, 0xa3, 0xb7, 0x84, +0x80, 0xb0, 0x5e, 0x3e, 0xb2, 0x4a, 0x13, 0xc4, +0x90, 0x84, 0xe1, 0xcc, 0x8b, 0xe7, 0xd5, 0xa5, +0xde, 0xc5, 0x86, 0xde, 0xc4, 0x85, 0xdd, 0xc3, +0x84, 0xe6, 0xd1, 0xa2, 0xe8, 0xd6, 0xa6, 0xed, +0xdf, 0xbb, 0xec, 0xde, 0xba, 0xe6, 0xd1, 0xa1, +0xeb, 0xdb, 0xb8, 0xed, 0xe0, 0xbc, 0xe6, 0xd4, +0xa4, 0xe6, 0xd3, 0xa4, 0xec, 0xdd, 0xba, 0xec, +0xdc, 0xb8, 0xe5, 0xd0, 0xa1, 0xe5, 0xcf, 0xa1, +0xe5, 0xce, 0xa0, 0xeb, 0xda, 0xb7, 0xe7, 0xd4, +0xa4, 0xde, 0xc4, 0x84, 0xdc, 0xbe, 0x80, 0xdb, +0xbd, 0x7f, 0xe4, 0xcd, 0x9f, 0xdd, 0xc2, 0x83, +0xdd, 0xc1, 0x82, 0xe4, 0xce, 0xa0, 0xdb, 0xbc, +0x7e, 0xda, 0xbb, 0x7e, 0xe3, 0xcc, 0x9e, 0xdc, +0xc0, 0x81, 0xdc, 0xbf, 0x81, 0xda, 0xba, 0x7d, +0xe3, 0xcb, 0x9e, 0xe4, 0xce, 0x9f, 0xea, 0xd9, +0xb6, 0xa8, 0x9c, 0x9e, 0x5c, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, +0x47, 0x44, 0x9d, 0x06, 0xbb, 0xf2, 0xb1, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x02, 0x69, +0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0x63, 0x60, +0x18, 0x05, 0x8c, 0x4c, 0x20, 0x80, 0x42, 0x12, +0xd2, 0xc2, 0xc4, 0xcc, 0xc2, 0xca, 0xc6, 0xce, +0xc4, 0xc1, 0xc9, 0xc5, 0xcd, 0xc3, 0xc4, 0xcb, +0xc7, 0x2f, 0x20, 0xc8, 0x44, 0x50, 0x8b, 0x90, +0xb0, 0x88, 0xa8, 0x18, 0x93, 0xb8, 0x84, 0xa4, +0x94, 0x34, 0x93, 0x8c, 0xac, 0x9c, 0xbc, 0xc2, +0x60, 0xd1, 0x42, 0xba, 0x5f, 0xc8, 0x08, 0x31, +0x0a, 0x80, 0xa2, 0x92, 0x22, 0xa9, 0x5a, 0x94, +0x94, 0x95, 0x28, 0xd2, 0xa2, 0xa2, 0x0a, 0x02, +0x10, 0x52, 0x0d, 0xc2, 0x26, 0xa4, 0x45, 0x55, +0x5d, 0x43, 0x53, 0x4b, 0x5b, 0x55, 0x47, 0x57, +0x4f, 0xdf, 0x40, 0x55, 0xdd, 0xd0, 0xc8, 0xd8, +0x44, 0x95, 0xa0, 0x16, 0x53, 0x33, 0x73, 0x0b, +0x4b, 0x55, 0x2b, 0x6b, 0x1b, 0x5b, 0x3b, 0x55, +0x53, 0x7b, 0x07, 0x47, 0x27, 0xc2, 0x5a, 0x88, +0xb3, 0xc5, 0x19, 0x49, 0x8b, 0x0b, 0xd8, 0xfd, +0x10, 0xd2, 0x15, 0x1c, 0x59, 0x6e, 0xd8, 0xb4, +0xb8, 0x23, 0x69, 0xf1, 0xf0, 0xf4, 0xf2, 0xf2, +0xf2, 0xf6, 0xf0, 0xf1, 0xf5, 0xf3, 0x0f, 0xf0, +0x60, 0x0e, 0x0c, 0x92, 0x0e, 0xc6, 0x96, 0x24, +0x94, 0x42, 0x90, 0xb5, 0x78, 0x85, 0x86, 0x86, +0x85, 0x7b, 0x44, 0x44, 0x46, 0x45, 0xc7, 0x78, +0x08, 0xc5, 0xc6, 0xc5, 0x27, 0x60, 0xd5, 0x92, +0x88, 0xa2, 0x25, 0x2c, 0x2c, 0x29, 0xc2, 0xc3, +0x3f, 0x3a, 0x39, 0x25, 0x15, 0x8f, 0x96, 0x34, +0x64, 0x2d, 0xe9, 0x49, 0x19, 0x99, 0xfe, 0x1e, +0x59, 0xc9, 0xd9, 0x39, 0xb9, 0x78, 0xb4, 0xe4, +0x21, 0x6b, 0xf1, 0x89, 0xf0, 0xf3, 0xcf, 0xf7, +0x28, 0x28, 0x2c, 0x2a, 0x2e, 0xc1, 0xe3, 0x97, +0x52, 0x24, 0x2d, 0x65, 0x1e, 0x20, 0x00, 0x21, +0xcb, 0x71, 0x26, 0x6f, 0xa5, 0x0a, 0x64, 0x5b, +0x2a, 0xb3, 0x62, 0x52, 0xab, 0x3c, 0x4a, 0xaa, +0x6b, 0x6a, 0xeb, 0xea, 0x1b, 0x1a, 0x9b, 0x9a, +0x5b, 0x5a, 0xb1, 0x69, 0x69, 0x43, 0xd6, 0x12, +0xd3, 0x9e, 0x9d, 0x53, 0xec, 0xd1, 0xd1, 0xd9, +0xd5, 0xdd, 0xd3, 0xdb, 0xd7, 0x3f, 0xa1, 0xbf, +0x6f, 0xe2, 0x24, 0x4c, 0x2d, 0x93, 0xa7, 0x4c, +0x9d, 0xc6, 0x00, 0xcb, 0x03, 0x1e, 0xa9, 0x39, +0xd3, 0x67, 0x74, 0x78, 0xd4, 0x76, 0xcd, 0x9c, +0x35, 0xbb, 0x6f, 0xce, 0x9c, 0xb9, 0x73, 0xe7, +0xf4, 0xcd, 0xc3, 0xd4, 0x32, 0x7f, 0xc1, 0xc2, +0x45, 0x40, 0x3d, 0x4a, 0x8b, 0x41, 0x7a, 0x3c, +0x72, 0x97, 0x2c, 0x5d, 0x56, 0xeb, 0xb1, 0x7c, +0xc5, 0xca, 0x55, 0xab, 0xfb, 0xe7, 0x80, 0xf4, +0xf4, 0xaf, 0xc1, 0xd4, 0xb2, 0x76, 0xdd, 0xfa, +0x0d, 0x53, 0x95, 0x94, 0x94, 0x36, 0x6e, 0x02, +0xea, 0xf1, 0x28, 0xe9, 0xd8, 0x5c, 0x5b, 0xe7, +0xb1, 0x65, 0xeb, 0xb6, 0xed, 0x4d, 0x13, 0xe6, +0x82, 0xf4, 0x4c, 0xd8, 0x81, 0xa9, 0x65, 0xe7, +0xda, 0x5d, 0xbb, 0xf7, 0xec, 0xdd, 0xb7, 0x71, +0xd3, 0xfe, 0xfd, 0x4a, 0xc8, 0x21, 0x76, 0xa0, +0x7f, 0x2e, 0x48, 0x0f, 0x36, 0x5b, 0x80, 0x7a, +0xe6, 0x4f, 0x06, 0xda, 0x02, 0xd4, 0x01, 0xb4, +0xa5, 0x6e, 0xf9, 0xc1, 0x43, 0x87, 0x3d, 0x8e, +0x1c, 0x3d, 0x76, 0xfc, 0x44, 0x1f, 0xc8, 0x2b, +0x58, 0xfd, 0x02, 0x0b, 0xb8, 0xfd, 0x60, 0xbf, +0x9c, 0x9c, 0xb5, 0xea, 0xd4, 0x76, 0x8f, 0xd3, +0x67, 0xce, 0x9e, 0x3b, 0x8f, 0x3b, 0xc4, 0xa0, +0x00, 0x1a, 0x62, 0x17, 0x4e, 0x5d, 0xbc, 0x74, +0xda, 0xe3, 0xf8, 0xe5, 0x2b, 0x57, 0xaf, 0xd5, +0x5f, 0xbf, 0x71, 0xb3, 0xf1, 0x56, 0x2b, 0x03, +0x01, 0xe0, 0xb1, 0xed, 0xd2, 0xed, 0x33, 0xc7, +0x3d, 0xee, 0xdc, 0xbd, 0x77, 0xff, 0x01, 0xee, +0x34, 0x86, 0xaa, 0xe5, 0xc8, 0xe9, 0x63, 0x0f, +0x1f, 0x79, 0x3c, 0xbe, 0xf6, 0xe0, 0xc9, 0x53, +0xdc, 0x69, 0x0c, 0x05, 0x10, 0x97, 0xc6, 0x50, +0x6d, 0x79, 0x76, 0xe7, 0xf9, 0x8b, 0x97, 0x1e, +0xaf, 0x5e, 0xbf, 0x79, 0xfb, 0x8e, 0x48, 0x5b, +0x3c, 0xde, 0x5f, 0xfd, 0x70, 0xff, 0x89, 0xc7, +0x9b, 0x8f, 0x9f, 0x3e, 0x7d, 0x26, 0xd6, 0x2f, +0xd7, 0xee, 0x7f, 0xf9, 0xfa, 0xda, 0xe3, 0xdb, +0xa7, 0xef, 0x3f, 0x7e, 0x12, 0xab, 0xe5, 0xc1, +0xd7, 0x5f, 0xbf, 0xdf, 0x7a, 0x7c, 0xfe, 0xfe, +0xe3, 0xcf, 0x5f, 0x62, 0xb5, 0x3c, 0x7d, 0xf3, +0xf6, 0xdf, 0x3b, 0x8f, 0xff, 0x3f, 0xff, 0xfe, +0xfd, 0x4f, 0xbb, 0x10, 0x1b, 0x05, 0xd8, 0x01, +0x00, 0x26, 0xe3, 0x15, 0x51, 0xc3, 0xf0, 0xc4, +0xd2, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, +0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_merge_anti_join_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_merge_anti_join_png = new wxImage(); + if (!img_ex_merge_anti_join_png || !img_ex_merge_anti_join_png->IsOk()) + { + wxMemoryInputStream img_ex_merge_anti_join_pngIS(ex_merge_anti_join_png_data, sizeof(ex_merge_anti_join_png_data)); + img_ex_merge_anti_join_png->LoadFile(img_ex_merge_anti_join_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_merge_anti_join_png; +} +#define ex_merge_anti_join_png_img ex_merge_anti_join_png_img() + +static wxBitmap *ex_merge_anti_join_png_bmp() +{ + static wxBitmap *bmp_ex_merge_anti_join_png; + if (!bmp_ex_merge_anti_join_png || !bmp_ex_merge_anti_join_png->IsOk()) + bmp_ex_merge_anti_join_png = new wxBitmap(*ex_merge_anti_join_png_img); + return bmp_ex_merge_anti_join_png; +} +#define ex_merge_anti_join_png_bmp ex_merge_anti_join_png_bmp() + +static wxIcon *ex_merge_anti_join_png_ico() +{ + static wxIcon *ico_ex_merge_anti_join_png; + if (!ico_ex_merge_anti_join_png || !ico_ex_merge_anti_join_png->IsOk()) + { + ico_ex_merge_anti_join_png = new wxIcon(); + ico_ex_merge_anti_join_png->CopyFromBitmap(*ex_merge_anti_join_png_bmp); + } + return ico_ex_merge_anti_join_png; +} +#define ex_merge_anti_join_png_ico ex_merge_anti_join_png_ico() + +#endif // EX_MERGE_ANTI_JOIN_PNG_H diff --git a/include/images/ex_merge_append.png b/include/images/ex_merge_append.png new file mode 100644 index 0000000000000000000000000000000000000000..12fc55d76f504140935d5fa422f9a5075431bbc3 GIT binary patch literal 980 zcmV;_11tQAP)8zdY-9xu0FMyetNM%gs???v_por zNkF{mMZW2fwrozm=1joprKsemspnI|>RQ3)jlolwyLFkoc&e=DiMiWd#p`6n=&rBn zp~POI$6%JsU2)6oq{?G&&F-hoW_r%-+rEF>y@|ZN?A*VB+`xgozwN%i?cKqGgVF8X z!h^rT?cT(M!ou!_)bQTLg~G${i`4Gl$A*&C@5RRNy3wP>#_+D%ag^Bb;mnHS&yCB> z@#M{(=8)Dj2~+?VOvsp{Fb*xB^D z?t)x#C;hXH;y6fMq?B2TS;+*W@t?c2h>g1i+<;(2i zukGQy?BlQOcjBtw(#t?^6bU)?Z)%($Mo^Z1Vq=200001bW%=J06^y0W&i*H32;bRa{vGf z6951U69E94oEQKA0kKI$K~zY`?UPkg!$1^;v)KUULUEU1#ogWAouV!7?ykih{xC_% z08P8uzzo9+=i$EWd~@#Ev&%65`jNspQS#J=aPdC=LHS%|Vph=rrxEdXaCDB~V*P?6 zOSoTiagtKVQ(H*3K0T*!kezPn9y(&R*|RBuD5{jL$;c}oWwnJQBj0x+hE!(ZG4|b2 z56J|uqU6ai*kJH@XNdN;E;@msASoyeeLdlI2K-Hg!O>Vfiyb6RLfk-BaV2;4y5! zFcp^>3gRlIkf(HCo=X%&Q8JG`mtuU?vnWc&GXk+=|5)+K-bO1R(MTt0_mbAQjO zbuYw{VGA{*NiY=`WVb62QpvD}s*xFtx!GwA)=08cuRN`gIaG!Ep))fzsaD}aS{Y79 zOvZIsXsWB7QXr(2iS{Zh6GdK`j1X5QioEi_{zPxhzn!H%4w>%&0000IsOk()) + { + wxMemoryInputStream img_ex_merge_append_pngIS(ex_merge_append_png_data, sizeof(ex_merge_append_png_data)); + img_ex_merge_append_png->LoadFile(img_ex_merge_append_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_merge_append_png; +} +#define ex_merge_append_png_img ex_merge_append_png_img() + +static wxBitmap *ex_merge_append_png_bmp() +{ + static wxBitmap *bmp_ex_merge_append_png; + if (!bmp_ex_merge_append_png || !bmp_ex_merge_append_png->IsOk()) + bmp_ex_merge_append_png = new wxBitmap(*ex_merge_append_png_img); + return bmp_ex_merge_append_png; +} +#define ex_merge_append_png_bmp ex_merge_append_png_bmp() + +static wxIcon *ex_merge_append_png_ico() +{ + static wxIcon *ico_ex_merge_append_png; + if (!ico_ex_merge_append_png || !ico_ex_merge_append_png->IsOk()) + { + ico_ex_merge_append_png = new wxIcon(); + ico_ex_merge_append_png->CopyFromBitmap(*ex_merge_append_png_bmp); + } + return ico_ex_merge_append_png; +} +#define ex_merge_append_png_ico ex_merge_append_png_ico() + +#endif // EX_MERGE_APPEND_PNG_H diff --git a/include/images/ex_merge_semi_join.png b/include/images/ex_merge_semi_join.png new file mode 100644 index 0000000000000000000000000000000000000000..6ce4839e02fd3f17b5fd8e358ff204046c38d26f GIT binary patch literal 1344 zcmY+CSx{347==TqEn;1Yb)kzRwvO5s8xTS1=pdpEBQS_s6{;)(R?#BJSj4Jq3RJBX zQDkYPh!_@AR0IrxkdTEC5=cT4vWF~}EH}AX?oB|$Ort*a;rwUL%=w=FQ>;#h1oUczW7R8US1I0KR>uy>o^_wbJQO_e)bxulW@b(HS=8h)pa;>PUr2w*vp69j|&N3$LV{>k!lrt7&peF2@=_WK3t6FL1zCrK1;c zH7nuAD!5GzQ;lwx*-Zivior!Ux61lETNxJ+QH5ZZ2v>;w(c zr$;)~&Sx6uh{@f|NG-y(<=?}pne`Kl{^u_ZM7rq_Go5lf9JaG;VDH?l&W*_Qz^qE` z(rDcPFl)8GZeeAZfrp4=T%kmSLZ?ImE0ivyaqclYvz3#LAOEF|e_A$BCFnXQ9V7Dv z_73408`uMxdz=u{jY#L*+Na`NlkRVmw$Z4rw*oIq zZCA}es>*=`951s&nb&8&N(4(twsIRVWR$lXrFet*iAB}#cBo*>Bn%3iW`PS*7^Q7$ z_8+Q|3MKs-z-xxVNk~tFw8K^n)nS-0h+9>R>&oGB1*KF!-sCj%Aq~|!O|hzn95ds< zWQ&4YCLb!14P4c6a1JBSs-{>}Ll!034sgw~K0UWdJBBk&^&l3R0~ojKxv*KPW#gp8 z%b+~h4>dY zSFdYJuBo}Vk>A|xk3MZ$+vF3p@YH_cBwxfkBosto!jdAwL$+=?ya7+A@<*k6g(9w! zvR@G^meB8Yt<;>!+s)T3aowoc;8%FDtaxd7@E|tXz%K`%f)vG>Tv0{ZT@XO_&ueyC`AKI845G$^ZA*NQ}>28@ViTY+6jXxB0|Ihe+ zAGQbA9hF3-ZM7wVqPyI&zbynjb2^vgu!ZXGXE!his~s5{t;!8Lhxdd2+H$ z`a^M1P2{d350QAO=#A%f!-lxV@)Wji(}5@Phm(@(Lzd&2xj)T=+t1GfFXQUTsNU3- z3CFt&S^TUm*_%@dF`1PP?D=^xPs_+6o5h4r&fZYnYKX{H+WIe;MNe~RudnS)#<~{;28H`~ zp;7y0eV6*_*%98?uP@khq#!fBAS?1jewNozp_mX%a7bt{Cgfl!CNgYGWLVg@n5~f* t%(lAqYyJnE&CNWOeepej+5QfA+m6J9zXwKZ4|RG0RP3IF7(#Sf>3IsOk()) + { + wxMemoryInputStream img_ex_merge_semi_join_pngIS(ex_merge_semi_join_png_data, sizeof(ex_merge_semi_join_png_data)); + img_ex_merge_semi_join_png->LoadFile(img_ex_merge_semi_join_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_merge_semi_join_png; +} +#define ex_merge_semi_join_png_img ex_merge_semi_join_png_img() + +static wxBitmap *ex_merge_semi_join_png_bmp() +{ + static wxBitmap *bmp_ex_merge_semi_join_png; + if (!bmp_ex_merge_semi_join_png || !bmp_ex_merge_semi_join_png->IsOk()) + bmp_ex_merge_semi_join_png = new wxBitmap(*ex_merge_semi_join_png_img); + return bmp_ex_merge_semi_join_png; +} +#define ex_merge_semi_join_png_bmp ex_merge_semi_join_png_bmp() + +static wxIcon *ex_merge_semi_join_png_ico() +{ + static wxIcon *ico_ex_merge_semi_join_png; + if (!ico_ex_merge_semi_join_png || !ico_ex_merge_semi_join_png->IsOk()) + { + ico_ex_merge_semi_join_png = new wxIcon(); + ico_ex_merge_semi_join_png->CopyFromBitmap(*ex_merge_semi_join_png_bmp); + } + return ico_ex_merge_semi_join_png; +} +#define ex_merge_semi_join_png_ico ex_merge_semi_join_png_ico() + +#endif // EX_MERGE_SEMI_JOIN_PNG_H diff --git a/include/images/ex_nested.png b/include/images/ex_nested.png new file mode 100644 index 0000000000000000000000000000000000000000..15c47316d5d4163d97b95cda99b2e3a2049341c5 GIT binary patch literal 1108 zcmV-a1grarP)mel+$nVI> z@W{&W%FFS~%<;_4^3Bfj&d%}9&+^dF^3v1u)YS9U)%4fb^{cMtuCeH+s^-7I?YX<_ zv9sxtmEUxE)|i{&!NTpPsL;d2(7e9v+1d5IzwF1wx2vUWos>nDi!Y6V8N`~o8Rb}-shO$=$_f!mC@3Tzr1kL*o)26 zebU;8+TxSc+KR}^cFoU%&Cc<&uw0mqEU~Ov&d-F$$aBxniISDkwXlcC#=6 zhS%DTytZrH;g{Fej@H)nL!K(600001bW%=J06^y0W&i*H32;bRa{vGUNB{r;NB~C3 zYd!z~0t-n*K~zY`?bYj3+CUHha0E^Sm0C-!f`UTD2bF{cA89RMMd}k-_8X`@6D zMDcCwzpmmq!zFho^0nPBncU28_IB=WSEKnK57DI6=@B#ZI&Bj!nhh;RQ)^pWyU}cZ z)A6?RoyGFL>qB>s)oQibdVBlq-DU@7w9Wkk{RS54bh=CqZ4J>G20jkDS^IJi4ZF;` z8lrbO21iC&#g2{)nR@g!3&`nlGsS~(TRx#$;_)EO3xVtkGWPWA<#-<`!pC#oDzTG@ zm-7e4Cnl!^LHPV-`fD&4425UD%|;##g>e44==XU{gcqWVOA$^@mY1u)d>}fv62tcu zi?6P&^D2@+DDn7(31MX;iI<(+h;RM?6?qPr6kSj{rZgGJZ_B{3m6ZPJE}8xcZ5m`Oke+!p|05UK!FfB1MEif@uGB7$c zGdeUhD=;-WFfcfoB_03(03~!qSaf7zbY(hiZ)9m^c>ppnF)%GKIV~_TR5CLIsOk()) + { + wxMemoryInputStream img_ex_nested_pngIS(ex_nested_png_data, sizeof(ex_nested_png_data)); + img_ex_nested_png->LoadFile(img_ex_nested_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_nested_png; +} +#define ex_nested_png_img ex_nested_png_img() + +static wxBitmap *ex_nested_png_bmp() +{ + static wxBitmap *bmp_ex_nested_png; + if (!bmp_ex_nested_png || !bmp_ex_nested_png->IsOk()) + bmp_ex_nested_png = new wxBitmap(*ex_nested_png_img); + return bmp_ex_nested_png; +} +#define ex_nested_png_bmp ex_nested_png_bmp() + +static wxIcon *ex_nested_png_ico() +{ + static wxIcon *ico_ex_nested_png; + if (!ico_ex_nested_png || !ico_ex_nested_png->IsOk()) + { + ico_ex_nested_png = new wxIcon(); + ico_ex_nested_png->CopyFromBitmap(*ex_nested_png_bmp); + } + return ico_ex_nested_png; +} +#define ex_nested_png_ico ex_nested_png_ico() + +#endif // EX_NESTED_PNG_H diff --git a/include/images/ex_nested_loop_anti_join.png b/include/images/ex_nested_loop_anti_join.png new file mode 100644 index 0000000000000000000000000000000000000000..c1c0763337617f9ffe8cf13ba0f47f4cbc228c5e GIT binary patch literal 1741 zcmV;;1~U1HP)-np$=8KNpd41PrYtf>m5`V; zba>TudDfVl;lRP|xVr1a#qMv-?nS=oOu*?=!s><8@RZo_dd}>F(d~=W?ycYRy1eVG zuIIwU?d=JclL^r_X^k;1`s>*k-lz3i*3=(DuyyuIzz)brEXi_X=6)7*yR z@}1)Fn#|LB(bkE)wI zTi@!H;_9L1^rM-NE%ET<;OUv$y@|D%e&zF`-4wXg1j0)t|Ru8_7)?*HI$j zR412IQuXNJ!o%*Zuj$3b@7mvzfv!Sxr8k+pc<<}B@94ABoNVG$DF6Te+NO%UzUZ#Y*jEuliF>JI z+IZ&awbj*$@8iDc*r(^!rR?6izl?*pWkAW5hS=YV*W8HI)Qi;9hvm?rfYsIXCi79B00001bW%=J06^y0 zW&i*H0b)x>M61aGXD9#w010qNS#tmY07w7;07w8v$!k6U00Q?(L_t(Y$75g^@qm$u znS~VvurM<*;@82(&cVsW&B?>d$1fl#BrGB-CN6rMV>tM72f}Z%Z3QOLTh>(SGUZ0BdRQ#HyvMyQjCW zf5JqF4qi8qo=HJLlR#QJC&RT&nK})sW%`Vnvu4kkJ7@O1`5+w&7A{Zd_RI3+D^|{4wQBY1RkPOsB}LXQTqq|BcSg|Sb#N`ymagBh3>sn^=d1$hnX?J( z6Il(UzzbTp8R3^@8@6l(+Olo?j-7pTSA+D-?L$g1Fu!cxg|KDA?ma+Tym#!~xBtML z)gV0}TVPry1syyH(i61n5W+8q_kjJfbKjAp$7X}P0`?13%cP*1<0no6^#mO{g%M(> z&zwDX9uZtC`ulF)n#h1;OVI5*Am0RCzDqcb zLA?(NU522$_b_a^e*gZ1hgfoD(7H!pEsq~#Xu1F7>9glpa%IqqLob1e|K(#0hj~AE z_UaWjErF%4-vG1N+js8+(X~8(go<&y{Qdd!=ijmT#s9~bukU{T z`u*pJKd~X^=l|o|`@4Vt{lF}gaM^;V=)>X{ECuX;{93RTIsOk()) + { + wxMemoryInputStream img_ex_nested_loop_anti_join_pngIS(ex_nested_loop_anti_join_png_data, sizeof(ex_nested_loop_anti_join_png_data)); + img_ex_nested_loop_anti_join_png->LoadFile(img_ex_nested_loop_anti_join_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_nested_loop_anti_join_png; +} +#define ex_nested_loop_anti_join_png_img ex_nested_loop_anti_join_png_img() + +static wxBitmap *ex_nested_loop_anti_join_png_bmp() +{ + static wxBitmap *bmp_ex_nested_loop_anti_join_png; + if (!bmp_ex_nested_loop_anti_join_png || !bmp_ex_nested_loop_anti_join_png->IsOk()) + bmp_ex_nested_loop_anti_join_png = new wxBitmap(*ex_nested_loop_anti_join_png_img); + return bmp_ex_nested_loop_anti_join_png; +} +#define ex_nested_loop_anti_join_png_bmp ex_nested_loop_anti_join_png_bmp() + +static wxIcon *ex_nested_loop_anti_join_png_ico() +{ + static wxIcon *ico_ex_nested_loop_anti_join_png; + if (!ico_ex_nested_loop_anti_join_png || !ico_ex_nested_loop_anti_join_png->IsOk()) + { + ico_ex_nested_loop_anti_join_png = new wxIcon(); + ico_ex_nested_loop_anti_join_png->CopyFromBitmap(*ex_nested_loop_anti_join_png_bmp); + } + return ico_ex_nested_loop_anti_join_png; +} +#define ex_nested_loop_anti_join_png_ico ex_nested_loop_anti_join_png_ico() + +#endif // EX_NESTED_LOOP_ANTI_JOIN_PNG_H diff --git a/include/images/ex_nested_loop_semi_join.png b/include/images/ex_nested_loop_semi_join.png new file mode 100644 index 0000000000000000000000000000000000000000..d0e8a17d409343ea937e43ebb76e8ebce3cbee49 GIT binary patch literal 1679 zcmV;A25|X_P)-np$=8KNpd41PrYtf>m0!p}cFpXj-txER_NL$Tu;TT) z=JnF<_`1C7tgh$6#O>_u`M<#JK)mS^tKuxPGr_E z?!CY5b9mKtde+Ix@Y&h**4Fgb*Y&BOdclu2o|AU6wdkn39S_}}36;^X(`=J@XJ`oh9?)!UTb=bh&Crswpj)Yy>1!FB8ApWWW|)z$Oa z+4SAs_UY;Q)7gv8)qvC7hU4;`;_#Zx(|Xa?iNU~h&Cc=8&+*mTkJe;uUp^il;Z25=JcbPk1g@=BYtG+TW6au0nIAH<`S6@9Vbj>b39av-9o7yuR$&-H@lxXLhSQxVh}u+>fx` zbW)8O?&h-X<+1GIukh!=*V>J;;C6bkLFU<&<<^tr(~#=is^sgb)x#5(2e2Ei{Q$M=hmg^@4C|3c;@M~)zyjb ze#luw`{_{ZP3qu&(3_myJ*M5c)Yf2*42*6#(>q;^w`+-+(*1K~zY`V_+Bsj7-cdtSEqmnTZj<4mNfU zPA+av9$r3v0YM>Q5m7O53A}ok*d(PSrIEGp$jHh`Fu@hbD}aEa5(p@RMVM8jRMpgx z-KC+arLDsZ*P@`Sr*B}WU}S7!YNiAhVKKK*v$R6C*UD1UT95^y#m3go-a*09$=Ssf zqJ`DX-NOpityZ31-mG|RVRd(BWk3V0KE4PsKYtJi2n2y3s1_NpbZ|&$Sa^77NHDq< z|A@%Q$O!+a=$P2JKx8e!A@K=`Ny#axAU&vBBGb~+BK^}dGPAN#w1mXxjE3c@msw}Fm2_>kdmX);@NQEcYRn|AuH#Rkg6Z8udgtz3kwlTD|ws)Xw z=>&&Z7dXVaQMB~*hJ&cSe&TJJ0MXJvF`Q_>OqvANGI26iEmM%R)Uxt=f%Hrb51$Is zGI<(Y%k&vDp;~6mo`cX*%Q|=7y!l{zAnu#C0Ip@m!bOY0ep#|~*>Z$mSVdOMn`bQw zcSiVvm2fRH7p+>o7&F9xK3Sv9ie$^mwFti~UcGKT(3a&JHg4LCC5^%SvUUr?mepIg z0d4W$xP8aYU6^TXYWVIwAU)w*_9FbUZyVSzoAw_#cnCww)bPVcjvfQ*3Ez7hBg9Ue zJazgEhL-TN6OW!-a6X(N{P+coc)57!%%#g1egXRA%2kkW!Y^DSoW`KuhlDOe__ga8 zwp_k(^VV%FAr`*!4p__GyBJz--n;+cA(mVj{%G%GVB&vr_bG;!ThE?9$EGE$=EX~3 z7JK#jO&GeChtIKV34QzS{i_eJK7RU)k&(YVeE9GS7Qcji{rK(m_a8rh{SF~E#DYV< zetz@x&)?seg%U1X@DzPm{DP%`{fA!*wqpF>e|%c7Ru(cyl?A3>2v$j$Ax5y`!vthh zuVhr>BNzYx`KOJp(wB}a0000bbVXQnWMOn=I%9HWVRU5xGB7bPEip1JFfmjzFgi3d zIy5vZFf}?bFgTed9smFUC3HntbYx+4WjbwdWNBu305UK!FfA}SEif@uGBY|fG&(Rg ZD=;-WFfhuORjdF2002ovPDHLkV1g+E(G&mx literal 0 HcmV?d00001 diff --git a/include/images/ex_nested_loop_semi_join.pngc b/include/images/ex_nested_loop_semi_join.pngc new file mode 100644 index 0000000..abcbf7c --- /dev/null +++ b/include/images/ex_nested_loop_semi_join.pngc @@ -0,0 +1,254 @@ +#ifndef EX_NESTED_LOOP_SEMI_JOIN_PNG_H +#define EX_NESTED_LOOP_SEMI_JOIN_PNG_H + +static const unsigned char ex_nested_loop_semi_join_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x03, 0x00, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xea, 0xeb, 0xf9, 0xab, +0xae, 0xe6, 0x8b, 0x8e, 0xdc, 0x79, 0x7d, 0xd7, +0x66, 0x6b, 0xd1, 0xa2, 0xa5, 0xe4, 0xb7, 0xb8, +0xea, 0xbd, 0xbf, 0xec, 0xc5, 0xc6, 0xef, 0xc3, +0xc4, 0xef, 0xc4, 0xc5, 0xef, 0xc7, 0xc8, 0xef, +0xc8, 0xc9, 0xf0, 0xca, 0xcb, 0xf0, 0xcb, 0xcc, +0xf1, 0xcc, 0xcd, 0xf2, 0xce, 0xce, 0xf2, 0xcf, +0xd0, 0xf2, 0xd1, 0xd1, 0xf2, 0xd3, 0xd3, 0xf3, +0xd5, 0xd6, 0xf4, 0xcd, 0xcd, 0xf1, 0xc3, 0xc4, +0xee, 0xab, 0xad, 0xe6, 0xaf, 0xb2, 0xe8, 0xa8, +0xaa, 0xe6, 0xb9, 0xb9, 0xea, 0xbe, 0xbf, 0xed, +0xb8, 0xb9, 0xeb, 0xbf, 0xc0, 0xec, 0x89, 0xb9, +0xdb, 0x36, 0x88, 0xc1, 0x70, 0xab, 0xd3, 0x9a, +0xc3, 0xe0, 0xc4, 0xdc, 0xed, 0xb5, 0xb7, 0xea, +0xb2, 0xb4, 0xe9, 0x92, 0x96, 0xdf, 0x74, 0x78, +0xd5, 0x75, 0x79, 0xd6, 0x98, 0x9b, 0xe1, 0xc0, +0xc1, 0xed, 0xb8, 0xba, 0xeb, 0xc4, 0xc5, 0xee, +0x6f, 0xcd, 0xee, 0x4d, 0xc0, 0xe9, 0x61, 0xc6, +0xeb, 0x76, 0xcd, 0xec, 0xa6, 0xde, 0xf2, 0xb7, +0xe6, 0xf6, 0xa6, 0xdf, 0xf4, 0xb0, 0xe2, 0xf5, +0xba, 0xe6, 0xf5, 0xd2, 0xee, 0xf8, 0xba, 0xbc, +0xeb, 0xac, 0xae, 0xe7, 0xc2, 0xc4, 0xed, 0xec, +0xed, 0xf9, 0xbf, 0xc0, 0xed, 0x40, 0xbc, 0xe9, +0x12, 0xab, 0xe2, 0x2c, 0xb3, 0xe4, 0x48, 0xbc, +0xe6, 0x89, 0xd3, 0xee, 0x9f, 0xdd, 0xf4, 0x88, +0xd5, 0xf0, 0x95, 0xd9, 0xf1, 0xa3, 0xdd, 0xf2, +0xc4, 0xe9, 0xf6, 0xc0, 0xc1, 0xee, 0xbd, 0xbf, +0xed, 0x73, 0x78, 0xd5, 0x75, 0x7a, 0xd6, 0xc9, +0xca, 0xf0, 0xd9, 0xd9, 0xf5, 0xd6, 0xd6, 0xf4, +0xd7, 0xd7, 0xf5, 0xa9, 0xa0, 0x7a, 0xc1, 0x8f, +0x36, 0x9e, 0x93, 0x76, 0xb2, 0xb5, 0xe8, 0xa8, +0xbb, 0xe4, 0xef, 0xee, 0xdf, 0xc0, 0xba, 0x81, +0xa8, 0x9f, 0x50, 0x9b, 0x90, 0x35, 0x8d, 0x81, +0x19, 0xf4, 0xf1, 0xc9, 0xf0, 0xec, 0xb7, 0xe5, +0xe6, 0xf8, 0xdf, 0xe0, 0xf6, 0xe2, 0xe3, 0xf7, +0xe6, 0xe6, 0xf8, 0xee, 0xee, 0xfa, 0xc2, 0xc2, +0x76, 0xd5, 0xdb, 0x94, 0xde, 0xe7, 0x9d, 0xe6, +0xf4, 0xa6, 0xe7, 0xf4, 0xa9, 0xd4, 0xd8, 0x90, +0xc2, 0xc1, 0x75, 0xeb, 0xe6, 0x9f, 0xdd, 0xde, +0xf5, 0xd5, 0xd5, 0xf3, 0xd9, 0xd9, 0xf4, 0xdd, +0xde, 0xf6, 0xe9, 0xe9, 0xf9, 0xd3, 0xd9, 0x8b, +0xce, 0xd5, 0x80, 0xd3, 0xdc, 0x86, 0xe3, 0xf2, +0x9d, 0xe2, 0xf0, 0x9a, 0xcc, 0xd3, 0x7a, 0xd1, +0xd6, 0x89, 0xc1, 0xc0, 0x74, 0xcd, 0xce, 0xf1, +0xce, 0xcf, 0xf1, 0xd5, 0xda, 0x91, 0xcd, 0xd5, +0x7c, 0xd4, 0xda, 0x8d, 0xb4, 0xb0, 0x5c, 0xa3, +0x9c, 0x3f, 0xca, 0xd1, 0x79, 0xd3, 0xd5, 0x8d, +0xa5, 0xa8, 0xe4, 0xe4, 0xf3, 0x9c, 0xd1, 0xcd, +0xa3, 0xe5, 0xe2, 0xcb, 0xb3, 0xaf, 0x5b, 0xdf, +0xeb, 0x94, 0xe2, 0xeb, 0xa1, 0xe6, 0xf4, 0xa3, +0x99, 0x8f, 0x2d, 0xf1, 0xf0, 0xe3, 0xdf, 0xe9, +0x95, 0xe0, 0xe9, 0x99, 0xdb, 0xbd, 0x89, 0xc8, +0xab, 0x83, 0xd2, 0xd3, 0xf1, 0xe5, 0xf3, 0xa2, +0xe4, 0xf1, 0xa0, 0xdf, 0xe8, 0x98, 0xde, 0xe7, +0x98, 0xe4, 0xf2, 0xa1, 0xdd, 0xe5, 0x96, 0xeb, +0xf4, 0xb7, 0xdd, 0xe3, 0x95, 0xf0, 0xec, 0xb6, +0xbc, 0xb5, 0x78, 0xdb, 0xe1, 0x93, 0xde, 0xea, +0xd4, 0x97, 0xbb, 0x75, 0xba, 0xd1, 0xa3, 0xeb, +0xe5, 0x9e, 0xea, 0xe4, 0x9d, 0xef, 0xe9, 0xb4, +0xc2, 0xc3, 0xee, 0xad, 0xaf, 0xe9, 0xc5, 0xc5, +0xef, 0xda, 0xdf, 0x92, 0x81, 0xae, 0x42, 0x73, +0xa5, 0x37, 0x99, 0xbc, 0x78, 0xef, 0xeb, 0xb6, +0xef, 0xea, 0xb5, 0xef, 0xe8, 0xb3, 0xf3, 0xed, +0xc6, 0xbc, 0xbe, 0xec, 0xd9, 0xdd, 0x90, 0xa7, +0xcf, 0x67, 0x76, 0xab, 0x3b, 0xb8, 0xb9, 0xec, +0xd8, 0xdc, 0x8f, 0xb0, 0xdd, 0x74, 0x52, 0x8d, +0x19, 0xee, 0xe6, 0xb2, 0xed, 0xe5, 0xb1, 0xec, +0xe2, 0xaf, 0xf0, 0xe7, 0xc1, 0xd7, 0xda, 0x8d, +0xb2, 0xe0, 0x76, 0x7a, 0xb1, 0x41, 0xe6, 0xd9, +0x95, 0xe5, 0xd6, 0x93, 0xe4, 0xd3, 0x90, 0xea, +0xdc, 0xaa, 0xe4, 0xeb, 0xa9, 0xe3, 0xe9, 0xa8, +0xd7, 0xd8, 0x8c, 0x8c, 0xc0, 0x52, 0xe4, 0xd5, +0x91, 0xe3, 0xd2, 0x8f, 0xe2, 0xce, 0x8c, 0xe9, +0xd8, 0xa7, 0xe1, 0xe9, 0xa0, 0xd5, 0xde, 0x7c, +0xd4, 0xdc, 0x7a, 0xde, 0xe4, 0x9c, 0xd6, 0xd7, +0x8a, 0xeb, 0xde, 0xac, 0xe2, 0xd0, 0x8d, 0xe1, +0xcd, 0x8b, 0xe0, 0xca, 0x89, 0xe7, 0xd6, 0xa5, +0xe9, 0xef, 0xba, 0xd2, 0xda, 0x78, 0xe6, 0xe9, +0xb5, 0xd5, 0xd5, 0x89, 0xef, 0xe3, 0xbe, 0xe6, +0xd4, 0xa4, 0xec, 0xde, 0xba, 0xd8, 0xdf, 0x8a, +0xd7, 0xdc, 0x88, 0xd4, 0xd4, 0x89, 0xd4, 0xd3, +0x87, 0xe6, 0xd1, 0xa2, 0xe5, 0xd0, 0xa1, 0xe4, +0xce, 0x9f, 0xeb, 0xd9, 0xb6, 0xd8, 0xdb, 0x8d, +0xd3, 0xd2, 0x86, 0xdc, 0xbe, 0x80, 0xdb, 0xbc, +0x7e, 0xda, 0xbb, 0x7d, 0xe3, 0xcb, 0x9e, 0xd9, +0xdd, 0x93, 0x98, 0x8d, 0x2c, 0x97, 0x8d, 0x2b, +0xd4, 0xd4, 0x8b, 0xda, 0xbb, 0x7e, 0xda, 0xba, +0x7d, 0xc7, 0xc6, 0x74, 0xb0, 0xa9, 0x56, 0xaf, +0xa7, 0x55, 0xc5, 0xc2, 0x70, 0xd0, 0xcd, 0x88, +0xcd, 0xcb, 0x87, 0xc3, 0xc0, 0x6e, 0xc9, 0xc6, +0x7e, 0xa0, 0x97, 0x3b, 0xc8, 0xc5, 0x7a, 0xc1, +0xbd, 0x6b, 0xcb, 0xc8, 0x84, 0xea, 0xd8, 0xb6, +0xbd, 0xb7, 0x6c, 0xc2, 0xbf, 0x6d, 0xd0, 0xcf, +0x7f, 0xcf, 0xce, 0x7c, 0xbf, 0xbb, 0x68, 0xc7, +0xc3, 0x78, 0xbc, 0xb6, 0x6b, 0xd6, 0xd5, 0x8e, +0xca, 0xc6, 0x80, 0xd5, 0xd5, 0xf4, 0xd8, 0xd8, +0xf5, 0xdc, 0x7c, 0xd9, 0x75, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0xc6, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0x63, 0x60, 0x18, 0x05, 0x8c, 0x4c, 0xcc, +0x2c, 0xac, 0x28, 0x80, 0x85, 0x99, 0x89, 0x11, +0xbf, 0x0e, 0x36, 0x76, 0x0e, 0x4e, 0x2e, 0x6e, +0x4e, 0x1e, 0x5e, 0x3e, 0x7e, 0x01, 0x41, 0x21, +0x61, 0x11, 0x51, 0x31, 0x71, 0x09, 0xbc, 0x7a, +0x98, 0xd8, 0x24, 0xa5, 0x24, 0xa5, 0x91, 0xb5, +0xf0, 0xc8, 0xc8, 0xca, 0x49, 0x30, 0xc1, 0x15, +0xc8, 0x2b, 0x80, 0x80, 0xa2, 0x12, 0x08, 0x28, +0x83, 0x45, 0x98, 0x55, 0xa4, 0x54, 0xd5, 0xd4, +0x91, 0xdd, 0xa5, 0xa1, 0xa9, 0xa5, 0xad, 0xc3, +0x0c, 0xd7, 0xa2, 0xa0, 0xab, 0xa7, 0x6f, 0x60, +0xa8, 0x60, 0x64, 0x6c, 0x62, 0x6a, 0xa6, 0x04, +0x16, 0x61, 0x31, 0xb7, 0x50, 0xb3, 0xb4, 0x42, +0xb6, 0xd7, 0xca, 0x52, 0xd3, 0x5a, 0x90, 0x05, +0xa1, 0xc5, 0xc6, 0xd6, 0xce, 0xde, 0x41, 0xc1, +0xd1, 0xc9, 0xd9, 0xc5, 0x15, 0xa2, 0x85, 0xd5, +0xcd, 0xdd, 0xc3, 0x0a, 0xd5, 0xad, 0x56, 0x9e, +0x5e, 0xde, 0xac, 0x78, 0x6c, 0x61, 0x75, 0x77, +0x67, 0x65, 0x40, 0x03, 0xac, 0x3e, 0xbe, 0x08, +0x31, 0x3f, 0x7f, 0x10, 0x08, 0x08, 0x04, 0x81, +0x20, 0xa8, 0x16, 0x19, 0xb0, 0x74, 0x70, 0x48, +0x68, 0x58, 0x78, 0x78, 0x68, 0x48, 0x30, 0xba, +0x16, 0xff, 0x88, 0xc8, 0xc8, 0xc8, 0x08, 0xff, +0xa8, 0xe8, 0x98, 0xd8, 0xb8, 0x40, 0x64, 0x2d, +0xc1, 0x21, 0xf1, 0x09, 0x89, 0x49, 0xc9, 0x29, +0xa9, 0x20, 0x3d, 0xa8, 0x5a, 0x22, 0xd3, 0xd2, +0xd2, 0x22, 0xfd, 0xd3, 0x33, 0x32, 0xb3, 0xb2, +0x51, 0xb4, 0x84, 0xc4, 0xe7, 0xe4, 0xe6, 0xe5, +0x17, 0x14, 0x16, 0x15, 0x87, 0x10, 0xd6, 0x52, +0x52, 0x0a, 0x92, 0x0e, 0x2d, 0x2b, 0xaf, 0xa8, +0xac, 0xaa, 0x2c, 0xaa, 0xae, 0x09, 0x25, 0xa8, +0xa5, 0x96, 0x95, 0xb5, 0x16, 0x48, 0x85, 0x27, +0xd7, 0x55, 0xd6, 0x37, 0xd4, 0x37, 0x36, 0x35, +0x87, 0x13, 0xf4, 0x0b, 0x14, 0x84, 0xb7, 0xe4, +0xb7, 0xb6, 0x31, 0xb4, 0xb5, 0xb6, 0x77, 0xa0, +0x6b, 0xe9, 0x04, 0x87, 0x58, 0x17, 0x38, 0xc4, +0xba, 0x51, 0xb4, 0xf4, 0xf4, 0x86, 0x83, 0xa8, +0xbe, 0x7e, 0xe2, 0x6d, 0x99, 0x00, 0xd1, 0xd2, +0x3f, 0x31, 0x9c, 0x68, 0xbf, 0x4c, 0x9a, 0x04, +0xd6, 0x32, 0x71, 0x32, 0x56, 0x2d, 0x53, 0x90, +0xb4, 0xd4, 0xb2, 0xf2, 0x7a, 0x81, 0xf4, 0x4c, +0x0d, 0x0f, 0x9f, 0x0a, 0xd2, 0x32, 0x79, 0x1a, +0x5c, 0xcb, 0xf4, 0x19, 0x33, 0xa1, 0x5a, 0x66, +0xcd, 0x9e, 0x83, 0xd0, 0x52, 0xcb, 0x3a, 0x77, +0xde, 0xbc, 0xf9, 0x60, 0x7b, 0x20, 0xee, 0x9b, +0xb6, 0x00, 0xae, 0x65, 0xc6, 0xc2, 0x45, 0x8b, +0xc1, 0x7e, 0x59, 0xb2, 0x74, 0xd9, 0x72, 0x84, +0x5f, 0x58, 0x45, 0x56, 0xcc, 0x9b, 0x67, 0x2d, +0x0a, 0x77, 0x46, 0xf8, 0x82, 0x95, 0x70, 0x2d, +0x33, 0x17, 0xad, 0x5a, 0xbd, 0x18, 0x33, 0xc4, +0x80, 0x3e, 0x59, 0xa3, 0xcd, 0x8a, 0x64, 0xcb, +0xca, 0xb5, 0x08, 0xbf, 0x2c, 0x5e, 0xbd, 0x6e, +0x3d, 0xd0, 0x96, 0xe5, 0x1b, 0x36, 0x6e, 0xda, +0x8c, 0x25, 0x8d, 0xc1, 0xfc, 0xb2, 0x76, 0x0b, +0xc2, 0x96, 0xd5, 0x5b, 0xb7, 0x01, 0x6d, 0xf1, +0xdf, 0xb8, 0x7d, 0xc7, 0xce, 0x5d, 0x98, 0x69, +0x6c, 0x6a, 0xf8, 0xee, 0x3d, 0x20, 0x3d, 0xe1, +0x5b, 0xf6, 0x22, 0xfc, 0xb2, 0x6f, 0x1b, 0xd8, +0x2f, 0x9b, 0xf6, 0x1f, 0x38, 0x78, 0x08, 0x43, +0xcb, 0xd4, 0xf0, 0xc3, 0x47, 0x8e, 0x1e, 0x03, +0xea, 0x09, 0xdf, 0x7b, 0x1c, 0x23, 0xc4, 0x4e, +0x9c, 0x3c, 0x75, 0xfa, 0x0c, 0x86, 0x96, 0xf0, +0xb3, 0x13, 0x8f, 0x9e, 0x5b, 0x70, 0x3e, 0x9c, +0x21, 0xfc, 0xf8, 0x05, 0x8c, 0x78, 0xb9, 0x78, +0xe8, 0xcc, 0xa5, 0xcb, 0x18, 0x7e, 0x01, 0xfa, +0xe4, 0xca, 0x55, 0x90, 0x6f, 0xc2, 0x2f, 0x5c, +0x23, 0x9c, 0xc6, 0xa0, 0xde, 0x87, 0x84, 0x2e, +0x43, 0xf8, 0xb5, 0xeb, 0x18, 0xb6, 0x5c, 0xbe, +0x71, 0xf3, 0xd6, 0x6d, 0x2c, 0x21, 0x16, 0xbe, +0xf2, 0x0e, 0x58, 0xcb, 0xdd, 0xbb, 0x18, 0x5a, +0x6e, 0xde, 0xbb, 0xff, 0xe0, 0x21, 0x96, 0x5c, +0x19, 0xfe, 0x68, 0xef, 0x63, 0x60, 0xe2, 0x7f, +0x72, 0xf7, 0x29, 0x86, 0x96, 0x5b, 0xcf, 0x9e, +0x3f, 0xc7, 0xa6, 0x25, 0xac, 0xe6, 0xc5, 0x4b, +0x60, 0x16, 0x7b, 0xf5, 0xfa, 0x4d, 0x18, 0xba, +0x96, 0x87, 0xcf, 0xb1, 0x6b, 0x09, 0x7d, 0xfb, +0xee, 0xfd, 0xab, 0x0f, 0xaf, 0x3e, 0x7e, 0xfa, +0x8c, 0x91, 0x91, 0xbf, 0x3c, 0x7c, 0xf8, 0xf0, +0x0b, 0x16, 0xbf, 0x84, 0x7c, 0xfd, 0xf8, 0xed, +0xf5, 0xf7, 0x1f, 0x3f, 0x7f, 0xfd, 0x0e, 0x21, +0x36, 0xc4, 0x82, 0x43, 0xbe, 0x7e, 0x7e, 0xf3, +0xf4, 0xcf, 0xdf, 0xdf, 0x98, 0x85, 0x12, 0x2e, +0x5b, 0xf0, 0x14, 0x7d, 0x58, 0xfc, 0x82, 0xa5, +0x80, 0xfd, 0x87, 0x5f, 0x0b, 0xb6, 0x62, 0xfc, +0xdf, 0x7f, 0x7c, 0x5a, 0xb0, 0x56, 0x16, 0x32, +0x48, 0x95, 0x05, 0xa6, 0x5f, 0x08, 0x56, 0x49, +0x98, 0x21, 0x46, 0xb0, 0xe2, 0xc3, 0x04, 0x64, +0x54, 0xaf, 0x64, 0x54, 0xe2, 0x23, 0x18, 0x00, +0x00, 0xf9, 0xa7, 0x8d, 0xae, 0xd2, 0x97, 0x8e, +0x2b, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, +0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_nested_loop_semi_join_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_nested_loop_semi_join_png = new wxImage(); + if (!img_ex_nested_loop_semi_join_png || !img_ex_nested_loop_semi_join_png->IsOk()) + { + wxMemoryInputStream img_ex_nested_loop_semi_join_pngIS(ex_nested_loop_semi_join_png_data, sizeof(ex_nested_loop_semi_join_png_data)); + img_ex_nested_loop_semi_join_png->LoadFile(img_ex_nested_loop_semi_join_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_nested_loop_semi_join_png; +} +#define ex_nested_loop_semi_join_png_img ex_nested_loop_semi_join_png_img() + +static wxBitmap *ex_nested_loop_semi_join_png_bmp() +{ + static wxBitmap *bmp_ex_nested_loop_semi_join_png; + if (!bmp_ex_nested_loop_semi_join_png || !bmp_ex_nested_loop_semi_join_png->IsOk()) + bmp_ex_nested_loop_semi_join_png = new wxBitmap(*ex_nested_loop_semi_join_png_img); + return bmp_ex_nested_loop_semi_join_png; +} +#define ex_nested_loop_semi_join_png_bmp ex_nested_loop_semi_join_png_bmp() + +static wxIcon *ex_nested_loop_semi_join_png_ico() +{ + static wxIcon *ico_ex_nested_loop_semi_join_png; + if (!ico_ex_nested_loop_semi_join_png || !ico_ex_nested_loop_semi_join_png->IsOk()) + { + ico_ex_nested_loop_semi_join_png = new wxIcon(); + ico_ex_nested_loop_semi_join_png->CopyFromBitmap(*ex_nested_loop_semi_join_png_bmp); + } + return ico_ex_nested_loop_semi_join_png; +} +#define ex_nested_loop_semi_join_png_ico ex_nested_loop_semi_join_png_ico() + +#endif // EX_NESTED_LOOP_SEMI_JOIN_PNG_H diff --git a/include/images/ex_pscan.png b/include/images/ex_pscan.png new file mode 100644 index 0000000000000000000000000000000000000000..d197f25e9aa12fc55977299c349d59757713f0db GIT binary patch literal 1275 zcmVf426vxx>Dfk32eMC!vM41L8L}3~zpm0S2bRZ?92@)caXsAFy0hB03OdJ$!0$5lv zPLzuc#&F5x+^C5QpUfT7Y1kht2!83zpT2nMW=p(0JJx%Pf%;?b{}qUfx3|S>zl`aC`DeXc1kNf_7x@$USV z(#%3jT)Q7U8IY$UBOiSEo$(z$4g18wemz$gZ(mwO=dq?#;IL!gu1#e^;IL!&4pKh= zX=@-Mf$WfU5C!o_`bu>zAhsBDPAjdh(orBdeP07<5rhJ%AAqz80t&T&8N$~$GcwTAGQ!zNOEO}MG3Rt|D^@arxYUAYs0F`R3yp(X z2(?b01dp$#|K&5 zjFirD*RsW!cWOjRri^eGVkL&T5Ete`Vwelqk%=CuPj+Mgndp=Dyi3N6*ka5%{m}@O zj05qgt3@q;wK%F4PzTBCK`mhK$!BPH^}HBZYQz>}&gu7hsAL1NT`dB`)xy?Ju`@)f zfglS2VC`8zY%%7X?rwCHi~~_?r@liwO{kr6OJxuQo)QF3zfS=V2&7N4f!JcqIW0(s z1q%q*LQLv8)B@K5x>4UNuZ5x95j<;XsS#U@Ij4E)FmG@=OI^zrW6tT<{{kgbMpC++ z@(s18ojlKkRO>=&E^Hp23)t}*4GJgE85xpBmWi0Nvfx6_{1PWK38K+-{m1Oe@z1myO=zLE`uA>zVZu(ea3 z33@xlKF~mhWFKiDqY@BXjLslDk<-FNw$%c<(ImBi9l>X^)QA(vt$%!_v)r|8F*-T% z$@5H5b3p4tJQD^bb3s3OyhbcO`F+QXSV8nJy>8SzrQ(-h$GKYQwV*mtp%zAkT2R5` znIyCtafy-s501s`+K%{srKN<=urYP9ou&>~3kKnqI?_N!6N0$Jn9-tu*olit&j^EX zOC1>I!oV;WhK0GXPas*)WETz@DT^@&qu*n6hm+RAzC$fwNARp-jT{xD(-*{NrE58T liCwK~RjXRns@Ai-{s;IK-9VD>=|unl002ovPDHLkV1nf-R%rkL literal 0 HcmV?d00001 diff --git a/include/images/ex_pscan.pngc b/include/images/ex_pscan.pngc new file mode 100644 index 0000000..3f6556a --- /dev/null +++ b/include/images/ex_pscan.pngc @@ -0,0 +1,204 @@ +#ifndef EX_PSCAN_PNG_H +#define EX_PSCAN_PNG_H + +static const unsigned char ex_pscan_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x06, 0x00, 0x00, 0x00, 0x1e, 0x3f, 0x88, +0xb1, 0x00, 0x00, 0x04, 0xc2, 0x49, 0x44, 0x41, +0x54, 0x78, 0xda, 0xed, 0x98, 0x31, 0x6f, 0x1c, +0x45, 0x14, 0xc7, 0xd3, 0xf0, 0x29, 0xf8, 0x04, +0x31, 0x7d, 0x44, 0x4b, 0x81, 0x44, 0x99, 0x06, +0x24, 0x44, 0x61, 0x1a, 0x28, 0xa0, 0x70, 0x45, +0x01, 0x74, 0x20, 0x25, 0xa4, 0x09, 0x12, 0x22, +0x91, 0x68, 0xa8, 0x40, 0x40, 0x01, 0x94, 0x28, +0x45, 0x4c, 0x1c, 0x14, 0x6c, 0x02, 0x58, 0x58, +0x31, 0x4e, 0x94, 0x8b, 0x0d, 0xc6, 0x77, 0x3e, +0x9f, 0x6f, 0xbd, 0x7b, 0xbb, 0x7b, 0xbb, 0xe7, +0x3b, 0xdf, 0x79, 0x98, 0xff, 0xdc, 0x7b, 0xeb, +0xd9, 0xf5, 0xcc, 0x7a, 0xce, 0x4e, 0x2c, 0x2b, +0xd9, 0x91, 0xfe, 0x9a, 0xdb, 0xe7, 0x27, 0xfb, +0xfd, 0xe6, 0xed, 0x7b, 0x6f, 0x7c, 0xe7, 0xce, +0x55, 0xab, 0x5a, 0xd5, 0xaa, 0xd6, 0x53, 0xb7, +0xae, 0xdc, 0xa8, 0x89, 0x0b, 0x9f, 0xcc, 0x1d, +0xd2, 0x69, 0xd8, 0x1f, 0x2b, 0x08, 0x7e, 0xe9, +0xcc, 0x9f, 0xbe, 0x78, 0xe9, 0x66, 0x4b, 0xbc, +0x3c, 0x3b, 0xd6, 0x7b, 0x8b, 0x81, 0xfa, 0x63, +0xef, 0xff, 0x15, 0x88, 0x8b, 0xb7, 0xb7, 0xc5, +0x6b, 0xbf, 0x8c, 0xf5, 0xf1, 0xbd, 0xce, 0x38, +0x88, 0xbf, 0x3b, 0xe2, 0xad, 0x05, 0x4f, 0xbc, +0xf3, 0x9b, 0x27, 0x66, 0xee, 0x7a, 0xe2, 0xf3, +0x07, 0xa1, 0xb2, 0x7f, 0xf1, 0x30, 0x14, 0x1f, +0x2e, 0xee, 0x88, 0x8f, 0x96, 0xc6, 0xfa, 0x6a, +0x75, 0x6c, 0xff, 0x76, 0x2d, 0x12, 0x57, 0x97, +0x7d, 0xf1, 0xd9, 0x4a, 0xa0, 0xf4, 0xe3, 0x7a, +0xac, 0xec, 0x8f, 0x1d, 0x04, 0x10, 0xcf, 0x7d, +0xb3, 0x9e, 0xe9, 0x95, 0x9f, 0x5b, 0xea, 0x0f, +0x01, 0xe2, 0xf9, 0x1f, 0x36, 0x32, 0xbd, 0x71, +0xa7, 0xad, 0xec, 0x80, 0x78, 0xf1, 0xa7, 0x46, +0x26, 0xc0, 0xc0, 0x0e, 0x88, 0x8b, 0xb3, 0x4d, +0xf1, 0xea, 0xad, 0xa6, 0x78, 0x7d, 0xae, 0x29, +0x2e, 0x49, 0x18, 0xd8, 0x01, 0xf1, 0xee, 0xfc, +0x96, 0xd2, 0xcc, 0x42, 0x4b, 0x5c, 0xbb, 0x1f, +0x3c, 0x19, 0x90, 0xa7, 0x22, 0x23, 0x1f, 0x7c, +0xf9, 0x9d, 0xf1, 0x1d, 0x3e, 0x0d, 0xfb, 0xc4, +0xc1, 0x7e, 0x3d, 0x57, 0x17, 0x6f, 0x5f, 0x5f, +0x52, 0xc2, 0x67, 0xfd, 0x67, 0x73, 0x9f, 0x5e, +0x10, 0xe1, 0xf6, 0x65, 0xb1, 0xb3, 0xf1, 0x66, +0x26, 0x3c, 0xeb, 0x76, 0x9f, 0x14, 0x91, 0x3d, +0x96, 0x7b, 0xb0, 0x31, 0x3d, 0x56, 0x7d, 0x5a, +0xc4, 0xed, 0xb1, 0xbd, 0x2b, 0xf7, 0x8e, 0x7c, +0x86, 0x42, 0xa9, 0x2e, 0xd9, 0x13, 0xb9, 0x47, +0xf2, 0x99, 0x95, 0x92, 0xdd, 0x35, 0xc6, 0x6c, +0xe1, 0x87, 0xeb, 0x41, 0x4f, 0x09, 0x9f, 0x8b, +0x20, 0x08, 0xb6, 0xf9, 0xf0, 0x85, 0x4c, 0x78, +0x86, 0x1d, 0xc1, 0x6f, 0xc9, 0xe7, 0xb1, 0xa6, +0x54, 0xe0, 0xb0, 0x63, 0xdf, 0xae, 0x4d, 0x65, +0x42, 0xe0, 0xb0, 0x63, 0xf7, 0xe4, 0x33, 0x2b, +0x22, 0x3b, 0x76, 0x5f, 0x3e, 0x07, 0xa4, 0xb8, +0x31, 0x7d, 0x08, 0xa4, 0x2c, 0xc6, 0x9c, 0xd3, +0xfd, 0xed, 0x44, 0x69, 0x72, 0x90, 0x29, 0xa5, +0x96, 0x0e, 0x52, 0x3f, 0x00, 0x69, 0x6b, 0x20, +0x21, 0x81, 0xec, 0x90, 0x74, 0x10, 0x05, 0xf1, +0x48, 0xfa, 0x4a, 0x75, 0x2d, 0x20, 0xb6, 0x18, +0x73, 0x4e, 0x2b, 0xad, 0xae, 0xd2, 0x51, 0x20, +0x38, 0x7d, 0x5f, 0x03, 0x69, 0x11, 0x84, 0x02, +0xa9, 0x1f, 0x80, 0xb4, 0x09, 0x02, 0x0a, 0xb5, +0x80, 0x19, 0xc2, 0xd7, 0x40, 0x62, 0xbc, 0x6e, +0x04, 0x01, 0x25, 0x16, 0x10, 0x5b, 0x8c, 0xce, +0x20, 0xa8, 0x05, 0xff, 0x18, 0xb5, 0x10, 0x3a, +0xd6, 0x42, 0x4f, 0xee, 0xc8, 0x42, 0x42, 0xda, +0x35, 0xd4, 0xc8, 0x89, 0x41, 0x6a, 0x37, 0xaf, +0xa8, 0x5f, 0x5a, 0xd4, 0x69, 0xd8, 0x8f, 0x05, +0xb2, 0x2c, 0x1d, 0x96, 0x2d, 0x19, 0x89, 0x28, +0x23, 0x7c, 0xfa, 0x31, 0x67, 0x44, 0x9e, 0x5c, +0x40, 0x5d, 0xa8, 0xa3, 0x9d, 0x3c, 0xf6, 0x50, +0x3b, 0xf9, 0x84, 0xec, 0xc8, 0x00, 0x5e, 0x23, +0x14, 0x33, 0x32, 0xd0, 0xd3, 0x32, 0xc2, 0xd9, +0x48, 0x4b, 0x32, 0x62, 0x8b, 0x31, 0xe7, 0x74, +0x6f, 0x2b, 0x56, 0x32, 0x81, 0xb8, 0xd4, 0x82, +0x67, 0xa8, 0x05, 0xbf, 0x58, 0x0b, 0x8d, 0x83, +0x5a, 0x08, 0xb5, 0x5a, 0xc0, 0x1e, 0xc9, 0xe7, +0x98, 0xd4, 0xb3, 0xd4, 0x88, 0x2d, 0xc6, 0x9c, +0xd3, 0x52, 0x33, 0x52, 0x32, 0x81, 0x20, 0x0b, +0x00, 0xe0, 0x4e, 0x14, 0x68, 0xed, 0xb4, 0x5d, +0xd2, 0x4e, 0xb9, 0xa5, 0xc6, 0x64, 0xef, 0x12, +0x48, 0x58, 0x00, 0x41, 0x16, 0x00, 0xd0, 0x25, +0xed, 0x5a, 0x40, 0x6c, 0x31, 0x4e, 0x04, 0x62, +0x9a, 0x0b, 0xa1, 0x36, 0x17, 0x8c, 0xed, 0x94, +0x5a, 0x6a, 0x57, 0x3b, 0x79, 0x00, 0x44, 0xa4, +0x94, 0xec, 0xc8, 0x00, 0x43, 0x24, 0x00, 0xd9, +0x7c, 0x42, 0x20, 0x65, 0xb5, 0x10, 0x95, 0xd4, +0x42, 0xd7, 0xb1, 0x16, 0xfa, 0x72, 0x47, 0x16, +0x00, 0x00, 0x0d, 0xbc, 0xcb, 0xc7, 0x07, 0x59, +0xdc, 0x8c, 0x94, 0xce, 0x72, 0xd7, 0xb2, 0xc5, +0x98, 0x77, 0x6a, 0x44, 0x4a, 0xa6, 0x8c, 0x70, +0x17, 0x62, 0x25, 0x86, 0xb9, 0x10, 0x17, 0xe6, +0x42, 0x62, 0x98, 0x0b, 0xd8, 0x91, 0x89, 0x1e, +0xa9, 0x4f, 0x76, 0x64, 0x00, 0x99, 0xe8, 0x93, +0xf6, 0xbc, 0x4b, 0xc6, 0x8c, 0xd8, 0x62, 0xcc, +0x39, 0xfd, 0xd1, 0x08, 0x95, 0x8c, 0x03, 0xf1, +0xa8, 0xab, 0x45, 0x2d, 0x7f, 0xb5, 0x38, 0xaa, +0x16, 0x50, 0x07, 0xc9, 0xea, 0x41, 0x2d, 0x60, +0xef, 0xc9, 0x67, 0x68, 0x77, 0xf5, 0xbc, 0x18, +0x58, 0x6a, 0xc4, 0x16, 0x63, 0xce, 0xe9, 0xf7, +0x7a, 0xa8, 0x64, 0x03, 0xb1, 0x5d, 0x2d, 0x02, +0xc3, 0xd5, 0xc2, 0xd6, 0x4e, 0xb1, 0x33, 0x44, +0xaa, 0x81, 0x20, 0x0b, 0x00, 0x60, 0xed, 0x59, +0x40, 0x6c, 0x31, 0xe6, 0x9c, 0xee, 0x6e, 0x74, +0x94, 0x8c, 0x03, 0x51, 0x6b, 0xa7, 0xbe, 0x43, +0x3b, 0x4d, 0xa8, 0x9d, 0x72, 0x4b, 0x65, 0x10, +0x04, 0x9e, 0x12, 0x04, 0x4e, 0xbf, 0x4f, 0x01, +0x0f, 0x08, 0xa4, 0x4f, 0xb2, 0x81, 0xd8, 0x62, +0xcc, 0x39, 0x2d, 0x48, 0x87, 0x05, 0x0b, 0x08, +0xd7, 0x42, 0x4c, 0xea, 0x39, 0xd4, 0x02, 0xd7, +0x01, 0xba, 0x51, 0xdf, 0x2b, 0xaf, 0x85, 0xa1, +0xdc, 0x11, 0x3c, 0x6b, 0x68, 0xa9, 0x11, 0x5b, +0x8c, 0x39, 0xa7, 0x79, 0xe9, 0x30, 0x6f, 0x70, +0x3a, 0x4b, 0x5d, 0xcb, 0x16, 0x63, 0xce, 0xe9, +0xd7, 0xff, 0x02, 0x25, 0x53, 0x46, 0x52, 0xba, +0x9d, 0xf2, 0x0d, 0xb5, 0xa7, 0x9d, 0x3c, 0xcf, +0x84, 0x54, 0xeb, 0x42, 0x6a, 0x2e, 0x6c, 0x1e, +0x9e, 0x0b, 0xd8, 0xf1, 0x1a, 0x0d, 0x0a, 0x27, +0xcf, 0x19, 0x19, 0x92, 0x46, 0x96, 0x8c, 0xd8, +0x62, 0xcc, 0x39, 0xdd, 0x59, 0x0f, 0x94, 0x8c, +0xed, 0x77, 0xc2, 0xab, 0x45, 0x59, 0x2d, 0xf4, +0x0d, 0xb5, 0x80, 0xe0, 0xf7, 0xd6, 0xce, 0x2b, +0x0d, 0xa5, 0x46, 0x96, 0x1a, 0xb1, 0xc5, 0xe8, +0x0c, 0x52, 0x6c, 0xa7, 0x3a, 0x88, 0xe9, 0x6a, +0xa1, 0xb7, 0xd3, 0x9e, 0xd6, 0x4e, 0xf7, 0x08, +0x64, 0x40, 0xd2, 0x41, 0x86, 0x04, 0x01, 0xed, +0x9f, 0x04, 0xe4, 0xf6, 0xbf, 0xbe, 0x92, 0x0d, +0x84, 0x21, 0xe2, 0xc2, 0x5c, 0xb0, 0xb5, 0x53, +0x9e, 0x09, 0x7a, 0x3b, 0xc5, 0x3e, 0xd0, 0x40, +0x86, 0x64, 0x1f, 0x69, 0x20, 0xa3, 0x12, 0x10, +0x5b, 0x8c, 0xce, 0x20, 0x3c, 0x91, 0xd3, 0xc2, +0x44, 0xb6, 0xd5, 0x02, 0xba, 0xd1, 0x24, 0xb5, +0x80, 0x1d, 0xc1, 0x67, 0xb2, 0xd4, 0x88, 0x13, +0xc8, 0xad, 0x7f, 0x7c, 0xa5, 0xb3, 0xdc, 0xb5, +0x6c, 0x31, 0x3a, 0x39, 0xf1, 0xc9, 0xf3, 0x4c, +0x50, 0x73, 0x40, 0xeb, 0x42, 0x3c, 0x13, 0x06, +0x25, 0x73, 0x41, 0x3f, 0x79, 0xbc, 0x46, 0x2c, +0x3e, 0xf9, 0x7d, 0xc7, 0x8c, 0x58, 0x41, 0xf4, +0x2f, 0xbd, 0x6e, 0xd4, 0x3c, 0xa5, 0xe2, 0x97, +0x60, 0xc7, 0xb9, 0x5a, 0xe8, 0xb5, 0xa0, 0x3a, +0x51, 0xa1, 0x16, 0x46, 0x85, 0x5a, 0x50, 0xc1, +0xe3, 0x99, 0x24, 0xb4, 0x1a, 0x71, 0x89, 0x91, +0xfe, 0x0f, 0x8e, 0xc5, 0xec, 0xda, 0x8e, 0xf8, +0x7e, 0xa5, 0xa5, 0x84, 0xcf, 0xb0, 0x31, 0x75, +0xb1, 0x9d, 0xa6, 0x0e, 0x57, 0x0b, 0x06, 0xe1, +0x96, 0x3a, 0xd2, 0x40, 0x46, 0x13, 0x82, 0xb8, +0xc4, 0x98, 0xd1, 0xa2, 0x80, 0xd8, 0x89, 0x8b, +0x49, 0xcf, 0x08, 0x83, 0x70, 0x4b, 0x1d, 0x18, +0xe6, 0xc2, 0xc0, 0x30, 0x17, 0x86, 0x85, 0xb9, +0xb0, 0x4f, 0x20, 0x59, 0xd0, 0x64, 0x17, 0x0e, +0x19, 0x29, 0x8b, 0x31, 0x07, 0xa3, 0xdf, 0x63, +0x74, 0x87, 0x93, 0xd6, 0xc2, 0xbe, 0x43, 0x2d, +0x60, 0x47, 0xf0, 0xac, 0x62, 0x8d, 0x1c, 0x15, +0xa3, 0xd3, 0x17, 0xc4, 0x67, 0xa5, 0x6b, 0x39, +0x7d, 0x89, 0x5d, 0xad, 0x6a, 0x55, 0xab, 0x5a, +0xd5, 0xaa, 0xd6, 0xb3, 0xbc, 0xfe, 0x07, 0xf8, +0x15, 0xdd, 0x40, 0x92, 0xef, 0xe9, 0x45, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_pscan_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_pscan_png = new wxImage(); + if (!img_ex_pscan_png || !img_ex_pscan_png->IsOk()) + { + wxMemoryInputStream img_ex_pscan_pngIS(ex_pscan_png_data, sizeof(ex_pscan_png_data)); + img_ex_pscan_png->LoadFile(img_ex_pscan_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_pscan_png; +} +#define ex_pscan_png_img ex_pscan_png_img() + +static wxBitmap *ex_pscan_png_bmp() +{ + static wxBitmap *bmp_ex_pscan_png; + if (!bmp_ex_pscan_png || !bmp_ex_pscan_png->IsOk()) + bmp_ex_pscan_png = new wxBitmap(*ex_pscan_png_img); + return bmp_ex_pscan_png; +} +#define ex_pscan_png_bmp ex_pscan_png_bmp() + +static wxIcon *ex_pscan_png_ico() +{ + static wxIcon *ico_ex_pscan_png; + if (!ico_ex_pscan_png || !ico_ex_pscan_png->IsOk()) + { + ico_ex_pscan_png = new wxIcon(); + ico_ex_pscan_png->CopyFromBitmap(*ex_pscan_png_bmp); + } + return ico_ex_pscan_png; +} +#define ex_pscan_png_ico ex_pscan_png_ico() + +#endif // EX_PSCAN_PNG_H diff --git a/include/images/ex_pscan2.png b/include/images/ex_pscan2.png new file mode 100644 index 0000000000000000000000000000000000000000..d197f25e9aa12fc55977299c349d59757713f0db GIT binary patch literal 1275 zcmVf426vxx>Dfk32eMC!vM41L8L}3~zpm0S2bRZ?92@)caXsAFy0hB03OdJ$!0$5lv zPLzuc#&F5x+^C5QpUfT7Y1kht2!83zpT2nMW=p(0JJx%Pf%;?b{}qUfx3|S>zl`aC`DeXc1kNf_7x@$USV z(#%3jT)Q7U8IY$UBOiSEo$(z$4g18wemz$gZ(mwO=dq?#;IL!gu1#e^;IL!&4pKh= zX=@-Mf$WfU5C!o_`bu>zAhsBDPAjdh(orBdeP07<5rhJ%AAqz80t&T&8N$~$GcwTAGQ!zNOEO}MG3Rt|D^@arxYUAYs0F`R3yp(X z2(?b01dp$#|K&5 zjFirD*RsW!cWOjRri^eGVkL&T5Ete`Vwelqk%=CuPj+Mgndp=Dyi3N6*ka5%{m}@O zj05qgt3@q;wK%F4PzTBCK`mhK$!BPH^}HBZYQz>}&gu7hsAL1NT`dB`)xy?Ju`@)f zfglS2VC`8zY%%7X?rwCHi~~_?r@liwO{kr6OJxuQo)QF3zfS=V2&7N4f!JcqIW0(s z1q%q*LQLv8)B@K5x>4UNuZ5x95j<;XsS#U@Ij4E)FmG@=OI^zrW6tT<{{kgbMpC++ z@(s18ojlKkRO>=&E^Hp23)t}*4GJgE85xpBmWi0Nvfx6_{1PWK38K+-{m1Oe@z1myO=zLE`uA>zVZu(ea3 z33@xlKF~mhWFKiDqY@BXjLslDk<-FNw$%c<(ImBi9l>X^)QA(vt$%!_v)r|8F*-T% z$@5H5b3p4tJQD^bb3s3OyhbcO`F+QXSV8nJy>8SzrQ(-h$GKYQwV*mtp%zAkT2R5` znIyCtafy-s501s`+K%{srKN<=urYP9ou&>~3kKnqI?_N!6N0$Jn9-tu*olit&j^EX zOC1>I!oV;WhK0GXPas*)WETz@DT^@&qu*n6hm+RAzC$fwNARp-jT{xD(-*{NrE58T liCwK~RjXRns@Ai-{s;IK-9VD>=|unl002ovPDHLkV1nf-R%rkL literal 0 HcmV?d00001 diff --git a/include/images/ex_recursive_union.png b/include/images/ex_recursive_union.png new file mode 100644 index 0000000000000000000000000000000000000000..66952ea454e3703dcb08251bd2273193aacaeb28 GIT binary patch literal 1224 zcmV;(1ULJMP)V?$sl-Tfk&g_HH?Tggzt>5!Nyy*w1;t;Fi8m{AA#p`j) z>`uPsTEXXJ#psgN?_`zG-s;qsyLGzJqh@Q-%+2w=zwN)l?ZU(F)710W+4RoO^3l=q z)YSCg;P-*9LUN@xnY?(sz3iu{=c=sduCM9E#_!9_@xH(9!ou#w#_-nG^mC;*r_X10 zsycS7JFwk!QjHmRt30ycc6zZujKETQu|cJ%EWC2=(Fb9mF3ryf)T}-9pzKn&{q{=iHa<n{?g@8!Sl;=SnCr{~qB=G3I@-MZ}IuH@B` z;?R!h*QVdchTg@6-NJ+A(V^?#t>e*;;mwQZ)TG|TgxtV^<<6ku&Wz#Air~qK=F+3x z!Ghesf!n@+^xnCJ=y<#A#t-W?^MxXX4=G;^tu@ zQVTC1zkncaJZKN(>M(aXP_REv;f1z+0g=bbYa!PVBrGNg6c&y zE$GHsxMJD@@iq)#7-!*Tfnhl$q2L6P?j9KF2$E260x1tqFN|~qPAIs6hL^VmnqMFZ z1!u;P^700z3Ljq(fRfOJf-}iV`hlc<{R0Anf_+0m!@?tc(LxL(V^~CjTHy^z z-{$b5#1`Myw)T!rge{O%fa+*?uJrBd&g`l4?d|KIFcHZw;8cL!(G0$mCYMfW^PM_v z!t@zPwt!Osc1JV#*3O(YyWMxr+%0_={)uLY~4@dA8~9tHFV07F>Y9b_N@c>n+aC3HntbYx+4WjbSWWnpw>05UK! zFfB1MEif@uGB7$cGdeUhD=;-WFfcfoB_03(03~!qSaf7zbY(hiZ)9m^c>ppnF)%GK mIV~_TR5CLIsOk()) + { + wxMemoryInputStream img_ex_recursive_union_pngIS(ex_recursive_union_png_data, sizeof(ex_recursive_union_png_data)); + img_ex_recursive_union_png->LoadFile(img_ex_recursive_union_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_recursive_union_png; +} +#define ex_recursive_union_png_img ex_recursive_union_png_img() + +static wxBitmap *ex_recursive_union_png_bmp() +{ + static wxBitmap *bmp_ex_recursive_union_png; + if (!bmp_ex_recursive_union_png || !bmp_ex_recursive_union_png->IsOk()) + bmp_ex_recursive_union_png = new wxBitmap(*ex_recursive_union_png_img); + return bmp_ex_recursive_union_png; +} +#define ex_recursive_union_png_bmp ex_recursive_union_png_bmp() + +static wxIcon *ex_recursive_union_png_ico() +{ + static wxIcon *ico_ex_recursive_union_png; + if (!ico_ex_recursive_union_png || !ico_ex_recursive_union_png->IsOk()) + { + ico_ex_recursive_union_png = new wxIcon(); + ico_ex_recursive_union_png->CopyFromBitmap(*ex_recursive_union_png_bmp); + } + return ico_ex_recursive_union_png; +} +#define ex_recursive_union_png_ico ex_recursive_union_png_ico() + +#endif // EX_RECURSIVE_UNION_PNG_H diff --git a/include/images/ex_redistribute_motion.png b/include/images/ex_redistribute_motion.png new file mode 100644 index 0000000000000000000000000000000000000000..06b72826862098966412a9ed9320ed4514fe3e5a GIT binary patch literal 218 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*@xBpA$Gw#oo0rjj7PUIsOk()) + { + wxMemoryInputStream img_ex_redistribute_motion_pngIS(ex_redistribute_motion_png_data, sizeof(ex_redistribute_motion_png_data)); + img_ex_redistribute_motion_png->LoadFile(img_ex_redistribute_motion_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_redistribute_motion_png; +} +#define ex_redistribute_motion_png_img ex_redistribute_motion_png_img() + +static wxBitmap *ex_redistribute_motion_png_bmp() +{ + static wxBitmap *bmp_ex_redistribute_motion_png; + if (!bmp_ex_redistribute_motion_png || !bmp_ex_redistribute_motion_png->IsOk()) + bmp_ex_redistribute_motion_png = new wxBitmap(*ex_redistribute_motion_png_img); + return bmp_ex_redistribute_motion_png; +} +#define ex_redistribute_motion_png_bmp ex_redistribute_motion_png_bmp() + +static wxIcon *ex_redistribute_motion_png_ico() +{ + static wxIcon *ico_ex_redistribute_motion_png; + if (!ico_ex_redistribute_motion_png || !ico_ex_redistribute_motion_png->IsOk()) + { + ico_ex_redistribute_motion_png = new wxIcon(); + ico_ex_redistribute_motion_png->CopyFromBitmap(*ex_redistribute_motion_png_bmp); + } + return ico_ex_redistribute_motion_png; +} +#define ex_redistribute_motion_png_ico ex_redistribute_motion_png_ico() + +#endif // EX_REDISTRIBUTE_MOTION_PNG_H diff --git a/include/images/ex_result.png b/include/images/ex_result.png new file mode 100644 index 0000000000000000000000000000000000000000..bfd7b5904f9b304709ac6aab37e24dcc06d233c7 GIT binary patch literal 1320 zcmV+@1=sqCP) zy&|Rq4YRc_yz2s%c>~px_ zSfSIA(d>o8VwejipJ$*z2zgay*ywR-w~O!0LI->S@2`Yq#KKzve-^=xegvb++DV$m?jj z8=EE-ir5<7j^*+nDazi&@X2h!2ImzwkBpdc1Oj$;KNWK&&*v{K zHc_Fp2T>6_XL(<6MG=Sv0DC5#0-#mAvC+Nq*9v^kIK2l8vdFM%Et8knvxnJo1c6|c z&4c}KvKHW}Vy0H@L~i3sM*z8wP6~1|m|;789O!rkC-wRX3IT({=^1*&oHufd5Vx<$E{y1rNF{wq{1pVhD#p6C2Rn5oh%7L0oleB1N|4Fp`jMQ=#pw)z990@QuA5do z%zYPv$i2ZQ&zL%%$z6BtR(}-AOZ|1ZsiIV3#aX_aKKpI?Rtwj~pUC1Wk{1EpWn@(i<$E=y+6>NkK z&qpAySa4-uHvH^XzT03OH>05UK!FfB1MEif@u zGB7$cGdeUhD=;-WFfcfoB_03(03~!qSaf7zbY(hiZ)9m^c>ppnF)%GKIV~_TR5CL< eG&DLeHY+eSIxsNGmsP9)0000n literal 0 HcmV?d00001 diff --git a/include/images/ex_result.pngc b/include/images/ex_result.pngc new file mode 100644 index 0000000..a450225 --- /dev/null +++ b/include/images/ex_result.pngc @@ -0,0 +1,209 @@ +#ifndef EX_RESULT_PNG_H +#define EX_RESULT_PNG_H + +static const unsigned char ex_result_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xbf, 0xc9, 0xd0, 0x96, +0xb8, 0xd0, 0xaf, 0xc2, 0xd0, 0x7d, 0xae, 0xd1, +0xb0, 0xc3, 0xd0, 0x85, 0xb1, 0xd1, 0x5d, 0xa5, +0xd5, 0x6e, 0xb9, 0xe0, 0x8f, 0xb5, 0xd1, 0xc1, +0xca, 0xd0, 0x68, 0xae, 0xda, 0x8d, 0xca, 0xe8, +0x90, 0xca, 0xe8, 0x64, 0xaa, 0xd8, 0xc8, 0xcd, +0xd0, 0x6a, 0xb4, 0xde, 0x86, 0xd4, 0xf0, 0x71, +0xbe, 0xe4, 0x82, 0xcf, 0xec, 0x61, 0xa9, 0xd8, +0xb7, 0xc6, 0xd0, 0x9e, 0xbc, 0xd0, 0x6c, 0xa7, +0xd1, 0x7f, 0xc0, 0xe3, 0x91, 0xcd, 0xe8, 0x60, +0xa6, 0xd6, 0x9e, 0xd4, 0xed, 0x81, 0xbe, 0xe1, +0x74, 0xab, 0xd1, 0xa8, 0xc0, 0xd0, 0x5d, 0xa8, +0xd7, 0x6a, 0xca, 0xed, 0x6e, 0xbd, 0xe4, 0x65, +0xc8, 0xec, 0x73, 0xb8, 0xe0, 0x58, 0xa1, 0xd3, +0x91, 0xd1, 0xec, 0x85, 0xc3, 0xe5, 0x5a, 0xa2, +0xd3, 0x97, 0xd2, 0xec, 0x59, 0xa2, 0xd3, 0x6e, +0xc1, 0xe6, 0x51, 0xc1, 0xea, 0x8d, 0xb5, 0xd1, +0x75, 0xbc, 0xe3, 0x8d, 0xd4, 0xee, 0x65, 0xad, +0xda, 0x8e, 0xcd, 0xe9, 0xb8, 0xc6, 0xd0, 0x9f, +0xda, 0xf0, 0x5a, 0xa5, 0xd5, 0x5b, 0xa0, 0xd1, +0x82, 0xc6, 0xe6, 0x73, 0xb4, 0xdd, 0x95, 0xd8, +0xef, 0x90, 0xca, 0xe7, 0x6f, 0xbb, 0xe2, 0x39, +0xb9, 0xe7, 0x5d, 0xc4, 0xe9, 0x76, 0xba, 0xe0, +0x75, 0xcd, 0xed, 0x7d, 0xc2, 0xe4, 0x91, 0xd5, +0xee, 0x64, 0xa4, 0xd1, 0x5e, 0xc1, 0xe8, 0x32, +0xb7, 0xe6, 0x75, 0xca, 0xea, 0x6e, 0xcb, 0xec, +0x6d, 0xb0, 0xda, 0x92, 0xd3, 0xed, 0x61, 0xac, +0xda, 0x40, 0xbc, 0xe8, 0x7a, 0xc0, 0xe4, 0x7a, +0xca, 0xea, 0x83, 0xd0, 0xed, 0x8a, 0xc6, 0xe5, +0x63, 0xbd, 0xe5, 0x23, 0xb2, 0xe4, 0x3c, 0xba, +0xe7, 0x55, 0xc1, 0xe8, 0x7f, 0xce, 0xec, 0x94, +0xd5, 0xee, 0x66, 0xb2, 0xdd, 0x61, 0xc0, 0xe7, +0x1c, 0xaf, 0xe4, 0x35, 0xb8, 0xe7, 0x65, 0xb7, +0xe0, 0x5a, 0xc3, 0xe9, 0x78, 0xc5, 0xe8, 0x75, +0xc5, 0xe8, 0x5c, 0xbc, 0xe5, 0x2c, 0xb5, 0xe5, +0x45, 0xbb, 0xe6, 0x7f, 0xc8, 0xe8, 0x80, 0xc8, +0xe8, 0x64, 0xc6, 0xeb, 0x88, 0xd1, 0xed, 0x3e, +0xb9, 0xe5, 0x6c, 0xc9, 0xeb, 0x53, 0x9d, 0xd1, +0x71, 0xc9, 0xe9, 0xa6, 0xbf, 0xd0, 0x64, 0xb0, +0xdc, 0x70, 0xb6, 0xde, 0x7c, 0xb9, 0xdf, 0x75, +0xc4, 0xe7, 0x49, 0xbe, 0xe9, 0x7b, 0xc5, 0xe7, +0x48, 0xbd, 0xe7, 0x7e, 0xcd, 0xeb, 0x94, 0xce, +0xea, 0x56, 0xa1, 0xd3, 0x4c, 0xc0, 0xea, 0x79, +0xcc, 0xea, 0x69, 0xbf, 0xe6, 0x6b, 0xb7, 0xe0, +0x65, 0xbf, 0xe6, 0x41, 0xbb, 0xe8, 0x6b, 0xb2, +0xdc, 0x75, 0xb6, 0xde, 0x69, 0xc8, 0xeb, 0x68, +0xba, 0xe3, 0x8c, 0xc8, 0xe6, 0x82, 0xcd, 0xeb, +0x7a, 0xbb, 0xe1, 0xa5, 0xda, 0xf0, 0x4f, 0xb7, +0xe3, 0x2d, 0x6b, 0x8a, 0xc1, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0xdf, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xed, 0x55, 0xe9, 0x53, 0xda, 0x40, 0x14, +0x0f, 0x21, 0x84, 0x44, 0x2c, 0xa9, 0x57, 0x28, +0xc8, 0x42, 0x2d, 0xc8, 0x95, 0x94, 0x82, 0x50, +0xbc, 0xa0, 0x22, 0x51, 0x01, 0x95, 0xc3, 0x03, +0x8a, 0x16, 0x5a, 0xa5, 0x08, 0x56, 0x45, 0xc5, +0xa3, 0xf5, 0xa8, 0xed, 0xbf, 0xde, 0x70, 0x04, +0x76, 0x43, 0x74, 0xa6, 0x5f, 0x3a, 0xfd, 0xe0, +0x9b, 0x61, 0x86, 0xb7, 0xbb, 0xbf, 0xf7, 0xde, +0xef, 0x5d, 0xc1, 0xb0, 0x67, 0xf9, 0xf7, 0xa2, +0xc2, 0x71, 0x15, 0xa4, 0xaa, 0x09, 0x0d, 0xa6, +0x11, 0x7f, 0x4f, 0x08, 0xa9, 0xa5, 0x28, 0x2d, +0x2d, 0x69, 0x03, 0xb4, 0x6e, 0x90, 0xc0, 0x88, +0x17, 0x7a, 0x9c, 0x79, 0x1c, 0xf1, 0x72, 0x88, +0x1a, 0x1e, 0x19, 0x1d, 0x6b, 0x6b, 0xac, 0xe1, +0x95, 0xd1, 0x24, 0x7a, 0xd1, 0x8f, 0x9b, 0x81, +0xe5, 0x11, 0x84, 0xc5, 0xfa, 0x7a, 0x82, 0x1c, +0x7e, 0x63, 0xc3, 0xdb, 0x08, 0xfb, 0xa4, 0xa3, +0xf5, 0x94, 0x75, 0x8e, 0xbb, 0xdc, 0xac, 0x32, +0x04, 0x78, 0x38, 0x1d, 0xff, 0xd6, 0xfb, 0x4e, +0xdd, 0x54, 0x34, 0x76, 0x9f, 0xcf, 0xed, 0x6f, +0x83, 0xdd, 0x53, 0x2e, 0xa7, 0x22, 0x21, 0x55, +0x80, 0xe3, 0x02, 0x2a, 0x3e, 0xd8, 0xe2, 0xc2, +0x10, 0xef, 0x87, 0xf4, 0x92, 0x69, 0x3a, 0x34, +0x3d, 0x43, 0x28, 0xf1, 0xe1, 0x67, 0xe7, 0xe6, +0x83, 0x92, 0x42, 0x87, 0x23, 0x1f, 0xc8, 0x9e, +0x7f, 0xe3, 0x82, 0x99, 0x56, 0x80, 0x44, 0x17, +0x63, 0x1e, 0xd0, 0xf9, 0xef, 0xd7, 0x0a, 0x4b, +0x3a, 0x75, 0x8f, 0xe5, 0xb2, 0x77, 0xc5, 0xe4, +0xef, 0x27, 0x1f, 0x4f, 0xcc, 0x51, 0xb8, 0x94, +0xbb, 0xe4, 0xfc, 0x6a, 0x14, 0x36, 0x37, 0xb9, +0xb6, 0x4e, 0xca, 0x00, 0x2c, 0x69, 0x48, 0xa5, +0x33, 0x71, 0xbc, 0x5d, 0x02, 0x95, 0x76, 0x29, +0x9b, 0x84, 0x9f, 0x90, 0xeb, 0x1b, 0x9b, 0x26, +0x15, 0x8a, 0xd8, 0x1a, 0xde, 0x8e, 0xe5, 0xf2, +0x1f, 0x29, 0xca, 0xde, 0xc4, 0xf0, 0xc9, 0x6c, +0xc1, 0x06, 0xe7, 0x15, 0x37, 0x8f, 0x8c, 0x98, +0x71, 0x04, 0x02, 0x76, 0x76, 0x3f, 0x15, 0x73, +0x25, 0xcf, 0xe7, 0x2f, 0x2d, 0x36, 0x51, 0xa1, +0xb4, 0x07, 0x51, 0x11, 0x3b, 0x67, 0x79, 0x5f, +0x70, 0x45, 0x11, 0x88, 0x05, 0x00, 0x7b, 0x26, +0x9d, 0x02, 0xa0, 0x55, 0xbc, 0xb1, 0xd1, 0xbd, +0xf2, 0xd7, 0x0a, 0x7c, 0xcf, 0x38, 0xbd, 0x07, +0x0b, 0xb2, 0xc8, 0xb0, 0x6a, 0x2d, 0x93, 0x97, +0xd8, 0xb3, 0x87, 0xd9, 0x72, 0x04, 0x81, 0x60, +0x95, 0xcd, 0x83, 0xfd, 0x6f, 0xb2, 0x16, 0xe0, +0xa9, 0x62, 0xa6, 0x56, 0xed, 0x44, 0x6e, 0xe3, +0x4a, 0x47, 0x00, 0xb9, 0x8e, 0x4e, 0x0a, 0x72, +0x32, 0x98, 0x61, 0x3b, 0x7d, 0x1c, 0xe8, 0x78, +0x06, 0x27, 0xf5, 0xfa, 0x09, 0x0a, 0x01, 0x83, +0xc2, 0xe9, 0x19, 0x7a, 0xc4, 0x9c, 0x37, 0x72, +0x8b, 0x12, 0x3f, 0x70, 0x54, 0xea, 0x83, 0xf8, +0x2e, 0x2e, 0x8c, 0xe8, 0x91, 0x48, 0x25, 0x7d, +0x49, 0xfc, 0x15, 0x04, 0xbf, 0x2a, 0xc6, 0xba, +0xb5, 0x07, 0x3b, 0x75, 0x25, 0x88, 0x2c, 0x30, +0x70, 0x9d, 0x4e, 0xc4, 0xa5, 0x4a, 0x90, 0xc9, +0xe3, 0xfa, 0x91, 0x9c, 0xcb, 0xc5, 0xe9, 0x0c, +0x81, 0x1c, 0x55, 0x1a, 0x39, 0xae, 0x9b, 0x56, +0x3c, 0xcc, 0x7d, 0x17, 0x82, 0xc8, 0xbd, 0xc1, +0x27, 0xcf, 0x98, 0x3a, 0x9e, 0xc9, 0x5d, 0x77, +0xed, 0x56, 0x7f, 0x14, 0xca, 0x4b, 0xfd, 0x75, +0xb9, 0xa9, 0xa2, 0x54, 0x62, 0xc5, 0x59, 0xbe, +0x9b, 0x3e, 0xfb, 0x6d, 0xf9, 0x56, 0x0b, 0xd7, +0xba, 0x59, 0x7d, 0x59, 0x5f, 0xf2, 0x77, 0xc5, +0xb9, 0x5a, 0xcf, 0x88, 0x61, 0xa7, 0xde, 0xdf, +0x63, 0x67, 0x06, 0x94, 0x5d, 0x2a, 0xd7, 0xb0, +0xf7, 0x46, 0x95, 0x3d, 0x2c, 0x14, 0xc2, 0x70, +0xe4, 0x62, 0x27, 0xaf, 0xc9, 0x8a, 0x5f, 0x69, +0xa4, 0xb7, 0x21, 0x23, 0x8c, 0x5d, 0xc8, 0x26, +0xe1, 0xfc, 0x10, 0xf7, 0x1b, 0x9b, 0x4e, 0x64, +0xfa, 0xc7, 0xac, 0x99, 0xe2, 0x15, 0x6c, 0x84, +0x0e, 0xcf, 0x47, 0x20, 0xaf, 0x58, 0x70, 0x65, +0x5f, 0x36, 0xfc, 0xec, 0x56, 0xbe, 0xdb, 0x60, +0x1d, 0x37, 0xab, 0xb7, 0xb6, 0x9e, 0x8d, 0x6a, +0xc8, 0xbb, 0x82, 0x3a, 0xc1, 0xc8, 0xbb, 0xfc, +0xb5, 0xac, 0x1b, 0x74, 0x91, 0x9f, 0xd1, 0xee, +0x23, 0x60, 0x9c, 0x0e, 0x41, 0x41, 0x58, 0x00, +0x8b, 0x45, 0x0b, 0xc7, 0x71, 0xd9, 0x0e, 0x25, +0xc3, 0x6b, 0x0f, 0xd2, 0xf4, 0xd3, 0xa1, 0x29, +0x07, 0xb4, 0x09, 0x34, 0xd6, 0xdd, 0x2d, 0xd6, +0xca, 0x5d, 0xa2, 0x4e, 0xc4, 0xd0, 0x48, 0xc7, +0xb4, 0xbe, 0x1d, 0x3e, 0x6b, 0xfa, 0x75, 0x4f, +0x0e, 0x40, 0xb9, 0xf0, 0x24, 0x52, 0xc4, 0xe5, +0x9e, 0xb5, 0x6f, 0x51, 0xfb, 0xc9, 0x87, 0xa9, +0xd6, 0xbe, 0xc4, 0x4d, 0xe3, 0x0e, 0x12, 0x5e, +0x62, 0xe4, 0x44, 0xe2, 0x77, 0x2a, 0x52, 0x53, +0xd8, 0x85, 0x0c, 0xad, 0x73, 0xdd, 0xb0, 0x22, +0xf5, 0x5f, 0x21, 0x7e, 0x00, 0x31, 0x76, 0x3e, +0xe1, 0xa1, 0x02, 0x4a, 0xdb, 0xb3, 0xb9, 0xfc, +0x1f, 0x70, 0xb1, 0x8a, 0x6e, 0xd9, 0x00, 0x8b, +0x01, 0x00, 0x5e, 0x85, 0x29, 0x0b, 0x23, 0x6e, +0x42, 0xe6, 0x89, 0x0f, 0xd2, 0xb3, 0xfc, 0x37, +0xf2, 0x07, 0x24, 0x4d, 0x7b, 0x3b, 0xff, 0xeb, +0xb4, 0x15, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, +0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_result_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_result_png = new wxImage(); + if (!img_ex_result_png || !img_ex_result_png->IsOk()) + { + wxMemoryInputStream img_ex_result_pngIS(ex_result_png_data, sizeof(ex_result_png_data)); + img_ex_result_png->LoadFile(img_ex_result_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_result_png; +} +#define ex_result_png_img ex_result_png_img() + +static wxBitmap *ex_result_png_bmp() +{ + static wxBitmap *bmp_ex_result_png; + if (!bmp_ex_result_png || !bmp_ex_result_png->IsOk()) + bmp_ex_result_png = new wxBitmap(*ex_result_png_img); + return bmp_ex_result_png; +} +#define ex_result_png_bmp ex_result_png_bmp() + +static wxIcon *ex_result_png_ico() +{ + static wxIcon *ico_ex_result_png; + if (!ico_ex_result_png || !ico_ex_result_png->IsOk()) + { + ico_ex_result_png = new wxIcon(); + ico_ex_result_png->CopyFromBitmap(*ex_result_png_bmp); + } + return ico_ex_result_png; +} +#define ex_result_png_ico ex_result_png_ico() + +#endif // EX_RESULT_PNG_H diff --git a/include/images/ex_scan.png b/include/images/ex_scan.png new file mode 100644 index 0000000000000000000000000000000000000000..396dfb4feabdd85e081bf8336304129058633c5c GIT binary patch literal 1320 zcmY+CX;4!K6or#E43U(&OiX7G0Tmtd5DXYmgR&F@acWZxiv&wwL>3hgrBoq~lr@it zLJ^duAZWq5fw&ZkC=h`X77>I3W&snjFJvdI(x|^WbI&<*@7(X#z04qTpskIa4Gade zJw!T4v82aGA-}XZR*;$vgTXU`4u=peEwhE|na4_cJ>&OMPHdC^GN?%#(geLygmo&i zN3_g;wJ~hf>0VV*pQ>a+SI*I098_lwt84kXyOa8Y(V1&wnnwbI)t>@VyL>~#^s#Q` z-ez%7n>4gTN@YnI!|M1RSrS`*eOyDod9RKoioG$+D)iJTAoVnDW}2o~Kn4Y*nFci? z(4d5jN=PdLbt2HDg!CeCRtX6-W+}%-_OSp37f^A587`pV0tPWSt}w|tfRYQSEfXG~ zX%f3E0nHYQkNqG4U%j7Mp2U7oF*>GZTDYnYlh_prI4U=^O{(k1 z1&_l=Y&sWTE`Nqyi*-+eA9Md zK3zI6YurED-VlgxD2VgQq4T)o<{Uc52dBM4_ns4qT@|3T=BIfA3pq|mf@Ygu#{_8Ub(bzb>X|nwg*!@UBbMkgoVpZr*Tf=$$yMQS7cHv zJl|yI9uG%_?<;ufhl(nz-b3s9yRngm7!eBB**@c+iOV>**WUgtxir4qH!Q58sBY^X z+t^lqCrqiOuN6j!FCm^Z-Pw}A4cEdyv#acY!)jFJxKh;d#_(duq1mbS2==EN8$unCzu)=|NpXJS+8k(y zsf-o0Hs=vz(jedS7h1^)Nk6Egj#I}j#|fGRi^DszZaa6=0txir$OP}|H5oNdm)-MvQ!!rm(9c)!#r=_M zBHea|)}|e>!%!27`lYDuS>)H4O$vGq?bkY|V%O_yDBIEKFR-P%ozXV=^u|^833oyO zaZUL45Q3B6k&=}Bj~!U7+UU*(%Cey-DHB+7FHqH zPj|}S-*ndrRToh|RU)~O z3XiIz)B{0V)^^ow^e^-{bxVdh`d7qN(nH;q3&j)u%b;lk?cGMHsP*lX<>$Ai5W`cV zkEg^CP9(=z0_K5p$GN(DxZ>PHJa7d3E&?9!g4<2N;r5nqb@(5Um=t{~HtjQj+xH3h axJ|%$eg^tVLmyfI*dZeMV8gextp5Q0yRj$$ literal 0 HcmV?d00001 diff --git a/include/images/ex_scan.pngc b/include/images/ex_scan.pngc new file mode 100644 index 0000000..dacd795 --- /dev/null +++ b/include/images/ex_scan.pngc @@ -0,0 +1,209 @@ +#ifndef EX_SCAN_PNG_H +#define EX_SCAN_PNG_H + +static const unsigned char ex_scan_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x89, 0xb9, 0xdb, 0x36, +0x88, 0xc1, 0x6f, 0xcd, 0xee, 0x41, 0xbd, 0xe9, +0x45, 0xbe, 0xe9, 0x75, 0xce, 0xef, 0x79, 0xd0, +0xef, 0x50, 0xc2, 0xea, 0x56, 0xc3, 0xea, 0x83, +0xd3, 0xf0, 0x89, 0xd5, 0xf0, 0x65, 0xc8, 0xec, +0x6a, 0xc9, 0xec, 0x6f, 0xca, 0xec, 0x94, 0xd8, +0xf1, 0x99, 0xda, 0xf1, 0x7b, 0xce, 0xed, 0x82, +0xd1, 0xed, 0xa4, 0xdd, 0xf1, 0xa8, 0xde, 0xf2, +0x8e, 0xd4, 0xee, 0x92, 0xd6, 0xef, 0xaf, 0xe1, +0xf3, 0x05, 0xa7, 0xe1, 0x48, 0xbf, 0xe9, 0x1b, +0xae, 0xe3, 0x5b, 0xc5, 0xeb, 0x38, 0xb7, 0xe5, +0x50, 0xbe, 0xe7, 0x55, 0xc0, 0xe7, 0x59, 0xc1, +0xe7, 0x86, 0xd1, 0xed, 0x6b, 0xc7, 0xe8, 0x6f, +0xc8, 0xe9, 0x95, 0xd7, 0xef, 0x7a, 0x9e, 0xa9, +0xa5, 0xc1, 0xe4, 0x66, 0x96, 0xd1, 0xc1, 0x8f, +0x36, 0xf1, 0xea, 0x87, 0xed, 0xe3, 0x60, 0xee, +0xe3, 0x60, 0xf2, 0xea, 0x87, 0xf3, 0xea, 0x87, +0xef, 0xe3, 0x5f, 0xef, 0xe4, 0x5f, 0xf3, 0xeb, +0x87, 0xf4, 0xeb, 0x87, 0xf0, 0xe4, 0x5f, 0xf1, +0xe4, 0x5f, 0xf5, 0xeb, 0x87, 0xf2, 0xe4, 0x5f, +0xf6, 0xeb, 0x87, 0xe1, 0xef, 0xf7, 0xe7, 0xda, +0x2b, 0xe8, 0xda, 0x2b, 0xe8, 0xda, 0x2a, 0xea, +0xdb, 0x2a, 0xec, 0xdb, 0x2a, 0xee, 0xdb, 0x2a, +0xef, 0xdb, 0x2a, 0xf3, 0xe5, 0x5f, 0xd7, 0xea, +0xf5, 0xe9, 0xda, 0x2a, 0xeb, 0xdb, 0x2a, 0xed, +0xdb, 0x2a, 0xef, 0xdc, 0x2a, 0xf0, 0xdc, 0x2a, +0xf4, 0xe5, 0x5f, 0xd6, 0xe9, 0xf4, 0xf3, 0xe4, +0x5f, 0xf5, 0xe5, 0x5f, 0xf7, 0xeb, 0x87, 0xf8, +0xeb, 0x87, 0xdb, 0xbd, 0x89, 0xd4, 0xe9, 0xf4, +0xf6, 0xe5, 0x5f, 0xd3, 0xe8, 0xf3, 0xf1, 0xdc, +0x2a, 0xf2, 0xdc, 0x2a, 0xf3, 0xdc, 0x2a, 0xf7, +0xe5, 0x5f, 0xd1, 0xe7, 0xf2, 0xf4, 0xdc, 0x2a, +0xf8, 0xe5, 0x5f, 0xf5, 0xdc, 0x2a, 0xf8, 0xe6, +0x5f, 0xf9, 0xeb, 0x87, 0xfa, 0xec, 0x87, 0xce, +0xe6, 0xf2, 0xce, 0xe5, 0xf2, 0xf9, 0xe6, 0x5f, +0xfb, 0xec, 0x86, 0xcc, 0xe5, 0xf1, 0xf5, 0xdd, +0x2a, 0xf7, 0xdd, 0x2a, 0xf8, 0xdd, 0x29, 0xfa, +0xe6, 0x5f, 0xcb, 0xe4, 0xf1, 0xf6, 0xdd, 0x2a, +0xfb, 0xe6, 0x5f, 0xca, 0xe3, 0xf0, 0xf9, 0xdd, +0x29, 0xc8, 0xe3, 0xf0, 0xf9, 0xec, 0x87, 0xfc, +0xec, 0x86, 0xc7, 0xe3, 0xf0, 0xc6, 0xe2, 0xef, +0xfc, 0xe6, 0x5f, 0xfd, 0xec, 0x86, 0xc5, 0xe1, +0xef, 0xfb, 0xde, 0x29, 0xfc, 0xde, 0x29, 0xfd, +0xe6, 0x5f, 0xf7, 0xdd, 0x29, 0xfa, 0xdd, 0x29, +0xfe, 0xe6, 0x5f, 0xc2, 0xe0, 0xee, 0xfd, 0xde, +0x29, 0xfe, 0xec, 0x86, 0xc0, 0xdf, 0xee, 0xb9, +0xdb, 0xec, 0xfe, 0xde, 0x29, 0xff, 0xe6, 0x5f, +0xd4, 0xe9, 0xf3, 0xbe, 0xde, 0xed, 0xad, 0xd6, +0xe9, 0x5f, 0x01, 0x98, 0x46, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0xdf, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xed, 0x94, 0xdb, 0x53, 0xda, 0x40, 0x14, +0x87, 0x6d, 0xaa, 0xad, 0xb6, 0xf6, 0xa2, 0xad, +0xd6, 0x5a, 0x7b, 0xb1, 0xad, 0x1c, 0x41, 0x83, +0x24, 0x04, 0x2f, 0x5c, 0x14, 0x30, 0x48, 0xa0, +0x46, 0x21, 0x82, 0x41, 0x45, 0x05, 0x04, 0xb1, +0x2a, 0x0a, 0x94, 0x80, 0x0a, 0xca, 0xbf, 0xde, +0xdd, 0x84, 0x58, 0xd8, 0x81, 0x07, 0x66, 0x3a, +0x9d, 0x3e, 0x78, 0x1e, 0x96, 0x17, 0xbe, 0x3d, +0xf9, 0x7e, 0xe7, 0xcc, 0xf6, 0xf4, 0x3c, 0xd4, +0xbf, 0xae, 0x47, 0x14, 0xae, 0x8e, 0x67, 0x3b, +0x84, 0x7a, 0xdc, 0xdb, 0xd7, 0xf7, 0x84, 0x7a, +0xda, 0x3f, 0x30, 0xf0, 0x8c, 0x7a, 0x3e, 0xf8, +0xe2, 0xe5, 0x2b, 0xea, 0xf5, 0xd0, 0xf0, 0xf0, +0x1b, 0xea, 0xed, 0xc8, 0xe8, 0xe8, 0x3b, 0xaa, +0x2d, 0xd2, 0x3b, 0x36, 0x36, 0xf6, 0x9e, 0xea, +0x1f, 0x1f, 0x1f, 0xff, 0x40, 0x0d, 0x4e, 0x4c, +0x4c, 0xbc, 0xa4, 0x86, 0x3e, 0x7e, 0xfa, 0xfc, +0x85, 0x1a, 0x99, 0x9c, 0xfc, 0xfa, 0x8d, 0xfa, +0x4b, 0x5d, 0xbe, 0xab, 0xdf, 0xdc, 0xf1, 0x6c, +0xf9, 0xef, 0x94, 0xc1, 0x30, 0x85, 0x7e, 0x60, +0xda, 0x68, 0x34, 0x4e, 0xa3, 0xd3, 0x64, 0x9a, +0x81, 0x59, 0x9a, 0x36, 0xcf, 0x81, 0x85, 0x61, +0x58, 0x0b, 0x58, 0x39, 0x8e, 0xb3, 0x41, 0x0b, +0x62, 0x98, 0x9f, 0x37, 0x60, 0xc4, 0xb8, 0xb0, +0xb0, 0x60, 0x04, 0xd3, 0xe2, 0xe2, 0x12, 0x0d, +0xb4, 0xdd, 0x6e, 0x67, 0x80, 0x71, 0x38, 0x1c, +0x1c, 0x70, 0x4e, 0x97, 0x6b, 0x99, 0x40, 0x56, +0x56, 0x9a, 0x91, 0xa5, 0x25, 0x37, 0x0d, 0x66, +0xbb, 0xdd, 0xc3, 0x00, 0xeb, 0xf0, 0x7a, 0x11, +0xe2, 0x5a, 0xe5, 0x7d, 0x04, 0xb2, 0xb6, 0xa6, +0x23, 0x8b, 0x26, 0x30, 0xb9, 0xdd, 0x6e, 0x33, +0x98, 0x3d, 0x1e, 0x0f, 0x0b, 0x9c, 0xd7, 0xeb, +0xe4, 0xc0, 0xcf, 0xf3, 0xbc, 0xd0, 0x1e, 0x99, +0x36, 0x35, 0x5b, 0xb0, 0xf7, 0x16, 0x01, 0x9f, +0x20, 0x04, 0xdb, 0x22, 0x3f, 0x00, 0x57, 0xc7, +0xb3, 0x15, 0x59, 0x5f, 0x57, 0xbb, 0xcc, 0x98, +0x68, 0x7a, 0x16, 0xe6, 0xcc, 0x0c, 0x63, 0x01, +0x0b, 0xcb, 0x71, 0x56, 0xb0, 0xf9, 0x97, 0x7d, +0x01, 0x08, 0x08, 0x82, 0x48, 0x76, 0xd9, 0xd8, +0x50, 0x91, 0x7b, 0x0b, 0x07, 0xb6, 0x70, 0x22, +0x8b, 0x65, 0x9e, 0xdf, 0x14, 0x40, 0x08, 0x85, +0xc3, 0x12, 0x81, 0x6c, 0x6d, 0xa9, 0x08, 0xed, +0xb6, 0xdb, 0xcd, 0xc0, 0x78, 0xb4, 0x60, 0x9d, +0x2e, 0x3f, 0xf8, 0xf8, 0x4d, 0x84, 0x88, 0xe1, +0x48, 0x24, 0xda, 0x01, 0x51, 0x67, 0xc1, 0x3a, +0x1c, 0x6a, 0xb0, 0xae, 0x55, 0x1f, 0x08, 0x9b, +0xa1, 0x90, 0x08, 0x52, 0x24, 0xb2, 0x2d, 0xb7, +0x47, 0x1a, 0x16, 0x9c, 0x66, 0xe1, 0xbb, 0xb7, +0x88, 0x45, 0x65, 0x79, 0x87, 0x40, 0x76, 0x77, +0xbb, 0x4e, 0x6c, 0x6f, 0x4f, 0xed, 0x62, 0x61, +0x59, 0xd6, 0x8a, 0x67, 0xe1, 0xb7, 0xe1, 0xfb, +0xd1, 0x2c, 0x82, 0xa2, 0x24, 0xc5, 0x60, 0x47, +0x8e, 0xc7, 0xf7, 0x89, 0x2e, 0x07, 0x07, 0x2a, +0xa2, 0xaf, 0x87, 0x8b, 0xff, 0x63, 0xb1, 0x7d, +0x28, 0x83, 0x9c, 0x48, 0x24, 0x53, 0x04, 0x72, +0x74, 0xa4, 0x21, 0xda, 0x7a, 0xac, 0xe2, 0xf5, +0xd0, 0x82, 0x95, 0xb6, 0x0f, 0xd3, 0x32, 0xc4, +0x93, 0xc9, 0x64, 0x86, 0x40, 0x8e, 0x8f, 0x55, +0x04, 0x05, 0xeb, 0xd4, 0x83, 0x15, 0xc2, 0xe1, +0x88, 0x04, 0x72, 0x3a, 0x9d, 0x88, 0x43, 0x2a, +0x99, 0xcd, 0x92, 0xc8, 0xc9, 0x89, 0x8a, 0x58, +0x39, 0xbf, 0x3f, 0xa0, 0x5b, 0x48, 0x52, 0xf4, +0x67, 0xc3, 0xe2, 0x34, 0x93, 0xc9, 0x9c, 0x12, +0xc8, 0xd9, 0x59, 0xd7, 0x89, 0x9d, 0x9f, 0xab, +0x5d, 0x6c, 0x3e, 0x9f, 0x10, 0x80, 0xa0, 0x20, +0x8a, 0x31, 0x88, 0xc9, 0x78, 0x16, 0x3b, 0xa9, +0x14, 0xba, 0xff, 0x34, 0x93, 0xcb, 0x5d, 0x10, +0x5d, 0x2e, 0x2f, 0x55, 0xa4, 0x79, 0x3d, 0x1a, +0x16, 0x59, 0x6c, 0x91, 0xcb, 0xe7, 0x0b, 0xc5, +0xf6, 0x08, 0x0e, 0x16, 0x21, 0xea, 0x7a, 0xa0, +0x60, 0x7f, 0xa5, 0x20, 0x93, 0x2d, 0x95, 0x10, +0x52, 0x28, 0x14, 0x14, 0x02, 0x29, 0x97, 0x35, +0x24, 0x14, 0x0a, 0x8b, 0x7a, 0xb0, 0x09, 0x1c, +0x6c, 0xa6, 0x54, 0x2a, 0xe5, 0xa0, 0x58, 0x28, +0x54, 0x3a, 0x20, 0x41, 0x51, 0x94, 0x74, 0x8b, +0xfd, 0x26, 0x8b, 0x0b, 0x45, 0x51, 0xae, 0x08, +0xe4, 0xfa, 0xba, 0xeb, 0xc4, 0x34, 0x04, 0x62, +0x52, 0x54, 0x46, 0xb3, 0x88, 0xc7, 0x53, 0xda, +0x2c, 0xd0, 0xfd, 0xc5, 0x62, 0xf1, 0x0a, 0xae, +0xc8, 0x2e, 0xe8, 0xe1, 0xbb, 0xb9, 0xc1, 0x8f, +0x5f, 0xcb, 0x7a, 0x20, 0x8b, 0x3c, 0xb6, 0xa8, +0x20, 0x0b, 0xa5, 0x5a, 0xad, 0xd6, 0x9a, 0x11, +0xc3, 0xed, 0x5d, 0xbd, 0x7e, 0x77, 0x6b, 0xe8, +0xc1, 0xc1, 0xa6, 0xf5, 0xf5, 0xc8, 0x94, 0xf2, +0xf9, 0x22, 0x14, 0x2b, 0x6d, 0x91, 0x29, 0x43, +0xb9, 0x5e, 0x2f, 0xe3, 0x2e, 0x72, 0x3a, 0x91, +0x48, 0xe1, 0x59, 0xe0, 0x60, 0xf3, 0x05, 0x34, +0x0b, 0xa5, 0x52, 0xad, 0x2a, 0x50, 0x23, 0x11, +0xc4, 0xa0, 0x1d, 0x43, 0x8f, 0x32, 0x69, 0xa1, +0xe8, 0x16, 0x57, 0xb5, 0x5a, 0x8d, 0x48, 0xac, +0xf1, 0x8c, 0x77, 0x93, 0xd8, 0x43, 0xfd, 0x5f, +0xf5, 0x1b, 0x60, 0xd9, 0x1d, 0xe7, 0xe4, 0xbb, +0xd2, 0xdf, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, +0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_scan_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_scan_png = new wxImage(); + if (!img_ex_scan_png || !img_ex_scan_png->IsOk()) + { + wxMemoryInputStream img_ex_scan_pngIS(ex_scan_png_data, sizeof(ex_scan_png_data)); + img_ex_scan_png->LoadFile(img_ex_scan_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_scan_png; +} +#define ex_scan_png_img ex_scan_png_img() + +static wxBitmap *ex_scan_png_bmp() +{ + static wxBitmap *bmp_ex_scan_png; + if (!bmp_ex_scan_png || !bmp_ex_scan_png->IsOk()) + bmp_ex_scan_png = new wxBitmap(*ex_scan_png_img); + return bmp_ex_scan_png; +} +#define ex_scan_png_bmp ex_scan_png_bmp() + +static wxIcon *ex_scan_png_ico() +{ + static wxIcon *ico_ex_scan_png; + if (!ico_ex_scan_png || !ico_ex_scan_png->IsOk()) + { + ico_ex_scan_png = new wxIcon(); + ico_ex_scan_png->CopyFromBitmap(*ex_scan_png_bmp); + } + return ico_ex_scan_png; +} +#define ex_scan_png_ico ex_scan_png_ico() + +#endif // EX_SCAN_PNG_H diff --git a/include/images/ex_seek.png b/include/images/ex_seek.png new file mode 100644 index 0000000000000000000000000000000000000000..130fbd8f53ff5c2c757c8173eb62a1b604555f34 GIT binary patch literal 1326 zcmV+}1=0G6P)$dan$M5O1^6ka$=CkqY#O&j+ zp~PP6<(}%}obT$j>EN30=(FhFndjV>?d7rN*p%$xt?c5jfEaDDj2{(~#oMjN#0S=-8+2;k;g#B*DnK#F|j0%w%+@ zIG(kKuGw+%>WA&)VD95x^XP-`;92wMfbif}@ZVJQ=6#RAQ?cH30002z+A8STDCyWG z>eeFb)Es@XL#xzmv*LH^)gSEB81mgwaGgbAl`r+=dg#}t=hUR^+_~n_qTtDi-^YgD z#D(V5q}{`W+`xk0$cWs(faK1gsoHLy(PX^vg!0`^^V>}K<977gNQk6&Tea1i1BihN$R<*($RcX1MKFRGK$JxVf+$KW zhy}F%>%F-wiB95-Go4N!ybt#&-#z)Ab9#DS&%Zx!2<}MUVuX;%#luYX`*kQjU` zlMN9=eZ#{e#K`E_*gHa$$j8UW8X!l8q66sme$E&ysih zt7&qYC!kO&l?v`wDPTseR?osLMNt~iXti1mw7()hkpiNeo10UDQm51DL2WP?=7BPr zOlHtpEEel?M1_c&BSs1+lgXro1&hV@3{im|lX;^N5wpo;(ZZt5X0wYEg;J%O;ZuCZ zDHa^yu-ffQqT~y3NAec0qSvcYm3fLnRm^78CC#GM>VRdZ)43x4V-;p8xoPq5?Ah6xNgTWoxp=o*tc0-}?Ubo6-WNU*YN&h}F5MZKA z00PlyGyuU^EFJ{<;NXCUP$H2C^W-qHdF1!+CzB*1Q6`E>EC|7PJWeB$N`)YtNT)MA zA&*Z`6(sm7u~>_s_vus$y&p~s$r0`tnG|LTK25Qg$z)ESkQa5#FPw|RYPB!JQhOF_ z*>zaY<#Kt*vn-njQ6gLqkFQY3Lhh_sJO}ooRAReiUr6j;FJ6yTv>w?);W7ugV)23n zwp6+*OAwdK?L_bUd~1-sJUh$5dGP|1D*;IgiByVwxm@mMIr;J89XtMchcm4nf0rwvzb1L2d001R)MObuXVRU6WV{&C-bY%cCFflMK zF)}SMF;p@zIy5snG&CzPH99abIGH6L0000bbVXQnWMOn=I&E)cX=ZrIsOk()) + { + wxMemoryInputStream img_ex_seek_pngIS(ex_seek_png_data, sizeof(ex_seek_png_data)); + img_ex_seek_png->LoadFile(img_ex_seek_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_seek_png; +} +#define ex_seek_png_img ex_seek_png_img() + +static wxBitmap *ex_seek_png_bmp() +{ + static wxBitmap *bmp_ex_seek_png; + if (!bmp_ex_seek_png || !bmp_ex_seek_png->IsOk()) + bmp_ex_seek_png = new wxBitmap(*ex_seek_png_img); + return bmp_ex_seek_png; +} +#define ex_seek_png_bmp ex_seek_png_bmp() + +static wxIcon *ex_seek_png_ico() +{ + static wxIcon *ico_ex_seek_png; + if (!ico_ex_seek_png || !ico_ex_seek_png->IsOk()) + { + ico_ex_seek_png = new wxIcon(); + ico_ex_seek_png->CopyFromBitmap(*ex_seek_png_bmp); + } + return ico_ex_seek_png; +} +#define ex_seek_png_ico ex_seek_png_ico() + +#endif // EX_SEEK_PNG_H diff --git a/include/images/ex_setop.png b/include/images/ex_setop.png new file mode 100644 index 0000000000000000000000000000000000000000..f3a9b1983b5b47c96ae910e73ab4260ae9c28b73 GIT binary patch literal 1143 zcmV--1c>{IP)B#-wM%nNGrzJd>5te}mbYo#C;w>b<`0$jI=)!tS)S z>Yk$FfrZ(}s&>qySJ}LMD z>*J&8;hW6M%aoVjwzuoBvgxw3>bkq^zQOKonbT;Cw%F6E=-!y;+?VRzrRLP5*SC1B zujqQE*JQ2NWs|?=+Lq|snys$rs;uaQsoGkq)?dWwX2$7un78KHmFC!#<=2zt){@q> zb)U22NtVh}z2-Hy=1RThb;#&boz14Or{vX=j^WVVTb!u;hfp;!=vh;meBO z#*ekO>Wt0lK!(EL%8BLApgM`e53A#l)9m2Mh~LPG-^YjE#f9R_n%=~P-olRE!h_qr zgxtV_;K!5Guy4}DpWelaCqTqQ00001bW%=J06^y0W&i*H32;bRa{vGUNB{r;NB~C3 zYd!z~0xn5JK~zY`?bK^i+CUTrVD7hwTp9u~3K&4efQ155Dpjm4f~c)k&`L{%-n1>) z8Vm%m{&hD%k|mfKr!(y*&NpUw=DfQ(dlZUEP3k|EQl-{twHmcbIry#98;mBC(V*AK z0c6TNZLwNy_D3iJkj{ZQUHHrlPB<~gy=WGlv$#E8ug7AuTIbPOJx2O`et#ek@cVEQ z(~p4#WO2zm9bC3Ac_=qPq43IMANT)2Boc{6p2Xsg1qngSR4_5mlTc_inS9EFXf&02 zhC3aSREyMFdQBwH*EcfBO%4E&da?EL)fS!|$)-f@i8MsEbNQXZ?%w{O1t(s=IdEa{ z9UyO)4`C8M+9{SY$0rd1ygNNTC_~YdQ=T+TwsVE|#Zvym-aY_BQK?j7P#cx`;~Y#@ z*NbPxQepRaGbMm(wdRV8r%``OjF8VqUpSKa`fZqr1GRJF!XOaM_w)$K<{IaFeOjS2AIsOk()) + { + wxMemoryInputStream img_ex_setop_pngIS(ex_setop_png_data, sizeof(ex_setop_png_data)); + img_ex_setop_png->LoadFile(img_ex_setop_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_setop_png; +} +#define ex_setop_png_img ex_setop_png_img() + +static wxBitmap *ex_setop_png_bmp() +{ + static wxBitmap *bmp_ex_setop_png; + if (!bmp_ex_setop_png || !bmp_ex_setop_png->IsOk()) + bmp_ex_setop_png = new wxBitmap(*ex_setop_png_img); + return bmp_ex_setop_png; +} +#define ex_setop_png_bmp ex_setop_png_bmp() + +static wxIcon *ex_setop_png_ico() +{ + static wxIcon *ico_ex_setop_png; + if (!ico_ex_setop_png || !ico_ex_setop_png->IsOk()) + { + ico_ex_setop_png = new wxIcon(); + ico_ex_setop_png->CopyFromBitmap(*ex_setop_png_bmp); + } + return ico_ex_setop_png; +} +#define ex_setop_png_ico ex_setop_png_ico() + +#endif // EX_SETOP_PNG_H diff --git a/include/images/ex_sort.png b/include/images/ex_sort.png new file mode 100644 index 0000000000000000000000000000000000000000..1d46fd34beee098f997529bf0b7714c52232a2df GIT binary patch literal 1157 zcmY+Ce>l?#9LKkGD0JGb!<|bOQ+Me`PIBs@X131ubm*x$mvXaab;*yACb5J^w1|LZ92`8{m!DQ{|nmX`=An**#5DzO7UKZPUMtXP6Il z5fWW|pN=clXUJv+$_1mFs&#^Aj(62w4Qg7mCQzhhh$nO8bCLPQz+!<`3u9yCLG%bb z?15U4$&kq)mBQ#~6BITAuO9LqLIsSB)IkpP_6i{rRI10&2s?LDwdh7Z8fJ@NCJm;! zFd4t3ITfD?Q+k-tfKm+#6{x2Ho*jVkUqDF&&9OlR$ex0982Sc5B7idXTM?bXpLR$}rBv8e3)XBr99y8x4qpF)h&;TP34lIsGOB-m{TFz%8 zmqJJT(fm=Knjt1)R-Gi%qYx#33{uyzT`1HF4+_yMfZVAcm^py)vTU8m)18%`sKnhj z*_|AHuUzvW>}&>XtFnD#12=5jSD-l}O2Xy6AEAsv_w~<-a~= zR7XZDI#BoKl9GL|_MWroq;CqTDQRU3U&c7L*{b^OT#I7a=4*Z|__`WB7ft(h<#lmL zwVUd+eFuzNvy3((g8#?Rm4)+uXRZ{0S zek&Lj2&|vqTX>h8z4p+Yu5=*Wb*%X-%fX;6ZCeB97F{VJdvHeYIL!geO(qzY#fd~4 zgP|L%u1gYzNTmVY-#^*ix*}V#)w7h0IfJh~vtp7<>2HN#d3gq@q^0Jug@L!_)33u3 zSD40j=<&?;yenlDmRu9KMFjKSyr(4e9y6VRvwCmgKfwx9qwK@bjUR zis9q0OCHVF-XIovFSc|R*2(*Lx0j!tMXN^#U$e&f2a$)ekM=$o%{USr>i$P$C?Y6l zf)l~f$=Q+M6yQv7ciHCd;_?IGCwBtDjc339GvLo~Mi}$-CxEcyBk-Zyo#6Tj=q}h_ PfdD9qH;q`i`*8CAb@5|F literal 0 HcmV?d00001 diff --git a/include/images/ex_sort.pngc b/include/images/ex_sort.pngc new file mode 100644 index 0000000..57c95a8 --- /dev/null +++ b/include/images/ex_sort.pngc @@ -0,0 +1,189 @@ +#ifndef EX_SORT_PNG_H +#define EX_SORT_PNG_H + +static const unsigned char ex_sort_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x75, 0xa6, 0xc7, 0x36, +0x88, 0xc1, 0x6f, 0xcd, 0xee, 0x43, 0xbd, 0xe9, +0x4c, 0xc0, 0xe9, 0x53, 0xc2, 0xea, 0x5d, 0xc5, +0xeb, 0x66, 0xc8, 0xec, 0x71, 0xcb, 0xec, 0x7a, +0xce, 0xec, 0x83, 0xd1, 0xed, 0x8b, 0xd4, 0xee, +0xad, 0xdf, 0xf3, 0x07, 0xa8, 0xe2, 0x15, 0xad, +0xe3, 0x2d, 0xb4, 0xe5, 0x41, 0xba, 0xe5, 0x4e, +0xbe, 0xe6, 0x5a, 0xc1, 0xe7, 0x64, 0xc5, 0xe8, +0x92, 0xd5, 0xef, 0x72, 0x96, 0xa1, 0xff, 0x68, +0x68, 0xff, 0xe7, 0xe7, 0xff, 0xde, 0xde, 0x48, +0xd6, 0x01, 0xda, 0xff, 0xc8, 0xcc, 0xff, 0xb3, +0xff, 0xd4, 0xd4, 0x00, 0x00, 0x00, 0xff, 0xd1, +0xd1, 0xff, 0xdc, 0xdc, 0xbd, 0xff, 0x9c, 0xbb, +0xff, 0x99, 0xb9, 0xff, 0x95, 0xc8, 0xff, 0xac, +0xff, 0xda, 0xda, 0xb7, 0xff, 0x92, 0xff, 0xcd, +0xcd, 0xb5, 0xff, 0x8f, 0xff, 0xe2, 0xe2, 0xd2, +0xff, 0xbb, 0xff, 0x3d, 0x3d, 0x4d, 0xe7, 0x01, +0xbb, 0x9b, 0x01, 0xff, 0xee, 0x9e, 0xff, 0xeb, +0x88, 0xff, 0xea, 0x83, 0xff, 0xe8, 0x7a, 0xfd, +0xe6, 0x75, 0x7a, 0x8f, 0xff, 0xe9, 0xed, 0xff, +0xe1, 0xe6, 0xff, 0xdf, 0xe5, 0xff, 0xdd, 0xe2, +0xff, 0xe5, 0xea, 0xff, 0xff, 0xe3, 0x57, 0xff, +0xe0, 0x4b, 0xff, 0xdf, 0x44, 0xff, 0xe6, 0x6b, +0xd6, 0xdd, 0xff, 0xd4, 0xdb, 0xff, 0xd1, 0xd9, +0xff, 0xce, 0xd6, 0xff, 0xcb, 0xd4, 0xff, 0xd9, +0xdf, 0xff, 0xff, 0xdd, 0x38, 0xff, 0xe5, 0x64, +0xca, 0xd3, 0xff, 0x86, 0xa9, 0x64, 0x52, 0x8d, +0x19, 0xd7, 0xb2, 0x01, 0xab, 0xd4, 0x6c, 0x48, +0x65, 0xff, 0xb3, 0xff, 0x8c, 0xb0, 0xff, 0x89, +0xaf, 0xdb, 0x72, 0xb3, 0xe1, 0x77, 0xff, 0xc9, +0xc9, 0xa6, 0xff, 0x78, 0xa1, 0xff, 0x72, 0x9c, +0xff, 0x6a, 0x97, 0xff, 0x62, 0x93, 0xff, 0x5c, +0xad, 0xff, 0x83, 0xa2, 0xc5, 0x5f, 0xa5, 0xcb, +0x64, 0xb0, 0xdc, 0x73, 0xb7, 0xe7, 0x7c, 0xb9, +0xec, 0x80, 0xff, 0xc5, 0xc5, 0xff, 0xbd, 0xbd, +0xff, 0xb9, 0xb9, 0xff, 0xb5, 0xb5, 0x8d, 0xff, +0x53, 0xa9, 0xff, 0x7e, 0xff, 0xc1, 0xc1, 0x99, +0xff, 0x65, 0x0c, 0xc5, 0xff, 0xc0, 0xf0, 0xff, +0xa6, 0xe9, 0xff, 0x9e, 0xe8, 0xff, 0x9c, 0xe7, +0xff, 0xb6, 0xee, 0xff, 0x85, 0xe2, 0xff, 0x7f, +0xe0, 0xff, 0x7c, 0xdf, 0xff, 0x76, 0xde, 0xff, +0x96, 0xe6, 0xff, 0x72, 0xdd, 0xff, 0xa2, 0xe9, +0xff, 0x93, 0xe5, 0xff, 0xac, 0xeb, 0xff, 0x07, +0xc4, 0xff, 0xc6, 0xd0, 0xff, 0xc4, 0xcd, 0xff, +0xc2, 0xcc, 0xff, 0xc1, 0xcb, 0xff, 0xb0, 0x99, +0x2d, 0xec, 0xd5, 0x69, 0xe9, 0xd2, 0x66, 0xf6, +0xdf, 0x73, 0xb1, 0xbe, 0xff, 0xad, 0xba, 0xff, +0xda, 0xc3, 0x57, 0xf7, 0xe0, 0x74, 0xd1, 0xba, +0x4e, 0x9a, 0xbf, 0x84, 0x8f, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0x3c, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xed, 0xd3, 0xeb, 0x57, 0x12, 0x41, 0x18, +0xc0, 0xe1, 0x95, 0xec, 0x7e, 0xd1, 0x6e, 0xae, +0x22, 0xbc, 0x0b, 0x2c, 0x17, 0x6f, 0xdc, 0x24, +0x40, 0x8b, 0x8b, 0x18, 0xb2, 0x22, 0xa6, 0x88, +0x90, 0x15, 0x26, 0xd8, 0x26, 0x68, 0x85, 0x91, +0x08, 0x48, 0xbb, 0xe5, 0xbf, 0xde, 0x0c, 0xb0, +0xad, 0x33, 0xed, 0x9e, 0x83, 0x7d, 0xe8, 0xf4, +0xc1, 0xdf, 0x7c, 0xdb, 0xf7, 0x3c, 0x67, 0x98, +0xdd, 0x81, 0x61, 0xae, 0xfa, 0x47, 0x0d, 0x19, +0xd4, 0x86, 0x06, 0x9b, 0x18, 0xae, 0x0d, 0x5f, +0xbf, 0x71, 0xf3, 0xd6, 0xed, 0x3b, 0x77, 0xef, +0xdd, 0x37, 0x30, 0x03, 0x4d, 0x0c, 0xc3, 0x0f, +0x46, 0x46, 0x46, 0x47, 0x1f, 0x3e, 0x7a, 0xfc, +0xe4, 0x29, 0x45, 0xf4, 0x26, 0x7f, 0xb1, 0xcb, +0xd8, 0x85, 0x5f, 0x3c, 0xc6, 0x0c, 0x34, 0x61, +0xc7, 0x27, 0x94, 0xc6, 0x59, 0x82, 0x18, 0x27, +0x4d, 0x4a, 0x93, 0x46, 0x82, 0x4c, 0x98, 0xcd, +0x80, 0x17, 0xc7, 0x59, 0x28, 0x62, 0xb2, 0xa2, +0xc0, 0x6a, 0xb5, 0xf1, 0x76, 0x2d, 0xc2, 0x21, +0xe2, 0xd0, 0x24, 0x36, 0x9e, 0x77, 0x6a, 0x10, +0x0e, 0x2f, 0x97, 0x16, 0xb1, 0x01, 0xef, 0x74, +0x4e, 0x51, 0x04, 0x9f, 0xc5, 0x62, 0xb1, 0x38, +0x1c, 0x8e, 0x69, 0x8d, 0xb3, 0xd8, 0x4d, 0x76, +0xd4, 0x0c, 0x41, 0x66, 0x59, 0xb5, 0x59, 0x82, +0xcc, 0x19, 0xd5, 0xe6, 0x2e, 0x0e, 0xdc, 0x1e, +0xaf, 0xd7, 0xe7, 0xf3, 0xf9, 0xfd, 0xfe, 0x79, +0x8f, 0x9b, 0x20, 0x81, 0x67, 0xc1, 0x60, 0x08, +0x15, 0x0e, 0x87, 0x17, 0x02, 0x04, 0xf1, 0xc2, +0x22, 0x5a, 0xcf, 0xe1, 0x05, 0x44, 0x28, 0x12, +0x8c, 0xc6, 0x62, 0x10, 0x87, 0xa5, 0xa5, 0xc4, +0x32, 0x49, 0x7c, 0x7d, 0xf0, 0x12, 0x92, 0x14, +0x09, 0xc5, 0x62, 0x71, 0x4c, 0x12, 0x7f, 0x92, +0x1e, 0xd0, 0x22, 0x71, 0x04, 0x20, 0xb1, 0xb2, +0x12, 0x25, 0x89, 0x07, 0x9d, 0x22, 0x12, 0x49, +0x26, 0x93, 0x8b, 0x3e, 0x85, 0xa4, 0x84, 0x14, +0x26, 0x0b, 0xe8, 0x14, 0xcb, 0xa8, 0x68, 0x34, +0x44, 0x90, 0x55, 0xb7, 0xda, 0x6a, 0xff, 0x99, +0x90, 0xc6, 0x66, 0x2d, 0xa0, 0xb6, 0x46, 0xbc, +0xfd, 0x19, 0x7c, 0x23, 0x78, 0xe7, 0x54, 0x66, +0x1d, 0x7d, 0xb0, 0x94, 0xd0, 0xed, 0xd5, 0x06, +0x32, 0xec, 0xb4, 0xd9, 0xcc, 0xa1, 0x5c, 0xae, +0x4d, 0xf2, 0x23, 0x1b, 0xad, 0xd9, 0xad, 0xad, +0x1c, 0xe4, 0xb6, 0xf3, 0xf9, 0x82, 0x91, 0x11, +0x5e, 0xef, 0xec, 0xa4, 0xd3, 0x6f, 0x36, 0xde, +0xbe, 0x13, 0x18, 0xd6, 0x5c, 0x2c, 0xc2, 0x2e, +0x5a, 0xef, 0xf7, 0x36, 0x49, 0x62, 0x43, 0x22, +0x07, 0xf9, 0x7c, 0xbe, 0x54, 0xfe, 0xbd, 0x0b, +0x12, 0x68, 0x17, 0x6e, 0x7f, 0x1f, 0x03, 0xd8, +0xa3, 0x09, 0x9f, 0xcb, 0x7d, 0xd8, 0x46, 0xa4, +0x54, 0xca, 0x2a, 0xd7, 0x42, 0xc0, 0x02, 0x91, +0xdd, 0x2e, 0x40, 0xa4, 0x48, 0x12, 0x7b, 0x26, +0xb3, 0x5e, 0x28, 0x14, 0xca, 0xe5, 0xac, 0x4d, +0x21, 0xbd, 0x37, 0xc6, 0x3a, 0xd0, 0x29, 0x70, +0xc5, 0x22, 0x47, 0x10, 0xdd, 0x9b, 0xa4, 0x7f, +0xfb, 0xc4, 0x8f, 0x07, 0xb8, 0x4a, 0xa5, 0x52, +0x3d, 0x14, 0x99, 0x81, 0x26, 0xe2, 0xc1, 0x11, +0x1c, 0xc1, 0x27, 0xf8, 0x0c, 0x5f, 0x6a, 0x14, +0xd1, 0x9b, 0xe0, 0x41, 0xf7, 0x31, 0x1c, 0x6b, +0x10, 0xcd, 0x89, 0xf8, 0xb5, 0xff, 0x18, 0x8e, +0xeb, 0x14, 0xd1, 0x9b, 0x88, 0x87, 0x95, 0x6a, +0xb5, 0x5a, 0xab, 0xd5, 0xea, 0xf5, 0x6f, 0x14, +0xd1, 0x9b, 0x9c, 0x88, 0x6a, 0x27, 0xcc, 0x40, +0x93, 0x40, 0xb4, 0xd1, 0x68, 0x9c, 0xa2, 0x9a, +0xad, 0x38, 0x71, 0x5f, 0x99, 0xf6, 0xfc, 0x59, +0xaf, 0x4e, 0xe7, 0x7b, 0x9b, 0x20, 0x0d, 0x49, +0x92, 0x40, 0x06, 0x59, 0x96, 0x5b, 0x14, 0x39, +0x83, 0x1f, 0xfd, 0xd5, 0x21, 0xc9, 0xa9, 0x24, +0xc9, 0x97, 0x26, 0xf2, 0x65, 0x49, 0xac, 0xd9, +0x6c, 0xf5, 0xa2, 0xcf, 0xf2, 0xb3, 0xa3, 0x44, +0x9e, 0x45, 0xf7, 0xbf, 0xc7, 0x9c, 0xb7, 0xd5, +0xce, 0x99, 0xab, 0xfe, 0xe3, 0x7e, 0x01, 0xe5, +0xdc, 0xd6, 0xf5, 0x68, 0xe0, 0x9b, 0x58, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_sort_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_sort_png = new wxImage(); + if (!img_ex_sort_png || !img_ex_sort_png->IsOk()) + { + wxMemoryInputStream img_ex_sort_pngIS(ex_sort_png_data, sizeof(ex_sort_png_data)); + img_ex_sort_png->LoadFile(img_ex_sort_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_sort_png; +} +#define ex_sort_png_img ex_sort_png_img() + +static wxBitmap *ex_sort_png_bmp() +{ + static wxBitmap *bmp_ex_sort_png; + if (!bmp_ex_sort_png || !bmp_ex_sort_png->IsOk()) + bmp_ex_sort_png = new wxBitmap(*ex_sort_png_img); + return bmp_ex_sort_png; +} +#define ex_sort_png_bmp ex_sort_png_bmp() + +static wxIcon *ex_sort_png_ico() +{ + static wxIcon *ico_ex_sort_png; + if (!ico_ex_sort_png || !ico_ex_sort_png->IsOk()) + { + ico_ex_sort_png = new wxIcon(); + ico_ex_sort_png->CopyFromBitmap(*ex_sort_png_bmp); + } + return ico_ex_sort_png; +} +#define ex_sort_png_ico ex_sort_png_ico() + +#endif // EX_SORT_PNG_H diff --git a/include/images/ex_subplan.png b/include/images/ex_subplan.png new file mode 100644 index 0000000000000000000000000000000000000000..e13d7794e91fc0842702b0b34c1a9b61607dcf92 GIT binary patch literal 1283 zcmV+e1^oJnP)NdYtf>m5`V;n496cyz8c@(AnDc$Hlj+rEHy)MVE~( zje!}GmC?n;b=BCB+u@bv?y2JJpyBGA(b0>*y>Y_8Zq(O`&Cz|**oW5HjmgV)&CP_q zyl}CsSnBe)wXlcC#=6+uj;W$#*yDlM;eY7uxXQ|X(bI*zwrqx}WKxY8b*9HQh{34O zXl={vL%r!uzvx%P>V?$sl-Tfk&g_TN?ycYR5Ub*n)$gj(YI2sLtk-VAk2du2$?)v9 z@9DJj?Z)lovFzcl@ae+p;+*H(mgLov>)x!v$huvZB(B3-?jshY`Moz7yq?t<^;!0Fhh?&7_NyG?JLL&vIhi>qwE$G7O#rsmV5>)g5C#f9C% zgW=4J+`xh5&Y;`Af8@=c4PV1400001bW%=J06^y0W&i*H32;bRa{vGUNB{r;NB~C3 zYd!z~0=h{=K~zY`&6Md=+CUh_IT8h`QXz`eqXw2kLy;n)g4XJmdbG8avTB3Kp(v<$ z)p}e1_3p-?5Zu7nnNFV%o0)f?-@M1}Mx*)X((3dKs}!TxX;p}pR)f)GG8$jBwRd!w z%`ZDUEmpIMqcggeuI?_I0%_~9**P5z(YJQL>Qz?8^x17DJq=;{x!wU~4cdV|%WIZ~ zu$^Xx5QDtK35c8yeo&)jELJMwVp*3&xINyX;bB4W`rcrMwbBt;yniI{)+-1?FfbY# z<5dwki^CHb36sj4;gCDzP(xg7TRUOE_;`3?5(g$H!Vxb}L0qhf6q?R^LC z+aGBz3y6${r7U>JZlAM>UNjEhXh=TF8Nd2bRuFzH;GTIO2?j%Mzk8N%fEdW$AV22w zL@?s0-wW-D+06_Mp*`e&BlRIa<9G3lpVBjaeSfJrI7i?75F?V; zhba6A>5ka^!s61W*yk_H%U@$pB6W_~LOdQ{ip?)B&3~&x5><%OLCKO($?{#QQC=UB zgwAm@Mw(G_XV%g#!oHwzf7zl+6?hyND182=m3g{rzGd!crMCwGM*d8pU;Vu)TYD zgz$MJ63OJ|-to!teyLO{m&;J$!1{@Z8k8**uFuf<<<-sY1Q997kA*u1=_V(_Af+!tz^Qco}$N!-}nbr1E9_U2o0000bbVXQnWMOn=I%9HW zVRU5xGB7bPEip1JFfmjzFgi3dIy5vZFf}?bFgTed9smFUC3HntbYx+4WjbwdWNBu3 t05UK!FfA}SEif@uGBY|fG&(RgD=;-WFfhuORjdF2002ovPDHLkV1oA>oooOA literal 0 HcmV?d00001 diff --git a/include/images/ex_subplan.pngc b/include/images/ex_subplan.pngc new file mode 100644 index 0000000..ef487f4 --- /dev/null +++ b/include/images/ex_subplan.pngc @@ -0,0 +1,205 @@ +#ifndef EX_SUBPLAN_PNG_H +#define EX_SUBPLAN_PNG_H + +static const unsigned char ex_subplan_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc2, 0xc3, 0xd0, 0x96, +0x99, 0xd1, 0x7f, 0x83, 0xd1, 0x74, 0x78, 0xd3, +0x66, 0x6b, 0xd1, 0xa2, 0xa5, 0xe4, 0xb6, 0xb8, +0xea, 0xbd, 0xbf, 0xec, 0xc4, 0xc5, 0xef, 0xc2, +0xc4, 0xee, 0xc6, 0xc8, 0xef, 0xc8, 0xc8, 0xf0, +0xc9, 0xca, 0xf0, 0xcb, 0xcc, 0xf1, 0xcd, 0xce, +0xf2, 0xcf, 0xd0, 0xf2, 0xd1, 0xd1, 0xf2, 0xd3, +0xd3, 0xf3, 0xd7, 0xd7, 0xf5, 0xac, 0xae, 0xe8, +0xaf, 0xb1, 0xe8, 0xa9, 0xab, 0xe6, 0xb8, 0xb9, +0xeb, 0xbe, 0xbf, 0xed, 0xc0, 0xc1, 0xed, 0xb2, +0xb4, 0xe9, 0x92, 0x96, 0xdf, 0x98, 0x9b, 0xe1, +0xba, 0xbc, 0xeb, 0xa6, 0xa8, 0xd0, 0xd9, 0xda, +0xf5, 0xc7, 0xc5, 0xb7, 0xab, 0xa5, 0x6c, 0x9d, +0x94, 0x45, 0x97, 0x8d, 0x2e, 0x8d, 0x81, 0x19, +0x92, 0x95, 0xd1, 0xc5, 0xc5, 0x75, 0xd5, 0xd8, +0x91, 0xdb, 0xe1, 0x95, 0xe5, 0xee, 0xa9, 0xe2, +0xec, 0xa0, 0xe1, 0xea, 0x9c, 0xd1, 0xd1, 0x8b, +0xc0, 0xbd, 0x71, 0xc2, 0xc0, 0x6e, 0xd4, 0xd7, +0x8a, 0xcd, 0xd1, 0x7d, 0xd2, 0xd8, 0x87, 0xd6, +0xd9, 0x8d, 0xc9, 0xcb, 0x76, 0xcd, 0xcd, 0x84, +0xbe, 0xbc, 0x70, 0xb1, 0xac, 0x58, 0xea, 0xf2, +0xb8, 0xb5, 0xb0, 0x87, 0xc8, 0xc6, 0xba, 0xd8, +0xdd, 0x8e, 0xa9, 0xa2, 0x64, 0xd8, 0xe3, 0x81, +0xd7, 0xe1, 0x7f, 0xe8, 0xed, 0xb8, 0xca, 0xca, +0x7d, 0xd1, 0xd3, 0x85, 0xbc, 0xb6, 0x6c, 0x86, +0xa9, 0x64, 0x52, 0x8d, 0x19, 0x75, 0xa6, 0xc7, +0x36, 0x88, 0xc1, 0xa8, 0xcf, 0x68, 0x6d, 0xcb, +0xec, 0x43, 0xbd, 0xe9, 0x4d, 0xbf, 0xe8, 0x57, +0xc3, 0xea, 0x85, 0xd4, 0xf0, 0x94, 0xd8, 0xf0, +0x7a, 0xce, 0xec, 0x87, 0xd3, 0xee, 0xad, 0xdf, +0xf3, 0x10, 0xab, 0xe2, 0x92, 0xd5, 0xef, 0xaa, +0xd2, 0x6a, 0x72, 0x96, 0xa1, 0xac, 0xd7, 0x6e, +0xc1, 0x8f, 0x36, 0xf4, 0xf1, 0xc9, 0xf0, 0xec, +0xb6, 0xef, 0xe9, 0xb4, 0xf3, 0xed, 0xc6, 0xed, +0xe4, 0xb1, 0xec, 0xe1, 0xae, 0xf0, 0xe9, 0xc2, +0xea, 0xe2, 0x9c, 0xe7, 0xdb, 0x96, 0xe4, 0xd5, +0x92, 0xeb, 0xde, 0xac, 0xc1, 0xc8, 0xba, 0x5d, +0x97, 0x24, 0xae, 0xda, 0x71, 0xe8, 0xdf, 0x99, +0xe3, 0xd1, 0x8e, 0xea, 0xdc, 0xaa, 0x9e, 0xb5, +0x87, 0x78, 0xad, 0x3d, 0xb8, 0xe9, 0x7e, 0xe9, +0xda, 0xa9, 0x9a, 0xc9, 0x5d, 0x9d, 0xce, 0x62, +0xba, 0xee, 0x82, 0xef, 0xe6, 0xc0, 0xe9, 0xd8, +0xa7, 0xee, 0xe2, 0xbd, 0x87, 0xbb, 0x4d, 0x6f, +0x9c, 0x43, 0xc7, 0xaa, 0x75, 0x8b, 0xab, 0x6c, +0xbf, 0xc7, 0xb7, 0xe8, 0xd6, 0xa6, 0xe6, 0xd3, +0xa3, 0xeb, 0xdc, 0xb9, 0xde, 0xc5, 0x85, 0xdd, +0xc2, 0x83, 0xe1, 0xcc, 0x8b, 0xdc, 0xc0, 0x81, +0xe5, 0xce, 0xa0, 0xdb, 0xbe, 0x7f, 0xe4, 0xcd, +0x9e, 0x0d, 0x5f, 0xc3, 0x29, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0xba, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xcd, 0x94, 0xe9, 0x53, 0xda, 0x40, 0x18, +0xc6, 0x39, 0x12, 0x05, 0xaa, 0x52, 0x21, 0x8a, +0xd4, 0xa3, 0x06, 0x96, 0x43, 0x43, 0x91, 0x22, +0xa2, 0x82, 0xd6, 0xea, 0x96, 0x7a, 0xb4, 0xb5, +0x94, 0xb2, 0x6a, 0x83, 0xc8, 0xa1, 0x28, 0xa8, +0x78, 0xd5, 0x7a, 0x5b, 0xff, 0xf5, 0xee, 0xc6, +0xa0, 0x10, 0xdc, 0xc0, 0xd8, 0x99, 0x4e, 0x9f, +0x0f, 0x9b, 0x99, 0x77, 0x9f, 0xdf, 0xbc, 0xc7, +0xee, 0x46, 0xa3, 0xf9, 0xe7, 0xd2, 0xea, 0xf4, +0x0c, 0xab, 0x14, 0xa3, 0xd7, 0x69, 0x55, 0x88, +0x96, 0x56, 0x83, 0xd1, 0x64, 0x32, 0x1a, 0x5f, +0xb4, 0xb5, 0x77, 0x74, 0x98, 0xcd, 0x2f, 0x3b, +0x3b, 0x2d, 0x56, 0xb3, 0x89, 0xa3, 0x33, 0xba, +0x96, 0xae, 0xee, 0x2e, 0x9b, 0x02, 0x69, 0xeb, +0xb1, 0xd9, 0x39, 0x1d, 0x0d, 0xd1, 0xb7, 0x76, +0xbf, 0xea, 0x55, 0x56, 0xc6, 0xf4, 0xd9, 0x6d, +0x26, 0x3d, 0x0d, 0x61, 0xfa, 0xb9, 0xde, 0x01, +0x65, 0x0d, 0xda, 0x81, 0x3e, 0xcb, 0x6b, 0x96, +0x86, 0xb0, 0x9d, 0x66, 0x86, 0x10, 0x83, 0xbc, +0xc3, 0x09, 0x88, 0x9c, 0x0e, 0x7e, 0x50, 0xa3, +0x65, 0x2c, 0x56, 0x2a, 0xe2, 0x62, 0x59, 0x97, +0x44, 0xb8, 0x3d, 0xde, 0xa1, 0xe1, 0x61, 0x41, +0xf0, 0xfa, 0xde, 0x60, 0x86, 0xb5, 0xd2, 0x11, +0x59, 0xbc, 0x7f, 0x24, 0xf0, 0xd6, 0x2b, 0x08, +0x42, 0x30, 0x30, 0x1a, 0x1a, 0xe3, 0x55, 0x11, +0x39, 0x8b, 0xc3, 0x13, 0x18, 0x09, 0x93, 0xca, +0x9c, 0xe1, 0x90, 0x3b, 0xe4, 0x50, 0x43, 0x5c, +0x6c, 0x5b, 0x3b, 0x61, 0xc0, 0xf8, 0x78, 0x78, +0x62, 0x12, 0x07, 0x26, 0x27, 0xc2, 0x11, 0x2f, +0x50, 0x41, 0x5c, 0xac, 0x89, 0xe3, 0x8c, 0x98, +0x89, 0x02, 0x10, 0xbd, 0x0f, 0x4d, 0x3a, 0x23, +0x11, 0x35, 0x84, 0xb5, 0x18, 0x38, 0xce, 0x5e, +0xbb, 0x0b, 0xd4, 0x11, 0xdc, 0x89, 0xcd, 0xc6, +0xd6, 0x64, 0xc1, 0x48, 0x10, 0xa8, 0xb6, 0xcf, +0x1a, 0x7a, 0xf0, 0x5e, 0x14, 0x0c, 0x0d, 0x55, +0x18, 0x10, 0x6c, 0x06, 0x89, 0x82, 0xe1, 0xa9, +0x69, 0x41, 0x66, 0x9a, 0x43, 0xc0, 0xb8, 0x30, +0x35, 0xed, 0x7d, 0x07, 0xee, 0xdb, 0x1f, 0x69, +0x2e, 0x0b, 0x88, 0x8c, 0x86, 0xa5, 0x2c, 0x78, +0xc8, 0x6e, 0x9f, 0xb3, 0x89, 0x5e, 0x34, 0x0e, +0xdf, 0x68, 0x48, 0x3e, 0xca, 0x19, 0xbf, 0xfa, +0x51, 0x56, 0x10, 0x7e, 0x2c, 0xe0, 0x9e, 0x79, +0x1f, 0x09, 0x06, 0x43, 0x6e, 0xbf, 0x7b, 0x96, +0x6f, 0x80, 0x18, 0xc8, 0xde, 0x20, 0x3f, 0xe6, +0xf3, 0x44, 0x30, 0xe2, 0xf1, 0x85, 0x66, 0x1b, +0x5c, 0x4b, 0xd6, 0xde, 0xf3, 0xe4, 0xe5, 0xb7, +0xd2, 0xdf, 0x0b, 0xed, 0x89, 0xd9, 0xcd, 0x0c, +0x0d, 0xa1, 0x3d, 0xe4, 0x7e, 0x23, 0xf5, 0x21, +0x3f, 0xe3, 0x77, 0xf1, 0x8c, 0x9f, 0xd2, 0x33, +0x7e, 0x7d, 0x7f, 0xa9, 0x39, 0x38, 0x47, 0xdf, +0xfc, 0x10, 0x23, 0x92, 0xd7, 0x87, 0x28, 0xfc, +0x08, 0xe9, 0x8e, 0xd8, 0xfc, 0xc2, 0xe2, 0xd2, +0xa7, 0xd8, 0xe7, 0x2f, 0xcb, 0xcb, 0x5f, 0x63, +0x4f, 0x22, 0x75, 0x8e, 0xd8, 0x42, 0x3c, 0x1e, +0x5f, 0x8a, 0xcd, 0x2f, 0x2e, 0xcd, 0x7f, 0xab, +0x42, 0x12, 0x55, 0x88, 0xd2, 0x41, 0xc9, 0x92, +0x50, 0xc9, 0xf2, 0x5d, 0xaa, 0x51, 0x5e, 0x1f, +0x91, 0xe4, 0x23, 0x52, 0xe7, 0x40, 0x2b, 0xab, +0xab, 0x6b, 0x2b, 0xe8, 0x87, 0x28, 0xa6, 0xd6, +0xd1, 0x93, 0x48, 0x9d, 0x03, 0xad, 0xa6, 0xd3, +0xe9, 0x35, 0x24, 0x6e, 0x64, 0x32, 0x59, 0x54, +0x19, 0x6f, 0x2e, 0xbf, 0x99, 0xcf, 0x55, 0x46, +0xad, 0x74, 0x48, 0x81, 0x2d, 0x11, 0x89, 0x99, +0x4c, 0x61, 0x1b, 0x11, 0x17, 0x9e, 0x55, 0x6e, +0xa7, 0x98, 0x2c, 0xee, 0xe4, 0x34, 0xb0, 0x44, +0x18, 0x85, 0x03, 0x07, 0xd6, 0xb6, 0xb6, 0x36, +0x44, 0x94, 0xcd, 0x14, 0x0a, 0xbb, 0x88, 0x10, +0x09, 0x08, 0xf3, 0xc5, 0xbd, 0xfd, 0xfd, 0x62, +0x1e, 0xc2, 0x52, 0x19, 0x33, 0xb5, 0x0e, 0x82, +0xe0, 0x1a, 0xc5, 0x75, 0x74, 0xb0, 0xbd, 0x7b, +0x78, 0x84, 0xf0, 0x79, 0x24, 0x12, 0xc9, 0xe4, +0xe6, 0xde, 0xf1, 0xc9, 0xf1, 0x7e, 0xa9, 0x54, +0x2a, 0x97, 0xcb, 0x50, 0xe1, 0xc0, 0xfa, 0x89, +0x88, 0xe4, 0x15, 0x67, 0x49, 0x24, 0x21, 0x84, +0x27, 0xa7, 0xbf, 0x4e, 0x4f, 0xf0, 0xb7, 0x4c, +0xb2, 0xd4, 0x3a, 0x48, 0x96, 0xf5, 0x54, 0x2a, +0x7b, 0x80, 0x8e, 0xce, 0xce, 0xce, 0x2f, 0xa4, +0x5e, 0xaa, 0x66, 0x05, 0xcb, 0x52, 0x2f, 0xb5, +0x0e, 0x1c, 0x48, 0x49, 0x35, 0x1e, 0x5e, 0x5e, +0x5e, 0x9d, 0x3f, 0x4c, 0xac, 0xe6, 0x72, 0x2a, +0x1d, 0x1a, 0x94, 0x2d, 0x14, 0xae, 0xcf, 0xd0, +0xf9, 0xe5, 0xd5, 0xcd, 0xed, 0xe3, 0xb9, 0x54, +0xab, 0xce, 0x81, 0xb6, 0xaf, 0xaf, 0x49, 0xe0, +0xea, 0xe6, 0xf7, 0x1d, 0x05, 0x51, 0x3a, 0xd0, +0xd1, 0x21, 0xa9, 0xf1, 0xe2, 0xf6, 0xf6, 0xee, +0x82, 0x82, 0x28, 0x1d, 0x75, 0xf3, 0xa8, 0x53, +0x63, 0xc7, 0xff, 0xa1, 0x3f, 0x99, 0xd5, 0xf6, +0x52, 0x1e, 0xe8, 0x44, 0xe6, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_subplan_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_subplan_png = new wxImage(); + if (!img_ex_subplan_png || !img_ex_subplan_png->IsOk()) + { + wxMemoryInputStream img_ex_subplan_pngIS(ex_subplan_png_data, sizeof(ex_subplan_png_data)); + img_ex_subplan_png->LoadFile(img_ex_subplan_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_subplan_png; +} +#define ex_subplan_png_img ex_subplan_png_img() + +static wxBitmap *ex_subplan_png_bmp() +{ + static wxBitmap *bmp_ex_subplan_png; + if (!bmp_ex_subplan_png || !bmp_ex_subplan_png->IsOk()) + bmp_ex_subplan_png = new wxBitmap(*ex_subplan_png_img); + return bmp_ex_subplan_png; +} +#define ex_subplan_png_bmp ex_subplan_png_bmp() + +static wxIcon *ex_subplan_png_ico() +{ + static wxIcon *ico_ex_subplan_png; + if (!ico_ex_subplan_png || !ico_ex_subplan_png->IsOk()) + { + ico_ex_subplan_png = new wxIcon(); + ico_ex_subplan_png->CopyFromBitmap(*ex_subplan_png_bmp); + } + return ico_ex_subplan_png; +} +#define ex_subplan_png_ico ex_subplan_png_ico() + +#endif // EX_SUBPLAN_PNG_H diff --git a/include/images/ex_tid_scan.png b/include/images/ex_tid_scan.png new file mode 100644 index 0000000000000000000000000000000000000000..0a6063a1af031c626802911fdca598983aff7d52 GIT binary patch literal 1074 zcmV-21kL-2P)hbyT^!nN5^vBrl+3WSI#^#K%-OAhV z)~3be%jEIR)Ek+0f?l*6Q@d;qbxV@5$rvYnjrc!{ox+?t7-# zwb1FX%;=%PEzqh$F9h;kiMjKx|(3PkxRstJB*5mfq{XC zhlh@ij+T~|prD|vtgO7eyv@zc+}zyo@bKZ`;laPVtDlO=oI}p1PuR6w-oa?$%4zD; zYVFo~;L^J5>E!0-=GocV($dn%$jHFJz_hfqs;a7)nVF-bqn?|W>)wU&>3;X;Y4PG! z_2EYK-Z;soXy4!8*4Eb0(9p`t%EiUS?d|R1)xgxbiOHZ?)2mYZ=33Can9k15#>U3O z!^66|x{;BQ>gwv<&a=xVX5tx3}Kg*UYkn%e$bxy}jh*9JvV-~OnfJ;0@};Mzn|G656V%rsV(N#@1DyaC>j%>yg4)_VZtpi^ z4$R~na=AT7>*IZ1AL@sFZhUwc9|;5piB`Y>L|~&3j^krablejP42`#Fv4k9O$mI$; zF%N;*>=WT2Y&Irr9@rh6L@)yJTD0r+VpD$OYqp`G5qH=Twobo1f&7qh2|N*)`RMCt z5>^5=+dBb3rrVuclg!S|FML{Dj6`FxSe&F1G{YvB49;`QE2-7B^m-<<5!u}0xots| zG{P073tp-|<+t)p+>BR|ra8=IsOk()) + { + wxMemoryInputStream img_ex_tid_scan_pngIS(ex_tid_scan_png_data, sizeof(ex_tid_scan_png_data)); + img_ex_tid_scan_png->LoadFile(img_ex_tid_scan_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_tid_scan_png; +} +#define ex_tid_scan_png_img ex_tid_scan_png_img() + +static wxBitmap *ex_tid_scan_png_bmp() +{ + static wxBitmap *bmp_ex_tid_scan_png; + if (!bmp_ex_tid_scan_png || !bmp_ex_tid_scan_png->IsOk()) + bmp_ex_tid_scan_png = new wxBitmap(*ex_tid_scan_png_img); + return bmp_ex_tid_scan_png; +} +#define ex_tid_scan_png_bmp ex_tid_scan_png_bmp() + +static wxIcon *ex_tid_scan_png_ico() +{ + static wxIcon *ico_ex_tid_scan_png; + if (!ico_ex_tid_scan_png || !ico_ex_tid_scan_png->IsOk()) + { + ico_ex_tid_scan_png = new wxIcon(); + ico_ex_tid_scan_png->CopyFromBitmap(*ex_tid_scan_png_bmp); + } + return ico_ex_tid_scan_png; +} +#define ex_tid_scan_png_ico ex_tid_scan_png_ico() + +#endif // EX_TID_SCAN_PNG_H diff --git a/include/images/ex_unique.png b/include/images/ex_unique.png new file mode 100644 index 0000000000000000000000000000000000000000..cb70480be8a4f49369d9a974ce9461284d1a4654 GIT binary patch literal 1238 zcmV;{1S$K8P)b0~uF5vPSFWp6cS9>EWB(wt%)SEA8a5a-%iq-I&LARP5lb z-DPF(<-exPW%BF9vLz+pz?JIUs&=Y7>DZ_2+_~o1l-8qo)LdNR&yAk7hpyUjc&t6d6NpNgVwgoYFIh(3 zy7;emwsT-WPoD8Z&*S?eXP>?A`{nFI5QC)~(-9-qn4TPw8K(^79c_;qX;>yRGhrkM zmgDZ;!yxpe#VVK0K;5Sag0tJFa13pkb~v0)7iDnswA^I|Fc`!t6CSVG?Df&|5A2Mc z!yy3hc-(%<1rabC4w>YwJny3XHeUcC4=@N!Y=Y67XxiA1bfc8ZIN0SO&+|UgKRXvh zUD&C47Dj2YfB}5L&;mV(@PZ&Ly2G|eBm_^E<{w2_CCX`sM~Fq1IsOk()) + { + wxMemoryInputStream img_ex_unique_pngIS(ex_unique_png_data, sizeof(ex_unique_png_data)); + img_ex_unique_png->LoadFile(img_ex_unique_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_unique_png; +} +#define ex_unique_png_img ex_unique_png_img() + +static wxBitmap *ex_unique_png_bmp() +{ + static wxBitmap *bmp_ex_unique_png; + if (!bmp_ex_unique_png || !bmp_ex_unique_png->IsOk()) + bmp_ex_unique_png = new wxBitmap(*ex_unique_png_img); + return bmp_ex_unique_png; +} +#define ex_unique_png_bmp ex_unique_png_bmp() + +static wxIcon *ex_unique_png_ico() +{ + static wxIcon *ico_ex_unique_png; + if (!ico_ex_unique_png || !ico_ex_unique_png->IsOk()) + { + ico_ex_unique_png = new wxIcon(); + ico_ex_unique_png->CopyFromBitmap(*ex_unique_png_bmp); + } + return ico_ex_unique_png; +} +#define ex_unique_png_ico ex_unique_png_ico() + +#endif // EX_UNIQUE_PNG_H diff --git a/include/images/ex_unknown.png b/include/images/ex_unknown.png new file mode 100644 index 0000000000000000000000000000000000000000..d5d54f5c7b253978b96993ea260828a144395095 GIT binary patch literal 1088 zcmV-G1i$->^ozY{g+H$$zaJ}Pq#prd!=Xk~Eea7c~!sL0n z;BT|sS)tRx%FtS*)o#A!TgB^2zUV@{=s>&YKf2~ayXQu|=uW=pS;FaL#_4Uz>V?ql zgTmx#uG*ix&}^sCZn)r0!09iw<{+@-AFtyivE(VUypmuTB6fvyyGgg<`JvnU&H8?(CcKb z+6}7WW5noy&+LiA0^9sp2xV zQNZYfzTthY(P6#i1*qX$pwV}|;(pHSdCBU($ZUZ&P@ z%j|o{>5S9ub++Dj%<5;W*ml6=ipuD1!|15M&|t;sdd}^2y5K>(=xE66YQW}z$LM~@ z=wip~XUObp%Itj4?KV3{{{R300d!JMQvg8b*k%9#010qNS#tmY07w7;07w8v$!k6U z00H_*L_t(Y$L-VoSJF@z2k>#Zm$&&66HySyHefJJgw$z(fRdI186mP%OejOc)GU0- z>Thp&cTUGnWA_LBjqi^;_jC5#=Xowg_45ER0W(yCfW=C5-iGWBdSGy9_=%GlaUqi- z7)9=}agTSxH_7@rUI+w3XtcKw!x1Su^>jKm6Hh#wotx+6KyX3qS=8e5Xfl=jOVUex zCY$SJ(DF(?f1kYIGpjlM+Q3>O|MFk*N?zYUx};D{l{E6&w>hhkH|4iEy=IG*tr8}& ziR$)Hxu#$u2i^f4va_4qyCc)=fD6Lr-g5o!YDdRuOx8EdI)ya=f(84cqtfc00Its*zP`{t zvGm*-tI5)xw)yaY^JDU5HB1@DiXyUq6VF9xpNhu9hUnU)HhsCxm`TK0GodYv9AJ>K zpwO8V$2+zpw@(TFp)QUR#cP=s&KF1o75*B>n>;TB;RT6Mw;+beHz%@@2+C4n@q3xe zxX1(rB0fx-PLf_>Qk9e@SL44kfRHrYjx{x*Q0S;ZNGK6#A=nd5v?4T3cRC&Bgw()6 z&n4?oZ*z4HNy+sL?wE4ZCuHQu?RfR}=da`6SyFNV?OMnlOFxg0KS=w20#>Z+^Z)<= zC3HntbYx+4WjbSWWnpw>05UK!FfB1MEif@uGB7$cGdeUhD=;-WFfcfoB_03(03~!q zSaf7zbY(hiZ)9m^c>ppnF)%GKIV~_TR5CLIsOk()) + { + wxMemoryInputStream img_ex_unknown_pngIS(ex_unknown_png_data, sizeof(ex_unknown_png_data)); + img_ex_unknown_png->LoadFile(img_ex_unknown_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_unknown_png; +} +#define ex_unknown_png_img ex_unknown_png_img() + +static wxBitmap *ex_unknown_png_bmp() +{ + static wxBitmap *bmp_ex_unknown_png; + if (!bmp_ex_unknown_png || !bmp_ex_unknown_png->IsOk()) + bmp_ex_unknown_png = new wxBitmap(*ex_unknown_png_img); + return bmp_ex_unknown_png; +} +#define ex_unknown_png_bmp ex_unknown_png_bmp() + +static wxIcon *ex_unknown_png_ico() +{ + static wxIcon *ico_ex_unknown_png; + if (!ico_ex_unknown_png || !ico_ex_unknown_png->IsOk()) + { + ico_ex_unknown_png = new wxIcon(); + ico_ex_unknown_png->CopyFromBitmap(*ex_unknown_png_bmp); + } + return ico_ex_unknown_png; +} +#define ex_unknown_png_ico ex_unknown_png_ico() + +#endif // EX_UNKNOWN_PNG_H diff --git a/include/images/ex_update.png b/include/images/ex_update.png new file mode 100644 index 0000000000000000000000000000000000000000..a45c53f83a0593704855bb8488871e8e8c9be701 GIT binary patch literal 1090 zcmV-I1ikx-P)iw+&W5()h$LMIt z>~72Kb_Lq;K_;M%!-%U@#D*$;?9iY%%0@Up5oArDj2~+?VOv zsp{Fb>D#L7+PCQ5nd;rD?A*BN;F{~+tnA&o>));H-n#7It?J{P?cclX;jZoAyXxef z?BcKO;k@kQu)m}Ik z`zl|u_nwKx@;3iqJ}~+$R5OHe*le~9W_M+Eb)VV);&7ZYr@MQ57tF=s@$q-Y6tOKY zFWZZl6PH7^x9N(m>1S^C~n`i3##!Jnm*; zhV*LqVXP05gphXrI;BEA5sz0XlFizcG0d`H|I-vdaf)Ui`bxFjrCB!Z-`K&F`2_lG zW8HeL^u3$4uQLXA^nuZXrj20OZmUD+*A=A;U0IeplNZl1u(P(dwqr=q)KgrQK@JCl z;>^E+p@=3)q}Ws)l=#)94014dCK_tO3=TIzaIq>bwt5*3%TPQ!V{>4cXY2w@vpi4H z5p%f~7?%#4`cmO#jZGLtp*Uy@&3d0|w^~NK=oCe<1FcLZ-GKRfgiQARl7;%8Pr;%T znUf=*08efhUT$a{bA%j*5fQuxo)|>jZr1{YRBA-{1CJ*HoZICJnIoNCF4LOJQi(<*B`9&BQ0dhg zYo(KD3qN#m*4FIU=Af z#HdEyIudfZoB=prjNI`tIsOk()) + { + wxMemoryInputStream img_ex_update_pngIS(ex_update_png_data, sizeof(ex_update_png_data)); + img_ex_update_png->LoadFile(img_ex_update_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_update_png; +} +#define ex_update_png_img ex_update_png_img() + +static wxBitmap *ex_update_png_bmp() +{ + static wxBitmap *bmp_ex_update_png; + if (!bmp_ex_update_png || !bmp_ex_update_png->IsOk()) + bmp_ex_update_png = new wxBitmap(*ex_update_png_img); + return bmp_ex_update_png; +} +#define ex_update_png_bmp ex_update_png_bmp() + +static wxIcon *ex_update_png_ico() +{ + static wxIcon *ico_ex_update_png; + if (!ico_ex_update_png || !ico_ex_update_png->IsOk()) + { + ico_ex_update_png = new wxIcon(); + ico_ex_update_png->CopyFromBitmap(*ex_update_png_bmp); + } + return ico_ex_update_png; +} +#define ex_update_png_ico ex_update_png_ico() + +#endif // EX_UPDATE_PNG_H diff --git a/include/images/ex_values_scan.png b/include/images/ex_values_scan.png new file mode 100644 index 0000000000000000000000000000000000000000..15b5ab4079cb8e2c015b4f5f10a3dbf8aa6410d3 GIT binary patch literal 913 zcmV;C18)3@P)SIp)9{Ja@MXyCYRT+x%IuWb@tNB3d(Q2G(e0$& z@u=SNj@0gw*6*+3^985jNWbYDuH#$9>o~XNP`>9?z~@=P=Z4YkYscts$mx~W?|Po8 zrNQK8meIkFHu36*?c-qX<6!dYhx6)(@8e(Z4V@7pT#)R^r+bZweD)8JY^yOdH>GbpD zU-ji*_v?rF>xbLDiPY)z_T^vG==1U1D)QVa^V}-;q+$#9yU-|2Y z`s|0!=JL+v^7-ap`|O6ySDf-ap0ssI20d!JMQvg8b*k%9#010qNS#tmY3ljhU3ljkVnw%H_ z00FH@L_t(Y$L-b0a)Lk*24Ek?nFomRW_gGUK~X^z7hFIQqoPPyTuOQNU}g{;#Yj~u zhm?Jq%hywM|1~5M&-$-bf~P9QA@C)YD!#&4B$dhJ^6-HRlK> z5m{ALg&>p3bzpku)=*JRlO)sW-M}cOX=((S&+i6irfAxdAd5xpz^qoW1LG6e7Dc)D zP+)8u6H)Rf`%_@fM3(#wc;Boj%jm#tw?0u-yn)kXbuBtDXA-pbh^`yxxHJr711}%G z-3~o|;r(g)dX0&(b{s2Az~Sh+#{;pMQ)_F3i9?ViuwB>2PwdUWSk8WbK|JGSEO{p| n8_Tjb@b)wQYk!?*{c(K(wSJimSdJ6(00000NkvXXu0mjfih%ky literal 0 HcmV?d00001 diff --git a/include/images/ex_values_scan.pngc b/include/images/ex_values_scan.pngc new file mode 100644 index 0000000..f2ad485 --- /dev/null +++ b/include/images/ex_values_scan.pngc @@ -0,0 +1,159 @@ +#ifndef EX_VALUES_SCAN_PNG_H +#define EX_VALUES_SCAN_PNG_H + +static const unsigned char ex_values_scan_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x7d, 0x50, 0x4c, 0x54, +0x45, 0x89, 0xb9, 0xdb, 0x36, 0x88, 0xc1, 0x6f, +0xcd, 0xee, 0x41, 0xbd, 0xe9, 0x45, 0xbe, 0xe9, +0x75, 0xce, 0xef, 0x79, 0xd0, 0xef, 0x50, 0xc2, +0xea, 0x56, 0xc3, 0xea, 0x83, 0xd3, 0xf0, 0x89, +0xd5, 0xf0, 0x65, 0xc8, 0xec, 0x6a, 0xc9, 0xec, +0x6f, 0xca, 0xec, 0x94, 0xd8, 0xf1, 0x99, 0xda, +0xf1, 0x7b, 0xce, 0xed, 0x82, 0xd1, 0xed, 0xa4, +0xdd, 0xf1, 0xa8, 0xde, 0xf2, 0x8e, 0xd4, 0xee, +0x92, 0xd6, 0xef, 0xaf, 0xe1, 0xf3, 0x05, 0xa7, +0xe1, 0x48, 0xbf, 0xe9, 0x1b, 0xae, 0xe3, 0x5b, +0xc5, 0xeb, 0x38, 0xb7, 0xe5, 0x50, 0xbe, 0xe7, +0x55, 0xc0, 0xe7, 0x59, 0xc1, 0xe7, 0x86, 0xd1, +0xed, 0x6b, 0xc7, 0xe8, 0x6f, 0xc8, 0xe9, 0x95, +0xd7, 0xef, 0x7a, 0x9e, 0xa9, 0xa5, 0xc1, 0xe4, +0x66, 0x96, 0xd1, 0xc1, 0x8f, 0x36, 0xf1, 0xea, +0x87, 0xed, 0xe3, 0x60, 0xee, 0xe3, 0x60, 0xf2, +0xea, 0x87, 0xf3, 0xea, 0x87, 0xef, 0xe3, 0x5f, +0xef, 0xe4, 0x5f, 0xf3, 0xeb, 0x87, 0xf4, 0xeb, +0x87, 0xf0, 0xe4, 0x5f, 0xf1, 0xe4, 0x5f, 0xf5, +0xeb, 0x87, 0xf2, 0xe4, 0x5f, 0xf6, 0xeb, 0x87, +0xe1, 0xef, 0xf7, 0xe7, 0xda, 0x2b, 0xe8, 0xda, +0x2b, 0xe8, 0xda, 0x2a, 0xea, 0xdb, 0x2a, 0xec, +0xdb, 0x2a, 0xee, 0xdb, 0x2a, 0xef, 0xdb, 0x2a, +0xf3, 0xe5, 0x5f, 0xd7, 0xea, 0xf5, 0xe9, 0xda, +0x2a, 0xeb, 0xdb, 0x2a, 0xed, 0xdb, 0x2a, 0xef, +0xdc, 0x2a, 0xf0, 0xdc, 0x2a, 0xf4, 0xe5, 0x5f, +0xd6, 0xe9, 0xf4, 0xf3, 0xe4, 0x5f, 0xf5, 0xe5, +0x5f, 0xf7, 0xeb, 0x87, 0xf8, 0xeb, 0x87, 0xdb, +0xbd, 0x89, 0xd4, 0xe9, 0xf4, 0xf6, 0xe5, 0x5f, +0xd3, 0xe8, 0xf3, 0xf1, 0xdc, 0x2a, 0xf2, 0xdc, +0x2a, 0xf3, 0xdc, 0x2a, 0xf7, 0xe5, 0x5f, 0xd1, +0xe7, 0xf2, 0xf4, 0xdc, 0x2a, 0xf8, 0xe5, 0x5f, +0xf5, 0xdc, 0x2a, 0xf8, 0xe6, 0x5f, 0xf9, 0xeb, +0x87, 0xfa, 0xec, 0x87, 0xce, 0xe6, 0xf2, 0xce, +0xe5, 0xf2, 0xf9, 0xe6, 0x5f, 0xfb, 0xec, 0x86, +0xcc, 0xe5, 0xf1, 0xf5, 0xdd, 0x2a, 0xf7, 0xdd, +0x2a, 0xf8, 0xdd, 0x29, 0xfa, 0xe6, 0x5f, 0xcb, +0xe4, 0xf1, 0xf6, 0xdd, 0x2a, 0xfb, 0xe6, 0x5f, +0xca, 0xe3, 0xf0, 0xf9, 0xdd, 0x29, 0xc8, 0xe3, +0xf0, 0xf9, 0xec, 0x87, 0xfc, 0xec, 0x86, 0xc7, +0xe3, 0xf0, 0xc6, 0xe2, 0xef, 0xfc, 0xe6, 0x5f, +0xfd, 0xec, 0x86, 0xc5, 0xe1, 0xef, 0xfb, 0xde, +0x29, 0xfc, 0xde, 0x29, 0xfd, 0xe6, 0x5f, 0xf7, +0xdd, 0x29, 0xfa, 0xdd, 0x29, 0xfe, 0xe6, 0x5f, +0xc2, 0xe0, 0xee, 0xfd, 0xde, 0x29, 0xfe, 0xec, +0x86, 0xc0, 0xdf, 0xee, 0xb9, 0xdb, 0xec, 0xfe, +0xde, 0x29, 0xff, 0xe6, 0x5f, 0xd4, 0xe9, 0xf3, +0xbe, 0xde, 0xed, 0xad, 0xd6, 0xe9, 0x34, 0x56, +0x14, 0x02, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, +0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x01, 0xad, +0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xed, 0xd5, +0xc9, 0x72, 0x82, 0x40, 0x10, 0x06, 0x60, 0x1f, +0xc6, 0x99, 0x07, 0x88, 0xf1, 0x66, 0x79, 0x88, +0x0b, 0x41, 0x51, 0x41, 0x14, 0x17, 0x5c, 0x40, +0x11, 0xa3, 0xa2, 0x48, 0x58, 0x5c, 0x4a, 0x79, +0xf6, 0x60, 0x66, 0x10, 0x1c, 0xc5, 0x48, 0x55, +0x2a, 0x87, 0x94, 0x7d, 0x9a, 0xcb, 0xd7, 0x53, +0x74, 0xff, 0x35, 0x24, 0x12, 0xcf, 0xfa, 0xaf, +0x55, 0x82, 0xa7, 0x2a, 0xc5, 0x21, 0xf0, 0x25, +0x95, 0x2a, 0xbe, 0xc2, 0x58, 0x24, 0x95, 0xc9, +0xe4, 0xf2, 0xf0, 0x81, 0x0b, 0x93, 0x00, 0x24, +0x11, 0x29, 0xbe, 0xe5, 0x72, 0xd4, 0x37, 0x81, +0xef, 0x14, 0x45, 0xd1, 0x91, 0x17, 0x82, 0x74, +0x1a, 0x20, 0x92, 0xcf, 0x55, 0xab, 0x98, 0x50, +0xd5, 0x5a, 0x8d, 0x89, 0xbc, 0x10, 0x64, 0xb3, +0x98, 0x04, 0xad, 0x21, 0x55, 0x63, 0x59, 0x0e, +0x1d, 0x69, 0x86, 0xe3, 0x5a, 0x97, 0x17, 0x82, +0x42, 0x01, 0x90, 0x13, 0x83, 0x14, 0xcb, 0xf2, +0x98, 0x70, 0x7c, 0x73, 0x20, 0x44, 0x90, 0xf0, +0x24, 0x68, 0x8e, 0x6b, 0x7c, 0x60, 0xd2, 0x1c, +0x8c, 0x1f, 0x20, 0xe1, 0x0b, 0x85, 0xf1, 0x78, +0x28, 0x12, 0xa4, 0x5c, 0x06, 0xf7, 0x46, 0xdf, +0x16, 0x44, 0xb1, 0x47, 0x90, 0x4a, 0x05, 0xc4, +0xcc, 0x04, 0xa8, 0xd7, 0x41, 0xcc, 0xc0, 0x9c, +0x09, 0xa4, 0x29, 0x86, 0x69, 0xc1, 0x58, 0x84, +0x61, 0x79, 0xbe, 0xf1, 0x48, 0x60, 0x40, 0xa7, +0xe3, 0x13, 0x9e, 0x6f, 0xa2, 0x71, 0xc2, 0x96, +0x20, 0x08, 0xed, 0xe8, 0xc0, 0x74, 0xbb, 0x98, +0x04, 0x1b, 0x08, 0x4d, 0xf6, 0xe6, 0xe7, 0xf7, +0xfb, 0x98, 0x04, 0xad, 0xa1, 0x30, 0x1c, 0x7e, +0xca, 0xe8, 0xd8, 0x96, 0x65, 0x65, 0x46, 0x0c, +0x79, 0x34, 0xba, 0x0e, 0x8c, 0x38, 0x94, 0x24, +0x05, 0x11, 0x59, 0x55, 0x55, 0x85, 0x20, 0x93, +0xc9, 0x75, 0x60, 0x7a, 0xe7, 0xd6, 0x50, 0x51, +0x4d, 0x93, 0x24, 0xd3, 0xe9, 0xdd, 0xc0, 0x28, +0xa6, 0x69, 0x6a, 0x04, 0x99, 0xcf, 0xef, 0x06, +0x66, 0xa6, 0x68, 0xda, 0x92, 0x20, 0x8b, 0x45, +0xec, 0xc0, 0xac, 0x56, 0xb1, 0x03, 0xe3, 0x13, +0xd8, 0x16, 0x45, 0xb9, 0xf7, 0x50, 0x60, 0x6c, +0x1b, 0x13, 0x51, 0xf2, 0x27, 0xfb, 0x53, 0x60, +0xce, 0x44, 0x96, 0xfc, 0x0d, 0x78, 0xdf, 0xac, +0x28, 0xcb, 0xe8, 0xc0, 0x6c, 0xb7, 0x3e, 0x51, +0x55, 0xbc, 0x81, 0xd3, 0x64, 0x75, 0x2d, 0x3a, +0x30, 0x67, 0x12, 0xb4, 0xf6, 0x88, 0xae, 0x1b, +0xe8, 0xb8, 0x34, 0x0c, 0x63, 0x03, 0x2f, 0x1f, +0xbe, 0xdd, 0x0e, 0x3d, 0x7e, 0xe1, 0xfd, 0x69, +0xfa, 0x7a, 0x8d, 0x89, 0xb1, 0x76, 0x1c, 0x2b, +0x4c, 0xc0, 0xe1, 0xe8, 0xba, 0xc7, 0x03, 0xb1, +0x99, 0x53, 0x6b, 0x6b, 0x83, 0x89, 0x43, 0x90, +0x24, 0xb0, 0x5d, 0xd7, 0xc6, 0x4f, 0xec, 0xcd, +0xc0, 0x58, 0xce, 0x7e, 0x7f, 0x41, 0x3c, 0xe3, +0x65, 0x2c, 0x79, 0x27, 0x30, 0x1b, 0xcb, 0xb2, +0x36, 0xf0, 0xf6, 0x33, 0xfe, 0x6b, 0x7f, 0x9d, +0x67, 0xfd, 0x71, 0x7d, 0x01, 0xb5, 0x7e, 0x99, +0x0d, 0x58, 0x8e, 0x13, 0xf3, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_values_scan_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_values_scan_png = new wxImage(); + if (!img_ex_values_scan_png || !img_ex_values_scan_png->IsOk()) + { + wxMemoryInputStream img_ex_values_scan_pngIS(ex_values_scan_png_data, sizeof(ex_values_scan_png_data)); + img_ex_values_scan_png->LoadFile(img_ex_values_scan_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_values_scan_png; +} +#define ex_values_scan_png_img ex_values_scan_png_img() + +static wxBitmap *ex_values_scan_png_bmp() +{ + static wxBitmap *bmp_ex_values_scan_png; + if (!bmp_ex_values_scan_png || !bmp_ex_values_scan_png->IsOk()) + bmp_ex_values_scan_png = new wxBitmap(*ex_values_scan_png_img); + return bmp_ex_values_scan_png; +} +#define ex_values_scan_png_bmp ex_values_scan_png_bmp() + +static wxIcon *ex_values_scan_png_ico() +{ + static wxIcon *ico_ex_values_scan_png; + if (!ico_ex_values_scan_png || !ico_ex_values_scan_png->IsOk()) + { + ico_ex_values_scan_png = new wxIcon(); + ico_ex_values_scan_png->CopyFromBitmap(*ex_values_scan_png_bmp); + } + return ico_ex_values_scan_png; +} +#define ex_values_scan_png_ico ex_values_scan_png_ico() + +#endif // EX_VALUES_SCAN_PNG_H diff --git a/include/images/ex_window_aggregate.png b/include/images/ex_window_aggregate.png new file mode 100644 index 0000000000000000000000000000000000000000..1f858be1cee3f5d8f2b67f55d730e6d3f43e9b42 GIT binary patch literal 2021 zcmY+EX;jl^7RCc83W}o8IHN*Uq-Zs4LRCbI4z#9NL@EWMAP(RVtW_JR7PVGNRRkQh znnZI+bIp?|eIrp6BcfY*ny;TxI33vX-xUB~aHl((Ytrq@|@%U)9qY40=Dq-`~HS zqpad7&!0aZckbN9i(hHy78aJ5xxA5pfPjgqDKTOk1mJRxqJpbv9oIs0OT5uhJRUy| zqFLG5J#Xns)BF$smvI#3Tt!t)O>=A8;_@Hk5IPPSMG!h`oS!rp*#J~MqN*EJ>p%#c zUz|csBOt=DP(zB!VZ{tG7akriMT|lS6+nhT02%1#B$t;G9V#_KR<$_4z%a@*> zo*o_^LKtNMQ0b7OYf>);joY_xhZmOkATp*mJbC)`?KCJwOd=Qs4QN7Qq7DEnh81;u zRe5ElVbMHiHs8K|djc|6@l>5%T|xkrD^+9)WpR0#I;t83A>*Ri#l?jS!YmM~ld;&dew`IXXIT#9}wR=R|q*^a=TK(y`GU9$sD?W=(frT}8=DHl6NZosse3Hr$SX z%c@c|5u1IJ34Z?mO|-Ps_YR=W&rpZ84i0TOIXStxA(@~5KsX)g&OhNpd!CnnCORcW z+ptTsn-H@{BoqqA$3@~p_wQp|?#5;p7Z?AW_fzRd z6X)vcTJSJVAwldPq#qdynv%)1TCMVZ4Bu(jI{rrInmc9gJN^9FBTRP0y`O(P92jW5 zdWV}^aZyo%wYBxt-N3deeA3@Iyu=qxtfg6%5}gSQyaKpp&SN#fHA}z zWN`)ual20B?2d4vbeEO3mh3E{v4@X^?*A>Yqp0D--`mUD+XJd!VJk{kcaYmg!iHH=^}w+KFHNzOxU{-i*b4 zQJzK#YPzyBj9Od!!iUsTBO)o9n>qQu=VBc?$VB%wSnDQ6_6F|Kr#}!LZmdq4t)E%&_+|eF9xu&T{ah!wYmx|EY6USeI6-05#ol0W_ir*KtD-b7p)wrHhWR0i!VCdEqOvz%$l$;MN* z5eUttCkw3kMGr$*ryr3Ic*MINA}tIwmt+Qew~kAs4bCMY_AS^oAT8ma&qnUNG|Nix zo7NktDI)t5l!%Ck=q5fTj-)#^aov;Z`21{&crnV@GWzx9uVT_~{o%Pgo|qLGs;azB z-QsiypCld3Uoz>1Rz>Sy#HMQ(_2L$vHNx2-P#S|-oAhwY7N;Or{AVe|Ji8S*mur_} zUta?Ya`t|UD@_VJOzu2u``MSCL#w<#7pC4ecH-8%e*OFRv8MJKom&mz7?pk_CeT(> zU;jspZkUS;IvhB0*VZfc*2kR$8$qMV&GF`9=Bb`kYQ;InbPcIIsOk()) + { + wxMemoryInputStream img_ex_window_aggregate_pngIS(ex_window_aggregate_png_data, sizeof(ex_window_aggregate_png_data)); + img_ex_window_aggregate_png->LoadFile(img_ex_window_aggregate_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_window_aggregate_png; +} +#define ex_window_aggregate_png_img ex_window_aggregate_png_img() + +static wxBitmap *ex_window_aggregate_png_bmp() +{ + static wxBitmap *bmp_ex_window_aggregate_png; + if (!bmp_ex_window_aggregate_png || !bmp_ex_window_aggregate_png->IsOk()) + bmp_ex_window_aggregate_png = new wxBitmap(*ex_window_aggregate_png_img); + return bmp_ex_window_aggregate_png; +} +#define ex_window_aggregate_png_bmp ex_window_aggregate_png_bmp() + +static wxIcon *ex_window_aggregate_png_ico() +{ + static wxIcon *ico_ex_window_aggregate_png; + if (!ico_ex_window_aggregate_png || !ico_ex_window_aggregate_png->IsOk()) + { + ico_ex_window_aggregate_png = new wxIcon(); + ico_ex_window_aggregate_png->CopyFromBitmap(*ex_window_aggregate_png_bmp); + } + return ico_ex_window_aggregate_png; +} +#define ex_window_aggregate_png_ico ex_window_aggregate_png_ico() + +#endif // EX_WINDOW_AGGREGATE_PNG_H diff --git a/include/images/ex_worktable_scan.png b/include/images/ex_worktable_scan.png new file mode 100644 index 0000000000000000000000000000000000000000..b51e0b3f4c61ba166b69bd7f32cb23dc8428429e GIT binary patch literal 1965 zcmV;e2U7TnP)VwnpiPi9C$n0v#>~6~Jl-Ti^+VOnO z?SRnjgVF7z-SMd2@{ZK*k=5>#*6*+3^8}~i2&m#nzv)fE=@+fz9k1hC#p`0n>oc|G zIJf0JxaD!n?0C-XP`>9?z~@=P=Z4YkYscts$mx~W?|qB4rNQK8meJ5eW%S9}@VCtG zw#)O!*Y2~(?y|@6#MJDt#q6)d?5@M`!O`!)(CVwe>8ii(zRuzA_v@d#>YcjkoVn?n zxbL*d=$WhI z*6H-`w94q2w(YUT=9RJKl(654q~D06=B2rdKT%UnPewyTlyrWDZFV|3I(I%y#G^OZnUe0+SQev3swK~YFc z(&zKMLtn3jlUz(tb6sRlLr2b%q)|yse`0FT=JL+w^5c=DVm(EGKTgi&@@ZOMwU(gB zm8FAjb)$QS&y=Rj|f@jBa3umU@DWa(Tz&@QGq<#^UczJ3z(Z@5Pa!#dVCr;O=lzTe*jp ziD`1#eV1`sU}jTT?7GS1p|$F^#p0f^;+?SJoUiD#!|1ZX-dk)+#@qS}w5Brg=d!@wmZ{#A zsN9mI+K-{yj-a{Q?BSfS)_9WDcaYU~kJECD(r}5;ZHCWmgwJb(&1iwmXMfp@p492{ zzTWMv*6G-LmDhTd)O3!~Z-~xng3M-q&S`?qX@S~~q2j5weBkSj00001bW%=J06^y0 zW&i*H0b)x>M0ugy)X)F`010qNS#tmY07w7;07w8v$!k6U00Y-aL_t(Y$L*APR8>_J z#_6U_Hcx6c*gRSBHar=`ATcUJ(Ht;saO%7iG$Fe8?l;``uHGjvHK9N)P1H=2tk6nR zgOUm|qrd?tL?l2>Amk|uYT-F2DDLgiTCU}4^@sb9ec!w5{MNU>{oQr^{La^ZT^9(f zI_$m>;lfUxJ6|MRe95JkbrCMV;>xS87OuJWy6bNcZtU8v`%QvRq*IR`H{T-MdRxz) zw+naNdDq?d2>0H1{{s&SU3>L<=waa;sXW4G?y&35`kPGt^Z@~Zfq?-KU^bh3L+_xV z;1CE2?Gx4)9u1F(cnoxisb4=6LjofsBh6s$|9I3B5cK3z(V@`i>6n-S5I!(Ac8~!X zJh(mbOw^Dd2#$^(8VX@C!-j`LL~LA~5g9R}4e4)&XQPIU42DrdpL;$G1`HcMFaid} zz3}2_pU9Z8)RH$@zx+n_RiIzv)q^r$GgC94zV*Jnr) zN5q*nR8byp@G@%_L*B5XQ&iD|vWA}7sSb$^CMsz*+TVQ3Cj#jda7ii~uT4cmnIbmS zG7QL^IUI?%O42x064O0@d6_AS+zYx=^vK+~44FsGsBb&bYO%C!Onb+JDn%4@r0S9R z^SMgMM6%#r3rSkIFq7r7D3fF^&L9gCNk#^lWKdbMgfE#TM=b9xCGXE(mPUUrPyT?c z$oi1KH+osQk|L6uC5PHa8mh}_en_XJGkyGtlf725^~kDKf2t^GBbIcLX2T-4qN^2g z{!?Z3YVPGzicDDMV#zUtemJy$_BlgltT7;K*Yb^JQzY>V4egRTl@G@Dn>~gNCMC?% zBkR`vt+HNZC)|9q){a#+Y~aY36iIW@12W3=u!kcgm3vwGFNmVqbKIKD2eY&8@VT+v zT#k%hLB9Grdt**s&c>8)Xcpflv!2RxF{-p8-{t4$7eK-Hn|{~~KNc4L^fMF{Z`ryH zwwLVKxyyj;-pw}#tUBzz5ZF^%y0-u}m+dRx5Bn>ADK3Jd%F2@Mu&b)7TBkxUz5@r? zwstF2*8Nt$6RM6JY4Em3Oh=D3HXb`_@`Jru$4`_&`QfIf z3Mj5^Zmxuq`udYqP~FgQ%Bxq&ZEVbCDw~dIsOk()) + { + wxMemoryInputStream img_ex_worktable_scan_pngIS(ex_worktable_scan_png_data, sizeof(ex_worktable_scan_png_data)); + img_ex_worktable_scan_png->LoadFile(img_ex_worktable_scan_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_worktable_scan_png; +} +#define ex_worktable_scan_png_img ex_worktable_scan_png_img() + +static wxBitmap *ex_worktable_scan_png_bmp() +{ + static wxBitmap *bmp_ex_worktable_scan_png; + if (!bmp_ex_worktable_scan_png || !bmp_ex_worktable_scan_png->IsOk()) + bmp_ex_worktable_scan_png = new wxBitmap(*ex_worktable_scan_png_img); + return bmp_ex_worktable_scan_png; +} +#define ex_worktable_scan_png_bmp ex_worktable_scan_png_bmp() + +static wxIcon *ex_worktable_scan_png_ico() +{ + static wxIcon *ico_ex_worktable_scan_png; + if (!ico_ex_worktable_scan_png || !ico_ex_worktable_scan_png->IsOk()) + { + ico_ex_worktable_scan_png = new wxIcon(); + ico_ex_worktable_scan_png->CopyFromBitmap(*ex_worktable_scan_png_bmp); + } + return ico_ex_worktable_scan_png; +} +#define ex_worktable_scan_png_ico ex_worktable_scan_png_ico() + +#endif // EX_WORKTABLE_SCAN_PNG_H diff --git a/include/images/exclude.png b/include/images/exclude.png new file mode 100644 index 0000000000000000000000000000000000000000..bd62eef6410d9315857d2e6d246770e8b65b8f47 GIT binary patch literal 725 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47y|-)LR^8|wi}= z_isLZP1<@%wQ`Qjk=K%*nNgG09JqAnY+~Zm($d$dsZT2^E~KQ~e)?Lsd6{J1L`ko# z8QYH^XzhAZSorVPuP+-md|tBT-`~HFYif>6nkJPuNuqp?YIOD56Ib^8`rV6+d^K<0 zzkmPUtXQ!pGFqZ!hGg3swe*g4XK!wIaz5qe_HfFSrwbQu^AC`0S|K@Qk7Uk-*~hPM zEhsq<82I=1?;BI6UhV1m_vg>S@bIm*jgk|0NG?2Of9R!T^@7Cpr%znEwc5~Vm%sly zUEQ5NKC5l*c3rqFx8Q{2nrn7@9?A45&&c`3`Z{FOOoV;9Hdxfs~=ES4#-&V>Eak7aXC5R07H*Y2Gbdx45l?XZ+LiQ zWMmY~)Ws(}c=qt=V{riyAu&Nw;pq&V9$ucOPnhyv$&ZhB;@K9Qt1bmBw`i*--4qPDWM%7n?>IsOk()) + { + wxMemoryInputStream img_exclude_pngIS(exclude_png_data, sizeof(exclude_png_data)); + img_exclude_png->LoadFile(img_exclude_pngIS, wxBITMAP_TYPE_PNG); + } + return img_exclude_png; +} +#define exclude_png_img exclude_png_img() + +static wxBitmap *exclude_png_bmp() +{ + static wxBitmap *bmp_exclude_png; + if (!bmp_exclude_png || !bmp_exclude_png->IsOk()) + bmp_exclude_png = new wxBitmap(*exclude_png_img); + return bmp_exclude_png; +} +#define exclude_png_bmp exclude_png_bmp() + +static wxIcon *exclude_png_ico() +{ + static wxIcon *ico_exclude_png; + if (!ico_exclude_png || !ico_exclude_png->IsOk()) + { + ico_exclude_png = new wxIcon(); + ico_exclude_png->CopyFromBitmap(*exclude_png_bmp); + } + return ico_exclude_png; +} +#define exclude_png_ico exclude_png_ico() + +#endif // EXCLUDE_PNG_H diff --git a/include/images/extension-sm.png b/include/images/extension-sm.png new file mode 100644 index 0000000000000000000000000000000000000000..432d2f44231c1f88e787091060efc5125d80ef64 GIT binary patch literal 423 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}QGic~E0BJDv+cp5$Qv6qzrVk7 zW3&9@vzBik`G5Ho|K-)uTicc2-1GkNGyU0x%oo?3fBedPak1gnHlr`^;(z|izO~Kb z%lm|1zjI$+bN~H2|Mm{mcMpR9{3*J*S>f3^`;Si}e|^pQ`={jETDdE$#Qyy)dv><$ z|KAGswyocQwlbCk`2{mLJiCzwvL>2>S4={E+nQaGTe!Vz zahdU=*X&ESFOpJE*&;e)`qd3*DpaT5u9JDLS%3P((k)@IsOk()) + { + wxMemoryInputStream img_extension_sm_pngIS(extension_sm_png_data, sizeof(extension_sm_png_data)); + img_extension_sm_png->LoadFile(img_extension_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_extension_sm_png; +} +#define extension_sm_png_img extension_sm_png_img() + +static wxBitmap *extension_sm_png_bmp() +{ + static wxBitmap *bmp_extension_sm_png; + if (!bmp_extension_sm_png || !bmp_extension_sm_png->IsOk()) + bmp_extension_sm_png = new wxBitmap(*extension_sm_png_img); + return bmp_extension_sm_png; +} +#define extension_sm_png_bmp extension_sm_png_bmp() + +static wxIcon *extension_sm_png_ico() +{ + static wxIcon *ico_extension_sm_png; + if (!ico_extension_sm_png || !ico_extension_sm_png->IsOk()) + { + ico_extension_sm_png = new wxIcon(); + ico_extension_sm_png->CopyFromBitmap(*extension_sm_png_bmp); + } + return ico_extension_sm_png; +} +#define extension_sm_png_ico extension_sm_png_ico() + +#endif // EXTENSION_SM_PNG_H diff --git a/include/images/extension.png b/include/images/extension.png new file mode 100644 index 0000000000000000000000000000000000000000..e3c533347883fc1dec73bcb21b32fc54e3c31732 GIT binary patch literal 996 zcmVPx%`cO<%MQ2zLf_6I6&9|zdd99>-@a*2m!Junh7N)|bRf|-bx|zVboSKha_w(lG z;mc-L4XVVcQjb)R!IoN>UTm6cdTlP+)48aeY_F(+!qvh)fIq$I$ak@QM1Demb2p-y zZNIpg%*U?Z+|0eUmR?Q)@#@yLtA3u9XFhv8mdv0tb~C!Ok)4xckc3Wsa4?*aUD?pH z@afX-<;s|gP-A^X%E{;lk+My5`xk#6?p?1NAale3n)0NuDkgb|nMQ$vEwur;)&X(P%klLe(*qwsbn0(Ze z&%lqBg+*3S1ZY?dnutTImr{GNfpyZ2etkM9XCNqTCtr9wihVOAV;iN_u6D(TK#xcf zTn`v!7(bOtw4`b=XCQ>Lht=`it<|(#mtSF?Wm1BZ;G0*SUx8%WGt7&4B zV3D+tb8RIwgF3Luu#bN^7G4v==*yVRp-_@kjmeoSdoaG!zSzWv!K`UHUKC!MVuZSj zaIAJVdpAyF9vxyClh&g+jY8GGe$u;klYuouT@*iVD?w)>Y;7EsekVC?DRR1gZ_tQZ zyKv99ZOyY~z@}84hBK{_JHn(!l6fLVbTnhFZfMSfV$6Lul0qhGC2*Z?NP$a6}(W;2>aI;l}Wz+t|fIeljlScFSfreaXWZ%f2# zMZ#t~zg?k^OOAUphI1*4cr3V}Qns8&igY1@Y#D@Y7H?b$T8UCtsbn_2S%i2!rk!)h z!>EaMCcvamyR?(W!KK8$qF<3+9BCaAUJ)8<9X6LmEss1DV->ZTL3e2=8EP9)hfaum zLy>wXERsEdsDEo(3zmE$ex`jsyImG&7=LOOfol~TcO*%INEmJ%7i}B|YRn1%0004W zQchC0W=QhVA)yH_FkL{}1;huk zpaKCQKz@=7s`{i97i0@vl2TS8w1C7?R&G7y;)1Nm<IsOk()) + { + wxMemoryInputStream img_extension_pngIS(extension_png_data, sizeof(extension_png_data)); + img_extension_png->LoadFile(img_extension_pngIS, wxBITMAP_TYPE_PNG); + } + return img_extension_png; +} +#define extension_png_img extension_png_img() + +static wxBitmap *extension_png_bmp() +{ + static wxBitmap *bmp_extension_png; + if (!bmp_extension_png || !bmp_extension_png->IsOk()) + bmp_extension_png = new wxBitmap(*extension_png_img); + return bmp_extension_png; +} +#define extension_png_bmp extension_png_bmp() + +static wxIcon *extension_png_ico() +{ + static wxIcon *ico_extension_png; + if (!ico_extension_png || !ico_extension_png->IsOk()) + { + ico_extension_png = new wxIcon(); + ico_extension_png->CopyFromBitmap(*extension_png_bmp); + } + return ico_extension_png; +} +#define extension_png_ico extension_png_ico() + +#endif // EXTENSION_PNG_H diff --git a/include/images/extensions.png b/include/images/extensions.png new file mode 100644 index 0000000000000000000000000000000000000000..eed7ca97a33ef595f448b8621168d531f86d51d5 GIT binary patch literal 1017 zcmVPx%_fSk!MS^xZ(#^N3p?R&Od+_Yu$ibj%T^6RorB#bmn!1_5x}2JiUH9|m=i$p{ zRt>7esZx(rkHMB&m|kp}YkF-i+S9qHoNTYCfx^|oK7c>H>Bx7neMEjjfO9vZnQgzg znaszo-`vc-ww7K_0rBeAwyS=gm1jPCJeJI$Gj=n&vyq*XV~~VSeQ+?GkzLu)v+(KC z?&Zpui%@D?5_o7K5L*te*2!a-MZ%4vg6gM;L)L= zk53w479M3BDQ+lfsBo&|xoE3!8)F$jd_LXGn5dUmHEJcE$)m~b(xK3*v*EqB=fkk& zzN6u@o!_pI*P(X7g>k=tf76xP$dIj?SVe9ugSLpn>&}+lsF2#DiP)Wj)|h*Toyk;|+MLMZbK)_+XojHAH5m&nL&4HC>d%SP=`*4d_$3X zCoGaZfT(|KS__tZB7UZQKD%8OXc&KL7J+LO8+Rm0f=C!{9T#mJ7UDFE00001bW%=J z06^y0W&i*H0b)x>L;#2d9Y_EG010qNS#tmY3ljhU3ljkVnw%H_000McNliru+XEXB z6Cp(Rbcp}}0B%V{K~xyiU68R2z#t3+nS(tt!3~hY^vGg42FL=`EENNm0{M!6-y1;) zQxFazvL_cK*b<_okFg0d8Hc#V=Eh`)h+yZmplehnlNZEdtgQ@hX0CNeIWEpxw!oyN ndc~tsp9TlidOzOC&-)*|KH)3pD2ngr00000NkvXXu0mjfIsOk()) + { + wxMemoryInputStream img_extensions_pngIS(extensions_png_data, sizeof(extensions_png_data)); + img_extensions_png->LoadFile(img_extensions_pngIS, wxBITMAP_TYPE_PNG); + } + return img_extensions_png; +} +#define extensions_png_img extensions_png_img() + +static wxBitmap *extensions_png_bmp() +{ + static wxBitmap *bmp_extensions_png; + if (!bmp_extensions_png || !bmp_extensions_png->IsOk()) + bmp_extensions_png = new wxBitmap(*extensions_png_img); + return bmp_extensions_png; +} +#define extensions_png_bmp extensions_png_bmp() + +static wxIcon *extensions_png_ico() +{ + static wxIcon *ico_extensions_png; + if (!ico_extensions_png || !ico_extensions_png->IsOk()) + { + ico_extensions_png = new wxIcon(); + ico_extensions_png->CopyFromBitmap(*extensions_png_bmp); + } + return ico_extensions_png; +} +#define extensions_png_ico extensions_png_ico() + +#endif // EXTENSIONS_PNG_H diff --git a/include/images/exttable-sm.png b/include/images/exttable-sm.png new file mode 100644 index 0000000000000000000000000000000000000000..acd43cb8abab6ef38daf34ff6d7544153a11dacf GIT binary patch literal 612 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47`X#{LR^7d#i`G`&i$Km{^#1O zpHAI*b?@=>XV0HMd-m+;jb~*$Ul`1J(Q)=)^XY$8$A0G@_?f)(TiB-0o~u9DE`4h_ z@3s2Om(8dDdI7mh-fGNz8JxJ$(RuCl>$mUSyLbQo{YQ@;J%0Rn>9T9)mKA9e*Bv-; z!q9k*y7s}c^63vAJOIkOd8|>@*q@f(clYkyWy_XDM0Trbo^~Gc%JJ_00swRNswPKgTu2MX+REVfk$L9koEv$x0Bg+K*j`57sn8Z%gG4} zOa@Af9Sp+8+}hIC?Ck2|<}MBG)BEEc0z4vIL{>Gq^Qb83DJpS_PM9=p;?&9E0U<$c zTq{IsOk()) + { + wxMemoryInputStream img_exttable_sm_pngIS(exttable_sm_png_data, sizeof(exttable_sm_png_data)); + img_exttable_sm_png->LoadFile(img_exttable_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_exttable_sm_png; +} +#define exttable_sm_png_img exttable_sm_png_img() + +static wxBitmap *exttable_sm_png_bmp() +{ + static wxBitmap *bmp_exttable_sm_png; + if (!bmp_exttable_sm_png || !bmp_exttable_sm_png->IsOk()) + bmp_exttable_sm_png = new wxBitmap(*exttable_sm_png_img); + return bmp_exttable_sm_png; +} +#define exttable_sm_png_bmp exttable_sm_png_bmp() + +static wxIcon *exttable_sm_png_ico() +{ + static wxIcon *ico_exttable_sm_png; + if (!ico_exttable_sm_png || !ico_exttable_sm_png->IsOk()) + { + ico_exttable_sm_png = new wxIcon(); + ico_exttable_sm_png->CopyFromBitmap(*exttable_sm_png_bmp); + } + return ico_exttable_sm_png; +} +#define exttable_sm_png_ico exttable_sm_png_ico() + +#endif // EXTTABLE_SM_PNG_H diff --git a/include/images/exttable.png b/include/images/exttable.png new file mode 100644 index 0000000000000000000000000000000000000000..5d84035feea62d53d457481178b1bcbe9622f856 GIT binary patch literal 793 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47;6K3LR^7d#i`GGFZ`c${`aEG zUw7Sjd-49u`;VVLefIp>vuC#+K3#L}dGf{=db3}2pa0)_=3m{3Kc$C%BxZ_*c zrqAAMJ~%9YXTIQ#?wnU@GhViy`J27(hvTw$W((iw&U_Y~)1HyF{qEhn_wL=hfB*i2 z2M-=TeE8_mqsNaQ8yXiV>iW%}zd>1TV^GL$BjYL^{S(WU9oVt+prXnmSNFZkm#=*C zTF^o@>PyZ-vst5*{zPLflcU|_QU>a|B#uU=JF?bJ2cziipY_3PKae*OB& zm8%-sEqaEB)ikG?m>;=w=lPpAZ{EIr`|{<>zP<^HDjPJkuS}Y>_5J(zA3l8e^y$;P zckfoNT)BGn>N#`fDXPqIbUAEeo3EjBs<&_JrcIlkKYzY=?-6CSwcft_U%!6i?2@ga zbAH+K$Dcoc{`&RnzI`WD)Hj5LAKkcd)7Gt9lT#YiwN7;R-um|K+wv9LmDM(Tcy0Rl z@#D5_+u{=nRW-JDc3)AL{8UY|HzVudq)BroPg$ri@$mwIO;dmoz*rLG7tG-B>_!@p z!&%@FSq!8-z}W3%wjGdh+0(@_MB;LCLV^n;4-Zd|&l#OHId5d<%!#>Uvqyo^u8z@B zF;Otku#nSp1DBm9qhscRhMqMtE)H>yfu51Bp}w)6&cZqimabjQ@@VyoS1+4cMR<97 zd#?KUoIRtfbCAhvS=cqRZDrs1`uxr%FfOPQ4>vF8_xIM%-_X$2-@kPI{CbCkfC7#P z2U8Or8zmzxD>XAS4xIy%;`1lWcrs_sq*>GW#5zu&ICF}R^VG?+r}Y`QMZ`qYkF!mE zGG*G-@CFvG)vNY8H+eN(zQmoCbx`Y7z#e{vFBY0Te&TE7f!IsOk()) + { + wxMemoryInputStream img_exttable_pngIS(exttable_png_data, sizeof(exttable_png_data)); + img_exttable_png->LoadFile(img_exttable_pngIS, wxBITMAP_TYPE_PNG); + } + return img_exttable_png; +} +#define exttable_png_img exttable_png_img() + +static wxBitmap *exttable_png_bmp() +{ + static wxBitmap *bmp_exttable_png; + if (!bmp_exttable_png || !bmp_exttable_png->IsOk()) + bmp_exttable_png = new wxBitmap(*exttable_png_img); + return bmp_exttable_png; +} +#define exttable_png_bmp exttable_png_bmp() + +static wxIcon *exttable_png_ico() +{ + static wxIcon *ico_exttable_png; + if (!ico_exttable_png || !ico_exttable_png->IsOk()) + { + ico_exttable_png = new wxIcon(); + ico_exttable_png->CopyFromBitmap(*exttable_png_bmp); + } + return ico_exttable_png; +} +#define exttable_png_ico exttable_png_ico() + +#endif // EXTTABLE_PNG_H diff --git a/include/images/exttables.png b/include/images/exttables.png new file mode 100644 index 0000000000000000000000000000000000000000..c5dfbd454ed33727bd1deeb87c62f8671f6a5a03 GIT binary patch literal 662 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47^MPyLR^7d#i`G`&i$Km{^#1O zpHAI*b?@=>XV0HMd-m+;jb~*$Ul`1J(Q)=)(1uT&ufDx|_ipp)e^tkR=O6f)yz^Vw zrq7vXAHE?^>wU&`SRt%hYy!6TNV*D zT}|t>v;9UL?W?Amt7goYwSN8jSFc`8IQ7}h=Aef5HBHT(=Pz7){rdI(-PetE&Kqf+ zTC?J?x9>_dt@Dk|J3fB=`1bAF+~nQb+SeRSH>_B(;_1_;Rn;?8HFg`BEWUQ_zJ=bg zri$H9o;-Q;=FOu=PwX9+YwPW<2KnxXa>IqjgMEvDp~F}b z)e_f;l9a@fRIB8oR3OD*WMF8ZYiOivU>IU#U}a)#Wn!XjU}|MxU@=ow4n;$5eoAIq iB}9XPC0GMUwUvPxM8m1+p=*E|7(8A5T-G@yGywoZHZsuw literal 0 HcmV?d00001 diff --git a/include/images/exttables.pngc b/include/images/exttables.pngc new file mode 100644 index 0000000..f6bf978 --- /dev/null +++ b/include/images/exttables.pngc @@ -0,0 +1,127 @@ +#ifndef EXTTABLES_PNG_H +#define EXTTABLES_PNG_H + +static const unsigned char exttables_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x1a, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x21, 0x95, 0xe7, 0x8a, +0xce, 0xfe, 0x94, 0xcf, 0xf9, 0xad, 0xd5, 0xf2, +0xca, 0xdc, 0xea, 0xde, 0xe3, 0xe7, 0xe6, 0xe7, +0xe7, 0xe6, 0xe6, 0xe6, 0xc5, 0xd8, 0xe6, 0x76, +0xb9, 0xe8, 0x30, 0x9c, 0xe8, 0x88, 0xcd, 0xfe, +0x52, 0xb0, 0xf2, 0xb3, 0xd5, 0xed, 0xdd, 0xdd, +0xdd, 0x83, 0xcb, 0xfe, 0x7a, 0xc6, 0xfb, 0x6f, +0xc0, 0xf9, 0x63, 0xb9, 0xf6, 0x56, 0xb2, 0xf3, +0x49, 0xab, 0xf0, 0x3d, 0xa5, 0xed, 0x31, 0x9e, +0xeb, 0x27, 0x99, 0xe9, 0xde, 0xde, 0xde, 0x83, +0xcb, 0xfd, 0x4a, 0xab, 0xf0, 0x3d, 0xa4, 0xed, +0x31, 0x98, 0xe9, 0x28, 0x99, 0xe9, 0xdf, 0xdf, +0xdf, 0x46, 0x51, 0xb2, 0x3c, 0x3e, 0x9a, 0xd4, +0xd4, 0xd7, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, +0x61, 0x55, 0xcd, 0x30, 0x2b, 0xd2, 0x7c, 0xb1, +0xd5, 0xe0, 0xe0, 0xe0, 0xc5, 0xc5, 0xd2, 0x36, +0x38, 0xb0, 0x26, 0x29, 0xb7, 0x77, 0x77, 0x92, +0xca, 0xc7, 0xde, 0x36, 0x2d, 0xcc, 0x30, 0x2a, +0xce, 0x8e, 0x88, 0xaf, 0xe9, 0xe9, 0xe9, 0xe1, +0xe1, 0xe1, 0xa6, 0xa6, 0xa6, 0x58, 0x5a, 0x97, +0x26, 0x2a, 0xcb, 0x43, 0x3f, 0xb1, 0x2c, 0x2b, +0xd5, 0x35, 0x29, 0xaa, 0x98, 0x98, 0x9a, 0xaf, +0xaf, 0xaf, 0xea, 0xea, 0xea, 0x90, 0xca, 0xf3, +0x46, 0x3c, 0xc1, 0x28, 0x2b, 0xd6, 0x29, 0x29, +0xb9, 0xcf, 0xd0, 0xd6, 0xeb, 0xeb, 0xeb, 0xbf, +0xbb, 0xd7, 0x33, 0x2c, 0xcf, 0x32, 0x2a, 0xca, +0xac, 0xa8, 0xc3, 0x4b, 0x4d, 0xa9, 0x26, 0x2a, +0xcf, 0x81, 0x83, 0xb8, 0xf1, 0xf1, 0xf1, 0xed, +0xed, 0xed, 0x6d, 0x63, 0xbb, 0x2b, 0x2b, 0xd6, +0x41, 0x35, 0xb0, 0xa8, 0xa8, 0xa8, 0xe5, 0xe5, +0xe5, 0x7a, 0x7b, 0x98, 0x25, 0x28, 0xbb, 0x32, +0x34, 0xa3, 0xd6, 0xd6, 0xdf, 0x38, 0x2e, 0xc6, +0x82, 0x78, 0xbb, 0xe4, 0xe4, 0xe4, 0xec, 0xec, +0xec, 0xe2, 0xe2, 0xe4, 0x3f, 0x41, 0xa7, 0x2b, +0x2e, 0xbb, 0x7b, 0xc6, 0xfb, 0x6f, 0xc0, 0xf8, +0x23, 0x80, 0xd0, 0x81, 0xc1, 0x8e, 0xa2, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0xb3, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x5d, 0xcf, 0x45, 0x16, 0xc2, +0x40, 0x10, 0x45, 0xd1, 0x2e, 0x34, 0x40, 0x80, +0xe0, 0x04, 0x0b, 0xee, 0x16, 0x5c, 0x82, 0x04, +0x77, 0x77, 0xd9, 0xff, 0x36, 0xe8, 0x26, 0x03, +0x0e, 0xa9, 0xe1, 0x3b, 0x77, 0xf0, 0x0b, 0xc1, +0xef, 0xd0, 0xf7, 0x40, 0xa1, 0x54, 0xa9, 0x35, +0x5a, 0x8a, 0xd2, 0xe9, 0x0d, 0x52, 0xa0, 0x8d, +0xff, 0x06, 0x68, 0x99, 0x01, 0x93, 0xcc, 0x80, +0x59, 0x66, 0x70, 0xc0, 0x86, 0xb1, 0x58, 0x6d, +0x76, 0x87, 0xd3, 0xe5, 0x06, 0x04, 0x2c, 0x31, +0x1e, 0x12, 0xbc, 0x3e, 0x7f, 0x00, 0x07, 0x0e, +0x87, 0x60, 0x28, 0xcc, 0x72, 0x91, 0x68, 0x2c, +0x9e, 0xc0, 0x21, 0x89, 0x4d, 0x2a, 0x9d, 0xc9, +0x26, 0x73, 0xf9, 0x42, 0x91, 0xc7, 0xa1, 0x44, +0x4c, 0xb9, 0x52, 0xad, 0xd5, 0x1b, 0xcd, 0x56, +0x1b, 0x90, 0x20, 0x10, 0xc3, 0xb1, 0x9d, 0x6e, +0xaf, 0xcf, 0xb7, 0x45, 0xb2, 0x8d, 0x98, 0xc1, +0x70, 0x34, 0x9e, 0x4c, 0x67, 0xf3, 0x05, 0x09, +0xd8, 0x2c, 0x57, 0xeb, 0xcd, 0x96, 0xdf, 0xed, +0x0f, 0x47, 0xe9, 0x43, 0x38, 0x9d, 0x2f, 0x5b, +0x4a, 0xbc, 0xde, 0xee, 0x0f, 0x29, 0x08, 0x34, +0xf3, 0x7c, 0x91, 0x1d, 0xae, 0x37, 0x7c, 0x00, +0x0a, 0x4a, 0x16, 0xe9, 0x3e, 0x23, 0x57, 0xc9, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, +0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *exttables_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_exttables_png = new wxImage(); + if (!img_exttables_png || !img_exttables_png->IsOk()) + { + wxMemoryInputStream img_exttables_pngIS(exttables_png_data, sizeof(exttables_png_data)); + img_exttables_png->LoadFile(img_exttables_pngIS, wxBITMAP_TYPE_PNG); + } + return img_exttables_png; +} +#define exttables_png_img exttables_png_img() + +static wxBitmap *exttables_png_bmp() +{ + static wxBitmap *bmp_exttables_png; + if (!bmp_exttables_png || !bmp_exttables_png->IsOk()) + bmp_exttables_png = new wxBitmap(*exttables_png_img); + return bmp_exttables_png; +} +#define exttables_png_bmp exttables_png_bmp() + +static wxIcon *exttables_png_ico() +{ + static wxIcon *ico_exttables_png; + if (!ico_exttables_png || !ico_exttables_png->IsOk()) + { + ico_exttables_png = new wxIcon(); + ico_exttables_png->CopyFromBitmap(*exttables_png_bmp); + } + return ico_exttables_png; +} +#define exttables_png_ico exttables_png_ico() + +#endif // EXTTABLES_PNG_H diff --git a/include/images/favourite.png b/include/images/favourite.png new file mode 100644 index 0000000000000000000000000000000000000000..a7fe1d6d472da3aaf7fc460954ae623de1d4b15f GIT binary patch literal 581 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMfp8%f_*Z=?jU)s}ma%Irfy{&gP zNqzhL`o+ByFE3PmJH~bA%$m>dp1gg2{l?LG{~qW4KhJe}XYt!-*N-i5es;d@{<)r; zN1E@PnEC&j&i`u)4^E_AKh$#XNXfGk>1S4X-#xS9@^ZO9FXH}x$o+rE=>Ivk{|_Dh z|7idJt>OP|y&EgIFYoC%w;|=(E{Xq_MgCtF`~N!r|G%m4Z-kv#?)~A_oim#%{$Dr! zf7j&yx4Qp7JI}2$`}Ond+vnHr9V-2Qf$!Tb&yO#b{r^z({)ptg^Xo3`?D%&l;@uIM zGaIrm?d^YdX~O@@3g^~^o!gN9WDDQreOYh7ML)4u<<_$}WhcbG3VQg}7c6DrFjEox^7EIXCv0}!KmL*fR@I*L-`NcT~dPcg2`o=OZ zY7Y(ej&=|Czkfg=uV>=M&XqHFvd+oROwCQsPJhoJUQkk0R#;m6y@9);s?ylt$B$nJ z?>>`fP-1Rw>ine2P<)5?@ZGkPkAQAbEpd$~Nl7e8wMs5Z1yT$~28IT@hDN#uh9O1< zRwl+)CMMbjrd9?97Bf}lP&DM`r(~v8LNpjyf;E6tTN#)^G@P0qx(29$!PC{xWt~$( F69Aww8a@C3 literal 0 HcmV?d00001 diff --git a/include/images/favourite.pngc b/include/images/favourite.pngc new file mode 100644 index 0000000..5f2b0f3 --- /dev/null +++ b/include/images/favourite.pngc @@ -0,0 +1,117 @@ +#ifndef FAVOURITE_PNG_H +#define FAVOURITE_PNG_H + +static const unsigned char favourite_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xfc, 0x50, 0x4c, 0x54, +0x45, 0xff, 0xff, 0xff, 0xd2, 0xbc, 0x8e, 0xc9, +0xa9, 0x52, 0xd5, 0xbd, 0x85, 0xdc, 0xb2, 0x1a, +0xf6, 0xf3, 0xeb, 0xe8, 0xde, 0xc8, 0xe9, 0xd0, +0x7a, 0xf6, 0xc6, 0x0a, 0xdc, 0xcc, 0xac, 0xf3, +0xee, 0xe4, 0xed, 0xe7, 0xd7, 0xd8, 0xc5, 0x9e, +0xfe, 0xe3, 0x6e, 0xff, 0xcf, 0x0a, 0xd3, 0xb9, +0x73, 0xed, 0xe6, 0xd7, 0xc6, 0xa0, 0x43, 0xe6, +0xcf, 0x7e, 0xdf, 0xce, 0x8c, 0xd9, 0xc4, 0x83, +0xdc, 0xc8, 0x99, 0xff, 0xd6, 0x2c, 0xff, 0xd6, +0x20, 0xe0, 0xc8, 0x66, 0xd7, 0xc2, 0x84, 0xde, +0xc4, 0x74, 0xe6, 0xc8, 0x67, 0xcc, 0xaa, 0x4b, +0xdd, 0xcc, 0xa8, 0xd3, 0xa7, 0x1e, 0xfc, 0xe8, +0x5e, 0xff, 0xf0, 0x6d, 0xff, 0xdc, 0x32, 0xff, +0xce, 0x06, 0xff, 0xe1, 0x40, 0xff, 0xf8, 0x87, +0xff, 0xf6, 0x80, 0xff, 0xdb, 0x2e, 0xd8, 0xa8, +0x0b, 0xd3, 0xbc, 0x88, 0xce, 0xb0, 0x64, 0xe6, +0xba, 0x18, 0xff, 0xd3, 0x14, 0xff, 0xd3, 0x16, +0xff, 0xeb, 0x5f, 0xff, 0xfe, 0x95, 0xef, 0xd8, +0x56, 0xc8, 0xa7, 0x4b, 0xf0, 0xea, 0xdc, 0xcc, +0xb2, 0x78, 0xff, 0xd7, 0x35, 0xff, 0xdd, 0x34, +0xff, 0xf6, 0x7e, 0xff, 0xf9, 0x89, 0xce, 0xaa, +0x36, 0xfa, 0xf9, 0xf5, 0xed, 0xe7, 0xd6, 0xde, +0xc2, 0x75, 0xff, 0xd0, 0x0e, 0xf6, 0xda, 0x49, +0xf1, 0xe8, 0xa6, 0xff, 0xf0, 0x72, 0xef, 0xc4, +0x19, 0xde, 0xcf, 0xae, 0xd0, 0xb9, 0x88, 0xfe, +0xdc, 0x58, 0xee, 0xc4, 0x1c, 0xcc, 0xb0, 0x6b, +0xd2, 0xbd, 0x8f, 0xe6, 0xd2, 0x90, 0xff, 0xd3, +0x20, 0xce, 0xae, 0x56, 0xce, 0xb0, 0x67, 0xe4, +0xb4, 0x0e, 0xd3, 0xbe, 0x8a, 0xda, 0xca, 0xa5, +0xdc, 0xc4, 0x85, 0xda, 0xbd, 0x54, 0xd4, 0xbe, +0x88, 0xe1, 0xd3, 0xb2, 0xe6, 0xdc, 0xc4, 0xcc, +0xb6, 0x80, 0xfa, 0xf9, 0xf6, 0x80, 0x47, 0x32, +0x54, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, +0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x80, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0x20, +0x16, 0x30, 0x32, 0xa1, 0x09, 0x30, 0xb3, 0xb0, +0xa2, 0xf0, 0xd9, 0xd8, 0x39, 0x38, 0xe1, 0x1c, +0x2e, 0x6e, 0x56, 0x06, 0x1e, 0x5e, 0x3e, 0x7e, +0x06, 0x56, 0x01, 0x01, 0xb0, 0x80, 0xa0, 0x90, +0xb0, 0x88, 0xa8, 0x98, 0xb8, 0x84, 0xa4, 0x94, +0xb4, 0x0c, 0x58, 0x40, 0x56, 0x4e, 0x5e, 0x41, +0x51, 0x49, 0x59, 0x45, 0x55, 0x4d, 0x5d, 0x03, +0xa2, 0x87, 0x55, 0x53, 0x4b, 0x5b, 0x47, 0x57, +0x4f, 0xdf, 0xc0, 0x10, 0x6e, 0x8c, 0x91, 0xb1, +0x89, 0xa9, 0x99, 0xb9, 0x05, 0x9c, 0x6f, 0x69, +0x65, 0x6d, 0x63, 0x6b, 0x67, 0xef, 0x00, 0x17, +0x70, 0x74, 0x72, 0x76, 0x71, 0x75, 0x73, 0xf7, +0x80, 0x0b, 0x78, 0x7a, 0x79, 0x33, 0x30, 0xf8, +0xf8, 0xfa, 0xc1, 0xdd, 0xe6, 0x1f, 0x00, 0x22, +0x03, 0x83, 0x82, 0x89, 0xf2, 0x25, 0x00, 0x73, +0xdc, 0x0d, 0xc3, 0xdd, 0x86, 0xc9, 0xe2, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *favourite_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_favourite_png = new wxImage(); + if (!img_favourite_png || !img_favourite_png->IsOk()) + { + wxMemoryInputStream img_favourite_pngIS(favourite_png_data, sizeof(favourite_png_data)); + img_favourite_png->LoadFile(img_favourite_pngIS, wxBITMAP_TYPE_PNG); + } + return img_favourite_png; +} +#define favourite_png_img favourite_png_img() + +static wxBitmap *favourite_png_bmp() +{ + static wxBitmap *bmp_favourite_png; + if (!bmp_favourite_png || !bmp_favourite_png->IsOk()) + bmp_favourite_png = new wxBitmap(*favourite_png_img); + return bmp_favourite_png; +} +#define favourite_png_bmp favourite_png_bmp() + +static wxIcon *favourite_png_ico() +{ + static wxIcon *ico_favourite_png; + if (!ico_favourite_png || !ico_favourite_png->IsOk()) + { + ico_favourite_png = new wxIcon(); + ico_favourite_png->CopyFromBitmap(*favourite_png_bmp); + } + return ico_favourite_png; +} +#define favourite_png_ico favourite_png_ico() + +#endif // FAVOURITE_PNG_H diff --git a/include/images/file_new.png b/include/images/file_new.png new file mode 100644 index 0000000000000000000000000000000000000000..f6affd3f7c196007d568a0bc38b22f0dc2508945 GIT binary patch literal 226 zcmeAS@N?(olHy`uVBq!ia0vp^0wBx?BpA#)4xIr~OeH~n!3+##lh0a!cuC&wE)0x! zyM&hjd7K3vk;OpT1B~5HX4?T7VxBIJAsp9}6B-!*G4uQpKk$VA4F?ayQ)jMiaq|mz z168P&xJHzuB$lLFB^RXvDF!10LjzqyBV7Z-5F-OC6JskAQ*8rND+7ah@AOuoXvob^ l$xN$+XfUt@YXGV?u`)1&XgD=JbPZ4ggQu&X%Q~loCIF+nIr#tp literal 0 HcmV?d00001 diff --git a/include/images/file_new.pngc b/include/images/file_new.pngc new file mode 100644 index 0000000..90c41e4 --- /dev/null +++ b/include/images/file_new.pngc @@ -0,0 +1,73 @@ +#ifndef FILE_NEW_PNG_H +#define FILE_NEW_PNG_H + +static const unsigned char file_new_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x01, 0x00, 0x00, 0x00, 0x00, 0x37, 0x88, 0xc2, +0xcc, 0x00, 0x00, 0x00, 0x02, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x00, 0x76, 0x93, 0xcd, 0x38, 0x00, +0x00, 0x00, 0x02, 0x62, 0x4b, 0x47, 0x44, 0x00, +0x01, 0xdd, 0x8a, 0x13, 0xa4, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x16, 0x49, 0x44, +0x41, 0x54, 0x08, 0xd7, 0x63, 0x60, 0x80, 0x01, +0xfe, 0x03, 0x0c, 0xfc, 0x17, 0xc0, 0xe4, 0x0f, +0xec, 0x08, 0x0c, 0x00, 0xe5, 0x43, 0x0a, 0xb6, +0x5e, 0x9f, 0x71, 0xbb, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *file_new_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_file_new_png = new wxImage(); + if (!img_file_new_png || !img_file_new_png->IsOk()) + { + wxMemoryInputStream img_file_new_pngIS(file_new_png_data, sizeof(file_new_png_data)); + img_file_new_png->LoadFile(img_file_new_pngIS, wxBITMAP_TYPE_PNG); + } + return img_file_new_png; +} +#define file_new_png_img file_new_png_img() + +static wxBitmap *file_new_png_bmp() +{ + static wxBitmap *bmp_file_new_png; + if (!bmp_file_new_png || !bmp_file_new_png->IsOk()) + bmp_file_new_png = new wxBitmap(*file_new_png_img); + return bmp_file_new_png; +} +#define file_new_png_bmp file_new_png_bmp() + +static wxIcon *file_new_png_ico() +{ + static wxIcon *ico_file_new_png; + if (!ico_file_new_png || !ico_file_new_png->IsOk()) + { + ico_file_new_png = new wxIcon(); + ico_file_new_png->CopyFromBitmap(*file_new_png_bmp); + } + return ico_file_new_png; +} +#define file_new_png_ico file_new_png_ico() + +#endif // FILE_NEW_PNG_H diff --git a/include/images/file_open.png b/include/images/file_open.png new file mode 100644 index 0000000000000000000000000000000000000000..82326bb3bc4673233d075c70084b2bf79e7f33c2 GIT binary patch literal 738 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47{da5LR^8|xhv0a*>xek;kj$N;?iGJ}HT~ ze>3^rtB&`tn%}>wd;hZH!^@%%FLOS=$oTrc<e0}Ut5-}-wr(jc`T9jvvVxbVx5wA#>=|91wQF*7 z8nxcMk(HS{CpPBp9b22ddm7Vz{P^{gorR6Hy`rV9)t!M=Y4M_DrsT&?YaR;=O`g=q zq`5NlrR1%dkvA=OR{rD(SnllTsL0IB5M?a8qI~-|Q=oTLOI#yLQW8s2t&)pUffR$0 zfuVt}p^>hEVTh4|m5H&HiK(`Msg;4jymxx5P&DM`r(~v8LNpjyf;9kDn^+l`K{TA2 S9=Zmofx*+&&t;ucLK6TwLVdje literal 0 HcmV?d00001 diff --git a/include/images/file_open.pngc b/include/images/file_open.pngc new file mode 100644 index 0000000..b98ad34 --- /dev/null +++ b/include/images/file_open.pngc @@ -0,0 +1,137 @@ +#ifndef FILE_OPEN_PNG_H +#define FILE_OPEN_PNG_H + +static const unsigned char file_open_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x56, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x9d, 0xa9, 0xcf, 0xb4, +0xba, 0xd0, 0x67, 0x80, 0xcf, 0x43, 0x64, 0xce, +0x49, 0x68, 0xce, 0x63, 0x7c, 0xce, 0x89, 0x9a, +0xcf, 0x8b, 0x9b, 0xcf, 0xca, 0xcc, 0xd0, 0x94, +0xa2, 0xcf, 0x66, 0x7f, 0xcf, 0xc0, 0xb0, 0x62, +0xb5, 0x99, 0x15, 0xfa, 0xf6, 0xa1, 0xf6, 0xef, +0x7f, 0xf5, 0xed, 0x7e, 0xf7, 0xf1, 0x94, 0xf0, +0xe4, 0x51, 0xef, 0xe2, 0x4f, 0xef, 0xe3, 0x59, +0xf4, 0xec, 0x86, 0xed, 0xe0, 0x4e, 0xeb, 0xde, +0x4c, 0xeb, 0xde, 0x57, 0xee, 0xe3, 0x6d, 0xef, +0xe4, 0x77, 0xed, 0xe2, 0x76, 0xeb, 0xe0, 0x75, +0xea, 0xde, 0x73, 0xf2, 0xea, 0x97, 0xf5, 0xec, +0x7d, 0xca, 0xb4, 0x2b, 0xc0, 0xaf, 0x60, 0xcb, +0xc6, 0xad, 0xf3, 0xeb, 0x7c, 0xd4, 0xc1, 0x35, +0xd1, 0xbf, 0x5d, 0xf6, 0xf4, 0xb6, 0xf4, 0xf1, +0xaa, 0xf4, 0xf1, 0xa7, 0xf5, 0xf1, 0xa3, 0xf5, +0xf1, 0x9f, 0xf5, 0xf1, 0x9a, 0xf5, 0xf1, 0x96, +0xf5, 0xf1, 0x91, 0xf8, 0xf3, 0x9d, 0xdf, 0xd2, +0x74, 0xf2, 0xea, 0x7a, 0xe9, 0xdb, 0x4b, 0xbf, +0xa5, 0x1f, 0xeb, 0xe4, 0x9a, 0xef, 0xec, 0x93, +0xee, 0xea, 0x88, 0xef, 0xea, 0x83, 0xef, 0xea, +0x7e, 0xef, 0xe9, 0x78, 0xf0, 0xe9, 0x72, 0xf0, +0xe9, 0x6c, 0xf1, 0xe8, 0x68, 0xf5, 0xef, 0x84, +0xc2, 0xab, 0x32, 0xf1, 0xe8, 0x7a, 0xdd, 0xcb, +0x3e, 0xc4, 0xad, 0x3b, 0xf3, 0xf1, 0xa6, 0xee, +0xea, 0x8a, 0xef, 0xea, 0x84, 0xef, 0xea, 0x7f, +0xef, 0xe9, 0x79, 0xf0, 0xe9, 0x73, 0xf0, 0xe9, +0x6d, 0xf1, 0xe8, 0x67, 0xf2, 0xea, 0x6c, 0xea, +0xe1, 0x7f, 0xbb, 0xa5, 0x3d, 0xf0, 0xe6, 0x78, +0xc7, 0xb0, 0x28, 0xdf, 0xd4, 0x81, 0xf0, 0xed, +0x96, 0xef, 0xea, 0x85, 0xef, 0xea, 0x80, 0xef, +0xe9, 0x7a, 0xf0, 0xe9, 0x74, 0xf0, 0xe9, 0x6e, +0xf1, 0xe8, 0x62, 0xf4, 0xed, 0x77, 0xcf, 0xbd, +0x4f, 0xc6, 0xbb, 0x8a, 0xeb, 0xdf, 0x70, 0xba, +0xa0, 0x22, 0xf2, 0xef, 0xa6, 0xf0, 0xeb, 0x8a, +0xef, 0xe9, 0x7b, 0xf0, 0xe9, 0x75, 0xf1, 0xe8, +0x63, 0xf2, 0xe9, 0x63, 0xf2, 0xeb, 0x83, 0xb7, +0x9c, 0x1a, 0xcf, 0xce, 0xc9, 0xd8, 0xc8, 0x5f, +0xd4, 0xc4, 0x65, 0xf8, 0xf5, 0xb6, 0xf5, 0xf1, +0xa2, 0xf5, 0xf1, 0x9e, 0xf5, 0xf1, 0x94, 0xf5, +0xf0, 0x90, 0xf6, 0xf0, 0x8b, 0xf6, 0xf0, 0x88, +0xf8, 0xf1, 0x8f, 0xdc, 0xce, 0x6a, 0xc1, 0xb2, +0x69, 0xba, 0xa2, 0x35, 0xcc, 0xc8, 0xb6, 0x9a, +0x70, 0x84, 0x4f, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0xc3, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, +0x60, 0x80, 0x01, 0x46, 0x46, 0x26, 0x06, 0x64, +0xc0, 0xcc, 0xc2, 0xca, 0xc6, 0xce, 0xc0, 0x02, +0xe7, 0x73, 0x30, 0x33, 0x70, 0x72, 0x71, 0xb3, +0xb0, 0xa0, 0x28, 0x62, 0x60, 0x01, 0x09, 0xf0, +0xf0, 0x02, 0x01, 0x0f, 0x94, 0xcf, 0x0a, 0x14, +0xe0, 0xe5, 0xe3, 0x17, 0x10, 0x84, 0x8a, 0x80, +0x01, 0x2f, 0xbf, 0x90, 0xb0, 0x88, 0x28, 0x2f, +0x2f, 0x5c, 0x21, 0xaf, 0x80, 0xb0, 0x98, 0xb8, +0x84, 0xa4, 0x94, 0xb4, 0x8c, 0xac, 0x1c, 0x2f, +0x58, 0x40, 0x5e, 0x4c, 0x5c, 0x81, 0x17, 0x06, +0x14, 0x95, 0x18, 0x78, 0x95, 0xc5, 0x55, 0x54, +0xd5, 0xd4, 0x35, 0x34, 0xb5, 0xb4, 0x75, 0x74, +0xf5, 0xf4, 0x15, 0x19, 0x78, 0x0d, 0x0c, 0x8d, +0x8c, 0x4d, 0x4c, 0xcd, 0xcc, 0x2d, 0x2c, 0xad, +0xac, 0x6d, 0x6c, 0x81, 0x2a, 0xec, 0xec, 0x1d, +0x1c, 0x9d, 0x9c, 0x5d, 0x5c, 0xdd, 0xdc, 0x3d, +0x3c, 0xbd, 0xbc, 0x81, 0x66, 0xf8, 0xf8, 0xfa, +0xf9, 0x07, 0x04, 0x06, 0x05, 0x87, 0x78, 0x84, +0x86, 0x85, 0x47, 0x00, 0x05, 0x22, 0xa3, 0xa2, +0x63, 0x02, 0x63, 0xe3, 0x42, 0xac, 0xe3, 0x13, +0x12, 0x93, 0x92, 0x81, 0x02, 0x29, 0xa9, 0x69, +0xe9, 0x19, 0xda, 0x99, 0x59, 0xd9, 0x39, 0xb9, +0x79, 0xf9, 0x0c, 0x50, 0xa7, 0x43, 0x41, 0x41, +0x21, 0x03, 0x03, 0x00, 0x5a, 0x33, 0x1d, 0xa8, +0x77, 0xb7, 0xf6, 0x35, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *file_open_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_file_open_png = new wxImage(); + if (!img_file_open_png || !img_file_open_png->IsOk()) + { + wxMemoryInputStream img_file_open_pngIS(file_open_png_data, sizeof(file_open_png_data)); + img_file_open_png->LoadFile(img_file_open_pngIS, wxBITMAP_TYPE_PNG); + } + return img_file_open_png; +} +#define file_open_png_img file_open_png_img() + +static wxBitmap *file_open_png_bmp() +{ + static wxBitmap *bmp_file_open_png; + if (!bmp_file_open_png || !bmp_file_open_png->IsOk()) + bmp_file_open_png = new wxBitmap(*file_open_png_img); + return bmp_file_open_png; +} +#define file_open_png_bmp file_open_png_bmp() + +static wxIcon *file_open_png_ico() +{ + static wxIcon *ico_file_open_png; + if (!ico_file_open_png || !ico_file_open_png->IsOk()) + { + ico_file_open_png = new wxIcon(); + ico_file_open_png->CopyFromBitmap(*file_open_png_bmp); + } + return ico_file_open_png; +} +#define file_open_png_ico file_open_png_ico() + +#endif // FILE_OPEN_PNG_H diff --git a/include/images/file_save.png b/include/images/file_save.png new file mode 100644 index 0000000000000000000000000000000000000000..52da50590d7af8762a7765442977eec0f855593d GIT binary patch literal 636 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl482JKxLR^8|f=Nep()P~2@bJ^m zKQF)jdiLel?ewd!M_zp0 z^YqJ>$6wYy{CxD)_qr_)s`uU4|KeNy<_Fb#Z$AI_`_j7~CtiO)^6LA6m*4lk_;&5% zulfy-YWCc+Za897b)sSYDNQ2-Uyv? zt6|-f+MRcT=3NS&eI;bZ^^j>dLZ{vgoqQ{7((Q(|Piwc|wW&E~TX`~U!kxy|&z^k# zdFSJgr(b`EO}HE0f46bfvndCk#4Wh-{L8OxPre*~{XM+zUU=`l#+A>f?0fd=+wUvy zf1G~v{qU>rH$MJqT=l$Z<@1Gm-?G{Et z!DHEv61CZ<#k-aoIkv7(%i3AB_-0l)$F8e#x?gTLD>6 z@4hY2W0&!Nep+<RdP`(kYX@0Ff`CL zG}1LN3^6jWGBLI?G1WFOwK6c6_fBsWiiX_$l+3hBhz0{oum+%N6DtEVh=xIsOk()) + { + wxMemoryInputStream img_file_save_pngIS(file_save_png_data, sizeof(file_save_png_data)); + img_file_save_png->LoadFile(img_file_save_pngIS, wxBITMAP_TYPE_PNG); + } + return img_file_save_png; +} +#define file_save_png_img file_save_png_img() + +static wxBitmap *file_save_png_bmp() +{ + static wxBitmap *bmp_file_save_png; + if (!bmp_file_save_png || !bmp_file_save_png->IsOk()) + bmp_file_save_png = new wxBitmap(*file_save_png_img); + return bmp_file_save_png; +} +#define file_save_png_bmp file_save_png_bmp() + +static wxIcon *file_save_png_ico() +{ + static wxIcon *ico_file_save_png; + if (!ico_file_save_png || !ico_file_save_png->IsOk()) + { + ico_file_save_png = new wxIcon(); + ico_file_save_png->CopyFromBitmap(*file_save_png_bmp); + } + return ico_file_save_png; +} +#define file_save_png_ico file_save_png_ico() + +#endif // FILE_SAVE_PNG_H diff --git a/include/images/folder.png b/include/images/folder.png new file mode 100644 index 0000000000000000000000000000000000000000..d7d09d292850aeb36209d81e4d33eb24cb9a8473 GIT binary patch literal 508 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMfoB*E?*Z=?jpP6ZLdWP}IX@+25mnXQj)m45rHqtY@Y(uC5ebQ6{jonAh9eyScgf+O=zoOP$q# z?qp2zc6VXuV3qX%aySb-B8!1Ei0#4Pb~4)z$e8Zw;us=vIraQYz9t7AmIn_b7A(+c zl2KAvvqs}lPm-IsOk()) + { + wxMemoryInputStream img_folder_pngIS(folder_png_data, sizeof(folder_png_data)); + img_folder_png->LoadFile(img_folder_pngIS, wxBITMAP_TYPE_PNG); + } + return img_folder_png; +} +#define folder_png_img folder_png_img() + +static wxBitmap *folder_png_bmp() +{ + static wxBitmap *bmp_folder_png; + if (!bmp_folder_png || !bmp_folder_png->IsOk()) + bmp_folder_png = new wxBitmap(*folder_png_img); + return bmp_folder_png; +} +#define folder_png_bmp folder_png_bmp() + +static wxIcon *folder_png_ico() +{ + static wxIcon *ico_folder_png; + if (!ico_folder_png || !ico_folder_png->IsOk()) + { + ico_folder_png = new wxIcon(); + ico_folder_png->CopyFromBitmap(*folder_png_bmp); + } + return ico_folder_png; +} +#define folder_png_ico folder_png_ico() + +#endif // FOLDER_PNG_H diff --git a/include/images/foreigndatawrapper-sm.png b/include/images/foreigndatawrapper-sm.png new file mode 100644 index 0000000000000000000000000000000000000000..2467ccf1422a59a7218fd0bb19c2a42bdf52e5d7 GIT binary patch literal 423 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}QGic~E0BJDv+cp5$Qv6qzrVk7 zW3&9@vzBik`G5Ho|K-)uTicc2-1GkNGyU0x%oo?3fBedPak1gnHlr`^;(z|izO~Kb z%lm|1zjI$+bN~H2|Mm{mcMpR9{3*J*S>f3^`;Si}e|^pQ`={jETDdE$#Qyy)dv><$ z|KAGswyocQwlbCk`2{mLJiCzwvL>2>S4={E+nQaGTe!Vz zahdU=*X&ESFOpJE*&;e)`qd3*DpaT5u9JDLS%3P((k)@7VQ?e2h_me>FVdQ&MBb@04%Yw7ytkO literal 0 HcmV?d00001 diff --git a/include/images/foreigndatawrapper-sm.pngc b/include/images/foreigndatawrapper-sm.pngc new file mode 100644 index 0000000..dc4cefa --- /dev/null +++ b/include/images/foreigndatawrapper-sm.pngc @@ -0,0 +1,97 @@ +#ifndef FOREIGNDATAWRAPPER_SM_PNG_H +#define FOREIGNDATAWRAPPER_SM_PNG_H + +static const unsigned char foreigndatawrapper_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x72, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xeb, 0xd9, 0x86, 0xe0, +0xc2, 0x59, 0xd8, 0xb1, 0x29, 0xf7, 0xef, 0xd4, +0xd8, 0xb3, 0x1f, 0xe3, 0xcd, 0x39, 0xed, 0xe2, +0x4f, 0xf4, 0xf2, 0x5f, 0xf4, 0xea, 0xc5, 0xda, +0xb7, 0x23, 0xec, 0xde, 0x4b, 0xf8, 0xf9, 0x67, +0xe6, 0xd0, 0x69, 0xe8, 0xd6, 0x43, 0xf8, 0xfa, +0x69, 0xe8, 0xd1, 0x80, 0xda, 0xb6, 0x32, 0xf4, +0xee, 0x5f, 0xf9, 0xfa, 0x6b, 0xda, 0xb6, 0x38, +0xf4, 0xef, 0x60, 0xfa, 0xfb, 0x6d, 0xe9, 0xd6, +0x47, 0xfb, 0xfb, 0x6f, 0xdb, 0xb8, 0x25, 0xee, +0xe0, 0x53, 0xfc, 0xfc, 0x72, 0xd9, 0xb3, 0x20, +0xe6, 0xce, 0x3f, 0xf1, 0xe5, 0x59, 0xfa, 0xf5, +0x6c, 0xfd, 0xfc, 0x74, 0xd6, 0xad, 0x1e, 0xd4, +0xaa, 0x16, 0xfe, 0xfd, 0x76, 0xe6, 0xcd, 0x76, +0xff, 0xfd, 0x78, 0x07, 0x86, 0xb5, 0xf6, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x6c, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x8d, 0x8f, 0x49, 0x0e, 0x80, +0x20, 0x10, 0x04, 0x47, 0x14, 0x5c, 0x50, 0xdc, +0x77, 0xdc, 0x40, 0xff, 0xff, 0x45, 0x13, 0x98, +0x18, 0xb9, 0x51, 0xb7, 0xae, 0xa4, 0x33, 0x3d, +0x00, 0x7e, 0x04, 0x24, 0x0c, 0x09, 0x44, 0x5f, +0xa6, 0x2c, 0x4e, 0x92, 0x98, 0xd1, 0x14, 0x73, +0xc6, 0x73, 0x03, 0xcf, 0x6c, 0x2e, 0x44, 0x89, +0x88, 0xca, 0x88, 0xba, 0x69, 0x91, 0xa6, 0x33, +0xa2, 0xeb, 0x07, 0xa4, 0xb7, 0xa2, 0x1a, 0x27, +0x64, 0xb4, 0x15, 0x98, 0x97, 0xd5, 0xb0, 0xcc, +0x78, 0x25, 0x95, 0xdb, 0x7e, 0x1c, 0xe7, 0x29, +0x7f, 0xcb, 0xc8, 0xa5, 0xb4, 0x56, 0xce, 0xd8, +0x5b, 0x3d, 0xae, 0x00, 0x50, 0xb7, 0xdf, 0x9f, +0x2f, 0xe4, 0x0e, 0x07, 0xe3, 0xd8, 0x9f, 0xd2, +0x10, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x31, 0x2d, 0x30, 0x33, 0x2d, 0x30, 0x38, 0x54, +0x31, 0x32, 0x3a, 0x31, 0x37, 0x3a, 0x30, 0x39, +0x2b, 0x30, 0x36, 0x3a, 0x30, 0x30, 0xd3, 0xe6, +0xa8, 0x62, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x31, 0x2d, 0x30, 0x33, 0x2d, 0x30, 0x38, +0x54, 0x31, 0x32, 0x3a, 0x31, 0x37, 0x3a, 0x30, +0x39, 0x2b, 0x30, 0x36, 0x3a, 0x30, 0x30, 0xa2, +0xbb, 0x10, 0xde, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *foreigndatawrapper_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_foreigndatawrapper_sm_png = new wxImage(); + if (!img_foreigndatawrapper_sm_png || !img_foreigndatawrapper_sm_png->IsOk()) + { + wxMemoryInputStream img_foreigndatawrapper_sm_pngIS(foreigndatawrapper_sm_png_data, sizeof(foreigndatawrapper_sm_png_data)); + img_foreigndatawrapper_sm_png->LoadFile(img_foreigndatawrapper_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_foreigndatawrapper_sm_png; +} +#define foreigndatawrapper_sm_png_img foreigndatawrapper_sm_png_img() + +static wxBitmap *foreigndatawrapper_sm_png_bmp() +{ + static wxBitmap *bmp_foreigndatawrapper_sm_png; + if (!bmp_foreigndatawrapper_sm_png || !bmp_foreigndatawrapper_sm_png->IsOk()) + bmp_foreigndatawrapper_sm_png = new wxBitmap(*foreigndatawrapper_sm_png_img); + return bmp_foreigndatawrapper_sm_png; +} +#define foreigndatawrapper_sm_png_bmp foreigndatawrapper_sm_png_bmp() + +static wxIcon *foreigndatawrapper_sm_png_ico() +{ + static wxIcon *ico_foreigndatawrapper_sm_png; + if (!ico_foreigndatawrapper_sm_png || !ico_foreigndatawrapper_sm_png->IsOk()) + { + ico_foreigndatawrapper_sm_png = new wxIcon(); + ico_foreigndatawrapper_sm_png->CopyFromBitmap(*foreigndatawrapper_sm_png_bmp); + } + return ico_foreigndatawrapper_sm_png; +} +#define foreigndatawrapper_sm_png_ico foreigndatawrapper_sm_png_ico() + +#endif // FOREIGNDATAWRAPPER_SM_PNG_H diff --git a/include/images/foreigndatawrapper.png b/include/images/foreigndatawrapper.png new file mode 100644 index 0000000000000000000000000000000000000000..0cb967671834e280190bbd5777c3ddc0ab07901d GIT binary patch literal 411 zcmV;M0c8G(P)Px#%uq~JMV5h&gKT{2-{<1h-r333(7nsXvB1BkxruUunTC_NsI%$c<=Dy8&%MgO zsJNYkmfO+T>fh$#)!om&%CMKI(8bI0@$&ij`StPg`uY0t?eFB<-|+75_VxDQ)7QkS zwX~I?#I3gP?(X;X_Qb2SvXGv`t+n>`_2Jam#ICsS?(f5@v$Bw##I3i-#>e2)*rJS- zwU(oyj+V{L%#n3~w3ea6t+uS9r||CZy0El+l%z|TsEn();ndlojFeiUv>)2XQlztI zgOXdNwqq#b)Bpeg0d!JMQvg8b*k%9#00Cl4M??UK1szBL000SaNLh0L01FcU01FcV z0GgZ_00007bV*G`2ipT36%jB#6T$fa0028lL_t&-)4k8p4FEs{1JD|y`!6c4MJ#YW zi1$$e#3`VFu7Q~S0WCEI5;Xx8$OU%L03E#0hyTHSKLJ-#4RL;k+`<3=002ovPDHLk FV1jzK&rSdU literal 0 HcmV?d00001 diff --git a/include/images/foreigndatawrapper.pngc b/include/images/foreigndatawrapper.pngc new file mode 100644 index 0000000..ee20c4d --- /dev/null +++ b/include/images/foreigndatawrapper.pngc @@ -0,0 +1,96 @@ +#ifndef FOREIGNDATAWRAPPER_PNG_H +#define FOREIGNDATAWRAPPER_PNG_H + +static const unsigned char foreigndatawrapper_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0xcc, 0x50, 0x4c, 0x54, 0x45, 0x96, 0x81, +0x8f, 0x83, 0x6c, 0x7c, 0xea, 0xdf, 0xe7, 0xe2, +0xd5, 0xde, 0xd9, 0xc9, 0xd5, 0xd0, 0xbd, 0xcb, +0xc6, 0xb1, 0xc0, 0xbf, 0xa6, 0xb9, 0x89, 0x72, +0x82, 0x99, 0x86, 0x93, 0xb8, 0xa8, 0xb3, 0xe9, +0xdf, 0xe5, 0xd8, 0xc9, 0xd4, 0xcf, 0xbd, 0xca, +0xbf, 0xa8, 0xb8, 0x9d, 0x84, 0x96, 0xdb, 0xd1, +0xd8, 0xea, 0xdf, 0xe6, 0xe2, 0xd5, 0xdd, 0xcf, +0xbe, 0xca, 0xb0, 0x97, 0xa9, 0xd0, 0xc5, 0xcb, +0xf2, 0xf1, 0xf2, 0xf9, 0xf8, 0xf9, 0xf5, 0xf1, +0xf2, 0xfa, 0xf9, 0xfa, 0xf1, 0xed, 0xef, 0xe4, +0xdb, 0xdf, 0xf0, 0xee, 0xef, 0xf6, 0xf5, 0xf6, +0xe0, 0xd3, 0xd7, 0xc4, 0xab, 0xb5, 0xb4, 0x95, +0xa1, 0xc4, 0xad, 0xb6, 0xef, 0xee, 0xee, 0xf7, +0xf5, 0xf6, 0xc4, 0xab, 0xb4, 0xb2, 0x90, 0x9e, +0xc3, 0xad, 0xb5, 0xf6, 0xf5, 0xf5, 0xe1, 0xd4, +0xd8, 0xc4, 0xae, 0xb8, 0xef, 0xee, 0xef, 0xc3, +0xaa, 0xb3, 0xb2, 0x90, 0x9d, 0xc4, 0xad, 0xb7, +0xc7, 0xc6, 0xc7, 0xe0, 0xd4, 0xd8, 0xa2, 0x8c, +0x94, 0xb5, 0x96, 0xa3, 0xa1, 0x8e, 0x96, 0xcd, +0xcc, 0xcc, 0x91, 0x75, 0x80, 0xb4, 0x96, 0xa1, +0xc3, 0xad, 0xb6, 0xac, 0xa2, 0xa7, 0xf0, 0xee, +0xf0, 0xba, 0xb0, 0xb4, 0x7b, 0x94, 0xa4, 0x4b, +0x98, 0xa8, 0x8c, 0xab, 0xb8, 0xe1, 0xd4, 0xd9, +0xa1, 0x8c, 0x94, 0x5a, 0xa2, 0xb4, 0x1f, 0xda, +0xc7, 0x52, 0xa4, 0xb3, 0x67, 0x83, 0x92, 0x5b, +0xa5, 0xb6, 0x63, 0x28, 0xe2, 0xd4, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, 0x62, +0x4b, 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x03, +0x1d, 0x15, 0x11, 0x30, 0x3e, 0x13, 0xc1, 0xf9, +0x00, 0x00, 0x00, 0x3b, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0xbd, 0xcf, 0xd1, 0x0d, 0x00, 0x40, +0x04, 0x03, 0xd0, 0x1a, 0xa3, 0xfb, 0x2f, 0x2a, +0xae, 0x45, 0x2c, 0x70, 0x3e, 0x88, 0xf7, 0x51, +0x01, 0xc4, 0x29, 0xa0, 0x80, 0xae, 0x81, 0x98, +0xfd, 0x01, 0x2d, 0x35, 0x04, 0x12, 0x35, 0x01, +0x15, 0xc8, 0x05, 0x76, 0xd0, 0x00, 0x1d, 0xbc, +0xd0, 0x87, 0xff, 0xc1, 0x7d, 0x3f, 0x01, 0x57, +0x52, 0x0d, 0x71, 0x7e, 0x86, 0xdc, 0xc2, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *foreigndatawrapper_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_foreigndatawrapper_png = new wxImage(); + if (!img_foreigndatawrapper_png || !img_foreigndatawrapper_png->IsOk()) + { + wxMemoryInputStream img_foreigndatawrapper_pngIS(foreigndatawrapper_png_data, sizeof(foreigndatawrapper_png_data)); + img_foreigndatawrapper_png->LoadFile(img_foreigndatawrapper_pngIS, wxBITMAP_TYPE_PNG); + } + return img_foreigndatawrapper_png; +} +#define foreigndatawrapper_png_img foreigndatawrapper_png_img() + +static wxBitmap *foreigndatawrapper_png_bmp() +{ + static wxBitmap *bmp_foreigndatawrapper_png; + if (!bmp_foreigndatawrapper_png || !bmp_foreigndatawrapper_png->IsOk()) + bmp_foreigndatawrapper_png = new wxBitmap(*foreigndatawrapper_png_img); + return bmp_foreigndatawrapper_png; +} +#define foreigndatawrapper_png_bmp foreigndatawrapper_png_bmp() + +static wxIcon *foreigndatawrapper_png_ico() +{ + static wxIcon *ico_foreigndatawrapper_png; + if (!ico_foreigndatawrapper_png || !ico_foreigndatawrapper_png->IsOk()) + { + ico_foreigndatawrapper_png = new wxIcon(); + ico_foreigndatawrapper_png->CopyFromBitmap(*foreigndatawrapper_png_bmp); + } + return ico_foreigndatawrapper_png; +} +#define foreigndatawrapper_png_ico foreigndatawrapper_png_ico() + +#endif // FOREIGNDATAWRAPPER_PNG_H diff --git a/include/images/foreigndatawrappers.png b/include/images/foreigndatawrappers.png new file mode 100644 index 0000000000000000000000000000000000000000..6b1c8543c69448b928acd21032fe50b21f032dd1 GIT binary patch literal 444 zcmV;t0YmPx#u24)=MV5h&gKT{2-{<1h-r333(7nsXvB1BkxruUunTC_NsI%$c<=Dy8&%MgO zsJNYkmfO+T>fh$#)!om&%CMKI(8bI0@$&ij`StPg`uY0t?eFB<-|+75_VxDQ)7QkS zwOpjOjH|fs?(X;X_Qb2STcEQa+Q(zD!I*rNXN8+jm#y^i^5N9j!>Y4erMBol`R4EO&)eYP)Y-$Uv|6IH_Vx9cr0AId0004WQchCj1x*-2O5foEZm^ z`4qFE7i6Pp7#W~t4s-!1H?RTG&^sRBo~lya!!orz>gCg2eO literal 0 HcmV?d00001 diff --git a/include/images/foreigndatawrappers.pngc b/include/images/foreigndatawrappers.pngc new file mode 100644 index 0000000..e01147c --- /dev/null +++ b/include/images/foreigndatawrappers.pngc @@ -0,0 +1,100 @@ +#ifndef FOREIGNDATAWRAPPERS_PNG_H +#define FOREIGNDATAWRAPPERS_PNG_H + +static const unsigned char foreigndatawrappers_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0xae, 0x50, 0x4c, 0x54, 0x45, 0x96, 0x81, +0x8f, 0x83, 0x6c, 0x7c, 0xea, 0xdf, 0xe7, 0xe2, +0xd5, 0xde, 0xd9, 0xc9, 0xd5, 0xd0, 0xbd, 0xcb, +0xc6, 0xb1, 0xc0, 0xbf, 0xa6, 0xb9, 0x89, 0x72, +0x82, 0x99, 0x86, 0x93, 0xb8, 0xa8, 0xb3, 0xe9, +0xdf, 0xe5, 0xd8, 0xc9, 0xd4, 0xcf, 0xbd, 0xca, +0xbf, 0xa8, 0xb8, 0x9d, 0x84, 0x96, 0xdb, 0xd1, +0xd8, 0xea, 0xdf, 0xe6, 0xe2, 0xd5, 0xdd, 0xcf, +0xbe, 0xca, 0xb0, 0x97, 0xa9, 0xd0, 0xc5, 0xcb, +0xf2, 0xf1, 0xf2, 0xf9, 0xf8, 0xf9, 0xf5, 0xf1, +0xf2, 0xfa, 0xf9, 0xfa, 0xf1, 0xed, 0xef, 0xe4, +0xdb, 0xdf, 0xf0, 0xee, 0xef, 0xf6, 0xf5, 0xf6, +0xe0, 0xd3, 0xd7, 0xc4, 0xab, 0xb5, 0x5c, 0xa4, +0xb6, 0x8c, 0xab, 0xb8, 0xef, 0xee, 0xee, 0xf7, +0xf5, 0xf6, 0xc4, 0xab, 0xb4, 0x5b, 0xa0, 0xb3, +0x1f, 0xda, 0xc7, 0x63, 0xb1, 0xc1, 0x98, 0x7c, +0x95, 0x67, 0x85, 0x9b, 0x4f, 0x97, 0xad, 0xf4, +0xf1, 0xf2, 0xe1, 0xd4, 0xd8, 0xc3, 0xaa, 0xb3, +0x5b, 0xa5, 0xb6, 0xef, 0xee, 0xef, 0xe0, 0xd4, +0xd8, 0x5b, 0xa2, 0xb4, 0xf5, 0xf1, 0xf3, 0xf9, +0xf9, 0xf9, 0xe6, 0xef, 0xf1, 0xcf, 0xdb, 0xe0, +0xe1, 0xd4, 0xd9, 0xc3, 0xab, 0xb4, 0x5a, 0xa2, +0xb4, 0xf6, 0xf5, 0xf5, 0x98, 0xa4, 0xe8, 0x99, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x01, 0x62, 0x4b, 0x47, 0x44, 0x00, 0x88, 0x05, +0x1d, 0x48, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, +0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, +0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, +0xdb, 0x03, 0x1d, 0x15, 0x11, 0x24, 0x24, 0xc9, +0x15, 0x84, 0x00, 0x00, 0x00, 0x7a, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x5d, 0x8e, 0xb1, 0x0a, +0x04, 0x21, 0x10, 0x43, 0xb5, 0xbd, 0x6d, 0xc5, +0x20, 0xd8, 0x68, 0x33, 0x90, 0x3e, 0xff, 0xff, +0x6b, 0x37, 0x3a, 0xbb, 0x8b, 0x77, 0x69, 0x24, +0x8f, 0x98, 0x49, 0xca, 0x87, 0xd2, 0x92, 0xbf, +0x6d, 0xeb, 0x00, 0xbf, 0x99, 0xdc, 0xfe, 0x32, +0x1b, 0x9c, 0x19, 0x07, 0x91, 0xf9, 0x14, 0xb3, +0xa1, 0x17, 0x64, 0xa3, 0x69, 0x18, 0x19, 0xa0, +0x65, 0x0e, 0x74, 0x01, 0x28, 0x37, 0xb0, 0x01, +0xd1, 0xd0, 0x3b, 0x1e, 0xe0, 0x9e, 0xaa, 0x52, +0xdd, 0xc3, 0x32, 0xb5, 0x3c, 0xea, 0xec, 0x8a, +0xc3, 0xbc, 0xe6, 0x2a, 0x55, 0x9d, 0x8a, 0xad, +0xbc, 0x00, 0xbf, 0x60, 0xa8, 0x16, 0xf3, 0x3d, +0xee, 0x7f, 0xb8, 0x9a, 0x02, 0x94, 0xb1, 0xbc, +0xd7, 0x30, 0x40, 0x4a, 0x66, 0xbc, 0xf5, 0x05, +0x6f, 0x95, 0x13, 0x38, 0x14, 0x91, 0x2d, 0xb4, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *foreigndatawrappers_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_foreigndatawrappers_png = new wxImage(); + if (!img_foreigndatawrappers_png || !img_foreigndatawrappers_png->IsOk()) + { + wxMemoryInputStream img_foreigndatawrappers_pngIS(foreigndatawrappers_png_data, sizeof(foreigndatawrappers_png_data)); + img_foreigndatawrappers_png->LoadFile(img_foreigndatawrappers_pngIS, wxBITMAP_TYPE_PNG); + } + return img_foreigndatawrappers_png; +} +#define foreigndatawrappers_png_img foreigndatawrappers_png_img() + +static wxBitmap *foreigndatawrappers_png_bmp() +{ + static wxBitmap *bmp_foreigndatawrappers_png; + if (!bmp_foreigndatawrappers_png || !bmp_foreigndatawrappers_png->IsOk()) + bmp_foreigndatawrappers_png = new wxBitmap(*foreigndatawrappers_png_img); + return bmp_foreigndatawrappers_png; +} +#define foreigndatawrappers_png_bmp foreigndatawrappers_png_bmp() + +static wxIcon *foreigndatawrappers_png_ico() +{ + static wxIcon *ico_foreigndatawrappers_png; + if (!ico_foreigndatawrappers_png || !ico_foreigndatawrappers_png->IsOk()) + { + ico_foreigndatawrappers_png = new wxIcon(); + ico_foreigndatawrappers_png->CopyFromBitmap(*foreigndatawrappers_png_bmp); + } + return ico_foreigndatawrappers_png; +} +#define foreigndatawrappers_png_ico foreigndatawrappers_png_ico() + +#endif // FOREIGNDATAWRAPPERS_PNG_H diff --git a/include/images/foreignkey.png b/include/images/foreignkey.png new file mode 100644 index 0000000000000000000000000000000000000000..b3605500439db72c2c43879abb61a24c956e1bf5 GIT binary patch literal 299 zcmeAS@N?(olHy`uVBq!ia0vp^0wBx*Bp9q_EZ7UAm`Z~Df*BafCZDwc@shmVT^JZv z^(q?yd7K3vk;OpT1B~5HX4?T7@t!V@ArhC96BcmYxO{&<`^@{hp1!(zcCE*!Xt{ek z>#~zoS#lB*UhMz1;M236-R60Bchvnn_1J5|fxo9_r|aE`sZD=6Ra!x`dfT1-l|Ns# zc?qz5Y;4QhSCW{_ZI`Xd&M@z_Ipcx{mt%ldsg}4#l%yncptAuDUumo!Wsy4AQFoS3~H9d3Uf LtDnm{r-UW|7b#?7 literal 0 HcmV?d00001 diff --git a/include/images/foreignkey.pngc b/include/images/foreignkey.pngc new file mode 100644 index 0000000..394ae2a --- /dev/null +++ b/include/images/foreignkey.pngc @@ -0,0 +1,82 @@ +#ifndef FOREIGNKEY_PNG_H +#define FOREIGNKEY_PNG_H + +static const unsigned char foreignkey_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x98, 0xa0, +0xbd, 0x00, 0x00, 0x00, 0x02, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x00, 0x76, 0x93, 0xcd, 0x38, 0x00, +0x00, 0x00, 0x02, 0x62, 0x4b, 0x47, 0x44, 0x00, +0x00, 0xaa, 0x8d, 0x23, 0x32, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x5f, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0xa0, 0x0a, +0xd8, 0xd3, 0xdf, 0xbf, 0x07, 0x99, 0xdf, 0xba, +0xe5, 0xea, 0xd5, 0xcd, 0xad, 0x48, 0xf2, 0x5b, +0x1e, 0xde, 0xb9, 0x7e, 0x6b, 0x63, 0x25, 0x04, +0x6c, 0x60, 0x60, 0xe8, 0xbf, 0xfa, 0xa0, 0xf2, +0xe6, 0xb9, 0x8b, 0x37, 0x6e, 0xdd, 0xb8, 0x7e, +0xf9, 0xca, 0xe3, 0x4a, 0x90, 0xc0, 0xfd, 0xca, +0x9b, 0x67, 0x2e, 0xdc, 0x5c, 0x7d, 0x67, 0xe5, +0x95, 0x1b, 0x20, 0x15, 0x7b, 0xb6, 0xdc, 0xbf, +0x79, 0xf9, 0xea, 0x86, 0x4a, 0x10, 0x04, 0xf1, +0x81, 0x86, 0x6e, 0xbe, 0x74, 0x61, 0x63, 0x0b, +0x3e, 0x6b, 0x29, 0x07, 0x00, 0x9e, 0xeb, 0x37, +0x01, 0xa0, 0xe0, 0xd3, 0x5c, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *foreignkey_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_foreignkey_png = new wxImage(); + if (!img_foreignkey_png || !img_foreignkey_png->IsOk()) + { + wxMemoryInputStream img_foreignkey_pngIS(foreignkey_png_data, sizeof(foreignkey_png_data)); + img_foreignkey_png->LoadFile(img_foreignkey_pngIS, wxBITMAP_TYPE_PNG); + } + return img_foreignkey_png; +} +#define foreignkey_png_img foreignkey_png_img() + +static wxBitmap *foreignkey_png_bmp() +{ + static wxBitmap *bmp_foreignkey_png; + if (!bmp_foreignkey_png || !bmp_foreignkey_png->IsOk()) + bmp_foreignkey_png = new wxBitmap(*foreignkey_png_img); + return bmp_foreignkey_png; +} +#define foreignkey_png_bmp foreignkey_png_bmp() + +static wxIcon *foreignkey_png_ico() +{ + static wxIcon *ico_foreignkey_png; + if (!ico_foreignkey_png || !ico_foreignkey_png->IsOk()) + { + ico_foreignkey_png = new wxIcon(); + ico_foreignkey_png->CopyFromBitmap(*foreignkey_png_bmp); + } + return ico_foreignkey_png; +} +#define foreignkey_png_ico foreignkey_png_ico() + +#endif // FOREIGNKEY_PNG_H diff --git a/include/images/foreignkeybad.png b/include/images/foreignkeybad.png new file mode 100644 index 0000000000000000000000000000000000000000..975561bcf7237d5e99e9d42ff705db67f1bb2fdb GIT binary patch literal 618 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47?}cmLR^8|J$v@__xDejFyZ2b zi$8z-{QB`zYisM4En6<0I(I!O=_mukh49ENQx_g}_r9B%`S9VxT^qNb3Jm#HUVhl! zdv;s@UR$S+;o(=WUVZT3K}|{3x3aQtMMYop^7dFed<+YF@9+Q4!}I?A`&DI?UvqQ6 zWMq6!O8O8Q`rZ#H?s56juX-#d5r&6_u0x^(Hn`SXVl9ln*C z`XLx7?)%QoZIzC3Utiz$4V$k4O$ZKt@8k2%)%A^?{c8)0-OjEbf`Zz;|9=Z=GFcI(xm;(te?;`dmTbt&{T+H?Q>ONi$u%pUW#W=hVD!YnKOx z0%J*#UoeBivm0qZ4rhT!WHFHT0Ash4*>*t2d`}n05Q)ocd!Gt51&FlhcQmc(yxVnG z_QqY=_y4tuT#tzt)X$mu_uM%>#d^WRQWlF}KCf&v?%p7fwDq9h|E9y52U)it=ayGp zV=v&MA>$~rv4TnDgeT|961JN$^VB39^+a5!oSK^T_Oj!Ts>L_67GHkr`19O1cITdB zlVAFHub7p*F(z^E%~veD|1!GIIVYasa7c9fZ)Shnk3kvpt3v;?HQy7Q(A;;*1?W`O z64!{5l*E!$tK_0oAjM#0U}&goV61Ck5n^a$WoT|?V5x0jW@TV-`Pqsj6b-rgDVb@N WxHT-=EpQL0fx*+&&t;ucLK6V@6Aj$} literal 0 HcmV?d00001 diff --git a/include/images/foreignkeybad.pngc b/include/images/foreignkeybad.pngc new file mode 100644 index 0000000..e76dd1f --- /dev/null +++ b/include/images/foreignkeybad.pngc @@ -0,0 +1,122 @@ +#ifndef FOREIGNKEYBAD_PNG_H +#define FOREIGNKEYBAD_PNG_H + +static const unsigned char foreignkeybad_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x02, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xbc, 0xbc, 0xbc, 0x8f, +0x8f, 0x8f, 0x90, 0x90, 0x90, 0xd1, 0xd0, 0xd1, +0xf9, 0xf8, 0xf9, 0xf5, 0xf1, 0xf2, 0x85, 0x85, +0x85, 0xb4, 0xb4, 0xb4, 0xd1, 0xca, 0xce, 0xd7, +0x62, 0x62, 0xc5, 0x00, 0x00, 0xd0, 0x57, 0x59, +0xb4, 0x95, 0xa1, 0xc5, 0x47, 0x4b, 0xdd, 0x69, +0x69, 0xe1, 0xe1, 0xe1, 0xba, 0xb1, 0xb7, 0xca, +0x51, 0x54, 0xf6, 0x77, 0x77, 0xc3, 0x47, 0x4b, +0x9b, 0x86, 0x8f, 0xbd, 0x3d, 0x42, 0xf1, 0x57, +0x57, 0xd5, 0xd5, 0xd5, 0xe0, 0xe0, 0xe0, 0x7c, +0x74, 0x7a, 0xf6, 0x76, 0x76, 0xf6, 0x72, 0x72, +0xf5, 0x6e, 0x6e, 0xbc, 0x3b, 0x40, 0xf1, 0x56, +0x56, 0xef, 0x4f, 0x4f, 0xee, 0x48, 0x49, 0xdf, +0xdf, 0xdf, 0x7a, 0x76, 0x79, 0xf5, 0x6d, 0x6d, +0xf4, 0x68, 0x68, 0xf3, 0x62, 0x62, 0xf0, 0x55, +0x55, 0xef, 0x4e, 0x4f, 0xee, 0x48, 0x48, 0xd3, +0xd2, 0xd3, 0xd0, 0xc8, 0xcc, 0xf3, 0x61, 0x61, +0xf1, 0x5b, 0x5b, 0xf0, 0x54, 0x54, 0xef, 0x4d, +0x4e, 0xee, 0x47, 0x47, 0xb3, 0xb3, 0xb3, 0xd2, +0xd2, 0xd2, 0xd0, 0xcf, 0xcf, 0xc3, 0xc2, 0xc3, +0xda, 0x65, 0x65, 0xf0, 0x53, 0x54, 0xef, 0x4d, +0x4d, 0xee, 0x46, 0x46, 0xaa, 0x2c, 0x33, 0x8e, +0x8e, 0x8e, 0xb7, 0xb0, 0xb3, 0xd6, 0x62, 0x62, +0xf0, 0x53, 0x53, 0xef, 0x4c, 0x4c, 0xee, 0x45, +0x45, 0xec, 0x3e, 0x3f, 0xeb, 0x38, 0x38, 0xbb, +0x43, 0x45, 0xf0, 0x52, 0x52, 0xef, 0x4b, 0x4b, +0xed, 0x44, 0x45, 0xeb, 0x37, 0x37, 0xea, 0x31, +0x31, 0xe9, 0x2b, 0x2b, 0xf0, 0x51, 0x51, 0xee, +0x4a, 0x4a, 0xed, 0x43, 0x44, 0x99, 0x43, 0x4a, +0xe9, 0x2a, 0x2b, 0xe8, 0x25, 0x25, 0xe7, 0x20, +0x20, 0xed, 0x42, 0x43, 0xc4, 0x46, 0x4a, 0x67, +0x83, 0x92, 0x99, 0x44, 0x4b, 0xe7, 0x1f, 0x20, +0x83, 0x6c, 0x7c, 0xef, 0x86, 0x87, 0x1f, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x9f, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0xad, 0x8d, 0xe5, 0x12, 0x82, +0x50, 0x14, 0x84, 0x2f, 0x88, 0x82, 0xac, 0x89, +0xdd, 0x8a, 0xdd, 0x1d, 0xd8, 0xdd, 0x1d, 0xef, +0xff, 0x2a, 0x72, 0x45, 0xc6, 0x17, 0x70, 0x7f, +0x9c, 0x99, 0xfd, 0xce, 0xce, 0x2e, 0x21, 0x7f, +0x11, 0xc3, 0x1a, 0x38, 0xa3, 0xe9, 0xe7, 0x79, +0x81, 0x33, 0x8b, 0xb0, 0x10, 0x62, 0xb5, 0xc1, +0x4e, 0xff, 0x82, 0xc3, 0x29, 0xc1, 0x05, 0xb7, +0xc7, 0x0b, 0x1f, 0x25, 0xac, 0x3f, 0x10, 0x44, +0x28, 0x1c, 0x41, 0x14, 0xb1, 0x78, 0x02, 0x14, +0xc8, 0x49, 0x09, 0xa9, 0x74, 0x06, 0xd9, 0x5c, +0x9e, 0x26, 0x18, 0x41, 0x2e, 0x14, 0x45, 0x94, +0xca, 0x95, 0x6a, 0xed, 0xd3, 0x41, 0xf8, 0x7a, +0xa3, 0xd9, 0x6a, 0xa3, 0xd3, 0xed, 0x41, 0xf9, +0xce, 0xf6, 0x07, 0x43, 0x8c, 0xc6, 0x93, 0xe9, +0x4c, 0x4b, 0xa8, 0x9a, 0x63, 0xb1, 0x5c, 0x61, +0xbd, 0xd9, 0xea, 0x04, 0xbb, 0xfd, 0x01, 0x47, +0x9c, 0xce, 0x17, 0x68, 0x40, 0xc2, 0x15, 0xb7, +0xfb, 0x03, 0x4f, 0x3d, 0xf1, 0x52, 0x68, 0x9f, +0x7a, 0x55, 0xff, 0x06, 0x83, 0xde, 0x11, 0x90, +0x83, 0x8e, 0xca, 0x44, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x31, 0x2d, 0x30, 0x33, 0x2d, +0x30, 0x38, 0x54, 0x31, 0x32, 0x3a, 0x31, 0x37, +0x3a, 0x30, 0x39, 0x2b, 0x30, 0x36, 0x3a, 0x30, +0x30, 0xd3, 0xe6, 0xa8, 0x62, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x31, 0x2d, 0x30, 0x33, +0x2d, 0x30, 0x38, 0x54, 0x31, 0x32, 0x3a, 0x31, +0x37, 0x3a, 0x30, 0x39, 0x2b, 0x30, 0x36, 0x3a, +0x30, 0x30, 0xa2, 0xbb, 0x10, 0xde, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *foreignkeybad_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_foreignkeybad_png = new wxImage(); + if (!img_foreignkeybad_png || !img_foreignkeybad_png->IsOk()) + { + wxMemoryInputStream img_foreignkeybad_pngIS(foreignkeybad_png_data, sizeof(foreignkeybad_png_data)); + img_foreignkeybad_png->LoadFile(img_foreignkeybad_pngIS, wxBITMAP_TYPE_PNG); + } + return img_foreignkeybad_png; +} +#define foreignkeybad_png_img foreignkeybad_png_img() + +static wxBitmap *foreignkeybad_png_bmp() +{ + static wxBitmap *bmp_foreignkeybad_png; + if (!bmp_foreignkeybad_png || !bmp_foreignkeybad_png->IsOk()) + bmp_foreignkeybad_png = new wxBitmap(*foreignkeybad_png_img); + return bmp_foreignkeybad_png; +} +#define foreignkeybad_png_bmp foreignkeybad_png_bmp() + +static wxIcon *foreignkeybad_png_ico() +{ + static wxIcon *ico_foreignkeybad_png; + if (!ico_foreignkeybad_png || !ico_foreignkeybad_png->IsOk()) + { + ico_foreignkeybad_png = new wxIcon(); + ico_foreignkeybad_png->CopyFromBitmap(*foreignkeybad_png_bmp); + } + return ico_foreignkeybad_png; +} +#define foreignkeybad_png_ico foreignkeybad_png_ico() + +#endif // FOREIGNKEYBAD_PNG_H diff --git a/include/images/foreignserver-sm.png b/include/images/foreignserver-sm.png new file mode 100644 index 0000000000000000000000000000000000000000..2467ccf1422a59a7218fd0bb19c2a42bdf52e5d7 GIT binary patch literal 423 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}QGic~E0BJDv+cp5$Qv6qzrVk7 zW3&9@vzBik`G5Ho|K-)uTicc2-1GkNGyU0x%oo?3fBedPak1gnHlr`^;(z|izO~Kb z%lm|1zjI$+bN~H2|Mm{mcMpR9{3*J*S>f3^`;Si}e|^pQ`={jETDdE$#Qyy)dv><$ z|KAGswyocQwlbCk`2{mLJiCzwvL>2>S4={E+nQaGTe!Vz zahdU=*X&ESFOpJE*&;e)`qd3*DpaT5u9JDLS%3P((k)@7VQ?e2h_me>FVdQ&MBb@04%Yw7ytkO literal 0 HcmV?d00001 diff --git a/include/images/foreignserver-sm.pngc b/include/images/foreignserver-sm.pngc new file mode 100644 index 0000000..6fab220 --- /dev/null +++ b/include/images/foreignserver-sm.pngc @@ -0,0 +1,97 @@ +#ifndef FOREIGNSERVER_SM_PNG_H +#define FOREIGNSERVER_SM_PNG_H + +static const unsigned char foreignserver_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x72, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xeb, 0xd9, 0x86, 0xe0, +0xc2, 0x59, 0xd8, 0xb1, 0x29, 0xf7, 0xef, 0xd4, +0xd8, 0xb3, 0x1f, 0xe3, 0xcd, 0x39, 0xed, 0xe2, +0x4f, 0xf4, 0xf2, 0x5f, 0xf4, 0xea, 0xc5, 0xda, +0xb7, 0x23, 0xec, 0xde, 0x4b, 0xf8, 0xf9, 0x67, +0xe6, 0xd0, 0x69, 0xe8, 0xd6, 0x43, 0xf8, 0xfa, +0x69, 0xe8, 0xd1, 0x80, 0xda, 0xb6, 0x32, 0xf4, +0xee, 0x5f, 0xf9, 0xfa, 0x6b, 0xda, 0xb6, 0x38, +0xf4, 0xef, 0x60, 0xfa, 0xfb, 0x6d, 0xe9, 0xd6, +0x47, 0xfb, 0xfb, 0x6f, 0xdb, 0xb8, 0x25, 0xee, +0xe0, 0x53, 0xfc, 0xfc, 0x72, 0xd9, 0xb3, 0x20, +0xe6, 0xce, 0x3f, 0xf1, 0xe5, 0x59, 0xfa, 0xf5, +0x6c, 0xfd, 0xfc, 0x74, 0xd6, 0xad, 0x1e, 0xd4, +0xaa, 0x16, 0xfe, 0xfd, 0x76, 0xe6, 0xcd, 0x76, +0xff, 0xfd, 0x78, 0x07, 0x86, 0xb5, 0xf6, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x6c, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x8d, 0x8f, 0x49, 0x0e, 0x80, +0x20, 0x10, 0x04, 0x47, 0x14, 0x5c, 0x50, 0xdc, +0x77, 0xdc, 0x40, 0xff, 0xff, 0x45, 0x13, 0x98, +0x18, 0xb9, 0x51, 0xb7, 0xae, 0xa4, 0x33, 0x3d, +0x00, 0x7e, 0x04, 0x24, 0x0c, 0x09, 0x44, 0x5f, +0xa6, 0x2c, 0x4e, 0x92, 0x98, 0xd1, 0x14, 0x73, +0xc6, 0x73, 0x03, 0xcf, 0x6c, 0x2e, 0x44, 0x89, +0x88, 0xca, 0x88, 0xba, 0x69, 0x91, 0xa6, 0x33, +0xa2, 0xeb, 0x07, 0xa4, 0xb7, 0xa2, 0x1a, 0x27, +0x64, 0xb4, 0x15, 0x98, 0x97, 0xd5, 0xb0, 0xcc, +0x78, 0x25, 0x95, 0xdb, 0x7e, 0x1c, 0xe7, 0x29, +0x7f, 0xcb, 0xc8, 0xa5, 0xb4, 0x56, 0xce, 0xd8, +0x5b, 0x3d, 0xae, 0x00, 0x50, 0xb7, 0xdf, 0x9f, +0x2f, 0xe4, 0x0e, 0x07, 0xe3, 0xd8, 0x9f, 0xd2, +0x10, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x31, 0x2d, 0x30, 0x33, 0x2d, 0x30, 0x38, 0x54, +0x31, 0x32, 0x3a, 0x31, 0x37, 0x3a, 0x30, 0x39, +0x2b, 0x30, 0x36, 0x3a, 0x30, 0x30, 0xd3, 0xe6, +0xa8, 0x62, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x31, 0x2d, 0x30, 0x33, 0x2d, 0x30, 0x38, +0x54, 0x31, 0x32, 0x3a, 0x31, 0x37, 0x3a, 0x30, +0x39, 0x2b, 0x30, 0x36, 0x3a, 0x30, 0x30, 0xa2, +0xbb, 0x10, 0xde, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *foreignserver_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_foreignserver_sm_png = new wxImage(); + if (!img_foreignserver_sm_png || !img_foreignserver_sm_png->IsOk()) + { + wxMemoryInputStream img_foreignserver_sm_pngIS(foreignserver_sm_png_data, sizeof(foreignserver_sm_png_data)); + img_foreignserver_sm_png->LoadFile(img_foreignserver_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_foreignserver_sm_png; +} +#define foreignserver_sm_png_img foreignserver_sm_png_img() + +static wxBitmap *foreignserver_sm_png_bmp() +{ + static wxBitmap *bmp_foreignserver_sm_png; + if (!bmp_foreignserver_sm_png || !bmp_foreignserver_sm_png->IsOk()) + bmp_foreignserver_sm_png = new wxBitmap(*foreignserver_sm_png_img); + return bmp_foreignserver_sm_png; +} +#define foreignserver_sm_png_bmp foreignserver_sm_png_bmp() + +static wxIcon *foreignserver_sm_png_ico() +{ + static wxIcon *ico_foreignserver_sm_png; + if (!ico_foreignserver_sm_png || !ico_foreignserver_sm_png->IsOk()) + { + ico_foreignserver_sm_png = new wxIcon(); + ico_foreignserver_sm_png->CopyFromBitmap(*foreignserver_sm_png_bmp); + } + return ico_foreignserver_sm_png; +} +#define foreignserver_sm_png_ico foreignserver_sm_png_ico() + +#endif // FOREIGNSERVER_SM_PNG_H diff --git a/include/images/foreignserver.png b/include/images/foreignserver.png new file mode 100644 index 0000000000000000000000000000000000000000..dda392a2280c994f48d89e3ed67bbfcbe14ba045 GIT binary patch literal 518 zcmV+h0{Q)kP)Px#&rnQMMX->YgKT`3fsg9n=i=4g*~!(=z01b2z`v%siE@IOhLgCcv+3XE*vZt- zy~@9+xSfQS+tJwS-{#`g-Os+tu$QUO#mn;X^7;7r_3`rh`TFtg@8sLx@b2&S_4eS? z*Tk!}w3VU6t+wy(?)UZf#H+Njkewf6P(;ndi~uDI{+@58FIvXGs`t+&U<$Kcf1 zqKuTamZPDLmd(t}k#&HymZ8I~wydJ3@b2)su(W%Wq)V8njH|fe)Y+kolv<*+AKJ%K zq_by(l3S&=Pb(w<00001bW%=J06^y0W&i*H0b)x>L;#2d9Y_EG010qNS#tmY3ljhU z3ljkVnw%H_000McNliru+XEdH1{&ZijJW^+0HaAnK~xyiMUK4=!Y~Yk8z{7t76^Ya z5NM?^ATeagkRWBT{Ql2Gs~`$KoE z>eI9&&I&GYz3D%=KlIsOk()) + { + wxMemoryInputStream img_foreignserver_pngIS(foreignserver_png_data, sizeof(foreignserver_png_data)); + img_foreignserver_png->LoadFile(img_foreignserver_pngIS, wxBITMAP_TYPE_PNG); + } + return img_foreignserver_png; +} +#define foreignserver_png_img foreignserver_png_img() + +static wxBitmap *foreignserver_png_bmp() +{ + static wxBitmap *bmp_foreignserver_png; + if (!bmp_foreignserver_png || !bmp_foreignserver_png->IsOk()) + bmp_foreignserver_png = new wxBitmap(*foreignserver_png_img); + return bmp_foreignserver_png; +} +#define foreignserver_png_bmp foreignserver_png_bmp() + +static wxIcon *foreignserver_png_ico() +{ + static wxIcon *ico_foreignserver_png; + if (!ico_foreignserver_png || !ico_foreignserver_png->IsOk()) + { + ico_foreignserver_png = new wxIcon(); + ico_foreignserver_png->CopyFromBitmap(*foreignserver_png_bmp); + } + return ico_foreignserver_png; +} +#define foreignserver_png_ico foreignserver_png_ico() + +#endif // FOREIGNSERVER_PNG_H diff --git a/include/images/foreignservers.png b/include/images/foreignservers.png new file mode 100644 index 0000000000000000000000000000000000000000..c1071768f4d2ed9797585b8725bfce1d3dbfafab GIT binary patch literal 476 zcmV<20VDp2P)Px#u~1A@MSGN_gKT`3fsg9n=i=4g*~!(=z01b2z`v%siE@IOhLgCcv+3XE*vZt- zy~@9+xSfQS+tJwS-{#`g-Os+tu$QUO#mn;X^7;7r_3`rh`TFtg@8sLx@b2&S_4eS? z*Tk!}T%@*)tGMs(?)UZf#H+MhptB#^$78X8t@QEo;ndi}s!aedF2ZD=|Nk^wNyodpXOfdtRf^G6C5vUfS~u;c z^sXQ3?XKA$ItAuUtf+&cek(eY9^AAkZ!~tFaSanc< zFu{AMgHmU4B5npOxx+;-vxA42rQ)LK!~moV1V?2hJ2;zWU_IsOk()) + { + wxMemoryInputStream img_foreignservers_pngIS(foreignservers_png_data, sizeof(foreignservers_png_data)); + img_foreignservers_png->LoadFile(img_foreignservers_pngIS, wxBITMAP_TYPE_PNG); + } + return img_foreignservers_png; +} +#define foreignservers_png_img foreignservers_png_img() + +static wxBitmap *foreignservers_png_bmp() +{ + static wxBitmap *bmp_foreignservers_png; + if (!bmp_foreignservers_png || !bmp_foreignservers_png->IsOk()) + bmp_foreignservers_png = new wxBitmap(*foreignservers_png_img); + return bmp_foreignservers_png; +} +#define foreignservers_png_bmp foreignservers_png_bmp() + +static wxIcon *foreignservers_png_ico() +{ + static wxIcon *ico_foreignservers_png; + if (!ico_foreignservers_png || !ico_foreignservers_png->IsOk()) + { + ico_foreignservers_png = new wxIcon(); + ico_foreignservers_png->CopyFromBitmap(*foreignservers_png_bmp); + } + return ico_foreignservers_png; +} +#define foreignservers_png_ico foreignservers_png_ico() + +#endif // FOREIGNSERVERS_PNG_H diff --git a/include/images/foreigntable.png b/include/images/foreigntable.png new file mode 100644 index 0000000000000000000000000000000000000000..53c133885a0c0c7050e4c8580adfd75f8ceaa852 GIT binary patch literal 563 zcmV-30?hr1P)Px#)lf`SMdakzW8Cd_Exg@A$?CYb4k%>8S=_(7)bHlge;oa(gJ z?%mzp-rnBd-{0Wi;Njun;^N}tFMX^=c%cwtgNi;?CkCB?eFjJ z>gwvJr>Cf>sI9H7udlD`>+A6F@bdEV?(XiZtE;fEu(7eRva+)A@$vKX^Y!)hwY9bO z_V)Pr__nsTxVX6Y_xDt#KRo~d00DGTPE!Ct=GbNc0004EOGiWihy@);00009a7bBm z000XU000XU0RWnu7ytkO2XskIMF-mh92F=elJWmr0002WNklIsOk()) + { + wxMemoryInputStream img_foreigntable_pngIS(foreigntable_png_data, sizeof(foreigntable_png_data)); + img_foreigntable_png->LoadFile(img_foreigntable_pngIS, wxBITMAP_TYPE_PNG); + } + return img_foreigntable_png; +} +#define foreigntable_png_img foreigntable_png_img() + +static wxBitmap *foreigntable_png_bmp() +{ + static wxBitmap *bmp_foreigntable_png; + if (!bmp_foreigntable_png || !bmp_foreigntable_png->IsOk()) + bmp_foreigntable_png = new wxBitmap(*foreigntable_png_img); + return bmp_foreigntable_png; +} +#define foreigntable_png_bmp foreigntable_png_bmp() + +static wxIcon *foreigntable_png_ico() +{ + static wxIcon *ico_foreigntable_png; + if (!ico_foreigntable_png || !ico_foreigntable_png->IsOk()) + { + ico_foreigntable_png = new wxIcon(); + ico_foreigntable_png->CopyFromBitmap(*foreigntable_png_bmp); + } + return ico_foreigntable_png; +} +#define foreigntable_png_ico foreigntable_png_ico() + +#endif // FOREIGNTABLE_PNG_H diff --git a/include/images/foreigntables.png b/include/images/foreigntables.png new file mode 100644 index 0000000000000000000000000000000000000000..dc1f742bbca05980f3c4cbf3c16af0e0cf9afa41 GIT binary patch literal 492 zcmVPx#x=>71MPs@4A(iKf&i<6o`K{IR%G~PS>E7PngUkI&tMEOf?I@Y)-{0Tj;^O1u zv~3?Ck9B?(XU7>EYqwrlzK-sHm;2t*@`I>gwu{%Jb*v=j-e1 z=;-LFsj2Vp@A2{R?d|QVs;aQCu(GnUIsOk()) + { + wxMemoryInputStream img_foreigntables_pngIS(foreigntables_png_data, sizeof(foreigntables_png_data)); + img_foreigntables_png->LoadFile(img_foreigntables_pngIS, wxBITMAP_TYPE_PNG); + } + return img_foreigntables_png; +} +#define foreigntables_png_img foreigntables_png_img() + +static wxBitmap *foreigntables_png_bmp() +{ + static wxBitmap *bmp_foreigntables_png; + if (!bmp_foreigntables_png || !bmp_foreigntables_png->IsOk()) + bmp_foreigntables_png = new wxBitmap(*foreigntables_png_img); + return bmp_foreigntables_png; +} +#define foreigntables_png_bmp foreigntables_png_bmp() + +static wxIcon *foreigntables_png_ico() +{ + static wxIcon *ico_foreigntables_png; + if (!ico_foreigntables_png || !ico_foreigntables_png->IsOk()) + { + ico_foreigntables_png = new wxIcon(); + ico_foreigntables_png->CopyFromBitmap(*foreigntables_png_bmp); + } + return ico_foreigntables_png; +} +#define foreigntables_png_ico foreigntables_png_ico() + +#endif // FOREIGNTABLES_PNG_H diff --git a/include/images/forward.png b/include/images/forward.png new file mode 100644 index 0000000000000000000000000000000000000000..3b22d70ae8069f20f73d94ca1ec011e30ba7bf85 GIT binary patch literal 352 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaN3?zjj6;1;wxd5LK*K3#0G5lv>XlikqwUnWW z!SMf_bLamvm{_(nwHO*COS|6Q160Xb;1O92q&>jc?PRtckkRJp;us=vIXU3~cMH!1 zi>7lPb1sOetlVIrvhqTR%1VQlDGL^4WMy?RhXiT_sQIuS^JHyOVb@R>P!yHY($Lb< zc)?cptAuDUumo!Wsy4AQFoS3~H9d3< PPy>UftDnm{r-UW|7%y(b literal 0 HcmV?d00001 diff --git a/include/images/forward.pngc b/include/images/forward.pngc new file mode 100644 index 0000000..34760f6 --- /dev/null +++ b/include/images/forward.pngc @@ -0,0 +1,88 @@ +#ifndef FORWARD_PNG_H +#define FORWARD_PNG_H + +static const unsigned char forward_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, +0x04, 0x03, 0x00, 0x00, 0x00, 0x12, 0x59, 0x20, +0xcb, 0x00, 0x00, 0x00, 0x1e, 0x50, 0x4c, 0x54, +0x45, 0xd6, 0xd3, 0xce, 0x00, 0xff, 0x00, 0x00, +0x82, 0x84, 0x42, 0x9a, 0xa5, 0x00, 0x82, 0x00, +0x31, 0xff, 0x9c, 0xce, 0xcf, 0xff, 0x00, 0x34, +0x39, 0x84, 0x82, 0x84, 0x31, 0x30, 0x63, 0x1b, +0x45, 0xdb, 0xbc, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x86, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0x60, 0xc0, 0x0b, 0x84, 0x0c, +0x90, 0x38, 0x82, 0xce, 0x48, 0x9c, 0xd0, 0x14, +0x24, 0xa9, 0xb0, 0x30, 0x24, 0xa9, 0xd0, 0x54, +0x24, 0xa9, 0x30, 0x84, 0x94, 0xa0, 0xa0, 0x68, +0x6a, 0x6a, 0x8a, 0x03, 0x54, 0x51, 0x28, 0x50, +0x26, 0x4c, 0x05, 0xc6, 0x49, 0x05, 0x82, 0x24, +0x07, 0x28, 0x27, 0x10, 0x21, 0x15, 0x1a, 0x2a, +0x28, 0x2a, 0x2a, 0x28, 0xe8, 0x04, 0x31, 0xcb, +0x18, 0x04, 0xcc, 0x8b, 0x20, 0x32, 0xce, 0xce, +0x2e, 0x2e, 0x2e, 0xe5, 0x0a, 0x60, 0x8e, 0x98, +0x89, 0x89, 0x8b, 0x8b, 0x7b, 0x11, 0xcc, 0x99, +0xce, 0x70, 0x09, 0x06, 0xf7, 0xf2, 0x62, 0xa0, +0x44, 0x47, 0x47, 0x47, 0x03, 0x98, 0xeb, 0xec, +0x52, 0xa9, 0x01, 0xe4, 0x80, 0x98, 0x1c, 0x1d, +0xce, 0xee, 0x93, 0x60, 0xe2, 0x0c, 0x1d, 0x20, +0x09, 0x98, 0xa3, 0x39, 0xda, 0x27, 0x31, 0x10, +0x00, 0x00, 0xb9, 0x91, 0x24, 0x76, 0xe1, 0x57, +0x5f, 0x47, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, +0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *forward_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_forward_png = new wxImage(); + if (!img_forward_png || !img_forward_png->IsOk()) + { + wxMemoryInputStream img_forward_pngIS(forward_png_data, sizeof(forward_png_data)); + img_forward_png->LoadFile(img_forward_pngIS, wxBITMAP_TYPE_PNG); + } + return img_forward_png; +} +#define forward_png_img forward_png_img() + +static wxBitmap *forward_png_bmp() +{ + static wxBitmap *bmp_forward_png; + if (!bmp_forward_png || !bmp_forward_png->IsOk()) + bmp_forward_png = new wxBitmap(*forward_png_img); + return bmp_forward_png; +} +#define forward_png_bmp forward_png_bmp() + +static wxIcon *forward_png_ico() +{ + static wxIcon *ico_forward_png; + if (!ico_forward_png || !ico_forward_png->IsOk()) + { + ico_forward_png = new wxIcon(); + ico_forward_png->CopyFromBitmap(*forward_png_bmp); + } + return ico_forward_png; +} +#define forward_png_ico forward_png_ico() + +#endif // FORWARD_PNG_H diff --git a/include/images/function.png b/include/images/function.png new file mode 100644 index 0000000000000000000000000000000000000000..656854a0191b5dd5d465f90cfbceebdc3913f1a2 GIT binary patch literal 325 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPHF3h)VW1=3U3Jn||!yY$MRhadm{ z{r~UY=bu~de4cgqZS9ih={*lqIv$kGe$v0=Wy+ox+kmPWOM?7@862M7NCR>>3p^r= zfwTu0yPeFo12TdIsOk()) + { + wxMemoryInputStream img_function_pngIS(function_png_data, sizeof(function_png_data)); + img_function_png->LoadFile(img_function_pngIS, wxBITMAP_TYPE_PNG); + } + return img_function_png; +} +#define function_png_img function_png_img() + +static wxBitmap *function_png_bmp() +{ + static wxBitmap *bmp_function_png; + if (!bmp_function_png || !bmp_function_png->IsOk()) + bmp_function_png = new wxBitmap(*function_png_img); + return bmp_function_png; +} +#define function_png_bmp function_png_bmp() + +static wxIcon *function_png_ico() +{ + static wxIcon *ico_function_png; + if (!ico_function_png || !ico_function_png->IsOk()) + { + ico_function_png = new wxIcon(); + ico_function_png->CopyFromBitmap(*function_png_bmp); + } + return ico_function_png; +} +#define function_png_ico function_png_ico() + +#endif // FUNCTION_PNG_H diff --git a/include/images/functions.png b/include/images/functions.png new file mode 100644 index 0000000000000000000000000000000000000000..c44874e5574e624c2687689ac75f3ba4ed69e811 GIT binary patch literal 349 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!aez;VE0CVL=8;#?*`-(h^sRi9 z*>&~c)34PF?}pc0oO}FT&eYpg3!lCJ{{QpuKPl}Gawb0N+VtXry&)e^8)He3UoeBi zvm0qZ4rhT!WHFHT0Ash4*>*riqNj^vh{WaCes{hD1{^FOt?qvPzrI(~vFzEgEEaCT zKn8&fCc|T@oHyDw|30!InX~Vp=DDQ@|E}SiWNDf1d5o{vOS9^Kd7b7@Arcm|Gc`Y8#kY85l5Do_~mzopr06KSqcmMzZ literal 0 HcmV?d00001 diff --git a/include/images/functions.pngc b/include/images/functions.pngc new file mode 100644 index 0000000..c9b22a2 --- /dev/null +++ b/include/images/functions.pngc @@ -0,0 +1,88 @@ +#ifndef FUNCTIONS_PNG_H +#define FUNCTIONS_PNG_H + +static const unsigned char functions_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x33, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x95, 0xac, 0xe2, 0x4a, +0x72, 0xcd, 0xa5, 0xd4, 0xfc, 0x8e, 0xa9, 0xe2, +0x69, 0x8a, 0xd5, 0xc1, 0xe5, 0xf5, 0x7b, 0xa1, +0xdd, 0x57, 0x7c, 0xd1, 0x9d, 0xc7, 0xee, 0x6c, +0x95, 0xdb, 0x7a, 0xa1, 0xe6, 0xef, 0xf7, 0xff, +0xf3, 0xfb, 0xfc, 0x64, 0x87, 0xe0, 0x6c, 0x91, +0xe2, 0x8a, 0xb2, 0xe8, 0xd0, 0x3f, 0x31, 0x0e, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x61, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x5d, 0x8f, 0x47, 0x0e, +0xc0, 0x30, 0x08, 0x04, 0xf1, 0x3a, 0xdd, 0xf5, +0xff, 0xaf, 0x8d, 0x29, 0x41, 0x76, 0xe6, 0xc6, +0x6a, 0x04, 0x0b, 0x11, 0x51, 0x00, 0x10, 0x68, +0x02, 0x31, 0xc6, 0x25, 0x09, 0xd8, 0x86, 0xb3, +0xfb, 0xc4, 0xb0, 0x63, 0x09, 0x8e, 0xc1, 0x29, +0xce, 0xa5, 0xc1, 0xfd, 0xac, 0x0e, 0x92, 0x39, +0x39, 0x67, 0x49, 0xc6, 0x0e, 0x73, 0x4a, 0x29, +0x7a, 0xcb, 0x1c, 0x41, 0x12, 0x76, 0x1c, 0xe8, +0xe5, 0xf4, 0x61, 0xfd, 0xb4, 0x4b, 0xad, 0xd5, +0xfb, 0x72, 0xd2, 0x5a, 0x9b, 0xfb, 0xa3, 0xf7, +0xfe, 0xfb, 0xe7, 0xf7, 0xb1, 0xf3, 0x02, 0x84, +0x99, 0x03, 0x0d, 0xf0, 0xed, 0x6f, 0x7b, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x31, 0x2d, +0x30, 0x31, 0x2d, 0x32, 0x35, 0x54, 0x31, 0x35, +0x3a, 0x30, 0x37, 0x3a, 0x30, 0x35, 0x2b, 0x30, +0x36, 0x3a, 0x30, 0x30, 0x01, 0x79, 0xcf, 0xe1, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *functions_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_functions_png = new wxImage(); + if (!img_functions_png || !img_functions_png->IsOk()) + { + wxMemoryInputStream img_functions_pngIS(functions_png_data, sizeof(functions_png_data)); + img_functions_png->LoadFile(img_functions_pngIS, wxBITMAP_TYPE_PNG); + } + return img_functions_png; +} +#define functions_png_img functions_png_img() + +static wxBitmap *functions_png_bmp() +{ + static wxBitmap *bmp_functions_png; + if (!bmp_functions_png || !bmp_functions_png->IsOk()) + bmp_functions_png = new wxBitmap(*functions_png_img); + return bmp_functions_png; +} +#define functions_png_bmp functions_png_bmp() + +static wxIcon *functions_png_ico() +{ + static wxIcon *ico_functions_png; + if (!ico_functions_png || !ico_functions_png->IsOk()) + { + ico_functions_png = new wxIcon(); + ico_functions_png->CopyFromBitmap(*functions_png_bmp); + } + return ico_functions_png; +} +#define functions_png_ico functions_png_ico() + +#endif // FUNCTIONS_PNG_H diff --git a/include/images/gqbAdd.png b/include/images/gqbAdd.png new file mode 100644 index 0000000000000000000000000000000000000000..620e7d8925909444b4ae3a7f594f2467011176b3 GIT binary patch literal 228 zcmeAS@N?(olHy`uVBq!ia0vp^!a&T=$P6THy3+E26kC8#h%1oxih2A!UBDU0Vk`;r z3ubV5b|VeQ;VkfoEC$jZVC;4>+YZPO^>lFz;kcfh(9p=gV#a@arp2cn85tZ>xK>w1 z&GZE-P%UwdC`m~yNwrEYN(E93Mh1okx`sx&28JO<2397IsOk()) + { + wxMemoryInputStream img_gqbAdd_pngIS(gqbAdd_png_data, sizeof(gqbAdd_png_data)); + img_gqbAdd_png->LoadFile(img_gqbAdd_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbAdd_png; +} +#define gqbAdd_png_img gqbAdd_png_img() + +static wxBitmap *gqbAdd_png_bmp() +{ + static wxBitmap *bmp_gqbAdd_png; + if (!bmp_gqbAdd_png || !bmp_gqbAdd_png->IsOk()) + bmp_gqbAdd_png = new wxBitmap(*gqbAdd_png_img); + return bmp_gqbAdd_png; +} +#define gqbAdd_png_bmp gqbAdd_png_bmp() + +static wxIcon *gqbAdd_png_ico() +{ + static wxIcon *ico_gqbAdd_png; + if (!ico_gqbAdd_png || !ico_gqbAdd_png->IsOk()) + { + ico_gqbAdd_png = new wxIcon(); + ico_gqbAdd_png->CopyFromBitmap(*gqbAdd_png_bmp); + } + return ico_gqbAdd_png; +} +#define gqbAdd_png_ico gqbAdd_png_ico() + +#endif // GQBADD_PNG_H diff --git a/include/images/gqbAddRest.png b/include/images/gqbAddRest.png new file mode 100644 index 0000000000000000000000000000000000000000..55f47029b6e480c5e59d700bd76eda987a278dca GIT binary patch literal 533 zcmeAS@N?(olHy`uVBq!ia0vp^!a&T=!3-n~XR*iusTBb}A+A7r>h!G@Ra***x9r?? zv$1*ahmW5>Jp2Fj#_zkAzuY|g>GH`p7Y@BSx##)OJr7?!|6I_qB*VRXF9r8L{+WYz5Ma=6)W@e^Or1JxqAAIzTy+{ z&u&LQy55?7DE!{#!&@H)-#R~c(em2lJ$_eDd0sf`dgh?R@jbiO-p&u*U~_oKwiVZB zEm*dG(WNI(o~&MbS!R7`2GFgHB|(0{3=Yq3qyagc1s;*bK-vS0-A-oP0U1j?T^vIs zE{FEt7HbR;a8N(KaJHV1lh4v15yij%=g(Xr{5w(Z+br8`UJvDO=Or5aml-Wwv1-|C zV`pQ_hNG#~?{s3ycScpuUVAW;zbs~B{SUanIt_lSe)n4`u+3$jpS@7Ll1(o8 zjqKe!?w%(M{n**xObO`7bW;|8=aV=qw(HZa^_!ww=kDVEzJlpg*Q8^c%hO`_OYkXP z+;ZRCqNVAN^ghNORiTKIO)l?&?o};ujVMV;EJ?LWE=mPb3`Pcq2D*kux(0?JMg~?U z##Sb#+6Jap1_txq>8(Q1kei>9nN|tWU|090*aWnc!;aB6z!8lVOSPgg&ebxsLQ E09DlOZvX%Q literal 0 HcmV?d00001 diff --git a/include/images/gqbAddRest.pngc b/include/images/gqbAddRest.pngc new file mode 100644 index 0000000..4dd225c --- /dev/null +++ b/include/images/gqbAddRest.pngc @@ -0,0 +1,111 @@ +#ifndef GQBADDREST_PNG_H +#define GQBADDREST_PNG_H + +static const unsigned char gqbAddRest_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0f, +0x08, 0x03, 0x00, 0x00, 0x00, 0x31, 0x9a, 0x04, +0x1e, 0x00, 0x00, 0x00, 0xa8, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x95, 0x97, 0xb5, 0x78, +0x7a, 0xb4, 0x70, 0x73, 0xb4, 0xb9, 0xba, 0xd9, +0x81, 0x83, 0xbd, 0xf0, 0xf1, 0xf3, 0xf0, 0xe6, +0xff, 0xe5, 0xd8, 0xfb, 0xdd, 0xd3, 0xf4, 0xd9, +0xcd, 0xf2, 0xd3, 0xc9, 0xec, 0xd0, 0xc2, 0xec, +0xc9, 0xbc, 0xe7, 0xc5, 0xbc, 0xe1, 0xea, 0xe7, +0xf3, 0x70, 0x88, 0xb4, 0xd5, 0xbd, 0xfa, 0xcd, +0xb1, 0xf9, 0xc6, 0xaf, 0xee, 0xc3, 0xa7, 0xf2, +0xb7, 0x9c, 0xe8, 0xad, 0x92, 0xe1, 0xa6, 0x8b, +0xdb, 0x9e, 0x83, 0xd5, 0x96, 0x7c, 0xce, 0x90, +0x75, 0xc9, 0x99, 0x83, 0xcc, 0x88, 0x8a, 0xa8, +0x5a, 0x7a, 0xaa, 0xbb, 0xa7, 0xe3, 0xa7, 0xa8, +0xa9, 0x6f, 0x6f, 0x6f, 0xa4, 0xa6, 0xa9, 0xab, +0x97, 0xd8, 0x8e, 0x73, 0xc8, 0x5f, 0xe6, 0xdb, +0x5b, 0xe2, 0xd7, 0x85, 0x6b, 0xc2, 0x57, 0xde, +0xd3, 0xc3, 0xb5, 0xe1, 0x53, 0xda, 0xcf, 0x9d, +0xa2, 0xa7, 0x7d, 0x63, 0xbc, 0x4e, 0xd5, 0xca, +0x49, 0xd0, 0xc5, 0x45, 0xcc, 0xc1, 0x40, 0xc7, +0xbc, 0xbb, 0xad, 0xdb, 0x6f, 0x55, 0xb0, 0x3c, +0xc3, 0xb8, 0xb6, 0xa8, 0xd7, 0x9a, 0xa0, 0xa6, +0xaf, 0xa2, 0xd2, 0xe4, 0xe4, 0xe4, 0xab, 0xad, +0xd3, 0x1c, 0xaf, 0x55, 0x68, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0xa4, 0x49, 0x44, 0x41, 0x54, 0x18, +0xd3, 0x55, 0x8f, 0xdb, 0x16, 0x81, 0x50, 0x10, +0x40, 0x27, 0xc7, 0xa1, 0x9b, 0x2e, 0x12, 0x42, +0x4c, 0xa5, 0x52, 0x14, 0x21, 0xfd, 0xff, 0x9f, +0x99, 0xa8, 0x13, 0xfb, 0x61, 0x1e, 0xf6, 0x9a, +0x3d, 0x6b, 0x0d, 0x48, 0x23, 0xf6, 0xcf, 0x18, +0x80, 0x4f, 0xa6, 0x32, 0xa1, 0xa8, 0xaa, 0xa6, +0xeb, 0x33, 0x43, 0x33, 0x39, 0x80, 0xc5, 0x65, +0x7b, 0xee, 0x2c, 0x5c, 0x77, 0xb9, 0x5a, 0x7b, +0x9b, 0xad, 0xc1, 0x69, 0x0f, 0x76, 0x5c, 0xb1, +0x7f, 0x94, 0x0f, 0x2d, 0x12, 0x57, 0x1c, 0xa1, +0x2c, 0x80, 0x4e, 0xaa, 0xfb, 0x8f, 0x3a, 0x20, +0x06, 0x9d, 0x03, 0x9f, 0x6b, 0xa1, 0x17, 0x79, +0x06, 0x1e, 0x63, 0xec, 0x1d, 0xdd, 0xdc, 0x47, +0x49, 0xc8, 0x31, 0x4e, 0x07, 0x07, 0xec, 0x94, +0x50, 0x88, 0x69, 0x46, 0x23, 0x17, 0xee, 0x4c, +0x61, 0x9a, 0x5d, 0x8a, 0xf2, 0xda, 0xaf, 0xb2, +0x5b, 0x85, 0x9d, 0xba, 0x0b, 0xf7, 0xa8, 0x02, +0xca, 0x8a, 0x92, 0xc6, 0xb3, 0x77, 0x66, 0x5d, +0xbf, 0x18, 0x0e, 0x21, 0xd1, 0xb4, 0xdf, 0x37, +0x38, 0x84, 0x82, 0xfc, 0x1b, 0xbe, 0x01, 0x8c, +0x25, 0x12, 0x58, 0x74, 0xb2, 0x44, 0xef, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *gqbAddRest_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_gqbAddRest_png = new wxImage(); + if (!img_gqbAddRest_png || !img_gqbAddRest_png->IsOk()) + { + wxMemoryInputStream img_gqbAddRest_pngIS(gqbAddRest_png_data, sizeof(gqbAddRest_png_data)); + img_gqbAddRest_png->LoadFile(img_gqbAddRest_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbAddRest_png; +} +#define gqbAddRest_png_img gqbAddRest_png_img() + +static wxBitmap *gqbAddRest_png_bmp() +{ + static wxBitmap *bmp_gqbAddRest_png; + if (!bmp_gqbAddRest_png || !bmp_gqbAddRest_png->IsOk()) + bmp_gqbAddRest_png = new wxBitmap(*gqbAddRest_png_img); + return bmp_gqbAddRest_png; +} +#define gqbAddRest_png_bmp gqbAddRest_png_bmp() + +static wxIcon *gqbAddRest_png_ico() +{ + static wxIcon *ico_gqbAddRest_png; + if (!ico_gqbAddRest_png || !ico_gqbAddRest_png->IsOk()) + { + ico_gqbAddRest_png = new wxIcon(); + ico_gqbAddRest_png->CopyFromBitmap(*gqbAddRest_png_bmp); + } + return ico_gqbAddRest_png; +} +#define gqbAddRest_png_ico gqbAddRest_png_ico() + +#endif // GQBADDREST_PNG_H diff --git a/include/images/gqbColNotSel.png b/include/images/gqbColNotSel.png new file mode 100644 index 0000000000000000000000000000000000000000..5b1abeecdd7faa7081cfcc7d81f4052c0e9ee671 GIT binary patch literal 362 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}RDe&2E0CT&dv<7O=-+?;e*gRT z^UuHUzyE#t_4m`SKY#xH`}G&d{rmOz-_O7PeE9k2$De=SK>d)IBzh8a-EhEpz0yLemB*-tA!Qt7BG$4nwz$3C4NPB>> z+sSM@Aj93$#W6(Ua&p1~ri2tGX15&-!p7X%($?(4P7Ra0XSYx1_iX5ncL?y1@N{qq z>6z{?o=I4Rj5SbPWtcj0~(yjIB&ewGB+I3=HPI(_4k2AvZrIGp!P$!N3x%0jS!<%D@bw U;neidH9!pvp00i_>zopr0DK^p*#H0l literal 0 HcmV?d00001 diff --git a/include/images/gqbColNotSel.pngc b/include/images/gqbColNotSel.pngc new file mode 100644 index 0000000..58cf3e8 --- /dev/null +++ b/include/images/gqbColNotSel.pngc @@ -0,0 +1,90 @@ +#ifndef GQBCOLNOTSEL_PNG_H +#define GQBCOLNOTSEL_PNG_H + +static const unsigned char gqbColNotSel_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x5a, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x9b, 0x9b, 0x9b, 0x55, +0x55, 0x55, 0xfd, 0xfe, 0xfe, 0xfb, 0xfe, 0xfe, +0xf9, 0xfc, 0xfe, 0xf7, 0xfb, 0xfe, 0xf4, 0xfa, +0xfd, 0xf2, 0xfa, 0xfc, 0xfc, 0xfe, 0xfe, 0xfa, +0xfd, 0xfe, 0xf7, 0xfb, 0xfd, 0xf5, 0xfb, 0xfd, +0xf3, 0xfa, 0xfc, 0xf0, 0xf9, 0xfc, 0xf8, 0xfc, +0xfe, 0xf6, 0xfb, 0xfd, 0xf3, 0xfa, 0xfd, 0xf2, +0xf9, 0xfd, 0xef, 0xf8, 0xfc, 0xf9, 0xfd, 0xfe, +0xf7, 0xfc, 0xfd, 0xf4, 0xfb, 0xfd, 0xed, 0xf7, +0xfb, 0xee, 0xf8, 0xfc, 0xec, 0xf7, 0xfb, 0xf6, +0xfc, 0xfd, 0xf2, 0xf9, 0xfc, 0xed, 0xf8, 0xfb, +0xea, 0xf7, 0xfb, 0x1c, 0x1f, 0x0e, 0x04, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x47, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x63, 0x60, 0xa0, 0x02, 0x60, +0x64, 0x02, 0x03, 0x46, 0xb8, 0x00, 0x13, 0x33, +0x0b, 0x2b, 0x1b, 0x3b, 0x07, 0x13, 0x42, 0x80, +0x93, 0x8b, 0x9b, 0x87, 0x97, 0x0f, 0x49, 0x80, +0x8b, 0x5f, 0x40, 0x50, 0x48, 0x18, 0x49, 0x40, +0x44, 0x54, 0x8c, 0x97, 0x4f, 0x1c, 0x49, 0x80, +0x9f, 0x47, 0x90, 0x4f, 0x42, 0x12, 0x49, 0x40, +0x8a, 0x5d, 0x5a, 0x58, 0x46, 0x96, 0x09, 0xb7, +0xb5, 0x54, 0x00, 0x00, 0x35, 0xfc, 0x02, 0x5e, +0x0d, 0x87, 0x6c, 0x90, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *gqbColNotSel_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_gqbColNotSel_png = new wxImage(); + if (!img_gqbColNotSel_png || !img_gqbColNotSel_png->IsOk()) + { + wxMemoryInputStream img_gqbColNotSel_pngIS(gqbColNotSel_png_data, sizeof(gqbColNotSel_png_data)); + img_gqbColNotSel_png->LoadFile(img_gqbColNotSel_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbColNotSel_png; +} +#define gqbColNotSel_png_img gqbColNotSel_png_img() + +static wxBitmap *gqbColNotSel_png_bmp() +{ + static wxBitmap *bmp_gqbColNotSel_png; + if (!bmp_gqbColNotSel_png || !bmp_gqbColNotSel_png->IsOk()) + bmp_gqbColNotSel_png = new wxBitmap(*gqbColNotSel_png_img); + return bmp_gqbColNotSel_png; +} +#define gqbColNotSel_png_bmp gqbColNotSel_png_bmp() + +static wxIcon *gqbColNotSel_png_ico() +{ + static wxIcon *ico_gqbColNotSel_png; + if (!ico_gqbColNotSel_png || !ico_gqbColNotSel_png->IsOk()) + { + ico_gqbColNotSel_png = new wxIcon(); + ico_gqbColNotSel_png->CopyFromBitmap(*gqbColNotSel_png_bmp); + } + return ico_gqbColNotSel_png; +} +#define gqbColNotSel_png_ico gqbColNotSel_png_ico() + +#endif // GQBCOLNOTSEL_PNG_H diff --git a/include/images/gqbColSel.png b/include/images/gqbColSel.png new file mode 100644 index 0000000000000000000000000000000000000000..7e9c811e15796cc02efc9e941e39bf8c25b8e507 GIT binary patch literal 408 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}OMp*^E0CT&dv<7O=-+?;e*gRT z^UuHUzyE#w_VdlRU*X~5fByaZ^%p4e_v6n$_cm?0v20CTbj;7+f8Jia{Py|FM`zBS zO-#Nxaauxr!slntt`!trYi+++QGL3!^4j&gSp`L3fBd|=Y{gl>fKy4S*AAb2^znOY zR?eqie_lR&eQD~ftLwKs`}p z+YZR^_H=O!k+__kuz)Ecg^Ag12ZOLNx3;u3ySh_D_w4rR{qYQn3K}XpN?K}t0uv@o znKW(URA-J8+8SD#t5+zoT)ARuvUSVMf@p7628QRqm~XvV##RV4R<*=6q9i4;B-JXp zC>2OC7#SEE=o%X78W@Hc8CaPZTbY<@8<<)d7|eU8w+cl=ZhlH;S|vn-fhAZ2P_>Db Yff+=@sp+9>fEpM)UHx3vIVCg!0E$nmqyPW_ literal 0 HcmV?d00001 diff --git a/include/images/gqbColSel.pngc b/include/images/gqbColSel.pngc new file mode 100644 index 0000000..7a5d50d --- /dev/null +++ b/include/images/gqbColSel.pngc @@ -0,0 +1,95 @@ +#ifndef GQBCOLSEL_PNG_H +#define GQBCOLSEL_PNG_H + +static const unsigned char gqbColSel_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x84, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x9b, 0x9b, 0x9b, 0x55, +0x55, 0x55, 0xfd, 0xfe, 0xfe, 0xfb, 0xfe, 0xfe, +0xf9, 0xfc, 0xfe, 0xf7, 0xfb, 0xfe, 0xf1, 0xf6, +0xf9, 0xec, 0xf6, 0xfa, 0x57, 0x57, 0x57, 0xfc, +0xfe, 0xfe, 0xfa, 0xfd, 0xfe, 0xf7, 0xfb, 0xfd, +0xf1, 0xf9, 0xfc, 0xde, 0xb2, 0xb4, 0xd8, 0xa6, +0xac, 0x5e, 0x5b, 0x5c, 0xf9, 0xfb, 0xfc, 0xed, +0xd1, 0xd3, 0xed, 0xe7, 0xe9, 0xe2, 0xcc, 0xcd, +0xcd, 0x61, 0x63, 0xd1, 0x91, 0x96, 0x60, 0x5f, +0x60, 0xf3, 0xe6, 0xe6, 0xd6, 0x70, 0x72, 0xd6, +0x85, 0x87, 0xd1, 0x78, 0x7b, 0xcb, 0x75, 0x79, +0xd6, 0xd7, 0xdd, 0x6a, 0x70, 0x72, 0xf5, 0xf8, +0xf9, 0xdd, 0xa6, 0xa8, 0xcd, 0x4e, 0x50, 0xca, +0x62, 0x65, 0xd6, 0xc3, 0xc9, 0xe2, 0xf1, 0xf7, +0x65, 0x6a, 0x6c, 0xf2, 0xfa, 0xfc, 0xe9, 0xe6, +0xeb, 0xd2, 0x95, 0x9a, 0xd5, 0xaf, 0xb4, 0xe6, +0xf1, 0xf5, 0xea, 0xf7, 0xfb, 0x35, 0xf1, 0x6c, +0x18, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x4b, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0xa0, +0x02, 0x60, 0x64, 0x02, 0x03, 0x46, 0xb8, 0x00, +0x13, 0x33, 0x0b, 0x2b, 0x1b, 0x3b, 0x07, 0x27, +0x42, 0x80, 0x8b, 0x9b, 0x87, 0x97, 0x8f, 0x5f, +0x00, 0x21, 0x20, 0x28, 0x24, 0x2c, 0x22, 0x2a, +0x26, 0x8e, 0x10, 0x90, 0x90, 0x94, 0x92, 0x96, +0x91, 0x95, 0x43, 0x08, 0xc8, 0x2b, 0x28, 0x2a, +0x29, 0xab, 0xa8, 0x22, 0x04, 0xd4, 0xd4, 0x35, +0x34, 0xb5, 0xb4, 0x99, 0x70, 0x5b, 0x4b, 0x05, +0x00, 0x00, 0xe7, 0xfa, 0x03, 0xda, 0xec, 0xa6, +0x06, 0x71, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, +0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *gqbColSel_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_gqbColSel_png = new wxImage(); + if (!img_gqbColSel_png || !img_gqbColSel_png->IsOk()) + { + wxMemoryInputStream img_gqbColSel_pngIS(gqbColSel_png_data, sizeof(gqbColSel_png_data)); + img_gqbColSel_png->LoadFile(img_gqbColSel_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbColSel_png; +} +#define gqbColSel_png_img gqbColSel_png_img() + +static wxBitmap *gqbColSel_png_bmp() +{ + static wxBitmap *bmp_gqbColSel_png; + if (!bmp_gqbColSel_png || !bmp_gqbColSel_png->IsOk()) + bmp_gqbColSel_png = new wxBitmap(*gqbColSel_png_img); + return bmp_gqbColSel_png; +} +#define gqbColSel_png_bmp gqbColSel_png_bmp() + +static wxIcon *gqbColSel_png_ico() +{ + static wxIcon *ico_gqbColSel_png; + if (!ico_gqbColSel_png || !ico_gqbColSel_png->IsOk()) + { + ico_gqbColSel_png = new wxIcon(); + ico_gqbColSel_png->CopyFromBitmap(*gqbColSel_png_bmp); + } + return ico_gqbColSel_png; +} +#define gqbColSel_png_ico gqbColSel_png_ico() + +#endif // GQBCOLSEL_PNG_H diff --git a/include/images/gqbDown.png b/include/images/gqbDown.png new file mode 100644 index 0000000000000000000000000000000000000000..2b3f9813af5024c3a1a96f49f786108c421e5318 GIT binary patch literal 388 zcmeAS@N?(olHy`uVBq!ia0vp@K+M6x3?xN=wEhKBMFBn`u0XnbV`9{7;d2j`@4DQ$ z>0IH4vpMTdr>{MowEAS+suNKwPlT;MlYI16@2)GY^A874-|H}Sx8e!&b5&u*jvIh+L^k;OpT1B~5HX4?T7o}Mm_Asp9TPrCCp81S$L z-fp>9{l4J8_N4V3sb&7oI%aBxQ(pgclsM|Cb!5_0*T}2Bw_h&5$^Y0yUz;KCcVQgc zf?f0FA7nF1)$9ym`d{^K<`kfzswJ)wB`Jv|saDBFsX&Us$iUD**U(7Uz%azfz{gTe~DWM4f DO_G%` literal 0 HcmV?d00001 diff --git a/include/images/gqbDown.pngc b/include/images/gqbDown.pngc new file mode 100644 index 0000000..4b95046 --- /dev/null +++ b/include/images/gqbDown.pngc @@ -0,0 +1,93 @@ +#ifndef GQBDOWN_PNG_H +#define GQBDOWN_PNG_H + +static const unsigned char gqbDown_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x08, +0x08, 0x03, 0x00, 0x00, 0x00, 0x15, 0xf8, 0x85, +0xfd, 0x00, 0x00, 0x00, 0x72, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x61, 0x5a, +0x9b, 0x13, 0xce, 0xe0, 0xa7, 0xba, 0xd3, 0x81, +0xb2, 0xce, 0x71, 0xb0, 0xcd, 0x6c, 0xae, 0xcb, +0x67, 0xad, 0xcb, 0x62, 0xab, 0xc9, 0x5e, 0xaa, +0xc8, 0x5a, 0xa9, 0xc8, 0x56, 0xaf, 0xcc, 0x63, +0xc5, 0xda, 0x8d, 0xba, 0xd4, 0x85, 0x9f, 0xc3, +0x53, 0x97, 0xbd, 0x40, 0x95, 0xbb, 0x39, 0x92, +0xba, 0x33, 0x90, 0xb8, 0x2c, 0x8e, 0xb7, 0x26, +0x94, 0xbb, 0x2f, 0xaf, 0xcc, 0x64, 0xba, 0xd4, +0x83, 0x9f, 0xc2, 0x51, 0x96, 0xbd, 0x3e, 0x94, +0xbb, 0x38, 0x92, 0xb9, 0x31, 0x97, 0xbc, 0x38, +0xb1, 0xcd, 0x69, 0xba, 0xd3, 0x83, 0x9e, 0xc2, +0x4f, 0x96, 0xbc, 0x3d, 0x9b, 0xbf, 0x43, 0xb4, +0xcf, 0x70, 0xa5, 0xc5, 0x5a, 0xb6, 0xd1, 0x78, +0xcc, 0xdf, 0xa3, 0x6d, 0x2e, 0x72, 0xd0, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x49, 0x49, 0x44, 0x41, +0x54, 0x08, 0xd7, 0x45, 0xc9, 0x47, 0x0e, 0x80, +0x30, 0x0c, 0x05, 0x51, 0xdb, 0x84, 0xde, 0x7b, +0xef, 0x70, 0xff, 0x2b, 0x92, 0xaf, 0x08, 0x65, +0x76, 0x4f, 0x43, 0x2c, 0x36, 0x26, 0x71, 0x94, +0xeb, 0xf9, 0x41, 0x18, 0xc5, 0x49, 0x2a, 0xc4, +0x92, 0xe5, 0x45, 0x59, 0xd5, 0x4d, 0xdb, 0xe9, +0xa7, 0xd9, 0x0f, 0xe3, 0x34, 0x2f, 0x2b, 0x00, +0x6e, 0xfb, 0x71, 0x5e, 0x06, 0xa0, 0xba, 0x9f, +0x1f, 0xe0, 0x6b, 0x01, 0x1a, 0x7c, 0xb9, 0x54, +0x02, 0xff, 0x7a, 0xee, 0x99, 0x94, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *gqbDown_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_gqbDown_png = new wxImage(); + if (!img_gqbDown_png || !img_gqbDown_png->IsOk()) + { + wxMemoryInputStream img_gqbDown_pngIS(gqbDown_png_data, sizeof(gqbDown_png_data)); + img_gqbDown_png->LoadFile(img_gqbDown_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbDown_png; +} +#define gqbDown_png_img gqbDown_png_img() + +static wxBitmap *gqbDown_png_bmp() +{ + static wxBitmap *bmp_gqbDown_png; + if (!bmp_gqbDown_png || !bmp_gqbDown_png->IsOk()) + bmp_gqbDown_png = new wxBitmap(*gqbDown_png_img); + return bmp_gqbDown_png; +} +#define gqbDown_png_bmp gqbDown_png_bmp() + +static wxIcon *gqbDown_png_ico() +{ + static wxIcon *ico_gqbDown_png; + if (!ico_gqbDown_png || !ico_gqbDown_png->IsOk()) + { + ico_gqbDown_png = new wxIcon(); + ico_gqbDown_png->CopyFromBitmap(*gqbDown_png_bmp); + } + return ico_gqbDown_png; +} +#define gqbDown_png_ico gqbDown_png_ico() + +#endif // GQBDOWN_PNG_H diff --git a/include/images/gqbDownBottom.png b/include/images/gqbDownBottom.png new file mode 100644 index 0000000000000000000000000000000000000000..e14c0232744798bd81cdbeae68a427366bd606cd GIT binary patch literal 349 zcmeAS@N?(olHy`uVBq!ia0vp@K+M6x3?xN=wEhKBfdM`tu0XnbV`9{7;d2j`@4DQ$ z>0IH4vpH)|C#^mixAH{T`ZLK#Z}slF(mMZe@btY7lXe+T*r79JxBmJwDZ8#T&p#A6 zWw*toorW9FW-dJ%we4cXnfr^I=S=Vc8p>D_&K3%K z-7P9T%#XYjflTE&ts58_a%~w`W*pG22O6hZ;u=wsl30>zm0Xkxq!^403=MP*jdTqR zLyQcpOpL8eOtlS6tqct2z0+HTq9HdwB{QuOqQSrttO2On#LB=7qT$r^&^15}44$rj JF6*2UngAEqb=Cj? literal 0 HcmV?d00001 diff --git a/include/images/gqbDownBottom.pngc b/include/images/gqbDownBottom.pngc new file mode 100644 index 0000000..3b69ced --- /dev/null +++ b/include/images/gqbDownBottom.pngc @@ -0,0 +1,88 @@ +#ifndef GQBDOWNBOTTOM_PNG_H +#define GQBDOWNBOTTOM_PNG_H + +static const unsigned char gqbDownBottom_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x08, +0x08, 0x03, 0x00, 0x00, 0x00, 0x15, 0xf8, 0x85, +0xfd, 0x00, 0x00, 0x00, 0x51, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x61, 0x5a, +0x9b, 0x13, 0xce, 0xe0, 0xa7, 0xba, 0xd3, 0x81, +0xb2, 0xce, 0x71, 0xb0, 0xcd, 0x6c, 0xad, 0xcb, +0x62, 0xab, 0xc9, 0x5e, 0xa9, 0xc8, 0x56, 0xaf, +0xcc, 0x63, 0xc5, 0xda, 0x8d, 0xba, 0xd4, 0x85, +0x9f, 0xc3, 0x53, 0x97, 0xbd, 0x40, 0x92, 0xba, +0x33, 0x90, 0xb8, 0x2c, 0x94, 0xbb, 0x2f, 0xaf, +0xcc, 0x64, 0xba, 0xd4, 0x83, 0x9f, 0xc2, 0x51, +0x94, 0xbb, 0x38, 0x92, 0xb9, 0x31, 0xb1, 0xcd, +0x69, 0xa5, 0xc5, 0x5a, 0xb6, 0xd1, 0x78, 0xcc, +0xdf, 0xa3, 0x83, 0x9c, 0x90, 0x4c, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x43, 0x49, 0x44, 0x41, 0x54, +0x08, 0xd7, 0x63, 0x60, 0x60, 0x64, 0x82, 0x01, +0x46, 0x06, 0x06, 0x06, 0x26, 0x66, 0x16, 0x56, +0x36, 0x76, 0x0e, 0x4e, 0x2e, 0x6e, 0x26, 0x20, +0x8f, 0x91, 0x89, 0x87, 0x97, 0x8f, 0x5f, 0x40, +0x50, 0x08, 0x2c, 0x07, 0xe4, 0x0a, 0x8b, 0x88, +0x8a, 0x89, 0x43, 0x38, 0x20, 0x2e, 0x8b, 0x84, +0x24, 0x8c, 0x03, 0xe2, 0x4a, 0x21, 0x38, 0x20, +0x2e, 0x23, 0x9c, 0x85, 0xb0, 0x01, 0x00, 0x6d, +0x3d, 0x01, 0xa9, 0x68, 0xc0, 0x2b, 0x7f, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *gqbDownBottom_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_gqbDownBottom_png = new wxImage(); + if (!img_gqbDownBottom_png || !img_gqbDownBottom_png->IsOk()) + { + wxMemoryInputStream img_gqbDownBottom_pngIS(gqbDownBottom_png_data, sizeof(gqbDownBottom_png_data)); + img_gqbDownBottom_png->LoadFile(img_gqbDownBottom_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbDownBottom_png; +} +#define gqbDownBottom_png_img gqbDownBottom_png_img() + +static wxBitmap *gqbDownBottom_png_bmp() +{ + static wxBitmap *bmp_gqbDownBottom_png; + if (!bmp_gqbDownBottom_png || !bmp_gqbDownBottom_png->IsOk()) + bmp_gqbDownBottom_png = new wxBitmap(*gqbDownBottom_png_img); + return bmp_gqbDownBottom_png; +} +#define gqbDownBottom_png_bmp gqbDownBottom_png_bmp() + +static wxIcon *gqbDownBottom_png_ico() +{ + static wxIcon *ico_gqbDownBottom_png; + if (!ico_gqbDownBottom_png || !ico_gqbDownBottom_png->IsOk()) + { + ico_gqbDownBottom_png = new wxIcon(); + ico_gqbDownBottom_png->CopyFromBitmap(*gqbDownBottom_png_bmp); + } + return ico_gqbDownBottom_png; +} +#define gqbDownBottom_png_ico gqbDownBottom_png_ico() + +#endif // GQBDOWNBOTTOM_PNG_H diff --git a/include/images/gqbJoin.png b/include/images/gqbJoin.png new file mode 100644 index 0000000000000000000000000000000000000000..776fe7d407594aa8513faa10235239ac9ad00c8d GIT binary patch literal 506 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~e!3-p0EYEHRQhNh@LR^9L?Adb~8X689I5cJQ z)So|p-oO8F*|KG2Wo7s7J-Bu2?xRPK7A{=0Y15X1g2J-0^3syh%a<=tnl$Ohk01B$ zKB%gyYHe*>wrs`1g^SOeKEG+>mZqjAcX#)1-@Ywau;A?3v!$hFnVDI$XU)BFCzR)j-8B&iF^C@?d@B4zkmPU)6;k1{N>o# z_*bu9B_4*dm#^6-IZXk2fUzXVFPOpM*^M+H zhqJ&VvKUBvfU(=jY&#&M#M8wwgyVX0!U1-PnKJ@eBO-22*m>rS%$hk4v$|)qdwlxz zk(+~yvzuY&oHdJ*cz7NOO$xeXv`K)`vXYg}Rh2DOG}N?oLc@l(Wz)9x=}lOIsOk()) + { + wxMemoryInputStream img_gqbJoin_pngIS(gqbJoin_png_data, sizeof(gqbJoin_png_data)); + img_gqbJoin_png->LoadFile(img_gqbJoin_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbJoin_png; +} +#define gqbJoin_png_img gqbJoin_png_img() + +static wxBitmap *gqbJoin_png_bmp() +{ + static wxBitmap *bmp_gqbJoin_png; + if (!bmp_gqbJoin_png || !bmp_gqbJoin_png->IsOk()) + bmp_gqbJoin_png = new wxBitmap(*gqbJoin_png_img); + return bmp_gqbJoin_png; +} +#define gqbJoin_png_bmp gqbJoin_png_bmp() + +static wxIcon *gqbJoin_png_ico() +{ + static wxIcon *ico_gqbJoin_png; + if (!ico_gqbJoin_png || !ico_gqbJoin_png->IsOk()) + { + ico_gqbJoin_png = new wxIcon(); + ico_gqbJoin_png->CopyFromBitmap(*gqbJoin_png_bmp); + } + return ico_gqbJoin_png; +} +#define gqbJoin_png_ico gqbJoin_png_ico() + +#endif // GQBJOIN_PNG_H diff --git a/include/images/gqbJoinCursor.png b/include/images/gqbJoinCursor.png new file mode 100644 index 0000000000000000000000000000000000000000..deb59cab9f592125c922f5ee856dd4c0ef538198 GIT binary patch literal 238 zcmeAS@N?(olHy`uVBq!ia0vp^3Lwk~Bp9L@-6Me%Q%R6tFatx`*sNlBbJf2*>s0ga&4Ifr$)CTn;X*b6y{45H?sWRG`bz z)iyA- xGBB9;PHz>8hTQy=%(O~~1_Mj52B2yaD+4o#hEvl+*8nvzc)I$ztaD0e0stf$Ig|hZ literal 0 HcmV?d00001 diff --git a/include/images/gqbJoinCursor.pngc b/include/images/gqbJoinCursor.pngc new file mode 100644 index 0000000..791e1c6 --- /dev/null +++ b/include/images/gqbJoinCursor.pngc @@ -0,0 +1,74 @@ +#ifndef GQBJOINCURSOR_PNG_H +#define GQBJOINCURSOR_PNG_H + +static const unsigned char gqbJoinCursor_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x01, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x01, 0x47, +0x59, 0x00, 0x00, 0x00, 0x02, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x00, 0x76, 0x93, 0xcd, 0x38, 0x00, +0x00, 0x00, 0x02, 0x62, 0x4b, 0x47, 0x44, 0x00, +0x01, 0xdd, 0x8a, 0x13, 0xa4, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x22, 0x49, 0x44, +0x41, 0x54, 0x08, 0xd7, 0x63, 0x60, 0x80, 0x03, +0x07, 0x10, 0x91, 0x00, 0x22, 0x0a, 0x40, 0x44, +0x05, 0x9c, 0xeb, 0xc0, 0x80, 0x13, 0x30, 0xa3, +0x12, 0x70, 0x2d, 0x08, 0x82, 0x42, 0x00, 0x00, +0x7c, 0x4b, 0x03, 0x52, 0x24, 0xcf, 0x43, 0xcb, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, +0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *gqbJoinCursor_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_gqbJoinCursor_png = new wxImage(); + if (!img_gqbJoinCursor_png || !img_gqbJoinCursor_png->IsOk()) + { + wxMemoryInputStream img_gqbJoinCursor_pngIS(gqbJoinCursor_png_data, sizeof(gqbJoinCursor_png_data)); + img_gqbJoinCursor_png->LoadFile(img_gqbJoinCursor_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbJoinCursor_png; +} +#define gqbJoinCursor_png_img gqbJoinCursor_png_img() + +static wxBitmap *gqbJoinCursor_png_bmp() +{ + static wxBitmap *bmp_gqbJoinCursor_png; + if (!bmp_gqbJoinCursor_png || !bmp_gqbJoinCursor_png->IsOk()) + bmp_gqbJoinCursor_png = new wxBitmap(*gqbJoinCursor_png_img); + return bmp_gqbJoinCursor_png; +} +#define gqbJoinCursor_png_bmp gqbJoinCursor_png_bmp() + +static wxIcon *gqbJoinCursor_png_ico() +{ + static wxIcon *ico_gqbJoinCursor_png; + if (!ico_gqbJoinCursor_png || !ico_gqbJoinCursor_png->IsOk()) + { + ico_gqbJoinCursor_png = new wxIcon(); + ico_gqbJoinCursor_png->CopyFromBitmap(*gqbJoinCursor_png_bmp); + } + return ico_gqbJoinCursor_png; +} +#define gqbJoinCursor_png_ico gqbJoinCursor_png_ico() + +#endif // GQBJOINCURSOR_PNG_H diff --git a/include/images/gqbOrderAdd.png b/include/images/gqbOrderAdd.png new file mode 100644 index 0000000000000000000000000000000000000000..59205c3979853d6fa846743a4803669d0c864d0c GIT binary patch literal 308 zcmeAS@N?(olHy`uVBq!ia0vp@K+MU(3?%O@35x(yW&u7Su0XnbV`9{7;d2j`@4DQ$ z>q_gUbA|H{2k*Mlyy0xl^t}%A4+X9~5jJJF{>HPJ>(3;wKa+CwR__s&SFAvtj3q&S z!3+-1ZlnP@oCO|{#X#BvjNMLV+W{G-o-U3d9M^r%o)lzI;9+t&^84Dq*IsOk()) + { + wxMemoryInputStream img_gqbOrderAdd_pngIS(gqbOrderAdd_png_data, sizeof(gqbOrderAdd_png_data)); + img_gqbOrderAdd_png->LoadFile(img_gqbOrderAdd_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbOrderAdd_png; +} +#define gqbOrderAdd_png_img gqbOrderAdd_png_img() + +static wxBitmap *gqbOrderAdd_png_bmp() +{ + static wxBitmap *bmp_gqbOrderAdd_png; + if (!bmp_gqbOrderAdd_png || !bmp_gqbOrderAdd_png->IsOk()) + bmp_gqbOrderAdd_png = new wxBitmap(*gqbOrderAdd_png_img); + return bmp_gqbOrderAdd_png; +} +#define gqbOrderAdd_png_bmp gqbOrderAdd_png_bmp() + +static wxIcon *gqbOrderAdd_png_ico() +{ + static wxIcon *ico_gqbOrderAdd_png; + if (!ico_gqbOrderAdd_png || !ico_gqbOrderAdd_png->IsOk()) + { + ico_gqbOrderAdd_png = new wxIcon(); + ico_gqbOrderAdd_png->CopyFromBitmap(*gqbOrderAdd_png_bmp); + } + return ico_gqbOrderAdd_png; +} +#define gqbOrderAdd_png_ico gqbOrderAdd_png_ico() + +#endif // GQBORDERADD_PNG_H diff --git a/include/images/gqbOrderAddAll.png b/include/images/gqbOrderAddAll.png new file mode 100644 index 0000000000000000000000000000000000000000..d95e9d2012331dbf5b0812f6dc2ef32323c25132 GIT binary patch literal 324 zcmeAS@N?(olHy`uVBq!ia0vp@K+MU(3?%O@35x(yW&u7Su0XnbV`9{7;d2j`@4DQ$ z>q_gUbA|H{2k*Mlyy0xl^t}%A4+X9~5jJJF{>HPJ>(3;wKa+CwR__s&SFAvtj3q&S z!3+-1ZlnP@oCO|{#X#BvjNMLV+W{G_o-U3d9M?m8J;e?va5yvHa$FnrzW%1$rdQ7< zH?kX;GblaC`L9;C+05aFLNyWd^d7Jp6j-f&)?rOhfihfnlDsz z1!$mZiEBhjN@7W>RdP`(kYX@0Ff`CLG}1LN3^6jWGBLI?G1WFOwK6c6_fBsWiiX_$ ml+3hBhz0{oum+%N6DtEVh=xIsOk()) + { + wxMemoryInputStream img_gqbOrderAddAll_pngIS(gqbOrderAddAll_png_data, sizeof(gqbOrderAddAll_png_data)); + img_gqbOrderAddAll_png->LoadFile(img_gqbOrderAddAll_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbOrderAddAll_png; +} +#define gqbOrderAddAll_png_img gqbOrderAddAll_png_img() + +static wxBitmap *gqbOrderAddAll_png_bmp() +{ + static wxBitmap *bmp_gqbOrderAddAll_png; + if (!bmp_gqbOrderAddAll_png || !bmp_gqbOrderAddAll_png->IsOk()) + bmp_gqbOrderAddAll_png = new wxBitmap(*gqbOrderAddAll_png_img); + return bmp_gqbOrderAddAll_png; +} +#define gqbOrderAddAll_png_bmp gqbOrderAddAll_png_bmp() + +static wxIcon *gqbOrderAddAll_png_ico() +{ + static wxIcon *ico_gqbOrderAddAll_png; + if (!ico_gqbOrderAddAll_png || !ico_gqbOrderAddAll_png->IsOk()) + { + ico_gqbOrderAddAll_png = new wxIcon(); + ico_gqbOrderAddAll_png->CopyFromBitmap(*gqbOrderAddAll_png_bmp); + } + return ico_gqbOrderAddAll_png; +} +#define gqbOrderAddAll_png_ico gqbOrderAddAll_png_ico() + +#endif // GQBORDERADDALL_PNG_H diff --git a/include/images/gqbOrderRemove.png b/include/images/gqbOrderRemove.png new file mode 100644 index 0000000000000000000000000000000000000000..06f7dc7db98047649725ec5fc93689b322f94884 GIT binary patch literal 309 zcmeAS@N?(olHy`uVBq!ia0vp@K+MU(3?%O@35x(yW&u7Su0XnbV`9{7;d2j`@4C{u z>vH3+E6wu{2X8u8IR8-K^t}!n&gN`9n>l5-{>l?!>(8XDKa+g)RRq5t#*!ev zU!n-K1qgOUw)Ha9iv)`G3&&NfZq&Svl))p`H1)eO;9ayjVMV;EJ?LWE=mPb z3`Pcq2D*kux(0?JMg~?U##Sb#+6Jap1_txq>8(Q1kei>9nN|tWU|090*aWnc!; UaB6z!8lVOSPgg&ebxsLQ05{iQ?*IS* literal 0 HcmV?d00001 diff --git a/include/images/gqbOrderRemove.pngc b/include/images/gqbOrderRemove.pngc new file mode 100644 index 0000000..f5dab80 --- /dev/null +++ b/include/images/gqbOrderRemove.pngc @@ -0,0 +1,83 @@ +#ifndef GQBORDERREMOVE_PNG_H +#define GQBORDERREMOVE_PNG_H + +static const unsigned char gqbOrderRemove_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x09, +0x08, 0x03, 0x00, 0x00, 0x00, 0xde, 0xa4, 0x56, +0x58, 0x00, 0x00, 0x00, 0x36, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x61, 0x5a, +0x9b, 0x13, 0xce, 0xe0, 0xa7, 0xba, 0xd4, 0x85, +0xba, 0xd3, 0x81, 0xba, 0xd4, 0x83, 0x9f, 0xc3, +0x53, 0xb2, 0xce, 0x71, 0x9f, 0xc2, 0x51, 0x97, +0xbd, 0x40, 0xb0, 0xcd, 0x6c, 0xb1, 0xcd, 0x69, +0x94, 0xbb, 0x2f, 0xa9, 0xc8, 0x56, 0xaf, 0xcc, +0x64, 0xaf, 0xcc, 0x63, 0xc5, 0xda, 0x8d, 0x36, +0x33, 0x65, 0xdd, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x36, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, +0x60, 0x80, 0x00, 0x46, 0x26, 0x46, 0x06, 0x38, +0x60, 0x64, 0x62, 0x66, 0x42, 0xe2, 0xb0, 0xb0, +0x32, 0x21, 0x38, 0x6c, 0xec, 0x1c, 0x4c, 0x70, +0x0e, 0x2b, 0x27, 0x17, 0x37, 0x92, 0x1c, 0x0f, +0x2f, 0x1f, 0xb2, 0x3e, 0x7e, 0x01, 0x26, 0x64, +0x33, 0x05, 0x91, 0x78, 0x50, 0xfb, 0x00, 0x2a, +0x9b, 0x00, 0xc7, 0x7e, 0x4c, 0x14, 0x4d, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *gqbOrderRemove_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_gqbOrderRemove_png = new wxImage(); + if (!img_gqbOrderRemove_png || !img_gqbOrderRemove_png->IsOk()) + { + wxMemoryInputStream img_gqbOrderRemove_pngIS(gqbOrderRemove_png_data, sizeof(gqbOrderRemove_png_data)); + img_gqbOrderRemove_png->LoadFile(img_gqbOrderRemove_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbOrderRemove_png; +} +#define gqbOrderRemove_png_img gqbOrderRemove_png_img() + +static wxBitmap *gqbOrderRemove_png_bmp() +{ + static wxBitmap *bmp_gqbOrderRemove_png; + if (!bmp_gqbOrderRemove_png || !bmp_gqbOrderRemove_png->IsOk()) + bmp_gqbOrderRemove_png = new wxBitmap(*gqbOrderRemove_png_img); + return bmp_gqbOrderRemove_png; +} +#define gqbOrderRemove_png_bmp gqbOrderRemove_png_bmp() + +static wxIcon *gqbOrderRemove_png_ico() +{ + static wxIcon *ico_gqbOrderRemove_png; + if (!ico_gqbOrderRemove_png || !ico_gqbOrderRemove_png->IsOk()) + { + ico_gqbOrderRemove_png = new wxIcon(); + ico_gqbOrderRemove_png->CopyFromBitmap(*gqbOrderRemove_png_bmp); + } + return ico_gqbOrderRemove_png; +} +#define gqbOrderRemove_png_ico gqbOrderRemove_png_ico() + +#endif // GQBORDERREMOVE_PNG_H diff --git a/include/images/gqbOrderRemoveAll.png b/include/images/gqbOrderRemoveAll.png new file mode 100644 index 0000000000000000000000000000000000000000..773aa1083d487e664ecaa7ce7ac4635fdb42f57e GIT binary patch literal 320 zcmeAS@N?(olHy`uVBq!ia0vp@K+MU(3?%O@35x(yW&u7Su0XnbV`9{7;d2j`@4C{u z>vH3+E6wu{2X8u8IR8-K^t}!n&gN`9n>l5-{>l?!>(8XDKa+g)RRq5t#*!ev zU?MniLsT5skVWsm4U&$cY3Q(H00)|WTsU@ hG#FTdH2_tcSQ(f>G@P0qx(29$!PC{xWt~$(699yyX~+No literal 0 HcmV?d00001 diff --git a/include/images/gqbOrderRemoveAll.pngc b/include/images/gqbOrderRemoveAll.pngc new file mode 100644 index 0000000..7dd627f --- /dev/null +++ b/include/images/gqbOrderRemoveAll.pngc @@ -0,0 +1,84 @@ +#ifndef GQBORDERREMOVEALL_PNG_H +#define GQBORDERREMOVEALL_PNG_H + +static const unsigned char gqbOrderRemoveAll_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x09, +0x08, 0x03, 0x00, 0x00, 0x00, 0xde, 0xa4, 0x56, +0x58, 0x00, 0x00, 0x00, 0x36, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x61, 0x5a, +0x9b, 0x13, 0xce, 0xe0, 0xa7, 0xba, 0xd4, 0x85, +0xba, 0xd3, 0x81, 0xba, 0xd4, 0x83, 0x9f, 0xc3, +0x53, 0xb2, 0xce, 0x71, 0x9f, 0xc2, 0x51, 0x97, +0xbd, 0x40, 0xb0, 0xcd, 0x6c, 0xb1, 0xcd, 0x69, +0x94, 0xbb, 0x2f, 0xa9, 0xc8, 0x56, 0xaf, 0xcc, +0x64, 0xaf, 0xcc, 0x63, 0xc5, 0xda, 0x8d, 0x36, +0x33, 0x65, 0xdd, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x41, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, +0x60, 0x00, 0x02, 0x46, 0x26, 0x46, 0x38, 0x09, +0xa4, 0x98, 0x99, 0x60, 0x24, 0x90, 0x62, 0x61, +0x65, 0x82, 0x92, 0x40, 0x8a, 0x8d, 0x9d, 0x83, +0x09, 0x42, 0x02, 0x39, 0xac, 0x9c, 0x5c, 0xdc, +0x4c, 0x10, 0x12, 0x24, 0xc7, 0xc3, 0xcb, 0xc7, +0x04, 0x21, 0xc1, 0xfa, 0xf8, 0x05, 0x98, 0xa0, +0x24, 0x98, 0x2b, 0xc8, 0x04, 0x23, 0x91, 0xed, +0x03, 0x00, 0x54, 0x79, 0x01, 0x8c, 0x64, 0xba, +0x1b, 0xba, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, +0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *gqbOrderRemoveAll_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_gqbOrderRemoveAll_png = new wxImage(); + if (!img_gqbOrderRemoveAll_png || !img_gqbOrderRemoveAll_png->IsOk()) + { + wxMemoryInputStream img_gqbOrderRemoveAll_pngIS(gqbOrderRemoveAll_png_data, sizeof(gqbOrderRemoveAll_png_data)); + img_gqbOrderRemoveAll_png->LoadFile(img_gqbOrderRemoveAll_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbOrderRemoveAll_png; +} +#define gqbOrderRemoveAll_png_img gqbOrderRemoveAll_png_img() + +static wxBitmap *gqbOrderRemoveAll_png_bmp() +{ + static wxBitmap *bmp_gqbOrderRemoveAll_png; + if (!bmp_gqbOrderRemoveAll_png || !bmp_gqbOrderRemoveAll_png->IsOk()) + bmp_gqbOrderRemoveAll_png = new wxBitmap(*gqbOrderRemoveAll_png_img); + return bmp_gqbOrderRemoveAll_png; +} +#define gqbOrderRemoveAll_png_bmp gqbOrderRemoveAll_png_bmp() + +static wxIcon *gqbOrderRemoveAll_png_ico() +{ + static wxIcon *ico_gqbOrderRemoveAll_png; + if (!ico_gqbOrderRemoveAll_png || !ico_gqbOrderRemoveAll_png->IsOk()) + { + ico_gqbOrderRemoveAll_png = new wxIcon(); + ico_gqbOrderRemoveAll_png->CopyFromBitmap(*gqbOrderRemoveAll_png_bmp); + } + return ico_gqbOrderRemoveAll_png; +} +#define gqbOrderRemoveAll_png_ico gqbOrderRemoveAll_png_ico() + +#endif // GQBORDERREMOVEALL_PNG_H diff --git a/include/images/gqbRemove.png b/include/images/gqbRemove.png new file mode 100644 index 0000000000000000000000000000000000000000..2b3a3f3db78fdb9af78c65d80e3b6b9017091bcf GIT binary patch literal 225 zcmeAS@N?(olHy`uVBq!ia0vp^!a&T=$P6THy3+E26kC8#h%1o(&1{>$*-8h+YZPO@^oUO_QmvAUQh^kMk%6IsuAz~xfnkV|ft87|m5HggfvJ^&!Mt~Rt57uL=BH$) jRYEivSb{YGRhw8Dm_an0njX3asDZ)L)z4*}Q$iB}Zx=W9 literal 0 HcmV?d00001 diff --git a/include/images/gqbRemove.pngc b/include/images/gqbRemove.pngc new file mode 100644 index 0000000..7fd85d4 --- /dev/null +++ b/include/images/gqbRemove.pngc @@ -0,0 +1,73 @@ +#ifndef GQBREMOVE_PNG_H +#define GQBREMOVE_PNG_H + +static const unsigned char gqbRemove_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0f, +0x01, 0x03, 0x00, 0x00, 0x00, 0x3c, 0x8a, 0x66, +0x6f, 0x00, 0x00, 0x00, 0x06, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xfb, 0x03, 0x3d, 0x6f, +0xb3, 0x3a, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x12, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, +0x60, 0xc0, 0x02, 0xec, 0xff, 0x37, 0x60, 0x60, +0x2c, 0x00, 0x00, 0x04, 0x5a, 0x08, 0xb7, 0xd0, +0x5b, 0x4a, 0xb6, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *gqbRemove_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_gqbRemove_png = new wxImage(); + if (!img_gqbRemove_png || !img_gqbRemove_png->IsOk()) + { + wxMemoryInputStream img_gqbRemove_pngIS(gqbRemove_png_data, sizeof(gqbRemove_png_data)); + img_gqbRemove_png->LoadFile(img_gqbRemove_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbRemove_png; +} +#define gqbRemove_png_img gqbRemove_png_img() + +static wxBitmap *gqbRemove_png_bmp() +{ + static wxBitmap *bmp_gqbRemove_png; + if (!bmp_gqbRemove_png || !bmp_gqbRemove_png->IsOk()) + bmp_gqbRemove_png = new wxBitmap(*gqbRemove_png_img); + return bmp_gqbRemove_png; +} +#define gqbRemove_png_bmp gqbRemove_png_bmp() + +static wxIcon *gqbRemove_png_ico() +{ + static wxIcon *ico_gqbRemove_png; + if (!ico_gqbRemove_png || !ico_gqbRemove_png->IsOk()) + { + ico_gqbRemove_png = new wxIcon(); + ico_gqbRemove_png->CopyFromBitmap(*gqbRemove_png_bmp); + } + return ico_gqbRemove_png; +} +#define gqbRemove_png_ico gqbRemove_png_ico() + +#endif // GQBREMOVE_PNG_H diff --git a/include/images/gqbRemoveRest.png b/include/images/gqbRemoveRest.png new file mode 100644 index 0000000000000000000000000000000000000000..a8a937b12686bd18c5c5ffd6caab854d04926e0b GIT binary patch literal 730 zcmeAS@N?(olHy`uVBq!ia0vp^!a&T=!3-n~XR*jJFfh6V_=LCuxl^Zat*F{kP`qX5 zuA7a`dp~^q{NdUEr#F7zz5M0o*-w{GzPWJd&B;B_kM4Q+>iOq_jxAUB{yMwy=dtzg z4ln<-ea?%ulO8VXzCEw`>a?136G~6cY(CS`wIZr&)$ZkwS5LpuSA61B@4Q2jQY+KT z?&aj1R8+iQUf!C0XuWshOU9z@5y!Byi@}3=9W>?It{%O7k$@%F6kn8@8>uzRtqyp}YIPs;aw|R`-pKf5*k&)6~3ZYPx&v?e&W; zwG=Koz|Hf()a*-a?5DuMJ6c-jO-!1Kmh9u@yRWDB(ar6)lF|iJ(vL>2>S4={E+nQaGT zob_~Z43W5;oRE^_#;U`^vnJ<_jKhJGM~|L8eE9V7v*%A8P&jZ(QA0&XNlQyjPf=6# z>~XG;;|hmQX?CcnoMvF^Su^KQfg&Rt+X{v0GF@5%6H=c}n;tSDBqS&;As{fcnd8)k zQ<^JIXJ=#?8f3hF;S_50dgW_r2`S0hGiJ?N7}I`QcX9!$8f;X}s>jTI3l7d{(qEd0pX>3LFtdvU6CZcV7m2Otr){q9i4;B-JXpC>2OC7#SEE=o%X78W@Hc8CaPZ zTbY<@8<<)d7|eU8w+cl=ZhlH;S|vn-fhAZ2P_>Dbff+=@sp+9>fEpM)UHx3vIVCg! E0I(K3>Hq)$ literal 0 HcmV?d00001 diff --git a/include/images/gqbRemoveRest.pngc b/include/images/gqbRemoveRest.pngc new file mode 100644 index 0000000..23880c8 --- /dev/null +++ b/include/images/gqbRemoveRest.pngc @@ -0,0 +1,136 @@ +#ifndef GQBREMOVEREST_PNG_H +#define GQBREMOVEREST_PNG_H + +static const unsigned char gqbRemoveRest_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0f, +0x08, 0x03, 0x00, 0x00, 0x00, 0x31, 0x9a, 0x04, +0x1e, 0x00, 0x00, 0x01, 0x44, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x95, 0x97, 0xb5, 0x78, +0x7a, 0xb4, 0x70, 0x73, 0xb4, 0xb9, 0xba, 0xd9, +0x81, 0x83, 0xbd, 0xf0, 0xf1, 0xf3, 0xf0, 0xe6, +0xff, 0xe5, 0xd8, 0xfb, 0xdd, 0xd3, 0xf4, 0xd9, +0xcd, 0xf2, 0xd3, 0xc9, 0xec, 0xd0, 0xc2, 0xec, +0xc9, 0xbc, 0xe7, 0xc5, 0xbc, 0xe1, 0xea, 0xe7, +0xf3, 0x70, 0x88, 0xb4, 0xd5, 0xbd, 0xfa, 0xcd, +0xb1, 0xf9, 0xc6, 0xaf, 0xee, 0xc3, 0xa7, 0xf2, +0xb7, 0x9c, 0xe8, 0xad, 0x92, 0xe1, 0xa6, 0x8b, +0xdb, 0x9e, 0x83, 0xd5, 0x96, 0x7c, 0xce, 0x90, +0x75, 0xc9, 0x99, 0x83, 0xcc, 0x88, 0x8a, 0xa8, +0x5a, 0x7a, 0xaa, 0xbb, 0xa7, 0xe3, 0xab, 0x97, +0xd8, 0x8e, 0x73, 0xc8, 0xca, 0x8d, 0x9e, 0xc2, +0x19, 0x1a, 0xa9, 0x67, 0x76, 0xde, 0x6c, 0x6c, +0xc9, 0x21, 0x21, 0xdf, 0x77, 0x77, 0x85, 0x6b, +0xc2, 0xaf, 0x4b, 0x61, 0xd9, 0x3d, 0x3e, 0xc7, +0x24, 0x25, 0xc5, 0x28, 0x28, 0xdc, 0x2e, 0x2e, +0xd2, 0x3b, 0x3b, 0xc3, 0xb5, 0xe1, 0x7d, 0x63, +0xbc, 0xb8, 0x2a, 0x36, 0xd4, 0x36, 0x3a, 0xff, +0x87, 0x87, 0xe8, 0x41, 0x41, 0xc0, 0x23, 0x25, +0xbb, 0x27, 0x2a, 0xdf, 0x31, 0x31, 0xf9, 0x5a, +0x5b, 0xd7, 0x23, 0x23, 0x6f, 0x55, 0xb0, 0xb6, +0xa8, 0xd7, 0xae, 0x38, 0x4a, 0xe1, 0x47, 0x47, +0xfe, 0x7a, 0x7a, 0xdd, 0x39, 0x3a, 0xdf, 0x33, +0x33, 0xfb, 0x5e, 0x5f, 0xde, 0x29, 0x29, 0xd1, +0x35, 0x35, 0xbb, 0xad, 0xdb, 0xaf, 0xa2, 0xd2, +0x84, 0x71, 0xa2, 0xc0, 0x0b, 0x0c, 0xe0, 0x35, +0x36, 0xf4, 0x5d, 0x5d, 0xf2, 0x51, 0x51, 0xdc, +0x2a, 0x2a, 0xcf, 0x34, 0x34, 0x82, 0x72, 0xa4, +0xbe, 0x0d, 0x0e, 0xdf, 0x2e, 0x2e, 0xf1, 0x46, +0x46, 0xdb, 0x22, 0x22, 0xd0, 0x35, 0x35, 0xe4, +0xe4, 0xe4, 0xac, 0x37, 0x4c, 0xde, 0x38, 0x39, +0xfc, 0x5c, 0x5c, 0xdc, 0x29, 0x29, 0xdb, 0x22, +0x23, 0xf5, 0x3c, 0x3c, 0xdb, 0x17, 0x17, 0xd1, +0x33, 0x33, 0xab, 0xad, 0xd3, 0xb6, 0x05, 0x06, +0xd5, 0x20, 0x1f, 0xfd, 0x58, 0x58, 0xd9, 0x1c, +0x1c, 0xb9, 0x26, 0x29, 0xbe, 0x2c, 0x2f, 0xdc, +0x15, 0x15, 0xf0, 0x24, 0x24, 0xd2, 0x0f, 0x0f, +0x9e, 0x34, 0x35, 0xc4, 0x2d, 0x2d, 0xda, 0x20, +0x20, 0xc4, 0x28, 0x28, 0xc9, 0x2b, 0x2c, 0xd3, +0x10, 0x10, 0xd2, 0x3a, 0x3a, 0xc2, 0x43, 0xa1, +0x8a, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0xcd, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0x64, +0x62, 0x46, 0x05, 0x2c, 0x0c, 0x0c, 0xac, 0x6c, +0xec, 0x1c, 0x40, 0xc0, 0xc9, 0xc5, 0xc5, 0xcd, +0xc3, 0xc3, 0xcb, 0xc7, 0xcd, 0xcf, 0xca, 0xc0, +0x20, 0xc0, 0xca, 0x21, 0x28, 0x24, 0x2c, 0x22, +0x2a, 0x2a, 0x26, 0x2e, 0x21, 0x29, 0x25, 0xcd, +0xc7, 0x0a, 0x54, 0xc7, 0x20, 0xc3, 0xca, 0x29, +0x88, 0x24, 0x24, 0xcb, 0x00, 0x02, 0x8c, 0xac, +0x9c, 0xc2, 0x70, 0x21, 0x01, 0x06, 0x06, 0xa8, +0x20, 0x97, 0x1c, 0x8a, 0x2a, 0x10, 0x90, 0x65, +0xe5, 0x96, 0x97, 0x54, 0x90, 0x54, 0x54, 0x52, +0x66, 0x60, 0x50, 0x51, 0x55, 0x83, 0x08, 0xca, +0xb0, 0xca, 0x29, 0xa8, 0xcb, 0x6b, 0x68, 0x6a, +0x31, 0x30, 0x68, 0xeb, 0xe8, 0x42, 0x55, 0x32, +0xeb, 0xa9, 0xeb, 0x1b, 0x18, 0x1a, 0x19, 0x9b, +0x98, 0x9a, 0x99, 0x5b, 0xc0, 0xc5, 0xf4, 0x2d, +0xad, 0xac, 0x6d, 0x6c, 0xed, 0xec, 0x1d, 0x1c, +0x9d, 0x60, 0x62, 0xce, 0x96, 0x96, 0x2e, 0xae, +0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x30, 0x5b, +0x98, 0xad, 0x80, 0x62, 0x3e, 0xbe, 0x7e, 0x9e, +0xfe, 0x01, 0x81, 0x70, 0x31, 0x7e, 0x17, 0x97, +0xa0, 0xe0, 0x90, 0xd0, 0xb0, 0xf0, 0x88, 0xc8, +0x28, 0xa8, 0x58, 0x34, 0xd0, 0xf3, 0x31, 0xb1, +0x71, 0xf1, 0x09, 0x89, 0x49, 0xc9, 0x29, 0x0c, +0x08, 0x90, 0x9a, 0x96, 0x9e, 0xc1, 0xc0, 0x90, +0x99, 0x95, 0x0d, 0x00, 0xbd, 0xaa, 0x1d, 0x9c, +0x04, 0x1b, 0xbb, 0xd3, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *gqbRemoveRest_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_gqbRemoveRest_png = new wxImage(); + if (!img_gqbRemoveRest_png || !img_gqbRemoveRest_png->IsOk()) + { + wxMemoryInputStream img_gqbRemoveRest_pngIS(gqbRemoveRest_png_data, sizeof(gqbRemoveRest_png_data)); + img_gqbRemoveRest_png->LoadFile(img_gqbRemoveRest_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbRemoveRest_png; +} +#define gqbRemoveRest_png_img gqbRemoveRest_png_img() + +static wxBitmap *gqbRemoveRest_png_bmp() +{ + static wxBitmap *bmp_gqbRemoveRest_png; + if (!bmp_gqbRemoveRest_png || !bmp_gqbRemoveRest_png->IsOk()) + bmp_gqbRemoveRest_png = new wxBitmap(*gqbRemoveRest_png_img); + return bmp_gqbRemoveRest_png; +} +#define gqbRemoveRest_png_bmp gqbRemoveRest_png_bmp() + +static wxIcon *gqbRemoveRest_png_ico() +{ + static wxIcon *ico_gqbRemoveRest_png; + if (!ico_gqbRemoveRest_png || !ico_gqbRemoveRest_png->IsOk()) + { + ico_gqbRemoveRest_png = new wxIcon(); + ico_gqbRemoveRest_png->CopyFromBitmap(*gqbRemoveRest_png_bmp); + } + return ico_gqbRemoveRest_png; +} +#define gqbRemoveRest_png_ico gqbRemoveRest_png_ico() + +#endif // GQBREMOVEREST_PNG_H diff --git a/include/images/gqbUp.png b/include/images/gqbUp.png new file mode 100644 index 0000000000000000000000000000000000000000..d780b118bbfeda0ffc01e2872e2cbb744ea6393a GIT binary patch literal 389 zcmeAS@N?(olHy`uVBq!ia0vp@K+M6x3?xN=wEhKBMFBn`u0XnbV`9{7;WPIa@4DQ$ z^k~$!ixs;rH_todKW&fg?ETJL&KK;u(melA;IzGVQ+8WS+G#j_kHyBbnY*sE&OaPH zeXqmR-IkMf8Bf@u)3;r1%5MGjXHw2RSib38;fAw0>rSVyJ)N}rWZbF~Q7cb`tv{1| z^j7Z|Nx2U|TNz7&{DK)Ap4~_TaySb-B8!2v2N=7Z%(eqEygXeTLpZLxo($(}P+(vQ zEIWFy`hC@ZZ7#!8fA;nWSP4Ah-@@aVX)W(~{d4mNRf(gXv!1r9MTC`JF8gbsRW#}I zro7*UapqTzA2O!;GyRX;BXtpIs%nXAL`h0wNvc(HQ7VvPFfuSS&^0vDH82b@GO#i+ zwlXo*HZZj^FqrpFZxxD$-29Zxv`UBu152<5plTB<12c$*Q`1A&05vdpy85}Sb4q9e E0OQA%yZ`_I literal 0 HcmV?d00001 diff --git a/include/images/gqbUp.pngc b/include/images/gqbUp.pngc new file mode 100644 index 0000000..009f17d --- /dev/null +++ b/include/images/gqbUp.pngc @@ -0,0 +1,93 @@ +#ifndef GQBUP_PNG_H +#define GQBUP_PNG_H + +static const unsigned char gqbUp_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x08, +0x08, 0x03, 0x00, 0x00, 0x00, 0x15, 0xf8, 0x85, +0xfd, 0x00, 0x00, 0x00, 0x72, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x61, 0x5a, +0x9b, 0x13, 0xcc, 0xdf, 0xa3, 0xba, 0xd3, 0x81, +0xa5, 0xc5, 0x5a, 0xb6, 0xd1, 0x78, 0xba, 0xd3, +0x83, 0x9e, 0xc2, 0x4f, 0x96, 0xbc, 0x3d, 0x9b, +0xbf, 0x43, 0xb4, 0xcf, 0x70, 0xba, 0xd4, 0x83, +0x9f, 0xc2, 0x51, 0x96, 0xbd, 0x3e, 0x94, 0xbb, +0x38, 0x92, 0xb9, 0x31, 0x97, 0xbc, 0x38, 0xb1, +0xcd, 0x69, 0xba, 0xd4, 0x85, 0x9f, 0xc3, 0x53, +0x97, 0xbd, 0x40, 0x95, 0xbb, 0x39, 0x92, 0xba, +0x33, 0x90, 0xb8, 0x2c, 0x8e, 0xb7, 0x26, 0x94, +0xbb, 0x2f, 0xaf, 0xcc, 0x64, 0xce, 0xe0, 0xa7, +0xb2, 0xce, 0x71, 0xb0, 0xcd, 0x6c, 0xae, 0xcb, +0x67, 0xad, 0xcb, 0x62, 0xab, 0xc9, 0x5e, 0xaa, +0xc8, 0x5a, 0xa9, 0xc8, 0x56, 0xaf, 0xcc, 0x63, +0xc5, 0xda, 0x8d, 0xf4, 0x19, 0x1e, 0xf0, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x4a, 0x49, 0x44, 0x41, +0x54, 0x08, 0xd7, 0x45, 0xc9, 0x57, 0x0e, 0x80, +0x20, 0x00, 0x04, 0x51, 0x76, 0xc5, 0xde, 0x7b, +0xef, 0x7a, 0xff, 0x2b, 0x0a, 0x31, 0xca, 0xfc, +0xbd, 0x8c, 0x10, 0x3a, 0x10, 0xe2, 0x0f, 0xb4, +0x0c, 0x41, 0x69, 0x3b, 0x1f, 0x41, 0xd7, 0xf3, +0x83, 0xf0, 0x25, 0x18, 0xc5, 0x49, 0x9a, 0xe5, +0x85, 0x26, 0x58, 0x56, 0x75, 0xd3, 0x76, 0xfd, +0x30, 0x2a, 0x72, 0x92, 0xf3, 0xb2, 0x6e, 0xfb, +0x71, 0x5e, 0x37, 0xd5, 0x33, 0xe1, 0x01, 0x65, +0x4f, 0x02, 0xff, 0x59, 0xbc, 0x1a, 0xd1, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *gqbUp_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_gqbUp_png = new wxImage(); + if (!img_gqbUp_png || !img_gqbUp_png->IsOk()) + { + wxMemoryInputStream img_gqbUp_pngIS(gqbUp_png_data, sizeof(gqbUp_png_data)); + img_gqbUp_png->LoadFile(img_gqbUp_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbUp_png; +} +#define gqbUp_png_img gqbUp_png_img() + +static wxBitmap *gqbUp_png_bmp() +{ + static wxBitmap *bmp_gqbUp_png; + if (!bmp_gqbUp_png || !bmp_gqbUp_png->IsOk()) + bmp_gqbUp_png = new wxBitmap(*gqbUp_png_img); + return bmp_gqbUp_png; +} +#define gqbUp_png_bmp gqbUp_png_bmp() + +static wxIcon *gqbUp_png_ico() +{ + static wxIcon *ico_gqbUp_png; + if (!ico_gqbUp_png || !ico_gqbUp_png->IsOk()) + { + ico_gqbUp_png = new wxIcon(); + ico_gqbUp_png->CopyFromBitmap(*gqbUp_png_bmp); + } + return ico_gqbUp_png; +} +#define gqbUp_png_ico gqbUp_png_ico() + +#endif // GQBUP_PNG_H diff --git a/include/images/gqbUpTop.png b/include/images/gqbUpTop.png new file mode 100644 index 0000000000000000000000000000000000000000..49ae93604b7c729524335ad3682a35a8b18fdbe5 GIT binary patch literal 347 zcmeAS@N?(olHy`uVBq!ia0vp@K+M6x3?xN=wEhKBfdM`tu0XnbV`9{7;WPIa@4DQ$ z^k~$!ixs=BG|xX2IAyoRq@9Kv&t~qr(mMZe@btY7lXe+T*r79JxBmJwDd!$6-*m2U z!`Ym*r;}Enj9YmkZ2g(!qqlmE`n;C{4P`6|@(X5gcy=QV$l)yTh%5%u9$@TtGTRQw zaP)L>4B@z*oRE;x#OTJxk?)FK#IZ0z|cU~&`8(7 zFvQ5f%EZ{p#8lhB)XKnM-aEZjC>nC}Q!>*kAsP%U!5V<7O{@&eAR10h4_yP)z~JfX K=d#Wzp$Py25_&iQ literal 0 HcmV?d00001 diff --git a/include/images/gqbUpTop.pngc b/include/images/gqbUpTop.pngc new file mode 100644 index 0000000..69ac0a0 --- /dev/null +++ b/include/images/gqbUpTop.pngc @@ -0,0 +1,88 @@ +#ifndef GQBUPTOP_PNG_H +#define GQBUPTOP_PNG_H + +static const unsigned char gqbUpTop_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x08, +0x08, 0x03, 0x00, 0x00, 0x00, 0x15, 0xf8, 0x85, +0xfd, 0x00, 0x00, 0x00, 0x51, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x61, 0x5a, +0x9b, 0x13, 0xcc, 0xdf, 0xa3, 0xba, 0xd3, 0x81, +0xa5, 0xc5, 0x5a, 0xb6, 0xd1, 0x78, 0xba, 0xd4, +0x83, 0x9f, 0xc2, 0x51, 0x94, 0xbb, 0x38, 0x92, +0xb9, 0x31, 0xb1, 0xcd, 0x69, 0xba, 0xd4, 0x85, +0x9f, 0xc3, 0x53, 0x97, 0xbd, 0x40, 0x92, 0xba, +0x33, 0x90, 0xb8, 0x2c, 0x94, 0xbb, 0x2f, 0xaf, +0xcc, 0x64, 0xce, 0xe0, 0xa7, 0xb2, 0xce, 0x71, +0xb0, 0xcd, 0x6c, 0xad, 0xcb, 0x62, 0xab, 0xc9, +0x5e, 0xa9, 0xc8, 0x56, 0xaf, 0xcc, 0x63, 0xc5, +0xda, 0x8d, 0x32, 0x8e, 0x4b, 0xa5, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x41, 0x49, 0x44, 0x41, 0x54, +0x08, 0xd7, 0x63, 0x60, 0x60, 0x64, 0x82, 0x01, +0x46, 0x06, 0x08, 0x60, 0x84, 0xb3, 0xc0, 0x1c, +0x66, 0x04, 0x97, 0x91, 0x89, 0x85, 0x95, 0x0d, +0xc6, 0x65, 0x64, 0x62, 0xe7, 0xe0, 0xe4, 0xe2, +0x86, 0x70, 0x19, 0x99, 0x78, 0x78, 0xf9, 0xf8, +0x05, 0x04, 0x85, 0xc0, 0x5c, 0x26, 0x61, 0x16, +0x11, 0x51, 0x31, 0x71, 0x09, 0x49, 0x29, 0x26, +0xb0, 0x1c, 0xc2, 0x06, 0x00, 0x3a, 0x4b, 0x01, +0xa9, 0x63, 0x1c, 0xbf, 0xf9, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *gqbUpTop_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_gqbUpTop_png = new wxImage(); + if (!img_gqbUpTop_png || !img_gqbUpTop_png->IsOk()) + { + wxMemoryInputStream img_gqbUpTop_pngIS(gqbUpTop_png_data, sizeof(gqbUpTop_png_data)); + img_gqbUpTop_png->LoadFile(img_gqbUpTop_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbUpTop_png; +} +#define gqbUpTop_png_img gqbUpTop_png_img() + +static wxBitmap *gqbUpTop_png_bmp() +{ + static wxBitmap *bmp_gqbUpTop_png; + if (!bmp_gqbUpTop_png || !bmp_gqbUpTop_png->IsOk()) + bmp_gqbUpTop_png = new wxBitmap(*gqbUpTop_png_img); + return bmp_gqbUpTop_png; +} +#define gqbUpTop_png_bmp gqbUpTop_png_bmp() + +static wxIcon *gqbUpTop_png_ico() +{ + static wxIcon *ico_gqbUpTop_png; + if (!ico_gqbUpTop_png || !ico_gqbUpTop_png->IsOk()) + { + ico_gqbUpTop_png = new wxIcon(); + ico_gqbUpTop_png->CopyFromBitmap(*gqbUpTop_png_bmp); + } + return ico_gqbUpTop_png; +} +#define gqbUpTop_png_ico gqbUpTop_png_ico() + +#endif // GQBUPTOP_PNG_H diff --git a/include/images/group.png b/include/images/group.png new file mode 100644 index 0000000000000000000000000000000000000000..819ff810f49f937fc3fc6d1d85a01a2f4bd81277 GIT binary patch literal 804 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47|R2ELR^8|RjXDN78WKY#xGqs z@z#}{H?QnmvT)Luw`V_t(7Cy@d*WiE`Wp(j&uiH+zj;zq;iq@!rcLcQwWjyX+MaXk zdMJ8iY3zcY9Lin^r4qxRXcW1p1&wFH$NjcziZCY*_-yH=N4|hn{@O?@_|o@|8Gs7 zzIf@SmmkhP|9JB0$0LtF?tl1k_x+FEOJWXxOFZ;7;s5oCJ5OKOcK6eQ1DCSP!Vi9l zpFMl_|7(3w5n-nuzukQM)4FT#A|gY-TX+irgPyS@$S;_|;n|HeAcwQSBeEDsdw{Xq z$!t3yV~E7%=HoYyb4lx5Zzsn<&q&u$-&kgq1uK{8E?Kd7_453Lj1-sX#dM?^_RGygQ(R`!kWl*7KolQ(y-mS%3=-M)AEbgl{S-#&iy`g#6g0f85i zB5Se|UOo{PdL=IQ?wr6wNfAj=Sz&4M`4eVLnIm*SKyZrG#A)*;&YU_|c>e6^@&^Sb zMhOIRJQEk4{$#qF!4%gi;UP^wL$8`H6-?!E5L5{`#=v0l(|FM{-7kSa|EiX_MwFx^ zmZVxG7o`Fz1|tJQ16@NST?4}qBLgcFV=EI=Z39y)1A}?*^j4v0$jwj5Osj-wFt7w` c0ID{zGBAT^I5jmdKI;Vst0Cs_b9RL6T literal 0 HcmV?d00001 diff --git a/include/images/group.pngc b/include/images/group.pngc new file mode 100644 index 0000000..566091c --- /dev/null +++ b/include/images/group.pngc @@ -0,0 +1,145 @@ +#ifndef GROUP_PNG_H +#define GROUP_PNG_H + +static const unsigned char group_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x77, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x71, +0x71, 0x71, 0x62, 0x61, 0x5f, 0xa5, 0xa1, 0x91, +0xda, 0xd4, 0xb9, 0xd9, 0xd4, 0xb9, 0xa4, 0xa1, +0x92, 0xf4, 0xed, 0xcd, 0xf3, 0xed, 0xcd, 0xf3, +0xed, 0xce, 0x9d, 0x9b, 0x8c, 0x5e, 0x5c, 0x5a, +0x8f, 0x80, 0x71, 0xb7, 0x9e, 0x84, 0xb8, 0x9f, +0x83, 0x92, 0x82, 0x71, 0xf2, 0xee, 0xce, 0x96, +0x95, 0x88, 0xca, 0xac, 0x8d, 0xcc, 0xad, 0x8c, +0xce, 0xae, 0x8c, 0xd1, 0xb0, 0x8c, 0x94, 0x84, +0x70, 0xe4, 0xe0, 0xc3, 0xa3, 0xa1, 0x92, 0x59, +0x58, 0x58, 0x65, 0x61, 0x5d, 0x90, 0x81, 0x70, +0xc3, 0xa6, 0x87, 0xd3, 0xb2, 0x8b, 0xc0, 0xa4, +0x82, 0x62, 0x61, 0x60, 0xa7, 0xa0, 0x99, 0xdd, +0xd1, 0xc8, 0xdd, 0xd1, 0xca, 0xa6, 0xa0, 0x9c, +0x62, 0x61, 0x61, 0xc8, 0xaa, 0x86, 0xd5, 0xb3, +0x8b, 0xc2, 0xa5, 0x81, 0xbf, 0xbf, 0xbf, 0x62, +0x62, 0x5f, 0xa4, 0xa2, 0x92, 0xf8, 0xea, 0xdf, +0xf8, 0xea, 0xe1, 0xf7, 0xea, 0xe3, 0xf7, 0xea, +0xe6, 0xa6, 0xa0, 0x9f, 0x95, 0x84, 0x70, 0xd8, +0xb5, 0x8a, 0x98, 0x86, 0x70, 0x73, 0x6e, 0x65, +0xc5, 0xb2, 0x8f, 0xaa, 0x9a, 0x7f, 0x5a, 0x59, +0x57, 0xf7, 0xea, 0xe8, 0xdc, 0xd1, 0xd2, 0x67, +0x62, 0x5c, 0x60, 0x5d, 0x5a, 0xa7, 0xa7, 0xa7, +0xad, 0x9e, 0x83, 0xff, 0xe0, 0xaa, 0xff, 0xdf, +0xa7, 0x71, 0x6b, 0x61, 0xf7, 0xea, 0xeb, 0xdc, +0xd1, 0xd4, 0x58, 0x5a, 0x56, 0x90, 0xaa, 0x5f, +0xa2, 0xc4, 0x62, 0x69, 0x72, 0x58, 0x78, 0x78, +0x78, 0xdc, 0xc4, 0x99, 0xff, 0xdd, 0xa0, 0xaa, +0x98, 0x79, 0xf7, 0xea, 0xed, 0xa6, 0xa0, 0xa2, +0xca, 0xfd, 0x68, 0xc8, 0xfb, 0x66, 0x90, 0xaa, +0x5d, 0x5a, 0x5a, 0x5a, 0xfa, 0xdb, 0xa5, 0xff, +0xdc, 0x9d, 0xbf, 0xa8, 0x7e, 0x62, 0x61, 0x62, +0x9e, 0xbe, 0x61, 0xc7, 0xfa, 0x65, 0xae, 0xd7, +0x60, 0x55, 0x55, 0x55, 0xe1, 0xc3, 0x8b, 0x6c, +0x70, 0x70, 0xaa, 0xb8, 0xbb, 0x93, 0x9f, 0xa2, +0x69, 0x6d, 0x6f, 0x68, 0x6d, 0x6f, 0x8a, 0x9c, +0xa5, 0x9b, 0xb2, 0xbc, 0x67, 0x6d, 0x71, 0xb3, +0xdd, 0x62, 0xc5, 0xf8, 0x63, 0xc0, 0xf2, 0x61, +0xff, 0xda, 0x97, 0x97, 0xa3, 0xa5, 0xd2, 0xe9, +0xf0, 0xcd, 0xe7, 0xf1, 0xc9, 0xe5, 0xf1, 0xc4, +0xe3, 0xf1, 0xbf, 0xe1, 0xf1, 0xbb, 0xdf, 0xf1, +0x8b, 0xa4, 0x5c, 0xc3, 0xf6, 0x61, 0xc2, 0xf5, +0x60, 0xff, 0xd7, 0x91, 0xb9, 0xcb, 0xd0, 0xb6, +0xdd, 0xf2, 0xa0, 0xc0, 0xd2, 0x6b, 0x76, 0x57, +0xc1, 0xf4, 0x5f, 0x9b, 0x9b, 0x9b, 0xff, 0xd6, +0x8e, 0x5a, 0x58, 0x56, 0xca, 0xe3, 0xed, 0xb3, +0xdb, 0xf2, 0xae, 0xd6, 0xee, 0x58, 0x59, 0x55, +0xf7, 0x38, 0x4b, 0x12, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0xe4, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x63, 0x60, 0x60, 0x60, 0x60, 0x64, 0x62, 0x62, +0x64, 0x40, 0x02, 0xcc, 0x2c, 0xac, 0x6c, 0xec, +0x48, 0xc2, 0x8c, 0x2c, 0x1c, 0x9c, 0x5c, 0x5c, +0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x3c, 0x20, +0x01, 0x26, 0x56, 0x20, 0x5f, 0x50, 0x88, 0x57, +0x58, 0x44, 0x54, 0x4c, 0x1c, 0xa4, 0x86, 0x89, +0x8d, 0x8b, 0x4b, 0x42, 0x52, 0x4a, 0x5a, 0x46, +0x56, 0x4c, 0x4e, 0x9e, 0x09, 0xa4, 0x85, 0x9d, +0x4b, 0x42, 0x41, 0x51, 0x49, 0x59, 0x45, 0x55, +0x4d, 0x5d, 0x03, 0x24, 0xa0, 0xa9, 0xa5, 0x2d, +0xa4, 0xa8, 0xa3, 0xab, 0xa7, 0x6f, 0x60, 0x68, +0x64, 0x0c, 0xd2, 0x62, 0x62, 0x6a, 0x66, 0xae, +0x04, 0xe4, 0x5b, 0x58, 0x5a, 0x19, 0x5b, 0x03, +0xf9, 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0xca, 0x40, +0xbe, 0xa3, 0x93, 0xb3, 0x8b, 0xab, 0x1b, 0x03, +0x83, 0xbb, 0x87, 0xbd, 0xa7, 0x97, 0x0a, 0x90, +0xef, 0xed, 0xe3, 0xe2, 0xeb, 0xe7, 0x6f, 0xc3, +0x10, 0x10, 0xe8, 0x19, 0x14, 0xac, 0x6a, 0x60, +0xe9, 0xe4, 0x13, 0x12, 0xea, 0x17, 0x16, 0xee, +0xce, 0x10, 0xe1, 0x19, 0x14, 0x19, 0x15, 0x1d, +0x13, 0x1b, 0x17, 0x9f, 0x90, 0x98, 0x94, 0x9c, +0x12, 0xc0, 0x10, 0x11, 0x94, 0x1a, 0x91, 0x96, +0x9e, 0x91, 0x99, 0x95, 0x9d, 0x13, 0x9f, 0x9b, +0x97, 0x1f, 0xc1, 0x10, 0x91, 0x5a, 0x10, 0x51, +0x08, 0xe6, 0x17, 0x15, 0x97, 0xe4, 0x97, 0x46, +0x30, 0x94, 0x45, 0x94, 0x57, 0x54, 0x82, 0xf9, +0x55, 0xd5, 0x35, 0xa5, 0x11, 0x65, 0x0c, 0x40, +0x11, 0x24, 0x50, 0xc6, 0x00, 0x00, 0x38, 0xf9, +0x33, 0xa2, 0xe6, 0x2d, 0xf4, 0x51, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *group_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_group_png = new wxImage(); + if (!img_group_png || !img_group_png->IsOk()) + { + wxMemoryInputStream img_group_pngIS(group_png_data, sizeof(group_png_data)); + img_group_png->LoadFile(img_group_pngIS, wxBITMAP_TYPE_PNG); + } + return img_group_png; +} +#define group_png_img group_png_img() + +static wxBitmap *group_png_bmp() +{ + static wxBitmap *bmp_group_png; + if (!bmp_group_png || !bmp_group_png->IsOk()) + bmp_group_png = new wxBitmap(*group_png_img); + return bmp_group_png; +} +#define group_png_bmp group_png_bmp() + +static wxIcon *group_png_ico() +{ + static wxIcon *ico_group_png; + if (!ico_group_png || !ico_group_png->IsOk()) + { + ico_group_png = new wxIcon(); + ico_group_png->CopyFromBitmap(*group_png_bmp); + } + return ico_group_png; +} +#define group_png_ico group_png_ico() + +#endif // GROUP_PNG_H diff --git a/include/images/groups.png b/include/images/groups.png new file mode 100644 index 0000000000000000000000000000000000000000..62d0b82661186a73af51738708ab55ec9b544620 GIT binary patch literal 757 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47+nH<_9T^+TBg@u)6#TSn5xo~t}cYEvSw`V`UJ$L%VhU&tMHPhWWSIyhJr*XpchK7bK z`=ZQL_|_o?XU=%2Ti99`EE9}`hrn15jV z=EB;jg@+O*t=_S4;ljws$fffaj}J!{Q1# zJsCAKB_k~>4Hq;pNzY$2X;ashRkL>OX;Wivp0=%Tom{~7eX|-DPTbfj*1U4&PS)j1 zJ625H+Pik{-e%3_#gjL8ubw?;&u;b;X8!JM`uP*sD7p0L0#R9EY4$4*($nPTPneN%Dq+@~ zNwdUWB)odT@??3sg^@)X)6dA8eQ|xK93H$l%8>5B$nbf;TKcVx&n^M|tXkq4QIe8a zl4_M)lnSI6j0_A7bPbJk4Gcq!46ICytxQa{4NR>J4CcMlTZN(_H$NpatrDWaz!Izh bsM^HJzzm|{)b!9bKn)C@u6{1-oD!MIsOk()) + { + wxMemoryInputStream img_groups_pngIS(groups_png_data, sizeof(groups_png_data)); + img_groups_png->LoadFile(img_groups_pngIS, wxBITMAP_TYPE_PNG); + } + return img_groups_png; +} +#define groups_png_img groups_png_img() + +static wxBitmap *groups_png_bmp() +{ + static wxBitmap *bmp_groups_png; + if (!bmp_groups_png || !bmp_groups_png->IsOk()) + bmp_groups_png = new wxBitmap(*groups_png_img); + return bmp_groups_png; +} +#define groups_png_bmp groups_png_bmp() + +static wxIcon *groups_png_ico() +{ + static wxIcon *ico_groups_png; + if (!ico_groups_png || !ico_groups_png->IsOk()) + { + ico_groups_png = new wxIcon(); + ico_groups_png->CopyFromBitmap(*groups_png_bmp); + } + return ico_groups_png; +} +#define groups_png_ico groups_png_ico() + +#endif // GROUPS_PNG_H diff --git a/include/images/help.png b/include/images/help.png new file mode 100644 index 0000000000000000000000000000000000000000..5d9805f5efdaf0e7af5fa0d05e4c87e1d8698a7f GIT binary patch literal 651 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47{vp8LR^8|9f$fBZ1tJ4PJ6}9 zqyxv796hyh&7R!tXX38EY<=>*|IxSZ$KU%;->+D8$Y<@I{IlndpSWG|_)eBehu@m+d?~p9wQk#)=zUjGZhp?c`Z4j==dvxQqmJDwe)4_NowpO`YRoR(}4zwo5#?$@?EpBpc~Xx)0S_2!%Y+n?)ieXhIl zrswkO$_wvf&cBbo_^Ry2o8FtBYj1w4x&Ee0h_5#Q7&MF}L4Lsu4$p3+0Xdun9+AaB z+5?Q;PG;Ky8LK^A977~7Cnqp4xv8b4rHO^HX(S{+fAHkdvxiR~i#Kp=;O64&?&#|D z_W0ENb4}1CqfJGhxVpSfX{}OV6f-U5_0>(wm5sHnb=%M>!`9|@?2p>Av}Xd0Y;I*~ z$#vY`+S$_4p)*|nOqy19?Hga8f!*rKo2PE=*0%3Cf8f!xcMo5-J}|EM{o~h9W5pjl zjK|KLImYP0bga?wpyII;ObZhq3TiM-47_M~%;F3KL+WbLbDynRcLSZRTH+c}l9E`G zYL#4+3Zxi}3=9o*4GeV+%|i@Ltc*;o49&F-%&ZIy9_+6EhN2-iKP5A*5~RUE*T52} iC&b9u%EZLVz)ah~6sY0U^w2dx4Gf;HelF{r5}E)7lR_u} literal 0 HcmV?d00001 diff --git a/include/images/help.pngc b/include/images/help.pngc new file mode 100644 index 0000000..1d4b8c2 --- /dev/null +++ b/include/images/help.pngc @@ -0,0 +1,126 @@ +#ifndef HELP_PNG_H +#define HELP_PNG_H + +static const unsigned char help_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x17, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xb8, 0xc2, 0x8e, 0xa0, +0xb5, 0x4c, 0x94, 0xae, 0x2b, 0xa8, 0xb9, 0x62, +0xc0, 0xc7, 0xa4, 0xc5, 0xca, 0xb1, 0xac, 0xbc, +0x6d, 0xb7, 0xcc, 0x5e, 0xd7, 0xe9, 0x85, 0xe4, +0xf7, 0x8f, 0xe2, 0xf6, 0x8b, 0xe3, 0xf7, 0x8f, +0xcb, 0xdf, 0x78, 0xaa, 0xc2, 0x4c, 0xad, 0xbc, +0x6f, 0xcd, 0xce, 0xc7, 0xc8, 0xdb, 0x78, 0xe3, +0xf7, 0x87, 0xde, 0xf5, 0x74, 0xdb, 0xf4, 0x6e, +0xda, 0xf4, 0x6b, 0xda, 0xf3, 0x6c, 0xdb, 0xf4, +0x72, 0xdf, 0xf5, 0x84, 0xbb, 0xd0, 0x63, 0xab, +0xc2, 0x4d, 0xe3, 0xf7, 0x8a, 0xdd, 0xf4, 0x70, +0xdc, 0xf4, 0x71, 0xde, 0xf5, 0x7c, 0xdf, 0xf5, +0x81, 0xdc, 0xf4, 0x76, 0xd8, 0xf2, 0x69, 0xd7, +0xf2, 0x67, 0xdf, 0xf4, 0x86, 0x9f, 0xb8, 0x3b, +0xc8, 0xcb, 0xba, 0xce, 0xe0, 0x80, 0xe1, 0xf6, +0x82, 0xdc, 0xf4, 0x70, 0xdf, 0xf5, 0x7e, 0xb6, +0xcc, 0x5b, 0xbe, 0xd4, 0x64, 0xd9, 0xf3, 0x6f, +0xd5, 0xf1, 0x61, 0xda, 0xf3, 0x76, 0xb4, 0xcb, +0x5a, 0xc6, 0xda, 0x73, 0xe4, 0xf7, 0x92, 0xdc, +0xed, 0x91, 0x9c, 0xb3, 0x41, 0xb9, 0xd0, 0x5e, +0xd8, 0xf2, 0x6e, 0xd4, 0xf1, 0x60, 0xd9, 0xf3, +0x75, 0xb5, 0xcb, 0x5b, 0xdc, 0xf3, 0x7c, 0xd5, +0xf1, 0x63, 0xd4, 0xf2, 0x63, 0xd8, 0xef, 0x7e, +0x9f, 0xb8, 0x3a, 0xd5, 0xf1, 0x64, 0xda, 0xf3, +0x7b, 0xb4, 0xcb, 0x59, 0xb1, 0xbe, 0x7a, 0xaa, +0xc1, 0x4b, 0xde, 0xf4, 0x81, 0xdb, 0xf3, 0x7e, +0xa9, 0xc1, 0x4a, 0xca, 0xde, 0x78, 0xd8, 0xf2, +0x6d, 0xd3, 0xf1, 0x5f, 0xd8, 0xf2, 0x75, 0xa4, +0xbc, 0x42, 0xa4, 0xb7, 0x57, 0xd0, 0xe4, 0x82, +0xdd, 0xf5, 0x86, 0xdc, 0xf3, 0x81, 0xd3, 0xe8, +0x85, 0xb5, 0xc1, 0x85, 0xd9, 0xec, 0x8f, 0xdb, +0xf3, 0x7f, 0xda, 0xf3, 0x7e, 0xd8, 0xec, 0x8c, +0xd3, 0xeb, 0x79, 0xd0, 0xef, 0x5c, 0xcf, 0xef, +0x5b, 0xd1, 0xea, 0x76, 0xd8, 0xec, 0x8d, 0xd9, +0xf3, 0x7d, 0xd9, 0xf2, 0x7c, 0xd7, 0xec, 0x8a, +0x12, 0x0e, 0x8d, 0x50, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0xab, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x63, 0x60, 0x00, 0x02, 0x46, 0x26, 0x66, 0x66, +0x66, 0x16, 0x56, 0x06, 0x28, 0x60, 0x63, 0xe7, +0xe0, 0xe4, 0xe2, 0xe6, 0xe1, 0xe5, 0xe3, 0x17, +0x80, 0x08, 0xb0, 0x0b, 0x0a, 0x09, 0x8b, 0x88, +0x8a, 0x89, 0x4b, 0x48, 0xf2, 0x83, 0xf9, 0xac, +0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, +0x4a, 0xca, 0x2a, 0xaa, 0x20, 0x01, 0x16, 0x35, +0x75, 0x0d, 0x4d, 0x2d, 0x66, 0x6d, 0x1d, 0x5d, +0x3d, 0x7d, 0x46, 0xb0, 0x89, 0x1c, 0x06, 0x86, +0x46, 0xc6, 0xfc, 0x26, 0xa6, 0x66, 0xe6, 0x10, +0x01, 0x06, 0x46, 0x76, 0x66, 0x63, 0x7e, 0x0b, +0x4b, 0x2b, 0x6b, 0x1b, 0x5b, 0x55, 0x98, 0x45, +0xfc, 0x92, 0x96, 0x76, 0xd6, 0xf6, 0x0e, 0x8e, +0x30, 0x3e, 0xab, 0x93, 0xb3, 0x95, 0xb5, 0x8b, +0x2b, 0x3f, 0x8c, 0xcf, 0xc0, 0xe2, 0xe6, 0xee, +0xe1, 0xe9, 0x85, 0xe0, 0x33, 0x78, 0xfb, 0xf8, +0xfa, 0xf9, 0x33, 0x21, 0xf8, 0x0c, 0x01, 0xc6, +0xcc, 0xcc, 0xc6, 0x01, 0x48, 0x02, 0xc6, 0x81, +0x41, 0xc1, 0x21, 0xc6, 0xc8, 0x02, 0xa1, 0x61, +0xe1, 0x11, 0x28, 0x02, 0x91, 0x51, 0xd1, 0x31, +0xc6, 0x38, 0xcc, 0x00, 0x00, 0x65, 0xab, 0x15, +0xce, 0xf3, 0x3a, 0x85, 0xbb, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x31, 0x2d, 0x30, 0x31, +0x2d, 0x31, 0x37, 0x54, 0x31, 0x34, 0x3a, 0x32, +0x34, 0x3a, 0x31, 0x37, 0x2b, 0x30, 0x36, 0x3a, +0x30, 0x30, 0xe0, 0xbb, 0x7b, 0xf6, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *help_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_help_png = new wxImage(); + if (!img_help_png || !img_help_png->IsOk()) + { + wxMemoryInputStream img_help_pngIS(help_png_data, sizeof(help_png_data)); + img_help_png->LoadFile(img_help_pngIS, wxBITMAP_TYPE_PNG); + } + return img_help_png; +} +#define help_png_img help_png_img() + +static wxBitmap *help_png_bmp() +{ + static wxBitmap *bmp_help_png; + if (!bmp_help_png || !bmp_help_png->IsOk()) + bmp_help_png = new wxBitmap(*help_png_img); + return bmp_help_png; +} +#define help_png_bmp help_png_bmp() + +static wxIcon *help_png_ico() +{ + static wxIcon *ico_help_png; + if (!ico_help_png || !ico_help_png->IsOk()) + { + ico_help_png = new wxIcon(); + ico_help_png->CopyFromBitmap(*help_png_bmp); + } + return ico_help_png; +} +#define help_png_ico help_png_ico() + +#endif // HELP_PNG_H diff --git a/include/images/help2.png b/include/images/help2.png new file mode 100644 index 0000000000000000000000000000000000000000..ff6d4d026b9e1aecd04ef9481a4f6a4baee701dc GIT binary patch literal 947 zcmV;k15EshP){iNVr*ufA=kzE0lk zqv-gYiMUoxK_Z(n6tom;r4yp^ljVpY}xZ^ z*z;%M^@`Z$p2W(c$jq#vxI*Xksn_yl*YaoH^@7vkn5w&A&fSmW_lMTX0#hUE8}<@cWA_Kn-~bk*@;)bU{5^nb_KhqAzSmI!-CP_kk#>J((zu`@@?PlpWO3);PRT)@nX~QVBzwf;PsH#@@mxbWZLSS#@B(; z;gs9+dd<(cowGpS?x51~UDNPk-SLs;@x9~rnc(cP%+I#r^_K4W#L)0r&+k~z?^n+6 zR^auO;PjN=^^VQ%Rp0cJE-1Tr00001bW%=J06^y0W&i*H32;bRa{vGUNB{r;NB~C3 zYd!z~0cuG^K~y-)V_={rU}R!u0RdJfHf+-D%p9Ct+&nxyynOsD0+>n!1cih}M8(7< zB&9^9W%y;~(B$O>xfR3|m4Ncf$|@>Ss%o<8DDoPbS_+DAd2MYST|Ipi1*`^!Vo35v z#wMm_8c6cy7BZF~c}pv68(TY|yuE{?lQWV6CQcWyysH}vi=ev{P~OASixt@hZxN9B zKE6QjG5PrelXV2HGc(v9{Ah>4A} zFvk*_YyyID@nHD`vq-G+{MO-#9sx<=$!7A{qC z=+@8l1j@%`We8+rPY*e{sU87&`2`j@Jt2$TLLdfCB@E1Be08-~@&z zc2J@jYHDg)T3W_}Q$b33c|~PaH9iGE`KlV+3Ti>}b@&v38jD+sNwuBoZV=}3a! zBohDto)}Fy#(PKC0000bbVXQnWMOn=I%9HWVRU5xGB7bPEip1JFfmjzFgi3dIy5ya zFf}?bFrMx%ssI20C3HntbYx+4WjbwdWNBu305UK!FfA}SEif@uGBY|fG&(RgD=;-W VFfhuORjdF2002ovPDHLkV1kjH=#>Bf literal 0 HcmV?d00001 diff --git a/include/images/help2.pngc b/include/images/help2.pngc new file mode 100644 index 0000000..f8f0ce5 --- /dev/null +++ b/include/images/help2.pngc @@ -0,0 +1,163 @@ +#ifndef HELP2_PNG_H +#define HELP2_PNG_H + +static const unsigned char help2_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x08, 0x03, 0x00, 0x00, 0x00, 0x44, 0xa4, 0x8a, +0xc6, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc4, 0xca, 0xa0, 0xb7, +0xc2, 0x80, 0xa1, 0xb6, 0x4b, 0x94, 0xae, 0x2b, +0xae, 0xbd, 0x6b, 0xd1, 0xd2, 0xc2, 0xbc, 0xc5, +0x8d, 0xae, 0xc3, 0x5a, 0xc2, 0xd2, 0x7d, 0xdd, +0xeb, 0xa0, 0xeb, 0xf9, 0xaa, 0xe8, 0xf8, 0xa2, +0xeb, 0xf9, 0xad, 0xcc, 0xdc, 0x89, 0xc1, 0xd2, +0x7c, 0xaf, 0xbe, 0x6d, 0xa7, 0xbe, 0x4e, 0xde, +0xec, 0xa3, 0xe8, 0xf8, 0x9c, 0xe3, 0xf6, 0x88, +0xdf, 0xf5, 0x7a, 0xdc, 0xf4, 0x6e, 0xdb, 0xf4, +0x6b, 0xda, 0xf4, 0x6b, 0xda, 0xf4, 0x6a, 0xd9, +0xf3, 0x6e, 0xe1, 0xf6, 0x8a, 0xea, 0xf9, 0xa7, +0xa5, 0xb8, 0x56, 0xc0, 0xc8, 0x98, 0xb3, 0xc0, +0x78, 0xe1, 0xf6, 0x7d, 0xdc, 0xf4, 0x6d, 0xdb, +0xf4, 0x6c, 0xd9, 0xf3, 0x69, 0xd8, 0xf3, 0x67, +0xe1, 0xf5, 0x8a, 0xd8, 0xe6, 0x9e, 0xc4, 0xca, +0xa2, 0xc8, 0xcc, 0xac, 0xa1, 0xb8, 0x42, 0xe7, +0xf5, 0xa9, 0xd7, 0xf2, 0x65, 0xd7, 0xf2, 0x67, +0xde, 0xf5, 0x82, 0xd3, 0xe1, 0x98, 0xaa, 0xbb, +0x60, 0xce, 0xdd, 0x8f, 0xe3, 0xf7, 0x87, 0xd6, +0xf2, 0x63, 0xd5, 0xf2, 0x62, 0xd6, 0xf1, 0x66, +0xe2, 0xf6, 0x97, 0xa7, 0xbd, 0x4d, 0xd1, 0xd1, +0xc0, 0x9a, 0xb3, 0x37, 0xdc, 0xf5, 0x72, 0xe0, +0xf5, 0x86, 0xe4, 0xf7, 0x9a, 0xe5, 0xf7, 0x9e, +0xe2, 0xf6, 0x8d, 0xdb, 0xf3, 0x74, 0xd5, 0xf1, +0x61, 0xd4, 0xf1, 0x60, 0xdd, 0xf4, 0x7f, 0xc7, +0xd7, 0x87, 0xb2, 0xc0, 0x76, 0xe4, 0xf6, 0x8e, +0xe4, 0xf6, 0x95, 0xc1, 0xd2, 0x7b, 0xdc, 0xed, +0x91, 0xd4, 0xf1, 0x5f, 0xda, 0xf3, 0x77, 0xcc, +0xdc, 0x8d, 0xcf, 0xdd, 0x93, 0xe0, 0xf5, 0x83, +0xc0, 0xd2, 0x77, 0xbf, 0xd1, 0x73, 0xdb, 0xf4, +0x78, 0xd3, 0xf1, 0x5e, 0xd9, 0xf3, 0x77, 0xbb, +0xcd, 0x71, 0xee, 0xfa, 0xb9, 0xe7, 0xf7, 0xa1, +0xee, 0xf9, 0xbf, 0xd3, 0xe5, 0x8e, 0xd9, 0xf2, +0x70, 0xde, 0xf4, 0x86, 0xb7, 0xc3, 0x82, 0xd1, +0xe1, 0x90, 0xd5, 0xf1, 0x65, 0xd2, 0xf1, 0x5e, +0xd7, 0xf2, 0x6d, 0xdf, 0xee, 0x9f, 0xdc, 0xf3, +0x7e, 0xe0, 0xf2, 0x9a, 0xd5, 0xf1, 0x62, 0xd3, +0xf1, 0x60, 0xe1, 0xf2, 0x9e, 0xe0, 0xf5, 0x90, +0xd7, 0xf2, 0x6a, 0xd4, 0xf2, 0x64, 0xda, 0xea, +0x9c, 0xc6, 0xd7, 0x81, 0xd2, 0xe1, 0x94, 0xdb, +0xf3, 0x7a, 0xcd, 0xcf, 0xb8, 0x9d, 0xb3, 0x40, +0xdf, 0xee, 0xa0, 0xd2, 0xf1, 0x5d, 0xd3, 0xf0, +0x61, 0xdd, 0xf1, 0x91, 0xe6, 0xf1, 0xbd, 0xe3, +0xf6, 0x99, 0xe0, 0xec, 0xb1, 0xcc, 0xcf, 0xb6, +0xe1, 0xf5, 0x96, 0xee, 0xf9, 0xc4, 0xd0, 0xf0, +0x59, 0xcf, 0xef, 0x58, 0xcf, 0xef, 0x57, 0xce, +0xef, 0x56, 0xe0, 0xf5, 0x95, 0xe0, 0xf4, 0x94, +0xdf, 0xf5, 0x8e, 0xcd, 0xee, 0x55, 0xdf, 0xf4, +0x93, 0x2e, 0x28, 0xbb, 0x78, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x01, 0x6a, 0x49, 0x44, 0x41, 0x54, 0x38, +0xcb, 0x63, 0x60, 0xa0, 0x26, 0x60, 0x64, 0x62, +0x66, 0x01, 0x01, 0x56, 0x26, 0x36, 0x6c, 0xd2, +0xec, 0xcc, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0x3c, +0x3c, 0xbc, 0x7c, 0xfc, 0x2c, 0x02, 0x98, 0x4a, +0x04, 0x04, 0x85, 0x84, 0x45, 0x44, 0xc5, 0xc4, +0x25, 0x24, 0xa5, 0x44, 0xa5, 0x65, 0xf8, 0x65, +0xe5, 0xd0, 0xe4, 0xe5, 0x05, 0xb9, 0x15, 0xc4, +0x14, 0x95, 0x80, 0xf2, 0xca, 0xca, 0x2a, 0x2a, +0x52, 0xaa, 0x6a, 0xb2, 0xea, 0x28, 0xf2, 0x1a, +0x9a, 0x5a, 0x0a, 0x8a, 0x70, 0x79, 0x6d, 0x6d, +0x1d, 0x5d, 0x3d, 0x7d, 0x14, 0x05, 0xac, 0x06, +0x86, 0x62, 0x48, 0xf2, 0x46, 0xc6, 0x26, 0xa6, +0x66, 0x1a, 0x48, 0xf2, 0xe6, 0x16, 0x32, 0x96, +0x20, 0x79, 0x4b, 0x2b, 0x6b, 0x1b, 0x5b, 0x3b, +0xa0, 0xbc, 0xbd, 0x83, 0xa3, 0x93, 0x33, 0x92, +0x02, 0x26, 0x4e, 0x17, 0xb0, 0xbc, 0xab, 0x1b, +0x0b, 0x8b, 0xa0, 0xbb, 0x14, 0x50, 0xde, 0xc3, +0xd3, 0x8b, 0x15, 0xd9, 0x06, 0x6f, 0x11, 0x90, +0xf9, 0x3e, 0xbe, 0x40, 0xef, 0x31, 0xf9, 0xf9, +0x03, 0xe5, 0x03, 0x02, 0x51, 0x14, 0xb0, 0x07, +0x05, 0x03, 0x03, 0x20, 0x24, 0x54, 0x50, 0x83, +0x41, 0x5d, 0x36, 0x2c, 0x1c, 0x28, 0x1f, 0x10, +0xe1, 0xc6, 0x84, 0x12, 0x0a, 0xe0, 0x20, 0x64, +0x11, 0x60, 0x88, 0xb4, 0x88, 0xd2, 0x8d, 0xf6, +0x08, 0x88, 0x89, 0x8d, 0xb3, 0x30, 0xc7, 0x12, +0x9a, 0x6c, 0x02, 0x82, 0x71, 0xf1, 0x60, 0xf9, +0x04, 0xb3, 0x48, 0xac, 0xf2, 0xfc, 0xd6, 0xe1, +0x89, 0x1e, 0x01, 0x49, 0xe1, 0xc9, 0x66, 0xf2, +0xd8, 0xa2, 0x43, 0x80, 0x3f, 0x25, 0x15, 0x68, +0x7f, 0x5a, 0x7c, 0xba, 0x26, 0x56, 0x79, 0x46, +0x0e, 0x6b, 0xb0, 0x7c, 0x44, 0x06, 0x33, 0x3b, +0xd6, 0xe8, 0xd6, 0xcf, 0xf4, 0x04, 0xca, 0xc7, +0x64, 0x65, 0x08, 0x64, 0x63, 0x4f, 0x0f, 0x39, +0xb9, 0xa9, 0x1e, 0x01, 0x79, 0xf9, 0x05, 0x16, +0x38, 0xe4, 0x19, 0x72, 0x0a, 0x43, 0x8a, 0x8a, +0x8a, 0x6c, 0x8a, 0x99, 0x71, 0xc8, 0x33, 0x44, +0xe6, 0x80, 0x03, 0x03, 0x87, 0x03, 0x88, 0x01, +0xd0, 0xe0, 0x04, 0x86, 0x27, 0x76, 0x50, 0xa2, +0x19, 0x6a, 0x6a, 0x6a, 0x5a, 0x5a, 0x5a, 0xc6, +0x82, 0x53, 0x41, 0x4a, 0x79, 0x79, 0x45, 0x65, +0x55, 0x35, 0x3e, 0x05, 0x40, 0xf9, 0xaa, 0x1a, +0xdc, 0x0a, 0x6a, 0x41, 0xf2, 0x75, 0xf8, 0x14, +0x80, 0xe4, 0xeb, 0xea, 0x71, 0x2b, 0x08, 0xad, +0xae, 0xae, 0xa9, 0xa9, 0xc7, 0xe9, 0x48, 0x82, +0xde, 0x24, 0x13, 0x00, 0x00, 0x9e, 0x18, 0x4d, +0x38, 0xc6, 0x7b, 0x47, 0xd7, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *help2_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_help2_png = new wxImage(); + if (!img_help2_png || !img_help2_png->IsOk()) + { + wxMemoryInputStream img_help2_pngIS(help2_png_data, sizeof(help2_png_data)); + img_help2_png->LoadFile(img_help2_pngIS, wxBITMAP_TYPE_PNG); + } + return img_help2_png; +} +#define help2_png_img help2_png_img() + +static wxBitmap *help2_png_bmp() +{ + static wxBitmap *bmp_help2_png; + if (!bmp_help2_png || !bmp_help2_png->IsOk()) + bmp_help2_png = new wxBitmap(*help2_png_img); + return bmp_help2_png; +} +#define help2_png_bmp help2_png_bmp() + +static wxIcon *help2_png_ico() +{ + static wxIcon *ico_help2_png; + if (!ico_help2_png || !ico_help2_png->IsOk()) + { + ico_help2_png = new wxIcon(); + ico_help2_png->CopyFromBitmap(*help2_png_bmp); + } + return ico_help2_png; +} +#define help2_png_ico help2_png_ico() + +#endif // HELP2_PNG_H diff --git a/include/images/hint.png b/include/images/hint.png new file mode 100644 index 0000000000000000000000000000000000000000..0ff0561a29ae4a50e3001a319d336a94e3a2474f GIT binary patch literal 1152 zcmV-`1b_R9P)UUj&$+p|?(XjK@$u!!$=#Zo^24p1oSf_H>&<lqy$jEP!ps&NqY zeXzos+3)VSm*~mGVvU|~tH681-Q~Zp;I*0Ux08^Lj`7C8>aUT;i;LH`s_ed}(XO1@ zvYYR^o8+a7w4R!;nT?Ewg0-89-kFA%fPmq!kCKv-uabqLmX^Mwm8X@A(yEcKk&U5= zfyKPM(80mqo|D3#pW@=;;MA#V00001bW%=J06^y0W&i*H32;bRa{vGUNB{r;NB~C3 zYd!z~0yjxSK~y-)m6PjJ+CUV=qY`OX1rit;f;S`-TTdcMz`?U3$c@iC@ z7*5PMtW!>>Yu4_5KIfPraO@!`Dcs}m&d)nt-N3?v&*8x-vVWcSGXbx)&tELgc>_$4 z4H=w6K{&GX5_0E19*tU-B4L1XdI0c(Ac(f*m?XvGZg(OnrIIT?5gzhD4-g?)UbQT* zt#53suO$+OzuH`tSY>`OgQy(@BD!3a<)hKa7&(R-+)WYX|lNyISKc!KbwsOb7| zd~$kva$GJOepV4t)Nd3CssI!}&c=h1lr1ktS8}OT?yU5w2q5S+ionmO?QjOQ8f?+$ zi~8kdsr2O>Cwh&7t*)A__IN|#d8Kis(8Skfsd8zt6Y~ILHG(EdTGRZ6?5+4{+z9fWC-SY@MXTLzbvp1Ft?`%_^2(1gEU;C*s+TI2 z&QB%J4J7UyzG%Iz%2>5oscf6>1~}Bc=~ufD2m~VZ?X~HC*st|8*l<^Z_S-Z3UlXA} zx&S?5Eohw4g^voL6pD4FsiQWFtpZh5SsocFTEp?IqK*zA8c!?!CpcU&C5SvJFfb$J zFEws^r^#F|bN~PVC3HntbYx+4WjbSWWnpw>05UK!FfB1MEif@uGB7$cGdeUiD=;-W zFfg9(E~)?k03~!qSaf7zbY(hiZ)9m^c>ppnF)%GKIV~_TR5CLIsOk()) + { + wxMemoryInputStream img_hint_pngIS(hint_png_data, sizeof(hint_png_data)); + img_hint_png->LoadFile(img_hint_pngIS, wxBITMAP_TYPE_PNG); + } + return img_hint_png; +} +#define hint_png_img hint_png_img() + +static wxBitmap *hint_png_bmp() +{ + static wxBitmap *bmp_hint_png; + if (!bmp_hint_png || !bmp_hint_png->IsOk()) + bmp_hint_png = new wxBitmap(*hint_png_img); + return bmp_hint_png; +} +#define hint_png_bmp hint_png_bmp() + +static wxIcon *hint_png_ico() +{ + static wxIcon *ico_hint_png; + if (!ico_hint_png || !ico_hint_png->IsOk()) + { + ico_hint_png = new wxIcon(); + ico_hint_png->CopyFromBitmap(*hint_png_bmp); + } + return ico_hint_png; +} +#define hint_png_ico hint_png_ico() + +#endif // HINT_PNG_H diff --git a/include/images/hint2.png b/include/images/hint2.png new file mode 100644 index 0000000000000000000000000000000000000000..c36e3c2b88c42f0f5d72e5e9a26d44a060231d27 GIT binary patch literal 752 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47`*~~LR^8|W5zrTOm>eZK;n;)-O@$uN<4~O?XTDss;Q{&2&D_5;rb@%SwhZ{FOUAy+j z)yv;6pZj*<_}8-s9xt1_b?esU%a^};_3GLA^9%c@6-}7Cal@8R=TCe*eQ@2Xm4$sX z7j*YepFaKExpN;rd{{Jl(bC;V-hBA9Va>XAt5-EOH9dX$G`C~w@kej6%4-VyXB|Cy z^zq}zvl`kfSM8m2@^00_4eM5|ShaLv_58K-=FPi&`SQ656DCiX)X~u~Yu2o(y`2jd zESTKWxpCserAwE-dGqGu$B(ye-Foum$%_{+=FXkFZSv$vlO}E7zJ2D*nG+{YT)ler znKNgao115~w{M%=+t}E+Zr!>SQ`(PAZkgTQe)jCy3rCO6X{i74xbVP%1DiK*{#oSu92lC6B|(0{3=Yq3 zqyagc1s;*bK-vS0-A-oP0U38aT^vIsE+;1dK}u3uVrpt)T2cxFvsoFRpI)9^oE=}8 znZW#bhX9WVmk^&ACy#)J`HhZ2UQupgesPY0o{_F@QC^cALw#eNgS~^J**!8=tX^sK z;+5xXX$dI_O=iy8Oxswt&}89Y<6>@a?d)RXVBzFYHc#nj>uPp)b@p_2aqDPl&jq?> z>+;^o&5M(}XSdJnPeS$IKg@raLjTIB-fTX=$IZvd%iYh>)6;dWx6#7X!c0%iPEo;7 z>=b*G%HAhWri8GuczB;b!E?q*C}Bh5=96yEjGweTcZy_){-=DsW1YVz(4(p)t`Q|E zi6yC4$wjF^iowXh&_LJFNY}tH#K^$P#MsKjRNKJR%D`aWJH1sX8glbfGSey{8VoGK d8i1-ztPIQ`8ct0QT?5p>;OXk;vd$@?2>`81V~PL( literal 0 HcmV?d00001 diff --git a/include/images/hint2.pngc b/include/images/hint2.pngc new file mode 100644 index 0000000..c17580b --- /dev/null +++ b/include/images/hint2.pngc @@ -0,0 +1,138 @@ +#ifndef HINT2_PNG_H +#define HINT2_PNG_H + +static const unsigned char hint2_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x4a, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xb0, +0xb0, 0xb0, 0xa2, 0x9a, 0x9a, 0xad, 0x84, 0x84, +0xc1, 0x7d, 0x7d, 0xb4, 0xb4, 0xb4, 0x8f, 0x8f, +0x8f, 0xb6, 0xab, 0xab, 0xd2, 0x83, 0x83, 0xe3, +0xa8, 0xa8, 0xf1, 0xc6, 0xc3, 0xf0, 0xc3, 0xbe, +0xe2, 0xa5, 0xa0, 0xd2, 0x82, 0x81, 0xa9, 0xa9, +0xa9, 0xaa, 0xaa, 0xaa, 0xdd, 0xdd, 0xdd, 0xe1, +0xb1, 0xb1, 0xe5, 0xad, 0xad, 0xf8, 0xd5, 0xd3, +0xf7, 0xd3, 0xce, 0xf6, 0xd0, 0xc7, 0xf5, 0xcd, +0xc0, 0xe3, 0xa6, 0x9d, 0xb5, 0xb5, 0xb5, 0xa7, +0xa7, 0xa7, 0xea, 0xea, 0xea, 0xe6, 0xcf, 0xcf, +0xa1, 0x8f, 0x96, 0x72, 0x90, 0x9d, 0xb1, 0xb0, +0xb4, 0xf2, 0xcf, 0xc8, 0xf1, 0xcb, 0xc1, 0xae, +0xaa, 0xa9, 0x71, 0x8e, 0x99, 0xa0, 0x8b, 0x8f, +0x97, 0x97, 0x97, 0xce, 0xce, 0xce, 0xf0, 0xf0, +0xf0, 0xa2, 0x9b, 0xa2, 0xa5, 0xbb, 0xc4, 0xec, +0xf0, 0xf2, 0xb0, 0xac, 0xae, 0xae, 0xab, 0xaa, +0x82, 0x82, 0x82, 0xe5, 0xe5, 0xe5, 0x6d, 0x88, +0x95, 0xc7, 0xe2, 0xec, 0x6a, 0x77, 0x7c, 0x71, +0x8f, 0x9a, 0xc5, 0xc5, 0xc5, 0xe3, 0xe3, 0xe3, +0x9a, 0x80, 0x87, 0x79, 0xaa, 0xbd, 0x92, 0xc9, +0xdd, 0x7a, 0xa1, 0xb0, 0xae, 0xaa, 0xa8, 0xaa, +0xa5, 0xa1, 0x7b, 0x9f, 0xad, 0x9e, 0x9e, 0x9e, +0xd3, 0xd3, 0xd3, 0xce, 0x90, 0x90, 0x93, 0x90, +0x92, 0x88, 0x88, 0x88, 0x9a, 0x9a, 0x9a, 0x95, +0x8d, 0x89, 0xa0, 0xa0, 0xa0, 0x93, 0x8c, 0x89, +0xb1, 0x91, 0x91, 0xa5, 0xa5, 0xa5, 0xec, 0xec, +0xec, 0xf1, 0xf1, 0xf1, 0xda, 0xda, 0xda, 0xe4, +0xe4, 0xe4, 0xe8, 0xe8, 0xe8, 0x9d, 0x9d, 0x9d, +0xb6, 0x93, 0x93, 0x92, 0x92, 0x92, 0xb7, 0xb7, +0xb7, 0x99, 0x99, 0x99, 0x91, 0x91, 0x91, 0xab, +0xab, 0xab, 0xcc, 0xcc, 0xcc, 0x83, 0x83, 0x83, +0x9a, 0x87, 0x87, 0xb6, 0x93, 0x8d, 0x81, 0x81, +0x81, 0xae, 0xae, 0xae, 0xa8, 0x94, 0x87, 0xc4, +0x93, 0x84, 0x9b, 0x87, 0x87, 0xcd, 0xcd, 0xcd, +0xd0, 0xc5, 0xc5, 0x9c, 0x80, 0x7f, 0xf8, 0xf8, +0xf8, 0xf2, 0xf2, 0xf2, 0xc0, 0x80, 0x7d, 0x85, +0x84, 0x84, 0xed, 0xed, 0xed, 0xbc, 0xbc, 0xbc, +0xa3, 0xa0, 0xa0, 0xa6, 0xa6, 0xa6, 0xa2, 0xa2, +0xa2, 0xe1, 0xe1, 0xe1, 0xe0, 0xe0, 0xe0, 0xc1, +0xc1, 0xc1, 0xa1, 0xa1, 0xa1, 0xc0, 0xc0, 0xc0, +0xb3, 0xb3, 0xb3, 0xf9, 0x72, 0x45, 0xe7, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0xdd, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x63, 0x60, 0x60, 0x60, 0x60, +0x64, 0x62, 0x66, 0x61, 0x65, 0x65, 0x61, 0x66, +0x62, 0x64, 0x00, 0x03, 0x36, 0x76, 0x0e, 0x4e, +0x2e, 0x6e, 0x1e, 0x5e, 0x3e, 0x0e, 0x76, 0x36, +0x10, 0x9f, 0x5f, 0x40, 0x50, 0x48, 0x58, 0x44, +0x54, 0x4c, 0x5c, 0x42, 0x48, 0x50, 0x80, 0x9f, +0x81, 0x41, 0x52, 0x4a, 0x5a, 0x46, 0x56, 0x4e, +0x5e, 0x41, 0x51, 0x49, 0x59, 0x45, 0x46, 0x5a, +0x4a, 0x92, 0x41, 0x55, 0x4d, 0x5d, 0x43, 0x53, +0x4b, 0x53, 0x5b, 0x07, 0x48, 0x68, 0xa8, 0xab, +0xa9, 0x32, 0xe8, 0xea, 0x49, 0xeb, 0x1b, 0x18, +0x1a, 0x18, 0x29, 0x03, 0x09, 0x7d, 0x69, 0x3d, +0x5d, 0x06, 0x55, 0x63, 0x13, 0x53, 0x33, 0x73, +0x0b, 0x4b, 0x2b, 0x6b, 0x73, 0x33, 0x53, 0x13, +0x63, 0x55, 0x06, 0x49, 0x1b, 0x5b, 0x3b, 0x7b, +0x07, 0x47, 0x27, 0x07, 0x67, 0x07, 0x17, 0x3b, +0x5b, 0x1b, 0x49, 0xa0, 0x2d, 0x36, 0xae, 0x6e, +0xee, 0x1e, 0x9e, 0x5e, 0x1e, 0xde, 0x3e, 0xbe, +0x36, 0xfc, 0x60, 0x7b, 0xfd, 0xfc, 0x03, 0xfc, +0x02, 0x55, 0xfd, 0x1c, 0x25, 0xd9, 0x83, 0xc0, +0x0e, 0x0b, 0x0e, 0x09, 0x0d, 0x0b, 0x8f, 0x08, +0x8c, 0x8c, 0x8a, 0xd6, 0x8d, 0x81, 0x38, 0x35, +0x38, 0x36, 0x2e, 0x26, 0x3e, 0x21, 0x20, 0x31, +0x16, 0xca, 0x07, 0x82, 0x24, 0xbd, 0xe4, 0xe4, +0x94, 0x54, 0x06, 0x04, 0x48, 0x4b, 0xcf, 0xc8, +0x0c, 0xcc, 0x42, 0x12, 0x60, 0xb0, 0x61, 0xb3, +0xc9, 0x46, 0xe6, 0x33, 0xe4, 0x84, 0xe7, 0x42, +0x59, 0x00, 0x5b, 0xfe, 0x23, 0xd7, 0x88, 0xae, +0x4f, 0x49, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, +0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *hint2_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_hint2_png = new wxImage(); + if (!img_hint2_png || !img_hint2_png->IsOk()) + { + wxMemoryInputStream img_hint2_pngIS(hint2_png_data, sizeof(hint2_png_data)); + img_hint2_png->LoadFile(img_hint2_pngIS, wxBITMAP_TYPE_PNG); + } + return img_hint2_png; +} +#define hint2_png_img hint2_png_img() + +static wxBitmap *hint2_png_bmp() +{ + static wxBitmap *bmp_hint2_png; + if (!bmp_hint2_png || !bmp_hint2_png->IsOk()) + bmp_hint2_png = new wxBitmap(*hint2_png_img); + return bmp_hint2_png; +} +#define hint2_png_bmp hint2_png_bmp() + +static wxIcon *hint2_png_ico() +{ + static wxIcon *ico_hint2_png; + if (!ico_hint2_png || !ico_hint2_png->IsOk()) + { + ico_hint2_png = new wxIcon(); + ico_hint2_png->CopyFromBitmap(*hint2_png_bmp); + } + return ico_hint2_png; +} +#define hint2_png_ico hint2_png_ico() + +#endif // HINT2_PNG_H diff --git a/include/images/index.png b/include/images/index.png new file mode 100644 index 0000000000000000000000000000000000000000..a239c125109ca8d73b6afa840b5740a8bb06934e GIT binary patch literal 562 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf+W?;sS0LTF`o3ZPMa`Pi^5sX2 z>o4lmo>isa+J5uHrmOGQUVOXa?3=}>Ud=o9a@OG&(+)g;b8MqB(8G)+L4Lsu4$p3+0Xdun z9+AaB+5?Q;PG;Ky88x0Rjv*44lM@t}42%pnFW}g)X=8DL5_f?jgZYf}hYz1VuCJh> zqN8+*RZu{9`h+QyrcInWxt&8pLrc?p<%(4+vooAnM7C}zT~hk>3olQv0@E?IWoggE zriEQI+a|y$Y+cRnuAVL)&N097^x3RdP`(kYX@0Ff`CLG}1LN3^6jWGBLI?G1WFOwK6c6_fBsWiiX_$l+3hB ihz0{oum+%N6DtEVh=xIsOk()) + { + wxMemoryInputStream img_index_pngIS(index_png_data, sizeof(index_png_data)); + img_index_png->LoadFile(img_index_pngIS, wxBITMAP_TYPE_PNG); + } + return img_index_png; +} +#define index_png_img index_png_img() + +static wxBitmap *index_png_bmp() +{ + static wxBitmap *bmp_index_png; + if (!bmp_index_png || !bmp_index_png->IsOk()) + bmp_index_png = new wxBitmap(*index_png_img); + return bmp_index_png; +} +#define index_png_bmp index_png_bmp() + +static wxIcon *index_png_ico() +{ + static wxIcon *ico_index_png; + if (!ico_index_png || !ico_index_png->IsOk()) + { + ico_index_png = new wxIcon(); + ico_index_png->CopyFromBitmap(*index_png_bmp); + } + return ico_index_png; +} +#define index_png_ico index_png_ico() + +#endif // INDEX_PNG_H diff --git a/include/images/indexes.png b/include/images/indexes.png new file mode 100644 index 0000000000000000000000000000000000000000..bb1513c8287e2ee5b39c36836fc01636ed35cf5f GIT binary patch literal 468 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMfoB*E?S0LTF`o3ZPMa`Pi^5sX2 z>o4lmo>i#s{~Mc;}!vhk&@*M_wFx^kv_@PdjdY*m&jL%JXj) zpL#Xt=!@wGpZi26dW9#rhbFAP@YX3X&fY(E*X@s+uf1P$;qB7Xujd_mIpfgtu2Mf2 zp!*n0g8YIR9G=}s19CVEJR*yMvIsOk()) + { + wxMemoryInputStream img_indexes_pngIS(indexes_png_data, sizeof(indexes_png_data)); + img_indexes_png->LoadFile(img_indexes_pngIS, wxBITMAP_TYPE_PNG); + } + return img_indexes_png; +} +#define indexes_png_img indexes_png_img() + +static wxBitmap *indexes_png_bmp() +{ + static wxBitmap *bmp_indexes_png; + if (!bmp_indexes_png || !bmp_indexes_png->IsOk()) + bmp_indexes_png = new wxBitmap(*indexes_png_img); + return bmp_indexes_png; +} +#define indexes_png_bmp indexes_png_bmp() + +static wxIcon *indexes_png_ico() +{ + static wxIcon *ico_indexes_png; + if (!ico_indexes_png || !ico_indexes_png->IsOk()) + { + ico_indexes_png = new wxIcon(); + ico_indexes_png->CopyFromBitmap(*indexes_png_bmp); + } + return ico_indexes_png; +} +#define indexes_png_ico indexes_png_ico() + +#endif // INDEXES_PNG_H diff --git a/include/images/job.png b/include/images/job.png new file mode 100644 index 0000000000000000000000000000000000000000..7754674229f36de23a8ec902319cc20b6639f41e GIT binary patch literal 678 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl482JKxLR^8|&0DtA)i?bA|Nrm5 z|3Cl!`}X_qr(b{G{`m9q+wUh|e%<@@Q!Zfb%@02=zx{UZ_1D{X?%&?MbKn zDKXE>3cAatfBo_E!_PmDKL5P^=F8p5lb(e5eV8-z!_DjOfBbpz?boHZ-!2|F{>0b) zWqQip_S$!!zd!%_>%pg=o$GF%eEH?jgEvoH9iKYe-31O70mkaRAxOVSLRoz3oWyv*O=`-yplso(q($|mx|hd z4LVb7G};bL%+Q(lgNrTFr)yz|l=01&eGD%D@;{4sr#{iT8YRooZDY3QY?!ol(Dv)> zhdwr$eBix#Q9}LlO&N}UA-zARr*62HQ~sM-z|m^nx#>T?mes%c=FhP8?d!Sgzovcq zw>;qedH(x98QCkuSLa=+?g9EnwZt`|BqgyV)hf9t6-Y4{85kPq8XD;u7={=bSeY1G znV4!Dm|7Va%zLM|3PnS1eoAIqB}9XPC0GMcwTYF18AQXW>7i?Y8W=oX{an^LB{Ts5 DQ$AJ4 literal 0 HcmV?d00001 diff --git a/include/images/job.pngc b/include/images/job.pngc new file mode 100644 index 0000000..b3130ff --- /dev/null +++ b/include/images/job.pngc @@ -0,0 +1,129 @@ +#ifndef JOB_PNG_H +#define JOB_PNG_H + +static const unsigned char job_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x0e, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xb3, 0xb4, 0xb4, 0x7e, +0x7f, 0x80, 0xff, 0xff, 0xff, 0xfd, 0xfe, 0xff, +0xf9, 0xfd, 0xfe, 0xf6, 0xfb, 0xfd, 0xf2, 0xfa, +0xfc, 0xed, 0xf8, 0xfc, 0xe9, 0xf6, 0xfb, 0xe4, +0xf4, 0xfa, 0xde, 0xf2, 0xf9, 0x1e, 0x50, 0xad, +0xd9, 0xf0, 0xf8, 0xd3, 0xed, 0xf6, 0xce, 0xeb, +0xf5, 0xdb, 0xdc, 0xdf, 0xdb, 0xbb, 0xb8, 0xde, +0x9f, 0x96, 0xe1, 0x8a, 0x7f, 0xd0, 0x81, 0x78, +0xef, 0xb5, 0xaf, 0x64, 0x6a, 0xa1, 0xc2, 0x89, +0x8c, 0xe2, 0x8e, 0x81, 0xe2, 0x88, 0x7c, 0xe2, +0x81, 0x76, 0xe2, 0x7a, 0x70, 0xe3, 0x73, 0x69, +0xe7, 0x82, 0x7b, 0xdf, 0xa2, 0x98, 0xeb, 0xb4, +0xad, 0xf1, 0xda, 0xd7, 0xf0, 0xf4, 0xf7, 0xe8, +0xd2, 0xd2, 0xe3, 0x9f, 0x9c, 0xe3, 0x64, 0x5c, +0xe7, 0x76, 0x70, 0x8b, 0x76, 0x97, 0xf5, 0xf8, +0xf9, 0xf0, 0xf9, 0xfc, 0xe2, 0xf3, 0xf9, 0xdb, +0xec, 0xf4, 0xdd, 0x93, 0x92, 0xe4, 0x54, 0x4e, +0xf0, 0x9c, 0x99, 0xf0, 0xd9, 0xd7, 0xef, 0xf8, +0xfc, 0xe8, 0xf6, 0xfa, 0xd2, 0xed, 0xf6, 0xd1, +0xc0, 0xc7, 0xe4, 0x4d, 0x47, 0xe9, 0x67, 0x64, +0xdd, 0x87, 0x7d, 0xee, 0xf3, 0xf7, 0xe7, 0xf5, +0xfa, 0xe0, 0xf2, 0xf9, 0x89, 0xae, 0xd9, 0xc9, +0xe9, 0xf4, 0xc2, 0xe0, 0xec, 0xe4, 0x45, 0x41, +0xe5, 0x43, 0x3f, 0xdc, 0x94, 0x8d, 0xe5, 0xd1, +0xd2, 0xd7, 0xef, 0xf7, 0x88, 0xad, 0xd9, 0x7f, +0xa9, 0xd7, 0xc5, 0xb7, 0xc0, 0xe4, 0x3e, 0x3a, +0xe9, 0x5c, 0x59, 0x8b, 0x67, 0x8b, 0xe1, 0x9d, +0x9b, 0xd5, 0xea, 0xf3, 0xc6, 0xe8, 0xf4, 0x7f, +0xa9, 0xd6, 0xb9, 0xde, 0xec, 0xd1, 0x7b, 0x7f, +0xe4, 0x37, 0x34, 0xf1, 0x8c, 0x8b, 0xc3, 0xe7, +0xf3, 0xbe, 0xe5, 0xf2, 0xc3, 0xc9, 0xd2, 0xdc, +0x7e, 0x79, 0xda, 0x91, 0x91, 0xce, 0xbe, 0xc6, +0xbf, 0xde, 0xeb, 0xc4, 0xb6, 0xc0, 0xe9, 0x50, +0x4f, 0xa2, 0x75, 0x73, 0xd3, 0x61, 0x5c, 0x22, +0x28, 0xc7, 0x77, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, +0x03, 0x11, 0x0c, 0x4c, 0xf2, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0xc2, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x3d, 0x8f, 0xd5, 0x12, +0xc2, 0x50, 0x0c, 0x05, 0xc3, 0x85, 0x52, 0x4a, +0xd3, 0x16, 0xa7, 0xb8, 0xbb, 0x3b, 0x14, 0x77, +0x77, 0xff, 0xff, 0x1f, 0x81, 0x0a, 0xec, 0x4b, +0x26, 0x7b, 0x32, 0x99, 0x39, 0xa0, 0x23, 0x7f, +0x40, 0x81, 0xe8, 0xf5, 0x06, 0xca, 0x48, 0x9b, +0x18, 0x33, 0x4b, 0x34, 0x81, 0x14, 0x2a, 0x70, +0x9a, 0xf8, 0xe5, 0x1c, 0xaf, 0x09, 0x0a, 0x69, +0xf5, 0x42, 0xd0, 0x84, 0x9a, 0x5b, 0xac, 0x36, +0xbb, 0xc3, 0xa9, 0x08, 0x1a, 0x19, 0x44, 0x97, +0x5b, 0xf4, 0x78, 0x7d, 0xfe, 0x80, 0x2c, 0x94, +0x3c, 0x28, 0x86, 0xc2, 0x91, 0x68, 0x2c, 0x9e, +0xf8, 0x0a, 0x06, 0x59, 0x4c, 0x8a, 0xa1, 0x54, +0x1a, 0x33, 0xd9, 0x5c, 0xbe, 0x00, 0x44, 0xfe, +0x6f, 0xf3, 0x14, 0x4b, 0x65, 0xe4, 0x2a, 0xd5, +0x5a, 0x1d, 0x08, 0x8b, 0x3c, 0x36, 0xbc, 0xcd, +0x56, 0x1b, 0x3b, 0x52, 0xb7, 0xd7, 0x07, 0xc2, +0xf1, 0x82, 0x34, 0xf0, 0x0d, 0xd9, 0xd1, 0x18, +0x27, 0xd3, 0xd9, 0x1c, 0x08, 0x8f, 0x12, 0x2e, +0xfc, 0xcb, 0x95, 0xb0, 0xde, 0x6c, 0x77, 0xfb, +0x03, 0x10, 0x41, 0x3a, 0x9e, 0xce, 0x97, 0xf8, +0xf5, 0x76, 0x7f, 0xec, 0xf6, 0x4f, 0x00, 0xb5, +0xed, 0xeb, 0x9d, 0xaf, 0xf5, 0x66, 0xf2, 0xfe, +0xa7, 0x50, 0xef, 0xcf, 0x0f, 0xdf, 0xf9, 0x01, +0x07, 0x78, 0x17, 0xab, 0x6e, 0xd4, 0x7b, 0x8c, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, +0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *job_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_job_png = new wxImage(); + if (!img_job_png || !img_job_png->IsOk()) + { + wxMemoryInputStream img_job_pngIS(job_png_data, sizeof(job_png_data)); + img_job_png->LoadFile(img_job_pngIS, wxBITMAP_TYPE_PNG); + } + return img_job_png; +} +#define job_png_img job_png_img() + +static wxBitmap *job_png_bmp() +{ + static wxBitmap *bmp_job_png; + if (!bmp_job_png || !bmp_job_png->IsOk()) + bmp_job_png = new wxBitmap(*job_png_img); + return bmp_job_png; +} +#define job_png_bmp job_png_bmp() + +static wxIcon *job_png_ico() +{ + static wxIcon *ico_job_png; + if (!ico_job_png || !ico_job_png->IsOk()) + { + ico_job_png = new wxIcon(); + ico_job_png->CopyFromBitmap(*job_png_bmp); + } + return ico_job_png; +} +#define job_png_ico job_png_ico() + +#endif // JOB_PNG_H diff --git a/include/images/jobdisabled.png b/include/images/jobdisabled.png new file mode 100644 index 0000000000000000000000000000000000000000..a9bf3ef791edd884b40a11415a2b08b53f82fdd7 GIT binary patch literal 601 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMfr2wB0S0KH4%a*$OhX4Qn|NZy> z=ih(de*gXS>(ARCe_nq3{p8E9d!K&F1+2aK;m75--_E`MdOjunC6T9-d!wbH8L{d`?RG5E}a4 z4=CbsJR#+CV&cc>=no+w?|uE=xx0S|1~Po#xw(A^4u0?B^Ul@vjh+2#3yTjyLGQi2 z-@3TIHaCA|X!ufFd*9Pf9|8m4d3n8ccG(%7^ioUvg{tav1%v{^w#% z1|rSgf`Xa}EG*yeRli^R{=e6@t+V96&#Cjg9JlD=eiJ2^Qrkq8vs0#STgh}LA*heZ z{(hmT!Hl226 zS$)Ha++-WU%i{MoxqAEyJjWj;DB$aDx+n_hc-0cuh?11Vl2ohYqEsNoU}RuuplfKP zYhV~+WME}tY-M7qZD49;U@-5U-YOIgx%nxXX_XKS29{tAK-DHz24)Zqr>2Ll0cv3I MboFyt=akR{07RbvaR2}S literal 0 HcmV?d00001 diff --git a/include/images/jobdisabled.pngc b/include/images/jobdisabled.pngc new file mode 100644 index 0000000..74ef465 --- /dev/null +++ b/include/images/jobdisabled.pngc @@ -0,0 +1,120 @@ +#ifndef JOBDISABLED_PNG_H +#define JOBDISABLED_PNG_H + +static const unsigned char jobdisabled_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xd2, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xb3, 0xb4, 0xb4, 0x7e, +0x7f, 0x80, 0xff, 0xff, 0xff, 0xfd, 0xfe, 0xff, +0xf9, 0xfd, 0xfe, 0xf6, 0xfb, 0xfd, 0xf2, 0xfa, +0xfc, 0xed, 0xf8, 0xfc, 0xe9, 0xf6, 0xfb, 0xe4, +0xf4, 0xfa, 0xde, 0xf2, 0xf9, 0x1e, 0x50, 0xad, +0xd9, 0xf0, 0xf8, 0xd3, 0xed, 0xf6, 0xce, 0xeb, +0xf5, 0xcf, 0x64, 0x67, 0xc5, 0x00, 0x00, 0xcb, +0x62, 0x65, 0xc9, 0xe9, 0xf4, 0xdd, 0x69, 0x69, +0x80, 0x21, 0x47, 0xf6, 0x77, 0x77, 0xc3, 0xe7, +0xf3, 0xa8, 0x34, 0x35, 0xf1, 0x57, 0x57, 0xf6, +0x76, 0x76, 0xf6, 0x72, 0x72, 0xf5, 0x6e, 0x6e, +0xc2, 0x5e, 0x64, 0xf1, 0x56, 0x56, 0xef, 0x4f, +0x4f, 0xee, 0x48, 0x49, 0xf5, 0x6d, 0x6d, 0xf4, +0x68, 0x68, 0xf3, 0x62, 0x62, 0xf0, 0x55, 0x55, +0xef, 0x4e, 0x4f, 0xee, 0x48, 0x48, 0xc7, 0x60, +0x64, 0xf3, 0x61, 0x61, 0xf1, 0x5b, 0x5b, 0xf0, +0x54, 0x54, 0xef, 0x4d, 0x4e, 0xee, 0x47, 0x47, +0xf0, 0x53, 0x54, 0xef, 0x4d, 0x4d, 0xee, 0x46, +0x46, 0xf0, 0x53, 0x53, 0xef, 0x4c, 0x4c, 0xee, +0x45, 0x45, 0xec, 0x3e, 0x3f, 0xeb, 0x38, 0x38, +0xf0, 0x52, 0x52, 0xef, 0x4b, 0x4b, 0xed, 0x44, +0x45, 0xeb, 0x37, 0x37, 0xea, 0x31, 0x31, 0xe9, +0x2b, 0x2b, 0xbe, 0xe5, 0xf2, 0xf0, 0x51, 0x51, +0xee, 0x4a, 0x4a, 0xed, 0x43, 0x44, 0xb9, 0x5b, +0x62, 0xe9, 0x2a, 0x2b, 0xe8, 0x25, 0x25, 0xe7, +0x20, 0x20, 0xed, 0x42, 0x43, 0xbd, 0x4a, 0x4b, +0xe7, 0x1f, 0x20, 0xca, 0x4c, 0x75, 0xf6, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, +0x62, 0x4b, 0x47, 0x44, 0x03, 0x11, 0x0c, 0x4c, +0xf2, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0xb1, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x3d, 0x8f, 0xe7, 0x16, 0x82, 0x30, 0x14, 0x83, +0x4b, 0x11, 0x11, 0x29, 0x60, 0x04, 0x04, 0xf7, +0xde, 0x7b, 0xef, 0xad, 0xef, 0xff, 0x4a, 0xb6, +0xb5, 0x9a, 0x1f, 0xf7, 0x9c, 0x7e, 0x49, 0xd3, +0x5e, 0xa2, 0xd1, 0xbf, 0x34, 0x22, 0x44, 0x75, +0x3d, 0x61, 0x24, 0xcd, 0x94, 0x95, 0xb6, 0xa9, +0x02, 0xcc, 0x60, 0x52, 0x8e, 0x02, 0x3f, 0xdf, +0x71, 0x15, 0x30, 0x98, 0xf9, 0x4d, 0x78, 0x0a, +0x48, 0x3f, 0x83, 0xac, 0xe7, 0xd3, 0x00, 0x01, +0x07, 0x26, 0xb3, 0x58, 0x88, 0x1c, 0xc2, 0x28, +0x46, 0x9e, 0x13, 0x2a, 0xee, 0xa3, 0x50, 0x2c, +0xa1, 0x8c, 0x4a, 0xb5, 0x06, 0x42, 0x2d, 0x66, +0xf3, 0x44, 0xbd, 0xd1, 0x44, 0xab, 0xdd, 0x11, +0x09, 0xd1, 0xef, 0x75, 0xd1, 0xeb, 0x0f, 0x86, +0x23, 0xd9, 0x61, 0x33, 0x97, 0x3f, 0x11, 0x62, +0x3c, 0x99, 0x8a, 0x33, 0xa1, 0xdc, 0xf7, 0xa3, +0x32, 0x66, 0xf3, 0xc5, 0x72, 0x25, 0x13, 0x2e, +0xf3, 0xb9, 0xbf, 0xde, 0x6c, 0xb1, 0xdb, 0x1f, +0x44, 0x07, 0xf7, 0x8f, 0x38, 0x9d, 0x2f, 0xb8, +0xe2, 0x76, 0x7f, 0x80, 0xc8, 0x6d, 0x63, 0x3c, +0x11, 0xd3, 0x17, 0xde, 0xb2, 0x45, 0x48, 0xfe, +0x51, 0xce, 0x0f, 0x5a, 0x11, 0x10, 0x4d, 0x4b, +0x35, 0xa2, 0x5a, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *jobdisabled_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_jobdisabled_png = new wxImage(); + if (!img_jobdisabled_png || !img_jobdisabled_png->IsOk()) + { + wxMemoryInputStream img_jobdisabled_pngIS(jobdisabled_png_data, sizeof(jobdisabled_png_data)); + img_jobdisabled_png->LoadFile(img_jobdisabled_pngIS, wxBITMAP_TYPE_PNG); + } + return img_jobdisabled_png; +} +#define jobdisabled_png_img jobdisabled_png_img() + +static wxBitmap *jobdisabled_png_bmp() +{ + static wxBitmap *bmp_jobdisabled_png; + if (!bmp_jobdisabled_png || !bmp_jobdisabled_png->IsOk()) + bmp_jobdisabled_png = new wxBitmap(*jobdisabled_png_img); + return bmp_jobdisabled_png; +} +#define jobdisabled_png_bmp jobdisabled_png_bmp() + +static wxIcon *jobdisabled_png_ico() +{ + static wxIcon *ico_jobdisabled_png; + if (!ico_jobdisabled_png || !ico_jobdisabled_png->IsOk()) + { + ico_jobdisabled_png = new wxIcon(); + ico_jobdisabled_png->CopyFromBitmap(*jobdisabled_png_bmp); + } + return ico_jobdisabled_png; +} +#define jobdisabled_png_ico jobdisabled_png_ico() + +#endif // JOBDISABLED_PNG_H diff --git a/include/images/jobs.png b/include/images/jobs.png new file mode 100644 index 0000000000000000000000000000000000000000..705e23318f03e1e8147e933e194e38cecd5e0e83 GIT binary patch literal 521 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf`~aU2S0KH4%a*$OhX4Qn|M~at z$DeLzqhZwadN@ZH!1OpGn4M5MO|L8>d@`y$LBA-6&(0=&8jb3 z*6%ng`vT}h#*!evUYWCJe)3W=ge>E#M?7Si|#X`z|*=Ea% z_pA{?reMxqCNtMOCbK-l#L|z=<{`>LIs_P$S`^SZu)-W2Ll0cv3IboFyt=akR{09Rt{xBvhE literal 0 HcmV?d00001 diff --git a/include/images/jobs.pngc b/include/images/jobs.pngc new file mode 100644 index 0000000..19559a5 --- /dev/null +++ b/include/images/jobs.pngc @@ -0,0 +1,110 @@ +#ifndef JOBS_PNG_H +#define JOBS_PNG_H + +static const unsigned char jobs_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x9f, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xb3, 0xb4, 0xb4, 0x7e, +0x7f, 0x80, 0xff, 0xff, 0xff, 0xfc, 0xfe, 0xfe, +0xf8, 0xfc, 0xfe, 0xf3, 0xfa, 0xfd, 0xed, 0xf8, +0xfc, 0xe7, 0xf5, 0xfa, 0xe1, 0xf3, 0xf9, 0xda, +0xf0, 0xf8, 0x56, 0x6c, 0x93, 0x1e, 0x50, 0xad, +0xd3, 0xed, 0xf6, 0xcd, 0xeb, 0xf5, 0xc6, 0xe8, +0xf4, 0xd3, 0xb4, 0xaf, 0xd8, 0x7e, 0x6d, 0xde, +0x56, 0x3e, 0xc5, 0x59, 0x49, 0xf3, 0xb9, 0xb1, +0x66, 0x53, 0x82, 0xe2, 0x79, 0x65, 0xf0, 0xbd, +0xb4, 0xf1, 0xf0, 0xf0, 0xe6, 0xb4, 0xb0, 0xe2, +0x6a, 0x5e, 0xef, 0xbc, 0xb4, 0xf0, 0xf9, 0xfc, +0xdd, 0xf1, 0xf8, 0xd8, 0xaa, 0xaa, 0xea, 0x6c, +0x63, 0xd7, 0x50, 0x3c, 0xed, 0xee, 0xf0, 0xe4, +0xf4, 0xfa, 0x89, 0xae, 0xd9, 0xc7, 0xdc, 0xe8, +0xe4, 0x36, 0x2d, 0xc0, 0xe5, 0xf3, 0xd5, 0x75, +0x69, 0xe1, 0xb2, 0xae, 0xd7, 0xef, 0xf7, 0x87, +0xad, 0xd8, 0xc9, 0xa0, 0xa5, 0xec, 0x64, 0x5f, +0xa3, 0x69, 0x62, 0xdc, 0x66, 0x5a, 0xd3, 0xa8, +0xaa, 0xc2, 0xdb, 0xe7, 0xc7, 0x9f, 0xa5, 0xda, +0x53, 0x51, 0xf5, 0xac, 0xaa, 0xf4, 0xb4, 0xaf, +0xb8, 0xcd, 0x1d, 0xe8, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, +0x44, 0x03, 0x11, 0x0c, 0x4c, 0xf2, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x94, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x5d, 0xcf, 0xd9, +0x12, 0x83, 0x20, 0x0c, 0x40, 0xd1, 0x48, 0x15, +0x91, 0x06, 0xac, 0xdd, 0x77, 0xed, 0x62, 0x57, +0xbb, 0xda, 0xff, 0xff, 0xb6, 0x42, 0xc0, 0x69, +0xc7, 0x3c, 0xde, 0x1c, 0x66, 0x02, 0x04, 0xcc, +0x0f, 0xf8, 0x61, 0x9d, 0x30, 0xe2, 0xb1, 0x48, +0x64, 0x53, 0x58, 0xd8, 0x6d, 0x4c, 0xe0, 0x42, +0xd4, 0x32, 0x8c, 0xff, 0x19, 0x0a, 0x71, 0xcb, +0x30, 0x61, 0x0d, 0x72, 0x34, 0xa3, 0x28, 0x24, +0xd6, 0xd0, 0x5e, 0x69, 0x0a, 0xd2, 0x1a, 0x14, +0x56, 0xa4, 0x14, 0x94, 0x35, 0x76, 0xdf, 0xcb, +0xfa, 0x83, 0x21, 0x80, 0xb9, 0xd4, 0x18, 0x94, +0x38, 0x1a, 0x4f, 0xa6, 0xb3, 0x39, 0x78, 0x63, +0xde, 0x67, 0x8b, 0x25, 0xae, 0xd6, 0x39, 0x38, +0x83, 0x1a, 0x8b, 0xcd, 0x16, 0x77, 0xfb, 0xd2, +0x1d, 0xa7, 0x74, 0x7a, 0x38, 0x9e, 0xce, 0x17, +0xbc, 0x56, 0x14, 0xe8, 0xc7, 0xb7, 0xfb, 0xe3, +0xf9, 0x7a, 0xd7, 0xf0, 0x9b, 0x4f, 0x5e, 0x56, +0x35, 0x7c, 0x01, 0x01, 0xa1, 0x09, 0x49, 0xf9, +0x16, 0x39, 0xcb, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *jobs_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_jobs_png = new wxImage(); + if (!img_jobs_png || !img_jobs_png->IsOk()) + { + wxMemoryInputStream img_jobs_pngIS(jobs_png_data, sizeof(jobs_png_data)); + img_jobs_png->LoadFile(img_jobs_pngIS, wxBITMAP_TYPE_PNG); + } + return img_jobs_png; +} +#define jobs_png_img jobs_png_img() + +static wxBitmap *jobs_png_bmp() +{ + static wxBitmap *bmp_jobs_png; + if (!bmp_jobs_png || !bmp_jobs_png->IsOk()) + bmp_jobs_png = new wxBitmap(*jobs_png_img); + return bmp_jobs_png; +} +#define jobs_png_bmp jobs_png_bmp() + +static wxIcon *jobs_png_ico() +{ + static wxIcon *ico_jobs_png; + if (!ico_jobs_png || !ico_jobs_png->IsOk()) + { + ico_jobs_png = new wxIcon(); + ico_jobs_png->CopyFromBitmap(*jobs_png_bmp); + } + return ico_jobs_png; +} +#define jobs_png_ico jobs_png_ico() + +#endif // JOBS_PNG_H diff --git a/include/images/key.png b/include/images/key.png new file mode 100644 index 0000000000000000000000000000000000000000..90405e791783575f818b0c447315974794fe2d69 GIT binary patch literal 450 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf%mAMdS0MfA+w+5$yQXio>EEEe z_j3J%k9+Tb*tO?!b>9Zf_y4cG{&(it-+j;i?B02)q6 zbK#f1v|RhryXSK4>whPo{Mm8$*OI$G7j3(k)4xG$_od2P?^a)byJW|u!oKzDMdm-8 zfR1A<3GxeOaCmkj4angv@Q5r1(jH*!b~4)z$Vl*XaSV~ToSd+LEg>Z-EiK9A(dG@C zHWn8sxy*>zxude;=MP1PhQ`L3z7yg-B3wdzVw{4!X31+PD4*6>U%z0*k~ND~u>~Dm zvTotZrE3rCGqfn!F)v;>Z(rj=LFK&cl?)8x&)6)_2QMlB+NE0J8c~vxSdwa$T$Bo= z7>o=I4Rj5SbPWtcj0~(yjIB&ewGB+I3=HPI(_4k2AvZrIGp!P$!N3x%0jS!<%D@bw U;neidH9!pvp00i_>zopr0J00q>Hq)$ literal 0 HcmV?d00001 diff --git a/include/images/key.pngc b/include/images/key.pngc new file mode 100644 index 0000000..ce543ac --- /dev/null +++ b/include/images/key.pngc @@ -0,0 +1,101 @@ +#ifndef KEY_PNG_H +#define KEY_PNG_H + +static const unsigned char key_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x99, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xf2, 0xf6, 0xe7, 0xc1, +0xd3, 0x8a, 0x97, 0xb5, 0x3c, 0x8f, 0xb0, 0x2b, +0xbd, 0xd3, 0x7f, 0xe0, 0xf1, 0xbd, 0xdf, 0xf0, +0xba, 0xbc, 0xd3, 0x7b, 0x8e, 0xb0, 0x29, 0xef, +0xff, 0xd6, 0xeb, 0xfe, 0xcc, 0xe6, 0xfd, 0xbe, +0xe6, 0xfc, 0xbb, 0xb9, 0xd2, 0x74, 0x83, 0xa7, +0x15, 0xb6, 0xcb, 0x75, 0xee, 0xff, 0xd2, 0xe6, +0xfd, 0xbd, 0xdb, 0xfa, 0xa0, 0xdb, 0xf9, 0x9e, +0xde, 0xf9, 0xa5, 0xdf, 0xf8, 0xa6, 0xdb, 0xf7, +0x9c, 0xd8, 0xf6, 0x93, 0xd2, 0xf4, 0x82, 0xd2, +0xf3, 0x82, 0xe1, 0xf7, 0xad, 0xe0, 0xf1, 0xbc, +0xec, 0xfe, 0xce, 0xe3, 0xfc, 0xb5, 0xd8, 0xf9, +0x95, 0xd8, 0xf8, 0x94, 0xdd, 0xf8, 0xa3, 0xb1, +0xcf, 0x5f, 0xdd, 0xf7, 0xa2, 0xae, 0xce, 0x57, +0xd2, 0xf4, 0x84, 0xd6, 0xf4, 0x8d, 0xbc, 0xd3, +0x7d, 0xeb, 0xfe, 0xc9, 0xe4, 0xfc, 0xb8, 0xdd, +0xfa, 0xa4, 0xdd, 0xf9, 0xa2, 0xb6, 0xd1, 0x6c, +0x8f, 0xb0, 0x2a, 0xbb, 0xd2, 0x79, 0xda, 0xee, +0xab, 0xd7, 0xed, 0xa4, 0xb8, 0xd2, 0x71, 0x8e, +0xaf, 0x27, 0x72, 0x37, 0xf8, 0x42, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x60, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0x60, 0xa0, 0x06, 0x60, 0x64, +0x62, 0x66, 0x66, 0x62, 0x44, 0xe2, 0xb3, 0xb0, +0xb2, 0xb1, 0x73, 0x70, 0x22, 0x44, 0x98, 0x58, +0xb9, 0xb8, 0x79, 0x78, 0xf9, 0xf8, 0x21, 0x40, +0x80, 0x81, 0x81, 0x99, 0x4d, 0x90, 0x5f, 0x48, +0x58, 0x44, 0x54, 0x4c, 0x5c, 0x42, 0x52, 0x4a, +0x9a, 0x1f, 0x28, 0x20, 0x23, 0xcb, 0x2f, 0x27, +0xaf, 0xa0, 0xa8, 0xa4, 0xac, 0xa2, 0xaa, 0x06, +0x52, 0xc1, 0xa4, 0xae, 0xa1, 0xa9, 0xa5, 0xad, +0xc3, 0x2f, 0x00, 0x84, 0x20, 0x3e, 0x03, 0xa3, +0xae, 0x9e, 0xbe, 0x81, 0xa1, 0x11, 0x23, 0x6e, +0x6b, 0xa9, 0x00, 0x00, 0x17, 0xe6, 0x06, 0x39, +0xcf, 0x53, 0xa2, 0x70, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *key_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_key_png = new wxImage(); + if (!img_key_png || !img_key_png->IsOk()) + { + wxMemoryInputStream img_key_pngIS(key_png_data, sizeof(key_png_data)); + img_key_png->LoadFile(img_key_pngIS, wxBITMAP_TYPE_PNG); + } + return img_key_png; +} +#define key_png_img key_png_img() + +static wxBitmap *key_png_bmp() +{ + static wxBitmap *bmp_key_png; + if (!bmp_key_png || !bmp_key_png->IsOk()) + bmp_key_png = new wxBitmap(*key_png_img); + return bmp_key_png; +} +#define key_png_bmp key_png_bmp() + +static wxIcon *key_png_ico() +{ + static wxIcon *ico_key_png; + if (!ico_key_png || !ico_key_png->IsOk()) + { + ico_key_png = new wxIcon(); + ico_key_png->CopyFromBitmap(*key_png_bmp); + } + return ico_key_png; +} +#define key_png_ico key_png_ico() + +#endif // KEY_PNG_H diff --git a/include/images/language-sm.png b/include/images/language-sm.png new file mode 100644 index 0000000000000000000000000000000000000000..432d2f44231c1f88e787091060efc5125d80ef64 GIT binary patch literal 423 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}QGic~E0BJDv+cp5$Qv6qzrVk7 zW3&9@vzBik`G5Ho|K-)uTicc2-1GkNGyU0x%oo?3fBedPak1gnHlr`^;(z|izO~Kb z%lm|1zjI$+bN~H2|Mm{mcMpR9{3*J*S>f3^`;Si}e|^pQ`={jETDdE$#Qyy)dv><$ z|KAGswyocQwlbCk`2{mLJiCzwvL>2>S4={E+nQaGTe!Vz zahdU=*X&ESFOpJE*&;e)`qd3*DpaT5u9JDLS%3P((k)@IsOk()) + { + wxMemoryInputStream img_language_sm_pngIS(language_sm_png_data, sizeof(language_sm_png_data)); + img_language_sm_png->LoadFile(img_language_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_language_sm_png; +} +#define language_sm_png_img language_sm_png_img() + +static wxBitmap *language_sm_png_bmp() +{ + static wxBitmap *bmp_language_sm_png; + if (!bmp_language_sm_png || !bmp_language_sm_png->IsOk()) + bmp_language_sm_png = new wxBitmap(*language_sm_png_img); + return bmp_language_sm_png; +} +#define language_sm_png_bmp language_sm_png_bmp() + +static wxIcon *language_sm_png_ico() +{ + static wxIcon *ico_language_sm_png; + if (!ico_language_sm_png || !ico_language_sm_png->IsOk()) + { + ico_language_sm_png = new wxIcon(); + ico_language_sm_png->CopyFromBitmap(*language_sm_png_bmp); + } + return ico_language_sm_png; +} +#define language_sm_png_ico language_sm_png_ico() + +#endif // LANGUAGE_SM_PNG_H diff --git a/include/images/language.png b/include/images/language.png new file mode 100644 index 0000000000000000000000000000000000000000..f391a0836c11c4bc3eb9d25e37340adf3e25d003 GIT binary patch literal 465 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}dw@@fE0BJ4H1XC}ldG$x-rk;b zbBn^`(-vB3jHJ%0Ymyt&2b z>xaajzp}r6O#1aZ_swnZ-@o(j?brSKHsR0jg12|(Jv?Ik>3Q^@KSejUDm^`G_u*04 zkB=FDei#4!Q*vdM*uTG}&(4%Q`v(SXV-scH!NM%y4?8OPq~)XwXYQue#$XVWA*#P5bMk*{PSFAAJ8$X zC9V-ADTyViR>?)FK#IZ0z|cU~&`8(7FvQ5f%EZ{p#8lhB)XKnM-aEZjC>nC}Q!>*k iAsP%U!5V<7O{@&eAR10h4_yP)z~JfX=d#Wzp$Py#z|P|U literal 0 HcmV?d00001 diff --git a/include/images/language.pngc b/include/images/language.pngc new file mode 100644 index 0000000..97125c2 --- /dev/null +++ b/include/images/language.pngc @@ -0,0 +1,103 @@ +#ifndef LANGUAGE_PNG_H +#define LANGUAGE_PNG_H + +static const unsigned char language_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x87, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xe2, 0xc5, 0x61, 0xda, +0xb5, 0x34, 0xd5, 0xab, 0x1a, 0xed, 0xdb, 0x9c, +0xd9, 0xb4, 0x20, 0xe3, 0xcb, 0x38, 0xec, 0xe0, +0x4c, 0xf2, 0xef, 0x5c, 0xf6, 0xf8, 0x65, 0xf0, +0xe2, 0xb0, 0xdf, 0xc3, 0x2f, 0xef, 0xe5, 0x52, +0xf8, 0xf9, 0x66, 0xdd, 0xbe, 0x2b, 0xf2, 0xeb, +0x5a, 0xf8, 0xf9, 0x68, 0xe5, 0xcb, 0x71, 0xea, +0xdb, 0x48, 0xf9, 0xfa, 0x69, 0xd9, 0xb4, 0x32, +0xf5, 0xf0, 0x61, 0xf9, 0xfa, 0x6b, 0xf5, 0xf1, +0x62, 0xfa, 0xfb, 0x6d, 0xec, 0xdb, 0x4b, 0xfb, +0xfb, 0x6e, 0xde, 0xbf, 0x2d, 0xf5, 0xed, 0x60, +0xfc, 0xfb, 0x70, 0xed, 0xdc, 0x9e, 0xe1, 0xc4, +0x33, 0xf2, 0xe7, 0x5b, 0xfc, 0xfc, 0x72, 0xd9, +0xb5, 0x22, 0xe5, 0xcd, 0x3e, 0xf0, 0xe2, 0x56, +0xf8, 0xf1, 0x68, 0xfc, 0xfb, 0x73, 0xfd, 0xfc, +0x74, 0xd4, 0xaa, 0x16, 0xfe, 0xfd, 0x75, 0xe6, +0xcd, 0x76, 0xfe, 0xfd, 0x77, 0xff, 0xfd, 0x78, +0xc4, 0x97, 0x4c, 0x3b, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x81, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x6d, 0xce, 0xe9, 0x0e, 0x82, 0x30, 0x10, 0x46, +0xd1, 0x01, 0xd9, 0xf7, 0xb2, 0xca, 0xa2, 0x55, +0x40, 0x6d, 0xc1, 0xf7, 0x7f, 0x3e, 0xa7, 0xd4, +0xd2, 0x90, 0x70, 0xfe, 0x7d, 0x37, 0x69, 0x3a, +0x00, 0x82, 0x61, 0x5e, 0x4c, 0xc3, 0x02, 0xc5, +0x76, 0x5c, 0xcf, 0xf7, 0x5c, 0xc7, 0x0e, 0xe4, +0x0e, 0xa3, 0x58, 0x8a, 0xc2, 0x6d, 0x27, 0x69, +0xa6, 0xa4, 0x09, 0x6e, 0x92, 0x17, 0x5a, 0x4e, +0x00, 0xca, 0xaa, 0xd6, 0xaa, 0x12, 0x43, 0x73, +0xd5, 0x1a, 0x0c, 0xa4, 0xed, 0xb4, 0x16, 0x9f, +0x40, 0x3f, 0xdc, 0x94, 0xa1, 0x17, 0xbf, 0xdc, +0xe9, 0xe3, 0xf9, 0x47, 0xe5, 0x1d, 0xc1, 0x38, +0xcd, 0xaf, 0xf7, 0x07, 0x31, 0x75, 0xaa, 0x85, +0xa7, 0x33, 0xce, 0xf9, 0x1e, 0x84, 0x85, 0xad, +0xeb, 0x21, 0x60, 0xf9, 0x1e, 0x03, 0x96, 0x05, +0x4e, 0xfc, 0x00, 0x5d, 0x43, 0x0e, 0x13, 0xf9, +0xce, 0x89, 0x8e, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *language_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_language_png = new wxImage(); + if (!img_language_png || !img_language_png->IsOk()) + { + wxMemoryInputStream img_language_pngIS(language_png_data, sizeof(language_png_data)); + img_language_png->LoadFile(img_language_pngIS, wxBITMAP_TYPE_PNG); + } + return img_language_png; +} +#define language_png_img language_png_img() + +static wxBitmap *language_png_bmp() +{ + static wxBitmap *bmp_language_png; + if (!bmp_language_png || !bmp_language_png->IsOk()) + bmp_language_png = new wxBitmap(*language_png_img); + return bmp_language_png; +} +#define language_png_bmp language_png_bmp() + +static wxIcon *language_png_ico() +{ + static wxIcon *ico_language_png; + if (!ico_language_png || !ico_language_png->IsOk()) + { + ico_language_png = new wxIcon(); + ico_language_png->CopyFromBitmap(*language_png_bmp); + } + return ico_language_png; +} +#define language_png_ico language_png_ico() + +#endif // LANGUAGE_PNG_H diff --git a/include/images/languages.png b/include/images/languages.png new file mode 100644 index 0000000000000000000000000000000000000000..e730cb2ec034b8ad0860a945fde442e8b698c83d GIT binary patch literal 477 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}SAb85E0BJ3YvzMPkvBGK-q7T!{zq~y1>v!(&-}&zz1poO{baS)9 zvvc+zpGN-rn)CNh$+fj|S5}Gr`&;(xY}x<66?UsN(t)mFED7=pW^j0RBMr#mEbxdd z2GSm2>~=ES4#?>8ba4!kxE$JlQ>@8=hxKsWg{al8YedCe4mSP&U)?4&{ap03GlzK@ z90c3~B@Rrt@Z7B9o8(p=r!%ca^+?p2?N4UEU0&!k)p~#6)qD9%>~3b?Sv8x#U^17aMMww)MOF^{=(Rt2quWmu2Jr-}CJ$w~6ur zX+A&R+4(bNJ_B8)TH+c}l9E`GYL#4+3Zxi}3=9o)4UKdS3`2|ztW1opOiZ;6OsxzI u=DpKfg`y!hKP5A*5~9Jt608BJ+QiDh45H!G^w2dx4Gf;HelF{r5}E*I-p~I4 literal 0 HcmV?d00001 diff --git a/include/images/languages.pngc b/include/images/languages.pngc new file mode 100644 index 0000000..86fd422 --- /dev/null +++ b/include/images/languages.pngc @@ -0,0 +1,104 @@ +#ifndef LANGUAGES_PNG_H +#define LANGUAGES_PNG_H + +static const unsigned char languages_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x8a, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xec, 0xda, 0x99, 0xe0, +0xc2, 0x59, 0xd8, 0xb1, 0x29, 0xd8, 0xb3, 0x1f, +0xe3, 0xcd, 0x39, 0xed, 0xe2, 0x4f, 0xf4, 0xf2, +0x5f, 0xf4, 0xea, 0xc5, 0xda, 0xb7, 0x23, 0xec, +0xde, 0x4b, 0xf8, 0xf9, 0x67, 0xf4, 0xf0, 0x5e, +0xe8, 0xd6, 0x43, 0xde, 0xc1, 0x2d, 0xd7, 0xb1, +0x1d, 0xdb, 0xb9, 0x25, 0xe8, 0xd1, 0x80, 0xf8, +0xfa, 0x69, 0xef, 0xe6, 0x54, 0xda, 0xb6, 0x38, +0xf4, 0xee, 0x5f, 0xf3, 0xed, 0x5d, 0xf4, 0xef, +0x60, 0xe5, 0xcf, 0x3e, 0xe9, 0xd6, 0x47, 0xda, +0xb6, 0x23, 0xdb, 0xb8, 0x25, 0xd8, 0xb2, 0x1f, +0xd6, 0xae, 0x1b, 0xf9, 0xfa, 0x6b, 0xf4, 0xe9, +0xc4, 0xfa, 0xfb, 0x6d, 0xfb, 0xfb, 0x6f, 0xee, +0xe0, 0x53, 0xfc, 0xfc, 0x72, 0xd9, 0xb3, 0x20, +0xe6, 0xce, 0x3f, 0xf1, 0xe5, 0x59, 0xfa, 0xf5, +0x6c, 0xfd, 0xfc, 0x74, 0xd6, 0xad, 0x1e, 0xd4, +0xaa, 0x16, 0xfe, 0xfd, 0x76, 0xe6, 0xcd, 0x76, +0xff, 0xfd, 0x78, 0x3e, 0xab, 0x28, 0x67, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x8a, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x55, 0x8f, 0xd9, 0x16, 0x82, +0x30, 0x0c, 0x05, 0xc3, 0x5e, 0xd0, 0x5a, 0xab, +0x45, 0xac, 0x15, 0x17, 0x44, 0xc1, 0x82, 0xff, +0xff, 0x7b, 0x86, 0x12, 0x97, 0xce, 0x5b, 0xe6, +0xcc, 0xc3, 0x0d, 0x00, 0x40, 0x10, 0x46, 0x51, +0x18, 0xc0, 0x97, 0x38, 0x49, 0xb3, 0x2c, 0x4d, +0x62, 0x46, 0x77, 0x5e, 0x2c, 0x96, 0x7c, 0x25, +0xc4, 0x5a, 0xcc, 0xb7, 0xe4, 0x9b, 0xed, 0xa7, +0x71, 0x42, 0x95, 0x3b, 0xbf, 0x51, 0xd5, 0xde, +0x6f, 0xa4, 0x3e, 0xb8, 0xc6, 0x51, 0xe4, 0x68, +0xcc, 0x71, 0x6a, 0x08, 0x2e, 0xd1, 0xd4, 0xd8, +0x9c, 0x88, 0x52, 0xa1, 0x38, 0x63, 0x73, 0x21, +0xaa, 0x49, 0x00, 0xab, 0xf5, 0x95, 0xd0, 0x72, +0x1e, 0x63, 0x9a, 0x9b, 0xa3, 0x31, 0xb4, 0x96, +0xb5, 0xf7, 0x47, 0xd7, 0xf5, 0x7d, 0xfb, 0x7b, +0x08, 0xc2, 0xa7, 0x1d, 0x06, 0x0b, 0xff, 0x8c, +0xf6, 0xe5, 0x0b, 0x34, 0x23, 0xc0, 0x1b, 0x0e, +0x4e, 0x0d, 0x9b, 0x6f, 0x99, 0x1c, 0xf3, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *languages_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_languages_png = new wxImage(); + if (!img_languages_png || !img_languages_png->IsOk()) + { + wxMemoryInputStream img_languages_pngIS(languages_png_data, sizeof(languages_png_data)); + img_languages_png->LoadFile(img_languages_pngIS, wxBITMAP_TYPE_PNG); + } + return img_languages_png; +} +#define languages_png_img languages_png_img() + +static wxBitmap *languages_png_bmp() +{ + static wxBitmap *bmp_languages_png; + if (!bmp_languages_png || !bmp_languages_png->IsOk()) + bmp_languages_png = new wxBitmap(*languages_png_img); + return bmp_languages_png; +} +#define languages_png_bmp languages_png_bmp() + +static wxIcon *languages_png_ico() +{ + static wxIcon *ico_languages_png; + if (!ico_languages_png || !ico_languages_png->IsOk()) + { + ico_languages_png = new wxIcon(); + ico_languages_png->CopyFromBitmap(*languages_png_bmp); + } + return ico_languages_png; +} +#define languages_png_ico languages_png_ico() + +#endif // LANGUAGES_PNG_H diff --git a/include/images/loginroles.png b/include/images/loginroles.png new file mode 100644 index 0000000000000000000000000000000000000000..33f2621d6f5444fec5f27839b3b0aff3410ff3be GIT binary patch literal 767 zcmVf!h5;`8R=$-ljjjEth5 zn&j8c_v+yH>g4z8=jqcY9bhl7P~ZEdBWpWM;Y-> zpr@z5%7~btXm4_Rfr7u%*U{+k&gbyY-`3T?WXrHV;LnS$&fa>6kdu~{q_MTl;o;D> zP3YXC?&!GS(1XRdT%EA0mX>{mh>5$;)yn1Y+QxO~+n?>_vG3`x^6akN%Wu!MKhL#2 z&$T+wv^LMRJkq*VZE$hP;p)cY@$c!q+sJX|+Kuq&mGSAA?&Os5=$Gi)c=G6j>DzhH zw@X-9SZ8Z&Woc{H!D;B-qUqk7?Btp8>6hWqaoEFO*uq)b#%b2SM$@}Y*1u)byH@Gm zo$ltN00001bW%=J06^y0W&i*H32;bRa{vGUNB{r;NB~C3 zYd!z~0Jcd)K~xyiV_*ORMkZ!P1|-13%Er#YiQsc_^YHTV3kbpmgoH)-M8(7<-~y6T zK)$q$EL=cN9>`ZvRDugAtEfsVsHtlpOx4uV*3s3|hw}{#jf_o9&CD&Jd`l~98(TYj z2S+Ce-`U05#?{T;!_&*#2Q1+0XX76b7!({58WtWA85PYC6YC#mAD@tzl$?^9mY$Kx zkd>X2lbe@cP*_x4Qd(AC0Wqkus=B5Y*}n{R^)MCyJQpH2u&$kv0000bbVXQnWMOn= zI%9HWVRU5xGB7bPEip1JFfmjzFgi3dIy5yaFf}?bFrMx%ssI20C3HntbYx+4Wjbwd xWNBu305UK!FfA}SEif@uGBY|fG&(RgD=;-WFfhuORjdF2002ovPDHLkV1hRbj(z|D literal 0 HcmV?d00001 diff --git a/include/images/loginroles.pngc b/include/images/loginroles.pngc new file mode 100644 index 0000000..531a5fc --- /dev/null +++ b/include/images/loginroles.pngc @@ -0,0 +1,140 @@ +#ifndef LOGINROLES_PNG_H +#define LOGINROLES_PNG_H + +static const unsigned char loginroles_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x99, 0x99, 0x99, 0x70, +0x70, 0x70, 0x6a, 0x6a, 0x6a, 0x98, 0x95, 0x92, +0xb1, 0xa8, 0xa2, 0xe1, 0xd5, 0xcb, 0xe6, 0xda, +0xd2, 0xb7, 0xaf, 0xab, 0x93, 0x8f, 0x8e, 0x91, +0x8d, 0x8a, 0xbd, 0xb4, 0xad, 0xf1, 0xe3, 0xd9, +0xf7, 0xea, 0xe1, 0xf7, 0xea, 0xe2, 0xf3, 0xe6, +0xe1, 0xc9, 0xbf, 0xbd, 0x90, 0x8c, 0x8c, 0xa2, +0x9e, 0x9a, 0xe4, 0xd7, 0xce, 0xf7, 0xea, 0xe0, +0xf7, 0xea, 0xe4, 0xf7, 0xea, 0xe7, 0xe9, 0xde, +0xdd, 0xad, 0xa7, 0xa8, 0x9e, 0x99, 0x95, 0xef, +0xe2, 0xd9, 0xf7, 0xea, 0xe9, 0xf1, 0xe4, 0xe6, +0xaf, 0xa9, 0xaa, 0xa3, 0x9f, 0x9d, 0xe0, 0xd5, +0xcf, 0xf7, 0xea, 0xeb, 0xe8, 0xdc, 0xdf, 0xab, +0xa6, 0xa7, 0x89, 0x85, 0x84, 0xb6, 0xae, 0xab, +0xef, 0xe2, 0xe0, 0xf2, 0xe6, 0xea, 0xc2, 0xb9, +0xbd, 0x87, 0x83, 0x85, 0x6e, 0x6d, 0x6d, 0xa5, +0x9f, 0x9f, 0xdc, 0xd1, 0xd3, 0xe3, 0xd8, 0xda, +0xad, 0xa6, 0xa9, 0x73, 0x71, 0x72, 0x5a, 0x5c, +0x5c, 0x8b, 0x94, 0x95, 0xb3, 0xc3, 0xc7, 0x9c, +0xa9, 0xad, 0x77, 0x7e, 0x80, 0x71, 0x78, 0x7b, +0x90, 0xa0, 0xa7, 0xa7, 0xbf, 0xca, 0x88, 0x98, +0xa0, 0x68, 0x6f, 0x72, 0x7b, 0x81, 0x82, 0xbf, +0xd2, 0xd7, 0xd1, 0xe8, 0xf0, 0xce, 0xe7, 0xf0, +0xcf, 0xdf, 0xd6, 0xd5, 0xbf, 0x64, 0xcb, 0xb0, +0x3e, 0xe0, 0xcf, 0x8b, 0xae, 0xce, 0xde, 0x7a, +0x88, 0x90, 0x93, 0x96, 0x96, 0xa4, 0xb1, 0xb5, +0xcd, 0xe1, 0xe1, 0xd0, 0xb6, 0x4d, 0xe8, 0xdc, +0xa3, 0xee, 0xe8, 0xb8, 0xe0, 0xd0, 0x83, 0xc5, +0xb7, 0x5c, 0x9d, 0xb0, 0xaa, 0x96, 0x96, 0x7d, +0x85, 0x88, 0x89, 0xbb, 0xcf, 0xd5, 0xca, 0xe5, +0xf0, 0xda, 0xc6, 0x75, 0xe7, 0xdb, 0x9f, 0xed, +0xe5, 0xb1, 0xef, 0xe9, 0xaf, 0xf2, 0xec, 0xae, +0xdd, 0xcb, 0x6f, 0xcf, 0xb5, 0x3f, 0xcf, 0xb5, +0x3d, 0xcf, 0xb5, 0x3a, 0xcf, 0xb4, 0x36, 0xcf, +0xb5, 0x3c, 0xd2, 0xba, 0x55, 0x6d, 0x70, 0x71, +0xc9, 0xe1, 0xea, 0xc6, 0xe3, 0xf1, 0xef, 0xe9, +0xbd, 0xdb, 0xc8, 0x71, 0xe6, 0xda, 0x8d, 0xf0, +0xe8, 0x95, 0xf1, 0xe9, 0x98, 0xee, 0xe4, 0x94, +0xf1, 0xe8, 0x97, 0xe8, 0xda, 0x78, 0xf2, 0xe8, +0x83, 0xe9, 0xdb, 0x79, 0xd1, 0xb7, 0x4b, 0x58, +0x58, 0x58, 0x67, 0x6b, 0x6c, 0x65, 0x69, 0x6b, +0xd6, 0xc1, 0x69, 0xe8, 0xdd, 0xa2, 0xe9, 0xde, +0x9b, 0xec, 0xe4, 0x99, 0xf1, 0xe9, 0x97, 0xe1, +0xd0, 0x71, 0xd8, 0xc3, 0x5f, 0xd8, 0xc2, 0x59, +0xda, 0xc6, 0x69, 0xd6, 0xbf, 0x46, 0xd3, 0xbb, +0x4c, 0xd6, 0xbf, 0x65, 0xd3, 0xbb, 0x56, 0xe9, +0xde, 0x9d, 0xee, 0xe6, 0xa3, 0xe3, 0xd3, 0x7e, +0xcc, 0xb0, 0x39, 0xd7, 0xc3, 0x6a, 0xcf, 0xb7, +0x4c, 0x00, 0x1e, 0xb5, 0x77, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0xb6, 0x49, 0x44, 0x41, 0x54, 0x18, +0xd3, 0x63, 0x60, 0x00, 0x02, 0x46, 0x26, 0x66, +0x46, 0x06, 0x24, 0xc0, 0xc2, 0xca, 0xc6, 0xce, +0xc1, 0x89, 0xe0, 0x73, 0x71, 0xf3, 0xf0, 0xf2, +0xf1, 0x0b, 0x08, 0xc2, 0x05, 0x84, 0x84, 0x45, +0xf8, 0x44, 0xc5, 0xc4, 0x25, 0xe0, 0x02, 0x92, +0x52, 0x40, 0xbe, 0xb4, 0x8c, 0x2c, 0x5c, 0x40, +0x4e, 0x1e, 0xc8, 0x57, 0x50, 0x54, 0x82, 0x0b, +0x28, 0xab, 0xa8, 0x4a, 0x2b, 0xa8, 0xa9, 0x6b, +0x20, 0x4c, 0xd5, 0xd4, 0xd2, 0xd6, 0xd1, 0xd5, +0xd3, 0x87, 0xf3, 0x0d, 0x0c, 0x8d, 0x8c, 0x4d, +0x4c, 0xcd, 0xcc, 0x2d, 0xa0, 0x7c, 0x4b, 0x2b, +0x6b, 0x1b, 0x5b, 0x3b, 0x7b, 0x07, 0x47, 0x27, +0x08, 0xdf, 0xd9, 0xc5, 0xda, 0xc6, 0xd5, 0xcd, +0xdd, 0xc3, 0xd3, 0xcb, 0xdb, 0x07, 0x2c, 0xe0, +0xeb, 0x67, 0xe3, 0x1f, 0x10, 0x18, 0x14, 0x1c, +0x12, 0x1a, 0x16, 0x1e, 0x11, 0x19, 0x15, 0xcd, +0x10, 0x13, 0xeb, 0x1f, 0x67, 0x1f, 0x9f, 0x90, +0x98, 0x94, 0x9c, 0x92, 0x9a, 0x96, 0x9e, 0x91, +0xc9, 0x90, 0x95, 0x9d, 0x93, 0x93, 0x9b, 0x97, +0x5f, 0x50, 0x58, 0x54, 0x5c, 0x52, 0x5a, 0x56, +0x5e, 0x01, 0x31, 0xa8, 0xb2, 0xaa, 0xba, 0xa6, +0x16, 0xd9, 0xbf, 0x0c, 0x75, 0xf5, 0x30, 0x16, +0x00, 0x3c, 0x17, 0x22, 0x37, 0xb0, 0xae, 0x9d, +0x91, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, +0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *loginroles_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_loginroles_png = new wxImage(); + if (!img_loginroles_png || !img_loginroles_png->IsOk()) + { + wxMemoryInputStream img_loginroles_pngIS(loginroles_png_data, sizeof(loginroles_png_data)); + img_loginroles_png->LoadFile(img_loginroles_pngIS, wxBITMAP_TYPE_PNG); + } + return img_loginroles_png; +} +#define loginroles_png_img loginroles_png_img() + +static wxBitmap *loginroles_png_bmp() +{ + static wxBitmap *bmp_loginroles_png; + if (!bmp_loginroles_png || !bmp_loginroles_png->IsOk()) + bmp_loginroles_png = new wxBitmap(*loginroles_png_img); + return bmp_loginroles_png; +} +#define loginroles_png_bmp loginroles_png_bmp() + +static wxIcon *loginroles_png_ico() +{ + static wxIcon *ico_loginroles_png; + if (!ico_loginroles_png || !ico_loginroles_png->IsOk()) + { + ico_loginroles_png = new wxIcon(); + ico_loginroles_png->CopyFromBitmap(*loginroles_png_bmp); + } + return ico_loginroles_png; +} +#define loginroles_png_ico loginroles_png_ico() + +#endif // LOGINROLES_PNG_H diff --git a/include/images/module.mk b/include/images/module.mk new file mode 100644 index 0000000..6d60abf --- /dev/null +++ b/include/images/module.mk @@ -0,0 +1,330 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - include/images/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/images/aggregate-sm.png \ + include/images/aggregate.png \ + include/images/aggregates.png \ + include/images/back.png \ + include/images/backup.png \ + include/images/baddatabase.png \ + include/images/cast-sm.png \ + include/images/cast.png \ + include/images/casts.png \ + include/images/catalog.png \ + include/images/catalog-sm.png \ + include/images/catalogs.png \ + include/images/catalogobject.png \ + include/images/catalogobject-sm.png \ + include/images/catalogobjects.png \ + include/images/check.png \ + include/images/checkbad.png \ + include/images/checked.png \ + include/images/clearAll.png \ + include/images/clip_copy.png \ + include/images/clip_cut.png \ + include/images/clip_paste.png \ + include/images/closeddatabase-sm.png \ + include/images/closeddatabase.png \ + include/images/collation-sm.png \ + include/images/collation.png \ + include/images/collations.png \ + include/images/column-sm.png \ + include/images/column.png \ + include/images/columns.png \ + include/images/configuration.png \ + include/images/configurations.png \ + include/images/connect.png \ + include/images/constraints.png \ + include/images/continue.png \ + include/images/conversion.png \ + include/images/conversions.png \ + include/images/create.png \ + include/images/database-sm.png \ + include/images/database.png \ + include/images/databases.png \ + include/images/ddAddColumn.png \ + include/images/ddAddColumnCursor.png \ + include/images/ddAddForeignKey.png \ + include/images/ddDeleteTableCursor.png \ + include/images/ddDown.png \ + include/images/ddMaximizeTable.png \ + include/images/ddMinMaxCursor.png \ + include/images/ddMinimizeTable.png \ + include/images/ddRelationshipCursor.png \ + include/images/ddRemoveColumn.png \ + include/images/ddRemoveColumnCursor.png \ + include/images/ddRemoveTable.png \ + include/images/ddRemoveTable2.png \ + include/images/ddUp.png \ + include/images/ddcancel.png \ + include/images/ddforeignkey.png \ + include/images/ddforeignkeyfromuk.png \ + include/images/ddforeignkeyuniquekey.png \ + include/images/ddforeignkeyuniquekeyfromuk.png \ + include/images/ddgendiagram.png \ + include/images/ddmodel-32.png \ + include/images/ddnewdiagram.png \ + include/images/ddnotnull.png \ + include/images/ddnull.png \ + include/images/ddprimaryforeignkey.png \ + include/images/ddprimaryforeignkeyfromuk.png \ + include/images/ddprimarykey.png \ + include/images/ddprimarykeyuniquekey.png \ + include/images/ddunique.png \ + include/images/debugger.png \ + include/images/delete.png \ + include/images/dictionary.png \ + include/images/dictionaries.png \ + include/images/disabled.png \ + include/images/dnd_copy.png \ + include/images/dnd_move.png \ + include/images/dnd_none.png \ + include/images/domain-sm.png \ + include/images/domain.png \ + include/images/domains.png \ + include/images/extension-sm.png \ + include/images/extension.png \ + include/images/extensions.png \ + include/images/down.png \ + include/images/drop.png \ + include/images/edit_clear.png \ + include/images/edit_find.png \ + include/images/edit_redo.png \ + include/images/edit_undo.png \ + include/images/enumeration.png \ + include/images/enumerations.png \ + include/images/ex_aggregate.png \ + include/images/ex_append.png \ + include/images/ex_bmp_and.png \ + include/images/ex_bmp_heap.png \ + include/images/ex_bmp_index.png \ + include/images/ex_bmp_or.png \ + include/images/ex_cte_scan.png \ + include/images/ex_delete.png \ + include/images/ex_foreign_scan.png \ + include/images/ex_group.png \ + include/images/ex_hash.png \ + include/images/ex_hash_anti_join.png \ + include/images/ex_hash_semi_join.png \ + include/images/ex_hash_setop_except.png \ + include/images/ex_hash_setop_except_all.png \ + include/images/ex_hash_setop_intersect.png \ + include/images/ex_hash_setop_intersect_all.png \ + include/images/ex_hash_setop_unknown.png \ + include/images/ex_index_only_scan.png \ + include/images/ex_index_scan.png \ + include/images/ex_insert.png \ + include/images/ex_join.png \ + include/images/ex_limit.png \ + include/images/ex_lock_rows.png \ + include/images/ex_materialize.png \ + include/images/ex_merge.png \ + include/images/ex_merge_anti_join.png \ + include/images/ex_merge_append.png \ + include/images/ex_merge_semi_join.png \ + include/images/ex_nested.png \ + include/images/ex_nested_loop_anti_join.png \ + include/images/ex_nested_loop_semi_join.png \ + include/images/ex_recursive_union.png \ + include/images/ex_result.png \ + include/images/ex_scan.png \ + include/images/ex_seek.png \ + include/images/ex_setop.png \ + include/images/ex_sort.png \ + include/images/ex_subplan.png \ + include/images/ex_tid_scan.png \ + include/images/ex_unique.png \ + include/images/ex_unknown.png \ + include/images/ex_update.png \ + include/images/ex_values_scan.png \ + include/images/ex_window_aggregate.png \ + include/images/ex_worktable_scan.png \ + include/images/exclude.png \ + include/images/favourite.png \ + include/images/file_new.png \ + include/images/file_open.png \ + include/images/file_save.png \ + include/images/folder.png \ + include/images/foreigndatawrapper.png \ + include/images/foreigndatawrapper-sm.png \ + include/images/foreigndatawrappers.png \ + include/images/foreignkey.png \ + include/images/foreignkeybad.png \ + include/images/foreignserver.png \ + include/images/foreignserver-sm.png \ + include/images/foreignservers.png \ + include/images/foreigntable.png \ + include/images/foreigntables.png \ + include/images/forward.png \ + include/images/function.png \ + include/images/functions.png \ + include/images/gqbAdd.png \ + include/images/gqbAddRest.png \ + include/images/gqbColNotSel.png \ + include/images/gqbColSel.png \ + include/images/gqbDown.png \ + include/images/gqbDownBottom.png \ + include/images/gqbJoin.png \ + include/images/gqbJoinCursor.png \ + include/images/gqbOrderAdd.png \ + include/images/gqbOrderAddAll.png \ + include/images/gqbOrderRemove.png \ + include/images/gqbOrderRemoveAll.png \ + include/images/gqbRemove.png \ + include/images/gqbRemoveRest.png \ + include/images/gqbUp.png \ + include/images/gqbUpTop.png \ + include/images/group.png \ + include/images/groups.png \ + include/images/help.png \ + include/images/help2.png \ + include/images/hint.png \ + include/images/hint2.png \ + include/images/index.png \ + include/images/indexes.png \ + include/images/job.png \ + include/images/jobdisabled.png \ + include/images/jobs.png \ + include/images/key.png \ + include/images/language-sm.png \ + include/images/language.png \ + include/images/languages.png \ + include/images/loginroles.png \ + include/images/mview.png \ + include/images/mview-sm.png \ + include/images/namespace-sm.png \ + include/images/namespace.png \ + include/images/namespaces.png \ + include/images/operator.png \ + include/images/operators.png \ + include/images/operatorclass.png \ + include/images/operatorclasses.png \ + include/images/operatorfamily.png \ + include/images/operatorfamilies.png \ + include/images/package.png \ + include/images/packages.png \ + include/images/parser.png \ + include/images/parsers.png \ + include/images/plugins.png \ + include/images/pgAdmin3.png \ + include/images/pgAdmin3-16.png \ + include/images/pgAdmin3-32.png \ + include/images/primarykey.png \ + include/images/procedures.png \ + include/images/procedure.png \ + include/images/properties.png \ + include/images/property.png \ + include/images/query_cancel.png \ + include/images/query_execfile.png \ + include/images/query_execute.png \ + include/images/query_explain.png \ + include/images/query_commit.png \ + include/images/query_rollback.png \ + include/images/query_pgscript.png \ + include/images/readdata.png \ + include/images/refresh.png \ + include/images/reload.png \ + include/images/resourcegroup.png \ + include/images/resourcegroups.png \ + include/images/restore.png \ + include/images/roles.png \ + include/images/rule.png \ + include/images/rulebad.png \ + include/images/rules.png \ + include/images/schedule.png \ + include/images/schedules.png \ + include/images/sequence-repl.png \ + include/images/sequence.png \ + include/images/sequences.png \ + include/images/server-sm.png \ + include/images/server.png \ + include/images/serverbad-sm.png \ + include/images/serverbad.png \ + include/images/servers.png \ + include/images/setBreak.png \ + include/images/slcluster.png \ + include/images/slclusters.png \ + include/images/sllisten.png \ + include/images/sllistens.png \ + include/images/slnode-disabled.png \ + include/images/slnode-local.png \ + include/images/slnode.png \ + include/images/slnodes.png \ + include/images/slpath.png \ + include/images/slpaths.png \ + include/images/slset.png \ + include/images/slset2.png \ + include/images/slsets.png \ + include/images/slsubscription.png \ + include/images/slsubscription2.png \ + include/images/slsubscriptions.png \ + include/images/sortfilter.png \ + include/images/splash.png \ + include/images/sql.png \ + include/images/sql-16.png \ + include/images/sql-32.png \ + include/images/statistics.png \ + include/images/step.png \ + include/images/steps.png \ + include/images/stepInto.png \ + include/images/stepOver.png \ + include/images/stop.png \ + include/images/storedata.png \ + include/images/synonym.png \ + include/images/synonyms.png \ + include/images/table-repl-sm.png \ + include/images/table-repl.png \ + include/images/table-sm.png \ + include/images/table.png \ + include/images/tables.png \ + include/images/tablespace.png \ + include/images/tablespaces.png \ + include/images/template.png \ + include/images/templates.png \ + include/images/terminate_backend.png \ + include/images/textsearch.png \ + include/images/trigger.png \ + include/images/triggerbad.png \ + include/images/triggerfunction.png \ + include/images/triggerfunctions.png \ + include/images/triggers.png \ + include/images/type.png \ + include/images/types.png \ + include/images/uncheck.png \ + include/images/unchecked.png \ + include/images/unique.png \ + include/images/up.png \ + include/images/user.png \ + include/images/usermapping.png \ + include/images/usermapping-sm.png \ + include/images/usermappings.png \ + include/images/users.png \ + include/images/vacuum.png \ + include/images/variable.png \ + include/images/variables.png \ + include/images/view-sm.png \ + include/images/view.png \ + include/images/viewdata.png \ + include/images/viewfiltereddata.png \ + include/images/views.png \ + include/images/ex_broadcast_motion.png \ + include/images/ex_redistribute_motion.png \ + include/images/ex_gather_motion.png \ + include/images/exttable-sm.png \ + include/images/exttables.png \ + include/images/exttable.png + +EXTRA_DIST += \ + include/images/module.mk \ + include/images/pgAdmin3.ico \ + include/images/sql.ico + diff --git a/include/images/mview-sm.png b/include/images/mview-sm.png new file mode 100644 index 0000000000000000000000000000000000000000..7b72bdbb024d206a9ccccc307b980af7dc9cea88 GIT binary patch literal 344 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9GG!XV7ZFl&wk0|O(M zr;B5V#p&b(iHrjr$vHbE{{BC@z1bzxXo_Zv!8F~plmsAXD*x6OT+Cpd08n!IM#^LZ1F3M3y)72cH;)3)hB@w(<$ENtuI!+37X&3YKpe7)iO zo7EB_E>059WTrQES9;xXdidD%!K10kJRqPs&0k{Df9H%vu?(M!xtNs?&v|Ub)6*j$ zbyq+v$yxg5%?jQE!}Cc$KEG!_e82v_q}|_|69*1#=yHs8ZfyjDhri#K1C8IsOk()) + { + wxMemoryInputStream img_mview_sm_pngIS(mview_sm_png_data, sizeof(mview_sm_png_data)); + img_mview_sm_png->LoadFile(img_mview_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_mview_sm_png; +} +#define mview_sm_png_img mview_sm_png_img() + +static wxBitmap *mview_sm_png_bmp() +{ + static wxBitmap *bmp_mview_sm_png; + if (!bmp_mview_sm_png || !bmp_mview_sm_png->IsOk()) + bmp_mview_sm_png = new wxBitmap(*mview_sm_png_img); + return bmp_mview_sm_png; +} +#define mview_sm_png_bmp mview_sm_png_bmp() + +static wxIcon *mview_sm_png_ico() +{ + static wxIcon *ico_mview_sm_png; + if (!ico_mview_sm_png || !ico_mview_sm_png->IsOk()) + { + ico_mview_sm_png = new wxIcon(); + ico_mview_sm_png->CopyFromBitmap(*mview_sm_png_bmp); + } + return ico_mview_sm_png; +} +#define mview_sm_png_ico mview_sm_png_ico() + +#endif // MVIEW_SM_PNG_H diff --git a/include/images/mview.png b/include/images/mview.png new file mode 100644 index 0000000000000000000000000000000000000000..40e65a96e18004104b041b0ae32579b26ae97058 GIT binary patch literal 374 zcmV-+0g3*JP)PA(>hLAOE$2b!1V^ni|PnE{A)5-}!eBlsp2!8Jwv{ z_xxYN&Za98fNAM!r+Elb4K)_xh3TSloEv+sugkCnz_QX^u*q6^bIsOk()) + { + wxMemoryInputStream img_mview_pngIS(mview_png_data, sizeof(mview_png_data)); + img_mview_png->LoadFile(img_mview_pngIS, wxBITMAP_TYPE_PNG); + } + return img_mview_png; +} +#define mview_png_img mview_png_img() + +static wxBitmap *mview_png_bmp() +{ + static wxBitmap *bmp_mview_png; + if (!bmp_mview_png || !bmp_mview_png->IsOk()) + bmp_mview_png = new wxBitmap(*mview_png_img); + return bmp_mview_png; +} +#define mview_png_bmp mview_png_bmp() + +static wxIcon *mview_png_ico() +{ + static wxIcon *ico_mview_png; + if (!ico_mview_png || !ico_mview_png->IsOk()) + { + ico_mview_png = new wxIcon(); + ico_mview_png->CopyFromBitmap(*mview_png_bmp); + } + return ico_mview_png; +} +#define mview_png_ico mview_png_ico() + +#endif // MVIEW_PNG_H diff --git a/include/images/namespace-sm.png b/include/images/namespace-sm.png new file mode 100644 index 0000000000000000000000000000000000000000..b16dc1e2567a1d295d190646b8d3f45864f09431 GIT binary patch literal 322 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFv5AX?b1=2UBOxf${`MnH^(Wh@Eu3ubV5b|VeMN%D4gVM|QgQ48d7 z7I;J!18EO1b~~AE2V}TJ4CcMlTZN(_H$NpatrDWaz!Izh bsM^HJzzm|{)b!9bKn)C@u6{1-oD!MIsOk()) + { + wxMemoryInputStream img_namespace_sm_pngIS(namespace_sm_png_data, sizeof(namespace_sm_png_data)); + img_namespace_sm_png->LoadFile(img_namespace_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_namespace_sm_png; +} +#define namespace_sm_png_img namespace_sm_png_img() + +static wxBitmap *namespace_sm_png_bmp() +{ + static wxBitmap *bmp_namespace_sm_png; + if (!bmp_namespace_sm_png || !bmp_namespace_sm_png->IsOk()) + bmp_namespace_sm_png = new wxBitmap(*namespace_sm_png_img); + return bmp_namespace_sm_png; +} +#define namespace_sm_png_bmp namespace_sm_png_bmp() + +static wxIcon *namespace_sm_png_ico() +{ + static wxIcon *ico_namespace_sm_png; + if (!ico_namespace_sm_png || !ico_namespace_sm_png->IsOk()) + { + ico_namespace_sm_png = new wxIcon(); + ico_namespace_sm_png->CopyFromBitmap(*namespace_sm_png_bmp); + } + return ico_namespace_sm_png; +} +#define namespace_sm_png_ico namespace_sm_png_ico() + +#endif // NAMESPACE_SM_PNG_H diff --git a/include/images/namespace.png b/include/images/namespace.png new file mode 100644 index 0000000000000000000000000000000000000000..4dacf1856fe53575aa1ee93bc146fd2a37b32650 GIT binary patch literal 376 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!S%6Q7E0Df1Wy)Sp&;Px>|GT>W zcXa%3Y55NX4GsTmYW|m(|1U27pPTzXGxL9H>i>j<|8a5uBO`y?dmIGnWGo5t3ubV5 zb|VeMN%D4gVHZp6cn#!m7I;J!18EO1b~~AE2V~@Ux;TbNT#ohc7HUx7XpYSMaq9p7 zn=I!qKe8xwzM-%wp&^sIt=Rgo#f8b@b_dIRY8v-$&wj8VV&(##$L}IS_tL57C59^J7gnB{q8L4G;;Lh>^1eErKX0`5@AbJqSl#`ZmagB%I2CBG zYKdz^NlIc#s#S7PDv)9@GB7mIH8j#SFbpv=ure{WGBMRQFtsu;nDIsOk()) + { + wxMemoryInputStream img_namespace_pngIS(namespace_png_data, sizeof(namespace_png_data)); + img_namespace_png->LoadFile(img_namespace_pngIS, wxBITMAP_TYPE_PNG); + } + return img_namespace_png; +} +#define namespace_png_img namespace_png_img() + +static wxBitmap *namespace_png_bmp() +{ + static wxBitmap *bmp_namespace_png; + if (!bmp_namespace_png || !bmp_namespace_png->IsOk()) + bmp_namespace_png = new wxBitmap(*namespace_png_img); + return bmp_namespace_png; +} +#define namespace_png_bmp namespace_png_bmp() + +static wxIcon *namespace_png_ico() +{ + static wxIcon *ico_namespace_png; + if (!ico_namespace_png || !ico_namespace_png->IsOk()) + { + ico_namespace_png = new wxIcon(); + ico_namespace_png->CopyFromBitmap(*namespace_png_bmp); + } + return ico_namespace_png; +} +#define namespace_png_ico namespace_png_ico() + +#endif // NAMESPACE_PNG_H diff --git a/include/images/namespaces.png b/include/images/namespaces.png new file mode 100644 index 0000000000000000000000000000000000000000..9733882b720b39bfed266843f84e1278c9bc588f GIT binary patch literal 374 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPHF4e$wZ1=2UBOxf${`MpGH zU{3;zvcy3SwTZqD+l$Y)vNKF*j=J$Hf58;3LkbJ^d(5uZnwoKWUzc38`RSUQj73r| zZ23m=S+P$%Q$DHn*Svh{6E-*f_92al^NVJ`+r2V#$Df7&rS+Sxi6&jF{agpMUbVzE zq9i4;B-JXpC>2OC7#SEE=o%X78W@Hc8CaPZTbY<@8<<)d7|eU8w+cl=ZhlH;S|vn- gfhAZ2P_>Dbff+=@sp+9>fEpM)UHx3vIVCg!0CBE_(*OVf literal 0 HcmV?d00001 diff --git a/include/images/namespaces.pngc b/include/images/namespaces.pngc new file mode 100644 index 0000000..5ffccc4 --- /dev/null +++ b/include/images/namespaces.pngc @@ -0,0 +1,91 @@ +#ifndef NAMESPACES_PNG_H +#define NAMESPACES_PNG_H + +static const unsigned char namespaces_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x2d, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xd8, 0x94, 0x94, 0xbd, +0x49, 0x49, 0xff, 0x8d, 0x8d, 0xff, 0x88, 0x88, +0xff, 0x83, 0x83, 0xff, 0xff, 0xff, 0xc8, 0x68, +0x68, 0xff, 0x7d, 0x7d, 0xd8, 0x5e, 0x5e, 0xff, +0x76, 0x76, 0xff, 0x6f, 0x6f, 0xff, 0x68, 0x68, +0xff, 0x60, 0x60, 0xff, 0x5c, 0x5c, 0x15, 0x89, +0x1c, 0x8d, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, 0x06, +0x61, 0x66, 0xb8, 0x7d, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x73, 0x49, 0x44, 0x41, +0x54, 0x08, 0xd7, 0x2d, 0x8e, 0x51, 0x15, 0x80, +0x30, 0x08, 0x45, 0xa1, 0xc1, 0xa4, 0xc1, 0xd0, +0xa1, 0x47, 0xa7, 0x1f, 0x46, 0x58, 0x84, 0x45, +0x20, 0x8a, 0x11, 0x8c, 0x60, 0x04, 0x23, 0x18, +0xc1, 0x08, 0x26, 0x91, 0x4d, 0xe1, 0x87, 0x73, +0xcf, 0x85, 0x07, 0x00, 0x90, 0x83, 0x5a, 0xd8, +0xfa, 0x6f, 0xa0, 0x94, 0x2a, 0xc2, 0x20, 0xa1, +0x2f, 0x8c, 0x36, 0xd5, 0x7d, 0x35, 0x36, 0x0a, +0x4b, 0xd7, 0x19, 0xa2, 0xb3, 0xe5, 0xac, 0xd9, +0x01, 0x72, 0x1a, 0x44, 0x06, 0x6f, 0x32, 0x1f, +0x6a, 0x5d, 0xe4, 0x49, 0x64, 0xf2, 0x26, 0x8f, +0x7c, 0xe9, 0xe5, 0x4c, 0x56, 0x9d, 0x67, 0xdb, +0xc2, 0x28, 0x91, 0x9f, 0x72, 0x9b, 0xee, 0xbb, +0xa9, 0x69, 0xb8, 0xfc, 0xa1, 0xff, 0x1b, 0x2f, +0x82, 0xd6, 0x15, 0x62, 0xd1, 0x7d, 0xf3, 0x7e, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, +0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *namespaces_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_namespaces_png = new wxImage(); + if (!img_namespaces_png || !img_namespaces_png->IsOk()) + { + wxMemoryInputStream img_namespaces_pngIS(namespaces_png_data, sizeof(namespaces_png_data)); + img_namespaces_png->LoadFile(img_namespaces_pngIS, wxBITMAP_TYPE_PNG); + } + return img_namespaces_png; +} +#define namespaces_png_img namespaces_png_img() + +static wxBitmap *namespaces_png_bmp() +{ + static wxBitmap *bmp_namespaces_png; + if (!bmp_namespaces_png || !bmp_namespaces_png->IsOk()) + bmp_namespaces_png = new wxBitmap(*namespaces_png_img); + return bmp_namespaces_png; +} +#define namespaces_png_bmp namespaces_png_bmp() + +static wxIcon *namespaces_png_ico() +{ + static wxIcon *ico_namespaces_png; + if (!ico_namespaces_png || !ico_namespaces_png->IsOk()) + { + ico_namespaces_png = new wxIcon(); + ico_namespaces_png->CopyFromBitmap(*namespaces_png_bmp); + } + return ico_namespaces_png; +} +#define namespaces_png_ico namespaces_png_ico() + +#endif // NAMESPACES_PNG_H diff --git a/include/images/operator.png b/include/images/operator.png new file mode 100644 index 0000000000000000000000000000000000000000..1c8273027cecccbc2187dad8d3f5a31b99608c96 GIT binary patch literal 315 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPHF3h)VW1=9KX`Kwl~dj9I`)0bZ# zzx?{}#h3ffzubNH<@VFhH=cgJ_T=-G$Dc1f`eZWC{TWa-V@Z%-FoVOh8)-leXMsm# zF_88EW4Dvpb|8kQi(?4K_2h&DY!a;tcoN+;oK*x)3HY|G5D?K8VOc3u=KDUTR$z(J znxt#gTe~DWM4f#zt@7 literal 0 HcmV?d00001 diff --git a/include/images/operator.pngc b/include/images/operator.pngc new file mode 100644 index 0000000..c8eba3a --- /dev/null +++ b/include/images/operator.pngc @@ -0,0 +1,84 @@ +#ifndef OPERATOR_PNG_H +#define OPERATOR_PNG_H + +static const unsigned char operator_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x2a, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x6f, 0x6f, 0x6f, 0xaa, +0xaa, 0xaa, 0xe7, 0xea, 0xf5, 0xe5, 0xe9, 0xf5, +0xe3, 0xe9, 0xf5, 0xe1, 0xe8, 0xf4, 0xdf, 0xe7, +0xf4, 0xdd, 0xe6, 0xf4, 0xdb, 0xe5, 0xf3, 0xd8, +0xe5, 0xf3, 0xd6, 0xe4, 0xf3, 0xd4, 0xe3, 0xf3, +0xd2, 0xe2, 0xf2, 0x34, 0x9e, 0x47, 0xe6, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x48, 0x49, 0x44, 0x41, +0x54, 0x08, 0xd7, 0x63, 0x60, 0xc0, 0x06, 0x18, +0x85, 0xa0, 0x0c, 0x61, 0x47, 0x28, 0x43, 0x24, +0x10, 0xca, 0x10, 0x4d, 0x84, 0xa8, 0x10, 0x14, +0x2b, 0x14, 0x04, 0xa9, 0x12, 0x76, 0x4d, 0xef, +0x5c, 0x7d, 0x10, 0xa4, 0x22, 0xac, 0x62, 0xd6, +0x9e, 0x8b, 0x40, 0x86, 0xa2, 0xa0, 0xe4, 0x42, +0x41, 0x01, 0xb0, 0x2a, 0xa9, 0x8d, 0x50, 0x5d, +0xd2, 0x07, 0xa1, 0x0c, 0x99, 0x8b, 0x30, 0x2b, +0x04, 0xb0, 0xda, 0x0c, 0x00, 0xfc, 0xee, 0x0b, +0x6e, 0xfb, 0x04, 0xfd, 0x81, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *operator_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_operator_png = new wxImage(); + if (!img_operator_png || !img_operator_png->IsOk()) + { + wxMemoryInputStream img_operator_pngIS(operator_png_data, sizeof(operator_png_data)); + img_operator_png->LoadFile(img_operator_pngIS, wxBITMAP_TYPE_PNG); + } + return img_operator_png; +} +#define operator_png_img operator_png_img() + +static wxBitmap *operator_png_bmp() +{ + static wxBitmap *bmp_operator_png; + if (!bmp_operator_png || !bmp_operator_png->IsOk()) + bmp_operator_png = new wxBitmap(*operator_png_img); + return bmp_operator_png; +} +#define operator_png_bmp operator_png_bmp() + +static wxIcon *operator_png_ico() +{ + static wxIcon *ico_operator_png; + if (!ico_operator_png || !ico_operator_png->IsOk()) + { + ico_operator_png = new wxIcon(); + ico_operator_png->CopyFromBitmap(*operator_png_bmp); + } + return ico_operator_png; +} +#define operator_png_ico operator_png_ico() + +#endif // OPERATOR_PNG_H diff --git a/include/images/operatorclass.png b/include/images/operatorclass.png new file mode 100644 index 0000000000000000000000000000000000000000..175fc51d932b622c4e6cf4f2011363dc62336337 GIT binary patch literal 588 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMffdHQnS0KH8`}WC`Cs$Th9y)ZW zqoaGx+RZ1=T)Fq~&D{rYj-S4=a?Pf;j;>9cHZ5GZ?CSLg&tH9g_Uh}?mtUW}{QBs{ z*M~2@oV|Q+&itj1p1fbMa9MtS{=9|D?mz!>@A;Q&_utN*zvN+A=>3AAJI}t{e){>u zrMoTdU3atmZa)2d9r@H_Z+))BgXAosM8fcyNm8tS08^qbNl6a z2eZqMKb^kya>o3nmmYoEarDxKho9!J*tq}Pou;;~Q@3AFox3FWg5o8h9~eu5{DK)A zp4~_TaySb-B8!2v2N=7Z%(eqE4tu&dhDcnt?SC%R}Kyidoi zoj9?8f41(8zSlqh#IaZ2V0*CRp`H-OTP1$SGq?Xu2so7Tr1{5;G?MniLsT5skVWsm4U&$cY3Q(H00)|WTsU@G#FTdH2_tcSQ(f>G@P0qx(29$ N!PC{xWt~$(6973AAHDzp literal 0 HcmV?d00001 diff --git a/include/images/operatorclass.pngc b/include/images/operatorclass.pngc new file mode 100644 index 0000000..4a92043 --- /dev/null +++ b/include/images/operatorclass.pngc @@ -0,0 +1,118 @@ +#ifndef OPERATORCLASS_PNG_H +#define OPERATORCLASS_PNG_H + +static const unsigned char operatorclass_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xc0, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xb7, 0xb7, 0xb7, 0x93, +0x93, 0x93, 0x79, 0x79, 0x79, 0xc2, 0xc2, 0xc2, +0x88, 0x88, 0x8b, 0xac, 0xad, 0xb3, 0xc9, 0xcc, +0xd4, 0xde, 0xe1, 0xec, 0xdd, 0xe0, 0xec, 0xc7, +0xcb, 0xd4, 0xa9, 0xac, 0xb2, 0x86, 0x88, 0x8a, +0xb2, 0xb2, 0xb2, 0xa1, 0xa1, 0xa6, 0xd5, 0xd7, +0xe0, 0xe7, 0xea, 0xf5, 0xe6, 0xea, 0xf5, 0xe5, +0xe9, 0xf5, 0xe4, 0xe9, 0xf5, 0xe2, 0xe8, 0xf5, +0xe1, 0xe8, 0xf4, 0xcd, 0xd3, 0xde, 0x9c, 0x9f, +0xa5, 0xe2, 0xe4, 0xef, 0xa0, 0xa1, 0xa6, 0x6f, +0x6f, 0x6f, 0x9e, 0xa1, 0xa6, 0xdf, 0xe7, 0xf4, +0xde, 0xe7, 0xf4, 0xd6, 0xdf, 0xed, 0x9b, 0x9f, +0xa4, 0xe1, 0x76, 0x55, 0xdf, 0x70, 0x52, 0xdc, +0xe6, 0xf4, 0xdb, 0xe5, 0xf3, 0xc8, 0xd2, 0xdd, +0x84, 0x87, 0x8a, 0xdd, 0x6a, 0x4e, 0xd9, 0xe5, +0xf3, 0xd8, 0xe4, 0xf3, 0xa3, 0xaa, 0xb1, 0xdb, +0x63, 0x4a, 0x9a, 0x9f, 0xa5, 0xd6, 0xe4, 0xf3, +0xbc, 0xc6, 0xd2, 0xd8, 0x5c, 0x46, 0xd6, 0x55, +0x42, 0xd4, 0x4e, 0x3e, 0xd1, 0x47, 0x3a, 0xd5, +0xe3, 0xf3, 0xcc, 0xdb, 0xe9, 0xcf, 0x40, 0x36, +0xd3, 0xe3, 0xf2, 0xcb, 0xda, 0xe9, 0x98, 0x9f, +0xa5, 0xd2, 0xe2, 0xf2, 0xb8, 0xc5, 0xd2, 0xd0, +0xe1, 0xf2, 0x9f, 0xa8, 0xb1, 0xbf, 0xce, 0xdc, +0x82, 0x86, 0x8a, 0xca, 0xdb, 0xeb, 0x95, 0x9d, +0xa4, 0x6d, 0xd0, 0x21, 0xd2, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0xc3, 0x49, 0x44, 0x41, 0x54, 0x18, +0xd3, 0x3d, 0x8f, 0xe7, 0x12, 0x82, 0x40, 0x0c, +0x84, 0x8f, 0x3b, 0x50, 0xa4, 0xd8, 0x05, 0x8d, +0x60, 0xa1, 0x0a, 0x8a, 0xa0, 0x58, 0x00, 0x0b, +0xef, 0xff, 0x56, 0x5e, 0x40, 0xcd, 0x8f, 0x4c, +0x76, 0xf2, 0x4d, 0xb2, 0x4b, 0x08, 0x96, 0x40, +0x19, 0xa3, 0x02, 0xf9, 0x95, 0x28, 0x75, 0xba, +0x72, 0x4f, 0x51, 0x35, 0xb1, 0xd5, 0x7a, 0x7f, +0x30, 0x1c, 0x8d, 0x27, 0xd3, 0x99, 0x61, 0xea, +0xcd, 0xbe, 0x3f, 0x1f, 0x8e, 0x16, 0x00, 0x4b, +0xcb, 0x5e, 0xad, 0x91, 0x91, 0x70, 0x0f, 0x9b, +0x2d, 0xd8, 0x8e, 0xeb, 0xf9, 0xfc, 0x5e, 0x07, +0x79, 0xd8, 0x06, 0xe0, 0xb8, 0xe1, 0x2e, 0x12, +0x08, 0xed, 0x22, 0x0f, 0x41, 0xcc, 0xdb, 0xfe, +0x90, 0x50, 0xc2, 0x64, 0xe4, 0x83, 0xf8, 0x98, +0x66, 0x27, 0x38, 0xe7, 0x8c, 0xb0, 0x1e, 0xf2, +0x8d, 0xbe, 0xc0, 0xf5, 0xc6, 0x08, 0x55, 0xa6, +0x4b, 0x4e, 0xa7, 0x19, 0x6f, 0xf7, 0xa2, 0xa4, +0x44, 0x50, 0x67, 0x96, 0xed, 0x00, 0xf2, 0xd7, +0xa2, 0x7a, 0x70, 0xbb, 0x9a, 0xc1, 0xff, 0x01, +0xf2, 0x45, 0xf5, 0x7c, 0xa1, 0x31, 0x73, 0xe5, +0x86, 0x7b, 0xe4, 0xab, 0x77, 0xdd, 0x9a, 0x5f, +0x7b, 0xbb, 0x03, 0xf2, 0xcf, 0x5a, 0xff, 0xa6, +0xf3, 0xa3, 0x24, 0xbf, 0x95, 0x8f, 0x97, 0xf8, +0xcf, 0xdb, 0xc4, 0x6f, 0xc7, 0x0f, 0x91, 0xe7, +0x17, 0x02, 0x64, 0xce, 0x51, 0xf5, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *operatorclass_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_operatorclass_png = new wxImage(); + if (!img_operatorclass_png || !img_operatorclass_png->IsOk()) + { + wxMemoryInputStream img_operatorclass_pngIS(operatorclass_png_data, sizeof(operatorclass_png_data)); + img_operatorclass_png->LoadFile(img_operatorclass_pngIS, wxBITMAP_TYPE_PNG); + } + return img_operatorclass_png; +} +#define operatorclass_png_img operatorclass_png_img() + +static wxBitmap *operatorclass_png_bmp() +{ + static wxBitmap *bmp_operatorclass_png; + if (!bmp_operatorclass_png || !bmp_operatorclass_png->IsOk()) + bmp_operatorclass_png = new wxBitmap(*operatorclass_png_img); + return bmp_operatorclass_png; +} +#define operatorclass_png_bmp operatorclass_png_bmp() + +static wxIcon *operatorclass_png_ico() +{ + static wxIcon *ico_operatorclass_png; + if (!ico_operatorclass_png || !ico_operatorclass_png->IsOk()) + { + ico_operatorclass_png = new wxIcon(); + ico_operatorclass_png->CopyFromBitmap(*operatorclass_png_bmp); + } + return ico_operatorclass_png; +} +#define operatorclass_png_ico operatorclass_png_ico() + +#endif // OPERATORCLASS_PNG_H diff --git a/include/images/operatorclasses.png b/include/images/operatorclasses.png new file mode 100644 index 0000000000000000000000000000000000000000..db292e3f6ed55ce65019eec06c2839b36cde90db GIT binary patch literal 473 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}V}MVHE0Er`Ygd1Ne{pefeSO2K z)f>*9zyA37$5ZF7FI%~xwyt5{{$np*eVsLDetv#_RaJFSQE`1kQ(1Y%sk2uXELt{i z;j;VBziiuc^x3Pg4@yJsKKpX}>E}hu*Wb?PC3sv5b-LtbeeuD&ne&(K zK5_NR<4+eKeVV&$U3G2!+MP$HcxAr_I)bqz$S;_|;n|HeAcwQSBeEDsdw{Xq$!t3y zqus-w{^y}~|C9V-ADTyViR>?)FK#IZ0z|cU~&`8(7FvQ5f%EZ{p#8lhB)XKnM-aEZj qC>nC}Q!>*kAsP%U!5V<7O{@&eAR10h4_yP)z~JfX=d#Wzp$Pz_amfMz literal 0 HcmV?d00001 diff --git a/include/images/operatorclasses.pngc b/include/images/operatorclasses.pngc new file mode 100644 index 0000000..55459b1 --- /dev/null +++ b/include/images/operatorclasses.pngc @@ -0,0 +1,104 @@ +#ifndef OPERATORCLASSES_PNG_H +#define OPERATORCLASSES_PNG_H + +static const unsigned char operatorclasses_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x81, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xba, 0xba, 0xba, 0x8f, +0x8f, 0x8f, 0x73, 0x73, 0x73, 0x7f, 0x7f, 0x80, +0xaa, 0xab, 0xb0, 0xcd, 0xcf, 0xd7, 0xe3, 0xe7, +0xf1, 0xca, 0xce, 0xd7, 0xa6, 0xa9, 0xb0, 0x7d, +0x7e, 0x80, 0xbe, 0xbf, 0xc6, 0xe8, 0xea, 0xf5, +0x9a, 0x9c, 0x9f, 0x6f, 0x6f, 0x6f, 0x7a, 0x7a, +0x7b, 0x72, 0x72, 0x73, 0x7f, 0x80, 0x82, 0x76, +0x77, 0x78, 0xca, 0xcd, 0xd5, 0xa0, 0xa2, 0xa6, +0x9e, 0xa1, 0xa6, 0xdf, 0xe7, 0xf4, 0xb6, 0xbc, +0xc5, 0xe6, 0xea, 0xf5, 0xe0, 0x75, 0x54, 0xdd, +0xe6, 0xf4, 0xdb, 0xe5, 0xf3, 0xa2, 0xa7, 0xaf, +0xdd, 0x6b, 0x4f, 0x9a, 0x9f, 0xa5, 0xbf, 0xca, +0xd5, 0xda, 0x60, 0x48, 0xd6, 0x55, 0x42, 0xd2, +0x4a, 0x3b, 0xd1, 0xe0, 0xee, 0x99, 0x9f, 0xa5, +0xbb, 0xc8, 0xd5, 0xd4, 0xe3, 0xf2, 0xd1, 0xe2, +0xf2, 0x9d, 0xa6, 0xae, 0x7b, 0x7d, 0x7f, 0xad, +0xb9, 0xc4, 0x94, 0x4a, 0x6b, 0xef, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x8f, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x5d, 0x8f, 0xd9, 0x16, 0x82, 0x30, +0x0c, 0x44, 0xdb, 0x20, 0xab, 0x30, 0x40, 0x65, +0x91, 0x5d, 0x36, 0x01, 0xff, 0xff, 0x03, 0xa5, +0xb8, 0xd4, 0x3a, 0x6f, 0x93, 0x73, 0x93, 0xc9, +0x30, 0xc6, 0x18, 0x27, 0x83, 0x38, 0x53, 0x3a, +0x99, 0x96, 0xed, 0xb8, 0x9e, 0xf2, 0x67, 0x3f, +0x40, 0x18, 0xc5, 0xe2, 0xed, 0xb9, 0xe9, 0x5f, +0x34, 0x86, 0xac, 0x40, 0x67, 0x0c, 0x1b, 0x3a, +0x43, 0x4e, 0x78, 0x30, 0x09, 0xd2, 0x2c, 0x97, +0x13, 0xee, 0x46, 0x92, 0xb9, 0xa2, 0x40, 0x59, +0xd5, 0x32, 0xdd, 0x8b, 0x77, 0x26, 0x01, 0x1a, +0xa0, 0xed, 0x48, 0x2e, 0x09, 0xc9, 0x14, 0xcd, +0xad, 0x1f, 0x30, 0x1a, 0xc7, 0xdd, 0x9d, 0x49, +0x81, 0x1e, 0x98, 0x66, 0x7a, 0x45, 0x0b, 0x37, +0x2b, 0x31, 0xe0, 0xbe, 0xac, 0x9f, 0x06, 0x5b, +0x5e, 0xb5, 0x98, 0x96, 0xc7, 0xf6, 0xfd, 0xdf, +0xab, 0xbb, 0x71, 0x5e, 0xb7, 0x9f, 0x86, 0xff, +0x8d, 0x95, 0x9e, 0x77, 0xa9, 0x09, 0x6b, 0xf3, +0xa2, 0xf7, 0x16, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *operatorclasses_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_operatorclasses_png = new wxImage(); + if (!img_operatorclasses_png || !img_operatorclasses_png->IsOk()) + { + wxMemoryInputStream img_operatorclasses_pngIS(operatorclasses_png_data, sizeof(operatorclasses_png_data)); + img_operatorclasses_png->LoadFile(img_operatorclasses_pngIS, wxBITMAP_TYPE_PNG); + } + return img_operatorclasses_png; +} +#define operatorclasses_png_img operatorclasses_png_img() + +static wxBitmap *operatorclasses_png_bmp() +{ + static wxBitmap *bmp_operatorclasses_png; + if (!bmp_operatorclasses_png || !bmp_operatorclasses_png->IsOk()) + bmp_operatorclasses_png = new wxBitmap(*operatorclasses_png_img); + return bmp_operatorclasses_png; +} +#define operatorclasses_png_bmp operatorclasses_png_bmp() + +static wxIcon *operatorclasses_png_ico() +{ + static wxIcon *ico_operatorclasses_png; + if (!ico_operatorclasses_png || !ico_operatorclasses_png->IsOk()) + { + ico_operatorclasses_png = new wxIcon(); + ico_operatorclasses_png->CopyFromBitmap(*operatorclasses_png_bmp); + } + return ico_operatorclasses_png; +} +#define operatorclasses_png_ico operatorclasses_png_ico() + +#endif // OPERATORCLASSES_PNG_H diff --git a/include/images/operatorfamilies.png b/include/images/operatorfamilies.png new file mode 100644 index 0000000000000000000000000000000000000000..cad9e59fba52083c2ed91687421790846d7ecdb1 GIT binary patch literal 429 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}RDe&2E0A8bYE^!I{{R2~|Ni^` z`|rP>zyE&w`S;WJKkvW(e)IX)i;q87u3WWz#mXhiRz7+EBkt*~2XDVe+`lq!@$$Q` zz6IVm>v`d*)5(1|UwoataM`tIUoJoSeBtruvkyOYtvP-YXgXs_kY6x^!?PP{AWo9E zy9=`*kIyF{hqJ&VvKUBvfU(=jY&#&M*3-o?MB;L4f3#4OfdI=wRZbNr0Rhnu|E`yq zJ4`+H^Ucd!?tw+ibb@w-9NV?)V5u`^R#- z6=zuY&#&0C4d@Wn64!{5l*E!$tK_0oAjM#0U}&IgXryak7-D2#Wnye)VybOmYGq(B u@15Q%6b-rgDVb@N5Df;FU=2XkCRPS!5DllMhpqu?VDNPHb6Mw<&;$VRueS^U literal 0 HcmV?d00001 diff --git a/include/images/operatorfamilies.pngc b/include/images/operatorfamilies.pngc new file mode 100644 index 0000000..3072715 --- /dev/null +++ b/include/images/operatorfamilies.pngc @@ -0,0 +1,98 @@ +#ifndef OPERATORFAMILIES_PNG_H +#define OPERATORFAMILIES_PNG_H + +static const unsigned char operatorfamilies_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x5a, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x6f, +0x6f, 0x6f, 0xff, 0xff, 0xff, 0xfd, 0xfe, 0xff, +0xfb, 0xfd, 0xfe, 0xf9, 0xfb, 0xfd, 0xf6, 0xf9, +0xfd, 0xf2, 0xf7, 0xfc, 0xef, 0xf5, 0xfb, 0xec, +0xf3, 0xfa, 0xe8, 0xf1, 0xf9, 0xa9, 0xa9, 0xaa, +0xa7, 0xa8, 0xa9, 0xa4, 0xa6, 0xa9, 0xe4, 0xef, +0xf8, 0x5e, 0xe5, 0xda, 0xe0, 0xed, 0xf7, 0x58, +0xdf, 0xd4, 0x9e, 0xa3, 0xa7, 0xdd, 0xea, 0xf6, +0x51, 0xd8, 0xcd, 0x49, 0xd0, 0xc5, 0x42, 0xc9, +0xbe, 0xd9, 0xe8, 0xf5, 0x9b, 0xa1, 0xa6, 0xd6, +0xe6, 0xf4, 0xd3, 0xe4, 0xf3, 0xd0, 0xe3, 0xf3, +0xcd, 0xe1, 0xf2, 0x8a, 0xac, 0xc7, 0xc9, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, +0x62, 0x4b, 0x47, 0x44, 0x03, 0x11, 0x0c, 0x4c, +0xf2, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x7d, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x65, 0x8f, 0x5b, 0x12, 0x82, 0x30, 0x10, 0x04, +0xa1, 0x25, 0x09, 0x24, 0x42, 0x10, 0x10, 0x15, +0xf0, 0xfe, 0xd7, 0x74, 0x37, 0x40, 0x95, 0xc6, +0xf9, 0xec, 0xe9, 0xda, 0x47, 0x51, 0x72, 0xa6, +0x2c, 0x52, 0xb8, 0x54, 0xc6, 0xba, 0xba, 0xf1, +0x81, 0x03, 0x54, 0xd7, 0x5f, 0x07, 0x93, 0x39, +0xd8, 0xcc, 0xc1, 0x65, 0x0e, 0xb5, 0x3a, 0xc6, +0xb6, 0x74, 0x3e, 0x44, 0x05, 0x8d, 0x3a, 0xd6, +0xd1, 0x13, 0xe2, 0x4d, 0x81, 0x57, 0xa7, 0x85, +0x01, 0xc6, 0x49, 0x41, 0x48, 0x4e, 0x3f, 0xdc, +0xe7, 0x07, 0x4f, 0x01, 0x72, 0xa9, 0x38, 0x1d, +0xcc, 0xf0, 0x5a, 0xf6, 0xc5, 0xe2, 0xc8, 0x7c, +0xe9, 0x97, 0x35, 0x01, 0x75, 0x42, 0x1c, 0xa5, +0x5f, 0xb7, 0xf3, 0x7c, 0x99, 0x3f, 0x49, 0xbf, +0xbd, 0x0f, 0xf0, 0xf7, 0xf1, 0x77, 0x3e, 0xa8, +0xcc, 0x05, 0xbf, 0x9f, 0x78, 0xbc, 0xb6, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *operatorfamilies_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_operatorfamilies_png = new wxImage(); + if (!img_operatorfamilies_png || !img_operatorfamilies_png->IsOk()) + { + wxMemoryInputStream img_operatorfamilies_pngIS(operatorfamilies_png_data, sizeof(operatorfamilies_png_data)); + img_operatorfamilies_png->LoadFile(img_operatorfamilies_pngIS, wxBITMAP_TYPE_PNG); + } + return img_operatorfamilies_png; +} +#define operatorfamilies_png_img operatorfamilies_png_img() + +static wxBitmap *operatorfamilies_png_bmp() +{ + static wxBitmap *bmp_operatorfamilies_png; + if (!bmp_operatorfamilies_png || !bmp_operatorfamilies_png->IsOk()) + bmp_operatorfamilies_png = new wxBitmap(*operatorfamilies_png_img); + return bmp_operatorfamilies_png; +} +#define operatorfamilies_png_bmp operatorfamilies_png_bmp() + +static wxIcon *operatorfamilies_png_ico() +{ + static wxIcon *ico_operatorfamilies_png; + if (!ico_operatorfamilies_png || !ico_operatorfamilies_png->IsOk()) + { + ico_operatorfamilies_png = new wxIcon(); + ico_operatorfamilies_png->CopyFromBitmap(*operatorfamilies_png_bmp); + } + return ico_operatorfamilies_png; +} +#define operatorfamilies_png_ico operatorfamilies_png_ico() + +#endif // OPERATORFAMILIES_PNG_H diff --git a/include/images/operatorfamily.png b/include/images/operatorfamily.png new file mode 100644 index 0000000000000000000000000000000000000000..461dcee4c2229f1cc097b2cafbca3cf1cf4cc4ff GIT binary patch literal 463 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}X@F0NE0A8bYE^!I{{R2~|NZ;_ z=kLE?fByaa{rB6izh8d*`SktI`>(&>eEIe2)6eH0e=c9Ka>=rlPu~BCe|9_i(e;OK zzlYzueE-e&;9KYCE?R!))i=MZr#vqlbv<*?;rO1LFTUCw-f{i;mstyzU3vQD(v!~@ z9)CXf@Y9(GpHzCwqktAOmIV0)GdMiEkp|)=^bhxNtk?-DGZ z4!zm7`SVAnTg&Z#C@iS`W#_{9?)n#J8P*;5FZ4ea_n!azG)w#o&ZXJUCtLu!N43N? zq9i4;B-JXpC>2OC7#SEE=o%X78W@Hc8CaPZTbY<@8<<)d7|eU8w+cl=ZhlH;S|vn- gfhAZ2P_>Dbff+=@sp+9>fEpM)UHx3vIVCg!09NVK#{d8T literal 0 HcmV?d00001 diff --git a/include/images/operatorfamily.pngc b/include/images/operatorfamily.pngc new file mode 100644 index 0000000..e06b453 --- /dev/null +++ b/include/images/operatorfamily.pngc @@ -0,0 +1,102 @@ +#ifndef OPERATORFAMILY_PNG_H +#define OPERATORFAMILY_PNG_H + +static const unsigned char operatorfamily_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x75, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x6f, +0x6f, 0x6f, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xff, +0xfc, 0xfd, 0xfe, 0xfa, 0xfc, 0xfe, 0xf9, 0xfb, +0xfd, 0xf6, 0xfa, 0xfd, 0xf4, 0xf8, 0xfc, 0xf2, +0xf7, 0xfc, 0xef, 0xf5, 0xfb, 0xec, 0xf4, 0xfa, +0xea, 0xf2, 0xf9, 0xe7, 0xf1, 0xf9, 0xa7, 0xa8, +0xa9, 0xa4, 0xa6, 0xa9, 0xe4, 0xef, 0xf8, 0x5f, +0xe6, 0xdb, 0x5b, 0xe2, 0xd7, 0xe1, 0xed, 0xf7, +0x57, 0xde, 0xd3, 0xdf, 0xec, 0xf7, 0x53, 0xda, +0xcf, 0x9d, 0xa2, 0xa7, 0xdc, 0xea, 0xf6, 0x4e, +0xd5, 0xca, 0x49, 0xd0, 0xc5, 0x45, 0xcc, 0xc1, +0x40, 0xc7, 0xbc, 0xd9, 0xe8, 0xf5, 0x3c, 0xc3, +0xb8, 0xd7, 0xe7, 0xf4, 0x9a, 0xa0, 0xa6, 0xd4, +0xe5, 0xf4, 0xd2, 0xe4, 0xf3, 0xd0, 0xe3, 0xf3, +0xce, 0xe1, 0xf2, 0xcc, 0xe0, 0xf2, 0x24, 0x8d, +0x77, 0x5a, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, 0x03, +0x11, 0x0c, 0x4c, 0xf2, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x84, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x6d, 0x8f, 0xd9, 0x0e, 0x82, +0x30, 0x14, 0x44, 0x61, 0x70, 0xc5, 0x0d, 0xc5, +0x0a, 0x08, 0x0a, 0xb6, 0xc5, 0xff, 0xff, 0x44, +0xee, 0xcc, 0x93, 0x11, 0xe6, 0xe1, 0x26, 0x73, +0x7a, 0x92, 0x49, 0x93, 0x64, 0x96, 0x14, 0x3f, +0x49, 0x0d, 0x20, 0x5b, 0xad, 0x37, 0xdb, 0xdd, +0x3e, 0x3f, 0x1c, 0x4f, 0x67, 0x10, 0xb0, 0x5f, +0x80, 0xc2, 0xfa, 0x55, 0x80, 0xef, 0xb8, 0x95, +0xb0, 0x7e, 0x17, 0xa0, 0x8f, 0xd2, 0xc1, 0xfa, +0x43, 0x80, 0x3e, 0x5c, 0x65, 0xa7, 0x6e, 0x04, +0xe8, 0xbb, 0xea, 0xd9, 0x76, 0x2f, 0xbc, 0x05, +0xe8, 0xab, 0xf7, 0x18, 0x04, 0xf2, 0xc2, 0xec, +0xb6, 0xb3, 0xf3, 0xf1, 0x02, 0xda, 0xa7, 0x3f, +0xf8, 0x20, 0xa0, 0x7d, 0xfa, 0x3e, 0x44, 0x01, +0xee, 0xd7, 0xf4, 0x43, 0x1c, 0x05, 0xb8, 0xdf, +0xd0, 0x8f, 0xe3, 0x17, 0x4b, 0x9f, 0xfb, 0xcb, +0x04, 0x5f, 0xe8, 0x09, 0xa5, 0x6b, 0xe7, 0x90, +0xd0, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, +0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *operatorfamily_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_operatorfamily_png = new wxImage(); + if (!img_operatorfamily_png || !img_operatorfamily_png->IsOk()) + { + wxMemoryInputStream img_operatorfamily_pngIS(operatorfamily_png_data, sizeof(operatorfamily_png_data)); + img_operatorfamily_png->LoadFile(img_operatorfamily_pngIS, wxBITMAP_TYPE_PNG); + } + return img_operatorfamily_png; +} +#define operatorfamily_png_img operatorfamily_png_img() + +static wxBitmap *operatorfamily_png_bmp() +{ + static wxBitmap *bmp_operatorfamily_png; + if (!bmp_operatorfamily_png || !bmp_operatorfamily_png->IsOk()) + bmp_operatorfamily_png = new wxBitmap(*operatorfamily_png_img); + return bmp_operatorfamily_png; +} +#define operatorfamily_png_bmp operatorfamily_png_bmp() + +static wxIcon *operatorfamily_png_ico() +{ + static wxIcon *ico_operatorfamily_png; + if (!ico_operatorfamily_png || !ico_operatorfamily_png->IsOk()) + { + ico_operatorfamily_png = new wxIcon(); + ico_operatorfamily_png->CopyFromBitmap(*operatorfamily_png_bmp); + } + return ico_operatorfamily_png; +} +#define operatorfamily_png_ico operatorfamily_png_ico() + +#endif // OPERATORFAMILY_PNG_H diff --git a/include/images/operators.png b/include/images/operators.png new file mode 100644 index 0000000000000000000000000000000000000000..1ce795f1ddc550337cb4e6f98fb2bacc9c2a2bed GIT binary patch literal 321 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFv5AX?b1=9KX`OjZ{efsk2{DsR_ zty=Z?#n%VVzubNH<@VFhH=caH`uOwZN1uv!+YZPG^mK6y;kcfh;K1O|m#i#XoubIE%YfQGA< zxJHzuB$lLFB^RXvDF!10LjzqyBV7Z-5F-OC6JskAQ*8rND+7ah@AOuoXvob^$xN$+ hXfUt@YXGV?u`)1&XgD=JbPZ4ggQu&X%Q~loCIGQ&YVrU8 literal 0 HcmV?d00001 diff --git a/include/images/operators.pngc b/include/images/operators.pngc new file mode 100644 index 0000000..a557578 --- /dev/null +++ b/include/images/operators.pngc @@ -0,0 +1,85 @@ +#ifndef OPERATORS_PNG_H +#define OPERATORS_PNG_H + +static const unsigned char operators_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x27, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x6f, 0x6f, 0x6f, 0xe7, +0xea, 0xf5, 0xe5, 0xe9, 0xf5, 0x9f, 0xa1, 0xa6, +0xaa, 0xaa, 0xaa, 0xe3, 0xe8, 0xf5, 0xe0, 0xe7, +0xf4, 0xdd, 0xe6, 0xf4, 0xdb, 0xe5, 0xf3, 0xd8, +0xe4, 0xf3, 0xd5, 0xe3, 0xf3, 0xd3, 0xe2, 0xf2, +0x73, 0xba, 0x6f, 0xb2, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x51, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, +0x63, 0x60, 0x40, 0x00, 0x46, 0x01, 0x28, 0x43, +0xc8, 0x10, 0xca, 0x10, 0x76, 0x14, 0x05, 0x51, +0xac, 0x82, 0x62, 0x42, 0x86, 0x01, 0x20, 0x15, +0xca, 0xe9, 0x10, 0x21, 0x46, 0x13, 0x98, 0x90, +0x20, 0x50, 0x28, 0x51, 0x00, 0x2a, 0x54, 0x28, +0x08, 0x15, 0xea, 0x5c, 0x0d, 0x12, 0x0a, 0x34, +0xab, 0x98, 0xb5, 0x47, 0x00, 0x6c, 0x80, 0xe4, +0x42, 0xb0, 0x14, 0x43, 0xa0, 0xd4, 0x46, 0xa8, +0xd9, 0xd2, 0x07, 0xa1, 0x8c, 0x40, 0x01, 0x24, +0x37, 0x00, 0x00, 0x38, 0x5e, 0x0d, 0x7b, 0xce, +0x63, 0xbc, 0x20, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *operators_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_operators_png = new wxImage(); + if (!img_operators_png || !img_operators_png->IsOk()) + { + wxMemoryInputStream img_operators_pngIS(operators_png_data, sizeof(operators_png_data)); + img_operators_png->LoadFile(img_operators_pngIS, wxBITMAP_TYPE_PNG); + } + return img_operators_png; +} +#define operators_png_img operators_png_img() + +static wxBitmap *operators_png_bmp() +{ + static wxBitmap *bmp_operators_png; + if (!bmp_operators_png || !bmp_operators_png->IsOk()) + bmp_operators_png = new wxBitmap(*operators_png_img); + return bmp_operators_png; +} +#define operators_png_bmp operators_png_bmp() + +static wxIcon *operators_png_ico() +{ + static wxIcon *ico_operators_png; + if (!ico_operators_png || !ico_operators_png->IsOk()) + { + ico_operators_png = new wxIcon(); + ico_operators_png->CopyFromBitmap(*operators_png_bmp); + } + return ico_operators_png; +} +#define operators_png_ico operators_png_ico() + +#endif // OPERATORS_PNG_H diff --git a/include/images/package.png b/include/images/package.png new file mode 100644 index 0000000000000000000000000000000000000000..3231977622d23a08664557074ac98662e915f203 GIT binary patch literal 673 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl480`XlLR^8|Ydb1;woCu}wg2zW zoqv98`u%P7udj=LexCK?G`2N2A+q>E$dt<-6%KrOv`>A8SzrU^c^<}}&&oh2}?En70?c3X$ zuWyPE?+*R+BJt1n^(T+E{rWQh=cnmEKK6Zo-}?1+(dSp0hj#gXd=~!u+wv2K>wkWl z_Tyvk_xCN|-d2BkUHJKB#-|tY2Y0xBc;fr(%e>=<%71+5`ToB7+uN!yuM0lEO#k#e z?&Gu21KVuhKXUo`Y09w!`QP6)eSKT`<#qn&mua7#$9{Yk^5Kck{;g*39@_l)&~$TqWAel z@~7ufAD;$&ck4uR&Vbct4=$A2^fNmB|(0{3=Yq3qyagc1s;*bK-vS0-A-oP z0U5JAT^vIsE+;1(V3L@r&>*OG;K-Rnr;eRFc#>uM^GDAfK7B0SuqshVL`Y0fRCxM? zDU;Y%Cr+9;b#iz>NKjZ{Xfwx(?2N3;*BY;1y_9xf;py%1^*MV+S7+@SMJBUtW#9Pv z{LbmE%M)NM=l9pomyfsq-{8>U5Kz!jo)J;uk`iJfd_~r9W8p{6PS1kvMykt~EL)nM zV)XC}cO3&mHm6vlcg@dtKv$}kxJHzuB$lLFB^RXvDF!10LjzqyBV7Z-5F-OC6JskA zQ*8rND+7ah@AOuoXvob^$xN$+XfUt@YXGV?u`)1&XgD=JbPZ4ggQu&X%Q~loCIBBN BT?POE literal 0 HcmV?d00001 diff --git a/include/images/package.pngc b/include/images/package.pngc new file mode 100644 index 0000000..9943fc6 --- /dev/null +++ b/include/images/package.pngc @@ -0,0 +1,129 @@ +#ifndef PACKAGE_PNG_H +#define PACKAGE_PNG_H + +static const unsigned char package_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x3e, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xd6, 0xb8, 0x79, 0xb9, +0x87, 0x1b, 0xfe, 0xfa, 0xbf, 0xfd, 0xf9, 0xb9, +0xfc, 0xf8, 0xb2, 0xfb, 0xf6, 0xab, 0xfa, 0xf5, +0xa3, 0xf9, 0xf3, 0x9a, 0xf8, 0xf1, 0x92, 0xca, +0xc7, 0x93, 0xca, 0xc6, 0x8e, 0xc9, 0xc5, 0x88, +0xc8, 0xc4, 0x82, 0xc7, 0xc2, 0x7a, 0xc6, 0xc1, +0x74, 0xc6, 0xbf, 0x6d, 0xfe, 0xfa, 0xbd, 0xca, +0xc7, 0x92, 0xfc, 0xf7, 0xb1, 0xfb, 0xf6, 0xa9, +0xfa, 0xf4, 0xa1, 0xf9, 0xf3, 0x99, 0xf8, 0xf1, +0x90, 0xf7, 0xef, 0x87, 0xf6, 0xee, 0x7d, 0xc4, +0xbd, 0x5d, 0xf4, 0xea, 0x6b, 0xfd, 0xf9, 0xb7, +0xca, 0xc6, 0x8d, 0xfb, 0xf6, 0xa8, 0xfa, 0xf4, +0xa0, 0xf9, 0xf3, 0x98, 0xf8, 0xf1, 0x8f, 0xf7, +0xef, 0x86, 0xf6, 0xed, 0x7c, 0xf5, 0xec, 0x73, +0xc3, 0xbb, 0x55, 0xf2, 0xe8, 0x61, 0xfc, 0xf7, +0xaf, 0xc9, 0xc5, 0x86, 0xfa, 0xf4, 0x9f, 0xf9, +0xf2, 0x97, 0xf8, 0xf1, 0x8e, 0xf7, 0xef, 0x85, +0xf5, 0xeb, 0x72, 0xf3, 0xea, 0x69, 0xc2, 0xba, +0x4d, 0xf1, 0xe6, 0x57, 0xfb, 0xf6, 0xa7, 0xc8, +0xc3, 0x7f, 0xf9, 0xf2, 0x96, 0xf8, 0xf1, 0x8d, +0xf7, 0xef, 0x84, 0xf6, 0xed, 0x7b, 0xf4, 0xeb, +0x71, 0xf3, 0xe9, 0x68, 0xf2, 0xe8, 0x5f, 0xc1, +0xb8, 0x45, 0xf0, 0xe4, 0x4d, 0xfa, 0xf4, 0x9e, +0xc7, 0xc2, 0x77, 0xf8, 0xf0, 0x8c, 0xf7, 0xef, +0x83, 0xf6, 0xed, 0x7a, 0xf4, 0xeb, 0x70, 0xf3, +0xe9, 0x67, 0xf2, 0xe7, 0x5e, 0xf1, 0xe6, 0x55, +0xc0, 0xb6, 0x3d, 0xef, 0xe2, 0x44, 0xf9, 0xf2, +0x94, 0xc6, 0xc0, 0x6f, 0xf7, 0xee, 0x82, 0xf5, +0xed, 0x79, 0xf4, 0xeb, 0x6f, 0xf3, 0xe9, 0x66, +0xf2, 0xe7, 0x5d, 0xf1, 0xe6, 0x54, 0xf0, 0xe4, +0x4c, 0xbf, 0xb5, 0x36, 0xee, 0xe1, 0x3c, 0xf8, +0xf0, 0x8a, 0xc5, 0xbe, 0x67, 0xf5, 0xec, 0x78, +0xf3, 0xe9, 0x65, 0xf2, 0xe7, 0x5c, 0xf1, 0xe5, +0x53, 0xf0, 0xe4, 0x4b, 0xef, 0xe2, 0x43, 0xbe, +0xb4, 0x2f, 0xed, 0xdf, 0x34, 0xc3, 0xbb, 0x58, +0xc2, 0xba, 0x50, 0xc2, 0xb9, 0x49, 0xc1, 0xb7, +0x42, 0xc0, 0xb6, 0x3b, 0xbf, 0xb5, 0x35, 0xbe, +0xb4, 0x2e, 0xf3, 0xe8, 0x63, 0xf2, 0xe7, 0x5a, +0xf1, 0xe5, 0x52, 0xf0, 0xe3, 0x49, 0xef, 0xe2, +0x41, 0xee, 0xe0, 0x3a, 0xed, 0xdf, 0x33, 0x25, +0x96, 0xcf, 0xd2, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x9a, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, +0x60, 0xc0, 0x02, 0x18, 0x99, 0x20, 0x80, 0x11, +0x26, 0xc0, 0xc4, 0xcc, 0xc2, 0xca, 0xc6, 0xce, +0xc1, 0xc9, 0x04, 0x97, 0xe7, 0xe2, 0xe6, 0xe1, +0xe5, 0xe3, 0x17, 0x80, 0xaa, 0x61, 0x12, 0x14, +0x12, 0x16, 0x11, 0x15, 0x13, 0x97, 0x90, 0x94, +0x92, 0x06, 0xab, 0x61, 0x92, 0x91, 0x95, 0x93, +0x57, 0x50, 0x54, 0x52, 0x56, 0x51, 0x55, 0x83, +0x08, 0xa8, 0x6b, 0x68, 0x6a, 0x69, 0xeb, 0x28, +0xeb, 0xea, 0xe9, 0x1b, 0x40, 0x04, 0x0c, 0x8d, +0x8c, 0x4d, 0x4c, 0xcd, 0xcc, 0x2d, 0x2c, 0xad, +0xac, 0x21, 0x02, 0x36, 0xb6, 0x76, 0xf6, 0x0e, +0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0x10, 0x01, +0x77, 0x0f, 0x4f, 0x2f, 0x6f, 0x1f, 0x5f, 0x3f, +0xff, 0x80, 0x40, 0x88, 0x40, 0x50, 0x70, 0x88, +0x77, 0x68, 0x58, 0x78, 0x44, 0x64, 0x54, 0x34, +0x13, 0xd4, 0x1d, 0x31, 0xb1, 0x71, 0xf1, 0x09, +0x89, 0x49, 0x70, 0xb7, 0x32, 0x25, 0xa7, 0xa4, +0xa6, 0xa5, 0x67, 0x64, 0x32, 0xe1, 0xf4, 0x0b, +0x7e, 0x00, 0x00, 0x6b, 0x09, 0x16, 0x81, 0x4b, +0x7c, 0xf9, 0xee, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *package_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_package_png = new wxImage(); + if (!img_package_png || !img_package_png->IsOk()) + { + wxMemoryInputStream img_package_pngIS(package_png_data, sizeof(package_png_data)); + img_package_png->LoadFile(img_package_pngIS, wxBITMAP_TYPE_PNG); + } + return img_package_png; +} +#define package_png_img package_png_img() + +static wxBitmap *package_png_bmp() +{ + static wxBitmap *bmp_package_png; + if (!bmp_package_png || !bmp_package_png->IsOk()) + bmp_package_png = new wxBitmap(*package_png_img); + return bmp_package_png; +} +#define package_png_bmp package_png_bmp() + +static wxIcon *package_png_ico() +{ + static wxIcon *ico_package_png; + if (!ico_package_png || !ico_package_png->IsOk()) + { + ico_package_png = new wxIcon(); + ico_package_png->CopyFromBitmap(*package_png_bmp); + } + return ico_package_png; +} +#define package_png_ico package_png_ico() + +#endif // PACKAGE_PNG_H diff --git a/include/images/packages.png b/include/images/packages.png new file mode 100644 index 0000000000000000000000000000000000000000..f1f91dbf5ec27ff6461c1d5ed05f7149c019f25c GIT binary patch literal 557 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf)c~ImS0H_DN9E3T>3_fW{Qa@z z&$l(dzApOtdB&+@{Rb9$9G&g>_vfxt$NGMMTlwe5#sdr8e}7y4>+|fBM>|d&ZajXd z;@E-wA0PXFeVPCB)70-Dy1u=uKe9LG^UI8rN85gVnfLS4lY<$;AD#vrJ6Q7lecQLURbO7`e}0+r=~?7~ZFcV; zxg6V{_4RG#msfe8UnG5e7XIOh@BXc3?;cnk-W_&mm*2r1t_QZ+?%!(q=|#fFXQ3aS zc)fq*`0jzl47=Z3fF5Hk3GxeOaCmkj4angv@Q5r1(jH*!b~4)z$msWUaSV~ToScx5 zkix|1#%7U_l$My9oZeK}_(^6?f@w@ZWu9D|h^bG_pA}g%ST0;K;B>me!P(u>^fpPT zd4=Hg2~#FbOJusu6r!xHzJ9@qC2N>2vV<&NwQSwOl}pz$i#=dkb@A$Da|072v&Kl> zw5+te#LU!OW>JP!8@FyQFL3!JIC=8s?$y%5hngkq+!z=(HFGz%KRI#;=rq+5*NBpo z#FA92CuWneJxo!%-G4Y~O#nQ4^}4F;BA d4M5cOJv literal 0 HcmV?d00001 diff --git a/include/images/packages.pngc b/include/images/packages.pngc new file mode 100644 index 0000000..0f289a1 --- /dev/null +++ b/include/images/packages.pngc @@ -0,0 +1,114 @@ +#ifndef PACKAGES_PNG_H +#define PACKAGES_PNG_H + +static const unsigned char packages_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xd5, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xd6, 0xb8, 0x79, 0xb9, +0x87, 0x1b, 0xfe, 0xfa, 0xbc, 0xfd, 0xf8, 0xb4, +0xfc, 0xf6, 0xac, 0xfa, 0xf5, 0xa2, 0xf9, 0xf3, +0x98, 0xca, 0xc6, 0x8f, 0xc0, 0xa1, 0x48, 0xc5, +0x9b, 0x41, 0xfd, 0xf9, 0xba, 0xca, 0xc6, 0x8e, +0xfb, 0xf6, 0xa9, 0xfc, 0xf8, 0xb1, 0xc0, 0xa1, +0x47, 0xfb, 0xf6, 0xa7, 0xfa, 0xf3, 0x9b, 0xc9, +0xc5, 0x88, 0xc8, 0xc3, 0x81, 0xc7, 0xc2, 0x78, +0xc6, 0xc0, 0x6f, 0xf8, 0xf1, 0x8f, 0xfa, 0xf4, +0x9f, 0xf9, 0xf2, 0x95, 0xf7, 0xf0, 0x8a, 0xf6, +0xee, 0x7f, 0xc4, 0xbd, 0x5c, 0xf3, 0xe9, 0x68, +0xc9, 0xc5, 0x86, 0xfa, 0xf4, 0x9e, 0xf9, 0xf2, +0x94, 0xf7, 0xf0, 0x89, 0xf6, 0xee, 0x7d, 0xf5, +0xeb, 0x72, 0xc2, 0xba, 0x52, 0xf2, 0xe7, 0x5c, +0xc8, 0xc3, 0x7e, 0xf8, 0xf2, 0x92, 0xf7, 0xef, +0x87, 0xf6, 0xed, 0x7c, 0xf4, 0xeb, 0x71, 0xf3, +0xe9, 0x65, 0xc2, 0xb9, 0x48, 0xf0, 0xe5, 0x50, +0xc6, 0xc1, 0x74, 0xf7, 0xef, 0x86, 0xf6, 0xed, +0x7a, 0xf4, 0xeb, 0x6f, 0xf3, 0xe9, 0x64, 0xf2, +0xe6, 0x59, 0xc0, 0xb6, 0x3e, 0xef, 0xe2, 0x44, +0xc6, 0xbf, 0x6a, 0xf5, 0xed, 0x79, 0xf4, 0xea, +0x6e, 0xf3, 0xe8, 0x62, 0xf1, 0xe6, 0x57, 0xf0, +0xe4, 0x4d, 0xbf, 0xb5, 0x36, 0xee, 0xe0, 0x3a, +0xc3, 0xbb, 0x56, 0xc2, 0xba, 0x4e, 0xc1, 0xb8, +0x45, 0xc0, 0xb6, 0x3d, 0xbf, 0xb5, 0x35, 0xf2, +0xe8, 0x60, 0xf1, 0xe6, 0x55, 0xf0, 0xe4, 0x4a, +0xef, 0xe2, 0x41, 0xee, 0xe0, 0x38, 0x98, 0x3e, +0xfb, 0xb4, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x8f, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, +0x60, 0x60, 0x64, 0x02, 0x01, 0x46, 0x06, 0x38, +0x60, 0x62, 0x66, 0x61, 0x65, 0x63, 0x67, 0x82, +0x71, 0x81, 0xf2, 0x1c, 0x9c, 0x60, 0x35, 0x5c, +0x50, 0x79, 0x6e, 0x1e, 0x5e, 0x14, 0x35, 0x4c, +0x7c, 0xfc, 0xa8, 0x6a, 0x98, 0x04, 0xd0, 0xd4, +0x30, 0x09, 0x42, 0xd4, 0x08, 0x09, 0x8b, 0x88, +0x82, 0xed, 0x62, 0x12, 0x83, 0xa8, 0x11, 0x97, +0x90, 0x94, 0x92, 0x96, 0x61, 0x02, 0xdb, 0x02, +0x54, 0x23, 0x2b, 0x27, 0xaf, 0xa0, 0xa8, 0xa4, +0xac, 0x02, 0xd1, 0x04, 0x54, 0xa3, 0xaa, 0xa6, +0xae, 0xa1, 0xa9, 0xa5, 0xad, 0x03, 0x16, 0xe0, +0x02, 0xaa, 0xd1, 0xd5, 0xd3, 0x37, 0x30, 0x34, +0x32, 0x36, 0x81, 0x59, 0x2d, 0x66, 0x6a, 0x66, +0x6e, 0x61, 0x69, 0x65, 0x6d, 0x03, 0x15, 0x00, +0xaa, 0xb1, 0xb5, 0xb3, 0x77, 0x70, 0x44, 0xf2, +0x11, 0x93, 0x93, 0xb3, 0x8b, 0xab, 0x1b, 0x13, +0xc2, 0x83, 0x18, 0x3e, 0x46, 0x00, 0x00, 0xb2, +0x83, 0x0b, 0x81, 0x87, 0xe4, 0xc4, 0xc2, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *packages_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_packages_png = new wxImage(); + if (!img_packages_png || !img_packages_png->IsOk()) + { + wxMemoryInputStream img_packages_pngIS(packages_png_data, sizeof(packages_png_data)); + img_packages_png->LoadFile(img_packages_pngIS, wxBITMAP_TYPE_PNG); + } + return img_packages_png; +} +#define packages_png_img packages_png_img() + +static wxBitmap *packages_png_bmp() +{ + static wxBitmap *bmp_packages_png; + if (!bmp_packages_png || !bmp_packages_png->IsOk()) + bmp_packages_png = new wxBitmap(*packages_png_img); + return bmp_packages_png; +} +#define packages_png_bmp packages_png_bmp() + +static wxIcon *packages_png_ico() +{ + static wxIcon *ico_packages_png; + if (!ico_packages_png || !ico_packages_png->IsOk()) + { + ico_packages_png = new wxIcon(); + ico_packages_png->CopyFromBitmap(*packages_png_bmp); + } + return ico_packages_png; +} +#define packages_png_ico packages_png_ico() + +#endif // PACKAGES_PNG_H diff --git a/include/images/parser.png b/include/images/parser.png new file mode 100644 index 0000000000000000000000000000000000000000..47eca9950499fc0ca1e2ee0a419a8a380fd528f3 GIT binary patch literal 715 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47-Ir_LR^8|m3!MN7a1f>VVS)( zuW6md$rpH42FSAQ?N{CnQTU$gf;X{leUmpx13#@FpP{%^Sa zZ|V8JbI<;ncItQEnctJH|6YFO*MdtwXJ7s?=gh~+_y6zPt#bY3@9s&PGFKn&x-jF& z5v?ajv>tCMU3>kOAtZ;p(r&7rIZ}On!3j=#D!_w%ka% zccJUVt-l-FS0uEqh&ueUwsD#7io?yvWZpcvzGK#|sF}M$A6{E?R^`L>KdX-YYB}_y zYTx&Q-QUvA|Cn^9Yu}Be`?n9Ty>)oi^`u+pIuBm?y{K_nK>ae$+9gigzC^aI@m_SW zcvI=}Q>G6OY2I63yx{!TzQP3xIkTlseVBgmd+E-viCaI1ZT#f3_M_9LkA8>0lpOq= zci>aj;ZOPdUl-2ZR?xiB?D+fc6WAQH&DASbt;}v< zG1P;3%h2vt?V0L0;9Wnx_G#GIlsStzWj!U_4Df;5&{Z5 zG9oHmR00&Vtklf(>=X?(Emci*xilusn>cgo+{v@2#|K1&%;77Wsc>d#lg^PJJivq_ zeouzQkE7)|(8a1Ht`Q|Ei6yC4$wjF^iowXh&_LJFNY}tH#K^$P#MsKjRNKJR%D`aW tJH1sX8glbfGSey{8VoGK8i1-ztPIQ`8ct0QT?5p>;OXk;vd$@?2>`SDU7!E} literal 0 HcmV?d00001 diff --git a/include/images/parser.pngc b/include/images/parser.pngc new file mode 100644 index 0000000..b27efb1 --- /dev/null +++ b/include/images/parser.pngc @@ -0,0 +1,134 @@ +#ifndef PARSER_PNG_H +#define PARSER_PNG_H + +static const unsigned char parser_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x5c, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xa9, 0xbd, 0x86, 0x79, +0xa2, 0x30, 0x60, 0x94, 0x04, 0x9b, 0xb5, 0x6e, +0x82, 0xae, 0x38, 0xc9, 0xe8, 0xa2, 0xe0, 0xff, +0xc1, 0xdd, 0xfe, 0xbc, 0xdc, 0xfe, 0xb7, 0xda, +0xfe, 0xb2, 0xd7, 0xfc, 0xac, 0xd5, 0xfb, 0xa6, +0xd3, 0xfb, 0x9e, 0xd1, 0xfa, 0x9b, 0xbe, 0xe4, +0x84, 0x7f, 0xad, 0x2e, 0x6b, 0x9a, 0x18, 0xd8, +0xf5, 0xb7, 0xd8, 0xff, 0xb0, 0xd3, 0xfe, 0xa5, +0xcf, 0xfd, 0x9d, 0xcd, 0xfc, 0x96, 0xca, 0xfb, +0x8e, 0xcc, 0xfb, 0x92, 0xd7, 0xfb, 0xa7, 0xd4, +0xfa, 0xa0, 0xd2, 0xf9, 0x9b, 0xd3, 0xf8, 0x9c, +0xcc, 0xf1, 0x93, 0xdf, 0xff, 0xbe, 0xbb, 0x24, +0xd7, 0xc9, 0xfb, 0x8b, 0x92, 0xb2, 0x69, 0xab, +0xc3, 0x8a, 0xd0, 0x98, 0xc4, 0xc4, 0x2a, 0xe4, +0xc4, 0x2a, 0xe3, 0xb4, 0x75, 0xad, 0xd7, 0xf8, +0xa4, 0x7b, 0xa6, 0x2e, 0xdc, 0xfe, 0xb8, 0xce, +0xfd, 0x99, 0xcb, 0xfc, 0x91, 0xc8, 0xfa, 0x89, +0xc4, 0xf9, 0x80, 0xd5, 0xfa, 0xa3, 0xd0, 0x8b, +0xc8, 0xd9, 0x63, 0xe4, 0xde, 0xc5, 0xb8, 0xdc, +0xc4, 0xb4, 0xd8, 0x62, 0xde, 0xd0, 0x8a, 0xc8, +0xda, 0xfd, 0xb1, 0x87, 0xa8, 0x60, 0x85, 0xa8, +0x5a, 0xc3, 0xf9, 0x7d, 0x81, 0xa6, 0x4d, 0xa8, +0xc3, 0x83, 0xc6, 0x1c, 0xec, 0xe4, 0xd7, 0xb8, +0x9a, 0xba, 0x5a, 0x99, 0xba, 0x55, 0xe1, 0xd6, +0xac, 0xcd, 0x24, 0xf0, 0xd7, 0xfc, 0xaa, 0xc6, +0xfa, 0x84, 0xc2, 0xf8, 0x7a, 0xbe, 0xf7, 0x70, +0xbb, 0xf6, 0x66, 0xcf, 0xf8, 0x92, 0xcc, 0x8a, +0xbe, 0xd8, 0x62, 0xdf, 0xdb, 0xc3, 0xad, 0xda, +0xc3, 0xaa, 0xd7, 0x62, 0xda, 0xce, 0x89, 0xc1, +0xd4, 0xfb, 0xa2, 0x81, 0xa6, 0x50, 0x7f, 0xa6, +0x49, 0x7d, 0xa4, 0x42, 0xb6, 0xf4, 0x59, 0x86, +0xac, 0x4b, 0xa2, 0xc1, 0x73, 0xb2, 0x75, 0xa7, +0xca, 0x35, 0xe1, 0xc2, 0x29, 0xde, 0xaf, 0x73, +0xa0, 0xcf, 0xf5, 0x8e, 0x71, 0xa0, 0x20, 0x6c, +0x9b, 0x1a, 0xca, 0xf0, 0x97, 0xc1, 0xf7, 0x75, +0xb9, 0xf5, 0x61, 0xb5, 0xf3, 0x56, 0xb1, 0xf2, +0x4c, 0xad, 0xf1, 0x42, 0xb2, 0xf1, 0x4e, 0xc3, +0xf4, 0x74, 0xc1, 0xf3, 0x6e, 0xc0, 0xf2, 0x6a, +0xc3, 0xf2, 0x6f, 0xbf, 0xeb, 0x71, 0x9d, 0xb6, +0x70, 0x83, 0xb1, 0x36, 0xc7, 0xef, 0x8b, 0xc8, +0xf6, 0x80, 0xc4, 0xf5, 0x77, 0xc1, 0xf4, 0x6f, +0xbf, 0xf3, 0x68, 0xbc, 0xf2, 0x62, 0xb9, 0xf2, +0x5b, 0xb7, 0xf1, 0x56, 0xb7, 0xf0, 0x54, 0xb7, +0xe9, 0x5f, 0x7f, 0xaf, 0x29, 0xf8, 0x7b, 0x6f, +0x74, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0xa6, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0x20, +0x02, 0x30, 0x32, 0x31, 0x43, 0x01, 0x13, 0x23, +0x88, 0xcf, 0xc2, 0xca, 0xc6, 0xce, 0xc1, 0xc9, +0xc5, 0xcd, 0xc3, 0xcb, 0xc7, 0x2f, 0xc0, 0x02, +0x14, 0x10, 0x14, 0x12, 0x16, 0x11, 0x15, 0x13, +0x97, 0x90, 0x94, 0x92, 0x96, 0x91, 0x15, 0x04, +0x0a, 0x30, 0xcb, 0xc9, 0xcb, 0xcb, 0x2b, 0x28, +0x2a, 0x29, 0xab, 0xa8, 0xaa, 0xa9, 0x6b, 0x80, +0x04, 0x34, 0xb5, 0xb4, 0x75, 0x74, 0xf5, 0xf4, +0x0d, 0x0c, 0x8d, 0x8c, 0x4d, 0xc0, 0x02, 0xa6, +0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, +0x76, 0xf6, 0x0e, 0x60, 0x01, 0x47, 0x27, 0x67, +0x17, 0x57, 0x37, 0x77, 0x0f, 0x4f, 0x2f, 0x6f, +0x1f, 0xb0, 0x80, 0xaf, 0x9f, 0x7f, 0x40, 0x60, +0x50, 0x70, 0x48, 0x68, 0x58, 0x78, 0x44, 0x24, +0x50, 0x20, 0x2a, 0x3a, 0x26, 0x36, 0x2e, 0x3e, +0x21, 0x31, 0x29, 0x39, 0x25, 0x35, 0x2d, 0x0a, +0x28, 0x90, 0x9e, 0x91, 0x99, 0x95, 0x9d, 0x93, +0x9b, 0x97, 0x5f, 0x50, 0x58, 0x54, 0x9c, 0x0e, +0x76, 0x99, 0x20, 0xcc, 0xa5, 0x82, 0x2c, 0xc4, +0xf8, 0x0c, 0x03, 0x00, 0x00, 0x17, 0xde, 0x1c, +0x04, 0x4e, 0x08, 0x84, 0xe7, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *parser_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_parser_png = new wxImage(); + if (!img_parser_png || !img_parser_png->IsOk()) + { + wxMemoryInputStream img_parser_pngIS(parser_png_data, sizeof(parser_png_data)); + img_parser_png->LoadFile(img_parser_pngIS, wxBITMAP_TYPE_PNG); + } + return img_parser_png; +} +#define parser_png_img parser_png_img() + +static wxBitmap *parser_png_bmp() +{ + static wxBitmap *bmp_parser_png; + if (!bmp_parser_png || !bmp_parser_png->IsOk()) + bmp_parser_png = new wxBitmap(*parser_png_img); + return bmp_parser_png; +} +#define parser_png_bmp parser_png_bmp() + +static wxIcon *parser_png_ico() +{ + static wxIcon *ico_parser_png; + if (!ico_parser_png || !ico_parser_png->IsOk()) + { + ico_parser_png = new wxIcon(); + ico_parser_png->CopyFromBitmap(*parser_png_bmp); + } + return ico_parser_png; +} +#define parser_png_ico parser_png_ico() + +#endif // PARSER_PNG_H diff --git a/include/images/parsers.png b/include/images/parsers.png new file mode 100644 index 0000000000000000000000000000000000000000..340ec6b7fbdcf1702f66fe2c833fcdcd512bb141 GIT binary patch literal 620 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47+C{+LR^8|m3!MN7a1f>VVS)( zuW6md$rp~=ES4#=42>Eak7aXC5R z07H+@8G!>wIG%0ZuxVp)K~dr751&46ZeU?yX>D2P<>KPVbS5doYsS%wQw$bsPh`-V zIAzkbiBl(s2ZRVEBm|_Tg$0HN2M1pdxP0YO8r!RjiPx@PHa9RaGBY$aX6Mu}j*f_m zynW-=O=}CQMiz;ZIk7Q!@7UVx-BVkm>cDiW&g&mzqvJtE#f6Ed1g>*C+*Leq$bp4{ z;lM(nj5%k`L4Hv!ag8WRNi0dVN-jzTQVd20h6cKZM!E)uAw~vPCdO7KrrHLkRt5(1 t-s!DE(U6;;l9^Ts(O_T+)&Nv(Vr5_k(Qs;d=o+8~22WQ%mvv4FO#s2@A-Vtn literal 0 HcmV?d00001 diff --git a/include/images/parsers.pngc b/include/images/parsers.pngc new file mode 100644 index 0000000..d5a5553 --- /dev/null +++ b/include/images/parsers.pngc @@ -0,0 +1,122 @@ +#ifndef PARSERS_PNG_H +#define PARSERS_PNG_H + +static const unsigned char parsers_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x05, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xa9, 0xbd, 0x86, 0x79, +0xa2, 0x30, 0x60, 0x94, 0x04, 0x9b, 0xb5, 0x6e, +0x82, 0xae, 0x38, 0xc9, 0xe8, 0xa2, 0xe0, 0xff, +0xc1, 0xdf, 0xff, 0xbf, 0xdd, 0xfe, 0xbb, 0xdb, +0xfe, 0xb6, 0xd9, 0xfd, 0xb0, 0xd7, 0xfc, 0xa8, +0xd5, 0xfb, 0xa4, 0xc0, 0xe5, 0x89, 0x7f, 0xad, +0x30, 0x6b, 0x9a, 0x18, 0xd8, 0xf5, 0xb7, 0xab, +0xd7, 0x70, 0x79, 0xaa, 0x27, 0x76, 0xa7, 0x20, +0x67, 0x98, 0x10, 0xa0, 0xca, 0x62, 0x6c, 0x9e, +0x15, 0x6c, 0x9b, 0x1a, 0xd8, 0xff, 0xb1, 0xd4, +0xfe, 0xa7, 0xd0, 0xfe, 0x9f, 0xcd, 0xfc, 0x97, +0xca, 0xfb, 0x8e, 0xc6, 0xfa, 0x84, 0xc2, 0xf8, +0x79, 0xbe, 0xf7, 0x6f, 0xbf, 0xf6, 0x70, 0xc6, +0xef, 0x88, 0x9d, 0xb6, 0x70, 0xdf, 0xff, 0xbe, +0xd1, 0xfe, 0xa2, 0xbb, 0x24, 0xd7, 0xc3, 0xf9, +0x7c, 0x9d, 0x65, 0x92, 0xba, 0x23, 0xd5, 0xbc, +0x93, 0x93, 0xc3, 0xf5, 0x74, 0x66, 0x98, 0x0f, +0xdb, 0xfe, 0xb4, 0xcb, 0xfc, 0x93, 0xc8, 0xfa, +0x89, 0xc4, 0xf9, 0x7e, 0xc0, 0xf7, 0x73, 0xc3, +0x89, 0xab, 0xd9, 0x63, 0xe3, 0xdd, 0xc4, 0xb5, +0xdc, 0xc4, 0xb0, 0xd8, 0x62, 0xdd, 0xc3, 0x87, +0xa8, 0xd7, 0xfc, 0xa9, 0xc5, 0xf9, 0x82, 0x81, +0xa6, 0x4f, 0x7e, 0xa5, 0x48, 0xb8, 0xf5, 0x5f, +0xc0, 0x18, 0xe2, 0xd4, 0xc2, 0xaa, 0x98, 0xba, +0x52, 0x96, 0xb9, 0x4d, 0xe0, 0xd5, 0xa7, 0xc9, +0x23, 0xe7, 0xcc, 0xf0, 0x99, 0xc2, 0xf8, 0x77, +0xba, 0xf5, 0x63, 0xb5, 0xf3, 0x56, 0xb0, 0xf2, +0x4a, 0xba, 0x86, 0x94, 0xd7, 0x62, 0xdc, 0xd9, +0xc3, 0xa6, 0xd9, 0xc3, 0xa2, 0xd7, 0x62, 0xda, +0xc0, 0x81, 0xa6, 0x83, 0xb1, 0x35, 0xc5, 0xf5, +0x7c, 0xc2, 0xf5, 0x71, 0xbf, 0xf3, 0x69, 0xbc, +0xf2, 0x62, 0xc0, 0x93, 0x9b, 0xc7, 0x34, 0xda, +0xbf, 0x8e, 0x9e, 0x7f, 0xaf, 0x29, 0x7b, 0x20, +0x17, 0xe1, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x9e, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, +0xc0, 0x00, 0x8c, 0x4c, 0xcc, 0x10, 0xc0, 0xc4, +0x08, 0xe6, 0xb3, 0xb0, 0xb2, 0xb1, 0x73, 0x70, +0x72, 0x71, 0xf3, 0xf0, 0xf2, 0xf1, 0xb3, 0x80, +0x04, 0x04, 0x04, 0x85, 0x84, 0xa1, 0x4a, 0x44, +0x44, 0x41, 0x02, 0xcc, 0x62, 0x68, 0x4a, 0x98, +0xc5, 0xd1, 0x94, 0x30, 0xa3, 0x2b, 0x91, 0x00, +0x2a, 0x91, 0x94, 0x92, 0x96, 0x91, 0x95, 0x93, +0x57, 0x50, 0x54, 0x12, 0x60, 0x60, 0x50, 0x66, +0x66, 0x56, 0x51, 0x55, 0x53, 0x53, 0x53, 0xd7, +0x50, 0xd3, 0xd4, 0xd2, 0x66, 0x06, 0xea, 0xd1, +0x61, 0xd6, 0xd5, 0xd3, 0x37, 0x30, 0x34, 0x32, +0x36, 0x31, 0x35, 0x33, 0x07, 0x09, 0x28, 0x33, +0x5b, 0x58, 0x5a, 0x59, 0xdb, 0xd8, 0xda, 0xd9, +0x3b, 0x38, 0x3a, 0x81, 0x04, 0x18, 0x74, 0x9c, +0x5d, 0x5c, 0xdd, 0xdc, 0x3d, 0x3c, 0xbd, 0xbc, +0x7d, 0x7c, 0x25, 0x40, 0x02, 0xca, 0x7e, 0x4a, +0xfe, 0x01, 0x81, 0x41, 0xc1, 0x21, 0x21, 0xa1, +0x61, 0xca, 0x10, 0xd7, 0x0b, 0x40, 0xdd, 0x21, +0xc0, 0xc2, 0x40, 0x04, 0x00, 0x00, 0xc0, 0xa1, +0x12, 0x68, 0x9c, 0xcd, 0x37, 0xe1, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *parsers_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_parsers_png = new wxImage(); + if (!img_parsers_png || !img_parsers_png->IsOk()) + { + wxMemoryInputStream img_parsers_pngIS(parsers_png_data, sizeof(parsers_png_data)); + img_parsers_png->LoadFile(img_parsers_pngIS, wxBITMAP_TYPE_PNG); + } + return img_parsers_png; +} +#define parsers_png_img parsers_png_img() + +static wxBitmap *parsers_png_bmp() +{ + static wxBitmap *bmp_parsers_png; + if (!bmp_parsers_png || !bmp_parsers_png->IsOk()) + bmp_parsers_png = new wxBitmap(*parsers_png_img); + return bmp_parsers_png; +} +#define parsers_png_bmp parsers_png_bmp() + +static wxIcon *parsers_png_ico() +{ + static wxIcon *ico_parsers_png; + if (!ico_parsers_png || !ico_parsers_png->IsOk()) + { + ico_parsers_png = new wxIcon(); + ico_parsers_png->CopyFromBitmap(*parsers_png_bmp); + } + return ico_parsers_png; +} +#define parsers_png_ico parsers_png_ico() + +#endif // PARSERS_PNG_H diff --git a/include/images/pgAdmin3-128.png b/include/images/pgAdmin3-128.png new file mode 100644 index 0000000000000000000000000000000000000000..48bf5cbeb402ad945e64bdfa7dfba8b579119432 GIT binary patch literal 8373 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 literal 0 HcmV?d00001 diff --git a/include/images/pgAdmin3-16.png b/include/images/pgAdmin3-16.png new file mode 100644 index 0000000000000000000000000000000000000000..8d7db549ac8c5d0075346c7085c4a44e5a59aba7 GIT binary patch literal 850 zcmV-Y1FigtP)Gd4PR*$^O{e?Nxw(&Xy09J8 zik`cd=l4GRpa1(3vMd9Dd2V^*s{d!GN~5B;Of0iz%F~W4uSZ&gksYUAs|G<3hS`-M zt;tbEoV>yB6$-lmLIBvTq%k|6JgDun_R zTaBnME5_{d240R#DqeR-GiZ`Pwdla-=>T#W)jVx8>&Feb+Oy&9z5X;s;okFMIISF- zy&mOqu2uzKU>ysqAtaJ%oURjt4vu?7ijMsLYSA9ff;2@SotEGW1hJb+D*>@Y68S8H zL@EuMB2gzg##mM}PXh2&xC@rDV0b$LQ=aaR{;~}CS3@wf3~EG2yx45$0RR#Jcuw!n zf*-#vqNUmcnj#^|2iAkPV?MOimqI8seJLv7J}3ch-teSWw8sD-v>nIM5`OCbm9~i- ziaHRG&PbRE1mU!D(YfV~o|RyviUfcno3X#6#XGLfq0!yZG$R&S`ZlBS9T#uR2!*Bt zAuisC{-KH5g|*Q6;C8}JW(~p4cRsk*{XWcfMf|fU+}Xf`2H+ z>9tX1%0kmB!>E1xf&T@BZJa)qJ)9^j_5)bl4-oR9r#h^Og_T>gfl#YauM1bWZFksQ c&Aa{nFYgupL+O8@`> literal 0 HcmV?d00001 diff --git a/include/images/pgAdmin3-16.pngc b/include/images/pgAdmin3-16.pngc new file mode 100644 index 0000000..c8bdfb6 --- /dev/null +++ b/include/images/pgAdmin3-16.pngc @@ -0,0 +1,151 @@ +#ifndef PGADMIN3_16_PNG_H +#define PGADMIN3_16_PNG_H + +static const unsigned char pgAdmin3_16_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff, +0x61, 0x00, 0x00, 0x00, 0x04, 0x73, 0x42, 0x49, +0x54, 0x08, 0x08, 0x08, 0x08, 0x7c, 0x08, 0x64, +0x88, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, +0x6b, 0x01, 0x0e, 0x5f, 0x5b, 0x51, 0x00, 0x00, +0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, +0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x00, 0x77, +0x77, 0x77, 0x2e, 0x69, 0x6e, 0x6b, 0x73, 0x63, +0x61, 0x70, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x9b, +0xee, 0x3c, 0x1a, 0x00, 0x00, 0x02, 0xcf, 0x49, +0x44, 0x41, 0x54, 0x38, 0x8d, 0x85, 0x92, 0x5d, +0x48, 0x53, 0x61, 0x1c, 0xc6, 0x9f, 0xf3, 0xe1, +0xbe, 0x8e, 0xf3, 0xec, 0x6c, 0x73, 0xdb, 0xd1, +0x4d, 0xb7, 0x79, 0x16, 0x07, 0xc5, 0xb4, 0xf9, +0x15, 0x06, 0x26, 0x8a, 0x44, 0x20, 0x88, 0x75, +0xd1, 0x97, 0x04, 0x5e, 0x79, 0x57, 0x74, 0x51, +0x50, 0xde, 0x7a, 0x11, 0x18, 0x41, 0x74, 0x11, +0x11, 0x21, 0x74, 0xd1, 0x4d, 0xd2, 0xc7, 0x45, +0x18, 0x5d, 0x24, 0xa9, 0x41, 0x98, 0x19, 0x81, +0x26, 0x4e, 0xcd, 0xa9, 0x33, 0x4d, 0xa7, 0xfb, +0xd0, 0xb9, 0xb9, 0x8f, 0x73, 0xba, 0xb0, 0x1d, +0xd4, 0x8a, 0x9e, 0xbb, 0x97, 0xe7, 0xf7, 0x3e, +0xfc, 0x9f, 0xff, 0xfb, 0x12, 0xb2, 0x2c, 0x03, +0x80, 0x79, 0x6e, 0x79, 0xe3, 0xaa, 0xff, 0x67, +0xa8, 0x4a, 0xa3, 0xa2, 0xb7, 0x4c, 0x2c, 0xb3, +0x66, 0xca, 0xd3, 0x8e, 0x2c, 0xaf, 0x47, 0x5a, +0x83, 0x91, 0x1d, 0xa7, 0x5e, 0xab, 0x06, 0x41, +0x10, 0x86, 0xd9, 0x95, 0x20, 0xad, 0xc9, 0x51, +0x45, 0x9c, 0xbc, 0xc1, 0xef, 0x15, 0x0a, 0xbb, +0x00, 0x44, 0x08, 0x59, 0x96, 0x6d, 0x03, 0xa3, +0xd3, 0xef, 0xef, 0x3e, 0x1b, 0x3a, 0x12, 0xda, +0x8a, 0x03, 0x00, 0x1a, 0x2b, 0x4b, 0x60, 0x66, +0x75, 0x78, 0x31, 0x3c, 0x89, 0x8c, 0x24, 0x81, +0x22, 0x49, 0xd4, 0x88, 0x76, 0x94, 0xbb, 0x6c, +0x78, 0x3c, 0xf0, 0x09, 0x8c, 0x46, 0x85, 0x9b, +0x17, 0x1a, 0x27, 0x4a, 0x05, 0xcb, 0x45, 0xaa, +0xfd, 0x72, 0x57, 0xef, 0x8d, 0x87, 0xaf, 0x4f, +0xc5, 0xe2, 0x49, 0x00, 0x40, 0x0e, 0x4d, 0xa1, +0xf5, 0xb8, 0x88, 0xbe, 0x37, 0x63, 0xf8, 0x3d, +0x1d, 0x64, 0x59, 0x46, 0x60, 0x3d, 0x82, 0xd5, +0xcd, 0x2d, 0x9c, 0x69, 0x28, 0xc7, 0xe8, 0xd4, +0x12, 0x06, 0xbf, 0x7e, 0xb7, 0x34, 0x57, 0x78, +0xb4, 0x64, 0x64, 0x2b, 0x6e, 0x49, 0xa6, 0x32, +0xc8, 0xca, 0x65, 0xe3, 0x30, 0xe6, 0x0b, 0xe0, +0x6f, 0xfa, 0xb1, 0x11, 0x05, 0x01, 0x20, 0x4f, +0xa7, 0x86, 0x24, 0xc9, 0x48, 0x24, 0x53, 0x1a, +0x5a, 0x92, 0x20, 0xef, 0x87, 0x2a, 0x85, 0x02, +0x14, 0x5b, 0x8d, 0xa8, 0x2f, 0x2b, 0xc6, 0xec, +0xf2, 0x06, 0x5e, 0x8e, 0x4c, 0x2a, 0x5e, 0x77, +0x47, 0x33, 0x68, 0x92, 0x40, 0xb5, 0xe8, 0xc0, +0xe7, 0xe9, 0x00, 0x72, 0x19, 0xd5, 0x3c, 0x6d, +0x33, 0xeb, 0xc7, 0x0d, 0xb9, 0xda, 0xb3, 0xe1, +0xed, 0xbd, 0xfe, 0x34, 0x45, 0xe1, 0xde, 0xf3, +0x61, 0x38, 0xad, 0x1c, 0x9a, 0xbd, 0x1e, 0xe5, +0x72, 0xae, 0x56, 0x05, 0x5f, 0x60, 0x1d, 0x0b, +0xab, 0x21, 0x24, 0x92, 0x69, 0x9c, 0xae, 0x13, +0x83, 0x0e, 0x8e, 0x7b, 0x44, 0x8a, 0x8e, 0xfc, +0xfe, 0x6a, 0xd1, 0x1e, 0xce, 0x82, 0x34, 0x45, +0x20, 0x9d, 0x96, 0xe0, 0x0b, 0x04, 0xb1, 0x9b, +0x4a, 0x2b, 0x01, 0xb1, 0x44, 0x12, 0xf9, 0x2c, +0x83, 0x44, 0x2a, 0x0d, 0x9a, 0x22, 0x51, 0x27, +0x3a, 0xc6, 0x58, 0x56, 0x33, 0x4f, 0x02, 0xf0, +0x55, 0xb8, 0x0b, 0x96, 0xb2, 0x60, 0x78, 0x3b, +0x01, 0x53, 0x9e, 0xee, 0x8f, 0xfe, 0xb2, 0x0c, +0xf8, 0x57, 0x43, 0x30, 0xb3, 0x0c, 0x6a, 0x44, +0x47, 0xbc, 0xd8, 0x6c, 0xe8, 0x01, 0x00, 0x12, +0x00, 0x78, 0x4e, 0xef, 0xcf, 0x82, 0x1f, 0xbf, +0x2d, 0xa2, 0xa5, 0xda, 0x03, 0x9a, 0x22, 0x21, +0xc9, 0x07, 0xd6, 0x83, 0xb7, 0x63, 0x3e, 0xb4, +0xd5, 0x97, 0x42, 0x28, 0x34, 0x7d, 0x29, 0x2a, +0xe0, 0x3e, 0x28, 0x01, 0x6e, 0xde, 0xf0, 0xa4, +0x56, 0xb4, 0xc7, 0x00, 0x20, 0xb4, 0x1d, 0xc7, +0xd1, 0x12, 0x7e, 0xea, 0xfe, 0x95, 0xb6, 0x89, +0x1c, 0x8a, 0x3a, 0x10, 0x90, 0xce, 0x48, 0x98, +0x09, 0x04, 0xe1, 0xb4, 0x72, 0xd1, 0xb9, 0xe5, +0x8d, 0x9e, 0x95, 0x60, 0xa4, 0x8a, 0x04, 0x80, +0x22, 0x9b, 0xb1, 0xbf, 0xa3, 0xc5, 0x3b, 0xae, +0xce, 0xa1, 0xd1, 0xdd, 0xd1, 0x34, 0x23, 0x16, +0x59, 0xfa, 0x36, 0xa3, 0xf1, 0x1d, 0x17, 0x6f, +0xcc, 0x08, 0x85, 0xa6, 0x03, 0x21, 0x2e, 0xde, +0x88, 0xfe, 0xa1, 0x89, 0xda, 0x85, 0xb5, 0xd0, +0xf9, 0xe0, 0x76, 0xc2, 0x4e, 0x66, 0x0d, 0xc1, +0xce, 0x77, 0x3e, 0xb8, 0xd6, 0xfe, 0xb4, 0xd1, +0x5b, 0xd2, 0x1e, 0x0c, 0xef, 0xb4, 0x66, 0x24, +0x49, 0x16, 0x1d, 0xe6, 0x5e, 0x33, 0xcb, 0x28, +0x3d, 0x38, 0xbd, 0x16, 0x46, 0x96, 0xb9, 0x7d, +0xfd, 0x5c, 0x43, 0x55, 0xd3, 0x31, 0xc1, 0x53, +0xee, 0xb4, 0xbe, 0xa2, 0xb3, 0xa6, 0x85, 0x55, +0xcf, 0x59, 0x58, 0xfe, 0xd2, 0xde, 0x5f, 0xe0, +0x4f, 0x56, 0x0a, 0x3c, 0x00, 0x88, 0x46, 0xbd, +0xae, 0x13, 0x80, 0x15, 0x00, 0xec, 0xf9, 0x86, +0x5d, 0x77, 0xbe, 0x61, 0x10, 0x80, 0xb2, 0x33, +0x65, 0x82, 0x7f, 0x28, 0xc6, 0xe9, 0xb5, 0x51, +0x65, 0xca, 0x42, 0xd3, 0x2a, 0xc3, 0xa8, 0x7d, +0xfb, 0x81, 0xff, 0x05, 0x84, 0x6d, 0x9c, 0x3e, +0x96, 0x3d, 0x9c, 0x28, 0x2b, 0xf6, 0x03, 0x58, +0xdc, 0x0f, 0x10, 0xf2, 0xa1, 0xa7, 0x3a, 0xac, +0x89, 0x85, 0x95, 0x5b, 0xb3, 0x81, 0x50, 0xab, +0x51, 0xaf, 0x0b, 0x57, 0xb8, 0x6d, 0x77, 0xd8, +0x5c, 0xcd, 0xbb, 0xfd, 0xfe, 0x2f, 0xef, 0x15, +0xfe, 0xe5, 0x06, 0xdb, 0x32, 0xf1, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *pgAdmin3_16_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_pgAdmin3_16_png = new wxImage(); + if (!img_pgAdmin3_16_png || !img_pgAdmin3_16_png->IsOk()) + { + wxMemoryInputStream img_pgAdmin3_16_pngIS(pgAdmin3_16_png_data, sizeof(pgAdmin3_16_png_data)); + img_pgAdmin3_16_png->LoadFile(img_pgAdmin3_16_pngIS, wxBITMAP_TYPE_PNG); + } + return img_pgAdmin3_16_png; +} +#define pgAdmin3_16_png_img pgAdmin3_16_png_img() + +static wxBitmap *pgAdmin3_16_png_bmp() +{ + static wxBitmap *bmp_pgAdmin3_16_png; + if (!bmp_pgAdmin3_16_png || !bmp_pgAdmin3_16_png->IsOk()) + bmp_pgAdmin3_16_png = new wxBitmap(*pgAdmin3_16_png_img); + return bmp_pgAdmin3_16_png; +} +#define pgAdmin3_16_png_bmp pgAdmin3_16_png_bmp() + +static wxIcon *pgAdmin3_16_png_ico() +{ + static wxIcon *ico_pgAdmin3_16_png; + if (!ico_pgAdmin3_16_png || !ico_pgAdmin3_16_png->IsOk()) + { + ico_pgAdmin3_16_png = new wxIcon(); + ico_pgAdmin3_16_png->CopyFromBitmap(*pgAdmin3_16_png_bmp); + } + return ico_pgAdmin3_16_png; +} +#define pgAdmin3_16_png_ico pgAdmin3_16_png_ico() + +#endif // PGADMIN3_16_PNG_H diff --git a/include/images/pgAdmin3-22.png b/include/images/pgAdmin3-22.png new file mode 100644 index 0000000000000000000000000000000000000000..626d3db8659fa59d71dddbb8a4a9dcbf60bcbf46 GIT binary patch literal 1180 zcmV;N1Y`S&P)uzb2$)A zbOa;uE|HM@P&7HG<`oJ86h>kR4M0&ECA+4O%SNn5&AR}S06-B!;0?vQmpp+ppY&g~ z&o23(hl*!WUsebJa0-T$#h@Ccd7hmpEYM|{${iLQZ>a{SkfFKC ziJrEate$tekAP$47`e9qVDomB+s$hX!`!2dYJRY(-0qQ@Vu>V9e>Z^h*Qd}ocndC@ zDGMBqt>eoJ!$^w+oiaMJ)LYFt7%_XGh^BycZzA&Mlcrsi1yfQ+G$N{et= zP2gDh5CG5s(mECIp=oM2Hn8)fk85~p9)~KN2t?vAYI!_=u-xwy3}0-6!LhPyWw!js zOcX_BJOfHjkp=#3heF1nzRWfUU}gtw(W`%LEH7HiG_CkTcw&zc08s6+ zVsdUJ3!F@)F}?5z2P+(CuPgNx<{M9L*XXVDuh#04V5aHpo95DSDbFGaqX)ElRCBX+xEKB_;#V#tP=&JcKFQ6qo+NjX8)Fz|0>A?R$ONOnp!~hSpe)&bH))mo zPrY=g2*4}=r&h(a0MKT71fwQgyRMP)WO_+_F=;JnVmie3+yg7P56?@WWIC0|8LGe=NzIa3TC91W$bqOd|M-O#K17jpq|wX&@{RM zbcaH6gUjoyk0`Jz3dR@}6$D6@FAx?aS>{+qHLX_BkF+fFnZPmM%@!pyfSjkUsf*{X zc4hq5|5)dl4q#c59%)Gisj|rGtSYjqzrNN(UAtowhn#MRIu0c{Y1mSh2mA0iPB(V| z07M;!!!K94DhjPFW~251fFMy61tYGh8wXA{RgF$~5v%taYH_)909}Jaabp0myJiiF zGA;PRbyo|*?{qqdv^P}$mR&rMXkJU<;?e`wL-0C2vo53Rj+9N$+L z^{(C-)HL7xGaW!F6%I$%cH4$i5`}kFug2Lcw-+rwt6zE^V#4c3*{T&$@2=yC(K+cW zr`*&2?6FBNNfgxa8hCtx{{#>MoN4(T`?r)vJ+mlCqETy8NfAXG3d?aJla7Nw7{-bH zbx0L;pa{XS&s*S*0j|wjhPQWZz{HdvdR`Ot^Q~q#4cw?I(nQaevjd~D(L;<+BCesqvXhKMI+dWThe>hOT zzF;Qv%-dGB%Ac&`KLG#=K*%7lBRtE*tsoXKcj)KT(m8<5rMaNU+&k?-O-=7(7T z1YXm)z92)I9}I*f2;3Z$QPV&IKviles3(!Mq8gfo&ex{`(5m8kz&wFoJMmJfIk)hBhMavYe&W8{9rIF1*+Gs zyxjDD!><(u8Nr6S5|D&P^4W@W(~}ihj?@i1JFrSf&okd|EY5bAMF9Y? zVYO90xV@~?BI@2@8D`|%Pj>=FfyJhEc?kip)D&UYi7(ZMPhH$`y1AoXQj`)3(zt5= zq!hjW;75mEy7F_6UAwcY@UDucZuQtkuAjPaBPA@!)ZW?>_k(|&hS=gPqk@)YJYT%~ z>faPijWV>V-C`0x1u(GypjM-+z?xc-ZWhY~j%oA;0yRknuJVI7H#;MW(kE(}OB6-U z09cS)o}>p&$mNVw@%31^D%JpC7dXZa00PUl3M^YaZ>%aw&yNCFz5tMHkdyS{Q(y*X(q9sqwW3BV|@3(hkkKzZSc0D%6b05~%( zCZENm0|4+WgJW;hI*dHmh?%P)PKu)Z-zRU_>F&Dscyz!y>AR&U%4>?EP>ap~7riCu UUSYF0O#lD@07*qoM6N<$g7Jk>$N&HU literal 0 HcmV?d00001 diff --git a/include/images/pgAdmin3-256.png b/include/images/pgAdmin3-256.png new file mode 100644 index 0000000000000000000000000000000000000000..cb5c55a5816978bd949408898c47dac565ee236c GIT binary patch literal 16995 zcmXwh1y~ea*!Jww-Ka>tG}7JOUDDDmjdU(8odVL0f^>(lfJiq;x3siK!#{lA_j6rb zyF0rxbK*Hq-1mJZN?lbB3!MZV001lnd1*}mfPily04g&0^3LsxHTZ(~K~mu@D){G* zYWWfTjOHS*{{aAyTc7_S;kT%!;K5h!GJ5V>&erZ;W^Pu1mzNi-os<0s3o{ohR%bVx ztYcvk0H6dEq$S>ZXCLKwd6Ul0My{=V(wQ>&uHTntHK@(%*8knChOr8FngAb)_7a~m zEK&Sg9)_5l2q?gS0uuHxYdG?2zGc6Y??Y}$R+pW34;=VTLRVu=3%n;6f9jidk4G9C zF0ww1i}d|=;b&(@#ixS3rR)pWh#X%Z{P- zkmk=WWQiEXMgB=L{IGfkYvbXHhMP61I2|};KF~*_ikO_aHXcL^sb!$! zV%TwJbZNWsP~0Am3?{RE5yN1L=%RALw3hOeomY!69ITdUB6lxDHiya!89?wYTK;`B z=I0!FK69RmyiT)=Sb*AxxV(Cgo@U}i#ZLHg_5L8HF7O}iEZoIIwg>}`k~ppmqOA*u5oy5eRy&C<+c~vq$Ca+c}@h z<<&y1thZo`;d`QF1H*p@9`Yy-@hcbOd^=gv97Uc_zhXeTmvYc8GUN%#SPCr`cBZ%M@ z@U96n`oVOlsidpk!>gLM4*T>GEX z6=dDAO?Dfs=QK)#+H;APaLk%fevDz~f3!{b_xasIHFf&c{`%QsYk5=dlYeXSD-2#U zoLDmEvL8!@ErHT%PA|3P6+1?Aw7ww)e#AH1=klio(BO9rNhYkW*FW^1+goCY?Q$P$ za!=)yluM{&W=tn?!NoW-UZ|v+Ii8Lar{cL&wKD2=!CP}Uz?f$|{913snw80RxaBeD zm3~Gf%VOm&6fndly!b72F&}gv`@&`~;2R!s75RL)VgKL%_^1bG6Veg*3jR>uAex|x zlPHErJL`(N|9$(ademTauEGm>hG4`9-@@YMlt}u9$P!l#Wuy+d{{mYnXt-+W4pu*V z;G&UxNIhc}9$Q+_XtEOMv{+S&yXicH>GkwBeq3tm*RV#CdxU?NV z%{>}a^%%Ebwrsxm#dqlKcPvCrQO4dV`(Auzkk2TX(dMMln7X1kV3W_dxElU@4A*Yt;>U<{!`1oc3H@ zo67Un5A&}rOMYAos1&_i{+`1`VHk%0@2Jrup&5}9i%gFIwz`mdL028+O3nDG0hlp-@_c1 z)n=lTftV(;GKARM*U=djE(CY1lQ6^~ynrj2Xc}m2?O%qZEyvOr-_2fTjx5Q%zB-Ha z+Cg$SjmiD-Q_pAp)~sroa-Iy^II}gRxl{kJ_p?trV{hBVX&iOqPn8+KLY-56<);?J z8__DyWFYz|()(Jh{_9ta&zkR9En=d7udJ=exBoh?%y-r~**t6BiTL64k?+++BTK@H zn}Gh;vrI8AuOp|&>oMU3{P4fUCcC`%+ctB!&eN%{y^u>zW0q>6xu|e+s^=B5 zHTSWwKeV57~Xk)MehM+tm!% z$t}s*f2DKtc!RTlMHxg;AR`z3CTNLmhvFhRK*QGdXbrJXE7CjB@7OMi3s$`U{2DIV z5;bXyD_hG_%Xn(xp5zis>34ozB+ydYP#AId^dK|wr|`!@q4&S4idPdQm1!G>8sr14 zFJ8Oq0=be3W^b)bG||!&5zPrQy$x?H(Zz&*;d9{a&f_chD^FQg7mF{E~6n-s@ zQFw@F#^@$(Fi%epQGifg;5dgWq6A_|@5Xf?eUUT0UBNd`29FnFKf@2Sj*IQSN9PNK zu57IHRgZyjXE{zQlDMngs$pio`BI!C=;2f-$C@zH|9*w|*yoW;MM$~Hmg(ufkH*() zV9LyTbz`<#=WHKeB|Nk=-xBZrPi@FcoOg62>=xa!zfN3-DeyF74?d0aM@>J6mbK1* z9`i!--@9)``dg01xwvU%77D3+&N`$1?x$Avj&$^Lov>MM$f{`nJdtH=DMHgl5^p&c z^K6Svx2|$IOD&KCGY}JFzPEzMIL<+@-@Zx+Rz3TSetdoSl+o_l?CzlamWFLrC@C-} zvFF1Uqk$D{t#Z~YXc|7PqJEodIL|$ZkbBH+#M#F^^U+LmWuH8RQeyLH%VA3h`BRvs=A2c*MIZ6 z0@*6OB5Vc@ZfN@YT>57b!YrD|gu7$%SZD2IHwL>zO~!(3s*~blnq*IxMYab2evo)k z35HhJwHPh|jW>;?Cz5u!)Y26Irp*5K4q+sMabBar)>p}_c6vxh zL>;%YZ}wZj$Zy=@6{2g;d!3wO!_;~e{<&_-mU!K(?t>i>%&ssrhWE%~oFmAq|6Gi$ zPAh{ZN;k;nSkNL;TF&_4JyErPtEM0;8&kN=ahqb>rorKF_68G zo-gjWq&HT$-^uHAN?An*_Qn8l-FmW{E&Z;+)^5V(VtbQqG`^Sq^Y@`^{hO3I>&l%9 zqVu(GggKldb}_BUS3YAyN0C(-P6dNrwLAX}z&O&~KCZweaTepmMy0WkJhP z_nMf2!;c#jK&`7;oaBo&Z*#w&0OEXA{$0V*y6L zX|gTubmuD+FjLEZLr}`sP79Q)fs-ctlj1?BnW*$GO=sqG^uS1PYyhrpocBF54*y9x zJ=;A{xGGPT%PoPLK3o*58BzQtUaf21#tg}{?&U5zL%1j=y`8B=vyk_nIDx5y;pT)x zIaS|vR;2iBW&$!*scmDgVJN?r@#qEtYdQr6DX2kL;x2_UAyp zfAxd*UnL$fd8_^&!4=c??3ALZDw+0sXkwVA`2ge3X^LC-5#nE0Cf~PEX}33w@L4i4 znw@aC(j5unL66L$Yf{>JR8nR8k=-McAfFB>UqS|6Um?qB$e6hKP;4Z8^f|oR<0e3G zK3kTHDM2zg?h4HKmHE(CSm2m_g}5#byRy9Eu}+Da{5~5bt>P&Z6KhT(A?IO)5R_9Z z&rc`78sSH;)V{tSUj=p1`{Rn~ZEM7UDF!(-8DK4O4@Lwg3`=yo9fa2t8(Zt+G<|*s! zoj>i&z=qRf|4+UBWnPubYtXCm8@}o!OOy(~+I9XdUfWj9)MLK$4?xFGZcuZEW~cpe zqXY27?HjqsL})SjQGGxsPRv{Ku5qg-zMkWhNX4_gVQl+a!e|gR(Yz2JW1V}w0kwn+ zg1gAG(b>#WLEYtO^VI)-ZpcjYHm{hMax(6Ckvn+ec zP>|WU|Hp_n#Ud^RbV%fi1AjbG{1Qk;H6-!cSGr%D#8kp6*bYPb{=Ba?I-%rv>Xw1v z9z)+o)&d`yVHUJjvd2NFT=v_l(W(`4aJs%e_WYO@wy^5N9{?-{N{RW#0ey=>JP9CW z)>&iaL=AjSI@8=eNS3-%RO?%Du{2<;M^M!1Xy&x_y__9Ku$t@PoeW^dtlvU7?jFL`2i8q03x0Ra<^Oq57hAOZ`vnTrgPsCiZn=JPXhyA*MZcE{v5?1 zKKNVl_mG!RT+9sR32L?!@*^(!sOF@JH<{NulQi6229L|;Ltq%v)HIe+(B~-|t|)e8 z@AYkJhpk>}Lf98`{?W}?j< zN%gMN+*DAD?n6w~`K4}9&=IXTq~CRy!EQLZPRhdf0A?zjrOt9w?@$+`nq(7mGV@yj zc`yj8I!@1bsO8o92<$7=kw^4ADD^@oJ`SL)AKb1va6YGNlix4)Kjq1I8bHx1vxyz> z-0B*VKM7&iyYz~tIf%pIe)KJ4^S~%NBpxL-wqIbuB7ss zvW{nXNcb=zqoP?@iKk4m7zY-Dliy9HpT-TuMyQxNaRrjFI`xHMuvh= zRUrhMGDIB#OOZr@Ju1+lbvZF;MO>X$?E8q~5p$`naHQGVBbqR;9iQx9r<$zs_Z(%d zIeDq;Xe)u?(T2&M^}2q+l8Ux~i1Cb96NEKr8mLx@St{Wbx|7RLoVlmc+^-Ocgrv?;hNKF^cnn>O3UeU-qXt zvIeEv?a7^+h4h+tUxMz}?5q?a`%Q(r-4)IM7OKX#+m^E&aVocZK&~JlVFX|Us!Ms` z?3(dr^^|jacc?G}xy$#S?V&1n3H5gajG*BP7;BE5C8LAy7(d_}g2oEBGFsyNVkjj0 zcchm&YPcq2RM>ae*6HpdHt{a!^C%s8o5cK&TfbjNqC?p{?fNaQ6eUE*x{gi`by_-% z@i#Sx4HQgxuq{}Fc!@la9RxS06X8fRSHNjhr|SIV<<~vS$6fortS+d_au|}{nb@zI zezu>?DQZ;r2`uQ2Kl97amty9BSmJgf)gA!zSzp0RnE6o6vHSa!H>4k$>LP4J^?r1C ztRBuX#Dv>Tbwg`pWQGd0O4Nc}qyTY!(Ba`H;L|j7m@nC`@)c4%oO*dVi}= z&GPOSZKMXcGN*XsWZOf3meP@A{mHKUX7+0+hk3zGeAYZV+46qB7I7~*h4nsQs{lY1 zGPExHQJ;It7_=RQq;9M|92=gMQR|X2ev1@X=Z*1+$3yrs#kCy!jbXzl!|J`!wWsDE z^dBa&Ud#R?JRX}r!Y22sGv zonF%`HPzg8;5$mS?Vc~M%$f6k?!3y%$eC%f9rPpS~qs?p`)Zlgyf zRd>$l)EPxB^*#E8D}O4X>EyV^4B=mCyOMD)L$@gct2hOo$|rE;iEH4MJ)7)GAUdt( zlD`b?_VPuKjWAC@XMX@ee0t0AyNAj7&b6|ZF~erLy)cp$dXs4__Qa&hAim@FnI50* z;ZLB6;idh3U$JQ7C?u{09gK;OX3Cm_JP2M9|wEnkV z#o1xww~*LsFiz{+fToo1>6kv&S%_abhxT4I`zxhZ--X|S!zW!o+UL|AMCphGFIabe zFDRxt3G6oKfOTdl7-{2A=IM^0DEc-3E#8TFZ^o7rd6s{RUV7vX9d6rk>HQ)J2HcO$ zGPS$5X!SbBre`|{Gdv%eZa|C+V|bGcuL17@8LhGqjFz+{brkcZm;O!|;vf>~-nx4^QFX z6-7Ep;mD?`^`SXSrQs^7;&Jl8x7B7q+*SVJsOTi4(G6t|^Uu)yV~%`mTtQuFJXjvz zT(`4~yz7j+Mc(D>ecZBP81c#+mkIQAxpS6=uE!LAyBJi^eE~!w#Al!90AQfQBxF8< zX_|gz+D(0E_*Fm!u*Ab%P7yvLQZAB24Tg;$oE`D|CzD00onIxq2$k|H90aFO8v=3_ zat^UPwn8E?!Z%fxN^POGXf6j1C2AFrtHWj4G$+y53JP5@NkrEvg3w+_5|E)Bje1Se zzOtc-xVCCxZZ?LoX$6~remreN%4Y>4{r>=@tJCc}V%`h@k{K1q_ZXY7AP7rXe@3dO z$d|BMK$sYc^mw5{C$IFjI%@xr3>f@pB61p6v73qpHx_T?@NMCT+8_2oamgsPVPkS{ zfQ4=*zy|5&8ieEnK!dc2A$Ed9heQfL&(F7p8!GrV1I=fkfghSPwTX)9VM#2Wp9&Gm ztN+B4jW_cOb*B>kUFN_r;Fo;NjMfROLb70j4buu6HlMI1F=%Lj6|t zi3I{x1H>JW5bJ?If^Lf59Yw|RAKPjAqLAPzic*}i1HD0A?z{JN98U^7lsk9g^dZkI%g?~|02CZv`a3a4>BJ8D9t#L6id_D;9&iCE zV{6N;7o?Q*BpR9M19h4woppe})nh0xWIhz$ii;gD{yDE`ut1GSPd5n-#{7*(y>^LA z@~~7qne`9r6fG=)8MYCw32|Y(zw&QD6`vP^TA9$v!DOX~)1$ej?-x3LXnCUF1J4U4 zw=9=qkCoFzt?@-lk3o%$;XeHsngIGYud90l$GI9$#7r6}ZvIu*4AYUS+@`qM5vyz8 z;f6@Dno4>S3sS%&zn6Tor*w2oV%zq;eYXV!HgScZM?)NMRHma|rMWgigQZi&Fk=VX*tec7om&QVSu zDC(fV`GJDe_YTZN7D$I9M45C-WhW>T@?|%`Uc3UB4?dZ}Zcn# ziN76F{&mSeapROy<13>3@4^W(BTJSJSl36PNfqxr*^`^}hu6kPquhB8{d1s$#5%m7 zR1W|s7J)P@*<-a7R>fXy$hsfZGykO0qJFQ1RgEUz zHCE7$$*z-HQ`EGSOt4NorZRwLsL+`sU0#L+FEDwbCzuF*shDfpRaK~anChSb z_M>Vsk8+tvG!c}qem1_l8RW;khSX_pX*2C23vo`5rR$sKQe_#|upwX*=9vu#o6l|y zx^ftx+u3e56mKPb(Sb23ztp6}sJcUy$n0clc@y{C`-nYGN|{9NEf-4V_DepGkj+;B zp6Go0uPnAS#~0*z+%rPMu=4}KS(4cG99r0d0#P|e5|2G3SG$cn!Wt&y6= zW59=T2{wfML)0&?V~f!{knwO7x%hRYA>zdQx#eg`)VMWm0B1dp7G7L%%l~BHq78%v z!bX1cSIe0oK?^%>xV9mzKr&*Q`YG!E!US96W5 zUdFK1>}`SETp|)e>mkbCS}Tj=6uz|7KT4nLw$OGw{PIB9F9lc2GV~{EiSPjksstqv zV)Q@Ps97TG5RuDh8Hy`HFA<`qQvDQV0ay4W^R2LPQ0t)VF)uxC~|-JsfJWS{fwWGTlM4t|!s9D0Fe2dsMD{2+1B1;PXd z3Vx%=gJpa0G2+Omx>`h1rA=s3#80}?Af~EBk3*t><+0@y8H6?q$UD$%9Yph}^*sGT z+MzWF`~{xuspn8jL%CoF2*^%^nG8J07<(|FVCJzdyul1sRg2xu3^rO8Y-T2z(58U( zIanVI}6k$wjvg_7&{bz0<6XQ4fN!#yjLU&oiIN{uT!jdUuE)Xm1 z5DO}D8A4f^~$WA-R5R!FEUfGb`CM$19nSY2h;dqT+RE08Es zMGS`u zmTv1Wr(?^PJyr(3n#_Fh2PIpvsegV5Ri%kOm>|tC<#^k(k_QITDfXF`#U8J8_fFqY z*h{;xLL%Iq>4iJ3ckyzpH%(Mib=b8u*?<3YeF(cDU)>pc%(3iKv=6qq%!nz2s$+gr z7n=W1h<2|TL55gd%3|FB2yFx12Z%XpgJ}csbmLaSe)1n!;e#OBKIe-#wWm4QmY{OK z1q8T$>&`x(4x!=_ zeK@0&%<4P$;l%zvjvy+0J0QgGl}nA@ioSJBbaCZ;($)*hqvCXDp)cdo(2rg_RRppq z2GlI~e-?+ibCiC+^hC}4k)eF5bu<0c1?Ny9ID>+2EEIJy@UKIcx2Ab#yL#`98f&J zlKolvFYAZi$)(CPLHo*o%Uma<;>0kXsUB?vL5%(ZsD)$>SVk&Tw%wItYKWvI;nO>m zd5%Pdn{jrlRVUrPScPH_Bm2B|=H=FHgn~FaHTw7IoIZ+=o$O$85^gUk(pu*-{nO3xPO#Zo$G?1~6gqVE`TgZR%+#&stc zY>#r2Nc(4!b_1)aeYer5#a=irdv&k%U!E{G48iEu?HubbvA_^*g?gTjLey~azdsE1zPos4bJ;H2^ZT5l`W-U-JO63}y2i^%^%(+T zEQ{{P66B6?xW{zd7v$@60s77uFtU=6uUh7XRN)G5f|WgtLK~izM~g01n2@Xv)pT}z ze?naYI$U-x7b?Pi@W3>A+24n4(?O%h?dsXEeXf`5PyW?D$iL7f?T93ZM%>{sP<0qGkd?9(F^(f&Ebf^wOqo~U76(TE4YpU(F3xzh4?|_as!7mQNZos8+X#qQy{-z zrI<-99u>iBt-MNW>oG#LkZZ-G{E<|2cWY)` zp=l8GzJF}uXd5ZJLA2)igg?SSKv1*;%~{a-Ba($L}xc7O-YsrWyH75adY> zGCCl+W1>RF`a1BX3;>0ipuzbVtmCz0iFeSpz9PH=7t8fO;RD)P82Np-i~a(A0(+Lq zyGgb0Ro{Ef93EOFRg4gv6&GWKii$gK{U~}GL)(U$9sqJ##_LzO*NVVN`=e_mld&$3%(r3u8 z|K|9?i=#TQF*>si*+9ndGp}8Z!?otRl-KSqhW~yX0V{%~T}AL13I=b@`$&EtCVG)1 zzCf-|{;qha&556%*1l<|jB%?MfLta>k^T~XJdLVfv(a7U^Z5u)annH1{v=`mj16g> zDHWYw_0@D4HHg*)c>Anvy1)sX1DG7}A&S>~_Bci-vy}hYhso$!mJB-K9Cie$WwiRg z&bqRz=)XDnJZx9D1PYjbg8~%G-ZjJ@jxi75HS;kgw505d!|ho=R7=_CyMRbU*=i0O z*$d~G%@PyUXGKx{3cV>$xAXi(`W4TTWaw`_jBL#J`$HI+EWYV&F-hY~gt@^;! zTJAfyO!ej=mXDd?)}WyGP{3$U+#NU3!pCRkd}Yqxw5Wc6W?e`g))m+n8bm-MHW#dQyCf zuLrT&>rgZQzd_Akh_e&TVxlcuC@bo!3eG|@+!3xa>aF=e>;yO7j>ysKIcd^zL^eMC z)zJ}Gjg*g9GEwlx_fPs==4}Msv7aj)2JfE~9OT7D)lG`&pBGaPDOR7%Sb8jQ>>8(kqFpMjv?O@sPOSg*(J$^`(U;uk$X?A?yc5-SP3IILjXu}AXKs!G z0U4@Vq{B?iRW@8+tnC#7L8$>zVo?9JmsVlSzv-_`M*u=59A+*MkaL%ja1sO+93@0N z>C$H)Oe^erXsccD1=OVM?_=23y{>&)-E`L{DjOL+bbZYUifMV*94Y^HqMgLPMo7mZwX z(RY62?wq%A;C8ty{wbmKH_u;u7_m*hR)R?km&=y1c95BRBH@c(rLOEhjjHlK`iym| zoG(oIpZxpRMDOE6Jonv`B5y-9_oR66c@sggq(OFY!dI-8oAXr(7ND}Q^8TVT>UYCG zlWMre_w!aOWoL7XZ>ec>pg|@dMXGWJJs7K|Bi;8hP;z9c{5_nBNcw(mg(Pb51$umS z){t!m)ePp&hw?|)y&(#cpBb4LZjfRO+;fKQkf<`*0tKeN=AGwb0*$SVv zH)dtaF7zM;4XTGW;uOc_G&(O#5QJdngk>!syKxt@MG2cphofENm;V452$ve{0xH{S{m=WKL;#wq3(kp+L0$jM~vU zhy-F*=y_d%uI^PJ{!F|MqF`_PhoaN)?IGb$dCt6pn00k4j)x^FlrXfOW z&|f0hDsb}^ecaN9t5YI;6g}D2c4ZLN>W)+EEMq*Qo#FVr-r8PmU7mnmH z@t~1&!IgTMs0B(VS%|bB6hWLisO3SCh3|=X{e8pAeZI7E74jqS4)RwVE&qK?9roWh zVC-9_J$Xk!d~YhPmhKb?dMi*pG&6(bo;}|8?!4hD65vn#E0HJM;0JFa7*|mHeR37s zm2Z`bj-u{QzB>QwBckXp&SzoC5sI3+W|cwG5%gIvYFx^l#Zp|GF>0{rH9c=>12VTD zs4Z#{bRp>Vcx2%eco3>22t{H~myWuzKm!!-yU8ha9pRvIXk(jAXOH(k7EoPuy3?y= zmqO=+hm{Hq4bCxc`#a2#WF<-LygCkgawQ)RGCG34C(CJeDacB_$+{=PJtE^lJ0)L{ zDG)H+uIJe3(E1&g4S#^*Czt&B*4(S(#J&cFP>*pZ5hI;&gp$+PFfMW4Xo7P;P+bjp zA+UWV`v#KCnUNI8ufsmJ`4IDGQCBFX4DuPj^mS$1FIQkJXE5JMMrO+>gdCzuwB^4Un@m`Y<)97)MXrN%R$sH+jpU zm}Xu+I<8>wI3E-RgMPUD{o&Vg$CmZ+5~5i!Mctkl)GT`yCDu`gbEQgNSkmK(q)6Ib ztF*Is{xsw_0}YZ>rw#x~B>zr_*Go9J%^5=vb2zh$Q-3%*ye@Dg7g+Ef<8{FKS`&T8 zEUWI}P}xV%tx3Or39IQ2J1e!KMRnG0>TOEvLBU1l#&%%XKH$n+tj{WJCYFJKMn318Vr zvGMsmyTH9LYxu6Y#^F#R%~9lwuP_HM9nAq}OY}GMi)Q<0-Hf9$`C<+ZMVHLsD9&jR z9J4X>kr<{(BQk})SaMhCx&E<7m?g(peDJ<)Nh$p(7+;AsR`%<+ue;sporM1y+FvFC zK#yW?fucjKcU-5A)K@-{z08y`CLHCBNkh5zO*5V7cJjc{hp%(dV@7at0hx~oklyjKOli}PAZDMF!>m6Z^l2km%6sL z4wB<4b+Nzst2)17fb_)-ww zK*b1ZzcXMNq{L$Q@M$HA*OX@0>3Y?>=8x~y(q+enEW$AHPb}QBW}TLGHB_RuZFC(& zx{^F8$M4SH0FYWWzWMz3I74MEe&O%H@C?3j)lYi32!jW}O&||dM;8v+Bydsmd=CwJ zxZznY;$Y|{Ql|6Xl+&FkD=IA{7enau@FYpix>roqd;HIv@%x9JI>(OFLCt2dHC~n^ z!~TySm=#x+kI}6+k-!SLr)Q+hX?MkWuHI=*;~&wd7VQs{4!lW8gmPJb5y425oRuV9 zjjiwQl(JLqa}qnvptPr?8PJF;4+Rt#YVr!-;(029MehA^+T{I)qs>*`-7=SJO~aNd zms+8>?l}F6Yb+?nPa{(761@EjiuRxj`iAJ8J`-i!%yz&Af#yI{&9Y=(YtwN#C@1-R z#j?5nsRch=SKClc#fX~618Zi6Z(_!>OuONe4u_7pMd3%sKs7Z786Cxrnv4n*f7Inj z^V@crd^8wBU#xx%{4KfI7mzL=KmC{OVcfb0>Wi<>_-FBvb}v{@uYH2l|vd*jU=jW0WSSz$%igk_agMSJ7Nu9(AD{mHq!%HDKzjM~4+ooTq4 zyp85-KiP4Xa2V6=`?aNJq2GAn1=5E!d7mE6>99@lPSsLT;&sv9LTV72fnkj>I3wuG z?{~WouOD82(Az7deU`@Leg}QHef<{0QUFUhx`jp>lziph11rv9(JQ;LJ-*I!P6L$I z7BCj;Vt{)~a8$@P+}8SB4jEgvnb&;*-Upyn_J%5^nr1HMgW8kv z$3O2uU2P^`mp;=98CcydbD80aku0eVrzsIBvUFVpK?oq}hq7S$QR@-JVeiGncb|sP zXS_BD4A|uiaCsRYxlL=RQ(^W-0rdchdRkYEMs(M=sjb3bW&l9ZfWF@O&!z6O3f*zr zKhB?*CnIZO#^2sc;xG?vRN1o?+2oe;xDqIat=`5w288_@JYjlcHXGmjZ8CmIVjp0nCdnd0VvGGd$dr{|SW~lhwUr4A>T5h<8t;6chj34OY>QA|C{X zn@DFWYwSQY(o5~-4^ZSMBB<8F0^$5o()C*7&0YhrXEmE-TxOhjm3 ziRcR$Sa$__TbcaC+EWI1@^rAan?bV2T?tKQHg@J-sQ#4BN0neA}>9+CbL<&?ohzrmq$;kMKPr|kPE+4z)g#?2eS2fTj zqxlUX_3ao~EDnJQ>jsF>{CkmO25R{4q7~;&+#{su6~hZkKt}5~|7#Gd0&|lHh|%H{ zE&a;M=_D3|giiS!14X7*u6-M_OK}lXxm$thZ&1($#6c zWpQ&>k4k?1C~>hCE`hVrfH+ZufJ;m)PWcwmEge0TR>GMOC5|cnh0v*3zL+9BNyxs% zPvabbHu8+frt(@)WM4T;7GRdq!XjP*Qb0&pB}2D>KEr2?7#HJ$vf`V0Ee6N5vcexa zem&C+D*=2y-sH}82-h6ZEk|v8852-c@JwV3xE>Vo6}<+DZ3Fk@M=88;9R@?e&Ns9T zkUa!t*(kCW{3q1I_o+1HpZWJ8bFr3arh33G9@t0*G-Fb~Sb^g%b`NF|L zQ};F|nxV+Ag3=PHQMe(qmp^}0ospW{Vv++ zKk>a*&;5I$F_og5PZ&HCU5jX2+Q^SyLyOArn*$N@lM^~2;sYJy< z`NEG-5!H^vWwYZdfMFpiH|zy^*9@H)uj%CLC?s6s9kG|td_L^dz>g>}wg;DhjrefB zo~TfyC?G5x0aw!E1zcRHXIs)z+S{KDEVw^L6N=vT{Dh(=thGpBNMcaFyG4F!2-{^x zr0l>o05<9n*$aVjJn}BrP~soNFlR+w6jBm%022dFNt2`xnAKi>`t)YBi~mb6Hxw!b z^k5W#q6F$5Nno)Ujj2^P-=RGMDFO(4(L)P{PJCi0rCoBJZnY006g)^#PKEo*3_C_0 z?r??=uUF-gi1-iKh%5)fLXi^jol`szI1%BL#Tu6g(t6DQIYSy$(*MbGrvb?S#kC>f zzPcrb{eYlGAerKBelY-kv42FcO?g8E^g`KD?P6(Rf*x>=oKk#TP$(Ms(G&7FJJKYP z8S;;S&I2$&eOPPh?n7k;PG%@^EI}e%=P(HDF{wr)KsBGgPWtDb6Qi=ge&7`CaK2?iRCukeeQMGHhzBPJUB$a%P_PEBp1g1;P>E&s6T&~TFA}lp=j=)hc2!s z`p}IFbNPV{!lo~yi9tao6_bn}8b31`%oJ6;rLYYXRfa;`+D$lFnErWincgB%60*QZ zi|}jSfU`(nE(D3HGzZ6*)!i|j^|kqPGs4S}5=ot>KajUgd=H4&t3jBroPG<%20M{r z-iT1k@hi~~Ssu|8MZNU@4iju-HXF$%8(*9X=rf+t^rNNoF#XL`qBKVp_ogBSTBn(9 z6TuB0ItLsH;(fTVQ_F-sQ`N(XS^(M0p8kLD*^ig6b7b0%iw6VqNov3Cn21!!l1HYh z`13V3#cM8SnZ&gEzh1{nAPIoG$7H0^C{bguQNYNFH9}S4{oNc5}0ydgspG9meWjJGT{9q zfJl_ogCzxE@=~863HwjWk3d%WubY@|+3jrk7HYKM7lO+4w(N*-V12wWRAkZSSu_6* z9rWGLJHNU*oW7)OBtSoj=4z^&p~4_=&eR$`?c)w>zzFKVXbSGEqqvH-0f&R7cMZk( z;w&`;JEa%zSHT4GZVObwW#V%*$?^SCKdGQb`E=^c^IpT_EY2{H(`V^z1`s%epVFVV z$=@iWfY8D7c9Wc-yNsf;doAfQ5O)VLZ+71uJ5{|m2)B4Y!^LD?LQP#nqZrhbHgo$|U={KA<5C9>{^kezP}qnSB!4AoTx@oM0PY;d>ENGkt%o#x)$S1gdPtCckn z&K6XH4a#TclQ4i6$d3S77Kd^niYjN@!s5crH`mxJd~QbDgN*az1Ll1~3SWp|lhBS7Pg6{keNi-Y5+_t+c-=EiXS z0;Gapb2tSyvoiw-m6(u64EKK*!Uw_Q>V>yEcRs8V3I74eRk&Ef5aF;*>WLIG_#wD! z(=Ml)tnRsM*hp};;KN``3Zo*39uhNP&G)nbAAbG@O~;hfg^Qj1w79W`Y#s*Yh~f)l z73c0D$mZY!6HbY1;SBi%iI9fQJrQzR!4q7Unwy7vF^V7Zzb12@P%wfr($!QJz^6k1 OfP##wbd{uO$o~T@FIcJo literal 0 HcmV?d00001 diff --git a/include/images/pgAdmin3-32.png b/include/images/pgAdmin3-32.png new file mode 100644 index 0000000000000000000000000000000000000000..ba759903e0a1cc9d518403f6dba02f376af48723 GIT binary patch literal 1906 zcmV-&2aWiNP)i_@%8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H12JcBkK~z|UwU>KvRA(8+f9E@A&+gfKlFglj1k!{+3SqdXkRptd zlF~vQJGAPQLLDsQXlEQ{EOt6oN9+}Ks)bI+OGlxWNWsQZm4XN@gWL@l36c^@0!c`h zWRuPAo|}JIwwq)(ZKw8`Ie(nj?{_5Iwi$s!U=A=97y#Z&xjF$GP=N-Z zDjL(PWmyV49m;tiuYWLBFNB!jP(;22B9<`P9kMv4xzwY;D?nFjGAYG?7T1l9v4pwm zcFlyXkpvllK_+#WKmHZVoF*5K;yh>%OS*Or>blKj8p^4P+UK==h%h9r~a_t zHx$=Lt_lDv7u9nA;#zzCmN%qxm%G!(RF>qje&s?gcJ}gM>^N|GRD40UkFPJAOVj=qY;3N+ zA7Oe$QIelfm_sz4Xm_a!0ytBapY0l@k^;vLKua?n(BFjXgaRB81g6(>zsEo}bZxLl)@9 z@Qu>jA0^wTk+Q{;INRPuSwR-L0S^Fi-9&ZB0MwKhAcWKbv?UD$Jg)7xPn(#r!zi*q zH%1qmlrB49m=?PapJ(~}DFB2cQL=q*0G7_4l+aY=g`2TAx8Lsisb%TQIYT19+sRNu zCsS*9?ciya&!2)U1mVaKL9d3}rP46BO4po@-;XqK$>mV`OLBv0#rg(f1ii!SbpEa7 zw6tBz@m3tP{;8Yb%%i@70GYr!(w*oyQ4IqTrd0Wl+v>ma%JIu6+MZ=yo z&YeW_p>r7x06f3*9ac5Wpt>}V{=qo+E}S})<#Vr3jY%5NoQ_>fW>@y56MFIW!+c|T zU9z19JT5AVL%egQJzaPbo!9&M%aK+Z=T4#|KMSW19$699oXQ485t|%}IAU0~cg@pHl;j3kGOKb- z18bJfV%^VPW5r{?^?mu?RU>^-ne=VAepAMDd2UT&<%6@mgd9aa#xsX z6@{!?G9&76C~ptM5(@#xNF9K@pclimdh2US*Qlzh0xdwROI4D^lXeVed$mV^9|2CF z13*af-S;h;zS6R+0D|6Jzh^U0l^66*28z?^6lVL-ExS!s)m>?qD3gH?a6R=#mTAuM zYt18KioKd@WD+RM@#A#JV>XL1PeLC95wGUVcup(L%eoQtxJDls{*ML*QjgsuF`+1H z02s4deQE=m(~(i5tRUM2E`62;BAE=%`i@y0iYzt* z@v#J?G=ImR6kq%IPx# literal 0 HcmV?d00001 diff --git a/include/images/pgAdmin3-32.pngc b/include/images/pgAdmin3-32.pngc new file mode 100644 index 0000000..5ac09cc --- /dev/null +++ b/include/images/pgAdmin3-32.pngc @@ -0,0 +1,283 @@ +#ifndef PGADMIN3_32_PNG_H +#define PGADMIN3_32_PNG_H + +static const unsigned char pgAdmin3_32_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x08, 0x06, 0x00, 0x00, 0x00, 0x73, 0x7a, 0x7a, +0xf4, 0x00, 0x00, 0x00, 0x04, 0x73, 0x42, 0x49, +0x54, 0x08, 0x08, 0x08, 0x08, 0x7c, 0x08, 0x64, +0x88, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0xd7, 0x00, 0x00, 0x00, +0xd7, 0x01, 0x2b, 0x27, 0x69, 0xeb, 0x00, 0x00, +0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, +0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x00, 0x77, +0x77, 0x77, 0x2e, 0x69, 0x6e, 0x6b, 0x73, 0x63, +0x61, 0x70, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x9b, +0xee, 0x3c, 0x1a, 0x00, 0x00, 0x06, 0xef, 0x49, +0x44, 0x41, 0x54, 0x58, 0x85, 0xb5, 0x97, 0x7b, +0x70, 0x54, 0x67, 0x19, 0xc6, 0x7f, 0xe7, 0x3b, +0x67, 0xcf, 0xee, 0xd9, 0x7b, 0x92, 0xcd, 0x9d, +0x84, 0x04, 0xd2, 0x84, 0x40, 0x0a, 0x61, 0xb8, +0xa7, 0x90, 0x22, 0x8c, 0x92, 0x92, 0xd2, 0x42, +0x1d, 0x3b, 0xb4, 0xea, 0x94, 0x42, 0x1d, 0x2c, +0xe3, 0x68, 0x67, 0x1c, 0x65, 0x2c, 0x76, 0x3a, +0x55, 0x47, 0xec, 0x15, 0x75, 0xaa, 0x85, 0x4e, +0xc7, 0x4b, 0x47, 0xa1, 0x96, 0x48, 0xc1, 0xc6, +0x52, 0x95, 0x82, 0x08, 0x2d, 0x83, 0xdc, 0x0d, +0x17, 0x09, 0x92, 0x12, 0x4a, 0x02, 0x49, 0x48, +0x97, 0x64, 0x93, 0xcd, 0xee, 0x9e, 0x9b, 0x7f, +0x58, 0xb6, 0x9b, 0x64, 0x37, 0x6d, 0xa7, 0xf6, +0x99, 0x39, 0x7f, 0x9c, 0xf3, 0xbc, 0xe7, 0x79, +0x9f, 0xf9, 0xce, 0xfb, 0xbd, 0xef, 0x77, 0x24, +0xdb, 0xb6, 0x19, 0x81, 0x42, 0x60, 0x0e, 0x30, +0x15, 0x18, 0x00, 0xde, 0x4b, 0xb9, 0x3a, 0x01, +0x1b, 0x50, 0x81, 0x06, 0xa0, 0x2a, 0x1a, 0xd3, +0xab, 0x65, 0x59, 0x0a, 0x3b, 0x1d, 0xca, 0x79, +0x20, 0xaf, 0x7f, 0x30, 0x56, 0x2f, 0x84, 0x98, +0xe0, 0x50, 0x44, 0xbe, 0x04, 0x22, 0x96, 0x30, +0xda, 0x1d, 0xb2, 0x38, 0xa6, 0xb9, 0xd4, 0xa3, +0xc0, 0x2b, 0x40, 0x57, 0x6a, 0x32, 0x29, 0xc5, +0x80, 0x16, 0xd7, 0x8d, 0x8d, 0xb1, 0x84, 0xb9, +0xea, 0x78, 0xeb, 0x95, 0x44, 0xcb, 0xa5, 0x6b, +0x7e, 0xbf, 0xe6, 0x34, 0x4a, 0x72, 0x03, 0xb1, +0xa2, 0x50, 0xc0, 0xca, 0xcb, 0xf2, 0x38, 0x3c, +0x9a, 0x53, 0x97, 0x85, 0xf4, 0x96, 0xae, 0x9b, +0xf5, 0xe7, 0x2e, 0xf7, 0xb8, 0x4e, 0xfe, 0xa7, +0xd3, 0xdb, 0xde, 0x15, 0x56, 0x3d, 0x2e, 0x95, +0xb2, 0x82, 0xac, 0xf8, 0xbc, 0x29, 0xe3, 0x15, +0x59, 0x08, 0xf9, 0x8f, 0xff, 0x68, 0x61, 0xdb, +0xde, 0x93, 0x00, 0x94, 0x17, 0x64, 0x51, 0x51, +0x1c, 0x62, 0x4a, 0x59, 0xfe, 0x40, 0xe3, 0xbc, +0x6a, 0xcb, 0x21, 0xc4, 0x66, 0xa7, 0xaa, 0x6c, +0x00, 0x8c, 0x54, 0x03, 0xca, 0x50, 0x5c, 0x3f, +0xb3, 0xe7, 0xd8, 0x85, 0xc2, 0xa7, 0xfe, 0xb0, +0xdf, 0x37, 0x14, 0xd7, 0x47, 0xae, 0x0a, 0x00, +0x2b, 0x17, 0xd5, 0x72, 0xff, 0xe2, 0x5a, 0x7b, +0xfd, 0x96, 0x37, 0xa4, 0x73, 0x97, 0xbb, 0xd3, +0xc6, 0x54, 0x96, 0xe4, 0xb2, 0x7e, 0xe5, 0x42, +0x2e, 0x76, 0xf6, 0xf2, 0x93, 0x6d, 0xfb, 0xb0, +0xac, 0x0f, 0x57, 0xd8, 0xef, 0x76, 0xf2, 0xd8, +0x57, 0x17, 0x0f, 0xce, 0xaa, 0x1e, 0x7f, 0xc8, +0xeb, 0x72, 0x34, 0x02, 0x09, 0x01, 0x60, 0x59, +0xac, 0x6d, 0x79, 0xf7, 0x5a, 0xc1, 0x13, 0x2f, +0xef, 0xc9, 0x98, 0xbc, 0x72, 0x5c, 0x88, 0xfb, +0x17, 0xd7, 0xf2, 0xd0, 0x33, 0x4d, 0x19, 0x93, +0x03, 0xb4, 0xbe, 0xd7, 0xc3, 0xc3, 0x9b, 0x76, +0xe0, 0x73, 0x3b, 0xd9, 0xb4, 0x6e, 0x19, 0x6e, +0xa7, 0x23, 0xc9, 0xf5, 0x47, 0xe3, 0x7c, 0xf7, +0xc5, 0x37, 0x3c, 0x7b, 0x8e, 0x9d, 0xaf, 0x8b, +0x44, 0xe3, 0xaf, 0x00, 0x08, 0x40, 0x8d, 0x1b, +0xc6, 0x0f, 0x9f, 0xdc, 0xf6, 0x77, 0x7f, 0x46, +0x55, 0x60, 0xed, 0xb2, 0xb9, 0xfc, 0x72, 0xd7, +0x21, 0xba, 0xc3, 0x03, 0x63, 0x85, 0x01, 0x90, +0x30, 0x4c, 0x1e, 0x7d, 0x69, 0x37, 0x17, 0x3b, +0x7b, 0x79, 0xfe, 0x9b, 0xcb, 0x11, 0x92, 0x94, +0xe4, 0x6c, 0x1b, 0x9e, 0x7d, 0xf5, 0x80, 0x5b, +0x75, 0xc8, 0x4b, 0x00, 0x49, 0x00, 0xc5, 0x7d, +0x03, 0x43, 0xb4, 0x77, 0x85, 0x33, 0x0a, 0x86, +0x02, 0x1e, 0x6e, 0x29, 0x0e, 0xf1, 0xd7, 0x23, +0xad, 0x1f, 0x99, 0x3c, 0x35, 0xd1, 0xcf, 0x77, +0xbc, 0x4d, 0xd7, 0x8d, 0x01, 0x56, 0x2c, 0xa8, +0x19, 0xc6, 0x0d, 0xc5, 0x75, 0x7a, 0xfa, 0x06, +0x75, 0xa0, 0x4a, 0x00, 0x85, 0xdd, 0x37, 0x06, +0xcd, 0xb1, 0xc4, 0x6a, 0x2b, 0x8a, 0x38, 0x7e, +0xa1, 0x03, 0x6b, 0xf4, 0x8e, 0xf9, 0x48, 0xfc, +0xb4, 0xe9, 0x20, 0xab, 0xef, 0x98, 0x89, 0xdf, +0xe3, 0x1a, 0xf6, 0x3c, 0x12, 0x4d, 0xd8, 0x40, +0x50, 0x00, 0x85, 0x5d, 0xef, 0xf7, 0x8b, 0xb1, +0x44, 0xa6, 0x57, 0x14, 0xf1, 0xaf, 0xb6, 0xab, +0x9f, 0x38, 0xb9, 0x10, 0x12, 0x91, 0xa1, 0x38, +0xfb, 0x4f, 0xb5, 0xd1, 0x38, 0x67, 0xd2, 0x30, +0xae, 0x34, 0x2f, 0xa0, 0x02, 0xe7, 0x15, 0xc0, +0x37, 0x18, 0xd3, 0x95, 0xb1, 0x84, 0xaa, 0x4b, +0xf3, 0x38, 0xd0, 0xf2, 0x2e, 0x8f, 0x7e, 0x79, +0x11, 0xd3, 0x6f, 0x29, 0xc2, 0x34, 0x6d, 0x8e, +0x5f, 0xb8, 0xc2, 0x73, 0xdb, 0x0f, 0x60, 0x98, +0x56, 0xda, 0x77, 0xee, 0xaa, 0x9b, 0xcc, 0xda, +0x65, 0x73, 0x90, 0x90, 0x70, 0xa9, 0x0a, 0x87, +0xce, 0xb6, 0x27, 0x39, 0xaf, 0xa6, 0x22, 0x0b, +0x61, 0x01, 0x61, 0x05, 0x68, 0xad, 0x2c, 0x09, +0xa5, 0x2f, 0xfd, 0x0f, 0x10, 0x0a, 0x7a, 0xf8, +0xc1, 0x83, 0x5f, 0x60, 0xdb, 0x5b, 0x27, 0xd9, +0x7f, 0xaa, 0x8d, 0x99, 0x95, 0xe3, 0x28, 0x2f, +0xca, 0xe2, 0xae, 0xba, 0xc9, 0xec, 0x38, 0x70, +0x7a, 0x54, 0x7c, 0x41, 0xb6, 0x8f, 0xaf, 0x2f, +0x9b, 0x4b, 0xd3, 0xfe, 0x16, 0x6c, 0x6c, 0xae, +0xbe, 0x1f, 0x61, 0x7a, 0x45, 0x51, 0x92, 0x9f, +0x50, 0x98, 0x43, 0x34, 0x9e, 0x68, 0x77, 0xa9, +0x0a, 0x02, 0x38, 0x53, 0x96, 0x9f, 0xed, 0x1a, +0xa5, 0x92, 0x02, 0xd3, 0xb2, 0x58, 0xf5, 0xe4, +0xab, 0xfc, 0xfa, 0xcd, 0xa3, 0x9c, 0x6e, 0xbb, +0x86, 0x2c, 0x24, 0x76, 0x1e, 0x3c, 0xcb, 0xed, +0xd3, 0x26, 0xa4, 0x8d, 0xbf, 0xb5, 0xbc, 0x80, +0xa3, 0xad, 0x57, 0xd8, 0xba, 0xf7, 0x04, 0x3b, +0x0e, 0x9e, 0x26, 0xc7, 0xef, 0xe6, 0x7a, 0xdf, +0x60, 0x92, 0xaf, 0x9f, 0x5a, 0x6e, 0x3a, 0x64, +0xf1, 0x27, 0xf8, 0xdf, 0x36, 0xec, 0x03, 0xe2, +0x41, 0xaf, 0x96, 0xd1, 0x80, 0x22, 0xcb, 0x44, +0xa2, 0x71, 0x00, 0xfa, 0xa2, 0x31, 0x9e, 0x6b, +0x3a, 0x40, 0x4b, 0xdb, 0x55, 0x8a, 0x43, 0x81, +0xb4, 0xf1, 0x5d, 0xe1, 0x01, 0x42, 0x01, 0x0f, +0xb1, 0x84, 0x41, 0xdf, 0x40, 0x8c, 0x1c, 0xbf, +0x9b, 0xde, 0xfe, 0x68, 0x92, 0xbf, 0x73, 0xde, +0xe4, 0x98, 0xcf, 0xed, 0x7a, 0xe9, 0xa6, 0x01, +0x74, 0xd3, 0x3c, 0x55, 0x53, 0x9e, 0x9f, 0xd1, +0x80, 0x43, 0x16, 0xe8, 0xc6, 0xf0, 0x8d, 0xd2, +0xdb, 0x1f, 0x25, 0xdb, 0xa7, 0x91, 0xb2, 0xc5, +0x93, 0x38, 0xdb, 0xde, 0x45, 0x59, 0x41, 0x16, +0xb9, 0x01, 0x0f, 0x00, 0x71, 0xdd, 0x44, 0x75, +0xc8, 0x00, 0xd4, 0x94, 0x17, 0x20, 0x84, 0xd4, +0x01, 0xb4, 0x25, 0x0d, 0x04, 0x3c, 0xae, 0xed, +0xb7, 0x4f, 0x9b, 0x98, 0xb1, 0xc3, 0x28, 0xb2, +0x40, 0x37, 0x46, 0x17, 0x9b, 0x94, 0x2e, 0x3b, +0x60, 0x98, 0x16, 0xbb, 0x0f, 0x9f, 0x67, 0xf9, +0xfc, 0x29, 0x00, 0x84, 0x23, 0x51, 0xb2, 0x7d, +0x6e, 0x00, 0x96, 0xce, 0x9e, 0x94, 0xd0, 0x54, +0xe5, 0x85, 0x9b, 0xb1, 0x37, 0xb7, 0xdf, 0xee, +0xfa, 0xa9, 0x65, 0xe9, 0xcb, 0x39, 0x43, 0x22, +0xbf, 0xdb, 0xc9, 0x50, 0x42, 0x27, 0x53, 0x6b, +0x78, 0xed, 0xe0, 0x69, 0x96, 0xcf, 0x9f, 0x82, +0x2c, 0x04, 0xe1, 0xc8, 0x10, 0x41, 0xaf, 0x86, +0xdb, 0xa5, 0xd2, 0x30, 0xb7, 0x4a, 0xd7, 0x9c, +0x8e, 0xdf, 0x8f, 0x34, 0x70, 0xc9, 0xe5, 0x50, +0xfa, 0x4b, 0x72, 0x83, 0x69, 0xc5, 0xfa, 0x06, +0x62, 0x04, 0xbd, 0xc3, 0xeb, 0x74, 0xfe, 0xad, +0xe5, 0xb4, 0xb4, 0x5d, 0xcb, 0xe4, 0x99, 0x2b, +0x3d, 0x7d, 0x9c, 0xba, 0x78, 0x95, 0x7b, 0x16, +0xd4, 0xe0, 0x54, 0x15, 0x4c, 0xcb, 0xe2, 0x81, +0x25, 0x33, 0x0c, 0xd3, 0x30, 0xb7, 0x02, 0x3d, +0x23, 0x0d, 0x20, 0x84, 0xd8, 0x79, 0x5b, 0xcd, +0xf8, 0xb4, 0x1d, 0xb1, 0xbd, 0x3b, 0xcc, 0xb4, +0x89, 0x45, 0xc3, 0x9e, 0x35, 0xce, 0x9d, 0x44, +0xf3, 0xa1, 0x73, 0x19, 0x0d, 0x00, 0x3c, 0xbf, +0xf3, 0x1d, 0x56, 0x35, 0xcc, 0xa0, 0xba, 0x34, +0x8f, 0xfe, 0xc1, 0x38, 0xf7, 0x2e, 0x9c, 0x3a, +0x94, 0xe5, 0x73, 0xaf, 0x4f, 0x8d, 0x49, 0x1a, +0xd0, 0x9c, 0x8e, 0x5d, 0x4b, 0x66, 0x57, 0xf6, +0xa5, 0x13, 0x7a, 0xf1, 0xf5, 0xc3, 0x7c, 0x63, +0x79, 0x5d, 0xb2, 0x9d, 0x06, 0x3c, 0x2e, 0x2a, +0x8a, 0x43, 0xbc, 0x73, 0xa6, 0x3d, 0x5d, 0x78, +0x12, 0x9d, 0xd7, 0xfb, 0xf9, 0xcb, 0x91, 0x56, +0x1a, 0xe7, 0x4e, 0xa2, 0x24, 0x3f, 0x10, 0x97, +0x6c, 0xfb, 0x49, 0x60, 0xd8, 0xd0, 0x49, 0x6d, +0xc1, 0xfb, 0x26, 0x14, 0x86, 0xac, 0xd2, 0xbc, +0xd1, 0x9f, 0xe1, 0xdc, 0xe5, 0x6e, 0xf6, 0x9d, +0xbc, 0x48, 0xd3, 0xe3, 0x5f, 0x31, 0x56, 0x7e, +0xae, 0x56, 0xbf, 0x67, 0x41, 0x0d, 0x27, 0x2e, +0x74, 0x60, 0x5a, 0x19, 0xcb, 0xe6, 0x43, 0xf3, +0xcd, 0x87, 0x19, 0x8a, 0xeb, 0xdc, 0x56, 0x53, +0x16, 0xf3, 0xba, 0x5d, 0xcf, 0x8c, 0xe4, 0x53, +0x0d, 0x98, 0x4e, 0x45, 0x7e, 0xf6, 0xbe, 0xc5, +0xb5, 0xd1, 0x91, 0x41, 0x59, 0x3e, 0x8d, 0x86, +0x59, 0x95, 0x83, 0x7e, 0xb7, 0x6b, 0xc3, 0xb7, +0xbe, 0x38, 0xff, 0x17, 0x0f, 0x36, 0xcc, 0xec, +0x98, 0x53, 0x5d, 0xc2, 0x13, 0xab, 0x3e, 0x3f, +0x6c, 0xd4, 0xa6, 0xc3, 0xc2, 0xda, 0x89, 0x98, +0x96, 0x0d, 0x48, 0xa2, 0x3f, 0x1a, 0xdf, 0x1e, +0x89, 0xc6, 0x5f, 0x8f, 0x0c, 0xc6, 0xcf, 0x44, +0xe3, 0x89, 0x76, 0xa0, 0x66, 0xd8, 0x10, 0x52, +0x14, 0xb1, 0x65, 0xe9, 0x9c, 0x49, 0x7a, 0x6a, +0x31, 0xba, 0x54, 0x85, 0x17, 0x1e, 0x59, 0x11, +0xd5, 0x9c, 0xca, 0x06, 0x45, 0x11, 0x9b, 0x1c, +0x8a, 0x38, 0x62, 0x58, 0xb6, 0x77, 0xcd, 0xd3, +0x4d, 0x94, 0xe4, 0x06, 0x59, 0x32, 0xab, 0x72, +0x4c, 0x03, 0x6b, 0x96, 0xce, 0x62, 0xdd, 0xcf, +0x5e, 0x63, 0xc5, 0x63, 0xbf, 0xf5, 0x7d, 0xff, +0x57, 0x6f, 0x2e, 0x7b, 0xfc, 0x37, 0x7f, 0xbb, +0xf3, 0xc4, 0xc5, 0xce, 0x2a, 0xdb, 0x92, 0x34, +0xa0, 0x7f, 0xe4, 0x10, 0x0a, 0xbb, 0x1c, 0xf2, +0xba, 0xa7, 0x1f, 0x6e, 0xdc, 0xbc, 0xe6, 0xa9, +0xed, 0x3e, 0xa7, 0xaa, 0xb0, 0xf1, 0xa1, 0x86, +0x58, 0x6e, 0xc0, 0xfb, 0xb2, 0xa2, 0xc8, 0x93, +0x63, 0x09, 0xa3, 0xe7, 0x42, 0xc7, 0x75, 0xe3, +0xc7, 0xbf, 0xdb, 0x1b, 0xe8, 0xed, 0x8f, 0x52, +0x9a, 0x1f, 0xb4, 0x67, 0x56, 0x8d, 0x93, 0x76, +0xff, 0xf3, 0x7c, 0xda, 0xe4, 0x42, 0x48, 0xe4, +0xf8, 0xdc, 0xac, 0xbb, 0xbb, 0xce, 0xd2, 0x75, +0x23, 0x5a, 0x5d, 0x96, 0x6f, 0x14, 0x64, 0xf9, +0x5c, 0x83, 0x43, 0x89, 0xdd, 0x1e, 0xcd, 0xf1, +0x00, 0x10, 0x19, 0x35, 0x05, 0x65, 0x59, 0xde, +0x9a, 0xed, 0x77, 0xcf, 0x6e, 0xde, 0xb8, 0x7a, +0x0d, 0x20, 0x99, 0xa6, 0xb5, 0x29, 0xe0, 0x75, +0x9d, 0xd0, 0x0d, 0x73, 0xfb, 0x96, 0xe6, 0xc3, +0xe2, 0x72, 0x57, 0x98, 0x69, 0x15, 0x85, 0xac, +0x5a, 0x32, 0x23, 0xea, 0x70, 0x28, 0x6f, 0x0f, +0xc4, 0x12, 0x0b, 0x01, 0xc7, 0x48, 0x1d, 0x80, +0xbc, 0xa0, 0x17, 0xc3, 0xb4, 0x7a, 0xeb, 0x6b, +0x4a, 0xd7, 0xa8, 0xaa, 0xaa, 0x02, 0x2d, 0x40, +0xab, 0x4b, 0x55, 0x92, 0xc5, 0x93, 0x76, 0x0c, +0x67, 0x7b, 0xb5, 0x47, 0x80, 0x1f, 0x01, 0x4e, +0xa0, 0x03, 0x40, 0x48, 0xf2, 0xdd, 0xf7, 0x2d, +0x9a, 0xbe, 0xd2, 0xb2, 0xac, 0x00, 0x82, 0xde, +0x5c, 0xbf, 0x67, 0x33, 0x50, 0x95, 0x17, 0xf4, +0x4e, 0x06, 0x8a, 0xd3, 0xe9, 0x14, 0x66, 0xfb, +0xd0, 0x2d, 0xbb, 0x4d, 0x55, 0xd5, 0x5d, 0x69, +0x97, 0x28, 0x93, 0x81, 0x0f, 0x70, 0x3d, 0xf5, +0x46, 0x96, 0x69, 0xce, 0xf1, 0x6b, 0xcd, 0x23, +0x62, 0x8a, 0xbd, 0x9a, 0x6a, 0x64, 0x12, 0x28, +0xcc, 0xf1, 0xe3, 0x74, 0xc8, 0x63, 0x36, 0x8b, +0x31, 0x4f, 0x42, 0x1f, 0x03, 0x11, 0xaf, 0xe6, +0xcc, 0x78, 0x4e, 0x2b, 0xcd, 0xcb, 0xba, 0x11, +0xf4, 0xb8, 0x46, 0x1f, 0x18, 0xfe, 0x8f, 0x06, +0x06, 0x52, 0x8f, 0xdd, 0x23, 0x31, 0xa1, 0x28, +0x6b, 0x00, 0x18, 0xb3, 0x5b, 0x7d, 0x6a, 0x03, +0x9a, 0xd3, 0x91, 0x51, 0xa3, 0xac, 0x20, 0xdb, +0x04, 0x2e, 0x7d, 0x96, 0x06, 0x22, 0x99, 0x0c, +0x84, 0x02, 0x1e, 0x4a, 0xf3, 0x82, 0x1a, 0x70, +0xea, 0xb3, 0x34, 0xd0, 0xed, 0xd3, 0x9c, 0x5a, +0x61, 0xb6, 0x6f, 0x14, 0xb1, 0xfa, 0x8e, 0x59, +0x1d, 0x8a, 0x2c, 0x36, 0x03, 0xf1, 0xb1, 0x04, +0xa4, 0x34, 0x7f, 0xc7, 0x9f, 0x14, 0x5f, 0xfb, +0xf7, 0xe5, 0xee, 0x8d, 0xdf, 0xd9, 0xfc, 0xe7, +0x9c, 0xbe, 0xc1, 0x18, 0x95, 0x25, 0xb9, 0xc6, +0xb7, 0xbf, 0x54, 0xdf, 0x59, 0x59, 0x12, 0xd2, +0x65, 0x21, 0xea, 0x80, 0xcc, 0xff, 0x71, 0x00, +0xb6, 0x6d, 0x7f, 0xea, 0x4b, 0xd7, 0xcd, 0xef, +0x45, 0x63, 0x7a, 0x77, 0x2c, 0xa1, 0xdf, 0x88, +0x25, 0xf4, 0xe3, 0xb6, 0x6d, 0xdf, 0x6b, 0xdb, +0xb6, 0xf8, 0x38, 0xef, 0xfe, 0x17, 0x21, 0x8e, +0xd6, 0x18, 0xd5, 0x75, 0x26, 0x38, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *pgAdmin3_32_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_pgAdmin3_32_png = new wxImage(); + if (!img_pgAdmin3_32_png || !img_pgAdmin3_32_png->IsOk()) + { + wxMemoryInputStream img_pgAdmin3_32_pngIS(pgAdmin3_32_png_data, sizeof(pgAdmin3_32_png_data)); + img_pgAdmin3_32_png->LoadFile(img_pgAdmin3_32_pngIS, wxBITMAP_TYPE_PNG); + } + return img_pgAdmin3_32_png; +} +#define pgAdmin3_32_png_img pgAdmin3_32_png_img() + +static wxBitmap *pgAdmin3_32_png_bmp() +{ + static wxBitmap *bmp_pgAdmin3_32_png; + if (!bmp_pgAdmin3_32_png || !bmp_pgAdmin3_32_png->IsOk()) + bmp_pgAdmin3_32_png = new wxBitmap(*pgAdmin3_32_png_img); + return bmp_pgAdmin3_32_png; +} +#define pgAdmin3_32_png_bmp pgAdmin3_32_png_bmp() + +static wxIcon *pgAdmin3_32_png_ico() +{ + static wxIcon *ico_pgAdmin3_32_png; + if (!ico_pgAdmin3_32_png || !ico_pgAdmin3_32_png->IsOk()) + { + ico_pgAdmin3_32_png = new wxIcon(); + ico_pgAdmin3_32_png->CopyFromBitmap(*pgAdmin3_32_png_bmp); + } + return ico_pgAdmin3_32_png; +} +#define pgAdmin3_32_png_ico pgAdmin3_32_png_ico() + +#endif // PGADMIN3_32_PNG_H diff --git a/include/images/pgAdmin3-36.png b/include/images/pgAdmin3-36.png new file mode 100644 index 0000000000000000000000000000000000000000..3389aca4ff3643ea043766298fcee7a9e8004e2e GIT binary patch literal 2174 zcmV-^2!Z#BP)Hv9x>;bj;&bjP|LK{mWqljwJNp@TQQW)5F`)?AuCG~Lbmtr zz3<-FKS)B7mzO}N!*}M)n{$4@^E;n=&O5*RyHYqDW&ouFg}_*#1*qw2)j(S>KNoN( zkk{1$Km`y23Im4q4IoET%7x3sDN}1-|aTu+$G|xDm29sY1-Ix!lrP zUUOOU$GGib2|g*w?{#@})nkS1OR|vP7lJEB$bO==J>aQqXtvMPG`cla4v!d?V2#U3 zbqOKK2TxW@I}U!$+1f@lRUtP$kx`k6_PFe{w#j+vE+nzdrOIo%9yS7KsbxEV-n{#` z{Pwml-G&v4*fvd-8K0fXb1UcBNparrx_3TP_MJFC&<-N7BDtDmDL-zQ(52C z#~$Z(@#vE2!9_)*O$lL>X$(hAX5NoorW23oB^+YkM77w#I_yIUu^!LfB@dzb(9pp zm-*B3BWyxQ5?~4-t*N!s8Y);pZaSrv7a2Hh4J}y+6h&s!r-%7|@x(s1j3ghSkP`$h zD?nTzI3y3FhbMEo<_gQ_6majfd_1~}Wjk!yQ#$A|N)oJ?Gl_@hPa(nQ0l*5`eSES~ z{B#&bm8N=7fQqaXzcv)m@YHy|JvEO*<+c3j^P{M$AlB{Tu_e>FaPca~&ejh&Z{~y% zJaBg*n|FVO?Ktc?Udiv*+}AgDiXVYg2A}|^UAm&h$GW-N7KjSu^XU9-cPVddJpjOS z56)wFN*o{WFJsa4u~C6$7mQ@<{xXhL)S)OcF&>@fw$462)5m8AV`JQV;QB4If@bJK zZhGRNJ9M=zz{#qMJ^feS{U<+p?ITW9UL-p;KI*)Vpoyj^96MXjf68k}^m(}23n3FPSl} z)8}=))!i3ezn@Ib%XDdq92H280u<}f2^c0$lzh+`H2L(&T>0eV)@H08rt6GxiSg0{2=d-6zc&6qHPBNerS0#(#CQd-%-gLfCAsWN8B zCM(&`(i!7zpVzgvw{H)SBE*h4lcEFFHD042cUYe>AtV+SjbZ1(Q-cBl{C3+x9{kp1 zCgu*Kv8996%kDBmPWUZ)6=!{bfCKTdZn^u<*I(~_ag6y>^BIwr&@(nAFOz^_@zuG8 zA%V`;HL>e(1&=N+;^^6W?i!n8d3E*0{(ilILT1R`v3SPV$WjrgZ)#=Z-%EJsnfoZ7 zG!h{sCXdSCKv~t0Fx~pi)&qE5D#a6XO(97yalKyeBc*r8>(bUQFD_WTac7BQT6TY5 z8k*X0Yl`vm!}B|IMfTf{BmMj21!??YM&rcct|W;B8<^#69-t>XT0`n`xxR-zXq+(-Zmi6N^n*l~)3n zfL~Z4d*}N1_lDQ~;WJv=13Yx^lp%qpj?QB9zmBtc_i^#)>mS9h+w^J7{uAf@$$pPy z7}jdwkTSr$Jwiyo`_)euta@S7E?0J1JTI)AXUIZ&C1hG_Z6U_(`KmJX@&1$El2g^p znmCfQgjna`*VU0ps+Sa5;PbfH`1CR-U|ObISGCTdS!;(W(NyI{y1vl{0zy}nXR=cK z%3s#~;74Z2X?LmWk7b#XknQ~ZPVf#jxypx2`q=QS0DnK;3HZ*T1AF;^i1c@9!5@WijY?(Xd1x zvXIUUu^xk-`z0Icf3ju^zqbb^)1QmpW)+o|Bf)0aV>CpqdnaOvE|%R#r+} z_;vzai1)c;q8Z(~N@h}=A2@xxfU10MJuynr$bxD4;gI8$avOK(oT@07@1IxL*58m2 z>*kT~Olx*)>Mw65&`{U@W)+eo9(rQw^xf?NGkl`5L2~OVOYa&VTv#+(QWbd{y~@-< z6%L30pKU=$&@44ft0`z$4I$fpGaL?Q-%5=C0<4cjF=Yw#yZ`_I07*qoM6N<$f~G1i As{jB1 literal 0 HcmV?d00001 diff --git a/include/images/pgAdmin3-48.png b/include/images/pgAdmin3-48.png new file mode 100644 index 0000000000000000000000000000000000000000..45d81070dfcf672f97f5b3cfc4bc0b117ec5bdc1 GIT binary patch literal 3073 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 P00000NkvXXu0mjf=)Ue3 literal 0 HcmV?d00001 diff --git a/include/images/pgAdmin3-96.png b/include/images/pgAdmin3-96.png new file mode 100644 index 0000000000000000000000000000000000000000..571aa30a87721d90fc896786829c37e7a07b50d1 GIT binary patch literal 6233 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 Dqk8(d literal 0 HcmV?d00001 diff --git a/include/images/pgAdmin3.ico b/include/images/pgAdmin3.ico new file mode 100644 index 0000000000000000000000000000000000000000..3fcebafdc9c16dedaf800066f84a3fb91a226ec1 GIT binary patch literal 35147 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 literal 0 HcmV?d00001 diff --git a/include/images/pgAdmin3.pngc b/include/images/pgAdmin3.pngc new file mode 100644 index 0000000..bf56b6d --- /dev/null +++ b/include/images/pgAdmin3.pngc @@ -0,0 +1,977 @@ +#ifndef PGADMIN3_PNG_H +#define PGADMIN3_PNG_H + +static const unsigned char pgAdmin3_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x80, +0x08, 0x06, 0x00, 0x00, 0x00, 0x22, 0x79, 0xb6, +0xdf, 0x00, 0x00, 0x00, 0x04, 0x73, 0x42, 0x49, +0x54, 0x08, 0x08, 0x08, 0x08, 0x7c, 0x08, 0x64, +0x88, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x02, 0x0d, 0x00, 0x00, 0x02, +0x0d, 0x01, 0x77, 0x4e, 0xbe, 0x70, 0x00, 0x00, +0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, +0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x00, 0x77, +0x77, 0x77, 0x2e, 0x69, 0x6e, 0x6b, 0x73, 0x63, +0x61, 0x70, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x9b, +0xee, 0x3c, 0x1a, 0x00, 0x00, 0x1c, 0x9f, 0x49, +0x44, 0x41, 0x54, 0x78, 0x9c, 0xed, 0x7d, 0x69, +0x78, 0x1c, 0xd5, 0x95, 0xf6, 0x7b, 0xaa, 0x7a, +0x6f, 0xed, 0x92, 0x25, 0xd9, 0xd6, 0xe6, 0x15, +0x63, 0x1b, 0x1b, 0xdb, 0x02, 0x6c, 0x76, 0x0c, +0x1f, 0x24, 0x84, 0xb0, 0x63, 0x96, 0x19, 0x20, +0x0c, 0xc1, 0x36, 0x90, 0x4c, 0x20, 0x61, 0x99, +0x84, 0x4c, 0x88, 0x27, 0xdf, 0x93, 0x2f, 0x10, +0xc6, 0x0b, 0x66, 0x09, 0x66, 0x0b, 0x4c, 0x42, +0x82, 0x01, 0xb3, 0xef, 0x04, 0xdb, 0x18, 0x6c, +0xbc, 0x6f, 0x32, 0x36, 0xb6, 0xe4, 0x45, 0xfb, +0xee, 0x56, 0xab, 0xd7, 0x5a, 0xee, 0xf9, 0x7e, +0x54, 0x57, 0xab, 0xed, 0xc8, 0xb6, 0xa4, 0x96, +0x5a, 0x62, 0xba, 0xdf, 0xe7, 0xd1, 0xa3, 0x7b, +0xab, 0xab, 0x6f, 0xdf, 0xaa, 0xb7, 0xce, 0xb9, +0xe7, 0x9e, 0x7b, 0xee, 0x29, 0x62, 0x66, 0xa4, +0x90, 0x9c, 0x90, 0x06, 0xbb, 0x03, 0x29, 0x0c, +0x1e, 0x52, 0xe4, 0x27, 0x31, 0x52, 0xe4, 0x27, +0x31, 0x52, 0xe4, 0x27, 0x31, 0x52, 0xe4, 0x27, +0x31, 0x52, 0xe4, 0x27, 0x31, 0x52, 0xe4, 0x27, +0x31, 0x52, 0xe4, 0x27, 0x31, 0x52, 0xe4, 0x27, +0x31, 0x52, 0xe4, 0x27, 0x31, 0x52, 0xe4, 0x27, +0x31, 0x52, 0xe4, 0x27, 0x31, 0x52, 0xe4, 0x27, +0x31, 0x52, 0xe4, 0x27, 0x31, 0x52, 0xe4, 0x27, +0x31, 0x52, 0xe4, 0x27, 0x31, 0x52, 0xe4, 0x27, +0x31, 0x52, 0xe4, 0x27, 0x31, 0x52, 0xe4, 0x27, +0x31, 0x52, 0xe4, 0x27, 0x31, 0x52, 0xe4, 0x27, +0x31, 0x52, 0xe4, 0x27, 0x31, 0x52, 0xe4, 0x27, +0x31, 0x2c, 0x83, 0xdd, 0x81, 0xef, 0x32, 0x66, +0xde, 0xb1, 0xa4, 0x40, 0xb7, 0x48, 0xa5, 0x2c, +0x44, 0x29, 0x11, 0x5b, 0x84, 0xa0, 0x76, 0x96, +0x44, 0x9b, 0x55, 0xb7, 0xb6, 0xf9, 0x6d, 0x52, +0x4b, 0xc5, 0x93, 0x77, 0xf9, 0x06, 0xbb, 0x8f, +0xc7, 0x03, 0x0d, 0xf5, 0x4d, 0x1b, 0x67, 0xfe, +0x7c, 0x91, 0x53, 0x0d, 0x5a, 0x4e, 0x11, 0xa0, +0x34, 0x66, 0x2d, 0x28, 0xb1, 0xc5, 0x07, 0x70, +0x00, 0xd0, 0x03, 0x36, 0x37, 0x7b, 0xd6, 0x2e, +0xbc, 0x37, 0xd8, 0x97, 0x76, 0xcb, 0xe7, 0x2d, +0x1d, 0xc3, 0x84, 0xa9, 0xc4, 0x7a, 0x0e, 0x40, +0x99, 0x00, 0xb9, 0x04, 0x8b, 0x3a, 0x62, 0xde, +0xa7, 0x59, 0x9c, 0xdf, 0x6e, 0x7f, 0x7a, 0x7e, +0x73, 0xec, 0xb9, 0x20, 0xbe, 0x94, 0x99, 0x27, +0x11, 0x49, 0x65, 0x00, 0x97, 0x02, 0x28, 0x05, +0xe0, 0x3c, 0xfe, 0xaf, 0x70, 0x05, 0x33, 0x3e, +0x93, 0x04, 0x7d, 0x1a, 0xec, 0x38, 0xfc, 0x45, +0xc5, 0xf2, 0x87, 0x87, 0xd4, 0xc3, 0x30, 0xa4, +0xc8, 0x27, 0x02, 0x9d, 0x76, 0xc7, 0x92, 0x72, +0x9d, 0xe8, 0x74, 0x89, 0x30, 0x83, 0x19, 0x33, +0x40, 0x98, 0x88, 0x63, 0x6b, 0x28, 0x06, 0x73, +0x15, 0x03, 0x9b, 0x01, 0xda, 0xc2, 0x84, 0xcd, +0x1c, 0x16, 0x9b, 0xb7, 0xbe, 0x78, 0x8f, 0xa7, +0xbb, 0x93, 0xa7, 0xcf, 0x5f, 0x72, 0xae, 0x0c, +0xe9, 0x2e, 0x06, 0x9f, 0x0b, 0x60, 0xf8, 0xf1, +0x7b, 0xc3, 0x5e, 0x30, 0x0e, 0x42, 0x92, 0x46, +0x82, 0x39, 0x37, 0xae, 0x0b, 0x33, 0xa0, 0x82, +0xc5, 0x4a, 0x9d, 0xc5, 0x82, 0xad, 0xcb, 0x7e, +0xbe, 0xb6, 0x1f, 0xda, 0x8b, 0x1b, 0x43, 0x82, +0x7c, 0x22, 0xd0, 0xf4, 0xf9, 0x8f, 0x5f, 0x49, +0x02, 0xbf, 0x05, 0x61, 0x4a, 0x9c, 0xcd, 0xe9, +0x10, 0x62, 0x0d, 0x13, 0xbd, 0xa1, 0x4b, 0xe2, +0xcd, 0x6d, 0x4f, 0xdf, 0x5b, 0x57, 0x3e, 0x6f, +0xe9, 0x18, 0x22, 0xf1, 0x28, 0x83, 0xae, 0xee, +0x97, 0x0e, 0x03, 0x00, 0x83, 0x85, 0xa6, 0xb4, +0xeb, 0x6a, 0xb0, 0x45, 0x0b, 0x05, 0x5b, 0x58, +0x68, 0x8a, 0x6c, 0xb5, 0xbb, 0x25, 0x8b, 0x35, +0x8d, 0x2c, 0xd6, 0x74, 0x8b, 0xd5, 0x51, 0x00, +0x49, 0x76, 0x74, 0xfb, 0x55, 0x4d, 0x79, 0x1f, +0x24, 0xee, 0xdf, 0xfc, 0xec, 0x03, 0xbb, 0xfb, +0xad, 0x3f, 0x7d, 0xc0, 0xa0, 0x93, 0x3f, 0xf3, +0x8e, 0xa5, 0x45, 0xba, 0x8c, 0xe5, 0x0c, 0x9e, +0xd5, 0xfd, 0x19, 0xac, 0x69, 0x21, 0x7f, 0xb5, +0xae, 0x2a, 0x5e, 0x92, 0x64, 0x1b, 0xc9, 0xb2, +0x5d, 0x22, 0xc9, 0x41, 0x92, 0x6c, 0x27, 0x8b, +0x35, 0x9d, 0x48, 0xb2, 0x1f, 0xa7, 0x79, 0x06, +0xd0, 0x08, 0xc2, 0x30, 0xf0, 0x91, 0xda, 0x83, +0x35, 0xd5, 0xab, 0x04, 0xbc, 0x7b, 0x75, 0x25, +0xd0, 0x2e, 0x54, 0x25, 0xc8, 0xba, 0xae, 0x58, +0x9c, 0xee, 0x1c, 0x8b, 0xdd, 0x5d, 0x28, 0xdb, +0x5d, 0x85, 0x92, 0xd5, 0x96, 0x03, 0x80, 0xba, +0x6b, 0x53, 0x0d, 0x78, 0xf7, 0xb6, 0xef, 0xdd, +0xf8, 0x4e, 0xed, 0xfa, 0x77, 0x36, 0x03, 0x08, +0x02, 0xf0, 0x03, 0x08, 0x00, 0xd0, 0x00, 0xd8, +0x00, 0xd8, 0x64, 0xbb, 0xdd, 0x99, 0x3f, 0xe9, +0xbc, 0x69, 0x19, 0x23, 0xc7, 0x4f, 0xb3, 0x67, +0x15, 0x4c, 0xb6, 0x3a, 0x33, 0xc6, 0x82, 0x20, +0xc7, 0xf4, 0x4c, 0x67, 0x5d, 0xfd, 0x1f, 0x16, +0xca, 0x03, 0x5b, 0x5e, 0xf8, 0x65, 0x4b, 0x2f, +0x6e, 0x59, 0xbf, 0x61, 0x50, 0xc9, 0x9f, 0x71, +0xd7, 0xd2, 0x99, 0x24, 0xf8, 0x4d, 0x00, 0x85, +0xe6, 0x31, 0x16, 0x7a, 0x20, 0x78, 0xb8, 0x71, +0x63, 0xd8, 0xd3, 0x5c, 0xd5, 0xd9, 0x78, 0xa0, +0xaa, 0x7d, 0xef, 0xfa, 0x6a, 0x5d, 0x09, 0x85, +0x01, 0x74, 0x00, 0x08, 0x03, 0x90, 0x23, 0x7f, +0x16, 0xc8, 0xb2, 0x35, 0x67, 0xf4, 0xf4, 0x51, +0xe9, 0x23, 0xc7, 0x8d, 0x73, 0x65, 0x17, 0x8c, +0xb6, 0xa6, 0xe7, 0x8e, 0xb1, 0x38, 0xd3, 0xc6, +0x12, 0xa8, 0xfb, 0x59, 0x0c, 0x43, 0x0f, 0xb4, +0x56, 0x7f, 0xde, 0xb4, 0xe3, 0xf3, 0x8f, 0xda, +0x2b, 0xb7, 0xd6, 0x45, 0xda, 0x6b, 0x83, 0x41, +0xa0, 0x0a, 0x40, 0x87, 0x31, 0x8e, 0xa7, 0xd9, +0x9c, 0x99, 0xb9, 0x19, 0xc5, 0xe3, 0x4b, 0x33, +0x8b, 0x27, 0x4e, 0x70, 0x17, 0x8d, 0xbf, 0xc0, +0xea, 0x48, 0x1b, 0x73, 0x74, 0x73, 0x5a, 0xd8, +0xff, 0x77, 0x7f, 0x53, 0xc3, 0xbc, 0xca, 0x0f, +0x97, 0xfa, 0x60, 0x3c, 0x68, 0x26, 0xcc, 0x87, +0x46, 0x02, 0x90, 0x03, 0xa0, 0x20, 0xa3, 0x6c, +0xd2, 0xa4, 0xa2, 0xd3, 0x2e, 0x9b, 0xeb, 0xc8, +0x19, 0x7e, 0x5e, 0x6c, 0xff, 0x84, 0xa6, 0x1e, +0xea, 0x6c, 0x3b, 0x74, 0xe1, 0xbe, 0x37, 0x1f, +0xaf, 0xea, 0xe3, 0x6d, 0xec, 0x33, 0x06, 0x8d, +0xfc, 0xe9, 0xf3, 0x9f, 0x28, 0x97, 0x20, 0xd6, +0x00, 0x70, 0x00, 0x00, 0x0b, 0xa1, 0xf8, 0x1a, +0xab, 0xde, 0xab, 0x5e, 0xf3, 0xda, 0xfb, 0x21, +0x4f, 0x93, 0x07, 0x40, 0x1d, 0x80, 0x76, 0x00, +0x87, 0x61, 0x10, 0xaf, 0x1f, 0xa3, 0x29, 0x02, +0x90, 0x06, 0xe3, 0x26, 0x67, 0xa7, 0x0d, 0x1f, +0x3d, 0x6a, 0xd8, 0xd4, 0xd9, 0x3f, 0xcc, 0x2e, +0x99, 0x74, 0x43, 0xac, 0x56, 0x08, 0x77, 0xb6, +0x6d, 0xa9, 0xdf, 0xf0, 0xee, 0x5f, 0xdb, 0x2b, +0xb7, 0xd6, 0x02, 0xd8, 0x0f, 0xa0, 0x12, 0x80, +0x17, 0x47, 0x92, 0x16, 0xdb, 0x26, 0x60, 0x3c, +0x64, 0x69, 0x00, 0xf2, 0x0a, 0xa7, 0x5f, 0x72, +0x71, 0xee, 0x98, 0x69, 0xd7, 0xd9, 0xb3, 0x0b, +0xce, 0x24, 0x92, 0xac, 0xe6, 0x89, 0x42, 0x53, +0x0f, 0xaa, 0x4a, 0xe8, 0xba, 0x9d, 0x2f, 0x3f, +0xb4, 0xe9, 0x58, 0xd7, 0x4a, 0x44, 0x14, 0x69, +0xd3, 0x35, 0x62, 0xda, 0xc5, 0x97, 0xe5, 0x4e, +0x9c, 0x75, 0xbf, 0x2d, 0x2d, 0x67, 0x7a, 0xb4, +0x0d, 0x55, 0x69, 0xec, 0x6c, 0xab, 0xbe, 0xb0, +0xf2, 0xed, 0xa5, 0xbb, 0x39, 0x81, 0x84, 0x0c, +0x0a, 0xf9, 0x67, 0xdf, 0xfe, 0x68, 0x7a, 0xc8, +0xea, 0xd8, 0x0a, 0x60, 0x0c, 0x00, 0x08, 0x4d, +0x6d, 0xaf, 0x5d, 0xff, 0xf6, 0x7f, 0xb7, 0x54, +0xac, 0xd9, 0x0b, 0xe0, 0x5b, 0x00, 0xfb, 0x60, +0x48, 0x25, 0x7a, 0x7a, 0x33, 0x22, 0x37, 0x18, +0x93, 0xae, 0xfb, 0xad, 0xdb, 0x9e, 0x9d, 0xb9, +0x92, 0x48, 0x2a, 0x07, 0x00, 0xd6, 0xf5, 0x40, +0xf3, 0x8e, 0xcf, 0x9f, 0xa8, 0xdd, 0xf0, 0xde, +0x16, 0x00, 0xf5, 0x00, 0x76, 0x02, 0xf0, 0x32, +0xb3, 0xe8, 0x69, 0x7f, 0x63, 0xc8, 0xcb, 0xc9, +0x2c, 0x9e, 0x30, 0x7d, 0xe4, 0xcc, 0x2b, 0x1f, +0x74, 0xe6, 0x0c, 0x9f, 0x1d, 0x3d, 0x81, 0x59, +0xd5, 0x42, 0x9d, 0xff, 0xb9, 0xfd, 0xe5, 0xff, +0x7c, 0xf4, 0x44, 0xfd, 0x25, 0x22, 0x09, 0x40, +0x66, 0xd9, 0xec, 0x5b, 0xe6, 0xe5, 0x8c, 0x99, +0xb6, 0x80, 0x24, 0xc9, 0x66, 0xdc, 0x03, 0xa5, +0xc5, 0xdf, 0x54, 0xfd, 0x7f, 0xf6, 0xbe, 0xb7, +0x74, 0x47, 0xa2, 0x1e, 0x80, 0x41, 0x99, 0xe7, +0x07, 0x2d, 0x8e, 0x27, 0x29, 0x42, 0x3c, 0x6b, +0xaa, 0x77, 0xdf, 0x87, 0x7f, 0xfa, 0x8d, 0xaf, +0xbe, 0xb2, 0x1a, 0xc0, 0x3a, 0x00, 0x6d, 0x7d, +0xb9, 0x78, 0x66, 0x66, 0x5a, 0xb0, 0x40, 0x72, +0x34, 0x64, 0xff, 0x05, 0x40, 0x79, 0xe4, 0xa8, +0x56, 0xbf, 0xf9, 0xc3, 0xc7, 0x1a, 0xb7, 0x7e, +0xba, 0x0d, 0xc0, 0x06, 0x00, 0x0d, 0xbd, 0x21, +0x3d, 0xb6, 0x6d, 0x18, 0x1a, 0xa2, 0x95, 0x88, +0x3e, 0xed, 0xa8, 0xf9, 0xc3, 0x9a, 0xb1, 0xdf, +0x9f, 0x7b, 0x6f, 0x46, 0xd1, 0x84, 0x87, 0x48, +0x92, 0x5d, 0x20, 0xb2, 0x5a, 0x9c, 0x19, 0x7f, +0x98, 0x74, 0xfd, 0xaf, 0x73, 0x89, 0xe8, 0x3f, +0x8e, 0xf7, 0x1b, 0x91, 0xcf, 0x0e, 0x13, 0xd1, +0xa3, 0xb6, 0xf4, 0xec, 0x03, 0x69, 0x05, 0x65, +0x2f, 0x11, 0x49, 0x76, 0xc9, 0x62, 0x1b, 0xe6, +0x2e, 0x28, 0xfd, 0xfc, 0xa4, 0xcb, 0x7f, 0x72, +0x09, 0x11, 0x6d, 0x4e, 0xc4, 0x03, 0x90, 0x70, +0x0f, 0x5f, 0xf9, 0xbc, 0xc5, 0xd3, 0x89, 0x70, +0x73, 0xa4, 0xca, 0x8d, 0x15, 0xab, 0x9e, 0xf2, +0xd5, 0x57, 0xd6, 0x02, 0x58, 0x89, 0x3e, 0x12, +0x1f, 0x6d, 0xbb, 0x21, 0xeb, 0x36, 0x00, 0x57, +0x98, 0xf5, 0xd6, 0x3d, 0x5f, 0x3f, 0xdb, 0xb8, +0xf5, 0xd3, 0x0a, 0x18, 0x0f, 0x55, 0x7d, 0x5f, +0x88, 0x3f, 0x1a, 0x6c, 0x20, 0x58, 0xf9, 0xe1, +0xb2, 0x3f, 0x34, 0xee, 0x58, 0x79, 0x89, 0x16, +0xf4, 0x7d, 0x6b, 0x7e, 0xe6, 0xc8, 0x1a, 0x76, +0xff, 0xc9, 0x57, 0xff, 0xe2, 0x57, 0x11, 0xe9, +0x3e, 0x51, 0x3b, 0x62, 0xef, 0xdb, 0x4b, 0x96, +0xfb, 0x9a, 0x0f, 0xdd, 0x00, 0xa1, 0x87, 0x00, +0x40, 0xb2, 0x58, 0x73, 0x9c, 0xb9, 0xc5, 0xaf, +0x03, 0x99, 0x59, 0xf1, 0xf6, 0xb3, 0x27, 0x48, +0x38, 0xf9, 0x0c, 0xe9, 0x6e, 0xb3, 0x1c, 0x6c, +0xaf, 0x5b, 0x55, 0xbf, 0xfe, 0xbd, 0x6d, 0x00, +0x36, 0x01, 0xf0, 0xc7, 0x45, 0xfc, 0xbc, 0x65, +0x56, 0x06, 0x3d, 0x64, 0xd6, 0x7d, 0x0d, 0x55, +0x6f, 0x1f, 0x5a, 0xfd, 0xf7, 0xd5, 0x91, 0xb6, +0x9b, 0xfa, 0x5b, 0x92, 0x98, 0x59, 0xd4, 0xaf, +0x7f, 0xf7, 0xab, 0x03, 0x9f, 0x3f, 0x7d, 0xa6, +0x1a, 0xe8, 0x58, 0x67, 0x1e, 0x77, 0x0e, 0x2b, +0x5e, 0x70, 0xf2, 0x55, 0xf7, 0xdc, 0x69, 0x0e, +0x43, 0x27, 0x68, 0x83, 0xf7, 0xbe, 0xb5, 0xf8, +0x6d, 0x6f, 0x63, 0xd5, 0x75, 0xcc, 0x22, 0x08, +0x00, 0xb2, 0xcd, 0x51, 0x5a, 0x7c, 0xd6, 0x85, +0x77, 0x12, 0x91, 0x7c, 0xa2, 0xef, 0xc7, 0x8b, +0x84, 0x92, 0x3f, 0xe5, 0xae, 0xa7, 0xb3, 0x89, +0x70, 0xa3, 0x59, 0x6f, 0xdc, 0xb6, 0xf2, 0x03, +0x00, 0x07, 0x60, 0xa8, 0xe3, 0x38, 0xc9, 0x09, +0xdd, 0x0a, 0x60, 0x14, 0x00, 0x08, 0x4d, 0xf5, +0xec, 0xff, 0xc7, 0x9f, 0x57, 0x00, 0xd8, 0x03, +0xe0, 0xd0, 0x40, 0xa9, 0x50, 0x66, 0xe6, 0x8e, +0x9a, 0x9a, 0x76, 0xbd, 0xa6, 0xf1, 0x62, 0x2d, +0xe4, 0xdf, 0x0a, 0x00, 0x04, 0x92, 0x5c, 0xf9, +0x65, 0x8b, 0xc7, 0x7d, 0x6f, 0xde, 0x55, 0x3d, +0x7d, 0x00, 0xf6, 0xbd, 0xfb, 0xe4, 0xfb, 0x7a, +0x38, 0xf0, 0x27, 0xf3, 0x58, 0x66, 0xf1, 0xa4, +0x2b, 0x01, 0x14, 0xf4, 0xe4, 0xfb, 0xf1, 0x20, +0xa1, 0xe4, 0xdb, 0x74, 0xf5, 0x1a, 0x44, 0x5c, +0xa2, 0xaa, 0xcf, 0xb3, 0xab, 0x7d, 0xdf, 0xc6, +0x1a, 0x00, 0xfb, 0xe2, 0x55, 0xc7, 0xe5, 0xf3, +0x96, 0x59, 0x41, 0xf8, 0x95, 0x59, 0xef, 0xac, +0xdb, 0xf3, 0x9e, 0xea, 0xf7, 0x76, 0x00, 0xd8, +0xdd, 0x1f, 0xaa, 0xfe, 0x44, 0xa8, 0x58, 0xf9, +0xa4, 0xaf, 0xad, 0xb1, 0xea, 0x22, 0x2d, 0x1c, +0xd8, 0x63, 0x1c, 0x21, 0x8b, 0x7b, 0xc4, 0xe8, +0xa7, 0xb2, 0xca, 0x4e, 0x2d, 0xed, 0xc9, 0xf7, +0x99, 0x99, 0xd9, 0x6a, 0x59, 0x68, 0xd6, 0xad, +0xe9, 0xd9, 0x27, 0x03, 0x18, 0x3d, 0x20, 0x9d, +0x8d, 0x41, 0x42, 0xc9, 0x67, 0x70, 0xb9, 0x59, +0xee, 0x6c, 0xdc, 0xbf, 0x0e, 0x40, 0x33, 0x8c, +0x69, 0x5c, 0x5c, 0x20, 0x0a, 0x5f, 0x0b, 0x53, +0xea, 0x75, 0xb5, 0xe3, 0xd0, 0x9a, 0xd7, 0x3f, +0x83, 0x31, 0x6b, 0x50, 0xe3, 0x6d, 0xbb, 0xa7, +0xa8, 0xf9, 0xe8, 0xb9, 0x76, 0xc5, 0xdb, 0x34, +0x5b, 0xe8, 0x5a, 0x3b, 0x00, 0xc8, 0x56, 0x47, +0xc1, 0xc8, 0xd3, 0xbe, 0xb7, 0x94, 0x88, 0x8e, +0xe7, 0x84, 0x8a, 0x62, 0xfb, 0xb3, 0x0f, 0xd4, +0xc2, 0x70, 0x14, 0x41, 0x92, 0x64, 0xb7, 0x6c, +0xb3, 0x15, 0xa2, 0x7b, 0x27, 0x53, 0xbf, 0x21, +0xa1, 0xe4, 0x13, 0xd1, 0x54, 0xb3, 0x1c, 0x68, +0x3e, 0x74, 0x08, 0x40, 0x2d, 0xba, 0x9f, 0x67, +0xf7, 0x0a, 0x82, 0xf9, 0x72, 0xb3, 0xdc, 0x59, +0x5f, 0xf5, 0x91, 0xea, 0xf7, 0x78, 0x00, 0xec, +0x4f, 0xe4, 0x9c, 0x19, 0x00, 0xbe, 0x79, 0x63, +0x51, 0x83, 0xae, 0x06, 0xe7, 0x9a, 0x75, 0x47, +0xce, 0xf0, 0x1f, 0x94, 0xcd, 0xbe, 0xf9, 0xb6, +0x9e, 0x18, 0x80, 0x11, 0xb4, 0x46, 0xfe, 0x93, +0x33, 0xb7, 0x38, 0x17, 0x03, 0xcc, 0x4f, 0xc2, +0xc8, 0xa7, 0x05, 0x0b, 0x24, 0x00, 0xa7, 0x00, +0x00, 0x18, 0xdc, 0xbe, 0x7f, 0x5b, 0x0d, 0x00, +0x4f, 0xbc, 0x04, 0xcd, 0x99, 0xf3, 0x9a, 0x4c, +0x84, 0x8b, 0xcd, 0x7a, 0xfb, 0xde, 0xaf, 0x37, +0xc0, 0x70, 0xe0, 0x24, 0x4c, 0xea, 0x63, 0xb1, +0xe3, 0xa5, 0x5f, 0xaf, 0xd0, 0xd5, 0xd0, 0x6b, +0x91, 0x2a, 0x65, 0x96, 0x4e, 0x7a, 0x08, 0x70, +0x15, 0xf6, 0x70, 0xfc, 0x6e, 0x33, 0x0b, 0x8e, +0xf4, 0x9c, 0x34, 0x18, 0xae, 0xe2, 0x01, 0x43, +0xc2, 0xc8, 0x3f, 0xbd, 0x36, 0xb7, 0x14, 0x80, +0x1b, 0x00, 0x74, 0x35, 0xd4, 0xac, 0xfa, 0x3d, +0x41, 0xf4, 0x83, 0xca, 0x3f, 0x98, 0xd5, 0x70, +0x06, 0x0c, 0xef, 0x1e, 0x74, 0x25, 0xd4, 0x14, +0x71, 0xdb, 0xd6, 0x26, 0x5a, 0xea, 0x4d, 0x30, +0x33, 0xab, 0x9d, 0xc1, 0xf9, 0x2c, 0x84, 0x07, +0x00, 0x2c, 0x36, 0x67, 0x51, 0xe9, 0xf9, 0x57, +0xdd, 0x89, 0x9e, 0xdd, 0x6b, 0xb7, 0x59, 0x50, +0x42, 0x7e, 0x05, 0xff, 0x5b, 0xc8, 0x17, 0x16, +0x11, 0xbd, 0x30, 0xd6, 0xb5, 0x00, 0x8c, 0xc5, +0x10, 0x2d, 0xde, 0x76, 0x59, 0xa6, 0x1f, 0x98, +0xe5, 0x90, 0xa7, 0x69, 0x2b, 0x00, 0x1f, 0x80, +0xce, 0x78, 0xdb, 0x8d, 0x07, 0x15, 0xcb, 0x1f, +0x6e, 0x67, 0xa1, 0x2f, 0x32, 0xeb, 0x59, 0xa5, +0x93, 0xfe, 0x05, 0xc0, 0xc8, 0x1e, 0x48, 0x7f, +0xbe, 0x59, 0x08, 0x36, 0xd7, 0x7a, 0x70, 0x6c, +0x97, 0x76, 0xbf, 0x20, 0x81, 0x63, 0x3e, 0x59, +0xbb, 0xca, 0xac, 0xa1, 0x9f, 0xd4, 0xb2, 0x00, +0x9f, 0x6e, 0x96, 0x7d, 0x0d, 0x55, 0xdb, 0x01, +0x34, 0xa0, 0x1f, 0xec, 0x88, 0x78, 0x21, 0xc9, +0xda, 0x12, 0xb0, 0xe8, 0x04, 0x00, 0x8b, 0xc3, +0x3d, 0x6a, 0x64, 0xf9, 0x0f, 0xae, 0xc6, 0x71, +0x0c, 0xb8, 0xf2, 0x79, 0xcb, 0xac, 0x00, 0xb2, +0x00, 0x63, 0x71, 0x4b, 0x0d, 0x79, 0x15, 0x00, +0xa1, 0x81, 0xec, 0x63, 0x22, 0xdd, 0xbb, 0x51, +0xf2, 0x99, 0x85, 0x0e, 0xa0, 0x5f, 0xa6, 0x60, +0xc4, 0x98, 0x60, 0x96, 0xbd, 0xb5, 0xdf, 0xd6, +0x02, 0x68, 0xea, 0x8f, 0x76, 0xfb, 0xd4, 0x17, +0x02, 0x9d, 0xfa, 0xa3, 0xc5, 0x99, 0x56, 0x27, +0x72, 0x48, 0x72, 0xba, 0x74, 0x4d, 0x7f, 0x57, +0x92, 0x71, 0x13, 0x00, 0xb8, 0x87, 0x8f, 0x3a, +0x13, 0xc0, 0x5f, 0x01, 0x74, 0xbb, 0x7c, 0x6b, +0x11, 0xe1, 0x02, 0x2d, 0xe2, 0xd6, 0x11, 0x9a, +0xe2, 0x41, 0xd7, 0x2a, 0xe3, 0x80, 0x21, 0x81, +0xe4, 0x93, 0x35, 0x2a, 0x90, 0xcc, 0x1a, 0xfa, +0x41, 0x3a, 0x27, 0xdf, 0xfd, 0x54, 0x9a, 0x03, +0x28, 0x32, 0x9a, 0x14, 0x61, 0x6f, 0xed, 0xbe, +0x56, 0x00, 0x1d, 0x93, 0xae, 0xfb, 0xad, 0xf5, +0xb4, 0x3b, 0x97, 0xfc, 0x50, 0x08, 0x3a, 0x0b, +0x40, 0x09, 0x11, 0x17, 0x32, 0xa3, 0x11, 0xe0, +0x0a, 0xc1, 0xf4, 0xfe, 0xd6, 0x65, 0x3f, 0xdb, +0x18, 0xef, 0x6f, 0xc7, 0xe2, 0xb4, 0xb9, 0x4f, +0x7c, 0x5f, 0x90, 0xb8, 0x71, 0xc6, 0x3c, 0x5c, +0x0e, 0x48, 0x99, 0x22, 0xf2, 0x58, 0x4b, 0x72, +0x97, 0x93, 0xce, 0x99, 0x57, 0x34, 0x0b, 0x86, +0xe3, 0xa6, 0xb5, 0x3b, 0x7b, 0x44, 0x95, 0x79, +0xb2, 0xa9, 0x16, 0x34, 0x25, 0xd8, 0x8c, 0x01, +0x96, 0x7a, 0x20, 0x81, 0xe4, 0xeb, 0xac, 0x09, +0x29, 0x32, 0xca, 0xb0, 0xb1, 0x9e, 0x1d, 0xb7, +0xe4, 0x3b, 0x34, 0x65, 0xbc, 0xb9, 0x34, 0xae, +0x2b, 0xc1, 0xc6, 0x9c, 0x93, 0xca, 0x0b, 0xcb, +0xce, 0xbb, 0xf1, 0xbf, 0x88, 0xe8, 0x66, 0x66, +0xe4, 0x75, 0x8d, 0xb0, 0x04, 0xa3, 0x4c, 0xd7, +0xc8, 0x84, 0xdf, 0x4c, 0xbb, 0xfd, 0xd1, 0xa7, +0x7d, 0x0d, 0xb5, 0x3f, 0xdf, 0xf7, 0xc1, 0xe3, +0xe1, 0x78, 0x7e, 0x7f, 0xf2, 0xdd, 0x4f, 0xa5, +0x39, 0x74, 0xed, 0x45, 0x48, 0xb8, 0xf6, 0x44, +0x83, 0xb9, 0x6c, 0x75, 0x14, 0x00, 0x28, 0x06, +0xf0, 0x0d, 0xba, 0x7b, 0xf0, 0x59, 0xcc, 0x34, +0xaf, 0x45, 0xe9, 0x6c, 0x3b, 0x00, 0xc3, 0x26, +0x1a, 0xd0, 0xe1, 0x2b, 0x61, 0xe4, 0x5b, 0x2d, +0xd6, 0xbd, 0xba, 0x66, 0x68, 0x31, 0x8b, 0xdd, +0x35, 0x02, 0xfd, 0xe0, 0xc0, 0x90, 0x58, 0xce, +0x11, 0x64, 0xdc, 0x1f, 0xd9, 0x62, 0xcf, 0x1b, +0x75, 0xfe, 0x4d, 0x8b, 0x4e, 0xf0, 0x15, 0x00, +0x20, 0xd9, 0xea, 0xb8, 0xcb, 0x5d, 0x30, 0x7c, +0x2a, 0x11, 0x5d, 0xc0, 0xcc, 0x7d, 0xb6, 0x3d, +0x1c, 0xba, 0xf6, 0x06, 0xd0, 0x35, 0xcd, 0x04, +0x00, 0x21, 0x74, 0x1f, 0xab, 0x4a, 0x27, 0xb3, +0x08, 0xcb, 0x16, 0x5b, 0x26, 0x59, 0xac, 0xd9, +0xc6, 0x07, 0xba, 0x8e, 0x18, 0x6b, 0xfe, 0x9f, +0xae, 0x85, 0xa4, 0x33, 0x4c, 0xa6, 0x03, 0x2d, +0x75, 0x95, 0x30, 0xe2, 0x18, 0x06, 0x14, 0x09, +0x23, 0x7f, 0xfd, 0x13, 0x77, 0xb7, 0x95, 0xcf, +0x5b, 0xd2, 0x04, 0xa2, 0x02, 0xc9, 0x62, 0xcd, +0x72, 0xe7, 0x15, 0x0d, 0xf7, 0xb7, 0xd6, 0xc6, +0xd5, 0xa6, 0x06, 0x91, 0x29, 0x45, 0x9e, 0x21, +0x92, 0x2d, 0x47, 0xdc, 0x58, 0x2d, 0xec, 0xaf, +0xf1, 0x37, 0x55, 0xaf, 0x09, 0x7b, 0x9b, 0xea, +0xc3, 0x3e, 0x8f, 0xd7, 0x99, 0x91, 0x9b, 0x9d, +0x36, 0x72, 0xc2, 0x99, 0x8e, 0xcc, 0x61, 0x67, +0x00, 0x80, 0xc5, 0xee, 0x3e, 0xab, 0xe4, 0x9c, +0xeb, 0xef, 0x26, 0xa2, 0xc7, 0xfb, 0xe2, 0x02, +0x3e, 0xed, 0xae, 0x25, 0x97, 0x03, 0x64, 0x12, +0xcf, 0xc1, 0x96, 0xea, 0x4f, 0xb4, 0xb0, 0xbf, +0xc3, 0x96, 0x9e, 0x57, 0xa2, 0x2b, 0xa1, 0xb6, +0x83, 0xab, 0xfe, 0xf6, 0xb2, 0xd5, 0x9d, 0x2e, +0x8f, 0xbb, 0xf4, 0xce, 0x57, 0x00, 0x80, 0x85, +0xde, 0x89, 0xe3, 0x48, 0x32, 0x03, 0x51, 0xc3, +0xd5, 0x73, 0x70, 0xfb, 0x7e, 0x18, 0x81, 0x2c, +0x03, 0x8a, 0x84, 0xae, 0xe7, 0x33, 0xa1, 0x82, +0x80, 0x02, 0x00, 0x48, 0x2f, 0x99, 0x38, 0xce, +0xdf, 0x5a, 0x6b, 0x43, 0x1c, 0x63, 0x1b, 0x11, +0x4a, 0x8e, 0x68, 0x5f, 0xe8, 0x4a, 0xf0, 0x70, +0xd3, 0xda, 0xb6, 0x6f, 0xbf, 0xfe, 0xbc, 0x79, +0xe7, 0xea, 0xbd, 0x00, 0x3a, 0x26, 0x5d, 0xf7, +0xab, 0xd9, 0xf6, 0xec, 0x61, 0xf3, 0x00, 0xa8, +0x5a, 0xc8, 0xbf, 0x3a, 0xe4, 0x69, 0xaa, 0x75, +0x64, 0x15, 0x5c, 0x03, 0x00, 0x99, 0x25, 0x27, +0xff, 0x08, 0xc0, 0xab, 0x44, 0xd4, 0xd8, 0x5b, +0xbf, 0x80, 0xd0, 0xe9, 0x16, 0x73, 0x58, 0xf1, +0x35, 0x54, 0xbd, 0x63, 0xcf, 0xcc, 0x9f, 0xe0, +0x1c, 0x56, 0x32, 0x1a, 0x80, 0x15, 0x2c, 0x82, +0x23, 0x4f, 0xbf, 0xf4, 0x73, 0x7b, 0x66, 0xe1, +0x3f, 0xba, 0xce, 0xd7, 0x7c, 0x00, 0x94, 0xee, +0xda, 0x3a, 0x63, 0xee, 0x93, 0xe3, 0x21, 0x45, +0x7c, 0x15, 0x9a, 0xd2, 0xee, 0x6b, 0xd8, 0x7f, +0x18, 0xc0, 0xe1, 0x81, 0xf6, 0x55, 0x24, 0xd6, +0xbd, 0x0b, 0xae, 0x30, 0xcb, 0xae, 0xbc, 0x91, +0xc5, 0x00, 0x32, 0xe3, 0x5b, 0xb9, 0xa2, 0x68, +0x48, 0xb5, 0x10, 0xba, 0xef, 0xe0, 0xaa, 0xbf, +0x3e, 0xb4, 0xfb, 0xf5, 0x47, 0x9e, 0x6c, 0xde, +0xb9, 0xfa, 0x63, 0x00, 0x9f, 0x03, 0xf8, 0xc4, +0x91, 0x53, 0x30, 0x82, 0x20, 0x15, 0x12, 0x49, +0x65, 0x16, 0xbb, 0xfb, 0x46, 0x4d, 0x55, 0x6a, +0xc0, 0xac, 0x00, 0x80, 0x2d, 0x2d, 0x7b, 0x6a, +0x56, 0xe9, 0xe4, 0x99, 0xe8, 0xc3, 0x10, 0x44, +0x44, 0x51, 0x49, 0x6d, 0xda, 0xb1, 0x6a, 0x65, +0xa0, 0xa5, 0xfa, 0x19, 0xa1, 0x69, 0x1e, 0xa1, +0xab, 0x1d, 0x81, 0xb6, 0xfa, 0xaf, 0x2a, 0x3f, +0x7a, 0xe1, 0x90, 0xea, 0x6d, 0x1d, 0x15, 0xed, +0x9f, 0xae, 0xf8, 0x71, 0x0c, 0xf2, 0x85, 0xac, +0x5f, 0x69, 0x96, 0xd5, 0xce, 0xc3, 0xdf, 0xc2, +0x88, 0x29, 0xec, 0xd3, 0x7e, 0x84, 0xde, 0x20, +0xb1, 0x91, 0x3c, 0x8c, 0x0a, 0xf3, 0x36, 0xdb, +0x33, 0xf2, 0x8a, 0x01, 0x64, 0xc2, 0x58, 0xdc, +0xe9, 0x5b, 0x73, 0xac, 0x57, 0x98, 0xcb, 0xde, +0x61, 0x4f, 0xcb, 0xd6, 0xf6, 0x7d, 0x9b, 0xab, +0x00, 0xac, 0x02, 0xd0, 0x61, 0xaa, 0xf2, 0x99, +0xff, 0xba, 0xe0, 0x2e, 0x3f, 0xe0, 0xb2, 0x3a, +0xdc, 0x67, 0x87, 0x3a, 0x5a, 0x77, 0x55, 0xbe, +0xfd, 0xf8, 0xba, 0x29, 0xb7, 0xfc, 0x6e, 0xa6, +0x64, 0x73, 0xcc, 0x04, 0x00, 0x47, 0xee, 0x88, +0xa9, 0x38, 0x54, 0xf1, 0x31, 0x22, 0x8b, 0x2a, +0xbd, 0xf8, 0xf5, 0xe8, 0xbd, 0x53, 0x7c, 0xed, +0xfe, 0xca, 0x8f, 0x96, 0xbd, 0x06, 0xe0, 0x75, +0x5b, 0x5a, 0xce, 0x4c, 0xc5, 0xd7, 0xae, 0x00, +0xa8, 0x4b, 0x1b, 0x39, 0x36, 0x1a, 0xf4, 0xa9, +0x87, 0xc3, 0x87, 0x71, 0x0c, 0xf2, 0x99, 0x8d, +0xe9, 0x20, 0x00, 0x78, 0x6b, 0x77, 0xaf, 0x83, +0xe1, 0xe3, 0x1f, 0x70, 0x5f, 0x45, 0x62, 0xd5, +0xbe, 0x10, 0x15, 0x24, 0x1b, 0xca, 0xc6, 0xea, +0x4c, 0x2f, 0x06, 0x90, 0x11, 0x4f, 0x7b, 0x12, +0x51, 0xd4, 0x93, 0x27, 0xc9, 0xb2, 0x03, 0x40, +0x23, 0x62, 0x88, 0x07, 0x80, 0xaf, 0xff, 0xf2, +0xb0, 0x97, 0x88, 0x6e, 0x84, 0xb1, 0xae, 0x50, +0x08, 0xa0, 0x99, 0xac, 0xf6, 0xdd, 0x00, 0x0c, +0xf2, 0x33, 0xf3, 0xf2, 0x01, 0xa4, 0x13, 0x51, +0xb0, 0x97, 0x6a, 0xb6, 0x1e, 0x91, 0x8d, 0x1f, +0xae, 0xbc, 0x91, 0x59, 0x81, 0xd6, 0x5a, 0x05, +0x40, 0xad, 0xe2, 0x6b, 0x7f, 0x03, 0x46, 0xe0, +0xa7, 0x46, 0x24, 0x9d, 0x6f, 0x9e, 0xac, 0x85, +0x3b, 0x5b, 0x61, 0x48, 0xf3, 0x11, 0xbf, 0x31, +0x7d, 0xfe, 0xd2, 0x89, 0x12, 0x30, 0x15, 0x30, +0x9c, 0x3b, 0xf5, 0x5b, 0x3e, 0xd9, 0x06, 0xa0, +0xa6, 0x17, 0xfd, 0xe8, 0x33, 0x12, 0xaa, 0xf6, +0x9d, 0x42, 0xdb, 0x85, 0xc8, 0xc5, 0x5b, 0xec, +0x6e, 0x53, 0xf2, 0xfb, 0xac, 0xf6, 0x45, 0x0c, +0xf9, 0x64, 0xb1, 0xd8, 0x61, 0xdc, 0xf4, 0x7f, +0x22, 0x90, 0x99, 0xc3, 0x00, 0x36, 0x03, 0xf8, +0x00, 0xc0, 0x46, 0x62, 0x1c, 0x34, 0x3f, 0xb3, +0xba, 0xb3, 0x87, 0xe1, 0x38, 0x56, 0xf8, 0xb1, +0xc0, 0x8c, 0x7a, 0xb3, 0x6c, 0x4f, 0xcb, 0xcb, +0x06, 0xe0, 0x88, 0x84, 0x78, 0x09, 0x66, 0x56, +0x99, 0x99, 0x21, 0x49, 0x45, 0xe6, 0x39, 0xaa, +0xbf, 0xb3, 0x0d, 0xdd, 0x68, 0x17, 0x62, 0x8e, +0x4a, 0x7d, 0xf0, 0x70, 0xd3, 0x06, 0x3d, 0xe4, +0xf7, 0x01, 0xe8, 0xb5, 0x0d, 0xd2, 0x17, 0x24, +0x94, 0xfc, 0x2f, 0x9f, 0x7f, 0xa0, 0x13, 0xcc, +0x35, 0x80, 0x61, 0x9d, 0xa7, 0x17, 0x9d, 0x54, +0x16, 0x4f, 0x7b, 0x24, 0x49, 0x5d, 0x37, 0x88, +0x89, 0x60, 0x68, 0xb2, 0x6e, 0x1f, 0xa6, 0x18, +0x62, 0x98, 0xa4, 0x2e, 0xf2, 0x6d, 0xce, 0xf4, +0x3e, 0x91, 0x4f, 0x12, 0xa2, 0x53, 0x15, 0x47, +0x6e, 0xe1, 0x08, 0x00, 0x8e, 0x6e, 0xec, 0x97, +0x91, 0x66, 0x41, 0xed, 0xf4, 0x74, 0x4f, 0x7e, +0x4c, 0x64, 0x93, 0xe7, 0xe0, 0x8e, 0xaf, 0x60, +0x84, 0xac, 0xc7, 0xbd, 0xe6, 0xd1, 0x13, 0x24, +0x7e, 0x8b, 0x36, 0x21, 0x6a, 0xf4, 0x65, 0x16, +0x4d, 0x1c, 0x87, 0x13, 0x6e, 0x76, 0x3c, 0x4e, +0x53, 0x7a, 0xd7, 0xb0, 0x21, 0x74, 0xb5, 0xc7, +0x06, 0x92, 0x8e, 0x2e, 0xf2, 0x25, 0x87, 0x2b, +0x1f, 0x80, 0xab, 0xb7, 0xbf, 0xcd, 0xcc, 0xab, +0xcd, 0xb2, 0x3b, 0xbf, 0x6c, 0x16, 0xba, 0x19, +0xc2, 0x98, 0xbb, 0x8c, 0x36, 0xb2, 0xc8, 0x16, +0x1c, 0x65, 0xc4, 0xcd, 0xb8, 0x6b, 0xe9, 0x4c, +0x44, 0x22, 0x76, 0x84, 0xa6, 0x1c, 0x6e, 0xd8, +0xfa, 0x49, 0x05, 0x12, 0xa4, 0xf2, 0x81, 0xc1, +0xd9, 0x9f, 0x1f, 0x0d, 0x76, 0x4c, 0x2b, 0x2c, +0x9b, 0x04, 0x20, 0xab, 0xef, 0x16, 0x3f, 0x67, +0x46, 0x8b, 0xba, 0x16, 0x84, 0x21, 0x31, 0x27, +0x54, 0x97, 0x12, 0xd3, 0x41, 0xb3, 0x6c, 0xb1, +0x3a, 0x4c, 0xc9, 0xef, 0x55, 0x1f, 0xb4, 0x80, +0xfa, 0x1e, 0x22, 0x92, 0x6c, 0x75, 0x65, 0x8c, +0xcf, 0x1e, 0x33, 0x65, 0xda, 0xd1, 0x6d, 0x10, +0x75, 0xf9, 0xf1, 0x2d, 0xce, 0xf4, 0xf4, 0x7f, +0xfa, 0x5c, 0x74, 0xa9, 0xfc, 0x40, 0x5b, 0xc3, +0x3a, 0xe8, 0x7a, 0x00, 0x40, 0x73, 0xa2, 0x96, +0xa3, 0x13, 0x4f, 0x3e, 0xd3, 0x2a, 0xb3, 0x68, +0xcf, 0xc8, 0x9b, 0x04, 0x60, 0x58, 0xdf, 0x1b, +0x13, 0x51, 0xf2, 0x75, 0x4d, 0x31, 0xb7, 0x5c, +0x9d, 0x10, 0xa3, 0x0f, 0x0f, 0xaf, 0x43, 0xc4, +0xbd, 0x4c, 0xc6, 0x9e, 0xbc, 0x5e, 0xab, 0xfd, +0xed, 0x2f, 0xdf, 0xe7, 0x67, 0x16, 0xef, 0x46, +0xaa, 0x94, 0x7b, 0xd2, 0xac, 0x1f, 0xe0, 0x68, +0x0d, 0x22, 0x84, 0x19, 0x99, 0x03, 0xd9, 0xee, +0xca, 0x04, 0x10, 0x0d, 0xe9, 0x9a, 0x33, 0xe7, +0x35, 0x19, 0xc0, 0x1c, 0xb3, 0xde, 0x5e, 0xb9, +0xf9, 0x2b, 0x18, 0x52, 0x3f, 0xe0, 0x31, 0x87, +0x26, 0x06, 0x41, 0xf2, 0x1d, 0xeb, 0x01, 0x0e, +0x02, 0x80, 0xc5, 0x91, 0x56, 0xe6, 0xcc, 0x2d, +0x1a, 0x8d, 0xbe, 0x1a, 0x7d, 0x44, 0x31, 0x6a, +0xbf, 0xe7, 0xe4, 0xd7, 0x16, 0xd5, 0xda, 0x60, +0x5e, 0xbb, 0x10, 0x21, 0xf4, 0x71, 0xe8, 0x91, +0x88, 0xff, 0x66, 0x96, 0xd3, 0x0b, 0x46, 0x5f, +0x04, 0x9b, 0xad, 0xf4, 0x08, 0x2d, 0x16, 0x23, +0xf9, 0x56, 0xbb, 0x23, 0x03, 0x91, 0xad, 0x69, +0x00, 0xb0, 0x3f, 0xbb, 0xf1, 0x42, 0x44, 0x1c, +0x5e, 0xba, 0x1a, 0x6c, 0x68, 0xa9, 0x58, 0x5d, +0x05, 0xa0, 0x26, 0x91, 0x41, 0x28, 0x09, 0x27, +0x7f, 0xd3, 0x33, 0x73, 0x55, 0x66, 0xfa, 0x0a, +0x00, 0x40, 0xa0, 0x61, 0x13, 0x4e, 0x9b, 0x89, +0x3e, 0x46, 0xac, 0x30, 0x53, 0xba, 0x59, 0x16, +0x6a, 0x54, 0xed, 0x9f, 0x10, 0x8a, 0x5f, 0x8e, +0x6a, 0x1b, 0xa1, 0x2a, 0x1d, 0x3d, 0xfd, 0xde, +0xd1, 0x08, 0xb6, 0x7b, 0x3f, 0x64, 0x16, 0x0d, +0x00, 0x20, 0xd9, 0x1c, 0x85, 0x65, 0x67, 0xcf, +0xb9, 0x19, 0x31, 0xf7, 0x54, 0x30, 0x45, 0x7d, +0x18, 0x92, 0xd5, 0x99, 0x8e, 0x18, 0xc9, 0x87, +0xd4, 0xa5, 0xf2, 0xfd, 0xcd, 0x35, 0x6b, 0x61, +0x04, 0xa0, 0x0c, 0xb8, 0x4b, 0x37, 0x16, 0x83, +0x94, 0x93, 0x47, 0xac, 0x32, 0x4b, 0xee, 0xfc, +0xd1, 0x93, 0x01, 0xe4, 0xf5, 0x65, 0xdc, 0x27, +0xea, 0x32, 0xb2, 0x58, 0x0b, 0x07, 0xd0, 0x43, +0xc9, 0x17, 0x24, 0x45, 0x23, 0x66, 0x84, 0xae, +0x74, 0xa0, 0x8f, 0x2e, 0xe6, 0x8a, 0xe5, 0x0f, +0x2b, 0xcc, 0x78, 0xcc, 0xac, 0x67, 0x15, 0x4f, +0xba, 0x11, 0x40, 0x71, 0xf4, 0x5a, 0x24, 0x8e, +0x4a, 0xbe, 0x64, 0xb5, 0x47, 0xd5, 0x7e, 0xf9, +0xbc, 0x65, 0x2e, 0x30, 0xae, 0x32, 0x3f, 0x6b, +0xfb, 0x66, 0x9d, 0xa9, 0xf2, 0x13, 0x1a, 0x84, +0x32, 0x28, 0xe4, 0x4b, 0x3a, 0x56, 0x99, 0xe5, +0xc8, 0xb8, 0x9f, 0x7f, 0xec, 0xb3, 0x8f, 0x03, +0xea, 0x52, 0xd7, 0x9a, 0x1a, 0x0e, 0xa3, 0x87, +0x12, 0x2c, 0x43, 0x74, 0x91, 0xaf, 0x84, 0x3d, +0x88, 0x6c, 0x0a, 0xed, 0x0b, 0x14, 0x4f, 0xc7, +0x32, 0x33, 0x5e, 0x4f, 0x76, 0xb8, 0x4a, 0x4a, +0xce, 0xbd, 0xe1, 0x56, 0x44, 0x86, 0x31, 0x89, +0xe5, 0x18, 0xc9, 0xb7, 0x66, 0xc0, 0x20, 0x9f, +0x40, 0xa1, 0xf9, 0x88, 0xcc, 0x0e, 0xb4, 0x90, +0x6f, 0x7f, 0xfb, 0xfe, 0x2d, 0xf5, 0x00, 0xaa, +0x13, 0x1d, 0x77, 0x38, 0x28, 0xe4, 0xb3, 0xec, +0xda, 0x60, 0x8e, 0xfb, 0xb2, 0xc3, 0x55, 0x9c, +0x51, 0x3a, 0xf1, 0x64, 0xf4, 0x61, 0xdc, 0x67, +0xd1, 0xa5, 0x46, 0x85, 0x12, 0x0a, 0xa1, 0x87, +0xe4, 0xb3, 0x10, 0xd1, 0x10, 0x72, 0x4d, 0x09, +0x7a, 0x60, 0x48, 0x7e, 0x9f, 0x6e, 0x7c, 0xc5, +0xf2, 0x87, 0x7d, 0x60, 0xb1, 0xc4, 0xac, 0x67, +0x8f, 0x9e, 0x72, 0x3b, 0x9c, 0xce, 0x22, 0x22, +0x22, 0x61, 0x95, 0xa2, 0xfd, 0x21, 0xc3, 0x0f, +0x61, 0x9f, 0x72, 0xf3, 0x7d, 0x4e, 0x00, 0x0f, +0x98, 0xc7, 0x3d, 0x07, 0x76, 0x7e, 0x00, 0x43, +0xdd, 0x27, 0x3c, 0xee, 0x70, 0x50, 0xc8, 0xdf, +0xf4, 0xcc, 0x5c, 0x95, 0x01, 0x73, 0x9e, 0x4c, +0x79, 0x27, 0xcd, 0x9a, 0x8d, 0x3e, 0x18, 0x5d, +0x44, 0x5d, 0xfe, 0x75, 0x92, 0x64, 0x0b, 0x7a, +0x1a, 0x17, 0x28, 0x49, 0xd7, 0x99, 0x45, 0x7f, +0xd3, 0xc1, 0x5d, 0x88, 0x73, 0x11, 0x85, 0x24, +0x75, 0x51, 0x34, 0x5a, 0xd7, 0xee, 0x2e, 0x1e, +0x73, 0xce, 0x0d, 0x3f, 0x05, 0x20, 0x41, 0xe3, +0x2e, 0xdb, 0x42, 0xa8, 0x01, 0x00, 0x64, 0x71, +0x8e, 0xbc, 0x03, 0xa6, 0xa1, 0x17, 0x0e, 0x36, +0x1c, 0xfa, 0xea, 0xb5, 0xb5, 0x30, 0xb6, 0xa4, +0x27, 0x3c, 0xee, 0x70, 0xf0, 0xf2, 0xf0, 0x09, +0xac, 0x30, 0x8b, 0x69, 0xc3, 0x4a, 0xce, 0x40, +0xcf, 0xa2, 0x5b, 0x8f, 0x46, 0x34, 0x9b, 0x85, +0x33, 0x67, 0x78, 0x19, 0x80, 0x13, 0x6e, 0x6e, +0x9c, 0x71, 0xf7, 0xa2, 0xb1, 0x00, 0xa6, 0x01, +0xa6, 0x2f, 0xfd, 0xe3, 0xed, 0x88, 0x63, 0x71, +0x09, 0x00, 0x36, 0x3d, 0xf3, 0x60, 0x07, 0x58, +0xfb, 0xbd, 0x59, 0xcf, 0x28, 0x3a, 0xf9, 0x47, +0xb6, 0xdc, 0x11, 0xe3, 0x64, 0x3d, 0x66, 0x78, +0xd1, 0x54, 0xbf, 0xdd, 0x95, 0x4d, 0x44, 0x52, +0x97, 0xd4, 0x1f, 0xda, 0xf1, 0x16, 0x74, 0xbd, +0x03, 0x09, 0xb6, 0xf2, 0x4d, 0x0c, 0x1a, 0xf9, +0xac, 0x05, 0xde, 0x42, 0x24, 0x40, 0xd1, 0xea, +0xce, 0x9a, 0x90, 0x3e, 0x62, 0x6c, 0xef, 0x55, +0x3f, 0xf3, 0x66, 0xb3, 0xe8, 0xc8, 0x2e, 0x9c, +0x82, 0x48, 0xf4, 0xeb, 0xf1, 0x40, 0x9a, 0x1c, +0x75, 0xa7, 0x86, 0x3c, 0x2d, 0x9b, 0xf5, 0x90, +0xdf, 0x8f, 0x7e, 0xd8, 0xc5, 0xdb, 0xae, 0xf9, +0x97, 0xb2, 0xd0, 0x0d, 0xcb, 0xdf, 0x6a, 0xcf, +0x2b, 0x39, 0xe3, 0x8a, 0x5f, 0x68, 0xac, 0x96, +0x99, 0x9f, 0x0b, 0x4d, 0xf1, 0x97, 0x5d, 0x74, +0xf3, 0x25, 0x88, 0x2c, 0x06, 0xe9, 0x4a, 0xa8, +0xa9, 0xe6, 0x8b, 0xd7, 0xbf, 0x84, 0xb1, 0x99, +0x34, 0x61, 0x73, 0xfb, 0x58, 0x0c, 0x1a, 0xf9, +0x5b, 0x5e, 0xf8, 0x65, 0x0b, 0xb3, 0xf8, 0x12, +0x00, 0x40, 0x90, 0x73, 0x27, 0x9c, 0x79, 0x09, +0x62, 0xa7, 0x42, 0x3d, 0x80, 0x1c, 0x0a, 0xae, +0xe9, 0xf2, 0x19, 0xb8, 0x47, 0x95, 0x5d, 0x78, +0xf3, 0xf5, 0x38, 0xce, 0x03, 0x74, 0xc1, 0x82, +0x05, 0x16, 0x10, 0xe6, 0x99, 0x75, 0xcf, 0xa1, +0x8a, 0xb5, 0x30, 0x56, 0xe7, 0xe2, 0xf6, 0xa5, +0x1f, 0x78, 0xf1, 0xe1, 0x10, 0x0b, 0xfe, 0xb5, +0x59, 0x4f, 0x1f, 0x31, 0xf6, 0x06, 0x82, 0x88, +0xfe, 0x56, 0xd8, 0xef, 0xa9, 0x73, 0xe7, 0x97, +0xfe, 0x4b, 0xf4, 0xb7, 0x0f, 0xee, 0x7c, 0x4b, +0x37, 0x66, 0x1a, 0x09, 0x37, 0xf4, 0x4c, 0x0c, +0x6a, 0xfa, 0x55, 0x22, 0xbc, 0x61, 0x96, 0xd3, +0x0b, 0xcb, 0xce, 0x00, 0x30, 0xbc, 0x37, 0xaa, +0x7f, 0xfd, 0x4b, 0xbf, 0x6c, 0x13, 0x42, 0x5f, +0x6c, 0xd6, 0xb3, 0x4a, 0x4e, 0xb9, 0xdd, 0x9e, +0x31, 0x6c, 0xcc, 0xb1, 0xda, 0xf0, 0x35, 0x66, +0x5f, 0x8b, 0xc8, 0x62, 0x8b, 0xae, 0x84, 0x9a, +0xea, 0x37, 0x7c, 0xb0, 0x1d, 0x40, 0x75, 0x9f, +0x2f, 0xe0, 0x28, 0x6c, 0xf5, 0x7e, 0xfd, 0x92, +0xd0, 0xb5, 0xbd, 0x00, 0x20, 0xc9, 0x96, 0x34, +0xc9, 0x62, 0x9f, 0x02, 0x18, 0xf9, 0x86, 0xac, +0x8e, 0xf4, 0x1c, 0x92, 0x2d, 0x79, 0x00, 0xa0, +0xab, 0xa1, 0x96, 0x9a, 0xaf, 0x96, 0xaf, 0x81, +0x21, 0xf5, 0x03, 0x1a, 0x9e, 0x7d, 0x3c, 0x0c, +0x2a, 0xf9, 0x1a, 0xf1, 0x0a, 0x44, 0x0c, 0x1d, +0x6b, 0x5a, 0xf6, 0x29, 0xf6, 0x9c, 0xe1, 0xe3, +0x7a, 0xdb, 0x46, 0x40, 0xd7, 0xfe, 0x1f, 0x0b, +0xbd, 0x15, 0x00, 0x64, 0x9b, 0x3d, 0xbf, 0xe4, +0xdc, 0xeb, 0x7f, 0x89, 0x63, 0xc4, 0x29, 0x30, +0x23, 0x9a, 0x18, 0xa2, 0xb3, 0x6e, 0xdf, 0xc7, +0x80, 0xee, 0x45, 0x3f, 0x26, 0x6e, 0xe0, 0xe5, +0xcb, 0x75, 0x82, 0xb8, 0xf3, 0xe8, 0xe3, 0x8a, +0xaf, 0x6d, 0x9b, 0x3b, 0xaf, 0xf8, 0x22, 0xb3, +0xde, 0xb6, 0x67, 0xfd, 0xcb, 0xba, 0xa2, 0x78, +0x30, 0x80, 0xb9, 0x03, 0x7a, 0x82, 0x41, 0x25, +0x7f, 0xdb, 0xd3, 0xf7, 0xd6, 0x81, 0x79, 0x03, +0x00, 0x10, 0x49, 0xd6, 0x91, 0x33, 0x2e, 0xb9, +0x0a, 0xbd, 0xf4, 0xf6, 0xed, 0x79, 0xfe, 0x81, +0x4e, 0x21, 0xc4, 0xc3, 0x66, 0x3d, 0x63, 0xe4, +0xb8, 0x1f, 0x4d, 0xbe, 0xe9, 0xb7, 0xcf, 0x8d, +0xba, 0xe0, 0xb6, 0x23, 0x12, 0x20, 0x9e, 0x7e, +0xf7, 0xc2, 0x62, 0x00, 0x67, 0x01, 0x00, 0x98, +0xd5, 0xba, 0x0d, 0xef, 0xae, 0x86, 0xb1, 0xa1, +0xb3, 0x5f, 0xc7, 0xdb, 0x2d, 0xcf, 0xdd, 0xbf, +0x52, 0x28, 0xa1, 0x15, 0xb1, 0xc7, 0x64, 0x9b, +0x2b, 0xdf, 0xcc, 0xc1, 0xa7, 0x74, 0xb6, 0x6d, +0xad, 0x59, 0xbb, 0x62, 0x23, 0x80, 0x1d, 0x18, +0x44, 0xa9, 0x07, 0x86, 0x40, 0xd6, 0x6d, 0x06, +0x5e, 0x34, 0xcb, 0xe9, 0x23, 0xc7, 0x5f, 0x8a, +0x58, 0x0f, 0x59, 0x0f, 0x91, 0x55, 0xe5, 0x5b, +0x26, 0x74, 0x75, 0x67, 0xa4, 0x4a, 0xf6, 0xf4, +0xec, 0x5b, 0x72, 0x46, 0x4f, 0xda, 0x36, 0xe5, +0xb6, 0x05, 0xd1, 0xdd, 0x3c, 0x42, 0x93, 0xe7, +0x20, 0x62, 0x0f, 0x84, 0xbc, 0xad, 0x5b, 0x43, +0x9e, 0x26, 0x2f, 0x06, 0x40, 0xf2, 0x98, 0x99, +0x41, 0xf8, 0x69, 0x64, 0x4b, 0x1a, 0x00, 0xc0, +0xe2, 0x70, 0x97, 0x01, 0x86, 0xfa, 0xaf, 0xf9, +0x72, 0xc5, 0x9f, 0x61, 0xd8, 0x19, 0x75, 0x83, +0x29, 0xf5, 0xc0, 0x10, 0x20, 0x9f, 0xe0, 0xf9, +0x9f, 0xd8, 0x39, 0x72, 0xd1, 0xcc, 0x2b, 0xae, +0x41, 0x2f, 0xad, 0xfe, 0x95, 0x2b, 0x1f, 0xd6, +0x82, 0x6d, 0x6d, 0x17, 0x08, 0x2d, 0x14, 0x1d, +0xbf, 0xc9, 0x6a, 0x3b, 0xc9, 0x66, 0xcf, 0xda, +0x39, 0x7d, 0xee, 0xa2, 0x2f, 0x67, 0xcc, 0x5b, +0xfc, 0x08, 0x88, 0xa2, 0xfb, 0xe6, 0xbd, 0xd5, +0xbb, 0xbe, 0x84, 0x11, 0xf2, 0x15, 0xd7, 0xa6, +0x8d, 0x63, 0x61, 0xcb, 0xf3, 0x0f, 0xd4, 0xb3, +0xa2, 0x3c, 0x70, 0xf4, 0x71, 0x5f, 0x7d, 0xe5, +0xdb, 0x9e, 0xea, 0x8a, 0x7a, 0x00, 0xdb, 0x13, +0x91, 0x31, 0xe4, 0x44, 0x18, 0xf4, 0xf4, 0xab, +0x00, 0x30, 0x63, 0xee, 0xc2, 0x47, 0x48, 0xb2, +0x3c, 0x00, 0x00, 0xe1, 0x8e, 0xd6, 0x8d, 0x15, +0x7f, 0xff, 0xdd, 0xe5, 0xe8, 0xe5, 0x58, 0x7c, +0xda, 0x9d, 0x4b, 0x7e, 0xc2, 0x4c, 0x4b, 0x7b, +0x72, 0xae, 0xae, 0xab, 0x1e, 0x12, 0xfc, 0x8d, +0x6c, 0xb5, 0x2c, 0xda, 0xf4, 0xcc, 0xbd, 0x6f, +0xf4, 0xb7, 0x04, 0x96, 0xcf, 0x5b, 0x66, 0x25, +0x0a, 0x3e, 0xca, 0xa0, 0x7b, 0xcc, 0x63, 0x0c, +0xa1, 0x1d, 0xde, 0xb7, 0xf5, 0x45, 0xd6, 0xd5, +0x95, 0xb9, 0x23, 0x4e, 0xfa, 0x54, 0x76, 0xe7, +0xa6, 0xab, 0xb2, 0x5e, 0x4c, 0x40, 0x09, 0x09, +0x2e, 0x86, 0x24, 0x15, 0x91, 0xe1, 0xe8, 0x52, +0x15, 0x5d, 0xf9, 0xc3, 0xf6, 0x67, 0xef, 0x3b, +0xd0, 0x9f, 0x7d, 0xea, 0x0e, 0x43, 0x82, 0xfc, +0xa9, 0x77, 0x3c, 0x5a, 0x64, 0x95, 0x1c, 0x07, +0x41, 0x90, 0x19, 0x2c, 0x0e, 0xae, 0xfa, 0xdb, +0xf5, 0xed, 0xdf, 0xae, 0x5f, 0xd1, 0x53, 0xe9, +0x98, 0x71, 0xe7, 0xe3, 0x57, 0x11, 0xe3, 0x75, +0x44, 0x34, 0x99, 0xe2, 0x6d, 0xdd, 0xcc, 0x24, +0xc9, 0xf6, 0xb4, 0x9c, 0x53, 0x8e, 0xc8, 0x77, +0xdb, 0x0d, 0xb4, 0x50, 0xe7, 0x8b, 0xdb, 0x5f, +0xfa, 0xf5, 0x8f, 0xfb, 0x4b, 0x12, 0x2f, 0xb8, +0xed, 0xcf, 0x0e, 0x9f, 0xdd, 0xfb, 0x26, 0x03, +0xdf, 0xeb, 0x6b, 0x1b, 0xac, 0x69, 0x35, 0xad, +0x87, 0x76, 0x9d, 0x5f, 0xfd, 0xd9, 0x0b, 0x07, +0x06, 0x72, 0x68, 0x18, 0x74, 0xb5, 0x0f, 0x18, +0xf9, 0x68, 0x84, 0xd0, 0xdf, 0x04, 0x8c, 0x6c, +0x56, 0xf9, 0x13, 0x67, 0xdd, 0x8c, 0x1e, 0x06, +0x58, 0x9c, 0x3e, 0xf7, 0xf1, 0x33, 0x89, 0xf1, +0x0a, 0x22, 0xd7, 0xa2, 0xfa, 0x3c, 0xbb, 0xbe, +0x79, 0xe3, 0x8f, 0x8b, 0x2b, 0x5e, 0x59, 0xf0, +0xb3, 0xdd, 0x6f, 0xfe, 0xf1, 0xf2, 0xe6, 0x6f, +0xd6, 0x3c, 0x16, 0xea, 0x68, 0x3e, 0x66, 0x8a, +0x73, 0x8b, 0x23, 0xfd, 0xb6, 0x31, 0x17, 0xff, +0xf8, 0x27, 0xbd, 0x48, 0x9d, 0x72, 0x5c, 0x74, +0xda, 0xbc, 0xf7, 0xc4, 0x12, 0xaf, 0x85, 0x02, +0xb5, 0xac, 0x6b, 0xbd, 0xf2, 0xdb, 0x93, 0xc5, +0x52, 0x2c, 0x43, 0xbf, 0x13, 0x31, 0xeb, 0xff, +0x03, 0x81, 0xa1, 0xf3, 0xa6, 0x0d, 0xa1, 0x2f, +0x84, 0x2c, 0x5f, 0x0b, 0x00, 0xae, 0x61, 0xa5, +0xdf, 0x2f, 0x2a, 0xbf, 0xf4, 0x62, 0x22, 0x5a, +0x71, 0xbc, 0x27, 0xff, 0x8c, 0xb9, 0x4f, 0x8e, +0x17, 0x12, 0xde, 0x41, 0xe4, 0x26, 0xe9, 0xa1, +0x40, 0xf5, 0xde, 0xf7, 0x9f, 0xf8, 0x6f, 0x5d, +0x09, 0xd5, 0x02, 0x58, 0x17, 0x68, 0xa9, 0xd5, +0xc7, 0x5e, 0x36, 0x23, 0x64, 0xb5, 0xb9, 0x7e, +0x66, 0x7e, 0x47, 0x53, 0x02, 0xb5, 0xf5, 0x1b, +0x3f, 0xfc, 0x53, 0xfe, 0xa4, 0x73, 0x2e, 0x75, +0x64, 0xe5, 0x9f, 0x09, 0x00, 0x69, 0x23, 0xc6, +0xdc, 0x07, 0x60, 0x05, 0x11, 0xc5, 0x6f, 0x84, +0x11, 0x9d, 0x6f, 0xba, 0xe9, 0x3b, 0x6b, 0xf7, +0xbe, 0xb6, 0xf7, 0xfd, 0x27, 0x57, 0xa4, 0x15, +0x8c, 0x41, 0xe1, 0xb4, 0x0b, 0x2f, 0xb4, 0xa7, +0xe7, 0x8c, 0xb5, 0x38, 0xd3, 0x4b, 0x25, 0x9b, +0x63, 0x18, 0x6b, 0x6a, 0xa7, 0xd0, 0xc2, 0x6d, +0x5a, 0x38, 0xd0, 0x2e, 0x59, 0xec, 0x6e, 0x7b, +0x46, 0xee, 0x74, 0x44, 0x6c, 0x1d, 0x06, 0x8b, +0xb6, 0xbd, 0x1b, 0xab, 0x61, 0xec, 0xea, 0x1d, +0xb0, 0xe9, 0xe0, 0x90, 0x21, 0x7f, 0xcb, 0xf3, +0xf7, 0xad, 0x9b, 0x71, 0xc7, 0xc2, 0x35, 0x24, +0x5b, 0xce, 0x21, 0x92, 0xac, 0x79, 0x93, 0xcf, +0x79, 0xec, 0xf0, 0xa1, 0x6f, 0xbe, 0x82, 0x61, +0x98, 0xfd, 0x13, 0x66, 0xde, 0xb1, 0xa4, 0x40, +0x97, 0xe9, 0x23, 0x00, 0xb9, 0x00, 0x20, 0x54, +0xa5, 0xad, 0xf2, 0xd3, 0xe7, 0x1f, 0x0d, 0x79, +0x5a, 0xea, 0xf3, 0x4e, 0x3a, 0x6b, 0x73, 0xe9, +0x79, 0xd7, 0x5f, 0x4c, 0xc4, 0x37, 0x30, 0x70, +0x15, 0x22, 0xb9, 0x01, 0xd4, 0x60, 0x67, 0xd5, +0xee, 0x37, 0x1e, 0xf9, 0x9d, 0xea, 0xef, 0x6c, +0x02, 0x4b, 0xaf, 0x96, 0x9c, 0x7d, 0xe5, 0x3e, +0x80, 0x60, 0xb1, 0xb9, 0x8a, 0x64, 0x57, 0xfa, +0x34, 0x3d, 0xd0, 0x59, 0x8f, 0x38, 0x17, 0x58, +0x08, 0x3c, 0xc9, 0x6c, 0xa0, 0x71, 0xeb, 0xa7, +0xab, 0x00, 0x54, 0xf8, 0x9a, 0xaa, 0x76, 0x57, +0x7e, 0x54, 0xf5, 0x0e, 0x8c, 0xed, 0xe4, 0xd9, +0x30, 0x42, 0xd6, 0xdd, 0x59, 0x25, 0x93, 0xd2, +0x47, 0xce, 0xba, 0xfc, 0x0a, 0x5b, 0x46, 0xce, +0xd9, 0x30, 0x8d, 0x5c, 0x06, 0x1f, 0xae, 0xda, +0xf2, 0x82, 0xb7, 0xfa, 0x9b, 0x26, 0xc4, 0x99, +0x91, 0xf4, 0x44, 0x18, 0x32, 0xe4, 0x03, 0x80, +0x06, 0x71, 0xab, 0x45, 0x88, 0x0a, 0x92, 0x24, +0x97, 0x6c, 0x77, 0x95, 0x95, 0x9e, 0x77, 0xed, +0x52, 0x22, 0xba, 0xe9, 0xe8, 0x9d, 0xb4, 0x53, +0x6f, 0x79, 0xcc, 0x6d, 0x75, 0xd9, 0xde, 0x47, +0x24, 0xfd, 0x1a, 0x0b, 0x3d, 0x50, 0xb3, 0xe6, +0xd5, 0x47, 0xd2, 0x86, 0x8f, 0x76, 0x8e, 0xbf, +0x74, 0xfe, 0xf5, 0x24, 0x5b, 0x5f, 0x01, 0x38, +0x27, 0xf6, 0xae, 0xe9, 0x4a, 0xb8, 0xb9, 0xf2, +0xa3, 0xe7, 0xfe, 0xa8, 0xfa, 0x3b, 0xeb, 0x00, +0x7c, 0x51, 0x76, 0xfa, 0x0f, 0x0b, 0x84, 0x39, +0xa9, 0x20, 0x90, 0x33, 0xb3, 0x70, 0x84, 0x2f, +0xd0, 0x29, 0x23, 0x8e, 0x79, 0xff, 0xcc, 0x7f, +0x5f, 0x9a, 0xc1, 0x66, 0xbe, 0x00, 0x80, 0x33, +0x4a, 0x4e, 0x2e, 0x19, 0x71, 0xd6, 0xe5, 0xe9, +0xe9, 0xee, 0xfc, 0x61, 0xba, 0xcb, 0x92, 0xc6, +0x2a, 0x86, 0x03, 0x18, 0x2e, 0x11, 0x4d, 0x04, +0x49, 0x97, 0x21, 0xb2, 0xc0, 0x64, 0x82, 0x85, +0x50, 0xda, 0xf6, 0x6e, 0x78, 0xee, 0xd0, 0xea, +0xbf, 0xad, 0x06, 0xb0, 0x05, 0x46, 0x8a, 0x99, +0x01, 0xc3, 0x90, 0x22, 0x7f, 0xfb, 0xb3, 0xf7, +0x1d, 0x98, 0x7a, 0xeb, 0xef, 0x7f, 0x66, 0x75, +0xa6, 0x3d, 0x0b, 0x00, 0xce, 0x9c, 0xe2, 0x6b, +0x46, 0xcd, 0xfe, 0xd7, 0x5b, 0x89, 0xe8, 0x05, +0xd3, 0x20, 0x8b, 0x10, 0xff, 0x26, 0x80, 0x19, +0x00, 0x00, 0x66, 0xd5, 0x5b, 0xbb, 0xe7, 0xad, +0xa2, 0x73, 0xae, 0xbb, 0x47, 0xb6, 0x3a, 0x46, +0x74, 0xd7, 0xae, 0x16, 0xf4, 0x55, 0x1e, 0xfa, +0xf2, 0xd5, 0x27, 0x03, 0xcd, 0x07, 0x6b, 0x01, +0xac, 0x9b, 0x31, 0x77, 0x49, 0xa1, 0x20, 0x7c, +0x72, 0xe4, 0x59, 0x02, 0x30, 0x1c, 0x4c, 0x7d, +0xde, 0xb2, 0x2d, 0x42, 0xfa, 0x68, 0x48, 0x86, +0xe9, 0x40, 0x00, 0x15, 0x4c, 0x9d, 0xfd, 0x20, +0x80, 0x07, 0x05, 0x00, 0xd2, 0x71, 0xac, 0xb7, +0x00, 0x00, 0x00, 0x42, 0x1d, 0x2d, 0x1b, 0x6a, +0xd6, 0xae, 0xf8, 0x8b, 0xb7, 0xfa, 0x9b, 0x7a, +0x18, 0xc4, 0x1f, 0x1c, 0x68, 0x3f, 0xc0, 0x90, +0x22, 0x1f, 0x00, 0x76, 0xbc, 0xfc, 0xd0, 0xf3, +0xa7, 0xde, 0xf6, 0xc8, 0x15, 0xb2, 0xcd, 0x71, +0x19, 0x08, 0x94, 0x3d, 0x66, 0xfa, 0x12, 0x77, +0x7e, 0xa9, 0x6b, 0xdc, 0xa5, 0xff, 0xfe, 0x4c, +0x7a, 0xc9, 0xb8, 0x31, 0x36, 0x97, 0xf5, 0x25, +0x8e, 0x66, 0xd5, 0x06, 0x1f, 0xde, 0xbf, 0xfd, +0x2f, 0x59, 0xa3, 0xa7, 0xdc, 0x74, 0xf4, 0x1b, +0x37, 0xf4, 0x70, 0xa0, 0xce, 0xdf, 0x5a, 0xbb, +0xae, 0x6d, 0xcf, 0xda, 0x75, 0x91, 0x0c, 0x5d, +0x6d, 0x00, 0x36, 0x4e, 0xff, 0xf1, 0xa2, 0x12, +0x18, 0xc4, 0x17, 0x1d, 0xfd, 0xdb, 0xf1, 0x42, +0x10, 0xca, 0x7a, 0x73, 0x3e, 0xb3, 0x08, 0x2b, +0xde, 0xc3, 0xbb, 0xda, 0x2a, 0x37, 0x7e, 0xd8, +0xb0, 0xe9, 0xc3, 0x9d, 0x30, 0xf2, 0x12, 0xee, +0x00, 0xe0, 0x4b, 0x84, 0x03, 0x68, 0xc8, 0x91, +0xcf, 0xcc, 0x3c, 0x79, 0xce, 0x82, 0x5b, 0x29, +0xd3, 0xb2, 0x5b, 0x92, 0x2d, 0xf9, 0x24, 0xc9, +0x2e, 0x7b, 0x66, 0xfe, 0x12, 0x7b, 0x66, 0xfe, +0x42, 0x80, 0x65, 0xee, 0xf2, 0xff, 0xb0, 0xe7, +0xc0, 0xb6, 0x97, 0x15, 0x9f, 0xa7, 0x39, 0x96, +0x78, 0x5d, 0x0d, 0x36, 0xb4, 0xec, 0x58, 0xf3, +0x62, 0xdd, 0xa6, 0xf7, 0x77, 0xc0, 0x78, 0x99, +0x42, 0x0d, 0x90, 0x55, 0x3b, 0xed, 0x8e, 0xdf, +0x4c, 0x95, 0x64, 0xf9, 0x31, 0x30, 0xae, 0x07, +0x60, 0x04, 0x7e, 0x32, 0x18, 0x14, 0x69, 0x50, +0x92, 0xe2, 0x4e, 0x16, 0xc1, 0xa0, 0x51, 0xd1, +0xd4, 0x2a, 0x21, 0xdf, 0x01, 0x5d, 0x09, 0xb7, +0xcb, 0x36, 0x7b, 0x36, 0x59, 0x6c, 0x59, 0xd0, +0xf5, 0xb0, 0xae, 0x2b, 0x1e, 0x56, 0x15, 0x8f, +0x16, 0xf2, 0xb7, 0xf9, 0xea, 0xf7, 0xef, 0x6a, +0xda, 0xb1, 0x72, 0x97, 0x1a, 0xf2, 0x06, 0x61, +0xe4, 0x11, 0xaa, 0x84, 0xe1, 0xdb, 0x48, 0x98, +0xf3, 0x67, 0xc8, 0x91, 0x0f, 0x18, 0xa9, 0xcc, +0x26, 0xdf, 0xf0, 0x9b, 0x8b, 0xad, 0xae, 0xb4, +0x77, 0x64, 0x9b, 0xc3, 0xdc, 0x83, 0x7f, 0xc4, +0xfb, 0x69, 0xda, 0xf6, 0xad, 0x5f, 0x76, 0x70, +0xe5, 0x2b, 0xab, 0x32, 0x4b, 0x26, 0x54, 0x15, +0x4c, 0x39, 0xef, 0x5e, 0x10, 0xd9, 0x00, 0x40, +0xb6, 0x3a, 0x87, 0x17, 0xce, 0xb8, 0xf8, 0x57, +0x05, 0xd3, 0x2f, 0x6a, 0x06, 0x49, 0xad, 0x11, +0xc7, 0x49, 0x26, 0x80, 0x9c, 0x58, 0x53, 0x8e, +0x75, 0xcd, 0xcf, 0x2c, 0x14, 0xc9, 0x62, 0xcb, +0xee, 0xaf, 0x7e, 0x13, 0x51, 0x34, 0xd7, 0x6e, +0x67, 0x7d, 0xd5, 0xea, 0xfd, 0x9f, 0xbe, 0xf0, +0x2a, 0x8c, 0x8d, 0x1d, 0x8e, 0xc8, 0x9f, 0x06, +0x23, 0x64, 0x2c, 0x14, 0x39, 0xde, 0x02, 0x23, +0x90, 0x44, 0x03, 0x7a, 0xfe, 0x62, 0x89, 0xfe, +0xc2, 0x90, 0x24, 0x1f, 0x00, 0x2a, 0xfe, 0xfe, +0x5f, 0xdb, 0xf3, 0x27, 0x9f, 0x7e, 0x46, 0xde, +0x49, 0xe7, 0x2d, 0xb2, 0x67, 0xe6, 0x9d, 0x2d, +0xdb, 0x9c, 0x23, 0x59, 0xe8, 0xa1, 0xb0, 0xb7, +0x75, 0x6b, 0xcb, 0x9e, 0x75, 0x1f, 0x35, 0x6f, +0x5f, 0xb9, 0x07, 0xc0, 0xe6, 0x8e, 0xea, 0x3d, +0x07, 0x75, 0x25, 0x70, 0x95, 0x64, 0xb1, 0x2f, +0x8f, 0xcd, 0xce, 0x41, 0x46, 0x84, 0x6e, 0xb7, +0x81, 0xa1, 0x5a, 0xc8, 0x7f, 0xb0, 0xf6, 0xeb, +0x77, 0x9e, 0x2e, 0x39, 0xeb, 0xea, 0x7b, 0xbb, +0x8e, 0x72, 0x7f, 0xe4, 0xb9, 0x2d, 0x33, 0x0b, +0x4a, 0x67, 0x7b, 0x33, 0x8c, 0x8c, 0xe2, 0xfb, +0xba, 0x39, 0x2f, 0x4a, 0xf2, 0x60, 0xfa, 0xf7, +0x87, 0x2c, 0xf9, 0x00, 0xd0, 0x5c, 0xb1, 0xa1, +0x91, 0x88, 0x6e, 0x05, 0x30, 0xc1, 0xe6, 0xca, +0x1a, 0xa5, 0x87, 0x03, 0x2e, 0x5d, 0x57, 0xc2, +0x30, 0x72, 0xed, 0x55, 0x02, 0x68, 0x65, 0x66, +0x26, 0xa2, 0x0f, 0x73, 0x27, 0x9f, 0x7b, 0x5a, +0x76, 0xd1, 0x84, 0x9f, 0xbb, 0x86, 0x15, 0x9d, +0x6d, 0x71, 0xa4, 0x95, 0x90, 0x24, 0x1f, 0xb1, +0x7b, 0x46, 0x68, 0xaa, 0x27, 0xd0, 0x56, 0xbf, +0xb6, 0x7d, 0xdf, 0x86, 0x35, 0x2d, 0xbb, 0xbe, +0x3c, 0x00, 0xe0, 0x70, 0xd9, 0xb9, 0x37, 0x44, +0x63, 0xf7, 0xe4, 0x13, 0x47, 0x80, 0xf5, 0x04, +0x65, 0x66, 0x21, 0xd4, 0x56, 0xd7, 0x02, 0xc3, +0x5a, 0xe7, 0xc1, 0x5e, 0xc0, 0x39, 0x16, 0x86, +0x34, 0xf9, 0x00, 0xc0, 0xcc, 0x0a, 0x11, 0xed, +0x54, 0x02, 0x9e, 0x0a, 0x18, 0xaa, 0x5f, 0x00, +0x10, 0xb1, 0x37, 0x34, 0xf2, 0x00, 0xec, 0x69, +0xab, 0xf8, 0xe2, 0xa7, 0x30, 0xde, 0x74, 0x59, +0x94, 0x3e, 0x62, 0x6c, 0xa9, 0x6c, 0x77, 0xb8, +0xf5, 0x80, 0x3f, 0x1c, 0x0a, 0x78, 0xc3, 0x6a, +0x67, 0x9b, 0xa9, 0x6e, 0xab, 0x23, 0x7f, 0x87, +0x41, 0x92, 0x7e, 0xd4, 0xb4, 0x3e, 0x5e, 0xe9, +0x2f, 0x33, 0x0b, 0x1d, 0xf5, 0xfb, 0x5a, 0x10, +0xe7, 0x0b, 0x24, 0x06, 0x1a, 0x43, 0x9e, 0x7c, +0xe0, 0x88, 0x77, 0xdc, 0x1c, 0xef, 0xdd, 0x35, +0x0c, 0x20, 0x44, 0x44, 0x7b, 0x01, 0xec, 0xeb, +0xac, 0xaf, 0x04, 0x8c, 0x71, 0x56, 0x86, 0xb1, +0x6e, 0xae, 0x45, 0xfe, 0xa2, 0x92, 0x58, 0x3e, +0xff, 0xf1, 0xae, 0x07, 0x48, 0x8a, 0x4f, 0xed, +0x4f, 0xbb, 0x6d, 0x71, 0x96, 0x6c, 0x97, 0x32, +0x01, 0x80, 0x85, 0xe6, 0x55, 0xfd, 0x1e, 0x73, +0x5c, 0x1f, 0xb2, 0xf8, 0x4e, 0x90, 0xdf, 0x1b, +0xc4, 0x3c, 0x28, 0xc0, 0x89, 0x6f, 0x7e, 0x8c, +0x54, 0xca, 0x71, 0x91, 0x6f, 0xb5, 0xa2, 0xcc, +0x7c, 0x32, 0x35, 0x25, 0xd4, 0x02, 0x63, 0xb9, +0x38, 0x21, 0xfb, 0xec, 0xfb, 0x8a, 0x21, 0xb1, +0xb0, 0xf3, 0xbf, 0x01, 0xb1, 0x73, 0x7c, 0x3d, +0x1c, 0x6c, 0x85, 0x91, 0x44, 0x71, 0x48, 0x23, +0xd9, 0xc9, 0xef, 0x92, 0x7c, 0x29, 0xbe, 0x5b, +0xc1, 0xa0, 0x68, 0xe6, 0x2d, 0x3d, 0xd4, 0xd9, +0x02, 0x43, 0xeb, 0x0c, 0xd9, 0xf1, 0x1e, 0x48, +0x76, 0xf2, 0xb9, 0xcb, 0x86, 0x90, 0x48, 0x3e, +0x66, 0x4a, 0x97, 0x9e, 0x20, 0x76, 0x8e, 0xaf, +0xf8, 0xbc, 0xcd, 0x48, 0x49, 0xfe, 0x50, 0x07, +0x47, 0x57, 0x0c, 0x1d, 0x59, 0xf9, 0x59, 0x88, +0xcf, 0xda, 0x2f, 0x33, 0x0b, 0x8a, 0xb7, 0xbd, +0x05, 0x29, 0xf2, 0x87, 0x3a, 0x38, 0x1a, 0xf3, +0x67, 0xcf, 0xc8, 0xcb, 0x43, 0x7c, 0xc1, 0x13, +0x65, 0x66, 0x21, 0xe0, 0xa9, 0x35, 0xd5, 0xfe, +0x90, 0x46, 0x72, 0x93, 0x4f, 0x74, 0xc8, 0x2c, +0xda, 0xdc, 0x59, 0x79, 0x00, 0x5c, 0x71, 0x64, +0x04, 0x2d, 0x33, 0x0b, 0x9d, 0x75, 0x55, 0xad, +0x18, 0xe2, 0x73, 0x7c, 0x20, 0xd9, 0xc9, 0x8f, +0xa4, 0x85, 0x03, 0x00, 0x8b, 0x3b, 0x3d, 0x17, +0x7d, 0xc8, 0xca, 0x05, 0x18, 0x2f, 0x8b, 0x84, +0xb1, 0x7e, 0x00, 0xd6, 0xd4, 0xef, 0xc4, 0x1c, +0x1f, 0x48, 0x72, 0xf2, 0x49, 0x74, 0x49, 0xbe, +0xc5, 0xe6, 0xcc, 0x43, 0x1f, 0xc9, 0xb7, 0x0b, +0x75, 0x96, 0x59, 0xd6, 0x94, 0x60, 0x03, 0xbe, +0x03, 0x73, 0x7c, 0x20, 0xc9, 0xc9, 0x87, 0xe8, +0xda, 0xa7, 0x27, 0xd9, 0x1c, 0x7d, 0x26, 0x9f, +0x89, 0x2f, 0x31, 0xcb, 0x21, 0x4f, 0xd3, 0x2e, +0x0c, 0xf2, 0x0b, 0x9e, 0x7a, 0x8a, 0xa4, 0x26, +0xdf, 0x9a, 0x29, 0xa2, 0xe4, 0xcb, 0x56, 0x87, +0xa9, 0xf6, 0x7b, 0x35, 0xe6, 0x13, 0x81, 0xc0, +0xf4, 0x7d, 0xb3, 0xee, 0xad, 0xde, 0x6d, 0xee, +0xf7, 0x1f, 0xd2, 0xe3, 0x3d, 0x90, 0xe4, 0xe4, +0xaf, 0x5d, 0x78, 0x6f, 0x10, 0x91, 0x00, 0x51, +0x92, 0x64, 0x57, 0xc1, 0xb4, 0x8b, 0x4e, 0xed, +0x6d, 0x1b, 0xe5, 0xf3, 0x96, 0xfc, 0x1b, 0x80, +0x71, 0x80, 0x11, 0x23, 0xd0, 0x52, 0xb1, 0xa6, +0x12, 0x09, 0xca, 0x9d, 0x1b, 0x2f, 0x92, 0x9a, +0x7c, 0x03, 0x1c, 0xdd, 0x54, 0x39, 0x6c, 0xe2, +0x59, 0xd7, 0x03, 0xc8, 0xeb, 0xe9, 0x37, 0xa7, +0xff, 0xf4, 0x89, 0x11, 0x0c, 0x7a, 0xc4, 0xac, +0xfb, 0x1a, 0xf6, 0x7f, 0xa0, 0x1b, 0xf9, 0x00, +0x07, 0xfc, 0x15, 0x29, 0xfd, 0x81, 0x14, 0xf9, +0xac, 0x2c, 0x64, 0x18, 0xa1, 0x53, 0xf6, 0xb4, +0x9c, 0x53, 0x4f, 0xbe, 0xfa, 0xbe, 0xdf, 0xf7, +0x64, 0x03, 0x47, 0xf9, 0xbc, 0xc5, 0x57, 0x4a, +0xaa, 0xd8, 0x8e, 0x48, 0xe8, 0xb8, 0x1e, 0x0e, +0xd6, 0x55, 0x7d, 0xfa, 0xfc, 0x3b, 0x30, 0x82, +0x37, 0x06, 0x75, 0xf7, 0x6d, 0x4f, 0x31, 0x24, +0xb6, 0x6b, 0x0d, 0x36, 0xa6, 0xdf, 0xfe, 0xc7, +0xc7, 0x24, 0xab, 0xfd, 0x17, 0x91, 0x2a, 0x2b, +0xfe, 0x8e, 0xd7, 0x6c, 0x92, 0xed, 0xfe, 0x4d, +0x2f, 0x3d, 0x78, 0x44, 0xe2, 0x86, 0xf2, 0x79, +0x8b, 0x87, 0x83, 0xa4, 0x2b, 0x98, 0x70, 0x0d, +0x31, 0x2e, 0xea, 0xfa, 0x84, 0xb5, 0xba, 0xf5, +0xef, 0xfd, 0xdf, 0xc6, 0x6d, 0x9f, 0x6d, 0x00, +0xf0, 0x59, 0x3c, 0x2f, 0x6d, 0x4a, 0x24, 0x52, +0xe4, 0x03, 0xa0, 0x39, 0x73, 0xe4, 0xa9, 0xae, +0xe9, 0xab, 0x2c, 0x0e, 0xd7, 0xd9, 0xd1, 0x83, +0xcc, 0x0a, 0x83, 0x37, 0x13, 0x49, 0x32, 0x8c, +0x90, 0x6e, 0x17, 0x8c, 0xb1, 0xfd, 0x08, 0x83, +0x50, 0x28, 0xa1, 0xc6, 0xba, 0x4d, 0x1f, 0x3c, +0xd5, 0xbc, 0x73, 0xf5, 0x6e, 0x00, 0x5f, 0x30, +0x73, 0x5c, 0xc9, 0x9d, 0x12, 0x89, 0x14, 0xf9, +0x11, 0x4c, 0x9e, 0xb3, 0x20, 0x47, 0x76, 0xca, +0xef, 0x59, 0x9d, 0x19, 0xb3, 0x4e, 0x7c, 0x36, +0x00, 0x66, 0x3d, 0xd0, 0x5a, 0xf3, 0x79, 0xe5, +0xc7, 0xcf, 0xff, 0x55, 0xf5, 0x7b, 0x5a, 0x00, +0x6c, 0x44, 0x24, 0xac, 0x6c, 0x40, 0x3b, 0xda, +0x8f, 0x48, 0x91, 0x1f, 0x03, 0x22, 0x72, 0x14, +0xcf, 0xbc, 0xf2, 0xb6, 0xac, 0xb1, 0xa7, 0xce, +0xb7, 0xb9, 0xb3, 0xa7, 0x1c, 0xfd, 0xb9, 0x11, +0x67, 0xdf, 0xb6, 0xd3, 0xd7, 0xb4, 0x7f, 0x63, +0xe3, 0xd6, 0x7f, 0x6c, 0x0a, 0x79, 0x9a, 0x3a, +0x01, 0xec, 0x07, 0xb0, 0x93, 0x23, 0x2f, 0x6d, +0xfa, 0x2e, 0x21, 0x45, 0xfe, 0x51, 0x88, 0x18, +0x7b, 0x79, 0xd9, 0xe3, 0xcb, 0x67, 0x5b, 0x6c, +0xce, 0x51, 0x1c, 0x0e, 0xa9, 0x9a, 0x1a, 0x56, +0x35, 0x25, 0xa0, 0x06, 0x5b, 0x6b, 0x3b, 0x74, +0x25, 0x14, 0x86, 0x31, 0x3d, 0xac, 0x83, 0x11, +0x48, 0x1a, 0xfe, 0x2e, 0x49, 0x7b, 0x2c, 0x52, +0xe4, 0x1f, 0x03, 0x91, 0x87, 0xc0, 0x0d, 0x63, +0xbc, 0x37, 0x5f, 0xfc, 0xac, 0xc3, 0x70, 0xdd, +0xea, 0xc0, 0xe0, 0x86, 0x5d, 0xf7, 0x07, 0x52, +0xe4, 0x27, 0x31, 0x52, 0xf3, 0xfc, 0x24, 0x46, +0x8a, 0xfc, 0x24, 0x46, 0x8a, 0xfc, 0x24, 0x46, +0x8a, 0xfc, 0x24, 0x46, 0x8a, 0xfc, 0x24, 0x46, +0x8a, 0xfc, 0x24, 0x46, 0x8a, 0xfc, 0x24, 0x46, +0x8a, 0xfc, 0x24, 0x46, 0x8a, 0xfc, 0x24, 0x46, +0x8a, 0xfc, 0x24, 0x46, 0x8a, 0xfc, 0x24, 0x46, +0x8a, 0xfc, 0x24, 0x46, 0x8a, 0xfc, 0x24, 0x46, +0x8a, 0xfc, 0x24, 0x46, 0x8a, 0xfc, 0x24, 0x46, +0x8a, 0xfc, 0x24, 0x46, 0x8a, 0xfc, 0x24, 0x46, +0x8a, 0xfc, 0x24, 0x46, 0x8a, 0xfc, 0x24, 0x46, +0x8a, 0xfc, 0x24, 0x46, 0x8a, 0xfc, 0x24, 0x46, +0x8a, 0xfc, 0x24, 0xc6, 0xff, 0x07, 0x4e, 0xdb, +0x8a, 0xd3, 0x88, 0xea, 0x3d, 0xd2, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *pgAdmin3_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_pgAdmin3_png = new wxImage(); + if (!img_pgAdmin3_png || !img_pgAdmin3_png->IsOk()) + { + wxMemoryInputStream img_pgAdmin3_pngIS(pgAdmin3_png_data, sizeof(pgAdmin3_png_data)); + img_pgAdmin3_png->LoadFile(img_pgAdmin3_pngIS, wxBITMAP_TYPE_PNG); + } + return img_pgAdmin3_png; +} +#define pgAdmin3_png_img pgAdmin3_png_img() + +static wxBitmap *pgAdmin3_png_bmp() +{ + static wxBitmap *bmp_pgAdmin3_png; + if (!bmp_pgAdmin3_png || !bmp_pgAdmin3_png->IsOk()) + bmp_pgAdmin3_png = new wxBitmap(*pgAdmin3_png_img); + return bmp_pgAdmin3_png; +} +#define pgAdmin3_png_bmp pgAdmin3_png_bmp() + +static wxIcon *pgAdmin3_png_ico() +{ + static wxIcon *ico_pgAdmin3_png; + if (!ico_pgAdmin3_png || !ico_pgAdmin3_png->IsOk()) + { + ico_pgAdmin3_png = new wxIcon(); + ico_pgAdmin3_png->CopyFromBitmap(*pgAdmin3_png_bmp); + } + return ico_pgAdmin3_png; +} +#define pgAdmin3_png_ico pgAdmin3_png_ico() + +#endif // PGADMIN3_PNG_H diff --git a/include/images/pgAdmin3.svg b/include/images/pgAdmin3.svg new file mode 100644 index 0000000..770c0da --- /dev/null +++ b/include/images/pgAdmin3.svg @@ -0,0 +1,54 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/include/images/plugins.png b/include/images/plugins.png new file mode 100644 index 0000000000000000000000000000000000000000..88c15dc89d1f957fe90f5b018af9ad1be62bdabe GIT binary patch literal 1457 zcmV;i1y1^jP)7e zsZx(rkHMB&m|kp}YkF-i+S9qHoNTYCfx^|oK7c>H>Bx7neMEjjfO9vZnQgzgnaszo z-`vc-ww7K_0rBeAwyS=gm1jPCJeJI$Gj=n&vyq*XV~~VSeQ+?GkzLu)v+(KC?&Zpu zi%@D?5_o7K5L*te*2!a-MZ%4vg6gM;L)L=k53w4 z79M3BDQ+lfsBo&|xoE3!8)F$jd_LXGn5dUmHEJcE$)m~b(xK3*v*EqB=fkk&zN6u@ zo!_pI*P(X7g>k=tf76xP$dIj?SVe9ugSLpn>&}+lsF2#DiP)Wj)|h*Toyk;|+MLMZbK)_+XojHAH5m&nL&4HC>d%SP=`*4d_$3XCoGaZ zfT(|KS__tZB7UZQKD%8OXc&KL7J+LO8+Rm0f=C!{9T#mJNTh~D00001bW%=J06^y0 zW&i*H32;bRa{vGUNB{r;NB~C3Yd!z~0q99YK~y-)V_={fU}R!u!6(nk#?HZs#OLDX zK~=!Z$1fm=;0g(gh>D@A5SNgYLhz(zWaZ?cYz0LnWfc`wHFXV5B=uU_Ixwc1uAaVu zfuWJHiK&{JnYk`R)WXsVuE5&Hmfz0a*u=rn$=Su#&B8*<-NM7u%iG7-*TMp%09oG8 zKOitDI3zU8D?B1HDmn(N09igZE*^aU8e#gIni&{czzU%DxBAqz1tqq_VU`}K63Qf@e^PL$nqyoojwDVKYQ-{i3?x_{ueJ@zH)W%wd*%-+`M_~_8lbo zyC4PkH18`tPo*n^Z{AeEQ;^!*cgP9w{qYZ|De~i| zO$S+#_!ghPpep#f>A*KW1o!)%A3sqQDE#`ZhQxjGrHY1 zO3(lR03~!qSaf7zbY(hYa%Ew3WdJfTF)%GLGA%GMR5CC+G&4FhH7hVRIxsMv?k=hT z001R)MObuXVRU6WZEs|0W_bWIFflMKFgYzSF;p@$Iy5voFg7bNH99ab%9mBF00000 LNkvXXu0mjfNq4QT literal 0 HcmV?d00001 diff --git a/include/images/plugins.pngc b/include/images/plugins.pngc new file mode 100644 index 0000000..8ebd2f6 --- /dev/null +++ b/include/images/plugins.pngc @@ -0,0 +1,227 @@ +#ifndef PLUGINS_PNG_H +#define PLUGINS_PNG_H + +static const unsigned char plugins_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x08, 0x03, 0x00, 0x00, 0x00, 0x44, 0xa4, 0x8a, +0xc6, 0x00, 0x00, 0x03, 0x00, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x93, 0x88, 0x55, 0x67, +0x58, 0x10, 0x82, 0x76, 0x3a, 0xd2, 0xcd, 0xb7, +0xaa, 0xa1, 0x79, 0xad, 0xa4, 0x7b, 0xf0, 0xec, +0xde, 0xc8, 0xc1, 0xa0, 0x6b, 0x5d, 0x16, 0xa6, +0xc2, 0xa5, 0x55, 0x8b, 0x54, 0x9a, 0xba, 0x99, +0xc0, 0xba, 0x9c, 0x9a, 0x8f, 0x5d, 0xf7, 0xf3, +0xe6, 0xe7, 0xe1, 0xcb, 0x66, 0x56, 0x0d, 0xaa, +0xc4, 0xa9, 0x52, 0x8f, 0x54, 0x8f, 0xc1, 0x96, +0x5a, 0x98, 0x5e, 0x6c, 0x9a, 0x6b, 0x7a, 0x6d, +0x2e, 0xda, 0xd3, 0xb9, 0xa8, 0x9c, 0x6c, 0xaf, +0xa8, 0x81, 0xc2, 0xd5, 0xc2, 0x3e, 0x80, 0x3f, +0xbd, 0xe9, 0xc8, 0x77, 0xb1, 0x7d, 0x44, 0x7e, +0x42, 0x80, 0x73, 0x37, 0xa2, 0x99, 0x6d, 0xbf, +0xb8, 0x99, 0xcc, 0xc7, 0xae, 0xdf, 0xdc, 0xcc, +0xbd, 0xb6, 0x96, 0x5e, 0x4e, 0x01, 0xf1, 0xea, +0xd6, 0xb6, 0xab, 0x7e, 0x9e, 0x95, 0x67, 0x3e, +0x7b, 0x3c, 0x96, 0xcc, 0xa0, 0x33, 0x76, 0x33, +0xba, 0xb3, 0x91, 0x9d, 0x93, 0x63, 0x90, 0x84, +0x4e, 0x7d, 0x70, 0x30, 0x9c, 0x91, 0x5d, 0xd9, +0xd0, 0xb3, 0xf0, 0xe9, 0xd2, 0xee, 0xe5, 0xca, +0x98, 0x8b, 0x50, 0x6a, 0x5b, 0x12, 0x78, 0x68, +0x21, 0x10, 0x5b, 0x0e, 0xae, 0xe3, 0xbc, 0x2d, +0x72, 0x2d, 0xfc, 0xfb, 0xf7, 0xfb, 0xf8, 0xf2, +0xf9, 0xf6, 0xec, 0xf5, 0xf0, 0xe0, 0xf3, 0xec, +0xd9, 0xeb, 0xe1, 0xc2, 0xe8, 0xdd, 0xba, 0xe6, +0xd9, 0xb2, 0xe3, 0xd5, 0xa9, 0xe0, 0xd1, 0xa1, +0xa0, 0x8f, 0x4f, 0x1a, 0x60, 0x16, 0x1e, 0x65, +0x1c, 0x29, 0x6e, 0x28, 0x69, 0xa8, 0x70, 0xaa, +0xe3, 0xb9, 0x68, 0xab, 0x70, 0x1b, 0x63, 0x19, +0x40, 0x7c, 0x3e, 0xdd, 0xcc, 0x98, 0xa8, 0x97, +0x57, 0x35, 0x6a, 0x25, 0x9e, 0xc9, 0xa3, 0xc9, +0xed, 0xd2, 0xa1, 0xd0, 0xaa, 0xb3, 0xe1, 0xbd, +0xb7, 0xe7, 0xc3, 0xb0, 0xe5, 0xbe, 0xa3, 0xe1, +0xb3, 0x9d, 0xdf, 0xae, 0x90, 0xd7, 0xa1, 0x76, +0xc1, 0x85, 0x71, 0xbf, 0x80, 0x7f, 0xd3, 0x95, +0xda, 0xc8, 0x90, 0xad, 0x9a, 0x58, 0x45, 0x6e, +0x2c, 0x83, 0xb6, 0x88, 0xc3, 0xeb, 0xce, 0x96, +0xdd, 0xa8, 0x90, 0xda, 0xa3, 0x89, 0xd8, 0x9d, +0x82, 0xd6, 0x98, 0x7c, 0xd4, 0x93, 0xcf, 0xc0, +0x8f, 0x95, 0x85, 0x45, 0x56, 0x50, 0x04, 0x68, +0x58, 0x0d, 0x9a, 0x88, 0x43, 0xab, 0x97, 0x52, +0x7b, 0xb1, 0x81, 0x75, 0xd2, 0x8d, 0x7e, 0x7d, +0x3a, 0x28, 0x67, 0x20, 0x28, 0x6d, 0x27, 0x5f, +0x78, 0x3b, 0x8a, 0x7d, 0x33, 0x24, 0x63, 0x1b, +0xa5, 0xd5, 0xae, 0x76, 0xc5, 0x87, 0x40, 0x8f, +0x48, 0x11, 0x5c, 0x0f, 0x18, 0x65, 0x18, 0x3f, +0x95, 0x4a, 0xb4, 0xa4, 0x6a, 0x31, 0x67, 0x20, +0x84, 0xb3, 0x87, 0xd5, 0xf1, 0xdc, 0xad, 0xd5, +0xb4, 0x5c, 0x97, 0x5f, 0x61, 0x9e, 0x66, 0x3f, +0x8e, 0x47, 0x97, 0xb8, 0x96, 0x64, 0x95, 0x63, +0x82, 0x77, 0x31, 0xcf, 0xef, 0xd7, 0xb7, 0xe4, +0xc1, 0x5c, 0xab, 0x69, 0x62, 0x93, 0x60, 0x91, +0xb4, 0x90, 0x73, 0x6d, 0x25, 0x34, 0x83, 0x3a, +0xb0, 0xc9, 0xb0, 0x8f, 0x7f, 0x39, 0x16, 0x5e, +0x13, 0xc2, 0xe8, 0xcb, 0x98, 0xcd, 0xa1, 0x50, +0x92, 0x54, 0x8d, 0xc9, 0x99, 0x2b, 0x7b, 0x30, +0xbe, 0xd3, 0xbe, 0xd8, 0xc4, 0x87, 0xc1, 0xac, +0x69, 0x39, 0x5e, 0x14, 0x5e, 0x9a, 0x62, 0x84, +0xba, 0x8b, 0x70, 0xac, 0x76, 0x36, 0x7b, 0x37, +0x4e, 0x63, 0x1e, 0x1d, 0x62, 0x19, 0x93, 0xd6, +0xa3, 0x38, 0x8d, 0x42, 0xd5, 0xbf, 0x7e, 0xd2, +0xbb, 0x76, 0x93, 0x81, 0x35, 0x43, 0x5d, 0x14, +0x3f, 0x6e, 0x2b, 0x41, 0x67, 0x22, 0x6c, 0x6d, +0x1c, 0x95, 0x7e, 0x27, 0x39, 0x6d, 0x29, 0x72, +0xba, 0x7e, 0x6f, 0xd0, 0x88, 0x5a, 0xbb, 0x70, +0xcf, 0xb7, 0x6d, 0xcd, 0xb3, 0x65, 0xc0, 0xa6, +0x54, 0x9d, 0x86, 0x33, 0xad, 0x92, 0x3b, 0xc2, +0xa4, 0x46, 0x92, 0x79, 0x22, 0x46, 0x74, 0x34, +0x63, 0xad, 0x6e, 0x68, 0xce, 0x83, 0x62, 0xcc, +0x7d, 0x36, 0x92, 0x42, 0x26, 0x6a, 0x25, 0x70, +0x9d, 0x6e, 0x48, 0x82, 0x47, 0x27, 0x86, 0x33, +0xca, 0xaf, 0x5d, 0xc7, 0xab, 0x55, 0xc5, 0xa7, +0x4d, 0xc0, 0xa0, 0x3f, 0x8a, 0x72, 0x1c, 0x4d, +0x7a, 0x3c, 0x5c, 0xca, 0x78, 0x56, 0xc8, 0x73, +0x4a, 0xbc, 0x66, 0x33, 0x9a, 0x45, 0x3a, 0xa9, +0x51, 0x40, 0xc0, 0x61, 0xbe, 0x9d, 0x39, 0x7d, +0x67, 0x11, 0x58, 0x84, 0x4b, 0x56, 0xa6, 0x62, +0x50, 0xc6, 0x6f, 0x4b, 0xc4, 0x6a, 0x45, 0xc2, +0x66, 0x3b, 0xbf, 0x5d, 0xa1, 0x8f, 0x4b, 0x8e, +0x7b, 0x33, 0x86, 0x73, 0x29, 0x8b, 0x78, 0x2c, +0xb8, 0xa0, 0x52, 0xb6, 0x9c, 0x47, 0x8a, 0x74, +0x21, 0x82, 0x6c, 0x19, 0x84, 0x6d, 0x16, 0x6f, +0x5c, 0x09, 0x5a, 0x89, 0x52, 0x56, 0xa9, 0x64, +0x36, 0xbd, 0x59, 0x84, 0x78, 0x3d, 0xa6, 0x9d, +0x73, 0xc8, 0xc3, 0xa8, 0x89, 0x75, 0x26, 0xc0, +0xa4, 0x4f, 0xbb, 0xb4, 0x93, 0xc6, 0xc1, 0xa5, +0xc4, 0xbe, 0xa2, 0x5f, 0x91, 0x5d, 0x1c, 0x69, +0x1d, 0x12, 0x5e, 0x11, 0x1a, 0x6a, 0x1d, 0x36, +0x97, 0x45, 0x2d, 0x8f, 0x3c, 0x14, 0x63, 0x15, +0xb5, 0x99, 0x41, 0x77, 0x69, 0x28, 0x19, 0x6a, +0x1b, 0x50, 0x87, 0x4e, 0x88, 0x7c, 0x43, 0x91, +0x7a, 0x27, 0x2c, 0x92, 0x3d, 0x80, 0xa8, 0x7f, +0x6b, 0x5a, 0x0b, 0x96, 0x7c, 0x22, 0x7e, 0xa6, +0x7d, 0x3e, 0xbb, 0x5d, 0x16, 0x68, 0x18, 0x7f, +0x6a, 0x16, 0x81, 0x6b, 0x15, 0x1b, 0x77, 0x24, +0x49, 0x82, 0x48, 0x18, 0x6e, 0x1d, 0x17, 0x6d, +0x1c, 0x48, 0xa4, 0x86, 0x44, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x01, 0xe8, 0x49, 0x44, 0x41, 0x54, 0x38, +0xcb, 0x63, 0x60, 0xa0, 0x1a, 0x60, 0x64, 0x62, +0x66, 0xc1, 0x27, 0xcf, 0xca, 0xc6, 0xce, 0xc1, +0x89, 0xc4, 0xe7, 0xe2, 0xe6, 0x41, 0x55, 0xc0, +0xcb, 0xc7, 0x2f, 0x20, 0x88, 0xe0, 0x0a, 0x09, +0x8b, 0x88, 0x8a, 0xa1, 0xaa, 0x10, 0x97, 0x90, +0x94, 0x42, 0xf0, 0xa4, 0x65, 0x64, 0xe5, 0xe4, +0xa1, 0x6c, 0x05, 0x45, 0x25, 0x65, 0x15, 0x15, +0x55, 0x35, 0x75, 0x0d, 0x4d, 0x24, 0xf5, 0x5a, +0xda, 0x3a, 0x30, 0xa6, 0x9a, 0xae, 0x9e, 0xbe, +0x81, 0x81, 0xa1, 0x91, 0xb1, 0x89, 0xa9, 0x9a, +0x9a, 0x99, 0xb9, 0x2e, 0x44, 0xd4, 0xc2, 0xd2, +0x0a, 0xae, 0xc0, 0xda, 0xc6, 0x96, 0xdf, 0xce, +0xde, 0xd8, 0xc4, 0xc1, 0xd1, 0xc9, 0xd9, 0xc5, +0xd5, 0xcd, 0xc2, 0x42, 0xcb, 0xdd, 0xc2, 0xc3, +0xd3, 0xcb, 0xdb, 0xc7, 0xd7, 0xd7, 0xc2, 0x02, +0xa4, 0x00, 0x59, 0xde, 0xcf, 0x3f, 0x20, 0x30, +0x28, 0x38, 0x24, 0x34, 0xcc, 0x2b, 0x3c, 0x22, +0x32, 0x2a, 0x3a, 0x06, 0xac, 0x00, 0x59, 0x3e, +0x36, 0x2e, 0x3e, 0x21, 0x51, 0x16, 0x2c, 0x9f, +0x94, 0x9c, 0x92, 0x9a, 0x06, 0x56, 0x00, 0x93, +0x4f, 0xcf, 0xc8, 0xcc, 0xca, 0xce, 0x89, 0xcf, +0x45, 0x92, 0xcf, 0x03, 0x2b, 0x80, 0xe9, 0xcf, +0x2f, 0x28, 0x74, 0x2b, 0x2a, 0x2e, 0x29, 0x85, +0xca, 0x97, 0x95, 0x57, 0x54, 0x56, 0x81, 0x15, +0x40, 0xe5, 0xab, 0x6b, 0x6a, 0xeb, 0xea, 0x1b, +0x2c, 0x1a, 0x61, 0xfa, 0x9b, 0x9a, 0x19, 0x18, +0x5a, 0xc0, 0x0a, 0xa0, 0xf6, 0xb7, 0xfa, 0xd4, +0xb5, 0x05, 0x25, 0xb6, 0xc3, 0xe4, 0x3b, 0x3a, +0x41, 0x5e, 0xec, 0x02, 0x29, 0x80, 0xba, 0xaf, +0xbb, 0x10, 0x28, 0x8f, 0xb0, 0xbf, 0xa7, 0x17, +0x1e, 0x0e, 0x50, 0xf7, 0xf7, 0xf5, 0x4f, 0x48, +0x94, 0x9d, 0x38, 0x69, 0x32, 0xd4, 0x7d, 0x53, +0xa6, 0xc2, 0x15, 0x40, 0xe4, 0xa7, 0x4d, 0x9f, +0x31, 0x73, 0xd6, 0xec, 0x39, 0x73, 0xe7, 0xcd, +0x87, 0xb8, 0x7f, 0x01, 0x3c, 0x36, 0xd5, 0x20, +0xf2, 0x0b, 0x17, 0x2d, 0x5e, 0xb2, 0x74, 0xd9, +0xf2, 0x15, 0x2b, 0x57, 0x81, 0xe5, 0x57, 0xaf, +0x29, 0x04, 0xca, 0x35, 0x83, 0x22, 0x44, 0x0d, +0x2a, 0xbf, 0x76, 0xdd, 0xfa, 0x0d, 0x1b, 0x37, +0x6d, 0xde, 0xb2, 0x15, 0x2c, 0xbf, 0x6d, 0xfb, +0x8e, 0x9d, 0xbb, 0x76, 0xef, 0x01, 0xfb, 0x02, +0x26, 0xbf, 0x77, 0xdf, 0xfe, 0x4d, 0x07, 0x0e, +0x1e, 0xea, 0x80, 0xc8, 0x1f, 0x3e, 0x72, 0xf4, +0xd8, 0xf1, 0x13, 0x60, 0x05, 0xc8, 0xf2, 0x27, +0x4f, 0x9d, 0x3e, 0x03, 0x95, 0x3f, 0x7b, 0xee, +0xfc, 0x89, 0x0b, 0x60, 0x05, 0xfe, 0x17, 0x2f, +0x5d, 0xbe, 0x72, 0x75, 0xef, 0xb5, 0xeb, 0x37, +0x6e, 0xdc, 0xbc, 0x79, 0xeb, 0xf6, 0x1d, 0x24, +0xf9, 0xbb, 0x20, 0x05, 0xf7, 0x34, 0xef, 0x2b, +0x3d, 0x50, 0x7a, 0xf8, 0xc8, 0xec, 0xf1, 0x93, +0xa7, 0x4a, 0x4a, 0x4a, 0xcf, 0x9e, 0xbf, 0xb0, +0xb0, 0x78, 0xf9, 0xea, 0xec, 0xeb, 0x37, 0x16, +0x15, 0x6f, 0xde, 0x54, 0xc0, 0x53, 0x90, 0xda, +0xdb, 0x77, 0xc8, 0x09, 0xf0, 0xfd, 0xf1, 0x0f, +0xa8, 0x29, 0xf2, 0xe3, 0xa7, 0x4d, 0x07, 0x59, +0x91, 0xf8, 0x16, 0x9f, 0xbf, 0xa0, 0x2a, 0xf8, +0xba, 0xe9, 0xc0, 0x37, 0x3e, 0x04, 0xf7, 0xfb, +0x9e, 0x1f, 0x3f, 0x51, 0x15, 0x28, 0xfc, 0xfa, +0xad, 0x86, 0xc4, 0x7d, 0xf1, 0xe3, 0xc2, 0x1f, +0xbc, 0xd9, 0xec, 0xef, 0xbf, 0xff, 0x56, 0x0c, +0x74, 0x03, 0x00, 0x6f, 0x3f, 0xeb, 0x4d, 0x72, +0x00, 0x4a, 0xd0, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *plugins_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_plugins_png = new wxImage(); + if (!img_plugins_png || !img_plugins_png->IsOk()) + { + wxMemoryInputStream img_plugins_pngIS(plugins_png_data, sizeof(plugins_png_data)); + img_plugins_png->LoadFile(img_plugins_pngIS, wxBITMAP_TYPE_PNG); + } + return img_plugins_png; +} +#define plugins_png_img plugins_png_img() + +static wxBitmap *plugins_png_bmp() +{ + static wxBitmap *bmp_plugins_png; + if (!bmp_plugins_png || !bmp_plugins_png->IsOk()) + bmp_plugins_png = new wxBitmap(*plugins_png_img); + return bmp_plugins_png; +} +#define plugins_png_bmp plugins_png_bmp() + +static wxIcon *plugins_png_ico() +{ + static wxIcon *ico_plugins_png; + if (!ico_plugins_png || !ico_plugins_png->IsOk()) + { + ico_plugins_png = new wxIcon(); + ico_plugins_png->CopyFromBitmap(*plugins_png_bmp); + } + return ico_plugins_png; +} +#define plugins_png_ico plugins_png_ico() + +#endif // PLUGINS_PNG_H diff --git a/include/images/primarykey.png b/include/images/primarykey.png new file mode 100644 index 0000000000000000000000000000000000000000..b57f59778554c3b0ee1b872a4174cbe631ee64e2 GIT binary patch literal 443 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMfD`Vm@3!4NRdR5F#O>qdUq7Aw{C>xWm$N>;n)Uh3 z;xBI(e|bIY^Q(!UUNnAw(e(Yp+IP=)e*Jjj^V^Ldo=^DrV#4P)3vM4z`1*Fitz!|N zUo?Mt)qC$u?bnY-Kfl}j@%4gFujk!8nS1w4)!Qd4-ac7$_f*mGm0D_V?`Q*^#aI&L z7tG-B>_!@p!&%@FSq!8-z}W3%wjGcW@9E+gB5^r6VF6b{N>Y-`Gvm!0Hf=0cIJvo? zsPOZLPmT=s%*?{88RjpTu%Tncj2$gYMC1b;qT2k!{Nfw~JtJL3mox?X#ySUk&+eD! zaI9ft8(Q1kei>9nN|tWU|090*aWnc!;aB6z!8lVOS MPgg&ebxsLQ07e(akpKVy literal 0 HcmV?d00001 diff --git a/include/images/primarykey.pngc b/include/images/primarykey.pngc new file mode 100644 index 0000000..2c6b06e --- /dev/null +++ b/include/images/primarykey.pngc @@ -0,0 +1,100 @@ +#ifndef PRIMARYKEY_PNG_H +#define PRIMARYKEY_PNG_H + +static const unsigned char primarykey_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x93, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xe0, 0xcf, 0x8b, 0xcb, +0xb0, 0x3e, 0xc7, 0xa9, 0x2d, 0xde, 0xcc, 0x7f, +0xee, 0xe7, 0xba, 0xee, 0xe7, 0xb7, 0xdd, 0xcc, +0x7b, 0xc7, 0xa9, 0x2c, 0xf6, 0xf3, 0xd0, 0xf4, +0xf0, 0xc6, 0xf2, 0xee, 0xb8, 0xf4, 0xee, 0xb6, +0xdd, 0xca, 0x74, 0xc1, 0xa0, 0x18, 0xdb, 0xc7, +0x77, 0xf5, 0xf2, 0xcd, 0xf3, 0xef, 0xb8, 0xf0, +0xe9, 0x9a, 0xf1, 0xea, 0x9a, 0xf3, 0xec, 0xa3, +0xf4, 0xed, 0xa3, 0xf4, 0xeb, 0x9a, 0xf3, 0xea, +0x91, 0xf2, 0xe8, 0x81, 0xf3, 0xe8, 0x82, 0xf7, +0xf0, 0xad, 0xee, 0xe7, 0xb9, 0xf5, 0xf1, 0xc8, +0xf3, 0xed, 0xb1, 0xf0, 0xe7, 0x90, 0xf1, 0xe8, +0x90, 0xf3, 0xec, 0xa0, 0xdb, 0xc7, 0x60, 0xf5, +0xed, 0xa0, 0xda, 0xc6, 0x58, 0xf3, 0xe8, 0x83, +0xf4, 0xea, 0x8d, 0xde, 0xcc, 0x7d, 0xf5, 0xf1, +0xc5, 0xf3, 0xee, 0xb3, 0xf1, 0xeb, 0xa0, 0xf2, +0xeb, 0x9e, 0xdd, 0xc9, 0x6d, 0xdd, 0xcc, 0x7a, +0xed, 0xe4, 0xa8, 0xed, 0xe4, 0xa2, 0xdd, 0xca, +0x72, 0xc7, 0xa9, 0x2a, 0x26, 0xed, 0xdc, 0x2b, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x5f, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0xa0, 0x0a, +0x60, 0x64, 0x62, 0x62, 0x44, 0xe6, 0x33, 0xb3, +0xb0, 0xb2, 0xb1, 0x73, 0x20, 0xc9, 0xb3, 0x70, +0x72, 0x71, 0xf3, 0xf0, 0xf2, 0x41, 0x00, 0x3f, +0x03, 0x03, 0x13, 0xab, 0x00, 0x9f, 0xa0, 0x90, +0xb0, 0x88, 0xa8, 0x98, 0xb8, 0x84, 0xa4, 0x14, +0x1f, 0x50, 0x40, 0x5a, 0x86, 0x4f, 0x56, 0x4e, +0x5e, 0x41, 0x51, 0x49, 0x59, 0x45, 0x15, 0xa4, +0x82, 0x51, 0x4d, 0x5d, 0x43, 0x53, 0x4b, 0x9b, +0x8f, 0x1f, 0x08, 0x41, 0x7c, 0x06, 0x06, 0x0e, +0x1d, 0x5d, 0x3d, 0x7d, 0x03, 0x34, 0x6b, 0xa9, +0xe3, 0x7e, 0x38, 0x00, 0x00, 0xd8, 0xad, 0x05, +0xb8, 0xcc, 0xed, 0x53, 0x77, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *primarykey_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_primarykey_png = new wxImage(); + if (!img_primarykey_png || !img_primarykey_png->IsOk()) + { + wxMemoryInputStream img_primarykey_pngIS(primarykey_png_data, sizeof(primarykey_png_data)); + img_primarykey_png->LoadFile(img_primarykey_pngIS, wxBITMAP_TYPE_PNG); + } + return img_primarykey_png; +} +#define primarykey_png_img primarykey_png_img() + +static wxBitmap *primarykey_png_bmp() +{ + static wxBitmap *bmp_primarykey_png; + if (!bmp_primarykey_png || !bmp_primarykey_png->IsOk()) + bmp_primarykey_png = new wxBitmap(*primarykey_png_img); + return bmp_primarykey_png; +} +#define primarykey_png_bmp primarykey_png_bmp() + +static wxIcon *primarykey_png_ico() +{ + static wxIcon *ico_primarykey_png; + if (!ico_primarykey_png || !ico_primarykey_png->IsOk()) + { + ico_primarykey_png = new wxIcon(); + ico_primarykey_png->CopyFromBitmap(*primarykey_png_bmp); + } + return ico_primarykey_png; +} +#define primarykey_png_ico primarykey_png_ico() + +#endif // PRIMARYKEY_PNG_H diff --git a/include/images/procedure.png b/include/images/procedure.png new file mode 100644 index 0000000000000000000000000000000000000000..8b65dff9eb2c373df031669adba7a82c0ae2aaa6 GIT binary patch literal 322 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFv5AX?b1=9Cs%{mqo^m6CUA1_|~ z|NHmbqerjy?R&Ir+0E|mOJ!vji;J%}H!SQ6wH%;50sMjDXAS>O>_45U54 z*zIJt9gq>^>Eal|aXmS~fyt>$U{>Hw4~8=dMTLzVhO64x7+WQ#PMLD)QiGGvQ-uJP z0|%}!vT^bF7&|6RVu(1qDl{Rt=hklXM&2Z=Vz#WlMH3iS#bz)t#6K1K?suIsOk()) + { + wxMemoryInputStream img_procedure_pngIS(procedure_png_data, sizeof(procedure_png_data)); + img_procedure_png->LoadFile(img_procedure_pngIS, wxBITMAP_TYPE_PNG); + } + return img_procedure_png; +} +#define procedure_png_img procedure_png_img() + +static wxBitmap *procedure_png_bmp() +{ + static wxBitmap *bmp_procedure_png; + if (!bmp_procedure_png || !bmp_procedure_png->IsOk()) + bmp_procedure_png = new wxBitmap(*procedure_png_img); + return bmp_procedure_png; +} +#define procedure_png_bmp procedure_png_bmp() + +static wxIcon *procedure_png_ico() +{ + static wxIcon *ico_procedure_png; + if (!ico_procedure_png || !ico_procedure_png->IsOk()) + { + ico_procedure_png = new wxIcon(); + ico_procedure_png->CopyFromBitmap(*procedure_png_bmp); + } + return ico_procedure_png; +} +#define procedure_png_ico procedure_png_ico() + +#endif // PROCEDURE_PNG_H diff --git a/include/images/procedures.png b/include/images/procedures.png new file mode 100644 index 0000000000000000000000000000000000000000..7c13a9bc73a782b5139095af596e15d7b68dd20c GIT binary patch literal 337 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFv5AX?b1=9EC%sCbm^nUN&dsC)d z%g%m(?%cJOmUB^2&)2TKR$To5`}b?r)x6ex&wxr9OM?7@862M7NCR>>3p^r=fwTu0 zyPeFo12PglT^vI=t|uoXgaoB9FsmgiGa57px_XMbaBFHxO0zOZW@WzA@{)3Bd#1Ev zf>nS=wRyl)0gsIDYK$8M1T>mj(wGjaEU!C8<`)MX5lF!N|bSP}jgv*T^))(A3Jn+{)NY+rZ4q zz+j);rTHita`RI%(<(t440H`FfqFuWjIB&etPFq}fI1CMO%GiI)WG2B>gTe~DWM4f DC&Fq! literal 0 HcmV?d00001 diff --git a/include/images/procedures.pngc b/include/images/procedures.pngc new file mode 100644 index 0000000..d13ee2a --- /dev/null +++ b/include/images/procedures.pngc @@ -0,0 +1,87 @@ +#ifndef PROCEDURES_PNG_H +#define PROCEDURES_PNG_H + +static const unsigned char procedures_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x27, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xde, 0x9c, 0x9c, 0xc6, +0x52, 0x52, 0xef, 0xbd, 0xbd, 0xde, 0x94, 0x94, +0xd6, 0x6b, 0x6b, 0xef, 0xce, 0xce, 0xd6, 0x84, +0x84, 0xce, 0x5a, 0x5a, 0xe7, 0xad, 0xad, 0xd6, +0x73, 0x73, 0xff, 0xf7, 0xf7, 0xd6, 0x7b, 0x7b, +0x0d, 0x3b, 0x0e, 0xe6, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x61, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, +0x63, 0x60, 0x60, 0x54, 0x52, 0x64, 0x00, 0x03, +0x26, 0x63, 0x23, 0x01, 0x30, 0x83, 0x51, 0x45, +0x49, 0x15, 0x44, 0x0b, 0x29, 0x29, 0x19, 0x1b, +0x05, 0x00, 0x19, 0x6a, 0x69, 0xe9, 0x2a, 0x4a, +0x1a, 0x40, 0x86, 0xe6, 0x22, 0xa8, 0x90, 0x3a, +0x50, 0x48, 0x7b, 0x37, 0x50, 0x95, 0x10, 0x48, +0x68, 0xf7, 0x26, 0x01, 0xb0, 0x10, 0x10, 0x28, +0x82, 0x84, 0x66, 0x02, 0xc1, 0x24, 0xa0, 0x39, +0xea, 0xe5, 0x40, 0xa0, 0x08, 0x31, 0x69, 0xd5, +0x22, 0x90, 0xe1, 0x8c, 0x4a, 0x3a, 0x67, 0x20, +0xd6, 0x31, 0xb9, 0x38, 0x41, 0x6d, 0x83, 0xd9, +0x0f, 0x06, 0x00, 0xe0, 0x9a, 0x15, 0x41, 0x5d, +0x96, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x31, 0x2d, 0x30, 0x31, 0x2d, 0x32, +0x35, 0x54, 0x31, 0x35, 0x3a, 0x30, 0x37, 0x3a, +0x33, 0x36, 0x2b, 0x30, 0x36, 0x3a, 0x30, 0x30, +0xbe, 0x1e, 0xd2, 0x9f, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *procedures_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_procedures_png = new wxImage(); + if (!img_procedures_png || !img_procedures_png->IsOk()) + { + wxMemoryInputStream img_procedures_pngIS(procedures_png_data, sizeof(procedures_png_data)); + img_procedures_png->LoadFile(img_procedures_pngIS, wxBITMAP_TYPE_PNG); + } + return img_procedures_png; +} +#define procedures_png_img procedures_png_img() + +static wxBitmap *procedures_png_bmp() +{ + static wxBitmap *bmp_procedures_png; + if (!bmp_procedures_png || !bmp_procedures_png->IsOk()) + bmp_procedures_png = new wxBitmap(*procedures_png_img); + return bmp_procedures_png; +} +#define procedures_png_bmp procedures_png_bmp() + +static wxIcon *procedures_png_ico() +{ + static wxIcon *ico_procedures_png; + if (!ico_procedures_png || !ico_procedures_png->IsOk()) + { + ico_procedures_png = new wxIcon(); + ico_procedures_png->CopyFromBitmap(*procedures_png_bmp); + } + return ico_procedures_png; +} +#define procedures_png_ico procedures_png_ico() + +#endif // PROCEDURES_PNG_H diff --git a/include/images/properties.png b/include/images/properties.png new file mode 100644 index 0000000000000000000000000000000000000000..f9b8c14d98fce28ecf4bdb4030e4c850368b9e0c GIT binary patch literal 908 zcmY+Ae^AqP9L5Lbxk=+LcU@kRE*EK*>pL1~yDl6XHjZwGNSq}WOZidCQMuCy67%Hz z5u6-#{Mfj0oRLA2p25}+e-J1ORx4bIe31=fcqna4b}aAszMoIu^soMS-p@UE&+G1e z&(R$7%km|UEs;nh@+^}vS9Ilnl0G0_n!`iH;G~5!HtS29OK54*DMO z1Czid(2u|kV9;jY>~vY$+uK2xfGNQ3@s#oWK9KnQG{^(GX}9OQT%{1ajAlF@E6-Om zVT92w#^#vdV|3eYFL1fanQ)cStjANu^GBF)jZugR7F(X?RrTpY|Aq0^EPD)F7qihB6oZML-R<(;LL z`hKN+sm7^otPWfsPpez-DFRci(TOP6mT~7-pD%$o6n^j~JCK{1*p+G+P@RwrbZWZI z<(zGB^;0Lmu*Z*lsF-URTlp|o;@n!c_wb(m`e3t^drtjbsmnbZ{Uk{d*Ek(e_3_E^ zySK0EQy=fSJG^#j(pi)J^rHI7ziLez9x-M}H=TJgN#C!l{dT5qP0-#TbN^{F^+`j1 zzA@r%c>2jTmItHzpKb9f^@~(1B3^ayiqSS^h?l9}2;k$YwxJcPo>;7E{- zwRd~ntLw8B6|tT>>6ee>@7t>mlq5VV*Vh*MOA;~@wa3jJ>zmaE+3hax>Fo8><3GGr zv&)~Xln*W}c2rk&MVcHH=qRY@b{=YdJ({mL#8)bp9X*+{@|^PTwu1Surq0TSY80XJ z>h!?chb)!bb;^8k?__J{R_jiSwMe(){UXsMDV&B|r%74IY4TDyo%VU1HuV`URmX9T ru)6DiKw0_Dw~H(81KbPu0I{vracTE~;igwliGU<4(`@`YqwwIru*(a2 literal 0 HcmV?d00001 diff --git a/include/images/properties.pngc b/include/images/properties.pngc new file mode 100644 index 0000000..8aeb23a --- /dev/null +++ b/include/images/properties.pngc @@ -0,0 +1,158 @@ +#ifndef PROPERTIES_PNG_H +#define PROPERTIES_PNG_H + +static const unsigned char properties_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x08, 0x03, 0x00, 0x00, 0x00, 0x44, 0xa4, 0x8a, +0xc6, 0x00, 0x00, 0x01, 0x68, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xde, 0xce, 0x66, 0xe4, +0xca, 0x1d, 0xe4, 0xca, 0x1b, 0xde, 0xce, 0x63, +0xee, 0xde, 0x71, 0xfe, 0xfd, 0xd6, 0xfe, 0xfe, +0xc8, 0xfe, 0xfe, 0xc9, 0xfe, 0xfe, 0xcb, 0xfe, +0xfe, 0xcc, 0xfe, 0xfe, 0xce, 0xfe, 0xfe, 0xd0, +0xfe, 0xfe, 0xd2, 0xfe, 0xfe, 0xd3, 0xfe, 0xfe, +0xd5, 0xfe, 0xfe, 0xd7, 0xff, 0xff, 0xf5, 0xfe, +0xfd, 0xbe, 0xfd, 0xfd, 0x99, 0xfd, 0xfd, 0x93, +0xfd, 0xfd, 0x97, 0xfd, 0xfd, 0x9a, 0xfd, 0xfd, +0x9e, 0xfd, 0xfd, 0xa1, 0xfd, 0xfd, 0xa5, 0xfd, +0xfd, 0xa8, 0xfd, 0xfd, 0xac, 0xfe, 0xfd, 0xb0, +0xfe, 0xfd, 0xb3, 0xfe, 0xfe, 0xdb, 0xef, 0xe0, +0x50, 0xe4, 0xcb, 0x1c, 0xff, 0xff, 0xee, 0xfd, +0xfe, 0xbc, 0xfd, 0xfe, 0xbd, 0xfd, 0xfe, 0xbe, +0xfd, 0xfe, 0xbf, 0xfd, 0xfe, 0xc0, 0xfd, 0xfe, +0xc2, 0xfd, 0xfe, 0xc3, 0xfe, 0xfe, 0xbf, 0xfe, +0xfe, 0xad, 0xfc, 0xfd, 0x7b, 0xfc, 0xfd, 0x7d, +0xfc, 0xfd, 0x80, 0xfc, 0xfd, 0x82, 0xfc, 0xfd, +0x85, 0xfc, 0xfd, 0x87, 0xfd, 0xfd, 0x8a, 0xfd, +0xfd, 0x8d, 0xfd, 0xfd, 0x90, 0xee, 0xdf, 0x43, +0xfe, 0xfd, 0xb7, 0xfe, 0xfe, 0xdc, 0xfe, 0xfd, +0xba, 0xfe, 0xfe, 0xde, 0xfe, 0xfe, 0xe0, 0xfe, +0xfe, 0xc4, 0xfe, 0xfd, 0xc1, 0xfe, 0xfe, 0xe1, +0xfe, 0xfe, 0xc6, 0x9a, 0x9b, 0x51, 0xb6, 0xb7, +0x61, 0xa1, 0xa1, 0xa1, 0xfe, 0xfd, 0xc4, 0xfe, +0xfe, 0xe3, 0xfe, 0xfe, 0xc7, 0xcb, 0xcb, 0x6d, +0xda, 0xda, 0x77, 0xfe, 0xfd, 0xc8, 0xfe, 0xfe, +0xe5, 0xfe, 0xfd, 0xcb, 0xfe, 0xfd, 0xe6, 0x9b, +0x9b, 0x56, 0xb7, 0xb7, 0x68, 0xfe, 0xfc, 0xce, +0xff, 0xfd, 0xe8, 0xcb, 0xcb, 0x74, 0xda, 0xda, +0x7f, 0xff, 0xfc, 0xd1, 0xff, 0xfd, 0xe9, 0xff, +0xff, 0xf2, 0xff, 0xfc, 0xd3, 0xff, 0xfd, 0xea, +0x9b, 0x9b, 0x5c, 0xb7, 0xb7, 0x6f, 0xff, 0xfc, +0xd6, 0xff, 0xfd, 0xeb, 0xcb, 0xcb, 0x7c, 0xda, +0xda, 0x88, 0xff, 0xfc, 0xd8, 0xff, 0xfd, 0xed, +0xff, 0xfc, 0xdb, 0xff, 0xfd, 0xee, 0xfd, 0xfd, +0xb5, 0xfe, 0xfd, 0xb6, 0xfe, 0xfd, 0xcd, 0xfe, +0xfd, 0xd7, 0xff, 0xfd, 0xe0, 0xff, 0xfd, 0xe1, +0xff, 0xfd, 0xdd, 0xff, 0xfc, 0xda, 0xff, 0xfc, +0xdd, 0xfd, 0xfd, 0xb6, 0xf5, 0xed, 0xa1, 0xeb, +0xd7, 0x53, 0xf6, 0xed, 0xa3, 0xfe, 0xfd, 0xc5, +0xf6, 0xed, 0xa9, 0xf6, 0xed, 0xaa, 0xff, 0xfc, +0xde, 0xff, 0xfd, 0xef, 0xfe, 0xfe, 0xe9, 0xe8, +0xd3, 0x41, 0xd9, 0xd1, 0x9e, 0xff, 0xfe, 0xee, +0xff, 0xfe, 0xf2, 0xff, 0xfe, 0xf6, 0xff, 0xff, +0xfb, 0x9c, 0x67, 0x31, 0x36, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x01, 0x5b, 0x49, 0x44, 0x41, 0x54, 0x38, +0xcb, 0xbd, 0x92, 0xd9, 0x3f, 0x02, 0x51, 0x18, +0x40, 0xe3, 0x0e, 0x6a, 0x94, 0x65, 0xb4, 0xda, +0xb5, 0x5b, 0x9a, 0x36, 0x4b, 0x1b, 0xa9, 0x68, +0x61, 0x90, 0xc2, 0x20, 0x0d, 0x12, 0x31, 0xb6, +0x34, 0x96, 0x7f, 0xdf, 0xdc, 0xdb, 0x36, 0x8d, +0xfb, 0xd3, 0x13, 0xdf, 0xe3, 0x9c, 0xf3, 0xdd, +0xf3, 0x30, 0x9f, 0x42, 0xf1, 0xcf, 0xd3, 0xd3, +0x0b, 0xda, 0x43, 0x60, 0x78, 0x5f, 0xff, 0x80, +0x52, 0x45, 0x0e, 0xaa, 0x35, 0x43, 0xc3, 0x23, +0xa3, 0x00, 0xc3, 0xa9, 0x31, 0xad, 0x4e, 0x6f, +0x30, 0x9a, 0xc6, 0x27, 0x26, 0xa7, 0xa6, 0x9b, +0x02, 0xd1, 0x7a, 0x13, 0xf2, 0x99, 0xd9, 0x1f, +0x11, 0x30, 0x67, 0xb6, 0x58, 0x6d, 0x76, 0x87, +0x73, 0x7e, 0x41, 0xe4, 0x98, 0x08, 0x30, 0x2f, +0x2e, 0xb9, 0x68, 0xb7, 0xc7, 0xeb, 0xf3, 0x8b, +0x1c, 0x13, 0x01, 0x96, 0xe5, 0xdf, 0x23, 0xc0, +0xda, 0x25, 0x02, 0x6c, 0x5d, 0x22, 0xc0, 0x2e, +0x8f, 0xb4, 0xf8, 0xca, 0x2a, 0x12, 0x1c, 0xb2, +0x48, 0x9b, 0xaf, 0x05, 0x90, 0xe0, 0xec, 0x8c, +0x48, 0x38, 0x15, 0x44, 0x42, 0x08, 0x46, 0xb0, +0x3c, 0x1c, 0x41, 0xc2, 0x3a, 0x8c, 0xb8, 0xe8, +0x8d, 0x28, 0xe4, 0x9b, 0x92, 0x09, 0xc7, 0xe2, +0x48, 0x48, 0xc0, 0x08, 0xed, 0xde, 0xda, 0x96, +0xef, 0xc7, 0x92, 0x29, 0x24, 0x28, 0x61, 0x04, +0xf3, 0x7e, 0x2c, 0x99, 0xce, 0x20, 0x41, 0x05, +0x23, 0x1e, 0xef, 0xce, 0x2e, 0xe4, 0xd2, 0x44, +0x9a, 0xd9, 0x43, 0x02, 0x09, 0x23, 0x5e, 0xdf, +0xfe, 0x81, 0x7c, 0x9f, 0xc9, 0x1e, 0x22, 0x21, +0x07, 0x23, 0x98, 0xf7, 0x99, 0x6c, 0xfe, 0x08, +0xd4, 0xef, 0x41, 0x8c, 0xf8, 0xb5, 0xc7, 0x27, +0x90, 0x4b, 0x13, 0x79, 0xf6, 0xb4, 0xf1, 0x3f, +0xc5, 0x88, 0x56, 0x77, 0x76, 0x2e, 0xdf, 0x67, +0x0b, 0x17, 0x0d, 0x41, 0x8c, 0x60, 0xde, 0x67, +0x0b, 0x45, 0x0e, 0x34, 0x8f, 0x4e, 0xa5, 0x37, +0x98, 0x2e, 0x43, 0x09, 0xea, 0xaa, 0xce, 0xaf, +0x4b, 0x37, 0xe5, 0xdb, 0xbb, 0x62, 0x85, 0x6b, +0xde, 0x25, 0x20, 0x0d, 0xc6, 0xfb, 0x07, 0x9e, +0x7f, 0x7c, 0xaa, 0xef, 0x97, 0x9e, 0x79, 0xfe, +0xa5, 0x5c, 0x79, 0xad, 0xb6, 0x84, 0x9c, 0x5a, +0xf3, 0x56, 0x13, 0x84, 0xda, 0x7b, 0x20, 0x18, +0x89, 0xa7, 0x32, 0x1f, 0xbc, 0x20, 0xf0, 0x9f, +0x5c, 0xf5, 0xab, 0xe3, 0xb2, 0x09, 0xc9, 0x85, +0x13, 0xed, 0x6f, 0x7f, 0x3f, 0xdf, 0x2a, 0x0c, +0x61, 0x7b, 0x5d, 0x3a, 0x20, 0x56, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *properties_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_properties_png = new wxImage(); + if (!img_properties_png || !img_properties_png->IsOk()) + { + wxMemoryInputStream img_properties_pngIS(properties_png_data, sizeof(properties_png_data)); + img_properties_png->LoadFile(img_properties_pngIS, wxBITMAP_TYPE_PNG); + } + return img_properties_png; +} +#define properties_png_img properties_png_img() + +static wxBitmap *properties_png_bmp() +{ + static wxBitmap *bmp_properties_png; + if (!bmp_properties_png || !bmp_properties_png->IsOk()) + bmp_properties_png = new wxBitmap(*properties_png_img); + return bmp_properties_png; +} +#define properties_png_bmp properties_png_bmp() + +static wxIcon *properties_png_ico() +{ + static wxIcon *ico_properties_png; + if (!ico_properties_png || !ico_properties_png->IsOk()) + { + ico_properties_png = new wxIcon(); + ico_properties_png->CopyFromBitmap(*properties_png_bmp); + } + return ico_properties_png; +} +#define properties_png_ico properties_png_ico() + +#endif // PROPERTIES_PNG_H diff --git a/include/images/property.png b/include/images/property.png new file mode 100644 index 0000000000000000000000000000000000000000..c410cb0923fe516ce82d5d646a53044fe9da8752 GIT binary patch literal 576 zcmY+BUr1AN6vyw1NN-ruKct|yVlb4uIYaM5Z8B@qkm07dBACssvZQ~D81>L!$wttN zR0QfE6wGwp{@_~WO3b#QfKj^En63=izXg&6Rs|_$@rg zaXBWVp-N`%VzO4sRhhreA|qPIjh~U5us} zr5O7Id{2z&7iI?;elw&Q`+KwC{6qORg}bWK!s(`?E_uj4X|$b@X7N6}E3I*?t<_crEeqmIjQ>bmW z5|2%3=J@NXNLZzhw^Um%tynKfWik1&1T(!ni^ehN9k&1sOLdvZ=?N) zz5e*22G`n+F~9$bBt270PbKN`IgT$DOM-pH!RPw}eYJtWm4m!{x5kvkafy))*M@e) z79X|UT~_O^uX8&^$7!bwP9vy=e6=QDP+K*Es4Wz=MJl046ol4PLDzpmIsOk()) + { + wxMemoryInputStream img_property_pngIS(property_png_data, sizeof(property_png_data)); + img_property_png->LoadFile(img_property_pngIS, wxBITMAP_TYPE_PNG); + } + return img_property_png; +} +#define property_png_img property_png_img() + +static wxBitmap *property_png_bmp() +{ + static wxBitmap *bmp_property_png; + if (!bmp_property_png || !bmp_property_png->IsOk()) + bmp_property_png = new wxBitmap(*property_png_img); + return bmp_property_png; +} +#define property_png_bmp property_png_bmp() + +static wxIcon *property_png_ico() +{ + static wxIcon *ico_property_png; + if (!ico_property_png || !ico_property_png->IsOk()) + { + ico_property_png = new wxIcon(); + ico_property_png->CopyFromBitmap(*property_png_bmp); + } + return ico_property_png; +} +#define property_png_ico property_png_ico() + +#endif // PROPERTY_PNG_H diff --git a/include/images/query_cancel.png b/include/images/query_cancel.png new file mode 100644 index 0000000000000000000000000000000000000000..f749a685f67246bcef5254cb4ac33e46ebff8d1f GIT binary patch literal 498 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf;Q*fyS0H_?H-3Mdz{?BE9v^6X zvcLJ+zPcBCs$T9YeY3OR(~17a2U_o}jJUTv=)qE-$BW&bEwFz%&-~+-l&AX}A1?KN zyvX(00=t)U&ECw`|GX*o+1}cROTC^fa(TYM=G9!&x3ly<%uxHfA^hd;@+XU&pU<~` zHP__rEZq;&RX{6g&CbH-^Q~UZF@8Hs`@?jV&r@W-O%nUP#^>F(?ALRQ-p$nd zI8FJ>6q#?6M1S`4|5@e!<#_j}&GBD1M1Ef%@^h{K@6}%a_7=|Jx)ura24hK(UoeBi zvm0qZ4rhT!WHFHT0Ash4*>*rinx~6nh{WaO1O;vbBS%K%kcQ5gty6pFHc#&6R6B6? z@ag0F3K}fp0?$MRMTMtNXyNwoJbmKSNo|cotW&0hhFra3YVwdN>Xy~6s$Xnv1&qqc z!okMH+}=AHrf%(BJ9qC=W?{Ydi5v{Cc5|$VUfG!mv{ALhHKHUXu_VKd7b7@ArcSXdcbXd9SW85qcGeey@qkei>9nN|tXV4!PY3Dgr}WNc+(Vr5{a YZ2;71aB6z!8lVOSPgg&ebxsLQ0NKsZ+yDRo literal 0 HcmV?d00001 diff --git a/include/images/query_cancel.pngc b/include/images/query_cancel.pngc new file mode 100644 index 0000000..566df25 --- /dev/null +++ b/include/images/query_cancel.pngc @@ -0,0 +1,107 @@ +#ifndef QUERY_CANCEL_PNG_H +#define QUERY_CANCEL_PNG_H + +static const unsigned char query_cancel_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xc3, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc6, 0x8d, 0x5f, 0xbf, +0x5e, 0x10, 0xe9, 0xd0, 0xa6, 0xe3, 0xc0, 0x86, +0xe4, 0xbf, 0x83, 0xe6, 0xbe, 0x7e, 0xe8, 0xbc, +0x7a, 0xe9, 0xba, 0x75, 0xec, 0xb9, 0x70, 0xf2, +0xc8, 0x8f, 0xe3, 0xc0, 0x85, 0xdc, 0xa9, 0x58, +0xde, 0xa7, 0x52, 0xe0, 0xa5, 0x4c, 0xe3, 0xa3, +0x46, 0xe6, 0xa0, 0x3f, 0xe9, 0x9e, 0x37, 0xf1, +0xb4, 0x64, 0xe5, 0xbf, 0x81, 0xe1, 0xa5, 0x4b, +0xe3, 0xa2, 0x45, 0xe6, 0xa0, 0x3e, 0xe9, 0x9d, +0x36, 0xec, 0x9b, 0x2f, 0xf3, 0xb2, 0x5d, 0xe6, +0xbd, 0x7d, 0xe1, 0xa5, 0x4a, 0xe4, 0xa2, 0x44, +0xe7, 0xa0, 0x3c, 0xea, 0x9d, 0x35, 0xed, 0x9a, +0x2e, 0xf0, 0x98, 0x26, 0xf5, 0xb0, 0x57, 0xe9, +0xbb, 0x77, 0xe4, 0xa2, 0x43, 0xe7, 0x9f, 0x3b, +0xea, 0x9d, 0x34, 0xed, 0x9a, 0x2d, 0xf0, 0x97, +0x25, 0xf3, 0x95, 0x1e, 0xf8, 0xad, 0x51, 0xec, +0xb9, 0x71, 0xe7, 0x9f, 0x3a, 0xea, 0x9c, 0x33, +0xed, 0x9a, 0x2b, 0xf0, 0x97, 0x24, 0xf3, 0x94, +0x1d, 0xf6, 0x92, 0x16, 0xfb, 0xac, 0x4c, 0xee, +0xb6, 0x6b, 0xeb, 0x9c, 0x32, 0xee, 0x99, 0x2a, +0xf1, 0x96, 0x23, 0xf4, 0x94, 0x1c, 0xf6, 0x92, +0x15, 0xf9, 0x8f, 0x0f, 0xfc, 0xaa, 0x47, 0xf4, +0xc7, 0x8b, 0xf2, 0xb3, 0x5f, 0xf5, 0xb0, 0x59, +0xf7, 0xaf, 0x54, 0xf9, 0xad, 0x4f, 0xfb, 0xab, +0x4a, 0xfe, 0xbd, 0x71, 0x9c, 0x0a, 0xd6, 0x59, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x66, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0x20, 0x0b, +0x30, 0x32, 0x41, 0x01, 0x23, 0x54, 0x80, 0x89, +0x99, 0x85, 0x95, 0x8d, 0x9d, 0x83, 0x93, 0x8b, +0x09, 0x26, 0xc0, 0xcd, 0xc3, 0xcb, 0xc7, 0x2f, +0x20, 0x28, 0x04, 0x17, 0x10, 0xe6, 0x15, 0x11, +0x15, 0x13, 0x97, 0x90, 0x84, 0x0b, 0x48, 0x49, +0xcb, 0xc8, 0xca, 0xc9, 0x2b, 0x28, 0xc2, 0x05, +0x94, 0x94, 0x55, 0x54, 0xd5, 0xd4, 0x35, 0x34, +0xe1, 0x02, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, +0x06, 0x86, 0x70, 0x01, 0x23, 0x63, 0x13, 0x53, +0x33, 0x73, 0x0b, 0x4b, 0xb8, 0x80, 0x95, 0xb5, +0x8d, 0xad, 0x9d, 0xbd, 0xa5, 0x03, 0x13, 0x2e, +0x87, 0x91, 0x08, 0x00, 0xea, 0xbb, 0x08, 0xa8, +0x5b, 0xa9, 0x89, 0x69, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x31, 0x2d, 0x30, 0x31, 0x2d, +0x32, 0x35, 0x54, 0x31, 0x35, 0x3a, 0x30, 0x38, +0x3a, 0x33, 0x38, 0x2b, 0x30, 0x36, 0x3a, 0x30, +0x30, 0x1f, 0x2a, 0xf2, 0x4f, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *query_cancel_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_query_cancel_png = new wxImage(); + if (!img_query_cancel_png || !img_query_cancel_png->IsOk()) + { + wxMemoryInputStream img_query_cancel_pngIS(query_cancel_png_data, sizeof(query_cancel_png_data)); + img_query_cancel_png->LoadFile(img_query_cancel_pngIS, wxBITMAP_TYPE_PNG); + } + return img_query_cancel_png; +} +#define query_cancel_png_img query_cancel_png_img() + +static wxBitmap *query_cancel_png_bmp() +{ + static wxBitmap *bmp_query_cancel_png; + if (!bmp_query_cancel_png || !bmp_query_cancel_png->IsOk()) + bmp_query_cancel_png = new wxBitmap(*query_cancel_png_img); + return bmp_query_cancel_png; +} +#define query_cancel_png_bmp query_cancel_png_bmp() + +static wxIcon *query_cancel_png_ico() +{ + static wxIcon *ico_query_cancel_png; + if (!ico_query_cancel_png || !ico_query_cancel_png->IsOk()) + { + ico_query_cancel_png = new wxIcon(); + ico_query_cancel_png->CopyFromBitmap(*query_cancel_png_bmp); + } + return ico_query_cancel_png; +} +#define query_cancel_png_ico query_cancel_png_ico() + +#endif // QUERY_CANCEL_PNG_H diff --git a/include/images/query_commit.png b/include/images/query_commit.png new file mode 100644 index 0000000000000000000000000000000000000000..500ef88c58b4fc812e4693177001b69fc0f55ed9 GIT binary patch literal 707 zcmV;!0zCbRP)N2bZe?^J zG%heMHD!e|WdHyIK}keGR5(w4ky}WUVI0P%;1LxWmcp!zvO;v9hn%woQ5W3=5_Q{M z6eM)nRd>;K(19^CN+b*OFtM!EDa&*nqzH^!>R4;%Ltf~h4D#3e&iUEbsy{q@@Av+n z=Xsy^|LOn@Ivw6h)JMTVO*~lZ7o+qU33)XBIC;ht|JZW!WM;) zMSKr6Gixv~R$9uPKdz!Kx@7chY%ebK&_hE&PCmRVJPzalh`08tz+*VG1L4lxc@+CAiH*=NV{CsBiRN=AI5f*ds znQL+GG;mkEOq!;a#$dS9g6q*a=4Y?aUs#BvvV!+D)lBcL;+{zMdg45effLwmCRL>x zJR3NT=UoTBRE`jj{r>?7do!t3qig`*wGmpav8$Y$Zy=qcu2p5?1& zgq6_bI^uSszUwMvU-F)Iw`mRfuhrvUm>{}1%JZRio^&0q{7Ay;y1`2HF^RA> zW#C&B23{-Cz=OXV%sMWm6D+F+sRaJt5_oOAabCzYkTulN%GBT)7F;(r2bmt?#_%S3 pkBetCt16AbM*VMyX^L8a?iVsPVn?ss%Xk0)002ovPDHLkV1ly(N`3$U literal 0 HcmV?d00001 diff --git a/include/images/query_commit.pngc b/include/images/query_commit.pngc new file mode 100644 index 0000000..c2f7814 --- /dev/null +++ b/include/images/query_commit.pngc @@ -0,0 +1,133 @@ +#ifndef QUERY_COMMIT_PNG_H +#define QUERY_COMMIT_PNG_H + +static const unsigned char query_commit_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff, +0x61, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, +0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, +0x05, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x0e, 0xc2, 0x00, 0x00, 0x0e, +0xc2, 0x01, 0x15, 0x28, 0x4a, 0x80, 0x00, 0x00, +0x00, 0x18, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, +0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x00, 0x70, +0x61, 0x69, 0x6e, 0x74, 0x2e, 0x6e, 0x65, 0x74, +0x20, 0x34, 0x2e, 0x30, 0x2e, 0x35, 0x65, 0x85, +0x32, 0x65, 0x00, 0x00, 0x02, 0x41, 0x49, 0x44, +0x41, 0x54, 0x38, 0x4f, 0x7d, 0x91, 0x5b, 0x48, +0x93, 0x61, 0x1c, 0xc6, 0xa7, 0xe0, 0x11, 0x15, +0x19, 0x96, 0xc2, 0xac, 0x8c, 0xb2, 0x42, 0x74, +0x9f, 0x87, 0x9c, 0xb3, 0x05, 0x51, 0x17, 0xdd, +0x04, 0x12, 0x75, 0xdb, 0x5d, 0x14, 0x24, 0x74, +0xd9, 0x55, 0x77, 0xd1, 0x75, 0xd0, 0x81, 0x31, +0x33, 0x4a, 0x24, 0x0b, 0xf3, 0x30, 0xb1, 0xac, +0xd4, 0x29, 0xcb, 0x74, 0x1d, 0xa4, 0x08, 0x8c, +0x5a, 0xea, 0x58, 0x6b, 0xe7, 0x43, 0x5e, 0xe8, +0xa0, 0x0c, 0xf2, 0xd7, 0xfb, 0xce, 0xf9, 0xd9, +0xd7, 0xaa, 0x3f, 0x3c, 0x7c, 0xef, 0xf7, 0xfe, +0x9f, 0xe7, 0x79, 0x9f, 0xf7, 0xff, 0xea, 0x00, +0x0d, 0x3a, 0xb3, 0xb2, 0xe8, 0xce, 0xc9, 0x61, +0xb8, 0xb8, 0x98, 0x87, 0x25, 0x25, 0xd8, 0x8b, +0x8a, 0xe8, 0xc9, 0xcb, 0xe3, 0xa6, 0x4e, 0xb6, +0xb5, 0x5c, 0x89, 0x8c, 0x8d, 0xdb, 0xd9, 0xd9, +0x38, 0xb7, 0x57, 0x10, 0xac, 0xaf, 0x25, 0xd2, +0xa4, 0x10, 0x6f, 0x30, 0x12, 0x6b, 0x36, 0x32, +0x59, 0x56, 0x26, 0xda, 0x5a, 0xae, 0x44, 0xc6, +0xc6, 0x2d, 0x91, 0xc0, 0x59, 0x5d, 0x49, 0xa8, +0xa9, 0x8e, 0xc8, 0x7e, 0x85, 0x88, 0x49, 0xa0, +0x55, 0x61, 0x5c, 0xaf, 0x17, 0x6d, 0x2d, 0x57, +0x42, 0x5d, 0x74, 0x14, 0xe5, 0x22, 0xe3, 0xcb, +0x04, 0xae, 0x23, 0x0d, 0xeb, 0xc2, 0x16, 0x85, +0x90, 0x45, 0x7c, 0x0f, 0x35, 0x33, 0x6b, 0x30, +0x30, 0x56, 0x5a, 0xca, 0x9d, 0x3f, 0xae, 0xa2, +0x2e, 0xba, 0x64, 0xf4, 0x8a, 0xad, 0xbc, 0xdd, +0xb5, 0x83, 0xa0, 0x10, 0xc6, 0x4d, 0x0d, 0x04, +0x8e, 0x9a, 0xf0, 0xb6, 0xb5, 0x10, 0x39, 0xd8, +0x48, 0xd8, 0xac, 0xf0, 0x61, 0xdf, 0xee, 0xd4, +0x21, 0x1b, 0x1a, 0x09, 0x75, 0x21, 0xd1, 0x93, +0x9b, 0xcb, 0xb8, 0xa1, 0x1c, 0xf7, 0x61, 0x85, +0x8f, 0x27, 0x1b, 0x09, 0x1d, 0x50, 0x08, 0x9b, +0x8c, 0xf8, 0xea, 0x6b, 0x98, 0xdc, 0x56, 0x4e, +0x7f, 0x41, 0x81, 0xa0, 0x6d, 0xf2, 0x25, 0x34, +0x35, 0x37, 0x73, 0x95, 0xde, 0xfc, 0x7c, 0x66, +0xf6, 0x54, 0xe1, 0xb1, 0xd4, 0x11, 0x16, 0x73, +0xf0, 0x99, 0x6b, 0x71, 0xee, 0x34, 0x70, 0x57, +0xbc, 0x4c, 0x9a, 0xa6, 0x96, 0xc6, 0x60, 0xb8, +0xd3, 0x82, 0xeb, 0xd1, 0x39, 0xe6, 0x67, 0xaf, +0xd0, 0x5f, 0x58, 0x88, 0xa3, 0xb2, 0x82, 0xf7, +0x35, 0xd5, 0x4c, 0xef, 0xad, 0xe2, 0x9e, 0x48, +0xf6, 0x7a, 0xe2, 0x3c, 0x8e, 0x81, 0x13, 0xd8, +0x6d, 0x26, 0x55, 0xa5, 0x1a, 0x3c, 0x1b, 0x38, +0x8d, 0xe7, 0x5d, 0x07, 0xfc, 0x5c, 0x12, 0xf0, +0xb3, 0xb6, 0xea, 0xe6, 0xbe, 0x78, 0xfb, 0xc1, +0x2d, 0xfa, 0x94, 0x38, 0x18, 0xec, 0x23, 0xe0, +0xeb, 0xc2, 0xeb, 0xed, 0xe4, 0x85, 0xa3, 0x1d, +0xc9, 0x97, 0x3a, 0xd5, 0x60, 0xc8, 0x66, 0xe1, +0xd5, 0xe8, 0x29, 0xe6, 0x5e, 0x9e, 0xe5, 0xab, +0x67, 0x84, 0x95, 0xd0, 0xe4, 0x3a, 0xe2, 0x76, +0xa2, 0xbe, 0xeb, 0x2a, 0x64, 0x5f, 0xf2, 0x9e, +0x76, 0xb7, 0x69, 0x0d, 0xfa, 0xaf, 0xd5, 0xe3, +0x5f, 0x98, 0x20, 0xba, 0x38, 0xca, 0xf3, 0xa1, +0x76, 0x9e, 0x74, 0x1d, 0xc3, 0x6e, 0x6d, 0x51, +0x21, 0xff, 0xe5, 0x7e, 0x22, 0x3a, 0x4d, 0xec, +0xcb, 0x18, 0x92, 0x2f, 0x75, 0x1a, 0x83, 0xa0, +0x67, 0x8a, 0x64, 0xcc, 0x0d, 0xdf, 0x57, 0xe0, +0xdb, 0x12, 0x6b, 0xc9, 0x39, 0x92, 0x89, 0x11, +0xe2, 0x3e, 0x1b, 0x9f, 0xe7, 0x2f, 0xe2, 0x9d, +0xbf, 0x2c, 0xae, 0x61, 0x25, 0xe2, 0xef, 0xfb, +0xb7, 0xc1, 0x72, 0xec, 0x13, 0xfc, 0x48, 0xc2, +0xea, 0xba, 0xc1, 0x4a, 0xf4, 0x31, 0x89, 0xb0, +0x35, 0x65, 0xe0, 0x5b, 0x14, 0x06, 0x5e, 0x2b, +0xd1, 0xc0, 0x83, 0xbf, 0x1b, 0xcc, 0x3a, 0x2e, +0xa5, 0x13, 0x2c, 0xab, 0x06, 0xa9, 0x04, 0xfe, +0xdf, 0x12, 0x78, 0x6d, 0xbc, 0x71, 0x5e, 0xc8, +0x34, 0x90, 0x35, 0xd4, 0xd1, 0xca, 0xd4, 0xe0, +0x19, 0x16, 0x5c, 0x37, 0x36, 0x07, 0x99, 0x1e, +0xe2, 0xc6, 0xf0, 0x26, 0x7a, 0x8f, 0x8b, 0x67, +0x34, 0xab, 0x2a, 0x8d, 0xc1, 0x46, 0xfd, 0x6f, +0x88, 0x69, 0x8a, 0x5a, 0x80, 0xee, 0x17, 0x32, +0x36, 0x62, 0x47, 0xaf, 0xdc, 0xcb, 0x78, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *query_commit_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_query_commit_png = new wxImage(); + if (!img_query_commit_png || !img_query_commit_png->IsOk()) + { + wxMemoryInputStream img_query_commit_pngIS(query_commit_png_data, sizeof(query_commit_png_data)); + img_query_commit_png->LoadFile(img_query_commit_pngIS, wxBITMAP_TYPE_PNG); + } + return img_query_commit_png; +} +#define query_commit_png_img query_commit_png_img() + +static wxBitmap *query_commit_png_bmp() +{ + static wxBitmap *bmp_query_commit_png; + if (!bmp_query_commit_png || !bmp_query_commit_png->IsOk()) + bmp_query_commit_png = new wxBitmap(*query_commit_png_img); + return bmp_query_commit_png; +} +#define query_commit_png_bmp query_commit_png_bmp() + +static wxIcon *query_commit_png_ico() +{ + static wxIcon *ico_query_commit_png; + if (!ico_query_commit_png || !ico_query_commit_png->IsOk()) + { + ico_query_commit_png = new wxIcon(); + ico_query_commit_png->CopyFromBitmap(*query_commit_png_bmp); + } + return ico_query_commit_png; +} +#define query_commit_png_ico query_commit_png_ico() + +#endif // QUERY_COMMIT_PNG_H diff --git a/include/images/query_execfile.png b/include/images/query_execfile.png new file mode 100644 index 0000000000000000000000000000000000000000..c0b5f24879006bef16890e3c480fd2bd4e61cf6a GIT binary patch literal 600 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf+W?;sS0LTJF)?bk@X=en>(3;w zKa;ZZMA($w`Ww$?t~wFbw_R=e9*ZsK3s#?uo3KM?(oVzK`<=I4tXO+GY0@s^DZ4GE z?Xg{YG%9b#CY`js1(S}hJDomtx8=0GcJmJT@4DPL`@+LdKmR=b{PXt5A5Xsio_pfi zhO;@-_d3i!6u9ehbJhOq8#it|@%nq+mIs^870y2#yz5GH^}ZXgzWu)R?#Hc9zv?$V z+;ye3X3s6_`Xe^gCmJ?9KKEdG&92*l3oiuCzZ5*@O7N_!A=9siPQBT%?s4tTJ2th) zY%5QOO}gE%=IP|aj~{&c88+cg_4~cuzy8mEtm?${ z?(xaAwCS8G2Dc|X_CN7*6ZcNrxY-lV%X37vIz99-NfYc+pR}@s?O2NB(@(97I)qeq zu35n3b~S3RV}?`MRk2$#R(It%UnCpk^cp-<@T*W-W^9|d@4<#E(i@`kx9$G>kmK8L z*5$_WJ7V$;P8GI)3HWfu=LFOGhtju>v&7c5*D|I{3%Si@c=8hHTGbNQh?11Vl2ohY zqEsNoU}RuuplfKPYhV~+WME}tY-M7qZD49;U@-5U-YOIgx%nxXX_XKS29{tAK-DHz Y24)Zqr>2Ll0cv3IboFyt=akR{0BzJ5f&c&j literal 0 HcmV?d00001 diff --git a/include/images/query_execfile.pngc b/include/images/query_execfile.pngc new file mode 100644 index 0000000..6e10a50 --- /dev/null +++ b/include/images/query_execfile.pngc @@ -0,0 +1,119 @@ +#ifndef QUERY_EXECFILE_PNG_H +#define QUERY_EXECFILE_PNG_H + +static const unsigned char query_execfile_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xed, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x61, 0x5a, +0x9b, 0x13, 0xc5, 0xda, 0x8d, 0xaf, 0xcc, 0x63, +0xaf, 0xcc, 0x64, 0xa9, 0xc8, 0x56, 0x94, 0xbb, +0x2f, 0xb1, 0xcd, 0x69, 0xaa, 0xc8, 0x5a, 0x8e, +0xb7, 0x26, 0x97, 0xbc, 0x38, 0xb4, 0xcf, 0x70, +0xab, 0xc9, 0x5e, 0x90, 0xb8, 0x2c, 0x92, 0xb9, +0x31, 0x9b, 0xbf, 0x43, 0xb6, 0xd1, 0x78, 0xad, +0xcb, 0x62, 0x92, 0xba, 0x33, 0x94, 0xbb, 0x38, +0x96, 0xbc, 0x3d, 0xa5, 0xc5, 0x5a, 0x6e, 0x98, +0xb2, 0x2c, 0x66, 0xbd, 0x70, 0x92, 0xc5, 0xae, +0xcb, 0x67, 0x95, 0xbb, 0x39, 0x96, 0xbd, 0x3e, +0x9e, 0xc2, 0x4f, 0xba, 0xd3, 0x81, 0x9b, 0xd0, +0xe1, 0xf2, 0xf9, 0xfc, 0xe3, 0xf3, 0xf9, 0xdb, +0xf1, 0xf8, 0xe4, 0xf5, 0xfb, 0x9d, 0xc8, 0xe6, +0xb0, 0xcd, 0x6c, 0x97, 0xbd, 0x40, 0x9f, 0xc2, +0x51, 0xba, 0xd3, 0x83, 0x7a, 0xbf, 0xd7, 0xb1, +0xb1, 0xb1, 0xc8, 0xeb, 0xf7, 0x7e, 0xb4, 0xe0, +0xb2, 0xce, 0x71, 0x9f, 0xc3, 0x53, 0xba, 0xd4, +0x83, 0x7b, 0xbe, 0xd8, 0xea, 0xf6, 0xfb, 0xd2, +0xee, 0xf8, 0xda, 0xf2, 0xfa, 0x7f, 0xb2, 0xe1, +0xba, 0xd4, 0x85, 0x7c, 0xbc, 0xda, 0x3b, 0x7f, +0xc4, 0x3c, 0x7b, 0xc8, 0x80, 0xb0, 0xe3, 0xce, +0xe0, 0xa7, 0x7c, 0xba, 0xdb, 0x51, 0xa1, 0xd0, +0x52, 0x9f, 0xd2, 0x53, 0x9c, 0xd4, 0x53, 0x9a, +0xd5, 0x54, 0x97, 0xd7, 0x55, 0x95, 0xd9, 0x80, +0xae, 0xe3, 0x7d, 0xb9, 0xdc, 0x3c, 0x7d, 0xc6, +0x3d, 0x79, 0xc9, 0x56, 0x92, 0xdb, 0x80, 0xac, +0xe5, 0x93, 0xc3, 0xe3, 0xe0, 0xf2, 0xf9, 0x56, +0x90, 0xdc, 0x81, 0xaa, 0xe6, 0xec, 0xf7, 0xfc, +0xdc, 0xf3, 0xfa, 0xa0, 0xbe, 0xed, 0xa6, 0x3b, +0x61, 0xb6, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0xa2, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x5d, 0xcf, +0xd7, 0x0e, 0x82, 0x50, 0x10, 0x04, 0xd0, 0xcb, +0xda, 0x7b, 0xd7, 0xb1, 0x21, 0x88, 0x15, 0x7b, +0xef, 0xbd, 0x8b, 0xfa, 0xff, 0x9f, 0xe3, 0x25, +0x42, 0x02, 0xee, 0xe3, 0xc9, 0x66, 0x66, 0x97, +0x09, 0x24, 0x30, 0xdb, 0x90, 0xe3, 0x4f, 0xc8, +0xe9, 0xb2, 0x0b, 0xb9, 0x3d, 0x5e, 0x9b, 0x90, +0xcf, 0x1f, 0x08, 0x5a, 0x85, 0x42, 0xe1, 0x48, +0x34, 0x66, 0x11, 0x8a, 0x27, 0x92, 0xa9, 0x74, +0x06, 0xc6, 0x64, 0x19, 0xe5, 0xf2, 0x85, 0xa2, +0x88, 0x12, 0x24, 0xb9, 0xac, 0xa0, 0x02, 0x46, +0xd5, 0x5a, 0xbd, 0x41, 0x68, 0x42, 0x56, 0xd5, +0x16, 0xda, 0x1c, 0x3a, 0xdd, 0x1e, 0x09, 0xe8, +0x63, 0x30, 0x6c, 0x8d, 0x30, 0xe6, 0x20, 0x4e, +0x78, 0x22, 0xa6, 0x33, 0x3d, 0x61, 0xbe, 0xe0, +0xb0, 0xd4, 0x1b, 0xb0, 0x5a, 0x6f, 0xb6, 0xbb, +0xfd, 0xe1, 0x08, 0xf6, 0xfb, 0x05, 0xa7, 0x33, +0x5f, 0xb8, 0x5c, 0x6f, 0x30, 0xca, 0x71, 0x87, +0xf4, 0x50, 0xf0, 0xd4, 0x4c, 0xc8, 0x02, 0xaf, +0xe1, 0x1b, 0xda, 0xc7, 0x04, 0x5d, 0x7e, 0x87, +0x7d, 0x01, 0x67, 0x1b, 0x12, 0x46, 0x9d, 0x00, +0xe4, 0xe9, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, +0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *query_execfile_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_query_execfile_png = new wxImage(); + if (!img_query_execfile_png || !img_query_execfile_png->IsOk()) + { + wxMemoryInputStream img_query_execfile_pngIS(query_execfile_png_data, sizeof(query_execfile_png_data)); + img_query_execfile_png->LoadFile(img_query_execfile_pngIS, wxBITMAP_TYPE_PNG); + } + return img_query_execfile_png; +} +#define query_execfile_png_img query_execfile_png_img() + +static wxBitmap *query_execfile_png_bmp() +{ + static wxBitmap *bmp_query_execfile_png; + if (!bmp_query_execfile_png || !bmp_query_execfile_png->IsOk()) + bmp_query_execfile_png = new wxBitmap(*query_execfile_png_img); + return bmp_query_execfile_png; +} +#define query_execfile_png_bmp query_execfile_png_bmp() + +static wxIcon *query_execfile_png_ico() +{ + static wxIcon *ico_query_execfile_png; + if (!ico_query_execfile_png || !ico_query_execfile_png->IsOk()) + { + ico_query_execfile_png = new wxIcon(); + ico_query_execfile_png->CopyFromBitmap(*query_execfile_png_bmp); + } + return ico_query_execfile_png; +} +#define query_execfile_png_ico query_execfile_png_ico() + +#endif // QUERY_EXECFILE_PNG_H diff --git a/include/images/query_execute.png b/include/images/query_execute.png new file mode 100644 index 0000000000000000000000000000000000000000..23c8dcb2c3205e76690aca34e761dfa1966ed8d8 GIT binary patch literal 402 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}QGic~E0FHqm>4x%_~@e!&b5&u*jvIh+L^k;OpT1B~5HX4?T7;hrvzArhC96ArLR%#;XZ zoiXF0%Z!MKK-U>JZdeAm%&^$GqjG}ljEbK>SXm~z%xGzGbvb%urT~-Bq@YViC$v(Y zJ`oK#6A%*Qw$;^*^{niw485ZtxZ@ZYI%}B4S^L(4>{TssjVMV;EJ?LWE=mPb3`Pcq z2D*kux(0?JMg~?U##Sb#+6Jap1_txq>8(Q1kei>9nN|tWU|090*aWnc!;aB6z! Q8lVOSPgg&ebxsLQ0PU@pEC2ui literal 0 HcmV?d00001 diff --git a/include/images/query_execute.pngc b/include/images/query_execute.pngc new file mode 100644 index 0000000..ca32fe4 --- /dev/null +++ b/include/images/query_execute.pngc @@ -0,0 +1,95 @@ +#ifndef QUERY_EXECUTE_PNG_H +#define QUERY_EXECUTE_PNG_H + +static const unsigned char query_execute_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x72, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x61, 0x5a, +0x9b, 0x13, 0xc5, 0xda, 0x8d, 0xaf, 0xcc, 0x63, +0xaf, 0xcc, 0x64, 0xa9, 0xc8, 0x56, 0x94, 0xbb, +0x2f, 0xb1, 0xcd, 0x69, 0xaa, 0xc8, 0x5a, 0x8e, +0xb7, 0x26, 0x97, 0xbc, 0x38, 0xb4, 0xcf, 0x70, +0xab, 0xc9, 0x5e, 0x90, 0xb8, 0x2c, 0x92, 0xb9, +0x31, 0x9b, 0xbf, 0x43, 0xb6, 0xd1, 0x78, 0xad, +0xcb, 0x62, 0x92, 0xba, 0x33, 0x94, 0xbb, 0x38, +0x96, 0xbc, 0x3d, 0xa5, 0xc5, 0x5a, 0xcc, 0xdf, +0xa3, 0xae, 0xcb, 0x67, 0x95, 0xbb, 0x39, 0x96, +0xbd, 0x3e, 0x9e, 0xc2, 0x4f, 0xba, 0xd3, 0x81, +0xb0, 0xcd, 0x6c, 0x97, 0xbd, 0x40, 0x9f, 0xc2, +0x51, 0xba, 0xd3, 0x83, 0xb2, 0xce, 0x71, 0x9f, +0xc3, 0x53, 0xba, 0xd4, 0x83, 0xba, 0xd4, 0x85, +0xce, 0xe0, 0xa7, 0x9d, 0xfc, 0x84, 0xf4, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x57, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x63, 0x60, 0xc0, 0x06, 0x18, +0x99, 0x18, 0x51, 0x05, 0x98, 0x98, 0xd1, 0x44, +0x98, 0x58, 0x58, 0x51, 0x45, 0x98, 0xd8, 0xd8, +0x39, 0x50, 0x44, 0x98, 0x38, 0xb9, 0xb8, 0x79, +0x90, 0x45, 0x98, 0x78, 0xf9, 0xf8, 0x05, 0x04, +0x91, 0x44, 0x98, 0x84, 0x84, 0x45, 0x44, 0xc5, +0xc4, 0x99, 0x10, 0x02, 0x12, 0x92, 0x52, 0xd2, +0x32, 0xc8, 0x2a, 0x64, 0xe5, 0xe4, 0x15, 0x50, +0xcc, 0x50, 0x54, 0x52, 0x46, 0xb5, 0x45, 0x46, +0x05, 0xcd, 0x1d, 0xaa, 0x68, 0x2e, 0xc5, 0xf0, +0x0b, 0x5e, 0x00, 0x00, 0x89, 0x7c, 0x03, 0x17, +0x05, 0x8e, 0xad, 0x66, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *query_execute_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_query_execute_png = new wxImage(); + if (!img_query_execute_png || !img_query_execute_png->IsOk()) + { + wxMemoryInputStream img_query_execute_pngIS(query_execute_png_data, sizeof(query_execute_png_data)); + img_query_execute_png->LoadFile(img_query_execute_pngIS, wxBITMAP_TYPE_PNG); + } + return img_query_execute_png; +} +#define query_execute_png_img query_execute_png_img() + +static wxBitmap *query_execute_png_bmp() +{ + static wxBitmap *bmp_query_execute_png; + if (!bmp_query_execute_png || !bmp_query_execute_png->IsOk()) + bmp_query_execute_png = new wxBitmap(*query_execute_png_img); + return bmp_query_execute_png; +} +#define query_execute_png_bmp query_execute_png_bmp() + +static wxIcon *query_execute_png_ico() +{ + static wxIcon *ico_query_execute_png; + if (!ico_query_execute_png || !ico_query_execute_png->IsOk()) + { + ico_query_execute_png = new wxIcon(); + ico_query_execute_png->CopyFromBitmap(*query_execute_png_bmp); + } + return ico_query_execute_png; +} +#define query_execute_png_ico query_execute_png_ico() + +#endif // QUERY_EXECUTE_PNG_H diff --git a/include/images/query_explain.png b/include/images/query_explain.png new file mode 100644 index 0000000000000000000000000000000000000000..986aa8af5663d414a6e06e3a8da425e90160a5ae GIT binary patch literal 455 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}OMp*^E08|1Ch5>*(bu3En!UZI{{2PZ$H%>&9>o6rRI;GeroKG6v9a;!tw&Am9ox5WpE+}8QBl#= z_dm8CJKNOOary0!sq+?1Zt%JK?#Gdvk1oCWIc47BD{p@sy773zgbACDp4)WfTw`0u z`By(D&s|(o*RbjExdYc8pL_Z1?8{%=2VSTG-N9HAe4RT>+k^l4m|H~DbMthoT!#rO8*L-w& zcFOL{A15sN?ZeYcptAuDUumo!Wsy4AQ XFoS3~H9d3UftDnm{r-UW|>hsBu literal 0 HcmV?d00001 diff --git a/include/images/query_explain.pngc b/include/images/query_explain.pngc new file mode 100644 index 0000000..7aa5059 --- /dev/null +++ b/include/images/query_explain.pngc @@ -0,0 +1,101 @@ +#ifndef QUERY_EXPLAIN_PNG_H +#define QUERY_EXPLAIN_PNG_H + +static const unsigned char query_explain_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x84, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc8, 0xac, 0x62, 0xc2, +0x93, 0x15, 0xeb, 0xdb, 0x9a, 0xe7, 0xd3, 0x73, +0xec, 0xda, 0x68, 0xf5, 0xe8, 0x85, 0xe6, 0xcd, +0x36, 0xed, 0xd6, 0x27, 0xf7, 0xe8, 0x51, 0xf1, +0xe3, 0x8d, 0xf2, 0xe0, 0x5d, 0xfd, 0xf2, 0x74, +0xa0, 0x85, 0x3c, 0x7f, 0x77, 0x63, 0x81, 0x81, +0x81, 0xc5, 0xda, 0xe2, 0x82, 0x87, 0x88, 0xb7, +0xb7, 0xb7, 0x99, 0x99, 0x99, 0x72, 0x72, 0x72, +0xd5, 0xef, 0xf8, 0xb5, 0xc6, 0xcd, 0x82, 0x86, +0x88, 0xd3, 0xed, 0xf8, 0x95, 0x9e, 0xa2, 0x93, +0x80, 0x4c, 0xd5, 0xee, 0xf8, 0xc4, 0xd9, 0xe2, +0xd2, 0xec, 0xf9, 0x94, 0x9e, 0xa3, 0xd4, 0xed, +0xf8, 0xc2, 0xd8, 0xe3, 0x90, 0x90, 0x90, 0xb2, +0xc5, 0xce, 0xb2, 0xc4, 0xce, 0x81, 0x86, 0x88, +0xcf, 0xea, 0xf9, 0x93, 0x9d, 0xa3, 0x7c, 0x7e, +0x80, 0xb2, 0xc3, 0xce, 0xc0, 0xd6, 0xe3, 0xce, +0xe9, 0xfa, 0xcd, 0xe9, 0xfa, 0x0b, 0xc0, 0xe8, +0x25, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x7a, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x55, 0xcf, 0xcb, +0x16, 0x82, 0x30, 0x0c, 0x45, 0xd1, 0xb4, 0xa2, +0x88, 0x88, 0xc5, 0x72, 0x85, 0x52, 0x44, 0x05, +0x04, 0x1f, 0xfc, 0xff, 0xff, 0xe9, 0xa8, 0x69, +0x32, 0xbc, 0x83, 0x7d, 0x56, 0x48, 0xe9, 0xff, +0x29, 0xe2, 0xd3, 0x9b, 0x64, 0xbb, 0xd3, 0xf1, +0x90, 0xa4, 0xfb, 0x4c, 0x0c, 0x87, 0x3c, 0x3b, +0xc6, 0x83, 0xd2, 0xc5, 0xa9, 0x88, 0x0d, 0x22, +0x53, 0x9e, 0x6d, 0x85, 0x8a, 0x75, 0x5c, 0xea, +0x06, 0xae, 0xf5, 0x41, 0x47, 0x57, 0x5f, 0x9d, +0xeb, 0x11, 0x74, 0x74, 0x30, 0xe8, 0x6f, 0x3e, +0xe8, 0xb8, 0x83, 0xa4, 0xe1, 0x40, 0xb2, 0xf2, +0x68, 0x64, 0x65, 0x18, 0xa7, 0x27, 0xe6, 0x85, +0x2b, 0xf6, 0xf5, 0xfe, 0xcc, 0xdf, 0x95, 0x2b, +0x64, 0x07, 0x83, 0x75, 0xf1, 0xe2, 0x07, 0x36, +0x7e, 0x70, 0x8c, 0x08, 0x96, 0x85, 0x6a, 0x4b, +0x1c, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, +0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *query_explain_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_query_explain_png = new wxImage(); + if (!img_query_explain_png || !img_query_explain_png->IsOk()) + { + wxMemoryInputStream img_query_explain_pngIS(query_explain_png_data, sizeof(query_explain_png_data)); + img_query_explain_png->LoadFile(img_query_explain_pngIS, wxBITMAP_TYPE_PNG); + } + return img_query_explain_png; +} +#define query_explain_png_img query_explain_png_img() + +static wxBitmap *query_explain_png_bmp() +{ + static wxBitmap *bmp_query_explain_png; + if (!bmp_query_explain_png || !bmp_query_explain_png->IsOk()) + bmp_query_explain_png = new wxBitmap(*query_explain_png_img); + return bmp_query_explain_png; +} +#define query_explain_png_bmp query_explain_png_bmp() + +static wxIcon *query_explain_png_ico() +{ + static wxIcon *ico_query_explain_png; + if (!ico_query_explain_png || !ico_query_explain_png->IsOk()) + { + ico_query_explain_png = new wxIcon(); + ico_query_explain_png->CopyFromBitmap(*query_explain_png_bmp); + } + return ico_query_explain_png; +} +#define query_explain_png_ico query_explain_png_ico() + +#endif // QUERY_EXPLAIN_PNG_H diff --git a/include/images/query_pgscript.png b/include/images/query_pgscript.png new file mode 100644 index 0000000000000000000000000000000000000000..c212ca5225e0a244d25035fdb7fc3229affac528 GIT binary patch literal 450 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}b%0NZE0FHqm>4x%_~@-(28Oit zXOh>SNm+R!Y|3u^jb}4gorvn&t~Py-#g_90t53#F*r79Nr{V1V&f6|ltUaAHX_xVo z-4@gK*e*R9b>{x!b*Iy(?zWt^*KXb+|6P|GH=NCxzSm*?p}<|2n>U>+oPRiY*Og|5 zG=`ZB47;who_nxd-!%O&(0ay_AirP+hi5m^fE>;OkH}&m?E%JaC$sH_rTMwWGqSFWG4uVs*V%bxG3zMLEA64esdh?11Vl2ohYqEsNoU}Ruu zplfKPYhV~+WME}tY-M7qZD49;U@-5U-YOIgx%nxXX_XKS29{tAK-DHz24)Zqr>2Ll Q0cv3IboFyt=akR{0Q9%8FaQ7m literal 0 HcmV?d00001 diff --git a/include/images/query_pgscript.pngc b/include/images/query_pgscript.pngc new file mode 100644 index 0000000..36e5dbd --- /dev/null +++ b/include/images/query_pgscript.pngc @@ -0,0 +1,101 @@ +#ifndef QUERY_PGSCRIPT_PNG_H +#define QUERY_PGSCRIPT_PNG_H + +static const unsigned char query_pgscript_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x7b, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x61, 0x5a, +0x9b, 0x13, 0xc5, 0xda, 0x8d, 0x00, 0x00, 0x66, +0xaf, 0xcc, 0x63, 0xaf, 0xcc, 0x64, 0xa9, 0xc8, +0x56, 0x94, 0xbb, 0x2f, 0xb1, 0xcd, 0x69, 0xaa, +0xc8, 0x5a, 0x8e, 0xb7, 0x26, 0x97, 0xbc, 0x38, +0xb4, 0xcf, 0x70, 0xab, 0xc9, 0x5e, 0x90, 0xb8, +0x2c, 0x92, 0xb9, 0x31, 0x9b, 0xbf, 0x43, 0xb6, +0xd1, 0x78, 0xad, 0xcb, 0x62, 0x92, 0xba, 0x33, +0x94, 0xbb, 0x38, 0x96, 0xbc, 0x3d, 0xa5, 0xc5, +0x5a, 0xcc, 0xdf, 0xa3, 0xae, 0xcb, 0x67, 0x95, +0xbb, 0x39, 0x96, 0xbd, 0x3e, 0x9e, 0xc2, 0x4f, +0xba, 0xd3, 0x81, 0xb0, 0xcd, 0x6c, 0x97, 0xbd, +0x40, 0x9f, 0xc2, 0x51, 0xba, 0xd3, 0x83, 0xb2, +0xce, 0x71, 0x9f, 0xc3, 0x53, 0xba, 0xd4, 0x83, +0x00, 0x66, 0x00, 0x99, 0x00, 0x00, 0xba, 0xd4, +0x85, 0xce, 0xe0, 0xa7, 0x2f, 0x35, 0x67, 0xc3, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x7e, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x65, 0x8f, 0xe7, 0x12, +0xc2, 0x30, 0x0c, 0x83, 0x15, 0x51, 0xf6, 0x2a, +0x7b, 0x96, 0x51, 0x70, 0xe0, 0xfd, 0x9f, 0x10, +0x57, 0x6d, 0x8e, 0x72, 0xe8, 0xf4, 0xc7, 0x9f, +0x65, 0x27, 0x46, 0x60, 0xc0, 0x8f, 0xd8, 0x69, +0x48, 0xe6, 0x12, 0xe8, 0xf6, 0x12, 0x91, 0xc1, +0xfe, 0x60, 0x58, 0x93, 0x04, 0x46, 0xe3, 0xc9, +0x54, 0x24, 0x8d, 0xcc, 0xe6, 0xf9, 0x62, 0x59, +0x91, 0xac, 0x59, 0xba, 0x5a, 0x6f, 0xb6, 0xbb, +0x3d, 0x53, 0x00, 0x3c, 0x1c, 0x4f, 0xe7, 0xa2, +0xf5, 0x36, 0x2f, 0xd7, 0xdb, 0xbd, 0xfd, 0x17, +0x96, 0x8f, 0x27, 0x83, 0x99, 0x01, 0xd1, 0xe5, +0xa0, 0x78, 0x79, 0xad, 0x5e, 0x94, 0xf9, 0xf6, +0x7c, 0x0d, 0x50, 0x05, 0xa0, 0x5b, 0x0c, 0x9a, +0x51, 0x42, 0x32, 0x39, 0x7e, 0x01, 0xd4, 0xd7, +0xce, 0x3f, 0x7d, 0x00, 0x1c, 0xed, 0x07, 0x6f, +0x41, 0x27, 0xa7, 0x0b, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *query_pgscript_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_query_pgscript_png = new wxImage(); + if (!img_query_pgscript_png || !img_query_pgscript_png->IsOk()) + { + wxMemoryInputStream img_query_pgscript_pngIS(query_pgscript_png_data, sizeof(query_pgscript_png_data)); + img_query_pgscript_png->LoadFile(img_query_pgscript_pngIS, wxBITMAP_TYPE_PNG); + } + return img_query_pgscript_png; +} +#define query_pgscript_png_img query_pgscript_png_img() + +static wxBitmap *query_pgscript_png_bmp() +{ + static wxBitmap *bmp_query_pgscript_png; + if (!bmp_query_pgscript_png || !bmp_query_pgscript_png->IsOk()) + bmp_query_pgscript_png = new wxBitmap(*query_pgscript_png_img); + return bmp_query_pgscript_png; +} +#define query_pgscript_png_bmp query_pgscript_png_bmp() + +static wxIcon *query_pgscript_png_ico() +{ + static wxIcon *ico_query_pgscript_png; + if (!ico_query_pgscript_png || !ico_query_pgscript_png->IsOk()) + { + ico_query_pgscript_png = new wxIcon(); + ico_query_pgscript_png->CopyFromBitmap(*query_pgscript_png_bmp); + } + return ico_query_pgscript_png; +} +#define query_pgscript_png_ico query_pgscript_png_ico() + +#endif // QUERY_PGSCRIPT_PNG_H diff --git a/include/images/query_rollback.png b/include/images/query_rollback.png new file mode 100644 index 0000000000000000000000000000000000000000..b78ce614bbff77a80aae4e32e4aa1adc71ce4642 GIT binary patch literal 583 zcmV-N0=WH&P)N2bZe?^J zG%heMHD!e|WdHyH#Ysd#R5(wCk=;vEaTv$_ANn7>5>f)4h!J$B;7i>N@xrJ`y68e7 z@Jj1iY}s*RkYRYCHaEhz&9ln+lCq>?H>Hl_oG+a@y>J6fs89PHcYf`(Gkf66;rBe> z?}vxylmWJKdauysX+V7cofXQqX@);(um1}vYM9}fua6mBb`py9UJ9{1%<$CbM|j`g zL{aN`8EMWzo|J?Xg$L)a(mz|yz+45c&^2Dn*D@5o!SLd3TZjc<%5H!xPn!=Z5$}!>kLO)jeg!H%K~`otz%{Cfngk9buzKmjxXB5Wb{6P^@m1Z_1(hn zu9hhYSn%B;{>1~ojtyfeX_}XhYA3=kauN`5*Rd9CBer^vqxdwL{dX5S^rI)9ONqJg z&5bl!0dHKDBsat8TR|2Boy@*!#IMvyiMQyd^(9g}A%tJ#EP%augly^?oMqtjnBUnL z+4MAr2{+ptJ!l(G*-a??NKTXnoTR?Pc@}x?8B(`z@O+nusw+BSkzWfF! z5@2kQEZ9JEv;LvG7$7R(sUIsOk()) + { + wxMemoryInputStream img_query_rollback_pngIS(query_rollback_png_data, sizeof(query_rollback_png_data)); + img_query_rollback_png->LoadFile(img_query_rollback_pngIS, wxBITMAP_TYPE_PNG); + } + return img_query_rollback_png; +} +#define query_rollback_png_img query_rollback_png_img() + +static wxBitmap *query_rollback_png_bmp() +{ + static wxBitmap *bmp_query_rollback_png; + if (!bmp_query_rollback_png || !bmp_query_rollback_png->IsOk()) + bmp_query_rollback_png = new wxBitmap(*query_rollback_png_img); + return bmp_query_rollback_png; +} +#define query_rollback_png_bmp query_rollback_png_bmp() + +static wxIcon *query_rollback_png_ico() +{ + static wxIcon *ico_query_rollback_png; + if (!ico_query_rollback_png || !ico_query_rollback_png->IsOk()) + { + ico_query_rollback_png = new wxIcon(); + ico_query_rollback_png->CopyFromBitmap(*query_rollback_png_bmp); + } + return ico_query_rollback_png; +} +#define query_rollback_png_ico query_rollback_png_ico() + +#endif // QUERY_ROLLBACK_PNG_H diff --git a/include/images/readdata.png b/include/images/readdata.png new file mode 100644 index 0000000000000000000000000000000000000000..fd9aa5a00ebd1cac32f914f0e7d5d6e5233c5ce0 GIT binary patch literal 819 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47#jk7LR^8|^E-B&EiFB5ZGB2m z@Z7X%=fp+th5Ns1Dfu+F_0#O8*9`^tLwwGQ37-iIJITOsMMvXheZiNRRi8VOKh=kS zt`7WK7y7+B^>tbD6)lxNTjzeBSn##x;ZQ#EezkdtrZ+>b$^)~Fn z`}F%?XKs5YzVn5`>31>PpG)j}ZM5R9?V(Prm7hz0G`_mYvNSd2=@U_rsZ&Bj8kv0FWWAD_6&3a7mesDRUk;4Sc6D{m z%E`%g!okMH+;uY!^3?p9Ruy*5><`bjvV?@w`R^aRNO^qbe8TfbuU@@+mdAdDgQIsOk()) + { + wxMemoryInputStream img_readdata_pngIS(readdata_png_data, sizeof(readdata_png_data)); + img_readdata_png->LoadFile(img_readdata_pngIS, wxBITMAP_TYPE_PNG); + } + return img_readdata_png; +} +#define readdata_png_img readdata_png_img() + +static wxBitmap *readdata_png_bmp() +{ + static wxBitmap *bmp_readdata_png; + if (!bmp_readdata_png || !bmp_readdata_png->IsOk()) + bmp_readdata_png = new wxBitmap(*readdata_png_img); + return bmp_readdata_png; +} +#define readdata_png_bmp readdata_png_bmp() + +static wxIcon *readdata_png_ico() +{ + static wxIcon *ico_readdata_png; + if (!ico_readdata_png || !ico_readdata_png->IsOk()) + { + ico_readdata_png = new wxIcon(); + ico_readdata_png->CopyFromBitmap(*readdata_png_bmp); + } + return ico_readdata_png; +} +#define readdata_png_ico readdata_png_ico() + +#endif // READDATA_PNG_H diff --git a/include/images/refresh.png b/include/images/refresh.png new file mode 100644 index 0000000000000000000000000000000000000000..4c7b134b5d43ca54041640d04ecaf579aeced157 GIT binary patch literal 1190 zcmV;X1X=ruP))~)Wf^bcXHT5KIC?A?30D{q>K2hk@B5}?2CQhU|aN! zYxIIz@^(w~Z$SK%are8h@OV%1aYXcMJoRWc`(-iqWHI`1KlF%W?Spgklzhnm0MBr1 z+*MNXd{g*fEBRR=`*A|{dRY2Y8v9QZ{E}?;n0NP`efV!c{*Y?mWnleF4br8a<62Dl zXgAwYP4$_6^pkPe#r;W)4zhu4)y)x-ut2A`l-Rv zo|e%$+WC#d^-9M1RLlBd-S()5${ViFakb%a)c1PE_fXIJZPM?Y+w+Xw^pxrNx$O7b ziO(C&)49;oz|HNG&G%);`B&Bafx+g6x8@kQ=pVZ2BgO7Z+3}yq_gJFYOS{pKxaS+Z z>nh6bYO2p`tK3}G^pVK=TG0G;)A60X?K0l|o5Alr(e`kK%@oMsCho>YCnUCkP&x zpSL<3?;Ri3*B2}!09(`BkWUB!Rvtidy4(_=Q0r|Zi2%FF2$kd1yTM0ub^M(0Zzn;3Q^%mG#U*D-%5?q@kAoYq|)OwUTIbW zSZ*(qN$zK9{tyTs2s%7EKFJOJJXI)WlBIG*=pk@$dU|?xR;~R!VMhV+da}es8ch*6 zKR>HpTuOfa>eqEKS!&(fQh5nLe*2Q6*jOkOV=3->zf@{5ciiwr-~i=cT(mpg0!LF6 z%@yKI9r@)#FC+m~6o82P?!)6_e6NV=x0su!VFx@=?bK@RcDvsn3Smr{^naDS;z2U!(AFKYGvH+!Y$5rODFAXuf8T%f`FKdZy0omm{}a zuQ}d3E6kr`sYWH6ibhk}N`qo^lRqOKLQOxN4hGY-znPc)hyDOFLXha+G+>7S001R) zMObuXVRU6WV{&C-bY%cCFflMKF)}SMF;p@zIy5snG&L(QH99abp6)KH0000bbVXQn zWMOn=I&E)cX=ZrIsOk()) + { + wxMemoryInputStream img_refresh_pngIS(refresh_png_data, sizeof(refresh_png_data)); + img_refresh_png->LoadFile(img_refresh_pngIS, wxBITMAP_TYPE_PNG); + } + return img_refresh_png; +} +#define refresh_png_img refresh_png_img() + +static wxBitmap *refresh_png_bmp() +{ + static wxBitmap *bmp_refresh_png; + if (!bmp_refresh_png || !bmp_refresh_png->IsOk()) + bmp_refresh_png = new wxBitmap(*refresh_png_img); + return bmp_refresh_png; +} +#define refresh_png_bmp refresh_png_bmp() + +static wxIcon *refresh_png_ico() +{ + static wxIcon *ico_refresh_png; + if (!ico_refresh_png || !ico_refresh_png->IsOk()) + { + ico_refresh_png = new wxIcon(); + ico_refresh_png->CopyFromBitmap(*refresh_png_bmp); + } + return ico_refresh_png; +} +#define refresh_png_ico refresh_png_ico() + +#endif // REFRESH_PNG_H diff --git a/include/images/reload.png b/include/images/reload.png new file mode 100644 index 0000000000000000000000000000000000000000..4dd0e004171363dada09264ead8e230e05b34cc6 GIT binary patch literal 368 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaN3?zjj6;1;w=>VS)*K3#0C8wS>+sSM@AY-Pdi(`ny<=(!HT!$3|+C;5( z%nLj*0ViTMyw$tG&T(X~!kt+ckH5>z*)+B8a_yi0vg$|lRTy5ZFFAIAJG!9s zTwA5aW0%gtYuANrXI8JUwVZn7cBn^biVG?$vke5;fsRxy zag8WRNi0dVN-jzTQVd20h6cKZM!E)uAw~vPCdO7KrrHLkRt5(1-s!DE(U6;;l9^Ts h(O_T+)&Nv(Vr5_k(Qs;d=o+8~22WQ%mvv4FO#nOrg#Q2l literal 0 HcmV?d00001 diff --git a/include/images/reload.pngc b/include/images/reload.pngc new file mode 100644 index 0000000..fd1d315 --- /dev/null +++ b/include/images/reload.pngc @@ -0,0 +1,90 @@ +#ifndef RELOAD_PNG_H +#define RELOAD_PNG_H + +static const unsigned char reload_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, +0x04, 0x03, 0x00, 0x00, 0x00, 0x12, 0x59, 0x20, +0xcb, 0x00, 0x00, 0x00, 0x1b, 0x50, 0x4c, 0x54, +0x45, 0xd6, 0xd3, 0xce, 0x63, 0x65, 0xce, 0x31, +0x30, 0x63, 0xc6, 0xc3, 0xc6, 0x9c, 0x9a, 0xff, +0x21, 0x20, 0x21, 0x00, 0x00, 0x84, 0xce, 0xcf, +0xff, 0x84, 0x82, 0x84, 0x7e, 0xd7, 0x45, 0xcb, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x99, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x8d, +0x8e, 0xb1, 0x0a, 0xc3, 0x20, 0x10, 0x86, 0x15, +0x3a, 0xb8, 0x9e, 0x51, 0xc8, 0x98, 0xdc, 0xd0, +0xbd, 0x50, 0xc8, 0x5c, 0xb0, 0xed, 0x2e, 0xd8, +0x07, 0x08, 0xc4, 0xbd, 0x20, 0xdc, 0x9a, 0xd1, +0xc7, 0xee, 0x69, 0x6c, 0xb2, 0x95, 0x7e, 0xd3, +0x7d, 0xfc, 0xff, 0x1d, 0x27, 0xc4, 0x2f, 0x24, +0x00, 0xe8, 0xaf, 0x74, 0xc6, 0xc0, 0x0b, 0x5b, +0x70, 0x75, 0xce, 0x86, 0x79, 0x28, 0xe3, 0x44, +0x89, 0x71, 0xd6, 0xd7, 0x12, 0x3d, 0x99, 0x7b, +0xa8, 0x3d, 0x39, 0x95, 0xc4, 0xc7, 0x6d, 0xa9, +0x23, 0x22, 0x7b, 0x6e, 0xc2, 0x5b, 0x6f, 0x1f, +0x9b, 0x70, 0x64, 0xc7, 0x5d, 0xe4, 0xc5, 0xcb, +0x5d, 0x04, 0x0e, 0x32, 0x2e, 0x78, 0x7c, 0xc4, +0xa2, 0xca, 0xc0, 0xc7, 0x28, 0x3d, 0x02, 0xaa, +0x95, 0x25, 0x39, 0xc6, 0x2e, 0x98, 0x0f, 0x09, +0x08, 0xa5, 0x96, 0x0c, 0x03, 0x5e, 0xf7, 0x45, +0x4e, 0x50, 0x19, 0x73, 0x3d, 0x75, 0xd3, 0x88, +0x33, 0xf6, 0xeb, 0x76, 0x58, 0xe5, 0x82, 0xf8, +0x97, 0x0f, 0x78, 0xd0, 0x24, 0xa9, 0x6b, 0x30, +0x10, 0x07, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, +0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *reload_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_reload_png = new wxImage(); + if (!img_reload_png || !img_reload_png->IsOk()) + { + wxMemoryInputStream img_reload_pngIS(reload_png_data, sizeof(reload_png_data)); + img_reload_png->LoadFile(img_reload_pngIS, wxBITMAP_TYPE_PNG); + } + return img_reload_png; +} +#define reload_png_img reload_png_img() + +static wxBitmap *reload_png_bmp() +{ + static wxBitmap *bmp_reload_png; + if (!bmp_reload_png || !bmp_reload_png->IsOk()) + bmp_reload_png = new wxBitmap(*reload_png_img); + return bmp_reload_png; +} +#define reload_png_bmp reload_png_bmp() + +static wxIcon *reload_png_ico() +{ + static wxIcon *ico_reload_png; + if (!ico_reload_png || !ico_reload_png->IsOk()) + { + ico_reload_png = new wxIcon(); + ico_reload_png->CopyFromBitmap(*reload_png_bmp); + } + return ico_reload_png; +} +#define reload_png_ico reload_png_ico() + +#endif // RELOAD_PNG_H diff --git a/include/images/resourcegroup.png b/include/images/resourcegroup.png new file mode 100644 index 0000000000000000000000000000000000000000..668089e80e8e05001aa5130a4578736fa97fbd2e GIT binary patch literal 966 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F z14ET614BbI1H;e%K>8&EL#Y7+!>a@a2CEqi4C48d;*Yv9FfgtP@CkAK|Np<+g3sQ| zetRzmqQ9Ptf4I$m=RWs=>#RG@GwyiIyyiFOtiz1w`puV=iw~(6?Nlq;;lA**X60e` zgfv-X1~&0D>ed^2rc<-O>(+x(~cjb{v6&KWdc)UG?DS$)!R)*GNL zCLLD|n$PJqUeIqisa>&U=IQ_IuKrzj_5a!{|L2|kpS=0M>-5XFLilb)Gd_srydS}R zH&FP>%m24t|G)J7|H2FZeOCOp?K|@*iT!__%-=5Ezpa`N;#h9H`tLIDqeaJwXKC#J z8|D7Dsr>EIyC2W8_`-juIqytbPd|$1{9mH*zg6RJt-*sh);VYX*B|(AJN21q`?;H8 z3U@-p9z;ppi4eRL&f>A?n_2H&!?tTi?KccsF1yS;=P>1(LG@0Z;`Lg^Tl6co0X^$5 z^R?5gXI@KwM6UZEuWZwUwZy)-L-GGUjH@gy<<1+`NnI%=bZU#+{Db?MZty=&*%>U%hxK6B;Zp^GPP9=&>Y zF2Blx+;<7D9=?3~_VMfI=lO*$T)D!_!NbMJ$;;g@z`(`f=H`0b<@m9q>MClg+>ER( z!8XCcwwEs%8wGFDadn7d+EiTh`4cx+_m*y37sa+|Q>IM~4+#ssex-|%b;j1$Ua~r` zq)TMH&PW|~WU^XXy3F^i?%HRiOLK)B7(IR09{bjJPOp2;yIXRa3mUfcteLZ?Y0;!j zU8`p8Vq5l{ai*Eko>+r<5rD+3cN z19NQ*NLJbH$NpatrDuiOxMUV#L&db#K_9f6r#bpq!1Ly44$rjF6*2UngA`s B)usRd literal 0 HcmV?d00001 diff --git a/include/images/resourcegroup.pngc b/include/images/resourcegroup.pngc new file mode 100644 index 0000000..bcbf18e --- /dev/null +++ b/include/images/resourcegroup.pngc @@ -0,0 +1,165 @@ +#ifndef RESOURCEGROUP_PNG_H +#define RESOURCEGROUP_PNG_H + +static const unsigned char resourcegroup_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, +0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, +0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, +0x4d, 0x00, 0x00, 0x7a, 0x25, 0x00, 0x00, 0x80, +0x83, 0x00, 0x00, 0xf9, 0xff, 0x00, 0x00, 0x80, +0xe9, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, +0x60, 0x00, 0x00, 0x3a, 0x98, 0x00, 0x00, 0x17, +0x6f, 0x92, 0x5f, 0xc5, 0x46, 0x00, 0x00, 0x01, +0xaa, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, +0x46, 0xa0, 0xf3, 0x4b, 0xa6, 0xfb, 0x4b, 0xa7, +0xfb, 0x4b, 0xa7, 0xfd, 0x49, 0xa3, 0xf8, 0x46, +0x9f, 0xee, 0x47, 0x9d, 0xe0, 0x45, 0x9a, 0xdc, +0x43, 0x98, 0xdc, 0x48, 0x99, 0xd6, 0x4e, 0x9c, +0xcd, 0x40, 0x98, 0xe7, 0x2f, 0x83, 0xd2, 0x23, +0x73, 0xc2, 0x27, 0x72, 0xb9, 0x26, 0x72, 0xb8, +0x47, 0xa1, 0xf3, 0x29, 0x79, 0xc3, 0x47, 0xa1, +0xf5, 0x45, 0x9f, 0xf2, 0x4a, 0xa4, 0xfa, 0x3d, +0x91, 0xcd, 0x36, 0x87, 0xc1, 0x34, 0x83, 0xb5, +0x4a, 0xa4, 0xf6, 0x35, 0x83, 0xaa, 0x4b, 0xa2, +0xdb, 0x46, 0x9f, 0xe5, 0x2f, 0x81, 0xcc, 0x30, +0x84, 0xce, 0x30, 0x83, 0xd1, 0x2b, 0x7e, 0xcc, +0x29, 0x7b, 0xc9, 0x41, 0x9a, 0xec, 0x46, 0xa0, +0xf3, 0x34, 0x88, 0xd5, 0x30, 0x83, 0xce, 0x2e, +0x81, 0xd0, 0x2f, 0x80, 0xc9, 0x2b, 0x78, 0xb4, +0x99, 0xcb, 0xff, 0xae, 0xd5, 0xfd, 0xae, 0xd5, +0xff, 0xad, 0xd4, 0xff, 0x9e, 0xcd, 0xff, 0x63, +0xb3, 0xff, 0x45, 0x97, 0xd3, 0xda, 0x54, 0x0e, +0xda, 0x5b, 0x01, 0xe0, 0x5d, 0x09, 0xdf, 0x58, +0x0b, 0xdd, 0x51, 0x13, 0xd4, 0xe9, 0xff, 0xda, +0xeb, 0xff, 0xd2, 0xe7, 0xff, 0xa1, 0xd0, 0xff, +0x4c, 0xa8, 0xff, 0x3d, 0x8e, 0xcc, 0xe2, 0x62, +0x07, 0xff, 0x7e, 0x1c, 0xfd, 0x8a, 0x2d, 0xfd, +0x85, 0x29, 0xe0, 0x5e, 0x04, 0xd8, 0xea, 0xff, +0x44, 0x9e, 0xf1, 0x38, 0x88, 0xc8, 0xe6, 0x66, +0x07, 0xff, 0x81, 0x1e, 0xff, 0x86, 0x24, 0xfd, +0x8a, 0x2e, 0xdf, 0x5f, 0x04, 0xa3, 0xd0, 0xff, +0x42, 0x9c, 0xee, 0x34, 0x85, 0xcb, 0xe2, 0x5f, +0x09, 0xff, 0x74, 0x20, 0xff, 0x85, 0x28, 0xfd, +0x7d, 0x30, 0xe0, 0x5e, 0x05, 0x9c, 0xcc, 0xff, +0x7f, 0xc0, 0xff, 0x3d, 0x95, 0xe6, 0x35, 0x87, +0xce, 0xd9, 0x56, 0x20, 0xdc, 0x54, 0x16, 0xe0, +0x5a, 0x18, 0xdc, 0x58, 0x11, 0xd2, 0x57, 0x04, +0x48, 0xa2, 0xf6, 0x36, 0x8d, 0xdd, 0x31, 0x86, +0xd6, 0x32, 0x87, 0xd8, 0x30, 0x84, 0xd3, 0x44, +0x99, 0xce, 0x40, 0x94, 0xd6, 0x30, 0x7b, 0xb9, +0x2c, 0x73, 0xaf, 0x2a, 0x73, 0xb4, 0x2f, 0x78, +0xb6, 0x4a, 0xa4, 0xfa, 0x40, 0x99, 0xeb, 0x42, +0x9a, 0xe6, 0x4a, 0xa4, 0xf8, 0x59, 0xae, 0xff, +0x50, 0xaa, 0xff, 0x4b, 0xa6, 0xfb, 0xa9, 0xd3, +0xff, 0xb1, 0xd6, 0xfd, 0xad, 0xd4, 0xfd, 0x9f, +0xd0, 0xec, 0x56, 0xab, 0xe5, 0x4b, 0xa7, 0xfd, +0x96, 0xca, 0xff, 0xab, 0xd4, 0xfd, 0xab, 0xd4, +0xff, 0xd5, 0xe9, 0xff, 0xd4, 0xe9, 0xfd, 0xa6, +0xd1, 0xfa, 0x43, 0x9c, 0xeb, 0x45, 0x9f, 0xf2, +0xa9, 0xd3, 0xfd, 0xd0, 0xe6, 0xfd, 0xd5, 0xe9, +0xfb, 0xd2, 0xe7, 0xfa, 0xae, 0xd6, 0xf6, 0xda, +0xeb, 0xfd, 0x36, 0x8d, 0xdc, 0x3e, 0x96, 0xe7, +0xb1, 0xd6, 0xfb, 0x9c, 0xcc, 0xfd, 0x33, 0x87, +0xd1, 0x3b, 0x93, 0xe3, 0xa7, 0xd2, 0xff, 0xaf, +0xd6, 0xf1, 0xb1, 0xd6, 0xff, 0x96, 0xca, 0xfd, +0x35, 0x88, 0xd2, 0x3c, 0x94, 0xe3, 0xb1, 0xd8, +0xf2, 0x9e, 0xd0, 0xe2, 0xff, 0xff, 0xff, 0x4c, +0x4c, 0x22, 0xb7, 0x00, 0x00, 0x00, 0x29, 0x74, +0x52, 0x4e, 0x53, 0x00, 0xef, 0xf7, 0xf7, 0xf7, +0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, +0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, +0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xef, 0xf7, +0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, +0xf7, 0xf7, 0xf7, 0xef, 0xc4, 0xe4, 0x36, 0xb0, +0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, +0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x2e, +0x23, 0x00, 0x00, 0x2e, 0x23, 0x01, 0x78, 0xa5, +0x3f, 0x76, 0x00, 0x00, 0x00, 0xe2, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0xc0, 0x00, +0x8c, 0x4c, 0xcc, 0x2c, 0x2c, 0x2c, 0xac, 0x6c, +0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x8c, 0x40, 0x01, +0x26, 0x4d, 0x2d, 0x6d, 0x1d, 0x5d, 0x3d, 0x7d, +0x03, 0x43, 0x23, 0x63, 0x13, 0x1e, 0xa0, 0x00, +0x8b, 0x8e, 0xa9, 0x99, 0xb9, 0x85, 0xa5, 0x95, +0xb5, 0x8d, 0xad, 0x9d, 0x3d, 0x2f, 0x48, 0x40, +0xcb, 0xcc, 0xd4, 0xc1, 0xc2, 0xd1, 0xc9, 0xd9, +0xc5, 0xd5, 0xcd, 0x9d, 0x0f, 0x24, 0xa0, 0x6d, +0xee, 0x60, 0xea, 0xe1, 0xe9, 0xe5, 0xed, 0xe3, +0xeb, 0xe7, 0xcf, 0x0f, 0x12, 0xd0, 0xd4, 0xd4, +0x0d, 0x08, 0x0c, 0x0a, 0x0e, 0x09, 0x0d, 0x0b, +0x8f, 0x10, 0x00, 0x0a, 0x08, 0x46, 0x46, 0x45, +0xc7, 0x44, 0xc7, 0xc6, 0xc5, 0x27, 0x24, 0x26, +0x25, 0x0b, 0x01, 0x05, 0x84, 0x53, 0x3c, 0x53, +0x53, 0x3d, 0xd3, 0xd2, 0x33, 0x32, 0x53, 0xb2, +0x2c, 0x45, 0x40, 0x5a, 0x02, 0xb2, 0x73, 0x72, +0xf3, 0xf2, 0x0b, 0x0a, 0x8b, 0xb4, 0x8b, 0x3d, +0x44, 0x21, 0x86, 0x96, 0x94, 0x96, 0x95, 0x57, +0x54, 0x56, 0x55, 0xd7, 0xd4, 0x8a, 0x01, 0x05, +0x98, 0xb5, 0xeb, 0x4a, 0x1d, 0x2c, 0xea, 0x1b, +0x74, 0x1c, 0x4a, 0xcc, 0x1a, 0xc5, 0x41, 0x02, +0x3a, 0xa5, 0x75, 0xa6, 0x4d, 0xcd, 0x2d, 0xad, +0xe6, 0x75, 0xa5, 0x6d, 0x12, 0x40, 0x01, 0x49, +0x4d, 0xad, 0xc6, 0xf6, 0x8e, 0xce, 0x2e, 0x8b, +0x9c, 0xee, 0xda, 0x1e, 0x29, 0xa0, 0x80, 0xb4, +0x8c, 0xac, 0x9c, 0xbc, 0x82, 0xa2, 0x92, 0xb2, +0x8a, 0xaa, 0x9a, 0xba, 0x06, 0xa6, 0xe7, 0x01, +0x99, 0x36, 0x32, 0xbc, 0x5d, 0x30, 0x9e, 0x18, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x34, +0x2d, 0x30, 0x37, 0x2d, 0x30, 0x35, 0x54, 0x31, +0x33, 0x3a, 0x30, 0x34, 0x3a, 0x30, 0x37, 0x2b, +0x30, 0x34, 0x3a, 0x30, 0x30, 0x75, 0x54, 0x1e, +0x89, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x34, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x39, 0x54, +0x31, 0x34, 0x3a, 0x34, 0x32, 0x3a, 0x31, 0x35, +0x2b, 0x30, 0x34, 0x3a, 0x30, 0x30, 0x3b, 0x74, +0x71, 0x48, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *resourcegroup_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_resourcegroup_png = new wxImage(); + if (!img_resourcegroup_png || !img_resourcegroup_png->IsOk()) + { + wxMemoryInputStream img_resourcegroup_pngIS(resourcegroup_png_data, sizeof(resourcegroup_png_data)); + img_resourcegroup_png->LoadFile(img_resourcegroup_pngIS, wxBITMAP_TYPE_PNG); + } + return img_resourcegroup_png; +} +#define resourcegroup_png_img resourcegroup_png_img() + +static wxBitmap *resourcegroup_png_bmp() +{ + static wxBitmap *bmp_resourcegroup_png; + if (!bmp_resourcegroup_png || !bmp_resourcegroup_png->IsOk()) + bmp_resourcegroup_png = new wxBitmap(*resourcegroup_png_img); + return bmp_resourcegroup_png; +} +#define resourcegroup_png_bmp resourcegroup_png_bmp() + +static wxIcon *resourcegroup_png_ico() +{ + static wxIcon *ico_resourcegroup_png; + if (!ico_resourcegroup_png || !ico_resourcegroup_png->IsOk()) + { + ico_resourcegroup_png = new wxIcon(); + ico_resourcegroup_png->CopyFromBitmap(*resourcegroup_png_bmp); + } + return ico_resourcegroup_png; +} +#define resourcegroup_png_ico resourcegroup_png_ico() + +#endif // RESOURCEGROUP_PNG_H diff --git a/include/images/resourcegroups.png b/include/images/resourcegroups.png new file mode 100644 index 0000000000000000000000000000000000000000..4ea2387bac58697bbf0bab29912818f66d11c1a5 GIT binary patch literal 1173 zcmY*X3rv$&6uwZ90d|5QWrC5(z(S$4wNNOt3bX@O>7*13F=4z_2t!7ZYN8S^_Xv0<2k%P4!R}O4LKFaf_0Cv^Jzo1{#R(GtxZnpsnG66c z#L)ym2@L>qIsj}n0Hnf(&wuy?0NZ27kBN9k8s{N|F^%Iw^~Lke#CX+hQfi)iY6&~V zk)E>e{p505^1hq5^9Hp_t_Bl#tclxEVH=E8LQ1uX)qtI7hxm?ZoJ?$m^lE+RH7j4G z;i#ZMU57J#Rr85<3_rHC*;U-J8d^8SyasuiwZlrY|D`cO3of_vG-#B1k#%j=@A6z= z)rzQfmZzTOHDes*FKhvbY#0hvOw((1K~)CdOGa*!nSFirh;lNZY=lw!ic+)QtHZQL zt6~D;d{3_3LK$J=tfRkdMQenI8zH3@+gmhUmtxzKPiW1y|4{lkryCxuSUakQNo`g^ z%OX#+!mMAU$@TOaV?Z_PSvZ^6iuLNyu?4eY!WyYuc#!5{xM(|Cej^_ zP;10=W~5S!1y%oU@D(~b4|OJM#VA6Nqy71|u!^ob@9iU<>(irG9hf&OMpL&XaEYOQ!I@^D8%nC?Kc7NWJoiS~1B{W0hK1)Q@pg zSjix!nMKtz=IEQ4&IBv9R!YsPVq#fmLdF)Cd-T?EBPJVN^Dkehn=p(Uk-_KNE(+mn zQgIJ*BtpTqH~+JiEEdbVt*s3U(em!?PRnk@-a@e1cx_$6*$uq8`PyRH+Hl(3!rr|> z*DXr}E@{2E+$NJB%e8^F!A87rJR6r<3;@-4J8YyKN6z8on|N-N$a601Rjmwi-hGuHpTK`I^V96(AAi2?;7IAJ`qyXa>DgJN;#=Wo{#16(-F~8u$PXj5%wK26lDiD|o>jdrt1Wu*1|xd03XGY+^=0n7X0+g~qWQaX zUeR_^&pPyv7ejFD`4qiL&eT~O1{@gFmxb+a6h+Sici5$!b_24XGn6`SzqSh z02nknGnmE-riF^=huAbGn;uHRGmS>g*v0vuprA1OOz!!A1YyC92oashW-|U2L`sU{ PZ~=(t3Ao+S>E(X|QTi=u literal 0 HcmV?d00001 diff --git a/include/images/resourcegroups.pngc b/include/images/resourcegroups.pngc new file mode 100644 index 0000000..19f0bc2 --- /dev/null +++ b/include/images/resourcegroups.pngc @@ -0,0 +1,191 @@ +#ifndef RESOURCEGROUPS_PNG_H +#define RESOURCEGROUPS_PNG_H + +static const unsigned char resourcegroups_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, +0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, +0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, +0x4d, 0x00, 0x00, 0x7a, 0x25, 0x00, 0x00, 0x80, +0x83, 0x00, 0x00, 0xf9, 0xff, 0x00, 0x00, 0x80, +0xe9, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, +0x60, 0x00, 0x00, 0x3a, 0x98, 0x00, 0x00, 0x17, +0x6f, 0x92, 0x5f, 0xc5, 0x46, 0x00, 0x00, 0x02, +0x4c, 0x50, 0x4c, 0x54, 0x45, 0x3f, 0x95, 0xdc, +0xff, 0xff, 0xff, 0x43, 0x95, 0xc2, 0x52, 0x98, +0x7d, 0x79, 0x9d, 0x0d, 0x49, 0x96, 0xa6, 0x17, +0x59, 0x6a, 0x14, 0x59, 0x75, 0x3a, 0x58, 0x09, +0x31, 0x58, 0x1d, 0x0e, 0x55, 0x82, 0x30, 0x55, +0x1d, 0x9b, 0xa6, 0x6a, 0xb6, 0xbf, 0x94, 0x44, +0x9a, 0xfc, 0x57, 0xa5, 0xef, 0x57, 0xa4, 0xf6, +0x52, 0xa3, 0xff, 0x3b, 0x94, 0xff, 0x2b, 0x88, +0xe9, 0x37, 0x92, 0xfc, 0x56, 0xa4, 0xff, 0x56, +0xa4, 0xff, 0x43, 0x95, 0xc4, 0x51, 0xa2, 0xff, +0x31, 0x88, 0xd6, 0x35, 0x91, 0xf9, 0x4b, 0x96, +0x9a, 0x3e, 0x96, 0xff, 0x4e, 0x98, 0x8d, 0x51, +0xa2, 0xff, 0x4b, 0x96, 0x9d, 0x56, 0xa4, 0xfc, +0x79, 0x9d, 0x0d, 0x77, 0x9d, 0x11, 0x57, 0xa5, +0xed, 0x35, 0x8d, 0xc6, 0x34, 0x91, 0xff, 0x45, +0x9a, 0xef, 0x3d, 0x94, 0xea, 0x26, 0x7e, 0xc0, +0x4e, 0x9f, 0xfc, 0x56, 0xa4, 0xf9, 0x45, 0x9a, +0xf6, 0x41, 0x98, 0xe1, 0x37, 0x91, 0xed, 0x25, +0x7f, 0xd3, 0x2a, 0x87, 0xe5, 0x54, 0xa2, 0xca, +0x45, 0x98, 0xca, 0x45, 0x9d, 0xfc, 0x3e, 0x94, +0xd1, 0x3a, 0x4e, 0x00, 0x3b, 0x92, 0xb7, 0x35, +0x8e, 0xc7, 0x31, 0x8b, 0xd4, 0x2c, 0x87, 0xd7, +0x23, 0x7e, 0xde, 0x44, 0x99, 0xea, 0x3a, 0x93, +0xed, 0x3f, 0x94, 0xc4, 0x29, 0x80, 0xba, 0x32, +0x8b, 0xe7, 0x2b, 0x89, 0xf1, 0xb0, 0xd4, 0xfc, +0xbf, 0xde, 0xf9, 0x8e, 0xc3, 0xff, 0x3a, 0x93, +0xed, 0xaf, 0x66, 0x04, 0xdf, 0x80, 0x03, 0xc3, +0x70, 0x09, 0x26, 0x83, 0xe5, 0xbf, 0xde, 0xff, +0x3d, 0x95, 0xff, 0x2b, 0x8b, 0xfc, 0x1a, 0x71, +0xc7, 0x8d, 0x58, 0x02, 0xaf, 0x6b, 0x03, 0xa2, +0x64, 0x05, 0x21, 0x78, 0xce, 0x65, 0xae, 0xff, +0x27, 0x85, 0xef, 0x40, 0x98, 0xff, 0x53, 0xa3, +0xf9, 0x4e, 0x9f, 0xe1, 0x45, 0x9a, 0xe5, 0x34, +0x8f, 0xe1, 0x30, 0x8a, 0xd6, 0x31, 0x89, 0xde, +0x29, 0x88, 0xf6, 0x18, 0x6f, 0xca, 0x51, 0xa2, +0xfc, 0xb0, 0xd4, 0xf6, 0xc0, 0xdf, 0xea, 0x8e, +0xc3, 0xf9, 0x3b, 0x94, 0xdf, 0xb2, 0x5e, 0x16, +0xd7, 0x7d, 0x02, 0xbe, 0x71, 0x07, 0x26, 0x83, +0xea, 0x67, 0xaf, 0xfc, 0x2f, 0x8d, 0xf1, 0x57, +0xa5, 0xff, 0xbf, 0xde, 0xfc, 0xd4, 0xea, 0xf3, +0x86, 0xbf, 0xfc, 0x2c, 0x8a, 0xea, 0xb5, 0x6a, +0x06, 0xff, 0x8e, 0x1c, 0xda, 0x7d, 0x0c, 0x1f, +0x78, 0xd7, 0x99, 0xc8, 0xff, 0x3a, 0x94, 0xf9, +0x56, 0xa4, 0xff, 0x7e, 0xba, 0xf6, 0x77, 0xb7, +0xe5, 0x1c, 0x74, 0xd0, 0x18, 0x6e, 0xc3, 0x7f, +0x52, 0x05, 0x80, 0x53, 0x07, 0x86, 0x54, 0x04, +0x20, 0x74, 0xbc, 0x96, 0xc7, 0xfc, 0x38, 0x92, +0xfc, 0x41, 0x99, 0xfc, 0x32, 0x8f, 0xf6, 0x29, +0x83, 0xd6, 0x16, 0x6d, 0xc6, 0x30, 0x8e, 0xfc, +0x3d, 0x94, 0xef, 0x43, 0x99, 0xe7, 0x3e, 0x94, +0xe5, 0x2e, 0x8a, 0xdc, 0x2f, 0x8a, 0xd7, 0x8a, +0xc2, 0xf3, 0x6b, 0xb1, 0xe9, 0x29, 0x88, 0xf3, +0xb0, 0xd4, 0xff, 0xbf, 0xde, 0xf6, 0x8e, 0xc4, +0xf6, 0x39, 0x93, 0xf3, 0xae, 0x63, 0x11, 0xd0, +0x78, 0x18, 0xb9, 0x6a, 0x2e, 0x27, 0x83, 0xe1, +0x7f, 0xba, 0xf1, 0x2b, 0x8b, 0xff, 0x4d, 0xa1, +0xf6, 0xbe, 0xdc, 0xff, 0xd4, 0xe9, 0xf9, 0x85, +0xbe, 0xf3, 0x2b, 0x8a, 0xf6, 0xb4, 0x6b, 0x02, +0xff, 0x87, 0x31, 0xd4, 0x79, 0x1c, 0x20, 0x78, +0xd3, 0xb1, 0xd6, 0xf6, 0x84, 0xbc, 0xef, 0x2b, +0x8a, 0xf3, 0x47, 0x9d, 0xfc, 0x7a, 0xb9, 0xff, +0x7e, 0xba, 0xf3, 0x62, 0xab, 0xf3, 0x28, 0x85, +0xe9, 0xa9, 0x5e, 0x0b, 0xaf, 0x62, 0x0d, 0xa9, +0x5b, 0x13, 0x1f, 0x75, 0xc6, 0x37, 0x92, 0xfc, +0x25, 0x82, 0xe9, 0x2f, 0x8e, 0xff, 0x3e, 0x92, +0xde, 0x2e, 0x84, 0xcb, 0x2e, 0x85, 0xc4, 0x3e, +0x98, 0xfc, 0x86, 0xbf, 0xff, 0x71, 0xb4, 0xfc, +0x3e, 0x96, 0xfc, 0x75, 0xb6, 0xfc, 0x9a, 0xca, +0xf6, 0x98, 0xc8, 0xea, 0x42, 0x9b, 0xfc, 0xd4, +0xe9, 0xff, 0x86, 0xbf, 0xf9, 0x2b, 0x89, 0xed, +0x8e, 0xc3, 0xe3, 0xd4, 0xe9, 0xf3, 0xc0, 0xe1, +0xe3, 0xaf, 0xd6, 0xf9, 0xc2, 0xde, 0xfc, 0x83, +0xbe, 0xef, 0x26, 0x82, 0xdf, 0x8d, 0xc3, 0xd7, +0xc2, 0xde, 0xf3, 0xb6, 0xda, 0xdc, 0xff, 0xff, +0xff, 0x2f, 0x3e, 0xf7, 0x2e, 0x00, 0x00, 0x00, +0x3e, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0xe2, 0xf0, 0xf0, 0xf0, 0xfd, +0xfe, 0xfe, 0xf4, 0xf0, 0x0d, 0xf0, 0xfd, 0xfb, +0x0c, 0xf0, 0x12, 0xf3, 0x05, 0xf0, 0x03, 0x01, +0xf4, 0xf8, 0xf9, 0xe2, 0xf0, 0xfd, 0xfe, 0xf4, +0xe2, 0xf0, 0xf0, 0xf7, 0xf8, 0xf0, 0xf0, 0xfe, +0xf4, 0x0a, 0xf7, 0xfe, 0xfc, 0xfd, 0xfa, 0xf6, +0xf1, 0xf0, 0xe2, 0xb5, 0x10, 0x5e, 0xb0, 0x00, +0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, 0x01, +0xff, 0x02, 0x2d, 0xde, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x2e, 0x23, +0x00, 0x00, 0x2e, 0x23, 0x01, 0x78, 0xa5, 0x3f, +0x76, 0x00, 0x00, 0x00, 0xfa, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x63, 0xe0, 0xe3, 0x17, 0x10, +0x14, 0xb2, 0xb3, 0x17, 0x16, 0x61, 0x60, 0x04, +0x03, 0x06, 0x51, 0x07, 0x47, 0x27, 0x67, 0x17, +0x57, 0x37, 0x77, 0x26, 0xa8, 0x80, 0x98, 0x87, +0xa7, 0x97, 0xb7, 0x8f, 0xaf, 0x9f, 0xbf, 0x38, +0x33, 0x44, 0x40, 0x22, 0x20, 0x30, 0x28, 0x38, +0x24, 0x34, 0x2c, 0x3c, 0x42, 0x52, 0x4a, 0x9a, +0x05, 0x28, 0x20, 0x13, 0x19, 0x15, 0x1d, 0x13, +0x1b, 0x17, 0x9f, 0x90, 0x98, 0x94, 0x2c, 0x0b, +0x12, 0x90, 0x4b, 0x49, 0x4d, 0x4b, 0xcf, 0xc8, +0xcc, 0xca, 0xce, 0xc9, 0xcd, 0x93, 0x07, 0x09, +0x28, 0xe4, 0x17, 0x14, 0x16, 0x15, 0x97, 0x94, +0x96, 0x95, 0x57, 0x54, 0x32, 0x2a, 0x2a, 0xb1, +0x32, 0x28, 0x57, 0x55, 0xd7, 0xd4, 0xd6, 0xd5, +0x37, 0x34, 0x36, 0x36, 0x35, 0xab, 0xb4, 0xb4, +0xaa, 0x32, 0xa8, 0xa9, 0x6b, 0x68, 0xb6, 0xb5, +0x77, 0x04, 0x77, 0x76, 0x75, 0xf7, 0xf4, 0xf6, +0xf5, 0x4f, 0x60, 0x60, 0x64, 0x63, 0x17, 0x73, +0x9c, 0x38, 0x69, 0xf2, 0x94, 0xa9, 0xd3, 0xa6, +0xcf, 0x98, 0x39, 0x6b, 0x36, 0x03, 0x23, 0x07, +0xa7, 0xd6, 0x9c, 0xb9, 0xf3, 0xe6, 0x2f, 0x58, +0xb8, 0x68, 0xf1, 0x92, 0xa5, 0xcb, 0x96, 0x83, +0x1c, 0xac, 0xad, 0xa3, 0xab, 0xb7, 0x62, 0xd2, +0xca, 0xc0, 0x55, 0xab, 0xd7, 0xac, 0xd5, 0x87, +0xf8, 0x80, 0x8b, 0x71, 0xdd, 0xfa, 0xfc, 0x0d, +0x1b, 0x37, 0x6d, 0xde, 0x62, 0x00, 0x11, 0xe0, +0x66, 0xdc, 0x9a, 0xbe, 0x6d, 0xfb, 0x8e, 0x9d, +0xbb, 0x76, 0x1b, 0x42, 0x04, 0x78, 0x18, 0x8d, +0xf6, 0xec, 0xdd, 0xb7, 0xff, 0xc0, 0xc1, 0x43, +0xc6, 0x10, 0x01, 0x5e, 0x13, 0x53, 0x33, 0x73, +0x0b, 0x4b, 0x2b, 0x6b, 0x1b, 0x5b, 0x00, 0xb7, +0x22, 0x4d, 0x03, 0xad, 0x66, 0xb4, 0x78, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x34, 0x2d, +0x30, 0x37, 0x2d, 0x30, 0x35, 0x54, 0x31, 0x33, +0x3a, 0x30, 0x34, 0x3a, 0x31, 0x35, 0x2b, 0x30, +0x34, 0x3a, 0x30, 0x30, 0x2e, 0x61, 0x0f, 0x3e, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x34, +0x2d, 0x30, 0x36, 0x2d, 0x32, 0x39, 0x54, 0x31, +0x34, 0x3a, 0x34, 0x32, 0x3a, 0x31, 0x35, 0x2b, +0x30, 0x34, 0x3a, 0x30, 0x30, 0x3b, 0x74, 0x71, +0x48, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *resourcegroups_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_resourcegroups_png = new wxImage(); + if (!img_resourcegroups_png || !img_resourcegroups_png->IsOk()) + { + wxMemoryInputStream img_resourcegroups_pngIS(resourcegroups_png_data, sizeof(resourcegroups_png_data)); + img_resourcegroups_png->LoadFile(img_resourcegroups_pngIS, wxBITMAP_TYPE_PNG); + } + return img_resourcegroups_png; +} +#define resourcegroups_png_img resourcegroups_png_img() + +static wxBitmap *resourcegroups_png_bmp() +{ + static wxBitmap *bmp_resourcegroups_png; + if (!bmp_resourcegroups_png || !bmp_resourcegroups_png->IsOk()) + bmp_resourcegroups_png = new wxBitmap(*resourcegroups_png_img); + return bmp_resourcegroups_png; +} +#define resourcegroups_png_bmp resourcegroups_png_bmp() + +static wxIcon *resourcegroups_png_ico() +{ + static wxIcon *ico_resourcegroups_png; + if (!ico_resourcegroups_png || !ico_resourcegroups_png->IsOk()) + { + ico_resourcegroups_png = new wxIcon(); + ico_resourcegroups_png->CopyFromBitmap(*resourcegroups_png_bmp); + } + return ico_resourcegroups_png; +} +#define resourcegroups_png_ico resourcegroups_png_ico() + +#endif // RESOURCEGROUPS_PNG_H diff --git a/include/images/restore.png b/include/images/restore.png new file mode 100644 index 0000000000000000000000000000000000000000..81e7ac4dd1f523f9151a466d5338b545300bc0f0 GIT binary patch literal 822 zcmV-61Ihe}P)dc!L4N7(3$`J?*IMcth{7$krSx6T=DL_?CG-Q<*Vf3px@t{$GmE=m^{N9f3x9)qbsu8TCUtk zm$*LC?)at1QnKJlvDQ*9XSh9j$$+rq^Xb~+<-)ezShU+yp1(z5n0Zs1)l`?)Rh8L* zuH*9R+5h?O#mt4Y)m>JR+<>g*%e;d0>e&AD(@1xCdzu|Ta*lzj=CGML+s2gb-L>=P zzJ8szG;6Bt_xzx~?P7X{nd}Q600001bW%=J06^y0W&i*H32;bRa{vGUNB{r;NB~C3 zYd!z~0PRUcK~xyiV_;-rW?^Lm0#+7gCPoGZ26hfkE^Z!PK7Ii~Az^l)fQYD=xP+vX zw2Z8ryn+Z&Kv79dSyDw(RgFhoLz5LKprx%NsjH_iX`o?fWUK`eFp*R-)iX1fw6L_Y zh6vb5O4`~<+B<-OBT&G}S<=PT&B5Kn)62oz0VLq#>*pU3=n)hY><|JG2n`F5ko1TQ z_Jj&JD@R4g*!jjfIK;(+1QL7_Lz9wIQq$7XGcrK}Sw7i05xD_@Km~dEK!Jin=j@{5 zl2UgMFNeG`2L|?Xk&4Qy>KcdINKc2dItK=*_v;;?4g&zW5H_w75X2h*001R)MObuX zVRU6WV{&C-bY%cCFflMKF)}SMF;p@zIy5snG&L(QH99abp6)KH0000bbVXQnWMOn= zI&E)cX=ZrIsOk()) + { + wxMemoryInputStream img_restore_pngIS(restore_png_data, sizeof(restore_png_data)); + img_restore_png->LoadFile(img_restore_pngIS, wxBITMAP_TYPE_PNG); + } + return img_restore_png; +} +#define restore_png_img restore_png_img() + +static wxBitmap *restore_png_bmp() +{ + static wxBitmap *bmp_restore_png; + if (!bmp_restore_png || !bmp_restore_png->IsOk()) + bmp_restore_png = new wxBitmap(*restore_png_img); + return bmp_restore_png; +} +#define restore_png_bmp restore_png_bmp() + +static wxIcon *restore_png_ico() +{ + static wxIcon *ico_restore_png; + if (!ico_restore_png || !ico_restore_png->IsOk()) + { + ico_restore_png = new wxIcon(); + ico_restore_png->CopyFromBitmap(*restore_png_bmp); + } + return ico_restore_png; +} +#define restore_png_ico restore_png_ico() + +#endif // RESTORE_PNG_H diff --git a/include/images/roles.png b/include/images/roles.png new file mode 100644 index 0000000000000000000000000000000000000000..68d3605dd8d214ff801b4d0d272a2ae04125c949 GIT binary patch literal 620 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf^8lX^S0LTe(h?IBvw#2o1q&9m zHPxLyxZ~54+ouoip48i2RbKMt*{vV19{hOq==-ZDpPxON)Y~(8^5nf+)_i~U?E9-1 zrw$%0C@8ph`PBDUuRcC`wr$(C*;6OYm^3LgG<5dt*(u3Mmrox1|NsA=fB$~``Sjj42~*F$ z{yKfp(#x+tTzK)}%(IVI;u6ls#2TS(Bac7I z1+3lm_+wE~(eCrt4m|w0<>7}NJ9ezU|98ylo`wuCZDe_PkV z`u~6R9gP>Yvv;2Krmnbph7)a`x*~@!RxoW!l6rP!Q{b6r-KrX|PQ^rjV>?lH zyn;XH|A8MIPfF5i7|$-`J1yE#om|5{H>tjsp>o&!-&Zyk9%BA)`QzI?ZGlVgFPpDB zDYGC>*zz0D>8d5J5hW>!C8<`)MX5lF!N|bSK-bVn*T68u$iT|P*viCI+rZSyz+m1x sy;Ue0a`RI%(<&hv3@pJKfT~Tb49p-JPE8M81JuCa>FVdQ&MBb@0QN&I9RL6T literal 0 HcmV?d00001 diff --git a/include/images/roles.pngc b/include/images/roles.pngc new file mode 100644 index 0000000..78cf4ee --- /dev/null +++ b/include/images/roles.pngc @@ -0,0 +1,122 @@ +#ifndef ROLES_PNG_H +#define ROLES_PNG_H + +static const unsigned char roles_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xe7, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x84, 0x84, 0x84, 0x5c, +0x5c, 0x5c, 0xbf, 0xbf, 0xbf, 0xa0, 0xa0, 0xa0, +0x86, 0x82, 0x7e, 0xcb, 0xc1, 0xb8, 0xf2, 0xe4, +0xdb, 0xcb, 0xc1, 0xbb, 0x92, 0x8d, 0x8b, 0x7a, +0x77, 0x74, 0xf4, 0xe6, 0xda, 0xf8, 0xea, 0xe0, +0xf8, 0xea, 0xe2, 0xf7, 0xea, 0xe4, 0xf3, 0xe6, +0xe2, 0x92, 0x8d, 0x8c, 0x93, 0x93, 0x93, 0xbd, +0xb4, 0xac, 0xf7, 0xea, 0xe6, 0xf7, 0xea, 0xe8, +0xca, 0xc1, 0xc1, 0x70, 0x70, 0x70, 0xde, 0xd3, +0xca, 0xf7, 0xea, 0xea, 0xf1, 0xe4, 0xe6, 0xb6, +0xb6, 0xb6, 0x9b, 0x95, 0x92, 0x98, 0x92, 0x92, +0x55, 0x55, 0x55, 0x9b, 0x9b, 0x9b, 0x64, 0x63, +0x62, 0xd3, 0xc9, 0xc6, 0xff, 0xff, 0xff, 0xfc, +0xfe, 0xfe, 0xf8, 0xfc, 0xfe, 0xf3, 0xfa, 0xfd, +0xed, 0xf8, 0xfc, 0xe7, 0xf5, 0xfa, 0xe1, 0xf3, +0xf9, 0xda, 0xf0, 0xf8, 0x56, 0x56, 0x56, 0x64, +0x63, 0x63, 0x9b, 0x95, 0x95, 0xdb, 0x93, 0x96, +0xc8, 0x00, 0x00, 0xd3, 0xed, 0xf6, 0x5c, 0x5d, +0x5e, 0x9a, 0xa5, 0xa8, 0xc7, 0xdc, 0xe1, 0x9b, +0xa9, 0xad, 0xd3, 0x90, 0x95, 0xcd, 0xeb, 0xf5, +0x97, 0xa2, 0xa5, 0xd3, 0xea, 0xf0, 0xd0, 0xe8, +0xf0, 0xcc, 0xe6, 0xf1, 0xd4, 0x5e, 0x60, 0xcf, +0x5c, 0x5f, 0xc6, 0xe8, 0xf4, 0xde, 0xde, 0xde, +0x6e, 0x72, 0x73, 0xc8, 0xe5, 0xf1, 0xd4, 0x99, +0x9f, 0xc0, 0xe5, 0xf3, 0xa8, 0xa8, 0xa8, 0x96, +0xa2, 0xa5, 0xc4, 0xe3, 0xf1, 0x1e, 0x50, 0xad, +0xba, 0xe3, 0xf1, 0x72, 0x72, 0x72, 0xbb, 0xcf, +0xd6, 0xc0, 0xe1, 0xf1, 0xb4, 0xe1, 0xf0, 0xb8, +0xb8, 0xb8, 0xaf, 0xdf, 0xef, 0xab, 0xdd, 0xef, +0x1a, 0x9c, 0x0d, 0x68, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, +0x44, 0x21, 0xc4, 0x6c, 0x0d, 0x16, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0xaf, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x45, 0x8e, 0xd7, +0x16, 0x82, 0x40, 0x0c, 0x05, 0x17, 0xc5, 0xae, +0xd8, 0xb0, 0x1b, 0x2c, 0xb4, 0x55, 0x01, 0x1b, +0xf6, 0xae, 0x88, 0x05, 0xff, 0xff, 0x7b, 0xdc, +0x28, 0xe8, 0x7d, 0x9b, 0xb9, 0xc9, 0x49, 0x08, +0xc1, 0x70, 0x21, 0x2e, 0x4c, 0xfe, 0xe1, 0x23, +0xd1, 0x58, 0x3c, 0xc1, 0xff, 0x45, 0x32, 0x95, +0xce, 0x08, 0xd9, 0xdc, 0x8f, 0xf3, 0x05, 0xc6, +0x45, 0xb1, 0xc4, 0x05, 0xa2, 0x5c, 0x41, 0xae, +0xd6, 0x42, 0x81, 0xa8, 0x37, 0x84, 0x62, 0x13, +0xfc, 0x48, 0x68, 0x5a, 0x6d, 0x11, 0x3a, 0x5d, +0x59, 0x51, 0x35, 0x9d, 0x02, 0x8a, 0x5e, 0x7f, +0x00, 0xc8, 0x86, 0x49, 0x2d, 0x14, 0xc3, 0xd1, +0x78, 0x02, 0xb2, 0x62, 0x1a, 0xe6, 0xd4, 0xb2, +0x51, 0xcc, 0xe6, 0x8b, 0x25, 0x28, 0xea, 0xca, +0x5c, 0x5b, 0xf6, 0x06, 0xc8, 0x76, 0xc7, 0x78, +0x0f, 0x6c, 0xff, 0xc0, 0xf8, 0x08, 0xe4, 0x74, +0x66, 0x7c, 0x01, 0xcd, 0xa1, 0x0e, 0xcb, 0x15, +0x88, 0x7b, 0x63, 0x7c, 0x07, 0x9d, 0x62, 0x7f, +0x7d, 0x00, 0x79, 0xba, 0x9f, 0xfb, 0xd4, 0xb1, +0x71, 0xc2, 0x03, 0xff, 0x39, 0xf8, 0xf6, 0xde, +0x2b, 0x10, 0xd2, 0xef, 0xd3, 0x37, 0xae, 0xc9, +0x1c, 0xa0, 0x5e, 0x13, 0x39, 0xf6, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *roles_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_roles_png = new wxImage(); + if (!img_roles_png || !img_roles_png->IsOk()) + { + wxMemoryInputStream img_roles_pngIS(roles_png_data, sizeof(roles_png_data)); + img_roles_png->LoadFile(img_roles_pngIS, wxBITMAP_TYPE_PNG); + } + return img_roles_png; +} +#define roles_png_img roles_png_img() + +static wxBitmap *roles_png_bmp() +{ + static wxBitmap *bmp_roles_png; + if (!bmp_roles_png || !bmp_roles_png->IsOk()) + bmp_roles_png = new wxBitmap(*roles_png_img); + return bmp_roles_png; +} +#define roles_png_bmp roles_png_bmp() + +static wxIcon *roles_png_ico() +{ + static wxIcon *ico_roles_png; + if (!ico_roles_png || !ico_roles_png->IsOk()) + { + ico_roles_png = new wxIcon(); + ico_roles_png->CopyFromBitmap(*roles_png_bmp); + } + return ico_roles_png; +} +#define roles_png_ico roles_png_ico() + +#endif // ROLES_PNG_H diff --git a/include/images/rule.png b/include/images/rule.png new file mode 100644 index 0000000000000000000000000000000000000000..8b4978090e33bbe3d5f7ed249fd93c2da34f52d6 GIT binary patch literal 373 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}cz{ocE0DgsQug(ks{c>t{C_(0 z|C1^IANT%y)b{UT{r{)4{y&-e|8f7nNA3R}HvW51{r~Cg|4*j>e>~yeqt1U1oBlnh z`S+mw|I-=&pG^AyxclFumVXax|2?Sq_n>kK%jYzp(TpWQe!&b5&u)M?oCO|{#X#Bv zjNMLV+W{G&o-U3d5|`KZnTs_T@Hi`bDEDUl`g^`}GN)YjKDBz@O#-F|X1Becro3=L zVnUz`J9~da#}rq6_MWOkIpP6gt8f32>#JDS-4zfcy)J)|(ya4dQ}_S3nP9`r$iw)~ zA83JUiEBhjN@7W>RdP`(kYX@0Ff`CLG}1LN3^6jWGBLI?G1WFOwK6c6_fBsWiiX_$ ml+3hBhz0{oum+%N6DtEVh=xIsOk()) + { + wxMemoryInputStream img_rule_pngIS(rule_png_data, sizeof(rule_png_data)); + img_rule_png->LoadFile(img_rule_pngIS, wxBITMAP_TYPE_PNG); + } + return img_rule_png; +} +#define rule_png_img rule_png_img() + +static wxBitmap *rule_png_bmp() +{ + static wxBitmap *bmp_rule_png; + if (!bmp_rule_png || !bmp_rule_png->IsOk()) + bmp_rule_png = new wxBitmap(*rule_png_img); + return bmp_rule_png; +} +#define rule_png_bmp rule_png_bmp() + +static wxIcon *rule_png_ico() +{ + static wxIcon *ico_rule_png; + if (!ico_rule_png || !ico_rule_png->IsOk()) + { + ico_rule_png = new wxIcon(); + ico_rule_png->CopyFromBitmap(*rule_png_bmp); + } + return ico_rule_png; +} +#define rule_png_ico rule_png_ico() + +#endif // RULE_PNG_H diff --git a/include/images/rulebad.png b/include/images/rulebad.png new file mode 100644 index 0000000000000000000000000000000000000000..94df61c2696d7c8df2c2253831893ccb34b9cd29 GIT binary patch literal 630 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl482JKxLR^8|yDMeytdxCrvi9xu zxzA75-dn46Z;R*Q8RoCgRQ-QC=lk86m-kG)o|JTyf#E`UoZJvr6^sz8SYtQ$GX)MSS16xvkPMzHs#PHK6w3;P*a0?_6Eq*xA3fuxQSy z+3oE5At>m*xA$8Y*VpFeuM7=eYHNQ841DM1_14*CrnA>eE$tVos?QY^-a0uSaq~)V zo;1_N`?jc?PRtckTKuW#W6(U^4i|3 zqK6nnoPQVa#@)GlcVR{0_rKx`b&VK*p0*Wi``O;%p%$*u8Ir}D$+}*7??H~qHNxgDz(Hwd(!_Hq6HkjTaoHHMP9kvaRcYT$XYD;( zZpoHZ*A{%Kl;bg!@?U1WQL$@&^2V6Ny*KMP%YHNWSbP0l+XkKdS?*s literal 0 HcmV?d00001 diff --git a/include/images/rulebad.pngc b/include/images/rulebad.pngc new file mode 100644 index 0000000..9defcb4 --- /dev/null +++ b/include/images/rulebad.pngc @@ -0,0 +1,123 @@ +#ifndef RULEBAD_PNG_H +#define RULEBAD_PNG_H + +static const unsigned char rulebad_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x0e, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xdd, 0xa9, 0x1d, 0xdc, +0xa9, 0x1d, 0xe6, 0xc9, 0x7d, 0xed, 0xd7, 0x9d, +0xe7, 0xc9, 0x7d, 0xde, 0xad, 0x2a, 0xde, 0xb4, +0x49, 0xc3, 0x98, 0x37, 0xeb, 0xcc, 0x7a, 0xff, +0xe5, 0x9c, 0xf7, 0xdd, 0x99, 0xd3, 0xbc, 0x95, +0xd7, 0x62, 0x62, 0xc5, 0x00, 0x00, 0xd0, 0x57, +0x59, 0xcf, 0xaa, 0x6c, 0xfa, 0xdd, 0x8d, 0xb9, +0x97, 0x8f, 0xc5, 0x47, 0x4b, 0xdd, 0x69, 0x69, +0xb4, 0x9b, 0x87, 0xca, 0x51, 0x54, 0xf6, 0x77, +0x77, 0xc5, 0x46, 0x49, 0xbd, 0x9c, 0x9a, 0xbe, +0x3d, 0x42, 0xf1, 0x57, 0x57, 0xff, 0xe5, 0x9b, +0xff, 0xe5, 0x99, 0xbe, 0xa5, 0x89, 0xf6, 0x76, +0x76, 0xf6, 0x72, 0x72, 0xf5, 0x6e, 0x6e, 0xbc, +0x3b, 0x40, 0xf1, 0x56, 0x56, 0xef, 0x4f, 0x4f, +0xee, 0x48, 0x49, 0xff, 0xe5, 0x98, 0xff, 0xe4, +0x95, 0xc9, 0xb0, 0x88, 0xf5, 0x6d, 0x6d, 0xf4, +0x68, 0x68, 0xf3, 0x62, 0x62, 0xf0, 0x55, 0x55, +0xef, 0x4e, 0x4f, 0xee, 0x48, 0x48, 0xff, 0xe4, +0x94, 0xff, 0xe3, 0x90, 0xfe, 0xe2, 0x8c, 0xe7, +0xd3, 0xa9, 0xf3, 0x61, 0x61, 0xf1, 0x5b, 0x5b, +0xf0, 0x54, 0x54, 0xef, 0x4d, 0x4e, 0xee, 0x47, +0x47, 0xdc, 0xaa, 0x25, 0xcd, 0xbe, 0x98, 0xda, +0x65, 0x65, 0xf0, 0x53, 0x54, 0xef, 0x4d, 0x4d, +0xee, 0x46, 0x46, 0xaa, 0x2c, 0x33, 0xd0, 0xc5, +0xcb, 0xd6, 0x62, 0x62, 0xf0, 0x53, 0x53, 0xef, +0x4c, 0x4c, 0xee, 0x45, 0x45, 0xec, 0x3e, 0x3f, +0xeb, 0x38, 0x38, 0x83, 0x6c, 0x7c, 0xbb, 0x43, +0x45, 0xf0, 0x52, 0x52, 0xef, 0x4b, 0x4b, 0xed, +0x44, 0x45, 0xeb, 0x37, 0x37, 0xea, 0x31, 0x31, +0xe9, 0x2b, 0x2b, 0xf0, 0x51, 0x51, 0xee, 0x4a, +0x4a, 0xed, 0x43, 0x44, 0x99, 0x43, 0x4a, 0xe9, +0x2a, 0x2b, 0xe8, 0x25, 0x25, 0xe7, 0x20, 0x20, +0xed, 0x42, 0x43, 0xc4, 0x46, 0x4a, 0x67, 0x83, +0x92, 0x99, 0x44, 0x4b, 0xe7, 0x1f, 0x20, 0x96, +0xef, 0xc2, 0x38, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x9f, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0xad, +0x8d, 0xd5, 0x15, 0xc2, 0x00, 0x14, 0x43, 0xfb, +0x70, 0x0d, 0x5e, 0xdc, 0xdd, 0xdd, 0xa1, 0x78, +0x71, 0xf7, 0xfd, 0x17, 0xa1, 0x2d, 0x32, 0x01, +0xf9, 0xcb, 0x3d, 0x11, 0x86, 0xf9, 0x87, 0x88, +0x48, 0x26, 0x57, 0x28, 0x89, 0x54, 0x6a, 0x0d, +0x69, 0x05, 0xaf, 0x23, 0xbd, 0xc1, 0x08, 0x93, +0xd9, 0x62, 0xb5, 0xc1, 0x4e, 0x12, 0x70, 0xb0, +0x70, 0xc2, 0xe5, 0xf6, 0xc0, 0x0b, 0xbb, 0x00, +0x7c, 0xfe, 0x00, 0x82, 0xa1, 0x30, 0x22, 0x88, +0xc6, 0xe2, 0x10, 0x40, 0x22, 0x99, 0x62, 0x91, +0xce, 0x64, 0x91, 0xcb, 0x17, 0xa4, 0x44, 0xb1, +0x54, 0xae, 0x18, 0x51, 0xad, 0xd5, 0x1b, 0x4d, +0x69, 0x43, 0x2b, 0xbc, 0xb4, 0xda, 0x1d, 0x74, +0x7b, 0x7d, 0x70, 0xf4, 0x79, 0x1e, 0x0c, 0x31, +0x1a, 0x4f, 0xa6, 0x33, 0xb1, 0x21, 0x8a, 0x9f, +0x63, 0xb1, 0x5c, 0x61, 0xbd, 0xd9, 0x7e, 0x09, +0x76, 0xfb, 0x03, 0x8e, 0x38, 0x9d, 0x2f, 0x78, +0x03, 0x16, 0x57, 0xdc, 0xee, 0x0f, 0x3c, 0x7f, +0x1d, 0x0e, 0x1c, 0xcf, 0x30, 0x9c, 0xe8, 0x5f, +0x5c, 0xfd, 0x13, 0x88, 0xd9, 0x2c, 0xd6, 0x76, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x31, +0x2d, 0x30, 0x33, 0x2d, 0x30, 0x38, 0x54, 0x31, +0x32, 0x3a, 0x31, 0x37, 0x3a, 0x30, 0x39, 0x2b, +0x30, 0x36, 0x3a, 0x30, 0x30, 0xd3, 0xe6, 0xa8, +0x62, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x31, 0x2d, 0x30, 0x33, 0x2d, 0x30, 0x38, 0x54, +0x31, 0x32, 0x3a, 0x31, 0x37, 0x3a, 0x30, 0x39, +0x2b, 0x30, 0x36, 0x3a, 0x30, 0x30, 0xa2, 0xbb, +0x10, 0xde, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *rulebad_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_rulebad_png = new wxImage(); + if (!img_rulebad_png || !img_rulebad_png->IsOk()) + { + wxMemoryInputStream img_rulebad_pngIS(rulebad_png_data, sizeof(rulebad_png_data)); + img_rulebad_png->LoadFile(img_rulebad_pngIS, wxBITMAP_TYPE_PNG); + } + return img_rulebad_png; +} +#define rulebad_png_img rulebad_png_img() + +static wxBitmap *rulebad_png_bmp() +{ + static wxBitmap *bmp_rulebad_png; + if (!bmp_rulebad_png || !bmp_rulebad_png->IsOk()) + bmp_rulebad_png = new wxBitmap(*rulebad_png_img); + return bmp_rulebad_png; +} +#define rulebad_png_bmp rulebad_png_bmp() + +static wxIcon *rulebad_png_ico() +{ + static wxIcon *ico_rulebad_png; + if (!ico_rulebad_png || !ico_rulebad_png->IsOk()) + { + ico_rulebad_png = new wxIcon(); + ico_rulebad_png->CopyFromBitmap(*rulebad_png_bmp); + } + return ico_rulebad_png; +} +#define rulebad_png_ico rulebad_png_ico() + +#endif // RULEBAD_PNG_H diff --git a/include/images/rules.png b/include/images/rules.png new file mode 100644 index 0000000000000000000000000000000000000000..cfe6ed27d98351a03e98451fe83e785aeb51351f GIT binary patch literal 357 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!Q-Dv1E0BJDrt0oW+5b=H{C_&@ z|C4F|pG^AyxbOed8ULTo{{Ljk|Hl*lKkj*b(Es0~_J5B$|2=B`_pssL!=`@^>;65g z`S+m8Y=`zEpec+cL4Lsu4$p3+0Xdun9+AaB+5?Q;PG;Ky8Bv}tjv*44r}laCH7M}7 zJY3k(rBU~;KGd5<=#Js+WtXq}O?@?enTE6ko10E>S;3Z`GiP+(9r|ThaVJc2?wlhg ziC9V-ADTyViR>?)F zK#IZ0z|cU~&`8(7FvQ5f%EZ{p#8lhB)XKnM-aEZjC>nC}Q!>*kAsP%U!5V<7O{@&e WAR10h4_yP)z~JfX=d#Wzp$P!7cZ;e3 literal 0 HcmV?d00001 diff --git a/include/images/rules.pngc b/include/images/rules.pngc new file mode 100644 index 0000000..56fc6bf --- /dev/null +++ b/include/images/rules.pngc @@ -0,0 +1,89 @@ +#ifndef RULES_PNG_H +#define RULES_PNG_H + +static const unsigned char rules_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x42, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xeb, 0xcc, 0x7a, 0xdd, +0xa9, 0x1d, 0xff, 0xe5, 0x9c, 0xff, 0xe5, 0x9a, +0xff, 0xe4, 0x96, 0xff, 0xe4, 0x92, 0xff, 0xe3, +0x8e, 0xff, 0xe5, 0x98, 0xff, 0xe5, 0x9b, 0xff, +0xe4, 0x94, 0xff, 0xe3, 0x90, 0xff, 0xe3, 0x8c, +0xeb, 0xc1, 0x4f, 0xfe, 0xe2, 0x87, 0xfe, 0xe2, +0x89, 0xfe, 0xe2, 0x85, 0xfe, 0xe1, 0x80, 0xfe, +0xe1, 0x82, 0xfe, 0xe1, 0x7e, 0xfe, 0xe1, 0x7c, +0xfe, 0xe0, 0x7a, 0x36, 0xb8, 0x2b, 0xe2, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x5a, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x95, 0x8e, 0x4b, 0x0e, 0x80, +0x20, 0x0c, 0x44, 0xe1, 0xa1, 0x88, 0x8a, 0x28, +0x7e, 0xee, 0x7f, 0x55, 0x4b, 0x04, 0x12, 0xdc, +0x31, 0x9b, 0xa6, 0xd3, 0xd7, 0x4e, 0x95, 0xea, +0x97, 0xa6, 0x28, 0x1b, 0x18, 0x06, 0x46, 0x2c, +0x53, 0x76, 0x70, 0xb4, 0x8c, 0xcc, 0xcc, 0x2c, +0xee, 0xc2, 0xfa, 0x31, 0x78, 0xdc, 0x56, 0x19, +0x9d, 0x9c, 0xc4, 0x34, 0x77, 0x12, 0x93, 0x36, +0xa4, 0x06, 0x72, 0xb0, 0x95, 0xfd, 0x3d, 0x1c, +0xc4, 0x92, 0xe4, 0xa5, 0x3b, 0xe3, 0x75, 0x3f, +0xf5, 0x99, 0xdf, 0x73, 0x7d, 0x7a, 0x01, 0x1b, +0x48, 0x02, 0x60, 0xa7, 0x73, 0x42, 0xc8, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *rules_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_rules_png = new wxImage(); + if (!img_rules_png || !img_rules_png->IsOk()) + { + wxMemoryInputStream img_rules_pngIS(rules_png_data, sizeof(rules_png_data)); + img_rules_png->LoadFile(img_rules_pngIS, wxBITMAP_TYPE_PNG); + } + return img_rules_png; +} +#define rules_png_img rules_png_img() + +static wxBitmap *rules_png_bmp() +{ + static wxBitmap *bmp_rules_png; + if (!bmp_rules_png || !bmp_rules_png->IsOk()) + bmp_rules_png = new wxBitmap(*rules_png_img); + return bmp_rules_png; +} +#define rules_png_bmp rules_png_bmp() + +static wxIcon *rules_png_ico() +{ + static wxIcon *ico_rules_png; + if (!ico_rules_png || !ico_rules_png->IsOk()) + { + ico_rules_png = new wxIcon(); + ico_rules_png->CopyFromBitmap(*rules_png_bmp); + } + return ico_rules_png; +} +#define rules_png_ico rules_png_ico() + +#endif // RULES_PNG_H diff --git a/include/images/schedule.png b/include/images/schedule.png new file mode 100644 index 0000000000000000000000000000000000000000..4203174cafa2490ed9c3f65860a790e154abf334 GIT binary patch literal 683 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl481(~uLR^8|M@?nV=TCXuS@(Qe z_qWRz-XGidaB}OT-iAl*)sJclAC=`iF3R|@cICrKEl+1pc)Nes#|QU6eEae8*6k-7 z);_K(d7K>mVcDXucW-{UeBsOQzwdwkkqcP+^vkdNpMKumckp3e=Hu|dZ^w>&`Sthx zk3X-z{l53<=Z*K@FTMSCWA6MX{+{ppd*9!`|L(`1m*0Lr{_^Y0tFLE|oqOWp@**MT z?bjbKfP$ZY-u?KabKT9;uf86A{^h{KcTb$`o;uh*zj^D?=bv{z{;zc#JDUcKVl*`A3{&5YkS)<3E$xwZGe z`PV?HFNdFh-uvWJ)rxCJmaV_%?ful);QQ{~5Argv&6$7d$k}}l-X7X_@=W){r-phT zySsJvgzW*t2W=|K#5Q)pl2?w|&X3mI| zhtS&rk5udH-kZbf5U2%1VnDB_CkgleDq$BWI^);7QGZ_D=0A$(uXa zT$UfWyKYHt&TBD=!wxbG3{$^Lw!CqXk_0+mwZt`|BqgyV)hf9t6-Y4{85kPq8XD;u z7={=bSeY1GnV4!Dm|7Va%zLM|3PnS1eoAIqB}9XPC0GMcwTYF18AQXW>7i?Y8W=oX L{an^LB{Ts5L&stP literal 0 HcmV?d00001 diff --git a/include/images/schedule.pngc b/include/images/schedule.pngc new file mode 100644 index 0000000..f9e5c8f --- /dev/null +++ b/include/images/schedule.pngc @@ -0,0 +1,130 @@ +#ifndef SCHEDULE_PNG_H +#define SCHEDULE_PNG_H + +static const unsigned char schedule_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x2f, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xe2, 0x82, 0x76, 0xe7, +0x9f, 0x94, 0xe3, 0x89, 0x7e, 0xe7, 0x96, 0x8b, +0xf6, 0xd3, 0xd0, 0xef, 0xc6, 0xbe, 0xe1, 0x93, +0x85, 0xe2, 0x8d, 0x80, 0xe2, 0x87, 0x7b, 0xe2, +0x7c, 0x71, 0xe2, 0x76, 0x6c, 0xe3, 0x72, 0x68, +0xf0, 0xad, 0xa9, 0xe1, 0x92, 0x84, 0xe5, 0x9b, +0x90, 0xed, 0xbf, 0xba, 0xf1, 0xe0, 0xdf, 0xf0, +0xf6, 0xf8, 0xe9, 0xda, 0xdb, 0xe4, 0xb0, 0xad, +0xe3, 0x7a, 0x74, 0xe3, 0x63, 0x5b, 0xf0, 0xa6, +0xa2, 0xf5, 0xdd, 0xd9, 0xf0, 0xd3, 0xd0, 0xf4, +0xfb, 0xfd, 0xef, 0xf9, 0xfc, 0x1e, 0x50, 0xad, +0xe5, 0xf4, 0xfa, 0xdf, 0xf2, 0xf9, 0xdd, 0xbe, +0xc1, 0xe1, 0x6e, 0x69, 0xe3, 0x57, 0x51, 0xf6, +0xc6, 0xc4, 0xf4, 0xfa, 0xfd, 0xef, 0xf8, 0xfc, +0xea, 0xf6, 0xfb, 0xde, 0xf2, 0xf9, 0xd8, 0xef, +0xf7, 0xd2, 0xed, 0xf6, 0xd8, 0x9d, 0x9f, 0xe4, +0x4f, 0x49, 0xee, 0x8f, 0x8d, 0xef, 0xdf, 0xdf, +0xee, 0xf8, 0xfc, 0xe9, 0xf6, 0xfb, 0xe3, 0xf4, +0xfa, 0xcc, 0xea, 0xf5, 0xcd, 0xc6, 0xce, 0xe4, +0x48, 0x44, 0xe8, 0x60, 0x5c, 0xed, 0xf5, 0xf8, +0xe8, 0xf6, 0xfb, 0xe3, 0xf3, 0xf9, 0xdd, 0xf1, +0xf8, 0x89, 0xae, 0xd9, 0xcb, 0xea, 0xf5, 0xc5, +0xe7, 0xf4, 0xc0, 0xe1, 0xee, 0xe4, 0x42, 0x3e, +0xe5, 0x40, 0x3d, 0xe7, 0xd9, 0xda, 0xe2, 0xf3, +0xf9, 0xdc, 0xf1, 0xf8, 0xd6, 0xee, 0xf7, 0x82, +0xab, 0xd8, 0xbf, 0xe5, 0xf2, 0xc3, 0xbf, 0xc9, +0xe4, 0x3c, 0x39, 0xe9, 0x56, 0x53, 0xed, 0xaf, +0xa8, 0xe2, 0xaf, 0xad, 0xdb, 0xf0, 0xf8, 0xd5, +0xee, 0xf7, 0xcf, 0xec, 0xf6, 0xc9, 0xe9, 0xf5, +0x82, 0xab, 0xd7, 0x7b, 0xa8, 0xd6, 0xcd, 0x8c, +0x91, 0xe5, 0x36, 0x33, 0xef, 0x81, 0x7f, 0xe2, +0x7a, 0x74, 0xda, 0xbd, 0xc0, 0xcf, 0xeb, 0xf6, +0xc9, 0xe9, 0xf4, 0xc3, 0xe7, 0xf3, 0xbd, 0xe4, +0xf2, 0x7a, 0xa8, 0xd6, 0xc4, 0xa6, 0xaf, 0xde, +0x4b, 0x4b, 0xe5, 0x33, 0x30, 0xf7, 0xbb, 0xbb, +0xe0, 0x6e, 0x69, 0xd6, 0x9c, 0x9f, 0xca, 0xc4, +0xcd, 0xbe, 0xe0, 0xed, 0xc2, 0xbe, 0xc9, 0xcc, +0x8b, 0x91, 0xe5, 0x31, 0x2e, 0xf1, 0x8b, 0x8b, +0x2c, 0xbc, 0x56, 0xbe, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0xb3, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x63, 0x60, 0xc0, 0x0a, 0x18, 0x99, 0x98, 0x59, +0x18, 0x59, 0xe1, 0x5c, 0x36, 0x76, 0x0e, 0x4e, +0x46, 0x2e, 0x6e, 0x1e, 0x5e, 0x98, 0x00, 0x1f, +0xbf, 0x80, 0xa0, 0x90, 0xb0, 0x88, 0xa8, 0x98, +0x38, 0x98, 0x2b, 0xc1, 0xce, 0x2f, 0x29, 0x25, +0x2d, 0x23, 0x2b, 0x27, 0xaf, 0xa0, 0xa8, 0x04, +0xd6, 0xcf, 0x21, 0xa0, 0xac, 0xa2, 0x2a, 0xa3, +0xa6, 0xae, 0xa1, 0xa9, 0xa5, 0x0d, 0x12, 0x60, +0xe2, 0xd4, 0xd1, 0xd5, 0xd3, 0x97, 0x51, 0xd7, +0x30, 0x30, 0x34, 0x32, 0x06, 0x09, 0x30, 0x33, +0x9a, 0x98, 0x9a, 0x99, 0xcb, 0x58, 0x58, 0x5a, +0x59, 0xdb, 0xd8, 0x82, 0x04, 0x58, 0xb8, 0xec, +0xec, 0x1d, 0x1c, 0x2d, 0x64, 0x9c, 0x9c, 0x5d, +0x5c, 0xdd, 0x40, 0x02, 0xee, 0xdc, 0x1e, 0x9e, +0x5e, 0xde, 0x3e, 0xbe, 0x32, 0x7e, 0xfe, 0x01, +0x81, 0x60, 0x6b, 0x78, 0x82, 0x82, 0x43, 0x42, +0xc3, 0xc2, 0x23, 0x22, 0xa3, 0xa2, 0x63, 0xc0, +0x02, 0xbc, 0x62, 0xb1, 0x71, 0xf1, 0x09, 0x89, +0x49, 0x51, 0xc9, 0x29, 0x50, 0x87, 0x89, 0x2b, +0x6a, 0x19, 0xd9, 0xb8, 0x06, 0x44, 0xa7, 0xc0, +0xdd, 0xae, 0xa4, 0x6d, 0x6c, 0xeb, 0x16, 0x18, +0xc3, 0x40, 0x1c, 0x00, 0x00, 0x95, 0xf7, 0x19, +0x84, 0xec, 0x44, 0x1a, 0x19, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *schedule_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_schedule_png = new wxImage(); + if (!img_schedule_png || !img_schedule_png->IsOk()) + { + wxMemoryInputStream img_schedule_pngIS(schedule_png_data, sizeof(schedule_png_data)); + img_schedule_png->LoadFile(img_schedule_pngIS, wxBITMAP_TYPE_PNG); + } + return img_schedule_png; +} +#define schedule_png_img schedule_png_img() + +static wxBitmap *schedule_png_bmp() +{ + static wxBitmap *bmp_schedule_png; + if (!bmp_schedule_png || !bmp_schedule_png->IsOk()) + bmp_schedule_png = new wxBitmap(*schedule_png_img); + return bmp_schedule_png; +} +#define schedule_png_bmp schedule_png_bmp() + +static wxIcon *schedule_png_ico() +{ + static wxIcon *ico_schedule_png; + if (!ico_schedule_png || !ico_schedule_png->IsOk()) + { + ico_schedule_png = new wxIcon(); + ico_schedule_png->CopyFromBitmap(*schedule_png_bmp); + } + return ico_schedule_png; +} +#define schedule_png_ico schedule_png_ico() + +#endif // SCHEDULE_PNG_H diff --git a/include/images/schedules.png b/include/images/schedules.png new file mode 100644 index 0000000000000000000000000000000000000000..43b2ae462e5c831961eba4b2a4931115934094b1 GIT binary patch literal 650 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47+C{+LR^8|AJ3n>JG|%l;u(*- z>z~i)f4_D8&--`2+`9T~>C8ucjgLBN9yOLdsw#L~ocX+|`s?u{ueYpyd-~{${W~7d zp75x%_EAmYlZt{b2lu|acJc9&nNN$e-<~@9eBX}8vnG7Jb^XJa?=LQ0dOUy51 ziwBNB@pXThp7QSV_vc@KJ^1vqbKT98FTWgm@aBoD<5Oq*rx!2X`}Fhr`|llVZ`QB8 zesueRCw5jZVW;4YI1r5BcGpMo?M(=9iztliIcqpJR)2|d}5fC4jfU{&}0o$<_$c2MpwCY zQCq9KSSYXddYOpcJxz-yZR*luW|p2W<MvN7o%Q;axDea-g{$VxoIAT-gISD$;on{H<*u6Z8-V^$Epd$~Nl7e8 zwMs5Z1yT$~28IT@hDN#uh9O1IsOk()) + { + wxMemoryInputStream img_schedules_pngIS(schedules_png_data, sizeof(schedules_png_data)); + img_schedules_png->LoadFile(img_schedules_pngIS, wxBITMAP_TYPE_PNG); + } + return img_schedules_png; +} +#define schedules_png_img schedules_png_img() + +static wxBitmap *schedules_png_bmp() +{ + static wxBitmap *bmp_schedules_png; + if (!bmp_schedules_png || !bmp_schedules_png->IsOk()) + bmp_schedules_png = new wxBitmap(*schedules_png_img); + return bmp_schedules_png; +} +#define schedules_png_bmp schedules_png_bmp() + +static wxIcon *schedules_png_ico() +{ + static wxIcon *ico_schedules_png; + if (!ico_schedules_png || !ico_schedules_png->IsOk()) + { + ico_schedules_png = new wxIcon(); + ico_schedules_png->CopyFromBitmap(*schedules_png_bmp); + } + return ico_schedules_png; +} +#define schedules_png_ico schedules_png_ico() + +#endif // SCHEDULES_PNG_H diff --git a/include/images/sequence-repl.png b/include/images/sequence-repl.png new file mode 100644 index 0000000000000000000000000000000000000000..676299f8d8c8ef804fb4e1c537a7ed8a37ccf10e GIT binary patch literal 587 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf+W?;sS0KH8`JI-`Bd3l%x_|%u z!~1U^-Fx@@@9#f<{`~s$=kM?TfByXY|NH;DS3f?y`t{+}k6RZ$+&cH+;KpZ%Ha(rQ zDRkSt$|(!e+6(rqo^f;ejB{&eU0yx?-rDK+=4=jKbvbLp-SVClR*N>|PulO_zQAx^ z$90dUeHD{V$9FciZOWK^F0prySO1Byx|vGF$L<#%xtDkFZt}XzNfYaO4+VA}3255y zS#bDX-hsQZOV3Ajws#x~Y~JfpyUV#^yIt=7JAo6A#xA=Mz4Sst?W*-_b~Y6+T(x*} z{+u((bI3bSz@#srI#3mRuKB2YQ&XB*-tA!Qt7BG$4nw zz$3C4NPB>>+sSM@AY-bhi(`ny<>UkgMmIG#wv+=Wj`S!UI&tLCsWzQMN6wu)c(PLk z$US=W?BQ0WL#L0QKHaaRq@bao(4eHGqN1b1A}S~-Dm;C{lu6SXS5BBZIXoaFD6H{A zXlUrwE2bt}x0EjUv}#w?FSa(fV`^3bUso+ldnPt5?3$TXz~|81w{K)+=FW*t5ZkqD zXLUtY<>Fu0j$h|L$Hw5w!~2Ed_D?~e16500BT7;dOH!?pi&B9UgOP!ufv%yEu7P2Q zk%5(ov6YFbwt=aYfx*0YdaF=0 literal 0 HcmV?d00001 diff --git a/include/images/sequence-repl.pngc b/include/images/sequence-repl.pngc new file mode 100644 index 0000000..125c436 --- /dev/null +++ b/include/images/sequence-repl.pngc @@ -0,0 +1,118 @@ +#ifndef SEQUENCE_REPL_PNG_H +#define SEQUENCE_REPL_PNG_H + +static const unsigned char sequence_repl_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xed, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xb7, 0xa7, 0xdc, 0x84, +0x69, 0xc4, 0xca, 0xc6, 0xe2, 0xdf, 0xdf, 0xef, +0xe1, 0xdf, 0xed, 0xe2, 0xde, 0xee, 0xfb, 0xfd, +0xfb, 0xfc, 0xfc, 0xfc, 0xfa, 0xfc, 0xfc, 0xfd, +0xfb, 0xff, 0xfc, 0xfc, 0xfe, 0xff, 0xfb, 0xff, +0xee, 0xea, 0xf8, 0xf0, 0xea, 0xfa, 0xf0, 0xea, +0xf8, 0xda, 0xd0, 0xf0, 0xda, 0xce, 0xf0, 0xc1, +0xb1, 0xe6, 0xc2, 0xb2, 0xe5, 0x9c, 0xb2, 0x55, +0xb6, 0xde, 0x79, 0x94, 0xa1, 0x66, 0x87, 0x70, +0xbc, 0xab, 0x98, 0xd9, 0xa7, 0x98, 0xce, 0xad, +0x9a, 0xd3, 0xab, 0x97, 0xde, 0xad, 0x97, 0xde, +0x9c, 0xb3, 0x55, 0xaa, 0xd3, 0x6a, 0xb0, 0xdd, +0x77, 0x8c, 0xa8, 0x3a, 0xa2, 0xb0, 0x6f, 0x92, +0xbf, 0x4f, 0x87, 0xa0, 0x31, 0x9e, 0x88, 0xd7, +0x48, 0x82, 0xbe, 0x78, 0x92, 0xcb, 0x5f, 0x89, +0x81, 0x86, 0xb2, 0x68, 0x9b, 0xce, 0x61, 0x8d, +0xbc, 0x4a, 0x8f, 0xc8, 0x56, 0x7e, 0x99, 0x22, +0x73, 0xc6, 0xdf, 0x71, 0xc4, 0xde, 0x6e, 0xc1, +0xdd, 0x63, 0xae, 0xd3, 0x62, 0x91, 0x7e, 0x8d, +0xc2, 0x51, 0x89, 0xc4, 0x50, 0x82, 0xbf, 0x49, +0x70, 0xc3, 0xde, 0x6e, 0xc0, 0xdd, 0x5d, 0xa5, +0xcf, 0x5a, 0x89, 0x87, 0x88, 0xc2, 0x51, 0x83, +0xbd, 0x48, 0x7d, 0xba, 0x43, 0x78, 0xb7, 0x3e, +0x6d, 0xbf, 0xdc, 0x51, 0x91, 0xc5, 0x5d, 0xa6, +0xd0, 0x5b, 0xa5, 0xd0, 0x60, 0x7d, 0xaa, 0xaf, +0xac, 0xb9, 0x82, 0x73, 0xa1, 0xaa, 0xa3, 0xb3, +0x6f, 0x9c, 0xcc, 0x63, 0x9d, 0xcc, 0x8f, 0xb2, +0xd7, 0x64, 0x9b, 0xcb, 0x5e, 0xac, 0xd4, 0x52, +0x96, 0xc8, 0x61, 0x7a, 0xc1, 0x60, 0x92, 0xc6, +0x58, 0x99, 0xca, 0x87, 0xad, 0xd4, 0xa4, 0xd7, +0x13, 0x27, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x95, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, +0x00, 0x01, 0x46, 0x26, 0x46, 0x06, 0x64, 0xc0, +0xc8, 0xc4, 0x8c, 0x22, 0xc2, 0xc8, 0xc4, 0xc2, +0xca, 0x86, 0x2c, 0xc2, 0xc4, 0xce, 0xce, 0xc1, +0xc9, 0x89, 0x24, 0xc2, 0xc8, 0xc4, 0xc5, 0xc5, +0xcd, 0xc3, 0x85, 0x22, 0xc2, 0xcb, 0xc7, 0xcb, +0xcb, 0x8f, 0x22, 0x22, 0x20, 0x28, 0x20, 0x20, +0x80, 0x22, 0x22, 0x24, 0x24, 0x2c, 0x24, 0x04, +0x15, 0x11, 0x11, 0x15, 0x13, 0x97, 0x90, 0x94, +0x92, 0x96, 0x81, 0xa9, 0x90, 0x95, 0x93, 0x57, +0x50, 0x54, 0x52, 0x56, 0x81, 0xf0, 0x55, 0x55, +0x55, 0xd5, 0xd4, 0x35, 0x34, 0xb5, 0xb4, 0x75, +0xa0, 0xf2, 0xaa, 0xba, 0x7a, 0xfa, 0x06, 0x86, +0x46, 0xc6, 0x26, 0x3a, 0x50, 0xf5, 0xaa, 0xa6, +0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0x3a, +0x50, 0xf3, 0x55, 0x6d, 0xed, 0xec, 0x1d, 0x1c, +0x9d, 0x9c, 0x5d, 0x60, 0x16, 0xba, 0xba, 0xb9, +0x7b, 0x78, 0x7a, 0x79, 0xa3, 0xfa, 0xd6, 0xc7, +0xd7, 0x0f, 0xce, 0x06, 0x00, 0x45, 0x0c, 0x0d, +0xf4, 0x00, 0xdb, 0xf9, 0x11, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *sequence_repl_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_sequence_repl_png = new wxImage(); + if (!img_sequence_repl_png || !img_sequence_repl_png->IsOk()) + { + wxMemoryInputStream img_sequence_repl_pngIS(sequence_repl_png_data, sizeof(sequence_repl_png_data)); + img_sequence_repl_png->LoadFile(img_sequence_repl_pngIS, wxBITMAP_TYPE_PNG); + } + return img_sequence_repl_png; +} +#define sequence_repl_png_img sequence_repl_png_img() + +static wxBitmap *sequence_repl_png_bmp() +{ + static wxBitmap *bmp_sequence_repl_png; + if (!bmp_sequence_repl_png || !bmp_sequence_repl_png->IsOk()) + bmp_sequence_repl_png = new wxBitmap(*sequence_repl_png_img); + return bmp_sequence_repl_png; +} +#define sequence_repl_png_bmp sequence_repl_png_bmp() + +static wxIcon *sequence_repl_png_ico() +{ + static wxIcon *ico_sequence_repl_png; + if (!ico_sequence_repl_png || !ico_sequence_repl_png->IsOk()) + { + ico_sequence_repl_png = new wxIcon(); + ico_sequence_repl_png->CopyFromBitmap(*sequence_repl_png_bmp); + } + return ico_sequence_repl_png; +} +#define sequence_repl_png_ico sequence_repl_png_ico() + +#endif // SEQUENCE_REPL_PNG_H diff --git a/include/images/sequence.png b/include/images/sequence.png new file mode 100644 index 0000000000000000000000000000000000000000..1ce216c07b2ede8fc5e0ed93df65d20a33475f80 GIT binary patch literal 405 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}W`IwKE0Es4{7y^ekyFPW-M|0- z;r+Ld?!Ei{_xGPae}4V>^Y{1vKY#xH|NZ~ns~;a;{rd3g$E^z=Zk_vZaO1N>o1U(o zerMH;yKAT4Sv~#U+UfTebX=bYL~YmSwq9G>e`9I?txb#WZd`b8!-Bi}Ha(t`$KDOJ zjIkuhFPOpM*^M+HhqJ&VvKUBvfU(=jY&#$$+0(@_MB;L4|4Ata10J^7H@sKgir%{S zzw;xfLwC~n{!iy9WaMaKlGwl`;by2iLnU+CL?(^YIFGQ9l_5vF)@{AEM&h!>XORQj zUbj#DkurDlk>|6^8UH@oo8J9;TYa8=-TlJ!Iea@=Tm!f?@`2W=mbgZgq$HN4S|t~y z0x1R~149E{LnB=S!w@3_D-&ZY6H{#iQ!4|5dGGXAp=ij>PsvQHglI6Z1Zx1QHnB1= WgJ?K4J#-CF1B0ilpUXO@geCwH#jsHT literal 0 HcmV?d00001 diff --git a/include/images/sequence.pngc b/include/images/sequence.pngc new file mode 100644 index 0000000..6d03fcd --- /dev/null +++ b/include/images/sequence.pngc @@ -0,0 +1,95 @@ +#ifndef SEQUENCE_PNG_H +#define SEQUENCE_PNG_H + +static const unsigned char sequence_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x69, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xb7, 0xa7, 0xdc, 0x84, +0x69, 0xc4, 0xca, 0xc6, 0xe2, 0xdf, 0xdf, 0xef, +0xe1, 0xdf, 0xed, 0xe2, 0xde, 0xee, 0xfb, 0xfd, +0xfb, 0xfc, 0xfc, 0xfc, 0xfa, 0xfc, 0xfc, 0xfd, +0xfb, 0xff, 0xfc, 0xfc, 0xfe, 0xff, 0xfb, 0xff, +0xee, 0xea, 0xf8, 0xf0, 0xea, 0xfa, 0xf0, 0xea, +0xf8, 0xda, 0xd0, 0xf0, 0xda, 0xce, 0xf0, 0xc1, +0xb1, 0xe6, 0xc2, 0xb2, 0xe5, 0xab, 0x97, 0xdc, +0xaa, 0x98, 0xdd, 0xad, 0x97, 0xdc, 0xab, 0x97, +0xde, 0xad, 0x97, 0xde, 0xa0, 0x88, 0xd7, 0x9e, +0x88, 0xd7, 0x9e, 0x86, 0xd7, 0x9d, 0x85, 0xd6, +0xa5, 0x8f, 0xd8, 0xa5, 0x8f, 0xda, 0xb2, 0xa2, +0xdd, 0xb1, 0xa1, 0xde, 0xb0, 0xa0, 0xdd, 0xbe, +0xb2, 0xe3, 0x9c, 0x6e, 0x07, 0x8b, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x63, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x65, 0x8f, 0xc9, 0x1a, 0x40, 0x30, +0x0c, 0x06, 0x9b, 0xd8, 0x4b, 0xa9, 0xda, 0x5b, +0xb5, 0xbd, 0xff, 0x43, 0xe2, 0x42, 0xc2, 0xdc, +0x66, 0x0e, 0xff, 0x97, 0x08, 0x71, 0x01, 0x08, +0x82, 0x02, 0x18, 0xb0, 0x02, 0x18, 0x46, 0x31, +0x2d, 0x98, 0x24, 0x69, 0x96, 0x91, 0x02, 0x28, +0x65, 0x5e, 0x48, 0x56, 0x54, 0xa9, 0x54, 0xc5, +0x8a, 0xae, 0xb5, 0xd6, 0xac, 0x18, 0xd3, 0x18, +0xf3, 0x14, 0xc0, 0xb6, 0xeb, 0x87, 0x91, 0xf8, +0x64, 0x9d, 0xb3, 0xc4, 0xe7, 0x9b, 0x77, 0x01, +0xfd, 0xe2, 0xbd, 0x67, 0x8b, 0xeb, 0xb6, 0x7f, +0x6e, 0x3f, 0x7e, 0xdf, 0x71, 0x67, 0x9c, 0x0e, +0xb9, 0x04, 0x45, 0x50, 0x0a, 0x28, 0x6f, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *sequence_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_sequence_png = new wxImage(); + if (!img_sequence_png || !img_sequence_png->IsOk()) + { + wxMemoryInputStream img_sequence_pngIS(sequence_png_data, sizeof(sequence_png_data)); + img_sequence_png->LoadFile(img_sequence_pngIS, wxBITMAP_TYPE_PNG); + } + return img_sequence_png; +} +#define sequence_png_img sequence_png_img() + +static wxBitmap *sequence_png_bmp() +{ + static wxBitmap *bmp_sequence_png; + if (!bmp_sequence_png || !bmp_sequence_png->IsOk()) + bmp_sequence_png = new wxBitmap(*sequence_png_img); + return bmp_sequence_png; +} +#define sequence_png_bmp sequence_png_bmp() + +static wxIcon *sequence_png_ico() +{ + static wxIcon *ico_sequence_png; + if (!ico_sequence_png || !ico_sequence_png->IsOk()) + { + ico_sequence_png = new wxIcon(); + ico_sequence_png->CopyFromBitmap(*sequence_png_bmp); + } + return ico_sequence_png; +} +#define sequence_png_ico sequence_png_ico() + +#endif // SEQUENCE_PNG_H diff --git a/include/images/sequences.png b/include/images/sequences.png new file mode 100644 index 0000000000000000000000000000000000000000..905554d8c6bcb27e0392b615a954a79dac53573b GIT binary patch literal 359 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!eSlAhE0Es4{7y^ekzap+;NSn> z|Ns8}|L)a~4fAfUoqlIZ&G~t4*XMOy|M2R^+}3NiE__(pf8)@mrw2DaTRr{W+UfVy zeAN_yMlhBH`2{mLJiCzwvL>2>S4={E+nQaGT#Cy6phDcmaJs-{2puppD@!Ssw zSH_Ef*M|z2g#5lfTiC;urDY3q*{%)pZreCbCc8ZlU%E)ZLZ5ZvyKC!wPUI}TV0pY} z&-ZdhX6{?bYnCp0Tyw8ha8|!@(=Lrac~^d0i-);09Y~X6xCpdLwZt`|BqgyV)hf9t z6-Y4{85kPq8XD;u7={=bSeY1GnV4!Dm|7Va%zLM|3PnS1eoAIqB}9XPC0GMcwTYF1 X8AQXW>7i?Y8W=oX{an^LB{Ts5VbzJn literal 0 HcmV?d00001 diff --git a/include/images/sequences.pngc b/include/images/sequences.pngc new file mode 100644 index 0000000..ac0bde0 --- /dev/null +++ b/include/images/sequences.pngc @@ -0,0 +1,89 @@ +#ifndef SEQUENCES_PNG_H +#define SEQUENCES_PNG_H + +static const unsigned char sequences_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x3f, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xb7, 0xa7, 0xdc, 0x84, +0x69, 0xc4, 0xfa, 0xfc, 0xfc, 0xfc, 0xfc, 0xfe, +0xff, 0xfb, 0xff, 0xfd, 0xfb, 0xff, 0xee, 0xea, +0xf8, 0xb0, 0x9e, 0xd9, 0xad, 0x97, 0xdc, 0x94, +0x7c, 0xcf, 0x9e, 0x86, 0xd7, 0x9e, 0x88, 0xd7, +0xf0, 0xea, 0xf8, 0x9d, 0x85, 0xd6, 0xda, 0xd0, +0xf0, 0xa5, 0x8f, 0xd8, 0xc2, 0xb2, 0xe5, 0xc1, +0xb1, 0xe6, 0xab, 0x97, 0xde, 0xad, 0x97, 0xde, +0x26, 0x4d, 0x26, 0x20, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x5f, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x65, 0xcf, 0x5b, 0x0e, 0x80, 0x20, 0x0c, 0x44, +0xd1, 0xce, 0xf8, 0x40, 0x45, 0x01, 0xd1, 0xfd, +0xaf, 0x55, 0x10, 0x34, 0x54, 0xfb, 0xd7, 0x9b, +0x13, 0x48, 0x45, 0x04, 0x84, 0xb4, 0x03, 0x76, +0xba, 0xb0, 0x1f, 0x46, 0xb6, 0x09, 0x34, 0x93, +0x46, 0xe0, 0x17, 0xa5, 0xa2, 0x10, 0x38, 0x2f, +0x05, 0xa1, 0xee, 0xd6, 0xae, 0x4c, 0xc8, 0x6c, +0xa5, 0xd0, 0x39, 0xc7, 0x8c, 0xbc, 0xf7, 0x77, +0x01, 0x03, 0x0b, 0xda, 0x63, 0xac, 0xa5, 0xa2, +0xe3, 0x7c, 0xde, 0x7d, 0x11, 0x9a, 0x8f, 0x33, +0x82, 0xba, 0x28, 0xfc, 0x6e, 0xd4, 0xfb, 0x3b, +0x17, 0x56, 0x47, 0x02, 0xc0, 0x66, 0x1a, 0x00, +0xd1, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, +0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *sequences_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_sequences_png = new wxImage(); + if (!img_sequences_png || !img_sequences_png->IsOk()) + { + wxMemoryInputStream img_sequences_pngIS(sequences_png_data, sizeof(sequences_png_data)); + img_sequences_png->LoadFile(img_sequences_pngIS, wxBITMAP_TYPE_PNG); + } + return img_sequences_png; +} +#define sequences_png_img sequences_png_img() + +static wxBitmap *sequences_png_bmp() +{ + static wxBitmap *bmp_sequences_png; + if (!bmp_sequences_png || !bmp_sequences_png->IsOk()) + bmp_sequences_png = new wxBitmap(*sequences_png_img); + return bmp_sequences_png; +} +#define sequences_png_bmp sequences_png_bmp() + +static wxIcon *sequences_png_ico() +{ + static wxIcon *ico_sequences_png; + if (!ico_sequences_png || !ico_sequences_png->IsOk()) + { + ico_sequences_png = new wxIcon(); + ico_sequences_png->CopyFromBitmap(*sequences_png_bmp); + } + return ico_sequences_png; +} +#define sequences_png_ico sequences_png_ico() + +#endif // SEQUENCES_PNG_H diff --git a/include/images/server-sm.png b/include/images/server-sm.png new file mode 100644 index 0000000000000000000000000000000000000000..40d864dc646e8400a9cf6bead73b8cfe679613b0 GIT binary patch literal 598 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47+C{+LR^8|=A4>YZBs5CIs5q9 z{TnB)oZWTe@S44gx@NDQwe0Stn~$#DyME&G*i(tcH%*+kXVIF;HC@jhKKc6P%l%8&_AgzxapK&)i`P!B>3;g~$^Iql_bys<|MuN4 zpFZEecy;Ie6`Ll_+c9tD#H!9K7cM<{{AA7KxvP6-Y?!gAue^2PgxL>n-#fkk$hJjm z8+&F=UbMcurhDm>`R7lc{rKVIrDLb(Oke1?c8kyE9o1D`5AWW;cJ=E0i`Q1pTNyiT zN$%?HP1W7axiw8WHB1XPt^fuEV@Z%-FoVOh8)-leXMsm#F_88EW4Dvpc0fjlr;B5V z#O36K18fop89W<0XSPo5oy)9v;N;P>hfg2ZXAl<<5fT#=6`tO}?cwEl`oyV|+6pWp zQ>TQ6T)iU5BsDAQmesB*4#ry5RAyOc6;ZciYRl4|iE%J`Yo}&QM_cb`*xNjH@#M|j z+A#;t-aUNz^zGx~3y+?+S1{19V0pMRV8Q)EhbHW8XJDwlEzp^KV4?-kO{yiX5hW>! zC8<`)MX5lF!N|bSK-bVn*T68u$iT|P*viCI+rZSyz+m1xy;Ue0a`RI%(<&hv3@pJK cfT~Tb49p-JPE8M81JuCa>FVdQ&MBb@0DK4{umAu6 literal 0 HcmV?d00001 diff --git a/include/images/server-sm.pngc b/include/images/server-sm.pngc new file mode 100644 index 0000000..3183e47 --- /dev/null +++ b/include/images/server-sm.pngc @@ -0,0 +1,119 @@ +#ifndef SERVER_SM_PNG_H +#define SERVER_SM_PNG_H + +static const unsigned char server_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x05, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x83, 0x6c, 0x7c, 0x9a, +0x86, 0x94, 0xd2, 0xc4, 0xcd, 0xe3, 0xd6, 0xdf, +0xd8, 0xc8, 0xd4, 0xcd, 0xba, 0xc8, 0xc3, 0xac, +0xbd, 0xa2, 0x8a, 0x9b, 0xab, 0x9a, 0xa6, 0xdd, +0xd2, 0xd9, 0xe2, 0xd6, 0xde, 0xd7, 0xc8, 0xd3, +0xcd, 0xba, 0xc7, 0xc3, 0xad, 0xbc, 0xae, 0x96, +0xa8, 0x96, 0x81, 0x90, 0xae, 0x9d, 0xa8, 0xe6, +0xde, 0xe3, 0xec, 0xe5, 0xea, 0xe5, 0xdb, 0xe1, +0xe1, 0xd7, 0xde, 0xda, 0xcd, 0xd7, 0xcd, 0xbd, +0xc8, 0x94, 0x7f, 0x8d, 0xab, 0x9a, 0xa5, 0xe6, +0xe2, 0xe4, 0xf6, 0xf5, 0xf6, 0xe7, 0xdd, 0xe0, +0xd5, 0xc5, 0xcb, 0xcc, 0xb8, 0xbf, 0xce, 0xbb, +0xc3, 0x96, 0x81, 0x8e, 0xe5, 0xe1, 0xe3, 0xf5, +0xf4, 0xf5, 0xde, 0xd1, 0xd5, 0xbf, 0xa5, 0xaf, +0xb2, 0x91, 0x9e, 0xbc, 0xa2, 0xac, 0x93, 0x7c, +0x8a, 0xe6, 0xe1, 0xe4, 0xf5, 0xf4, 0xf4, 0xdf, +0xd2, 0xd6, 0xbf, 0xa5, 0xae, 0xb1, 0x91, 0x9d, +0xbd, 0xa3, 0xad, 0x93, 0x7c, 0x8b, 0xe5, 0xe1, +0xe4, 0xbf, 0xa4, 0xaf, 0xbd, 0xa2, 0xac, 0xdf, +0xdb, 0xdd, 0xf4, 0xf2, 0xf3, 0xdf, 0xd1, 0xd5, +0xb9, 0x9f, 0xa8, 0xb2, 0x92, 0x9e, 0xb8, 0x9e, +0xa9, 0x91, 0x7a, 0x89, 0xd4, 0xd0, 0xd2, 0xe4, +0xe3, 0xe4, 0xac, 0x93, 0x9d, 0xab, 0x8c, 0x98, +0xb0, 0x98, 0xa2, 0x8e, 0x77, 0x85, 0xa1, 0x90, +0x9b, 0xe0, 0xdb, 0xde, 0xcb, 0xbf, 0xc4, 0xb6, +0xa2, 0xad, 0x81, 0x8c, 0x9a, 0x93, 0xa2, 0xaf, +0x8b, 0x7c, 0x8b, 0xa5, 0x94, 0x9f, 0xcf, 0xcb, +0xcd, 0xf1, 0xf0, 0xf1, 0xd2, 0xc6, 0xcb, 0x9c, +0x97, 0xa1, 0x4e, 0xad, 0xb4, 0x4c, 0xb3, 0xb8, +0x7b, 0x7a, 0x8a, 0xe1, 0xdd, 0xdf, 0xd6, 0xd5, +0xd5, 0xdf, 0xd1, 0xd6, 0xa9, 0x9e, 0xa9, 0x5d, +0x96, 0xa4, 0x6d, 0xab, 0xb7, 0x82, 0x7b, 0x8b, +0x83, 0x6d, 0x7c, 0x82, 0x6c, 0x7c, 0x02, 0xa1, +0xb1, 0xa8, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x88, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, +0xc0, 0x06, 0x18, 0xc1, 0x00, 0x49, 0x80, 0x89, +0x99, 0x85, 0x95, 0x8d, 0x9d, 0x03, 0x21, 0xc0, +0xc9, 0xc5, 0xcd, 0xc3, 0xcb, 0xc7, 0x2f, 0x00, +0x17, 0x10, 0x14, 0x12, 0x16, 0x11, 0x15, 0x13, +0x97, 0x80, 0x0b, 0x48, 0x4a, 0x49, 0xcb, 0xc8, +0xca, 0xc9, 0x2b, 0x20, 0x04, 0x14, 0x95, 0x94, +0x55, 0x54, 0xd5, 0xd4, 0x11, 0x02, 0x1a, 0x9a, +0x5a, 0xda, 0x3a, 0xba, 0x7a, 0x08, 0x01, 0x7d, +0x25, 0x65, 0x03, 0x1d, 0x43, 0x24, 0x15, 0x46, +0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x08, 0x01, +0x4b, 0x2b, 0x65, 0x6b, 0x1b, 0x5b, 0x3b, 0xb8, +0x80, 0xbd, 0x83, 0x95, 0xa3, 0x93, 0xb3, 0x8b, +0x2b, 0x5c, 0xc0, 0xcd, 0xdd, 0xc3, 0xd3, 0xcb, +0xdb, 0xc7, 0x17, 0xa1, 0xc5, 0xcf, 0x3f, 0x20, +0x30, 0x28, 0x38, 0x04, 0xe1, 0xb9, 0x50, 0xa0, +0xdf, 0xc2, 0xc2, 0x90, 0xbd, 0x87, 0x00, 0x00, +0x7b, 0xdb, 0x10, 0x89, 0x63, 0xc0, 0x91, 0x38, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, +0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *server_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_server_sm_png = new wxImage(); + if (!img_server_sm_png || !img_server_sm_png->IsOk()) + { + wxMemoryInputStream img_server_sm_pngIS(server_sm_png_data, sizeof(server_sm_png_data)); + img_server_sm_png->LoadFile(img_server_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_server_sm_png; +} +#define server_sm_png_img server_sm_png_img() + +static wxBitmap *server_sm_png_bmp() +{ + static wxBitmap *bmp_server_sm_png; + if (!bmp_server_sm_png || !bmp_server_sm_png->IsOk()) + bmp_server_sm_png = new wxBitmap(*server_sm_png_img); + return bmp_server_sm_png; +} +#define server_sm_png_bmp server_sm_png_bmp() + +static wxIcon *server_sm_png_ico() +{ + static wxIcon *ico_server_sm_png; + if (!ico_server_sm_png || !ico_server_sm_png->IsOk()) + { + ico_server_sm_png = new wxIcon(); + ico_server_sm_png->CopyFromBitmap(*server_sm_png_bmp); + } + return ico_server_sm_png; +} +#define server_sm_png_ico server_sm_png_ico() + +#endif // SERVER_SM_PNG_H diff --git a/include/images/server.png b/include/images/server.png new file mode 100644 index 0000000000000000000000000000000000000000..2ab73d5654a26b4d5acc3dc50dc659d4bdfee42f GIT binary patch literal 553 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMfr2wB0S0LS-Q!}lx|JD8HkFMUk zdGhLoy{C_DJg|S+&d#EynQfDItl0eW{?i*Lubkg|YX6EIb6cj}zIfx+{b!G^-aWtX z)Q0IRFC0Dn>EoxLKYo7w`03ZrUmxGTe{%c&hj;J4ef{>}^7SLDw{Dm)d&|^?N7in8 z|L)!QuiuWW-m+=Jyu)j^e*60M;guUl*6n!z?)~9an>S6Edt~kQ7r&y=mx z7BB3ZcJ|DfiKPu&rY$_YcH5do%RjvPuxrDX>M2XSXRPR1z2o7Pn+toUL@nAPf9rVA zlFjMOlcJYy+i~mtG@!2-OM?7@862M7NCR>>3p^r=fwTu0yPeFo12XzNT^vIsE+;22 zFu8FgG%%~BiG`V!@%c&2@1EV>I=z2xd;_=E0Syh6GunsFDRNytqM@dzsHv!`+bl3) z>g4c%kRUgX6)R4yUa6g_u=2u{px}^8ZX7RGEXtfX_41{w!I#`QBvwdCy_B4-kZE`| z$iR4e19wE!%Ba;hZ`@MMoVdBXprpv{;-c4&x&j#49rzfc()q>Pd9o)1U8Y*%8c~vx zSdwa$T$Bo=7>o=I4Rj5SbPWtcj0~(yjIB&ewGB+I3=HPI(_4k2AvZrIGp!P$!N3x% c0jS!<%D@bw;neidH9!pvp00i_>zopr0E;gKO#lD@ literal 0 HcmV?d00001 diff --git a/include/images/server.pngc b/include/images/server.pngc new file mode 100644 index 0000000..fc52104 --- /dev/null +++ b/include/images/server.pngc @@ -0,0 +1,114 @@ +#ifndef SERVER_PNG_H +#define SERVER_PNG_H + +static const unsigned char server_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xd2, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x83, 0x6c, 0x7c, 0x96, +0x81, 0x8f, 0xea, 0xdf, 0xe7, 0xe2, 0xd5, 0xde, +0xd9, 0xc9, 0xd5, 0xd0, 0xbd, 0xcb, 0xc6, 0xb1, +0xc0, 0xbf, 0xa6, 0xb9, 0x89, 0x72, 0x82, 0x99, +0x86, 0x93, 0xb8, 0xa8, 0xb3, 0xe9, 0xdf, 0xe5, +0xd8, 0xc9, 0xd4, 0xcf, 0xbd, 0xca, 0xbf, 0xa8, +0xb8, 0x9d, 0x84, 0x96, 0xdb, 0xd1, 0xd8, 0xea, +0xdf, 0xe6, 0xe2, 0xd5, 0xdd, 0xcf, 0xbe, 0xca, +0xb0, 0x97, 0xa9, 0xd0, 0xc5, 0xcb, 0xf2, 0xf1, +0xf2, 0xf9, 0xf8, 0xf9, 0xf5, 0xf1, 0xf2, 0xfa, +0xf9, 0xfa, 0xf1, 0xed, 0xef, 0xe4, 0xdb, 0xdf, +0xf0, 0xee, 0xef, 0xf6, 0xf5, 0xf6, 0xe0, 0xd3, +0xd7, 0xc4, 0xab, 0xb5, 0xb0, 0x90, 0x9b, 0xb4, +0x95, 0xa1, 0xc4, 0xad, 0xb6, 0xef, 0xee, 0xee, +0xf7, 0xf5, 0xf6, 0xc4, 0xab, 0xb4, 0xb2, 0x90, +0x9e, 0xc3, 0xad, 0xb5, 0xf6, 0xf5, 0xf5, 0xe1, +0xd4, 0xd8, 0xc4, 0xae, 0xb8, 0xef, 0xee, 0xef, +0xc3, 0xaa, 0xb3, 0xb2, 0x90, 0x9d, 0xc4, 0xad, +0xb7, 0xc7, 0xc6, 0xc7, 0xe0, 0xd4, 0xd8, 0xa2, +0x8c, 0x94, 0xb5, 0x96, 0xa3, 0xa1, 0x8e, 0x96, +0xcd, 0xcc, 0xcc, 0x91, 0x75, 0x80, 0xb4, 0x96, +0xa1, 0xc3, 0xad, 0xb6, 0xac, 0xa2, 0xa7, 0xf0, +0xee, 0xf0, 0xba, 0xb0, 0xb4, 0x7b, 0x94, 0xa4, +0x4b, 0x98, 0xa8, 0x8c, 0xab, 0xb8, 0xe1, 0xd4, +0xd9, 0xa1, 0x8c, 0x94, 0x5a, 0xa2, 0xb4, 0x1f, +0xda, 0xc7, 0x52, 0xa4, 0xb3, 0x67, 0x83, 0x92, +0x5b, 0xa5, 0xb6, 0xb8, 0xda, 0xef, 0x96, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x8e, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x63, 0x60, 0x00, 0x02, 0x46, +0x08, 0x60, 0x80, 0x03, 0x26, 0x66, 0x16, 0x56, +0x36, 0x76, 0x0e, 0x4e, 0x18, 0x9f, 0x8b, 0x9b, +0x87, 0x85, 0x97, 0x8f, 0x9d, 0x5f, 0x80, 0x0b, +0x2a, 0xc0, 0x28, 0x28, 0x24, 0xcc, 0x2b, 0xc2, +0xce, 0x21, 0x0a, 0xd3, 0xc4, 0x28, 0x26, 0x2e, +0x21, 0x29, 0x21, 0x25, 0x2d, 0x83, 0x10, 0x90, +0x95, 0x93, 0x57, 0x50, 0x54, 0x52, 0x46, 0x08, +0xa8, 0xa8, 0xca, 0xab, 0xa9, 0x2b, 0x69, 0x20, +0xa9, 0xd0, 0xd4, 0x52, 0x53, 0x54, 0xd2, 0x46, +0x08, 0xe8, 0xa8, 0xa2, 0x69, 0x91, 0x95, 0xd3, +0xd2, 0xd5, 0x53, 0xd2, 0x47, 0x08, 0x18, 0xa8, +0x1a, 0x1a, 0xe9, 0x19, 0x9b, 0x20, 0x69, 0x31, +0xd5, 0x52, 0x30, 0x33, 0xb7, 0x80, 0x0b, 0x58, +0x5a, 0xa9, 0x5a, 0xab, 0xd9, 0xd8, 0xda, 0x21, +0x69, 0x91, 0xb3, 0x77, 0x70, 0x74, 0x72, 0x46, +0xd1, 0xa2, 0xeb, 0xe2, 0x8a, 0x50, 0x01, 0x07, +0x40, 0x0e, 0x00, 0x5a, 0x67, 0x0f, 0x17, 0x87, +0x0c, 0x6b, 0x93, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *server_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_server_png = new wxImage(); + if (!img_server_png || !img_server_png->IsOk()) + { + wxMemoryInputStream img_server_pngIS(server_png_data, sizeof(server_png_data)); + img_server_png->LoadFile(img_server_pngIS, wxBITMAP_TYPE_PNG); + } + return img_server_png; +} +#define server_png_img server_png_img() + +static wxBitmap *server_png_bmp() +{ + static wxBitmap *bmp_server_png; + if (!bmp_server_png || !bmp_server_png->IsOk()) + bmp_server_png = new wxBitmap(*server_png_img); + return bmp_server_png; +} +#define server_png_bmp server_png_bmp() + +static wxIcon *server_png_ico() +{ + static wxIcon *ico_server_png; + if (!ico_server_png || !ico_server_png->IsOk()) + { + ico_server_png = new wxIcon(); + ico_server_png->CopyFromBitmap(*server_png_bmp); + } + return ico_server_png; +} +#define server_png_ico server_png_ico() + +#endif // SERVER_PNG_H diff --git a/include/images/serverbad-sm.png b/include/images/serverbad-sm.png new file mode 100644 index 0000000000000000000000000000000000000000..ddb7adb2ec368d9dc503cf2cf1340470875d06b6 GIT binary patch literal 705 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47$XCGLR^8|=A4?@?NcuuIrsS5 z{TnB)oZWTe@S44gx@NDLz3kqlTaT{YyME&G* z+<)@)?&JGc?p!*2c4|Za>RC%~&YXSO)AMFy^SNDz4zJ#FvZHU8f$5Ee#1%=|#}yRc zBqSW=nO}Lz+~TpD+vn8O*8u@{_4VKT`9HO^JgcB^e&OQtwzhYTO+JK%z4!HdWMXna zQu=yK?1kww&*d5?MwFx^mZVxG z7o`Fz1|tJQ16@NST?4}qBLgcFV=EI=Z39y)1A}?*^j4v0$jwj5Osj-wFt7w`0ID{z YGBAT^I5jmdKI;Vst0H^mLKL7v# literal 0 HcmV?d00001 diff --git a/include/images/serverbad-sm.pngc b/include/images/serverbad-sm.pngc new file mode 100644 index 0000000..bb4dc04 --- /dev/null +++ b/include/images/serverbad-sm.pngc @@ -0,0 +1,133 @@ +#ifndef SERVERBAD_SM_PNG_H +#define SERVERBAD_SM_PNG_H + +static const unsigned char serverbad_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x59, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x83, 0x6c, 0x7c, 0x9b, +0x87, 0x95, 0xd2, 0xc4, 0xce, 0xe3, 0xd6, 0xdf, +0xd8, 0xc8, 0xd4, 0xcd, 0xba, 0xc8, 0xc3, 0xac, +0xbd, 0xa2, 0x8a, 0x9b, 0xac, 0x9b, 0xa6, 0xde, +0xd2, 0xda, 0xe2, 0xd6, 0xde, 0xd7, 0xc8, 0xd3, +0xcd, 0xba, 0xc7, 0xc3, 0xad, 0xbc, 0xaf, 0x97, +0xa8, 0x92, 0x7a, 0x8b, 0xad, 0x9d, 0xa8, 0xe6, +0xdf, 0xe4, 0xee, 0xe8, 0xec, 0xe8, 0xdf, 0xe4, +0xe5, 0xdd, 0xe3, 0xdf, 0xd4, 0xdc, 0xd2, 0xc3, +0xcd, 0x95, 0x80, 0x8f, 0xab, 0x9a, 0xa5, 0xd9, +0x99, 0x9b, 0xd3, 0x49, 0x49, 0xd9, 0x81, 0x83, +0xce, 0xba, 0xc2, 0xc3, 0xab, 0xb4, 0xc9, 0x88, +0x8e, 0xba, 0x30, 0x35, 0xd8, 0x60, 0x61, 0xa8, +0x62, 0x6b, 0xc7, 0x20, 0x21, 0xec, 0x60, 0x60, +0xc5, 0x09, 0x0a, 0xc0, 0x5c, 0x62, 0xb6, 0x71, +0x7c, 0xc1, 0x20, 0x22, 0xe3, 0x3d, 0x3d, 0xc9, +0x0d, 0x0d, 0xdd, 0x69, 0x69, 0xa5, 0x38, 0x40, +0xe3, 0x4b, 0x4b, 0xf5, 0x70, 0x70, 0xf2, 0x68, +0x68, 0xc7, 0x14, 0x15, 0xc2, 0x23, 0x26, 0xdf, +0x34, 0x34, 0xef, 0x4f, 0x50, 0xe9, 0x41, 0x41, +0xc7, 0x0b, 0x0b, 0xa9, 0x6f, 0x79, 0xca, 0x37, +0x38, 0xe3, 0x46, 0x46, 0xf3, 0x65, 0x65, 0xeb, +0x50, 0x50, 0xdd, 0x2f, 0x2f, 0xef, 0x4e, 0x4f, +0xe5, 0x39, 0x39, 0xcd, 0x20, 0x20, 0xcf, 0xa1, +0xa3, 0xcf, 0x3d, 0x3d, 0xdd, 0x33, 0x34, 0xf0, +0x55, 0x56, 0xef, 0x4d, 0x4e, 0xe2, 0x34, 0x34, +0xc0, 0x19, 0x1b, 0xd7, 0x5c, 0x5d, 0xd0, 0x97, +0x99, 0xcc, 0x2e, 0x2e, 0xe2, 0x38, 0x38, 0xef, +0x4c, 0x4d, 0xed, 0x44, 0x45, 0xe4, 0x31, 0x31, +0xc4, 0x14, 0x16, 0xd9, 0x5e, 0x5e, 0xa1, 0x60, +0x69, 0xc4, 0x24, 0x25, 0xe5, 0x3e, 0x3e, 0xef, +0x4b, 0x4b, 0xe5, 0x38, 0x38, 0xd7, 0x1c, 0x1c, +0xea, 0x34, 0x34, 0xe5, 0x28, 0x28, 0xca, 0x11, +0x11, 0xdd, 0x68, 0x68, 0xa5, 0x35, 0x3c, 0xe1, +0x37, 0x37, 0xee, 0x4a, 0x4a, 0xe9, 0x3d, 0x3e, +0xba, 0x11, 0x13, 0xa8, 0x2a, 0x2f, 0xd8, 0x18, +0x18, 0xe7, 0x25, 0x25, 0xe5, 0x1f, 0x1f, 0xc5, +0x03, 0x03, 0x9f, 0x61, 0x6b, 0xbd, 0x21, 0x24, +0xdf, 0x2d, 0x2e, 0xbe, 0x0c, 0x0e, 0xa5, 0x58, +0x61, 0x7c, 0x6a, 0x77, 0xac, 0x26, 0x2b, 0xd7, +0x14, 0x15, 0xcc, 0x17, 0x17, 0xdc, 0x69, 0x69, +0x9e, 0x3f, 0x49, 0xc1, 0x05, 0x06, 0xa8, 0x2e, +0x36, 0x99, 0x47, 0x52, 0xbe, 0x0b, 0x0d, 0xdb, +0x60, 0x60, 0xf6, 0x7f, 0xd9, 0x0f, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x9f, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0x60, 0xc0, 0x02, 0x18, 0x21, +0x00, 0x21, 0xc0, 0xc4, 0xcc, 0xc2, 0xca, 0xc6, +0xce, 0x81, 0x10, 0xe0, 0xe4, 0xe2, 0xe6, 0xe1, +0xe5, 0xe3, 0x17, 0x80, 0x0b, 0x08, 0x0a, 0x09, +0x8b, 0x88, 0x8a, 0x89, 0x4b, 0xc0, 0x05, 0x24, +0xa5, 0xa4, 0x65, 0x64, 0xe5, 0xe4, 0x15, 0x14, +0x61, 0x02, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, +0x1a, 0x9a, 0x5a, 0xda, 0x50, 0x01, 0x1d, 0x5d, +0x3d, 0x7d, 0x03, 0x43, 0x23, 0x63, 0x13, 0x53, +0xa8, 0x80, 0x99, 0xb9, 0x85, 0xa5, 0x95, 0xb5, +0x8d, 0xad, 0x1d, 0x4c, 0x85, 0xa4, 0xbd, 0x83, +0xa3, 0x93, 0xb3, 0x8b, 0xab, 0x1b, 0xdc, 0x50, +0x77, 0x0f, 0x4f, 0x2f, 0x6f, 0x1f, 0x5f, 0x3f, +0x98, 0x80, 0x7f, 0x40, 0x60, 0x50, 0x70, 0x48, +0x68, 0x58, 0x78, 0x04, 0x54, 0x20, 0x32, 0x2a, +0x3a, 0x26, 0x36, 0x2e, 0x3e, 0x21, 0x31, 0x09, +0x2a, 0x90, 0x9c, 0x92, 0x9a, 0x96, 0x9e, 0x91, +0x99, 0x95, 0x9d, 0x03, 0xf3, 0x5c, 0x6e, 0x5e, +0x3e, 0x23, 0x63, 0x41, 0x61, 0x11, 0x36, 0x9f, +0x33, 0x00, 0x00, 0x60, 0xd0, 0x1a, 0x02, 0x8f, +0x05, 0x3b, 0xa3, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *serverbad_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_serverbad_sm_png = new wxImage(); + if (!img_serverbad_sm_png || !img_serverbad_sm_png->IsOk()) + { + wxMemoryInputStream img_serverbad_sm_pngIS(serverbad_sm_png_data, sizeof(serverbad_sm_png_data)); + img_serverbad_sm_png->LoadFile(img_serverbad_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_serverbad_sm_png; +} +#define serverbad_sm_png_img serverbad_sm_png_img() + +static wxBitmap *serverbad_sm_png_bmp() +{ + static wxBitmap *bmp_serverbad_sm_png; + if (!bmp_serverbad_sm_png || !bmp_serverbad_sm_png->IsOk()) + bmp_serverbad_sm_png = new wxBitmap(*serverbad_sm_png_img); + return bmp_serverbad_sm_png; +} +#define serverbad_sm_png_bmp serverbad_sm_png_bmp() + +static wxIcon *serverbad_sm_png_ico() +{ + static wxIcon *ico_serverbad_sm_png; + if (!ico_serverbad_sm_png || !ico_serverbad_sm_png->IsOk()) + { + ico_serverbad_sm_png = new wxIcon(); + ico_serverbad_sm_png->CopyFromBitmap(*serverbad_sm_png_bmp); + } + return ico_serverbad_sm_png; +} +#define serverbad_sm_png_ico serverbad_sm_png_ico() + +#endif // SERVERBAD_SM_PNG_H diff --git a/include/images/serverbad.png b/include/images/serverbad.png new file mode 100644 index 0000000000000000000000000000000000000000..20612397a69882da16635c462129b2a7e41f5a55 GIT binary patch literal 643 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47)1hnLR^8|=A4>ojs36gKYw)f z-p!L&FYG;iY~z9b%XW4aHO*|Byko`Ym-nCEIC&H*Oe*XIS_WhIF_pc`<9c5s+5FUAC_0|m&W^b9g@Tj}@ z-OS8Wfg#_@%a6KwZJID|pRLo!@bGVCW#5X5zUJlav3B?v7WUrX|DA{D*WBDM85y6G zl0JlnzV`!)czjMw{1_emAtdCzuira&_v6Qo-%3sW5Det{zH@V1rDJ>zs5m(Iy^qg3 zSJyXo_OC50c00R%2nu@d?furp^|iVAD?`JV+S(ri1K)Xhy>)h(>Fo7VOZ$bY>T?B! zw@%JS+`Q78C(U&6elD-jvV!R~FkBc*g8YIR9G=}s19CVEJR*yMvJeFNL;nAWn`}E?5 zq?J6gR)l1)FrQ_jShnTX+`Rr$i{H#V?#UcEsZB3)_C;(u!u9&B*zUiLYi0b?V+!`( zy?KiH{B>#hSqe-npLQ?$&(s$qc70XRH(-P?sFt`!l%yncptAuDUumo!Wsy4AQFoS3~H9d3Uf LtDnm{r-UW|L$oBQ literal 0 HcmV?d00001 diff --git a/include/images/serverbad.pngc b/include/images/serverbad.pngc new file mode 100644 index 0000000..e799deb --- /dev/null +++ b/include/images/serverbad.pngc @@ -0,0 +1,125 @@ +#ifndef SERVERBAD_PNG_H +#define SERVERBAD_PNG_H + +static const unsigned char serverbad_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x14, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x83, 0x6c, 0x7c, 0x96, +0x81, 0x8f, 0xea, 0xdf, 0xe7, 0xe2, 0xd5, 0xde, +0xd9, 0xc9, 0xd5, 0xd0, 0xbd, 0xcb, 0xc6, 0xb1, +0xc0, 0xbf, 0xa6, 0xb9, 0x89, 0x72, 0x82, 0x99, +0x86, 0x93, 0xb8, 0xa8, 0xb3, 0xe9, 0xdf, 0xe5, +0xd8, 0xc9, 0xd4, 0xcf, 0xbd, 0xca, 0xbf, 0xa8, +0xb8, 0x9d, 0x84, 0x96, 0xdb, 0xd1, 0xd8, 0xea, +0xdf, 0xe6, 0xe2, 0xd5, 0xdd, 0xcf, 0xbe, 0xca, +0xb0, 0x97, 0xa9, 0xd0, 0xc5, 0xcb, 0xf2, 0xf1, +0xf2, 0xf9, 0xf8, 0xf9, 0xf5, 0xf1, 0xf2, 0xfa, +0xf9, 0xfa, 0xf1, 0xed, 0xef, 0xe4, 0xdb, 0xdf, +0xd7, 0x62, 0x62, 0xc5, 0x00, 0x00, 0xd0, 0x57, +0x59, 0xc4, 0xab, 0xb5, 0xb0, 0x90, 0x9b, 0xb4, +0x95, 0xa1, 0xc5, 0x47, 0x4b, 0xdd, 0x69, 0x69, +0xca, 0x51, 0x54, 0xf6, 0x77, 0x77, 0xc5, 0x46, +0x4a, 0xb2, 0x90, 0x9e, 0xbe, 0x3d, 0x42, 0xf1, +0x57, 0x57, 0xf6, 0x76, 0x76, 0xf6, 0x72, 0x72, +0xf5, 0x6e, 0x6e, 0xbc, 0x3b, 0x40, 0xf1, 0x56, +0x56, 0xef, 0x4f, 0x4f, 0xee, 0x48, 0x49, 0xf5, +0x6d, 0x6d, 0xf4, 0x68, 0x68, 0xf3, 0x62, 0x62, +0xf0, 0x55, 0x55, 0xef, 0x4e, 0x4f, 0xee, 0x48, +0x48, 0xf3, 0x61, 0x61, 0xf1, 0x5b, 0x5b, 0xf0, +0x54, 0x54, 0xef, 0x4d, 0x4e, 0xee, 0x47, 0x47, +0xc7, 0xc6, 0xc7, 0xda, 0x65, 0x65, 0xf0, 0x53, +0x54, 0xef, 0x4d, 0x4d, 0xee, 0x46, 0x46, 0xaa, +0x2c, 0x33, 0xd6, 0x62, 0x62, 0xf0, 0x53, 0x53, +0xef, 0x4c, 0x4c, 0xee, 0x45, 0x45, 0xec, 0x3e, +0x3f, 0xeb, 0x38, 0x38, 0xbb, 0x43, 0x45, 0xf0, +0x52, 0x52, 0xef, 0x4b, 0x4b, 0xed, 0x44, 0x45, +0xeb, 0x37, 0x37, 0xea, 0x31, 0x31, 0xe9, 0x2b, +0x2b, 0xf0, 0x51, 0x51, 0xee, 0x4a, 0x4a, 0xed, +0x43, 0x44, 0x99, 0x43, 0x4a, 0xe9, 0x2a, 0x2b, +0xe8, 0x25, 0x25, 0xe7, 0x20, 0x20, 0xed, 0x42, +0x43, 0xc4, 0x46, 0x4a, 0x67, 0x83, 0x92, 0x99, +0x44, 0x4b, 0xe7, 0x1f, 0x20, 0x84, 0xa8, 0x02, +0xeb, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0xa6, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x45, 0x8d, 0x55, +0x0e, 0xc3, 0x40, 0x10, 0x43, 0xb3, 0xa5, 0x94, +0x99, 0xc1, 0x65, 0x66, 0x66, 0x4a, 0x99, 0x99, +0xef, 0x7f, 0x8f, 0xa6, 0x52, 0x76, 0xeb, 0x8f, +0x91, 0xfc, 0xe4, 0xb1, 0x39, 0x4e, 0x14, 0x91, +0xc4, 0x51, 0xc9, 0xe4, 0x0a, 0xa5, 0x8a, 0x57, +0x6b, 0xa8, 0xd7, 0xea, 0xf4, 0x0a, 0x83, 0x91, +0x37, 0x99, 0x29, 0x20, 0x16, 0xab, 0xcd, 0x60, +0xe7, 0xd5, 0x0e, 0xfa, 0x43, 0x9c, 0x2e, 0xb7, +0xc7, 0xed, 0xf5, 0xf9, 0xff, 0x20, 0x80, 0x60, +0x28, 0x1c, 0x89, 0x22, 0x26, 0x81, 0x38, 0x12, +0x48, 0xa6, 0xd2, 0xc8, 0x48, 0x84, 0x20, 0x9b, +0xcb, 0xa3, 0x80, 0x62, 0xa9, 0x0c, 0x9a, 0xa8, +0x54, 0x6b, 0xa8, 0x37, 0x9a, 0x34, 0x21, 0x76, +0xb4, 0xda, 0x9d, 0x6e, 0x8f, 0x75, 0x38, 0xfb, +0x03, 0x0c, 0x47, 0x63, 0x08, 0x6c, 0x65, 0x82, +0xe9, 0x6c, 0xbe, 0x58, 0xb2, 0xc4, 0x0a, 0xeb, +0xcd, 0x16, 0xbb, 0xfd, 0x81, 0xad, 0x1c, 0x4f, +0x67, 0x5c, 0x70, 0xbd, 0xdd, 0xd9, 0xca, 0x03, +0xcf, 0xd7, 0x1b, 0x1f, 0x9a, 0x20, 0x02, 0x04, +0xf2, 0xbb, 0xa2, 0xff, 0x02, 0x8e, 0x5c, 0x16, +0xd7, 0xaa, 0x72, 0xf6, 0xc5, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *serverbad_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_serverbad_png = new wxImage(); + if (!img_serverbad_png || !img_serverbad_png->IsOk()) + { + wxMemoryInputStream img_serverbad_pngIS(serverbad_png_data, sizeof(serverbad_png_data)); + img_serverbad_png->LoadFile(img_serverbad_pngIS, wxBITMAP_TYPE_PNG); + } + return img_serverbad_png; +} +#define serverbad_png_img serverbad_png_img() + +static wxBitmap *serverbad_png_bmp() +{ + static wxBitmap *bmp_serverbad_png; + if (!bmp_serverbad_png || !bmp_serverbad_png->IsOk()) + bmp_serverbad_png = new wxBitmap(*serverbad_png_img); + return bmp_serverbad_png; +} +#define serverbad_png_bmp serverbad_png_bmp() + +static wxIcon *serverbad_png_ico() +{ + static wxIcon *ico_serverbad_png; + if (!ico_serverbad_png || !ico_serverbad_png->IsOk()) + { + ico_serverbad_png = new wxIcon(); + ico_serverbad_png->CopyFromBitmap(*serverbad_png_bmp); + } + return ico_serverbad_png; +} +#define serverbad_png_ico serverbad_png_ico() + +#endif // SERVERBAD_PNG_H diff --git a/include/images/servers.png b/include/images/servers.png new file mode 100644 index 0000000000000000000000000000000000000000..bd49bd271f9be5ddf43a180638783626895c0548 GIT binary patch literal 504 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMfmH?j+S0LS-Q!}lx|JD8HkFMUk zdGhLoy{C_DJg|S+&d#EynQfDItl0eW{?i*Lubkg|YX6EIb6cj}zIfx+{b!G^-aWtX z)Q0IRFC0Dn>EoxLKYo7w`03ZrUmxGTe{%c&hj;J4ef{>}^7SLDw^mPC60>Am&*~lT z-@W_(_1lrvTcQ_imcMm8dE>zuHB-}DXZufI`{m=OhgWVKUbQ)T>9+Up-aoi)v3-1r7=tpgewDrdA0 zom1qxd{{$GPf=4*RkvAS!qmy(0U<$d94l6wTD>wm;}Gi>2Zv~P>6<*UCB|RAi1JQ2 zV-R8*WUQ9Z*4eUhrsXC{v1wr*QAc>z2J)u5e6nXy?d82)6r;Qx=nT~o*NBpo#FA92 zCuWneJxo!%-G4Y~O#nQ4^}4F;BA4M5c< ZRt9De4X37ut^sOb@O1TaS?83{1OPP$<_Q1* literal 0 HcmV?d00001 diff --git a/include/images/servers.pngc b/include/images/servers.pngc new file mode 100644 index 0000000..fd96384 --- /dev/null +++ b/include/images/servers.pngc @@ -0,0 +1,107 @@ +#ifndef SERVERS_PNG_H +#define SERVERS_PNG_H + +static const unsigned char servers_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xb4, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x83, 0x6c, 0x7c, 0x96, +0x81, 0x8f, 0xea, 0xdf, 0xe7, 0xe2, 0xd5, 0xde, +0xd9, 0xc9, 0xd5, 0xd0, 0xbd, 0xcb, 0xc6, 0xb1, +0xc0, 0xbf, 0xa6, 0xb9, 0x89, 0x72, 0x82, 0x99, +0x86, 0x93, 0xb8, 0xa8, 0xb3, 0xe9, 0xdf, 0xe5, +0xd8, 0xc9, 0xd4, 0xcf, 0xbd, 0xca, 0xbf, 0xa8, +0xb8, 0x9d, 0x84, 0x96, 0xdb, 0xd1, 0xd8, 0xea, +0xdf, 0xe6, 0xe2, 0xd5, 0xdd, 0xcf, 0xbe, 0xca, +0xb0, 0x97, 0xa9, 0xd0, 0xc5, 0xcb, 0xf2, 0xf1, +0xf2, 0xf9, 0xf8, 0xf9, 0xf5, 0xf1, 0xf2, 0xfa, +0xf9, 0xfa, 0xf1, 0xed, 0xef, 0xe4, 0xdb, 0xdf, +0xf0, 0xee, 0xef, 0xf6, 0xf5, 0xf6, 0xe0, 0xd3, +0xd7, 0xc4, 0xab, 0xb5, 0x7b, 0x94, 0xa4, 0x5c, +0xa4, 0xb6, 0x8c, 0xab, 0xb8, 0xef, 0xee, 0xee, +0xf7, 0xf5, 0xf6, 0xc4, 0xab, 0xb4, 0x5b, 0xa0, +0xb3, 0x1f, 0xda, 0xc7, 0x63, 0xb1, 0xc1, 0x98, +0x7c, 0x95, 0x67, 0x85, 0x9b, 0x4f, 0x97, 0xad, +0xf4, 0xf1, 0xf2, 0xe1, 0xd4, 0xd8, 0xc3, 0xaa, +0xb3, 0x5b, 0xa5, 0xb6, 0xef, 0xee, 0xef, 0xe0, +0xd4, 0xd8, 0x5b, 0xa2, 0xb4, 0xf5, 0xf1, 0xf3, +0xf9, 0xf9, 0xf9, 0xe6, 0xef, 0xf1, 0xcf, 0xdb, +0xe0, 0xe1, 0xd4, 0xd9, 0xc3, 0xab, 0xb4, 0x5a, +0xa2, 0xb4, 0xf6, 0xf5, 0xf5, 0x29, 0xc3, 0xc9, +0x52, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x7b, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0x00, +0x02, 0x46, 0x28, 0x60, 0x80, 0x01, 0x26, 0x66, +0x16, 0x56, 0x36, 0x76, 0x0e, 0x4e, 0x18, 0x9f, +0x8b, 0x9b, 0x87, 0x85, 0x97, 0x8f, 0x9d, 0x5f, +0x80, 0x0b, 0x2a, 0xc0, 0x28, 0x28, 0x24, 0xcc, +0x2b, 0xc2, 0xce, 0x21, 0x0a, 0xd3, 0xc3, 0x28, +0x26, 0x2e, 0x21, 0x29, 0x21, 0x25, 0x2d, 0x83, +0x10, 0x90, 0x95, 0x93, 0x57, 0x50, 0x54, 0x52, +0x46, 0x08, 0xa8, 0xa8, 0xca, 0xab, 0xa9, 0x6b, +0x68, 0xc2, 0x05, 0xb4, 0x40, 0x40, 0x5b, 0x47, +0x1b, 0xd9, 0x0c, 0x5d, 0x74, 0x33, 0xf4, 0xf4, +0x15, 0x0d, 0x90, 0xcc, 0x30, 0x54, 0x35, 0x52, +0x33, 0x26, 0x60, 0x86, 0x89, 0x84, 0xa9, 0x99, +0x39, 0xb2, 0x19, 0x16, 0x96, 0x56, 0x48, 0x5a, +0xc4, 0x0c, 0xad, 0x51, 0x0d, 0x65, 0x44, 0xf2, +0x3f, 0x00, 0x25, 0x8d, 0x0d, 0xdb, 0x72, 0x5c, +0x23, 0xa7, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, +0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *servers_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_servers_png = new wxImage(); + if (!img_servers_png || !img_servers_png->IsOk()) + { + wxMemoryInputStream img_servers_pngIS(servers_png_data, sizeof(servers_png_data)); + img_servers_png->LoadFile(img_servers_pngIS, wxBITMAP_TYPE_PNG); + } + return img_servers_png; +} +#define servers_png_img servers_png_img() + +static wxBitmap *servers_png_bmp() +{ + static wxBitmap *bmp_servers_png; + if (!bmp_servers_png || !bmp_servers_png->IsOk()) + bmp_servers_png = new wxBitmap(*servers_png_img); + return bmp_servers_png; +} +#define servers_png_bmp servers_png_bmp() + +static wxIcon *servers_png_ico() +{ + static wxIcon *ico_servers_png; + if (!ico_servers_png || !ico_servers_png->IsOk()) + { + ico_servers_png = new wxIcon(); + ico_servers_png->CopyFromBitmap(*servers_png_bmp); + } + return ico_servers_png; +} +#define servers_png_ico servers_png_ico() + +#endif // SERVERS_PNG_H diff --git a/include/images/setBreak.png b/include/images/setBreak.png new file mode 100644 index 0000000000000000000000000000000000000000..9bb52b6e1fb2fbb27665805302d5cfbf9743d04b GIT binary patch literal 299 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPE^3h)VW1=0r&9B620_|L%5(7@2Z zz~EbY&jcvSSQ6wH%;50sMjDXAS>O>_45U54*zIJt9gq>=>Eal|aXmS~fvKrUAnL>o z7eNx~x3z61?3wS1RGG()KHEc27 z#U#mgTe~ HDWM4fUOrMQ literal 0 HcmV?d00001 diff --git a/include/images/setBreak.pngc b/include/images/setBreak.pngc new file mode 100644 index 0000000..7f95839 --- /dev/null +++ b/include/images/setBreak.pngc @@ -0,0 +1,82 @@ +#ifndef SETBREAK_PNG_H +#define SETBREAK_PNG_H + +static const unsigned char setBreak_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x12, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0x80, +0x80, 0x80, 0xff, 0x00, 0x00, 0x80, 0x80, 0x00, +0x80, 0x00, 0x00, 0x4d, 0x75, 0xde, 0x34, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x50, 0x49, 0x44, 0x41, +0x54, 0x08, 0xd7, 0x63, 0x60, 0x40, 0x02, 0x82, +0x82, 0x10, 0x5a, 0xc8, 0xd8, 0x44, 0x11, 0x44, +0x33, 0x1a, 0x1b, 0x9b, 0x86, 0x2a, 0x00, 0x19, +0xc2, 0x20, 0x46, 0x20, 0x90, 0xa1, 0xac, 0x08, +0x64, 0x84, 0x80, 0x64, 0x04, 0x9d, 0x4d, 0x43, +0x43, 0x05, 0x40, 0x0c, 0x63, 0x28, 0xc3, 0xd8, +0x38, 0x14, 0x85, 0xc1, 0xa0, 0x0c, 0x92, 0x09, +0x02, 0x6b, 0x07, 0x0a, 0x80, 0xb4, 0x33, 0xba, +0x02, 0x19, 0x0a, 0x60, 0x2b, 0x42, 0x43, 0x15, +0x51, 0x2d, 0x85, 0x00, 0x00, 0x59, 0x8e, 0x10, +0x28, 0x64, 0xac, 0xd7, 0xec, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *setBreak_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_setBreak_png = new wxImage(); + if (!img_setBreak_png || !img_setBreak_png->IsOk()) + { + wxMemoryInputStream img_setBreak_pngIS(setBreak_png_data, sizeof(setBreak_png_data)); + img_setBreak_png->LoadFile(img_setBreak_pngIS, wxBITMAP_TYPE_PNG); + } + return img_setBreak_png; +} +#define setBreak_png_img setBreak_png_img() + +static wxBitmap *setBreak_png_bmp() +{ + static wxBitmap *bmp_setBreak_png; + if (!bmp_setBreak_png || !bmp_setBreak_png->IsOk()) + bmp_setBreak_png = new wxBitmap(*setBreak_png_img); + return bmp_setBreak_png; +} +#define setBreak_png_bmp setBreak_png_bmp() + +static wxIcon *setBreak_png_ico() +{ + static wxIcon *ico_setBreak_png; + if (!ico_setBreak_png || !ico_setBreak_png->IsOk()) + { + ico_setBreak_png = new wxIcon(); + ico_setBreak_png->CopyFromBitmap(*setBreak_png_bmp); + } + return ico_setBreak_png; +} +#define setBreak_png_ico setBreak_png_ico() + +#endif // SETBREAK_PNG_H diff --git a/include/images/slcluster.png b/include/images/slcluster.png new file mode 100644 index 0000000000000000000000000000000000000000..ee5b1e18cc11db79c7eb54c01f6e464f4afe335f GIT binary patch literal 628 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf{{Wv5S0Mf7*~NQT)*arMb8uby z$sN^~j!wLKV#eJ|tB-8XyK;QunhU~)| zvrq4?xq4#C@9%fsygB&#<<6^TC*HX*@8kOmpFZ9A`}^yuoi*q7xBmG0Yo}7RG?9BJi_rJV9@Z!nRH_tA8fB*RZ&rkop z-~ICTz}I(=|Ns8B@1Okt{rT2~nP1;O{`%(pr`LP#UhTVjs{PQ$oEv8s9p03C z@lfB#XD35FtCj$RfUzXVFPOpM*^M+HhqJ&VvKUBvfU(=jY&#%hji-xah{WaOgoKo& zw6w(3M9FtssuaxifbTUE=WMb|r6e(PiReA7`bD}Zxq&Nk}eDjVu{p;t~Gh9e)?8_6dTyfd5 zsmXakQ9#49T85812Ll0cv3IboFyt=akR{ E0HttBrT_o{ literal 0 HcmV?d00001 diff --git a/include/images/slcluster.pngc b/include/images/slcluster.pngc new file mode 100644 index 0000000..1177263 --- /dev/null +++ b/include/images/slcluster.pngc @@ -0,0 +1,123 @@ +#ifndef SLCLUSTER_PNG_H +#define SLCLUSTER_PNG_H + +static const unsigned char slcluster_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xff, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xec, 0xe6, 0xd1, 0xde, +0xd4, 0xae, 0xc3, 0xb1, 0x6c, 0xc1, 0xae, 0x67, +0xc9, 0xb8, 0x7b, 0xd2, 0xc5, 0x91, 0xd5, 0xc8, +0x98, 0xdd, 0xd2, 0xab, 0xc4, 0xb3, 0x6e, 0xd4, +0xc7, 0x91, 0xec, 0xe4, 0xc0, 0xf2, 0xee, 0xcf, +0xea, 0xe7, 0xbb, 0xe1, 0xdb, 0xa8, 0xd7, 0xce, +0x94, 0xc3, 0xb2, 0x6b, 0xd0, 0xc2, 0x8d, 0xe6, +0xdc, 0xb4, 0xff, 0xfe, 0xf2, 0xfe, 0xfb, 0xe3, +0xfb, 0xfb, 0xdd, 0xf1, 0xef, 0xc7, 0xea, 0xe9, +0xbc, 0xde, 0xd7, 0xa0, 0xca, 0xbc, 0x7b, 0xc1, +0xaf, 0x68, 0xc4, 0xb2, 0x6f, 0xee, 0xe9, 0xca, +0xfd, 0xfb, 0xe3, 0xfb, 0xf8, 0xdb, 0xf1, 0xf1, +0xcd, 0xd6, 0xcb, 0x96, 0xdd, 0xd3, 0xaf, 0xd6, +0xc8, 0x96, 0xc3, 0xb0, 0x6b, 0xc3, 0xb1, 0x6b, +0xcb, 0xbb, 0x7c, 0xd5, 0xc8, 0x94, 0xfb, 0xf7, +0xdc, 0xec, 0xec, 0xc1, 0xeb, 0xe9, 0xb9, 0xd5, +0xcd, 0x91, 0xdc, 0xd0, 0x9e, 0xf1, 0xef, 0xd0, +0xf2, 0xf2, 0xd8, 0xfd, 0xfb, 0xf5, 0xca, 0xb9, +0x7c, 0xce, 0xbf, 0x85, 0xf8, 0xf5, 0xe4, 0xfe, +0xfe, 0xfc, 0xf9, 0xf7, 0xee, 0xf4, 0xf2, 0xde, +0xef, 0xea, 0xcd, 0xfe, 0xf6, 0xde, 0xf4, 0xec, +0xc1, 0xe7, 0xe4, 0x9e, 0xe7, 0xe3, 0xa5, 0xed, +0xea, 0xc1, 0xea, 0xe4, 0xcf, 0xef, 0xe6, 0xcc, +0xf7, 0xf3, 0xdf, 0xf4, 0xef, 0xc0, 0xe8, 0xe4, +0xa5, 0xec, 0xe6, 0xd2, 0xf7, 0xef, 0xe3, 0xff, +0xf9, 0xf2, 0xfe, 0xf7, 0xdd, 0xf4, 0xed, 0xc0, +0xf5, 0xee, 0xe3, 0xff, 0xfb, 0xf2, 0xee, 0xea, +0xc0, 0xf6, 0xef, 0xe4, 0xff, 0xfb, 0xf3, 0xda, +0xd0, 0x99, 0xf5, 0xef, 0xe3, 0xf5, 0xec, 0xcf, +0xf2, 0xeb, 0xbc, 0xdd, 0xd5, 0x8e, 0xd5, 0xca, +0x87, 0xc2, 0xb1, 0x6c, 0xd8, 0xcd, 0xa2, 0xc3, +0xb2, 0x6d, 0xd1, 0xc2, 0x8e, 0xf1, 0xe6, 0xc9, +0x55, 0x49, 0x7a, 0xa4, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0xac, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x63, 0x60, 0x60, 0x64, 0x62, 0x66, 0x66, 0x61, +0x65, 0x63, 0x67, 0x80, 0x02, 0x0e, 0x4e, 0x2e, +0x6e, 0x1e, 0x5e, 0x3e, 0x7e, 0x01, 0x0e, 0xa8, +0x80, 0xa0, 0x90, 0xb0, 0x88, 0xa8, 0x98, 0xb8, +0x84, 0xa4, 0x14, 0x54, 0x9d, 0xb4, 0x8c, 0xb0, +0xac, 0x9c, 0xbc, 0x02, 0x42, 0x1d, 0x8b, 0xa2, +0x92, 0xb2, 0x0a, 0x8b, 0xb2, 0xaa, 0x9a, 0xba, +0xa8, 0x98, 0x86, 0xa6, 0x96, 0x20, 0x03, 0x0b, +0x4c, 0x4e, 0x5b, 0x4e, 0x5e, 0x47, 0x57, 0x4f, +0x9f, 0x81, 0x05, 0x6c, 0x06, 0x50, 0xce, 0xc0, +0xd0, 0xc8, 0xd8, 0xc4, 0x94, 0x85, 0x81, 0x05, +0x6c, 0x06, 0x48, 0xce, 0xcc, 0xdc, 0xc2, 0xd2, +0x0a, 0x28, 0x60, 0x6d, 0x63, 0x0b, 0x91, 0x33, +0xb3, 0xb3, 0xb0, 0x07, 0x09, 0x38, 0x38, 0x3a, +0x41, 0xe4, 0x9c, 0x5d, 0x20, 0x2a, 0x1c, 0x5c, +0xdd, 0x20, 0x72, 0x20, 0xd2, 0x1d, 0x24, 0xe0, +0xe1, 0x09, 0x91, 0x33, 0x03, 0x92, 0x5e, 0x20, +0x01, 0x6f, 0x37, 0x88, 0x9c, 0x8f, 0xaf, 0x9f, +0x7f, 0x00, 0xd0, 0x61, 0x81, 0x8e, 0x6e, 0x10, +0x39, 0xa8, 0xd3, 0x39, 0x82, 0x82, 0x43, 0xa0, +0x72, 0x50, 0x80, 0xe6, 0x7d, 0x00, 0xf1, 0xb9, +0x1f, 0x71, 0xf9, 0xd1, 0xc7, 0xbd, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *slcluster_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_slcluster_png = new wxImage(); + if (!img_slcluster_png || !img_slcluster_png->IsOk()) + { + wxMemoryInputStream img_slcluster_pngIS(slcluster_png_data, sizeof(slcluster_png_data)); + img_slcluster_png->LoadFile(img_slcluster_pngIS, wxBITMAP_TYPE_PNG); + } + return img_slcluster_png; +} +#define slcluster_png_img slcluster_png_img() + +static wxBitmap *slcluster_png_bmp() +{ + static wxBitmap *bmp_slcluster_png; + if (!bmp_slcluster_png || !bmp_slcluster_png->IsOk()) + bmp_slcluster_png = new wxBitmap(*slcluster_png_img); + return bmp_slcluster_png; +} +#define slcluster_png_bmp slcluster_png_bmp() + +static wxIcon *slcluster_png_ico() +{ + static wxIcon *ico_slcluster_png; + if (!ico_slcluster_png || !ico_slcluster_png->IsOk()) + { + ico_slcluster_png = new wxIcon(); + ico_slcluster_png->CopyFromBitmap(*slcluster_png_bmp); + } + return ico_slcluster_png; +} +#define slcluster_png_ico slcluster_png_ico() + +#endif // SLCLUSTER_PNG_H diff --git a/include/images/slclusters.png b/include/images/slclusters.png new file mode 100644 index 0000000000000000000000000000000000000000..91884fd6316a9ba2625207470e8c3cc9318c6aa7 GIT binary patch literal 673 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl482JKxLR^8|H_tBKyRz=^#+-xe z(ogQFzI1fr)e|%BURr%*bKaHX6W=^JP`PZoYRR&qdCRY#n{s$l_Ju>e&+csb|L;@X zn*GZ!Un^g-?&{fzM>gfZdwHsU?a^7MF4e6$erjjUt0(7ccAqTVd~Evhi>W<5xzpyo zd3LFK`TmM+Cnq1iF#XWQukRk$uQ^)0@p$y2167+&maaWfy!!aJ_fP)+{#>_euhXPm zp40XO&D`hGzbkdo;lIDXetrM=|L;%#zTK-@zR|jShegMB)7EWC^AEp&b@s;DMc>~) z{_^&KQRB9Rxrg4qI(T?f?!`lWAD^B4`sRG)()IfFTjORQY}|0Ve(mYfMa$m3I`I6- zyyuUX-nuaJ)9XEVul8L%)qZGW&P&0$8-O9gSQ6wH%;50sMjDXAS>O>_45U54*zIJt z9guO#)5S4F;2_>f!|NnRFu8MfI_S@mO zQodwBW5_DDxO8lWz~Yx{ zuFv<*=-qNuNINO#@6W9_7u~rgwtFw1#C*P`mn8MS-)DPZdEmtPiEAo%z5HIXts(E% z?wJ2;h2Q({V7x9WwWgnCdlJxBswJ)wB`Jv|saDBFsX&Us$iUD**U(7Uz%azfz{gTe~DWM4f DOO#Hj literal 0 HcmV?d00001 diff --git a/include/images/slclusters.pngc b/include/images/slclusters.pngc new file mode 100644 index 0000000..6e07aee --- /dev/null +++ b/include/images/slclusters.pngc @@ -0,0 +1,129 @@ +#ifndef SLCLUSTERS_PNG_H +#define SLCLUSTERS_PNG_H + +static const unsigned char slclusters_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x0e, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xec, 0xe6, 0xd1, 0xde, +0xd4, 0xae, 0xc3, 0xb1, 0x6c, 0xc1, 0xae, 0x67, +0xc9, 0xb8, 0x7b, 0xd2, 0xc5, 0x91, 0xd5, 0xc8, +0x98, 0xdd, 0xd2, 0xab, 0xc4, 0xb3, 0x6e, 0xd4, +0xc7, 0x91, 0xec, 0xe4, 0xc0, 0x79, 0xa6, 0xb7, +0x25, 0x74, 0xa6, 0x72, 0x9e, 0xa7, 0xd7, 0xce, +0x94, 0xc3, 0xb2, 0x6b, 0xd0, 0xc2, 0x8d, 0xe6, +0xdc, 0xb4, 0xff, 0xfe, 0xf2, 0x7e, 0xac, 0xbf, +0xa7, 0xd3, 0xd6, 0x77, 0xa4, 0xae, 0xd5, 0xcd, +0x91, 0xc4, 0xb2, 0x6f, 0xee, 0xe9, 0xca, 0x7f, +0xad, 0xc5, 0x9a, 0xca, 0xd2, 0x7e, 0xac, 0xc7, +0xca, 0xb9, 0x7c, 0xea, 0xe4, 0xcf, 0x7c, 0xbb, +0xc9, 0x71, 0xb3, 0xc6, 0x97, 0xc7, 0xd1, 0x65, +0x8c, 0x8c, 0x6d, 0x96, 0x9e, 0xec, 0xe6, 0xd2, +0x7b, 0xa7, 0xbf, 0x78, 0xb6, 0xc9, 0x93, 0xc3, +0xd0, 0x97, 0xc2, 0xd1, 0xf5, 0xee, 0xe3, 0x7f, +0xac, 0xc5, 0x73, 0xb1, 0xc7, 0x5b, 0xa2, 0xc0, +0x7a, 0xb2, 0xc9, 0x75, 0xad, 0xc8, 0x73, 0xab, +0xc7, 0xf6, 0xef, 0xe4, 0xff, 0xfb, 0xf3, 0x7e, +0xaa, 0xbd, 0x42, 0x92, 0xba, 0x49, 0x96, 0xbc, +0x52, 0x99, 0xbe, 0x44, 0x8f, 0xba, 0x65, 0xa2, +0xc3, 0xfd, 0xfb, 0xf5, 0xf5, 0xef, 0xe3, 0xff, +0xfb, 0xf2, 0xfe, 0xf6, 0xde, 0x7a, 0xa7, 0xb1, +0x3b, 0x8b, 0xb8, 0x38, 0x88, 0xb7, 0x35, 0x85, +0xb6, 0x62, 0x9f, 0xc3, 0xef, 0xea, 0xcd, 0xd8, +0xcd, 0xa2, 0xf7, 0xef, 0xe3, 0xf4, 0xed, 0xc0, +0x32, 0x81, 0xb6, 0x60, 0x9d, 0xc2, 0xed, 0xea, +0xc1, 0xc3, 0xb2, 0x6d, 0xd1, 0xc2, 0x8e, 0xf1, +0xe6, 0xc9, 0xf5, 0xec, 0xcf, 0x79, 0xa5, 0xaf, +0x2f, 0x7f, 0xb5, 0x5e, 0x9b, 0xc1, 0x81, 0xb0, +0xcb, 0x7f, 0xad, 0xcb, 0x75, 0xa2, 0xa6, 0xee, +0xea, 0xc0, 0xe7, 0xe4, 0x9e, 0xe7, 0xe3, 0xa5, +0xda, 0xd0, 0x99, 0xf2, 0xeb, 0xbc, 0xdd, 0xd5, +0x8e, 0xd5, 0xca, 0x87, 0xc2, 0xb1, 0x6c, 0xe9, +0x11, 0x9d, 0xb0, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0xca, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x45, +0x90, 0xd9, 0x76, 0x01, 0x51, 0x14, 0x44, 0x6f, +0xf4, 0x41, 0x07, 0x15, 0x63, 0x24, 0x88, 0xa0, +0x35, 0xda, 0xd0, 0xe6, 0x29, 0xa6, 0x36, 0x93, +0x18, 0x22, 0x42, 0xc8, 0xff, 0xff, 0x88, 0xbb, +0x7a, 0x58, 0xea, 0xad, 0xf6, 0xc3, 0x5e, 0x75, +0x0e, 0x63, 0x0f, 0x36, 0x41, 0x20, 0xbb, 0xc3, +0xc9, 0xcc, 0x88, 0x8f, 0x2e, 0xb7, 0x07, 0x4f, +0x5e, 0x9f, 0x68, 0x02, 0x7f, 0x20, 0x18, 0xc2, +0x33, 0xc2, 0x2f, 0x7e, 0x13, 0xbc, 0x46, 0xa2, +0xbc, 0xc7, 0xf0, 0x16, 0x37, 0x01, 0xbd, 0xf3, +0x9e, 0x48, 0xa6, 0x20, 0x09, 0x12, 0xd2, 0xdc, +0x44, 0x72, 0x06, 0xb1, 0x64, 0x16, 0x39, 0x78, +0xa0, 0x80, 0x9b, 0x48, 0xce, 0x17, 0x90, 0x42, +0xb1, 0xa4, 0xa2, 0x5c, 0x01, 0x37, 0x91, 0x5c, +0xad, 0xd5, 0x91, 0x2b, 0x35, 0x9a, 0xad, 0x76, +0x07, 0xdd, 0x38, 0x07, 0x1f, 0xbd, 0xfe, 0x00, +0x6a, 0x73, 0x38, 0xd2, 0xc6, 0x98, 0x10, 0xa3, +0xe9, 0xac, 0xd7, 0x9f, 0x4b, 0x68, 0x8d, 0xb4, +0xc5, 0x12, 0x2b, 0x62, 0x6c, 0xfd, 0xf9, 0xb5, +0xd9, 0xa2, 0xdc, 0xd6, 0x16, 0xbb, 0xbd, 0x0e, +0x18, 0x9f, 0x0e, 0xa5, 0xd2, 0x19, 0x2f, 0xf7, +0xdf, 0x06, 0xe0, 0x39, 0xc0, 0xc8, 0xcf, 0x91, +0xac, 0x79, 0xba, 0xe9, 0xf7, 0x74, 0xb6, 0x80, +0x6e, 0xfa, 0xbb, 0x5c, 0xff, 0xad, 0x13, 0xef, +0x4f, 0xb8, 0x01, 0xd7, 0x15, 0x1a, 0xac, 0x8f, +0x04, 0xb7, 0x62, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *slclusters_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_slclusters_png = new wxImage(); + if (!img_slclusters_png || !img_slclusters_png->IsOk()) + { + wxMemoryInputStream img_slclusters_pngIS(slclusters_png_data, sizeof(slclusters_png_data)); + img_slclusters_png->LoadFile(img_slclusters_pngIS, wxBITMAP_TYPE_PNG); + } + return img_slclusters_png; +} +#define slclusters_png_img slclusters_png_img() + +static wxBitmap *slclusters_png_bmp() +{ + static wxBitmap *bmp_slclusters_png; + if (!bmp_slclusters_png || !bmp_slclusters_png->IsOk()) + bmp_slclusters_png = new wxBitmap(*slclusters_png_img); + return bmp_slclusters_png; +} +#define slclusters_png_bmp slclusters_png_bmp() + +static wxIcon *slclusters_png_ico() +{ + static wxIcon *ico_slclusters_png; + if (!ico_slclusters_png || !ico_slclusters_png->IsOk()) + { + ico_slclusters_png = new wxIcon(); + ico_slclusters_png->CopyFromBitmap(*slclusters_png_bmp); + } + return ico_slclusters_png; +} +#define slclusters_png_ico slclusters_png_ico() + +#endif // SLCLUSTERS_PNG_H diff --git a/include/images/sllisten.png b/include/images/sllisten.png new file mode 100644 index 0000000000000000000000000000000000000000..04e13436e9ab0ff6eeafae7f8248b5b8b1cca3e2 GIT binary patch literal 393 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}T7XZ8E0A8hc5QKS@s%s5jvYI2 z=+N%9YuD`9vFXZ{vqz5}*t2KnqD6}~Z(h4@-MSSkR?L|*XZ`vW2M_L?<;o?~r%&zb>RPmD)|xd-dV0F%&!4_*+1w>dX6@d+I%|p1L7+{H zB|(0{3=Yq3qyagc1s;*bK-vS0-A-oP0U1%AE{-7*mrKuEiZv+kumng5x)$6o-}_&6 zsqw|*C7**;1eGK>f4&rya5$k_rg*8~kJ6Hj+Jysf@0^rGfHJJaIX&r+X8 zZ~L22?lDK)-sjP?55HAsuoul_dKY$GQUhpIsOk()) + { + wxMemoryInputStream img_sllisten_pngIS(sllisten_png_data, sizeof(sllisten_png_data)); + img_sllisten_png->LoadFile(img_sllisten_pngIS, wxBITMAP_TYPE_PNG); + } + return img_sllisten_png; +} +#define sllisten_png_img sllisten_png_img() + +static wxBitmap *sllisten_png_bmp() +{ + static wxBitmap *bmp_sllisten_png; + if (!bmp_sllisten_png || !bmp_sllisten_png->IsOk()) + bmp_sllisten_png = new wxBitmap(*sllisten_png_img); + return bmp_sllisten_png; +} +#define sllisten_png_bmp sllisten_png_bmp() + +static wxIcon *sllisten_png_ico() +{ + static wxIcon *ico_sllisten_png; + if (!ico_sllisten_png || !ico_sllisten_png->IsOk()) + { + ico_sllisten_png = new wxIcon(); + ico_sllisten_png->CopyFromBitmap(*sllisten_png_bmp); + } + return ico_sllisten_png; +} +#define sllisten_png_ico sllisten_png_ico() + +#endif // SLLISTEN_PNG_H diff --git a/include/images/sllistens.png b/include/images/sllistens.png new file mode 100644 index 0000000000000000000000000000000000000000..6cd5dcd9ec6bf5531976cfe05e8a26cf82624aa3 GIT binary patch literal 409 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}a)3{WE0A8hc5QKS@s%s5jvYI2 z=+N%9YuD`9vFXZ{vqz5}*t2KnqD6~(d%M@ITi4mydGO$#6)RSpK7Dxe=CyO?%vryF z#k6VDR;^mHcJ0bJb7oJNFk#uUc^fybm^iV2(V|%^S1wq#Z0_#etEWF%%nr1Mu_VYZ zn8D%MjWi&Kv%n*=7)X17vD?XPJ0K(1)5S4F;&SYSn?lV7Jj|1ya){h&*%7{)qBUJJUKePwYKdz^NlIc# zs#S7PDv)9@GB7mIH8j#SFbpv=ure{WGBMRQFtsu;nDLs$ literal 0 HcmV?d00001 diff --git a/include/images/sllistens.pngc b/include/images/sllistens.pngc new file mode 100644 index 0000000..d7e30bd --- /dev/null +++ b/include/images/sllistens.pngc @@ -0,0 +1,96 @@ +#ifndef SLLISTENS_PNG_H +#define SLLISTENS_PNG_H + +static const unsigned char sllistens_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xad, 0xad, 0xad, 0x73, +0x73, 0x73, 0xd4, 0xd4, 0xca, 0xc6, 0xc6, 0xc0, +0xc2, 0xc2, 0xbb, 0xad, 0xad, 0xac, 0xb8, 0xb8, +0xb2, 0xd4, 0xd4, 0xcd, 0xc5, 0xc5, 0xc0, 0xbc, +0xbc, 0xb9, 0xa2, 0xa2, 0xa2, 0x8d, 0x8d, 0x8b, +0xae, 0xae, 0xae, 0x89, 0x89, 0x89, 0xc1, 0xc1, +0xbc, 0xa8, 0xa8, 0xa8, 0xcb, 0xcb, 0xc3, 0xb3, +0xb3, 0xad, 0x9c, 0x9c, 0x9c, 0xaf, 0xaf, 0xa8, +0x96, 0x96, 0x96, 0xaa, 0xaa, 0xa4, 0xad, 0xad, +0xa9, 0x9c, 0x9c, 0x9b, 0x90, 0x90, 0x90, 0xa6, +0xa6, 0x9e, 0xb1, 0xb1, 0xa8, 0x91, 0x91, 0x8f, +0xa2, 0xa2, 0x9a, 0xa9, 0xa9, 0xa0, 0xa6, 0xa6, +0x9d, 0xbb, 0xbb, 0xab, 0x97, 0xe4, 0xa3, 0x07, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x6d, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x5d, 0x90, 0xd9, 0x12, +0x83, 0x30, 0x0c, 0x03, 0x93, 0xe5, 0x08, 0x14, +0xda, 0x84, 0xb3, 0x77, 0xe1, 0xff, 0xbf, 0x12, +0xc8, 0x14, 0x12, 0xe3, 0x37, 0x69, 0x76, 0x64, +0xd9, 0x4a, 0xf9, 0xd1, 0x68, 0x15, 0x8f, 0x26, +0x41, 0xea, 0x34, 0xe3, 0x80, 0x34, 0x90, 0xe6, +0x86, 0x03, 0xa2, 0x28, 0x2f, 0x79, 0x55, 0x07, +0x88, 0xf2, 0x7a, 0x13, 0x10, 0xd6, 0x45, 0xd0, +0x66, 0x34, 0x26, 0x82, 0xfe, 0xa1, 0x3b, 0xd4, +0xee, 0xb9, 0x1e, 0x72, 0x55, 0xd7, 0x13, 0x36, +0xdb, 0x55, 0x0f, 0x23, 0xa1, 0x5a, 0x63, 0xee, +0x8f, 0xe7, 0x8b, 0xa8, 0x2c, 0xbc, 0x3f, 0x5f, +0x44, 0x7f, 0x7e, 0x13, 0xa7, 0x13, 0x67, 0x69, +0xf8, 0x27, 0x2c, 0xea, 0xb0, 0x04, 0x2a, 0x97, +0x29, 0x5f, 0x2d, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *sllistens_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_sllistens_png = new wxImage(); + if (!img_sllistens_png || !img_sllistens_png->IsOk()) + { + wxMemoryInputStream img_sllistens_pngIS(sllistens_png_data, sizeof(sllistens_png_data)); + img_sllistens_png->LoadFile(img_sllistens_pngIS, wxBITMAP_TYPE_PNG); + } + return img_sllistens_png; +} +#define sllistens_png_img sllistens_png_img() + +static wxBitmap *sllistens_png_bmp() +{ + static wxBitmap *bmp_sllistens_png; + if (!bmp_sllistens_png || !bmp_sllistens_png->IsOk()) + bmp_sllistens_png = new wxBitmap(*sllistens_png_img); + return bmp_sllistens_png; +} +#define sllistens_png_bmp sllistens_png_bmp() + +static wxIcon *sllistens_png_ico() +{ + static wxIcon *ico_sllistens_png; + if (!ico_sllistens_png || !ico_sllistens_png->IsOk()) + { + ico_sllistens_png = new wxIcon(); + ico_sllistens_png->CopyFromBitmap(*sllistens_png_bmp); + } + return ico_sllistens_png; +} +#define sllistens_png_ico sllistens_png_ico() + +#endif // SLLISTENS_PNG_H diff --git a/include/images/slnode-disabled.png b/include/images/slnode-disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..98dfa2a88dbe326a8e809ab9607f63c5a5b9186d GIT binary patch literal 355 zcmeAS@N?(olHy`uVBq!ia0vp^0wBx*Bp9q_EZ7UAm`Z~Df*BafCZDwc@shmVT^JZv z^(q?yd7K3vk;OpT1B~5HX4?T7(>+}rLnJQep1;V|WFT^^Fupp@LTOT2u$@y<-!rrF zG`(rs8cn-isZ}iqNlU4C_iukUzn_4QyaJ1|!+UY5!;k;5Z-1>n!^LD<#Abb!bD^uu zRxk8^>QKbC=8J<~^~rKe+X;+*tKRBdmMh6gz5UYd$gXx(iHpojySKdk@KUO7&4PQU z9?6s?upFBqAmeKJ-r@XI`R!R|AHTCtVDuF}5jP_n=tR{L*NBpo#FA92CuWneJxo!%-G4Y~O#nQ4^}4F;BA4M5cIsOk()) + { + wxMemoryInputStream img_slnode_disabled_pngIS(slnode_disabled_png_data, sizeof(slnode_disabled_png_data)); + img_slnode_disabled_png->LoadFile(img_slnode_disabled_pngIS, wxBITMAP_TYPE_PNG); + } + return img_slnode_disabled_png; +} +#define slnode_disabled_png_img slnode_disabled_png_img() + +static wxBitmap *slnode_disabled_png_bmp() +{ + static wxBitmap *bmp_slnode_disabled_png; + if (!bmp_slnode_disabled_png || !bmp_slnode_disabled_png->IsOk()) + bmp_slnode_disabled_png = new wxBitmap(*slnode_disabled_png_img); + return bmp_slnode_disabled_png; +} +#define slnode_disabled_png_bmp slnode_disabled_png_bmp() + +static wxIcon *slnode_disabled_png_ico() +{ + static wxIcon *ico_slnode_disabled_png; + if (!ico_slnode_disabled_png || !ico_slnode_disabled_png->IsOk()) + { + ico_slnode_disabled_png = new wxIcon(); + ico_slnode_disabled_png->CopyFromBitmap(*slnode_disabled_png_bmp); + } + return ico_slnode_disabled_png; +} +#define slnode_disabled_png_ico slnode_disabled_png_ico() + +#endif // SLNODE_DISABLED_PNG_H diff --git a/include/images/slnode-local.png b/include/images/slnode-local.png new file mode 100644 index 0000000000000000000000000000000000000000..1873d905812ff3a6bacf926bdf7be7b3f3a118d0 GIT binary patch literal 693 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47+nH~r%nc5Lc8w`IzMjT7&!Z$C3PZTr@qW1A1xHq2Jrv1a4e zsSj4Q-&xUodtJ}%ZBwq!N!>PQXYhhUVY61`tX;T%<>Y;ndmC5HU%9&d#`^YCyC$8Q zw#IwM)5c8?tDEL%PG03U{Zw?_Or-^tm$y#6HY;J1N7KH7!W}971zlUC=UhncKN!$^ zC}3{Mr44?!MjQ8 zu7q^VZrl;wcF?zeuUpktyIBS27gk+d-E?wl)P{A92lEcx&E9)EW9Kc;rd$7H_ zid}U%c*e;?3oh)Me0oyo+H9cu8K(}i9gqZuBV$RBUoeBivm0qZ4rhT!WHFHT0Ash4 z*>*t23Qrfu5Q)pl2?zKjX3mfZWSKD|az+4a#LWvVH!LTxTI}3WS@H7+YeJ2qVxnN6 zVIimIjD{&&de+R@)3j)kQHXs#%U~XVyWOmWWw3%Z@bVO9-?Hji; zZ(3VeHL~c;iH*5?$JS=+o;|fSe;b(oF*Z6LjB*eVk`j|+6e;NJ>FVpedbPK=yW5|E zOGQm}`I2QX8+*LZpJ=%?dunfiDZ{Vt(h7IBIr9PCtXkq4QIe8al4_M)lnSI6j0_A7 zbPbJk4Gcq!46ICytxQa{4NR>J4CcMlTZN(_H$NpatrDWaz!IzhsM^HJzzm|{)b!9b PKn)C@u6{1-oD!MIsOk()) + { + wxMemoryInputStream img_slnode_local_pngIS(slnode_local_png_data, sizeof(slnode_local_png_data)); + img_slnode_local_png->LoadFile(img_slnode_local_pngIS, wxBITMAP_TYPE_PNG); + } + return img_slnode_local_png; +} +#define slnode_local_png_img slnode_local_png_img() + +static wxBitmap *slnode_local_png_bmp() +{ + static wxBitmap *bmp_slnode_local_png; + if (!bmp_slnode_local_png || !bmp_slnode_local_png->IsOk()) + bmp_slnode_local_png = new wxBitmap(*slnode_local_png_img); + return bmp_slnode_local_png; +} +#define slnode_local_png_bmp slnode_local_png_bmp() + +static wxIcon *slnode_local_png_ico() +{ + static wxIcon *ico_slnode_local_png; + if (!ico_slnode_local_png || !ico_slnode_local_png->IsOk()) + { + ico_slnode_local_png = new wxIcon(); + ico_slnode_local_png->CopyFromBitmap(*slnode_local_png_bmp); + } + return ico_slnode_local_png; +} +#define slnode_local_png_ico slnode_local_png_ico() + +#endif // SLNODE_LOCAL_PNG_H diff --git a/include/images/slnode.png b/include/images/slnode.png new file mode 100644 index 0000000000000000000000000000000000000000..e087eea07af804d53423b9bac52f2d63c3b146f2 GIT binary patch literal 617 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47&!ubLR^8|-BVBZcrCxU_w|L{ zFAuGFdSKbpy$hf0ng3}2>~r%nc5Lc8w`IzMjT7&!Z$C3PZTr@qV|(V@+B)^Ys`fi8 zns2Y`xxH=5)j6r#c1=39wg3FqX%AMm-d@&lYf0^mMK#w}x8GRberi_2ru~cVuIaq9 zuU6W5AT5w@f=-RMas};boU@Qsp3ubV5b|VeQ;VkfoEC$jZVC;4>+YZQ>;pyTS zB5^r6;Q*h+%o!4aEHh?A&In+QxOsu)hUElSi=8_vD}Mf9eZUmcRdP`(kYX@0Ff`CLG}1LN3^6jWGBLI?G1WFOwK6c6 u_fBsWiiX_$l+3hBhz0{oum+%N6DtEVh=xIsOk()) + { + wxMemoryInputStream img_slnode_pngIS(slnode_png_data, sizeof(slnode_png_data)); + img_slnode_png->LoadFile(img_slnode_pngIS, wxBITMAP_TYPE_PNG); + } + return img_slnode_png; +} +#define slnode_png_img slnode_png_img() + +static wxBitmap *slnode_png_bmp() +{ + static wxBitmap *bmp_slnode_png; + if (!bmp_slnode_png || !bmp_slnode_png->IsOk()) + bmp_slnode_png = new wxBitmap(*slnode_png_img); + return bmp_slnode_png; +} +#define slnode_png_bmp slnode_png_bmp() + +static wxIcon *slnode_png_ico() +{ + static wxIcon *ico_slnode_png; + if (!ico_slnode_png || !ico_slnode_png->IsOk()) + { + ico_slnode_png = new wxIcon(); + ico_slnode_png->CopyFromBitmap(*slnode_png_bmp); + } + return ico_slnode_png; +} +#define slnode_png_ico slnode_png_ico() + +#endif // SLNODE_PNG_H diff --git a/include/images/slnodes.png b/include/images/slnodes.png new file mode 100644 index 0000000000000000000000000000000000000000..7cfab77c6f723bf1247325eac8cb2166627dffd4 GIT binary patch literal 490 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf%mAMdS0KH6>ggV@<=2k9KD*<^ z{+Z`iR2y$9bWNx=Y*4MY7T7azqDn- z<)x+jkFI^(>$`Gw`<>Mtx3K zj$CuWneJxo!%-G4Y~O#nQ4^}4F;BA4M5cIsOk()) + { + wxMemoryInputStream img_slnodes_pngIS(slnodes_png_data, sizeof(slnodes_png_data)); + img_slnodes_png->LoadFile(img_slnodes_pngIS, wxBITMAP_TYPE_PNG); + } + return img_slnodes_png; +} +#define slnodes_png_img slnodes_png_img() + +static wxBitmap *slnodes_png_bmp() +{ + static wxBitmap *bmp_slnodes_png; + if (!bmp_slnodes_png || !bmp_slnodes_png->IsOk()) + bmp_slnodes_png = new wxBitmap(*slnodes_png_img); + return bmp_slnodes_png; +} +#define slnodes_png_bmp slnodes_png_bmp() + +static wxIcon *slnodes_png_ico() +{ + static wxIcon *ico_slnodes_png; + if (!ico_slnodes_png || !ico_slnodes_png->IsOk()) + { + ico_slnodes_png = new wxIcon(); + ico_slnodes_png->CopyFromBitmap(*slnodes_png_bmp); + } + return ico_slnodes_png; +} +#define slnodes_png_ico slnodes_png_ico() + +#endif // SLNODES_PNG_H diff --git a/include/images/slpath.png b/include/images/slpath.png new file mode 100644 index 0000000000000000000000000000000000000000..3c8b7621e49e9a59145b8f0117878ffd2afc5768 GIT binary patch literal 519 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMffdHQnS0KI9tL^EYOFKQ=_JvKj zIpy%#iZv&T7Cqa0`E>EJD_z?kZ9a3Me$$&hZ(gi>@nGSlqiORl_iX-f{mIdk*|(-1 zy*Km1qotS5l&!cnWyjg_HBVRHd%FDb(-jYIOgy+Rw0~bn|Fzz|_h(7Mm~@bDJ=7dz&z7XNNFKM_WsW@ZY>~)YZGbLOEpd$~Nl7e8wMs5Z1yT$~28IT@hDN#uh9O1IsOk()) + { + wxMemoryInputStream img_slpath_pngIS(slpath_png_data, sizeof(slpath_png_data)); + img_slpath_png->LoadFile(img_slpath_pngIS, wxBITMAP_TYPE_PNG); + } + return img_slpath_png; +} +#define slpath_png_img slpath_png_img() + +static wxBitmap *slpath_png_bmp() +{ + static wxBitmap *bmp_slpath_png; + if (!bmp_slpath_png || !bmp_slpath_png->IsOk()) + bmp_slpath_png = new wxBitmap(*slpath_png_img); + return bmp_slpath_png; +} +#define slpath_png_bmp slpath_png_bmp() + +static wxIcon *slpath_png_ico() +{ + static wxIcon *ico_slpath_png; + if (!ico_slpath_png || !ico_slpath_png->IsOk()) + { + ico_slpath_png = new wxIcon(); + ico_slpath_png->CopyFromBitmap(*slpath_png_bmp); + } + return ico_slpath_png; +} +#define slpath_png_ico slpath_png_ico() + +#endif // SLPATH_PNG_H diff --git a/include/images/slpaths.png b/include/images/slpaths.png new file mode 100644 index 0000000000000000000000000000000000000000..c9cfd451a4f0fe80fad6c388ab06ca046955ad45 GIT binary patch literal 518 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMffdHQnS0KIHuj^#dqGx+A@AmE7 z<=t_A(YZ$}t{qFCce!Wt(bU;@=bX4X?Z7VY_PxPwWv~&%JVY`uT?|&h829xx4JhF0b}86>AR1&br*V=fT|T_oiREKj-3w#`Oo|rW{RL zc)oi5zL35nsWYFidv>~f$(62M&(}VAyy*VJ1-Ey4w(XCYbff>!oe7t3^_;)jxqE;3 zglkiF?2njmt$)|O8JF)&Id^a7g*#Kv+?{du_LP$kmY;dB?)ui7)yfuf*Bm1 z-ADs+I14-?i-EKU7`vU!wgWP1JzX3_BrYc>B%~yzF)*r$85})u>e#u1Cl4GrdGzdI zZm|cC#RWu!!~{i!r%zzv_V7GyaO%`aZ4E6?ZRO0Mz|i31Ydae)e5EvInJnG9rL^SW zEQtjU{`U`DIC0~M$gy+-)iyA-GBB9;P7mZa qgofPwl+3hBhz0{oum+%N6DtEVh=x+E^ literal 0 HcmV?d00001 diff --git a/include/images/slpaths.pngc b/include/images/slpaths.pngc new file mode 100644 index 0000000..66a2332 --- /dev/null +++ b/include/images/slpaths.pngc @@ -0,0 +1,109 @@ +#ifndef SLPATHS_PNG_H +#define SLPATHS_PNG_H + +static const unsigned char slpaths_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xc0, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xbb, 0x4e, 0x8a, 0xc9, +0x72, 0xa2, 0xe6, 0xbd, 0xd3, 0xbb, 0x4d, 0x89, +0xba, 0x4b, 0x88, 0xdf, 0xa2, 0xce, 0xe2, 0xa8, +0xd6, 0xc6, 0x67, 0x9e, 0xd3, 0x8c, 0xb3, 0xc5, +0x65, 0x9b, 0xdd, 0x9c, 0xc8, 0xd9, 0x96, 0xc0, +0xba, 0x4b, 0x87, 0xbd, 0x53, 0x8e, 0xea, 0xba, +0xe5, 0xe7, 0xae, 0xe9, 0xe5, 0xaa, 0xe2, 0xd9, +0x93, 0xc4, 0xbe, 0x55, 0x90, 0xbe, 0x55, 0x8f, +0xd7, 0x8e, 0xbe, 0xdf, 0x9d, 0xd4, 0xdd, 0x97, +0xcf, 0xe1, 0xa8, 0xcd, 0xbc, 0x51, 0x8c, 0xdd, +0xa6, 0xc4, 0xba, 0x4a, 0x87, 0xcc, 0x78, 0xac, +0xc3, 0x5d, 0x9a, 0xd3, 0x81, 0xbc, 0xe0, 0x9d, +0xd7, 0xde, 0x97, 0xd2, 0xdf, 0x9c, 0xd1, 0xd0, +0x81, 0xaf, 0xc1, 0x5e, 0x94, 0xc5, 0x62, 0xa1, +0xcf, 0x7b, 0xaf, 0xbe, 0x54, 0x8e, 0xc4, 0x65, +0x99, 0xe7, 0xae, 0xe6, 0xcb, 0x77, 0xa4, 0xd4, +0x8a, 0xba, 0xe7, 0xad, 0xe4, 0xe3, 0xa2, 0xdf, +0xe1, 0xa0, 0xdb, 0xb9, 0x49, 0x86, 0xbf, 0x58, +0x92, 0xd8, 0x8f, 0xc2, 0xdc, 0x90, 0xd3, 0xda, +0x8c, 0xcf, 0xd5, 0x89, 0xbb, 0xbf, 0x57, 0x90, +0xd6, 0x94, 0xb8, 0xbf, 0x58, 0x90, 0xd6, 0x8f, +0xba, 0xde, 0x98, 0xd3, 0xdc, 0x94, 0xce, 0xde, +0x99, 0xd0, 0xdc, 0x95, 0xcc, 0xdd, 0x98, 0xcd, +0xdb, 0x94, 0xc9, 0xe0, 0xa7, 0xcc, 0xe0, 0xa4, +0xc9, 0x7f, 0x51, 0x1d, 0xaa, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0x7d, 0x49, 0x44, 0x41, 0x54, 0x18, +0xd3, 0x63, 0x60, 0x60, 0x64, 0x62, 0x66, 0x00, +0x01, 0x26, 0x16, 0x30, 0xc5, 0xc0, 0xca, 0xc6, +0xce, 0xc1, 0xc9, 0xc0, 0xc0, 0xc9, 0xc5, 0xcd, +0xc3, 0x0b, 0x16, 0xe0, 0xe3, 0x17, 0x10, 0x14, +0x12, 0x16, 0x11, 0x15, 0x13, 0x97, 0x90, 0x04, +0x0b, 0x48, 0x49, 0xcb, 0x30, 0xca, 0xca, 0xc9, +0x2b, 0x28, 0x2a, 0x49, 0x2b, 0x23, 0x69, 0x52, +0x51, 0x55, 0x53, 0xc7, 0xad, 0x89, 0x81, 0x38, +0x4d, 0x1a, 0x28, 0x9a, 0x34, 0xa5, 0xb5, 0xb4, +0x75, 0x74, 0xc1, 0x9a, 0x18, 0xa0, 0x40, 0x4f, +0xdf, 0xc0, 0xd0, 0xc8, 0xd8, 0xc4, 0x14, 0xc6, +0x67, 0x30, 0x33, 0xd7, 0xb3, 0xb0, 0xd4, 0x63, +0x40, 0x02, 0x66, 0x7a, 0x56, 0xd6, 0x28, 0x02, +0x0c, 0x7a, 0x36, 0xb6, 0xa8, 0x02, 0x66, 0x76, +0xf6, 0x66, 0x0c, 0xa8, 0x22, 0x10, 0x3e, 0x00, +0x62, 0xe9, 0x0f, 0x06, 0xee, 0xa0, 0x94, 0x85, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, +0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *slpaths_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_slpaths_png = new wxImage(); + if (!img_slpaths_png || !img_slpaths_png->IsOk()) + { + wxMemoryInputStream img_slpaths_pngIS(slpaths_png_data, sizeof(slpaths_png_data)); + img_slpaths_png->LoadFile(img_slpaths_pngIS, wxBITMAP_TYPE_PNG); + } + return img_slpaths_png; +} +#define slpaths_png_img slpaths_png_img() + +static wxBitmap *slpaths_png_bmp() +{ + static wxBitmap *bmp_slpaths_png; + if (!bmp_slpaths_png || !bmp_slpaths_png->IsOk()) + bmp_slpaths_png = new wxBitmap(*slpaths_png_img); + return bmp_slpaths_png; +} +#define slpaths_png_bmp slpaths_png_bmp() + +static wxIcon *slpaths_png_ico() +{ + static wxIcon *ico_slpaths_png; + if (!ico_slpaths_png || !ico_slpaths_png->IsOk()) + { + ico_slpaths_png = new wxIcon(); + ico_slpaths_png->CopyFromBitmap(*slpaths_png_bmp); + } + return ico_slpaths_png; +} +#define slpaths_png_ico slpaths_png_ico() + +#endif // SLPATHS_PNG_H diff --git a/include/images/slset.png b/include/images/slset.png new file mode 100644 index 0000000000000000000000000000000000000000..c018b133fd20249a5ccd0004fe24f696c8a104af GIT binary patch literal 625 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMfp8%f_S0KIlaBba8rNeJ~4!!B# z{k&!8v!<<&>oz>7oP9BQ?cK7)*Rp4vPndi<+M{V-TzB1qD;cvcBuzaNJK?L@@wAj_2>KAg?(}bhwf$VzMZl2)|5_{Uti|`_&D*}j>_Bv zcXRgMN#AiRdGqzZKeqh-w({4PIX^!3e|y*P^>tD9-aCmKuKoVD{O9LcKR)z)dsp}6 zb^hlUi65T^$FIHm^Ye`FAG*H1t@-jQ_tT5`k52<9Z@oEbYWk<=F(01ze|X|!#eDe@ z(Ep4jL4Lsu4$p3+0Xdun9+AaB+5?Q;PG;Ky8EZUU977~7hxT6;IuyXedi%k&Mp_cg8rl9xENN`v&dAOkweH&Nw|V|LhpO4F=AE1Vy0_e-yk>*+dGXBm8)Wv@|CWFC zk2#=DxSC(9?HAD9swJ)wB`Jv|saDBFsX&Us$iUD**U(7Uz%azfz{gTe~DWM4fKLa9K literal 0 HcmV?d00001 diff --git a/include/images/slset.pngc b/include/images/slset.pngc new file mode 100644 index 0000000..12aa3d8 --- /dev/null +++ b/include/images/slset.pngc @@ -0,0 +1,123 @@ +#ifndef SLSET_PNG_H +#define SLSET_PNG_H + +static const unsigned char slset_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xfc, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xb3, 0xc3, 0x7d, 0x7e, +0x99, 0x22, 0xc3, 0xed, 0x8c, 0xc2, 0xec, 0x8b, +0xbb, 0xe7, 0x84, 0xb9, 0xe6, 0x82, 0xb5, 0xe3, +0x7e, 0xb0, 0xe0, 0x79, 0x9b, 0xd1, 0x63, 0xad, +0xdd, 0x76, 0xa3, 0xd6, 0x6b, 0x98, 0xcf, 0x60, +0x93, 0xcb, 0x5b, 0x48, 0x82, 0xbe, 0x5e, 0x8b, +0x7e, 0xa0, 0xd4, 0x68, 0x9a, 0xd0, 0x62, 0x95, +0xcc, 0x5d, 0x90, 0xc9, 0x57, 0x8b, 0xc5, 0x52, +0x74, 0xc8, 0xe0, 0x73, 0xc7, 0xdf, 0x72, 0xc5, +0xdf, 0x70, 0xc3, 0xde, 0x6f, 0xc1, 0xdd, 0x6d, +0xbf, 0xdc, 0x92, 0xca, 0x5a, 0x8d, 0xc7, 0x54, +0x88, 0xc3, 0x4f, 0x83, 0xc0, 0x4b, 0x73, 0xc6, +0xdf, 0x6e, 0xc1, 0xdd, 0x6c, 0xbe, 0xdc, 0x8f, +0xc8, 0x56, 0x8a, 0xc4, 0x51, 0xa4, 0x9f, 0x30, +0xb9, 0x87, 0x1b, 0xa0, 0x9c, 0x2c, 0x71, 0xc5, +0xdf, 0x6e, 0xc0, 0xdd, 0x8c, 0xc6, 0x53, 0x87, +0xc2, 0x4e, 0x83, 0xbf, 0x4a, 0xfc, 0xf7, 0xad, +0xa1, 0x8e, 0x1e, 0x70, 0xc2, 0xde, 0x6a, 0xbb, +0xdb, 0x68, 0xb9, 0xda, 0x94, 0x89, 0x44, 0xfa, +0xf4, 0x9f, 0xf8, 0xf1, 0x91, 0xd6, 0xb8, 0x79, +0x6d, 0xc0, 0xdd, 0x6c, 0xbd, 0xdc, 0x67, 0xb8, +0xda, 0x63, 0xb3, 0xd7, 0xfd, 0xf8, 0xb4, 0xfb, +0xf6, 0xa9, 0xfa, 0xf4, 0x9c, 0xf8, 0xf1, 0x8f, +0xf6, 0xee, 0x80, 0xf5, 0xeb, 0x72, 0x6b, 0xbd, +0xdc, 0x61, 0xb0, 0xd6, 0xfb, 0xf6, 0xa7, 0xf9, +0xf3, 0x9a, 0xf8, 0xf0, 0x8c, 0xf6, 0xee, 0x7e, +0xf4, 0xeb, 0x6f, 0xf3, 0xe8, 0x61, 0xf1, 0xe5, +0x53, 0x5f, 0xad, 0xd5, 0xf9, 0xf3, 0x98, 0xf7, +0xf0, 0x8a, 0xf6, 0xed, 0x7c, 0xf4, 0xea, 0x6d, +0xf2, 0xe8, 0x5f, 0xf1, 0xe5, 0x51, 0x93, 0xb5, +0xd9, 0x92, 0x95, 0x67, 0xf2, 0xe7, 0x5c, 0xf0, +0xe4, 0x4f, 0xf0, 0xe4, 0x4c, 0x3a, 0x03, 0xd3, +0xe2, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0xac, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x55, 0x8f, 0xd5, +0x12, 0xc2, 0x50, 0x0c, 0x05, 0xdb, 0xe0, 0x96, +0xe2, 0x14, 0xa7, 0x40, 0x70, 0x77, 0x77, 0x77, +0xf9, 0xff, 0x7f, 0xe1, 0xde, 0x32, 0x4c, 0xe9, +0xbe, 0x65, 0x73, 0x4e, 0x66, 0x22, 0x08, 0x1c, +0x11, 0x44, 0xe1, 0x1f, 0x11, 0x0c, 0xa0, 0x13, +0x60, 0x04, 0x13, 0xe8, 0x72, 0x60, 0xb6, 0x58, +0x41, 0x04, 0x1b, 0x68, 0x1d, 0x3b, 0x38, 0xc0, +0xe9, 0xe2, 0x02, 0xbf, 0x48, 0x6e, 0x8f, 0xd7, +0xe7, 0x57, 0x45, 0x20, 0x18, 0x92, 0xc3, 0x11, +0x84, 0x68, 0x2c, 0x9e, 0x50, 0x45, 0x32, 0x24, +0xa7, 0x14, 0x94, 0xd2, 0x99, 0x2c, 0xe5, 0x54, +0x91, 0x97, 0x0b, 0x6c, 0x2e, 0x96, 0xca, 0x54, +0xa1, 0x2a, 0x17, 0xb5, 0x82, 0x52, 0x6f, 0x60, +0x93, 0x88, 0x5a, 0x6d, 0xea, 0x30, 0xd1, 0xed, +0x61, 0x1f, 0x07, 0x34, 0x1c, 0x8d, 0x27, 0xd3, +0x19, 0x33, 0x38, 0x47, 0x01, 0x07, 0x0b, 0x5a, +0xae, 0xd6, 0x9b, 0xed, 0x6e, 0x4f, 0x2c, 0xc2, +0x7b, 0x07, 0x3a, 0x9e, 0xce, 0x97, 0xeb, 0x8d, +0x77, 0x38, 0x77, 0x7c, 0xb0, 0x1b, 0xcf, 0x17, +0x69, 0xef, 0xb0, 0x1c, 0xbd, 0x7f, 0xfb, 0x1f, +0xea, 0xfe, 0x03, 0x50, 0x7e, 0x13, 0x7b, 0x0f, +0x2a, 0x86, 0xfa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *slset_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_slset_png = new wxImage(); + if (!img_slset_png || !img_slset_png->IsOk()) + { + wxMemoryInputStream img_slset_pngIS(slset_png_data, sizeof(slset_png_data)); + img_slset_png->LoadFile(img_slset_pngIS, wxBITMAP_TYPE_PNG); + } + return img_slset_png; +} +#define slset_png_img slset_png_img() + +static wxBitmap *slset_png_bmp() +{ + static wxBitmap *bmp_slset_png; + if (!bmp_slset_png || !bmp_slset_png->IsOk()) + bmp_slset_png = new wxBitmap(*slset_png_img); + return bmp_slset_png; +} +#define slset_png_bmp slset_png_bmp() + +static wxIcon *slset_png_ico() +{ + static wxIcon *ico_slset_png; + if (!ico_slset_png || !ico_slset_png->IsOk()) + { + ico_slset_png = new wxIcon(); + ico_slset_png->CopyFromBitmap(*slset_png_bmp); + } + return ico_slset_png; +} +#define slset_png_ico slset_png_ico() + +#endif // SLSET_PNG_H diff --git a/include/images/slset2.png b/include/images/slset2.png new file mode 100644 index 0000000000000000000000000000000000000000..6f3eb0fb90c7be5dc8867979da3e799fcfac1af2 GIT binary patch literal 527 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf_5hy{S0KIlaBba8rNeJ~4!!B# z{k&!8v!<<&>oz>7oP9BQ?cK7)*Rp4vPndi<+M{V-TzB1qD;cvcBuzaNJKj|ahR?E~U=!+-@7}-t`22jflJw6< ziIsOk()) + { + wxMemoryInputStream img_slset2_pngIS(slset2_png_data, sizeof(slset2_png_data)); + img_slset2_png->LoadFile(img_slset2_pngIS, wxBITMAP_TYPE_PNG); + } + return img_slset2_png; +} +#define slset2_png_img slset2_png_img() + +static wxBitmap *slset2_png_bmp() +{ + static wxBitmap *bmp_slset2_png; + if (!bmp_slset2_png || !bmp_slset2_png->IsOk()) + bmp_slset2_png = new wxBitmap(*slset2_png_img); + return bmp_slset2_png; +} +#define slset2_png_bmp slset2_png_bmp() + +static wxIcon *slset2_png_ico() +{ + static wxIcon *ico_slset2_png; + if (!ico_slset2_png || !ico_slset2_png->IsOk()) + { + ico_slset2_png = new wxIcon(); + ico_slset2_png->CopyFromBitmap(*slset2_png_bmp); + } + return ico_slset2_png; +} +#define slset2_png_ico slset2_png_ico() + +#endif // SLSET2_PNG_H diff --git a/include/images/slsets.png b/include/images/slsets.png new file mode 100644 index 0000000000000000000000000000000000000000..18b1551737a1f26f4cab96cae1a3990dd2d008f7 GIT binary patch literal 439 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}QGic~E0C_6skHfU?cujQ2VQq> zf7-C=VfDnVE*?$$GA1OIoOn=t?0(^qdlf75i;mqdID9W+&gr}Zch}r4U3N2n)`g_p z{dX2z$(VdPy7zeK4U%k+kW0(#GqttFOea zy3+Okn-mdKI;Vst E0M6C0ga7~l literal 0 HcmV?d00001 diff --git a/include/images/slsets.pngc b/include/images/slsets.pngc new file mode 100644 index 0000000..ad939be --- /dev/null +++ b/include/images/slsets.pngc @@ -0,0 +1,99 @@ +#ifndef SLSETS_PNG_H +#define SLSETS_PNG_H + +static const unsigned char slsets_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x72, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x7e, 0x99, 0x22, 0xb3, +0xc3, 0x7d, 0xc3, 0xed, 0x8c, 0xc0, 0xeb, 0x89, +0xb7, 0xe5, 0x80, 0xb2, 0xe1, 0x7b, 0x91, 0xb5, +0x44, 0x48, 0x82, 0xbe, 0x68, 0x90, 0x62, 0x74, +0xc8, 0xe0, 0x73, 0xc6, 0xdf, 0x71, 0xc4, 0xde, +0x78, 0xa9, 0x6f, 0x72, 0xc6, 0xdf, 0x70, 0xc3, +0xde, 0x58, 0x9c, 0xcb, 0x6e, 0xc0, 0xdd, 0xac, +0xdd, 0x75, 0xa6, 0xd9, 0x6f, 0x9a, 0xd0, 0x62, +0x6d, 0xbf, 0xdc, 0xa0, 0xd4, 0x68, 0x93, 0xcb, +0x5b, 0x8d, 0xc7, 0x55, 0x93, 0xb5, 0xd9, 0x88, +0xc3, 0x4f, 0x82, 0xbf, 0x4a, 0x7e, 0xbc, 0x45, +0x7a, 0xb9, 0x41, 0x6b, 0xbd, 0xdb, 0x75, 0xa6, +0x6e, 0x68, 0xb9, 0xda, 0x65, 0xb5, 0xd8, 0x62, +0xb2, 0xd7, 0x62, 0xb1, 0xd7, 0x5d, 0xab, 0xd4, +0x5d, 0xaa, 0xd4, 0x8a, 0xff, 0xf6, 0x2a, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x7c, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x55, 0xcf, 0xd9, 0x16, 0xc2, +0x20, 0x0c, 0x45, 0xd1, 0xdc, 0x3a, 0x5d, 0x47, +0x44, 0xab, 0x36, 0xad, 0xf3, 0xf0, 0xff, 0xbf, +0x68, 0xa8, 0x0b, 0x4c, 0x79, 0xe3, 0xac, 0x0d, +0x04, 0x11, 0x5b, 0xa8, 0xc4, 0xaf, 0x0a, 0x23, +0x0c, 0x02, 0xc6, 0x98, 0x00, 0xbe, 0x61, 0x3a, +0x33, 0x94, 0x0b, 0xc9, 0x39, 0x3c, 0xe2, 0x62, +0xb9, 0x5a, 0xc3, 0x21, 0x6e, 0xc2, 0xb6, 0x20, +0xb1, 0xc4, 0x10, 0x33, 0xda, 0xed, 0x51, 0x43, +0x78, 0x60, 0x46, 0xc7, 0xfa, 0xd4, 0x40, 0x94, +0x5a, 0x50, 0xd3, 0x76, 0xbf, 0x6b, 0x7a, 0x14, +0xd1, 0x76, 0xe7, 0x4b, 0x1f, 0xd4, 0x9e, 0x0e, +0xf1, 0x7a, 0x03, 0xfe, 0xf3, 0x19, 0xba, 0x3f, +0x9e, 0xd4, 0x32, 0x6c, 0x42, 0x2f, 0xbe, 0xe9, +0xbf, 0xa4, 0xfc, 0x0c, 0xf6, 0xa9, 0xa4, 0x13, +0x5f, 0x9b, 0x88, 0x06, 0x71, 0x34, 0x11, 0x66, +0x61, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, +0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *slsets_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_slsets_png = new wxImage(); + if (!img_slsets_png || !img_slsets_png->IsOk()) + { + wxMemoryInputStream img_slsets_pngIS(slsets_png_data, sizeof(slsets_png_data)); + img_slsets_png->LoadFile(img_slsets_pngIS, wxBITMAP_TYPE_PNG); + } + return img_slsets_png; +} +#define slsets_png_img slsets_png_img() + +static wxBitmap *slsets_png_bmp() +{ + static wxBitmap *bmp_slsets_png; + if (!bmp_slsets_png || !bmp_slsets_png->IsOk()) + bmp_slsets_png = new wxBitmap(*slsets_png_img); + return bmp_slsets_png; +} +#define slsets_png_bmp slsets_png_bmp() + +static wxIcon *slsets_png_ico() +{ + static wxIcon *ico_slsets_png; + if (!ico_slsets_png || !ico_slsets_png->IsOk()) + { + ico_slsets_png = new wxIcon(); + ico_slsets_png->CopyFromBitmap(*slsets_png_bmp); + } + return ico_slsets_png; +} +#define slsets_png_ico slsets_png_ico() + +#endif // SLSETS_PNG_H diff --git a/include/images/slsubscription.png b/include/images/slsubscription.png new file mode 100644 index 0000000000000000000000000000000000000000..78f4953d9cde140d1a98358368c15f3ea3516170 GIT binary patch literal 703 zcmY+ATS!v@7{`w$%WE2xq=tx86l$JLEgBITTPli9=cp)X^RjM;rUNslNDpP+Eg{h; zUn-TEK|YudCZXl6vUFa$sq@SoH+MNZ_nmXLj{4NY|NDP``2QZh?~yDkHON2Q9{_-$ z^fXB>?;+dr-NVo0alvu`@H!#O%#-p_p-^}{9?tDyI5)+*afU-^)=IIP1Y^WqYbgB( zp2sFl&5mdF`tO zM_ru0s(Q9kJGqJ3X;y!)`ili0Ghr5zG2yP&6=-&8ZDJD}8PL3c7|~jmu#VDyo%GVL z_34VL88hERS+aj&sM3Ja%MMC!BWJgW4+9z(_JTs%B4zy?HOLUXF6E>lV;?tAhImb*os^@Iu+?Ce5)@V;M)|yzq|px2QBPR4n7P;qUqg&J-z>zG z8UF-hBam}=9U0PG-!JG>uf}_E{ zfj_P*10VGG`UM5F)cN$*)i)!}O$~cH+gg2v2L;%ZQSFiL;AkN9Rb*^-SIkTPmZKW! zB~779QzR}ZE8-0hfkH4&D2fAxc_L7pm>^C}iUE_vAo$#NvhP2jxTNr=x^fo)&+Gtv ZJ5dat+6AVbDs(&mq)W3TZ_X?4{{w+2eKi08 literal 0 HcmV?d00001 diff --git a/include/images/slsubscription.pngc b/include/images/slsubscription.pngc new file mode 100644 index 0000000..d48682d --- /dev/null +++ b/include/images/slsubscription.pngc @@ -0,0 +1,132 @@ +#ifndef SLSUBSCRIPTION_PNG_H +#define SLSUBSCRIPTION_PNG_H + +static const unsigned char slsubscription_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x29, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0xff, +0xff, 0xff, 0xfd, 0xfe, 0xff, 0xfb, 0xfd, 0xfe, +0xf8, 0xfc, 0xfe, 0xf5, 0xfb, 0xfd, 0xf1, 0xf9, +0xfc, 0xed, 0xf8, 0xfc, 0xe9, 0xf6, 0xfb, 0xe5, +0xf5, 0xfa, 0xe1, 0xf3, 0xf9, 0xdd, 0xf1, 0xf8, +0xfa, 0xfd, 0xfe, 0xf7, 0xfc, 0xfe, 0xf4, 0xfb, +0xfd, 0xed, 0xf8, 0xfb, 0xe2, 0xdf, 0xe4, 0xd1, +0x79, 0x7c, 0xda, 0xdc, 0xe3, 0xd8, 0xef, 0xf7, +0xf7, 0xfc, 0xfd, 0xf0, 0xf9, 0xfc, 0xc5, 0x00, +0x00, 0xcc, 0x77, 0x7b, 0xd3, 0xed, 0xf6, 0xf0, +0xe4, 0xe7, 0xd9, 0x7c, 0x7e, 0xe8, 0xe2, 0xe5, +0xe8, 0xf6, 0xfb, 0xe1, 0xdf, 0xe4, 0xd1, 0xd9, +0xe1, 0xce, 0xeb, 0xf5, 0xf3, 0xfa, 0xfd, 0xd5, +0x7b, 0x7d, 0xd0, 0x79, 0x7c, 0xc9, 0xe9, 0xf4, +0xef, 0xf9, 0xfc, 0xd5, 0x7a, 0x7d, 0xcd, 0xeb, +0xf5, 0xc4, 0xe7, 0xf4, 0xeb, 0xf7, 0xfb, 0xe7, +0xf5, 0xfa, 0xe0, 0xdf, 0xe4, 0xd0, 0xd8, 0xe1, +0xc8, 0xe9, 0xf4, 0xbe, 0xaf, 0x74, 0xb9, 0x87, +0x1b, 0x90, 0x72, 0x33, 0xe3, 0xf3, 0xf9, 0xde, +0xf2, 0xf9, 0xd8, 0xdb, 0xe3, 0xcb, 0x77, 0x7b, +0xcc, 0xea, 0xf5, 0xc4, 0xe7, 0xf3, 0xfc, 0xf7, +0xad, 0xd6, 0xb8, 0x79, 0xe2, 0xf3, 0xf9, 0xd9, +0xf0, 0xf8, 0xd5, 0xee, 0xf7, 0xd0, 0xec, 0xf6, +0xbf, 0xaf, 0x74, 0xfa, 0xf4, 0x9f, 0xf8, 0xf1, +0x91, 0x1e, 0x50, 0xad, 0xfd, 0xf8, 0xb4, 0xfb, +0xf6, 0xa9, 0xfa, 0xf4, 0x9c, 0xf8, 0xf1, 0x8f, +0xf6, 0xee, 0x80, 0xf5, 0xeb, 0x72, 0xd9, 0xef, +0xf7, 0xd4, 0xee, 0xf7, 0xcb, 0xea, 0xf5, 0xc7, +0xe8, 0xf4, 0xc2, 0xe6, 0xf3, 0xfb, 0xf6, 0xa7, +0xf9, 0xf3, 0x9a, 0xf8, 0xf0, 0x8c, 0xf6, 0xee, +0x7e, 0xf4, 0xeb, 0x6f, 0xf3, 0xe8, 0x61, 0xf1, +0xe5, 0x53, 0xd4, 0xed, 0xf7, 0xf9, 0xf3, 0x98, +0xf7, 0xf0, 0x8a, 0xf6, 0xed, 0x7c, 0xf4, 0xea, +0x6d, 0xf2, 0xe8, 0x5f, 0xf1, 0xe5, 0x51, 0xcf, +0xeb, 0xf6, 0xca, 0xea, 0xf5, 0xc6, 0xe8, 0xf4, +0xbe, 0xe4, 0xf2, 0xba, 0xe3, 0xf1, 0xb8, 0xac, +0x73, 0xf2, 0xe7, 0x5c, 0xf0, 0xe4, 0x4f, 0xf0, +0xe4, 0x4c, 0x2f, 0xc4, 0xf0, 0x26, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, 0x62, +0x4b, 0x47, 0x44, 0x02, 0x66, 0x0b, 0x7c, 0x64, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0xc0, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, +0x60, 0x60, 0x44, 0x00, 0x06, 0x10, 0x60, 0x64, +0x62, 0x66, 0x61, 0x65, 0x63, 0xe7, 0xe0, 0xe4, +0xe2, 0xe6, 0x01, 0x8b, 0x30, 0x32, 0xf3, 0xf2, +0xf1, 0xb3, 0x0b, 0x70, 0x0a, 0x0a, 0x09, 0x8b, +0x40, 0x04, 0x78, 0x45, 0xf9, 0xc5, 0x40, 0x7c, +0x71, 0x09, 0x49, 0x88, 0x80, 0xa8, 0x94, 0xb4, +0x8c, 0xac, 0x1c, 0x90, 0x2f, 0xaf, 0x00, 0x11, +0x50, 0x94, 0x16, 0x57, 0x92, 0x53, 0x06, 0xf1, +0x55, 0x20, 0x02, 0xaa, 0x32, 0x6a, 0xe2, 0x20, +0xbe, 0xba, 0x8a, 0x06, 0x44, 0x40, 0x53, 0x4b, +0x1b, 0xc8, 0xd7, 0x51, 0xd7, 0xd5, 0xd3, 0x37, +0x00, 0x0b, 0x68, 0x19, 0x1a, 0x19, 0x9b, 0xe8, +0x98, 0xea, 0x9a, 0xe9, 0x9b, 0xeb, 0x5b, 0x80, +0x04, 0x2c, 0x8d, 0xac, 0xac, 0x6d, 0x4c, 0x6d, +0xf5, 0xf5, 0xf5, 0xed, 0xec, 0x41, 0x22, 0x8c, +0x3c, 0x0e, 0x20, 0xa0, 0xef, 0xe8, 0xe4, 0xec, +0xe2, 0xea, 0x06, 0x14, 0x61, 0x74, 0xf7, 0xb0, +0xf1, 0xf4, 0xf2, 0xd6, 0xf7, 0xf1, 0xf5, 0xf3, +0x0f, 0x08, 0x0c, 0xd2, 0x67, 0x60, 0x0c, 0x86, +0xa8, 0x08, 0x09, 0x0d, 0x0b, 0x8f, 0x88, 0x04, +0xa9, 0x88, 0x8a, 0x8e, 0xf1, 0x8e, 0x8d, 0x8b, +0x07, 0x9a, 0x91, 0x90, 0x08, 0x31, 0x15, 0x06, +0xf4, 0x93, 0xc0, 0x7c, 0x24, 0xa0, 0x0f, 0x22, +0x00, 0x16, 0xa6, 0x1e, 0x2c, 0x4f, 0x9b, 0x2b, +0xa5, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, +0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *slsubscription_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_slsubscription_png = new wxImage(); + if (!img_slsubscription_png || !img_slsubscription_png->IsOk()) + { + wxMemoryInputStream img_slsubscription_pngIS(slsubscription_png_data, sizeof(slsubscription_png_data)); + img_slsubscription_png->LoadFile(img_slsubscription_pngIS, wxBITMAP_TYPE_PNG); + } + return img_slsubscription_png; +} +#define slsubscription_png_img slsubscription_png_img() + +static wxBitmap *slsubscription_png_bmp() +{ + static wxBitmap *bmp_slsubscription_png; + if (!bmp_slsubscription_png || !bmp_slsubscription_png->IsOk()) + bmp_slsubscription_png = new wxBitmap(*slsubscription_png_img); + return bmp_slsubscription_png; +} +#define slsubscription_png_bmp slsubscription_png_bmp() + +static wxIcon *slsubscription_png_ico() +{ + static wxIcon *ico_slsubscription_png; + if (!ico_slsubscription_png || !ico_slsubscription_png->IsOk()) + { + ico_slsubscription_png = new wxIcon(); + ico_slsubscription_png->CopyFromBitmap(*slsubscription_png_bmp); + } + return ico_slsubscription_png; +} +#define slsubscription_png_ico slsubscription_png_ico() + +#endif // SLSUBSCRIPTION_PNG_H diff --git a/include/images/slsubscription2.png b/include/images/slsubscription2.png new file mode 100644 index 0000000000000000000000000000000000000000..9b7837f5afdb7b9d6d09db57c60e4472e4d55966 GIT binary patch literal 639 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47?}cmLR^8|*|TSdhKBzC|Nrm5 z|G)qK`|;=B*WZ6X{`~Xy$Dfzqen0*C>*430cR&94_4nWRKmWe`{`>aF???BaT&%3Q zb?5Po_us$&`TODLpQ8*6XUeNDzy0>%$@7~vbuS)0eev!0L!h#o56`{+`uW%2tJSp^ zDr-)@{POD(`RBb)KX2TA ze7d~)%&V{apMKu`_|v1$KW~2carNEz3va%ic=6@%^UwRAe%k)%qg=q+%@01@eE+z=z_di^D`+e=b_vc@KJN4@8u@_(VJpqb;-1hL}rUxI^ z-+#a6?)z1D-ZghxzXOH>V@Z%-FoVOh8)+a;lDE4HvmlSpCm@Hjz$3C4NPB>>+sSM@ zAY-|wi(`ny<>Z8f6ek8ZHid+ww8Yfp=MSDddiF4tiF?C`kK6?uMVy@79ZoDij<6hY ztl{+3>}Z&=rDx3?n+fX|a0muWniw!Gobh9*B2(6;S3(N=+E%H#ICw|1pSXVY!e#RY zjtprj$=NSvy?Qx&rZbC9kIvdPzPUMX&%9M++QVn?fJ3mLXj@rfY4P_BFbnuQW4;(<<9Epd$~Nl7e8wMs5Z1yT$~28IT@ zhDN#uh9O1IsOk()) + { + wxMemoryInputStream img_slsubscription2_pngIS(slsubscription2_png_data, sizeof(slsubscription2_png_data)); + img_slsubscription2_png->LoadFile(img_slsubscription2_pngIS, wxBITMAP_TYPE_PNG); + } + return img_slsubscription2_png; +} +#define slsubscription2_png_img slsubscription2_png_img() + +static wxBitmap *slsubscription2_png_bmp() +{ + static wxBitmap *bmp_slsubscription2_png; + if (!bmp_slsubscription2_png || !bmp_slsubscription2_png->IsOk()) + bmp_slsubscription2_png = new wxBitmap(*slsubscription2_png_img); + return bmp_slsubscription2_png; +} +#define slsubscription2_png_bmp slsubscription2_png_bmp() + +static wxIcon *slsubscription2_png_ico() +{ + static wxIcon *ico_slsubscription2_png; + if (!ico_slsubscription2_png || !ico_slsubscription2_png->IsOk()) + { + ico_slsubscription2_png = new wxIcon(); + ico_slsubscription2_png->CopyFromBitmap(*slsubscription2_png_bmp); + } + return ico_slsubscription2_png; +} +#define slsubscription2_png_ico slsubscription2_png_ico() + +#endif // SLSUBSCRIPTION2_PNG_H diff --git a/include/images/slsubscriptions.png b/include/images/slsubscriptions.png new file mode 100644 index 0000000000000000000000000000000000000000..50f7e60dcdeb7cb8d7c4d0ecd245d9ea8502a1dc GIT binary patch literal 408 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}V1Q4EE0CT&dv<7O=>Px!|NQ&+ zD84zh8a#eGkKpUZA0jB|(0{3=Yq3q=7g|-tI2Uf;>K-fE>;O zkH}&m?E%JaC$sHi8ej+I9c9`=^lc4g(ucyu-ISK+9E2Tq8?MniLsT5skVWsm4U&$cY3Q(H00)|WTsU@G#FTdH2_tcSQ(f> VG@P0qx(29$!PC{xWt~$(69D!cpc()G literal 0 HcmV?d00001 diff --git a/include/images/slsubscriptions.pngc b/include/images/slsubscriptions.pngc new file mode 100644 index 0000000..09b21a4 --- /dev/null +++ b/include/images/slsubscriptions.pngc @@ -0,0 +1,95 @@ +#ifndef SLSUBSCRIPTIONS_PNG_H +#define SLSUBSCRIPTIONS_PNG_H + +static const unsigned char slsubscriptions_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x51, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x9b, 0x9b, 0x9b, 0x55, +0x55, 0x55, 0xff, 0xff, 0xff, 0xfc, 0xfe, 0xfe, +0xf8, 0xfc, 0xfe, 0xf3, 0xfa, 0xfd, 0xed, 0xf8, +0xfc, 0xe7, 0xf5, 0xfa, 0xe1, 0xf3, 0xf9, 0xda, +0xf0, 0xf8, 0x96, 0x99, 0x9a, 0x1e, 0x50, 0xad, +0xdb, 0x93, 0x96, 0xc8, 0x00, 0x00, 0xd3, 0xed, +0xf6, 0xd3, 0x90, 0x95, 0xcd, 0xeb, 0xf5, 0xd4, +0x5e, 0x60, 0xcf, 0x5c, 0x5f, 0xc6, 0xe8, 0xf4, +0xd4, 0x99, 0x9f, 0xc0, 0xe5, 0xf3, 0xba, 0xe3, +0xf1, 0xb4, 0xe1, 0xf0, 0xaf, 0xdf, 0xef, 0xab, +0xdd, 0xef, 0x8c, 0x00, 0xd8, 0x8d, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, 0x62, +0x4b, 0x47, 0x44, 0x03, 0x11, 0x0c, 0x4c, 0xf2, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x71, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x65, +0x8f, 0x49, 0x0e, 0x80, 0x20, 0x0c, 0x00, 0xb1, +0xca, 0x22, 0xb2, 0xb8, 0x23, 0xfe, 0xff, 0xa1, +0xd6, 0x56, 0x34, 0xc4, 0xb9, 0x75, 0x3a, 0x09, +0x54, 0x34, 0xf0, 0xd0, 0x08, 0x06, 0xda, 0x4e, +0x2a, 0x6d, 0x7a, 0x0b, 0x45, 0x74, 0x72, 0xa8, +0x22, 0x90, 0xaa, 0x8e, 0x40, 0xe9, 0x3a, 0x02, +0x6d, 0xea, 0x08, 0x8c, 0xe3, 0x48, 0x69, 0x1f, +0x6c, 0x44, 0x81, 0x96, 0xa2, 0xe0, 0xc3, 0x18, +0x27, 0x14, 0xd6, 0x71, 0x34, 0x87, 0x25, 0x4e, +0x2b, 0x0a, 0xb4, 0x14, 0xf5, 0x1b, 0xce, 0x3b, +0x88, 0xfb, 0xa7, 0x14, 0x11, 0x89, 0x5f, 0xa6, +0xe8, 0xde, 0xa7, 0x83, 0x04, 0x47, 0x44, 0x7e, +0x0f, 0xe0, 0x7d, 0x3e, 0x8b, 0xf8, 0xdd, 0xfc, +0x71, 0x01, 0xdc, 0x00, 0x06, 0x0c, 0x5f, 0x40, +0xf6, 0x9c, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, +0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *slsubscriptions_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_slsubscriptions_png = new wxImage(); + if (!img_slsubscriptions_png || !img_slsubscriptions_png->IsOk()) + { + wxMemoryInputStream img_slsubscriptions_pngIS(slsubscriptions_png_data, sizeof(slsubscriptions_png_data)); + img_slsubscriptions_png->LoadFile(img_slsubscriptions_pngIS, wxBITMAP_TYPE_PNG); + } + return img_slsubscriptions_png; +} +#define slsubscriptions_png_img slsubscriptions_png_img() + +static wxBitmap *slsubscriptions_png_bmp() +{ + static wxBitmap *bmp_slsubscriptions_png; + if (!bmp_slsubscriptions_png || !bmp_slsubscriptions_png->IsOk()) + bmp_slsubscriptions_png = new wxBitmap(*slsubscriptions_png_img); + return bmp_slsubscriptions_png; +} +#define slsubscriptions_png_bmp slsubscriptions_png_bmp() + +static wxIcon *slsubscriptions_png_ico() +{ + static wxIcon *ico_slsubscriptions_png; + if (!ico_slsubscriptions_png || !ico_slsubscriptions_png->IsOk()) + { + ico_slsubscriptions_png = new wxIcon(); + ico_slsubscriptions_png->CopyFromBitmap(*slsubscriptions_png_bmp); + } + return ico_slsubscriptions_png; +} +#define slsubscriptions_png_ico slsubscriptions_png_ico() + +#endif // SLSUBSCRIPTIONS_PNG_H diff --git a/include/images/sortfilter.png b/include/images/sortfilter.png new file mode 100644 index 0000000000000000000000000000000000000000..378d0292e005372a204ae9eea19a2294df915f8c GIT binary patch literal 510 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf_5hy{S0KH3$>Hj{?FGeK8k_gN zefRCdv;Qw{{d;ol_oFL6?_KzQ`|OwNCqG_3`tJO}SEu$oKfde9)ibZ&y!qPDy!Za~ zuUGc`JihwN{>ATi%z3$C>f;r?cNer?n_hEaLfNUA&1a78d2r|Q=TnJ zm%UiofA8YS*K4QV?khPtwf@xMUHA8_df1wMXw}TiN47n#N!q<_#f^ho9+X6F*|O~F zp7nRK1J|x!bZN)xn@OI_SI;~D>e=UKk3P(pc|dq($0DH98B2ovf*Bm1-ADs+I14-? zi-EKU7`vU!wgWQiJY5_^BrYc>II#ElobhProY>epwRdjw&MT4?N5L%Q7v(e zC`m~yNwrEYN(E93Mh1okx`sx&28JO<2397IsOk()) + { + wxMemoryInputStream img_sortfilter_pngIS(sortfilter_png_data, sizeof(sortfilter_png_data)); + img_sortfilter_png->LoadFile(img_sortfilter_pngIS, wxBITMAP_TYPE_PNG); + } + return img_sortfilter_png; +} +#define sortfilter_png_img sortfilter_png_img() + +static wxBitmap *sortfilter_png_bmp() +{ + static wxBitmap *bmp_sortfilter_png; + if (!bmp_sortfilter_png || !bmp_sortfilter_png->IsOk()) + bmp_sortfilter_png = new wxBitmap(*sortfilter_png_img); + return bmp_sortfilter_png; +} +#define sortfilter_png_bmp sortfilter_png_bmp() + +static wxIcon *sortfilter_png_ico() +{ + static wxIcon *ico_sortfilter_png; + if (!ico_sortfilter_png || !ico_sortfilter_png->IsOk()) + { + ico_sortfilter_png = new wxIcon(); + ico_sortfilter_png->CopyFromBitmap(*sortfilter_png_bmp); + } + return ico_sortfilter_png; +} +#define sortfilter_png_ico sortfilter_png_ico() + +#endif // SORTFILTER_PNG_H diff --git a/include/images/splash.png b/include/images/splash.png new file mode 100644 index 0000000000000000000000000000000000000000..63755e672066c24ae22f989e787950c3197fd9cc GIT binary patch literal 100644 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 mkR9Z|0WYNf9f13^sPqf*{|5A?8IIsOk()) + { + wxMemoryInputStream img_splash_pngIS(splash_png_data, sizeof(splash_png_data)); + img_splash_png->LoadFile(img_splash_pngIS, wxBITMAP_TYPE_PNG); + } + return img_splash_png; +} +#define splash_png_img splash_png_img() + +static wxBitmap *splash_png_bmp() +{ + static wxBitmap *bmp_splash_png; + if (!bmp_splash_png || !bmp_splash_png->IsOk()) + bmp_splash_png = new wxBitmap(*splash_png_img); + return bmp_splash_png; +} +#define splash_png_bmp splash_png_bmp() + +static wxIcon *splash_png_ico() +{ + static wxIcon *ico_splash_png; + if (!ico_splash_png || !ico_splash_png->IsOk()) + { + ico_splash_png = new wxIcon(); + ico_splash_png->CopyFromBitmap(*splash_png_bmp); + } + return ico_splash_png; +} +#define splash_png_ico splash_png_ico() + +#endif // SPLASH_PNG_H diff --git a/include/images/sql-16.png b/include/images/sql-16.png new file mode 100644 index 0000000000000000000000000000000000000000..01246deb34dd2e6108cc0d8cdc617a1b043592b3 GIT binary patch literal 1030 zcmV+h1o``kP)eSQC&C0;d%fQsq%=-HJ#l5Q5yKwc&UG~sk_10na+GF(FWAoT!)xUDaz^(W9 z_sz0+_sU%N#ar^kTid;B%e#NZyNJrZgww!p?$2NL&R)*9d-nGB#JHmO!dcw4X}Ytd z!otJJ$;!&f%F4>h%gW2h#JSYBZ}!Dn#JZo&t9AFjSk|&>ySlj0(9ql4+~wuw+}zyN z)z;S5*VEF|+S%FAuW;0~ZqB1|@U&L5uB64q#dC9Wf`Wp^#>Rkvfqi{_r>Cf_tgYYP z-^awh&!T3|qj1)oSEs3|(9qGQrl)jtb&rsc)z#I9hlsVcwe$4!&(6=gp?1xqbJw3% zq@<AzR#;pxF*GnSGEPJ_ z&#F@O&|l`rVb{TT;LL>N%zfv>VfMdR_peg+tWn6PfJjJ3Qc+NbX-Dj}R`$hP_0wkd z*?0BWX!Xxt_QP8DxmNX~P}I=MZf$M3xw*!>t?{l__0(bX-fZ>YdGy|B^w?td%w6}p zSMjS=$GoiI;o;ug+QzPj>bqd}$Xxc%WA@Hp_Qzc5x?skyhu+=V($C4?-rE(^>ec`N z00DGTPE!Ct=GbNc000SaNLh0L002k;002k;M#*bF00034NklKR_igC^#e(C=eDN5g8R7 z6B`$wkeHMV6i7);OV7y6%*xKm&dtjQX(=cSC@L<=%ql4@E3aT+sI024sjaJTXl!b3 zX>Ds~VCd-V>h9_7>z^=j(&Q;qr!g>0pD}Zm-t0MZ=gnWBw{X#728Ja|mo1;YV&$sU zYu2t?zX53GMh1pWo40J;wtdIWUAq}zpmO(~J$u1kWdH!YwM+>mmsHCD001R)MObuX zVRU6WV{&C-bY%cCFflMKF)}SMF;p@zIy5snG&L(QH99abp6)KH0000bbVXQnWMOn= zI&E)cX=ZrIsOk()) + { + wxMemoryInputStream img_sql_16_pngIS(sql_16_png_data, sizeof(sql_16_png_data)); + img_sql_16_png->LoadFile(img_sql_16_pngIS, wxBITMAP_TYPE_PNG); + } + return img_sql_16_png; +} +#define sql_16_png_img sql_16_png_img() + +static wxBitmap *sql_16_png_bmp() +{ + static wxBitmap *bmp_sql_16_png; + if (!bmp_sql_16_png || !bmp_sql_16_png->IsOk()) + bmp_sql_16_png = new wxBitmap(*sql_16_png_img); + return bmp_sql_16_png; +} +#define sql_16_png_bmp sql_16_png_bmp() + +static wxIcon *sql_16_png_ico() +{ + static wxIcon *ico_sql_16_png; + if (!ico_sql_16_png || !ico_sql_16_png->IsOk()) + { + ico_sql_16_png = new wxIcon(); + ico_sql_16_png->CopyFromBitmap(*sql_16_png_bmp); + } + return ico_sql_16_png; +} +#define sql_16_png_ico sql_16_png_ico() + +#endif // SQL_16_PNG_H diff --git a/include/images/sql-32.png b/include/images/sql-32.png new file mode 100644 index 0000000000000000000000000000000000000000..450e2c4917f784a5c3399505511d2c8ef42e1b74 GIT binary patch literal 1761 zcmV<71|Io|P)+|aab@XKHI&0Y1-Ui8#q^x0zc++)tV za=x>i;o;%>`~2wW=)kXv@5W&E$z1lvTUr+uYsV-RJ1&?CtH)&(QX;Q}Vf1v7C3l zzrdrTq(4AFLqkJTQc_%8TxVuxl9G~kb#>$8QNNj9@$vCHJ3F7BpqZJO z^78cW@bSEpYWJQ@u8d)MdVTfv^~=h}mzkQ4j*xkIdH47Dv!Z;)rFE`@T1!hyGc+`} zlyk$FSEQz>WMN)xY;44jVZo}1_o-0isZ*JgirbV<_OevCnPlUpP@t1}ub-2BVn9qo zIC^z%uA-B%eMCnXJ*UB zz~QG}^XO{y?}hd7mi6wC^Xz%zt6s~;zrd=D?Xy|-%Vze@X!g!yz^#qtG>#JsJp5qn$!0004WQchC!4)CrD+dIQkv>sw3ejK%F|ncU zaq$V^iAj#hDUm61{)t?^sfm7KhG7a85Cv(m=^1vJ_F36ExlAH?IXU@>1%)C-jzz^K zrCk+Q^NhUZ93AJDf+HlPykg!|AU~o$Z)(T%`3v&%YHb%Tte2F-Fgub1G&a(M<$@*)00!}6YMusy7xoe5VLX9 z<}KONwr-n}l_25^jLpmhImf0M+e6FC%Rur>3wG?>vSrJhU6s4{?A_<>n=G5sIGJs~ zTg8(8v;#nSqk}uPfWV={+S)otjvhOH;^ZmrxFGk~CFO19AwUJEH}9NtX3p7j>3o9c zFI>EIS&bhE_!MH>mQ*Y$mjfy|(>Z%~&Xubbv9a2`{MW8uzjj`LPs%;EqQbqc{{|>U z&92GIy?HBEK>?KRBqf1K5t!Dr6{LXjx9@=5SeU=S_U^qUv63K@K>$oj#-^3ue*pI6 z!)Zwj438eKsBq^Mc=Ghw^A}If3-D^ku1I_N3X-O~CxLU$>o=g3EA{r>dyoz8p>IBj zK{Ev`hkb1Q^jV4*Y`oN$PhXj^IsOk()) + { + wxMemoryInputStream img_sql_32_pngIS(sql_32_png_data, sizeof(sql_32_png_data)); + img_sql_32_png->LoadFile(img_sql_32_pngIS, wxBITMAP_TYPE_PNG); + } + return img_sql_32_png; +} +#define sql_32_png_img sql_32_png_img() + +static wxBitmap *sql_32_png_bmp() +{ + static wxBitmap *bmp_sql_32_png; + if (!bmp_sql_32_png || !bmp_sql_32_png->IsOk()) + bmp_sql_32_png = new wxBitmap(*sql_32_png_img); + return bmp_sql_32_png; +} +#define sql_32_png_bmp sql_32_png_bmp() + +static wxIcon *sql_32_png_ico() +{ + static wxIcon *ico_sql_32_png; + if (!ico_sql_32_png || !ico_sql_32_png->IsOk()) + { + ico_sql_32_png = new wxIcon(); + ico_sql_32_png->CopyFromBitmap(*sql_32_png_bmp); + } + return ico_sql_32_png; +} +#define sql_32_png_ico sql_32_png_ico() + +#endif // SQL_32_PNG_H diff --git a/include/images/sql.ico b/include/images/sql.ico new file mode 100644 index 0000000000000000000000000000000000000000..9c3cef93c6494282a2c8404abf5515c97f435b14 GIT binary patch literal 82726 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

    3X4>ULe*iUn71aEU35X4-5uV={ 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 T-1#~*>VUY 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 + { + wxMemoryInputStream img_sql_pngIS(sql_png_data, sizeof(sql_png_data)); + img_sql_png->LoadFile(img_sql_pngIS, wxBITMAP_TYPE_PNG); + } + return img_sql_png; +} +#define sql_png_img sql_png_img() + +static wxBitmap *sql_png_bmp() +{ + static wxBitmap *bmp_sql_png; + if (!bmp_sql_png || !bmp_sql_png->IsOk()) + bmp_sql_png = new wxBitmap(*sql_png_img); + return bmp_sql_png; +} +#define sql_png_bmp sql_png_bmp() + +static wxIcon *sql_png_ico() +{ + static wxIcon *ico_sql_png; + if (!ico_sql_png || !ico_sql_png->IsOk()) + { + ico_sql_png = new wxIcon(); + ico_sql_png->CopyFromBitmap(*sql_png_bmp); + } + return ico_sql_png; +} +#define sql_png_ico sql_png_ico() + +#endif // SQL_PNG_H diff --git a/include/images/statistics.png b/include/images/statistics.png new file mode 100644 index 0000000000000000000000000000000000000000..1e163b07c78b2198cd1459497e083d92058a2900 GIT binary patch literal 769 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47^?z&LR^8|l?QGW%{b&;z0s$3 zbIsy2Gxt7NcKXfIlW(T)x>vREw0F(s6W5=|bnTwD``+vm?>qOtY25y*e#?uNZ7-(m zdp&W>?dXo(({|mPbogDvj#t&2Usi5>UcT;G>FTFttDdxPem-H-E$`}0^&qJil^dQH zuXtRr^ikoGN4;B~Rm?lpvFCNw<`?B_pOvhlMsXE0|}MKhHaFZfgGAg3fg_mY#TBxA{fMswahuCoeddbnVsj zL-)$}-K^Piv24@%nz{RvqB^UZx4tM?a$}bAUqz$4nC;v z+~Bd{_{NI4rzUK;HFNuumQ~Gj_a_(4YM!^L{RuGi8B2ovf*Bm1-ADs+I14-?i-EKU z7`vU!wgWQudAc};NL)@%IKU+_bH>b>5`r~iVP<7~etLNt)7z)_$2$agM7V_Xuq)~7 zDQc?fDr>8+U%+wg{HgUz)+i~jUbSr9LQbRhPG9e6SNCxL`v)$Zn8B%WASWp+EiW-M zH8(js{XCCQL4iqmQCVSW@%Im3KCxv!{8D)7^ViS(96VfnoUD>kVse6#qO!u$;`1lW zVA<4WZK-OiYpZOmZLKc;Xw#lQO@|gensjN-rlJ+WqS{)kS7i$opANJMpWSlzF~cb% zrS#RJ3pN6MqFUk_QIe8al4_M)lnSI6j0_A7bPbJk4Gcq!46ICytxQa{4NR>J4CcMl rTZN(_H$NpatrDWaz!IzhsM^HJzzm|{)b!9bKn)C@u6{1-oD!MIsOk()) + { + wxMemoryInputStream img_statistics_pngIS(statistics_png_data, sizeof(statistics_png_data)); + img_statistics_png->LoadFile(img_statistics_pngIS, wxBITMAP_TYPE_PNG); + } + return img_statistics_png; +} +#define statistics_png_img statistics_png_img() + +static wxBitmap *statistics_png_bmp() +{ + static wxBitmap *bmp_statistics_png; + if (!bmp_statistics_png || !bmp_statistics_png->IsOk()) + bmp_statistics_png = new wxBitmap(*statistics_png_img); + return bmp_statistics_png; +} +#define statistics_png_bmp statistics_png_bmp() + +static wxIcon *statistics_png_ico() +{ + static wxIcon *ico_statistics_png; + if (!ico_statistics_png || !ico_statistics_png->IsOk()) + { + ico_statistics_png = new wxIcon(); + ico_statistics_png->CopyFromBitmap(*statistics_png_bmp); + } + return ico_statistics_png; +} +#define statistics_png_ico statistics_png_ico() + +#endif // STATISTICS_PNG_H diff --git a/include/images/step.png b/include/images/step.png new file mode 100644 index 0000000000000000000000000000000000000000..72f898a1193a78f46b71d33121d5fcd0d4b54819 GIT binary patch literal 430 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}W`IwKE0C_MZ}|WJ|KETAfByaV z?f2hLzy7@a@#p2Y-%q~$y7%d)T)^6!AAVeZ`|VRx)4QswmwEY*6B6$R23~b^JZETl zLP_b6h{#?Jj&rZSo_zUbCj-Ob=b!gI{j}@x$E^=PZoL0t-M#m#?!H@b=Uw4b*BYQ@ zj3q&S!3+-1Zlr-YN#5=*OljOTDL@Wqfk$L9koEv$x0Bg+Kt{f&i(`ny<=B3Ap#}vW z21ZfuBlo0V{g+?q@MuN#oz|2?5|8y~G;%-u*~qilLXpufB1q&)aH?zCiSA9SW^a4l z``}9ZME@|4jypY)tY0e&AN{nydqelib>8c03-0jrHto6>s3CE;o0;|NW0#Nnznx~C z)WKY+XtipIYeY#(Vo9o1a#1RfVlXl=G|)9P(lsy)F*2|+F}5->)iyA-GBB9; tPHz>8hTQy=%(O~~1_Mj52B2yaD+4o#hEvl+*8nvzc)I$ztaD0e0sufbvq}H} literal 0 HcmV?d00001 diff --git a/include/images/step.pngc b/include/images/step.pngc new file mode 100644 index 0000000..3b580c1 --- /dev/null +++ b/include/images/step.pngc @@ -0,0 +1,98 @@ +#ifndef STEP_PNG_H +#define STEP_PNG_H + +static const unsigned char step_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x69, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x7e, 0x7f, 0x80, 0xff, +0xff, 0xff, 0xfd, 0xfe, 0xff, 0xf9, 0xfd, 0xfe, +0xf6, 0xfb, 0xfd, 0xf2, 0xfa, 0xfc, 0xed, 0xf8, +0xfc, 0xe9, 0xf6, 0xfb, 0xe4, 0xf4, 0xfa, 0xde, +0xf2, 0xf9, 0x1e, 0x50, 0xad, 0xd9, 0xf0, 0xf8, +0xd3, 0xed, 0xf6, 0xf2, 0x82, 0x82, 0xee, 0x7a, +0x7a, 0xe9, 0x6e, 0x6f, 0xe3, 0x60, 0x61, 0xdd, +0x51, 0x51, 0xd5, 0x41, 0x41, 0xce, 0x31, 0x31, +0xc8, 0x22, 0x22, 0xc2, 0x14, 0x14, 0xbd, 0x08, +0x08, 0xce, 0xeb, 0xf5, 0xc9, 0xe9, 0xf4, 0xb9, +0x00, 0x00, 0xc3, 0xe7, 0xf3, 0xbe, 0xe5, 0xf2, +0xba, 0xe3, 0xf1, 0xb5, 0xe1, 0xf1, 0xb1, 0xdf, +0xf0, 0xae, 0xde, 0xef, 0xaa, 0xdd, 0xee, 0xa8, +0xdc, 0xee, 0x71, 0xe5, 0x45, 0x7c, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, 0x62, +0x4b, 0x47, 0x44, 0x02, 0x66, 0x0b, 0x7c, 0x64, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x6f, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x5d, +0x8f, 0x47, 0x12, 0x80, 0x20, 0x0c, 0x00, 0x01, +0x15, 0x4b, 0xc4, 0xde, 0x1b, 0xea, 0xff, 0x1f, +0xa9, 0x40, 0xe2, 0xa8, 0x7b, 0xdc, 0x85, 0x64, +0xc2, 0x18, 0xe3, 0x2f, 0x98, 0x81, 0x0b, 0xe1, +0xf9, 0x81, 0x0c, 0xa3, 0x38, 0x21, 0x01, 0x3e, +0x58, 0x52, 0x14, 0xd4, 0x53, 0x65, 0x45, 0x66, +0xc8, 0x8b, 0xb2, 0xaa, 0x9b, 0xb6, 0xeb, 0x8d, +0xe0, 0xd4, 0x87, 0x91, 0x4f, 0x56, 0x48, 0x88, +0xdc, 0x8c, 0x19, 0x05, 0xf5, 0x79, 0x71, 0xe2, +0xf9, 0x3f, 0xdd, 0xd8, 0x2d, 0xd4, 0xd7, 0x0d, +0xd7, 0x26, 0xa0, 0xdc, 0x0c, 0x8d, 0x82, 0xba, +0xde, 0x51, 0x28, 0x18, 0xdd, 0x8b, 0x03, 0x05, +0xf5, 0xe3, 0x44, 0xf1, 0xbf, 0xf6, 0xcb, 0x05, +0x92, 0x88, 0x09, 0x33, 0x39, 0x74, 0x34, 0xc3, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, +0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *step_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_step_png = new wxImage(); + if (!img_step_png || !img_step_png->IsOk()) + { + wxMemoryInputStream img_step_pngIS(step_png_data, sizeof(step_png_data)); + img_step_png->LoadFile(img_step_pngIS, wxBITMAP_TYPE_PNG); + } + return img_step_png; +} +#define step_png_img step_png_img() + +static wxBitmap *step_png_bmp() +{ + static wxBitmap *bmp_step_png; + if (!bmp_step_png || !bmp_step_png->IsOk()) + bmp_step_png = new wxBitmap(*step_png_img); + return bmp_step_png; +} +#define step_png_bmp step_png_bmp() + +static wxIcon *step_png_ico() +{ + static wxIcon *ico_step_png; + if (!ico_step_png || !ico_step_png->IsOk()) + { + ico_step_png = new wxIcon(); + ico_step_png->CopyFromBitmap(*step_png_bmp); + } + return ico_step_png; +} +#define step_png_ico step_png_ico() + +#endif // STEP_PNG_H diff --git a/include/images/stepInto.png b/include/images/stepInto.png new file mode 100644 index 0000000000000000000000000000000000000000..49d729b1ce5411439c933bc78397e23b5c3e23f5 GIT binary patch literal 253 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9oB=)|u0WcB;Xe?^roA@=Qj8@* ze!&b5&u*jvIh+L^k;OpT1B~5HX4?T7+MX_sAsp9}6BrmT1}G>pBykq3jbco-Y=~e~ zxGA8}&3GhG9Lq{LSr|3ujEr8loOI#yLQW8s2t&)pUffR$0fuVt}p^>hE zVTh4|m5H&HiK(`Msg;4jymxx5P&DM`r(~v8LNpjyf;9kDn^+l`K{TA29=Zmofx*+& K&t;ucLK6V7gg>MJ literal 0 HcmV?d00001 diff --git a/include/images/stepInto.pngc b/include/images/stepInto.pngc new file mode 100644 index 0000000..43f04fa --- /dev/null +++ b/include/images/stepInto.pngc @@ -0,0 +1,76 @@ +#ifndef STEPINTO_PNG_H +#define STEPINTO_PNG_H + +static const unsigned char stepInto_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x02, 0x03, 0x00, 0x00, 0x00, 0x62, 0x9d, 0x17, +0xf2, 0x00, 0x00, 0x00, 0x09, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, +0x00, 0x00, 0x5d, 0x66, 0xef, 0x31, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x2b, 0x49, 0x44, 0x41, 0x54, +0x08, 0xd7, 0x63, 0x60, 0x00, 0x01, 0xd1, 0x50, +0x20, 0x21, 0x00, 0x62, 0x09, 0x70, 0xad, 0x5a, +0x01, 0x65, 0x39, 0x80, 0x58, 0x01, 0x20, 0xd9, +0x10, 0x20, 0x8b, 0x01, 0xc4, 0x62, 0x00, 0x89, +0x41, 0x00, 0x17, 0x9c, 0x85, 0x02, 0x00, 0x88, +0x8e, 0x08, 0xf2, 0x5b, 0xe2, 0xff, 0x38, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *stepInto_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_stepInto_png = new wxImage(); + if (!img_stepInto_png || !img_stepInto_png->IsOk()) + { + wxMemoryInputStream img_stepInto_pngIS(stepInto_png_data, sizeof(stepInto_png_data)); + img_stepInto_png->LoadFile(img_stepInto_pngIS, wxBITMAP_TYPE_PNG); + } + return img_stepInto_png; +} +#define stepInto_png_img stepInto_png_img() + +static wxBitmap *stepInto_png_bmp() +{ + static wxBitmap *bmp_stepInto_png; + if (!bmp_stepInto_png || !bmp_stepInto_png->IsOk()) + bmp_stepInto_png = new wxBitmap(*stepInto_png_img); + return bmp_stepInto_png; +} +#define stepInto_png_bmp stepInto_png_bmp() + +static wxIcon *stepInto_png_ico() +{ + static wxIcon *ico_stepInto_png; + if (!ico_stepInto_png || !ico_stepInto_png->IsOk()) + { + ico_stepInto_png = new wxIcon(); + ico_stepInto_png->CopyFromBitmap(*stepInto_png_bmp); + } + return ico_stepInto_png; +} +#define stepInto_png_ico stepInto_png_ico() + +#endif // STEPINTO_PNG_H diff --git a/include/images/stepOver.png b/include/images/stepOver.png new file mode 100644 index 0000000000000000000000000000000000000000..1b1d702751e9444a5cebd97306d1712a465472bd GIT binary patch literal 249 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9oB=)|u0WcB;Xe?^roA@=Qj8@* ze!&b5&u*jvIh+L^k;OpT1B~5HX4?T7>Ygr+Asp9}6BrmT1}G>pBykq3jdJXG%8IsOk()) + { + wxMemoryInputStream img_stepOver_pngIS(stepOver_png_data, sizeof(stepOver_png_data)); + img_stepOver_png->LoadFile(img_stepOver_pngIS, wxBITMAP_TYPE_PNG); + } + return img_stepOver_png; +} +#define stepOver_png_img stepOver_png_img() + +static wxBitmap *stepOver_png_bmp() +{ + static wxBitmap *bmp_stepOver_png; + if (!bmp_stepOver_png || !bmp_stepOver_png->IsOk()) + bmp_stepOver_png = new wxBitmap(*stepOver_png_img); + return bmp_stepOver_png; +} +#define stepOver_png_bmp stepOver_png_bmp() + +static wxIcon *stepOver_png_ico() +{ + static wxIcon *ico_stepOver_png; + if (!ico_stepOver_png || !ico_stepOver_png->IsOk()) + { + ico_stepOver_png = new wxIcon(); + ico_stepOver_png->CopyFromBitmap(*stepOver_png_bmp); + } + return ico_stepOver_png; +} +#define stepOver_png_ico stepOver_png_ico() + +#endif // STEPOVER_PNG_H diff --git a/include/images/steps.png b/include/images/steps.png new file mode 100644 index 0000000000000000000000000000000000000000..51b86a7a01c83b5cea77ec95b5462d09b6440283 GIT binary patch literal 505 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMfC#V4O&{wU-q+N; ztEhNWQt~Rl;6+yU)6~?*@d*#2qV9!+-1ham;qHFb(eeNP|9}7e|M~adx8Hw1{rdCv z$Dfzqen0v0>)xlIH$VKiY;7$Uu=euXZx>8W&%OS7R!{%5hUUqaUk*S2d_q}y-_uXW zWMy|f{&-kI;-Ikb)`uTA-v6+lk8j<*_j|dxR^5HKhmCC)GjsEe!0$k3F_r}R1v5B2 zyO9RsBze2L2u$6?s{`b47I;J!18EO1b~~AE2V_j}ba4!kxSV=ESJ){)gyq3*#TKtg zJL0sKIQ{y+f8E?ObFHt|)s%fZBcu31RPo3mgSAWF?$AEZe@(inF?UDzw~vaJ%T92p zIZ2-MFA`zlUUl9(gk|sfu2(J_7XJFoYI@L7XYxW6W6jozy1^3_m=|Vt(#|*0o|rr;u=wsl30>zm0Xkx zq!^403=MP*jdTqRLyQcpOpL8eOtlS6tqct2z0+HTq9HdwB{QuOqQSrttO2On#LB=7 VqT$r^&^15}44$rjF6*2UngF{3+gktt literal 0 HcmV?d00001 diff --git a/include/images/steps.pngc b/include/images/steps.pngc new file mode 100644 index 0000000..69b25b9 --- /dev/null +++ b/include/images/steps.pngc @@ -0,0 +1,108 @@ +#ifndef STEPS_PNG_H +#define STEPS_PNG_H + +static const unsigned char steps_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x93, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xa5, 0xa5, 0xa5, 0xf2, +0x82, 0x82, 0xf1, 0x7f, 0x80, 0xef, 0x7c, 0x7c, +0xee, 0x78, 0x78, 0xec, 0x74, 0x74, 0xea, 0x6f, +0x70, 0xe8, 0x6a, 0x6b, 0xe5, 0x65, 0x65, 0xe3, +0x5f, 0x60, 0xe0, 0x5a, 0x5a, 0xde, 0x54, 0x54, +0xdb, 0x4d, 0x4e, 0xd8, 0x47, 0x47, 0xd5, 0x41, +0x41, 0xff, 0xff, 0xff, 0xfd, 0xfe, 0xff, 0xf9, +0xfd, 0xfe, 0xf6, 0xfb, 0xfd, 0xf2, 0xfa, 0xfc, +0xed, 0xf8, 0xfc, 0xe9, 0xf6, 0xfb, 0xe4, 0xf4, +0xfa, 0xde, 0xf2, 0xf9, 0xd9, 0xf0, 0xf8, 0xd3, +0x3b, 0x3b, 0x1e, 0x50, 0xad, 0xd3, 0xed, 0xf6, +0xd0, 0x35, 0x35, 0xce, 0xeb, 0xf5, 0xcd, 0x2e, +0x2f, 0xcb, 0x28, 0x29, 0xc9, 0xe9, 0xf4, 0xc3, +0xe7, 0xf3, 0xc8, 0x23, 0x23, 0xbe, 0xe5, 0xf2, +0xc6, 0x1d, 0x1d, 0xba, 0xe3, 0xf1, 0xc3, 0x18, +0x18, 0xc1, 0x13, 0x13, 0xb5, 0xe1, 0xf1, 0xb1, +0xdf, 0xf0, 0xbf, 0x0e, 0x0e, 0xae, 0xde, 0xef, +0xbd, 0x0a, 0x0a, 0xaa, 0xdd, 0xee, 0xbc, 0x06, +0x06, 0xba, 0x03, 0x03, 0x83, 0xd8, 0x51, 0xf7, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x01, 0x62, 0x4b, 0x47, 0x44, 0x10, 0x95, 0xb2, +0x0d, 0x2c, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0x90, 0x49, 0x44, 0x41, 0x54, 0x18, +0xd3, 0x65, 0xcf, 0x6d, 0x13, 0x42, 0x50, 0x14, +0x04, 0xe0, 0xbb, 0x21, 0x84, 0x4a, 0x92, 0xb8, +0x5e, 0x2a, 0xa4, 0x42, 0xfa, 0xff, 0xbf, 0xae, +0x9d, 0xcc, 0x9d, 0x3b, 0xd5, 0x7e, 0x7c, 0x76, +0xf6, 0xcc, 0x1c, 0x21, 0xf0, 0x15, 0x21, 0xc4, +0xc2, 0x30, 0xad, 0xa5, 0xed, 0xb8, 0x2b, 0xcf, +0x0f, 0xd6, 0x1b, 0x82, 0x81, 0x6d, 0xb8, 0x8b, +0xf6, 0xf1, 0x21, 0x39, 0xa6, 0xc8, 0x08, 0x26, +0x42, 0x19, 0xc9, 0x4f, 0x72, 0x14, 0x04, 0x0b, +0xaa, 0xcf, 0x4b, 0x54, 0x04, 0xbd, 0xcf, 0x8a, +0xea, 0x44, 0xb0, 0xa1, 0xfa, 0xf3, 0x05, 0x35, +0xc1, 0x41, 0x2c, 0x93, 0xf9, 0x46, 0x83, 0x96, +0xe0, 0x42, 0xf5, 0xcd, 0x15, 0x1d, 0x41, 0xef, +0xeb, 0xb6, 0xbb, 0x11, 0x3c, 0xa8, 0xfe, 0xfe, +0x40, 0x4f, 0xf0, 0x91, 0xca, 0x72, 0xbe, 0x31, +0x60, 0x24, 0x04, 0x50, 0xfd, 0xf0, 0xc4, 0x44, +0xd0, 0xfb, 0x7e, 0x9c, 0x5e, 0x84, 0xbf, 0x6f, +0x7f, 0xf2, 0x06, 0xf7, 0xe9, 0x10, 0x17, 0x85, +0xb3, 0x98, 0x76, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *steps_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_steps_png = new wxImage(); + if (!img_steps_png || !img_steps_png->IsOk()) + { + wxMemoryInputStream img_steps_pngIS(steps_png_data, sizeof(steps_png_data)); + img_steps_png->LoadFile(img_steps_pngIS, wxBITMAP_TYPE_PNG); + } + return img_steps_png; +} +#define steps_png_img steps_png_img() + +static wxBitmap *steps_png_bmp() +{ + static wxBitmap *bmp_steps_png; + if (!bmp_steps_png || !bmp_steps_png->IsOk()) + bmp_steps_png = new wxBitmap(*steps_png_img); + return bmp_steps_png; +} +#define steps_png_bmp steps_png_bmp() + +static wxIcon *steps_png_ico() +{ + static wxIcon *ico_steps_png; + if (!ico_steps_png || !ico_steps_png->IsOk()) + { + ico_steps_png = new wxIcon(); + ico_steps_png->CopyFromBitmap(*steps_png_bmp); + } + return ico_steps_png; +} +#define steps_png_ico steps_png_ico() + +#endif // STEPS_PNG_H diff --git a/include/images/stop.png b/include/images/stop.png new file mode 100644 index 0000000000000000000000000000000000000000..bea28d9e09b4ec9356d3042ef082920e6976b490 GIT binary patch literal 498 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf;Q*fyS0H_?H-3Mdz{?BE9v^6X zvcLJ+zPcBCs$T9YeY3OR(~17a2U_o}jJUTv=)qE-$BW&bEwFz%&-~+-l&AX}A1?KN zyvX(00=t)U&ECw`|GX*o+1}cROTC^fa(TYM=G9!&x3ly<%uxHfA^hd;@+XU&pU<~` zHP__rEZq;&RX{6g&CbH-^Q~UZF@8Hs`@?jV&r@W-O%nUP#^>F(?ALRQ-p$nd zI8FJ>6q#?6M1S`4|5@e!<#_j}&GBD1M1Ef%@^h{K@6}%a_7=|Jx)ura24hK(UoeBi zvm0qZ4rhT!WHFHT0Ash4*>*rinx~6nh{WaO1O;vbBS%K%kcQ5gty6pFHc#&6R6B6? z@ag0F3K}fp0?$MRMTMtNXyNwoJbmKSNo|cotW&0hhFra3YVwdN>Xy~6s$Xnv1&qqc z!okMH+}=AHrf%(BJ9qC=W?{Ydi5v{Cc5|$VUfG!mv{ALhHKHUXu_VQ?^ RYk(RUJYD@<);T3K0RRmF(Ww9c literal 0 HcmV?d00001 diff --git a/include/images/stop.pngc b/include/images/stop.pngc new file mode 100644 index 0000000..b6e7927 --- /dev/null +++ b/include/images/stop.pngc @@ -0,0 +1,107 @@ +#ifndef STOP_PNG_H +#define STOP_PNG_H + +static const unsigned char stop_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xc3, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc6, 0x8d, 0x5f, 0xbf, +0x5e, 0x10, 0xe9, 0xd0, 0xa6, 0xe3, 0xc0, 0x86, +0xe4, 0xbf, 0x83, 0xe6, 0xbe, 0x7e, 0xe8, 0xbc, +0x7a, 0xe9, 0xba, 0x75, 0xec, 0xb9, 0x70, 0xf2, +0xc8, 0x8f, 0xe3, 0xc0, 0x85, 0xdc, 0xa9, 0x58, +0xde, 0xa7, 0x52, 0xe0, 0xa5, 0x4c, 0xe3, 0xa3, +0x46, 0xe6, 0xa0, 0x3f, 0xe9, 0x9e, 0x37, 0xf1, +0xb4, 0x64, 0xe5, 0xbf, 0x81, 0xe1, 0xa5, 0x4b, +0xe3, 0xa2, 0x45, 0xe6, 0xa0, 0x3e, 0xe9, 0x9d, +0x36, 0xec, 0x9b, 0x2f, 0xf3, 0xb2, 0x5d, 0xe6, +0xbd, 0x7d, 0xe1, 0xa5, 0x4a, 0xe4, 0xa2, 0x44, +0xe7, 0xa0, 0x3c, 0xea, 0x9d, 0x35, 0xed, 0x9a, +0x2e, 0xf0, 0x98, 0x26, 0xf5, 0xb0, 0x57, 0xe9, +0xbb, 0x77, 0xe4, 0xa2, 0x43, 0xe7, 0x9f, 0x3b, +0xea, 0x9d, 0x34, 0xed, 0x9a, 0x2d, 0xf0, 0x97, +0x25, 0xf3, 0x95, 0x1e, 0xf8, 0xad, 0x51, 0xec, +0xb9, 0x71, 0xe7, 0x9f, 0x3a, 0xea, 0x9c, 0x33, +0xed, 0x9a, 0x2b, 0xf0, 0x97, 0x24, 0xf3, 0x94, +0x1d, 0xf6, 0x92, 0x16, 0xfb, 0xac, 0x4c, 0xee, +0xb6, 0x6b, 0xeb, 0x9c, 0x32, 0xee, 0x99, 0x2a, +0xf1, 0x96, 0x23, 0xf4, 0x94, 0x1c, 0xf6, 0x92, +0x15, 0xf9, 0x8f, 0x0f, 0xfc, 0xaa, 0x47, 0xf4, +0xc7, 0x8b, 0xf2, 0xb3, 0x5f, 0xf5, 0xb0, 0x59, +0xf7, 0xaf, 0x54, 0xf9, 0xad, 0x4f, 0xfb, 0xab, +0x4a, 0xfe, 0xbd, 0x71, 0x9c, 0x0a, 0xd6, 0x59, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x66, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0x20, 0x0b, +0x30, 0x32, 0x41, 0x01, 0x23, 0x54, 0x80, 0x89, +0x99, 0x85, 0x95, 0x8d, 0x9d, 0x83, 0x93, 0x8b, +0x09, 0x26, 0xc0, 0xcd, 0xc3, 0xcb, 0xc7, 0x2f, +0x20, 0x28, 0x04, 0x17, 0x10, 0xe6, 0x15, 0x11, +0x15, 0x13, 0x97, 0x90, 0x84, 0x0b, 0x48, 0x49, +0xcb, 0xc8, 0xca, 0xc9, 0x2b, 0x28, 0xc2, 0x05, +0x94, 0x94, 0x55, 0x54, 0xd5, 0xd4, 0x35, 0x34, +0xe1, 0x02, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, +0x06, 0x86, 0x70, 0x01, 0x23, 0x63, 0x13, 0x53, +0x33, 0x73, 0x0b, 0x4b, 0xb8, 0x80, 0x95, 0xb5, +0x8d, 0xad, 0x9d, 0xbd, 0xa5, 0x03, 0x13, 0x2e, +0x87, 0x91, 0x08, 0x00, 0xea, 0xbb, 0x08, 0xa8, +0x5b, 0xa9, 0x89, 0x69, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *stop_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_stop_png = new wxImage(); + if (!img_stop_png || !img_stop_png->IsOk()) + { + wxMemoryInputStream img_stop_pngIS(stop_png_data, sizeof(stop_png_data)); + img_stop_png->LoadFile(img_stop_pngIS, wxBITMAP_TYPE_PNG); + } + return img_stop_png; +} +#define stop_png_img stop_png_img() + +static wxBitmap *stop_png_bmp() +{ + static wxBitmap *bmp_stop_png; + if (!bmp_stop_png || !bmp_stop_png->IsOk()) + bmp_stop_png = new wxBitmap(*stop_png_img); + return bmp_stop_png; +} +#define stop_png_bmp stop_png_bmp() + +static wxIcon *stop_png_ico() +{ + static wxIcon *ico_stop_png; + if (!ico_stop_png || !ico_stop_png->IsOk()) + { + ico_stop_png = new wxIcon(); + ico_stop_png->CopyFromBitmap(*stop_png_bmp); + } + return ico_stop_png; +} +#define stop_png_ico stop_png_ico() + +#endif // STOP_PNG_H diff --git a/include/images/storedata.png b/include/images/storedata.png new file mode 100644 index 0000000000000000000000000000000000000000..52da50590d7af8762a7765442977eec0f855593d GIT binary patch literal 636 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl482JKxLR^8|f=Nep()P~2@bJ^m zKQF)jdiLel?ewd!M_zp0 z^YqJ>$6wYy{CxD)_qr_)s`uU4|KeNy<_Fb#Z$AI_`_j7~CtiO)^6LA6m*4lk_;&5% zulfy-YWCc+Za897b)sSYDNQ2-Uyv? zt6|-f+MRcT=3NS&eI;bZ^^j>dLZ{vgoqQ{7((Q(|Piwc|wW&E~TX`~U!kxy|&z^k# zdFSJgr(b`EO}HE0f46bfvndCk#4Wh-{L8OxPre*~{XM+zUU=`l#+A>f?0fd=+wUvy zf1G~v{qU>rH$MJqT=l$Z<@1Gm-?G{Et z!DHEv61CZ<#k-aoIkv7(%i3AB_-0l)$F8e#x?gTLD>6 z@4hY2W0&!Nep+<RdP`(kYX@0Ff`CL zG}1LN3^6jWGBLI?G1WFOwK6c6_fBsWiiX_$l+3hBhz0{oum+%N6DtEVh=xIsOk()) + { + wxMemoryInputStream img_storedata_pngIS(storedata_png_data, sizeof(storedata_png_data)); + img_storedata_png->LoadFile(img_storedata_pngIS, wxBITMAP_TYPE_PNG); + } + return img_storedata_png; +} +#define storedata_png_img storedata_png_img() + +static wxBitmap *storedata_png_bmp() +{ + static wxBitmap *bmp_storedata_png; + if (!bmp_storedata_png || !bmp_storedata_png->IsOk()) + bmp_storedata_png = new wxBitmap(*storedata_png_img); + return bmp_storedata_png; +} +#define storedata_png_bmp storedata_png_bmp() + +static wxIcon *storedata_png_ico() +{ + static wxIcon *ico_storedata_png; + if (!ico_storedata_png || !ico_storedata_png->IsOk()) + { + ico_storedata_png = new wxIcon(); + ico_storedata_png->CopyFromBitmap(*storedata_png_bmp); + } + return ico_storedata_png; +} +#define storedata_png_ico storedata_png_ico() + +#endif // STOREDATA_PNG_H diff --git a/include/images/synonym.png b/include/images/synonym.png new file mode 100644 index 0000000000000000000000000000000000000000..aa2777c25eba40eb46f415143f1f0edfda67d26f GIT binary patch literal 478 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMfiU6MwS0Fw2(7DLzt55v;fAGh@ z9bf;h{rG3$+h3Dk{%n2nebTmF$AA6L+xXP9{<8nFhiNxIAN%!x-}ir~pMN{@=*zC# zAJ<=gx8&68&?_H3&VM-i^MBWtotr=ZNm={YanXIZ^Y5)rzcV=gcK5fx8$bV9`u_L+ z`=7U7|FH7>n|a4xPCf9<;?z66<8Rh~`cuAc+q73d!&g2sn|Dw5*qieEUo&ofj=J{A z=iv+qq$zSTbV<_z;vHlSM>OM?7@862M7NCR>>3p^r=fwTu0yPeFo12S?wT^vIs zE+;1_$Ql?OWK@o5=#=D$h`4#f(n3+m=S<8Un>`8#j`NEpCW#3=5fu^>6n!i@ouSjf z)64U8L+FW9C$$Y2Sw*H!sSFLddd0NDbn5}FEu|%24`_YiRY+s#H8(LbGc+}BztQxN zPm6)!=qmO^>H0Sy7pRuFMwFx^mZVxG7o`Fz1|tJQ16@NST?4}qBLgcFV=EI=Z39y) w1A}?*^j4v0$jwj5Osj-wFt7w`0ID{zGBAT^I5jmdKI;Vst0D#`qfB*mh literal 0 HcmV?d00001 diff --git a/include/images/synonym.pngc b/include/images/synonym.pngc new file mode 100644 index 0000000..12242fb --- /dev/null +++ b/include/images/synonym.pngc @@ -0,0 +1,104 @@ +#ifndef SYNONYM_PNG_H +#define SYNONYM_PNG_H + +static const unsigned char synonym_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xa8, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x9d, 0xc2, 0xce, 0x59, +0x97, 0xab, 0xc8, 0xfa, 0xff, 0xc1, 0xf8, 0xfe, +0xb8, 0xf5, 0xfd, 0xad, 0xf1, 0xfc, 0xa1, 0xed, +0xfa, 0x93, 0xe9, 0xf9, 0x85, 0xe4, 0xf7, 0x92, +0xb6, 0xba, 0xc7, 0xfa, 0xff, 0x6e, 0xb1, 0xe5, +0x35, 0x7f, 0xd3, 0x4f, 0xa6, 0xe1, 0x66, 0xd9, +0xf3, 0xc6, 0xfa, 0xff, 0xbe, 0xf7, 0xfe, 0xcb, +0xe7, 0xf6, 0xc4, 0xe2, 0xf4, 0xba, 0xdb, 0xf1, +0xaf, 0xd3, 0xee, 0xa4, 0xca, 0xeb, 0x55, 0xd4, +0xf1, 0x48, 0xcf, 0xf0, 0xc5, 0xf9, 0xff, 0x8a, +0xb4, 0xb9, 0xb3, 0xf3, 0xfc, 0x64, 0xad, 0xe3, +0x41, 0xa2, 0xdf, 0x46, 0xcf, 0xef, 0x3a, 0xcb, +0xee, 0x30, 0xc7, 0xed, 0xbb, 0xf6, 0xfd, 0xb1, +0xf3, 0xfc, 0xa5, 0xef, 0xfb, 0xbf, 0xdf, 0xf3, +0xb5, 0xd7, 0xf0, 0xa9, 0xcf, 0xec, 0x9e, 0xc6, +0xe9, 0x95, 0xc0, 0xe6, 0x38, 0xca, 0xee, 0x2e, +0xc7, 0xec, 0xaf, 0xf2, 0xfc, 0x77, 0xae, 0xb6, +0x96, 0xea, 0xf9, 0x57, 0xa9, 0xe2, 0x36, 0x9e, +0xde, 0x2d, 0xc6, 0xec, 0x77, 0xdf, 0xf5, 0x68, +0xda, 0xf3, 0x5a, 0xd6, 0xf2, 0x4c, 0xd1, 0xf0, +0x40, 0xcd, 0xef, 0x35, 0xc9, 0xed, 0x2b, 0xc6, +0xec, 0xcc, 0x03, 0xa5, 0x06, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0x6d, 0x49, 0x44, 0x41, 0x54, 0x18, +0xd3, 0x63, 0x60, 0x20, 0x1d, 0x30, 0x32, 0xc1, +0x01, 0x23, 0x58, 0x80, 0x89, 0x19, 0x08, 0x58, +0x58, 0xd9, 0xd8, 0x39, 0x38, 0x21, 0x22, 0x4c, +0xcc, 0x5c, 0xdc, 0x3c, 0xbc, 0x20, 0xc0, 0xc7, +0x0f, 0x16, 0x61, 0x62, 0x16, 0x10, 0xe4, 0x15, +0x12, 0x16, 0x11, 0x15, 0xe3, 0x15, 0x97, 0x00, +0x89, 0x30, 0x49, 0x4a, 0x49, 0xcb, 0x80, 0x55, +0xc8, 0xca, 0xc9, 0x2b, 0x30, 0x01, 0x05, 0x14, +0x95, 0x94, 0x79, 0x55, 0x54, 0xd5, 0xd4, 0x35, +0x78, 0x35, 0xb5, 0xc0, 0x2a, 0xb4, 0x75, 0x74, +0xf5, 0xc0, 0x2a, 0xf4, 0x0d, 0x20, 0x66, 0x00, +0x8d, 0x37, 0x34, 0x32, 0x36, 0x31, 0x35, 0x33, +0x87, 0xd8, 0x82, 0xe1, 0x0e, 0x2a, 0x00, 0x00, +0xc5, 0xaa, 0x07, 0x61, 0x1b, 0x7f, 0xec, 0x48, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, +0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *synonym_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_synonym_png = new wxImage(); + if (!img_synonym_png || !img_synonym_png->IsOk()) + { + wxMemoryInputStream img_synonym_pngIS(synonym_png_data, sizeof(synonym_png_data)); + img_synonym_png->LoadFile(img_synonym_pngIS, wxBITMAP_TYPE_PNG); + } + return img_synonym_png; +} +#define synonym_png_img synonym_png_img() + +static wxBitmap *synonym_png_bmp() +{ + static wxBitmap *bmp_synonym_png; + if (!bmp_synonym_png || !bmp_synonym_png->IsOk()) + bmp_synonym_png = new wxBitmap(*synonym_png_img); + return bmp_synonym_png; +} +#define synonym_png_bmp synonym_png_bmp() + +static wxIcon *synonym_png_ico() +{ + static wxIcon *ico_synonym_png; + if (!ico_synonym_png || !ico_synonym_png->IsOk()) + { + ico_synonym_png = new wxIcon(); + ico_synonym_png->CopyFromBitmap(*synonym_png_bmp); + } + return ico_synonym_png; +} +#define synonym_png_ico synonym_png_ico() + +#endif // SYNONYM_PNG_H diff --git a/include/images/synonyms.png b/include/images/synonyms.png new file mode 100644 index 0000000000000000000000000000000000000000..7e5307f5e9301915afde5191fe795240db6f7b86 GIT binary patch literal 448 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}U4T!BE0CUh=v?IV)hB-aKltO{ z&aZ#hefqQb-S4&o=So-ZJpA+D_OE|eeE2=>)z89BPfhDDN3VL+{P_Fn=iiPz`m*!Z z$90$97To=kbmMc{x+mUCAI4t$6maQ-^SSqnPQIFP@VWPe5B6u?MXY>ev*5nf>33!K zzh>O}9ChuJ@5K*}XWyHhd~3(VssVHXV@Z%-FoVOh8)-leXMsm#F_88EW4Dvpc0fj@ zr;B5V#O2!axA~e31XwN@iLwY@PYM*AvU>af|Bk!Fegz0WD=gYHQ}mEO!|Vi2g{5~| zE?zU8@G)o7&Ks7=(o5zYyk~skhRlg4D}ES>NT2fGwcztnleBijaIvRrS1GPhjJ+d& zWy^lk94oQE8`d;S&0qih`Ri-{{%)Sdx!@h^ivus#oB}#RwZt`|BqgyV)hf9t6-Y4{ z85kPq8XD;u7={=bSeY1GnV4!Dm|7Va%zLM|3PnS1eoAIqB}9XPC0GMcwTYF18AQXW T>7i?Y8W=oX{an^LB{Ts5(=ExX literal 0 HcmV?d00001 diff --git a/include/images/synonyms.pngc b/include/images/synonyms.pngc new file mode 100644 index 0000000..19db391 --- /dev/null +++ b/include/images/synonyms.pngc @@ -0,0 +1,100 @@ +#ifndef SYNONYMS_PNG_H +#define SYNONYMS_PNG_H + +static const unsigned char synonyms_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x7e, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x9d, 0xc2, 0xce, 0x59, +0x97, 0xab, 0xc8, 0xfa, 0xff, 0xc1, 0xf8, 0xfe, +0xb9, 0xf5, 0xfd, 0xae, 0xf2, 0xfc, 0xa3, 0xee, +0xfb, 0x86, 0xc0, 0xce, 0x75, 0xa9, 0xb9, 0xc3, +0xf9, 0xfe, 0xb7, 0xf5, 0xfd, 0xa8, 0xf0, 0xfb, +0x96, 0xea, 0xf9, 0x71, 0xb2, 0xe5, 0x35, 0x7f, +0xd3, 0x5b, 0xaa, 0xe2, 0x83, 0xe3, 0xf7, 0xcb, +0xe7, 0xf6, 0xc4, 0xe2, 0xf4, 0xb9, 0xda, 0xf1, +0xae, 0xd2, 0xed, 0x70, 0xdd, 0xf4, 0x62, 0xd8, +0xf3, 0x66, 0xae, 0xe4, 0x4b, 0xa5, 0xe1, 0x5d, +0xd6, 0xf2, 0x50, 0xd2, 0xf0, 0x43, 0xce, 0xef, +0xa2, 0xc9, 0xea, 0x98, 0xc1, 0xe7, 0x4b, 0xd0, +0xf0, 0x3f, 0xcc, 0xee, 0x58, 0xa9, 0xe2, 0x3c, +0xa0, 0xdf, 0x3a, 0xcb, 0xee, 0x76, 0xdf, 0xf5, +0x68, 0xda, 0xf3, 0x5a, 0xd6, 0xf2, 0x4d, 0xd1, +0xf0, 0x41, 0xcd, 0xef, 0x36, 0xc9, 0xed, 0x3e, +0x02, 0x05, 0x28, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x79, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x7d, +0xcf, 0xdb, 0x0e, 0x82, 0x30, 0x10, 0x04, 0xd0, +0x32, 0x15, 0x04, 0x11, 0xd7, 0x62, 0x51, 0x11, +0x94, 0xab, 0xb7, 0xff, 0xff, 0x41, 0xba, 0x16, +0xfa, 0x50, 0x13, 0xe6, 0x71, 0x72, 0xb2, 0x99, +0x15, 0xc2, 0x4f, 0x00, 0x9b, 0x60, 0x29, 0x20, +0xa5, 0xdc, 0x84, 0xd1, 0xd6, 0x35, 0x90, 0xf1, +0x6c, 0x92, 0xb9, 0xd8, 0x39, 0x63, 0x1b, 0xa4, +0x9e, 0xc1, 0xde, 0x33, 0xc8, 0xd8, 0x1c, 0xc8, +0xe4, 0xa8, 0xf8, 0x32, 0x14, 0x1b, 0xca, 0x4f, +0xba, 0xa0, 0xf3, 0xc5, 0x34, 0x66, 0x87, 0x31, +0x57, 0x16, 0xe5, 0xad, 0xaa, 0x21, 0xac, 0x21, +0x5d, 0xdc, 0x1f, 0xd4, 0xb4, 0xbf, 0x35, 0x6c, +0x3a, 0x16, 0xfd, 0xb0, 0xac, 0x83, 0x1a, 0x9f, +0xaf, 0xf7, 0xe7, 0xeb, 0xd6, 0xfe, 0xfd, 0xb3, +0x9a, 0x09, 0xa0, 0xee, 0x05, 0xe8, 0xc0, 0xe8, +0xac, 0xca, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, +0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *synonyms_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_synonyms_png = new wxImage(); + if (!img_synonyms_png || !img_synonyms_png->IsOk()) + { + wxMemoryInputStream img_synonyms_pngIS(synonyms_png_data, sizeof(synonyms_png_data)); + img_synonyms_png->LoadFile(img_synonyms_pngIS, wxBITMAP_TYPE_PNG); + } + return img_synonyms_png; +} +#define synonyms_png_img synonyms_png_img() + +static wxBitmap *synonyms_png_bmp() +{ + static wxBitmap *bmp_synonyms_png; + if (!bmp_synonyms_png || !bmp_synonyms_png->IsOk()) + bmp_synonyms_png = new wxBitmap(*synonyms_png_img); + return bmp_synonyms_png; +} +#define synonyms_png_bmp synonyms_png_bmp() + +static wxIcon *synonyms_png_ico() +{ + static wxIcon *ico_synonyms_png; + if (!ico_synonyms_png || !ico_synonyms_png->IsOk()) + { + ico_synonyms_png = new wxIcon(); + ico_synonyms_png->CopyFromBitmap(*synonyms_png_bmp); + } + return ico_synonyms_png; +} +#define synonyms_png_ico synonyms_png_ico() + +#endif // SYNONYMS_PNG_H diff --git a/include/images/table-repl-sm.png b/include/images/table-repl-sm.png new file mode 100644 index 0000000000000000000000000000000000000000..967bd937fb89c483a95146c88fb4c066f6da5711 GIT binary patch literal 675 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47>xpaLR^7d#i`G`&i$Km{^#1O zpHAI*b?@=>XV0HMd-m+;jb~*$Ul`1J(Q)=)^XY$8$A0G@_?f)(TiB-0o~u9DE`4h_ z@3s2Om(8dDdI7mh-fGNzx%ukbyLa#2yLa#Y{ris|J$n53@zbYI+YdaSw90wIwfqwo z*FAoGfBDMAH*a5Fvu4ekH*em(d-w9?%PH&JH{32+bvgH?KAH>pEkLwcYDb6lTnjSMzn9Td;a|S>({S~kKHdkaxd?|-Ppw^%jf&_9uI9h z=v%+m{Qdj)A3uJ4`}S?Y;d{CJ?}SW0kv_e={eWNN9=GZpj#VoSH*DCjY15{heRqN; z9}AyzIO^#`_{y}aw(m0jnr?*8!ML;jpIsdLYCufG;M>s0K@OF`34WUhOff8dA4 z%okCUjx~DRx&#b0#*!evU+O&yNCx<@>XyMS% zT)kq|%G22yS((l(B_&_K@bZY7^z`^PFfCiQEbW=tw6JS3X1CO~DKJ`Bv%9OOi-$`m zo0s!XXjnddd;j|R^$pt!6DEjxC|IbN=-4P3oeI0`tSzM>AS^9Df5MC@JZ0`&N5tB$ zgxJ`zGT48TG(363Ckg0g)e_f;l9a@fRIB8oR3OD*WMF8ZYiOivU>IU#U}a)#Wn!vr zU}|MxFz=n-DijU5`6-!cl@JXEmS7D))h1R3W)KahriZQpYGCkm^>bP0l+XkKRw_GR literal 0 HcmV?d00001 diff --git a/include/images/table-repl-sm.pngc b/include/images/table-repl-sm.pngc new file mode 100644 index 0000000..579a13a --- /dev/null +++ b/include/images/table-repl-sm.pngc @@ -0,0 +1,129 @@ +#ifndef TABLE_REPL_SM_PNG_H +#define TABLE_REPL_SM_PNG_H + +static const unsigned char table_repl_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x32, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x21, 0x95, 0xe7, 0x8a, +0xce, 0xfe, 0x94, 0xcf, 0xf9, 0xad, 0xd5, 0xf2, +0xca, 0xdc, 0xea, 0xde, 0xe3, 0xe7, 0xe6, 0xe7, +0xe7, 0xe6, 0xe6, 0xe6, 0xc5, 0xd8, 0xe6, 0x76, +0xb9, 0xe8, 0x30, 0x9c, 0xe8, 0x88, 0xcd, 0xfe, +0x83, 0xcb, 0xfe, 0x7a, 0xc6, 0xfb, 0x6f, 0xc0, +0xf9, 0x63, 0xb9, 0xf6, 0x56, 0xb2, 0xf3, 0x49, +0xab, 0xf0, 0x3d, 0xa5, 0xed, 0x31, 0x9e, 0xeb, +0x27, 0x99, 0xe9, 0x83, 0xcb, 0xfd, 0x4a, 0xab, +0xf0, 0x3d, 0xa4, 0xed, 0x28, 0x99, 0xe9, 0xb3, +0xd5, 0xed, 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde, +0xdf, 0xdf, 0xdf, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, +0xe3, 0xe5, 0xe5, 0xe5, 0x87, 0xc0, 0xe7, 0x92, +0xaa, 0x43, 0xb0, 0xd6, 0x6f, 0xc8, 0xd1, 0xae, +0xe3, 0xe3, 0xdf, 0xa7, 0xa9, 0xa3, 0xd9, 0xdb, +0xd3, 0xac, 0xac, 0xac, 0xec, 0xec, 0xec, 0xee, +0xee, 0xee, 0xe9, 0xe9, 0xe9, 0x94, 0xae, 0x47, +0xb0, 0xdb, 0x74, 0xaa, 0xd7, 0x6e, 0x95, 0xa9, +0x4c, 0x8b, 0xa3, 0x3a, 0x8f, 0xb5, 0x46, 0xad, +0xad, 0xad, 0xaf, 0xaf, 0xaf, 0xea, 0xea, 0xea, +0x48, 0x82, 0xbe, 0x37, 0x8a, 0xcf, 0x66, 0x93, +0x7a, 0x8d, 0xb7, 0x54, 0x97, 0xc9, 0x5a, 0x92, +0xc9, 0x58, 0x87, 0xb2, 0x3e, 0xe7, 0xe7, 0xe7, +0xeb, 0xeb, 0xeb, 0x73, 0xc6, 0xdf, 0x71, 0xc4, +0xde, 0x6e, 0xc0, 0xdd, 0x5d, 0xa3, 0xc9, 0x77, +0x9f, 0x4c, 0x8d, 0xc7, 0x55, 0x86, 0xc1, 0x4d, +0x7f, 0xad, 0x37, 0xef, 0xef, 0xef, 0xf1, 0xf1, +0xf1, 0xed, 0xed, 0xed, 0x70, 0xc3, 0xde, 0x6d, +0xbf, 0xdc, 0x54, 0x97, 0xc8, 0x67, 0x97, 0x77, +0x87, 0xc0, 0x4e, 0x81, 0xbc, 0x46, 0x7b, 0xb8, +0x41, 0x7a, 0xa9, 0x31, 0xb0, 0xb0, 0xb0, 0xb2, +0xb2, 0xb2, 0x6c, 0xbe, 0xdc, 0x52, 0x93, 0xc6, +0x57, 0x9c, 0xcb, 0x59, 0xa0, 0xca, 0xaf, 0xc0, +0xb6, 0xcd, 0xd3, 0xba, 0xce, 0xd4, 0xba, 0xcf, +0xd5, 0xbb, 0xf0, 0xf0, 0xf0, 0x6f, 0x9c, 0xcc, +0x65, 0x9d, 0xcc, 0x8b, 0xaf, 0xd6, 0x5d, 0x9a, +0xca, 0x5d, 0xa9, 0xd2, 0x52, 0x96, 0xc8, 0x69, +0xae, 0xe5, 0x6f, 0xc0, 0xf8, 0x28, 0x99, 0xe8, +0x5a, 0x92, 0xc6, 0x81, 0x48, 0xda, 0xd2, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0xa8, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x63, 0x60, 0x20, 0x06, 0x30, +0x22, 0x01, 0x88, 0x00, 0x13, 0x33, 0x0b, 0x2b, +0x1b, 0x3b, 0x07, 0x07, 0x27, 0x17, 0x37, 0x44, +0x80, 0x87, 0x97, 0x8f, 0x5f, 0x40, 0x50, 0x48, +0x58, 0x44, 0x14, 0xaa, 0x82, 0x47, 0x0c, 0x24, +0x20, 0x2e, 0x21, 0x22, 0x09, 0x15, 0x90, 0x92, +0x96, 0x96, 0x91, 0x95, 0x93, 0x57, 0xe0, 0x50, +0x84, 0x08, 0x28, 0x29, 0xab, 0xa8, 0xaa, 0xa9, +0xcb, 0x6b, 0x68, 0x6a, 0x69, 0x43, 0x04, 0x74, +0x74, 0xf5, 0xf4, 0x0d, 0x0c, 0x15, 0x34, 0x8c, +0x8c, 0x4d, 0x80, 0x02, 0xa6, 0xa6, 0xa6, 0x66, +0xe6, 0x16, 0x96, 0x56, 0xd6, 0x1c, 0x36, 0xda, +0x26, 0xb6, 0x20, 0x01, 0x3b, 0x7b, 0x07, 0x47, +0x27, 0x67, 0x17, 0x57, 0x1b, 0x63, 0x37, 0x77, +0x0f, 0x90, 0x80, 0xa7, 0x97, 0xb7, 0x8f, 0xaf, +0x9f, 0x7f, 0x80, 0xb6, 0x71, 0x60, 0x90, 0x16, +0x48, 0x20, 0x38, 0x24, 0x34, 0x2c, 0x3c, 0x22, +0x32, 0xca, 0x56, 0xd3, 0x43, 0x2b, 0x1a, 0x28, +0x10, 0x13, 0x1b, 0x17, 0x9f, 0x90, 0x98, 0x94, +0x0c, 0x76, 0x47, 0x0a, 0xc4, 0x16, 0x86, 0xd4, +0x54, 0x3c, 0x3e, 0x05, 0x00, 0x3f, 0xf2, 0x19, +0x31, 0xc9, 0xd8, 0x4c, 0x62, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *table_repl_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_table_repl_sm_png = new wxImage(); + if (!img_table_repl_sm_png || !img_table_repl_sm_png->IsOk()) + { + wxMemoryInputStream img_table_repl_sm_pngIS(table_repl_sm_png_data, sizeof(table_repl_sm_png_data)); + img_table_repl_sm_png->LoadFile(img_table_repl_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_table_repl_sm_png; +} +#define table_repl_sm_png_img table_repl_sm_png_img() + +static wxBitmap *table_repl_sm_png_bmp() +{ + static wxBitmap *bmp_table_repl_sm_png; + if (!bmp_table_repl_sm_png || !bmp_table_repl_sm_png->IsOk()) + bmp_table_repl_sm_png = new wxBitmap(*table_repl_sm_png_img); + return bmp_table_repl_sm_png; +} +#define table_repl_sm_png_bmp table_repl_sm_png_bmp() + +static wxIcon *table_repl_sm_png_ico() +{ + static wxIcon *ico_table_repl_sm_png; + if (!ico_table_repl_sm_png || !ico_table_repl_sm_png->IsOk()) + { + ico_table_repl_sm_png = new wxIcon(); + ico_table_repl_sm_png->CopyFromBitmap(*table_repl_sm_png_bmp); + } + return ico_table_repl_sm_png; +} +#define table_repl_sm_png_ico table_repl_sm_png_ico() + +#endif // TABLE_REPL_SM_PNG_H diff --git a/include/images/table-repl.png b/include/images/table-repl.png new file mode 100644 index 0000000000000000000000000000000000000000..2a082c67b8c307b673d32fc0df12fb5e857fc1f7 GIT binary patch literal 839 zcmV-N1GxN&P)EGk$<>u$+=H}Yr<*d%a^DG-QC^Z-rnEe-{9cj z;o;%p;^O1u9WCpoxM|ysXD2tspRD3tgNi;?CkCB?eFjJ>gwu{ zsX?E@R!@hogbGU53F;fxbw4xv*<+N)Ih*5}x!G5j$xe;LSDnnO!`mg6=3t=LR+PtVpU^d$&@U_=27 zKmjIZ7FITP4o*%kZXRBc03W}AppdYLsF=8fBv=KXlz^Z#P(Vgj4k940prELvtfH!> z&Zz+wK=3uSzyjJjx|({b`UZwZ#wK6^Q!{f5ODk&|TRS^@uz-W3le3Gfo4b~Yp%Ej4 zho_g9m$#3vpTE0tKwuD1AUGs6EIcAID%w3JHZ}k#5Eq}2n3SB7n&zG!n2`w-h|kK- z$<50z$Sce&DlP&Fl$4g0S5(FZq*qnf)YLLE)YUgMHZ`}jg47q))`G2VYwzgnf_WbR zhg&kzn38;O0000bbVXQnWMOn=I%9HWVRU5xGB7bPEip1JFfmjzFgi3dIy5yaFf}?b zFrMx%ssI20C3HntbYx+4WjbwdWNBu305UK!FfA}SEif@uGBY|fG&(RgD=;-WFfhuO RRjdF2002ovPDHLkV1h^asowwq literal 0 HcmV?d00001 diff --git a/include/images/table-repl.pngc b/include/images/table-repl.pngc new file mode 100644 index 0000000..a873c8e --- /dev/null +++ b/include/images/table-repl.pngc @@ -0,0 +1,149 @@ +#ifndef TABLE_REPL_PNG_H +#define TABLE_REPL_PNG_H + +static const unsigned char table_repl_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0xa1, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x21, 0x95, 0xe7, 0x8d, +0xd0, 0xff, 0x92, 0xcf, 0xfb, 0xa2, 0xd3, 0xf5, +0xba, 0xd8, 0xed, 0xd1, 0xdf, 0xe9, 0xdf, 0xe3, +0xe7, 0xe5, 0xe6, 0xe7, 0xe6, 0xe6, 0xe6, 0xda, +0xe1, 0xe5, 0xac, 0xce, 0xe7, 0x63, 0xb1, 0xe8, +0x2e, 0x9b, 0xe8, 0x8b, 0xcf, 0xff, 0x85, 0xcc, +0xfe, 0x7e, 0xc8, 0xfc, 0x75, 0xc3, 0xfa, 0x6c, +0xbe, 0xf8, 0x61, 0xb8, 0xf6, 0x56, 0xb2, 0xf3, +0x4b, 0xac, 0xf0, 0x40, 0xa7, 0xee, 0x37, 0xa0, +0xec, 0x2d, 0x9c, 0xea, 0x26, 0x98, 0xe9, 0x85, +0xcc, 0xfd, 0x6b, 0xbe, 0xf8, 0x41, 0xa6, 0xee, +0x36, 0xa1, 0xec, 0x2e, 0x9c, 0xea, 0xb4, 0xd6, +0xee, 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde, 0xdf, +0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, +0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe5, 0xe5, +0xe5, 0x87, 0xbf, 0xe7, 0xe8, 0xe8, 0xe8, 0xe9, +0xe9, 0xe9, 0xb2, 0xc1, 0x7f, 0x9d, 0xbd, 0x53, +0x8d, 0xa9, 0x3a, 0xa9, 0xa9, 0xa9, 0xe4, 0xe4, +0xe4, 0xac, 0xac, 0xac, 0xec, 0xec, 0xec, 0xed, +0xed, 0xed, 0xef, 0xef, 0xef, 0xea, 0xea, 0xea, +0x90, 0xa9, 0x41, 0x9f, 0xc2, 0x56, 0xb2, 0xdc, +0x76, 0x91, 0xaf, 0x43, 0xa7, 0xb3, 0x82, 0xa6, +0xb8, 0x68, 0x8e, 0xad, 0x42, 0xa3, 0xb6, 0x62, +0xad, 0xad, 0xad, 0xaf, 0xaf, 0xaf, 0xeb, 0xeb, +0xeb, 0xd0, 0xd5, 0xbf, 0xaa, 0xbd, 0x77, 0xa9, +0xd6, 0x6e, 0x8e, 0xb2, 0x40, 0x92, 0xb2, 0x47, +0x90, 0xbd, 0x4c, 0x8e, 0xbd, 0x4b, 0x7e, 0x99, +0x22, 0x48, 0x82, 0xbe, 0x4d, 0x8a, 0xc1, 0x4c, +0x89, 0xc1, 0x58, 0x89, 0x8f, 0x9b, 0xcd, 0x60, +0x96, 0xcd, 0x5e, 0x8f, 0xc8, 0x56, 0x86, 0xb7, +0x43, 0xf0, 0xf0, 0xf0, 0xf2, 0xf2, 0xf2, 0xee, +0xee, 0xee, 0x73, 0xc6, 0xdf, 0x71, 0xc4, 0xde, +0x6e, 0xc1, 0xdd, 0x64, 0xb0, 0xd4, 0x54, 0x8a, +0xa4, 0x88, 0xb5, 0x42, 0x8a, 0xc5, 0x52, 0x84, +0xc0, 0x4b, 0x7f, 0xb2, 0x3c, 0xb1, 0xb1, 0xb1, +0xb2, 0xb2, 0xb2, 0x70, 0xc4, 0xde, 0x6e, 0xc0, +0xdd, 0x68, 0xb8, 0xd9, 0x52, 0x87, 0xa3, 0x81, +0xb8, 0x5d, 0x86, 0xc1, 0x4d, 0x81, 0xbe, 0x48, +0x7b, 0xba, 0x42, 0x79, 0xaf, 0x36, 0xf1, 0xf1, +0xf1, 0xf3, 0xf3, 0xf3, 0xf5, 0xf5, 0xf5, 0x63, +0xae, 0xd4, 0x67, 0xb7, 0xd9, 0x57, 0x9d, 0xcb, +0x55, 0x89, 0x9d, 0xa5, 0xb7, 0x6a, 0x8f, 0xa1, +0x54, 0xa4, 0xb7, 0x6a, 0x90, 0xa2, 0x55, 0xf6, +0xf6, 0xf6, 0xf8, 0xf8, 0xf8, 0x61, 0xac, 0xd3, +0x74, 0xa2, 0xcf, 0x50, 0x91, 0xc5, 0x5e, 0xab, +0xd3, 0x5a, 0xa5, 0xd0, 0x70, 0x94, 0xb9, 0xb5, +0xb5, 0xb5, 0xb6, 0xb6, 0xb6, 0xb8, 0xb8, 0xb8, +0xf7, 0xf7, 0xf7, 0x93, 0xb5, 0xd9, 0x63, 0x94, +0xc7, 0x39, 0x9b, 0xe3, 0x9a, 0xb9, 0xd9, 0x57, +0x97, 0xc9, 0x4e, 0x8d, 0xc4, 0x57, 0x9d, 0xcc, +0xab, 0xc3, 0xdb, 0x25, 0x96, 0xe6, 0x60, 0xa0, +0xd7, 0x56, 0x94, 0xc7, 0x6c, 0x9f, 0xd0, 0x35, +0x9a, 0xe4, 0x68, 0x2d, 0x4a, 0xf8, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0xdd, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0x60, 0x60, 0x60, 0x44, 0x01, +0x0c, 0x40, 0x01, 0x26, 0x66, 0x16, 0x56, 0x36, +0x76, 0x0e, 0x4e, 0x4e, 0x2e, 0x6e, 0x1e, 0x5e, +0x90, 0x00, 0x1f, 0xbf, 0x80, 0xa0, 0x90, 0xb0, +0x88, 0xa8, 0x98, 0xb8, 0x84, 0x24, 0x58, 0x05, +0x9f, 0x94, 0x80, 0xa0, 0x34, 0x50, 0x40, 0x46, +0x56, 0x0e, 0x22, 0x20, 0xaf, 0xa0, 0xa0, 0xa8, +0xa4, 0xac, 0xa2, 0xaa, 0xa6, 0xce, 0xa9, 0x01, +0x16, 0x40, 0xf0, 0x35, 0xb5, 0xc0, 0x02, 0xda, +0x3a, 0xba, 0x9a, 0x7a, 0xaa, 0xfa, 0x06, 0x86, +0x46, 0xc6, 0x26, 0x60, 0x01, 0x53, 0x33, 0x73, +0x0b, 0x4b, 0x2b, 0x6b, 0x1b, 0x5b, 0x3b, 0x3b, +0x7b, 0xb0, 0x80, 0x83, 0xa3, 0x93, 0xb3, 0x8b, +0xab, 0x9b, 0xbb, 0x96, 0x89, 0xa1, 0x11, 0x23, +0x83, 0x87, 0xa7, 0x97, 0x97, 0x97, 0xb7, 0x8f, +0xaf, 0x9f, 0xbf, 0xbb, 0x71, 0x40, 0x60, 0x10, +0x50, 0x20, 0x38, 0x24, 0x34, 0x2c, 0x3c, 0x22, +0x32, 0x2a, 0xda, 0x3d, 0x26, 0x36, 0x36, 0x00, +0x28, 0x10, 0x17, 0x9f, 0x90, 0x98, 0x94, 0x9c, +0x92, 0x9a, 0xe6, 0x9e, 0x1e, 0x98, 0x91, 0x09, +0x14, 0x88, 0xcf, 0xca, 0xce, 0xc9, 0xcd, 0xcb, +0x2f, 0xc8, 0x2b, 0xcc, 0x2c, 0x2a, 0x2e, 0x02, +0x0a, 0x94, 0x94, 0x96, 0x95, 0x57, 0x54, 0xc6, +0x06, 0xa4, 0x57, 0x55, 0xd7, 0xd4, 0xd4, 0x32, +0x32, 0xd4, 0xd5, 0x37, 0x34, 0x36, 0x35, 0xb7, +0xb4, 0x82, 0xd4, 0x17, 0xd5, 0xd6, 0x82, 0xad, +0x6d, 0x6b, 0xef, 0xe8, 0xec, 0x82, 0x79, 0x1f, +0x00, 0x87, 0x5b, 0x32, 0xd2, 0x98, 0x92, 0x7c, +0x70, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, +0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *table_repl_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_table_repl_png = new wxImage(); + if (!img_table_repl_png || !img_table_repl_png->IsOk()) + { + wxMemoryInputStream img_table_repl_pngIS(table_repl_png_data, sizeof(table_repl_png_data)); + img_table_repl_png->LoadFile(img_table_repl_pngIS, wxBITMAP_TYPE_PNG); + } + return img_table_repl_png; +} +#define table_repl_png_img table_repl_png_img() + +static wxBitmap *table_repl_png_bmp() +{ + static wxBitmap *bmp_table_repl_png; + if (!bmp_table_repl_png || !bmp_table_repl_png->IsOk()) + bmp_table_repl_png = new wxBitmap(*table_repl_png_img); + return bmp_table_repl_png; +} +#define table_repl_png_bmp table_repl_png_bmp() + +static wxIcon *table_repl_png_ico() +{ + static wxIcon *ico_table_repl_png; + if (!ico_table_repl_png || !ico_table_repl_png->IsOk()) + { + ico_table_repl_png = new wxIcon(); + ico_table_repl_png->CopyFromBitmap(*table_repl_png_bmp); + } + return ico_table_repl_png; +} +#define table_repl_png_ico table_repl_png_ico() + +#endif // TABLE_REPL_PNG_H diff --git a/include/images/table-sm.png b/include/images/table-sm.png new file mode 100644 index 0000000000000000000000000000000000000000..6a40e15b09edd130ac1b4d9d827927252771922c GIT binary patch literal 526 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf_5hy{S0Jr8^?BF1e^bu?TzmD? zsXMRkJ%0Y|`SWMbo*ljMtZe5CgE=oc&i-pY{jciS@B9NllXrd#+w|FU^#|LfZw=?Y zR-gH@`Sf2eAa}`IjhQbuUwwP`?%jL$?%ltC|IwpIj~_pN`t)i0f#=JYFMsgh!J0K| z-n@D9?%lhWFJCTOwrs_U6%QXiT)TGd`t|Eyy?XWh`SaJWU%zfwE$(-}*G{DK)Ap4~_TaySb-B8!2v z2N=7Z%(eqE`aE46LnJQuo~C z?WtEg{!SN?Ivck8GV6=4?5Y;;3QXqtq~DW~KKF?G^wjNcH-6L!2%Spke!%Q9=UC?i z(Kn0sCVg~V&f$1Mw9#jorBlU}wzOX*dICEP#nrxkRTB`|X?$X`lg%pGcb~uB{IsOk()) + { + wxMemoryInputStream img_table_sm_pngIS(table_sm_png_data, sizeof(table_sm_png_data)); + img_table_sm_png->LoadFile(img_table_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_table_sm_png; +} +#define table_sm_png_img table_sm_png_img() + +static wxBitmap *table_sm_png_bmp() +{ + static wxBitmap *bmp_table_sm_png; + if (!bmp_table_sm_png || !bmp_table_sm_png->IsOk()) + bmp_table_sm_png = new wxBitmap(*table_sm_png_img); + return bmp_table_sm_png; +} +#define table_sm_png_bmp table_sm_png_bmp() + +static wxIcon *table_sm_png_ico() +{ + static wxIcon *ico_table_sm_png; + if (!ico_table_sm_png || !ico_table_sm_png->IsOk()) + { + ico_table_sm_png = new wxIcon(); + ico_table_sm_png->CopyFromBitmap(*table_sm_png_bmp); + } + return ico_table_sm_png; +} +#define table_sm_png_ico table_sm_png_ico() + +#endif // TABLE_SM_PNG_H diff --git a/include/images/table.png b/include/images/table.png new file mode 100644 index 0000000000000000000000000000000000000000..37b2227d8fe0cf76bde23855676403c57ccfb569 GIT binary patch literal 593 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMfjR2nzS0Jr8^?C1w|C7%DUUd2E zt{ZPJ-hX-j@$;w8oT%hof0v-kaQT=vdv;Tyd3Q5-o1ObdiClJ8#Zj*xN*~_O&>pg{QUXz*RNl;OkH}&m?E%JaC$sHdY(w2yI*ETJB#CxDVyM_6hsq?*{ z%bR2yj^^b{bb0Zwd(Bu=J=bCx>jtGG3nR*NpRqG!KlWJZ=J(tnh2i}TIU#U}a)#Wn!vrU}|MxFz=n-DijU5`6-!cl@JXEmS7D))h1R3W)Kah TriZQpYGCkm^>bP0l+XkKw!A9P literal 0 HcmV?d00001 diff --git a/include/images/table.pngc b/include/images/table.pngc new file mode 100644 index 0000000..3705f43 --- /dev/null +++ b/include/images/table.pngc @@ -0,0 +1,119 @@ +#ifndef TABLE_PNG_H +#define TABLE_PNG_H + +static const unsigned char table_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xd8, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x21, 0x95, 0xe7, 0x8d, +0xd0, 0xff, 0x92, 0xcf, 0xfb, 0xa2, 0xd3, 0xf5, +0xba, 0xd8, 0xed, 0xd1, 0xdf, 0xe9, 0xdf, 0xe3, +0xe7, 0xe5, 0xe6, 0xe7, 0xe6, 0xe6, 0xe6, 0xda, +0xe1, 0xe5, 0xac, 0xce, 0xe7, 0x63, 0xb1, 0xe8, +0x2e, 0x9b, 0xe8, 0x8b, 0xcf, 0xff, 0x85, 0xcc, +0xfe, 0x7e, 0xc8, 0xfc, 0x75, 0xc3, 0xfa, 0x6c, +0xbe, 0xf8, 0x61, 0xb8, 0xf6, 0x56, 0xb2, 0xf3, +0x4b, 0xac, 0xf0, 0x40, 0xa7, 0xee, 0x37, 0xa0, +0xec, 0x2d, 0x9c, 0xea, 0x26, 0x98, 0xe9, 0x85, +0xcc, 0xfd, 0x6b, 0xbe, 0xf8, 0x41, 0xa6, 0xee, +0x36, 0xa1, 0xec, 0x2e, 0x9c, 0xea, 0xb4, 0xd6, +0xee, 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde, 0xdf, +0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, +0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe5, 0xe5, +0xe5, 0x87, 0xbf, 0xe7, 0xe8, 0xe8, 0xe8, 0xe9, +0xe9, 0xe9, 0xe7, 0xe7, 0xe7, 0xa9, 0xa9, 0xa9, +0xe4, 0xe4, 0xe4, 0xac, 0xac, 0xac, 0xec, 0xec, +0xec, 0xed, 0xed, 0xed, 0xef, 0xef, 0xef, 0xea, +0xea, 0xea, 0xa7, 0xa7, 0xa7, 0xa8, 0xa8, 0xa8, +0xad, 0xad, 0xad, 0xaf, 0xaf, 0xaf, 0xeb, 0xeb, +0xeb, 0xf0, 0xf0, 0xf0, 0xf2, 0xf2, 0xf2, 0xee, +0xee, 0xee, 0xab, 0xab, 0xab, 0xb0, 0xb0, 0xb0, +0xb1, 0xb1, 0xb1, 0xb2, 0xb2, 0xb2, 0xf1, 0xf1, +0xf1, 0xf3, 0xf3, 0xf3, 0xf5, 0xf5, 0xf5, 0xb5, +0xb5, 0xb5, 0xf6, 0xf6, 0xf6, 0xf8, 0xf8, 0xf8, +0xb6, 0xb6, 0xb6, 0xb8, 0xb8, 0xb8, 0xf7, 0xf7, +0xf7, 0x73, 0xda, 0xb6, 0x7b, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0xb0, 0x49, 0x44, 0x41, 0x54, 0x18, +0xd3, 0x55, 0xcf, 0xd7, 0x12, 0x82, 0x30, 0x10, +0x85, 0xe1, 0x60, 0x8f, 0x1d, 0x7b, 0x17, 0x0b, +0x20, 0x01, 0x43, 0x51, 0x21, 0xa0, 0x62, 0x41, +0xe1, 0xfd, 0xdf, 0x48, 0xdd, 0x38, 0x3a, 0xec, +0xdd, 0xf9, 0xe6, 0xbf, 0x59, 0x84, 0x84, 0xd4, +0x21, 0x84, 0x84, 0x4c, 0x36, 0x97, 0x2f, 0x14, +0x4b, 0x18, 0x97, 0x2b, 0xd5, 0xda, 0x07, 0xea, +0x8d, 0xa6, 0xd8, 0x6a, 0x77, 0xba, 0xbd, 0xfe, +0x60, 0x08, 0x45, 0x7d, 0xd4, 0x14, 0xc7, 0x6f, +0x98, 0x4c, 0x67, 0x1c, 0xe6, 0x92, 0xb4, 0x58, +0xae, 0xd6, 0xb2, 0xa2, 0xe2, 0x0d, 0xc0, 0x7f, +0x6b, 0x84, 0x03, 0xd6, 0x35, 0x43, 0xde, 0x52, +0xd3, 0xb2, 0x1d, 0x80, 0xc5, 0x6e, 0x6f, 0x18, +0x8a, 0x4a, 0x0f, 0xae, 0xeb, 0x01, 0x7c, 0x7b, +0x9d, 0x38, 0xa6, 0x05, 0xb0, 0x22, 0xc4, 0xa1, +0x58, 0x77, 0x6d, 0xe6, 0x07, 0x00, 0x6b, 0xe3, +0x48, 0xa9, 0x46, 0x4e, 0xe7, 0x30, 0x64, 0x00, +0xef, 0xd8, 0x33, 0xad, 0x80, 0x5d, 0xfc, 0xeb, +0x0d, 0x40, 0xb7, 0x19, 0x0b, 0x03, 0x76, 0xbf, +0x45, 0x8f, 0x08, 0x80, 0xc7, 0x97, 0xfb, 0x33, +0x8e, 0x13, 0x80, 0x5f, 0x1f, 0x25, 0x1c, 0xd2, +0xef, 0xbf, 0x00, 0xb2, 0x0f, 0x1b, 0x0f, 0xe3, +0x76, 0xaa, 0x7b, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *table_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_table_png = new wxImage(); + if (!img_table_png || !img_table_png->IsOk()) + { + wxMemoryInputStream img_table_pngIS(table_png_data, sizeof(table_png_data)); + img_table_png->LoadFile(img_table_pngIS, wxBITMAP_TYPE_PNG); + } + return img_table_png; +} +#define table_png_img table_png_img() + +static wxBitmap *table_png_bmp() +{ + static wxBitmap *bmp_table_png; + if (!bmp_table_png || !bmp_table_png->IsOk()) + bmp_table_png = new wxBitmap(*table_png_img); + return bmp_table_png; +} +#define table_png_bmp table_png_bmp() + +static wxIcon *table_png_ico() +{ + static wxIcon *ico_table_png; + if (!ico_table_png || !ico_table_png->IsOk()) + { + ico_table_png = new wxIcon(); + ico_table_png->CopyFromBitmap(*table_png_bmp); + } + return ico_table_png; +} +#define table_png_ico table_png_ico() + +#endif // TABLE_PNG_H diff --git a/include/images/tables.png b/include/images/tables.png new file mode 100644 index 0000000000000000000000000000000000000000..680e86457e8c48cd01329f0303d663b0304ab44d GIT binary patch literal 555 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf-Te%o613!~@ehb_5 z*>m*=+of*}=e<^+`SRYqd(Ef+dI3e2yw#Zb^8Wq%j~+dG{P^+Hr%&4tJb&=u!SdzH z*Q{Cd=FOXT@7}$9`SRhzhs%~NTd`ur+O=!fuV4S_)vF1oK0kl{{PpYCFJ8P@xpL+E z_wPS`{P_0m+f}PpZP>73)22;No;>;R;X^gZ0Y5ZmzF7BH^&ij!j3q&S!3+-1ZlnP@ zoCO|{#X#BvjNMLV+W{F%JzX3_BreCEKQ7i}Akg}-$5cydO$Teo7MG=+N#Fmg3_MdIbtj55z467wYr(8Tf`DM;NgJ}*2Ts9xt za8DvyRL7)e=Crp3yMhn8I2OC7#SEE=o%X78W@Hc8CaPZTbY<@8<<)d7|eU8w+cl=ZhlH;S|vn-fhAZ2 cP_>Dbff+=@sp+9>fEpM)UHx3vIVCg!0JlsKi2wiq literal 0 HcmV?d00001 diff --git a/include/images/tables.pngc b/include/images/tables.pngc new file mode 100644 index 0000000..473e2e8 --- /dev/null +++ b/include/images/tables.pngc @@ -0,0 +1,114 @@ +#ifndef TABLES_PNG_H +#define TABLES_PNG_H + +static const unsigned char tables_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xbd, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x21, 0x95, 0xe7, 0x8a, +0xce, 0xfe, 0x94, 0xcf, 0xf9, 0xad, 0xd5, 0xf2, +0xca, 0xdc, 0xea, 0xde, 0xe3, 0xe7, 0xe6, 0xe7, +0xe7, 0xe6, 0xe6, 0xe6, 0xc5, 0xd8, 0xe6, 0x76, +0xb9, 0xe8, 0x30, 0x9c, 0xe8, 0x88, 0xcd, 0xfe, +0x52, 0xb0, 0xf2, 0xb3, 0xd5, 0xed, 0xdd, 0xdd, +0xdd, 0x83, 0xcb, 0xfe, 0x7a, 0xc6, 0xfb, 0x6f, +0xc0, 0xf9, 0x63, 0xb9, 0xf6, 0x56, 0xb2, 0xf3, +0x49, 0xab, 0xf0, 0x3d, 0xa5, 0xed, 0x31, 0x9e, +0xeb, 0x27, 0x99, 0xe9, 0xde, 0xde, 0xde, 0x83, +0xcb, 0xfd, 0x4a, 0xab, 0xf0, 0x3d, 0xa4, 0xed, +0x28, 0x99, 0xe9, 0xdf, 0xdf, 0xdf, 0xe2, 0xe2, +0xe2, 0xe3, 0xe3, 0xe3, 0xe5, 0xe5, 0xe5, 0x87, +0xc0, 0xe7, 0xe0, 0xe0, 0xe0, 0xa7, 0xa7, 0xa7, +0xac, 0xac, 0xac, 0xec, 0xec, 0xec, 0xee, 0xee, +0xee, 0xe9, 0xe9, 0xe9, 0xe1, 0xe1, 0xe1, 0xa6, +0xa6, 0xa6, 0xa8, 0xa8, 0xa8, 0xad, 0xad, 0xad, +0xaf, 0xaf, 0xaf, 0xea, 0xea, 0xea, 0x90, 0xca, +0xf3, 0xe7, 0xe7, 0xe7, 0xeb, 0xeb, 0xeb, 0xe8, +0xe8, 0xe8, 0xa9, 0xa9, 0xa9, 0xef, 0xef, 0xef, +0xf1, 0xf1, 0xf1, 0xed, 0xed, 0xed, 0xaa, 0xaa, +0xaa, 0xb0, 0xb0, 0xb0, 0xb2, 0xb2, 0xb2, 0xe4, +0xe4, 0xe4, 0xf0, 0xf0, 0xf0, 0x7b, 0xc6, 0xfb, +0x6f, 0xc0, 0xf8, 0x28, 0x99, 0xe8, 0xae, 0xfd, +0x25, 0xfe, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0xa5, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x5d, 0xcf, +0xc7, 0x16, 0x82, 0x30, 0x10, 0x85, 0xe1, 0x8c, +0x35, 0x2a, 0x1a, 0xac, 0x88, 0x05, 0x88, 0xb4, +0x44, 0xa5, 0x89, 0x62, 0xf7, 0xfd, 0x1f, 0xcb, +0x0c, 0x2c, 0x3c, 0x32, 0xcb, 0xff, 0x7c, 0x8b, +0x3b, 0x04, 0x7e, 0x47, 0xca, 0x83, 0x46, 0xb3, +0xd5, 0xee, 0x74, 0x29, 0xed, 0xf5, 0x07, 0x55, +0xd0, 0x86, 0xff, 0x06, 0xb4, 0x9a, 0x81, 0x51, +0xcd, 0x00, 0xab, 0x19, 0x15, 0x94, 0xd1, 0xc7, +0x93, 0xe9, 0x6c, 0xbe, 0x30, 0x96, 0x40, 0xc0, +0x44, 0xb3, 0xc2, 0xb0, 0xde, 0x18, 0x5b, 0x15, +0x2c, 0x34, 0x8c, 0x99, 0x96, 0xed, 0x70, 0xba, +0x53, 0xc1, 0x45, 0x43, 0xa9, 0xe7, 0x3a, 0x7e, +0x10, 0x0a, 0x15, 0x24, 0x9a, 0xbd, 0x77, 0x90, +0xdc, 0x3f, 0x46, 0x31, 0x90, 0x24, 0x41, 0x63, +0xb9, 0xd2, 0xa6, 0xa9, 0x88, 0x33, 0xdc, 0x86, +0xe6, 0x24, 0x72, 0x27, 0x8d, 0xce, 0x97, 0x02, +0x03, 0x9a, 0x3c, 0xbf, 0x72, 0x11, 0xdd, 0xee, +0x61, 0xf5, 0x21, 0x48, 0xfb, 0xc1, 0x69, 0x16, +0x14, 0xe1, 0xb3, 0x0a, 0x89, 0xa6, 0xbf, 0xde, +0xe5, 0x8e, 0x0f, 0x7c, 0x01, 0x9f, 0x6d, 0x10, +0xb4, 0xc9, 0xf5, 0x15, 0xb2, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *tables_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_tables_png = new wxImage(); + if (!img_tables_png || !img_tables_png->IsOk()) + { + wxMemoryInputStream img_tables_pngIS(tables_png_data, sizeof(tables_png_data)); + img_tables_png->LoadFile(img_tables_pngIS, wxBITMAP_TYPE_PNG); + } + return img_tables_png; +} +#define tables_png_img tables_png_img() + +static wxBitmap *tables_png_bmp() +{ + static wxBitmap *bmp_tables_png; + if (!bmp_tables_png || !bmp_tables_png->IsOk()) + bmp_tables_png = new wxBitmap(*tables_png_img); + return bmp_tables_png; +} +#define tables_png_bmp tables_png_bmp() + +static wxIcon *tables_png_ico() +{ + static wxIcon *ico_tables_png; + if (!ico_tables_png || !ico_tables_png->IsOk()) + { + ico_tables_png = new wxIcon(); + ico_tables_png->CopyFromBitmap(*tables_png_bmp); + } + return ico_tables_png; +} +#define tables_png_ico tables_png_ico() + +#endif // TABLES_PNG_H diff --git a/include/images/tablespace.png b/include/images/tablespace.png new file mode 100644 index 0000000000000000000000000000000000000000..4995c6c44708d99f8df253580d06164125fa2411 GIT binary patch literal 378 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}V1Q4EE0BJ0s_xWMm0#ay{rooV z$G3^!zxLcc=Kt+W>z!jhFYcy%{ZjYy+vFE_5g`_t#* zC%1iX9kKuTDf96y_sd&6&#aNV&zS!hXeeVzkY6x^!?PP{Kn`btM`SUO_5fqIli7Aa zMuMk{V~E7%-t+E44GKK00Y9|F0(2ri{9_lL6ftdI?7t;GQ+_!r|76n;da+&4Gw-p$ z)n@iYA6`e@jHp|aN~Rn*)OqizBF~4UFCso0lD3KHa3t}TuuGSfDSUc(Tk`*&D#j~c zS(dBwMXLerQY~?fC`m~yNwrEYN(E93Mh1okx`sx&28JO<2397IsOk()) + { + wxMemoryInputStream img_tablespace_pngIS(tablespace_png_data, sizeof(tablespace_png_data)); + img_tablespace_png->LoadFile(img_tablespace_pngIS, wxBITMAP_TYPE_PNG); + } + return img_tablespace_png; +} +#define tablespace_png_img tablespace_png_img() + +static wxBitmap *tablespace_png_bmp() +{ + static wxBitmap *bmp_tablespace_png; + if (!bmp_tablespace_png || !bmp_tablespace_png->IsOk()) + bmp_tablespace_png = new wxBitmap(*tablespace_png_img); + return bmp_tablespace_png; +} +#define tablespace_png_bmp tablespace_png_bmp() + +static wxIcon *tablespace_png_ico() +{ + static wxIcon *ico_tablespace_png; + if (!ico_tablespace_png || !ico_tablespace_png->IsOk()) + { + ico_tablespace_png = new wxIcon(); + ico_tablespace_png->CopyFromBitmap(*tablespace_png_bmp); + } + return ico_tablespace_png; +} +#define tablespace_png_ico tablespace_png_ico() + +#endif // TABLESPACE_PNG_H diff --git a/include/images/tablespaces.png b/include/images/tablespaces.png new file mode 100644 index 0000000000000000000000000000000000000000..9b090e419671c8179d99fa534b5bd91037da1036 GIT binary patch literal 336 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPGa3-AeX1=6RMsysMV_v`ztpWh~b z|Jr%?nBUhgb)P;LfBclm?tKNMjj<%iFPOpM*^M+HhqJ&VvKUBvfU(=jY&#$$)6>N< zgyVX0LIb0lqaug%jT-`oL<)g`#n9z23#+gr&qt@^WJgCG23o0rrD-}<$boTZ2xd}KIJv%c~Sn(Sd7uSJUMus_J z!b;bB{wxAos#@Y2QIe8al4_M)lnSI6j0_A7bqx%4jf_JKjIDsk&{*5R%*w#vIsOk()) + { + wxMemoryInputStream img_tablespaces_pngIS(tablespaces_png_data, sizeof(tablespaces_png_data)); + img_tablespaces_png->LoadFile(img_tablespaces_pngIS, wxBITMAP_TYPE_PNG); + } + return img_tablespaces_png; +} +#define tablespaces_png_img tablespaces_png_img() + +static wxBitmap *tablespaces_png_bmp() +{ + static wxBitmap *bmp_tablespaces_png; + if (!bmp_tablespaces_png || !bmp_tablespaces_png->IsOk()) + bmp_tablespaces_png = new wxBitmap(*tablespaces_png_img); + return bmp_tablespaces_png; +} +#define tablespaces_png_bmp tablespaces_png_bmp() + +static wxIcon *tablespaces_png_ico() +{ + static wxIcon *ico_tablespaces_png; + if (!ico_tablespaces_png || !ico_tablespaces_png->IsOk()) + { + ico_tablespaces_png = new wxIcon(); + ico_tablespaces_png->CopyFromBitmap(*tablespaces_png_bmp); + } + return ico_tablespaces_png; +} +#define tablespaces_png_ico tablespaces_png_ico() + +#endif // TABLESPACES_PNG_H diff --git a/include/images/template.png b/include/images/template.png new file mode 100644 index 0000000000000000000000000000000000000000..eb780bf0bb0f5d777e8a72720b5ed0e2ad48bc45 GIT binary patch literal 696 zcmY+CS4>j@6ozkcq>wQ5!GLk#CLzU3S)oQ!Yr$eFU<-t$cHKq-h(bd^Q2~h-MIjMo zBO)RJ1T=0%>WGXeVM%<^_+&IudiTD!Ug61y|NQ4q&iC@?)TAUG@by{m0|0<;qE2g& zJm8`;n6HC~D{V`Wn#u^!KY$1^XAv!XaHik}2wQV_;?{=MCv=JCwg z?M6|Yf}q2KFb+Y6lX;7qaaKO!Uvvz%k!fg_mbnDvg{+49p?FWJn!PT zR~+|@WgoNb1BSV8vuSC%o99P3?m5doVcCZaGsrM~G<}z*Z&Oq|NjBSTI+h(`n0}h> zq3JG)>Y%6=lDuiLs0iXJ!wfLYJ(|8lQMV|nl_VQU@;X6W!|}^Fei6f}Xu8vCjU&k> zl58M|I)b=@@6%eCr;WPOgta4;(&-EXUFOUO`XZ}&h~Uyt9KfZ6H!*@c!P-s3N06!6+37b}WYV{Rb2j+H&n>%K#X=1W4DBDlmE(m~2cNkN_Yt LK1n;MF;)Eq048yN literal 0 HcmV?d00001 diff --git a/include/images/template.pngc b/include/images/template.pngc new file mode 100644 index 0000000..bf09c6d --- /dev/null +++ b/include/images/template.pngc @@ -0,0 +1,131 @@ +#ifndef TEMPLATE_PNG_H +#define TEMPLATE_PNG_H + +static const unsigned char template_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x4d, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xd1, 0xc7, 0x79, 0xce, +0xbd, 0x39, 0xff, 0xff, 0xd6, 0xff, 0xff, 0xd4, +0xfe, 0xfe, 0xd2, 0xfe, 0xfe, 0xd0, 0xfe, 0xfe, +0xcd, 0xfd, 0xfd, 0xca, 0xfd, 0xfd, 0xc7, 0xfc, +0xfc, 0xc4, 0x66, 0x66, 0x55, 0xff, 0xff, 0xd3, +0x66, 0x66, 0x53, 0xfe, 0xfe, 0xce, 0x65, 0x65, +0x51, 0xfd, 0xfd, 0xc8, 0x65, 0x65, 0x4f, 0xfc, +0xfc, 0xc1, 0x65, 0x65, 0x4c, 0xfb, 0xfb, 0xba, +0xfe, 0xfe, 0xd1, 0xfe, 0xfe, 0xcc, 0xfd, 0xfd, +0xc9, 0xfd, 0xfd, 0xc6, 0xfc, 0xfc, 0xc2, 0xfc, +0xfc, 0xbf, 0xfb, 0xfb, 0xbb, 0xfb, 0xfb, 0xb7, +0xfa, 0xfa, 0xb4, 0xfa, 0xfa, 0xb0, 0xfc, 0xfc, +0xc3, 0xfc, 0xfc, 0xc0, 0xfb, 0xfb, 0xbc, 0xfb, +0xfb, 0xb8, 0xfa, 0xfa, 0xb5, 0xfa, 0xfa, 0xb1, +0xf9, 0xf9, 0xad, 0x64, 0x64, 0x44, 0xf8, 0xf8, +0xa4, 0xfc, 0xfc, 0xbd, 0xfb, 0xfb, 0xb9, 0xfa, +0xfa, 0xb6, 0xfa, 0xfa, 0xb2, 0xf9, 0xf9, 0xae, +0xf9, 0xf9, 0xaa, 0xf8, 0xf8, 0xa5, 0xf8, 0xf8, +0xa1, 0xf7, 0xf7, 0x9d, 0xf6, 0xf6, 0x99, 0x64, +0x64, 0x48, 0xfa, 0xfa, 0xaf, 0xf9, 0xf9, 0xab, +0xf8, 0xf8, 0xa6, 0xf8, 0xf8, 0xa2, 0xf7, 0xf7, +0x9e, 0xf7, 0xf7, 0x9a, 0xf6, 0xf6, 0x96, 0x62, +0x62, 0x3a, 0xf5, 0xf5, 0x8d, 0xf9, 0xf9, 0xac, +0xf9, 0xf9, 0xa7, 0xf8, 0xf8, 0xa3, 0xf7, 0xf7, +0x9f, 0xf7, 0xf7, 0x9b, 0xf6, 0xf6, 0x97, 0xf6, +0xf6, 0x93, 0xf5, 0xf5, 0x8e, 0xf4, 0xf4, 0x8a, +0xf4, 0xf4, 0x86, 0xf3, 0xf3, 0x82, 0xf8, 0xf8, +0xa0, 0x63, 0x63, 0x3e, 0xf6, 0xf6, 0x98, 0xf6, +0xf6, 0x94, 0xf5, 0xf5, 0x8f, 0xf5, 0xf5, 0x8b, +0xf4, 0xf4, 0x87, 0xf4, 0xf4, 0x83, 0xf3, 0xf3, +0x80, 0x61, 0x61, 0x32, 0xf2, 0xf2, 0x78, 0xf6, +0xf6, 0x95, 0xf5, 0xf5, 0x90, 0xf5, 0xf5, 0x8c, +0xf4, 0xf4, 0x88, 0xf4, 0xf4, 0x84, 0xf3, 0xf3, +0x81, 0xf3, 0xf3, 0x7d, 0xf2, 0xf2, 0x79, 0xf2, +0xf2, 0x76, 0xf1, 0xf1, 0x73, 0xf1, 0xf1, 0x6f, +0xf4, 0xf4, 0x89, 0x62, 0x62, 0x35, 0xf2, 0xf2, +0x7a, 0x61, 0x61, 0x30, 0x60, 0x60, 0x2d, 0xf0, +0xf0, 0x6d, 0x60, 0x60, 0x2b, 0xf0, 0xf0, 0x68, +0xf3, 0xf3, 0x7f, 0xf2, 0xf2, 0x7b, 0xf1, 0xf1, +0x74, 0xf1, 0xf1, 0x71, 0xf1, 0xf1, 0x6e, 0xf0, +0xf0, 0x6b, 0xf0, 0xf0, 0x69, 0xef, 0xef, 0x66, +0xef, 0xef, 0x64, 0xef, 0xef, 0x63, 0x05, 0x7c, +0x09, 0x42, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0xa2, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, +0xc0, 0x00, 0x8c, 0x4c, 0x08, 0xc0, 0x08, 0x12, +0x60, 0x62, 0x06, 0x02, 0x16, 0x56, 0x36, 0x76, +0x0e, 0x4e, 0x2e, 0x26, 0x88, 0x00, 0x37, 0x0f, +0x2f, 0x1f, 0xbf, 0x80, 0xa0, 0x90, 0xb0, 0x08, +0x44, 0x40, 0x94, 0x4f, 0x4c, 0x5c, 0x42, 0x52, +0x4a, 0x5a, 0x46, 0x56, 0x0e, 0x22, 0xc0, 0x21, +0x28, 0xaf, 0xa0, 0xa8, 0xa4, 0xac, 0xa2, 0xaa, +0xa6, 0x0e, 0x11, 0x10, 0xd2, 0xd0, 0xd4, 0xd2, +0xd6, 0xd1, 0xd5, 0xd3, 0x37, 0x30, 0x84, 0x08, +0xc8, 0x18, 0x19, 0x9b, 0x98, 0x9a, 0x99, 0x5b, +0x58, 0x5a, 0x59, 0x43, 0x04, 0x6c, 0x6c, 0xed, +0xec, 0x1d, 0x1c, 0x9d, 0x9c, 0x5d, 0x5c, 0xdd, +0x20, 0x02, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, +0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x10, 0x81, 0xa0, +0xe0, 0x90, 0xd0, 0xb0, 0xf0, 0x88, 0xc8, 0xa8, +0xe8, 0x18, 0x88, 0x40, 0x6c, 0x9c, 0x5b, 0x40, +0x7c, 0x42, 0x74, 0x62, 0x52, 0x72, 0x0a, 0x44, +0x20, 0x35, 0x2d, 0x30, 0x3d, 0x23, 0x33, 0x2b, +0x3b, 0x27, 0x37, 0x8f, 0x09, 0xab, 0x5f, 0x08, +0x01, 0x00, 0x78, 0xe9, 0x19, 0xd6, 0xac, 0x53, +0x24, 0x0a, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, +0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *template_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_template_png = new wxImage(); + if (!img_template_png || !img_template_png->IsOk()) + { + wxMemoryInputStream img_template_pngIS(template_png_data, sizeof(template_png_data)); + img_template_png->LoadFile(img_template_pngIS, wxBITMAP_TYPE_PNG); + } + return img_template_png; +} +#define template_png_img template_png_img() + +static wxBitmap *template_png_bmp() +{ + static wxBitmap *bmp_template_png; + if (!bmp_template_png || !bmp_template_png->IsOk()) + bmp_template_png = new wxBitmap(*template_png_img); + return bmp_template_png; +} +#define template_png_bmp template_png_bmp() + +static wxIcon *template_png_ico() +{ + static wxIcon *ico_template_png; + if (!ico_template_png || !ico_template_png->IsOk()) + { + ico_template_png = new wxIcon(); + ico_template_png->CopyFromBitmap(*template_png_bmp); + } + return ico_template_png; +} +#define template_png_ico template_png_ico() + +#endif // TEMPLATE_PNG_H diff --git a/include/images/templates.png b/include/images/templates.png new file mode 100644 index 0000000000000000000000000000000000000000..fabd47da7ae27b04b0bfd38a7b1ee9f6c1a74d2c GIT binary patch literal 601 zcmY+9Ye-W86vyuj!!5?7zDS=7f?QnJEZv8iwXIEZ*mjEw%H7=uILpipL87b$mOaoY zG^59ICOS;*K|&8hv}qE{A&!ucGBAp8clWjXUN`;JhyVGV1Lp_lv{kzg=yjWQ008J+ zPMb$%;lC8DQ|mUP!K;F=J_y-WCa0Pc@5*zzR4zBCD6@+4NtUN2X;PBj=W_GWZkwVc zWch7eOret#)NwPdsRSoRLXw9|AOMO~(-3nbZ`$%Op=GMc^u!)A&)55r(46ZH9t z38IdoE|KIpl5EOk8VRDFAOh($o=&3+LQOz@UK8@Ty?}N33$6~@2IsM$O6O`EAM5t0 zO_$470Ts<5J~XUxtOtF59LHe{`S}eE>l)5RWAIXicVhB-Uu&D8O228Z^XA1!$H>+G zyJb#mUa!MbdE9ZteNwX}Qs9a94)(_IsOk()) + { + wxMemoryInputStream img_templates_pngIS(templates_png_data, sizeof(templates_png_data)); + img_templates_png->LoadFile(img_templates_pngIS, wxBITMAP_TYPE_PNG); + } + return img_templates_png; +} +#define templates_png_img templates_png_img() + +static wxBitmap *templates_png_bmp() +{ + static wxBitmap *bmp_templates_png; + if (!bmp_templates_png || !bmp_templates_png->IsOk()) + bmp_templates_png = new wxBitmap(*templates_png_img); + return bmp_templates_png; +} +#define templates_png_bmp templates_png_bmp() + +static wxIcon *templates_png_ico() +{ + static wxIcon *ico_templates_png; + if (!ico_templates_png || !ico_templates_png->IsOk()) + { + ico_templates_png = new wxIcon(); + ico_templates_png->CopyFromBitmap(*templates_png_bmp); + } + return ico_templates_png; +} +#define templates_png_ico templates_png_ico() + +#endif // TEMPLATES_PNG_H diff --git a/include/images/terminate_backend.png b/include/images/terminate_backend.png new file mode 100644 index 0000000000000000000000000000000000000000..5634349cfca6d8af7bd11870612c005f4526f12d GIT binary patch literal 368 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}RDe&2E08|c8-G6#}+7VY3O^vV4KL$)52*WEY_gD=62nj>HELFzHweoB#|k2-sa$gK!a6F zTq8?MniLsT5skVWsm4U&$cY3Q(H00)|WTsU@ hG#FTdH2_tcSQ(f>G@P0qx(29$!PC{xWt~$(696SvjkW*) literal 0 HcmV?d00001 diff --git a/include/images/terminate_backend.pngc b/include/images/terminate_backend.pngc new file mode 100644 index 0000000..c4dee21 --- /dev/null +++ b/include/images/terminate_backend.pngc @@ -0,0 +1,90 @@ +#ifndef TERMINATE_BACKEND_PNG_H +#define TERMINATE_BACKEND_PNG_H + +static const unsigned char terminate_backend_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x5a, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc6, 0x8d, 0x5f, 0xd5, +0x17, 0x17, 0xe9, 0xd0, 0xa6, 0xe3, 0xc0, 0x86, +0xe4, 0xbf, 0x83, 0xe6, 0xbe, 0x7e, 0xe8, 0xbc, +0x7a, 0xe9, 0xba, 0x75, 0xec, 0xb9, 0x70, 0xf2, +0xc8, 0x8f, 0xe3, 0xc0, 0x85, 0xf1, 0xb4, 0x64, +0xe5, 0xbf, 0x81, 0xf3, 0xb2, 0x5d, 0xe6, 0xbd, +0x7d, 0xf5, 0xb0, 0x57, 0xe9, 0xbb, 0x77, 0xf8, +0xad, 0x51, 0xec, 0xb9, 0x71, 0xfb, 0xac, 0x4c, +0xee, 0xb6, 0x6b, 0xfc, 0xaa, 0x47, 0xf4, 0xc7, +0x8b, 0xf2, 0xb3, 0x5f, 0xf5, 0xb0, 0x59, 0xf7, +0xaf, 0x54, 0xf9, 0xad, 0x4f, 0xfb, 0xab, 0x4a, +0xfe, 0xbd, 0x71, 0xbc, 0xa7, 0x14, 0xb6, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x4d, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x9d, 0xce, 0x37, 0x16, 0x80, +0x30, 0x10, 0x43, 0x41, 0xef, 0x02, 0x26, 0x63, +0xa2, 0xc9, 0xf7, 0xbf, 0x26, 0x85, 0x8c, 0x3a, +0x0a, 0xfc, 0xcb, 0x79, 0x2a, 0x64, 0x4c, 0x54, +0xa2, 0x21, 0x09, 0xa0, 0x49, 0x9a, 0xd9, 0xbc, +0x28, 0x2b, 0x7d, 0xa1, 0xc6, 0xa0, 0x21, 0xb4, +0x80, 0x8e, 0xe0, 0x00, 0x3d, 0x61, 0x00, 0x8c, +0x84, 0x09, 0x30, 0x13, 0x16, 0x80, 0x27, 0xac, +0xdb, 0x7e, 0x9c, 0x97, 0xbf, 0xf5, 0xeb, 0xd8, +0xcf, 0x1e, 0x14, 0x61, 0x02, 0x53, 0x9e, 0xb3, +0x53, 0xc1, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, +0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *terminate_backend_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_terminate_backend_png = new wxImage(); + if (!img_terminate_backend_png || !img_terminate_backend_png->IsOk()) + { + wxMemoryInputStream img_terminate_backend_pngIS(terminate_backend_png_data, sizeof(terminate_backend_png_data)); + img_terminate_backend_png->LoadFile(img_terminate_backend_pngIS, wxBITMAP_TYPE_PNG); + } + return img_terminate_backend_png; +} +#define terminate_backend_png_img terminate_backend_png_img() + +static wxBitmap *terminate_backend_png_bmp() +{ + static wxBitmap *bmp_terminate_backend_png; + if (!bmp_terminate_backend_png || !bmp_terminate_backend_png->IsOk()) + bmp_terminate_backend_png = new wxBitmap(*terminate_backend_png_img); + return bmp_terminate_backend_png; +} +#define terminate_backend_png_bmp terminate_backend_png_bmp() + +static wxIcon *terminate_backend_png_ico() +{ + static wxIcon *ico_terminate_backend_png; + if (!ico_terminate_backend_png || !ico_terminate_backend_png->IsOk()) + { + ico_terminate_backend_png = new wxIcon(); + ico_terminate_backend_png->CopyFromBitmap(*terminate_backend_png_bmp); + } + return ico_terminate_backend_png; +} +#define terminate_backend_png_ico terminate_backend_png_ico() + +#endif // TERMINATE_BACKEND_PNG_H diff --git a/include/images/textsearch.png b/include/images/textsearch.png new file mode 100644 index 0000000000000000000000000000000000000000..7820b6bb901a9698b9b27c020de46718f2c2b894 GIT binary patch literal 788 zcmV+v1MB>WP)g>$U&bYa`rlzK_v9iL&#^L7Y^Z5CVnW0fpQJSW$hOfnv#^R&e z_nyq;1gv`>Eaah_uLff`^Kfo5#t@ ze5SpU&+bT8TGR6WOjlgX?)gMhSUOHrb(yMvg^8@Jt%bbV*Yy2MS6aH{@0-=;b*{yA zczV*((vp&rp4If#^8M5D`pfP1!Rhj`;Om#t<8!;$Z*OnU&(EHppqR$rK~hzt+2t`w zPiLjOZ*p|Dy1Rp;wXEOvzUTF{;p~vl-YP{+UWb==dw$sB=5>FCpV#lA*y@YS-gdv% zUzMq2ZgYx`k<-)D)z#JK@A4ZP8*qAmah0Zcuf}%0*?oO|nVFfhv$NLL*5~l^*5&HN z(A9i@foN%Ik(r#BpP`VDknr~S|DyxVyW%iKd9_+B&)r0X=;=4Ff|pBV!X&Gq8ZUg{-BOwT-Qvy@MlIz{y$0 zP|e20)y>@lBH-!e?W5(Z?dKm52oVSh76=J74hxTnjEar{3B<<5CnP4h2Sg^Pq^1Ey zn9?&cC9|>vb8_=i!6Hog1%*Y$K|v*@W#;8T5eB&DDk>_?tEy`lkbqfjT~!?esz^Nt z08(2jn-2srwEzGBC3HntbYx+4WjbSWWnpw>05UK!FfB1MEif@uGB7$cGdeUiD=;-W zFfg9(E~)?k03~!qSaf7zbY(hiZ)9m^c>ppnF)%GKIV~_TR5CLIsOk()) + { + wxMemoryInputStream img_textsearch_pngIS(textsearch_png_data, sizeof(textsearch_png_data)); + img_textsearch_png->LoadFile(img_textsearch_pngIS, wxBITMAP_TYPE_PNG); + } + return img_textsearch_png; +} +#define textsearch_png_img textsearch_png_img() + +static wxBitmap *textsearch_png_bmp() +{ + static wxBitmap *bmp_textsearch_png; + if (!bmp_textsearch_png || !bmp_textsearch_png->IsOk()) + bmp_textsearch_png = new wxBitmap(*textsearch_png_img); + return bmp_textsearch_png; +} +#define textsearch_png_bmp textsearch_png_bmp() + +static wxIcon *textsearch_png_ico() +{ + static wxIcon *ico_textsearch_png; + if (!ico_textsearch_png || !ico_textsearch_png->IsOk()) + { + ico_textsearch_png = new wxIcon(); + ico_textsearch_png->CopyFromBitmap(*textsearch_png_bmp); + } + return ico_textsearch_png; +} +#define textsearch_png_ico textsearch_png_ico() + +#endif // TEXTSEARCH_PNG_H diff --git a/include/images/trigger.png b/include/images/trigger.png new file mode 100644 index 0000000000000000000000000000000000000000..3b413e4a648c999c0dcc005aaaf02a710be4414b GIT binary patch literal 324 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPHF3h)VW1=6kiPU=rwT=MDBssBIz z{{Mgc|Bu?=uTvji_Bye{WYZ$U_4Az$Y>2*ja-Gx8WkA)8B|(0{3=Yq3qyagc1s;*b zK-vS0-A-oP0U3dwE{-7_*OL<(nB7!eIhs%2;5b!K7}#Lo*a4r5?=RWIaqXXEsv zK*Lo_Tq8IsOk()) + { + wxMemoryInputStream img_trigger_pngIS(trigger_png_data, sizeof(trigger_png_data)); + img_trigger_png->LoadFile(img_trigger_pngIS, wxBITMAP_TYPE_PNG); + } + return img_trigger_png; +} +#define trigger_png_img trigger_png_img() + +static wxBitmap *trigger_png_bmp() +{ + static wxBitmap *bmp_trigger_png; + if (!bmp_trigger_png || !bmp_trigger_png->IsOk()) + bmp_trigger_png = new wxBitmap(*trigger_png_img); + return bmp_trigger_png; +} +#define trigger_png_bmp trigger_png_bmp() + +static wxIcon *trigger_png_ico() +{ + static wxIcon *ico_trigger_png; + if (!ico_trigger_png || !ico_trigger_png->IsOk()) + { + ico_trigger_png = new wxIcon(); + ico_trigger_png->CopyFromBitmap(*trigger_png_bmp); + } + return ico_trigger_png; +} +#define trigger_png_ico trigger_png_ico() + +#endif // TRIGGER_PNG_H diff --git a/include/images/triggerbad.png b/include/images/triggerbad.png new file mode 100644 index 0000000000000000000000000000000000000000..6cc2fe96c8f234a73672cc73fd272a15fc7de4f9 GIT binary patch literal 610 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf&j6ngS0LTG@1*|3#U-B}o%;Xd z@BjbbfBg9M>-UfEKmPptck0#i>q$vR85k~vM;h66vGt;?!=F#Zb zZ{_7j+`X5s+_2Bq>0@|!L|y;4va)YQMPKvs_EKeX=}P-AfLdmo>7uC8zF>|a}0_%=`3<>K}sDCoVn_gfd&*XHK03=LmuYd7cA zdvL>2>S4={E+nQaGTEbw%343W5;d-f{dp#&b*2lcZ1ns=Wr`2LXZ@Y}!gZH&=I zLRA-+#NU!T_D{s!WsY3O^U7b0%|TU)i%;fkeASY}^oDQwY2NeVd+dG)aM5p$oE-1tl3!?oFZs`=O(lN+cwV$Ps+oeiATx_obU^~(ExO-YKdz^NlIc#s#S7P zDv)9@GB7mMH89pSum~|UvNANcGO*M(Ftai+xcqEI5{ic0{FKbJO57S2?H0HP)WG2B L>gTe~DWM4fI7SDA literal 0 HcmV?d00001 diff --git a/include/images/triggerbad.pngc b/include/images/triggerbad.pngc new file mode 100644 index 0000000..caedb0e --- /dev/null +++ b/include/images/triggerbad.pngc @@ -0,0 +1,121 @@ +#ifndef TRIGGERBAD_PNG_H +#define TRIGGERBAD_PNG_H + +static const unsigned char triggerbad_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xf9, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x85, 0xbe, 0xc9, 0x2f, +0x91, 0xa3, 0x74, 0xf2, 0xe2, 0xca, 0xff, 0xf8, +0xfd, 0xff, 0xff, 0xf7, 0xf8, 0xf8, 0xfa, 0xfa, +0xfb, 0xf8, 0xf7, 0xf8, 0xfc, 0xfe, 0xfe, 0xca, +0xea, 0xe7, 0xd7, 0x62, 0x62, 0xc5, 0x00, 0x00, +0xd0, 0x57, 0x59, 0xc4, 0xc4, 0xc8, 0xc6, 0xfd, +0xf6, 0x93, 0x94, 0xa1, 0xc5, 0x47, 0x4b, 0xdd, +0x69, 0x69, 0x43, 0x87, 0x99, 0xc5, 0x5b, 0x5d, +0xf6, 0x77, 0x77, 0xc4, 0x47, 0x4b, 0xa5, 0xa9, +0xb0, 0xbe, 0x3d, 0x42, 0xf1, 0x57, 0x57, 0x58, +0x7e, 0x8f, 0xf6, 0x76, 0x76, 0xf6, 0x72, 0x72, +0xf5, 0x6e, 0x6e, 0xbc, 0x3b, 0x40, 0xf1, 0x56, +0x56, 0xef, 0x4f, 0x4f, 0xee, 0x48, 0x49, 0x5e, +0x7b, 0x8c, 0xca, 0x51, 0x54, 0xf5, 0x6d, 0x6d, +0xf4, 0x68, 0x68, 0xf3, 0x62, 0x62, 0xf0, 0x55, +0x55, 0xef, 0x4e, 0x4f, 0xee, 0x48, 0x48, 0x38, +0x8c, 0x9e, 0x98, 0xbe, 0xbc, 0xf3, 0x61, 0x61, +0xf1, 0x5b, 0x5b, 0xf0, 0x54, 0x54, 0xef, 0x4d, +0x4e, 0xee, 0x47, 0x47, 0x36, 0xaf, 0xa0, 0xa3, +0xc0, 0xbd, 0xda, 0x65, 0x65, 0xf0, 0x53, 0x54, +0xef, 0x4d, 0x4d, 0xee, 0x46, 0x46, 0xaa, 0x2c, +0x33, 0x8f, 0xc2, 0xbe, 0xd6, 0x62, 0x62, 0xf0, +0x53, 0x53, 0xef, 0x4c, 0x4c, 0xee, 0x45, 0x45, +0xec, 0x3e, 0x3f, 0xeb, 0x38, 0x38, 0x4d, 0x83, +0x94, 0xba, 0x44, 0x46, 0xf0, 0x52, 0x52, 0xef, +0x4b, 0x4b, 0xed, 0x44, 0x45, 0xeb, 0x37, 0x37, +0xea, 0x31, 0x31, 0xe9, 0x2b, 0x2b, 0x83, 0x6c, +0x7c, 0xf0, 0x51, 0x51, 0xee, 0x4a, 0x4a, 0xed, +0x43, 0x44, 0x99, 0x43, 0x4a, 0xe9, 0x2a, 0x2b, +0xe8, 0x25, 0x25, 0xe7, 0x20, 0x20, 0xed, 0x42, +0x43, 0xc4, 0x46, 0x4a, 0x99, 0x44, 0x4b, 0xe7, +0x1f, 0x20, 0xaf, 0xf9, 0x42, 0x9f, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0xa0, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x6d, 0xcd, 0xd5, 0x0e, 0xc2, 0x60, +0x0c, 0x05, 0xe0, 0x7f, 0x1d, 0xbe, 0x83, 0xbb, +0xcb, 0x70, 0xf7, 0xe1, 0x0e, 0xc3, 0xed, 0xfd, +0x1f, 0x86, 0x01, 0x5b, 0x32, 0x12, 0x7a, 0xd1, +0xa4, 0x5f, 0xda, 0x1e, 0xc6, 0xfe, 0x14, 0x47, +0x44, 0x9c, 0x1e, 0x88, 0xe7, 0x79, 0xfa, 0x01, +0x83, 0x52, 0x7a, 0x21, 0xa3, 0xc9, 0x6c, 0xb1, +0xea, 0x84, 0x6c, 0x02, 0xec, 0x0e, 0xa7, 0xcb, +0x0d, 0xcf, 0x17, 0xbc, 0x3e, 0xf8, 0x11, 0x08, +0x86, 0x10, 0x56, 0x25, 0x82, 0x68, 0x2c, 0x8e, +0x04, 0x92, 0xa9, 0x34, 0x3e, 0x90, 0x11, 0x91, +0xcd, 0xe5, 0x51, 0x28, 0x96, 0xd4, 0x8d, 0x72, +0x45, 0x40, 0xb5, 0x56, 0x6f, 0x34, 0xb5, 0x1f, +0xd4, 0x6a, 0x77, 0xd0, 0xed, 0xf5, 0x21, 0x69, +0x29, 0x83, 0x21, 0x46, 0xe3, 0xc9, 0x74, 0xa6, +0x6d, 0xcc, 0x17, 0x58, 0xae, 0xd6, 0xd8, 0x6c, +0x77, 0xaa, 0xc8, 0xd8, 0x1f, 0x8e, 0x38, 0xe1, +0x7c, 0xb9, 0x7e, 0x53, 0x64, 0x11, 0x37, 0xdc, +0xd9, 0x03, 0x4f, 0xed, 0x86, 0x49, 0x90, 0xe4, +0x77, 0x57, 0xe6, 0x17, 0x59, 0x1e, 0x10, 0xc8, +0x4e, 0x56, 0xd8, 0x80, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x31, 0x2d, 0x30, 0x33, 0x2d, +0x30, 0x38, 0x54, 0x31, 0x32, 0x3a, 0x31, 0x37, +0x3a, 0x30, 0x39, 0x2b, 0x30, 0x36, 0x3a, 0x30, +0x30, 0xd3, 0xe6, 0xa8, 0x62, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x31, 0x2d, 0x30, 0x33, +0x2d, 0x30, 0x38, 0x54, 0x31, 0x32, 0x3a, 0x31, +0x37, 0x3a, 0x30, 0x39, 0x2b, 0x30, 0x36, 0x3a, +0x30, 0x30, 0xa2, 0xbb, 0x10, 0xde, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *triggerbad_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_triggerbad_png = new wxImage(); + if (!img_triggerbad_png || !img_triggerbad_png->IsOk()) + { + wxMemoryInputStream img_triggerbad_pngIS(triggerbad_png_data, sizeof(triggerbad_png_data)); + img_triggerbad_png->LoadFile(img_triggerbad_pngIS, wxBITMAP_TYPE_PNG); + } + return img_triggerbad_png; +} +#define triggerbad_png_img triggerbad_png_img() + +static wxBitmap *triggerbad_png_bmp() +{ + static wxBitmap *bmp_triggerbad_png; + if (!bmp_triggerbad_png || !bmp_triggerbad_png->IsOk()) + bmp_triggerbad_png = new wxBitmap(*triggerbad_png_img); + return bmp_triggerbad_png; +} +#define triggerbad_png_bmp triggerbad_png_bmp() + +static wxIcon *triggerbad_png_ico() +{ + static wxIcon *ico_triggerbad_png; + if (!ico_triggerbad_png || !ico_triggerbad_png->IsOk()) + { + ico_triggerbad_png = new wxIcon(); + ico_triggerbad_png->CopyFromBitmap(*triggerbad_png_bmp); + } + return ico_triggerbad_png; +} +#define triggerbad_png_ico triggerbad_png_ico() + +#endif // TRIGGERBAD_PNG_H diff --git a/include/images/triggerfunction.png b/include/images/triggerfunction.png new file mode 100644 index 0000000000000000000000000000000000000000..2b8ba80bacbeb1dda277ce0e84b9a1f0039eae06 GIT binary patch literal 334 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPHF3h)VW1=6kiPU=rwT=MDBssBIz z{{Mgc|Bu?=uTvji_Bye{WYZ$U_4Az$Y>2*ja-Gx8WkA)8B|(0{3=Yq3qyagc1s;*b zK-vS0-A-oP0U6PrE{-7_*OL<(7~Nb2n3&X*85NieV?-J`j&Se_aq%*787^I_xpXOG z>x@&UyBjM3DsnO5H1>zVOgZNfU^E(aE)=aU!&6mPdO zGHmydsNK(U2;?u-64!{5l*E!$tK_0oAjM#0U}&IgXryak7-D2#Wnye)VybOmYGq(B u@15Q%6b-rgDVb@N5Df;FU=2XkCRPS!5DllMhpqu?VDNPHb6Mw<&;$TXS!~Pz literal 0 HcmV?d00001 diff --git a/include/images/triggerfunction.pngc b/include/images/triggerfunction.pngc new file mode 100644 index 0000000..7457df2 --- /dev/null +++ b/include/images/triggerfunction.pngc @@ -0,0 +1,86 @@ +#ifndef TRIGGERFUNCTION_PNG_H +#define TRIGGERFUNCTION_PNG_H + +static const unsigned char triggerfunction_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x2a, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x85, 0xbe, 0xc9, 0x2f, +0x91, 0xa3, 0x74, 0xf2, 0xe2, 0xca, 0xff, 0xf8, +0xfd, 0xff, 0xff, 0xc7, 0xff, 0xf8, 0x7d, 0xfb, +0xeb, 0x65, 0xe3, 0xd3, 0x4a, 0xc8, 0xb8, 0x34, +0xb2, 0xa2, 0x31, 0xaf, 0x9f, 0x42, 0xc0, 0xb0, +0x5b, 0xd9, 0xc9, 0xae, 0x42, 0xb9, 0xa6, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x5b, 0x49, 0x44, 0x41, +0x54, 0x08, 0xd7, 0x63, 0x60, 0x80, 0x01, 0x46, +0x45, 0x10, 0x02, 0x02, 0x26, 0x23, 0x01, 0x20, +0x02, 0x31, 0x5c, 0x14, 0x81, 0x08, 0xc4, 0x08, +0x0d, 0x12, 0x0a, 0x0d, 0x02, 0x0a, 0x31, 0xa5, +0xa5, 0x29, 0xa5, 0xa5, 0x01, 0x85, 0x98, 0xca, +0xcb, 0x8b, 0x80, 0x48, 0x80, 0x81, 0xa9, 0x03, +0x0c, 0x14, 0x18, 0x98, 0x66, 0xce, 0x9c, 0x04, +0x44, 0x40, 0x91, 0x55, 0xab, 0x94, 0x56, 0xad, +0x02, 0xa9, 0xd9, 0xbd, 0x49, 0x68, 0xf7, 0x26, +0x90, 0xae, 0x33, 0x8a, 0x40, 0x04, 0x32, 0xe7, +0x92, 0x00, 0x10, 0x21, 0xdb, 0x85, 0x01, 0x00, +0xb7, 0x48, 0x18, 0x7d, 0xbf, 0x04, 0xc2, 0x0a, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, +0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *triggerfunction_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_triggerfunction_png = new wxImage(); + if (!img_triggerfunction_png || !img_triggerfunction_png->IsOk()) + { + wxMemoryInputStream img_triggerfunction_pngIS(triggerfunction_png_data, sizeof(triggerfunction_png_data)); + img_triggerfunction_png->LoadFile(img_triggerfunction_pngIS, wxBITMAP_TYPE_PNG); + } + return img_triggerfunction_png; +} +#define triggerfunction_png_img triggerfunction_png_img() + +static wxBitmap *triggerfunction_png_bmp() +{ + static wxBitmap *bmp_triggerfunction_png; + if (!bmp_triggerfunction_png || !bmp_triggerfunction_png->IsOk()) + bmp_triggerfunction_png = new wxBitmap(*triggerfunction_png_img); + return bmp_triggerfunction_png; +} +#define triggerfunction_png_bmp triggerfunction_png_bmp() + +static wxIcon *triggerfunction_png_ico() +{ + static wxIcon *ico_triggerfunction_png; + if (!ico_triggerfunction_png || !ico_triggerfunction_png->IsOk()) + { + ico_triggerfunction_png = new wxIcon(); + ico_triggerfunction_png->CopyFromBitmap(*triggerfunction_png_bmp); + } + return ico_triggerfunction_png; +} +#define triggerfunction_png_ico triggerfunction_png_ico() + +#endif // TRIGGERFUNCTION_PNG_H diff --git a/include/images/triggerfunctions.png b/include/images/triggerfunctions.png new file mode 100644 index 0000000000000000000000000000000000000000..d310acbf8dab1ac682b80798e7ffecf3a28aca1b GIT binary patch literal 358 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFP2=EDU1=6kiPU=rwT=MDBga5xP z_8kvevia@*zqR{LO#1)PZsy9&=hxkjZZ%jp&vN_nuq#Jyoy)le)WcX3 zty^Cm{$1}xf#P2Gs{RAlUTVK`&S}2Q&&ZIzTq5Lt_k_DZi&aZpBT7;dOH!?pi&B9U zgOP!ufv%yEu7P2Qk%5(ov6YFbwt=aYfx*0YdaF=0IsOk()) + { + wxMemoryInputStream img_triggerfunctions_pngIS(triggerfunctions_png_data, sizeof(triggerfunctions_png_data)); + img_triggerfunctions_png->LoadFile(img_triggerfunctions_pngIS, wxBITMAP_TYPE_PNG); + } + return img_triggerfunctions_png; +} +#define triggerfunctions_png_img triggerfunctions_png_img() + +static wxBitmap *triggerfunctions_png_bmp() +{ + static wxBitmap *bmp_triggerfunctions_png; + if (!bmp_triggerfunctions_png || !bmp_triggerfunctions_png->IsOk()) + bmp_triggerfunctions_png = new wxBitmap(*triggerfunctions_png_img); + return bmp_triggerfunctions_png; +} +#define triggerfunctions_png_bmp triggerfunctions_png_bmp() + +static wxIcon *triggerfunctions_png_ico() +{ + static wxIcon *ico_triggerfunctions_png; + if (!ico_triggerfunctions_png || !ico_triggerfunctions_png->IsOk()) + { + ico_triggerfunctions_png = new wxIcon(); + ico_triggerfunctions_png->CopyFromBitmap(*triggerfunctions_png_bmp); + } + return ico_triggerfunctions_png; +} +#define triggerfunctions_png_ico triggerfunctions_png_ico() + +#endif // TRIGGERFUNCTIONS_PNG_H diff --git a/include/images/triggers.png b/include/images/triggers.png new file mode 100644 index 0000000000000000000000000000000000000000..3c339406fa325dad67f59141a6a08a5334debcda GIT binary patch literal 350 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFv5AX?b1=6kiPU=rwT=MDBga5xP z_8ouw|L>&#A2Xj{cR#w-VBI{+?aRZi97(#*xCE$_u_VYZn8D%MjWi&Kv%n*=7)X17 zvD?XPJ0K&^)5S4_<9f0{kWc~xb80dxhx5@;Pr)+*-bQ9j-mAoSvNTT3G+F96CDTtU zys(goD^vGXfVVgEs_XYmg7@y()6wYo{DM|*UmqVUo8r>Dvy9XIn6#3t7H`cGJ>lb~ z`u6T@g>5h9G)5dcu;fSs3qwIU#U}a)#Wn!vrU}|MxFz=n-DijU5`6-!cl@JXEmS7D))h1R3W)KahriZQpYGCkm L^>bP0l+XkKAR%?3 literal 0 HcmV?d00001 diff --git a/include/images/triggers.pngc b/include/images/triggers.pngc new file mode 100644 index 0000000..a229be0 --- /dev/null +++ b/include/images/triggers.pngc @@ -0,0 +1,88 @@ +#ifndef TRIGGERS_PNG_H +#define TRIGGERS_PNG_H + +static const unsigned char triggers_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x27, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x85, 0xbe, 0xc9, 0x2f, +0x91, 0xa3, 0x74, 0xf2, 0xe2, 0xe0, 0xff, 0xfb, +0x78, 0xbe, 0xc7, 0xed, 0xff, 0xfd, 0x92, 0xff, +0xf1, 0x69, 0xe7, 0xd7, 0x47, 0xc5, 0xb5, 0x30, +0xae, 0x9e, 0x39, 0xb7, 0xa7, 0x56, 0xd4, 0xc4, +0x62, 0xdf, 0x01, 0xa4, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x6e, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, +0x63, 0x10, 0x52, 0x12, 0x60, 0x00, 0x03, 0x65, +0x63, 0x05, 0x08, 0x43, 0xc5, 0x55, 0x49, 0x11, +0xcc, 0x50, 0x4b, 0x32, 0x36, 0x02, 0x4b, 0xaa, +0x17, 0xb9, 0x04, 0x81, 0x95, 0x69, 0x34, 0xa5, +0x41, 0x94, 0x69, 0x4e, 0x2a, 0x57, 0x71, 0x71, +0x02, 0x0a, 0x69, 0x2d, 0xea, 0x50, 0x4b, 0x4b, +0x03, 0xaa, 0xd7, 0xde, 0x34, 0x53, 0xbd, 0xbc, +0xbc, 0x88, 0x81, 0x41, 0xe7, 0xd0, 0x2a, 0x8d, +0x8e, 0x8e, 0x0e, 0x05, 0x06, 0x21, 0xa5, 0xdd, +0x9a, 0x33, 0x67, 0x4e, 0x02, 0x2a, 0x62, 0x3a, +0xa3, 0xb5, 0x6a, 0x15, 0xc8, 0x4c, 0x46, 0x25, +0xed, 0xdd, 0x9b, 0x20, 0xb6, 0xe8, 0x9c, 0x81, +0x58, 0xc2, 0xc0, 0xa4, 0xc4, 0x80, 0x04, 0x00, +0x82, 0x8a, 0x18, 0x64, 0x25, 0x1c, 0x07, 0x64, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, +0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *triggers_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_triggers_png = new wxImage(); + if (!img_triggers_png || !img_triggers_png->IsOk()) + { + wxMemoryInputStream img_triggers_pngIS(triggers_png_data, sizeof(triggers_png_data)); + img_triggers_png->LoadFile(img_triggers_pngIS, wxBITMAP_TYPE_PNG); + } + return img_triggers_png; +} +#define triggers_png_img triggers_png_img() + +static wxBitmap *triggers_png_bmp() +{ + static wxBitmap *bmp_triggers_png; + if (!bmp_triggers_png || !bmp_triggers_png->IsOk()) + bmp_triggers_png = new wxBitmap(*triggers_png_img); + return bmp_triggers_png; +} +#define triggers_png_bmp triggers_png_bmp() + +static wxIcon *triggers_png_ico() +{ + static wxIcon *ico_triggers_png; + if (!ico_triggers_png || !ico_triggers_png->IsOk()) + { + ico_triggers_png = new wxIcon(); + ico_triggers_png->CopyFromBitmap(*triggers_png_bmp); + } + return ico_triggers_png; +} +#define triggers_png_ico triggers_png_ico() + +#endif // TRIGGERS_PNG_H diff --git a/include/images/type.png b/include/images/type.png new file mode 100644 index 0000000000000000000000000000000000000000..6c16764e7d08c56922a97a2f0c6cc06455c86a56 GIT binary patch literal 325 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFv5AX?b1=8~#9EmzT>)QWU=l(xE z`v2js|F_rtzdY~%nF;@oHvQjQ{(pPk|IMk)0@*;Nj3q&S!3+-1ZlnP@oCO|{#X#Bv zjNMLV+W{G&o-U3d9M_W*4zM_RIV|8v(U4|t6r8Z|5fh7_LtB=H01KmJR;I%QmXsCK znH_-=7a3W69onAxD9m6<$ym$O2Ll0cv3IboFyt=akR{01h5&qyPW_ literal 0 HcmV?d00001 diff --git a/include/images/type.pngc b/include/images/type.pngc new file mode 100644 index 0000000..ab654c7 --- /dev/null +++ b/include/images/type.pngc @@ -0,0 +1,85 @@ +#ifndef TYPE_PNG_H +#define TYPE_PNG_H + +static const unsigned char type_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x27, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x9e, 0xe0, 0xc4, 0x5a, +0xcb, 0x9a, 0xd6, 0xff, 0xea, 0xce, 0xff, 0xe5, +0xc5, 0xff, 0xe1, 0xba, 0xff, 0xdb, 0xac, 0xff, +0xd3, 0x9e, 0xff, 0xcc, 0x90, 0xff, 0xc5, 0x82, +0xff, 0xbd, 0x77, 0xff, 0xb7, 0x6e, 0xff, 0xb3, +0x65, 0x03, 0x10, 0x6b, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x55, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, +0x63, 0x60, 0xc0, 0x04, 0x42, 0x4a, 0x40, 0xa0, +0x08, 0x64, 0x28, 0x1b, 0x03, 0x81, 0x11, 0x90, +0xa1, 0xe2, 0x02, 0x04, 0x4e, 0x40, 0x86, 0x6a, +0x28, 0x10, 0x04, 0x01, 0x19, 0x6a, 0x69, 0x40, +0x90, 0x04, 0x64, 0xa8, 0x97, 0x03, 0x41, 0x11, +0x90, 0xa1, 0xd1, 0x01, 0x04, 0x4d, 0x40, 0x86, +0xe6, 0x4c, 0x20, 0x98, 0x04, 0x64, 0x68, 0xad, +0x02, 0x82, 0x45, 0x40, 0x86, 0xf6, 0x6e, 0x20, +0xd8, 0x04, 0x64, 0xe8, 0x9c, 0x01, 0x82, 0x43, +0x30, 0x2b, 0x14, 0xb0, 0xd8, 0x0d, 0x00, 0xcb, +0xbc, 0x1b, 0xb1, 0xe0, 0x4d, 0x88, 0x44, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *type_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_type_png = new wxImage(); + if (!img_type_png || !img_type_png->IsOk()) + { + wxMemoryInputStream img_type_pngIS(type_png_data, sizeof(type_png_data)); + img_type_png->LoadFile(img_type_pngIS, wxBITMAP_TYPE_PNG); + } + return img_type_png; +} +#define type_png_img type_png_img() + +static wxBitmap *type_png_bmp() +{ + static wxBitmap *bmp_type_png; + if (!bmp_type_png || !bmp_type_png->IsOk()) + bmp_type_png = new wxBitmap(*type_png_img); + return bmp_type_png; +} +#define type_png_bmp type_png_bmp() + +static wxIcon *type_png_ico() +{ + static wxIcon *ico_type_png; + if (!ico_type_png || !ico_type_png->IsOk()) + { + ico_type_png = new wxIcon(); + ico_type_png->CopyFromBitmap(*type_png_bmp); + } + return ico_type_png; +} +#define type_png_ico type_png_ico() + +#endif // TYPE_PNG_H diff --git a/include/images/types.png b/include/images/types.png new file mode 100644 index 0000000000000000000000000000000000000000..fb020d7d99f84439046d288615e865ee1fbdb815 GIT binary patch literal 329 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFv3GfMV1=3NcXI=aM>fHaQT@Q91 z`hS1R{~OExU!3;;MEm~(mH&6<{olN3-cDJdI>wS9zhDN3XE)M-9L@rd$YLPv0mg18 zv+aP47*7|+5RU7%XQO!=40zlgo^wo$EU!My#3j(ks*}LT9dUr^nFV*x`64!{5l*E!$tK_0oAjM#0U}&IgXryak7-D2#Wnye)VybOmYGq(B@15Q% q6b-rgDVb@N5Df;FU=2XkCRPS!5DllMhpqu?VDNPHb6Mw<&;$UZ$8*O3 literal 0 HcmV?d00001 diff --git a/include/images/types.pngc b/include/images/types.pngc new file mode 100644 index 0000000..6b5d965 --- /dev/null +++ b/include/images/types.pngc @@ -0,0 +1,86 @@ +#ifndef TYPES_PNG_H +#define TYPES_PNG_H + +static const unsigned char types_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x24, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x5a, 0xcb, 0x9a, 0xd6, +0xff, 0xea, 0xce, 0xff, 0xe5, 0x8a, 0xe0, 0xb9, +0xc2, 0xff, 0xdf, 0xb4, 0xff, 0xd8, 0xa6, 0xff, +0xd1, 0x96, 0xff, 0xc8, 0x87, 0xff, 0xc0, 0x79, +0xff, 0xb9, 0x6e, 0xff, 0xb3, 0xa2, 0x9e, 0xb9, +0x1d, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x5c, 0x49, +0x44, 0x41, 0x54, 0x08, 0xd7, 0x3d, 0xcd, 0x5b, +0x0d, 0x80, 0x30, 0x0c, 0x46, 0xe1, 0xce, 0x41, +0x61, 0x59, 0x77, 0x7b, 0xc3, 0x02, 0x0a, 0x10, +0x81, 0x05, 0x2c, 0x60, 0x01, 0x0b, 0x58, 0xc0, +0x02, 0xe6, 0x38, 0x0b, 0x8c, 0xef, 0xe9, 0xcf, +0x49, 0x9a, 0x8a, 0x1b, 0x20, 0x18, 0x27, 0x28, +0xc3, 0x2f, 0x5f, 0x0a, 0x3d, 0x59, 0x4f, 0xb1, +0xa7, 0x64, 0x7e, 0x86, 0x4a, 0x8e, 0x61, 0x85, +0x4a, 0x49, 0xb6, 0x41, 0xa5, 0xe6, 0xb8, 0x43, +0xc5, 0x95, 0x74, 0x80, 0xfb, 0x9a, 0x4f, 0x30, +0x5c, 0xb9, 0xd0, 0x9e, 0xd4, 0x1b, 0x6d, 0xfc, +0xff, 0x5f, 0x0f, 0x09, 0xd3, 0x15, 0xf2, 0x10, +0xf1, 0x85, 0x33, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *types_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_types_png = new wxImage(); + if (!img_types_png || !img_types_png->IsOk()) + { + wxMemoryInputStream img_types_pngIS(types_png_data, sizeof(types_png_data)); + img_types_png->LoadFile(img_types_pngIS, wxBITMAP_TYPE_PNG); + } + return img_types_png; +} +#define types_png_img types_png_img() + +static wxBitmap *types_png_bmp() +{ + static wxBitmap *bmp_types_png; + if (!bmp_types_png || !bmp_types_png->IsOk()) + bmp_types_png = new wxBitmap(*types_png_img); + return bmp_types_png; +} +#define types_png_bmp types_png_bmp() + +static wxIcon *types_png_ico() +{ + static wxIcon *ico_types_png; + if (!ico_types_png || !ico_types_png->IsOk()) + { + ico_types_png = new wxIcon(); + ico_types_png->CopyFromBitmap(*types_png_bmp); + } + return ico_types_png; +} +#define types_png_ico types_png_ico() + +#endif // TYPES_PNG_H diff --git a/include/images/uncheck.png b/include/images/uncheck.png new file mode 100644 index 0000000000000000000000000000000000000000..b655bc72e65484fadfbde6006d73a14c9639da6b GIT binary patch literal 617 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf=K!A&S0H`#(!!-X^EMo;zj|*^ z;bigtZRShP`prG+e*E&1rWIOiZiH{V8{57{|IGEZTOTLYEKojob7R*g!#T%Y7oYc8 zb3Nkl$AbFB>g{XwH{Oexcii(%O88L*hO4pmmtyU9+lbsvOZrw`elgnYV|e)8%*=0P zW#5X5zUJk<_xFG2;ko``-QD!0uerHjGBQ3VC4C4Dz4PSw=fuR1(a|4*L*D!Py>oZJ zndJ4}*Y`@C+lS!b_dY)FTwUMT*}t~1_z)EI-rM`Fi|cE1^H+w3FSWHl1O~qI@_Os+ zav{q2g{tav1%<28-fx|pPY3Bdmsi+hCw?l>=5~6@8;xa#KyNda1o;IsI6S+N2IO!S zctjQhX%8@VJDF_P?mWZJuRM zx-(gEQ_5!R7ydHuOLqPj>VF_wd*-)nnRKC(!<42q+^x!f^ZJiHiq9A5Tw<=OoO?$y z#Xc}VsQAQU2NqV>$z6*>)-`ynyq3ULD%zXIoqO20$;xQg-hT-v%zSz;$nzWitdzWb zvu5KTL9MXYyxXkL-a7EFpoQ;kNm~4iChd}45Ay`S7|d3W`@;6)oG@p&s`O5v!&OUM zBT7;dOH!?pi&B9UgOP!up{@ZCnT8lzSQ%Ja85?OEm{}PZ9Pcn|L(!0%pOTqYiCe?A St9@2L4Gf;HelF{r5}E)dg8p#; literal 0 HcmV?d00001 diff --git a/include/images/uncheck.pngc b/include/images/uncheck.pngc new file mode 100644 index 0000000..c5e5d2d --- /dev/null +++ b/include/images/uncheck.pngc @@ -0,0 +1,122 @@ +#ifndef UNCHECK_PNG_H +#define UNCHECK_PNG_H + +static const unsigned char uncheck_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xf3, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc5, 0xd2, 0xa1, 0xa5, +0xb9, 0x6e, 0xb0, 0xc1, 0x7f, 0xd5, 0xde, 0xbc, +0x71, 0x93, 0x17, 0x8f, 0xb6, 0x37, 0xa4, 0xcd, +0x4e, 0x9d, 0xc5, 0x47, 0xc7, 0xd3, 0xa4, 0x82, +0xa8, 0x2a, 0xac, 0xd8, 0x57, 0xb1, 0xdd, 0x5d, +0x87, 0xac, 0x2f, 0xcc, 0xd7, 0xad, 0xb5, 0xe3, +0x62, 0x7c, 0xa0, 0x23, 0xce, 0xd9, 0xb1, 0x8a, +0xb2, 0x31, 0x9c, 0xc7, 0x45, 0xa3, 0xcf, 0x4c, +0xac, 0xd7, 0x58, 0xc3, 0xf1, 0x70, 0x7f, 0xa3, +0x27, 0x87, 0xad, 0x2f, 0xb1, 0xde, 0x5c, 0x9e, +0xc7, 0x49, 0xdc, 0x64, 0x57, 0xc5, 0x00, 0x00, +0xd5, 0x5d, 0x3f, 0xd2, 0x5d, 0x3e, 0xbb, 0x3c, +0x14, 0xdd, 0x66, 0x62, 0xf6, 0x77, 0x77, 0xd1, +0x5b, 0x36, 0xf1, 0x57, 0x57, 0xdd, 0x69, 0x69, +0xf6, 0x76, 0x76, 0xf6, 0x72, 0x72, 0xf5, 0x6e, +0x6e, 0xef, 0x4f, 0x4f, 0xee, 0x48, 0x49, 0xaf, +0xc1, 0x7e, 0xdd, 0x67, 0x62, 0xf5, 0x6d, 0x6d, +0xf4, 0x68, 0x68, 0xf3, 0x62, 0x62, 0xf0, 0x55, +0x55, 0xdc, 0xe4, 0xc7, 0xf3, 0x61, 0x61, 0xf1, +0x5b, 0x5b, 0xf0, 0x53, 0x54, 0xef, 0x4d, 0x4e, +0xee, 0x47, 0x47, 0xd9, 0x62, 0x4a, 0xef, 0x4d, +0x4d, 0xd4, 0x5e, 0x46, 0xf0, 0x53, 0x53, 0xef, +0x4c, 0x4c, 0xee, 0x45, 0x45, 0xec, 0x3e, 0x3f, +0xeb, 0x38, 0x38, 0xf0, 0x52, 0x52, 0xef, 0x4b, +0x4b, 0xed, 0x44, 0x45, 0xeb, 0x37, 0x37, 0xea, +0x31, 0x31, 0xe9, 0x2b, 0x2b, 0xf0, 0x51, 0x51, +0xee, 0x4a, 0x4a, 0xed, 0x43, 0x44, 0xd0, 0x5a, +0x33, 0xe8, 0x25, 0x25, 0xe7, 0x20, 0x20, 0xd5, +0x5b, 0x4b, 0xed, 0x42, 0x43, 0xcb, 0x52, 0x2c, +0xe7, 0x1f, 0x20, 0xbc, 0x3e, 0x17, 0xca, 0x51, +0x3c, 0xdb, 0x67, 0x64, 0xec, 0x28, 0xa6, 0x31, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0xad, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x4d, 0x8d, 0x57, 0x16, +0x82, 0x50, 0x10, 0x43, 0x47, 0x05, 0x0b, 0xa2, +0x62, 0x2f, 0xc4, 0x8a, 0x1d, 0x7b, 0xef, 0x0d, +0x15, 0xbb, 0xee, 0x7f, 0x35, 0x22, 0x4f, 0x3c, +0xe6, 0x6b, 0x92, 0xdc, 0x93, 0x21, 0xb2, 0x64, +0xb3, 0x3b, 0xe8, 0x4f, 0x1c, 0xef, 0x74, 0xb9, +0xff, 0x12, 0x8f, 0xe0, 0x15, 0x7d, 0xcc, 0xfb, +0x1d, 0x76, 0x1b, 0x71, 0x42, 0x40, 0x94, 0x82, +0xac, 0x0b, 0x85, 0x23, 0x4e, 0x9e, 0x8f, 0xc6, +0xe2, 0x5f, 0x6f, 0x10, 0x89, 0xa4, 0x37, 0x25, +0x23, 0x6d, 0xdc, 0x19, 0x64, 0x3f, 0x51, 0x50, +0x12, 0x73, 0xc8, 0xa3, 0x40, 0x04, 0x05, 0x45, +0x93, 0x8a, 0xa3, 0x54, 0xae, 0x80, 0x48, 0xa9, +0xd6, 0x60, 0x06, 0x75, 0x15, 0x8d, 0x66, 0x0b, +0x6d, 0xc3, 0x33, 0x82, 0x3a, 0x32, 0xba, 0xbd, +0xfe, 0x60, 0xc8, 0x36, 0x4c, 0x8d, 0xd0, 0x1f, +0x0f, 0x31, 0xf9, 0x79, 0x19, 0xd3, 0xd9, 0x7c, +0xb1, 0xfc, 0x11, 0x2a, 0x56, 0xeb, 0x0d, 0xb6, +0x3b, 0xcd, 0xda, 0xc0, 0xfe, 0x70, 0x84, 0x0e, +0xed, 0x74, 0x66, 0x5f, 0xe8, 0x82, 0x2b, 0x74, +0xba, 0xe1, 0x6e, 0x11, 0xf4, 0x30, 0x9b, 0x27, +0x5e, 0xf4, 0x06, 0xf8, 0xce, 0x13, 0x09, 0x57, +0x25, 0x1b, 0xb9, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x31, 0x2d, 0x30, 0x31, 0x2d, 0x30, +0x35, 0x54, 0x31, 0x38, 0x3a, 0x30, 0x39, 0x3a, +0x33, 0x32, 0x2b, 0x30, 0x36, 0x3a, 0x30, 0x30, +0xc7, 0x88, 0x36, 0x86, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x31, 0x2d, 0x30, 0x31, 0x2d, +0x30, 0x35, 0x54, 0x31, 0x38, 0x3a, 0x30, 0x39, +0x3a, 0x33, 0x32, 0x2b, 0x30, 0x36, 0x3a, 0x30, +0x30, 0xb6, 0xd5, 0x8e, 0x3a, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *uncheck_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_uncheck_png = new wxImage(); + if (!img_uncheck_png || !img_uncheck_png->IsOk()) + { + wxMemoryInputStream img_uncheck_pngIS(uncheck_png_data, sizeof(uncheck_png_data)); + img_uncheck_png->LoadFile(img_uncheck_pngIS, wxBITMAP_TYPE_PNG); + } + return img_uncheck_png; +} +#define uncheck_png_img uncheck_png_img() + +static wxBitmap *uncheck_png_bmp() +{ + static wxBitmap *bmp_uncheck_png; + if (!bmp_uncheck_png || !bmp_uncheck_png->IsOk()) + bmp_uncheck_png = new wxBitmap(*uncheck_png_img); + return bmp_uncheck_png; +} +#define uncheck_png_bmp uncheck_png_bmp() + +static wxIcon *uncheck_png_ico() +{ + static wxIcon *ico_uncheck_png; + if (!ico_uncheck_png || !ico_uncheck_png->IsOk()) + { + ico_uncheck_png = new wxIcon(); + ico_uncheck_png->CopyFromBitmap(*uncheck_png_bmp); + } + return ico_uncheck_png; +} +#define uncheck_png_ico uncheck_png_ico() + +#endif // UNCHECK_PNG_H diff --git a/include/images/unchecked.png b/include/images/unchecked.png new file mode 100644 index 0000000000000000000000000000000000000000..7573ac714c05f3cd88e4bf6d35d78f796f2c170f GIT binary patch literal 267 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPHV5AX?b1=0--4gdfDcW`jHa^ZyF z@;B^2A;yv*zhDN3XE)M7oFs2|7p64sniL?1v%n*=7)X17vD?XPJ0L^N)5S4_<9c$! z0fwF?1qGHAiRK3335iQsSgxe(XkeIda0v?=$7x1a7oM-j`Mbq|I#f$sBT7;dOH!?p zi&B9UgOP!up{{|UuAxzgp^24&ft87Ywt*Rt;ilBT5k*68eoAIqB}jvTu7M>`Pl%DR el?hOfnYMu`P{XO|p=*E|7(8A5T-G@yGywqN_DDVe literal 0 HcmV?d00001 diff --git a/include/images/unchecked.pngc b/include/images/unchecked.pngc new file mode 100644 index 0000000..2dd8371 --- /dev/null +++ b/include/images/unchecked.pngc @@ -0,0 +1,78 @@ +#ifndef UNCHECKED_PNG_H +#define UNCHECKED_PNG_H + +static const unsigned char unchecked_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x0f, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0xff, +0xff, 0xff, 0x40, 0x40, 0x40, 0xd4, 0xd0, 0xc8, +0x11, 0xa7, 0xec, 0x07, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, +0x44, 0x02, 0x66, 0x0b, 0x7c, 0x64, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x26, 0x49, +0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0x60, 0xc0, +0x00, 0x8c, 0x82, 0x20, 0x20, 0x04, 0x64, 0x18, +0x83, 0x80, 0x13, 0x90, 0x61, 0xa4, 0x04, 0x04, +0xd4, 0x64, 0xb8, 0x80, 0x00, 0x90, 0xc1, 0xa4, +0x04, 0x06, 0x08, 0xcb, 0x01, 0x45, 0x44, 0x0c, +0xf5, 0xc7, 0x0f, 0x8b, 0x17, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x31, 0x2d, 0x30, 0x31, +0x2d, 0x31, 0x32, 0x54, 0x31, 0x34, 0x3a, 0x30, +0x30, 0x3a, 0x34, 0x30, 0x2b, 0x30, 0x36, 0x3a, +0x30, 0x30, 0x46, 0x22, 0x8f, 0xb1, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *unchecked_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_unchecked_png = new wxImage(); + if (!img_unchecked_png || !img_unchecked_png->IsOk()) + { + wxMemoryInputStream img_unchecked_pngIS(unchecked_png_data, sizeof(unchecked_png_data)); + img_unchecked_png->LoadFile(img_unchecked_pngIS, wxBITMAP_TYPE_PNG); + } + return img_unchecked_png; +} +#define unchecked_png_img unchecked_png_img() + +static wxBitmap *unchecked_png_bmp() +{ + static wxBitmap *bmp_unchecked_png; + if (!bmp_unchecked_png || !bmp_unchecked_png->IsOk()) + bmp_unchecked_png = new wxBitmap(*unchecked_png_img); + return bmp_unchecked_png; +} +#define unchecked_png_bmp unchecked_png_bmp() + +static wxIcon *unchecked_png_ico() +{ + static wxIcon *ico_unchecked_png; + if (!ico_unchecked_png || !ico_unchecked_png->IsOk()) + { + ico_unchecked_png = new wxIcon(); + ico_unchecked_png->CopyFromBitmap(*unchecked_png_bmp); + } + return ico_unchecked_png; +} +#define unchecked_png_ico unchecked_png_ico() + +#endif // UNCHECKED_PNG_H diff --git a/include/images/unique.png b/include/images/unique.png new file mode 100644 index 0000000000000000000000000000000000000000..e82857235ed1d5bb351b981c447ec3370d495fa9 GIT binary patch literal 422 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}V}MVHE0AtpdP65|Z{ONGc?&PK z9lkT?%wyl?6GdCEg|9qcv+MTqD^L55-OJi^HFW8P+MRbYmt2Wha=CWfUF*U_tvl~U zF1%W|<$g;4`J&}FqUK+(-}In$+k@yiHybuQDqDIhZuaelb&vDr-HMxer)=5dRj1!9 zI{IqDj_1wmp7v~dv0(q3HOJoP31mnB9l=-<+NGIBA*;;oEjPCQ(Bz!3V!CK3^T!Lkmz5Z{ zJ+895(X7z(qO)VNNwR|esV?IU#U}a)#Wn!vrU}|MxFz=n-DijU5 n`6-!cl@JXEmS7D))h1R3W)KahriZQpYGCkm^>bP0l+XkKGQ6yC literal 0 HcmV?d00001 diff --git a/include/images/unique.pngc b/include/images/unique.pngc new file mode 100644 index 0000000..3614582 --- /dev/null +++ b/include/images/unique.pngc @@ -0,0 +1,97 @@ +#ifndef UNIQUE_PNG_H +#define UNIQUE_PNG_H + +static const unsigned char unique_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x81, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x83, 0xa5, 0xd8, 0x2c, +0x66, 0xbd, 0x8e, 0xad, 0xdc, 0x6e, 0xa1, 0xd2, +0x86, 0xc3, 0xdc, 0x9c, 0xcc, 0xe3, 0x4d, 0x83, +0xc8, 0x72, 0xb5, 0xd6, 0x57, 0xa9, 0xcf, 0x7c, +0xba, 0xdb, 0xa7, 0xd4, 0xe5, 0x8e, 0xc6, 0xde, +0x6a, 0xb2, 0xd5, 0x55, 0xa5, 0xd0, 0x7d, 0xb9, +0xdc, 0x69, 0xa4, 0xd4, 0x58, 0xa4, 0xd3, 0x7d, +0xb6, 0xdd, 0x3b, 0x71, 0xc2, 0x85, 0xb9, 0xde, +0x59, 0xa1, 0xd5, 0x7e, 0xb4, 0xdf, 0x64, 0x8f, +0xcf, 0x72, 0xa7, 0xd8, 0x5a, 0x9f, 0xd7, 0x7f, +0xb2, 0xe0, 0x85, 0xb6, 0xe0, 0x5b, 0x9c, 0xd9, +0x80, 0xb0, 0xe2, 0x76, 0xa5, 0xda, 0x5e, 0x9b, +0xdb, 0x80, 0xae, 0xe3, 0x6e, 0x9e, 0xda, 0x5e, +0x99, 0xdc, 0x76, 0xa6, 0xe3, 0xaa, 0xcb, 0xec, +0xa2, 0xc5, 0xea, 0x90, 0xb8, 0xe7, 0x83, 0xae, +0xe5, 0x8c, 0xb2, 0xe8, 0xa0, 0xbf, 0xec, 0xac, +0xc6, 0xef, 0x6e, 0x10, 0x68, 0x18, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x5c, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x8d, 0x8e, 0x35, 0x0e, 0xc0, 0x50, +0x0c, 0x43, 0x7f, 0x5d, 0x66, 0x66, 0x66, 0xb8, +0xff, 0x01, 0x2b, 0x75, 0x69, 0x32, 0x54, 0xaa, +0x37, 0x3f, 0x39, 0xb1, 0x85, 0xf8, 0x29, 0x09, +0x90, 0xa8, 0x97, 0x15, 0x55, 0x03, 0xf1, 0xd0, +0x0d, 0xd3, 0x22, 0x00, 0xb6, 0xe3, 0x7a, 0x3e, +0xd8, 0x83, 0x20, 0x8c, 0xe8, 0x89, 0x88, 0x93, +0x34, 0x63, 0x20, 0x2f, 0xca, 0x8a, 0x27, 0xea, +0xa6, 0xe5, 0x89, 0xae, 0x1f, 0x58, 0x2d, 0xc6, +0x69, 0xc6, 0x4b, 0xb0, 0xac, 0xdb, 0x7e, 0x9c, +0x17, 0x48, 0xed, 0x23, 0x36, 0xfe, 0x5b, 0x37, +0xa9, 0x13, 0x03, 0xea, 0x7a, 0x3c, 0xc8, 0x3c, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, +0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *unique_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_unique_png = new wxImage(); + if (!img_unique_png || !img_unique_png->IsOk()) + { + wxMemoryInputStream img_unique_pngIS(unique_png_data, sizeof(unique_png_data)); + img_unique_png->LoadFile(img_unique_pngIS, wxBITMAP_TYPE_PNG); + } + return img_unique_png; +} +#define unique_png_img unique_png_img() + +static wxBitmap *unique_png_bmp() +{ + static wxBitmap *bmp_unique_png; + if (!bmp_unique_png || !bmp_unique_png->IsOk()) + bmp_unique_png = new wxBitmap(*unique_png_img); + return bmp_unique_png; +} +#define unique_png_bmp unique_png_bmp() + +static wxIcon *unique_png_ico() +{ + static wxIcon *ico_unique_png; + if (!ico_unique_png || !ico_unique_png->IsOk()) + { + ico_unique_png = new wxIcon(); + ico_unique_png->CopyFromBitmap(*unique_png_bmp); + } + return ico_unique_png; +} +#define unique_png_ico unique_png_ico() + +#endif // UNIQUE_PNG_H diff --git a/include/images/up.png b/include/images/up.png new file mode 100644 index 0000000000000000000000000000000000000000..9c0e0a7554d5c4bf4e30ccbf8a0c78da7d82e0d1 GIT binary patch literal 389 zcmeAS@N?(olHy`uVBq!ia0vp@K+M6x3?xN=wEhKBMFBn`u0XnbV`9{7;WPIa@4DQ$ z^k~$!ixs;rH_todKW&fg?ETJL&KK;u(melA;IzGVQ+8WS+G#j_kHyBbnY*sE&OaPH zeXqmR-IkMf8Bf@u)3;r1%5MGjXHw2RSib38;fAw0>rSVyJ)N}rWZbF~Q7cb`tv{1| z^j7Z|Nx2U|TNz7&{DK)Ap4~_TaySb-B8!2v2N=7Z%(eqEygXeTLpZLxo($(}P+(vQ zEIWFy`hC@ZZ7#!8fA;nWSP4Ah-@@aVX)W(~{d4mNRf(gXv!1r9MTC`JF8gbsRW#}I zro7*UapqTzA2O!;GyRX;BXtpIs%nXAL`h0wNvc(HQ7VvPFfuSS)HN{FH8Kq`G_^7? zw=y=14T?2~{14AnVV=Gfjh=z<~lX-v|7(8A5 KT-G@yGywqFK$Rf? literal 0 HcmV?d00001 diff --git a/include/images/up.pngc b/include/images/up.pngc new file mode 100644 index 0000000..0cd6466 --- /dev/null +++ b/include/images/up.pngc @@ -0,0 +1,93 @@ +#ifndef UP_PNG_H +#define UP_PNG_H + +static const unsigned char up_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x08, +0x08, 0x03, 0x00, 0x00, 0x00, 0x15, 0xf8, 0x85, +0xfd, 0x00, 0x00, 0x00, 0x72, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x61, 0x5a, +0x9b, 0x13, 0xcc, 0xdf, 0xa3, 0xba, 0xd3, 0x81, +0xa5, 0xc5, 0x5a, 0xb6, 0xd1, 0x78, 0xba, 0xd3, +0x83, 0x9e, 0xc2, 0x4f, 0x96, 0xbc, 0x3d, 0x9b, +0xbf, 0x43, 0xb4, 0xcf, 0x70, 0xba, 0xd4, 0x83, +0x9f, 0xc2, 0x51, 0x96, 0xbd, 0x3e, 0x94, 0xbb, +0x38, 0x92, 0xb9, 0x31, 0x97, 0xbc, 0x38, 0xb1, +0xcd, 0x69, 0xba, 0xd4, 0x85, 0x9f, 0xc3, 0x53, +0x97, 0xbd, 0x40, 0x95, 0xbb, 0x39, 0x92, 0xba, +0x33, 0x90, 0xb8, 0x2c, 0x8e, 0xb7, 0x26, 0x94, +0xbb, 0x2f, 0xaf, 0xcc, 0x64, 0xce, 0xe0, 0xa7, +0xb2, 0xce, 0x71, 0xb0, 0xcd, 0x6c, 0xae, 0xcb, +0x67, 0xad, 0xcb, 0x62, 0xab, 0xc9, 0x5e, 0xaa, +0xc8, 0x5a, 0xa9, 0xc8, 0x56, 0xaf, 0xcc, 0x63, +0xc5, 0xda, 0x8d, 0xf4, 0x19, 0x1e, 0xf0, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x4a, 0x49, 0x44, 0x41, +0x54, 0x08, 0xd7, 0x45, 0xc9, 0x57, 0x0e, 0x80, +0x20, 0x00, 0x04, 0x51, 0x76, 0xc5, 0xde, 0x7b, +0xef, 0x7a, 0xff, 0x2b, 0x0a, 0x31, 0xca, 0xfc, +0xbd, 0x8c, 0x10, 0x3a, 0x10, 0xe2, 0x0f, 0xb4, +0x0c, 0x41, 0x69, 0x3b, 0x1f, 0x41, 0xd7, 0xf3, +0x83, 0xf0, 0x25, 0x18, 0xc5, 0x49, 0x9a, 0xe5, +0x85, 0x26, 0x58, 0x56, 0x75, 0xd3, 0x76, 0xfd, +0x30, 0x2a, 0x72, 0x92, 0xf3, 0xb2, 0x6e, 0xfb, +0x71, 0x5e, 0x37, 0xd5, 0x33, 0xe1, 0x01, 0x65, +0x4f, 0x02, 0xff, 0x59, 0xbc, 0x1a, 0xd1, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x31, 0x2d, +0x30, 0x31, 0x2d, 0x32, 0x35, 0x54, 0x31, 0x35, +0x3a, 0x30, 0x37, 0x3a, 0x33, 0x36, 0x2b, 0x30, +0x36, 0x3a, 0x30, 0x30, 0xbe, 0x1e, 0xd2, 0x9f, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x38, 0x54, 0x30, +0x31, 0x3a, 0x30, 0x33, 0x3a, 0x35, 0x39, 0x2b, +0x30, 0x36, 0x3a, 0x30, 0x30, 0x68, 0xc6, 0x93, +0x0c, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *up_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_up_png = new wxImage(); + if (!img_up_png || !img_up_png->IsOk()) + { + wxMemoryInputStream img_up_pngIS(up_png_data, sizeof(up_png_data)); + img_up_png->LoadFile(img_up_pngIS, wxBITMAP_TYPE_PNG); + } + return img_up_png; +} +#define up_png_img up_png_img() + +static wxBitmap *up_png_bmp() +{ + static wxBitmap *bmp_up_png; + if (!bmp_up_png || !bmp_up_png->IsOk()) + bmp_up_png = new wxBitmap(*up_png_img); + return bmp_up_png; +} +#define up_png_bmp up_png_bmp() + +static wxIcon *up_png_ico() +{ + static wxIcon *ico_up_png; + if (!ico_up_png || !ico_up_png->IsOk()) + { + ico_up_png = new wxIcon(); + ico_up_png->CopyFromBitmap(*up_png_bmp); + } + return ico_up_png; +} +#define up_png_ico up_png_ico() + +#endif // UP_PNG_H diff --git a/include/images/user.png b/include/images/user.png new file mode 100644 index 0000000000000000000000000000000000000000..ef54e88ad5ed7543fe5cbc287ecd997a470026bd GIT binary patch literal 557 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMf`2e2~S0Fue=FF_Dti5~p)>V~n zU$^|pjdM?KT-dg5Rb5r(^)rWmyt@D6)x+czHo>%PBw z_4vlE@2}oGzH$5et9RShZM=5oLTyz|bWBWCOiWg8?y@c0w;Vm$K4Ef7dPZ`3Mswff z75h)kT)RCrJ2xsSYVn56S6+R%`0~TK=O0c#`*{4x$0LtF9(?$5?}Lw%R&0rgif-=e z*>&&J_Pd|TTYIKVnX+{A_APflO<1)fFE4NZ<(r#se_DL(c0@$PnWyhI-ukrR#)r_* zP}ZdzDuG^NED7=pW^j0RBMr#mEbxdd2GSm2>~=ES4#=45>Eak7aoP3kOQC}XB5e;< z?&j)-hPuA}y-&<_!tecRo<4o=?|(iw$CBe@qLaZd|I56WH_7rg%{wjLrFuR1SX;r) zN2|4yyuz6mHL1pOhaT8gV%y~2r+ug6q4(v_%?4f3r`|5P{PrvR;fp_>pDZzp*9m`p zwruIsOk()) + { + wxMemoryInputStream img_user_pngIS(user_png_data, sizeof(user_png_data)); + img_user_png->LoadFile(img_user_pngIS, wxBITMAP_TYPE_PNG); + } + return img_user_png; +} +#define user_png_img user_png_img() + +static wxBitmap *user_png_bmp() +{ + static wxBitmap *bmp_user_png; + if (!bmp_user_png || !bmp_user_png->IsOk()) + bmp_user_png = new wxBitmap(*user_png_img); + return bmp_user_png; +} +#define user_png_bmp user_png_bmp() + +static wxIcon *user_png_ico() +{ + static wxIcon *ico_user_png; + if (!ico_user_png || !ico_user_png->IsOk()) + { + ico_user_png = new wxIcon(); + ico_user_png->CopyFromBitmap(*user_png_bmp); + } + return ico_user_png; +} +#define user_png_ico user_png_ico() + +#endif // USER_PNG_H diff --git a/include/images/usermapping-sm.png b/include/images/usermapping-sm.png new file mode 100644 index 0000000000000000000000000000000000000000..e768c9bfc0b3e55f32f12bd037b7ecd52a9e430f GIT binary patch literal 518 zcmV+h0{Q)kP)Px#%uq~JMYgW7nVFetYHGc`y?%Okx2~t;*v{nG(6+9setLP=%)|KV-}vg`_v+&J z>g3nV$$olz_v+^N>gcwvuJ`Kdg?m#+xP13*38g-dVE`4Tv}XQYHe+%w70ay z$%l}WWM^n&XJ~_tlc>MSnXR{FYi(LuTBESD)avlj>G00y@XO}$$K>(Ej zlBl#;T3dsPjJn?Px83r0g^ZMxl%=z`wA}KLs<>`$ZokvnvfJ{b#@kp}Sj^?_vD)&m z*zi?VRXL11s{jB10d!JMQvg8b*k%9#00Cl4M??UK1szBL000SaNLh0L01FcU01FcV z0GgZ_00007bV*G`2ipV@5d#koeph1v005>*L_t&-(?!kO4#FS|fMH-~Pn%P*iBT^d z+q^Q1rW!`z{ol#5$n4$!g%-x9;X-ispD0e!EH9!N;>B{c-jr2np7`F@yRaqFsrLsF zAe&kq1Mu88qSg45qO4H^7yxJ{I91dZkpO(3FIV(!!44j7jY3O307x(d57nZQh}s&E z1kYF7p#nhkhc#pGPuJ6P+M%lheLR}}-sr(Mk}~E-=N!)S1$}xN(oSpy>i_@%07*qo IM6N<$g7m}xI{*Lx literal 0 HcmV?d00001 diff --git a/include/images/usermapping-sm.pngc b/include/images/usermapping-sm.pngc new file mode 100644 index 0000000..7d7bfff --- /dev/null +++ b/include/images/usermapping-sm.pngc @@ -0,0 +1,109 @@ +#ifndef USERMAPPING_SM_PNG_H +#define USERMAPPING_SM_PNG_H + +static const unsigned char usermapping_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0xcc, 0x50, 0x4c, 0x54, 0x45, 0xb6, 0xae, +0xb1, 0x99, 0x99, 0x99, 0x6a, 0x6a, 0x6a, 0xbd, +0xbd, 0xbd, 0x7e, 0x7a, 0x77, 0xb7, 0xae, 0xa7, +0xe4, 0xd8, 0xce, 0xe4, 0xd8, 0xd0, 0xb6, 0xae, +0xaa, 0x7e, 0x7a, 0x79, 0xd7, 0xcc, 0xc3, 0xf8, +0xea, 0xdf, 0xf8, 0xea, 0xe1, 0xf7, 0xea, 0xe2, +0xf7, 0xea, 0xe4, 0xd7, 0xcc, 0xc9, 0x7e, 0x7a, +0x7a, 0xf7, 0xea, 0xe6, 0xf7, 0xea, 0xe8, 0xb6, +0xae, 0xae, 0xf7, 0xea, 0xea, 0xe3, 0xd8, 0xda, +0xf7, 0xea, 0xec, 0xe3, 0xd8, 0xdb, 0xf7, 0xea, +0xee, 0xd6, 0xcc, 0xd0, 0x7d, 0x7a, 0x7c, 0x5b, +0x5c, 0x5c, 0x5a, 0x5c, 0x5c, 0x6a, 0x6d, 0x6d, +0xa6, 0xb4, 0xb7, 0xb4, 0xc5, 0xc9, 0x87, 0x90, +0x93, 0x64, 0x67, 0x68, 0x63, 0x67, 0x68, 0x83, +0x8e, 0x93, 0xa8, 0xbf, 0xca, 0x99, 0xad, 0xb7, +0x65, 0x6b, 0x6d, 0x5a, 0x5a, 0x5a, 0xa3, 0xb0, +0xb3, 0xd4, 0xea, 0xf0, 0xd1, 0xe9, 0xf0, 0xce, +0xe7, 0xf0, 0xcb, 0xe6, 0xf1, 0xc7, 0xe4, 0xf1, +0xc4, 0xe3, 0xf1, 0xc1, 0xe1, 0xf1, 0xbd, 0xe0, +0xf1, 0x92, 0xa8, 0xb4, 0x58, 0x5a, 0x5b, 0x83, +0x8a, 0x8c, 0xba, 0xde, 0xf2, 0xb7, 0xdd, 0xf2, +0x77, 0x85, 0x8c, 0x94, 0x94, 0x94, 0xa5, 0xb3, +0xb7, 0xb4, 0xdc, 0xf2, 0x90, 0xaa, 0xb8, 0x6e, +0x6e, 0x6e, 0xbf, 0xd3, 0xd9, 0xb2, 0xdb, 0xf2, +0xa3, 0xc6, 0xdb, 0x58, 0x58, 0x58, 0xcc, 0xe5, +0xee, 0xb1, 0xda, 0xf2, 0xb0, 0xd8, 0xf0, 0x55, +0x55, 0x55, 0x39, 0x8c, 0x3b, 0xab, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, 0x62, +0x4b, 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x04, +0x11, 0x11, 0x03, 0x0f, 0x0f, 0x7e, 0x57, 0x63, +0x00, 0x00, 0x00, 0xa6, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x45, 0xcd, 0xdb, 0x0e, 0xc2, 0x20, +0x0c, 0x80, 0x61, 0x60, 0x67, 0x4f, 0x9b, 0x53, +0xb1, 0x89, 0x51, 0x2f, 0x1d, 0xdb, 0xbc, 0x32, +0x8b, 0xa6, 0x1a, 0x46, 0xe0, 0xfd, 0xdf, 0xc9, +0xb2, 0xc8, 0xec, 0xdd, 0xff, 0x85, 0x16, 0xc6, +0xa6, 0xe1, 0x42, 0x70, 0xf6, 0x9f, 0x28, 0x4e, +0xd2, 0x2c, 0x2f, 0xa2, 0x19, 0xe2, 0xc5, 0x72, +0xb5, 0xde, 0x94, 0x55, 0x68, 0x9e, 0xf8, 0xde, +0xd6, 0xbb, 0xb0, 0x25, 0xd2, 0xa9, 0xf7, 0x07, +0x11, 0x20, 0x9b, 0x5a, 0x1e, 0x03, 0xf0, 0xdc, +0x37, 0xa2, 0xd5, 0xf8, 0x93, 0xa2, 0xac, 0x51, +0x03, 0x18, 0x00, 0x68, 0x26, 0x38, 0x55, 0xd4, +0x16, 0x91, 0x00, 0x7c, 0x9f, 0x2f, 0x57, 0xf4, +0x6d, 0xc1, 0x0e, 0x1e, 0x6e, 0x8d, 0x42, 0x4b, +0x3d, 0x00, 0x48, 0x30, 0x04, 0x0f, 0xd5, 0xa2, +0x92, 0x88, 0xda, 0x1a, 0x90, 0x04, 0xcf, 0x57, +0xdb, 0xa1, 0x02, 0x40, 0xf4, 0x87, 0x35, 0x63, +0xef, 0x4f, 0xd7, 0xd3, 0x73, 0xda, 0xa1, 0xab, +0x03, 0x7d, 0x3c, 0x9a, 0xfe, 0xde, 0xe8, 0xc1, +0x37, 0x92, 0x32, 0xe6, 0x46, 0xe7, 0x1c, 0xce, +0xf3, 0x05, 0x7d, 0x7a, 0x1a, 0xd2, 0x4e, 0x6c, +0x04, 0xeb, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *usermapping_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_usermapping_sm_png = new wxImage(); + if (!img_usermapping_sm_png || !img_usermapping_sm_png->IsOk()) + { + wxMemoryInputStream img_usermapping_sm_pngIS(usermapping_sm_png_data, sizeof(usermapping_sm_png_data)); + img_usermapping_sm_png->LoadFile(img_usermapping_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_usermapping_sm_png; +} +#define usermapping_sm_png_img usermapping_sm_png_img() + +static wxBitmap *usermapping_sm_png_bmp() +{ + static wxBitmap *bmp_usermapping_sm_png; + if (!bmp_usermapping_sm_png || !bmp_usermapping_sm_png->IsOk()) + bmp_usermapping_sm_png = new wxBitmap(*usermapping_sm_png_img); + return bmp_usermapping_sm_png; +} +#define usermapping_sm_png_bmp usermapping_sm_png_bmp() + +static wxIcon *usermapping_sm_png_ico() +{ + static wxIcon *ico_usermapping_sm_png; + if (!ico_usermapping_sm_png || !ico_usermapping_sm_png->IsOk()) + { + ico_usermapping_sm_png = new wxIcon(); + ico_usermapping_sm_png->CopyFromBitmap(*usermapping_sm_png_bmp); + } + return ico_usermapping_sm_png; +} +#define usermapping_sm_png_ico usermapping_sm_png_ico() + +#endif // USERMAPPING_SM_PNG_H diff --git a/include/images/usermapping.png b/include/images/usermapping.png new file mode 100644 index 0000000000000000000000000000000000000000..e768c9bfc0b3e55f32f12bd037b7ecd52a9e430f GIT binary patch literal 518 zcmV+h0{Q)kP)Px#%uq~JMYgW7nVFetYHGc`y?%Okx2~t;*v{nG(6+9setLP=%)|KV-}vg`_v+&J z>g3nV$$olz_v+^N>gcwvuJ`Kdg?m#+xP13*38g-dVE`4Tv}XQYHe+%w70ay z$%l}WWM^n&XJ~_tlc>MSnXR{FYi(LuTBESD)avlj>G00y@XO}$$K>(Ej zlBl#;T3dsPjJn?Px83r0g^ZMxl%=z`wA}KLs<>`$ZokvnvfJ{b#@kp}Sj^?_vD)&m z*zi?VRXL11s{jB10d!JMQvg8b*k%9#00Cl4M??UK1szBL000SaNLh0L01FcU01FcV z0GgZ_00007bV*G`2ipV@5d#koeph1v005>*L_t&-(?!kO4#FS|fMH-~Pn%P*iBT^d z+q^Q1rW!`z{ol#5$n4$!g%-x9;X-ispD0e!EH9!N;>B{c-jr2np7`F@yRaqFsrLsF zAe&kq1Mu88qSg45qO4H^7yxJ{I91dZkpO(3FIV(!!44j7jY3O307x(d57nZQh}s&E z1kYF7p#nhkhc#pGPuJ6P+M%lheLR}}-sr(Mk}~E-=N!)S1$}xN(oSpy>i_@%07*qo IM6N<$g7m}xI{*Lx literal 0 HcmV?d00001 diff --git a/include/images/usermapping.pngc b/include/images/usermapping.pngc new file mode 100644 index 0000000..24375e0 --- /dev/null +++ b/include/images/usermapping.pngc @@ -0,0 +1,109 @@ +#ifndef USERMAPPING_PNG_H +#define USERMAPPING_PNG_H + +static const unsigned char usermapping_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0xcc, 0x50, 0x4c, 0x54, 0x45, 0xb6, 0xae, +0xb1, 0x99, 0x99, 0x99, 0x6a, 0x6a, 0x6a, 0xbd, +0xbd, 0xbd, 0x7e, 0x7a, 0x77, 0xb7, 0xae, 0xa7, +0xe4, 0xd8, 0xce, 0xe4, 0xd8, 0xd0, 0xb6, 0xae, +0xaa, 0x7e, 0x7a, 0x79, 0xd7, 0xcc, 0xc3, 0xf8, +0xea, 0xdf, 0xf8, 0xea, 0xe1, 0xf7, 0xea, 0xe2, +0xf7, 0xea, 0xe4, 0xd7, 0xcc, 0xc9, 0x7e, 0x7a, +0x7a, 0xf7, 0xea, 0xe6, 0xf7, 0xea, 0xe8, 0xb6, +0xae, 0xae, 0xf7, 0xea, 0xea, 0xe3, 0xd8, 0xda, +0xf7, 0xea, 0xec, 0xe3, 0xd8, 0xdb, 0xf7, 0xea, +0xee, 0xd6, 0xcc, 0xd0, 0x7d, 0x7a, 0x7c, 0x5b, +0x5c, 0x5c, 0x5a, 0x5c, 0x5c, 0x6a, 0x6d, 0x6d, +0xa6, 0xb4, 0xb7, 0xb4, 0xc5, 0xc9, 0x87, 0x90, +0x93, 0x64, 0x67, 0x68, 0x63, 0x67, 0x68, 0x83, +0x8e, 0x93, 0xa8, 0xbf, 0xca, 0x99, 0xad, 0xb7, +0x65, 0x6b, 0x6d, 0x5a, 0x5a, 0x5a, 0xa3, 0xb0, +0xb3, 0xd4, 0xea, 0xf0, 0xd1, 0xe9, 0xf0, 0xce, +0xe7, 0xf0, 0xcb, 0xe6, 0xf1, 0xc7, 0xe4, 0xf1, +0xc4, 0xe3, 0xf1, 0xc1, 0xe1, 0xf1, 0xbd, 0xe0, +0xf1, 0x92, 0xa8, 0xb4, 0x58, 0x5a, 0x5b, 0x83, +0x8a, 0x8c, 0xba, 0xde, 0xf2, 0xb7, 0xdd, 0xf2, +0x77, 0x85, 0x8c, 0x94, 0x94, 0x94, 0xa5, 0xb3, +0xb7, 0xb4, 0xdc, 0xf2, 0x90, 0xaa, 0xb8, 0x6e, +0x6e, 0x6e, 0xbf, 0xd3, 0xd9, 0xb2, 0xdb, 0xf2, +0xa3, 0xc6, 0xdb, 0x58, 0x58, 0x58, 0xcc, 0xe5, +0xee, 0xb1, 0xda, 0xf2, 0xb0, 0xd8, 0xf0, 0x55, +0x55, 0x55, 0x39, 0x8c, 0x3b, 0xab, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, 0x62, +0x4b, 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x04, +0x11, 0x11, 0x03, 0x0f, 0x0f, 0x7e, 0x57, 0x63, +0x00, 0x00, 0x00, 0xa6, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x45, 0xcd, 0xdb, 0x0e, 0xc2, 0x20, +0x0c, 0x80, 0x61, 0x60, 0x67, 0x4f, 0x9b, 0x53, +0xb1, 0x89, 0x51, 0x2f, 0x1d, 0xdb, 0xbc, 0x32, +0x8b, 0xa6, 0x1a, 0x46, 0xe0, 0xfd, 0xdf, 0xc9, +0xb2, 0xc8, 0xec, 0xdd, 0xff, 0x85, 0x16, 0xc6, +0xa6, 0xe1, 0x42, 0x70, 0xf6, 0x9f, 0x28, 0x4e, +0xd2, 0x2c, 0x2f, 0xa2, 0x19, 0xe2, 0xc5, 0x72, +0xb5, 0xde, 0x94, 0x55, 0x68, 0x9e, 0xf8, 0xde, +0xd6, 0xbb, 0xb0, 0x25, 0xd2, 0xa9, 0xf7, 0x07, +0x11, 0x20, 0x9b, 0x5a, 0x1e, 0x03, 0xf0, 0xdc, +0x37, 0xa2, 0xd5, 0xf8, 0x93, 0xa2, 0xac, 0x51, +0x03, 0x18, 0x00, 0x68, 0x26, 0x38, 0x55, 0xd4, +0x16, 0x91, 0x00, 0x7c, 0x9f, 0x2f, 0x57, 0xf4, +0x6d, 0xc1, 0x0e, 0x1e, 0x6e, 0x8d, 0x42, 0x4b, +0x3d, 0x00, 0x48, 0x30, 0x04, 0x0f, 0xd5, 0xa2, +0x92, 0x88, 0xda, 0x1a, 0x90, 0x04, 0xcf, 0x57, +0xdb, 0xa1, 0x02, 0x40, 0xf4, 0x87, 0x35, 0x63, +0xef, 0x4f, 0xd7, 0xd3, 0x73, 0xda, 0xa1, 0xab, +0x03, 0x7d, 0x3c, 0x9a, 0xfe, 0xde, 0xe8, 0xc1, +0x37, 0x92, 0x32, 0xe6, 0x46, 0xe7, 0x1c, 0xce, +0xf3, 0x05, 0x7d, 0x7a, 0x1a, 0xd2, 0x4e, 0x6c, +0x04, 0xeb, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *usermapping_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_usermapping_png = new wxImage(); + if (!img_usermapping_png || !img_usermapping_png->IsOk()) + { + wxMemoryInputStream img_usermapping_pngIS(usermapping_png_data, sizeof(usermapping_png_data)); + img_usermapping_png->LoadFile(img_usermapping_pngIS, wxBITMAP_TYPE_PNG); + } + return img_usermapping_png; +} +#define usermapping_png_img usermapping_png_img() + +static wxBitmap *usermapping_png_bmp() +{ + static wxBitmap *bmp_usermapping_png; + if (!bmp_usermapping_png || !bmp_usermapping_png->IsOk()) + bmp_usermapping_png = new wxBitmap(*usermapping_png_img); + return bmp_usermapping_png; +} +#define usermapping_png_bmp usermapping_png_bmp() + +static wxIcon *usermapping_png_ico() +{ + static wxIcon *ico_usermapping_png; + if (!ico_usermapping_png || !ico_usermapping_png->IsOk()) + { + ico_usermapping_png = new wxIcon(); + ico_usermapping_png->CopyFromBitmap(*usermapping_png_bmp); + } + return ico_usermapping_png; +} +#define usermapping_png_ico usermapping_png_ico() + +#endif // USERMAPPING_PNG_H diff --git a/include/images/usermappings.png b/include/images/usermappings.png new file mode 100644 index 0000000000000000000000000000000000000000..0e68c2b12866ad4b480a41a7d1032a1df34a1f45 GIT binary patch literal 557 zcmV+|0@D47P)Px#}!MO6|+snbbl8uXccXagT+W6|=`0C>K z>g4n0;*yPwlarIZw5<2)=J)F8%E7^KaB$w!%J=H(@#N;Vwzivm&s<-|==9#+-fnVp$mQ|WnV-Pr^Qfq(mZGJ^ zc=v006Z~ zL_t&-(?yQg4#F@D08{qfqYSg$l)WM-NCgS7nEC(z!9fM??M}86Aq-Z?3X4CHXe^#c zM*bm{&SZ1>!q1B(_Hw0aeM7Bo+-`)vq1non+Yrz(rQ54Oe}Im3ha)gyJeh*=*<5MO zzFe&ppfjIov_0go*?K#0IsOk()) + { + wxMemoryInputStream img_usermappings_pngIS(usermappings_png_data, sizeof(usermappings_png_data)); + img_usermappings_png->LoadFile(img_usermappings_pngIS, wxBITMAP_TYPE_PNG); + } + return img_usermappings_png; +} +#define usermappings_png_img usermappings_png_img() + +static wxBitmap *usermappings_png_bmp() +{ + static wxBitmap *bmp_usermappings_png; + if (!bmp_usermappings_png || !bmp_usermappings_png->IsOk()) + bmp_usermappings_png = new wxBitmap(*usermappings_png_img); + return bmp_usermappings_png; +} +#define usermappings_png_bmp usermappings_png_bmp() + +static wxIcon *usermappings_png_ico() +{ + static wxIcon *ico_usermappings_png; + if (!ico_usermappings_png || !ico_usermappings_png->IsOk()) + { + ico_usermappings_png = new wxIcon(); + ico_usermappings_png->CopyFromBitmap(*usermappings_png_bmp); + } + return ico_usermappings_png; +} +#define usermappings_png_ico usermappings_png_ico() + +#endif // USERMAPPINGS_PNG_H diff --git a/include/images/users.png b/include/images/users.png new file mode 100644 index 0000000000000000000000000000000000000000..f5c20bfb9df3fcfd5637142b5edadee88d16f1dd GIT binary patch literal 472 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}dw@@fE08{V^k{v3eRq4)g`;~e z9NpL5-umO!!|$)2oIiTx`>Pk{j~?H@e}8v-M|4a~ZF5V0aYq#;_yj z3T>;K`{Y|Vq&xEjj%G~k6hHR+h!THhnaxw_$SGHMPMfZMPi)i9%XhNulY>gPzF~iB z|KgKQLWq9XH}ze6r2ic?sZII+S2M0acw&}`vH8UR{h3j<5wpVPAM$;3o^cn?p;iC4 zi2>cDTH+c}l9E`GYL#4+3Zxi}3=9o)4UKdS3`2|ztW1opOiZ;6OsxzI=DpKfg`y!h mKP5A*5~9Jt608BJ+QiDh45H!G^w2dx4Gf;HelF{r5}E*Jd&X1% literal 0 HcmV?d00001 diff --git a/include/images/users.pngc b/include/images/users.pngc new file mode 100644 index 0000000..461134e --- /dev/null +++ b/include/images/users.pngc @@ -0,0 +1,103 @@ +#ifndef USERS_PNG_H +#define USERS_PNG_H + +static const unsigned char users_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x87, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc5, 0xc5, 0xc5, 0x7f, +0x7f, 0x7f, 0x8b, 0x87, 0x82, 0xd0, 0xc5, 0xbc, +0xd0, 0xc5, 0xbe, 0x8b, 0x87, 0x85, 0xf8, 0xea, +0xe1, 0xf7, 0xea, 0xe4, 0xcf, 0xc5, 0xc4, 0xf7, +0xea, 0xe8, 0xcf, 0xc5, 0xc7, 0xbf, 0xbf, 0xbf, +0x8b, 0x87, 0x88, 0x5b, 0x5c, 0x5c, 0x7d, 0x83, +0x84, 0x6f, 0x73, 0x74, 0x6e, 0x73, 0x74, 0x79, +0x81, 0x84, 0x5a, 0x5c, 0x5c, 0xb7, 0xb7, 0xb7, +0x8c, 0x95, 0x97, 0xd4, 0xea, 0xf0, 0xd0, 0xe8, +0xf0, 0xca, 0xe6, 0xf1, 0xc4, 0xe3, 0xf1, 0x72, +0x7c, 0x80, 0x6d, 0x6d, 0x6d, 0x9b, 0x9b, 0x9b, +0x80, 0x80, 0x80, 0xb4, 0xc4, 0xc8, 0x9a, 0xb1, +0xbc, 0x5b, 0x5b, 0x5b, 0xcc, 0xe3, 0xeb, 0xbe, +0xe0, 0xf1, 0x6d, 0x77, 0x7c, 0x74, 0x7a, 0x7b, +0x81, 0x90, 0x97, 0xa1, 0xa1, 0xa1, 0x55, 0x55, +0x55, 0x73, 0x79, 0x7b, 0x9f, 0xbb, 0xca, 0x9e, +0xb0, 0xb7, 0xb8, 0xde, 0xf2, 0xb1, 0xd7, 0xec, +0x6d, 0x89, 0xdf, 0x84, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x88, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x4d, 0x8e, 0xd9, 0x16, 0x82, 0x30, 0x0c, 0x05, +0xd3, 0xc8, 0x0e, 0x0a, 0xca, 0x22, 0x55, 0x91, +0x02, 0x8a, 0xb8, 0xfc, 0xff, 0xf7, 0x91, 0x36, +0x08, 0xbd, 0x6f, 0x49, 0x66, 0xce, 0x0d, 0x00, +0x08, 0x44, 0x01, 0x56, 0xc4, 0xce, 0x71, 0x3d, +0x7b, 0x83, 0x8e, 0x1f, 0x84, 0x08, 0x1b, 0x89, +0x6e, 0x10, 0xc5, 0x68, 0x91, 0x89, 0x17, 0xc6, +0xfb, 0xc4, 0x22, 0x0f, 0x69, 0x76, 0x3c, 0xe5, +0x1b, 0x59, 0x94, 0xd5, 0xb9, 0x96, 0x97, 0x2b, +0xde, 0x16, 0xb2, 0xb9, 0xd3, 0xdc, 0x6a, 0x3f, +0x63, 0x52, 0x75, 0xb5, 0xec, 0x07, 0xed, 0x3f, +0xe8, 0xf2, 0x2c, 0x60, 0x54, 0x2f, 0x8a, 0xf6, +0x27, 0xba, 0xbc, 0x1b, 0xfe, 0xc5, 0x34, 0x7d, +0x64, 0xff, 0xfd, 0x29, 0x5e, 0x70, 0x13, 0x91, +0x6a, 0x34, 0x33, 0x37, 0x91, 0xff, 0x8f, 0x69, +0x5a, 0x7d, 0x58, 0x9a, 0x56, 0x9f, 0xc2, 0x4d, +0xec, 0xcf, 0x01, 0xba, 0x0c, 0xc2, 0xaa, 0xff, +0xb6, 0x16, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, +0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *users_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_users_png = new wxImage(); + if (!img_users_png || !img_users_png->IsOk()) + { + wxMemoryInputStream img_users_pngIS(users_png_data, sizeof(users_png_data)); + img_users_png->LoadFile(img_users_pngIS, wxBITMAP_TYPE_PNG); + } + return img_users_png; +} +#define users_png_img users_png_img() + +static wxBitmap *users_png_bmp() +{ + static wxBitmap *bmp_users_png; + if (!bmp_users_png || !bmp_users_png->IsOk()) + bmp_users_png = new wxBitmap(*users_png_img); + return bmp_users_png; +} +#define users_png_bmp users_png_bmp() + +static wxIcon *users_png_ico() +{ + static wxIcon *ico_users_png; + if (!ico_users_png || !ico_users_png->IsOk()) + { + ico_users_png = new wxIcon(); + ico_users_png->CopyFromBitmap(*users_png_bmp); + } + return ico_users_png; +} +#define users_png_ico users_png_ico() + +#endif // USERS_PNG_H diff --git a/include/images/vacuum.png b/include/images/vacuum.png new file mode 100644 index 0000000000000000000000000000000000000000..8ace91e8187b9ddb318b823a17f48c118dc55b6a GIT binary patch literal 969 zcmV;)12+7LP)+$jN`}_O<|Nq9u#$aGz($UDGqN3{R z>f77f^z{Dz{>jP7UteF>*Vp0U;bdfFwzaRu#lGO+;K<0xVq#)&aB$w<-tX`4 z{r&xHY;3o-uVZ6l$H&Kpg@W$x?(OaE{QUf7Wo5y^!S(g^`uh6z_V&8Ev&F^5+}zx~ zy}fa9ac^&LwY9a8k&ShAb@KA^<>lqt+S=9C)z;S5&CShzetx>Tx{!~HUS3}F^Yhu+ z*~`nzw6wIYuCB4MvA4Ik%F4=XYisH0>A%0fudlDLu&~6$#N_1UkdTbs-QCX4&bGF; zkB^Ige}B)<&%?vR!otGe-{1H5_tDYO`1ttJ($e|)`QqZ@)YR0Kl#tKP#g2}O@bK_w zXJ(q3m64E)r>Cdp=H{81l&7bmnVFe{goKxul74-A(9qDGotR-^U}$J)=;-L6prF*# z%4NFK0ssI20d!JMQvg8b*k%9#00Cl4M??+wv|;rC000SaNLh0L002k;002k;M#*bF z0004kNkl01F&6oFg2yA#MnZSWvGPEVv8hFT1ZSv%U|Ej(`SRzGbas`GfRcf#x)o68k17TdAQ$d7kO=g~3NdB?{ z5MY^ZRY6c|0vE3XsvuhH22E^k@kesowgV9C4hCn00ZFIJjsOHVhI_oou9~#Ce14F? z;Fv-l*i-EXd_jN^I>51TBpPGccp`Xco)M0YF)S%NNhQ*m%xN|kfv0(%VGL)w_<8yw zbD1p^QPCtXIsOk()) + { + wxMemoryInputStream img_vacuum_pngIS(vacuum_png_data, sizeof(vacuum_png_data)); + img_vacuum_png->LoadFile(img_vacuum_pngIS, wxBITMAP_TYPE_PNG); + } + return img_vacuum_png; +} +#define vacuum_png_img vacuum_png_img() + +static wxBitmap *vacuum_png_bmp() +{ + static wxBitmap *bmp_vacuum_png; + if (!bmp_vacuum_png || !bmp_vacuum_png->IsOk()) + bmp_vacuum_png = new wxBitmap(*vacuum_png_img); + return bmp_vacuum_png; +} +#define vacuum_png_bmp vacuum_png_bmp() + +static wxIcon *vacuum_png_ico() +{ + static wxIcon *ico_vacuum_png; + if (!ico_vacuum_png || !ico_vacuum_png->IsOk()) + { + ico_vacuum_png = new wxIcon(); + ico_vacuum_png->CopyFromBitmap(*vacuum_png_bmp); + } + return ico_vacuum_png; +} +#define vacuum_png_ico vacuum_png_ico() + +#endif // VACUUM_PNG_H diff --git a/include/images/variable.png b/include/images/variable.png new file mode 100644 index 0000000000000000000000000000000000000000..046a08842b850b21311797f9c0b554b4cb9dc344 GIT binary patch literal 311 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPGa2=EDU1=8P7w7p+y`Tg3G|L?E; zzPI)NqoeOPh8;W+{~0L9SQ6wH%;50sMjDXAS>O>_45U54*zIJt9gq>`>Eal|aXmTV z0E?5C!vc;J4X)igB%~N6PkE{Jc{w_?&6+T4VvhEVTh4|m5H&HiK(`Msg;4jymxx5P&DM`r(~v8LNpjyf;9kDn^+l` WK{TA29=Zmofx*+&&t;ucLK6VL9%Oj{ literal 0 HcmV?d00001 diff --git a/include/images/variable.pngc b/include/images/variable.pngc new file mode 100644 index 0000000..925821d --- /dev/null +++ b/include/images/variable.pngc @@ -0,0 +1,83 @@ +#ifndef VARIABLE_PNG_H +#define VARIABLE_PNG_H + +static const unsigned char variable_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x18, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xf7, 0xc8, 0x86, 0xef, +0xa5, 0x39, 0xf7, 0xd6, 0xa4, 0xff, 0xef, 0xd6, +0xfb, 0xde, 0xb5, 0xff, 0xe2, 0xc5, 0xef, 0xb1, +0x56, 0xc1, 0xc8, 0x5f, 0xf3, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0x56, 0x49, 0x44, 0x41, 0x54, 0x08, +0xd7, 0x63, 0x60, 0xc0, 0x04, 0x42, 0x4a, 0x40, +0xa0, 0x08, 0x64, 0x28, 0x0a, 0xbb, 0xb8, 0x18, +0x1a, 0x01, 0x19, 0xca, 0x4a, 0x26, 0x8e, 0x4a, +0x41, 0x40, 0x86, 0x9a, 0x90, 0x9a, 0x91, 0x62, +0x12, 0x88, 0x91, 0xa8, 0x5e, 0x24, 0x06, 0x62, +0xa8, 0x06, 0x17, 0xa9, 0x87, 0x82, 0xa4, 0x94, +0x8d, 0x8b, 0xd4, 0x8d, 0xc1, 0x8a, 0x0d, 0xd5, +0x8b, 0x84, 0x41, 0x0c, 0x45, 0x21, 0x10, 0x04, +0x31, 0x94, 0x04, 0x05, 0x95, 0xc0, 0x0c, 0x41, +0x20, 0x10, 0x82, 0x59, 0xa1, 0x80, 0xc5, 0x6e, +0x00, 0xb5, 0x30, 0x0c, 0x55, 0xe5, 0x87, 0xe5, +0xae, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, +0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *variable_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_variable_png = new wxImage(); + if (!img_variable_png || !img_variable_png->IsOk()) + { + wxMemoryInputStream img_variable_pngIS(variable_png_data, sizeof(variable_png_data)); + img_variable_png->LoadFile(img_variable_pngIS, wxBITMAP_TYPE_PNG); + } + return img_variable_png; +} +#define variable_png_img variable_png_img() + +static wxBitmap *variable_png_bmp() +{ + static wxBitmap *bmp_variable_png; + if (!bmp_variable_png || !bmp_variable_png->IsOk()) + bmp_variable_png = new wxBitmap(*variable_png_img); + return bmp_variable_png; +} +#define variable_png_bmp variable_png_bmp() + +static wxIcon *variable_png_ico() +{ + static wxIcon *ico_variable_png; + if (!ico_variable_png || !ico_variable_png->IsOk()) + { + ico_variable_png = new wxIcon(); + ico_variable_png->CopyFromBitmap(*variable_png_bmp); + } + return ico_variable_png; +} +#define variable_png_ico variable_png_ico() + +#endif // VARIABLE_PNG_H diff --git a/include/images/variables.png b/include/images/variables.png new file mode 100644 index 0000000000000000000000000000000000000000..236bad7dc44ebcaa11a8f5c8f24e6ba4015114fa GIT binary patch literal 350 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPHF3h)VW1=8=ATK<23?fc&R|BsIT zzPI)Jy|v%3EqTAx>HCSc_iMf0Z%ux`G3@=`?6Wy#vOv|0B|(0{3=Yq3qyagc1s;*b zK-vS0-A-oP0U6nzE{-7_*OL=OSeV!p1cI2D7zGXsXsIv>3$=1~c6LnDUOAQ1prgCX zOf7W_mw`uDXNXSz9Hx|xZZ|K^b|%S5NtxW!mvb5zcy)z)pPa({)!Qr1W@n-Lgo7H| zhQ)0hE zVTh4|m5H&HiK(`Msg;4jymxx5P&DM`r(~v8LNpjyf;9kDn^+l`K{TA29=Zmofx*+& K&t;ucLK6VH>T_QJ literal 0 HcmV?d00001 diff --git a/include/images/variables.pngc b/include/images/variables.pngc new file mode 100644 index 0000000..2ad33c5 --- /dev/null +++ b/include/images/variables.pngc @@ -0,0 +1,88 @@ +#ifndef VARIABLES_PNG_H +#define VARIABLES_PNG_H + +static const unsigned char variables_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x2a, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xef, 0xa5, 0x39, 0xff, +0xef, 0xd6, 0xf7, 0xbd, 0x6f, 0xff, 0xe2, 0xc5, +0xfb, 0xde, 0xb5, 0xf7, 0xde, 0xad, 0xf7, 0xd6, +0xa4, 0xef, 0xa5, 0x42, 0xf7, 0xc8, 0x86, 0xef, +0xad, 0x4a, 0xef, 0xb5, 0x63, 0xef, 0xb1, 0x56, +0xef, 0xbd, 0x6b, 0xcd, 0x6c, 0x76, 0x1d, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x6b, 0x49, 0x44, 0x41, +0x54, 0x08, 0xd7, 0x63, 0x60, 0x14, 0x04, 0x02, +0x06, 0x20, 0x10, 0x52, 0x02, 0x02, 0x01, 0x10, +0xc3, 0x10, 0x2a, 0x24, 0x02, 0x13, 0x12, 0x85, +0x09, 0x89, 0x89, 0x88, 0x96, 0x2b, 0xa9, 0x95, +0x09, 0x30, 0x88, 0x8b, 0x8a, 0x36, 0x26, 0x65, +0xb4, 0x0a, 0x30, 0x48, 0x8a, 0x89, 0x54, 0x2c, +0x6f, 0x9c, 0x02, 0x64, 0x88, 0x8b, 0x46, 0x4a, +0x09, 0x87, 0x02, 0x19, 0x92, 0x62, 0x69, 0x0b, +0x97, 0xa7, 0x09, 0x30, 0x30, 0x4a, 0x8a, 0x57, +0x4b, 0xc9, 0x94, 0x03, 0xf5, 0x4b, 0x4a, 0x5e, +0x3c, 0xb9, 0x71, 0x27, 0x90, 0xc1, 0x28, 0x2b, +0x31, 0x73, 0x86, 0x2c, 0xc8, 0x12, 0xc9, 0x99, +0x40, 0x00, 0x62, 0xc0, 0xed, 0x87, 0x00, 0x00, +0x61, 0xf2, 0x15, 0xae, 0xd7, 0x6b, 0x2c, 0x79, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, +0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *variables_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_variables_png = new wxImage(); + if (!img_variables_png || !img_variables_png->IsOk()) + { + wxMemoryInputStream img_variables_pngIS(variables_png_data, sizeof(variables_png_data)); + img_variables_png->LoadFile(img_variables_pngIS, wxBITMAP_TYPE_PNG); + } + return img_variables_png; +} +#define variables_png_img variables_png_img() + +static wxBitmap *variables_png_bmp() +{ + static wxBitmap *bmp_variables_png; + if (!bmp_variables_png || !bmp_variables_png->IsOk()) + bmp_variables_png = new wxBitmap(*variables_png_img); + return bmp_variables_png; +} +#define variables_png_bmp variables_png_bmp() + +static wxIcon *variables_png_ico() +{ + static wxIcon *ico_variables_png; + if (!ico_variables_png || !ico_variables_png->IsOk()) + { + ico_variables_png = new wxIcon(); + ico_variables_png->CopyFromBitmap(*variables_png_bmp); + } + return ico_variables_png; +} +#define variables_png_ico variables_png_ico() + +#endif // VARIABLES_PNG_H diff --git a/include/images/view-sm.png b/include/images/view-sm.png new file mode 100644 index 0000000000000000000000000000000000000000..305a14035988ceae00ce676ef7d46fbf74e261e5 GIT binary patch literal 395 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}Y=BRQE0ErHEn?1bnX`|3=bcb^ z^k>@RZ_6LO+xO(v<)_c@J%9f6*|TSlp5D6teC3vl(U1OjZ-1%w|NsB(FVye6S+o6x z+Qa|dr$2`s|KR=LU)!BObvJ*N9{=cl_`SovH)gwD>6!n^{{^&wu_VYZn8D%MjWiG^ z$=lsU@X=P=T|f?Jfk$L9koEv$x0Bg+Kt_b8i(`ny<>UkfCIh2`jK&cSty6pFHc#%J zJ-dB6zs`Xp{J{zbScC;wm{S-h>`|C3FsZ@7e1bqDR|nJ0q(>f1H?}zNxUO*69_AF} z2Ll0cv3I MboFyt=akR{0Cm2XmjD0& literal 0 HcmV?d00001 diff --git a/include/images/view-sm.pngc b/include/images/view-sm.pngc new file mode 100644 index 0000000..756f3cd --- /dev/null +++ b/include/images/view-sm.pngc @@ -0,0 +1,94 @@ +#ifndef VIEW_SM_PNG_H +#define VIEW_SM_PNG_H + +static const unsigned char view_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x5d, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xb6, 0xd6, 0x58, 0x9c, +0xc7, 0x1c, 0xcd, 0xe3, 0x8d, 0x9e, 0xc8, 0x20, +0xe2, 0xfc, 0x96, 0xe3, 0xf6, 0xa7, 0xe2, 0xee, +0xbe, 0xe4, 0xea, 0xd3, 0xe5, 0xe7, 0xde, 0xe7, +0xe7, 0xe5, 0xe6, 0xe6, 0xe6, 0xe2, 0xe5, 0xda, +0xd7, 0xe7, 0xa9, 0xb4, 0xd1, 0x5b, 0xe2, 0xff, +0x8b, 0xb7, 0xe9, 0x26, 0xff, 0xff, 0xff, 0xb7, +0xe8, 0x27, 0xdc, 0xec, 0xac, 0xb7, 0xe8, 0x26, +0xe1, 0xff, 0x8b, 0xcb, 0xf3, 0x56, 0xc7, 0xf0, +0x4b, 0xe0, 0xfe, 0x86, 0xdc, 0xfc, 0x7e, 0xd9, +0xfa, 0x75, 0xc7, 0xf1, 0x4b, 0xc3, 0xef, 0x40, +0xbe, 0xec, 0x36, 0xba, 0xea, 0x2e, 0x37, 0xfa, +0x6f, 0xfa, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, 0x11, +0xe2, 0xb5, 0x3d, 0xba, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x58, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x63, 0x60, 0x20, 0x02, 0x30, +0x32, 0xc1, 0x01, 0x33, 0x58, 0x80, 0x85, 0x95, +0x8d, 0x9d, 0x83, 0x93, 0x8b, 0x9b, 0x9b, 0x87, +0x97, 0x0f, 0x2c, 0xc0, 0xc4, 0x0f, 0x53, 0x20, +0xc0, 0x04, 0x13, 0x10, 0x04, 0x03, 0x64, 0x01, +0x90, 0xbc, 0x20, 0x93, 0x10, 0x92, 0x80, 0x30, +0x37, 0x90, 0x10, 0x81, 0x0a, 0x88, 0x02, 0xd9, +0x62, 0xe2, 0x48, 0x02, 0xd8, 0xb4, 0x40, 0x0c, +0x45, 0xa8, 0x40, 0xb7, 0x56, 0x42, 0x52, 0x4a, +0x4c, 0x5a, 0x46, 0x56, 0x0e, 0xaa, 0x82, 0x19, +0xdd, 0xe9, 0x04, 0x00, 0x00, 0x55, 0x66, 0x04, +0xb8, 0xcb, 0x08, 0xe4, 0xdf, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x31, 0x2d, 0x30, 0x31, +0x2d, 0x32, 0x33, 0x54, 0x30, 0x33, 0x3a, 0x30, +0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x36, 0x3a, +0x30, 0x30, 0x44, 0xd4, 0x3d, 0x9a, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *view_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_view_sm_png = new wxImage(); + if (!img_view_sm_png || !img_view_sm_png->IsOk()) + { + wxMemoryInputStream img_view_sm_pngIS(view_sm_png_data, sizeof(view_sm_png_data)); + img_view_sm_png->LoadFile(img_view_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_view_sm_png; +} +#define view_sm_png_img view_sm_png_img() + +static wxBitmap *view_sm_png_bmp() +{ + static wxBitmap *bmp_view_sm_png; + if (!bmp_view_sm_png || !bmp_view_sm_png->IsOk()) + bmp_view_sm_png = new wxBitmap(*view_sm_png_img); + return bmp_view_sm_png; +} +#define view_sm_png_bmp view_sm_png_bmp() + +static wxIcon *view_sm_png_ico() +{ + static wxIcon *ico_view_sm_png; + if (!ico_view_sm_png || !ico_view_sm_png->IsOk()) + { + ico_view_sm_png = new wxIcon(); + ico_view_sm_png->CopyFromBitmap(*view_sm_png_bmp); + } + return ico_view_sm_png; +} +#define view_sm_png_ico view_sm_png_ico() + +#endif // VIEW_SM_PNG_H diff --git a/include/images/view.png b/include/images/view.png new file mode 100644 index 0000000000000000000000000000000000000000..44116db56496bb477c8ece7d3fdda666e1b3758b GIT binary patch literal 437 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}X@F0NE08|>xOdKRnaBToAO4>7 z;On9XZ+AU@dGYD<`_G?0efI3xZ-1%w|NsB(FVt^;p7P|y zjoU9bT=|i6;cMdQ&tb_QLRH3SlxI5?abofwq#PpGhn z3y3`waupO1o<6}vaKfZ%6BvUwB`{h}XxPzW6T>ijp+R<{)&<#R3sx-A(NkQ!Xcb#n z<0DHqpYzNNJzLm||5$yx0JK%L#5JNMC9x#cD!C{XNHG{07#ipr8tEDsh8P)GnHXD{ zm}(oCS{WG3d#ASwMMG|WN@iLmM1z4PSOZYCiIssFM8m1+p=*E|7(8A5T-G@yGywnx Cm9(({ literal 0 HcmV?d00001 diff --git a/include/images/view.pngc b/include/images/view.pngc new file mode 100644 index 0000000..2316123 --- /dev/null +++ b/include/images/view.pngc @@ -0,0 +1,99 @@ +#ifndef VIEW_PNG_H +#define VIEW_PNG_H + +static const unsigned char view_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x75, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xcd, 0xe3, 0x8d, 0x9c, +0xc7, 0x1c, 0xe3, 0xff, 0x8d, 0xe1, 0xfb, 0x92, +0xe0, 0xf5, 0xa2, 0xe0, 0xed, 0xba, 0xe3, 0xe9, +0xd1, 0xe5, 0xe7, 0xdf, 0xe7, 0xe7, 0xe5, 0xe6, +0xe6, 0xe6, 0xe3, 0xe5, 0xda, 0xd8, 0xe7, 0xac, +0xc6, 0xe8, 0x63, 0xa1, 0xca, 0x29, 0xe2, 0xff, +0x8b, 0xb7, 0xe9, 0x26, 0xff, 0xff, 0xff, 0xb7, +0xe8, 0x27, 0xdb, 0xf3, 0x94, 0xe4, 0xe8, 0xd8, +0xdb, 0xe9, 0xb0, 0xd4, 0xf8, 0x6c, 0xd0, 0xf5, +0x61, 0xcb, 0xf3, 0x56, 0xc6, 0xf1, 0x4b, 0xd4, +0xf7, 0x6c, 0xd0, 0xf6, 0x61, 0xc7, 0xf1, 0x4b, +0xb7, 0xe8, 0x26, 0xe1, 0xff, 0x8b, 0xc7, 0xf0, +0x4b, 0xe0, 0xfe, 0x86, 0xdc, 0xfc, 0x7e, 0xd9, +0xfa, 0x75, 0xd5, 0xf8, 0x6b, 0xc3, 0xef, 0x40, +0xbe, 0xec, 0x36, 0xba, 0xea, 0x2e, 0xf5, 0x25, +0xaa, 0x61, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, 0x11, +0xe2, 0xb5, 0x3d, 0xba, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x6a, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x63, 0x60, 0xc0, 0x00, 0x8c, +0x4c, 0x48, 0x00, 0x24, 0xc0, 0xc4, 0xcc, 0xc2, +0xca, 0xc6, 0xce, 0xc1, 0xc9, 0xc5, 0xc5, 0xcd, +0xc3, 0xcb, 0x07, 0x12, 0xe0, 0x47, 0x28, 0x10, +0x60, 0x82, 0x08, 0x08, 0x42, 0x01, 0x42, 0x00, +0x22, 0x2f, 0xc8, 0x24, 0x04, 0x17, 0x10, 0x16, +0xe1, 0x12, 0x45, 0x11, 0x10, 0x13, 0x97, 0x90, +0x44, 0x11, 0x90, 0x92, 0x96, 0x90, 0x01, 0x52, +0xb2, 0x60, 0x01, 0x39, 0x90, 0x80, 0xb8, 0x84, +0x3c, 0x5c, 0x00, 0x9b, 0xa1, 0x30, 0x6b, 0x61, +0x2a, 0xd0, 0x1d, 0xa6, 0xa0, 0xa8, 0xa4, 0x2c, +0x2e, 0x21, 0xa3, 0xa2, 0xaa, 0x06, 0x56, 0x81, +0xe2, 0x39, 0x46, 0x4c, 0xcf, 0x03, 0x00, 0x8c, +0xb4, 0x07, 0x73, 0xfc, 0x3a, 0xf2, 0xd0, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *view_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_view_png = new wxImage(); + if (!img_view_png || !img_view_png->IsOk()) + { + wxMemoryInputStream img_view_pngIS(view_png_data, sizeof(view_png_data)); + img_view_png->LoadFile(img_view_pngIS, wxBITMAP_TYPE_PNG); + } + return img_view_png; +} +#define view_png_img view_png_img() + +static wxBitmap *view_png_bmp() +{ + static wxBitmap *bmp_view_png; + if (!bmp_view_png || !bmp_view_png->IsOk()) + bmp_view_png = new wxBitmap(*view_png_img); + return bmp_view_png; +} +#define view_png_bmp view_png_bmp() + +static wxIcon *view_png_ico() +{ + static wxIcon *ico_view_png; + if (!ico_view_png || !ico_view_png->IsOk()) + { + ico_view_png = new wxIcon(); + ico_view_png->CopyFromBitmap(*view_png_bmp); + } + return ico_view_png; +} +#define view_png_ico view_png_ico() + +#endif // VIEW_PNG_H diff --git a/include/images/viewdata.png b/include/images/viewdata.png new file mode 100644 index 0000000000000000000000000000000000000000..e98d20b1920c590ed2094006109860f7e7e04f4b GIT binary patch literal 1090 zcmV-I1ikx-P)-E#>_0Z_`%;)vU<@Cnn z^u^=!!{YS7;q>3|`OoO_%;)jR+9?5`}_O<|No50>;3)x!Q$|t((Q@I>$ctVy58@v+3u>=?x)r5n9l5x%j}QJ z>xISZwA=E7#Oku!@_)kWl+5gW!RoKs^10scm(J{t$?J&5>v+HFt=RH*zUi*m?uy9k za=huP*79(>>8RH7sMhX~%It*2>w&}Sd%)^-zUghc>7~{2YPjfUx9FnN@n*K@&gk`< z(CmiB>vX;8WVYyGwCJGH@n5s&p3(8k=JZ{%=UcJooY3)Owdh!|=bF#)Rj=ol&hS#L z=D*?epVIN0(D9be@XO}-8Z;m?00001bW%=J06^y0W&i*H0b)x>L^;<0l|TRh010qN zS#tmY07w7;07w8v$!k6U00HbtL_t(I%cYa)H)>HBhe?sC!Bm~xiaIJMp)OZZNrf~} z8Ol^Np^L8JR_?{W?(BEJtnCZd@_sn$ch-5<`aS#I>$J6fI_;7VrdkZLqqtxm`3M}HWMrm=Ceg`cq6?303H$_c=*(F+jox-vp)bpr;g+FO9tbz*dMg4 zgseWh5OzdXz5caz3UI{1$T$e-5ZwTv3+k5{hcM~co(!@B#F(;A$bc@H|G>w^q z{7T5?n-sRIsOk()) + { + wxMemoryInputStream img_viewdata_pngIS(viewdata_png_data, sizeof(viewdata_png_data)); + img_viewdata_png->LoadFile(img_viewdata_pngIS, wxBITMAP_TYPE_PNG); + } + return img_viewdata_png; +} +#define viewdata_png_img viewdata_png_img() + +static wxBitmap *viewdata_png_bmp() +{ + static wxBitmap *bmp_viewdata_png; + if (!bmp_viewdata_png || !bmp_viewdata_png->IsOk()) + bmp_viewdata_png = new wxBitmap(*viewdata_png_img); + return bmp_viewdata_png; +} +#define viewdata_png_bmp viewdata_png_bmp() + +static wxIcon *viewdata_png_ico() +{ + static wxIcon *ico_viewdata_png; + if (!ico_viewdata_png || !ico_viewdata_png->IsOk()) + { + ico_viewdata_png = new wxIcon(); + ico_viewdata_png->CopyFromBitmap(*viewdata_png_bmp); + } + return ico_viewdata_png; +} +#define viewdata_png_ico viewdata_png_ico() + +#endif // VIEWDATA_PNG_H diff --git a/include/images/viewfiltereddata.png b/include/images/viewfiltereddata.png new file mode 100644 index 0000000000000000000000000000000000000000..3177d55d66cae4de07c3a2cd5f8f85821e1400eb GIT binary patch literal 1162 zcmV;51ah;g)^UUY<$mR6Lna}K%%-+or|NsAs$m{+6{fNfvkICz^+wz3O>V3iLuGsQ< zzv*(k>8aN8rPT44%;=HDNJ|K-^G-P82h&GOU9?9jsO z$-L*qyy5ES^Kgi?)xG-7vH8ZY?!%|@x18v$lHsO{+n$5fmVC~Tb;+57%*x8jh>ECM zdaAppL@c`9ajO6T010qN zS#tmY07w7;07w8v$!k6U00J~gL_t(I%Y~EsThdS%$AtvsBFG)N4s?sl7*_{@pfLxS ztwsXoC9|SHOVbpEqWss}dv@Si&*PKdAI{!A=d*pkd*7Y8xksf^|3@kbP(PUmX*3$G zR;$x3==FMo(P%O)nk|+kH30JlgVk!Y*&R-&%kB0odwo8CAQ%b};fM%03g9|91sLhZ$;|fYAg)s~pt0E{f3OFCKll?wIGRqTQW+Vr zLk71Z1A#MSF@WsdiVOsUIy^zgMSeGBjBIS=5lKoa6tyIB10Ny zU}Zpu?0t$1NnEo941lE%76ysVCgg%GB4AIdqi8SLp4?!VLwUbw!z845gkdxro^1njfZ|AA?7!u8E)C~&PQ5KX7# z@v|&D9*=)s3BN|8iLiZ(fu&e1=E-F8`Fx>JC>D#s-@*`pa`^6#`oXhV6AmU5QmEmx z`GD?WO!tqUd!)Z*H=dvT*>}(Y001R)MObuXVRU6WV{&C-bY%cCFflMKF)}SMF;p@z zIy5snG&L(QH99abp6)KH0000bbVXQnWMOn=I&E)cX=ZrIsOk()) + { + wxMemoryInputStream img_viewfiltereddata_pngIS(viewfiltereddata_png_data, sizeof(viewfiltereddata_png_data)); + img_viewfiltereddata_png->LoadFile(img_viewfiltereddata_pngIS, wxBITMAP_TYPE_PNG); + } + return img_viewfiltereddata_png; +} +#define viewfiltereddata_png_img viewfiltereddata_png_img() + +static wxBitmap *viewfiltereddata_png_bmp() +{ + static wxBitmap *bmp_viewfiltereddata_png; + if (!bmp_viewfiltereddata_png || !bmp_viewfiltereddata_png->IsOk()) + bmp_viewfiltereddata_png = new wxBitmap(*viewfiltereddata_png_img); + return bmp_viewfiltereddata_png; +} +#define viewfiltereddata_png_bmp viewfiltereddata_png_bmp() + +static wxIcon *viewfiltereddata_png_ico() +{ + static wxIcon *ico_viewfiltereddata_png; + if (!ico_viewfiltereddata_png || !ico_viewfiltereddata_png->IsOk()) + { + ico_viewfiltereddata_png = new wxIcon(); + ico_viewfiltereddata_png->CopyFromBitmap(*viewfiltereddata_png_bmp); + } + return ico_viewfiltereddata_png; +} +#define viewfiltereddata_png_ico viewfiltereddata_png_ico() + +#endif // VIEWFILTEREDDATA_PNG_H diff --git a/include/images/views.png b/include/images/views.png new file mode 100644 index 0000000000000000000000000000000000000000..078d533684b8bd7e185749c4f1c9620af23d114b GIT binary patch literal 418 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbK}Y=BRQE08|>xOdKRnRzD^9{rj2 z_}lVF@Af@;b@}P@d(WRgefI3xqo=p7KVP}!V)Uc`-T(gmd-%V5`%AU||Nn1)p?>Gh zn(Z&tPJa$N{=xgfzqUJn>TdojJ^s=A@Oy`SZ_IYR((AHW{03+NV@Z%-FoVOh8)+a; zlDE5yQ1zZ1Ae(`+z$3C4NPB>>+sSM@AS2(?#W6(Ua%g{~P=f-Gv+27P9V>QJ|4;U6 zbe!GKH+kPSMNh%0YD;wVPp!&p$=H2Qa>4_iC-Ws`4oVu`kXvDIe5l_eV|jwW;+5+S zYgy6~PYdy+-cS45)~k2Z!$WAAUct+ok^krC+MlVs+ppfyc`@F`nC<>l-VMq?t5r)} zBT7;dOH!?pi&B9UgOP!up{{|Eu910&p^25DrIo3vwt<IsOk()) + { + wxMemoryInputStream img_views_pngIS(views_png_data, sizeof(views_png_data)); + img_views_png->LoadFile(img_views_pngIS, wxBITMAP_TYPE_PNG); + } + return img_views_png; +} +#define views_png_img views_png_img() + +static wxBitmap *views_png_bmp() +{ + static wxBitmap *bmp_views_png; + if (!bmp_views_png || !bmp_views_png->IsOk()) + bmp_views_png = new wxBitmap(*views_png_img); + return bmp_views_png; +} +#define views_png_bmp views_png_bmp() + +static wxIcon *views_png_ico() +{ + static wxIcon *ico_views_png; + if (!ico_views_png || !ico_views_png->IsOk()) + { + ico_views_png = new wxIcon(); + ico_views_png->CopyFromBitmap(*views_png_bmp); + } + return ico_views_png; +} +#define views_png_ico views_png_ico() + +#endif // VIEWS_PNG_H diff --git a/include/libssh2/Win32/libssh2_config.h b/include/libssh2/Win32/libssh2_config.h new file mode 100644 index 0000000..3e3caf4 --- /dev/null +++ b/include/libssh2/Win32/libssh2_config.h @@ -0,0 +1,45 @@ +#ifndef LIBSSH2_CONFIG_H +#define LIBSSH2_CONFIG_H + +#ifndef WIN32 +#define WIN32 +#endif +#ifndef _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif /* _CRT_SECURE_NO_DEPRECATE */ +#include +#include +#include + +#ifdef __MINGW32__ +#define HAVE_UNISTD_H +#define HAVE_INTTYPES_H +#define HAVE_SYS_TIME_H +#define HAVE_GETTIMEOFDAY +#endif /* __MINGW32__ */ + +#define HAVE_LIBCRYPT32 +#define HAVE_WINSOCK2_H +#define HAVE_IOCTLSOCKET +#define HAVE_SELECT + +#ifdef _MSC_VER +#define snprintf _snprintf +#if _MSC_VER < 1500 +#define vsnprintf _vsnprintf +#endif +#define strdup _strdup +#define strncasecmp _strnicmp +#define strcasecmp _stricmp +#else +#ifndef __MINGW32__ +#define strncasecmp strnicmp +#define strcasecmp stricmp +#endif /* __MINGW32__ */ +#endif /* _MSC_VER */ + +/* Enable newer diffie-hellman-group-exchange-sha1 syntax */ +#define LIBSSH2_DH_GEX_NEW 1 + +#endif /* LIBSSH2_CONFIG_H */ + diff --git a/include/libssh2/channel.h b/include/libssh2/channel.h new file mode 100644 index 0000000..dc0ee37 --- /dev/null +++ b/include/libssh2/channel.h @@ -0,0 +1,141 @@ +#ifndef __LIBSSH2_CHANNEL_H +#define __LIBSSH2_CHANNEL_H +/* Copyright (c) 2008-2010 by Daniel Stenberg + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +/* + * _libssh2_channel_receive_window_adjust + * + * Adjust the receive window for a channel by adjustment bytes. If the amount + * to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the + * adjustment amount will be queued for a later packet. + * + * Always non-blocking. + */ +int _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel, + uint32_t adjustment, + unsigned char force, + unsigned int *store); + +/* + * _libssh2_channel_flush + * + * Flush data from one (or all) stream + * Returns number of bytes flushed, or negative on failure + */ +int _libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid); + +/* + * _libssh2_channel_free + * + * Make sure a channel is closed, then remove the channel from the session + * and free its resource(s) + * + * Returns 0 on success, negative on failure + */ +int _libssh2_channel_free(LIBSSH2_CHANNEL *channel); + +int +_libssh2_channel_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode); + +/* + * _libssh2_channel_write + * + * Send data to a channel + */ +ssize_t +_libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id, + const unsigned char *buf, size_t buflen); + +/* + * _libssh2_channel_open + * + * Establish a generic session channel + */ +LIBSSH2_CHANNEL * +_libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type, + uint32_t channel_type_len, + uint32_t window_size, + uint32_t packet_size, + const unsigned char *message, size_t message_len); + + +/* + * _libssh2_channel_process_startup + * + * Primitive for libssh2_channel_(shell|exec|subsystem) + */ +int +_libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, + const char *request, size_t request_len, + const char *message, size_t message_len); + +/* + * _libssh2_channel_read + * + * Read data from a channel + * + * It is important to not return 0 until the currently read channel is + * complete. If we read stuff from the wire but it was no payload data to fill + * in the buffer with, we MUST make sure to return PACKET_EAGAIN. + */ +ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id, + char *buf, size_t buflen); + +uint32_t _libssh2_channel_nextid(LIBSSH2_SESSION * session); + +LIBSSH2_CHANNEL *_libssh2_channel_locate(LIBSSH2_SESSION * session, + uint32_t channel_id); + +size_t _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, + int stream_id); + +int _libssh2_channel_close(LIBSSH2_CHANNEL * channel); + +/* + * _libssh2_channel_forward_cancel + * + * Stop listening on a remote port and free the listener + * Toss out any pending (un-accept()ed) connections + * + * Return 0 on success, LIBSSH2_ERROR_EAGAIN if would block, -1 on error + */ +int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener); + +#endif /* __LIBSSH2_CHANNEL_H */ + diff --git a/include/libssh2/comp.h b/include/libssh2/comp.h new file mode 100644 index 0000000..8edc150 --- /dev/null +++ b/include/libssh2/comp.h @@ -0,0 +1,45 @@ +#ifndef __LIBSSH2_COMP_H +#define __LIBSSH2_COMP_H + +/* Copyright (C) 2009-2010 by Daniel Stenberg + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + */ + +#include "libssh2_priv.h" + +const LIBSSH2_COMP_METHOD **_libssh2_comp_methods(LIBSSH2_SESSION *session); + +#endif /* __LIBSSH2_COMP_H */ diff --git a/include/libssh2/crypto.h b/include/libssh2/crypto.h new file mode 100644 index 0000000..05f5a5c --- /dev/null +++ b/include/libssh2/crypto.h @@ -0,0 +1,142 @@ +/* Copyright (C) 2009, 2010 Simon Josefsson + * Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved. + * Copyright (C) 2010 Daniel Stenberg + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ +#ifndef LIBSSH2_CRYPTO_H +#define LIBSSH2_CRYPTO_H + +#ifdef LIBSSH2_OPENSSL +#include "openssl.h" +#endif + +#ifdef LIBSSH2_LIBGCRYPT +#include "libgcrypt.h" +#endif + +#ifdef LIBSSH2_WINCNG +#include "wincng.h" +#endif + +int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa, + const unsigned char *edata, + unsigned long elen, + const unsigned char *ndata, + unsigned long nlen, + const unsigned char *ddata, + unsigned long dlen, + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *e1data, + unsigned long e1len, + const unsigned char *e2data, + unsigned long e2len, + const unsigned char *coeffdata, unsigned long coefflen); +int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa, + LIBSSH2_SESSION * session, + const char *filename, + unsigned const char *passphrase); +int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa, + const unsigned char *sig, + unsigned long sig_len, + const unsigned char *m, unsigned long m_len); +int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session, + libssh2_rsa_ctx * rsactx, + const unsigned char *hash, + size_t hash_len, + unsigned char **signature, + size_t *signature_len); +int _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa, + LIBSSH2_SESSION * session, + const char *filedata, size_t filedata_len, + unsigned const char *passphrase); + +#if LIBSSH2_DSA +int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa, + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *gdata, + unsigned long glen, + const unsigned char *ydata, + unsigned long ylen, + const unsigned char *x, unsigned long x_len); +int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa, + LIBSSH2_SESSION * session, + const char *filename, + unsigned const char *passphrase); +int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx, + const unsigned char *sig, + const unsigned char *m, unsigned long m_len); +int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx, + const unsigned char *hash, + unsigned long hash_len, unsigned char *sig); +int _libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa, + LIBSSH2_SESSION * session, + const char *filedata, size_t filedata_len, + unsigned const char *passphrase); +#endif + +int _libssh2_cipher_init(_libssh2_cipher_ctx * h, + _libssh2_cipher_type(algo), + unsigned char *iv, + unsigned char *secret, int encrypt); + +int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx, + _libssh2_cipher_type(algo), + int encrypt, unsigned char *block, size_t blocksize); + +int _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekey, + const char *passphrase); +int _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekeydata, + size_t privatekeydata_len, + const char *passphrase); + +void _libssh2_init_aes_ctr(void); + +#endif diff --git a/include/libssh2/libgcrypt.h b/include/libssh2/libgcrypt.h new file mode 100644 index 0000000..20062ed --- /dev/null +++ b/include/libssh2/libgcrypt.h @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2008, 2009, 2010 Simon Josefsson + * Copyright (C) 2006, 2007, The Written Word, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include + +#define LIBSSH2_MD5 1 + +#define LIBSSH2_HMAC_RIPEMD 1 +#define LIBSSH2_HMAC_SHA256 1 +#define LIBSSH2_HMAC_SHA512 1 + +#define LIBSSH2_AES 1 +#define LIBSSH2_AES_CTR 1 +#define LIBSSH2_BLOWFISH 1 +#define LIBSSH2_RC4 1 +#define LIBSSH2_CAST 1 +#define LIBSSH2_3DES 1 + +#define LIBSSH2_RSA 1 +#define LIBSSH2_DSA 1 + +#define MD5_DIGEST_LENGTH 16 +#define SHA_DIGEST_LENGTH 20 +#define SHA256_DIGEST_LENGTH 32 + +#define _libssh2_random(buf, len) \ + (gcry_randomize ((buf), (len), GCRY_STRONG_RANDOM), 1) + +#define libssh2_sha1_ctx gcry_md_hd_t + +/* returns 0 in case of failure */ +#define libssh2_sha1_init(ctx) \ + (GPG_ERR_NO_ERROR == gcry_md_open (ctx, GCRY_MD_SHA1, 0)) +#define libssh2_sha1_update(ctx, data, len) \ + gcry_md_write (ctx, (unsigned char *) data, len) +#define libssh2_sha1_final(ctx, out) \ + memcpy (out, gcry_md_read (ctx, 0), SHA_DIGEST_LENGTH), gcry_md_close (ctx) +#define libssh2_sha1(message, len, out) \ + gcry_md_hash_buffer (GCRY_MD_SHA1, out, message, len) + +#define libssh2_sha256_ctx gcry_md_hd_t + +#define libssh2_sha256_init(ctx) \ + (GPG_ERR_NO_ERROR == gcry_md_open (ctx, GCRY_MD_SHA256, 0)) +#define libssh2_sha256_update(ctx, data, len) \ + gcry_md_write (ctx, (unsigned char *) data, len) +#define libssh2_sha256_final(ctx, out) \ + memcpy (out, gcry_md_read (ctx, 0), SHA256_DIGEST_LENGTH), gcry_md_close (ctx) +#define libssh2_sha256(message, len, out) \ + gcry_md_hash_buffer (GCRY_MD_SHA256, out, message, len) + +#define libssh2_md5_ctx gcry_md_hd_t + +/* returns 0 in case of failure */ +#define libssh2_md5_init(ctx) \ + (GPG_ERR_NO_ERROR == gcry_md_open (ctx, GCRY_MD_MD5, 0)) + +#define libssh2_md5_update(ctx, data, len) \ + gcry_md_write (ctx, (unsigned char *) data, len) +#define libssh2_md5_final(ctx, out) \ + memcpy (out, gcry_md_read (ctx, 0), MD5_DIGEST_LENGTH), gcry_md_close (ctx) +#define libssh2_md5(message, len, out) \ + gcry_md_hash_buffer (GCRY_MD_MD5, out, message, len) + +#define libssh2_hmac_ctx gcry_md_hd_t +#define libssh2_hmac_ctx_init(ctx) +#define libssh2_hmac_sha1_init(ctx, key, keylen) \ + gcry_md_open (ctx, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC), \ + gcry_md_setkey (*ctx, key, keylen) +#define libssh2_hmac_md5_init(ctx, key, keylen) \ + gcry_md_open (ctx, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC), \ + gcry_md_setkey (*ctx, key, keylen) +#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \ + gcry_md_open (ctx, GCRY_MD_RMD160, GCRY_MD_FLAG_HMAC), \ + gcry_md_setkey (*ctx, key, keylen) +#define libssh2_hmac_sha256_init(ctx, key, keylen) \ + gcry_md_open (ctx, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC), \ + gcry_md_setkey (*ctx, key, keylen) +#define libssh2_hmac_sha512_init(ctx, key, keylen) \ + gcry_md_open (ctx, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC), \ + gcry_md_setkey (*ctx, key, keylen) +#define libssh2_hmac_update(ctx, data, datalen) \ + gcry_md_write (ctx, (unsigned char *) data, datalen) +#define libssh2_hmac_final(ctx, data) \ + memcpy (data, gcry_md_read (ctx, 0), \ + gcry_md_get_algo_dlen (gcry_md_get_algo (ctx))) +#define libssh2_hmac_cleanup(ctx) gcry_md_close (*ctx); + +#define libssh2_crypto_init() gcry_control (GCRYCTL_DISABLE_SECMEM) +#define libssh2_crypto_exit() + +#define libssh2_rsa_ctx struct gcry_sexp + +#define _libssh2_rsa_free(rsactx) gcry_sexp_release (rsactx) + +#define libssh2_dsa_ctx struct gcry_sexp + +#define _libssh2_dsa_free(dsactx) gcry_sexp_release (dsactx) + +#define _libssh2_cipher_type(name) int name +#define _libssh2_cipher_ctx gcry_cipher_hd_t + +#define _libssh2_gcry_ciphermode(c,m) ((c << 8) | m) +#define _libssh2_gcry_cipher(c) (c >> 8) +#define _libssh2_gcry_mode(m) (m & 0xFF) + +#define _libssh2_cipher_aes256ctr \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR) +#define _libssh2_cipher_aes192ctr \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CTR) +#define _libssh2_cipher_aes128ctr \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CTR) +#define _libssh2_cipher_aes256 \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC) +#define _libssh2_cipher_aes192 \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC) +#define _libssh2_cipher_aes128 \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC) +#define _libssh2_cipher_blowfish \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC) +#define _libssh2_cipher_arcfour \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM) +#define _libssh2_cipher_cast5 \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC) +#define _libssh2_cipher_3des \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC) + + +#define _libssh2_cipher_dtor(ctx) gcry_cipher_close(*(ctx)) + +#define _libssh2_bn struct gcry_mpi +#define _libssh2_bn_ctx int +#define _libssh2_bn_ctx_new() 0 +#define _libssh2_bn_ctx_free(bnctx) ((void)0) +#define _libssh2_bn_init() gcry_mpi_new(0) +#define _libssh2_bn_init_from_bin() NULL /* because gcry_mpi_scan() creates a new bignum */ +#define _libssh2_bn_rand(bn, bits, top, bottom) gcry_mpi_randomize (bn, bits, GCRY_WEAK_RANDOM) +#define _libssh2_bn_mod_exp(r, a, p, m, ctx) gcry_mpi_powm (r, a, p, m) +#define _libssh2_bn_set_word(bn, val) gcry_mpi_set_ui(bn, val) +#define _libssh2_bn_from_bin(bn, len, val) gcry_mpi_scan(&((bn)), GCRYMPI_FMT_USG, val, len, NULL) +#define _libssh2_bn_to_bin(bn, val) gcry_mpi_print (GCRYMPI_FMT_USG, val, _libssh2_bn_bytes(bn), NULL, bn) +#define _libssh2_bn_bytes(bn) (gcry_mpi_get_nbits (bn) / 8 + ((gcry_mpi_get_nbits (bn) % 8 == 0) ? 0 : 1)) +#define _libssh2_bn_bits(bn) gcry_mpi_get_nbits (bn) +#define _libssh2_bn_free(bn) gcry_mpi_release(bn) + diff --git a/include/libssh2/libssh2.h b/include/libssh2/libssh2.h new file mode 100644 index 0000000..f3d976c --- /dev/null +++ b/include/libssh2/libssh2.h @@ -0,0 +1,1283 @@ +/* Copyright (c) 2004-2009, Sara Golemon + * Copyright (c) 2009-2015 Daniel Stenberg + * Copyright (c) 2010 Simon Josefsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#ifndef LIBSSH2_H +#define LIBSSH2_H 1 + +#define LIBSSH2_COPYRIGHT "2004-2015 The libssh2 project and its contributors." + +/* We use underscore instead of dash when appending DEV in dev versions just + to make the BANNER define (used by src/session.c) be a valid SSH + banner. Release versions have no appended strings and may of course not + have dashes either. */ +#define LIBSSH2_VERSION "1.6.1_DEV" + +/* The numeric version number is also available "in parts" by using these + defines: */ +#define LIBSSH2_VERSION_MAJOR 1 +#define LIBSSH2_VERSION_MINOR 6 +#define LIBSSH2_VERSION_PATCH 1 + +/* This is the numeric version of the libssh2 version number, meant for easier + parsing and comparions by programs. The LIBSSH2_VERSION_NUM define will + always follow this syntax: + + 0xXXYYZZ + + Where XX, YY and ZZ are the main version, release and patch numbers in + hexadecimal (using 8 bits each). All three numbers are always represented + using two digits. 1.2 would appear as "0x010200" while version 9.11.7 + appears as "0x090b07". + + This 6-digit (24 bits) hexadecimal number does not show pre-release number, + and it is always a greater number in a more recent release. It makes + comparisons with greater than and less than work. +*/ +#define LIBSSH2_VERSION_NUM 0x010601 + +/* + * This is the date and time when the full source package was created. The + * timestamp is not stored in the source code repo, as the timestamp is + * properly set in the tarballs by the maketgz script. + * + * The format of the date should follow this template: + * + * "Mon Feb 12 11:35:33 UTC 2007" + */ +#define LIBSSH2_TIMESTAMP "DEV" + +#ifndef RC_INVOKED + +#ifdef __cplusplus +extern "C" { +#endif +#ifdef _WIN32 +# include +# include +#endif + +#include +#include +#include +#include + +/* Allow alternate API prefix from CFLAGS or calling app */ +#ifndef LIBSSH2_API +# ifdef LIBSSH2_WIN32 +# ifdef _WINDLL +# ifdef LIBSSH2_LIBRARY +# define LIBSSH2_API __declspec(dllexport) +# else +# define LIBSSH2_API __declspec(dllimport) +# endif /* LIBSSH2_LIBRARY */ +# else +# define LIBSSH2_API +# endif +# else /* !LIBSSH2_WIN32 */ +# define LIBSSH2_API +# endif /* LIBSSH2_WIN32 */ +#endif /* LIBSSH2_API */ + +#ifdef HAVE_SYS_UIO_H +# include +#endif + +#if (defined(NETWARE) && !defined(__NOVELL_LIBC__)) +# include +typedef unsigned char uint8_t; +typedef unsigned int uint32_t; +#endif + +#ifdef _MSC_VER +typedef unsigned char uint8_t; +typedef unsigned int uint32_t; +typedef unsigned __int64 libssh2_uint64_t; +typedef __int64 libssh2_int64_t; +#ifndef ssize_t +typedef SSIZE_T ssize_t; +#endif +#else +typedef unsigned long long libssh2_uint64_t; +typedef long long libssh2_int64_t; +#endif + +#ifdef WIN32 +typedef SOCKET libssh2_socket_t; +#define LIBSSH2_INVALID_SOCKET INVALID_SOCKET +#else /* !WIN32 */ +typedef int libssh2_socket_t; +#define LIBSSH2_INVALID_SOCKET -1 +#endif /* WIN32 */ + +/* + * Determine whether there is small or large file support on windows. + */ + +#if defined(_MSC_VER) && !defined(_WIN32_WCE) +# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64) +# define LIBSSH2_USE_WIN32_LARGE_FILES +# else +# define LIBSSH2_USE_WIN32_SMALL_FILES +# endif +#endif + +#if defined(__MINGW32__) && !defined(LIBSSH2_USE_WIN32_LARGE_FILES) +# define LIBSSH2_USE_WIN32_LARGE_FILES +#endif + +#if defined(__WATCOMC__) && !defined(LIBSSH2_USE_WIN32_LARGE_FILES) +# define LIBSSH2_USE_WIN32_LARGE_FILES +#endif + +#if defined(__POCC__) +# undef LIBSSH2_USE_WIN32_LARGE_FILES +#endif + +#if defined(_WIN32) && !defined(LIBSSH2_USE_WIN32_LARGE_FILES) && !defined(LIBSSH2_USE_WIN32_SMALL_FILES) +# define LIBSSH2_USE_WIN32_SMALL_FILES +#endif + +/* + * Large file (>2Gb) support using WIN32 functions. + */ + +#ifdef LIBSSH2_USE_WIN32_LARGE_FILES +# include +# include +# include +# define LIBSSH2_STRUCT_STAT_SIZE_FORMAT "%I64d" +typedef struct _stati64 libssh2_struct_stat; +typedef __int64 libssh2_struct_stat_size; +#endif + +/* + * Small file (<2Gb) support using WIN32 functions. + */ + +#ifdef LIBSSH2_USE_WIN32_SMALL_FILES +# include +# include +# ifndef _WIN32_WCE +# define LIBSSH2_STRUCT_STAT_SIZE_FORMAT "%d" +typedef struct _stat libssh2_struct_stat; +typedef off_t libssh2_struct_stat_size; +# endif +#endif + +#ifndef LIBSSH2_STRUCT_STAT_SIZE_FORMAT +# define LIBSSH2_STRUCT_STAT_SIZE_FORMAT "%zd" +typedef struct stat libssh2_struct_stat; +typedef off_t libssh2_struct_stat_size; +#endif + +/* Part of every banner, user specified or not */ +#define LIBSSH2_SSH_BANNER "SSH-2.0-libssh2_" LIBSSH2_VERSION + +/* We *could* add a comment here if we so chose */ +#define LIBSSH2_SSH_DEFAULT_BANNER LIBSSH2_SSH_BANNER +#define LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF LIBSSH2_SSH_DEFAULT_BANNER "\r\n" + +/* Default generate and safe prime sizes for diffie-hellman-group-exchange-sha1 */ +#define LIBSSH2_DH_GEX_MINGROUP 1024 +#define LIBSSH2_DH_GEX_OPTGROUP 1536 +#define LIBSSH2_DH_GEX_MAXGROUP 2048 + +/* Defaults for pty requests */ +#define LIBSSH2_TERM_WIDTH 80 +#define LIBSSH2_TERM_HEIGHT 24 +#define LIBSSH2_TERM_WIDTH_PX 0 +#define LIBSSH2_TERM_HEIGHT_PX 0 + +/* 1/4 second */ +#define LIBSSH2_SOCKET_POLL_UDELAY 250000 +/* 0.25 * 120 == 30 seconds */ +#define LIBSSH2_SOCKET_POLL_MAXLOOPS 120 + +/* Maximum size to allow a payload to compress to, plays it safe by falling + short of spec limits */ +#define LIBSSH2_PACKET_MAXCOMP 32000 + +/* Maximum size to allow a payload to deccompress to, plays it safe by + allowing more than spec requires */ +#define LIBSSH2_PACKET_MAXDECOMP 40000 + +/* Maximum size for an inbound compressed payload, plays it safe by + overshooting spec limits */ +#define LIBSSH2_PACKET_MAXPAYLOAD 40000 + +/* Malloc callbacks */ +#define LIBSSH2_ALLOC_FUNC(name) void *name(size_t count, void **abstract) +#define LIBSSH2_REALLOC_FUNC(name) void *name(void *ptr, size_t count, \ + void **abstract) +#define LIBSSH2_FREE_FUNC(name) void name(void *ptr, void **abstract) + +typedef struct _LIBSSH2_USERAUTH_KBDINT_PROMPT +{ + char* text; + unsigned int length; + unsigned char echo; +} LIBSSH2_USERAUTH_KBDINT_PROMPT; + +typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE +{ + char* text; + unsigned int length; +} LIBSSH2_USERAUTH_KBDINT_RESPONSE; + +/* 'publickey' authentication callback */ +#define LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC(name) \ + int name(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, \ + const unsigned char *data, size_t data_len, void **abstract) + +/* 'keyboard-interactive' authentication callback */ +#define LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC(name_) \ + void name_(const char* name, int name_len, const char* instruction, \ + int instruction_len, int num_prompts, \ + const LIBSSH2_USERAUTH_KBDINT_PROMPT* prompts, \ + LIBSSH2_USERAUTH_KBDINT_RESPONSE* responses, void **abstract) + +/* Callbacks for special SSH packets */ +#define LIBSSH2_IGNORE_FUNC(name) \ + void name(LIBSSH2_SESSION *session, const char *message, int message_len, \ + void **abstract) + +#define LIBSSH2_DEBUG_FUNC(name) \ + void name(LIBSSH2_SESSION *session, int always_display, const char *message, \ + int message_len, const char *language, int language_len, \ + void **abstract) + +#define LIBSSH2_DISCONNECT_FUNC(name) \ + void name(LIBSSH2_SESSION *session, int reason, const char *message, \ + int message_len, const char *language, int language_len, \ + void **abstract) + +#define LIBSSH2_PASSWD_CHANGEREQ_FUNC(name) \ + void name(LIBSSH2_SESSION *session, char **newpw, int *newpw_len, \ + void **abstract) + +#define LIBSSH2_MACERROR_FUNC(name) \ + int name(LIBSSH2_SESSION *session, const char *packet, int packet_len, \ + void **abstract) + +#define LIBSSH2_X11_OPEN_FUNC(name) \ + void name(LIBSSH2_SESSION *session, LIBSSH2_CHANNEL *channel, \ + const char *shost, int sport, void **abstract) + +#define LIBSSH2_CHANNEL_CLOSE_FUNC(name) \ + void name(LIBSSH2_SESSION *session, void **session_abstract, \ + LIBSSH2_CHANNEL *channel, void **channel_abstract) + +/* I/O callbacks */ +#define LIBSSH2_RECV_FUNC(name) ssize_t name(libssh2_socket_t socket, \ + void *buffer, size_t length, \ + int flags, void **abstract) +#define LIBSSH2_SEND_FUNC(name) ssize_t name(libssh2_socket_t socket, \ + const void *buffer, size_t length,\ + int flags, void **abstract) + +/* libssh2_session_callback_set() constants */ +#define LIBSSH2_CALLBACK_IGNORE 0 +#define LIBSSH2_CALLBACK_DEBUG 1 +#define LIBSSH2_CALLBACK_DISCONNECT 2 +#define LIBSSH2_CALLBACK_MACERROR 3 +#define LIBSSH2_CALLBACK_X11 4 +#define LIBSSH2_CALLBACK_SEND 5 +#define LIBSSH2_CALLBACK_RECV 6 + +/* libssh2_session_method_pref() constants */ +#define LIBSSH2_METHOD_KEX 0 +#define LIBSSH2_METHOD_HOSTKEY 1 +#define LIBSSH2_METHOD_CRYPT_CS 2 +#define LIBSSH2_METHOD_CRYPT_SC 3 +#define LIBSSH2_METHOD_MAC_CS 4 +#define LIBSSH2_METHOD_MAC_SC 5 +#define LIBSSH2_METHOD_COMP_CS 6 +#define LIBSSH2_METHOD_COMP_SC 7 +#define LIBSSH2_METHOD_LANG_CS 8 +#define LIBSSH2_METHOD_LANG_SC 9 + +/* flags */ +#define LIBSSH2_FLAG_SIGPIPE 1 +#define LIBSSH2_FLAG_COMPRESS 2 + +typedef struct _LIBSSH2_SESSION LIBSSH2_SESSION; +typedef struct _LIBSSH2_CHANNEL LIBSSH2_CHANNEL; +typedef struct _LIBSSH2_LISTENER LIBSSH2_LISTENER; +typedef struct _LIBSSH2_KNOWNHOSTS LIBSSH2_KNOWNHOSTS; +typedef struct _LIBSSH2_AGENT LIBSSH2_AGENT; + +typedef struct _LIBSSH2_POLLFD { + unsigned char type; /* LIBSSH2_POLLFD_* below */ + + union { + libssh2_socket_t socket; /* File descriptors -- examined with + system select() call */ + LIBSSH2_CHANNEL *channel; /* Examined by checking internal state */ + LIBSSH2_LISTENER *listener; /* Read polls only -- are inbound + connections waiting to be accepted? */ + } fd; + + unsigned long events; /* Requested Events */ + unsigned long revents; /* Returned Events */ +} LIBSSH2_POLLFD; + +/* Poll FD Descriptor Types */ +#define LIBSSH2_POLLFD_SOCKET 1 +#define LIBSSH2_POLLFD_CHANNEL 2 +#define LIBSSH2_POLLFD_LISTENER 3 + +/* Note: Win32 Doesn't actually have a poll() implementation, so some of these + values are faked with select() data */ +/* Poll FD events/revents -- Match sys/poll.h where possible */ +#define LIBSSH2_POLLFD_POLLIN 0x0001 /* Data available to be read or + connection available -- + All */ +#define LIBSSH2_POLLFD_POLLPRI 0x0002 /* Priority data available to + be read -- Socket only */ +#define LIBSSH2_POLLFD_POLLEXT 0x0002 /* Extended data available to + be read -- Channel only */ +#define LIBSSH2_POLLFD_POLLOUT 0x0004 /* Can may be written -- + Socket/Channel */ +/* revents only */ +#define LIBSSH2_POLLFD_POLLERR 0x0008 /* Error Condition -- Socket */ +#define LIBSSH2_POLLFD_POLLHUP 0x0010 /* HangUp/EOF -- Socket */ +#define LIBSSH2_POLLFD_SESSION_CLOSED 0x0010 /* Session Disconnect */ +#define LIBSSH2_POLLFD_POLLNVAL 0x0020 /* Invalid request -- Socket + Only */ +#define LIBSSH2_POLLFD_POLLEX 0x0040 /* Exception Condition -- + Socket/Win32 */ +#define LIBSSH2_POLLFD_CHANNEL_CLOSED 0x0080 /* Channel Disconnect */ +#define LIBSSH2_POLLFD_LISTENER_CLOSED 0x0080 /* Listener Disconnect */ + +#define HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION +/* Block Direction Types */ +#define LIBSSH2_SESSION_BLOCK_INBOUND 0x0001 +#define LIBSSH2_SESSION_BLOCK_OUTBOUND 0x0002 + +/* Hash Types */ +#define LIBSSH2_HOSTKEY_HASH_MD5 1 +#define LIBSSH2_HOSTKEY_HASH_SHA1 2 + +/* Hostkey Types */ +#define LIBSSH2_HOSTKEY_TYPE_UNKNOWN 0 +#define LIBSSH2_HOSTKEY_TYPE_RSA 1 +#define LIBSSH2_HOSTKEY_TYPE_DSS 2 + +/* Disconnect Codes (defined by SSH protocol) */ +#define SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1 +#define SSH_DISCONNECT_PROTOCOL_ERROR 2 +#define SSH_DISCONNECT_KEY_EXCHANGE_FAILED 3 +#define SSH_DISCONNECT_RESERVED 4 +#define SSH_DISCONNECT_MAC_ERROR 5 +#define SSH_DISCONNECT_COMPRESSION_ERROR 6 +#define SSH_DISCONNECT_SERVICE_NOT_AVAILABLE 7 +#define SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8 +#define SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9 +#define SSH_DISCONNECT_CONNECTION_LOST 10 +#define SSH_DISCONNECT_BY_APPLICATION 11 +#define SSH_DISCONNECT_TOO_MANY_CONNECTIONS 12 +#define SSH_DISCONNECT_AUTH_CANCELLED_BY_USER 13 +#define SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14 +#define SSH_DISCONNECT_ILLEGAL_USER_NAME 15 + +/* Error Codes (defined by libssh2) */ +#define LIBSSH2_ERROR_NONE 0 + +/* The library once used -1 as a generic error return value on numerous places + through the code, which subsequently was converted to + LIBSSH2_ERROR_SOCKET_NONE uses over time. As this is a generic error code, + the goal is to never ever return this code but instead make sure that a + more accurate and descriptive error code is used. */ +#define LIBSSH2_ERROR_SOCKET_NONE -1 + +#define LIBSSH2_ERROR_BANNER_RECV -2 +#define LIBSSH2_ERROR_BANNER_SEND -3 +#define LIBSSH2_ERROR_INVALID_MAC -4 +#define LIBSSH2_ERROR_KEX_FAILURE -5 +#define LIBSSH2_ERROR_ALLOC -6 +#define LIBSSH2_ERROR_SOCKET_SEND -7 +#define LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE -8 +#define LIBSSH2_ERROR_TIMEOUT -9 +#define LIBSSH2_ERROR_HOSTKEY_INIT -10 +#define LIBSSH2_ERROR_HOSTKEY_SIGN -11 +#define LIBSSH2_ERROR_DECRYPT -12 +#define LIBSSH2_ERROR_SOCKET_DISCONNECT -13 +#define LIBSSH2_ERROR_PROTO -14 +#define LIBSSH2_ERROR_PASSWORD_EXPIRED -15 +#define LIBSSH2_ERROR_FILE -16 +#define LIBSSH2_ERROR_METHOD_NONE -17 +#define LIBSSH2_ERROR_AUTHENTICATION_FAILED -18 +#define LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED LIBSSH2_ERROR_AUTHENTICATION_FAILED +#define LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED -19 +#define LIBSSH2_ERROR_CHANNEL_OUTOFORDER -20 +#define LIBSSH2_ERROR_CHANNEL_FAILURE -21 +#define LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED -22 +#define LIBSSH2_ERROR_CHANNEL_UNKNOWN -23 +#define LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED -24 +#define LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED -25 +#define LIBSSH2_ERROR_CHANNEL_CLOSED -26 +#define LIBSSH2_ERROR_CHANNEL_EOF_SENT -27 +#define LIBSSH2_ERROR_SCP_PROTOCOL -28 +#define LIBSSH2_ERROR_ZLIB -29 +#define LIBSSH2_ERROR_SOCKET_TIMEOUT -30 +#define LIBSSH2_ERROR_SFTP_PROTOCOL -31 +#define LIBSSH2_ERROR_REQUEST_DENIED -32 +#define LIBSSH2_ERROR_METHOD_NOT_SUPPORTED -33 +#define LIBSSH2_ERROR_INVAL -34 +#define LIBSSH2_ERROR_INVALID_POLL_TYPE -35 +#define LIBSSH2_ERROR_PUBLICKEY_PROTOCOL -36 +#define LIBSSH2_ERROR_EAGAIN -37 +#define LIBSSH2_ERROR_BUFFER_TOO_SMALL -38 +#define LIBSSH2_ERROR_BAD_USE -39 +#define LIBSSH2_ERROR_COMPRESS -40 +#define LIBSSH2_ERROR_OUT_OF_BOUNDARY -41 +#define LIBSSH2_ERROR_AGENT_PROTOCOL -42 +#define LIBSSH2_ERROR_SOCKET_RECV -43 +#define LIBSSH2_ERROR_ENCRYPT -44 +#define LIBSSH2_ERROR_BAD_SOCKET -45 +#define LIBSSH2_ERROR_KNOWN_HOSTS -46 + +/* this is a define to provide the old (<= 1.2.7) name */ +#define LIBSSH2_ERROR_BANNER_NONE LIBSSH2_ERROR_BANNER_RECV + +/* Global API */ +#define LIBSSH2_INIT_NO_CRYPTO 0x0001 + +/* + * libssh2_init() + * + * Initialize the libssh2 functions. This typically initialize the + * crypto library. It uses a global state, and is not thread safe -- + * you must make sure this function is not called concurrently. + * + * Flags can be: + * 0: Normal initialize + * LIBSSH2_INIT_NO_CRYPTO: Do not initialize the crypto library (ie. + * OPENSSL_add_cipher_algoritms() for OpenSSL + * + * Returns 0 if succeeded, or a negative value for error. + */ +LIBSSH2_API int libssh2_init(int flags); + +/* + * libssh2_exit() + * + * Exit the libssh2 functions and free's all memory used internal. + */ +LIBSSH2_API void libssh2_exit(void); + +/* + * libssh2_free() + * + * Deallocate memory allocated by earlier call to libssh2 functions. + */ +LIBSSH2_API void libssh2_free(LIBSSH2_SESSION *session, void *ptr); + +/* + * libssh2_session_supported_algs() + * + * Fills algs with a list of supported acryptographic algorithms. Returns a + * non-negative number (number of supported algorithms) on success or a + * negative number (an eror code) on failure. + * + * NOTE: on success, algs must be deallocated (by calling libssh2_free) when + * not needed anymore + */ +LIBSSH2_API int libssh2_session_supported_algs(LIBSSH2_SESSION* session, + int method_type, + const char*** algs); + +/* Session API */ +LIBSSH2_API LIBSSH2_SESSION * +libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)), + LIBSSH2_FREE_FUNC((*my_free)), + LIBSSH2_REALLOC_FUNC((*my_realloc)), void *abstract); +#define libssh2_session_init() libssh2_session_init_ex(NULL, NULL, NULL, NULL) + +LIBSSH2_API void **libssh2_session_abstract(LIBSSH2_SESSION *session); + +LIBSSH2_API void *libssh2_session_callback_set(LIBSSH2_SESSION *session, + int cbtype, void *callback); +LIBSSH2_API int libssh2_session_banner_set(LIBSSH2_SESSION *session, + const char *banner); +LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION *session, + const char *banner); + +LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int sock); +LIBSSH2_API int libssh2_session_handshake(LIBSSH2_SESSION *session, + libssh2_socket_t sock); +LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, + int reason, + const char *description, + const char *lang); +#define libssh2_session_disconnect(session, description) \ + libssh2_session_disconnect_ex((session), SSH_DISCONNECT_BY_APPLICATION, \ + (description), "") + +LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session); + +LIBSSH2_API const char *libssh2_hostkey_hash(LIBSSH2_SESSION *session, + int hash_type); + +LIBSSH2_API const char *libssh2_session_hostkey(LIBSSH2_SESSION *session, + size_t *len, int *type); + +LIBSSH2_API int libssh2_session_method_pref(LIBSSH2_SESSION *session, + int method_type, + const char *prefs); +LIBSSH2_API const char *libssh2_session_methods(LIBSSH2_SESSION *session, + int method_type); +LIBSSH2_API int libssh2_session_last_error(LIBSSH2_SESSION *session, + char **errmsg, + int *errmsg_len, int want_buf); +LIBSSH2_API int libssh2_session_last_errno(LIBSSH2_SESSION *session); +LIBSSH2_API int libssh2_session_set_last_error(LIBSSH2_SESSION* session, + int errcode, + const char* errmsg); +LIBSSH2_API int libssh2_session_block_directions(LIBSSH2_SESSION *session); + +LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag, + int value); +LIBSSH2_API const char *libssh2_session_banner_get(LIBSSH2_SESSION *session); + +/* Userauth API */ +LIBSSH2_API char *libssh2_userauth_list(LIBSSH2_SESSION *session, + const char *username, + unsigned int username_len); +LIBSSH2_API int libssh2_userauth_authenticated(LIBSSH2_SESSION *session); + +LIBSSH2_API int libssh2_userauth_password_ex(LIBSSH2_SESSION *session, + const char *username, + unsigned int username_len, + const char *password, + unsigned int password_len, + LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb))); + +#define libssh2_userauth_password(session, username, password) \ + libssh2_userauth_password_ex((session), (username), \ + (unsigned int)strlen(username), \ + (password), (unsigned int)strlen(password), NULL) + +LIBSSH2_API int +libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, + const char *username, + unsigned int username_len, + const char *publickey, + const char *privatekey, + const char *passphrase); + +#define libssh2_userauth_publickey_fromfile(session, username, publickey, \ + privatekey, passphrase) \ + libssh2_userauth_publickey_fromfile_ex((session), (username), \ + (unsigned int)strlen(username), \ + (publickey), \ + (privatekey), (passphrase)) + +LIBSSH2_API int +libssh2_userauth_publickey(LIBSSH2_SESSION *session, + const char *username, + const unsigned char *pubkeydata, + size_t pubkeydata_len, + LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*sign_callback)), + void **abstract); + +LIBSSH2_API int +libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session, + const char *username, + unsigned int username_len, + const char *publickey, + const char *privatekey, + const char *passphrase, + const char *hostname, + unsigned int hostname_len, + const char *local_username, + unsigned int local_username_len); + +#define libssh2_userauth_hostbased_fromfile(session, username, publickey, \ + privatekey, passphrase, hostname) \ + libssh2_userauth_hostbased_fromfile_ex((session), (username), \ + (unsigned int)strlen(username), \ + (publickey), \ + (privatekey), (passphrase), \ + (hostname), \ + (unsigned int)strlen(hostname), \ + (username), \ + (unsigned int)strlen(username)) + +LIBSSH2_API int +libssh2_userauth_publickey_frommemory(LIBSSH2_SESSION *session, + const char *username, + size_t username_len, + const char *publickeyfiledata, + size_t publickeyfiledata_len, + const char *privatekeyfiledata, + size_t privatekeyfiledata_len, + const char *passphrase); + +/* + * response_callback is provided with filled by library prompts array, + * but client must allocate and fill individual responses. Responses + * array is already allocated. Responses data will be freed by libssh2 + * after callback return, but before subsequent callback invokation. + */ +LIBSSH2_API int +libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION* session, + const char *username, + unsigned int username_len, + LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*response_callback))); + +#define libssh2_userauth_keyboard_interactive(session, username, \ + response_callback) \ + libssh2_userauth_keyboard_interactive_ex((session), (username), \ + (unsigned int)strlen(username), \ + (response_callback)) + +LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, + long timeout); + +/* Channel API */ +#define LIBSSH2_CHANNEL_WINDOW_DEFAULT (2*1024*1024) +#define LIBSSH2_CHANNEL_PACKET_DEFAULT 32768 +#define LIBSSH2_CHANNEL_MINADJUST 1024 + +/* Extended Data Handling */ +#define LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL 0 +#define LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE 1 +#define LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE 2 + +#define SSH_EXTENDED_DATA_STDERR 1 + +/* Returned by any function that would block during a read/write opperation */ +#define LIBSSH2CHANNEL_EAGAIN LIBSSH2_ERROR_EAGAIN + +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_channel_open_ex(LIBSSH2_SESSION *session, const char *channel_type, + unsigned int channel_type_len, + unsigned int window_size, unsigned int packet_size, + const char *message, unsigned int message_len); + +#define libssh2_channel_open_session(session) \ + libssh2_channel_open_ex((session), "session", sizeof("session") - 1, \ + LIBSSH2_CHANNEL_WINDOW_DEFAULT, \ + LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0) + +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, const char *host, + int port, const char *shost, int sport); +#define libssh2_channel_direct_tcpip(session, host, port) \ + libssh2_channel_direct_tcpip_ex((session), (host), (port), "127.0.0.1", 22) + +LIBSSH2_API LIBSSH2_LISTENER * +libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, const char *host, + int port, int *bound_port, int queue_maxsize); +#define libssh2_channel_forward_listen(session, port) \ + libssh2_channel_forward_listen_ex((session), NULL, (port), NULL, 16) + +LIBSSH2_API int libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener); + +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_channel_forward_accept(LIBSSH2_LISTENER *listener); + +LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, + const char *varname, + unsigned int varname_len, + const char *value, + unsigned int value_len); + +#define libssh2_channel_setenv(channel, varname, value) \ + libssh2_channel_setenv_ex((channel), (varname), \ + (unsigned int)strlen(varname), (value), \ + (unsigned int)strlen(value)) + +LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, + const char *term, + unsigned int term_len, + const char *modes, + unsigned int modes_len, + int width, int height, + int width_px, int height_px); +#define libssh2_channel_request_pty(channel, term) \ + libssh2_channel_request_pty_ex((channel), (term), \ + (unsigned int)strlen(term), \ + NULL, 0, \ + LIBSSH2_TERM_WIDTH, LIBSSH2_TERM_HEIGHT, \ + LIBSSH2_TERM_WIDTH_PX, LIBSSH2_TERM_HEIGHT_PX) + +LIBSSH2_API int libssh2_channel_request_pty_size_ex(LIBSSH2_CHANNEL *channel, + int width, int height, + int width_px, + int height_px); +#define libssh2_channel_request_pty_size(channel, width, height) \ + libssh2_channel_request_pty_size_ex( (channel), (width), (height), 0, 0) + +LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, + int single_connection, + const char *auth_proto, + const char *auth_cookie, + int screen_number); +#define libssh2_channel_x11_req(channel, screen_number) \ + libssh2_channel_x11_req_ex((channel), 0, NULL, NULL, (screen_number)) + +LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, + const char *request, + unsigned int request_len, + const char *message, + unsigned int message_len); +#define libssh2_channel_shell(channel) \ + libssh2_channel_process_startup((channel), "shell", sizeof("shell") - 1, \ + NULL, 0) +#define libssh2_channel_exec(channel, command) \ + libssh2_channel_process_startup((channel), "exec", sizeof("exec") - 1, \ + (command), (unsigned int)strlen(command)) +#define libssh2_channel_subsystem(channel, subsystem) \ + libssh2_channel_process_startup((channel), "subsystem", \ + sizeof("subsystem") - 1, (subsystem), \ + (unsigned int)strlen(subsystem)) + +LIBSSH2_API ssize_t libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, + int stream_id, char *buf, + size_t buflen); +#define libssh2_channel_read(channel, buf, buflen) \ + libssh2_channel_read_ex((channel), 0, (buf), (buflen)) +#define libssh2_channel_read_stderr(channel, buf, buflen) \ + libssh2_channel_read_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen)) + +LIBSSH2_API int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, + int extended); + +LIBSSH2_API unsigned long +libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channel, + unsigned long *read_avail, + unsigned long *window_size_initial); +#define libssh2_channel_window_read(channel) \ + libssh2_channel_window_read_ex((channel), NULL, NULL) + +/* libssh2_channel_receive_window_adjust is DEPRECATED, do not use! */ +LIBSSH2_API unsigned long +libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel, + unsigned long adjustment, + unsigned char force); + +LIBSSH2_API int +libssh2_channel_receive_window_adjust2(LIBSSH2_CHANNEL *channel, + unsigned long adjustment, + unsigned char force, + unsigned int *storewindow); + +LIBSSH2_API ssize_t libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, + int stream_id, const char *buf, + size_t buflen); + +#define libssh2_channel_write(channel, buf, buflen) \ + libssh2_channel_write_ex((channel), 0, (buf), (buflen)) +#define libssh2_channel_write_stderr(channel, buf, buflen) \ + libssh2_channel_write_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen)) + +LIBSSH2_API unsigned long +libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *channel, + unsigned long *window_size_initial); +#define libssh2_channel_window_write(channel) \ + libssh2_channel_window_write_ex((channel), NULL) + +LIBSSH2_API void libssh2_session_set_blocking(LIBSSH2_SESSION* session, + int blocking); +LIBSSH2_API int libssh2_session_get_blocking(LIBSSH2_SESSION* session); + +LIBSSH2_API void libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, + int blocking); + +LIBSSH2_API void libssh2_session_set_timeout(LIBSSH2_SESSION* session, + long timeout); +LIBSSH2_API long libssh2_session_get_timeout(LIBSSH2_SESSION* session); + +/* libssh2_channel_handle_extended_data is DEPRECATED, do not use! */ +LIBSSH2_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, + int ignore_mode); +LIBSSH2_API int libssh2_channel_handle_extended_data2(LIBSSH2_CHANNEL *channel, + int ignore_mode); + +/* libssh2_channel_ignore_extended_data() is defined below for BC with version + * 0.1 + * + * Future uses should use libssh2_channel_handle_extended_data() directly if + * LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE is passed, extended data will be read + * (FIFO) from the standard data channel + */ +/* DEPRECATED */ +#define libssh2_channel_ignore_extended_data(channel, ignore) \ + libssh2_channel_handle_extended_data((channel), \ + (ignore) ? \ + LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE : \ + LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL ) + +#define LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA -1 +#define LIBSSH2_CHANNEL_FLUSH_ALL -2 +LIBSSH2_API int libssh2_channel_flush_ex(LIBSSH2_CHANNEL *channel, + int streamid); +#define libssh2_channel_flush(channel) libssh2_channel_flush_ex((channel), 0) +#define libssh2_channel_flush_stderr(channel) \ + libssh2_channel_flush_ex((channel), SSH_EXTENDED_DATA_STDERR) + +LIBSSH2_API int libssh2_channel_get_exit_status(LIBSSH2_CHANNEL* channel); +LIBSSH2_API int libssh2_channel_get_exit_signal(LIBSSH2_CHANNEL* channel, + char **exitsignal, + size_t *exitsignal_len, + char **errmsg, + size_t *errmsg_len, + char **langtag, + size_t *langtag_len); +LIBSSH2_API int libssh2_channel_send_eof(LIBSSH2_CHANNEL *channel); +LIBSSH2_API int libssh2_channel_eof(LIBSSH2_CHANNEL *channel); +LIBSSH2_API int libssh2_channel_wait_eof(LIBSSH2_CHANNEL *channel); +LIBSSH2_API int libssh2_channel_close(LIBSSH2_CHANNEL *channel); +LIBSSH2_API int libssh2_channel_wait_closed(LIBSSH2_CHANNEL *channel); +LIBSSH2_API int libssh2_channel_free(LIBSSH2_CHANNEL *channel); + +/* libssh2_scp_recv is DEPRECATED, do not use! */ +LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, + const char *path, + struct stat *sb); +/* Use libssh2_scp_recv2 for large (> 2GB) file support on windows */ +LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv2(LIBSSH2_SESSION *session, + const char *path, + libssh2_struct_stat *sb); +LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_send_ex(LIBSSH2_SESSION *session, + const char *path, int mode, + size_t size, long mtime, + long atime); +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_scp_send64(LIBSSH2_SESSION *session, const char *path, int mode, + libssh2_int64_t size, time_t mtime, time_t atime); + +#define libssh2_scp_send(session, path, mode, size) \ + libssh2_scp_send_ex((session), (path), (mode), (size), 0, 0) + +LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **dest, + unsigned int *dest_len, + const char *src, unsigned int src_len); + +LIBSSH2_API +const char *libssh2_version(int req_version_num); + +#define HAVE_LIBSSH2_KNOWNHOST_API 0x010101 /* since 1.1.1 */ +#define HAVE_LIBSSH2_VERSION_API 0x010100 /* libssh2_version since 1.1 */ + +struct libssh2_knownhost { + unsigned int magic; /* magic stored by the library */ + void *node; /* handle to the internal representation of this host */ + char *name; /* this is NULL if no plain text host name exists */ + char *key; /* key in base64/printable format */ + int typemask; +}; + +/* + * libssh2_knownhost_init + * + * Init a collection of known hosts. Returns the pointer to a collection. + * + */ +LIBSSH2_API LIBSSH2_KNOWNHOSTS * +libssh2_knownhost_init(LIBSSH2_SESSION *session); + +/* + * libssh2_knownhost_add + * + * Add a host and its associated key to the collection of known hosts. + * + * The 'type' argument specifies on what format the given host and keys are: + * + * plain - ascii "hostname.domain.tld" + * sha1 - SHA1( ) base64-encoded! + * custom - another hash + * + * If 'sha1' is selected as type, the salt must be provided to the salt + * argument. This too base64 encoded. + * + * The SHA-1 hash is what OpenSSH can be told to use in known_hosts files. If + * a custom type is used, salt is ignored and you must provide the host + * pre-hashed when checking for it in the libssh2_knownhost_check() function. + * + * The keylen parameter may be omitted (zero) if the key is provided as a + * NULL-terminated base64-encoded string. + */ + +/* host format (2 bits) */ +#define LIBSSH2_KNOWNHOST_TYPE_MASK 0xffff +#define LIBSSH2_KNOWNHOST_TYPE_PLAIN 1 +#define LIBSSH2_KNOWNHOST_TYPE_SHA1 2 /* always base64 encoded */ +#define LIBSSH2_KNOWNHOST_TYPE_CUSTOM 3 + +/* key format (2 bits) */ +#define LIBSSH2_KNOWNHOST_KEYENC_MASK (3<<16) +#define LIBSSH2_KNOWNHOST_KEYENC_RAW (1<<16) +#define LIBSSH2_KNOWNHOST_KEYENC_BASE64 (2<<16) + +/* type of key (2 bits) */ +#define LIBSSH2_KNOWNHOST_KEY_MASK (7<<18) +#define LIBSSH2_KNOWNHOST_KEY_SHIFT 18 +#define LIBSSH2_KNOWNHOST_KEY_RSA1 (1<<18) +#define LIBSSH2_KNOWNHOST_KEY_SSHRSA (2<<18) +#define LIBSSH2_KNOWNHOST_KEY_SSHDSS (3<<18) +#define LIBSSH2_KNOWNHOST_KEY_UNKNOWN (7<<18) + +LIBSSH2_API int +libssh2_knownhost_add(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, + const char *salt, + const char *key, size_t keylen, int typemask, + struct libssh2_knownhost **store); + +/* + * libssh2_knownhost_addc + * + * Add a host and its associated key to the collection of known hosts. + * + * Takes a comment argument that may be NULL. A NULL comment indicates + * there is no comment and the entry will end directly after the key + * when written out to a file. An empty string "" comment will indicate an + * empty comment which will cause a single space to be written after the key. + * + * The 'type' argument specifies on what format the given host and keys are: + * + * plain - ascii "hostname.domain.tld" + * sha1 - SHA1( ) base64-encoded! + * custom - another hash + * + * If 'sha1' is selected as type, the salt must be provided to the salt + * argument. This too base64 encoded. + * + * The SHA-1 hash is what OpenSSH can be told to use in known_hosts files. If + * a custom type is used, salt is ignored and you must provide the host + * pre-hashed when checking for it in the libssh2_knownhost_check() function. + * + * The keylen parameter may be omitted (zero) if the key is provided as a + * NULL-terminated base64-encoded string. + */ + +LIBSSH2_API int +libssh2_knownhost_addc(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, + const char *salt, + const char *key, size_t keylen, + const char *comment, size_t commentlen, int typemask, + struct libssh2_knownhost **store); + +/* + * libssh2_knownhost_check + * + * Check a host and its associated key against the collection of known hosts. + * + * The type is the type/format of the given host name. + * + * plain - ascii "hostname.domain.tld" + * custom - prehashed base64 encoded. Note that this cannot use any salts. + * + * + * 'knownhost' may be set to NULL if you don't care about that info. + * + * Returns: + * + * LIBSSH2_KNOWNHOST_CHECK_* values, see below + * + */ + +#define LIBSSH2_KNOWNHOST_CHECK_MATCH 0 +#define LIBSSH2_KNOWNHOST_CHECK_MISMATCH 1 +#define LIBSSH2_KNOWNHOST_CHECK_NOTFOUND 2 +#define LIBSSH2_KNOWNHOST_CHECK_FAILURE 3 + +LIBSSH2_API int +libssh2_knownhost_check(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, const char *key, size_t keylen, + int typemask, + struct libssh2_knownhost **knownhost); + +/* this function is identital to the above one, but also takes a port + argument that allows libssh2 to do a better check */ +LIBSSH2_API int +libssh2_knownhost_checkp(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, int port, + const char *key, size_t keylen, + int typemask, + struct libssh2_knownhost **knownhost); + +/* + * libssh2_knownhost_del + * + * Remove a host from the collection of known hosts. The 'entry' struct is + * retrieved by a call to libssh2_knownhost_check(). + * + */ +LIBSSH2_API int +libssh2_knownhost_del(LIBSSH2_KNOWNHOSTS *hosts, + struct libssh2_knownhost *entry); + +/* + * libssh2_knownhost_free + * + * Free an entire collection of known hosts. + * + */ +LIBSSH2_API void +libssh2_knownhost_free(LIBSSH2_KNOWNHOSTS *hosts); + +/* + * libssh2_knownhost_readline() + * + * Pass in a line of a file of 'type'. It makes libssh2 read this line. + * + * LIBSSH2_KNOWNHOST_FILE_OPENSSH is the only supported type. + * + */ +LIBSSH2_API int +libssh2_knownhost_readline(LIBSSH2_KNOWNHOSTS *hosts, + const char *line, size_t len, int type); + +/* + * libssh2_knownhost_readfile + * + * Add hosts+key pairs from a given file. + * + * Returns a negative value for error or number of successfully added hosts. + * + * This implementation currently only knows one 'type' (openssh), all others + * are reserved for future use. + */ + +#define LIBSSH2_KNOWNHOST_FILE_OPENSSH 1 + +LIBSSH2_API int +libssh2_knownhost_readfile(LIBSSH2_KNOWNHOSTS *hosts, + const char *filename, int type); + +/* + * libssh2_knownhost_writeline() + * + * Ask libssh2 to convert a known host to an output line for storage. + * + * Note that this function returns LIBSSH2_ERROR_BUFFER_TOO_SMALL if the given + * output buffer is too small to hold the desired output. + * + * This implementation currently only knows one 'type' (openssh), all others + * are reserved for future use. + * + */ +LIBSSH2_API int +libssh2_knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts, + struct libssh2_knownhost *known, + char *buffer, size_t buflen, + size_t *outlen, /* the amount of written data */ + int type); + +/* + * libssh2_knownhost_writefile + * + * Write hosts+key pairs to a given file. + * + * This implementation currently only knows one 'type' (openssh), all others + * are reserved for future use. + */ + +LIBSSH2_API int +libssh2_knownhost_writefile(LIBSSH2_KNOWNHOSTS *hosts, + const char *filename, int type); + +/* + * libssh2_knownhost_get() + * + * Traverse the internal list of known hosts. Pass NULL to 'prev' to get + * the first one. Or pass a poiner to the previously returned one to get the + * next. + * + * Returns: + * 0 if a fine host was stored in 'store' + * 1 if end of hosts + * [negative] on errors + */ +LIBSSH2_API int +libssh2_knownhost_get(LIBSSH2_KNOWNHOSTS *hosts, + struct libssh2_knownhost **store, + struct libssh2_knownhost *prev); + +#define HAVE_LIBSSH2_AGENT_API 0x010202 /* since 1.2.2 */ + +struct libssh2_agent_publickey { + unsigned int magic; /* magic stored by the library */ + void *node; /* handle to the internal representation of key */ + unsigned char *blob; /* public key blob */ + size_t blob_len; /* length of the public key blob */ + char *comment; /* comment in printable format */ +}; + +/* + * libssh2_agent_init + * + * Init an ssh-agent handle. Returns the pointer to the handle. + * + */ +LIBSSH2_API LIBSSH2_AGENT * +libssh2_agent_init(LIBSSH2_SESSION *session); + +/* + * libssh2_agent_connect() + * + * Connect to an ssh-agent. + * + * Returns 0 if succeeded, or a negative value for error. + */ +LIBSSH2_API int +libssh2_agent_connect(LIBSSH2_AGENT *agent); + +/* + * libssh2_agent_list_identities() + * + * Request an ssh-agent to list identities. + * + * Returns 0 if succeeded, or a negative value for error. + */ +LIBSSH2_API int +libssh2_agent_list_identities(LIBSSH2_AGENT *agent); + +/* + * libssh2_agent_get_identity() + * + * Traverse the internal list of public keys. Pass NULL to 'prev' to get + * the first one. Or pass a poiner to the previously returned one to get the + * next. + * + * Returns: + * 0 if a fine public key was stored in 'store' + * 1 if end of public keys + * [negative] on errors + */ +LIBSSH2_API int +libssh2_agent_get_identity(LIBSSH2_AGENT *agent, + struct libssh2_agent_publickey **store, + struct libssh2_agent_publickey *prev); + +/* + * libssh2_agent_userauth() + * + * Do publickey user authentication with the help of ssh-agent. + * + * Returns 0 if succeeded, or a negative value for error. + */ +LIBSSH2_API int +libssh2_agent_userauth(LIBSSH2_AGENT *agent, + const char *username, + struct libssh2_agent_publickey *identity); + +/* + * libssh2_agent_disconnect() + * + * Close a connection to an ssh-agent. + * + * Returns 0 if succeeded, or a negative value for error. + */ +LIBSSH2_API int +libssh2_agent_disconnect(LIBSSH2_AGENT *agent); + +/* + * libssh2_agent_free() + * + * Free an ssh-agent handle. This function also frees the internal + * collection of public keys. + */ +LIBSSH2_API void +libssh2_agent_free(LIBSSH2_AGENT *agent); + + +/* + * libssh2_keepalive_config() + * + * Set how often keepalive messages should be sent. WANT_REPLY + * indicates whether the keepalive messages should request a response + * from the server. INTERVAL is number of seconds that can pass + * without any I/O, use 0 (the default) to disable keepalives. To + * avoid some busy-loop corner-cases, if you specify an interval of 1 + * it will be treated as 2. + * + * Note that non-blocking applications are responsible for sending the + * keepalive messages using libssh2_keepalive_send(). + */ +LIBSSH2_API void libssh2_keepalive_config (LIBSSH2_SESSION *session, + int want_reply, + unsigned interval); + +/* + * libssh2_keepalive_send() + * + * Send a keepalive message if needed. SECONDS_TO_NEXT indicates how + * many seconds you can sleep after this call before you need to call + * it again. Returns 0 on success, or LIBSSH2_ERROR_SOCKET_SEND on + * I/O errors. + */ +LIBSSH2_API int libssh2_keepalive_send (LIBSSH2_SESSION *session, + int *seconds_to_next); + +/* NOTE NOTE NOTE + libssh2_trace() has no function in builds that aren't built with debug + enabled + */ +LIBSSH2_API int libssh2_trace(LIBSSH2_SESSION *session, int bitmask); +#define LIBSSH2_TRACE_TRANS (1<<1) +#define LIBSSH2_TRACE_KEX (1<<2) +#define LIBSSH2_TRACE_AUTH (1<<3) +#define LIBSSH2_TRACE_CONN (1<<4) +#define LIBSSH2_TRACE_SCP (1<<5) +#define LIBSSH2_TRACE_SFTP (1<<6) +#define LIBSSH2_TRACE_ERROR (1<<7) +#define LIBSSH2_TRACE_PUBLICKEY (1<<8) +#define LIBSSH2_TRACE_SOCKET (1<<9) + +typedef void (*libssh2_trace_handler_func)(LIBSSH2_SESSION*, + void*, + const char *, + size_t); +LIBSSH2_API int libssh2_trace_sethandler(LIBSSH2_SESSION *session, + void* context, + libssh2_trace_handler_func callback); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* !RC_INVOKED */ + +#endif /* LIBSSH2_H */ diff --git a/include/libssh2/libssh2_config.h.in b/include/libssh2/libssh2_config.h.in new file mode 100644 index 0000000..6a52f0c --- /dev/null +++ b/include/libssh2/libssh2_config.h.in @@ -0,0 +1,223 @@ +/* src/libssh2_config.h.in. Generated from configure.ac by autoheader. */ + +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. + */ +#undef CRAY_STACKSEG_END + +/* Define to 1 if using `alloca.c'. */ +#undef C_ALLOCA + +/* Define to 1 if you have `alloca', as a function or macro. */ +#undef HAVE_ALLOCA + +/* Define to 1 if you have and it should be used (not on Ultrix). + */ +#undef HAVE_ALLOCA_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ARPA_INET_H + +/* disabled non-blocking sockets */ +#undef HAVE_DISABLED_NONBLOCKING + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ERRNO_H + +/* Define to 1 if you have the `EVP_aes_128_ctr' function. */ +#undef HAVE_EVP_AES_128_CTR + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* use FIONBIO for non-blocking sockets */ +#undef HAVE_FIONBIO + +/* Define to 1 if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* use ioctlsocket() for non-blocking sockets */ +#undef HAVE_IOCTLSOCKET + +/* use Ioctlsocket() for non-blocking sockets */ +#undef HAVE_IOCTLSOCKET_CASE + +/* Define if you have the gcrypt library. */ +#undef HAVE_LIBGCRYPT + +/* Define if you have the ssl library. */ +#undef HAVE_LIBSSL + +/* Define if you have the z library. */ +#undef HAVE_LIBZ + +/* Define to 1 if the compiler supports the 'long long' data type. */ +#undef HAVE_LONGLONG + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IN_H + +/* use O_NONBLOCK for non-blocking sockets */ +#undef HAVE_O_NONBLOCK + +/* Define to 1 if you have the `poll' function. */ +#undef HAVE_POLL + +/* Define to 1 if you have the select function. */ +#undef HAVE_SELECT + +/* use SO_NONBLOCK for non-blocking sockets */ +#undef HAVE_SO_NONBLOCK + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strtoll' function. */ +#undef HAVE_STRTOLL + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_IOCTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_UIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_UN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_WINDOWS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_WINSOCK2_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_WS2TCPIP_H + +/* to make a symbol visible */ +#undef LIBSSH2_API + +/* Enable "none" cipher -- NOT RECOMMENDED */ +#undef LIBSSH2_CRYPT_NONE + +/* Enable newer diffie-hellman-group-exchange-sha1 syntax */ +#undef LIBSSH2_DH_GEX_NEW + +/* Compile in zlib support */ +#undef LIBSSH2_HAVE_ZLIB + +/* Use libgcrypt */ +#undef LIBSSH2_LIBGCRYPT + +/* Enable "none" MAC -- NOT RECOMMENDED */ +#undef LIBSSH2_MAC_NONE + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + +/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ +#undef NEED_REENTRANT + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +#undef STACK_DIRECTION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +# undef WORDS_BIGENDIAN +# endif +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif diff --git a/include/libssh2/libssh2_priv.h b/include/libssh2/libssh2_priv.h new file mode 100644 index 0000000..1023943 --- /dev/null +++ b/include/libssh2/libssh2_priv.h @@ -0,0 +1,1062 @@ +/* Copyright (c) 2004-2008, 2010, Sara Golemon + * Copyright (c) 2009-2014 by Daniel Stenberg + * Copyright (c) 2010 Simon Josefsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#ifndef LIBSSH2_PRIV_H +#define LIBSSH2_PRIV_H 1 + +#define LIBSSH2_LIBRARY +#include "libssh2_config.h" + +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#undef WIN32_LEAN_AND_MEAN +#endif + +#ifdef HAVE_WS2TCPIP_H +#include +#endif + +#include +#include + +/* The following CPP block should really only be in session.c and + packet.c. However, AIX have #define's for 'events' and 'revents' + and we are using those names in libssh2.h, so we need to include + the AIX headers first, to make sure all code is compiled with + consistent names of these fields. While arguable the best would to + change libssh2.h to use other names, that would break backwards + compatibility. For more information, see: + http://www.mail-archive.com/libssh2-devel%40lists.sourceforge.net/msg00003.html + http://www.mail-archive.com/libssh2-devel%40lists.sourceforge.net/msg00224.html +*/ +#ifdef HAVE_POLL +# include +#else +# if defined(HAVE_SELECT) && !defined(WIN32) +# ifdef HAVE_SYS_SELECT_H +# include +# else +# include +# include +# endif +# endif +#endif + +/* Needed for struct iovec on some platforms */ +#ifdef HAVE_SYS_UIO_H +#include +#endif + +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#ifdef HAVE_INTTYPES_H +#include +#endif + +#include "libssh2.h" +#include "libssh2_publickey.h" +#include "libssh2_sftp.h" +#include "misc.h" /* for the linked list stuff */ + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +#ifdef _MSC_VER +/* "inline" keyword is valid only with C++ engine! */ +#define inline __inline +#endif + +/* Provide iovec / writev on WIN32 platform. */ +#ifdef WIN32 + +struct iovec { + size_t iov_len; + void * iov_base; +}; + +static inline int writev(int sock, struct iovec *iov, int nvecs) +{ + DWORD ret; + if (WSASend(sock, (LPWSABUF)iov, nvecs, &ret, 0, NULL, NULL) == 0) { + return ret; + } + return -1; +} + +#endif /* WIN32 */ + +#include "crypto.h" + +#ifdef HAVE_WINSOCK2_H + +#include +#include + +#endif + +/* RFC4253 section 6.1 Maximum Packet Length says: + * + * "All implementations MUST be able to process packets with + * uncompressed payload length of 32768 bytes or less and + * total packet size of 35000 bytes or less (including length, + * padding length, payload, padding, and MAC.)." + */ +#define MAX_SSH_PACKET_LEN 35000 +#define MAX_SHA_DIGEST_LEN SHA256_DIGEST_LENGTH + +#define LIBSSH2_ALLOC(session, count) \ + session->alloc((count), &(session)->abstract) +#define LIBSSH2_CALLOC(session, count) _libssh2_calloc(session, count) +#define LIBSSH2_REALLOC(session, ptr, count) \ + ((ptr) ? session->realloc((ptr), (count), &(session)->abstract) : \ + session->alloc((count), &(session)->abstract)) +#define LIBSSH2_FREE(session, ptr) \ + session->free((ptr), &(session)->abstract) +#define LIBSSH2_IGNORE(session, data, datalen) \ + session->ssh_msg_ignore((session), (data), (datalen), &(session)->abstract) +#define LIBSSH2_DEBUG(session, always_display, message, message_len, \ + language, language_len) \ + session->ssh_msg_debug((session), (always_display), (message), \ + (message_len), (language), (language_len), \ + &(session)->abstract) +#define LIBSSH2_DISCONNECT(session, reason, message, message_len, \ + language, language_len) \ + session->ssh_msg_disconnect((session), (reason), (message), \ + (message_len), (language), (language_len), \ + &(session)->abstract) + +#define LIBSSH2_MACERROR(session, data, datalen) \ + session->macerror((session), (data), (datalen), &(session)->abstract) +#define LIBSSH2_X11_OPEN(channel, shost, sport) \ + channel->session->x11(((channel)->session), (channel), \ + (shost), (sport), (&(channel)->session->abstract)) + +#define LIBSSH2_CHANNEL_CLOSE(session, channel) \ + channel->close_cb((session), &(session)->abstract, \ + (channel), &(channel)->abstract) + +#define LIBSSH2_SEND_FD(session, fd, buffer, length, flags) \ + session->send(fd, buffer, length, flags, &session->abstract) +#define LIBSSH2_RECV_FD(session, fd, buffer, length, flags) \ + session->recv(fd, buffer, length, flags, &session->abstract) + +#define LIBSSH2_SEND(session, buffer, length, flags) \ + LIBSSH2_SEND_FD(session, session->socket_fd, buffer, length, flags) +#define LIBSSH2_RECV(session, buffer, length, flags) \ + LIBSSH2_RECV_FD(session, session->socket_fd, buffer, length, flags) + +typedef struct _LIBSSH2_KEX_METHOD LIBSSH2_KEX_METHOD; +typedef struct _LIBSSH2_HOSTKEY_METHOD LIBSSH2_HOSTKEY_METHOD; +typedef struct _LIBSSH2_CRYPT_METHOD LIBSSH2_CRYPT_METHOD; +typedef struct _LIBSSH2_COMP_METHOD LIBSSH2_COMP_METHOD; + +typedef struct _LIBSSH2_PACKET LIBSSH2_PACKET; + +typedef enum +{ + libssh2_NB_state_idle = 0, + libssh2_NB_state_allocated, + libssh2_NB_state_created, + libssh2_NB_state_sent, + libssh2_NB_state_sent1, + libssh2_NB_state_sent2, + libssh2_NB_state_sent3, + libssh2_NB_state_sent4, + libssh2_NB_state_sent5, + libssh2_NB_state_sent6, + libssh2_NB_state_sent7, + libssh2_NB_state_jump1, + libssh2_NB_state_jump2, + libssh2_NB_state_jump3, + libssh2_NB_state_jump4, + libssh2_NB_state_jump5, + libssh2_NB_state_end +} libssh2_nonblocking_states; + +typedef struct packet_require_state_t +{ + libssh2_nonblocking_states state; + time_t start; +} packet_require_state_t; + +typedef struct packet_requirev_state_t +{ + time_t start; +} packet_requirev_state_t; + +typedef struct kmdhgGPshakex_state_t +{ + libssh2_nonblocking_states state; + unsigned char *e_packet; + unsigned char *s_packet; + unsigned char *tmp; + unsigned char h_sig_comp[MAX_SHA_DIGEST_LEN]; + unsigned char c; + size_t e_packet_len; + size_t s_packet_len; + size_t tmp_len; + _libssh2_bn_ctx *ctx; + _libssh2_bn *x; + _libssh2_bn *e; + _libssh2_bn *f; + _libssh2_bn *k; + unsigned char *s; + unsigned char *f_value; + unsigned char *k_value; + unsigned char *h_sig; + size_t f_value_len; + size_t k_value_len; + size_t h_sig_len; + void *exchange_hash; + packet_require_state_t req_state; + libssh2_nonblocking_states burn_state; +} kmdhgGPshakex_state_t; + +typedef struct key_exchange_state_low_t +{ + libssh2_nonblocking_states state; + packet_require_state_t req_state; + kmdhgGPshakex_state_t exchange_state; + _libssh2_bn *p; /* SSH2 defined value (p_value) */ + _libssh2_bn *g; /* SSH2 defined value (2) */ + unsigned char request[13]; + unsigned char *data; + size_t request_len; + size_t data_len; +} key_exchange_state_low_t; + +typedef struct key_exchange_state_t +{ + libssh2_nonblocking_states state; + packet_require_state_t req_state; + key_exchange_state_low_t key_state_low; + unsigned char *data; + size_t data_len; + unsigned char *oldlocal; + size_t oldlocal_len; +} key_exchange_state_t; + +#define FwdNotReq "Forward not requested" + +typedef struct packet_queue_listener_state_t +{ + libssh2_nonblocking_states state; + unsigned char packet[17 + (sizeof(FwdNotReq) - 1)]; + unsigned char *host; + unsigned char *shost; + uint32_t sender_channel; + uint32_t initial_window_size; + uint32_t packet_size; + uint32_t port; + uint32_t sport; + uint32_t host_len; + uint32_t shost_len; + LIBSSH2_CHANNEL *channel; +} packet_queue_listener_state_t; + +#define X11FwdUnAvil "X11 Forward Unavailable" + +typedef struct packet_x11_open_state_t +{ + libssh2_nonblocking_states state; + unsigned char packet[17 + (sizeof(X11FwdUnAvil) - 1)]; + unsigned char *shost; + uint32_t sender_channel; + uint32_t initial_window_size; + uint32_t packet_size; + uint32_t sport; + uint32_t shost_len; + LIBSSH2_CHANNEL *channel; +} packet_x11_open_state_t; + +struct _LIBSSH2_PACKET +{ + struct list_node node; /* linked list header */ + + /* the raw unencrypted payload */ + unsigned char *data; + size_t data_len; + + /* Where to start reading data from, + * used for channel data that's been partially consumed */ + size_t data_head; +}; + +typedef struct _libssh2_channel_data +{ + /* Identifier */ + uint32_t id; + + /* Limits and restrictions */ + uint32_t window_size_initial, window_size, packet_size; + + /* Set to 1 when CHANNEL_CLOSE / CHANNEL_EOF sent/received */ + char close, eof, extended_data_ignore_mode; +} libssh2_channel_data; + +struct _LIBSSH2_CHANNEL +{ + struct list_node node; + + unsigned char *channel_type; + unsigned channel_type_len; + + /* channel's program exit status */ + int exit_status; + + /* channel's program exit signal (without the SIG prefix) */ + char *exit_signal; + + libssh2_channel_data local, remote; + /* Amount of bytes to be refunded to receive window (but not yet sent) */ + uint32_t adjust_queue; + /* Data immediately available for reading */ + uint32_t read_avail; + + LIBSSH2_SESSION *session; + + void *abstract; + LIBSSH2_CHANNEL_CLOSE_FUNC((*close_cb)); + + /* State variables used in libssh2_channel_setenv_ex() */ + libssh2_nonblocking_states setenv_state; + unsigned char *setenv_packet; + size_t setenv_packet_len; + unsigned char setenv_local_channel[4]; + packet_requirev_state_t setenv_packet_requirev_state; + + /* State variables used in libssh2_channel_request_pty_ex() + libssh2_channel_request_pty_size_ex() */ + libssh2_nonblocking_states reqPTY_state; + unsigned char reqPTY_packet[41 + 256]; + size_t reqPTY_packet_len; + unsigned char reqPTY_local_channel[4]; + packet_requirev_state_t reqPTY_packet_requirev_state; + + /* State variables used in libssh2_channel_x11_req_ex() */ + libssh2_nonblocking_states reqX11_state; + unsigned char *reqX11_packet; + size_t reqX11_packet_len; + unsigned char reqX11_local_channel[4]; + packet_requirev_state_t reqX11_packet_requirev_state; + + /* State variables used in libssh2_channel_process_startup() */ + libssh2_nonblocking_states process_state; + unsigned char *process_packet; + size_t process_packet_len; + unsigned char process_local_channel[4]; + packet_requirev_state_t process_packet_requirev_state; + + /* State variables used in libssh2_channel_flush_ex() */ + libssh2_nonblocking_states flush_state; + size_t flush_refund_bytes; + size_t flush_flush_bytes; + + /* State variables used in libssh2_channel_receive_window_adjust() */ + libssh2_nonblocking_states adjust_state; + unsigned char adjust_adjust[9]; /* packet_type(1) + channel(4) + adjustment(4) */ + + /* State variables used in libssh2_channel_read_ex() */ + libssh2_nonblocking_states read_state; + + uint32_t read_local_id; + + /* State variables used in libssh2_channel_write_ex() */ + libssh2_nonblocking_states write_state; + unsigned char write_packet[13]; + size_t write_packet_len; + size_t write_bufwrite; + + /* State variables used in libssh2_channel_close() */ + libssh2_nonblocking_states close_state; + unsigned char close_packet[5]; + + /* State variables used in libssh2_channel_wait_closedeof() */ + libssh2_nonblocking_states wait_eof_state; + + /* State variables used in libssh2_channel_wait_closed() */ + libssh2_nonblocking_states wait_closed_state; + + /* State variables used in libssh2_channel_free() */ + libssh2_nonblocking_states free_state; + + /* State variables used in libssh2_channel_handle_extended_data2() */ + libssh2_nonblocking_states extData2_state; + +}; + +struct _LIBSSH2_LISTENER +{ + struct list_node node; /* linked list header */ + + LIBSSH2_SESSION *session; + + char *host; + int port; + + /* a list of CHANNELs for this listener */ + struct list_head queue; + + int queue_size; + int queue_maxsize; + + /* State variables used in libssh2_channel_forward_cancel() */ + libssh2_nonblocking_states chanFwdCncl_state; + unsigned char *chanFwdCncl_data; + size_t chanFwdCncl_data_len; +}; + +typedef struct _libssh2_endpoint_data +{ + unsigned char *banner; + + unsigned char *kexinit; + size_t kexinit_len; + + const LIBSSH2_CRYPT_METHOD *crypt; + void *crypt_abstract; + + const struct _LIBSSH2_MAC_METHOD *mac; + uint32_t seqno; + void *mac_abstract; + + const LIBSSH2_COMP_METHOD *comp; + void *comp_abstract; + + /* Method Preferences -- NULL yields "load order" */ + char *crypt_prefs; + char *mac_prefs; + char *comp_prefs; + char *lang_prefs; +} libssh2_endpoint_data; + +#define PACKETBUFSIZE (1024*16) + +struct transportpacket +{ + /* ------------- for incoming data --------------- */ + unsigned char buf[PACKETBUFSIZE]; + unsigned char init[5]; /* first 5 bytes of the incoming data stream, + still encrypted */ + size_t writeidx; /* at what array index we do the next write into + the buffer */ + size_t readidx; /* at what array index we do the next read from + the buffer */ + uint32_t packet_length; /* the most recent packet_length as read from the + network data */ + uint8_t padding_length; /* the most recent padding_length as read from the + network data */ + size_t data_num; /* How much of the total package that has been read + so far. */ + size_t total_num; /* How much a total package is supposed to be, in + number of bytes. A full package is + packet_length + padding_length + 4 + + mac_length. */ + unsigned char *payload; /* this is a pointer to a LIBSSH2_ALLOC() + area to which we write decrypted data */ + unsigned char *wptr; /* write pointer into the payload to where we + are currently writing decrypted data */ + + /* ------------- for outgoing data --------------- */ + unsigned char outbuf[MAX_SSH_PACKET_LEN]; /* area for the outgoing data */ + + int ototal_num; /* size of outbuf in number of bytes */ + const unsigned char *odata; /* original pointer to the data */ + size_t olen; /* original size of the data we stored in + outbuf */ + size_t osent; /* number of bytes already sent */ +}; + +struct _LIBSSH2_PUBLICKEY +{ + LIBSSH2_CHANNEL *channel; + uint32_t version; + + /* State variables used in libssh2_publickey_packet_receive() */ + libssh2_nonblocking_states receive_state; + unsigned char *receive_packet; + size_t receive_packet_len; + + /* State variables used in libssh2_publickey_add_ex() */ + libssh2_nonblocking_states add_state; + unsigned char *add_packet; + unsigned char *add_s; + + /* State variables used in libssh2_publickey_remove_ex() */ + libssh2_nonblocking_states remove_state; + unsigned char *remove_packet; + unsigned char *remove_s; + + /* State variables used in libssh2_publickey_list_fetch() */ + libssh2_nonblocking_states listFetch_state; + unsigned char *listFetch_s; + unsigned char listFetch_buffer[12]; + unsigned char *listFetch_data; + size_t listFetch_data_len; +}; + +#define LIBSSH2_SCP_RESPONSE_BUFLEN 256 + +struct flags { + int sigpipe; /* LIBSSH2_FLAG_SIGPIPE */ + int compress; /* LIBSSH2_FLAG_COMPRESS */ +}; + +struct _LIBSSH2_SESSION +{ + /* Memory management callbacks */ + void *abstract; + LIBSSH2_ALLOC_FUNC((*alloc)); + LIBSSH2_REALLOC_FUNC((*realloc)); + LIBSSH2_FREE_FUNC((*free)); + + /* Other callbacks */ + LIBSSH2_IGNORE_FUNC((*ssh_msg_ignore)); + LIBSSH2_DEBUG_FUNC((*ssh_msg_debug)); + LIBSSH2_DISCONNECT_FUNC((*ssh_msg_disconnect)); + LIBSSH2_MACERROR_FUNC((*macerror)); + LIBSSH2_X11_OPEN_FUNC((*x11)); + LIBSSH2_SEND_FUNC((*send)); + LIBSSH2_RECV_FUNC((*recv)); + + /* Method preferences -- NULL yields "load order" */ + char *kex_prefs; + char *hostkey_prefs; + + int state; + + /* Flag options */ + struct flags flag; + + /* Agreed Key Exchange Method */ + const LIBSSH2_KEX_METHOD *kex; + unsigned int burn_optimistic_kexinit:1; + + unsigned char *session_id; + uint32_t session_id_len; + + /* this is set to TRUE if a blocking API behavior is requested */ + int api_block_mode; + + /* Timeout used when blocking API behavior is active */ + long api_timeout; + + /* Server's public key */ + const LIBSSH2_HOSTKEY_METHOD *hostkey; + void *server_hostkey_abstract; + + /* Either set with libssh2_session_hostkey() (for server mode) + * Or read from server in (eg) KEXDH_INIT (for client mode) + */ + unsigned char *server_hostkey; + uint32_t server_hostkey_len; +#if LIBSSH2_MD5 + unsigned char server_hostkey_md5[MD5_DIGEST_LENGTH]; + int server_hostkey_md5_valid; +#endif /* ! LIBSSH2_MD5 */ + unsigned char server_hostkey_sha1[SHA_DIGEST_LENGTH]; + int server_hostkey_sha1_valid; + + /* (remote as source of data -- packet_read ) */ + libssh2_endpoint_data remote; + + /* (local as source of data -- packet_write ) */ + libssh2_endpoint_data local; + + /* Inbound Data linked list -- Sometimes the packet that comes in isn't the + packet we're ready for */ + struct list_head packets; + + /* Active connection channels */ + struct list_head channels; + + uint32_t next_channel; + + struct list_head listeners; /* list of LIBSSH2_LISTENER structs */ + + /* Actual I/O socket */ + libssh2_socket_t socket_fd; + int socket_state; + int socket_block_directions; + int socket_prev_blockstate; /* stores the state of the socket blockiness + when libssh2_session_startup() is called */ + + /* Error tracking */ + const char *err_msg; + int err_code; + int err_flags; + + /* struct members for packet-level reading */ + struct transportpacket packet; +#ifdef LIBSSH2DEBUG + int showmask; /* what debug/trace messages to display */ + libssh2_trace_handler_func tracehandler; /* callback to display trace messages */ + void* tracehandler_context; /* context for the trace handler */ +#endif + + /* State variables used in libssh2_banner_send() */ + libssh2_nonblocking_states banner_TxRx_state; + char banner_TxRx_banner[256]; + ssize_t banner_TxRx_total_send; + + /* State variables used in libssh2_kexinit() */ + libssh2_nonblocking_states kexinit_state; + unsigned char *kexinit_data; + size_t kexinit_data_len; + + /* State variables used in libssh2_session_startup() */ + libssh2_nonblocking_states startup_state; + unsigned char *startup_data; + size_t startup_data_len; + unsigned char startup_service[sizeof("ssh-userauth") + 5 - 1]; + size_t startup_service_length; + packet_require_state_t startup_req_state; + key_exchange_state_t startup_key_state; + + /* State variables used in libssh2_session_free() */ + libssh2_nonblocking_states free_state; + + /* State variables used in libssh2_session_disconnect_ex() */ + libssh2_nonblocking_states disconnect_state; + unsigned char disconnect_data[256 + 13]; + size_t disconnect_data_len; + + /* State variables used in libssh2_packet_read() */ + libssh2_nonblocking_states readPack_state; + int readPack_encrypted; + + /* State variables used in libssh2_userauth_list() */ + libssh2_nonblocking_states userauth_list_state; + unsigned char *userauth_list_data; + size_t userauth_list_data_len; + packet_requirev_state_t userauth_list_packet_requirev_state; + + /* State variables used in libssh2_userauth_password_ex() */ + libssh2_nonblocking_states userauth_pswd_state; + unsigned char *userauth_pswd_data; + unsigned char userauth_pswd_data0; + size_t userauth_pswd_data_len; + char *userauth_pswd_newpw; + int userauth_pswd_newpw_len; + packet_requirev_state_t userauth_pswd_packet_requirev_state; + + /* State variables used in libssh2_userauth_hostbased_fromfile_ex() */ + libssh2_nonblocking_states userauth_host_state; + unsigned char *userauth_host_data; + size_t userauth_host_data_len; + unsigned char *userauth_host_packet; + size_t userauth_host_packet_len; + unsigned char *userauth_host_method; + size_t userauth_host_method_len; + unsigned char *userauth_host_s; + packet_requirev_state_t userauth_host_packet_requirev_state; + + /* State variables used in libssh2_userauth_publickey_fromfile_ex() */ + libssh2_nonblocking_states userauth_pblc_state; + unsigned char *userauth_pblc_data; + size_t userauth_pblc_data_len; + unsigned char *userauth_pblc_packet; + size_t userauth_pblc_packet_len; + unsigned char *userauth_pblc_method; + size_t userauth_pblc_method_len; + unsigned char *userauth_pblc_s; + unsigned char *userauth_pblc_b; + packet_requirev_state_t userauth_pblc_packet_requirev_state; + + /* State variables used in libssh2_userauth_keyboard_interactive_ex() */ + libssh2_nonblocking_states userauth_kybd_state; + unsigned char *userauth_kybd_data; + size_t userauth_kybd_data_len; + unsigned char *userauth_kybd_packet; + size_t userauth_kybd_packet_len; + unsigned int userauth_kybd_auth_name_len; + char *userauth_kybd_auth_name; + unsigned userauth_kybd_auth_instruction_len; + char *userauth_kybd_auth_instruction; + unsigned int userauth_kybd_num_prompts; + int userauth_kybd_auth_failure; + LIBSSH2_USERAUTH_KBDINT_PROMPT *userauth_kybd_prompts; + LIBSSH2_USERAUTH_KBDINT_RESPONSE *userauth_kybd_responses; + packet_requirev_state_t userauth_kybd_packet_requirev_state; + + /* State variables used in libssh2_channel_open_ex() */ + libssh2_nonblocking_states open_state; + packet_requirev_state_t open_packet_requirev_state; + LIBSSH2_CHANNEL *open_channel; + unsigned char *open_packet; + size_t open_packet_len; + unsigned char *open_data; + size_t open_data_len; + uint32_t open_local_channel; + + /* State variables used in libssh2_channel_direct_tcpip_ex() */ + libssh2_nonblocking_states direct_state; + unsigned char *direct_message; + size_t direct_host_len; + size_t direct_shost_len; + size_t direct_message_len; + + /* State variables used in libssh2_channel_forward_listen_ex() */ + libssh2_nonblocking_states fwdLstn_state; + unsigned char *fwdLstn_packet; + uint32_t fwdLstn_host_len; + uint32_t fwdLstn_packet_len; + packet_requirev_state_t fwdLstn_packet_requirev_state; + + /* State variables used in libssh2_publickey_init() */ + libssh2_nonblocking_states pkeyInit_state; + LIBSSH2_PUBLICKEY *pkeyInit_pkey; + LIBSSH2_CHANNEL *pkeyInit_channel; + unsigned char *pkeyInit_data; + size_t pkeyInit_data_len; + /* 19 = packet_len(4) + version_len(4) + "version"(7) + version_num(4) */ + unsigned char pkeyInit_buffer[19]; + size_t pkeyInit_buffer_sent; /* how much of buffer that has been sent */ + + /* State variables used in libssh2_packet_add() */ + libssh2_nonblocking_states packAdd_state; + LIBSSH2_CHANNEL *packAdd_channelp; /* keeper of the channel during EAGAIN + states */ + packet_queue_listener_state_t packAdd_Qlstn_state; + packet_x11_open_state_t packAdd_x11open_state; + + /* State variables used in fullpacket() */ + libssh2_nonblocking_states fullpacket_state; + int fullpacket_macstate; + size_t fullpacket_payload_len; + int fullpacket_packet_type; + + /* State variables used in libssh2_sftp_init() */ + libssh2_nonblocking_states sftpInit_state; + LIBSSH2_SFTP *sftpInit_sftp; + LIBSSH2_CHANNEL *sftpInit_channel; + unsigned char sftpInit_buffer[9]; /* sftp_header(5){excludes request_id} + + version_id(4) */ + int sftpInit_sent; /* number of bytes from the buffer that have been + sent */ + + /* State variables used in libssh2_scp_recv() / libssh_scp_recv2() */ + libssh2_nonblocking_states scpRecv_state; + unsigned char *scpRecv_command; + size_t scpRecv_command_len; + unsigned char scpRecv_response[LIBSSH2_SCP_RESPONSE_BUFLEN]; + size_t scpRecv_response_len; + long scpRecv_mode; +#if defined(HAVE_LONGLONG) && defined(HAVE_STRTOLL) + /* we have the type and we can parse such numbers */ + long long scpRecv_size; +#define scpsize_strtol strtoll +#elif defined(HAVE_STRTOI64) + __int64 scpRecv_size; +#define scpsize_strtol _strtoi64 +#else + long scpRecv_size; +#define scpsize_strtol strtol +#endif + long scpRecv_mtime; + long scpRecv_atime; + LIBSSH2_CHANNEL *scpRecv_channel; + + /* State variables used in libssh2_scp_send_ex() */ + libssh2_nonblocking_states scpSend_state; + unsigned char *scpSend_command; + size_t scpSend_command_len; + unsigned char scpSend_response[LIBSSH2_SCP_RESPONSE_BUFLEN]; + size_t scpSend_response_len; + LIBSSH2_CHANNEL *scpSend_channel; + + /* Keepalive variables used by keepalive.c. */ + int keepalive_interval; + int keepalive_want_reply; + time_t keepalive_last_sent; +}; + +/* session.state bits */ +#define LIBSSH2_STATE_EXCHANGING_KEYS 0x00000001 +#define LIBSSH2_STATE_NEWKEYS 0x00000002 +#define LIBSSH2_STATE_AUTHENTICATED 0x00000004 +#define LIBSSH2_STATE_KEX_ACTIVE 0x00000008 + +/* session.flag helpers */ +#ifdef MSG_NOSIGNAL +#define LIBSSH2_SOCKET_SEND_FLAGS(session) \ + (((session)->flag.sigpipe) ? 0 : MSG_NOSIGNAL) +#define LIBSSH2_SOCKET_RECV_FLAGS(session) \ + (((session)->flag.sigpipe) ? 0 : MSG_NOSIGNAL) +#else +/* If MSG_NOSIGNAL isn't defined we're SOL on blocking SIGPIPE */ +#define LIBSSH2_SOCKET_SEND_FLAGS(session) 0 +#define LIBSSH2_SOCKET_RECV_FLAGS(session) 0 +#endif + +/* --------- */ + +/* libssh2 extensible ssh api, ultimately I'd like to allow loading additional + methods via .so/.dll */ + +struct _LIBSSH2_KEX_METHOD +{ + const char *name; + + /* Key exchange, populates session->* and returns 0 on success, non-0 on error */ + int (*exchange_keys) (LIBSSH2_SESSION * session, + key_exchange_state_low_t * key_state); + + long flags; +}; + +struct _LIBSSH2_HOSTKEY_METHOD +{ + const char *name; + unsigned long hash_len; + + int (*init) (LIBSSH2_SESSION * session, const unsigned char *hostkey_data, + size_t hostkey_data_len, void **abstract); + int (*initPEM) (LIBSSH2_SESSION * session, const char *privkeyfile, + unsigned const char *passphrase, void **abstract); + int (*initPEMFromMemory) (LIBSSH2_SESSION * session, + const char *privkeyfiledata, size_t privkeyfiledata_len, + unsigned const char *passphrase, void **abstract); + int (*sig_verify) (LIBSSH2_SESSION * session, const unsigned char *sig, + size_t sig_len, const unsigned char *m, + size_t m_len, void **abstract); + int (*signv) (LIBSSH2_SESSION * session, unsigned char **signature, + size_t *signature_len, int veccount, + const struct iovec datavec[], void **abstract); + int (*encrypt) (LIBSSH2_SESSION * session, unsigned char **dst, + size_t *dst_len, const unsigned char *src, + size_t src_len, void **abstract); + int (*dtor) (LIBSSH2_SESSION * session, void **abstract); +}; + +struct _LIBSSH2_CRYPT_METHOD +{ + const char *name; + + int blocksize; + + /* iv and key sizes (-1 for variable length) */ + int iv_len; + int secret_len; + + long flags; + + int (*init) (LIBSSH2_SESSION * session, + const LIBSSH2_CRYPT_METHOD * method, unsigned char *iv, + int *free_iv, unsigned char *secret, int *free_secret, + int encrypt, void **abstract); + int (*crypt) (LIBSSH2_SESSION * session, unsigned char *block, + size_t blocksize, void **abstract); + int (*dtor) (LIBSSH2_SESSION * session, void **abstract); + + _libssh2_cipher_type(algo); +}; + +struct _LIBSSH2_COMP_METHOD +{ + const char *name; + int compress; /* 1 if it does compress, 0 if it doesn't */ + int use_in_auth; /* 1 if compression should be used in userauth */ + int (*init) (LIBSSH2_SESSION *session, int compress, void **abstract); + int (*comp) (LIBSSH2_SESSION *session, + unsigned char *dest, + size_t *dest_len, + const unsigned char *src, + size_t src_len, + void **abstract); + int (*decomp) (LIBSSH2_SESSION *session, + unsigned char **dest, + size_t *dest_len, + size_t payload_limit, + const unsigned char *src, + size_t src_len, + void **abstract); + int (*dtor) (LIBSSH2_SESSION * session, int compress, void **abstract); +}; + +#ifdef LIBSSH2DEBUG +void _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, + ...); +#else +#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || defined(__GNUC__) +/* C99 supported and also by older GCC */ +#define _libssh2_debug(x,y,z,...) do {} while (0) +#else +/* no gcc and not C99, do static and hopefully inline */ +static inline void +_libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...) +{ + (void)session; + (void)context; + (void)format; +} +#endif +#endif + +#define LIBSSH2_SOCKET_UNKNOWN 1 +#define LIBSSH2_SOCKET_CONNECTED 0 +#define LIBSSH2_SOCKET_DISCONNECTED -1 + +/* Initial packet state, prior to MAC check */ +#define LIBSSH2_MAC_UNCONFIRMED 1 +/* When MAC type is "none" (proto initiation phase) all packets are deemed "confirmed" */ +#define LIBSSH2_MAC_CONFIRMED 0 +/* Something very bad is going on */ +#define LIBSSH2_MAC_INVALID -1 + +/* Flags for _libssh2_error_flags */ +/* Error message is allocated on the heap */ +#define LIBSSH2_ERR_FLAG_DUP 1 + +/* SSH Packet Types -- Defined by internet draft */ +/* Transport Layer */ +#define SSH_MSG_DISCONNECT 1 +#define SSH_MSG_IGNORE 2 +#define SSH_MSG_UNIMPLEMENTED 3 +#define SSH_MSG_DEBUG 4 +#define SSH_MSG_SERVICE_REQUEST 5 +#define SSH_MSG_SERVICE_ACCEPT 6 + +#define SSH_MSG_KEXINIT 20 +#define SSH_MSG_NEWKEYS 21 + +/* diffie-hellman-group1-sha1 */ +#define SSH_MSG_KEXDH_INIT 30 +#define SSH_MSG_KEXDH_REPLY 31 + +/* diffie-hellman-group-exchange-sha1 and diffie-hellman-group-exchange-sha256 */ +#define SSH_MSG_KEX_DH_GEX_REQUEST_OLD 30 +#define SSH_MSG_KEX_DH_GEX_REQUEST 34 +#define SSH_MSG_KEX_DH_GEX_GROUP 31 +#define SSH_MSG_KEX_DH_GEX_INIT 32 +#define SSH_MSG_KEX_DH_GEX_REPLY 33 + +/* User Authentication */ +#define SSH_MSG_USERAUTH_REQUEST 50 +#define SSH_MSG_USERAUTH_FAILURE 51 +#define SSH_MSG_USERAUTH_SUCCESS 52 +#define SSH_MSG_USERAUTH_BANNER 53 + +/* "public key" method */ +#define SSH_MSG_USERAUTH_PK_OK 60 +/* "password" method */ +#define SSH_MSG_USERAUTH_PASSWD_CHANGEREQ 60 +/* "keyboard-interactive" method */ +#define SSH_MSG_USERAUTH_INFO_REQUEST 60 +#define SSH_MSG_USERAUTH_INFO_RESPONSE 61 + +/* Channels */ +#define SSH_MSG_GLOBAL_REQUEST 80 +#define SSH_MSG_REQUEST_SUCCESS 81 +#define SSH_MSG_REQUEST_FAILURE 82 + +#define SSH_MSG_CHANNEL_OPEN 90 +#define SSH_MSG_CHANNEL_OPEN_CONFIRMATION 91 +#define SSH_MSG_CHANNEL_OPEN_FAILURE 92 +#define SSH_MSG_CHANNEL_WINDOW_ADJUST 93 +#define SSH_MSG_CHANNEL_DATA 94 +#define SSH_MSG_CHANNEL_EXTENDED_DATA 95 +#define SSH_MSG_CHANNEL_EOF 96 +#define SSH_MSG_CHANNEL_CLOSE 97 +#define SSH_MSG_CHANNEL_REQUEST 98 +#define SSH_MSG_CHANNEL_SUCCESS 99 +#define SSH_MSG_CHANNEL_FAILURE 100 + +/* Error codes returned in SSH_MSG_CHANNEL_OPEN_FAILURE message + (see RFC4254) */ +#define SSH_OPEN_ADMINISTRATIVELY_PROHIBITED 1 +#define SSH_OPEN_CONNECT_FAILED 2 +#define SSH_OPEN_UNKNOWN_CHANNELTYPE 3 +#define SSH_OPEN_RESOURCE_SHORTAGE 4 + +ssize_t _libssh2_recv(libssh2_socket_t socket, void *buffer, + size_t length, int flags, void **abstract); +ssize_t _libssh2_send(libssh2_socket_t socket, const void *buffer, + size_t length, int flags, void **abstract); + +#define LIBSSH2_READ_TIMEOUT 60 /* generic timeout in seconds used when + waiting for more data to arrive */ + + +int _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange, + key_exchange_state_t * state); + +/* Let crypt.c/hostkey.c expose their method structs */ +const LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void); +const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void); + +/* pem.c */ +int _libssh2_pem_parse(LIBSSH2_SESSION * session, + const char *headerbegin, + const char *headerend, + FILE * fp, unsigned char **data, unsigned int *datalen); +int _libssh2_pem_parse_memory(LIBSSH2_SESSION * session, + const char *headerbegin, + const char *headerend, + const char *filedata, size_t filedata_len, + unsigned char **data, unsigned int *datalen); +int _libssh2_pem_decode_sequence(unsigned char **data, unsigned int *datalen); +int _libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen, + unsigned char **i, unsigned int *ilen); + +/* global.c */ +void _libssh2_init_if_needed (void); + + +#define ARRAY_SIZE(a) (sizeof ((a)) / sizeof ((a)[0])) + +/* define to output the libssh2_int64_t type in a *printf() */ +#if defined( __BORLANDC__ ) || defined( _MSC_VER ) || defined( __MINGW32__ ) +#define LIBSSH2_INT64_T_FORMAT "I64d" +#else +#define LIBSSH2_INT64_T_FORMAT "lld" +#endif + +#endif /* LIBSSH2_H */ diff --git a/include/libssh2/libssh2_publickey.h b/include/libssh2/libssh2_publickey.h new file mode 100644 index 0000000..7350e9f --- /dev/null +++ b/include/libssh2/libssh2_publickey.h @@ -0,0 +1,118 @@ +/* Copyright (c) 2004-2006, Sara Golemon + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +/* Note: This include file is only needed for using the + * publickey SUBSYSTEM which is not the same as publickey + * authentication. For authentication you only need libssh2.h + * + * For more information on the publickey subsystem, + * refer to IETF draft: secsh-publickey + */ + +#ifndef LIBSSH2_PUBLICKEY_H +#define LIBSSH2_PUBLICKEY_H 1 + +#include "libssh2.h" + +typedef struct _LIBSSH2_PUBLICKEY LIBSSH2_PUBLICKEY; + +typedef struct _libssh2_publickey_attribute { + const char *name; + unsigned long name_len; + const char *value; + unsigned long value_len; + char mandatory; +} libssh2_publickey_attribute; + +typedef struct _libssh2_publickey_list { + unsigned char *packet; /* For freeing */ + + const unsigned char *name; + unsigned long name_len; + const unsigned char *blob; + unsigned long blob_len; + unsigned long num_attrs; + libssh2_publickey_attribute *attrs; /* free me */ +} libssh2_publickey_list; + +/* Generally use the first macro here, but if both name and value are string literals, you can use _fast() to take advantage of preprocessing */ +#define libssh2_publickey_attribute(name, value, mandatory) \ + { (name), strlen(name), (value), strlen(value), (mandatory) }, +#define libssh2_publickey_attribute_fast(name, value, mandatory) \ + { (name), sizeof(name) - 1, (value), sizeof(value) - 1, (mandatory) }, + +#ifdef __cplusplus +extern "C" { +#endif + +/* Publickey Subsystem */ +LIBSSH2_API LIBSSH2_PUBLICKEY *libssh2_publickey_init(LIBSSH2_SESSION *session); + +LIBSSH2_API int libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, + const unsigned char *name, + unsigned long name_len, + const unsigned char *blob, + unsigned long blob_len, char overwrite, + unsigned long num_attrs, + const libssh2_publickey_attribute attrs[]); +#define libssh2_publickey_add(pkey, name, blob, blob_len, overwrite, \ + num_attrs, attrs) \ + libssh2_publickey_add_ex((pkey), (name), strlen(name), (blob), (blob_len), \ + (overwrite), (num_attrs), (attrs)) + +LIBSSH2_API int libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY *pkey, + const unsigned char *name, + unsigned long name_len, + const unsigned char *blob, + unsigned long blob_len); +#define libssh2_publickey_remove(pkey, name, blob, blob_len) \ + libssh2_publickey_remove_ex((pkey), (name), strlen(name), (blob), (blob_len)) + +LIBSSH2_API int +libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, + unsigned long *num_keys, + libssh2_publickey_list **pkey_list); +LIBSSH2_API void libssh2_publickey_list_free(LIBSSH2_PUBLICKEY *pkey, + libssh2_publickey_list *pkey_list); + +LIBSSH2_API int libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* ifndef: LIBSSH2_PUBLICKEY_H */ diff --git a/include/libssh2/libssh2_sftp.h b/include/libssh2/libssh2_sftp.h new file mode 100644 index 0000000..677faf2 --- /dev/null +++ b/include/libssh2/libssh2_sftp.h @@ -0,0 +1,346 @@ +/* Copyright (c) 2004-2008, Sara Golemon + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#ifndef LIBSSH2_SFTP_H +#define LIBSSH2_SFTP_H 1 + +#include "libssh2.h" + +#ifndef WIN32 +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Note: Version 6 was documented at the time of writing + * However it was marked as "DO NOT IMPLEMENT" due to pending changes + * + * Let's start with Version 3 (The version found in OpenSSH) and go from there + */ +#define LIBSSH2_SFTP_VERSION 3 + +typedef struct _LIBSSH2_SFTP LIBSSH2_SFTP; +typedef struct _LIBSSH2_SFTP_HANDLE LIBSSH2_SFTP_HANDLE; +typedef struct _LIBSSH2_SFTP_ATTRIBUTES LIBSSH2_SFTP_ATTRIBUTES; +typedef struct _LIBSSH2_SFTP_STATVFS LIBSSH2_SFTP_STATVFS; + +/* Flags for open_ex() */ +#define LIBSSH2_SFTP_OPENFILE 0 +#define LIBSSH2_SFTP_OPENDIR 1 + +/* Flags for rename_ex() */ +#define LIBSSH2_SFTP_RENAME_OVERWRITE 0x00000001 +#define LIBSSH2_SFTP_RENAME_ATOMIC 0x00000002 +#define LIBSSH2_SFTP_RENAME_NATIVE 0x00000004 + +/* Flags for stat_ex() */ +#define LIBSSH2_SFTP_STAT 0 +#define LIBSSH2_SFTP_LSTAT 1 +#define LIBSSH2_SFTP_SETSTAT 2 + +/* Flags for symlink_ex() */ +#define LIBSSH2_SFTP_SYMLINK 0 +#define LIBSSH2_SFTP_READLINK 1 +#define LIBSSH2_SFTP_REALPATH 2 + +/* SFTP attribute flag bits */ +#define LIBSSH2_SFTP_ATTR_SIZE 0x00000001 +#define LIBSSH2_SFTP_ATTR_UIDGID 0x00000002 +#define LIBSSH2_SFTP_ATTR_PERMISSIONS 0x00000004 +#define LIBSSH2_SFTP_ATTR_ACMODTIME 0x00000008 +#define LIBSSH2_SFTP_ATTR_EXTENDED 0x80000000 + +/* SFTP statvfs flag bits */ +#define LIBSSH2_SFTP_ST_RDONLY 0x00000001 +#define LIBSSH2_SFTP_ST_NOSUID 0x00000002 + +struct _LIBSSH2_SFTP_ATTRIBUTES { + /* If flags & ATTR_* bit is set, then the value in this struct will be + * meaningful Otherwise it should be ignored + */ + unsigned long flags; + + libssh2_uint64_t filesize; + unsigned long uid, gid; + unsigned long permissions; + unsigned long atime, mtime; +}; + +struct _LIBSSH2_SFTP_STATVFS { + libssh2_uint64_t f_bsize; /* file system block size */ + libssh2_uint64_t f_frsize; /* fragment size */ + libssh2_uint64_t f_blocks; /* size of fs in f_frsize units */ + libssh2_uint64_t f_bfree; /* # free blocks */ + libssh2_uint64_t f_bavail; /* # free blocks for non-root */ + libssh2_uint64_t f_files; /* # inodes */ + libssh2_uint64_t f_ffree; /* # free inodes */ + libssh2_uint64_t f_favail; /* # free inodes for non-root */ + libssh2_uint64_t f_fsid; /* file system ID */ + libssh2_uint64_t f_flag; /* mount flags */ + libssh2_uint64_t f_namemax; /* maximum filename length */ +}; + +/* SFTP filetypes */ +#define LIBSSH2_SFTP_TYPE_REGULAR 1 +#define LIBSSH2_SFTP_TYPE_DIRECTORY 2 +#define LIBSSH2_SFTP_TYPE_SYMLINK 3 +#define LIBSSH2_SFTP_TYPE_SPECIAL 4 +#define LIBSSH2_SFTP_TYPE_UNKNOWN 5 +#define LIBSSH2_SFTP_TYPE_SOCKET 6 +#define LIBSSH2_SFTP_TYPE_CHAR_DEVICE 7 +#define LIBSSH2_SFTP_TYPE_BLOCK_DEVICE 8 +#define LIBSSH2_SFTP_TYPE_FIFO 9 + +/* + * Reproduce the POSIX file modes here for systems that are not POSIX + * compliant. + * + * These is used in "permissions" of "struct _LIBSSH2_SFTP_ATTRIBUTES" + */ +/* File type */ +#define LIBSSH2_SFTP_S_IFMT 0170000 /* type of file mask */ +#define LIBSSH2_SFTP_S_IFIFO 0010000 /* named pipe (fifo) */ +#define LIBSSH2_SFTP_S_IFCHR 0020000 /* character special */ +#define LIBSSH2_SFTP_S_IFDIR 0040000 /* directory */ +#define LIBSSH2_SFTP_S_IFBLK 0060000 /* block special */ +#define LIBSSH2_SFTP_S_IFREG 0100000 /* regular */ +#define LIBSSH2_SFTP_S_IFLNK 0120000 /* symbolic link */ +#define LIBSSH2_SFTP_S_IFSOCK 0140000 /* socket */ + +/* File mode */ +/* Read, write, execute/search by owner */ +#define LIBSSH2_SFTP_S_IRWXU 0000700 /* RWX mask for owner */ +#define LIBSSH2_SFTP_S_IRUSR 0000400 /* R for owner */ +#define LIBSSH2_SFTP_S_IWUSR 0000200 /* W for owner */ +#define LIBSSH2_SFTP_S_IXUSR 0000100 /* X for owner */ +/* Read, write, execute/search by group */ +#define LIBSSH2_SFTP_S_IRWXG 0000070 /* RWX mask for group */ +#define LIBSSH2_SFTP_S_IRGRP 0000040 /* R for group */ +#define LIBSSH2_SFTP_S_IWGRP 0000020 /* W for group */ +#define LIBSSH2_SFTP_S_IXGRP 0000010 /* X for group */ +/* Read, write, execute/search by others */ +#define LIBSSH2_SFTP_S_IRWXO 0000007 /* RWX mask for other */ +#define LIBSSH2_SFTP_S_IROTH 0000004 /* R for other */ +#define LIBSSH2_SFTP_S_IWOTH 0000002 /* W for other */ +#define LIBSSH2_SFTP_S_IXOTH 0000001 /* X for other */ + +/* macros to check for specific file types, added in 1.2.5 */ +#define LIBSSH2_SFTP_S_ISLNK(m) \ + (((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFLNK) +#define LIBSSH2_SFTP_S_ISREG(m) \ + (((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFREG) +#define LIBSSH2_SFTP_S_ISDIR(m) \ + (((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFDIR) +#define LIBSSH2_SFTP_S_ISCHR(m) \ + (((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFCHR) +#define LIBSSH2_SFTP_S_ISBLK(m) \ + (((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFBLK) +#define LIBSSH2_SFTP_S_ISFIFO(m) \ + (((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFIFO) +#define LIBSSH2_SFTP_S_ISSOCK(m) \ + (((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFSOCK) + +/* SFTP File Transfer Flags -- (e.g. flags parameter to sftp_open()) + * Danger will robinson... APPEND doesn't have any effect on OpenSSH servers */ +#define LIBSSH2_FXF_READ 0x00000001 +#define LIBSSH2_FXF_WRITE 0x00000002 +#define LIBSSH2_FXF_APPEND 0x00000004 +#define LIBSSH2_FXF_CREAT 0x00000008 +#define LIBSSH2_FXF_TRUNC 0x00000010 +#define LIBSSH2_FXF_EXCL 0x00000020 + +/* SFTP Status Codes (returned by libssh2_sftp_last_error() ) */ +#define LIBSSH2_FX_OK 0 +#define LIBSSH2_FX_EOF 1 +#define LIBSSH2_FX_NO_SUCH_FILE 2 +#define LIBSSH2_FX_PERMISSION_DENIED 3 +#define LIBSSH2_FX_FAILURE 4 +#define LIBSSH2_FX_BAD_MESSAGE 5 +#define LIBSSH2_FX_NO_CONNECTION 6 +#define LIBSSH2_FX_CONNECTION_LOST 7 +#define LIBSSH2_FX_OP_UNSUPPORTED 8 +#define LIBSSH2_FX_INVALID_HANDLE 9 +#define LIBSSH2_FX_NO_SUCH_PATH 10 +#define LIBSSH2_FX_FILE_ALREADY_EXISTS 11 +#define LIBSSH2_FX_WRITE_PROTECT 12 +#define LIBSSH2_FX_NO_MEDIA 13 +#define LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM 14 +#define LIBSSH2_FX_QUOTA_EXCEEDED 15 +#define LIBSSH2_FX_UNKNOWN_PRINCIPLE 16 /* Initial mis-spelling */ +#define LIBSSH2_FX_UNKNOWN_PRINCIPAL 16 +#define LIBSSH2_FX_LOCK_CONFlICT 17 /* Initial mis-spelling */ +#define LIBSSH2_FX_LOCK_CONFLICT 17 +#define LIBSSH2_FX_DIR_NOT_EMPTY 18 +#define LIBSSH2_FX_NOT_A_DIRECTORY 19 +#define LIBSSH2_FX_INVALID_FILENAME 20 +#define LIBSSH2_FX_LINK_LOOP 21 + +/* Returned by any function that would block during a read/write opperation */ +#define LIBSSH2SFTP_EAGAIN LIBSSH2_ERROR_EAGAIN + +/* SFTP API */ +LIBSSH2_API LIBSSH2_SFTP *libssh2_sftp_init(LIBSSH2_SESSION *session); +LIBSSH2_API int libssh2_sftp_shutdown(LIBSSH2_SFTP *sftp); +LIBSSH2_API unsigned long libssh2_sftp_last_error(LIBSSH2_SFTP *sftp); +LIBSSH2_API LIBSSH2_CHANNEL *libssh2_sftp_get_channel(LIBSSH2_SFTP *sftp); + +/* File / Directory Ops */ +LIBSSH2_API LIBSSH2_SFTP_HANDLE *libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp, + const char *filename, + unsigned int filename_len, + unsigned long flags, + long mode, int open_type); +#define libssh2_sftp_open(sftp, filename, flags, mode) \ + libssh2_sftp_open_ex((sftp), (filename), strlen(filename), (flags), \ + (mode), LIBSSH2_SFTP_OPENFILE) +#define libssh2_sftp_opendir(sftp, path) \ + libssh2_sftp_open_ex((sftp), (path), strlen(path), 0, 0, \ + LIBSSH2_SFTP_OPENDIR) + +LIBSSH2_API ssize_t libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *handle, + char *buffer, size_t buffer_maxlen); + +LIBSSH2_API int libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *handle, \ + char *buffer, size_t buffer_maxlen, + char *longentry, + size_t longentry_maxlen, + LIBSSH2_SFTP_ATTRIBUTES *attrs); +#define libssh2_sftp_readdir(handle, buffer, buffer_maxlen, attrs) \ + libssh2_sftp_readdir_ex((handle), (buffer), (buffer_maxlen), NULL, 0, \ + (attrs)) + +LIBSSH2_API ssize_t libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle, + const char *buffer, size_t count); +LIBSSH2_API int libssh2_sftp_fsync(LIBSSH2_SFTP_HANDLE *handle); + +LIBSSH2_API int libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle); +#define libssh2_sftp_close(handle) libssh2_sftp_close_handle(handle) +#define libssh2_sftp_closedir(handle) libssh2_sftp_close_handle(handle) + +LIBSSH2_API void libssh2_sftp_seek(LIBSSH2_SFTP_HANDLE *handle, size_t offset); +LIBSSH2_API void libssh2_sftp_seek64(LIBSSH2_SFTP_HANDLE *handle, + libssh2_uint64_t offset); +#define libssh2_sftp_rewind(handle) libssh2_sftp_seek64((handle), 0) + +LIBSSH2_API size_t libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE *handle); +LIBSSH2_API libssh2_uint64_t libssh2_sftp_tell64(LIBSSH2_SFTP_HANDLE *handle); + +LIBSSH2_API int libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *handle, + LIBSSH2_SFTP_ATTRIBUTES *attrs, + int setstat); +#define libssh2_sftp_fstat(handle, attrs) \ + libssh2_sftp_fstat_ex((handle), (attrs), 0) +#define libssh2_sftp_fsetstat(handle, attrs) \ + libssh2_sftp_fstat_ex((handle), (attrs), 1) + +/* Miscellaneous Ops */ +LIBSSH2_API int libssh2_sftp_rename_ex(LIBSSH2_SFTP *sftp, + const char *source_filename, + unsigned int srouce_filename_len, + const char *dest_filename, + unsigned int dest_filename_len, + long flags); +#define libssh2_sftp_rename(sftp, sourcefile, destfile) \ + libssh2_sftp_rename_ex((sftp), (sourcefile), strlen(sourcefile), \ + (destfile), strlen(destfile), \ + LIBSSH2_SFTP_RENAME_OVERWRITE | \ + LIBSSH2_SFTP_RENAME_ATOMIC | \ + LIBSSH2_SFTP_RENAME_NATIVE) + +LIBSSH2_API int libssh2_sftp_unlink_ex(LIBSSH2_SFTP *sftp, + const char *filename, + unsigned int filename_len); +#define libssh2_sftp_unlink(sftp, filename) \ + libssh2_sftp_unlink_ex((sftp), (filename), strlen(filename)) + +LIBSSH2_API int libssh2_sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle, + LIBSSH2_SFTP_STATVFS *st); + +LIBSSH2_API int libssh2_sftp_statvfs(LIBSSH2_SFTP *sftp, + const char *path, + size_t path_len, + LIBSSH2_SFTP_STATVFS *st); + +LIBSSH2_API int libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, + const char *path, + unsigned int path_len, long mode); +#define libssh2_sftp_mkdir(sftp, path, mode) \ + libssh2_sftp_mkdir_ex((sftp), (path), strlen(path), (mode)) + +LIBSSH2_API int libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp, + const char *path, + unsigned int path_len); +#define libssh2_sftp_rmdir(sftp, path) \ + libssh2_sftp_rmdir_ex((sftp), (path), strlen(path)) + +LIBSSH2_API int libssh2_sftp_stat_ex(LIBSSH2_SFTP *sftp, + const char *path, + unsigned int path_len, + int stat_type, + LIBSSH2_SFTP_ATTRIBUTES *attrs); +#define libssh2_sftp_stat(sftp, path, attrs) \ + libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_STAT, \ + (attrs)) +#define libssh2_sftp_lstat(sftp, path, attrs) \ + libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_LSTAT, \ + (attrs)) +#define libssh2_sftp_setstat(sftp, path, attrs) \ + libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_SETSTAT, \ + (attrs)) + +LIBSSH2_API int libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp, + const char *path, + unsigned int path_len, + char *target, + unsigned int target_len, int link_type); +#define libssh2_sftp_symlink(sftp, orig, linkpath) \ + libssh2_sftp_symlink_ex((sftp), (orig), strlen(orig), (linkpath), \ + strlen(linkpath), LIBSSH2_SFTP_SYMLINK) +#define libssh2_sftp_readlink(sftp, path, target, maxlen) \ + libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), \ + LIBSSH2_SFTP_READLINK) +#define libssh2_sftp_realpath(sftp, path, target, maxlen) \ + libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), \ + LIBSSH2_SFTP_REALPATH) + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LIBSSH2_SFTP_H */ diff --git a/include/libssh2/mac.h b/include/libssh2/mac.h new file mode 100644 index 0000000..66d3e61 --- /dev/null +++ b/include/libssh2/mac.h @@ -0,0 +1,67 @@ +#ifndef __LIBSSH2_MAC_H +#define __LIBSSH2_MAC_H + +/* Copyright (C) 2009-2010 by Daniel Stenberg + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + */ + +#include "libssh2_priv.h" + +struct _LIBSSH2_MAC_METHOD +{ + const char *name; + + /* The length of a given MAC packet */ + int mac_len; + + /* integrity key length */ + int key_len; + + /* Message Authentication Code Hashing algo */ + int (*init) (LIBSSH2_SESSION * session, unsigned char *key, int *free_key, + void **abstract); + int (*hash) (LIBSSH2_SESSION * session, unsigned char *buf, + uint32_t seqno, const unsigned char *packet, + uint32_t packet_len, const unsigned char *addtl, + uint32_t addtl_len, void **abstract); + int (*dtor) (LIBSSH2_SESSION * session, void **abstract); +}; + +typedef struct _LIBSSH2_MAC_METHOD LIBSSH2_MAC_METHOD; + +const LIBSSH2_MAC_METHOD **_libssh2_mac_methods(void); + +#endif /* __LIBSSH2_MAC_H */ diff --git a/include/libssh2/misc.h b/include/libssh2/misc.h new file mode 100644 index 0000000..54ae546 --- /dev/null +++ b/include/libssh2/misc.h @@ -0,0 +1,96 @@ +#ifndef __LIBSSH2_MISC_H +#define __LIBSSH2_MISC_H +/* Copyright (c) 2009-2014 by Daniel Stenberg + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +struct list_head { + struct list_node *last; + struct list_node *first; +}; + +struct list_node { + struct list_node *next; + struct list_node *prev; + struct list_head *head; +}; + +int _libssh2_error_flags(LIBSSH2_SESSION* session, int errcode, const char* errmsg, int errflags); +int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char* errmsg); + +void _libssh2_list_init(struct list_head *head); + +/* add a node last in the list */ +void _libssh2_list_add(struct list_head *head, + struct list_node *entry); + +/* return the "first" node in the list this head points to */ +void *_libssh2_list_first(struct list_head *head); + +/* return the next node in the list */ +void *_libssh2_list_next(struct list_node *node); + +/* return the prev node in the list */ +void *_libssh2_list_prev(struct list_node *node); + +/* remove this node from the list */ +void _libssh2_list_remove(struct list_node *entry); + +size_t _libssh2_base64_encode(struct _LIBSSH2_SESSION *session, + const char *inp, size_t insize, char **outptr); + +unsigned int _libssh2_ntohu32(const unsigned char *buf); +libssh2_uint64_t _libssh2_ntohu64(const unsigned char *buf); +void _libssh2_htonu32(unsigned char *buf, uint32_t val); +void _libssh2_store_u32(unsigned char **buf, uint32_t value); +void _libssh2_store_str(unsigned char **buf, const char *str, size_t len); +void *_libssh2_calloc(LIBSSH2_SESSION* session, size_t size); + +#if defined(LIBSSH2_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) +/* provide a private one */ +#undef HAVE_GETTIMEOFDAY +int __cdecl _libssh2_gettimeofday(struct timeval *tp, void *tzp); +#define HAVE_LIBSSH2_GETTIMEOFDAY +#define LIBSSH2_GETTIMEOFDAY_WIN32 /* enable the win32 implementation */ +#else +#ifdef HAVE_GETTIMEOFDAY +#define _libssh2_gettimeofday(x,y) gettimeofday(x,y) +#define HAVE_LIBSSH2_GETTIMEOFDAY +#endif +#endif + +#endif /* _LIBSSH2_MISC_H */ diff --git a/include/libssh2/module.mk b/include/libssh2/module.mk new file mode 100644 index 0000000..e882048 --- /dev/null +++ b/include/libssh2/module.mk @@ -0,0 +1,35 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/ Makefile fragment +# +####################################################################### + +if BUILD_SSH_TUNNEL + +pgadmin3_SOURCES += \ + include/libssh2/channel.h \ + include/libssh2/comp.h \ + include/libssh2/crypto.h \ + include/libssh2/libgcrypt.h \ + include/libssh2/libssh2.h \ + include/libssh2/libssh2_priv.h \ + include/libssh2/libssh2_publickey.h \ + include/libssh2/libssh2_sftp.h \ + include/libssh2/mac.h \ + include/libssh2/misc.h \ + include/libssh2/openssl.h \ + include/libssh2/packet.h \ + include/libssh2/session.h \ + include/libssh2/sftp.h \ + include/libssh2/transport.h \ + include/libssh2/userauth.h + +EXTRA_DIST += \ + include/libssh2/module.mk \ + include/libssh2/Win32/libssh2_config.h +endif diff --git a/include/libssh2/openssl.h b/include/libssh2/openssl.h new file mode 100644 index 0000000..82d09f6 --- /dev/null +++ b/include/libssh2/openssl.h @@ -0,0 +1,222 @@ +/* Copyright (C) 2009, 2010 Simon Josefsson + * Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved. + * + * Author: Simon Josefsson + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#ifndef OPENSSL_NO_DSA +#include +#endif +#ifndef OPENSSL_NO_MD5 +#include +#endif +#include +#include +#include +#include +#include + +#ifdef OPENSSL_NO_RSA +# define LIBSSH2_RSA 0 +#else +# define LIBSSH2_RSA 1 +#endif + +#ifdef OPENSSL_NO_DSA +# define LIBSSH2_DSA 0 +#else +# define LIBSSH2_DSA 1 +#endif + +#ifdef OPENSSL_NO_MD5 +# define LIBSSH2_MD5 0 +#else +# define LIBSSH2_MD5 1 +#endif + +#ifdef OPENSSL_NO_RIPEMD +# define LIBSSH2_HMAC_RIPEMD 0 +#else +# define LIBSSH2_HMAC_RIPEMD 1 +#endif + +#define LIBSSH2_HMAC_SHA256 1 +#define LIBSSH2_HMAC_SHA512 1 + +#if OPENSSL_VERSION_NUMBER >= 0x00907000L && !defined(OPENSSL_NO_AES) +# define LIBSSH2_AES_CTR 1 +# define LIBSSH2_AES 1 +#else +# define LIBSSH2_AES_CTR 0 +# define LIBSSH2_AES 0 +#endif + +#ifdef OPENSSL_NO_BF +# define LIBSSH2_BLOWFISH 0 +#else +# define LIBSSH2_BLOWFISH 1 +#endif + +#ifdef OPENSSL_NO_RC4 +# define LIBSSH2_RC4 0 +#else +# define LIBSSH2_RC4 1 +#endif + +#ifdef OPENSSL_NO_CAST +# define LIBSSH2_CAST 0 +#else +# define LIBSSH2_CAST 1 +#endif + +#ifdef OPENSSL_NO_DES +# define LIBSSH2_3DES 0 +#else +# define LIBSSH2_3DES 1 +#endif + +#define _libssh2_random(buf, len) RAND_bytes ((buf), (len)) + +#define libssh2_sha1_ctx EVP_MD_CTX + +/* returns 0 in case of failure */ +int _libssh2_sha1_init(libssh2_sha1_ctx *ctx); +#define libssh2_sha1_init(x) _libssh2_sha1_init(x) +#define libssh2_sha1_update(ctx, data, len) EVP_DigestUpdate(&(ctx), data, len) +#define libssh2_sha1_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL) +int _libssh2_sha1(const unsigned char *message, unsigned long len, + unsigned char *out); +#define libssh2_sha1(x,y,z) _libssh2_sha1(x,y,z) + +#define libssh2_sha256_ctx EVP_MD_CTX + +/* returns 0 in case of failure */ +int _libssh2_sha256_init(libssh2_sha256_ctx *ctx); +#define libssh2_sha256_init(x) _libssh2_sha256_init(x) +#define libssh2_sha256_update(ctx, data, len) EVP_DigestUpdate(&(ctx), data, len) +#define libssh2_sha256_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL) +int _libssh2_sha256(const unsigned char *message, unsigned long len, + unsigned char *out); +#define libssh2_sha256(x,y,z) _libssh2_sha256(x,y,z) + +#define libssh2_md5_ctx EVP_MD_CTX + +/* returns 0 in case of failure */ +int _libssh2_md5_init(libssh2_md5_ctx *); +#define libssh2_md5_init(x) _libssh2_md5_init(x) +#define libssh2_md5_update(ctx, data, len) EVP_DigestUpdate(&(ctx), data, len) +#define libssh2_md5_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL) + +#define libssh2_hmac_ctx HMAC_CTX +#define libssh2_hmac_ctx_init(ctx) \ + HMAC_CTX_init(&ctx) +#define libssh2_hmac_sha1_init(ctx, key, keylen) \ + HMAC_Init_ex(ctx, key, keylen, EVP_sha1(), NULL) +#define libssh2_hmac_md5_init(ctx, key, keylen) \ + HMAC_Init_ex(ctx, key, keylen, EVP_md5(), NULL) +#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \ + HMAC_Init_ex(ctx, key, keylen, EVP_ripemd160(), NULL) +#define libssh2_hmac_sha256_init(ctx, key, keylen) \ + HMAC_Init_ex(ctx, key, keylen, EVP_sha256(), NULL) +#define libssh2_hmac_sha512_init(ctx, key, keylen) \ + HMAC_Init_ex(ctx, key, keylen, EVP_sha512(), NULL) + +#define libssh2_hmac_update(ctx, data, datalen) \ + HMAC_Update(&(ctx), data, datalen) +#define libssh2_hmac_final(ctx, data) HMAC_Final(&(ctx), data, NULL) +#define libssh2_hmac_cleanup(ctx) HMAC_cleanup(ctx) + +#define libssh2_crypto_init() \ + OpenSSL_add_all_algorithms(); \ + ENGINE_load_builtin_engines(); \ + ENGINE_register_all_complete() + +#define libssh2_crypto_exit() + +#define libssh2_rsa_ctx RSA + +#define _libssh2_rsa_free(rsactx) RSA_free(rsactx) + +#define libssh2_dsa_ctx DSA + + +#define _libssh2_dsa_free(dsactx) DSA_free(dsactx) + +#define _libssh2_cipher_type(name) const EVP_CIPHER *(*name)(void) +#define _libssh2_cipher_ctx EVP_CIPHER_CTX + +#define _libssh2_cipher_aes256 EVP_aes_256_cbc +#define _libssh2_cipher_aes192 EVP_aes_192_cbc +#define _libssh2_cipher_aes128 EVP_aes_128_cbc +#ifdef HAVE_EVP_AES_128_CTR +#define _libssh2_cipher_aes128ctr EVP_aes_128_ctr +#define _libssh2_cipher_aes192ctr EVP_aes_192_ctr +#define _libssh2_cipher_aes256ctr EVP_aes_256_ctr +#else +#define _libssh2_cipher_aes128ctr _libssh2_EVP_aes_128_ctr +#define _libssh2_cipher_aes192ctr _libssh2_EVP_aes_192_ctr +#define _libssh2_cipher_aes256ctr _libssh2_EVP_aes_256_ctr +#endif +#define _libssh2_cipher_blowfish EVP_bf_cbc +#define _libssh2_cipher_arcfour EVP_rc4 +#define _libssh2_cipher_cast5 EVP_cast5_cbc +#define _libssh2_cipher_3des EVP_des_ede3_cbc + +#define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_cleanup(ctx) + +#define _libssh2_bn BIGNUM +#define _libssh2_bn_ctx BN_CTX +#define _libssh2_bn_ctx_new() BN_CTX_new() +#define _libssh2_bn_ctx_free(bnctx) BN_CTX_free(bnctx) +#define _libssh2_bn_init() BN_new() +#define _libssh2_bn_init_from_bin() _libssh2_bn_init() +#define _libssh2_bn_rand(bn, bits, top, bottom) BN_rand(bn, bits, top, bottom) +#define _libssh2_bn_mod_exp(r, a, p, m, ctx) BN_mod_exp(r, a, p, m, ctx) +#define _libssh2_bn_set_word(bn, val) BN_set_word(bn, val) +#define _libssh2_bn_from_bin(bn, len, val) BN_bin2bn(val, len, bn) +#define _libssh2_bn_to_bin(bn, val) BN_bn2bin(bn, val) +#define _libssh2_bn_bytes(bn) BN_num_bytes(bn) +#define _libssh2_bn_bits(bn) BN_num_bits(bn) +#define _libssh2_bn_free(bn) BN_clear_free(bn) + +const EVP_CIPHER *_libssh2_EVP_aes_128_ctr(void); +const EVP_CIPHER *_libssh2_EVP_aes_192_ctr(void); +const EVP_CIPHER *_libssh2_EVP_aes_256_ctr(void); + diff --git a/include/libssh2/packet.h b/include/libssh2/packet.h new file mode 100644 index 0000000..d66b15b --- /dev/null +++ b/include/libssh2/packet.h @@ -0,0 +1,76 @@ +#ifndef LIBSSH2_PACKET_H +#define LIBSSH2_PACKET_H +/* + * Copyright (C) 2010 by Daniel Stenberg + * Author: Daniel Stenberg + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + */ + +int _libssh2_packet_read(LIBSSH2_SESSION * session); + +int _libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type, + unsigned char **data, size_t *data_len, + int match_ofs, + const unsigned char *match_buf, + size_t match_len); + +int _libssh2_packet_askv(LIBSSH2_SESSION * session, + const unsigned char *packet_types, + unsigned char **data, size_t *data_len, + int match_ofs, + const unsigned char *match_buf, + size_t match_len); +int _libssh2_packet_require(LIBSSH2_SESSION * session, + unsigned char packet_type, unsigned char **data, + size_t *data_len, int match_ofs, + const unsigned char *match_buf, + size_t match_len, + packet_require_state_t * state); +int _libssh2_packet_requirev(LIBSSH2_SESSION *session, + const unsigned char *packet_types, + unsigned char **data, size_t *data_len, + int match_ofs, + const unsigned char *match_buf, + size_t match_len, + packet_requirev_state_t * state); +int _libssh2_packet_burn(LIBSSH2_SESSION * session, + libssh2_nonblocking_states * state); +int _libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data, + unsigned long data_len); +int _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data, + size_t datalen, int macstate); + +#endif /* LIBSSH2_PACKET_H */ diff --git a/include/libssh2/session.h b/include/libssh2/session.h new file mode 100644 index 0000000..aff4f2c --- /dev/null +++ b/include/libssh2/session.h @@ -0,0 +1,93 @@ +#ifndef LIBSSH2_SESSION_H +#define LIBSSH2_SESSION_H +/* Copyright (c) 2004-2007 Sara Golemon + * Copyright (c) 2009-2010 by Daniel Stenberg + * Copyright (c) 2010 Simon Josefsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +/* Conveniance-macros to allow code like this; + + int rc = BLOCK_ADJUST(rc, session, session_startup(session, sock) ); + + int rc = BLOCK_ADJUST_ERRNO(ptr, session, session_startup(session, sock) ); + + The point of course being to make sure that while in non-blocking mode + these always return no matter what the return code is, but in blocking mode + it blocks if EAGAIN is the reason for the return from the underlying + function. + +*/ +#define BLOCK_ADJUST(rc,sess,x) \ + do { \ + time_t entry_time = time (NULL); \ + do { \ + rc = x; \ + /* the order of the check below is important to properly deal with \ + the case when the 'sess' is freed */ \ + if((rc != LIBSSH2_ERROR_EAGAIN) || !sess->api_block_mode) \ + break; \ + rc = _libssh2_wait_socket(sess, entry_time); \ + } while(!rc); \ + } while(0) + +/* + * For functions that returns a pointer, we need to check if the API is + * non-blocking and return immediately. If the pointer is non-NULL we return + * immediately. If the API is blocking and we get a NULL we check the errno + * and *only* if that is EAGAIN we loop and wait for socket action. + */ +#define BLOCK_ADJUST_ERRNO(ptr,sess,x) \ + do { \ + time_t entry_time = time (NULL); \ + int rc; \ + do { \ + ptr = x; \ + if(!sess->api_block_mode || \ + (ptr != NULL) || \ + (libssh2_session_last_errno(sess) != LIBSSH2_ERROR_EAGAIN) ) \ + break; \ + rc = _libssh2_wait_socket(sess, entry_time); \ + } while(!rc); \ + } while(0) + + +int _libssh2_wait_socket(LIBSSH2_SESSION *session, time_t entry_time); + +/* this is the lib-internal set blocking function */ +int _libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking); + +#endif /* LIBSSH2_SESSION_H */ diff --git a/include/libssh2/sftp.h b/include/libssh2/sftp.h new file mode 100644 index 0000000..b553b16 --- /dev/null +++ b/include/libssh2/sftp.h @@ -0,0 +1,235 @@ +#ifndef _LIBSSH2_SFTP_H +#define _LIBSSH2_SFTP_H +/* + * Copyright (C) 2010 - 2012 by Daniel Stenberg + * Author: Daniel Stenberg + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + */ + +/* + * MAX_SFTP_OUTGOING_SIZE MUST not be larger than 32500 or so. This is the + * amount of data sent in each FXP_WRITE packet + */ +#define MAX_SFTP_OUTGOING_SIZE 30000 + +/* MAX_SFTP_READ_SIZE is how much data is asked for at max in each FXP_READ + * packets. + */ +#define MAX_SFTP_READ_SIZE 30000 + +struct sftp_pipeline_chunk { + struct list_node node; + size_t len; /* WRITE: size of the data to write + READ: how many bytes that was asked for */ + size_t sent; + ssize_t lefttosend; /* if 0, the entire packet has been sent off */ + uint32_t request_id; + unsigned char packet[1]; /* data */ +}; + +struct sftp_zombie_requests { + struct list_node node; + uint32_t request_id; +}; + +#ifndef MIN +#define MIN(x,y) ((x)<(y)?(x):(y)) +#endif + +struct _LIBSSH2_SFTP_PACKET +{ + struct list_node node; /* linked list header */ + uint32_t request_id; + unsigned char *data; + size_t data_len; /* payload size */ +}; + +typedef struct _LIBSSH2_SFTP_PACKET LIBSSH2_SFTP_PACKET; + +#define SFTP_HANDLE_MAXLEN 256 /* according to spec! */ + +struct _LIBSSH2_SFTP_HANDLE +{ + struct list_node node; + + LIBSSH2_SFTP *sftp; + + char handle[SFTP_HANDLE_MAXLEN]; + size_t handle_len; + + enum { + LIBSSH2_SFTP_HANDLE_FILE, + LIBSSH2_SFTP_HANDLE_DIR + } handle_type; + + union _libssh2_sftp_handle_data + { + struct _libssh2_sftp_handle_file_data + { + libssh2_uint64_t offset; + libssh2_uint64_t offset_sent; + size_t acked; /* container for acked data that hasn't been + returned to caller yet, used for sftp_write */ + + /* 'data' is used by sftp_read() and is allocated data that has + been received already from the server but wasn't returned to + the caller yet. It is of size 'data_len' and 'data_left is the + number of bytes not yet returned, counted from the end of the + buffer. */ + unsigned char *data; + size_t data_len; + size_t data_left; + + char eof; /* we have read to the end */ + } file; + struct _libssh2_sftp_handle_dir_data + { + uint32_t names_left; + void *names_packet; + char *next_name; + } dir; + } u; + + /* State variables used in libssh2_sftp_close_handle() */ + libssh2_nonblocking_states close_state; + uint32_t close_request_id; + unsigned char *close_packet; + + /* list of outstanding packets sent to server */ + struct list_head packet_list; + +}; + +struct _LIBSSH2_SFTP +{ + LIBSSH2_CHANNEL *channel; + + uint32_t request_id, version; + + struct list_head packets; + + /* List of FXP_READ responses to ignore because EOF already received. */ + struct list_head zombie_requests; + + /* a list of _LIBSSH2_SFTP_HANDLE structs */ + struct list_head sftp_handles; + + uint32_t last_errno; + + /* Holder for partial packet, use in libssh2_sftp_packet_read() */ + unsigned char partial_size[4]; /* buffer for size field */ + size_t partial_size_len; /* size field length */ + unsigned char *partial_packet; /* The data */ + uint32_t partial_len; /* Desired number of bytes */ + size_t partial_received; /* Bytes received so far */ + + /* Time that libssh2_sftp_packet_requirev() started reading */ + time_t requirev_start; + + /* State variables used in libssh2_sftp_open_ex() */ + libssh2_nonblocking_states open_state; + unsigned char *open_packet; + uint32_t open_packet_len; /* 32 bit on the wire */ + size_t open_packet_sent; + uint32_t open_request_id; + + /* State variable used in sftp_read() */ + libssh2_nonblocking_states read_state; + + /* State variable used in sftp_packet_read() */ + libssh2_nonblocking_states packet_state; + + /* State variable used in sftp_write() */ + libssh2_nonblocking_states write_state; + + /* State variables used in sftp_fsync() */ + libssh2_nonblocking_states fsync_state; + unsigned char *fsync_packet; + uint32_t fsync_request_id; + + /* State variables used in libssh2_sftp_readdir() */ + libssh2_nonblocking_states readdir_state; + unsigned char *readdir_packet; + uint32_t readdir_request_id; + + /* State variables used in libssh2_sftp_fstat_ex() */ + libssh2_nonblocking_states fstat_state; + unsigned char *fstat_packet; + uint32_t fstat_request_id; + + /* State variables used in libssh2_sftp_unlink_ex() */ + libssh2_nonblocking_states unlink_state; + unsigned char *unlink_packet; + uint32_t unlink_request_id; + + /* State variables used in libssh2_sftp_rename_ex() */ + libssh2_nonblocking_states rename_state; + unsigned char *rename_packet; + unsigned char *rename_s; + uint32_t rename_request_id; + + /* State variables used in libssh2_sftp_fstatvfs() */ + libssh2_nonblocking_states fstatvfs_state; + unsigned char *fstatvfs_packet; + uint32_t fstatvfs_request_id; + + /* State variables used in libssh2_sftp_statvfs() */ + libssh2_nonblocking_states statvfs_state; + unsigned char *statvfs_packet; + uint32_t statvfs_request_id; + + /* State variables used in libssh2_sftp_mkdir() */ + libssh2_nonblocking_states mkdir_state; + unsigned char *mkdir_packet; + uint32_t mkdir_request_id; + + /* State variables used in libssh2_sftp_rmdir() */ + libssh2_nonblocking_states rmdir_state; + unsigned char *rmdir_packet; + uint32_t rmdir_request_id; + + /* State variables used in libssh2_sftp_stat() */ + libssh2_nonblocking_states stat_state; + unsigned char *stat_packet; + uint32_t stat_request_id; + + /* State variables used in libssh2_sftp_symlink() */ + libssh2_nonblocking_states symlink_state; + unsigned char *symlink_packet; + uint32_t symlink_request_id; +}; + +#endif diff --git a/include/libssh2/transport.h b/include/libssh2/transport.h new file mode 100644 index 0000000..89982a6 --- /dev/null +++ b/include/libssh2/transport.h @@ -0,0 +1,87 @@ +#ifndef __LIBSSH2_TRANSPORT_H +#define __LIBSSH2_TRANSPORT_H + +/* Copyright (C) 2007 The Written Word, Inc. All rights reserved. + * Copyright (C) 2009-2010 by Daniel Stenberg + * Author: Daniel Stenberg + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file handles reading and writing to the SECSH transport layer. RFC4253. + */ + +#include "libssh2_priv.h" +#include "packet.h" + + +/* + * libssh2_transport_send + * + * Send a packet, encrypting it and adding a MAC code if necessary + * Returns 0 on success, non-zero on failure. + * + * The data is provided as _two_ data areas that are combined by this + * function. The 'data' part is sent immediately before 'data2'. 'data2' can + * be set to NULL (or data2_len to 0) to only use a single part. + * + * Returns LIBSSH2_ERROR_EAGAIN if it would block or if the whole packet was + * not sent yet. If it does so, the caller should call this function again as + * soon as it is likely that more data can be sent, and this function MUST + * then be called with the same argument set (same data pointer and same + * data_len) until ERROR_NONE or failure is returned. + * + * This function DOES NOT call _libssh2_error() on any errors. + */ +int _libssh2_transport_send(LIBSSH2_SESSION *session, + const unsigned char *data, size_t data_len, + const unsigned char *data2, size_t data2_len); + +/* + * _libssh2_transport_read + * + * Collect a packet into the input brigade block only controls whether or not + * to wait for a packet to start. + * + * Returns packet type added to input brigade (PACKET_NONE if nothing added), + * or PACKET_FAIL on failure and PACKET_EAGAIN if it couldn't process a full + * packet. + */ + +/* + * This function reads the binary stream as specified in chapter 6 of RFC4253 + * "The Secure Shell (SSH) Transport Layer Protocol" + */ +int _libssh2_transport_read(LIBSSH2_SESSION * session); + +#endif /* __LIBSSH2_TRANSPORT_H */ diff --git a/include/libssh2/userauth.h b/include/libssh2/userauth.h new file mode 100644 index 0000000..c0442ae --- /dev/null +++ b/include/libssh2/userauth.h @@ -0,0 +1,50 @@ +#ifndef LIBSSH2_USERAUTH_H +#define LIBSSH2_USERAUTH_H +/* Copyright (c) 2004-2007, Sara Golemon + * Copyright (c) 2009-2010 by Daniel Stenberg + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +int +_libssh2_userauth_publickey(LIBSSH2_SESSION *session, + const char *username, + unsigned int username_len, + const unsigned char *pubkeydata, + unsigned long pubkeydata_len, + LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*sign_callback)), + void *abstract); + +#endif /* LIBSSH2_USERAUTH_H */ diff --git a/include/module.mk b/include/module.mk new file mode 100644 index 0000000..85a9382 --- /dev/null +++ b/include/module.mk @@ -0,0 +1,40 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/copyright.h \ + include/pgAdmin3.h \ + include/postgres.h \ + include/precomp.h \ + include/svnversion.h \ + include/version.h + +EXTRA_DIST += \ + include/module.mk + +include include/agent/module.mk +include include/db/module.mk +include include/dd/module.mk +include include/dlg/module.mk +include include/debugger/module.mk +include include/ctl/module.mk +include include/frm/module.mk +include include/images/module.mk +include include/parser/module.mk +include include/pgscript/module.mk +include include/schema/module.mk +include include/slony/module.mk +include include/gqb/module.mk +include include/hotdraw/module.mk +include include/utils/module.mk +include include/ogl/module.mk +include include/libssh2/module.mk + diff --git a/include/ogl/README b/include/ogl/README new file mode 100644 index 0000000..b5f2e06 --- /dev/null +++ b/include/ogl/README @@ -0,0 +1,3 @@ +This is the latest version of the wxOGL code, as donated to the project +with written permission to relicence under the PostgreSQL licence from +Julian Smart. diff --git a/include/ogl/basic.h b/include/ogl/basic.h new file mode 100644 index 0000000..9a17a70 --- /dev/null +++ b/include/ogl/basic.h @@ -0,0 +1,963 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// basic.h - Basic OGL classes and definitions +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _OGL_BASIC_H_ +#define _OGL_BASIC_H_ + +#ifndef wxUSE_DEPRECATED +#define wxUSE_DEPRECATED 0 +#endif + +#if wxUSE_DEPRECATED +#include +#endif + +#define OGL_VERSION 2.0 + +#ifndef DEFAULT_MOUSE_TOLERANCE +#define DEFAULT_MOUSE_TOLERANCE 3 +#endif + +// Key identifiers +#define KEY_SHIFT 1 +#define KEY_CTRL 2 + +// Arrow styles + +#define ARROW_NONE 0 +#define ARROW_END 1 +#define ARROW_BOTH 2 +#define ARROW_MIDDLE 3 +#define ARROW_START 4 + +// Control point types +// Rectangle and most other shapes +#define CONTROL_POINT_VERTICAL 1 +#define CONTROL_POINT_HORIZONTAL 2 +#define CONTROL_POINT_DIAGONAL 3 + +// Line +#define CONTROL_POINT_ENDPOINT_TO 4 +#define CONTROL_POINT_ENDPOINT_FROM 5 +#define CONTROL_POINT_LINE 6 + +// Types of formatting: can be combined in a bit list +#define FORMAT_NONE 0 +// Left justification +#define FORMAT_CENTRE_HORIZ 1 +// Centre horizontally +#define FORMAT_CENTRE_VERT 2 +// Centre vertically +#define FORMAT_SIZE_TO_CONTENTS 4 +// Resize shape to contents + +// Shadow mode +#define SHADOW_NONE 0 +#define SHADOW_LEFT 1 +#define SHADOW_RIGHT 2 + +/* + * Declare types + * + */ + +#define SHAPE_BASIC wxTYPE_USER + 1 +#define SHAPE_RECTANGLE wxTYPE_USER + 2 +#define SHAPE_ELLIPSE wxTYPE_USER + 3 +#define SHAPE_POLYGON wxTYPE_USER + 4 +#define SHAPE_CIRCLE wxTYPE_USER + 5 +#define SHAPE_LINE wxTYPE_USER + 6 +#define SHAPE_DIVIDED_RECTANGLE wxTYPE_USER + 8 +#define SHAPE_COMPOSITE wxTYPE_USER + 9 +#define SHAPE_CONTROL_POINT wxTYPE_USER + 10 +#define SHAPE_DRAWN wxTYPE_USER + 11 +#define SHAPE_DIVISION wxTYPE_USER + 12 +#define SHAPE_LABEL_OBJECT wxTYPE_USER + 13 +#define SHAPE_BITMAP wxTYPE_USER + 14 +#define SHAPE_DIVIDED_OBJECT_CONTROL_POINT wxTYPE_USER + 15 + +#define OBJECT_REGION wxTYPE_USER + 20 + +#define OP_CLICK_LEFT 1 +#define OP_CLICK_RIGHT 2 +#define OP_DRAG_LEFT 4 +#define OP_DRAG_RIGHT 8 + +#define OP_ALL (OP_CLICK_LEFT | OP_CLICK_RIGHT | OP_DRAG_LEFT | OP_DRAG_RIGHT) + +// Attachment modes +#define ATTACHMENT_MODE_NONE 0 +#define ATTACHMENT_MODE_EDGE 1 +#define ATTACHMENT_MODE_BRANCHING 2 + +// Sub-modes for branching attachment mode +#define BRANCHING_ATTACHMENT_NORMAL 1 +#define BRANCHING_ATTACHMENT_BLOB 2 + +class wxShapeTextLine; +class wxShapeCanvas; +class wxLineShape; +class wxControlPoint; +class wxShapeRegion; +class wxShape; + +#if wxUSE_PROLOGIO +class WXDLLEXPORT wxExpr; +class WXDLLEXPORT wxExprDatabase; +#endif + +// Round up +#define WXROUND(x) ( (long) (x + 0.5) ) + + +// logical function to use when drawing rubberband boxes, etc. +#define OGLRBLF wxINVERT + + + +class wxShapeEvtHandler: public wxObject, public wxClientDataContainer +{ + DECLARE_DYNAMIC_CLASS(wxShapeEvtHandler) + +public: + wxShapeEvtHandler(wxShapeEvtHandler *prev = NULL, wxShape *shape = NULL); + virtual ~wxShapeEvtHandler(); + + inline void SetShape(wxShape *sh) + { + m_handlerShape = sh; + } + inline wxShape *GetShape() const + { + return m_handlerShape; + } + + inline void SetPreviousHandler(wxShapeEvtHandler *handler) + { + m_previousHandler = handler; + } + inline wxShapeEvtHandler *GetPreviousHandler() const + { + return m_previousHandler; + } + + // This is called when the _shape_ is deleted. + virtual void OnDelete(); + virtual void OnDraw(wxDC &dc); + virtual void OnDrawContents(wxDC &dc); + virtual void OnDrawBranches(wxDC &dc, bool erase = FALSE); + virtual void OnMoveLinks(); + virtual void OnHighlight(wxDC &dc); + virtual void OnLeftClick(double x, double y, int keys = 0, int attachment = 0); + virtual void OnLeftDoubleClick(double x, double y, int keys = 0, int attachment = 0); + virtual void OnRightClick(double x, double y, int keys = 0, int attachment = 0); + virtual void OnSize(double x, double y); + virtual bool OnMovePre(double x, double y, double old_x, double old_y, bool display = TRUE); + virtual void OnMovePost(double x, double y, double old_x, double old_y, bool display = TRUE); + + virtual void OnDragLeft(bool draw, double x, double y, int keys = 0, int attachment = 0); // Erase if draw false + virtual void OnBeginDragLeft(double x, double y, int keys = 0, int attachment = 0); + virtual void OnEndDragLeft(double x, double y, int keys = 0, int attachment = 0); + virtual void OnDragRight(bool draw, double x, double y, int keys = 0, int attachment = 0); // Erase if draw false + virtual void OnBeginDragRight(double x, double y, int keys = 0, int attachment = 0); + virtual void OnEndDragRight(double x, double y, int keys = 0, int attachment = 0); + virtual void OnDrawOutline(wxDC &dc, double x, double y, double w, double h); + virtual void OnDrawControlPoints(wxDC &dc); + virtual void OnMoveLink(bool moveControlPoints = TRUE); + + // Control points ('handles') redirect control to the actual shape, to make it easier + // to override sizing behaviour. + virtual void OnSizingDragLeft(wxControlPoint *pt, bool draw, double x, double y, int keys = 0, int attachment = 0); // Erase if draw false + virtual void OnSizingBeginDragLeft(wxControlPoint *pt, double x, double y, int keys = 0, int attachment = 0); + virtual void OnSizingEndDragLeft(wxControlPoint *pt, double x, double y, int keys = 0, int attachment = 0); + + virtual void OnBeginSize(double WXUNUSED(w), double WXUNUSED(h)) { } + virtual void OnEndSize(double WXUNUSED(w), double WXUNUSED(h)) { } + + // Can override this to prevent or intercept line reordering. + virtual void OnChangeAttachment(int attachment, wxLineShape *line, wxList &ordering); + + // Creates a copy of this event handler. + wxShapeEvtHandler *CreateNewCopy(); + + // Does the copy - override for new event handlers which might store + // app-specific data. + virtual void CopyData(wxShapeEvtHandler &WXUNUSED(copy)) {}; + +private: + wxShapeEvtHandler *m_previousHandler; + wxShape *m_handlerShape; +}; + +class wxShape: public wxShapeEvtHandler +{ + DECLARE_ABSTRACT_CLASS(wxShape) + +public: + + wxShape(wxShapeCanvas *can = NULL); + virtual ~wxShape(); + virtual void GetBoundingBoxMax(double *width, double *height); + virtual void GetBoundingBoxMin(double *width, double *height) = 0; + virtual bool GetPerimeterPoint(double x1, double y1, + double x2, double y2, + double *x3, double *y3); + inline wxShapeCanvas *GetCanvas() + { + return m_canvas; + } + virtual void SetCanvas(wxShapeCanvas *the_canvas); + virtual void AddToCanvas(wxShapeCanvas *the_canvas, wxShape *addAfter = NULL); + virtual void InsertInCanvas(wxShapeCanvas *the_canvas); + + virtual void RemoveFromCanvas(wxShapeCanvas *the_canvas); + inline double GetX() const + { + return m_xpos; + } + inline double GetY() const + { + return m_ypos; + } + inline void SetX(double x) + { + m_xpos = x; + } + inline void SetY(double y) + { + m_ypos = y; + } + + inline wxShape *GetParent() const + { + return m_parent; + } + inline void SetParent(wxShape *p) + { + m_parent = p; + } + wxShape *GetTopAncestor(); + inline wxList &GetChildren() + { + return m_children; + } + + virtual void OnDraw(wxDC &dc); + virtual void OnDrawContents(wxDC &dc); + virtual void OnMoveLinks(); + virtual void Unlink() { }; + void SetDrawHandles(bool drawH); + inline bool GetDrawHandles() + { + return m_drawHandles; + } + virtual void OnHighlight(wxDC &dc); + virtual void OnLeftClick(double x, double y, int keys = 0, int attachment = 0); + virtual void OnLeftDoubleClick(double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys) = 0, int WXUNUSED(attachment) = 0) {} + virtual void OnRightClick(double x, double y, int keys = 0, int attachment = 0); + virtual void OnSize(double x, double y); + virtual bool OnMovePre(double x, double y, double old_x, double old_y, bool display = TRUE); + virtual void OnMovePost(double x, double y, double old_x, double old_y, bool display = TRUE); + + virtual void OnDragLeft(bool draw, double x, double y, int keys = 0, int attachment = 0); // Erase if draw false + virtual void OnBeginDragLeft(double x, double y, int keys = 0, int attachment = 0); + virtual void OnEndDragLeft(double x, double y, int keys = 0, int attachment = 0); + virtual void OnDragRight(bool draw, double x, double y, int keys = 0, int attachment = 0); // Erase if draw false + virtual void OnBeginDragRight(double x, double y, int keys = 0, int attachment = 0); + virtual void OnEndDragRight(double x, double y, int keys = 0, int attachment = 0); + virtual void OnDrawOutline(wxDC &dc, double x, double y, double w, double h); + virtual void OnDrawControlPoints(wxDC &dc); + + virtual void OnBeginSize(double WXUNUSED(w), double WXUNUSED(h)) { } + virtual void OnEndSize(double WXUNUSED(w), double WXUNUSED(h)) { } + + // Control points ('handles') redirect control to the actual shape, to make it easier + // to override sizing behaviour. + virtual void OnSizingDragLeft(wxControlPoint *pt, bool draw, double x, double y, int keys = 0, int attachment = 0); // Erase if draw false + virtual void OnSizingBeginDragLeft(wxControlPoint *pt, double x, double y, int keys = 0, int attachment = 0); + virtual void OnSizingEndDragLeft(wxControlPoint *pt, double x, double y, int keys = 0, int attachment = 0); + + virtual void MakeControlPoints(); + virtual void DeleteControlPoints(wxDC *dc = NULL); + virtual void ResetControlPoints(); + + // Remove any child shapes before deleting shape. Currently for benefit of line shape. + virtual void RemoveChildren() {} + + inline wxShapeEvtHandler *GetEventHandler() + { + return m_eventHandler; + } + inline void SetEventHandler(wxShapeEvtHandler *handler) + { + m_eventHandler = handler; + } + + // Mandatory control points, e.g. the divided line moving handles + // should appear even if a child of the 'selected' image + virtual void MakeMandatoryControlPoints(); + virtual void ResetMandatoryControlPoints(); + + inline virtual bool Recompute() + { + return TRUE; + }; + // Calculate size recursively, if size changes. Size might depend on children. + inline virtual void CalculateSize() { }; + virtual void Select(bool select = TRUE); + virtual void SetHighlight(bool hi = TRUE, bool recurse = FALSE); + inline virtual bool IsHighlighted() const + { + return m_highlighted; + }; + virtual bool Selected() const; + virtual bool AncestorSelected() const; + void SetSensitivityFilter(int sens = OP_ALL, bool recursive = FALSE); + int GetSensitivityFilter() const + { + return m_sensitivity; + } + void SetDraggable(bool drag, bool recursive = FALSE); + inline void SetFixedSize(bool x, bool y) + { + m_fixedWidth = x; + m_fixedHeight = y; + }; + inline void GetFixedSize(bool *x, bool *y) const + { + *x = m_fixedWidth; + *y = m_fixedHeight; + }; + inline bool GetFixedWidth() const + { + return m_fixedWidth; + } + inline bool GetFixedHeight() const + { + return m_fixedHeight; + } + inline void SetSpaceAttachments(bool sp) + { + m_spaceAttachments = sp; + }; + inline bool GetSpaceAttachments() const + { + return m_spaceAttachments; + }; + void SetShadowMode(int mode, bool redraw = FALSE); + inline int GetShadowMode() const + { + return m_shadowMode; + } + virtual bool HitTest(double x, double y, int *attachment, double *distance); + inline void SetCentreResize(bool cr) + { + m_centreResize = cr; + } + inline bool GetCentreResize() const + { + return m_centreResize; + } + inline void SetMaintainAspectRatio(bool ar) + { + m_maintainAspectRatio = ar; + } + inline bool GetMaintainAspectRatio() const + { + return m_maintainAspectRatio; + } + inline wxList &GetLines() const + { + return (wxList &) m_lines; + } + inline void SetDisableLabel(bool flag) + { + m_disableLabel = flag; + } + inline bool GetDisableLabel() const + { + return m_disableLabel; + } + inline void SetAttachmentMode(int mode) + { + m_attachmentMode = mode; + } + inline int GetAttachmentMode() const + { + return m_attachmentMode; + } + inline void SetId(long i) + { + m_id = i; + } + inline long GetId() const + { + return m_id; + } + + void SetPen(wxPen *pen); + void SetBrush(wxBrush *brush); + + virtual void Refresh(wxShapeCanvas *canvas = NULL); + virtual void Show(bool show); + virtual bool IsShown() const + { + return m_visible; + } + virtual void Move(double x1, double y1, bool display = TRUE); + virtual void Erase(); + virtual void Draw(wxDC &dc); + virtual void Flash(); + virtual void MoveLinks(); + virtual void DrawContents(wxDC &dc); // E.g. for drawing text label + virtual void SetSize(double x, double y, bool recursive = TRUE); + virtual void SetAttachmentSize(double x, double y); + void Attach(wxShapeCanvas *can); + void Detach(); + + inline virtual bool Constrain() + { + return FALSE; + } ; + + void AddLine(wxLineShape *line, wxShape *other, + int attachFrom = 0, int attachTo = 0, + // The line ordering + int positionFrom = -1, int positionTo = -1); + + // Return the zero-based position in m_lines of line. + int GetLinePosition(wxLineShape *line); + + void AddText(const wxString &string); + + inline wxPen *GetPen() const + { + return m_pen; + } + inline wxBrush *GetBrush() const + { + return m_brush; + } + + /* + * Region-specific functions (defaults to the default region + * for simple objects + */ + + // Set the default, single region size to be consistent + // with the object size + void SetDefaultRegionSize(); + virtual void FormatText(wxDC &dc, const wxString &s, int regionId = 0); + virtual void SetFormatMode(int mode, int regionId = 0); + virtual int GetFormatMode(int regionId = 0) const; + virtual void SetFont(wxFont *font, int regionId = 0); + virtual wxFont *GetFont(int regionId = 0) const; + virtual void SetTextColour(const wxString &colour, int regionId = 0); + virtual void SetTextColour(const wxColour &colour, int regionId = 0); + virtual wxString GetTextColour(int regionId = 0) const; + virtual wxColour GetActualTextColour(int regionId = 0) const; + virtual inline int GetNumberOfTextRegions() const + { + return m_regions.GetCount(); + } + virtual void SetRegionName(const wxString &name, int regionId = 0); + + // Get the name representing the region for this image alone. + // I.e. this image's region ids go from 0 to N-1. + // But the names might be "0.2.0", "0.2.1" etc. depending on position in composite. + // So the last digit represents the region Id, the others represent positions + // in composites. + virtual wxString GetRegionName(int regionId); + + // Gets the region corresponding to the name, or -1 if not found. + virtual int GetRegionId(const wxString &name); + + // Construct names for regions, unique even for children of a composite. + virtual void NameRegions(const wxString &parentName = wxEmptyString); + + // Get list of regions + inline wxList &GetRegions() const + { + return (wxList &) m_regions; + } + + virtual void AddRegion(wxShapeRegion *region); + + virtual void ClearRegions(); + + // Assign new ids to this image and children (if composite) + void AssignNewIds(); + + // Returns actual image (same as 'this' if non-composite) and region id + // for given region name. + virtual wxShape *FindRegion(const wxString ®ionName, int *regionId); + + // Finds all region names for this image (composite or simple). + // Supply empty string list. + virtual void FindRegionNames(wxStringList &list); + + virtual void ClearText(int regionId = 0); + void RemoveLine(wxLineShape *line); + +#if wxUSE_PROLOGIO + // I/O + virtual void WriteAttributes(wxExpr *clause); + virtual void ReadAttributes(wxExpr *clause); + + // In case the object has constraints it needs to read in in a different pass + inline virtual void ReadConstraints(wxExpr *WXUNUSED(clause), wxExprDatabase *WXUNUSED(database)) { }; + virtual void WriteRegions(wxExpr *clause); + virtual void ReadRegions(wxExpr *clause); +#endif + + // Attachment code + virtual bool GetAttachmentPosition(int attachment, double *x, double *y, + int nth = 0, int no_arcs = 1, wxLineShape *line = NULL); + virtual int GetNumberOfAttachments() const; + virtual wxList &GetAttachments() + { + return m_attachmentPoints; + } + + virtual bool AttachmentIsValid(int attachment) const; + + // Only get the attachment position at the _edge_ of the shape, ignoring + // branching mode. This is used e.g. to indicate the edge of interest, not the point + // on the attachment branch. + virtual bool GetAttachmentPositionEdge(int attachment, double *x, double *y, + int nth = 0, int no_arcs = 1, wxLineShape *line = NULL); + + // Assuming the attachment lies along a vertical or horizontal line, + // calculate the position on that point. + virtual wxRealPoint CalcSimpleAttachment(const wxRealPoint &pt1, const wxRealPoint &pt2, + int nth, int noArcs, wxLineShape *line); + + // Returns TRUE if pt1 <= pt2 in the sense that one point comes before another on an + // edge of the shape. + // attachmentPoint is the attachment point (= side) in question. + virtual bool AttachmentSortTest(int attachmentPoint, const wxRealPoint &pt1, const wxRealPoint &pt2); + + virtual void DrawLinks(wxDC &dc, int attachment = -1, bool recurse = FALSE); + + virtual bool MoveLineToNewAttachment(wxLineShape *to_move, + double x, double y); + + // Reorders the lines coming into the node image at this attachment + // position, in the order in which they appear in linesToSort. + virtual void SortLines(int attachment, wxList &linesToSort); + + // Apply an attachment ordering change + void ApplyAttachmentOrdering(wxList &ordering); + + // Can override this to prevent or intercept line reordering. + virtual void OnChangeAttachment(int attachment, wxLineShape *line, wxList &ordering); + + //// New banching attachment code, 24/9/98 + + // + // |________| + // | <- root + // | <- neck + // shoulder1 ->---------<- shoulder2 + // | | | | |<- stem + // <- branching attachment point N-1 + + // This function gets the root point at the given attachment. + virtual wxRealPoint GetBranchingAttachmentRoot(int attachment); + + // This function gets information about where branching connections go (calls GetBranchingAttachmentRoot) + virtual bool GetBranchingAttachmentInfo(int attachment, wxRealPoint &root, wxRealPoint &neck, + wxRealPoint &shoulder1, wxRealPoint &shoulder2); + + // n is the number of the adjoining line, from 0 to N-1 where N is the number of lines + // at this attachment point. + // attachmentPoint is where the arc meets the stem, and stemPoint is where the stem meets the + // shoulder. + virtual bool GetBranchingAttachmentPoint(int attachment, int n, wxRealPoint &attachmentPoint, + wxRealPoint &stemPoint); + + // Get the number of lines at this attachment position. + virtual int GetAttachmentLineCount(int attachment) const; + + // Draw the branches (not the actual arcs though) + virtual void OnDrawBranches(wxDC &dc, int attachment, bool erase = FALSE); + virtual void OnDrawBranches(wxDC &dc, bool erase = FALSE); + + // Branching attachment settings + inline void SetBranchNeckLength(int len) + { + m_branchNeckLength = len; + } + inline int GetBranchNeckLength() const + { + return m_branchNeckLength; + } + + inline void SetBranchStemLength(int len) + { + m_branchStemLength = len; + } + inline int GetBranchStemLength() const + { + return m_branchStemLength; + } + + inline void SetBranchSpacing(int len) + { + m_branchSpacing = len; + } + inline int GetBranchSpacing() const + { + return m_branchSpacing; + } + + // Further detail on branching style, e.g. blobs on interconnections + inline void SetBranchStyle(long style) + { + m_branchStyle = style; + } + inline long GetBranchStyle() const + { + return m_branchStyle; + } + + // Rotate the standard attachment point from physical (0 is always North) + // to logical (0 -> 1 if rotated by 90 degrees) + virtual int PhysicalToLogicalAttachment(int physicalAttachment) const; + + // Rotate the standard attachment point from logical + // to physical (0 is always North) + virtual int LogicalToPhysicalAttachment(int logicalAttachment) const; + + // This is really to distinguish between lines and other images. + // For lines, want to pass drag to canvas, since lines tend to prevent + // dragging on a canvas (they get in the way.) + virtual bool Draggable() const + { + return TRUE; + } + + // Returns TRUE if image is a descendant of this image + bool HasDescendant(wxShape *image); + + // Creates a copy of this shape. + wxShape *CreateNewCopy(bool resetMapping = TRUE, bool recompute = TRUE); + + // Does the copying for this object + virtual void Copy(wxShape ©); + + // Does the copying for this object, including copying event + // handler data if any. Calls the virtual Copy function. + void CopyWithHandler(wxShape ©); + + // Rotate about the given axis by the given amount in radians. + virtual void Rotate(double x, double y, double theta); + virtual double GetRotation() const + { + return m_rotation; + } + virtual void SetRotation(double rotation) + { + m_rotation = rotation; + } + + void ClearAttachments(); + + // Recentres all the text regions for this object + void Recentre(wxDC &dc); + + // Clears points from a list of wxRealPoints + void ClearPointList(wxList &list); + + // Return pen or brush of the right colour for the background + wxPen GetBackgroundPen(); + wxBrush GetBackgroundBrush(); + + +protected: + wxShapeEvtHandler *m_eventHandler; + bool m_formatted; + double m_xpos, m_ypos; + wxPen *m_pen; + wxBrush *m_brush; + wxFont *m_font; + wxColour m_textColour; + wxString m_textColourName; + wxShapeCanvas *m_canvas; + wxList m_lines; + wxList m_text; + wxList m_controlPoints; + wxList m_regions; + wxList m_attachmentPoints; + bool m_visible; + bool m_disableLabel; + long m_id; + bool m_selected; + bool m_highlighted; // Different from selected: user-defined highlighting, + // e.g. thick border. + double m_rotation; + int m_sensitivity; + bool m_draggable; + int m_attachmentMode; // 0 for no attachments, 1 if using normal attachments, + // 2 for branching attachments + bool m_spaceAttachments; // TRUE if lines at one side should be spaced + bool m_fixedWidth; + bool m_fixedHeight; + bool m_centreResize; // Default is to resize keeping the centre constant (TRUE) + bool m_drawHandles; // Don't draw handles if FALSE, usually TRUE + wxList m_children; // In case it's composite + wxShape *m_parent; // In case it's a child + int m_formatMode; + int m_shadowMode; + wxBrush *m_shadowBrush; + int m_shadowOffsetX; + int m_shadowOffsetY; + int m_textMarginX; // Gap between text and border + int m_textMarginY; + wxString m_regionName; + bool m_maintainAspectRatio; + int m_branchNeckLength; + int m_branchStemLength; + int m_branchSpacing; + long m_branchStyle; +}; + +class wxPolygonShape: public wxShape +{ + DECLARE_DYNAMIC_CLASS(wxPolygonShape) +public: + wxPolygonShape(); + ~wxPolygonShape(); + + // Takes a list of wxRealPoints; each point is an OFFSET from the centre. + // Deletes user's points in destructor. + // If points is NULL, simply creates both empty lists. + virtual void Create(wxList *points); + virtual void ClearPoints(); + + void GetBoundingBoxMin(double *w, double *h); + void CalculateBoundingBox(); + bool GetPerimeterPoint(double x1, double y1, + double x2, double y2, + double *x3, double *y3); + bool HitTest(double x, double y, int *attachment, double *distance); + void SetSize(double x, double y, bool recursive = TRUE); + void OnDraw(wxDC &dc); + void OnDrawOutline(wxDC &dc, double x, double y, double w, double h); + + // Control points ('handles') redirect control to the actual shape, to make it easier + // to override sizing behaviour. + virtual void OnSizingDragLeft(wxControlPoint *pt, bool draw, double x, double y, int keys = 0, int attachment = 0); + virtual void OnSizingBeginDragLeft(wxControlPoint *pt, double x, double y, int keys = 0, int attachment = 0); + virtual void OnSizingEndDragLeft(wxControlPoint *pt, double x, double y, int keys = 0, int attachment = 0); + + // A polygon should have a control point at each vertex, + // with the option of moving the control points individually + // to change the shape. + void MakeControlPoints(); + void ResetControlPoints(); + + // If we've changed the shape, must make the original + // points match the working points + void UpdateOriginalPoints(); + + // Add a control point after the given point + virtual void AddPolygonPoint(int pos = 0); + + // Delete a control point + virtual void DeletePolygonPoint(int pos = 0); + + // Recalculates the centre of the polygon + virtual void CalculatePolygonCentre(); + +#if wxUSE_PROLOGIO + void WriteAttributes(wxExpr *clause); + void ReadAttributes(wxExpr *clause); +#endif + + int GetNumberOfAttachments() const; + bool GetAttachmentPosition(int attachment, double *x, double *y, + int nth = 0, int no_arcs = 1, wxLineShape *line = NULL); + bool AttachmentIsValid(int attachment) const; + // Does the copying for this object + void Copy(wxShape ©); + + inline wxList *GetPoints() + { + return m_points; + } + inline wxList *GetOriginalPoints() + { + return m_originalPoints; + } + + // Rotate about the given axis by the given amount in radians + virtual void Rotate(double x, double y, double theta); + + double GetOriginalWidth() const + { + return m_originalWidth; + } + double GetOriginalHeight() const + { + return m_originalHeight; + } + + void SetOriginalWidth(double w) + { + m_originalWidth = w; + } + void SetOriginalHeight(double h) + { + m_originalHeight = h; + } + +private: + wxList *m_points; + wxList *m_originalPoints; + double m_boundWidth; + double m_boundHeight; + double m_originalWidth; + double m_originalHeight; +}; + +class wxRectangleShape: public wxShape +{ + DECLARE_DYNAMIC_CLASS(wxRectangleShape) +public: + wxRectangleShape(double w = 0.0, double h = 0.0); + void GetBoundingBoxMin(double *w, double *h); + bool GetPerimeterPoint(double x1, double y1, + double x2, double y2, + double *x3, double *y3); + void OnDraw(wxDC &dc); + void SetSize(double x, double y, bool recursive = TRUE); + void SetCornerRadius(double rad); // If > 0, rounded corners + double GetCornerRadius() const + { + return m_cornerRadius; + } + +#if wxUSE_PROLOGIO + void WriteAttributes(wxExpr *clause); + void ReadAttributes(wxExpr *clause); +#endif + + int GetNumberOfAttachments() const; + bool GetAttachmentPosition(int attachment, double *x, double *y, + int nth = 0, int no_arcs = 1, wxLineShape *line = NULL); + // Does the copying for this object + void Copy(wxShape ©); + + inline double GetWidth() const + { + return m_width; + } + inline double GetHeight() const + { + return m_height; + } + inline void SetWidth(double w) + { + m_width = w; + } + inline void SetHeight(double h) + { + m_height = h; + } + +protected: + double m_width; + double m_height; + double m_cornerRadius; +}; + +class wxTextShape: public wxRectangleShape +{ + DECLARE_DYNAMIC_CLASS(wxTextShape) +public: + wxTextShape(double width = 0.0, double height = 0.0); + + void OnDraw(wxDC &dc); + +#if wxUSE_PROLOGIO + void WriteAttributes(wxExpr *clause); +#endif + + // Does the copying for this object + void Copy(wxShape ©); +}; + +class wxEllipseShape: public wxShape +{ + DECLARE_DYNAMIC_CLASS(wxEllipseShape) +public: + wxEllipseShape(double w = 0.0, double h = 0.0); + + void GetBoundingBoxMin(double *w, double *h); + bool GetPerimeterPoint(double x1, double y1, + double x2, double y2, + double *x3, double *y3); + + void OnDraw(wxDC &dc); + void SetSize(double x, double y, bool recursive = TRUE); + +#if wxUSE_PROLOGIO + void WriteAttributes(wxExpr *clause); + void ReadAttributes(wxExpr *clause); +#endif + + int GetNumberOfAttachments() const; + bool GetAttachmentPosition(int attachment, double *x, double *y, + int nth = 0, int no_arcs = 1, wxLineShape *line = NULL); + + // Does the copying for this object + void Copy(wxShape ©); + + inline double GetWidth() const + { + return m_width; + } + inline double GetHeight() const + { + return m_height; + } + + inline void SetWidth(double w) + { + m_width = w; + } + inline void SetHeight(double h) + { + m_height = h; + } + +protected: + double m_width; + double m_height; +}; + +class wxCircleShape: public wxEllipseShape +{ + DECLARE_DYNAMIC_CLASS(wxCircleShape) +public: + wxCircleShape(double w = 0.0); + + bool GetPerimeterPoint(double x1, double y1, + double x2, double y2, + double *x3, double *y3); + // Does the copying for this object + void Copy(wxShape ©); +}; + +#endif +// _OGL_BASIC_H_ diff --git a/include/ogl/basicp.h b/include/ogl/basicp.h new file mode 100644 index 0000000..acc7116 --- /dev/null +++ b/include/ogl/basicp.h @@ -0,0 +1,305 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// basicp.h - Private OGL classes and definitions +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _OGL_BASICP_H_ +#define _OGL_BASICP_H_ + +#define CONTROL_POINT_SIZE 6 + +class wxShapeTextLine: public wxObject +{ + DECLARE_DYNAMIC_CLASS(wxShapeTextLine) +public: + wxShapeTextLine(double the_x = 0.0, double the_y = 0.0, const wxString &the_line = wxEmptyString); + ~wxShapeTextLine(); + + inline double GetX() const + { + return m_x; + } + inline double GetY() const + { + return m_y; + } + + inline void SetX(double x) + { + m_x = x; + } + inline void SetY(double y) + { + m_y = y; + } + + inline void SetText(const wxString &text) + { + m_line = text; + } + inline wxString GetText() const + { + return m_line; + } + +protected: + wxString m_line; + double m_x; + double m_y; +}; + +//class wxShape; +class wxControlPoint: public wxRectangleShape +{ + DECLARE_DYNAMIC_CLASS(wxControlPoint) + + friend class wxShapeEvtHandler; + friend class wxShape; + +public: + wxControlPoint(wxShapeCanvas *the_canvas = NULL, wxShape *object = NULL, double size = 0.0, double the_xoffset = 0.0, + double the_yoffset = 0.0, int the_type = 0); + ~wxControlPoint(); + + void OnDraw(wxDC &dc); + void OnErase(wxDC &dc); + void OnDrawContents(wxDC &dc); + void OnDragLeft(bool draw, double x, double y, int keys = 0, int attachment = 0); + void OnBeginDragLeft(double x, double y, int keys = 0, int attachment = 0); + void OnEndDragLeft(double x, double y, int keys = 0, int attachment = 0); + + bool GetAttachmentPosition(int attachment, double *x, double *y, + int nth = 0, int no_arcs = 1, wxLineShape *line = NULL); + int GetNumberOfAttachments() const; + + inline void SetEraseObject(bool er) + { + m_eraseObject = er; + } + +public: + int m_type; + double m_xoffset; + double m_yoffset; + wxShape *m_shape; + wxCursor *m_oldCursor; + bool m_eraseObject; // If TRUE, erases object before dragging handle. + + /* + * Store original top-left, bottom-right coordinates + * in case we're doing non-vertical resizing. + */ + static double sm_controlPointDragStartX; + static double sm_controlPointDragStartY; + static double sm_controlPointDragStartWidth; + static double sm_controlPointDragStartHeight; + static double sm_controlPointDragEndWidth; + static double sm_controlPointDragEndHeight; + static double sm_controlPointDragPosX; + static double sm_controlPointDragPosY; +}; + +class wxPolygonShape; +class wxPolygonControlPoint: public wxControlPoint +{ + DECLARE_DYNAMIC_CLASS(wxPolygonControlPoint) + friend class wxPolygonShape; +public: + wxPolygonControlPoint(wxShapeCanvas *the_canvas = NULL, wxShape *object = NULL, double size = 0.0, wxRealPoint *vertex = NULL, + double the_xoffset = 0.0, double the_yoffset = 0.0); + ~wxPolygonControlPoint(); + + void OnDragLeft(bool draw, double x, double y, int keys = 0, int attachment = 0); + void OnBeginDragLeft(double x, double y, int keys = 0, int attachment = 0); + void OnEndDragLeft(double x, double y, int keys = 0, int attachment = 0); + + // Calculate what new size would be, at end of resize + virtual void CalculateNewSize(double x, double y); + + // Get new size + inline wxRealPoint GetNewSize() const + { + return m_newSize; + }; + +public: + wxRealPoint *m_polygonVertex; + wxRealPoint m_originalSize; + double m_originalDistance; + wxRealPoint m_newSize; +}; + +/* + * Object regions. + * Every shape has one or more text regions with various + * properties. Not all of a region's properties will be used + * by a shape. + * + */ + +class wxShapeRegion: public wxObject +{ + DECLARE_DYNAMIC_CLASS(wxShapeRegion) + +public: + // Constructor + wxShapeRegion(); + // Copy constructor + wxShapeRegion(wxShapeRegion ®ion); + // Destructor + ~wxShapeRegion(); + + // Accessors + inline void SetText(const wxString &s) + { + m_regionText = s; /* m_formattedText.Append(new wxShapeTextLine(0,0,s)); */ + } + void SetFont(wxFont *f); + void SetMinSize(double w, double h); + void SetSize(double w, double h); + void SetPosition(double x, double y); + void SetProportions(double x, double y); + void SetFormatMode(int mode); + inline void SetName(const wxString &s) + { + m_regionName = s; + }; + void SetColour(const wxString &col); // Text colour + void SetColour(const wxColour &col); // Text colour + + inline wxString GetText() const + { + return m_regionText; + } + inline wxFont *GetFont() const + { + return m_font; + } + inline void GetMinSize(double *x, double *y) const + { + *x = m_minWidth; + *y = m_minHeight; + } + inline void GetProportion(double *x, double *y) const + { + *x = m_regionProportionX; + *y = m_regionProportionY; + } + inline void GetSize(double *x, double *y) const + { + *x = m_width; + *y = m_height; + } + inline void GetPosition(double *xp, double *yp) const + { + *xp = m_x; + *yp = m_y; + } + inline int GetFormatMode() const + { + return m_formatMode; + } + inline wxString GetName() const + { + return m_regionName; + } + inline wxString GetColour() const + { + return m_textColour; + } + const wxColour &GetActualColourObject(); + inline wxList &GetFormattedText() + { + return m_formattedText; + } + inline wxString GetPenColour() const + { + return m_penColour; + } + inline int GetPenStyle() const + { + return m_penStyle; + } + inline void SetPenStyle(int style) + { + m_penStyle = style; + m_actualPenObject = NULL; + } + void SetPenColour(const wxString &col); + wxPen *GetActualPen(); + inline double GetWidth() const + { + return m_width; + } + inline double GetHeight() const + { + return m_height; + } + + void ClearText(); + +public: + wxString m_regionText; + wxList m_formattedText; // List of wxShapeTextLines + wxFont *m_font; + double m_minHeight; // If zero, hide region. + double m_minWidth; // If zero, hide region. + double m_width; + double m_height; + double m_x; + double m_y; + + double m_regionProportionX; // Proportion of total object size; + // -1.0 indicates equal proportion + double m_regionProportionY; // Proportion of total object size; + // -1.0 indicates equal proportion + + int m_formatMode; // FORMAT_CENTRE_HORIZ | FORMAT_CENTRE_VERT | FORMAT_NONE + wxString m_regionName; + wxString m_textColour; + wxColour m_actualColourObject; // For speed purposes + + // New members for specifying divided rectangle division colour/style 30/6/94 + wxString m_penColour; + int m_penStyle; + wxPen *m_actualPenObject; + +}; + +/* + * User-defined attachment point + */ + +class wxAttachmentPoint: public wxObject +{ + DECLARE_DYNAMIC_CLASS(wxAttachmentPoint) + +public: + inline wxAttachmentPoint() + { + m_id = 0; + m_x = 0.0; + m_y = 0.0; + } + inline wxAttachmentPoint(int id, double x, double y) + { + m_id = id; + m_x = x; + m_y = y; + } + +public: + int m_id; // Identifier + double m_x; // x offset from centre of object + double m_y; // y offset from centre of object +}; + +#endif +// _OGL_BASICP_H_ diff --git a/include/ogl/bmpshape.h b/include/ogl/bmpshape.h new file mode 100644 index 0000000..304fa7e --- /dev/null +++ b/include/ogl/bmpshape.h @@ -0,0 +1,59 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// bmpshape.h - wxBitmapShape +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _OGL_BITMAP_H_ +#define _OGL_BITMAP_H_ + +#include "wx/bitmap.h" + +class wxBitmapShape: public wxRectangleShape +{ + DECLARE_DYNAMIC_CLASS(wxBitmapShape) +public: + wxBitmapShape(); + ~wxBitmapShape(); + + void OnDraw(wxDC &dc); + +#if wxUSE_PROLOGIO + // I/O + void WriteAttributes(wxExpr *clause); + void ReadAttributes(wxExpr *clause); +#endif + + // Does the copying for this object + void Copy(wxShape ©); + + void SetSize(double w, double h, bool recursive = TRUE); + inline wxBitmap &GetBitmap() const + { + return (wxBitmap &) m_bitmap; + } + void SetBitmap(const wxBitmap &bm); + inline void SetFilename(const wxString &f) + { + m_filename = f; + }; + inline wxString GetFilename() const + { + return m_filename; + } + +private: + wxBitmap m_bitmap; + wxString m_filename; +}; + +#endif +// _OGL_BITMAP_H_ + + diff --git a/include/ogl/canvas.h b/include/ogl/canvas.h new file mode 100644 index 0000000..9bc6ef6 --- /dev/null +++ b/include/ogl/canvas.h @@ -0,0 +1,119 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// canvas.h - wxShapeCanvas +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _OGL_CANVAS_H_ +#define _OGL_CANVAS_H_ + +// Drag states +#define NoDragging 0 +#define StartDraggingLeft 1 +#define ContinueDraggingLeft 2 +#define StartDraggingRight 3 +#define ContinueDraggingRight 4 + +#ifdef __WXMSW__ +#define OGL_USE_BUFFERED_PAINT 1 +#else +#define OGL_USE_BUFFERED_PAINT 0 +#endif + + +extern const wxChar *wxShapeCanvasNameStr; + +// When drag_count reaches 0, process drag message + +class wxDiagram; + +class wxShapeCanvas: public wxScrolledWindow +{ + DECLARE_DYNAMIC_CLASS(wxShapeCanvas) +public: + wxShapeCanvas(wxWindow *parent = NULL, wxWindowID id = -1, + const wxPoint &pos = wxDefaultPosition, + const wxSize &size = wxDefaultSize, + long style = wxBORDER | wxRETAINED, + const wxString &name = wxShapeCanvasNameStr); + ~wxShapeCanvas(); + + inline void SetDiagram(wxDiagram *diag) + { + m_shapeDiagram = diag; + } + inline wxDiagram *GetDiagram() const + { + return m_shapeDiagram; + } + + virtual void OnLeftClick(double x, double y, int keys = 0); + virtual void OnRightClick(double x, double y, int keys = 0); + + virtual void OnDragLeft(bool draw, double x, double y, int keys = 0); // Erase if draw false + virtual void OnBeginDragLeft(double x, double y, int keys = 0); + virtual void OnEndDragLeft(double x, double y, int keys = 0); + + virtual void OnDragRight(bool draw, double x, double y, int keys = 0); // Erase if draw false + virtual void OnBeginDragRight(double x, double y, int keys = 0); + virtual void OnEndDragRight(double x, double y, int keys = 0); + + // Find object for mouse click, of given wxClassInfo (NULL for any type). + // If notImage is non-NULL, don't find an object that is equal to or a descendant of notImage + virtual wxShape *FindShape(double x, double y, int *attachment, wxClassInfo *info = NULL, wxShape *notImage = NULL); + wxShape *FindFirstSensitiveShape(double x, double y, int *new_attachment, int op); + wxShape *FindFirstSensitiveShape1(wxShape *image, int op); + + // Redirect to wxDiagram object + virtual void AddShape(wxShape *object, wxShape *addAfter = NULL); + virtual void InsertShape(wxShape *object); + virtual void RemoveShape(wxShape *object); + virtual bool GetQuickEditMode(); + virtual void Redraw(wxDC &dc); + void Snap(double *x, double *y); + + // Returns the current scroll position + wxPoint GetCurrentPixelScrollPosition(); + + void ResetDragState() + { + m_dragState = NoDragging; + } + +#if OGL_USE_BUFFERED_PAINT + /// Recreate buffer bitmap if necessary + bool RecreateBuffer(const wxSize &size = wxDefaultSize); +#endif + + virtual void DrawBackground(wxDC &dc, bool transformed = FALSE); + + // Events + void OnPaint(wxPaintEvent &event); + void OnMouseEvent(wxMouseEvent &event); + void OnEraseBackground(wxEraseEvent &event); + +protected: + wxDiagram *m_shapeDiagram; + int m_dragState; + double m_oldDragX, m_oldDragY; // Previous drag coordinates + double m_firstDragX, m_firstDragY; // INITIAL drag coordinates + bool m_checkTolerance; // Whether to check drag tolerance + wxShape *m_draggedShape; + int m_draggedAttachment; + +#if OGL_USE_BUFFERED_PAINT + /// Buffer bitmap + wxBitmap m_bufferBitmap; +#endif + + DECLARE_EVENT_TABLE() +}; + +#endif +// _OGL_CANVAS_H_ diff --git a/include/ogl/composit.h b/include/ogl/composit.h new file mode 100644 index 0000000..481e153 --- /dev/null +++ b/include/ogl/composit.h @@ -0,0 +1,294 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// composit.h - wxCompositeShape +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _OGL_COMPOSIT_H_ +#define _OGL_COMPOSIT_H_ + +class wxDivisionShape; +class wxOGLConstraint; + +/* + * A composite object is an invisible rectangle surrounding all children + * + */ + +class wxCompositeShape: public wxRectangleShape +{ + DECLARE_DYNAMIC_CLASS(wxCompositeShape) +public: + + wxCompositeShape(); + ~wxCompositeShape(); + + void OnDraw(wxDC &dc); + void OnDrawContents(wxDC &dc); + bool OnMovePre(double x, double y, double oldX, double oldY, bool display = TRUE); + void OnDragLeft(bool draw, double x, double y, int keys, int attachment = 0); + void OnBeginDragLeft(double x, double y, int keys, int attachment = 0); + void OnEndDragLeft(double x, double y, int keys, int attachment = 0); + + void OnRightClick(double x, double y, int keys, int attachment = 0); + + void SetSize(double w, double h, bool recursive = TRUE); + + // Returns TRUE if it settled down + bool Recompute(); + + // New members + void AddChild(wxShape *child, wxShape *addAfter = NULL); + void RemoveChild(wxShape *child); + + wxOGLConstraint *AddConstraint(wxOGLConstraint *constraint); + wxOGLConstraint *AddConstraint(int type, wxShape *constraining, wxList &constrained); + wxOGLConstraint *AddConstraint(int type, wxShape *constraining, wxShape *constrained); + + void DeleteConstraint(wxOGLConstraint *constraint); + + // Delete constraints that involve this child. + void DeleteConstraintsInvolvingChild(wxShape *child); + + // Remove the image from any constraints involving it, but DON'T + // remove any constraints. + void RemoveChildFromConstraints(wxShape *child); + + // Find constraint, also returning actual composite the constraint was in, + // in case it had to find it recursively. + wxOGLConstraint *FindConstraint(long id, wxCompositeShape **actualComposite = NULL); + + // Returns TRUE if something changed + bool Constrain(); + + // Make this composite into a container by creating one wxDivisionShape + void MakeContainer(); + + // Calculates size and position of composite object based on children + void CalculateSize(); + +#if wxUSE_PROLOGIO + void WriteAttributes(wxExpr *clause); + void ReadAttributes(wxExpr *clause); + // In case the object has constraints it needs to read in in a different pass + void ReadConstraints(wxExpr *clause, wxExprDatabase *database); +#endif + // Does the copying for this object + void Copy(wxShape ©); + + virtual wxDivisionShape *OnCreateDivision(); + + // Finds the image used to visualize a container. This is any child + // of the composite that is not in the divisions list. + wxShape *FindContainerImage(); + + // Returns TRUE if division is a descendant of this container + bool ContainsDivision(wxDivisionShape *division); + + inline wxList &GetDivisions() const + { + return (wxList &) m_divisions; + } + inline wxList &GetConstraints() const + { + return (wxList &) m_constraints; + } + +protected: + double m_oldX; + double m_oldY; + wxList m_constraints; + wxList m_divisions; // In case it's a container +}; + +/* + * A division object is a composite with special properties, + * to be used for containment. It's a subdivision of a container. + * A containing node image consists of a composite with a main child shape + * such as rounded rectangle, plus a list of division objects. + * It needs to be a composite because a division contains pieces + * of diagram. + * NOTE a container has at least one wxDivisionShape for consistency. + * This can be subdivided, so it turns into two objects, then each of + * these can be subdivided, etc. + */ +#define DIVISION_SIDE_NONE 0 +#define DIVISION_SIDE_LEFT 1 +#define DIVISION_SIDE_TOP 2 +#define DIVISION_SIDE_RIGHT 3 +#define DIVISION_SIDE_BOTTOM 4 + +class wxDivisionShape: public wxCompositeShape +{ + DECLARE_DYNAMIC_CLASS(wxDivisionShape) +public: + + wxDivisionShape(); + ~wxDivisionShape(); + + void OnDraw(wxDC &dc); + void OnDrawContents(wxDC &dc); + bool OnMovePre(double x, double y, double oldX, double oldY, bool display = TRUE); + void OnDragLeft(bool draw, double x, double y, int keys, int attachment = 0); + void OnBeginDragLeft(double x, double y, int keys, int attachment = 0); + void OnEndDragLeft(double x, double y, int keys, int attachment = 0); + + void OnRightClick(double x, double y, int keys = 0, int attachment = 0); + + // Don't want this kind of composite to resize its subdiagrams, so + // override composite's SetSize. + void SetSize(double w, double h, bool recursive = TRUE); + + // Similarly for calculating size: it's fixed at whatever SetSize + // set it to, not in terms of children. + void CalculateSize(); + + void MakeControlPoints(); + void ResetControlPoints(); + void MakeMandatoryControlPoints(); + void ResetMandatoryControlPoints(); + +#if wxUSE_PROLOGIO + void WriteAttributes(wxExpr *clause); + void ReadAttributes(wxExpr *clause); +#endif + // Does the copying for this object + void Copy(wxShape ©); + + // Divide horizontally (wxHORIZONTAL) or vertically (wxVERTICAL) + bool Divide(int direction); + + // Resize adjoining divisions at the given side. If test is TRUE, + // just see whether it's possible for each adjoining region, + // returning FALSE if it's not. + bool ResizeAdjoining(int side, double newPos, bool test); + + // Adjust a side, returning FALSE if it's not physically possible. + bool AdjustLeft(double left, bool test); + bool AdjustTop(double top, bool test); + bool AdjustRight(double right, bool test); + bool AdjustBottom(double bottom, bool test); + + // Edit style of left or top side + void EditEdge(int side); + + // Popup menu + void PopupMenu(double x, double y); + + inline void SetLeftSide(wxDivisionShape *shape) + { + m_leftSide = shape; + } + inline void SetTopSide(wxDivisionShape *shape) + { + m_topSide = shape; + } + inline void SetRightSide(wxDivisionShape *shape) + { + m_rightSide = shape; + } + inline void SetBottomSide(wxDivisionShape *shape) + { + m_bottomSide = shape; + } + inline wxDivisionShape *GetLeftSide() const + { + return m_leftSide; + } + inline wxDivisionShape *GetTopSide() const + { + return m_topSide; + } + inline wxDivisionShape *GetRightSide() const + { + return m_rightSide; + } + inline wxDivisionShape *GetBottomSide() const + { + return m_bottomSide; + } + + inline void SetHandleSide(int side) + { + m_handleSide = side; + } + inline int GetHandleSide() const + { + return m_handleSide; + } + + inline void SetLeftSidePen(wxPen *pen) + { + m_leftSidePen = pen; + } + inline wxPen *GetLeftSidePen() const + { + return m_leftSidePen; + } + inline void SetTopSidePen(wxPen *pen) + { + m_topSidePen = pen; + } + inline wxPen *GetTopSidePen() const + { + return m_topSidePen; + } + + void SetLeftSideColour(const wxString &colour); + void SetTopSideColour(const wxString &colour); + void SetLeftSideStyle(const wxString &style); + void SetTopSideStyle(const wxString &style); + + inline wxString GetLeftSideColour() const + { + return m_leftSideColour; + } + inline wxString GetTopSideColour() const + { + return m_topSideColour; + } + inline wxString GetLeftSideStyle() const + { + return m_leftSideStyle; + } + inline wxString GetTopSideStyle() const + { + return m_topSideStyle; + } + +protected: + // Adjoining divisions. NULL indicates edge + // of container, and that side shouldn't be + // drawn. + wxDivisionShape *m_leftSide; + wxDivisionShape *m_rightSide; + wxDivisionShape *m_topSide; + wxDivisionShape *m_bottomSide; + + int m_handleSide; // Side at which handle is legal + + wxPen *m_leftSidePen; + wxPen *m_topSidePen; + wxString m_leftSideColour; + wxString m_topSideColour; + wxString m_leftSideStyle; + wxString m_topSideStyle; +}; + + +#define DIVISION_MENU_SPLIT_HORIZONTALLY 1 +#define DIVISION_MENU_SPLIT_VERTICALLY 2 +#define DIVISION_MENU_EDIT_LEFT_EDGE 3 +#define DIVISION_MENU_EDIT_TOP_EDGE 4 +#define DIVISION_MENU_EDIT_RIGHT_EDGE 5 +#define DIVISION_MENU_EDIT_BOTTOM_EDGE 6 +#define DIVISION_MENU_DELETE_ALL 7 + +#endif +// _OGL_COMPOSIT_H_ diff --git a/include/ogl/constrnt.h b/include/ogl/constrnt.h new file mode 100644 index 0000000..e3990b7 --- /dev/null +++ b/include/ogl/constrnt.h @@ -0,0 +1,96 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// constrnt.h - OGL constraint definitions +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _OGL_CONSTRNT_H_ +#define _OGL_CONSTRNT_H_ + +/* + * OGL Constraints + * + */ + +class wxOGLConstraintType: public wxObject +{ + DECLARE_DYNAMIC_CLASS(wxOGLConstraintType) +public: + wxOGLConstraintType(int type = 0, const wxString &name = wxEmptyString, + const wxString &phrase = wxEmptyString); + ~wxOGLConstraintType(); + +public: + int m_type; // E.g. gyCONSTRAINT_CENTRED_VERTICALLY + wxString m_name; // E.g. "Centre vertically" + wxString m_phrase; // E.g. "centred vertically with respect to", "left of" + +}; + +extern wxList *wxOGLConstraintTypes; + +#define gyCONSTRAINT_CENTRED_VERTICALLY 1 +#define gyCONSTRAINT_CENTRED_HORIZONTALLY 2 +#define gyCONSTRAINT_CENTRED_BOTH 3 +#define gyCONSTRAINT_LEFT_OF 4 +#define gyCONSTRAINT_RIGHT_OF 5 +#define gyCONSTRAINT_ABOVE 6 +#define gyCONSTRAINT_BELOW 7 +#define gyCONSTRAINT_ALIGNED_TOP 8 +#define gyCONSTRAINT_ALIGNED_BOTTOM 9 +#define gyCONSTRAINT_ALIGNED_LEFT 10 +#define gyCONSTRAINT_ALIGNED_RIGHT 11 + +// Like aligned, but with the objects centred on the respective edge +// of the reference object. +#define gyCONSTRAINT_MIDALIGNED_TOP 12 +#define gyCONSTRAINT_MIDALIGNED_BOTTOM 13 +#define gyCONSTRAINT_MIDALIGNED_LEFT 14 +#define gyCONSTRAINT_MIDALIGNED_RIGHT 15 + +class wxOGLConstraint: public wxObject +{ + DECLARE_DYNAMIC_CLASS(wxOGLConstraint) +public: + wxOGLConstraint() + { + m_xSpacing = 0.0; + m_ySpacing = 0.0; + m_constraintType = 0; + m_constraintName = wxEmptyString; + m_constraintId = 0; + m_constrainingObject = NULL; + } + wxOGLConstraint(int type, wxShape *constraining, wxList &constrained); + ~wxOGLConstraint(); + + // Returns TRUE if anything changed + bool Evaluate(); + inline void SetSpacing(double x, double y) + { + m_xSpacing = x; + m_ySpacing = y; + }; + bool Equals(double a, double b); + + double m_xSpacing; + double m_ySpacing; + int m_constraintType; + wxString m_constraintName; + long m_constraintId; + wxShape *m_constrainingObject; + wxList m_constrainedObjects; + +}; + +void OGLInitializeConstraintTypes(); +void OGLCleanUpConstraintTypes(); + +#endif +// _OGL_CONSTRNT_H_ diff --git a/include/ogl/divided.h b/include/ogl/divided.h new file mode 100644 index 0000000..b8443ad --- /dev/null +++ b/include/ogl/divided.h @@ -0,0 +1,72 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// divided.h - wxDividedShape +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _OGL_DIVIDED_H_ +#define _OGL_DIVIDED_H_ + +/* + * Definition of a region + * + */ + +/* + * Box divided into horizontal regions + * + */ + +extern wxFont *g_oglNormalFont; +class wxDividedShape: public wxRectangleShape +{ + DECLARE_DYNAMIC_CLASS(wxDividedShape) + +public: + wxDividedShape(double w = 0.0, double h = 0.0); + ~wxDividedShape(); + + void OnDraw(wxDC &dc); + void OnDrawContents(wxDC &dc); + + void SetSize(double w, double h, bool recursive = TRUE); + + void MakeControlPoints(); + void ResetControlPoints(); + + void MakeMandatoryControlPoints(); + void ResetMandatoryControlPoints(); + +#if wxUSE_PROLOGIO + void WriteAttributes(wxExpr *clause); + void ReadAttributes(wxExpr *clause); +#endif + + void Copy(wxShape ©); + + // Set all region sizes according to proportions and + // this object total size + void SetRegionSizes(); + + // Edit region colours/styles + void EditRegions(); + + // Attachment points correspond to regions in the divided box + bool GetAttachmentPosition(int attachment, double *x, double *y, + int nth = 0, int no_arcs = 1, wxLineShape *line = NULL); + bool AttachmentIsValid(int attachment) const; + int GetNumberOfAttachments() const; + + // Invoke editor on CTRL-right click + void OnRightClick(double x, double y, int keys = 0, int attachment = 0); +}; + +#endif +// _OGL_DIVIDED_H_ + diff --git a/include/ogl/drawn.h b/include/ogl/drawn.h new file mode 100644 index 0000000..c874793 --- /dev/null +++ b/include/ogl/drawn.h @@ -0,0 +1,280 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// drawn.h - wxDrawnShape +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _OGL_DRAWN_H_ +#define _OGL_DRAWN_H_ + +#define oglMETAFLAGS_OUTLINE 1 +#define oglMETAFLAGS_ATTACHMENTS 2 + +class wxDrawnShape; +class wxPseudoMetaFile: public wxObject +{ + DECLARE_DYNAMIC_CLASS(wxPseudoMetaFile) +public: + wxPseudoMetaFile(); + wxPseudoMetaFile(wxPseudoMetaFile &mf); + ~wxPseudoMetaFile(); + + void Draw(wxDC &dc, double xoffset, double yoffset); + +#if wxUSE_PROLOGIO + void WriteAttributes(wxExpr *clause, int whichAngle); + void ReadAttributes(wxExpr *clause, int whichAngle); +#endif + + void Clear(); + + void Copy(wxPseudoMetaFile ©); + + void Scale(double sx, double sy); + void ScaleTo(double w, double h); // Scale to fit size + void Translate(double x, double y); + + // Rotate about the given axis by theta radians from the x axis. + void Rotate(double x, double y, double theta); + + bool LoadFromMetaFile(const wxString &filename, double *width, double *height); + + void GetBounds(double *minX, double *minY, double *maxX, double *maxY); + + // Calculate size from current operations + void CalculateSize(wxDrawnShape *shape); + + inline wxList &GetOutlineColours() const + { + return (wxList &) m_outlineColours; + } + inline wxList &GetFillColours() const + { + return (wxList &) m_fillColours; + } + inline void SetRotateable(bool rot) + { + m_rotateable = rot; + } + inline bool GetRotateable() const + { + return m_rotateable; + } + + inline void SetSize(double w, double h) + { + m_width = w; + m_height = h; + } + + inline void SetFillBrush(wxBrush *brush) + { + m_fillBrush = brush; + } + inline wxBrush *GetFillBrush() const + { + return m_fillBrush; + } + + inline void SetOutlinePen(wxPen *pen) + { + m_outlinePen = pen; + } + inline wxPen *GetOutlinePen() const + { + return m_outlinePen; + } + + inline void SetOutlineOp(int op) + { + m_outlineOp = op; + } + inline int GetOutlineOp() const + { + return m_outlineOp; + } + + inline wxList &GetOps() const + { + return (wxList &) m_ops; + } + + // Is this a valid (non-empty) metafile? + inline bool IsValid() const + { + return (m_ops.GetCount() > 0); + } + +public: + /// Set of functions for drawing into a pseudo metafile. + /// They use integers, but doubles are used internally for accuracy + /// when scaling. + + virtual void DrawLine(const wxPoint &pt1, const wxPoint &pt2); + virtual void DrawRectangle(const wxRect &rect); + virtual void DrawRoundedRectangle(const wxRect &rect, double radius); + virtual void DrawArc(const wxPoint ¢rePt, const wxPoint &startPt, const wxPoint &endPt); + virtual void DrawEllipticArc(const wxRect &rect, double startAngle, double endAngle); + virtual void DrawEllipse(const wxRect &rect); + virtual void DrawPoint(const wxPoint &pt); + virtual void DrawText(const wxString &text, const wxPoint &pt); + virtual void DrawLines(int n, wxPoint pts[]); + // flags: + // oglMETAFLAGS_OUTLINE: will be used for drawing the outline and + // also drawing lines/arrows at the circumference. + // oglMETAFLAGS_ATTACHMENTS: will be used for initialising attachment points at + // the vertices (perhaps a rare case...) + virtual void DrawPolygon(int n, wxPoint pts[], int flags = 0); + virtual void DrawSpline(int n, wxPoint pts[]); + + virtual void SetClippingRect(const wxRect &rect); + virtual void DestroyClippingRect(); + + virtual void SetPen(wxPen *pen, bool isOutline = FALSE); // TODO: eventually, just store GDI object attributes, not actual + virtual void SetBrush(wxBrush *brush, bool isFill = FALSE); // pens/brushes etc. + virtual void SetFont(wxFont *font); + virtual void SetTextColour(const wxColour &colour); + virtual void SetBackgroundColour(const wxColour &colour); + virtual void SetBackgroundMode(int mode); + +public: + bool m_rotateable; + double m_width; + double m_height; + wxList m_ops; // List of drawing operations (see drawnp.h) + wxList m_gdiObjects; // List of pens, brushes and fonts for this object. + int m_outlineOp; // The op representing the outline, if any + + // Pen/brush specifying outline/fill colours + // to override operations. + wxPen *m_outlinePen; + wxBrush *m_fillBrush; + wxList m_outlineColours; // List of the GDI operations that comprise the outline + wxList m_fillColours; // List of the GDI operations that fill the shape + double m_currentRotation; +}; + +#define oglDRAWN_ANGLE_0 0 +#define oglDRAWN_ANGLE_90 1 +#define oglDRAWN_ANGLE_180 2 +#define oglDRAWN_ANGLE_270 3 + +class wxDrawnShape: public wxRectangleShape +{ + DECLARE_DYNAMIC_CLASS(wxDrawnShape) +public: + wxDrawnShape(); + ~wxDrawnShape(); + + void OnDraw(wxDC &dc); + +#if wxUSE_PROLOGIO + // I/O + void WriteAttributes(wxExpr *clause); + void ReadAttributes(wxExpr *clause); +#endif + + // Does the copying for this object + void Copy(wxShape ©); + + void Scale(double sx, double sy); + void Translate(double x, double y); + // Rotate about the given axis by theta radians from the x axis. + void Rotate(double x, double y, double theta); + + // Get current rotation + inline double GetRotation() const + { + return m_rotation; + } + + void SetSize(double w, double h, bool recursive = TRUE); + bool LoadFromMetaFile(const wxString &filename); + + inline void SetSaveToFile(bool save) + { + m_saveToFile = save; + } + inline wxPseudoMetaFile &GetMetaFile(int which = 0) const + { + return (wxPseudoMetaFile &) m_metafiles[which]; + } + + void OnDrawOutline(wxDC &dc, double x, double y, double w, double h); + + // Get the perimeter point using the special outline op, if there is one, + // otherwise use default wxRectangleShape scheme + bool GetPerimeterPoint(double x1, double y1, + double x2, double y2, + double *x3, double *y3); + + /// Set of functions for drawing into a pseudo metafile. + /// They use integers, but doubles are used internally for accuracy + /// when scaling. + + virtual void DrawLine(const wxPoint &pt1, const wxPoint &pt2); + virtual void DrawRectangle(const wxRect &rect); + virtual void DrawRoundedRectangle(const wxRect &rect, double radius); + virtual void DrawArc(const wxPoint ¢rePt, const wxPoint &startPt, const wxPoint &endPt); + virtual void DrawEllipticArc(const wxRect &rect, double startAngle, double endAngle); + virtual void DrawEllipse(const wxRect &rect); + virtual void DrawPoint(const wxPoint &pt); + virtual void DrawText(const wxString &text, const wxPoint &pt); + virtual void DrawLines(int n, wxPoint pts[]); + virtual void DrawPolygon(int n, wxPoint pts[], int flags = 0); + virtual void DrawSpline(int n, wxPoint pts[]); + + virtual void SetClippingRect(const wxRect &rect); + virtual void DestroyClippingRect(); + + virtual void SetDrawnPen(wxPen *pen, bool isOutline = FALSE); // TODO: eventually, just store GDI object attributes, not actual + virtual void SetDrawnBrush(wxBrush *brush, bool isFill = FALSE); // pens/brushes etc. + virtual void SetDrawnFont(wxFont *font); + virtual void SetDrawnTextColour(const wxColour &colour); + virtual void SetDrawnBackgroundColour(const wxColour &colour); + virtual void SetDrawnBackgroundMode(int mode); + + // Set the width/height according to the shapes in the metafile. + // Call this after drawing into the shape. + inline void CalculateSize() + { + m_metafiles[m_currentAngle].CalculateSize(this); + } + + inline void DrawAtAngle(int angle) + { + m_currentAngle = angle; + }; + + inline int GetAngle() const + { + return m_currentAngle; + } + +// Implementation +protected: + // Which metafile do we use now? Based on current rotation and validity + // of metafiles. + int DetermineMetaFile(double rotation); + +private: + // One metafile for each 90 degree rotation (or just a single one). + wxPseudoMetaFile m_metafiles[4]; + + // Don't save all wxDrawnShape metafiles to file: sometimes + // we take the metafile data from a symbol library. + bool m_saveToFile; + + // Which angle are we using/drawing into? + int m_currentAngle; +}; + +#endif +// _DRAWN_H_ + diff --git a/include/ogl/drawnp.h b/include/ogl/drawnp.h new file mode 100644 index 0000000..ea77f20 --- /dev/null +++ b/include/ogl/drawnp.h @@ -0,0 +1,220 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// drawnp.h - Private header for wxDrawnShape +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _OGL_DRAWNP_H_ +#define _OGL_DRAWNP_H_ + +/* + * Drawing operations + * + */ + +#define DRAWOP_SET_PEN 1 +#define DRAWOP_SET_BRUSH 2 +#define DRAWOP_SET_FONT 3 +#define DRAWOP_SET_TEXT_COLOUR 4 +#define DRAWOP_SET_BK_COLOUR 5 +#define DRAWOP_SET_BK_MODE 6 +#define DRAWOP_SET_CLIPPING_RECT 7 +#define DRAWOP_DESTROY_CLIPPING_RECT 8 + +/* +#define DRAWOP_CREATE_PEN 10 +#define DRAWOP_CREATE_BRUSH 11 +#define DRAWOP_CREATE_FONT 12 +*/ + +#define DRAWOP_DRAW_LINE 20 +#define DRAWOP_DRAW_POLYLINE 21 +#define DRAWOP_DRAW_POLYGON 22 +#define DRAWOP_DRAW_RECT 23 +#define DRAWOP_DRAW_ROUNDED_RECT 24 +#define DRAWOP_DRAW_ELLIPSE 25 +#define DRAWOP_DRAW_POINT 26 +#define DRAWOP_DRAW_ARC 27 +#define DRAWOP_DRAW_TEXT 28 +#define DRAWOP_DRAW_SPLINE 29 +#define DRAWOP_DRAW_ELLIPTIC_ARC 30 + +/* + * Base, virtual class + * + */ + +class wxDrawOp: public wxObject +{ +public: + inline wxDrawOp(int theOp) + { + m_op = theOp; + } + inline ~wxDrawOp() {} + inline virtual void Scale(double xScale, double yScale) {}; + inline virtual void Translate(double x, double y) {}; + inline virtual void Rotate(double x, double y, double theta, double sinTheta, double cosTheta) {}; + virtual void Do(wxDC &dc, double xoffset, double yoffset) = 0; + virtual wxDrawOp *Copy(wxPseudoMetaFile *newImage) = 0; +#if wxUSE_PROLOGIO + virtual wxExpr *WriteExpr(wxPseudoMetaFile *image) = 0; + virtual void ReadExpr(wxPseudoMetaFile *image, wxExpr *expr) = 0; +#endif + inline int GetOp() const + { + return m_op; + } + + // Draw an outline using the current operation. By default, return FALSE (not drawn) + virtual bool OnDrawOutline(wxDC &dc, double x, double y, double w, double h, + double oldW, double oldH) + { + return FALSE; + } + + // Get the perimeter point using this data + virtual bool GetPerimeterPoint(double x1, double y1, + double x2, double y2, + double *x3, double *y3, + double xOffset, double yOffset, + int attachmentMode) + { + return FALSE; + } + +protected: + int m_op; + +}; + +/* + * Set font, brush, text colour + * + */ + +class wxOpSetGDI: public wxDrawOp +{ +public: + wxOpSetGDI(int theOp, wxPseudoMetaFile *theImage, int theGdiIndex, int theMode = 0); + void Do(wxDC &dc, double xoffset, double yoffset); + wxDrawOp *Copy(wxPseudoMetaFile *newImage); +#if wxUSE_PROLOGIO + wxExpr *WriteExpr(wxPseudoMetaFile *image); + void ReadExpr(wxPseudoMetaFile *image, wxExpr *expr); +#endif + +public: + int m_mode; + int m_gdiIndex; + wxPseudoMetaFile *m_image; + unsigned char m_r; + unsigned char m_g; + unsigned char m_b; +}; + +/* + * Set/destroy clipping + * + */ + +class wxOpSetClipping: public wxDrawOp +{ +public: + wxOpSetClipping(int theOp, double theX1, double theY1, double theX2, double theY2); + void Do(wxDC &dc, double xoffset, double yoffset); + void Scale(double xScale, double yScale); + void Translate(double x, double y); + wxDrawOp *Copy(wxPseudoMetaFile *newImage); +#if wxUSE_PROLOGIO + wxExpr *WriteExpr(wxPseudoMetaFile *image); + void ReadExpr(wxPseudoMetaFile *image, wxExpr *expr); +#endif + +public: + double m_x1; + double m_y1; + double m_x2; + double m_y2; +}; + +/* + * Draw line, rectangle, rounded rectangle, ellipse, point, arc, text + * + */ + +class wxOpDraw: public wxDrawOp +{ +public: + wxOpDraw(int theOp, double theX1, double theY1, double theX2, double theY2, + double radius = 0.0, wxChar *s = NULL); + ~wxOpDraw(); + void Do(wxDC &dc, double xoffset, double yoffset); + void Scale(double scaleX, double scaleY); + void Translate(double x, double y); + void Rotate(double x, double y, double theta, double sinTheta, double cosTheta); + wxDrawOp *Copy(wxPseudoMetaFile *newImage); +#if wxUSE_PROLOGIO + wxExpr *WriteExpr(wxPseudoMetaFile *image); + void ReadExpr(wxPseudoMetaFile *image, wxExpr *expr); +#endif + +public: + double m_x1; + double m_y1; + double m_x2; + double m_y2; + double m_x3; + double m_y3; + double m_radius; + wxChar *m_textString; + +}; + +/* + * Draw polyline, spline, polygon + * + */ + +class wxOpPolyDraw: public wxDrawOp +{ +public: + wxOpPolyDraw(int theOp, int n, wxRealPoint *thePoints); + ~wxOpPolyDraw(); + void Do(wxDC &dc, double xoffset, double yoffset); + void Scale(double scaleX, double scaleY); + void Translate(double x, double y); + void Rotate(double x, double y, double theta, double sinTheta, double cosTheta); + wxDrawOp *Copy(wxPseudoMetaFile *newImage); +#if wxUSE_PROLOGIO + wxExpr *WriteExpr(wxPseudoMetaFile *image); + void ReadExpr(wxPseudoMetaFile *image, wxExpr *expr); +#endif + + // Draw an outline using the current operation. + virtual bool OnDrawOutline(wxDC &dc, double x, double y, double w, double h, + double oldW, double oldH); + + // Get the perimeter point using this data + bool GetPerimeterPoint(double x1, double y1, + double x2, double y2, + double *x3, double *y3, + double xOffset, double yOffset, + int attachmentMode); + +public: + wxRealPoint *m_points; + int m_noPoints; + +}; + +#endif +// _OGL_DRAWNP_H_ + + diff --git a/include/ogl/lines.h b/include/ogl/lines.h new file mode 100644 index 0000000..8333a45 --- /dev/null +++ b/include/ogl/lines.h @@ -0,0 +1,403 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// lines.h - wxLineShape +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _OGL_LINES_H_ +#define _OGL_LINES_H_ + +class wxLabelShape; +class wxPseudoMetaFile; +class wxLineControlPoint; +/* + * Arcs with multiple arrowheads + * + */ + +// Types of arrowhead +// (i) Built-in +#define ARROW_HOLLOW_CIRCLE 1 +#define ARROW_FILLED_CIRCLE 2 +#define ARROW_ARROW 3 +#define ARROW_SINGLE_OBLIQUE 4 +#define ARROW_DOUBLE_OBLIQUE 5 +// (ii) Custom +#define ARROW_METAFILE 20 + +// Position of arrow on line +#define ARROW_POSITION_START 0 +#define ARROW_POSITION_END 1 +#define ARROW_POSITION_MIDDLE 2 + +// Line alignment flags +// Vertical by default +#define LINE_ALIGNMENT_HORIZ 1 +#define LINE_ALIGNMENT_VERT 0 +#define LINE_ALIGNMENT_TO_NEXT_HANDLE 2 +#define LINE_ALIGNMENT_NONE 0 + +class wxArrowHead: public wxObject +{ + DECLARE_DYNAMIC_CLASS(wxArrowHead) + +public: + wxArrowHead(WXTYPE type = 0, int end = 0, double size = 0.0, double dist = 0.0, const wxString &name = wxEmptyString, wxPseudoMetaFile *mf = NULL, + long arrowId = -1); + ~wxArrowHead(); + wxArrowHead(wxArrowHead &toCopy); + + inline WXTYPE _GetType() const + { + return m_arrowType; + } + inline int GetPosition() const + { + return m_arrowEnd; + } + inline void SetPosition(int pos) + { + m_arrowEnd = pos; + } + inline double GetXOffset() const + { + return m_xOffset; + } + inline double GetYOffset() const + { + return m_yOffset; + } + inline double GetSpacing() const + { + return m_spacing; + } + inline double GetSize() const + { + return m_arrowSize; + } + inline wxString GetName() const + { + return m_arrowName; + } + inline void SetXOffset(double x) + { + m_xOffset = x; + } + inline void SetYOffset(double y) + { + m_yOffset = y; + } + inline wxPseudoMetaFile *GetMetaFile() const + { + return m_metaFile; + } + inline long GetId() const + { + return m_id; + } + inline int GetArrowEnd() const + { + return m_arrowEnd; + } + inline double GetArrowSize() const + { + return m_arrowSize; + } + void SetSize(double size); + inline void SetSpacing(double sp) + { + m_spacing = sp; + } + +protected: + WXTYPE m_arrowType; + int m_arrowEnd; // Position on line + double m_xOffset; // Distance from arc start or end, w.r.t. point on arrowhead + // nearest start or end. If zero, use default spacing. + double m_yOffset; // vertical offset (w.r.t. a horizontal line). Normally zero. + double m_spacing; // Spacing from the last arrowhead + double m_arrowSize; // Length of arrowhead + wxString m_arrowName; // Name of arrow + bool m_saveToFile; // TRUE if we want to save custom arrowheads to file. + wxPseudoMetaFile *m_metaFile; // Pseudo metafile if this is a custom arrowhead + long m_id; // identifier +}; + +// Line object +class wxLabelShape; +class wxLineShape: public wxShape +{ + DECLARE_DYNAMIC_CLASS(wxLineShape) + +public: + wxLineShape(); + ~wxLineShape(); + + // Called when a connected object has moved, to move the link to + // correct position + // moveControlPoints must be disabled when a control point is being + // dragged. + void OnMoveLink(bool moveControlPoints = TRUE); + bool OnMovePre(double x, double y, double old_x, double old_y, bool display = TRUE); + void OnDraw(wxDC &dc); + void OnDrawContents(wxDC &dc); + void OnDrawControlPoints(wxDC &dc); + virtual bool OnMoveControlPoint(int WXUNUSED(which), double WXUNUSED(x), double WXUNUSED(y)) + { + return FALSE; + } + virtual bool OnMoveMiddleControlPoint(wxLineControlPoint *lpt, const wxRealPoint &pt); + virtual bool OnLabelMovePre(wxLabelShape *labelShape, double x, double y, double old_x, double old_y, bool display); + void OnDrawOutline(wxDC &dc, double x, double y, double w, double h); + void GetBoundingBoxMin(double *w, double *h); + void FormatText(wxDC &dc, const wxString &s, int regionId = 0); + virtual void SetEnds(double x1, double y1, double x2, double y2); + virtual void GetEnds(double *x1, double *y1, double *x2, double *y2); + inline virtual wxShape *GetFrom() + { + return m_from; + } + inline virtual wxShape *GetTo() + { + return m_to; + } + inline virtual int GetAttachmentFrom() + { + return m_attachmentFrom; + } + inline virtual int GetAttachmentTo() + { + return m_attachmentTo; + } + + virtual void SetFrom(wxShape *object); + virtual void SetTo(wxShape *object); + virtual void DrawArrows(wxDC &dc); + + // Finds the x, y points at the two ends of the line. + // This function can be used by e.g. line-routing routines to + // get the actual points on the two node images where the lines will be drawn + // to/from. + void FindLineEndPoints(double *fromX, double *fromY, double *toX, double *toY); + + // Format one region at this position + void DrawRegion(wxDC &dc, wxShapeRegion *region, double x, double y); + + // Get the reference point for a label. Region x and y + // are offsets from this. + // position is 0 (middle), 1 (start), 2 (end) + void GetLabelPosition(int position, double *x, double *y); + + // Can override this to create a different class of label shape + virtual wxLabelShape *OnCreateLabelShape(wxLineShape *parent = NULL, wxShapeRegion *region = NULL, double w = 0.0, double h = 0.0); + + // Straighten verticals and horizontals + virtual void Straighten(); + + // Not implemented + inline void SetMaintainStraightLines(bool flag) + { + m_maintainStraightLines = flag; + } + inline bool GetMaintainStraightLines() const + { + return m_maintainStraightLines; + } + + virtual void SetCanvas(wxShapeCanvas *the_canvas); + + // Make handle control points + void MakeControlPoints(); + void ResetControlPoints(); + + // Make a given number of control points + virtual void MakeLineControlPoints(int n); + virtual wxNode *InsertLineControlPoint(); + virtual bool DeleteLineControlPoint(); + virtual void Initialise(); + inline wxList *GetLineControlPoints() + { + return m_lineControlPoints; + } + + // Remove any child shapes before deleting shape. + virtual void RemoveChildren(); + + // Override dragging behaviour - don't want to be able to drag lines! + void OnDragLeft(bool draw, double x, double y, int keys = 0, int attachment = 0); + void OnBeginDragLeft(double x, double y, int keys = 0, int attachment = 0); + void OnEndDragLeft(double x, double y, int keys = 0, int attachment = 0); + + // Control points ('handles') redirect control to the actual shape, to make it easier + // to override sizing behaviour. + virtual void OnSizingDragLeft(wxControlPoint *pt, bool draw, double x, double y, int keys = 0, int attachment = 0); + virtual void OnSizingBeginDragLeft(wxControlPoint *pt, double x, double y, int keys = 0, int attachment = 0); + virtual void OnSizingEndDragLeft(wxControlPoint *pt, double x, double y, int keys = 0, int attachment = 0); + + // Override select, to create/delete temporary label-moving objects + void Select(bool select = TRUE); + + // Set to spline (TRUE) or line (FALSE) + inline void SetSpline(bool spl) + { + m_isSpline = spl; + } + inline bool IsSpline() const + { + return m_isSpline; + } + + void Unlink(); + void SetAttachments(int from_attach, int to_attach); + inline void SetAttachmentFrom(int attach) + { + m_attachmentFrom = attach; + } + inline void SetAttachmentTo(int attach) + { + m_attachmentTo = attach; + } + + bool HitTest(double x, double y, int *attachment, double *distance); + +#if wxUSE_PROLOGIO + // I/O + virtual void WriteAttributes(wxExpr *clause); + virtual void ReadAttributes(wxExpr *clause); +#endif + + virtual void FindNth(wxShape *image, int *nth, int *no_arcs, bool incoming); + + // Find which position we're talking about at this (x, y). + // Returns ARROW_POSITION_START, ARROW_POSITION_MIDDLE, ARROW_POSITION_END + int FindLinePosition(double x, double y); + + // This is really to distinguish between lines and other images. + // For lines, want to pass drag to canvas, since lines tend to prevent + // dragging on a canvas (they get in the way.) + virtual bool Draggable() const + { + return FALSE; + } + + // Does the copying for this object + void Copy(wxShape ©); + + // Add an arrowhead. + wxArrowHead *AddArrow(WXTYPE type, int end = ARROW_POSITION_END, + double arrowSize = 10.0, double xOffset = 0.0, + const wxString &name = wxEmptyString, + wxPseudoMetaFile *mf = NULL, long arrowId = -1); + + // Add an arrowhead in the position indicated by the reference + // list of arrowheads, which contains all legal arrowheads for this + // line, in the correct order. + // E.g. reference list: a b c d e + // Current line list: a d + // Add c, then line list is: a c d + // If no legal arrowhead position, return FALSE. + // Assume reference list is for one end only, since it potentially defines + // the ordering for any one of the 3 positions. So we don't check + // the reference list for arrowhead position. + bool AddArrowOrdered(wxArrowHead *arrow, wxList &referenceList, int end); + + // Delete arrowhead(s) + void ClearArrowsAtPosition(int end = -1); + bool ClearArrow(const wxString &name); + wxArrowHead *FindArrowHead(int position, const wxString &name); + wxArrowHead *FindArrowHead(long arrowId); + bool DeleteArrowHead(int position, const wxString &name); + bool DeleteArrowHead(long arrowId); + void DrawArrow(wxDC &dc, wxArrowHead *arrow, double xOffset, bool proportionalOffset); + inline void SetIgnoreOffsets(bool ignore) + { + m_ignoreArrowOffsets = ignore; + } + inline wxList &GetArrows() const + { + return (wxList &) m_arcArrows; + } + + // Find horizontal width for drawing a line with + // arrows in minimum space. Assume arrows at + // END only + double FindMinimumWidth(); + + // Set alignment flags. ALIGNMENT NOT IMPLEMENTED. + void SetAlignmentOrientation(bool isEnd, bool isHoriz); + void SetAlignmentType(bool isEnd, int alignType); + bool GetAlignmentOrientation(bool isEnd); + int GetAlignmentType(bool isEnd); + int GetAlignmentStart() const + { + return m_alignmentStart; + } + int GetAlignmentEnd() const + { + return m_alignmentEnd; + } + void SetAlignmentStart(int alignStart) + { + m_alignmentStart = alignStart; + } + void SetAlignmentEnd(int alignEnd) + { + m_alignmentEnd = alignEnd; + } + + // Find next control point in line after the start/end point + // (depending on whether the node object is at start or end) + wxRealPoint *GetNextControlPoint(wxShape *nodeObject); + inline bool IsEnd(wxShape *nodeObject) const + { + return (m_to == nodeObject); + } + +private: + bool m_erasing; // flag to say whether we're erasing or drawing + // this line (really so metafiles can draw a + // blank rectangle) + bool m_ignoreArrowOffsets; // Don't always want to draw arrowhead offsets + // because they may not work on tool palettes (for example) + bool m_isSpline; + bool m_maintainStraightLines; + +protected: + // Temporary list of line segment orientations + // so we know what direction the line is supposed to be dog-legging + // in. The values are integer: 0 for vertical, 1 for horizontal. + wxList m_lineOrientations; + + // Temporary pointers for start, middle and end label editing objects + // (active only when the line is selected) + wxLabelShape *m_labelObjects[3]; + + // These define the segmented line - not to be confused with temporary control + // points which appear when object is selected (although in this case they'll + // probably be the same) + wxList *m_lineControlPoints; + + double m_arrowSpacing; // Separation between adjacent arrows + + wxShape *m_to; + wxShape *m_from; + + int m_attachmentTo; // Attachment point at one end + int m_attachmentFrom; // Attachment point at other end + + // Alignment flags + int m_alignmentStart; + int m_alignmentEnd; + + wxList m_arcArrows; + +}; + +#endif +// _OGL_LINES_H_ diff --git a/include/ogl/linesp.h b/include/ogl/linesp.h new file mode 100644 index 0000000..25518b4 --- /dev/null +++ b/include/ogl/linesp.h @@ -0,0 +1,86 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// linesp.h - Lines private header file +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _OGL_LINESP_H_ +#define _OGL_LINESP_H_ + +class wxLineShape; +class wxLineControlPoint: public wxControlPoint +{ + DECLARE_DYNAMIC_CLASS(wxLineControlPoint) + friend class wxLineShape; +public: + + wxLineControlPoint(wxShapeCanvas *the_canvas = NULL, wxShape *object = NULL, double size = 0.0, + double x = 0.0, double y = 0.0, int the_type = 0); + ~wxLineControlPoint(); + + void OnDraw(wxDC &dc); + void OnDragLeft(bool draw, double x, double y, int keys = 0, int attachment = 0); + void OnBeginDragLeft(double x, double y, int keys = 0, int attachment = 0); + void OnEndDragLeft(double x, double y, int keys = 0, int attachment = 0); + + // Obsolete (left-dragging now moves attachment point to new relative position OR new + // attachment id) +#if 0 + void OnDragRight(bool draw, double x, double y, int keys = 0, int attachment = 0); + void OnBeginDragRight(double x, double y, int keys = 0, int attachment = 0); + void OnEndDragRight(double x, double y, int keys = 0, int attachment = 0); +#endif + +public: + + int m_type; + wxRealPoint *m_point; // Line point + wxRealPoint m_originalPos; + +}; + +/* + * Temporary arc label object + */ + +class wxLabelShape: public wxRectangleShape +{ + DECLARE_DYNAMIC_CLASS(wxLabelShape) + +public: + wxLabelShape(wxLineShape *parent = NULL, wxShapeRegion *region = NULL, double w = 0.0, double h = 0.0); + ~wxLabelShape(); + + void OnDraw(wxDC &dc); + void OnDrawContents(wxDC &dc); + void OnLeftClick(double x, double y, int keys = 0, int attachment = 0); + void OnRightClick(double x, double y, int keys = 0, int attachment = 0); + void OnDragLeft(bool draw, double x, double y, int keys = 0, int attachment = 0); + void OnBeginDragLeft(double x, double y, int keys = 0, int attachment = 0); + void OnEndDragLeft(double x, double y, int keys = 0, int attachment = 0); + bool OnMovePre(double x, double y, double old_x, double old_y, bool display = TRUE); + +public: + wxLineShape *m_lineShape; + wxShapeRegion *m_shapeRegion; + +}; + +/* + * Get the point on the given line (x1, y1) (x2, y2) + * distance 'length' along from the end, + * returned values in x and y + */ + +void GetPointOnLine(double x1, double y1, double x2, double y2, + double length, double *x, double *y); + +#endif +// _OGL_LINESP_H_ + diff --git a/include/ogl/mfutils.h b/include/ogl/mfutils.h new file mode 100644 index 0000000..9e5bdfb --- /dev/null +++ b/include/ogl/mfutils.h @@ -0,0 +1,418 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// mfutils.h - Metafile utilities: reading a placeable metafile independently of Windows. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _MFUTILS_H_ +#define _MFUTILS_H_ + +#include + +#ifndef GetRValue +#define GetRValue(rgb) ((unsigned char)(rgb)) +#define GetGValue(rgb) ((unsigned char)(((int)(rgb)) >> 8)) +#define GetBValue(rgb) ((unsigned char)((rgb)>>16)) +#endif + +/* Metafile Functions */ +// some compilers have them in their include files + +#ifndef META_SETBKCOLOR +#define META_SETBKCOLOR 0x0201 +#endif +#ifndef META_SETBKMODE +#define META_SETBKMODE 0x0102 +#endif +#ifndef META_SETMAPMODE +#define META_SETMAPMODE 0x0103 +#endif +#ifndef META_SETROP2 +#define META_SETROP2 0x0104 +#endif +#ifndef META_SETRELABS +#define META_SETRELABS 0x0105 +#endif +#ifndef META_SETPOLYFILLMODE +#define META_SETPOLYFILLMODE 0x0106 +#endif +#ifndef META_SETSTRETCHBLTMODE +#define META_SETSTRETCHBLTMODE 0x0107 +#endif +#ifndef META_SETTEXTCHAREXTRA +#define META_SETTEXTCHAREXTRA 0x0108 +#endif +#ifndef META_SETTEXTCOLOR +#define META_SETTEXTCOLOR 0x0209 +#endif +#ifndef META_SETTEXTJUSTIFICATION +#define META_SETTEXTJUSTIFICATION 0x020A +#endif +#ifndef META_SETWINDOWORG +#define META_SETWINDOWORG 0x020B +#endif +#ifndef META_SETWINDOWEXT +#define META_SETWINDOWEXT 0x020C +#endif +#ifndef META_SETVIEWPORTORG +#define META_SETVIEWPORTORG 0x020D +#endif +#ifndef META_SETVIEWPORTEXT +#define META_SETVIEWPORTEXT 0x020E +#endif +#ifndef META_OFFSETWINDOWORG +#define META_OFFSETWINDOWORG 0x020F +#endif +#ifndef META_SCALEWINDOWEXT +#define META_SCALEWINDOWEXT 0x0410 +#endif +#ifndef META_OFFSETVIEWPORTORG +#define META_OFFSETVIEWPORTORG 0x0211 +#endif +#ifndef META_SCALEVIEWPORTEXT +#define META_SCALEVIEWPORTEXT 0x0412 +#endif +#ifndef META_LINETO +#define META_LINETO 0x0213 +#endif +#ifndef META_MOVETO +#define META_MOVETO 0x0214 +#endif +#ifndef META_EXCLUDECLIPRECT +#define META_EXCLUDECLIPRECT 0x0415 +#endif +#ifndef META_INTERSECTCLIPRECT +#define META_INTERSECTCLIPRECT 0x0416 +#endif +#ifndef META_ARC +#define META_ARC 0x0817 +#endif +#ifndef META_ELLIPSE +#define META_ELLIPSE 0x0418 +#endif +#ifndef META_FLOODFILL +#define META_FLOODFILL 0x0419 +#endif +#ifndef META_PIE +#define META_PIE 0x081A +#endif +#ifndef META_RECTANGLE +#define META_RECTANGLE 0x041B +#endif +#ifndef META_ROUNDRECT +#define META_ROUNDRECT 0x061C +#endif +#ifndef META_PATBLT +#define META_PATBLT 0x061D +#endif +#ifndef META_SAVEDC +#define META_SAVEDC 0x001E +#endif +#ifndef META_SETPIXEL +#define META_SETPIXEL 0x041F +#endif +#ifndef META_OFFSETCLIPRGN +#define META_OFFSETCLIPRGN 0x0220 +#endif +#ifndef META_TEXTOUT +#define META_TEXTOUT 0x0521 +#endif +#ifndef META_BITBLT +#define META_BITBLT 0x0922 +#endif +#ifndef META_STRETCHBLT +#define META_STRETCHBLT 0x0B23 +#endif +#ifndef META_POLYGON +#define META_POLYGON 0x0324 +#endif +#ifndef META_POLYLINE +#define META_POLYLINE 0x0325 +#endif +#ifndef META_ESCAPE +#define META_ESCAPE 0x0626 +#endif +#ifndef META_RESTOREDC +#define META_RESTOREDC 0x0127 +#endif +#ifndef META_FILLREGION +#define META_FILLREGION 0x0228 +#endif +#ifndef META_FRAMEREGION +#define META_FRAMEREGION 0x0429 +#endif +#ifndef META_INVERTREGION +#define META_INVERTREGION 0x012A +#endif +#ifndef META_PAINTREGION +#define META_PAINTREGION 0x012B +#endif +#ifndef META_SELECTCLIPREGION +#define META_SELECTCLIPREGION 0x012C +#endif +#ifndef META_SELECTOBJECT +#define META_SELECTOBJECT 0x012D +#endif +#ifndef META_SETTEXTALIGN +#define META_SETTEXTALIGN 0x012E +#endif +#ifndef META_DRAWTEXT +#define META_DRAWTEXT 0x062F +#endif + +#ifndef META_CHORD +#define META_CHORD 0x0830 +#endif +#ifndef META_SETMAPPERFLAGS +#define META_SETMAPPERFLAGS 0x0231 +#endif +#ifndef META_EXTTEXTOUT +#define META_EXTTEXTOUT 0x0a32 +#endif +#ifndef META_SETDIBTODEV +#define META_SETDIBTODEV 0x0d33 +#endif +#ifndef META_SELECTPALETTE +#define META_SELECTPALETTE 0x0234 +#endif +#ifndef META_REALIZEPALETTE +#define META_REALIZEPALETTE 0x0035 +#endif +#ifndef META_ANIMATEPALETTE +#define META_ANIMATEPALETTE 0x0436 +#endif +#ifndef META_SETPALENTRIES +#define META_SETPALENTRIES 0x0037 +#endif +#ifndef META_POLYPOLYGON +#define META_POLYPOLYGON 0x0538 +#endif +#ifndef META_RESIZEPALETTE +#define META_RESIZEPALETTE 0x0139 +#endif + +#ifndef META_DIBBITBLT +#define META_DIBBITBLT 0x0940 +#endif +#ifndef META_DIBSTRETCHBLT +#define META_DIBSTRETCHBLT 0x0b41 +#endif +#ifndef META_DIBCREATEPATTERNBRUSH +#define META_DIBCREATEPATTERNBRUSH 0x0142 +#endif +#ifndef META_STRETCHDIB +#define META_STRETCHDIB 0x0f43 +#endif + +#ifndef META_EXTFLOODFILL +#define META_EXTFLOODFILL 0x0548 +#endif + +#ifndef META_RESETDC +#define META_RESETDC 0x014C +#endif +#ifndef META_STARTDOC +#define META_STARTDOC 0x014D +#endif +#ifndef META_STARTPAGE +#define META_STARTPAGE 0x004F +#endif +#ifndef META_ENDPAGE +#define META_ENDPAGE 0x0050 +#endif +#ifndef META_ABORTDOC +#define META_ABORTDOC 0x0052 +#endif +#ifndef META_ENDDOC +#define META_ENDDOC 0x005E +#endif + +#ifndef META_DELETEOBJECT +#define META_DELETEOBJECT 0x01f0 +#endif + +#ifndef META_CREATEPALETTE +#define META_CREATEPALETTE 0x00f7 +#endif +#ifndef META_CREATEBRUSH +#define META_CREATEBRUSH 0x00F8 +#endif +#ifndef META_CREATEPATTERNBRUSH +#define META_CREATEPATTERNBRUSH 0x01F9 +#endif +#ifndef META_CREATEPENINDIRECT +#define META_CREATEPENINDIRECT 0x02FA +#endif +#ifndef META_CREATEFONTINDIRECT +#define META_CREATEFONTINDIRECT 0x02FB +#endif +#ifndef META_CREATEBRUSHINDIRECT +#define META_CREATEBRUSHINDIRECT 0x02FC +#endif +#ifndef META_CREATEBITMAPINDIRECT +#define META_CREATEBITMAPINDIRECT 0x02FD +#endif +#ifndef META_CREATEBITMAP +#define META_CREATEBITMAP 0x06FE +#endif +#ifndef META_CREATEREGION +#define META_CREATEREGION 0x06FF +#endif + +/* Background Modes */ +#ifndef TRANSPARENT +#define TRANSPARENT 1 +#endif +#ifndef OPAQUE +#define OPAQUE 2 +#endif + +/* Pen Styles */ +#ifndef PS_SOLID +#define PS_SOLID 0 +#endif +#ifndef PS_DASH +#define PS_DASH 1 +#endif +#ifndef PS_DOT +#define PS_DOT 2 +#endif +#ifndef PS_DASHDOT +#define PS_DASHDOT 3 +#endif +#ifndef PS_DASHDOTDOT +#define PS_DASHDOTDOT 4 +#endif +#ifndef PS_NULL +#define PS_NULL 5 +#endif +#ifndef PS_INSIDEFRAME +#define PS_INSIDEFRAME 6 +#endif + +/* PitchAndFamily family values (high 4 bits) */ +#ifndef FF_DONTCARE +#define FF_DONTCARE 0x00 +#endif +#ifndef FF_ROMAN +#define FF_ROMAN 0x10 +#endif +#ifndef FF_SWISS +#define FF_SWISS 0x20 +#endif +#ifndef FF_MODERN +#define FF_MODERN 0x30 +#endif +#ifndef FF_SCRIPT +#define FF_SCRIPT 0x40 +#endif +#ifndef FF_DECORATIVE +#define FF_DECORATIVE 0x50 +#endif + +/* Brush Styles */ +#ifndef BS_SOLID +#define BS_SOLID 0 +#endif +#ifndef BS_NULL +#define BS_NULL 1 +#endif +#ifndef BS_HOLLOW +#define BS_HOLLOW BS_NULL +#endif +#ifndef BS_HATCHED +#define BS_HATCHED 2 +#endif +#ifndef BS_PATTERN +#define BS_PATTERN 3 +#endif +#ifndef BS_INDEXED +#define BS_INDEXED 4 +#endif +#ifndef BS_DIBPATTERN +#define BS_DIBPATTERN 5 +#endif + +/* Hatch Styles */ +#ifndef HS_HORIZONTAL +#define HS_HORIZONTAL 0 +#endif +#ifndef HS_VERTICAL +#define HS_VERTICAL 1 +#endif +#ifndef HS_FDIAGONAL +#define HS_FDIAGONAL 2 +#endif +#ifndef HS_BDIAGONAL +#define HS_BDIAGONAL 3 +#endif +#ifndef HS_CROSS +#define HS_CROSS 4 +#endif +#ifndef HS_DIAGCROSS +#define HS_DIAGCROSS 5 +#endif + +class wxMetaRecord: public wxObject +{ +public: + int metaFunction; + long param1; + long param2; + long param3; + long param4; + long param5; + long param6; + long param7; + long param8; + wxChar *stringParam; + wxRealPoint *points; + + wxMetaRecord(int fun) + { + metaFunction = fun; + points = NULL; + stringParam = NULL; + param1 = 0; + } + ~wxMetaRecord(void); +}; + +class wxXMetaFile: public wxObject +{ +public: + double lastX; + double lastY; + bool ok; + + double left; + double top; + double right; + double bottom; + + wxList metaRecords; + wxList gdiObjects; // List of wxMetaRecord objects created with Create..., + // referenced by position in list by SelectObject + wxXMetaFile(const wxChar *file = NULL); + ~wxXMetaFile(void); + + // After this is called, the metafile cannot be used for anything + // since it is now owned by the clipboard. + bool SetClipboard(int width = 0, int height = 0); + + bool Play(wxDC *dc); + inline bool Ok(void) const + { + return ok; + } + bool ReadFile(const wxChar *file); +}; + +#endif +// _MFUTILS_H_ diff --git a/include/ogl/misc.h b/include/ogl/misc.h new file mode 100644 index 0000000..20c0972 --- /dev/null +++ b/include/ogl/misc.h @@ -0,0 +1,109 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// misc.h - Miscellaneous utilities for OGL +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _OGL_MISC_H_ +#define _OGL_MISC_H_ + +// List to use when copying objects; may need to associate elements of new objects +// with elements of old objects, e.g. when copying constraint.s +extern wxList oglObjectCopyMapping; + +/* + * TEXT FORMATTING FUNCTIONS + * + */ + +// Centres the given list of wxShapeTextLine strings in the given box +// (changing the positions in situ). Doesn't actually draw into the DC. +void oglCentreText(wxDC &dc, wxList *text, double m_xpos, double m_ypos, + double width, double height, + int formatMode = FORMAT_CENTRE_HORIZ | FORMAT_CENTRE_VERT); + +// Given a string, returns a list of strings that fit within the given +// width of box. Height is ignored. +wxArrayString *oglFormatText(wxDC &dc, const wxString &text, double width, double height, int formatMode = 0); + +// Centres the list of wxShapeTextLine strings, doesn't clip. +// Doesn't actually draw into the DC. +void oglCentreTextNoClipping(wxDC &dc, wxList *text_list, + double m_xpos, double m_ypos, double width, double height); + +// Gets the maximum width and height of the given list of wxShapeTextLines. +void oglGetCentredTextExtent(wxDC &dc, wxList *text_list, + double m_xpos, double m_ypos, double width, double height, + double *actual_width, double *actual_height); + +// Actually draw the preformatted list of wxShapeTextLines. +void oglDrawFormattedText(wxDC &context, wxList *text_list, + double m_xpos, double m_ypos, double width, double height, + int formatMode = FORMAT_CENTRE_HORIZ | FORMAT_CENTRE_VERT); + +// Give it a list of points, finds the centre. +void oglFindPolylineCentroid(wxList *points, double *x, double *y); + +void oglCheckLineIntersection(double x1, double y1, double x2, double y2, + double x3, double y3, double x4, double y4, + double *ratio1, double *ratio2); + +void oglFindEndForPolyline(double n, double xvec[], double yvec[], + double x1, double y1, double x2, double y2, double *x3, double *y3); + + +void oglFindEndForBox(double width, double height, + double x1, double y1, // Centre of box (possibly) + double x2, double y2, // other end of line + double *x3, double *y3); // End on box edge + +void oglFindEndForCircle(double radius, + double x1, double y1, // Centre of circle + double x2, double y2, // Other end of line + double *x3, double *y3); + +void oglGetArrowPoints(double x1, double y1, double x2, double y2, + double length, double width, + double *tip_x, double *tip_y, + double *side1_x, double *side1_y, + double *side2_x, double *side2_y); + +/* + * Given an ellipse and endpoints of a line, returns the point at which + * the line touches the ellipse in values x4, y4. + * This function assumes that the centre of the ellipse is at x1, y1, and the + * ellipse has a width of a1 and a height of b1. It also assumes you are + * wanting to draw an arc FROM point x2, y2 TOWARDS point x3, y3. + * This function calculates the x,y coordinates of the intersection point of + * the arc with the ellipse. + * Author: Ian Harrison + */ + +void oglDrawArcToEllipse(double x1, double y1, double a1, double b1, double x2, double y2, double x3, double y3, + double *x4, double *y4); + +bool oglRoughlyEqual(double val1, double val2, double tol = 0.00001); + +extern wxFont *g_oglNormalFont; +extern wxPen *g_oglBlackPen; +extern wxPen *g_oglWhiteBackgroundPen; +extern wxPen *g_oglTransparentPen; +extern wxBrush *g_oglWhiteBackgroundBrush; +extern wxPen *g_oglBlackForegroundPen; + +extern wxFont *oglMatchFont(int point_size); + +extern wxString oglColourToHex(const wxColour &colour); +extern wxColour oglHexToColour(const wxString &hex); +extern void oglDecToHex(unsigned int dec, char *buf); +extern unsigned int oglHexToDec(char *buf); + + +#endif +// _OGL_MISC_H_ diff --git a/include/ogl/module.mk b/include/ogl/module.mk new file mode 100644 index 0000000..c5bcf94 --- /dev/null +++ b/include/ogl/module.mk @@ -0,0 +1,32 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/ogl/basic.h \ + include/ogl/bmpshape.h \ + include/ogl/composit.h \ + include/ogl/divided.h \ + include/ogl/drawnp.h \ + include/ogl/linesp.h \ + include/ogl/misc.h \ + include/ogl/ogl.h \ + include/ogl/basicp.h \ + include/ogl/canvas.h \ + include/ogl/constrnt.h \ + include/ogl/drawn.h \ + include/ogl/lines.h \ + include/ogl/mfutils.h \ + include/ogl/ogldiag.h + +EXTRA_DIST += \ + include/ogl/module.mk \ + include/ogl/README + diff --git a/include/ogl/ogl.h b/include/ogl/ogl.h new file mode 100644 index 0000000..e06ff79 --- /dev/null +++ b/include/ogl/ogl.h @@ -0,0 +1,37 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ogl.h - OGL main include +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _OGL_OGL_H_ +#define _OGL_OGL_H_ + +#include "ogl/basic.h" // Basic shapes +#include "ogl/basicp.h" +#include "ogl/lines.h" // Lines and splines +#include "ogl/linesp.h" +#include "ogl/divided.h" // Vertically-divided rectangle +#include "ogl/composit.h" // Composite images +#include "ogl/canvas.h" // wxShapeCanvas for displaying objects +#include "ogl/ogldiag.h" // wxDiagram + +#include "ogl/bmpshape.h" +#include "ogl/constrnt.h" +#include "ogl/drawn.h" +#include "ogl/drawnp.h" +#include "ogl/mfutils.h" +#include "ogl/misc.h" + +// TODO: replace with wxModule implementation +extern void wxOGLInitialize(); +extern void wxOGLCleanUp(); + +#endif +// _OGL_OGL_H_ diff --git a/include/ogl/ogldiag.h b/include/ogl/ogldiag.h new file mode 100644 index 0000000..5824ed6 --- /dev/null +++ b/include/ogl/ogldiag.h @@ -0,0 +1,157 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ogldiag.h - OGL - wxDiagram class +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _OGL_OGLDIAG_H_ +#define _OGL_OGLDIAG_H_ + +#include "ogl/basic.h" + +#if wxUSE_PROLOGIO +#include +#endif + + +class wxDiagram: public wxObject +{ + DECLARE_DYNAMIC_CLASS(wxDiagram) + +public: + + wxDiagram(); + virtual ~wxDiagram(); + + void SetCanvas(wxShapeCanvas *can); + + inline wxShapeCanvas *GetCanvas() const + { + return m_diagramCanvas; + } + + virtual void Redraw(wxDC &dc); + virtual void Clear(wxDC &dc); + virtual void DrawOutline(wxDC &dc, double x1, double y1, double x2, double y2); + + // Add object to end of object list (if addAfter is NULL) + // or just after addAfter. + virtual void AddShape(wxShape *object, wxShape *addAfter = NULL); + + // Add object to front of object list + virtual void InsertShape(wxShape *object); + + void SetSnapToGrid(bool snap); + void SetGridSpacing(double spacing); + inline double GetGridSpacing() const + { + return m_gridSpacing; + } + inline bool GetSnapToGrid() const + { + return m_snapToGrid; + } + void Snap(double *x, double *y); + + inline void SetQuickEditMode(bool qem) + { + m_quickEditMode = qem; + } + inline bool GetQuickEditMode() const + { + return m_quickEditMode; + } + + virtual void RemoveShape(wxShape *object); + virtual void RemoveAllShapes(); + virtual void DeleteAllShapes(); + virtual void ShowAll(bool show); + + // Find a shape by its id + wxShape *FindShape(long id) const; + + inline void SetMouseTolerance(int tol) + { + m_mouseTolerance = tol; + } + inline int GetMouseTolerance() const + { + return m_mouseTolerance; + } + inline wxList *GetShapeList() const + { + return m_shapeList; + } + inline int GetCount() const + { + return m_shapeList->GetCount(); + } + + // Make sure all text that should be centred, is centred. + void RecentreAll(wxDC &dc); + +#if wxUSE_PROLOGIO + virtual bool SaveFile(const wxString &filename); + virtual bool LoadFile(const wxString &filename); + + virtual void ReadNodes(wxExprDatabase &database); + virtual void ReadLines(wxExprDatabase &database); + virtual void ReadContainerGeometry(wxExprDatabase &database); + + // Allow for modifying file + virtual bool OnDatabaseLoad(wxExprDatabase &db); + virtual bool OnDatabaseSave(wxExprDatabase &db); + virtual bool OnShapeSave(wxExprDatabase &db, wxShape &shape, wxExpr &expr); + virtual bool OnShapeLoad(wxExprDatabase &db, wxShape &shape, wxExpr &expr); + virtual bool OnHeaderSave(wxExprDatabase &db, wxExpr &expr); + virtual bool OnHeaderLoad(wxExprDatabase &db, wxExpr &expr); +#endif + +protected: + wxShapeCanvas *m_diagramCanvas; + bool m_quickEditMode; + bool m_snapToGrid; + double m_gridSpacing; + int m_mouseTolerance; + wxList *m_shapeList; +}; + +class wxLineCrossing: public wxObject +{ +public: + wxLineCrossing() + { + m_lineShape1 = NULL; + m_lineShape2 = NULL; + } + wxRealPoint m_pt1; // First line + wxRealPoint m_pt2; + wxRealPoint m_pt3; // Second line + wxRealPoint m_pt4; + wxRealPoint m_intersect; + wxLineShape *m_lineShape1; + wxLineShape *m_lineShape2; +}; + +class wxLineCrossings: public wxObject +{ +public: + wxLineCrossings(); + ~wxLineCrossings(); + + void FindCrossings(wxDiagram &diagram); + void DrawCrossings(wxDiagram &diagram, wxDC &dc); + void ClearCrossings(); + +public: + wxList m_crossings; +}; + +#endif +// _OGL_OGLDIAG_H_ diff --git a/include/parser/keywords.h b/include/parser/keywords.h new file mode 100644 index 0000000..7fe9872 --- /dev/null +++ b/include/parser/keywords.h @@ -0,0 +1,44 @@ +/*------------------------------------------------------------------------- + * + * keywords.h + * lexical token lookup for reserved words in postgres SQL + * + * + * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * $PostgreSQL: pgsql/src/include/parser/keywords.h,v 1.21 2006/03/05 15:58:57 momjian Exp $ + * + *------------------------------------------------------------------------- + */ + +/////////////////////////////////////////////////////////////////////////// +// +// pgAdmin note: This file is based on src/include/parser/keywords.h from +// PostgreSQL, but with the token code entry removed. +// +// This file is under the BSD licence, per PostgreSQL. +/////////////////////////////////////////////////////////////////////////// + +#ifndef KEYWORDS_H +#define KEYWORDS_H + +/* Keyword categories --- should match lists in gram.y */ +#define UNRESERVED_KEYWORD 0 +#define COL_NAME_KEYWORD 1 +#define TYPE_FUNC_NAME_KEYWORD 2 +#define RESERVED_KEYWORD 3 + +typedef struct ScanKeyword +{ + const char *name; /* in lower case */ + int category; /* see codes above */ +} ScanKeyword; + +extern const ScanKeyword *ScanKeywordLookup(const char *text); + +extern const ScanKeyword ScanKeywords[]; +extern const ScanKeyword ScanKeywordsExtra[]; +extern const int NumScanKeywords; +extern const int NumScanKeywordsExtra; +#endif /* KEYWORDS_H */ diff --git a/include/parser/module.mk b/include/parser/module.mk new file mode 100644 index 0000000..eca48e3 --- /dev/null +++ b/include/parser/module.mk @@ -0,0 +1,16 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/parser/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/parser/keywords.h + +EXTRA_DIST += \ + include/parser/module.mk diff --git a/include/pgAdmin3.h b/include/pgAdmin3.h new file mode 100644 index 0000000..761125d --- /dev/null +++ b/include/pgAdmin3.h @@ -0,0 +1,266 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgAdmin3.h - The main application header +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGADMIN3_H +#define PGADMIN3_H + +// wxWindows headers +#include +#include +#include +#include +#include + +#ifdef WIN32 +#include +#endif + +#include "utils/misc.h" +#include +#include "ctl/ctlSQLBox.h" +#include "ctl/ctlListView.h" +#include "ctl/ctlComboBox.h" +#include +#include +#include "dlg/dlgClasses.h" +#include "db/pgConn.h" +#include "db/pgSet.h" +#include "utils/factory.h" + +#include "precomp.h" + +// App headers +#include "utils/sysSettings.h" + +#ifdef __WXMSW__ +#else +#include "config.h" +#undef VERSION +#endif + +// Check the wxWidgets config +#if !wxCHECK_VERSION(2, 8, 0) +#error wxWidgets 2.8.0 or higher is required to compile this version of pgAdmin. +#endif + +#if !wxUSE_UNICODE +#error wxWidgets must be compiled with Unicode support to build pgAdmin. +#endif + +// Supported server minimum and maximum values. +const short SERVER_MIN_VERSION_N = 0x0804; +const wxString SERVER_MIN_VERSION_T = wxT("8.4"); +<<<<<<< HEAD +const short SERVER_MAX_VERSION_N = 0x0C00; +const wxString SERVER_MAX_VERSION_T = wxT("12"); +======= +const short SERVER_MAX_VERSION_N = 0x0906; +const wxString SERVER_MAX_VERSION_T = wxT("9.6"); + +>>>>>>> 216f52a5135db3124268a32c553b812547d4b918 +// Supported Greenplum Database and Greenplum HAWQ minimum and maximum values. +const short GP_MIN_VERSION_N = 0x0802; +const wxString GP_MIN_VERSION_T = wxT("8.2"); +const short GP_MAX_VERSION_N = 0x0803; +const wxString GP_MAX_VERSION_T = wxT("8.3"); + +// The registry file +#ifndef __WXMSW__ +#define REGISTRY_FILE wxT("/etc/postgres-reg.ini") +#endif + +// Some redefines for modern Microsoft compilers +#if defined(_MSC_VER) +#define creat _creat +#define close _close +#define mkdir _mkdir +#define sprintf _sprintf +#define snprintf _snprintf +#define strcat _strcat +#define strdup _strdup +#define stricmp _stricmp +#define strincmp _strincmp +#endif + +extern wxPathList path; // The search path +extern wxString loadPath; // Where the program is loaded from +extern wxString docPath; // Where docs are stored +extern wxString uiPath; // Where ui data is stored +extern wxString i18nPath; // Where i18n data is stored +extern wxString pluginsDir; // The plugins ini file directory +extern wxString settingsIni; // The default settings file + +extern sysSettings *settings; // The settings manager + +extern frmMain *winMain; // The main app window + +extern wxLocale *locale; // Application locale +extern wxArrayInt existingLangs; // Language IDs +extern wxArrayString existingLangNames; // Language Names + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) +class CSSHTunnelThread; +extern CSSHTunnelThread *pgadminTunnelThread; // SSH Tunneling Thread Object +#endif + +// Helper app paths - PG +extern wxString pgBackupExecutable; +extern wxString pgBackupAllExecutable; +extern wxString pgRestoreExecutable; + +// Helper app paths - EDB +extern wxString edbBackupExecutable; +extern wxString edbBackupAllExecutable; +extern wxString edbRestoreExecutable; + +// Helper app paths - Greenplum +extern wxString gpBackupExecutable; +extern wxString gpBackupAllExecutable; +extern wxString gpRestoreExecutable; + +// +// Support for additional functions included in the EnterpriseDB +// version of libpq. These are enable via runtime loading of the +// functions on Windows, and a configure time macro on other +// platforms (EDB_LIBPQ). +// +// Currently, these are only use to support EDB callable statements +// so the debugger can grab OUT/INOUT parameters from EDB stored +// procedures. +// +#ifdef __WXMSW__ +// Dynamically loaded PQgetOutResult +typedef PGresult *(*PQGETOUTRESULT)(PGconn *); +extern PQGETOUTRESULT PQiGetOutResult; +#define PQiGetOutResult (PQiGetOutResult) + +// Dynamically loaded PQprepareOut +typedef PGresult *(*PQPREPAREOUT)(PGconn *, const char *, const char *, int, const Oid *, const int *); +extern PQPREPAREOUT PQiPrepareOut; +#define PQiPrepareOut (PQiPrepareOut) + +// Dynamically loaded PQsendQueryPreparedOut +typedef int (*PQSENDQUERYPREPAREDOUT)(PGconn *, const char *, int, const char *const *, const int *, const int *, int); +extern PQSENDQUERYPREPAREDOUT PQiSendQueryPreparedOut; +#define PQiSendQueryPreparedOut (PQiSendQueryPreparedOut) + +#else +#ifdef EDB_LIBPQ +#define PQiGetOutResult PQgetOutResult +#define PQiPrepareOut PQprepareOut +#define PQiSendQueryPreparedOut PQsendQueryPreparedOut +#endif +#endif + +// Simple hash map used as an ad-hoc data cache +WX_DECLARE_STRING_HASH_MAP(wxString, cacheMap); + +// Class declarations +class pgAdmin3 : public wxApp +{ +public: + virtual bool OnInit(); + virtual int OnExit(); + +#ifdef __WXMAC__ + void MacOpenFile(const wxString &fileName); +#endif + +private: + wxString LocatePath(const wxString &pathToFind, const bool isFile); + wxString GenerateHelpPath(const wxString &file, const wxString ¤t, wxPathList stdPaths, wxPathList dbmsPaths); + bool LoadAllXrc(const wxString dir); + +#ifdef __WXMAC__ + wxString macFileToOpen; +#endif + +protected: + void InitAppPaths(); + void InitXtraPaths(); + void InitHelp(); + void InitLogger(); + void InitNetwork(); + void InitXml(); + +#ifdef __WXMSW__ + void InitLibpq(); +#endif + +}; + +class pgAppearanceFactory +{ +public: + pgAppearanceFactory(); + + void SetIcons(wxDialog *dlg); + void SetIcons(wxTopLevelWindow *dlg); + wxIcon GetSmallIconImage(); + wxIcon GetBigIconImage(); + wxBitmap GetSplashImage() + { + return wxBitmap(splash_image); + }; + wxFont GetSplashTextFont(); + wxColour GetSplashTextColour() + { + return splash_text_colour; + }; + long GetSplashTextOffset() + { + return splash_pos_offset; + }; + wxPoint GetSplashTextPos() + { + return wxPoint(splash_pos_x, splash_pos_y); + }; + wxString GetShortAppName() + { + return short_appname; + }; + wxString GetLongAppName() + { + return long_appname; + }; + wxString GetWebsiteUrl() + { + return website_url; + }; + wxColour GetReportKeyColour() + { + return report_key_colour; + }; + bool GetHideEnterprisedbHelp() + { + return hide_enterprisedb_help; + }; + bool GetHideGreenplumHelp() + { + return hide_greenplum_help; + }; + bool IsBranded() + { + return is_branded; + }; + +private: + wxString long_appname, short_appname, website_url, icon; + wxImage large_icon, small_icon, splash_image; + long splash_font_size, splash_pos_x, splash_pos_y, splash_pos_offset; + wxColor splash_text_colour, report_key_colour; + bool hide_enterprisedb_help, hide_greenplum_help, is_branded; +}; + +extern pgAppearanceFactory *appearanceFactory; + + +#endif // PGADMIN3_H diff --git a/include/pgscript/FlexLexer.h b/include/pgscript/FlexLexer.h new file mode 100644 index 0000000..9535812 --- /dev/null +++ b/include/pgscript/FlexLexer.h @@ -0,0 +1,223 @@ +// -*-C++-*- +// FlexLexer.h -- define interfaces for lexical analyzer classes generated +// by flex + +// Copyright (c) 1993 The Regents of the University of California. +// All rights reserved. +// +// This code is derived from software contributed to Berkeley by +// Kent Williams and Tom Epperly. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: + +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. + +// Neither the name of the University nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. + +// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE. + +// This file defines FlexLexer, an abstract class which specifies the +// external interface provided to flex C++ lexer objects, and yyFlexLexer, +// which defines a particular lexer class. +// +// If you want to create multiple lexer classes, you use the -P flag +// to rename each yyFlexLexer to some other xxFlexLexer. You then +// include in your other sources once per lexer class: +// +// #undef yyFlexLexer +// #define yyFlexLexer xxFlexLexer +// #include +// +// #undef yyFlexLexer +// #define yyFlexLexer zzFlexLexer +// #include +// ... + +#ifndef __FLEX_LEXER_H +// Never included before - need to define base class. +#define __FLEX_LEXER_H + +#include +# ifndef FLEX_STD +# define FLEX_STD std:: +# endif + +extern "C++" +{ + + struct yy_buffer_state; + typedef int yy_state_type; + + class FlexLexer + { + public: + virtual ~FlexLexer() { } + + const char *YYText() + { + return yytext; + } + int YYLeng() + { + return yyleng; + } + + virtual void + yy_switch_to_buffer( struct yy_buffer_state * new_buffer ) = 0; + virtual struct yy_buffer_state * + yy_create_buffer( FLEX_STD istream * s, int size ) = 0; + virtual void yy_delete_buffer( struct yy_buffer_state * b ) = 0; + virtual void yyrestart( FLEX_STD istream * s ) = 0; + + virtual int yylex() = 0; + + // Call yylex with new input/output sources. + int yylex( FLEX_STD istream * new_in, FLEX_STD ostream *new_out = 0 ) + { + switch_streams( new_in, new_out ); + return yylex(); + } + + // Switch to new input/output streams. A nil stream pointer + // indicates "keep the current one". + virtual void switch_streams( FLEX_STD istream *new_in = 0, + FLEX_STD ostream *new_out = 0 ) = 0; + + int lineno() const + { + return yylineno; + } + + int debug() const + { + return yy_flex_debug; + } + void set_debug( int flag ) + { + yy_flex_debug = flag; + } + + protected: + char *yytext; + int yyleng; + int yylineno; // only maintained if you use %option yylineno + int yy_flex_debug; // only has effect with -d or "%option debug" + }; + +} +#endif + +#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce) +// Either this is the first time through (yyFlexLexerOnce not defined), +// or this is a repeated include to define a different flavor of +// yyFlexLexer, as discussed in the flex man page. +#define yyFlexLexerOnce + +extern "C++" +{ + + class yyFlexLexer : public FlexLexer + { + public: + // arg_yyin and arg_yyout default to the cin and cout, but we + // only make that assignment when initializing in yylex(). + yyFlexLexer( FLEX_STD istream *arg_yyin = 0, FLEX_STD ostream *arg_yyout = 0 ); + + virtual ~yyFlexLexer(); + + void yy_switch_to_buffer( struct yy_buffer_state * new_buffer ); + struct yy_buffer_state * yy_create_buffer( FLEX_STD istream * s, int size ); + void yy_delete_buffer( struct yy_buffer_state * b ); + void yyrestart( FLEX_STD istream * s ); + + void yypush_buffer_state( struct yy_buffer_state * new_buffer ); + void yypop_buffer_state(void); + + virtual int yylex(); + virtual void switch_streams( FLEX_STD istream * new_in, FLEX_STD ostream * new_out ); + + protected: + virtual int LexerInput( char *buf, int max_size ); + virtual void LexerOutput( const char *buf, int size ); + virtual void LexerError( const char *msg ); + + void yyunput( int c, char *buf_ptr ); + int yyinput(); + + void yy_load_buffer_state(); + void yy_init_buffer( struct yy_buffer_state * b, FLEX_STD istream * s ); + void yy_flush_buffer( struct yy_buffer_state * b ); + + int yy_start_stack_ptr; + int yy_start_stack_depth; + int *yy_start_stack; + + void yy_push_state( int new_state ); + void yy_pop_state(); + int yy_top_state(); + + yy_state_type yy_get_previous_state(); + yy_state_type yy_try_NUL_trans( yy_state_type current_state ); + int yy_get_next_buffer(); + + FLEX_STD istream *yyin; // input source for default LexerInput + FLEX_STD ostream *yyout; // output sink for default LexerOutput + + // yy_hold_char holds the character lost when yytext is formed. + char yy_hold_char; + + // Number of characters read into yy_ch_buf. + int yy_n_chars; + + // Points to current character in buffer. + char *yy_c_buf_p; + + int yy_init; // whether we need to initialize + int yy_start; // start state number + + // Flag which is used to allow yywrap()'s to do buffer switches + // instead of setting up a fresh yyin. A bit of a hack ... + int yy_did_buffer_switch_on_eof; + + + size_t yy_buffer_stack_top; /**< index of top of stack. */ + size_t yy_buffer_stack_max; /**< capacity of stack. */ + struct yy_buffer_state **yy_buffer_stack; /**< Stack as an array. */ + void yyensure_buffer_stack(void); + + // The following are not always needed, but may be depending + // on use of certain flex features (like REJECT or yymore()). + + yy_state_type yy_last_accepting_state; + char *yy_last_accepting_cpos; + + yy_state_type *yy_state_buf; + yy_state_type *yy_state_ptr; + + char *yy_full_match; + int *yy_full_state; + int yy_full_lp; + + int yy_lp; + int yy_looking_for_trail_begin; + + int yy_more_flag; + int yy_more_len; + int yy_more_offset; + int yy_prev_more_offset; + }; + +} + +#endif diff --git a/include/pgscript/exceptions/module.mk b/include/pgscript/exceptions/module.mk new file mode 100644 index 0000000..0f866e8 --- /dev/null +++ b/include/pgscript/exceptions/module.mk @@ -0,0 +1,24 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/pgscript/exceptions/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/pgscript/exceptions/pgsArithmeticException.h \ + include/pgscript/exceptions/pgsAssertException.h \ + include/pgscript/exceptions/pgsBreakException.h \ + include/pgscript/exceptions/pgsCastException.h \ + include/pgscript/exceptions/pgsContinueException.h \ + include/pgscript/exceptions/pgsException.h \ + include/pgscript/exceptions/pgsInterruptException.h \ + include/pgscript/exceptions/pgsParameterException.h + +EXTRA_DIST += \ + include/pgscript/exceptions/module.mk + diff --git a/include/pgscript/exceptions/pgsArithmeticException.h b/include/pgscript/exceptions/pgsArithmeticException.h new file mode 100644 index 0000000..ca3ddd6 --- /dev/null +++ b/include/pgscript/exceptions/pgsArithmeticException.h @@ -0,0 +1,35 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSARITHMETICEXCEPTION_H_ +#define PGSARITHMETICEXCEPTION_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/exceptions/pgsException.h" + +class pgsArithmeticException : public pgsException +{ + +protected: + + const wxString m_left; + const wxString m_right; + +public: + + pgsArithmeticException(const wxString &left, const wxString &right); + + virtual ~pgsArithmeticException(); + + virtual const wxString message() const; + +}; + +#endif /*PGSARITHMETICEXCEPTION_H_*/ diff --git a/include/pgscript/exceptions/pgsAssertException.h b/include/pgscript/exceptions/pgsAssertException.h new file mode 100644 index 0000000..18832eb --- /dev/null +++ b/include/pgscript/exceptions/pgsAssertException.h @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSASSERTEXCEPTION_H_ +#define PGSASSERTEXCEPTION_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/exceptions/pgsException.h" + +class pgsAssertException : public pgsException +{ + +protected: + + const wxString m_message; + +public: + + pgsAssertException(const wxString &message); + + virtual ~pgsAssertException(); + + virtual const wxString message() const; + +}; + +#endif /*PGSASSERTEXCEPTION_H_*/ diff --git a/include/pgscript/exceptions/pgsBreakException.h b/include/pgscript/exceptions/pgsBreakException.h new file mode 100644 index 0000000..695795d --- /dev/null +++ b/include/pgscript/exceptions/pgsBreakException.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSBREAKEXCEPTION_H_ +#define PGSBREAKEXCEPTION_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/exceptions/pgsException.h" + +class pgsBreakException : public pgsException +{ + +public: + + pgsBreakException(); + + virtual ~pgsBreakException(); + + virtual const wxString message() const; + +}; + +#endif /*PGSBREAKEXCEPTION_H_*/ diff --git a/include/pgscript/exceptions/pgsCastException.h b/include/pgscript/exceptions/pgsCastException.h new file mode 100644 index 0000000..e4a5888 --- /dev/null +++ b/include/pgscript/exceptions/pgsCastException.h @@ -0,0 +1,35 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSCASTEXCEPTION_H_ +#define PGSCASTEXCEPTION_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/exceptions/pgsException.h" + +class pgsCastException : public pgsException +{ + +protected: + + const wxString m_value; + const wxString m_type; + +public: + + pgsCastException(const wxString &value, const wxString &type); + + virtual ~pgsCastException(); + + virtual const wxString message() const; + +}; + +#endif /*PGSCASTEXCEPTION_H_*/ diff --git a/include/pgscript/exceptions/pgsContinueException.h b/include/pgscript/exceptions/pgsContinueException.h new file mode 100644 index 0000000..227c334 --- /dev/null +++ b/include/pgscript/exceptions/pgsContinueException.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSCONTINUEEXCEPTION_H_ +#define PGSCONTINUEEXCEPTION_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/exceptions/pgsException.h" + +class pgsContinueException : public pgsException +{ + +public: + + pgsContinueException(); + + virtual ~pgsContinueException(); + + virtual const wxString message() const; + +}; + +#endif /*PGSCONTINUEEXCEPTION_H_*/ diff --git a/include/pgscript/exceptions/pgsException.h b/include/pgscript/exceptions/pgsException.h new file mode 100644 index 0000000..f67f34c --- /dev/null +++ b/include/pgscript/exceptions/pgsException.h @@ -0,0 +1,31 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSEXCEPTION_H_ +#define PGSEXCEPTION_H_ + +#include "pgscript/pgScript.h" + +class pgsException +{ + +protected: + + pgsException(); + +public: + + virtual ~pgsException(); + + virtual const wxString message() const = 0; + +}; + +#endif /*PGSEXCEPTION_H_*/ diff --git a/include/pgscript/exceptions/pgsInterruptException.h b/include/pgscript/exceptions/pgsInterruptException.h new file mode 100644 index 0000000..e133de2 --- /dev/null +++ b/include/pgscript/exceptions/pgsInterruptException.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSINTERRUPTEXCEPTION_H_ +#define PGSINTERRUPTEXCEPTION_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/exceptions/pgsException.h" + +class pgsInterruptException : public pgsException +{ + +public: + + pgsInterruptException(); + + virtual ~pgsInterruptException(); + + virtual const wxString message() const; + +}; + +#endif /*PGSINTERRUPTEXCEPTION_H_*/ diff --git a/include/pgscript/exceptions/pgsParameterException.h b/include/pgscript/exceptions/pgsParameterException.h new file mode 100644 index 0000000..3faecdb --- /dev/null +++ b/include/pgscript/exceptions/pgsParameterException.h @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSPARAMETEREXCEPTION_H_ +#define PGSPARAMETEREXCEPTION_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/exceptions/pgsException.h" + +class pgsParameterException : public pgsException +{ + +protected: + + const wxString m_message; + +public: + + pgsParameterException(const wxString &message = wxT("unknown")); + + virtual ~pgsParameterException(); + + virtual const wxString message() const; + +}; + +#endif /*PGSPARAMETEREXCEPTION_H_*/ diff --git a/include/pgscript/expressions/module.mk b/include/pgscript/expressions/module.mk new file mode 100644 index 0000000..c66766c --- /dev/null +++ b/include/pgscript/expressions/module.mk @@ -0,0 +1,54 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/pgscript/expressions/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/pgscript/expressions/pgsAnd.h \ + include/pgscript/expressions/pgsAssign.h \ + include/pgscript/expressions/pgsAssignToRecord.h \ + include/pgscript/expressions/pgsCast.h \ + include/pgscript/expressions/pgsColumns.h \ + include/pgscript/expressions/pgsDifferent.h \ + include/pgscript/expressions/pgsEqual.h \ + include/pgscript/expressions/pgsExecute.h \ + include/pgscript/expressions/pgsExpression.h \ + include/pgscript/expressions/pgsExpressions.h \ + include/pgscript/expressions/pgsGenDate.h \ + include/pgscript/expressions/pgsGenDateTime.h \ + include/pgscript/expressions/pgsGenDictionary.h \ + include/pgscript/expressions/pgsGenInt.h \ + include/pgscript/expressions/pgsGenReal.h \ + include/pgscript/expressions/pgsGenReference.h \ + include/pgscript/expressions/pgsGenRegex.h \ + include/pgscript/expressions/pgsGenString.h \ + include/pgscript/expressions/pgsGenTime.h \ + include/pgscript/expressions/pgsGreater.h \ + include/pgscript/expressions/pgsGreaterEqual.h \ + include/pgscript/expressions/pgsIdent.h \ + include/pgscript/expressions/pgsIdentRecord.h \ + include/pgscript/expressions/pgsLines.h \ + include/pgscript/expressions/pgsLower.h \ + include/pgscript/expressions/pgsLowerEqual.h \ + include/pgscript/expressions/pgsMinus.h \ + include/pgscript/expressions/pgsModulo.h \ + include/pgscript/expressions/pgsNegate.h \ + include/pgscript/expressions/pgsNot.h \ + include/pgscript/expressions/pgsOperation.h \ + include/pgscript/expressions/pgsOr.h \ + include/pgscript/expressions/pgsOver.h \ + include/pgscript/expressions/pgsParenthesis.h \ + include/pgscript/expressions/pgsPlus.h \ + include/pgscript/expressions/pgsRemoveLine.h \ + include/pgscript/expressions/pgsTimes.h \ + include/pgscript/expressions/pgsTrim.h + +EXTRA_DIST += \ + include/pgscript/expressions/module.mk + diff --git a/include/pgscript/expressions/pgsAnd.h b/include/pgscript/expressions/pgsAnd.h new file mode 100644 index 0000000..4f76087 --- /dev/null +++ b/include/pgscript/expressions/pgsAnd.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSAND_H_ +#define PGSAND_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsAnd : public pgsOperation +{ + +public: + + pgsAnd(const pgsExpression *left, const pgsExpression *right); + + virtual ~pgsAnd(); + + virtual pgsExpression *clone() const; + + pgsAnd(const pgsAnd &that); + + pgsAnd &operator =(const pgsAnd &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSAND_H_*/ diff --git a/include/pgscript/expressions/pgsAssign.h b/include/pgscript/expressions/pgsAssign.h new file mode 100644 index 0000000..848762d --- /dev/null +++ b/include/pgscript/expressions/pgsAssign.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSASSIGN_H_ +#define PGSASSIGN_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsAssign : public pgsExpression +{ + +protected: + + wxString m_name; + const pgsExpression *m_var; + +public: + + pgsAssign(const wxString &name, const pgsExpression *var); + + virtual ~pgsAssign(); + + pgsAssign(const pgsAssign &that); + + pgsAssign &operator=(const pgsAssign &that); + + virtual pgsExpression *clone() const; + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSASSIGN_H_*/ diff --git a/include/pgscript/expressions/pgsAssignToRecord.h b/include/pgscript/expressions/pgsAssignToRecord.h new file mode 100644 index 0000000..27a7e76 --- /dev/null +++ b/include/pgscript/expressions/pgsAssignToRecord.h @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSASSIGNTORECORD_H_ +#define PGSASSIGNTORECORD_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsAssign.h" + +class pgsAssignToRecord : public pgsAssign +{ + +private: + + const pgsExpression *m_line; + const pgsExpression *m_column; + +public: + + pgsAssignToRecord(const wxString &name, const pgsExpression *line, + const pgsExpression *column, const pgsExpression *var); + + virtual ~pgsAssignToRecord(); + + pgsAssignToRecord(const pgsAssignToRecord &that); + + pgsAssignToRecord &operator=(const pgsAssignToRecord &that); + + virtual pgsExpression *clone() const; + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSASSIGNTORECORD_H_*/ diff --git a/include/pgscript/expressions/pgsCast.h b/include/pgscript/expressions/pgsCast.h new file mode 100644 index 0000000..a2f3903 --- /dev/null +++ b/include/pgscript/expressions/pgsCast.h @@ -0,0 +1,46 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSCAST_H_ +#define PGSCAST_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsCast : public pgsExpression +{ + +private: + + int m_cast_type; + + const pgsExpression *m_var; + +public: + + pgsCast(const int &cast_type, const pgsExpression *var); + + virtual ~pgsCast(); + + virtual pgsExpression *clone() const; + + pgsCast(const pgsCast &that); + + pgsCast &operator=(const pgsCast &that); + +public: + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSCAST_H_*/ diff --git a/include/pgscript/expressions/pgsColumns.h b/include/pgscript/expressions/pgsColumns.h new file mode 100644 index 0000000..40abe3a --- /dev/null +++ b/include/pgscript/expressions/pgsColumns.h @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSCOLUMNS_H_ +#define PGSCOLUMNS_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsColumns : public pgsExpression +{ + +private: + + wxString m_name; + +public: + + pgsColumns(const wxString &name); + + virtual ~pgsColumns(); + + /* pgsColumns(const pgsColumns & that); */ + + /* pgsColumns & operator=(const pgsColumns & that); */ + + virtual pgsExpression *clone() const; + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSCOLUMNS_H_*/ diff --git a/include/pgscript/expressions/pgsDifferent.h b/include/pgscript/expressions/pgsDifferent.h new file mode 100644 index 0000000..4c31e7e --- /dev/null +++ b/include/pgscript/expressions/pgsDifferent.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSDIFFERENT_H_ +#define PGSDIFFERENT_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsDifferent : public pgsOperation +{ + +public: + + pgsDifferent(const pgsExpression *left, const pgsExpression *right); + + virtual ~pgsDifferent(); + + virtual pgsExpression *clone() const; + + pgsDifferent(const pgsDifferent &that); + + pgsDifferent &operator =(const pgsDifferent &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSDIFFERENT_H_*/ diff --git a/include/pgscript/expressions/pgsEqual.h b/include/pgscript/expressions/pgsEqual.h new file mode 100644 index 0000000..30c9211 --- /dev/null +++ b/include/pgscript/expressions/pgsEqual.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSEQUAL_H_ +#define PGSEQUAL_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsEqual : public pgsOperation +{ + +private: + + bool m_case_sensitive; + +public: + + pgsEqual(const pgsExpression *left, const pgsExpression *right, + bool case_sensitive = true); + + virtual ~pgsEqual(); + + virtual pgsExpression *clone() const; + + pgsEqual(const pgsEqual &that); + + pgsEqual &operator =(const pgsEqual &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSEQUAL_H_*/ diff --git a/include/pgscript/expressions/pgsExecute.h b/include/pgscript/expressions/pgsExecute.h new file mode 100644 index 0000000..ec78797 --- /dev/null +++ b/include/pgscript/expressions/pgsExecute.h @@ -0,0 +1,50 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSEXECUTE_H_ +#define PGSEXECUTE_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsOutputStream; +class pgsThread; + +class pgsExecute : public pgsExpression +{ + +private: + + wxString m_query; + + pgsOutputStream *m_cout; + + pgsThread *m_app; + +public: + + pgsExecute(const wxString &query, pgsOutputStream *cout = 0, + pgsThread *app = 0); + + virtual ~pgsExecute(); + + /* pgsExecute(const pgsExecute & that); */ + + pgsExecute &operator=(const pgsExecute &that); + + virtual pgsExpression *clone() const; + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSEXECUTE_H_*/ diff --git a/include/pgscript/expressions/pgsExpression.h b/include/pgscript/expressions/pgsExpression.h new file mode 100644 index 0000000..2663386 --- /dev/null +++ b/include/pgscript/expressions/pgsExpression.h @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSEXPRESSION_H_ +#define PGSEXPRESSION_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/utilities/pgsCopiedPtr.h" + +class pgsProgram; +class pgsVariable; + +WX_DECLARE_STRING_HASH_MAP(pgsCopiedPtr, pgsVarMap); +typedef pgsCopiedPtr pgsOperand; + +class pgsExpression +{ + +protected: + + pgsExpression(); + +public: + + virtual ~pgsExpression(); + + virtual pgsExpression *clone() const = 0; + + /* pgsExpression(const pgsExpression & that); */ + + /* pgsExpression & operator =(const pgsExpression & that); */ + +public: + + virtual wxString value() const = 0; + + virtual pgsOperand eval(pgsVarMap &vars) const = 0; + +}; + +#endif /*PGSEXPRESSION_H_*/ diff --git a/include/pgscript/expressions/pgsExpressions.h b/include/pgscript/expressions/pgsExpressions.h new file mode 100644 index 0000000..06d8a5a --- /dev/null +++ b/include/pgscript/expressions/pgsExpressions.h @@ -0,0 +1,52 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSEXPRESSIONS_H_ +#define PGSEXPRESSIONS_H_ + +#include "pgsAnd.h" +#include "pgsAssign.h" +#include "pgsAssignToRecord.h" +#include "pgsCast.h" +#include "pgsColumns.h" +#include "pgsDifferent.h" +#include "pgsEqual.h" +#include "pgsExecute.h" +#include "pgsExpression.h" +#include "pgsGenDate.h" +#include "pgsGenDateTime.h" +#include "pgsGenDictionary.h" +#include "pgsGenInt.h" +#include "pgsGenReal.h" +#include "pgsGenReference.h" +#include "pgsGenRegex.h" +#include "pgsGenString.h" +#include "pgsGenTime.h" +#include "pgsGreater.h" +#include "pgsGreaterEqual.h" +#include "pgsIdent.h" +#include "pgsIdentRecord.h" +#include "pgsLines.h" +#include "pgsLower.h" +#include "pgsLowerEqual.h" +#include "pgsMinus.h" +#include "pgsModulo.h" +#include "pgsNegate.h" +#include "pgsNot.h" +#include "pgsOperation.h" +#include "pgsOr.h" +#include "pgsOver.h" +#include "pgsParenthesis.h" +#include "pgsPlus.h" +#include "pgsRemoveLine.h" +#include "pgsTimes.h" +#include "pgsTrim.h" + +#endif /*PGSEXPRESSIONS_H_*/ diff --git a/include/pgscript/expressions/pgsGenDate.h b/include/pgscript/expressions/pgsGenDate.h new file mode 100644 index 0000000..6ba20a5 --- /dev/null +++ b/include/pgscript/expressions/pgsGenDate.h @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSGENDATE_H_ +#define PGSGENDATE_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsGenDate : public pgsExpression +{ + +private: + + const pgsExpression *m_min; + const pgsExpression *m_max; + const pgsExpression *m_sequence; + const pgsExpression *m_seed; + +public: + + pgsGenDate(const pgsExpression *min, const pgsExpression *max, + const pgsExpression *sequence, const pgsExpression *seed); + + virtual ~pgsGenDate(); + + virtual pgsExpression *clone() const; + + pgsGenDate(const pgsGenDate &that); + + pgsGenDate &operator =(const pgsGenDate &that); + +public: + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSGENDATE_H_*/ diff --git a/include/pgscript/expressions/pgsGenDateTime.h b/include/pgscript/expressions/pgsGenDateTime.h new file mode 100644 index 0000000..29be538 --- /dev/null +++ b/include/pgscript/expressions/pgsGenDateTime.h @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSGENDATETIME_H_ +#define PGSGENDATETIME_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsGenDateTime : public pgsExpression +{ + +private: + + const pgsExpression *m_min; + const pgsExpression *m_max; + const pgsExpression *m_sequence; + const pgsExpression *m_seed; + +public: + + pgsGenDateTime(const pgsExpression *min, const pgsExpression *max, + const pgsExpression *sequence, const pgsExpression *seed); + + virtual ~pgsGenDateTime(); + + virtual pgsExpression *clone() const; + + pgsGenDateTime(const pgsGenDateTime &that); + + pgsGenDateTime &operator =(const pgsGenDateTime &that); + +public: + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSGENDATETIME_H_*/ diff --git a/include/pgscript/expressions/pgsGenDictionary.h b/include/pgscript/expressions/pgsGenDictionary.h new file mode 100644 index 0000000..fe1936f --- /dev/null +++ b/include/pgscript/expressions/pgsGenDictionary.h @@ -0,0 +1,49 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSGENDICTIONARY_H_ +#define PGSGENDICTIONARY_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsGenDictionary : public pgsExpression +{ + +private: + + const pgsExpression *m_file_path; + const pgsExpression *m_sequence; + const pgsExpression *m_seed; + const pgsExpression *m_wx_conv; + +public: + + pgsGenDictionary(const pgsExpression *file_path, + const pgsExpression *sequence, + const pgsExpression *seed, const pgsExpression *wx_conv); + + virtual ~pgsGenDictionary(); + + virtual pgsExpression *clone() const; + + pgsGenDictionary(const pgsGenDictionary &that); + + pgsGenDictionary &operator =(const pgsGenDictionary &that); + +public: + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSGENDICTIONARY_H_*/ diff --git a/include/pgscript/expressions/pgsGenInt.h b/include/pgscript/expressions/pgsGenInt.h new file mode 100644 index 0000000..915684f --- /dev/null +++ b/include/pgscript/expressions/pgsGenInt.h @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSGENINT_H_ +#define PGSGENINT_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsGenInt : public pgsExpression +{ + +private: + + const pgsExpression *m_min; + const pgsExpression *m_max; + const pgsExpression *m_sequence; + const pgsExpression *m_seed; + +public: + + pgsGenInt(const pgsExpression *min, const pgsExpression *max, + const pgsExpression *sequence, const pgsExpression *seed); + + virtual ~pgsGenInt(); + + virtual pgsExpression *clone() const; + + pgsGenInt(const pgsGenInt &that); + + pgsGenInt &operator =(const pgsGenInt &that); + +public: + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSGENINT_H_*/ diff --git a/include/pgscript/expressions/pgsGenReal.h b/include/pgscript/expressions/pgsGenReal.h new file mode 100644 index 0000000..8bec0f1 --- /dev/null +++ b/include/pgscript/expressions/pgsGenReal.h @@ -0,0 +1,50 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSGENREAL_H_ +#define PGSGENREAL_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsGenReal : public pgsExpression +{ + +private: + + const pgsExpression *m_min; + const pgsExpression *m_max; + const pgsExpression *m_precision; + const pgsExpression *m_sequence; + const pgsExpression *m_seed; + +public: + + pgsGenReal(const pgsExpression *min, const pgsExpression *max, + const pgsExpression *precision, + const pgsExpression *sequence, const pgsExpression *seed); + + virtual ~pgsGenReal(); + + virtual pgsExpression *clone() const; + + pgsGenReal(const pgsGenReal &that); + + pgsGenReal &operator =(const pgsGenReal &that); + +public: + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSGENREAL_H_*/ diff --git a/include/pgscript/expressions/pgsGenReference.h b/include/pgscript/expressions/pgsGenReference.h new file mode 100644 index 0000000..b44eca9 --- /dev/null +++ b/include/pgscript/expressions/pgsGenReference.h @@ -0,0 +1,53 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSGENREFERENCE_H_ +#define PGSGENREFERENCE_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsThread; + +class pgsGenReference : public pgsExpression +{ + +private: + + const pgsExpression *m_table; + const pgsExpression *m_column; + const pgsExpression *m_sequence; + const pgsExpression *m_seed; + + pgsThread *m_app; + +public: + + pgsGenReference(const pgsExpression *table, const pgsExpression *column, + const pgsExpression *sequence, const pgsExpression *seed, + pgsThread *app = 0); + + virtual ~pgsGenReference(); + + virtual pgsExpression *clone() const; + + pgsGenReference(const pgsGenReference &that); + + pgsGenReference &operator =(const pgsGenReference &that); + +public: + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSGENREFERENCE_H_*/ diff --git a/include/pgscript/expressions/pgsGenRegex.h b/include/pgscript/expressions/pgsGenRegex.h new file mode 100644 index 0000000..ec2192d --- /dev/null +++ b/include/pgscript/expressions/pgsGenRegex.h @@ -0,0 +1,45 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSGENREGEX_H_ +#define PGSGENREGEX_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsGenRegex : public pgsExpression +{ + +private: + + const pgsExpression *m_regex; + const pgsExpression *m_seed; + +public: + + pgsGenRegex(const pgsExpression *regex, const pgsExpression *seed); + + virtual ~pgsGenRegex(); + + virtual pgsExpression *clone() const; + + pgsGenRegex(const pgsGenRegex &that); + + pgsGenRegex &operator =(const pgsGenRegex &that); + +public: + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSGENREGEX_H_*/ diff --git a/include/pgscript/expressions/pgsGenString.h b/include/pgscript/expressions/pgsGenString.h new file mode 100644 index 0000000..5307efc --- /dev/null +++ b/include/pgscript/expressions/pgsGenString.h @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSGENSTRING_H_ +#define PGSGENSTRING_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsGenString : public pgsExpression +{ + +private: + + const pgsExpression *m_min; + const pgsExpression *m_max; + const pgsExpression *m_nb_words; + const pgsExpression *m_seed; + +public: + + pgsGenString(const pgsExpression *min, const pgsExpression *max, + const pgsExpression *nb_words, const pgsExpression *seed); + + virtual ~pgsGenString(); + + virtual pgsExpression *clone() const; + + pgsGenString(const pgsGenString &that); + + pgsGenString &operator =(const pgsGenString &that); + +public: + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSGENSTRING_H_*/ diff --git a/include/pgscript/expressions/pgsGenTime.h b/include/pgscript/expressions/pgsGenTime.h new file mode 100644 index 0000000..fab6eca --- /dev/null +++ b/include/pgscript/expressions/pgsGenTime.h @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSGENTIME_H_ +#define PGSGENTIME_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsGenTime : public pgsExpression +{ + +private: + + const pgsExpression *m_min; + const pgsExpression *m_max; + const pgsExpression *m_sequence; + const pgsExpression *m_seed; + +public: + + pgsGenTime(const pgsExpression *min, const pgsExpression *max, + const pgsExpression *sequence, const pgsExpression *seed); + + virtual ~pgsGenTime(); + + virtual pgsExpression *clone() const; + + pgsGenTime(const pgsGenTime &that); + + pgsGenTime &operator =(const pgsGenTime &that); + +public: + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSGENTIME_H_*/ diff --git a/include/pgscript/expressions/pgsGreater.h b/include/pgscript/expressions/pgsGreater.h new file mode 100644 index 0000000..90f8900 --- /dev/null +++ b/include/pgscript/expressions/pgsGreater.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSGREATER_H_ +#define PGSGREATER_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsGreater : public pgsOperation +{ + +public: + + pgsGreater(const pgsExpression *left, const pgsExpression *right); + + virtual ~pgsGreater(); + + virtual pgsExpression *clone() const; + + pgsGreater(const pgsGreater &that); + + pgsGreater &operator =(const pgsGreater &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSGREATER_H_*/ diff --git a/include/pgscript/expressions/pgsGreaterEqual.h b/include/pgscript/expressions/pgsGreaterEqual.h new file mode 100644 index 0000000..ddd6c38 --- /dev/null +++ b/include/pgscript/expressions/pgsGreaterEqual.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSGREATEREQUAL_H_ +#define PGSGREATEREQUAL_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsGreaterEqual : public pgsOperation +{ + +public: + + pgsGreaterEqual(const pgsExpression *left, const pgsExpression *right); + + virtual ~pgsGreaterEqual(); + + virtual pgsExpression *clone() const; + + pgsGreaterEqual(const pgsGreaterEqual &that); + + pgsGreaterEqual &operator =(const pgsGreaterEqual &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSGREATEREQUAL_H_*/ diff --git a/include/pgscript/expressions/pgsIdent.h b/include/pgscript/expressions/pgsIdent.h new file mode 100644 index 0000000..aeb11e2 --- /dev/null +++ b/include/pgscript/expressions/pgsIdent.h @@ -0,0 +1,46 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSIDENT_H_ +#define PGSIDENT_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsIdent : public pgsExpression +{ + +protected: + + wxString m_name; + +public: + + pgsIdent(const wxString &name); + + virtual ~pgsIdent(); + + /* pgsIdent(const pgsIdent & that); */ + + /* pgsIdent & operator=(const pgsIdent & that); */ + + virtual pgsExpression *clone() const; + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +public: + + static const wxString m_now; + +}; + +#endif /*PGSIDENT_H_*/ diff --git a/include/pgscript/expressions/pgsIdentRecord.h b/include/pgscript/expressions/pgsIdentRecord.h new file mode 100644 index 0000000..1257470 --- /dev/null +++ b/include/pgscript/expressions/pgsIdentRecord.h @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSIDENTRECORD_H_ +#define PGSIDENTRECORD_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsIdent.h" + +class pgsIdentRecord : public pgsIdent +{ + +private: + + const pgsExpression *m_line; + const pgsExpression *m_column; + +public: + + pgsIdentRecord(const wxString &name, const pgsExpression *line, + const pgsExpression *column = 0); + + virtual ~pgsIdentRecord(); + + pgsIdentRecord(const pgsIdentRecord &that); + + pgsIdentRecord &operator=(const pgsIdentRecord &that); + + virtual pgsExpression *clone() const; + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSIDENTRECORD_H_*/ diff --git a/include/pgscript/expressions/pgsLines.h b/include/pgscript/expressions/pgsLines.h new file mode 100644 index 0000000..f92eb4f --- /dev/null +++ b/include/pgscript/expressions/pgsLines.h @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSLINES_H_ +#define PGSLINES_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsLines : public pgsExpression +{ + +private: + + wxString m_name; + +public: + + pgsLines(const wxString &name); + + virtual ~pgsLines(); + + /* pgsLines(const pgsLines & that); */ + + /* pgsLines & operator=(const pgsLines & that); */ + + virtual pgsExpression *clone() const; + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSLINES_H_*/ diff --git a/include/pgscript/expressions/pgsLower.h b/include/pgscript/expressions/pgsLower.h new file mode 100644 index 0000000..2aea0cf --- /dev/null +++ b/include/pgscript/expressions/pgsLower.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSLOWER_H_ +#define PGSLOWER_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsLower : public pgsOperation +{ + +public: + + pgsLower(const pgsExpression *left, const pgsExpression *right); + + virtual ~pgsLower(); + + virtual pgsExpression *clone() const; + + pgsLower(const pgsLower &that); + + pgsLower &operator =(const pgsLower &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSLOWER_H_*/ diff --git a/include/pgscript/expressions/pgsLowerEqual.h b/include/pgscript/expressions/pgsLowerEqual.h new file mode 100644 index 0000000..186eec0 --- /dev/null +++ b/include/pgscript/expressions/pgsLowerEqual.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSLOWEREQUAL_H_ +#define PGSLOWEREQUAL_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsLowerEqual : public pgsOperation +{ + +public: + + pgsLowerEqual(const pgsExpression *left, const pgsExpression *right); + + virtual ~pgsLowerEqual(); + + virtual pgsExpression *clone() const; + + pgsLowerEqual(const pgsLowerEqual &that); + + pgsLowerEqual &operator =(const pgsLowerEqual &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSLOWEREQUAL_H_*/ diff --git a/include/pgscript/expressions/pgsMinus.h b/include/pgscript/expressions/pgsMinus.h new file mode 100644 index 0000000..4210c90 --- /dev/null +++ b/include/pgscript/expressions/pgsMinus.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSMINUS_H_ +#define PGSMINUS_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsMinus : public pgsOperation +{ + +public: + + pgsMinus(const pgsExpression *left, const pgsExpression *right); + + virtual ~pgsMinus(); + + virtual pgsExpression *clone() const; + + pgsMinus(const pgsMinus &that); + + pgsMinus &operator =(const pgsMinus &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSMINUS_H_*/ diff --git a/include/pgscript/expressions/pgsModulo.h b/include/pgscript/expressions/pgsModulo.h new file mode 100644 index 0000000..45d8ca7 --- /dev/null +++ b/include/pgscript/expressions/pgsModulo.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSMODULO_H_ +#define PGSMODULO_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsModulo : public pgsOperation +{ + +public: + + pgsModulo(const pgsExpression *left, const pgsExpression *right); + + virtual ~pgsModulo(); + + virtual pgsExpression *clone() const; + + pgsModulo(const pgsModulo &that); + + pgsModulo &operator =(const pgsModulo &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSMODULO_H_*/ diff --git a/include/pgscript/expressions/pgsNegate.h b/include/pgscript/expressions/pgsNegate.h new file mode 100644 index 0000000..7e2db2c --- /dev/null +++ b/include/pgscript/expressions/pgsNegate.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSNEGATE_H_ +#define PGSNEGATE_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsNegate : public pgsOperation +{ + +public: + + pgsNegate(const pgsExpression *left); + + virtual ~pgsNegate(); + + virtual pgsExpression *clone() const; + + pgsNegate(const pgsNegate &that); + + pgsNegate &operator =(const pgsNegate &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSNEGATE_H_*/ diff --git a/include/pgscript/expressions/pgsNot.h b/include/pgscript/expressions/pgsNot.h new file mode 100644 index 0000000..359dc28 --- /dev/null +++ b/include/pgscript/expressions/pgsNot.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSNOT_H_ +#define PGSNOT_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsNot : public pgsOperation +{ + +public: + + pgsNot(const pgsExpression *left); + + virtual ~pgsNot(); + + virtual pgsExpression *clone() const; + + pgsNot(const pgsNot &that); + + pgsNot &operator =(const pgsNot &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSNOT_H_*/ diff --git a/include/pgscript/expressions/pgsOperation.h b/include/pgscript/expressions/pgsOperation.h new file mode 100644 index 0000000..4abe71d --- /dev/null +++ b/include/pgscript/expressions/pgsOperation.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSOPERATION_H_ +#define PGSOPERATION_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsOperation : public pgsExpression +{ + +protected: + + const pgsExpression *m_left; + const pgsExpression *m_right; + +public: + + pgsOperation(const pgsExpression *left, const pgsExpression *right); + + virtual ~pgsOperation(); + + virtual pgsExpression *clone() const = 0; + + pgsOperation(const pgsOperation &that); + + pgsOperation &operator =(const pgsOperation &that); + + virtual wxString value() const = 0; + + virtual pgsOperand eval(pgsVarMap &vars) const = 0; + +}; + +#endif /*PGSOPERATION_H_*/ diff --git a/include/pgscript/expressions/pgsOr.h b/include/pgscript/expressions/pgsOr.h new file mode 100644 index 0000000..b1b7026 --- /dev/null +++ b/include/pgscript/expressions/pgsOr.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSOR_H_ +#define PGSOR_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsOr : public pgsOperation +{ + +public: + + pgsOr(const pgsExpression *left, const pgsExpression *right); + + virtual ~pgsOr(); + + virtual pgsExpression *clone() const; + + pgsOr(const pgsOr &that); + + pgsOr &operator =(const pgsOr &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSOR_H_*/ diff --git a/include/pgscript/expressions/pgsOver.h b/include/pgscript/expressions/pgsOver.h new file mode 100644 index 0000000..0ae9a8f --- /dev/null +++ b/include/pgscript/expressions/pgsOver.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSOVER_H_ +#define PGSOVER_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsOver : public pgsOperation +{ + +public: + + pgsOver(const pgsExpression *left, const pgsExpression *right); + + virtual ~pgsOver(); + + virtual pgsExpression *clone() const; + + pgsOver(const pgsOver &that); + + pgsOver &operator =(const pgsOver &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSOVER_H_*/ diff --git a/include/pgscript/expressions/pgsParenthesis.h b/include/pgscript/expressions/pgsParenthesis.h new file mode 100644 index 0000000..38ae645 --- /dev/null +++ b/include/pgscript/expressions/pgsParenthesis.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSPARENTHESIS_H_ +#define PGSPARENTHESIS_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsParenthesis : public pgsOperation +{ + +public: + + pgsParenthesis(const pgsExpression *left); + + virtual ~pgsParenthesis(); + + virtual pgsExpression *clone() const; + + pgsParenthesis(const pgsParenthesis &that); + + pgsParenthesis &operator =(const pgsParenthesis &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSPARENTHESIS_H_*/ diff --git a/include/pgscript/expressions/pgsPlus.h b/include/pgscript/expressions/pgsPlus.h new file mode 100644 index 0000000..a06ac09 --- /dev/null +++ b/include/pgscript/expressions/pgsPlus.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSPLUS_H_ +#define PGSPLUS_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsPlus : public pgsOperation +{ + +public: + + pgsPlus(const pgsExpression *left, const pgsExpression *right); + + virtual ~pgsPlus(); + + virtual pgsExpression *clone() const; + + pgsPlus(const pgsPlus &that); + + pgsPlus &operator =(const pgsPlus &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSPLUS_H_*/ diff --git a/include/pgscript/expressions/pgsRemoveLine.h b/include/pgscript/expressions/pgsRemoveLine.h new file mode 100644 index 0000000..b133772 --- /dev/null +++ b/include/pgscript/expressions/pgsRemoveLine.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSREMOVELINE_H_ +#define PGSREMOVELINE_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsRemoveLine : public pgsExpression +{ + +private: + + wxString m_rec; + const pgsExpression *m_line; + +public: + + pgsRemoveLine(const wxString &rec, const pgsExpression *line); + + virtual ~pgsRemoveLine(); + + pgsRemoveLine(const pgsRemoveLine &that); + + pgsRemoveLine &operator=(const pgsRemoveLine &that); + + virtual pgsExpression *clone() const; + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSREMOVELINE_H_*/ diff --git a/include/pgscript/expressions/pgsTimes.h b/include/pgscript/expressions/pgsTimes.h new file mode 100644 index 0000000..817690a --- /dev/null +++ b/include/pgscript/expressions/pgsTimes.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSTIMES_H_ +#define PGSTIMES_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsTimes : public pgsOperation +{ + +public: + + pgsTimes(const pgsExpression *left, const pgsExpression *right); + + virtual ~pgsTimes(); + + virtual pgsExpression *clone() const; + + pgsTimes(const pgsTimes &that); + + pgsTimes &operator =(const pgsTimes &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSTIMES_H_*/ diff --git a/include/pgscript/expressions/pgsTrim.h b/include/pgscript/expressions/pgsTrim.h new file mode 100644 index 0000000..79d541e --- /dev/null +++ b/include/pgscript/expressions/pgsTrim.h @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSTRIM_H_ +#define PGSTRIM_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsTrim : public pgsExpression +{ + +private: + + const pgsExpression *m_exp; + +public: + + pgsTrim(const pgsExpression *exp); + + virtual ~pgsTrim(); + + pgsTrim(const pgsTrim &that); + + pgsTrim &operator=(const pgsTrim &that); + + virtual pgsExpression *clone() const; + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSTRIM_H_*/ diff --git a/include/pgscript/generators/module.mk b/include/pgscript/generators/module.mk new file mode 100644 index 0000000..11108c4 --- /dev/null +++ b/include/pgscript/generators/module.mk @@ -0,0 +1,27 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/pgscript/generators/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/pgscript/generators/pgsDateGen.h \ + include/pgscript/generators/pgsDateTimeGen.h \ + include/pgscript/generators/pgsDictionaryGen.h \ + include/pgscript/generators/pgsIntegerGen.h \ + include/pgscript/generators/pgsNumberGen.h \ + include/pgscript/generators/pgsObjectGen.h \ + include/pgscript/generators/pgsRealGen.h \ + include/pgscript/generators/pgsReferenceGen.h \ + include/pgscript/generators/pgsRegexGen.h \ + include/pgscript/generators/pgsStringGen.h \ + include/pgscript/generators/pgsTimeGen.h + +EXTRA_DIST += \ + include/pgscript/generators/module.mk + diff --git a/include/pgscript/generators/pgsDateGen.h b/include/pgscript/generators/pgsDateGen.h new file mode 100644 index 0000000..e88edf3 --- /dev/null +++ b/include/pgscript/generators/pgsDateGen.h @@ -0,0 +1,51 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSDATEGEN_H_ +#define PGSDATEGEN_H_ + +#include "pgscript/pgScript.h" +#include +#include "pgscript/generators/pgsIntegerGen.h" + +class pgsDateGen : public pgsObjectGen +{ +private: + + typedef pgsCopiedPtr pgsRandomizer; // Needs a clone() method + + wxDateTime m_min; + wxDateTime m_max; + int m_range; + + bool m_sequence; + + pgsRandomizer m_randomizer; + +public: + + pgsDateGen(wxDateTime min, wxDateTime max, const bool &sequence, + const long &seed = wxDateTime::GetTimeNow()); + + bool is_sequence() const; + + virtual wxString random(); + + virtual ~pgsDateGen(); + + virtual pgsDateGen *clone(); + + /* pgsDateGen & operator =(const pgsDateGen & that); */ + + /* pgsDateGen(const pgsDateGen & that); */ + +}; + +#endif /*PGSDATEGEN_H_*/ diff --git a/include/pgscript/generators/pgsDateTimeGen.h b/include/pgscript/generators/pgsDateTimeGen.h new file mode 100644 index 0000000..add132b --- /dev/null +++ b/include/pgscript/generators/pgsDateTimeGen.h @@ -0,0 +1,51 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSDATETIMEGEN_H_ +#define PGSDATETIMEGEN_H_ + +#include "pgscript/pgScript.h" +#include +#include "pgscript/generators/pgsIntegerGen.h" + +class pgsDateTimeGen : public pgsObjectGen +{ +private: + + typedef pgsCopiedPtr pgsRandomizer; // Needs a clone() method + + wxDateTime m_min; + wxDateTime m_max; + wxLongLong m_range; + + bool m_sequence; + + pgsRandomizer m_randomizer; + +public: + + pgsDateTimeGen(wxDateTime min, wxDateTime max, const bool &sequence, + const long &seed = wxDateTime::GetTimeNow()); + + bool is_sequence() const; + + virtual wxString random(); + + virtual ~pgsDateTimeGen(); + + virtual pgsDateTimeGen *clone(); + + /* pgsDateTimeGen & operator =(const pgsDateTimeGen & that); */ + + /* pgsDateTimeGen(const pgsDateTimeGen & that); */ + +}; + +#endif /*PGSDATETIMEGEN_H_*/ diff --git a/include/pgscript/generators/pgsDictionaryGen.h b/include/pgscript/generators/pgsDictionaryGen.h new file mode 100644 index 0000000..4dbb72c --- /dev/null +++ b/include/pgscript/generators/pgsDictionaryGen.h @@ -0,0 +1,58 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSDICTIONARYGEN_H_ +#define PGSDICTIONARYGEN_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/generators/pgsIntegerGen.h" + +class pgsDictionaryGen : public pgsObjectGen +{ + +private: + + typedef pgsCopiedPtr pgsRandomizer; // Needs a clone() method + + wxString m_file_path; + wxCSConv m_conv; + + long m_nb_lines; + + pgsRandomizer m_randomizer; + +public: + + pgsDictionaryGen(const wxString &file_path, const bool &sequence = false, + const long &seed = wxDateTime::GetTimeNow(), wxCSConv conv = wxConvLocal); + + virtual wxString random(); + + virtual ~pgsDictionaryGen(); + + virtual pgsDictionaryGen *clone(); + + /* pgsDictionaryGen(const pgsDictionaryGen & that); */ + + const long &nb_lines() const; + +private: + + pgsDictionaryGen &operator =(const pgsDictionaryGen &that); + +private: + + long count_lines(); + + wxString get_line(long line_nb); + +}; + +#endif /*PGSDICTIONARYGEN_H_*/ diff --git a/include/pgscript/generators/pgsIntegerGen.h b/include/pgscript/generators/pgsIntegerGen.h new file mode 100644 index 0000000..c46b339 --- /dev/null +++ b/include/pgscript/generators/pgsIntegerGen.h @@ -0,0 +1,115 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSINTEGERGEN_H_ +#define PGSINTEGERGEN_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/generators/pgsNumberGen.h" +#include "pgscript/generators/pgsObjectGen.h" +#include "pgscript/utilities/pgsCopiedPtr.h" + +class pgsIntegerGen : public pgsObjectGen +{ + +private: + + class pgsSequentialIntGen : public pgsNumberGen + { + + private: + + MAPM m_state; + MAPM m_m; + + static const MAPM arg_a; + static const MAPM arg_c; + + MAPM m_remainder; + + pgsVectorMapm m_buffer; + + public: + + pgsSequentialIntGen(const MAPM &range, const long &seed); + + virtual MAPM random(); + + virtual ~pgsSequentialIntGen(); + + virtual pgsNumberGen *clone(); + + /* pgsSequentialIntGen & operator =(const pgsSequentialIntGen & that); */ + + /* pgsSequentialIntGen(const pgsSequentialIntGen & that); */ + }; + + class pgsNormalIntGen : public pgsNumberGen + { + + private: + + MAPM m_state; + MAPM m_top; + + static const MAPM arg_a; + static const MAPM arg_c; + static const MAPM arg_m; + + public: + + pgsNormalIntGen(const MAPM &range, const long &seed); + + virtual MAPM random(); + + virtual ~pgsNormalIntGen(); + + virtual pgsNumberGen *clone(); + + /* pgsNormalIntGen & operator =(const pgsNormalIntGen & that); */ + + /* pgsNormalIntGen(const pgsNormalIntGen & that); */ + }; + + friend class pgsRealGen; + +private: + + typedef pgsCopiedPtr pgsRandomizer; // Needs a clone() method + + MAPM m_min; + MAPM m_max; + MAPM m_range; + + bool m_sequence; + + pgsRandomizer m_randomizer; + +public: + + pgsIntegerGen(const MAPM &min, const MAPM &max, + const bool &sequence = false, const long &seed = wxDateTime::GetTimeNow()); + + bool is_sequence() const; + + virtual wxString random(); + + long random_long(); + + virtual ~pgsIntegerGen(); + + virtual pgsIntegerGen *clone(); + + /* pgsIntegerGen & operator =(const pgsIntegerGen & that); */ + + /* pgsIntegerGen(const pgsIntegerGen & that); */ +}; + +#endif /*PGSINTEGERGEN_H_*/ diff --git a/include/pgscript/generators/pgsNumberGen.h b/include/pgscript/generators/pgsNumberGen.h new file mode 100644 index 0000000..492e154 --- /dev/null +++ b/include/pgscript/generators/pgsNumberGen.h @@ -0,0 +1,41 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSNUMBERGEN_H_ +#define PGSNUMBERGEN_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/utilities/pgsMapm.h" + +class pgsNumberGen +{ + +protected: + + MAPM m_range; + + static const int BUFFER_SIZE = 1000; + + pgsNumberGen(const MAPM &range); + +public: + + virtual ~pgsNumberGen(); + + virtual MAPM random() = 0; + + virtual pgsNumberGen *clone() = 0; + + /* pgsNumberGen & operator =(const pgsNumberGen & that); */ + + /* pgsNumberGen(const pgsNumberGen & that); */ +}; + +#endif /*PGSNUMBERGEN_H_*/ diff --git a/include/pgscript/generators/pgsObjectGen.h b/include/pgscript/generators/pgsObjectGen.h new file mode 100644 index 0000000..5c2e0ee --- /dev/null +++ b/include/pgscript/generators/pgsObjectGen.h @@ -0,0 +1,40 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSOBJECTGEN_H_ +#define PGSOBJECTGEN_H_ + +#include "pgscript/pgScript.h" +#include + +class pgsObjectGen +{ + +protected: + + long m_seed; + + pgsObjectGen(const long &seed = wxDateTime::GetTimeNow()); + + /* pgsObjectGen & operator =(const pgsObjectGen & that); */ + + /* pgsObjectGen(const pgsObjectGen & that); */ + +public: + + virtual ~pgsObjectGen(); + + virtual wxString random() = 0; + + virtual pgsObjectGen *clone() = 0; + +}; + +#endif /*PGSOBJECTGEN_H_*/ diff --git a/include/pgscript/generators/pgsRealGen.h b/include/pgscript/generators/pgsRealGen.h new file mode 100644 index 0000000..83ec305 --- /dev/null +++ b/include/pgscript/generators/pgsRealGen.h @@ -0,0 +1,56 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef RANDREAL_H_ +#define RANDREAL_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/generators/pgsIntegerGen.h" + +class pgsRealGen : public pgsObjectGen +{ + +private: + + typedef pgsCopiedPtr pgsRandomizer; // Needs a clone() method + + MAPM m_min; + MAPM m_max; + MAPM m_range; + + bool m_sequence; + + MAPM m_pow; + MAPM m_int_max; + + pgsRandomizer m_randomizer; + +public: + + /** + * Builds a new real number generator. Precision cannot be greater that 255. + */ + pgsRealGen(const MAPM &min, const MAPM &max, const UCHAR &precision, + const bool &sequence = false, const long &seed = wxDateTime::GetTimeNow()); + + bool is_sequence() const; + + virtual wxString random(); + + virtual ~pgsRealGen(); + + virtual pgsRealGen *clone(); + + /* pgsRealGen & operator =(const pgsRealGen & that); */ + + /* pgsRealGen(const pgsRealGen & that); */ +}; + +#endif /*RANDREAL_H_*/ diff --git a/include/pgscript/generators/pgsReferenceGen.h b/include/pgscript/generators/pgsReferenceGen.h new file mode 100644 index 0000000..ac786d6 --- /dev/null +++ b/include/pgscript/generators/pgsReferenceGen.h @@ -0,0 +1,53 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSREFERENCEGEN_H_ +#define PGSREFERENCEGEN_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/generators/pgsIntegerGen.h" + +class pgsThread; + +class pgsReferenceGen : public pgsObjectGen +{ + +private: + + typedef pgsCopiedPtr pgsRandomizer; // Needs a clone() method + + pgsThread *m_app; + wxString m_table; + wxString m_column; + bool m_sequence; + + MAPM m_nb_rows; + + pgsRandomizer m_randomizer; + +public: + + pgsReferenceGen(pgsThread *app, const wxString &table, const wxString &column, + const bool &sequence = false, const long &seed = wxDateTime::GetTimeNow()); + + bool is_sequence() const; + + virtual wxString random(); + + virtual ~pgsReferenceGen(); + + virtual pgsReferenceGen *clone(); + + /* pgsReferenceGen & operator =(const pgsReferenceGen & that); */ + + /* pgsReferenceGen(const pgsReferenceGen & that); */ +}; + +#endif /*PGSREFERENCEGEN_H_*/ diff --git a/include/pgscript/generators/pgsRegexGen.h b/include/pgscript/generators/pgsRegexGen.h new file mode 100644 index 0000000..d799236 --- /dev/null +++ b/include/pgscript/generators/pgsRegexGen.h @@ -0,0 +1,102 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSREGEXGEN_H_ +#define PGSREGEXGEN_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/generators/pgsObjectGen.h" +#include "pgscript/generators/pgsStringGen.h" + +WX_DECLARE_OBJARRAY(pgsStringGen, pgsVectorStringGen); + +class pgsRegexGen : public pgsObjectGen +{ + +private: + + class pgsRegex + { + + private: + + pgsVectorChar m_characters; + + long m_first; + long m_second; + + public: + + pgsRegex(const pgsVectorChar &characters, const long &first, + const long &second); + + pgsRegex(); + + ~pgsRegex(); + + pgsRegex *clone(); + + /* pgsRegex & operator =(const pgsRegex & that); */ + + /* pgsRegex(const pgsRegex & that); */ + + void set_characters(const pgsVectorChar &characters); + + void add_character(const wxChar &c); + + void set_first(const long &first); + + void set_second(const long &second); + + const pgsVectorChar &get_characters() const; + + const long &get_first() const; + + const long &get_second() const; + + }; + +private: + + wxString m_regex; + + bool m_valid; + + pgsVectorStringGen m_string_gens; + +public: + + pgsRegexGen(const wxString ®ex, const long &seed = wxDateTime::GetTimeNow()); + + virtual wxString random(); + + virtual ~pgsRegexGen(); + + virtual pgsRegexGen *clone(); + + /* pgsRegexGen & operator =(const pgsRegexGen & that); */ + + /* pgsRegexGen(const pgsRegexGen & that); */ + + const bool &is_valid() const; + + const pgsVectorStringGen &string_gens() const; + + size_t string_gens_size() const; + +private: + + static wxString espace_xml_char(const wxChar &c); + + static wxString char_range(const wxChar &b, const wxChar &c); + +}; + +#endif /*PGSREGEXGEN_H_*/ diff --git a/include/pgscript/generators/pgsStringGen.h b/include/pgscript/generators/pgsStringGen.h new file mode 100644 index 0000000..3f783c1 --- /dev/null +++ b/include/pgscript/generators/pgsStringGen.h @@ -0,0 +1,54 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSSTRINGGEN_H_ +#define PGSSTRINGGEN_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/generators/pgsIntegerGen.h" + +WX_DECLARE_OBJARRAY(wxChar, pgsVectorChar); + +class pgsStringGen : public pgsObjectGen +{ +private: + + typedef pgsCopiedPtr pgsRandomizer; // Needs a clone() method + + pgsRandomizer m_w_size_randomizer; + pgsRandomizer m_letter_randomizer; + + UCHAR m_nb_words; + + pgsVectorChar m_characters; + +public: + + pgsStringGen(USHORT w_size_min, USHORT w_size_max = 0, const UCHAR &nb_words = 1, + const long &seed = wxDateTime::GetTimeNow(), + pgsVectorChar characters = pgsVectorChar()); + + virtual wxString random(); + + virtual ~pgsStringGen(); + + virtual pgsStringGen *clone(); + + /* pgsStringGen & operator =(const pgsStringGen & that); */ + + /* pgsStringGen(const pgsStringGen & that); */ + +private: + + void init_characters(); + +}; + +#endif /*PGSSTRINGGEN_H_*/ diff --git a/include/pgscript/generators/pgsTimeGen.h b/include/pgscript/generators/pgsTimeGen.h new file mode 100644 index 0000000..fe7645b --- /dev/null +++ b/include/pgscript/generators/pgsTimeGen.h @@ -0,0 +1,51 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSTIMEGEN_H_ +#define PGSTIMEGEN_H_ + +#include "pgscript/pgScript.h" +#include +#include "pgscript/generators/pgsIntegerGen.h" + +class pgsTimeGen : public pgsObjectGen +{ +private: + + typedef pgsCopiedPtr pgsRandomizer; // Needs a clone() method + + wxDateTime m_min; + wxDateTime m_max; + wxLongLong m_range; + + bool m_sequence; + + pgsRandomizer m_randomizer; + +public: + + pgsTimeGen(wxDateTime min, wxDateTime max, const bool &sequence, + const long &seed = wxDateTime::GetTimeNow()); + + bool is_sequence() const; + + virtual wxString random(); + + virtual ~pgsTimeGen(); + + virtual pgsTimeGen *clone(); + + /* pgsTimeGen & operator =(const pgsTimeGen & that); */ + + /* pgsTimeGen(const pgsTimeGen & that); */ + +}; + +#endif /*PGSTIMEGEN_H_*/ diff --git a/include/pgscript/location.hh b/include/pgscript/location.hh new file mode 100644 index 0000000..9cacc15 --- /dev/null +++ b/include/pgscript/location.hh @@ -0,0 +1,145 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Locations for Bison parsers in C++ + + Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/** + ** \file location.hh + ** Define the pgscript::location class. + */ + +#ifndef BISON_LOCATION_HH +# define BISON_LOCATION_HH + +# include +# include +# include "position.hh" + +namespace pgscript +{ + + /// Abstract a location. + class location + { + public: + + /// Construct a location. + location () + : begin (), end () + { + } + + + /// Initialization. + inline void initialize (std::string* fn) + { + begin.initialize (fn); + end = begin; + } + + /** \name Line and Column related manipulators + ** \{ */ + public: + /// Reset initial location to final location. + inline void step () + { + begin = end; + } + + /// Extend the current location to the COUNT next columns. + inline void columns (unsigned int count = 1) + { + end += count; + } + + /// Extend the current location to the COUNT next lines. + inline void lines (unsigned int count = 1) + { + end.lines (count); + } + /** \} */ + + + public: + /// Beginning of the located region. + position begin; + /// End of the located region. + position end; + }; + + /// Join two location objects to create a location. + inline const location operator+ (const location& begin, const location& end) + { + location res = begin; + res.end = end.end; + return res; + } + + /// Add two location objects. + inline const location operator+ (const location& begin, unsigned int width) + { + location res = begin; + res.columns (width); + return res; + } + + /// Add and assign a location. + inline location& operator+= (location& res, unsigned int width) + { + res.columns (width); + return res; + } + + /** \brief Intercept output stream redirection. + ** \param ostr the destination output stream + ** \param loc a reference to the location to redirect + ** + ** Avoid duplicate information. + */ + inline std::ostream& operator<< (std::ostream& ostr, const location& loc) + { + position last = loc.end - 1; + ostr << loc.begin; + if (last.filename + && (!loc.begin.filename + || *loc.begin.filename != *last.filename)) + ostr << '-' << last; + else if (loc.begin.line != last.line) + ostr << '-' << last.line << '.' << last.column; + else if (loc.begin.column != last.column) + ostr << '-' << last.column; + return ostr; + } + +} + +#endif // not BISON_LOCATION_HH diff --git a/include/pgscript/module.mk b/include/pgscript/module.mk new file mode 100644 index 0000000..950c670 --- /dev/null +++ b/include/pgscript/module.mk @@ -0,0 +1,29 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/pgscript/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/pgscript/location.hh \ + include/pgscript/parser.tab.hh \ + include/pgscript/position.hh \ + include/pgscript/stack.hh \ + include/pgscript/FlexLexer.h \ + include/pgscript/pgsApplication.h \ + include/pgscript/pgScript.h + +EXTRA_DIST += \ + include/pgscript/module.mk + +include include/pgscript/exceptions/module.mk +include include/pgscript/expressions/module.mk +include include/pgscript/generators/module.mk +include include/pgscript/objects/module.mk +include include/pgscript/statements/module.mk +include include/pgscript/utilities/module.mk diff --git a/include/pgscript/objects/module.mk b/include/pgscript/objects/module.mk new file mode 100644 index 0000000..208271a --- /dev/null +++ b/include/pgscript/objects/module.mk @@ -0,0 +1,22 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/pgscript/objects/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/pgscript/objects/pgsGenerator.h \ + include/pgscript/objects/pgsNumber.h \ + include/pgscript/objects/pgsObjects.h \ + include/pgscript/objects/pgsRecord.h \ + include/pgscript/objects/pgsString.h \ + include/pgscript/objects/pgsVariable.h + +EXTRA_DIST += \ + include/pgscript/objects/module.mk + diff --git a/include/pgscript/objects/pgsGenerator.h b/include/pgscript/objects/pgsGenerator.h new file mode 100644 index 0000000..eb43da1 --- /dev/null +++ b/include/pgscript/objects/pgsGenerator.h @@ -0,0 +1,94 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSGENERATOR_H_ +#define PGSGENERATOR_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/generators/pgsObjectGen.h" +#include "pgscript/objects/pgsVariable.h" +#include "pgscript/utilities/pgsSharedPtr.h" + +class pgsNumber; +class pgsRecord; +class pgsString; + +class pgsGenerator : public pgsVariable +{ + +public: + + virtual pgsOperand pgs_plus(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_minus(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_times(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_over(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_modulo(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_equal(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_different(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_greater(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_lower(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_lower_equal(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_greater_equal(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_not() const; + + virtual bool pgs_is_true() const; + + virtual pgsOperand pgs_almost_equal(const pgsVariable &rhs) const; + +protected: + + typedef pgsSharedPtr pgsRandomizer; + + mutable pgsRandomizer m_randomizer; + +public: + + pgsGenerator(const pgsTypes &generator_type, pgsObjectGen *randomizer); + + virtual ~pgsGenerator(); + + virtual pgsVariable *clone() const; + + /* pgsGenerator(const pgsGenerator & that); */ + + /* pgsGenerator & operator =(const pgsGenerator & that); */ + +public: + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +protected: + + pgsOperand operand() const; + +public: + + virtual pgsNumber number() const; + + virtual pgsRecord record() const; + + virtual pgsString string() const; + +}; + +#endif /*PGSGENERATOR_H_*/ diff --git a/include/pgscript/objects/pgsNumber.h b/include/pgscript/objects/pgsNumber.h new file mode 100644 index 0000000..34131fc --- /dev/null +++ b/include/pgscript/objects/pgsNumber.h @@ -0,0 +1,98 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSNUMBER_H_ +#define PGSNUMBER_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/objects/pgsVariable.h" + +class pgsRecord; +class pgsString; + +/** + * A pgsNumber represents either a number or a string. If the data (a string) + * matches with a regular expression that represents a number then it is a + * number otherwise it is a string. The difference between a string stored + * in this object and a string stored in pgsString is that a string in pgsNumber + * cannot be concatenated with another one in pgsPlus. + */ +class pgsNumber : public pgsVariable +{ + +public: + + virtual pgsOperand pgs_plus(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_minus(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_times(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_over(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_modulo(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_equal(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_different(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_greater(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_lower(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_lower_equal(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_greater_equal(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_not() const; + + virtual bool pgs_is_true() const; + + virtual pgsOperand pgs_almost_equal(const pgsVariable &rhs) const; + +protected: + + wxString m_data; + +public: + + explicit pgsNumber(const wxString &data, const bool &is_real = pgsInt); + + virtual ~pgsNumber(); + + virtual pgsVariable *clone() const; + + pgsNumber(const pgsNumber &that); + + pgsNumber &operator =(const pgsNumber &that); + +public: + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +public: + + bool is_valid() const; + + static pgsTypes num_type(const wxString &num); + +public: + + virtual pgsNumber number() const; + + virtual pgsRecord record() const; + + virtual pgsString string() const; + +}; + +#endif /*PGSNUMBER_H_*/ diff --git a/include/pgscript/objects/pgsObjects.h b/include/pgscript/objects/pgsObjects.h new file mode 100644 index 0000000..2cdd0dc --- /dev/null +++ b/include/pgscript/objects/pgsObjects.h @@ -0,0 +1,20 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSOBJECTS_H_ +#define PGSOBJECTS_H_ + +#include "pgsGenerator.h" +#include "pgsNumber.h" +#include "pgsRecord.h" +#include "pgsString.h" +#include "pgsVariable.h" + +#endif /*PGSOBJECTS_H_*/ diff --git a/include/pgscript/objects/pgsRecord.h b/include/pgscript/objects/pgsRecord.h new file mode 100644 index 0000000..9f4010e --- /dev/null +++ b/include/pgscript/objects/pgsRecord.h @@ -0,0 +1,155 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSRECORD_H_ +#define PGSRECORD_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/objects/pgsVariable.h" + +WX_DECLARE_OBJARRAY(pgsOperand, pgsVectorRecordLine); +WX_DECLARE_OBJARRAY(pgsVectorRecordLine, pgsVectorRecord); + +class pgsNumber; +class pgsString; + +class pgsRecord : public pgsVariable +{ + +public: + + virtual pgsOperand pgs_plus(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_minus(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_times(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_over(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_modulo(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_equal(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_different(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_greater(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_lower(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_lower_equal(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_greater_equal(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_not() const; + + virtual bool pgs_is_true() const; + + virtual pgsOperand pgs_almost_equal(const pgsVariable &rhs) const; + +protected: + + pgsVectorRecord m_record; + + wxArrayString m_columns; + +public: + + explicit pgsRecord(const USHORT &nb_columns); + + virtual ~pgsRecord(); + + virtual pgsVariable *clone() const; + + /* pgsRecord(const pgsRecord & that); */ + + /* pgsRecord & operator =(const pgsRecord & that); */ + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +public: + + USHORT count_lines() const; + + USHORT count_columns() const; + + /** + * Inserts a new element at line.column. If there is something then + * it is deleted before inserting the new element. + */ + bool insert(const USHORT &line, const USHORT &column, + pgsOperand value); + + /** + * Retrieves the element at line.column. If it does not exist it + * returns an empty string. + */ + pgsOperand get(const USHORT &line, + const USHORT &column) const; + + pgsOperand get_line(const USHORT &line) const; + + /** + * Sets the name of a column. If the index is too high or if the name + * already exists then false is returned. + */ + bool set_column_name(const USHORT &column, wxString name); + + /** + * Gets the index of a given column. If this column does not exist then it + * returns count_columns() (the number of columns) which means that this value + * is unusable. So if get_column(...) == count_colums() an error occurred. + */ + USHORT get_column(wxString name) const; + + bool remove_line(const USHORT &line); + +private: + + bool newline(); + + bool valid() const; + +public: + + bool operator==(const pgsRecord &rhs) const; + + bool operator!=(const pgsRecord &rhs) const; + + bool operator<(const pgsRecord &rhs) const; + + bool operator>(const pgsRecord &rhs) const; + + bool operator<=(const pgsRecord &rhs) const; + + bool operator>=(const pgsRecord &rhs) const; + + bool almost_equal(const pgsRecord &rhs) const; + +private: + + bool records_equal(const pgsRecord &lhs, const pgsRecord &rhs, + bool case_sensitive = true) const; + + bool lines_equal(const pgsVectorRecordLine &lhs, + const pgsVectorRecordLine &rhs, bool case_sensitive = true) const; + +public: + + virtual pgsNumber number() const; + + virtual pgsRecord record() const; + + virtual pgsString string() const; + +}; + +#endif /*PGSRECORD_H_*/ diff --git a/include/pgscript/objects/pgsString.h b/include/pgscript/objects/pgsString.h new file mode 100644 index 0000000..fbe4a9c --- /dev/null +++ b/include/pgscript/objects/pgsString.h @@ -0,0 +1,85 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSSTRING_H_ +#define PGSSTRING_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/objects/pgsVariable.h" + +class pgsRecord; +class pgsString; + +class pgsString : public pgsVariable +{ + +public: + + virtual pgsOperand pgs_plus(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_minus(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_times(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_over(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_modulo(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_equal(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_different(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_greater(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_lower(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_lower_equal(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_greater_equal(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_not() const; + + virtual bool pgs_is_true() const; + + virtual pgsOperand pgs_almost_equal(const pgsVariable &rhs) const; + +protected: + + wxString m_data; + +public: + + explicit pgsString(const wxString &data); + + virtual ~pgsString(); + + virtual pgsVariable *clone() const; + + /* pgsString(const pgsString & that); */ + + /* pgsString & operator =(const pgsString & that); */ + +public: + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +public: + + virtual pgsNumber number() const; + + virtual pgsRecord record() const; + + virtual pgsString string() const; + +}; + +#endif /*PGSSTRING_H_*/ diff --git a/include/pgscript/objects/pgsVariable.h b/include/pgscript/objects/pgsVariable.h new file mode 100644 index 0000000..89db031 --- /dev/null +++ b/include/pgscript/objects/pgsVariable.h @@ -0,0 +1,138 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSVARIABLE_H_ +#define PGSVARIABLE_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/utilities/pgsMapm.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsNumber; +class pgsRecord; +class pgsString; + +class pgsVariable : public pgsExpression +{ + + friend pgsOperand operator+(const pgsVariable &lhs, const pgsVariable &rhs); + + friend pgsOperand operator-(const pgsVariable &lhs, const pgsVariable &rhs); + + friend pgsOperand operator*(const pgsVariable &lhs, const pgsVariable &rhs); + + friend pgsOperand operator/(const pgsVariable &lhs, const pgsVariable &rhs); + + friend pgsOperand operator%(const pgsVariable &lhs, const pgsVariable &rhs); + + friend pgsOperand operator==(const pgsVariable &lhs, const pgsVariable &rhs); + + friend pgsOperand operator!=(const pgsVariable &lhs, const pgsVariable &rhs); + + friend pgsOperand operator<(const pgsVariable &lhs, const pgsVariable &rhs); + + friend pgsOperand operator>(const pgsVariable &lhs, const pgsVariable &rhs); + + friend pgsOperand operator<=(const pgsVariable &lhs, const pgsVariable &rhs); + + friend pgsOperand operator>=(const pgsVariable &lhs, const pgsVariable &rhs); + + friend pgsOperand operator!(const pgsVariable &lhs); + + friend pgsOperand operator&=(const pgsVariable &lhs, const pgsVariable &rhs); + +public: + + virtual pgsOperand pgs_plus(const pgsVariable &rhs) const = 0; + + virtual pgsOperand pgs_minus(const pgsVariable &rhs) const = 0; + + virtual pgsOperand pgs_times(const pgsVariable &rhs) const = 0; + + virtual pgsOperand pgs_over(const pgsVariable &rhs) const = 0; + + virtual pgsOperand pgs_modulo(const pgsVariable &rhs) const = 0; + + virtual pgsOperand pgs_equal(const pgsVariable &rhs) const = 0; + + virtual pgsOperand pgs_different(const pgsVariable &rhs) const = 0; + + virtual pgsOperand pgs_greater(const pgsVariable &rhs) const = 0; + + virtual pgsOperand pgs_lower(const pgsVariable &rhs) const = 0; + + virtual pgsOperand pgs_lower_equal(const pgsVariable &rhs) const = 0; + + virtual pgsOperand pgs_greater_equal(const pgsVariable &rhs) const = 0; + + virtual pgsOperand pgs_not() const = 0; + + virtual bool pgs_is_true() const = 0; + + virtual pgsOperand pgs_almost_equal(const pgsVariable &rhs) const = 0; + +public: + + enum pgsTypes + { + pgsTReal, pgsTInt, pgsTString, pgsTRecord + }; + +protected: + + pgsVariable(const pgsTypes &type); + + pgsTypes m_type; + +public: + + virtual ~pgsVariable(); + + virtual pgsVariable *clone() const = 0; + + /* pgsVariable(const pgsVariable & that); */ + + /* pgsVariable & operator =(const pgsVariable & that); */ + + static MAPM num(const pgsOperand &var); + + static MAPM num(const wxString &var); + +public: + + virtual wxString value() const = 0; + + virtual pgsOperand eval(pgsVarMap &vars) const = 0; + +public: + + bool is_number() const; + + bool is_integer() const; + + bool is_real() const; + + bool is_string() const; + + bool is_record() const; + + const pgsTypes &type() const; + +public: + + virtual pgsNumber number() const = 0; + + virtual pgsRecord record() const = 0; + + virtual pgsString string() const = 0; + +}; + +#endif /*PGSVARIABLE_H_*/ diff --git a/include/pgscript/parser.tab.hh b/include/pgscript/parser.tab.hh new file mode 100644 index 0000000..f93f5d4 --- /dev/null +++ b/include/pgscript/parser.tab.hh @@ -0,0 +1,403 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Skeleton interface for Bison LALR(1) parsers in C++ + + Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C++ LALR(1) parser skeleton written by Akim Demaille. */ + +#ifndef PARSER_HEADER_H +# define PARSER_HEADER_H + +#include +#include +#include "stack.hh" + +namespace pgscript +{ + class position; + class location; +} + +/* First part of user declarations. */ +#line 1 "pgscript/pgsParser.yy" + /*** C/C++ Declarations ***/ + +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + +#include "pgscript/pgScript.h" +#include "pgscript/statements/pgsStatements.h" +#include "pgscript/expressions/pgsExpressions.h" +#include "pgscript/objects/pgsObjects.h" +#include "pgscript/utilities/pgsContext.h" + + + +/* Line 35 of lalr1.cc. */ +#line 73 "pgscript/parser.tab.hh" + +#include "location.hh" + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 1 +#endif + +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 0 +#endif + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ +do { \ + if (N) \ + { \ + (Current).begin = (Rhs)[1].begin; \ + (Current).end = (Rhs)[N].end; \ + } \ + else \ + { \ + (Current).begin = (Current).end = (Rhs)[0].end; \ + } \ +} while (false) +#endif + +namespace pgscript +{ + + /// A Bison parser. + class pgsParser + { + public: + /// Symbol semantic values. +#ifndef YYSTYPE + union semantic_type +#line 106 "pgscript/pgsParser.yy" +{ + const wxString * str; + int integer; + pgsExpression * expr; + pgsStmt * stmt; + pgsStmtList * stmt_list; +} +/* Line 35 of lalr1.cc. */ +#line 133 "pgscript/parser.tab.hh" + ; +#else + typedef YYSTYPE semantic_type; +#endif + /// Symbol locations. + typedef location location_type; + /// Tokens. + struct token + { + /* Tokens. */ + enum yytokentype { + PGS_END = 0, + PGS_WHILE = 258, + PGS_BREAK = 259, + PGS_RETURN = 260, + PGS_CONTINUE = 261, + PGS_IF = 262, + PGS_ELSE = 263, + PGS_WAITFOR = 264, + PGS_AS = 265, + PGS_OPEN = 266, + PGS_CLOSE = 267, + PGS_ASSERT = 268, + PGS_PRINT = 269, + PGS_LOG = 270, + PGS_CNT_COLUMNS = 271, + PGS_CNT_LINES = 272, + PGS_TRIM = 273, + PGS_RM_LINE = 274, + PGS_CAST = 275, + PGS_RECORD = 276, + PGS_INTEGER = 277, + PGS_REAL = 278, + PGS_STRING = 279, + PGS_REGEX = 280, + PGS_FILE = 281, + PGS_DATE = 282, + PGS_TIME = 283, + PGS_DATE_TIME = 284, + PGS_REFERENCE = 285, + PGS_LE_OP = 286, + PGS_GE_OP = 287, + PGS_EQ_OP = 288, + PGS_AE_OP = 289, + PGS_NE_OP = 290, + PGS_AND_OP = 291, + PGS_OR_OP = 292, + PGS_NOT_OP = 293, + PGS_UNKNOWN = 294, + PGS_SET_ASSIGN = 295, + PGS_DECLARE_ASSGN = 296, + PGS_ABORT = 297, + PGS_ALTER = 298, + PGS_ANALYZE = 299, + PGS_BEGIN = 300, + PGS_CHECKPOINT = 301, + PGS_CLOSE_ST = 302, + PGS_CLUSTER = 303, + PGS_COMMENT = 304, + PGS_COMMIT = 305, + PGS_COPY = 306, + PGS_CREATE = 307, + PGS_DEALLOCATE = 308, + PGS_DECLARE = 309, + PGS_DELETE = 310, + PGS_DISCARD = 311, + PGS_DROP = 312, + PGS_END_ST = 313, + PGS_EXECUTE = 314, + PGS_EXPLAIN = 315, + PGS_FETCH = 316, + PGS_GRANT = 317, + PGS_INSERT = 318, + PGS_LISTEN = 319, + PGS_LOAD = 320, + PGS_LOCK = 321, + PGS_MOVE = 322, + PGS_NOTIFY = 323, + PGS_PREPARE = 324, + PGS_REASSIGN = 325, + PGS_REINDEX = 326, + PGS_RELEASE = 327, + PGS_RESET = 328, + PGS_REVOKE = 329, + PGS_ROLLBACK = 330, + PGS_SAVEPOINT = 331, + PGS_SELECT = 332, + PGS_SET = 333, + PGS_SHOW = 334, + PGS_START = 335, + PGS_TRUNCATE = 336, + PGS_UNLISTEN = 337, + PGS_UPDATE = 338, + PGS_VACUUM = 339, + PGS_VALUES = 340, + PGS_IDENTIFIER = 341, + PGS_VAL_INT = 342, + PGS_VAL_REAL = 343, + PGS_VAL_STR = 344 + }; + + }; + /// Token type. + typedef token::yytokentype token_type; + + /// Build a parser object. + pgsParser (class pgsDriver & driver_yyarg); + virtual ~pgsParser (); + + /// Parse. + /// \returns 0 iff parsing succeeded. + virtual int parse (); + + /// The current debugging stream. + std::ostream& debug_stream () const; + /// Set the current debugging stream. + void set_debug_stream (std::ostream &); + + /// Type for debugging levels. + typedef int debug_level_type; + /// The current debugging level. + debug_level_type debug_level () const; + /// Set the current debugging level. + void set_debug_level (debug_level_type l); + + private: + /// Report a syntax error. + /// \param loc where the syntax error is found. + /// \param msg a description of the syntax error. + virtual void error (const location_type& loc, const std::string& msg); + + /// Generate an error message. + /// \param state the state where the error occurred. + /// \param tok the look-ahead token. + virtual std::string yysyntax_error_ (int yystate, int tok); + +#if YYDEBUG + /// \brief Report a symbol value on the debug stream. + /// \param yytype The token type. + /// \param yyvaluep Its semantic value. + /// \param yylocationp Its location. + virtual void yy_symbol_value_print_ (int yytype, + const semantic_type* yyvaluep, + const location_type* yylocationp); + /// \brief Report a symbol on the debug stream. + /// \param yytype The token type. + /// \param yyvaluep Its semantic value. + /// \param yylocationp Its location. + virtual void yy_symbol_print_ (int yytype, + const semantic_type* yyvaluep, + const location_type* yylocationp); +#endif /* ! YYDEBUG */ + + + /// State numbers. + typedef int state_type; + /// State stack type. + typedef stack state_stack_type; + /// Semantic value stack type. + typedef stack semantic_stack_type; + /// location stack type. + typedef stack location_stack_type; + + /// The state stack. + state_stack_type yystate_stack_; + /// The semantic value stack. + semantic_stack_type yysemantic_stack_; + /// The location stack. + location_stack_type yylocation_stack_; + + /// Internal symbol numbers. + typedef unsigned char token_number_type; + /* Tables. */ + /// For a state, the index in \a yytable_ of its portion. + static const short int yypact_[]; + static const signed char yypact_ninf_; + + /// For a state, default rule to reduce. + /// Unless\a yytable_ specifies something else to do. + /// Zero means the default is an error. + static const unsigned char yydefact_[]; + + static const short int yypgoto_[]; + static const short int yydefgoto_[]; + + /// What to do in a state. + /// \a yytable_[yypact_[s]]: what to do in state \a s. + /// - if positive, shift that token. + /// - if negative, reduce the rule which number is the opposite. + /// - if zero, do what YYDEFACT says. + static const unsigned short int yytable_[]; + static const signed char yytable_ninf_; + + static const short int yycheck_[]; + + /// For a state, its accessing symbol. + static const unsigned char yystos_[]; + + /// For a rule, its LHS. + static const unsigned char yyr1_[]; + /// For a rule, its RHS length. + static const unsigned char yyr2_[]; + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE + /// For a symbol, its name in clear. + static const char* const yytname_[]; +#endif + +#if YYERROR_VERBOSE + /// Convert the symbol name \a n to a form suitable for a diagnostic. + virtual std::string yytnamerr_ (const char *n); +#endif + +#if YYDEBUG + /// A type to store symbol numbers and -1. + typedef short int rhs_number_type; + /// A `-1'-separated list of the rules' RHS. + static const rhs_number_type yyrhs_[]; + /// For each rule, the index of the first RHS symbol in \a yyrhs_. + static const unsigned short int yyprhs_[]; + /// For each rule, its source line number. + static const unsigned short int yyrline_[]; + /// For each scanner token number, its symbol number. + static const unsigned short int yytoken_number_[]; + /// Report on the debug stream that the rule \a r is going to be reduced. + virtual void yy_reduce_print_ (int r); + /// Print the state stack on the debug stream. + virtual void yystack_print_ (); +#endif + + /// Convert a scanner token number \a t to a symbol number. + token_number_type yytranslate_ (int t); + + /// \brief Reclaim the memory associated to a symbol. + /// \param yymsg Why this token is reclaimed. + /// \param yytype The symbol type. + /// \param yyvaluep Its semantic value. + /// \param yylocationp Its location. + inline void yydestruct_ (const char* yymsg, + int yytype, + semantic_type* yyvaluep, + location_type* yylocationp); + + /// Pop \a n symbols the three stacks. + inline void yypop_ (unsigned int n = 1); + + /* Constants. */ + static const int yyeof_; + /* LAST_ -- Last index in TABLE_. */ + static const int yylast_; + static const int yynnts_; + static const int yyempty_; + static const int yyfinal_; + static const int yyterror_; + static const int yyerrcode_; + static const int yyntokens_; + static const unsigned int yyuser_token_number_max_; + static const token_number_type yyundef_token_; + + /* Debugging. */ + int yydebug_; + std::ostream* yycdebug_; + + + /* User arguments. */ + class pgsDriver & driver; + }; +} + + +#endif /* ! defined PARSER_HEADER_H */ diff --git a/include/pgscript/pgScript.h b/include/pgscript/pgScript.h new file mode 100644 index 0000000..c7eb297 --- /dev/null +++ b/include/pgscript/pgScript.h @@ -0,0 +1,45 @@ +#ifndef PGSNITTEST_H_ +#define PGSNITTEST_H_ + +/*** TYPEDEFS ***/ + +typedef unsigned char UCHAR; +typedef unsigned short int USHORT; + +/*** DEFINES ***/ + +#define pgsReal true +#define pgsInt false + +/*** PGADMIN ***/ + +#include "pgAdmin3.h" + +/*** INCLUDES ***/ + +#if defined(HAVE_CONFIG_H) && defined(PGSCLI) +#include "config.h" +#endif + +#include + +/*** OUTPUT ***/ + +#include +#define pgsOutputStream wxTextOutputStream + +const wxString PGSOUTPGSCRIPT (wxT("[PGSCRIPT ] ")); +const wxString PGSOUTEXCEPTION(wxT("[EXCEPTION] ")); +const wxString PGSOUTQUERY (wxT("[QUERY ] ")); +const wxString PGSOUTWARNING (wxT("[WARNING ] ")); +const wxString PGSOUTERROR (wxT("[ERROR ] ")); + +/*** LOGGING ***/ + +#include "utils/sysLogger.h" + +/*** MEMORY LEAK DETECTION ***/ + +#include "pgscript/utilities/pgsAlloc.h" + +#endif /*PGSNITTEST_H_*/ diff --git a/include/pgscript/pgsApplication.h b/include/pgscript/pgsApplication.h new file mode 100644 index 0000000..7e3e950 --- /dev/null +++ b/include/pgscript/pgsApplication.h @@ -0,0 +1,128 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSAPP_H_ +#define PGSAPP_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/utilities/pgsThread.h" + +class pgsApplication +{ + +public: + + static const int default_port = 5432; + +private: + + /** Global symbol table shared between different runs. */ + pgsVarMap m_vars; + + /** In order to have only one thread at once. */ + wxSemaphore m_mutex; + + /** Protects stream accesses. */ + wxSemaphore m_stream; + + /** Connection to the database. */ + pgConn *m_connection; + + /** Is m_connection provided in the constructor or has it been created. */ + bool m_defined_conn; + + /** Detached thread running a pgScript (parses a file or a string). */ + pgsThread *m_thread; + + /** pgAdmin specific: post an event to this window when m_thread is done. */ + wxWindow *m_caller; + + /** pgAdmin specific: post this event when m_thread is done. */ + long m_event_id; + + /** Location of the last error if there was one. */ + int m_last_error_line; + +public: + + /** Creates an application and creates a connection. */ + pgsApplication(const wxString &host, const wxString &database, + const wxString &user, const wxString &password, int port = default_port); + + /** Creates an application and uses an existing connection. This connection + * is not deleted when the application is deleted. */ + pgsApplication(pgConn *connection); + + /** Deletes custom connection if one was created (first constructor). */ + ~pgsApplication(); + + /** Parses a file by creating a new thread. */ + bool ParseFile(const wxString &file, pgsOutputStream &out, + wxMBConv *conv = &wxConvLocal); + + /** Parses a string by creating a new thread. */ + bool ParseString(const wxString &string, pgsOutputStream &out); + + /** Is m_thread running? */ + bool IsRunning(); + + /** If m_thread is running then wait for it to terminate. */ + void Wait(); + + /** If m_thread is running then delete it. */ + void Terminate(); + + /** Called by m_thread when the thread is finished: IsRunning() becomes + * false and m_event_id is pushed into the event queue if m_caller exists. */ + void Complete(); + + /** Uses a new database connection instead of the previous one. If the + * previous one was user-defined then it is deleted otherwise it is just + * replaced with the new one. */ + void SetConnection(pgConn *conn); + + /** Deletes everything in the symbol table. */ + void ClearSymbols(); + +#if !defined(PGSCLI) + /** Used in pgAdmin integration for sending an event to the caller when the + * thread is finishing its task. */ + void SetCaller(wxWindow *caller, long event_id); +#endif // PGSCLI + + /** Tells whether the database connection is valid. */ + bool IsConnectionValid() const; + + /** Gets a lock on the output stream. */ + void LockOutput(); + + /** Releases the lock on the output stream. */ + void UnlockOutput(); + + /** Was there an error? */ + bool errorOccurred() const; + + /** Get the position (line) of the last error. */ + int errorLine() const; + +private: + + /** Common method for parse_file & parse_string: runs the thread. */ + bool RunThread(); + +private: + + pgsApplication(const pgsApplication &that); + + pgsApplication &operator=(const pgsApplication &that); + +}; + +#endif /*PGSAPP_H_*/ diff --git a/include/pgscript/position.hh b/include/pgscript/position.hh new file mode 100644 index 0000000..2172ab5 --- /dev/null +++ b/include/pgscript/position.hh @@ -0,0 +1,142 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Positions for Bison parsers in C++ + + Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/** + ** \file position.hh + ** Define the pgscript::position class. + */ + +#ifndef BISON_POSITION_HH +# define BISON_POSITION_HH + +# include +# include + +namespace pgscript +{ + /// Abstract a position. + class position + { + public: + + /// Construct a position. + position () + : filename (0), line (1), column (0) + { + } + + + /// Initialization. + inline void initialize (std::string* fn) + { + filename = fn; + line = 1; + column = 0; + } + + /** \name Line and Column related manipulators + ** \{ */ + public: + /// (line related) Advance to the COUNT next lines. + inline void lines (int count = 1) + { + column = 0; + line += count; + } + + /// (column related) Advance to the COUNT next columns. + inline void columns (int count = 1) + { + int leftmost = 0; + int current = column; + if (leftmost <= current + count) + column += count; + else + column = 0; + } + /** \} */ + + public: + /// File name to which this position refers. + std::string* filename; + /// Current line number. + unsigned int line; + /// Current column number. + unsigned int column; + }; + + /// Add and assign a position. + inline const position& + operator+= (position& res, const int width) + { + res.columns (width); + return res; + } + + /// Add two position objects. + inline const position + operator+ (const position& begin, const int width) + { + position res = begin; + return res += width; + } + + /// Add and assign a position. + inline const position& + operator-= (position& res, const int width) + { + return res += -width; + } + + /// Add two position objects. + inline const position + operator- (const position& begin, const int width) + { + return begin + -width; + } + + /** \brief Intercept output stream redirection. + ** \param ostr the destination output stream + ** \param pos a reference to the position to redirect + */ + inline std::ostream& + operator<< (std::ostream& ostr, const position& pos) + { + if (pos.filename) + ostr << *pos.filename << ':'; + return ostr << pos.line << '.' << pos.column; + } + +} +#endif // not BISON_POSITION_HH diff --git a/include/pgscript/stack.hh b/include/pgscript/stack.hh new file mode 100644 index 0000000..5b62318 --- /dev/null +++ b/include/pgscript/stack.hh @@ -0,0 +1,152 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Stack handling for Bison parsers in C++ + + Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +#ifndef BISON_STACK_HH +# define BISON_STACK_HH + +/* The Sun compiler defines _T, which conflicts with wxWidgets, so + we must un-define it if needed. */ +#if defined(__SUNPRO_CC) +#ifdef _T +#undef _T +#define _T_is_defined +#endif +#endif /*__SUNPRO_CC */ + +#include + +namespace pgscript +{ + template > + class stack + { + public: + + // Hide our reversed order. + typedef typename S::reverse_iterator iterator; + typedef typename S::const_reverse_iterator const_iterator; + + stack () : seq_ () + { + } + + stack (unsigned int n) : seq_ (n) + { + } + + inline + T& + operator [] (unsigned int i) + { + return seq_[i]; + } + + inline + const T& + operator [] (unsigned int i) const + { + return seq_[i]; + } + + inline + void + push (const T& t) + { + seq_.push_front (t); + } + + inline + void + pop (unsigned int n = 1) + { + for (; n; --n) + seq_.pop_front (); + } + + inline + unsigned int + height () const + { + return seq_.size (); + } + + inline const_iterator begin () const { return seq_.rbegin (); } + inline const_iterator end () const { return seq_.rend (); } + + private: + + S seq_; + }; + + /// Present a slice of the top of a stack. + template > + class slice + { + public: + + slice (const S& stack, + unsigned int range) : stack_ (stack), + range_ (range) + { + } + + inline + const T& + operator [] (unsigned int i) const + { + return stack_[range_ - i]; + } + + private: + + const S& stack_; + unsigned int range_; + }; +} + +/* Redefine _T if we un-defined it for the Sun compiler. */ +#if defined(__SUNPRO_CC) +#ifdef _T_is_defined +#undef _T_is_defined +/* we need to define it back only if _T already was defined. */ +#if !wxUSE_UNICODE +#define _T(x) x +#else /* Unicode */ +/* use wxCONCAT_HELPER so that x could be expanded if it's a macro */ +#define _T(x) wxCONCAT_HELPER(L, x) +#endif /* ASCII/Unicode */ +#endif /* T_is_defined */ +#endif /*__SUNPRO_CC */ + +#endif // not BISON_STACK_HH diff --git a/include/pgscript/statements/module.mk b/include/pgscript/statements/module.mk new file mode 100644 index 0000000..fc260f8 --- /dev/null +++ b/include/pgscript/statements/module.mk @@ -0,0 +1,28 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/pgscript/statements/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/pgscript/statements/pgsAssertStmt.h \ + include/pgscript/statements/pgsBreakStmt.h \ + include/pgscript/statements/pgsContinueStmt.h \ + include/pgscript/statements/pgsDeclareRecordStmt.h \ + include/pgscript/statements/pgsExpressionStmt.h \ + include/pgscript/statements/pgsIfStmt.h \ + include/pgscript/statements/pgsPrintStmt.h \ + include/pgscript/statements/pgsProgram.h \ + include/pgscript/statements/pgsStatements.h \ + include/pgscript/statements/pgsStmt.h \ + include/pgscript/statements/pgsStmtList.h \ + include/pgscript/statements/pgsWhileStmt.h + +EXTRA_DIST += \ + include/pgscript/statements/module.mk + diff --git a/include/pgscript/statements/pgsAssertStmt.h b/include/pgscript/statements/pgsAssertStmt.h new file mode 100644 index 0000000..bf7d6ca --- /dev/null +++ b/include/pgscript/statements/pgsAssertStmt.h @@ -0,0 +1,40 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSASSERTSTMT_H_ +#define PGSASSERTSTMT_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/statements/pgsStmt.h" + +class pgsAssertStmt : public pgsStmt +{ + +private: + + const pgsExpression *m_cond; + +public: + + pgsAssertStmt(const pgsExpression *cond, pgsThread *app = 0); + + virtual ~pgsAssertStmt(); + + virtual void eval(pgsVarMap &vars) const; + +private: + + pgsAssertStmt(const pgsAssertStmt &that); + + pgsAssertStmt &operator=(const pgsAssertStmt &that); + +}; + +#endif /*PGSASSERTSTMT_H_*/ diff --git a/include/pgscript/statements/pgsBreakStmt.h b/include/pgscript/statements/pgsBreakStmt.h new file mode 100644 index 0000000..73a4921 --- /dev/null +++ b/include/pgscript/statements/pgsBreakStmt.h @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSBREAKSTMT_H_ +#define PGSBREAKSTMT_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/statements/pgsStmt.h" + +class pgsBreakStmt : public pgsStmt +{ + +public: + + pgsBreakStmt(pgsThread *app = 0); + + virtual ~pgsBreakStmt(); + + virtual void eval(pgsVarMap &vars) const; + +private: + + pgsBreakStmt(const pgsBreakStmt &that); + + pgsBreakStmt &operator=(const pgsBreakStmt &that); + +}; + +#endif /*PGSBREAKSTMT_H_*/ diff --git a/include/pgscript/statements/pgsContinueStmt.h b/include/pgscript/statements/pgsContinueStmt.h new file mode 100644 index 0000000..b66aa6b --- /dev/null +++ b/include/pgscript/statements/pgsContinueStmt.h @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSCONTINUESTMT_H_ +#define PGSCONTINUESTMT_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/statements/pgsStmt.h" + +class pgsContinueStmt : public pgsStmt +{ + +public: + + pgsContinueStmt(pgsThread *app = 0); + + virtual ~pgsContinueStmt(); + + virtual void eval(pgsVarMap &vars) const; + +private: + + pgsContinueStmt(const pgsContinueStmt &that); + + pgsContinueStmt &operator=(const pgsContinueStmt &that); + +}; + +#endif /*PGSCONTINUESTMT_H_*/ diff --git a/include/pgscript/statements/pgsDeclareRecordStmt.h b/include/pgscript/statements/pgsDeclareRecordStmt.h new file mode 100644 index 0000000..4284202 --- /dev/null +++ b/include/pgscript/statements/pgsDeclareRecordStmt.h @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSDECLARERECORDSTMT_H_ +#define PGSDECLARERECORDSTMT_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/statements/pgsStmt.h" + +class pgsDeclareRecordStmt : public pgsStmt +{ + +private: + + const wxString m_rec; + const wxArrayString m_columns; + +public: + + pgsDeclareRecordStmt(const wxString &rec, + const wxArrayString &columns, pgsThread *app = 0); + + virtual ~pgsDeclareRecordStmt(); + + virtual void eval(pgsVarMap &vars) const; + +private: + + pgsDeclareRecordStmt(const pgsDeclareRecordStmt &that); + + pgsDeclareRecordStmt &operator=(const pgsDeclareRecordStmt &that); + +}; + +#endif /*PGSDECLARERECORDSTMT_H_*/ diff --git a/include/pgscript/statements/pgsExpressionStmt.h b/include/pgscript/statements/pgsExpressionStmt.h new file mode 100644 index 0000000..5866b66 --- /dev/null +++ b/include/pgscript/statements/pgsExpressionStmt.h @@ -0,0 +1,40 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSEXPRESSIONSTMT_H_ +#define PGSEXPRESSIONSTMT_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/statements/pgsStmt.h" + +class pgsExpressionStmt : public pgsStmt +{ + +private: + + const pgsExpression *m_var; + +public: + + pgsExpressionStmt(const pgsExpression *var, pgsThread *app = 0); + + virtual ~pgsExpressionStmt(); + + virtual void eval(pgsVarMap &vars) const; + +private: + + pgsExpressionStmt(const pgsExpressionStmt &that); + + pgsExpressionStmt &operator=(const pgsExpressionStmt &that); + +}; + +#endif /*PGSEXPRESSIONSTMT_H_*/ diff --git a/include/pgscript/statements/pgsIfStmt.h b/include/pgscript/statements/pgsIfStmt.h new file mode 100644 index 0000000..7193453 --- /dev/null +++ b/include/pgscript/statements/pgsIfStmt.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSIFSTMT_H_ +#define PGSIFSTMT_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/statements/pgsStmt.h" + +class pgsIfStmt : public pgsStmt +{ + +private: + + const pgsExpression *m_cond; + const pgsStmt *m_stmt_list_if; + const pgsStmt *m_stmt_list_else; + +public: + + pgsIfStmt(const pgsExpression *cond, const pgsStmt *stmt_list_if, + const pgsStmt *stmt_list_else, pgsThread *app = 0); + + virtual ~pgsIfStmt(); + + virtual void eval(pgsVarMap &vars) const; + +private: + + pgsIfStmt(const pgsIfStmt &that); + + pgsIfStmt &operator=(const pgsIfStmt &that); + +}; + +#endif /*PGSIFSTMT_H_*/ diff --git a/include/pgscript/statements/pgsPrintStmt.h b/include/pgscript/statements/pgsPrintStmt.h new file mode 100644 index 0000000..431756f --- /dev/null +++ b/include/pgscript/statements/pgsPrintStmt.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSPRINTSTMT_H_ +#define PGSPRINTSTMT_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/statements/pgsStmt.h" + +class pgsPrintStmt : public pgsStmt +{ + +private: + + const pgsExpression *m_var; + + pgsOutputStream &m_cout; + +public: + + pgsPrintStmt(const pgsExpression *var, pgsOutputStream &cout, + pgsThread *app = 0); + + virtual ~pgsPrintStmt(); + + virtual void eval(pgsVarMap &vars) const; + +private: + + pgsPrintStmt(const pgsPrintStmt &that); + + pgsPrintStmt &operator=(const pgsPrintStmt &that); + +}; + +#endif /*PGSPRINTSTMT_H_*/ diff --git a/include/pgscript/statements/pgsProgram.h b/include/pgscript/statements/pgsProgram.h new file mode 100644 index 0000000..9f20b9a --- /dev/null +++ b/include/pgscript/statements/pgsProgram.h @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSPROGRAM_H_ +#define PGSPROGRAM_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/objects/pgsVariable.h" + +#include + +class pgsStmtList; + +class pgsProgram +{ + +private: + + pgsVarMap &m_vars; + +public: + + pgsProgram(pgsVarMap &vars); + + ~pgsProgram(); + + void dump(); + + static void dump(const pgsVarMap &vars); + + void eval(pgsStmtList *stmt_list); + +private: + + pgsProgram(const pgsProgram &that); + + pgsProgram &operator=(const pgsProgram &that); + +}; + +#endif /*PGSPROGRAM_H_*/ diff --git a/include/pgscript/statements/pgsStatements.h b/include/pgscript/statements/pgsStatements.h new file mode 100644 index 0000000..24c4878 --- /dev/null +++ b/include/pgscript/statements/pgsStatements.h @@ -0,0 +1,26 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSSTATEMENTS_H_ +#define PGSSTATEMENTS_H_ + +#include "pgsAssertStmt.h" +#include "pgsBreakStmt.h" +#include "pgsContinueStmt.h" +#include "pgsDeclareRecordStmt.h" +#include "pgsExpressionStmt.h" +#include "pgsIfStmt.h" +#include "pgsPrintStmt.h" +#include "pgsProgram.h" +#include "pgsStmt.h" +#include "pgsStmtList.h" +#include "pgsWhileStmt.h" + +#endif /*PGSSTATEMENTS_H_*/ diff --git a/include/pgscript/statements/pgsStmt.h b/include/pgscript/statements/pgsStmt.h new file mode 100644 index 0000000..5522748 --- /dev/null +++ b/include/pgscript/statements/pgsStmt.h @@ -0,0 +1,50 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSSTMT_H_ +#define PGSSTMT_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/objects/pgsVariable.h" + +class pgsThread; + +class pgsStmt +{ + +private: + + unsigned int m_line; + +protected: + + pgsThread *m_app; + +public: + + pgsStmt(pgsThread *app = 0); + + virtual ~pgsStmt(); + + void set_position(int line); + + int line() const; + + virtual void eval(pgsVarMap &vars) const = 0; + +private: + + pgsStmt(const pgsStmt &that); + + pgsStmt &operator=(const pgsStmt &that); + +}; + +#endif /*PGSSTMT_H_*/ diff --git a/include/pgscript/statements/pgsStmtList.h b/include/pgscript/statements/pgsStmtList.h new file mode 100644 index 0000000..a697710 --- /dev/null +++ b/include/pgscript/statements/pgsStmtList.h @@ -0,0 +1,52 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSSTMTLIST_H_ +#define PGSSTMTLIST_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/statements/pgsStmt.h" + +WX_DECLARE_LIST(pgsStmt, pgsListStmt); + +class pgsStmtList : public pgsStmt +{ + +private: + + pgsListStmt m_stmt_list; + + pgsOutputStream &m_cout; + +public: + + static bool m_exception_thrown; + +public: + + pgsStmtList(pgsOutputStream &cout, pgsThread *app = 0); + + virtual ~pgsStmtList(); + + virtual void eval(pgsVarMap &vars) const; + + void insert_front(pgsStmt *stmt); + + void insert_back(pgsStmt *stmt); + +private: + + pgsStmtList(const pgsStmtList &that); + + pgsStmtList &operator=(const pgsStmtList &that); + +}; + +#endif /*PGSSTMTLIST_H_*/ diff --git a/include/pgscript/statements/pgsWhileStmt.h b/include/pgscript/statements/pgsWhileStmt.h new file mode 100644 index 0000000..f1f6e12 --- /dev/null +++ b/include/pgscript/statements/pgsWhileStmt.h @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSWHILESTMT_H_ +#define PGSWHILESTMT_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/statements/pgsStmt.h" + +class pgsWhileStmt : public pgsStmt +{ + +private: + + const pgsExpression *m_cond; + const pgsStmt *m_stmt_list; + +public: + + pgsWhileStmt(const pgsExpression *cond, const pgsStmt *stmt_list, + pgsThread *app = 0); + + virtual ~pgsWhileStmt(); + + virtual void eval(pgsVarMap &vars) const; + +private: + + pgsWhileStmt(const pgsWhileStmt &that); + + pgsWhileStmt &operator=(const pgsWhileStmt &that); + +}; + +#endif /*PGSWHILESTMT_H_*/ diff --git a/include/pgscript/utilities/mapm-lib/license.txt b/include/pgscript/utilities/mapm-lib/license.txt new file mode 100644 index 0000000..a441a7a --- /dev/null +++ b/include/pgscript/utilities/mapm-lib/license.txt @@ -0,0 +1,13 @@ + +/* + * THIS FILE HAS BEEN MODIFIED FROM THE OFFICIAL MAPM DISTRIBUTION + * BY 'Mickael Deloison/pgScript' on 2008/02/26. + * + * THIS FILE IS ORIGINALLY FROM MAPM VERSION 4.9.5. + * + * .... OPTIONAL: a brief description of file changes here .... + */ + +... start of MAPM original file ... + + diff --git a/include/pgscript/utilities/mapm-lib/m_apm.h b/include/pgscript/utilities/mapm-lib/m_apm.h new file mode 100644 index 0000000..8690080 --- /dev/null +++ b/include/pgscript/utilities/mapm-lib/m_apm.h @@ -0,0 +1,767 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + + +/* + * M_APM - m_apm.h + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * This is the header file that the user will include. + * + */ + +#undef sprintf +#undef strcat + +#ifndef M__APM__INCLUDED +#define M__APM__INCLUDED + +#ifdef __cplusplus +/* Comment this line out if you've compiled the library as C++. */ +#define APM_CONVERT_FROM_C +#endif + +#ifdef APM_CONVERT_FROM_C +extern "C" { +#endif + +typedef unsigned char UCHAR; + +typedef struct +{ + UCHAR *m_apm_data; + long m_apm_id; + int m_apm_refcount; /* <- used only by C++ MAPM class */ + int m_apm_malloclength; + int m_apm_datalength; + int m_apm_exponent; + int m_apm_sign; +} M_APM_struct; + +typedef M_APM_struct *M_APM; + + +#define MAPM_LIB_VERSION \ + "MAPM Library Version 4.9.5 Copyright (C) 1999-2007, Michael C. Ring" +#define MAPM_LIB_SHORT_VERSION "4.9.5" + + +/* + * convienient predefined constants + */ + +extern M_APM MM_Zero; +extern M_APM MM_One; +extern M_APM MM_Two; +extern M_APM MM_Three; +extern M_APM MM_Four; +extern M_APM MM_Five; +extern M_APM MM_Ten; + +extern M_APM MM_PI; +extern M_APM MM_HALF_PI; +extern M_APM MM_2_PI; +extern M_APM MM_E; + +extern M_APM MM_LOG_E_BASE_10; +extern M_APM MM_LOG_10_BASE_E; +extern M_APM MM_LOG_2_BASE_E; +extern M_APM MM_LOG_3_BASE_E; + + +/* + * function prototypes + */ + +extern M_APM m_apm_init(void); +extern void m_apm_free(M_APM); +extern void m_apm_free_all_mem(void); +extern void m_apm_trim_mem_usage(void); +extern char *m_apm_lib_version(char *); +extern char *m_apm_lib_short_version(char *); + +extern void m_apm_set_string(M_APM, const char *); +extern void m_apm_set_double(M_APM, double); +extern void m_apm_set_long(M_APM, long); + +extern void m_apm_to_string(char *, int, M_APM); +extern void m_apm_to_fixpt_string(char *, int, M_APM); +extern void m_apm_to_fixpt_stringex(char *, int, M_APM, char, char, int); +extern char *m_apm_to_fixpt_stringexp(int, M_APM, char, char, int); +extern void m_apm_to_integer_string(char *, M_APM); + +extern void m_apm_absolute_value(M_APM, M_APM); +extern void m_apm_negate(M_APM, M_APM); +extern void m_apm_copy(M_APM, M_APM); +extern void m_apm_round(M_APM, int, M_APM); +extern int m_apm_compare(M_APM, M_APM); +extern int m_apm_sign(M_APM); +extern int m_apm_exponent(M_APM); +extern int m_apm_significant_digits(M_APM); +extern int m_apm_is_integer(M_APM); +extern int m_apm_is_even(M_APM); +extern int m_apm_is_odd(M_APM); + +extern void m_apm_gcd(M_APM, M_APM, M_APM); +extern void m_apm_lcm(M_APM, M_APM, M_APM); + +extern void m_apm_add(M_APM, M_APM, M_APM); +extern void m_apm_subtract(M_APM, M_APM, M_APM); +extern void m_apm_multiply(M_APM, M_APM, M_APM); +extern void m_apm_divide(M_APM, int, M_APM, M_APM); +extern void m_apm_integer_divide(M_APM, M_APM, M_APM); +extern void m_apm_integer_div_rem(M_APM, M_APM, M_APM, M_APM); +extern void m_apm_reciprocal(M_APM, int, M_APM); +extern void m_apm_factorial(M_APM, M_APM); +extern void m_apm_floor(M_APM, M_APM); +extern void m_apm_ceil(M_APM, M_APM); +extern void m_apm_get_random(M_APM); +extern void m_apm_set_random_seed(char *); + +extern void m_apm_sqrt(M_APM, int, M_APM); +extern void m_apm_cbrt(M_APM, int, M_APM); +extern void m_apm_log(M_APM, int, M_APM); +extern void m_apm_log10(M_APM, int, M_APM); +extern void m_apm_exp(M_APM, int, M_APM); +extern void m_apm_pow(M_APM, int, M_APM, M_APM); +extern void m_apm_integer_pow(M_APM, int, M_APM, int); +extern void m_apm_integer_pow_nr(M_APM, M_APM, int); + +extern void m_apm_sin_cos(M_APM, M_APM, int, M_APM); +extern void m_apm_sin(M_APM, int, M_APM); +extern void m_apm_cos(M_APM, int, M_APM); +extern void m_apm_tan(M_APM, int, M_APM); +extern void m_apm_arcsin(M_APM, int, M_APM); +extern void m_apm_arccos(M_APM, int, M_APM); +extern void m_apm_arctan(M_APM, int, M_APM); +extern void m_apm_arctan2(M_APM, int, M_APM, M_APM); + +extern void m_apm_sinh(M_APM, int, M_APM); +extern void m_apm_cosh(M_APM, int, M_APM); +extern void m_apm_tanh(M_APM, int, M_APM); +extern void m_apm_arcsinh(M_APM, int, M_APM); +extern void m_apm_arccosh(M_APM, int, M_APM); +extern void m_apm_arctanh(M_APM, int, M_APM); + +extern void m_apm_cpp_precision(int); /* only for C++ wrapper */ + +/* more intuitive alternate names for the ARC functions ... */ + +#define m_apm_asin m_apm_arcsin +#define m_apm_acos m_apm_arccos +#define m_apm_atan m_apm_arctan +#define m_apm_atan2 m_apm_arctan2 + +#define m_apm_asinh m_apm_arcsinh +#define m_apm_acosh m_apm_arccosh +#define m_apm_atanh m_apm_arctanh + +#ifdef APM_CONVERT_FROM_C +} /* End extern "C" bracket */ +#endif + +#ifdef __cplusplus /*<- Hides the class below from C compilers */ + +/* + This class lets you use M_APM's a bit more intuitively with + C++'s operator and function overloading, constructors, etc. + + Added 3/24/2000 by Orion Sky Lawlor, olawlor@acm.org +*/ + +extern +#ifdef APM_CONVERT_FROM_C +"C" +#endif +int MM_cpp_min_precision; + + +class MAPM +{ +protected: + + /* + The M_APM structure here is implemented as a reference- + counted, copy-on-write data structure-- this makes copies + very fast, but that's why it's so ugly. A MAPM object is + basically just a wrapper around a (possibly shared) + M_APM_struct myVal. + */ + + + M_APM myVal; /* My M_APM structure */ + void create(void) + { + myVal = makeNew(); + } + void destroy(void) + { + unref(myVal); + myVal = NULL; + } + void copyFrom(M_APM Nval) + { + M_APM oldVal = myVal; + myVal = Nval; + ref(myVal); + unref(oldVal); + } + static M_APM makeNew(void) + { + M_APM val = m_apm_init(); + /* refcount initialized to 1 by 'm_apm_init' */ + return val; + } + static void ref(M_APM val) + { + val->m_apm_refcount++; + } + static void unref(M_APM val) + { + val->m_apm_refcount--; + if (val->m_apm_refcount == 0) + m_apm_free(val); + } + + /* This routine is called to get a private (mutable) + copy of our current value. */ + M_APM val(void) + { + if (myVal->m_apm_refcount == 1) + /* Return my private myVal */ + return myVal; + + /* Otherwise, our copy of myVal is shared-- + we need to make a new private copy. + */ + M_APM oldVal = myVal; + myVal = makeNew(); + m_apm_copy(myVal, oldVal); + unref(oldVal); + return myVal; + } + + /*BAD: C M_APM routines doesn't use "const" where they should-- + hence we have to cast to a non-const type here (FIX THIS!). + + (in due time.... MCR) + */ + M_APM cval(void) const + { + return (M_APM)myVal; + } + /* This is the default number of digits to use for + 1-ary functions like sin, cos, tan, etc. + It's the larger of my digits and cpp_min_precision. + */ + int myDigits(void) const + { + int maxd = m_apm_significant_digits(cval()); + if (maxd < MM_cpp_min_precision) maxd = MM_cpp_min_precision; + return maxd; + } + /* This is the default number of digits to use for + 2-ary functions like divide, atan2, etc. + It's the larger of my digits, his digits, and cpp_min_precision. + */ + int digits(const MAPM &otherVal) const + { + int maxd = myDigits(); + int his = m_apm_significant_digits(otherVal.cval()); + if (maxd < his) maxd = his; + return maxd; + } +public: + /* Constructors: */ + MAPM(void) /* Default constructor (takes no value) */ + { + create(); + } + MAPM(const MAPM &m) /* Copy constructor */ + { + myVal = (M_APM)m.cval(); + ref(myVal); + } + MAPM(M_APM m) /* M_APM constructor (refcount starts at one) */ + { + myVal = (M_APM)m; + ref(myVal); + } + MAPM(const char *s) /* Constructor from string */ + { + create(); + m_apm_set_string(val(), (char *)s); + } + MAPM(double d) /* Constructor from double-precision float */ + { + create(); + m_apm_set_double(val(), d); + } + MAPM(int l) /* Constructor from int */ + { + create(); + m_apm_set_long(val(), l); + } + MAPM(long l) /* Constructor from long int */ + { + create(); + m_apm_set_long(val(), l); + } + /* Destructor */ + ~MAPM() + { + destroy(); + } + + /* Extracting string descriptions: */ + void toString(char *dest, int decimalPlaces) const + { + m_apm_to_string(dest, decimalPlaces, cval()); + } + void toFixPtString(char *dest, int decimalPlaces) const + { + m_apm_to_fixpt_string(dest, decimalPlaces, cval()); + } + void toFixPtStringEx(char *dest, int dp, char a, char b, int c) const + { + m_apm_to_fixpt_stringex(dest, dp, cval(), a, b, c); + } + char *toFixPtStringExp(int dp, char a, char b, int c) const + { + return(m_apm_to_fixpt_stringexp(dp, cval(), a, b, c)); + } + void toIntegerString(char *dest) const + { + m_apm_to_integer_string(dest, cval()); + } + + /* Basic operators: */ + MAPM &operator=(const MAPM &m) /* Assigment operator */ + { + copyFrom((M_APM)m.cval()); + return *this; + } + MAPM &operator=(const char *s) /* Assigment operator */ + { + m_apm_set_string(val(), (char *)s); + return *this; + } + MAPM &operator=(double d) /* Assigment operator */ + { + m_apm_set_double(val(), d); + return *this; + } + MAPM &operator=(int l) /* Assigment operator */ + { + m_apm_set_long(val(), l); + return *this; + } + MAPM &operator=(long l) /* Assigment operator */ + { + m_apm_set_long(val(), l); + return *this; + } + MAPM operator++() /* Prefix increment operator */ + { + return *this = *this + MM_One; + } + MAPM operator--() /* Prefix decrement operator */ + { + return *this = *this - MM_One; + } + const MAPM operator++(int) /* Postfix increment operator */ + { + MAPM old = *this; + ++(*this); /* Call prefix increment */ + return old; + } + const MAPM operator--(int) /* Postfix decrement operator */ + { + MAPM old = *this; + --(*this); /* Call prefix decrement */ + return old; + } + + /* Comparison operators */ + int operator==(const MAPM &m) const /* Equality operator */ + { + return m_apm_compare(cval(), m.cval()) == 0; + } + int operator!=(const MAPM &m) const /* Inequality operator */ + { + return m_apm_compare(cval(), m.cval()) != 0; + } + int operator<(const MAPM &m) const + { + return m_apm_compare(cval(), m.cval()) < 0; + } + int operator<=(const MAPM &m) const + { + return m_apm_compare(cval(), m.cval()) <= 0; + } + int operator>(const MAPM &m) const + { + return m_apm_compare(cval(), m.cval()) > 0; + } + int operator>=(const MAPM &m) const + { + return m_apm_compare(cval(), m.cval()) >= 0; + } + + /* Basic arithmetic operators */ + friend MAPM operator+(const MAPM &a, const MAPM &b); + friend MAPM operator-(const MAPM &a, const MAPM &b); + friend MAPM operator*(const MAPM &a, const MAPM &b) + { + MAPM ret; + m_apm_multiply(ret.val(), a.cval(), b.cval()); + return ret; + } + friend MAPM operator%(const MAPM &a, const MAPM &b) + { + MAPM quot, ret; + m_apm_integer_div_rem(quot.val(), ret.val(), + a.cval(), b.cval()); + return ret; + } + + /* Default division keeps larger of cpp_min_precision, numerator + digits of precision, or denominator digits of precision. */ + friend MAPM operator/(const MAPM &a, const MAPM &b) + { + return a.divide(b, a.digits(b)); + } + + MAPM divide(const MAPM &m, int toDigits) const + { + MAPM ret; + m_apm_divide(ret.val(), toDigits, cval(), + m.cval()); + return ret; + } + MAPM divide(const MAPM &m) const + { + return divide(m, digits(m)); + } + + /* Assignment arithmetic operators */ + MAPM &operator+=(const MAPM &m) + { + *this = *this + m; + return *this; + } + MAPM &operator-=(const MAPM &m) + { + *this = *this - m; + return *this; + } + MAPM &operator*=(const MAPM &m) + { + *this = *this * m; + return *this; + } + MAPM &operator/=(const MAPM &m) + { + *this = *this / m; + return *this; + } + MAPM &operator%=(const MAPM &m) + { + *this = *this % m; + return *this; + } + + /* Extracting/setting simple information: */ + int sign(void) const + { + return m_apm_sign(cval()); + } + int exponent(void) const + { + return m_apm_exponent(cval()); + } + int significant_digits(void) const + { + return m_apm_significant_digits(cval()); + } + int is_integer(void) const + { + return m_apm_is_integer(cval()); + } + int is_even(void) const + { + return m_apm_is_even(cval()); + } + int is_odd(void) const + { + return m_apm_is_odd(cval()); + } + + /* Functions: */ + MAPM abs(void) const + { + MAPM ret; + m_apm_absolute_value(ret.val(), cval()); + return ret; + } + MAPM neg(void) const + { + MAPM ret; + m_apm_negate(ret.val(), cval()); + return ret; + } + MAPM round(int toDigits) const + { + MAPM ret; + m_apm_round(ret.val(), toDigits, cval()); + return ret; + } + MAPM operator-(void) const + { + return neg(); + } + + /* I got tired of typing the various declarations for a simple + 1-ary real-to-real function on MAPM's; hence this define: + The digits-free versions return my digits of precision or + cpp_min_precision, whichever is bigger. + */ + +#define MAPM_1aryFunc(func) \ + MAPM func(int toDigits) const\ + {MAPM ret;m_apm_##func(ret.val(),toDigits,cval());return ret;}\ + MAPM func(void) const {return func(myDigits());} + + MAPM_1aryFunc(sqrt) + MAPM_1aryFunc(cbrt) + MAPM_1aryFunc(log) + MAPM_1aryFunc(exp) + MAPM_1aryFunc(log10) + MAPM_1aryFunc(sin) + MAPM_1aryFunc(asin) + MAPM_1aryFunc(cos) + MAPM_1aryFunc(acos) + MAPM_1aryFunc(tan) + MAPM_1aryFunc(atan) + MAPM_1aryFunc(sinh) + MAPM_1aryFunc(asinh) + MAPM_1aryFunc(cosh) + MAPM_1aryFunc(acosh) + MAPM_1aryFunc(tanh) + MAPM_1aryFunc(atanh) +#undef MAPM_1aryFunc + + void sincos(MAPM &sinR, MAPM &cosR, int toDigits) + { + m_apm_sin_cos(sinR.val(), cosR.val(), toDigits, cval()); + } + void sincos(MAPM &sinR, MAPM &cosR) + { + sincos(sinR, cosR, myDigits()); + } + MAPM pow(const MAPM &m, int toDigits) const + { + MAPM ret; + m_apm_pow(ret.val(), toDigits, cval(), + m.cval()); + return ret; + } + MAPM pow(const MAPM &m) const + { + return pow(m, digits(m)); + } + MAPM atan2(const MAPM &x, int toDigits) const + { + MAPM ret; + m_apm_arctan2(ret.val(), toDigits, cval(), + x.cval()); + return ret; + } + MAPM atan2(const MAPM &x) const + { + return atan2(x, digits(x)); + } + + MAPM gcd(const MAPM &m) const + { + MAPM ret; + m_apm_gcd(ret.val(), cval(), m.cval()); + return ret; + } + + MAPM lcm(const MAPM &m) const + { + MAPM ret; + m_apm_lcm(ret.val(), cval(), m.cval()); + return ret; + } + + static MAPM random(void) + { + MAPM ret; + m_apm_get_random(ret.val()); + return ret; + } + + MAPM floor(void) const + { + MAPM ret; + m_apm_floor(ret.val(), cval()); + return ret; + } + MAPM ceil(void) const + { + MAPM ret; + m_apm_ceil(ret.val(), cval()); + return ret; + } + + /* Functions defined only on integers: */ + MAPM factorial(void) const + { + MAPM ret; + m_apm_factorial(ret.val(), cval()); + return ret; + } + MAPM ipow_nr(int p) const + { + MAPM ret; + m_apm_integer_pow_nr(ret.val(), + cval(), p); + return ret; + } + MAPM ipow(int p, int toDigits) const + { + MAPM ret; + m_apm_integer_pow(ret.val(), + toDigits, cval(), p); + return ret; + } + MAPM ipow(int p) const + { + return ipow(p, myDigits()); + } + MAPM integer_divide(const MAPM &denom) const + { + MAPM ret; + m_apm_integer_divide(ret.val(), cval(), + denom.cval()); + return ret; + } + void integer_div_rem(const MAPM &denom, MAPM ", MAPM &rem) const + { + m_apm_integer_div_rem(quot.val(), rem.val(), cval(), + denom.cval()); + } + MAPM div(const MAPM &denom) const + { + return integer_divide(denom); + } + MAPM rem(const MAPM &denom) const + { + MAPM ret, ignored; + integer_div_rem(denom, ignored, ret); + return ret; + } +}; + +/* math.h-style functions: */ + +inline MAPM fabs(const MAPM &m) +{ + return m.abs(); +} +inline MAPM factorial(const MAPM &m) +{ + return m.factorial(); +} +inline MAPM floor(const MAPM &m) +{ + return m.floor(); +} +inline MAPM ceil(const MAPM &m) +{ + return m.ceil(); +} +inline MAPM get_random(void) +{ + return MAPM::random(); +} + +/* I got tired of typing the various declarations for a simple + 1-ary real-to-real function on MAPM's; hence this define: +*/ +#define MAPM_1aryFunc(func) \ + inline MAPM func(const MAPM &m) {return m.func();} \ + inline MAPM func(const MAPM &m,int toDigits) {return m.func(toDigits);} + +/* Define a big block of simple functions: */ +MAPM_1aryFunc(sqrt) +MAPM_1aryFunc(cbrt) +MAPM_1aryFunc(log) +MAPM_1aryFunc(exp) +MAPM_1aryFunc(log10) +MAPM_1aryFunc(sin) +MAPM_1aryFunc(asin) +MAPM_1aryFunc(cos) +MAPM_1aryFunc(acos) +MAPM_1aryFunc(tan) +MAPM_1aryFunc(atan) +MAPM_1aryFunc(sinh) +MAPM_1aryFunc(asinh) +MAPM_1aryFunc(cosh) +MAPM_1aryFunc(acosh) +MAPM_1aryFunc(tanh) +MAPM_1aryFunc(atanh) +#undef MAPM_1aryFunc + +/* Computes x to the power y */ +inline MAPM pow(const MAPM &x, const MAPM &y, int toDigits) +{ + return x.pow(y, toDigits); +} +inline MAPM pow(const MAPM &x, const MAPM &y) +{ + return x.pow(y); +} +inline MAPM atan2(const MAPM &y, const MAPM &x, int toDigits) +{ + return y.atan2(x, toDigits); +} +inline MAPM atan2(const MAPM &y, const MAPM &x) +{ + return y.atan2(x); +} +inline MAPM gcd(const MAPM &u, const MAPM &v) +{ + return u.gcd(v); +} +inline MAPM lcm(const MAPM &u, const MAPM &v) +{ + return u.lcm(v); +} +#endif +#endif diff --git a/include/pgscript/utilities/mapm-lib/m_apm_lc.h b/include/pgscript/utilities/mapm-lib/m_apm_lc.h new file mode 100644 index 0000000..e1cbf01 --- /dev/null +++ b/include/pgscript/utilities/mapm-lib/m_apm_lc.h @@ -0,0 +1,271 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + + +/* + * M_APM - m_apm_lc.h + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * This is the local header file needed to build the library + * + */ + +#ifndef M__APM_LOCAL_INC +#define M__APM_LOCAL_INC + +#include +#include +#include +#include +#include "m_apm.h" + +/* + * this supports older (and maybe newer?) Borland compilers. + * these Borland compilers define __MSDOS__ + */ + +#ifndef MSDOS +#ifdef __MSDOS__ +#define MSDOS +#endif +#endif + +/* + * this supports some newer Borland compilers (i.e., v5.5). + */ + +#ifndef MSDOS +#ifdef __BORLANDC__ +#define MSDOS +#endif +#endif + +/* + * this supports the LCC-WIN32 compiler + */ + +#ifndef MSDOS +#ifdef __LCC__ +#define MSDOS +#endif +#endif + +/* + * this supports Micro$oft Visual C++ and also possibly older + * straight C compilers as well. + */ + +#ifndef MSDOS +#ifdef _MSC_VER +#define MSDOS +#endif +#endif + +/* + * this supports the Metrowerks CodeWarrior 7.0 compiler (I think...) + */ + +#ifndef MSDOS +#ifdef __MWERKS__ +#define MSDOS +#endif +#endif + +/* + * this supports the MINGW 32 compiler + */ + +#ifndef MSDOS +#ifdef __MINGW_H +#define MSDOS +#endif +#endif + +/* + * this supports the Open Watcom 1.0 compiler + */ + +#ifndef MSDOS +#ifdef __WATCOMC__ +#define MSDOS +#endif +#endif + +/* + * this supports the Digital Mars compiler + */ + +#ifndef MSDOS +#ifdef __DMC__ +#define MSDOS +#endif +#endif + +/* + * this supports National Instruments LabWindows CVI + */ + +#ifndef _HAVE_NI_LABWIN_CVI_ +#ifdef _CVI_ +#define _HAVE_NI_LABWIN_CVI_ +#endif +#endif + +/* + * If for some reason (RAM limitations, slow floating point, whatever) + * you do NOT want to use the FFT multiply algorithm, un-comment the + * #define below, delete mapm_fft.c and remove mapm_fft from the build. + */ + +/* #define NO_FFT_MULTIPLY */ + +/* + * use your own memory management functions if desired. + * re-define MAPM_* below to point to your functions. + * an example is shown below. + */ + +/* +extern void *memory_allocate(unsigned int); +extern void *memory_reallocate(void *, unsigned int); +extern void memory_free(void *); + +#define MAPM_MALLOC memory_allocate +#define MAPM_REALLOC memory_reallocate +#define MAPM_FREE memory_free +*/ + +/* default: use the standard C library memory functions ... */ + +#define MAPM_MALLOC malloc +#define MAPM_REALLOC realloc +#define MAPM_FREE free + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#define M_APM_IDENT 0x6BCC9AE5 +#define M_APM_RETURN 0 +#define M_APM_FATAL 1 + +/* number of digits in the global constants, PI, E, etc */ + +#define VALID_DECIMAL_PLACES 128 + +extern int MM_lc_PI_digits; +extern int MM_lc_log_digits; + +/* + * constants not in m_apm.h + */ + +extern M_APM MM_0_5; +extern M_APM MM_0_85; +extern M_APM MM_5x_125R; +extern M_APM MM_5x_64R; +extern M_APM MM_5x_256R; +extern M_APM MM_5x_Eight; +extern M_APM MM_5x_Sixteen; +extern M_APM MM_5x_Twenty; +extern M_APM MM_lc_PI; +extern M_APM MM_lc_HALF_PI; +extern M_APM MM_lc_2_PI; +extern M_APM MM_lc_log2; +extern M_APM MM_lc_log10; +extern M_APM MM_lc_log10R; + +/* + * prototypes for internal functions + */ + +#ifndef NO_FFT_MULTIPLY +extern void M_free_all_fft(void); +#endif + +extern void M_init_trig_globals(void); +extern void M_free_all_add(void); +extern void M_free_all_div(void); +extern void M_free_all_exp(void); +extern void M_free_all_pow(void); +extern void M_free_all_rnd(void); +extern void M_free_all_set(void); +extern void M_free_all_cnst(void); +extern void M_free_all_fmul(void); +extern void M_free_all_stck(void); +extern void M_free_all_util(void); + +extern int M_exp_compute_nn(int *, M_APM, M_APM); +extern void M_raw_exp(M_APM, int, M_APM); +extern void M_raw_sin(M_APM, int, M_APM); +extern void M_raw_cos(M_APM, int, M_APM); +extern void M_5x_sin(M_APM, int, M_APM); +extern void M_4x_cos(M_APM, int, M_APM); +extern void M_5x_do_it(M_APM, int, M_APM); +extern void M_4x_do_it(M_APM, int, M_APM); + +extern M_APM M_get_stack_var(void); +extern void M_restore_stack(int); +extern int M_get_sizeof_int(void); + +extern void M_apm_sdivide(M_APM, int, M_APM, M_APM); +extern void M_cos_to_sin(M_APM, int, M_APM); +extern void M_limit_angle_to_pi(M_APM, int, M_APM); +extern void M_log_near_1(M_APM, int, M_APM); +extern void M_get_sqrt_guess(M_APM, M_APM); +extern void M_get_cbrt_guess(M_APM, M_APM); +extern void M_get_log_guess(M_APM, M_APM); +extern void M_get_asin_guess(M_APM, M_APM); +extern void M_get_acos_guess(M_APM, M_APM); +extern void M_arcsin_near_0(M_APM, int, M_APM); +extern void M_arccos_near_0(M_APM, int, M_APM); +extern void M_arctan_near_0(M_APM, int, M_APM); +extern void M_arctan_large_input(M_APM, int, M_APM); +extern void M_log_basic_iteration(M_APM, int, M_APM); +extern void M_log_solve_cubic(M_APM, int, M_APM); +extern void M_check_log_places(int); +extern void M_log_AGM_R_func(M_APM, int, M_APM, M_APM); +extern void M_init_util_data(void); +extern void M_get_div_rem_addr(UCHAR **, UCHAR **); +extern void M_get_div_rem(int, UCHAR *, UCHAR *); +extern void M_get_div_rem_10(int, UCHAR *, UCHAR *); +extern void M_apm_normalize(M_APM); +extern void M_apm_scale(M_APM, int); +extern void M_apm_pad(M_APM, int); +extern void M_long_2_ascii(char *, long); +extern void M_check_PI_places(int); +extern void M_calculate_PI_AGM(M_APM, int); +extern void M_set_to_zero(M_APM); +extern int M_strposition(char *, char *); +extern char *M_lowercase(char *); +extern void M_apm_log_error_msg(int, const char *); +extern void M_apm_round_fixpt(M_APM, int, M_APM); + +#endif diff --git a/include/pgscript/utilities/mapm-lib/module.mk b/include/pgscript/utilities/mapm-lib/module.mk new file mode 100644 index 0000000..2bf702e --- /dev/null +++ b/include/pgscript/utilities/mapm-lib/module.mk @@ -0,0 +1,18 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/pgscript/utilities/mapm-lib/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/pgscript/utilities/mapm-lib/m_apm.h \ + include/pgscript/utilities/mapm-lib/m_apm_lc.h + +EXTRA_DIST += \ + include/pgscript/utilities/mapm-lib/module.mk \ + include/pgscript/utilities/mapm-lib/license.txt diff --git a/include/pgscript/utilities/module.mk b/include/pgscript/utilities/module.mk new file mode 100644 index 0000000..14d3043 --- /dev/null +++ b/include/pgscript/utilities/module.mk @@ -0,0 +1,26 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/pgscript/utilities/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/pgscript/utilities/pgsAlloc.h \ + include/pgscript/utilities/pgsContext.h \ + include/pgscript/utilities/pgsCopiedPtr.h \ + include/pgscript/utilities/pgsDriver.h \ + include/pgscript/utilities/pgsMapm.h \ + include/pgscript/utilities/pgsScanner.h \ + include/pgscript/utilities/pgsSharedPtr.h \ + include/pgscript/utilities/pgsThread.h \ + include/pgscript/utilities/pgsUtilities.h + +EXTRA_DIST += \ + include/pgscript/utilities/module.mk + +include include/pgscript/utilities/mapm-lib/module.mk diff --git a/include/pgscript/utilities/pgsAlloc.h b/include/pgscript/utilities/pgsAlloc.h new file mode 100644 index 0000000..8e3d1eb --- /dev/null +++ b/include/pgscript/utilities/pgsAlloc.h @@ -0,0 +1,77 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSALLOC_H +#define PGSALLOC_H + +#if defined(PGSDEBUG) + +#include // malloc and free +#include // std::bad_alloc +#include + +struct pgsMallocInfo +{ + const void *ptr; + size_t size; + wxString filename; + size_t line_nb; +}; + +WX_DECLARE_VOIDPTR_HASH_MAP(pgsMallocInfo, pgsMallocInfoMap); + +class pgsAlloc +{ + +protected: + + pgsAlloc(); + + pgsMallocInfoMap m_malloc_info; + +private: + + void add_malloc(const pgsMallocInfo &malloc_info); + + void rm_malloc(const void *ptr); + +public: + + void *pmalloc(size_t size, const char *filename, size_t line_nb); + + void dump(); + + void pfree(void *ptr); + + static pgsAlloc &instance(); + +}; + +void *operator new(size_t size) throw (std::bad_alloc); +void *operator new[](size_t size) throw (std::bad_alloc); +void *operator new(size_t size, const char *filename, size_t line_nb) +throw (std::bad_alloc); +void *operator new[](size_t size, const char *filename, size_t line_nb) +throw (std::bad_alloc); +void operator delete(void *ptr) throw (); +void operator delete[](void *ptr) throw (); + +#define pnew new(__FILE__, __LINE__) + +#else + +#define pnew new + +#endif // PGSDEBUG + +#define pdelete(x) if ((x) != 0) { delete x; x = 0; } +#define pdeletea(x) if ((x) != 0) { delete[] x; x = 0; } + +#endif /*PGSALLOC_H_*/ diff --git a/include/pgscript/utilities/pgsContext.h b/include/pgscript/utilities/pgsContext.h new file mode 100644 index 0000000..398170f --- /dev/null +++ b/include/pgscript/utilities/pgsContext.h @@ -0,0 +1,119 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSCONTEXT_H_ +#define PGSCONTEXT_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/statements/pgsStmtList.h" + +WX_DECLARE_LIST(pgsExpression, pgsListExpression); + +class pgsThread; + +/** pgsContext is kind of a util class used during script parsing. + * It is used in pgsParser.yy. Some members are made public because they need + * to be easily available in order to be passed to some other objects. */ +class pgsContext +{ + +private: + + wxArrayString m_columns; + + /** List of temporary expressions or variables. */ + pgsListExpression m_vars; + + /** List of temporary statements. */ + pgsListStmt m_stmts; + +public: + + /** For writing to the output. */ + pgsOutputStream &m_cout; + +public: + + ////////////////////////////// + // Constructor & destructor // + ////////////////////////////// + + pgsContext(pgsOutputStream &cout); + + ~pgsContext(); + + /////////////////////////////// + // Methods generating values // + /////////////////////////////// + + /** Generates a pgsNumber with value '0' and put it on stack. */ + pgsVariable *zero(); + + /** Generates a pgsNumber with value '0' and put it on stack. */ + pgsVariable *one(); + + /** Generates a pgsNumber with value now() and put it on stack. */ + pgsVariable *seed(); + + /** Generates a pgsString with the locale encoding and put it on stack. */ + pgsVariable *encoding(); + + /** Generates an empty statement list and put it on stack. */ + pgsStmtList *stmt_list(pgsThread *app = 0); + + //////////////////////////////////////////////// + // For managing a new record declaration list // + //////////////////////////////////////////////// + + /** Adds a column name to the column list. */ + void add_column(const wxString &column); + + /** Retrieves the column list. */ + const wxArrayString &columns(); + + /** Clears the column list. */ + void clear_columns(); + + + ///////////////////////////////////////////// + // For managing stacks of temporary values // + ///////////////////////////////////////////// + + /** Adds a pgsExpression on stack. */ + void push_var(pgsExpression *var); + + /** Removes the last pgsExpression on stack. */ + void pop_var(); + + /** Gives the number of pgsExpression on stack. */ + size_t size_vars() const; + + /** Adds a pgsStmt on stack. */ + void push_stmt(pgsStmt *stmt); + + /** Removes the last pgsStmt on stack. */ + void pop_stmt(); + + /** Gives the number of pgsStmt on stack. */ + size_t size_stmts() const; + + /** When an error occurs in the parser this method must be called in order + * to free the memory (i.e the temporary pgsExpression & pgsStmt). */ + void clear_stacks(); + +private: + + pgsContext(const pgsContext &that); + + pgsContext &operator=(const pgsContext &that); + +}; + +#endif /*PGSCONTEXT_H_*/ diff --git a/include/pgscript/utilities/pgsCopiedPtr.h b/include/pgscript/utilities/pgsCopiedPtr.h new file mode 100644 index 0000000..e5c3995 --- /dev/null +++ b/include/pgscript/utilities/pgsCopiedPtr.h @@ -0,0 +1,80 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSCOPIEDPTR_H_ +#define PGSCOPIEDPTR_H_ + +#include + +template class pgsCopiedPtr +{ + +private: + + T *p; + +public: + + pgsCopiedPtr(T *p) : + p(p) + { + + } + + pgsCopiedPtr() : + p(0) + { + + } + + pgsCopiedPtr(const pgsCopiedPtr &that) : + p(that.p == 0 ? 0 : that.p->clone()) + { + + } + + ~pgsCopiedPtr() + { + pdelete(p); + } + + pgsCopiedPtr &operator =(pgsCopiedPtr that) + { + std::swap(p, that.p); + return (*this); + } + + T &operator *() + { + return *p; + } + + const T &operator *() const + { + return *p; + } + + T *operator ->() + { + return p; + } + + const T *operator ->() const + { + return p; + } + + const T *get() const + { + return p; + } +}; + +#endif /*PGSCOPIEDPTR_H_*/ diff --git a/include/pgscript/utilities/pgsDriver.h b/include/pgscript/utilities/pgsDriver.h new file mode 100644 index 0000000..e7c637b --- /dev/null +++ b/include/pgscript/utilities/pgsDriver.h @@ -0,0 +1,98 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSDRIVER_H_ +#define PGSDRIVER_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/utilities/pgsScanner.h" +#include "pgscript/parser.tab.hh" + +// Forward declaration +class pgsContext; + +// Forward declaration +class pgsProgram; + +// Forward declaration +class pgsThread; + +/** The pgscript namespace is used to encapsulate the three parser classes + * pgscript::pgsParser, pgscript::pgsScanner and pgscript::pgsDriver */ +namespace pgscript +{ + +/** The pgsDriver class brings together all components. It creates an instance of + * the pgsParser and pgsScanner classes and connects them. Then the input stream is + * fed into the scanner object and the parser gets its token + * sequence. Furthermore the driver object is available in the grammar rules as + * a parameter. Therefore the driver class contains a reference to the + * structure into which the parsed data is saved. */ +class pgsDriver +{ +public: + /// Construct a new parser driver context + pgsDriver(class pgsContext &_context, class pgsProgram &_program, + class pgsThread &_thread); + + /// Destroy parser + ~pgsDriver(); + + /// Enable debug output in the flex scanner + bool trace_scanning; + + /// Enable debug output in the bison parser + bool trace_parsing; + + /** Invoke the scanner and parser for a stream. + * @param in input stream + * @return true if successfully parsed + */ + bool parse_stream(std::istream &in); + + /** Invoke the scanner and parser on an input string. + * @param input input string + * @return true if successfully parsed + */ + bool parse_string(const wxString &input); + + /** Invoke the scanner and parser on a file. Use parse_stream with a + * std::ifstream if detection of file reading errors is required. + * @param filename input file name + * @param conv multi-byte string converter + * @return true if successfully parsed + */ + bool parse_file(const wxString &filename, wxMBConv &conv = wxConvLocal); + + // To demonstrate pure handling of parse errors, instead of + // simply dumping them on the standard error output, we will pass + // them to the driver using the following two member functions. + + /** Error handling with associated line number. This can be modified to + * output the error e.g. to a dialog box. */ + void error(const class location &l, const wxString &m); + + /** Pointer to the current lexer instance, this is used to connect the + * parser to the scanner. It is used in the yylex macro. */ + class pgsScanner *lexer; + + /** Reference to the context filled during parsing of the expressions. */ + class pgsContext &context; + + /** Contains the list of statements to execute. */ + class pgsProgram &program; + + /** The thread in which this driver is included. */ + class pgsThread &thread; +}; + +} // namespace pgscript + +#endif // PGSDRIVER_H_ diff --git a/include/pgscript/utilities/pgsMapm.h b/include/pgscript/utilities/pgsMapm.h new file mode 100644 index 0000000..8c26af4 --- /dev/null +++ b/include/pgscript/utilities/pgsMapm.h @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSMAPMLIB_H_ +#define PGSMAPMLIB_H_ + +#include "pgscript/pgScript.h" +#include "mapm-lib/m_apm.h" + +WX_DECLARE_OBJARRAY(MAPM, pgsVectorMapm); + +class pgsMapm +{ + +public: + + static wxString pgs_mapm_str(const MAPM &m, const bool &as_int = false); + + static MAPM pgs_mapm_round(const MAPM &m); + + static wxString pgs_mapm_str_fixed(const MAPM &m); + + static wxString pgs_mapm_str_float(const MAPM &m); + + static MAPM pgs_str_mapm(const wxString &s); + +}; + +#endif /*PGSMAPMLIB_H_*/ diff --git a/include/pgscript/utilities/pgsScanner.h b/include/pgscript/utilities/pgsScanner.h new file mode 100644 index 0000000..87a7fa7 --- /dev/null +++ b/include/pgscript/utilities/pgsScanner.h @@ -0,0 +1,87 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSSCANNER_H_ +#define PGSSCANNER_H_ + +// Flex expects the signature of yylex to be defined in the macro YY_DECL, and +// the C++ parser expects it to be declared. We can factor both as follows. + +#ifndef YY_DECL + +#define YY_DECL \ + pgscript::pgsParser::token_type \ + pgscript::pgsScanner::lex( \ + pgscript::pgsParser::semantic_type* yylval, \ + pgscript::pgsParser::location_type* yylloc \ + ) +#endif + +#ifndef __FLEX_LEXER_H +#define yyFlexLexer pgsFlexLexer +#include "pgscript/FlexLexer.h" +#undef yyFlexLexer +#endif + +#include "pgscript/parser.tab.hh" +#include +#include +#include + +namespace pgscript +{ + +/** pgsScanner is a derived class to add some extra function to the scanner + * class. Flex itself creates a class named yyFlexLexer, which is renamed using + * macros to pgsFlexLexer. However we change the context of the generated + * yylex() function to be contained within the pgsScanner class. This is required + * because the yylex() defined in pgsFlexLexer has no parameters. */ +class pgsScanner : public pgsFlexLexer +{ +public: + /** Create a new scanner object. The streams arg_yyin and arg_yyout default + * to cin and cout, but that assignment is only made when initializing in + * yylex(). */ + pgsScanner(wxMBConv &conv, std::istream *arg_yyin = 0, + std::ostream *arg_yyout = 0); + + /** Required for virtual functions */ + virtual ~pgsScanner(); + + /** This is the main lexing function. It is generated by flex according to + * the macro declaration YY_DECL above. The generated bison parser then + * calls this virtual function to fetch new tokens. */ + virtual pgsParser::token_type lex(pgsParser::semantic_type *yylval, + pgsParser::location_type *yylloc); + + /** Enable debug output (via arg_yyout) if compiled into the scanner. */ + void set_debug(bool b); + +private: + + /** Corrects column count because of multi-byte UTF8 characters. */ + int columns(const char &c); + + /** To count parenthesis. */ + int m_parent; + + std::string query, dollar, str; + + int comment_caller, string_caller; + + pgscript::pgsParser::token_type query_token; + + wxMBConv &m_conv; + +}; + +} // namespace pgscript + +#endif // PGSSCANNER_H_ diff --git a/include/pgscript/utilities/pgsSharedPtr.h b/include/pgscript/utilities/pgsSharedPtr.h new file mode 100644 index 0000000..543e68b --- /dev/null +++ b/include/pgscript/utilities/pgsSharedPtr.h @@ -0,0 +1,99 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSSHAREDPTR_H_ +#define PGSSHAREDPTR_H_ + +template class pgsSharedPtr +{ + +private: + + struct count + { + long c; + + T *q; + + count(T *q) : + c(1), q(q) + { + + } + + ~count() + { + pdelete(q); + } + }; + + count *p; + +public: + + pgsSharedPtr(T *q) : + p(pnew count(q)) + { + + } + + pgsSharedPtr() : + p(pnew count(0)) + { + + } + + pgsSharedPtr(const pgsSharedPtr &that) : + p(that.p) + { + ++p->c; + } + + ~pgsSharedPtr() + { + if (!--p->c) + { + pdelete(p); + } + } + + pgsSharedPtr &operator =(pgsSharedPtr that) + { + std::swap(p, that.p); + return (*this); + } + + T &operator *() + { + return *(p->q); + } + + const T &operator *() const + { + return *(p->q); + } + + T *operator ->() + { + return p->q; + } + + const T *operator ->() const + { + return p->q; + } + + const T *get() const + { + return p->q; + } +}; + +#endif /*PGSSHAREDPTR_H_*/ diff --git a/include/pgscript/utilities/pgsThread.h b/include/pgscript/utilities/pgsThread.h new file mode 100644 index 0000000..2445f32 --- /dev/null +++ b/include/pgscript/utilities/pgsThread.h @@ -0,0 +1,92 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSTHREAD_H_ +#define PGSTHREAD_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/objects/pgsVariable.h" + +#include + +class pgConn; +class pgsApplication; +class pgsStmtList; + +class pgsThread : public wxThread +{ + +private: + + /** Symbol table (memory variables). */ + pgsVarMap &m_vars; + + /** In order to have only one thread at once. */ + wxSemaphore &m_mutex; + + /** Connection to the database. */ + pgConn *m_connection; + + /** Either the file to parse or the string. */ + wxString m_data; + + /** Where to write the output. */ + pgsOutputStream &m_out; + + /** The calling application. */ + pgsApplication &m_app; + + /** If set it is the encoding used in the file to parse. */ + wxMBConv *m_conv; + + /** Location of the last error if there was one otherwise -1 */ + int m_last_error_line; + +public: + + /** Parses a file with the provided encoding. */ + pgsThread(pgsVarMap &vars, wxSemaphore &mutex, pgConn *connection, + const wxString &file, pgsOutputStream &out, + pgsApplication &app, wxMBConv *conv); + + /** Parses a wxString. */ + pgsThread(pgsVarMap &vars, wxSemaphore &mutex, pgConn *connection, + const wxString &string, pgsOutputStream &out, pgsApplication &app); + + /** Destructor. */ + ~pgsThread(); + + /** Thread main code. */ + virtual void *Entry(); + + /** Retrieves the connection to the database. */ + pgConn *connection(); + + /** Gets a lock on the output stream. */ + void LockOutput(); + + /** Releases the lock on the output stream. */ + void UnlockOutput(); + + /** Set the position (line) of the last error. */ + void last_error_line(int line); + + /** Get the position (line) of the last error. */ + int last_error_line() const; + +private: + + pgsThread(const pgsThread &that); + + pgsThread &operator=(const pgsThread &that); + +}; + +#endif /*PGSTHREAD_H_*/ diff --git a/include/pgscript/utilities/pgsUtilities.h b/include/pgscript/utilities/pgsUtilities.h new file mode 100644 index 0000000..689b0d3 --- /dev/null +++ b/include/pgscript/utilities/pgsUtilities.h @@ -0,0 +1,27 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSUTILITIES_H_ +#define PGSUTILITIES_H_ + +#include "pgscript/pgScript.h" + +class pgsUtilities +{ + +public: + + static wxString uniform_line_returns(wxString s); + static wxString escape_quotes(wxString s); + static wxString unescape_quotes(wxString s); + +}; + +#endif /*PGSUTILITIES_H_*/ diff --git a/include/postgres.h b/include/postgres.h new file mode 100644 index 0000000..f3ef6d5 --- /dev/null +++ b/include/postgres.h @@ -0,0 +1,25 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// postgres.h - dummy include +// +////////////////////////////////////////////////////////////////////////// + + +#include + +#define lengthof(array) (sizeof (array) / sizeof ((array)[0])) +#define endof(array) (&array[lengthof(array)]) + + + +// to suppress much stuff in parse.h +#define YYTOKENTYPE +#define YYSTYPE int + + +#define NAMEDATALEN 32 diff --git a/include/precomp.h b/include/precomp.h new file mode 100644 index 0000000..f8d305a --- /dev/null +++ b/include/precomp.h @@ -0,0 +1,250 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// precomp.h - All header files for compilers supporting precompiled headers +// +////////////////////////////////////////////////////////////////////////// + +#ifdef WX_PRECOMP + +#include "copyright.h" +#include "pgAdmin3.h" +#include "version.h" + +#include "agent/dlgJob.h" +#include "agent/dlgSchedule.h" +#include "agent/dlgStep.h" +#include "agent/pgaJob.h" +#include "agent/pgaSchedule.h" +#include "agent/pgaStep.h" + +#include "ctl/calbox.h" +#include "ctl/ctlAuiNotebook.h" +#include "ctl/ctlCheckTreeView.h" +#include "ctl/ctlColourPicker.h" +#include "ctl/ctlComboBox.h" +#include "ctl/ctlListView.h" +#include "ctl/ctlSecurityPanel.h" +#include "ctl/ctlSQLBox.h" +#include "ctl/ctlSQLGrid.h" +#include "ctl/ctlSQLResult.h" +#include "ctl/ctlTree.h" +#include "ctl/explainCanvas.h" +#include "ctl/timespin.h" +#include "ctl/wxgridsel.h" +#include "ctl/xh_calb.h" +#include "ctl/xh_ctlcombo.h" +#include "ctl/xh_ctlchecktreeview.h" +#include "ctl/xh_ctlcolourpicker.h" +#include "ctl/xh_ctltree.h" +#include "ctl/xh_sqlbox.h" +#include "ctl/xh_timespin.h" + +#include "db/pgConn.h" +#include "db/pgQueryThread.h" +#include "db/pgQueryResultEvent.h" +#include "db/pgSet.h" + +#include "debugger/ctlMessageWindow.h" +#include "debugger/ctlResultGrid.h" +#include "debugger/ctlStackWindow.h" +#include "debugger/ctlTabWindow.h" +#include "debugger/ctlVarWindow.h" +#include "debugger/dbgBreakPoint.h" +#include "debugger/dbgConst.h" +#include "debugger/dbgController.h" +#include "debugger/dbgModel.h" +#include "debugger/dbgTargetInfo.h" +#include "debugger/debugger.h" +#include "debugger/dlgDirectDbg.h" +#include "debugger/frmDebugger.h" + +#include "dlg/dlgAddFavourite.h" +#include "dlg/dlgAggregate.h" +#include "dlg/dlgCast.h" +#include "dlg/dlgCheck.h" +#include "dlg/dlgClasses.h" +#include "dlg/dlgColumn.h" +#include "dlg/dlgConnect.h" +#include "dlg/dlgConversion.h" +#include "dlg/dlgDatabase.h" +#include "dlg/dlgDomain.h" +#include "dlg/dlgEditGridOptions.h" +#include "dlg/dlgFindReplace.h" +#include "dlg/dlgForeignDataWrapper.h" +#include "dlg/dlgForeignKey.h" +#include "dlg/dlgForeignServer.h" +#include "dlg/dlgFunction.h" +#include "dlg/dlgGroup.h" +#include "dlg/dlgHbaConfig.h" +#include "dlg/dlgIndex.h" +#include "dlg/dlgIndexConstraint.h" +#include "dlg/dlgLanguage.h" +#include "dlg/dlgMainConfig.h" +#include "dlg/dlgManageFavourites.h" +#include "dlg/dlgManageMacros.h" +#include "dlg/dlgOperator.h" +#include "dlg/dlgPackage.h" +#include "dlg/dlgPgpassConfig.h" +#include "dlg/dlgProperty.h" +#include "dlg/dlgRole.h" +#include "dlg/dlgRule.h" +#include "dlg/dlgSchema.h" +#include "dlg/dlgSelectConnection.h" +#include "dlg/dlgSelectDatabase.h" +#include "dlg/dlgSequence.h" +#include "dlg/dlgServer.h" +#include "dlg/dlgSynonym.h" +#include "dlg/dlgTable.h" +#include "dlg/dlgTablespace.h" +#include "dlg/dlgTextSearchConfiguration.h" +#include "dlg/dlgTextSearchDictionary.h" +#include "dlg/dlgTextSearchTemplate.h" +#include "dlg/dlgTextSearchParser.h" +#include "dlg/dlgTrigger.h" +#include "dlg/dlgType.h" +#include "dlg/dlgUser.h" +#include "dlg/dlgUserMapping.h" +#include "dlg/dlgView.h" +#include "dlg/dlgExtTable.h" + +#include "frm/frmAbout.h" +#include "frm/frmBackup.h" +#include "frm/frmConfig.h" +#include "frm/frmEditGrid.h" +#include "frm/frmExport.h" +#include "frm/frmGrantWizard.h" +#include "frm/frmHbaConfig.h" +#include "frm/frmHint.h" +#include "frm/frmMain.h" +#include "frm/frmMainConfig.h" +#include "frm/frmMaintenance.h" +#include "frm/frmOptions.h" +#include "frm/frmPassword.h" +#include "frm/frmPgpassConfig.h" +#include "frm/frmQuery.h" +#include "frm/frmReport.h" +#include "frm/frmRestore.h" +#include "frm/frmSplash.h" +#include "frm/frmStatus.h" +#include "frm/menu.h" + +#include "ogl/basic.h" +#include "ogl/basicp.h" +#include "ogl/bmpshape.h" +#include "ogl/canvas.h" +#include "ogl/composit.h" +#include "ogl/constrnt.h" +#include "ogl/divided.h" +#include "ogl/drawn.h" +#include "ogl/drawnp.h" +#include "ogl/lines.h" +#include "ogl/linesp.h" +#include "ogl/mfutils.h" +#include "ogl/misc.h" +#include "ogl/ogl.h" +#include "ogl/ogldiag.h" + +#include "gqb/gqbArrayCollection.h" +#include "gqb/gqbBrowser.h" +#include "gqb/gqbCollection.h" +#include "gqb/gqbCollectionBase.h" +#include "gqb/gqbColumn.h" +#include "gqb/gqbDatabase.h" +#include "gqb/gqbEvents.h" +#include "gqb/gqbGraphBehavior.h" +#include "gqb/gqbGraphSimple.h" +#include "gqb/gqbGridOrderTable.h" +#include "gqb/gqbGridProjTable.h" +#include "gqb/gqbGridRestTable.h" +#include "gqb/gqbModel.h" +#include "gqb/gqbObject.h" +#include "gqb/gqbObjectCollection.h" +#include "gqb/gqbQueryObjs.h" +#include "gqb/gqbSchema.h" +#include "gqb/gqbTable.h" +#include "gqb/gqbViewController.h" +#include "gqb/gqbViewPanels.h" + +#include "schema/edbPackage.h" +#include "schema/edbPackageFunction.h" +#include "schema/edbPackageVariable.h" +#include "schema/edbSynonym.h" +#include "schema/pgAggregate.h" +#include "schema/pgCast.h" +#include "schema/pgCatalogObject.h" +#include "schema/pgCheck.h" +#include "schema/pgCollection.h" +#include "schema/pgColumn.h" +#include "schema/pgConstraints.h" +#include "schema/pgConversion.h" +#include "schema/pgDatabase.h" +#include "schema/pgDatatype.h" +#include "schema/pgDomain.h" +#include "schema/pgForeignDataWrapper.h" +#include "schema/pgForeignKey.h" +#include "schema/pgForeignServer.h" +#include "schema/pgFunction.h" +#include "schema/pgGroup.h" +#include "schema/pgIndex.h" +#include "schema/pgIndexConstraint.h" +#include "schema/pgLanguage.h" +#include "schema/pgObject.h" +#include "schema/pgOperator.h" +#include "schema/pgOperatorClass.h" +#include "schema/pgRole.h" +#include "schema/pgRule.h" +#include "schema/pgSchema.h" +#include "schema/pgSequence.h" +#include "schema/pgServer.h" +#include "schema/pgTable.h" +#include "schema/pgTablespace.h" +#include "schema/pgTextSearchConfiguration.h" +#include "schema/pgTextSearchDictionary.h" +#include "schema/pgTextSearchTemplate.h" +#include "schema/pgTextSearchParser.h" +#include "schema/pgTrigger.h" +#include "schema/pgType.h" +#include "schema/pgUser.h" +#include "schema/pgUserMapping.h" +#include "schema/pgView.h" +#include "schema/gpExtTable.h" +#include "schema/gpPartition.h" +#include "schema/gpResQueue.h" + +#include "slony/dlgRepCluster.h" +#include "slony/dlgRepListen.h" +#include "slony/dlgRepNode.h" +#include "slony/dlgRepPath.h" +#include "slony/dlgRepProperty.h" +#include "slony/dlgRepSequence.h" +#include "slony/dlgRepSet.h" +#include "slony/dlgRepSubscription.h" +#include "slony/dlgRepTable.h" +#include "slony/slCluster.h" +#include "slony/slListen.h" +#include "slony/slNode.h" +#include "slony/slPath.h" +#include "slony/slSequence.h" +#include "slony/slSet.h" +#include "slony/slSubscription.h" +#include "slony/slTable.h" + +#include "utils/csvfiles.h" +#include "utils/factory.h" +#include "utils/favourites.h" +#include "utils/macros.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" +#include "utils/pgconfig.h" +#include "utils/pgfeatures.h" +#include "utils/sysLogger.h" +#include "utils/sysProcess.h" +#include "utils/sysSettings.h" +#include "utils/utffile.h" + +#endif diff --git a/include/schema/edbPackage.h b/include/schema/edbPackage.h new file mode 100644 index 0000000..63ca359 --- /dev/null +++ b/include/schema/edbPackage.h @@ -0,0 +1,189 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// edbPackage.h - EnterpriseDB Package class +// +////////////////////////////////////////////////////////////////////////// + +#ifndef EDBPACKAGE_H +#define EDBPACKAGE_H + + +// App headers +#include "pgDatabase.h" +#include "pgSchema.h" + +class pgCollection; + +class edbPackageFactory : public pgSchemaObjFactory +{ +public: + edbPackageFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + pgCollection *CreateCollection(pgObject *obj); +}; +extern edbPackageFactory packageFactory; + + +class edbPackage : public pgSchemaObject +{ +public: + edbPackage(pgSchema *newSchema, const wxString &newName = wxT("")); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + bool GetSystemObject() const + { + return GetOid() <= GetConnection()->GetLastSystemOID(); + } + + void iSetHeader(const wxString &data) + { + header = data; + }; + wxString GetHeader() + { + return header; + }; + void iSetBody(const wxString &data) + { + body = data; + }; + wxString GetBody() + { + return body; + }; + + wxString GetHeaderInner(); + wxString GetBodyInner(); + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + + bool IsUpToDate(); + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/packages-create"); + } +private: + wxString GetInner(const wxString &def); + + long numProcedures, numFunctions, numVariables; + wxString body, header; +}; + +class edbPackageObject : public pgSchemaObject +{ +public: + edbPackageObject(edbPackage *newPackage, pgaFactory &factory, const wxString &newName = wxT("")) + : pgSchemaObject(newPackage->GetSchema(), factory, newName) + { + package = newPackage; + } + virtual edbPackage *GetPackage() const + { + return package; + } + OID GetPackageOid() const + { + return package->GetOid(); + } + wxString GetPackageOidStr() const + { + return NumToStr(package->GetOid()) + wxT("::oid"); + } + + bool CanCreate() + { + return false; + } + bool CanEdit() + { + return false; + } + bool CanDrop() + { + return false; + } + bool CanDropCascaded() + { + return false; + } + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return false; + } + bool HasReferences() + { + return false; + } + +protected: + edbPackage *package; +}; + +class edbPackageCollection : public pgSchemaObjCollection +{ +public: + edbPackageCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +class edbPackageObjCollection : public pgSchemaObjCollection +{ +public: + edbPackageObjCollection(pgaFactory *factory, edbPackage *_package) + : pgSchemaObjCollection(factory, _package->GetSchema()) + { + iSetOid(_package->GetOid()); + package = _package; + } + virtual edbPackage *GetPackage() const + { + return package; + } + + virtual bool CanCreate() + { + return false; + } + +protected: + edbPackage *package; +}; + +class edbPackageObjFactory : public pgSchemaObjFactory +{ +public: + edbPackageObjFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm = 0) + : pgSchemaObjFactory(tn, ns, nls, img, imgSm) {} + virtual pgCollection *CreateCollection(pgObject *obj); +}; + +#endif diff --git a/include/schema/edbPackageFunction.h b/include/schema/edbPackageFunction.h new file mode 100644 index 0000000..ecfb4da --- /dev/null +++ b/include/schema/edbPackageFunction.h @@ -0,0 +1,166 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// edbPackageFunction.h - EnterpriseDB Package member function +// +////////////////////////////////////////////////////////////////////////// + +#ifndef EDBPACKAGEFUNCTION_H +#define EDBPACKAGEFUNCTION_H + +#include "edbPackage.h" + +class pgCollection; +class edbPackageFunction; + +class edbPackageFunctionFactory : public edbPackageObjFactory +{ +public: + edbPackageFunctionFactory(const wxChar *tn = 0, const wxChar *ns = 0, const wxChar *nls = 0, wxImage *img = 0); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) + { + return 0; + }; + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + pgCollection *CreateCollection(pgObject *obj); + + edbPackageFunction *AppendFunctions(pgObject *obj, edbPackage *package, ctlTree *browser, const wxString &restriction); +}; +extern edbPackageFunctionFactory packageFunctionFactory; + + +class edbPackageFunction : public edbPackageObject +{ +public: + edbPackageFunction(edbPackage *newPackage, const wxString &newName = wxT("")); + edbPackageFunction(edbPackage *newPackage, pgaFactory &factory, const wxString &newName = wxT("")); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + wxString GetSql(ctlTree *browser); + + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + virtual bool GetIsProcedure() const + { + return false; + } + + wxString GetFullName(); + wxString GetArgListWithNames(); + wxString GetArgSigList(); + + wxArrayString &GetArgNamesArray() + { + return argNamesArray; + } + void iAddArgName(const wxString &s) + { + argNamesArray.Add(s); + } + wxArrayString &GetArgTypesArray() + { + return argTypesArray; + } + void iAddArgType(const wxString &s) + { + argTypesArray.Add(s); + } + wxArrayString &GetArgModesArray() + { + return argModesArray; + } + void iAddArgMode(const wxString &s) + { + argModesArray.Add(s); + } + wxArrayString &GetArgDefsArray() + { + return argDefsArray; + } + void iAddArgDef(const wxString &s) + { + argDefsArray.Add(s); + } + + wxString GetReturnType() const + { + return returnType; + } + void iSetReturnType(const wxString &s) + { + returnType = s; + } + wxString GetSource() const + { + return source; + } + void iSetSource(const wxString &s) + { + source = s; + } + wxString GetVisibility() const + { + return visibility; + } + void iSetVisibility(const wxString &s) + { + visibility = s; + } + long GetArgCount() const + { + return argCount; + } + void iSetArgCount(long ac) + { + argCount = ac; + } + + bool CanCreate() + { + return false; + } + +private: + long argCount; + wxArrayString argNamesArray, argTypesArray, argModesArray, argDefsArray; + wxString returnType, source, visibility; +}; + +class edbPackageFunctionCollection : public edbPackageObjCollection +{ +public: + edbPackageFunctionCollection(pgaFactory *factory, edbPackage *pkg); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +class edbPackageProcedureFactory : public edbPackageFunctionFactory +{ +public: + edbPackageProcedureFactory(); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); +}; +extern edbPackageProcedureFactory packageProcedureFactory; + + +class edbPackageProcedure : public edbPackageFunction +{ +public: + edbPackageProcedure(edbPackage *newPackage, const wxString &newName = wxT("")); + wxString GetFullName(); + + bool GetIsProcedure() const + { + return true; + } + + wxString GetSql(ctlTree *browser); +}; + + +#endif diff --git a/include/schema/edbPackageVariable.h b/include/schema/edbPackageVariable.h new file mode 100644 index 0000000..910bc7c --- /dev/null +++ b/include/schema/edbPackageVariable.h @@ -0,0 +1,78 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// edbPackageVariable.h - EnterpriseDB Package variable +// +////////////////////////////////////////////////////////////////////////// + +#ifndef EDBPACKAGEVARIABLE_H +#define EDBPACKAGEVARIABLE_H + +#include "edbPackage.h" +class pgCollection; +class edbPackageVariable; + +class edbPackageVariableFactory : public edbPackageObjFactory +{ +public: + edbPackageVariableFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) + { + return 0; + }; + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + pgCollection *CreateCollection(pgObject *obj); +}; +extern edbPackageVariableFactory packageVariableFactory; + + +class edbPackageVariable : public edbPackageObject +{ +public: + edbPackageVariable(edbPackage *newPackage, const wxString &newName = wxT("")); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + wxString GetSql(ctlTree *browser); + + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + wxString GetDataType() const + { + return dataType; + } + void iSetDataType(const wxString &s) + { + dataType = s; + } + wxString GetVisibility() const + { + return visibility; + } + void iSetVisibility(const wxString &s) + { + visibility = s; + } + + bool CanCreate() + { + return false; + } + +private: + wxString dataType, visibility; +}; + +class edbPackageVariableCollection : public edbPackageObjCollection +{ +public: + edbPackageVariableCollection(pgaFactory *factory, edbPackage *pkg); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/edbPrivateSynonym.h b/include/schema/edbPrivateSynonym.h new file mode 100644 index 0000000..038c585 --- /dev/null +++ b/include/schema/edbPrivateSynonym.h @@ -0,0 +1,101 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// edbPrivateSynonym.h PostgreSQL Table +// +////////////////////////////////////////////////////////////////////////// + +#ifndef EDBPRIVATESYNONYM_H +#define EDBPRIVATESYNONYM_H + +#include "schema/pgSchema.h" + + +class edbPrivateSynonymFactory : public pgSchemaObjFactory +{ +public: + edbPrivateSynonymFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + pgCollection *CreateCollection(pgObject *obj); +private: +}; +extern edbPrivateSynonymFactory edbPrivFactory; + +class edbPrivateSynonym : public pgSchemaObject +{ +public: + edbPrivateSynonym(pgSchema *newSchema, const wxString &newName = wxT("")); + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + virtual wxString GetSql(ctlTree *browser); + + bool DropObject(wxFrame *, ctlTree *, bool); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + wxString GetTranslatedMessage(int kindOfMessage) const; + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + bool GetSystemObject() const + { + return GetSchema()->GetSystemObject(); + } + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createpubsynonym"); + } + + wxString GetTargetType() const + { + return targetType; + } + void iSetTargetType(const wxString &s) + { + targetType = s; + } + wxString GetTargetSchema() const + { + return targetSchema; + } + void iSetTargetSchema(const wxString &s) + { + targetSchema = s; + } + wxString GetTargetObject() const + { + return targetObject; + } + void iSetTargetObject(const wxString &s) + { + targetObject = s; + } + +private: + wxString targetType, targetSchema, targetObject; + bool isPublic; +}; + +class edbPrivateSynonymCollection : public pgSchemaObjCollection +{ +public: + edbPrivateSynonymCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/edbResourceGroup.h b/include/schema/edbResourceGroup.h new file mode 100644 index 0000000..3fd2fcc --- /dev/null +++ b/include/schema/edbResourceGroup.h @@ -0,0 +1,71 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// edbResourceGroup.h - Resource Group (only used for PPAS 9.4) +// +////////////////////////////////////////////////////////////////////////// + +#ifndef EDBRESOURCEGROUP_H +#define EDBRESOURCEGROUP_H + +#include "pgServer.h" + +class edbResourceGroupFactory : public pgServerObjFactory +{ +public: + edbResourceGroupFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; + +extern edbResourceGroupFactory resourceGroupFactory; + + +// Class declarations +class edbResourceGroup : public pgServerObject +{ +public: + edbResourceGroup(const wxString &newName = wxT("")); + ~edbResourceGroup(); + wxString GetTranslatedMessage(int kindOfMessage) const; + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + double GetCPURateLimit() const + { + return cpuRateLimit; + } + void iSetCPURateLimit(const double b) + { + cpuRateLimit = b; + } + double GetDirtyRateLimit() const + { + return dirtyRateLimit; + } + void iSetDirtyRateLimit(const double b) + { + dirtyRateLimit = b; + } + +private: + double cpuRateLimit, dirtyRateLimit; +}; + +class edbResourceGroupCollection : public pgServerObjCollection +{ +public: + edbResourceGroupCollection(pgaFactory *factory, pgServer *sv); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/edbSynonym.h b/include/schema/edbSynonym.h new file mode 100644 index 0000000..b65ac0e --- /dev/null +++ b/include/schema/edbSynonym.h @@ -0,0 +1,102 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// edbSynonym.h - EnterpriseDB Synonym class +// +////////////////////////////////////////////////////////////////////////// + +#ifndef EDBSYNONYM_H +#define EDBSYNONYM_H + + +// App headers +#include "pgDatabase.h" + +class pgCollection; +class edbSynonymFactory : public pgDatabaseObjFactory +{ +public: + edbSynonymFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + pgCollection *CreateCollection(pgObject *obj); +}; +extern edbSynonymFactory synonymFactory; + + +class edbSynonym : public pgDatabaseObject +{ +public: + edbSynonym(const wxString &newName = wxT("")); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + bool GetSystemObject() const + { + return false; + } + wxString GetTargetType() const + { + return targetType; + } + void iSetTargetType(const wxString &s) + { + targetType = s; + } + wxString GetTargetSchema() const + { + return targetSchema; + } + void iSetTargetSchema(const wxString &s) + { + targetSchema = s; + } + wxString GetTargetObject() const + { + return targetObject; + } + void iSetTargetObject(const wxString &s) + { + targetObject = s; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createpubsynonym"); + } + +private: + wxString targetType, targetSchema, targetObject; +}; + +class edbSynonymCollection : public pgDatabaseObjCollection +{ +public: + edbSynonymCollection(pgaFactory *factory, pgDatabase *db); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + + +#endif diff --git a/include/schema/gpExtTable.h b/include/schema/gpExtTable.h new file mode 100644 index 0000000..fb89ebd --- /dev/null +++ b/include/schema/gpExtTable.h @@ -0,0 +1,91 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gpExtTable.h Greenplum External Table +// +////////////////////////////////////////////////////////////////////////// + +#ifndef gpExtTable_H +#define gpExtTable_H + +#include "pgSchema.h" + +class pgCollection; + +class gpExtTableFactory : public pgSchemaObjFactory +{ +public: + gpExtTableFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + pgCollection *CreateCollection(pgObject *obj); +}; +extern gpExtTableFactory extTableFactory; + + +class gpExtTable : public pgSchemaObject +{ +public: + gpExtTable(pgSchema *newSchema, const wxString &newName = wxT("")); + ~gpExtTable(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return !GetSystemObject() && pgSchemaObject::CanDrop(); + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + bool CanView() + { + return true; + } + bool WantDummyChild() + { + return false; + } + + wxMenu *GetNewMenu(); + wxString GetSql(ctlTree *browser); + wxString GetSelectSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + + void ShowHint(frmMain *form, bool force); + bool GetCanHint() + { + return true; + }; + + bool IsUpToDate(); + //wxString GetFormattedDefinition(); + +private: + wxString GetCols(ctlTree *browser, size_t indent, wxString &QMs, bool withQM); +}; + +class gpExtTableCollection : public pgSchemaObjCollection +{ +public: + gpExtTableCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/gpPartition.h b/include/schema/gpPartition.h new file mode 100644 index 0000000..b58a5f6 --- /dev/null +++ b/include/schema/gpPartition.h @@ -0,0 +1,100 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gpPartition.h Greenplum Partitioned Table Partition +// +////////////////////////////////////////////////////////////////////////// + +#ifndef gpPartition_H +#define gpPartition_H + +#include "pgSchema.h" +#include "pgTable.h" + + + +class gpPartitionFactory : public pgTableObjFactory +{ +public: + gpPartitionFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) ; + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + virtual void AppendMenu(wxMenu *menu); +}; + +extern gpPartitionFactory partitionFactory; + +class gpPartition : public pgTable +{ +public: + gpPartition(pgSchema *newSchema, const wxString &newName = wxT("")); + ~gpPartition(); + bool CanCreate(); + wxMenu *GetNewMenu(); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + wxString GetPartitionName() + { + return partitionname; + } + void iSetPartitionName(const wxString &pn) + { + partitionname = pn; + } + +private: + wxString partitionname; +}; + + +class gpPartitionObject : public pgTableObject +{ +public: + gpPartitionObject(gpPartition *newTable, pgaFactory &factory, const wxString &newName = wxT("")) + : pgTableObject(newTable, factory, newName) { }; + virtual gpPartition *GetTable() const + { + return dynamic_cast(table); + } + OID GetTableOid() const + { + return table->GetOid(); + } + wxString GetTableOidStr() const + { + return NumToStr(table->GetOid()) + wxT("::oid"); + } +}; + + +class gpPartitionCollection : public pgTableCollection +{ +public: + gpPartitionCollection(pgaFactory *factory, gpPartition *_table); + virtual bool CanCreate() + { + return false; + }; +}; + + +class gpPartitionObjCollection : public pgTableObjCollection +{ +public: + gpPartitionObjCollection(pgaFactory *factory, gpPartition *_table) + : pgTableObjCollection(factory, (pgTable *)_table ) { }; + virtual pgTable *GetTable() const + { + return table; + } + virtual bool CanCreate(); +}; + + + +#endif diff --git a/include/schema/gpResQueue.h b/include/schema/gpResQueue.h new file mode 100644 index 0000000..7851940 --- /dev/null +++ b/include/schema/gpResQueue.h @@ -0,0 +1,113 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gpResQueue.h - Greenplum Resource Queue +// +////////////////////////////////////////////////////////////////////////// + +#ifndef gpResQueue_H +#define gpResQueue_H + +#include "pgServer.h" + + + +class gpResQueueFactory : public pgServerObjFactory +{ +public: + gpResQueueFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + pgCollection *CreateCollection(pgObject *obj); +}; + +extern gpResQueueFactory resQueueFactory; + + + + +// Class declarations +class gpResQueue : public pgServerObject +{ + +protected: + gpResQueue(pgaFactory &factory, const wxString &newName = wxT("")); + +public: + gpResQueue(const wxString &newName = wxT("")); + wxString GetTranslatedMessage(int kindOfMessage) const; + int GetIconId(); + + double GetCountLimit() const + { + return countlimit; + } + double GetCostLimit() const + { + return costlimit; + } + bool GetOvercommit() const + { + return overcommit; + } + double GetIgnoreCostLimit() const + { + return ignorecostlimit; + } + + void iSetCountLimit(double newVal) + { + countlimit = newVal; + } + void iSetCostLimit(double newVal) + { + costlimit = newVal; + } + void iSetOvercommit(bool newVal) + { + overcommit = newVal; + } + void iSetIgnoreCostLimit(double newVal) + { + ignorecostlimit = newVal; + } + + // Tree object creation + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + // virtual methods + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } +private: + wxArrayString queuesIn; + double countlimit, costlimit, ignorecostlimit; + bool overcommit; + +}; + +class gpResQueueCollection : public pgServerObjCollection +{ +public: + gpResQueueCollection(pgaFactory *factory, pgServer *sv); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/module.mk b/include/schema/module.mk new file mode 100644 index 0000000..b36a8c5 --- /dev/null +++ b/include/schema/module.mk @@ -0,0 +1,68 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/schema/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/schema/edbPackage.h \ + include/schema/edbPackageFunction.h \ + include/schema/edbPackageVariable.h \ + include/schema/edbSynonym.h \ + include/schema/edbPrivateSynonym.h \ + include/schema/pgAggregate.h \ + include/schema/pgCatalogObject.h \ + include/schema/pgCast.h \ + include/schema/pgCheck.h \ + include/schema/pgCollation.h \ + include/schema/pgCollection.h \ + include/schema/pgColumn.h \ + include/schema/pgConstraints.h \ + include/schema/pgConversion.h \ + include/schema/pgDatabase.h \ + include/schema/pgDatatype.h \ + include/schema/pgDomain.h \ + include/schema/pgEventTrigger.h \ + include/schema/pgExtension.h \ + include/schema/pgForeignDataWrapper.h \ + include/schema/pgForeignKey.h \ + include/schema/pgForeignServer.h \ + include/schema/pgForeignTable.h \ + include/schema/pgFunction.h \ + include/schema/pgGroup.h \ + include/schema/pgIndex.h \ + include/schema/pgIndexConstraint.h \ + include/schema/pgLanguage.h \ + include/schema/pgObject.h \ + include/schema/pgOperator.h \ + include/schema/pgOperatorClass.h \ + include/schema/pgOperatorFamily.h \ + include/schema/pgRole.h \ + include/schema/pgRule.h \ + include/schema/pgSchema.h \ + include/schema/pgSequence.h \ + include/schema/pgServer.h \ + include/schema/pgTable.h \ + include/schema/pgTablespace.h \ + include/schema/pgTextSearchConfiguration.h \ + include/schema/pgTextSearchDictionary.h \ + include/schema/pgTextSearchParser.h \ + include/schema/pgTextSearchTemplate.h \ + include/schema/pgTrigger.h \ + include/schema/pgType.h \ + include/schema/pgUser.h \ + include/schema/pgUserMapping.h \ + include/schema/pgView.h \ + include/schema/gpExtTable.h \ + include/schema/gpResQueue.h \ + include/schema/gpPartition.h \ + include/schema/edbResourceGroup.h + +EXTRA_DIST += \ + include/schema/module.mk + diff --git a/include/schema/pgAggregate.h b/include/schema/pgAggregate.h new file mode 100644 index 0000000..8b87ce9 --- /dev/null +++ b/include/schema/pgAggregate.h @@ -0,0 +1,140 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgAggregate.h - Aggregate class +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGAGGREGATE_H +#define PGAGGREGATE_H + +#include "pgSchema.h" + +class pgCollection; +class pgAggregateFactory : public pgSchemaObjFactory +{ +public: + pgAggregateFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgAggregateFactory aggregateFactory; + +class pgAggregate : public pgSchemaObject +{ +public: + pgAggregate(pgSchema *newSchema, const wxString &newName = wxT("")); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + wxString GetQuotedFullName(); + wxString GetFullName(); + + bool CanDropCascaded() + { + return GetSchema()->GetMetaType() != PGM_CATALOG; + } + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + + + wxArrayString &GetInputTypesArray() + { + return inputTypes; + } + void iAddInputType(const wxString &s) + { + inputTypes.Add(s); + } + wxString GetInputTypesList(); + + wxString GetStateType() + { + return stateType; + } + void iSetStateType(const wxString &s) + { + stateType = s; + } + wxString GetFinalType() + { + return finalType; + } + void iSetFinalType(const wxString &s) + { + finalType = s; + } + wxString GetStateFunction() + { + return stateFunction; + } + void iSetStateFunction(const wxString &s) + { + stateFunction = s; + } + wxString GetFinalFunction() + { + return finalFunction; + } + void iSetFinalFunction(const wxString &s) + { + finalFunction = s; + } + wxString GetInitialCondition() + { + return initialCondition; + } + void iSetInitialCondition(const wxString &s) + { + initialCondition = s; + } + wxString GetSortOp() + { + return sortOp; + } + void iSetSortOp(const wxString &s) + { + sortOp = s; + } + wxString GetQuotedSortOp() + { + return quotedSortOp; + } + void iSetQuotedSortOp(const wxString &s) + { + quotedSortOp = s; + } + +private: + wxArrayString inputTypes; + wxString stateType, finalType, sortOp, quotedSortOp, + stateFunction, finalFunction, initialCondition; +}; + +class pgAggregateCollection : public pgSchemaObjCollection +{ +public: + pgAggregateCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgCast.h b/include/schema/pgCast.h new file mode 100644 index 0000000..3c988e2 --- /dev/null +++ b/include/schema/pgCast.h @@ -0,0 +1,153 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgCast.h PostgreSQL Cast +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGCAST_H +#define PGCAST_H + + +// App headers +#include "pgDatabase.h" + +class pgCollection; +class pgCastFactory : public pgDatabaseObjFactory +{ +public: + pgCastFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgCastFactory castFactory; + + +class pgCast : public pgDatabaseObject +{ +public: + pgCast(const wxString &newName = wxT("")); + ~pgCast(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + bool CanDropCascaded() + { + return true; + } + + bool GetSystemObject() const + { + return GetOid() <= GetConnection()->GetLastSystemOID(); + } + wxString GetSourceType() const + { + return sourceType; + } + void iSetSourceType(const wxString &s) + { + sourceType = s; + } + wxString GetTargetType() const + { + return targetType; + } + void iSetTargetType(const wxString &s) + { + targetType = s; + } + wxString GetSourceNamespace() const + { + return sourceNamespace; + } + void iSetSourceNamespace(const wxString &s) + { + sourceNamespace = s; + } + wxString GetTargetNamespace() const + { + return targetNamespace; + } + void iSetTargetNamespace(const wxString &s) + { + targetNamespace = s; + } + OID GetSourceTypeOid() const + { + return sourceTypeOid; + } + void iSetSourceTypeOid(const OID o) + { + sourceTypeOid = o; + } + OID GetTargetTypeOid() const + { + return targetTypeOid; + } + void iSetTargetTypeOid(const OID o) + { + targetTypeOid = o; + } + wxString GetCastFunction() const + { + return castFunction; + } + void iSetCastFunction(const wxString &s) + { + castFunction = s; + } + wxString GetCastNamespace() const + { + return castNamespace; + } + void iSetCastNamespace(const wxString &s) + { + castNamespace = s; + } + + wxString GetCastContext() const + { + return castContext; + } + void iSetCastContext(const wxString &s) + { + castContext = s; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString sourceType, sourceNamespace, targetType, targetNamespace, + castFunction, castContext, castNamespace; + OID sourceTypeOid, targetTypeOid; +}; + +class pgCastCollection : public pgDatabaseObjCollection +{ +public: + pgCastCollection(pgaFactory *factory, pgDatabase *db); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgCatalogObject.h b/include/schema/pgCatalogObject.h new file mode 100644 index 0000000..84db5cd --- /dev/null +++ b/include/schema/pgCatalogObject.h @@ -0,0 +1,75 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgCatalogObject.h - EnterpriseDB catalog class +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGCATALOGOBJECT_H +#define PGCATALOGOBJECT_H + +#include "pgSchema.h" + +class pgCatalogObjectFactory : public pgSchemaObjFactory +{ +public: + pgCatalogObjectFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) + { + return NULL; + }; + virtual pgObject *CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgCatalogObjectFactory catalogObjectFactory; + + +// Class declarations +class pgCatalogObject : public pgSchemaObject +{ +public: + pgCatalogObject(pgSchema *newSchema, const wxString &newName = wxT("")); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + bool CanCreate() + { + return false; + } + bool CanEdit() + { + return false; + } + +private: + +}; + +class pgCatalogObjectCollection : public pgSchemaObjCollection +{ +public: + pgCatalogObjectCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgCheck.h b/include/schema/pgCheck.h new file mode 100644 index 0000000..57b0f6a --- /dev/null +++ b/include/schema/pgCheck.h @@ -0,0 +1,142 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgCheck.h PostgreSQL Check +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGCHECK_H +#define PGCHECK_H + +// App headers +#include "pgTable.h" +#include "pgConstraints.h" + + + +class pgCheckFactory : public pgSchemaObjFactory +{ +public: + pgCheckFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + + int GetClosedIconId() + { + return closedId; + } + +protected: + int closedId; +}; +extern pgCheckFactory checkFactory; + + +class pgCheck : public pgSchemaObject +{ +public: + pgCheck(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgCheck(); + + int GetIconId(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + wxString GetObjectName() const + { + return objectName; + } + void iSetObjectName(const wxString &s) + { + objectName = s; + } + wxString GetObjectSchema() const + { + return objectSchema; + } + void iSetObjectSchema(const wxString &s) + { + objectSchema = s; + } + wxString GetObjectKind() const + { + return objectKind; + } + void iSetObjectKind(const wxString &s) + { + objectKind = s; + } + wxString GetDefinition() const + { + return definition; + } + void iSetDefinition(const wxString &s) + { + definition = s; + } + bool GetNoInherit() const + { + return noinherit; + } + void iSetNoInherit(const bool b) + { + noinherit = b; + } + bool GetValid() const + { + return valid; + } + void iSetValid(const bool b) + { + valid = b; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetConstraint(); + wxString GetSql(ctlTree *browser); + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-altertable"); + } + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + void Validate(frmMain *form); + +private: + wxString definition, objectKind, objectName, objectSchema; + bool noinherit, valid; +}; + +class pgCheckCollection : public pgSchemaObjCollection +{ +public: + pgCheckCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +class validateCheckFactory : public contextActionFactory +{ +public: + validateCheckFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif diff --git a/include/schema/pgCollation.h b/include/schema/pgCollation.h new file mode 100644 index 0000000..40593cb --- /dev/null +++ b/include/schema/pgCollation.h @@ -0,0 +1,88 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgCollation.h PostgreSQL Collation +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGCOLLATION_H +#define PGCOLLATION_H + +#include "pgSchema.h" + +class pgCollection; + +class pgCollationFactory : public pgSchemaObjFactory +{ +public: + pgCollationFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgCollationFactory collationFactory; + + +class pgCollation : public pgSchemaObject +{ +public: + pgCollation(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgCollation(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return GetSchema()->GetMetaType() != PGM_CATALOG; + } + + wxString GetLcCollate() const + { + return lccollate; + } + void iSetLcCollate(const wxString &s) + { + lccollate = s; + } + wxString GetLcCtype() const + { + return lcctype; + } + void iSetLcCtype(const wxString &s) + { + lcctype = s; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString lccollate, lcctype; +}; + +class pgCollationCollection : public pgSchemaObjCollection +{ +public: + pgCollationCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgCollection.h b/include/schema/pgCollection.h new file mode 100644 index 0000000..9cb886f --- /dev/null +++ b/include/schema/pgCollection.h @@ -0,0 +1,105 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgCollection.h - Simple object for use with 'collection' nodes +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGCOLLECTION_H +#define PGCOLLECTION_H + +// App headers +#include "pgAdmin3.h" +#include "pgObject.h" + +class pgServer; +class pgDatabase; +class pgaJob; +class pgSchema; +class pgForeignDataWrapper; +class pgForeignServer; +class pgUserMapping; + +// Class declarations +class pgCollection : public pgObject +{ +public: + pgCollection(pgaFactory *factory); + + virtual bool IsCollection() const + { + return true; + } + bool IsCollectionForType(const int type); + bool IsCollectionFor(pgObject *obj); + + pgServer *GetServer() const + { + return server; + } + pgDatabase *GetDatabase() const + { + return database; + } + pgSchema *GetSchema() const + { + return schema; + } + pgForeignDataWrapper *GetForeignDataWrapper() const + { + return fdw; + } + pgForeignServer *GetForeignServer() const + { + return fsrv; + } + pgUserMapping *GetUserMapping() const + { + return um; + } + pgaJob *GetJob() const + { + return job; + } + + int GetIconId(); + pgaFactory *GetItemFactory() + { + if (factory) return ((pgaCollectionFactory *)factory)->GetItemFactory(); + else return NULL; + } + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + void ShowList(const wxString &name, ctlTree *browser, ctlListView *properties); + void ShowList(ctlTree *browser, ctlListView *properties); + void UpdateChildCount(ctlTree *browser, int substract = 0); + pgObject *FindChild(ctlTree *browser, const int index); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return false; + } + bool HasReferences() + { + return false; + } + +protected: + pgServer *server; + pgDatabase *database; + pgSchema *schema; + pgaJob *job; + pgForeignDataWrapper *fdw; + pgForeignServer *fsrv; + pgUserMapping *um; +}; + + +#endif diff --git a/include/schema/pgColumn.h b/include/schema/pgColumn.h new file mode 100644 index 0000000..63c8a81 --- /dev/null +++ b/include/schema/pgColumn.h @@ -0,0 +1,318 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgColumn.h PostgreSQL Column +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGCOLUMN_H +#define PGCOLUMN_H + +// App headers +#include "pgTable.h" + +WX_DECLARE_STRING_HASH_MAP(wxString, inheritHashMap); + +class pgCollection; + +class pgColumnFactory : public pgTableObjFactory +{ +public: + pgColumnFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgColumnFactory columnFactory; + +class pgColumn : public pgTableObject +{ +public: + pgColumn(pgTable *newTable, const wxString &newName = wxT("")); + ~pgColumn(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + void ShowStatistics(frmMain *form, ctlListView *statistics); + void ShowDependencies(frmMain *form, ctlListView *Dependencies, const wxString &where = wxEmptyString); + void ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &where = wxEmptyString); + + wxString GetDefinition(); + + bool IsReferenced(); + + wxString GetRawTypename() const + { + return rawTypename; + } + void iSetRawTypename(const wxString &s) + { + rawTypename = s; + } + wxString GetVarTypename() const + { + return varTypename; + } + void iSetVarTypename(const wxString &s) + { + varTypename = s; + } + wxString GetQuotedTypename() const + { + return quotedTypename; + } + void iSetQuotedTypename(const wxString &s) + { + quotedTypename = s; + } + wxString GetDefault() const + { + return defaultVal; + } + void iSetDefault(const wxString &s) + { + defaultVal = s; + } + long GetColNumber() const + { + return colNumber; + } + void iSetColNumber(const long l) + { + colNumber = l; + } + long GetLength() const + { + return length; + } + void iSetLength(const long l) + { + length = l; + } + long GetPrecision() const + { + return precision; + } + void iSetPrecision(const long l) + { + precision = l; + } + long GetStatistics() const + { + return statistics; + } + void iSetStatistics(const long l) + { + statistics = l; + } + bool GetIsPK() const + { + return isPK; + } + bool GetIsFK() const + { + return isFK; + } + bool GetNotNull() const + { + return notNull; + } + void iSetNotNull(const bool b) + { + notNull = b; + } + bool GetIsArray() const + { + return isArray; + } + void iSetIsArray(const bool b) + { + isArray = b; + } + long GetTyplen() const + { + return typlen; + } + void iSetTyplen(const long l) + { + typlen = l; + } + long GetTypmod() const + { + return typmod; + } + void iSetTypmod(const long l) + { + typmod = l; + } + wxString GetTableName() const + { + return tableName; + } + void iSetTableName(const wxString &s) + { + tableName = s; + } + wxString GetQuotedFullTable() const + { + return quotedFullTable; + } + void iSetQuotedFullTable(const wxString &s) + { + quotedFullTable = s; + } + wxString GetDefaultStorage() const + { + return defaultStorage; + } + void iSetDefaultStorage(const wxString &s) + { + defaultStorage = s; + } + wxString GetStorage() const + { + return storage; + } + void iSetStorage(const wxString &s) + { + storage = s; + } + long GetInheritedCount() const + { + return inheritedCount; + } + void iSetInheritedCount(const long l) + { + inheritedCount = l; + } + wxString GetInheritedTableName() const + { + return inheritedTableName; + } + void iSetInheritedTableName(const wxString &s) + { + inheritedTableName = s; + } + bool GetIsLocal() const + { + return isLocal; + } + void iSetIsLocal(const bool b) + { + isLocal = b; + } + OID GetAttTypId() const + { + return attTypId; + } + void iSetAttTypId(const OID o) + { + attTypId = o; + } + long GetAttstattarget() const + { + return attstattarget; + } + void iSetAttstattarget(const long l) + { + attstattarget = l; + } + wxString GetSerialSequence() const + { + return serialSequence; + } + void iSetSerialSequence(const wxString &s) + { + serialSequence = s; + } + wxString GetSerialSchema() const + { + return serialSchema; + } + void iSetSerialSchema(const wxString &s) + { + serialSchema = s; + } + void iSetPkCols(const wxString &s) + { + pkCols = s; + } + void iSetIsFK(const bool b) + { + isFK = b; + } + wxArrayString &GetVariables() + { + return variables; + } + wxString GetCollation() const + { + return collation; + } + void iSetCollation(const wxString &s) + { + collation = s; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + bool GetSystemObject() const + { + return colNumber < 0; + } + wxString GetSql(ctlTree *browser); + wxString GetCommentSql(); + wxString GetStorageSql(); + wxString GetAttstattargetSql(); + wxString GetVariablesSql(); + wxString GetPrivileges(); + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-altertable"); + } + + virtual bool CanDrop() + { + return inheritedCount == 0 && pgSchemaObject::CanDrop() && GetSchema()->GetMetaType() != PGM_CATALOG && GetTable()->GetMetaType() != PGM_VIEW && GetTable()->GetMetaType() != GP_EXTTABLE; + } + virtual bool CanCreate() + { + return GetTable()->GetMetaType() != PGM_VIEW && GetTable()->GetMetaType() != GP_EXTTABLE && GetSchema()->GetMetaType() != PGM_CATALOG; + } + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return true; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString varTypename, quotedTypename, defaultVal, tableName, quotedFullTable, defaultStorage, storage, rawTypename; + wxString serialSequence, serialSchema, pkCols, inheritedTableName, collation; + long colNumber, length, precision, statistics, attstattarget; + long typlen, typmod, inheritedCount; + bool isPK, isFK, notNull, isArray, isLocal; + OID attTypId; + int isReferenced; + wxArrayString variables; +}; + +class pgColumnCollection : public pgTableObjCollection +{ +public: + pgColumnCollection(pgaFactory *factory, pgTable *tbl); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgConstraints.h b/include/schema/pgConstraints.h new file mode 100644 index 0000000..c38b2dc --- /dev/null +++ b/include/schema/pgConstraints.h @@ -0,0 +1,56 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgConstraints.h - Constraint collection +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __CONSTRAINTS_H +#define __CONSTRAINTS_H + +#include "pgTable.h" +#include "pgDomain.h" + + +class pgConstraintCollection : public pgSchemaObjCollection +{ +public: + pgConstraintCollection(pgaFactory *factory, pgSchema *schema); + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-altertable"); + } + bool CanCreate() + { + return true; + } + wxMenu *GetNewMenu(); + + void ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane); + wxString GetTranslatedMessage(int kindOfMessage) const; + + pgTable *table; + pgDomain *domain; +}; + + +class pgConstraintFactory : public pgSchemaObjFactory +{ +public: + pgConstraintFactory(); + virtual dlgProperty *CreateDialog(class frmMain *, class pgObject *, class pgObject *) + { + return 0; + } + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgConstraintFactory constraintFactory; +extern pgaCollectionFactory constraintCollectionFactory; + +#endif diff --git a/include/schema/pgConversion.h b/include/schema/pgConversion.h new file mode 100644 index 0000000..a6e3011 --- /dev/null +++ b/include/schema/pgConversion.h @@ -0,0 +1,113 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgConversion.h PostgreSQL Conversion +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGCONVERSION_H +#define PGCONVERSION_H + +#include "pgSchema.h" + +class pgCollection; + +class pgConversionFactory : public pgSchemaObjFactory +{ +public: + pgConversionFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgConversionFactory conversionFactory; + + +class pgConversion : public pgSchemaObject +{ +public: + pgConversion(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgConversion(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return GetSchema()->GetMetaType() != PGM_CATALOG; + } + + wxString GetProc() const + { + return proc; + } + void iSetProc(const wxString &s) + { + proc = s; + } + wxString GetProcNamespace() const + { + return procNamespace; + } + void iSetProcNamespace(const wxString &s) + { + procNamespace = s; + } + wxString GetForEncoding() const + { + return forEncoding; + } + void iSetForEncoding(const wxString &s) + { + forEncoding = s; + } + wxString GetToEncoding() const + { + return toEncoding; + } + void iSetToEncoding(const wxString &s) + { + toEncoding = s; + } + bool GetDefaultConversion() const + { + return defaultConversion; + } + void iSetDefaultConversion(const bool b) + { + defaultConversion = b; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString proc, procNamespace, forEncoding, toEncoding; + bool defaultConversion; +}; + +class pgConversionCollection : public pgSchemaObjCollection +{ +public: + pgConversionCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgDatabase.h b/include/schema/pgDatabase.h new file mode 100644 index 0000000..dfc9fda --- /dev/null +++ b/include/schema/pgDatabase.h @@ -0,0 +1,360 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgDatabase.h - PostgreSQL Database +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGDATABASE_H +#define PGDATABASE_H + +#include "pgServer.h" + +class pgDatabaseFactory : public pgServerObjFactory +{ +public: + pgDatabaseFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + + int GetClosedIconId() + { + return WantSmallIcon() ? smallClosedId : closedId; + } +protected: + int closedId, smallClosedId; +}; + +extern pgDatabaseFactory databaseFactory; + + +// Class declarations +class pgDatabase : public pgServerObject +{ +public: + pgDatabase(const wxString &newName = wxT("")); + ~pgDatabase(); + wxString GetTranslatedMessage(int kindOfMessage) const; + int GetIconId(); + + static wxString GetDefaultPrivileges(const wxChar &cType, wxString strDefPrivs, const wxString &strSchema); + + pgDatabase *GetDatabase() const + { + return (pgDatabase *)this; + } + bool BackendMinimumVersion(int major, int minor) + { + return connection()->BackendMinimumVersion(major, minor); + } + bool BackendMinimumVersion(int major, int minor, int patch) + { + return connection()->BackendMinimumVersion(major, minor, patch); + } + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + void ShowHint(frmMain *form, bool force); + void ShowStatistics(frmMain *form, ctlListView *statistics); + + pgSet *ExecuteSet(const wxString &sql); + wxString ExecuteScalar(const wxString &sql); + bool ExecuteVoid(const wxString &sql, bool reportError = true); + void UpdateDefaultSchema(); + + pgConn *CreateConn(const wxString &applicationname) + { + return server->CreateConn(GetName(), GetOid(), applicationname); + } + + wxString GetPrettyOption() const + { + return prettyOption; + } + + bool GetCreatePrivilege() const + { + return createPrivilege; + } + void iSetCreatePrivilege(const bool b) + { + createPrivilege = b; + } + + // Default Privileges on ALL + wxString GetDefPrivsOnTables() + { + return m_defPrivsOnTables; + } + wxString GetDefPrivsOnSequences() + { + return m_defPrivsOnSeqs; + } + wxString GetDefPrivsOnFunctions() + { + return m_defPrivsOnFuncs; + } + wxString GetDefPrivsOnTypes() + { + return m_defPrivsOnTypes; + } + + wxString GetPath() const + { + return path; + }; + void iSetPath(const wxString &newVal) + { + path = newVal; + } + wxString GetTablespace() const + { + return tablespace; + }; + void iSetTablespace(const wxString &newVal) + { + tablespace = newVal; + } + OID GetTablespaceOid() const + { + return tablespaceOid; + }; + void iSetTablespaceOid(const OID newVal) + { + tablespaceOid = newVal; + } + wxString GetDefaultTablespace() const + { + return defaultTablespace; + }; + void iSetDefaultTablespace(const wxString &newVal) + { + defaultTablespace = newVal; + } + wxString GetEncoding() const + { + return encoding; + } + void iSetEncoding(const wxString &newVal) + { + encoding = newVal; + } + wxString GetSchemaRestriction() + { + return schemaRestriction; + } + void iSetSchemaRestriction(const wxString &s) + { + schemaRestriction = s; + } + wxString GetCollate() const + { + return collate; + } + void iSetCollate( const wxString &newVal) + { + collate = newVal; + } + wxString GetCType() const + { + return ctype; + } + void iSetCType( const wxString &newVal) + { + ctype = newVal; + } + long GetConnectionLimit() + { + return connectionLimit; + } + void iSetConnectionLimit(long newVal) + { + connectionLimit = newVal; + } + + wxArrayString &GetVariables() + { + return variables; + } + bool GetAllowConnections() const + { + return allowConnections; + } + void iSetAllowConnections(bool newVal) + { + allowConnections = newVal; + } + wxString GetSearchPath() const + { + return searchPath; + } + wxString GetSchemaPrefix(const wxString &schemaname) const; + wxString GetQuotedSchemaPrefix(const wxString &schemaname) const; + wxString GetDefaultSchema() + { + return defaultSchema; + }; + bool GetConnected() + { + return connected; + } + bool GetSystemObject() const; + long GetMissingFKs() const + { + return missingFKs; + } + wxArrayString GetSlonyClusters(ctlTree *browser); + + + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + bool CanCreate(); + bool CanMaintenance() + { + return connected; + } + bool CanBackup() + { + return connected; + } + bool CanRestore() + { + return connected; + } + bool GetCanHint(); + bool RequireDropConfirm() + { + return true; + } + pgConn *connection(); + int Connect(); + void Disconnect(); + void CheckAlive(); + void AppendSchemaChange(const wxString &sql); + wxString GetSchemaChanges() + { + return schemaChanges; + } + void ClearSchemaChanges() + { + schemaChanges = wxEmptyString; + } + + wxMenu *GetNewMenu(); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + + bool CanDebugPlpgsql(); + bool CanDebugEdbspl(); + +private: + pgConn *conn; + bool connected; + bool useServerConnection; + wxString searchPath, path, tablespace, defaultTablespace, encoding, collate, ctype; + wxString prettyOption, defaultSchema; + bool allowConnections, createPrivilege; + long missingFKs; + long connectionLimit; + wxArrayString variables; + + wxString schemaChanges; + wxString schemaRestriction; + wxString m_defPrivsOnTables, m_defPrivsOnSeqs, m_defPrivsOnFuncs, m_defPrivsOnTypes; + + int canDebugPlpgsql, canDebugEdbspl; + + OID tablespaceOid; +}; + +class pgDatabaseCollection : public pgServerObjCollection +{ +public: + pgDatabaseCollection(pgaFactory *factory, pgServer *sv); + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowStatistics(frmMain *form, ctlListView *statistics); +}; + + +//////////////////////////////////////////////// + +class pgDatabaseObjFactory : public pgServerObjFactory +{ +public: + pgDatabaseObjFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm = 0) + : pgServerObjFactory(tn, ns, nls, img, imgSm) {} + virtual pgCollection *CreateCollection(pgObject *obj); +}; + +class disconnectDatabaseFactory : public contextActionFactory +{ +public: + disconnectDatabaseFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +// Object that lives in a database +class pgDatabaseObject : public pgObject +{ +public: + pgDatabaseObject(pgaFactory &factory, const wxString &newName = wxEmptyString) : pgObject(factory, newName) {} + pgDatabaseObject(int newType, const wxString &newName) : pgObject(newType, newName) {} + + void iSetDatabase(pgDatabase *newDatabase) + { + database = newDatabase; + } + pgDatabase *GetDatabase() const + { + return database; + } + pgServer *GetServer() const; + + void DisplayStatistics(ctlListView *statistics, const wxString &query); + + // compiles a prefix from the schema name with '.', if necessary + wxString GetSchemaPrefix(const wxString &schemaname) const; + wxString GetQuotedSchemaPrefix(const wxString &schemaname) const; + + bool CanDrop(); + bool CanEdit() + { + return true; + } + bool CanCreate(); + +protected: + pgDatabase *database; +}; + + +// collection of pgDatabaseObject +class pgDatabaseObjCollection : public pgCollection +{ +public: + pgDatabaseObjCollection(pgaFactory *factory, pgDatabase *db); + bool CanCreate(); +}; + + + +#endif diff --git a/include/schema/pgDatatype.h b/include/schema/pgDatatype.h new file mode 100644 index 0000000..78efa4a --- /dev/null +++ b/include/schema/pgDatatype.h @@ -0,0 +1,113 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgDatatype.h - PostgreSQL Datatypes +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __DATATYPE_INC +#define __DATATYPE_INC + +#include + +// App headers + +#include "db/pgSet.h" +#include "db/pgConn.h" + +class pgDatabase; + +class pgDatatype +{ +public: + pgDatatype(const wxString &nsp, const wxString &typname, bool isduplicate, long numdims = 0, long typmod = -1); + wxString Name() const + { + return name; + }; + wxString LengthString() const + { + return length; + } + wxString Array() const + { + return array; + } + wxString FullName() const; + wxString QuotedFullName() const; + wxString GetSchemaPrefix(pgDatabase *db) const; + wxString GetQuotedSchemaPrefix(pgDatabase *db) const; + long Length() const + { + return len; + } + long Precision() const + { + return prec; + } + static long GetTypmod(const wxString &name, const wxString &len, const wxString &prec); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString schema; + wxString name; + wxString length; + wxString array; + long len, prec; + bool needSchema; +}; + + +class DatatypeReader +{ +public: + DatatypeReader(pgDatabase *db, bool withDomains = true, bool addSerials = false); + DatatypeReader(pgDatabase *db, const wxString &condition, bool addSerials = false); + ~DatatypeReader() + { + if (set) delete set; + } + bool HasMore() const + { + return set && !set->Eof(); + } + void MoveNext() + { + if (set) set->MoveNext(); + } + + bool IsDomain() const; + bool IsVarlen() const; + bool MaySpecifyLength() const; + bool MaySpecifyPrecision() const; + pgDatatype GetDatatype() const; + wxString GetTypename() const; + wxString GetSchema() const; + wxString GetSchemaPrefix() const; + wxString GetQuotedSchemaPrefix() const; + wxString GetOidStr() const; + OID GetOid() const; + +private: + pgSet *set; + pgDatabase *database; + void init(pgDatabase *db, const wxString &condition, bool addSerials = false); +}; + +#endif diff --git a/include/schema/pgDomain.h b/include/schema/pgDomain.h new file mode 100644 index 0000000..e8a5f31 --- /dev/null +++ b/include/schema/pgDomain.h @@ -0,0 +1,226 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgDomain.h PostgreSQL Domain +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGDOMAIN_H +#define PGDOMAIN_H + +#include "pgSchema.h" + +class pgCollection; + +class pgDomainFactory : public pgSchemaObjFactory +{ +public: + pgDomainFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgDomainFactory domainFactory; + + +class pgDomain : public pgSchemaObject +{ +public: + pgDomain(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgDomain(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return GetSchema()->GetMetaType() != PGM_CATALOG; + } + + wxString GetBasetype() const + { + return basetype; + } + void iSetBasetype(const wxString &s) + { + basetype = s; + } + wxString GetQuotedBasetype() const + { + return quotedBasetype; + } + void iSetQuotedBasetype(const wxString &s) + { + quotedBasetype = s; + } + wxString GetCollation() const + { + return collation; + } + void iSetCollation(const wxString &s) + { + collation = s; + } + wxString GetQuotedCollation() const + { + return quotedCollation; + } + void iSetQuotedCollation(const wxString &s) + { + quotedCollation = s; + } + void iSetIsDup(bool b) + { + isDup = b; + } + long GetLength() const + { + return length; + } + void iSetLength(long l) + { + length = l; + } + long GetPrecision() const + { + return precision; + } + void iSetPrecision(long l) + { + precision = l; + } + wxString GetCheck() const + { + return check; + } + void iSetCheck(const wxString &s) + { + check = s; + } + wxString GetDefault() const + { + return defaultVal; + } + void iSetDefault(const wxString &s) + { + defaultVal = s; + } + bool GetNotNull() const + { + return notNull; + } + void iSetNotNull(bool b) + { + notNull = b; + } + long GetDimensions() const + { + return dimensions; + } + void iSetDimensions(long l) + { + dimensions = l; + } + wxString GetDelimiter() const + { + return delimiter; + } + void iSetDelimiter(const wxString &s) + { + delimiter = s; + } + OID GetBasetypeOid() const + { + return basetypeOid; + } + void iSetBasetypeOid(OID d) + { + basetypeOid = d; + } + OID GetCollationOid() const + { + return collationOid; + } + void iSetCollationOid(OID d) + { + collationOid = d; + } + long GetTyplen() const + { + return typlen; + } + void iSetTyplen(const long l) + { + typlen = l; + } + long GetTypmod() const + { + return typmod; + } + void iSetTypmod(const long l) + { + typmod = l; + } + bool GetValid() const + { + return constraintvalid; + } + void iSetValid(const bool b) + { + constraintvalid = b; + } + wxString GetCheckConstraintName() const + { + return checkconstraintname; + } + void iSetCheckConstraintName(const wxString &s) + { + checkconstraintname = s; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + wxMenu *GetNewMenu(); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + void Validate(frmMain *form); + +private: + wxString basetype, quotedBasetype, defaultVal, delimiter, check, collation, quotedCollation, checkconstraintname; + long length, precision, dimensions; + long typlen, typmod; + bool notNull, isDup, constraintvalid; + OID basetypeOid, collationOid; +}; + +class pgDomainCollection : public pgSchemaObjCollection +{ +public: + pgDomainCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +class validateDomainCheckFactory : public contextActionFactory +{ +public: + validateDomainCheckFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif diff --git a/include/schema/pgEventTrigger.h b/include/schema/pgEventTrigger.h new file mode 100644 index 0000000..2293ea4 --- /dev/null +++ b/include/schema/pgEventTrigger.h @@ -0,0 +1,154 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgEventTrigger.h PostgreSQL Event Trigger +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGEVENTTRIGGER_H +#define PGEVENTTRIGGER_H + +#include "pgDatabase.h" + +class pgCollection; +class pgFunction; + +class pgEventTriggerFactory : public pgDatabaseObjFactory +{ +public: + pgEventTriggerFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + virtual ~pgEventTriggerFactory() {}; + + int GetClosedIconId() + { + return closedId; + } + +protected: + int closedId; +}; + +extern pgEventTriggerFactory eventTriggerFactory; + +class pgEventTrigger : public pgDatabaseObject +{ +public: + pgEventTrigger(const wxString &newName = wxT("")); + ~pgEventTrigger(); + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + bool IsUpToDate(); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + int GetIconId(); + + wxString GetFunction() const + { + return function; + } + void iSetFunction(const wxString &s) + { + function = s ; + } + wxString GetWhen() const + { + return when; + } + void iSetWhen(const wxString &s) + { + when = s; + } + OID GetFunctionOid() const + { + return functionOid; + } + void iSetFunctionOid(const OID d) + { + functionOid = d; + } + OID GetSchemaOid() const + { + return schemaOid; + } + void iSetSchemaOid(const OID d) + { + schemaOid = d; + } + wxString GetSource() const + { + return source; + } + void iSetSource(const wxString &s) + { + source = s; + } + wxString GetLanguage() const + { + return language; + } + void iSetLanguage(const wxString &s) + { + language = s; + } + wxString GetEventName() const + { + return eventName; + } + wxString GetEnableStatus() const + { + return enableStatus; + } + void iSetEnableStatus(const wxString &s) + { + enableStatus = s; + } + void iSetEventName(const wxString &s) + { + eventName = s; + } + + bool GetEnabled() const + { + return enabled; + } + void iSetEnabled(const bool b) + { + enabled = b; + } + void SetEnabled(ctlTree *browser, const bool b); + void SetDirty(); + +private: + wxString function, when, language, source, eventName, enableStatus; + OID functionOid, schemaOid; + bool enabled; + pgFunction *eventTriggerFunction; + pgSchema *eventTriggerFunctionSchema; +}; + +class pgEventTriggerCollection : public pgDatabaseObjCollection +{ +public: + pgEventTriggerCollection(pgaFactory *factory, pgDatabase *db); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +class enabledisableEventTriggerFactory : public contextActionFactory +{ +public: + enabledisableEventTriggerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); + bool CheckChecked(pgObject *obj); +}; + +#endif \ No newline at end of file diff --git a/include/schema/pgExtension.h b/include/schema/pgExtension.h new file mode 100644 index 0000000..8f2a649 --- /dev/null +++ b/include/schema/pgExtension.h @@ -0,0 +1,94 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgExtension.h PostgreSQL Extension +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGEXTENSION_H +#define PGEXTENSION_H + +#include "pgDatabase.h" + +class pgCollection; +class pgExtensionFactory : public pgDatabaseObjFactory +{ +public: + pgExtensionFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgExtensionFactory extensionFactory; + +class pgExtension : public pgDatabaseObject +{ +public: + pgExtension(const wxString &newName = wxT("")); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return true; + } + + wxString GetSchemaStr() const + { + return schema; + } + void iSetSchemaStr(const wxString &s) + { + schema = s; + } + wxString GetVersion() const + { + return version; + } + void iSetVersion(const wxString &s) + { + version = s; + } + bool GetIsRelocatable() const + { + return isrelocatable; + } + void iSetIsRelocatable(const bool b) + { + isrelocatable = b; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return false; + } + bool HasReferences() + { + return false; + } + +private: + wxString schema, version; + bool isrelocatable; +}; + +class pgExtensionCollection : public pgDatabaseObjCollection +{ +public: + pgExtensionCollection(pgaFactory *factory, pgDatabase *db); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgForeignDataWrapper.h b/include/schema/pgForeignDataWrapper.h new file mode 100644 index 0000000..ebc59ce --- /dev/null +++ b/include/schema/pgForeignDataWrapper.h @@ -0,0 +1,152 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgForeignDataWrapper.h PostgreSQL Foreign Data Wrapper +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGFOREIGNDATAWRAPPER_H +#define PGFOREIGNDATAWRAPPER_H + +#include "pgDatabase.h" + +class pgCollection; +class pgForeignDataWrapperFactory : public pgDatabaseObjFactory +{ +public: + pgForeignDataWrapperFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgForeignDataWrapperFactory foreignDataWrapperFactory; + +class pgForeignDataWrapper : public pgDatabaseObject +{ +public: + pgForeignDataWrapper(const wxString &newName = wxT("")); + wxString GetTranslatedMessage(int kindOfMessage) const; + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return true; + } + wxMenu *GetNewMenu(); + + wxString GetHandlerProc() const + { + return handlerProc; + } + void iSetHandlerProc(const wxString &s) + { + handlerProc = s; + } + wxString GetValidatorProc() const + { + return validatorProc; + } + void iSetValidatorProc(const wxString &s) + { + validatorProc = s; + } + wxString GetOptions() const + { + return options; + } + wxString GetCreateOptions(); + void iSetOptions(const wxString &s) + { + options = s; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString handlerProc, validatorProc, options; +}; + +class pgForeignDataWrapperObjFactory : public pgDatabaseObjFactory +{ +public: + pgForeignDataWrapperObjFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm = 0) + : pgDatabaseObjFactory(tn, ns, nls, img, imgSm) {} + virtual pgCollection *CreateCollection(pgObject *obj); +}; + + +class pgForeignDataWrapperCollection : public pgDatabaseObjCollection +{ +public: + pgForeignDataWrapperCollection(pgaFactory *factory, pgDatabase *db); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + + +// Object that lives in a foreign data wrapper +class pgForeignDataWrapperObject : public pgDatabaseObject +{ +public: + pgForeignDataWrapperObject(pgForeignDataWrapper *newForeignDataWrapper, pgaFactory &factory, const wxString &newName = wxEmptyString) : pgDatabaseObject(factory, newName) + { + SetForeignDataWrapper(newForeignDataWrapper); + } + pgForeignDataWrapperObject(pgForeignDataWrapper *newForeignDataWrapper, int newType, const wxString &newName = wxT("")) : pgDatabaseObject(newType, newName) + { + SetForeignDataWrapper(newForeignDataWrapper); + } + + bool CanDrop(); + bool CanEdit() + { + return true; + } + bool CanCreate(); + + void SetForeignDataWrapper(pgForeignDataWrapper *newForeignDataWrapper); + virtual pgForeignDataWrapper *GetForeignDataWrapper() const + { + return fdw; + } + pgSet *ExecuteSet(const wxString &sql); + wxString ExecuteScalar(const wxString &sql); + bool ExecuteVoid(const wxString &sql); + + +protected: + virtual void SetContextInfo(frmMain *form); + + pgForeignDataWrapper *fdw; +}; + + + +// collection of pgForeignDataWrapperObject +class pgForeignDataWrapperObjCollection : public pgCollection +{ +public: + pgForeignDataWrapperObjCollection(pgaFactory *factory, pgForeignDataWrapper *newfdw); + wxString GetTranslatedMessage(int kindOfMessage) const; + virtual bool CanCreate(); +}; + +#endif diff --git a/include/schema/pgForeignKey.h b/include/schema/pgForeignKey.h new file mode 100644 index 0000000..a55ca51 --- /dev/null +++ b/include/schema/pgForeignKey.h @@ -0,0 +1,225 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgForeignKey.h PostgreSQL ForeignKey +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGFOREIGNKEY_H +#define PGFOREIGNKEY_H + +#include "pgIndex.h" + +class pgForeignKeyFactory : public pgSchemaObjFactory +{ +public: + pgForeignKeyFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + + int GetClosedIconId() + { + return closedId; + } + +protected: + int closedId; +}; +extern pgForeignKeyFactory foreignKeyFactory; + +class pgForeignKey : public pgSchemaObject +{ +public: + pgForeignKey(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgForeignKey(); + + int GetIconId(); + + wxString GetDefinition(); + wxString GetFullName(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + wxString GetOnUpdate() const + { + return onUpdate; + } + void iSetOnUpdate(const wxString &s) + { + onUpdate = s; + } + wxString GetOnDelete() const + { + return onDelete; + } + void iSetOnDelete(const wxString &s) + { + onDelete = s; + } + + wxString GetFkTable() const + { + return fkTable; + } + void iSetFkTable(const wxString &s) + { + fkTable = s; + } + wxString GetFkSchema() const + { + return fkSchema; + } + void iSetFkSchema(const wxString &s) + { + fkSchema = s; + } + wxString GetReferences() const + { + return references; + } + void iSetReferences(const wxString &s) + { + references = s; + } + wxString GetRefSchema() const + { + return refSchema; + } + void iSetRefSchema(const wxString &s) + { + refSchema = s; + } + wxString GetConkey() const + { + return conkey; + } + void iSetConkey(const wxString &s) + { + conkey = s; + } + wxString GetConfkey() const + { + return confkey; + } + void iSetConfkey(const wxString &s) + { + confkey = s; + } + bool GetDeferrable() const + { + return deferrable; + } + void iSetDeferrable(const bool b) + { + deferrable = b; + } + bool GetDeferred() const + { + return deferred; + } + void iSetDeferred(const bool b) + { + deferred = b; + } + wxString GetMatch() const + { + return match; + } + void iSetMatch(const wxString &s) + { + match = s; + } + bool GetValid() const + { + return valid; + } + void iSetValid(const bool b) + { + valid = b; + } + wxString GetRelTableOidStr() const + { + return NumToStr(relTableOid) + wxT("::oid"); + } + OID GetRelTableOid() const + { + return relTableOid; + } + void iSetRelTableOid(const OID d) + { + relTableOid = d; + } + + wxString GetFkColumns() const + { + return fkColumns; + } + wxString GetRefColumns() const + { + return refColumns; + } + wxString GetQuotedFkColumns() const + { + return quotedFkColumns; + } + wxString GetQuotedRefColumns() const + { + return quotedRefColumns; + } + wxString GetCoveringIndex() const + { + return coveringIndex; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetConstraint(); + wxString GetSql(ctlTree *browser); + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-altertable"); + } + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + void Validate(frmMain *form); + +private: + wxString onUpdate, onDelete, conkey, confkey, + fkTable, fkSchema, references, refSchema; + wxString fkColumns, refColumns, quotedFkColumns, quotedRefColumns, coveringIndex, match; + bool deferrable, deferred, valid; + OID relTableOid; +}; + +class pgForeignKeyCollection : public pgSchemaObjCollection +{ +public: + pgForeignKeyCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +class validateForeignKeyFactory : public contextActionFactory +{ +public: + validateForeignKeyFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif diff --git a/include/schema/pgForeignServer.h b/include/schema/pgForeignServer.h new file mode 100644 index 0000000..52c3571 --- /dev/null +++ b/include/schema/pgForeignServer.h @@ -0,0 +1,145 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgForeignServer.h PostgreSQL Foreign Server +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGFOREIGNSERVER_H +#define PGFOREIGNSERVER_H + +#include "pgForeignDataWrapper.h" + +class pgCollection; +class pgForeignServerFactory : public pgForeignDataWrapperObjFactory +{ +public: + pgForeignServerFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); +}; +extern pgForeignServerFactory foreignServerFactory; + + +class pgForeignServer : public pgForeignDataWrapperObject +{ +public: + pgForeignServer(pgForeignDataWrapper *newForeignDataWrapper, const wxString &newName = wxT("")); + wxString GetTranslatedMessage(int kindOfMessage) const; + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + wxMenu *GetNewMenu(); + bool CanDropCascaded() + { + return true; + } + bool CanCreate() + { + return true; + } + wxString GetType() const + { + return type; + } + void iSetType(const wxString &s) + { + type = s; + } + wxString GetVersion() const + { + return version; + } + void iSetVersion(const wxString &s) + { + version = s; + } + wxString GetOptions() const + { + return options; + } + wxString GetCreateOptions(); + void iSetOptions(const wxString &s) + { + options = s; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString type, version, options; +}; + + +class pgForeignServerObjFactory : public pgForeignDataWrapperObjFactory +{ +public: + pgForeignServerObjFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm = 0) + : pgForeignDataWrapperObjFactory(tn, ns, nls, img, imgSm) {} + virtual pgCollection *CreateCollection(pgObject *obj); +}; + + +// Object that lives in a foreign server +class pgForeignServerObject : public pgForeignDataWrapperObject +{ +public: + pgForeignServerObject(pgForeignServer *newForeignServer, pgaFactory &factory, const wxString &newName = wxEmptyString) : pgForeignDataWrapperObject(newForeignServer->GetForeignDataWrapper(), factory, newName) + { + SetForeignServer(newForeignServer); + } + pgForeignServerObject(pgForeignServer *newForeignServer, int newType, const wxString &newName = wxT("")) : pgForeignDataWrapperObject(newForeignServer->GetForeignDataWrapper(), newType, newName) + { + SetForeignServer(newForeignServer); + } + + bool CanDrop(); + bool CanEdit() + { + return true; + } + bool CanCreate(); + + void SetForeignServer(pgForeignServer *newForeignServer); + virtual pgForeignServer *GetForeignServer() const + { + return srv; + } + pgSet *ExecuteSet(const wxString &sql); + wxString ExecuteScalar(const wxString &sql); + bool ExecuteVoid(const wxString &sql); + + +protected: + virtual void SetContextInfo(frmMain *form); + + pgForeignServer *srv; +}; + + +class pgForeignServerObjCollection : public pgCollection +{ +public: + pgForeignServerObjCollection(pgaFactory *factory, pgForeignServer *newsrv); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgForeignTable.h b/include/schema/pgForeignTable.h new file mode 100644 index 0000000..26210aa --- /dev/null +++ b/include/schema/pgForeignTable.h @@ -0,0 +1,105 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgForeignTable.h PostgreSQL Foreign Table +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGFOREIGNTABLE_H +#define PGFOREIGNTABLE_H + +#include "pgSchema.h" + +class pgForeignTableFactory : public pgSchemaObjFactory +{ +public: + pgForeignTableFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgForeignTableFactory foreignTableFactory; + +class pgForeignTable : public pgSchemaObject +{ +public: + pgForeignTable(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgForeignTable(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return !GetSystemObject() && pgSchemaObject::CanDrop(); + } + + wxString GetForeignServer() const + { + return foreignserver; + } + void iSetForeignServer(const wxString &s) + { + foreignserver = s; + } + const wxArrayString &GetOptionsArray() + { + return optionsArray; + } + wxString GetOptionsList() const + { + return options; + } + void iSetOptions(const wxString &s); + const wxArrayString &GetTypesArray() + { + return typesArray; + } + wxString GetTypesList() const + { + return typesList; + } + wxString GetQuotedTypesList() const + { + return quotedTypesList; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + wxString GetSelectSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + bool CanView() + { + return true; + } + +private: + wxString foreignserver, options, typesList, quotedTypesList; + wxArrayString typesArray; + wxArrayString optionsArray; +}; + +class pgForeignTableCollection : public pgSchemaObjCollection +{ +public: + pgForeignTableCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgFunction.h b/include/schema/pgFunction.h new file mode 100644 index 0000000..31f3c08 --- /dev/null +++ b/include/schema/pgFunction.h @@ -0,0 +1,355 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgFunction.h PostgreSQL Function +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGFUNCTION_H +#define PGFUNCTION_H + +#include "pgSchema.h" + +class pgFunction; + +class pgFunctionFactory : public pgSchemaObjFactory +{ +public: + pgFunctionFactory(const wxChar *tn = 0, const wxChar *ns = 0, const wxChar *nls = 0, wxImage *img = 0); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + + pgFunction *AppendFunctions(pgObject *obj, pgSchema *schema, ctlTree *browser, const wxString &restriction); +}; + + +extern pgFunctionFactory functionFactory; + +class pgFunction : public pgSchemaObject +{ +public: + pgFunction(pgSchema *newSchema, const wxString &newName = wxT("")); + pgFunction(pgSchema *newSchema, pgaFactory &factory, const wxString &newName = wxT("")); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return GetSchema()->GetMetaType() != PGM_CATALOG; + } + void ShowStatistics(frmMain *form, ctlListView *statistics); + + virtual bool GetIsProcedure() const + { + return false; + } + + wxString GetFullName(); + wxString GetArgListWithNames(bool multiline = false); + wxString GetArgSigList(const bool forScript = false); + + wxArrayString &GetArgNamesArray() + { + return argNamesArray; + } + void iAddArgName(const wxString &s) + { + argNamesArray.Add(s); + } + wxArrayString &GetArgTypesArray() + { + return argTypesArray; + } + void iAddArgType(const wxString &s) + { + argTypesArray.Add(s); + } + wxArrayString &GetArgModesArray() + { + return argModesArray; + } + void iAddArgMode(const wxString &s) + { + argModesArray.Add(s); + } + wxArrayString &GetArgDefsArray() + { + return argDefsArray; + } + void iAddArgDef(const wxString &s) + { + argDefsArray.Add(s); + } + + wxString GetReturnType() const + { + return returnType; + } + void iSetReturnType(const wxString &s) + { + returnType = s; + } + wxString GetLanguage() const + { + return language; + } + void iSetLanguage(const wxString &s) + { + language = s; + } + wxString GetVolatility() const + { + return volatility; + } + void iSetVolatility(const wxString &s) + { + volatility = s; + } + wxString GetParallel() const + { + return parallel; + } + void iSetParallel(const wxString &s) + { + parallel = s; + } + wxString GetSource() const + { + return source; + } + void iSetSource(const wxString &s) + { + source = s; + } + wxString GetBin() const + { + return bin; + } + void iSetBin(const wxString &s) + { + bin = s; + } + long GetArgCount() const + { + return argCount; + } + void iSetArgCount(long ac) + { + argCount = ac; + } + void iSetArgDefValCount(long ac) + { + argDefValCount = ac; + } + long GetArgDefValCount() + { + return argDefValCount; + } + long GetCost() const + { + return cost; + } + void iSetCost(long c) + { + cost = c; + } + long GetRows() const + { + return rows; + } + void iSetRows(long r) + { + rows = r; + } + bool GetReturnAsSet() const + { + return returnAsSet; + } + void iSetReturnAsSet(bool b) + { + returnAsSet = b; + } + bool GetSecureDefiner() const + { + return secureDefiner; + } + void iSetSecureDefiner(bool b) + { + secureDefiner = b; + } + bool GetIsStrict() const + { + return isStrict; + } + void iSetIsStrict(bool b) + { + isStrict = b; + } + bool GetIsWindow() const + { + return isWindow; + } + void iSetIsWindow(bool b) + { + isWindow = b; + } + long GetProcType() + { + return procType; + } + void iSetProcType(long l) + { + procType = l; + } + wxArrayString &GetConfigList() + { + return configList; + } + bool GetIsLeakProof() const + { + return isLeakProof; + } + void iSetIsLeakProof(bool b) + { + isLeakProof = b; + } + + bool CanRestore() + { + return true; + } + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createfunction"); + } + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + wxString GetSelectSql(ctlTree *browser); + + bool ResetStats(); + + void ShowHint(frmMain *form, bool force); + bool GetCanHint() + { + return true; + }; + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + + bool IsUpToDate(); + +protected: + pgFunction(pgSchema *newSchema, int newType, const wxString &newName = wxT("")); + +private: + wxString returnType, language, volatility, parallel, source, bin; + wxArrayString argNamesArray, argTypesArray, argModesArray, argDefsArray; + bool returnAsSet, secureDefiner, isStrict, isWindow, isLeakProof; + long argCount, cost, rows, argDefValCount, procType; + wxArrayString configList; +}; + + +class pgFunctionCollection : public pgSchemaObjCollection +{ +public: + pgFunctionCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowStatistics(frmMain *form, ctlListView *statistics); +}; + + +class pgTriggerFunctionFactory : public pgFunctionFactory +{ +public: + pgTriggerFunctionFactory(); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); +}; +extern pgTriggerFunctionFactory triggerFunctionFactory; + + +class pgTriggerFunction : public pgFunction +{ +public: + pgTriggerFunction(pgSchema *newSchema, const wxString &newName = wxT("")); + wxString GetTranslatedMessage(int kindOfMessage) const; + static pgObject *ReadObjects(pgCollection *collection, ctlTree *browser); +}; + + +class pgTriggerFunctionCollection : public pgSchemaObjCollection +{ +public: + pgTriggerFunctionCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + + +class pgProcedureFactory : public pgFunctionFactory +{ +public: + pgProcedureFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); +}; +extern pgProcedureFactory procedureFactory; + + +class pgProcedure : public pgFunction +{ +public: + pgProcedure(pgSchema *newSchema, const wxString &newName = wxT("")); + wxString GetFullName(); + wxString GetTranslatedMessage(int kindOfMessage) const; + static pgObject *ReadObjects(pgCollection *collection, ctlTree *browser); + bool GetIsProcedure() const + { + return true; + } + + wxString GetSql(ctlTree *browser); + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetExecSql(ctlTree *browser); + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createprocedure"); + } +}; + + +class resetFunctionStatsFactory : public contextActionFactory +{ +public: + resetFunctionStatsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +class pgProcedureCollection : public pgSchemaObjCollection +{ +public: + pgProcedureCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + + +#endif diff --git a/include/schema/pgGroup.h b/include/schema/pgGroup.h new file mode 100644 index 0000000..62ab888 --- /dev/null +++ b/include/schema/pgGroup.h @@ -0,0 +1,105 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgGroup.h - PostgreSQL Group +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGGROUP_H +#define PGGROUP_H + +#include "pgServer.h" + + +class pgGroupFactory : public pgServerObjFactory +{ +public: + pgGroupFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); +}; +extern pgGroupFactory groupFactory; + + +// Class declarations +class pgGroup : public pgServerObject +{ +public: + pgGroup(const wxString &newName = wxT("")); + wxString GetTranslatedMessage(int kindOfMessage) const; + + // Group Specific + long GetGroupId() const + { + return groupId; + } + void iSetGroupId(const long l) + { + groupId = l; + } + long GetMemberCount() const + { + return memberCount; + } + void iSetMemberCount(const long l) + { + memberCount = l; + } + wxString GetMemberIds() const + { + return memberIds; + } + void iSetMemberIds(const wxString &s) + { + memberIds = s; + } + wxString GetMembers() const + { + return members; + } + void iSetMembers(const wxString &s) + { + members = s; + } + wxArrayString &GetUsersIn() + { + return usersIn; + } + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + long groupId, memberCount; + wxString memberIds, members, quotedMembers; + wxArrayString usersIn; +}; + +class pgGroupCollection : public pgServerObjCollection +{ +public: + pgGroupCollection(pgaFactory *factory, pgServer *sv); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgIndex.h b/include/schema/pgIndex.h new file mode 100644 index 0000000..f05a801 --- /dev/null +++ b/include/schema/pgIndex.h @@ -0,0 +1,342 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgIndex.h PostgreSQL Index +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGINDEX_H +#define PGINDEX_H + +#include "pgTable.h" +#include + + + + +class pgIndexBase : public pgSchemaObject +{ +protected: + pgIndexBase(pgSchema *newSchema, pgaFactory &factory, const wxString &newName = wxT("")); + +public: + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + void ShowStatistics(frmMain *form, ctlListView *statistics); + bool CanDropCascaded() + { + return GetSchema()->GetMetaType() != PGM_CATALOG; + } + + wxString GetProcArgs() const + { + return procArgs; + } + wxString GetQuotedTypedColumns() const + { + return quotedTypedColumns; + } + wxString GetTypedColumns() const + { + return typedColumns; + } + wxString GetOperatorClasses() const + { + return operatorClasses; + } + wxString GetQuotedColumns() const + { + return quotedColumns; + } + wxString GetColumns() const + { + return columns; + } + wxArrayString GetColumnList() const + { + return columnList; + } + + wxString GetColumnNumbers() const + { + return columnNumbers; + } + void iSetColumnNumbers(const wxString &s) + { + columnNumbers = s; + } + wxString GetConstraint() const + { + return constraint; + } + void iSetConstraint(const wxString &s) + { + constraint = s; + } + wxString GetIndexType() const + { + return indexType; + } + void iSetIndexType(const wxString &s) + { + indexType = s; + } + long GetColumnCount() const + { + return columnCount; + } + void iSetColumnCount(const long l) + { + columnCount = l; + } + bool GetIsUnique() const + { + return isUnique; + } + void iSetIsUnique(const bool b) + { + isUnique = b; + } + bool GetIsExclude() const + { + return isExclude; + } + void iSetIsExclude(const bool b) + { + isExclude = b; + } + bool GetIsPrimary() const + { + return isPrimary; + } + void iSetIsPrimary(const bool b) + { + isPrimary = b; + } + bool GetIsClustered() const + { + return isClustered; + } + void iSetIsClustered(const bool b) + { + isClustered = b; + } + bool GetIsValid() const + { + return isValid; + } + void iSetIsValid(const bool b) + { + isValid = b; + } + wxString GetIdxTable() const + { + return idxTable; + } + void iSetIdxTable(const wxString &s) + { + idxTable = s; + } + wxString GetIdxSchema() const + { + return idxSchema; + } + void iSetIdxSchema(const wxString &s) + { + idxSchema = s; + } + OID GetRelTableOid() const + { + return relTableOid; + } + void iSetRelTableOid(const OID d) + { + relTableOid = d; + } + wxString GetTablespace() const + { + return tablespace; + }; + void iSetTablespace(const wxString &newVal) + { + tablespace = newVal; + } + OID GetTablespaceOid() const + { + return tablespaceOid; + }; + void iSetTablespaceOid(const OID newVal) + { + tablespaceOid = newVal; + } + wxString GetFillFactor() + { + return fillFactor; + } + void iSetFillFactor(const wxString &s) + { + fillFactor = s; + } + + wxString GetProcName() const + { + return procName; + } + void iSetProcName(const wxString &s) + { + procName = s; + } + wxString GetProcNamespace() const + { + return procNamespace; + } + void iSetProcNamespace(const wxString &s) + { + procNamespace = s; + } + + bool GetDeferrable() const + { + return deferrable; + } + void iSetDeferrable(const bool b) + { + deferrable = b; + } + bool GetDeferred() const + { + return deferred; + } + void iSetDeferred(const bool b) + { + deferred = b; + } + + void iSetOperatorClassList(const wxString &s) + { + operatorClassList = s; + } + void iSetProcArgTypeList(const wxString &s) + { + procArgTypeList = s; + } + + const wxArrayString &GetOrdersArray() + { + return ordersArray; + } + + const wxArrayString &GetNullsArray() + { + return nullsArray; + } + + const wxArrayString &GetOpClassesArray() + { + return opclassesArray; + } + + const wxArrayString &GetCollationsArray() + { + return collationsArray; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetCreate(); + bool CanRestore() + { + return true; + } + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + bool CanMaintenance() + { + return true; + } + bool GetShowExtendedStatistics() + { + return showExtendedStatistics; + } + void iSetShowExtendedStatistics(bool b) + { + showExtendedStatistics = b; + } + + bool HasStats() + { + return true; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + bool HasPgstatindex(); + +protected: + void ReadColumnDetails(); + +private: + wxString columnNumbers, columns, quotedColumns, indexType, idxTable, idxSchema, constraint, tablespace; + wxString procName, procNamespace, procArgs, procArgTypeList, typedColumns, quotedTypedColumns, operatorClasses, operatorClassList; + long columnCount; + wxArrayString columnList, ordersArray, nullsArray, opclassesArray, collationsArray; + bool isUnique, isPrimary, isExclude, isClustered, isValid; + bool deferrable, deferred, showExtendedStatistics; + OID relTableOid, tablespaceOid; + wxString fillFactor; +}; + + +class pgIndex : public pgIndexBase +{ +public: + pgIndex(pgSchema *newSchema, const wxString &newName = wxT("")); +}; + + +class pgIndexBaseFactory : public pgSchemaObjFactory +{ +public: + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +protected: + pgIndexBaseFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img = 0) : pgSchemaObjFactory(tn, ns, nls, img) {} +}; + +class pgIndexFactory : public pgIndexBaseFactory +{ +public: + pgIndexFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); +}; +extern pgIndexFactory indexFactory; + +class pgIndexBaseCollection : public pgSchemaObjCollection +{ +public: + pgIndexBaseCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowStatistics(frmMain *form, ctlListView *statistics); +}; + + +class executePgstatindexFactory : public contextActionFactory +{ +public: + executePgstatindexFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); + bool CheckChecked(pgObject *obj); +}; + + +#endif diff --git a/include/schema/pgIndexConstraint.h b/include/schema/pgIndexConstraint.h new file mode 100644 index 0000000..d0ac414 --- /dev/null +++ b/include/schema/pgIndexConstraint.h @@ -0,0 +1,113 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgIndexConstraint.h PostgreSQL Index Constraint: PK, Unique +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __PG_INDEXCONSTRAINT +#define __PG_INDEXCONSTRAINT + +#include "pgIndex.h" + +class pgIndexConstraint : public pgIndexBase +{ +public: + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool DropObject(wxFrame *frame, ctlTree *browse, bool cascadedr); + wxString GetDefinition(); + wxString GetCreate(); + wxString GetSql(ctlTree *browser); + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-altertable"); + } + OID GetConstraintOid() + { + return constraintOid; + } + void iSetConstraintOid(const OID o) + { + constraintOid = o; + } + +protected: + pgIndexConstraint(pgSchema *newSchema, pgaFactory &factory, const wxString &newName) + : pgIndexBase(newSchema, factory, newName) {} + +private: + OID constraintOid; +}; + + +class pgPrimaryKeyFactory : public pgIndexBaseFactory +{ +public: + pgPrimaryKeyFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); +}; +extern pgPrimaryKeyFactory primaryKeyFactory; + +class pgPrimaryKey : public pgIndexConstraint +{ +public: + pgPrimaryKey(pgSchema *newSchema, const wxString &newName = wxT("")) + : pgIndexConstraint(newSchema, primaryKeyFactory, newName) {} + + wxString GetTranslatedMessage(int kindOfMessage) const; + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + bool CanCreate() + { + return false; + } +}; + + +class pgUniqueFactory : public pgIndexBaseFactory +{ +public: + pgUniqueFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); +}; +extern pgUniqueFactory uniqueFactory; + +class pgUnique : public pgIndexConstraint +{ +public: + pgUnique(pgSchema *newSchema, const wxString &newName = wxT("")) + : pgIndexConstraint(newSchema, uniqueFactory, newName) {} + + wxString GetTranslatedMessage(int kindOfMessage) const; + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); +}; + + +class pgExcludeFactory : public pgIndexBaseFactory +{ +public: + pgExcludeFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); +}; +extern pgExcludeFactory excludeFactory; + +class pgExclude : public pgIndexConstraint +{ +public: + pgExclude(pgSchema *newSchema, const wxString &newName = wxT("")) + : pgIndexConstraint(newSchema, excludeFactory, newName) {} + + wxString GetTranslatedMessage(int kindOfMessage) const; + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); +}; + + +#endif diff --git a/include/schema/pgLanguage.h b/include/schema/pgLanguage.h new file mode 100644 index 0000000..4e61f7d --- /dev/null +++ b/include/schema/pgLanguage.h @@ -0,0 +1,101 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgLanguage.h - Language class +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGLANGUAGE_H +#define PGLANGUAGE_H + +#include "pgDatabase.h" + +class pgCollection; +class pgLanguageFactory : public pgDatabaseObjFactory +{ +public: + pgLanguageFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgLanguageFactory languageFactory; + +class pgLanguage : public pgDatabaseObject +{ +public: + pgLanguage(const wxString &newName = wxT("")); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool CanDropCascaded() + { + return true; + } + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + + wxString GetHandlerProc() const + { + return handlerProc; + } + void iSetHandlerProc(const wxString &s) + { + handlerProc = s; + } + wxString GetInlineProc() const + { + return inlineProc; + } + void iSetInlineProc(const wxString &s) + { + inlineProc = s; + } + wxString GetValidatorProc() const + { + return validatorProc; + } + void iSetValidatorProc(const wxString &s) + { + validatorProc = s; + } + bool GetTrusted() const + { + return trusted; + } + void iSetTrusted(const bool b) + { + trusted = b; + } + +private: + wxString handlerProc, inlineProc, validatorProc; + bool trusted; +}; + +class pgLanguageCollection : public pgDatabaseObjCollection +{ +public: + pgLanguageCollection(pgaFactory *factory, pgDatabase *db); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgObject.h b/include/schema/pgObject.h new file mode 100644 index 0000000..da7cd24 --- /dev/null +++ b/include/schema/pgObject.h @@ -0,0 +1,393 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgObject.h - PostgreSQL base object class +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGOBJECT_H +#define PGOBJECT_H + +class ctlTree; +class ctlSQLBox; +class ctlListView; +class frmMain; +class frmReport; +class pgDatabase; +class pgSchema; +class pgCollection; +class pgConn; +class pgSet; +class pgServer; +class pgTable; +class pgaJob; + + +class pgTypes +{ +public: + wxChar *typName; + long typeIcon; + wxChar *newString; + wxChar *newLongString; +}; + + +class pgaFactory; + + +enum +{ + RETRIEVINGDETAILS = 1, + REFRESHINGDETAILS, + BACKUPGLOBALS, + GRANTWIZARDTITLE, + MAINTENANCEDIALOGTITLE, + BACKUPSERVERTITLE, + BACKUPTITLE, + RESTORETITLE, + CANNOTDROPSYSTEM, + DROPINCLUDINGDEPS, + DROPEXCLUDINGDEPS, + DROPCASCADETITLE, + DROPTITLE, + PROPERTIESREPORT, + PROPERTIES, + DDLREPORT, + DDL, + DATADICTIONNARYREPORT, + STATISTICSREPORT, + OBJSTATISTICS, + DEPENDENCIESREPORT, + DEPENDENCIES, + DEPENDENTSREPORT, + DEPENDENTS, + OBJECTSLISTREPORT +}; + + +// Class declarations +class pgObject : public wxTreeItemData +{ +protected: + pgObject(int newType, const wxString &newName = wxEmptyString); + pgObject(pgaFactory &factory, const wxString &newName = wxEmptyString); + +public: + /* + * Except column level privileges, column will be always an empty + * string in any case + */ + static wxString GetPrivileges(const wxString &allPattern, + const wxString &acl, const wxString &grantObject, + const wxString &user, const wxString &column = wxT("")); + + static wxString GetDefaultPrivileges(const wxString &strType, const wxString &strSupportedPrivs, + const wxString &strSchema, const wxString &strOrigDefPrivs, + const wxString &strNewDefPrivs, const wxString &strRole); + static wxString GetPrivilegeName(wxChar privilege); + static bool findUserPrivs(wxString &, wxString &, wxString &); + + static int GetTypeId(const wxString &typname); + + pgaFactory *GetFactory() + { + return factory; + } + bool IsCreatedBy(pgaFactory &f) const + { + return &f == factory; + } + bool IsCreatedBy(pgaFactory *f) const + { + return f == factory; + } + int GetType() const; + int GetMetaType() const; + wxString GetTypeName() const; + wxString GetTranslatedTypeName() const; + virtual wxString GetTranslatedMessage(int kindOfMessage) const; + virtual int GetIconId(); + bool UpdateIcon(ctlTree *browser); + + virtual void ShowProperties() const {}; + virtual pgDatabase *GetDatabase() const + { + return 0; + } + virtual pgServer *GetServer() const + { + return 0; + } + virtual pgSchema *GetSchema() const + { + return 0; + } + virtual pgTable *GetTable() const + { + return 0; + } + virtual pgaJob *GetJob() const + { + return 0; + } + void iSetName(const wxString &newVal) + { + name = newVal; + } + wxString GetName() const + { + return name; + } + OID GetOid() const + { + return oid; + } + wxString GetOidStr() const + { + return NumToStr(oid) + wxT("::oid"); + } + void iSetOid(const OID newVal) + { + oid = newVal; + } + void iSetXid(const OID x) + { + xid = x; + }; + OID GetXid() + { + return xid; + }; + wxString GetOwner() const + { + return owner; + } + void iSetOwner(const wxString &newVal) + { + owner = newVal; + } + wxString GetComment() const + { + return comment; + } + void iSetComment(const wxString &newVal) + { + comment = newVal; + } + wxString GetAcl() const + { + return acl; + } + void iSetAcl(const wxString &newVal) + { + acl = newVal; + } + virtual bool GetSystemObject() const + { + return false; + } + virtual bool IsCollection() const + { + return false; + } + virtual void ShowHint(frmMain *form, bool force) {} + + void ShowTree(frmMain *form, ctlTree *browser, ctlListView *properties, ctlSQLBox *sqlPane); + + wxTreeItemId AppendBrowserItem(ctlTree *browser, pgObject *object); + + virtual wxString GetHelpPage(bool forCreate) const; + virtual wxString GetFullName() + { + return name; + } + virtual wxString GetIdentifier() const + { + return name; + } + virtual wxString GetQuotedIdentifier() const + { + return qtIdent(name); + } + virtual wxString GetDisplayName() + { + return GetFullName(); + }; + void iSetProviders(const wxString &newVal) + { + providers = newVal; + } + wxString GetProviders() const + { + return providers; + } + void iSetLabels(const wxString &newVal) + { + labels = newVal; + } + wxString GetLabels() const + { + return labels; + } + wxArrayString GetProviderLabelArray(); + wxString GetSeqLabelsSql(); + + virtual wxMenu *GetNewMenu(); + + virtual wxString GetSql(ctlTree *browser) + { + return wxT(""); + } + /* + * Except column level privileges, column will be always an empty + * string in any case + */ + wxString GetGrant(const wxString &allPattern, const wxString &grantFor = wxT(""), const wxString &column = wxT("")); + wxString GetCommentSql(); + wxString GetOwnerSql(int major, int minor, wxString objname = wxEmptyString, wxString objtype = wxEmptyString); + pgConn *GetConnection() const; + + virtual void SetDirty() + { + sql = wxT(""); + expandedKids = false; + needReread = true; + } + virtual wxString GetFullIdentifier() const + { + return GetName(); + } + virtual wxString GetQuotedFullIdentifier() const + { + return qtIdent(name); + } + + virtual void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0) = 0; + virtual void ShowStatistics(frmMain *form, ctlListView *statistics); + virtual void ShowDependencies(frmMain *form, ctlListView *Dependencies, const wxString &where = wxEmptyString); + virtual void ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &where = wxEmptyString); + virtual pgObject *Refresh(ctlTree *browser, const wxTreeItemId item) + { + return this; + } + virtual bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded = false) + { + return false; + } + virtual bool EditObject(wxFrame *frame, ctlTree *browser) + { + return false; + } + + virtual bool NeedCascadedDrop() + { + return false; + } + virtual bool CanCreate() + { + return false; + } + virtual bool CanView() + { + return false; + } + virtual bool CanEdit() + { + return false; + } + virtual bool CanDrop() + { + return false; + } + virtual bool CanDropCascaded() + { + return false; + } + virtual bool CanMaintenance() + { + return false; + } + virtual bool RequireDropConfirm() + { + return false; + } + virtual bool WantDummyChild() + { + return false; + } + virtual bool CanBackup() + { + return false; + } + virtual bool CanBackupGlobals() + { + return false; + } + virtual bool CanRestore() + { + return false; + } + virtual bool GetCanHint() + { + return false; + } + virtual bool HasStats() + { + return false; + } + virtual bool HasDepends() + { + return false; + } + virtual bool HasReferences() + { + return false; + } + + wxString qtDbString(const wxString &str); + + void SetWindowPtr(dlgProperty *dlgprop); + wxString GetSqlReCreate(frmMain *form, pgObject *obj); + dlgProperty *GetWindowPtr() + { + return dlg; + } + + bool CheckOpenDialogs(ctlTree *browser, wxTreeItemId node); + +protected: + void CreateList3Columns(ctlListView *properties, const wxString &left = _("Object"), const wxString &middle = _("Owner"), const wxString &right = _("Value")); + void CreateListColumns(ctlListView *properties, const wxString &left = _("Property"), const wxString &right = _("Value")); + + void AppendMenu(wxMenu *menu, int type = -1); + virtual void SetContextInfo(frmMain *form) {} + + bool expandedKids, needReread; + wxString sql; + bool hintShown; + pgaFactory *factory; + +private: + /* + * Except column level privileges, column will be always an empty + * string in any case + */ + static void AppendRight(wxString &rights, const wxString &acl, wxChar c, const wxChar *rightName, const wxString &column = wxEmptyString); + static wxString GetPrivilegeGrant(const wxString &allPattern, const wxString &acl, const wxString &grantObject, const wxString &user, const wxString &column); + void ShowDependency(pgDatabase *db, ctlListView *list, const wxString &query, const wxString &clsOrder); + wxString name, owner, schema, comment, acl; + int type; + OID oid, xid; + wxString providers, labels; + dlgProperty *dlg; + + friend class pgaFactory; +}; + +#endif + diff --git a/include/schema/pgOperator.h b/include/schema/pgOperator.h new file mode 100644 index 0000000..09204f7 --- /dev/null +++ b/include/schema/pgOperator.h @@ -0,0 +1,218 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgOperator.h PostgreSQL Operator +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PG_OPERATOR_H +#define PG_OPERATOR_H + + +#include "pgSchema.h" + + +class pgOperatorFactory : public pgSchemaObjFactory +{ +public: + pgOperatorFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgOperatorFactory operatorFactory; + +class pgOperator : public pgSchemaObject +{ +public: + pgOperator(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgOperator(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + virtual wxString GetQuotedIdentifier() const + { + return GetName(); + } + bool CanDropCascaded() + { + return GetSchema()->GetMetaType() != PGM_CATALOG; + } + + wxString GetFullName(); + wxString GetOperands() const; + wxString GetLeftType() const + { + return leftType; + } + void iSetLeftType(const wxString &s) + { + leftType = s; + } + wxString GetRightType() const + { + return rightType; + } + void iSetRightType(const wxString &s) + { + rightType = s; + } + OID GetLeftTypeOid() const + { + return leftTypeOid; + } + void iSetLeftTypeOid(const OID o) + { + leftTypeOid = o; + } + OID GetRightTypeOid() const + { + return rightTypeOid; + } + void iSetRightTypeOid(const OID o) + { + rightTypeOid = o; + } + wxString GetResultType() + { + return resultType; + } + void iSetResultType(const wxString &s) + { + resultType = s; + } + wxString GetOperatorFunction() const + { + return operatorFunction; + } + void iSetOperatorFunction(const wxString &s) + { + operatorFunction = s; + } + wxString GetJoinFunction() const + { + return joinFunction; + } + void iSetJoinFunction(const wxString &s) + { + joinFunction = s; + } + wxString GetRestrictFunction() const + { + return restrictFunction; + } + void iSetRestrictFunction(const wxString &s) + { + restrictFunction = s; + } + wxString GetCommutator() const + { + return commutator; + } + void iSetCommutator(const wxString &s) + { + commutator = s; + } + wxString GetNegator() const + { + return negator; + } + void iSetNegator(const wxString &s) + { + negator = s; + } + wxString GetKind() const + { + return kind; + } + void iSetKind(const wxString &s) + { + kind = s; + } + wxString GetLeftSortOperator() const + { + return leftSortOperator; + } + void iSetLeftSortOperator(const wxString &s) + { + leftSortOperator = s; + } + wxString GetRightSortOperator() const + { + return rightSortOperator; + } + void iSetRightSortOperator(const wxString &s) + { + rightSortOperator = s; + } + wxString GetLessOperator() const + { + return lessOperator; + } + void iSetLessOperator(const wxString &s) + { + lessOperator = s; + } + wxString GetGreaterOperator() const + { + return greaterOperator; + } + void iSetGreaterOperator(const wxString &s) + { + greaterOperator = s; + } + bool GetHashJoins() const + { + return hashJoins; + } + void iSetHashJoins(bool b) + { + hashJoins = b; + } + bool GetMergeJoins() const + { + return mergeJoins; + } + void iSetMergeJoins(bool b) + { + mergeJoins = b; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString leftType, rightType, resultType, + operatorFunction, joinFunction, restrictFunction, + commutator, negator, kind, + leftSortOperator, rightSortOperator, lessOperator, greaterOperator; + OID leftTypeOid, rightTypeOid; + bool hashJoins, mergeJoins; +}; + +class pgOperatorCollection : public pgSchemaObjCollection +{ +public: + pgOperatorCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgOperatorClass.h b/include/schema/pgOperatorClass.h new file mode 100644 index 0000000..8a18d47 --- /dev/null +++ b/include/schema/pgOperatorClass.h @@ -0,0 +1,140 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgOperatorClass.h PostgreSQL OperatorClass +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGOPERATORCLASS_H +#define PGOPERATORCLASS_H + +#include "pgSchema.h" + +class pgCollection; +class pgOperatorClassFactory : public pgSchemaObjFactory +{ +public: + pgOperatorClassFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgOperatorClassFactory operatorClassFactory; + + +class pgOperatorClass : public pgSchemaObject +{ +public: + pgOperatorClass(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgOperatorClass(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + wxString GetFullName() + { + return GetName() + wxT("(") + GetAccessMethod() + wxT(")"); + } + wxString GetAccessMethod() const + { + return accessMethod; + } + void iSetAccessMethod(const wxString &s) + { + accessMethod = s; + } + + wxArrayString GetOperators() + { + return operators; + } + wxArrayString GetFunctions() + { + return functions; + } + wxArrayString GetQuotedFunctions() + { + return quotedFunctions; + } + wxString GetInType() const + { + return inType; + } + void iSetInType(const wxString &s) + { + inType = s; + } + wxString GetKeyType() const + { + return keyType; + } + void iSetKeyType(const wxString &s) + { + keyType = s; + } + wxString GetSql(ctlTree *browser); + bool GetOpcDefault() const + { + return opcDefault; + } + void iSetOpcDefault(const bool b) + { + opcDefault = b; + } + wxString GetFamily() const + { + return opFamily; + } + void iSetFamily(const wxString &s) + { + opFamily = s; + } + + bool CanCreate() + { + return false; + } + bool CanEdit() + { + return false; + } + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createopclass"); + } + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString inType, keyType, accessMethod, opFamily ; + wxArrayString operators; + wxArrayString functions, quotedFunctions; + wxArrayString functionOids; + bool opcDefault; +}; + +class pgOperatorClassCollection : public pgSchemaObjCollection +{ +public: + pgOperatorClassCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgOperatorFamily.h b/include/schema/pgOperatorFamily.h new file mode 100644 index 0000000..3b2b974 --- /dev/null +++ b/include/schema/pgOperatorFamily.h @@ -0,0 +1,91 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgOperatorFamily.h PostgreSQL OperatorFamily +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGOPERATORFAMILY_H +#define PGOPERATORFAMILY_H + +#include "pgSchema.h" + +class pgCollection; +class pgOperatorFamilyFactory : public pgSchemaObjFactory +{ +public: + pgOperatorFamilyFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgOperatorFamilyFactory operatorFamilyFactory; + + +class pgOperatorFamily : public pgSchemaObject +{ +public: + pgOperatorFamily(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgOperatorFamily(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + wxString GetFullName() + { + return GetName() + wxT("(") + GetAccessMethod() + wxT(")"); + } + wxString GetAccessMethod() const + { + return accessMethod; + } + void iSetAccessMethod(const wxString &s) + { + accessMethod = s; + } + wxString GetSql(ctlTree *browser); + + bool CanCreate() + { + return false; + } + bool CanEdit() + { + return false; + } + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createopfamily"); + } + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString accessMethod; +}; + +class pgOperatorFamilyCollection : public pgSchemaObjCollection +{ +public: + pgOperatorFamilyCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgPartition.h b/include/schema/pgPartition.h new file mode 100644 index 0000000..e158701 --- /dev/null +++ b/include/schema/pgPartition.h @@ -0,0 +1,100 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgPartition.h Greenplum Partitioned Table Partition +// +////////////////////////////////////////////////////////////////////////// + +#ifndef pgPartition_H +#define pgPartition_H + +#include "pgSchema.h" +#include "pgTable.h" + + + +class pgPartitionFactory : public pgTableObjFactory +{ +public: + pgPartitionFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) ; + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + virtual void AppendMenu(wxMenu *menu); +}; + +extern pgPartitionFactory pg_partitionFactory; + +class pgPartition : public pgTable +{ +public: + pgPartition(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgPartition(); + bool CanCreate(); + wxMenu *GetNewMenu(); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + wxString GetPartitionName() + { + return partitionname; + } + void iSetPartitionName(const wxString &pn) + { + partitionname = pn; + } + +private: + wxString partitionname; +}; + + +class pgPartitionObject : public pgTableObject +{ +public: + pgPartitionObject(pgPartition *newTable, pgaFactory &factory, const wxString &newName = wxT("")) + : pgTableObject(newTable, factory, newName) { }; + virtual pgPartition *GetTable() const + { + return dynamic_cast(table); + } + OID GetTableOid() const + { + return table->GetOid(); + } + wxString GetTableOidStr() const + { + return NumToStr(table->GetOid()) + wxT("::oid"); + } +}; + + +class pgPartitionCollection : public pgTableCollection +{ +public: + pgPartitionCollection(pgaFactory *factory, pgPartition *_table); + virtual bool CanCreate() + { + return false; + }; +}; + + +class pgPartitionObjCollection : public pgTableObjCollection +{ +public: + pgPartitionObjCollection(pgaFactory *factory, pgPartition *_table) + : pgTableObjCollection(factory, (pgTable *)_table ) { }; + virtual pgTable *GetTable() const + { + return table; + } + virtual bool CanCreate(); +}; + + + +#endif diff --git a/include/schema/pgRole.h b/include/schema/pgRole.h new file mode 100644 index 0000000..e895e06 --- /dev/null +++ b/include/schema/pgRole.h @@ -0,0 +1,241 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgRole.h - PostgreSQL Role +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGROLE_H +#define PGROLE_H + +#include "pgServer.h" + + +#define PGROLE_ADMINOPTION wxT("(*)") +#define PGROLE_ADMINOPTION_LEN 3 + + +class pgRoleBaseFactory : public pgServerObjFactory +{ +public: + pgRoleBaseFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img = 0); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr); +}; + +class pgLoginRoleFactory : public pgRoleBaseFactory +{ +public: + pgLoginRoleFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr); + virtual pgCollection *CreateCollection(pgObject *obj); +}; + +class pgGroupRoleFactory : public pgRoleBaseFactory +{ +public: + pgGroupRoleFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr); + virtual pgCollection *CreateCollection(pgObject *obj); +}; + +extern pgLoginRoleFactory loginRoleFactory; +extern pgGroupRoleFactory groupRoleFactory; + + +// Class declarations +class pgRole : public pgServerObject +{ +protected: + pgRole(pgaFactory &factory, const wxString &newName = wxT("")); + +public: + int GetIconId(); + + + // Role Specific + wxDateTime GetAccountExpires() const + { + return accountExpires; + } + void iSetAccountExpires(const wxDateTime &dt) + { + accountExpires = dt; + } + wxString GetPassword() const + { + return password; + } + void iSetPassword(const wxString &s) + { + password = s; + } + void iSetInherits(const bool b) + { + inherits = b; + } + bool GetInherits() const + { + return inherits; + } + void iSetCanLogin(const bool b) + { + canLogin = b; + } + bool GetCanLogin() const + { + return canLogin; + } + bool GetCreateDatabase() const + { + return createDatabase; + } + void iSetCreateDatabase(const bool b) + { + createDatabase = b; + } + bool GetCreateRole() const + { + return createRole; + } + void iSetCreateRole(const bool b) + { + createRole = b; + } + bool GetSuperuser() const + { + return superuser; + } + void iSetSuperuser(const bool b) + { + superuser = b; + } + bool GetUpdateCatalog() const + { + return updateCatalog; + } + void iSetUpdateCatalog(const bool b) + { + updateCatalog = b; + } + bool GetReplication() const + { + return replication; + } + void iSetReplication(const bool b) + { + replication = b; + } + wxString GetRolQueueName() const + { + return rolqueuename; + } + void iSetRolQueueName(const wxString &newVal) + { + rolqueuename = newVal; + } + long GetConnectionLimit() const + { + return connectionLimit; + } + void iSetConnectionLimit(long newVal) + { + connectionLimit = newVal; + } + void iSetIsValidInfinity(const bool b) + { + isValidInfinity = b; + } + wxArrayString &GetRolesIn() + { + return rolesIn; + } + wxArrayString &GetVariables() + { + return variables; + } + + void ReassignDropOwnedTo(frmMain *form); + + // Tree object creation + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + void ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &where); + + // virtual methods + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + bool GetIsValidInfinity() + { + return isValidInfinity; + } +private: + wxString password; + wxString rolqueuename; + wxDateTime accountExpires; + bool superuser, createDatabase, createRole, updateCatalog, inherits, canLogin, replication, isValidInfinity; + long connectionLimit; + wxArrayString rolesIn; + wxArrayString variables; +}; + + + +class pgLoginRole : public pgRole +{ +public: + pgLoginRole(const wxString &newName = wxT("")); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + + +class pgGroupRole : public pgRole +{ +public: + pgGroupRole(const wxString &newName = wxT("")); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +class pgLoginRoleCollection : public pgServerObjCollection +{ +public: + pgLoginRoleCollection(pgaFactory *factory, pgServer *sv); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + + +class pgGroupRoleCollection : public pgServerObjCollection +{ +public: + pgGroupRoleCollection(pgaFactory *factory, pgServer *sv); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +class reassignDropOwnedFactory : public contextActionFactory +{ +public: + reassignDropOwnedFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +#endif diff --git a/include/schema/pgRule.h b/include/schema/pgRule.h new file mode 100644 index 0000000..ba612aa --- /dev/null +++ b/include/schema/pgRule.h @@ -0,0 +1,183 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgRule.h PostgreSQL Rule +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGRULE_H +#define PGRULE_H + + +#include "pgSchema.h" + +class pgRuleObject : public pgSchemaObject +{ +public: + pgRuleObject(pgSchema *newSchema, pgaFactory &factory, const wxString &newName = wxEmptyString) : pgSchemaObject(newSchema, factory, newName) {} + + wxString GetFormattedDefinition(); + wxString GetDefinition() const + { + return definition; + } + void iSetDefinition(const wxString &s) + { + definition = s; + } + +protected: + wxString definition; +}; + + + +//////////////////////////////////////////////////////////7 + + +class pgRuleFactory : public pgSchemaObjFactory +{ +public: + pgRuleFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + + int GetClosedIconId() + { + return closedId; + } + +protected: + int closedId; +}; +extern pgRuleFactory ruleFactory; + + +class pgRule : public pgRuleObject +{ +public: + pgRule(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgRule(); + + int GetIconId(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return GetSchema()->GetMetaType() != PGM_CATALOG; + } + + wxString GetEvent() const + { + return event; + } + void iSetEvent(const wxString &s) + { + event = s; + } + wxString GetCondition() const + { + return condition; + } + void iSetCondition(const wxString &s) + { + condition = s; + } + wxString GetAction() const + { + return action; + } + void iSetAction(const wxString &s) + { + action = s; + } + bool GetDoInstead() const + { + return doInstead; + } + void iSetDoInstead(const bool b) + { + doInstead = b; + } + bool GetEnabled() const + { + return enabled; + } + void SetEnabled(ctlTree *browser, const bool b); + void iSetEnabled(const bool b) + { + enabled = b; + } + wxString GetQuotedFullTable() const + { + return quotedFullTable; + } + void iSetQuotedFullTable(const wxString &s) + { + quotedFullTable = s; + } + void iSetParentIsTable(const bool b) + { + parentistable = b; + } + bool GetParentIsTable() + { + return parentistable; + } + + bool GetSystemObject() const + { + return GetName() == wxT("_RETURN"); + } + bool CanDrop() + { + return !GetSystemObject() && GetSchema()->CanDrop(); + } + bool CanCreate() + { + return GetSchema()->CanCreate(); + } + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } +private: + wxString event, condition, action, quotedFullTable; + bool doInstead, enabled, parentistable; +}; + +class pgRuleCollection : public pgSchemaObjCollection +{ +public: + pgRuleCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +class enabledisableRuleFactory : public contextActionFactory +{ +public: + enabledisableRuleFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); + bool CheckChecked(pgObject *obj); +}; + +#endif diff --git a/include/schema/pgSchema.h b/include/schema/pgSchema.h new file mode 100644 index 0000000..daa3f81 --- /dev/null +++ b/include/schema/pgSchema.h @@ -0,0 +1,286 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgSchema.h PostgreSQL Schema +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGSCHEMA_H +#define PGSCHEMA_H + +#include "pgDatabase.h" + + +enum +{ + SCHEMATYP_SYSTEM = 0, + SCHEMATYP_TEMP, + SCHEMATYP_USERSYS, + SCHEMATYP_NORMAL +}; + +class pgSchemaBaseFactory : public pgDatabaseObjFactory +{ +public: + pgSchemaBaseFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm = 0); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); +}; + +class pgSchemaFactory : public pgSchemaBaseFactory +{ +public: + pgSchemaFactory(); + virtual pgCollection *CreateCollection(pgObject *obj); +}; + +class pgCatalogFactory : public pgSchemaBaseFactory +{ +public: + pgCatalogFactory(); + virtual pgCollection *CreateCollection(pgObject *obj); + bool CanCreate() + { + return false; + } + bool CanEdit() + { + return true; + } +}; + +extern pgSchemaFactory schemaFactory; +extern pgCatalogFactory catalogFactory; + + +class pgSchemaBase : public pgDatabaseObject +{ +public: + pgSchemaBase(pgaFactory &factory, const wxString &newName = wxT("")); + + wxString GetPrefix() const + { + return database->GetSchemaPrefix(GetName()); + } + wxString GetQuotedPrefix() const + { + return database->GetQuotedSchemaPrefix(GetName()); + } + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + static pgObject *ReadObjects(pgCollection *collection, ctlTree *browser); + bool CanDropCascaded() + { + return GetMetaType() != PGM_CATALOG; + } + + long GetSchemaTyp() const + { + return schemaTyp; + } + void iSetSchemaTyp(const long l) + { + schemaTyp = l; + } + bool GetCreatePrivilege() const + { + return createPrivilege; + } + void iSetCreatePrivilege(const bool b) + { + createPrivilege = b; + } + bool GetSystemObject() const + { + return schemaTyp <= SCHEMATYP_TEMP; + } + + bool CanBackup() + { + return true; + } + bool RequireDropConfirm() + { + return true; + } + bool WantDummyChild() + { + return true; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxMenu *GetNewMenu(); + bool CanRestore() + { + return GetConnection()->BackendMinimumVersion(8, 1); + } + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + // Default Privileges on Schema + void iSetDefPrivsOnTables(const wxString &privs) + { + m_defPrivsOnTables = privs; + } + void iSetDefPrivsOnSeqs(const wxString &privs) + { + m_defPrivsOnSeqs = privs; + } + void iSetDefPrivsOnFuncs(const wxString &privs) + { + m_defPrivsOnFuncs = privs; + } + void iSetDefPrivsOnTypes(const wxString &privs) + { + m_defPrivsOnTypes = privs; + } + + wxString GetDefPrivsOnTables() + { + return m_defPrivsOnTables; + } + wxString GetDefPrivsOnSequences() + { + return m_defPrivsOnSeqs; + } + wxString GetDefPrivsOnFunctions() + { + return m_defPrivsOnFuncs; + } + wxString GetDefPrivsOnTypes() + { + return m_defPrivsOnTypes; + } + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +protected: + wxString m_defPrivsOnTables, m_defPrivsOnSeqs, m_defPrivsOnFuncs, m_defPrivsOnTypes; + +private: + long schemaTyp; + bool createPrivilege; +}; + +class pgSchema : public pgSchemaBase +{ +public: + pgSchema(const wxString &newName = wxT("")); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +class pgCatalog : public pgSchemaBase +{ +public: + pgCatalog(const wxString &newName = wxT("")); + wxString GetTranslatedMessage(int kindOfMessage) const; + virtual wxString GetDisplayName(); + bool CanCreate() + { + return false; + } + bool CanEdit() + { + return true; + } +}; + +///////////////////////////////////////////////////// + +class pgSchemaObjFactory : public pgDatabaseObjFactory +{ +public: + pgSchemaObjFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm = 0) + : pgDatabaseObjFactory(tn, ns, nls, img, imgSm) {} + virtual pgCollection *CreateCollection(pgObject *obj); +}; + +// Object that lives in a schema +class pgSchemaObject : public pgDatabaseObject +{ +public: + pgSchemaObject(pgSchema *newSchema, pgaFactory &factory, const wxString &newName = wxEmptyString) : pgDatabaseObject(factory, newName) + { + SetSchema(newSchema); + } + pgSchemaObject(pgSchema *newSchema, int newType, const wxString &newName = wxT("")) : pgDatabaseObject(newType, newName) + { + SetSchema(newSchema); + } + + bool GetSystemObject() const; + + bool CanDrop(); + bool CanEdit() + { + return schema->GetMetaType() != PGM_CATALOG; + } + bool CanCreate(); + + void SetSchema(pgSchema *newSchema); + void UpdateSchema(ctlTree *browser, OID schemaOid); + virtual pgSchema *GetSchema() const + { + return schema; + } + pgSet *ExecuteSet(const wxString &sql); + wxString ExecuteScalar(const wxString &sql); + bool ExecuteVoid(const wxString &sql); + virtual wxString GetFullIdentifier() const; + virtual wxString GetQuotedFullIdentifier() const; + + +protected: + virtual void SetContextInfo(frmMain *form); + + pgSchema *schema; +}; + + +class pgSchemaCollection : public pgDatabaseObjCollection +{ +public: + pgSchemaCollection(pgaFactory *factory, pgDatabase *db); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + + +class pgCatalogCollection : public pgDatabaseObjCollection +{ +public: + pgCatalogCollection(pgaFactory *factory, pgDatabase *db); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + + +// collection of pgSchemaObject +class pgSchemaObjCollection : public pgCollection +{ +public: + pgSchemaObjCollection(pgaFactory *factory, pgSchema *sch); + virtual bool CanCreate(); +}; + +// collection of pgSchemaObject +class pgCatalogObjCollection : public pgCollection +{ +public: + pgCatalogObjCollection(pgaFactory *factory, pgSchema *sch); +}; + + +#endif diff --git a/include/schema/pgSequence.h b/include/schema/pgSequence.h new file mode 100644 index 0000000..da1d620 --- /dev/null +++ b/include/schema/pgSequence.h @@ -0,0 +1,112 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgSequence.h PostgreSQL Sequence +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGSEQUENCE_H +#define PGSEQUENCE_H + + +#include "pgSchema.h" + +class pgSequenceFactory : public pgSchemaObjFactory +{ +public: + pgSequenceFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + int GetReplicatedIconId() + { + return replicatedIconId; + } +private: + int replicatedIconId; +}; +extern pgSequenceFactory sequenceFactory; + +class pgSequence : public pgSchemaObject +{ +public: + pgSequence(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgSequence(); + wxString GetTranslatedMessage(int kindOfMessage) const; + int GetIconId(); + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + void ShowStatistics(frmMain *form, ctlListView *statistics); + bool CanDropCascaded() + { + return !GetSystemObject() && pgSchemaObject::CanDrop(); + } + + void UpdateValues(); + wxLongLong GetLastValue() const + { + return lastValue; + } + wxLongLong GetNextValue() const + { + return nextValue; + } + wxLongLong GetMinValue() const + { + return minValue; + } + wxLongLong GetMaxValue() const + { + return maxValue; + } + wxLongLong GetCacheValue() const + { + return cacheValue; + } + wxLongLong GetIncrement() const + { + return increment; + } + bool GetCycled() const + { + return cycled; + } + bool GetCalled() const + { + return called; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return true; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxLongLong lastValue, nextValue, minValue, maxValue, cacheValue, increment; + bool cycled, called, isReplicated; +}; + +class pgSequenceCollection : public pgSchemaObjCollection +{ +public: + pgSequenceCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgServer.h b/include/schema/pgServer.h new file mode 100644 index 0000000..edf5e96 --- /dev/null +++ b/include/schema/pgServer.h @@ -0,0 +1,709 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgServer.h - PostgreSQL Server +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGSERVER_H +#define PGSERVER_H + +#include "db/pgConn.h" +#include "pgCollection.h" + +class frmMain; +class pgServer; + +class pgServerFactory : public pgaFactory +{ +public: + pgServerFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + + int GetClosedIconId() + { + return WantSmallIcon() ? smallClosedId : closedId; + } + +protected: + int closedId, smallClosedId; +}; +extern pgServerFactory serverFactory; +#define DEFAULT_SSH_PORT 22 + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) +class CSSHTunnelThread; +#endif + +class pgServer : public pgObject +{ +public: + pgServer(const wxString &newServer = wxT(""), const wxString &newHostAddr = wxT(""), const wxString &newDescription = wxT(""), + const wxString &newService = wxT(""), const wxString &newDatabase = wxT(""), const wxString &newUsername = wxT(""), int newPort = 5432, + bool storePwd = false, const wxString &newRolename = wxT(""), bool restore = true, int sslMode = 0, + const wxString &colour = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW).GetAsString(wxC2S_HTML_SYNTAX), const wxString &group = wxEmptyString, + bool sshTunnel = false, const wxString &newTunnelHost = wxEmptyString, const wxString &newTunnelUserName = wxEmptyString, bool authModePwd = true, + const wxString &newTunnelPassword = wxEmptyString, const wxString &newPublicKey = wxEmptyString, const wxString &newIdentityFile = wxEmptyString, + const int &sshPort = DEFAULT_SSH_PORT); + ~pgServer(); + int GetIconId(); + + wxString GetTypeName() const + { + return wxT("Server"); + } + wxString GetTranslatedMessage(int kindOfMessage) const; + int Connect(frmMain *form, bool askPassword = true, const wxString &pwd = wxEmptyString, bool forceStorePassword = false, bool askTunnelPassword = false); + bool Disconnect(frmMain *form); + void StorePassword(); + bool GetPasswordIsStored(); + void InvalidatePassword() + { + passwordValid = false; + } + + bool StartService(); + bool StopService(); + bool GetServerRunning(); + bool GetServerControllable(); + bool ReloadConfiguration(); + bool IsReplayPaused(); + bool PauseReplay(); + bool ResumeReplay(); + bool AddNamedRestorePoint(); + + pgServer *GetServer() const; + + wxString GetIdentifier() const; + wxString GetVersionString(); + wxString GetVersionNumber(); + OID GetLastSystemOID(); + wxString GetHostAddr() const + { + return hostaddr; + } + wxString GetService() const + { + return service; + } + wxString GetDatabaseName() const + { + return database; + } + wxString GetUsername() const + { + return username; + } + wxString GetPassword() const + { + return (password == wxEmptyString ? conn->GetPassword() : password); + } + bool GetStorePwd() const + { + return storePwd; + } + wxString GetRolename() const + { + return rolename; + } + bool GetRestore() const + { + return restore; + } + wxString GetLastError() const; + + bool GetDiscovered() const + { + return discovered; + } + void iSetDiscovered(const bool b) + { + discovered = b; + } + wxString GetServiceID() const + { + return serviceId; + } + void iSetServiceID(const wxString &s); + wxString GetDiscoveryID() const + { + return discoveryId; + } + void iSetDiscoveryID(const wxString &s) + { + discoveryId = s; + } + + bool GetCreatePrivilege() const + { + return createPrivilege; + } + void iSetCreatePrivilege(const bool b) + { + createPrivilege = b; + } + bool GetSuperUser() const + { + return superUser; + } + void iSetSuperUser(const bool b) + { + superUser = b; + } + bool GetCreateRole() const + { + return createRole; + } + void iSetCreateRole(const bool b) + { + createRole = b; + } + + bool GetInRecovery() const + { + return inRecovery; + } + void iSetInRecovery(const bool b) + { + inRecovery = b; + } + bool GetReplayPaused() const + { + return replayPaused; + } + void SetReplayPaused(const bool b) + { + replayPaused = b; + } + wxDateTime GetConfLoadedSince() + { + return confLoadedSince; + } + void iSetConfLoadedSince(const wxDateTime &d) + { + confLoadedSince = d; + } + wxString GetReceiveLoc() const + { + return receiveLoc; + } + void iSetReceiveLoc(const wxString &s) + { + receiveLoc = s; + } + wxString GetReplayLoc() const + { + return replayLoc; + } + void iSetReplayLoc(const wxString &s) + { + replayLoc = s; + } + wxString GetReplayTimestamp() const + { + return replayTimestamp; + } + void iSetReplayTimestamp(const wxString &s) + { + replayTimestamp = s; + } + + pgConn *CreateConn(wxString dbName = wxEmptyString, OID oid = 0, wxString applicationname = wxEmptyString); + + wxString GetLastDatabase() const + { + return lastDatabase; + } + void iSetLastDatabase(const wxString &s) + { + lastDatabase = s; + } + wxString GetLastSchema() const + { + return lastSchema; + } + void iSetLastSchema(const wxString &s) + { + lastSchema = s; + } + wxString GetDescription() const + { + return description; + } + void iSetDescription(const wxString &s) + { + description = s; + } + void iSetHostAddr(const wxString &s) + { + hostaddr = s; + } + + wxString GetDbRestriction() const + { + return dbRestriction; + } + void iSetDbRestriction(const wxString &s) + { + dbRestriction = s; + } + + long GetServerIndex() const + { + return serverIndex; + } + void iSetServerIndex(long l) + { + serverIndex = l; + } + wxString GetFullName(); + wxString GetFullIdentifier(); + int GetPort() const + { + return port; + } + int GetSSL() const + { + return ssl; + } + bool GetConnected() const + { + return connected; + } + void iSetService(const wxString &newVal) + { + service = newVal; + } + void iSetDatabase(const wxString &newVal) + { + database = newVal; + } + void iSetPort(int newval) + { + port = newval; + } + void iSetSSL(int newval) + { + ssl = newval; + } + void iSetUsername(const wxString &newVal) + { + username = newVal; + } + void iSetPassword(const wxString &newVal) + { + password = newVal; + } + void iSetStorePwd(const bool b) + { + storePwd = b; + } + void iSetRolename(const wxString &newVal) + { + rolename = newVal; + } + void iSetRestore(const bool b) + { + restore = b; + } + bool SetPassword(const wxString &newVal); + wxDateTime GetUpSince() + { + return upSince; + } + void iSetUpSince(const wxDateTime &d) + { + upSince = d; + } + void iSetColour(const wxString &s) + { + colour = s; + } + wxString GetColour() + { + return colour; + } + + void iSetGroup(const wxString &s) + { + group = s; + } + wxString GetGroup() + { + return group; + } + + bool HasPrivilege(const wxString &objTyp, const wxString &objName, const wxString &priv) + { + return conn->HasPrivilege(objTyp, objName, priv); + } + bool ExecuteVoid(const wxString &sql) + { + return conn->ExecuteVoid(sql); + } + wxString ExecuteScalar(const wxString &sql) + { + return conn->ExecuteScalar(sql); + } + pgSet *ExecuteSet(const wxString &sql) + { + return conn->ExecuteSet(sql); + } + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + void ShowHint(frmMain *form, bool force); + void ShowStatistics(frmMain *form, ctlListView *statistics); + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/managing-databases"); + } + wxMenu *GetNewMenu(); + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) + { + return true; + } + bool GetCanHint(); + bool CanEdit() + { + return true; + } + bool CanDrop() + { + return true; + } + bool CanBackupGlobals() + { + return true; + } + bool HasStats() + { + return true; + } + bool HasDepends() + { + return false; + } + bool HasReferences() + { + return false; + } + + pgConn *connection() + { + return conn; + } + + wxString GetSSLCert() const + { + return sslcert; + } + void SetSSLCert(const wxString &s) + { + sslcert = s; + } + wxString GetSSLKey() const + { + return sslkey; + } + void SetSSLKey(const wxString &s) + { + sslkey = s; + } + wxString GetSSLRootCert() const + { + return sslrootcert; + } + void SetSSLRootCert(const wxString &s) + { + sslrootcert = s; + } + wxString GetSSLCrl() const + { + return sslcrl; + } + void SetSSLCrl(const wxString &s) + { + sslcrl = s; + } + + bool GetSSLCompression() const + { + return sslcompression; + } + void iSetSSLCompression(const bool b) + { + sslcompression = b; + } + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + //SSH Tunnel + bool GetSSHTunnel() const + { + return sshTunnel; + } + void iSetSSHTunnel(const bool b) + { + sshTunnel = b; + } + bool GetAuthModePwd() const + { + return authModePwd; + } + void iSetAuthModePwd(const bool b) + { + authModePwd = b; + } + wxString GetLocalListenHost() const + { + return local_listenhost; + } + void SetLocalListenHost(const wxString &s) + { + local_listenhost = s; + } + int GetLocalListenPort() const + { + return local_listenport; + } + void SetLocalListenPort(int newVal) + { + local_listenport = newVal; + } + wxString GetTunnelHost() const + { + return tunnelHost; + } + void SetTunnelHost(const wxString &s) + { + tunnelHost = s; + } + wxString GetTunnelUserName() const + { + return tunnelUserName; + } + void SetTunnelUserName(const wxString &s) + { + tunnelUserName = s; + } + wxString GetTunnelPassword() const + { + return tunnelPassword; + } + void SetTunnelPassword(const wxString &s) + { + tunnelPassword = s; + } + wxString GetPublicKeyFile() const + { + return publicKeyFile; + } + void SetPublicKeyFile(const wxString &s) + { + publicKeyFile = s; + } + wxString GetIdentityFile() const + { + return identityFile; + } + void SetIdentityFile(const wxString &s) + { + identityFile = s; + } + int GetTunnelPort() const + { + return tunnelPort; + } + void iSetTunnelPort(const int newval) + { + tunnelPort = newval; + } +#endif + + void ShowDependencies(frmMain *form, ctlListView *Dependencies, const wxString &where = wxEmptyString); + void ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &where = wxEmptyString); + +private: + wxString passwordFilename(); + + pgConn *conn; + long serverIndex; + bool connected, passwordValid, autovacuumRunning; + wxString service, hostaddr, database, username, password, rolename, ver, error; + wxString lastDatabase, lastSchema, description, serviceId, discoveryId; + wxDateTime upSince; + int port, ssl; + bool storePwd, restore, discovered, createPrivilege, superUser, createRole; + OID lastSystemOID; + OID dbOid; + wxString versionNum; + wxString dbRestriction; + wxString colour; + wxString group; + wxString sslcert, sslkey, sslrootcert, sslcrl; + bool sslcompression; + bool sshTunnel; + + bool inRecovery, replayPaused; + wxString receiveLoc, replayLoc, replayTimestamp; + wxDateTime confLoadedSince; + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + bool createSSHTunnel(); + + //SSH Tunnel + CSSHTunnelThread *tunnelObj; + bool authModePwd; + int local_listenport; + int tunnelPort; + wxString tunnelHost, tunnelUserName, tunnelPassword, publicKeyFile, identityFile, local_listenhost; +#endif + +#ifdef WIN32 + SC_HANDLE scmHandle; + SC_HANDLE serviceHandle; + wxArrayString GetDependentServices(SC_HANDLE handle); +#endif +}; + + +// collection of pgServer +class pgServerCollection : public pgCollection +{ +public: + pgServerCollection(pgaFactory *factory); + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0) {}; +}; + + +/////////////////////////////////////////////// + + +class pgServerObjFactory : public pgaFactory +{ +public: + pgServerObjFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm = 0) + : pgaFactory(tn, ns, nls, img, imgSm) {} + virtual pgCollection *CreateCollection(pgObject *obj); +}; + + +// Object that lives under a server +class pgServerObject : public pgObject +{ +public: + pgServerObject(pgaFactory &factory, const wxString &newName = wxEmptyString) : pgObject(factory, newName) {} + pgServerObject(int newType, const wxString &newName) : pgObject(newType, newName) {} + + void iSetServer(pgServer *s) + { + server = s; + } + pgServer *GetServer() const + { + return server; + } + + void FillOwned(ctlTree *browser, ctlListView *referencedBy, const wxArrayString &dblist, const wxString &query); + + bool CanCreate(); + bool CanDrop(); + bool CanEdit() + { + return true; + } + +protected: + pgServer *server; +}; + + +// collection of pgServerObject +class pgServerObjCollection : public pgCollection +{ +public: + pgServerObjCollection(pgaFactory *factory, pgServer *server); + bool CanCreate(); +}; + +class addServerFactory : public actionFactory +{ +public: + addServerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + + +class startServiceFactory : public contextActionFactory +{ +public: + startServiceFactory (menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class stopServiceFactory : public contextActionFactory +{ +public: + stopServiceFactory (menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +class connectServerFactory : public contextActionFactory +{ +public: + connectServerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +class disconnectServerFactory : public contextActionFactory +{ +public: + disconnectServerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class reloadconfServiceFactory : public contextActionFactory +{ +public: + reloadconfServiceFactory (menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class pausereplayServiceFactory : public contextActionFactory +{ +public: + pausereplayServiceFactory (menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class resumereplayServiceFactory : public contextActionFactory +{ +public: + resumereplayServiceFactory (menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class addnamedrestorepointServiceFactory : public contextActionFactory +{ +public: + addnamedrestorepointServiceFactory (menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif diff --git a/include/schema/pgTable.h b/include/schema/pgTable.h new file mode 100644 index 0000000..e3e205f --- /dev/null +++ b/include/schema/pgTable.h @@ -0,0 +1,729 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgTable.h PostgreSQL Table +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGTABLE_H +#define PGTABLE_H + +#include "pgSchema.h" + + +enum +{ + REPLICATIONSTATUS_NONE = 0, + REPLICATIONSTATUS_SUBSCRIBED, + REPLICATIONSTATUS_REPLICATED, + REPLICATIONSTATUS_MULTIPLY_PUBLISHED +}; + + +class pgTableFactory : public pgSchemaObjFactory +{ +public: + pgTableFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + int GetReplicatedIconId() + { + return replicatedIconId; + } + int GetPartitionsIconId() + { + return partitionsIconId; + } +private: + int replicatedIconId; + int partitionsIconId; +}; +extern pgTableFactory tableFactory; + +class slSet; +class pgTable : public pgSchemaObject +{ +public: + pgTable(pgSchema *newSchema, const wxString &newName = wxT("")); + pgTable(pgSchema *newSchema, pgaFactory &factory, const wxString &newName = wxT("")); + ~pgTable(); + wxString GetTranslatedMessage(int kindOfMessage) const; + int GetIconId(); + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + void ShowHint(frmMain *form, bool force); + void ShowStatistics(frmMain *form, ctlListView *statistics); + + bool CanDropCascaded() + { + return !GetSystemObject() && pgSchemaObject::CanDrop(); + } + int GetReplicationStatus(ctlTree *browser, wxString *clusterName = 0, long *setId = 0); + + bool GetHasOids() const + { + return hasOids; + } + void iSetHasOids(bool b) + { + hasOids = b; + } + bool GetUnlogged() const + { + return unlogged; + } + void iSetUnlogged(bool b) + { + unlogged = b; + } + wxString GetPrimaryKey() const + { + return primaryKey; + } + void iSetPrimaryKey(const wxString &s) + { + primaryKey = s; + } + wxString GetQuotedPrimaryKey() const + { + return quotedPrimaryKey; + } + void iSetQuotedPrimaryKey(const wxString &s) + { + quotedPrimaryKey = s; + } + wxString GetPrimaryKeyColNumbers() const + { + return primaryKeyColNumbers; + } + void iSetPrimaryKeyColNumbers(const wxString &s) + { + primaryKeyColNumbers = s; + } + wxString GetPrimaryKeyName() const + { + return primaryKeyName; + } + void iSetPrimaryKeyName(const wxString &s) + { + primaryKeyName = s; + } + wxString GetDistributionColNumbers() const + { + return distributionColNumbers; // for Greenplum + } + void iSetDistributionColNumbers(const wxString &s) + { + distributionColNumbers = s; // for Greenplum + if (s.Length() > 0) distributionIsRandom = false; + } + void iSetDistributionIsRandom() + { + distributionIsRandom = true; + } + double GetEstimatedRows() const + { + return estimatedRows; + } + void iSetEstimatedRows(const double d) + { + estimatedRows = d; + } + wxString GetTablespace() const + { + return tablespace; + }; + void iSetTablespace(const wxString &newVal) + { + tablespace = newVal; + } + OID GetTablespaceOid() const + { + return tablespaceOid; + }; + void iSetTablespaceOid(const OID newVal) + { + tablespaceOid = newVal; + } + wxString GetOfType() const + { + return ofType; + }; + void iSetOfType(const wxString &newVal) + { + ofType = newVal; + } + OID GetOfTypeOid() const + { + return ofTypeOid; + }; + void iSetOfTypeOid(const OID newVal) + { + ofTypeOid = newVal; + } + wxULongLong GetRows() const + { + return rows; + } + long GetInheritedTableCount() + { + if (inheritedTableCount < 0) UpdateInheritance(); + return inheritedTableCount; + } + wxString GetInheritedTables() + { + GetInheritedTableCount(); + return inheritedTables; + } + wxString GetQuotedInheritedTables() + { + GetInheritedTableCount(); + return quotedInheritedTables; + } + wxArrayString GetInheritedTablesOidList() + { + GetInheritedTableCount(); + return inheritedTablesOidList; + } + wxArrayString GetQuotedInheritedTablesList() + { + GetInheritedTableCount(); + return quotedInheritedTablesList; + } + wxString GetCoveringIndex(ctlTree *browser, const wxString &collist); + pgCollection *GetColumnCollection(ctlTree *browser); + pgCollection *GetConstraintCollection(ctlTree *browser); + bool GetHasSubclass() const + { + return hasSubclass; + } + void iSetHasSubclass(bool b) + { + hasSubclass = b; + } + void iSetIsReplicated(bool b) + { + isReplicated = b; + } + bool GetIsReplicated() const + { + return isReplicated; + } + void iSetTriggerCount(long l) + { + triggerCount = l; + } + int GetTriggerCount() const + { + return triggerCount; + } + bool EnableTriggers(const bool b); + void UpdateRows(); + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + bool Truncate(bool cascaded); + bool ResetStats(); + bool CanView() + { + return true; + } + bool CanMaintenance() + { + return true; + } + bool CanBackup() + { + return true; + } + bool CanRestore() + { + return true; + } + bool WantDummyChild() + { + return true; + } + bool GetCanHint(); + bool GetShowExtendedStatistics() + { + return showExtendedStatistics; + } + void iSetShowExtendedStatistics(bool b) + { + showExtendedStatistics = b; + } + wxString GetFillFactor() + { + return fillFactor; + } + void iSetFillFactor(const wxString &s) + { + fillFactor = s; + } + wxString GetAppendOnly() + { + return appendOnly; + } + void iSetAppendOnly(const wxString &s) + { + appendOnly = s; + } + wxString GetCompressLevel() + { + return compressLevel; + } + void iSetCompressLevel(const wxString &s) + { + compressLevel = s; + } + wxString GetOrientation() + { + return orientation; + } + void iSetOrientation(const wxString &s) + { + orientation = s; + } + wxString GetCompressType() + { + return compresstype; + } + void iSetCompressType(const wxString &s) + { + compresstype = s; + }; + wxString GetBlocksize() + { + return blocksize; + } + void iSetBlocksize(const wxString &s) + { + blocksize = s; + }; + wxString GetChecksum() + { + return checksum; + } + void iSetChecksum(const wxString &s) + { + checksum = s; + }; + wxString GetPartitionDef() + { + return partitionDef; + } + void iSetPartitionDef(const wxString &s) + { + partitionDef = s; + } + wxString GetPartKeyDef() + { + return partkeydef; + } + void iSetPartKeyDef(const wxString &s) + { + partkeydef = s; + } + wxString GetPartExp() + { + return partexp; + } + void iSetPartExp(const wxString &s) + { + partexp = s; + } + bool GetIsPartitioned() const + { + return isPartitioned || partitionDef.Length() > 0; + } + void iSetIsPartitioned(bool b) + { + isPartitioned = b; + } + + bool GetCustomAutoVacuumEnabled() + { + return !reloptions.IsEmpty(); + } + wxString GetRelOptions() + { + return reloptions; + } + void iSetRelOptions(const wxString &s) + { + reloptions = s; + } + int GetAutoVacuumEnabled() + { + return autovacuum_enabled; + } + void iSetAutoVacuumEnabled(int i) + { + autovacuum_enabled = i; + } + wxString GetAutoVacuumVacuumThreshold() + { + return autovacuum_vacuum_threshold; + } + void iSetAutoVacuumVacuumThreshold(const wxString &s) + { + autovacuum_vacuum_threshold = s; + } + wxString GetAutoVacuumVacuumScaleFactor() + { + return autovacuum_vacuum_scale_factor; + } + void iSetAutoVacuumVacuumScaleFactor(const wxString &s) + { + autovacuum_vacuum_scale_factor = s; + } + wxString GetAutoVacuumAnalyzeThreshold() + { + return autovacuum_analyze_threshold; + } + void iSetAutoVacuumAnalyzeThreshold(const wxString &s) + { + autovacuum_analyze_threshold = s; + } + wxString GetAutoVacuumAnalyzeScaleFactor() + { + return autovacuum_analyze_scale_factor; + } + void iSetAutoVacuumAnalyzeScaleFactor(const wxString &s) + { + autovacuum_analyze_scale_factor = s; + } + wxString GetAutoVacuumVacuumCostDelay() + { + return autovacuum_vacuum_cost_delay; + } + void iSetAutoVacuumVacuumCostDelay(const wxString &s) + { + autovacuum_vacuum_cost_delay = s; + } + wxString GetAutoVacuumVacuumCostLimit() + { + return autovacuum_vacuum_cost_limit; + } + void iSetAutoVacuumVacuumCostLimit(const wxString &s) + { + autovacuum_vacuum_cost_limit = s; + } + wxString GetAutoVacuumFreezeMinAge() + { + return autovacuum_freeze_min_age; + } + void iSetAutoVacuumFreezeMinAge(const wxString &s) + { + autovacuum_freeze_min_age = s; + } + wxString GetAutoVacuumFreezeMaxAge() + { + return autovacuum_freeze_max_age; + } + void iSetAutoVacuumFreezeMaxAge(const wxString &s) + { + autovacuum_freeze_max_age = s; + } + wxString GetAutoVacuumFreezeTableAge() + { + return autovacuum_freeze_table_age; + } + void iSetAutoVacuumFreezeTableAge(const wxString &s) + { + autovacuum_freeze_table_age = s; + } + bool GetHasToastTable() + { + return hasToastTable; + } + void iSetHasToastTable(bool b) + { + hasToastTable = b; + } + + /* TOAST TABLE autovacuum settings */ + bool GetToastCustomAutoVacuumEnabled() + { + return !toast_reloptions.IsEmpty(); + } + wxString GetToastRelOptions() + { + return toast_reloptions; + } + void iSetToastRelOptions(const wxString &s) + { + toast_reloptions = s; + } + int GetToastAutoVacuumEnabled() + { + return toast_autovacuum_enabled; + } + void iSetToastAutoVacuumEnabled(int i) + { + toast_autovacuum_enabled = i; + } + wxString GetToastAutoVacuumVacuumThreshold() + { + return toast_autovacuum_vacuum_threshold; + } + void iSetToastAutoVacuumVacuumThreshold(const wxString &s) + { + toast_autovacuum_vacuum_threshold = s; + } + wxString GetToastAutoVacuumVacuumScaleFactor() + { + return toast_autovacuum_vacuum_scale_factor; + } + void iSetToastAutoVacuumVacuumScaleFactor(const wxString &s) + { + toast_autovacuum_vacuum_scale_factor = s; + } + wxString GetToastAutoVacuumVacuumCostDelay() + { + return toast_autovacuum_vacuum_cost_delay; + } + void iSetToastAutoVacuumVacuumCostDelay(const wxString &s) + { + toast_autovacuum_vacuum_cost_delay = s; + } + wxString GetToastAutoVacuumVacuumCostLimit() + { + return toast_autovacuum_vacuum_cost_limit; + } + void iSetToastAutoVacuumVacuumCostLimit(const wxString &s) + { + toast_autovacuum_vacuum_cost_limit = s; + } + wxString GetToastAutoVacuumFreezeMinAge() + { + return toast_autovacuum_freeze_min_age; + } + void iSetToastAutoVacuumFreezeMinAge(const wxString &s) + { + toast_autovacuum_freeze_min_age = s; + } + wxString GetToastAutoVacuumFreezeMaxAge() + { + return toast_autovacuum_freeze_max_age; + } + void iSetToastAutoVacuumFreezeMaxAge(const wxString &s) + { + toast_autovacuum_freeze_max_age = s; + } + wxString GetToastAutoVacuumFreezeTableAge() + { + return toast_autovacuum_freeze_table_age; + } + void iSetToastAutoVacuumFreezeTableAge(const wxString &s) + { + toast_autovacuum_freeze_table_age = s; + } + + bool HasStats() + { + return true; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + bool HasPgstattuple(); + + virtual wxMenu *GetNewMenu(); + virtual wxString GetSql(ctlTree *browser); + wxString GetSelectSql(ctlTree *browser); + wxString GetInsertSql(ctlTree *browser); + wxString GetUpdateSql(ctlTree *browser); + wxString GetDeleteSql(ctlTree *browser); + wxString GetHelpPage(bool forCreate) const; + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + void iSetTriggersEnabled(ctlTree *browser, bool enable); + +private: + void UpdateInheritance(); + bool GetVacuumHint(); + wxString GetCols(ctlTree *browser, size_t indent, wxString &QMs, bool withQM); + void AppendStuff(wxString &sql, ctlTree *browser, pgaFactory &factory); + void AppendStuffNoSql(wxString &sql, ctlTree *browser, pgaFactory &factory); + + void Init(); + + wxULongLong rows; + double estimatedRows; + + bool hasToastTable; + /* + * Three possible values: + * 0 - Disabled + * 1 - Enabled + * 2 - GUC Setting + */ + int autovacuum_enabled, toast_autovacuum_enabled; + wxString reloptions, toast_reloptions; + + wxString fillFactor, autovacuum_vacuum_threshold, + autovacuum_vacuum_scale_factor, autovacuum_analyze_threshold, + autovacuum_analyze_scale_factor, autovacuum_vacuum_cost_delay, + autovacuum_vacuum_cost_limit, autovacuum_freeze_min_age, + autovacuum_freeze_max_age, autovacuum_freeze_table_age; + wxString appendOnly; + wxString compressLevel; + wxString orientation; // "row" or "column" + wxString compresstype; + wxString blocksize; + wxString checksum; + wxString partkeydef; // partition feature 10 version + wxString partexp; // partition feature 10 version + wxString partitionDef; + bool isPartitioned; + bool hasOids, unlogged, hasSubclass, rowsCounted, isReplicated, showExtendedStatistics, distributionIsRandom; + + wxString toast_fillFactor, toast_autovacuum_vacuum_threshold, + toast_autovacuum_vacuum_scale_factor, toast_autovacuum_vacuum_cost_delay, + toast_autovacuum_vacuum_cost_limit, toast_autovacuum_freeze_min_age, + toast_autovacuum_freeze_max_age, toast_autovacuum_freeze_table_age; + + long inheritedTableCount, triggerCount; + wxString quotedInheritedTables, inheritedTables, primaryKey, quotedPrimaryKey, + primaryKeyName, primaryKeyColNumbers, tablespace, + distributionColNumbers, ofType; + wxArrayString quotedInheritedTablesList, inheritedTablesOidList; + + slSet *replicationSet; + OID tablespaceOid; + OID ofTypeOid; +}; + + +class pgTableObject : public pgSchemaObject +{ +public: + pgTableObject(pgTable *newTable, pgaFactory &factory, const wxString &newName = wxT("")) + : pgSchemaObject(newTable->GetSchema(), factory, newName) + { + table = newTable; + } + virtual pgTable *GetTable() const + { + return table; + } + OID GetTableOid() const + { + return table->GetOid(); + } + wxString GetTableOidStr() const + { + return NumToStr(table->GetOid()) + wxT("::oid"); + } + +protected: + pgTable *table; +}; + + +class pgTableCollection : public pgSchemaObjCollection +{ +public: + pgTableCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowStatistics(frmMain *form, ctlListView *statistics); +}; + +class pgTableObjCollection : public pgSchemaObjCollection +{ +public: + pgTableObjCollection(pgaFactory *factory, pgTable *_table) + : pgSchemaObjCollection(factory, _table->GetSchema()) + { + iSetOid(_table->GetOid()); + table = _table; + } + virtual pgTable *GetTable() const + { + return table; + } + bool CanCreate(); + +protected: + pgTable *table; +}; + +class pgTableObjFactory : public pgSchemaObjFactory +{ +public: + pgTableObjFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm = 0) + : pgSchemaObjFactory(tn, ns, nls, img, imgSm) {} + virtual pgCollection *CreateCollection(pgObject *obj); +}; + +class countRowsFactory : public contextActionFactory +{ +public: + countRowsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +class executePgstattupleFactory : public contextActionFactory +{ +public: + executePgstattupleFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); + bool CheckChecked(pgObject *obj); +}; + +class disableAllTriggersFactory : public contextActionFactory +{ +public: + disableAllTriggersFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class enableAllTriggersFactory : public contextActionFactory +{ +public: + enableAllTriggersFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class truncateFactory : public contextActionFactory +{ +public: + truncateFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +class truncateCascadedFactory : public contextActionFactory +{ +public: + truncateCascadedFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +class resetTableStatsFactory : public contextActionFactory +{ +public: + resetTableStatsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +#endif diff --git a/include/schema/pgTablespace.h b/include/schema/pgTablespace.h new file mode 100644 index 0000000..e095028 --- /dev/null +++ b/include/schema/pgTablespace.h @@ -0,0 +1,99 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgTablespace.h - PostgreSQL Tablespace +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGTABLESPACE_H +#define PGTABLESPACE_H + + +#include "pgServer.h" + +class pgTablespaceFactory : public pgServerObjFactory +{ +public: + pgTablespaceFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgTablespaceFactory tablespaceFactory; + + +class pgTablespace : public pgServerObject +{ +public: + pgTablespace(const wxString &newName = wxT("")); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + void ShowStatistics(frmMain *form, ctlListView *statistics); + void ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &where = wxEmptyString); + + wxString GetLocation() const + { + return location; + }; + void iSetLocation(const wxString &newVal) + { + location = newVal; + } + wxArrayString &GetVariables() + { + return variables; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + bool RequireDropConfirm() + { + return true; + } + pgConn *connection(); + + wxString GetSql(ctlTree *browser); + void MoveTablespace(frmMain *form); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return true; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString location; + wxArrayString variables; +}; + + +class pgTablespaceCollection : public pgServerObjCollection +{ +public: + pgTablespaceCollection(pgaFactory *factory, pgServer *sv); + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowStatistics(frmMain *form, ctlListView *statistics); +}; + +class moveTablespaceFactory : public contextActionFactory +{ +public: + moveTablespaceFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +#endif diff --git a/include/schema/pgTextSearchConfiguration.h b/include/schema/pgTextSearchConfiguration.h new file mode 100644 index 0000000..1d116ae --- /dev/null +++ b/include/schema/pgTextSearchConfiguration.h @@ -0,0 +1,109 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgTextSearchConfiguration.h PostgreSQL Text Search Configuration +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PG_TSCONFIGURATION_H +#define PG_TSCONFIGURATION_H + + +#include "pgSchema.h" + + +class pgTextSearchConfigurationFactory : public pgSchemaObjFactory +{ +public: + pgTextSearchConfigurationFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgTextSearchConfigurationFactory textSearchConfigurationFactory; + +class pgTextSearchConfiguration : public pgSchemaObject +{ +public: + pgTextSearchConfiguration(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgTextSearchConfiguration(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return GetSchema()->GetMetaType() != PGM_CATALOG; + } + + wxString GetParser() const + { + return parser; + } + void iSetParser(const wxString &s) + { + parser = s; + } + wxString GetCopy() const + { + return copy; + } + void iSetCopy(const wxString &s) + { + copy = s; + } + OID GetParserOid() const + { + return parserOid; + } + void iSetParserOid(const OID o) + { + parserOid = o; + } + wxString GetParserOidStr() const + { + return NumToStr(GetParserOid()) + wxT("::oid"); + } + wxArrayString &GetTokens() + { + return tokens; + } + virtual wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createtsconfig"); + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString parser, copy; + OID parserOid; + wxArrayString tokens; +}; + +class pgTextSearchConfigurationCollection : public pgSchemaObjCollection +{ +public: + pgTextSearchConfigurationCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgTextSearchDictionary.h b/include/schema/pgTextSearchDictionary.h new file mode 100644 index 0000000..7b6a696 --- /dev/null +++ b/include/schema/pgTextSearchDictionary.h @@ -0,0 +1,91 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgTextSearchDictionary.h PostgreSQL Text Search Dictionary +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PG_TSDICTIONARY_H +#define PG_TSDICTIONARY_H + + +#include "pgSchema.h" + + +class pgTextSearchDictionaryFactory : public pgSchemaObjFactory +{ +public: + pgTextSearchDictionaryFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgTextSearchDictionaryFactory textSearchDictionaryFactory; + +class pgTextSearchDictionary : public pgSchemaObject +{ +public: + pgTextSearchDictionary(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgTextSearchDictionary(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return GetSchema()->GetMetaType() != PGM_CATALOG; + } + + wxString GetTemplate() const + { + return tmpl; + } + void iSetTemplate(const wxString &s) + { + tmpl = s; + } + wxString GetOptions() const + { + return options; + } + void iSetOptions(const wxString &s) + { + options = s; + } + virtual wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createtsdictionary"); + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString tmpl, options; +}; + +class pgTextSearchDictionaryCollection : public pgSchemaObjCollection +{ +public: + pgTextSearchDictionaryCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgTextSearchParser.h b/include/schema/pgTextSearchParser.h new file mode 100644 index 0000000..ae46c40 --- /dev/null +++ b/include/schema/pgTextSearchParser.h @@ -0,0 +1,115 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgTextSearchParser.h PostgreSQL Text Search Parser +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PG_TSPARSER_H +#define PG_TSPARSER_H + + +#include "pgSchema.h" + + +class pgTextSearchParserFactory : public pgSchemaObjFactory +{ +public: + pgTextSearchParserFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgTextSearchParserFactory textSearchParserFactory; + +class pgTextSearchParser : public pgSchemaObject +{ +public: + pgTextSearchParser(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgTextSearchParser(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + virtual wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createtsparser"); + } + bool CanDropCascaded() + { + return GetSchema()->GetMetaType() != PGM_CATALOG; + } + + wxString GetStart() const + { + return start; + } + void iSetStart(const wxString &s) + { + start = s; + } + wxString GetGettoken() const + { + return gettoken; + } + void iSetGettoken(const wxString &s) + { + gettoken = s; + } + wxString GetEnd() const + { + return end; + } + void iSetEnd(const wxString &s) + { + end = s; + } + wxString GetLextypes() const + { + return lextypes; + } + void iSetLextypes(const wxString &s) + { + lextypes = s; + } + wxString GetHeadline() const + { + return headline; + } + void iSetHeadline(const wxString &s) + { + headline = s; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString start, gettoken, end, lextypes, headline; +}; + +class pgTextSearchParserCollection : public pgSchemaObjCollection +{ +public: + pgTextSearchParserCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgTextSearchTemplate.h b/include/schema/pgTextSearchTemplate.h new file mode 100644 index 0000000..8ebda16 --- /dev/null +++ b/include/schema/pgTextSearchTemplate.h @@ -0,0 +1,91 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgTextSearchTemplate.h PostgreSQL Text Search Template +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PG_TSTEMPLATE_H +#define PG_TSTEMPLATE_H + + +#include "pgSchema.h" + + +class pgTextSearchTemplateFactory : public pgSchemaObjFactory +{ +public: + pgTextSearchTemplateFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgTextSearchTemplateFactory textSearchTemplateFactory; + +class pgTextSearchTemplate : public pgSchemaObject +{ +public: + pgTextSearchTemplate(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgTextSearchTemplate(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + virtual wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createtstemplate"); + } + bool CanDropCascaded() + { + return GetSchema()->GetMetaType() != PGM_CATALOG; + } + + wxString GetInit() const + { + return init; + } + void iSetInit(const wxString &s) + { + init = s; + } + wxString GetLexize() const + { + return lexize; + } + void iSetLexize(const wxString &s) + { + lexize = s; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString init, lexize; +}; + +class pgTextSearchTemplateCollection : public pgSchemaObjCollection +{ +public: + pgTextSearchTemplateCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgTrigger.h b/include/schema/pgTrigger.h new file mode 100644 index 0000000..ec36666 --- /dev/null +++ b/include/schema/pgTrigger.h @@ -0,0 +1,280 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgTrigger.h PostgreSQL Trigger +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGTRIGGER_H +#define PGTRIGGER_H + +#include "pgTable.h" + +class pgFunction; + +class pgTriggerObject : public pgSchemaObject +{ +public: + pgTriggerObject(pgSchema *newSchema, pgaFactory &factory, const wxString &newName = wxEmptyString) : pgSchemaObject(newSchema, factory, newName) {} + + wxString GetFormattedDefinition(); + wxString GetDefinition() const + { + return definition; + } + void iSetDefinition(const wxString &s) + { + definition = s; + } + +protected: + wxString definition; +}; + + + +class pgTriggerFactory : public pgSchemaObjFactory +{ +public: + pgTriggerFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + + int GetClosedIconId() + { + return closedId; + } + +protected: + int closedId; +}; +extern pgTriggerFactory triggerFactory; + + +class pgTrigger : public pgTriggerObject +{ +public: + pgTrigger(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgTrigger(); + + int GetIconId(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return !GetSystemObject() && pgSchemaObject::CanDrop(); + } + + wxString GetFireWhen() const; + wxString GetEvent() const; + wxString GetForEach() const; + wxString GetFunction() const + { + return function; + } + void iSetFunction(const wxString &s) + { + function = s; + } + void iSetArguments(const wxString &s) + { + arguments = s; + } + wxString GetArguments() const + { + return arguments; + } + void iSetWhen(const wxString &s) + { + when = s; + } + wxString GetWhen() const + { + return when; + } + bool GetIsConstraint() const + { + return isconstraint; + } + void SetIsConstraint(const bool b) + { + isconstraint = b; + } + bool GetDeferrable() const + { + return deferrable; + } + void iSetDeferrable(const bool b) + { + deferrable = b; + } + bool GetDeferred() const + { + return deferred; + } + void iSetDeferred(const bool b) + { + deferred = b; + } + wxString GetLanguage() const + { + return language; + } + void iSetLanguage(const wxString &s) + { + language = s; + } + wxString GetSource() const + { + return source; + } + void iSetSource(const wxString &s) + { + source = s; + } + wxString GetReferences() const + { + return references; + } + void iSetReferences(const wxString &s) + { + references = s; + } + + long GetTriggerType() const + { + return triggerType; + } + void iSetTriggerType(const long l) + { + triggerType = l; + } + bool GetEnabled() const + { + return enabled; + } + void SetEnabled(ctlTree *browser, const bool b); + void iSetEnabled(const bool b) + { + enabled = b; + } + void iSetTriggerFunction(pgFunction *fkt) + { + triggerFunction = fkt; + } + wxString GetQuotedFullTable() const + { + return quotedFullTable; + } + void iSetQuotedFullTable(const wxString &s) + { + quotedFullTable = s; + } + OID GetFunctionOid() const + { + return functionOid; + } + void iSetFunctionOid(const OID d) + { + functionOid = d; + } + OID GetRelationOid() const + { + return relationOid; + } + void iSetRelationOid(const OID d) + { + relationOid = d; + } + wxString GetQuotedColumns() const + { + return quotedColumns; + } + wxString GetColumns() const + { + return columns; + } + wxArrayString GetColumnList() const + { + return columnList; + } + long GetColumnCount() const + { + return columnCount; + } + void iSetColumnCount(const long l) + { + columnCount = l; + } + void iSetParentIsTable(const bool b) + { + parentistable = b; + } + bool GetParentIsTable() + { + return parentistable; + } + + void SetDirty(); + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + bool CanRestore() + { + return true; + } + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + + bool IsUpToDate(); + +protected: + void ReadColumnDetails(); + +private: + wxString function, quotedFullTable, arguments, when, language, source, columns, quotedColumns,references; + wxArrayString columnList; + long columnCount; + OID functionOid, relationOid; + long triggerType; + bool enabled, parentistable, isconstraint, deferrable, deferred; + pgFunction *triggerFunction; +}; + + +class pgTriggerCollection : public pgSchemaObjCollection +{ +public: + pgTriggerCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + + +class enabledisableTriggerFactory : public contextActionFactory +{ +public: + enabledisableTriggerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); + bool CheckChecked(pgObject *obj); +}; + +#endif diff --git a/include/schema/pgType.h b/include/schema/pgType.h new file mode 100644 index 0000000..9d7461c --- /dev/null +++ b/include/schema/pgType.h @@ -0,0 +1,347 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgType.h PostgreSQL Type +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGTYPE_H +#define PGTYPE_H + +#include "pgSchema.h" + +// Note: This must match the radio buttons on dlgType +enum TYPE_CLASS +{ + TYPE_COMPOSITE = 0, + TYPE_ENUM, + TYPE_EXTERNAL, + TYPE_RANGE +}; + +class pgTypeFactory : public pgSchemaObjFactory +{ +public: + pgTypeFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgTypeFactory typeFactory; + +class pgType : public pgSchemaObject +{ +public: + pgType(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgType(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return !GetSystemObject() && pgSchemaObject::CanDrop(); + } + + wxString GetAlias() const + { + return alias; + } + void iSetAlias(const wxString &s) + { + alias = s; + } + wxString GetInputFunction() const + { + return inputFunction; + } + void iSetInputFunction(const wxString &s) + { + inputFunction = s; + } + wxString GetOutputFunction() const + { + return outputFunction; + } + void iSetOutputFunction(const wxString &s) + { + outputFunction = s; + } + wxString GetReceiveFunction() const + { + return receiveFunction; + } + void iSetReceiveFunction(const wxString &s) + { + receiveFunction = s; + } + wxString GetSendFunction() const + { + return sendFunction; + } + void iSetSendFunction(const wxString &s) + { + sendFunction = s; + } + wxString GetTypmodinFunction() const + { + return typmodinFunction; + } + void iSetTypmodinFunction(const wxString &s) + { + typmodinFunction = s; + } + wxString GetTypmodoutFunction() const + { + return typmodoutFunction; + } + void iSetTypmodoutFunction(const wxString &s) + { + typmodoutFunction = s; + } + wxString GetAnalyzeFunction() const + { + return analyzeFunction; + } + void iSetAnalyzeFunction(const wxString &s) + { + analyzeFunction = s; + } + wxString GetCategory() const + { + return category; + } + void iSetCategory(const wxString &s) + { + category = s; + } + bool GetPrefered() const + { + return prefered; + } + void iSetPrefered(const bool b) + { + prefered = b; + } + wxString GetDefault() const + { + return defaultVal; + } + void iSetDefault(const wxString &s) + { + defaultVal = s; + } + wxString GetElement() + { + return element; + } + void iSetElement(const wxString &s) + { + element = s; + } + wxString GetDelimiter() const + { + return delimiter; + } + void iSetDelimiter(const wxString &s) + { + delimiter = s; + } + wxString GetAlignment() const + { + return alignment; + } + void iSetAlignment(const wxString &s) + { + alignment = s; + } + wxString GetStorage() const + { + return storage; + } + void iSetStorage(const wxString &s) + { + storage = s; + } + long GetInternalLength() const + { + return internalLength; + } + void iSetInternalLength(const long l) + { + internalLength = l; + } + bool GetPassedByValue() const + { + return passedByValue; + } + void iSetPassedByValue(const bool b) + { + passedByValue = b; + } + int GetTypeClass() const + { + return typeClass; + } + void iSetTypeClass(const int c) + { + typeClass = c; + } + bool GetIsRecordType() const + { + return isRecordType; + } + void iSetIsRecordType(const bool b) + { + isRecordType = b; + } + bool GetCollatable() const + { + return collatable; + } + void iSetCollatable(const bool b) + { + collatable = b; + } + void iSetRelOid(const OID d) + { + relOid = d; + } + const wxArrayString &GetTypesArray() + { + return typesArray; + } + const wxArrayString &GetCollationsArray() + { + return collationsArray; + } + const wxArrayString &GetLabelArray() + { + return labelArray; + } + wxString GetTypesList() const + { + return typesList; + } + wxString GetQuotedTypesList() const + { + return quotedTypesList; + } + wxString GetLabelList() const + { + return labelList; + } + wxString GetQuotedLabelList() const + { + return quotedLabelList; + } + bool GetSystemObject() const + { + return pgSchemaObject::GetSystemObject() || isRecordType; + } + OID GetSubtypeFunction() const + { + return rngsubtype; + } + void iSetSubtypeFunction(const OID d) + { + rngsubtype = d; + } + wxString GetSubtypeFunctionStr() const + { + return rngsubtypestr; + } + void iSetSubtypeFunctionStr(const wxString s) + { + rngsubtypestr = s; + } + OID GetCollationFunction() const + { + return rngcollation; + } + void iSetCollationFunction(const OID d) + { + rngcollation = d; + } + wxString GetCollationFunctionStr() const + { + return rngcollationstr; + } + void iSetCollationFunctionStr(const wxString s) + { + rngcollationstr = s; + } + OID GetSubtypeOpClassFunction() const + { + return rngsubopc; + } + void iSetSubtypeOpClassFunction(const OID d) + { + rngsubopc = d; + } + wxString GetSubtypeOpClassFunctionStr() const + { + return rngsubopcstr; + } + void iSetSubtypeOpClassFunctionStr(const wxString s) + { + rngsubopcstr = s; + } + wxString GetCanonical() const + { + return rngcanonical; + } + void iSetCanonical(const wxString s) + { + rngcanonical = s; + } + wxString GetSubtypeDiff() const + { + return rngsubdiff; + } + void iSetSubtypeDiff(const wxString s) + { + rngsubdiff = s; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString alias, inputFunction, outputFunction, defaultVal, element, delimiter, alignment, storage, + typesList, quotedTypesList, labelList, quotedLabelList, sendFunction, receiveFunction, + typmodinFunction, typmodoutFunction, analyzeFunction, category; + wxArrayString typesArray, labelArray, collationsArray; + long internalLength; + int typeClass; + bool passedByValue, isRecordType, collatable, prefered; + int rngsubtype, rngcollation, rngsubopc; + wxString rngsubtypestr, rngcollationstr, rngsubopcstr, rngcanonical, rngsubdiff; + OID relOid; +}; + +class pgTypeCollection : public pgSchemaObjCollection +{ +public: + pgTypeCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgUser.h b/include/schema/pgUser.h new file mode 100644 index 0000000..69b22ff --- /dev/null +++ b/include/schema/pgUser.h @@ -0,0 +1,135 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgUser.h - PostgreSQL User +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGUSER_H +#define PGUSER_H + +#include "pgServer.h" + +class pgUserFactory : public pgServerObjFactory +{ +public: + pgUserFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); +}; +extern pgUserFactory userFactory; + + +// Class declarations +class pgUser : public pgServerObject +{ +public: + pgUser(const wxString &newName = wxT("")); + wxString GetTranslatedMessage(int kindOfMessage) const; + + // User Specific + bool GetSystemObject() const + { + return userId < 100; + } + long GetUserId() const + { + return userId; + } + void iSetUserId(const long l) + { + userId = l; + } + wxDateTime GetAccountExpires() const + { + return accountExpires; + } + void iSetAccountExpires(const wxDateTime &dt) + { + accountExpires = dt; + } + wxString GetPassword() const + { + return password; + } + void iSetPassword(const wxString &s) + { + password = s; + } + bool GetCreateDatabase() const + { + return createDatabase; + } + void iSetCreateDatabase(const bool b) + { + createDatabase = b; + } + bool GetSuperuser() const + { + return superuser; + } + void iSetSuperuser(const bool b) + { + superuser = b; + } + bool GetUpdateCatalog() const + { + return updateCatalog; + } + void iSetUpdateCatalog(const bool b) + { + updateCatalog = b; + } + wxArrayString &GetGroupsIn() + { + return groupsIn; + } + wxArrayString &GetConfigList() + { + return configList; + } + + + // Tree object creation + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + void ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &where); + + // virtual methods + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString password; + wxDateTime accountExpires; + bool createDatabase, superuser, updateCatalog; + wxArrayString groupsIn; + wxArrayString configList; + long userId; +}; + +class pgUserCollection : public pgServerObjCollection +{ +public: + pgUserCollection(pgaFactory *factory, pgServer *sv); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgUserMapping.h b/include/schema/pgUserMapping.h new file mode 100644 index 0000000..1ec508e --- /dev/null +++ b/include/schema/pgUserMapping.h @@ -0,0 +1,99 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgUserMapping.h PostgreSQL User Mapping +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGUSERMAPPING_H +#define PGUSERMAPPING_H + +#include "pgForeignServer.h" + +class pgCollection; +class pgUserMappingFactory : public pgForeignServerObjFactory +{ +public: + pgUserMappingFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); +}; +extern pgUserMappingFactory userMappingFactory; + + +class pgUserMapping : public pgForeignServerObject +{ +public: + pgUserMapping(pgForeignServer *newForeignServer, const wxString &newName = wxT("")); + wxString GetTranslatedMessage(int kindOfMessage) const; + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return true; + } + bool CanCreate() + { + return true; + } + + wxString GetUsr() const + { + return user; + } + void iSetUsr(const wxString &s) + { + user = s; + } + wxString GetOptions() const + { + return options; + } + wxString GetCreateOptions(); + void iSetOptions(const wxString &s) + { + options = s; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString user, options; +}; + +class pgUserMappingObjFactory : public pgForeignServerObjFactory +{ +public: + pgUserMappingObjFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm = 0) + : pgForeignServerObjFactory(tn, ns, nls, img, imgSm) {} + virtual pgCollection *CreateCollection(pgObject *obj); +}; + + +class pgUserMappingCollection : public pgCollection +{ +public: + pgUserMappingCollection(pgaFactory *factory, pgUserMapping *um); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgView.h b/include/schema/pgView.h new file mode 100644 index 0000000..0dd14b7 --- /dev/null +++ b/include/schema/pgView.h @@ -0,0 +1,401 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgView.h PostgreSQL View +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGVIEW_H +#define PGVIEW_H + +#include "pgRule.h" + +class pgCollection; + +class pgViewFactory : public pgSchemaObjFactory +{ +public: + pgViewFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + int GetMaterializedIconId() + { + return WantSmallIcon() ? smallMaterializedId : materializedId; + } + +protected: + int materializedId, smallMaterializedId; + +}; +extern pgViewFactory viewFactory; + + +class pgView : public pgRuleObject +{ +public: + pgView(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgView(); + + int GetIconId(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return !GetSystemObject() && pgSchemaObject::CanDrop(); + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + bool CanCreate() + { + return GetSchema()->CanCreate(); + } + bool CanView() + { + return true; + } + bool WantDummyChild() + { + return true; + } + + bool HasInsertRule() + { + return hasInsertRule; + } + bool HasUpdateRule() + { + return hasUpdateRule; + } + bool HasDeleteRule() + { + return hasDeleteRule; + } + wxString GetSecurityBarrier() + { + return security_barrier; + } + void iSetSecurityBarrier(const wxString &s) + { + security_barrier = s; + } + + wxString GetTablespace() const + { + return tablespace; + } + void iSetTablespace(const wxString &newVal) + { + tablespace = newVal; + } + OID GetTablespaceOid() const + { + return tablespaceOid; + } + void iSetTablespaceOid(const OID newVal) + { + tablespaceOid = newVal; + } + + wxMenu *GetNewMenu(); + wxString GetSql(ctlTree *browser); + wxString GetSelectSql(ctlTree *browser); + wxString GetInsertSql(ctlTree *browser); + wxString GetUpdateSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + void RefreshMatView(bool concurrently); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + + void ShowHint(frmMain *form, bool force); + bool GetCanHint() + { + return true; + }; + + bool IsUpToDate(); + + wxString GetFillFactor() + { + return fillFactor; + } + void iSetFillFactor(const wxString &s) + { + fillFactor = s; + } + + wxString GetIsPopulated() + { + return isPopulated; + } + void iSetIsPopulated(const wxString &s) + { + isPopulated = s; + } + + wxString GetCheckOption() + { + return check_option; + } + void iSetCheckOption(const wxString &s) + { + check_option = s; + } + + bool GetCustomAutoVacuumEnabled() + { + return !reloptions.IsEmpty(); + } + wxString GetRelOptions() + { + return reloptions; + } + void iSetRelOptions(const wxString &s) + { + reloptions = s; + } + int GetAutoVacuumEnabled() + { + return autovacuum_enabled; + } + void iSetAutoVacuumEnabled(int i) + { + autovacuum_enabled = i; + } + wxString GetAutoVacuumVacuumThreshold() + { + return autovacuum_vacuum_threshold; + } + void iSetAutoVacuumVacuumThreshold(const wxString &s) + { + autovacuum_vacuum_threshold = s; + } + wxString GetAutoVacuumVacuumScaleFactor() + { + return autovacuum_vacuum_scale_factor; + } + void iSetAutoVacuumVacuumScaleFactor(const wxString &s) + { + autovacuum_vacuum_scale_factor = s; + } + wxString GetAutoVacuumAnalyzeThreshold() + { + return autovacuum_analyze_threshold; + } + void iSetAutoVacuumAnalyzeThreshold(const wxString &s) + { + autovacuum_analyze_threshold = s; + } + wxString GetAutoVacuumAnalyzeScaleFactor() + { + return autovacuum_analyze_scale_factor; + } + void iSetAutoVacuumAnalyzeScaleFactor(const wxString &s) + { + autovacuum_analyze_scale_factor = s; + } + wxString GetAutoVacuumVacuumCostDelay() + { + return autovacuum_vacuum_cost_delay; + } + void iSetAutoVacuumVacuumCostDelay(const wxString &s) + { + autovacuum_vacuum_cost_delay = s; + } + wxString GetAutoVacuumVacuumCostLimit() + { + return autovacuum_vacuum_cost_limit; + } + void iSetAutoVacuumVacuumCostLimit(const wxString &s) + { + autovacuum_vacuum_cost_limit = s; + } + wxString GetAutoVacuumFreezeMinAge() + { + return autovacuum_freeze_min_age; + } + void iSetAutoVacuumFreezeMinAge(const wxString &s) + { + autovacuum_freeze_min_age = s; + } + wxString GetAutoVacuumFreezeMaxAge() + { + return autovacuum_freeze_max_age; + } + void iSetAutoVacuumFreezeMaxAge(const wxString &s) + { + autovacuum_freeze_max_age = s; + } + wxString GetAutoVacuumFreezeTableAge() + { + return autovacuum_freeze_table_age; + } + void iSetAutoVacuumFreezeTableAge(const wxString &s) + { + autovacuum_freeze_table_age = s; + } + bool GetHasToastTable() + { + return hasToastTable; + } + void iSetHasToastTable(bool b) + { + hasToastTable = b; + } + + /* TOAST TABLE autovacuum settings */ + bool GetToastCustomAutoVacuumEnabled() + { + return !toast_reloptions.IsEmpty(); + } + wxString GetToastRelOptions() + { + return toast_reloptions; + } + void iSetToastRelOptions(const wxString &s) + { + toast_reloptions = s; + } + int GetToastAutoVacuumEnabled() + { + return toast_autovacuum_enabled; + } + void iSetToastAutoVacuumEnabled(int i) + { + toast_autovacuum_enabled = i; + } + wxString GetToastAutoVacuumVacuumThreshold() + { + return toast_autovacuum_vacuum_threshold; + } + void iSetToastAutoVacuumVacuumThreshold(const wxString &s) + { + toast_autovacuum_vacuum_threshold = s; + } + wxString GetToastAutoVacuumVacuumScaleFactor() + { + return toast_autovacuum_vacuum_scale_factor; + } + void iSetToastAutoVacuumVacuumScaleFactor(const wxString &s) + { + toast_autovacuum_vacuum_scale_factor = s; + } + wxString GetToastAutoVacuumVacuumCostDelay() + { + return toast_autovacuum_vacuum_cost_delay; + } + void iSetToastAutoVacuumVacuumCostDelay(const wxString &s) + { + toast_autovacuum_vacuum_cost_delay = s; + } + wxString GetToastAutoVacuumVacuumCostLimit() + { + return toast_autovacuum_vacuum_cost_limit; + } + void iSetToastAutoVacuumVacuumCostLimit(const wxString &s) + { + toast_autovacuum_vacuum_cost_limit = s; + } + wxString GetToastAutoVacuumFreezeMinAge() + { + return toast_autovacuum_freeze_min_age; + } + void iSetToastAutoVacuumFreezeMinAge(const wxString &s) + { + toast_autovacuum_freeze_min_age = s; + } + wxString GetToastAutoVacuumFreezeMaxAge() + { + return toast_autovacuum_freeze_max_age; + } + void iSetToastAutoVacuumFreezeMaxAge(const wxString &s) + { + toast_autovacuum_freeze_max_age = s; + } + wxString GetToastAutoVacuumFreezeTableAge() + { + return toast_autovacuum_freeze_table_age; + } + void iSetToastAutoVacuumFreezeTableAge(const wxString &s) + { + toast_autovacuum_freeze_table_age = s; + } + + void iSetMaterializedView(const bool matView) + { + materializedView = matView; + } + + bool GetMaterializedView() const + { + return materializedView; + } + +private: + wxString GetCols(ctlTree *browser, size_t indent, wxString &QMs, bool withQM); + void AppendStuff(wxString &sql, ctlTree *browser, pgaFactory &factory); + bool IsMaterializedView(ctlTree *browser); + bool hasInsertRule, hasUpdateRule, hasDeleteRule, materializedView; + wxString security_barrier; + + int autovacuum_enabled, toast_autovacuum_enabled; + wxString reloptions, toast_reloptions; + + wxString fillFactor, autovacuum_vacuum_threshold, + autovacuum_vacuum_scale_factor, autovacuum_analyze_threshold, + autovacuum_analyze_scale_factor, autovacuum_vacuum_cost_delay, + autovacuum_vacuum_cost_limit, autovacuum_freeze_min_age, + autovacuum_freeze_max_age, autovacuum_freeze_table_age; + + wxString toast_fillFactor, toast_autovacuum_vacuum_threshold, + toast_autovacuum_vacuum_scale_factor, toast_autovacuum_vacuum_cost_delay, + toast_autovacuum_vacuum_cost_limit, toast_autovacuum_freeze_min_age, + toast_autovacuum_freeze_max_age, toast_autovacuum_freeze_table_age; + + wxString tablespace, isPopulated, check_option; + bool hasToastTable; + OID tablespaceOid; + +}; + +class pgViewCollection : public pgSchemaObjCollection +{ +public: + pgViewCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +class refreshMatViewFactory : public contextActionFactory +{ +public: + refreshMatViewFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class refreshConcurrentlyMatViewFactory : public contextActionFactory +{ +public: + refreshConcurrentlyMatViewFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +#endif diff --git a/include/slony/dlgRepCluster.h b/include/slony/dlgRepCluster.h new file mode 100644 index 0000000..e0c6d65 --- /dev/null +++ b/include/slony/dlgRepCluster.h @@ -0,0 +1,105 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepCluster.h - Slony-I cluster property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_REPCLUSTERPROP +#define __DLG_REPCLUSTERPROP + +#include "dlg/dlgProperty.h" + + +class slCluster; +class sysProcess; +class wxProcessEvent; + +class dlgRepClusterBase : public dlgProperty +{ +public: + dlgRepClusterBase(pgaFactory *factory, frmMain *frame, const wxString &dlgName, slCluster *cl, pgDatabase *obj); + ~dlgRepClusterBase(); + pgObject *GetObject(); + int Go(bool modal); + +private: + virtual void OnChangeCluster(wxCommandEvent &ev) = 0; + +protected: + void OnChangeServer(wxCommandEvent &ev); + void OnChangeDatabase(wxCommandEvent &ev); + + bool AddScript(wxString &sql, const wxString &filename); + slCluster *cluster; + wxTreeItemId servers; + pgServer *remoteServer; + pgConn *remoteConn; + wxString remoteVersion; + wxString createScript; + + DECLARE_EVENT_TABLE() +}; + + +class dlgRepCluster : public dlgRepClusterBase +{ +public: + dlgRepCluster(pgaFactory *factory, frmMain *frame, slCluster *cl, pgDatabase *obj); + int Go(bool modal); + wxString GetHelpPage() const; + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + +private: + void OnOK(wxCommandEvent &ev); + void OnChangeJoin(wxCommandEvent &ev); + void OnChangeCluster(wxCommandEvent &ev); + void OnEndProcess(wxProcessEvent &event); + + bool CopyTable(pgConn *from, pgConn *to, const wxString &table); + sysProcess *process; + + bool SlonyMaximumVersion(const wxString &series, long minor); + + wxArrayLong usedNodes; + wxString clusterBackup; + wxString slonyVersion; + + + DECLARE_EVENT_TABLE() +}; + + + +class dlgRepClusterUpgrade : public dlgRepClusterBase +{ +public: + dlgRepClusterUpgrade(pgaFactory *factory, frmMain *frame, slCluster *cl); + int Go(bool modal); + wxString GetHelpPage() const + { + return wxT("slony-install#upgrade"); + } + + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + +private: + void OnChangeCluster(wxCommandEvent &ev); + + wxString version; + wxString sql; + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/slony/dlgRepListen.h b/include/slony/dlgRepListen.h new file mode 100644 index 0000000..d1395f9 --- /dev/null +++ b/include/slony/dlgRepListen.h @@ -0,0 +1,45 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepListen.h - Slony-I listen property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_REPLISTENPROP +#define __DLG_REPLISTENPROP + +#include "slony/dlgRepProperty.h" + +class slNode; +class slListen; + +class dlgRepListen : public dlgRepProperty +{ +public: + dlgRepListen(pgaFactory *factory, frmMain *frame, slListen *l, slNode *n); + int Go(bool modal); + wxString GetHelpPage() const + { + return wxT("slony-path#listen"); + } + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + + slListen *listen; + slNode *node; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/slony/dlgRepNode.h b/include/slony/dlgRepNode.h new file mode 100644 index 0000000..67f6d45 --- /dev/null +++ b/include/slony/dlgRepNode.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepNode.h - Slony-I Node property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_REPNODEPROP +#define __DLG_REPNODEPROP + +#include "slony/dlgRepProperty.h" + + +class slCluster; +class slNode; + +class dlgRepNode : public dlgRepProperty +{ +public: + dlgRepNode(pgaFactory *factory, frmMain *frame, slNode *node, slCluster *c); + int Go(bool modal); + wxString GetHelpPage() const + { + return wxT("slony-install#node"); + } + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + slNode *node; + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/slony/dlgRepPath.h b/include/slony/dlgRepPath.h new file mode 100644 index 0000000..5aceed8 --- /dev/null +++ b/include/slony/dlgRepPath.h @@ -0,0 +1,45 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepPath.h - Slony-I path property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_REPPATHPROP +#define __DLG_REPPATHPROP + +#include "slony/dlgRepProperty.h" + +class slNode; +class slPath; + +class dlgRepPath : public dlgRepProperty +{ +public: + dlgRepPath(pgaFactory *factory, frmMain *frame, slPath *p, slNode *n); + int Go(bool modal); + wxString GetHelpPage() const + { + return wxT("slony-path"); + } + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + + slPath *path; + slNode *node; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/slony/dlgRepProperty.h b/include/slony/dlgRepProperty.h new file mode 100644 index 0000000..bd3ab23 --- /dev/null +++ b/include/slony/dlgRepProperty.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepSet.h - Slony-I property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_REPPROP +#define __DLG_REPPROP + +#include "dlg/dlgProperty.h" + +class slCluster; + +class dlgRepProperty : public dlgProperty +{ +public: + dlgRepProperty(pgaFactory *f, frmMain *frame, slCluster *c, const wxString &resName); + +protected: + slCluster *cluster; +}; + + +#endif diff --git a/include/slony/dlgRepSequence.h b/include/slony/dlgRepSequence.h new file mode 100644 index 0000000..9bbe14c --- /dev/null +++ b/include/slony/dlgRepSequence.h @@ -0,0 +1,47 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepSequence.h - Slony-I sequence property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_REPSEQUENCEPROP +#define __DLG_REPSEQUENCEPROP + +#include "slony/dlgRepProperty.h" + +class slSet; +class slSequence; + +class dlgRepSequence : public dlgRepProperty +{ +public: + dlgRepSequence(pgaFactory *factory, frmMain *frame, slSequence *tab, slSet *s); + int Go(bool modal); + wxString GetHelpPage() const + { + return wxT("slony-set#sequence"); + } + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + + void OnChangeSel(wxCommandEvent &ev); + + slSequence *sequence; + slSet *set; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/slony/dlgRepSet.h b/include/slony/dlgRepSet.h new file mode 100644 index 0000000..302fd12 --- /dev/null +++ b/include/slony/dlgRepSet.h @@ -0,0 +1,100 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepSet.h - Slony-I Set property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_REPSETPROP +#define __DLG_REPSETPROP + +#include "slony/dlgRepProperty.h" + +class slCluster; +class slSet; + +class dlgRepSet : public dlgRepProperty +{ +public: + dlgRepSet(pgaFactory *factory, frmMain *frame, slSet *set, slCluster *c); + int Go(bool modal); + wxString GetHelpPage() const + { + return wxT("slony-set"); + } + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject() + { + return (pgObject *)set; + } + +private: + slSet *set; + + DECLARE_EVENT_TABLE() +}; + + +class dlgRepSetMerge : public dlgRepProperty +{ +public: + dlgRepSetMerge(pgaFactory *factory, frmMain *frame, slSet *set); + int Go(bool modal); + wxString GetHelpPage() const + { + return wxT("slony-functions"); + } + + void CheckChange(); + wxString GetSql(); + pgObject *GetObject() + { + return (pgObject *)set; + } + pgObject *CreateObject(pgCollection *collection) + { + return 0; + } + +private: + slSet *set; + + DECLARE_EVENT_TABLE() +}; + +class dlgRepSetMove : public dlgRepProperty +{ +public: + dlgRepSetMove(pgaFactory *f, frmMain *frame, slSet *set); + int Go(bool modal); + wxString GetHelpPage() const + { + return wxT("slony-functions"); + } + + void CheckChange(); + wxString GetSql(); + pgObject *GetObject() + { + return (pgObject *)set; + } + pgObject *CreateObject(pgCollection *collection) + { + return 0; + } + +private: + slSet *set; + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/slony/dlgRepSubscription.h b/include/slony/dlgRepSubscription.h new file mode 100644 index 0000000..c734f6c --- /dev/null +++ b/include/slony/dlgRepSubscription.h @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepSubscription.h - Slony-I Subscription property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_REPSUBSCPROP +#define __DLG_REPSUBSCPROP + +#include "slony/dlgRepProperty.h" + +class slSubscription; +class slSet; + +class dlgRepSubscription : public dlgRepProperty +{ +public: + dlgRepSubscription(pgaFactory *factory, frmMain *frame, slSubscription *sub, slSet *s); + int Go(bool modal); + wxString GetHelpPage() const + { + return wxT("slony-set#subscription"); + } + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + slSubscription *subscription; + slSet *set; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/slony/dlgRepTable.h b/include/slony/dlgRepTable.h new file mode 100644 index 0000000..65b3c67 --- /dev/null +++ b/include/slony/dlgRepTable.h @@ -0,0 +1,51 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepTable.h - Slony-I table property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_REPTABLEPROP +#define __DLG_REPTABLEPROP + +#include "slony/dlgRepProperty.h" + +class slSet; +class slTable; + +class dlgRepTable : public dlgRepProperty +{ +public: + dlgRepTable(pgaFactory *factory, frmMain *frame, slTable *tab, slSet *s); + int Go(bool modal); + wxString GetHelpPage() const + { + return wxT("slony-set#table"); + } + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + + slTable *table; + slSet *set; + long lastTableSelection; + + void LoadTrigger(OID relid); + + void OnChangeTable(wxCommandEvent &ev); + void OnChangeTableSel(wxCommandEvent &ev); + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/slony/module.mk b/include/slony/module.mk new file mode 100644 index 0000000..b1fff4c --- /dev/null +++ b/include/slony/module.mk @@ -0,0 +1,33 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/slony/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/slony/dlgRepCluster.h \ + include/slony/dlgRepListen.h \ + include/slony/dlgRepNode.h \ + include/slony/dlgRepPath.h \ + include/slony/dlgRepProperty.h \ + include/slony/dlgRepSequence.h \ + include/slony/dlgRepSet.h \ + include/slony/dlgRepSubscription.h \ + include/slony/dlgRepTable.h \ + include/slony/slCluster.h \ + include/slony/slListen.h \ + include/slony/slNode.h \ + include/slony/slPath.h \ + include/slony/slSequence.h \ + include/slony/slSet.h \ + include/slony/slSubscription.h \ + include/slony/slTable.h + +EXTRA_DIST += \ + include/slony/module.mk + diff --git a/include/slony/slCluster.h b/include/slony/slCluster.h new file mode 100644 index 0000000..d15407f --- /dev/null +++ b/include/slony/slCluster.h @@ -0,0 +1,226 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slCluster.h PostgreSQL Slony-I Cluster +// +////////////////////////////////////////////////////////////////////////// + +#ifndef SLCLUSTER_H +#define SLCLUSTER_H + +#include "schema/pgDatabase.h" + +class frmMain; +class RemoteConn; +class slNode; + + +WX_DECLARE_OBJARRAY(RemoteConn, RemoteConnArray); + + +class pgaSlClusterFactory : public pgDatabaseObjFactory +{ +public: + pgaSlClusterFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgaSlClusterFactory slClusterFactory; + + +class slCluster : public pgDatabaseObject +{ +public: + slCluster(const wxString &newName = wxT("")); + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + static pgObject *ReadObjects(pgCollection *coll, ctlTree *browser); + + wxString GetTranslatedMessage(int kindOfMessage) const; + + bool ClusterMinimumVersion(int major, int minor); + + void iSetSchemaPrefix(const wxString &s) + { + schemaPrefix = s; + } + wxString GetSchemaPrefix() const + { + return schemaPrefix; + } + void iSetLocalNodeID(long l) + { + localNodeID = l; + } + long GetLocalNodeID() + { + return localNodeID; + } + void iSetLocalNodeName(const wxString &s) + { + localNodeName = s; + } + wxString GetLocalNodeName() const + { + return localNodeName; + } + void iSetAdminNodeID(long l) + { + adminNodeID = l; + } + long GetAdminNodeID() + { + return adminNodeID; + } + void iSetAdminNodeName(const wxString &s) + { + adminNodeName = s; + } + wxString GetAdminNodeName() const + { + return adminNodeName; + } + void iSetClusterVersion(const wxString &s) + { + clusterVersion = s; + } + wxString GetClusterVersion() const + { + return clusterVersion; + } + long GetSlonPid(); + + slNode *GetLocalNode(ctlTree *browser); + + bool RequireDropConfirm() + { + return true; + } + bool WantDummyChild() + { + return true; + } + + pgConn *GetNodeConn(frmMain *form, long nodeId, bool create = true); + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxMenu *GetNewMenu(); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + +private: + wxString schemaPrefix; + wxString localNodeName, adminNodeName; + wxString clusterVersion; + long localNodeID, adminNodeID; + slNode *localNode; + + RemoteConnArray remoteConns; +}; + + +class slClusterCollection : public pgDatabaseObjCollection +{ +public: + slClusterCollection(pgaFactory *factory, pgDatabase *db); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + + +// Slony-I object +class slObject : public pgDatabaseObject +{ +public: + slObject(slCluster *_slCluster, pgaFactory &factory, const wxString &newName = wxT("")); + slCluster *GetCluster() + { + return cluster; + } + + void iSetSlId(long i) + { + slId = i; + } + long GetSlId() const + { + return slId; + } + +private: + slCluster *cluster; + long slId; +}; + + +// Collection of Slony-I objects +class slObjCollection : public pgDatabaseObjCollection +{ +public: + slObjCollection(pgaFactory *factory, slCluster *_cluster); + + slCluster *GetCluster() + { + return cluster; + } + long GetSlId() const + { + return slId; + } + void iSetSlId(long l) + { + slId = l; + } + +private: + slCluster *cluster; + long slId; +}; + +class slObjFactory : public pgDatabaseObjFactory +{ +public: + slObjFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm = 0) : pgDatabaseObjFactory(tn, ns, nls, img, imgSm) {} + virtual pgCollection *CreateCollection(pgObject *obj); +}; + +class clusterActionFactory : public contextActionFactory +{ +public: + clusterActionFactory(menuFactoryList *list) : contextActionFactory(list) {} + bool CheckEnable(pgObject *obj); +}; + + +class slonyRestartFactory : public clusterActionFactory +{ +public: + slonyRestartFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + + +class slonyUpgradeFactory : public clusterActionFactory +{ +public: + slonyUpgradeFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + + +class slonyFailoverFactory : public clusterActionFactory +{ +public: + slonyFailoverFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +#endif + + diff --git a/include/slony/slListen.h b/include/slony/slListen.h new file mode 100644 index 0000000..ad729a7 --- /dev/null +++ b/include/slony/slListen.h @@ -0,0 +1,80 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slListen.h PostgreSQL Slony-I Node +// +////////////////////////////////////////////////////////////////////////// + +#ifndef SLLISTEN_H +#define SLLISTEN_H + +#include "slony/slNode.h" + + +class slListenFactory : public slNodeObjFactory +{ +public: + slListenFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern slListenFactory listenFactory; + + +class slListen : public slNodeObject +{ +public: + slListen(slNode *n, const wxString &newName = wxT("")); + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + wxString GetTranslatedMessage(int kindOfMessage) const; + + long GetProviderId() const + { + return providerId; + } + void iSetProviderId(long l) + { + providerId = l; + } + wxString GetProviderName() const + { + return providerName; + } + void iSetProviderName(const wxString &s) + { + providerName = s; + } + wxString GetOriginName() const + { + return originName; + } + void iSetOriginName(const wxString &s) + { + originName = s; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + +private: + long providerId; + wxString providerName, originName; +}; + +class slListenCollection : public slNodeObjCollection +{ +public: + slListenCollection(pgaFactory *factory, slNode *nd) : slNodeObjCollection(factory, nd) {} + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif + diff --git a/include/slony/slNode.h b/include/slony/slNode.h new file mode 100644 index 0000000..bef1d3c --- /dev/null +++ b/include/slony/slNode.h @@ -0,0 +1,155 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slNode.h PostgreSQL Slony-I Node +// +////////////////////////////////////////////////////////////////////////// + +#ifndef SLNODE_H +#define SLNODE_H + +#include "slony/slCluster.h" + + +class slNodeFactory : public slObjFactory +{ +public: + slNodeFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + int GetLocalIconId() + { + return localIconId; + } + int GetDisabledIconId() + { + return disabledIconId; + } + +private: + int localIconId, disabledIconId; +}; +extern slNodeFactory nodeFactory; + + +class slNode : public slObject +{ +public: + slNode(slCluster *_cluster, const wxString &newName = wxT("")); + + int GetIconId(); + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + void ShowStatistics(frmMain *form, ctlListView *statistics); + + wxString GetTranslatedMessage(int kindOfMessage) const; + + bool CanDrop(); + bool RequireDropConfirm() + { + return true; + } + bool WantDummyChild() + { + return true; + } + + long GetOutstandingAcks(); + bool CheckAcksAndContinue(wxFrame *frame); + + bool GetActive() const + { + return active; + } + void iSetActive(bool b) + { + active = b; + } + bool GetSpool() const + { + return spool; + } + void iSetSpool(bool b) + { + spool = b; + } + wxString GetConnInfo() const + { + return connInfo; + } + void iSetConnInfo(const wxString s) + { + connInfo = s; + } + long GetPid() + { + return pid; + } + bool WaitForEvent(long evNode); + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxMenu *GetNewMenu(); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + +private: + bool active, spool; + long pid; + wxString connInfo; +}; + + +class slNodeCollection : public slObjCollection +{ +public: + slNodeCollection(pgaFactory *factory, slCluster *cl) : slObjCollection(factory, cl) {} + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowStatistics(frmMain *form, ctlListView *statistics); +}; + +////////////////////////////////////////// + +// Object under a Slony-I node +class slNodeObject : public slObject +{ +public: + slNodeObject(slNode *n, pgaFactory &factory, const wxString &newName = wxT("")); + slNode *GetNode() const + { + return node; + } + +private: + slNode *node; +}; + +// Collection of node objects +class slNodeObjCollection : public slObjCollection +{ +public: + slNodeObjCollection(pgaFactory *factory, slNode *n); + slNode *GetNode() + { + return node; + } + +private: + slNode *node; +}; + + +class slNodeObjFactory : public slObjFactory +{ +public: + slNodeObjFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img = 0) : slObjFactory(tn, ns, nls, img) {} + virtual pgCollection *CreateCollection(pgObject *obj); +}; + + +#endif + diff --git a/include/slony/slPath.h b/include/slony/slPath.h new file mode 100644 index 0000000..ea5713a --- /dev/null +++ b/include/slony/slPath.h @@ -0,0 +1,75 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slPath.h PostgreSQL Slony-I Node +// +////////////////////////////////////////////////////////////////////////// + +#ifndef SLPATH_H +#define SLPATH_H + + +#include "slony/slNode.h" + + +class slPathFactory : public slNodeObjFactory +{ +public: + slPathFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern slPathFactory pathFactory; + + +class slPath : public slNodeObject +{ +public: + slPath(slNode *n, const wxString &newName = wxT("")); + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + static pgObject *ReadObjects(slNodeCollection *coll, ctlTree *browser); + + wxString GetTranslatedMessage(int kindOfMessage) const; + + void iSetConnInfo(const wxString &s) + { + connInfo = s; + } + wxString GetConnInfo() const + { + return connInfo; + } + void iSetConnRetry(long l) + { + connRetry = l; + } + long GetConnRetry() + { + return connRetry; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + +private: + long connRetry; + wxString connInfo; +}; + +class slPathCollection : public slNodeObjCollection +{ +public: + slPathCollection(pgaFactory *factory, slNode *nd) : slNodeObjCollection(factory, nd) {} + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + + +#endif + diff --git a/include/slony/slSequence.h b/include/slony/slSequence.h new file mode 100644 index 0000000..6cff281 --- /dev/null +++ b/include/slony/slSequence.h @@ -0,0 +1,63 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slSequence.h PostgreSQL Slony-I Node +// +////////////////////////////////////////////////////////////////////////// + +#ifndef SLSEQUENCE_H +#define SLSEQUENCE_H + +#include "schema/pgDatabase.h" +#include "slony/slSet.h" + +class slSlSequenceFactory : public slSetObjFactory +{ +public: + slSlSequenceFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern slSlSequenceFactory slSequenceFactory; + + +class slSequence : public slSetObject +{ +public: + slSequence(slSet *set, const wxString &newName = wxT("")); + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + wxString GetTranslatedMessage(int kindOfMessage) const; + + bool GetActive() const + { + return active; + } + void iSetActive(bool b) + { + active = b; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + +private: + bool active; +}; + +class slSlSequenceCollection : public slSetObjCollection +{ +public: + slSlSequenceCollection(pgaFactory *factory, slSet *set) : slSetObjCollection(factory, set) {} + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif + diff --git a/include/slony/slSet.h b/include/slony/slSet.h new file mode 100644 index 0000000..c1b412f --- /dev/null +++ b/include/slony/slSet.h @@ -0,0 +1,189 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slSet.h PostgreSQL Slony-I Set +// +////////////////////////////////////////////////////////////////////////// + +#ifndef SLSET_H +#define SLSET_H + +#include "slony/slCluster.h" + + +class slSetFactory : public slObjFactory +{ +public: + slSetFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + int GetExportedIconId() + { + return exportedIconId; + } + +protected: + int exportedIconId; +}; +extern slSetFactory setFactory; + + +class slSet : public slObject +{ +public: + slSet(slCluster *_cluster, const wxString &newName = wxT("")); + + int GetIconId(); + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + wxString GetTranslatedMessage(int kindOfMessage) const; + + bool CanDrop(); + bool RequireDropConfirm() + { + return true; + } + bool WantDummyChild() + { + return true; + } + + long GetOriginId() const + { + return originId; + } + void iSetOriginId(long l) + { + originId = l; + } + wxString GetOriginNode() const + { + return originNode; + } + void iSetOriginNode(const wxString s) + { + originNode = s; + } + long GetSubscriptionCount() + { + return subscriptionCount; + } + void iSetSubscriptionCount(long l) + { + subscriptionCount = l; + } + + wxString GetLockXXID(); + bool Lock(); + bool Unlock(); + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxMenu *GetNewMenu(); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + void ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &wh); + void ShowDependencies(frmMain *form, ctlListView *Dependencies, const wxString &wh); + void ShowStatistics(pgCollection *collection, ctlListView *statistics); + +private: + long subscriptionCount; + long originId; + wxString originNode; +}; + + +class slSetCollection : public slObjCollection +{ +public: + slSetCollection(pgaFactory *factory, slCluster *cl) : slObjCollection(factory, cl) {} + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +// Object in a Slony-I set +class slSetObject : public slObject +{ +public: + slSetObject(slSet *s, pgaFactory &factory, const wxString &newName = wxT("")); + slSet *GetSet() + { + return set; + } + + bool CanDrop(); + bool CanCreate(); + +private: + slSet *set; +}; + + +// Collection of set objects +class slSubscription; +class slSetObjCollection : public slObjCollection +{ +public: + slSetObjCollection(pgaFactory *factory, slSet *_set); + bool CanCreate(); + + slSet *GetSet() + { + return set; + } + +private: + slSet *set; + slSubscription *subscription; +}; + + +class slSetObjFactory : public slObjFactory +{ +public: + slSetObjFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm = 0) : slObjFactory(tn, ns, nls, img, imgSm) {} + virtual pgCollection *CreateCollection(pgObject *obj); +}; + +class slonyMoveSetFactory : public contextActionFactory +{ +public: + slonyMoveSetFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +class slonyMergeSetFactory : public contextActionFactory +{ +public: + slonyMergeSetFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +class slonyLockSetFactory : public contextActionFactory +{ +public: + slonyLockSetFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +class slonyUnlockSetFactory : public contextActionFactory +{ +public: + slonyUnlockSetFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif + + diff --git a/include/slony/slSubscription.h b/include/slony/slSubscription.h new file mode 100644 index 0000000..ca1cfa9 --- /dev/null +++ b/include/slony/slSubscription.h @@ -0,0 +1,132 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slSubscription.h PostgreSQL Slony-I Node +// +////////////////////////////////////////////////////////////////////////// + +#ifndef SLSUBSCRIPTION_H +#define SLSUBSCRIPTION_H + +#include "slony/slSet.h" + + +class slSubscriptionFactory : public slSetObjFactory +{ +public: + slSubscriptionFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + int GetExportedIconId() + { + return exportedIconId; + } + +protected: + int exportedIconId; +}; +extern slSubscriptionFactory subscriptionFactory; + + +class slSubscription : public slSetObject +{ +public: + slSubscription(slSet *set, const wxString &newName = wxT("")); + + int GetIconId(); + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + wxString GetTranslatedMessage(int kindOfMessage) const; + + bool WantDummyChild(); + bool RequireDropConfirm() + { + return true; + } + + bool GetActive() const + { + return active; + } + void iSetActive(bool b) + { + active = b; + } + bool GetForward() const + { + return forward; + } + void iSetForward(bool b) + { + forward = b; + } + wxString GetProviderNode() const + { + return providerNode; + } + void iSetProviderNode(const wxString &s) + { + providerNode = s; + } + wxString GetReceiverNode() const + { + return receiverNode; + } + void iSetReceiverNode(const wxString &s) + { + receiverNode = s; + } + long GetProviderId() const + { + return providerId; + } + void iSetProviderId(long l) + { + providerId = l; + } + long GetReceiverId() const + { + return receiverId; + } + void iSetReceiverId(long l) + { + receiverId = l; + } + bool GetIsSubscribed() + { + return isSubscribed; + } + void iSetIsSubscribed(bool b) + { + isSubscribed = b; + } + + + + bool CanCreate(); + bool CanDrop(); + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + +private: + bool active, forward, isSubscribed; + long providerId, receiverId; + wxString providerNode, receiverNode; +}; + +class slSubscriptionCollection : public slSetObjCollection +{ +public: + slSubscriptionCollection(pgaFactory *factory, slSet *set) : slSetObjCollection(factory, set) {} + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif + diff --git a/include/slony/slTable.h b/include/slony/slTable.h new file mode 100644 index 0000000..a6298f3 --- /dev/null +++ b/include/slony/slTable.h @@ -0,0 +1,76 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slTable.h PostgreSQL Slony-I Node +// +////////////////////////////////////////////////////////////////////////// + +#ifndef SLTABLE_H +#define SLTABLE_H + +#include "slony/slSet.h" + +class slSlTableFactory : public slSetObjFactory +{ +public: + slSlTableFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern slSlTableFactory slTableFactory; + + +class slTable : public slSetObject +{ +public: + slTable(slSet *set, const wxString &newName = wxT("")); + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + wxString GetTranslatedMessage(int kindOfMessage) const; + + bool GetAltered() const + { + return altered; + } + void iSetAltered(bool b) + { + altered = b; + } + wxString GetIndexName() const + { + return indexName; + } + void iSetIndexName(const wxString s) + { + indexName = s; + } + const wxArrayString &GetTriggers() + { + return triggers; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + +private: + bool altered; + wxString indexName; + wxArrayString triggers; +}; + +class slSlTableCollection : public slSetObjCollection +{ +public: + slSlTableCollection(pgaFactory *factory, slSet *set) : slSetObjCollection(factory, set) {} + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif + diff --git a/include/utils/csvfiles.h b/include/utils/csvfiles.h new file mode 100644 index 0000000..c9c7ef6 --- /dev/null +++ b/include/utils/csvfiles.h @@ -0,0 +1,53 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// csvfiles.h - CSV file parsing +// +////////////////////////////////////////////////////////////////////////// + +#ifndef CSVFILES_H +#define CSVFILES_H + +// PostgreSQL and GPDB now support CSV format logs. +// So, we need a way to parse the CSV files into lines, and lines into tokens (fields). + +#include + +class CSVTokenizer : public wxObject +{ +public: + CSVTokenizer(const wxString &str): m_string(str), m_pos(0) { } + + bool HasMoreTokens() const; + + // Get the next token (CSV field). Will return empty string if !HasMoreTokens() + wxString GetNextToken(); + +protected: + + const wxString m_string; // the string we tokenize into fields + size_t m_pos; // the current position in m_string +}; + +class CSVLineTokenizer : public wxObject +{ +public: + CSVLineTokenizer(const wxString &str): m_string(str), m_pos(0) { } + + bool HasMoreLines() const; + + // Get the next line. Will return empty string if !HasMoreLines(). + // partial is set "true" if the last line returned was not a complete + // line (no newline char at end). + wxString GetNextLine(bool &partial); + +protected: + + const wxString m_string; // the string we tokenize into lines + size_t m_pos; // the current position in m_string +}; +#endif diff --git a/include/utils/factory.h b/include/utils/factory.h new file mode 100644 index 0000000..d5b62e5 --- /dev/null +++ b/include/utils/factory.h @@ -0,0 +1,237 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// factory.h - Object classes factory +// +////////////////////////////////////////////////////////////////////////// + +#ifndef FACTORY_H +#define FACTORY_H + +// wxWindows headers +#include + +#include "frm/menu.h" + +#ifdef WIN32 +#ifndef __GNUC__ +#pragma warning(disable:4183) +#endif +#endif + +class pgObject; +class frmMain; +class dlgProperty; +class ctlTree; +class pgCollection; +class pgSchema; +class pgaCollectionFactory; + + +class pgaFactory +{ +public: + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) = 0; + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString) + { + return 0; + } + virtual pgCollection *CreateCollection(pgObject *obj) = 0; + virtual bool IsCollection() + { + return false; + } + virtual void AppendMenu(wxMenu *menu); + bool IsCollectionFor(pgaFactory &f) + { + return f.GetCollectionFactory() == (pgaCollectionFactory *)this; + } + bool WantSmallIcon(); + + static pgaFactory *GetFactory(int id); + static pgaFactory *GetFactory(const wxString &name); + static pgaFactory *GetFactoryByMetaType(const int type); + int GetId() + { + return id; + } + int GetMetaType(); + wxChar *GetTypeName() + { + return typeName; + } + wxChar *GetNewString() + { + return newString; + } + wxChar *GetNewLongString() + { + return newLongString; + } + pgaCollectionFactory *GetCollectionFactory() + { + return collectionFactory; + } + + int GetIconId(); + static void RegisterMenu(wxWindow *w, wxObjectEventFunction func); + const wxImage &GetImage() const + { + return image; + } + + static void RealizeImages(); + +protected: + pgaFactory(const wxChar *tn = 0, const wxChar *ns = 0, const wxChar *nls = 0, wxImage *img = 0, wxImage *imgSm = 0); + + int addIcon(wxImage *img); + + int id, metaType; + wxChar *typeName; + wxChar *newString, *newLongString; + int iconId, smallIconId; + wxImage image; + + pgaCollectionFactory *collectionFactory; + friend class pgaCollectionFactory; +}; + + +class pgaCollectionFactory : public pgaFactory +{ +public: + pgaCollectionFactory(pgaFactory *f, const wxChar *tn = 0, wxImage *img = 0, wxImage *imgSm = 0); + wxChar *GetItemTypeName() + { + return itemFactory->GetTypeName(); + } + pgaFactory *GetItemFactory() + { + return itemFactory; + } + pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + +protected: + virtual bool IsCollection() + { + return true; + } + dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgCollection *CreateCollection(pgObject *obj) + { + return 0; + }; + + pgaFactory *itemFactory; +}; + + +class actionFactory; +class menuFactory; +class menuFactoryList : public wxArrayPtrVoid +{ +public: + ~menuFactoryList(); + + void CheckMenu(pgObject *obj, wxMenuBar *menubar, ctlMenuToolbar *toolbar); + void AppendEnabledMenus(wxMenuBar *menuBar, wxMenu *treeContextMenu); + actionFactory *GetFactory(int id, bool actionOnly = true); + void RegisterMenu(wxWindow *w, wxObjectEventFunction func); + void EnableSubmenu(wxMenuBar *menubar, int id); + +private: + void Add(menuFactory *f) + { + wxArrayPtrVoid::Add(f); + } + friend class menuFactory; +}; + + +class menuFactory +{ +public: + virtual ~menuFactory(); + virtual bool IsAction() + { + return false; + } + virtual bool IsSubmenu() + { + return false; + } + +protected: + menuFactory(menuFactoryList *list); +}; + + +class actionFactory : public menuFactory +{ +public: + virtual bool IsAction() + { + return true; + } + virtual wxWindow *StartDialog(frmMain *form, pgObject *obj) = 0; + virtual bool CheckEnable(pgObject *obj) + { + return true; + } + virtual bool CheckChecked(pgObject *obj) + { + return true; + } + bool GetContext() + { + return context; + } + int GetId() + { + return id; + } + +protected: + actionFactory(menuFactoryList *list); + + int id; + bool context; + + friend class menuFactoryList; +}; + + +class contextActionFactory : public actionFactory +{ +protected: + contextActionFactory(menuFactoryList *list) : actionFactory(list) + { + context = true; + } +}; + +class submenuFactory : public contextActionFactory +{ +public: + submenuFactory(menuFactoryList *list) : contextActionFactory(list) {}; + wxWindow *StartDialog(frmMain *form, pgObject *obj) + { + return 0; + }; + virtual bool IsSubmenu() + { + return true; + } +}; + +class separatorFactory : public menuFactory +{ +public: + separatorFactory(menuFactoryList *list) : menuFactory(list) {} +}; +#endif diff --git a/include/utils/favourites.h b/include/utils/favourites.h new file mode 100644 index 0000000..5fb4666 --- /dev/null +++ b/include/utils/favourites.h @@ -0,0 +1,95 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// favourites.h - Query favourites +// +////////////////////////////////////////////////////////////////////////// + +#ifndef FAVOURITES_H +#define FAVOURITES_H + +#include +#include + +#include +#include + +class queryFavouriteItem +{ +public: + queryFavouriteItem(const wxString newtitle, const wxString newcontents); + + wxString GetTitle() + { + return title; + }; + void SetTitle(const wxString &newtitle) + { + if (!newtitle.IsEmpty()) title = newtitle; + }; + + int GetId() + { + return id; + }; + wxString GetContents() + { + return contents; + }; + + wxTreeItemId &GetTreeId() + { + return treeid; + }; + void SetTreeId(const wxTreeItemId &newtreeid) + { + treeid = newtreeid; + }; + + void AppendToMenu(wxMenu *menu, int newid); +protected: + int id; + wxString title, contents; + wxTreeItemId treeid; +}; + + +WX_DEFINE_ARRAY_PTR(queryFavouriteItem *, queryFavouriteArray); +class queryFavouriteFolder : public queryFavouriteItem +{ +public: + queryFavouriteFolder(wxString title = wxT("")); + queryFavouriteFolder(xmlTextReaderPtr reader, wxString title); + + int AppendAllToMenu(wxMenu *menu, int startid); + void AppendAllToTree(wxTreeCtrl *tree, const wxTreeItemId &parent, bool onlyfolders); + bool DeleteTreeItem(const wxTreeItemId &treeitem); + + queryFavouriteItem *FindFavourite(int id); + queryFavouriteItem *FindFavourite(const wxString &title); + queryFavouriteItem *FindTreeItem(const wxTreeItemId &treeitem); + + void AddNewFavourite(const wxString &title, const wxString &contents); + queryFavouriteFolder *AddNewFolder(const wxString &title); + + bool ContainsFolder(const wxString &title); + + void saveFolder(xmlTextWriterPtr writer); + + ~queryFavouriteFolder(); +protected: + queryFavouriteArray favourites; +}; + +class queryFavouriteFileProvider +{ +public: + static queryFavouriteFolder *LoadFavourites(bool emptyonfailure = false); + static void SaveFavourites(queryFavouriteFolder *favourites); +}; + +#endif diff --git a/include/utils/macros.h b/include/utils/macros.h new file mode 100644 index 0000000..91be0ca --- /dev/null +++ b/include/utils/macros.h @@ -0,0 +1,86 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// macros.h - Query SQL macros +// +////////////////////////////////////////////////////////////////////////// + +#ifndef MACROS_H +#define MACROS_H + +#include +#include + +#include +#include + +class queryMacroItem +{ +public: + queryMacroItem(const wxString newKey, const wxString newTitle, const wxString newQuery, const int newId = -1); + + wxString GetKey() + { + return key; + }; + wxString GetName() + { + return name; + }; + wxString GetQuery() + { + return query; + }; + int GetId() + { + return id; + }; + + void AppendToMenu(wxMenu *menu, int newId); + void Update(const wxString &newName, const wxString &newQuery); + +protected: + int id; + wxString key, name, query; +}; + +WX_DEFINE_ARRAY_PTR(queryMacroItem *, queryMacroArray); +class queryMacroList +{ +public: + queryMacroList() {}; + queryMacroList(xmlTextReaderPtr reader); + + int AppendAllToMenu(wxMenu *menu, int startId); + + queryMacroItem *FindMacro(int id); + queryMacroItem *FindMacro(const wxString &key); + queryMacroItem *GetItem(int i); + void AddNewMacro(const wxString &key, const wxString &name, const wxString &query); + void AddOrUpdateMacro(const wxString &key, const wxString &name, const wxString &query); + bool DelMacro(int id); + int Count(); + bool DelMacro(const wxString &key); + + void saveList(xmlTextWriterPtr writer); + + ~queryMacroList(); +protected: + queryMacroArray macros; +}; + +class queryMacroFileProvider +{ +public: + static queryMacroList *LoadMacros(bool emptyOnFailure = false); + static void SaveMacros(queryMacroList *macros); + static queryMacroList *LoadAutoReplace(bool emptyOnFailure = false); + static void SaveAutoReplace(queryMacroList *macros); +}; + +#endif /* MACROS_H */ + diff --git a/include/utils/misc.h b/include/utils/misc.h new file mode 100644 index 0000000..4afe107 --- /dev/null +++ b/include/utils/misc.h @@ -0,0 +1,276 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// misc.h - Miscellaneous Utilties +// +////////////////////////////////////////////////////////////////////////// + +#ifndef MISC_H +#define MISC_H + +#include +#include +#include + +#include "utils/misc.h" + +class wxImageList; +extern wxImageList *imageList; + +class wxHelpControllerBase; + +#define __(str) wxT(str) + +typedef unsigned long OID; +#define SSH_MAX_PASSWORD_LEN 256 + +// we dont have an appropriate wxLongLong method +#ifdef __WIN32__ +#define atolonglong _atoi64 +#else +#ifdef __WXMAC__ +#define atolonglong(str) strtoll(str, (char **)NULL, 10) +#else +#ifdef __FreeBSD__ +#define atolonglong(str) strtoll(str, (char **)NULL, 10) +#else +#define atolonglong atoll +#endif +#endif +#endif + +#ifdef __WXMSW__ +#define END_OF_LINE wxT("\r\n") +#else +#define END_OF_LINE wxT("\n") +#endif + +#if !defined(PGSCLI) + +#define wxCookieType wxTreeItemIdValue + +class sysSettings; +extern sysSettings *settings; + +#undef wxStaticCast +#define wxStaticCast(obj, className) ((className *)(obj)) + +// making life easier +#define CTRL(id, typ) (XRCCTRL(*this, id, typ)) + +#define CTRL_STATIC(id) (XRCCTRL(*this, id, wxStaticText)) +#define CTRL_STATICBOX(id) (XRCCTRL(*this, id, wxStaticBox)) +#define CTRL_TEXT(id) (XRCCTRL(*this, id, wxTextCtrl)) +#define CTRL_TEXTNUMERIC(id) ((wxTextNumericCtrl*)(XRCCTRL(*this, id, wxTextCtrl))) +#define CTRL_LISTBOX(id) (XRCCTRL(*this, id, wxListBox)) +#define CTRL_LISTCTRL(id) (XRCCTRL(*this, id, wxListCtrl)) +#define CTRL_COMBOBOX(id) ((ctlComboBoxFix*)(XRCCTRL(*this, id, wxComboBox))) +#define CTRL_COMBOBOX1(id) (XRCCTRL(*this, id, wxComboBox)) +#define CTRL_LISTVIEW(id) ((ctlListView*)(XRCCTRL(*this, id, wxListCtrl))) +#define CTRL_COMBOBOX2(id) (XRCCTRL(*this, id, ctlComboBox)) +#define CTRL_CHOICE(id) (XRCCTRL(*this, id, wxChoice)) +#define CTRL_CHECKBOX(id) (XRCCTRL(*this, id, wxCheckBox)) +#define CTRL_RADIOBOX(id) (XRCCTRL(*this, id, wxRadioBox)) +#define CTRL_BUTTON(id) (XRCCTRL(*this, id, wxButton)) +#define CTRL_CALENDAR(id) (XRCCTRL(*this, id, wxCalendarBox)) +#define CTRL_TIME(id) (XRCCTRL(*this, id, wxTimeSpinCtrl)) +#define CTRL_FLEXGRIDSIZER(id) (XRCCTRL(*this, id, wxFlexGridSizer)) +#define CTRL_PANEL(id) (XRCCTRL(*this, id, wxPanel)) +#define CTRL_SLIDER(id) (XRCCTRL(*this, id, wxSlider)) +#define CTRL_SQLBOX(id) (XRCCTRL(*this, id, ctlSQLBox)) +#define CTRL_RADIOBUTTON(id) (XRCCTRL(*this, id, wxRadioButton)) +#define CTRL_NOTEBOOK(id) (XRCCTRL(*this, id, wxNotebook)) +#define CTRL_SPIN(id) (XRCCTRL(*this, id, wxSpinCtrl)) +#define CTRL_CHECKLISTBOX(id) (XRCCTRL(*this, id, wxCheckListBox)) +#define CTRL_DATEPICK(id) (XRCCTRL(*this, id, wxDatePickerCtrl)) +#define CTRL_TREE(id) (XRCCTRL(*this, id, ctlTree)) +#define CTRL_COLOURPICKER(id) (XRCCTRL(*this, id, ctlColourPicker)) +#define CTRL_DIRPICKER(id) (XRCCTRL(*this, id, wxDirPickerCtrl)) +#define CTRL_FILEPICKER(id) (XRCCTRL(*this, id, wxFilePickerCtrl)) +#define CTRL_FONTPICKER(id) (XRCCTRL(*this, id, wxFontPickerCtrl)) +#define CTRL_CHECKTREEVIEW(id) (XRCCTRL(*this, id, ctlCheckTreeView)) +#define CTRL_GAUGE(id) (XRCCTRL(*this, id, wxGauge)) + +#endif // PGSCLI + +// Conversions +wxString BoolToStr(bool value); // english; used for config values +wxString DateToAnsiStr(const wxDateTime &datetime); + +bool StrToBool(const wxString &value); // english +long StrToLong(const wxString &value); +double StrToDouble(const wxString &value); +wxLongLong StrToLongLong(const wxString &value); +wxDateTime StrToDateTime(const wxString &value); +OID StrToOid(const wxString &value); + +wxString generate_spaces(int length); + +// nls aware +wxString BoolToYesNo(bool value); +wxString NumToStr(long value); +wxString NumToStr(double value); +wxString NumToStr(OID value); +wxString NumToStr(wxLongLong value); +wxString DateToStr(const wxDateTime &datetime); +wxString ElapsedTimeToStr(wxLongLong msec); + + +// Quoting +wxString qtConnString(const wxString &value); // connection strings always have single quotes escaped with backslash + +#if !defined(PGSCLI) + +// check if size/pos have reasonable values +void CheckOnScreen(wxWindow *win, wxPoint &pos, wxSize &size, const int w0 = 100, const int h0 = 70); + +// compile ID and Name into one string +wxString IdAndName(long id, const wxString &name); + +// Quoting +wxString qtDbStringDollar(const wxString &value); +wxString qtStrip(const wxString &value); // remove \" + + +// string build helper +void AppendIfFilled(wxString &str, const wxString &delimiter, const wxString &what); + +// Create keyword list from PostgreSQL list +void FillKeywords(wxString &str); + +// Recreate a 9.0 datconfig +wxString TransformToNewDatconfig(const wxString &list); + +// Fill array, splitting the string separated by commas (maybe quoted elements) +void FillArray(wxArrayString &array, const wxString &str); + + +// splitting of strings, obeying quotes +class queryTokenizer : public wxStringTokenizer +{ +public: + queryTokenizer(const wxString &str, const wxChar delim = (wxChar)' '); + wxString GetNextToken(); +private: + char delimiter; +}; + +// Get an array from a comma(,) separated list +bool getArrayFromCommaSeparatedList(const wxString &str, wxArrayString &res); + +// File handling including encoding according to sysSettings if format<0, +// 0-> local charset, 1->utf8 +wxString FileRead(const wxString &filename, int format = -1); +bool FileWrite(const wxString &filename, const wxString &data, int format = -1); + +typedef enum +{ + HELP_PGADMIN, + HELP_POSTGRESQL, + HELP_ENTERPRISEDB, + HELP_GREENPLUM, + HELP_SLONY +} HelpType; + +wxString CleanHelpPath(const wxString &path); +bool HelpPathValid(const wxString &path); +void DisplayHelp(const wxString &helpTopic, const HelpType helpType); +void DisplayPgAdminHelp(const wxString &helpTopic); +void DisplayExternalHelp(const wxString &helpTopic, const wxString &docPath, wxHelpControllerBase *helpCtl, const bool init); + +#ifndef WIN32 +wxString ExecProcess(const wxString &cmd); +int ExecProcess(const wxString &command, wxArrayString &result); +#endif + +wxString GetHtmlEntity(const wxChar ch); +wxString HtmlEntities(const wxString &str); + +wxString firstLineOnly(const wxString &str); + +bool pgAppMinimumVersion(const wxString &cmd, const int majorVer, const int minorVer); +bool isPgApp(const wxString &app); +bool isEdbApp(const wxString &app); +bool isGpApp(const wxString &app); + +enum +{ + EDB_PACKAGE, + EDB_PACKAGEFUNCTION, + EDB_PACKAGEVARIABLE, + EDB_SYNONYM, + + PGM_CATALOG, + PGM_CATALOGOBJECT, + PGM_CHECK, + PGM_COLUMN, + PGM_CONSTRAINT, + PGM_DATABASE, + PGM_DOMAIN, + PGM_EXCLUDE, + PGM_FOREIGNKEY, + PGM_FOREIGNSERVER, + PGM_FOREIGNTABLE, + PGM_USERMAPPING, + PGM_FUNCTION, + PGM_INDEX, + PGM_OPCLASS, + PGM_OPFAMILY, + PGM_PRIMARYKEY, + PGM_ROLE, + PGM_RULE, + PGM_SCHEMA, + PGM_SERVER, + PGM_SEQUENCE, + PGM_TABLE, + PGM_TABLESPACE, + PGM_TRIGGER, + PGM_UNKNOWN, + PGM_UNIQUE, + PGM_VIEW, + + GP_EXTTABLE, + GP_RESOURCE_QUEUE, + GP_PARTITION, + + PG_PARTITION, + + PGM_JOB, + PGM_SCHEDULE, + PGM_STEP, + + SLM_LISTEN, + SLM_NODE, + SLM_PATH, + SLM_SEQUENCE, + SLM_SET, + SLM_SUBSCRIPTION, + SLM_TABLE, + + PGM_LANGUAGE, + PGM_EVENTTRIGGER +}; + + +enum // depends on pgaFactory::addImage order! +{ + PGICON_PROPERTY, + PGICON_STATISTICS, + PGICON_PUBLIC +}; + +// File/directory name cleanup +wxString sanitizePath(const wxString &path); +wxString commandLineCleanOption(const wxString &option, bool schemaObject = false); +#endif // PGSCLI + +// Quoting +wxString qtIdent(const wxString &value); // add " if necessary +wxString qtTypeIdent(const wxString &value); // add " if necessary + +#endif + diff --git a/include/utils/module.mk b/include/utils/module.mk new file mode 100644 index 0000000..69483c3 --- /dev/null +++ b/include/utils/module.mk @@ -0,0 +1,34 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/utild/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/utils/csvfiles.h \ + include/utils/factory.h \ + include/utils/favourites.h \ + include/utils/misc.h \ + include/utils/pgfeatures.h \ + include/utils/pgDefs.h \ + include/utils/pgconfig.h \ + include/utils/registry.h \ + include/utils/sysLogger.h \ + include/utils/sysProcess.h \ + include/utils/sysSettings.h \ + include/utils/utffile.h \ + include/utils/macros.h + +if BUILD_SSH_TUNNEL +pgadmin3_SOURCES += \ + include/utils/sshTunnel.h +endif + +EXTRA_DIST += \ + include/utils/module.mk + diff --git a/include/utils/pgDefs.h b/include/utils/pgDefs.h new file mode 100644 index 0000000..5bfc48a --- /dev/null +++ b/include/utils/pgDefs.h @@ -0,0 +1,80 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgDefs.h PostgreSQL constants +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGDEFS_H +#define PGDEFS_H + +#define PGOID_SCHEMA_CATALOG 11L +#define PGOID_SCHEMA_TOAST 99L +#define PGOID_SCHEMA_PUBLIC 2200L + +#define PGOID_CLASS_PG_AUTHID 1260L + +#define PGOID_TYPE_SERIAL -42L +#define PGOID_TYPE_SERIAL8 -43L +#define PGOID_TYPE_SERIAL2 -44L +#define PGOID_TYPE_BOOL 16L +#define PGOID_TYPE_BYTEA 17L +#define PGOID_TYPE_CHAR 18L +#define PGOID_TYPE_NAME 19L +#define PGOID_TYPE_INT8 20L +#define PGOID_TYPE_INT2 21L +#define PGOID_TYPE_INT4 23L +#define PGOID_TYPE_TEXT 25L +#define PGOID_TYPE_OID 26L +#define PGOID_TYPE_TID 27L +#define PGOID_TYPE_XID 28L +#define PGOID_TYPE_CID 29L +#define PGOID_TYPE_FLOAT4 700L +#define PGOID_TYPE_FLOAT8 701L +#define PGOID_TYPE_MONEY 790L +#define PGOID_TYPE_CHAR_ARRAY 1002L +#define PGOID_TYPE_TEXT_ARRAY 1009L +#define PGOID_TYPE_BPCHAR_ARRAY 1014L +#define PGOID_TYPE_VARCHAR_ARRAY 1015L +#define PGOID_TYPE_BPCHAR 1042L +#define PGOID_TYPE_VARCHAR 1043L +#define PGOID_TYPE_DATE 1082L +#define PGOID_TYPE_TIME 1083L +#define PGOID_TYPE_TIMESTAMP 1114L +#define PGOID_TYPE_TIMESTAMP_ARRAY 1115L +#define PGOID_TYPE_TIME_ARRAY 1183L +#define PGOID_TYPE_TIMESTAMPTZ 1184L +#define PGOID_TYPE_TIMESTAMPTZ_ARRAY 1185L +#define PGOID_TYPE_INTERVAL 1186L +#define PGOID_TYPE_INTERVAL_ARRAY 1187L +#define PGOID_TYPE_NUMERIC_ARRAY 1231L +#define PGOID_TYPE_TIMETZ 1266L +#define PGOID_TYPE_TIMETZ_ARRAY 1270L +#define PGOID_TYPE_BIT 1560L +#define PGOID_TYPE_BIT_ARRAY 1561L +#define PGOID_TYPE_VARBIT 1562L +#define PGOID_TYPE_VARBIT_ARRAY 1563L +#define PGOID_TYPE_NUMERIC 1700L +#define PGOID_TYPE_CSTRING 2275L +#define PGOID_TYPE_ANY 2276L +#define PGOID_TYPE_VOID 2278L +#define PGOID_TYPE_TRIGGER 2279L +#define PGOID_TYPE_LANGUAGE_HANDLER 2280L +#define PGOID_TYPE_INTERNAL 2281L +#define PGOID_TYPE_HANDLER 3115L + + +// These constants come from pgsql/src/include/catalog/pg_trigger.h +#define TRIGGER_TYPE_ROW (1 << 0) +#define TRIGGER_TYPE_BEFORE (1 << 1) +#define TRIGGER_TYPE_INSERT (1 << 2) +#define TRIGGER_TYPE_DELETE (1 << 3) +#define TRIGGER_TYPE_UPDATE (1 << 4) +#define TRIGGER_TYPE_TRUNCATE (1 << 5) +#define TRIGGER_TYPE_INSTEAD (1 << 6) + +#endif diff --git a/include/utils/pgconfig.h b/include/utils/pgconfig.h new file mode 100644 index 0000000..719c069 --- /dev/null +++ b/include/utils/pgconfig.h @@ -0,0 +1,241 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgconfig.h - backend configuration classes +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __PGCONFIG +#define __PGCONFIG + +#include + + +class pgSet; +class pgConn; + +class pgSettingItem; + +class pgConfigLine +{ +public: + pgConfigLine() + { + item = 0; + isComment = false; + } + + pgConfigLine(pgConfigLine *line); + + bool Differs(pgConfigLine *line); + wxString GetNewText(); + + pgSettingItem *item; + wxString value; + wxString comment; + bool isComment; +}; + +class pgConfigOrgLine : public pgConfigLine +{ +public: + pgConfigOrgLine(const wxString str) : pgConfigLine() + { + text = str; + } + pgConfigOrgLine(pgConfigLine *line); + wxString GetNewText(); + + wxString text; + wxString commentIndent; +}; + +class pgHbaConfigLine +{ +public: + pgHbaConfigLine(const wxString &line = wxEmptyString); + wxString GetText(); + const wxChar *GetConnectType(); + const wxChar *GetMethod(); + void Init(const wxString &line); + + enum pgHbaConnectType + { + PGC_LOCAL = 0, + PGC_HOST, + PGC_HOSTSSL, + PGC_HOSTNOSSL, + PGC_INVALIDCONF + }; + enum pgHbaMethod + { + PGC_TRUST = 0, + PGC_REJECT, + PGC_MD5, + PGC_CRYPT, + PGC_PASSWORD, + PGC_KRB4, + PGC_KRB5, + PGC_IDENT, + PGC_PAM, + PGC_LDAP, + PGC_GSS, + PGC_SSPI, + PGC_CERT, + PGC_PEER, + PGC_RADIUS, + PGC_INVALIDMETHOD + }; + + wxString text; + wxString database, user, ipaddress, option; + pgHbaConnectType connectType; + pgHbaMethod method; + + long item; + + bool isValid; + bool isComment; + bool changed; +}; + +class pgPassConfigLine +{ +public: + pgPassConfigLine(const wxString &line = wxEmptyString); + wxString GetText(); + void Init(const wxString &line); + + wxString text; + wxString hostname, port, database, username, password; + + long item; + + bool isComment; +}; + + +class pgSettingItem +{ +public: + enum pgConfigType + { + PGC_BOOL = 0, + PGC_INT, + PGC_REAL, + PGC_STRING + }; + + enum pgConfigContext + { + PGC_INTERNAL = 0, + PGC_POSTMASTER, + PGC_SIGHUP, + PGC_BACKEND, + PGC_SUSET, + PGC_USERLIMIT, + PGC_USERSET, + PGC_UNKNOWNCONTEXT + }; + + enum pgConfigSource + { + PGC_DEFAULT = 0, + PGC_ENVIRONMENT, + PGC_FILE, + PGC_ARGV, + PGC_UNPRIV, + PGC_DATABASE, + PGC_USER, + PGC_CLIENT, + PGC_OVERRIDE, + PGC_INTERACTIVE, + PGC_TEST, + PGC_SESSION, + PGC_UNKNOWNSOURCE + }; + + pgSettingItem() + { + orgLine = 0; + newLine = 0; + source = PGC_UNKNOWNSOURCE; + context = PGC_UNKNOWNCONTEXT; + } + ~pgSettingItem() + { + if (newLine) delete newLine; + } + + void SetType(const wxString &str); + void SetContext(const wxString &str); + void SetSource(const wxString &str); + wxString GetActiveValue(); + + wxString name; + wxString category; + wxString short_desc; + wxString extra_desc; + wxString value; + pgConfigType type; + pgConfigContext context; + pgConfigSource source; + + wxString min_val, max_val; + + pgConfigLine *newLine; + pgConfigOrgLine *orgLine; +}; + + + +WX_DECLARE_HASH_MAP(wxString, pgSettingItem *, wxStringHash, wxStringEqual, pgSettingItemHashmap); +WX_DECLARE_HASH_MAP(wxString, wxArrayString *, wxStringHash, wxStringEqual, pgCategoryHashmap); + +class pgSettingReader +{ +public: + virtual bool IsValid() = 0; + virtual pgSettingItem *GetNextItem() = 0; + virtual ~pgSettingReader() {} +}; + + +class pgSettingFileReader : public pgSettingReader +{ + wxString columnNames; + wxString buffer; + wxChar *bp; + +public: + pgSettingFileReader(bool localized); + ~pgSettingFileReader(); + virtual bool IsValid() + { + return !buffer.IsEmpty(); + } + virtual pgSettingItem *GetNextItem(); +}; + + +class pgSettingDbReader : public pgSettingReader +{ + pgSet *set; + +public: + pgSettingDbReader(pgConn *conn); + ~pgSettingDbReader(); + + virtual bool IsValid() + { + return set != NULL; + } + virtual pgSettingItem *GetNextItem(); +}; + +#endif diff --git a/include/utils/pgfeatures.h b/include/utils/pgfeatures.h new file mode 100644 index 0000000..0e68e38 --- /dev/null +++ b/include/utils/pgfeatures.h @@ -0,0 +1,31 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgfeatures.h PostgreSQL features constants +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __FEATURE_H +#define __FEATURE_H + +enum +{ + FEATURE_INITIALIZED = 0, + FEATURE_SIZE, + FEATURE_FILEREAD, + FEATURE_ROTATELOG, + FEATURE_POSTMASTER_STARTTIME, + FEATURE_TERMINATE_BACKEND, + FEATURE_RELOAD_CONF, + FEATURE_PGSTATTUPLE, + FEATURE_PGSTATINDEX, + FEATURE_FUNCTION_DEFAULTS, + FEATURE_LAST +}; + +#endif diff --git a/include/utils/registry.h b/include/utils/registry.h new file mode 100644 index 0000000..8e4e2bc --- /dev/null +++ b/include/utils/registry.h @@ -0,0 +1,89 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// RCS-ID: +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// registry.h - Windows Registry Reader for both 32 and 64 mode +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __PGREG_WINREGISTRY_H__ +#define __PGREG_WINREGISTRY_H__ + +#ifdef __WXMSW__ + +#include + +class pgRegKey +{ + +public: + enum PGREGWOWMODE + { + /* + * Read/Write 32 bit registry for 32 bit applications, + * Read/Write 64 bit registry for 64 bit applications + */ + PGREG_WOW_DEFAULT, + /* Read/Write 32 bit registry */ + PGREG_WOW32, + /* Read/Write 64 bit registry on 64 bit windows */ + PGREG_WOW64 + }; + + enum PGREGACCESSMODE + { + /* READ ONLY */ + PGREG_READ, + /* READ & Write */ + PGREG_WRITE + }; + +public: + static pgRegKey *OpenRegKey(HKEY root, const wxString &subkey, PGREGACCESSMODE accessmode = PGREG_READ, PGREGWOWMODE wowMode = PGREG_WOW_DEFAULT); + ~pgRegKey(); + + static bool KeyExists(HKEY root, const wxString &subKey, PGREGWOWMODE wowMode = PGREG_WOW_DEFAULT); + + bool GetKeyInfo(size_t *pnSubKeys, // number of subkeys + size_t *pnMaxKeyLen, // max len of subkey name + size_t *pnValues, // number of values + size_t *pnMaxValueLen) const; + + bool QueryValue(const wxString &strVal, LPDWORD pVal) const; + bool QueryValue(const wxString &strVal, wxString &pVal) const; + bool QueryValue(const wxString &strVal, LPBYTE &pVal, DWORD &len) const; + + bool GetFirstValue(wxString &strVal, long &lindex) const; + bool GetNextValue(wxString &strVal, long &lindex) const; + bool HasValue(const wxString &strVal); + + bool GetFirstKey(pgRegKey *&pkey, long &lindex) const; + bool GetNextKey(pgRegKey *&pkey, long &lindex) const; + bool HasKey(const wxString &strKey) const; + + DWORD GetValueType(const wxString &strVal) const; + + wxString ToString() const; + wxString GetKeyName() const; + +private: + pgRegKey(HKEY root, const wxString &subkey, PGREGWOWMODE wowMode, PGREGACCESSMODE accessMode); + pgRegKey(const pgRegKey &keyParent, const wxString &strKey); + + void Init(HKEY root, const wxString &subkey, PGREGWOWMODE wowMode, PGREGACCESSMODE accessMode); + void Close(); + + HKEY m_hRoot; + HKEY m_hKey; + wxString m_strName; + DWORD m_wowMode; + PGREGACCESSMODE m_accessMode; + +}; + +#endif // __WXMSW__ +#endif // __PGREG_WINREGISTRY_H__ + diff --git a/include/utils/sshTunnel.h b/include/utils/sshTunnel.h new file mode 100644 index 0000000..c78b742 --- /dev/null +++ b/include/utils/sshTunnel.h @@ -0,0 +1,119 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// sshTunnel.h - Used to create SSH Tunnels +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __SSH_TUNNELING +#define __SSH_TUNNELING + +#include +#include + +#ifdef WIN32 +#include +#else +#include +#include +#include +#include +#include +#include +#endif + +#include +#include +#include +#include "utils/misc.h" + +struct _LIBSSH2_CHANNEL; +struct _LIBSSH2_SESSION; +struct _LIBSSH2_USERAUTH_KBDINT_PROMPT; +struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE; + +enum enAuthenticationMethod +{ + AUTH_NONE = 0, + AUTH_PASSWORD, + AUTH_KEYBOARD_INTERACTIVE, + AUTH_PUBLICKEY = 4 +}; + +void LogSSHTunnelErrors(const wxString &msg, const int &id, struct _LIBSSH2_SESSION *session = NULL); +static wxMutex g_SSHThreadMutex; + +WX_DECLARE_HASH_SET( int, wxIntegerHash, wxIntegerEqual, subThreadSDSet); +static subThreadSDSet g_setSocketDescriptor; + +class CSSHTunnelThread : + public wxThread +{ +public: + CSSHTunnelThread(const wxString tunnelhost, const wxString remote_desthost, const unsigned int remote_destport, + const wxString username, const wxString password, const wxString publickey, const wxString privatekey, + const enAuthenticationMethod &enAuthMethod, const unsigned int tunnelPort = 22); + virtual ~CSSHTunnelThread(void); + virtual void *Entry(); + bool Initialize(); + void Cleanup(); + + wxString GetLocalListenIP() const + { + return m_local_listenip; + } + + unsigned int GetLocalListenPort() const + { + return m_local_listenport; + } + +private: + bool resolveDNS(const char *host, wxArrayString &arrIPAddress); + static void keyboard_interactive(const char *name, int name_len, const char *instr, int instr_len, + int num_prompts, const struct _LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts, struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE *res, void **abstract); + bool IsHostKeyVerified(const wxString &newHostKey); + + int m_listensock, m_sock; + struct sockaddr_in m_sin; + socklen_t m_sinlen; + struct _LIBSSH2_SESSION *m_session; + static char m_keyboard_interactive_pwd[SSH_MAX_PASSWORD_LEN]; + + wxString m_publickey; + wxString m_privatekey; + wxString m_username; + wxString m_password; + wxString m_tunnelhost; + wxString m_local_listenip; + wxString m_remote_desthost; + unsigned int m_local_listenport; + unsigned int m_remote_destport; + unsigned int m_tunnelPort; + enAuthenticationMethod m_enAuthMethod; +}; + +class CSubThread : + public wxThread +{ +public: + CSubThread(const struct sockaddr_in sin, const wxString remote_desthost, const unsigned int remote_destport, + struct _LIBSSH2_SESSION *session, int forwardsock); + virtual ~CSubThread(void); + virtual void *Entry(); + +private: + struct sockaddr_in m_sin; + wxString m_remote_desthost; + unsigned int m_remote_destport; + struct _LIBSSH2_SESSION *m_subThreadSession; + struct _LIBSSH2_CHANNEL *m_channel; + int m_forwardsock; +}; + +#endif diff --git a/include/utils/sysLogger.h b/include/utils/sysLogger.h new file mode 100644 index 0000000..a69aad9 --- /dev/null +++ b/include/utils/sysLogger.h @@ -0,0 +1,77 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// sysLogger.h - Log handling class +// +////////////////////////////////////////////////////////////////////////// + +#ifndef SYSLOGGER_H +#define SYSLOGGER_H + +// wxWindows headers +#include + +// App headers + +enum LOG_LEVEL +{ + LOG_NONE = 0, + LOG_ERRORS = 1, + LOG_NOTICE = 2, + LOG_SQL = 3, + LOG_DEBUG = 4 +}; + +// Class declarations +class sysLogger : public wxLog +{ +public: +#if wxCHECK_VERSION(2, 9, 0) + void DoLogTextAtLevel(wxLogLevel level, const wxString &msg); +#else + virtual void DoLog(wxLogLevel level, const wxChar *msg, time_t timestamp); +#endif + + static wxLogLevel logLevel; + static wxString logFile; + +private: + void WriteLog(const wxString &msg); + bool SilenceMessage(const wxString &msg); +}; + +#define wxLOG_Notice (wxLOG_User+1) +#define wxLOG_Sql (wxLOG_User+2) +#define wxLOG_QuietError (wxLOG_User+3) +#define wxLOG_Script (wxLOG_User+4) +#define wxLOG_ScriptVerbose (wxLOG_User+5) + +#if wxCHECK_VERSION(2, 9, 0) + +#define wxLogNotice wxDO_LOG(Notice) +#define wxLogSql wxDO_LOG(Sql) +#define wxLogQuietError wxDO_LOG(QuietError) +#define wxLogScript wxDO_LOG(Script) +#define wxLogScriptVerbose wxDO_LOG(ScriptVerbose) + +#else + +#define DECLARE_INT_LOG_FUNCTION(level) \ +extern void wxVLog##level(const wxChar *szFormat, va_list argptr); \ +extern void wxLog##level(const wxChar *szFormat, ...) + +DECLARE_INT_LOG_FUNCTION(Notice); +DECLARE_INT_LOG_FUNCTION(Sql); +DECLARE_INT_LOG_FUNCTION(QuietError); +DECLARE_INT_LOG_FUNCTION(Script); +DECLARE_INT_LOG_FUNCTION(ScriptVerbose); + +#endif + + +#endif // SYSLOGGER_H + diff --git a/include/utils/sysProcess.h b/include/utils/sysProcess.h new file mode 100644 index 0000000..6e44555 --- /dev/null +++ b/include/utils/sysProcess.h @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// sysProcess.h - External process +// +////////////////////////////////////////////////////////////////////////// + +#ifndef SYSPROCESS_H +#define SYSPROCESS_H + +#include +#include "wx/process.h" +#include + +class sysProcess : public wxProcess +{ +public: + sysProcess(wxEvtHandler *evh, wxMBConv &conv = wxConvLibc); + + bool Run(const wxString &exec); + void Abort(); + void SetEnvironment(const wxArrayString &environment); + wxString ReadInputStream(); + wxString ReadErrorStream(); + void WriteOutputStream(const wxString &out); + + static sysProcess *Create(const wxString &exec, wxEvtHandler *evh = 0, wxArrayString *env = 0, wxMBConv &conv = wxConvLibc); + +private: + int pid; + wxMBConv &m_conv; + void OnTerminate(int pid, int status) const; + wxString ReadStream(wxInputStream *input); +}; + + + +#endif diff --git a/include/utils/sysSettings.h b/include/utils/sysSettings.h new file mode 100644 index 0000000..c0707ed --- /dev/null +++ b/include/utils/sysSettings.h @@ -0,0 +1,857 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// sysSettings.h - Settings handling class +// +////////////////////////////////////////////////////////////////////////// + +#ifndef SYSSETTINGS_H +#define SYSSETTINGS_H + +#include "utils/sysLogger.h" + +// wxWindows headers +#include +#include +#include + +// Class declarations +class sysSettings : private wxConfig +{ +public: + sysSettings(const wxString &name); + ~sysSettings(); + // Display options + bool GetDisplayOption(const wxString &objtype, bool GetDefault = false); + void SetDisplayOption(const wxString &objtype, bool display); + + void FlushChanges() + { + wxConfig::Flush(); + } + + // Log + wxString GetLogFile(); + void SetLogFile(const wxString &newval) + { + Write(wxT("LogFile"), newval); + sysLogger::logFile = newval; + } + int GetLogLevel() const + { + int i; + Read(wxT("LogLevel"), &i, LOG_ERRORS); + return i; + } + void SetLogLevel(const int newval) + { + WriteInt(wxT("LogLevel"), newval); + sysLogger::logLevel = newval; + } + + // Last connection + wxString GetLastDescription() const + { + wxString s; + Read(wxT("LastDescription"), &s, wxT("PostgreSQL Server")); + return s; + } + void SetLastDescription(const wxString &newval) + { + Write(wxT("LastDescription"), newval); + } + wxString GetLastServer() const + { + wxString s; + Read(wxT("LastServer"), &s, wxT("localhost")); + return s; + } + void SetLastServer(const wxString &newval) + { + Write(wxT("LastServer"), newval); + } + wxString GetLastDatabase() const + { + wxString s; + Read(wxT("LastDatabase"), &s, wxT("postgres")); + return s; + } + void SetLastDatabase(const wxString &newval) + { + Write(wxT("LastDatabase"), newval); + } + wxString GetLastUsername() const + { + wxString s; + Read(wxT("LastUsername"), &s, wxT("postgres")); + return s; + } + void SetLastUsername(const wxString &newval) + { + Write(wxT("LastUsername"), newval); + } + int GetLastPort() const + { + int i; + Read(wxT("LastPort"), &i, 5432); + return i; + } + void SetLastPort(const int newval) + { + WriteInt(wxT("LastPort"), newval); + } + int GetLastSSL() const + { + int i; + Read(wxT("LastSSL"), &i, 0); + return i; + } + void SetLastSSL(const int newval) + { + WriteInt(wxT("LastSSL"), newval); + } + + // Helper paths + wxString GetSlonyPath() const + { + wxString s; + Read(wxT("SlonyPath"), &s, wxEmptyString); + return s; + } + void SetSlonyPath(const wxString &newval) + { + Write(wxT("SlonyPath"), newval); + } + wxString GetPostgresqlPath() const + { + wxString s; + Read(wxT("PostgreSQLPath"), &s, wxEmptyString); + return s; + } + void SetPostgresqlPath(const wxString &newval) + { + Write(wxT("PostgreSQLPath"), newval); + } + wxString GetEnterprisedbPath() const + { + wxString s; + Read(wxT("EnterpriseDBPath"), &s, wxEmptyString); + return s; + } + void SetEnterprisedbPath(const wxString &newval) + { + Write(wxT("EnterpriseDBPath"), newval); + } + wxString GetGPDBPath() const + { + wxString s; + Read(wxT("GreenplumDBPath"), &s, wxEmptyString); + return s; + } + void SetGPDBPath(const wxString &newval) + { + Write(wxT("GreenplumDBPath"), newval); + } + + // Help paths + wxString GetSlonyHelpPath(); + void SetSlonyHelpPath(const wxString &newval) + { + Write(wxT("SlonyHelpPath"), newval); + } + wxString GetPgHelpPath(); + void SetPgHelpPath(const wxString &newval) + { + Write(wxT("PostgreSQLHelpPath"), newval); + } + wxString GetEdbHelpPath(); + void SetEdbHelpPath(const wxString &newval) + { + Write(wxT("EnterpriseDBHelpPath"), newval); + } + wxString GetGpHelpPath(); + void SetGpHelpPath(const wxString &newval) + { + Write(wxT("GreenplumDBHelpPath"), newval); + } + + // Copy options + wxString GetCopyQuoteChar() const + { + wxString s; + Read(wxT("Copy/QuoteChar"), &s, wxT("\"")); + return s; + } + void SetCopyQuoteChar(const wxString &newval) + { + Write(wxT("Copy/QuoteChar"), newval); + } + wxString GetCopyColSeparator() const + { + wxString s; + Read(wxT("Copy/ColSeparator"), &s, wxT(";")); + return s; + } + void SetCopyColSeparator(const wxString &newval) + { + Write(wxT("Copy/ColSeparator"), newval); + } + int GetCopyQuoting(); // 0=none 1=string 2=all + void SetCopyQuoting(const int i); + + // Export options + wxString GetExportQuoteChar() const + { + wxString s; + Read(wxT("Export/QuoteChar"), &s, wxT("\"")); + return s; + } + void SetExportQuoteChar(const wxString &newval) + { + Write(wxT("Export/QuoteChar"), newval); + } + wxString GetExportColSeparator() const + { + wxString s; + Read(wxT("Export/ColSeparator"), &s, wxT(";")); + return s; + } + void SetExportColSeparator(const wxString &newval) + { + Write(wxT("Export/ColSeparator"), newval); + } + wxString GetExportRowSeparator(); + void SetExportRowSeparator(const wxString &s); + int GetExportQuoting(); // 0=none 1=string 2=all + void SetExportQuoting(const int i); + bool GetExportUnicode() const + { + bool b; + Read(wxT("Export/Unicode"), &b, true); + return b; + } + void SetExportUnicode(const bool newval) + { + WriteBool(wxT("Export/Unicode"), newval); + } + bool GetWriteBOM() const + { + bool b; + Read(wxT("Export/WriteBOM"), &b, true); + return b; + } + void SetWriteBOM(const bool newval) + { + WriteBool(wxT("Export/WriteBOM"), newval); + } + + // Explain options + bool GetExplainVerbose() const + { + bool b; + Read(wxT("frmQuery/ExplainVerbose"), &b, false); + return b; + } + void SetExplainVerbose(const bool newval) + { + WriteBool(wxT("frmQuery/ExplainVerbose"), newval); + } + bool GetExplainCosts() const + { + bool b; + Read(wxT("frmQuery/ExplainCosts"), &b, true); + return b; + } + void SetExplainCosts(const bool newval) + { + WriteBool(wxT("frmQuery/ExplainCosts"), newval); + } + bool GetExplainBuffers() const + { + bool b; + Read(wxT("frmQuery/ExplainBuffers"), &b, false); + return b; + } + void SetExplainBuffers(const bool newval) + { + WriteBool(wxT("frmQuery/ExplainBuffers"), newval); + } + bool GetExplainTiming() const + { + bool b; + Read(wxT("frmQuery/ExplainTiming"), &b, true); + return b; + } + void SetExplainTiming(const bool newval) + { + WriteBool(wxT("frmQuery/ExplainTiming"), newval); + } + + // Display options + wxString GetSystemSchemas() const + { + wxString s; + Read(wxT("SystemSchemas"), &s, wxEmptyString); + return s; + } + void SetSystemSchemas(const wxString &newval) + { + Write(wxT("SystemSchemas"), newval); + } + bool GetShowUsersForPrivileges() const + { + bool b; + Read(wxT("ShowUsersForPrivileges"), &b, false); + return b; + } + void SetShowUsersForPrivileges(const bool newval) + { + WriteBool(wxT("ShowUsersForPrivileges"), newval); + } + bool GetShowSystemObjects() const + { + bool b; + Read(wxT("ShowSystemObjects"), &b, false); + return b; + } + void SetShowSystemObjects(const bool newval) + { + WriteBool(wxT("ShowSystemObjects"), newval); + } + + // Editor options + bool GetSpacesForTabs() const + { + bool b; + Read(wxT("SpacesForTabs"), &b, false); + return b; + } + void SetSpacesForTabs(const bool newval) + { + WriteBool(wxT("SpacesForTabs"), newval); + } + long GetIndentSpaces() const + { + long l; + Read(wxT("IndentSpaces"), &l, 0L); + return l; + } + void SetIndentSpaces(const long newval) + { + WriteLong(wxT("IndentSpaces"), newval); + } + bool GetIndicateNull() const + { + bool b; + Read(wxT("frmQuery/IndicateNull"), &b, false); + return b; + } + void SetIndicateNull(const bool newval) + { + WriteBool(wxT("frmQuery/IndicateNull"), newval); + } + wxString GetThousandsSeparator() const + { + wxString s; + Read(wxT("frmQuery/ThousandsSeparator"), &s, wxEmptyString); + return s; + } + void SetThousandsSeparator(const wxString &newval) + { + Write(wxT("frmQuery/ThousandsSeparator"), newval); + } + bool GetAutoRollback() const + { + bool b; + Read(wxT("frmQuery/AutoRollback"), &b, false); + return b; + } + bool GetAutoSelectQuery() const + { + bool b; + Read(wxT("frmQuery/AutoSelectQuery"), &b, false); + return b; + } + void SetAutoRollback(const bool newval) + { + WriteBool(wxT("frmQuery/AutoRollback"), newval); + } + bool GetAutoCommit() const + { + bool b; + Read(wxT("frmQuery/AutoCommit"), &b, true); + return b; + } + void SetAutoCommit(const bool newval) + { + WriteBool(wxT("frmQuery/AutoCommit"), newval); + } + wxString GetDecimalMark() const + { + wxString s; + Read(wxT("DecimalMark"), &s, wxEmptyString); + return s; + } + void SetDecimalMark(const wxString &newval) + { + Write(wxT("DecimalMark"), newval); + } + bool GetColumnNames() const + { + bool b; + Read(wxT("ColumnNames"), &b, false); + return b; + } + void SetColumnNames(const bool newval) + { + WriteBool(wxT("ColumnNames"), newval); + } + bool GetLineNumber() const + { + bool b; + Read(wxT("ShowLineNumber"), &b, false); + return b; + } + void SetLineNumber(const bool newval) + { + WriteBool(wxT("ShowLineNumber"), newval); + } + bool GetUnicodeFile() const + { + bool b; + Read(wxT("WriteUnicodeFile"), &b, true); + return b; + } + void SetUnicodeFile(const bool newval) + { + WriteBool(wxT("WriteUnicodeFile"), newval); + } + wxFont GetSystemFont(); + void SetSystemFont(const wxFont &font); + wxFont GetSQLFont(); + void SetSQLFont(const wxFont &font); + wxFont GetDDFont(); + void SetDDFont(const wxFont &font); + int GetLineEndingType() const + { + int i; + int defval = 2; +#ifdef __WXMSW__ + defval = 0; /* SC_EOL_CRLF in Scintilla.h */ +#else + defval = 2; /* SC_EOL_LF in Scintilla.h */ +#endif + Read(wxT("LineEndingType"), &i, defval); + return i; + } + void SetLineEndingType(const int newval) + { + WriteInt(wxT("LineEndingType"), newval); + } + wxString GetFavouritesFile(); + void SetFavouritesFile(const wxString &newval) + { + Write(wxT("FavouritesFile"), newval); + } + wxString GetMacrosFile(); + wxString GetAutoReplaceFile(); + void SetAutoReplaceFile(const wxString &newval) + { + Write(wxT("AutoReplaceFile"), newval); + } + void SetMacrosFile(const wxString &newval) + { + Write(wxT("MacrosFile"), newval); + } + wxString GetExtFormatCmd() + { + wxString s; + Read(wxT("ExtFormatCmd"), &s, wxEmptyString); + return s; + } + void SetExtFormatCmd(const wxString &newval) + { + Write(wxT("ExtFormatCmd"), newval); + } + long GetExtFormatTimeout() const + { + long l; + Read(wxT("ExtFormatTimeout"), &l, 3000L); + return l; + } + void SetExtFormatTimeout(const long newval) + { + WriteLong(wxT("ExtFormatTimeout"), newval); + } + wxString GetHistoryFile(); + void SetHistoryFile(const wxString &newval) + { + Write(wxT("History/File"), newval); + } + long GetHistoryMaxQueries() const + { + long l; + Read(wxT("History/MaxQueries"), &l, 10L); + return l; + } + void SetHistoryMaxQueries(const long newval) + { + WriteLong(wxT("History/MaxQueries"), newval); + } + long GetHistoryMaxQuerySize() const + { + long l; + Read(wxT("History/MaxQuerySize"), &l, 1024L); + return l; + } + void SetHistoryMaxQuerySize(const long newval) + { + WriteLong(wxT("History/MaxQuerySize"), newval); + } + + // Custom Colours options + wxString GetCustomColour(int index) const + { + wxString s; + Read(wxT("CustomColour") + NumToStr((long) index), &s, wxT("#ffffff")); + return s; + } + void SetCustomColour(int index, const wxString &newval) + { + Write(wxT("CustomColour") + NumToStr((long) index), newval); + } + + // Status Colours options + wxString GetIdleProcessColour() const + { + wxString s; + Read(wxT("IdleProcessColour"), &s, wxT("#5fa4d9")); + return s; + } + void SetIdleProcessColour(const wxString &newval) + { + Write(wxT("IdleProcessColour"), newval); + } + wxString GetActiveProcessColour() const + { + wxString s; + Read(wxT("ActiveProcessColour"), &s, wxT("#5fd95f")); + return s; + } + void SetActiveProcessColour(const wxString &newval) + { + Write(wxT("ActiveProcessColour"), newval); + } + wxString GetSlowProcessColour() const + { + wxString s; + Read(wxT("SlowProcessColour"), &s, wxT("#d9a75f")); + return s; + } + void SetSlowProcessColour(const wxString &newval) + { + Write(wxT("SlowProcessColour"), newval); + } + wxString GetBlockedProcessColour() const + { + wxString s; + Read(wxT("BlockedProcessColour"), &s, wxT("#d96e5f")); + return s; + } + void SetBlockedProcessColour(const wxString &newval) + { + Write(wxT("BlockedProcessColour"), newval); + } + + // SQL Editor Colours options + bool GetSQLBoxUseSystemBackground() const + { + bool b; + Read(wxT("ctlSQLBox/UseSystemBackground"), &b, true); + return b; + } + void SetSQLBoxUseSystemBackground(const bool newval) + { + WriteBool(wxT("ctlSQLBox/UseSystemBackground"), newval); + } + bool GetSQLBoxUseSystemForeground() const + { + bool b; + Read(wxT("ctlSQLBox/UseSystemForeground"), &b, true); + return b; + } + void SetSQLBoxUseSystemForeground(const bool newval) + { + WriteBool(wxT("ctlSQLBox/UseSystemForeground"), newval); + } + + wxString GetSQLBoxColourBackground() const + { + wxString s; + Read(wxT("ctlSQLBox/ColourBackground"), &s, wxT("#ffffff")); + return s; + } + void SetSQLBoxColourBackground(const wxString &newval) + { + Write(wxT("ctlSQLBox/ColourBackground"), newval); + } + wxString GetSQLBoxColourForeground() const + { + wxString s; + Read(wxT("ctlSQLBox/ColourForeground"), &s, wxT("#000000")); + return s; + } + void SetSQLBoxColourForeground(const wxString &newval) + { + Write(wxT("ctlSQLBox/ColourForeground"), newval); + } + + wxString GetSQLColourCaret() const + { + wxString s; + Read(wxT("ctlSQLBox/ColourCaret"), &s, wxT("#000000")); + return s; + } + void SetSQLColourCaret(const wxString &newval) + { + Write(wxT("ctlSQLBox/ColourCaret"), newval); + } + + wxString GetSQLBoxColour(int index) const + { + wxString s; + Read(wxString::Format(wxT("ctlSQLBox/Colour%i"), index), &s, getDefaultElementColor(index)); + return s; + } + void SetSQLBoxColour(int index, const wxString &newval) + { + Write(wxString::Format(wxT("ctlSQLBox/Colour%i"), index), newval); + } + + wxString GetSQLMarginBackgroundColour() const + { + wxString s; + Read(wxT("ctlSQLBox/MarginBackgroundColour"), &s, wxT("#dddddd")); + return s; + } + void SetSQLMarginBackgroundColour(const wxString &newval) + { + Write(wxT("ctlSQLBox/MarginBackgroundColour"), newval); + } + bool GetSQLKeywordsInUppercase() const + { + bool b; + Read(wxT("KeywordsInUppercase"), &b, false); + return b; + } + void SetSQLKeywordsInUppercase(const bool newval) + { + WriteBool(wxT("KeywordsInUppercase"), newval); + } + + // Misc options + long GetAutoRowCountThreshold() const + { + long l; + Read(wxT("AutoRowCount"), &l, 2000L); + return l; + } + void SetAutoRowCountThreshold(const long newval) + { + WriteLong(wxT("AutoRowCount"), newval); + } + bool GetStickySql() const + { + bool b; + Read(wxT("StickySql"), &b, false); + return b; + } + void SetStickySql(const bool newval) + { + WriteBool(wxT("StickySql"), newval); + } + bool GetDoubleClickProperties() const + { + bool b; + Read(wxT("DoubleClickProperties"), &b, false); + return b; + } + void SetDoubleClickProperties(const bool newval) + { + WriteBool(wxT("DoubleClickProperties"), newval); + } + long GetMaxServerLogSize() const + { + long l; + Read(wxT("MaxServerLogSize"), &l, 100000L); + return l; + } + void SetMaxServerLogSize(const long newval) + { + WriteLong(wxT("MaxServerLogSize"), newval); + } + bool GetSuppressGuruHints() const + { + bool b; + Read(wxT("SuppressGuruHints"), &b, false); + return b; + } + void SetSuppressGuruHints(const bool newval) + { + WriteBool(wxT("SuppressGuruHints"), newval); + } + long GetMaxRows() const + { + long l; + Read(wxT("frmQuery/MaxRows"), &l, 100L); + return l; + } + void SetMaxRows(const long newval) + { + WriteLong(wxT("frmQuery/MaxRows"), newval); + } + long GetMaxColSize() const + { + long l; + Read(wxT("frmQuery/MaxColSize"), &l, 256L); + return l; + } + void SetMaxColSize(const long newval) + { + WriteLong(wxT("frmQuery/MaxColSize"), newval); + } + bool GetAskSaveConfirmation() const + { + bool b; + Read(wxT("AskSaveConfirmation"), &b, true); + return b; + } + void SetAskSaveConfirmation(const bool newval) + { + WriteBool(wxT("AskSaveConfirmation"), newval); + } + bool GetConfirmDelete() const + { + bool b; + Read(wxT("ConfirmDelete"), &b, true); + return b; + } + void SetConfirmDelete(const bool newval) + { + WriteBool(wxT("ConfirmDelete"), newval); + } + wxString GetCanonicalLanguageName(); + wxLanguage GetCanonicalLanguage() const + { + int i; + Read(wxT("LanguageId"), &i, wxLANGUAGE_UNKNOWN); + return (wxLanguage)i; + } + void SetCanonicalLanguage(const wxLanguage &lang); + bool GetIgnoreVersion() const + { + bool b; + Read(wxT("IgnoreVersion"), &b, false); + return b; + } + void SetIgnoreVersion(const bool newval) + { + WriteBool(wxT("IgnoreVersion"), newval); + } + + int GetRefreshOnClick() const + { + int i; + Read(wxT("RefreshOnClick"), &i, 0); + return i; + } + void SetRefreshOnClick(const int newval) + { + WriteInt(wxT("RefreshOnClick"), newval); + } + + bool GetShowNotices() const + { + bool b; + Read(wxT("ShowNotices"), &b, false); + return b; + } + void SetShowNotices(const bool newval) + { + WriteBool(wxT("ShowNotices"), newval); + } + + wxString GetOptionsLastTreeItem() const + { + wxString s; + Read(wxT("OptionsLastTreeItem"), &s, wxEmptyString); + return s; + } + void SetOptionsLastTreeItem(const wxString &newval) + { + Write(wxT("OptionsLastTreeItem"), newval); + } + + + // Functions for storing settings + bool Write(const wxString &key, const wxString &value) + { + return wxConfig::Write(key, value); + } + bool WriteLong(const wxString &key, long value) + { + return wxConfig::Write(key, value); + } + bool WriteInt(const wxString &key, int value) + { + return wxConfig::Write(key, value); + } + bool WriteBool(const wxString &key, bool value); + bool WritePoint(const wxString &key, const wxPoint &value); + bool WriteSize(const wxString &key, const wxSize &value); + bool WriteSizePoint(const wxString &key, const wxSize &size, const wxPoint &point) + { + WritePoint(key, point); + WriteSize(key, size); + return true; + } + + // Functions for reading settings + bool Read(const wxString &key, wxString *str, const wxString &defaultVal) const; + bool Read(const wxString &key, bool *str, bool defaultVal) const; + bool Read(const wxString &key, int *i, int defaultVal) const; + bool Read(const wxString &key, long *l, long defaultVal) const; + wxString Read(const wxString &key, const wxString &defaultVal) const; + long Read(const wxString &key, long defaultVal) const; + wxPoint Read(const wxString &key, const wxPoint &defaultVal) const; + wxSize Read(const wxString &key, const wxSize &defaultVal) const; + + enum configFileName + { + PGPASS + }; + static wxString GetConfigFile(configFileName cfgname); + +private: + static const wxString &getDefaultElementColor(int index) + { + static const wxString colors[] = + { + wxT("#808080"), wxT("#007f00"), wxT("#007f00"), wxT("#7f7f7f"), + wxT("#007f7f"), wxT("#00007f"), wxT("#7f007f"), wxT("#7f007f"), + wxT("#007f7f"), wxT("#7f7f7f"), wxT("#000000"), wxT("#000000") + }; + return colors[index]; + } + + bool moveStringValue(const wxChar *oldKey, const wxChar *newKey, int index = -1); + bool moveLongValue(const wxChar *oldKey, const wxChar *newKey, int index = -1); + + wxFileConfig *defaultSettings; +}; + +#endif diff --git a/include/utils/utffile.h b/include/utils/utffile.h new file mode 100644 index 0000000..43130de --- /dev/null +++ b/include/utils/utffile.h @@ -0,0 +1,62 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// utffile.h - file io with BOM interpretation +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef _WX_UTFFILEH__ +#define _WX_UTFFILEH__ + +#include "wx/wx.h" +#include "wx/font.h" +#include "wx/file.h" + +class wxUtfFile : public wxFile +{ +public: + wxUtfFile(); + wxUtfFile(const wxChar *szFileName, OpenMode mode = read, wxFontEncoding encoding = wxFONTENCODING_DEFAULT); + wxUtfFile(int fd, wxFontEncoding encoding = wxFONTENCODING_DEFAULT); + + bool Create(const wxChar *szFileName, bool bOverwrite = false, int access = wxS_DEFAULT, wxFontEncoding encoding = wxFONTENCODING_DEFAULT); + bool Open(const wxChar *szFileName, OpenMode mode = read, int access = wxS_DEFAULT, wxFontEncoding encoding = wxFONTENCODING_DEFAULT); + void Attach(int fd, wxFontEncoding encoding = wxFONTENCODING_DEFAULT); + + wxFontEncoding GetEncoding(); + + off_t Seek(off_t ofs, wxSeekMode mode = wxFromStart); + off_t SeekEnd(off_t ofs = 0) + { + return Seek(ofs, wxFromEnd); + } + off_t Tell() const + { + return wxFile::Tell() - m_bomOffset; + } + off_t Length() const + { + return wxFile::Length() - m_bomOffset; + } + + off_t Read(wxString &str, off_t nCount = (off_t) - 1); + bool Write(const wxString &str); + +protected: + + void WriteBOM(); + void DetermineConversion(wxFontEncoding encoding); + bool EvalBOM(wxFontEncoding encoding); + + wxMBConv *m_conversion; + wxFontEncoding m_encoding; + off_t m_bomOffset; + wxString m_strFileName; +}; + +#endif // _WX_UTFFILEH__ diff --git a/include/version.h b/include/version.h new file mode 100644 index 0000000..167907e --- /dev/null +++ b/include/version.h @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// version.h - pgAdmin version info +// +////////////////////////////////////////////////////////////////////////// + +#ifndef VERSION_H +#define VERSION_H + +// Application Versions +#define VERSION_STR wxT("1.25.0 Dev ASUTP version with support PG11") +#define VERSION_NUM 1,25,0,0 +#define VERSION_PACKAGE 1.25.0-dev + +#define PRERELEASE 1 +// #define BUILD "..." + +#ifdef RC_INVOKED + +#define wxT(str) str +#define _(str) str + +#include "winver.h" +#ifdef __WXDEBUG__ +#define VER_DEBUG VS_FF_DEBUG +#else +#define VER_DEBUG 0 +#endif + +#if PRERELEASE +#define VER_PRERELEASE VS_FF_PRERELEASE +#else +#define VER_PRERELEASE 0 +#endif +#endif +#define VERSION_WITH_DATE wxT("Version ") VERSION_STR wxT(" (") __TDATE__ wxT(")") +#define VERSION_WITHOUT_DATE wxT("Version ") VERSION_STR + +#endif diff --git a/libssh2/agent.c b/libssh2/agent.c new file mode 100644 index 0000000..b797cbd --- /dev/null +++ b/libssh2/agent.c @@ -0,0 +1,810 @@ +/* + * Copyright (c) 2009 by Daiki Ueno + * Copyright (C) 2010-2014 by Daniel Stenberg + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#include "misc.h" +#include +#ifdef HAVE_SYS_UN_H +#include +#else +/* Use the existence of sys/un.h as a test if Unix domain socket is + supported. winsock*.h define PF_UNIX/AF_UNIX but do not actually + support them. */ +#undef PF_UNIX +#endif +#include "userauth.h" +#include "session.h" + +/* Requests from client to agent for protocol 1 key operations */ +#define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1 +#define SSH_AGENTC_RSA_CHALLENGE 3 +#define SSH_AGENTC_ADD_RSA_IDENTITY 7 +#define SSH_AGENTC_REMOVE_RSA_IDENTITY 8 +#define SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9 +#define SSH_AGENTC_ADD_RSA_ID_CONSTRAINED 24 + +/* Requests from client to agent for protocol 2 key operations */ +#define SSH2_AGENTC_REQUEST_IDENTITIES 11 +#define SSH2_AGENTC_SIGN_REQUEST 13 +#define SSH2_AGENTC_ADD_IDENTITY 17 +#define SSH2_AGENTC_REMOVE_IDENTITY 18 +#define SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19 +#define SSH2_AGENTC_ADD_ID_CONSTRAINED 25 + +/* Key-type independent requests from client to agent */ +#define SSH_AGENTC_ADD_SMARTCARD_KEY 20 +#define SSH_AGENTC_REMOVE_SMARTCARD_KEY 21 +#define SSH_AGENTC_LOCK 22 +#define SSH_AGENTC_UNLOCK 23 +#define SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26 + +/* Generic replies from agent to client */ +#define SSH_AGENT_FAILURE 5 +#define SSH_AGENT_SUCCESS 6 + +/* Replies from agent to client for protocol 1 key operations */ +#define SSH_AGENT_RSA_IDENTITIES_ANSWER 2 +#define SSH_AGENT_RSA_RESPONSE 4 + +/* Replies from agent to client for protocol 2 key operations */ +#define SSH2_AGENT_IDENTITIES_ANSWER 12 +#define SSH2_AGENT_SIGN_RESPONSE 14 + +/* Key constraint identifiers */ +#define SSH_AGENT_CONSTRAIN_LIFETIME 1 +#define SSH_AGENT_CONSTRAIN_CONFIRM 2 + +/* non-blocking mode on agent connection is not yet implemented, but + for future use. */ +typedef enum { + agent_NB_state_init = 0, + agent_NB_state_request_created, + agent_NB_state_request_length_sent, + agent_NB_state_request_sent, + agent_NB_state_response_length_received, + agent_NB_state_response_received +} agent_nonblocking_states; + +typedef struct agent_transaction_ctx { + unsigned char *request; + size_t request_len; + unsigned char *response; + size_t response_len; + agent_nonblocking_states state; +} *agent_transaction_ctx_t; + +typedef int (*agent_connect_func)(LIBSSH2_AGENT *agent); +typedef int (*agent_transact_func)(LIBSSH2_AGENT *agent, + agent_transaction_ctx_t transctx); +typedef int (*agent_disconnect_func)(LIBSSH2_AGENT *agent); + +struct agent_publickey { + struct list_node node; + + /* this is the struct we expose externally */ + struct libssh2_agent_publickey external; +}; + +struct agent_ops { + agent_connect_func connect; + agent_transact_func transact; + agent_disconnect_func disconnect; +}; + +struct _LIBSSH2_AGENT +{ + LIBSSH2_SESSION *session; /* the session this "belongs to" */ + + libssh2_socket_t fd; + + struct agent_ops *ops; + + struct agent_transaction_ctx transctx; + struct agent_publickey *identity; + struct list_head head; /* list of public keys */ +}; + +#ifdef PF_UNIX +static int +agent_connect_unix(LIBSSH2_AGENT *agent) +{ + const char *path; + struct sockaddr_un s_un; + + path = getenv("SSH_AUTH_SOCK"); + if (!path) + return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_USE, + "no auth sock variable"); + + agent->fd = socket(PF_UNIX, SOCK_STREAM, 0); + if (agent->fd < 0) + return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_SOCKET, + "failed creating socket"); + + s_un.sun_family = AF_UNIX; + strncpy (s_un.sun_path, path, sizeof s_un.sun_path); + s_un.sun_path[sizeof(s_un.sun_path)-1]=0; /* make sure there's a trailing + zero */ + if (connect(agent->fd, (struct sockaddr*)(&s_un), sizeof s_un) != 0) { + close (agent->fd); + return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, + "failed connecting with agent"); + } + + return LIBSSH2_ERROR_NONE; +} + +static int +agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx) +{ + unsigned char buf[4]; + int rc; + + /* Send the length of the request */ + if (transctx->state == agent_NB_state_request_created) { + _libssh2_htonu32(buf, transctx->request_len); + rc = LIBSSH2_SEND_FD(agent->session, agent->fd, buf, sizeof buf, 0); + if (rc == -EAGAIN) + return LIBSSH2_ERROR_EAGAIN; + else if (rc < 0) + return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND, + "agent send failed"); + transctx->state = agent_NB_state_request_length_sent; + } + + /* Send the request body */ + if (transctx->state == agent_NB_state_request_length_sent) { + rc = LIBSSH2_SEND_FD(agent->session, agent->fd, transctx->request, + transctx->request_len, 0); + if (rc == -EAGAIN) + return LIBSSH2_ERROR_EAGAIN; + else if (rc < 0) + return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND, + "agent send failed"); + transctx->state = agent_NB_state_request_sent; + } + + /* Receive the length of a response */ + if (transctx->state == agent_NB_state_request_sent) { + rc = LIBSSH2_RECV_FD(agent->session, agent->fd, buf, sizeof buf, 0); + if (rc < 0) { + if (rc == -EAGAIN) + return LIBSSH2_ERROR_EAGAIN; + return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_RECV, + "agent recv failed"); + } + transctx->response_len = _libssh2_ntohu32(buf); + transctx->response = LIBSSH2_ALLOC(agent->session, + transctx->response_len); + if (!transctx->response) + return LIBSSH2_ERROR_ALLOC; + + transctx->state = agent_NB_state_response_length_received; + } + + /* Receive the response body */ + if (transctx->state == agent_NB_state_response_length_received) { + rc = LIBSSH2_RECV_FD(agent->session, agent->fd, transctx->response, + transctx->response_len, 0); + if (rc < 0) { + if (rc == -EAGAIN) + return LIBSSH2_ERROR_EAGAIN; + return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND, + "agent recv failed"); + } + transctx->state = agent_NB_state_response_received; + } + + return 0; +} + +static int +agent_disconnect_unix(LIBSSH2_AGENT *agent) +{ + int ret; + ret = close(agent->fd); + + if(ret == -1) + return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_DISCONNECT, + "failed closing the agent socket"); + return LIBSSH2_ERROR_NONE; +} + +struct agent_ops agent_ops_unix = { + agent_connect_unix, + agent_transact_unix, + agent_disconnect_unix +}; +#endif /* PF_UNIX */ + +#ifdef WIN32 +/* Code to talk to Pageant was taken from PuTTY. + * + * Portions copyright Robert de Bath, Joris van Rantwijk, Delian + * Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas + * Barry, Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, + * Markus Kuhn, Colin Watson, and CORE SDI S.A. + */ +#define PAGEANT_COPYDATA_ID 0x804e50ba /* random goop */ +#define PAGEANT_MAX_MSGLEN 8192 + +static int +agent_connect_pageant(LIBSSH2_AGENT *agent) +{ + HWND hwnd; + hwnd = FindWindow("Pageant", "Pageant"); + if (!hwnd) + return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, + "failed connecting agent"); + agent->fd = 0; /* Mark as the connection has been established */ + return LIBSSH2_ERROR_NONE; +} + +static int +agent_transact_pageant(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx) +{ + HWND hwnd; + char mapname[23]; + HANDLE filemap; + unsigned char *p; + unsigned char *p2; + int id; + COPYDATASTRUCT cds; + + if (!transctx || 4 + transctx->request_len > PAGEANT_MAX_MSGLEN) + return _libssh2_error(agent->session, LIBSSH2_ERROR_INVAL, + "illegal input"); + + hwnd = FindWindow("Pageant", "Pageant"); + if (!hwnd) + return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, + "found no pageant"); + + sprintf(mapname, "PageantRequest%08x", (unsigned)GetCurrentThreadId()); + filemap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, + 0, PAGEANT_MAX_MSGLEN, mapname); + + if (filemap == NULL || filemap == INVALID_HANDLE_VALUE) + return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, + "failed setting up pageant filemap"); + + p2 = p = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0); + if (p == NULL || p2 == NULL) { + CloseHandle(filemap); + return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, + "failed to open pageant filemap for writing"); + } + + _libssh2_store_str(&p2, (const char *)transctx->request, + transctx->request_len); + + cds.dwData = PAGEANT_COPYDATA_ID; + cds.cbData = 1 + strlen(mapname); + cds.lpData = mapname; + + id = SendMessage(hwnd, WM_COPYDATA, (WPARAM) NULL, (LPARAM) &cds); + if (id > 0) { + transctx->response_len = _libssh2_ntohu32(p); + if (transctx->response_len > PAGEANT_MAX_MSGLEN) { + UnmapViewOfFile(p); + CloseHandle(filemap); + return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, + "agent setup fail"); + } + transctx->response = LIBSSH2_ALLOC(agent->session, + transctx->response_len); + if (!transctx->response) { + UnmapViewOfFile(p); + CloseHandle(filemap); + return _libssh2_error(agent->session, LIBSSH2_ERROR_ALLOC, + "agent malloc"); + } + memcpy(transctx->response, p + 4, transctx->response_len); + } + + UnmapViewOfFile(p); + CloseHandle(filemap); + return 0; +} + +static int +agent_disconnect_pageant(LIBSSH2_AGENT *agent) +{ + agent->fd = LIBSSH2_INVALID_SOCKET; + return 0; +} + +struct agent_ops agent_ops_pageant = { + agent_connect_pageant, + agent_transact_pageant, + agent_disconnect_pageant +}; +#endif /* WIN32 */ + +static struct { + const char *name; + struct agent_ops *ops; +} supported_backends[] = { +#ifdef WIN32 + {"Pageant", &agent_ops_pageant}, +#endif /* WIN32 */ +#ifdef PF_UNIX + {"Unix", &agent_ops_unix}, +#endif /* PF_UNIX */ + {NULL, NULL} +}; + +static int +agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, + const unsigned char *data, size_t data_len, void **abstract) +{ + LIBSSH2_AGENT *agent = (LIBSSH2_AGENT *) (*abstract); + agent_transaction_ctx_t transctx = &agent->transctx; + struct agent_publickey *identity = agent->identity; + ssize_t len = 1 + 4 + identity->external.blob_len + 4 + data_len + 4; + ssize_t method_len; + unsigned char *s; + int rc; + + /* Create a request to sign the data */ + if (transctx->state == agent_NB_state_init) { + s = transctx->request = LIBSSH2_ALLOC(session, len); + if (!transctx->request) + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "out of memory"); + + *s++ = SSH2_AGENTC_SIGN_REQUEST; + /* key blob */ + _libssh2_store_str(&s, (const char *)identity->external.blob, + identity->external.blob_len); + /* data */ + _libssh2_store_str(&s, (const char *)data, data_len); + + /* flags */ + _libssh2_store_u32(&s, 0); + + transctx->request_len = s - transctx->request; + transctx->state = agent_NB_state_request_created; + } + + /* Make sure to be re-called as a result of EAGAIN. */ + if (*transctx->request != SSH2_AGENTC_SIGN_REQUEST) + return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE, + "illegal request"); + + if (!agent->ops) + /* if no agent has been connected, bail out */ + return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE, + "agent not connected"); + + rc = agent->ops->transact(agent, transctx); + if (rc) { + goto error; + } + LIBSSH2_FREE(session, transctx->request); + transctx->request = NULL; + + len = transctx->response_len; + s = transctx->response; + len--; + if (len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + if (*s != SSH2_AGENT_SIGN_RESPONSE) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + s++; + + /* Skip the entire length of the signature */ + len -= 4; + if (len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + s += 4; + + /* Skip signing method */ + len -= 4; + if (len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + method_len = _libssh2_ntohu32(s); + s += 4; + len -= method_len; + if (len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + s += method_len; + + /* Read the signature */ + len -= 4; + if (len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + *sig_len = _libssh2_ntohu32(s); + s += 4; + len -= *sig_len; + if (len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + + *sig = LIBSSH2_ALLOC(session, *sig_len); + if (!*sig) { + rc = LIBSSH2_ERROR_ALLOC; + goto error; + } + memcpy(*sig, s, *sig_len); + + error: + LIBSSH2_FREE(session, transctx->request); + transctx->request = NULL; + + LIBSSH2_FREE(session, transctx->response); + transctx->response = NULL; + + return _libssh2_error(session, rc, "agent sign failure"); +} + +static int +agent_list_identities(LIBSSH2_AGENT *agent) +{ + agent_transaction_ctx_t transctx = &agent->transctx; + ssize_t len, num_identities; + unsigned char *s; + int rc; + unsigned char c = SSH2_AGENTC_REQUEST_IDENTITIES; + + /* Create a request to list identities */ + if (transctx->state == agent_NB_state_init) { + transctx->request = &c; + transctx->request_len = 1; + transctx->state = agent_NB_state_request_created; + } + + /* Make sure to be re-called as a result of EAGAIN. */ + if (*transctx->request != SSH2_AGENTC_REQUEST_IDENTITIES) + return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_USE, + "illegal agent request"); + + if (!agent->ops) + /* if no agent has been connected, bail out */ + return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_USE, + "agent not connected"); + + rc = agent->ops->transact(agent, transctx); + if (rc) { + goto error; + } + transctx->request = NULL; + + len = transctx->response_len; + s = transctx->response; + len--; + if (len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + if (*s != SSH2_AGENT_IDENTITIES_ANSWER) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + s++; + + /* Read the length of identities */ + len -= 4; + if (len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + num_identities = _libssh2_ntohu32(s); + s += 4; + + while (num_identities--) { + struct agent_publickey *identity; + ssize_t comment_len; + + /* Read the length of the blob */ + len -= 4; + if (len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + identity = LIBSSH2_ALLOC(agent->session, sizeof *identity); + if (!identity) { + rc = LIBSSH2_ERROR_ALLOC; + goto error; + } + identity->external.blob_len = _libssh2_ntohu32(s); + s += 4; + + /* Read the blob */ + len -= identity->external.blob_len; + if (len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + LIBSSH2_FREE(agent->session, identity); + goto error; + } + + identity->external.blob = LIBSSH2_ALLOC(agent->session, + identity->external.blob_len); + if (!identity->external.blob) { + rc = LIBSSH2_ERROR_ALLOC; + LIBSSH2_FREE(agent->session, identity); + goto error; + } + memcpy(identity->external.blob, s, identity->external.blob_len); + s += identity->external.blob_len; + + /* Read the length of the comment */ + len -= 4; + if (len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + LIBSSH2_FREE(agent->session, identity->external.blob); + LIBSSH2_FREE(agent->session, identity); + goto error; + } + comment_len = _libssh2_ntohu32(s); + s += 4; + + /* Read the comment */ + len -= comment_len; + if (len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + LIBSSH2_FREE(agent->session, identity->external.blob); + LIBSSH2_FREE(agent->session, identity); + goto error; + } + + identity->external.comment = LIBSSH2_ALLOC(agent->session, + comment_len + 1); + if (!identity->external.comment) { + rc = LIBSSH2_ERROR_ALLOC; + LIBSSH2_FREE(agent->session, identity->external.blob); + LIBSSH2_FREE(agent->session, identity); + goto error; + } + identity->external.comment[comment_len] = '\0'; + memcpy(identity->external.comment, s, comment_len); + s += comment_len; + + _libssh2_list_add(&agent->head, &identity->node); + } + error: + LIBSSH2_FREE(agent->session, transctx->response); + transctx->response = NULL; + + return _libssh2_error(agent->session, rc, + "agent list id failed"); +} + +static void +agent_free_identities(LIBSSH2_AGENT *agent) { + struct agent_publickey *node; + struct agent_publickey *next; + + for (node = _libssh2_list_first(&agent->head); node; node = next) { + next = _libssh2_list_next(&node->node); + LIBSSH2_FREE(agent->session, node->external.blob); + LIBSSH2_FREE(agent->session, node->external.comment); + LIBSSH2_FREE(agent->session, node); + } + _libssh2_list_init(&agent->head); +} + +#define AGENT_PUBLICKEY_MAGIC 0x3bdefed2 +/* + * agent_publickey_to_external() + * + * Copies data from the internal to the external representation struct. + * + */ +static struct libssh2_agent_publickey * +agent_publickey_to_external(struct agent_publickey *node) +{ + struct libssh2_agent_publickey *ext = &node->external; + + ext->magic = AGENT_PUBLICKEY_MAGIC; + ext->node = node; + + return ext; +} + +/* + * libssh2_agent_init + * + * Init an ssh-agent handle. Returns the pointer to the handle. + * + */ +LIBSSH2_API LIBSSH2_AGENT * +libssh2_agent_init(LIBSSH2_SESSION *session) +{ + LIBSSH2_AGENT *agent; + + agent = LIBSSH2_CALLOC(session, sizeof *agent); + if (!agent) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate space for agent connection"); + return NULL; + } + agent->fd = LIBSSH2_INVALID_SOCKET; + agent->session = session; + _libssh2_list_init(&agent->head); + + return agent; +} + +/* + * libssh2_agent_connect() + * + * Connect to an ssh-agent. + * + * Returns 0 if succeeded, or a negative value for error. + */ +LIBSSH2_API int +libssh2_agent_connect(LIBSSH2_AGENT *agent) +{ + int i, rc = -1; + for (i = 0; supported_backends[i].name; i++) { + agent->ops = supported_backends[i].ops; + rc = agent->ops->connect(agent); + if (!rc) + return 0; + } + return rc; +} + +/* + * libssh2_agent_list_identities() + * + * Request ssh-agent to list identities. + * + * Returns 0 if succeeded, or a negative value for error. + */ +LIBSSH2_API int +libssh2_agent_list_identities(LIBSSH2_AGENT *agent) +{ + memset(&agent->transctx, 0, sizeof agent->transctx); + /* Abondon the last fetched identities */ + agent_free_identities(agent); + return agent_list_identities(agent); +} + +/* + * libssh2_agent_get_identity() + * + * Traverse the internal list of public keys. Pass NULL to 'prev' to get + * the first one. Or pass a pointer to the previously returned one to get the + * next. + * + * Returns: + * 0 if a fine public key was stored in 'store' + * 1 if end of public keys + * [negative] on errors + */ +LIBSSH2_API int +libssh2_agent_get_identity(LIBSSH2_AGENT *agent, + struct libssh2_agent_publickey **ext, + struct libssh2_agent_publickey *oprev) +{ + struct agent_publickey *node; + if (oprev && oprev->node) { + /* we have a starting point */ + struct agent_publickey *prev = oprev->node; + + /* get the next node in the list */ + node = _libssh2_list_next(&prev->node); + } + else + node = _libssh2_list_first(&agent->head); + + if (!node) + /* no (more) node */ + return 1; + + *ext = agent_publickey_to_external(node); + + return 0; +} + +/* + * libssh2_agent_userauth() + * + * Do publickey user authentication with the help of ssh-agent. + * + * Returns 0 if succeeded, or a negative value for error. + */ +LIBSSH2_API int +libssh2_agent_userauth(LIBSSH2_AGENT *agent, + const char *username, + struct libssh2_agent_publickey *identity) +{ + void *abstract = agent; + int rc; + + if (agent->session->userauth_pblc_state == libssh2_NB_state_idle) { + memset(&agent->transctx, 0, sizeof agent->transctx); + agent->identity = identity->node; + } + + BLOCK_ADJUST(rc, agent->session, + _libssh2_userauth_publickey(agent->session, username, + strlen(username), + identity->blob, + identity->blob_len, + agent_sign, + &abstract)); + return rc; +} + +/* + * libssh2_agent_disconnect() + * + * Close a connection to an ssh-agent. + * + * Returns 0 if succeeded, or a negative value for error. + */ +LIBSSH2_API int +libssh2_agent_disconnect(LIBSSH2_AGENT *agent) +{ + if (agent->ops && agent->fd != LIBSSH2_INVALID_SOCKET) + return agent->ops->disconnect(agent); + return 0; +} + +/* + * libssh2_agent_free() + * + * Free an ssh-agent handle. This function also frees the internal + * collection of public keys. + */ +LIBSSH2_API void +libssh2_agent_free(LIBSSH2_AGENT *agent) { + /* Allow connection freeing when the socket has lost its connection */ + if (agent->fd != LIBSSH2_INVALID_SOCKET) { + libssh2_agent_disconnect(agent); + } + agent_free_identities(agent); + LIBSSH2_FREE(agent->session, agent); +} diff --git a/libssh2/channel.c b/libssh2/channel.c new file mode 100644 index 0000000..32d914d --- /dev/null +++ b/libssh2/channel.c @@ -0,0 +1,2621 @@ +/* Copyright (c) 2004-2007 Sara Golemon + * Copyright (c) 2005 Mikhail Gusarov + * Copyright (c) 2008-2014 by Daniel Stenberg + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#ifdef HAVE_INTTYPES_H +#include +#endif +#include + +#include "channel.h" +#include "transport.h" +#include "packet.h" +#include "session.h" + +/* + * _libssh2_channel_nextid + * + * Determine the next channel ID we can use at our end + */ +uint32_t +_libssh2_channel_nextid(LIBSSH2_SESSION * session) +{ + uint32_t id = session->next_channel; + LIBSSH2_CHANNEL *channel; + + channel = _libssh2_list_first(&session->channels); + + while (channel) { + if (channel->local.id > id) { + id = channel->local.id; + } + channel = _libssh2_list_next(&channel->node); + } + + /* This is a shortcut to avoid waiting for close packets on channels we've + * forgotten about, This *could* be a problem if we request and close 4 + * billion or so channels in too rapid succession for the remote end to + * respond, but the worst case scenario is that some data meant for + * another channel Gets picked up by the new one.... Pretty unlikely all + * told... + */ + session->next_channel = id + 1; + _libssh2_debug(session, LIBSSH2_TRACE_CONN, "Allocated new channel ID#%lu", + id); + return id; +} + +/* + * _libssh2_channel_locate + * + * Locate a channel pointer by number + */ +LIBSSH2_CHANNEL * +_libssh2_channel_locate(LIBSSH2_SESSION *session, uint32_t channel_id) +{ + LIBSSH2_CHANNEL *channel; + LIBSSH2_LISTENER *l; + + for(channel = _libssh2_list_first(&session->channels); + channel; + channel = _libssh2_list_next(&channel->node)) { + if (channel->local.id == channel_id) + return channel; + } + + /* We didn't find the channel in the session, let's then check its + listeners since each listener may have its own set of pending channels + */ + for(l = _libssh2_list_first(&session->listeners); l; + l = _libssh2_list_next(&l->node)) { + for(channel = _libssh2_list_first(&l->queue); + channel; + channel = _libssh2_list_next(&channel->node)) { + if (channel->local.id == channel_id) + return channel; + } + } + + return NULL; +} + +/* + * _libssh2_channel_open + * + * Establish a generic session channel + */ +LIBSSH2_CHANNEL * +_libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type, + uint32_t channel_type_len, + uint32_t window_size, + uint32_t packet_size, + const unsigned char *message, + size_t message_len) +{ + static const unsigned char reply_codes[3] = { + SSH_MSG_CHANNEL_OPEN_CONFIRMATION, + SSH_MSG_CHANNEL_OPEN_FAILURE, + 0 + }; + unsigned char *s; + int rc; + + if (session->open_state == libssh2_NB_state_idle) { + session->open_channel = NULL; + session->open_packet = NULL; + session->open_data = NULL; + /* 17 = packet_type(1) + channel_type_len(4) + sender_channel(4) + + * window_size(4) + packet_size(4) */ + session->open_packet_len = channel_type_len + 17; + session->open_local_channel = _libssh2_channel_nextid(session); + + /* Zero the whole thing out */ + memset(&session->open_packet_requirev_state, 0, + sizeof(session->open_packet_requirev_state)); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Opening Channel - win %d pack %d", window_size, + packet_size); + session->open_channel = + LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL)); + if (!session->open_channel) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate space for channel data"); + return NULL; + } + session->open_channel->channel_type_len = channel_type_len; + session->open_channel->channel_type = + LIBSSH2_ALLOC(session, channel_type_len); + if (!session->open_channel->channel_type) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Failed allocating memory for channel type name"); + LIBSSH2_FREE(session, session->open_channel); + session->open_channel = NULL; + return NULL; + } + memcpy(session->open_channel->channel_type, channel_type, + channel_type_len); + + /* REMEMBER: local as in locally sourced */ + session->open_channel->local.id = session->open_local_channel; + session->open_channel->remote.window_size = window_size; + session->open_channel->remote.window_size_initial = window_size; + session->open_channel->remote.packet_size = packet_size; + session->open_channel->session = session; + + _libssh2_list_add(&session->channels, + &session->open_channel->node); + + s = session->open_packet = + LIBSSH2_ALLOC(session, session->open_packet_len); + if (!session->open_packet) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate temporary space for packet"); + goto channel_error; + } + *(s++) = SSH_MSG_CHANNEL_OPEN; + _libssh2_store_str(&s, channel_type, channel_type_len); + _libssh2_store_u32(&s, session->open_local_channel); + _libssh2_store_u32(&s, window_size); + _libssh2_store_u32(&s, packet_size); + + /* Do not copy the message */ + + session->open_state = libssh2_NB_state_created; + } + + if (session->open_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, + session->open_packet, + session->open_packet_len, + message, message_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, rc, + "Would block sending channel-open request"); + return NULL; + } + else if (rc) { + _libssh2_error(session, rc, + "Unable to send channel-open request"); + goto channel_error; + } + + session->open_state = libssh2_NB_state_sent; + } + + if (session->open_state == libssh2_NB_state_sent) { + rc = _libssh2_packet_requirev(session, reply_codes, + &session->open_data, + &session->open_data_len, 1, + session->open_packet + 5 + + channel_type_len, 4, + &session->open_packet_requirev_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); + return NULL; + } else if (rc) { + goto channel_error; + } + + if (session->open_data[0] == SSH_MSG_CHANNEL_OPEN_CONFIRMATION) { + session->open_channel->remote.id = + _libssh2_ntohu32(session->open_data + 5); + session->open_channel->local.window_size = + _libssh2_ntohu32(session->open_data + 9); + session->open_channel->local.window_size_initial = + _libssh2_ntohu32(session->open_data + 9); + session->open_channel->local.packet_size = + _libssh2_ntohu32(session->open_data + 13); + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Connection Established - ID: %lu/%lu win: %lu/%lu" + " pack: %lu/%lu", + session->open_channel->local.id, + session->open_channel->remote.id, + session->open_channel->local.window_size, + session->open_channel->remote.window_size, + session->open_channel->local.packet_size, + session->open_channel->remote.packet_size); + LIBSSH2_FREE(session, session->open_packet); + session->open_packet = NULL; + LIBSSH2_FREE(session, session->open_data); + session->open_data = NULL; + + session->open_state = libssh2_NB_state_idle; + return session->open_channel; + } + + if (session->open_data[0] == SSH_MSG_CHANNEL_OPEN_FAILURE) { + unsigned int reason_code = _libssh2_ntohu32(session->open_data + 5); + switch (reason_code) { + case SSH_OPEN_ADMINISTRATIVELY_PROHIBITED: + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Channel open failure (admininstratively prohibited)"); + break; + case SSH_OPEN_CONNECT_FAILED: + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Channel open failure (connect failed)"); + break; + case SSH_OPEN_UNKNOWN_CHANNELTYPE: + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Channel open failure (unknown channel type)"); + break; + case SSH_OPEN_RESOURCE_SHORTAGE: + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Channel open failure (resource shortage)"); + break; + default: + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Channel open failure"); + } + } + } + + channel_error: + + if (session->open_data) { + LIBSSH2_FREE(session, session->open_data); + session->open_data = NULL; + } + if (session->open_packet) { + LIBSSH2_FREE(session, session->open_packet); + session->open_packet = NULL; + } + if (session->open_channel) { + unsigned char channel_id[4]; + LIBSSH2_FREE(session, session->open_channel->channel_type); + + _libssh2_list_remove(&session->open_channel->node); + + /* Clear out packets meant for this channel */ + _libssh2_htonu32(channel_id, session->open_channel->local.id); + while ((_libssh2_packet_ask(session, SSH_MSG_CHANNEL_DATA, + &session->open_data, + &session->open_data_len, 1, + channel_id, 4) >= 0) + || + (_libssh2_packet_ask(session, SSH_MSG_CHANNEL_EXTENDED_DATA, + &session->open_data, + &session->open_data_len, 1, + channel_id, 4) >= 0)) { + LIBSSH2_FREE(session, session->open_data); + session->open_data = NULL; + } + + LIBSSH2_FREE(session, session->open_channel); + session->open_channel = NULL; + } + + session->open_state = libssh2_NB_state_idle; + return NULL; +} + +/* + * libssh2_channel_open_ex + * + * Establish a generic session channel + */ +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_channel_open_ex(LIBSSH2_SESSION *session, const char *type, + unsigned int type_len, + unsigned int window_size, unsigned int packet_size, + const char *msg, unsigned int msg_len) +{ + LIBSSH2_CHANNEL *ptr; + + if(!session) + return NULL; + + BLOCK_ADJUST_ERRNO(ptr, session, + _libssh2_channel_open(session, type, type_len, + window_size, packet_size, + (unsigned char *)msg, + msg_len)); + return ptr; +} + +/* + * libssh2_channel_direct_tcpip_ex + * + * Tunnel TCP/IP connect through the SSH session to direct host/port + */ +static LIBSSH2_CHANNEL * +channel_direct_tcpip(LIBSSH2_SESSION * session, const char *host, + int port, const char *shost, int sport) +{ + LIBSSH2_CHANNEL *channel; + unsigned char *s; + + if (session->direct_state == libssh2_NB_state_idle) { + session->direct_host_len = strlen(host); + session->direct_shost_len = strlen(shost); + /* host_len(4) + port(4) + shost_len(4) + sport(4) */ + session->direct_message_len = + session->direct_host_len + session->direct_shost_len + 16; + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Requesting direct-tcpip session to from %s:%d to %s:%d", + shost, sport, host, port); + + s = session->direct_message = + LIBSSH2_ALLOC(session, session->direct_message_len); + if (!session->direct_message) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for direct-tcpip connection"); + return NULL; + } + _libssh2_store_str(&s, host, session->direct_host_len); + _libssh2_store_u32(&s, port); + _libssh2_store_str(&s, shost, session->direct_shost_len); + _libssh2_store_u32(&s, sport); + } + + channel = + _libssh2_channel_open(session, "direct-tcpip", + sizeof("direct-tcpip") - 1, + LIBSSH2_CHANNEL_WINDOW_DEFAULT, + LIBSSH2_CHANNEL_PACKET_DEFAULT, + session->direct_message, + session->direct_message_len); + + if (!channel && + libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) { + /* The error code is still set to LIBSSH2_ERROR_EAGAIN, set our state + to created to avoid re-creating the package on next invoke */ + session->direct_state = libssh2_NB_state_created; + return NULL; + } + /* by default we set (keep?) idle state... */ + session->direct_state = libssh2_NB_state_idle; + + LIBSSH2_FREE(session, session->direct_message); + session->direct_message = NULL; + + return channel; +} + +/* + * libssh2_channel_direct_tcpip_ex + * + * Tunnel TCP/IP connect through the SSH session to direct host/port + */ +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, const char *host, + int port, const char *shost, int sport) +{ + LIBSSH2_CHANNEL *ptr; + + if(!session) + return NULL; + + BLOCK_ADJUST_ERRNO(ptr, session, + channel_direct_tcpip(session, host, port, shost, sport)); + return ptr; +} + +/* + * channel_forward_listen + * + * Bind a port on the remote host and listen for connections + */ +static LIBSSH2_LISTENER * +channel_forward_listen(LIBSSH2_SESSION * session, const char *host, + int port, int *bound_port, int queue_maxsize) +{ + unsigned char *s; + static const unsigned char reply_codes[3] = + { SSH_MSG_REQUEST_SUCCESS, SSH_MSG_REQUEST_FAILURE, 0 }; + int rc; + + if(!host) + host = "0.0.0.0"; + + if (session->fwdLstn_state == libssh2_NB_state_idle) { + session->fwdLstn_host_len = strlen(host); + /* 14 = packet_type(1) + request_len(4) + want_replay(1) + host_len(4) + + port(4) */ + session->fwdLstn_packet_len = + session->fwdLstn_host_len + (sizeof("tcpip-forward") - 1) + 14; + + /* Zero the whole thing out */ + memset(&session->fwdLstn_packet_requirev_state, 0, + sizeof(session->fwdLstn_packet_requirev_state)); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Requesting tcpip-forward session for %s:%d", host, + port); + + s = session->fwdLstn_packet = + LIBSSH2_ALLOC(session, session->fwdLstn_packet_len); + if (!session->fwdLstn_packet) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for setenv packet"); + return NULL; + } + + *(s++) = SSH_MSG_GLOBAL_REQUEST; + _libssh2_store_str(&s, "tcpip-forward", sizeof("tcpip-forward") - 1); + *(s++) = 0x01; /* want_reply */ + + _libssh2_store_str(&s, host, session->fwdLstn_host_len); + _libssh2_store_u32(&s, port); + + session->fwdLstn_state = libssh2_NB_state_created; + } + + if (session->fwdLstn_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, + session->fwdLstn_packet, + session->fwdLstn_packet_len, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending global-request packet for " + "forward listen request"); + return NULL; + } + else if (rc) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send global-request packet for forward " + "listen request"); + LIBSSH2_FREE(session, session->fwdLstn_packet); + session->fwdLstn_packet = NULL; + session->fwdLstn_state = libssh2_NB_state_idle; + return NULL; + } + LIBSSH2_FREE(session, session->fwdLstn_packet); + session->fwdLstn_packet = NULL; + + session->fwdLstn_state = libssh2_NB_state_sent; + } + + if (session->fwdLstn_state == libssh2_NB_state_sent) { + unsigned char *data; + size_t data_len; + rc = _libssh2_packet_requirev(session, reply_codes, &data, &data_len, + 0, NULL, 0, + &session->fwdLstn_packet_requirev_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); + return NULL; + } else if (rc) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unknown"); + session->fwdLstn_state = libssh2_NB_state_idle; + return NULL; + } + + if (data[0] == SSH_MSG_REQUEST_SUCCESS) { + LIBSSH2_LISTENER *listener; + + listener = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_LISTENER)); + if (!listener) + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for listener queue"); + else { + listener->host = + LIBSSH2_ALLOC(session, session->fwdLstn_host_len + 1); + if (!listener->host) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for listener queue"); + LIBSSH2_FREE(session, listener); + listener = NULL; + } + else { + listener->session = session; + memcpy(listener->host, host, session->fwdLstn_host_len); + listener->host[session->fwdLstn_host_len] = 0; + if (data_len >= 5 && !port) { + listener->port = _libssh2_ntohu32(data + 1); + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Dynamic tcpip-forward port allocated: %d", + listener->port); + } + else + listener->port = port; + + listener->queue_size = 0; + listener->queue_maxsize = queue_maxsize; + + /* append this to the parent's list of listeners */ + _libssh2_list_add(&session->listeners, &listener->node); + + if (bound_port) { + *bound_port = listener->port; + } + } + } + + LIBSSH2_FREE(session, data); + session->fwdLstn_state = libssh2_NB_state_idle; + return listener; + } + else if (data[0] == SSH_MSG_REQUEST_FAILURE) { + LIBSSH2_FREE(session, data); + _libssh2_error(session, LIBSSH2_ERROR_REQUEST_DENIED, + "Unable to complete request for forward-listen"); + session->fwdLstn_state = libssh2_NB_state_idle; + return NULL; + } + } + + session->fwdLstn_state = libssh2_NB_state_idle; + + return NULL; +} + +/* + * libssh2_channel_forward_listen_ex + * + * Bind a port on the remote host and listen for connections + */ +LIBSSH2_API LIBSSH2_LISTENER * +libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, const char *host, + int port, int *bound_port, int queue_maxsize) +{ + LIBSSH2_LISTENER *ptr; + + if(!session) + return NULL; + + BLOCK_ADJUST_ERRNO(ptr, session, + channel_forward_listen(session, host, port, bound_port, + queue_maxsize)); + return ptr; +} + +/* + * _libssh2_channel_forward_cancel + * + * Stop listening on a remote port and free the listener + * Toss out any pending (un-accept()ed) connections + * + * Return 0 on success, LIBSSH2_ERROR_EAGAIN if would block, -1 on error + */ +int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener) +{ + LIBSSH2_SESSION *session = listener->session; + LIBSSH2_CHANNEL *queued; + unsigned char *packet, *s; + size_t host_len = strlen(listener->host); + /* 14 = packet_type(1) + request_len(4) + want_replay(1) + host_len(4) + + port(4) */ + size_t packet_len = + host_len + 14 + sizeof("cancel-tcpip-forward") - 1; + int rc; + int retcode = 0; + + if (listener->chanFwdCncl_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Cancelling tcpip-forward session for %s:%d", + listener->host, listener->port); + + s = packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for setenv packet"); + return LIBSSH2_ERROR_ALLOC; + } + + *(s++) = SSH_MSG_GLOBAL_REQUEST; + _libssh2_store_str(&s, "cancel-tcpip-forward", + sizeof("cancel-tcpip-forward") - 1); + *(s++) = 0x00; /* want_reply */ + + _libssh2_store_str(&s, listener->host, host_len); + _libssh2_store_u32(&s, listener->port); + + listener->chanFwdCncl_state = libssh2_NB_state_created; + } else { + packet = listener->chanFwdCncl_data; + } + + if (listener->chanFwdCncl_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, packet, packet_len, NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, rc, + "Would block sending forward request"); + listener->chanFwdCncl_data = packet; + return rc; + } + else if (rc) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send global-request packet for forward " + "listen request"); + /* set the state to something we don't check for, for the + unfortunate situation where we get an EAGAIN further down + when trying to bail out due to errors! */ + listener->chanFwdCncl_state = libssh2_NB_state_sent; + retcode = LIBSSH2_ERROR_SOCKET_SEND; + } + LIBSSH2_FREE(session, packet); + + listener->chanFwdCncl_state = libssh2_NB_state_sent; + } + + queued = _libssh2_list_first(&listener->queue); + while (queued) { + LIBSSH2_CHANNEL *next = _libssh2_list_next(&queued->node); + + rc = _libssh2_channel_free(queued); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + queued = next; + } + LIBSSH2_FREE(session, listener->host); + + /* remove this entry from the parent's list of listeners */ + _libssh2_list_remove(&listener->node); + + LIBSSH2_FREE(session, listener); + + return retcode; +} + +/* + * libssh2_channel_forward_cancel + * + * Stop listening on a remote port and free the listener + * Toss out any pending (un-accept()ed) connections + * + * Return 0 on success, LIBSSH2_ERROR_EAGAIN if would block, -1 on error + */ +LIBSSH2_API int +libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener) +{ + int rc; + + if(!listener) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, listener->session, + _libssh2_channel_forward_cancel(listener)); + return rc; +} + +/* + * channel_forward_accept + * + * Accept a connection + */ +static LIBSSH2_CHANNEL * +channel_forward_accept(LIBSSH2_LISTENER *listener) +{ + int rc; + + do { + rc = _libssh2_transport_read(listener->session); + } while (rc > 0); + + if (_libssh2_list_first(&listener->queue)) { + LIBSSH2_CHANNEL *channel = _libssh2_list_first(&listener->queue); + + /* detach channel from listener's queue */ + _libssh2_list_remove(&channel->node); + + listener->queue_size--; + + /* add channel to session's channel list */ + _libssh2_list_add(&channel->session->channels, &channel->node); + + return channel; + } + + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(listener->session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for packet"); + } + else + _libssh2_error(listener->session, LIBSSH2_ERROR_CHANNEL_UNKNOWN, + "Channel not found"); + return NULL; +} + +/* + * libssh2_channel_forward_accept + * + * Accept a connection + */ +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_channel_forward_accept(LIBSSH2_LISTENER *listener) +{ + LIBSSH2_CHANNEL *ptr; + + if(!listener) + return NULL; + + BLOCK_ADJUST_ERRNO(ptr, listener->session, + channel_forward_accept(listener)); + return ptr; + +} + +/* + * channel_setenv + * + * Set an environment variable prior to requesting a shell/program/subsystem + */ +static int channel_setenv(LIBSSH2_CHANNEL *channel, + const char *varname, unsigned int varname_len, + const char *value, unsigned int value_len) +{ + LIBSSH2_SESSION *session = channel->session; + unsigned char *s, *data; + static const unsigned char reply_codes[3] = + { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; + size_t data_len; + int rc; + + if (channel->setenv_state == libssh2_NB_state_idle) { + /* 21 = packet_type(1) + channel_id(4) + request_len(4) + + * request(3)"env" + want_reply(1) + varname_len(4) + value_len(4) */ + channel->setenv_packet_len = varname_len + value_len + 21; + + /* Zero the whole thing out */ + memset(&channel->setenv_packet_requirev_state, 0, + sizeof(channel->setenv_packet_requirev_state)); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Setting remote environment variable: %s=%s on " + "channel %lu/%lu", + varname, value, channel->local.id, channel->remote.id); + + s = channel->setenv_packet = + LIBSSH2_ALLOC(session, channel->setenv_packet_len); + if (!channel->setenv_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory " + "for setenv packet"); + } + + *(s++) = SSH_MSG_CHANNEL_REQUEST; + _libssh2_store_u32(&s, channel->remote.id); + _libssh2_store_str(&s, "env", sizeof("env") - 1); + *(s++) = 0x01; + _libssh2_store_str(&s, varname, varname_len); + _libssh2_store_str(&s, value, value_len); + + channel->setenv_state = libssh2_NB_state_created; + } + + if (channel->setenv_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, + channel->setenv_packet, + channel->setenv_packet_len, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, rc, + "Would block sending setenv request"); + return rc; + } else if (rc) { + LIBSSH2_FREE(session, channel->setenv_packet); + channel->setenv_packet = NULL; + channel->setenv_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send channel-request packet for " + "setenv request"); + } + LIBSSH2_FREE(session, channel->setenv_packet); + channel->setenv_packet = NULL; + + _libssh2_htonu32(channel->setenv_local_channel, channel->local.id); + + channel->setenv_state = libssh2_NB_state_sent; + } + + if (channel->setenv_state == libssh2_NB_state_sent) { + rc = _libssh2_packet_requirev(session, reply_codes, &data, &data_len, + 1, channel->setenv_local_channel, 4, + &channel-> + setenv_packet_requirev_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + if (rc) { + channel->setenv_state = libssh2_NB_state_idle; + return rc; + } + + if (data[0] == SSH_MSG_CHANNEL_SUCCESS) { + LIBSSH2_FREE(session, data); + channel->setenv_state = libssh2_NB_state_idle; + return 0; + } + + LIBSSH2_FREE(session, data); + } + + channel->setenv_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, + "Unable to complete request for channel-setenv"); +} + +/* + * libssh2_channel_setenv_ex + * + * Set an environment variable prior to requesting a shell/program/subsystem + */ +LIBSSH2_API int +libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, + const char *varname, unsigned int varname_len, + const char *value, unsigned int value_len) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, + channel_setenv(channel, varname, varname_len, + value, value_len)); + return rc; +} + +/* + * channel_request_pty + * Duh... Request a PTY + */ +static int channel_request_pty(LIBSSH2_CHANNEL *channel, + const char *term, unsigned int term_len, + const char *modes, unsigned int modes_len, + int width, int height, + int width_px, int height_px) +{ + LIBSSH2_SESSION *session = channel->session; + unsigned char *s; + static const unsigned char reply_codes[3] = + { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; + int rc; + + if (channel->reqPTY_state == libssh2_NB_state_idle) { + /* 41 = packet_type(1) + channel(4) + pty_req_len(4) + "pty_req"(7) + + * want_reply(1) + term_len(4) + width(4) + height(4) + width_px(4) + + * height_px(4) + modes_len(4) */ + if(term_len + modes_len > 256) { + return _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "term + mode lengths too large"); + } + + channel->reqPTY_packet_len = term_len + modes_len + 41; + + /* Zero the whole thing out */ + memset(&channel->reqPTY_packet_requirev_state, 0, + sizeof(channel->reqPTY_packet_requirev_state)); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Allocating tty on channel %lu/%lu", channel->local.id, + channel->remote.id); + + s = channel->reqPTY_packet; + + *(s++) = SSH_MSG_CHANNEL_REQUEST; + _libssh2_store_u32(&s, channel->remote.id); + _libssh2_store_str(&s, (char *)"pty-req", sizeof("pty-req") - 1); + + *(s++) = 0x01; + + _libssh2_store_str(&s, term, term_len); + _libssh2_store_u32(&s, width); + _libssh2_store_u32(&s, height); + _libssh2_store_u32(&s, width_px); + _libssh2_store_u32(&s, height_px); + _libssh2_store_str(&s, modes, modes_len); + + channel->reqPTY_state = libssh2_NB_state_created; + } + + if (channel->reqPTY_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, channel->reqPTY_packet, + channel->reqPTY_packet_len, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, rc, + "Would block sending pty request"); + return rc; + } else if (rc) { + channel->reqPTY_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Unable to send pty-request packet"); + } + _libssh2_htonu32(channel->reqPTY_local_channel, channel->local.id); + + channel->reqPTY_state = libssh2_NB_state_sent; + } + + if (channel->reqPTY_state == libssh2_NB_state_sent) { + unsigned char *data; + size_t data_len; + unsigned char code; + rc = _libssh2_packet_requirev(session, reply_codes, &data, &data_len, + 1, channel->reqPTY_local_channel, 4, + &channel->reqPTY_packet_requirev_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + channel->reqPTY_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Failed to require the PTY package"); + } + + code = data[0]; + + LIBSSH2_FREE(session, data); + channel->reqPTY_state = libssh2_NB_state_idle; + + if (code == SSH_MSG_CHANNEL_SUCCESS) + return 0; + } + + return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, + "Unable to complete request for channel request-pty"); +} + +/* + * libssh2_channel_request_pty_ex + * Duh... Request a PTY + */ +LIBSSH2_API int +libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, const char *term, + unsigned int term_len, const char *modes, + unsigned int modes_len, int width, int height, + int width_px, int height_px) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, + channel_request_pty(channel, term, term_len, modes, + modes_len, width, height, + width_px, height_px)); + return rc; +} + +static int +channel_request_pty_size(LIBSSH2_CHANNEL * channel, int width, + int height, int width_px, int height_px) +{ + LIBSSH2_SESSION *session = channel->session; + unsigned char *s; + int rc; + int retcode = LIBSSH2_ERROR_PROTO; + + if (channel->reqPTY_state == libssh2_NB_state_idle) { + channel->reqPTY_packet_len = 39; + + /* Zero the whole thing out */ + memset(&channel->reqPTY_packet_requirev_state, 0, + sizeof(channel->reqPTY_packet_requirev_state)); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "changing tty size on channel %lu/%lu", + channel->local.id, + channel->remote.id); + + s = channel->reqPTY_packet; + + *(s++) = SSH_MSG_CHANNEL_REQUEST; + _libssh2_store_u32(&s, channel->remote.id); + _libssh2_store_str(&s, (char *)"window-change", + sizeof("window-change") - 1); + *(s++) = 0x00; /* Don't reply */ + _libssh2_store_u32(&s, width); + _libssh2_store_u32(&s, height); + _libssh2_store_u32(&s, width_px); + _libssh2_store_u32(&s, height_px); + + channel->reqPTY_state = libssh2_NB_state_created; + } + + if (channel->reqPTY_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, channel->reqPTY_packet, + channel->reqPTY_packet_len, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, rc, + "Would block sending window-change request"); + return rc; + } else if (rc) { + channel->reqPTY_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Unable to send window-change packet"); + } + _libssh2_htonu32(channel->reqPTY_local_channel, channel->local.id); + retcode = LIBSSH2_ERROR_NONE; + } + + channel->reqPTY_state = libssh2_NB_state_idle; + return retcode; +} + +LIBSSH2_API int +libssh2_channel_request_pty_size_ex(LIBSSH2_CHANNEL *channel, int width, + int height, int width_px, int height_px) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, + channel_request_pty_size(channel, width, height, width_px, + height_px)); + return rc; +} + +/* Keep this an even number */ +#define LIBSSH2_X11_RANDOM_COOKIE_LEN 32 + +/* + * channel_x11_req + * Request X11 forwarding + */ +static int +channel_x11_req(LIBSSH2_CHANNEL *channel, int single_connection, + const char *auth_proto, const char *auth_cookie, + int screen_number) +{ + LIBSSH2_SESSION *session = channel->session; + unsigned char *s; + static const unsigned char reply_codes[3] = + { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; + size_t proto_len = + auth_proto ? strlen(auth_proto) : (sizeof("MIT-MAGIC-COOKIE-1") - 1); + size_t cookie_len = + auth_cookie ? strlen(auth_cookie) : LIBSSH2_X11_RANDOM_COOKIE_LEN; + int rc; + + if (channel->reqX11_state == libssh2_NB_state_idle) { + /* 30 = packet_type(1) + channel(4) + x11_req_len(4) + "x11-req"(7) + + * want_reply(1) + single_cnx(1) + proto_len(4) + cookie_len(4) + + * screen_num(4) */ + channel->reqX11_packet_len = proto_len + cookie_len + 30; + + /* Zero the whole thing out */ + memset(&channel->reqX11_packet_requirev_state, 0, + sizeof(channel->reqX11_packet_requirev_state)); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Requesting x11-req for channel %lu/%lu: single=%d " + "proto=%s cookie=%s screen=%d", + channel->local.id, channel->remote.id, + single_connection, + auth_proto ? auth_proto : "MIT-MAGIC-COOKIE-1", + auth_cookie ? auth_cookie : "", screen_number); + + s = channel->reqX11_packet = + LIBSSH2_ALLOC(session, channel->reqX11_packet_len); + if (!channel->reqX11_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for pty-request"); + } + + *(s++) = SSH_MSG_CHANNEL_REQUEST; + _libssh2_store_u32(&s, channel->remote.id); + _libssh2_store_str(&s, "x11-req", sizeof("x11-req") - 1); + + *(s++) = 0x01; /* want_reply */ + *(s++) = single_connection ? 0x01 : 0x00; + + _libssh2_store_str(&s, auth_proto?auth_proto:"MIT-MAGIC-COOKIE-1", + proto_len); + + _libssh2_store_u32(&s, cookie_len); + if (auth_cookie) { + memcpy(s, auth_cookie, cookie_len); + } else { + int i; + /* note: the extra +1 below is necessary since the sprintf() + loop will always write 3 bytes so the last one will write + the trailing zero at the LIBSSH2_X11_RANDOM_COOKIE_LEN/2 + border */ + unsigned char buffer[(LIBSSH2_X11_RANDOM_COOKIE_LEN / 2) +1]; + + _libssh2_random(buffer, LIBSSH2_X11_RANDOM_COOKIE_LEN / 2); + for(i = 0; i < (LIBSSH2_X11_RANDOM_COOKIE_LEN / 2); i++) { + sprintf((char *)&s[i*2], "%02X", buffer[i]); + } + } + s += cookie_len; + + _libssh2_store_u32(&s, screen_number); + channel->reqX11_state = libssh2_NB_state_created; + } + + if (channel->reqX11_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, channel->reqX11_packet, + channel->reqX11_packet_len, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, rc, + "Would block sending X11-req packet"); + return rc; + } + if (rc) { + LIBSSH2_FREE(session, channel->reqX11_packet); + channel->reqX11_packet = NULL; + channel->reqX11_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Unable to send x11-req packet"); + } + LIBSSH2_FREE(session, channel->reqX11_packet); + channel->reqX11_packet = NULL; + + _libssh2_htonu32(channel->reqX11_local_channel, channel->local.id); + + channel->reqX11_state = libssh2_NB_state_sent; + } + + if (channel->reqX11_state == libssh2_NB_state_sent) { + size_t data_len; + unsigned char *data; + unsigned char code; + + rc = _libssh2_packet_requirev(session, reply_codes, &data, &data_len, + 1, channel->reqX11_local_channel, 4, + &channel->reqX11_packet_requirev_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + channel->reqX11_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "waiting for x11-req response packet"); + } + + code = data[0]; + LIBSSH2_FREE(session, data); + channel->reqX11_state = libssh2_NB_state_idle; + + if (code == SSH_MSG_CHANNEL_SUCCESS) + return 0; + } + + return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, + "Unable to complete request for channel x11-req"); +} + +/* + * libssh2_channel_x11_req_ex + * Request X11 forwarding + */ +LIBSSH2_API int +libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_connection, + const char *auth_proto, const char *auth_cookie, + int screen_number) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, + channel_x11_req(channel, single_connection, auth_proto, + auth_cookie, screen_number)); + return rc; +} + + +/* + * _libssh2_channel_process_startup + * + * Primitive for libssh2_channel_(shell|exec|subsystem) + */ +int +_libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, + const char *request, size_t request_len, + const char *message, size_t message_len) +{ + LIBSSH2_SESSION *session = channel->session; + unsigned char *s; + static const unsigned char reply_codes[3] = + { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; + int rc; + + if (channel->process_state == libssh2_NB_state_end) { + return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE, + "Channel can not be reused"); + } + + if (channel->process_state == libssh2_NB_state_idle) { + /* 10 = packet_type(1) + channel(4) + request_len(4) + want_reply(1) */ + channel->process_packet_len = request_len + 10; + + /* Zero the whole thing out */ + memset(&channel->process_packet_requirev_state, 0, + sizeof(channel->process_packet_requirev_state)); + + if (message) + channel->process_packet_len += + 4; + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "starting request(%s) on channel %lu/%lu, message=%s", + request, channel->local.id, channel->remote.id, + message?message:""); + s = channel->process_packet = + LIBSSH2_ALLOC(session, channel->process_packet_len); + if (!channel->process_packet) + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory " + "for channel-process request"); + + *(s++) = SSH_MSG_CHANNEL_REQUEST; + _libssh2_store_u32(&s, channel->remote.id); + _libssh2_store_str(&s, request, request_len); + *(s++) = 0x01; + + if (message) + _libssh2_store_u32(&s, message_len); + + channel->process_state = libssh2_NB_state_created; + } + + if (channel->process_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, + channel->process_packet, + channel->process_packet_len, + (unsigned char *)message, message_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, rc, + "Would block sending channel request"); + return rc; + } + else if (rc) { + LIBSSH2_FREE(session, channel->process_packet); + channel->process_packet = NULL; + channel->process_state = libssh2_NB_state_end; + return _libssh2_error(session, rc, + "Unable to send channel request"); + } + LIBSSH2_FREE(session, channel->process_packet); + channel->process_packet = NULL; + + _libssh2_htonu32(channel->process_local_channel, channel->local.id); + + channel->process_state = libssh2_NB_state_sent; + } + + if (channel->process_state == libssh2_NB_state_sent) { + unsigned char *data; + size_t data_len; + unsigned char code; + rc = _libssh2_packet_requirev(session, reply_codes, &data, &data_len, + 1, channel->process_local_channel, 4, + &channel->process_packet_requirev_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + channel->process_state = libssh2_NB_state_end; + return _libssh2_error(session, rc, + "Failed waiting for channel success"); + } + + code = data[0]; + LIBSSH2_FREE(session, data); + channel->process_state = libssh2_NB_state_end; + + if (code == SSH_MSG_CHANNEL_SUCCESS) + return 0; + } + + return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, + "Unable to complete request for " + "channel-process-startup"); +} + +/* + * libssh2_channel_process_startup + * + * Primitive for libssh2_channel_(shell|exec|subsystem) + */ +LIBSSH2_API int +libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, + const char *req, unsigned int req_len, + const char *msg, unsigned int msg_len) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, + _libssh2_channel_process_startup(channel, req, req_len, + msg, msg_len)); + return rc; +} + + +/* + * libssh2_channel_set_blocking + * + * Set a channel's BEHAVIOR blocking on or off. The socket will remain non- + * blocking. + */ +LIBSSH2_API void +libssh2_channel_set_blocking(LIBSSH2_CHANNEL * channel, int blocking) +{ + if(channel) + (void) _libssh2_session_set_blocking(channel->session, blocking); +} + +/* + * _libssh2_channel_flush + * + * Flush data from one (or all) stream + * Returns number of bytes flushed, or negative on failure + */ +int +_libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid) +{ + if (channel->flush_state == libssh2_NB_state_idle) { + LIBSSH2_PACKET *packet = + _libssh2_list_first(&channel->session->packets); + channel->flush_refund_bytes = 0; + channel->flush_flush_bytes = 0; + + while (packet) { + LIBSSH2_PACKET *next = _libssh2_list_next(&packet->node); + unsigned char packet_type = packet->data[0]; + + if (((packet_type == SSH_MSG_CHANNEL_DATA) + || (packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA)) + && (_libssh2_ntohu32(packet->data + 1) == channel->local.id)) { + /* It's our channel at least */ + long packet_stream_id = + (packet_type == SSH_MSG_CHANNEL_DATA) ? 0 : + _libssh2_ntohu32(packet->data + 5); + if ((streamid == LIBSSH2_CHANNEL_FLUSH_ALL) + || ((packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA) + && ((streamid == LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA) + || (streamid == packet_stream_id))) + || ((packet_type == SSH_MSG_CHANNEL_DATA) + && (streamid == 0))) { + int bytes_to_flush = packet->data_len - packet->data_head; + + _libssh2_debug(channel->session, LIBSSH2_TRACE_CONN, + "Flushing %d bytes of data from stream " + "%lu on channel %lu/%lu", + bytes_to_flush, packet_stream_id, + channel->local.id, channel->remote.id); + + /* It's one of the streams we wanted to flush */ + channel->flush_refund_bytes += packet->data_len - 13; + channel->flush_flush_bytes += bytes_to_flush; + + LIBSSH2_FREE(channel->session, packet->data); + + /* remove this packet from the parent's list */ + _libssh2_list_remove(&packet->node); + LIBSSH2_FREE(channel->session, packet); + } + } + packet = next; + } + + channel->flush_state = libssh2_NB_state_created; + } + + channel->read_avail -= channel->flush_flush_bytes; + channel->remote.window_size -= channel->flush_flush_bytes; + + if (channel->flush_refund_bytes) { + int rc; + + rc = _libssh2_channel_receive_window_adjust(channel, + channel->flush_refund_bytes, + 1, NULL); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + } + + channel->flush_state = libssh2_NB_state_idle; + + return channel->flush_flush_bytes; +} + +/* + * libssh2_channel_flush_ex + * + * Flush data from one (or all) stream + * Returns number of bytes flushed, or negative on failure + */ +LIBSSH2_API int +libssh2_channel_flush_ex(LIBSSH2_CHANNEL *channel, int stream) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, + _libssh2_channel_flush(channel, stream)); + return rc; +} + +/* + * libssh2_channel_get_exit_status + * + * Return the channel's program exit status. Note that the actual protocol + * provides the full 32bit this function returns. We cannot abuse it to + * return error values in case of errors so we return a zero if channel is + * NULL. + */ +LIBSSH2_API int +libssh2_channel_get_exit_status(LIBSSH2_CHANNEL *channel) +{ + if(!channel) + return 0; + + return channel->exit_status; +} + +/* + * libssh2_channel_get_exit_signal + * + * Get exit signal (without leading "SIG"), error message, and language + * tag into newly allocated buffers of indicated length. Caller can + * use NULL pointers to indicate that the value should not be set. The + * *_len variables are set if they are non-NULL even if the + * corresponding string parameter is NULL. Returns LIBSSH2_ERROR_NONE + * on success, or an API error code. + */ +LIBSSH2_API int +libssh2_channel_get_exit_signal(LIBSSH2_CHANNEL *channel, + char **exitsignal, + size_t *exitsignal_len, + char **errmsg, + size_t *errmsg_len, + char **langtag, + size_t *langtag_len) +{ + size_t namelen = 0; + + if (channel) { + LIBSSH2_SESSION *session = channel->session; + + if (channel->exit_signal) { + namelen = strlen(channel->exit_signal); + if (exitsignal) { + *exitsignal = LIBSSH2_ALLOC(session, namelen + 1); + if (!*exitsignal) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for signal name"); + } + memcpy(*exitsignal, channel->exit_signal, namelen); + (*exitsignal)[namelen] = '\0'; + } + if (exitsignal_len) + *exitsignal_len = namelen; + } else { + if (exitsignal) + *exitsignal = NULL; + if (exitsignal_len) + *exitsignal_len = 0; + } + + /* TODO: set error message and language tag */ + + if (errmsg) + *errmsg = NULL; + + if (errmsg_len) + *errmsg_len = 0; + + if (langtag) + *langtag = NULL; + + if (langtag_len) + *langtag_len = 0; + } + + return LIBSSH2_ERROR_NONE; +} + +/* + * _libssh2_channel_receive_window_adjust + * + * Adjust the receive window for a channel by adjustment bytes. If the amount + * to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the + * adjustment amount will be queued for a later packet. + * + * Calls _libssh2_error() ! + */ +int +_libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel, + uint32_t adjustment, + unsigned char force, + unsigned int *store) +{ + int rc; + + if(store) + *store = channel->remote.window_size; + + if (channel->adjust_state == libssh2_NB_state_idle) { + if (!force + && (adjustment + channel->adjust_queue < + LIBSSH2_CHANNEL_MINADJUST)) { + _libssh2_debug(channel->session, LIBSSH2_TRACE_CONN, + "Queueing %lu bytes for receive window adjustment " + "for channel %lu/%lu", + adjustment, channel->local.id, channel->remote.id); + channel->adjust_queue += adjustment; + return 0; + } + + if (!adjustment && !channel->adjust_queue) { + return 0; + } + + adjustment += channel->adjust_queue; + channel->adjust_queue = 0; + + /* Adjust the window based on the block we just freed */ + channel->adjust_adjust[0] = SSH_MSG_CHANNEL_WINDOW_ADJUST; + _libssh2_htonu32(&channel->adjust_adjust[1], channel->remote.id); + _libssh2_htonu32(&channel->adjust_adjust[5], adjustment); + _libssh2_debug(channel->session, LIBSSH2_TRACE_CONN, + "Adjusting window %lu bytes for data on " + "channel %lu/%lu", + adjustment, channel->local.id, channel->remote.id); + + channel->adjust_state = libssh2_NB_state_created; + } + + rc = _libssh2_transport_send(channel->session, channel->adjust_adjust, 9, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(channel->session, rc, + "Would block sending window adjust"); + return rc; + } + else if (rc) { + channel->adjust_queue = adjustment; + return _libssh2_error(channel->session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send transfer-window adjustment " + "packet, deferring"); + } + else { + channel->remote.window_size += adjustment; + } + + channel->adjust_state = libssh2_NB_state_idle; + + return 0; +} + +/* + * libssh2_channel_receive_window_adjust + * + * DEPRECATED + * + * Adjust the receive window for a channel by adjustment bytes. If the amount + * to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the + * adjustment amount will be queued for a later packet. + * + * Returns the new size of the receive window (as understood by remote end). + * Note that it might return EAGAIN too which is highly stupid. + * + */ +LIBSSH2_API unsigned long +libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel, + unsigned long adj, + unsigned char force) +{ + unsigned int window; + int rc; + + if(!channel) + return (unsigned long)LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, + _libssh2_channel_receive_window_adjust(channel, adj, + force, &window)); + + /* stupid - but this is how it was made to work before and this is just + kept for backwards compatibility */ + return rc?(unsigned long)rc:window; +} + +/* + * libssh2_channel_receive_window_adjust2 + * + * Adjust the receive window for a channel by adjustment bytes. If the amount + * to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the + * adjustment amount will be queued for a later packet. + * + * Stores the new size of the receive window in the data 'window' points to. + * + * Returns the "normal" error code: 0 for success, negative for failure. + */ +LIBSSH2_API int +libssh2_channel_receive_window_adjust2(LIBSSH2_CHANNEL *channel, + unsigned long adj, + unsigned char force, + unsigned int *window) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, + _libssh2_channel_receive_window_adjust(channel, adj, force, + window)); + return rc; +} + +int +_libssh2_channel_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode) +{ + if (channel->extData2_state == libssh2_NB_state_idle) { + _libssh2_debug(channel->session, LIBSSH2_TRACE_CONN, + "Setting channel %lu/%lu handle_extended_data" + " mode to %d", + channel->local.id, channel->remote.id, ignore_mode); + channel->remote.extended_data_ignore_mode = (char)ignore_mode; + + channel->extData2_state = libssh2_NB_state_created; + } + + if (channel->extData2_state == libssh2_NB_state_idle) { + if (ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) { + int rc = + _libssh2_channel_flush(channel, + LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA); + if(LIBSSH2_ERROR_EAGAIN == rc) + return rc; + } + } + + channel->extData2_state = libssh2_NB_state_idle; + return 0; +} + +/* + * libssh2_channel_handle_extended_data2() + * + */ +LIBSSH2_API int +libssh2_channel_handle_extended_data2(LIBSSH2_CHANNEL *channel, + int mode) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, _libssh2_channel_extended_data(channel, + mode)); + return rc; +} + +/* + * libssh2_channel_handle_extended_data + * + * DEPRECATED DO NOTE USE! + * + * How should extended data look to the calling app? Keep it in separate + * channels[_read() _read_stdder()]? (NORMAL) Merge the extended data to the + * standard data? [everything via _read()]? (MERGE) Ignore it entirely [toss + * out packets as they come in]? (IGNORE) + */ +LIBSSH2_API void +libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, + int ignore_mode) +{ + (void)libssh2_channel_handle_extended_data2(channel, ignore_mode); +} + + + +/* + * _libssh2_channel_read + * + * Read data from a channel + * + * It is important to not return 0 until the currently read channel is + * complete. If we read stuff from the wire but it was no payload data to fill + * in the buffer with, we MUST make sure to return LIBSSH2_ERROR_EAGAIN. + * + * The receive window must be maintained (enlarged) by the user of this + * function. + */ +ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id, + char *buf, size_t buflen) +{ + LIBSSH2_SESSION *session = channel->session; + int rc; + int bytes_read = 0; + int bytes_want; + int unlink_packet; + LIBSSH2_PACKET *read_packet; + LIBSSH2_PACKET *read_next; + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "channel_read() wants %d bytes from channel %lu/%lu " + "stream #%d", + (int) buflen, channel->local.id, channel->remote.id, + stream_id); + + /* expand the receiving window first if it has become too narrow */ + if( (channel->read_state == libssh2_NB_state_jump1) || + (channel->remote.window_size < channel->remote.window_size_initial / 4 * 3 + buflen) ) { + + uint32_t adjustment = channel->remote.window_size_initial + buflen - channel->remote.window_size; + if (adjustment < LIBSSH2_CHANNEL_MINADJUST) + adjustment = LIBSSH2_CHANNEL_MINADJUST; + + /* the actual window adjusting may not finish so we need to deal with + this special state here */ + channel->read_state = libssh2_NB_state_jump1; + rc = _libssh2_channel_receive_window_adjust(channel, adjustment, + 0, NULL); + if (rc) + return rc; + + channel->read_state = libssh2_NB_state_idle; + } + + /* Process all pending incoming packets. Tests prove that this way + produces faster transfers. */ + do { + rc = _libssh2_transport_read(session); + } while (rc > 0); + + if ((rc < 0) && (rc != LIBSSH2_ERROR_EAGAIN)) + return _libssh2_error(session, rc, "transport read"); + + read_packet = _libssh2_list_first(&session->packets); + while (read_packet && (bytes_read < (int) buflen)) { + /* previously this loop condition also checked for + !channel->remote.close but we cannot let it do this: + + We may have a series of packets to read that are still pending even + if a close has been received. Acknowledging the close too early + makes us flush buffers prematurely and loose data. + */ + + LIBSSH2_PACKET *readpkt = read_packet; + + /* In case packet gets destroyed during this iteration */ + read_next = _libssh2_list_next(&readpkt->node); + + channel->read_local_id = + _libssh2_ntohu32(readpkt->data + 1); + + /* + * Either we asked for a specific extended data stream + * (and data was available), + * or the standard stream (and data was available), + * or the standard stream with extended_data_merge + * enabled and data was available + */ + if ((stream_id + && (readpkt->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) + && (channel->local.id == channel->read_local_id) + && (stream_id == (int) _libssh2_ntohu32(readpkt->data + 5))) + || (!stream_id && (readpkt->data[0] == SSH_MSG_CHANNEL_DATA) + && (channel->local.id == channel->read_local_id)) + || (!stream_id + && (readpkt->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) + && (channel->local.id == channel->read_local_id) + && (channel->remote.extended_data_ignore_mode == + LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE))) { + + /* figure out much more data we want to read */ + bytes_want = buflen - bytes_read; + unlink_packet = FALSE; + + if (bytes_want >= (int) (readpkt->data_len - readpkt->data_head)) { + /* we want more than this node keeps, so adjust the number and + delete this node after the copy */ + bytes_want = readpkt->data_len - readpkt->data_head; + unlink_packet = TRUE; + } + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "channel_read() got %d of data from %lu/%lu/%d%s", + bytes_want, channel->local.id, + channel->remote.id, stream_id, + unlink_packet?" [ul]":""); + + /* copy data from this struct to the target buffer */ + memcpy(&buf[bytes_read], + &readpkt->data[readpkt->data_head], bytes_want); + + /* advance pointer and counter */ + readpkt->data_head += bytes_want; + bytes_read += bytes_want; + + /* if drained, remove from list */ + if (unlink_packet) { + /* detach readpkt from session->packets list */ + _libssh2_list_remove(&readpkt->node); + + LIBSSH2_FREE(session, readpkt->data); + LIBSSH2_FREE(session, readpkt); + } + } + + /* check the next struct in the chain */ + read_packet = read_next; + } + + if (!bytes_read) { + /* If the channel is already at EOF or even closed, we need to signal + that back. We may have gotten that info while draining the incoming + transport layer until EAGAIN so we must not be fooled by that + return code. */ + if(channel->remote.eof || channel->remote.close) + return 0; + else if(rc != LIBSSH2_ERROR_EAGAIN) + return 0; + + /* if the transport layer said EAGAIN then we say so as well */ + return _libssh2_error(session, rc, "would block"); + } + + channel->read_avail -= bytes_read; + channel->remote.window_size -= bytes_read; + + return bytes_read; +} + +/* + * libssh2_channel_read_ex + * + * Read data from a channel (blocking or non-blocking depending on set state) + * + * When this is done non-blocking, it is important to not return 0 until the + * currently read channel is complete. If we read stuff from the wire but it + * was no payload data to fill in the buffer with, we MUST make sure to return + * LIBSSH2_ERROR_EAGAIN. + * + * This function will first make sure there's a receive window enough to + * receive a full buffer's wort of contents. An application may choose to + * adjust the receive window more to increase transfer performance. + */ +LIBSSH2_API ssize_t +libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, + size_t buflen) +{ + int rc; + unsigned long recv_window; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + recv_window = libssh2_channel_window_read_ex(channel, NULL, NULL); + + if(buflen > recv_window) { + BLOCK_ADJUST(rc, channel->session, + _libssh2_channel_receive_window_adjust(channel, buflen, + 1, NULL)); + } + + BLOCK_ADJUST(rc, channel->session, + _libssh2_channel_read(channel, stream_id, buf, buflen)); + return rc; +} + +/* + * _libssh2_channel_packet_data_len + * + * Return the size of the data block of the current packet, or 0 if there + * isn't a packet. + */ +size_t +_libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id) +{ + LIBSSH2_SESSION *session = channel->session; + LIBSSH2_PACKET *read_packet; + uint32_t read_local_id; + + read_packet = _libssh2_list_first(&session->packets); + if (read_packet == NULL) + return 0; + + while (read_packet) { + read_local_id = _libssh2_ntohu32(read_packet->data + 1); + + /* + * Either we asked for a specific extended data stream + * (and data was available), + * or the standard stream (and data was available), + * or the standard stream with extended_data_merge + * enabled and data was available + */ + if ((stream_id + && (read_packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) + && (channel->local.id == read_local_id) + && (stream_id == (int) _libssh2_ntohu32(read_packet->data + 5))) + || + (!stream_id + && (read_packet->data[0] == SSH_MSG_CHANNEL_DATA) + && (channel->local.id == read_local_id)) + || + (!stream_id + && (read_packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) + && (channel->local.id == read_local_id) + && (channel->remote.extended_data_ignore_mode + == LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE))) + { + return (read_packet->data_len - read_packet->data_head); + } + read_packet = _libssh2_list_next(&read_packet->node); + } + + return 0; +} + +/* + * _libssh2_channel_write + * + * Send data to a channel. Note that if this returns EAGAIN, the caller must + * call this function again with the SAME input arguments. + * + * Returns: number of bytes sent, or if it returns a negative number, that is + * the error code! + */ +ssize_t +_libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id, + const unsigned char *buf, size_t buflen) +{ + int rc = 0; + LIBSSH2_SESSION *session = channel->session; + ssize_t wrote = 0; /* counter for this specific this call */ + + /* In theory we could split larger buffers into several smaller packets + * but it turns out to be really hard and nasty to do while still offering + * the API/prototype. + * + * Instead we only deal with the first 32K in this call and for the parent + * function to call it again with the remainder! 32K is a conservative + * limit based on the text in RFC4253 section 6.1. + */ + if(buflen > 32700) + buflen = 32700; + + if (channel->write_state == libssh2_NB_state_idle) { + unsigned char *s = channel->write_packet; + + _libssh2_debug(channel->session, LIBSSH2_TRACE_CONN, + "Writing %d bytes on channel %lu/%lu, stream #%d", + (int) buflen, channel->local.id, channel->remote.id, + stream_id); + + if (channel->local.close) + return _libssh2_error(channel->session, + LIBSSH2_ERROR_CHANNEL_CLOSED, + "We've already closed this channel"); + else if (channel->local.eof) + return _libssh2_error(channel->session, + LIBSSH2_ERROR_CHANNEL_EOF_SENT, + "EOF has already been received, " + "data might be ignored"); + + /* drain the incoming flow first, mostly to make sure we get all + * pending window adjust packets */ + do + rc = _libssh2_transport_read(session); + while (rc > 0); + + if((rc < 0) && (rc != LIBSSH2_ERROR_EAGAIN)) { + return _libssh2_error(channel->session, rc, + "Failure while draining incoming flow"); + } + + if(channel->local.window_size <= 0) { + /* there's no room for data so we stop */ + + /* Waiting on the socket to be writable would be wrong because we + * would be back here immediately, but a readable socket might + * herald an incoming window adjustment. + */ + session->socket_block_directions = LIBSSH2_SESSION_BLOCK_INBOUND; + + return (rc==LIBSSH2_ERROR_EAGAIN?rc:0); + } + + channel->write_bufwrite = buflen; + + *(s++) = stream_id ? SSH_MSG_CHANNEL_EXTENDED_DATA : + SSH_MSG_CHANNEL_DATA; + _libssh2_store_u32(&s, channel->remote.id); + if (stream_id) + _libssh2_store_u32(&s, stream_id); + + /* Don't exceed the remote end's limits */ + /* REMEMBER local means local as the SOURCE of the data */ + if (channel->write_bufwrite > channel->local.window_size) { + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Splitting write block due to %lu byte " + "window_size on %lu/%lu/%d", + channel->local.window_size, channel->local.id, + channel->remote.id, stream_id); + channel->write_bufwrite = channel->local.window_size; + } + if (channel->write_bufwrite > channel->local.packet_size) { + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Splitting write block due to %lu byte " + "packet_size on %lu/%lu/%d", + channel->local.packet_size, channel->local.id, + channel->remote.id, stream_id); + channel->write_bufwrite = channel->local.packet_size; + } + /* store the size here only, the buffer is passed in as-is to + _libssh2_transport_send() */ + _libssh2_store_u32(&s, channel->write_bufwrite); + channel->write_packet_len = s - channel->write_packet; + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Sending %d bytes on channel %lu/%lu, stream_id=%d", + (int) channel->write_bufwrite, channel->local.id, + channel->remote.id, stream_id); + + channel->write_state = libssh2_NB_state_created; + } + + if (channel->write_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, channel->write_packet, + channel->write_packet_len, + buf, channel->write_bufwrite); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, rc, + "Unable to send channel data"); + } + else if (rc) { + channel->write_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Unable to send channel data"); + } + /* Shrink local window size */ + channel->local.window_size -= channel->write_bufwrite; + + wrote += channel->write_bufwrite; + + /* Since _libssh2_transport_write() succeeded, we must return + now to allow the caller to provide the next chunk of data. + + We cannot move on to send the next piece of data that may + already have been provided in this same function call, as we + risk getting EAGAIN for that and we can't return information + both about sent data as well as EAGAIN. So, by returning short + now, the caller will call this function again with new data to + send */ + + channel->write_state = libssh2_NB_state_idle; + + return wrote; + } + + return LIBSSH2_ERROR_INVAL; /* reaching this point is really bad */ +} + +/* + * libssh2_channel_write_ex + * + * Send data to a channel + */ +LIBSSH2_API ssize_t +libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int stream_id, + const char *buf, size_t buflen) +{ + ssize_t rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, + _libssh2_channel_write(channel, stream_id, + (unsigned char *)buf, buflen)); + return rc; +} + +/* + * channel_send_eof + * + * Send EOF on channel + */ +static int channel_send_eof(LIBSSH2_CHANNEL *channel) +{ + LIBSSH2_SESSION *session = channel->session; + unsigned char packet[5]; /* packet_type(1) + channelno(4) */ + int rc; + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, "Sending EOF on channel %lu/%lu", + channel->local.id, channel->remote.id); + packet[0] = SSH_MSG_CHANNEL_EOF; + _libssh2_htonu32(packet + 1, channel->remote.id); + rc = _libssh2_transport_send(session, packet, 5, NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, rc, + "Would block sending EOF"); + return rc; + } + else if (rc) { + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send EOF on channel"); + } + channel->local.eof = 1; + + return 0; +} + +/* + * libssh2_channel_send_eof + * + * Send EOF on channel + */ +LIBSSH2_API int +libssh2_channel_send_eof(LIBSSH2_CHANNEL *channel) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, channel_send_eof(channel)); + return rc; +} + +/* + * libssh2_channel_eof + * + * Read channel's eof status + */ +LIBSSH2_API int +libssh2_channel_eof(LIBSSH2_CHANNEL * channel) +{ + LIBSSH2_SESSION *session; + LIBSSH2_PACKET *packet; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + session = channel->session; + packet = _libssh2_list_first(&session->packets); + + while (packet) { + if (((packet->data[0] == SSH_MSG_CHANNEL_DATA) + || (packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)) + && (channel->local.id == _libssh2_ntohu32(packet->data + 1))) { + /* There's data waiting to be read yet, mask the EOF status */ + return 0; + } + packet = _libssh2_list_next(&packet->node); + } + + return channel->remote.eof; +} + +/* + * channel_wait_eof + * + * Awaiting channel EOF + */ +static int channel_wait_eof(LIBSSH2_CHANNEL *channel) +{ + LIBSSH2_SESSION *session = channel->session; + int rc; + + if (channel->wait_eof_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Awaiting close of channel %lu/%lu", channel->local.id, + channel->remote.id); + + channel->wait_eof_state = libssh2_NB_state_created; + } + + /* + * While channel is not eof, read more packets from the network. + * Either the EOF will be set or network timeout will occur. + */ + do { + if (channel->remote.eof) { + break; + } + rc = _libssh2_transport_read(session); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if (rc < 0) { + channel->wait_eof_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "_libssh2_transport_read() bailed out!"); + } + } while (1); + + channel->wait_eof_state = libssh2_NB_state_idle; + + return 0; +} + +/* + * libssh2_channel_wait_eof + * + * Awaiting channel EOF + */ +LIBSSH2_API int +libssh2_channel_wait_eof(LIBSSH2_CHANNEL *channel) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, channel_wait_eof(channel)); + return rc; +} + +int _libssh2_channel_close(LIBSSH2_CHANNEL * channel) +{ + LIBSSH2_SESSION *session = channel->session; + int rc = 0; + + if (channel->local.close) { + /* Already closed, act like we sent another close, + * even though we didn't... shhhhhh */ + channel->close_state = libssh2_NB_state_idle; + return 0; + } + + if (!channel->local.eof) { + if ((rc = channel_send_eof(channel))) { + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + _libssh2_error(session, rc, + "Unable to send EOF, but closing channel anyway"); + } + } + + /* ignore if we have received a remote eof or not, as it is now too + late for us to wait for it. Continue closing! */ + + if (channel->close_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_CONN, "Closing channel %lu/%lu", + channel->local.id, channel->remote.id); + + channel->close_packet[0] = SSH_MSG_CHANNEL_CLOSE; + _libssh2_htonu32(channel->close_packet + 1, channel->remote.id); + + channel->close_state = libssh2_NB_state_created; + } + + if (channel->close_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, channel->close_packet, 5, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, rc, + "Would block sending close-channel"); + return rc; + + } else if (rc) { + _libssh2_error(session, rc, + "Unable to send close-channel request, " + "but closing anyway"); + /* skip waiting for the response and fall through to + LIBSSH2_CHANNEL_CLOSE below */ + + } else + channel->close_state = libssh2_NB_state_sent; + } + + if (channel->close_state == libssh2_NB_state_sent) { + /* We must wait for the remote SSH_MSG_CHANNEL_CLOSE message */ + + while (!channel->remote.close && !rc && + (session->socket_state != LIBSSH2_SOCKET_DISCONNECTED)) + rc = _libssh2_transport_read(session); + } + + if(rc != LIBSSH2_ERROR_EAGAIN) { + /* set the local close state first when we're perfectly confirmed to not + do any more EAGAINs */ + channel->local.close = 1; + + /* We call the callback last in this function to make it keep the local + data as long as EAGAIN is returned. */ + if (channel->close_cb) { + LIBSSH2_CHANNEL_CLOSE(session, channel); + } + + channel->close_state = libssh2_NB_state_idle; + } + + /* return 0 or an error */ + return rc>=0?0:rc; +} + +/* + * libssh2_channel_close + * + * Close a channel + */ +LIBSSH2_API int +libssh2_channel_close(LIBSSH2_CHANNEL *channel) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, _libssh2_channel_close(channel) ); + return rc; +} + +/* + * channel_wait_closed + * + * Awaiting channel close after EOF + */ +static int channel_wait_closed(LIBSSH2_CHANNEL *channel) +{ + LIBSSH2_SESSION *session = channel->session; + int rc; + + if (!libssh2_channel_eof(channel)) { + return _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "libssh2_channel_wait_closed() invoked when " + "channel is not in EOF state"); + } + + if (channel->wait_closed_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Awaiting close of channel %lu/%lu", channel->local.id, + channel->remote.id); + + channel->wait_closed_state = libssh2_NB_state_created; + } + + /* + * While channel is not closed, read more packets from the network. + * Either the channel will be closed or network timeout will occur. + */ + if (!channel->remote.close) { + do { + rc = _libssh2_transport_read(session); + if (channel->remote.close) + /* it is now closed, move on! */ + break; + } while (rc > 0); + if(rc < 0) + return rc; + } + + channel->wait_closed_state = libssh2_NB_state_idle; + + return 0; +} + +/* + * libssh2_channel_wait_closed + * + * Awaiting channel close after EOF + */ +LIBSSH2_API int +libssh2_channel_wait_closed(LIBSSH2_CHANNEL *channel) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, channel_wait_closed(channel)); + return rc; +} + +/* + * _libssh2_channel_free + * + * Make sure a channel is closed, then remove the channel from the session + * and free its resource(s) + * + * Returns 0 on success, negative on failure + */ +int _libssh2_channel_free(LIBSSH2_CHANNEL *channel) +{ + LIBSSH2_SESSION *session = channel->session; + unsigned char channel_id[4]; + unsigned char *data; + size_t data_len; + int rc; + + assert(session); + + if (channel->free_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Freeing channel %lu/%lu resources", channel->local.id, + channel->remote.id); + + channel->free_state = libssh2_NB_state_created; + } + + /* Allow channel freeing even when the socket has lost its connection */ + if (!channel->local.close + && (session->socket_state == LIBSSH2_SOCKET_CONNECTED)) { + rc = _libssh2_channel_close(channel); + + if(rc == LIBSSH2_ERROR_EAGAIN) + return rc; + + /* ignore all other errors as they otherwise risk blocking the channel + free from happening */ + } + + channel->free_state = libssh2_NB_state_idle; + + if (channel->exit_signal) { + LIBSSH2_FREE(session, channel->exit_signal); + } + + /* + * channel->remote.close *might* not be set yet, Well... + * We've sent the close packet, what more do you want? + * Just let packet_add ignore it when it finally arrives + */ + + /* Clear out packets meant for this channel */ + _libssh2_htonu32(channel_id, channel->local.id); + while ((_libssh2_packet_ask(session, SSH_MSG_CHANNEL_DATA, &data, + &data_len, 1, channel_id, 4) >= 0) + || + (_libssh2_packet_ask(session, SSH_MSG_CHANNEL_EXTENDED_DATA, &data, + &data_len, 1, channel_id, 4) >= 0)) { + LIBSSH2_FREE(session, data); + } + + /* free "channel_type" */ + if (channel->channel_type) { + LIBSSH2_FREE(session, channel->channel_type); + } + + /* Unlink from channel list */ + _libssh2_list_remove(&channel->node); + + /* + * Make sure all memory used in the state variables are free + */ + if (channel->setenv_packet) { + LIBSSH2_FREE(session, channel->setenv_packet); + } + if (channel->reqX11_packet) { + LIBSSH2_FREE(session, channel->reqX11_packet); + } + if (channel->process_packet) { + LIBSSH2_FREE(session, channel->process_packet); + } + + LIBSSH2_FREE(session, channel); + + return 0; +} + +/* + * libssh2_channel_free + * + * Make sure a channel is closed, then remove the channel from the session + * and free its resource(s) + * + * Returns 0 on success, negative on failure + */ +LIBSSH2_API int +libssh2_channel_free(LIBSSH2_CHANNEL *channel) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, _libssh2_channel_free(channel)); + return rc; +} +/* + * libssh2_channel_window_read_ex + * + * Check the status of the read window. Returns the number of bytes which the + * remote end may send without overflowing the window limit read_avail (if + * passed) will be populated with the number of bytes actually available to be + * read window_size_initial (if passed) will be populated with the + * window_size_initial as defined by the channel_open request + */ +LIBSSH2_API unsigned long +libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channel, + unsigned long *read_avail, + unsigned long *window_size_initial) +{ + if(!channel) + return 0; /* no channel, no window! */ + + if (window_size_initial) { + *window_size_initial = channel->remote.window_size_initial; + } + + if (read_avail) { + size_t bytes_queued = 0; + LIBSSH2_PACKET *packet = + _libssh2_list_first(&channel->session->packets); + + while (packet) { + unsigned char packet_type = packet->data[0]; + + if (((packet_type == SSH_MSG_CHANNEL_DATA) + || (packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA)) + && (_libssh2_ntohu32(packet->data + 1) == channel->local.id)) { + bytes_queued += packet->data_len - packet->data_head; + } + + packet = _libssh2_list_next(&packet->node); + } + + *read_avail = bytes_queued; + } + + return channel->remote.window_size; +} + +/* + * libssh2_channel_window_write_ex + * + * Check the status of the write window Returns the number of bytes which may + * be safely written on the channel without blocking window_size_initial (if + * passed) will be populated with the size of the initial window as defined by + * the channel_open request + */ +LIBSSH2_API unsigned long +libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *channel, + unsigned long *window_size_initial) +{ + if(!channel) + return 0; /* no channel, no window! */ + + if (window_size_initial) { + /* For locally initiated channels this is very often 0, so it's not + * *that* useful as information goes */ + *window_size_initial = channel->local.window_size_initial; + } + + return channel->local.window_size; +} diff --git a/libssh2/comp.c b/libssh2/comp.c new file mode 100644 index 0000000..4560188 --- /dev/null +++ b/libssh2/comp.c @@ -0,0 +1,366 @@ +/* Copyright (c) 2004-2007, Sara Golemon + * Copyright (c) 2010-2014, Daniel Stenberg + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#ifdef LIBSSH2_HAVE_ZLIB +# include +#endif + +#include "comp.h" + +/* ******** + * none * + ******** */ + +/* + * comp_method_none_comp + * + * Minimalist compression: Absolutely none + */ +static int +comp_method_none_comp(LIBSSH2_SESSION *session, + unsigned char *dest, + size_t *dest_len, + const unsigned char *src, + size_t src_len, + void **abstract) +{ + (void) session; + (void) abstract; + (void) dest; + (void) dest_len; + (void) src; + (void) src_len; + + return 0; +} + +/* + * comp_method_none_decomp + * + * Minimalist decompression: Absolutely none + */ +static int +comp_method_none_decomp(LIBSSH2_SESSION * session, + unsigned char **dest, + size_t *dest_len, + size_t payload_limit, + const unsigned char *src, + size_t src_len, void **abstract) +{ + (void) session; + (void) payload_limit; + (void) abstract; + *dest = (unsigned char *) src; + *dest_len = src_len; + return 0; +} + + + +static const LIBSSH2_COMP_METHOD comp_method_none = { + "none", + 0, /* not really compressing */ + 0, /* isn't used in userauth, go figure */ + NULL, + comp_method_none_comp, + comp_method_none_decomp, + NULL +}; + +#ifdef LIBSSH2_HAVE_ZLIB +/* ******** + * zlib * + ******** */ + +/* Memory management wrappers + * Yes, I realize we're doing a callback to a callback, + * Deal... + */ + +static voidpf +comp_method_zlib_alloc(voidpf opaque, uInt items, uInt size) +{ + LIBSSH2_SESSION *session = (LIBSSH2_SESSION *) opaque; + + return (voidpf) LIBSSH2_ALLOC(session, items * size); +} + +static void +comp_method_zlib_free(voidpf opaque, voidpf address) +{ + LIBSSH2_SESSION *session = (LIBSSH2_SESSION *) opaque; + + LIBSSH2_FREE(session, address); +} + + + +/* libssh2_comp_method_zlib_init + * All your bandwidth are belong to us (so save some) + */ +static int +comp_method_zlib_init(LIBSSH2_SESSION * session, int compr, + void **abstract) +{ + z_stream *strm; + int status; + + strm = LIBSSH2_CALLOC(session, sizeof(z_stream)); + if (!strm) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "zlib compression/decompression"); + } + + strm->opaque = (voidpf) session; + strm->zalloc = (alloc_func) comp_method_zlib_alloc; + strm->zfree = (free_func) comp_method_zlib_free; + if (compr) { + /* deflate */ + status = deflateInit(strm, Z_DEFAULT_COMPRESSION); + } else { + /* inflate */ + status = inflateInit(strm); + } + + if (status != Z_OK) { + LIBSSH2_FREE(session, strm); + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "unhandled zlib error %d", status); + return LIBSSH2_ERROR_COMPRESS; + } + *abstract = strm; + + return LIBSSH2_ERROR_NONE; +} + +/* + * libssh2_comp_method_zlib_comp + * + * Compresses source to destination. Without allocation. + */ +static int +comp_method_zlib_comp(LIBSSH2_SESSION *session, + unsigned char *dest, + + /* dest_len is a pointer to allow this function to + update it with the final actual size used */ + size_t *dest_len, + const unsigned char *src, + size_t src_len, + void **abstract) +{ + z_stream *strm = *abstract; + int out_maxlen = *dest_len; + int status; + + strm->next_in = (unsigned char *) src; + strm->avail_in = src_len; + strm->next_out = dest; + strm->avail_out = out_maxlen; + + status = deflate(strm, Z_PARTIAL_FLUSH); + + if ((status == Z_OK) && (strm->avail_out > 0)) { + *dest_len = out_maxlen - strm->avail_out; + return 0; + } + + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "unhandled zlib compression error %d, avail_out", status, strm->avail_out); + return _libssh2_error(session, LIBSSH2_ERROR_ZLIB, "compression failure"); +} + +/* + * libssh2_comp_method_zlib_decomp + * + * Decompresses source to destination. Allocates the output memory. + */ +static int +comp_method_zlib_decomp(LIBSSH2_SESSION * session, + unsigned char **dest, + size_t *dest_len, + size_t payload_limit, + const unsigned char *src, + size_t src_len, void **abstract) +{ + z_stream *strm = *abstract; + /* A short-term alloc of a full data chunk is better than a series of + reallocs */ + char *out; + int out_maxlen = 4 * src_len; + + /* If strm is null, then we have not yet been initialized. */ + if (strm == NULL) + return _libssh2_error(session, LIBSSH2_ERROR_COMPRESS, + "decompression uninitialized");; + + /* In practice they never come smaller than this */ + if (out_maxlen < 25) + out_maxlen = 25; + + if (out_maxlen > (int) payload_limit) + out_maxlen = payload_limit; + + strm->next_in = (unsigned char *) src; + strm->avail_in = src_len; + strm->next_out = (unsigned char *) LIBSSH2_ALLOC(session, out_maxlen); + out = (char *) strm->next_out; + strm->avail_out = out_maxlen; + if (!strm->next_out) + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate decompression buffer"); + + /* Loop until it's all inflated or hit error */ + for (;;) { + int status; + size_t out_ofs; + char *newout; + + status = inflate(strm, Z_PARTIAL_FLUSH); + + if (status == Z_OK) { + if (strm->avail_out > 0) + /* status is OK and the output buffer has not been exhausted so we're done */ + break; + } else if (status == Z_BUF_ERROR) { + /* the input data has been exhausted so we are done */ + break; + } else { + /* error state */ + LIBSSH2_FREE(session, out); + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "unhandled zlib error %d", status); + return _libssh2_error(session, LIBSSH2_ERROR_ZLIB, + "decompression failure"); + } + + if (out_maxlen >= (int) payload_limit) { + LIBSSH2_FREE(session, out); + return _libssh2_error(session, LIBSSH2_ERROR_ZLIB, + "Excessive growth in decompression phase"); + } + + /* If we get here we need to grow the output buffer and try again */ + out_ofs = out_maxlen - strm->avail_out; + out_maxlen *= 2; + newout = LIBSSH2_REALLOC(session, out, out_maxlen); + if (!newout) { + LIBSSH2_FREE(session, out); + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to expand decompression buffer"); + } + out = newout; + strm->next_out = (unsigned char *) out + out_ofs; + strm->avail_out = out_maxlen - out_ofs; + } + + *dest = (unsigned char *) out; + *dest_len = out_maxlen - strm->avail_out; + + return 0; +} + + +/* libssh2_comp_method_zlib_dtor + * All done, no more compression for you + */ +static int +comp_method_zlib_dtor(LIBSSH2_SESSION *session, int compr, void **abstract) +{ + z_stream *strm = *abstract; + + if (strm) { + if (compr) + deflateEnd(strm); + else + inflateEnd(strm); + LIBSSH2_FREE(session, strm); + } + + *abstract = NULL; + return 0; +} + +static const LIBSSH2_COMP_METHOD comp_method_zlib = { + "zlib", + 1, /* yes, this compresses */ + 1, /* do compression during userauth */ + comp_method_zlib_init, + comp_method_zlib_comp, + comp_method_zlib_decomp, + comp_method_zlib_dtor, +}; + +static const LIBSSH2_COMP_METHOD comp_method_zlib_openssh = { + "zlib@openssh.com", + 1, /* yes, this compresses */ + 0, /* don't use compression during userauth */ + comp_method_zlib_init, + comp_method_zlib_comp, + comp_method_zlib_decomp, + comp_method_zlib_dtor, +}; +#endif /* LIBSSH2_HAVE_ZLIB */ + +/* If compression is enabled by the API, then this array is used which then + may allow compression if zlib is available at build time */ +static const LIBSSH2_COMP_METHOD *comp_methods[] = { +#ifdef LIBSSH2_HAVE_ZLIB + &comp_method_zlib, + &comp_method_zlib_openssh, +#endif /* LIBSSH2_HAVE_ZLIB */ + &comp_method_none, + NULL +}; + +/* If compression is disabled by the API, then this array is used */ +static const LIBSSH2_COMP_METHOD *no_comp_methods[] = { + &comp_method_none, + NULL +}; + +const LIBSSH2_COMP_METHOD ** +_libssh2_comp_methods(LIBSSH2_SESSION *session) +{ + if(session->flag.compress) + return comp_methods; + else + return no_comp_methods; +} diff --git a/libssh2/crypt.c b/libssh2/crypt.c new file mode 100644 index 0000000..931ae8b --- /dev/null +++ b/libssh2/crypt.c @@ -0,0 +1,336 @@ +/* Copyright (c) 2009, 2010 Simon Josefsson + * Copyright (c) 2004-2007, Sara Golemon + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" + +#ifdef LIBSSH2_CRYPT_NONE + +/* crypt_none_crypt + * Minimalist cipher: VERY secure *wink* + */ +static int +crypt_none_crypt(LIBSSH2_SESSION * session, unsigned char *buf, + void **abstract) +{ + /* Do nothing to the data! */ + return 0; +} + +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_none = { + "none", + 8, /* blocksize (SSH2 defines minimum blocksize as 8) */ + 0, /* iv_len */ + 0, /* secret_len */ + 0, /* flags */ + NULL, + crypt_none_crypt, + NULL +}; +#endif /* LIBSSH2_CRYPT_NONE */ + +struct crypt_ctx +{ + int encrypt; + _libssh2_cipher_type(algo); + _libssh2_cipher_ctx h; +}; + +static int +crypt_init(LIBSSH2_SESSION * session, + const LIBSSH2_CRYPT_METHOD * method, + unsigned char *iv, int *free_iv, + unsigned char *secret, int *free_secret, + int encrypt, void **abstract) +{ + struct crypt_ctx *ctx = LIBSSH2_ALLOC(session, + sizeof(struct crypt_ctx)); + if (!ctx) + return LIBSSH2_ERROR_ALLOC; + + ctx->encrypt = encrypt; + ctx->algo = method->algo; + if (_libssh2_cipher_init(&ctx->h, ctx->algo, iv, secret, encrypt)) { + LIBSSH2_FREE(session, ctx); + return -1; + } + *abstract = ctx; + *free_iv = 1; + *free_secret = 1; + return 0; +} + +static int +crypt_encrypt(LIBSSH2_SESSION * session, unsigned char *block, + size_t blocksize, void **abstract) +{ + struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract; + (void) session; + return _libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block, + blocksize); +} + +static int +crypt_dtor(LIBSSH2_SESSION * session, void **abstract) +{ + struct crypt_ctx **cctx = (struct crypt_ctx **) abstract; + if (cctx && *cctx) { + _libssh2_cipher_dtor(&(*cctx)->h); + LIBSSH2_FREE(session, *cctx); + *abstract = NULL; + } + return 0; +} + +#if LIBSSH2_AES_CTR +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_ctr = { + "aes128-ctr", + 16, /* blocksize */ + 16, /* initial value length */ + 16, /* secret length -- 16*8 == 128bit */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_aes128ctr +}; + +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_ctr = { + "aes192-ctr", + 16, /* blocksize */ + 16, /* initial value length */ + 24, /* secret length -- 24*8 == 192bit */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_aes192ctr +}; + +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_ctr = { + "aes256-ctr", + 16, /* blocksize */ + 16, /* initial value length */ + 32, /* secret length -- 32*8 == 256bit */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_aes256ctr +}; +#endif + +#if LIBSSH2_AES +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = { + "aes128-cbc", + 16, /* blocksize */ + 16, /* initial value length */ + 16, /* secret length -- 16*8 == 128bit */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_aes128 +}; + +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_cbc = { + "aes192-cbc", + 16, /* blocksize */ + 16, /* initial value length */ + 24, /* secret length -- 24*8 == 192bit */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_aes192 +}; + +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_cbc = { + "aes256-cbc", + 16, /* blocksize */ + 16, /* initial value length */ + 32, /* secret length -- 32*8 == 256bit */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_aes256 +}; + +/* rijndael-cbc@lysator.liu.se == aes256-cbc */ +static const LIBSSH2_CRYPT_METHOD + libssh2_crypt_method_rijndael_cbc_lysator_liu_se = { + "rijndael-cbc@lysator.liu.se", + 16, /* blocksize */ + 16, /* initial value length */ + 32, /* secret length -- 32*8 == 256bit */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_aes256 +}; +#endif /* LIBSSH2_AES */ + +#if LIBSSH2_BLOWFISH +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_blowfish_cbc = { + "blowfish-cbc", + 8, /* blocksize */ + 8, /* initial value length */ + 16, /* secret length */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_blowfish +}; +#endif /* LIBSSH2_BLOWFISH */ + +#if LIBSSH2_RC4 +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = { + "arcfour", + 8, /* blocksize */ + 8, /* initial value length */ + 16, /* secret length */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_arcfour +}; + +static int +crypt_init_arcfour128(LIBSSH2_SESSION * session, + const LIBSSH2_CRYPT_METHOD * method, + unsigned char *iv, int *free_iv, + unsigned char *secret, int *free_secret, + int encrypt, void **abstract) +{ + int rc; + + rc = crypt_init (session, method, iv, free_iv, secret, free_secret, + encrypt, abstract); + if (rc == 0) { + struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract; + unsigned char block[8]; + size_t discard = 1536; + for (; discard; discard -= 8) + _libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block, + method->blocksize); + } + + return rc; +} + +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour128 = { + "arcfour128", + 8, /* blocksize */ + 8, /* initial value length */ + 16, /* secret length */ + 0, /* flags */ + &crypt_init_arcfour128, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_arcfour +}; +#endif /* LIBSSH2_RC4 */ + +#if LIBSSH2_CAST +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_cast128_cbc = { + "cast128-cbc", + 8, /* blocksize */ + 8, /* initial value length */ + 16, /* secret length */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_cast5 +}; +#endif /* LIBSSH2_CAST */ + +#if LIBSSH2_3DES +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = { + "3des-cbc", + 8, /* blocksize */ + 8, /* initial value length */ + 24, /* secret length */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_3des +}; +#endif + +static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = { +#if LIBSSH2_AES_CTR + &libssh2_crypt_method_aes128_ctr, + &libssh2_crypt_method_aes192_ctr, + &libssh2_crypt_method_aes256_ctr, +#endif /* LIBSSH2_AES */ +#if LIBSSH2_AES + &libssh2_crypt_method_aes256_cbc, + &libssh2_crypt_method_rijndael_cbc_lysator_liu_se, /* == aes256-cbc */ + &libssh2_crypt_method_aes192_cbc, + &libssh2_crypt_method_aes128_cbc, +#endif /* LIBSSH2_AES */ +#if LIBSSH2_BLOWFISH + &libssh2_crypt_method_blowfish_cbc, +#endif /* LIBSSH2_BLOWFISH */ +#if LIBSSH2_RC4 + &libssh2_crypt_method_arcfour128, + &libssh2_crypt_method_arcfour, +#endif /* LIBSSH2_RC4 */ +#if LIBSSH2_CAST + &libssh2_crypt_method_cast128_cbc, +#endif /* LIBSSH2_CAST */ +#if LIBSSH2_3DES + &libssh2_crypt_method_3des_cbc, +#endif /* LIBSSH2_DES */ +#ifdef LIBSSH2_CRYPT_NONE + &libssh2_crypt_method_none, +#endif + NULL +}; + +/* Expose to kex.c */ +const LIBSSH2_CRYPT_METHOD ** +libssh2_crypt_methods(void) +{ + return _libssh2_crypt_methods; +} diff --git a/libssh2/global.c b/libssh2/global.c new file mode 100644 index 0000000..dc45e70 --- /dev/null +++ b/libssh2/global.c @@ -0,0 +1,78 @@ +/* Copyright (c) 2010 Lars Nordin + * Copyright (C) 2010 Simon Josefsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" + +static int _libssh2_initialized = 0; +static int _libssh2_init_flags = 0; + +LIBSSH2_API int +libssh2_init(int flags) +{ + if (_libssh2_initialized == 0 && !(flags & LIBSSH2_INIT_NO_CRYPTO)) { + libssh2_crypto_init(); + _libssh2_init_aes_ctr(); + } + + _libssh2_initialized++; + _libssh2_init_flags |= flags; + + return 0; +} + +LIBSSH2_API void +libssh2_exit(void) +{ + if (_libssh2_initialized == 0) + return; + + _libssh2_initialized--; + + if (!(_libssh2_init_flags & LIBSSH2_INIT_NO_CRYPTO)) { + libssh2_crypto_exit(); + } + + return; +} + +void +_libssh2_init_if_needed(void) +{ + if (_libssh2_initialized == 0) + (void)libssh2_init (0); +} diff --git a/libssh2/hostkey.c b/libssh2/hostkey.c new file mode 100644 index 0000000..a3c2f04 --- /dev/null +++ b/libssh2/hostkey.c @@ -0,0 +1,566 @@ +/* Copyright (c) 2004-2006, Sara Golemon + * Copyright (c) 2009-2014 by Daniel Stenberg + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#include "misc.h" + +/* Needed for struct iovec on some platforms */ +#ifdef HAVE_SYS_UIO_H +#include +#endif + +#if LIBSSH2_RSA +/* *********** + * ssh-rsa * + *********** */ + +static int hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session, + void **abstract); + +/* + * hostkey_method_ssh_rsa_init + * + * Initialize the server hostkey working area with e/n pair + */ +static int +hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session, + const unsigned char *hostkey_data, + size_t hostkey_data_len, + void **abstract) +{ + libssh2_rsa_ctx *rsactx; + const unsigned char *s, *e, *n; + unsigned long len, e_len, n_len; + int ret; + + (void) hostkey_data_len; + + if (*abstract) { + hostkey_method_ssh_rsa_dtor(session, abstract); + *abstract = NULL; + } + + s = hostkey_data; + len = _libssh2_ntohu32(s); + s += 4; + + if (len != 7 || strncmp((char *) s, "ssh-rsa", 7) != 0) { + return -1; + } + s += 7; + + e_len = _libssh2_ntohu32(s); + s += 4; + + e = s; + s += e_len; + n_len = _libssh2_ntohu32(s); + s += 4; + n = s; + + ret = _libssh2_rsa_new(&rsactx, e, e_len, n, n_len, NULL, 0, + NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0); + if (ret) { + return -1; + } + + *abstract = rsactx; + + return 0; +} + +/* + * hostkey_method_ssh_rsa_initPEM + * + * Load a Private Key from a PEM file + */ +static int +hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION * session, + const char *privkeyfile, + unsigned const char *passphrase, + void **abstract) +{ + libssh2_rsa_ctx *rsactx; + int ret; + + if (*abstract) { + hostkey_method_ssh_rsa_dtor(session, abstract); + *abstract = NULL; + } + + ret = _libssh2_rsa_new_private(&rsactx, session, privkeyfile, passphrase); + if (ret) { + return -1; + } + + *abstract = rsactx; + + return 0; +} + +/* + * hostkey_method_ssh_rsa_initPEMFromMemory + * + * Load a Private Key from a memory + */ +static int +hostkey_method_ssh_rsa_initPEMFromMemory(LIBSSH2_SESSION * session, + const char *privkeyfiledata, + size_t privkeyfiledata_len, + unsigned const char *passphrase, + void **abstract) +{ + libssh2_rsa_ctx *rsactx; + int ret; + + if (*abstract) { + hostkey_method_ssh_rsa_dtor(session, abstract); + *abstract = NULL; + } + + ret = _libssh2_rsa_new_private_frommemory(&rsactx, session, + privkeyfiledata, + privkeyfiledata_len, passphrase); + if (ret) { + return -1; + } + + *abstract = rsactx; + + return 0; +} + +/* + * hostkey_method_ssh_rsa_sign + * + * Verify signature created by remote + */ +static int +hostkey_method_ssh_rsa_sig_verify(LIBSSH2_SESSION * session, + const unsigned char *sig, + size_t sig_len, + const unsigned char *m, + size_t m_len, void **abstract) +{ + libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract); + (void) session; + + /* Skip past keyname_len(4) + keyname(7){"ssh-rsa"} + signature_len(4) */ + sig += 15; + sig_len -= 15; + return _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len); +} + +/* + * hostkey_method_ssh_rsa_signv + * + * Construct a signature from an array of vectors + */ +static int +hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION * session, + unsigned char **signature, + size_t *signature_len, + int veccount, + const struct iovec datavec[], + void **abstract) +{ + libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract); + int ret; + int i; + unsigned char hash[SHA_DIGEST_LENGTH]; + libssh2_sha1_ctx ctx; + + libssh2_sha1_init(&ctx); + for(i = 0; i < veccount; i++) { + libssh2_sha1_update(ctx, datavec[i].iov_base, datavec[i].iov_len); + } + libssh2_sha1_final(ctx, hash); + + ret = _libssh2_rsa_sha1_sign(session, rsactx, hash, SHA_DIGEST_LENGTH, + signature, signature_len); + if (ret) { + return -1; + } + + return 0; +} + +/* + * hostkey_method_ssh_rsa_dtor + * + * Shutdown the hostkey + */ +static int +hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session, void **abstract) +{ + libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract); + (void) session; + + _libssh2_rsa_free(rsactx); + + *abstract = NULL; + + return 0; +} + +#ifdef OPENSSL_NO_MD5 +#define MD5_DIGEST_LENGTH 16 +#endif + +static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa = { + "ssh-rsa", + MD5_DIGEST_LENGTH, + hostkey_method_ssh_rsa_init, + hostkey_method_ssh_rsa_initPEM, + hostkey_method_ssh_rsa_initPEMFromMemory, + hostkey_method_ssh_rsa_sig_verify, + hostkey_method_ssh_rsa_signv, + NULL, /* encrypt */ + hostkey_method_ssh_rsa_dtor, +}; +#endif /* LIBSSH2_RSA */ + +#if LIBSSH2_DSA +/* *********** + * ssh-dss * + *********** */ + +static int hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session, + void **abstract); + +/* + * hostkey_method_ssh_dss_init + * + * Initialize the server hostkey working area with p/q/g/y set + */ +static int +hostkey_method_ssh_dss_init(LIBSSH2_SESSION * session, + const unsigned char *hostkey_data, + size_t hostkey_data_len, + void **abstract) +{ + libssh2_dsa_ctx *dsactx; + const unsigned char *p, *q, *g, *y, *s; + unsigned long p_len, q_len, g_len, y_len, len; + int ret; + (void) hostkey_data_len; + + if (*abstract) { + hostkey_method_ssh_dss_dtor(session, abstract); + *abstract = NULL; + } + + s = hostkey_data; + len = _libssh2_ntohu32(s); + s += 4; + if (len != 7 || strncmp((char *) s, "ssh-dss", 7) != 0) { + return -1; + } + s += 7; + + p_len = _libssh2_ntohu32(s); + s += 4; + p = s; + s += p_len; + q_len = _libssh2_ntohu32(s); + s += 4; + q = s; + s += q_len; + g_len = _libssh2_ntohu32(s); + s += 4; + g = s; + s += g_len; + y_len = _libssh2_ntohu32(s); + s += 4; + y = s; + /* s += y_len; */ + + ret = _libssh2_dsa_new(&dsactx, p, p_len, q, q_len, + g, g_len, y, y_len, NULL, 0); + if (ret) { + return -1; + } + + *abstract = dsactx; + + return 0; +} + +/* + * hostkey_method_ssh_dss_initPEM + * + * Load a Private Key from a PEM file + */ +static int +hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION * session, + const char *privkeyfile, + unsigned const char *passphrase, + void **abstract) +{ + libssh2_dsa_ctx *dsactx; + int ret; + + if (*abstract) { + hostkey_method_ssh_dss_dtor(session, abstract); + *abstract = NULL; + } + + ret = _libssh2_dsa_new_private(&dsactx, session, privkeyfile, passphrase); + if (ret) { + return -1; + } + + *abstract = dsactx; + + return 0; +} + +/* + * hostkey_method_ssh_dss_initPEMFromMemory + * + * Load a Private Key from memory + */ +static int +hostkey_method_ssh_dss_initPEMFromMemory(LIBSSH2_SESSION * session, + const char *privkeyfiledata, + size_t privkeyfiledata_len, + unsigned const char *passphrase, + void **abstract) +{ + libssh2_dsa_ctx *dsactx; + int ret; + + if (*abstract) { + hostkey_method_ssh_dss_dtor(session, abstract); + *abstract = NULL; + } + + ret = _libssh2_dsa_new_private_frommemory(&dsactx, session, + privkeyfiledata, + privkeyfiledata_len, passphrase); + if (ret) { + return -1; + } + + *abstract = dsactx; + + return 0; +} + +/* + * libssh2_hostkey_method_ssh_dss_sign + * + * Verify signature created by remote + */ +static int +hostkey_method_ssh_dss_sig_verify(LIBSSH2_SESSION * session, + const unsigned char *sig, + size_t sig_len, + const unsigned char *m, + size_t m_len, void **abstract) +{ + libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract); + + /* Skip past keyname_len(4) + keyname(7){"ssh-dss"} + signature_len(4) */ + sig += 15; + sig_len -= 15; + if (sig_len != 40) { + return _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Invalid DSS signature length"); + } + return _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len); +} + +/* + * hostkey_method_ssh_dss_signv + * + * Construct a signature from an array of vectors + */ +static int +hostkey_method_ssh_dss_signv(LIBSSH2_SESSION * session, + unsigned char **signature, + size_t *signature_len, + int veccount, + const struct iovec datavec[], + void **abstract) +{ + libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract); + unsigned char hash[SHA_DIGEST_LENGTH]; + libssh2_sha1_ctx ctx; + int i; + + *signature = LIBSSH2_CALLOC(session, 2 * SHA_DIGEST_LENGTH); + if (!*signature) { + return -1; + } + + *signature_len = 2 * SHA_DIGEST_LENGTH; + + libssh2_sha1_init(&ctx); + for(i = 0; i < veccount; i++) { + libssh2_sha1_update(ctx, datavec[i].iov_base, datavec[i].iov_len); + } + libssh2_sha1_final(ctx, hash); + + if (_libssh2_dsa_sha1_sign(dsactx, hash, SHA_DIGEST_LENGTH, *signature)) { + LIBSSH2_FREE(session, *signature); + return -1; + } + + return 0; +} + +/* + * libssh2_hostkey_method_ssh_dss_dtor + * + * Shutdown the hostkey method + */ +static int +hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session, void **abstract) +{ + libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract); + (void) session; + + _libssh2_dsa_free(dsactx); + + *abstract = NULL; + + return 0; +} + +static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_dss = { + "ssh-dss", + MD5_DIGEST_LENGTH, + hostkey_method_ssh_dss_init, + hostkey_method_ssh_dss_initPEM, + hostkey_method_ssh_dss_initPEMFromMemory, + hostkey_method_ssh_dss_sig_verify, + hostkey_method_ssh_dss_signv, + NULL, /* encrypt */ + hostkey_method_ssh_dss_dtor, +}; +#endif /* LIBSSH2_DSA */ + +static const LIBSSH2_HOSTKEY_METHOD *hostkey_methods[] = { +#if LIBSSH2_RSA + &hostkey_method_ssh_rsa, +#endif /* LIBSSH2_RSA */ +#if LIBSSH2_DSA + &hostkey_method_ssh_dss, +#endif /* LIBSSH2_DSA */ + NULL +}; + +const LIBSSH2_HOSTKEY_METHOD ** +libssh2_hostkey_methods(void) +{ + return hostkey_methods; +} + +/* + * libssh2_hostkey_hash + * + * Returns hash signature + * Returned buffer should NOT be freed + * Length of buffer is determined by hash type + * i.e. MD5 == 16, SHA1 == 20 + */ +LIBSSH2_API const char * +libssh2_hostkey_hash(LIBSSH2_SESSION * session, int hash_type) +{ + switch (hash_type) { +#if LIBSSH2_MD5 + case LIBSSH2_HOSTKEY_HASH_MD5: + return (session->server_hostkey_md5_valid) + ? (char *) session->server_hostkey_md5 + : NULL; + break; +#endif /* LIBSSH2_MD5 */ + case LIBSSH2_HOSTKEY_HASH_SHA1: + return (session->server_hostkey_sha1_valid) + ? (char *) session->server_hostkey_sha1 + : NULL; + break; + default: + return NULL; + } +} + +static int hostkey_type(const unsigned char *hostkey, size_t len) +{ + const unsigned char rsa[] = { + 0, 0, 0, 0x07, 's', 's', 'h', '-', 'r', 's', 'a' + }; + const unsigned char dss[] = { + 0, 0, 0, 0x07, 's', 's', 'h', '-', 'd', 's', 's' + }; + + if (len < 11) + return LIBSSH2_HOSTKEY_TYPE_UNKNOWN; + + if (!memcmp(rsa, hostkey, 11)) + return LIBSSH2_HOSTKEY_TYPE_RSA; + + if (!memcmp(dss, hostkey, 11)) + return LIBSSH2_HOSTKEY_TYPE_DSS; + + return LIBSSH2_HOSTKEY_TYPE_UNKNOWN; +} + +/* + * libssh2_session_hostkey() + * + * Returns the server key and length. + * + */ +LIBSSH2_API const char * +libssh2_session_hostkey(LIBSSH2_SESSION *session, size_t *len, int *type) +{ + if(session->server_hostkey_len) { + if(len) + *len = session->server_hostkey_len; + if (type) + *type = hostkey_type(session->server_hostkey, + session->server_hostkey_len); + return (char *) session->server_hostkey; + } + if(len) + *len = 0; + return NULL; +} + diff --git a/libssh2/keepalive.c b/libssh2/keepalive.c new file mode 100644 index 0000000..fd749dd --- /dev/null +++ b/libssh2/keepalive.c @@ -0,0 +1,99 @@ +/* Copyright (C) 2010 Simon Josefsson + * Author: Simon Josefsson + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + */ + +#include "libssh2_priv.h" +#include "transport.h" /* _libssh2_transport_write */ + +/* Keep-alive stuff. */ + +LIBSSH2_API void +libssh2_keepalive_config (LIBSSH2_SESSION *session, + int want_reply, + unsigned interval) +{ + if (interval == 1) + session->keepalive_interval = 2; + else + session->keepalive_interval = interval; + session->keepalive_want_reply = want_reply ? 1 : 0; +} + +LIBSSH2_API int +libssh2_keepalive_send (LIBSSH2_SESSION *session, + int *seconds_to_next) +{ + time_t now; + + if (!session->keepalive_interval) { + if (seconds_to_next) + *seconds_to_next = 0; + return 0; + } + + now = time (NULL); + + if (session->keepalive_last_sent + session->keepalive_interval <= now) { + /* Format is + "SSH_MSG_GLOBAL_REQUEST || 4-byte len || str || want-reply". */ + unsigned char keepalive_data[] + = "\x50\x00\x00\x00\x15keepalive@libssh2.orgW"; + size_t len = sizeof (keepalive_data) - 1; + int rc; + + keepalive_data[len - 1] = + (unsigned char)session->keepalive_want_reply; + + rc = _libssh2_transport_send(session, keepalive_data, len, NULL, 0); + /* Silently ignore PACKET_EAGAIN here: if the write buffer is + already full, sending another keepalive is not useful. */ + if (rc && rc != LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send keepalive message"); + return rc; + } + + session->keepalive_last_sent = now; + if (seconds_to_next) + *seconds_to_next = session->keepalive_interval; + } else if (seconds_to_next) { + *seconds_to_next = (int) (session->keepalive_last_sent - now) + + session->keepalive_interval; + } + + return 0; +} diff --git a/libssh2/kex.c b/libssh2/kex.c new file mode 100644 index 0000000..590b30a --- /dev/null +++ b/libssh2/kex.c @@ -0,0 +1,2794 @@ +/* Copyright (c) 2004-2007, Sara Golemon + * Copyright (c) 2010, Daniel Stenberg + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" + +#include "transport.h" +#include "comp.h" +#include "mac.h" + +/* TODO: Switch this to an inline and handle alloc() failures */ +/* Helper macro called from kex_method_diffie_hellman_group1_sha1_key_exchange */ +#define LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(value, reqlen, version) \ + { \ + libssh2_sha1_ctx hash; \ + unsigned long len = 0; \ + if (!(value)) { \ + value = LIBSSH2_ALLOC(session, reqlen + SHA_DIGEST_LENGTH); \ + } \ + if (value) \ + while (len < (unsigned long)reqlen) { \ + libssh2_sha1_init(&hash); \ + libssh2_sha1_update(hash, exchange_state->k_value, \ + exchange_state->k_value_len); \ + libssh2_sha1_update(hash, exchange_state->h_sig_comp, \ + SHA_DIGEST_LENGTH); \ + if (len > 0) { \ + libssh2_sha1_update(hash, value, len); \ + } else { \ + libssh2_sha1_update(hash, (version), 1); \ + libssh2_sha1_update(hash, session->session_id, \ + session->session_id_len); \ + } \ + libssh2_sha1_final(hash, (value) + len); \ + len += SHA_DIGEST_LENGTH; \ + } \ + } + + +/* Helper macro called from kex_method_diffie_hellman_group1_sha256_key_exchange */ +#define LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA256_HASH(value, reqlen, version) \ +{ \ + libssh2_sha256_ctx hash; \ + unsigned long len = 0; \ + if (!(value)) { \ + value = LIBSSH2_ALLOC(session, reqlen + SHA256_DIGEST_LENGTH); \ + } \ + if (value) \ + while (len < (unsigned long)reqlen) { \ + libssh2_sha256_init(&hash); \ + libssh2_sha256_update(hash, exchange_state->k_value, \ + exchange_state->k_value_len); \ + libssh2_sha256_update(hash, exchange_state->h_sig_comp, \ + SHA256_DIGEST_LENGTH); \ + if (len > 0) { \ + libssh2_sha256_update(hash, value, len); \ + } else { \ + libssh2_sha256_update(hash, (version), 1); \ + libssh2_sha256_update(hash, session->session_id, \ + session->session_id_len); \ + } \ + libssh2_sha256_final(hash, (value) + len); \ + len += SHA256_DIGEST_LENGTH; \ + } \ +} + + +/* + * diffie_hellman_sha1 + * + * Diffie Hellman Key Exchange, Group Agnostic + */ +static int diffie_hellman_sha1(LIBSSH2_SESSION *session, + _libssh2_bn *g, + _libssh2_bn *p, + int group_order, + unsigned char packet_type_init, + unsigned char packet_type_reply, + unsigned char *midhash, + unsigned long midhash_len, + kmdhgGPshakex_state_t *exchange_state) +{ + int ret = 0; + int rc; + libssh2_sha1_ctx exchange_hash_ctx; + + if (exchange_state->state == libssh2_NB_state_idle) { + /* Setup initial values */ + exchange_state->e_packet = NULL; + exchange_state->s_packet = NULL; + exchange_state->k_value = NULL; + exchange_state->ctx = _libssh2_bn_ctx_new(); + exchange_state->x = _libssh2_bn_init(); /* Random from client */ + exchange_state->e = _libssh2_bn_init(); /* g^x mod p */ + exchange_state->f = _libssh2_bn_init_from_bin(); /* g^(Random from server) mod p */ + exchange_state->k = _libssh2_bn_init(); /* The shared secret: f^x mod p */ + + /* Zero the whole thing out */ + memset(&exchange_state->req_state, 0, sizeof(packet_require_state_t)); + + /* Generate x and e */ + _libssh2_bn_rand(exchange_state->x, group_order, 0, -1); + _libssh2_bn_mod_exp(exchange_state->e, g, exchange_state->x, p, + exchange_state->ctx); + + /* Send KEX init */ + /* packet_type(1) + String Length(4) + leading 0(1) */ + exchange_state->e_packet_len = + _libssh2_bn_bytes(exchange_state->e) + 6; + if (_libssh2_bn_bits(exchange_state->e) % 8) { + /* Leading 00 not needed */ + exchange_state->e_packet_len--; + } + + exchange_state->e_packet = + LIBSSH2_ALLOC(session, exchange_state->e_packet_len); + if (!exchange_state->e_packet) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Out of memory error"); + goto clean_exit; + } + exchange_state->e_packet[0] = packet_type_init; + _libssh2_htonu32(exchange_state->e_packet + 1, + exchange_state->e_packet_len - 5); + if (_libssh2_bn_bits(exchange_state->e) % 8) { + _libssh2_bn_to_bin(exchange_state->e, + exchange_state->e_packet + 5); + } else { + exchange_state->e_packet[5] = 0; + _libssh2_bn_to_bin(exchange_state->e, + exchange_state->e_packet + 6); + } + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sending KEX packet %d", + (int) packet_type_init); + exchange_state->state = libssh2_NB_state_created; + } + + if (exchange_state->state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, exchange_state->e_packet, + exchange_state->e_packet_len, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + ret = _libssh2_error(session, rc, + "Unable to send KEX init message"); + goto clean_exit; + } + exchange_state->state = libssh2_NB_state_sent; + } + + if (exchange_state->state == libssh2_NB_state_sent) { + if (session->burn_optimistic_kexinit) { + /* The first KEX packet to come along will be the guess initially + * sent by the server. That guess turned out to be wrong so we + * need to silently ignore it */ + int burn_type; + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Waiting for badly guessed KEX packet (to be ignored)"); + burn_type = + _libssh2_packet_burn(session, &exchange_state->burn_state); + if (burn_type == LIBSSH2_ERROR_EAGAIN) { + return burn_type; + } else if (burn_type <= 0) { + /* Failed to receive a packet */ + ret = burn_type; + goto clean_exit; + } + session->burn_optimistic_kexinit = 0; + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Burnt packet of type: %02x", + (unsigned int) burn_type); + } + + exchange_state->state = libssh2_NB_state_sent1; + } + + if (exchange_state->state == libssh2_NB_state_sent1) { + /* Wait for KEX reply */ + rc = _libssh2_packet_require(session, packet_type_reply, + &exchange_state->s_packet, + &exchange_state->s_packet_len, 0, NULL, + 0, &exchange_state->req_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + if (rc) { + ret = _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, + "Timed out waiting for KEX reply"); + goto clean_exit; + } + + /* Parse KEXDH_REPLY */ + exchange_state->s = exchange_state->s_packet + 1; + + session->server_hostkey_len = _libssh2_ntohu32(exchange_state->s); + exchange_state->s += 4; + + if (session->server_hostkey) + LIBSSH2_FREE(session, session->server_hostkey); + + session->server_hostkey = + LIBSSH2_ALLOC(session, session->server_hostkey_len); + if (!session->server_hostkey) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for a copy " + "of the host key"); + goto clean_exit; + } + memcpy(session->server_hostkey, exchange_state->s, + session->server_hostkey_len); + exchange_state->s += session->server_hostkey_len; + +#if LIBSSH2_MD5 + { + libssh2_md5_ctx fingerprint_ctx; + + if (libssh2_md5_init(&fingerprint_ctx)) { + libssh2_md5_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len); + libssh2_md5_final(fingerprint_ctx, + session->server_hostkey_md5); + session->server_hostkey_md5_valid = TRUE; + } + else { + session->server_hostkey_md5_valid = FALSE; + } + } +#ifdef LIBSSH2DEBUG + { + char fingerprint[50], *fprint = fingerprint; + int i; + for(i = 0; i < 16; i++, fprint += 3) { + snprintf(fprint, 4, "%02x:", session->server_hostkey_md5[i]); + } + *(--fprint) = '\0'; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server's MD5 Fingerprint: %s", fingerprint); + } +#endif /* LIBSSH2DEBUG */ +#endif /* ! LIBSSH2_MD5 */ + + { + libssh2_sha1_ctx fingerprint_ctx; + + if (libssh2_sha1_init(&fingerprint_ctx)) { + libssh2_sha1_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len); + libssh2_sha1_final(fingerprint_ctx, + session->server_hostkey_sha1); + session->server_hostkey_sha1_valid = TRUE; + } + else { + session->server_hostkey_sha1_valid = FALSE; + } + } +#ifdef LIBSSH2DEBUG + { + char fingerprint[64], *fprint = fingerprint; + int i; + + for(i = 0; i < 20; i++, fprint += 3) { + snprintf(fprint, 4, "%02x:", session->server_hostkey_sha1[i]); + } + *(--fprint) = '\0'; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server's SHA1 Fingerprint: %s", fingerprint); + } +#endif /* LIBSSH2DEBUG */ + + if (session->hostkey->init(session, session->server_hostkey, + session->server_hostkey_len, + &session->server_hostkey_abstract)) { + ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, + "Unable to initialize hostkey importer"); + goto clean_exit; + } + + exchange_state->f_value_len = _libssh2_ntohu32(exchange_state->s); + exchange_state->s += 4; + exchange_state->f_value = exchange_state->s; + exchange_state->s += exchange_state->f_value_len; + _libssh2_bn_from_bin(exchange_state->f, exchange_state->f_value_len, + exchange_state->f_value); + + exchange_state->h_sig_len = _libssh2_ntohu32(exchange_state->s); + exchange_state->s += 4; + exchange_state->h_sig = exchange_state->s; + + /* Compute the shared secret */ + _libssh2_bn_mod_exp(exchange_state->k, exchange_state->f, + exchange_state->x, p, exchange_state->ctx); + exchange_state->k_value_len = _libssh2_bn_bytes(exchange_state->k) + 5; + if (_libssh2_bn_bits(exchange_state->k) % 8) { + /* don't need leading 00 */ + exchange_state->k_value_len--; + } + exchange_state->k_value = + LIBSSH2_ALLOC(session, exchange_state->k_value_len); + if (!exchange_state->k_value) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate buffer for K"); + goto clean_exit; + } + _libssh2_htonu32(exchange_state->k_value, + exchange_state->k_value_len - 4); + if (_libssh2_bn_bits(exchange_state->k) % 8) { + _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 4); + } else { + exchange_state->k_value[4] = 0; + _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 5); + } + + exchange_state->exchange_hash = (void*)&exchange_hash_ctx; + libssh2_sha1_init(&exchange_hash_ctx); + + if (session->local.banner) { + _libssh2_htonu32(exchange_state->h_sig_comp, + strlen((char *) session->local.banner) - 2); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha1_update(exchange_hash_ctx, + (char *) session->local.banner, + strlen((char *) session->local.banner) - 2); + } else { + _libssh2_htonu32(exchange_state->h_sig_comp, + sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha1_update(exchange_hash_ctx, + LIBSSH2_SSH_DEFAULT_BANNER, + sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); + } + + _libssh2_htonu32(exchange_state->h_sig_comp, + strlen((char *) session->remote.banner)); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha1_update(exchange_hash_ctx, + session->remote.banner, + strlen((char *) session->remote.banner)); + + _libssh2_htonu32(exchange_state->h_sig_comp, + session->local.kexinit_len); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha1_update(exchange_hash_ctx, + session->local.kexinit, + session->local.kexinit_len); + + _libssh2_htonu32(exchange_state->h_sig_comp, + session->remote.kexinit_len); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha1_update(exchange_hash_ctx, + session->remote.kexinit, + session->remote.kexinit_len); + + _libssh2_htonu32(exchange_state->h_sig_comp, + session->server_hostkey_len); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha1_update(exchange_hash_ctx, + session->server_hostkey, + session->server_hostkey_len); + + if (packet_type_init == SSH_MSG_KEX_DH_GEX_INIT) { + /* diffie-hellman-group-exchange hashes additional fields */ +#ifdef LIBSSH2_DH_GEX_NEW + _libssh2_htonu32(exchange_state->h_sig_comp, + LIBSSH2_DH_GEX_MINGROUP); + _libssh2_htonu32(exchange_state->h_sig_comp + 4, + LIBSSH2_DH_GEX_OPTGROUP); + _libssh2_htonu32(exchange_state->h_sig_comp + 8, + LIBSSH2_DH_GEX_MAXGROUP); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 12); +#else + _libssh2_htonu32(exchange_state->h_sig_comp, + LIBSSH2_DH_GEX_OPTGROUP); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); +#endif + } + + if (midhash) { + libssh2_sha1_update(exchange_hash_ctx, midhash, + midhash_len); + } + + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->e_packet + 1, + exchange_state->e_packet_len - 1); + + _libssh2_htonu32(exchange_state->h_sig_comp, + exchange_state->f_value_len); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->f_value, + exchange_state->f_value_len); + + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->k_value, + exchange_state->k_value_len); + + libssh2_sha1_final(exchange_hash_ctx, + exchange_state->h_sig_comp); + + if (session->hostkey-> + sig_verify(session, exchange_state->h_sig, + exchange_state->h_sig_len, exchange_state->h_sig_comp, + 20, &session->server_hostkey_abstract)) { + ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_SIGN, + "Unable to verify hostkey signature"); + goto clean_exit; + } + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sending NEWKEYS message"); + exchange_state->c = SSH_MSG_NEWKEYS; + + exchange_state->state = libssh2_NB_state_sent2; + } + + if (exchange_state->state == libssh2_NB_state_sent2) { + rc = _libssh2_transport_send(session, &exchange_state->c, 1, NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + ret = _libssh2_error(session, rc, "Unable to send NEWKEYS message"); + goto clean_exit; + } + + exchange_state->state = libssh2_NB_state_sent3; + } + + if (exchange_state->state == libssh2_NB_state_sent3) { + rc = _libssh2_packet_require(session, SSH_MSG_NEWKEYS, + &exchange_state->tmp, + &exchange_state->tmp_len, 0, NULL, 0, + &exchange_state->req_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + ret = _libssh2_error(session, rc, "Timed out waiting for NEWKEYS"); + goto clean_exit; + } + /* The first key exchange has been performed, + switch to active crypt/comp/mac mode */ + session->state |= LIBSSH2_STATE_NEWKEYS; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Received NEWKEYS message"); + + /* This will actually end up being just packet_type(1) + for this packet type anyway */ + LIBSSH2_FREE(session, exchange_state->tmp); + + if (!session->session_id) { + session->session_id = LIBSSH2_ALLOC(session, SHA_DIGEST_LENGTH); + if (!session->session_id) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate buffer for SHA digest"); + goto clean_exit; + } + memcpy(session->session_id, exchange_state->h_sig_comp, + SHA_DIGEST_LENGTH); + session->session_id_len = SHA_DIGEST_LENGTH; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "session_id calculated"); + } + + /* Cleanup any existing cipher */ + if (session->local.crypt->dtor) { + session->local.crypt->dtor(session, + &session->local.crypt_abstract); + } + + /* Calculate IV/Secret/Key for each direction */ + if (session->local.crypt->init) { + unsigned char *iv = NULL, *secret = NULL; + int free_iv = 0, free_secret = 0; + + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(iv, + session->local.crypt-> + iv_len, "A"); + if (!iv) { + ret = -1; + goto clean_exit; + } + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(secret, + session->local.crypt-> + secret_len, "C"); + if (!secret) { + LIBSSH2_FREE(session, iv); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + if (session->local.crypt-> + init(session, session->local.crypt, iv, &free_iv, secret, + &free_secret, 1, &session->local.crypt_abstract)) { + LIBSSH2_FREE(session, iv); + LIBSSH2_FREE(session, secret); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + + if (free_iv) { + memset(iv, 0, session->local.crypt->iv_len); + LIBSSH2_FREE(session, iv); + } + + if (free_secret) { + memset(secret, 0, session->local.crypt->secret_len); + LIBSSH2_FREE(session, secret); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Client to Server IV and Key calculated"); + + if (session->remote.crypt->dtor) { + /* Cleanup any existing cipher */ + session->remote.crypt->dtor(session, + &session->remote.crypt_abstract); + } + + if (session->remote.crypt->init) { + unsigned char *iv = NULL, *secret = NULL; + int free_iv = 0, free_secret = 0; + + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(iv, + session->remote.crypt-> + iv_len, "B"); + if (!iv) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(secret, + session->remote.crypt-> + secret_len, "D"); + if (!secret) { + LIBSSH2_FREE(session, iv); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + if (session->remote.crypt-> + init(session, session->remote.crypt, iv, &free_iv, secret, + &free_secret, 0, &session->remote.crypt_abstract)) { + LIBSSH2_FREE(session, iv); + LIBSSH2_FREE(session, secret); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + + if (free_iv) { + memset(iv, 0, session->remote.crypt->iv_len); + LIBSSH2_FREE(session, iv); + } + + if (free_secret) { + memset(secret, 0, session->remote.crypt->secret_len); + LIBSSH2_FREE(session, secret); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server to Client IV and Key calculated"); + + if (session->local.mac->dtor) { + session->local.mac->dtor(session, &session->local.mac_abstract); + } + + if (session->local.mac->init) { + unsigned char *key = NULL; + int free_key = 0; + + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(key, + session->local.mac-> + key_len, "E"); + if (!key) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + session->local.mac->init(session, key, &free_key, + &session->local.mac_abstract); + + if (free_key) { + memset(key, 0, session->local.mac->key_len); + LIBSSH2_FREE(session, key); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Client to Server HMAC Key calculated"); + + if (session->remote.mac->dtor) { + session->remote.mac->dtor(session, &session->remote.mac_abstract); + } + + if (session->remote.mac->init) { + unsigned char *key = NULL; + int free_key = 0; + + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(key, + session->remote.mac-> + key_len, "F"); + if (!key) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + session->remote.mac->init(session, key, &free_key, + &session->remote.mac_abstract); + + if (free_key) { + memset(key, 0, session->remote.mac->key_len); + LIBSSH2_FREE(session, key); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server to Client HMAC Key calculated"); + + /* Initialize compression for each direction */ + + /* Cleanup any existing compression */ + if (session->local.comp && session->local.comp->dtor) { + session->local.comp->dtor(session, 1, + &session->local.comp_abstract); + } + + if (session->local.comp && session->local.comp->init) { + if (session->local.comp->init(session, 1, + &session->local.comp_abstract)) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Client to Server compression initialized"); + + if (session->remote.comp && session->remote.comp->dtor) { + session->remote.comp->dtor(session, 0, + &session->remote.comp_abstract); + } + + if (session->remote.comp && session->remote.comp->init) { + if (session->remote.comp->init(session, 0, + &session->remote.comp_abstract)) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server to Client compression initialized"); + + } + + clean_exit: + _libssh2_bn_free(exchange_state->x); + exchange_state->x = NULL; + _libssh2_bn_free(exchange_state->e); + exchange_state->e = NULL; + _libssh2_bn_free(exchange_state->f); + exchange_state->f = NULL; + _libssh2_bn_free(exchange_state->k); + exchange_state->k = NULL; + _libssh2_bn_ctx_free(exchange_state->ctx); + exchange_state->ctx = NULL; + + if (exchange_state->e_packet) { + LIBSSH2_FREE(session, exchange_state->e_packet); + exchange_state->e_packet = NULL; + } + + if (exchange_state->s_packet) { + LIBSSH2_FREE(session, exchange_state->s_packet); + exchange_state->s_packet = NULL; + } + + if (exchange_state->k_value) { + LIBSSH2_FREE(session, exchange_state->k_value); + exchange_state->k_value = NULL; + } + + exchange_state->state = libssh2_NB_state_idle; + + return ret; +} + + +/* + * diffie_hellman_sha256 + * + * Diffie Hellman Key Exchange, Group Agnostic + */ +static int diffie_hellman_sha256(LIBSSH2_SESSION *session, + _libssh2_bn *g, + _libssh2_bn *p, + int group_order, + unsigned char packet_type_init, + unsigned char packet_type_reply, + unsigned char *midhash, + unsigned long midhash_len, + kmdhgGPshakex_state_t *exchange_state) +{ + int ret = 0; + int rc; + libssh2_sha256_ctx exchange_hash_ctx; + + if (exchange_state->state == libssh2_NB_state_idle) { + /* Setup initial values */ + exchange_state->e_packet = NULL; + exchange_state->s_packet = NULL; + exchange_state->k_value = NULL; + exchange_state->ctx = _libssh2_bn_ctx_new(); + exchange_state->x = _libssh2_bn_init(); /* Random from client */ + exchange_state->e = _libssh2_bn_init(); /* g^x mod p */ + exchange_state->f = _libssh2_bn_init_from_bin(); /* g^(Random from server) mod p */ + exchange_state->k = _libssh2_bn_init(); /* The shared secret: f^x mod p */ + + /* Zero the whole thing out */ + memset(&exchange_state->req_state, 0, sizeof(packet_require_state_t)); + + /* Generate x and e */ + _libssh2_bn_rand(exchange_state->x, group_order, 0, -1); + _libssh2_bn_mod_exp(exchange_state->e, g, exchange_state->x, p, + exchange_state->ctx); + + /* Send KEX init */ + /* packet_type(1) + String Length(4) + leading 0(1) */ + exchange_state->e_packet_len = + _libssh2_bn_bytes(exchange_state->e) + 6; + if (_libssh2_bn_bits(exchange_state->e) % 8) { + /* Leading 00 not needed */ + exchange_state->e_packet_len--; + } + + exchange_state->e_packet = + LIBSSH2_ALLOC(session, exchange_state->e_packet_len); + if (!exchange_state->e_packet) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Out of memory error"); + goto clean_exit; + } + exchange_state->e_packet[0] = packet_type_init; + _libssh2_htonu32(exchange_state->e_packet + 1, + exchange_state->e_packet_len - 5); + if (_libssh2_bn_bits(exchange_state->e) % 8) { + _libssh2_bn_to_bin(exchange_state->e, + exchange_state->e_packet + 5); + } else { + exchange_state->e_packet[5] = 0; + _libssh2_bn_to_bin(exchange_state->e, + exchange_state->e_packet + 6); + } + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sending KEX packet %d", + (int) packet_type_init); + exchange_state->state = libssh2_NB_state_created; + } + + if (exchange_state->state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, exchange_state->e_packet, + exchange_state->e_packet_len, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + ret = _libssh2_error(session, rc, + "Unable to send KEX init message"); + goto clean_exit; + } + exchange_state->state = libssh2_NB_state_sent; + } + + if (exchange_state->state == libssh2_NB_state_sent) { + if (session->burn_optimistic_kexinit) { + /* The first KEX packet to come along will be the guess initially + * sent by the server. That guess turned out to be wrong so we + * need to silently ignore it */ + int burn_type; + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Waiting for badly guessed KEX packet (to be ignored)"); + burn_type = + _libssh2_packet_burn(session, &exchange_state->burn_state); + if (burn_type == LIBSSH2_ERROR_EAGAIN) { + return burn_type; + } else if (burn_type <= 0) { + /* Failed to receive a packet */ + ret = burn_type; + goto clean_exit; + } + session->burn_optimistic_kexinit = 0; + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Burnt packet of type: %02x", + (unsigned int) burn_type); + } + + exchange_state->state = libssh2_NB_state_sent1; + } + + if (exchange_state->state == libssh2_NB_state_sent1) { + /* Wait for KEX reply */ + rc = _libssh2_packet_require(session, packet_type_reply, + &exchange_state->s_packet, + &exchange_state->s_packet_len, 0, NULL, + 0, &exchange_state->req_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + if (rc) { + ret = _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, + "Timed out waiting for KEX reply"); + goto clean_exit; + } + + /* Parse KEXDH_REPLY */ + exchange_state->s = exchange_state->s_packet + 1; + + session->server_hostkey_len = _libssh2_ntohu32(exchange_state->s); + exchange_state->s += 4; + + if (session->server_hostkey) + LIBSSH2_FREE(session, session->server_hostkey); + + session->server_hostkey = + LIBSSH2_ALLOC(session, session->server_hostkey_len); + if (!session->server_hostkey) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for a copy " + "of the host key"); + goto clean_exit; + } + memcpy(session->server_hostkey, exchange_state->s, + session->server_hostkey_len); + exchange_state->s += session->server_hostkey_len; + +#if LIBSSH2_MD5 + { + libssh2_md5_ctx fingerprint_ctx; + + if (libssh2_md5_init(&fingerprint_ctx)) { + libssh2_md5_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len); + libssh2_md5_final(fingerprint_ctx, + session->server_hostkey_md5); + session->server_hostkey_md5_valid = TRUE; + } + else { + session->server_hostkey_md5_valid = FALSE; + } + } +#ifdef LIBSSH2DEBUG + { + char fingerprint[50], *fprint = fingerprint; + int i; + for(i = 0; i < 16; i++, fprint += 3) { + snprintf(fprint, 4, "%02x:", session->server_hostkey_md5[i]); + } + *(--fprint) = '\0'; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server's MD5 Fingerprint: %s", fingerprint); + } +#endif /* LIBSSH2DEBUG */ +#endif /* ! LIBSSH2_MD5 */ + + { + libssh2_sha1_ctx fingerprint_ctx; + + if (libssh2_sha1_init(&fingerprint_ctx)) { + libssh2_sha1_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len); + libssh2_sha1_final(fingerprint_ctx, + session->server_hostkey_sha1); + session->server_hostkey_sha1_valid = TRUE; + } + else { + session->server_hostkey_sha1_valid = FALSE; + } + } +#ifdef LIBSSH2DEBUG + { + char fingerprint[64], *fprint = fingerprint; + int i; + + for(i = 0; i < 20; i++, fprint += 3) { + snprintf(fprint, 4, "%02x:", session->server_hostkey_sha1[i]); + } + *(--fprint) = '\0'; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server's SHA1 Fingerprint: %s", fingerprint); + } +#endif /* LIBSSH2DEBUG */ + + if (session->hostkey->init(session, session->server_hostkey, + session->server_hostkey_len, + &session->server_hostkey_abstract)) { + ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, + "Unable to initialize hostkey importer"); + goto clean_exit; + } + + exchange_state->f_value_len = _libssh2_ntohu32(exchange_state->s); + exchange_state->s += 4; + exchange_state->f_value = exchange_state->s; + exchange_state->s += exchange_state->f_value_len; + _libssh2_bn_from_bin(exchange_state->f, exchange_state->f_value_len, + exchange_state->f_value); + + exchange_state->h_sig_len = _libssh2_ntohu32(exchange_state->s); + exchange_state->s += 4; + exchange_state->h_sig = exchange_state->s; + + /* Compute the shared secret */ + _libssh2_bn_mod_exp(exchange_state->k, exchange_state->f, + exchange_state->x, p, exchange_state->ctx); + exchange_state->k_value_len = _libssh2_bn_bytes(exchange_state->k) + 5; + if (_libssh2_bn_bits(exchange_state->k) % 8) { + /* don't need leading 00 */ + exchange_state->k_value_len--; + } + exchange_state->k_value = + LIBSSH2_ALLOC(session, exchange_state->k_value_len); + if (!exchange_state->k_value) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate buffer for K"); + goto clean_exit; + } + _libssh2_htonu32(exchange_state->k_value, + exchange_state->k_value_len - 4); + if (_libssh2_bn_bits(exchange_state->k) % 8) { + _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 4); + } else { + exchange_state->k_value[4] = 0; + _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 5); + } + + exchange_state->exchange_hash = (void*)&exchange_hash_ctx; + libssh2_sha256_init(&exchange_hash_ctx); + + if (session->local.banner) { + _libssh2_htonu32(exchange_state->h_sig_comp, + strlen((char *) session->local.banner) - 2); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha256_update(exchange_hash_ctx, + (char *) session->local.banner, + strlen((char *) session->local.banner) - 2); + } else { + _libssh2_htonu32(exchange_state->h_sig_comp, + sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha256_update(exchange_hash_ctx, + LIBSSH2_SSH_DEFAULT_BANNER, + sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); + } + + _libssh2_htonu32(exchange_state->h_sig_comp, + strlen((char *) session->remote.banner)); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha256_update(exchange_hash_ctx, + session->remote.banner, + strlen((char *) session->remote.banner)); + + _libssh2_htonu32(exchange_state->h_sig_comp, + session->local.kexinit_len); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha256_update(exchange_hash_ctx, + session->local.kexinit, + session->local.kexinit_len); + + _libssh2_htonu32(exchange_state->h_sig_comp, + session->remote.kexinit_len); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha256_update(exchange_hash_ctx, + session->remote.kexinit, + session->remote.kexinit_len); + + _libssh2_htonu32(exchange_state->h_sig_comp, + session->server_hostkey_len); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha256_update(exchange_hash_ctx, + session->server_hostkey, + session->server_hostkey_len); + + if (packet_type_init == SSH_MSG_KEX_DH_GEX_INIT) { + /* diffie-hellman-group-exchange hashes additional fields */ +#ifdef LIBSSH2_DH_GEX_NEW + _libssh2_htonu32(exchange_state->h_sig_comp, + LIBSSH2_DH_GEX_MINGROUP); + _libssh2_htonu32(exchange_state->h_sig_comp + 4, + LIBSSH2_DH_GEX_OPTGROUP); + _libssh2_htonu32(exchange_state->h_sig_comp + 8, + LIBSSH2_DH_GEX_MAXGROUP); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 12); +#else + _libssh2_htonu32(exchange_state->h_sig_comp, + LIBSSH2_DH_GEX_OPTGROUP); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); +#endif + } + + if (midhash) { + libssh2_sha256_update(exchange_hash_ctx, midhash, + midhash_len); + } + + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->e_packet + 1, + exchange_state->e_packet_len - 1); + + _libssh2_htonu32(exchange_state->h_sig_comp, + exchange_state->f_value_len); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->f_value, + exchange_state->f_value_len); + + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->k_value, + exchange_state->k_value_len); + + libssh2_sha256_final(exchange_hash_ctx, + exchange_state->h_sig_comp); + + if (session->hostkey-> + sig_verify(session, exchange_state->h_sig, + exchange_state->h_sig_len, exchange_state->h_sig_comp, + SHA256_DIGEST_LENGTH, &session->server_hostkey_abstract)) { + ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_SIGN, + "Unable to verify hostkey signature"); + goto clean_exit; + } + + + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sending NEWKEYS message"); + exchange_state->c = SSH_MSG_NEWKEYS; + + exchange_state->state = libssh2_NB_state_sent2; + } + + if (exchange_state->state == libssh2_NB_state_sent2) { + rc = _libssh2_transport_send(session, &exchange_state->c, 1, NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + ret = _libssh2_error(session, rc, "Unable to send NEWKEYS message"); + goto clean_exit; + } + + exchange_state->state = libssh2_NB_state_sent3; + } + + if (exchange_state->state == libssh2_NB_state_sent3) { + rc = _libssh2_packet_require(session, SSH_MSG_NEWKEYS, + &exchange_state->tmp, + &exchange_state->tmp_len, 0, NULL, 0, + &exchange_state->req_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + ret = _libssh2_error(session, rc, "Timed out waiting for NEWKEYS"); + goto clean_exit; + } + /* The first key exchange has been performed, + switch to active crypt/comp/mac mode */ + session->state |= LIBSSH2_STATE_NEWKEYS; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Received NEWKEYS message"); + + /* This will actually end up being just packet_type(1) + for this packet type anyway */ + LIBSSH2_FREE(session, exchange_state->tmp); + + if (!session->session_id) { + session->session_id = LIBSSH2_ALLOC(session, SHA256_DIGEST_LENGTH); + if (!session->session_id) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate buffer for SHA digest"); + goto clean_exit; + } + memcpy(session->session_id, exchange_state->h_sig_comp, + SHA256_DIGEST_LENGTH); + session->session_id_len = SHA256_DIGEST_LENGTH; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "session_id calculated"); + } + + /* Cleanup any existing cipher */ + if (session->local.crypt->dtor) { + session->local.crypt->dtor(session, + &session->local.crypt_abstract); + } + + /* Calculate IV/Secret/Key for each direction */ + if (session->local.crypt->init) { + unsigned char *iv = NULL, *secret = NULL; + int free_iv = 0, free_secret = 0; + + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA256_HASH(iv, + session->local.crypt-> + iv_len, "A"); + if (!iv) { + ret = -1; + goto clean_exit; + } + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA256_HASH(secret, + session->local.crypt-> + secret_len, "C"); + if (!secret) { + LIBSSH2_FREE(session, iv); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + if (session->local.crypt-> + init(session, session->local.crypt, iv, &free_iv, secret, + &free_secret, 1, &session->local.crypt_abstract)) { + LIBSSH2_FREE(session, iv); + LIBSSH2_FREE(session, secret); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + + if (free_iv) { + memset(iv, 0, session->local.crypt->iv_len); + LIBSSH2_FREE(session, iv); + } + + if (free_secret) { + memset(secret, 0, session->local.crypt->secret_len); + LIBSSH2_FREE(session, secret); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Client to Server IV and Key calculated"); + + if (session->remote.crypt->dtor) { + /* Cleanup any existing cipher */ + session->remote.crypt->dtor(session, + &session->remote.crypt_abstract); + } + + if (session->remote.crypt->init) { + unsigned char *iv = NULL, *secret = NULL; + int free_iv = 0, free_secret = 0; + + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA256_HASH(iv, + session->remote.crypt-> + iv_len, "B"); + if (!iv) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA256_HASH(secret, + session->remote.crypt-> + secret_len, "D"); + if (!secret) { + LIBSSH2_FREE(session, iv); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + if (session->remote.crypt-> + init(session, session->remote.crypt, iv, &free_iv, secret, + &free_secret, 0, &session->remote.crypt_abstract)) { + LIBSSH2_FREE(session, iv); + LIBSSH2_FREE(session, secret); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + + if (free_iv) { + memset(iv, 0, session->remote.crypt->iv_len); + LIBSSH2_FREE(session, iv); + } + + if (free_secret) { + memset(secret, 0, session->remote.crypt->secret_len); + LIBSSH2_FREE(session, secret); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server to Client IV and Key calculated"); + + if (session->local.mac->dtor) { + session->local.mac->dtor(session, &session->local.mac_abstract); + } + + if (session->local.mac->init) { + unsigned char *key = NULL; + int free_key = 0; + + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA256_HASH(key, + session->local.mac-> + key_len, "E"); + if (!key) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + session->local.mac->init(session, key, &free_key, + &session->local.mac_abstract); + + if (free_key) { + memset(key, 0, session->local.mac->key_len); + LIBSSH2_FREE(session, key); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Client to Server HMAC Key calculated"); + + if (session->remote.mac->dtor) { + session->remote.mac->dtor(session, &session->remote.mac_abstract); + } + + if (session->remote.mac->init) { + unsigned char *key = NULL; + int free_key = 0; + + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA256_HASH(key, + session->remote.mac-> + key_len, "F"); + if (!key) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + session->remote.mac->init(session, key, &free_key, + &session->remote.mac_abstract); + + if (free_key) { + memset(key, 0, session->remote.mac->key_len); + LIBSSH2_FREE(session, key); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server to Client HMAC Key calculated"); + + /* Initialize compression for each direction */ + + /* Cleanup any existing compression */ + if (session->local.comp && session->local.comp->dtor) { + session->local.comp->dtor(session, 1, + &session->local.comp_abstract); + } + + if (session->local.comp && session->local.comp->init) { + if (session->local.comp->init(session, 1, + &session->local.comp_abstract)) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Client to Server compression initialized"); + + if (session->remote.comp && session->remote.comp->dtor) { + session->remote.comp->dtor(session, 0, + &session->remote.comp_abstract); + } + + if (session->remote.comp && session->remote.comp->init) { + if (session->remote.comp->init(session, 0, + &session->remote.comp_abstract)) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server to Client compression initialized"); + + } + + clean_exit: + _libssh2_bn_free(exchange_state->x); + exchange_state->x = NULL; + _libssh2_bn_free(exchange_state->e); + exchange_state->e = NULL; + _libssh2_bn_free(exchange_state->f); + exchange_state->f = NULL; + _libssh2_bn_free(exchange_state->k); + exchange_state->k = NULL; + _libssh2_bn_ctx_free(exchange_state->ctx); + exchange_state->ctx = NULL; + + if (exchange_state->e_packet) { + LIBSSH2_FREE(session, exchange_state->e_packet); + exchange_state->e_packet = NULL; + } + + if (exchange_state->s_packet) { + LIBSSH2_FREE(session, exchange_state->s_packet); + exchange_state->s_packet = NULL; + } + + if (exchange_state->k_value) { + LIBSSH2_FREE(session, exchange_state->k_value); + exchange_state->k_value = NULL; + } + + exchange_state->state = libssh2_NB_state_idle; + + return ret; +} + + + +/* kex_method_diffie_hellman_group1_sha1_key_exchange + * Diffie-Hellman Group1 (Actually Group2) Key Exchange using SHA1 + */ +static int +kex_method_diffie_hellman_group1_sha1_key_exchange(LIBSSH2_SESSION *session, + key_exchange_state_low_t + * key_state) +{ + static const unsigned char p_value[128] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + }; + + int ret; + + if (key_state->state == libssh2_NB_state_idle) { + /* g == 2 */ + key_state->p = _libssh2_bn_init_from_bin(); /* SSH2 defined value (p_value) */ + key_state->g = _libssh2_bn_init(); /* SSH2 defined value (2) */ + + /* Initialize P and G */ + _libssh2_bn_set_word(key_state->g, 2); + _libssh2_bn_from_bin(key_state->p, 128, p_value); + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Initiating Diffie-Hellman Group1 Key Exchange"); + + key_state->state = libssh2_NB_state_created; + } + ret = diffie_hellman_sha1(session, key_state->g, key_state->p, 128, + SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY, + NULL, 0, &key_state->exchange_state); + if (ret == LIBSSH2_ERROR_EAGAIN) { + return ret; + } + + _libssh2_bn_free(key_state->p); + key_state->p = NULL; + _libssh2_bn_free(key_state->g); + key_state->g = NULL; + key_state->state = libssh2_NB_state_idle; + + return ret; +} + + + +/* kex_method_diffie_hellman_group14_sha1_key_exchange + * Diffie-Hellman Group14 Key Exchange using SHA1 + */ +static int +kex_method_diffie_hellman_group14_sha1_key_exchange(LIBSSH2_SESSION *session, + key_exchange_state_low_t + * key_state) +{ + static const unsigned char p_value[256] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, + 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, + 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, + 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + }; + int ret; + + if (key_state->state == libssh2_NB_state_idle) { + key_state->p = _libssh2_bn_init_from_bin(); /* SSH2 defined value (p_value) */ + key_state->g = _libssh2_bn_init(); /* SSH2 defined value (2) */ + + /* g == 2 */ + /* Initialize P and G */ + _libssh2_bn_set_word(key_state->g, 2); + _libssh2_bn_from_bin(key_state->p, 256, p_value); + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Initiating Diffie-Hellman Group14 Key Exchange"); + + key_state->state = libssh2_NB_state_created; + } + ret = diffie_hellman_sha1(session, key_state->g, key_state->p, + 256, SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY, + NULL, 0, &key_state->exchange_state); + if (ret == LIBSSH2_ERROR_EAGAIN) { + return ret; + } + + key_state->state = libssh2_NB_state_idle; + _libssh2_bn_free(key_state->p); + key_state->p = NULL; + _libssh2_bn_free(key_state->g); + key_state->g = NULL; + + return ret; +} + + + +/* kex_method_diffie_hellman_group_exchange_sha1_key_exchange + * Diffie-Hellman Group Exchange Key Exchange using SHA1 + * Negotiates random(ish) group for secret derivation + */ +static int +kex_method_diffie_hellman_group_exchange_sha1_key_exchange +(LIBSSH2_SESSION * session, key_exchange_state_low_t * key_state) +{ + unsigned long p_len, g_len; + int ret = 0; + int rc; + + if (key_state->state == libssh2_NB_state_idle) { + key_state->p = _libssh2_bn_init_from_bin(); + key_state->g = _libssh2_bn_init_from_bin(); + /* Ask for a P and G pair */ +#ifdef LIBSSH2_DH_GEX_NEW + key_state->request[0] = SSH_MSG_KEX_DH_GEX_REQUEST; + _libssh2_htonu32(key_state->request + 1, LIBSSH2_DH_GEX_MINGROUP); + _libssh2_htonu32(key_state->request + 5, LIBSSH2_DH_GEX_OPTGROUP); + _libssh2_htonu32(key_state->request + 9, LIBSSH2_DH_GEX_MAXGROUP); + key_state->request_len = 13; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Initiating Diffie-Hellman Group-Exchange (New Method)"); +#else + key_state->request[0] = SSH_MSG_KEX_DH_GEX_REQUEST_OLD; + _libssh2_htonu32(key_state->request + 1, LIBSSH2_DH_GEX_OPTGROUP); + key_state->request_len = 5; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Initiating Diffie-Hellman Group-Exchange (Old Method)"); +#endif + + key_state->state = libssh2_NB_state_created; + } + + if (key_state->state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, key_state->request, + key_state->request_len, NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + ret = _libssh2_error(session, rc, + "Unable to send Group Exchange Request"); + goto dh_gex_clean_exit; + } + + key_state->state = libssh2_NB_state_sent; + } + + if (key_state->state == libssh2_NB_state_sent) { + rc = _libssh2_packet_require(session, SSH_MSG_KEX_DH_GEX_GROUP, + &key_state->data, &key_state->data_len, + 0, NULL, 0, &key_state->req_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + ret = _libssh2_error(session, rc, + "Timeout waiting for GEX_GROUP reply"); + goto dh_gex_clean_exit; + } + + key_state->state = libssh2_NB_state_sent1; + } + + if (key_state->state == libssh2_NB_state_sent1) { + unsigned char *s = key_state->data + 1; + p_len = _libssh2_ntohu32(s); + s += 4; + _libssh2_bn_from_bin(key_state->p, p_len, s); + s += p_len; + + g_len = _libssh2_ntohu32(s); + s += 4; + _libssh2_bn_from_bin(key_state->g, g_len, s); + + ret = diffie_hellman_sha1(session, key_state->g, key_state->p, p_len, + SSH_MSG_KEX_DH_GEX_INIT, + SSH_MSG_KEX_DH_GEX_REPLY, + key_state->data + 1, + key_state->data_len - 1, + &key_state->exchange_state); + if (ret == LIBSSH2_ERROR_EAGAIN) { + return ret; + } + + LIBSSH2_FREE(session, key_state->data); + } + + dh_gex_clean_exit: + key_state->state = libssh2_NB_state_idle; + _libssh2_bn_free(key_state->g); + key_state->g = NULL; + _libssh2_bn_free(key_state->p); + key_state->p = NULL; + + return ret; +} + + + +/* kex_method_diffie_hellman_group_exchange_sha256_key_exchange + * Diffie-Hellman Group Exchange Key Exchange using SHA256 + * Negotiates random(ish) group for secret derivation + */ +static int +kex_method_diffie_hellman_group_exchange_sha256_key_exchange +(LIBSSH2_SESSION * session, key_exchange_state_low_t * key_state) +{ + unsigned long p_len, g_len; + int ret = 0; + int rc; + + if (key_state->state == libssh2_NB_state_idle) { + key_state->p = _libssh2_bn_init(); + key_state->g = _libssh2_bn_init(); + /* Ask for a P and G pair */ +#ifdef LIBSSH2_DH_GEX_NEW + key_state->request[0] = SSH_MSG_KEX_DH_GEX_REQUEST; + _libssh2_htonu32(key_state->request + 1, LIBSSH2_DH_GEX_MINGROUP); + _libssh2_htonu32(key_state->request + 5, LIBSSH2_DH_GEX_OPTGROUP); + _libssh2_htonu32(key_state->request + 9, LIBSSH2_DH_GEX_MAXGROUP); + key_state->request_len = 13; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Initiating Diffie-Hellman Group-Exchange (New Method SHA256)"); +#else + key_state->request[0] = SSH_MSG_KEX_DH_GEX_REQUEST_OLD; + _libssh2_htonu32(key_state->request + 1, LIBSSH2_DH_GEX_OPTGROUP); + key_state->request_len = 5; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Initiating Diffie-Hellman Group-Exchange (Old Method SHA256)"); +#endif + + key_state->state = libssh2_NB_state_created; + } + + if (key_state->state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, key_state->request, + key_state->request_len, NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + ret = _libssh2_error(session, rc, + "Unable to send Group Exchange Request SHA256"); + goto dh_gex_clean_exit; + } + + key_state->state = libssh2_NB_state_sent; + } + + if (key_state->state == libssh2_NB_state_sent) { + rc = _libssh2_packet_require(session, SSH_MSG_KEX_DH_GEX_GROUP, + &key_state->data, &key_state->data_len, + 0, NULL, 0, &key_state->req_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + ret = _libssh2_error(session, rc, + "Timeout waiting for GEX_GROUP reply SHA256"); + goto dh_gex_clean_exit; + } + + key_state->state = libssh2_NB_state_sent1; + } + + if (key_state->state == libssh2_NB_state_sent1) { + unsigned char *s = key_state->data + 1; + p_len = _libssh2_ntohu32(s); + s += 4; + _libssh2_bn_from_bin(key_state->p, p_len, s); + s += p_len; + + g_len = _libssh2_ntohu32(s); + s += 4; + _libssh2_bn_from_bin(key_state->g, g_len, s); + + ret = diffie_hellman_sha256(session, key_state->g, key_state->p, p_len, + SSH_MSG_KEX_DH_GEX_INIT, + SSH_MSG_KEX_DH_GEX_REPLY, + key_state->data + 1, + key_state->data_len - 1, + &key_state->exchange_state); + if (ret == LIBSSH2_ERROR_EAGAIN) { + return ret; + } + + LIBSSH2_FREE(session, key_state->data); + } + + dh_gex_clean_exit: + key_state->state = libssh2_NB_state_idle; + _libssh2_bn_free(key_state->g); + key_state->g = NULL; + _libssh2_bn_free(key_state->p); + key_state->p = NULL; + + return ret; +} + + +#define LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY 0x0001 +#define LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY 0x0002 + +static const LIBSSH2_KEX_METHOD kex_method_diffie_helman_group1_sha1 = { + "diffie-hellman-group1-sha1", + kex_method_diffie_hellman_group1_sha1_key_exchange, + LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, +}; + +static const LIBSSH2_KEX_METHOD kex_method_diffie_helman_group14_sha1 = { + "diffie-hellman-group14-sha1", + kex_method_diffie_hellman_group14_sha1_key_exchange, + LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, +}; + +static const LIBSSH2_KEX_METHOD +kex_method_diffie_helman_group_exchange_sha1 = { + "diffie-hellman-group-exchange-sha1", + kex_method_diffie_hellman_group_exchange_sha1_key_exchange, + LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, +}; + +static const LIBSSH2_KEX_METHOD +kex_method_diffie_helman_group_exchange_sha256 = { + "diffie-hellman-group-exchange-sha256", + kex_method_diffie_hellman_group_exchange_sha256_key_exchange, + LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, +}; + +static const LIBSSH2_KEX_METHOD *libssh2_kex_methods[] = { + &kex_method_diffie_helman_group_exchange_sha256, + &kex_method_diffie_helman_group_exchange_sha1, + &kex_method_diffie_helman_group14_sha1, + &kex_method_diffie_helman_group1_sha1, + NULL +}; + +typedef struct _LIBSSH2_COMMON_METHOD +{ + const char *name; +} LIBSSH2_COMMON_METHOD; + +/* kex_method_strlen + * Calculate the length of a particular method list's resulting string + * Includes SUM(strlen() of each individual method plus 1 (for coma)) - 1 (because the last coma isn't used) + * Another sign of bad coding practices gone mad. Pretend you don't see this. + */ +static size_t +kex_method_strlen(LIBSSH2_COMMON_METHOD ** method) +{ + size_t len = 0; + + if (!method || !*method) { + return 0; + } + + while (*method && (*method)->name) { + len += strlen((*method)->name) + 1; + method++; + } + + return len - 1; +} + + + +/* kex_method_list + * Generate formatted preference list in buf + */ +static size_t +kex_method_list(unsigned char *buf, size_t list_strlen, + LIBSSH2_COMMON_METHOD ** method) +{ + _libssh2_htonu32(buf, list_strlen); + buf += 4; + + if (!method || !*method) { + return 4; + } + + while (*method && (*method)->name) { + int mlen = strlen((*method)->name); + memcpy(buf, (*method)->name, mlen); + buf += mlen; + *(buf++) = ','; + method++; + } + + return list_strlen + 4; +} + + + +#define LIBSSH2_METHOD_PREFS_LEN(prefvar, defaultvar) \ + ((prefvar) ? strlen(prefvar) : \ + kex_method_strlen((LIBSSH2_COMMON_METHOD**)(defaultvar))) + +#define LIBSSH2_METHOD_PREFS_STR(buf, prefvarlen, prefvar, defaultvar) \ + if (prefvar) { \ + _libssh2_htonu32((buf), (prefvarlen)); \ + buf += 4; \ + memcpy((buf), (prefvar), (prefvarlen)); \ + buf += (prefvarlen); \ + } else { \ + buf += kex_method_list((buf), (prefvarlen), \ + (LIBSSH2_COMMON_METHOD**)(defaultvar)); \ + } + +/* kexinit + * Send SSH_MSG_KEXINIT packet + */ +static int kexinit(LIBSSH2_SESSION * session) +{ + /* 62 = packet_type(1) + cookie(16) + first_packet_follows(1) + + reserved(4) + length longs(40) */ + size_t data_len = 62; + size_t kex_len, hostkey_len = 0; + size_t crypt_cs_len, crypt_sc_len; + size_t comp_cs_len, comp_sc_len; + size_t mac_cs_len, mac_sc_len; + size_t lang_cs_len, lang_sc_len; + unsigned char *data, *s; + int rc; + + if (session->kexinit_state == libssh2_NB_state_idle) { + kex_len = + LIBSSH2_METHOD_PREFS_LEN(session->kex_prefs, libssh2_kex_methods); + hostkey_len = + LIBSSH2_METHOD_PREFS_LEN(session->hostkey_prefs, + libssh2_hostkey_methods()); + crypt_cs_len = + LIBSSH2_METHOD_PREFS_LEN(session->local.crypt_prefs, + libssh2_crypt_methods()); + crypt_sc_len = + LIBSSH2_METHOD_PREFS_LEN(session->remote.crypt_prefs, + libssh2_crypt_methods()); + mac_cs_len = + LIBSSH2_METHOD_PREFS_LEN(session->local.mac_prefs, + _libssh2_mac_methods()); + mac_sc_len = + LIBSSH2_METHOD_PREFS_LEN(session->remote.mac_prefs, + _libssh2_mac_methods()); + comp_cs_len = + LIBSSH2_METHOD_PREFS_LEN(session->local.comp_prefs, + _libssh2_comp_methods(session)); + comp_sc_len = + LIBSSH2_METHOD_PREFS_LEN(session->remote.comp_prefs, + _libssh2_comp_methods(session)); + lang_cs_len = + LIBSSH2_METHOD_PREFS_LEN(session->local.lang_prefs, NULL); + lang_sc_len = + LIBSSH2_METHOD_PREFS_LEN(session->remote.lang_prefs, NULL); + + data_len += kex_len + hostkey_len + crypt_cs_len + crypt_sc_len + + comp_cs_len + comp_sc_len + mac_cs_len + mac_sc_len + + lang_cs_len + lang_sc_len; + + s = data = LIBSSH2_ALLOC(session, data_len); + if (!data) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory"); + } + + *(s++) = SSH_MSG_KEXINIT; + + _libssh2_random(s, 16); + s += 16; + + /* Ennumerating through these lists twice is probably (certainly?) + inefficient from a CPU standpoint, but it saves multiple + malloc/realloc calls */ + LIBSSH2_METHOD_PREFS_STR(s, kex_len, session->kex_prefs, + libssh2_kex_methods); + LIBSSH2_METHOD_PREFS_STR(s, hostkey_len, session->hostkey_prefs, + libssh2_hostkey_methods()); + LIBSSH2_METHOD_PREFS_STR(s, crypt_cs_len, session->local.crypt_prefs, + libssh2_crypt_methods()); + LIBSSH2_METHOD_PREFS_STR(s, crypt_sc_len, session->remote.crypt_prefs, + libssh2_crypt_methods()); + LIBSSH2_METHOD_PREFS_STR(s, mac_cs_len, session->local.mac_prefs, + _libssh2_mac_methods()); + LIBSSH2_METHOD_PREFS_STR(s, mac_sc_len, session->remote.mac_prefs, + _libssh2_mac_methods()); + LIBSSH2_METHOD_PREFS_STR(s, comp_cs_len, session->local.comp_prefs, + _libssh2_comp_methods(session)); + LIBSSH2_METHOD_PREFS_STR(s, comp_sc_len, session->remote.comp_prefs, + _libssh2_comp_methods(session)); + LIBSSH2_METHOD_PREFS_STR(s, lang_cs_len, session->local.lang_prefs, + NULL); + LIBSSH2_METHOD_PREFS_STR(s, lang_sc_len, session->remote.lang_prefs, + NULL); + + /* No optimistic KEX packet follows */ + /* Deal with optimistic packets + * session->flags |= KEXINIT_OPTIMISTIC + * session->flags |= KEXINIT_METHODSMATCH + */ + *(s++) = 0; + + /* Reserved == 0 */ + _libssh2_htonu32(s, 0); + +#ifdef LIBSSH2DEBUG + { + /* Funnily enough, they'll all "appear" to be '\0' terminated */ + unsigned char *p = data + 21; /* type(1) + cookie(16) + len(4) */ + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent KEX: %s", p); + p += kex_len + 4; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent HOSTKEY: %s", p); + p += hostkey_len + 4; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent CRYPT_CS: %s", p); + p += crypt_cs_len + 4; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent CRYPT_SC: %s", p); + p += crypt_sc_len + 4; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent MAC_CS: %s", p); + p += mac_cs_len + 4; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent MAC_SC: %s", p); + p += mac_sc_len + 4; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent COMP_CS: %s", p); + p += comp_cs_len + 4; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent COMP_SC: %s", p); + p += comp_sc_len + 4; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent LANG_CS: %s", p); + p += lang_cs_len + 4; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent LANG_SC: %s", p); + p += lang_sc_len + 4; + } +#endif /* LIBSSH2DEBUG */ + + session->kexinit_state = libssh2_NB_state_created; + } else { + data = session->kexinit_data; + data_len = session->kexinit_data_len; + /* zap the variables to ensure there is NOT a double free later */ + session->kexinit_data = NULL; + session->kexinit_data_len = 0; + } + + rc = _libssh2_transport_send(session, data, data_len, NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + session->kexinit_data = data; + session->kexinit_data_len = data_len; + return rc; + } + else if (rc) { + LIBSSH2_FREE(session, data); + session->kexinit_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Unable to send KEXINIT packet to remote host"); + + } + + if (session->local.kexinit) { + LIBSSH2_FREE(session, session->local.kexinit); + } + + session->local.kexinit = data; + session->local.kexinit_len = data_len; + + session->kexinit_state = libssh2_NB_state_idle; + + return 0; +} + +/* kex_agree_instr + * Kex specific variant of strstr() + * Needle must be preceed by BOL or ',', and followed by ',' or EOL + */ +static unsigned char * +kex_agree_instr(unsigned char *haystack, unsigned long haystack_len, + const unsigned char *needle, unsigned long needle_len) +{ + unsigned char *s; + + /* Haystack too short to bother trying */ + if (haystack_len < needle_len) { + return NULL; + } + + /* Needle at start of haystack */ + if ((strncmp((char *) haystack, (char *) needle, needle_len) == 0) && + (needle_len == haystack_len || haystack[needle_len] == ',')) { + return haystack; + } + + s = haystack; + /* Search until we run out of comas or we run out of haystack, + whichever comes first */ + while ((s = (unsigned char *) strchr((char *) s, ',')) + && ((haystack_len - (s - haystack)) > needle_len)) { + s++; + /* Needle at X position */ + if ((strncmp((char *) s, (char *) needle, needle_len) == 0) && + (((s - haystack) + needle_len) == haystack_len + || s[needle_len] == ',')) { + return s; + } + } + + return NULL; +} + + + +/* kex_get_method_by_name + */ +static const LIBSSH2_COMMON_METHOD * +kex_get_method_by_name(const char *name, size_t name_len, + const LIBSSH2_COMMON_METHOD ** methodlist) +{ + while (*methodlist) { + if ((strlen((*methodlist)->name) == name_len) && + (strncmp((*methodlist)->name, name, name_len) == 0)) { + return *methodlist; + } + methodlist++; + } + return NULL; +} + + + +/* kex_agree_hostkey + * Agree on a Hostkey which works with this kex + */ +static int kex_agree_hostkey(LIBSSH2_SESSION * session, + unsigned long kex_flags, + unsigned char *hostkey, unsigned long hostkey_len) +{ + const LIBSSH2_HOSTKEY_METHOD **hostkeyp = libssh2_hostkey_methods(); + unsigned char *s; + + if (session->hostkey_prefs) { + s = (unsigned char *) session->hostkey_prefs; + + while (s && *s) { + unsigned char *p = (unsigned char *) strchr((char *) s, ','); + size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s)); + if (kex_agree_instr(hostkey, hostkey_len, s, method_len)) { + const LIBSSH2_HOSTKEY_METHOD *method = + (const LIBSSH2_HOSTKEY_METHOD *) + kex_get_method_by_name((char *) s, method_len, + (const LIBSSH2_COMMON_METHOD **) + hostkeyp); + + if (!method) { + /* Invalid method -- Should never be reached */ + return -1; + } + + /* So far so good, but does it suit our purposes? (Encrypting + vs Signing) */ + if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY) == + 0) || (method->encrypt)) { + /* Either this hostkey can do encryption or this kex just + doesn't require it */ + if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY) + == 0) || (method->sig_verify)) { + /* Either this hostkey can do signing or this kex just + doesn't require it */ + session->hostkey = method; + return 0; + } + } + } + + s = p ? p + 1 : NULL; + } + return -1; + } + + while (hostkeyp && (*hostkeyp) && (*hostkeyp)->name) { + s = kex_agree_instr(hostkey, hostkey_len, + (unsigned char *) (*hostkeyp)->name, + strlen((*hostkeyp)->name)); + if (s) { + /* So far so good, but does it suit our purposes? (Encrypting vs + Signing) */ + if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY) == 0) || + ((*hostkeyp)->encrypt)) { + /* Either this hostkey can do encryption or this kex just + doesn't require it */ + if (((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY) == + 0) || ((*hostkeyp)->sig_verify)) { + /* Either this hostkey can do signing or this kex just + doesn't require it */ + session->hostkey = *hostkeyp; + return 0; + } + } + } + hostkeyp++; + } + + return -1; +} + + + +/* kex_agree_kex_hostkey + * Agree on a Key Exchange method and a hostkey encoding type + */ +static int kex_agree_kex_hostkey(LIBSSH2_SESSION * session, unsigned char *kex, + unsigned long kex_len, unsigned char *hostkey, + unsigned long hostkey_len) +{ + const LIBSSH2_KEX_METHOD **kexp = libssh2_kex_methods; + unsigned char *s; + + if (session->kex_prefs) { + s = (unsigned char *) session->kex_prefs; + + while (s && *s) { + unsigned char *q, *p = (unsigned char *) strchr((char *) s, ','); + size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s)); + if ((q = kex_agree_instr(kex, kex_len, s, method_len))) { + const LIBSSH2_KEX_METHOD *method = (const LIBSSH2_KEX_METHOD *) + kex_get_method_by_name((char *) s, method_len, + (const LIBSSH2_COMMON_METHOD **) + kexp); + + if (!method) { + /* Invalid method -- Should never be reached */ + return -1; + } + + /* We've agreed on a key exchange method, + * Can we agree on a hostkey that works with this kex? + */ + if (kex_agree_hostkey(session, method->flags, hostkey, + hostkey_len) == 0) { + session->kex = method; + if (session->burn_optimistic_kexinit && (kex == q)) { + /* Server sent an optimistic packet, + * and client agrees with preference + * cancel burning the first KEX_INIT packet that comes in */ + session->burn_optimistic_kexinit = 0; + } + return 0; + } + } + + s = p ? p + 1 : NULL; + } + return -1; + } + + while (*kexp && (*kexp)->name) { + s = kex_agree_instr(kex, kex_len, + (unsigned char *) (*kexp)->name, + strlen((*kexp)->name)); + if (s) { + /* We've agreed on a key exchange method, + * Can we agree on a hostkey that works with this kex? + */ + if (kex_agree_hostkey(session, (*kexp)->flags, hostkey, + hostkey_len) == 0) { + session->kex = *kexp; + if (session->burn_optimistic_kexinit && (kex == s)) { + /* Server sent an optimistic packet, + * and client agrees with preference + * cancel burning the first KEX_INIT packet that comes in */ + session->burn_optimistic_kexinit = 0; + } + return 0; + } + } + kexp++; + } + return -1; +} + + + +/* kex_agree_crypt + * Agree on a cipher algo + */ +static int kex_agree_crypt(LIBSSH2_SESSION * session, + libssh2_endpoint_data *endpoint, + unsigned char *crypt, + unsigned long crypt_len) +{ + const LIBSSH2_CRYPT_METHOD **cryptp = libssh2_crypt_methods(); + unsigned char *s; + + (void) session; + + if (endpoint->crypt_prefs) { + s = (unsigned char *) endpoint->crypt_prefs; + + while (s && *s) { + unsigned char *p = (unsigned char *) strchr((char *) s, ','); + size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s)); + + if (kex_agree_instr(crypt, crypt_len, s, method_len)) { + const LIBSSH2_CRYPT_METHOD *method = + (const LIBSSH2_CRYPT_METHOD *) + kex_get_method_by_name((char *) s, method_len, + (const LIBSSH2_COMMON_METHOD **) + cryptp); + + if (!method) { + /* Invalid method -- Should never be reached */ + return -1; + } + + endpoint->crypt = method; + return 0; + } + + s = p ? p + 1 : NULL; + } + return -1; + } + + while (*cryptp && (*cryptp)->name) { + s = kex_agree_instr(crypt, crypt_len, + (unsigned char *) (*cryptp)->name, + strlen((*cryptp)->name)); + if (s) { + endpoint->crypt = *cryptp; + return 0; + } + cryptp++; + } + + return -1; +} + + + +/* kex_agree_mac + * Agree on a message authentication hash + */ +static int kex_agree_mac(LIBSSH2_SESSION * session, + libssh2_endpoint_data * endpoint, unsigned char *mac, + unsigned long mac_len) +{ + const LIBSSH2_MAC_METHOD **macp = _libssh2_mac_methods(); + unsigned char *s; + (void) session; + + if (endpoint->mac_prefs) { + s = (unsigned char *) endpoint->mac_prefs; + + while (s && *s) { + unsigned char *p = (unsigned char *) strchr((char *) s, ','); + size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s)); + + if (kex_agree_instr(mac, mac_len, s, method_len)) { + const LIBSSH2_MAC_METHOD *method = (const LIBSSH2_MAC_METHOD *) + kex_get_method_by_name((char *) s, method_len, + (const LIBSSH2_COMMON_METHOD **) + macp); + + if (!method) { + /* Invalid method -- Should never be reached */ + return -1; + } + + endpoint->mac = method; + return 0; + } + + s = p ? p + 1 : NULL; + } + return -1; + } + + while (*macp && (*macp)->name) { + s = kex_agree_instr(mac, mac_len, (unsigned char *) (*macp)->name, + strlen((*macp)->name)); + if (s) { + endpoint->mac = *macp; + return 0; + } + macp++; + } + + return -1; +} + + + +/* kex_agree_comp + * Agree on a compression scheme + */ +static int kex_agree_comp(LIBSSH2_SESSION *session, + libssh2_endpoint_data *endpoint, unsigned char *comp, + unsigned long comp_len) +{ + const LIBSSH2_COMP_METHOD **compp = _libssh2_comp_methods(session); + unsigned char *s; + (void) session; + + if (endpoint->comp_prefs) { + s = (unsigned char *) endpoint->comp_prefs; + + while (s && *s) { + unsigned char *p = (unsigned char *) strchr((char *) s, ','); + size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s)); + + if (kex_agree_instr(comp, comp_len, s, method_len)) { + const LIBSSH2_COMP_METHOD *method = + (const LIBSSH2_COMP_METHOD *) + kex_get_method_by_name((char *) s, method_len, + (const LIBSSH2_COMMON_METHOD **) + compp); + + if (!method) { + /* Invalid method -- Should never be reached */ + return -1; + } + + endpoint->comp = method; + return 0; + } + + s = p ? p + 1 : NULL; + } + return -1; + } + + while (*compp && (*compp)->name) { + s = kex_agree_instr(comp, comp_len, (unsigned char *) (*compp)->name, + strlen((*compp)->name)); + if (s) { + endpoint->comp = *compp; + return 0; + } + compp++; + } + + return -1; +} + + + +/* TODO: When in server mode we need to turn this logic on its head + * The Client gets to make the final call on "agreed methods" + */ + +/* + * kex_string_pair() extracts a string from the packet and makes sure it fits + * within the given packet. + */ +static int kex_string_pair(unsigned char **sp, /* parsing position */ + unsigned char *data, /* start pointer to packet */ + size_t data_len, /* size of total packet */ + size_t *lenp, /* length of the string */ + unsigned char **strp) /* pointer to string start */ +{ + unsigned char *s = *sp; + *lenp = _libssh2_ntohu32(s); + + /* the length of the string must fit within the current pointer and the + end of the packet */ + if (*lenp > (data_len - (s - data) -4)) + return 1; + *strp = s + 4; + s += 4 + *lenp; + + *sp = s; + return 0; +} + +/* kex_agree_methods + * Decide which specific method to use of the methods offered by each party + */ +static int kex_agree_methods(LIBSSH2_SESSION * session, unsigned char *data, + unsigned data_len) +{ + unsigned char *kex, *hostkey, *crypt_cs, *crypt_sc, *comp_cs, *comp_sc, + *mac_cs, *mac_sc; + size_t kex_len, hostkey_len, crypt_cs_len, crypt_sc_len, comp_cs_len; + size_t comp_sc_len, mac_cs_len, mac_sc_len; + unsigned char *s = data; + + /* Skip packet_type, we know it already */ + s++; + + /* Skip cookie, don't worry, it's preserved in the kexinit field */ + s += 16; + + /* Locate each string */ + if(kex_string_pair(&s, data, data_len, &kex_len, &kex)) + return -1; + if(kex_string_pair(&s, data, data_len, &hostkey_len, &hostkey)) + return -1; + if(kex_string_pair(&s, data, data_len, &crypt_cs_len, &crypt_cs)) + return -1; + if(kex_string_pair(&s, data, data_len, &crypt_sc_len, &crypt_sc)) + return -1; + if(kex_string_pair(&s, data, data_len, &mac_cs_len, &mac_cs)) + return -1; + if(kex_string_pair(&s, data, data_len, &mac_sc_len, &mac_sc)) + return -1; + if(kex_string_pair(&s, data, data_len, &comp_cs_len, &comp_cs)) + return -1; + if(kex_string_pair(&s, data, data_len, &comp_sc_len, &comp_sc)) + return -1; + + /* If the server sent an optimistic packet, assume that it guessed wrong. + * If the guess is determined to be right (by kex_agree_kex_hostkey) + * This flag will be reset to zero so that it's not ignored */ + session->burn_optimistic_kexinit = *(s++); + /* Next uint32 in packet is all zeros (reserved) */ + + if (data_len < (unsigned) (s - data)) + return -1; /* short packet */ + + if (kex_agree_kex_hostkey(session, kex, kex_len, hostkey, hostkey_len)) { + return -1; + } + + if (kex_agree_crypt(session, &session->local, crypt_cs, crypt_cs_len) + || kex_agree_crypt(session, &session->remote, crypt_sc, crypt_sc_len)) { + return -1; + } + + if (kex_agree_mac(session, &session->local, mac_cs, mac_cs_len) || + kex_agree_mac(session, &session->remote, mac_sc, mac_sc_len)) { + return -1; + } + + if (kex_agree_comp(session, &session->local, comp_cs, comp_cs_len) || + kex_agree_comp(session, &session->remote, comp_sc, comp_sc_len)) { + return -1; + } + +#if 0 + if (libssh2_kex_agree_lang(session, &session->local, lang_cs, lang_cs_len) + || libssh2_kex_agree_lang(session, &session->remote, lang_sc, + lang_sc_len)) { + return -1; + } +#endif + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on KEX method: %s", + session->kex->name); + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on HOSTKEY method: %s", + session->hostkey->name); + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on CRYPT_CS method: %s", + session->local.crypt->name); + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on CRYPT_SC method: %s", + session->remote.crypt->name); + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on MAC_CS method: %s", + session->local.mac->name); + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on MAC_SC method: %s", + session->remote.mac->name); + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on COMP_CS method: %s", + session->local.comp->name); + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on COMP_SC method: %s", + session->remote.comp->name); + + return 0; +} + + + +/* _libssh2_kex_exchange + * Exchange keys + * Returns 0 on success, non-zero on failure + * + * Returns some errors without _libssh2_error() + */ +int +_libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange, + key_exchange_state_t * key_state) +{ + int rc = 0; + int retcode; + + session->state |= LIBSSH2_STATE_KEX_ACTIVE; + + if (key_state->state == libssh2_NB_state_idle) { + /* Prevent loop in packet_add() */ + session->state |= LIBSSH2_STATE_EXCHANGING_KEYS; + + if (reexchange) { + session->kex = NULL; + + if (session->hostkey && session->hostkey->dtor) { + session->hostkey->dtor(session, + &session->server_hostkey_abstract); + } + session->hostkey = NULL; + } + + key_state->state = libssh2_NB_state_created; + } + + if (!session->kex || !session->hostkey) { + if (key_state->state == libssh2_NB_state_created) { + /* Preserve in case of failure */ + key_state->oldlocal = session->local.kexinit; + key_state->oldlocal_len = session->local.kexinit_len; + + session->local.kexinit = NULL; + + key_state->state = libssh2_NB_state_sent; + } + + if (key_state->state == libssh2_NB_state_sent) { + retcode = kexinit(session); + if (retcode == LIBSSH2_ERROR_EAGAIN) { + session->state &= ~LIBSSH2_STATE_KEX_ACTIVE; + return retcode; + } else if (retcode) { + session->local.kexinit = key_state->oldlocal; + session->local.kexinit_len = key_state->oldlocal_len; + key_state->state = libssh2_NB_state_idle; + session->state &= ~LIBSSH2_STATE_KEX_ACTIVE; + session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS; + return -1; + } + + key_state->state = libssh2_NB_state_sent1; + } + + if (key_state->state == libssh2_NB_state_sent1) { + retcode = + _libssh2_packet_require(session, SSH_MSG_KEXINIT, + &key_state->data, + &key_state->data_len, 0, NULL, 0, + &key_state->req_state); + if (retcode == LIBSSH2_ERROR_EAGAIN) { + session->state &= ~LIBSSH2_STATE_KEX_ACTIVE; + return retcode; + } + else if (retcode) { + if (session->local.kexinit) { + LIBSSH2_FREE(session, session->local.kexinit); + } + session->local.kexinit = key_state->oldlocal; + session->local.kexinit_len = key_state->oldlocal_len; + key_state->state = libssh2_NB_state_idle; + session->state &= ~LIBSSH2_STATE_KEX_ACTIVE; + session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS; + return -1; + } + + if (session->remote.kexinit) { + LIBSSH2_FREE(session, session->remote.kexinit); + } + session->remote.kexinit = key_state->data; + session->remote.kexinit_len = key_state->data_len; + + if (kex_agree_methods(session, key_state->data, + key_state->data_len)) + rc = LIBSSH2_ERROR_KEX_FAILURE; + + key_state->state = libssh2_NB_state_sent2; + } + } else { + key_state->state = libssh2_NB_state_sent2; + } + + if (rc == 0 && session->kex) { + if (key_state->state == libssh2_NB_state_sent2) { + retcode = session->kex->exchange_keys(session, + &key_state->key_state_low); + if (retcode == LIBSSH2_ERROR_EAGAIN) { + session->state &= ~LIBSSH2_STATE_KEX_ACTIVE; + return retcode; + } else if (retcode) { + rc = _libssh2_error(session, LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE, + "Unrecoverable error exchanging keys"); + } + } + } + + /* Done with kexinit buffers */ + if (session->local.kexinit) { + LIBSSH2_FREE(session, session->local.kexinit); + session->local.kexinit = NULL; + } + if (session->remote.kexinit) { + LIBSSH2_FREE(session, session->remote.kexinit); + session->remote.kexinit = NULL; + } + + session->state &= ~LIBSSH2_STATE_KEX_ACTIVE; + session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS; + + key_state->state = libssh2_NB_state_idle; + + return rc; +} + + + +/* libssh2_session_method_pref + * Set preferred method + */ +LIBSSH2_API int +libssh2_session_method_pref(LIBSSH2_SESSION * session, int method_type, + const char *prefs) +{ + char **prefvar, *s, *newprefs; + int prefs_len = strlen(prefs); + const LIBSSH2_COMMON_METHOD **mlist; + + switch (method_type) { + case LIBSSH2_METHOD_KEX: + prefvar = &session->kex_prefs; + mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_kex_methods; + break; + + case LIBSSH2_METHOD_HOSTKEY: + prefvar = &session->hostkey_prefs; + mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_hostkey_methods(); + break; + + case LIBSSH2_METHOD_CRYPT_CS: + prefvar = &session->local.crypt_prefs; + mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_crypt_methods(); + break; + + case LIBSSH2_METHOD_CRYPT_SC: + prefvar = &session->remote.crypt_prefs; + mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_crypt_methods(); + break; + + case LIBSSH2_METHOD_MAC_CS: + prefvar = &session->local.mac_prefs; + mlist = (const LIBSSH2_COMMON_METHOD **) _libssh2_mac_methods(); + break; + + case LIBSSH2_METHOD_MAC_SC: + prefvar = &session->remote.mac_prefs; + mlist = (const LIBSSH2_COMMON_METHOD **) _libssh2_mac_methods(); + break; + + case LIBSSH2_METHOD_COMP_CS: + prefvar = &session->local.comp_prefs; + mlist = (const LIBSSH2_COMMON_METHOD **) + _libssh2_comp_methods(session); + break; + + case LIBSSH2_METHOD_COMP_SC: + prefvar = &session->remote.comp_prefs; + mlist = (const LIBSSH2_COMMON_METHOD **) + _libssh2_comp_methods(session); + break; + + case LIBSSH2_METHOD_LANG_CS: + prefvar = &session->local.lang_prefs; + mlist = NULL; + break; + + case LIBSSH2_METHOD_LANG_SC: + prefvar = &session->remote.lang_prefs; + mlist = NULL; + break; + + default: + return _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "Invalid parameter specified for method_type"); + } + + s = newprefs = LIBSSH2_ALLOC(session, prefs_len + 1); + if (!newprefs) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Error allocated space for method preferences"); + } + memcpy(s, prefs, prefs_len + 1); + + while (s && *s && mlist) { + char *p = strchr(s, ','); + int method_len = p ? (p - s) : (int) strlen(s); + + if (!kex_get_method_by_name(s, method_len, mlist)) { + /* Strip out unsupported method */ + if (p) { + memcpy(s, p + 1, strlen(s) - method_len); + } else { + if (s > newprefs) { + *(--s) = '\0'; + } else { + *s = '\0'; + } + } + } + + s = p ? (p + 1) : NULL; + } + + if (strlen(newprefs) == 0) { + LIBSSH2_FREE(session, newprefs); + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "The requested method(s) are not currently " + "supported"); + } + + if (*prefvar) { + LIBSSH2_FREE(session, *prefvar); + } + *prefvar = newprefs; + + return 0; +} + +/* + * libssh2_session_supported_algs() + * returns a number of returned algorithms (a positive number) on success, + * a negative number on failure + */ + +LIBSSH2_API int libssh2_session_supported_algs(LIBSSH2_SESSION* session, + int method_type, + const char*** algs) +{ + unsigned int i; + unsigned int j; + unsigned int ialg; + const LIBSSH2_COMMON_METHOD **mlist; + + /* to prevent coredumps due to dereferencing of NULL */ + if (NULL == algs) + return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE, + "algs must not be NULL"); + + switch (method_type) { + case LIBSSH2_METHOD_KEX: + mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_kex_methods; + break; + + case LIBSSH2_METHOD_HOSTKEY: + mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_hostkey_methods(); + break; + + case LIBSSH2_METHOD_CRYPT_CS: + case LIBSSH2_METHOD_CRYPT_SC: + mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_crypt_methods(); + break; + + case LIBSSH2_METHOD_MAC_CS: + case LIBSSH2_METHOD_MAC_SC: + mlist = (const LIBSSH2_COMMON_METHOD **) _libssh2_mac_methods(); + break; + + case LIBSSH2_METHOD_COMP_CS: + case LIBSSH2_METHOD_COMP_SC: + mlist = (const LIBSSH2_COMMON_METHOD **) _libssh2_comp_methods(session); + break; + + default: + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unknown method type"); + } /* switch */ + + /* weird situation */ + if (NULL==mlist) + return _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "No algorithm found"); + + /* + mlist is looped through twice. The first time to find the number od + supported algorithms (needed to allocate the proper size of array) and + the second time to actually copy the pointers. Typically this function + will not be called often (typically at the beginning of a session) and + the number of algorithms (i.e. niumber of iterations in one loop) will + not be high (typically it will not exceed 20) for quite a long time. + + So double looping really shouldn't be an issue and it is definitely a + better solution than reallocation several times. + */ + + /* count the number of supported algorithms */ + for ( i=0, ialg=0; NULL!=mlist[i]; i++) { + /* do not count fields with NULL name */ + if (mlist[i]->name) + ialg++; + } + + /* weird situation, no algorithm found */ + if (0==ialg) + return _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "No algorithm found"); + + /* allocate buffer */ + *algs = (const char**) LIBSSH2_ALLOC(session, ialg*sizeof(const char*)); + if ( NULL==*algs ) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Memory allocation failed"); + } + /* Past this point *algs must be deallocated in case of an error!! */ + + /* copy non-NULL pointers only */ + for ( i=0, j=0; NULL!=mlist[i] && jname ){ + /* maybe a weird situation but if it occurs, do not include NULL + pointers */ + continue; + } + + /* note that [] has higher priority than * (dereferencing) */ + (*algs)[j++] = mlist[i]->name; + } + + /* correct number of pointers copied? (test the code above) */ + if ( j!=ialg ) { + /* deallocate buffer */ + LIBSSH2_FREE(session, (void *)*algs); + *algs = NULL; + + return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE, + "Internal error"); + } + + return ialg; +} diff --git a/libssh2/knownhost.c b/libssh2/knownhost.c new file mode 100644 index 0000000..a32dcf8 --- /dev/null +++ b/libssh2/knownhost.c @@ -0,0 +1,1245 @@ +/* + * Copyright (c) 2009-2014 by Daniel Stenberg + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#include "misc.h" + +struct known_host { + struct list_node node; + char *name; /* points to the name or the hash (allocated) */ + size_t name_len; /* needed for hashed data */ + int port; /* if non-zero, a specific port this key is for on this + host */ + int typemask; /* plain, sha1, custom, ... */ + char *salt; /* points to binary salt (allocated) */ + size_t salt_len; /* size of salt */ + char *key; /* the (allocated) associated key. This is kept base64 + encoded in memory. */ + char *key_type_name; /* the (allocated) key type name */ + size_t key_type_len; /* size of key_type_name */ + char *comment; /* the (allocated) optional comment text, may be + NULL */ + size_t comment_len; /* the size of comment */ + + /* this is the struct we expose externally */ + struct libssh2_knownhost external; +}; + +struct _LIBSSH2_KNOWNHOSTS +{ + LIBSSH2_SESSION *session; /* the session this "belongs to" */ + struct list_head head; +}; + +static void free_host(LIBSSH2_SESSION *session, struct known_host *entry) +{ + if(entry) { + if(entry->comment) + LIBSSH2_FREE(session, entry->comment); + if (entry->key_type_name) + LIBSSH2_FREE(session, entry->key_type_name); + if(entry->key) + LIBSSH2_FREE(session, entry->key); + if(entry->salt) + LIBSSH2_FREE(session, entry->salt); + if(entry->name) + LIBSSH2_FREE(session, entry->name); + LIBSSH2_FREE(session, entry); + } +} + +/* + * libssh2_knownhost_init + * + * Init a collection of known hosts. Returns the pointer to a collection. + * + */ +LIBSSH2_API LIBSSH2_KNOWNHOSTS * +libssh2_knownhost_init(LIBSSH2_SESSION *session) +{ + LIBSSH2_KNOWNHOSTS *knh = + LIBSSH2_ALLOC(session, sizeof(struct _LIBSSH2_KNOWNHOSTS)); + + if(!knh) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for known-hosts " + "collection"); + return NULL; + } + + knh->session = session; + + _libssh2_list_init(&knh->head); + + return knh; +} + +#define KNOWNHOST_MAGIC 0xdeadcafe +/* + * knownhost_to_external() + * + * Copies data from the internal to the external representation struct. + * + */ +static struct libssh2_knownhost *knownhost_to_external(struct known_host *node) +{ + struct libssh2_knownhost *ext = &node->external; + + ext->magic = KNOWNHOST_MAGIC; + ext->node = node; + ext->name = ((node->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) == + LIBSSH2_KNOWNHOST_TYPE_PLAIN)? node->name:NULL; + ext->key = node->key; + ext->typemask = node->typemask; + + return ext; +} + +static int +knownhost_add(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, const char *salt, + const char *key_type_name, size_t key_type_len, + const char *key, size_t keylen, + const char *comment, size_t commentlen, + int typemask, struct libssh2_knownhost **store) +{ + struct known_host *entry; + size_t hostlen = strlen(host); + int rc; + char *ptr; + unsigned int ptrlen; + + /* make sure we have a key type set */ + if(!(typemask & LIBSSH2_KNOWNHOST_KEY_MASK)) + return _libssh2_error(hosts->session, LIBSSH2_ERROR_INVAL, + "No key type set"); + + if(!(entry = LIBSSH2_CALLOC(hosts->session, sizeof(struct known_host)))) + return _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for known host " + "entry"); + + entry->typemask = typemask; + + switch(entry->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) { + case LIBSSH2_KNOWNHOST_TYPE_PLAIN: + case LIBSSH2_KNOWNHOST_TYPE_CUSTOM: + entry->name = LIBSSH2_ALLOC(hosts->session, hostlen+1); + if(!entry->name) { + rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for host name"); + goto error; + } + memcpy(entry->name, host, hostlen+1); + entry->name_len = hostlen; + break; + case LIBSSH2_KNOWNHOST_TYPE_SHA1: + rc = libssh2_base64_decode(hosts->session, &ptr, &ptrlen, + host, hostlen); + if(rc) + goto error; + entry->name = ptr; + entry->name_len = ptrlen; + + rc = libssh2_base64_decode(hosts->session, &ptr, &ptrlen, + salt, strlen(salt)); + if(rc) + goto error; + entry->salt = ptr; + entry->salt_len = ptrlen; + break; + default: + rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unknown host name type"); + goto error; + } + + if(typemask & LIBSSH2_KNOWNHOST_KEYENC_BASE64) { + /* the provided key is base64 encoded already */ + if(!keylen) + keylen = strlen(key); + entry->key = LIBSSH2_ALLOC(hosts->session, keylen+1); + if(!entry->key) { + rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for key"); + goto error; + } + memcpy(entry->key, key, keylen+1); + entry->key[keylen]=0; /* force a terminating zero trailer */ + } + else { + /* key is raw, we base64 encode it and store it as such */ + size_t nlen = _libssh2_base64_encode(hosts->session, key, keylen, + &ptr); + if(!nlen) { + rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "base64-encoded key"); + goto error; + } + + entry->key = ptr; + } + + if (key_type_name && ((typemask & LIBSSH2_KNOWNHOST_KEY_MASK) == + LIBSSH2_KNOWNHOST_KEY_UNKNOWN)) { + entry->key_type_name = LIBSSH2_ALLOC(hosts->session, key_type_len+1); + if (!entry->key_type_name) { + rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for key type"); + goto error; + } + memcpy(entry->key_type_name, key_type_name, key_type_len); + entry->key_type_name[key_type_len]=0; + entry->key_type_len = key_type_len; + } + + if (comment) { + entry->comment = LIBSSH2_ALLOC(hosts->session, commentlen+1); + if(!entry->comment) { + rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for comment"); + goto error; + } + memcpy(entry->comment, comment, commentlen+1); + entry->comment[commentlen]=0; /* force a terminating zero trailer */ + entry->comment_len = commentlen; + } + else { + entry->comment = NULL; + } + + /* add this new host to the big list of known hosts */ + _libssh2_list_add(&hosts->head, &entry->node); + + if(store) + *store = knownhost_to_external(entry); + + return LIBSSH2_ERROR_NONE; + error: + free_host(hosts->session, entry); + return rc; +} + +/* + * libssh2_knownhost_add + * + * Add a host and its associated key to the collection of known hosts. + * + * The 'type' argument specifies on what format the given host and keys are: + * + * plain - ascii "hostname.domain.tld" + * sha1 - SHA1( ) base64-encoded! + * custom - another hash + * + * If 'sha1' is selected as type, the salt must be provided to the salt + * argument. This too base64 encoded. + * + * The SHA-1 hash is what OpenSSH can be told to use in known_hosts files. If + * a custom type is used, salt is ignored and you must provide the host + * pre-hashed when checking for it in the libssh2_knownhost_check() function. + * + * The keylen parameter may be omitted (zero) if the key is provided as a + * NULL-terminated base64-encoded string. + */ + +LIBSSH2_API int +libssh2_knownhost_add(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, const char *salt, + const char *key, size_t keylen, + int typemask, struct libssh2_knownhost **store) +{ + return knownhost_add(hosts, host, salt, NULL, 0, key, keylen, NULL, + 0, typemask, store); +} + + +/* + * libssh2_knownhost_addc + * + * Add a host and its associated key to the collection of known hosts. + * + * Takes a comment argument that may be NULL. A NULL comment indicates + * there is no comment and the entry will end directly after the key + * when written out to a file. An empty string "" comment will indicate an + * empty comment which will cause a single space to be written after the key. + * + * The 'type' argument specifies on what format the given host and keys are: + * + * plain - ascii "hostname.domain.tld" + * sha1 - SHA1( ) base64-encoded! + * custom - another hash + * + * If 'sha1' is selected as type, the salt must be provided to the salt + * argument. This too base64 encoded. + * + * The SHA-1 hash is what OpenSSH can be told to use in known_hosts files. If + * a custom type is used, salt is ignored and you must provide the host + * pre-hashed when checking for it in the libssh2_knownhost_check() function. + * + * The keylen parameter may be omitted (zero) if the key is provided as a + * NULL-terminated base64-encoded string. + */ + +LIBSSH2_API int +libssh2_knownhost_addc(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, const char *salt, + const char *key, size_t keylen, + const char *comment, size_t commentlen, + int typemask, struct libssh2_knownhost **store) +{ + return knownhost_add(hosts, host, salt, NULL, 0, key, keylen, + comment, commentlen, typemask, store); +} + +/* + * knownhost_check + * + * Check a host and its associated key against the collection of known hosts. + * + * The typemask is the type/format of the given host name and key + * + * plain - ascii "hostname.domain.tld" + * sha1 - NOT SUPPORTED AS INPUT + * custom - prehashed base64 encoded. Note that this cannot use any salts. + * + * Returns: + * + * LIBSSH2_KNOWNHOST_CHECK_FAILURE + * LIBSSH2_KNOWNHOST_CHECK_NOTFOUND + * LIBSSH2_KNOWNHOST_CHECK_MATCH + * LIBSSH2_KNOWNHOST_CHECK_MISMATCH + */ +static int +knownhost_check(LIBSSH2_KNOWNHOSTS *hosts, + const char *hostp, int port, + const char *key, size_t keylen, + int typemask, + struct libssh2_knownhost **ext) +{ + struct known_host *node; + struct known_host *badkey = NULL; + int type = typemask & LIBSSH2_KNOWNHOST_TYPE_MASK; + char *keyalloc = NULL; + int rc = LIBSSH2_KNOWNHOST_CHECK_NOTFOUND; + char hostbuff[270]; /* most host names can't be longer than like 256 */ + const char *host; + int numcheck; /* number of host combos to check */ + int match = 0; + + if(type == LIBSSH2_KNOWNHOST_TYPE_SHA1) + /* we can't work with a sha1 as given input */ + return LIBSSH2_KNOWNHOST_CHECK_MISMATCH; + + /* if a port number is given, check for a '[host]:port' first before the + plain 'host' */ + if(port >= 0) { + int len = snprintf(hostbuff, sizeof(hostbuff), "[%s]:%d", hostp, port); + if (len < 0 || len >= (int)sizeof(hostbuff)) { + _libssh2_error(hosts->session, + LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "Known-host write buffer too small"); + return LIBSSH2_KNOWNHOST_CHECK_FAILURE; + } + host = hostbuff; + numcheck = 2; /* check both combos, start with this */ + } + else { + host = hostp; + numcheck = 1; /* only check this host version */ + } + + if(!(typemask & LIBSSH2_KNOWNHOST_KEYENC_BASE64)) { + /* we got a raw key input, convert it to base64 for the checks below */ + size_t nlen = _libssh2_base64_encode(hosts->session, key, keylen, + &keyalloc); + if(!nlen) { + _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for base64-encoded " + "key"); + return LIBSSH2_KNOWNHOST_CHECK_FAILURE; + } + + /* make the key point to this */ + key = keyalloc; + } + + do { + node = _libssh2_list_first(&hosts->head); + while (node) { + switch(node->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) { + case LIBSSH2_KNOWNHOST_TYPE_PLAIN: + if(type == LIBSSH2_KNOWNHOST_TYPE_PLAIN) + match = !strcmp(host, node->name); + break; + case LIBSSH2_KNOWNHOST_TYPE_CUSTOM: + if(type == LIBSSH2_KNOWNHOST_TYPE_CUSTOM) + match = !strcmp(host, node->name); + break; + case LIBSSH2_KNOWNHOST_TYPE_SHA1: + if(type == LIBSSH2_KNOWNHOST_TYPE_PLAIN) { + /* when we have the sha1 version stored, we can use a + plain input to produce a hash to compare with the + stored hash. + */ + unsigned char hash[SHA_DIGEST_LENGTH]; + libssh2_hmac_ctx ctx; + libssh2_hmac_ctx_init(ctx); + + if(SHA_DIGEST_LENGTH != node->name_len) { + /* the name hash length must be the sha1 size or + we can't match it */ + break; + } + libssh2_hmac_sha1_init(&ctx, (unsigned char *)node->salt, + node->salt_len); + libssh2_hmac_update(ctx, (unsigned char *)host, + strlen(host)); + libssh2_hmac_final(ctx, hash); + libssh2_hmac_cleanup(&ctx); + + if(!memcmp(hash, node->name, SHA_DIGEST_LENGTH)) + /* this is a node we're interested in */ + match = 1; + } + break; + default: /* unsupported type */ + break; + } + if(match) { + int host_key_type = typemask & LIBSSH2_KNOWNHOST_KEY_MASK; + int known_key_type = + node->typemask & LIBSSH2_KNOWNHOST_KEY_MASK; + /* match on key type as follows: + - never match on an unknown key type + - if key_type is set to zero, ignore it an match always + - otherwise match when both key types are equal + */ + if ( (host_key_type != LIBSSH2_KNOWNHOST_KEY_UNKNOWN ) && + ( (host_key_type == 0) || + (host_key_type == known_key_type) ) ) { + /* host name and key type match, now compare the keys */ + if(!strcmp(key, node->key)) { + /* they match! */ + if (ext) + *ext = knownhost_to_external(node); + badkey = NULL; + rc = LIBSSH2_KNOWNHOST_CHECK_MATCH; + break; + } + else { + /* remember the first node that had a host match but a + failed key match since we continue our search from + here */ + if(!badkey) + badkey = node; + } + } + match = 0; /* don't count this as a match anymore */ + } + node= _libssh2_list_next(&node->node); + } + host = hostp; + } while(!match && --numcheck); + + if(badkey) { + /* key mismatch */ + if (ext) + *ext = knownhost_to_external(badkey); + rc = LIBSSH2_KNOWNHOST_CHECK_MISMATCH; + } + + if(keyalloc) + LIBSSH2_FREE(hosts->session, keyalloc); + + return rc; +} + +/* + * libssh2_knownhost_check + * + * Check a host and its associated key against the collection of known hosts. + * + * The typemask is the type/format of the given host name and key + * + * plain - ascii "hostname.domain.tld" + * sha1 - NOT SUPPORTED AS INPUT + * custom - prehashed base64 encoded. Note that this cannot use any salts. + * + * Returns: + * + * LIBSSH2_KNOWNHOST_CHECK_FAILURE + * LIBSSH2_KNOWNHOST_CHECK_NOTFOUND + * LIBSSH2_KNOWNHOST_CHECK_MATCH + * LIBSSH2_KNOWNHOST_CHECK_MISMATCH + */ +LIBSSH2_API int +libssh2_knownhost_check(LIBSSH2_KNOWNHOSTS *hosts, + const char *hostp, const char *key, size_t keylen, + int typemask, + struct libssh2_knownhost **ext) +{ + return knownhost_check(hosts, hostp, -1, key, keylen, + typemask, ext); +} + +/* + * libssh2_knownhost_checkp + * + * Check a host+port and its associated key against the collection of known + * hosts. + * + * Note that if 'port' is specified as greater than zero, the check function + * will be able to check for a dedicated key for this particular host+port + * combo, and if 'port' is negative it only checks for the generic host key. + * + * The typemask is the type/format of the given host name and key + * + * plain - ascii "hostname.domain.tld" + * sha1 - NOT SUPPORTED AS INPUT + * custom - prehashed base64 encoded. Note that this cannot use any salts. + * + * Returns: + * + * LIBSSH2_KNOWNHOST_CHECK_FAILURE + * LIBSSH2_KNOWNHOST_CHECK_NOTFOUND + * LIBSSH2_KNOWNHOST_CHECK_MATCH + * LIBSSH2_KNOWNHOST_CHECK_MISMATCH + */ +LIBSSH2_API int +libssh2_knownhost_checkp(LIBSSH2_KNOWNHOSTS *hosts, + const char *hostp, int port, + const char *key, size_t keylen, + int typemask, + struct libssh2_knownhost **ext) +{ + return knownhost_check(hosts, hostp, port, key, keylen, + typemask, ext); +} + + +/* + * libssh2_knownhost_del + * + * Remove a host from the collection of known hosts. + * + */ +LIBSSH2_API int +libssh2_knownhost_del(LIBSSH2_KNOWNHOSTS *hosts, + struct libssh2_knownhost *entry) +{ + struct known_host *node; + + /* check that this was retrieved the right way or get out */ + if(!entry || (entry->magic != KNOWNHOST_MAGIC)) + return _libssh2_error(hosts->session, LIBSSH2_ERROR_INVAL, + "Invalid host information"); + + /* get the internal node pointer */ + node = entry->node; + + /* unlink from the list of all hosts */ + _libssh2_list_remove(&node->node); + + /* clear the struct now since the memory in which it is allocated is + about to be freed! */ + memset(entry, 0, sizeof(struct libssh2_knownhost)); + + /* free all resources */ + free_host(hosts->session, node); + + return 0; +} + +/* + * libssh2_knownhost_free + * + * Free an entire collection of known hosts. + * + */ +LIBSSH2_API void +libssh2_knownhost_free(LIBSSH2_KNOWNHOSTS *hosts) +{ + struct known_host *node; + struct known_host *next; + + for(node = _libssh2_list_first(&hosts->head); node; node = next) { + next = _libssh2_list_next(&node->node); + free_host(hosts->session, node); + } + LIBSSH2_FREE(hosts->session, hosts); +} + + +/* old style plain text: [name]([,][name])* + + for the sake of simplicity, we add them as separate hosts with the same + key +*/ +static int oldstyle_hostline(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, size_t hostlen, + const char *key_type_name, size_t key_type_len, + const char *key, size_t keylen, int key_type, + const char *comment, size_t commentlen) +{ + int rc = 0; + size_t namelen = 0; + const char *name = host + hostlen; + + if(hostlen < 1) + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Failed to parse known_hosts line " + "(no host names)"); + + while(name > host) { + --name; + ++namelen; + + /* when we get the the start or see a comma coming up, add the host + name to the collection */ + if((name == host) || (*(name-1) == ',')) { + + char hostbuf[256]; + + /* make sure we don't overflow the buffer */ + if(namelen >= sizeof(hostbuf)-1) + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Failed to parse known_hosts line " + "(unexpected length)"); + + /* copy host name to the temp buffer and zero terminate */ + memcpy(hostbuf, name, namelen); + hostbuf[namelen]=0; + + rc = knownhost_add(hosts, hostbuf, NULL, + key_type_name, key_type_len, + key, keylen, + comment, commentlen, + key_type | LIBSSH2_KNOWNHOST_TYPE_PLAIN | + LIBSSH2_KNOWNHOST_KEYENC_BASE64, NULL); + if(rc) + return rc; + + if(name > host) { + namelen = 0; + --name; /* skip comma */ + } + } + } + + return rc; +} + +/* |1|[salt]|[hash] */ +static int hashed_hostline(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, size_t hostlen, + const char *key_type_name, size_t key_type_len, + const char *key, size_t keylen, int key_type, + const char *comment, size_t commentlen) +{ + const char *p; + char saltbuf[32]; + char hostbuf[256]; + + const char *salt = &host[3]; /* skip the magic marker */ + hostlen -= 3; /* deduct the marker */ + + /* this is where the salt starts, find the end of it */ + for(p = salt; *p && (*p != '|'); p++) + ; + + if(*p=='|') { + const char *hash = NULL; + size_t saltlen = p - salt; + if(saltlen >= (sizeof(saltbuf)-1)) /* weird length */ + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Failed to parse known_hosts line " + "(unexpectedly long salt)"); + + memcpy(saltbuf, salt, saltlen); + saltbuf[saltlen] = 0; /* zero terminate */ + salt = saltbuf; /* point to the stack based buffer */ + + hash = p+1; /* the host hash is after the separator */ + + /* now make the host point to the hash */ + host = hash; + hostlen -= saltlen+1; /* deduct the salt and separator */ + + /* check that the lengths seem sensible */ + if(hostlen >= sizeof(hostbuf)-1) + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Failed to parse known_hosts line " + "(unexpected length)"); + + memcpy(hostbuf, host, hostlen); + hostbuf[hostlen]=0; + + return knownhost_add(hosts, hostbuf, salt, + key_type_name, key_type_len, + key, keylen, + comment, commentlen, + key_type | LIBSSH2_KNOWNHOST_TYPE_SHA1 | + LIBSSH2_KNOWNHOST_KEYENC_BASE64, NULL); + } + else + return 0; /* XXX: This should be an error, shouldn't it? */ +} + +/* + * hostline() + * + * Parse a single known_host line pre-split into host and key. + * + * The key part may include an optional comment which will be parsed here + * for ssh-rsa and ssh-dsa keys. Comments in other key types aren't handled. + * + * The function assumes new-lines have already been removed from the arguments. + */ +static int hostline(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, size_t hostlen, + const char *key, size_t keylen) +{ + const char *comment = NULL; + const char *key_type_name = NULL; + size_t commentlen = 0; + size_t key_type_len = 0; + int key_type; + + /* make some checks that the lengths seem sensible */ + if(keylen < 20) + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Failed to parse known_hosts line " + "(key too short)"); + + switch(key[0]) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + key_type = LIBSSH2_KNOWNHOST_KEY_RSA1; + + /* Note that the old-style keys (RSA1) aren't truly base64, but we + * claim it is for now since we can get away with strcmp()ing the + * entire anything anyway! We need to check and fix these to make them + * work properly. + */ + break; + + default: + key_type_name = key; + while (keylen && *key && + (*key != ' ') && (*key != '\t')) { + key++; + keylen--; + } + key_type_len = key - key_type_name; + + if (!strncmp(key_type_name, "ssh-dss", key_type_len)) + key_type = LIBSSH2_KNOWNHOST_KEY_SSHDSS; + else if (!strncmp(key_type_name, "ssh-rsa", key_type_len)) + key_type = LIBSSH2_KNOWNHOST_KEY_SSHRSA; + else + key_type = LIBSSH2_KNOWNHOST_KEY_UNKNOWN; + + /* skip whitespaces */ + while((*key ==' ') || (*key == '\t')) { + key++; + keylen--; + } + + comment = key; + commentlen = keylen; + + /* move over key */ + while(commentlen && *comment && + (*comment != ' ') && (*comment != '\t')) { + comment++; + commentlen--; + } + + /* reduce key by comment length */ + keylen -= commentlen; + + /* Distinguish empty comment (a space) from no comment (no space) */ + if (commentlen == 0) + comment = NULL; + + /* skip whitespaces */ + while(commentlen && *comment && + ((*comment ==' ') || (*comment == '\t'))) { + comment++; + commentlen--; + } + break; + } + + /* Figure out host format */ + if((hostlen >2) && memcmp(host, "|1|", 3)) { + /* old style plain text: [name]([,][name])* + + for the sake of simplicity, we add them as separate hosts with the + same key + */ + return oldstyle_hostline(hosts, host, hostlen, key_type_name, + key_type_len, key, keylen, key_type, + comment, commentlen); + } + else { + /* |1|[salt]|[hash] */ + return hashed_hostline(hosts, host, hostlen, key_type_name, + key_type_len, key, keylen, key_type, + comment, commentlen); + } +} + +/* + * libssh2_knownhost_readline() + * + * Pass in a line of a file of 'type'. + * + * LIBSSH2_KNOWNHOST_FILE_OPENSSH is the only supported type. + * + * OpenSSH line format: + * + * + * + * Where the two parts can be created like: + * + * can be either + * or + * + * consists of + * [name] optionally followed by [,name] one or more times + * + * consists of + * |1||hash + * + * can be one of: + * [RSA bits] [e] [n as a decimal number] + * 'ssh-dss' [base64-encoded-key] + * 'ssh-rsa' [base64-encoded-key] + * + */ +LIBSSH2_API int +libssh2_knownhost_readline(LIBSSH2_KNOWNHOSTS *hosts, + const char *line, size_t len, int type) +{ + const char *cp; + const char *hostp; + const char *keyp; + size_t hostlen; + size_t keylen; + int rc; + + if(type != LIBSSH2_KNOWNHOST_FILE_OPENSSH) + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unsupported type of known-host information " + "store"); + + cp = line; + + /* skip leading whitespaces */ + while(len && ((*cp==' ') || (*cp == '\t'))) { + cp++; + len--; + } + + if(!len || !*cp || (*cp == '#') || (*cp == '\n')) + /* comment or empty line */ + return LIBSSH2_ERROR_NONE; + + /* the host part starts here */ + hostp = cp; + + /* move over the host to the separator */ + while(len && *cp && (*cp!=' ') && (*cp != '\t')) { + cp++; + len--; + } + + hostlen = cp - hostp; + + /* the key starts after the whitespaces */ + while(len && *cp && ((*cp==' ') || (*cp == '\t'))) { + cp++; + len--; + } + + if(!*cp || !len) /* illegal line */ + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Failed to parse known_hosts line"); + + keyp = cp; /* the key starts here */ + keylen = len; + + /* check if the line (key) ends with a newline and if so kill it */ + while(len && *cp && (*cp != '\n')) { + cp++; + len--; + } + + /* zero terminate where the newline is */ + if(*cp == '\n') + keylen--; /* don't include this in the count */ + + /* deal with this one host+key line */ + rc = hostline(hosts, hostp, hostlen, keyp, keylen); + if(rc) + return rc; /* failed */ + + return LIBSSH2_ERROR_NONE; /* success */ +} + +/* + * libssh2_knownhost_readfile + * + * Read hosts+key pairs from a given file. + * + * Returns a negative value for error or number of successfully added hosts. + * + */ + +LIBSSH2_API int +libssh2_knownhost_readfile(LIBSSH2_KNOWNHOSTS *hosts, + const char *filename, int type) +{ + FILE *file; + int num = 0; + char buf[2048]; + + if(type != LIBSSH2_KNOWNHOST_FILE_OPENSSH) + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unsupported type of known-host information " + "store"); + + file = fopen(filename, "r"); + if(file) { + while(fgets(buf, sizeof(buf), file)) { + if(libssh2_knownhost_readline(hosts, buf, strlen(buf), type)) { + num = _libssh2_error(hosts->session, LIBSSH2_ERROR_KNOWN_HOSTS, + "Failed to parse known hosts file"); + break; + } + num++; + } + fclose(file); + } + else + return _libssh2_error(hosts->session, LIBSSH2_ERROR_FILE, + "Failed to open file"); + + return num; +} + +/* + * knownhost_writeline() + * + * Ask libssh2 to convert a known host to an output line for storage. + * + * Note that this function returns LIBSSH2_ERROR_BUFFER_TOO_SMALL if the given + * output buffer is too small to hold the desired output. The 'outlen' field + * will then contain the size libssh2 wanted to store, which then is the + * smallest sufficient buffer it would require. + * + */ +static int +knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts, + struct known_host *node, + char *buf, size_t buflen, + size_t *outlen, int type) +{ + size_t required_size; + + const char *key_type_name; + size_t key_type_len; + + /* we only support this single file type for now, bail out on all other + attempts */ + if(type != LIBSSH2_KNOWNHOST_FILE_OPENSSH) + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unsupported type of known-host information " + "store"); + + switch(node->typemask & LIBSSH2_KNOWNHOST_KEY_MASK) { + case LIBSSH2_KNOWNHOST_KEY_RSA1: + key_type_name = NULL; + key_type_len = 0; + break; + case LIBSSH2_KNOWNHOST_KEY_SSHRSA: + key_type_name = "ssh-rsa"; + key_type_len = 7; + break; + case LIBSSH2_KNOWNHOST_KEY_SSHDSS: + key_type_name = "ssh-dss"; + key_type_len = 7; + break; + case LIBSSH2_KNOWNHOST_KEY_UNKNOWN: + key_type_name = node->key_type_name; + if (key_type_name) { + key_type_len = node->key_type_len; + break; + } + /* otherwise fallback to default and error */ + default: + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unsupported type of known-host entry"); + } + + /* When putting together the host line there are three aspects to consider: + - Hashed (SHA1) or unhashed hostname + - key name or no key name (RSA1) + - comment or no comment + + This means there are 2^3 different formats: + ("|1|%s|%s %s %s %s\n", salt, hashed_host, key_name, key, comment) + ("|1|%s|%s %s %s\n", salt, hashed_host, key_name, key) + ("|1|%s|%s %s %s\n", salt, hashed_host, key, comment) + ("|1|%s|%s %s\n", salt, hashed_host, key) + ("%s %s %s %s\n", host, key_name, key, comment) + ("%s %s %s\n", host, key_name, key) + ("%s %s %s\n", host, key, comment) + ("%s %s\n", host, key) + + Even if the buffer is too small, we have to set outlen to the number of + characters the complete line would have taken. We also don't write + anything to the buffer unless we are sure we can write everything to the + buffer. */ + + required_size = strlen(node->key); + + if(key_type_len) + required_size += key_type_len + 1; /* ' ' = 1 */ + if(node->comment) + required_size += node->comment_len + 1; /* ' ' = 1 */ + + if((node->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) == + LIBSSH2_KNOWNHOST_TYPE_SHA1) { + char *namealloc; + size_t name_base64_len; + char *saltalloc; + size_t salt_base64_len; + + name_base64_len = _libssh2_base64_encode(hosts->session, node->name, + node->name_len, &namealloc); + if(!name_base64_len) + return _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "base64-encoded host name"); + + salt_base64_len = _libssh2_base64_encode(hosts->session, + node->salt, node->salt_len, + &saltalloc); + if(!salt_base64_len) { + LIBSSH2_FREE(hosts->session, namealloc); + return _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "base64-encoded salt"); + } + + required_size += salt_base64_len + name_base64_len + 7; + /* |1| + | + ' ' + \n + \0 = 7 */ + + if(required_size <= buflen) { + if(node->comment && key_type_len) + snprintf(buf, buflen, "|1|%s|%s %s %s %s\n", saltalloc, + namealloc, key_type_name, node->key, node->comment); + else if (node->comment) + snprintf(buf, buflen, "|1|%s|%s %s %s\n", saltalloc, namealloc, + node->key, node->comment); + else if (key_type_len) + snprintf(buf, buflen, "|1|%s|%s %s %s\n", saltalloc, namealloc, + key_type_name, node->key); + else + snprintf(buf, buflen, "|1|%s|%s %s\n", saltalloc, namealloc, + node->key); + } + + LIBSSH2_FREE(hosts->session, namealloc); + LIBSSH2_FREE(hosts->session, saltalloc); + } + else { + required_size += node->name_len + 3; + /* ' ' + '\n' + \0 = 3 */ + + if(required_size <= buflen) { + if(node->comment && key_type_len) + snprintf(buf, buflen, "%s %s %s %s\n", node->name, + key_type_name, node->key, node->comment); + else if (node->comment) + snprintf(buf, buflen, "%s %s %s\n", node->name, node->key, + node->comment); + else if (key_type_len) + snprintf(buf, buflen, "%s %s %s\n", node->name, key_type_name, + node->key); + else + snprintf(buf, buflen, "%s %s\n", node->name, node->key); + } + } + + /* we report the full length of the data with the trailing zero excluded */ + *outlen = required_size-1; + + if(required_size <= buflen) + return LIBSSH2_ERROR_NONE; + else + return _libssh2_error(hosts->session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "Known-host write buffer too small"); +} + +/* + * libssh2_knownhost_writeline() + * + * Ask libssh2 to convert a known host to an output line for storage. + * + * Note that this function returns LIBSSH2_ERROR_BUFFER_TOO_SMALL if the given + * output buffer is too small to hold the desired output. + */ +LIBSSH2_API int +libssh2_knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts, + struct libssh2_knownhost *known, + char *buffer, size_t buflen, + size_t *outlen, /* the amount of written data */ + int type) +{ + struct known_host *node; + + if(known->magic != KNOWNHOST_MAGIC) + return _libssh2_error(hosts->session, LIBSSH2_ERROR_INVAL, + "Invalid host information"); + + node = known->node; + + return knownhost_writeline(hosts, node, buffer, buflen, outlen, type); +} + +/* + * libssh2_knownhost_writefile() + * + * Write hosts+key pairs to the given file. + */ +LIBSSH2_API int +libssh2_knownhost_writefile(LIBSSH2_KNOWNHOSTS *hosts, + const char *filename, int type) +{ + struct known_host *node; + FILE *file; + int rc = LIBSSH2_ERROR_NONE; + char buffer[2048]; + + /* we only support this single file type for now, bail out on all other + attempts */ + if(type != LIBSSH2_KNOWNHOST_FILE_OPENSSH) + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unsupported type of known-host information " + "store"); + + file = fopen(filename, "w"); + if(!file) + return _libssh2_error(hosts->session, LIBSSH2_ERROR_FILE, + "Failed to open file"); + + for(node = _libssh2_list_first(&hosts->head); + node; + node = _libssh2_list_next(&node->node)) { + size_t wrote = 0; + size_t nwrote; + rc = knownhost_writeline(hosts, node, buffer, sizeof(buffer), &wrote, + type); + if(rc) + break; + + nwrote = fwrite(buffer, 1, wrote, file); + if(nwrote != wrote) { + /* failed to write the whole thing, bail out */ + rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_FILE, + "Write failed"); + break; + } + } + fclose(file); + + return rc; +} + + +/* + * libssh2_knownhost_get() + * + * Traverse the internal list of known hosts. Pass NULL to 'prev' to get + * the first one. + * + * Returns: + * 0 if a fine host was stored in 'store' + * 1 if end of hosts + * [negative] on errors + */ +LIBSSH2_API int +libssh2_knownhost_get(LIBSSH2_KNOWNHOSTS *hosts, + struct libssh2_knownhost **ext, + struct libssh2_knownhost *oprev) +{ + struct known_host *node; + if(oprev && oprev->node) { + /* we have a starting point */ + struct known_host *prev = oprev->node; + + /* get the next node in the list */ + node = _libssh2_list_next(&prev->node); + + } + else + node = _libssh2_list_first(&hosts->head); + + if(!node) + /* no (more) node */ + return 1; + + *ext = knownhost_to_external(node); + + return 0; +} diff --git a/libssh2/libgcrypt.c b/libssh2/libgcrypt.c new file mode 100644 index 0000000..e85aecd --- /dev/null +++ b/libssh2/libgcrypt.c @@ -0,0 +1,624 @@ +/* Copyright (C) 2008, 2009, Simon Josefsson + * Copyright (C) 2006, 2007, The Written Word, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" + +#ifdef LIBSSH2_LIBGCRYPT /* compile only if we build with libgcrypt */ + +#include + +int +_libssh2_rsa_new(libssh2_rsa_ctx ** rsa, + const unsigned char *edata, + unsigned long elen, + const unsigned char *ndata, + unsigned long nlen, + const unsigned char *ddata, + unsigned long dlen, + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *e1data, + unsigned long e1len, + const unsigned char *e2data, + unsigned long e2len, + const unsigned char *coeffdata, unsigned long coefflen) +{ + int rc; + (void) e1data; + (void) e1len; + (void) e2data; + (void) e2len; + + if (ddata) { + rc = gcry_sexp_build + (rsa, NULL, + "(private-key(rsa(n%b)(e%b)(d%b)(q%b)(p%b)(u%b)))", + nlen, ndata, elen, edata, dlen, ddata, plen, pdata, + qlen, qdata, coefflen, coeffdata); + } else { + rc = gcry_sexp_build(rsa, NULL, "(public-key(rsa(n%b)(e%b)))", + nlen, ndata, elen, edata); + } + if (rc) { + *rsa = NULL; + return -1; + } + + return 0; +} + +int +_libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa, + const unsigned char *sig, + unsigned long sig_len, + const unsigned char *m, unsigned long m_len) +{ + unsigned char hash[SHA_DIGEST_LENGTH]; + gcry_sexp_t s_sig, s_hash; + int rc = -1; + + libssh2_sha1(m, m_len, hash); + + rc = gcry_sexp_build(&s_hash, NULL, + "(data (flags pkcs1) (hash sha1 %b))", + SHA_DIGEST_LENGTH, hash); + if (rc != 0) { + return -1; + } + + rc = gcry_sexp_build(&s_sig, NULL, "(sig-val(rsa(s %b)))", sig_len, sig); + if (rc != 0) { + gcry_sexp_release(s_hash); + return -1; + } + + rc = gcry_pk_verify(s_sig, s_hash, rsa); + gcry_sexp_release(s_sig); + gcry_sexp_release(s_hash); + + return (rc == 0) ? 0 : -1; +} + +int +_libssh2_dsa_new(libssh2_dsa_ctx ** dsactx, + const unsigned char *p, + unsigned long p_len, + const unsigned char *q, + unsigned long q_len, + const unsigned char *g, + unsigned long g_len, + const unsigned char *y, + unsigned long y_len, + const unsigned char *x, unsigned long x_len) +{ + int rc; + + if (x_len) { + rc = gcry_sexp_build + (dsactx, NULL, + "(private-key(dsa(p%b)(q%b)(g%b)(y%b)(x%b)))", + p_len, p, q_len, q, g_len, g, y_len, y, x_len, x); + } else { + rc = gcry_sexp_build(dsactx, NULL, + "(public-key(dsa(p%b)(q%b)(g%b)(y%b)))", + p_len, p, q_len, q, g_len, g, y_len, y); + } + + if (rc) { + *dsactx = NULL; + return -1; + } + + return 0; +} + +int +_libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa, + LIBSSH2_SESSION * session, + const char *filedata, size_t filedata_len, + unsigned const char *passphrase) +{ + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unable to extract private key from memory: " + "Method unimplemented in libgcrypt backend"); +} + +int +_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa, + LIBSSH2_SESSION * session, + const char *filename, unsigned const char *passphrase) +{ + FILE *fp; + unsigned char *data, *save_data; + unsigned int datalen; + int ret; + unsigned char *n, *e, *d, *p, *q, *e1, *e2, *coeff; + unsigned int nlen, elen, dlen, plen, qlen, e1len, e2len, coefflen; + + (void) passphrase; + + fp = fopen(filename, "r"); + if (!fp) { + return -1; + } + + ret = _libssh2_pem_parse(session, + "-----BEGIN RSA PRIVATE KEY-----", + "-----END RSA PRIVATE KEY-----", + fp, &data, &datalen); + fclose(fp); + if (ret) { + return -1; + } + + save_data = data; + + if (_libssh2_pem_decode_sequence(&data, &datalen)) { + ret = -1; + goto fail; + } +/* First read Version field (should be 0). */ + ret = _libssh2_pem_decode_integer(&data, &datalen, &n, &nlen); + if (ret != 0 || (nlen != 1 && *n != '\0')) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &n, &nlen); + if (ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &e, &elen); + if (ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &d, &dlen); + if (ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen); + if (ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &q, &qlen); + if (ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &e1, &e1len); + if (ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &e2, &e2len); + if (ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &coeff, &coefflen); + if (ret != 0) { + ret = -1; + goto fail; + } + + if (_libssh2_rsa_new(rsa, e, elen, n, nlen, d, dlen, p, plen, + q, qlen, e1, e1len, e2, e2len, coeff, coefflen)) { + ret = -1; + goto fail; + } + + ret = 0; + + fail: + LIBSSH2_FREE(session, save_data); + return ret; +} + +int +_libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa, + LIBSSH2_SESSION * session, + const char *filedata, size_t filedata_len, + unsigned const char *passphrase) +{ + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unable to extract private key from memory: " + "Method unimplemented in libgcrypt backend"); +} + +int +_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa, + LIBSSH2_SESSION * session, + const char *filename, unsigned const char *passphrase) +{ + FILE *fp; + unsigned char *data, *save_data; + unsigned int datalen; + int ret; + unsigned char *p, *q, *g, *y, *x; + unsigned int plen, qlen, glen, ylen, xlen; + + (void) passphrase; + + fp = fopen(filename, "r"); + if (!fp) { + return -1; + } + + ret = _libssh2_pem_parse(session, + "-----BEGIN DSA PRIVATE KEY-----", + "-----END DSA PRIVATE KEY-----", + fp, &data, &datalen); + fclose(fp); + if (ret) { + return -1; + } + + save_data = data; + + if (_libssh2_pem_decode_sequence(&data, &datalen)) { + ret = -1; + goto fail; + } + +/* First read Version field (should be 0). */ + ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen); + if (ret != 0 || (plen != 1 && *p != '\0')) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen); + if (ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &q, &qlen); + if (ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &g, &glen); + if (ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &y, &ylen); + if (ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &x, &xlen); + if (ret != 0) { + ret = -1; + goto fail; + } + + if (datalen != 0) { + ret = -1; + goto fail; + } + + if (_libssh2_dsa_new(dsa, p, plen, q, qlen, g, glen, y, ylen, x, xlen)) { + ret = -1; + goto fail; + } + + ret = 0; + + fail: + LIBSSH2_FREE(session, save_data); + return ret; +} + +int +_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session, + libssh2_rsa_ctx * rsactx, + const unsigned char *hash, + size_t hash_len, + unsigned char **signature, size_t *signature_len) +{ + gcry_sexp_t sig_sexp; + gcry_sexp_t data; + int rc; + const char *tmp; + size_t size; + + if (hash_len != SHA_DIGEST_LENGTH) { + return -1; + } + + if (gcry_sexp_build(&data, NULL, + "(data (flags pkcs1) (hash sha1 %b))", + hash_len, hash)) { + return -1; + } + + rc = gcry_pk_sign(&sig_sexp, data, rsactx); + + gcry_sexp_release(data); + + if (rc != 0) { + return -1; + } + + data = gcry_sexp_find_token(sig_sexp, "s", 0); + if (!data) { + return -1; + } + + tmp = gcry_sexp_nth_data(data, 1, &size); + if (!tmp) { + return -1; + } + + if (tmp[0] == '\0') { + tmp++; + size--; + } + + *signature = LIBSSH2_ALLOC(session, size); + memcpy(*signature, tmp, size); + *signature_len = size; + + return rc; +} + +int +_libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx, + const unsigned char *hash, + unsigned long hash_len, unsigned char *sig) +{ + unsigned char zhash[SHA_DIGEST_LENGTH + 1]; + gcry_sexp_t sig_sexp; + gcry_sexp_t data; + int ret; + const char *tmp; + size_t size; + + if (hash_len != SHA_DIGEST_LENGTH) { + return -1; + } + + memcpy(zhash + 1, hash, hash_len); + zhash[0] = 0; + + if (gcry_sexp_build(&data, NULL, "(data (value %b))", hash_len + 1, zhash)) { + return -1; + } + + ret = gcry_pk_sign(&sig_sexp, data, dsactx); + + gcry_sexp_release(data); + + if (ret != 0) { + return -1; + } + + memset(sig, 0, 40); + +/* Extract R. */ + + data = gcry_sexp_find_token(sig_sexp, "r", 0); + if (!data) + goto err; + + tmp = gcry_sexp_nth_data(data, 1, &size); + if (!tmp) + goto err; + + if (tmp[0] == '\0') { + tmp++; + size--; + } + + if (size < 1 || size > 20) + goto err; + + memcpy(sig + (20 - size), tmp, size); + + gcry_sexp_release(data); + +/* Extract S. */ + + data = gcry_sexp_find_token(sig_sexp, "s", 0); + if (!data) + goto err; + + tmp = gcry_sexp_nth_data(data, 1, &size); + if (!tmp) + goto err; + + if (tmp[0] == '\0') { + tmp++; + size--; + } + + if (size < 1 || size > 20) + goto err; + + memcpy(sig + 20 + (20 - size), tmp, size); + goto out; + + err: + ret = -1; + + out: + if (sig_sexp) { + gcry_sexp_release(sig_sexp); + } + if (data) { + gcry_sexp_release(data); + } + return ret; +} + +int +_libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx, + const unsigned char *sig, + const unsigned char *m, unsigned long m_len) +{ + unsigned char hash[SHA_DIGEST_LENGTH + 1]; + gcry_sexp_t s_sig, s_hash; + int rc = -1; + + libssh2_sha1(m, m_len, hash + 1); + hash[0] = 0; + + if (gcry_sexp_build(&s_hash, NULL, "(data(flags raw)(value %b))", + SHA_DIGEST_LENGTH + 1, hash)) { + return -1; + } + + if (gcry_sexp_build(&s_sig, NULL, "(sig-val(dsa(r %b)(s %b)))", + 20, sig, 20, sig + 20)) { + gcry_sexp_release(s_hash); + return -1; + } + + rc = gcry_pk_verify(s_sig, s_hash, dsactx); + gcry_sexp_release(s_sig); + gcry_sexp_release(s_hash); + + return (rc == 0) ? 0 : -1; +} + +int +_libssh2_cipher_init(_libssh2_cipher_ctx * h, + _libssh2_cipher_type(algo), + unsigned char *iv, unsigned char *secret, int encrypt) +{ + int ret; + int cipher = _libssh2_gcry_cipher (algo); + int mode = _libssh2_gcry_mode (algo); + int keylen = gcry_cipher_get_algo_keylen(cipher); + + (void) encrypt; + + ret = gcry_cipher_open(h, cipher, mode, 0); + if (ret) { + return -1; + } + + ret = gcry_cipher_setkey(*h, secret, keylen); + if (ret) { + gcry_cipher_close(*h); + return -1; + } + + if (mode != GCRY_CIPHER_MODE_STREAM) { + int blklen = gcry_cipher_get_algo_blklen(cipher); + if (mode == GCRY_CIPHER_MODE_CTR) + ret = gcry_cipher_setctr(*h, iv, blklen); + else + ret = gcry_cipher_setiv(*h, iv, blklen); + if (ret) { + gcry_cipher_close(*h); + return -1; + } + } + + return 0; +} + +int +_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx, + _libssh2_cipher_type(algo), + int encrypt, unsigned char *block, size_t blklen) +{ + int cipher = _libssh2_gcry_cipher (algo); + int ret; + + if (encrypt) { + ret = gcry_cipher_encrypt(*ctx, block, blklen, block, blklen); + } else { + ret = gcry_cipher_decrypt(*ctx, block, blklen, block, blklen); + } + return ret; +} + +int +_libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekeydata, + size_t privatekeydata_len, + const char *passphrase) +{ + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unable to extract public key from private key in memory: " + "Method unimplemented in libgcrypt backend"); +} + +int +_libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekey, + const char *passphrase) +{ + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to extract public key from private key file: " + "Method unimplemented in libgcrypt backend"); +} + +void _libssh2_init_aes_ctr(void) +{ + /* no implementation */ +} +#endif /* LIBSSH2_LIBGCRYPT */ diff --git a/libssh2/mac.c b/libssh2/mac.c new file mode 100644 index 0000000..5ec26eb --- /dev/null +++ b/libssh2/mac.c @@ -0,0 +1,414 @@ +/* Copyright (c) 2004-2007, Sara Golemon + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#include "mac.h" + +#ifdef LIBSSH2_MAC_NONE +/* mac_none_MAC + * Minimalist MAC: No MAC + */ +static int +mac_none_MAC(LIBSSH2_SESSION * session, unsigned char *buf, + uint32_t seqno, const unsigned char *packet, + uint32_t packet_len, const unsigned char *addtl, + uint32_t addtl_len, void **abstract) +{ + return 0; +} + + + + +static LIBSSH2_MAC_METHOD mac_method_none = { + "none", + 0, + 0, + NULL, + mac_none_MAC, + NULL +}; +#endif /* LIBSSH2_MAC_NONE */ + +/* mac_method_common_init + * Initialize simple mac methods + */ +static int +mac_method_common_init(LIBSSH2_SESSION * session, unsigned char *key, + int *free_key, void **abstract) +{ + *abstract = key; + *free_key = 0; + (void) session; + + return 0; +} + + + +/* mac_method_common_dtor + * Cleanup simple mac methods + */ +static int +mac_method_common_dtor(LIBSSH2_SESSION * session, void **abstract) +{ + if (*abstract) { + LIBSSH2_FREE(session, *abstract); + } + *abstract = NULL; + + return 0; +} + + + +#if LIBSSH2_HMAC_SHA512 +/* mac_method_hmac_sha512_hash + * Calculate hash using full sha512 value + */ +static int +mac_method_hmac_sha2_512_hash(LIBSSH2_SESSION * session, + unsigned char *buf, uint32_t seqno, + const unsigned char *packet, + uint32_t packet_len, + const unsigned char *addtl, + uint32_t addtl_len, void **abstract) +{ + libssh2_hmac_ctx ctx; + unsigned char seqno_buf[4]; + (void) session; + + _libssh2_htonu32(seqno_buf, seqno); + + libssh2_hmac_ctx_init(ctx); + libssh2_hmac_sha512_init(&ctx, *abstract, 64); + libssh2_hmac_update(ctx, seqno_buf, 4); + libssh2_hmac_update(ctx, packet, packet_len); + if (addtl && addtl_len) { + libssh2_hmac_update(ctx, addtl, addtl_len); + } + libssh2_hmac_final(ctx, buf); + libssh2_hmac_cleanup(&ctx); + + return 0; +} + + + +static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_512 = { + "hmac-sha2-512", + 64, + 64, + mac_method_common_init, + mac_method_hmac_sha2_512_hash, + mac_method_common_dtor, +}; +#endif + + + +#if LIBSSH2_HMAC_SHA256 +/* mac_method_hmac_sha256_hash + * Calculate hash using full sha256 value + */ +static int +mac_method_hmac_sha2_256_hash(LIBSSH2_SESSION * session, + unsigned char *buf, uint32_t seqno, + const unsigned char *packet, + uint32_t packet_len, + const unsigned char *addtl, + uint32_t addtl_len, void **abstract) +{ + libssh2_hmac_ctx ctx; + unsigned char seqno_buf[4]; + (void) session; + + _libssh2_htonu32(seqno_buf, seqno); + + libssh2_hmac_ctx_init(ctx); + libssh2_hmac_sha256_init(&ctx, *abstract, 32); + libssh2_hmac_update(ctx, seqno_buf, 4); + libssh2_hmac_update(ctx, packet, packet_len); + if (addtl && addtl_len) { + libssh2_hmac_update(ctx, addtl, addtl_len); + } + libssh2_hmac_final(ctx, buf); + libssh2_hmac_cleanup(&ctx); + + return 0; +} + + + +static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_256 = { + "hmac-sha2-256", + 32, + 32, + mac_method_common_init, + mac_method_hmac_sha2_256_hash, + mac_method_common_dtor, +}; +#endif + + + + +/* mac_method_hmac_sha1_hash + * Calculate hash using full sha1 value + */ +static int +mac_method_hmac_sha1_hash(LIBSSH2_SESSION * session, + unsigned char *buf, uint32_t seqno, + const unsigned char *packet, + uint32_t packet_len, + const unsigned char *addtl, + uint32_t addtl_len, void **abstract) +{ + libssh2_hmac_ctx ctx; + unsigned char seqno_buf[4]; + (void) session; + + _libssh2_htonu32(seqno_buf, seqno); + + libssh2_hmac_ctx_init(ctx); + libssh2_hmac_sha1_init(&ctx, *abstract, 20); + libssh2_hmac_update(ctx, seqno_buf, 4); + libssh2_hmac_update(ctx, packet, packet_len); + if (addtl && addtl_len) { + libssh2_hmac_update(ctx, addtl, addtl_len); + } + libssh2_hmac_final(ctx, buf); + libssh2_hmac_cleanup(&ctx); + + return 0; +} + + + +static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1 = { + "hmac-sha1", + 20, + 20, + mac_method_common_init, + mac_method_hmac_sha1_hash, + mac_method_common_dtor, +}; + +/* mac_method_hmac_sha1_96_hash + * Calculate hash using first 96 bits of sha1 value + */ +static int +mac_method_hmac_sha1_96_hash(LIBSSH2_SESSION * session, + unsigned char *buf, uint32_t seqno, + const unsigned char *packet, + uint32_t packet_len, + const unsigned char *addtl, + uint32_t addtl_len, void **abstract) +{ + unsigned char temp[SHA_DIGEST_LENGTH]; + + mac_method_hmac_sha1_hash(session, temp, seqno, packet, packet_len, + addtl, addtl_len, abstract); + memcpy(buf, (char *) temp, 96 / 8); + + return 0; +} + + + +static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1_96 = { + "hmac-sha1-96", + 12, + 20, + mac_method_common_init, + mac_method_hmac_sha1_96_hash, + mac_method_common_dtor, +}; + +#if LIBSSH2_MD5 +/* mac_method_hmac_md5_hash + * Calculate hash using full md5 value + */ +static int +mac_method_hmac_md5_hash(LIBSSH2_SESSION * session, unsigned char *buf, + uint32_t seqno, + const unsigned char *packet, + uint32_t packet_len, + const unsigned char *addtl, + uint32_t addtl_len, void **abstract) +{ + libssh2_hmac_ctx ctx; + unsigned char seqno_buf[4]; + (void) session; + + _libssh2_htonu32(seqno_buf, seqno); + + libssh2_hmac_ctx_init(ctx); + libssh2_hmac_md5_init(&ctx, *abstract, 16); + libssh2_hmac_update(ctx, seqno_buf, 4); + libssh2_hmac_update(ctx, packet, packet_len); + if (addtl && addtl_len) { + libssh2_hmac_update(ctx, addtl, addtl_len); + } + libssh2_hmac_final(ctx, buf); + libssh2_hmac_cleanup(&ctx); + + return 0; +} + + + +static const LIBSSH2_MAC_METHOD mac_method_hmac_md5 = { + "hmac-md5", + 16, + 16, + mac_method_common_init, + mac_method_hmac_md5_hash, + mac_method_common_dtor, +}; + +/* mac_method_hmac_md5_96_hash + * Calculate hash using first 96 bits of md5 value + */ +static int +mac_method_hmac_md5_96_hash(LIBSSH2_SESSION * session, + unsigned char *buf, uint32_t seqno, + const unsigned char *packet, + uint32_t packet_len, + const unsigned char *addtl, + uint32_t addtl_len, void **abstract) +{ + unsigned char temp[MD5_DIGEST_LENGTH]; + mac_method_hmac_md5_hash(session, temp, seqno, packet, packet_len, + addtl, addtl_len, abstract); + memcpy(buf, (char *) temp, 96 / 8); + return 0; +} + + + +static const LIBSSH2_MAC_METHOD mac_method_hmac_md5_96 = { + "hmac-md5-96", + 12, + 16, + mac_method_common_init, + mac_method_hmac_md5_96_hash, + mac_method_common_dtor, +}; +#endif /* LIBSSH2_MD5 */ + +#if LIBSSH2_HMAC_RIPEMD +/* mac_method_hmac_ripemd160_hash + * Calculate hash using ripemd160 value + */ +static int +mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION * session, + unsigned char *buf, uint32_t seqno, + const unsigned char *packet, + uint32_t packet_len, + const unsigned char *addtl, + uint32_t addtl_len, + void **abstract) +{ + libssh2_hmac_ctx ctx; + unsigned char seqno_buf[4]; + (void) session; + + _libssh2_htonu32(seqno_buf, seqno); + + libssh2_hmac_ctx_init(ctx); + libssh2_hmac_ripemd160_init(&ctx, *abstract, 20); + libssh2_hmac_update(ctx, seqno_buf, 4); + libssh2_hmac_update(ctx, packet, packet_len); + if (addtl && addtl_len) { + libssh2_hmac_update(ctx, addtl, addtl_len); + } + libssh2_hmac_final(ctx, buf); + libssh2_hmac_cleanup(&ctx); + + return 0; +} + + + +static const LIBSSH2_MAC_METHOD mac_method_hmac_ripemd160 = { + "hmac-ripemd160", + 20, + 20, + mac_method_common_init, + mac_method_hmac_ripemd160_hash, + mac_method_common_dtor, +}; + +static const LIBSSH2_MAC_METHOD mac_method_hmac_ripemd160_openssh_com = { + "hmac-ripemd160@openssh.com", + 20, + 20, + mac_method_common_init, + mac_method_hmac_ripemd160_hash, + mac_method_common_dtor, +}; +#endif /* LIBSSH2_HMAC_RIPEMD */ + +static const LIBSSH2_MAC_METHOD *mac_methods[] = { +#if LIBSSH2_HMAC_SHA256 + &mac_method_hmac_sha2_256, +#endif +#if LIBSSH2_HMAC_SHA512 + &mac_method_hmac_sha2_512, +#endif + &mac_method_hmac_sha1, + &mac_method_hmac_sha1_96, +#if LIBSSH2_MD5 + &mac_method_hmac_md5, + &mac_method_hmac_md5_96, +#endif +#if LIBSSH2_HMAC_RIPEMD + &mac_method_hmac_ripemd160, + &mac_method_hmac_ripemd160_openssh_com, +#endif /* LIBSSH2_HMAC_RIPEMD */ +#ifdef LIBSSH2_MAC_NONE + &mac_method_none, +#endif /* LIBSSH2_MAC_NONE */ + NULL +}; + +const LIBSSH2_MAC_METHOD ** +_libssh2_mac_methods(void) +{ + return mac_methods; +} diff --git a/libssh2/misc.c b/libssh2/misc.c new file mode 100644 index 0000000..320df44 --- /dev/null +++ b/libssh2/misc.c @@ -0,0 +1,654 @@ +/* Copyright (c) 2004-2007 Sara Golemon + * Copyright (c) 2009-2014 by Daniel Stenberg + * Copyright (c) 2010 Simon Josefsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#include "misc.h" + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_SYS_TIME_H +#include +#endif + +#include +#include + +int _libssh2_error_flags(LIBSSH2_SESSION* session, int errcode, const char* errmsg, int errflags) +{ + if (session->err_flags & LIBSSH2_ERR_FLAG_DUP) + LIBSSH2_FREE(session, (char *)session->err_msg); + + session->err_code = errcode; + session->err_flags = 0; + + if ((errmsg != NULL) && ((errflags & LIBSSH2_ERR_FLAG_DUP) != 0)) { + size_t len = strlen(errmsg); + char *copy = LIBSSH2_ALLOC(session, len + 1); + if (copy) { + memcpy(copy, errmsg, len + 1); + session->err_flags = LIBSSH2_ERR_FLAG_DUP; + session->err_msg = copy; + } + else + /* Out of memory: this code path is very unlikely */ + session->err_msg = "former error forgotten (OOM)"; + } + else + session->err_msg = errmsg; + +#ifdef LIBSSH2DEBUG + if((errcode == LIBSSH2_ERROR_EAGAIN) && !session->api_block_mode) + /* if this is EAGAIN and we're in non-blocking mode, don't generate + a debug output for this */ + return errcode; + _libssh2_debug(session, LIBSSH2_TRACE_ERROR, "%d - %s", session->err_code, + session->err_msg); +#endif + + return errcode; +} + +int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char* errmsg) +{ + return _libssh2_error_flags(session, errcode, errmsg, 0); +} + +#ifdef WIN32 +static int wsa2errno(void) +{ + switch (WSAGetLastError()) { + case WSAEWOULDBLOCK: + return EAGAIN; + + case WSAENOTSOCK: + return EBADF; + + case WSAEINTR: + return EINTR; + + default: + /* It is most important to ensure errno does not stay at EAGAIN + * when a different error occurs so just set errno to a generic + * error */ + return EIO; + } +} +#endif + +/* _libssh2_recv + * + * Replacement for the standard recv, return -errno on failure. + */ +ssize_t +_libssh2_recv(libssh2_socket_t sock, void *buffer, size_t length, + int flags, void **abstract) +{ + ssize_t rc; + + (void) abstract; + + rc = recv(sock, buffer, length, flags); +#ifdef WIN32 + if (rc < 0 ) + return -wsa2errno(); +#elif defined(__VMS) + if (rc < 0 ){ + if ( errno == EWOULDBLOCK ) + return -EAGAIN; + else + return -errno; + } +#else + if (rc < 0 ){ + /* Sometimes the first recv() function call sets errno to ENOENT on + Solaris and HP-UX */ + if ( errno == ENOENT ) + return -EAGAIN; + else + return -errno; + } +#endif + return rc; +} + +/* _libssh2_send + * + * Replacement for the standard send, return -errno on failure. + */ +ssize_t +_libssh2_send(libssh2_socket_t sock, const void *buffer, size_t length, + int flags, void **abstract) +{ + ssize_t rc; + + (void) abstract; + + rc = send(sock, buffer, length, flags); +#ifdef WIN32 + if (rc < 0 ) + return -wsa2errno(); +#elif defined(__VMS) + if (rc < 0 ) { + if ( errno == EWOULDBLOCK ) + return -EAGAIN; + else + return -errno; + } +#else + if (rc < 0 ) + return -errno; +#endif + return rc; +} + +/* libssh2_ntohu32 + */ +unsigned int +_libssh2_ntohu32(const unsigned char *buf) +{ + return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; +} + + +/* _libssh2_ntohu64 + */ +libssh2_uint64_t +_libssh2_ntohu64(const unsigned char *buf) +{ + unsigned long msl, lsl; + + msl = ((libssh2_uint64_t)buf[0] << 24) | ((libssh2_uint64_t)buf[1] << 16) + | ((libssh2_uint64_t)buf[2] << 8) | (libssh2_uint64_t)buf[3]; + lsl = ((libssh2_uint64_t)buf[4] << 24) | ((libssh2_uint64_t)buf[5] << 16) + | ((libssh2_uint64_t)buf[6] << 8) | (libssh2_uint64_t)buf[7]; + + return ((libssh2_uint64_t)msl <<32) | lsl; +} + +/* _libssh2_htonu32 + */ +void +_libssh2_htonu32(unsigned char *buf, uint32_t value) +{ + buf[0] = (value >> 24) & 0xFF; + buf[1] = (value >> 16) & 0xFF; + buf[2] = (value >> 8) & 0xFF; + buf[3] = value & 0xFF; +} + +/* _libssh2_store_u32 + */ +void _libssh2_store_u32(unsigned char **buf, uint32_t value) +{ + _libssh2_htonu32(*buf, value); + *buf += sizeof(uint32_t); +} + +/* _libssh2_store_str + */ +void _libssh2_store_str(unsigned char **buf, const char *str, size_t len) +{ + _libssh2_store_u32(buf, (uint32_t)len); + if(len) { + memcpy(*buf, str, len); + *buf += len; + } +} + +/* Base64 Conversion */ + +static const char base64_table[] = +{ + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0' +}; + +static const char base64_pad = '='; + +static const short base64_reverse_table[256] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 +}; + +/* libssh2_base64_decode + * + * Decode a base64 chunk and store it into a newly alloc'd buffer + */ +LIBSSH2_API int +libssh2_base64_decode(LIBSSH2_SESSION *session, char **data, + unsigned int *datalen, const char *src, + unsigned int src_len) +{ + unsigned char *s, *d; + short v; + int i = 0, len = 0; + + *data = LIBSSH2_ALLOC(session, (3 * src_len / 4) + 1); + d = (unsigned char *) *data; + if (!d) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for base64 decoding"); + } + + for(s = (unsigned char *) src; ((char *) s) < (src + src_len); s++) { + if ((v = base64_reverse_table[*s]) < 0) + continue; + switch (i % 4) { + case 0: + d[len] = (unsigned char)(v << 2); + break; + case 1: + d[len++] |= v >> 4; + d[len] = (unsigned char)(v << 4); + break; + case 2: + d[len++] |= v >> 2; + d[len] = (unsigned char)(v << 6); + break; + case 3: + d[len++] |= v; + break; + } + i++; + } + if ((i % 4) == 1) { + /* Invalid -- We have a byte which belongs exclusively to a partial + octet */ + LIBSSH2_FREE(session, *data); + return _libssh2_error(session, LIBSSH2_ERROR_INVAL, "Invalid base64"); + } + + *datalen = len; + return 0; +} + +/* ---- Base64 Encoding/Decoding Table --- */ +static const char table64[]= + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/* + * _libssh2_base64_encode() + * + * Returns the length of the newly created base64 string. The third argument + * is a pointer to an allocated area holding the base64 data. If something + * went wrong, 0 is returned. + * + */ +size_t _libssh2_base64_encode(LIBSSH2_SESSION *session, + const char *inp, size_t insize, char **outptr) +{ + unsigned char ibuf[3]; + unsigned char obuf[4]; + int i; + int inputparts; + char *output; + char *base64data; + const char *indata = inp; + + *outptr = NULL; /* set to NULL in case of failure before we reach the end */ + + if(0 == insize) + insize = strlen(indata); + + base64data = output = LIBSSH2_ALLOC(session, insize*4/3+4); + if(NULL == output) + return 0; + + while(insize > 0) { + for (i = inputparts = 0; i < 3; i++) { + if(insize > 0) { + inputparts++; + ibuf[i] = *indata; + indata++; + insize--; + } + else + ibuf[i] = 0; + } + + obuf[0] = (unsigned char) ((ibuf[0] & 0xFC) >> 2); + obuf[1] = (unsigned char) (((ibuf[0] & 0x03) << 4) | \ + ((ibuf[1] & 0xF0) >> 4)); + obuf[2] = (unsigned char) (((ibuf[1] & 0x0F) << 2) | \ + ((ibuf[2] & 0xC0) >> 6)); + obuf[3] = (unsigned char) (ibuf[2] & 0x3F); + + switch(inputparts) { + case 1: /* only one byte read */ + snprintf(output, 5, "%c%c==", + table64[obuf[0]], + table64[obuf[1]]); + break; + case 2: /* two bytes read */ + snprintf(output, 5, "%c%c%c=", + table64[obuf[0]], + table64[obuf[1]], + table64[obuf[2]]); + break; + default: + snprintf(output, 5, "%c%c%c%c", + table64[obuf[0]], + table64[obuf[1]], + table64[obuf[2]], + table64[obuf[3]] ); + break; + } + output += 4; + } + *output=0; + *outptr = base64data; /* make it return the actual data memory */ + + return strlen(base64data); /* return the length of the new data */ +} +/* ---- End of Base64 Encoding ---- */ + +LIBSSH2_API void +libssh2_free(LIBSSH2_SESSION *session, void *ptr) +{ + LIBSSH2_FREE(session, ptr); +} + +#ifdef LIBSSH2DEBUG +LIBSSH2_API int +libssh2_trace(LIBSSH2_SESSION * session, int bitmask) +{ + session->showmask = bitmask; + return 0; +} + +LIBSSH2_API int +libssh2_trace_sethandler(LIBSSH2_SESSION *session, void* handler_context, + libssh2_trace_handler_func callback) +{ + session->tracehandler = callback; + session->tracehandler_context = handler_context; + return 0; +} + +void +_libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...) +{ + char buffer[1536]; + int len, msglen, buflen = sizeof(buffer); + va_list vargs; + struct timeval now; + static int firstsec; + static const char *const contexts[] = { + "Unknown", + "Transport", + "Key Ex", + "Userauth", + "Conn", + "SCP", + "SFTP", + "Failure Event", + "Publickey", + "Socket", + }; + const char* contexttext = contexts[0]; + unsigned int contextindex; + + if (!(session->showmask & context)) { + /* no such output asked for */ + return; + } + + /* Find the first matching context string for this message */ + for (contextindex = 0; contextindex < ARRAY_SIZE(contexts); + contextindex++) { + if ((context & (1 << contextindex)) != 0) { + contexttext = contexts[contextindex]; + break; + } + } + + _libssh2_gettimeofday(&now, NULL); + if(!firstsec) { + firstsec = now.tv_sec; + } + now.tv_sec -= firstsec; + + len = snprintf(buffer, buflen, "[libssh2] %d.%06d %s: ", + (int)now.tv_sec, (int)now.tv_usec, contexttext); + + if (len >= buflen) + msglen = buflen - 1; + else { + buflen -= len; + msglen = len; + va_start(vargs, format); + len = vsnprintf(buffer + msglen, buflen, format, vargs); + va_end(vargs); + msglen += len < buflen ? len : buflen - 1; + } + + if (session->tracehandler) + (session->tracehandler)(session, session->tracehandler_context, buffer, + msglen); + else + fprintf(stderr, "%s\n", buffer); +} + +#else +LIBSSH2_API int +libssh2_trace(LIBSSH2_SESSION * session, int bitmask) +{ + (void) session; + (void) bitmask; + return 0; +} + +LIBSSH2_API int +libssh2_trace_sethandler(LIBSSH2_SESSION *session, void* handler_context, + libssh2_trace_handler_func callback) +{ + (void) session; + (void) handler_context; + (void) callback; + return 0; +} +#endif + +/* init the list head */ +void _libssh2_list_init(struct list_head *head) +{ + head->first = head->last = NULL; +} + +/* add a node to the list */ +void _libssh2_list_add(struct list_head *head, + struct list_node *entry) +{ + /* store a pointer to the head */ + entry->head = head; + + /* we add this entry at the "top" so it has no next */ + entry->next = NULL; + + /* make our prev point to what the head thinks is last */ + entry->prev = head->last; + + /* and make head's last be us now */ + head->last = entry; + + /* make sure our 'prev' node points to us next */ + if(entry->prev) + entry->prev->next = entry; + else + head->first = entry; +} + +/* return the "first" node in the list this head points to */ +void *_libssh2_list_first(struct list_head *head) +{ + return head->first; +} + +/* return the next node in the list */ +void *_libssh2_list_next(struct list_node *node) +{ + return node->next; +} + +/* return the prev node in the list */ +void *_libssh2_list_prev(struct list_node *node) +{ + return node->prev; +} + +/* remove this node from the list */ +void _libssh2_list_remove(struct list_node *entry) +{ + if(entry->prev) + entry->prev->next = entry->next; + else + entry->head->first = entry->next; + + if(entry->next) + entry->next->prev = entry->prev; + else + entry->head->last = entry->prev; +} + +#if 0 +/* insert a node before the given 'after' entry */ +void _libssh2_list_insert(struct list_node *after, /* insert before this */ + struct list_node *entry) +{ + /* 'after' is next to 'entry' */ + bentry->next = after; + + /* entry's prev is then made to be the prev after current has */ + entry->prev = after->prev; + + /* the node that is now before 'entry' was previously before 'after' + and must be made to point to 'entry' correctly */ + if(entry->prev) + entry->prev->next = entry; + else + /* there was no node before this, so we make sure we point the head + pointer to this node */ + after->head->first = entry; + + /* after's prev entry points back to entry */ + after->prev = entry; + + /* after's next entry is still the same as before */ + + /* entry's head is the same as after's */ + entry->head = after->head; +} + +#endif + +/* this define is defined in misc.h for the correct platforms */ +#ifdef LIBSSH2_GETTIMEOFDAY_WIN32 +/* + * gettimeofday + * Implementation according to: + * The Open Group Base Specifications Issue 6 + * IEEE Std 1003.1, 2004 Edition + */ + +/* + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Contributed by: + * Danny Smith + */ + +/* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */ +#define _W32_FT_OFFSET (116444736000000000) + +int __cdecl _libssh2_gettimeofday(struct timeval *tp, void *tzp) + { + union { + unsigned __int64 ns100; /*time since 1 Jan 1601 in 100ns units */ + FILETIME ft; + } _now; + (void)tzp; + if(tp) + { + GetSystemTimeAsFileTime (&_now.ft); + tp->tv_usec=(long)((_now.ns100 / 10) % 1000000 ); + tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000); + } + /* Always return 0 as per Open Group Base Specifications Issue 6. + Do not set errno on error. */ + return 0; +} + + +#endif + +void *_libssh2_calloc(LIBSSH2_SESSION* session, size_t size) +{ + void *p = LIBSSH2_ALLOC(session, size); + if(p) { + memset(p, 0, size); + } + return p; +} diff --git a/libssh2/module.mk b/libssh2/module.mk new file mode 100644 index 0000000..34a3f0e --- /dev/null +++ b/libssh2/module.mk @@ -0,0 +1,40 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/libssh2 Makefile fragment +# +####################################################################### + +if BUILD_SSH_TUNNEL + +pgadmin3_SOURCES += \ + libssh2/agent.c \ + libssh2/channel.c \ + libssh2/comp.c \ + libssh2/crypt.c \ + libssh2/global.c \ + libssh2/hostkey.c \ + libssh2/keepalive.c \ + libssh2/kex.c \ + libssh2/knownhost.c \ + libssh2/libgcrypt.c \ + libssh2/mac.c \ + libssh2/misc.c \ + libssh2/openssl.c \ + libssh2/packet.c \ + libssh2/pem.c \ + libssh2/publickey.c \ + libssh2/scp.c \ + libssh2/session.c \ + libssh2/sftp.c \ + libssh2/transport.c \ + libssh2/userauth.c \ + libssh2/version.c + +EXTRA_DIST += \ + libssh2/module.mk +endif diff --git a/libssh2/openssl.c b/libssh2/openssl.c new file mode 100644 index 0000000..c3de2d1 --- /dev/null +++ b/libssh2/openssl.c @@ -0,0 +1,963 @@ +/* Copyright (C) 2009, 2010 Simon Josefsson + * Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved. + * Copyright (c) 2004-2006, Sara Golemon + * + * Author: Simon Josefsson + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" + +#ifdef LIBSSH2_OPENSSL /* compile only if we build with openssl */ + +#include + +#ifndef EVP_MAX_BLOCK_LENGTH +#define EVP_MAX_BLOCK_LENGTH 32 +#endif + +int +_libssh2_rsa_new(libssh2_rsa_ctx ** rsa, + const unsigned char *edata, + unsigned long elen, + const unsigned char *ndata, + unsigned long nlen, + const unsigned char *ddata, + unsigned long dlen, + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *e1data, + unsigned long e1len, + const unsigned char *e2data, + unsigned long e2len, + const unsigned char *coeffdata, unsigned long coefflen) +{ + *rsa = RSA_new(); + + (*rsa)->e = BN_new(); + BN_bin2bn(edata, elen, (*rsa)->e); + + (*rsa)->n = BN_new(); + BN_bin2bn(ndata, nlen, (*rsa)->n); + + if (ddata) { + (*rsa)->d = BN_new(); + BN_bin2bn(ddata, dlen, (*rsa)->d); + + (*rsa)->p = BN_new(); + BN_bin2bn(pdata, plen, (*rsa)->p); + + (*rsa)->q = BN_new(); + BN_bin2bn(qdata, qlen, (*rsa)->q); + + (*rsa)->dmp1 = BN_new(); + BN_bin2bn(e1data, e1len, (*rsa)->dmp1); + + (*rsa)->dmq1 = BN_new(); + BN_bin2bn(e2data, e2len, (*rsa)->dmq1); + + (*rsa)->iqmp = BN_new(); + BN_bin2bn(coeffdata, coefflen, (*rsa)->iqmp); + } + return 0; +} + +int +_libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsactx, + const unsigned char *sig, + unsigned long sig_len, + const unsigned char *m, unsigned long m_len) +{ + unsigned char hash[SHA_DIGEST_LENGTH]; + int ret; + + if (_libssh2_sha1(m, m_len, hash)) + return -1; /* failure */ + ret = RSA_verify(NID_sha1, hash, SHA_DIGEST_LENGTH, + (unsigned char *) sig, sig_len, rsactx); + return (ret == 1) ? 0 : -1; +} + +#if LIBSSH2_DSA +int +_libssh2_dsa_new(libssh2_dsa_ctx ** dsactx, + const unsigned char *p, + unsigned long p_len, + const unsigned char *q, + unsigned long q_len, + const unsigned char *g, + unsigned long g_len, + const unsigned char *y, + unsigned long y_len, + const unsigned char *x, unsigned long x_len) +{ + *dsactx = DSA_new(); + + (*dsactx)->p = BN_new(); + BN_bin2bn(p, p_len, (*dsactx)->p); + + (*dsactx)->q = BN_new(); + BN_bin2bn(q, q_len, (*dsactx)->q); + + (*dsactx)->g = BN_new(); + BN_bin2bn(g, g_len, (*dsactx)->g); + + (*dsactx)->pub_key = BN_new(); + BN_bin2bn(y, y_len, (*dsactx)->pub_key); + + if (x_len) { + (*dsactx)->priv_key = BN_new(); + BN_bin2bn(x, x_len, (*dsactx)->priv_key); + } + + return 0; +} + +int +_libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx, + const unsigned char *sig, + const unsigned char *m, unsigned long m_len) +{ + unsigned char hash[SHA_DIGEST_LENGTH]; + DSA_SIG dsasig; + int ret = -1; + + dsasig.r = BN_new(); + BN_bin2bn(sig, 20, dsasig.r); + dsasig.s = BN_new(); + BN_bin2bn(sig + 20, 20, dsasig.s); + + if (!_libssh2_sha1(m, m_len, hash)) + /* _libssh2_sha1() succeeded */ + ret = DSA_do_verify(hash, SHA_DIGEST_LENGTH, &dsasig, dsactx); + + BN_clear_free(dsasig.s); + BN_clear_free(dsasig.r); + + return (ret == 1) ? 0 : -1; +} +#endif /* LIBSSH_DSA */ + +int +_libssh2_cipher_init(_libssh2_cipher_ctx * h, + _libssh2_cipher_type(algo), + unsigned char *iv, unsigned char *secret, int encrypt) +{ + EVP_CIPHER_CTX_init(h); + return !EVP_CipherInit(h, algo(), secret, iv, encrypt); +} + +int +_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx, + _libssh2_cipher_type(algo), + int encrypt, unsigned char *block, size_t blocksize) +{ + unsigned char buf[EVP_MAX_BLOCK_LENGTH]; + int ret; + (void) algo; + (void) encrypt; + + ret = EVP_Cipher(ctx, buf, block, blocksize); + if (ret == 1) { + memcpy(block, buf, blocksize); + } + return ret == 1 ? 0 : 1; +} + +#if LIBSSH2_AES_CTR + +#include +#include + +typedef struct +{ + AES_KEY key; + EVP_CIPHER_CTX *aes_ctx; + unsigned char ctr[AES_BLOCK_SIZE]; +} aes_ctr_ctx; + +static int +aes_ctr_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) /* init key */ +{ + /* + * variable "c" is leaked from this scope, but is later freed + * in aes_ctr_cleanup + */ + aes_ctr_ctx *c; + const EVP_CIPHER *aes_cipher; + (void) enc; + + switch (ctx->key_len) { + case 16: + aes_cipher = EVP_aes_128_ecb(); + break; + case 24: + aes_cipher = EVP_aes_192_ecb(); + break; + case 32: + aes_cipher = EVP_aes_256_ecb(); + break; + default: + return 0; + } + + c = malloc(sizeof(*c)); + if (c == NULL) + return 0; + + c->aes_ctx = malloc(sizeof(EVP_CIPHER_CTX)); + if (c->aes_ctx == NULL) { + free(c); + return 0; + } + + if (EVP_EncryptInit(c->aes_ctx, aes_cipher, key, NULL) != 1) { + free(c->aes_ctx); + free(c); + return 0; + } + + EVP_CIPHER_CTX_set_padding(c->aes_ctx, 0); + + memcpy(c->ctr, iv, AES_BLOCK_SIZE); + + EVP_CIPHER_CTX_set_app_data(ctx, c); + + return 1; +} + +static int +aes_ctr_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, + size_t inl) /* encrypt/decrypt data */ +{ + aes_ctr_ctx *c = EVP_CIPHER_CTX_get_app_data(ctx); + unsigned char b1[AES_BLOCK_SIZE]; + size_t i = 0; + int outlen = 0; + + if (inl != 16) /* libssh2 only ever encrypt one block */ + return 0; + + if (c == NULL) { + return 0; + } + +/* + To encrypt a packet P=P1||P2||...||Pn (where P1, P2, ..., Pn are each + blocks of length L), the encryptor first encrypts with + to obtain a block B1. The block B1 is then XORed with P1 to generate + the ciphertext block C1. The counter X is then incremented +*/ + + if (EVP_EncryptUpdate(c->aes_ctx, b1, &outlen, c->ctr, AES_BLOCK_SIZE) != 1) { + return 0; + } + + for (i = 0; i < 16; i++) + *out++ = *in++ ^ b1[i]; + + i = 15; + while (c->ctr[i]++ == 0xFF) { + if (i == 0) + break; + i--; + } + + return 1; +} + +static int +aes_ctr_cleanup(EVP_CIPHER_CTX *ctx) /* cleanup ctx */ +{ + aes_ctr_ctx *c = EVP_CIPHER_CTX_get_app_data(ctx); + + if (c == NULL) { + return 1; + } + + if (c->aes_ctx != NULL) { + _libssh2_cipher_dtor(c->aes_ctx); + free(c->aes_ctx); + } + + free(c); + + return 1; +} + +static const EVP_CIPHER * +make_ctr_evp (size_t keylen, EVP_CIPHER *aes_ctr_cipher) +{ + aes_ctr_cipher->block_size = 16; + aes_ctr_cipher->key_len = keylen; + aes_ctr_cipher->iv_len = 16; + aes_ctr_cipher->init = aes_ctr_init; + aes_ctr_cipher->do_cipher = aes_ctr_do_cipher; + aes_ctr_cipher->cleanup = aes_ctr_cleanup; + + return aes_ctr_cipher; +} + +const EVP_CIPHER * +_libssh2_EVP_aes_128_ctr(void) +{ + static EVP_CIPHER aes_ctr_cipher; + return !aes_ctr_cipher.key_len? + make_ctr_evp (16, &aes_ctr_cipher) : &aes_ctr_cipher; +} + +const EVP_CIPHER * +_libssh2_EVP_aes_192_ctr(void) +{ + static EVP_CIPHER aes_ctr_cipher; + return !aes_ctr_cipher.key_len? + make_ctr_evp (24, &aes_ctr_cipher) : &aes_ctr_cipher; +} + +const EVP_CIPHER * +_libssh2_EVP_aes_256_ctr(void) +{ + static EVP_CIPHER aes_ctr_cipher; + return !aes_ctr_cipher.key_len? + make_ctr_evp (32, &aes_ctr_cipher) : &aes_ctr_cipher; +} + +void _libssh2_init_aes_ctr(void) +{ + _libssh2_EVP_aes_128_ctr(); + _libssh2_EVP_aes_192_ctr(); + _libssh2_EVP_aes_256_ctr(); +} + +#else +void _libssh2_init_aes_ctr(void) {} +#endif /* LIBSSH2_AES_CTR */ + +/* TODO: Optionally call a passphrase callback specified by the + * calling program + */ +static int +passphrase_cb(char *buf, int size, int rwflag, char *passphrase) +{ + int passphrase_len = strlen(passphrase); + (void) rwflag; + + if (passphrase_len > (size - 1)) { + passphrase_len = size - 1; + } + memcpy(buf, passphrase, passphrase_len); + buf[passphrase_len] = '\0'; + + return passphrase_len; +} + +typedef void * (*pem_read_bio_func)(BIO *, void **, pem_password_cb *, + void * u); + +static int +read_private_key_from_memory(void ** key_ctx, + pem_read_bio_func read_private_key, + const char * filedata, + size_t filedata_len, + unsigned const char *passphrase) +{ + BIO * bp; + + *key_ctx = NULL; + + bp = BIO_new_mem_buf((char *)filedata, filedata_len); + if (!bp) { + return -1; + } + *key_ctx = read_private_key(bp, NULL, (pem_password_cb *) passphrase_cb, + (void *) passphrase); + + BIO_free(bp); + return (*key_ctx) ? 0 : -1; +} + +static int +read_private_key_from_file(void ** key_ctx, + pem_read_bio_func read_private_key, + const char * filename, + unsigned const char *passphrase) +{ + BIO * bp; + + *key_ctx = NULL; + + bp = BIO_new_file(filename, "r"); + if (!bp) { + return -1; + } + + *key_ctx = read_private_key(bp, NULL, (pem_password_cb *) passphrase_cb, + (void *) passphrase); + + BIO_free(bp); + return (*key_ctx) ? 0 : -1; +} + +int +_libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa, + LIBSSH2_SESSION * session, + const char *filedata, size_t filedata_len, + unsigned const char *passphrase) +{ + pem_read_bio_func read_rsa = + (pem_read_bio_func) &PEM_read_bio_RSAPrivateKey; + (void) session; + + _libssh2_init_if_needed(); + + return read_private_key_from_memory((void **) rsa, read_rsa, + filedata, filedata_len, passphrase); +} + +int +_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa, + LIBSSH2_SESSION * session, + const char *filename, unsigned const char *passphrase) +{ + pem_read_bio_func read_rsa = + (pem_read_bio_func) &PEM_read_bio_RSAPrivateKey; + (void) session; + + _libssh2_init_if_needed (); + + return read_private_key_from_file((void **) rsa, read_rsa, + filename, passphrase); +} + +#if LIBSSH2_DSA +int +_libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa, + LIBSSH2_SESSION * session, + const char *filedata, size_t filedata_len, + unsigned const char *passphrase) +{ + pem_read_bio_func read_dsa = + (pem_read_bio_func) &PEM_read_bio_DSAPrivateKey; + (void) session; + + _libssh2_init_if_needed(); + + return read_private_key_from_memory((void **) dsa, read_dsa, + filedata, filedata_len, passphrase); +} + +int +_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa, + LIBSSH2_SESSION * session, + const char *filename, unsigned const char *passphrase) +{ + pem_read_bio_func read_dsa = + (pem_read_bio_func) &PEM_read_bio_DSAPrivateKey; + (void) session; + + _libssh2_init_if_needed (); + + return read_private_key_from_file((void **) dsa, read_dsa, + filename, passphrase); +} +#endif /* LIBSSH_DSA */ + +int +_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session, + libssh2_rsa_ctx * rsactx, + const unsigned char *hash, + size_t hash_len, + unsigned char **signature, size_t *signature_len) +{ + int ret; + unsigned char *sig; + unsigned int sig_len; + + sig_len = RSA_size(rsactx); + sig = LIBSSH2_ALLOC(session, sig_len); + + if (!sig) { + return -1; + } + + ret = RSA_sign(NID_sha1, hash, hash_len, sig, &sig_len, rsactx); + + if (!ret) { + LIBSSH2_FREE(session, sig); + return -1; + } + + *signature = sig; + *signature_len = sig_len; + + return 0; +} + +#if LIBSSH2_DSA +int +_libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx, + const unsigned char *hash, + unsigned long hash_len, unsigned char *signature) +{ + DSA_SIG *sig; + int r_len, s_len; + (void) hash_len; + + sig = DSA_do_sign(hash, SHA_DIGEST_LENGTH, dsactx); + if (!sig) { + return -1; + } + + r_len = BN_num_bytes(sig->r); + if (r_len < 1 || r_len > 20) { + DSA_SIG_free(sig); + return -1; + } + s_len = BN_num_bytes(sig->s); + if (s_len < 1 || s_len > 20) { + DSA_SIG_free(sig); + return -1; + } + + memset(signature, 0, 40); + + BN_bn2bin(sig->r, signature + (20 - r_len)); + BN_bn2bin(sig->s, signature + 20 + (20 - s_len)); + + DSA_SIG_free(sig); + + return 0; +} +#endif /* LIBSSH_DSA */ + +int +_libssh2_sha1_init(libssh2_sha1_ctx *ctx) +{ + EVP_MD_CTX_init(ctx); + return EVP_DigestInit(ctx, EVP_get_digestbyname("sha1")); +} + +int +_libssh2_sha1(const unsigned char *message, unsigned long len, + unsigned char *out) +{ + EVP_MD_CTX ctx; + + EVP_MD_CTX_init(&ctx); + if (EVP_DigestInit(&ctx, EVP_get_digestbyname("sha1"))) { + EVP_DigestUpdate(&ctx, message, len); + EVP_DigestFinal(&ctx, out, NULL); + return 0; /* success */ + } + return 1; /* error */ +} + +int +_libssh2_sha256_init(libssh2_sha256_ctx *ctx) +{ + EVP_MD_CTX_init(ctx); + return EVP_DigestInit(ctx, EVP_get_digestbyname("sha256")); +} + +int +_libssh2_sha256(const unsigned char *message, unsigned long len, + unsigned char *out) +{ + EVP_MD_CTX ctx; + + EVP_MD_CTX_init(&ctx); + if(EVP_DigestInit(&ctx, EVP_get_digestbyname("sha256"))) { + EVP_DigestUpdate(&ctx, message, len); + EVP_DigestFinal(&ctx, out, NULL); + return 0; /* success */ + } + return 1; /* error */ +} + +int +_libssh2_md5_init(libssh2_md5_ctx *ctx) +{ + EVP_MD_CTX_init(ctx); + return EVP_DigestInit(ctx, EVP_get_digestbyname("md5")); +} + +static unsigned char * +write_bn(unsigned char *buf, const BIGNUM *bn, int bn_bytes) +{ + unsigned char *p = buf; + + /* Left space for bn size which will be written below. */ + p += 4; + + *p = 0; + BN_bn2bin(bn, p + 1); + if (!(*(p + 1) & 0x80)) { + memmove(p, p + 1, --bn_bytes); + } + _libssh2_htonu32(p - 4, bn_bytes); /* Post write bn size. */ + + return p + bn_bytes; +} + +static unsigned char * +gen_publickey_from_rsa(LIBSSH2_SESSION *session, RSA *rsa, + size_t *key_len) +{ + int e_bytes, n_bytes; + unsigned long len; + unsigned char* key; + unsigned char* p; + + e_bytes = BN_num_bytes(rsa->e) + 1; + n_bytes = BN_num_bytes(rsa->n) + 1; + + /* Key form is "ssh-rsa" + e + n. */ + len = 4 + 7 + 4 + e_bytes + 4 + n_bytes; + + key = LIBSSH2_ALLOC(session, len); + if (key == NULL) { + return NULL; + } + + /* Process key encoding. */ + p = key; + + _libssh2_htonu32(p, 7); /* Key type. */ + p += 4; + memcpy(p, "ssh-rsa", 7); + p += 7; + + p = write_bn(p, rsa->e, e_bytes); + p = write_bn(p, rsa->n, n_bytes); + + *key_len = (size_t)(p - key); + return key; +} + +#if LIBSSH2_DSA +static unsigned char * +gen_publickey_from_dsa(LIBSSH2_SESSION* session, DSA *dsa, + size_t *key_len) +{ + int p_bytes, q_bytes, g_bytes, k_bytes; + unsigned long len; + unsigned char* key; + unsigned char* p; + + p_bytes = BN_num_bytes(dsa->p) + 1; + q_bytes = BN_num_bytes(dsa->q) + 1; + g_bytes = BN_num_bytes(dsa->g) + 1; + k_bytes = BN_num_bytes(dsa->pub_key) + 1; + + /* Key form is "ssh-dss" + p + q + g + pub_key. */ + len = 4 + 7 + 4 + p_bytes + 4 + q_bytes + 4 + g_bytes + 4 + k_bytes; + + key = LIBSSH2_ALLOC(session, len); + if (key == NULL) { + return NULL; + } + + /* Process key encoding. */ + p = key; + + _libssh2_htonu32(p, 7); /* Key type. */ + p += 4; + memcpy(p, "ssh-dss", 7); + p += 7; + + p = write_bn(p, dsa->p, p_bytes); + p = write_bn(p, dsa->q, q_bytes); + p = write_bn(p, dsa->g, g_bytes); + p = write_bn(p, dsa->pub_key, k_bytes); + + *key_len = (size_t)(p - key); + return key; +} +#endif /* LIBSSH_DSA */ + +static int +gen_publickey_from_rsa_evp(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + EVP_PKEY *pk) +{ + RSA* rsa = NULL; + unsigned char* key; + unsigned char* method_buf = NULL; + size_t key_len; + + _libssh2_debug(session, + LIBSSH2_TRACE_AUTH, + "Computing public key from RSA private key envelop"); + + rsa = EVP_PKEY_get1_RSA(pk); + if (rsa == NULL) { + /* Assume memory allocation error... what else could it be ? */ + goto __alloc_error; + } + + method_buf = LIBSSH2_ALLOC(session, 7); /* ssh-rsa. */ + if (method_buf == NULL) { + goto __alloc_error; + } + + key = gen_publickey_from_rsa(session, rsa, &key_len); + if (key == NULL) { + goto __alloc_error; + } + RSA_free(rsa); + + memcpy(method_buf, "ssh-rsa", 7); + *method = method_buf; + *method_len = 7; + *pubkeydata = key; + *pubkeydata_len = key_len; + return 0; + + __alloc_error: + if (rsa != NULL) { + RSA_free(rsa); + } + if (method_buf != NULL) { + LIBSSH2_FREE(session, method_buf); + } + + return _libssh2_error(session, + LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for private key data"); +} + +#if LIBSSH2_DSA +static int +gen_publickey_from_dsa_evp(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + EVP_PKEY *pk) +{ + DSA* dsa = NULL; + unsigned char* key; + unsigned char* method_buf = NULL; + size_t key_len; + + _libssh2_debug(session, + LIBSSH2_TRACE_AUTH, + "Computing public key from DSA private key envelop"); + + dsa = EVP_PKEY_get1_DSA(pk); + if (dsa == NULL) { + /* Assume memory allocation error... what else could it be ? */ + goto __alloc_error; + } + + method_buf = LIBSSH2_ALLOC(session, 7); /* ssh-dss. */ + if (method_buf == NULL) { + goto __alloc_error; + } + + key = gen_publickey_from_dsa(session, dsa, &key_len); + if (key == NULL) { + goto __alloc_error; + } + DSA_free(dsa); + + memcpy(method_buf, "ssh-dss", 7); + *method = method_buf; + *method_len = 7; + *pubkeydata = key; + *pubkeydata_len = key_len; + return 0; + + __alloc_error: + if (dsa != NULL) { + DSA_free(dsa); + } + if (method_buf != NULL) { + LIBSSH2_FREE(session, method_buf); + } + + return _libssh2_error(session, + LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for private key data"); +} +#endif /* LIBSSH_DSA */ + +int +_libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekey, + const char *passphrase) +{ + int st; + BIO* bp; + EVP_PKEY* pk; + + _libssh2_debug(session, + LIBSSH2_TRACE_AUTH, + "Computing public key from private key file: %s", + privatekey); + + bp = BIO_new_file(privatekey, "r"); + if (bp == NULL) { + return _libssh2_error(session, + LIBSSH2_ERROR_FILE, + "Unable to extract public key from private key " + "file: Unable to open private key file"); + } + if (!EVP_get_cipherbyname("des")) { + /* If this cipher isn't loaded it's a pretty good indication that none + * are. I have *NO DOUBT* that there's a better way to deal with this + * ($#&%#$(%$#( Someone buy me an OpenSSL manual and I'll read up on + * it. + */ + OpenSSL_add_all_ciphers(); + } + BIO_reset(bp); + pk = PEM_read_bio_PrivateKey(bp, NULL, NULL, (void*)passphrase); + BIO_free(bp); + + if (pk == NULL) { + return _libssh2_error(session, + LIBSSH2_ERROR_FILE, + "Unable to extract public key " + "from private key file: " + "Wrong passphrase or invalid/unrecognized " + "private key file format"); + } + + switch (pk->type) { + case EVP_PKEY_RSA : + st = gen_publickey_from_rsa_evp( + session, method, method_len, pubkeydata, pubkeydata_len, pk); + break; + +#if LIBSSH2_DSA + case EVP_PKEY_DSA : + st = gen_publickey_from_dsa_evp( + session, method, method_len, pubkeydata, pubkeydata_len, pk); + break; +#endif /* LIBSSH_DSA */ + + default : + st = _libssh2_error(session, + LIBSSH2_ERROR_FILE, + "Unable to extract public key " + "from private key file: " + "Unsupported private key file format"); + break; + } + + EVP_PKEY_free(pk); + return st; +} + +int +_libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekeydata, + size_t privatekeydata_len, + const char *passphrase) +{ + int st; + BIO* bp; + EVP_PKEY* pk; + + _libssh2_debug(session, + LIBSSH2_TRACE_AUTH, + "Computing public key from private key."); + + bp = BIO_new_mem_buf((char *)privatekeydata, privatekeydata_len); + if (!bp) { + return -1; + } + if (!EVP_get_cipherbyname("des")) { + /* If this cipher isn't loaded it's a pretty good indication that none + * are. I have *NO DOUBT* that there's a better way to deal with this + * ($#&%#$(%$#( Someone buy me an OpenSSL manual and I'll read up on + * it. + */ + OpenSSL_add_all_ciphers(); + } + BIO_reset(bp); + pk = PEM_read_bio_PrivateKey(bp, NULL, NULL, (void*)passphrase); + BIO_free(bp); + + if (pk == NULL) { + return _libssh2_error(session, + LIBSSH2_ERROR_FILE, + "Unable to extract public key " + "from private key file: " + "Wrong passphrase or invalid/unrecognized " + "private key file format"); + } + + switch (pk->type) { + case EVP_PKEY_RSA : + st = gen_publickey_from_rsa_evp(session, method, method_len, + pubkeydata, pubkeydata_len, pk); + break; +#if LIBSSH2_DSA + case EVP_PKEY_DSA : + st = gen_publickey_from_dsa_evp(session, method, method_len, + pubkeydata, pubkeydata_len, pk); + break; +#endif /* LIBSSH_DSA */ + default : + st = _libssh2_error(session, + LIBSSH2_ERROR_FILE, + "Unable to extract public key " + "from private key file: " + "Unsupported private key file format"); + break; + } + + EVP_PKEY_free(pk); + return st; +} + +#endif /* LIBSSH2_OPENSSL */ diff --git a/libssh2/packet.c b/libssh2/packet.c new file mode 100644 index 0000000..5f1feb8 --- /dev/null +++ b/libssh2/packet.c @@ -0,0 +1,1267 @@ +/* Copyright (c) 2004-2007, Sara Golemon + * Copyright (c) 2005,2006 Mikhail Gusarov + * Copyright (c) 2009-2014 by Daniel Stenberg + * Copyright (c) 2010 Simon Josefsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_SYS_TIME_H +#include +#endif + +#ifdef HAVE_INTTYPES_H +#include +#endif + +/* Needed for struct iovec on some platforms */ +#ifdef HAVE_SYS_UIO_H +#include +#endif + +#include + +#include "transport.h" +#include "channel.h" +#include "packet.h" + +/* + * libssh2_packet_queue_listener + * + * Queue a connection request for a listener + */ +static inline int +packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data, + unsigned long datalen, + packet_queue_listener_state_t *listen_state) +{ + /* + * Look for a matching listener + */ + /* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */ + unsigned long packet_len = 17 + (sizeof(FwdNotReq) - 1); + unsigned char *p; + LIBSSH2_LISTENER *listn = _libssh2_list_first(&session->listeners); + char failure_code = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED; + int rc; + + (void) datalen; + + if (listen_state->state == libssh2_NB_state_idle) { + unsigned char *s = data + (sizeof("forwarded-tcpip") - 1) + 5; + listen_state->sender_channel = _libssh2_ntohu32(s); + s += 4; + + listen_state->initial_window_size = _libssh2_ntohu32(s); + s += 4; + listen_state->packet_size = _libssh2_ntohu32(s); + s += 4; + + listen_state->host_len = _libssh2_ntohu32(s); + s += 4; + listen_state->host = s; + s += listen_state->host_len; + listen_state->port = _libssh2_ntohu32(s); + s += 4; + + listen_state->shost_len = _libssh2_ntohu32(s); + s += 4; + listen_state->shost = s; + s += listen_state->shost_len; + listen_state->sport = _libssh2_ntohu32(s); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Remote received connection from %s:%ld to %s:%ld", + listen_state->shost, listen_state->sport, + listen_state->host, listen_state->port); + + listen_state->state = libssh2_NB_state_allocated; + } + + if (listen_state->state != libssh2_NB_state_sent) { + while (listn) { + if ((listn->port == (int) listen_state->port) && + (strlen(listn->host) == listen_state->host_len) && + (memcmp (listn->host, listen_state->host, + listen_state->host_len) == 0)) { + /* This is our listener */ + LIBSSH2_CHANNEL *channel = NULL; + listen_state->channel = NULL; + + if (listen_state->state == libssh2_NB_state_allocated) { + if (listn->queue_maxsize && + (listn->queue_maxsize <= listn->queue_size)) { + /* Queue is full */ + failure_code = SSH_OPEN_RESOURCE_SHORTAGE; + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Listener queue full, ignoring"); + listen_state->state = libssh2_NB_state_sent; + break; + } + + channel = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL)); + if (!channel) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate a channel for " + "new connection"); + failure_code = SSH_OPEN_RESOURCE_SHORTAGE; + listen_state->state = libssh2_NB_state_sent; + break; + } + listen_state->channel = channel; + + channel->session = session; + channel->channel_type_len = sizeof("forwarded-tcpip") - 1; + channel->channel_type = LIBSSH2_ALLOC(session, + channel-> + channel_type_len + + 1); + if (!channel->channel_type) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate a channel for new" + " connection"); + LIBSSH2_FREE(session, channel); + failure_code = SSH_OPEN_RESOURCE_SHORTAGE; + listen_state->state = libssh2_NB_state_sent; + break; + } + memcpy(channel->channel_type, "forwarded-tcpip", + channel->channel_type_len + 1); + + channel->remote.id = listen_state->sender_channel; + channel->remote.window_size_initial = + LIBSSH2_CHANNEL_WINDOW_DEFAULT; + channel->remote.window_size = + LIBSSH2_CHANNEL_WINDOW_DEFAULT; + channel->remote.packet_size = + LIBSSH2_CHANNEL_PACKET_DEFAULT; + + channel->local.id = _libssh2_channel_nextid(session); + channel->local.window_size_initial = + listen_state->initial_window_size; + channel->local.window_size = + listen_state->initial_window_size; + channel->local.packet_size = listen_state->packet_size; + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Connection queued: channel %lu/%lu " + "win %lu/%lu packet %lu/%lu", + channel->local.id, channel->remote.id, + channel->local.window_size, + channel->remote.window_size, + channel->local.packet_size, + channel->remote.packet_size); + + p = listen_state->packet; + *(p++) = SSH_MSG_CHANNEL_OPEN_CONFIRMATION; + _libssh2_store_u32(&p, channel->remote.id); + _libssh2_store_u32(&p, channel->local.id); + _libssh2_store_u32(&p, + channel->remote.window_size_initial); + _libssh2_store_u32(&p, channel->remote.packet_size); + + listen_state->state = libssh2_NB_state_created; + } + + if (listen_state->state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, listen_state->packet, + 17, NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + else if (rc) { + listen_state->state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Unable to send channel " + "open confirmation"); + } + + /* Link the channel into the end of the queue list */ + if (listen_state->channel) { + _libssh2_list_add(&listn->queue, + &listen_state->channel->node); + listn->queue_size++; + } + + listen_state->state = libssh2_NB_state_idle; + return 0; + } + } + + listn = _libssh2_list_next(&listn->node); + } + + listen_state->state = libssh2_NB_state_sent; + } + + /* We're not listening to you */ + p = listen_state->packet; + *(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE; + _libssh2_store_u32(&p, listen_state->sender_channel); + _libssh2_store_u32(&p, failure_code); + _libssh2_store_str(&p, FwdNotReq, sizeof(FwdNotReq) - 1); + _libssh2_htonu32(p, 0); + + rc = _libssh2_transport_send(session, listen_state->packet, + packet_len, NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + listen_state->state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, "Unable to send open failure"); + + } + listen_state->state = libssh2_NB_state_idle; + return 0; +} + +/* + * packet_x11_open + * + * Accept a forwarded X11 connection + */ +static inline int +packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data, + unsigned long datalen, + packet_x11_open_state_t *x11open_state) +{ + int failure_code = SSH_OPEN_CONNECT_FAILED; + /* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */ + unsigned long packet_len = 17 + (sizeof(X11FwdUnAvil) - 1); + unsigned char *p; + LIBSSH2_CHANNEL *channel = x11open_state->channel; + int rc; + + (void) datalen; + + if (x11open_state->state == libssh2_NB_state_idle) { + unsigned char *s = data + (sizeof("x11") - 1) + 5; + x11open_state->sender_channel = _libssh2_ntohu32(s); + s += 4; + x11open_state->initial_window_size = _libssh2_ntohu32(s); + s += 4; + x11open_state->packet_size = _libssh2_ntohu32(s); + s += 4; + x11open_state->shost_len = _libssh2_ntohu32(s); + s += 4; + x11open_state->shost = s; + s += x11open_state->shost_len; + x11open_state->sport = _libssh2_ntohu32(s); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "X11 Connection Received from %s:%ld on channel %lu", + x11open_state->shost, x11open_state->sport, + x11open_state->sender_channel); + + x11open_state->state = libssh2_NB_state_allocated; + } + + if (session->x11) { + if (x11open_state->state == libssh2_NB_state_allocated) { + channel = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL)); + if (!channel) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "allocate a channel for new connection"); + failure_code = SSH_OPEN_RESOURCE_SHORTAGE; + goto x11_exit; + } + + channel->session = session; + channel->channel_type_len = sizeof("x11") - 1; + channel->channel_type = LIBSSH2_ALLOC(session, + channel->channel_type_len + + 1); + if (!channel->channel_type) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "allocate a channel for new connection"); + LIBSSH2_FREE(session, channel); + failure_code = SSH_OPEN_RESOURCE_SHORTAGE; + goto x11_exit; + } + memcpy(channel->channel_type, "x11", + channel->channel_type_len + 1); + + channel->remote.id = x11open_state->sender_channel; + channel->remote.window_size_initial = + LIBSSH2_CHANNEL_WINDOW_DEFAULT; + channel->remote.window_size = LIBSSH2_CHANNEL_WINDOW_DEFAULT; + channel->remote.packet_size = LIBSSH2_CHANNEL_PACKET_DEFAULT; + + channel->local.id = _libssh2_channel_nextid(session); + channel->local.window_size_initial = + x11open_state->initial_window_size; + channel->local.window_size = x11open_state->initial_window_size; + channel->local.packet_size = x11open_state->packet_size; + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "X11 Connection established: channel %lu/%lu " + "win %lu/%lu packet %lu/%lu", + channel->local.id, channel->remote.id, + channel->local.window_size, + channel->remote.window_size, + channel->local.packet_size, + channel->remote.packet_size); + p = x11open_state->packet; + *(p++) = SSH_MSG_CHANNEL_OPEN_CONFIRMATION; + _libssh2_store_u32(&p, channel->remote.id); + _libssh2_store_u32(&p, channel->local.id); + _libssh2_store_u32(&p, channel->remote.window_size_initial); + _libssh2_store_u32(&p, channel->remote.packet_size); + + x11open_state->state = libssh2_NB_state_created; + } + + if (x11open_state->state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, x11open_state->packet, 17, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + x11open_state->state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send channel open " + "confirmation"); + } + + /* Link the channel into the session */ + _libssh2_list_add(&session->channels, &channel->node); + + /* + * Pass control to the callback, they may turn right around and + * free the channel, or actually use it + */ + LIBSSH2_X11_OPEN(channel, (char *)x11open_state->shost, + x11open_state->sport); + + x11open_state->state = libssh2_NB_state_idle; + return 0; + } + } + else + failure_code = SSH_OPEN_RESOURCE_SHORTAGE; + /* fall-trough */ + x11_exit: + p = x11open_state->packet; + *(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE; + _libssh2_store_u32(&p, x11open_state->sender_channel); + _libssh2_store_u32(&p, failure_code); + _libssh2_store_str(&p, X11FwdUnAvil, sizeof(X11FwdUnAvil) - 1); + _libssh2_htonu32(p, 0); + + rc = _libssh2_transport_send(session, x11open_state->packet, packet_len, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + x11open_state->state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, "Unable to send open failure"); + } + x11open_state->state = libssh2_NB_state_idle; + return 0; +} + +/* + * _libssh2_packet_add + * + * Create a new packet and attach it to the brigade. Called from the transport + * layer when it has received a packet. + * + * The input pointer 'data' is pointing to allocated data that this function + * is asked to deal with so on failure OR success, it must be freed fine. + * The only exception is when the return code is LIBSSH2_ERROR_EAGAIN. + * + * This function will always be called with 'datalen' greater than zero. + */ +int +_libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data, + size_t datalen, int macstate) +{ + int rc = 0; + char *message=NULL; + char *language=NULL; + size_t message_len=0; + size_t language_len=0; + LIBSSH2_CHANNEL *channelp = NULL; + size_t data_head = 0; + unsigned char msg = data[0]; + + switch(session->packAdd_state) { + case libssh2_NB_state_idle: + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "Packet type %d received, length=%d", + (int) msg, (int) datalen); + + if ((macstate == LIBSSH2_MAC_INVALID) && + (!session->macerror || + LIBSSH2_MACERROR(session, (char *) data, datalen))) { + /* Bad MAC input, but no callback set or non-zero return from the + callback */ + + LIBSSH2_FREE(session, data); + return _libssh2_error(session, LIBSSH2_ERROR_INVALID_MAC, + "Invalid MAC received"); + } + session->packAdd_state = libssh2_NB_state_allocated; + break; + case libssh2_NB_state_jump1: + goto libssh2_packet_add_jump_point1; + case libssh2_NB_state_jump2: + goto libssh2_packet_add_jump_point2; + case libssh2_NB_state_jump3: + goto libssh2_packet_add_jump_point3; + case libssh2_NB_state_jump4: + goto libssh2_packet_add_jump_point4; + case libssh2_NB_state_jump5: + goto libssh2_packet_add_jump_point5; + default: /* nothing to do */ + break; + } + + if (session->packAdd_state == libssh2_NB_state_allocated) { + /* A couple exceptions to the packet adding rule: */ + switch (msg) { + + /* + byte SSH_MSG_DISCONNECT + uint32 reason code + string description in ISO-10646 UTF-8 encoding [RFC3629] + string language tag [RFC3066] + */ + + case SSH_MSG_DISCONNECT: + if(datalen >= 5) { + size_t reason = _libssh2_ntohu32(data + 1); + + if(datalen >= 9) { + message_len = _libssh2_ntohu32(data + 5); + + if(message_len < datalen-13) { + /* 9 = packet_type(1) + reason(4) + message_len(4) */ + message = (char *) data + 9; + + language_len = _libssh2_ntohu32(data + 9 + message_len); + language = (char *) data + 9 + message_len + 4; + + if(language_len > (datalen-13-message_len)) { + /* bad input, clear info */ + language = message = NULL; + language_len = message_len = 0; + } + } + else + /* bad size, clear it */ + message_len=0; + } + if (session->ssh_msg_disconnect) { + LIBSSH2_DISCONNECT(session, reason, message, + message_len, language, language_len); + } + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "Disconnect(%d): %s(%s)", reason, + message, language); + } + + LIBSSH2_FREE(session, data); + session->socket_state = LIBSSH2_SOCKET_DISCONNECTED; + session->packAdd_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_DISCONNECT, + "socket disconnect"); + /* + byte SSH_MSG_IGNORE + string data + */ + + case SSH_MSG_IGNORE: + if (datalen >= 2) { + if (session->ssh_msg_ignore) { + LIBSSH2_IGNORE(session, (char *) data + 1, datalen - 1); + } + } else if (session->ssh_msg_ignore) { + LIBSSH2_IGNORE(session, "", 0); + } + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + + /* + byte SSH_MSG_DEBUG + boolean always_display + string message in ISO-10646 UTF-8 encoding [RFC3629] + string language tag [RFC3066] + */ + + case SSH_MSG_DEBUG: + if(datalen >= 2) { + int always_display= data[1]; + + if(datalen >= 6) { + message_len = _libssh2_ntohu32(data + 2); + + if(message_len <= (datalen - 10)) { + /* 6 = packet_type(1) + display(1) + message_len(4) */ + message = (char *) data + 6; + language_len = _libssh2_ntohu32(data + 6 + message_len); + + if(language_len <= (datalen - 10 - message_len)) + language = (char *) data + 10 + message_len; + } + } + + if (session->ssh_msg_debug) { + LIBSSH2_DEBUG(session, always_display, message, + message_len, language, language_len); + } + } + /* + * _libssh2_debug will actually truncate this for us so + * that it's not an inordinate about of data + */ + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "Debug Packet: %s", message); + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + + /* + byte SSH_MSG_GLOBAL_REQUEST + string request name in US-ASCII only + boolean want reply + .... request-specific data follows + */ + + case SSH_MSG_GLOBAL_REQUEST: + if(datalen >= 5) { + uint32_t len =0; + unsigned char want_reply=0; + len = _libssh2_ntohu32(data + 1); + if(datalen >= (6 + len)) { + want_reply = data[5 + len]; + _libssh2_debug(session, + LIBSSH2_TRACE_CONN, + "Received global request type %.*s (wr %X)", + len, data + 5, want_reply); + } + + + if (want_reply) { + static const unsigned char packet = + SSH_MSG_REQUEST_FAILURE; + libssh2_packet_add_jump_point5: + session->packAdd_state = libssh2_NB_state_jump5; + rc = _libssh2_transport_send(session, &packet, 1, NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + } + } + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + + /* + byte SSH_MSG_CHANNEL_EXTENDED_DATA + uint32 recipient channel + uint32 data_type_code + string data + */ + + case SSH_MSG_CHANNEL_EXTENDED_DATA: + /* streamid(4) */ + data_head += 4; + + /* fall-through */ + + /* + byte SSH_MSG_CHANNEL_DATA + uint32 recipient channel + string data + */ + + case SSH_MSG_CHANNEL_DATA: + /* packet_type(1) + channelno(4) + datalen(4) */ + data_head += 9; + + if(datalen >= data_head) + channelp = + _libssh2_channel_locate(session, + _libssh2_ntohu32(data + 1)); + + if (!channelp) { + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_UNKNOWN, + "Packet received for unknown channel"); + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + } +#ifdef LIBSSH2DEBUG + { + uint32_t stream_id = 0; + if (msg == SSH_MSG_CHANNEL_EXTENDED_DATA) + stream_id = _libssh2_ntohu32(data + 5); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "%d bytes packet_add() for %lu/%lu/%lu", + (int) (datalen - data_head), + channelp->local.id, + channelp->remote.id, + stream_id); + } +#endif + if ((channelp->remote.extended_data_ignore_mode == + LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) && + (msg == SSH_MSG_CHANNEL_EXTENDED_DATA)) { + /* Pretend we didn't receive this */ + LIBSSH2_FREE(session, data); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Ignoring extended data and refunding %d bytes", + (int) (datalen - 13)); + if (channelp->read_avail + datalen - data_head >= + channelp->remote.window_size) + datalen = channelp->remote.window_size - + channelp->read_avail + data_head; + + channelp->remote.window_size -= datalen - data_head; + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "shrinking window size by %lu bytes to %lu, read_avail %lu", + datalen - data_head, + channelp->remote.window_size, + channelp->read_avail); + + session->packAdd_channelp = channelp; + + /* Adjust the window based on the block we just freed */ + libssh2_packet_add_jump_point1: + session->packAdd_state = libssh2_NB_state_jump1; + rc = _libssh2_channel_receive_window_adjust(session-> + packAdd_channelp, + datalen - 13, + 1, NULL); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + + session->packAdd_state = libssh2_NB_state_idle; + return 0; + } + + /* + * REMEMBER! remote means remote as source of data, + * NOT remote window! + */ + if (channelp->remote.packet_size < (datalen - data_head)) { + /* + * Spec says we MAY ignore bytes sent beyond + * packet_size + */ + _libssh2_error(session, + LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED, + "Packet contains more data than we offered" + " to receive, truncating"); + datalen = channelp->remote.packet_size + data_head; + } + if (channelp->remote.window_size <= channelp->read_avail) { + /* + * Spec says we MAY ignore bytes sent beyond + * window_size + */ + _libssh2_error(session, + LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED, + "The current receive window is full," + " data ignored"); + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + } + /* Reset EOF status */ + channelp->remote.eof = 0; + + if (channelp->read_avail + datalen - data_head > + channelp->remote.window_size) { + _libssh2_error(session, + LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED, + "Remote sent more data than current " + "window allows, truncating"); + datalen = channelp->remote.window_size - + channelp->read_avail + data_head; + } + + /* Update the read_avail counter. The window size will be + * updated once the data is actually read from the queue + * from an upper layer */ + channelp->read_avail += datalen - data_head; + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "increasing read_avail by %lu bytes to %lu/%lu", + (long)(datalen - data_head), + (long)channelp->read_avail, + (long)channelp->remote.window_size); + + break; + + /* + byte SSH_MSG_CHANNEL_EOF + uint32 recipient channel + */ + + case SSH_MSG_CHANNEL_EOF: + if(datalen >= 5) + channelp = + _libssh2_channel_locate(session, + _libssh2_ntohu32(data + 1)); + if (!channelp) + /* We may have freed already, just quietly ignore this... */ + ; + else { + _libssh2_debug(session, + LIBSSH2_TRACE_CONN, + "EOF received for channel %lu/%lu", + channelp->local.id, + channelp->remote.id); + channelp->remote.eof = 1; + } + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + + /* + byte SSH_MSG_CHANNEL_REQUEST + uint32 recipient channel + string request type in US-ASCII characters only + boolean want reply + .... type-specific data follows + */ + + case SSH_MSG_CHANNEL_REQUEST: + if(datalen >= 9) { + uint32_t channel = _libssh2_ntohu32(data + 1); + uint32_t len = _libssh2_ntohu32(data + 5); + unsigned char want_reply = 1; + + if(len < (datalen - 10)) + want_reply = data[9 + len]; + + _libssh2_debug(session, + LIBSSH2_TRACE_CONN, + "Channel %d received request type %.*s (wr %X)", + channel, len, data + 9, want_reply); + + if (len == sizeof("exit-status") - 1 + && !memcmp("exit-status", data + 9, + sizeof("exit-status") - 1)) { + + /* we've got "exit-status" packet. Set the session value */ + if(datalen >= 20) + channelp = + _libssh2_channel_locate(session, channel); + + if (channelp) { + channelp->exit_status = + _libssh2_ntohu32(data + 9 + sizeof("exit-status")); + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Exit status %lu received for " + "channel %lu/%lu", + channelp->exit_status, + channelp->local.id, + channelp->remote.id); + } + + } + else if (len == sizeof("exit-signal") - 1 + && !memcmp("exit-signal", data + 9, + sizeof("exit-signal") - 1)) { + /* command terminated due to signal */ + if(datalen >= 20) + channelp = _libssh2_channel_locate(session, channel); + + if (channelp) { + /* set signal name (without SIG prefix) */ + uint32_t namelen = + _libssh2_ntohu32(data + 9 + sizeof("exit-signal")); + channelp->exit_signal = + LIBSSH2_ALLOC(session, namelen + 1); + if (!channelp->exit_signal) + rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "memory for signal name"); + else { + memcpy(channelp->exit_signal, + data + 13 + sizeof("exit_signal"), namelen); + channelp->exit_signal[namelen] = '\0'; + /* TODO: save error message and language tag */ + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Exit signal %s received for " + "channel %lu/%lu", + channelp->exit_signal, + channelp->local.id, + channelp->remote.id); + } + } + } + + + if (want_reply) { + unsigned char packet[5]; + libssh2_packet_add_jump_point4: + session->packAdd_state = libssh2_NB_state_jump4; + packet[0] = SSH_MSG_CHANNEL_FAILURE; + memcpy(&packet[1], data+1, 4); + rc = _libssh2_transport_send(session, packet, 5, NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + } + } + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return rc; + + /* + byte SSH_MSG_CHANNEL_CLOSE + uint32 recipient channel + */ + + case SSH_MSG_CHANNEL_CLOSE: + if(datalen >= 5) + channelp = + _libssh2_channel_locate(session, + _libssh2_ntohu32(data + 1)); + if (!channelp) { + /* We may have freed already, just quietly ignore this... */ + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + } + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Close received for channel %lu/%lu", + channelp->local.id, + channelp->remote.id); + + channelp->remote.close = 1; + channelp->remote.eof = 1; + + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + + /* + byte SSH_MSG_CHANNEL_OPEN + string "session" + uint32 sender channel + uint32 initial window size + uint32 maximum packet size + */ + + case SSH_MSG_CHANNEL_OPEN: + if(datalen < 17) + ; + else if ((datalen >= (sizeof("forwarded-tcpip") + 4)) && + ((sizeof("forwarded-tcpip") - 1) == + _libssh2_ntohu32(data + 1)) + && + (memcmp(data + 5, "forwarded-tcpip", + sizeof("forwarded-tcpip") - 1) == 0)) { + + /* init the state struct */ + memset(&session->packAdd_Qlstn_state, 0, + sizeof(session->packAdd_Qlstn_state)); + + libssh2_packet_add_jump_point2: + session->packAdd_state = libssh2_NB_state_jump2; + rc = packet_queue_listener(session, data, datalen, + &session->packAdd_Qlstn_state); + } + else if ((datalen >= (sizeof("x11") + 4)) && + ((sizeof("x11") - 1) == _libssh2_ntohu32(data + 1)) && + (memcmp(data + 5, "x11", sizeof("x11") - 1) == 0)) { + + /* init the state struct */ + memset(&session->packAdd_x11open_state, 0, + sizeof(session->packAdd_x11open_state)); + + libssh2_packet_add_jump_point3: + session->packAdd_state = libssh2_NB_state_jump3; + rc = packet_x11_open(session, data, datalen, + &session->packAdd_x11open_state); + } + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return rc; + + /* + byte SSH_MSG_CHANNEL_WINDOW_ADJUST + uint32 recipient channel + uint32 bytes to add + */ + case SSH_MSG_CHANNEL_WINDOW_ADJUST: + if(datalen < 9) + ; + else { + uint32_t bytestoadd = _libssh2_ntohu32(data + 5); + channelp = + _libssh2_channel_locate(session, + _libssh2_ntohu32(data + 1)); + if(channelp) { + channelp->local.window_size += bytestoadd; + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Window adjust for channel %lu/%lu, " + "adding %lu bytes, new window_size=%lu", + channelp->local.id, + channelp->remote.id, + bytestoadd, + channelp->local.window_size); + } + } + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + default: + break; + } + + session->packAdd_state = libssh2_NB_state_sent; + } + + if (session->packAdd_state == libssh2_NB_state_sent) { + LIBSSH2_PACKET *packetp = + LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET)); + if (!packetp) { + _libssh2_debug(session, LIBSSH2_ERROR_ALLOC, + "memory for packet"); + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return LIBSSH2_ERROR_ALLOC; + } + packetp->data = data; + packetp->data_len = datalen; + packetp->data_head = data_head; + + _libssh2_list_add(&session->packets, &packetp->node); + + session->packAdd_state = libssh2_NB_state_sent1; + } + + if ((msg == SSH_MSG_KEXINIT && + !(session->state & LIBSSH2_STATE_EXCHANGING_KEYS)) || + (session->packAdd_state == libssh2_NB_state_sent2)) { + if (session->packAdd_state == libssh2_NB_state_sent1) { + /* + * Remote wants new keys + * Well, it's already in the brigade, + * let's just call back into ourselves + */ + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Renegotiating Keys"); + + session->packAdd_state = libssh2_NB_state_sent2; + } + + /* + * The KEXINIT message has been added to the queue. The packAdd and + * readPack states need to be reset because _libssh2_kex_exchange + * (eventually) calls upon _libssh2_transport_read to read the rest of + * the key exchange conversation. + */ + session->readPack_state = libssh2_NB_state_idle; + session->packet.total_num = 0; + session->packAdd_state = libssh2_NB_state_idle; + session->fullpacket_state = libssh2_NB_state_idle; + + memset(&session->startup_key_state, 0, sizeof(key_exchange_state_t)); + + /* + * If there was a key reexchange failure, let's just hope we didn't + * send NEWKEYS yet, otherwise remote will drop us like a rock + */ + rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + } + + session->packAdd_state = libssh2_NB_state_idle; + return 0; +} + +/* + * _libssh2_packet_ask + * + * Scan the brigade for a matching packet type, optionally poll the socket for + * a packet first + */ +int +_libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type, + unsigned char **data, size_t *data_len, + int match_ofs, const unsigned char *match_buf, + size_t match_len) +{ + LIBSSH2_PACKET *packet = _libssh2_list_first(&session->packets); + + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "Looking for packet of type: %d", (int) packet_type); + + while (packet) { + if (packet->data[0] == packet_type + && (packet->data_len >= (match_ofs + match_len)) + && (!match_buf || + (memcmp(packet->data + match_ofs, match_buf, + match_len) == 0))) { + *data = packet->data; + *data_len = packet->data_len; + + /* unlink struct from session->packets */ + _libssh2_list_remove(&packet->node); + + LIBSSH2_FREE(session, packet); + + return 0; + } + packet = _libssh2_list_next(&packet->node); + } + return -1; +} + +/* + * libssh2_packet_askv + * + * Scan for any of a list of packet types in the brigade, optionally poll the + * socket for a packet first + */ +int +_libssh2_packet_askv(LIBSSH2_SESSION * session, + const unsigned char *packet_types, + unsigned char **data, size_t *data_len, + int match_ofs, + const unsigned char *match_buf, + size_t match_len) +{ + int i, packet_types_len = strlen((char *) packet_types); + + for(i = 0; i < packet_types_len; i++) { + if (0 == _libssh2_packet_ask(session, packet_types[i], data, + data_len, match_ofs, + match_buf, match_len)) { + return 0; + } + } + + return -1; +} + +/* + * _libssh2_packet_require + * + * Loops _libssh2_transport_read() until the packet requested is available + * SSH_DISCONNECT or a SOCKET_DISCONNECTED will cause a bailout + * + * Returns negative on error + * Returns 0 when it has taken care of the requested packet. + */ +int +_libssh2_packet_require(LIBSSH2_SESSION * session, unsigned char packet_type, + unsigned char **data, size_t *data_len, + int match_ofs, + const unsigned char *match_buf, + size_t match_len, + packet_require_state_t *state) +{ + if (state->start == 0) { + if (_libssh2_packet_ask(session, packet_type, data, data_len, + match_ofs, match_buf, + match_len) == 0) { + /* A packet was available in the packet brigade */ + return 0; + } + + state->start = time(NULL); + } + + while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) { + int ret = _libssh2_transport_read(session); + if (ret == LIBSSH2_ERROR_EAGAIN) + return ret; + else if (ret < 0) { + state->start = 0; + /* an error which is not just because of blocking */ + return ret; + } else if (ret == packet_type) { + /* Be lazy, let packet_ask pull it out of the brigade */ + ret = _libssh2_packet_ask(session, packet_type, data, data_len, + match_ofs, match_buf, match_len); + state->start = 0; + return ret; + } else if (ret == 0) { + /* nothing available, wait until data arrives or we time out */ + long left = LIBSSH2_READ_TIMEOUT - (long)(time(NULL) - + state->start); + + if (left <= 0) { + state->start = 0; + return LIBSSH2_ERROR_TIMEOUT; + } + return -1; /* no packet available yet */ + } + } + + /* Only reached if the socket died */ + return LIBSSH2_ERROR_SOCKET_DISCONNECT; +} + +/* + * _libssh2_packet_burn + * + * Loops _libssh2_transport_read() until any packet is available and promptly + * discards it. + * Used during KEX exchange to discard badly guessed KEX_INIT packets + */ +int +_libssh2_packet_burn(LIBSSH2_SESSION * session, + libssh2_nonblocking_states * state) +{ + unsigned char *data; + size_t data_len; + unsigned char i, all_packets[255]; + int ret; + + if (*state == libssh2_NB_state_idle) { + for(i = 1; i < 255; i++) { + all_packets[i - 1] = i; + } + all_packets[254] = 0; + + if (_libssh2_packet_askv(session, all_packets, &data, &data_len, 0, + NULL, 0) == 0) { + i = data[0]; + /* A packet was available in the packet brigade, burn it */ + LIBSSH2_FREE(session, data); + return i; + } + + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "Blocking until packet becomes available to burn"); + *state = libssh2_NB_state_created; + } + + while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) { + ret = _libssh2_transport_read(session); + if (ret == LIBSSH2_ERROR_EAGAIN) { + return ret; + } else if (ret < 0) { + *state = libssh2_NB_state_idle; + return ret; + } else if (ret == 0) { + /* FIXME: this might busyloop */ + continue; + } + + /* Be lazy, let packet_ask pull it out of the brigade */ + if (0 == + _libssh2_packet_ask(session, (unsigned char)ret, + &data, &data_len, 0, NULL, 0)) { + /* Smoke 'em if you got 'em */ + LIBSSH2_FREE(session, data); + *state = libssh2_NB_state_idle; + return ret; + } + } + + /* Only reached if the socket died */ + return LIBSSH2_ERROR_SOCKET_DISCONNECT; +} + +/* + * _libssh2_packet_requirev + * + * Loops _libssh2_transport_read() until one of a list of packet types + * requested is available. SSH_DISCONNECT or a SOCKET_DISCONNECTED will cause + * a bailout. packet_types is a null terminated list of packet_type numbers + */ + +int +_libssh2_packet_requirev(LIBSSH2_SESSION *session, + const unsigned char *packet_types, + unsigned char **data, size_t *data_len, + int match_ofs, + const unsigned char *match_buf, size_t match_len, + packet_requirev_state_t * state) +{ + if (_libssh2_packet_askv(session, packet_types, data, data_len, match_ofs, + match_buf, match_len) == 0) { + /* One of the packets listed was available in the packet brigade */ + state->start = 0; + return 0; + } + + if (state->start == 0) { + state->start = time(NULL); + } + + while (session->socket_state != LIBSSH2_SOCKET_DISCONNECTED) { + int ret = _libssh2_transport_read(session); + if ((ret < 0) && (ret != LIBSSH2_ERROR_EAGAIN)) { + state->start = 0; + return ret; + } + if (ret <= 0) { + long left = LIBSSH2_READ_TIMEOUT - + (long)(time(NULL) - state->start); + + if (left <= 0) { + state->start = 0; + return LIBSSH2_ERROR_TIMEOUT; + } + else if (ret == LIBSSH2_ERROR_EAGAIN) { + return ret; + } + } + + if (strchr((char *) packet_types, ret)) { + /* Be lazy, let packet_ask pull it out of the brigade */ + return _libssh2_packet_askv(session, packet_types, data, + data_len, match_ofs, match_buf, + match_len); + } + } + + /* Only reached if the socket died */ + state->start = 0; + return LIBSSH2_ERROR_SOCKET_DISCONNECT; +} + diff --git a/libssh2/pem.c b/libssh2/pem.c new file mode 100644 index 0000000..9f51bba --- /dev/null +++ b/libssh2/pem.c @@ -0,0 +1,324 @@ +/* Copyright (C) 2007 The Written Word, Inc. + * Copyright (C) 2008, Simon Josefsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" + +static int +readline(char *line, int line_size, FILE * fp) +{ + size_t len; + + if (!line) { + return -1; + } + if (!fgets(line, line_size, fp)) { + return -1; + } + + if (*line) { + len = strlen(line); + if (len > 0 && line[len - 1] == '\n') { + line[len - 1] = '\0'; + } + } + + if (*line) { + len = strlen(line); + if (len > 0 && line[len - 1] == '\r') { + line[len - 1] = '\0'; + } + } + + return 0; +} + +static int +readline_memory(char *line, size_t line_size, + const char *filedata, size_t filedata_len, + size_t *filedata_offset) +{ + size_t off, len; + + off = *filedata_offset; + + for (len = 0; off + len < filedata_len && len < line_size; len++) { + if (filedata[off + len] == '\n' || + filedata[off + len] == '\r') { + break; + } + } + + if (len) { + memcpy(line, filedata + off, len); + *filedata_offset += len; + } + + line[len] = '\0'; + *filedata_offset += 1; + + return 0; +} + +#define LINE_SIZE 128 + +int +_libssh2_pem_parse(LIBSSH2_SESSION * session, + const char *headerbegin, + const char *headerend, + FILE * fp, unsigned char **data, unsigned int *datalen) +{ + char line[LINE_SIZE]; + char *b64data = NULL; + unsigned int b64datalen = 0; + int ret; + + do { + *line = '\0'; + + if (readline(line, LINE_SIZE, fp)) { + return -1; + } + } + while (strcmp(line, headerbegin) != 0); + + *line = '\0'; + + do { + if (*line) { + char *tmp; + size_t linelen; + + linelen = strlen(line); + tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen); + if (!tmp) { + ret = -1; + goto out; + } + memcpy(tmp + b64datalen, line, linelen); + b64data = tmp; + b64datalen += linelen; + } + + *line = '\0'; + + if (readline(line, LINE_SIZE, fp)) { + ret = -1; + goto out; + } + } while (strcmp(line, headerend) != 0); + + if (!b64data) { + return -1; + } + + if (libssh2_base64_decode(session, (char**) data, datalen, + b64data, b64datalen)) { + ret = -1; + goto out; + } + + ret = 0; + out: + if (b64data) { + LIBSSH2_FREE(session, b64data); + } + return ret; +} + +int +_libssh2_pem_parse_memory(LIBSSH2_SESSION * session, + const char *headerbegin, + const char *headerend, + const char *filedata, size_t filedata_len, + unsigned char **data, unsigned int *datalen) +{ + char line[LINE_SIZE]; + char *b64data = NULL; + unsigned int b64datalen = 0; + size_t off = 0; + int ret; + + do { + *line = '\0'; + + if (readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) { + return -1; + } + } + while (strcmp(line, headerbegin) != 0); + + *line = '\0'; + + do { + if (*line) { + char *tmp; + size_t linelen; + + linelen = strlen(line); + tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen); + if (!tmp) { + ret = -1; + goto out; + } + memcpy(tmp + b64datalen, line, linelen); + b64data = tmp; + b64datalen += linelen; + } + + *line = '\0'; + + if (readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) { + ret = -1; + goto out; + } + } while (strcmp(line, headerend) != 0); + + if (!b64data) { + return -1; + } + + if (libssh2_base64_decode(session, (char**) data, datalen, + b64data, b64datalen)) { + ret = -1; + goto out; + } + + ret = 0; + out: + if (b64data) { + LIBSSH2_FREE(session, b64data); + } + return ret; +} + +static int +read_asn1_length(const unsigned char *data, + unsigned int datalen, unsigned int *len) +{ + unsigned int lenlen; + int nextpos; + + if (datalen < 1) { + return -1; + } + *len = data[0]; + + if (*len >= 0x80) { + lenlen = *len & 0x7F; + *len = data[1]; + if (1 + lenlen > datalen) { + return -1; + } + if (lenlen > 1) { + *len <<= 8; + *len |= data[2]; + } + } else { + lenlen = 0; + } + + nextpos = 1 + lenlen; + if (lenlen > 2 || 1 + lenlen + *len > datalen) { + return -1; + } + + return nextpos; +} + +int +_libssh2_pem_decode_sequence(unsigned char **data, unsigned int *datalen) +{ + unsigned int len; + int lenlen; + + if (*datalen < 1) { + return -1; + } + + if ((*data)[0] != '\x30') { + return -1; + } + + (*data)++; + (*datalen)--; + + lenlen = read_asn1_length(*data, *datalen, &len); + if (lenlen < 0 || lenlen + len != *datalen) { + return -1; + } + + *data += lenlen; + *datalen -= lenlen; + + return 0; +} + +int +_libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen, + unsigned char **i, unsigned int *ilen) +{ + unsigned int len; + int lenlen; + + if (*datalen < 1) { + return -1; + } + + if ((*data)[0] != '\x02') { + return -1; + } + + (*data)++; + (*datalen)--; + + lenlen = read_asn1_length(*data, *datalen, &len); + if (lenlen < 0 || lenlen + len > *datalen) { + return -1; + } + + *data += lenlen; + *datalen -= lenlen; + + *i = *data; + *ilen = len; + + *data += len; + *datalen -= len; + + return 0; +} diff --git a/libssh2/publickey.c b/libssh2/publickey.c new file mode 100644 index 0000000..bfee0a8 --- /dev/null +++ b/libssh2/publickey.c @@ -0,0 +1,1059 @@ +/* Copyright (c) 2004-2007, Sara Golemon + * Copyright (c) 2010-2014 by Daniel Stenberg + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#include "libssh2_publickey.h" +#include "channel.h" +#include "session.h" + +#define LIBSSH2_PUBLICKEY_VERSION 2 + +/* Numericised response codes -- Not IETF, just local representation */ +#define LIBSSH2_PUBLICKEY_RESPONSE_STATUS 0 +#define LIBSSH2_PUBLICKEY_RESPONSE_VERSION 1 +#define LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY 2 + +typedef struct _LIBSSH2_PUBLICKEY_CODE_LIST +{ + int code; + const char *name; + int name_len; +} LIBSSH2_PUBLICKEY_CODE_LIST; + +static const LIBSSH2_PUBLICKEY_CODE_LIST publickey_response_codes[] = +{ + {LIBSSH2_PUBLICKEY_RESPONSE_STATUS, "status", sizeof("status") - 1}, + {LIBSSH2_PUBLICKEY_RESPONSE_VERSION, "version", sizeof("version") - 1}, + {LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY, "publickey", + sizeof("publickey") - 1} , + {0, NULL, 0} +}; + +/* PUBLICKEY status codes -- IETF defined */ +#define LIBSSH2_PUBLICKEY_SUCCESS 0 +#define LIBSSH2_PUBLICKEY_ACCESS_DENIED 1 +#define LIBSSH2_PUBLICKEY_STORAGE_EXCEEDED 2 +#define LIBSSH2_PUBLICKEY_VERSION_NOT_SUPPORTED 3 +#define LIBSSH2_PUBLICKEY_KEY_NOT_FOUND 4 +#define LIBSSH2_PUBLICKEY_KEY_NOT_SUPPORTED 5 +#define LIBSSH2_PUBLICKEY_KEY_ALREADY_PRESENT 6 +#define LIBSSH2_PUBLICKEY_GENERAL_FAILURE 7 +#define LIBSSH2_PUBLICKEY_REQUEST_NOT_SUPPORTED 8 + +#define LIBSSH2_PUBLICKEY_STATUS_CODE_MAX 8 + +static const LIBSSH2_PUBLICKEY_CODE_LIST publickey_status_codes[] = { + {LIBSSH2_PUBLICKEY_SUCCESS, "success", sizeof("success") - 1} , + {LIBSSH2_PUBLICKEY_ACCESS_DENIED, "access denied", + sizeof("access denied") - 1}, + {LIBSSH2_PUBLICKEY_STORAGE_EXCEEDED, "storage exceeded", + sizeof("storage exceeded") - 1} , + {LIBSSH2_PUBLICKEY_VERSION_NOT_SUPPORTED, "version not supported", + sizeof("version not supported") - 1} , + {LIBSSH2_PUBLICKEY_KEY_NOT_FOUND, "key not found", + sizeof("key not found") - 1}, + {LIBSSH2_PUBLICKEY_KEY_NOT_SUPPORTED, "key not supported", + sizeof("key not supported") - 1}, + {LIBSSH2_PUBLICKEY_KEY_ALREADY_PRESENT, "key already present", + sizeof("key already present") - 1}, + {LIBSSH2_PUBLICKEY_GENERAL_FAILURE, "general failure", + sizeof("general failure") - 1}, + {LIBSSH2_PUBLICKEY_REQUEST_NOT_SUPPORTED, "request not supported", + sizeof("request not supported") - 1}, + {0, NULL, 0} +}; + +/* + * publickey_status_error + * + * Format an error message from a status code + */ +static void +publickey_status_error(const LIBSSH2_PUBLICKEY *pkey, + LIBSSH2_SESSION *session, int status) +{ + const char *msg; + + /* GENERAL_FAILURE got remapped between version 1 and 2 */ + if (status == 6 && pkey && pkey->version == 1) { + status = 7; + } + + if (status < 0 || status > LIBSSH2_PUBLICKEY_STATUS_CODE_MAX) { + msg = "unknown"; + } else { + msg = publickey_status_codes[status].name; + } + + _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, msg); +} + +/* + * publickey_packet_receive + * + * Read a packet from the subsystem + */ +static int +publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey, + unsigned char **data, size_t *data_len) +{ + LIBSSH2_CHANNEL *channel = pkey->channel; + LIBSSH2_SESSION *session = channel->session; + unsigned char buffer[4]; + int rc; + *data = NULL; /* default to nothing returned */ + *data_len = 0; + + if (pkey->receive_state == libssh2_NB_state_idle) { + rc = _libssh2_channel_read(channel, 0, (char *) buffer, 4); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc != 4) { + return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Invalid response from publickey subsystem"); + } + + pkey->receive_packet_len = _libssh2_ntohu32(buffer); + pkey->receive_packet = + LIBSSH2_ALLOC(session, pkey->receive_packet_len); + if (!pkey->receive_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate publickey response " + "buffer"); + } + + pkey->receive_state = libssh2_NB_state_sent; + } + + if (pkey->receive_state == libssh2_NB_state_sent) { + rc = _libssh2_channel_read(channel, 0, (char *) pkey->receive_packet, + pkey->receive_packet_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc != (int)pkey->receive_packet_len) { + LIBSSH2_FREE(session, pkey->receive_packet); + pkey->receive_packet = NULL; + pkey->receive_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Timeout waiting for publickey subsystem " + "response packet"); + } + + *data = pkey->receive_packet; + *data_len = pkey->receive_packet_len; + } + + pkey->receive_state = libssh2_NB_state_idle; + + return 0; +} + +/* publickey_response_id + * + * Translate a string response name to a numeric code + * Data will be incremented by 4 + response_len on success only + */ +static int +publickey_response_id(unsigned char **pdata, size_t data_len) +{ + size_t response_len; + unsigned char *data = *pdata; + const LIBSSH2_PUBLICKEY_CODE_LIST *codes = publickey_response_codes; + + if (data_len < 4) { + /* Malformed response */ + return -1; + } + response_len = _libssh2_ntohu32(data); + data += 4; + data_len -= 4; + if (data_len < response_len) { + /* Malformed response */ + return -1; + } + + while (codes->name) { + if ((unsigned long)codes->name_len == response_len && + strncmp(codes->name, (char *) data, response_len) == 0) { + *pdata = data + response_len; + return codes->code; + } + codes++; + } + + return -1; +} + +/* publickey_response_success + * + * Generic helper routine to wait for success response and nothing else + */ +static int +publickey_response_success(LIBSSH2_PUBLICKEY * pkey) +{ + LIBSSH2_SESSION *session = pkey->channel->session; + unsigned char *data, *s; + size_t data_len; + int response; + + while (1) { + int rc = publickey_packet_receive(pkey, &data, &data_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Timeout waiting for response from " + "publickey subsystem"); + } + + s = data; + response = publickey_response_id(&s, data_len); + + switch (response) { + case LIBSSH2_PUBLICKEY_RESPONSE_STATUS: + /* Error, or processing complete */ + { + unsigned long status = _libssh2_ntohu32(s); + + LIBSSH2_FREE(session, data); + + if (status == LIBSSH2_PUBLICKEY_SUCCESS) + return 0; + + publickey_status_error(pkey, session, status); + return -1; + } + default: + LIBSSH2_FREE(session, data); + if (response < 0) { + return _libssh2_error(session, + LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Invalid publickey subsystem response"); + } + /* Unknown/Unexpected */ + _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Unexpected publickey subsystem response"); + data = NULL; + } + } + /* never reached, but include `return` to silence compiler warnings */ + return -1; +} + +/* ***************** + * Publickey API * + ***************** */ + +/* + * publickey_init + * + * Startup the publickey subsystem + */ +static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session) +{ + int response; + int rc; + + if (session->pkeyInit_state == libssh2_NB_state_idle) { + session->pkeyInit_data = NULL; + session->pkeyInit_pkey = NULL; + session->pkeyInit_channel = NULL; + + _libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, + "Initializing publickey subsystem"); + + session->pkeyInit_state = libssh2_NB_state_allocated; + } + + if (session->pkeyInit_state == libssh2_NB_state_allocated) { + + session->pkeyInit_channel = + _libssh2_channel_open(session, "session", + sizeof("session") - 1, + LIBSSH2_CHANNEL_WINDOW_DEFAULT, + LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, + 0); + if (!session->pkeyInit_channel) { + if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) + /* The error state is already set, so leave it */ + return NULL; + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Unable to startup channel"); + goto err_exit; + } + + session->pkeyInit_state = libssh2_NB_state_sent; + } + + if (session->pkeyInit_state == libssh2_NB_state_sent) { + rc = _libssh2_channel_process_startup(session->pkeyInit_channel, + "subsystem", + sizeof("subsystem") - 1, + "publickey", + sizeof("publickey") - 1); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block starting publickey subsystem"); + return NULL; + } else if (rc) { + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Unable to request publickey subsystem"); + goto err_exit; + } + + session->pkeyInit_state = libssh2_NB_state_sent1; + } + + if (session->pkeyInit_state == libssh2_NB_state_sent1) { + unsigned char *s; + rc = _libssh2_channel_extended_data(session->pkeyInit_channel, + LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block starting publickey subsystem"); + return NULL; + } + + session->pkeyInit_pkey = + LIBSSH2_CALLOC(session, sizeof(LIBSSH2_PUBLICKEY)); + if (!session->pkeyInit_pkey) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate a new publickey structure"); + goto err_exit; + } + session->pkeyInit_pkey->channel = session->pkeyInit_channel; + session->pkeyInit_pkey->version = 0; + + s = session->pkeyInit_buffer; + _libssh2_htonu32(s, 4 + (sizeof("version") - 1) + 4); + s += 4; + _libssh2_htonu32(s, sizeof("version") - 1); + s += 4; + memcpy(s, "version", sizeof("version") - 1); + s += sizeof("version") - 1; + _libssh2_htonu32(s, LIBSSH2_PUBLICKEY_VERSION); + + session->pkeyInit_buffer_sent = 0; + + _libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, + "Sending publickey advertising version %d support", + (int) LIBSSH2_PUBLICKEY_VERSION); + + session->pkeyInit_state = libssh2_NB_state_sent2; + } + + if (session->pkeyInit_state == libssh2_NB_state_sent2) { + rc = _libssh2_channel_write(session->pkeyInit_channel, 0, + session->pkeyInit_buffer, + 19 - session->pkeyInit_buffer_sent); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending publickey version packet"); + return NULL; + } else if (rc < 0) { + _libssh2_error(session, rc, + "Unable to send publickey version packet"); + goto err_exit; + } + session->pkeyInit_buffer_sent += rc; + if(session->pkeyInit_buffer_sent < 19) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Need to be called again to complete this"); + return NULL; + } + + session->pkeyInit_state = libssh2_NB_state_sent3; + } + + if (session->pkeyInit_state == libssh2_NB_state_sent3) { + while (1) { + unsigned char *s; + rc = publickey_packet_receive(session->pkeyInit_pkey, + &session->pkeyInit_data, + &session->pkeyInit_data_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for response from " + "publickey subsystem"); + return NULL; + } else if (rc) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Timeout waiting for response from " + "publickey subsystem"); + goto err_exit; + } + + s = session->pkeyInit_data; + if ((response = + publickey_response_id(&s, session->pkeyInit_data_len)) < 0) { + _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Invalid publickey subsystem response code"); + goto err_exit; + } + + switch (response) { + case LIBSSH2_PUBLICKEY_RESPONSE_STATUS: + /* Error */ + { + unsigned long status, descr_len, lang_len; + + status = _libssh2_ntohu32(s); + s += 4; + descr_len = _libssh2_ntohu32(s); + s += 4; + /* description starts here */ + s += descr_len; + lang_len = _libssh2_ntohu32(s); + s += 4; + /* lang starts here */ + s += lang_len; + + if (s > + session->pkeyInit_data + session->pkeyInit_data_len) { + _libssh2_error(session, + LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Malformed publickey subsystem packet"); + goto err_exit; + } + + publickey_status_error(NULL, session, status); + + goto err_exit; + } + + case LIBSSH2_PUBLICKEY_RESPONSE_VERSION: + /* What we want */ + session->pkeyInit_pkey->version = _libssh2_ntohu32(s); + if (session->pkeyInit_pkey->version > + LIBSSH2_PUBLICKEY_VERSION) { + _libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, + "Truncate remote publickey version from %lu", + session->pkeyInit_pkey->version); + session->pkeyInit_pkey->version = + LIBSSH2_PUBLICKEY_VERSION; + } + _libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, + "Enabling publickey subsystem version %lu", + session->pkeyInit_pkey->version); + LIBSSH2_FREE(session, session->pkeyInit_data); + session->pkeyInit_data = NULL; + session->pkeyInit_state = libssh2_NB_state_idle; + return session->pkeyInit_pkey; + + default: + /* Unknown/Unexpected */ + _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Unexpected publickey subsystem response, " + "ignoring"); + LIBSSH2_FREE(session, session->pkeyInit_data); + session->pkeyInit_data = NULL; + } + } + } + + /* Never reached except by direct goto */ + err_exit: + session->pkeyInit_state = libssh2_NB_state_sent4; + if (session->pkeyInit_channel) { + rc = _libssh2_channel_close(session->pkeyInit_channel); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block closing channel"); + return NULL; + } + } + if (session->pkeyInit_pkey) { + LIBSSH2_FREE(session, session->pkeyInit_pkey); + session->pkeyInit_pkey = NULL; + } + if (session->pkeyInit_data) { + LIBSSH2_FREE(session, session->pkeyInit_data); + session->pkeyInit_data = NULL; + } + session->pkeyInit_state = libssh2_NB_state_idle; + return NULL; +} + +/* + * libssh2_publickey_init + * + * Startup the publickey subsystem + */ +LIBSSH2_API LIBSSH2_PUBLICKEY * +libssh2_publickey_init(LIBSSH2_SESSION *session) +{ + LIBSSH2_PUBLICKEY *ptr; + + BLOCK_ADJUST_ERRNO(ptr, session, + publickey_init(session)); + return ptr; +} + + + +/* + * libssh2_publickey_add_ex + * + * Add a new public key entry + */ +LIBSSH2_API int +libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, + unsigned long name_len, const unsigned char *blob, + unsigned long blob_len, char overwrite, + unsigned long num_attrs, + const libssh2_publickey_attribute attrs[]) +{ + LIBSSH2_CHANNEL *channel; + LIBSSH2_SESSION *session; + /* 19 = packet_len(4) + add_len(4) + "add"(3) + name_len(4) + {name} + blob_len(4) + {blob} */ + unsigned long i, packet_len = 19 + name_len + blob_len; + unsigned char *comment = NULL; + unsigned long comment_len = 0; + int rc; + + if(!pkey) + return LIBSSH2_ERROR_BAD_USE; + + channel = pkey->channel; + session = channel->session; + + if (pkey->add_state == libssh2_NB_state_idle) { + pkey->add_packet = NULL; + + _libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, "Adding %s publickey", + name); + + if (pkey->version == 1) { + for(i = 0; i < num_attrs; i++) { + /* Search for a comment attribute */ + if (attrs[i].name_len == (sizeof("comment") - 1) && + strncmp(attrs[i].name, "comment", + sizeof("comment") - 1) == 0) { + comment = (unsigned char *) attrs[i].value; + comment_len = attrs[i].value_len; + break; + } + } + packet_len += 4 + comment_len; + } else { + packet_len += 5; /* overwrite(1) + attribute_count(4) */ + for(i = 0; i < num_attrs; i++) { + packet_len += 9 + attrs[i].name_len + attrs[i].value_len; + /* name_len(4) + value_len(4) + mandatory(1) */ + } + } + + pkey->add_packet = LIBSSH2_ALLOC(session, packet_len); + if (!pkey->add_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "publickey \"add\" packet"); + } + + pkey->add_s = pkey->add_packet; + _libssh2_htonu32(pkey->add_s, packet_len - 4); + pkey->add_s += 4; + _libssh2_htonu32(pkey->add_s, sizeof("add") - 1); + pkey->add_s += 4; + memcpy(pkey->add_s, "add", sizeof("add") - 1); + pkey->add_s += sizeof("add") - 1; + if (pkey->version == 1) { + _libssh2_htonu32(pkey->add_s, comment_len); + pkey->add_s += 4; + if (comment) { + memcpy(pkey->add_s, comment, comment_len); + pkey->add_s += comment_len; + } + + _libssh2_htonu32(pkey->add_s, name_len); + pkey->add_s += 4; + memcpy(pkey->add_s, name, name_len); + pkey->add_s += name_len; + _libssh2_htonu32(pkey->add_s, blob_len); + pkey->add_s += 4; + memcpy(pkey->add_s, blob, blob_len); + pkey->add_s += blob_len; + } else { + /* Version == 2 */ + + _libssh2_htonu32(pkey->add_s, name_len); + pkey->add_s += 4; + memcpy(pkey->add_s, name, name_len); + pkey->add_s += name_len; + _libssh2_htonu32(pkey->add_s, blob_len); + pkey->add_s += 4; + memcpy(pkey->add_s, blob, blob_len); + pkey->add_s += blob_len; + *(pkey->add_s++) = overwrite ? 0x01 : 0; + _libssh2_htonu32(pkey->add_s, num_attrs); + pkey->add_s += 4; + for(i = 0; i < num_attrs; i++) { + _libssh2_htonu32(pkey->add_s, attrs[i].name_len); + pkey->add_s += 4; + memcpy(pkey->add_s, attrs[i].name, attrs[i].name_len); + pkey->add_s += attrs[i].name_len; + _libssh2_htonu32(pkey->add_s, attrs[i].value_len); + pkey->add_s += 4; + memcpy(pkey->add_s, attrs[i].value, attrs[i].value_len); + pkey->add_s += attrs[i].value_len; + *(pkey->add_s++) = attrs[i].mandatory ? 0x01 : 0; + } + } + + _libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, + "Sending publickey \"add\" packet: " + "type=%s blob_len=%ld num_attrs=%ld", + name, blob_len, num_attrs); + + pkey->add_state = libssh2_NB_state_created; + } + + if (pkey->add_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, pkey->add_packet, + (pkey->add_s - pkey->add_packet)); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if ((pkey->add_s - pkey->add_packet) != rc) { + LIBSSH2_FREE(session, pkey->add_packet); + pkey->add_packet = NULL; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send publickey add packet"); + } + LIBSSH2_FREE(session, pkey->add_packet); + pkey->add_packet = NULL; + + pkey->add_state = libssh2_NB_state_sent; + } + + rc = publickey_response_success(pkey); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + + pkey->add_state = libssh2_NB_state_idle; + + return rc; +} + +/* libssh2_publickey_remove_ex + * Remove an existing publickey so that authentication can no longer be + * performed using it + */ +LIBSSH2_API int +libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY * pkey, + const unsigned char *name, unsigned long name_len, + const unsigned char *blob, unsigned long blob_len) +{ + LIBSSH2_CHANNEL *channel; + LIBSSH2_SESSION *session; + /* 22 = packet_len(4) + remove_len(4) + "remove"(6) + name_len(4) + {name} + + blob_len(4) + {blob} */ + unsigned long packet_len = 22 + name_len + blob_len; + int rc; + + if(!pkey) + return LIBSSH2_ERROR_BAD_USE; + + channel = pkey->channel; + session = channel->session; + + if (pkey->remove_state == libssh2_NB_state_idle) { + pkey->remove_packet = NULL; + + pkey->remove_packet = LIBSSH2_ALLOC(session, packet_len); + if (!pkey->remove_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "publickey \"remove\" packet"); + } + + pkey->remove_s = pkey->remove_packet; + _libssh2_htonu32(pkey->remove_s, packet_len - 4); + pkey->remove_s += 4; + _libssh2_htonu32(pkey->remove_s, sizeof("remove") - 1); + pkey->remove_s += 4; + memcpy(pkey->remove_s, "remove", sizeof("remove") - 1); + pkey->remove_s += sizeof("remove") - 1; + _libssh2_htonu32(pkey->remove_s, name_len); + pkey->remove_s += 4; + memcpy(pkey->remove_s, name, name_len); + pkey->remove_s += name_len; + _libssh2_htonu32(pkey->remove_s, blob_len); + pkey->remove_s += 4; + memcpy(pkey->remove_s, blob, blob_len); + pkey->remove_s += blob_len; + + _libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, + "Sending publickey \"remove\" packet: " + "type=%s blob_len=%ld", + name, blob_len); + + pkey->remove_state = libssh2_NB_state_created; + } + + if (pkey->remove_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, pkey->remove_packet, + (pkey->remove_s - pkey->remove_packet)); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if ((pkey->remove_s - pkey->remove_packet) != rc) { + LIBSSH2_FREE(session, pkey->remove_packet); + pkey->remove_packet = NULL; + pkey->remove_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send publickey remove packet"); + } + LIBSSH2_FREE(session, pkey->remove_packet); + pkey->remove_packet = NULL; + + pkey->remove_state = libssh2_NB_state_sent; + } + + rc = publickey_response_success(pkey); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + + pkey->remove_state = libssh2_NB_state_idle; + + return rc; +} + +/* libssh2_publickey_list_fetch + * Fetch a list of supported public key from a server + */ +LIBSSH2_API int +libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys, + libssh2_publickey_list ** pkey_list) +{ + LIBSSH2_CHANNEL *channel; + LIBSSH2_SESSION *session; + libssh2_publickey_list *list = NULL; + unsigned long buffer_len = 12, keys = 0, max_keys = 0, i; + /* 12 = packet_len(4) + list_len(4) + "list"(4) */ + int response; + int rc; + + if(!pkey) + return LIBSSH2_ERROR_BAD_USE; + + channel = pkey->channel; + session = channel->session; + + if (pkey->listFetch_state == libssh2_NB_state_idle) { + pkey->listFetch_data = NULL; + + pkey->listFetch_s = pkey->listFetch_buffer; + _libssh2_htonu32(pkey->listFetch_s, buffer_len - 4); + pkey->listFetch_s += 4; + _libssh2_htonu32(pkey->listFetch_s, sizeof("list") - 1); + pkey->listFetch_s += 4; + memcpy(pkey->listFetch_s, "list", sizeof("list") - 1); + pkey->listFetch_s += sizeof("list") - 1; + + _libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, + "Sending publickey \"list\" packet"); + + pkey->listFetch_state = libssh2_NB_state_created; + } + + if (pkey->listFetch_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, + pkey->listFetch_buffer, + (pkey->listFetch_s - + pkey->listFetch_buffer)); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if ((pkey->listFetch_s - pkey->listFetch_buffer) != rc) { + pkey->listFetch_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send publickey list packet"); + } + + pkey->listFetch_state = libssh2_NB_state_sent; + } + + while (1) { + rc = publickey_packet_receive(pkey, &pkey->listFetch_data, + &pkey->listFetch_data_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Timeout waiting for response from " + "publickey subsystem"); + goto err_exit; + } + + pkey->listFetch_s = pkey->listFetch_data; + if ((response = + publickey_response_id(&pkey->listFetch_s, + pkey->listFetch_data_len)) < 0) { + _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Invalid publickey subsystem response code"); + goto err_exit; + } + + switch (response) { + case LIBSSH2_PUBLICKEY_RESPONSE_STATUS: + /* Error, or processing complete */ + { + unsigned long status, descr_len, lang_len; + + status = _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + descr_len = _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + /* description starts at pkey->listFetch_s */ + pkey->listFetch_s += descr_len; + lang_len = _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + /* lang starts at pkey->listFetch_s */ + pkey->listFetch_s += lang_len; + + if (pkey->listFetch_s > + pkey->listFetch_data + pkey->listFetch_data_len) { + _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Malformed publickey subsystem packet"); + goto err_exit; + } + + if (status == LIBSSH2_PUBLICKEY_SUCCESS) { + LIBSSH2_FREE(session, pkey->listFetch_data); + pkey->listFetch_data = NULL; + *pkey_list = list; + *num_keys = keys; + pkey->listFetch_state = libssh2_NB_state_idle; + return 0; + } + + publickey_status_error(pkey, session, status); + goto err_exit; + } + case LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY: + /* What we want */ + if (keys >= max_keys) { + libssh2_publickey_list *newlist; + /* Grow the key list if necessary */ + max_keys += 8; + newlist = + LIBSSH2_REALLOC(session, list, + (max_keys + + 1) * sizeof(libssh2_publickey_list)); + if (!newlist) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "publickey list"); + goto err_exit; + } + list = newlist; + } + if (pkey->version == 1) { + unsigned long comment_len; + + comment_len = _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + if (comment_len) { + list[keys].num_attrs = 1; + list[keys].attrs = + LIBSSH2_ALLOC(session, + sizeof(libssh2_publickey_attribute)); + if (!list[keys].attrs) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "publickey attributes"); + goto err_exit; + } + list[keys].attrs[0].name = "comment"; + list[keys].attrs[0].name_len = sizeof("comment") - 1; + list[keys].attrs[0].value = (char *) pkey->listFetch_s; + list[keys].attrs[0].value_len = comment_len; + list[keys].attrs[0].mandatory = 0; + + pkey->listFetch_s += comment_len; + } else { + list[keys].num_attrs = 0; + list[keys].attrs = NULL; + } + list[keys].name_len = _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + list[keys].name = pkey->listFetch_s; + pkey->listFetch_s += list[keys].name_len; + list[keys].blob_len = _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + list[keys].blob = pkey->listFetch_s; + pkey->listFetch_s += list[keys].blob_len; + } else { + /* Version == 2 */ + list[keys].name_len = _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + list[keys].name = pkey->listFetch_s; + pkey->listFetch_s += list[keys].name_len; + list[keys].blob_len = _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + list[keys].blob = pkey->listFetch_s; + pkey->listFetch_s += list[keys].blob_len; + list[keys].num_attrs = _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + if (list[keys].num_attrs) { + list[keys].attrs = + LIBSSH2_ALLOC(session, + list[keys].num_attrs * + sizeof(libssh2_publickey_attribute)); + if (!list[keys].attrs) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "publickey attributes"); + goto err_exit; + } + for(i = 0; i < list[keys].num_attrs; i++) { + list[keys].attrs[i].name_len = + _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + list[keys].attrs[i].name = (char *) pkey->listFetch_s; + pkey->listFetch_s += list[keys].attrs[i].name_len; + list[keys].attrs[i].value_len = + _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + list[keys].attrs[i].value = (char *) pkey->listFetch_s; + pkey->listFetch_s += list[keys].attrs[i].value_len; + + /* actually an ignored value */ + list[keys].attrs[i].mandatory = 0; + } + } else { + list[keys].attrs = NULL; + } + } + /* To be FREEd in libssh2_publickey_list_free() */ + list[keys].packet = pkey->listFetch_data; + keys++; + + list[keys].packet = NULL; /* Terminate the list */ + pkey->listFetch_data = NULL; + break; + default: + /* Unknown/Unexpected */ + _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Unexpected publickey subsystem response"); + LIBSSH2_FREE(session, pkey->listFetch_data); + pkey->listFetch_data = NULL; + } + } + + /* Only reached via explicit goto */ + err_exit: + if (pkey->listFetch_data) { + LIBSSH2_FREE(session, pkey->listFetch_data); + pkey->listFetch_data = NULL; + } + if (list) { + libssh2_publickey_list_free(pkey, list); + } + pkey->listFetch_state = libssh2_NB_state_idle; + return -1; +} + +/* libssh2_publickey_list_free + * Free a previously fetched list of public keys + */ +LIBSSH2_API void +libssh2_publickey_list_free(LIBSSH2_PUBLICKEY * pkey, + libssh2_publickey_list * pkey_list) +{ + LIBSSH2_SESSION *session; + libssh2_publickey_list *p = pkey_list; + + if(!pkey || !p) + return; + + session = pkey->channel->session; + + while (p->packet) { + if (p->attrs) { + LIBSSH2_FREE(session, p->attrs); + } + LIBSSH2_FREE(session, p->packet); + p++; + } + + LIBSSH2_FREE(session, pkey_list); +} + +/* libssh2_publickey_shutdown + * Shutdown the publickey subsystem + */ +LIBSSH2_API int +libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey) +{ + LIBSSH2_SESSION *session; + int rc; + + if(!pkey) + return LIBSSH2_ERROR_BAD_USE; + + session = pkey->channel->session; + + /* + * Make sure all memory used in the state variables are free + */ + if (pkey->receive_packet) { + LIBSSH2_FREE(session, pkey->receive_packet); + pkey->receive_packet = NULL; + } + if (pkey->add_packet) { + LIBSSH2_FREE(session, pkey->add_packet); + pkey->add_packet = NULL; + } + if (pkey->remove_packet) { + LIBSSH2_FREE(session, pkey->remove_packet); + pkey->remove_packet = NULL; + } + if (pkey->listFetch_data) { + LIBSSH2_FREE(session, pkey->listFetch_data); + pkey->listFetch_data = NULL; + } + + rc = _libssh2_channel_free(pkey->channel); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + + LIBSSH2_FREE(session, pkey); + return 0; +} diff --git a/libssh2/scp.c b/libssh2/scp.c new file mode 100644 index 0000000..22778dd --- /dev/null +++ b/libssh2/scp.c @@ -0,0 +1,1126 @@ +/* Copyright (c) 2009-2010 by Daniel Stenberg + * Copyright (c) 2004-2008, Sara Golemon + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#include +#include + +#include "channel.h" +#include "session.h" + + +/* Max. length of a quoted string after libssh2_shell_quotearg() processing */ +#define _libssh2_shell_quotedsize(s) (3 * strlen(s) + 2) + +/* + This function quotes a string in a way suitable to be used with a + shell, e.g. the file name + one two + becomes + 'one two' + + The resulting output string is crafted in a way that makes it usable + with the two most common shell types: Bourne Shell derived shells + (sh, ksh, ksh93, bash, zsh) and C-Shell derivates (csh, tcsh). + + The following special cases are handled: + o If the string contains an apostrophy itself, the apostrophy + character is written in quotation marks, e.g. "'". + The shell cannot handle the syntax 'doesn\'t', so we close the + current argument word, add the apostrophe in quotation marks "", + and open a new argument word instead (_ indicate the input + string characters): + _____ _ _ + 'doesn' "'" 't' + + Sequences of apostrophes are combined in one pair of quotation marks: + a'''b + becomes + _ ___ _ + 'a'"'''"'b' + + o If the string contains an exclamation mark (!), the C-Shell + interprets it as an event number. Using \! (not within quotation + marks or single quotation marks) is a mechanism understood by + both Bourne Shell and C-Shell. + + If a quotation was already started, the argument word is closed + first: + a!b + + become + _ _ _ + 'a'\!'b' + + The result buffer must be large enough for the expanded result. A + bad case regarding expansion is alternating characters and + apostrophes: + + a'b'c'd' (length 8) gets converted to + 'a'"'"'b'"'"'c'"'"'d'"'" (length 24) + + This is the worst case. + + Maximum length of the result: + 1 + 6 * (length(input) + 1) / 2) + 1 + + => 3 * length(input) + 2 + + Explanation: + o leading apostrophe + o one character / apostrophe pair (two characters) can get + represented as 6 characters: a' -> a'"'"' + o String terminator (+1) + + A result buffer three times the size of the input buffer + 2 + characters should be safe. + + References: + o csh-compatible quotation (special handling for '!' etc.), see + http://www.grymoire.com/Unix/Csh.html#toc-uh-10 + + Return value: + Length of the resulting string (not counting the terminating '\0'), + or 0 in case of errors, e.g. result buffer too small + + Note: this function could possible be used elsewhere within libssh2, but + until then it is kept static and in this source file. +*/ + +static unsigned +shell_quotearg(const char *path, unsigned char *buf, + unsigned bufsize) +{ + const char *src; + unsigned char *dst, *endp; + + /* + * Processing States: + * UQSTRING: unquoted string: ... -- used for quoting exclamation + * marks. This is the initial state + * SQSTRING: single-quoted-string: '... -- any character may follow + * QSTRING: quoted string: "... -- only apostrophes may follow + */ + enum { UQSTRING, SQSTRING, QSTRING } state = UQSTRING; + + endp = &buf[bufsize]; + src = path; + dst = buf; + while (*src && dst < endp - 1) { + + switch (*src) { + /* + * Special handling for apostrophe. + * An apostrophe is always written in quotation marks, e.g. + * ' -> "'". + */ + + case '\'': + switch (state) { + case UQSTRING: /* Unquoted string */ + if (dst+1 >= endp) + return 0; + *dst++ = '"'; + break; + case QSTRING: /* Continue quoted string */ + break; + case SQSTRING: /* Close single quoted string */ + if (dst+2 >= endp) + return 0; + *dst++ = '\''; + *dst++ = '"'; + break; + default: + break; + } + state = QSTRING; + break; + + /* + * Special handling for exclamation marks. CSH interprets + * exclamation marks even when quoted with apostrophes. We convert + * it to the plain string \!, because both Bourne Shell and CSH + * interpret that as a verbatim exclamation mark. + */ + + case '!': + switch (state) { + case UQSTRING: + if (dst+1 >= endp) + return 0; + *dst++ = '\\'; + break; + case QSTRING: + if (dst+2 >= endp) + return 0; + *dst++ = '"'; /* Closing quotation mark */ + *dst++ = '\\'; + break; + case SQSTRING: /* Close single quoted string */ + if (dst+2 >= endp) + return 0; + *dst++ = '\''; + *dst++ = '\\'; + break; + default: + break; + } + state = UQSTRING; + break; + + /* + * Ordinary character: prefer single-quoted string + */ + + default: + switch (state) { + case UQSTRING: + if (dst+1 >= endp) + return 0; + *dst++ = '\''; + break; + case QSTRING: + if (dst+2 >= endp) + return 0; + *dst++ = '"'; /* Closing quotation mark */ + *dst++ = '\''; + break; + case SQSTRING: /* Continue single quoted string */ + break; + default: + break; + } + state = SQSTRING; /* Start single-quoted string */ + break; + } + + if (dst+1 >= endp) + return 0; + *dst++ = *src++; + } + + switch (state) { + case UQSTRING: + break; + case QSTRING: /* Close quoted string */ + if (dst+1 >= endp) + return 0; + *dst++ = '"'; + break; + case SQSTRING: /* Close single quoted string */ + if (dst+1 >= endp) + return 0; + *dst++ = '\''; + break; + default: + break; + } + + if (dst+1 >= endp) + return 0; + *dst = '\0'; + + /* The result cannot be larger than 3 * strlen(path) + 2 */ + /* assert((dst - buf) <= (3 * (src - path) + 2)); */ + + return dst - buf; +} + +/* + * scp_recv + * + * Open a channel and request a remote file via SCP + * + */ +static LIBSSH2_CHANNEL * +scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb) +{ + int cmd_len; + int rc; + int tmp_err_code; + const char *tmp_err_msg; + + if (session->scpRecv_state == libssh2_NB_state_idle) { + session->scpRecv_mode = 0; + session->scpRecv_size = 0; + session->scpRecv_mtime = 0; + session->scpRecv_atime = 0; + + session->scpRecv_command_len = + _libssh2_shell_quotedsize(path) + sizeof("scp -f ") + (sb?1:0); + + session->scpRecv_command = + LIBSSH2_ALLOC(session, session->scpRecv_command_len); + + if (!session->scpRecv_command) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate a command buffer for " + "SCP session"); + return NULL; + } + + snprintf((char *)session->scpRecv_command, + session->scpRecv_command_len, + "scp -%sf ", sb?"p":""); + + cmd_len = strlen((char *)session->scpRecv_command); + cmd_len += shell_quotearg(path, + &session->scpRecv_command[cmd_len], + session->scpRecv_command_len - cmd_len); + + session->scpRecv_command[cmd_len] = '\0'; + session->scpRecv_command_len = cmd_len + 1; + + _libssh2_debug(session, LIBSSH2_TRACE_SCP, + "Opening channel for SCP receive"); + + session->scpRecv_state = libssh2_NB_state_created; + } + + if (session->scpRecv_state == libssh2_NB_state_created) { + /* Allocate a channel */ + session->scpRecv_channel = + _libssh2_channel_open(session, "session", + sizeof("session") - 1, + LIBSSH2_CHANNEL_WINDOW_DEFAULT, + LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, + 0); + if (!session->scpRecv_channel) { + if (libssh2_session_last_errno(session) != + LIBSSH2_ERROR_EAGAIN) { + LIBSSH2_FREE(session, session->scpRecv_command); + session->scpRecv_command = NULL; + session->scpRecv_state = libssh2_NB_state_idle; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block starting up channel"); + } + return NULL; + } + + session->scpRecv_state = libssh2_NB_state_sent; + } + + if (session->scpRecv_state == libssh2_NB_state_sent) { + /* Request SCP for the desired file */ + rc = _libssh2_channel_process_startup(session->scpRecv_channel, "exec", + sizeof("exec") - 1, + (char *) session->scpRecv_command, + session->scpRecv_command_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block requesting SCP startup"); + return NULL; + } else if (rc) { + LIBSSH2_FREE(session, session->scpRecv_command); + session->scpRecv_command = NULL; + goto scp_recv_error; + } + LIBSSH2_FREE(session, session->scpRecv_command); + session->scpRecv_command = NULL; + + _libssh2_debug(session, LIBSSH2_TRACE_SCP, "Sending initial wakeup"); + /* SCP ACK */ + session->scpRecv_response[0] = '\0'; + + session->scpRecv_state = libssh2_NB_state_sent1; + } + + if (session->scpRecv_state == libssh2_NB_state_sent1) { + rc = _libssh2_channel_write(session->scpRecv_channel, 0, + session->scpRecv_response, 1); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending initial wakeup"); + return NULL; + } else if (rc != 1) { + goto scp_recv_error; + } + + /* Parse SCP response */ + session->scpRecv_response_len = 0; + + session->scpRecv_state = libssh2_NB_state_sent2; + } + + if ((session->scpRecv_state == libssh2_NB_state_sent2) + || (session->scpRecv_state == libssh2_NB_state_sent3)) { + while (sb && (session->scpRecv_response_len < + LIBSSH2_SCP_RESPONSE_BUFLEN)) { + unsigned char *s, *p; + + if (session->scpRecv_state == libssh2_NB_state_sent2) { + rc = _libssh2_channel_read(session->scpRecv_channel, 0, + (char *) session-> + scpRecv_response + + session->scpRecv_response_len, 1); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for SCP response"); + return NULL; + } + else if (rc < 0) { + /* error, give up */ + _libssh2_error(session, rc, "Failed reading SCP response"); + goto scp_recv_error; + } + else if(rc == 0) + goto scp_recv_empty_channel; + + session->scpRecv_response_len++; + + if (session->scpRecv_response[0] != 'T') { + size_t err_len; + char *err_msg; + + /* there can be + 01 for warnings + 02 for errors + + The following string MUST be newline terminated + */ + err_len = + _libssh2_channel_packet_data_len(session-> + scpRecv_channel, 0); + err_msg = LIBSSH2_ALLOC(session, err_len + 1); + if (!err_msg) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Failed to get memory "); + goto scp_recv_error; + } + + /* Read the remote error message */ + (void)_libssh2_channel_read(session->scpRecv_channel, 0, + err_msg, err_len); + /* If it failed for any reason, we ignore it anyway. */ + + /* zero terminate the error */ + err_msg[err_len]=0; + + _libssh2_debug(session, LIBSSH2_TRACE_SCP, + "got %02x %s", session->scpRecv_response[0], + err_msg); + + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Failed to recv file"); + + LIBSSH2_FREE(session, err_msg); + goto scp_recv_error; + } + + if ((session->scpRecv_response_len > 1) && + ((session-> + scpRecv_response[session->scpRecv_response_len - 1] < + '0') + || (session-> + scpRecv_response[session->scpRecv_response_len - 1] > + '9')) + && (session-> + scpRecv_response[session->scpRecv_response_len - 1] != + ' ') + && (session-> + scpRecv_response[session->scpRecv_response_len - 1] != + '\r') + && (session-> + scpRecv_response[session->scpRecv_response_len - 1] != + '\n')) { + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid data in SCP response"); + goto scp_recv_error; + } + + if ((session->scpRecv_response_len < 9) + || (session-> + scpRecv_response[session->scpRecv_response_len - 1] != + '\n')) { + if (session->scpRecv_response_len == + LIBSSH2_SCP_RESPONSE_BUFLEN) { + /* You had your chance */ + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Unterminated response from SCP server"); + goto scp_recv_error; + } + /* Way too short to be an SCP response, or not done yet, + short circuit */ + continue; + } + + /* We're guaranteed not to go under response_len == 0 by the + logic above */ + while ((session-> + scpRecv_response[session->scpRecv_response_len - 1] == + '\r') + || (session-> + scpRecv_response[session->scpRecv_response_len - + 1] == '\n')) + session->scpRecv_response_len--; + session->scpRecv_response[session->scpRecv_response_len] = + '\0'; + + if (session->scpRecv_response_len < 8) { + /* EOL came too soon */ + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, " + "too short" ); + goto scp_recv_error; + } + + s = session->scpRecv_response + 1; + + p = (unsigned char *) strchr((char *) s, ' '); + if (!p || ((p - s) <= 0)) { + /* No spaces or space in the wrong spot */ + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, " + "malformed mtime"); + goto scp_recv_error; + } + + *(p++) = '\0'; + /* Make sure we don't get fooled by leftover values */ + session->scpRecv_mtime = strtol((char *) s, NULL, 10); + + s = (unsigned char *) strchr((char *) p, ' '); + if (!s || ((s - p) <= 0)) { + /* No spaces or space in the wrong spot */ + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, malformed mtime.usec"); + goto scp_recv_error; + } + + /* Ignore mtime.usec */ + s++; + p = (unsigned char *) strchr((char *) s, ' '); + if (!p || ((p - s) <= 0)) { + /* No spaces or space in the wrong spot */ + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, too short or malformed"); + goto scp_recv_error; + } + + *p = '\0'; + /* Make sure we don't get fooled by leftover values */ + session->scpRecv_atime = strtol((char *) s, NULL, 10); + + /* SCP ACK */ + session->scpRecv_response[0] = '\0'; + + session->scpRecv_state = libssh2_NB_state_sent3; + } + + if (session->scpRecv_state == libssh2_NB_state_sent3) { + rc = _libssh2_channel_write(session->scpRecv_channel, 0, + session->scpRecv_response, 1); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting to send SCP ACK"); + return NULL; + } else if (rc != 1) { + goto scp_recv_error; + } + + _libssh2_debug(session, LIBSSH2_TRACE_SCP, + "mtime = %ld, atime = %ld", + session->scpRecv_mtime, session->scpRecv_atime); + + /* We *should* check that atime.usec is valid, but why let + that stop use? */ + break; + } + } + + session->scpRecv_state = libssh2_NB_state_sent4; + } + + if (session->scpRecv_state == libssh2_NB_state_sent4) { + session->scpRecv_response_len = 0; + + session->scpRecv_state = libssh2_NB_state_sent5; + } + + if ((session->scpRecv_state == libssh2_NB_state_sent5) + || (session->scpRecv_state == libssh2_NB_state_sent6)) { + while (session->scpRecv_response_len < LIBSSH2_SCP_RESPONSE_BUFLEN) { + char *s, *p, *e = NULL; + + if (session->scpRecv_state == libssh2_NB_state_sent5) { + rc = _libssh2_channel_read(session->scpRecv_channel, 0, + (char *) session-> + scpRecv_response + + session->scpRecv_response_len, 1); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for SCP response"); + return NULL; + } + else if (rc < 0) { + /* error, bail out*/ + _libssh2_error(session, rc, "Failed reading SCP response"); + goto scp_recv_error; + } + else if(rc == 0) + goto scp_recv_empty_channel; + + session->scpRecv_response_len++; + + if (session->scpRecv_response[0] != 'C') { + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server"); + goto scp_recv_error; + } + + if ((session->scpRecv_response_len > 1) && + (session-> + scpRecv_response[session->scpRecv_response_len - 1] != + '\r') + && (session-> + scpRecv_response[session->scpRecv_response_len - 1] != + '\n') + && + (session-> + scpRecv_response[session->scpRecv_response_len - 1] + < 32)) { + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid data in SCP response"); + goto scp_recv_error; + } + + if ((session->scpRecv_response_len < 7) + || (session-> + scpRecv_response[session->scpRecv_response_len - 1] != + '\n')) { + if (session->scpRecv_response_len == + LIBSSH2_SCP_RESPONSE_BUFLEN) { + /* You had your chance */ + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Unterminated response from SCP server"); + goto scp_recv_error; + } + /* Way too short to be an SCP response, or not done yet, + short circuit */ + continue; + } + + /* We're guaranteed not to go under response_len == 0 by the + logic above */ + while ((session-> + scpRecv_response[session->scpRecv_response_len - 1] == + '\r') + || (session-> + scpRecv_response[session->scpRecv_response_len - + 1] == '\n')) { + session->scpRecv_response_len--; + } + session->scpRecv_response[session->scpRecv_response_len] = + '\0'; + + if (session->scpRecv_response_len < 6) { + /* EOL came too soon */ + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, too short"); + goto scp_recv_error; + } + + s = (char *) session->scpRecv_response + 1; + + p = strchr(s, ' '); + if (!p || ((p - s) <= 0)) { + /* No spaces or space in the wrong spot */ + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, malformed mode"); + goto scp_recv_error; + } + + *(p++) = '\0'; + /* Make sure we don't get fooled by leftover values */ + + session->scpRecv_mode = strtol(s, &e, 8); + if (e && *e) { + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, invalid mode"); + goto scp_recv_error; + } + + s = strchr(p, ' '); + if (!s || ((s - p) <= 0)) { + /* No spaces or space in the wrong spot */ + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, too short or malformed"); + goto scp_recv_error; + } + + *s = '\0'; + /* Make sure we don't get fooled by leftover values */ + session->scpRecv_size = scpsize_strtol(p, &e, 10); + if (e && *e) { + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, invalid size"); + goto scp_recv_error; + } + + /* SCP ACK */ + session->scpRecv_response[0] = '\0'; + + session->scpRecv_state = libssh2_NB_state_sent6; + } + + if (session->scpRecv_state == libssh2_NB_state_sent6) { + rc = _libssh2_channel_write(session->scpRecv_channel, 0, + session->scpRecv_response, 1); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending SCP ACK"); + return NULL; + } else if (rc != 1) { + goto scp_recv_error; + } + _libssh2_debug(session, LIBSSH2_TRACE_SCP, + "mode = 0%lo size = %ld", session->scpRecv_mode, + session->scpRecv_size); + + /* We *should* check that basename is valid, but why let that + stop us? */ + break; + } + } + + session->scpRecv_state = libssh2_NB_state_sent7; + } + + if (sb) { + memset(sb, 0, sizeof(libssh2_struct_stat)); + + sb->st_mtime = session->scpRecv_mtime; + sb->st_atime = session->scpRecv_atime; + sb->st_size = session->scpRecv_size; + sb->st_mode = (unsigned short)session->scpRecv_mode; + } + + session->scpRecv_state = libssh2_NB_state_idle; + return session->scpRecv_channel; + + scp_recv_empty_channel: + /* the code only jumps here as a result of a zero read from channel_read() + so we check EOF status to avoid getting stuck in a loop */ + if(libssh2_channel_eof(session->scpRecv_channel)) + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Unexpected channel close"); + else + return session->scpRecv_channel; + /* fall-through */ + scp_recv_error: + tmp_err_code = session->err_code; + tmp_err_msg = session->err_msg; + while (libssh2_channel_free(session->scpRecv_channel) == + LIBSSH2_ERROR_EAGAIN); + session->err_code = tmp_err_code; + session->err_msg = tmp_err_msg; + session->scpRecv_channel = NULL; + session->scpRecv_state = libssh2_NB_state_idle; + return NULL; +} + +/* + * libssh2_scp_recv + * + * DEPRECATED + * + * Open a channel and request a remote file via SCP. This receives files larger + * than 2 GB, but is unable to report the proper size on platforms where the + * st_size member of struct stat is limited to 2 GB (e.g. windows). + * + */ +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_scp_recv(LIBSSH2_SESSION *session, const char *path, struct stat * sb) +{ + LIBSSH2_CHANNEL *ptr; + + /* scp_recv uses libssh2_struct_stat, so pass one if the caller gave us a struct to populate... */ + libssh2_struct_stat sb_intl; + libssh2_struct_stat *sb_ptr; + sb_ptr = sb ? &sb_intl : NULL; + + BLOCK_ADJUST_ERRNO(ptr, session, scp_recv(session, path, sb_ptr)); + + /* ...and populate the caller's with as much info as fits. */ + if (sb) { + memset(sb, 0, sizeof(struct stat)); + + sb->st_mtime = sb_intl.st_mtime; + sb->st_atime = sb_intl.st_atime; + sb->st_size = (off_t)sb_intl.st_size; + sb->st_mode = sb_intl.st_mode; + } + + return ptr; +} + +/* + * libssh2_scp_recv2 + * + * Open a channel and request a remote file via SCP. This supports files > 2GB + * on platforms that support it. + * + */ +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_scp_recv2(LIBSSH2_SESSION *session, const char *path, libssh2_struct_stat * sb) +{ + LIBSSH2_CHANNEL *ptr; + BLOCK_ADJUST_ERRNO(ptr, session, scp_recv(session, path, sb)); + return ptr; +} + +/* + * scp_send() + * + * Send a file using SCP + * + */ +static LIBSSH2_CHANNEL * +scp_send(LIBSSH2_SESSION * session, const char *path, int mode, + libssh2_int64_t size, time_t mtime, time_t atime) +{ + int cmd_len; + int rc; + int tmp_err_code; + const char *tmp_err_msg; + + if (session->scpSend_state == libssh2_NB_state_idle) { + session->scpSend_command_len = + _libssh2_shell_quotedsize(path) + sizeof("scp -t ") + + ((mtime || atime)?1:0); + + session->scpSend_command = + LIBSSH2_ALLOC(session, session->scpSend_command_len); + + if (!session->scpSend_command) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate a command buffer for " + "SCP session"); + return NULL; + } + + snprintf((char *)session->scpSend_command, + session->scpSend_command_len, + "scp -%st ", (mtime || atime)?"p":""); + + cmd_len = strlen((char *)session->scpSend_command); + cmd_len += shell_quotearg(path, + &session->scpSend_command[cmd_len], + session->scpSend_command_len - cmd_len); + + session->scpSend_command[cmd_len] = '\0'; + session->scpSend_command_len = cmd_len + 1; + + _libssh2_debug(session, LIBSSH2_TRACE_SCP, + "Opening channel for SCP send"); + /* Allocate a channel */ + + session->scpSend_state = libssh2_NB_state_created; + } + + if (session->scpSend_state == libssh2_NB_state_created) { + session->scpSend_channel = + _libssh2_channel_open(session, "session", sizeof("session") - 1, + LIBSSH2_CHANNEL_WINDOW_DEFAULT, + LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0); + if (!session->scpSend_channel) { + if (libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) { + /* previous call set libssh2_session_last_error(), pass it + through */ + LIBSSH2_FREE(session, session->scpSend_command); + session->scpSend_command = NULL; + session->scpSend_state = libssh2_NB_state_idle; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block starting up channel"); + } + return NULL; + } + + session->scpSend_state = libssh2_NB_state_sent; + } + + if (session->scpSend_state == libssh2_NB_state_sent) { + /* Request SCP for the desired file */ + rc = _libssh2_channel_process_startup(session->scpSend_channel, "exec", + sizeof("exec") - 1, + (char *) session->scpSend_command, + session->scpSend_command_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block requesting SCP startup"); + return NULL; + } + else if (rc) { + /* previous call set libssh2_session_last_error(), pass it + through */ + LIBSSH2_FREE(session, session->scpSend_command); + session->scpSend_command = NULL; + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Unknown error while getting error string"); + goto scp_send_error; + } + LIBSSH2_FREE(session, session->scpSend_command); + session->scpSend_command = NULL; + + session->scpSend_state = libssh2_NB_state_sent1; + } + + if (session->scpSend_state == libssh2_NB_state_sent1) { + /* Wait for ACK */ + rc = _libssh2_channel_read(session->scpSend_channel, 0, + (char *) session->scpSend_response, 1); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for response from remote"); + return NULL; + } + else if (rc < 0) { + _libssh2_error(session, rc, "SCP failure"); + goto scp_send_error; + } + else if(!rc) + /* remain in the same state */ + goto scp_send_empty_channel; + else if (session->scpSend_response[0] != 0) { + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid ACK response from remote"); + goto scp_send_error; + } + if (mtime || atime) { + /* Send mtime and atime to be used for file */ + session->scpSend_response_len = + snprintf((char *) session->scpSend_response, + LIBSSH2_SCP_RESPONSE_BUFLEN, "T%ld 0 %ld 0\n", + (long)mtime, (long)atime); + _libssh2_debug(session, LIBSSH2_TRACE_SCP, "Sent %s", + session->scpSend_response); + } + + session->scpSend_state = libssh2_NB_state_sent2; + } + + /* Send mtime and atime to be used for file */ + if (mtime || atime) { + if (session->scpSend_state == libssh2_NB_state_sent2) { + rc = _libssh2_channel_write(session->scpSend_channel, 0, + session->scpSend_response, + session->scpSend_response_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending time data for SCP file"); + return NULL; + } else if (rc != (int)session->scpSend_response_len) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send time data for SCP file"); + goto scp_send_error; + } + + session->scpSend_state = libssh2_NB_state_sent3; + } + + if (session->scpSend_state == libssh2_NB_state_sent3) { + /* Wait for ACK */ + rc = _libssh2_channel_read(session->scpSend_channel, 0, + (char *) session->scpSend_response, 1); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for response"); + return NULL; + } + else if (rc < 0) { + _libssh2_error(session, rc, "SCP failure"); + goto scp_send_error; + } + else if(!rc) + /* remain in the same state */ + goto scp_send_empty_channel; + else if (session->scpSend_response[0] != 0) { + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid SCP ACK response"); + goto scp_send_error; + } + + session->scpSend_state = libssh2_NB_state_sent4; + } + } else { + if (session->scpSend_state == libssh2_NB_state_sent2) { + session->scpSend_state = libssh2_NB_state_sent4; + } + } + + if (session->scpSend_state == libssh2_NB_state_sent4) { + /* Send mode, size, and basename */ + const char *base = strrchr(path, '/'); + if (base) + base++; + else + base = path; + + session->scpSend_response_len = + snprintf((char *) session->scpSend_response, + LIBSSH2_SCP_RESPONSE_BUFLEN, "C0%o %" + LIBSSH2_INT64_T_FORMAT " %s\n", mode, + size, base); + _libssh2_debug(session, LIBSSH2_TRACE_SCP, "Sent %s", + session->scpSend_response); + + session->scpSend_state = libssh2_NB_state_sent5; + } + + if (session->scpSend_state == libssh2_NB_state_sent5) { + rc = _libssh2_channel_write(session->scpSend_channel, 0, + session->scpSend_response, + session->scpSend_response_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block send core file data for SCP file"); + return NULL; + } else if (rc != (int)session->scpSend_response_len) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send core file data for SCP file"); + goto scp_send_error; + } + + session->scpSend_state = libssh2_NB_state_sent6; + } + + if (session->scpSend_state == libssh2_NB_state_sent6) { + /* Wait for ACK */ + rc = _libssh2_channel_read(session->scpSend_channel, 0, + (char *) session->scpSend_response, 1); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for response"); + return NULL; + } + else if (rc < 0) { + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid ACK response from remote"); + goto scp_send_error; + } + else if (rc == 0) + goto scp_send_empty_channel; + + else if (session->scpSend_response[0] != 0) { + size_t err_len; + char *err_msg; + + err_len = + _libssh2_channel_packet_data_len(session->scpSend_channel, 0); + err_msg = LIBSSH2_ALLOC(session, err_len + 1); + if (!err_msg) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "failed to get memory"); + goto scp_send_error; + } + + /* Read the remote error message */ + rc = _libssh2_channel_read(session->scpSend_channel, 0, + err_msg, err_len); + if (rc > 0) { + err_msg[err_len]=0; + _libssh2_debug(session, LIBSSH2_TRACE_SCP, + "got %02x %s", session->scpSend_response[0], + err_msg); + } + LIBSSH2_FREE(session, err_msg); + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "failed to send file"); + goto scp_send_error; + } + } + + session->scpSend_state = libssh2_NB_state_idle; + return session->scpSend_channel; + + scp_send_empty_channel: + /* the code only jumps here as a result of a zero read from channel_read() + so we check EOF status to avoid getting stuck in a loop */ + if(libssh2_channel_eof(session->scpSend_channel)) { + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Unexpected channel close"); + } + else + return session->scpSend_channel; + /* fall-through */ + scp_send_error: + tmp_err_code = session->err_code; + tmp_err_msg = session->err_msg; + while (libssh2_channel_free(session->scpSend_channel) == + LIBSSH2_ERROR_EAGAIN); + session->err_code = tmp_err_code; + session->err_msg = tmp_err_msg; + session->scpSend_channel = NULL; + session->scpSend_state = libssh2_NB_state_idle; + return NULL; +} + +/* + * libssh2_scp_send_ex + * + * Send a file using SCP. Old API. + */ +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, + size_t size, long mtime, long atime) +{ + LIBSSH2_CHANNEL *ptr; + BLOCK_ADJUST_ERRNO(ptr, session, + scp_send(session, path, mode, size, + (time_t)mtime, (time_t)atime)); + return ptr; +} + +/* + * libssh2_scp_send64 + * + * Send a file using SCP + */ +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_scp_send64(LIBSSH2_SESSION *session, const char *path, int mode, + libssh2_int64_t size, time_t mtime, time_t atime) +{ + LIBSSH2_CHANNEL *ptr; + BLOCK_ADJUST_ERRNO(ptr, session, + scp_send(session, path, mode, size, mtime, atime)); + return ptr; +} diff --git a/libssh2/session.c b/libssh2/session.c new file mode 100644 index 0000000..06e61dd --- /dev/null +++ b/libssh2/session.c @@ -0,0 +1,1791 @@ +/* Copyright (c) 2004-2007 Sara Golemon + * Copyright (c) 2009-2015 by Daniel Stenberg + * Copyright (c) 2010 Simon Josefsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include + +#ifdef HAVE_GETTIMEOFDAY +#include +#endif +#ifdef HAVE_ALLOCA_H +#include +#endif + +#include "transport.h" +#include "session.h" +#include "channel.h" +#include "mac.h" +#include "misc.h" + +/* libssh2_default_alloc + */ +static +LIBSSH2_ALLOC_FUNC(libssh2_default_alloc) +{ + (void) abstract; + return malloc(count); +} + +/* libssh2_default_free + */ +static +LIBSSH2_FREE_FUNC(libssh2_default_free) +{ + (void) abstract; + free(ptr); +} + +/* libssh2_default_realloc + */ +static +LIBSSH2_REALLOC_FUNC(libssh2_default_realloc) +{ + (void) abstract; + return realloc(ptr, count); +} + +/* + * banner_receive + * + * Wait for a hello from the remote host + * Allocate a buffer and store the banner in session->remote.banner + * Returns: 0 on success, LIBSSH2_ERROR_EAGAIN if read would block, negative + * on failure + */ +static int +banner_receive(LIBSSH2_SESSION * session) +{ + int ret; + int banner_len; + + if (session->banner_TxRx_state == libssh2_NB_state_idle) { + banner_len = 0; + + session->banner_TxRx_state = libssh2_NB_state_created; + } else { + banner_len = session->banner_TxRx_total_send; + } + + while ((banner_len < (int) sizeof(session->banner_TxRx_banner)) && + ((banner_len == 0) + || (session->banner_TxRx_banner[banner_len - 1] != '\n'))) { + char c = '\0'; + + /* no incoming block yet! */ + session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_INBOUND; + + ret = LIBSSH2_RECV(session, &c, 1, + LIBSSH2_SOCKET_RECV_FLAGS(session)); + if (ret < 0) { + if(session->api_block_mode || (ret != -EAGAIN)) + /* ignore EAGAIN when non-blocking */ + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Error recving %d bytes: %d", 1, -ret); + } + else + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Recved %d bytes banner", ret); + + if (ret < 0) { + if (ret == -EAGAIN) { + session->socket_block_directions = + LIBSSH2_SESSION_BLOCK_INBOUND; + session->banner_TxRx_total_send = banner_len; + return LIBSSH2_ERROR_EAGAIN; + } + + /* Some kinda error */ + session->banner_TxRx_state = libssh2_NB_state_idle; + session->banner_TxRx_total_send = 0; + return LIBSSH2_ERROR_SOCKET_RECV; + } + + if (ret == 0) { + session->socket_state = LIBSSH2_SOCKET_DISCONNECTED; + return LIBSSH2_ERROR_SOCKET_DISCONNECT; + } + + if (c == '\0') { + /* NULLs are not allowed in SSH banners */ + session->banner_TxRx_state = libssh2_NB_state_idle; + session->banner_TxRx_total_send = 0; + return LIBSSH2_ERROR_BANNER_RECV; + } + + session->banner_TxRx_banner[banner_len++] = c; + } + + while (banner_len && + ((session->banner_TxRx_banner[banner_len - 1] == '\n') || + (session->banner_TxRx_banner[banner_len - 1] == '\r'))) { + banner_len--; + } + + /* From this point on, we are done here */ + session->banner_TxRx_state = libssh2_NB_state_idle; + session->banner_TxRx_total_send = 0; + + if (!banner_len) + return LIBSSH2_ERROR_BANNER_RECV; + + session->remote.banner = LIBSSH2_ALLOC(session, banner_len + 1); + if (!session->remote.banner) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Error allocating space for remote banner"); + } + memcpy(session->remote.banner, session->banner_TxRx_banner, banner_len); + session->remote.banner[banner_len] = '\0'; + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Received Banner: %s", + session->remote.banner); + return LIBSSH2_ERROR_NONE; +} + +/* + * banner_send + * + * Send the default banner, or the one set via libssh2_setopt_string + * + * Returns LIBSSH2_ERROR_EAGAIN if it would block - and if it does so, you + * should call this function again as soon as it is likely that more data can + * be sent, and this function should then be called with the same argument set + * (same data pointer and same data_len) until zero or failure is returned. + */ +static int +banner_send(LIBSSH2_SESSION * session) +{ + char *banner = (char *) LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF; + int banner_len = sizeof(LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF) - 1; + ssize_t ret; +#ifdef LIBSSH2DEBUG + char banner_dup[256]; +#endif + + if (session->banner_TxRx_state == libssh2_NB_state_idle) { + if (session->local.banner) { + /* setopt_string will have given us our \r\n characters */ + banner_len = strlen((char *) session->local.banner); + banner = (char *) session->local.banner; + } +#ifdef LIBSSH2DEBUG + /* Hack and slash to avoid sending CRLF in debug output */ + if (banner_len < 256) { + memcpy(banner_dup, banner, banner_len - 2); + banner_dup[banner_len - 2] = '\0'; + } else { + memcpy(banner_dup, banner, 255); + banner[255] = '\0'; + } + + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Sending Banner: %s", + banner_dup); +#endif + + session->banner_TxRx_state = libssh2_NB_state_created; + } + + /* no outgoing block yet! */ + session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_OUTBOUND; + + ret = LIBSSH2_SEND(session, + banner + session->banner_TxRx_total_send, + banner_len - session->banner_TxRx_total_send, + LIBSSH2_SOCKET_SEND_FLAGS(session)); + if (ret < 0) + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Error sending %d bytes: %d", + banner_len - session->banner_TxRx_total_send, -ret); + else + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Sent %d/%d bytes at %p+%d", ret, + banner_len - session->banner_TxRx_total_send, + banner, session->banner_TxRx_total_send); + + if (ret != (banner_len - session->banner_TxRx_total_send)) { + if (ret >= 0 || ret == -EAGAIN) { + /* the whole packet could not be sent, save the what was */ + session->socket_block_directions = + LIBSSH2_SESSION_BLOCK_OUTBOUND; + if (ret > 0) + session->banner_TxRx_total_send += ret; + return LIBSSH2_ERROR_EAGAIN; + } + session->banner_TxRx_state = libssh2_NB_state_idle; + session->banner_TxRx_total_send = 0; + return LIBSSH2_ERROR_SOCKET_RECV; + } + + /* Set the state back to idle */ + session->banner_TxRx_state = libssh2_NB_state_idle; + session->banner_TxRx_total_send = 0; + + return 0; +} + +/* + * session_nonblock() sets the given socket to either blocking or + * non-blocking mode based on the 'nonblock' boolean argument. This function + * is copied from the libcurl sources with permission. + */ +static int +session_nonblock(libssh2_socket_t sockfd, /* operate on this */ + int nonblock /* TRUE or FALSE */ ) +{ +#undef SETBLOCK +#define SETBLOCK 0 +#ifdef HAVE_O_NONBLOCK + /* most recent unix versions */ + int flags; + + flags = fcntl(sockfd, F_GETFL, 0); + if (nonblock) + return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); + else + return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK)); +#undef SETBLOCK +#define SETBLOCK 1 +#endif + +#if defined(HAVE_FIONBIO) && (SETBLOCK == 0) + /* older unix versions and VMS*/ + int flags; + + flags = nonblock; + return ioctl(sockfd, FIONBIO, &flags); +#undef SETBLOCK +#define SETBLOCK 2 +#endif + +#if defined(HAVE_IOCTLSOCKET) && (SETBLOCK == 0) + /* Windows? */ + unsigned long flags; + flags = nonblock; + + return ioctlsocket(sockfd, FIONBIO, &flags); +#undef SETBLOCK +#define SETBLOCK 3 +#endif + +#if defined(HAVE_IOCTLSOCKET_CASE) && (SETBLOCK == 0) + /* presumably for Amiga */ + return IoctlSocket(sockfd, FIONBIO, (long) nonblock); +#undef SETBLOCK +#define SETBLOCK 4 +#endif + +#if defined(HAVE_SO_NONBLOCK) && (SETBLOCK == 0) + /* BeOS */ + long b = nonblock ? 1 : 0; + return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b)); +#undef SETBLOCK +#define SETBLOCK 5 +#endif + +#ifdef HAVE_DISABLED_NONBLOCKING + return 0; /* returns success */ +#undef SETBLOCK +#define SETBLOCK 6 +#endif + +#if (SETBLOCK == 0) +#error "no non-blocking method was found/used/set" +#endif +} + +/* + * get_socket_nonblocking() + * + * gets the given blocking or non-blocking state of the socket. + */ +static int +get_socket_nonblocking(int sockfd) +{ /* operate on this */ +#undef GETBLOCK +#define GETBLOCK 0 +#ifdef HAVE_O_NONBLOCK + /* most recent unix versions */ + int flags; + + if ((flags = fcntl(sockfd, F_GETFL, 0)) == -1) { + /* Assume blocking on error */ + return 1; + } + return (flags & O_NONBLOCK); +#undef GETBLOCK +#define GETBLOCK 1 +#endif + +#if defined(WSAEWOULDBLOCK) && (GETBLOCK == 0) + /* Windows? */ + unsigned int option_value; + socklen_t option_len = sizeof(option_value); + + if (getsockopt + (sockfd, SOL_SOCKET, SO_ERROR, (void *) &option_value, &option_len)) { + /* Assume blocking on error */ + return 1; + } + return (int) option_value; +#undef GETBLOCK +#define GETBLOCK 2 +#endif + +#if defined(HAVE_SO_NONBLOCK) && (GETBLOCK == 0) + /* BeOS */ + long b; + if (getsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b))) { + /* Assume blocking on error */ + return 1; + } + return (int) b; +#undef GETBLOCK +#define GETBLOCK 5 +#endif + +#if defined(SO_STATE) && defined( __VMS ) && (GETBLOCK == 0) + + /* VMS TCP/IP Services */ + + size_t sockstat = 0; + int callstat = 0; + size_t size = sizeof( int ); + + callstat = getsockopt(sockfd, SOL_SOCKET, SO_STATE, + (char *)&sockstat, &size); + if ( callstat == -1 ) return(0); + if ( (sockstat&SS_NBIO) )return(1); + return(0); + +#undef GETBLOCK +#define GETBLOCK 6 +#endif + +#ifdef HAVE_DISABLED_NONBLOCKING + return 1; /* returns blocking */ +#undef GETBLOCK +#define GETBLOCK 7 +#endif + +#if (GETBLOCK == 0) +#error "no non-blocking method was found/used/get" +#endif +} + +/* libssh2_session_banner_set + * Set the local banner to use in the server handshake. + */ +LIBSSH2_API int +libssh2_session_banner_set(LIBSSH2_SESSION * session, const char *banner) +{ + size_t banner_len = banner ? strlen(banner) : 0; + + if (session->local.banner) { + LIBSSH2_FREE(session, session->local.banner); + session->local.banner = NULL; + } + + if (!banner_len) + return 0; + + session->local.banner = LIBSSH2_ALLOC(session, banner_len + 3); + if (!session->local.banner) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for local banner"); + } + + memcpy(session->local.banner, banner, banner_len); + + /* first zero terminate like this so that the debug output is nice */ + session->local.banner[banner_len] = '\0'; + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Setting local Banner: %s", + session->local.banner); + session->local.banner[banner_len++] = '\r'; + session->local.banner[banner_len++] = '\n'; + session->local.banner[banner_len] = '\0'; + + return 0; +} + +/* libssh2_banner_set + * Set the local banner. DEPRECATED VERSION + */ +LIBSSH2_API int +libssh2_banner_set(LIBSSH2_SESSION * session, const char *banner) +{ + return libssh2_session_banner_set(session, banner); +} + +/* + * libssh2_session_init_ex + * + * Allocate and initialize a libssh2 session structure. Allows for malloc + * callbacks in case the calling program has its own memory manager It's + * allowable (but unadvisable) to define some but not all of the malloc + * callbacks An additional pointer value may be optionally passed to be sent + * to the callbacks (so they know who's asking) + */ +LIBSSH2_API LIBSSH2_SESSION * +libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)), + LIBSSH2_FREE_FUNC((*my_free)), + LIBSSH2_REALLOC_FUNC((*my_realloc)), void *abstract) +{ + LIBSSH2_ALLOC_FUNC((*local_alloc)) = libssh2_default_alloc; + LIBSSH2_FREE_FUNC((*local_free)) = libssh2_default_free; + LIBSSH2_REALLOC_FUNC((*local_realloc)) = libssh2_default_realloc; + LIBSSH2_SESSION *session; + + if (my_alloc) { + local_alloc = my_alloc; + } + if (my_free) { + local_free = my_free; + } + if (my_realloc) { + local_realloc = my_realloc; + } + + session = local_alloc(sizeof(LIBSSH2_SESSION), &abstract); + if (session) { + memset(session, 0, sizeof(LIBSSH2_SESSION)); + session->alloc = local_alloc; + session->free = local_free; + session->realloc = local_realloc; + session->send = _libssh2_send; + session->recv = _libssh2_recv; + session->abstract = abstract; + session->api_timeout = 0; /* timeout-free API by default */ + session->api_block_mode = 1; /* blocking API by default */ + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "New session resource allocated"); + _libssh2_init_if_needed (); + } + return session; +} + +/* + * libssh2_session_callback_set + * + * Set (or reset) a callback function + * Returns the prior address + * + * FIXME: this function relies on that we can typecast function pointers + * to void pointers, which isn't allowed in ISO C! + */ +LIBSSH2_API void * +libssh2_session_callback_set(LIBSSH2_SESSION * session, + int cbtype, void *callback) +{ + void *oldcb; + + switch (cbtype) { + case LIBSSH2_CALLBACK_IGNORE: + oldcb = session->ssh_msg_ignore; + session->ssh_msg_ignore = callback; + return oldcb; + + case LIBSSH2_CALLBACK_DEBUG: + oldcb = session->ssh_msg_debug; + session->ssh_msg_debug = callback; + return oldcb; + + case LIBSSH2_CALLBACK_DISCONNECT: + oldcb = session->ssh_msg_disconnect; + session->ssh_msg_disconnect = callback; + return oldcb; + + case LIBSSH2_CALLBACK_MACERROR: + oldcb = session->macerror; + session->macerror = callback; + return oldcb; + + case LIBSSH2_CALLBACK_X11: + oldcb = session->x11; + session->x11 = callback; + return oldcb; + + case LIBSSH2_CALLBACK_SEND: + oldcb = session->send; + session->send = callback; + return oldcb; + + case LIBSSH2_CALLBACK_RECV: + oldcb = session->recv; + session->recv = callback; + return oldcb; + } + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Setting Callback %d", cbtype); + + return NULL; +} + +/* + * _libssh2_wait_socket() + * + * Utility function that waits for action on the socket. Returns 0 when ready + * to run again or error on timeout. + */ +int _libssh2_wait_socket(LIBSSH2_SESSION *session, time_t start_time) +{ + int rc; + int seconds_to_next; + int dir; + int has_timeout; + long ms_to_next = 0; + long elapsed_ms; + + /* since libssh2 often sets EAGAIN internally before this function is + called, we can decrease some amount of confusion in user programs by + resetting the error code in this function to reduce the risk of EAGAIN + being stored as error when a blocking function has returned */ + session->err_code = LIBSSH2_ERROR_NONE; + + rc = libssh2_keepalive_send (session, &seconds_to_next); + if (rc < 0) + return rc; + + ms_to_next = seconds_to_next * 1000; + + /* figure out what to wait for */ + dir = libssh2_session_block_directions(session); + + if(!dir) { + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Nothing to wait for in wait_socket"); + /* To avoid that we hang below just because there's nothing set to + wait for, we timeout on 1 second to also avoid busy-looping + during this condition */ + ms_to_next = 1000; + } + + if (session->api_timeout > 0 && + (seconds_to_next == 0 || + seconds_to_next > session->api_timeout)) { + time_t now = time (NULL); + elapsed_ms = (long)(1000*difftime(now, start_time)); + if (elapsed_ms > session->api_timeout) { + session->err_code = LIBSSH2_ERROR_TIMEOUT; + return LIBSSH2_ERROR_TIMEOUT; + } + ms_to_next = (session->api_timeout - elapsed_ms); + has_timeout = 1; + } + else if (ms_to_next > 0) { + has_timeout = 1; + } + else + has_timeout = 0; + +#ifdef HAVE_POLL + { + struct pollfd sockets[1]; + + sockets[0].fd = session->socket_fd; + sockets[0].events = 0; + sockets[0].revents = 0; + + if(dir & LIBSSH2_SESSION_BLOCK_INBOUND) + sockets[0].events |= POLLIN; + + if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND) + sockets[0].events |= POLLOUT; + + rc = poll(sockets, 1, has_timeout?ms_to_next: -1); + } +#else + { + fd_set rfd; + fd_set wfd; + fd_set *writefd = NULL; + fd_set *readfd = NULL; + struct timeval tv; + + tv.tv_sec = ms_to_next / 1000; + tv.tv_usec = (ms_to_next - tv.tv_sec*1000) * 1000; + + if(dir & LIBSSH2_SESSION_BLOCK_INBOUND) { + FD_ZERO(&rfd); + FD_SET(session->socket_fd, &rfd); + readfd = &rfd; + } + + if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND) { + FD_ZERO(&wfd); + FD_SET(session->socket_fd, &wfd); + writefd = &wfd; + } + + rc = select(session->socket_fd + 1, readfd, writefd, NULL, + has_timeout ? &tv : NULL); + } +#endif + if(rc <= 0) { + /* timeout (or error), bail out with a timeout error */ + session->err_code = LIBSSH2_ERROR_TIMEOUT; + return LIBSSH2_ERROR_TIMEOUT; + } + + return 0; /* ready to try again */ +} + +static int +session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock) +{ + int rc; + + if (session->startup_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "session_startup for socket %d", sock); + if (LIBSSH2_INVALID_SOCKET == sock) { + /* Did we forget something? */ + return _libssh2_error(session, LIBSSH2_ERROR_BAD_SOCKET, + "Bad socket provided"); + } + session->socket_fd = sock; + + session->socket_prev_blockstate = + !get_socket_nonblocking(session->socket_fd); + + if (session->socket_prev_blockstate) { + /* If in blocking state change to non-blocking */ + rc = session_nonblock(session->socket_fd, 1); + if (rc) { + return _libssh2_error(session, rc, + "Failed changing socket's " + "blocking state to non-blocking"); + } + } + + session->startup_state = libssh2_NB_state_created; + } + + if (session->startup_state == libssh2_NB_state_created) { + rc = banner_send(session); + if (rc) { + return _libssh2_error(session, rc, + "Failed sending banner"); + } + session->startup_state = libssh2_NB_state_sent; + session->banner_TxRx_state = libssh2_NB_state_idle; + } + + if (session->startup_state == libssh2_NB_state_sent) { + do { + rc = banner_receive(session); + if (rc) + return _libssh2_error(session, rc, + "Failed getting banner"); + } while(strncmp("SSH-", (char *)session->remote.banner, 4)); + + session->startup_state = libssh2_NB_state_sent1; + } + + if (session->startup_state == libssh2_NB_state_sent1) { + rc = _libssh2_kex_exchange(session, 0, &session->startup_key_state); + if (rc) + return _libssh2_error(session, rc, + "Unable to exchange encryption keys"); + + session->startup_state = libssh2_NB_state_sent2; + } + + if (session->startup_state == libssh2_NB_state_sent2) { + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "Requesting userauth service"); + + /* Request the userauth service */ + session->startup_service[0] = SSH_MSG_SERVICE_REQUEST; + _libssh2_htonu32(session->startup_service + 1, + sizeof("ssh-userauth") - 1); + memcpy(session->startup_service + 5, "ssh-userauth", + sizeof("ssh-userauth") - 1); + + session->startup_state = libssh2_NB_state_sent3; + } + + if (session->startup_state == libssh2_NB_state_sent3) { + rc = _libssh2_transport_send(session, session->startup_service, + sizeof("ssh-userauth") + 5 - 1, + NULL, 0); + if (rc) { + return _libssh2_error(session, rc, + "Unable to ask for ssh-userauth service"); + } + + session->startup_state = libssh2_NB_state_sent4; + } + + if (session->startup_state == libssh2_NB_state_sent4) { + rc = _libssh2_packet_require(session, SSH_MSG_SERVICE_ACCEPT, + &session->startup_data, + &session->startup_data_len, 0, NULL, 0, + &session->startup_req_state); + if (rc) + return rc; + + session->startup_service_length = + _libssh2_ntohu32(session->startup_data + 1); + + if ((session->startup_service_length != (sizeof("ssh-userauth") - 1)) + || strncmp("ssh-userauth", (char *) session->startup_data + 5, + session->startup_service_length)) { + LIBSSH2_FREE(session, session->startup_data); + session->startup_data = NULL; + return _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Invalid response received from server"); + } + LIBSSH2_FREE(session, session->startup_data); + session->startup_data = NULL; + + session->startup_state = libssh2_NB_state_idle; + + return 0; + } + + /* just for safety return some error */ + return LIBSSH2_ERROR_INVAL; +} + +/* + * libssh2_session_handshake() + * + * session: LIBSSH2_SESSION struct allocated and owned by the calling program + * sock: *must* be populated with an opened and connected socket. + * + * Returns: 0 on success, or non-zero on failure + */ +LIBSSH2_API int +libssh2_session_handshake(LIBSSH2_SESSION *session, libssh2_socket_t sock) +{ + int rc; + + BLOCK_ADJUST(rc, session, session_startup(session, sock) ); + + return rc; +} + +/* + * libssh2_session_startup() + * + * DEPRECATED. Use libssh2_session_handshake() instead! This function is not + * portable enough. + * + * session: LIBSSH2_SESSION struct allocated and owned by the calling program + * sock: *must* be populated with an opened and connected socket. + * + * Returns: 0 on success, or non-zero on failure + */ +LIBSSH2_API int +libssh2_session_startup(LIBSSH2_SESSION *session, int sock) +{ + return libssh2_session_handshake(session, (libssh2_socket_t) sock); +} + +/* + * libssh2_session_free + * + * Frees the memory allocated to the session + * Also closes and frees any channels attached to this session + */ +static int +session_free(LIBSSH2_SESSION *session) +{ + int rc; + LIBSSH2_PACKET *pkg; + LIBSSH2_CHANNEL *ch; + LIBSSH2_LISTENER *l; + int packets_left = 0; + + if (session->free_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Freeing session resource", + session->remote.banner); + + session->free_state = libssh2_NB_state_created; + } + + if (session->free_state == libssh2_NB_state_created) { + while ((ch = _libssh2_list_first(&session->channels))) { + + rc = _libssh2_channel_free(ch); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + } + + session->free_state = libssh2_NB_state_sent; + } + + if (session->free_state == libssh2_NB_state_sent) { + while ((l = _libssh2_list_first(&session->listeners))) { + rc = _libssh2_channel_forward_cancel(l); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + } + + session->free_state = libssh2_NB_state_sent1; + } + + if (session->state & LIBSSH2_STATE_NEWKEYS) { + /* hostkey */ + if (session->hostkey && session->hostkey->dtor) { + session->hostkey->dtor(session, &session->server_hostkey_abstract); + } + + /* Client to Server */ + /* crypt */ + if (session->local.crypt && session->local.crypt->dtor) { + session->local.crypt->dtor(session, + &session->local.crypt_abstract); + } + /* comp */ + if (session->local.comp && session->local.comp->dtor) { + session->local.comp->dtor(session, 1, + &session->local.comp_abstract); + } + /* mac */ + if (session->local.mac && session->local.mac->dtor) { + session->local.mac->dtor(session, &session->local.mac_abstract); + } + + /* Server to Client */ + /* crypt */ + if (session->remote.crypt && session->remote.crypt->dtor) { + session->remote.crypt->dtor(session, + &session->remote.crypt_abstract); + } + /* comp */ + if (session->remote.comp && session->remote.comp->dtor) { + session->remote.comp->dtor(session, 0, + &session->remote.comp_abstract); + } + /* mac */ + if (session->remote.mac && session->remote.mac->dtor) { + session->remote.mac->dtor(session, &session->remote.mac_abstract); + } + + /* session_id */ + if (session->session_id) { + LIBSSH2_FREE(session, session->session_id); + } + } + + /* Free banner(s) */ + if (session->remote.banner) { + LIBSSH2_FREE(session, session->remote.banner); + } + if (session->local.banner) { + LIBSSH2_FREE(session, session->local.banner); + } + + /* Free preference(s) */ + if (session->kex_prefs) { + LIBSSH2_FREE(session, session->kex_prefs); + } + if (session->hostkey_prefs) { + LIBSSH2_FREE(session, session->hostkey_prefs); + } + + if (session->local.kexinit) { + LIBSSH2_FREE(session, session->local.kexinit); + } + if (session->local.crypt_prefs) { + LIBSSH2_FREE(session, session->local.crypt_prefs); + } + if (session->local.mac_prefs) { + LIBSSH2_FREE(session, session->local.mac_prefs); + } + if (session->local.comp_prefs) { + LIBSSH2_FREE(session, session->local.comp_prefs); + } + if (session->local.lang_prefs) { + LIBSSH2_FREE(session, session->local.lang_prefs); + } + + if (session->remote.kexinit) { + LIBSSH2_FREE(session, session->remote.kexinit); + } + if (session->remote.crypt_prefs) { + LIBSSH2_FREE(session, session->remote.crypt_prefs); + } + if (session->remote.mac_prefs) { + LIBSSH2_FREE(session, session->remote.mac_prefs); + } + if (session->remote.comp_prefs) { + LIBSSH2_FREE(session, session->remote.comp_prefs); + } + if (session->remote.lang_prefs) { + LIBSSH2_FREE(session, session->remote.lang_prefs); + } + + /* + * Make sure all memory used in the state variables are free + */ + if (session->kexinit_data) { + LIBSSH2_FREE(session, session->kexinit_data); + } + if (session->startup_data) { + LIBSSH2_FREE(session, session->startup_data); + } + if (session->userauth_list_data) { + LIBSSH2_FREE(session, session->userauth_list_data); + } + if (session->userauth_pswd_data) { + LIBSSH2_FREE(session, session->userauth_pswd_data); + } + if (session->userauth_pswd_newpw) { + LIBSSH2_FREE(session, session->userauth_pswd_newpw); + } + if (session->userauth_host_packet) { + LIBSSH2_FREE(session, session->userauth_host_packet); + } + if (session->userauth_host_method) { + LIBSSH2_FREE(session, session->userauth_host_method); + } + if (session->userauth_host_data) { + LIBSSH2_FREE(session, session->userauth_host_data); + } + if (session->userauth_pblc_data) { + LIBSSH2_FREE(session, session->userauth_pblc_data); + } + if (session->userauth_pblc_packet) { + LIBSSH2_FREE(session, session->userauth_pblc_packet); + } + if (session->userauth_pblc_method) { + LIBSSH2_FREE(session, session->userauth_pblc_method); + } + if (session->userauth_kybd_data) { + LIBSSH2_FREE(session, session->userauth_kybd_data); + } + if (session->userauth_kybd_packet) { + LIBSSH2_FREE(session, session->userauth_kybd_packet); + } + if (session->userauth_kybd_auth_instruction) { + LIBSSH2_FREE(session, session->userauth_kybd_auth_instruction); + } + if (session->open_packet) { + LIBSSH2_FREE(session, session->open_packet); + } + if (session->open_data) { + LIBSSH2_FREE(session, session->open_data); + } + if (session->direct_message) { + LIBSSH2_FREE(session, session->direct_message); + } + if (session->fwdLstn_packet) { + LIBSSH2_FREE(session, session->fwdLstn_packet); + } + if (session->pkeyInit_data) { + LIBSSH2_FREE(session, session->pkeyInit_data); + } + if (session->scpRecv_command) { + LIBSSH2_FREE(session, session->scpRecv_command); + } + if (session->scpSend_command) { + LIBSSH2_FREE(session, session->scpSend_command); + } + if (session->sftpInit_sftp) { + LIBSSH2_FREE(session, session->sftpInit_sftp); + } + + /* Free payload buffer */ + if (session->packet.total_num) { + LIBSSH2_FREE(session, session->packet.payload); + } + + /* Cleanup all remaining packets */ + while ((pkg = _libssh2_list_first(&session->packets))) { + packets_left++; + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "packet left with id %d", pkg->data[0]); + /* unlink the node */ + _libssh2_list_remove(&pkg->node); + + /* free */ + LIBSSH2_FREE(session, pkg->data); + LIBSSH2_FREE(session, pkg); + } + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "Extra packets left %d", packets_left); + + if(session->socket_prev_blockstate) { + /* if the socket was previously blocking, put it back so */ + rc = session_nonblock(session->socket_fd, 0); + if (rc) { + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "unable to reset socket's blocking state"); + } + } + + if (session->server_hostkey) { + LIBSSH2_FREE(session, session->server_hostkey); + } + + /* error string */ + if (session->err_msg && ((session->err_flags & LIBSSH2_ERR_FLAG_DUP) != 0)) { + LIBSSH2_FREE(session, (char *)session->err_msg); + } + + LIBSSH2_FREE(session, session); + + return 0; +} + +/* + * libssh2_session_free + * + * Frees the memory allocated to the session + * Also closes and frees any channels attached to this session + */ +LIBSSH2_API int +libssh2_session_free(LIBSSH2_SESSION * session) +{ + int rc; + + BLOCK_ADJUST(rc, session, session_free(session) ); + + return rc; +} + +/* + * libssh2_session_disconnect_ex + */ +static int +session_disconnect(LIBSSH2_SESSION *session, int reason, + const char *description, + const char *lang) +{ + unsigned char *s; + unsigned long descr_len = 0, lang_len = 0; + int rc; + + if (session->disconnect_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "Disconnecting: reason=%d, desc=%s, lang=%s", reason, + description, lang); + if (description) + descr_len = strlen(description); + + if (lang) + lang_len = strlen(lang); + + if(descr_len > 256) + return _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "too long description"); + + /* 13 = packet_type(1) + reason code(4) + descr_len(4) + lang_len(4) */ + session->disconnect_data_len = descr_len + lang_len + 13; + + s = session->disconnect_data; + + *(s++) = SSH_MSG_DISCONNECT; + _libssh2_store_u32(&s, reason); + _libssh2_store_str(&s, description, descr_len); + /* store length only, lang is sent separately */ + _libssh2_store_u32(&s, lang_len); + + session->disconnect_state = libssh2_NB_state_created; + } + + rc = _libssh2_transport_send(session, session->disconnect_data, + session->disconnect_data_len, + (unsigned char *)lang, lang_len); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + + session->disconnect_state = libssh2_NB_state_idle; + + return 0; +} + +/* + * libssh2_session_disconnect_ex + */ +LIBSSH2_API int +libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason, + const char *desc, const char *lang) +{ + int rc; + + BLOCK_ADJUST(rc, session, + session_disconnect(session, reason, desc, lang)); + + return rc; +} + +/* libssh2_session_methods + * + * Return the currently active methods for method_type + * + * NOTE: Currently lang_cs and lang_sc are ALWAYS set to empty string + * regardless of actual negotiation Strings should NOT be freed + */ +LIBSSH2_API const char * +libssh2_session_methods(LIBSSH2_SESSION * session, int method_type) +{ + /* All methods have char *name as their first element */ + const LIBSSH2_KEX_METHOD *method = NULL; + + switch (method_type) { + case LIBSSH2_METHOD_KEX: + method = session->kex; + break; + + case LIBSSH2_METHOD_HOSTKEY: + method = (LIBSSH2_KEX_METHOD *) session->hostkey; + break; + + case LIBSSH2_METHOD_CRYPT_CS: + method = (LIBSSH2_KEX_METHOD *) session->local.crypt; + break; + + case LIBSSH2_METHOD_CRYPT_SC: + method = (LIBSSH2_KEX_METHOD *) session->remote.crypt; + break; + + case LIBSSH2_METHOD_MAC_CS: + method = (LIBSSH2_KEX_METHOD *) session->local.mac; + break; + + case LIBSSH2_METHOD_MAC_SC: + method = (LIBSSH2_KEX_METHOD *) session->remote.mac; + break; + + case LIBSSH2_METHOD_COMP_CS: + method = (LIBSSH2_KEX_METHOD *) session->local.comp; + break; + + case LIBSSH2_METHOD_COMP_SC: + method = (LIBSSH2_KEX_METHOD *) session->remote.comp; + break; + + case LIBSSH2_METHOD_LANG_CS: + return ""; + + case LIBSSH2_METHOD_LANG_SC: + return ""; + + default: + _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "Invalid parameter specified for method_type"); + return NULL; + } + + if (!method) { + _libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE, + "No method negotiated"); + return NULL; + } + + return method->name; +} + +/* libssh2_session_abstract + * Retrieve a pointer to the abstract property + */ +LIBSSH2_API void ** +libssh2_session_abstract(LIBSSH2_SESSION * session) +{ + return &session->abstract; +} + +/* libssh2_session_last_error + * + * Returns error code and populates an error string into errmsg If want_buf is + * non-zero then the string placed into errmsg must be freed by the calling + * program. Otherwise it is assumed to be owned by libssh2 + */ +LIBSSH2_API int +libssh2_session_last_error(LIBSSH2_SESSION * session, char **errmsg, + int *errmsg_len, int want_buf) +{ + size_t msglen = 0; + + /* No error to report */ + if (!session->err_code) { + if (errmsg) { + if (want_buf) { + *errmsg = LIBSSH2_ALLOC(session, 1); + if (*errmsg) { + **errmsg = 0; + } + } else { + *errmsg = (char *) ""; + } + } + if (errmsg_len) { + *errmsg_len = 0; + } + return 0; + } + + if (errmsg) { + const char *error = session->err_msg ? session->err_msg : ""; + + msglen = strlen(error); + + if (want_buf) { + /* Make a copy so the calling program can own it */ + *errmsg = LIBSSH2_ALLOC(session, msglen + 1); + if (*errmsg) { + memcpy(*errmsg, error, msglen); + (*errmsg)[msglen] = 0; + } + } + else + *errmsg = (char *)error; + } + + if (errmsg_len) { + *errmsg_len = msglen; + } + + return session->err_code; +} + +/* libssh2_session_last_errno + * + * Returns error code + */ +LIBSSH2_API int +libssh2_session_last_errno(LIBSSH2_SESSION * session) +{ + return session->err_code; +} + +/* libssh2_session_set_last_error + * + * Sets the internal error code for the session. + * + * This function is available specifically to be used by high level + * language wrappers (i.e. Python or Perl) that may extend the library + * features while still relying on its error reporting mechanism. + */ +LIBSSH2_API int +libssh2_session_set_last_error(LIBSSH2_SESSION* session, + int errcode, + const char* errmsg) +{ + return _libssh2_error_flags(session, errcode, errmsg, + LIBSSH2_ERR_FLAG_DUP); +} + +/* Libssh2_session_flag + * + * Set/Get session flags + * + * Return error code. + */ +LIBSSH2_API int +libssh2_session_flag(LIBSSH2_SESSION * session, int flag, int value) +{ + switch(flag) { + case LIBSSH2_FLAG_SIGPIPE: + session->flag.sigpipe = value; + break; + case LIBSSH2_FLAG_COMPRESS: + session->flag.compress = value; + break; + default: + /* unknown flag */ + return LIBSSH2_ERROR_INVAL; + } + + return LIBSSH2_ERROR_NONE; +} + +/* _libssh2_session_set_blocking + * + * Set a session's blocking mode on or off, return the previous status when + * this function is called. Note this function does not alter the state of the + * actual socket involved. + */ +int +_libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking) +{ + int bl = session->api_block_mode; + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Setting blocking mode %s", blocking?"ON":"OFF"); + session->api_block_mode = blocking; + + return bl; +} + +/* libssh2_session_set_blocking + * + * Set a channel's blocking mode on or off, similar to a socket's + * fcntl(fd, F_SETFL, O_NONBLOCK); type command + */ +LIBSSH2_API void +libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking) +{ + (void) _libssh2_session_set_blocking(session, blocking); +} + +/* libssh2_session_get_blocking + * + * Returns a session's blocking mode on or off + */ +LIBSSH2_API int +libssh2_session_get_blocking(LIBSSH2_SESSION * session) +{ + return session->api_block_mode; +} + + +/* libssh2_session_set_timeout + * + * Set a session's timeout (in msec) for blocking mode, + * or 0 to disable timeouts. + */ +LIBSSH2_API void +libssh2_session_set_timeout(LIBSSH2_SESSION * session, long timeout) +{ + session->api_timeout = timeout; +} + +/* libssh2_session_get_timeout + * + * Returns a session's timeout, or 0 if disabled + */ +LIBSSH2_API long +libssh2_session_get_timeout(LIBSSH2_SESSION * session) +{ + return session->api_timeout; +} + +/* + * libssh2_poll_channel_read + * + * Returns 0 if no data is waiting on channel, + * non-0 if data is available + */ +LIBSSH2_API int +libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended) +{ + LIBSSH2_SESSION *session; + LIBSSH2_PACKET *packet; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + session = channel->session; + packet = _libssh2_list_first(&session->packets); + + while (packet) { + if ( channel->local.id == _libssh2_ntohu32(packet->data + 1)) { + if ( extended == 1 && + (packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA + || packet->data[0] == SSH_MSG_CHANNEL_DATA )) { + return 1; + } else if ( extended == 0 && + packet->data[0] == SSH_MSG_CHANNEL_DATA) { + return 1; + } + /* else - no data of any type is ready to be read */ + } + packet = _libssh2_list_next(&packet->node); + } + + return 0; +} + +/* + * poll_channel_write + * + * Returns 0 if writing to channel would block, + * non-0 if data can be written without blocking + */ +static inline int +poll_channel_write(LIBSSH2_CHANNEL * channel) +{ + return channel->local.window_size ? 1 : 0; +} + +/* poll_listener_queued + * + * Returns 0 if no connections are waiting to be accepted + * non-0 if one or more connections are available + */ +static inline int +poll_listener_queued(LIBSSH2_LISTENER * listener) +{ + return _libssh2_list_first(&listener->queue) ? 1 : 0; +} + +/* + * libssh2_poll + * + * Poll sockets, channels, and listeners for activity + */ +LIBSSH2_API int +libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout) +{ + long timeout_remaining; + unsigned int i, active_fds; +#ifdef HAVE_POLL + LIBSSH2_SESSION *session = NULL; +#ifdef HAVE_ALLOCA + struct pollfd *sockets = alloca(sizeof(struct pollfd) * nfds); +#else + struct pollfd sockets[256]; + + if (nfds > 256) + /* systems without alloca use a fixed-size array, this can be fixed if + we really want to, at least if the compiler is a C99 capable one */ + return -1; +#endif + /* Setup sockets for polling */ + for(i = 0; i < nfds; i++) { + fds[i].revents = 0; + switch (fds[i].type) { + case LIBSSH2_POLLFD_SOCKET: + sockets[i].fd = fds[i].fd.socket; + sockets[i].events = fds[i].events; + sockets[i].revents = 0; + break; + + case LIBSSH2_POLLFD_CHANNEL: + sockets[i].fd = fds[i].fd.channel->session->socket_fd; + sockets[i].events = POLLIN; + sockets[i].revents = 0; + if (!session) + session = fds[i].fd.channel->session; + break; + + case LIBSSH2_POLLFD_LISTENER: + sockets[i].fd = fds[i].fd.listener->session->socket_fd; + sockets[i].events = POLLIN; + sockets[i].revents = 0; + if (!session) + session = fds[i].fd.listener->session; + break; + + default: + if (session) + _libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE, + "Invalid descriptor passed to libssh2_poll()"); + return -1; + } + } +#elif defined(HAVE_SELECT) + LIBSSH2_SESSION *session = NULL; + libssh2_socket_t maxfd = 0; + fd_set rfds, wfds; + struct timeval tv; + + FD_ZERO(&rfds); + FD_ZERO(&wfds); + for(i = 0; i < nfds; i++) { + fds[i].revents = 0; + switch (fds[i].type) { + case LIBSSH2_POLLFD_SOCKET: + if (fds[i].events & LIBSSH2_POLLFD_POLLIN) { + FD_SET(fds[i].fd.socket, &rfds); + if (fds[i].fd.socket > maxfd) + maxfd = fds[i].fd.socket; + } + if (fds[i].events & LIBSSH2_POLLFD_POLLOUT) { + FD_SET(fds[i].fd.socket, &wfds); + if (fds[i].fd.socket > maxfd) + maxfd = fds[i].fd.socket; + } + break; + + case LIBSSH2_POLLFD_CHANNEL: + FD_SET(fds[i].fd.channel->session->socket_fd, &rfds); + if (fds[i].fd.channel->session->socket_fd > maxfd) + maxfd = fds[i].fd.channel->session->socket_fd; + if (!session) + session = fds[i].fd.channel->session; + break; + + case LIBSSH2_POLLFD_LISTENER: + FD_SET(fds[i].fd.listener->session->socket_fd, &rfds); + if (fds[i].fd.listener->session->socket_fd > maxfd) + maxfd = fds[i].fd.listener->session->socket_fd; + if (!session) + session = fds[i].fd.listener->session; + break; + + default: + if (session) + _libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE, + "Invalid descriptor passed to libssh2_poll()"); + return -1; + } + } +#else + /* No select() or poll() + * no sockets structure to setup + */ + + timeout = 0; +#endif /* HAVE_POLL or HAVE_SELECT */ + + timeout_remaining = timeout; + do { +#if defined(HAVE_POLL) || defined(HAVE_SELECT) + int sysret; +#endif + + active_fds = 0; + + for(i = 0; i < nfds; i++) { + if (fds[i].events != fds[i].revents) { + switch (fds[i].type) { + case LIBSSH2_POLLFD_CHANNEL: + if ((fds[i].events & LIBSSH2_POLLFD_POLLIN) && + /* Want to be ready for read */ + ((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) { + /* Not yet known to be ready for read */ + fds[i].revents |= + libssh2_poll_channel_read(fds[i].fd.channel, + 0) ? + LIBSSH2_POLLFD_POLLIN : 0; + } + if ((fds[i].events & LIBSSH2_POLLFD_POLLEXT) && + /* Want to be ready for extended read */ + ((fds[i].revents & LIBSSH2_POLLFD_POLLEXT) == 0)) { + /* Not yet known to be ready for extended read */ + fds[i].revents |= + libssh2_poll_channel_read(fds[i].fd.channel, + 1) ? + LIBSSH2_POLLFD_POLLEXT : 0; + } + if ((fds[i].events & LIBSSH2_POLLFD_POLLOUT) && + /* Want to be ready for write */ + ((fds[i].revents & LIBSSH2_POLLFD_POLLOUT) == 0)) { + /* Not yet known to be ready for write */ + fds[i].revents |= + poll_channel_write(fds[i].fd. channel) ? + LIBSSH2_POLLFD_POLLOUT : 0; + } + if (fds[i].fd.channel->remote.close + || fds[i].fd.channel->local.close) { + fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED; + } + if (fds[i].fd.channel->session->socket_state == + LIBSSH2_SOCKET_DISCONNECTED) { + fds[i].revents |= + LIBSSH2_POLLFD_CHANNEL_CLOSED | + LIBSSH2_POLLFD_SESSION_CLOSED; + } + break; + + case LIBSSH2_POLLFD_LISTENER: + if ((fds[i].events & LIBSSH2_POLLFD_POLLIN) && + /* Want a connection */ + ((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) { + /* No connections known of yet */ + fds[i].revents |= + poll_listener_queued(fds[i].fd. listener) ? + LIBSSH2_POLLFD_POLLIN : 0; + } + if (fds[i].fd.listener->session->socket_state == + LIBSSH2_SOCKET_DISCONNECTED) { + fds[i].revents |= + LIBSSH2_POLLFD_LISTENER_CLOSED | + LIBSSH2_POLLFD_SESSION_CLOSED; + } + break; + } + } + if (fds[i].revents) { + active_fds++; + } + } + + if (active_fds) { + /* Don't block on the sockets if we have channels/listeners which + are ready */ + timeout_remaining = 0; + } +#ifdef HAVE_POLL + +#ifdef HAVE_LIBSSH2_GETTIMEOFDAY + { + struct timeval tv_begin, tv_end; + + _libssh2_gettimeofday((struct timeval *) &tv_begin, NULL); + sysret = poll(sockets, nfds, timeout_remaining); + _libssh2_gettimeofday((struct timeval *) &tv_end, NULL); + timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000; + timeout_remaining -= (tv_end.tv_usec - tv_begin.tv_usec) / 1000; + } +#else + /* If the platform doesn't support gettimeofday, + * then just make the call non-blocking and walk away + */ + sysret = poll(sockets, nfds, timeout_remaining); + timeout_remaining = 0; +#endif /* HAVE_GETTIMEOFDAY */ + + if (sysret > 0) { + for(i = 0; i < nfds; i++) { + switch (fds[i].type) { + case LIBSSH2_POLLFD_SOCKET: + fds[i].revents = sockets[i].revents; + sockets[i].revents = 0; /* In case we loop again, be nice */ + if (fds[i].revents) { + active_fds++; + } + break; + case LIBSSH2_POLLFD_CHANNEL: + if (sockets[i].events & POLLIN) { + /* Spin session until no data available */ + while (_libssh2_transport_read(fds[i].fd.channel->session) + > 0); + } + if (sockets[i].revents & POLLHUP) { + fds[i].revents |= + LIBSSH2_POLLFD_CHANNEL_CLOSED | + LIBSSH2_POLLFD_SESSION_CLOSED; + } + sockets[i].revents = 0; + break; + case LIBSSH2_POLLFD_LISTENER: + if (sockets[i].events & POLLIN) { + /* Spin session until no data available */ + while (_libssh2_transport_read(fds[i].fd.listener->session) + > 0); + } + if (sockets[i].revents & POLLHUP) { + fds[i].revents |= + LIBSSH2_POLLFD_LISTENER_CLOSED | + LIBSSH2_POLLFD_SESSION_CLOSED; + } + sockets[i].revents = 0; + break; + } + } + } +#elif defined(HAVE_SELECT) + tv.tv_sec = timeout_remaining / 1000; + tv.tv_usec = (timeout_remaining % 1000) * 1000; +#ifdef HAVE_LIBSSH2_GETTIMEOFDAY + { + struct timeval tv_begin, tv_end; + + _libssh2_gettimeofday((struct timeval *) &tv_begin, NULL); + sysret = select(maxfd+1, &rfds, &wfds, NULL, &tv); + _libssh2_gettimeofday((struct timeval *) &tv_end, NULL); + + timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000; + timeout_remaining -= (tv_end.tv_usec - tv_begin.tv_usec) / 1000; + } +#else + /* If the platform doesn't support gettimeofday, + * then just make the call non-blocking and walk away + */ + sysret = select(maxfd+1, &rfds, &wfds, NULL, &tv); + timeout_remaining = 0; +#endif + + if (sysret > 0) { + for(i = 0; i < nfds; i++) { + switch (fds[i].type) { + case LIBSSH2_POLLFD_SOCKET: + if (FD_ISSET(fds[i].fd.socket, &rfds)) { + fds[i].revents |= LIBSSH2_POLLFD_POLLIN; + } + if (FD_ISSET(fds[i].fd.socket, &wfds)) { + fds[i].revents |= LIBSSH2_POLLFD_POLLOUT; + } + if (fds[i].revents) { + active_fds++; + } + break; + + case LIBSSH2_POLLFD_CHANNEL: + if (FD_ISSET(fds[i].fd.channel->session->socket_fd, &rfds)) { + /* Spin session until no data available */ + while (_libssh2_transport_read(fds[i].fd.channel->session) + > 0); + } + break; + + case LIBSSH2_POLLFD_LISTENER: + if (FD_ISSET + (fds[i].fd.listener->session->socket_fd, &rfds)) { + /* Spin session until no data available */ + while (_libssh2_transport_read(fds[i].fd.listener->session) + > 0); + } + break; + } + } + } +#endif /* else no select() or poll() -- timeout (and by extension + * timeout_remaining) will be equal to 0 */ + } while ((timeout_remaining > 0) && !active_fds); + + return active_fds; +} + +/* + * libssh2_session_block_directions + * + * Get blocked direction when a function returns LIBSSH2_ERROR_EAGAIN + * Returns LIBSSH2_SOCKET_BLOCK_INBOUND if recv() blocked + * or LIBSSH2_SOCKET_BLOCK_OUTBOUND if send() blocked + */ +LIBSSH2_API int +libssh2_session_block_directions(LIBSSH2_SESSION *session) +{ + return session->socket_block_directions; +} + +/* libssh2_session_banner_get + * Get the remote banner (server ID string) + */ + +LIBSSH2_API const char * +libssh2_session_banner_get(LIBSSH2_SESSION *session) +{ + /* to avoid a coredump when session is NULL */ + if (NULL == session) + return NULL; + + if (NULL==session->remote.banner) + return NULL; + + return (const char *) session->remote.banner; +} diff --git a/libssh2/sftp.c b/libssh2/sftp.c new file mode 100644 index 0000000..b0a3f1d --- /dev/null +++ b/libssh2/sftp.c @@ -0,0 +1,3425 @@ +/* Copyright (c) 2004-2008, Sara Golemon + * Copyright (c) 2007 Eli Fant + * Copyright (c) 2009-2014 by Daniel Stenberg + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include + +#include "libssh2_priv.h" +#include "libssh2_sftp.h" +#include "channel.h" +#include "session.h" +#include "sftp.h" + +/* Note: Version 6 was documented at the time of writing + * However it was marked as "DO NOT IMPLEMENT" due to pending changes + * + * This release of libssh2 implements Version 5 with automatic downgrade + * based on server's declaration + */ + +/* SFTP packet types */ +#define SSH_FXP_INIT 1 +#define SSH_FXP_VERSION 2 +#define SSH_FXP_OPEN 3 +#define SSH_FXP_CLOSE 4 +#define SSH_FXP_READ 5 +#define SSH_FXP_WRITE 6 +#define SSH_FXP_LSTAT 7 +#define SSH_FXP_FSTAT 8 +#define SSH_FXP_SETSTAT 9 +#define SSH_FXP_FSETSTAT 10 +#define SSH_FXP_OPENDIR 11 +#define SSH_FXP_READDIR 12 +#define SSH_FXP_REMOVE 13 +#define SSH_FXP_MKDIR 14 +#define SSH_FXP_RMDIR 15 +#define SSH_FXP_REALPATH 16 +#define SSH_FXP_STAT 17 +#define SSH_FXP_RENAME 18 +#define SSH_FXP_READLINK 19 +#define SSH_FXP_SYMLINK 20 +#define SSH_FXP_STATUS 101 +#define SSH_FXP_HANDLE 102 +#define SSH_FXP_DATA 103 +#define SSH_FXP_NAME 104 +#define SSH_FXP_ATTRS 105 +#define SSH_FXP_EXTENDED 200 +#define SSH_FXP_EXTENDED_REPLY 201 + +/* S_IFREG */ +#define LIBSSH2_SFTP_ATTR_PFILETYPE_FILE 0100000 +/* S_IFDIR */ +#define LIBSSH2_SFTP_ATTR_PFILETYPE_DIR 0040000 + +#define SSH_FXE_STATVFS_ST_RDONLY 0x00000001 +#define SSH_FXE_STATVFS_ST_NOSUID 0x00000002 + +/* This is the maximum packet length to accept, as larger than this indicate + some kind of server problem. */ +#define LIBSSH2_SFTP_PACKET_MAXLEN 80000 + +static int sftp_packet_ask(LIBSSH2_SFTP *sftp, unsigned char packet_type, + uint32_t request_id, unsigned char **data, + size_t *data_len); +static void sftp_packet_flush(LIBSSH2_SFTP *sftp); + +/* sftp_attrsize + * Size that attr with this flagset will occupy when turned into a bin struct + */ +static int sftp_attrsize(unsigned long flags) +{ + return (4 + /* flags(4) */ + ((flags & LIBSSH2_SFTP_ATTR_SIZE) ? 8 : 0) + + ((flags & LIBSSH2_SFTP_ATTR_UIDGID) ? 8 : 0) + + ((flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) ? 4 : 0) + + ((flags & LIBSSH2_SFTP_ATTR_ACMODTIME) ? 8 : 0)); + /* atime + mtime as u32 */ +} + +/* _libssh2_store_u64 + */ +static void _libssh2_store_u64(unsigned char **ptr, libssh2_uint64_t value) +{ + uint32_t msl = (uint32_t)(value >> 32); + unsigned char *buf = *ptr; + + buf[0] = (unsigned char)((msl >> 24) & 0xFF); + buf[1] = (unsigned char)((msl >> 16) & 0xFF); + buf[2] = (unsigned char)((msl >> 8) & 0xFF); + buf[3] = (unsigned char)( msl & 0xFF); + + buf[4] = (unsigned char)((value >> 24) & 0xFF); + buf[5] = (unsigned char)((value >> 16) & 0xFF); + buf[6] = (unsigned char)((value >> 8) & 0xFF); + buf[7] = (unsigned char)( value & 0xFF); + + *ptr += 8; +} + +/* + * Search list of zombied FXP_READ request IDs. + * + * Returns NULL if ID not in list. + */ +static struct sftp_zombie_requests * +find_zombie_request(LIBSSH2_SFTP *sftp, uint32_t request_id) +{ + struct sftp_zombie_requests *zombie = + _libssh2_list_first(&sftp->zombie_requests); + + while(zombie) { + if(zombie->request_id == request_id) + break; + else + zombie = _libssh2_list_next(&zombie->node); + } + + return zombie; +} + +static void +remove_zombie_request(LIBSSH2_SFTP *sftp, uint32_t request_id) +{ + LIBSSH2_SESSION *session = sftp->channel->session; + + struct sftp_zombie_requests *zombie = find_zombie_request(sftp, + request_id); + if(zombie) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Removing request ID %ld from the list of zombie requests", + request_id); + + _libssh2_list_remove(&zombie->node); + LIBSSH2_FREE(session, zombie); + } +} + +static int +add_zombie_request(LIBSSH2_SFTP *sftp, uint32_t request_id) +{ + LIBSSH2_SESSION *session = sftp->channel->session; + + struct sftp_zombie_requests *zombie; + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Marking request ID %ld as a zombie request", request_id); + + zombie = LIBSSH2_ALLOC(sftp->channel->session, + sizeof(struct sftp_zombie_requests)); + if (!zombie) + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "malloc fail for zombie request ID"); + else { + zombie->request_id = request_id; + _libssh2_list_add(&sftp->zombie_requests, &zombie->node); + return LIBSSH2_ERROR_NONE; + } +} + +/* + * sftp_packet_add + * + * Add a packet to the SFTP packet brigade + */ +static int +sftp_packet_add(LIBSSH2_SFTP *sftp, unsigned char *data, + size_t data_len) +{ + LIBSSH2_SESSION *session = sftp->channel->session; + LIBSSH2_SFTP_PACKET *packet; + uint32_t request_id; + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Received packet type %d (len %d)", + (int) data[0], data_len); + + /* + * Experience shows that if we mess up EAGAIN handling somewhere or + * otherwise get out of sync with the channel, this is where we first get + * a wrong byte and if so we need to bail out at once to aid tracking the + * problem better. + */ + + switch(data[0]) { + case SSH_FXP_INIT: + case SSH_FXP_VERSION: + case SSH_FXP_OPEN: + case SSH_FXP_CLOSE: + case SSH_FXP_READ: + case SSH_FXP_WRITE: + case SSH_FXP_LSTAT: + case SSH_FXP_FSTAT: + case SSH_FXP_SETSTAT: + case SSH_FXP_FSETSTAT: + case SSH_FXP_OPENDIR: + case SSH_FXP_READDIR: + case SSH_FXP_REMOVE: + case SSH_FXP_MKDIR: + case SSH_FXP_RMDIR: + case SSH_FXP_REALPATH: + case SSH_FXP_STAT: + case SSH_FXP_RENAME: + case SSH_FXP_READLINK: + case SSH_FXP_SYMLINK: + case SSH_FXP_STATUS: + case SSH_FXP_HANDLE: + case SSH_FXP_DATA: + case SSH_FXP_NAME: + case SSH_FXP_ATTRS: + case SSH_FXP_EXTENDED: + case SSH_FXP_EXTENDED_REPLY: + break; + default: + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Out of sync with the world"); + } + + request_id = _libssh2_ntohu32(&data[1]); + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Received packet id %d", + request_id); + + /* Don't add the packet if it answers a request we've given up on. */ + if((data[0] == SSH_FXP_STATUS || data[0] == SSH_FXP_DATA) + && find_zombie_request(sftp, request_id)) { + + /* If we get here, the file ended before the response arrived. We + are no longer interested in the request so we discard it */ + + LIBSSH2_FREE(session, data); + + remove_zombie_request(sftp, request_id); + return LIBSSH2_ERROR_NONE; + } + + packet = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_SFTP_PACKET)); + if (!packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate datablock for SFTP packet"); + } + + packet->data = data; + packet->data_len = data_len; + packet->request_id = request_id; + + _libssh2_list_add(&sftp->packets, &packet->node); + + return LIBSSH2_ERROR_NONE; +} + +/* + * sftp_packet_read + * + * Frame an SFTP packet off the channel + */ +static int +sftp_packet_read(LIBSSH2_SFTP *sftp) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + unsigned char *packet = NULL; + ssize_t rc; + unsigned long recv_window; + int packet_type; + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "recv packet"); + + switch(sftp->packet_state) { + case libssh2_NB_state_sent: /* EAGAIN from window adjusting */ + sftp->packet_state = libssh2_NB_state_idle; + + packet = sftp->partial_packet; + goto window_adjust; + + case libssh2_NB_state_sent1: /* EAGAIN from channel read */ + sftp->packet_state = libssh2_NB_state_idle; + + packet = sftp->partial_packet; + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "partial read cont, len: %lu", sftp->partial_len); + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "partial read cont, already recvd: %lu", + sftp->partial_received); + /* fall-through */ + default: + if(!packet) { + /* only do this if there's not already a packet buffer allocated + to use */ + + /* each packet starts with a 32 bit length field */ + rc = _libssh2_channel_read(channel, 0, + (char *)&sftp->partial_size[ + sftp->partial_size_len], + 4 - sftp->partial_size_len); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + else if (rc < 0) + return _libssh2_error(session, rc, "channel read"); + + sftp->partial_size_len += rc; + + if(4 != sftp->partial_size_len) + /* we got a short read for the length part */ + return LIBSSH2_ERROR_EAGAIN; + + sftp->partial_len = _libssh2_ntohu32(sftp->partial_size); + /* make sure we don't proceed if the packet size is unreasonably + large */ + if (sftp->partial_len > LIBSSH2_SFTP_PACKET_MAXLEN) + return _libssh2_error(session, + LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED, + "SFTP packet too large"); + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Data begin - Packet Length: %lu", + sftp->partial_len); + packet = LIBSSH2_ALLOC(session, sftp->partial_len); + if (!packet) + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate SFTP packet"); + sftp->partial_size_len = 0; + sftp->partial_received = 0; /* how much of the packet already + received */ + sftp->partial_packet = packet; + + window_adjust: + recv_window = libssh2_channel_window_read_ex(channel, NULL, NULL); + + if(sftp->partial_len > recv_window) { + /* ask for twice the data amount we need at once */ + rc = _libssh2_channel_receive_window_adjust(channel, + sftp->partial_len*2, + 1, NULL); + /* store the state so that we continue with the correct + operation at next invoke */ + sftp->packet_state = (rc == LIBSSH2_ERROR_EAGAIN)? + libssh2_NB_state_sent: + libssh2_NB_state_idle; + + if(rc == LIBSSH2_ERROR_EAGAIN) + return rc; + } + } + + /* Read as much of the packet as we can */ + while (sftp->partial_len > sftp->partial_received) { + rc = _libssh2_channel_read(channel, 0, + (char *)&packet[sftp->partial_received], + sftp->partial_len - + sftp->partial_received); + + if (rc == LIBSSH2_ERROR_EAGAIN) { + /* + * We received EAGAIN, save what we have and return EAGAIN to + * the caller. Set 'partial_packet' so that this function + * knows how to continue on the next invoke. + */ + sftp->packet_state = libssh2_NB_state_sent1; + return rc; + } + else if (rc < 0) { + LIBSSH2_FREE(session, packet); + sftp->partial_packet = NULL; + return _libssh2_error(session, rc, + "Error waiting for SFTP packet"); + } + sftp->partial_received += rc; + } + + sftp->partial_packet = NULL; + + /* sftp_packet_add takes ownership of the packet and might free it + so we take a copy of the packet type before we call it. */ + packet_type = packet[0]; + rc = sftp_packet_add(sftp, packet, sftp->partial_len); + if (rc) { + LIBSSH2_FREE(session, packet); + return rc; + } + else { + return packet_type; + } + } + /* WON'T REACH */ +} +/* + * sftp_packetlist_flush + * + * Remove all pending packets in the packet_list and the corresponding one(s) + * in the SFTP packet brigade. + */ +static void sftp_packetlist_flush(LIBSSH2_SFTP_HANDLE *handle) +{ + struct sftp_pipeline_chunk *chunk; + LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_SESSION *session = sftp->channel->session; + + /* remove pending packets, if any */ + chunk = _libssh2_list_first(&handle->packet_list); + while(chunk) { + unsigned char *data; + size_t data_len; + int rc; + struct sftp_pipeline_chunk *next = _libssh2_list_next(&chunk->node); + + rc = sftp_packet_ask(sftp, SSH_FXP_STATUS, + chunk->request_id, &data, &data_len); + if(rc) + rc = sftp_packet_ask(sftp, SSH_FXP_DATA, + chunk->request_id, &data, &data_len); + + if(!rc) + /* we found a packet, free it */ + LIBSSH2_FREE(session, data); + else if(chunk->sent) + /* there was no incoming packet for this request, mark this + request as a zombie if it ever sent the request */ + add_zombie_request(sftp, chunk->request_id); + + _libssh2_list_remove(&chunk->node); + LIBSSH2_FREE(session, chunk); + chunk = next; + } +} + + +/* + * sftp_packet_ask() + * + * Checks if there's a matching SFTP packet available. + */ +static int +sftp_packet_ask(LIBSSH2_SFTP *sftp, unsigned char packet_type, + uint32_t request_id, unsigned char **data, + size_t *data_len) +{ + LIBSSH2_SESSION *session = sftp->channel->session; + LIBSSH2_SFTP_PACKET *packet = _libssh2_list_first(&sftp->packets); + + if(!packet) + return -1; + + /* Special consideration when getting VERSION packet */ + + while (packet) { + if((packet->data[0] == packet_type) && + ((packet_type == SSH_FXP_VERSION) || + (packet->request_id == request_id))) { + + /* Match! Fetch the data */ + *data = packet->data; + *data_len = packet->data_len; + + /* unlink and free this struct */ + _libssh2_list_remove(&packet->node); + LIBSSH2_FREE(session, packet); + + return 0; + } + /* check next struct in the list */ + packet = _libssh2_list_next(&packet->node); + } + return -1; +} + +/* sftp_packet_require + * A la libssh2_packet_require + */ +static int +sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type, + uint32_t request_id, unsigned char **data, + size_t *data_len) +{ + LIBSSH2_SESSION *session = sftp->channel->session; + int rc; + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Requiring packet %d id %ld", + (int) packet_type, request_id); + + if (sftp_packet_ask(sftp, packet_type, request_id, data, data_len) == 0) { + /* The right packet was available in the packet brigade */ + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Got %d", + (int) packet_type); + return LIBSSH2_ERROR_NONE; + } + + while (session->socket_state == LIBSSH2_SOCKET_CONNECTED) { + rc = sftp_packet_read(sftp); + if (rc < 0) + return rc; + + /* data was read, check the queue again */ + if (!sftp_packet_ask(sftp, packet_type, request_id, data, data_len)) { + /* The right packet was available in the packet brigade */ + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Got %d", + (int) packet_type); + return LIBSSH2_ERROR_NONE; + } + } + + /* Only reached if the socket died */ + return LIBSSH2_ERROR_SOCKET_DISCONNECT; +} + +/* sftp_packet_requirev + * Require one of N possible responses + */ +static int +sftp_packet_requirev(LIBSSH2_SFTP *sftp, int num_valid_responses, + const unsigned char *valid_responses, + uint32_t request_id, unsigned char **data, + size_t *data_len) +{ + int i; + int rc; + + /* If no timeout is active, start a new one */ + if (sftp->requirev_start == 0) + sftp->requirev_start = time(NULL); + + while (sftp->channel->session->socket_state == LIBSSH2_SOCKET_CONNECTED) { + for(i = 0; i < num_valid_responses; i++) { + if (sftp_packet_ask(sftp, valid_responses[i], request_id, + data, data_len) == 0) { + /* + * Set to zero before all returns to say + * the timeout is not active + */ + sftp->requirev_start = 0; + return LIBSSH2_ERROR_NONE; + } + } + + rc = sftp_packet_read(sftp); + if ((rc < 0) && (rc != LIBSSH2_ERROR_EAGAIN)) { + sftp->requirev_start = 0; + return rc; + } else if (rc <= 0) { + /* prevent busy-looping */ + long left = + LIBSSH2_READ_TIMEOUT - (long)(time(NULL) - sftp->requirev_start); + + if (left <= 0) { + sftp->requirev_start = 0; + return LIBSSH2_ERROR_TIMEOUT; + } + else if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + } + } + + sftp->requirev_start = 0; + + /* Only reached if the socket died */ + return LIBSSH2_ERROR_SOCKET_DISCONNECT; +} + +/* sftp_attr2bin + * Populate attributes into an SFTP block + */ +static ssize_t +sftp_attr2bin(unsigned char *p, const LIBSSH2_SFTP_ATTRIBUTES * attrs) +{ + unsigned char *s = p; + uint32_t flag_mask = + LIBSSH2_SFTP_ATTR_SIZE | LIBSSH2_SFTP_ATTR_UIDGID | + LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME; + + /* TODO: When we add SFTP4+ functionality flag_mask can get additional + bits */ + + if (!attrs) { + _libssh2_htonu32(s, 0); + return 4; + } + + _libssh2_store_u32(&s, attrs->flags & flag_mask); + + if (attrs->flags & LIBSSH2_SFTP_ATTR_SIZE) { + _libssh2_store_u64(&s, attrs->filesize); + } + + if (attrs->flags & LIBSSH2_SFTP_ATTR_UIDGID) { + _libssh2_store_u32(&s, attrs->uid); + _libssh2_store_u32(&s, attrs->gid); + } + + if (attrs->flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) { + _libssh2_store_u32(&s, attrs->permissions); + } + + if (attrs->flags & LIBSSH2_SFTP_ATTR_ACMODTIME) { + _libssh2_store_u32(&s, attrs->atime); + _libssh2_store_u32(&s, attrs->mtime); + } + + return (s - p); +} + +/* sftp_bin2attr + */ +static int +sftp_bin2attr(LIBSSH2_SFTP_ATTRIBUTES * attrs, const unsigned char *p) +{ + const unsigned char *s = p; + + memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); + attrs->flags = _libssh2_ntohu32(s); + s += 4; + + if (attrs->flags & LIBSSH2_SFTP_ATTR_SIZE) { + attrs->filesize = _libssh2_ntohu64(s); + s += 8; + } + + if (attrs->flags & LIBSSH2_SFTP_ATTR_UIDGID) { + attrs->uid = _libssh2_ntohu32(s); + s += 4; + attrs->gid = _libssh2_ntohu32(s); + s += 4; + } + + if (attrs->flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) { + attrs->permissions = _libssh2_ntohu32(s); + s += 4; + } + + if (attrs->flags & LIBSSH2_SFTP_ATTR_ACMODTIME) { + attrs->atime = _libssh2_ntohu32(s); + s += 4; + attrs->mtime = _libssh2_ntohu32(s); + s += 4; + } + + return (s - p); +} + +/* ************ + * SFTP API * + ************ */ + +LIBSSH2_CHANNEL_CLOSE_FUNC(libssh2_sftp_dtor); + +/* libssh2_sftp_dtor + * Shutdown an SFTP stream when the channel closes + */ +LIBSSH2_CHANNEL_CLOSE_FUNC(libssh2_sftp_dtor) +{ + LIBSSH2_SFTP *sftp = (LIBSSH2_SFTP *) (*channel_abstract); + + (void) session_abstract; + (void) channel; + + /* Free the partial packet storage for sftp_packet_read */ + if (sftp->partial_packet) { + LIBSSH2_FREE(session, sftp->partial_packet); + } + + /* Free the packet storage for _libssh2_sftp_packet_readdir */ + if (sftp->readdir_packet) { + LIBSSH2_FREE(session, sftp->readdir_packet); + } + + LIBSSH2_FREE(session, sftp); +} + +/* + * sftp_init + * + * Startup an SFTP session + */ +static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session) +{ + unsigned char *data, *s; + size_t data_len; + ssize_t rc; + LIBSSH2_SFTP *sftp_handle; + + if (session->sftpInit_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Initializing SFTP subsystem"); + + /* + * The 'sftpInit_sftp' and 'sftpInit_channel' struct fields within the + * session struct are only to be used during the setup phase. As soon + * as the SFTP session is created they are cleared and can thus be + * re-used again to allow any amount of SFTP handles per sessions. + * + * Note that you MUST NOT try to call libssh2_sftp_init() again to get + * another handle until the previous call has finished and either + * successfully made a handle or failed and returned error (not + * including *EAGAIN). + */ + + assert(session->sftpInit_sftp == NULL); + session->sftpInit_sftp = NULL; + session->sftpInit_state = libssh2_NB_state_created; + } + + sftp_handle = session->sftpInit_sftp; + + if (session->sftpInit_state == libssh2_NB_state_created) { + session->sftpInit_channel = + _libssh2_channel_open(session, "session", sizeof("session") - 1, + LIBSSH2_CHANNEL_WINDOW_DEFAULT, + LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0); + if (!session->sftpInit_channel) { + if (libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block starting up channel"); + } + else { + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Unable to startup channel"); + session->sftpInit_state = libssh2_NB_state_idle; + } + return NULL; + } + + session->sftpInit_state = libssh2_NB_state_sent; + } + + if (session->sftpInit_state == libssh2_NB_state_sent) { + int ret = _libssh2_channel_process_startup(session->sftpInit_channel, + "subsystem", + sizeof("subsystem") - 1, "sftp", + strlen("sftp")); + if (ret == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block to request SFTP subsystem"); + return NULL; + } else if (ret) { + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Unable to request SFTP subsystem"); + goto sftp_init_error; + } + + session->sftpInit_state = libssh2_NB_state_sent1; + } + + if (session->sftpInit_state == libssh2_NB_state_sent1) { + rc = _libssh2_channel_extended_data(session->sftpInit_channel, + LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block requesting handle extended data"); + return NULL; + } + + sftp_handle = + session->sftpInit_sftp = + LIBSSH2_CALLOC(session, sizeof(LIBSSH2_SFTP)); + if (!sftp_handle) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate a new SFTP structure"); + goto sftp_init_error; + } + sftp_handle->channel = session->sftpInit_channel; + sftp_handle->request_id = 0; + + _libssh2_htonu32(session->sftpInit_buffer, 5); + session->sftpInit_buffer[4] = SSH_FXP_INIT; + _libssh2_htonu32(session->sftpInit_buffer + 5, LIBSSH2_SFTP_VERSION); + session->sftpInit_sent = 0; /* nothing's sent yet */ + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Sending FXP_INIT packet advertising version %d support", + (int) LIBSSH2_SFTP_VERSION); + + session->sftpInit_state = libssh2_NB_state_sent2; + } + + if (session->sftpInit_state == libssh2_NB_state_sent2) { + /* sent off what's left of the init buffer to send */ + rc = _libssh2_channel_write(session->sftpInit_channel, 0, + session->sftpInit_buffer + + session->sftpInit_sent, + 9 - session->sftpInit_sent); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending SSH_FXP_INIT"); + return NULL; + } + else if(rc < 0) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send SSH_FXP_INIT"); + goto sftp_init_error; + } + else { + /* add up the number of bytes sent */ + session->sftpInit_sent += rc; + + if(session->sftpInit_sent == 9) + /* move on */ + session->sftpInit_state = libssh2_NB_state_sent3; + + /* if less than 9, we remain in this state to send more later on */ + } + } + + rc = sftp_packet_require(sftp_handle, SSH_FXP_VERSION, + 0, &data, &data_len); + if (rc == LIBSSH2_ERROR_EAGAIN) + return NULL; + else if (rc) { + _libssh2_error(session, rc, + "Timeout waiting for response from SFTP subsystem"); + goto sftp_init_error; + } + if (data_len < 5) { + _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Invalid SSH_FXP_VERSION response"); + LIBSSH2_FREE(session, data); + goto sftp_init_error; + } + + s = data + 1; + sftp_handle->version = _libssh2_ntohu32(s); + s += 4; + if (sftp_handle->version > LIBSSH2_SFTP_VERSION) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Truncating remote SFTP version from %lu", + sftp_handle->version); + sftp_handle->version = LIBSSH2_SFTP_VERSION; + } + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Enabling SFTP version %lu compatibility", + sftp_handle->version); + while (s < (data + data_len)) { + size_t extname_len, extdata_len; + + extname_len = _libssh2_ntohu32(s); + s += 4; + /* the extension name starts here */ + s += extname_len; + + extdata_len = _libssh2_ntohu32(s); + s += 4; + + /* TODO: Actually process extensions */ + s += extdata_len; + + } + LIBSSH2_FREE(session, data); + + /* Make sure that when the channel gets closed, the SFTP service is shut + down too */ + sftp_handle->channel->abstract = sftp_handle; + sftp_handle->channel->close_cb = libssh2_sftp_dtor; + + session->sftpInit_state = libssh2_NB_state_idle; + + /* clear the sftp and channel pointers in this session struct now */ + session->sftpInit_sftp = NULL; + session->sftpInit_channel = NULL; + + _libssh2_list_init(&sftp_handle->sftp_handles); + + return sftp_handle; + + sftp_init_error: + while (_libssh2_channel_free(session->sftpInit_channel) == + LIBSSH2_ERROR_EAGAIN); + session->sftpInit_channel = NULL; + if (session->sftpInit_sftp) { + LIBSSH2_FREE(session, session->sftpInit_sftp); + session->sftpInit_sftp = NULL; + } + session->sftpInit_state = libssh2_NB_state_idle; + return NULL; +} + +/* + * libssh2_sftp_init + * + * Startup an SFTP session + */ +LIBSSH2_API LIBSSH2_SFTP *libssh2_sftp_init(LIBSSH2_SESSION *session) +{ + LIBSSH2_SFTP *ptr; + + if(!session) + return NULL; + + if(!(session->state & LIBSSH2_STATE_AUTHENTICATED)) { + _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "session not authenticated yet"); + return NULL; + } + + BLOCK_ADJUST_ERRNO(ptr, session, sftp_init(session)); + return ptr; +} + +/* + * sftp_shutdown + * + * Shuts down the SFTP subsystem + */ +static int +sftp_shutdown(LIBSSH2_SFTP *sftp) +{ + int rc; + LIBSSH2_SESSION *session = sftp->channel->session; + /* + * Make sure all memory used in the state variables are free + */ + if (sftp->partial_packet) { + LIBSSH2_FREE(session, sftp->partial_packet); + sftp->partial_packet = NULL; + } + if (sftp->open_packet) { + LIBSSH2_FREE(session, sftp->open_packet); + sftp->open_packet = NULL; + } + if (sftp->readdir_packet) { + LIBSSH2_FREE(session, sftp->readdir_packet); + sftp->readdir_packet = NULL; + } + if (sftp->fstat_packet) { + LIBSSH2_FREE(session, sftp->fstat_packet); + sftp->fstat_packet = NULL; + } + if (sftp->unlink_packet) { + LIBSSH2_FREE(session, sftp->unlink_packet); + sftp->unlink_packet = NULL; + } + if (sftp->rename_packet) { + LIBSSH2_FREE(session, sftp->rename_packet); + sftp->rename_packet = NULL; + } + if (sftp->fstatvfs_packet) { + LIBSSH2_FREE(session, sftp->fstatvfs_packet); + sftp->fstatvfs_packet = NULL; + } + if (sftp->statvfs_packet) { + LIBSSH2_FREE(session, sftp->statvfs_packet); + sftp->statvfs_packet = NULL; + } + if (sftp->mkdir_packet) { + LIBSSH2_FREE(session, sftp->mkdir_packet); + sftp->mkdir_packet = NULL; + } + if (sftp->rmdir_packet) { + LIBSSH2_FREE(session, sftp->rmdir_packet); + sftp->rmdir_packet = NULL; + } + if (sftp->stat_packet) { + LIBSSH2_FREE(session, sftp->stat_packet); + sftp->stat_packet = NULL; + } + if (sftp->symlink_packet) { + LIBSSH2_FREE(session, sftp->symlink_packet); + sftp->symlink_packet = NULL; + } + if (sftp->fsync_packet) { + LIBSSH2_FREE(session, sftp->fsync_packet); + sftp->fsync_packet = NULL; + } + + sftp_packet_flush(sftp); + + /* TODO: We should consider walking over the sftp_handles list and kill + * any remaining sftp handles ... */ + + rc = _libssh2_channel_free(sftp->channel); + + return rc; +} + +/* libssh2_sftp_shutdown + * Shutsdown the SFTP subsystem + */ +LIBSSH2_API int +libssh2_sftp_shutdown(LIBSSH2_SFTP *sftp) +{ + int rc; + if(!sftp) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, sftp->channel->session, sftp_shutdown(sftp)); + return rc; +} + +/* ******************************* + * SFTP File and Directory Ops * + ******************************* */ + +/* sftp_open + */ +static LIBSSH2_SFTP_HANDLE * +sftp_open(LIBSSH2_SFTP *sftp, const char *filename, + size_t filename_len, uint32_t flags, long mode, + int open_type) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + LIBSSH2_SFTP_HANDLE *fp; + LIBSSH2_SFTP_ATTRIBUTES attrs = { + LIBSSH2_SFTP_ATTR_PERMISSIONS, 0, 0, 0, 0, 0, 0 + }; + unsigned char *s; + ssize_t rc; + int open_file = (open_type == LIBSSH2_SFTP_OPENFILE)?1:0; + + if (sftp->open_state == libssh2_NB_state_idle) { + /* packet_len(4) + packet_type(1) + request_id(4) + filename_len(4) + + flags(4) */ + sftp->open_packet_len = filename_len + 13 + + (open_file? (4 + sftp_attrsize(LIBSSH2_SFTP_ATTR_PERMISSIONS)) : 0); + + /* surprise! this starts out with nothing sent */ + sftp->open_packet_sent = 0; + s = sftp->open_packet = LIBSSH2_ALLOC(session, sftp->open_packet_len); + if (!sftp->open_packet) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_OPEN or " + "FXP_OPENDIR packet"); + return NULL; + } + /* Filetype in SFTP 3 and earlier */ + attrs.permissions = mode | + (open_file ? LIBSSH2_SFTP_ATTR_PFILETYPE_FILE : + LIBSSH2_SFTP_ATTR_PFILETYPE_DIR); + + _libssh2_store_u32(&s, sftp->open_packet_len - 4); + *(s++) = open_file? SSH_FXP_OPEN : SSH_FXP_OPENDIR; + sftp->open_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->open_request_id); + _libssh2_store_str(&s, filename, filename_len); + + if (open_file) { + _libssh2_store_u32(&s, flags); + s += sftp_attr2bin(s, &attrs); + } + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Sending %s open request", + open_file? "file" : "directory"); + + sftp->open_state = libssh2_NB_state_created; + } + + if (sftp->open_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, sftp->open_packet+ + sftp->open_packet_sent, + sftp->open_packet_len - + sftp->open_packet_sent); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending FXP_OPEN or FXP_OPENDIR command"); + return NULL; + } + else if(rc < 0) { + _libssh2_error(session, rc, "Unable to send FXP_OPEN*"); + LIBSSH2_FREE(session, sftp->open_packet); + sftp->open_packet = NULL; + sftp->open_state = libssh2_NB_state_idle; + return NULL; + } + + /* bump the sent counter and remain in this state until the whole + data is off */ + sftp->open_packet_sent += rc; + + if(sftp->open_packet_len == sftp->open_packet_sent) { + LIBSSH2_FREE(session, sftp->open_packet); + sftp->open_packet = NULL; + + sftp->open_state = libssh2_NB_state_sent; + } + } + + if (sftp->open_state == libssh2_NB_state_sent) { + size_t data_len; + unsigned char *data; + static const unsigned char fopen_responses[2] = + { SSH_FXP_HANDLE, SSH_FXP_STATUS }; + rc = sftp_packet_requirev(sftp, 2, fopen_responses, + sftp->open_request_id, &data, + &data_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for status message"); + return NULL; + } + sftp->open_state = libssh2_NB_state_idle; + if (rc) { + _libssh2_error(session, rc, "Timeout waiting for status message"); + return NULL; + } + + /* OPEN can basically get STATUS or HANDLE back, where HANDLE implies + a fine response while STATUS means error. It seems though that at + times we get an SSH_FX_OK back in a STATUS, followed the "real" + HANDLE so we need to properly deal with that. */ + if (data[0] == SSH_FXP_STATUS) { + int badness = 1; + + if(data_len < 9) { + _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Too small FXP_STATUS"); + LIBSSH2_FREE(session, data); + return NULL; + } + + sftp->last_errno = _libssh2_ntohu32(data + 5); + + if(LIBSSH2_FX_OK == sftp->last_errno) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "got HANDLE FXOK!"); + + LIBSSH2_FREE(session, data); + + /* silly situation, but check for a HANDLE */ + rc = sftp_packet_require(sftp, SSH_FXP_HANDLE, + sftp->open_request_id, &data, + &data_len); + if(rc == LIBSSH2_ERROR_EAGAIN) { + /* go back to sent state and wait for something else */ + sftp->open_state = libssh2_NB_state_sent; + return NULL; + } + else if(!rc) + /* we got the handle so this is not a bad situation */ + badness = 0; + } + + if(badness) { + _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Failed opening remote file"); + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "got FXP_STATUS %d", + sftp->last_errno); + LIBSSH2_FREE(session, data); + return NULL; + } + } + + if(data_len < 10) { + _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Too small FXP_HANDLE"); + LIBSSH2_FREE(session, data); + return NULL; + } + + fp = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_SFTP_HANDLE)); + if (!fp) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate new SFTP handle structure"); + LIBSSH2_FREE(session, data); + return NULL; + } + fp->handle_type = open_file ? LIBSSH2_SFTP_HANDLE_FILE : + LIBSSH2_SFTP_HANDLE_DIR; + + fp->handle_len = _libssh2_ntohu32(data + 5); + if (fp->handle_len > SFTP_HANDLE_MAXLEN) + /* SFTP doesn't allow handles longer than 256 characters */ + fp->handle_len = SFTP_HANDLE_MAXLEN; + + if(fp->handle_len > (data_len - 9)) + /* do not reach beyond the end of the data we got */ + fp->handle_len = data_len - 9; + + memcpy(fp->handle, data + 9, fp->handle_len); + + LIBSSH2_FREE(session, data); + + /* add this file handle to the list kept in the sftp session */ + _libssh2_list_add(&sftp->sftp_handles, &fp->node); + + fp->sftp = sftp; /* point to the parent struct */ + + fp->u.file.offset = 0; + fp->u.file.offset_sent = 0; + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Open command successful"); + return fp; + } + return NULL; +} + +/* libssh2_sftp_open_ex + */ +LIBSSH2_API LIBSSH2_SFTP_HANDLE * +libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp, const char *filename, + unsigned int filename_len, unsigned long flags, long mode, + int open_type) +{ + LIBSSH2_SFTP_HANDLE *hnd; + + if(!sftp) + return NULL; + + BLOCK_ADJUST_ERRNO(hnd, sftp->channel->session, + sftp_open(sftp, filename, filename_len, flags, mode, + open_type)); + return hnd; +} + +/* + * sftp_read + * + * Read from an SFTP file handle + * + */ +static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer, + size_t buffer_size) +{ + LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t count = 0; + struct sftp_pipeline_chunk *chunk; + struct sftp_pipeline_chunk *next; + ssize_t rc; + struct _libssh2_sftp_handle_file_data *filep = + &handle->u.file; + size_t bytes_in_buffer = 0; + char *sliding_bufferp = buffer; + + /* This function can be interrupted in three different places where it + might need to wait for data from the network. It returns EAGAIN to + allow non-blocking clients to do other work but these client are + expected to call this function again (possibly many times) to finish + the operation. + + The tricky part is that if we previously aborted a sftp_read due to + EAGAIN, we must continue at the same spot to continue the previously + interrupted operation. This is done using a state machine to record + what phase of execution we were at. The state is stored in + sftp->read_state. + + libssh2_NB_state_idle: The first phase is where we prepare multiple + FXP_READ packets to do optimistic read-ahead. We send off as many as + possible in the second phase without waiting for a response to each + one; this is the key to fast reads. But we may have to adjust the + channel window size to do this which may interrupt this function while + waiting. The state machine saves the phase as libssh2_NB_state_idle so + it returns here on the next call. + + libssh2_NB_state_sent: The second phase is where we send the FXP_READ + packets. Writing them to the channel can be interrupted with EAGAIN + but the state machine ensures we skip the first phase on the next call + and resume sending. + + libssh2_NB_state_sent2: In the third phase (indicated by ) we read the + data from the responses that have arrived so far. Reading can be + interrupted with EAGAIN but the state machine ensures we skip the first + and second phases on the next call and resume sending. + */ + + switch (sftp->read_state) { + case libssh2_NB_state_idle: + + /* Some data may already have been read from the server in the + previous call but didn't fit in the buffer at the time. If so, we + return that now as we can't risk being interrupted later with data + partially written to the buffer. */ + if(filep->data_left) { + size_t copy = MIN(buffer_size, filep->data_left); + + memcpy(buffer, &filep->data[ filep->data_len - filep->data_left], + copy); + + filep->data_left -= copy; + filep->offset += copy; + + if(!filep->data_left) { + LIBSSH2_FREE(session, filep->data); + filep->data = NULL; + } + + return copy; + } + + /* We allow a number of bytes being requested at any given time + without having been acked - until we reach EOF. */ + if(!filep->eof) { + /* Number of bytes asked for that haven't been acked yet */ + size_t already = (size_t)(filep->offset_sent - filep->offset); + + size_t max_read_ahead = buffer_size*4; + unsigned long recv_window; + + if(max_read_ahead > LIBSSH2_CHANNEL_WINDOW_DEFAULT*4) + max_read_ahead = LIBSSH2_CHANNEL_WINDOW_DEFAULT*4; + + /* if the buffer_size passed in now is smaller than what has + already been sent, we risk getting count become a very large + number */ + if(max_read_ahead > already) + count = max_read_ahead - already; + + /* 'count' is how much more data to ask for, and 'already' is how + much data that already has been asked for but not yet returned. + Specificly, 'count' means how much data that have or will be + asked for by the nodes that are already added to the linked + list. Some of those read requests may not actually have been + sent off successfully yet. + + If 'already' is very large it should be perfectly fine to have + count set to 0 as then we don't have to ask for more data + (right now). + + buffer_size*4 is just picked more or less out of the air. The + idea is that when reading SFTP from a remote server, we send + away multiple read requests guessing that the client will read + more than only this 'buffer_size' amount of memory. So we ask + for maximum buffer_size*4 amount of data so that we can return + them very fast in subsequent calls. + */ + + recv_window = libssh2_channel_window_read_ex(sftp->channel, + NULL, NULL); + if(max_read_ahead > recv_window) { + /* more data will be asked for than what the window currently + allows, expand it! */ + + rc = _libssh2_channel_receive_window_adjust(sftp->channel, + max_read_ahead*8, + 1, NULL); + /* if this returns EAGAIN, we will get back to this function + at next call */ + assert(rc != LIBSSH2_ERROR_EAGAIN || !filep->data_left); + assert(rc != LIBSSH2_ERROR_EAGAIN || !filep->eof); + if (rc) + return rc; + } + } + + while(count > 0) { + unsigned char *s; + uint32_t size = MIN(MAX_SFTP_READ_SIZE, count); + + /* 25 = packet_len(4) + packet_type(1) + request_id(4) + + handle_len(4) + offset(8) + count(4) */ + uint32_t packet_len = (uint32_t)handle->handle_len + 25; + uint32_t request_id; + + chunk = LIBSSH2_ALLOC(session, packet_len + + sizeof(struct sftp_pipeline_chunk)); + if (!chunk) + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "malloc fail for FXP_WRITE"); + + chunk->len = size; + chunk->lefttosend = packet_len; + chunk->sent = 0; + + s = chunk->packet; + + _libssh2_store_u32(&s, packet_len - 4); + *s++ = SSH_FXP_READ; + request_id = sftp->request_id++; + chunk->request_id = request_id; + _libssh2_store_u32(&s, request_id); + _libssh2_store_str(&s, handle->handle, handle->handle_len); + _libssh2_store_u64(&s, filep->offset_sent); + filep->offset_sent += size; /* advance offset at once */ + _libssh2_store_u32(&s, size); + + /* add this new entry LAST in the list */ + _libssh2_list_add(&handle->packet_list, &chunk->node); + count -= size; /* deduct the size we used, as we might have + to create more packets */ + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "read request id %d sent", request_id); + } + + case libssh2_NB_state_sent: + + sftp->read_state = libssh2_NB_state_idle; + + /* move through the READ packets that haven't been sent and send as + many as possible - remember that we don't block */ + chunk = _libssh2_list_first(&handle->packet_list); + + while(chunk) { + if(chunk->lefttosend) { + + rc = _libssh2_channel_write(channel, 0, + &chunk->packet[chunk->sent], + chunk->lefttosend); + if(rc < 0) { + sftp->read_state = libssh2_NB_state_sent; + return rc; + } + + /* remember where to continue sending the next time */ + chunk->lefttosend -= rc; + chunk->sent += rc; + + if(chunk->lefttosend) + /* data left to send, get out of loop */ + break; + } + + /* move on to the next chunk with data to send */ + chunk = _libssh2_list_next(&chunk->node); + } + + case libssh2_NB_state_sent2: + + sftp->read_state = libssh2_NB_state_idle; + + /* + * Count all ACKed packets and act on the contents of them. + */ + chunk = _libssh2_list_first(&handle->packet_list); + + while(chunk) { + unsigned char *data; + size_t data_len; + uint32_t rc32; + static const unsigned char read_responses[2] = { + SSH_FXP_DATA, SSH_FXP_STATUS + }; + + if(chunk->lefttosend) + /* if the chunk still has data left to send, we shouldn't wait + for an ACK for it just yet */ + break; + + rc = sftp_packet_requirev(sftp, 2, read_responses, + chunk->request_id, &data, &data_len); + if (rc < 0) { + sftp->read_state = libssh2_NB_state_sent2; + return rc; + } + + /* + * We get DATA or STATUS back. STATUS can be error, or it is + * FX_EOF when we reach the end of the file. + */ + + switch (data[0]) { + case SSH_FXP_STATUS: + /* remove the chunk we just processed */ + + _libssh2_list_remove(&chunk->node); + LIBSSH2_FREE(session, chunk); + + /* we must remove all outstanding READ requests, as either we + got an error or we're at end of file */ + sftp_packetlist_flush(handle); + + rc32 = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + + if (rc32 == LIBSSH2_FX_EOF) { + filep->eof = TRUE; + return bytes_in_buffer; + } + else { + sftp->last_errno = rc32; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP READ error"); + } + break; + + case SSH_FXP_DATA: + rc32 = _libssh2_ntohu32(data + 5); + if (rc32 > (data_len - 9)) + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol badness"); + + if(rc32 > chunk->len) { + /* A chunk larger than we requested was returned to us. + This is a protocol violation and we don't know how to + deal with it. Bail out! */ + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "FXP_READ response too big"); + } + + if(rc32 != chunk->len) { + /* a short read does not imply end of file, but we must + adjust the offset_sent since it was advanced with a + full chunk->len before */ + filep->offset_sent -= (chunk->len - rc32); + } + + if((bytes_in_buffer + rc32) > buffer_size) { + /* figure out the overlap amount */ + filep->data_left = (bytes_in_buffer + rc32) - buffer_size; + + /* getting the full packet would overflow the buffer, so + only get the correct amount and keep the remainder */ + rc32 = (uint32_t)buffer_size - bytes_in_buffer; + + /* store data to keep for next call */ + filep->data = data; + filep->data_len = data_len; + } + else + filep->data_len = 0; + + /* copy the received data from the received FXP_DATA packet to + the buffer at the correct index */ + memcpy(sliding_bufferp, data + 9, rc32); + filep->offset += rc32; + + if(filep->data_len == 0) + /* free the allocated data if not stored to keep */ + LIBSSH2_FREE(session, data); + + + /* remove the chunk we just processed keeping track of the + * next one in case we need it */ + next = _libssh2_list_next(&chunk->node); + _libssh2_list_remove(&chunk->node); + LIBSSH2_FREE(session, chunk); + chunk = NULL; + + if(rc32 > 0) { + /* continue to the next chunk */ + bytes_in_buffer += rc32; + sliding_bufferp += rc32; + chunk = next; + } else { + /* A zero-byte read is not necessarily EOF so we must not + * return 0 (that would signal EOF to the caller) so + * instead we carry on to the next chunk */ + chunk = next; + } + + break; + default: + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol badness: unrecognised " + "read request response"); + } + } + + if (bytes_in_buffer > 0) + return bytes_in_buffer; + + break; + + default: + assert(!"State machine error; unrecognised read state"); + } + + return 0; +} + +/* libssh2_sftp_read + * Read from an SFTP file handle + */ +LIBSSH2_API ssize_t +libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *hnd, char *buffer, + size_t buffer_maxlen) +{ + ssize_t rc; + if(!hnd) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, hnd->sftp->channel->session, + sftp_read(hnd, buffer, buffer_maxlen)); + return rc; +} + +/* sftp_readdir + * Read from an SFTP directory handle + */ +static ssize_t sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer, + size_t buffer_maxlen, char *longentry, + size_t longentry_maxlen, + LIBSSH2_SFTP_ATTRIBUTES *attrs) +{ + LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + uint32_t num_names; + /* 13 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */ + uint32_t packet_len = handle->handle_len + 13; + unsigned char *s, *data; + static const unsigned char read_responses[2] = { + SSH_FXP_NAME, SSH_FXP_STATUS }; + ssize_t retcode; + + if (sftp->readdir_state == libssh2_NB_state_idle) { + if (handle->u.dir.names_left) { + /* + * A prior request returned more than one directory entry, + * feed it back from the buffer + */ + LIBSSH2_SFTP_ATTRIBUTES attrs_dummy; + size_t real_longentry_len; + size_t real_filename_len; + size_t filename_len; + size_t longentry_len; + + s = (unsigned char *) handle->u.dir.next_name; + real_filename_len = _libssh2_ntohu32(s); + + s += 4; + + filename_len = real_filename_len; + if (filename_len >= buffer_maxlen) { + filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL; + goto end; + } + + memcpy(buffer, s, filename_len); + buffer[filename_len] = '\0'; /* zero terminate */ + s += real_filename_len; + + real_longentry_len = _libssh2_ntohu32(s); + s += 4; + + if (longentry && (longentry_maxlen>1)) { + longentry_len = real_longentry_len; + + if (longentry_len >= longentry_maxlen) { + filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL; + goto end; + } + + memcpy(longentry, s, longentry_len); + longentry[longentry_len] = '\0'; /* zero terminate */ + } + s += real_longentry_len; + + if (attrs) + memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); + + s += sftp_bin2attr(attrs ? attrs : &attrs_dummy, s); + + handle->u.dir.next_name = (char *) s; + end: + + if ((--handle->u.dir.names_left) == 0) + LIBSSH2_FREE(session, handle->u.dir.names_packet); + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "libssh2_sftp_readdir_ex() return %d", + filename_len); + return (ssize_t)filename_len; + } + + /* Request another entry(entries?) */ + + s = sftp->readdir_packet = LIBSSH2_ALLOC(session, packet_len); + if (!sftp->readdir_packet) + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "FXP_READDIR packet"); + + _libssh2_store_u32(&s, packet_len - 4); + *(s++) = SSH_FXP_READDIR; + sftp->readdir_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->readdir_request_id); + _libssh2_store_str(&s, handle->handle, handle->handle_len); + + sftp->readdir_state = libssh2_NB_state_created; + } + + if (sftp->readdir_state == libssh2_NB_state_created) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Reading entries from directory handle"); + retcode = _libssh2_channel_write(channel, 0, sftp->readdir_packet, + packet_len); + if (retcode == LIBSSH2_ERROR_EAGAIN) { + return retcode; + } + else if ((ssize_t)packet_len != retcode) { + LIBSSH2_FREE(session, sftp->readdir_packet); + sftp->readdir_packet = NULL; + sftp->readdir_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "_libssh2_channel_write() failed"); + } + + LIBSSH2_FREE(session, sftp->readdir_packet); + sftp->readdir_packet = NULL; + + sftp->readdir_state = libssh2_NB_state_sent; + } + + retcode = sftp_packet_requirev(sftp, 2, read_responses, + sftp->readdir_request_id, &data, + &data_len); + if (retcode == LIBSSH2_ERROR_EAGAIN) + return retcode; + else if (retcode) { + sftp->readdir_state = libssh2_NB_state_idle; + return _libssh2_error(session, retcode, + "Timeout waiting for status message"); + } + + if (data[0] == SSH_FXP_STATUS) { + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + if (retcode == LIBSSH2_FX_EOF) { + sftp->readdir_state = libssh2_NB_state_idle; + return 0; + } + else { + sftp->last_errno = retcode; + sftp->readdir_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } + } + + sftp->readdir_state = libssh2_NB_state_idle; + + num_names = _libssh2_ntohu32(data + 5); + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "%lu entries returned", + num_names); + if (!num_names) { + LIBSSH2_FREE(session, data); + return 0; + } + + handle->u.dir.names_left = num_names; + handle->u.dir.names_packet = data; + handle->u.dir.next_name = (char *) data + 9; + + /* use the name popping mechanism from the start of the function */ + return sftp_readdir(handle, buffer, buffer_maxlen, longentry, + longentry_maxlen, attrs); +} + +/* libssh2_sftp_readdir_ex + * Read from an SFTP directory handle + */ +LIBSSH2_API int +libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *hnd, char *buffer, + size_t buffer_maxlen, char *longentry, + size_t longentry_maxlen, + LIBSSH2_SFTP_ATTRIBUTES *attrs) +{ + int rc; + if(!hnd) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, hnd->sftp->channel->session, + sftp_readdir(hnd, buffer, buffer_maxlen, longentry, + longentry_maxlen, attrs)); + return rc; +} + +/* + * sftp_write + * + * Write data to an SFTP handle. Returns the number of bytes written, or + * a negative error code. + * + * We recommend sending very large data buffers to this function! + * + * Concept: + * + * - Detect how much of the given buffer that was already sent in a previous + * call by inspecting the linked list of outgoing chunks. Make sure to skip + * passed the data that has already been taken care of. + * + * - Split all (new) outgoing data in chunks no larger than N. + * + * - Each N bytes chunk gets created as a separate SFTP packet. + * + * - Add all created outgoing packets to the linked list. + * + * - Walk through the list and send the chunks that haven't been sent, + * as many as possible until EAGAIN. Some of the chunks may have been put + * in the list in a previous invoke. + * + * - For all the chunks in the list that have been completely sent off, check + * for ACKs. If a chunk has been ACKed, it is removed from the linked + * list and the "acked" counter gets increased with that data amount. + * + * - Return TOTAL bytes acked so far. + * + * Caveats: + * - be careful: we must not return a higher number than what was given! + * + * TODO: + * Introduce an option that disables this sort of "speculative" ahead writing + * as there's a risk that it will do harm to some app. + */ + +static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer, + size_t count) +{ + LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + uint32_t retcode; + uint32_t packet_len; + unsigned char *s, *data; + ssize_t rc; + struct sftp_pipeline_chunk *chunk; + struct sftp_pipeline_chunk *next; + size_t acked = 0; + size_t org_count = count; + size_t already; + + switch(sftp->write_state) { + default: + case libssh2_NB_state_idle: + + /* Number of bytes sent off that haven't been acked and therefor we + will get passed in here again. + + Also, add up the number of bytes that actually already have been + acked but we haven't been able to return as such yet, so we will + get that data as well passed in here again. + */ + already = (size_t) (handle->u.file.offset_sent - handle->u.file.offset)+ + handle->u.file.acked; + + if(count >= already) { + /* skip the part already made into packets */ + buffer += already; + count -= already; + } + else + /* there is more data already fine than what we got in this call */ + count = 0; + + sftp->write_state = libssh2_NB_state_idle; + while(count) { + /* TODO: Possibly this should have some logic to prevent a very + very small fraction to be left but lets ignore that for now */ + uint32_t size = MIN(MAX_SFTP_OUTGOING_SIZE, count); + uint32_t request_id; + + /* 25 = packet_len(4) + packet_type(1) + request_id(4) + + handle_len(4) + offset(8) + count(4) */ + packet_len = handle->handle_len + size + 25; + + chunk = LIBSSH2_ALLOC(session, packet_len + + sizeof(struct sftp_pipeline_chunk)); + if (!chunk) + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "malloc fail for FXP_WRITE"); + + chunk->len = size; + chunk->sent = 0; + chunk->lefttosend = packet_len; + + s = chunk->packet; + _libssh2_store_u32(&s, packet_len - 4); + + *(s++) = SSH_FXP_WRITE; + request_id = sftp->request_id++; + chunk->request_id = request_id; + _libssh2_store_u32(&s, request_id); + _libssh2_store_str(&s, handle->handle, handle->handle_len); + _libssh2_store_u64(&s, handle->u.file.offset_sent); + handle->u.file.offset_sent += size; /* advance offset at once */ + _libssh2_store_str(&s, buffer, size); + + /* add this new entry LAST in the list */ + _libssh2_list_add(&handle->packet_list, &chunk->node); + + buffer += size; + count -= size; /* deduct the size we used, as we might have + to create more packets */ + } + + /* move through the WRITE packets that haven't been sent and send as many + as possible - remember that we don't block */ + chunk = _libssh2_list_first(&handle->packet_list); + + while(chunk) { + if(chunk->lefttosend) { + rc = _libssh2_channel_write(channel, 0, + &chunk->packet[chunk->sent], + chunk->lefttosend); + if(rc < 0) + /* remain in idle state */ + return rc; + + /* remember where to continue sending the next time */ + chunk->lefttosend -= rc; + chunk->sent += rc; + + if(chunk->lefttosend) + /* data left to send, get out of loop */ + break; + } + + /* move on to the next chunk with data to send */ + chunk = _libssh2_list_next(&chunk->node); + } + + /* fall-through */ + case libssh2_NB_state_sent: + + sftp->write_state = libssh2_NB_state_idle; + /* + * Count all ACKed packets + */ + chunk = _libssh2_list_first(&handle->packet_list); + + while(chunk) { + if(chunk->lefttosend) + /* if the chunk still has data left to send, we shouldn't wait + for an ACK for it just yet */ + break; + + else if(acked) + /* if we have sent data that is acked, we must return that + info before we call a function that might return EAGAIN */ + break; + + /* we check the packets in order */ + rc = sftp_packet_require(sftp, SSH_FXP_STATUS, + chunk->request_id, &data, &data_len); + if (rc < 0) { + if (rc == LIBSSH2_ERROR_EAGAIN) + sftp->write_state = libssh2_NB_state_sent; + return rc; + } + + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + + sftp->last_errno = retcode; + if (retcode == LIBSSH2_FX_OK) { + acked += chunk->len; /* number of payload data that was acked + here */ + + /* we increase the offset value for all acks */ + handle->u.file.offset += chunk->len; + + next = _libssh2_list_next(&chunk->node); + + _libssh2_list_remove(&chunk->node); /* remove from list */ + LIBSSH2_FREE(session, chunk); /* free memory */ + + chunk = next; + } + else { + /* flush all pending packets from the outgoing list */ + sftp_packetlist_flush(handle); + + /* since we return error now, the application will not get any + outstanding data acked, so we need to rewind the offset to + where the application knows it has reached with acked data */ + handle->u.file.offset -= handle->u.file.acked; + + /* then reset the offset_sent to be the same as the offset */ + handle->u.file.offset_sent = handle->u.file.offset; + + /* clear the acked counter since we can have no pending data to + ack after an error */ + handle->u.file.acked = 0; + + /* the server returned an error for that written chunk, propagate + this back to our parent function */ + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "FXP write failed"); + } + } + break; + } + + /* if there were acked data in a previous call that wasn't returned then, + add that up and try to return it all now. This can happen if the app + first sends a huge buffer of data, and then in a second call it sends a + smaller one. */ + acked += handle->u.file.acked; + + if(acked) { + ssize_t ret = MIN(acked, org_count); + /* we got data acked so return that amount, but no more than what + was asked to get sent! */ + + /* store the remainder. 'ret' is always equal to or less than 'acked' + here */ + handle->u.file.acked = acked - ret; + + return ret; + } + + else + return 0; /* nothing was acked, and no EAGAIN was received! */ +} + +/* libssh2_sftp_write + * Write data to a file handle + */ +LIBSSH2_API ssize_t +libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *hnd, const char *buffer, + size_t count) +{ + ssize_t rc; + if(!hnd) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, hnd->sftp->channel->session, + sftp_write(hnd, buffer, count)); + return rc; + +} + +static int sftp_fsync(LIBSSH2_SFTP_HANDLE *handle) +{ + LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + /* 34 = packet_len(4) + packet_type(1) + request_id(4) + + string_len(4) + strlen("fsync@openssh.com")(17) + handle_len(4) */ + uint32_t packet_len = handle->handle_len + 34; + size_t data_len; + unsigned char *packet, *s, *data; + ssize_t rc; + uint32_t retcode; + + if (sftp->fsync_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Issuing fsync command"); + s = packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_EXTENDED " + "packet"); + } + + _libssh2_store_u32(&s, packet_len - 4); + *(s++) = SSH_FXP_EXTENDED; + sftp->fsync_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->fsync_request_id); + _libssh2_store_str(&s, "fsync@openssh.com", 17); + _libssh2_store_str(&s, handle->handle, handle->handle_len); + + sftp->fsync_state = libssh2_NB_state_created; + } else { + packet = sftp->fsync_packet; + } + + if (sftp->fsync_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, packet, packet_len); + if (rc == LIBSSH2_ERROR_EAGAIN || + (0 <= rc && rc < (ssize_t)packet_len)) { + sftp->fsync_packet = packet; + return LIBSSH2_ERROR_EAGAIN; + } + + LIBSSH2_FREE(session, packet); + sftp->fsync_packet = NULL; + + if (rc < 0) { + sftp->fsync_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "_libssh2_channel_write() failed"); + } + sftp->fsync_state = libssh2_NB_state_sent; + } + + rc = sftp_packet_require(sftp, SSH_FXP_STATUS, + sftp->fsync_request_id, &data, &data_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + sftp->fsync_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Error waiting for FXP EXTENDED REPLY"); + } + + sftp->fsync_state = libssh2_NB_state_idle; + + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + + if (retcode != LIBSSH2_FX_OK) { + sftp->last_errno = retcode; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "fsync failed"); + } + + return 0; +} + +/* libssh2_sftp_fsync + * Commit data on the handle to disk. + */ +LIBSSH2_API int +libssh2_sftp_fsync(LIBSSH2_SFTP_HANDLE *hnd) +{ + int rc; + if(!hnd) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, hnd->sftp->channel->session, + sftp_fsync(hnd)); + return rc; +} + + +/* + * sftp_fstat + * + * Get or Set stat on a file + */ +static int sftp_fstat(LIBSSH2_SFTP_HANDLE *handle, + LIBSSH2_SFTP_ATTRIBUTES *attrs, int setstat) +{ + LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + /* 13 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */ + uint32_t packet_len = + handle->handle_len + 13 + (setstat ? sftp_attrsize(attrs->flags) : 0); + unsigned char *s, *data; + static const unsigned char fstat_responses[2] = + { SSH_FXP_ATTRS, SSH_FXP_STATUS }; + ssize_t rc; + + if (sftp->fstat_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Issuing %s command", + setstat ? "set-stat" : "stat"); + s = sftp->fstat_packet = LIBSSH2_ALLOC(session, packet_len); + if (!sftp->fstat_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "FSTAT/FSETSTAT packet"); + } + + _libssh2_store_u32(&s, packet_len - 4); + *(s++) = setstat ? SSH_FXP_FSETSTAT : SSH_FXP_FSTAT; + sftp->fstat_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->fstat_request_id); + _libssh2_store_str(&s, handle->handle, handle->handle_len); + + if (setstat) { + s += sftp_attr2bin(s, attrs); + } + + sftp->fstat_state = libssh2_NB_state_created; + } + + if (sftp->fstat_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, sftp->fstat_packet, + packet_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if ((ssize_t)packet_len != rc) { + LIBSSH2_FREE(session, sftp->fstat_packet); + sftp->fstat_packet = NULL; + sftp->fstat_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + (setstat ? "Unable to send FXP_FSETSTAT" + : "Unable to send FXP_FSTAT command")); + } + LIBSSH2_FREE(session, sftp->fstat_packet); + sftp->fstat_packet = NULL; + + sftp->fstat_state = libssh2_NB_state_sent; + } + + rc = sftp_packet_requirev(sftp, 2, fstat_responses, + sftp->fstat_request_id, &data, + &data_len); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + else if (rc) { + sftp->fstat_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Timeout waiting for status message"); + } + + sftp->fstat_state = libssh2_NB_state_idle; + + if (data[0] == SSH_FXP_STATUS) { + uint32_t retcode; + + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + if (retcode == LIBSSH2_FX_OK) { + return 0; + } else { + sftp->last_errno = retcode; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } + } + + sftp_bin2attr(attrs, data + 5); + LIBSSH2_FREE(session, data); + + return 0; +} + +/* libssh2_sftp_fstat_ex + * Get or Set stat on a file + */ +LIBSSH2_API int +libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *hnd, + LIBSSH2_SFTP_ATTRIBUTES *attrs, int setstat) +{ + int rc; + if(!hnd || !attrs) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, hnd->sftp->channel->session, + sftp_fstat(hnd, attrs, setstat)); + return rc; +} + + +/* libssh2_sftp_seek64 + * Set the read/write pointer to an arbitrary position within the file + */ +LIBSSH2_API void +libssh2_sftp_seek64(LIBSSH2_SFTP_HANDLE *handle, libssh2_uint64_t offset) +{ + if(!handle) + return; + if(handle->u.file.offset == offset && handle->u.file.offset_sent == offset) + return; + + handle->u.file.offset = handle->u.file.offset_sent = offset; + /* discard all pending requests and currently read data */ + sftp_packetlist_flush(handle); + + /* free the left received buffered data */ + if (handle->u.file.data_left) { + LIBSSH2_FREE(handle->sftp->channel->session, handle->u.file.data); + handle->u.file.data_left = handle->u.file.data_len = 0; + handle->u.file.data = NULL; + } + + /* reset EOF to False */ + handle->u.file.eof = FALSE; +} + +/* libssh2_sftp_seek + * Set the read/write pointer to an arbitrary position within the file + */ +LIBSSH2_API void +libssh2_sftp_seek(LIBSSH2_SFTP_HANDLE *handle, size_t offset) +{ + libssh2_sftp_seek64(handle, (libssh2_uint64_t)offset); +} + +/* libssh2_sftp_tell + * Return the current read/write pointer's offset + */ +LIBSSH2_API size_t +libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE *handle) +{ + if(!handle) + return 0; /* no handle, no size */ + + /* NOTE: this may very well truncate the size if it is larger than what + size_t can hold, so libssh2_sftp_tell64() is really the function you + should use */ + return (size_t)(handle->u.file.offset); +} + +/* libssh2_sftp_tell64 + * Return the current read/write pointer's offset + */ +LIBSSH2_API libssh2_uint64_t +libssh2_sftp_tell64(LIBSSH2_SFTP_HANDLE *handle) +{ + if(!handle) + return 0; /* no handle, no size */ + + return handle->u.file.offset; +} + +/* + * Flush all remaining incoming SFTP packets and zombies. + */ +static void sftp_packet_flush(LIBSSH2_SFTP *sftp) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + LIBSSH2_SFTP_PACKET *packet = _libssh2_list_first(&sftp->packets); + struct sftp_zombie_requests *zombie = + _libssh2_list_first(&sftp->zombie_requests); + + while(packet) { + LIBSSH2_SFTP_PACKET *next; + + /* check next struct in the list */ + next = _libssh2_list_next(&packet->node); + _libssh2_list_remove(&packet->node); + LIBSSH2_FREE(session, packet->data); + LIBSSH2_FREE(session, packet); + + packet = next; + } + + while(zombie) { + /* figure out the next node */ + struct sftp_zombie_requests *next = _libssh2_list_next(&zombie->node); + /* unlink the current one */ + _libssh2_list_remove(&zombie->node); + /* free the memory */ + LIBSSH2_FREE(session, zombie); + zombie = next; + } + +} + +/* sftp_close_handle + * + * Close a file or directory handle. + * Also frees handle resource and unlinks it from the SFTP structure. + * The handle is no longer usable after return of this function, unless + * the return value is LIBSSH2_ERROR_EAGAIN in which case this function + * should be called again. + */ +static int +sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle) +{ + LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + /* 13 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */ + uint32_t packet_len = handle->handle_len + 13; + unsigned char *s, *data = NULL; + int rc = 0; + + if (handle->close_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Closing handle"); + s = handle->close_packet = LIBSSH2_ALLOC(session, packet_len); + if (!handle->close_packet) { + handle->close_state = libssh2_NB_state_idle; + rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_CLOSE " + "packet"); + } else { + + _libssh2_store_u32(&s, packet_len - 4); + *(s++) = SSH_FXP_CLOSE; + handle->close_request_id = sftp->request_id++; + _libssh2_store_u32(&s, handle->close_request_id); + _libssh2_store_str(&s, handle->handle, handle->handle_len); + handle->close_state = libssh2_NB_state_created; + } + } + + if (handle->close_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, handle->close_packet, + packet_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if ((ssize_t)packet_len != rc) { + handle->close_state = libssh2_NB_state_idle; + rc = _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send FXP_CLOSE command"); + } else + handle->close_state = libssh2_NB_state_sent; + + LIBSSH2_FREE(session, handle->close_packet); + handle->close_packet = NULL; + } + + if (handle->close_state == libssh2_NB_state_sent) { + rc = sftp_packet_require(sftp, SSH_FXP_STATUS, + handle->close_request_id, &data, + &data_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + + } else if (rc) { + _libssh2_error(session, rc, + "Error waiting for status message"); + } + + handle->close_state = libssh2_NB_state_sent1; + } + + if(!data) { + /* if it reaches this point with data unset, something unwanted + happened for which we should have set an error code */ + assert(rc); + + } else { + int retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + + if (retcode != LIBSSH2_FX_OK) { + sftp->last_errno = retcode; + handle->close_state = libssh2_NB_state_idle; + rc = _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } + } + + /* remove this handle from the parent's list */ + _libssh2_list_remove(&handle->node); + + if ((handle->handle_type == LIBSSH2_SFTP_HANDLE_DIR) + && handle->u.dir.names_left) { + LIBSSH2_FREE(session, handle->u.dir.names_packet); + } + else { + if(handle->u.file.data) + LIBSSH2_FREE(session, handle->u.file.data); + } + + sftp_packetlist_flush(handle); + sftp->read_state = libssh2_NB_state_idle; + + handle->close_state = libssh2_NB_state_idle; + + LIBSSH2_FREE(session, handle); + + return rc; +} + +/* libssh2_sftp_close_handle + * + * Close a file or directory handle + * Also frees handle resource and unlinks it from the SFTP structure + */ +LIBSSH2_API int +libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *hnd) +{ + int rc; + if(!hnd) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, hnd->sftp->channel->session, sftp_close_handle(hnd)); + return rc; +} + +/* sftp_unlink + * Delete a file from the remote server + */ +static int sftp_unlink(LIBSSH2_SFTP *sftp, const char *filename, + size_t filename_len) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + int retcode; + /* 13 = packet_len(4) + packet_type(1) + request_id(4) + filename_len(4) */ + uint32_t packet_len = filename_len + 13; + unsigned char *s, *data; + int rc; + + if (sftp->unlink_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Unlinking %s", filename); + s = sftp->unlink_packet = LIBSSH2_ALLOC(session, packet_len); + if (!sftp->unlink_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_REMOVE " + "packet"); + } + + _libssh2_store_u32(&s, packet_len - 4); + *(s++) = SSH_FXP_REMOVE; + sftp->unlink_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->unlink_request_id); + _libssh2_store_str(&s, filename, filename_len); + sftp->unlink_state = libssh2_NB_state_created; + } + + if (sftp->unlink_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, sftp->unlink_packet, + packet_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if ((ssize_t)packet_len != rc) { + LIBSSH2_FREE(session, sftp->unlink_packet); + sftp->unlink_packet = NULL; + sftp->unlink_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send FXP_REMOVE command"); + } + LIBSSH2_FREE(session, sftp->unlink_packet); + sftp->unlink_packet = NULL; + + sftp->unlink_state = libssh2_NB_state_sent; + } + + rc = sftp_packet_require(sftp, SSH_FXP_STATUS, + sftp->unlink_request_id, &data, + &data_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if (rc) { + sftp->unlink_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Error waiting for FXP STATUS"); + } + + sftp->unlink_state = libssh2_NB_state_idle; + + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + + if (retcode == LIBSSH2_FX_OK) { + return 0; + } else { + sftp->last_errno = retcode; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } +} + +/* libssh2_sftp_unlink_ex + * Delete a file from the remote server + */ +LIBSSH2_API int +libssh2_sftp_unlink_ex(LIBSSH2_SFTP *sftp, const char *filename, + unsigned int filename_len) +{ + int rc; + if(!sftp) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, sftp->channel->session, + sftp_unlink(sftp, filename, filename_len)); + return rc; +} + +/* + * sftp_rename + * + * Rename a file on the remote server + */ +static int sftp_rename(LIBSSH2_SFTP *sftp, const char *source_filename, + unsigned int source_filename_len, + const char *dest_filename, + unsigned int dest_filename_len, long flags) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + int retcode; + uint32_t packet_len = + source_filename_len + dest_filename_len + 17 + (sftp->version >= + 5 ? 4 : 0); + /* packet_len(4) + packet_type(1) + request_id(4) + + source_filename_len(4) + dest_filename_len(4) + flags(4){SFTP5+) */ + unsigned char *data; + ssize_t rc; + + if (sftp->version < 2) { + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Server does not support RENAME"); + } + + if (sftp->rename_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Renaming %s to %s", + source_filename, dest_filename); + sftp->rename_s = sftp->rename_packet = + LIBSSH2_ALLOC(session, packet_len); + if (!sftp->rename_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_RENAME " + "packet"); + } + + _libssh2_store_u32(&sftp->rename_s, packet_len - 4); + *(sftp->rename_s++) = SSH_FXP_RENAME; + sftp->rename_request_id = sftp->request_id++; + _libssh2_store_u32(&sftp->rename_s, sftp->rename_request_id); + _libssh2_store_str(&sftp->rename_s, source_filename, + source_filename_len); + _libssh2_store_str(&sftp->rename_s, dest_filename, dest_filename_len); + + if (sftp->version >= 5) + _libssh2_store_u32(&sftp->rename_s, flags); + + sftp->rename_state = libssh2_NB_state_created; + } + + if (sftp->rename_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, sftp->rename_packet, + sftp->rename_s - sftp->rename_packet); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if ((ssize_t)packet_len != rc) { + LIBSSH2_FREE(session, sftp->rename_packet); + sftp->rename_packet = NULL; + sftp->rename_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send FXP_RENAME command"); + } + LIBSSH2_FREE(session, sftp->rename_packet); + sftp->rename_packet = NULL; + + sftp->rename_state = libssh2_NB_state_sent; + } + + rc = sftp_packet_require(sftp, SSH_FXP_STATUS, + sftp->rename_request_id, &data, + &data_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + sftp->rename_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Error waiting for FXP STATUS"); + } + + sftp->rename_state = libssh2_NB_state_idle; + + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + + sftp->last_errno = retcode; + + /* now convert the SFTP error code to libssh2 return code or error + message */ + switch (retcode) { + case LIBSSH2_FX_OK: + retcode = LIBSSH2_ERROR_NONE; + break; + + case LIBSSH2_FX_FILE_ALREADY_EXISTS: + retcode = _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "File already exists and " + "SSH_FXP_RENAME_OVERWRITE not specified"); + break; + + case LIBSSH2_FX_OP_UNSUPPORTED: + retcode = _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Operation Not Supported"); + break; + + default: + retcode = _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + break; + } + + return retcode; +} + +/* libssh2_sftp_rename_ex + * Rename a file on the remote server + */ +LIBSSH2_API int +libssh2_sftp_rename_ex(LIBSSH2_SFTP *sftp, const char *source_filename, + unsigned int source_filename_len, + const char *dest_filename, + unsigned int dest_filename_len, long flags) +{ + int rc; + if(!sftp) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, sftp->channel->session, + sftp_rename(sftp, source_filename, source_filename_len, + dest_filename, dest_filename_len, flags)); + return rc; +} + +/* + * sftp_fstatvfs + * + * Get file system statistics + */ +static int sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_STATVFS *st) +{ + LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + /* 17 = packet_len(4) + packet_type(1) + request_id(4) + ext_len(4) + + handle_len (4) */ + /* 20 = strlen ("fstatvfs@openssh.com") */ + uint32_t packet_len = handle->handle_len + 20 + 17; + unsigned char *packet, *s, *data; + ssize_t rc; + unsigned int flag; + static const unsigned char responses[2] = + { SSH_FXP_EXTENDED_REPLY, SSH_FXP_STATUS }; + + if (sftp->fstatvfs_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Getting file system statistics"); + s = packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_EXTENDED " + "packet"); + } + + _libssh2_store_u32(&s, packet_len - 4); + *(s++) = SSH_FXP_EXTENDED; + sftp->fstatvfs_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->fstatvfs_request_id); + _libssh2_store_str(&s, "fstatvfs@openssh.com", 20); + _libssh2_store_str(&s, handle->handle, handle->handle_len); + + sftp->fstatvfs_state = libssh2_NB_state_created; + } + else { + packet = sftp->fstatvfs_packet; + } + + if (sftp->fstatvfs_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, packet, packet_len); + if (rc == LIBSSH2_ERROR_EAGAIN || + (0 <= rc && rc < (ssize_t)packet_len)) { + sftp->fstatvfs_packet = packet; + return LIBSSH2_ERROR_EAGAIN; + } + + LIBSSH2_FREE(session, packet); + sftp->fstatvfs_packet = NULL; + + if (rc < 0) { + sftp->fstatvfs_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "_libssh2_channel_write() failed"); + } + sftp->fstatvfs_state = libssh2_NB_state_sent; + } + + rc = sftp_packet_requirev(sftp, 2, responses, sftp->fstatvfs_request_id, + &data, &data_len); + + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + sftp->fstatvfs_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Error waiting for FXP EXTENDED REPLY"); + } + + if (data[0] == SSH_FXP_STATUS) { + int retcode = _libssh2_ntohu32(data + 5); + sftp->fstatvfs_state = libssh2_NB_state_idle; + LIBSSH2_FREE(session, data); + sftp->last_errno = retcode; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } + + if (data_len < 93) { + LIBSSH2_FREE(session, data); + sftp->fstatvfs_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error: short response"); + } + + sftp->fstatvfs_state = libssh2_NB_state_idle; + + st->f_bsize = _libssh2_ntohu64(data + 5); + st->f_frsize = _libssh2_ntohu64(data + 13); + st->f_blocks = _libssh2_ntohu64(data + 21); + st->f_bfree = _libssh2_ntohu64(data + 29); + st->f_bavail = _libssh2_ntohu64(data + 37); + st->f_files = _libssh2_ntohu64(data + 45); + st->f_ffree = _libssh2_ntohu64(data + 53); + st->f_favail = _libssh2_ntohu64(data + 61); + st->f_fsid = _libssh2_ntohu64(data + 69); + flag = (unsigned int)_libssh2_ntohu64(data + 77); + st->f_namemax = _libssh2_ntohu64(data + 85); + + st->f_flag = (flag & SSH_FXE_STATVFS_ST_RDONLY) + ? LIBSSH2_SFTP_ST_RDONLY : 0; + st->f_flag |= (flag & SSH_FXE_STATVFS_ST_NOSUID) + ? LIBSSH2_SFTP_ST_NOSUID : 0; + + LIBSSH2_FREE(session, data); + return 0; +} + +/* libssh2_sftp_fstatvfs + * Get filesystem space and inode utilization (requires fstatvfs@openssh.com + * support on the server) + */ +LIBSSH2_API int +libssh2_sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_STATVFS *st) +{ + int rc; + if(!handle || !st) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, handle->sftp->channel->session, sftp_fstatvfs(handle, st)); + return rc; +} + +/* + * sftp_statvfs + * + * Get file system statistics + */ +static int sftp_statvfs(LIBSSH2_SFTP *sftp, const char *path, + unsigned int path_len, LIBSSH2_SFTP_STATVFS *st) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + /* 17 = packet_len(4) + packet_type(1) + request_id(4) + ext_len(4) + + path_len (4) */ + /* 19 = strlen ("statvfs@openssh.com") */ + uint32_t packet_len = path_len + 19 + 17; + unsigned char *packet, *s, *data; + ssize_t rc; + unsigned int flag; + static const unsigned char responses[2] = + { SSH_FXP_EXTENDED_REPLY, SSH_FXP_STATUS }; + + if (sftp->statvfs_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Getting file system statistics of %s", path); + s = packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_EXTENDED " + "packet"); + } + + _libssh2_store_u32(&s, packet_len - 4); + *(s++) = SSH_FXP_EXTENDED; + sftp->statvfs_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->statvfs_request_id); + _libssh2_store_str(&s, "statvfs@openssh.com", 19); + _libssh2_store_str(&s, path, path_len); + + sftp->statvfs_state = libssh2_NB_state_created; + } + else { + packet = sftp->statvfs_packet; + } + + if (sftp->statvfs_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, packet, packet_len); + if (rc == LIBSSH2_ERROR_EAGAIN || + (0 <= rc && rc < (ssize_t)packet_len)) { + sftp->statvfs_packet = packet; + return LIBSSH2_ERROR_EAGAIN; + } + + LIBSSH2_FREE(session, packet); + sftp->statvfs_packet = NULL; + + if (rc < 0) { + sftp->statvfs_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "_libssh2_channel_write() failed"); + } + sftp->statvfs_state = libssh2_NB_state_sent; + } + + rc = sftp_packet_requirev(sftp, 2, responses, sftp->statvfs_request_id, + &data, &data_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + sftp->statvfs_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Error waiting for FXP EXTENDED REPLY"); + } + + if (data[0] == SSH_FXP_STATUS) { + int retcode = _libssh2_ntohu32(data + 5); + sftp->statvfs_state = libssh2_NB_state_idle; + LIBSSH2_FREE(session, data); + sftp->last_errno = retcode; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } + + if (data_len < 93) { + LIBSSH2_FREE(session, data); + sftp->statvfs_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error: short response"); + } + + sftp->statvfs_state = libssh2_NB_state_idle; + + st->f_bsize = _libssh2_ntohu64(data + 5); + st->f_frsize = _libssh2_ntohu64(data + 13); + st->f_blocks = _libssh2_ntohu64(data + 21); + st->f_bfree = _libssh2_ntohu64(data + 29); + st->f_bavail = _libssh2_ntohu64(data + 37); + st->f_files = _libssh2_ntohu64(data + 45); + st->f_ffree = _libssh2_ntohu64(data + 53); + st->f_favail = _libssh2_ntohu64(data + 61); + st->f_fsid = _libssh2_ntohu64(data + 69); + flag = (unsigned int)_libssh2_ntohu64(data + 77); + st->f_namemax = _libssh2_ntohu64(data + 85); + + st->f_flag = (flag & SSH_FXE_STATVFS_ST_RDONLY) + ? LIBSSH2_SFTP_ST_RDONLY : 0; + st->f_flag |= (flag & SSH_FXE_STATVFS_ST_NOSUID) + ? LIBSSH2_SFTP_ST_NOSUID : 0; + + LIBSSH2_FREE(session, data); + return 0; +} + +/* libssh2_sftp_statvfs_ex + * Get filesystem space and inode utilization (requires statvfs@openssh.com + * support on the server) + */ +LIBSSH2_API int +libssh2_sftp_statvfs(LIBSSH2_SFTP *sftp, const char *path, + size_t path_len, LIBSSH2_SFTP_STATVFS *st) +{ + int rc; + if(!sftp || !st) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, sftp->channel->session, sftp_statvfs(sftp, path, path_len, + st)); + return rc; +} + + +/* + * sftp_mkdir + * + * Create an SFTP directory + */ +static int sftp_mkdir(LIBSSH2_SFTP *sftp, const char *path, + unsigned int path_len, long mode) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + LIBSSH2_SFTP_ATTRIBUTES attrs = { + LIBSSH2_SFTP_ATTR_PERMISSIONS, 0, 0, 0, 0, 0, 0 + }; + size_t data_len; + int retcode; + /* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */ + ssize_t packet_len = path_len + 13 + + sftp_attrsize(LIBSSH2_SFTP_ATTR_PERMISSIONS); + unsigned char *packet, *s, *data; + int rc; + + if (sftp->mkdir_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Creating directory %s with mode 0%lo", path, mode); + s = packet = LIBSSH2_ALLOC(session, packet_len); + if (!packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_MKDIR " + "packet"); + } + /* Filetype in SFTP 3 and earlier */ + attrs.permissions = mode | LIBSSH2_SFTP_ATTR_PFILETYPE_DIR; + + _libssh2_store_u32(&s, packet_len - 4); + *(s++) = SSH_FXP_MKDIR; + sftp->mkdir_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->mkdir_request_id); + _libssh2_store_str(&s, path, path_len); + + s += sftp_attr2bin(s, &attrs); + + sftp->mkdir_state = libssh2_NB_state_created; + } + else { + packet = sftp->mkdir_packet; + } + + if (sftp->mkdir_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, packet, packet_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + sftp->mkdir_packet = packet; + return rc; + } + if (packet_len != rc) { + LIBSSH2_FREE(session, packet); + sftp->mkdir_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "_libssh2_channel_write() failed"); + } + LIBSSH2_FREE(session, packet); + sftp->mkdir_state = libssh2_NB_state_sent; + sftp->mkdir_packet = NULL; + } + + rc = sftp_packet_require(sftp, SSH_FXP_STATUS, sftp->mkdir_request_id, + &data, &data_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + sftp->mkdir_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Error waiting for FXP STATUS"); + } + + sftp->mkdir_state = libssh2_NB_state_idle; + + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + + if (retcode == LIBSSH2_FX_OK) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "OK!"); + return 0; + } else { + sftp->last_errno = retcode; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } +} + +/* + * libssh2_sftp_mkdir_ex + * + * Create an SFTP directory + */ +LIBSSH2_API int +libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, const char *path, + unsigned int path_len, long mode) +{ + int rc; + if(!sftp) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, sftp->channel->session, + sftp_mkdir(sftp, path, path_len, mode)); + return rc; +} + +/* sftp_rmdir + * Remove a directory + */ +static int sftp_rmdir(LIBSSH2_SFTP *sftp, const char *path, + unsigned int path_len) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + int retcode; + /* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */ + ssize_t packet_len = path_len + 13; + unsigned char *s, *data; + int rc; + + if (sftp->rmdir_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Removing directory: %s", + path); + s = sftp->rmdir_packet = LIBSSH2_ALLOC(session, packet_len); + if (!sftp->rmdir_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_RMDIR " + "packet"); + } + + _libssh2_store_u32(&s, packet_len - 4); + *(s++) = SSH_FXP_RMDIR; + sftp->rmdir_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->rmdir_request_id); + _libssh2_store_str(&s, path, path_len); + + sftp->rmdir_state = libssh2_NB_state_created; + } + + if (sftp->rmdir_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, sftp->rmdir_packet, + packet_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (packet_len != rc) { + LIBSSH2_FREE(session, sftp->rmdir_packet); + sftp->rmdir_packet = NULL; + sftp->rmdir_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send FXP_RMDIR command"); + } + LIBSSH2_FREE(session, sftp->rmdir_packet); + sftp->rmdir_packet = NULL; + + sftp->rmdir_state = libssh2_NB_state_sent; + } + + rc = sftp_packet_require(sftp, SSH_FXP_STATUS, + sftp->rmdir_request_id, &data, &data_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (rc) { + sftp->rmdir_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Error waiting for FXP STATUS"); + } + + sftp->rmdir_state = libssh2_NB_state_idle; + + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + + if (retcode == LIBSSH2_FX_OK) { + return 0; + } else { + sftp->last_errno = retcode; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } +} + +/* libssh2_sftp_rmdir_ex + * Remove a directory + */ +LIBSSH2_API int +libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp, const char *path, + unsigned int path_len) +{ + int rc; + if(!sftp) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, sftp->channel->session, + sftp_rmdir(sftp, path, path_len)); + return rc; +} + +/* sftp_stat + * Stat a file or symbolic link + */ +static int sftp_stat(LIBSSH2_SFTP *sftp, const char *path, + unsigned int path_len, int stat_type, + LIBSSH2_SFTP_ATTRIBUTES * attrs) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + /* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */ + ssize_t packet_len = + path_len + 13 + + ((stat_type == + LIBSSH2_SFTP_SETSTAT) ? sftp_attrsize(attrs->flags) : 0); + unsigned char *s, *data; + static const unsigned char stat_responses[2] = + { SSH_FXP_ATTRS, SSH_FXP_STATUS }; + int rc; + + if (sftp->stat_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "%s %s", + (stat_type == LIBSSH2_SFTP_SETSTAT) ? "Set-statting" : + (stat_type == + LIBSSH2_SFTP_LSTAT ? "LStatting" : "Statting"), path); + s = sftp->stat_packet = LIBSSH2_ALLOC(session, packet_len); + if (!sftp->stat_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_*STAT " + "packet"); + } + + _libssh2_store_u32(&s, packet_len - 4); + + switch (stat_type) { + case LIBSSH2_SFTP_SETSTAT: + *(s++) = SSH_FXP_SETSTAT; + break; + + case LIBSSH2_SFTP_LSTAT: + *(s++) = SSH_FXP_LSTAT; + break; + + case LIBSSH2_SFTP_STAT: + default: + *(s++) = SSH_FXP_STAT; + } + sftp->stat_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->stat_request_id); + _libssh2_store_str(&s, path, path_len); + + if (stat_type == LIBSSH2_SFTP_SETSTAT) + s += sftp_attr2bin(s, attrs); + + sftp->stat_state = libssh2_NB_state_created; + } + + if (sftp->stat_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, sftp->stat_packet, packet_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } else if (packet_len != rc) { + LIBSSH2_FREE(session, sftp->stat_packet); + sftp->stat_packet = NULL; + sftp->stat_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send STAT/LSTAT/SETSTAT command"); + } + LIBSSH2_FREE(session, sftp->stat_packet); + sftp->stat_packet = NULL; + + sftp->stat_state = libssh2_NB_state_sent; + } + + rc = sftp_packet_requirev(sftp, 2, stat_responses, + sftp->stat_request_id, &data, &data_len); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + else if (rc) { + sftp->stat_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Timeout waiting for status message"); + } + + sftp->stat_state = libssh2_NB_state_idle; + + if (data[0] == SSH_FXP_STATUS) { + int retcode; + + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + if (retcode == LIBSSH2_FX_OK) { + return 0; + } else { + sftp->last_errno = retcode; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } + } + + memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); + sftp_bin2attr(attrs, data + 5); + LIBSSH2_FREE(session, data); + + return 0; +} + +/* libssh2_sftp_stat_ex + * Stat a file or symbolic link + */ +LIBSSH2_API int +libssh2_sftp_stat_ex(LIBSSH2_SFTP *sftp, const char *path, + unsigned int path_len, int stat_type, + LIBSSH2_SFTP_ATTRIBUTES *attrs) +{ + int rc; + if(!sftp) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, sftp->channel->session, + sftp_stat(sftp, path, path_len, stat_type, attrs)); + return rc; +} + +/* sftp_symlink + * Read or set a symlink + */ +static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path, + unsigned int path_len, char *target, + unsigned int target_len, int link_type) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len, link_len; + /* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */ + ssize_t packet_len = + path_len + 13 + + ((link_type == LIBSSH2_SFTP_SYMLINK) ? (4 + target_len) : 0); + unsigned char *s, *data; + static const unsigned char link_responses[2] = + { SSH_FXP_NAME, SSH_FXP_STATUS }; + int retcode; + + if ((sftp->version < 3) && (link_type != LIBSSH2_SFTP_REALPATH)) { + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Server does not support SYMLINK or READLINK"); + } + + if (sftp->symlink_state == libssh2_NB_state_idle) { + s = sftp->symlink_packet = LIBSSH2_ALLOC(session, packet_len); + if (!sftp->symlink_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "SYMLINK/READLINK/REALPATH packet"); + } + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "%s %s on %s", + (link_type == + LIBSSH2_SFTP_SYMLINK) ? "Creating" : "Reading", + (link_type == + LIBSSH2_SFTP_REALPATH) ? "realpath" : "symlink", path); + + _libssh2_store_u32(&s, packet_len - 4); + + switch (link_type) { + case LIBSSH2_SFTP_REALPATH: + *(s++) = SSH_FXP_REALPATH; + break; + + case LIBSSH2_SFTP_SYMLINK: + *(s++) = SSH_FXP_SYMLINK; + break; + + case LIBSSH2_SFTP_READLINK: + default: + *(s++) = SSH_FXP_READLINK; + } + sftp->symlink_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->symlink_request_id); + _libssh2_store_str(&s, path, path_len); + + if (link_type == LIBSSH2_SFTP_SYMLINK) + _libssh2_store_str(&s, target, target_len); + + sftp->symlink_state = libssh2_NB_state_created; + } + + if (sftp->symlink_state == libssh2_NB_state_created) { + ssize_t rc = _libssh2_channel_write(channel, 0, sftp->symlink_packet, + packet_len); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + else if (packet_len != rc) { + LIBSSH2_FREE(session, sftp->symlink_packet); + sftp->symlink_packet = NULL; + sftp->symlink_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send SYMLINK/READLINK command"); + } + LIBSSH2_FREE(session, sftp->symlink_packet); + sftp->symlink_packet = NULL; + + sftp->symlink_state = libssh2_NB_state_sent; + } + + retcode = sftp_packet_requirev(sftp, 2, link_responses, + sftp->symlink_request_id, &data, + &data_len); + if (retcode == LIBSSH2_ERROR_EAGAIN) + return retcode; + else if (retcode) { + sftp->symlink_state = libssh2_NB_state_idle; + return _libssh2_error(session, retcode, + "Error waiting for status message"); + } + + sftp->symlink_state = libssh2_NB_state_idle; + + if (data[0] == SSH_FXP_STATUS) { + int retcode; + + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + if (retcode == LIBSSH2_FX_OK) + return LIBSSH2_ERROR_NONE; + else { + sftp->last_errno = retcode; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } + } + + if (_libssh2_ntohu32(data + 5) < 1) { + LIBSSH2_FREE(session, data); + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Invalid READLINK/REALPATH response, " + "no name entries"); + } + + /* this reads a u32 and stores it into a signed 32bit value */ + link_len = _libssh2_ntohu32(data + 9); + if (link_len < target_len) { + memcpy(target, data + 13, link_len); + target[link_len] = 0; + retcode = (int)link_len; + } + else + retcode = LIBSSH2_ERROR_BUFFER_TOO_SMALL; + LIBSSH2_FREE(session, data); + + return retcode; +} + +/* libssh2_sftp_symlink_ex + * Read or set a symlink + */ +LIBSSH2_API int +libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp, const char *path, + unsigned int path_len, char *target, + unsigned int target_len, int link_type) +{ + int rc; + if(!sftp) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, sftp->channel->session, + sftp_symlink(sftp, path, path_len, target, target_len, + link_type)); + return rc; +} + +/* libssh2_sftp_last_error + * Returns the last error code reported by SFTP + */ +LIBSSH2_API unsigned long +libssh2_sftp_last_error(LIBSSH2_SFTP *sftp) +{ + if(!sftp) + return 0; + + return sftp->last_errno; +} + +/* libssh2_sftp_get_channel + * Return the channel of sftp, then caller can control the channel's behavior. + */ +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_sftp_get_channel(LIBSSH2_SFTP *sftp) +{ + if (!sftp) + return NULL; + + return sftp->channel; +} diff --git a/libssh2/transport.c b/libssh2/transport.c new file mode 100644 index 0000000..8725da0 --- /dev/null +++ b/libssh2/transport.c @@ -0,0 +1,891 @@ +/* Copyright (C) 2007 The Written Word, Inc. All rights reserved. + * Copyright (C) 2009-2010 by Daniel Stenberg + * Author: Daniel Stenberg + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file handles reading and writing to the SECSH transport layer. RFC4253. + */ + +#include "libssh2_priv.h" +#include +#include +#include +#ifdef LIBSSH2DEBUG +#include +#endif + +#include + +#include "transport.h" +#include "mac.h" + +#define MAX_BLOCKSIZE 32 /* MUST fit biggest crypto block size we use/get */ +#define MAX_MACSIZE 64 /* MUST fit biggest MAC length we support */ + +#ifdef LIBSSH2DEBUG +#define UNPRINTABLE_CHAR '.' +static void +debugdump(LIBSSH2_SESSION * session, + const char *desc, const unsigned char *ptr, size_t size) +{ + size_t i; + size_t c; + unsigned int width = 0x10; + char buffer[256]; /* Must be enough for width*4 + about 30 or so */ + size_t used; + static const char* hex_chars = "0123456789ABCDEF"; + + if (!(session->showmask & LIBSSH2_TRACE_TRANS)) { + /* not asked for, bail out */ + return; + } + + used = snprintf(buffer, sizeof(buffer), "=> %s (%d bytes)\n", + desc, (int) size); + if (session->tracehandler) + (session->tracehandler)(session, session->tracehandler_context, + buffer, used); + else + fprintf(stderr, "%s", buffer); + + for(i = 0; i < size; i += width) { + + used = snprintf(buffer, sizeof(buffer), "%04lx: ", (long)i); + + /* hex not disabled, show it */ + for(c = 0; c < width; c++) { + if (i + c < size) { + buffer[used++] = hex_chars[(ptr[i+c] >> 4) & 0xF]; + buffer[used++] = hex_chars[ptr[i+c] & 0xF]; + } + else { + buffer[used++] = ' '; + buffer[used++] = ' '; + } + + buffer[used++] = ' '; + if ((width/2) - 1 == c) + buffer[used++] = ' '; + } + + buffer[used++] = ':'; + buffer[used++] = ' '; + + for(c = 0; (c < width) && (i + c < size); c++) { + buffer[used++] = isprint(ptr[i + c]) ? + ptr[i + c] : UNPRINTABLE_CHAR; + } + buffer[used++] = '\n'; + buffer[used] = 0; + + if (session->tracehandler) + (session->tracehandler)(session, session->tracehandler_context, + buffer, used); + else + fprintf(stderr, "%s", buffer); + } +} +#else +#define debugdump(a,x,y,z) +#endif + + +/* decrypt() decrypts 'len' bytes from 'source' to 'dest'. + * + * returns 0 on success and negative on failure + */ + +static int +decrypt(LIBSSH2_SESSION * session, unsigned char *source, + unsigned char *dest, int len) +{ + struct transportpacket *p = &session->packet; + int blocksize = session->remote.crypt->blocksize; + + /* if we get called with a len that isn't an even number of blocksizes + we risk losing those extra bytes */ + assert((len % blocksize) == 0); + + while (len >= blocksize) { + if (session->remote.crypt->crypt(session, source, blocksize, + &session->remote.crypt_abstract)) { + LIBSSH2_FREE(session, p->payload); + return LIBSSH2_ERROR_DECRYPT; + } + + /* if the crypt() function would write to a given address it + wouldn't have to memcpy() and we could avoid this memcpy() + too */ + memcpy(dest, source, blocksize); + + len -= blocksize; /* less bytes left */ + dest += blocksize; /* advance write pointer */ + source += blocksize; /* advance read pointer */ + } + return LIBSSH2_ERROR_NONE; /* all is fine */ +} + +/* + * fullpacket() gets called when a full packet has been received and properly + * collected. + */ +static int +fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ ) +{ + unsigned char macbuf[MAX_MACSIZE]; + struct transportpacket *p = &session->packet; + int rc; + int compressed; + + if (session->fullpacket_state == libssh2_NB_state_idle) { + session->fullpacket_macstate = LIBSSH2_MAC_CONFIRMED; + session->fullpacket_payload_len = p->packet_length - 1; + + if (encrypted) { + + /* Calculate MAC hash */ + session->remote.mac->hash(session, macbuf, /* store hash here */ + session->remote.seqno, + p->init, 5, + p->payload, + session->fullpacket_payload_len, + &session->remote.mac_abstract); + + /* Compare the calculated hash with the MAC we just read from + * the network. The read one is at the very end of the payload + * buffer. Note that 'payload_len' here is the packet_length + * field which includes the padding but not the MAC. + */ + if (memcmp(macbuf, p->payload + session->fullpacket_payload_len, + session->remote.mac->mac_len)) { + session->fullpacket_macstate = LIBSSH2_MAC_INVALID; + } + } + + session->remote.seqno++; + + /* ignore the padding */ + session->fullpacket_payload_len -= p->padding_length; + + /* Check for and deal with decompression */ + compressed = + session->local.comp != NULL && + session->local.comp->compress && + ((session->state & LIBSSH2_STATE_AUTHENTICATED) || + session->local.comp->use_in_auth); + + if (compressed && session->remote.comp_abstract) { + /* + * The buffer for the decompression (remote.comp_abstract) is + * initialised in time when it is needed so as long it is NULL we + * cannot decompress. + */ + + unsigned char *data; + size_t data_len; + rc = session->remote.comp->decomp(session, + &data, &data_len, + LIBSSH2_PACKET_MAXDECOMP, + p->payload, + session->fullpacket_payload_len, + &session->remote.comp_abstract); + LIBSSH2_FREE(session, p->payload); + if(rc) + return rc; + + p->payload = data; + session->fullpacket_payload_len = data_len; + } + + session->fullpacket_packet_type = p->payload[0]; + + debugdump(session, "libssh2_transport_read() plain", + p->payload, session->fullpacket_payload_len); + + session->fullpacket_state = libssh2_NB_state_created; + } + + if (session->fullpacket_state == libssh2_NB_state_created) { + rc = _libssh2_packet_add(session, p->payload, + session->fullpacket_payload_len, + session->fullpacket_macstate); + if (rc == LIBSSH2_ERROR_EAGAIN) + return rc; + if (rc) { + session->fullpacket_state = libssh2_NB_state_idle; + return rc; + } + } + + session->fullpacket_state = libssh2_NB_state_idle; + + return session->fullpacket_packet_type; +} + + +/* + * _libssh2_transport_read + * + * Collect a packet into the input queue. + * + * Returns packet type added to input queue (0 if nothing added), or a + * negative error number. + */ + +/* + * This function reads the binary stream as specified in chapter 6 of RFC4253 + * "The Secure Shell (SSH) Transport Layer Protocol" + * + * DOES NOT call _libssh2_error() for ANY error case. + */ +int _libssh2_transport_read(LIBSSH2_SESSION * session) +{ + int rc; + struct transportpacket *p = &session->packet; + int remainbuf; + int remainpack; + int numbytes; + int numdecrypt; + unsigned char block[MAX_BLOCKSIZE]; + int blocksize; + int encrypted = 1; + size_t total_num; + + /* default clear the bit */ + session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_INBOUND; + + /* + * All channels, systems, subsystems, etc eventually make it down here + * when looking for more incoming data. If a key exchange is going on + * (LIBSSH2_STATE_EXCHANGING_KEYS bit is set) then the remote end will + * ONLY send key exchange related traffic. In non-blocking mode, there is + * a chance to break out of the kex_exchange function with an EAGAIN + * status, and never come back to it. If LIBSSH2_STATE_EXCHANGING_KEYS is + * active, then we must redirect to the key exchange. However, if + * kex_exchange is active (as in it is the one that calls this execution + * of packet_read, then don't redirect, as that would be an infinite loop! + */ + + if (session->state & LIBSSH2_STATE_EXCHANGING_KEYS && + !(session->state & LIBSSH2_STATE_KEX_ACTIVE)) { + + /* Whoever wants a packet won't get anything until the key re-exchange + * is done! + */ + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Redirecting into the" + " key re-exchange from _libssh2_transport_read"); + rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state); + if (rc) + return rc; + } + + /* + * =============================== NOTE =============================== + * I know this is very ugly and not a really good use of "goto", but + * this case statement would be even uglier to do it any other way + */ + if (session->readPack_state == libssh2_NB_state_jump1) { + session->readPack_state = libssh2_NB_state_idle; + encrypted = session->readPack_encrypted; + goto libssh2_transport_read_point1; + } + + do { + if (session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) { + return LIBSSH2_ERROR_NONE; + } + + if (session->state & LIBSSH2_STATE_NEWKEYS) { + blocksize = session->remote.crypt->blocksize; + } else { + encrypted = 0; /* not encrypted */ + blocksize = 5; /* not strictly true, but we can use 5 here to + make the checks below work fine still */ + } + + /* read/use a whole big chunk into a temporary area stored in + the LIBSSH2_SESSION struct. We will decrypt data from that + buffer into the packet buffer so this temp one doesn't have + to be able to keep a whole SSH packet, just be large enough + so that we can read big chunks from the network layer. */ + + /* how much data there is remaining in the buffer to deal with + before we should read more from the network */ + remainbuf = p->writeidx - p->readidx; + + /* if remainbuf turns negative we have a bad internal error */ + assert(remainbuf >= 0); + + if (remainbuf < blocksize) { + /* If we have less than a blocksize left, it is too + little data to deal with, read more */ + ssize_t nread; + + /* move any remainder to the start of the buffer so + that we can do a full refill */ + if (remainbuf) { + memmove(p->buf, &p->buf[p->readidx], remainbuf); + p->readidx = 0; + p->writeidx = remainbuf; + } else { + /* nothing to move, just zero the indexes */ + p->readidx = p->writeidx = 0; + } + + /* now read a big chunk from the network into the temp buffer */ + nread = + LIBSSH2_RECV(session, &p->buf[remainbuf], + PACKETBUFSIZE - remainbuf, + LIBSSH2_SOCKET_RECV_FLAGS(session)); + if (nread <= 0) { + /* check if this is due to EAGAIN and return the special + return code if so, error out normally otherwise */ + if ((nread < 0) && (nread == -EAGAIN)) { + session->socket_block_directions |= + LIBSSH2_SESSION_BLOCK_INBOUND; + return LIBSSH2_ERROR_EAGAIN; + } + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Error recving %d bytes (got %d)", + PACKETBUFSIZE - remainbuf, -nread); + return LIBSSH2_ERROR_SOCKET_RECV; + } + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Recved %d/%d bytes to %p+%d", nread, + PACKETBUFSIZE - remainbuf, p->buf, remainbuf); + + debugdump(session, "libssh2_transport_read() raw", + &p->buf[remainbuf], nread); + /* advance write pointer */ + p->writeidx += nread; + + /* update remainbuf counter */ + remainbuf = p->writeidx - p->readidx; + } + + /* how much data to deal with from the buffer */ + numbytes = remainbuf; + + if (!p->total_num) { + /* No payload package area allocated yet. To know the + size of this payload, we need to decrypt the first + blocksize data. */ + + if (numbytes < blocksize) { + /* we can't act on anything less than blocksize, but this + check is only done for the initial block since once we have + got the start of a block we can in fact deal with fractions + */ + session->socket_block_directions |= + LIBSSH2_SESSION_BLOCK_INBOUND; + return LIBSSH2_ERROR_EAGAIN; + } + + if (encrypted) { + rc = decrypt(session, &p->buf[p->readidx], block, blocksize); + if (rc != LIBSSH2_ERROR_NONE) { + return rc; + } + /* save the first 5 bytes of the decrypted package, to be + used in the hash calculation later down. */ + memcpy(p->init, &p->buf[p->readidx], 5); + } else { + /* the data is plain, just copy it verbatim to + the working block buffer */ + memcpy(block, &p->buf[p->readidx], blocksize); + } + + /* advance the read pointer */ + p->readidx += blocksize; + + /* we now have the initial blocksize bytes decrypted, + * and we can extract packet and padding length from it + */ + p->packet_length = _libssh2_ntohu32(block); + if (p->packet_length < 1) + return LIBSSH2_ERROR_DECRYPT; + + p->padding_length = block[4]; + + /* total_num is the number of bytes following the initial + (5 bytes) packet length and padding length fields */ + total_num = + p->packet_length - 1 + + (encrypted ? session->remote.mac->mac_len : 0); + + /* RFC4253 section 6.1 Maximum Packet Length says: + * + * "All implementations MUST be able to process + * packets with uncompressed payload length of 32768 + * bytes or less and total packet size of 35000 bytes + * or less (including length, padding length, payload, + * padding, and MAC.)." + */ + if (total_num > LIBSSH2_PACKET_MAXPAYLOAD) { + return LIBSSH2_ERROR_OUT_OF_BOUNDARY; + } + + /* Get a packet handle put data into. We get one to + hold all data, including padding and MAC. */ + p->payload = LIBSSH2_ALLOC(session, total_num); + if (!p->payload) { + return LIBSSH2_ERROR_ALLOC; + } + p->total_num = total_num; + /* init write pointer to start of payload buffer */ + p->wptr = p->payload; + + if (blocksize > 5) { + /* copy the data from index 5 to the end of + the blocksize from the temporary buffer to + the start of the decrypted buffer */ + memcpy(p->wptr, &block[5], blocksize - 5); + p->wptr += blocksize - 5; /* advance write pointer */ + } + + /* init the data_num field to the number of bytes of + the package read so far */ + p->data_num = p->wptr - p->payload; + + /* we already dealt with a blocksize worth of data */ + numbytes -= blocksize; + } + + /* how much there is left to add to the current payload + package */ + remainpack = p->total_num - p->data_num; + + if (numbytes > remainpack) { + /* if we have more data in the buffer than what is going into this + particular packet, we limit this round to this packet only */ + numbytes = remainpack; + } + + if (encrypted) { + /* At the end of the incoming stream, there is a MAC, + and we don't want to decrypt that since we need it + "raw". We MUST however decrypt the padding data + since it is used for the hash later on. */ + int skip = session->remote.mac->mac_len; + + /* if what we have plus numbytes is bigger than the + total minus the skip margin, we should lower the + amount to decrypt even more */ + if ((p->data_num + numbytes) > (p->total_num - skip)) { + numdecrypt = (p->total_num - skip) - p->data_num; + } else { + int frac; + numdecrypt = numbytes; + frac = numdecrypt % blocksize; + if (frac) { + /* not an aligned amount of blocks, + align it */ + numdecrypt -= frac; + /* and make it no unencrypted data + after it */ + numbytes = 0; + } + } + } else { + /* unencrypted data should not be decrypted at all */ + numdecrypt = 0; + } + + /* if there are bytes to decrypt, do that */ + if (numdecrypt > 0) { + /* now decrypt the lot */ + rc = decrypt(session, &p->buf[p->readidx], p->wptr, numdecrypt); + if (rc != LIBSSH2_ERROR_NONE) { + p->total_num = 0; /* no packet buffer available */ + return rc; + } + + /* advance the read pointer */ + p->readidx += numdecrypt; + /* advance write pointer */ + p->wptr += numdecrypt; + /* increase data_num */ + p->data_num += numdecrypt; + + /* bytes left to take care of without decryption */ + numbytes -= numdecrypt; + } + + /* if there are bytes to copy that aren't decrypted, simply + copy them as-is to the target buffer */ + if (numbytes > 0) { + memcpy(p->wptr, &p->buf[p->readidx], numbytes); + + /* advance the read pointer */ + p->readidx += numbytes; + /* advance write pointer */ + p->wptr += numbytes; + /* increase data_num */ + p->data_num += numbytes; + } + + /* now check how much data there's left to read to finish the + current packet */ + remainpack = p->total_num - p->data_num; + + if (!remainpack) { + /* we have a full packet */ + libssh2_transport_read_point1: + rc = fullpacket(session, encrypted); + if (rc == LIBSSH2_ERROR_EAGAIN) { + + if (session->packAdd_state != libssh2_NB_state_idle) + { + /* fullpacket only returns LIBSSH2_ERROR_EAGAIN if + * libssh2_packet_add returns LIBSSH2_ERROR_EAGAIN. If that + * returns LIBSSH2_ERROR_EAGAIN but the packAdd_state is idle, + * then the packet has been added to the brigade, but some + * immediate action that was taken based on the packet + * type (such as key re-exchange) is not yet complete. + * Clear the way for a new packet to be read in. + */ + session->readPack_encrypted = encrypted; + session->readPack_state = libssh2_NB_state_jump1; + } + + return rc; + } + + p->total_num = 0; /* no packet buffer available */ + + return rc; + } + } while (1); /* loop */ + + return LIBSSH2_ERROR_SOCKET_RECV; /* we never reach this point */ +} + +static int +send_existing(LIBSSH2_SESSION *session, const unsigned char *data, + size_t data_len, ssize_t *ret) +{ + ssize_t rc; + ssize_t length; + struct transportpacket *p = &session->packet; + + if (!p->olen) { + *ret = 0; + return LIBSSH2_ERROR_NONE; + } + + /* send as much as possible of the existing packet */ + if ((data != p->odata) || (data_len != p->olen)) { + /* When we are about to complete the sending of a packet, it is vital + that the caller doesn't try to send a new/different packet since + we don't add this one up until the previous one has been sent. To + make the caller really notice his/hers flaw, we return error for + this case */ + return LIBSSH2_ERROR_BAD_USE; + } + + *ret = 1; /* set to make our parent return */ + + /* number of bytes left to send */ + length = p->ototal_num - p->osent; + + rc = LIBSSH2_SEND(session, &p->outbuf[p->osent], length, + LIBSSH2_SOCKET_SEND_FLAGS(session)); + if (rc < 0) + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Error sending %d bytes: %d", length, -rc); + else { + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Sent %d/%d bytes at %p+%d", rc, length, p->outbuf, + p->osent); + debugdump(session, "libssh2_transport_write send()", + &p->outbuf[p->osent], rc); + } + + if (rc == length) { + /* the remainder of the package was sent */ + p->ototal_num = 0; + p->olen = 0; + /* we leave *ret set so that the parent returns as we MUST return back + a send success now, so that we don't risk sending EAGAIN later + which then would confuse the parent function */ + return LIBSSH2_ERROR_NONE; + + } + else if (rc < 0) { + /* nothing was sent */ + if (rc != -EAGAIN) + /* send failure! */ + return LIBSSH2_ERROR_SOCKET_SEND; + + session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_OUTBOUND; + return LIBSSH2_ERROR_EAGAIN; + } + + p->osent += rc; /* we sent away this much data */ + + return rc < length ? LIBSSH2_ERROR_EAGAIN : LIBSSH2_ERROR_NONE; +} + +/* + * libssh2_transport_send + * + * Send a packet, encrypting it and adding a MAC code if necessary + * Returns 0 on success, non-zero on failure. + * + * The data is provided as _two_ data areas that are combined by this + * function. The 'data' part is sent immediately before 'data2'. 'data2' may + * be set to NULL to only use a single part. + * + * Returns LIBSSH2_ERROR_EAGAIN if it would block or if the whole packet was + * not sent yet. If it does so, the caller should call this function again as + * soon as it is likely that more data can be sent, and this function MUST + * then be called with the same argument set (same data pointer and same + * data_len) until ERROR_NONE or failure is returned. + * + * This function DOES NOT call _libssh2_error() on any errors. + */ +int _libssh2_transport_send(LIBSSH2_SESSION *session, + const unsigned char *data, size_t data_len, + const unsigned char *data2, size_t data2_len) +{ + int blocksize = + (session->state & LIBSSH2_STATE_NEWKEYS) ? + session->local.crypt->blocksize : 8; + int padding_length; + size_t packet_length; + int total_length; +#ifdef RANDOM_PADDING + int rand_max; + int seed = data[0]; /* FIXME: make this random */ +#endif + struct transportpacket *p = &session->packet; + int encrypted; + int compressed; + ssize_t ret; + int rc; + const unsigned char *orgdata = data; + size_t orgdata_len = data_len; + + /* + * If the last read operation was interrupted in the middle of a key + * exchange, we must complete that key exchange before continuing to write + * further data. + * + * See the similar block in _libssh2_transport_read for more details. + */ + if (session->state & LIBSSH2_STATE_EXCHANGING_KEYS && + !(session->state & LIBSSH2_STATE_KEX_ACTIVE)) { + /* Don't write any new packets if we're still in the middle of a key + * exchange. */ + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Redirecting into the" + " key re-exchange from _libssh2_transport_send"); + rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state); + if (rc) + return rc; + } + + debugdump(session, "libssh2_transport_write plain", data, data_len); + if(data2) + debugdump(session, "libssh2_transport_write plain2", data2, data2_len); + + /* FIRST, check if we have a pending write to complete. send_existing + only sanity-check data and data_len and not data2 and data2_len!! */ + rc = send_existing(session, data, data_len, &ret); + if (rc) + return rc; + + session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_OUTBOUND; + + if (ret) + /* set by send_existing if data was sent */ + return rc; + + encrypted = (session->state & LIBSSH2_STATE_NEWKEYS) ? 1 : 0; + + compressed = + session->local.comp != NULL && + session->local.comp->compress && + ((session->state & LIBSSH2_STATE_AUTHENTICATED) || + session->local.comp->use_in_auth); + + if (encrypted && compressed) { + /* the idea here is that these function must fail if the output gets + larger than what fits in the assigned buffer so thus they don't + check the input size as we don't know how much it compresses */ + size_t dest_len = MAX_SSH_PACKET_LEN-5-256; + size_t dest2_len = dest_len; + + /* compress directly to the target buffer */ + rc = session->local.comp->comp(session, + &p->outbuf[5], &dest_len, + data, data_len, + &session->local.comp_abstract); + if(rc) + return rc; /* compression failure */ + + if(data2 && data2_len) { + /* compress directly to the target buffer right after where the + previous call put data */ + dest2_len -= dest_len; + + rc = session->local.comp->comp(session, + &p->outbuf[5+dest_len], &dest2_len, + data2, data2_len, + &session->local.comp_abstract); + } + else + dest2_len = 0; + if(rc) + return rc; /* compression failure */ + + data_len = dest_len + dest2_len; /* use the combined length */ + } + else { + if((data_len + data2_len) >= (MAX_SSH_PACKET_LEN-0x100)) + /* too large packet, return error for this until we make this + function split it up and send multiple SSH packets */ + return LIBSSH2_ERROR_INVAL; + + /* copy the payload data */ + memcpy(&p->outbuf[5], data, data_len); + if(data2 && data2_len) + memcpy(&p->outbuf[5+data_len], data2, data2_len); + data_len += data2_len; /* use the combined length */ + } + + + /* RFC4253 says: Note that the length of the concatenation of + 'packet_length', 'padding_length', 'payload', and 'random padding' + MUST be a multiple of the cipher block size or 8, whichever is + larger. */ + + /* Plain math: (4 + 1 + packet_length + padding_length) % blocksize == 0 */ + + packet_length = data_len + 1 + 4; /* 1 is for padding_length field + 4 for the packet_length field */ + + /* at this point we have it all except the padding */ + + /* first figure out our minimum padding amount to make it an even + block size */ + padding_length = blocksize - (packet_length % blocksize); + + /* if the padding becomes too small we add another blocksize worth + of it (taken from the original libssh2 where it didn't have any + real explanation) */ + if (padding_length < 4) { + padding_length += blocksize; + } +#ifdef RANDOM_PADDING + /* FIXME: we can add padding here, but that also makes the packets + bigger etc */ + + /* now we can add 'blocksize' to the padding_length N number of times + (to "help thwart traffic analysis") but it must be less than 255 in + total */ + rand_max = (255 - padding_length) / blocksize + 1; + padding_length += blocksize * (seed % rand_max); +#endif + + packet_length += padding_length; + + /* append the MAC length to the total_length size */ + total_length = + packet_length + (encrypted ? session->local.mac->mac_len : 0); + + /* store packet_length, which is the size of the whole packet except + the MAC and the packet_length field itself */ + _libssh2_htonu32(p->outbuf, packet_length - 4); + /* store padding_length */ + p->outbuf[4] = (unsigned char)padding_length; + + /* fill the padding area with random junk */ + _libssh2_random(p->outbuf + 5 + data_len, padding_length); + + if (encrypted) { + size_t i; + + /* Calculate MAC hash. Put the output at index packet_length, + since that size includes the whole packet. The MAC is + calculated on the entire unencrypted packet, including all + fields except the MAC field itself. */ + session->local.mac->hash(session, p->outbuf + packet_length, + session->local.seqno, p->outbuf, + packet_length, NULL, 0, + &session->local.mac_abstract); + + /* Encrypt the whole packet data, one block size at a time. + The MAC field is not encrypted. */ + for(i = 0; i < packet_length; i += session->local.crypt->blocksize) { + unsigned char *ptr = &p->outbuf[i]; + if (session->local.crypt->crypt(session, ptr, + session->local.crypt->blocksize, + &session->local.crypt_abstract)) + return LIBSSH2_ERROR_ENCRYPT; /* encryption failure */ + } + } + + session->local.seqno++; + + ret = LIBSSH2_SEND(session, p->outbuf, total_length, + LIBSSH2_SOCKET_SEND_FLAGS(session)); + if (ret < 0) + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Error sending %d bytes: %d", total_length, -ret); + else { + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, "Sent %d/%d bytes at %p", + ret, total_length, p->outbuf); + debugdump(session, "libssh2_transport_write send()", p->outbuf, ret); + } + + if (ret != total_length) { + if (ret >= 0 || ret == -EAGAIN) { + /* the whole packet could not be sent, save the rest */ + session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_OUTBOUND; + p->odata = orgdata; + p->olen = orgdata_len; + p->osent = ret <= 0 ? 0 : ret; + p->ototal_num = total_length; + return LIBSSH2_ERROR_EAGAIN; + } + return LIBSSH2_ERROR_SOCKET_SEND; + } + + /* the whole thing got sent away */ + p->odata = NULL; + p->olen = 0; + + return LIBSSH2_ERROR_NONE; /* all is good */ +} diff --git a/libssh2/userauth.c b/libssh2/userauth.c new file mode 100644 index 0000000..67bb9d2 --- /dev/null +++ b/libssh2/userauth.c @@ -0,0 +1,1914 @@ +/* Copyright (c) 2004-2007, Sara Golemon + * Copyright (c) 2005 Mikhail Gusarov + * Copyright (c) 2009-2014 by Daniel Stenberg + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" + +#include +#include + +#include + +/* Needed for struct iovec on some platforms */ +#ifdef HAVE_SYS_UIO_H +#include +#endif + +#include "transport.h" +#include "session.h" +#include "userauth.h" + +/* libssh2_userauth_list + * + * List authentication methods + * Will yield successful login if "none" happens to be allowable for this user + * Not a common configuration for any SSH server though + * username should be NULL, or a null terminated string + */ +static char *userauth_list(LIBSSH2_SESSION *session, const char *username, + unsigned int username_len) +{ + static const unsigned char reply_codes[3] = + { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 }; + /* packet_type(1) + username_len(4) + service_len(4) + + service(14)"ssh-connection" + method_len(4) = 27 */ + unsigned long methods_len; + unsigned char *s; + int rc; + + if (session->userauth_list_state == libssh2_NB_state_idle) { + /* Zero the whole thing out */ + memset(&session->userauth_list_packet_requirev_state, 0, + sizeof(session->userauth_list_packet_requirev_state)); + + session->userauth_list_data_len = username_len + 27; + + s = session->userauth_list_data = + LIBSSH2_ALLOC(session, session->userauth_list_data_len); + if (!session->userauth_list_data) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for userauth_list"); + return NULL; + } + + *(s++) = SSH_MSG_USERAUTH_REQUEST; + _libssh2_store_str(&s, username, username_len); + _libssh2_store_str(&s, "ssh-connection", 14); + _libssh2_store_u32(&s, 4); /* send "none" separately */ + + session->userauth_list_state = libssh2_NB_state_created; + } + + if (session->userauth_list_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, session->userauth_list_data, + session->userauth_list_data_len, + (unsigned char *)"none", 4); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block requesting userauth list"); + return NULL; + } + /* now free the packet that was sent */ + LIBSSH2_FREE(session, session->userauth_list_data); + session->userauth_list_data = NULL; + + if (rc) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send userauth-none request"); + session->userauth_list_state = libssh2_NB_state_idle; + return NULL; + } + + session->userauth_list_state = libssh2_NB_state_sent; + } + + if (session->userauth_list_state == libssh2_NB_state_sent) { + rc = _libssh2_packet_requirev(session, reply_codes, + &session->userauth_list_data, + &session->userauth_list_data_len, 0, + NULL, 0, + &session->userauth_list_packet_requirev_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block requesting userauth list"); + return NULL; + } else if (rc) { + _libssh2_error(session, rc, "Failed getting response"); + session->userauth_list_state = libssh2_NB_state_idle; + return NULL; + } + + if (session->userauth_list_data[0] == SSH_MSG_USERAUTH_SUCCESS) { + /* Wow, who'dve thought... */ + _libssh2_error(session, LIBSSH2_ERROR_NONE, "No error"); + LIBSSH2_FREE(session, session->userauth_list_data); + session->userauth_list_data = NULL; + session->state |= LIBSSH2_STATE_AUTHENTICATED; + session->userauth_list_state = libssh2_NB_state_idle; + return NULL; + } + + methods_len = _libssh2_ntohu32(session->userauth_list_data + 1); + + /* Do note that the memory areas overlap! */ + memmove(session->userauth_list_data, session->userauth_list_data + 5, + methods_len); + session->userauth_list_data[methods_len] = '\0'; + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Permitted auth methods: %s", + session->userauth_list_data); + } + + session->userauth_list_state = libssh2_NB_state_idle; + return (char *) session->userauth_list_data; +} + +/* libssh2_userauth_list + * + * List authentication methods + * Will yield successful login if "none" happens to be allowable for this user + * Not a common configuration for any SSH server though + * username should be NULL, or a null terminated string + */ +LIBSSH2_API char * +libssh2_userauth_list(LIBSSH2_SESSION * session, const char *user, + unsigned int user_len) +{ + char *ptr; + BLOCK_ADJUST_ERRNO(ptr, session, + userauth_list(session, user, user_len)); + return ptr; +} + +/* + * libssh2_userauth_authenticated + * + * Returns: 0 if not yet authenticated + * 1 if already authenticated + */ +LIBSSH2_API int +libssh2_userauth_authenticated(LIBSSH2_SESSION * session) +{ + return (session->state & LIBSSH2_STATE_AUTHENTICATED)?1:0; +} + + + +/* userauth_password + * Plain ol' login + */ +static int +userauth_password(LIBSSH2_SESSION *session, + const char *username, unsigned int username_len, + const unsigned char *password, unsigned int password_len, + LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb))) +{ + unsigned char *s; + static const unsigned char reply_codes[4] = + { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, + SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, 0 + }; + int rc; + + if (session->userauth_pswd_state == libssh2_NB_state_idle) { + /* Zero the whole thing out */ + memset(&session->userauth_pswd_packet_requirev_state, 0, + sizeof(session->userauth_pswd_packet_requirev_state)); + + /* + * 40 = packet_type(1) + username_len(4) + service_len(4) + + * service(14)"ssh-connection" + method_len(4) + method(8)"password" + + * chgpwdbool(1) + password_len(4) */ + session->userauth_pswd_data_len = username_len + 40; + + session->userauth_pswd_data0 = + (unsigned char) ~SSH_MSG_USERAUTH_PASSWD_CHANGEREQ; + + /* TODO: remove this alloc with a fixed buffer in the session + struct */ + s = session->userauth_pswd_data = + LIBSSH2_ALLOC(session, session->userauth_pswd_data_len); + if (!session->userauth_pswd_data) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "userauth-password request"); + } + + *(s++) = SSH_MSG_USERAUTH_REQUEST; + _libssh2_store_str(&s, username, username_len); + _libssh2_store_str(&s, "ssh-connection", sizeof("ssh-connection") - 1); + _libssh2_store_str(&s, "password", sizeof("password") - 1); + *s++ = '\0'; + _libssh2_store_u32(&s, password_len); + /* 'password' is sent separately */ + + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Attempting to login using password authentication"); + + session->userauth_pswd_state = libssh2_NB_state_created; + } + + if (session->userauth_pswd_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, session->userauth_pswd_data, + session->userauth_pswd_data_len, + password, password_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block writing password request"); + } + + /* now free the sent packet */ + LIBSSH2_FREE(session, session->userauth_pswd_data); + session->userauth_pswd_data = NULL; + + if (rc) { + session->userauth_pswd_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send userauth-password request"); + } + + session->userauth_pswd_state = libssh2_NB_state_sent; + } + + password_response: + + if ((session->userauth_pswd_state == libssh2_NB_state_sent) + || (session->userauth_pswd_state == libssh2_NB_state_sent1) + || (session->userauth_pswd_state == libssh2_NB_state_sent2)) { + if (session->userauth_pswd_state == libssh2_NB_state_sent) { + rc = _libssh2_packet_requirev(session, reply_codes, + &session->userauth_pswd_data, + &session->userauth_pswd_data_len, + 0, NULL, 0, + &session-> + userauth_pswd_packet_requirev_state); + + if (rc) { + if (rc != LIBSSH2_ERROR_EAGAIN) + session->userauth_pswd_state = libssh2_NB_state_idle; + + return _libssh2_error(session, rc, + "Waiting for password response"); + } + + if (session->userauth_pswd_data[0] == SSH_MSG_USERAUTH_SUCCESS) { + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Password authentication successful"); + LIBSSH2_FREE(session, session->userauth_pswd_data); + session->userauth_pswd_data = NULL; + session->state |= LIBSSH2_STATE_AUTHENTICATED; + session->userauth_pswd_state = libssh2_NB_state_idle; + return 0; + } else if (session->userauth_pswd_data[0] == SSH_MSG_USERAUTH_FAILURE) { + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Password authentication failed"); + LIBSSH2_FREE(session, session->userauth_pswd_data); + session->userauth_pswd_data = NULL; + session->userauth_pswd_state = libssh2_NB_state_idle; + return _libssh2_error(session, + LIBSSH2_ERROR_AUTHENTICATION_FAILED, + "Authentication failed " + "(username/password)"); + } + + session->userauth_pswd_newpw = NULL; + session->userauth_pswd_newpw_len = 0; + + session->userauth_pswd_state = libssh2_NB_state_sent1; + } + + if ((session->userauth_pswd_data[0] == + SSH_MSG_USERAUTH_PASSWD_CHANGEREQ) + || (session->userauth_pswd_data0 == + SSH_MSG_USERAUTH_PASSWD_CHANGEREQ)) { + session->userauth_pswd_data0 = SSH_MSG_USERAUTH_PASSWD_CHANGEREQ; + + if ((session->userauth_pswd_state == libssh2_NB_state_sent1) || + (session->userauth_pswd_state == libssh2_NB_state_sent2)) { + if (session->userauth_pswd_state == libssh2_NB_state_sent1) { + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Password change required"); + LIBSSH2_FREE(session, session->userauth_pswd_data); + session->userauth_pswd_data = NULL; + } + if (passwd_change_cb) { + if (session->userauth_pswd_state == libssh2_NB_state_sent1) { + passwd_change_cb(session, + &session->userauth_pswd_newpw, + &session->userauth_pswd_newpw_len, + &session->abstract); + if (!session->userauth_pswd_newpw) { + return _libssh2_error(session, + LIBSSH2_ERROR_PASSWORD_EXPIRED, + "Password expired, and " + "callback failed"); + } + + /* basic data_len + newpw_len(4) */ + session->userauth_pswd_data_len = + username_len + password_len + 44; + + s = session->userauth_pswd_data = + LIBSSH2_ALLOC(session, + session->userauth_pswd_data_len); + if (!session->userauth_pswd_data) { + LIBSSH2_FREE(session, + session->userauth_pswd_newpw); + session->userauth_pswd_newpw = NULL; + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory " + "for userauth password " + "change request"); + } + + *(s++) = SSH_MSG_USERAUTH_REQUEST; + _libssh2_store_str(&s, username, username_len); + _libssh2_store_str(&s, "ssh-connection", + sizeof("ssh-connection") - 1); + _libssh2_store_str(&s, "password", + sizeof("password") - 1); + *s++ = 0x01; + _libssh2_store_str(&s, (char *)password, password_len); + _libssh2_store_u32(&s, + session->userauth_pswd_newpw_len); + /* send session->userauth_pswd_newpw separately */ + + session->userauth_pswd_state = libssh2_NB_state_sent2; + } + + if (session->userauth_pswd_state == libssh2_NB_state_sent2) { + rc = _libssh2_transport_send(session, + session->userauth_pswd_data, + session->userauth_pswd_data_len, + (unsigned char *) + session->userauth_pswd_newpw, + session->userauth_pswd_newpw_len); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting"); + } + + /* free the allocated packets again */ + LIBSSH2_FREE(session, session->userauth_pswd_data); + session->userauth_pswd_data = NULL; + LIBSSH2_FREE(session, session->userauth_pswd_newpw); + session->userauth_pswd_newpw = NULL; + + if (rc) { + return _libssh2_error(session, + LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send userauth " + "password-change request"); + } + + /* + * Ugliest use of goto ever. Blame it on the + * askN => requirev migration. + */ + session->userauth_pswd_state = libssh2_NB_state_sent; + goto password_response; + } + } + } else { + session->userauth_pswd_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_PASSWORD_EXPIRED, + "Password Expired, and no callback " + "specified"); + } + } + } + + /* FAILURE */ + LIBSSH2_FREE(session, session->userauth_pswd_data); + session->userauth_pswd_data = NULL; + session->userauth_pswd_state = libssh2_NB_state_idle; + + return _libssh2_error(session, LIBSSH2_ERROR_AUTHENTICATION_FAILED, + "Authentication failed"); +} + +/* + * libssh2_userauth_password_ex + * + * Plain ol' login + */ + +LIBSSH2_API int +libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const char *username, + unsigned int username_len, const char *password, + unsigned int password_len, + LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb))) +{ + int rc; + BLOCK_ADJUST(rc, session, + userauth_password(session, username, username_len, + (unsigned char *)password, password_len, + passwd_change_cb)); + return rc; +} + +static int +memory_read_publickey(LIBSSH2_SESSION * session, unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *pubkeyfiledata, + size_t pubkeyfiledata_len) +{ + unsigned char *pubkey = NULL, *sp1, *sp2, *tmp; + size_t pubkey_len = pubkeyfiledata_len; + unsigned int tmp_len; + + if (pubkeyfiledata_len <= 1) { + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Invalid data in public key file"); + } + + pubkey = LIBSSH2_ALLOC(session, pubkeyfiledata_len); + if (!pubkey) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for public key data"); + } + + memcpy(pubkey, pubkeyfiledata, pubkeyfiledata_len); + + /* + * Remove trailing whitespace + */ + while (pubkey_len && isspace(pubkey[pubkey_len - 1])) + pubkey_len--; + + if (!pubkey_len) { + LIBSSH2_FREE(session, pubkey); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Missing public key data"); + } + + if ((sp1 = memchr(pubkey, ' ', pubkey_len)) == NULL) { + LIBSSH2_FREE(session, pubkey); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Invalid public key data"); + } + + sp1++; + + if ((sp2 = memchr(sp1, ' ', pubkey_len - (sp1 - pubkey - 1))) == NULL) { + /* Assume that the id string is missing, but that it's okay */ + sp2 = pubkey + pubkey_len; + } + + if (libssh2_base64_decode(session, (char **) &tmp, &tmp_len, + (char *) sp1, sp2 - sp1)) { + LIBSSH2_FREE(session, pubkey); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Invalid key data, not base64 encoded"); + } + + /* Wasting some bytes here (okay, more than some), but since it's likely + * to be freed soon anyway, we'll just avoid the extra free/alloc and call + * it a wash + */ + *method = pubkey; + *method_len = sp1 - pubkey - 1; + + *pubkeydata = tmp; + *pubkeydata_len = tmp_len; + + return 0; +} + +/* + * file_read_publickey + * + * Read a public key from an id_???.pub style file + * + * Returns an allocated string containing the decoded key in *pubkeydata + * on success. + * Returns an allocated string containing the key method (e.g. "ssh-dss") + * in method on success. + */ +static int +file_read_publickey(LIBSSH2_SESSION * session, unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *pubkeyfile) +{ + FILE *fd; + char c; + unsigned char *pubkey = NULL, *sp1, *sp2, *tmp; + size_t pubkey_len = 0, sp_len; + unsigned int tmp_len; + + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, "Loading public key file: %s", + pubkeyfile); + /* Read Public Key */ + fd = fopen(pubkeyfile, "r"); + if (!fd) { + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to open public key file"); + } + while (!feof(fd) && 1 == fread(&c, 1, 1, fd) && c != '\r' && c != '\n') { + pubkey_len++; + } + rewind(fd); + + if (pubkey_len <= 1) { + fclose(fd); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Invalid data in public key file"); + } + + pubkey = LIBSSH2_ALLOC(session, pubkey_len); + if (!pubkey) { + fclose(fd); + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for public key data"); + } + if (fread(pubkey, 1, pubkey_len, fd) != pubkey_len) { + LIBSSH2_FREE(session, pubkey); + fclose(fd); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to read public key from file"); + } + fclose(fd); + /* + * Remove trailing whitespace + */ + while (pubkey_len && isspace(pubkey[pubkey_len - 1])) { + pubkey_len--; + } + + if (!pubkey_len) { + LIBSSH2_FREE(session, pubkey); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Missing public key data"); + } + + if ((sp1 = memchr(pubkey, ' ', pubkey_len)) == NULL) { + LIBSSH2_FREE(session, pubkey); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Invalid public key data"); + } + + sp1++; + + sp_len = sp1 > pubkey ? (sp1 - pubkey) - 1 : 0; + if ((sp2 = memchr(sp1, ' ', pubkey_len - sp_len)) == NULL) { + /* Assume that the id string is missing, but that it's okay */ + sp2 = pubkey + pubkey_len; + } + + if (libssh2_base64_decode(session, (char **) &tmp, &tmp_len, + (char *) sp1, sp2 - sp1)) { + LIBSSH2_FREE(session, pubkey); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Invalid key data, not base64 encoded"); + } + + /* Wasting some bytes here (okay, more than some), but since it's likely + * to be freed soon anyway, we'll just avoid the extra free/alloc and call + * it a wash */ + *method = pubkey; + *method_len = sp1 - pubkey - 1; + + *pubkeydata = tmp; + *pubkeydata_len = tmp_len; + + return 0; +} + +static int +memory_read_privatekey(LIBSSH2_SESSION * session, + const LIBSSH2_HOSTKEY_METHOD ** hostkey_method, + void **hostkey_abstract, + const unsigned char *method, int method_len, + const char *privkeyfiledata, size_t privkeyfiledata_len, + const char *passphrase) +{ + const LIBSSH2_HOSTKEY_METHOD **hostkey_methods_avail = + libssh2_hostkey_methods(); + + *hostkey_method = NULL; + *hostkey_abstract = NULL; + while (*hostkey_methods_avail && (*hostkey_methods_avail)->name) { + if ((*hostkey_methods_avail)->initPEMFromMemory + && strncmp((*hostkey_methods_avail)->name, (const char *) method, + method_len) == 0) { + *hostkey_method = *hostkey_methods_avail; + break; + } + hostkey_methods_avail++; + } + if (!*hostkey_method) { + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE, + "No handler for specified private key"); + } + + if ((*hostkey_method)-> + initPEMFromMemory(session, privkeyfiledata, privkeyfiledata_len, + (unsigned char *) passphrase, + hostkey_abstract)) { + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to initialize private key from file"); + } + + return 0; +} + +/* libssh2_file_read_privatekey + * Read a PEM encoded private key from an id_??? style file + */ +static int +file_read_privatekey(LIBSSH2_SESSION * session, + const LIBSSH2_HOSTKEY_METHOD ** hostkey_method, + void **hostkey_abstract, + const unsigned char *method, int method_len, + const char *privkeyfile, const char *passphrase) +{ + const LIBSSH2_HOSTKEY_METHOD **hostkey_methods_avail = + libssh2_hostkey_methods(); + + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, "Loading private key file: %s", + privkeyfile); + *hostkey_method = NULL; + *hostkey_abstract = NULL; + while (*hostkey_methods_avail && (*hostkey_methods_avail)->name) { + if ((*hostkey_methods_avail)->initPEM + && strncmp((*hostkey_methods_avail)->name, (const char *) method, + method_len) == 0) { + *hostkey_method = *hostkey_methods_avail; + break; + } + hostkey_methods_avail++; + } + if (!*hostkey_method) { + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE, + "No handler for specified private key"); + } + + if ((*hostkey_method)-> + initPEM(session, privkeyfile, (unsigned char *) passphrase, + hostkey_abstract)) { + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to initialize private key from file"); + } + + return 0; +} + +struct privkey_file { + const char *filename; + const char *passphrase; +}; + +static int +sign_frommemory(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, + const unsigned char *data, size_t data_len, void **abstract) +{ + struct privkey_file *pk_file = (struct privkey_file *) (*abstract); + const LIBSSH2_HOSTKEY_METHOD *privkeyobj; + void *hostkey_abstract; + struct iovec datavec; + int rc; + + rc = memory_read_privatekey(session, &privkeyobj, &hostkey_abstract, + session->userauth_pblc_method, + session->userauth_pblc_method_len, + pk_file->filename, + strlen(pk_file->filename), + pk_file->passphrase); + if(rc) + return rc; + + datavec.iov_base = (void *)data; + datavec.iov_len = data_len; + + if (privkeyobj->signv(session, sig, sig_len, 1, &datavec, + &hostkey_abstract)) { + if (privkeyobj->dtor) { + privkeyobj->dtor(session, abstract); + } + return -1; + } + + if (privkeyobj->dtor) { + privkeyobj->dtor(session, &hostkey_abstract); + } + return 0; +} + +static int +sign_fromfile(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, + const unsigned char *data, size_t data_len, void **abstract) +{ + struct privkey_file *privkey_file = (struct privkey_file *) (*abstract); + const LIBSSH2_HOSTKEY_METHOD *privkeyobj; + void *hostkey_abstract; + struct iovec datavec; + int rc; + + rc = file_read_privatekey(session, &privkeyobj, &hostkey_abstract, + session->userauth_pblc_method, + session->userauth_pblc_method_len, + privkey_file->filename, + privkey_file->passphrase); + if(rc) + return rc; + + datavec.iov_base = (void *)data; + datavec.iov_len = data_len; + + if (privkeyobj->signv(session, sig, sig_len, 1, &datavec, + &hostkey_abstract)) { + if (privkeyobj->dtor) { + privkeyobj->dtor(session, &hostkey_abstract); + } + return -1; + } + + if (privkeyobj->dtor) { + privkeyobj->dtor(session, &hostkey_abstract); + } + return 0; +} + + + +/* userauth_hostbased_fromfile + * Authenticate using a keypair found in the named files + */ +static int +userauth_hostbased_fromfile(LIBSSH2_SESSION *session, + const char *username, size_t username_len, + const char *publickey, const char *privatekey, + const char *passphrase, const char *hostname, + size_t hostname_len, + const char *local_username, + size_t local_username_len) +{ + int rc; + + if (session->userauth_host_state == libssh2_NB_state_idle) { + const LIBSSH2_HOSTKEY_METHOD *privkeyobj; + unsigned char *pubkeydata, *sig = NULL; + size_t pubkeydata_len = 0; + size_t sig_len = 0; + void *abstract; + unsigned char buf[5]; + struct iovec datavec[4]; + + /* Zero the whole thing out */ + memset(&session->userauth_host_packet_requirev_state, 0, + sizeof(session->userauth_host_packet_requirev_state)); + + if (publickey) { + rc = file_read_publickey(session, &session->userauth_host_method, + &session->userauth_host_method_len, + &pubkeydata, &pubkeydata_len, publickey); + if(rc) + /* Note: file_read_publickey() calls _libssh2_error() */ + return rc; + } + else { + /* Compute public key from private key. */ + rc = _libssh2_pub_priv_keyfile(session, + &session->userauth_host_method, + &session->userauth_host_method_len, + &pubkeydata, &pubkeydata_len, + privatekey, passphrase); + if (rc) + /* libssh2_pub_priv_keyfile calls _libssh2_error() */ + return rc; + } + + /* + * 52 = packet_type(1) + username_len(4) + servicename_len(4) + + * service_name(14)"ssh-connection" + authmethod_len(4) + + * authmethod(9)"hostbased" + method_len(4) + pubkeydata_len(4) + + * hostname_len(4) + local_username_len(4) + */ + session->userauth_host_packet_len = + username_len + session->userauth_host_method_len + hostname_len + + local_username_len + pubkeydata_len + 52; + + /* + * Preallocate space for an overall length, method name again, + * and the signature, which won't be any larger than the size of + * the publickeydata itself + */ + session->userauth_host_s = session->userauth_host_packet = + LIBSSH2_ALLOC(session, + session->userauth_host_packet_len + 4 + + (4 + session->userauth_host_method_len) + + (4 + pubkeydata_len)); + if (!session->userauth_host_packet) { + LIBSSH2_FREE(session, session->userauth_host_method); + session->userauth_host_method = NULL; + LIBSSH2_FREE(session, pubkeydata); + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Out of memory"); + } + + *(session->userauth_host_s++) = SSH_MSG_USERAUTH_REQUEST; + _libssh2_store_str(&session->userauth_host_s, username, username_len); + _libssh2_store_str(&session->userauth_host_s, "ssh-connection", 14); + _libssh2_store_str(&session->userauth_host_s, "hostbased", 9); + _libssh2_store_str(&session->userauth_host_s, + (const char *)session->userauth_host_method, + session->userauth_host_method_len); + _libssh2_store_str(&session->userauth_host_s, (const char *)pubkeydata, + pubkeydata_len); + LIBSSH2_FREE(session, pubkeydata); + _libssh2_store_str(&session->userauth_host_s, hostname, hostname_len); + _libssh2_store_str(&session->userauth_host_s, local_username, + local_username_len); + + rc = file_read_privatekey(session, &privkeyobj, &abstract, + session->userauth_host_method, + session->userauth_host_method_len, + privatekey, passphrase); + if(rc) { + /* Note: file_read_privatekey() calls _libssh2_error() */ + LIBSSH2_FREE(session, session->userauth_host_method); + session->userauth_host_method = NULL; + LIBSSH2_FREE(session, session->userauth_host_packet); + session->userauth_host_packet = NULL; + return rc; + } + + _libssh2_htonu32(buf, session->session_id_len); + datavec[0].iov_base = (void *)buf; + datavec[0].iov_len = 4; + datavec[1].iov_base = (void *)session->session_id; + datavec[1].iov_len = session->session_id_len; + datavec[2].iov_base = (void *)session->userauth_host_packet; + datavec[2].iov_len = session->userauth_host_packet_len; + + if (privkeyobj && privkeyobj->signv && + privkeyobj->signv(session, &sig, &sig_len, 3, + datavec, &abstract)) { + LIBSSH2_FREE(session, session->userauth_host_method); + session->userauth_host_method = NULL; + LIBSSH2_FREE(session, session->userauth_host_packet); + session->userauth_host_packet = NULL; + if (privkeyobj->dtor) { + privkeyobj->dtor(session, &abstract); + } + return -1; + } + + if (privkeyobj && privkeyobj->dtor) { + privkeyobj->dtor(session, &abstract); + } + + if (sig_len > pubkeydata_len) { + unsigned char *newpacket; + /* Should *NEVER* happen, but...well.. better safe than sorry */ + newpacket = LIBSSH2_REALLOC(session, session->userauth_host_packet, + session->userauth_host_packet_len + 4 + + (4 + session->userauth_host_method_len) + + (4 + sig_len)); /* PK sigblob */ + if (!newpacket) { + LIBSSH2_FREE(session, sig); + LIBSSH2_FREE(session, session->userauth_host_packet); + session->userauth_host_packet = NULL; + LIBSSH2_FREE(session, session->userauth_host_method); + session->userauth_host_method = NULL; + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Failed allocating additional space for " + "userauth-hostbased packet"); + } + session->userauth_host_packet = newpacket; + } + + session->userauth_host_s = + session->userauth_host_packet + session->userauth_host_packet_len; + + _libssh2_store_u32(&session->userauth_host_s, + 4 + session->userauth_host_method_len + 4 + sig_len); + _libssh2_store_str(&session->userauth_host_s, + (const char *)session->userauth_host_method, + session->userauth_host_method_len); + LIBSSH2_FREE(session, session->userauth_host_method); + session->userauth_host_method = NULL; + + _libssh2_store_str(&session->userauth_host_s, (const char *)sig, + sig_len); + LIBSSH2_FREE(session, sig); + + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Attempting hostbased authentication"); + + session->userauth_host_state = libssh2_NB_state_created; + } + + if (session->userauth_host_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, session->userauth_host_packet, + session->userauth_host_s - + session->userauth_host_packet, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); + } + else if (rc) { + LIBSSH2_FREE(session, session->userauth_host_packet); + session->userauth_host_packet = NULL; + session->userauth_host_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send userauth-hostbased request"); + } + LIBSSH2_FREE(session, session->userauth_host_packet); + session->userauth_host_packet = NULL; + + session->userauth_host_state = libssh2_NB_state_sent; + } + + if (session->userauth_host_state == libssh2_NB_state_sent) { + static const unsigned char reply_codes[3] = + { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 }; + size_t data_len; + rc = _libssh2_packet_requirev(session, reply_codes, + &session->userauth_host_data, + &data_len, 0, NULL, 0, + &session-> + userauth_host_packet_requirev_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); + } + + session->userauth_host_state = libssh2_NB_state_idle; + if (rc) { + return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, + "Auth failed"); + } + + if (session->userauth_host_data[0] == SSH_MSG_USERAUTH_SUCCESS) { + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Hostbased authentication successful"); + /* We are us and we've proved it. */ + LIBSSH2_FREE(session, session->userauth_host_data); + session->userauth_host_data = NULL; + session->state |= LIBSSH2_STATE_AUTHENTICATED; + return 0; + } + } + + /* This public key is not allowed for this user on this server */ + LIBSSH2_FREE(session, session->userauth_host_data); + session->userauth_host_data = NULL; + return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, + "Invalid signature for supplied public key, or bad " + "username/public key combination"); +} + +/* libssh2_userauth_hostbased_fromfile_ex + * Authenticate using a keypair found in the named files + */ +LIBSSH2_API int +libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session, + const char *user, + unsigned int user_len, + const char *publickey, + const char *privatekey, + const char *passphrase, + const char *host, + unsigned int host_len, + const char *localuser, + unsigned int localuser_len) +{ + int rc; + BLOCK_ADJUST(rc, session, + userauth_hostbased_fromfile(session, user, user_len, + publickey, privatekey, + passphrase, host, host_len, + localuser, localuser_len)); + return rc; +} + + + +int +_libssh2_userauth_publickey(LIBSSH2_SESSION *session, + const char *username, + unsigned int username_len, + const unsigned char *pubkeydata, + unsigned long pubkeydata_len, + LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*sign_callback)), + void *abstract) +{ + unsigned char reply_codes[4] = + { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, + SSH_MSG_USERAUTH_PK_OK, 0 + }; + int rc; + unsigned char *s; + + if (session->userauth_pblc_state == libssh2_NB_state_idle) { + + /* + * The call to _libssh2_ntohu32 later relies on pubkeydata having at + * least 4 valid bytes containing the length of the method name. + */ + if (pubkeydata_len < 4) + return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, + "Invalid public key, too short"); + + /* Zero the whole thing out */ + memset(&session->userauth_pblc_packet_requirev_state, 0, + sizeof(session->userauth_pblc_packet_requirev_state)); + + /* + * As an optimisation, userauth_publickey_fromfile reuses a + * previously allocated copy of the method name to avoid an extra + * allocation/free. + * For other uses, we allocate and populate it here. + */ + if (!session->userauth_pblc_method) { + session->userauth_pblc_method_len = _libssh2_ntohu32(pubkeydata); + + if(session->userauth_pblc_method_len > pubkeydata_len) + /* the method length simply cannot be longer than the entire + passed in data, so we use this to detect crazy input + data */ + return _libssh2_error(session, + LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, + "Invalid public key"); + + session->userauth_pblc_method = + LIBSSH2_ALLOC(session, session->userauth_pblc_method_len); + if (!session->userauth_pblc_method) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for public key " + "data"); + } + memcpy(session->userauth_pblc_method, pubkeydata + 4, + session->userauth_pblc_method_len); + } + /* + * The length of the method name read from plaintext prefix in the + * file must match length embedded in the key. + * TODO: The data should match too but we don't check that. Should we? + */ + else if (session->userauth_pblc_method_len != + _libssh2_ntohu32(pubkeydata)) + return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, + "Invalid public key"); + + /* + * 45 = packet_type(1) + username_len(4) + servicename_len(4) + + * service_name(14)"ssh-connection" + authmethod_len(4) + + * authmethod(9)"publickey" + sig_included(1)'\0' + algmethod_len(4) + + * publickey_len(4) + */ + session->userauth_pblc_packet_len = + username_len + session->userauth_pblc_method_len + pubkeydata_len + + 45; + + /* + * Preallocate space for an overall length, method name again, and the + * signature, which won't be any larger than the size of the + * publickeydata itself. + * + * Note that the 'pubkeydata_len' extra bytes allocated here will not + * be used in this first send, but will be used in the later one where + * this same allocation is re-used. + */ + s = session->userauth_pblc_packet = + LIBSSH2_ALLOC(session, + session->userauth_pblc_packet_len + 4 + + (4 + session->userauth_pblc_method_len) + + (4 + pubkeydata_len)); + if (!session->userauth_pblc_packet) { + LIBSSH2_FREE(session, session->userauth_pblc_method); + session->userauth_pblc_method = NULL; + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Out of memory"); + } + + *s++ = SSH_MSG_USERAUTH_REQUEST; + _libssh2_store_str(&s, username, username_len); + _libssh2_store_str(&s, "ssh-connection", 14); + _libssh2_store_str(&s, "publickey", 9); + + session->userauth_pblc_b = s; + /* Not sending signature with *this* packet */ + *s++ = 0; + + _libssh2_store_str(&s, (const char *)session->userauth_pblc_method, + session->userauth_pblc_method_len); + _libssh2_store_str(&s, (const char *)pubkeydata, pubkeydata_len); + + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Attempting publickey authentication"); + + session->userauth_pblc_state = libssh2_NB_state_created; + } + + if (session->userauth_pblc_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, session->userauth_pblc_packet, + session->userauth_pblc_packet_len, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); + else if (rc) { + LIBSSH2_FREE(session, session->userauth_pblc_packet); + session->userauth_pblc_packet = NULL; + LIBSSH2_FREE(session, session->userauth_pblc_method); + session->userauth_pblc_method = NULL; + session->userauth_pblc_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send userauth-publickey request"); + } + + session->userauth_pblc_state = libssh2_NB_state_sent; + } + + if (session->userauth_pblc_state == libssh2_NB_state_sent) { + rc = _libssh2_packet_requirev(session, reply_codes, + &session->userauth_pblc_data, + &session->userauth_pblc_data_len, 0, + NULL, 0, + &session-> + userauth_pblc_packet_requirev_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); + } + else if (rc) { + LIBSSH2_FREE(session, session->userauth_pblc_packet); + session->userauth_pblc_packet = NULL; + LIBSSH2_FREE(session, session->userauth_pblc_method); + session->userauth_pblc_method = NULL; + session->userauth_pblc_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, + "Waiting for USERAUTH response"); + } + + if (session->userauth_pblc_data[0] == SSH_MSG_USERAUTH_SUCCESS) { + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Pubkey authentication prematurely successful"); + /* + * God help any SSH server that allows an UNVERIFIED + * public key to validate the user + */ + LIBSSH2_FREE(session, session->userauth_pblc_data); + session->userauth_pblc_data = NULL; + LIBSSH2_FREE(session, session->userauth_pblc_packet); + session->userauth_pblc_packet = NULL; + LIBSSH2_FREE(session, session->userauth_pblc_method); + session->userauth_pblc_method = NULL; + session->state |= LIBSSH2_STATE_AUTHENTICATED; + session->userauth_pblc_state = libssh2_NB_state_idle; + return 0; + } + + if (session->userauth_pblc_data[0] == SSH_MSG_USERAUTH_FAILURE) { + /* This public key is not allowed for this user on this server */ + LIBSSH2_FREE(session, session->userauth_pblc_data); + session->userauth_pblc_data = NULL; + LIBSSH2_FREE(session, session->userauth_pblc_packet); + session->userauth_pblc_packet = NULL; + LIBSSH2_FREE(session, session->userauth_pblc_method); + session->userauth_pblc_method = NULL; + session->userauth_pblc_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_AUTHENTICATION_FAILED, + "Username/PublicKey combination invalid"); + } + + /* Semi-Success! */ + LIBSSH2_FREE(session, session->userauth_pblc_data); + session->userauth_pblc_data = NULL; + + *session->userauth_pblc_b = 0x01; + session->userauth_pblc_state = libssh2_NB_state_sent1; + } + + if (session->userauth_pblc_state == libssh2_NB_state_sent1) { + unsigned char *buf; + unsigned char *sig; + size_t sig_len; + + s = buf = LIBSSH2_ALLOC(session, 4 + session->session_id_len + + session->userauth_pblc_packet_len); + if (!buf) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "userauth-publickey signed data"); + } + + _libssh2_store_str(&s, (const char *)session->session_id, + session->session_id_len); + + memcpy (s, session->userauth_pblc_packet, + session->userauth_pblc_packet_len); + s += session->userauth_pblc_packet_len; + + rc = sign_callback(session, &sig, &sig_len, buf, s - buf, abstract); + LIBSSH2_FREE(session, buf); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); + } else if (rc) { + LIBSSH2_FREE(session, session->userauth_pblc_method); + session->userauth_pblc_method = NULL; + LIBSSH2_FREE(session, session->userauth_pblc_packet); + session->userauth_pblc_packet = NULL; + session->userauth_pblc_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, + "Callback returned error"); + } + + /* + * If this function was restarted, pubkeydata_len might still be 0 + * which will cause an unnecessary but harmless realloc here. + */ + if (sig_len > pubkeydata_len) { + unsigned char *newpacket; + /* Should *NEVER* happen, but...well.. better safe than sorry */ + newpacket = LIBSSH2_REALLOC(session, + session->userauth_pblc_packet, + session->userauth_pblc_packet_len + 4 + + (4 + session->userauth_pblc_method_len) + + (4 + sig_len)); /* PK sigblob */ + if (!newpacket) { + LIBSSH2_FREE(session, sig); + LIBSSH2_FREE(session, session->userauth_pblc_packet); + session->userauth_pblc_packet = NULL; + LIBSSH2_FREE(session, session->userauth_pblc_method); + session->userauth_pblc_method = NULL; + session->userauth_pblc_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Failed allocating additional space for " + "userauth-publickey packet"); + } + session->userauth_pblc_packet = newpacket; + } + + s = session->userauth_pblc_packet + session->userauth_pblc_packet_len; + session->userauth_pblc_b = NULL; + + _libssh2_store_u32(&s, + 4 + session->userauth_pblc_method_len + 4 + sig_len); + _libssh2_store_str(&s, (const char *)session->userauth_pblc_method, + session->userauth_pblc_method_len); + + LIBSSH2_FREE(session, session->userauth_pblc_method); + session->userauth_pblc_method = NULL; + + _libssh2_store_str(&s, (const char *)sig, sig_len); + LIBSSH2_FREE(session, sig); + + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Attempting publickey authentication -- phase 2"); + + session->userauth_pblc_s = s; + session->userauth_pblc_state = libssh2_NB_state_sent2; + } + + if (session->userauth_pblc_state == libssh2_NB_state_sent2) { + rc = _libssh2_transport_send(session, session->userauth_pblc_packet, + session->userauth_pblc_s - + session->userauth_pblc_packet, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); + } else if (rc) { + LIBSSH2_FREE(session, session->userauth_pblc_packet); + session->userauth_pblc_packet = NULL; + session->userauth_pblc_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send userauth-publickey request"); + } + LIBSSH2_FREE(session, session->userauth_pblc_packet); + session->userauth_pblc_packet = NULL; + + session->userauth_pblc_state = libssh2_NB_state_sent3; + } + + /* PK_OK is no longer valid */ + reply_codes[2] = 0; + + rc = _libssh2_packet_requirev(session, reply_codes, + &session->userauth_pblc_data, + &session->userauth_pblc_data_len, 0, NULL, 0, + &session->userauth_pblc_packet_requirev_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block requesting userauth list"); + } else if (rc) { + session->userauth_pblc_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, + "Waiting for publickey USERAUTH response"); + } + + if (session->userauth_pblc_data[0] == SSH_MSG_USERAUTH_SUCCESS) { + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Publickey authentication successful"); + /* We are us and we've proved it. */ + LIBSSH2_FREE(session, session->userauth_pblc_data); + session->userauth_pblc_data = NULL; + session->state |= LIBSSH2_STATE_AUTHENTICATED; + session->userauth_pblc_state = libssh2_NB_state_idle; + return 0; + } + + /* This public key is not allowed for this user on this server */ + LIBSSH2_FREE(session, session->userauth_pblc_data); + session->userauth_pblc_data = NULL; + session->userauth_pblc_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, + "Invalid signature for supplied public key, or bad " + "username/public key combination"); +} + + /* + * userauth_publickey_frommemory + * Authenticate using a keypair from memory + */ +static int +userauth_publickey_frommemory(LIBSSH2_SESSION *session, + const char *username, + size_t username_len, + const char *publickeydata, + size_t publickeydata_len, + const char *privatekeydata, + size_t privatekeydata_len, + const char *passphrase) +{ + unsigned char *pubkeydata = NULL; + size_t pubkeydata_len = 0; + struct privkey_file privkey_file; + void *abstract = &privkey_file; + int rc; + + privkey_file.filename = privatekeydata; + privkey_file.passphrase = passphrase; + + if (session->userauth_pblc_state == libssh2_NB_state_idle) { + if (publickeydata_len && publickeydata) { + rc = memory_read_publickey(session, &session->userauth_pblc_method, + &session->userauth_pblc_method_len, + &pubkeydata, &pubkeydata_len, + publickeydata, publickeydata_len); + if(rc) + return rc; + } + else if (privatekeydata_len && privatekeydata) { + /* Compute public key from private key. */ + if (_libssh2_pub_priv_keyfilememory(session, + &session->userauth_pblc_method, + &session->userauth_pblc_method_len, + &pubkeydata, &pubkeydata_len, + privatekeydata, privatekeydata_len, + passphrase)) + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to extract public key " + "from private key."); + } + else { + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Invalid data in public and private key."); + } + } + + rc = _libssh2_userauth_publickey(session, username, username_len, + pubkeydata, pubkeydata_len, + sign_frommemory, &abstract); + if(pubkeydata) + LIBSSH2_FREE(session, pubkeydata); + + return rc; +} + +/* + * userauth_publickey_fromfile + * Authenticate using a keypair found in the named files + */ +static int +userauth_publickey_fromfile(LIBSSH2_SESSION *session, + const char *username, + size_t username_len, + const char *publickey, + const char *privatekey, + const char *passphrase) +{ + unsigned char *pubkeydata = NULL; + size_t pubkeydata_len = 0; + struct privkey_file privkey_file; + void *abstract = &privkey_file; + int rc; + + privkey_file.filename = privatekey; + privkey_file.passphrase = passphrase; + + if (session->userauth_pblc_state == libssh2_NB_state_idle) { + if (publickey) { + rc = file_read_publickey(session, &session->userauth_pblc_method, + &session->userauth_pblc_method_len, + &pubkeydata, &pubkeydata_len,publickey); + if (rc) + return rc; + } + else { + /* Compute public key from private key. */ + rc = _libssh2_pub_priv_keyfile(session, + &session->userauth_pblc_method, + &session->userauth_pblc_method_len, + &pubkeydata, &pubkeydata_len, + privatekey, passphrase); + + /* _libssh2_pub_priv_keyfile calls _libssh2_error() */ + if (rc) + return rc; + } + } + + rc = _libssh2_userauth_publickey(session, username, username_len, + pubkeydata, pubkeydata_len, + sign_fromfile, &abstract); + if(pubkeydata) + LIBSSH2_FREE(session, pubkeydata); + + return rc; +} + +/* libssh2_userauth_publickey_frommemory + * Authenticate using a keypair from memory + */ +LIBSSH2_API int +libssh2_userauth_publickey_frommemory(LIBSSH2_SESSION *session, + const char *user, + size_t user_len, + const char *publickeyfiledata, + size_t publickeyfiledata_len, + const char *privatekeyfiledata, + size_t privatekeyfiledata_len, + const char *passphrase) +{ + int rc; + + if(NULL == passphrase) + /* if given a NULL pointer, make it point to a zero-length + string to save us from having to check this all over */ + passphrase=""; + + BLOCK_ADJUST(rc, session, + userauth_publickey_frommemory(session, user, user_len, + publickeyfiledata, + publickeyfiledata_len, + privatekeyfiledata, + privatekeyfiledata_len, + passphrase)); + return rc; +} + +/* libssh2_userauth_publickey_fromfile_ex + * Authenticate using a keypair found in the named files + */ +LIBSSH2_API int +libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, + const char *user, + unsigned int user_len, + const char *publickey, + const char *privatekey, + const char *passphrase) +{ + int rc; + + if(NULL == passphrase) + /* if given a NULL pointer, make it point to a zero-length + string to save us from having to check this all over */ + passphrase=""; + + BLOCK_ADJUST(rc, session, + userauth_publickey_fromfile(session, user, user_len, + publickey, privatekey, + passphrase)); + return rc; +} + +/* libssh2_userauth_publickey_ex + * Authenticate using an external callback function + */ +LIBSSH2_API int +libssh2_userauth_publickey(LIBSSH2_SESSION *session, + const char *user, + const unsigned char *pubkeydata, + size_t pubkeydata_len, + LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*sign_callback)), + void **abstract) +{ + int rc; + + if(!session) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, session, + _libssh2_userauth_publickey(session, user, strlen(user), + pubkeydata, pubkeydata_len, + sign_callback, abstract)); + return rc; +} + + + +/* + * userauth_keyboard_interactive + * + * Authenticate using a challenge-response authentication + */ +static int +userauth_keyboard_interactive(LIBSSH2_SESSION * session, + const char *username, + unsigned int username_len, + LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*response_callback))) +{ + unsigned char *s; + int rc; + + static const unsigned char reply_codes[4] = { + SSH_MSG_USERAUTH_SUCCESS, + SSH_MSG_USERAUTH_FAILURE, SSH_MSG_USERAUTH_INFO_REQUEST, 0 + }; + unsigned int language_tag_len; + unsigned int i; + + if (session->userauth_kybd_state == libssh2_NB_state_idle) { + session->userauth_kybd_auth_name = NULL; + session->userauth_kybd_auth_instruction = NULL; + session->userauth_kybd_num_prompts = 0; + session->userauth_kybd_auth_failure = 1; + session->userauth_kybd_prompts = NULL; + session->userauth_kybd_responses = NULL; + + /* Zero the whole thing out */ + memset(&session->userauth_kybd_packet_requirev_state, 0, + sizeof(session->userauth_kybd_packet_requirev_state)); + + session->userauth_kybd_packet_len = + 1 /* byte SSH_MSG_USERAUTH_REQUEST */ + + 4 + username_len /* string user name (ISO-10646 UTF-8, as + defined in [RFC-3629]) */ + + 4 + 14 /* string service name (US-ASCII) */ + + 4 + 20 /* string "keyboard-interactive" (US-ASCII) */ + + 4 + 0 /* string language tag (as defined in + [RFC-3066]) */ + + 4 + 0 /* string submethods (ISO-10646 UTF-8) */ + ; + + session->userauth_kybd_data = s = + LIBSSH2_ALLOC(session, session->userauth_kybd_packet_len); + if (!s) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "keyboard-interactive authentication"); + } + + *s++ = SSH_MSG_USERAUTH_REQUEST; + + /* user name */ + _libssh2_store_str(&s, username, username_len); + + /* service name */ + _libssh2_store_str(&s, "ssh-connection", sizeof("ssh-connection") - 1); + + /* "keyboard-interactive" */ + _libssh2_store_str(&s, "keyboard-interactive", + sizeof("keyboard-interactive") - 1); + /* language tag */ + _libssh2_store_u32(&s, 0); + + /* submethods */ + _libssh2_store_u32(&s, 0); + + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Attempting keyboard-interactive authentication"); + + session->userauth_kybd_state = libssh2_NB_state_created; + } + + if (session->userauth_kybd_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, session->userauth_kybd_data, + session->userauth_kybd_packet_len, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); + } else if (rc) { + LIBSSH2_FREE(session, session->userauth_kybd_data); + session->userauth_kybd_data = NULL; + session->userauth_kybd_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send keyboard-interactive request"); + } + LIBSSH2_FREE(session, session->userauth_kybd_data); + session->userauth_kybd_data = NULL; + + session->userauth_kybd_state = libssh2_NB_state_sent; + } + + for(;;) { + if (session->userauth_kybd_state == libssh2_NB_state_sent) { + rc = _libssh2_packet_requirev(session, reply_codes, + &session->userauth_kybd_data, + &session->userauth_kybd_data_len, + 0, NULL, 0, + &session-> + userauth_kybd_packet_requirev_state); + if (rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block"); + } else if (rc) { + session->userauth_kybd_state = libssh2_NB_state_idle; + return _libssh2_error(session, + LIBSSH2_ERROR_AUTHENTICATION_FAILED, + "Waiting for keyboard USERAUTH response"); + } + + if (session->userauth_kybd_data[0] == SSH_MSG_USERAUTH_SUCCESS) { + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Keyboard-interactive authentication successful"); + LIBSSH2_FREE(session, session->userauth_kybd_data); + session->userauth_kybd_data = NULL; + session->state |= LIBSSH2_STATE_AUTHENTICATED; + session->userauth_kybd_state = libssh2_NB_state_idle; + return 0; + } + + if (session->userauth_kybd_data[0] == SSH_MSG_USERAUTH_FAILURE) { + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Keyboard-interactive authentication failed"); + LIBSSH2_FREE(session, session->userauth_kybd_data); + session->userauth_kybd_data = NULL; + session->userauth_kybd_state = libssh2_NB_state_idle; + return _libssh2_error(session, + LIBSSH2_ERROR_AUTHENTICATION_FAILED, + "Authentication failed " + "(keyboard-interactive)"); + } + + /* server requested PAM-like conversation */ + s = session->userauth_kybd_data + 1; + + /* string name (ISO-10646 UTF-8) */ + session->userauth_kybd_auth_name_len = _libssh2_ntohu32(s); + s += 4; + if(session->userauth_kybd_auth_name_len) { + session->userauth_kybd_auth_name = + LIBSSH2_ALLOC(session, + session->userauth_kybd_auth_name_len); + if (!session->userauth_kybd_auth_name) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "keyboard-interactive 'name' " + "request field"); + goto cleanup; + } + memcpy(session->userauth_kybd_auth_name, s, + session->userauth_kybd_auth_name_len); + s += session->userauth_kybd_auth_name_len; + } + + /* string instruction (ISO-10646 UTF-8) */ + session->userauth_kybd_auth_instruction_len = _libssh2_ntohu32(s); + s += 4; + if(session->userauth_kybd_auth_instruction_len) { + session->userauth_kybd_auth_instruction = + LIBSSH2_ALLOC(session, + session->userauth_kybd_auth_instruction_len); + if (!session->userauth_kybd_auth_instruction) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "keyboard-interactive 'instruction' " + "request field"); + goto cleanup; + } + memcpy(session->userauth_kybd_auth_instruction, s, + session->userauth_kybd_auth_instruction_len); + s += session->userauth_kybd_auth_instruction_len; + } + + /* string language tag (as defined in [RFC-3066]) */ + language_tag_len = _libssh2_ntohu32(s); + s += 4; + + /* ignoring this field as deprecated */ + s += language_tag_len; + + /* int num-prompts */ + session->userauth_kybd_num_prompts = _libssh2_ntohu32(s); + s += 4; + + if(session->userauth_kybd_num_prompts) { + session->userauth_kybd_prompts = + LIBSSH2_CALLOC(session, + sizeof(LIBSSH2_USERAUTH_KBDINT_PROMPT) * + session->userauth_kybd_num_prompts); + if (!session->userauth_kybd_prompts) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "keyboard-interactive prompts array"); + goto cleanup; + } + + session->userauth_kybd_responses = + LIBSSH2_CALLOC(session, + sizeof(LIBSSH2_USERAUTH_KBDINT_RESPONSE) * + session->userauth_kybd_num_prompts); + if (!session->userauth_kybd_responses) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "keyboard-interactive responses array"); + goto cleanup; + } + + for(i = 0; i < session->userauth_kybd_num_prompts; i++) { + /* string prompt[1] (ISO-10646 UTF-8) */ + session->userauth_kybd_prompts[i].length = + _libssh2_ntohu32(s); + s += 4; + session->userauth_kybd_prompts[i].text = + LIBSSH2_CALLOC(session, + session->userauth_kybd_prompts[i].length); + if (!session->userauth_kybd_prompts[i].text) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "keyboard-interactive prompt message"); + goto cleanup; + } + memcpy(session->userauth_kybd_prompts[i].text, s, + session->userauth_kybd_prompts[i].length); + s += session->userauth_kybd_prompts[i].length; + + /* boolean echo[1] */ + session->userauth_kybd_prompts[i].echo = *s++; + } + } + + response_callback(session->userauth_kybd_auth_name, + session->userauth_kybd_auth_name_len, + session->userauth_kybd_auth_instruction, + session->userauth_kybd_auth_instruction_len, + session->userauth_kybd_num_prompts, + session->userauth_kybd_prompts, + session->userauth_kybd_responses, + &session->abstract); + + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Keyboard-interactive response callback function" + " invoked"); + + session->userauth_kybd_packet_len = + 1 /* byte SSH_MSG_USERAUTH_INFO_RESPONSE */ + + 4 /* int num-responses */ + ; + + for(i = 0; i < session->userauth_kybd_num_prompts; i++) { + /* string response[1] (ISO-10646 UTF-8) */ + session->userauth_kybd_packet_len += + 4 + session->userauth_kybd_responses[i].length; + } + + /* A new userauth_kybd_data area is to be allocated, free the + former one. */ + LIBSSH2_FREE(session, session->userauth_kybd_data); + + session->userauth_kybd_data = s = + LIBSSH2_ALLOC(session, session->userauth_kybd_packet_len); + if (!s) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for keyboard-" + "interactive response packet"); + goto cleanup; + } + + *s = SSH_MSG_USERAUTH_INFO_RESPONSE; + s++; + _libssh2_store_u32(&s, session->userauth_kybd_num_prompts); + + for(i = 0; i < session->userauth_kybd_num_prompts; i++) { + _libssh2_store_str(&s, + session->userauth_kybd_responses[i].text, + session->userauth_kybd_responses[i].length); + } + + session->userauth_kybd_state = libssh2_NB_state_sent1; + } + + if (session->userauth_kybd_state == libssh2_NB_state_sent1) { + rc = _libssh2_transport_send(session, session->userauth_kybd_data, + session->userauth_kybd_packet_len, + NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block"); + if (rc) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send userauth-keyboard-interactive" + " request"); + goto cleanup; + } + + session->userauth_kybd_auth_failure = 0; + } + + cleanup: + /* + * It's safe to clean all the data here, because unallocated pointers + * are filled by zeroes + */ + + LIBSSH2_FREE(session, session->userauth_kybd_data); + session->userauth_kybd_data = NULL; + + if (session->userauth_kybd_prompts) { + for(i = 0; i < session->userauth_kybd_num_prompts; i++) { + LIBSSH2_FREE(session, session->userauth_kybd_prompts[i].text); + session->userauth_kybd_prompts[i].text = NULL; + } + } + + if (session->userauth_kybd_responses) { + for(i = 0; i < session->userauth_kybd_num_prompts; i++) { + LIBSSH2_FREE(session, + session->userauth_kybd_responses[i].text); + session->userauth_kybd_responses[i].text = NULL; + } + } + + if(session->userauth_kybd_prompts) { + LIBSSH2_FREE(session, session->userauth_kybd_prompts); + session->userauth_kybd_prompts = NULL; + } + if(session->userauth_kybd_responses) { + LIBSSH2_FREE(session, session->userauth_kybd_responses); + session->userauth_kybd_responses = NULL; + } + if(session->userauth_kybd_auth_name) { + LIBSSH2_FREE(session, session->userauth_kybd_auth_name); + session->userauth_kybd_auth_name = NULL; + } + if(session->userauth_kybd_auth_instruction) { + LIBSSH2_FREE(session, session->userauth_kybd_auth_instruction); + session->userauth_kybd_auth_instruction = NULL; + } + + if (session->userauth_kybd_auth_failure) { + session->userauth_kybd_state = libssh2_NB_state_idle; + return -1; + } + + session->userauth_kybd_state = libssh2_NB_state_sent; + } +} + +/* + * libssh2_userauth_keyboard_interactive_ex + * + * Authenticate using a challenge-response authentication + */ +LIBSSH2_API int +libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION *session, + const char *user, + unsigned int user_len, + LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*response_callback))) +{ + int rc; + BLOCK_ADJUST(rc, session, + userauth_keyboard_interactive(session, user, user_len, + response_callback)); + return rc; +} diff --git a/libssh2/version.c b/libssh2/version.c new file mode 100644 index 0000000..408f83a --- /dev/null +++ b/libssh2/version.c @@ -0,0 +1,54 @@ +/* Copyright (C) 2009 Daniel Stenberg. All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + */ + +#include "libssh2_priv.h" + +/* + libssh2_version() can be used like this: + + if (!libssh2_version(LIBSSH2_VERSION_NUM)) { + fprintf (stderr, "Runtime libssh2 version too old!\n"); + exit(1); + } +*/ +LIBSSH2_API +const char *libssh2_version(int req_version_num) +{ + if(req_version_num <= LIBSSH2_VERSION_NUM) + return LIBSSH2_VERSION; + return NULL; /* this is not a suitable library! */ +} diff --git a/ogl/README b/ogl/README new file mode 100644 index 0000000..b5f2e06 --- /dev/null +++ b/ogl/README @@ -0,0 +1,3 @@ +This is the latest version of the wxOGL code, as donated to the project +with written permission to relicence under the PostgreSQL licence from +Julian Smart. diff --git a/ogl/basic.cpp b/ogl/basic.cpp new file mode 100644 index 0000000..d4ef7cd --- /dev/null +++ b/ogl/basic.cpp @@ -0,0 +1,3217 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// basic.cpp - Basic OGL classes +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include +#include +#include + +#include "ogl/ogl.h" + + +// Control point types +// Rectangle and most other shapes +#define CONTROL_POINT_VERTICAL 1 +#define CONTROL_POINT_HORIZONTAL 2 +#define CONTROL_POINT_DIAGONAL 3 + +// Line +#define CONTROL_POINT_ENDPOINT_TO 4 +#define CONTROL_POINT_ENDPOINT_FROM 5 +#define CONTROL_POINT_LINE 6 + +IMPLEMENT_DYNAMIC_CLASS(wxShapeTextLine, wxObject) +IMPLEMENT_DYNAMIC_CLASS(wxAttachmentPoint, wxObject) + +wxShapeTextLine::wxShapeTextLine(double the_x, double the_y, const wxString &the_line) +{ + m_x = the_x; + m_y = the_y; + m_line = the_line; +} + +wxShapeTextLine::~wxShapeTextLine() +{ +} + +IMPLEMENT_ABSTRACT_CLASS(wxShapeEvtHandler, wxObject) + +wxShapeEvtHandler::wxShapeEvtHandler(wxShapeEvtHandler *prev, wxShape *shape) +{ + m_previousHandler = prev; + m_handlerShape = shape; +} + +wxShapeEvtHandler::~wxShapeEvtHandler() +{ +} + +// Creates a copy of this event handler. +wxShapeEvtHandler *wxShapeEvtHandler::CreateNewCopy() +{ + wxShapeEvtHandler *newObject = (wxShapeEvtHandler *) GetClassInfo()->CreateObject(); + + wxASSERT( (newObject != NULL) ); + wxASSERT( (newObject->IsKindOf(CLASSINFO(wxShapeEvtHandler))) ); + + newObject->m_previousHandler = newObject; + + CopyData(*newObject); + + return newObject; +} + + +void wxShapeEvtHandler::OnDelete() +{ + if (this != GetShape()) + delete this; +} + +void wxShapeEvtHandler::OnDraw(wxDC &dc) +{ + if (m_previousHandler) + m_previousHandler->OnDraw(dc); +} + +void wxShapeEvtHandler::OnMoveLinks() +{ + if (m_previousHandler) + m_previousHandler->OnMoveLinks(); +} + +void wxShapeEvtHandler::OnMoveLink(bool moveControlPoints) +{ + if (m_previousHandler) + m_previousHandler->OnMoveLink(moveControlPoints); +} + +void wxShapeEvtHandler::OnDrawContents(wxDC &dc) +{ + if (m_previousHandler) + m_previousHandler->OnDrawContents(dc); +} + +void wxShapeEvtHandler::OnDrawBranches(wxDC &dc, bool erase) +{ + if (m_previousHandler) + m_previousHandler->OnDrawBranches(dc, erase); +} + +void wxShapeEvtHandler::OnSize(double x, double y) +{ + if (m_previousHandler) + m_previousHandler->OnSize(x, y); +} + +bool wxShapeEvtHandler::OnMovePre(double x, double y, double old_x, double old_y, bool display) +{ + if (m_previousHandler) + return m_previousHandler->OnMovePre(x, y, old_x, old_y, display); + else + return TRUE; +} + +void wxShapeEvtHandler::OnMovePost(double x, double y, double old_x, double old_y, bool display) +{ + if (m_previousHandler) + m_previousHandler->OnMovePost(x, y, old_x, old_y, display); +} + +void wxShapeEvtHandler::OnHighlight(wxDC &dc) +{ + if (m_previousHandler) + m_previousHandler->OnHighlight(dc); +} + +void wxShapeEvtHandler::OnLeftClick(double x, double y, int keys, int attachment) +{ + if (m_previousHandler) + m_previousHandler->OnLeftClick(x, y, keys, attachment); +} + +void wxShapeEvtHandler::OnLeftDoubleClick(double x, double y, int keys, int attachment) +{ + if (m_previousHandler) + m_previousHandler->OnLeftDoubleClick(x, y, keys, attachment); +} + +void wxShapeEvtHandler::OnRightClick(double x, double y, int keys, int attachment) +{ + if (m_previousHandler) + m_previousHandler->OnRightClick(x, y, keys, attachment); +} + +void wxShapeEvtHandler::OnDragLeft(bool draw, double x, double y, int keys, int attachment) +{ + if (m_previousHandler) + m_previousHandler->OnDragLeft(draw, x, y, keys, attachment); +} + +void wxShapeEvtHandler::OnBeginDragLeft(double x, double y, int keys, int attachment) +{ + if (m_previousHandler) + m_previousHandler->OnBeginDragLeft(x, y, keys, attachment); +} + +void wxShapeEvtHandler::OnEndDragLeft(double x, double y, int keys, int attachment) +{ + if (m_previousHandler) + m_previousHandler->OnEndDragLeft(x, y, keys, attachment); +} + +void wxShapeEvtHandler::OnDragRight(bool draw, double x, double y, int keys, int attachment) +{ + if (m_previousHandler) + m_previousHandler->OnDragRight(draw, x, y, keys, attachment); +} + +void wxShapeEvtHandler::OnBeginDragRight(double x, double y, int keys, int attachment) +{ + if (m_previousHandler) + m_previousHandler->OnBeginDragRight(x, y, keys, attachment); +} + +void wxShapeEvtHandler::OnEndDragRight(double x, double y, int keys, int attachment) +{ + if (m_previousHandler) + m_previousHandler->OnEndDragRight(x, y, keys, attachment); +} + +// Control points ('handles') redirect control to the actual shape, to make it easier +// to override sizing behaviour. +void wxShapeEvtHandler::OnSizingDragLeft(wxControlPoint *pt, bool draw, double x, double y, int keys, int attachment) +{ + if (m_previousHandler) + m_previousHandler->OnSizingDragLeft(pt, draw, x, y, keys, attachment); +} + +void wxShapeEvtHandler::OnSizingBeginDragLeft(wxControlPoint *pt, double x, double y, int keys, int attachment) +{ + if (m_previousHandler) + m_previousHandler->OnSizingBeginDragLeft(pt, x, y, keys, attachment); +} + +void wxShapeEvtHandler::OnSizingEndDragLeft(wxControlPoint *pt, double x, double y, int keys, int attachment) +{ + if (m_previousHandler) + m_previousHandler->OnSizingEndDragLeft(pt, x, y, keys, attachment); +} + +void wxShapeEvtHandler::OnDrawOutline(wxDC &dc, double x, double y, double w, double h) +{ + if (m_previousHandler) + m_previousHandler->OnDrawOutline(dc, x, y, w, h); +} + +void wxShapeEvtHandler::OnDrawControlPoints(wxDC &dc) +{ + if (m_previousHandler) + m_previousHandler->OnDrawControlPoints(dc); +} + +// Can override this to prevent or intercept line reordering. +void wxShapeEvtHandler::OnChangeAttachment(int attachment, wxLineShape *line, wxList &ordering) +{ + if (m_previousHandler) + m_previousHandler->OnChangeAttachment(attachment, line, ordering); +} + +IMPLEMENT_ABSTRACT_CLASS(wxShape, wxShapeEvtHandler) + +wxShape::wxShape(wxShapeCanvas *can) +{ + m_eventHandler = this; + SetShape(this); + m_id = 0; + m_formatted = FALSE; + m_canvas = can; + m_xpos = 0.0; + m_ypos = 0.0; + m_pen = g_oglBlackPen; + m_brush = (wxBrush *) wxWHITE_BRUSH; + m_font = g_oglNormalFont; + m_textColour = * wxBLACK; + m_textColourName = wxT("BLACK"); + m_visible = FALSE; + m_selected = FALSE; + m_attachmentMode = ATTACHMENT_MODE_NONE; + m_spaceAttachments = TRUE; + m_disableLabel = FALSE; + m_fixedWidth = FALSE; + m_fixedHeight = FALSE; + m_drawHandles = TRUE; + m_sensitivity = OP_ALL; + m_draggable = TRUE; + m_parent = NULL; + m_formatMode = FORMAT_CENTRE_HORIZ | FORMAT_CENTRE_VERT; + m_shadowMode = SHADOW_NONE; + m_shadowOffsetX = 6; + m_shadowOffsetY = 6; + m_shadowBrush = (wxBrush *) wxBLACK_BRUSH; + m_textMarginX = 5; + m_textMarginY = 5; + m_regionName = wxT("0"); + m_centreResize = TRUE; + m_maintainAspectRatio = FALSE; + m_highlighted = FALSE; + m_rotation = 0.0; + m_branchNeckLength = 10; + m_branchStemLength = 10; + m_branchSpacing = 10; + m_branchStyle = BRANCHING_ATTACHMENT_NORMAL; + + // Set up a default region. Much of the above will be put into + // the region eventually (the duplication is for compatibility) + wxShapeRegion *region = new wxShapeRegion; + m_regions.Append(region); + region->SetName(wxT("0")); + region->SetFont(g_oglNormalFont); + region->SetFormatMode(FORMAT_CENTRE_HORIZ | FORMAT_CENTRE_VERT); + region->SetColour(wxString(wxT("BLACK"))); +} + +wxShape::~wxShape() +{ + if (m_parent) + m_parent->GetChildren().DeleteObject(this); + + ClearText(); + ClearRegions(); + ClearAttachments(); + + if (m_canvas) + m_canvas->RemoveShape(this); + + GetEventHandler()->OnDelete(); +} + +void wxShape::SetHighlight(bool hi, bool recurse) +{ + m_highlighted = hi; + if (recurse) + { + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + child->SetHighlight(hi, recurse); + node = node->GetNext(); + } + } +} + +void wxShape::SetSensitivityFilter(int sens, bool recursive) +{ + if (sens & OP_DRAG_LEFT) + m_draggable = TRUE; + else + m_draggable = FALSE; + + m_sensitivity = sens; + if (recursive) + { + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *obj = (wxShape *)node->GetData(); + obj->SetSensitivityFilter(sens, TRUE); + node = node->GetNext(); + } + } +} + +void wxShape::SetDraggable(bool drag, bool recursive) +{ + m_draggable = drag; + if (m_draggable) + m_sensitivity |= OP_DRAG_LEFT; + else if (m_sensitivity & OP_DRAG_LEFT) + m_sensitivity = m_sensitivity - OP_DRAG_LEFT; + + if (recursive) + { + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *obj = (wxShape *)node->GetData(); + obj->SetDraggable(drag, TRUE); + node = node->GetNext(); + } + } +} + +void wxShape::SetDrawHandles(bool drawH) +{ + m_drawHandles = drawH; + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *obj = (wxShape *)node->GetData(); + obj->SetDrawHandles(drawH); + node = node->GetNext(); + } +} + +void wxShape::SetShadowMode(int mode, bool redraw) +{ + if (redraw && GetCanvas()) + { + Refresh(); + + m_shadowMode = mode; + + Refresh(); + } + else + { + m_shadowMode = mode; + } +} + +void wxShape::Refresh(wxShapeCanvas *canvas) +{ + if (!canvas) + canvas = m_canvas; + if (canvas) + { + double w, h; + GetBoundingBoxMax(& w, & h); + double x1 = (double)(GetX() - w / 2.0) - canvas->GetCurrentPixelScrollPosition().x; + double y1 = (double)(GetY() - h / 2.0) - canvas->GetCurrentPixelScrollPosition().y; + canvas->RefreshRect(wxRect(WXROUND(x1), WXROUND(y1), WXROUND(w), WXROUND(h))); + } +} + +void wxShape::SetCanvas(wxShapeCanvas *theCanvas) +{ + m_canvas = theCanvas; + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + child->SetCanvas(theCanvas); + node = node->GetNext(); + } +} + +void wxShape::AddToCanvas(wxShapeCanvas *theCanvas, wxShape *addAfter) +{ + theCanvas->AddShape(this, addAfter); + wxNode *node = m_children.GetFirst(); + wxShape *lastImage = this; + while (node) + { + wxShape *object = (wxShape *)node->GetData(); + object->AddToCanvas(theCanvas, lastImage); + lastImage = object; + + node = node->GetNext(); + } +} + +// Insert at front of canvas +void wxShape::InsertInCanvas(wxShapeCanvas *theCanvas) +{ + theCanvas->InsertShape(this); + wxNode *node = m_children.GetFirst(); + wxShape *lastImage = this; + while (node) + { + wxShape *object = (wxShape *)node->GetData(); + object->AddToCanvas(theCanvas, lastImage); + lastImage = object; + + node = node->GetNext(); + } +} + +void wxShape::RemoveFromCanvas(wxShapeCanvas *theCanvas) +{ + if (Selected()) + Select(FALSE); + theCanvas->RemoveShape(this); + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *object = (wxShape *)node->GetData(); + object->RemoveFromCanvas(theCanvas); + + node = node->GetNext(); + } +} + +void wxShape::ClearAttachments() +{ + wxNode *node = m_attachmentPoints.GetFirst(); + while (node) + { + wxAttachmentPoint *point = (wxAttachmentPoint *)node->GetData(); + delete point; + node = node->GetNext(); + } + m_attachmentPoints.Clear(); +} + +void wxShape::ClearText(int regionId) +{ + if (regionId == 0) + { + m_text.DeleteContents(TRUE); + m_text.Clear(); + m_text.DeleteContents(FALSE); + } + wxNode *node = m_regions.Item(regionId); + if (!node) + return; + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + region->ClearText(); +} + +void wxShape::ClearRegions() +{ + wxNode *node = m_regions.GetFirst(); + while (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + wxNode *next = node->GetNext(); + delete region; + delete node; + node = next; + } +} + +void wxShape::AddRegion(wxShapeRegion *region) +{ + m_regions.Append(region); +} + +void wxShape::SetDefaultRegionSize() +{ + wxNode *node = m_regions.GetFirst(); + if (!node) return; + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + double w, h; + GetBoundingBoxMin(&w, &h); + region->SetSize(w, h); +} + +bool wxShape::HitTest(double x, double y, int *attachment, double *distance) +{ +// if (!sensitive) +// return FALSE; + + double width = 0.0, height = 0.0; + GetBoundingBoxMin(&width, &height); + if (fabs(width) < 4.0) width = 4.0; + if (fabs(height) < 4.0) height = 4.0; + + width += (double)4.0; + height += (double)4.0; // Allowance for inaccurate mousing + + double left = (double)(m_xpos - (width / 2.0)); + double top = (double)(m_ypos - (height / 2.0)); + double right = (double)(m_xpos + (width / 2.0)); + double bottom = (double)(m_ypos + (height / 2.0)); + + int nearest_attachment = 0; + + // If within the bounding box, check the attachment points + // within the object. + + if (x >= left && x <= right && y >= top && y <= bottom) + { + int n = GetNumberOfAttachments(); + double nearest = 999999.0; + + // GetAttachmentPosition[Edge] takes a logical attachment position, + // i.e. if it's rotated through 90%, position 0 is East-facing. + + for (int i = 0; i < n; i++) + { + double xp, yp; + if (GetAttachmentPositionEdge(i, &xp, &yp)) + { + double l = (double)sqrt(((xp - x) * (xp - x)) + + ((yp - y) * (yp - y))); + + if (l < nearest) + { + nearest = l; + nearest_attachment = i; + } + } + } + *attachment = nearest_attachment; + *distance = nearest; + return TRUE; + } + else return FALSE; +} + +// Format a text string according to the region size, adding +// strings with positions to region text list + +static bool GraphicsInSizeToContents = FALSE; // Infinite recursion elimination +void wxShape::FormatText(wxDC &dc, const wxString &s, int i) +{ + double w, h; + ClearText(i); + + if (m_regions.GetCount() < 1) + return; + wxNode *node = m_regions.Item(i); + if (!node) + return; + + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + // region->SetText(s); // don't set the formatted text yet, it will be done below + region->m_regionText = s; + dc.SetFont(* region->GetFont()); + + region->GetSize(&w, &h); + + wxArrayString *stringList = oglFormatText(dc, s, (w - 2 * m_textMarginX), (h - 2 * m_textMarginY), region->GetFormatMode()); + size_t j; + for (j = 0; j < stringList->GetCount(); j++) + { + const wxString &s = (*stringList)[j]; + wxShapeTextLine *line = new wxShapeTextLine(0.0, 0.0, s); + region->GetFormattedText().Append((wxObject *)line); + } + delete stringList; + double actualW = w; + double actualH = h; + // Don't try to resize an object with more than one image (this case should be dealt + // with by overriden handlers) + if ((region->GetFormatMode() & FORMAT_SIZE_TO_CONTENTS) && + (region->GetFormattedText().GetCount() > 0) && + (m_regions.GetCount() == 1) && !GraphicsInSizeToContents) + { + oglGetCentredTextExtent(dc, &(region->GetFormattedText()), m_xpos, m_ypos, w, h, &actualW, &actualH); + if ((actualW + 2 * m_textMarginX != w ) || (actualH + 2 * m_textMarginY != h)) + { + // If we are a descendant of a composite, must make sure the composite gets + // resized properly + wxShape *topAncestor = GetTopAncestor(); + + if (topAncestor != this) + { + // Make sure we don't recurse infinitely + GraphicsInSizeToContents = TRUE; + + wxCompositeShape *composite = (wxCompositeShape *)topAncestor; + // composite->Erase(dc); + SetSize(actualW + 2 * m_textMarginX, actualH + 2 * m_textMarginY); + Move(m_xpos, m_ypos); + composite->CalculateSize(); + if (composite->Selected()) + { + composite->DeleteControlPoints(& dc); + composite->MakeControlPoints(); + composite->MakeMandatoryControlPoints(); + } + // Where infinite recursion might happen if we didn't stop it + composite->Draw(dc); + + GraphicsInSizeToContents = FALSE; + } + else + { + // Erase(dc); + SetSize(actualW + 2 * m_textMarginX, actualH + 2 * m_textMarginY); + Move(m_xpos, m_ypos); + } + SetSize(actualW + 2 * m_textMarginX, actualH + 2 * m_textMarginY); + Move(m_xpos, m_ypos); + // EraseContents(dc); + } + } + region->GetSize(&actualW, &actualH); + oglCentreText(dc, &(region->GetFormattedText()), m_xpos, m_ypos, actualW - 2 * m_textMarginX, actualH - 2 * m_textMarginY, region->GetFormatMode()); + m_formatted = TRUE; +} + +void wxShape::Recentre(wxDC &dc) +{ + double w, h; + GetBoundingBoxMin(&w, &h); + + int noRegions = m_regions.GetCount(); + for (int i = 0; i < noRegions; i++) + { + wxNode *node = m_regions.Item(i); + if (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + oglCentreText(dc, &(region->GetFormattedText()), m_xpos, m_ypos, w - 2 * m_textMarginX, h - 2 * m_textMarginY, region->GetFormatMode()); + } + } +} + +bool wxShape::GetPerimeterPoint(double WXUNUSED(x1), double WXUNUSED(y1), + double WXUNUSED(x2), double WXUNUSED(y2), + double *WXUNUSED(x3), double *WXUNUSED(y3)) +{ + return FALSE; +} + +void wxShape::SetPen(wxPen *the_pen) +{ + m_pen = the_pen; +} + +void wxShape::SetBrush(wxBrush *the_brush) +{ + m_brush = the_brush; +} + +// Get the top-most (non-division) ancestor, or self +wxShape *wxShape::GetTopAncestor() +{ + if (!GetParent()) + return this; + + if (GetParent()->IsKindOf(CLASSINFO(wxDivisionShape))) + return this; + else return GetParent()->GetTopAncestor(); +} + +/* + * Region functions + * + */ +void wxShape::SetFont(wxFont *the_font, int regionId) +{ + m_font = the_font; + wxNode *node = m_regions.Item(regionId); + if (!node) + return; + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + region->SetFont(the_font); +} + +wxFont *wxShape::GetFont(int n) const +{ + wxNode *node = m_regions.Item(n); + if (!node) + return NULL; + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + return region->GetFont(); +} + +void wxShape::SetFormatMode(int mode, int regionId) +{ + wxNode *node = m_regions.Item(regionId); + if (!node) + return; + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + region->SetFormatMode(mode); +} + +int wxShape::GetFormatMode(int regionId) const +{ + wxNode *node = m_regions.Item(regionId); + if (!node) + return 0; + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + return region->GetFormatMode(); +} + +void wxShape::SetTextColour(const wxString &the_colour, int regionId) +{ + m_textColour = wxTheColourDatabase->Find(the_colour); + m_textColourName = the_colour; + + wxNode *node = m_regions.Item(regionId); + if (!node) + return; + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + region->SetColour(the_colour); +} + +void wxShape::SetTextColour(const wxColour &the_colour, int regionId) +{ + wxNode *node = m_regions.Item(regionId); + if (!node) + return; + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + region->SetColour(the_colour); +} + +wxString wxShape::GetTextColour(int regionId) const +{ + wxNode *node = m_regions.Item(regionId); + if (!node) + return wxEmptyString; + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + return region->GetColour(); +} + +wxColour wxShape::GetActualTextColour(int regionId) const +{ + wxNode *node = m_regions.Item(regionId); + if (!node) + return wxColour(); + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + return region->GetActualColourObject(); +} + +void wxShape::SetRegionName(const wxString &name, int regionId) +{ + wxNode *node = m_regions.Item(regionId); + if (!node) + return; + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + region->SetName(name); +} + +wxString wxShape::GetRegionName(int regionId) +{ + wxNode *node = m_regions.Item(regionId); + if (!node) + return wxEmptyString; + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + return region->GetName(); +} + +int wxShape::GetRegionId(const wxString &name) +{ + wxNode *node = m_regions.GetFirst(); + int i = 0; + while (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + if (region->GetName() == name) + return i; + node = node->GetNext(); + i ++; + } + return -1; +} + +// Name all m_regions in all subimages recursively. +void wxShape::NameRegions(const wxString &parentName) +{ + int n = GetNumberOfTextRegions(); + wxString buff; + for (int i = 0; i < n; i++) + { + if (parentName.Length() > 0) + buff << parentName << wxT(".") << i; + else + buff << i; + SetRegionName(buff, i); + } + wxNode *node = m_children.GetFirst(); + int j = 0; + while (node) + { + buff.Empty(); + wxShape *child = (wxShape *)node->GetData(); + if (parentName.Length() > 0) + buff << parentName << wxT(".") << j; + else + buff << j; + child->NameRegions(buff); + node = node->GetNext(); + j ++; + } +} + +// Get a region by name, possibly looking recursively into composites. +wxShape *wxShape::FindRegion(const wxString &name, int *regionId) +{ + int id = GetRegionId(name); + if (id > -1) + { + *regionId = id; + return this; + } + + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + wxShape *actualImage = child->FindRegion(name, regionId); + if (actualImage) + return actualImage; + node = node->GetNext(); + } + return NULL; +} + +// Finds all region names for this image (composite or simple). +// Supply empty string list. +void wxShape::FindRegionNames(wxStringList &list) +{ + int n = GetNumberOfTextRegions(); + for (int i = 0; i < n; i++) + { + wxString name(GetRegionName(i)); + list.Add(name); + } + + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + child->FindRegionNames(list); + node = node->GetNext(); + } +} + +void wxShape::AssignNewIds() +{ +// if (m_id == 0) + m_id = wxNewId(); + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + child->AssignNewIds(); + node = node->GetNext(); + } +} + +void wxShape::OnDraw(wxDC &WXUNUSED(dc)) +{ +} + +void wxShape::OnMoveLinks() +{ + // Want to set the ends of all attached links + // to point to/from this object + + wxNode *current = m_lines.GetFirst(); + while (current) + { + wxLineShape *line = (wxLineShape *)current->GetData(); + line->GetEventHandler()->OnMoveLink(); + current = current->GetNext(); + } +} + + +void wxShape::OnDrawContents(wxDC &dc) +{ + double bound_x, bound_y; + GetBoundingBoxMin(&bound_x, &bound_y); + if (m_regions.GetCount() < 1) return; + + if (m_pen) dc.SetPen(* m_pen); + + wxShapeRegion *region = (wxShapeRegion *)m_regions.GetFirst()->GetData(); + if (region->GetFont()) dc.SetFont(* region->GetFont()); + + dc.SetTextForeground(region->GetActualColourObject()); + dc.SetBackgroundMode(wxTRANSPARENT); + if (!m_formatted) + { + oglCentreText(dc, &(region->GetFormattedText()), m_xpos, m_ypos, bound_x - 2 * m_textMarginX, bound_y - 2 * m_textMarginY, region->GetFormatMode()); + m_formatted = TRUE; + } + if (!GetDisableLabel()) + { + oglDrawFormattedText(dc, &(region->GetFormattedText()), m_xpos, m_ypos, bound_x - 2 * m_textMarginX, bound_y - 2 * m_textMarginY, region->GetFormatMode()); + } +} + +void wxShape::DrawContents(wxDC &dc) +{ + GetEventHandler()->OnDrawContents(dc); +} + +void wxShape::OnSize(double WXUNUSED(x), double WXUNUSED(y)) +{ +} + +bool wxShape::OnMovePre(double WXUNUSED(x), double WXUNUSED(y), double WXUNUSED(old_x), double WXUNUSED(old_y), bool WXUNUSED(display)) +{ + return TRUE; +} + +void wxShape::OnMovePost(double WXUNUSED(x), double WXUNUSED(y), double WXUNUSED(old_x), double WXUNUSED(old_y), bool WXUNUSED(display)) +{ +} + +void wxShape::DrawLinks(wxDC &dc, int attachment, bool recurse) +{ + if (!m_visible) + return; + + wxNode *current = m_lines.GetFirst(); + while (current) + { + wxLineShape *line = (wxLineShape *)current->GetData(); + if (attachment == -1 || + (line->GetTo() == this && line->GetAttachmentTo() == attachment) || + (line->GetFrom() == this && line->GetAttachmentFrom() == attachment)) + line->Draw(dc); + current = current->GetNext(); + } + if (recurse) + { + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + child->DrawLinks(dc, attachment, recurse); + node = node->GetNext(); + } + } +} + +// Returns TRUE if pt1 <= pt2 in the sense that one point comes before another on an +// edge of the shape. +// attachmentPoint is the attachment point (= side) in question. + +// This is the default, rectangular implementation. +bool wxShape::AttachmentSortTest(int attachmentPoint, const wxRealPoint &pt1, const wxRealPoint &pt2) +{ + int physicalAttachment = LogicalToPhysicalAttachment(attachmentPoint); + switch (physicalAttachment) + { + case 0: + case 2: + { + return (pt1.x <= pt2.x) ; + } + case 1: + case 3: + { + return (pt1.y <= pt2.y) ; + } + } + + return FALSE; +} + +bool wxShape::MoveLineToNewAttachment(wxLineShape *to_move, + double x, double y) +{ + if (GetAttachmentMode() == ATTACHMENT_MODE_NONE) + return FALSE; + + int newAttachment, oldAttachment; + double distance; + + // Is (x, y) on this object? If so, find the new attachment point + // the user has moved the point to + bool hit = HitTest(x, y, &newAttachment, &distance); + if (!hit) + return FALSE; + + // EraseLinks(); + + if (to_move->GetTo() == this) + oldAttachment = to_move->GetAttachmentTo(); + else + oldAttachment = to_move->GetAttachmentFrom(); + + // The links in a new ordering. + wxList newOrdering; + + // First, add all links to the new list. + wxNode *node = m_lines.GetFirst(); + while (node) + { + newOrdering.Append(node->GetData()); + node = node->GetNext(); + } + + // Delete the line object from the list of links; we're going to move + // it to another position in the list + newOrdering.DeleteObject(to_move); + + double old_x = (double) - 99999.9; + double old_y = (double) - 99999.9; + + node = newOrdering.GetFirst(); + bool found = FALSE; + + while (!found && node) + { + wxLineShape *line = (wxLineShape *)node->GetData(); + if ((line->GetTo() == this && oldAttachment == line->GetAttachmentTo()) || + (line->GetFrom() == this && oldAttachment == line->GetAttachmentFrom())) + { + double startX, startY, endX, endY; + double xp, yp; + line->GetEnds(&startX, &startY, &endX, &endY); + if (line->GetTo() == this) + { + xp = endX; + yp = endY; + } + else + { + xp = startX; + yp = startY; + } + + wxRealPoint thisPoint(xp, yp); + wxRealPoint lastPoint(old_x, old_y); + wxRealPoint newPoint(x, y); + + if (AttachmentSortTest(newAttachment, newPoint, thisPoint) && AttachmentSortTest(newAttachment, lastPoint, newPoint)) + { + found = TRUE; + newOrdering.Insert(node, to_move); + } + + old_x = xp; + old_y = yp; + } + node = node->GetNext(); + } + + if (!found) + newOrdering.Append(to_move); + + GetEventHandler()->OnChangeAttachment(newAttachment, to_move, newOrdering); + + return TRUE; +} + +void wxShape::OnChangeAttachment(int attachment, wxLineShape *line, wxList &ordering) +{ + if (line->GetTo() == this) + line->SetAttachmentTo(attachment); + else + line->SetAttachmentFrom(attachment); + + ApplyAttachmentOrdering(ordering); + + MoveLinks(); + + GetCanvas()->Refresh(); +} + +// Reorders the lines according to the given list. +void wxShape::ApplyAttachmentOrdering(wxList &linesToSort) +{ + // This is a temporary store of all the lines. + wxList linesStore; + + wxNode *node = m_lines.GetFirst(); + while (node) + { + wxLineShape *line = (wxLineShape *)node->GetData(); + linesStore.Append(line); + node = node->GetNext();; + } + + m_lines.Clear(); + + node = linesToSort.GetFirst(); + while (node) + { + wxLineShape *line = (wxLineShape *)node->GetData(); + if (linesStore.Member(line)) + { + // Done this one + linesStore.DeleteObject(line); + m_lines.Append(line); + } + node = node->GetNext(); + } + + // Now add any lines that haven't been listed in linesToSort. + node = linesStore.GetFirst(); + while (node) + { + wxLineShape *line = (wxLineShape *)node->GetData(); + m_lines.Append(line); + node = node->GetNext(); + } +} + +// Reorders the lines coming into the node image at this attachment +// position, in the order in which they appear in linesToSort. +// Any remaining lines not in the list will be added to the end. +void wxShape::SortLines(int attachment, wxList &linesToSort) +{ + // This is a temporary store of all the lines at this attachment + // point. We'll tick them off as we've processed them. + wxList linesAtThisAttachment; + + wxNode *node = m_lines.GetFirst(); + while (node) + { + wxLineShape *line = (wxLineShape *)node->GetData(); + wxNode *next = node->GetNext(); + if ((line->GetTo() == this && line->GetAttachmentTo() == attachment) || + (line->GetFrom() == this && line->GetAttachmentFrom() == attachment)) + { + linesAtThisAttachment.Append(line); + delete node; + node = next; + } + else node = node->GetNext(); + } + + node = linesToSort.GetFirst(); + while (node) + { + wxLineShape *line = (wxLineShape *)node->GetData(); + if (linesAtThisAttachment.Member(line)) + { + // Done this one + linesAtThisAttachment.DeleteObject(line); + m_lines.Append(line); + } + node = node->GetNext(); + } + + // Now add any lines that haven't been listed in linesToSort. + node = linesAtThisAttachment.GetFirst(); + while (node) + { + wxLineShape *line = (wxLineShape *)node->GetData(); + m_lines.Append(line); + node = node->GetNext(); + } +} + +void wxShape::OnHighlight(wxDC &WXUNUSED(dc)) +{ +} + +void wxShape::OnLeftClick(double x, double y, int keys, int attachment) +{ + if ((m_sensitivity & OP_CLICK_LEFT) != OP_CLICK_LEFT) + { + attachment = 0; + double dist; + if (m_parent) + { + m_parent->HitTest(x, y, &attachment, &dist); + m_parent->GetEventHandler()->OnLeftClick(x, y, keys, attachment); + } + return; + } +} + +void wxShape::OnRightClick(double x, double y, int keys, int attachment) +{ + if ((m_sensitivity & OP_CLICK_RIGHT) != OP_CLICK_RIGHT) + { + attachment = 0; + double dist; + if (m_parent) + { + m_parent->HitTest(x, y, &attachment, &dist); + m_parent->GetEventHandler()->OnRightClick(x, y, keys, attachment); + } + return; + } +} + +double DragOffsetX = 0.0; +double DragOffsetY = 0.0; + +void wxShape::OnDragLeft(bool draw, double x, double y, int keys, int attachment) +{ + if ((m_sensitivity & OP_DRAG_LEFT) != OP_DRAG_LEFT) + { + attachment = 0; + double dist; + if (m_parent) + { + m_parent->HitTest(x, y, &attachment, &dist); + m_parent->GetEventHandler()->OnDragLeft(draw, x, y, keys, attachment); + } + return; + } + + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + dc.SetLogicalFunction(OGLRBLF); + + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + dc.SetPen(dottedPen); + dc.SetBrush(* wxTRANSPARENT_BRUSH); + + double xx, yy; + xx = x + DragOffsetX; + yy = y + DragOffsetY; + + m_canvas->Snap(&xx, &yy); +// m_xpos = xx; m_ypos = yy; + double w, h; + GetBoundingBoxMax(&w, &h); + GetEventHandler()->OnDrawOutline(dc, xx, yy, w, h); +} + +void wxShape::OnBeginDragLeft(double x, double y, int keys, int attachment) +{ + if ((m_sensitivity & OP_DRAG_LEFT) != OP_DRAG_LEFT) + { + attachment = 0; + double dist; + if (m_parent) + { + m_parent->HitTest(x, y, &attachment, &dist); + m_parent->GetEventHandler()->OnBeginDragLeft(x, y, keys, attachment); + } + return; + } + + DragOffsetX = m_xpos - x; + DragOffsetY = m_ypos - y; + + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + double xx, yy; + xx = x + DragOffsetX; + yy = y + DragOffsetY; + m_canvas->Snap(&xx, &yy); +// m_xpos = xx; m_ypos = yy; + dc.SetLogicalFunction(OGLRBLF); + + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + dc.SetPen(dottedPen); + dc.SetBrush((* wxTRANSPARENT_BRUSH)); + + double w, h; + GetBoundingBoxMax(&w, &h); + GetEventHandler()->OnDrawOutline(dc, xx, yy, w, h); + m_canvas->CaptureMouse(); +} + +void wxShape::OnEndDragLeft(double x, double y, int keys, int attachment) +{ + m_canvas->ReleaseMouse(); + if ((m_sensitivity & OP_DRAG_LEFT) != OP_DRAG_LEFT) + { + attachment = 0; + double dist; + if (m_parent) + { + m_parent->HitTest(x, y, &attachment, &dist); + m_parent->GetEventHandler()->OnEndDragLeft(x, y, keys, attachment); + } + return; + } + + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + dc.SetLogicalFunction(wxCOPY); + + double xx = x + DragOffsetX; + double yy = y + DragOffsetY; + m_canvas->Snap(&xx, &yy); +// canvas->Snap(&m_xpos, &m_ypos); + + // New policy: erase shape at end of drag. + // Erase(dc); + + Move(xx, yy); + m_canvas->Refresh(); +} + +void wxShape::OnDragRight(bool draw, double x, double y, int keys, int attachment) +{ + if ((m_sensitivity & OP_DRAG_RIGHT) != OP_DRAG_RIGHT) + { + attachment = 0; + double dist; + if (m_parent) + { + m_parent->HitTest(x, y, &attachment, &dist); + m_parent->GetEventHandler()->OnDragRight(draw, x, y, keys, attachment); + } + return; + } +} + +void wxShape::OnBeginDragRight(double x, double y, int keys, int attachment) +{ + if ((m_sensitivity & OP_DRAG_RIGHT) != OP_DRAG_RIGHT) + { + attachment = 0; + double dist; + if (m_parent) + { + m_parent->HitTest(x, y, &attachment, &dist); + m_parent->GetEventHandler()->OnBeginDragRight(x, y, keys, attachment); + } + return; + } +} + +void wxShape::OnEndDragRight(double x, double y, int keys, int attachment) +{ + if ((m_sensitivity & OP_DRAG_RIGHT) != OP_DRAG_RIGHT) + { + attachment = 0; + double dist; + if (m_parent) + { + m_parent->HitTest(x, y, &attachment, &dist); + m_parent->GetEventHandler()->OnEndDragRight(x, y, keys, attachment); + } + return; + } +} + +void wxShape::OnDrawOutline(wxDC &dc, double x, double y, double w, double h) +{ + double top_left_x = (double)(x - w / 2.0); + double top_left_y = (double)(y - h / 2.0); + double top_right_x = (double)(top_left_x + w); + double top_right_y = (double)top_left_y; + double bottom_left_x = (double)top_left_x; + double bottom_left_y = (double)(top_left_y + h); + double bottom_right_x = (double)top_right_x; + double bottom_right_y = (double)bottom_left_y; + + wxPoint points[5]; + points[0].x = WXROUND(top_left_x); + points[0].y = WXROUND(top_left_y); + points[1].x = WXROUND(top_right_x); + points[1].y = WXROUND(top_right_y); + points[2].x = WXROUND(bottom_right_x); + points[2].y = WXROUND(bottom_right_y); + points[3].x = WXROUND(bottom_left_x); + points[3].y = WXROUND(bottom_left_y); + points[4].x = WXROUND(top_left_x); + points[4].y = WXROUND(top_left_y); + + dc.DrawLines(5, points); +} + +void wxShape::Attach(wxShapeCanvas *can) +{ + m_canvas = can; +} + +void wxShape::Detach() +{ + m_canvas = NULL; +} + +void wxShape::Move(double x, double y, bool display) +{ + double old_x = m_xpos; + double old_y = m_ypos; + + if (!GetEventHandler()->OnMovePre(x, y, old_x, old_y, display)) + { +// m_xpos = old_x; +// m_ypos = old_y; + return; + } + + m_xpos = x; + m_ypos = y; + + ResetControlPoints(); + + if (display) + Refresh(); + + MoveLinks(); + + GetEventHandler()->OnMovePost(x, y, old_x, old_y, display); +} + +void wxShape::MoveLinks() +{ + GetEventHandler()->OnMoveLinks(); +} + + +void wxShape::Draw(wxDC &dc) +{ + if (m_visible) + { + GetEventHandler()->OnDraw(dc); + GetEventHandler()->OnDrawContents(dc); + GetEventHandler()->OnDrawControlPoints(dc); + GetEventHandler()->OnDrawBranches(dc); + } +} + +void wxShape::Flash() +{ + if (GetCanvas()) + { + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + dc.SetLogicalFunction(OGLRBLF); + Draw(dc); + dc.SetLogicalFunction(wxCOPY); + Draw(dc); + } +} + +void wxShape::Show(bool show) +{ + m_visible = show; + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *image = (wxShape *)node->GetData(); + image->Show(show); + node = node->GetNext(); + } +} + +void wxShape::Erase() +{ + Refresh(); +} + +void wxShape::AddText(const wxString &string) +{ + wxNode *node = m_regions.GetFirst(); + if (!node) + return; + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + region->ClearText(); + wxShapeTextLine *new_line = + new wxShapeTextLine(0.0, 0.0, string); + region->GetFormattedText().Append(new_line); + + m_formatted = FALSE; +} + +void wxShape::SetSize(double x, double y, bool WXUNUSED(recursive)) +{ + SetAttachmentSize(x, y); + SetDefaultRegionSize(); +} + +void wxShape::SetAttachmentSize(double w, double h) +{ + double scaleX; + double scaleY; + double width, height; + GetBoundingBoxMin(&width, &height); + if (width == 0.0) + scaleX = 1.0; + else scaleX = w / width; + if (height == 0.0) + scaleY = 1.0; + else scaleY = h / height; + + wxNode *node = m_attachmentPoints.GetFirst(); + while (node) + { + wxAttachmentPoint *point = (wxAttachmentPoint *)node->GetData(); + point->m_x = (double)(point->m_x * scaleX); + point->m_y = (double)(point->m_y * scaleY); + node = node->GetNext(); + } +} + +// Add line FROM this object +void wxShape::AddLine(wxLineShape *line, wxShape *other, + int attachFrom, int attachTo, + // The line ordering + int positionFrom, int positionTo) +{ + if (positionFrom == -1) + { + if (!m_lines.Member(line)) + m_lines.Append(line); + } + else + { + // Don't preserve old ordering if we have new ordering instructions + m_lines.DeleteObject(line); + if (positionFrom < (int) m_lines.GetCount()) + { + wxNode *node = m_lines.Item(positionFrom); + m_lines.Insert(node, line); + } + else + m_lines.Append(line); + } + + if (positionTo == -1) + { + if (!other->m_lines.Member(line)) + other->m_lines.Append(line); + } + else + { + // Don't preserve old ordering if we have new ordering instructions + other->m_lines.DeleteObject(line); + if (positionTo < (int) other->m_lines.GetCount()) + { + wxNode *node = other->m_lines.Item(positionTo); + other->m_lines.Insert(node, line); + } + else + other->m_lines.Append(line); + } +#if 0 + // Wrong: doesn't preserve ordering of shape already linked + m_lines.DeleteObject(line); + other->m_lines.DeleteObject(line); + + if (positionFrom == -1) + m_lines.Append(line); + else + { + if (positionFrom < m_lines.GetCount()) + { + wxNode *node = m_lines.Item(positionFrom); + m_lines.Insert(node, line); + } + else + m_lines.Append(line); + } + + if (positionTo == -1) + other->m_lines.Append(line); + else + { + if (positionTo < other->m_lines.GetCount()) + { + wxNode *node = other->m_lines.Item(positionTo); + other->m_lines.Insert(node, line); + } + else + other->m_lines.Append(line); + } +#endif + + line->SetFrom(this); + line->SetTo(other); + line->SetAttachments(attachFrom, attachTo); +} + +void wxShape::RemoveLine(wxLineShape *line) +{ + if (line->GetFrom() == this) + line->GetTo()->m_lines.DeleteObject(line); + else + line->GetFrom()->m_lines.DeleteObject(line); + + m_lines.DeleteObject(line); +} + +#if wxUSE_PROLOGIO +void wxShape::WriteAttributes(wxExpr *clause) +{ + clause->AddAttributeValueString(wxT("type"), GetClassInfo()->GetClassName()); + clause->AddAttributeValue(wxT("id"), m_id); + + if (m_pen) + { + int penWidth = m_pen->GetWidth(); + int penStyle = m_pen->GetStyle(); + if (penWidth != 1) + clause->AddAttributeValue(wxT("pen_width"), (long)penWidth); + if (penStyle != wxSOLID) + clause->AddAttributeValue(wxT("pen_style"), (long)penStyle); + + wxString penColour = wxTheColourDatabase->FindName(m_pen->GetColour()); + if (penColour == wxEmptyString) + { + wxString hex(oglColourToHex(m_pen->GetColour())); + hex = wxString(wxT("#")) + hex; + clause->AddAttributeValueString(wxT("pen_colour"), hex); + } + else if (penColour != wxT("BLACK")) + clause->AddAttributeValueString(wxT("pen_colour"), penColour); + } + + if (m_brush) + { + wxString brushColour = wxTheColourDatabase->FindName(m_brush->GetColour()); + + if (brushColour == wxEmptyString) + { + wxString hex(oglColourToHex(m_brush->GetColour())); + hex = wxString(wxT("#")) + hex; + clause->AddAttributeValueString(wxT("brush_colour"), hex); + } + else if (brushColour != wxT("WHITE")) + clause->AddAttributeValueString(wxT("brush_colour"), brushColour); + + if (m_brush->GetStyle() != wxSOLID) + clause->AddAttributeValue(wxT("brush_style"), (long)m_brush->GetStyle()); + } + + // Output line ids + + int n_lines = m_lines.GetCount(); + if (n_lines > 0) + { + wxExpr *list = new wxExpr(wxExprList); + wxNode *node = m_lines.GetFirst(); + while (node) + { + wxShape *line = (wxShape *)node->GetData(); + wxExpr *id_expr = new wxExpr(line->GetId()); + list->Append(id_expr); + node = node->GetNext(); + } + clause->AddAttributeValue(wxT("arcs"), list); + } + + // Miscellaneous members + if (m_attachmentMode != 0) + clause->AddAttributeValue(wxT("use_attachments"), (long)m_attachmentMode); + if (m_sensitivity != OP_ALL) + clause->AddAttributeValue(wxT("sensitivity"), (long)m_sensitivity); + if (!m_spaceAttachments) + clause->AddAttributeValue(wxT("space_attachments"), (long)m_spaceAttachments); + if (m_fixedWidth) + clause->AddAttributeValue(wxT("fixed_width"), (long)m_fixedWidth); + if (m_fixedHeight) + clause->AddAttributeValue(wxT("fixed_height"), (long)m_fixedHeight); + if (m_shadowMode != SHADOW_NONE) + clause->AddAttributeValue(wxT("shadow_mode"), (long)m_shadowMode); + if (m_centreResize != TRUE) + clause->AddAttributeValue(wxT("centre_resize"), (long)0); + clause->AddAttributeValue(wxT("maintain_aspect_ratio"), (long) m_maintainAspectRatio); + if (m_highlighted != FALSE) + clause->AddAttributeValue(wxT("hilite"), (long)m_highlighted); + + if (m_parent) // For composite objects + clause->AddAttributeValue(wxT("parent"), (long)m_parent->GetId()); + + if (m_rotation != 0.0) + clause->AddAttributeValue(wxT("rotation"), m_rotation); + + if (!this->IsKindOf(CLASSINFO(wxLineShape))) + { + clause->AddAttributeValue(wxT("neck_length"), (long) m_branchNeckLength); + clause->AddAttributeValue(wxT("stem_length"), (long) m_branchStemLength); + clause->AddAttributeValue(wxT("branch_spacing"), (long) m_branchSpacing); + clause->AddAttributeValue(wxT("branch_style"), (long) m_branchStyle); + } + + // Write user-defined attachment points, if any + if (m_attachmentPoints.GetCount() > 0) + { + wxExpr *attachmentList = new wxExpr(wxExprList); + wxNode *node = m_attachmentPoints.GetFirst(); + while (node) + { + wxAttachmentPoint *point = (wxAttachmentPoint *)node->GetData(); + wxExpr *pointExpr = new wxExpr(wxExprList); + pointExpr->Append(new wxExpr((long)point->m_id)); + pointExpr->Append(new wxExpr(point->m_x)); + pointExpr->Append(new wxExpr(point->m_y)); + attachmentList->Append(pointExpr); + node = node->GetNext(); + } + clause->AddAttributeValue(wxT("user_attachments"), attachmentList); + } + + // Write text regions + WriteRegions(clause); +} + +void wxShape::WriteRegions(wxExpr *clause) +{ + // Output regions as region1 = (...), region2 = (...), etc + // and formatted text as text1 = (...), text2 = (...) etc. + int regionNo = 1; + wxChar regionNameBuf[20]; + wxChar textNameBuf[20]; + wxNode *node = m_regions.GetFirst(); + while (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + wxSprintf(regionNameBuf, wxT("region%d"), regionNo); + wxSprintf(textNameBuf, wxT("text%d"), regionNo); + + // Original text and region attributes: + // region1 = (regionName regionText x y width height minWidth minHeight proportionX proportionY + // formatMode fontSize fontFamily fontStyle fontWeight textColour) + wxExpr *regionExpr = new wxExpr(wxExprList); + regionExpr->Append(new wxExpr(wxExprString, region->m_regionName)); + regionExpr->Append(new wxExpr(wxExprString, region->m_regionText)); + + regionExpr->Append(new wxExpr(region->m_x)); + regionExpr->Append(new wxExpr(region->m_y)); + regionExpr->Append(new wxExpr(region->GetWidth())); + regionExpr->Append(new wxExpr(region->GetHeight())); + + regionExpr->Append(new wxExpr(region->m_minWidth)); + regionExpr->Append(new wxExpr(region->m_minHeight)); + regionExpr->Append(new wxExpr(region->m_regionProportionX)); + regionExpr->Append(new wxExpr(region->m_regionProportionY)); + + regionExpr->Append(new wxExpr((long)region->m_formatMode)); + + regionExpr->Append(new wxExpr((long)(region->m_font ? region->m_font->GetPointSize() : 10))); + regionExpr->Append(new wxExpr((long)(region->m_font ? region->m_font->GetFamily() : wxDEFAULT))); + regionExpr->Append(new wxExpr((long)(region->m_font ? region->m_font->GetStyle() : wxDEFAULT))); + regionExpr->Append(new wxExpr((long)(region->m_font ? region->m_font->GetWeight() : wxNORMAL))); + regionExpr->Append(new wxExpr(wxExprString, region->m_textColour)); + + // New members for pen colour/style + regionExpr->Append(new wxExpr(wxExprString, region->m_penColour)); + regionExpr->Append(new wxExpr((long)region->m_penStyle)); + + // Formatted text: + // text1 = ((x y string) (x y string) ...) + wxExpr *textExpr = new wxExpr(wxExprList); + + wxNode *textNode = region->m_formattedText.GetFirst(); + while (textNode) + { + wxShapeTextLine *line = (wxShapeTextLine *)textNode->GetData(); + wxExpr *list2 = new wxExpr(wxExprList); + list2->Append(new wxExpr(line->GetX())); + list2->Append(new wxExpr(line->GetY())); + list2->Append(new wxExpr(wxExprString, line->GetText())); + textExpr->Append(list2); + textNode = textNode->GetNext(); + } + + // Now add both attributes to the clause + clause->AddAttributeValue(regionNameBuf, regionExpr); + clause->AddAttributeValue(textNameBuf, textExpr); + + node = node->GetNext(); + regionNo ++; + } +} + +void wxShape::ReadAttributes(wxExpr *clause) +{ + clause->GetAttributeValue(wxT("id"), m_id); + wxRegisterId(m_id); + + clause->GetAttributeValue(wxT("x"), m_xpos); + clause->GetAttributeValue(wxT("y"), m_ypos); + + // Input text strings (FOR COMPATIBILITY WITH OLD FILES ONLY. SEE REGION CODE BELOW.) + ClearText(); + wxExpr *strings = clause->AttributeValue(wxT("text")); + if (strings && strings->Type() == wxExprList) + { + m_formatted = TRUE; // Assume text is formatted unless we prove otherwise + wxExpr *node = strings->value.first; + while (node) + { + wxExpr *string_expr = node; + double the_x = 0.0; + double the_y = 0.0; + wxString the_string = wxEmptyString; + + // string_expr can either be a string, or a list of + // 3 elements: x, y, and string. + if (string_expr->Type() == wxExprString) + { + the_string = string_expr->StringValue(); + m_formatted = FALSE; + } + else if (string_expr->Type() == wxExprList) + { + wxExpr *first = string_expr->value.first; + wxExpr *second = first ? first->next : (wxExpr *) NULL; + wxExpr *third = second ? second->next : (wxExpr *) NULL; + + if (first && second && third && + (first->Type() == wxExprReal || first->Type() == wxExprInteger) && + (second->Type() == wxExprReal || second->Type() == wxExprInteger) && + third->Type() == wxExprString) + { + if (first->Type() == wxExprReal) + the_x = first->RealValue(); + else the_x = (double)first->IntegerValue(); + + if (second->Type() == wxExprReal) + the_y = second->RealValue(); + else the_y = (double)second->IntegerValue(); + + the_string = third->StringValue(); + } + } + wxShapeTextLine *line = + new wxShapeTextLine(the_x, the_y, the_string); + m_text.Append(line); + + node = node->next; + } + } + + wxString pen_string = wxEmptyString; + wxString brush_string = wxEmptyString; + int pen_width = 1; + int pen_style = wxSOLID; + int brush_style = wxSOLID; + m_attachmentMode = ATTACHMENT_MODE_NONE; + + clause->GetAttributeValue(wxT("pen_colour"), pen_string); + clause->GetAttributeValue(wxT("text_colour"), m_textColourName); + + SetTextColour(m_textColourName); + + clause->GetAttributeValue(wxT("region_name"), m_regionName); + + clause->GetAttributeValue(wxT("brush_colour"), brush_string); + clause->GetAttributeValue(wxT("pen_width"), pen_width); + clause->GetAttributeValue(wxT("pen_style"), pen_style); + clause->GetAttributeValue(wxT("brush_style"), brush_style); + + int iVal = (int) m_attachmentMode; + clause->GetAttributeValue(wxT("use_attachments"), iVal); + m_attachmentMode = iVal; + + clause->GetAttributeValue(wxT("sensitivity"), m_sensitivity); + + iVal = (int) m_spaceAttachments; + clause->GetAttributeValue(wxT("space_attachments"), iVal); + m_spaceAttachments = (iVal != 0); + + iVal = (int) m_fixedWidth; + clause->GetAttributeValue(wxT("fixed_width"), iVal); + m_fixedWidth = (iVal != 0); + + iVal = (int) m_fixedHeight; + clause->GetAttributeValue(wxT("fixed_height"), iVal); + m_fixedHeight = (iVal != 0); + + clause->GetAttributeValue(wxT("format_mode"), m_formatMode); + clause->GetAttributeValue(wxT("shadow_mode"), m_shadowMode); + + iVal = m_branchNeckLength; + clause->GetAttributeValue(wxT("neck_length"), iVal); + m_branchNeckLength = iVal; + + iVal = m_branchStemLength; + clause->GetAttributeValue(wxT("stem_length"), iVal); + m_branchStemLength = iVal; + + iVal = m_branchSpacing; + clause->GetAttributeValue(wxT("branch_spacing"), iVal); + m_branchSpacing = iVal; + + clause->GetAttributeValue(wxT("branch_style"), m_branchStyle); + + iVal = (int) m_centreResize; + clause->GetAttributeValue(wxT("centre_resize"), iVal); + m_centreResize = (iVal != 0); + + iVal = (int) m_maintainAspectRatio; + clause->GetAttributeValue(wxT("maintain_aspect_ratio"), iVal); + m_maintainAspectRatio = (iVal != 0); + + iVal = (int) m_highlighted; + clause->GetAttributeValue(wxT("hilite"), iVal); + m_highlighted = (iVal != 0); + + clause->GetAttributeValue(wxT("rotation"), m_rotation); + + if (pen_string == wxEmptyString) + pen_string = wxT("BLACK"); + if (brush_string == wxEmptyString) + brush_string = wxT("WHITE"); + + if (pen_string.GetChar(0) == '#') + { + wxColour col(oglHexToColour(pen_string.After('#'))); + m_pen = wxThePenList->FindOrCreatePen(col, pen_width, pen_style); + } + else + m_pen = wxThePenList->FindOrCreatePen(pen_string, pen_width, pen_style); + + if (!m_pen) + m_pen = wxBLACK_PEN; + + if (brush_string.GetChar(0) == '#') + { + wxColour col(oglHexToColour(brush_string.After('#'))); + m_brush = wxTheBrushList->FindOrCreateBrush(col, brush_style); + } + else + m_brush = wxTheBrushList->FindOrCreateBrush(brush_string, brush_style); + + if (!m_brush) + m_brush = wxWHITE_BRUSH; + + int point_size = 10; + clause->GetAttributeValue(wxT("point_size"), point_size); + SetFont(oglMatchFont(point_size)); + + // Read user-defined attachment points, if any + wxExpr *attachmentList = clause->AttributeValue(wxT("user_attachments")); + if (attachmentList) + { + wxExpr *pointExpr = attachmentList->GetFirst(); + while (pointExpr) + { + wxExpr *idExpr = pointExpr->Nth(0); + wxExpr *xExpr = pointExpr->Nth(1); + wxExpr *yExpr = pointExpr->Nth(2); + if (idExpr && xExpr && yExpr) + { + wxAttachmentPoint *point = new wxAttachmentPoint; + point->m_id = (int)idExpr->IntegerValue(); + point->m_x = xExpr->RealValue(); + point->m_y = yExpr->RealValue(); + m_attachmentPoints.Append((wxObject *)point); + } + pointExpr = pointExpr->GetNext(); + } + } + + // Read text regions + ReadRegions(clause); +} + +void wxShape::ReadRegions(wxExpr *clause) +{ + ClearRegions(); + + // region1 = (regionName regionText x y width height minWidth minHeight proportionX proportionY + // formatMode fontSize fontFamily fontStyle fontWeight textColour) + int regionNo = 1; + wxChar regionNameBuf[20]; + wxChar textNameBuf[20]; + + wxExpr *regionExpr; + wxExpr *textExpr = NULL; + wxSprintf(regionNameBuf, wxT("region%d"), regionNo); + wxSprintf(textNameBuf, wxT("text%d"), regionNo); + + m_formatted = TRUE; // Assume text is formatted unless we prove otherwise + + while ((regionExpr = clause->AttributeValue(regionNameBuf)) != NULL) + { + /* + * Get the region information + * + */ + + wxString regionName = wxEmptyString; + wxString regionText = wxEmptyString; + double x = 0.0; + double y = 0.0; + double width = 0.0; + double height = 0.0; + double minWidth = 5.0; + double minHeight = 5.0; + double m_regionProportionX = -1.0; + double m_regionProportionY = -1.0; + int formatMode = FORMAT_NONE; + int fontSize = 10; + int fontFamily = wxSWISS; + int fontStyle = wxNORMAL; + int fontWeight = wxNORMAL; + wxString regionTextColour = wxEmptyString; + wxString penColour = wxEmptyString; + int penStyle = wxSOLID; + + if (regionExpr->Type() == wxExprList) + { + wxExpr *nameExpr = regionExpr->Nth(0); + wxExpr *textExpr = regionExpr->Nth(1); + wxExpr *xExpr = regionExpr->Nth(2); + wxExpr *yExpr = regionExpr->Nth(3); + wxExpr *widthExpr = regionExpr->Nth(4); + wxExpr *heightExpr = regionExpr->Nth(5); + wxExpr *minWidthExpr = regionExpr->Nth(6); + wxExpr *minHeightExpr = regionExpr->Nth(7); + wxExpr *propXExpr = regionExpr->Nth(8); + wxExpr *propYExpr = regionExpr->Nth(9); + wxExpr *formatExpr = regionExpr->Nth(10); + wxExpr *sizeExpr = regionExpr->Nth(11); + wxExpr *familyExpr = regionExpr->Nth(12); + wxExpr *styleExpr = regionExpr->Nth(13); + wxExpr *weightExpr = regionExpr->Nth(14); + wxExpr *colourExpr = regionExpr->Nth(15); + wxExpr *penColourExpr = regionExpr->Nth(16); + wxExpr *penStyleExpr = regionExpr->Nth(17); + + regionName = nameExpr->StringValue(); + regionText = textExpr->StringValue(); + + x = xExpr->RealValue(); + y = yExpr->RealValue(); + + width = widthExpr->RealValue(); + height = heightExpr->RealValue(); + + minWidth = minWidthExpr->RealValue(); + minHeight = minHeightExpr->RealValue(); + + m_regionProportionX = propXExpr->RealValue(); + m_regionProportionY = propYExpr->RealValue(); + + formatMode = (int) formatExpr->IntegerValue(); + fontSize = (int)sizeExpr->IntegerValue(); + fontFamily = (int)familyExpr->IntegerValue(); + fontStyle = (int)styleExpr->IntegerValue(); + fontWeight = (int)weightExpr->IntegerValue(); + + if (colourExpr) + { + regionTextColour = colourExpr->StringValue(); + } + else + regionTextColour = wxT("BLACK"); + + if (penColourExpr) + penColour = penColourExpr->StringValue(); + if (penStyleExpr) + penStyle = (int)penStyleExpr->IntegerValue(); + } + wxFont *font = wxTheFontList->FindOrCreateFont(fontSize, fontFamily, fontStyle, fontWeight); + + wxShapeRegion *region = new wxShapeRegion; + region->SetProportions(m_regionProportionX, m_regionProportionY); + region->SetFont(font); + region->SetSize(width, height); + region->SetPosition(x, y); + region->SetMinSize(minWidth, minHeight); + region->SetFormatMode(formatMode); + region->SetPenStyle(penStyle); + if (penColour != wxEmptyString) + region->SetPenColour(penColour); + + region->m_textColour = regionTextColour; + region->m_regionText = regionText; + region->m_regionName = regionName; + + m_regions.Append(region); + + /* + * Get the formatted text strings + * + */ + textExpr = clause->AttributeValue(textNameBuf); + if (textExpr && (textExpr->Type() == wxExprList)) + { + wxExpr *node = textExpr->value.first; + while (node) + { + wxExpr *string_expr = node; + double the_x = 0.0; + double the_y = 0.0; + wxString the_string = wxEmptyString; + + // string_expr can either be a string, or a list of + // 3 elements: x, y, and string. + if (string_expr->Type() == wxExprString) + { + the_string = string_expr->StringValue(); + m_formatted = FALSE; + } + else if (string_expr->Type() == wxExprList) + { + wxExpr *first = string_expr->value.first; + wxExpr *second = first ? first->next : (wxExpr *) NULL; + wxExpr *third = second ? second->next : (wxExpr *) NULL; + + if (first && second && third && + (first->Type() == wxExprReal || first->Type() == wxExprInteger) && + (second->Type() == wxExprReal || second->Type() == wxExprInteger) && + third->Type() == wxExprString) + { + if (first->Type() == wxExprReal) + the_x = first->RealValue(); + else the_x = (double)first->IntegerValue(); + + if (second->Type() == wxExprReal) + the_y = second->RealValue(); + else the_y = (double)second->IntegerValue(); + + the_string = third->StringValue(); + } + } + if (the_string) + { + wxShapeTextLine *line = + new wxShapeTextLine(the_x, the_y, the_string); + region->m_formattedText.Append(line); + } + node = node->next; + } + } + + regionNo ++; + wxSprintf(regionNameBuf, wxT("region%d"), regionNo); + wxSprintf(textNameBuf, wxT("text%d"), regionNo); + } + + // Compatibility: check for no regions (old file). + // Lines and divided rectangles must deal with this compatibility + // theirselves. Composites _may_ not have any regions anyway. + if ((m_regions.GetCount() == 0) && + !this->IsKindOf(CLASSINFO(wxLineShape)) && !this->IsKindOf(CLASSINFO(wxDividedShape)) && + !this->IsKindOf(CLASSINFO(wxCompositeShape))) + { + wxShapeRegion *newRegion = new wxShapeRegion; + newRegion->SetName(wxT("0")); + m_regions.Append((wxObject *)newRegion); + if (m_text.GetCount() > 0) + { + newRegion->ClearText(); + wxNode *node = m_text.GetFirst(); + while (node) + { + wxShapeTextLine *textLine = (wxShapeTextLine *)node->GetData(); + wxNode *next = node->GetNext(); + newRegion->GetFormattedText().Append((wxObject *)textLine); + delete node; + node = next; + } + } + } +} + +#endif + +void wxShape::Copy(wxShape ©) +{ + copy.m_id = m_id; + copy.m_xpos = m_xpos; + copy.m_ypos = m_ypos; + copy.m_pen = m_pen; + copy.m_brush = m_brush; + copy.m_textColour = m_textColour; + copy.m_centreResize = m_centreResize; + copy.m_maintainAspectRatio = m_maintainAspectRatio; + copy.m_attachmentMode = m_attachmentMode; + copy.m_spaceAttachments = m_spaceAttachments; + copy.m_highlighted = m_highlighted; + copy.m_rotation = m_rotation; + copy.m_textColourName = m_textColourName; + copy.m_regionName = m_regionName; + + copy.m_sensitivity = m_sensitivity; + copy.m_draggable = m_draggable; + copy.m_fixedWidth = m_fixedWidth; + copy.m_fixedHeight = m_fixedHeight; + copy.m_formatMode = m_formatMode; + copy.m_drawHandles = m_drawHandles; + + copy.m_visible = m_visible; + copy.m_shadowMode = m_shadowMode; + copy.m_shadowOffsetX = m_shadowOffsetX; + copy.m_shadowOffsetY = m_shadowOffsetY; + copy.m_shadowBrush = m_shadowBrush; + + copy.m_branchNeckLength = m_branchNeckLength; + copy.m_branchStemLength = m_branchStemLength; + copy.m_branchSpacing = m_branchSpacing; + + // Copy text regions + copy.ClearRegions(); + wxNode *node = m_regions.GetFirst(); + while (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + wxShapeRegion *newRegion = new wxShapeRegion(*region); + copy.m_regions.Append(newRegion); + node = node->GetNext(); + } + + // Copy attachments + copy.ClearAttachments(); + node = m_attachmentPoints.GetFirst(); + while (node) + { + wxAttachmentPoint *point = (wxAttachmentPoint *)node->GetData(); + wxAttachmentPoint *newPoint = new wxAttachmentPoint; + newPoint->m_id = point->m_id; + newPoint->m_x = point->m_x; + newPoint->m_y = point->m_y; + copy.m_attachmentPoints.Append((wxObject *)newPoint); + node = node->GetNext(); + } + + // Copy lines + copy.m_lines.Clear(); + node = m_lines.GetFirst(); + while (node) + { + wxLineShape *line = (wxLineShape *) node->GetData(); + copy.m_lines.Append(line); + node = node->GetNext(); + } +} + +// Create and return a new, fully copied object. +wxShape *wxShape::CreateNewCopy(bool resetMapping, bool recompute) +{ + if (resetMapping) + oglObjectCopyMapping.Clear(); + + wxShape *newObject = (wxShape *) GetClassInfo()->CreateObject(); + + wxASSERT( (newObject != NULL) ); + wxASSERT( (newObject->IsKindOf(CLASSINFO(wxShape))) ); + + Copy(*newObject); + + if (GetEventHandler() != this) + { + wxShapeEvtHandler *newHandler = GetEventHandler()->CreateNewCopy(); + newObject->SetEventHandler(newHandler); + newObject->SetPreviousHandler(NULL); + newHandler->SetPreviousHandler(newObject); + newHandler->SetShape(newObject); + } + + if (recompute) + newObject->Recompute(); + return newObject; +} + +// Does the copying for this object, including copying event +// handler data if any. Calls the virtual Copy function. +void wxShape::CopyWithHandler(wxShape ©) +{ + Copy(copy); + + if (GetEventHandler() != this) + { + wxASSERT( copy.GetEventHandler() != NULL ); + wxASSERT( copy.GetEventHandler() != (©) ); + wxASSERT( GetEventHandler()->GetClassInfo() == copy.GetEventHandler()->GetClassInfo() ); + GetEventHandler()->CopyData(* (copy.GetEventHandler())); + } +} + + +// Default - make 6 control points +void wxShape::MakeControlPoints() +{ + double maxX, maxY, minX, minY; + + GetBoundingBoxMax(&maxX, &maxY); + GetBoundingBoxMin(&minX, &minY); + + double widthMin = (double)(minX + CONTROL_POINT_SIZE + 2); + double heightMin = (double)(minY + CONTROL_POINT_SIZE + 2); + + // Offsets from main object + double top = (double)(- (heightMin / 2.0)); + double bottom = (double)(heightMin / 2.0 + (maxY - minY)); + double left = (double)(- (widthMin / 2.0)); + double right = (double)(widthMin / 2.0 + (maxX - minX)); + + wxControlPoint *control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, left, top, + CONTROL_POINT_DIAGONAL); + m_canvas->AddShape(control); + m_controlPoints.Append(control); + + control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, 0, top, + CONTROL_POINT_VERTICAL); + m_canvas->AddShape(control); + m_controlPoints.Append(control); + + control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, right, top, + CONTROL_POINT_DIAGONAL); + m_canvas->AddShape(control); + m_controlPoints.Append(control); + + control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, right, 0, + CONTROL_POINT_HORIZONTAL); + m_canvas->AddShape(control); + m_controlPoints.Append(control); + + control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, right, bottom, + CONTROL_POINT_DIAGONAL); + m_canvas->AddShape(control); + m_controlPoints.Append(control); + + control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, 0, bottom, + CONTROL_POINT_VERTICAL); + m_canvas->AddShape(control); + m_controlPoints.Append(control); + + control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, left, bottom, + CONTROL_POINT_DIAGONAL); + m_canvas->AddShape(control); + m_controlPoints.Append(control); + + control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, left, 0, + CONTROL_POINT_HORIZONTAL); + m_canvas->AddShape(control); + m_controlPoints.Append(control); + +} + +void wxShape::MakeMandatoryControlPoints() +{ + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + child->MakeMandatoryControlPoints(); + node = node->GetNext(); + } +} + +void wxShape::ResetMandatoryControlPoints() +{ + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + child->ResetMandatoryControlPoints(); + node = node->GetNext(); + } +} + +void wxShape::ResetControlPoints() +{ + ResetMandatoryControlPoints(); + + if (m_controlPoints.GetCount() < 1) + return; + + double maxX, maxY, minX, minY; + + GetBoundingBoxMax(&maxX, &maxY); + GetBoundingBoxMin(&minX, &minY); + + double widthMin = (double)(minX + CONTROL_POINT_SIZE + 2); + double heightMin = (double)(minY + CONTROL_POINT_SIZE + 2); + + // Offsets from main object + double top = (double)(- (heightMin / 2.0)); + double bottom = (double)(heightMin / 2.0 + (maxY - minY)); + double left = (double)(- (widthMin / 2.0)); + double right = (double)(widthMin / 2.0 + (maxX - minX)); + + wxNode *node = m_controlPoints.GetFirst(); + wxControlPoint *control = (wxControlPoint *)node->GetData(); + control->m_xoffset = left; + control->m_yoffset = top; + + node = node->GetNext(); + control = (wxControlPoint *)node->GetData(); + control->m_xoffset = 0; + control->m_yoffset = top; + + node = node->GetNext(); + control = (wxControlPoint *)node->GetData(); + control->m_xoffset = right; + control->m_yoffset = top; + + node = node->GetNext(); + control = (wxControlPoint *)node->GetData(); + control->m_xoffset = right; + control->m_yoffset = 0; + + node = node->GetNext(); + control = (wxControlPoint *)node->GetData(); + control->m_xoffset = right; + control->m_yoffset = bottom; + + node = node->GetNext(); + control = (wxControlPoint *)node->GetData(); + control->m_xoffset = 0; + control->m_yoffset = bottom; + + node = node->GetNext(); + control = (wxControlPoint *)node->GetData(); + control->m_xoffset = left; + control->m_yoffset = bottom; + + node = node->GetNext(); + control = (wxControlPoint *)node->GetData(); + control->m_xoffset = left; + control->m_yoffset = 0; +} + +void wxShape::DeleteControlPoints(wxDC *dc) +{ + wxNode *node = m_controlPoints.GetFirst(); + while (node) + { + wxControlPoint *control = (wxControlPoint *)node->GetData(); + control->Refresh(); + m_canvas->RemoveShape(control); + delete control; + delete node; + node = m_controlPoints.GetFirst(); + } + // Children of divisions are contained objects, + // so stop here + if (!IsKindOf(CLASSINFO(wxDivisionShape))) + { + node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + child->DeleteControlPoints(dc); + node = node->GetNext(); + } + } +} + +void wxShape::OnDrawControlPoints(wxDC &dc) +{ + if (!m_drawHandles) + return; + + dc.SetBrush(* wxBLACK_BRUSH); + dc.SetPen(* wxBLACK_PEN); + + wxNode *node = m_controlPoints.GetFirst(); + while (node) + { + wxControlPoint *control = (wxControlPoint *)node->GetData(); + control->Draw(dc); + node = node->GetNext(); + } + // Children of divisions are contained objects, + // so stop here. + // This test bypasses the type facility for speed + // (critical when drawing) + if (!IsKindOf(CLASSINFO(wxDivisionShape))) + { + node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + child->GetEventHandler()->OnDrawControlPoints(dc); + node = node->GetNext(); + } + } +} + +void wxShape::Select(bool select) +{ + m_selected = select; + if (select) + { + MakeControlPoints(); + // Children of divisions are contained objects, + // so stop here + if (!IsKindOf(CLASSINFO(wxDivisionShape))) + { + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + child->MakeMandatoryControlPoints(); + node = node->GetNext(); + } + } + } + if (!select) + { + DeleteControlPoints(); + if (!IsKindOf(CLASSINFO(wxDivisionShape))) + { + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + node = node->GetNext(); + } + } + } + Refresh(); +} + +bool wxShape::Selected() const +{ + return m_selected; +} + +bool wxShape::AncestorSelected() const +{ + if (m_selected) return TRUE; + if (!GetParent()) + return FALSE; + else + return GetParent()->AncestorSelected(); +} + +int wxShape::GetNumberOfAttachments() const +{ + // Should return the MAXIMUM attachment point id here, + // so higher-level functions can iterate through all attachments, + // even if they're not contiguous. + if (m_attachmentPoints.GetCount() == 0) + return 4; + else + { + int maxN = 3; + wxNode *node = m_attachmentPoints.GetFirst(); + while (node) + { + wxAttachmentPoint *point = (wxAttachmentPoint *)node->GetData(); + if (point->m_id > maxN) + maxN = point->m_id; + node = node->GetNext(); + } + return maxN + 1;; + } +} + +bool wxShape::AttachmentIsValid(int attachment) const +{ + if (m_attachmentPoints.GetCount() == 0) + { + return ((attachment >= 0) && (attachment < 4)) ; + } + + wxNode *node = m_attachmentPoints.GetFirst(); + while (node) + { + wxAttachmentPoint *point = (wxAttachmentPoint *)node->GetData(); + if (point->m_id == attachment) + return TRUE; + node = node->GetNext(); + } + return FALSE; +} + +bool wxShape::GetAttachmentPosition(int attachment, double *x, double *y, + int nth, int no_arcs, wxLineShape *line) +{ + if (m_attachmentMode == ATTACHMENT_MODE_NONE) + { + *x = m_xpos; + *y = m_ypos; + return TRUE; + } + else if (m_attachmentMode == ATTACHMENT_MODE_BRANCHING) + { + wxRealPoint pt, stemPt; + GetBranchingAttachmentPoint(attachment, nth, pt, stemPt); + *x = pt.x; + *y = pt.y; + return TRUE; + } + else if (m_attachmentMode == ATTACHMENT_MODE_EDGE) + { + if (m_attachmentPoints.GetCount() > 0) + { + wxNode *node = m_attachmentPoints.GetFirst(); + while (node) + { + wxAttachmentPoint *point = (wxAttachmentPoint *)node->GetData(); + if (point->m_id == attachment) + { + *x = (double)(m_xpos + point->m_x); + *y = (double)(m_ypos + point->m_y); + return TRUE; + } + node = node->GetNext(); + } + *x = m_xpos; + *y = m_ypos; + return FALSE; + } + else + { + // Assume is rectangular + double w, h; + GetBoundingBoxMax(&w, &h); + double top = (double)(m_ypos + h / 2.0); + double bottom = (double)(m_ypos - h / 2.0); + double left = (double)(m_xpos - w / 2.0); + double right = (double)(m_xpos + w / 2.0); + + /* bool isEnd = */ + (line && line->IsEnd(this)); + + int physicalAttachment = LogicalToPhysicalAttachment(attachment); + + // Simplified code + switch (physicalAttachment) + { + case 0: + { + wxRealPoint pt = CalcSimpleAttachment(wxRealPoint(left, bottom), wxRealPoint(right, bottom), + nth, no_arcs, line); + + *x = pt.x; + *y = pt.y; + break; + } + case 1: + { + wxRealPoint pt = CalcSimpleAttachment(wxRealPoint(right, bottom), wxRealPoint(right, top), + nth, no_arcs, line); + + *x = pt.x; + *y = pt.y; + break; + } + case 2: + { + wxRealPoint pt = CalcSimpleAttachment(wxRealPoint(left, top), wxRealPoint(right, top), + nth, no_arcs, line); + + *x = pt.x; + *y = pt.y; + break; + } + case 3: + { + wxRealPoint pt = CalcSimpleAttachment(wxRealPoint(left, bottom), wxRealPoint(left, top), + nth, no_arcs, line); + + *x = pt.x; + *y = pt.y; + break; + } + default: + { + return FALSE; + } + } + return TRUE; + } + } + return FALSE; +} + +void wxShape::GetBoundingBoxMax(double *w, double *h) +{ + double ww, hh; + GetBoundingBoxMin(&ww, &hh); + if (m_shadowMode != SHADOW_NONE) + { + ww += m_shadowOffsetX; + hh += m_shadowOffsetY; + } + *w = ww; + *h = hh; +} + +// Returns TRUE if image is a descendant of this composite +bool wxShape::HasDescendant(wxShape *image) +{ + if (image == this) + return TRUE; + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + bool ans = child->HasDescendant(image); + if (ans) + return TRUE; + node = node->GetNext(); + } + return FALSE; +} + +// Clears points from a list of wxRealPoints, and clears list +void wxShape::ClearPointList(wxList &list) +{ + wxNode *node = list.GetFirst(); + while (node) + { + wxRealPoint *pt = (wxRealPoint *) node->GetData(); + delete pt; + + node = node->GetNext(); + } + list.Clear(); +} + +// Assuming the attachment lies along a vertical or horizontal line, +// calculate the position on that point. +wxRealPoint wxShape::CalcSimpleAttachment(const wxRealPoint &pt1, const wxRealPoint &pt2, + int nth, int noArcs, wxLineShape *line) +{ + bool isEnd = (line && line->IsEnd(this)); + + // Are we horizontal or vertical? + bool isHorizontal = (oglRoughlyEqual(pt1.y, pt2.y) == TRUE); + + double x, y; + + if (isHorizontal) + { + wxRealPoint firstPoint, secondPoint; + if (pt1.x > pt2.x) + { + firstPoint = pt2; + secondPoint = pt1; + } + else + { + firstPoint = pt1; + secondPoint = pt2; + } + + if (m_spaceAttachments) + { + if (line && (line->GetAlignmentType(isEnd) == LINE_ALIGNMENT_TO_NEXT_HANDLE)) + { + // Align line according to the next handle along + wxRealPoint *point = line->GetNextControlPoint(this); + if (point->x < firstPoint.x) + x = firstPoint.x; + else if (point->x > secondPoint.x) + x = secondPoint.x; + else + x = point->x; + } + else + x = firstPoint.x + (nth + 1) * (secondPoint.x - firstPoint.x) / (noArcs + 1); + } + else x = (secondPoint.x - firstPoint.x) / 2.0; // Midpoint + + y = pt1.y; + } + else + { + wxASSERT( oglRoughlyEqual(pt1.x, pt2.x) == TRUE ); + + wxRealPoint firstPoint, secondPoint; + if (pt1.y > pt2.y) + { + firstPoint = pt2; + secondPoint = pt1; + } + else + { + firstPoint = pt1; + secondPoint = pt2; + } + + if (m_spaceAttachments) + { + if (line && (line->GetAlignmentType(isEnd) == LINE_ALIGNMENT_TO_NEXT_HANDLE)) + { + // Align line according to the next handle along + wxRealPoint *point = line->GetNextControlPoint(this); + if (point->y < firstPoint.y) + y = firstPoint.y; + else if (point->y > secondPoint.y) + y = secondPoint.y; + else + y = point->y; + } + else + y = firstPoint.y + (nth + 1) * (secondPoint.y - firstPoint.y) / (noArcs + 1); + } + else y = (secondPoint.y - firstPoint.y) / 2.0; // Midpoint + + x = pt1.x; + } + + return wxRealPoint(x, y); +} + +// Return the zero-based position in m_lines of line. +int wxShape::GetLinePosition(wxLineShape *line) +{ + for (size_t i = 0; i < m_lines.GetCount(); i++) + if ((wxLineShape *) (m_lines.Item(i)->GetData()) == line) + return i; + + return 0; +} + +// +// |________| +// | <- root +// | <- neck +// shoulder1 ->---------<- shoulder2 +// | | | | | +// <- branching attachment point N-1 + +// This function gets information about where branching connections go. +// Returns FALSE if there are no lines at this attachment. +bool wxShape::GetBranchingAttachmentInfo(int attachment, wxRealPoint &root, wxRealPoint &neck, + wxRealPoint &shoulder1, wxRealPoint &shoulder2) +{ + int physicalAttachment = LogicalToPhysicalAttachment(attachment); + + // Number of lines at this attachment. + int lineCount = GetAttachmentLineCount(attachment); + + if (lineCount == 0) + return FALSE; + + int totalBranchLength = m_branchSpacing * (lineCount - 1); + + root = GetBranchingAttachmentRoot(attachment); + + // Assume that we have attachment points 0 to 3: top, right, bottom, left. + switch (physicalAttachment) + { + case 0: + { + neck.x = GetX(); + neck.y = root.y - m_branchNeckLength; + + shoulder1.x = root.x - (totalBranchLength / 2.0) ; + shoulder2.x = root.x + (totalBranchLength / 2.0) ; + + shoulder1.y = neck.y; + shoulder2.y = neck.y; + break; + } + case 1: + { + neck.x = root.x + m_branchNeckLength; + neck.y = root.y; + + shoulder1.x = neck.x ; + shoulder2.x = neck.x ; + + shoulder1.y = neck.y - (totalBranchLength / 2.0) ; + shoulder2.y = neck.y + (totalBranchLength / 2.0) ; + break; + } + case 2: + { + neck.x = GetX(); + neck.y = root.y + m_branchNeckLength; + + shoulder1.x = root.x - (totalBranchLength / 2.0) ; + shoulder2.x = root.x + (totalBranchLength / 2.0) ; + + shoulder1.y = neck.y; + shoulder2.y = neck.y; + break; + } + case 3: + { + neck.x = root.x - m_branchNeckLength; + neck.y = root.y ; + + shoulder1.x = neck.x ; + shoulder2.x = neck.x ; + + shoulder1.y = neck.y - (totalBranchLength / 2.0) ; + shoulder2.y = neck.y + (totalBranchLength / 2.0) ; + break; + } + default: + { + wxFAIL_MSG( wxT("Unrecognised attachment point in GetBranchingAttachmentInfo.") ); + break; + } + } + return TRUE; +} + +// n is the number of the adjoining line, from 0 to N-1 where N is the number of lines +// at this attachment point. +// Get the attachment point where the arc joins the stem, and also the point where the +// the stem meets the shoulder. +bool wxShape::GetBranchingAttachmentPoint(int attachment, int n, wxRealPoint &pt, wxRealPoint &stemPt) +{ + int physicalAttachment = LogicalToPhysicalAttachment(attachment); + + wxRealPoint root, neck, shoulder1, shoulder2; + GetBranchingAttachmentInfo(attachment, root, neck, shoulder1, shoulder2); + + // Assume that we have attachment points 0 to 3: top, right, bottom, left. + switch (physicalAttachment) + { + case 0: + { + pt.y = neck.y - m_branchStemLength; + pt.x = shoulder1.x + n * m_branchSpacing; + + stemPt.x = pt.x; + stemPt.y = neck.y; + break; + } + case 2: + { + pt.y = neck.y + m_branchStemLength; + pt.x = shoulder1.x + n * m_branchSpacing; + + stemPt.x = pt.x; + stemPt.y = neck.y; + break; + } + case 1: + { + pt.x = neck.x + m_branchStemLength; + pt.y = shoulder1.y + n * m_branchSpacing; + + stemPt.x = neck.x; + stemPt.y = pt.y; + break; + } + case 3: + { + pt.x = neck.x - m_branchStemLength; + pt.y = shoulder1.y + n * m_branchSpacing; + + stemPt.x = neck.x; + stemPt.y = pt.y; + break; + } + default: + { + wxFAIL_MSG( wxT("Unrecognised attachment point in GetBranchingAttachmentPoint.") ); + break; + } + } + + return TRUE; +} + +// Get the number of lines at this attachment position. +int wxShape::GetAttachmentLineCount(int attachment) const +{ + int count = 0; + wxNode *node = m_lines.GetFirst(); + while (node) + { + wxLineShape *lineShape = (wxLineShape *) node->GetData(); + if ((lineShape->GetFrom() == this) && (lineShape->GetAttachmentFrom() == attachment)) + count ++; + else if ((lineShape->GetTo() == this) && (lineShape->GetAttachmentTo() == attachment)) + count ++; + + node = node->GetNext(); + } + return count; +} + +// This function gets the root point at the given attachment. +wxRealPoint wxShape::GetBranchingAttachmentRoot(int attachment) +{ + int physicalAttachment = LogicalToPhysicalAttachment(attachment); + + wxRealPoint root; + + double width, height; + GetBoundingBoxMax(& width, & height); + + // Assume that we have attachment points 0 to 3: top, right, bottom, left. + switch (physicalAttachment) + { + case 0: + { + root.x = GetX() ; + root.y = GetY() - height / 2.0; + break; + } + case 1: + { + root.x = GetX() + width / 2.0; + root.y = GetY() ; + break; + } + case 2: + { + root.x = GetX() ; + root.y = GetY() + height / 2.0; + break; + } + case 3: + { + root.x = GetX() - width / 2.0; + root.y = GetY() ; + break; + } + default: + { + wxFAIL_MSG( wxT("Unrecognised attachment point in GetBranchingAttachmentRoot.") ); + break; + } + } + return root; +} + +// Draw or erase the branches (not the actual arcs though) +void wxShape::OnDrawBranches(wxDC &dc, int attachment, bool erase) +{ + if (erase) + { + Refresh(); + return; + } + + int count = GetAttachmentLineCount(attachment); + if (count == 0) + return; + + wxRealPoint root, neck, shoulder1, shoulder2; + GetBranchingAttachmentInfo(attachment, root, neck, shoulder1, shoulder2); + +#if 0 + if (erase) + { + dc.SetPen(*wxWHITE_PEN); + dc.SetBrush(*wxWHITE_BRUSH); + } + else +#endif + { + dc.SetPen(*wxBLACK_PEN); + dc.SetBrush(*wxBLACK_BRUSH); + } + + // Draw neck + dc.DrawLine((long) root.x, (long) root.y, (long) neck.x, (long) neck.y); + + if (count > 1) + { + // Draw shoulder-to-shoulder line + dc.DrawLine((long) shoulder1.x, (long) shoulder1.y, (long) shoulder2.x, (long) shoulder2.y); + } + // Draw all the little branches + int i; + for (i = 0; i < count; i++) + { + wxRealPoint pt, stemPt; + GetBranchingAttachmentPoint(attachment, i, pt, stemPt); + dc.DrawLine((long) stemPt.x, (long) stemPt.y, (long) pt.x, (long) pt.y); + + if ((GetBranchStyle() & BRANCHING_ATTACHMENT_BLOB) && (count > 1)) + { + long blobSize = 6; +// dc.DrawEllipse((long) (stemPt.x + 0.5 - (blobSize/2.0)), (long) (stemPt.y + 0.5 - (blobSize/2.0)), blobSize, blobSize); + dc.DrawEllipse((long) (stemPt.x - (blobSize / 2.0)), (long) (stemPt.y - (blobSize / 2.0)), blobSize, blobSize); + } + } +} + +// Draw or erase the branches (not the actual arcs though) +void wxShape::OnDrawBranches(wxDC &dc, bool erase) +{ + if (m_attachmentMode != ATTACHMENT_MODE_BRANCHING) + return; + + int count = GetNumberOfAttachments(); + int i; + for (i = 0; i < count; i++) + OnDrawBranches(dc, i, erase); +} + +// Only get the attachment position at the _edge_ of the shape, ignoring +// branching mode. This is used e.g. to indicate the edge of interest, not the point +// on the attachment branch. +bool wxShape::GetAttachmentPositionEdge(int attachment, double *x, double *y, + int nth, int no_arcs, wxLineShape *line) +{ + int oldMode = m_attachmentMode; + + // Calculate as if to edge, not branch + if (m_attachmentMode == ATTACHMENT_MODE_BRANCHING) + m_attachmentMode = ATTACHMENT_MODE_EDGE; + bool success = GetAttachmentPosition(attachment, x, y, nth, no_arcs, line); + m_attachmentMode = oldMode; + + return success; +} + +// Rotate the standard attachment point from physical (0 is always North) +// to logical (0 -> 1 if rotated by 90 degrees) +int wxShape::PhysicalToLogicalAttachment(int physicalAttachment) const +{ + const double pi = 3.1415926535897932384626433832795 ; + int i; + if (oglRoughlyEqual(GetRotation(), 0.0)) + { + i = physicalAttachment; + } + else if (oglRoughlyEqual(GetRotation(), (pi / 2.0))) + { + i = physicalAttachment - 1; + } + else if (oglRoughlyEqual(GetRotation(), pi)) + { + i = physicalAttachment - 2; + } + else if (oglRoughlyEqual(GetRotation(), (3.0 * pi / 2.0))) + { + i = physicalAttachment - 3; + } + else + // Can't handle -- assume the same. + return physicalAttachment; + + if (i < 0) + i += 4; + + return i; +} + +// Rotate the standard attachment point from logical +// to physical (0 is always North) +int wxShape::LogicalToPhysicalAttachment(int logicalAttachment) const +{ + const double pi = 3.1415926535897932384626433832795 ; + int i; + if (oglRoughlyEqual(GetRotation(), 0.0)) + { + i = logicalAttachment; + } + else if (oglRoughlyEqual(GetRotation(), (pi / 2.0))) + { + i = logicalAttachment + 1; + } + else if (oglRoughlyEqual(GetRotation(), pi)) + { + i = logicalAttachment + 2; + } + else if (oglRoughlyEqual(GetRotation(), (3.0 * pi / 2.0))) + { + i = logicalAttachment + 3; + } + else + // Can't handle -- assume the same. + return logicalAttachment; + + if (i > 3) + i -= 4; + + return i; +} + +void wxShape::Rotate(double WXUNUSED(x), double WXUNUSED(y), double theta) +{ + const double pi = 3.1415926535897932384626433832795 ; + m_rotation = theta; + if (m_rotation < 0.0) + { + m_rotation += 2 * pi; + } + else if (m_rotation > 2 * pi) + { + m_rotation -= 2 * pi; + } +} + + +wxPen wxShape::GetBackgroundPen() +{ + if (GetCanvas()) + { + wxColour c = GetCanvas()->GetBackgroundColour(); + return wxPen(c, 1, wxSOLID); + } + return * g_oglWhiteBackgroundPen; +} + + +wxBrush wxShape::GetBackgroundBrush() +{ + if (GetCanvas()) + { + wxColour c = GetCanvas()->GetBackgroundColour(); + return wxBrush(c, wxSOLID); + } + return * g_oglWhiteBackgroundBrush; +} + diff --git a/ogl/basic2.cpp b/ogl/basic2.cpp new file mode 100644 index 0000000..78d0541 --- /dev/null +++ b/ogl/basic2.cpp @@ -0,0 +1,1880 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// basic2.cpp - Basic OGL classes (2) +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include +#include +#include + +#include "ogl/ogl.h" + + +// Control point types +// Rectangle and most other shapes +#define CONTROL_POINT_VERTICAL 1 +#define CONTROL_POINT_HORIZONTAL 2 +#define CONTROL_POINT_DIAGONAL 3 + +// Line +#define CONTROL_POINT_ENDPOINT_TO 4 +#define CONTROL_POINT_ENDPOINT_FROM 5 +#define CONTROL_POINT_LINE 6 + +// Two stage construction: need to call Create +IMPLEMENT_DYNAMIC_CLASS(wxPolygonShape, wxShape) + +wxPolygonShape::wxPolygonShape() +{ + m_points = NULL; + m_originalPoints = NULL; +} + +void wxPolygonShape::Create(wxList *the_points) +{ + ClearPoints(); + + if (!the_points) + { + m_originalPoints = new wxList; + m_points = new wxList; + } + else + { + m_originalPoints = the_points; + + // Duplicate the list of points + m_points = new wxList; + + wxNode *node = the_points->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + wxRealPoint *new_point = new wxRealPoint(point->x, point->y); + m_points->Append((wxObject *) new_point); + node = node->GetNext(); + } + CalculateBoundingBox(); + m_originalWidth = m_boundWidth; + m_originalHeight = m_boundHeight; + SetDefaultRegionSize(); + } +} + +wxPolygonShape::~wxPolygonShape() +{ + ClearPoints(); +} + +void wxPolygonShape::ClearPoints() +{ + if (m_points) + { + wxNode *node = m_points->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + delete point; + delete node; + node = m_points->GetFirst(); + } + delete m_points; + m_points = NULL; + } + if (m_originalPoints) + { + wxNode *node = m_originalPoints->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + delete point; + delete node; + node = m_originalPoints->GetFirst(); + } + delete m_originalPoints; + m_originalPoints = NULL; + } +} + + +// Width and height. Centre of object is centre of box. +void wxPolygonShape::GetBoundingBoxMin(double *width, double *height) +{ + *width = m_boundWidth; + *height = m_boundHeight; +} + +void wxPolygonShape::CalculateBoundingBox() +{ + // Calculate bounding box at construction (and presumably resize) time + double left = 10000; + double right = -10000; + double top = 10000; + double bottom = -10000; + + wxNode *node = m_points->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + if (point->x < left) left = point->x; + if (point->x > right) right = point->x; + + if (point->y < top) top = point->y; + if (point->y > bottom) bottom = point->y; + + node = node->GetNext(); + } + m_boundWidth = right - left; + m_boundHeight = bottom - top; +} + +// Recalculates the centre of the polygon, and +// readjusts the point offsets accordingly. +// Necessary since the centre of the polygon +// is expected to be the real centre of the bounding +// box. +void wxPolygonShape::CalculatePolygonCentre() +{ + double left = 10000; + double right = -10000; + double top = 10000; + double bottom = -10000; + + wxNode *node = m_points->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + if (point->x < left) left = point->x; + if (point->x > right) right = point->x; + + if (point->y < top) top = point->y; + if (point->y > bottom) bottom = point->y; + + node = node->GetNext(); + } + double bwidth = right - left; + double bheight = bottom - top; + + double newCentreX = (double)(left + (bwidth / 2.0)); + double newCentreY = (double)(top + (bheight / 2.0)); + + node = m_points->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + point->x -= newCentreX; + point->y -= newCentreY; + node = node->GetNext(); + } + m_xpos += newCentreX; + m_ypos += newCentreY; +} + +bool PolylineHitTest(double n, double xvec[], double yvec[], + double x1, double y1, double x2, double y2) +{ + bool isAHit = FALSE; + int i; + double lastx = xvec[0]; + double lasty = yvec[0]; + + double min_ratio = 1.0; + double line_ratio; + double other_ratio; + + for (i = 1; i < n; i++) + { + oglCheckLineIntersection(x1, y1, x2, y2, lastx, lasty, xvec[i], yvec[i], + &line_ratio, &other_ratio); + if (line_ratio != 1.0) + isAHit = TRUE; + lastx = xvec[i]; + lasty = yvec[i]; + + if (line_ratio < min_ratio) + min_ratio = line_ratio; + } + + // Do last (implicit) line if last and first doubles are not identical + if (!(xvec[0] == lastx && yvec[0] == lasty)) + { + oglCheckLineIntersection(x1, y1, x2, y2, lastx, lasty, xvec[0], yvec[0], + &line_ratio, &other_ratio); + if (line_ratio != 1.0) + isAHit = TRUE; + + } + return isAHit; +} + +bool wxPolygonShape::HitTest(double x, double y, int *attachment, double *distance) +{ + // Imagine four lines radiating from this point. If all of these lines hit the polygon, + // we're inside it, otherwise we're not. Obviously we'd need more radiating lines + // to be sure of correct results for very strange (concave) shapes. + double endPointsX[4]; + double endPointsY[4]; + // North + endPointsX[0] = x; + endPointsY[0] = (double)(y - 1000.0); + // East + endPointsX[1] = (double)(x + 1000.0); + endPointsY[1] = y; + // South + endPointsX[2] = x; + endPointsY[2] = (double)(y + 1000.0); + // West + endPointsX[3] = (double)(x - 1000.0); + endPointsY[3] = y; + + // Store polygon points in an array + int np = m_points->GetCount(); + double *xpoints = new double[np]; + double *ypoints = new double[np]; + wxNode *node = m_points->GetFirst(); + int i = 0; + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + xpoints[i] = point->x + m_xpos; + ypoints[i] = point->y + m_ypos; + node = node->GetNext(); + i ++; + } + + // We assume it's inside the polygon UNLESS one or more + // lines don't hit the outline. + bool isContained = TRUE; + + int noPoints = 4; + for (i = 0; i < noPoints; i++) + { + if (!PolylineHitTest(np, xpoints, ypoints, x, y, endPointsX[i], endPointsY[i])) + isContained = FALSE; + } + /* + if (isContained) + ClipsErrorFunction("It's a hit!\n"); + else + ClipsErrorFunction("No hit.\n"); + */ + delete[] xpoints; + delete[] ypoints; + + if (!isContained) + return FALSE; + + int nearest_attachment = 0; + + // If a hit, check the attachment points within the object. + int n = GetNumberOfAttachments(); + double nearest = 999999.0; + + for (i = 0; i < n; i++) + { + double xp, yp; + if (GetAttachmentPositionEdge(i, &xp, &yp)) + { + double l = (double)sqrt(((xp - x) * (xp - x)) + + ((yp - y) * (yp - y))); + if (l < nearest) + { + nearest = l; + nearest_attachment = i; + } + } + } + *attachment = nearest_attachment; + *distance = nearest; + return TRUE; +} + +// Really need to be able to reset the shape! Otherwise, if the +// points ever go to zero, we've lost it, and can't resize. +void wxPolygonShape::SetSize(double new_width, double new_height, bool WXUNUSED(recursive)) +{ + SetAttachmentSize(new_width, new_height); + + // Multiply all points by proportion of new size to old size + double x_proportion = (double)(fabs(new_width / m_originalWidth)); + double y_proportion = (double)(fabs(new_height / m_originalHeight)); + + wxNode *node = m_points->GetFirst(); + wxNode *original_node = m_originalPoints->GetFirst(); + while (node && original_node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + wxRealPoint *original_point = (wxRealPoint *)original_node->GetData(); + + point->x = (original_point->x * x_proportion); + point->y = (original_point->y * y_proportion); + + node = node->GetNext(); + original_node = original_node->GetNext(); + } + +// CalculateBoundingBox(); + m_boundWidth = (double)fabs(new_width); + m_boundHeight = (double)fabs(new_height); + SetDefaultRegionSize(); +} + +// Make the original points the same as the working points +void wxPolygonShape::UpdateOriginalPoints() +{ + if (!m_originalPoints) m_originalPoints = new wxList; + wxNode *original_node = m_originalPoints->GetFirst(); + while (original_node) + { + wxNode *next_node = original_node->GetNext(); + wxRealPoint *original_point = (wxRealPoint *)original_node->GetData(); + delete original_point; + delete original_node; + + original_node = next_node; + } + + wxNode *node = m_points->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + wxRealPoint *original_point = new wxRealPoint(point->x, point->y); + m_originalPoints->Append((wxObject *) original_point); + + node = node->GetNext(); + } + CalculateBoundingBox(); + m_originalWidth = m_boundWidth; + m_originalHeight = m_boundHeight; +} + +void wxPolygonShape::AddPolygonPoint(int pos) +{ + wxNode *node = m_points->Item(pos); + if (!node) node = m_points->GetFirst(); + wxRealPoint *firstPoint = (wxRealPoint *)node->GetData(); + + wxNode *node2 = m_points->Item(pos + 1); + if (!node2) node2 = m_points->GetFirst(); + wxRealPoint *secondPoint = (wxRealPoint *)node2->GetData(); + + double x = (double)((secondPoint->x - firstPoint->x) / 2.0 + firstPoint->x); + double y = (double)((secondPoint->y - firstPoint->y) / 2.0 + firstPoint->y); + wxRealPoint *point = new wxRealPoint(x, y); + + if (pos >= (int) (m_points->GetCount() - 1)) + m_points->Append((wxObject *) point); + else + m_points->Insert(node2, (wxObject *) point); + + UpdateOriginalPoints(); + + if (m_selected) + { + DeleteControlPoints(); + MakeControlPoints(); + } +} + +void wxPolygonShape::DeletePolygonPoint(int pos) +{ + wxNode *node = m_points->Item(pos); + if (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + delete point; + delete node; + UpdateOriginalPoints(); + if (m_selected) + { + DeleteControlPoints(); + MakeControlPoints(); + } + } +} + +// Assume (x1, y1) is centre of box (most generally, line end at box) +bool wxPolygonShape::GetPerimeterPoint(double x1, double y1, + double x2, double y2, + double *x3, double *y3) +{ + int n = m_points->GetCount(); + + // First check for situation where the line is vertical, + // and we would want to connect to a point on that vertical -- + // oglFindEndForPolyline can't cope with this (the arrow + // gets drawn to the wrong place). + if ((m_attachmentMode == ATTACHMENT_MODE_NONE) && (x1 == x2)) + { + // Look for the point we'd be connecting to. This is + // a heuristic... + wxNode *node = m_points->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + if (point->x == 0.0) + { + if ((y2 > y1) && (point->y > 0.0)) + { + *x3 = point->x + m_xpos; + *y3 = point->y + m_ypos; + return TRUE; + } + else if ((y2 < y1) && (point->y < 0.0)) + { + *x3 = point->x + m_xpos; + *y3 = point->y + m_ypos; + return TRUE; + } + } + node = node->GetNext(); + } + } + + double *xpoints = new double[n]; + double *ypoints = new double[n]; + + wxNode *node = m_points->GetFirst(); + int i = 0; + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + xpoints[i] = point->x + m_xpos; + ypoints[i] = point->y + m_ypos; + node = node->GetNext(); + i ++; + } + + oglFindEndForPolyline(n, xpoints, ypoints, + x1, y1, x2, y2, x3, y3); + + delete[] xpoints; + delete[] ypoints; + + return TRUE; +} + +void wxPolygonShape::OnDraw(wxDC &dc) +{ + int n = m_points->GetCount(); + wxPoint *intPoints = new wxPoint[n]; + int i; + for (i = 0; i < n; i++) + { + wxRealPoint *point = (wxRealPoint *) m_points->Item(i)->GetData(); + intPoints[i].x = WXROUND(point->x); + intPoints[i].y = WXROUND(point->y); + } + + if (m_shadowMode != SHADOW_NONE) + { + if (m_shadowBrush) + dc.SetBrush(* m_shadowBrush); + dc.SetPen(* g_oglTransparentPen); + + dc.DrawPolygon(n, intPoints, WXROUND(m_xpos + m_shadowOffsetX), WXROUND(m_ypos + m_shadowOffsetY)); + } + + if (m_pen) + { + if (m_pen->GetWidth() == 0) + dc.SetPen(* g_oglTransparentPen); + else + dc.SetPen(* m_pen); + } + if (m_brush) + dc.SetBrush(* m_brush); + dc.DrawPolygon(n, intPoints, WXROUND(m_xpos), WXROUND(m_ypos)); + + delete[] intPoints; +} + +void wxPolygonShape::OnDrawOutline(wxDC &dc, double x, double y, double w, double h) +{ + dc.SetBrush(* wxTRANSPARENT_BRUSH); + // Multiply all points by proportion of new size to old size + double x_proportion = (double)(fabs(w / m_originalWidth)); + double y_proportion = (double)(fabs(h / m_originalHeight)); + + int n = m_originalPoints->GetCount(); + wxPoint *intPoints = new wxPoint[n]; + int i; + for (i = 0; i < n; i++) + { + wxRealPoint *point = (wxRealPoint *) m_originalPoints->Item(i)->GetData(); + intPoints[i].x = WXROUND(x_proportion * point->x); + intPoints[i].y = WXROUND(y_proportion * point->y); + } + dc.DrawPolygon(n, intPoints, WXROUND(x), WXROUND(y)); + delete[] intPoints; +} + +// Make as many control points as there are vertices. +void wxPolygonShape::MakeControlPoints() +{ + wxNode *node = m_points->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + wxPolygonControlPoint *control = new wxPolygonControlPoint(m_canvas, this, CONTROL_POINT_SIZE, + point, point->x, point->y); + m_canvas->AddShape(control); + m_controlPoints.Append(control); + node = node->GetNext(); + } +} + +void wxPolygonShape::ResetControlPoints() +{ + wxNode *node = m_points->GetFirst(); + wxNode *controlPointNode = m_controlPoints.GetFirst(); + while (node && controlPointNode) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + wxPolygonControlPoint *controlPoint = (wxPolygonControlPoint *)controlPointNode->GetData(); + + controlPoint->m_xoffset = point->x; + controlPoint->m_yoffset = point->y; + controlPoint->m_polygonVertex = point; + + node = node->GetNext(); + controlPointNode = controlPointNode->GetNext(); + } +} + + +#if wxUSE_PROLOGIO +void wxPolygonShape::WriteAttributes(wxExpr *clause) +{ + wxShape::WriteAttributes(clause); + + clause->AddAttributeValue(wxT("x"), m_xpos); + clause->AddAttributeValue(wxT("y"), m_ypos); + + // Make a list of lists for the coordinates + wxExpr *list = new wxExpr(wxExprList); + wxNode *node = m_points->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + wxExpr *point_list = new wxExpr(wxExprList); + wxExpr *x_expr = new wxExpr((double)point->x); + wxExpr *y_expr = new wxExpr((double)point->y); + + point_list->Append(x_expr); + point_list->Append(y_expr); + list->Append(point_list); + + node = node->GetNext(); + } + clause->AddAttributeValue(wxT("points"), list); + + // Save the original (unscaled) points + list = new wxExpr(wxExprList); + node = m_originalPoints->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + wxExpr *point_list = new wxExpr(wxExprList); + wxExpr *x_expr = new wxExpr((double) point->x); + wxExpr *y_expr = new wxExpr((double) point->y); + point_list->Append(x_expr); + point_list->Append(y_expr); + list->Append(point_list); + + node = node->GetNext(); + } + clause->AddAttributeValue(wxT("m_originalPoints"), list); +} + +void wxPolygonShape::ReadAttributes(wxExpr *clause) +{ + wxShape::ReadAttributes(clause); + + // Read a list of lists + m_points = new wxList; + m_originalPoints = new wxList; + + wxExpr *points_list = NULL; + clause->AssignAttributeValue(wxT("points"), &points_list); + + // If no points_list, don't crash!! Assume a diamond instead. + double the_height = 100.0; + double the_width = 100.0; + if (!points_list) + { + wxRealPoint *point = new wxRealPoint(0.0, (-the_height / 2)); + m_points->Append((wxObject *) point); + + point = new wxRealPoint((the_width / 2), 0.0); + m_points->Append((wxObject *) point); + + point = new wxRealPoint(0.0, (the_height / 2)); + m_points->Append((wxObject *) point); + + point = new wxRealPoint((-the_width / 2), 0.0); + m_points->Append((wxObject *) point); + + point = new wxRealPoint(0.0, (-the_height / 2)); + m_points->Append((wxObject *) point); + } + else + { + wxExpr *node = points_list->value.first; + + while (node) + { + wxExpr *xexpr = node->value.first; + long x = xexpr->IntegerValue(); + + wxExpr *yexpr = xexpr->next; + long y = yexpr->IntegerValue(); + + wxRealPoint *point = new wxRealPoint((double)x, (double)y); + m_points->Append((wxObject *) point); + + node = node->next; + } + } + + points_list = NULL; + clause->AssignAttributeValue(wxT("m_originalPoints"), &points_list); + + // If no points_list, don't crash!! Assume a diamond instead. + if (!points_list) + { + wxRealPoint *point = new wxRealPoint(0.0, (-the_height / 2)); + m_originalPoints->Append((wxObject *) point); + + point = new wxRealPoint((the_width / 2), 0.0); + m_originalPoints->Append((wxObject *) point); + + point = new wxRealPoint(0.0, (the_height / 2)); + m_originalPoints->Append((wxObject *) point); + + point = new wxRealPoint((-the_width / 2), 0.0); + m_originalPoints->Append((wxObject *) point); + + point = new wxRealPoint(0.0, (-the_height / 2)); + m_originalPoints->Append((wxObject *) point); + + m_originalWidth = the_width; + m_originalHeight = the_height; + } + else + { + wxExpr *node = points_list->value.first; + double min_x = 1000; + double min_y = 1000; + double max_x = -1000; + double max_y = -1000; + while (node) + { + wxExpr *xexpr = node->value.first; + long x = xexpr->IntegerValue(); + + wxExpr *yexpr = xexpr->next; + long y = yexpr->IntegerValue(); + + wxRealPoint *point = new wxRealPoint((double)x, (double)y); + m_originalPoints->Append((wxObject *) point); + + if (x < min_x) + min_x = (double)x; + if (y < min_y) + min_y = (double)y; + if (x > max_x) + max_x = (double)x; + if (y > max_y) + max_y = (double)y; + + node = node->next; + } + m_originalWidth = max_x - min_x; + m_originalHeight = max_y - min_y; + } + + CalculateBoundingBox(); +} +#endif + +void wxPolygonShape::Copy(wxShape ©) +{ + wxShape::Copy(copy); + + wxASSERT( copy.IsKindOf(CLASSINFO(wxPolygonShape)) ); + + wxPolygonShape &polyCopy = (wxPolygonShape &) copy; + + polyCopy.ClearPoints(); + + polyCopy.m_points = new wxList; + polyCopy.m_originalPoints = new wxList; + + wxNode *node = m_points->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + wxRealPoint *new_point = new wxRealPoint(point->x, point->y); + polyCopy.m_points->Append((wxObject *) new_point); + node = node->GetNext(); + } + node = m_originalPoints->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + wxRealPoint *new_point = new wxRealPoint(point->x, point->y); + polyCopy.m_originalPoints->Append((wxObject *) new_point); + node = node->GetNext(); + } + polyCopy.m_boundWidth = m_boundWidth; + polyCopy.m_boundHeight = m_boundHeight; + polyCopy.m_originalWidth = m_originalWidth; + polyCopy.m_originalHeight = m_originalHeight; +} + +int wxPolygonShape::GetNumberOfAttachments() const +{ + int maxN = (m_points ? (m_points->GetCount() - 1) : 0); + wxNode *node = m_attachmentPoints.GetFirst(); + while (node) + { + wxAttachmentPoint *point = (wxAttachmentPoint *)node->GetData(); + if (point->m_id > maxN) + maxN = point->m_id; + node = node->GetNext(); + } + return maxN + 1;; +} + +bool wxPolygonShape::GetAttachmentPosition(int attachment, double *x, double *y, + int nth, int no_arcs, wxLineShape *line) +{ + if ((m_attachmentMode == ATTACHMENT_MODE_EDGE) && m_points && attachment < (int) m_points->GetCount()) + { + wxRealPoint *point = (wxRealPoint *)m_points->Item(attachment)->GetData(); + *x = point->x + m_xpos; + *y = point->y + m_ypos; + return TRUE; + } + else + { + return wxShape::GetAttachmentPosition(attachment, x, y, nth, no_arcs, line); + } +} + +bool wxPolygonShape::AttachmentIsValid(int attachment) const +{ + if (!m_points) + return FALSE; + + if ((attachment >= 0) && (attachment < (int) m_points->GetCount())) + return TRUE; + + wxNode *node = m_attachmentPoints.GetFirst(); + while (node) + { + wxAttachmentPoint *point = (wxAttachmentPoint *)node->GetData(); + if (point->m_id == attachment) + return TRUE; + node = node->GetNext(); + } + return FALSE; +} + +// Rotate about the given axis by the given amount in radians +void wxPolygonShape::Rotate(double x, double y, double theta) +{ + double actualTheta = theta - m_rotation; + + // Rotate attachment points + double sinTheta = (double)sin(actualTheta); + double cosTheta = (double)cos(actualTheta); + wxNode *node = m_attachmentPoints.GetFirst(); + while (node) + { + wxAttachmentPoint *point = (wxAttachmentPoint *)node->GetData(); + double x1 = point->m_x; + double y1 = point->m_y; + point->m_x = x1 * cosTheta - y1 * sinTheta + x * (1.0 - cosTheta) + y * sinTheta; + point->m_y = x1 * sinTheta + y1 * cosTheta + y * (1.0 - cosTheta) + x * sinTheta; + node = node->GetNext(); + } + + node = m_points->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + double x1 = point->x; + double y1 = point->y; + point->x = x1 * cosTheta - y1 * sinTheta + x * (1.0 - cosTheta) + y * sinTheta; + point->y = x1 * sinTheta + y1 * cosTheta + y * (1.0 - cosTheta) + x * sinTheta; + node = node->GetNext(); + } + node = m_originalPoints->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + double x1 = point->x; + double y1 = point->y; + point->x = x1 * cosTheta - y1 * sinTheta + x * (1.0 - cosTheta) + y * sinTheta; + point->y = x1 * sinTheta + y1 * cosTheta + y * (1.0 - cosTheta) + x * sinTheta; + node = node->GetNext(); + } + + m_rotation = theta; + + CalculatePolygonCentre(); + CalculateBoundingBox(); + ResetControlPoints(); +} + +// Rectangle object + +IMPLEMENT_DYNAMIC_CLASS(wxRectangleShape, wxShape) + +wxRectangleShape::wxRectangleShape(double w, double h) +{ + m_width = w; + m_height = h; + m_cornerRadius = 0.0; + SetDefaultRegionSize(); +} + +void wxRectangleShape::OnDraw(wxDC &dc) +{ + double x1 = (double)(m_xpos - m_width / 2.0); + double y1 = (double)(m_ypos - m_height / 2.0); + + if (m_shadowMode != SHADOW_NONE) + { + if (m_shadowBrush) + dc.SetBrush(* m_shadowBrush); + dc.SetPen(* g_oglTransparentPen); + + if (m_cornerRadius != 0.0) + dc.DrawRoundedRectangle(WXROUND(x1 + m_shadowOffsetX), WXROUND(y1 + m_shadowOffsetY), + WXROUND(m_width), WXROUND(m_height), m_cornerRadius); + else + dc.DrawRectangle(WXROUND(x1 + m_shadowOffsetX), WXROUND(y1 + m_shadowOffsetY), WXROUND(m_width), WXROUND(m_height)); + } + + if (m_pen) + { + if (m_pen->GetWidth() == 0) + dc.SetPen(* g_oglTransparentPen); + else + dc.SetPen(* m_pen); + } + if (m_brush) + dc.SetBrush(* m_brush); + + if (m_cornerRadius != 0.0) + dc.DrawRoundedRectangle(WXROUND(x1), WXROUND(y1), WXROUND(m_width), WXROUND(m_height), m_cornerRadius); + else + dc.DrawRectangle(WXROUND(x1), WXROUND(y1), WXROUND(m_width), WXROUND(m_height)); +} + +void wxRectangleShape::GetBoundingBoxMin(double *the_width, double *the_height) +{ + *the_width = m_width; + *the_height = m_height; +} + +void wxRectangleShape::SetSize(double x, double y, bool WXUNUSED(recursive)) +{ + SetAttachmentSize(x, y); + m_width = (double)wxMax(x, 1.0); + m_height = (double)wxMax(y, 1.0); + SetDefaultRegionSize(); +} + +void wxRectangleShape::SetCornerRadius(double rad) +{ + m_cornerRadius = rad; +} + +// Assume (x1, y1) is centre of box (most generally, line end at box) +bool wxRectangleShape::GetPerimeterPoint(double WXUNUSED(x1), double WXUNUSED(y1), + double x2, double y2, + double *x3, double *y3) +{ + double bound_x, bound_y; + GetBoundingBoxMax(&bound_x, &bound_y); + oglFindEndForBox(bound_x, bound_y, m_xpos, m_ypos, x2, y2, x3, y3); + + return TRUE; +} + +#if wxUSE_PROLOGIO +void wxRectangleShape::WriteAttributes(wxExpr *clause) +{ + wxShape::WriteAttributes(clause); + clause->AddAttributeValue(wxT("x"), m_xpos); + clause->AddAttributeValue(wxT("y"), m_ypos); + + clause->AddAttributeValue(wxT("width"), m_width); + clause->AddAttributeValue(wxT("height"), m_height); + if (m_cornerRadius != 0.0) + clause->AddAttributeValue(wxT("corner"), m_cornerRadius); +} + +void wxRectangleShape::ReadAttributes(wxExpr *clause) +{ + wxShape::ReadAttributes(clause); + clause->AssignAttributeValue(wxT("width"), &m_width); + clause->AssignAttributeValue(wxT("height"), &m_height); + clause->AssignAttributeValue(wxT("corner"), &m_cornerRadius); + + // In case we're reading an old file, set the region's size + if (m_regions.GetCount() == 1) + { + wxShapeRegion *region = (wxShapeRegion *)m_regions.GetFirst()->GetData(); + region->SetSize(m_width, m_height); + } +} +#endif + +void wxRectangleShape::Copy(wxShape ©) +{ + wxShape::Copy(copy); + + wxASSERT( copy.IsKindOf(CLASSINFO(wxRectangleShape)) ); + + wxRectangleShape &rectCopy = (wxRectangleShape &) copy; + rectCopy.m_width = m_width; + rectCopy.m_height = m_height; + rectCopy.m_cornerRadius = m_cornerRadius; +} + +int wxRectangleShape::GetNumberOfAttachments() const +{ + return wxShape::GetNumberOfAttachments(); +} + + +// There are 4 attachment points on a rectangle - 0 = top, 1 = right, 2 = bottom, +// 3 = left. +bool wxRectangleShape::GetAttachmentPosition(int attachment, double *x, double *y, + int nth, int no_arcs, wxLineShape *line) +{ + return wxShape::GetAttachmentPosition(attachment, x, y, nth, no_arcs, line); +} + +// Text object (no box) + +IMPLEMENT_DYNAMIC_CLASS(wxTextShape, wxRectangleShape) + +wxTextShape::wxTextShape(double width, double height): + wxRectangleShape(width, height) +{ +} + +void wxTextShape::OnDraw(wxDC &WXUNUSED(dc)) +{ +} + +void wxTextShape::Copy(wxShape ©) +{ + wxRectangleShape::Copy(copy); +} + +#if wxUSE_PROLOGIO +void wxTextShape::WriteAttributes(wxExpr *clause) +{ + wxRectangleShape::WriteAttributes(clause); +} +#endif + +// Ellipse object + +IMPLEMENT_DYNAMIC_CLASS(wxEllipseShape, wxShape) + +wxEllipseShape::wxEllipseShape(double w, double h) +{ + m_width = w; + m_height = h; + SetDefaultRegionSize(); +} + +void wxEllipseShape::GetBoundingBoxMin(double *w, double *h) +{ + *w = m_width; + *h = m_height; +} + +bool wxEllipseShape::GetPerimeterPoint(double x1, double y1, + double x2, double y2, + double *x3, double *y3) +{ + double bound_x, bound_y; + GetBoundingBoxMax(&bound_x, &bound_y); + +// oglFindEndForBox(bound_x, bound_y, m_xpos, m_ypos, x2, y2, x3, y3); + oglDrawArcToEllipse(m_xpos, m_ypos, bound_x, bound_y, x2, y2, x1, y1, x3, y3); + + return TRUE; +} + +void wxEllipseShape::OnDraw(wxDC &dc) +{ + if (m_shadowMode != SHADOW_NONE) + { + if (m_shadowBrush) + dc.SetBrush(* m_shadowBrush); + dc.SetPen(* g_oglTransparentPen); + dc.DrawEllipse((long) ((m_xpos - GetWidth() / 2) + m_shadowOffsetX), + (long) ((m_ypos - GetHeight() / 2) + m_shadowOffsetY), + (long) GetWidth(), (long) GetHeight()); + } + + if (m_pen) + { + if (m_pen->GetWidth() == 0) + dc.SetPen(* g_oglTransparentPen); + else + dc.SetPen(* m_pen); + } + if (m_brush) + dc.SetBrush(* m_brush); + dc.DrawEllipse((long) (m_xpos - GetWidth() / 2), (long) (m_ypos - GetHeight() / 2), (long) GetWidth(), (long) GetHeight()); +} + +void wxEllipseShape::SetSize(double x, double y, bool WXUNUSED(recursive)) +{ + SetAttachmentSize(x, y); + m_width = x; + m_height = y; + SetDefaultRegionSize(); +} + +#if wxUSE_PROLOGIO +void wxEllipseShape::WriteAttributes(wxExpr *clause) +{ + wxShape::WriteAttributes(clause); + clause->AddAttributeValue(wxT("x"), m_xpos); + clause->AddAttributeValue(wxT("y"), m_ypos); + + clause->AddAttributeValue(wxT("width"), m_width); + clause->AddAttributeValue(wxT("height"), m_height); +} + +void wxEllipseShape::ReadAttributes(wxExpr *clause) +{ + wxShape::ReadAttributes(clause); + clause->AssignAttributeValue(wxT("width"), &m_width); + clause->AssignAttributeValue(wxT("height"), &m_height); + + // In case we're reading an old file, set the region's size + if (m_regions.GetCount() == 1) + { + wxShapeRegion *region = (wxShapeRegion *)m_regions.GetFirst()->GetData(); + region->SetSize(m_width, m_height); + } +} +#endif + +void wxEllipseShape::Copy(wxShape ©) +{ + wxShape::Copy(copy); + + wxASSERT( copy.IsKindOf(CLASSINFO(wxEllipseShape)) ); + + wxEllipseShape &ellipseCopy = (wxEllipseShape &) copy; + + ellipseCopy.m_width = m_width; + ellipseCopy.m_height = m_height; +} + +int wxEllipseShape::GetNumberOfAttachments() const +{ + return wxShape::GetNumberOfAttachments(); +} + +// There are 4 attachment points on an ellipse - 0 = top, 1 = right, 2 = bottom, +// 3 = left. +bool wxEllipseShape::GetAttachmentPosition(int attachment, double *x, double *y, + int nth, int no_arcs, wxLineShape *line) +{ + if (m_attachmentMode == ATTACHMENT_MODE_BRANCHING) + return wxShape::GetAttachmentPosition(attachment, x, y, nth, no_arcs, line); + + if (m_attachmentMode != ATTACHMENT_MODE_NONE) + { + double top = (double)(m_ypos + m_height / 2.0); + double bottom = (double)(m_ypos - m_height / 2.0); + double left = (double)(m_xpos - m_width / 2.0); + double right = (double)(m_xpos + m_width / 2.0); + + int physicalAttachment = LogicalToPhysicalAttachment(attachment); + + switch (physicalAttachment) + { + case 0: + { + if (m_spaceAttachments) + *x = left + (nth + 1) * m_width / (no_arcs + 1); + else *x = m_xpos; + *y = top; + // We now have the point on the bounding box: but get the point on the ellipse + // by imagining a vertical line from (*x, m_ypos - m_height- 500) to (*x, m_ypos) intersecting + // the ellipse. + oglDrawArcToEllipse(m_xpos, m_ypos, m_width, m_height, *x, (double)(m_ypos - m_height - 500), *x, m_ypos, x, y); + break; + } + case 1: + { + *x = right; + if (m_spaceAttachments) + *y = bottom + (nth + 1) * m_height / (no_arcs + 1); + else *y = m_ypos; + oglDrawArcToEllipse(m_xpos, m_ypos, m_width, m_height, (double)(m_xpos + m_width + 500), *y, m_xpos, *y, x, y); + break; + } + case 2: + { + if (m_spaceAttachments) + *x = left + (nth + 1) * m_width / (no_arcs + 1); + else *x = m_xpos; + *y = bottom; + oglDrawArcToEllipse(m_xpos, m_ypos, m_width, m_height, *x, (double)(m_ypos + m_height + 500), *x, m_ypos, x, y); + break; + } + case 3: + { + *x = left; + if (m_spaceAttachments) + *y = bottom + (nth + 1) * m_height / (no_arcs + 1); + else *y = m_ypos; + oglDrawArcToEllipse(m_xpos, m_ypos, m_width, m_height, (double)(m_xpos - m_width - 500), *y, m_xpos, *y, x, y); + break; + } + default: + { + return wxShape::GetAttachmentPosition(attachment, x, y, nth, no_arcs, line); + } + } + return TRUE; + } + else + { + *x = m_xpos; + *y = m_ypos; + return TRUE; + } +} + + +// Circle object +IMPLEMENT_DYNAMIC_CLASS(wxCircleShape, wxEllipseShape) + +wxCircleShape::wxCircleShape(double diameter): wxEllipseShape(diameter, diameter) +{ + SetMaintainAspectRatio(TRUE); +} + +void wxCircleShape::Copy(wxShape ©) +{ + wxEllipseShape::Copy(copy); +} + +bool wxCircleShape::GetPerimeterPoint(double WXUNUSED(x1), double WXUNUSED(y1), + double x2, double y2, + double *x3, double *y3) +{ + oglFindEndForCircle(m_width / 2, + m_xpos, m_ypos, // Centre of circle + x2, y2, // Other end of line + x3, y3); + + return TRUE; +} + +// Control points + +double wxControlPoint::sm_controlPointDragStartX = 0.0; +double wxControlPoint::sm_controlPointDragStartY = 0.0; +double wxControlPoint::sm_controlPointDragStartWidth = 0.0; +double wxControlPoint::sm_controlPointDragStartHeight = 0.0; +double wxControlPoint::sm_controlPointDragEndWidth = 0.0; +double wxControlPoint::sm_controlPointDragEndHeight = 0.0; +double wxControlPoint::sm_controlPointDragPosX = 0.0; +double wxControlPoint::sm_controlPointDragPosY = 0.0; + +IMPLEMENT_DYNAMIC_CLASS(wxControlPoint, wxRectangleShape) + +wxControlPoint::wxControlPoint(wxShapeCanvas *theCanvas, wxShape *object, double size, double the_xoffset, double the_yoffset, int the_type): wxRectangleShape(size, size) +{ + m_canvas = theCanvas; + m_shape = object; + m_xoffset = the_xoffset; + m_yoffset = the_yoffset; + m_type = the_type; + SetPen(g_oglBlackForegroundPen); + SetBrush((wxBrush *) wxBLACK_BRUSH); + m_oldCursor = NULL; + m_visible = TRUE; + m_eraseObject = TRUE; +} + +wxControlPoint::~wxControlPoint() +{ +} + +// Don't even attempt to draw any text - waste of time! +void wxControlPoint::OnDrawContents(wxDC &WXUNUSED(dc)) +{ +} + +void wxControlPoint::OnDraw(wxDC &dc) +{ + m_xpos = m_shape->GetX() + m_xoffset; + m_ypos = m_shape->GetY() + m_yoffset; + wxRectangleShape::OnDraw(dc); +} + +// Implement resizing of canvas object +void wxControlPoint::OnDragLeft(bool draw, double x, double y, int keys, int attachment) +{ + m_shape->GetEventHandler()->OnSizingDragLeft(this, draw, x, y, keys, attachment); +} + +void wxControlPoint::OnBeginDragLeft(double x, double y, int keys, int attachment) +{ + m_shape->GetEventHandler()->OnSizingBeginDragLeft(this, x, y, keys, attachment); +} + +void wxControlPoint::OnEndDragLeft(double x, double y, int keys, int attachment) +{ + m_shape->GetEventHandler()->OnSizingEndDragLeft(this, x, y, keys, attachment); +} + +int wxControlPoint::GetNumberOfAttachments() const +{ + return 1; +} + +bool wxControlPoint::GetAttachmentPosition(int WXUNUSED(attachment), double *x, double *y, + int WXUNUSED(nth), int WXUNUSED(no_arcs), wxLineShape *WXUNUSED(line)) +{ + *x = m_xpos; + *y = m_ypos; + return TRUE; +} + +// Control points ('handles') redirect control to the actual shape, to make it easier +// to override sizing behaviour. +void wxShape::OnSizingDragLeft(wxControlPoint *pt, bool WXUNUSED(draw), double x, double y, int keys, int WXUNUSED(attachment)) +{ + double bound_x; + double bound_y; + this->GetBoundingBoxMin(&bound_x, &bound_y); + + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + dc.SetLogicalFunction(OGLRBLF); + + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + dc.SetPen(dottedPen); + dc.SetBrush((* wxTRANSPARENT_BRUSH)); + + if (this->GetCentreResize()) + { + // Maintain the same centre point. + double new_width = (double)(2.0 * fabs(x - this->GetX())); + double new_height = (double)(2.0 * fabs(y - this->GetY())); + + // Constrain sizing according to what control point you're dragging + if (pt->m_type == CONTROL_POINT_HORIZONTAL) + { + if (GetMaintainAspectRatio()) + { + new_height = bound_y * (new_width / bound_x); + } + else + new_height = bound_y; + } + else if (pt->m_type == CONTROL_POINT_VERTICAL) + { + if (GetMaintainAspectRatio()) + { + new_width = bound_x * (new_height / bound_y); + } + else + new_width = bound_x; + } + else if (pt->m_type == CONTROL_POINT_DIAGONAL && (keys & KEY_SHIFT)) + new_height = bound_y * (new_width / bound_x); + + if (this->GetFixedWidth()) + new_width = bound_x; + + if (this->GetFixedHeight()) + new_height = bound_y; + + pt->sm_controlPointDragEndWidth = new_width; + pt->sm_controlPointDragEndHeight = new_height; + + this->GetEventHandler()->OnDrawOutline(dc, this->GetX(), this->GetY(), + new_width, new_height); + } + else + { + // Don't maintain the same centre point! + double newX1 = wxMin(pt->sm_controlPointDragStartX, x); + double newY1 = wxMin(pt->sm_controlPointDragStartY, y); + double newX2 = wxMax(pt->sm_controlPointDragStartX, x); + double newY2 = wxMax(pt->sm_controlPointDragStartY, y); + if (pt->m_type == CONTROL_POINT_HORIZONTAL) + { + newY1 = pt->sm_controlPointDragStartY; + newY2 = newY1 + pt->sm_controlPointDragStartHeight; + } + else if (pt->m_type == CONTROL_POINT_VERTICAL) + { + newX1 = pt->sm_controlPointDragStartX; + newX2 = newX1 + pt->sm_controlPointDragStartWidth; + } + else if (pt->m_type == CONTROL_POINT_DIAGONAL && ((keys & KEY_SHIFT) || GetMaintainAspectRatio())) + { + double newH = (double)((newX2 - newX1) * (pt->sm_controlPointDragStartHeight / pt->sm_controlPointDragStartWidth)); + if (GetY() > pt->sm_controlPointDragStartY) + newY2 = (double)(newY1 + newH); + else + newY1 = (double)(newY2 - newH); + } + double newWidth = (double)(newX2 - newX1); + double newHeight = (double)(newY2 - newY1); + + if (pt->m_type == CONTROL_POINT_VERTICAL && GetMaintainAspectRatio()) + { + newWidth = bound_x * (newHeight / bound_y) ; + } + + if (pt->m_type == CONTROL_POINT_HORIZONTAL && GetMaintainAspectRatio()) + { + newHeight = bound_y * (newWidth / bound_x) ; + } + + pt->sm_controlPointDragPosX = (double)(newX1 + (newWidth / 2.0)); + pt->sm_controlPointDragPosY = (double)(newY1 + (newHeight / 2.0)); + if (this->GetFixedWidth()) + newWidth = bound_x; + + if (this->GetFixedHeight()) + newHeight = bound_y; + + pt->sm_controlPointDragEndWidth = newWidth; + pt->sm_controlPointDragEndHeight = newHeight; + this->GetEventHandler()->OnDrawOutline(dc, pt->sm_controlPointDragPosX, pt->sm_controlPointDragPosY, newWidth, newHeight); + } +} + +void wxShape::OnSizingBeginDragLeft(wxControlPoint *pt, double x, double y, int keys, int WXUNUSED(attachment)) +{ + m_canvas->CaptureMouse(); + + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + /* + if (pt->m_eraseObject) + this->Erase(dc); + */ + + dc.SetLogicalFunction(OGLRBLF); + + double bound_x; + double bound_y; + this->GetBoundingBoxMin(&bound_x, &bound_y); + + // Choose the 'opposite corner' of the object as the stationary + // point in case this is non-centring resizing. + if (pt->GetX() < this->GetX()) + pt->sm_controlPointDragStartX = (double)(this->GetX() + (bound_x / 2.0)); + else + pt->sm_controlPointDragStartX = (double)(this->GetX() - (bound_x / 2.0)); + + if (pt->GetY() < this->GetY()) + pt->sm_controlPointDragStartY = (double)(this->GetY() + (bound_y / 2.0)); + else + pt->sm_controlPointDragStartY = (double)(this->GetY() - (bound_y / 2.0)); + + if (pt->m_type == CONTROL_POINT_HORIZONTAL) + pt->sm_controlPointDragStartY = (double)(this->GetY() - (bound_y / 2.0)); + else if (pt->m_type == CONTROL_POINT_VERTICAL) + pt->sm_controlPointDragStartX = (double)(this->GetX() - (bound_x / 2.0)); + + // We may require the old width and height. + pt->sm_controlPointDragStartWidth = bound_x; + pt->sm_controlPointDragStartHeight = bound_y; + + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + dc.SetPen(dottedPen); + dc.SetBrush((* wxTRANSPARENT_BRUSH)); + + if (this->GetCentreResize()) + { + double new_width = (double)(2.0 * fabs(x - this->GetX())); + double new_height = (double)(2.0 * fabs(y - this->GetY())); + + // Constrain sizing according to what control point you're dragging + if (pt->m_type == CONTROL_POINT_HORIZONTAL) + { + if (GetMaintainAspectRatio()) + { + new_height = bound_y * (new_width / bound_x); + } + else + new_height = bound_y; + } + else if (pt->m_type == CONTROL_POINT_VERTICAL) + { + if (GetMaintainAspectRatio()) + { + new_width = bound_x * (new_height / bound_y); + } + else + new_width = bound_x; + } + else if (pt->m_type == CONTROL_POINT_DIAGONAL && (keys & KEY_SHIFT)) + new_height = bound_y * (new_width / bound_x); + + if (this->GetFixedWidth()) + new_width = bound_x; + + if (this->GetFixedHeight()) + new_height = bound_y; + + pt->sm_controlPointDragEndWidth = new_width; + pt->sm_controlPointDragEndHeight = new_height; + this->GetEventHandler()->OnDrawOutline(dc, this->GetX(), this->GetY(), + new_width, new_height); + } + else + { + // Don't maintain the same centre point! + double newX1 = wxMin(pt->sm_controlPointDragStartX, x); + double newY1 = wxMin(pt->sm_controlPointDragStartY, y); + double newX2 = wxMax(pt->sm_controlPointDragStartX, x); + double newY2 = wxMax(pt->sm_controlPointDragStartY, y); + if (pt->m_type == CONTROL_POINT_HORIZONTAL) + { + newY1 = pt->sm_controlPointDragStartY; + newY2 = newY1 + pt->sm_controlPointDragStartHeight; + } + else if (pt->m_type == CONTROL_POINT_VERTICAL) + { + newX1 = pt->sm_controlPointDragStartX; + newX2 = newX1 + pt->sm_controlPointDragStartWidth; + } + else if (pt->m_type == CONTROL_POINT_DIAGONAL && ((keys & KEY_SHIFT) || GetMaintainAspectRatio())) + { + double newH = (double)((newX2 - newX1) * (pt->sm_controlPointDragStartHeight / pt->sm_controlPointDragStartWidth)); + if (pt->GetY() > pt->sm_controlPointDragStartY) + newY2 = (double)(newY1 + newH); + else + newY1 = (double)(newY2 - newH); + } + double newWidth = (double)(newX2 - newX1); + double newHeight = (double)(newY2 - newY1); + + if (pt->m_type == CONTROL_POINT_VERTICAL && GetMaintainAspectRatio()) + { + newWidth = bound_x * (newHeight / bound_y) ; + } + + if (pt->m_type == CONTROL_POINT_HORIZONTAL && GetMaintainAspectRatio()) + { + newHeight = bound_y * (newWidth / bound_x) ; + } + + pt->sm_controlPointDragPosX = (double)(newX1 + (newWidth / 2.0)); + pt->sm_controlPointDragPosY = (double)(newY1 + (newHeight / 2.0)); + if (this->GetFixedWidth()) + newWidth = bound_x; + + if (this->GetFixedHeight()) + newHeight = bound_y; + + pt->sm_controlPointDragEndWidth = newWidth; + pt->sm_controlPointDragEndHeight = newHeight; + this->GetEventHandler()->OnDrawOutline(dc, pt->sm_controlPointDragPosX, pt->sm_controlPointDragPosY, newWidth, newHeight); + } +} + +void wxShape::OnSizingEndDragLeft(wxControlPoint *pt, double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys), int WXUNUSED(attachment)) +{ + m_canvas->ReleaseMouse(); + this->Recompute(); + this->ResetControlPoints(); + + this->Erase(); + /* + if (!pt->m_eraseObject) + this->Show(FALSE); + */ + + this->SetSize(pt->sm_controlPointDragEndWidth, pt->sm_controlPointDragEndHeight); + + // The next operation could destroy this control point (it does for label objects, + // via formatting the text), so save all values we're going to use, or + // we'll be accessing garbage. + wxShape *theObject = this; + wxShapeCanvas *theCanvas = m_canvas; + bool eraseIt = pt->m_eraseObject; + + if (theObject->GetCentreResize()) + theObject->Move(theObject->GetX(), theObject->GetY()); + else + theObject->Move(pt->sm_controlPointDragPosX, pt->sm_controlPointDragPosY); + + /* + if (!eraseIt) + theObject->Show(TRUE); + */ + + double width, height; + theObject->GetBoundingBoxMax(&width, &height); + theObject->GetEventHandler()->OnEndSize(width, height); + + theCanvas->Refresh(); +} + + + +// Polygon control points + +IMPLEMENT_DYNAMIC_CLASS(wxPolygonControlPoint, wxControlPoint) + +wxPolygonControlPoint::wxPolygonControlPoint(wxShapeCanvas *theCanvas, wxShape *object, double size, + wxRealPoint *vertex, double the_xoffset, double the_yoffset): + wxControlPoint(theCanvas, object, size, the_xoffset, the_yoffset, 0) +{ + m_polygonVertex = vertex; + m_originalDistance = 0.0; +} + +wxPolygonControlPoint::~wxPolygonControlPoint() +{ +} + +// Calculate what new size would be, at end of resize +void wxPolygonControlPoint::CalculateNewSize(double x, double y) +{ + double bound_x; + double bound_y; + GetShape()->GetBoundingBoxMin(&bound_x, &bound_y); + + double dist = (double)sqrt((x - m_shape->GetX()) * (x - m_shape->GetX()) + + (y - m_shape->GetY()) * (y - m_shape->GetY())); + + m_newSize.x = (double)(dist / this->m_originalDistance) * this->m_originalSize.x; + m_newSize.y = (double)(dist / this->m_originalDistance) * this->m_originalSize.y; +} + + +// Implement resizing polygon or moving the vertex. +void wxPolygonControlPoint::OnDragLeft(bool draw, double x, double y, int keys, int attachment) +{ + m_shape->GetEventHandler()->OnSizingDragLeft(this, draw, x, y, keys, attachment); +} + +void wxPolygonControlPoint::OnBeginDragLeft(double x, double y, int keys, int attachment) +{ + m_shape->GetEventHandler()->OnSizingBeginDragLeft(this, x, y, keys, attachment); +} + +void wxPolygonControlPoint::OnEndDragLeft(double x, double y, int keys, int attachment) +{ + m_shape->GetEventHandler()->OnSizingEndDragLeft(this, x, y, keys, attachment); +} + +// Control points ('handles') redirect control to the actual shape, to make it easier +// to override sizing behaviour. +void wxPolygonShape::OnSizingDragLeft(wxControlPoint *pt, bool WXUNUSED(draw), double x, double y, int WXUNUSED(keys), int WXUNUSED(attachment)) +{ + wxPolygonControlPoint *ppt = (wxPolygonControlPoint *) pt; + + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + dc.SetLogicalFunction(OGLRBLF); + + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + dc.SetPen(dottedPen); + dc.SetBrush((* wxTRANSPARENT_BRUSH)); + +#if 0 // keys & KEY_CTRL) + { + // TODO: mend this code. Currently we rely on altering the + // actual points, but we should assume we're not, as per + // the normal sizing case. + m_canvas->Snap(&x, &y); + + // Move point + ppt->m_polygonVertex->x = x - this->GetX(); + ppt->m_polygonVertex->y = y - this->GetY(); + ppt->SetX(x); + ppt->SetY(y); + ((wxPolygonShape *)this)->CalculateBoundingBox(); + ((wxPolygonShape *)this)->CalculatePolygonCentre(); + } +#else + { + ppt->CalculateNewSize(x, y); + } +#endif + + this->GetEventHandler()->OnDrawOutline(dc, this->GetX(), this->GetY(), + ppt->GetNewSize().x, ppt->GetNewSize().y); +} + +void wxPolygonShape::OnSizingBeginDragLeft(wxControlPoint *pt, double x, double y, int WXUNUSED(keys), int WXUNUSED(attachment)) +{ + wxPolygonControlPoint *ppt = (wxPolygonControlPoint *) pt; + + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + this->Erase(); + + dc.SetLogicalFunction(OGLRBLF); + + double bound_x; + double bound_y; + this->GetBoundingBoxMin(&bound_x, &bound_y); + + double dist = (double)sqrt((x - this->GetX()) * (x - this->GetX()) + + (y - this->GetY()) * (y - this->GetY())); + ppt->m_originalDistance = dist; + ppt->m_originalSize.x = bound_x; + ppt->m_originalSize.y = bound_y; + + if (ppt->m_originalDistance == 0.0) ppt->m_originalDistance = (double) 0.0001; + + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + dc.SetPen(dottedPen); + dc.SetBrush((* wxTRANSPARENT_BRUSH)); + +#if 0 // keys & KEY_CTRL) + { + // TODO: mend this code. Currently we rely on altering the + // actual points, but we should assume we're not, as per + // the normal sizing case. + m_canvas->Snap(&x, &y); + + // Move point + ppt->m_polygonVertex->x = x - this->GetX(); + ppt->m_polygonVertex->y = y - this->GetY(); + ppt->SetX(x); + ppt->SetY(y); + ((wxPolygonShape *)this)->CalculateBoundingBox(); + ((wxPolygonShape *)this)->CalculatePolygonCentre(); + } +#else + { + ppt->CalculateNewSize(x, y); + } +#endif + + this->GetEventHandler()->OnDrawOutline(dc, this->GetX(), this->GetY(), + ppt->GetNewSize().x, ppt->GetNewSize().y); + + m_canvas->CaptureMouse(); +} + +void wxPolygonShape::OnSizingEndDragLeft(wxControlPoint *pt, double WXUNUSED(x), double WXUNUSED(y), int keys, int WXUNUSED(attachment)) +{ + wxPolygonControlPoint *ppt = (wxPolygonControlPoint *) pt; + + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + m_canvas->ReleaseMouse(); + dc.SetLogicalFunction(wxCOPY); + + // If we're changing shape, must reset the original points + if (keys & KEY_CTRL) + { + ((wxPolygonShape *)this)->CalculateBoundingBox(); + ((wxPolygonShape *)this)->UpdateOriginalPoints(); + } + else + { + SetSize(ppt->GetNewSize().x, ppt->GetNewSize().y); + } + + ((wxPolygonShape *)this)->CalculateBoundingBox(); + ((wxPolygonShape *)this)->CalculatePolygonCentre(); + + this->Recompute(); + this->ResetControlPoints(); + this->Move(this->GetX(), this->GetY()); + m_canvas->Refresh(); +} + +/* + * Object region + * + */ +IMPLEMENT_DYNAMIC_CLASS(wxShapeRegion, wxObject) + +wxShapeRegion::wxShapeRegion() +{ + m_regionText = wxEmptyString; + m_font = g_oglNormalFont; + m_minHeight = 5.0; + m_minWidth = 5.0; + m_width = 0.0; + m_height = 0.0; + m_x = 0.0; + m_y = 0.0; + + m_regionProportionX = -1.0; + m_regionProportionY = -1.0; + m_formatMode = FORMAT_CENTRE_HORIZ | FORMAT_CENTRE_VERT; + m_regionName = wxEmptyString; + m_textColour = wxT("BLACK"); + m_penColour = wxT("BLACK"); + m_penStyle = wxSOLID; + m_actualPenObject = NULL; +} + +wxShapeRegion::wxShapeRegion(wxShapeRegion ®ion) +{ + m_regionText = region.m_regionText; + m_regionName = region.m_regionName; + m_textColour = region.m_textColour; + + m_font = region.m_font; + m_minHeight = region.m_minHeight; + m_minWidth = region.m_minWidth; + m_width = region.m_width; + m_height = region.m_height; + m_x = region.m_x; + m_y = region.m_y; + + m_regionProportionX = region.m_regionProportionX; + m_regionProportionY = region.m_regionProportionY; + m_formatMode = region.m_formatMode; + m_actualColourObject = region.GetActualColourObject(); + m_actualPenObject = NULL; + m_penStyle = region.m_penStyle; + m_penColour = region.m_penColour; + + ClearText(); + wxNode *node = region.m_formattedText.GetFirst(); + while (node) + { + wxShapeTextLine *line = (wxShapeTextLine *)node->GetData(); + wxShapeTextLine *new_line = + new wxShapeTextLine(line->GetX(), line->GetY(), line->GetText()); + m_formattedText.Append(new_line); + node = node->GetNext(); + } +} + +wxShapeRegion::~wxShapeRegion() +{ + ClearText(); +} + +void wxShapeRegion::ClearText() +{ + wxNode *node = m_formattedText.GetFirst(); + while (node) + { + wxShapeTextLine *line = (wxShapeTextLine *)node->GetData(); + wxNode *next = node->GetNext(); + delete line; + delete node; + node = next; + } +} + +void wxShapeRegion::SetFont(wxFont *f) +{ + m_font = f; +} + +void wxShapeRegion::SetMinSize(double w, double h) +{ + m_minWidth = w; + m_minHeight = h; +} + +void wxShapeRegion::SetSize(double w, double h) +{ + m_width = w; + m_height = h; +} + +void wxShapeRegion::SetPosition(double xp, double yp) +{ + m_x = xp; + m_y = yp; +} + +void wxShapeRegion::SetProportions(double xp, double yp) +{ + m_regionProportionX = xp; + m_regionProportionY = yp; +} + +void wxShapeRegion::SetFormatMode(int mode) +{ + m_formatMode = mode; +} + +void wxShapeRegion::SetColour(const wxString &col) +{ + m_textColour = col; + m_actualColourObject = wxColour(); +} + +void wxShapeRegion::SetColour(const wxColour &col) +{ + m_actualColourObject = col; +} + +const wxColour &wxShapeRegion::GetActualColourObject() +{ + if (!m_actualColourObject.IsOk()) + m_actualColourObject = wxTheColourDatabase->Find(GetColour()); + if (!m_actualColourObject.IsOk()) + m_actualColourObject = * wxBLACK; + return m_actualColourObject; +} + +void wxShapeRegion::SetPenColour(const wxString &col) +{ + m_penColour = col; + m_actualPenObject = NULL; +} + +// Returns NULL if the pen is invisible +// (different to pen being transparent; indicates that +// region boundary should not be drawn.) +wxPen *wxShapeRegion::GetActualPen() +{ + if (m_actualPenObject) + return m_actualPenObject; + + if (!m_penColour) return NULL; + if (m_penColour == wxT("Invisible")) + return NULL; + m_actualPenObject = wxThePenList->FindOrCreatePen(m_penColour, 1, m_penStyle); + return m_actualPenObject; +} + + diff --git a/ogl/bmpshape.cpp b/ogl/bmpshape.cpp new file mode 100644 index 0000000..e005044 --- /dev/null +++ b/ogl/bmpshape.cpp @@ -0,0 +1,95 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// bmpshape.cpp - Bitmap shape class +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include "ogl/ogl.h" + +/* + * Bitmap object + * + */ + +IMPLEMENT_DYNAMIC_CLASS(wxBitmapShape, wxRectangleShape) + +wxBitmapShape::wxBitmapShape(): wxRectangleShape(100.0, 50.0) +{ + m_filename = wxEmptyString; +} + +wxBitmapShape::~wxBitmapShape() +{ +} + +void wxBitmapShape::OnDraw(wxDC &dc) +{ + if (!m_bitmap.Ok()) + return; + + double x, y; + x = WXROUND(m_xpos - m_bitmap.GetWidth() / 2.0); + y = WXROUND(m_ypos - m_bitmap.GetHeight() / 2.0); + dc.DrawBitmap(m_bitmap, (int) x, (int) y, true); +} + +void wxBitmapShape::SetSize(double w, double h, bool WXUNUSED(recursive)) +{ + if (m_bitmap.Ok()) + { + w = m_bitmap.GetWidth(); + h = m_bitmap.GetHeight(); + } + + SetAttachmentSize(w, h); + + m_width = w; + m_height = h; + SetDefaultRegionSize(); +} + +#if wxUSE_PROLOGIO +void wxBitmapShape::WriteAttributes(wxExpr *clause) +{ + // Can't really save the bitmap; so instantiate the bitmap + // at a higher level in the application, from a symbol library. + wxRectangleShape::WriteAttributes(clause); + clause->AddAttributeValueString(wxT("filename"), m_filename); +} + +void wxBitmapShape::ReadAttributes(wxExpr *clause) +{ + wxRectangleShape::ReadAttributes(clause); + clause->GetAttributeValue(wxT("filename"), m_filename); +} +#endif + +// Does the copying for this object +void wxBitmapShape::Copy(wxShape ©) +{ + wxRectangleShape::Copy(copy); + + wxASSERT( copy.IsKindOf(CLASSINFO(wxBitmapShape)) ) ; + + wxBitmapShape &bitmapCopy = (wxBitmapShape &) copy; + + bitmapCopy.m_bitmap = m_bitmap; + bitmapCopy.SetFilename(m_filename); +} + +void wxBitmapShape::SetBitmap(const wxBitmap &bm) +{ + m_bitmap = bm; + if (m_bitmap.Ok()) + SetSize(m_bitmap.GetWidth(), m_bitmap.GetHeight()); +} + + diff --git a/ogl/canvas.cpp b/ogl/canvas.cpp new file mode 100644 index 0000000..0ca8f59 --- /dev/null +++ b/ogl/canvas.cpp @@ -0,0 +1,574 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// canvas.cpp - Shape canvas class +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include +#include +#include + +#include "wx/dcbuffer.h" +#include "ogl/ogl.h" + +#define CONTROL_POINT_SIZE 6 + +// Control point types +// Rectangle and most other shapes +#define CONTROL_POINT_VERTICAL 1 +#define CONTROL_POINT_HORIZONTAL 2 +#define CONTROL_POINT_DIAGONAL 3 + +// Line +#define CONTROL_POINT_ENDPOINT_TO 4 +#define CONTROL_POINT_ENDPOINT_FROM 5 +#define CONTROL_POINT_LINE 6 + +IMPLEMENT_DYNAMIC_CLASS(wxShapeCanvas, wxScrolledWindow) + +BEGIN_EVENT_TABLE(wxShapeCanvas, wxScrolledWindow) + EVT_PAINT(wxShapeCanvas::OnPaint) + EVT_ERASE_BACKGROUND(wxShapeCanvas::OnEraseBackground) + EVT_MOUSE_EVENTS(wxShapeCanvas::OnMouseEvent) +END_EVENT_TABLE() + +const wxChar *wxShapeCanvasNameStr = wxT("shapeCanvas"); + +// Object canvas +wxShapeCanvas::wxShapeCanvas(wxWindow *parent, wxWindowID id, + const wxPoint &pos, + const wxSize &size, + long style, + const wxString &name): + wxScrolledWindow(parent, id, pos, size, style | wxVSCROLL | wxHSCROLL, name) +{ + m_shapeDiagram = NULL; + m_dragState = NoDragging; + m_draggedShape = NULL; + m_oldDragX = 0; + m_oldDragY = 0; + m_firstDragX = 0; + m_firstDragY = 0; + m_checkTolerance = TRUE; + +#if OGL_USE_BUFFERED_PAINT + RecreateBuffer(size); +#endif + +} + +wxShapeCanvas::~wxShapeCanvas() +{ + if(m_shapeDiagram) + delete m_shapeDiagram; +} + +#if OGL_USE_BUFFERED_PAINT +/// Recreate buffer bitmap if necessary +bool wxShapeCanvas::RecreateBuffer(const wxSize &size) +{ + wxSize sz = size; + if (sz == wxDefaultSize) + sz = GetClientSize(); + + if (sz.x < 1 || sz.y < 1) + return false; + + if (!m_bufferBitmap.Ok() || m_bufferBitmap.GetWidth() < sz.x || m_bufferBitmap.GetHeight() < sz.y) + m_bufferBitmap = wxBitmap(sz.x, sz.y); + return m_bufferBitmap.Ok(); +} +#endif + +void wxShapeCanvas::OnPaint(wxPaintEvent &WXUNUSED(event)) +{ +#if OGL_USE_BUFFERED_PAINT + RecreateBuffer(); + wxBufferedPaintDC dc(this, m_bufferBitmap); +#else + wxPaintDC dc(this); +#endif + + PrepareDC(dc); + + DrawBackground(dc, true); + + if (GetDiagram()) + GetDiagram()->Redraw(dc); + + // Necessary or it unscales again if there's a zoom level + dc.SetUserScale(1.0, 1.0); +} + +// Draws the background +void wxShapeCanvas::DrawBackground(wxDC &dc, bool transformed) +{ + dc.SetBackground(wxBrush(GetBackgroundColour(), wxSOLID)); + dc.Clear(); +} + +void wxShapeCanvas::OnEraseBackground(wxEraseEvent &event) +{ +} + +void wxShapeCanvas::OnMouseEvent(wxMouseEvent &event) +{ + wxClientDC dc(this); + PrepareDC(dc); + + wxPoint logPos(event.GetLogicalPosition(dc)); + + double x, y; + x = (double) logPos.x; + y = (double) logPos.y; + + int keys = 0; + if (event.ShiftDown()) + keys = keys | KEY_SHIFT; + if (event.ControlDown()) + keys = keys | KEY_CTRL; + + bool dragging = event.Dragging(); + + // Check if we're within the tolerance for mouse movements. + // If we're very close to the position we started dragging + // from, this may not be an intentional drag at all. + if (dragging) + { + int dx = abs(dc.LogicalToDeviceX((long) (x - m_firstDragX))); + int dy = abs(dc.LogicalToDeviceY((long) (y - m_firstDragY))); + if (m_checkTolerance && (dx <= GetDiagram()->GetMouseTolerance()) && (dy <= GetDiagram()->GetMouseTolerance())) + { + return; + } + else + // If we've ignored the tolerance once, then ALWAYS ignore + // tolerance in this drag, even if we come back within + // the tolerance range. + m_checkTolerance = FALSE; + } + + // Dragging - note that the effect of dragging is left entirely up + // to the object, so no movement is done unless explicitly done by + // object. + if (dragging && m_draggedShape && m_dragState == StartDraggingLeft) + { + m_dragState = ContinueDraggingLeft; + + // If the object isn't m_draggable, transfer message to canvas + if (m_draggedShape->Draggable()) + m_draggedShape->GetEventHandler()->OnBeginDragLeft((double)x, (double)y, keys, m_draggedAttachment); + else + { + m_draggedShape = NULL; + OnBeginDragLeft((double)x, (double)y, keys); + } + + m_oldDragX = x; + m_oldDragY = y; + } + else if (dragging && m_draggedShape && m_dragState == ContinueDraggingLeft) + { + // Continue dragging + m_draggedShape->GetEventHandler()->OnDragLeft(FALSE, m_oldDragX, m_oldDragY, keys, m_draggedAttachment); + m_draggedShape->GetEventHandler()->OnDragLeft(TRUE, (double)x, (double)y, keys, m_draggedAttachment); + m_oldDragX = x; + m_oldDragY = y; + } + else if (event.LeftUp() && m_draggedShape && m_dragState == ContinueDraggingLeft) + { + m_dragState = NoDragging; + m_checkTolerance = TRUE; + + m_draggedShape->GetEventHandler()->OnDragLeft(FALSE, m_oldDragX, m_oldDragY, keys, m_draggedAttachment); + + m_draggedShape->GetEventHandler()->OnEndDragLeft((double)x, (double)y, keys, m_draggedAttachment); + m_draggedShape = NULL; + } + else if (dragging && m_draggedShape && m_dragState == StartDraggingRight) + { + m_dragState = ContinueDraggingRight; + + if (m_draggedShape->Draggable()) + m_draggedShape->GetEventHandler()->OnBeginDragRight((double)x, (double)y, keys, m_draggedAttachment); + else + { + m_draggedShape = NULL; + OnBeginDragRight((double)x, (double)y, keys); + } + m_oldDragX = x; + m_oldDragY = y; + } + else if (dragging && m_draggedShape && m_dragState == ContinueDraggingRight) + { + // Continue dragging + m_draggedShape->GetEventHandler()->OnDragRight(FALSE, m_oldDragX, m_oldDragY, keys, m_draggedAttachment); + m_draggedShape->GetEventHandler()->OnDragRight(TRUE, (double)x, (double)y, keys, m_draggedAttachment); + m_oldDragX = x; + m_oldDragY = y; + } + else if (event.RightUp() && m_draggedShape && m_dragState == ContinueDraggingRight) + { + m_dragState = NoDragging; + m_checkTolerance = TRUE; + + m_draggedShape->GetEventHandler()->OnDragRight(FALSE, m_oldDragX, m_oldDragY, keys, m_draggedAttachment); + + m_draggedShape->GetEventHandler()->OnEndDragRight((double)x, (double)y, keys, m_draggedAttachment); + m_draggedShape = NULL; + } + + // All following events sent to canvas, not object + else if (dragging && !m_draggedShape && m_dragState == StartDraggingLeft) + { + m_dragState = ContinueDraggingLeft; + OnBeginDragLeft((double)x, (double)y, keys); + m_oldDragX = x; + m_oldDragY = y; + } + else if (dragging && !m_draggedShape && m_dragState == ContinueDraggingLeft) + { + // Continue dragging + OnDragLeft(FALSE, m_oldDragX, m_oldDragY, keys); + OnDragLeft(TRUE, (double)x, (double)y, keys); + m_oldDragX = x; + m_oldDragY = y; + } + else if (event.LeftUp() && !m_draggedShape && m_dragState == ContinueDraggingLeft) + { + m_dragState = NoDragging; + m_checkTolerance = TRUE; + + OnDragLeft(FALSE, m_oldDragX, m_oldDragY, keys); + OnEndDragLeft((double)x, (double)y, keys); + m_draggedShape = NULL; + } + else if (dragging && !m_draggedShape && m_dragState == StartDraggingRight) + { + m_dragState = ContinueDraggingRight; + OnBeginDragRight((double)x, (double)y, keys); + m_oldDragX = x; + m_oldDragY = y; + } + else if (dragging && !m_draggedShape && m_dragState == ContinueDraggingRight) + { + // Continue dragging + OnDragRight(FALSE, m_oldDragX, m_oldDragY, keys); + OnDragRight(TRUE, (double)x, (double)y, keys); + m_oldDragX = x; + m_oldDragY = y; + } + else if (event.RightUp() && !m_draggedShape && m_dragState == ContinueDraggingRight) + { + m_dragState = NoDragging; + m_checkTolerance = TRUE; + + OnDragRight(FALSE, m_oldDragX, m_oldDragY, keys); + OnEndDragRight((double)x, (double)y, keys); + m_draggedShape = NULL; + } + + // Non-dragging events + else if (event.IsButton()) + { + m_checkTolerance = TRUE; + + // Find the nearest object + int attachment = 0; + wxShape *nearest_object = FindShape(x, y, &attachment); + if (nearest_object) // Object event + { + if (event.LeftDown()) + { + m_draggedShape = nearest_object; + m_draggedAttachment = attachment; + m_dragState = StartDraggingLeft; + m_firstDragX = x; + m_firstDragY = y; + } + else if (event.LeftUp()) + { + // N.B. Only register a click if the same object was + // identified for down *and* up. + if (nearest_object == m_draggedShape) + nearest_object->GetEventHandler()->OnLeftClick((double)x, (double)y, keys, attachment); + + m_draggedShape = NULL; + m_dragState = NoDragging; + } + else if (event.LeftDClick()) + { + nearest_object->GetEventHandler()->OnLeftDoubleClick((double)x, (double)y, keys, attachment); + + m_draggedShape = NULL; + m_dragState = NoDragging; + } + else if (event.RightDown()) + { + m_draggedShape = nearest_object; + m_draggedAttachment = attachment; + m_dragState = StartDraggingRight; + m_firstDragX = x; + m_firstDragY = y; + } + else if (event.RightUp()) + { + if (nearest_object == m_draggedShape) + nearest_object->GetEventHandler()->OnRightClick((double)x, (double)y, keys, attachment); + + m_draggedShape = NULL; + m_dragState = NoDragging; + } + } + else // Canvas event (no nearest object) + { + if (event.LeftDown()) + { + m_draggedShape = NULL; + m_dragState = StartDraggingLeft; + m_firstDragX = x; + m_firstDragY = y; + } + else if (event.LeftUp()) + { + OnLeftClick((double)x, (double)y, keys); + + m_draggedShape = NULL; + m_dragState = NoDragging; + } + else if (event.RightDown()) + { + m_draggedShape = NULL; + m_dragState = StartDraggingRight; + m_firstDragX = x; + m_firstDragY = y; + } + else if (event.RightUp()) + { + OnRightClick((double)x, (double)y, keys); + + m_draggedShape = NULL; + m_dragState = NoDragging; + } + } + } +} + +/* + * Try to find a sensitive object, working up the hierarchy of composites. + * + */ +wxShape *wxShapeCanvas::FindFirstSensitiveShape(double x, double y, int *new_attachment, int op) +{ + wxShape *image = FindShape(x, y, new_attachment); + if (!image) return NULL; + + wxShape *actualImage = FindFirstSensitiveShape1(image, op); + if (actualImage) + { + double dist; + // Find actual attachment + actualImage->HitTest(x, y, new_attachment, &dist); + } + return actualImage; +} + +wxShape *wxShapeCanvas::FindFirstSensitiveShape1(wxShape *image, int op) +{ + if (image->GetSensitivityFilter() & op) + return image; + if (image->GetParent()) + return FindFirstSensitiveShape1(image->GetParent(), op); + return NULL; +} + +// Helper function: TRUE if 'contains' wholly contains 'contained'. +static bool WhollyContains(wxShape *contains, wxShape *contained) +{ + double xp1, yp1, xp2, yp2; + double w1, h1, w2, h2; + double left1, top1, right1, bottom1, left2, top2, right2, bottom2; + + xp1 = contains->GetX(); + yp1 = contains->GetY(); + xp2 = contained->GetX(); + yp2 = contained->GetY(); + contains->GetBoundingBoxMax(&w1, &h1); + contained->GetBoundingBoxMax(&w2, &h2); + + left1 = (double)(xp1 - (w1 / 2.0)); + top1 = (double)(yp1 - (h1 / 2.0)); + right1 = (double)(xp1 + (w1 / 2.0)); + bottom1 = (double)(yp1 + (h1 / 2.0)); + + left2 = (double)(xp2 - (w2 / 2.0)); + top2 = (double)(yp2 - (h2 / 2.0)); + right2 = (double)(xp2 + (w2 / 2.0)); + bottom2 = (double)(yp2 + (h2 / 2.0)); + + return ((left1 <= left2) && (top1 <= top2) && (right1 >= right2) && (bottom1 >= bottom2)); +} + +wxShape *wxShapeCanvas::FindShape(double x, double y, int *attachment, wxClassInfo *info, wxShape *notObject) +{ + double nearest = 100000.0; + int nearest_attachment = 0; + wxShape *nearest_object = NULL; + + // Go backward through the object list, since we want: + // (a) to have the control points drawn LAST to overlay + // the other objects + // (b) to find the control points FIRST if they exist + + wxNode *current = GetDiagram()->GetShapeList()->GetLast(); + while (current) + { + wxShape *object = (wxShape *)current->GetData(); + + double dist; + int temp_attachment; + + // First pass for lines, which might be inside a container, so we + // want lines to take priority over containers. This first loop + // could fail if we clickout side a line, so then we'll + // try other shapes. + if (object->IsShown() && + object->IsKindOf(CLASSINFO(wxLineShape)) && + object->HitTest(x, y, &temp_attachment, &dist) && + ((info == NULL) || object->IsKindOf(info)) && + (!notObject || !notObject->HasDescendant(object))) + { + // A line is trickier to spot than a normal object. + // For a line, since it's the diagonal of the box + // we use for the hit test, we may have several + // lines in the box and therefore we need to be able + // to specify the nearest point to the centre of the line + // as our hit criterion, to give the user some room for + // manouevre. + if (dist < nearest) + { + nearest = dist; + nearest_object = object; + nearest_attachment = temp_attachment; + } + } + if (current) + current = current->GetPrevious(); + } + + current = GetDiagram()->GetShapeList()->GetLast(); + while (current) + { + wxShape *object = (wxShape *)current->GetData(); + double dist; + int temp_attachment; + + // On second pass, only ever consider non-composites or divisions. If children want to pass + // up control to the composite, that's up to them. + if (object->IsShown() && (object->IsKindOf(CLASSINFO(wxDivisionShape)) || !object->IsKindOf(CLASSINFO(wxCompositeShape))) + && object->HitTest(x, y, &temp_attachment, &dist) && ((info == NULL) || object->IsKindOf(info)) && + (!notObject || !notObject->HasDescendant(object))) + { + if (!object->IsKindOf(CLASSINFO(wxLineShape))) + { + // If we've hit a container, and we have already found a line in the + // first pass, then ignore the container in case the line is in the container. + // Check for division in case line straddles divisions (i.e. is not wholly contained). + if (!nearest_object || !(object->IsKindOf(CLASSINFO(wxDivisionShape)) || WhollyContains(object, nearest_object))) + { + nearest_object = object; + nearest_attachment = temp_attachment; + current = NULL; + } + } + } + if (current) + current = current->GetPrevious(); + } + + *attachment = nearest_attachment; + return nearest_object; +} + +/* + * Higher-level events called by OnEvent + * + */ + +void wxShapeCanvas::OnLeftClick(double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys)) +{ +} + +void wxShapeCanvas::OnRightClick(double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys)) +{ +} + +void wxShapeCanvas::OnDragLeft(bool WXUNUSED(draw), double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys)) +{ +} + +void wxShapeCanvas::OnBeginDragLeft(double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys)) +{ +} + +void wxShapeCanvas::OnEndDragLeft(double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys)) +{ +} + +void wxShapeCanvas::OnDragRight(bool WXUNUSED(draw), double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys)) +{ +} + +void wxShapeCanvas::OnBeginDragRight(double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys)) +{ +} + +void wxShapeCanvas::OnEndDragRight(double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys)) +{ +} + +void wxShapeCanvas::AddShape(wxShape *object, wxShape *addAfter) +{ + GetDiagram()->AddShape(object, addAfter); +} +void wxShapeCanvas::InsertShape(wxShape *object) +{ + GetDiagram()->InsertShape(object); +} +void wxShapeCanvas::RemoveShape(wxShape *object) +{ + GetDiagram()->RemoveShape(object); +} +bool wxShapeCanvas::GetQuickEditMode() +{ + return GetDiagram()->GetQuickEditMode(); +} +void wxShapeCanvas::Redraw(wxDC &dc) +{ + GetDiagram()->Redraw(dc); +} +void wxShapeCanvas::Snap(double *x, double *y) +{ + GetDiagram()->Snap(x, y); +} + +// Returns the current scroll position +wxPoint wxShapeCanvas::GetCurrentPixelScrollPosition() +{ + int pixelsPerUnitX, pixelsPerUnitY; + GetScrollPixelsPerUnit(& pixelsPerUnitX, & pixelsPerUnitY); + + int posX, posY; + GetViewStart(& posX, & posY); + + wxPoint pt(pixelsPerUnitX * posX, pixelsPerUnitY * posY); + return pt; +} diff --git a/ogl/composit.cpp b/ogl/composit.cpp new file mode 100644 index 0000000..6205d36 --- /dev/null +++ b/ogl/composit.cpp @@ -0,0 +1,1757 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// composit.cpp - Composite OGL class +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include "ogl/ogl.h" + +#if wxUSE_PROLOGIO +// Sometimes, objects need to access the whole database to +// construct themselves. +wxExprDatabase *GlobalwxExprDatabase = NULL; +#endif + +/* + * Division control point + */ + +class wxDivisionControlPoint: public wxControlPoint +{ + DECLARE_DYNAMIC_CLASS(wxDivisionControlPoint) +public: + wxDivisionControlPoint() {} + wxDivisionControlPoint(wxShapeCanvas *the_canvas, wxShape *object, double size, double the_xoffset, double the_yoffset, int the_type); + ~wxDivisionControlPoint(); + + void OnDragLeft(bool draw, double x, double y, int keys = 0, int attachment = 0); + void OnBeginDragLeft(double x, double y, int keys = 0, int attachment = 0); + void OnEndDragLeft(double x, double y, int keys = 0, int attachment = 0); +}; + +IMPLEMENT_DYNAMIC_CLASS(wxDivisionControlPoint, wxControlPoint) + +/* + * Composite object + * + */ + +IMPLEMENT_DYNAMIC_CLASS(wxCompositeShape, wxRectangleShape) + +wxCompositeShape::wxCompositeShape(): wxRectangleShape(10.0, 10.0) +{ +// selectable = FALSE; + m_oldX = m_xpos; + m_oldY = m_ypos; +} + +wxCompositeShape::~wxCompositeShape() +{ + wxNode *node = m_constraints.GetFirst(); + while (node) + { + wxOGLConstraint *constraint = (wxOGLConstraint *)node->GetData(); + delete constraint; + node = node->GetNext(); + } + node = m_children.GetFirst(); + while (node) + { + wxShape *object = (wxShape *)node->GetData(); + wxNode *next = node->GetNext(); + object->Unlink(); + delete object; + node = next; + } +} + +void wxCompositeShape::OnDraw(wxDC &dc) +{ + double x1 = (double)(m_xpos - m_width / 2.0); + double y1 = (double)(m_ypos - m_height / 2.0); + + if (m_shadowMode != SHADOW_NONE) + { + if (m_shadowBrush) + dc.SetBrush(* m_shadowBrush); + dc.SetPen(* g_oglTransparentPen); + + if (m_cornerRadius != 0.0) + dc.DrawRoundedRectangle(WXROUND(x1 + m_shadowOffsetX), WXROUND(y1 + m_shadowOffsetY), + WXROUND(m_width), WXROUND(m_height), m_cornerRadius); + else + dc.DrawRectangle(WXROUND(x1 + m_shadowOffsetX), WXROUND(y1 + m_shadowOffsetY), WXROUND(m_width), WXROUND(m_height)); + } +} + +void wxCompositeShape::OnDrawContents(wxDC &dc) +{ + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *object = (wxShape *)node->GetData(); + object->Draw(dc); + object->DrawLinks(dc); + node = node->GetNext(); + } + wxShape::OnDrawContents(dc); +} + +bool wxCompositeShape::OnMovePre(double x, double y, double oldx, double oldy, bool display) +{ + double diffX = x - oldx; + double diffY = y - oldy; + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *object = (wxShape *)node->GetData(); + + object->Move(object->GetX() + diffX, object->GetY() + diffY, display); + + node = node->GetNext(); + } + return TRUE; +} + +static double objectStartX = 0.0; +static double objectStartY = 0.0; + +void wxCompositeShape::OnDragLeft(bool WXUNUSED(draw), double x, double y, int WXUNUSED(keys), int WXUNUSED(attachment)) +{ + double xx = x; + double yy = y; + m_canvas->Snap(&xx, &yy); + double offsetX = xx - objectStartX; + double offsetY = yy - objectStartY; + + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + dc.SetLogicalFunction(OGLRBLF); + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + dc.SetPen(dottedPen); + dc.SetBrush((* wxTRANSPARENT_BRUSH)); + + GetEventHandler()->OnDrawOutline(dc, GetX() + offsetX, GetY() + offsetY, GetWidth(), GetHeight()); +// wxShape::OnDragLeft(draw, x, y, keys, attachment); +} + +void wxCompositeShape::OnBeginDragLeft(double x, double y, int WXUNUSED(keys), int WXUNUSED(attachment)) +{ + objectStartX = x; + objectStartY = y; + + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + Erase(); + + dc.SetLogicalFunction(OGLRBLF); + + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + dc.SetPen(dottedPen); + dc.SetBrush((* wxTRANSPARENT_BRUSH)); + m_canvas->CaptureMouse(); + + double xx = x; + double yy = y; + m_canvas->Snap(&xx, &yy); + double offsetX = xx - objectStartX; + double offsetY = yy - objectStartY; + + GetEventHandler()->OnDrawOutline(dc, GetX() + offsetX, GetY() + offsetY, GetWidth(), GetHeight()); + +// wxShape::OnBeginDragLeft(x, y, keys, attachment); +} + +void wxCompositeShape::OnEndDragLeft(double x, double y, int keys, int WXUNUSED(attachment)) +{ +// wxShape::OnEndDragLeft(x, y, keys, attachment); + + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + m_canvas->ReleaseMouse(); + + if (!m_draggable) + { + if (m_parent) m_parent->GetEventHandler()->OnEndDragLeft(x, y, keys, 0); + return; + } + + dc.SetLogicalFunction(wxCOPY); + double xx = x; + double yy = y; + m_canvas->Snap(&xx, &yy); + double offsetX = xx - objectStartX; + double offsetY = yy - objectStartY; + + Move(GetX() + offsetX, GetY() + offsetY); + + if (m_canvas && !m_canvas->GetQuickEditMode()) m_canvas->Redraw(dc); +} + +void wxCompositeShape::OnRightClick(double x, double y, int keys, int WXUNUSED(attachment)) +{ + // If we get a ctrl-right click, this means send the message to + // the division, so we can invoke a user interface for dealing with regions. + if (keys & KEY_CTRL) + { + wxNode *node = m_divisions.GetFirst(); + while (node) + { + wxDivisionShape *division = (wxDivisionShape *)node->GetData(); + wxNode *next = node->GetNext(); + int attach = 0; + double dist = 0.0; + if (division->HitTest(x, y, &attach, &dist)) + { + division->GetEventHandler()->OnRightClick(x, y, keys, attach); + node = NULL; + } + if (node) + node = next; + } + } +} + +void wxCompositeShape::SetSize(double w, double h, bool recursive) +{ + SetAttachmentSize(w, h); + + double xScale = (double)(w / (wxMax(1.0, GetWidth()))); + double yScale = (double)(h / (wxMax(1.0, GetHeight()))); + + m_width = w; + m_height = h; + + if (!recursive) return; + + wxNode *node = m_children.GetFirst(); + + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + double xBound, yBound; + while (node) + { + wxShape *object = (wxShape *)node->GetData(); + + // Scale the position first + double newX = (double)(((object->GetX() - GetX()) * xScale) + GetX()); + double newY = (double)(((object->GetY() - GetY()) * yScale) + GetY()); + object->Show(FALSE); + object->Move(newX, newY); + object->Show(TRUE); + + // Now set the scaled size + object->GetBoundingBoxMin(&xBound, &yBound); + object->SetSize(object->GetFixedWidth() ? xBound : xScale * xBound, + object->GetFixedHeight() ? yBound : yScale * yBound); + + node = node->GetNext(); + } + SetDefaultRegionSize(); +} + +void wxCompositeShape::AddChild(wxShape *child, wxShape *addAfter) +{ + m_children.Append(child); + child->SetParent(this); + if (m_canvas) + { + // Ensure we add at the right position + if (addAfter) + child->RemoveFromCanvas(m_canvas); + child->AddToCanvas(m_canvas, addAfter); + } +} + +void wxCompositeShape::RemoveChild(wxShape *child) +{ + m_children.DeleteObject(child); + m_divisions.DeleteObject(child); + RemoveChildFromConstraints(child); + child->SetParent(NULL); +} + +void wxCompositeShape::DeleteConstraintsInvolvingChild(wxShape *child) +{ + wxNode *node = m_constraints.GetFirst(); + while (node) + { + wxOGLConstraint *constraint = (wxOGLConstraint *)node->GetData(); + wxNode *nextNode = node->GetNext(); + + if ((constraint->m_constrainingObject == child) || + constraint->m_constrainedObjects.Member(child)) + { + delete constraint; + delete node; + } + node = nextNode; + } +} + +void wxCompositeShape::RemoveChildFromConstraints(wxShape *child) +{ + wxNode *node = m_constraints.GetFirst(); + while (node) + { + wxOGLConstraint *constraint = (wxOGLConstraint *)node->GetData(); + wxNode *nextNode = node->GetNext(); + + if (constraint->m_constrainedObjects.Member(child)) + constraint->m_constrainedObjects.DeleteObject(child); + if (constraint->m_constrainingObject == child) + constraint->m_constrainingObject = NULL; + + // Delete the constraint if no participants left + if (!constraint->m_constrainingObject) + { + delete constraint; + delete node; + } + + node = nextNode; + } +} + +void wxCompositeShape::Copy(wxShape ©) +{ + wxRectangleShape::Copy(copy); + + wxASSERT( copy.IsKindOf(CLASSINFO(wxCompositeShape)) ) ; + + wxCompositeShape &compositeCopy = (wxCompositeShape &) copy; + + // Associate old and new copies for compositeCopying constraints and division geometry + oglObjectCopyMapping.Append((long)this, &compositeCopy); + + // Copy the children + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *object = (wxShape *)node->GetData(); + wxShape *newObject = object->CreateNewCopy(FALSE, FALSE); + if (newObject->GetId() == 0) + newObject->SetId(wxNewId()); + + newObject->SetParent(&compositeCopy); + compositeCopy.m_children.Append(newObject); + + // Some m_children may be divisions + if (m_divisions.Member(object)) + compositeCopy.m_divisions.Append(newObject); + + oglObjectCopyMapping.Append((long)object, newObject); + + node = node->GetNext(); + } + + // Copy the constraints + node = m_constraints.GetFirst(); + while (node) + { + wxOGLConstraint *constraint = (wxOGLConstraint *)node->GetData(); + + wxShape *newConstraining = (wxShape *)(oglObjectCopyMapping.Find((long)constraint->m_constrainingObject)->GetData()); + + wxList newConstrainedList; + wxNode *node2 = constraint->m_constrainedObjects.GetFirst(); + while (node2) + { + wxShape *constrainedObject = (wxShape *)node2->GetData(); + wxShape *newConstrained = (wxShape *)(oglObjectCopyMapping.Find((long)constrainedObject)->GetData()); + newConstrainedList.Append(newConstrained); + node2 = node2->GetNext(); + } + + wxOGLConstraint *newConstraint = new wxOGLConstraint(constraint->m_constraintType, newConstraining, + newConstrainedList); + newConstraint->m_constraintId = constraint->m_constraintId; + if (!constraint->m_constraintName.IsEmpty()) + { + newConstraint->m_constraintName = constraint->m_constraintName; + } + newConstraint->SetSpacing(constraint->m_xSpacing, constraint->m_ySpacing); + compositeCopy.m_constraints.Append(newConstraint); + + node = node->GetNext(); + } + + // Now compositeCopy the division geometry + node = m_divisions.GetFirst(); + while (node) + { + wxDivisionShape *division = (wxDivisionShape *)node->GetData(); + wxNode *node1 = oglObjectCopyMapping.Find((long)division); + wxNode *leftNode = NULL; + wxNode *topNode = NULL; + wxNode *rightNode = NULL; + wxNode *bottomNode = NULL; + if (division->GetLeftSide()) + leftNode = oglObjectCopyMapping.Find((long)division->GetLeftSide()); + if (division->GetTopSide()) + topNode = oglObjectCopyMapping.Find((long)division->GetTopSide()); + if (division->GetRightSide()) + rightNode = oglObjectCopyMapping.Find((long)division->GetRightSide()); + if (division->GetBottomSide()) + bottomNode = oglObjectCopyMapping.Find((long)division->GetBottomSide()); + if (node1) + { + wxDivisionShape *newDivision = (wxDivisionShape *)node1->GetData(); + if (leftNode) + newDivision->SetLeftSide((wxDivisionShape *)leftNode->GetData()); + if (topNode) + newDivision->SetTopSide((wxDivisionShape *)topNode->GetData()); + if (rightNode) + newDivision->SetRightSide((wxDivisionShape *)rightNode->GetData()); + if (bottomNode) + newDivision->SetBottomSide((wxDivisionShape *)bottomNode->GetData()); + } + node = node->GetNext(); + } +} + +wxOGLConstraint *wxCompositeShape::AddConstraint(wxOGLConstraint *constraint) +{ + m_constraints.Append(constraint); + if (constraint->m_constraintId == 0) + constraint->m_constraintId = wxNewId(); + return constraint; +} + +wxOGLConstraint *wxCompositeShape::AddConstraint(int type, wxShape *constraining, wxList &constrained) +{ + wxOGLConstraint *constraint = new wxOGLConstraint(type, constraining, constrained); + if (constraint->m_constraintId == 0) + constraint->m_constraintId = wxNewId(); + m_constraints.Append(constraint); + return constraint; +} + +wxOGLConstraint *wxCompositeShape::AddConstraint(int type, wxShape *constraining, wxShape *constrained) +{ + wxList l; + l.Append(constrained); + wxOGLConstraint *constraint = new wxOGLConstraint(type, constraining, l); + if (constraint->m_constraintId == 0) + constraint->m_constraintId = wxNewId(); + m_constraints.Append(constraint); + return constraint; +} + +wxOGLConstraint *wxCompositeShape::FindConstraint(long cId, wxCompositeShape **actualComposite) +{ + wxNode *node = m_constraints.GetFirst(); + while (node) + { + wxOGLConstraint *constraint = (wxOGLConstraint *)node->GetData(); + if (constraint->m_constraintId == cId) + { + if (actualComposite) + *actualComposite = this; + return constraint; + } + node = node->GetNext(); + } + // If not found, try children. + node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + if (child->IsKindOf(CLASSINFO(wxCompositeShape))) + { + wxOGLConstraint *constraint = ((wxCompositeShape *)child)->FindConstraint(cId, actualComposite); + if (constraint) + { + if (actualComposite) + *actualComposite = (wxCompositeShape *)child; + return constraint; + } + } + node = node->GetNext(); + } + return NULL; +} + +void wxCompositeShape::DeleteConstraint(wxOGLConstraint *constraint) +{ + m_constraints.DeleteObject(constraint); + delete constraint; +} + +void wxCompositeShape::CalculateSize() +{ + double maxX = (double) - 999999.9; + double maxY = (double) - 999999.9; + double minX = (double) 999999.9; + double minY = (double) 999999.9; + + double w, h; + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *object = (wxShape *)node->GetData(); + + // Recalculate size of composite objects because may not conform + // to size it was set to - depends on the children. + object->CalculateSize(); + + object->GetBoundingBoxMax(&w, &h); + if ((object->GetX() + (w / 2.0)) > maxX) + maxX = (double)(object->GetX() + (w / 2.0)); + if ((object->GetX() - (w / 2.0)) < minX) + minX = (double)(object->GetX() - (w / 2.0)); + if ((object->GetY() + (h / 2.0)) > maxY) + maxY = (double)(object->GetY() + (h / 2.0)); + if ((object->GetY() - (h / 2.0)) < minY) + minY = (double)(object->GetY() - (h / 2.0)); + + node = node->GetNext(); + } + m_width = maxX - minX; + m_height = maxY - minY; + m_xpos = (double)(m_width / 2.0 + minX); + m_ypos = (double)(m_height / 2.0 + minY); +} + +bool wxCompositeShape::Recompute() +{ + int noIterations = 0; + bool changed = TRUE; + while (changed && (noIterations < 500)) + { + changed = Constrain(); + noIterations ++; + } + /* + #ifdef wx_x + if (changed) + cerr << "Warning: constraint algorithm failed after 500 iterations.\n"; + #endif + */ + return (!changed); +} + +bool wxCompositeShape::Constrain() +{ + CalculateSize(); + + bool changed = FALSE; + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *object = (wxShape *)node->GetData(); + if (object->Constrain()) + changed = TRUE; + node = node->GetNext(); + } + + node = m_constraints.GetFirst(); + while (node) + { + wxOGLConstraint *constraint = (wxOGLConstraint *)node->GetData(); + if (constraint->Evaluate()) changed = TRUE; + node = node->GetNext(); + } + return changed; +} + +#if wxUSE_PROLOGIO +void wxCompositeShape::WriteAttributes(wxExpr *clause) +{ + wxRectangleShape::WriteAttributes(clause); + +// clause->AddAttributeValue("selectable", (long)selectable); + + // Output constraints as constraint1 = (...), constraint2 = (...), etc. + int constraintNo = 1; + wxChar m_constraintNameBuf[20]; + wxNode *node = m_constraints.GetFirst(); + while (node) + { + wxOGLConstraint *constraint = (wxOGLConstraint *)node->GetData(); + wxSprintf(m_constraintNameBuf, wxT("constraint%d"), constraintNo); + + // Each constraint is stored in the form + // (type name id xspacing yspacing m_constrainingObjectId constrainedObjectIdList) + wxExpr *constraintExpr = new wxExpr(wxExprList); + constraintExpr->Append(new wxExpr((long)constraint->m_constraintType)); + constraintExpr->Append(new wxExpr(wxExprString, constraint->m_constraintName)); + constraintExpr->Append(new wxExpr(constraint->m_constraintId)); + constraintExpr->Append(new wxExpr(constraint->m_xSpacing)); + constraintExpr->Append(new wxExpr(constraint->m_ySpacing)); + constraintExpr->Append(new wxExpr(constraint->m_constrainingObject->GetId())); + + wxExpr *objectList = new wxExpr(wxExprList); + wxNode *node1 = constraint->m_constrainedObjects.GetFirst(); + while (node1) + { + wxShape *obj = (wxShape *)node1->GetData(); + objectList->Append(new wxExpr(obj->GetId())); + node1 = node1->GetNext(); + } + constraintExpr->Append(objectList); + + clause->AddAttributeValue(m_constraintNameBuf, constraintExpr); + + node = node->GetNext(); + constraintNo ++; + } + + // Write the ids of all the child images + wxExpr *childrenExpr = new wxExpr(wxExprList); + node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + childrenExpr->Append(new wxExpr(child->GetId())); + node = node->GetNext(); + } + clause->AddAttributeValue(wxT("children"), childrenExpr); + + // Write the ids of all the division images + if (m_divisions.GetCount() > 0) + { + wxExpr *divisionsExpr = new wxExpr(wxExprList); + node = m_divisions.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + divisionsExpr->Append(new wxExpr(child->GetId())); + node = node->GetNext(); + } + clause->AddAttributeValue(wxT("divisions"), divisionsExpr); + } +} + +// Problem. Child images are always written AFTER the parent +// so as to be able to link up to parent. So we may not be able +// to find the constraint participants until we've read everything +// in. Need to have another pass for composites. +void wxCompositeShape::ReadAttributes(wxExpr *clause) +{ + wxRectangleShape::ReadAttributes(clause); + +// clause->GetAttributeValue("selectable", selectable); +} + +void wxCompositeShape::ReadConstraints(wxExpr *clause, wxExprDatabase *database) +{ + // Constraints are output as constraint1 = (...), constraint2 = (...), etc. + int constraintNo = 1; + wxChar m_constraintNameBuf[20]; + bool haveConstraints = TRUE; + + while (haveConstraints) + { + wxSprintf(m_constraintNameBuf, wxT("constraint%d"), constraintNo); + wxExpr *constraintExpr = NULL; + clause->GetAttributeValue(m_constraintNameBuf, &constraintExpr); + if (!constraintExpr) + { + haveConstraints = FALSE; + break; + } + wxString cName = wxEmptyString; + wxShape *m_constrainingObject = NULL; + wxList m_constrainedObjects; + + // Each constraint is stored in the form + // (type name id xspacing yspacing m_constrainingObjectId constrainedObjectIdList) + + wxExpr *typeExpr = constraintExpr->Nth(0); + wxExpr *nameExpr = constraintExpr->Nth(1); + wxExpr *idExpr = constraintExpr->Nth(2); + wxExpr *xExpr = constraintExpr->Nth(3); + wxExpr *yExpr = constraintExpr->Nth(4); + wxExpr *constrainingExpr = constraintExpr->Nth(5); + wxExpr *constrainedExpr = constraintExpr->Nth(6); + + int cType = (int)typeExpr->IntegerValue(); + double cXSpacing = xExpr->RealValue(); + double cYSpacing = yExpr->RealValue(); + cName = nameExpr->StringValue(); + long cId = idExpr->IntegerValue(); + + wxExpr *objExpr1 = database->HashFind(wxT("node_image"), constrainingExpr->IntegerValue()); + if (objExpr1 && objExpr1->GetClientData()) + m_constrainingObject = (wxShape *)objExpr1->GetClientData(); + else + wxLogFatalError(wxT("Object graphics error: Couldn't find constraining image of composite.")); + + int i = 0; + wxExpr *currentIdExpr = constrainedExpr->Nth(i); + while (currentIdExpr) + { + long currentId = currentIdExpr->IntegerValue(); + wxExpr *objExpr2 = database->HashFind(wxT("node_image"), currentId); + if (objExpr2 && objExpr2->GetClientData()) + { + m_constrainedObjects.Append((wxShape *)objExpr2->GetClientData()); + } + else + { + wxLogFatalError(wxT("Object graphics error: Couldn't find constrained image of composite.")); + } + + i ++; + currentIdExpr = constrainedExpr->Nth(i); + } + wxOGLConstraint *newConstraint = AddConstraint(cType, m_constrainingObject, m_constrainedObjects); + newConstraint->SetSpacing(cXSpacing, cYSpacing); + newConstraint->m_constraintId = cId; + newConstraint->m_constraintName = cName; + constraintNo ++; + } +} +#endif + +// Make this composite into a container by creating one wxDivisionShape +void wxCompositeShape::MakeContainer() +{ + wxDivisionShape *division = OnCreateDivision(); + m_divisions.Append(division); + AddChild(division); + + division->SetSize(m_width, m_height); + + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + division->Move(GetX(), GetY()); + Recompute(); + division->Show(TRUE); +} + +wxDivisionShape *wxCompositeShape::OnCreateDivision() +{ + return new wxDivisionShape; +} + +wxShape *wxCompositeShape::FindContainerImage() +{ + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + if (!m_divisions.Member(child)) + return child; + node = node->GetNext(); + } + return NULL; +} + +// Returns TRUE if division is a descendant of this container +bool wxCompositeShape::ContainsDivision(wxDivisionShape *division) +{ + if (m_divisions.Member(division)) + return TRUE; + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + if (child->IsKindOf(CLASSINFO(wxCompositeShape))) + { + bool ans = ((wxCompositeShape *)child)->ContainsDivision(division); + if (ans) + return TRUE; + } + node = node->GetNext(); + } + return FALSE; +} + +/* + * Division object + * + */ + +IMPLEMENT_DYNAMIC_CLASS(wxDivisionShape, wxCompositeShape) + +wxDivisionShape::wxDivisionShape() +{ + SetSensitivityFilter(OP_CLICK_LEFT | OP_CLICK_RIGHT | OP_DRAG_RIGHT); + SetCentreResize(FALSE); + SetAttachmentMode(TRUE); + m_leftSide = NULL; + m_rightSide = NULL; + m_topSide = NULL; + m_bottomSide = NULL; + m_handleSide = DIVISION_SIDE_NONE; + m_leftSidePen = (wxPen *) wxBLACK_PEN; + m_topSidePen = (wxPen *) wxBLACK_PEN; + m_leftSideColour = wxT("BLACK"); + m_topSideColour = wxT("BLACK"); + m_leftSideStyle = wxT("Solid"); + m_topSideStyle = wxT("Solid"); + ClearRegions(); +} + +wxDivisionShape::~wxDivisionShape() +{ +} + +void wxDivisionShape::OnDraw(wxDC &dc) +{ + dc.SetBrush(* wxTRANSPARENT_BRUSH); + dc.SetBackgroundMode(wxTRANSPARENT); + + double x1 = (double)(GetX() - (GetWidth() / 2.0)); + double y1 = (double)(GetY() - (GetHeight() / 2.0)); + double x2 = (double)(GetX() + (GetWidth() / 2.0)); + double y2 = (double)(GetY() + (GetHeight() / 2.0)); + + // Should subtract 1 pixel if drawing under Windows +#ifdef __WXMSW__ + y2 -= (double)1.0; +#endif + + if (m_leftSide) + { + dc.SetPen(* m_leftSidePen); + dc.DrawLine(WXROUND(x1), WXROUND(y2), WXROUND(x1), WXROUND(y1)); + } + if (m_topSide) + { + dc.SetPen(* m_topSidePen); + dc.DrawLine(WXROUND(x1), WXROUND(y1), WXROUND(x2), WXROUND(y1)); + } + + // For testing purposes, draw a rectangle so we know + // how big the division is. +// SetBrush(* wxCYAN_BRUSH); +// wxRectangleShape::OnDraw(dc); +} + +void wxDivisionShape::OnDrawContents(wxDC &dc) +{ + wxCompositeShape::OnDrawContents(dc); +} + +bool wxDivisionShape::OnMovePre(double x, double y, double oldx, double oldy, bool display) +{ + double diffX = x - oldx; + double diffY = y - oldy; + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *object = (wxShape *)node->GetData(); + object->Erase(); + object->Move(object->GetX() + diffX, object->GetY() + diffY, display); + node = node->GetNext(); + } + return TRUE; +} + +void wxDivisionShape::OnDragLeft(bool draw, double x, double y, int keys, int attachment) +{ + if ((m_sensitivity & OP_DRAG_LEFT) != OP_DRAG_LEFT) + { + attachment = 0; + double dist; + if (m_parent) + { + m_parent->HitTest(x, y, &attachment, &dist); + m_parent->GetEventHandler()->OnDragLeft(draw, x, y, keys, attachment); + } + return; + } + wxShape::OnDragLeft(draw, x, y, keys, attachment); +} + +void wxDivisionShape::OnBeginDragLeft(double x, double y, int keys, int attachment) +{ + if ((m_sensitivity & OP_DRAG_LEFT) != OP_DRAG_LEFT) + { + attachment = 0; + double dist; + if (m_parent) + { + m_parent->HitTest(x, y, &attachment, &dist); + m_parent->GetEventHandler()->OnBeginDragLeft(x, y, keys, attachment); + } + return; + } + + wxShape::OnBeginDragLeft(x, y, keys, attachment); +} + +void wxDivisionShape::OnEndDragLeft(double x, double y, int keys, int attachment) +{ + m_canvas->ReleaseMouse(); + if ((m_sensitivity & OP_DRAG_LEFT) != OP_DRAG_LEFT) + { + attachment = 0; + double dist; + if (m_parent) + { + m_parent->HitTest(x, y, &attachment, &dist); + m_parent->GetEventHandler()->OnEndDragLeft(x, y, keys, attachment); + } + return; + } + +#if 0 + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + dc.SetLogicalFunction(wxCOPY); +#endif + + m_canvas->Snap(&m_xpos, &m_ypos); + GetEventHandler()->OnMovePre(x, y, m_oldX, m_oldY); + + ResetControlPoints(); + MoveLinks(); + + if (m_canvas) + m_canvas->Refresh(); +} + +void wxDivisionShape::SetSize(double w, double h, bool recursive) +{ + m_width = w; + m_height = h; + wxRectangleShape::SetSize(w, h, recursive); +} + +void wxDivisionShape::CalculateSize() +{ +} + +void wxDivisionShape::Copy(wxShape ©) +{ + wxCompositeShape::Copy(copy); + + wxASSERT( copy.IsKindOf(CLASSINFO(wxDivisionShape)) ) ; + + wxDivisionShape &divisionCopy = (wxDivisionShape &) copy; + + divisionCopy.m_leftSideStyle = m_leftSideStyle; + divisionCopy.m_topSideStyle = m_topSideStyle; + divisionCopy.m_leftSideColour = m_leftSideColour; + divisionCopy.m_topSideColour = m_topSideColour; + + divisionCopy.m_leftSidePen = m_leftSidePen; + divisionCopy.m_topSidePen = m_topSidePen; + divisionCopy.m_handleSide = m_handleSide; + + // Division geometry copying is handled at the wxCompositeShape level. +} + +#if wxUSE_PROLOGIO +void wxDivisionShape::WriteAttributes(wxExpr *clause) +{ + wxCompositeShape::WriteAttributes(clause); + + if (m_leftSide) + clause->AddAttributeValue(wxT("left_side"), (long)m_leftSide->GetId()); + if (m_topSide) + clause->AddAttributeValue(wxT("top_side"), (long)m_topSide->GetId()); + if (m_rightSide) + clause->AddAttributeValue(wxT("right_side"), (long)m_rightSide->GetId()); + if (m_bottomSide) + clause->AddAttributeValue(wxT("bottom_side"), (long)m_bottomSide->GetId()); + + clause->AddAttributeValue(wxT("handle_side"), (long)m_handleSide); + clause->AddAttributeValueString(wxT("left_colour"), m_leftSideColour); + clause->AddAttributeValueString(wxT("top_colour"), m_topSideColour); + clause->AddAttributeValueString(wxT("left_style"), m_leftSideStyle); + clause->AddAttributeValueString(wxT("top_style"), m_topSideStyle); +} + +void wxDivisionShape::ReadAttributes(wxExpr *clause) +{ + wxCompositeShape::ReadAttributes(clause); + + clause->GetAttributeValue(wxT("handle_side"), m_handleSide); + clause->GetAttributeValue(wxT("left_colour"), m_leftSideColour); + clause->GetAttributeValue(wxT("top_colour"), m_topSideColour); + clause->GetAttributeValue(wxT("left_style"), m_leftSideStyle); + clause->GetAttributeValue(wxT("top_style"), m_topSideStyle); +} +#endif + +// Experimental +void wxDivisionShape::OnRightClick(double x, double y, int keys, int attachment) +{ + if (keys & KEY_CTRL) + { + PopupMenu(x, y); + } + /* + else if (keys & KEY_SHIFT) + { + if (m_leftSide || m_topSide || m_rightSide || m_bottomSide) + { + if (Selected()) + { + Select(FALSE); + GetParent()->Draw(dc); + } + else + Select(TRUE); + } + } + */ + else + { + attachment = 0; + double dist; + if (m_parent) + { + m_parent->HitTest(x, y, &attachment, &dist); + m_parent->GetEventHandler()->OnRightClick(x, y, keys, attachment); + } + return; + } +} + + +// Divide wxHORIZONTALly or wxVERTICALly +bool wxDivisionShape::Divide(int direction) +{ + // Calculate existing top-left, bottom-right + double x1 = (double)(GetX() - (GetWidth() / 2.0)); + double y1 = (double)(GetY() - (GetHeight() / 2.0)); + wxCompositeShape *compositeParent = (wxCompositeShape *)GetParent(); + double oldWidth = GetWidth(); + double oldHeight = GetHeight(); + if (Selected()) + Select(FALSE); + + //wxClientDC dc(GetCanvas()); + //GetCanvas()->PrepareDC(dc); + + if (direction == wxVERTICAL) + { + // Dividing vertically means notionally putting a horizontal line through it. + // Break existing piece into two. + double newXPos1 = GetX(); + double newYPos1 = (double)(y1 + (GetHeight() / 4.0)); + double newXPos2 = GetX(); + double newYPos2 = (double)(y1 + (3.0 * GetHeight() / 4.0)); + wxDivisionShape *newDivision = compositeParent->OnCreateDivision(); + newDivision->Show(TRUE); + + // Erase(); + + // Anything adjoining the bottom of this division now adjoins the + // bottom of the new division. + wxNode *node = compositeParent->GetDivisions().GetFirst(); + while (node) + { + wxDivisionShape *obj = (wxDivisionShape *)node->GetData(); + if (obj->GetTopSide() == this) + obj->SetTopSide(newDivision); + node = node->GetNext(); + } + newDivision->SetTopSide(this); + newDivision->SetBottomSide(m_bottomSide); + newDivision->SetLeftSide(m_leftSide); + newDivision->SetRightSide(m_rightSide); + m_bottomSide = newDivision; + + compositeParent->GetDivisions().Append(newDivision); + + // CHANGE: Need to insert this division at start of divisions in the object + // list, because e.g.: + // 1) Add division + // 2) Add contained object + // 3) Add division + // Division is now receiving mouse events _before_ the contained object, + // because it was added last (on top of all others) + + // Add after the image that visualizes the container + compositeParent->AddChild(newDivision, compositeParent->FindContainerImage()); + + m_handleSide = DIVISION_SIDE_BOTTOM; + newDivision->SetHandleSide(DIVISION_SIDE_TOP); + + SetSize(oldWidth, (double)(oldHeight / 2.0)); + Move(newXPos1, newYPos1); + + newDivision->SetSize(oldWidth, (double)(oldHeight / 2.0)); + newDivision->Move(newXPos2, newYPos2); + } + else + { + // Dividing horizontally means notionally putting a vertical line through it. + // Break existing piece into two. + double newXPos1 = (double)(x1 + (GetWidth() / 4.0)); + double newYPos1 = GetY(); + double newXPos2 = (double)(x1 + (3.0 * GetWidth() / 4.0)); + double newYPos2 = GetY(); + wxDivisionShape *newDivision = compositeParent->OnCreateDivision(); + newDivision->Show(TRUE); + + // Erase(dc); + + // Anything adjoining the left of this division now adjoins the + // left of the new division. + wxNode *node = compositeParent->GetDivisions().GetFirst(); + while (node) + { + wxDivisionShape *obj = (wxDivisionShape *)node->GetData(); + if (obj->GetLeftSide() == this) + obj->SetLeftSide(newDivision); + node = node->GetNext(); + } + newDivision->SetTopSide(m_topSide); + newDivision->SetBottomSide(m_bottomSide); + newDivision->SetLeftSide(this); + newDivision->SetRightSide(m_rightSide); + m_rightSide = newDivision; + + compositeParent->GetDivisions().Append(newDivision); + compositeParent->AddChild(newDivision, compositeParent->FindContainerImage()); + + m_handleSide = DIVISION_SIDE_RIGHT; + newDivision->SetHandleSide(DIVISION_SIDE_LEFT); + + SetSize((double)(oldWidth / 2.0), oldHeight); + Move(newXPos1, newYPos1); + + newDivision->SetSize((double)(oldWidth / 2.0), oldHeight); + newDivision->Move(newXPos2, newYPos2); + } + if (compositeParent->Selected()) + { + compositeParent->DeleteControlPoints(); + compositeParent->MakeControlPoints(); + compositeParent->MakeMandatoryControlPoints(); + } + // compositeParent->Draw(dc); + + if (GetCanvas()) + GetCanvas()->Refresh(); + return TRUE; +} + +// Make one control point for every visible line +void wxDivisionShape::MakeControlPoints() +{ + MakeMandatoryControlPoints(); +} + +void wxDivisionShape::MakeMandatoryControlPoints() +{ + double maxX, maxY; + + GetBoundingBoxMax(&maxX, &maxY); + double x = 0.0 , y = 0.0; + int direction = 0; + /* + if (m_leftSide) + { + x = (double)(-maxX/2.0); + y = 0.0; + wxDivisionControlPoint *control = new wxDivisionControlPoint(m_canvas, this, CONTROL_POINT_SIZE, x, y, + CONTROL_POINT_HORIZONTAL); + m_canvas->AddShape(control); + m_controlPoints.Append(control); + } + if (m_topSide) + { + x = 0.0; + y = (double)(-maxY/2.0); + wxDivisionControlPoint *control = new wxDivisionControlPoint(m_canvas, this, CONTROL_POINT_SIZE, x, y, + CONTROL_POINT_VERTICAL); + m_canvas->AddShape(control); + m_controlPoints.Append(control); + } + */ + switch (m_handleSide) + { + case DIVISION_SIDE_LEFT: + { + x = (double)(-maxX / 2.0); + y = 0.0; + direction = CONTROL_POINT_HORIZONTAL; + break; + } + case DIVISION_SIDE_TOP: + { + x = 0.0; + y = (double)(-maxY / 2.0); + direction = CONTROL_POINT_VERTICAL; + break; + } + case DIVISION_SIDE_RIGHT: + { + x = (double)(maxX / 2.0); + y = 0.0; + direction = CONTROL_POINT_HORIZONTAL; + break; + } + case DIVISION_SIDE_BOTTOM: + { + x = 0.0; + y = (double)(maxY / 2.0); + direction = CONTROL_POINT_VERTICAL; + break; + } + default: + break; + } + if (m_handleSide != DIVISION_SIDE_NONE) + { + wxDivisionControlPoint *control = new wxDivisionControlPoint(m_canvas, this, CONTROL_POINT_SIZE, x, y, + direction); + m_canvas->AddShape(control); + m_controlPoints.Append(control); + } +} + +void wxDivisionShape::ResetControlPoints() +{ + ResetMandatoryControlPoints(); +} + +void wxDivisionShape::ResetMandatoryControlPoints() +{ + if (m_controlPoints.GetCount() < 1) + return; + + double maxX, maxY; + + GetBoundingBoxMax(&maxX, &maxY); + /* + wxNode *node = m_controlPoints.GetFirst(); + while (node) + { + wxDivisionControlPoint *control = (wxDivisionControlPoint *)node->GetData(); + if (control->type == CONTROL_POINT_HORIZONTAL) + { + control->xoffset = (double)(-maxX/2.0); control->m_yoffset = 0.0; + } + else if (control->type == CONTROL_POINT_VERTICAL) + { + control->xoffset = 0.0; control->m_yoffset = (double)(-maxY/2.0); + } + node = node->GetNext(); + } + */ + wxNode *node = m_controlPoints.GetFirst(); + if ((m_handleSide == DIVISION_SIDE_LEFT) && node) + { + wxDivisionControlPoint *control = (wxDivisionControlPoint *)node->GetData(); + control->m_xoffset = (double)(-maxX / 2.0); + control->m_yoffset = 0.0; + } + + if ((m_handleSide == DIVISION_SIDE_TOP) && node) + { + wxDivisionControlPoint *control = (wxDivisionControlPoint *)node->GetData(); + control->m_xoffset = 0.0; + control->m_yoffset = (double)(-maxY / 2.0); + } + + if ((m_handleSide == DIVISION_SIDE_RIGHT) && node) + { + wxDivisionControlPoint *control = (wxDivisionControlPoint *)node->GetData(); + control->m_xoffset = (double)(maxX / 2.0); + control->m_yoffset = 0.0; + } + + if ((m_handleSide == DIVISION_SIDE_BOTTOM) && node) + { + wxDivisionControlPoint *control = (wxDivisionControlPoint *)node->GetData(); + control->m_xoffset = 0.0; + control->m_yoffset = (double)(maxY / 2.0); + } +} + +// Adjust a side, returning FALSE if it's not physically possible. +bool wxDivisionShape::AdjustLeft(double left, bool test) +{ + double x2 = (double)(GetX() + (GetWidth() / 2.0)); + + if (left >= x2) + return FALSE; + if (test) + return TRUE; + + double newW = x2 - left; + double newX = (double)(left + newW / 2.0); + SetSize(newW, GetHeight()); + + Move(newX, GetY()); + + if (GetCanvas()) + GetCanvas()->Refresh(); + + return TRUE; +} + +bool wxDivisionShape::AdjustTop(double top, bool test) +{ + double y2 = (double)(GetY() + (GetHeight() / 2.0)); + + if (top >= y2) + return FALSE; + if (test) + return TRUE; + + double newH = y2 - top; + double newY = (double)(top + newH / 2.0); + SetSize(GetWidth(), newH); + + Move(GetX(), newY); + + if (GetCanvas()) + GetCanvas()->Refresh(); + + return TRUE; +} + +bool wxDivisionShape::AdjustRight(double right, bool test) +{ + double x1 = (double)(GetX() - (GetWidth() / 2.0)); + + if (right <= x1) + return FALSE; + if (test) + return TRUE; + + double newW = right - x1; + double newX = (double)(x1 + newW / 2.0); + SetSize(newW, GetHeight()); + + Move(newX, GetY()); + + if (GetCanvas()) + GetCanvas()->Refresh(); + + return TRUE; +} + +bool wxDivisionShape::AdjustBottom(double bottom, bool test) +{ + double y1 = (double)(GetY() - (GetHeight() / 2.0)); + + if (bottom <= y1) + return FALSE; + if (test) + return TRUE; + + double newH = bottom - y1; + double newY = (double)(y1 + newH / 2.0); + SetSize(GetWidth(), newH); + + Move(GetX(), newY); + + if (GetCanvas()) + GetCanvas()->Refresh(); + + return TRUE; +} + +wxDivisionControlPoint::wxDivisionControlPoint(wxShapeCanvas *the_canvas, wxShape *object, double size, double the_xoffset, double the_yoffset, int the_type): + wxControlPoint(the_canvas, object, size, the_xoffset, the_yoffset, the_type) +{ + SetEraseObject(FALSE); +} + +wxDivisionControlPoint::~wxDivisionControlPoint() +{ +} + +static double originalX = 0.0; +static double originalY = 0.0; +static double originalW = 0.0; +static double originalH = 0.0; + +// Implement resizing of canvas object +void wxDivisionControlPoint::OnDragLeft(bool draw, double x, double y, int keys, int attachment) +{ + wxControlPoint::OnDragLeft(draw, x, y, keys, attachment); +} + +void wxDivisionControlPoint::OnBeginDragLeft(double x, double y, int keys, int attachment) +{ + wxDivisionShape *division = (wxDivisionShape *)m_shape; + originalX = division->GetX(); + originalY = division->GetY(); + originalW = division->GetWidth(); + originalH = division->GetHeight(); + + wxControlPoint::OnBeginDragLeft(x, y, keys, attachment); +} + +void wxDivisionControlPoint::OnEndDragLeft(double x, double y, int keys, int attachment) +{ + wxControlPoint::OnEndDragLeft(x, y, keys, attachment); + + wxDivisionShape *division = (wxDivisionShape *)m_shape; + wxCompositeShape *divisionParent = (wxCompositeShape *)division->GetParent(); + + // Need to check it's within the bounds of the parent composite. + double x1 = (double)(divisionParent->GetX() - (divisionParent->GetWidth() / 2.0)); + double y1 = (double)(divisionParent->GetY() - (divisionParent->GetHeight() / 2.0)); + double x2 = (double)(divisionParent->GetX() + (divisionParent->GetWidth() / 2.0)); + double y2 = (double)(divisionParent->GetY() + (divisionParent->GetHeight() / 2.0)); + + // Need to check it has not made the division zero or negative width/height + double dx1 = (double)(division->GetX() - (division->GetWidth() / 2.0)); + double dy1 = (double)(division->GetY() - (division->GetHeight() / 2.0)); + double dx2 = (double)(division->GetX() + (division->GetWidth() / 2.0)); + double dy2 = (double)(division->GetY() + (division->GetHeight() / 2.0)); + + bool success = TRUE; + switch (division->GetHandleSide()) + { + case DIVISION_SIDE_LEFT: + { + if ((x <= x1) || (x >= x2) || (x >= dx2)) + success = FALSE; + // Try it out first... + else if (!division->ResizeAdjoining(DIVISION_SIDE_LEFT, x, TRUE)) + success = FALSE; + else + division->ResizeAdjoining(DIVISION_SIDE_LEFT, x, FALSE); + + break; + } + case DIVISION_SIDE_TOP: + { + if ((y <= y1) || (y >= y2) || (y >= dy2)) + success = FALSE; + else if (!division->ResizeAdjoining(DIVISION_SIDE_TOP, y, TRUE)) + success = FALSE; + else + division->ResizeAdjoining(DIVISION_SIDE_TOP, y, FALSE); + + break; + } + case DIVISION_SIDE_RIGHT: + { + if ((x <= x1) || (x >= x2) || (x <= dx1)) + success = FALSE; + else if (!division->ResizeAdjoining(DIVISION_SIDE_RIGHT, x, TRUE)) + success = FALSE; + else + division->ResizeAdjoining(DIVISION_SIDE_RIGHT, x, FALSE); + + break; + } + case DIVISION_SIDE_BOTTOM: + { + if ((y <= y1) || (y >= y2) || (y <= dy1)) + success = FALSE; + else if (!division->ResizeAdjoining(DIVISION_SIDE_BOTTOM, y, TRUE)) + success = FALSE; + else + division->ResizeAdjoining(DIVISION_SIDE_BOTTOM, y, FALSE); + + break; + } + } + if (!success) + { + division->SetSize(originalW, originalH); + division->Move(originalX, originalY); + } + + if (GetCanvas()) + GetCanvas()->Refresh(); + +} + +/* Resize adjoining divisions. + * + Behaviour should be as follows: + If right edge moves, find all objects whose left edge + adjoins this object, and move left edge accordingly. + If left..., move ... right. + If top..., move ... bottom. + If bottom..., move top. + If size goes to zero or end position is other side of start position, + resize to original size and return. + */ +bool wxDivisionShape::ResizeAdjoining(int side, double newPos, bool test) +{ + wxCompositeShape *divisionParent = (wxCompositeShape *)GetParent(); + wxNode *node = divisionParent->GetDivisions().GetFirst(); + while (node) + { + wxDivisionShape *division = (wxDivisionShape *)node->GetData(); + switch (side) + { + case DIVISION_SIDE_LEFT: + { + if (division->m_rightSide == this) + { + bool success = division->AdjustRight(newPos, test); + if (!success && test) + return FALSE; + } + break; + } + case DIVISION_SIDE_TOP: + { + if (division->m_bottomSide == this) + { + bool success = division->AdjustBottom(newPos, test); + if (!success && test) + return FALSE; + } + break; + } + case DIVISION_SIDE_RIGHT: + { + if (division->m_leftSide == this) + { + bool success = division->AdjustLeft(newPos, test); + if (!success && test) + return FALSE; + } + break; + } + case DIVISION_SIDE_BOTTOM: + { + if (division->m_topSide == this) + { + bool success = division->AdjustTop(newPos, test); + if (!success && test) + return FALSE; + } + break; + } + default: + break; + } + node = node->GetNext(); + } + + return TRUE; +} + +/* + * Popup menu for editing divisions + * + */ +class OGLPopupDivisionMenu : public wxMenu +{ +public: + OGLPopupDivisionMenu() : wxMenu() + { + Append(DIVISION_MENU_SPLIT_HORIZONTALLY, wxT("Split horizontally")); + Append(DIVISION_MENU_SPLIT_VERTICALLY, wxT("Split vertically")); + AppendSeparator(); + Append(DIVISION_MENU_EDIT_LEFT_EDGE, wxT("Edit left edge")); + Append(DIVISION_MENU_EDIT_TOP_EDGE, wxT("Edit top edge")); + } + + void OnMenu(wxCommandEvent &event); + + DECLARE_EVENT_TABLE() +}; + +BEGIN_EVENT_TABLE(OGLPopupDivisionMenu, wxMenu) + EVT_MENU_RANGE(DIVISION_MENU_SPLIT_HORIZONTALLY, + DIVISION_MENU_EDIT_BOTTOM_EDGE, + OGLPopupDivisionMenu::OnMenu) +END_EVENT_TABLE() + + +void OGLPopupDivisionMenu::OnMenu(wxCommandEvent &event) +{ + wxDivisionShape *division = (wxDivisionShape *)GetClientData(); + switch (event.GetInt()) + { + case DIVISION_MENU_SPLIT_HORIZONTALLY: + { + division->Divide(wxHORIZONTAL); + break; + } + case DIVISION_MENU_SPLIT_VERTICALLY: + { + division->Divide(wxVERTICAL); + break; + } + case DIVISION_MENU_EDIT_LEFT_EDGE: + { + division->EditEdge(DIVISION_SIDE_LEFT); + break; + } + case DIVISION_MENU_EDIT_TOP_EDGE: + { + division->EditEdge(DIVISION_SIDE_TOP); + break; + } + default: + break; + } +} + +void wxDivisionShape::EditEdge(int WXUNUSED(side)) +{ + wxMessageBox(wxT("EditEdge() not implemented"), wxT("OGL"), wxOK); + +#if 0 + wxBeginBusyCursor(); + + wxPen *currentPen = NULL; + char **pColour = NULL; + char **pStyle = NULL; + if (side == DIVISION_SIDE_LEFT) + { + currentPen = m_leftSidePen; + pColour = &m_leftSideColour; + pStyle = &m_leftSideStyle; + } + else + { + currentPen = m_topSidePen; + pColour = &m_topSideColour; + pStyle = &m_topSideStyle; + } + + GraphicsForm *form = new GraphicsForm("Containers"); + int lineWidth = currentPen->GetWidth(); + + form->Add(wxMakeFormShort("Width", &lineWidth, wxFORM_DEFAULT, NULL, NULL, wxVERTICAL, + 150)); + form->Add(wxMakeFormString("Colour", pColour, wxFORM_CHOICE, + new wxList(wxMakeConstraintStrings( + "BLACK" , + "BLUE" , + "BROWN" , + "CORAL" , + "CYAN" , + "DARK GREY" , + "DARK GREEN" , + "DIM GREY" , + "GREY" , + "GREEN" , + "LIGHT BLUE" , + "LIGHT GREY" , + "MAGENTA" , + "MAROON" , + "NAVY" , + "ORANGE" , + "PURPLE" , + "RED" , + "TURQUOISE" , + "VIOLET" , + "WHITE" , + "YELLOW" , + NULL), + NULL), NULL, wxVERTICAL, 150)); + form->Add(wxMakeFormString("Style", pStyle, wxFORM_CHOICE, + new wxList(wxMakeConstraintStrings( + "Solid" , + "Short Dash" , + "Long Dash" , + "Dot" , + "Dot Dash" , + NULL), + NULL), NULL, wxVERTICAL, 100)); + + wxDialogBox *dialog = new wxDialogBox(m_canvas->GetParent(), "Division properties", 10, 10, 500, 500); + if (GraphicsLabelFont) + dialog->SetLabelFont(GraphicsLabelFont); + if (GraphicsButtonFont) + dialog->SetButtonFont(GraphicsButtonFont); + + form->AssociatePanel(dialog); + form->dialog = dialog; + + dialog->Fit(); + dialog->Centre(wxBOTH); + + wxEndBusyCursor(); + dialog->Show(TRUE); + + int lineStyle = wxSOLID; + if (*pStyle) + { + if (strcmp(*pStyle, "Solid") == 0) + lineStyle = wxSOLID; + else if (strcmp(*pStyle, "Dot") == 0) + lineStyle = wxDOT; + else if (strcmp(*pStyle, "Short Dash") == 0) + lineStyle = wxSHORT_DASH; + else if (strcmp(*pStyle, "Long Dash") == 0) + lineStyle = wxLONG_DASH; + else if (strcmp(*pStyle, "Dot Dash") == 0) + lineStyle = wxDOT_DASH; + } + + wxPen *newPen = wxThePenList->FindOrCreatePen(*pColour, lineWidth, lineStyle); + if (!pen) + pen = wxBLACK_PEN; + if (side == DIVISION_SIDE_LEFT) + m_leftSidePen = newPen; + else + m_topSidePen = newPen; + + // Need to draw whole image again + wxCompositeShape *compositeParent = (wxCompositeShape *)GetParent(); + compositeParent->Draw(dc); +#endif +} + +// Popup menu +void wxDivisionShape::PopupMenu(double x, double y) +{ + wxMenu *oglPopupDivisionMenu = new OGLPopupDivisionMenu; + + oglPopupDivisionMenu->SetClientData((void *)this); + if (m_leftSide) + oglPopupDivisionMenu->Enable(DIVISION_MENU_EDIT_LEFT_EDGE, TRUE); + else + oglPopupDivisionMenu->Enable(DIVISION_MENU_EDIT_LEFT_EDGE, FALSE); + if (m_topSide) + oglPopupDivisionMenu->Enable(DIVISION_MENU_EDIT_TOP_EDGE, TRUE); + else + oglPopupDivisionMenu->Enable(DIVISION_MENU_EDIT_TOP_EDGE, FALSE); + + int x1, y1; + m_canvas->GetViewStart(&x1, &y1); + + int unit_x, unit_y; + m_canvas->GetScrollPixelsPerUnit(&unit_x, &unit_y); + + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + int mouse_x = (int)(dc.LogicalToDeviceX((long)(x - x1 * unit_x))); + int mouse_y = (int)(dc.LogicalToDeviceY((long)(y - y1 * unit_y))); + + m_canvas->PopupMenu(oglPopupDivisionMenu, mouse_x, mouse_y); + delete oglPopupDivisionMenu; +} + +void wxDivisionShape::SetLeftSideColour(const wxString &colour) +{ + m_leftSideColour = colour; +} + +void wxDivisionShape::SetTopSideColour(const wxString &colour) +{ + m_topSideColour = colour; +} + +void wxDivisionShape::SetLeftSideStyle(const wxString &style) +{ + m_leftSideStyle = style; +} + +void wxDivisionShape::SetTopSideStyle(const wxString &style) +{ + m_topSideStyle = style; +} + diff --git a/ogl/constrnt.cpp b/ogl/constrnt.cpp new file mode 100644 index 0000000..0d90461 --- /dev/null +++ b/ogl/constrnt.cpp @@ -0,0 +1,606 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// constrnt.cpp - OGL Constraint classes +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include "ogl/ogl.h" + + +wxList *wxOGLConstraintTypes = NULL; + +/* + * Constraint type + * + */ + +IMPLEMENT_DYNAMIC_CLASS(wxOGLConstraintType, wxObject) + +wxOGLConstraintType::wxOGLConstraintType(int theType, const wxString &theName, const wxString &thePhrase) +{ + m_type = theType; + m_name = theName; + m_phrase = thePhrase; +} + +wxOGLConstraintType::~wxOGLConstraintType() +{ +} + +void OGLInitializeConstraintTypes() +{ + if (!wxOGLConstraintTypes) + return; + + wxOGLConstraintTypes = new wxList(wxKEY_INTEGER); + + wxOGLConstraintTypes->Append(gyCONSTRAINT_CENTRED_VERTICALLY, + new wxOGLConstraintType(gyCONSTRAINT_CENTRED_VERTICALLY, wxT("Centre vertically"), wxT("centred vertically w.r.t."))); + + wxOGLConstraintTypes->Append(gyCONSTRAINT_CENTRED_HORIZONTALLY, + new wxOGLConstraintType(gyCONSTRAINT_CENTRED_HORIZONTALLY, wxT("Centre horizontally"), wxT("centred horizontally w.r.t."))); + + wxOGLConstraintTypes->Append(gyCONSTRAINT_CENTRED_BOTH, + new wxOGLConstraintType(gyCONSTRAINT_CENTRED_BOTH, wxT("Centre"), wxT("centred w.r.t."))); + + wxOGLConstraintTypes->Append(gyCONSTRAINT_LEFT_OF, + new wxOGLConstraintType(gyCONSTRAINT_LEFT_OF, wxT("Left of"), wxT("left of"))); + + wxOGLConstraintTypes->Append(gyCONSTRAINT_RIGHT_OF, + new wxOGLConstraintType(gyCONSTRAINT_RIGHT_OF, wxT("Right of"), wxT("right of"))); + + wxOGLConstraintTypes->Append(gyCONSTRAINT_ABOVE, + new wxOGLConstraintType(gyCONSTRAINT_ABOVE, wxT("Above"), wxT("above"))); + + wxOGLConstraintTypes->Append(gyCONSTRAINT_BELOW, + new wxOGLConstraintType(gyCONSTRAINT_BELOW, wxT("Below"), wxT("below"))); + + // Alignment + wxOGLConstraintTypes->Append(gyCONSTRAINT_ALIGNED_TOP, + new wxOGLConstraintType(gyCONSTRAINT_ALIGNED_TOP, wxT("Top-aligned"), wxT("aligned to the top of"))); + + wxOGLConstraintTypes->Append(gyCONSTRAINT_ALIGNED_BOTTOM, + new wxOGLConstraintType(gyCONSTRAINT_ALIGNED_BOTTOM, wxT("Bottom-aligned"), wxT("aligned to the bottom of"))); + + wxOGLConstraintTypes->Append(gyCONSTRAINT_ALIGNED_LEFT, + new wxOGLConstraintType(gyCONSTRAINT_ALIGNED_LEFT, wxT("Left-aligned"), wxT("aligned to the left of"))); + + wxOGLConstraintTypes->Append(gyCONSTRAINT_ALIGNED_RIGHT, + new wxOGLConstraintType(gyCONSTRAINT_ALIGNED_RIGHT, wxT("Right-aligned"), wxT("aligned to the right of"))); + + // Mid-alignment + wxOGLConstraintTypes->Append(gyCONSTRAINT_MIDALIGNED_TOP, + new wxOGLConstraintType(gyCONSTRAINT_MIDALIGNED_TOP, wxT("Top-midaligned"), wxT("centred on the top of"))); + + wxOGLConstraintTypes->Append(gyCONSTRAINT_MIDALIGNED_BOTTOM, + new wxOGLConstraintType(gyCONSTRAINT_MIDALIGNED_BOTTOM, wxT("Bottom-midaligned"), wxT("centred on the bottom of"))); + + wxOGLConstraintTypes->Append(gyCONSTRAINT_MIDALIGNED_LEFT, + new wxOGLConstraintType(gyCONSTRAINT_MIDALIGNED_LEFT, wxT("Left-midaligned"), wxT("centred on the left of"))); + + wxOGLConstraintTypes->Append(gyCONSTRAINT_MIDALIGNED_RIGHT, + new wxOGLConstraintType(gyCONSTRAINT_MIDALIGNED_RIGHT, wxT("Right-midaligned"), wxT("centred on the right of"))); +} + +void OGLCleanUpConstraintTypes() +{ + if (!wxOGLConstraintTypes) + return; + + wxNode *node = wxOGLConstraintTypes->GetFirst(); + while (node) + { + wxOGLConstraintType *ct = (wxOGLConstraintType *) node->GetData(); + delete ct; + node = node->GetNext(); + } + delete wxOGLConstraintTypes; + wxOGLConstraintTypes = NULL; +} + +/* + * Constraint Stuff + * + */ + +IMPLEMENT_DYNAMIC_CLASS(wxOGLConstraint, wxObject) + +wxOGLConstraint::wxOGLConstraint(int type, wxShape *constraining, wxList &constrained) +{ + m_xSpacing = 0.0; + m_ySpacing = 0.0; + + m_constraintType = type; + m_constrainingObject = constraining; + + m_constraintId = 0; + m_constraintName = wxT("noname"); + + wxNode *node = constrained.GetFirst(); + while (node) + { + m_constrainedObjects.Append(node->GetData()); + node = node->GetNext(); + } +} + +wxOGLConstraint::~wxOGLConstraint() +{ +} + +bool wxOGLConstraint::Equals(double a, double b) +{ + double marg = 0.5; + + bool eq = ((b <= a + marg) && (b >= a - marg)); + return eq; +} + +// Return TRUE if anything changed +bool wxOGLConstraint::Evaluate() +{ + double maxWidth, maxHeight, minWidth, minHeight, x, y; + m_constrainingObject->GetBoundingBoxMax(&maxWidth, &maxHeight); + m_constrainingObject->GetBoundingBoxMin(&minWidth, &minHeight); + x = m_constrainingObject->GetX(); + y = m_constrainingObject->GetY(); + + switch (m_constraintType) + { + case gyCONSTRAINT_CENTRED_VERTICALLY: + { + int n = m_constrainedObjects.GetCount(); + double totalObjectHeight = 0.0; + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double width2, height2; + constrainedObject->GetBoundingBoxMax(&width2, &height2); + totalObjectHeight += height2; + node = node->GetNext(); + } + double startY; + double spacingY; + // Check if within the constraining object... + if ((totalObjectHeight + (n + 1)*m_ySpacing) <= minHeight) + { + spacingY = (double)((minHeight - totalObjectHeight) / (n + 1)); + startY = (double)(y - (minHeight / 2.0)); + } + // Otherwise, use default spacing + else + { + spacingY = m_ySpacing; + startY = (double)(y - ((totalObjectHeight + (n + 1) * spacingY) / 2.0)); + } + + // Now position the objects + bool changed = FALSE; + node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + double width2, height2; + constrainedObject->GetBoundingBoxMax(&width2, &height2); + startY += (double)(spacingY + (height2 / 2.0)); + if (!Equals(startY, constrainedObject->GetY())) + { + constrainedObject->Move(constrainedObject->GetX(), startY, FALSE); + changed = TRUE; + } + startY += (double)(height2 / 2.0); + node = node->GetNext(); + } + return changed; + } + case gyCONSTRAINT_CENTRED_HORIZONTALLY: + { + int n = m_constrainedObjects.GetCount(); + double totalObjectWidth = 0.0; + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double width2, height2; + constrainedObject->GetBoundingBoxMax(&width2, &height2); + totalObjectWidth += width2; + node = node->GetNext(); + } + double startX; + double spacingX; + // Check if within the constraining object... + if ((totalObjectWidth + (n + 1)*m_xSpacing) <= minWidth) + { + spacingX = (double)((minWidth - totalObjectWidth) / (n + 1)); + startX = (double)(x - (minWidth / 2.0)); + } + // Otherwise, use default spacing + else + { + spacingX = m_xSpacing; + startX = (double)(x - ((totalObjectWidth + (n + 1) * spacingX) / 2.0)); + } + + // Now position the objects + bool changed = FALSE; + node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + double width2, height2; + constrainedObject->GetBoundingBoxMax(&width2, &height2); + startX += (double)(spacingX + (width2 / 2.0)); + if (!Equals(startX, constrainedObject->GetX())) + { + constrainedObject->Move(startX, constrainedObject->GetY(), FALSE); + changed = TRUE; + } + startX += (double)(width2 / 2.0); + node = node->GetNext(); + } + return changed; + } + case gyCONSTRAINT_CENTRED_BOTH: + { + int n = m_constrainedObjects.GetCount(); + double totalObjectWidth = 0.0; + double totalObjectHeight = 0.0; + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double width2, height2; + constrainedObject->GetBoundingBoxMax(&width2, &height2); + totalObjectWidth += width2; + totalObjectHeight += height2; + node = node->GetNext(); + } + double startX; + double spacingX; + double startY; + double spacingY; + + // Check if within the constraining object... + if ((totalObjectWidth + (n + 1)*m_xSpacing) <= minWidth) + { + spacingX = (double)((minWidth - totalObjectWidth) / (n + 1)); + startX = (double)(x - (minWidth / 2.0)); + } + // Otherwise, use default spacing + else + { + spacingX = m_xSpacing; + startX = (double)(x - ((totalObjectWidth + (n + 1) * spacingX) / 2.0)); + } + + // Check if within the constraining object... + if ((totalObjectHeight + (n + 1)*m_ySpacing) <= minHeight) + { + spacingY = (double)((minHeight - totalObjectHeight) / (n + 1)); + startY = (double)(y - (minHeight / 2.0)); + } + // Otherwise, use default spacing + else + { + spacingY = m_ySpacing; + startY = (double)(y - ((totalObjectHeight + (n + 1) * spacingY) / 2.0)); + } + + // Now position the objects + bool changed = FALSE; + node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + double width2, height2; + constrainedObject->GetBoundingBoxMax(&width2, &height2); + startX += (double)(spacingX + (width2 / 2.0)); + startY += (double)(spacingY + (height2 / 2.0)); + + if ((!Equals(startX, constrainedObject->GetX())) || (!Equals(startY, constrainedObject->GetY()))) + { + constrainedObject->Move(startX, startY, FALSE); + changed = TRUE; + } + + startX += (double)(width2 / 2.0); + startY += (double)(height2 / 2.0); + + node = node->GetNext(); + } + return changed; + } + case gyCONSTRAINT_LEFT_OF: + { + bool changed = FALSE; + + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double width2, height2; + constrainedObject->GetBoundingBoxMax(&width2, &height2); + + double x3 = (double)(x - (minWidth / 2.0) - (width2 / 2.0) - m_xSpacing); + if (!Equals(x3, constrainedObject->GetX())) + { + changed = TRUE; + constrainedObject->Move(x3, constrainedObject->GetY(), FALSE); + } + + node = node->GetNext(); + } + return changed; + } + case gyCONSTRAINT_RIGHT_OF: + { + bool changed = FALSE; + + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double width2, height2; + constrainedObject->GetBoundingBoxMax(&width2, &height2); + + double x3 = (double)(x + (minWidth / 2.0) + (width2 / 2.0) + m_xSpacing); + if (!Equals(x3, constrainedObject->GetX())) + { + changed = TRUE; + constrainedObject->Move(x3, constrainedObject->GetY(), FALSE); + } + + node = node->GetNext(); + } + return changed; + } + case gyCONSTRAINT_ABOVE: + { + bool changed = FALSE; + + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double width2, height2; + constrainedObject->GetBoundingBoxMax(&width2, &height2); + + double y3 = (double)(y - (minHeight / 2.0) - (height2 / 2.0) - m_ySpacing); + if (!Equals(y3, constrainedObject->GetY())) + { + changed = TRUE; + constrainedObject->Move(constrainedObject->GetX(), y3, FALSE); + } + + node = node->GetNext(); + } + return changed; + } + case gyCONSTRAINT_BELOW: + { + bool changed = FALSE; + + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double width2, height2; + constrainedObject->GetBoundingBoxMax(&width2, &height2); + + double y3 = (double)(y + (minHeight / 2.0) + (height2 / 2.0) + m_ySpacing); + if (!Equals(y3, constrainedObject->GetY())) + { + changed = TRUE; + constrainedObject->Move(constrainedObject->GetX(), y3, FALSE); + } + + node = node->GetNext(); + } + return changed; + } + case gyCONSTRAINT_ALIGNED_LEFT: + { + bool changed = FALSE; + + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double width2, height2; + constrainedObject->GetBoundingBoxMax(&width2, &height2); + + double x3 = (double)(x - (minWidth / 2.0) + (width2 / 2.0) + m_xSpacing); + if (!Equals(x3, constrainedObject->GetX())) + { + changed = TRUE; + constrainedObject->Move(x3, constrainedObject->GetY(), FALSE); + } + + node = node->GetNext(); + } + return changed; + } + case gyCONSTRAINT_ALIGNED_RIGHT: + { + bool changed = FALSE; + + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double width2, height2; + constrainedObject->GetBoundingBoxMax(&width2, &height2); + + double x3 = (double)(x + (minWidth / 2.0) - (width2 / 2.0) - m_xSpacing); + if (!Equals(x3, constrainedObject->GetX())) + { + changed = TRUE; + constrainedObject->Move(x3, constrainedObject->GetY(), FALSE); + } + + node = node->GetNext(); + } + return changed; +#if 0 + // two returned values ? + return FALSE; +#endif + } + case gyCONSTRAINT_ALIGNED_TOP: + { + bool changed = FALSE; + + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double width2, height2; + constrainedObject->GetBoundingBoxMax(&width2, &height2); + + double y3 = (double)(y - (minHeight / 2.0) + (height2 / 2.0) + m_ySpacing); + if (!Equals(y3, constrainedObject->GetY())) + { + changed = TRUE; + constrainedObject->Move(constrainedObject->GetX(), y3, FALSE); + } + + node = node->GetNext(); + } + return changed; + } + case gyCONSTRAINT_ALIGNED_BOTTOM: + { + bool changed = FALSE; + + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double width2, height2; + constrainedObject->GetBoundingBoxMax(&width2, &height2); + + double y3 = (double)(y + (minHeight / 2.0) - (height2 / 2.0) - m_ySpacing); + if (!Equals(y3, constrainedObject->GetY())) + { + changed = TRUE; + constrainedObject->Move(constrainedObject->GetX(), y3, FALSE); + } + + node = node->GetNext(); + } + return changed; + } + case gyCONSTRAINT_MIDALIGNED_LEFT: + { + bool changed = FALSE; + + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double x3 = (double)(x - (minWidth / 2.0)); + if (!Equals(x3, constrainedObject->GetX())) + { + changed = TRUE; + constrainedObject->Move(x3, constrainedObject->GetY(), FALSE); + } + + node = node->GetNext(); + } + return changed; + } + case gyCONSTRAINT_MIDALIGNED_RIGHT: + { + bool changed = FALSE; + + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double x3 = (double)(x + (minWidth / 2.0)); + if (!Equals(x3, constrainedObject->GetX())) + { + changed = TRUE; + constrainedObject->Move(x3, constrainedObject->GetY(), FALSE); + } + + node = node->GetNext(); + } + return changed; +#if 0 + // two returned values ? + return FALSE; +#endif + } + case gyCONSTRAINT_MIDALIGNED_TOP: + { + bool changed = FALSE; + + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double y3 = (double)(y - (minHeight / 2.0)); + if (!Equals(y3, constrainedObject->GetY())) + { + changed = TRUE; + constrainedObject->Move(constrainedObject->GetX(), y3, FALSE); + } + + node = node->GetNext(); + } + return changed; + } + case gyCONSTRAINT_MIDALIGNED_BOTTOM: + { + bool changed = FALSE; + + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double y3 = (double)(y + (minHeight / 2.0)); + if (!Equals(y3, constrainedObject->GetY())) + { + changed = TRUE; + constrainedObject->Move(constrainedObject->GetX(), y3, FALSE); + } + + node = node->GetNext(); + } + return changed; + } +#if 0 + // default value handled in main function body + default: + return FALSE; +#endif + } + + return FALSE; +} + diff --git a/ogl/divided.cpp b/ogl/divided.cpp new file mode 100644 index 0000000..a141cee --- /dev/null +++ b/ogl/divided.cpp @@ -0,0 +1,714 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// divided.cpp - wxDividedShape class +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include "ogl/ogl.h" + +static wxChar * +oglCopystring (const wxChar *s) +{ + if (s == NULL) s = wxEmptyString; + size_t len = wxStrlen (s) + 1; + + wxChar *news = new wxChar[len]; + memcpy (news, s, len * sizeof(wxChar)); // Should be the fastest + + return news; +} + +class wxDividedShapeControlPoint: public wxControlPoint +{ + DECLARE_DYNAMIC_CLASS(wxDividedShapeControlPoint) +private: + int regionId; +public: + wxDividedShapeControlPoint() + { + regionId = 0; + } + wxDividedShapeControlPoint(wxShapeCanvas *the_canvas, wxShape *object, int region, + double size, double the_xoffset, double the_yoffset, int the_type); + ~wxDividedShapeControlPoint(); + + void OnDragLeft(bool draw, double x, double y, int keys = 0, int attachment = 0); + void OnBeginDragLeft(double x, double y, int keys = 0, int attachment = 0); + void OnEndDragLeft(double x, double y, int keys = 0, int attachment = 0); +}; + +IMPLEMENT_DYNAMIC_CLASS(wxDividedShapeControlPoint, wxControlPoint) + +/* + * Divided object + * + */ + +IMPLEMENT_DYNAMIC_CLASS(wxDividedShape, wxRectangleShape) + +wxDividedShape::wxDividedShape(double w, double h): wxRectangleShape(w, h) +{ + ClearRegions(); +} + +wxDividedShape::~wxDividedShape() +{ +} + +void wxDividedShape::OnDraw(wxDC &dc) +{ + wxRectangleShape::OnDraw(dc); +} + +void wxDividedShape::OnDrawContents(wxDC &dc) +{ + double defaultProportion = (double)(GetRegions().GetCount() > 0 ? (1.0 / ((double)(GetRegions().GetCount()))) : 0.0); + double currentY = (double)(m_ypos - (m_height / 2.0)); + double maxY = (double)(m_ypos + (m_height / 2.0)); + + double leftX = (double)(m_xpos - (m_width / 2.0)); + double rightX = (double)(m_xpos + (m_width / 2.0)); + + if (m_pen) dc.SetPen(* m_pen); + + if (m_textColour.IsOk()) dc.SetTextForeground(m_textColour); + +#ifdef __WXMSW__ + // For efficiency, don't do this under X - doesn't make + // any visible difference for our purposes. + if (m_brush) + dc.SetTextBackground(m_brush->GetColour()); +#endif + /* + if (!formatted) + { + FormatRegionText(); + formatted = TRUE; + } + */ + if (GetDisableLabel()) return; + + double xMargin = 2; + double yMargin = 2; + dc.SetBackgroundMode(wxTRANSPARENT); + + wxNode *node = GetRegions().GetFirst(); + while (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + dc.SetFont(* region->GetFont()); + dc.SetTextForeground(region->GetActualColourObject()); + + double proportion = + region->m_regionProportionY < 0.0 ? defaultProportion : region->m_regionProportionY; + + double y = currentY + m_height * proportion; + double actualY = maxY < y ? maxY : y; + + double centreX = m_xpos; + double centreY = (double)(currentY + (actualY - currentY) / 2.0); + + oglDrawFormattedText(dc, ®ion->m_formattedText, + (double)(centreX), (double)(centreY), (double)(m_width - 2 * xMargin), (double)(actualY - currentY - 2 * yMargin), + region->m_formatMode); + if ((y <= maxY) && (node->GetNext())) + { + wxPen *regionPen = region->GetActualPen(); + if (regionPen) + { + dc.SetPen(* regionPen); + dc.DrawLine(WXROUND(leftX), WXROUND(y), WXROUND(rightX), WXROUND(y)); + } + } + + currentY = actualY; + + node = node->GetNext(); + } +} + +void wxDividedShape::SetSize(double w, double h, bool WXUNUSED(recursive)) +{ + SetAttachmentSize(w, h); + m_width = w; + m_height = h; + SetRegionSizes(); +} + +void wxDividedShape::SetRegionSizes() +{ + if (GetRegions().GetCount() == 0) + return; + + double defaultProportion = (double)(GetRegions().GetCount() > 0 ? (1.0 / ((double)(GetRegions().GetCount()))) : 0.0); + double currentY = (double)(m_ypos - (m_height / 2.0)); + double maxY = (double)(m_ypos + (m_height / 2.0)); + +// double leftX = (double)(m_xpos - (m_width / 2.0)); +// double rightX = (double)(m_xpos + (m_width / 2.0)); + + wxNode *node = GetRegions().GetFirst(); + while (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + double proportion = + region->m_regionProportionY <= 0.0 ? defaultProportion : region->m_regionProportionY; + + double sizeY = (double)proportion * m_height; + double y = currentY + sizeY; + double actualY = maxY < y ? maxY : y; + + double centreY = (double)(currentY + (actualY - currentY) / 2.0); + + region->SetSize(m_width, sizeY); + region->SetPosition(0.0, (double)(centreY - m_ypos)); + currentY = actualY; + node = node->GetNext(); + } +} + +// Attachment points correspond to regions in the divided box +bool wxDividedShape::GetAttachmentPosition(int attachment, double *x, double *y, int nth, int no_arcs, + wxLineShape *line) +{ + int totalNumberAttachments = (GetRegions().GetCount() * 2) + 2; + if ((GetAttachmentMode() == ATTACHMENT_MODE_NONE) || (attachment >= totalNumberAttachments)) + { + return wxShape::GetAttachmentPosition(attachment, x, y, nth, no_arcs); + } + + int n = GetRegions().GetCount(); + bool isEnd = (line && line->IsEnd(this)); + + double left = (double)(m_xpos - m_width / 2.0); + double right = (double)(m_xpos + m_width / 2.0); + double top = (double)(m_ypos - m_height / 2.0); + double bottom = (double)(m_ypos + m_height / 2.0); + + // Zero is top, n+1 is bottom. + if (attachment == 0) + { + *y = top; + if (m_spaceAttachments) + { + if (line && (line->GetAlignmentType(isEnd) == LINE_ALIGNMENT_TO_NEXT_HANDLE)) + { + // Align line according to the next handle along + wxRealPoint *point = line->GetNextControlPoint(this); + if (point->x < left) + *x = left; + else if (point->x > right) + *x = right; + else + *x = point->x; + } + else + *x = left + (nth + 1) * m_width / (no_arcs + 1); + } + else + *x = m_xpos; + } + else if (attachment == (n + 1)) + { + *y = bottom; + if (m_spaceAttachments) + { + if (line && (line->GetAlignmentType(isEnd) == LINE_ALIGNMENT_TO_NEXT_HANDLE)) + { + // Align line according to the next handle along + wxRealPoint *point = line->GetNextControlPoint(this); + if (point->x < left) + *x = left; + else if (point->x > right) + *x = right; + else + *x = point->x; + } + else + *x = left + (nth + 1) * m_width / (no_arcs + 1); + } + else + *x = m_xpos; + } + // Left or right. + else + { + bool isLeft = !(attachment < (n + 1)); + int i = (isLeft) ? (totalNumberAttachments - attachment - 1) : (attachment - 1); + wxNode *node = GetRegions().Item(i); + if (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + + if (isLeft) + *x = left; + else + *x = right; + + // Calculate top and bottom of region + top = (double)((m_ypos + region->m_y) - (region->m_height / 2.0)); + bottom = (double)((m_ypos + region->m_y) + (region->m_height / 2.0)); + + // Assuming we can trust the absolute size and + // position of these regions... + if (m_spaceAttachments) + { + if (line && (line->GetAlignmentType(isEnd) == LINE_ALIGNMENT_TO_NEXT_HANDLE)) + { + // Align line according to the next handle along + wxRealPoint *point = line->GetNextControlPoint(this); + if (point->y < bottom) + *y = bottom; + else if (point->y > top) + *y = top; + else + *y = point->y; + } + else +// *y = (double)(((m_ypos + region->m_y) - (region->m_height/2.0)) + (nth + 1)*region->m_height/(no_arcs+1)); + *y = (double)(top + (nth + 1) * region->m_height / (no_arcs + 1)); + } + else + *y = (double)(m_ypos + region->m_y); + } + else + { + *x = m_xpos; + *y = m_ypos; + return FALSE; + } + } + return TRUE; +} + +int wxDividedShape::GetNumberOfAttachments() const +{ + // There are two attachments for each region (left and right), + // plus one on the top and one on the bottom. + int n = (GetRegions().GetCount() * 2) + 2; + + int maxN = n - 1; + wxNode *node = m_attachmentPoints.GetFirst(); + while (node) + { + wxAttachmentPoint *point = (wxAttachmentPoint *)node->GetData(); + if (point->m_id > maxN) + maxN = point->m_id; + node = node->GetNext(); + } + return maxN + 1; +} + +bool wxDividedShape::AttachmentIsValid(int attachment) const +{ + int totalNumberAttachments = (GetRegions().GetCount() * 2) + 2; + if (attachment >= totalNumberAttachments) + { + return wxShape::AttachmentIsValid(attachment); + } + else if (attachment >= 0) + return TRUE; + else + return FALSE; +} + +void wxDividedShape::Copy(wxShape ©) +{ + wxRectangleShape::Copy(copy); +} + +// Region operations + +void wxDividedShape::MakeControlPoints() +{ + wxRectangleShape::MakeControlPoints(); + + MakeMandatoryControlPoints(); +} + +void wxDividedShape::MakeMandatoryControlPoints() +{ + double currentY = (double)(GetY() - (m_height / 2.0)); + double maxY = (double)(GetY() + (m_height / 2.0)); + + wxNode *node = GetRegions().GetFirst(); + int i = 0; + while (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + + double proportion = region->m_regionProportionY; + + double y = currentY + m_height * proportion; + double actualY = (double)(maxY < y ? maxY : y); + + if (node->GetNext()) + { + wxDividedShapeControlPoint *controlPoint = + new wxDividedShapeControlPoint(m_canvas, this, i, CONTROL_POINT_SIZE, 0.0, (double)(actualY - GetY()), 0); + m_canvas->AddShape(controlPoint); + m_controlPoints.Append(controlPoint); + } + currentY = actualY; + i ++; + node = node->GetNext(); + } +} + +void wxDividedShape::ResetControlPoints() +{ + // May only have the region handles, (n - 1) of them. + if (m_controlPoints.GetCount() > (GetRegions().GetCount() - 1)) + wxRectangleShape::ResetControlPoints(); + + ResetMandatoryControlPoints(); +} + +void wxDividedShape::ResetMandatoryControlPoints() +{ + double currentY = (double)(GetY() - (m_height / 2.0)); + double maxY = (double)(GetY() + (m_height / 2.0)); + + wxNode *node = m_controlPoints.GetFirst(); + int i = 0; + while (node) + { + wxControlPoint *controlPoint = (wxControlPoint *)node->GetData(); + if (controlPoint->IsKindOf(CLASSINFO(wxDividedShapeControlPoint))) + { + wxNode *node1 = GetRegions().Item(i); + wxShapeRegion *region = (wxShapeRegion *)node1->GetData(); + + double proportion = region->m_regionProportionY; + + double y = currentY + m_height * proportion; + double actualY = (double)(maxY < y ? maxY : y); + + controlPoint->m_xoffset = 0.0; + controlPoint->m_yoffset = (double)(actualY - GetY()); + currentY = actualY; + i ++; + } + node = node->GetNext(); + } +} + +#if wxUSE_PROLOGIO +void wxDividedShape::WriteAttributes(wxExpr *clause) +{ + wxRectangleShape::WriteAttributes(clause); +} + +void wxDividedShape::ReadAttributes(wxExpr *clause) +{ + wxRectangleShape::ReadAttributes(clause); +} +#endif + +/* + * Edit the division colour/style + * + */ + +void wxDividedShape::EditRegions() +{ + wxMessageBox(wxT("EditRegions() is unimplemented."), wxT("OGL"), wxOK); + + // TODO +#if 0 + if (GetRegions().GetCount() < 2) + return; + + wxBeginBusyCursor(); + + GraphicsForm *form = new GraphicsForm("Divided nodes"); + // Need an array to store all the style strings, + // since they need to be converted to integers + char **styleStrings = new char *[GetRegions().GetCount()]; + for (int j = 0; j < GetRegions().GetCount(); j++) + styleStrings[j] = NULL; + + int i = 0; + wxNode *node = GetRegions().GetFirst(); + while (node && node->GetNext()) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + char buf[50]; + sprintf(buf, "Region %d", (i + 1)); + form->Add(wxMakeFormMessage(buf)); + form->Add(wxMakeFormNewLine()); + + form->Add(wxMakeFormString("Colour", ®ion->penColour, wxFORM_CHOICE, + new wxList(wxMakeConstraintStrings( + "Invisible" , + "BLACK" , + "BLUE" , + "BROWN" , + "CORAL" , + "CYAN" , + "DARK GREY" , + "DARK GREEN" , + "DIM GREY" , + "GREY" , + "GREEN" , + "LIGHT BLUE" , + "LIGHT GREY" , + "MAGENTA" , + "MAROON" , + "NAVY" , + "ORANGE" , + "PURPLE" , + "RED" , + "TURQUOISE" , + "VIOLET" , + "WHITE" , + "YELLOW" , + NULL), + NULL), NULL, wxVERTICAL, 150)); + + char *styleString = NULL; + switch (region->penStyle) + { + case wxSHORT_DASH: + styleString = "Short Dash"; + break; + case wxLONG_DASH: + styleString = "Long Dash"; + break; + case wxDOT: + styleString = "Dot"; + break; + case wxDOT_DASH: + styleString = "Dot Dash"; + break; + case wxSOLID: + default: + styleString = "Solid"; + break; + } + styleStrings[i] = oglCopystring(styleString); + form->Add(wxMakeFormString("Style", &(styleStrings[i]), wxFORM_CHOICE, + new wxList(wxMakeConstraintStrings( + "Solid" , + "Short Dash" , + "Long Dash" , + "Dot" , + "Dot Dash" , + NULL), + NULL), NULL, wxVERTICAL, 100)); + node = node->GetNext(); + i ++; + if (node && node->GetNext()) + form->Add(wxMakeFormNewLine()); + } + wxDialogBox *dialog = new wxDialogBox(m_canvas->GetParent(), "Divided object properties", 10, 10, 500, 500); + if (GraphicsLabelFont) + dialog->SetLabelFont(GraphicsLabelFont); + if (GraphicsButtonFont) + dialog->SetButtonFont(GraphicsButtonFont); + form->AssociatePanel(dialog); + form->dialog = dialog; + + dialog->Fit(); + dialog->Centre(wxBOTH); + + wxEndBusyCursor(); + + dialog->Show(TRUE); + + node = GetRegions().GetFirst(); + i = 0; + while (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + + if (styleStrings[i]) + { + if (strcmp(styleStrings[i], "Solid") == 0) + region->penStyle = wxSOLID; + else if (strcmp(styleStrings[i], "Dot") == 0) + region->penStyle = wxDOT; + else if (strcmp(styleStrings[i], "Short Dash") == 0) + region->penStyle = wxSHORT_DASH; + else if (strcmp(styleStrings[i], "Long Dash") == 0) + region->penStyle = wxLONG_DASH; + else if (strcmp(styleStrings[i], "Dot Dash") == 0) + region->penStyle = wxDOT_DASH; + delete[] styleStrings[i]; + } + region->m_actualPenObject = NULL; + node = node->GetNext(); + i ++; + } + delete[] styleStrings; + Draw(dc); +#endif +} + +void wxDividedShape::OnRightClick(double x, double y, int keys, int attachment) +{ + if (keys & KEY_CTRL) + { + EditRegions(); + } + else + { + wxRectangleShape::OnRightClick(x, y, keys, attachment); + } +} + +wxDividedShapeControlPoint::wxDividedShapeControlPoint(wxShapeCanvas *the_canvas, wxShape *object, + int region, double size, double the_m_xoffset, double the_m_yoffset, int the_type): + wxControlPoint(the_canvas, object, size, the_m_xoffset, the_m_yoffset, the_type) +{ + regionId = region; +} + +wxDividedShapeControlPoint::~wxDividedShapeControlPoint() +{ +} + +// Implement resizing of divided object division +void wxDividedShapeControlPoint::OnDragLeft(bool WXUNUSED(draw), double WXUNUSED(x), double y, int WXUNUSED(keys), int WXUNUSED(attachment)) +{ + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + dc.SetLogicalFunction(OGLRBLF); + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + dc.SetPen(dottedPen); + dc.SetBrush((* wxTRANSPARENT_BRUSH)); + + wxDividedShape *dividedObject = (wxDividedShape *)m_shape; + double x1 = (double)(dividedObject->GetX() - (dividedObject->GetWidth() / 2.0)); + double y1 = y; + double x2 = (double)(dividedObject->GetX() + (dividedObject->GetWidth() / 2.0)); + double y2 = y; + dc.DrawLine(WXROUND(x1), WXROUND(y1), WXROUND(x2), WXROUND(y2)); +} + +void wxDividedShapeControlPoint::OnBeginDragLeft(double WXUNUSED(x), double y, int WXUNUSED(keys), int WXUNUSED(attachment)) +{ + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + wxDividedShape *dividedObject = (wxDividedShape *)m_shape; + dc.SetLogicalFunction(OGLRBLF); + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + dc.SetPen(dottedPen); + dc.SetBrush((* wxTRANSPARENT_BRUSH)); + + double x1 = (double)(dividedObject->GetX() - (dividedObject->GetWidth() / 2.0)); + double y1 = y; + double x2 = (double)(dividedObject->GetX() + (dividedObject->GetWidth() / 2.0)); + double y2 = y; + dc.DrawLine(WXROUND(x1), WXROUND(y1), WXROUND(x2), WXROUND(y2)); + m_canvas->CaptureMouse(); +} + +void wxDividedShapeControlPoint::OnEndDragLeft(double WXUNUSED(x), double y, int WXUNUSED(keys), int WXUNUSED(attachment)) +{ + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + wxDividedShape *dividedObject = (wxDividedShape *)m_shape; + wxNode *node = dividedObject->GetRegions().Item(regionId); + if (!node) + return; + + wxShapeRegion *thisRegion = (wxShapeRegion *)node->GetData(); + wxShapeRegion *nextRegion = NULL; // Region below this one + + dc.SetLogicalFunction(wxCOPY); + + m_canvas->ReleaseMouse(); + + // Find the old top and bottom of this region, + // and calculate the new proportion for this region + // if legal. + + double currentY = (double)(dividedObject->GetY() - (dividedObject->GetHeight() / 2.0)); + double maxY = (double)(dividedObject->GetY() + (dividedObject->GetHeight() / 2.0)); + + // Save values + double thisRegionTop = 0.0; +#if 0 + // this variable is not readed later + double thisRegionBottom = 0.0; +#endif + double nextRegionBottom = 0.0; + + node = dividedObject->GetRegions().GetFirst(); + while (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + + double proportion = region->m_regionProportionY; + double yy = currentY + (dividedObject->GetHeight() * proportion); + double actualY = (double)(maxY < yy ? maxY : yy); + + if (region == thisRegion) + { + thisRegionTop = currentY; +#if 0 + // no need for assignment if value is not used later + thisRegionBottom = actualY; +#endif + if (node->GetNext()) + nextRegion = (wxShapeRegion *)node->GetNext()->GetData(); + } + if (region == nextRegion) + { + nextRegionBottom = actualY; + } + + currentY = actualY; + node = node->GetNext(); + } + if (!nextRegion) + return; + + // Check that we haven't gone above this region or below + // next region. + if ((y <= thisRegionTop) || (y >= nextRegionBottom)) + return; + + // dividedObject->EraseLinks(dc); + + // Now calculate the new proportions of this region and the next region. + double thisProportion = (double)((y - thisRegionTop) / dividedObject->GetHeight()); + double nextProportion = (double)((nextRegionBottom - y) / dividedObject->GetHeight()); + thisRegion->SetProportions(0.0, thisProportion); + nextRegion->SetProportions(0.0, nextProportion); + m_yoffset = (double)(y - dividedObject->GetY()); + + // Now reformat text + int i = 0; + node = dividedObject->GetRegions().GetFirst(); + while (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + if (!region->GetText().IsEmpty()) + { + wxChar *s = oglCopystring(region->GetText()); + dividedObject->FormatText(dc, s, i); + delete[] s; + } + node = node->GetNext(); + i++; + } + dividedObject->SetRegionSizes(); + dividedObject->GetEventHandler()->OnMoveLinks(); + + if (GetCanvas()) + GetCanvas()->Refresh(); +} + diff --git a/ogl/drawn.cpp b/ogl/drawn.cpp new file mode 100644 index 0000000..db239c0 --- /dev/null +++ b/ogl/drawn.cpp @@ -0,0 +1,2498 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// drawn.cpp - wxDrawnShape +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include "ogl/ogl.h" + +static wxChar * +oglCopystring (const wxChar *s) +{ + if (s == NULL) s = wxEmptyString; + size_t len = wxStrlen (s) + 1; + + wxChar *news = new wxChar[len]; + memcpy (news, s, len * sizeof(wxChar)); // Should be the fastest + + return news; +} + +#include + +#if 0 +static void IntToHex(unsigned int dec, wxChar *buf); +static unsigned long HexToInt(wxChar *buf); +#endif + +extern wxChar *oglBuffer; + +#define gyTYPE_PEN 40 +#define gyTYPE_BRUSH 41 +#define gyTYPE_FONT 42 + +/* + * Drawn object + * + */ + +IMPLEMENT_DYNAMIC_CLASS(wxDrawnShape, wxRectangleShape) + +wxDrawnShape::wxDrawnShape(): wxRectangleShape(100.0, 50.0) +{ + m_saveToFile = TRUE; + m_currentAngle = oglDRAWN_ANGLE_0; +} + +wxDrawnShape::~wxDrawnShape() +{ +} + +void wxDrawnShape::OnDraw(wxDC &dc) +{ + // Pass pen and brush in case we have force outline + // and fill colours + if (m_shadowMode != SHADOW_NONE) + { + if (m_shadowBrush) + m_metafiles[m_currentAngle].m_fillBrush = m_shadowBrush; + m_metafiles[m_currentAngle].m_outlinePen = g_oglTransparentPen; + m_metafiles[m_currentAngle].Draw(dc, m_xpos + m_shadowOffsetX, m_ypos + m_shadowOffsetY); + } + + m_metafiles[m_currentAngle].m_outlinePen = m_pen; + m_metafiles[m_currentAngle].m_fillBrush = m_brush; + m_metafiles[m_currentAngle].Draw(dc, m_xpos, m_ypos); +} + +void wxDrawnShape::SetSize(double w, double h, bool WXUNUSED(recursive)) +{ + SetAttachmentSize(w, h); + + double scaleX; + double scaleY; + if (GetWidth() == 0.0) + scaleX = 1.0; + else scaleX = w / GetWidth(); + if (GetHeight() == 0.0) + scaleY = 1.0; + else scaleY = h / GetHeight(); + + for (int i = 0; i < 4; i++) + { + if (m_metafiles[i].IsValid()) + m_metafiles[i].Scale(scaleX, scaleY); + } + m_width = w; + m_height = h; + SetDefaultRegionSize(); +} + +void wxDrawnShape::Scale(double sx, double sy) +{ + int i; + for (i = 0; i < 4; i++) + { + if (m_metafiles[i].IsValid()) + { + m_metafiles[i].Scale(sx, sy); + m_metafiles[i].CalculateSize(this); + } + } +} + +void wxDrawnShape::Translate(double x, double y) +{ + int i; + for (i = 0; i < 4; i++) + { + if (m_metafiles[i].IsValid()) + { + m_metafiles[i].Translate(x, y); + m_metafiles[i].CalculateSize(this); + } + } +} + +// theta is absolute rotation from the zero position +void wxDrawnShape::Rotate(double x, double y, double theta) +{ + m_currentAngle = DetermineMetaFile(theta); + + if (m_currentAngle == 0) + { + // Rotate metafile + if (!m_metafiles[0].GetRotateable()) + return; + + m_metafiles[0].Rotate(x, y, theta); + } + + double actualTheta = theta - m_rotation; + + // Rotate attachment points + double sinTheta = (double)sin(actualTheta); + double cosTheta = (double)cos(actualTheta); + wxNode *node = m_attachmentPoints.GetFirst(); + while (node) + { + wxAttachmentPoint *point = (wxAttachmentPoint *)node->GetData(); + double x1 = point->m_x; + double y1 = point->m_y; + point->m_x = x1 * cosTheta - y1 * sinTheta + x * (1.0 - cosTheta) + y * sinTheta; + point->m_y = x1 * sinTheta + y1 * cosTheta + y * (1.0 - cosTheta) + x * sinTheta; + node = node->GetNext(); + } + m_rotation = theta; + + m_metafiles[m_currentAngle].CalculateSize(this); +} + +// Which metafile do we use now? Based on current rotation and validity +// of metafiles. + +int wxDrawnShape::DetermineMetaFile(double rotation) +{ + double tolerance = 0.0001; + const double pi = 3.1415926535897932384626433832795 ; + double angle1 = 0.0; + double angle2 = pi / 2.0; + double angle3 = pi; + double angle4 = 3.0 * pi / 2.0; + + int whichMetafile = 0; + + if (oglRoughlyEqual(rotation, angle1, tolerance)) + { + whichMetafile = 0; + } + else if (oglRoughlyEqual(rotation, angle2, tolerance)) + { + whichMetafile = 1; + } + else if (oglRoughlyEqual(rotation, angle3, tolerance)) + { + whichMetafile = 2; + } + else if (oglRoughlyEqual(rotation, angle4, tolerance)) + { + whichMetafile = 3; + } + + if ((whichMetafile > 0) && !m_metafiles[whichMetafile].IsValid()) + whichMetafile = 0; + + return whichMetafile; +} + +void wxDrawnShape::OnDrawOutline(wxDC &dc, double x, double y, double w, double h) +{ + if (m_metafiles[m_currentAngle].GetOutlineOp() != -1) + { + wxNode *node = m_metafiles[m_currentAngle].GetOps().Item(m_metafiles[m_currentAngle].GetOutlineOp()); + wxASSERT (node != NULL); + wxDrawOp *op = (wxDrawOp *) node->GetData(); + + if (op->OnDrawOutline(dc, x, y, w, h, m_width, m_height)) + return; + } + + // Default... just use a rectangle + wxRectangleShape::OnDrawOutline(dc, x, y, w, h); +} + +// Get the perimeter point using the special outline op, if there is one, +// otherwise use default wxRectangleShape scheme +bool wxDrawnShape::GetPerimeterPoint(double x1, double y1, + double x2, double y2, + double *x3, double *y3) +{ + if (m_metafiles[m_currentAngle].GetOutlineOp() != -1) + { + wxNode *node = m_metafiles[m_currentAngle].GetOps().Item(m_metafiles[m_currentAngle].GetOutlineOp()); + wxASSERT (node != NULL); + wxDrawOp *op = (wxDrawOp *) node->GetData(); + + if (op->GetPerimeterPoint(x1, y1, x2, y2, x3, y3, GetX(), GetY(), GetAttachmentMode())) + return TRUE; + } + + // Default... just use a rectangle + return wxRectangleShape::GetPerimeterPoint(x1, y1, x2, y2, x3, y3); +} + +#if wxUSE_PROLOGIO +void wxDrawnShape::WriteAttributes(wxExpr *clause) +{ + wxRectangleShape::WriteAttributes(clause); + + clause->AddAttributeValue(wxT("current_angle"), (long)m_currentAngle); + clause->AddAttributeValue(wxT("save_metafile"), (long)m_saveToFile); + if (m_saveToFile) + { + for (int i = 0; i < 4; i++) + { + if (m_metafiles[i].IsValid()) + m_metafiles[i].WriteAttributes(clause, i); + } + } +} + +void wxDrawnShape::ReadAttributes(wxExpr *clause) +{ + wxRectangleShape::ReadAttributes(clause); + + int iVal = (int) m_saveToFile; + clause->GetAttributeValue(wxT("save_metafile"), iVal); + clause->GetAttributeValue(wxT("current_angle"), m_currentAngle); + m_saveToFile = (iVal != 0); + + if (m_saveToFile) + { + for (int i = 0; i < 4; i++) + { + m_metafiles[i].ReadAttributes(clause, i); + } + } +} +#endif + +// Does the copying for this object +void wxDrawnShape::Copy(wxShape ©) +{ + wxRectangleShape::Copy(copy); + + wxASSERT( copy.IsKindOf(CLASSINFO(wxDrawnShape)) ) ; + + wxDrawnShape &drawnCopy = (wxDrawnShape &) copy; + + for (int i = 0; i < 4; i++) + { + m_metafiles[i].Copy(drawnCopy.m_metafiles[i]); + } + drawnCopy.m_saveToFile = m_saveToFile; + drawnCopy.m_currentAngle = m_currentAngle; +} + +bool wxDrawnShape::LoadFromMetaFile(const wxString &filename) +{ + return m_metafiles[0].LoadFromMetaFile(filename, &m_width, &m_height); +} + +// Set of functions for drawing into a pseudo metafile. +// They use integers, but doubles are used internally for accuracy +// when scaling. + +void wxDrawnShape::DrawLine(const wxPoint &pt1, const wxPoint &pt2) +{ + m_metafiles[m_currentAngle].DrawLine(pt1, pt2); +} + +void wxDrawnShape::DrawRectangle(const wxRect &rect) +{ + m_metafiles[m_currentAngle].DrawRectangle(rect); +} + +void wxDrawnShape::DrawRoundedRectangle(const wxRect &rect, double radius) +{ + m_metafiles[m_currentAngle].DrawRoundedRectangle(rect, radius); +} + +void wxDrawnShape::DrawEllipse(const wxRect &rect) +{ + m_metafiles[m_currentAngle].DrawEllipse(rect); +} + +void wxDrawnShape::DrawArc(const wxPoint ¢rePt, const wxPoint &startPt, const wxPoint &endPt) +{ + m_metafiles[m_currentAngle].DrawArc(centrePt, startPt, endPt); +} + +void wxDrawnShape::DrawEllipticArc(const wxRect &rect, double startAngle, double endAngle) +{ + m_metafiles[m_currentAngle].DrawEllipticArc(rect, startAngle, endAngle); +} + +void wxDrawnShape::DrawPoint(const wxPoint &pt) +{ + m_metafiles[m_currentAngle].DrawPoint(pt); +} + +void wxDrawnShape::DrawText(const wxString &text, const wxPoint &pt) +{ + m_metafiles[m_currentAngle].DrawText(text, pt); +} + +void wxDrawnShape::DrawLines(int n, wxPoint pts[]) +{ + m_metafiles[m_currentAngle].DrawLines(n, pts); +} + +void wxDrawnShape::DrawPolygon(int n, wxPoint pts[], int flags) +{ + if (flags & oglMETAFLAGS_ATTACHMENTS) + { + ClearAttachments(); + int i; + for (i = 0; i < n; i++) + m_attachmentPoints.Append(new wxAttachmentPoint(i, pts[i].x, pts[i].y)); + } + m_metafiles[m_currentAngle].DrawPolygon(n, pts, flags); +} + +void wxDrawnShape::DrawSpline(int n, wxPoint pts[]) +{ + m_metafiles[m_currentAngle].DrawSpline(n, pts); +} + +void wxDrawnShape::SetClippingRect(const wxRect &rect) +{ + m_metafiles[m_currentAngle].SetClippingRect(rect); +} + +void wxDrawnShape::DestroyClippingRect() +{ + m_metafiles[m_currentAngle].DestroyClippingRect(); +} + +void wxDrawnShape::SetDrawnPen(wxPen *pen, bool isOutline) +{ + m_metafiles[m_currentAngle].SetPen(pen, isOutline); +} + +void wxDrawnShape::SetDrawnBrush(wxBrush *brush, bool isFill) +{ + m_metafiles[m_currentAngle].SetBrush(brush, isFill); +} + +void wxDrawnShape::SetDrawnFont(wxFont *font) +{ + m_metafiles[m_currentAngle].SetFont(font); +} + +void wxDrawnShape::SetDrawnTextColour(const wxColour &colour) +{ + m_metafiles[m_currentAngle].SetTextColour(colour); +} + +void wxDrawnShape::SetDrawnBackgroundColour(const wxColour &colour) +{ + m_metafiles[m_currentAngle].SetBackgroundColour(colour); +} + +void wxDrawnShape::SetDrawnBackgroundMode(int mode) +{ + m_metafiles[m_currentAngle].SetBackgroundMode(mode); +} + + +/* + * Individual operations + * + */ + +/* + * Set font, brush, text colour + * + */ + +wxOpSetGDI::wxOpSetGDI(int theOp, wxPseudoMetaFile *theImage, int theGdiIndex, int theMode): + wxDrawOp(theOp) +{ + m_gdiIndex = theGdiIndex; + m_image = theImage; + m_mode = theMode; +} + +void wxOpSetGDI::Do(wxDC &dc, double WXUNUSED(xoffset), double WXUNUSED(yoffset)) +{ + switch (m_op) + { + case DRAWOP_SET_PEN: + { + // Check for overriding this operation for outline + // colour + if (m_image->m_outlineColours.Member((wxObject *)m_gdiIndex)) + { + if (m_image->m_outlinePen) + dc.SetPen(* m_image->m_outlinePen); + } + else + { + wxNode *node = m_image->m_gdiObjects.Item(m_gdiIndex); + if (node) + { + wxPen *pen = (wxPen *)node->GetData(); + if (pen) + dc.SetPen(* pen); + } + } + break; + } + case DRAWOP_SET_BRUSH: + { + // Check for overriding this operation for outline or fill + // colour + if (m_image->m_outlineColours.Member((wxObject *)m_gdiIndex)) + { + // Need to construct a brush to match the outline pen's colour + if (m_image->m_outlinePen) + { + wxBrush *br = wxTheBrushList->FindOrCreateBrush(m_image->m_outlinePen->GetColour(), wxSOLID); + if (br) + dc.SetBrush(* br); + } + } + else if (m_image->m_fillColours.Member((wxObject *)m_gdiIndex)) + { + if (m_image->m_fillBrush) + { + dc.SetBrush(* m_image->m_fillBrush); + } + } + else + { + wxNode *node = m_image->m_gdiObjects.Item(m_gdiIndex); + if (node) + { + wxBrush *brush = (wxBrush *)node->GetData(); + if (brush) + dc.SetBrush(* brush); + } + } + break; + } + case DRAWOP_SET_FONT: + { + wxNode *node = m_image->m_gdiObjects.Item(m_gdiIndex); + if (node) + { + wxFont *font = (wxFont *)node->GetData(); + if (font) + dc.SetFont(* font); + } + break; + } + case DRAWOP_SET_TEXT_COLOUR: + { + wxColour col(m_r, m_g, m_b); + dc.SetTextForeground(col); + break; + } + case DRAWOP_SET_BK_COLOUR: + { + wxColour col(m_r, m_g, m_b); + dc.SetTextBackground(col); + break; + } + case DRAWOP_SET_BK_MODE: + { + dc.SetBackgroundMode(m_mode); + break; + } + default: + break; + } +} + +wxDrawOp *wxOpSetGDI::Copy(wxPseudoMetaFile *newImage) +{ + wxOpSetGDI *newOp = new wxOpSetGDI(m_op, newImage, m_gdiIndex, m_mode); + newOp->m_r = m_r; + newOp->m_g = m_g; + newOp->m_b = m_b; + return newOp; +} + +#if wxUSE_PROLOGIO +wxExpr *wxOpSetGDI::WriteExpr(wxPseudoMetaFile *WXUNUSED(image)) +{ + wxExpr *expr = new wxExpr(wxExprList); + expr->Append(new wxExpr((long)m_op)); + switch (m_op) + { + case DRAWOP_SET_PEN: + case DRAWOP_SET_BRUSH: + case DRAWOP_SET_FONT: + { + expr->Append(new wxExpr((long)m_gdiIndex)); + break; + } + case DRAWOP_SET_TEXT_COLOUR: + case DRAWOP_SET_BK_COLOUR: + { + expr->Append(new wxExpr((long)m_r)); + expr->Append(new wxExpr((long)m_g)); + expr->Append(new wxExpr((long)m_b)); + break; + } + case DRAWOP_SET_BK_MODE: + { + expr->Append(new wxExpr((long)m_mode)); + break; + } + default: + break; + } + return expr; +} + +void wxOpSetGDI::ReadExpr(wxPseudoMetaFile *WXUNUSED(image), wxExpr *expr) +{ + switch (m_op) + { + case DRAWOP_SET_PEN: + case DRAWOP_SET_BRUSH: + case DRAWOP_SET_FONT: + { + m_gdiIndex = (int)expr->Nth(1)->IntegerValue(); + break; + } + case DRAWOP_SET_TEXT_COLOUR: + case DRAWOP_SET_BK_COLOUR: + { + m_r = (unsigned char)expr->Nth(1)->IntegerValue(); + m_g = (unsigned char)expr->Nth(2)->IntegerValue(); + m_b = (unsigned char)expr->Nth(3)->IntegerValue(); + break; + } + case DRAWOP_SET_BK_MODE: + { + m_mode = (int)expr->Nth(1)->IntegerValue(); + break; + } + default: + break; + } +} +#endif + +/* + * Set/destroy clipping + * + */ + +wxOpSetClipping::wxOpSetClipping(int theOp, double theX1, double theY1, + double theX2, double theY2): wxDrawOp(theOp) +{ + m_x1 = theX1; + m_y1 = theY1; + m_x2 = theX2; + m_y2 = theY2; +} + +wxDrawOp *wxOpSetClipping::Copy(wxPseudoMetaFile *WXUNUSED(newImage)) +{ + wxOpSetClipping *newOp = new wxOpSetClipping(m_op, m_x1, m_y1, m_x2, m_y2); + return newOp; +} + +void wxOpSetClipping::Do(wxDC &dc, double xoffset, double yoffset) +{ + switch (m_op) + { + case DRAWOP_SET_CLIPPING_RECT: + { + dc.SetClippingRegion((long)(m_x1 + xoffset), (long)(m_y1 + yoffset), (long)(m_x2 + xoffset), (long)(m_y2 + yoffset)); + break; + } + case DRAWOP_DESTROY_CLIPPING_RECT: + { + dc.DestroyClippingRegion(); + break; + } + default: + break; + } +} + +void wxOpSetClipping::Scale(double xScale, double yScale) +{ + m_x1 *= xScale; + m_y1 *= yScale; + m_x2 *= xScale; + m_y2 *= yScale; +} + +void wxOpSetClipping::Translate(double x, double y) +{ + m_x1 += x; + m_y1 += y; +} + +#if wxUSE_PROLOGIO +wxExpr *wxOpSetClipping::WriteExpr(wxPseudoMetaFile *WXUNUSED(image)) +{ + wxExpr *expr = new wxExpr(wxExprList); + expr->Append(new wxExpr((long)m_op)); + switch (m_op) + { + case DRAWOP_SET_CLIPPING_RECT: + { + expr->Append(new wxExpr(m_x1)); + expr->Append(new wxExpr(m_y1)); + expr->Append(new wxExpr(m_x2)); + expr->Append(new wxExpr(m_y2)); + break; + } + default: + break; + } + return expr; +} + +void wxOpSetClipping::ReadExpr(wxPseudoMetaFile *WXUNUSED(image), wxExpr *expr) +{ + switch (m_op) + { + case DRAWOP_SET_CLIPPING_RECT: + { + m_x1 = expr->Nth(1)->RealValue(); + m_y1 = expr->Nth(2)->RealValue(); + m_x2 = expr->Nth(3)->RealValue(); + m_y2 = expr->Nth(4)->RealValue(); + break; + } + default: + break; + } +} +#endif + +/* + * Draw line, rectangle, rounded rectangle, ellipse, point, arc, text + * + */ + +wxOpDraw::wxOpDraw(int theOp, double theX1, double theY1, double theX2, double theY2, + double theRadius, wxChar *s) : wxDrawOp(theOp) +{ + m_x1 = theX1; + m_y1 = theY1; + m_x2 = theX2; + m_y2 = theY2; + m_x3 = 0.0; + m_y3 = 0.0; + m_radius = theRadius; + if (s) m_textString = oglCopystring(s); + else m_textString = NULL; +} + +wxOpDraw::~wxOpDraw() +{ + if (m_textString) delete[] m_textString; +} + +wxDrawOp *wxOpDraw::Copy(wxPseudoMetaFile *WXUNUSED(newImage)) +{ + wxOpDraw *newOp = new wxOpDraw(m_op, m_x1, m_y1, m_x2, m_y2, m_radius, m_textString); + newOp->m_x3 = m_x3; + newOp->m_y3 = m_y3; + return newOp; +} + +void wxOpDraw::Do(wxDC &dc, double xoffset, double yoffset) +{ + switch (m_op) + { + case DRAWOP_DRAW_LINE: + { + dc.DrawLine(WXROUND(m_x1 + xoffset), WXROUND(m_y1 + yoffset), WXROUND(m_x2 + xoffset), WXROUND(m_y2 + yoffset)); + break; + } + case DRAWOP_DRAW_RECT: + { + dc.DrawRectangle(WXROUND(m_x1 + xoffset), WXROUND(m_y1 + yoffset), WXROUND(m_x2), WXROUND(m_y2)); + break; + } + case DRAWOP_DRAW_ROUNDED_RECT: + { + dc.DrawRoundedRectangle(WXROUND(m_x1 + xoffset), WXROUND(m_y1 + yoffset), WXROUND(m_x2), WXROUND(m_y2), m_radius); + break; + } + case DRAWOP_DRAW_ELLIPSE: + { + dc.DrawEllipse(WXROUND(m_x1 + xoffset), WXROUND(m_y1 + yoffset), WXROUND(m_x2), WXROUND(m_y2)); + break; + } + case DRAWOP_DRAW_ARC: + { + dc.DrawArc(WXROUND(m_x2 + xoffset), WXROUND(m_y2 + yoffset), + WXROUND(m_x3 + xoffset), WXROUND(m_y3 + yoffset), + WXROUND(m_x1 + xoffset), WXROUND(m_y1 + yoffset)); + break; + } + case DRAWOP_DRAW_ELLIPTIC_ARC: + { + const double pi = 3.1415926535897932384626433832795 ; + + // Convert back to degrees + dc.DrawEllipticArc( + WXROUND(m_x1 + xoffset), WXROUND(m_y1 + yoffset), + WXROUND(m_x2), WXROUND(m_y2), + WXROUND(m_x3 * (360.0 / (2.0 * pi))), WXROUND(m_y3 * (360.0 / (2.0 * pi)))); + break; + } + case DRAWOP_DRAW_POINT: + { + dc.DrawPoint(WXROUND(m_x1 + xoffset), WXROUND(m_y1 + yoffset)); + break; + } + case DRAWOP_DRAW_TEXT: + { + dc.DrawText(m_textString, WXROUND(m_x1 + xoffset), WXROUND(m_y1 + yoffset)); + break; + } + default: + break; + } +} + +void wxOpDraw::Scale(double scaleX, double scaleY) +{ + m_x1 *= scaleX; + m_y1 *= scaleY; + m_x2 *= scaleX; + m_y2 *= scaleY; + + if (m_op != DRAWOP_DRAW_ELLIPTIC_ARC) + { + m_x3 *= scaleX; + m_y3 *= scaleY; + } + + m_radius *= scaleX; +} + +void wxOpDraw::Translate(double x, double y) +{ + m_x1 += x; + m_y1 += y; + + switch (m_op) + { + case DRAWOP_DRAW_LINE: + { + m_x2 += x; + m_y2 += y; + break; + } + case DRAWOP_DRAW_ARC: + { + m_x2 += x; + m_y2 += y; + m_x3 += x; + m_y3 += y; + break; + } + case DRAWOP_DRAW_ELLIPTIC_ARC: + { + break; + } + default: + break; + } +} + +void wxOpDraw::Rotate(double x, double y, double theta, double sinTheta, double cosTheta) +{ + double newX1 = m_x1 * cosTheta - m_y1 * sinTheta + x * (1.0 - cosTheta) + y * sinTheta; + double newY1 = m_x1 * sinTheta + m_y1 * cosTheta + y * (1.0 - cosTheta) + x * sinTheta; + + switch (m_op) + { + case DRAWOP_DRAW_LINE: + { + double newX2 = m_x2 * cosTheta - m_y2 * sinTheta + x * (1.0 - cosTheta) + y * sinTheta; + double newY2 = m_x2 * sinTheta + m_y2 * cosTheta + y * (1.0 - cosTheta) + x * sinTheta; + + m_x1 = newX1; + m_y1 = newY1; + m_x2 = newX2; + m_y2 = newY2; + break; + } + case DRAWOP_DRAW_RECT: + case DRAWOP_DRAW_ROUNDED_RECT: + case DRAWOP_DRAW_ELLIPTIC_ARC: + { + // Assume only 0, 90, 180, 270 degree rotations. + // oldX1, oldY1 represents the top left corner. Find the + // bottom right, and rotate that. Then the width/height is the difference + // between x/y values. + double oldBottomRightX = m_x1 + m_x2; + double oldBottomRightY = m_y1 + m_y2; + double newBottomRightX = oldBottomRightX * cosTheta - oldBottomRightY * sinTheta + x * (1.0 - cosTheta) + y * sinTheta; + double newBottomRightY = oldBottomRightX * sinTheta + oldBottomRightY * cosTheta + y * (1.0 - cosTheta) + x * sinTheta; + + // Now find the new top-left, bottom-right coordinates. + double minX = wxMin(newX1, newBottomRightX); + double minY = wxMin(newY1, newBottomRightY); + double maxX = wxMax(newX1, newBottomRightX); + double maxY = wxMax(newY1, newBottomRightY); + + m_x1 = minX; + m_y1 = minY; + m_x2 = maxX - minX; // width + m_y2 = maxY - minY; // height + + if (m_op == DRAWOP_DRAW_ELLIPTIC_ARC) + { + // Add rotation to angles + m_x3 += theta; + m_y3 += theta; + } + + break; + } + case DRAWOP_DRAW_ARC: + { + double newX2 = m_x2 * cosTheta - m_y2 * sinTheta + x * (1.0 - cosTheta) + y * sinTheta; + double newY2 = m_x2 * sinTheta + m_y2 * cosTheta + y * (1.0 - cosTheta) + x * sinTheta; + double newX3 = m_x3 * cosTheta - m_y3 * sinTheta + x * (1.0 - cosTheta) + y * sinTheta; + double newY3 = m_x3 * sinTheta + m_y3 * cosTheta + y * (1.0 - cosTheta) + x * sinTheta; + + m_x1 = newX1; + m_y1 = newY1; + m_x2 = newX2; + m_y2 = newY2; + m_x3 = newX3; + m_y3 = newY3; + + break; + } + default: + break; + } +} + +#if wxUSE_PROLOGIO +wxExpr *wxOpDraw::WriteExpr(wxPseudoMetaFile *WXUNUSED(image)) +{ + wxExpr *expr = new wxExpr(wxExprList); + expr->Append(new wxExpr((long)m_op)); + switch (m_op) + { + case DRAWOP_DRAW_LINE: + case DRAWOP_DRAW_RECT: + case DRAWOP_DRAW_ELLIPSE: + { + expr->Append(new wxExpr(m_x1)); + expr->Append(new wxExpr(m_y1)); + expr->Append(new wxExpr(m_x2)); + expr->Append(new wxExpr(m_y2)); + break; + } + case DRAWOP_DRAW_ROUNDED_RECT: + { + expr->Append(new wxExpr(m_x1)); + expr->Append(new wxExpr(m_y1)); + expr->Append(new wxExpr(m_x2)); + expr->Append(new wxExpr(m_y2)); + expr->Append(new wxExpr(m_radius)); + break; + } + case DRAWOP_DRAW_POINT: + { + expr->Append(new wxExpr(m_x1)); + expr->Append(new wxExpr(m_y1)); + break; + } + case DRAWOP_DRAW_TEXT: + { + expr->Append(new wxExpr(m_x1)); + expr->Append(new wxExpr(m_y1)); + expr->Append(new wxExpr(wxExprString, m_textString)); + break; + } + case DRAWOP_DRAW_ARC: + case DRAWOP_DRAW_ELLIPTIC_ARC: + { + expr->Append(new wxExpr(m_x1)); + expr->Append(new wxExpr(m_y1)); + expr->Append(new wxExpr(m_x2)); + expr->Append(new wxExpr(m_y2)); + expr->Append(new wxExpr(m_x3)); + expr->Append(new wxExpr(m_y3)); + break; + } + default: + { + break; + } + } + return expr; +} + +void wxOpDraw::ReadExpr(wxPseudoMetaFile *WXUNUSED(image), wxExpr *expr) +{ + switch (m_op) + { + case DRAWOP_DRAW_LINE: + case DRAWOP_DRAW_RECT: + case DRAWOP_DRAW_ELLIPSE: + { + m_x1 = expr->Nth(1)->RealValue(); + m_y1 = expr->Nth(2)->RealValue(); + m_x2 = expr->Nth(3)->RealValue(); + m_y2 = expr->Nth(4)->RealValue(); + break; + } + case DRAWOP_DRAW_ROUNDED_RECT: + { + m_x1 = expr->Nth(1)->RealValue(); + m_y1 = expr->Nth(2)->RealValue(); + m_x2 = expr->Nth(3)->RealValue(); + m_y2 = expr->Nth(4)->RealValue(); + m_radius = expr->Nth(5)->RealValue(); + break; + } + case DRAWOP_DRAW_POINT: + { + m_x1 = expr->Nth(1)->RealValue(); + m_y1 = expr->Nth(2)->RealValue(); + break; + } + case DRAWOP_DRAW_TEXT: + { + m_x1 = expr->Nth(1)->RealValue(); + m_y1 = expr->Nth(2)->RealValue(); + wxString str(expr->Nth(3)->StringValue()); + m_textString = oglCopystring(str); + break; + } + case DRAWOP_DRAW_ARC: + case DRAWOP_DRAW_ELLIPTIC_ARC: + { + m_x1 = expr->Nth(1)->RealValue(); + m_y1 = expr->Nth(2)->RealValue(); + m_x2 = expr->Nth(3)->RealValue(); + m_y2 = expr->Nth(4)->RealValue(); + m_x3 = expr->Nth(5)->RealValue(); + m_y3 = expr->Nth(6)->RealValue(); + break; + } + default: + { + break; + } + } +} +#endif + +/* + * Draw polygon, polyline, spline + * + */ + +wxOpPolyDraw::wxOpPolyDraw(int theOp, int n, wxRealPoint *thePoints): wxDrawOp(theOp) +{ + m_noPoints = n; + m_points = thePoints; +} + +wxOpPolyDraw::~wxOpPolyDraw() +{ + delete[] m_points; +} + +wxDrawOp *wxOpPolyDraw::Copy(wxPseudoMetaFile *WXUNUSED(newImage)) +{ + wxRealPoint *newPoints = new wxRealPoint[m_noPoints]; + for (int i = 0; i < m_noPoints; i++) + { + newPoints[i].x = m_points[i].x; + newPoints[i].y = m_points[i].y; + } + wxOpPolyDraw *newOp = new wxOpPolyDraw(m_op, m_noPoints, newPoints); + return newOp; +} + +void wxOpPolyDraw::Do(wxDC &dc, double xoffset, double yoffset) +{ + switch (m_op) + { + case DRAWOP_DRAW_POLYLINE: + { + wxPoint *actualPoints = new wxPoint[m_noPoints]; + int i; + for (i = 0; i < m_noPoints; i++) + { + actualPoints[i].x = WXROUND(m_points[i].x); + actualPoints[i].y = WXROUND(m_points[i].y); + } + + dc.DrawLines(m_noPoints, actualPoints, WXROUND(xoffset), WXROUND(yoffset)); + + delete[] actualPoints; + break; + } + case DRAWOP_DRAW_POLYGON: + { + wxPoint *actualPoints = new wxPoint[m_noPoints]; + int i; + for (i = 0; i < m_noPoints; i++) + { + actualPoints[i].x = WXROUND(m_points[i].x); + actualPoints[i].y = WXROUND(m_points[i].y); + } + + dc.DrawPolygon(m_noPoints, actualPoints, WXROUND(xoffset), WXROUND(yoffset)); + + delete[] actualPoints; + break; + } + case DRAWOP_DRAW_SPLINE: + { + wxPoint *actualPoints = new wxPoint[m_noPoints]; + int i; + for (i = 0; i < m_noPoints; i++) + { + actualPoints[i].x = WXROUND(m_points[i].x); + actualPoints[i].y = WXROUND(m_points[i].y); + } + + dc.DrawSpline(m_noPoints, actualPoints); // no offsets in DrawSpline // , xoffset, yoffset); + + delete[] actualPoints; + break; + } + default: + break; + } +} + +void wxOpPolyDraw::Scale(double scaleX, double scaleY) +{ + for (int i = 0; i < m_noPoints; i++) + { + m_points[i].x *= scaleX; + m_points[i].y *= scaleY; + } +} + +void wxOpPolyDraw::Translate(double x, double y) +{ + for (int i = 0; i < m_noPoints; i++) + { + m_points[i].x += x; + m_points[i].y += y; + } +} + +void wxOpPolyDraw::Rotate(double x, double y, double WXUNUSED(theta), double sinTheta, double cosTheta) +{ + for (int i = 0; i < m_noPoints; i++) + { + double x1 = m_points[i].x; + double y1 = m_points[i].y; + m_points[i].x = x1 * cosTheta - y1 * sinTheta + x * (1.0 - cosTheta) + y * sinTheta; + m_points[i].y = x1 * sinTheta + y1 * cosTheta + y * (1.0 - cosTheta) + x * sinTheta; + } +} + +#if wxUSE_PROLOGIO +wxExpr *wxOpPolyDraw::WriteExpr(wxPseudoMetaFile *WXUNUSED(image)) +{ + wxExpr *expr = new wxExpr(wxExprList); + expr->Append(new wxExpr((long)m_op)); + expr->Append(new wxExpr((long)m_noPoints)); + +// char buf1[9]; + wxChar buf2[5]; + wxChar buf3[5]; + + oglBuffer[0] = 0; + + /* + * Store each coordinate pair in a hex string to save space. + * E.g. "1B9080CD". 4 hex digits per coordinate pair. + * + */ + + for (int i = 0; i < m_noPoints; i++) + { + long signedX = (long)(m_points[i].x * 100.0); + long signedY = (long)(m_points[i].y * 100.0); + + // Scale to 0 -> 64K + long unSignedX = (long)(signedX + 32767.0); + long unSignedY = (long)(signedY + 32767.0); + +// IntToHex((unsigned int)signedX, buf2); +// IntToHex((unsigned int)signedY, buf3); + IntToHex((int)unSignedX, buf2); + IntToHex((int)unSignedY, buf3); + + // Don't overrun the buffer + if ((i * 8) < 3000) + { + wxStrcat(oglBuffer, buf2); + wxStrcat(oglBuffer, buf3); + } + } + expr->Append(new wxExpr(wxExprString, oglBuffer)); + return expr; +} + +void wxOpPolyDraw::ReadExpr(wxPseudoMetaFile *WXUNUSED(image), wxExpr *expr) +{ + m_noPoints = (int)expr->Nth(1)->IntegerValue(); + + wxChar buf1[5]; + wxChar buf2[5]; + + m_points = new wxRealPoint[m_noPoints]; + int i = 0; + int bufPtr = 0; + wxString hexString = expr->Nth(2)->StringValue(); + while (i < m_noPoints) + { + buf1[0] = hexString[(size_t)bufPtr]; + buf1[1] = hexString[(size_t)(bufPtr + 1)]; + buf1[2] = hexString[(size_t)(bufPtr + 2)]; + buf1[3] = hexString[(size_t)(bufPtr + 3)]; + buf1[4] = 0; + + buf2[0] = hexString[(size_t)(bufPtr + 4)]; + buf2[1] = hexString[(size_t)(bufPtr + 5)]; + buf2[2] = hexString[(size_t)(bufPtr + 6)]; + buf2[3] = hexString[(size_t)(bufPtr + 7)]; + buf2[4] = 0; + + bufPtr += 8; + +// int signedX = (signed int)HexToInt(buf1); +// int signedY = (signed int)HexToInt(buf2); + long unSignedX = HexToInt(buf1); + long unSignedY = HexToInt(buf2); + // Scale -32K -> +32K + long signedX = unSignedX - 32767; + long signedY = unSignedY - 32767; +#if defined(__WXMSW__) && 0 + int testX = (signed int)unSignedX; + int testY = (signed int)unSignedY; +#endif + + m_points[i].x = (double)(signedX / 100.0); + m_points[i].y = (double)(signedY / 100.0); + + i ++; + } +} +#endif + +// Draw an outline using the current operation. +bool wxOpPolyDraw::OnDrawOutline(wxDC &dc, double x, double y, double w, double h, double oldW, double oldH) +{ + dc.SetBrush(* wxTRANSPARENT_BRUSH); + + // Multiply all points by proportion of new size to old size + double x_proportion = (double)(fabs(w / oldW)); + double y_proportion = (double)(fabs(h / oldH)); + + int n = m_noPoints; + wxPoint *intPoints = new wxPoint[n]; + int i; + for (i = 0; i < n; i++) + { + intPoints[i].x = WXROUND (x_proportion * m_points[i].x); + intPoints[i].y = WXROUND (y_proportion * m_points[i].y); + } + dc.DrawPolygon(n, intPoints, (long) x, (long) y); + delete[] intPoints; + return TRUE; +} + +// Assume (x1, y1) is centre of box (most generally, line end at box) +bool wxOpPolyDraw::GetPerimeterPoint(double x1, double y1, + double x2, double y2, + double *x3, double *y3, + double xOffset, double yOffset, + int attachmentMode) +{ + int n = m_noPoints; + + // First check for situation where the line is vertical, + // and we would want to connect to a point on that vertical -- + // oglFindEndForPolyline can't cope with this (the arrow + // gets drawn to the wrong place). + if ((attachmentMode == ATTACHMENT_MODE_NONE) && (x1 == x2)) + { + // Look for the point we'd be connecting to. This is + // a heuristic... + int i; + for (i = 0; i < n; i++) + { + wxRealPoint *point = & (m_points[i]); + if (point->x == 0.0) + { + if ((y2 > y1) && (point->y > 0.0)) + { + *x3 = point->x + xOffset; + *y3 = point->y + yOffset; + return TRUE; + } + else if ((y2 < y1) && (point->y < 0.0)) + { + *x3 = point->x + xOffset; + *y3 = point->y + yOffset; + return TRUE; + } + } + } + } + + double *xpoints = new double[n]; + double *ypoints = new double[n]; + + for (int i = 0; i < n; i++) + { + wxRealPoint *point = & (m_points[i]); + xpoints[i] = point->x + xOffset; + ypoints[i] = point->y + yOffset; + } + + oglFindEndForPolyline(n, xpoints, ypoints, + x1, y1, x2, y2, x3, y3); + + delete[] xpoints; + delete[] ypoints; + + return TRUE; +} + + +/* + * Utilities + * + */ + +#if 0 +static char hexArray[] = +{ + wxT('0'), wxT('1'), wxT('2'), wxT('3'), wxT('4'), wxT('5'), wxT('6'), wxT('7'), + wxT('8'), wxT('9'), wxT('A'), wxT('B'), wxT('C'), wxT('D'), wxT('E'), wxT('F') +}; + +// Convert unsigned 16-bit integer to 4-character hex string +static void IntToHex(unsigned int dec, wxChar *buf) +{ + int digit1 = (int)(dec / 4096); + int digit2 = (int)((dec - (digit1 * 4096)) / 256); + int digit3 = (int)((dec - (digit1 * 4096) - (digit2 * 256)) / 16); + int digit4 = dec - (digit1 * 4096 + digit2 * 256 + digit3 * 16); + + buf[0] = hexArray[digit1]; + buf[1] = hexArray[digit2]; + buf[2] = hexArray[digit3]; + buf[3] = hexArray[digit4]; + buf[4] = 0; +} +#endif + +#if 0 +// One hex digit to decimal number +static int HexToInt1(wxChar hex) +{ + switch (hex) + { + case wxT('0'): + return 0; + case wxT('1'): + return 1; + case wxT('2'): + return 2; + case wxT('3'): + return 3; + case wxT('4'): + return 4; + case wxT('5'): + return 5; + case wxT('6'): + return 6; + case wxT('7'): + return 7; + case wxT('8'): + return 8; + case wxT('9'): + return 9; + case wxT('A'): + return 10; + case wxT('B'): + return 11; + case wxT('C'): + return 12; + case wxT('D'): + return 13; + case wxT('E'): + return 14; + case wxT('F'): + return 15; +#if 0 + // handling this default outside switch removes warning under Borland + default: + return 0; +#endif + } + + return 0; +} + +// 4-digit hex string to unsigned integer +static unsigned long HexToInt(wxChar *buf) +{ + long d1 = (long)(HexToInt1(buf[0]) * 4096.0) ; + long d2 = (long)(HexToInt1(buf[1]) * 256.0) ; + long d3 = (long)(HexToInt1(buf[2]) * 16.0) ; + long d4 = (long)(HexToInt1(buf[3])) ; + unsigned long n = (long)(d1 + d2 + d3 + d4) ; + return n; +} +#endif + +/* + * wxPseudo meta-file + * + */ + +IMPLEMENT_DYNAMIC_CLASS(wxPseudoMetaFile, wxObject) + +wxPseudoMetaFile::wxPseudoMetaFile() +{ + m_currentRotation = 0; + m_rotateable = TRUE; + m_width = 0.0; + m_height = 0.0; + m_outlinePen = NULL; + m_fillBrush = NULL; + m_outlineOp = -1; +} + +wxPseudoMetaFile::wxPseudoMetaFile(wxPseudoMetaFile &mf) +{ + mf.Copy(*this); +} + +wxPseudoMetaFile::~wxPseudoMetaFile() +{ + Clear(); +} + +void wxPseudoMetaFile::Clear() +{ + wxNode *node = m_ops.GetFirst(); + while (node) + { + wxDrawOp *op = (wxDrawOp *)node->GetData(); + delete op; + node = node->GetNext(); + } + m_ops.Clear(); + m_gdiObjects.Clear(); + m_outlineColours.Clear(); + m_fillColours.Clear(); + m_outlineOp = -1; +} + +void wxPseudoMetaFile::Draw(wxDC &dc, double xoffset, double yoffset) +{ + wxNode *node = m_ops.GetFirst(); + while (node) + { + wxDrawOp *op = (wxDrawOp *)node->GetData(); + op->Do(dc, xoffset, yoffset); + node = node->GetNext(); + } +} + +void wxPseudoMetaFile::Scale(double sx, double sy) +{ + wxNode *node = m_ops.GetFirst(); + while (node) + { + wxDrawOp *op = (wxDrawOp *)node->GetData(); + op->Scale(sx, sy); + node = node->GetNext(); + } + m_width *= sx; + m_height *= sy; +} + +void wxPseudoMetaFile::Translate(double x, double y) +{ + wxNode *node = m_ops.GetFirst(); + while (node) + { + wxDrawOp *op = (wxDrawOp *)node->GetData(); + op->Translate(x, y); + node = node->GetNext(); + } +} + +void wxPseudoMetaFile::Rotate(double x, double y, double theta) +{ + double theta1 = theta - m_currentRotation; + if (theta1 == 0.0) return; + double cosTheta = (double)cos(theta1); + double sinTheta = (double)sin(theta1); + + wxNode *node = m_ops.GetFirst(); + while (node) + { + wxDrawOp *op = (wxDrawOp *)node->GetData(); + op->Rotate(x, y, theta, sinTheta, cosTheta); + node = node->GetNext(); + } + m_currentRotation = theta; +} + +#if wxUSE_PROLOGIO +void wxPseudoMetaFile::WriteAttributes(wxExpr *clause, int whichAngle) +{ + wxString widthStr; + widthStr.Printf(wxT("meta_width%d"), whichAngle); + + wxString heightStr; + heightStr.Printf(wxT("meta_height%d"), whichAngle); + + wxString outlineStr; + outlineStr.Printf(wxT("outline_op%d"), whichAngle); + + wxString rotateableStr; + rotateableStr.Printf(wxT("meta_rotateable%d"), whichAngle); + + // Write width and height + clause->AddAttributeValue(widthStr, m_width); + clause->AddAttributeValue(heightStr, m_height); + clause->AddAttributeValue(rotateableStr, (long)m_rotateable); + clause->AddAttributeValue(outlineStr, (long)m_outlineOp); + + // Write GDI objects + wxChar buf[50]; + int i = 1; + wxNode *node = m_gdiObjects.GetFirst(); + while (node) + { + wxSprintf(buf, wxT("gdi%d_%d"), whichAngle, i); + wxObject *obj = (wxObject *)node->GetData(); + wxExpr *expr = NULL; + if (obj) + { + if (obj->IsKindOf(CLASSINFO(wxPen))) + { + wxPen *thePen = (wxPen *)obj; + expr = new wxExpr(wxExprList); + expr->Append(new wxExpr((long)gyTYPE_PEN)); + expr->Append(new wxExpr((long)thePen->GetWidth())); + expr->Append(new wxExpr((long)thePen->GetStyle())); + expr->Append(new wxExpr((long)thePen->GetColour().Red())); + expr->Append(new wxExpr((long)thePen->GetColour().Green())); + expr->Append(new wxExpr((long)thePen->GetColour().Blue())); + } + else if (obj->IsKindOf(CLASSINFO(wxBrush))) + { + wxBrush *theBrush = (wxBrush *)obj; + expr = new wxExpr(wxExprList); + expr->Append(new wxExpr((long)gyTYPE_BRUSH)); + expr->Append(new wxExpr((long)theBrush->GetStyle())); + expr->Append(new wxExpr((long)theBrush->GetColour().Red())); + expr->Append(new wxExpr((long)theBrush->GetColour().Green())); + expr->Append(new wxExpr((long)theBrush->GetColour().Blue())); + } + else if (obj->IsKindOf(CLASSINFO(wxFont))) + { + wxFont *theFont = (wxFont *)obj; + expr = new wxExpr(wxExprList); + expr->Append(new wxExpr((long)gyTYPE_FONT)); + expr->Append(new wxExpr((long)theFont->GetPointSize())); + expr->Append(new wxExpr((long)theFont->GetFamily())); + expr->Append(new wxExpr((long)theFont->GetStyle())); + expr->Append(new wxExpr((long)theFont->GetWeight())); + expr->Append(new wxExpr((long)theFont->GetUnderlined())); + } + } + else + { + // If no recognised GDI object, append a place holder anyway. + expr = new wxExpr(wxExprList); + expr->Append(new wxExpr((long)0)); + } + + if (expr) + { + clause->AddAttributeValue(buf, expr); + i ++; + } + node = node->GetNext(); + } + + // Write drawing operations + i = 1; + node = m_ops.GetFirst(); + while (node) + { + wxSprintf(buf, wxT("op%d_%d"), whichAngle, i); + wxDrawOp *op = (wxDrawOp *)node->GetData(); + wxExpr *expr = op->WriteExpr(this); + if (expr) + { + clause->AddAttributeValue(buf, expr); + i ++; + } + node = node->GetNext(); + } + + // Write outline and fill GDI op lists (if any) + if (m_outlineColours.GetCount() > 0) + { + wxExpr *outlineExpr = new wxExpr(wxExprList); + node = m_outlineColours.GetFirst(); + while (node) + { + outlineExpr->Append(new wxExpr((long)node->GetData())); + node = node->GetNext(); + } + wxString outlineObjectsStr; + outlineObjectsStr.Printf(wxT("outline_objects%d"), whichAngle); + + clause->AddAttributeValue(outlineObjectsStr, outlineExpr); + } + if (m_fillColours.GetCount() > 0) + { + wxExpr *fillExpr = new wxExpr(wxExprList); + node = m_fillColours.GetFirst(); + while (node) + { + fillExpr->Append(new wxExpr((long)node->GetData())); + node = node->GetNext(); + } + wxString fillObjectsStr; + fillObjectsStr.Printf(wxT("fill_objects%d"), whichAngle); + + clause->AddAttributeValue(fillObjectsStr, fillExpr); + } + +} + +void wxPseudoMetaFile::ReadAttributes(wxExpr *clause, int whichAngle) +{ + wxString widthStr; + widthStr.Printf(wxT("meta_width%d"), whichAngle); + + wxString heightStr; + heightStr.Printf(wxT("meta_height%d"), whichAngle); + + wxString outlineStr; + outlineStr.Printf(wxT("outline_op%d"), whichAngle); + + wxString rotateableStr; + rotateableStr.Printf(wxT("meta_rotateable%d"), whichAngle); + + clause->GetAttributeValue(widthStr, m_width); + clause->GetAttributeValue(heightStr, m_height); + clause->GetAttributeValue(outlineStr, m_outlineOp); + + int iVal = (int) m_rotateable; + clause->GetAttributeValue(rotateableStr, iVal); + m_rotateable = (iVal != 0); + + // Read GDI objects + wxChar buf[50]; + int i = 1; + bool keepGoing = TRUE; + while (keepGoing) + { + wxSprintf(buf, wxT("gdi%d_%d"), whichAngle, i); + wxExpr *expr = NULL; + clause->GetAttributeValue(buf, &expr); + if (!expr) + { + keepGoing = FALSE; + } + else + { + wxExpr *idExpr = expr->Nth(0); + switch (idExpr->IntegerValue()) + { + case gyTYPE_PEN: + { + int penWidth = (int)expr->Nth(1)->IntegerValue(); + int penStyle = (int)expr->Nth(2)->IntegerValue(); + int penRed = (int)expr->Nth(3)->IntegerValue(); + int penGreen = (int)expr->Nth(4)->IntegerValue(); + int penBlue = (int)expr->Nth(5)->IntegerValue(); + wxColour col(penRed, penGreen, penBlue); + wxPen *p = wxThePenList->FindOrCreatePen(col, penWidth, penStyle); + if (!p) + p = wxBLACK_PEN; + m_gdiObjects.Append(p); + break; + } + case gyTYPE_BRUSH: + { + int brushStyle = (int)expr->Nth(1)->IntegerValue(); + int brushRed = (int)expr->Nth(2)->IntegerValue(); + int brushGreen = (int)expr->Nth(3)->IntegerValue(); + int brushBlue = (int)expr->Nth(4)->IntegerValue(); + wxColour col(brushRed, brushGreen, brushBlue); + wxBrush *b = wxTheBrushList->FindOrCreateBrush(col, brushStyle); + if (!b) + b = wxWHITE_BRUSH; + m_gdiObjects.Append(b); + break; + } + case gyTYPE_FONT: + { + int fontPointSize = (int)expr->Nth(1)->IntegerValue(); + int fontFamily = (int)expr->Nth(2)->IntegerValue(); + int fontStyle = (int)expr->Nth(3)->IntegerValue(); + int fontWeight = (int)expr->Nth(4)->IntegerValue(); + int fontUnderlined = (int)expr->Nth(5)->IntegerValue(); + m_gdiObjects.Append(wxTheFontList->FindOrCreateFont(fontPointSize, + fontFamily, fontStyle, fontWeight, (fontUnderlined != 0))); + break; + } + default: + { + // Place holder + m_gdiObjects.Append(NULL); + break; + } + } + i ++; + } + } + + // Now read in the operations + keepGoing = TRUE; + i = 1; + while (keepGoing) + { + wxSprintf(buf, wxT("op%d_%d"), whichAngle, i); + wxExpr *expr = NULL; + clause->GetAttributeValue(buf, &expr); + if (!expr) + { + keepGoing = FALSE; + } + else + { + wxExpr *idExpr = expr->Nth(0); + int opId = (int)idExpr->IntegerValue(); + switch (opId) + { + case DRAWOP_SET_PEN: + case DRAWOP_SET_BRUSH: + case DRAWOP_SET_FONT: + case DRAWOP_SET_TEXT_COLOUR: + case DRAWOP_SET_BK_COLOUR: + case DRAWOP_SET_BK_MODE: + { + wxOpSetGDI *theOp = new wxOpSetGDI(opId, this, 0); + theOp->ReadExpr(this, expr); + m_ops.Append(theOp); + break; + } + + case DRAWOP_SET_CLIPPING_RECT: + case DRAWOP_DESTROY_CLIPPING_RECT: + { + wxOpSetClipping *theOp = new wxOpSetClipping(opId, 0.0, 0.0, 0.0, 0.0); + theOp->ReadExpr(this, expr); + m_ops.Append(theOp); + break; + } + + case DRAWOP_DRAW_LINE: + case DRAWOP_DRAW_RECT: + case DRAWOP_DRAW_ROUNDED_RECT: + case DRAWOP_DRAW_ELLIPSE: + case DRAWOP_DRAW_POINT: + case DRAWOP_DRAW_ARC: + case DRAWOP_DRAW_TEXT: + { + wxOpDraw *theOp = new wxOpDraw(opId, 0.0, 0.0, 0.0, 0.0); + theOp->ReadExpr(this, expr); + m_ops.Append(theOp); + break; + } + case DRAWOP_DRAW_SPLINE: + case DRAWOP_DRAW_POLYLINE: + case DRAWOP_DRAW_POLYGON: + { + wxOpPolyDraw *theOp = new wxOpPolyDraw(opId, 0, NULL); + theOp->ReadExpr(this, expr); + m_ops.Append(theOp); + break; + } + default: + break; + } + } + i ++; + } + + wxString outlineObjectsStr; + outlineObjectsStr.Printf(wxT("outline_objects%d"), whichAngle); + + // Now read in the list of outline and fill operations, if any + wxExpr *expr1 = clause->AttributeValue(outlineObjectsStr); + if (expr1) + { + wxExpr *eachExpr = expr1->GetFirst(); + while (eachExpr) + { + m_outlineColours.Append((wxObject *)eachExpr->IntegerValue()); + eachExpr = eachExpr->GetNext(); + } + } + + wxString fillObjectsStr; + fillObjectsStr.Printf(wxT("fill_objects%d"), whichAngle); + + expr1 = clause->AttributeValue(fillObjectsStr); + if (expr1) + { + wxExpr *eachExpr = expr1->GetFirst(); + while (eachExpr) + { + m_fillColours.Append((wxObject *)eachExpr->IntegerValue()); + eachExpr = eachExpr->GetNext(); + } + } +} +#endif + +// Does the copying for this object +void wxPseudoMetaFile::Copy(wxPseudoMetaFile ©) +{ + copy.Clear(); + + copy.m_currentRotation = m_currentRotation; + copy.m_width = m_width; + copy.m_height = m_height; + copy.m_rotateable = m_rotateable; + copy.m_fillBrush = m_fillBrush; + copy.m_outlinePen = m_outlinePen; + copy.m_outlineOp = m_outlineOp; + + // Copy the GDI objects + wxNode *node = m_gdiObjects.GetFirst(); + while (node) + { + wxObject *obj = (wxObject *)node->GetData(); + copy.m_gdiObjects.Append(obj); + node = node->GetNext(); + } + + // Copy the operations + node = m_ops.GetFirst(); + while (node) + { + wxDrawOp *op = (wxDrawOp *)node->GetData(); + copy.m_ops.Append(op->Copy(©)); + node = node->GetNext(); + } + + // Copy the outline/fill operations + node = m_outlineColours.GetFirst(); + while (node) + { + copy.m_outlineColours.Append((wxObject *)node->GetData()); + node = node->GetNext(); + } + node = m_fillColours.GetFirst(); + while (node) + { + copy.m_fillColours.Append((wxObject *)node->GetData()); + node = node->GetNext(); + } +} + +/* + * Pass size of existing image; scale height to + * fit width and return new width and height. + * + */ + +bool wxPseudoMetaFile::LoadFromMetaFile(const wxString &filename, double *rwidth, double *rheight) +{ + if (!wxFileExists(filename)) + return FALSE; + + wxXMetaFile *metaFile = new wxXMetaFile; + + if (!metaFile->ReadFile(filename)) + { + delete metaFile; + return FALSE; + } + + double lastX = 0.0; + double lastY = 0.0; + + // Convert from metafile records to wxDrawnShape records + wxNode *node = metaFile->metaRecords.GetFirst(); + while (node) + { + wxMetaRecord *record = (wxMetaRecord *)node->GetData(); + switch (record->metaFunction) + { + case META_SETBKCOLOR: + { + wxOpSetGDI *op = new wxOpSetGDI(DRAWOP_SET_BK_COLOUR, this, 0); + op->m_r = (unsigned char)record->param1; + op->m_g = (unsigned char)record->param2; + op->m_b = (unsigned char)record->param3; + m_ops.Append(op); + break; + } + case META_SETBKMODE: + { + wxOpSetGDI *op = new wxOpSetGDI(DRAWOP_SET_BK_MODE, this, 0, (int)record->param1); + m_ops.Append(op); + break; + } + case META_SETMAPMODE: + { + break; + } +// case META_SETROP2: +// case META_SETRELABS: +// case META_SETPOLYFILLMODE: +// case META_SETSTRETCHBLTMODE: +// case META_SETTEXTCHAREXTRA: + case META_SETTEXTCOLOR: + { + wxOpSetGDI *op = new wxOpSetGDI(DRAWOP_SET_TEXT_COLOUR, this, 0); + op->m_r = (unsigned char)record->param1; + op->m_g = (unsigned char)record->param2; + op->m_b = (unsigned char)record->param3; + m_ops.Append(op); + break; + } +// case META_SETTEXTJUSTIFICATION: +// case META_SETWINDOWORG: +// case META_SETWINDOWEXT: +// case META_SETVIEWPORTORG: +// case META_SETVIEWPORTEXT: +// case META_OFFSETWINDOWORG: +// case META_SCALEWINDOWEXT: +// case META_OFFSETVIEWPORTORG: +// case META_SCALEVIEWPORTEXT: + case META_LINETO: + { + wxOpDraw *op = new wxOpDraw(DRAWOP_DRAW_LINE, (double)lastX, (double)lastY, + (double)record->param1, (double)record->param2); + m_ops.Append(op); + break; + } + case META_MOVETO: + { + lastX = (double)record->param1; + lastY = (double)record->param2; + break; + } + case META_EXCLUDECLIPRECT: + { + /* + wxMetaRecord *rec = new wxMetaRecord(META_EXCLUDECLIPRECT); + rec->param4 = getshort(handle); // m_y2 + rec->param3 = getshort(handle); // x2 + rec->param2 = getshort(handle); // y1 + rec->param1 = getshort(handle); // x1 + */ + break; + } + case META_INTERSECTCLIPRECT: + { + /* + rec->param4 = getshort(handle); // m_y2 + rec->param3 = getshort(handle); // x2 + rec->param2 = getshort(handle); // y1 + rec->param1 = getshort(handle); // x1 + */ + break; + } +// case META_ARC: // DO!!! + case META_ELLIPSE: + { + wxOpDraw *op = new wxOpDraw(DRAWOP_DRAW_ELLIPSE, + (double)record->param1, (double)record->param2, + (double)(record->param3 - record->param1), + (double)(record->param4 - record->param2)); + m_ops.Append(op); + break; + } +// case META_FLOODFILL: +// case META_PIE: // DO!!! + case META_RECTANGLE: + { + wxOpDraw *op = new wxOpDraw(DRAWOP_DRAW_RECT, + (double)record->param1, (double)record->param2, + (double)(record->param3 - record->param1), + (double)(record->param4 - record->param2)); + m_ops.Append(op); + break; + } + case META_ROUNDRECT: + { + wxOpDraw *op = new wxOpDraw(DRAWOP_DRAW_ROUNDED_RECT, + (double)record->param1, (double)record->param2, + (double)(record->param3 - record->param1), + (double)(record->param4 - record->param2), (double)record->param5); + m_ops.Append(op); + break; + } +// case META_PATBLT: +// case META_SAVEDC: + case META_SETPIXEL: + { + wxOpDraw *op = new wxOpDraw(DRAWOP_DRAW_POINT, + (double)record->param1, (double)record->param2, + 0.0, 0.0); + +// SHOULD SET THE COLOUR - SET PEN? +// rec->param3 = getint(handle); // COLORREF + m_ops.Append(op); + break; + } +// case META_OFFSETCLIPRGN: + case META_TEXTOUT: + { + wxOpDraw *op = new wxOpDraw(DRAWOP_DRAW_TEXT, + (double)record->param1, (double)record->param2, + 0.0, 0.0, 0.0, record->stringParam); + m_ops.Append(op); + break; + } +// case META_BITBLT: +// case META_STRETCHBLT: + case META_POLYGON: + { + int n = (int)record->param1; + wxRealPoint *newPoints = new wxRealPoint[n]; + for (int i = 0; i < n; i++) + { + newPoints[i].x = record->points[i].x; + newPoints[i].y = record->points[i].y; + } + + wxOpPolyDraw *op = new wxOpPolyDraw(DRAWOP_DRAW_POLYGON, n, newPoints); + m_ops.Append(op); + break; + } + case META_POLYLINE: + { + int n = (int)record->param1; + wxRealPoint *newPoints = new wxRealPoint[n]; + for (int i = 0; i < n; i++) + { + newPoints[i].x = record->points[i].x; + newPoints[i].y = record->points[i].y; + } + + wxOpPolyDraw *op = new wxOpPolyDraw(DRAWOP_DRAW_POLYLINE, n, newPoints); + m_ops.Append(op); + break; + } +// case META_ESCAPE: +// case META_RESTOREDC: +// case META_FILLREGION: +// case META_FRAMEREGION: +// case META_INVERTREGION: +// case META_PAINTREGION: +// case META_SELECTCLIPREGION: // DO THIS! + case META_SELECTOBJECT: + { + // The pen, brush etc. has already been created when the metafile + // was read in, so we don't create it - we set it. + wxNode *recNode = metaFile->gdiObjects.Item((int)record->param2); + if (recNode) + { + wxMetaRecord *gdiRec = (wxMetaRecord *)recNode->GetData(); + if (gdiRec && (gdiRec->param1 != 0)) + { + wxObject *obj = (wxObject *)gdiRec->param1; + if (obj->IsKindOf(CLASSINFO(wxPen))) + { + wxOpSetGDI *op = new wxOpSetGDI(DRAWOP_SET_PEN, this, (int)record->param2); + m_ops.Append(op); + } + else if (obj->IsKindOf(CLASSINFO(wxBrush))) + { + wxOpSetGDI *op = new wxOpSetGDI(DRAWOP_SET_BRUSH, this, (int)record->param2); + m_ops.Append(op); + } + else if (obj->IsKindOf(CLASSINFO(wxFont))) + { + wxOpSetGDI *op = new wxOpSetGDI(DRAWOP_SET_FONT, this, (int)record->param2); + m_ops.Append(op); + } + } + } + break; + } +// case META_SETTEXTALIGN: +// case META_DRAWTEXT: +// case META_CHORD: +// case META_SETMAPPERFLAGS: +// case META_EXTTEXTOUT: +// case META_SETDIBTODEV: +// case META_SELECTPALETTE: +// case META_REALIZEPALETTE: +// case META_ANIMATEPALETTE: +// case META_SETPALENTRIES: +// case META_POLYPOLYGON: +// case META_RESIZEPALETTE: +// case META_DIBBITBLT: +// case META_DIBSTRETCHBLT: + case META_DIBCREATEPATTERNBRUSH: + { + // Place holder + m_gdiObjects.Append(NULL); + break; + } +// case META_STRETCHDIB: +// case META_EXTFLOODFILL: +// case META_RESETDC: +// case META_STARTDOC: +// case META_STARTPAGE: +// case META_ENDPAGE: +// case META_ABORTDOC: +// case META_ENDDOC: +// case META_DELETEOBJECT: // DO!! + case META_CREATEPALETTE: + { + // Place holder + m_gdiObjects.Append(NULL); + break; + } + case META_CREATEBRUSH: + { + // Place holder + m_gdiObjects.Append(NULL); + break; + } + case META_CREATEPATTERNBRUSH: + { + // Place holder + m_gdiObjects.Append(NULL); + break; + } + case META_CREATEPENINDIRECT: + { + // The pen is created when the metafile is read in. + // We keep track of all the GDI objects needed for this + // image so when reading the wxDrawnShape from file, + // we can read in all the GDI objects, then refer + // to them by an index starting from zero thereafter. + m_gdiObjects.Append((wxObject *)record->param1); + break; + } + case META_CREATEFONTINDIRECT: + { + m_gdiObjects.Append((wxObject *)record->param1); + break; + } + case META_CREATEBRUSHINDIRECT: + { + // Don't have to do anything here: the pen is created + // when the metafile is read in. + m_gdiObjects.Append((wxObject *)record->param1); + break; + } + case META_CREATEBITMAPINDIRECT: + { + // Place holder + m_gdiObjects.Append(NULL); + break; + } + case META_CREATEBITMAP: + { + // Place holder + m_gdiObjects.Append(NULL); + break; + } + case META_CREATEREGION: + { + // Place holder + m_gdiObjects.Append(NULL); + break; + } + default: + { + break; + } + } + node = node->GetNext(); + } + double actualWidth = (double)fabs(metaFile->right - metaFile->left); + double actualHeight = (double)fabs(metaFile->bottom - metaFile->top); + + double initialScaleX = 1.0; + double initialScaleY = 1.0; + + double xoffset, yoffset; + + // Translate so origin is at centre of rectangle + if (metaFile->bottom > metaFile->top) + yoffset = - (double)((metaFile->bottom - metaFile->top) / 2.0); + else + yoffset = - (double)((metaFile->top - metaFile->bottom) / 2.0); + + if (metaFile->right > metaFile->left) + xoffset = - (double)((metaFile->right - metaFile->left) / 2.0); + else + xoffset = - (double)((metaFile->left - metaFile->right) / 2.0); + + Translate(xoffset, yoffset); + + // Scale to a reasonable size (take the width of this wxDrawnShape + // as a guide) + if (actualWidth != 0.0) + { + initialScaleX = (double)((*rwidth) / actualWidth); + initialScaleY = initialScaleX; + (*rheight) = initialScaleY * actualHeight; + } + Scale(initialScaleX, initialScaleY); + + m_width = (actualWidth * initialScaleX); + m_height = *rheight; + + delete metaFile; + return TRUE; +} + +// Scale to fit size +void wxPseudoMetaFile::ScaleTo(double w, double h) +{ + double scaleX = (double)(w / m_width); + double scaleY = (double)(h / m_height); + + // Do the scaling + Scale(scaleX, scaleY); +} + +void wxPseudoMetaFile::GetBounds(double *boundMinX, double *boundMinY, double *boundMaxX, double *boundMaxY) +{ + double maxX = (double) - 99999.9; + double maxY = (double) - 99999.9; + double minX = (double) 99999.9; + double minY = (double) 99999.9; + + wxNode *node = m_ops.GetFirst(); + while (node) + { + wxDrawOp *op = (wxDrawOp *)node->GetData(); + switch (op->GetOp()) + { + case DRAWOP_DRAW_LINE: + case DRAWOP_DRAW_RECT: + case DRAWOP_DRAW_ROUNDED_RECT: + case DRAWOP_DRAW_ELLIPSE: + case DRAWOP_DRAW_POINT: + case DRAWOP_DRAW_TEXT: + { + wxOpDraw *opDraw = (wxOpDraw *)op; + if (opDraw->m_x1 < minX) minX = opDraw->m_x1; + if (opDraw->m_x1 > maxX) maxX = opDraw->m_x1; + if (opDraw->m_y1 < minY) minY = opDraw->m_y1; + if (opDraw->m_y1 > maxY) maxY = opDraw->m_y1; + if (op->GetOp() == DRAWOP_DRAW_LINE) + { + if (opDraw->m_x2 < minX) minX = opDraw->m_x2; + if (opDraw->m_x2 > maxX) maxX = opDraw->m_x2; + if (opDraw->m_y2 < minY) minY = opDraw->m_y2; + if (opDraw->m_y2 > maxY) maxY = opDraw->m_y2; + } + else if (op->GetOp() == DRAWOP_DRAW_RECT || + op->GetOp() == DRAWOP_DRAW_ROUNDED_RECT || + op->GetOp() == DRAWOP_DRAW_ELLIPSE) + { + if ((opDraw->m_x1 + opDraw->m_x2) < minX) minX = (opDraw->m_x1 + opDraw->m_x2); + if ((opDraw->m_x1 + opDraw->m_x2) > maxX) maxX = (opDraw->m_x1 + opDraw->m_x2); + if ((opDraw->m_y1 + opDraw->m_y2) < minY) minY = (opDraw->m_y1 + opDraw->m_y2); + if ((opDraw->m_y1 + opDraw->m_y2) > maxY) maxY = (opDraw->m_y1 + opDraw->m_y2); + } + break; + } + case DRAWOP_DRAW_ARC: + { + // TODO: don't yet know how to calculate the bounding box + // for an arc. So pretend it's a line; to get a correct + // bounding box, draw a blank rectangle first, of the correct + // size. + wxOpDraw *opDraw = (wxOpDraw *)op; + if (opDraw->m_x1 < minX) minX = opDraw->m_x1; + if (opDraw->m_x1 > maxX) maxX = opDraw->m_x1; + if (opDraw->m_y1 < minY) minY = opDraw->m_y1; + if (opDraw->m_y1 > maxY) maxY = opDraw->m_y1; + if (opDraw->m_x2 < minX) minX = opDraw->m_x2; + if (opDraw->m_x2 > maxX) maxX = opDraw->m_x2; + if (opDraw->m_y2 < minY) minY = opDraw->m_y2; + if (opDraw->m_y2 > maxY) maxY = opDraw->m_y2; + break; + } + case DRAWOP_DRAW_POLYLINE: + case DRAWOP_DRAW_POLYGON: + case DRAWOP_DRAW_SPLINE: + { + wxOpPolyDraw *poly = (wxOpPolyDraw *)op; + for (int i = 0; i < poly->m_noPoints; i++) + { + if (poly->m_points[i].x < minX) minX = poly->m_points[i].x; + if (poly->m_points[i].x > maxX) maxX = poly->m_points[i].x; + if (poly->m_points[i].y < minY) minY = poly->m_points[i].y; + if (poly->m_points[i].y > maxY) maxY = poly->m_points[i].y; + } + break; + } + default: + break; + } + node = node->GetNext(); + } + + *boundMinX = minX; + *boundMinY = minY; + *boundMaxX = maxX; + *boundMaxY = maxY; + /* + *w = (double)fabs(maxX - minX); + *h = (double)fabs(maxY - minY); + */ +} + +// Calculate size from current operations +void wxPseudoMetaFile::CalculateSize(wxDrawnShape *shape) +{ + double boundMinX, boundMinY, boundMaxX, boundMaxY; + + GetBounds(& boundMinX, & boundMinY, & boundMaxX, & boundMaxY); + + SetSize(boundMaxX - boundMinX, boundMaxY - boundMinY); + + if (shape) + { + shape->SetWidth(m_width); + shape->SetHeight(m_height); + } +} + +// Set of functions for drawing into a pseudo metafile. +// They use integers, but doubles are used internally for accuracy +// when scaling. + +void wxPseudoMetaFile::DrawLine(const wxPoint &pt1, const wxPoint &pt2) +{ + wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_LINE, + (double) pt1.x, (double) pt1.y, (double) pt2.x, (double) pt2.y); + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::DrawRectangle(const wxRect &rect) +{ + wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_RECT, + (double) rect.x, (double) rect.y, (double) rect.width, (double) rect.height); + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::DrawRoundedRectangle(const wxRect &rect, double radius) +{ + wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_ROUNDED_RECT, + (double) rect.x, (double) rect.y, (double) rect.width, (double) rect.height); + + theOp->m_radius = radius; + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::DrawEllipse(const wxRect &rect) +{ + wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_ELLIPSE, + (double) rect.x, (double) rect.y, (double) rect.width, (double) rect.height); + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::DrawArc(const wxPoint ¢rePt, const wxPoint &startPt, const wxPoint &endPt) +{ + wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_ARC, + (double) centrePt.x, (double) centrePt.y, (double) startPt.x, (double) startPt.y); + + theOp->m_x3 = (double) endPt.x; + theOp->m_y3 = (double) endPt.y; + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::DrawEllipticArc(const wxRect &rect, double startAngle, double endAngle) +{ + const double pi = 3.1415926535897932384626433832795 ; + + double startAngleRadians = startAngle * (pi * 2.0 / 360.0); + double endAngleRadians = endAngle * (pi * 2.0 / 360.0); + + wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_ELLIPTIC_ARC, + (double) rect.x, (double) rect.y, (double) rect.width, (double) rect.height); + + theOp->m_x3 = startAngleRadians; + theOp->m_y3 = endAngleRadians; + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::DrawPoint(const wxPoint &pt) +{ + wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_POINT, + (double) pt.x, (double) pt.y, 0.0, 0.0); + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::DrawText(const wxString &text, const wxPoint &pt) +{ + wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_TEXT, + (double) pt.x, (double) pt.y, 0.0, 0.0); + + theOp->m_textString = oglCopystring(text); + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::DrawLines(int n, wxPoint pts[]) +{ + wxRealPoint *realPoints = new wxRealPoint[n]; + int i; + for (i = 0; i < n; i++) + { + realPoints[i].x = pts[i].x; + realPoints[i].y = pts[i].y; + } + wxOpPolyDraw *theOp = new wxOpPolyDraw(DRAWOP_DRAW_POLYLINE, n, realPoints); + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::DrawPolygon(int n, wxPoint pts[], int flags) +{ + wxRealPoint *realPoints = new wxRealPoint[n]; + int i; + for (i = 0; i < n; i++) + { + realPoints[i].x = pts[i].x; + realPoints[i].y = pts[i].y; + } + wxOpPolyDraw *theOp = new wxOpPolyDraw(DRAWOP_DRAW_POLYGON, n, realPoints); + m_ops.Append(theOp); + + if (flags & oglMETAFLAGS_OUTLINE) + m_outlineOp = (m_ops.GetCount() - 1); +} + +void wxPseudoMetaFile::DrawSpline(int n, wxPoint pts[]) +{ + wxRealPoint *realPoints = new wxRealPoint[n]; + int i; + for (i = 0; i < n; i++) + { + realPoints[i].x = pts[i].x; + realPoints[i].y = pts[i].y; + } + wxOpPolyDraw *theOp = new wxOpPolyDraw(DRAWOP_DRAW_SPLINE, n, realPoints); + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::SetClippingRect(const wxRect &rect) +{ + /* wxOpSetClipping* theOp = */ new wxOpSetClipping(DRAWOP_SET_CLIPPING_RECT, + (double) rect.x, (double) rect.y, (double) rect.width, (double) rect.height); +} + +void wxPseudoMetaFile::DestroyClippingRect() +{ + wxOpSetClipping *theOp = new wxOpSetClipping(DRAWOP_DESTROY_CLIPPING_RECT, + 0.0, 0.0, 0.0, 0.0); + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::SetPen(wxPen *pen, bool isOutline) +{ + m_gdiObjects.Append(pen); + int n = m_gdiObjects.GetCount(); + + wxOpSetGDI *theOp = new wxOpSetGDI(DRAWOP_SET_PEN, this, n - 1); + + m_ops.Append(theOp); + + if (isOutline) + { + m_outlineColours.Append((wxObject *) (n - 1)); + } +} + +void wxPseudoMetaFile::SetBrush(wxBrush *brush, bool isFill) +{ + m_gdiObjects.Append(brush); + int n = m_gdiObjects.GetCount(); + + wxOpSetGDI *theOp = new wxOpSetGDI(DRAWOP_SET_BRUSH, this, n - 1); + + m_ops.Append(theOp); + + if (isFill) + { + m_fillColours.Append((wxObject *) (n - 1)); + } +} + +void wxPseudoMetaFile::SetFont(wxFont *font) +{ + m_gdiObjects.Append(font); + int n = m_gdiObjects.GetCount(); + + wxOpSetGDI *theOp = new wxOpSetGDI(DRAWOP_SET_FONT, this, n - 1); + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::SetTextColour(const wxColour &colour) +{ + wxOpSetGDI *theOp = new wxOpSetGDI(DRAWOP_SET_TEXT_COLOUR, this, 0); + theOp->m_r = colour.Red(); + theOp->m_g = colour.Green(); + theOp->m_b = colour.Blue(); + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::SetBackgroundColour(const wxColour &colour) +{ + wxOpSetGDI *theOp = new wxOpSetGDI(DRAWOP_SET_BK_COLOUR, this, 0); + theOp->m_r = colour.Red(); + theOp->m_g = colour.Green(); + theOp->m_b = colour.Blue(); + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::SetBackgroundMode(int mode) +{ + wxOpSetGDI *theOp = new wxOpSetGDI(DRAWOP_SET_BK_MODE, this, 0, mode); + + m_ops.Append(theOp); +} + diff --git a/ogl/lines.cpp b/ogl/lines.cpp new file mode 100644 index 0000000..a13a0c6 --- /dev/null +++ b/ogl/lines.cpp @@ -0,0 +1,2498 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// lines.cpp - wxLineShape +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include +#include + +#include "ogl/ogl.h" + + +// Line shape +IMPLEMENT_DYNAMIC_CLASS(wxLineShape, wxShape) + +wxLineShape::wxLineShape() +{ + m_sensitivity = OP_CLICK_LEFT | OP_CLICK_RIGHT; + m_draggable = FALSE; + m_attachmentTo = 0; + m_attachmentFrom = 0; + /* + m_actualTextWidth = 0.0; + m_actualTextHeight = 0.0; + */ + m_from = NULL; + m_to = NULL; + m_erasing = FALSE; + m_arrowSpacing = 5.0; // For the moment, don't bother saving this to file. + m_ignoreArrowOffsets = FALSE; + m_isSpline = FALSE; + m_maintainStraightLines = FALSE; + m_alignmentStart = 0; + m_alignmentEnd = 0; + + m_lineControlPoints = NULL; + + // Clear any existing regions (created in an earlier constructor) + // and make the three line regions. + ClearRegions(); + wxShapeRegion *newRegion = new wxShapeRegion; + newRegion->SetName(wxT("Middle")); + newRegion->SetSize(150, 50); + m_regions.Append((wxObject *)newRegion); + + newRegion = new wxShapeRegion; + newRegion->SetName(wxT("Start")); + newRegion->SetSize(150, 50); + m_regions.Append((wxObject *)newRegion); + + newRegion = new wxShapeRegion; + newRegion->SetName(wxT("End")); + newRegion->SetSize(150, 50); + m_regions.Append((wxObject *)newRegion); + + for (int i = 0; i < 3; i++) + m_labelObjects[i] = NULL; +} + +wxLineShape::~wxLineShape() +{ + if (m_lineControlPoints) + { + ClearPointList(*m_lineControlPoints); + delete m_lineControlPoints; + } + ClearArrowsAtPosition(-1); + + for (int i = 0; i < 3; i++) + { + if (m_labelObjects[i]) + { + if (m_labelObjects[i]->Selected() && m_canvas) + m_labelObjects[i]->Select(FALSE); + if (m_canvas) + m_labelObjects[i]->RemoveFromCanvas(m_canvas); + delete m_labelObjects[i]; + m_labelObjects[i] = NULL; + } + } +} + +// Remove any child shapes before deleting shape. +void wxLineShape::RemoveChildren() +{ + for (int i = 0; i < 3; i++) + { + if (m_labelObjects[i]) + { + if (m_labelObjects[i]->Selected() && m_canvas) + m_labelObjects[i]->Select(FALSE); + if (m_canvas) + m_labelObjects[i]->RemoveFromCanvas(m_canvas); + } + } +} + +void wxLineShape::SetCanvas(wxShapeCanvas *the_canvas) +{ + wxShape::SetCanvas(the_canvas); + + for (int i = 0; i < 3; i++) + { + if (m_labelObjects[i]) + { + m_labelObjects[i]->SetCanvas(the_canvas); + } + } +} + +void wxLineShape::MakeLineControlPoints(int n) +{ + if (m_lineControlPoints) + { + ClearPointList(*m_lineControlPoints); + delete m_lineControlPoints; + } + m_lineControlPoints = new wxList; + + for (int i = 0; i < n; i++) + { + wxRealPoint *point = new wxRealPoint(-999, -999); + m_lineControlPoints->Append((wxObject *) point); + } +} + +wxNode *wxLineShape::InsertLineControlPoint() +{ + Refresh(); + + wxNode *last = m_lineControlPoints->GetLast(); + wxNode *second_last = last->GetPrevious(); + wxRealPoint *last_point = (wxRealPoint *)last->GetData(); + wxRealPoint *second_last_point = (wxRealPoint *)second_last->GetData(); + + // Choose a point half way between the last and penultimate points + double line_x = ((last_point->x + second_last_point->x) / 2); + double line_y = ((last_point->y + second_last_point->y) / 2); + + wxRealPoint *point = new wxRealPoint(line_x, line_y); + wxNode *node = m_lineControlPoints->Insert(last, (wxObject *) point); + + Refresh(); + + return node; +} + +bool wxLineShape::DeleteLineControlPoint() +{ + if (m_lineControlPoints->GetCount() < 3) + return FALSE; + + wxNode *last = m_lineControlPoints->GetLast(); + wxNode *second_last = last->GetPrevious(); + + wxRealPoint *second_last_point = (wxRealPoint *)second_last->GetData(); + delete second_last_point; + delete second_last; + + return TRUE; +} + +void wxLineShape::Initialise() +{ + if (m_lineControlPoints) + { + // Just move the first and last control points + wxNode *first = m_lineControlPoints->GetFirst(); + wxRealPoint *first_point = (wxRealPoint *)first->GetData(); + + wxNode *last = m_lineControlPoints->GetLast(); + wxRealPoint *last_point = (wxRealPoint *)last->GetData(); + + // If any of the line points are at -999, we must + // initialize them by placing them half way between the first + // and the last. + wxNode *node = first->GetNext(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + if (point->x == -999) + { + double x1, y1, x2, y2; + if (first_point->x < last_point->x) + { + x1 = first_point->x; + x2 = last_point->x; + } + else + { + x2 = first_point->x; + x1 = last_point->x; + } + + if (first_point->y < last_point->y) + { + y1 = first_point->y; + y2 = last_point->y; + } + else + { + y2 = first_point->y; + y1 = last_point->y; + } + + point->x = ((x2 - x1) / 2 + x1); + point->y = ((y2 - y1) / 2 + y1); + } + node = node->GetNext(); + } + } +} + +// Format a text string according to the region size, adding +// strings with positions to region text list +void wxLineShape::FormatText(wxDC &dc, const wxString &s, int i) +{ + double w, h; + ClearText(i); + + if (m_regions.GetCount() < 1) + return; + wxNode *node = m_regions.Item(i); + if (!node) + return; + + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + region->SetText(s); + dc.SetFont(* region->GetFont()); + + region->GetSize(&w, &h); + // Initialize the size if zero + if (((w == 0) || (h == 0)) && (s.Length() > 0)) + { + w = 100; + h = 50; + region->SetSize(w, h); + } + + wxArrayString *string_list = oglFormatText(dc, s, (w - 5), (h - 5), region->GetFormatMode()); + size_t j; + for (j = 0; j < string_list->GetCount(); j++) + { + const wxString &s = (*string_list)[j]; + wxShapeTextLine *line = new wxShapeTextLine(0.0, 0.0, s); + region->GetFormattedText().Append((wxObject *)line); + } + delete string_list; + double actualW = w; + double actualH = h; + if (region->GetFormatMode() & FORMAT_SIZE_TO_CONTENTS) + { + oglGetCentredTextExtent(dc, &(region->GetFormattedText()), m_xpos, m_ypos, w, h, &actualW, &actualH); + if ((actualW != w ) || (actualH != h)) + { + double xx, yy; + GetLabelPosition(i, &xx, &yy); + if (m_labelObjects[i]) + { + m_labelObjects[i]->Select(FALSE); + m_labelObjects[i]->SetSize(actualW, actualH); + } + + region->SetSize(actualW, actualH); + + if (m_labelObjects[i]) + { + m_labelObjects[i]->Select(TRUE); + m_labelObjects[i]->Draw(dc); + } + } + } + oglCentreText(dc, &(region->GetFormattedText()), m_xpos, m_ypos, actualW, actualH, region->GetFormatMode()); + m_formatted = TRUE; +} + +void wxLineShape::DrawRegion(wxDC &dc, wxShapeRegion *region, double x, double y) +{ + if (GetDisableLabel()) + return; + + double w, h; + double xx, yy; + region->GetSize(&w, &h); + + // Get offset from x, y + region->GetPosition(&xx, &yy); + + double xp = xx + x; + double yp = yy + y; + + // First, clear a rectangle for the text IF there is any + if (region->GetFormattedText().GetCount() > 0) + { + dc.SetPen(GetBackgroundPen()); + dc.SetBrush(GetBackgroundBrush()); + + // Now draw the text + if (region->GetFont()) dc.SetFont(* region->GetFont()); + + dc.DrawRectangle((long)(xp - w / 2.0), (long)(yp - h / 2.0), (long)w, (long)h); + + if (m_pen) dc.SetPen(* m_pen); + dc.SetTextForeground(region->GetActualColourObject()); + +#ifdef __WXMSW__ + dc.SetTextBackground(GetBackgroundBrush().GetColour()); +#endif + + oglDrawFormattedText(dc, &(region->GetFormattedText()), xp, yp, w, h, region->GetFormatMode()); + } +} + +// Get the reference point for a label. Region x and y +// are offsets from this. +// position is 0, 1, 2 +void wxLineShape::GetLabelPosition(int position, double *x, double *y) +{ + switch (position) + { + case 0: + { + // Want to take the middle section for the label + int n = m_lineControlPoints->GetCount(); + int half_way = (int)(n / 2); + + // Find middle of this line + wxNode *node = m_lineControlPoints->Item(half_way - 1); + wxRealPoint *point = (wxRealPoint *)node->GetData(); + wxNode *next_node = node->GetNext(); + wxRealPoint *next_point = (wxRealPoint *)next_node->GetData(); + + double dx = (next_point->x - point->x); + double dy = (next_point->y - point->y); + *x = (double)(point->x + dx / 2.0); + *y = (double)(point->y + dy / 2.0); + break; + } + case 1: + { + wxNode *node = m_lineControlPoints->GetFirst(); + *x = ((wxRealPoint *)node->GetData())->x; + *y = ((wxRealPoint *)node->GetData())->y; + break; + } + case 2: + { + wxNode *node = m_lineControlPoints->GetLast(); + *x = ((wxRealPoint *)node->GetData())->x; + *y = ((wxRealPoint *)node->GetData())->y; + break; + } + default: + break; + } +} + +/* + * Find whether line is supposed to be vertical or horizontal and + * make it so. + * + */ +void GraphicsStraightenLine(wxRealPoint *point1, wxRealPoint *point2) +{ + double dx = point2->x - point1->x; + double dy = point2->y - point1->y; + + if (dx == 0.0) + return; + else if (fabs(dy / dx) > 1.0) + { + point2->x = point1->x; + } + else point2->y = point1->y; +} + +void wxLineShape::Straighten() +{ + if (!m_lineControlPoints || m_lineControlPoints->GetCount() < 3) + return; + + Refresh(); + + wxNode *first_point_node = m_lineControlPoints->GetFirst(); + wxNode *last_point_node = m_lineControlPoints->GetLast(); + wxNode *second_last_point_node = last_point_node->GetPrevious(); + + wxRealPoint *last_point = (wxRealPoint *)last_point_node->GetData(); + wxRealPoint *second_last_point = (wxRealPoint *)second_last_point_node->GetData(); + + GraphicsStraightenLine(last_point, second_last_point); + + wxNode *node = first_point_node; + while (node && (node != second_last_point_node)) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + wxRealPoint *next_point = (wxRealPoint *)(node->GetNext()->GetData()); + + GraphicsStraightenLine(point, next_point); + node = node->GetNext(); + } + + Refresh(); +} + + +void wxLineShape::Unlink() +{ + if (m_to) + m_to->GetLines().DeleteObject(this); + if (m_from) + m_from->GetLines().DeleteObject(this); + m_to = NULL; + m_from = NULL; +} + +void wxLineShape::SetEnds(double x1, double y1, double x2, double y2) +{ + // Find centre point + wxNode *first_point_node = m_lineControlPoints->GetFirst(); + wxNode *last_point_node = m_lineControlPoints->GetLast(); + wxRealPoint *first_point = (wxRealPoint *)first_point_node->GetData(); + wxRealPoint *last_point = (wxRealPoint *)last_point_node->GetData(); + + first_point->x = x1; + first_point->y = y1; + last_point->x = x2; + last_point->y = y2; + + m_xpos = (double)((x1 + x2) / 2.0); + m_ypos = (double)((y1 + y2) / 2.0); +} + +// Get absolute positions of ends +void wxLineShape::GetEnds(double *x1, double *y1, double *x2, double *y2) +{ + wxNode *first_point_node = m_lineControlPoints->GetFirst(); + wxNode *last_point_node = m_lineControlPoints->GetLast(); + wxRealPoint *first_point = (wxRealPoint *)first_point_node->GetData(); + wxRealPoint *last_point = (wxRealPoint *)last_point_node->GetData(); + + *x1 = first_point->x; + *y1 = first_point->y; + *x2 = last_point->x; + *y2 = last_point->y; +} + +void wxLineShape::SetAttachments(int from_attach, int to_attach) +{ + m_attachmentFrom = from_attach; + m_attachmentTo = to_attach; +} + +bool wxLineShape::HitTest(double x, double y, int *attachment, double *distance) +{ + if (!m_lineControlPoints) + return FALSE; + + // Look at label regions in case mouse is over a label + bool inLabelRegion = FALSE; + for (int i = 0; i < 3; i ++) + { + wxNode *regionNode = m_regions.Item(i); + if (regionNode) + { + wxShapeRegion *region = (wxShapeRegion *)regionNode->GetData(); + if (region->m_formattedText.GetCount() > 0) + { + double xp, yp, cx, cy, cw, ch; + GetLabelPosition(i, &xp, &yp); + // Offset region from default label position + region->GetPosition(&cx, &cy); + region->GetSize(&cw, &ch); + cx += xp; + cy += yp; + double rLeft = (double)(cx - (cw / 2.0)); + double rTop = (double)(cy - (ch / 2.0)); + double rRight = (double)(cx + (cw / 2.0)); + double rBottom = (double)(cy + (ch / 2.0)); + if (x > rLeft && x < rRight && y > rTop && y < rBottom) + { + inLabelRegion = TRUE; + i = 3; + } + } + } + } + + wxNode *node = m_lineControlPoints->GetFirst(); + + while (node && node->GetNext()) + { + wxRealPoint *point1 = (wxRealPoint *)node->GetData(); + wxRealPoint *point2 = (wxRealPoint *)node->GetNext()->GetData(); + + // For inaccurate mousing allow 8 pixel corridor + int extra = 4; + + double dx = point2->x - point1->x; + double dy = point2->y - point1->y; + double seg_len = sqrt(dx * dx + dy * dy); + double distance_from_seg = + seg_len * ((x - point1->x) * dy - (y - point1->y) * dx) / (dy * dy + dx * dx); + double distance_from_prev = + seg_len * ((y - point1->y) * dy + (x - point1->x) * dx) / (dy * dy + dx * dx); + + if ((fabs(distance_from_seg) < extra && + distance_from_prev >= 0 && distance_from_prev <= seg_len) + || inLabelRegion) + { + *attachment = 0; + *distance = distance_from_seg; + return TRUE; + } + + node = node->GetNext(); + } + return FALSE; +} + +void wxLineShape::DrawArrows(wxDC &dc) +{ + // Distance along line of each arrow: space them out evenly. + double startArrowPos = 0.0; + double endArrowPos = 0.0; + double middleArrowPos = 0.0; + + wxNode *node = m_arcArrows.GetFirst(); + while (node) + { + wxArrowHead *arrow = (wxArrowHead *)node->GetData(); + switch (arrow->GetArrowEnd()) + { + case ARROW_POSITION_START: + { + if ((arrow->GetXOffset() != 0.0) && !m_ignoreArrowOffsets) + // If specified, x offset is proportional to line length + DrawArrow(dc, arrow, arrow->GetXOffset(), TRUE); + else + { + DrawArrow(dc, arrow, startArrowPos, FALSE); // Absolute distance + startArrowPos += arrow->GetSize() + arrow->GetSpacing(); + } + break; + } + case ARROW_POSITION_END: + { + if ((arrow->GetXOffset() != 0.0) && !m_ignoreArrowOffsets) + DrawArrow(dc, arrow, arrow->GetXOffset(), TRUE); + else + { + DrawArrow(dc, arrow, endArrowPos, FALSE); + endArrowPos += arrow->GetSize() + arrow->GetSpacing(); + } + break; + } + case ARROW_POSITION_MIDDLE: + { + arrow->SetXOffset(middleArrowPos); + if ((arrow->GetXOffset() != 0.0) && !m_ignoreArrowOffsets) + DrawArrow(dc, arrow, arrow->GetXOffset(), TRUE); + else + { + DrawArrow(dc, arrow, middleArrowPos, FALSE); + middleArrowPos += arrow->GetSize() + arrow->GetSpacing(); + } + break; + } + } + node = node->GetNext(); + } +} + +void wxLineShape::DrawArrow(wxDC &dc, wxArrowHead *arrow, double xOffset, bool proportionalOffset) +{ + wxNode *first_line_node = m_lineControlPoints->GetFirst(); + wxRealPoint *first_line_point = (wxRealPoint *)first_line_node->GetData(); + wxNode *second_line_node = first_line_node->GetNext(); + wxRealPoint *second_line_point = (wxRealPoint *)second_line_node->GetData(); + + wxNode *last_line_node = m_lineControlPoints->GetLast(); + wxRealPoint *last_line_point = (wxRealPoint *)last_line_node->GetData(); + wxNode *second_last_line_node = last_line_node->GetPrevious(); + wxRealPoint *second_last_line_point = (wxRealPoint *)second_last_line_node->GetData(); + + // Position where we want to start drawing + double positionOnLineX, positionOnLineY; + + // Position of start point of line, at the end of which we draw the arrow. + double startPositionX = 0.0 , startPositionY = 0.0; + + switch (arrow->GetPosition()) + { + case ARROW_POSITION_START: + { + // If we're using a proportional offset, calculate just where this will + // be on the line. + double realOffset = xOffset; + if (proportionalOffset) + { + double totalLength = + (double)sqrt((second_line_point->x - first_line_point->x) * (second_line_point->x - first_line_point->x) + + (second_line_point->y - first_line_point->y) * (second_line_point->y - first_line_point->y)); + realOffset = (double)(xOffset * totalLength); + } + GetPointOnLine(second_line_point->x, second_line_point->y, + first_line_point->x, first_line_point->y, + realOffset, &positionOnLineX, &positionOnLineY); + startPositionX = second_line_point->x; + startPositionY = second_line_point->y; + break; + } + case ARROW_POSITION_END: + { + // If we're using a proportional offset, calculate just where this will + // be on the line. + double realOffset = xOffset; + if (proportionalOffset) + { + double totalLength = + (double)sqrt((second_last_line_point->x - last_line_point->x) * (second_last_line_point->x - last_line_point->x) + + (second_last_line_point->y - last_line_point->y) * (second_last_line_point->y - last_line_point->y)); + realOffset = (double)(xOffset * totalLength); + } + GetPointOnLine(second_last_line_point->x, second_last_line_point->y, + last_line_point->x, last_line_point->y, + realOffset, &positionOnLineX, &positionOnLineY); + startPositionX = second_last_line_point->x; + startPositionY = second_last_line_point->y; + break; + } + case ARROW_POSITION_MIDDLE: + { + // Choose a point half way between the last and penultimate points + double x = ((last_line_point->x + second_last_line_point->x) / 2); + double y = ((last_line_point->y + second_last_line_point->y) / 2); + + // If we're using a proportional offset, calculate just where this will + // be on the line. + double realOffset = xOffset; + if (proportionalOffset) + { + double totalLength = + (double)sqrt((second_last_line_point->x - x) * (second_last_line_point->x - x) + + (second_last_line_point->y - y) * (second_last_line_point->y - y)); + realOffset = (double)(xOffset * totalLength); + } + + GetPointOnLine(second_last_line_point->x, second_last_line_point->y, + x, y, realOffset, &positionOnLineX, &positionOnLineY); + startPositionX = second_last_line_point->x; + startPositionY = second_last_line_point->y; + break; + } + } + + /* + * Add yOffset to arrow, if any + */ + + const double myPi = (double) 3.14159265; + // The translation that the y offset may give + double deltaX = 0.0; + double deltaY = 0.0; + if ((arrow->GetYOffset() != 0.0) && !m_ignoreArrowOffsets) + { + /* + |(x4, y4) + |d + | + (x1, y1)--------------(x3, y3)------------------(x2, y2) + x4 = x3 - d * sin(theta) + y4 = y3 + d * cos(theta) + + Where theta = tan(-1) of (y3-y1)/(x3-x1) + */ + double x1 = startPositionX; + double y1 = startPositionY; + double x3 = positionOnLineX; + double y3 = positionOnLineY; + double d = -arrow->GetYOffset(); // Negate so +offset is above line + + double theta; + if (x3 == x1) + theta = (double)(myPi / 2.0); + else + theta = (double)atan((y3 - y1) / (x3 - x1)); + + double x4 = (double)(x3 - (d * sin(theta))); + double y4 = (double)(y3 + (d * cos(theta))); + + deltaX = x4 - positionOnLineX; + deltaY = y4 - positionOnLineY; + } + + switch (arrow->_GetType()) + { + case ARROW_ARROW: + { + double arrowLength = arrow->GetSize(); + double arrowWidth = (double)(arrowLength / 3.0); + + double tip_x, tip_y, side1_x, side1_y, side2_x, side2_y; + oglGetArrowPoints(startPositionX + deltaX, startPositionY + deltaY, + positionOnLineX + deltaX, positionOnLineY + deltaY, + arrowLength, arrowWidth, &tip_x, &tip_y, + &side1_x, &side1_y, &side2_x, &side2_y); + + wxPoint points[4]; + points[0].x = (int) tip_x; + points[0].y = (int) tip_y; + points[1].x = (int) side1_x; + points[1].y = (int) side1_y; + points[2].x = (int) side2_x; + points[2].y = (int) side2_y; + points[3].x = (int) tip_x; + points[3].y = (int) tip_y; + + dc.SetPen(* m_pen); + dc.SetBrush(* m_brush); + dc.DrawPolygon(4, points); + break; + } + case ARROW_HOLLOW_CIRCLE: + case ARROW_FILLED_CIRCLE: + { + // Find point on line of centre of circle, which is a radius away + // from the end position + double diameter = (double)(arrow->GetSize()); + double x, y; + GetPointOnLine(startPositionX + deltaX, startPositionY + deltaY, + positionOnLineX + deltaX, positionOnLineY + deltaY, + (double)(diameter / 2.0), + &x, &y); + + // Convert ellipse centre to top-left coordinates + double x1 = (double)(x - (diameter / 2.0)); + double y1 = (double)(y - (diameter / 2.0)); + + dc.SetPen(* m_pen); + if (arrow->_GetType() == ARROW_HOLLOW_CIRCLE) + dc.SetBrush(GetBackgroundBrush()); + else + dc.SetBrush(* m_brush); + + dc.DrawEllipse((long) x1, (long) y1, (long) diameter, (long) diameter); + break; + } + case ARROW_SINGLE_OBLIQUE: + { + break; + } + case ARROW_METAFILE: + { + if (arrow->GetMetaFile()) + { + // Find point on line of centre of object, which is a half-width away + // from the end position + /* + * width + * <-- start pos <-----><-- positionOnLineX + * _____ + * --------------| x | <-- e.g. rectangular arrowhead + * ----- + */ + double x, y; + GetPointOnLine(startPositionX, startPositionY, + positionOnLineX, positionOnLineY, + (double)(arrow->GetMetaFile()->m_width / 2.0), + &x, &y); + + // Calculate theta for rotating the metafile. + /* + | + | o(x2, y2) 'o' represents the arrowhead. + | / + | / + | /theta + | /(x1, y1) + |______________________ + */ + double theta = 0.0; + double x1 = startPositionX; + double y1 = startPositionY; + double x2 = positionOnLineX; + double y2 = positionOnLineY; + + if ((x1 == x2) && (y1 == y2)) + theta = 0.0; + + else if ((x1 == x2) && (y1 > y2)) + theta = (double)(3.0 * myPi / 2.0); + + else if ((x1 == x2) && (y2 > y1)) + theta = (double)(myPi / 2.0); + + else if ((x2 > x1) && (y2 >= y1)) + theta = (double)atan((y2 - y1) / (x2 - x1)); + + else if (x2 < x1) + theta = (double)(myPi + atan((y2 - y1) / (x2 - x1))); + + else if ((x2 > x1) && (y2 < y1)) + theta = (double)(2 * myPi + atan((y2 - y1) / (x2 - x1))); + + else + { + wxLogFatalError(wxT("Unknown arrowhead rotation case in lines.cc")); + } + + // Rotate about the centre of the object, then place + // the object on the line. + if (arrow->GetMetaFile()->GetRotateable()) + arrow->GetMetaFile()->Rotate(0.0, 0.0, theta); + + if (m_erasing) + { + // If erasing, just draw a rectangle. + double minX, minY, maxX, maxY; + arrow->GetMetaFile()->GetBounds(&minX, &minY, &maxX, &maxY); + // Make erasing rectangle slightly bigger or you get droppings. + int extraPixels = 4; + dc.DrawRectangle((long)(deltaX + x + minX - (extraPixels / 2.0)), (long)(deltaY + y + minY - (extraPixels / 2.0)), + (long)(maxX - minX + extraPixels), (long)(maxY - minY + extraPixels)); + } + else + arrow->GetMetaFile()->Draw(dc, x + deltaX, y + deltaY); + } + break; + } + default: + { + } + } +} + +void wxLineShape::GetBoundingBoxMin(double *w, double *h) +{ + double x1 = 10000; + double y1 = 10000; + double x2 = -10000; + double y2 = -10000; + + wxNode *node = m_lineControlPoints->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + + if (point->x < x1) x1 = point->x; + if (point->y < y1) y1 = point->y; + if (point->x > x2) x2 = point->x; + if (point->y > y2) y2 = point->y; + + node = node->GetNext(); + } + *w = (double)(x2 - x1); + *h = (double)(y2 - y1); +} + +/* + * For a node image of interest, finds the position of this arc + * amongst all the arcs which are attached to THIS SIDE of the node image, + * and the number of same. + */ +void wxLineShape::FindNth(wxShape *image, int *nth, int *no_arcs, bool incoming) +{ + int n = -1; + int num = 0; + wxNode *node = image->GetLines().GetFirst(); + int this_attachment; + if (image == m_to) + this_attachment = m_attachmentTo; + else + this_attachment = m_attachmentFrom; + + // Find number of lines going into/out of this particular attachment point + while (node) + { + wxLineShape *line = (wxLineShape *)node->GetData(); + + if (line->m_from == image) + { + // This is the nth line attached to 'image' + if ((line == this) && !incoming) + n = num; + + // Increment num count if this is the same side (attachment number) + if (line->m_attachmentFrom == this_attachment) + num ++; + } + + if (line->m_to == image) + { + // This is the nth line attached to 'image' + if ((line == this) && incoming) + n = num; + + // Increment num count if this is the same side (attachment number) + if (line->m_attachmentTo == this_attachment) + num ++; + } + + node = node->GetNext(); + } + *nth = n; + *no_arcs = num; +} + +void wxLineShape::OnDrawOutline(wxDC &dc, double WXUNUSED(x), double WXUNUSED(y), double WXUNUSED(w), double WXUNUSED(h)) +{ + wxPen *old_pen = m_pen; + wxBrush *old_brush = m_brush; + + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + SetPen(& dottedPen); + SetBrush( (wxBrush *) wxTRANSPARENT_BRUSH ); + + GetEventHandler()->OnDraw(dc); + + if (old_pen) SetPen(old_pen); + else SetPen(NULL); + if (old_brush) SetBrush(old_brush); + else SetBrush(NULL); +} + +bool wxLineShape::OnMovePre(double x, double y, double old_x, double old_y, bool WXUNUSED(display)) +{ + double x_offset = x - old_x; + double y_offset = y - old_y; + + if (m_lineControlPoints && !(x_offset == 0.0 && y_offset == 0.0)) + { + wxNode *node = m_lineControlPoints->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + point->x += x_offset; + point->y += y_offset; + node = node->GetNext(); + } + + } + + // Move temporary label rectangles if necessary + for (int i = 0; i < 3; i++) + { + if (m_labelObjects[i] && m_labelObjects[i]->Selected()) + { + double xp, yp, xr, yr; + GetLabelPosition(i, &xp, &yp); + wxNode *node = m_regions.Item(i); + if (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + region->GetPosition(&xr, &yr); + } + else + { + xr = 0.0; + yr = 0.0; + } + + m_labelObjects[i]->Move(xp + xr, yp + yr); + } + } + return TRUE; +} + +void wxLineShape::OnMoveLink(bool moveControlPoints) +{ + if (!m_from || !m_to) + return; + + if (m_lineControlPoints->GetCount() > 2) + Initialise(); + + // Do each end - nothing in the middle. User has to move other points + // manually if necessary. + double end_x, end_y; + double other_end_x, other_end_y; + + FindLineEndPoints(&end_x, &end_y, &other_end_x, &other_end_y); + + wxNode *first = m_lineControlPoints->GetFirst(); + wxNode *last = m_lineControlPoints->GetLast(); + + /* This is redundant, surely? Done by SetEnds. + first_point->x = end_x; first_point->y = end_y; + last_point->x = other_end_x; last_point->y = other_end_y; + */ + + double oldX = m_xpos; + double oldY = m_ypos; + + SetEnds(end_x, end_y, other_end_x, other_end_y); + + // Do a second time, because one may depend on the other. + FindLineEndPoints(&end_x, &end_y, &other_end_x, &other_end_y); + SetEnds(end_x, end_y, other_end_x, other_end_y); + + // Try to move control points with the arc + double x_offset = m_xpos - oldX; + double y_offset = m_ypos - oldY; + +// if (moveControlPoints && m_lineControlPoints && !(x_offset == 0.0 && y_offset == 0.0)) + // Only move control points if it's a self link. And only works if attachment mode is ON. + if ((m_from == m_to) && (m_from->GetAttachmentMode() != ATTACHMENT_MODE_NONE) && moveControlPoints && m_lineControlPoints && !(x_offset == 0.0 && y_offset == 0.0)) + { + wxNode *node = m_lineControlPoints->GetFirst(); + while (node) + { + if ((node != m_lineControlPoints->GetFirst()) && (node != m_lineControlPoints->GetLast())) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + point->x += x_offset; + point->y += y_offset; + } + node = node->GetNext(); + } + } + + Move(m_xpos, m_ypos); +} + +// Finds the x, y points at the two ends of the line. +// This function can be used by e.g. line-routing routines to +// get the actual points on the two node images where the lines will be drawn +// to/from. +void wxLineShape::FindLineEndPoints(double *fromX, double *fromY, double *toX, double *toY) +{ + if (!m_from || !m_to) + return; + + // Do each end - nothing in the middle. User has to move other points + // manually if necessary. + double end_x, end_y; + double other_end_x, other_end_y; + + wxNode *first = m_lineControlPoints->GetFirst(); + wxNode *last = m_lineControlPoints->GetLast(); + + wxNode *second = first->GetNext(); + wxRealPoint *second_point = (wxRealPoint *)second->GetData(); + + wxNode *second_last = last->GetPrevious(); + wxRealPoint *second_last_point = (wxRealPoint *)second_last->GetData(); + + if (m_lineControlPoints->GetCount() > 2) + { + if (m_from->GetAttachmentMode() != ATTACHMENT_MODE_NONE) + { + int nth, no_arcs; + FindNth(m_from, &nth, &no_arcs, FALSE); // Not incoming + m_from->GetAttachmentPosition(m_attachmentFrom, &end_x, &end_y, nth, no_arcs, this); + } + else + (void) m_from->GetPerimeterPoint(m_from->GetX(), m_from->GetY(), + (double)second_point->x, (double)second_point->y, + &end_x, &end_y); + + if (m_to->GetAttachmentMode() != ATTACHMENT_MODE_NONE) + { + int nth, no_arcs; + FindNth(m_to, &nth, &no_arcs, TRUE); // Incoming + m_to->GetAttachmentPosition(m_attachmentTo, &other_end_x, &other_end_y, nth, no_arcs, this); + } + else + (void) m_to->GetPerimeterPoint(m_to->GetX(), m_to->GetY(), + (double)second_last_point->x, (double)second_last_point->y, + &other_end_x, &other_end_y); + } + else + { + double fromX = m_from->GetX(); + double fromY = m_from->GetY(); + double toX = m_to->GetX(); + double toY = m_to->GetY(); + + if (m_from->GetAttachmentMode() != ATTACHMENT_MODE_NONE) + { + int nth, no_arcs; + FindNth(m_from, &nth, &no_arcs, FALSE); + m_from->GetAttachmentPosition(m_attachmentFrom, &end_x, &end_y, nth, no_arcs, this); + fromX = end_x; + fromY = end_y; + } + + if (m_to->GetAttachmentMode() != ATTACHMENT_MODE_NONE) + { + int nth, no_arcs; + FindNth(m_to, &nth, &no_arcs, TRUE); + m_to->GetAttachmentPosition(m_attachmentTo, &other_end_x, &other_end_y, nth, no_arcs, this); + toX = other_end_x; + toY = other_end_y; + } + + if (m_from->GetAttachmentMode() == ATTACHMENT_MODE_NONE) + (void) m_from->GetPerimeterPoint(m_from->GetX(), m_from->GetY(), + toX, toY, + &end_x, &end_y); + + if (m_to->GetAttachmentMode() == ATTACHMENT_MODE_NONE) + (void) m_to->GetPerimeterPoint(m_to->GetX(), m_to->GetY(), + fromX, fromY, + &other_end_x, &other_end_y); + } + *fromX = end_x; + *fromY = end_y; + *toX = other_end_x; + *toY = other_end_y; +} + +void wxLineShape::OnDraw(wxDC &dc) +{ + if (m_lineControlPoints) + { + if (m_pen) + dc.SetPen(* m_pen); + if (m_brush) + dc.SetBrush(* m_brush); + + int n = m_lineControlPoints->GetCount(); + wxPoint *points = new wxPoint[n]; + int i; + for (i = 0; i < n; i++) + { + wxRealPoint *point = (wxRealPoint *) m_lineControlPoints->Item(i)->GetData(); + points[i].x = WXROUND(point->x); + points[i].y = WXROUND(point->y); + } + + if (m_isSpline) + dc.DrawSpline(n, points); + else + dc.DrawLines(n, points); + +#ifdef __WXMSW__ + // For some reason, last point isn't drawn under Windows. + dc.DrawPoint(points[n - 1]); +#endif + + delete[] points; + + + // Problem with pen - if not a solid pen, does strange things + // to the arrowhead. So make (get) a new pen that's solid. + if (m_pen && (m_pen->GetStyle() != wxSOLID)) + { + wxPen *solid_pen = + wxThePenList->FindOrCreatePen(m_pen->GetColour(), 1, wxSOLID); + if (solid_pen) + dc.SetPen(* solid_pen); + } + DrawArrows(dc); + } +} + +void wxLineShape::OnDrawControlPoints(wxDC &dc) +{ + if (!m_drawHandles) + return; + + // Draw temporary label rectangles if necessary + if (Selected()) + { + for (int i = 0; i < 3; i++) + { + if (m_labelObjects[i] && m_labelObjects[i]->IsShown()) + m_labelObjects[i]->Draw(dc); + } + } + wxShape::OnDrawControlPoints(dc); +} + +void wxLineShape::OnDragLeft(bool WXUNUSED(draw), double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys), int WXUNUSED(attachment)) +{ +} + +void wxLineShape::OnBeginDragLeft(double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys), int WXUNUSED(attachment)) +{ +} + +void wxLineShape::OnEndDragLeft(double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys), int WXUNUSED(attachment)) +{ +} + +/* +void wxLineShape::SetArrowSize(double length, double width) +{ + arrow_length = length; + arrow_width = width; +} + +void wxLineShape::SetStartArrow(int style) +{ + start_style = style; +} + +void wxLineShape::SetMiddleArrow(int style) +{ + middle_style = style; +} + +void wxLineShape::SetEndArrow(int style) +{ + end_style = style; +} +*/ + +void wxLineShape::OnDrawContents(wxDC &dc) +{ + if (GetDisableLabel()) + return; + + for (int i = 0; i < 3; i++) + { + wxNode *node = m_regions.Item(i); + if (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + double x, y; + GetLabelPosition(i, &x, &y); + DrawRegion(dc, region, x, y); + } + } +} + +void wxLineShape::SetTo(wxShape *object) +{ + m_to = object; +} + +void wxLineShape::SetFrom(wxShape *object) +{ + m_from = object; +} + +void wxLineShape::MakeControlPoints() +{ + if (m_canvas && m_lineControlPoints) + { + wxNode *first = m_lineControlPoints->GetFirst(); + wxNode *last = m_lineControlPoints->GetLast(); + wxRealPoint *first_point = (wxRealPoint *)first->GetData(); + wxRealPoint *last_point = (wxRealPoint *)last->GetData(); + + wxLineControlPoint *control = new wxLineControlPoint(m_canvas, this, CONTROL_POINT_SIZE, + first_point->x, first_point->y, + CONTROL_POINT_ENDPOINT_FROM); + control->m_point = first_point; + m_canvas->AddShape(control); + m_controlPoints.Append(control); + + + wxNode *node = first->GetNext(); + while (node != last) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + + control = new wxLineControlPoint(m_canvas, this, CONTROL_POINT_SIZE, + point->x, point->y, + CONTROL_POINT_LINE); + control->m_point = point; + + m_canvas->AddShape(control); + m_controlPoints.Append(control); + + node = node->GetNext(); + } + control = new wxLineControlPoint(m_canvas, this, CONTROL_POINT_SIZE, + last_point->x, last_point->y, + CONTROL_POINT_ENDPOINT_TO); + control->m_point = last_point; + m_canvas->AddShape(control); + m_controlPoints.Append(control); + + } + +} + +void wxLineShape::ResetControlPoints() +{ + if (m_canvas && m_lineControlPoints && m_controlPoints.GetCount() > 0) + { + wxNode *node = m_controlPoints.GetFirst(); + wxNode *control_node = m_lineControlPoints->GetFirst(); + while (node && control_node) + { + wxRealPoint *point = (wxRealPoint *)control_node->GetData(); + wxLineControlPoint *control = (wxLineControlPoint *)node->GetData(); + control->SetX(point->x); + control->SetY(point->y); + + node = node->GetNext(); + control_node = control_node->GetNext(); + } + } +} + +#if wxUSE_PROLOGIO +void wxLineShape::WriteAttributes(wxExpr *clause) +{ + wxShape::WriteAttributes(clause); + + if (m_from) + clause->AddAttributeValue(wxT("from"), m_from->GetId()); + if (m_to) + clause->AddAttributeValue(wxT("to"), m_to->GetId()); + + if (m_attachmentTo != 0) + clause->AddAttributeValue(wxT("attachment_to"), (long)m_attachmentTo); + if (m_attachmentFrom != 0) + clause->AddAttributeValue(wxT("attachment_from"), (long)m_attachmentFrom); + + if (m_alignmentStart != 0) + clause->AddAttributeValue(wxT("align_start"), (long)m_alignmentStart); + if (m_alignmentEnd != 0) + clause->AddAttributeValue(wxT("align_end"), (long)m_alignmentEnd); + + clause->AddAttributeValue(wxT("is_spline"), (long)m_isSpline); + if (m_maintainStraightLines) + clause->AddAttributeValue(wxT("keep_lines_straight"), (long)m_maintainStraightLines); + + // Make a list of lists for the (sp)line controls + wxExpr *list = new wxExpr(wxExprList); + wxNode *node = m_lineControlPoints->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + wxExpr *point_list = new wxExpr(wxExprList); + wxExpr *x_expr = new wxExpr((double) point->x); + wxExpr *y_expr = new wxExpr((double) point->y); + point_list->Append(x_expr); + point_list->Append(y_expr); + list->Append(point_list); + + node = node->GetNext(); + } + clause->AddAttributeValue(wxT("controls"), list); + + // Write arc arrows in new OGL format, if there are any. + // This is a list of lists. Each sublist comprises: + // (arrowType arrowEnd xOffset arrowSize) + if (m_arcArrows.GetCount() > 0) + { + wxExpr *arrow_list = new wxExpr(wxExprList); + node = m_arcArrows.GetFirst(); + while (node) + { + wxArrowHead *head = (wxArrowHead *)node->GetData(); + wxExpr *head_list = new wxExpr(wxExprList); + head_list->Append(new wxExpr((long)head->_GetType())); + head_list->Append(new wxExpr((long)head->GetArrowEnd())); + head_list->Append(new wxExpr(head->GetXOffset())); + head_list->Append(new wxExpr(head->GetArrowSize())); + head_list->Append(new wxExpr(wxExprString, head->GetName())); + head_list->Append(new wxExpr(head->GetId())); + + // New members of wxArrowHead + head_list->Append(new wxExpr(head->GetYOffset())); + head_list->Append(new wxExpr(head->GetSpacing())); + + arrow_list->Append(head_list); + + node = node->GetNext(); + } + clause->AddAttributeValue(wxT("arrows"), arrow_list); + } +} + +void wxLineShape::ReadAttributes(wxExpr *clause) +{ + wxShape::ReadAttributes(clause); + + int iVal = (int) m_isSpline; + clause->AssignAttributeValue(wxT("is_spline"), &iVal); + m_isSpline = (iVal != 0); + + iVal = (int) m_maintainStraightLines; + clause->AssignAttributeValue(wxT("keep_lines_straight"), &iVal); + m_maintainStraightLines = (iVal != 0); + + clause->AssignAttributeValue(wxT("align_start"), &m_alignmentStart); + clause->AssignAttributeValue(wxT("align_end"), &m_alignmentEnd); + + // Compatibility: check for no regions. + if (m_regions.GetCount() == 0) + { + wxShapeRegion *newRegion = new wxShapeRegion; + newRegion->SetName(wxT("Middle")); + newRegion->SetSize(150, 50); + m_regions.Append((wxObject *)newRegion); + if (m_text.GetCount() > 0) + { + newRegion->ClearText(); + wxNode *node = m_text.GetFirst(); + while (node) + { + wxShapeTextLine *textLine = (wxShapeTextLine *)node->GetData(); + wxNode *next = node->GetNext(); + newRegion->GetFormattedText().Append((wxObject *)textLine); + delete node; + node = next; + } + } + + newRegion = new wxShapeRegion; + newRegion->SetName(wxT("Start")); + newRegion->SetSize(150, 50); + m_regions.Append((wxObject *)newRegion); + + newRegion = new wxShapeRegion; + newRegion->SetName(wxT("End")); + newRegion->SetSize(150, 50); + m_regions.Append((wxObject *)newRegion); + } + + m_attachmentTo = 0; + m_attachmentFrom = 0; + + clause->AssignAttributeValue(wxT("attachment_to"), &m_attachmentTo); + clause->AssignAttributeValue(wxT("attachment_from"), &m_attachmentFrom); + + wxExpr *line_list = NULL; + + // When image is created, there are default control points. Override + // them if there are some in the file. + clause->AssignAttributeValue(wxT("controls"), &line_list); + + if (line_list) + { + // Read a list of lists for the spline controls + if (m_lineControlPoints) + { + ClearPointList(*m_lineControlPoints); + } + else + m_lineControlPoints = new wxList; + + wxExpr *node = line_list->value.first; + + while (node) + { + wxExpr *xexpr = node->value.first; + double x = xexpr->RealValue(); + + wxExpr *yexpr = xexpr->next; + double y = yexpr->RealValue(); + + wxRealPoint *point = new wxRealPoint(x, y); + m_lineControlPoints->Append((wxObject *) point); + + node = node->next; + } + } + + // Read arrow list, for new OGL code + wxExpr *arrow_list = NULL; + + clause->AssignAttributeValue(wxT("arrows"), &arrow_list); + if (arrow_list) + { + wxExpr *node = arrow_list->value.first; + + while (node) + { + WXTYPE arrowType = ARROW_ARROW; + int arrowEnd = 0; + double xOffset = 0.0; + double arrowSize = 0.0; + wxString arrowName; + long arrowId = -1; + + wxExpr *type_expr = node->Nth(0); + wxExpr *end_expr = node->Nth(1); + wxExpr *dist_expr = node->Nth(2); + wxExpr *size_expr = node->Nth(3); + wxExpr *name_expr = node->Nth(4); + wxExpr *id_expr = node->Nth(5); + + // New members of wxArrowHead + wxExpr *yOffsetExpr = node->Nth(6); + wxExpr *spacingExpr = node->Nth(7); + + if (type_expr) + arrowType = (int)type_expr->IntegerValue(); + if (end_expr) + arrowEnd = (int)end_expr->IntegerValue(); + if (dist_expr) + xOffset = dist_expr->RealValue(); + if (size_expr) + arrowSize = size_expr->RealValue(); + if (name_expr) + arrowName = name_expr->StringValue(); + if (id_expr) + arrowId = id_expr->IntegerValue(); + + if (arrowId == -1) + arrowId = wxNewId(); + else + wxRegisterId(arrowId); + + wxArrowHead *arrowHead = AddArrow(arrowType, arrowEnd, arrowSize, xOffset, arrowName, NULL, arrowId); + if (yOffsetExpr) + arrowHead->SetYOffset(yOffsetExpr->RealValue()); + if (spacingExpr) + arrowHead->SetSpacing(spacingExpr->RealValue()); + + node = node->next; + } + } +} +#endif + +void wxLineShape::Copy(wxShape ©) +{ + wxShape::Copy(copy); + + wxASSERT( copy.IsKindOf(CLASSINFO(wxLineShape)) ); + + wxLineShape &lineCopy = (wxLineShape &) copy; + + lineCopy.m_to = m_to; + lineCopy.m_from = m_from; + lineCopy.m_attachmentTo = m_attachmentTo; + lineCopy.m_attachmentFrom = m_attachmentFrom; + lineCopy.m_isSpline = m_isSpline; + lineCopy.m_alignmentStart = m_alignmentStart; + lineCopy.m_alignmentEnd = m_alignmentEnd; + lineCopy.m_maintainStraightLines = m_maintainStraightLines; + lineCopy.m_lineOrientations.Clear(); + + wxNode *node = m_lineOrientations.GetFirst(); + while (node) + { + lineCopy.m_lineOrientations.Append(node->GetData()); + node = node->GetNext(); + } + + if (lineCopy.m_lineControlPoints) + { + ClearPointList(*lineCopy.m_lineControlPoints); + delete lineCopy.m_lineControlPoints; + } + + lineCopy.m_lineControlPoints = new wxList; + + node = m_lineControlPoints->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + wxRealPoint *new_point = new wxRealPoint(point->x, point->y); + lineCopy.m_lineControlPoints->Append((wxObject *) new_point); + node = node->GetNext(); + } + + // Copy arrows + lineCopy.ClearArrowsAtPosition(-1); + node = m_arcArrows.GetFirst(); + while (node) + { + wxArrowHead *arrow = (wxArrowHead *)node->GetData(); + lineCopy.m_arcArrows.Append(new wxArrowHead(*arrow)); + node = node->GetNext(); + } +} + +// Override select, to create/delete temporary label-moving objects +void wxLineShape::Select(bool select) +{ + wxShape::Select(select); + if (select) + { + for (int i = 0; i < 3; i++) + { + wxNode *node = m_regions.Item(i); + if (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + if (region->m_formattedText.GetCount() > 0) + { + double w, h, x, y, xx, yy; + region->GetSize(&w, &h); + region->GetPosition(&x, &y); + GetLabelPosition(i, &xx, &yy); +#if 0 + if (m_labelObjects[i]) + { + m_labelObjects[i]->Select(FALSE); + m_labelObjects[i]->RemoveFromCanvas(m_canvas); + delete m_labelObjects[i]; + } +#endif + if (!m_labelObjects[i]) + { + m_labelObjects[i] = OnCreateLabelShape(this, region, w, h); + } + m_labelObjects[i]->AddToCanvas(m_canvas); + m_labelObjects[i]->Show(TRUE); + m_labelObjects[i]->Move((double)(x + xx), (double)(y + yy)); + m_labelObjects[i]->Select(TRUE); + } + } + } + } + else + { + for (int i = 0; i < 3; i++) + { + if (m_labelObjects[i]) + { + // Don't delete the shape, it might be mentioned in a command + m_labelObjects[i]->Select(FALSE); + m_labelObjects[i]->Show(false); + m_labelObjects[i]->RemoveFromCanvas(m_canvas); +#if 0 + m_labelObjects[i]->Select(FALSE); + m_labelObjects[i]->RemoveFromCanvas(m_canvas); + delete m_labelObjects[i]; + m_labelObjects[i] = NULL; +#endif + } + } + } + Refresh(); +} + +/* + * Line control point + * + */ + +IMPLEMENT_DYNAMIC_CLASS(wxLineControlPoint, wxControlPoint) + +wxLineControlPoint::wxLineControlPoint(wxShapeCanvas *theCanvas, wxShape *object, double size, double x, double y, int the_type): + wxControlPoint(theCanvas, object, size, x, y, the_type) +{ + m_xpos = x; + m_ypos = y; + m_type = the_type; + m_point = NULL; +} + +wxLineControlPoint::~wxLineControlPoint() +{ +} + +void wxLineControlPoint::OnDraw(wxDC &dc) +{ + wxRectangleShape::OnDraw(dc); +} + +// Implement movement of Line point +void wxLineControlPoint::OnDragLeft(bool draw, double x, double y, int keys, int attachment) +{ + m_shape->GetEventHandler()->OnSizingDragLeft(this, draw, x, y, keys, attachment); +} + +void wxLineControlPoint::OnBeginDragLeft(double x, double y, int keys, int attachment) +{ + m_shape->GetEventHandler()->OnSizingBeginDragLeft(this, x, y, keys, attachment); +} + +void wxLineControlPoint::OnEndDragLeft(double x, double y, int keys, int attachment) +{ + m_shape->GetEventHandler()->OnSizingEndDragLeft(this, x, y, keys, attachment); +} + +// Control points ('handles') redirect control to the actual shape, to make it easier +// to override sizing behaviour. +void wxLineShape::OnSizingDragLeft(wxControlPoint *pt, bool WXUNUSED(draw), double x, double y, int WXUNUSED(keys), int WXUNUSED(attachment)) +{ + wxLineControlPoint *lpt = (wxLineControlPoint *) pt; + +#if 0 + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + dc.SetLogicalFunction(OGLRBLF); + + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + dc.SetPen(dottedPen); + dc.SetBrush((* wxTRANSPARENT_BRUSH)); +#endif + + if (lpt->m_type == CONTROL_POINT_LINE) + { + m_canvas->Snap(&x, &y); + + lpt->SetX(x); + lpt->SetY(y); + lpt->m_point->x = x; + lpt->m_point->y = y; + +#if 0 + wxLineShape *lineShape = (wxLineShape *)this; + + wxPen *old_pen = lineShape->GetPen(); + wxBrush *old_brush = lineShape->GetBrush(); + + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + lineShape->SetPen(& dottedPen); + lineShape->SetBrush((wxBrush *) wxTRANSPARENT_BRUSH); + + lineShape->SetPen(old_pen); + lineShape->SetBrush(old_brush); +#endif + } + + GetEventHandler()->OnMoveLink(FALSE); + + + if (lpt->m_type == CONTROL_POINT_ENDPOINT_FROM || lpt->m_type == CONTROL_POINT_ENDPOINT_TO) + { +// lpt->SetX(x); lpt->SetY(y); + } + + if (GetCanvas()) + GetCanvas()->Refresh(); + +} + +void wxLineShape::OnSizingBeginDragLeft(wxControlPoint *pt, double x, double y, int WXUNUSED(keys), int WXUNUSED(attachment)) +{ + wxLineControlPoint *lpt = (wxLineControlPoint *) pt; + +#if 0 + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); +#endif + + wxLineShape *lineShape = (wxLineShape *)this; + if (lpt->m_type == CONTROL_POINT_LINE) + { + lpt->m_originalPos = * (lpt->m_point); + m_canvas->Snap(&x, &y); +#if 0 + this->Erase(); + + // Redraw start and end objects because we've left holes + // when erasing the line + lineShape->GetFrom()->OnDraw(dc); + lineShape->GetFrom()->OnDrawContents(dc); + lineShape->GetTo()->OnDraw(dc); + lineShape->GetTo()->OnDrawContents(dc); + + this->SetDisableLabel(TRUE); + dc.SetLogicalFunction(OGLRBLF); +#endif + + lpt->m_xpos = x; + lpt->m_ypos = y; + lpt->m_point->x = x; + lpt->m_point->y = y; + +#if 0 + wxPen *old_pen = lineShape->GetPen(); + wxBrush *old_brush = lineShape->GetBrush(); + + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + lineShape->SetPen(& dottedPen); + lineShape->SetBrush((wxBrush *) wxTRANSPARENT_BRUSH); +#endif + + lineShape->GetEventHandler()->OnMoveLink(FALSE); + +#if 0 + lineShape->SetPen(old_pen); + lineShape->SetBrush(old_brush); +#endif + } + + if (lpt->m_type == CONTROL_POINT_ENDPOINT_FROM || lpt->m_type == CONTROL_POINT_ENDPOINT_TO) + { + m_canvas->SetCursor(wxCursor(wxCURSOR_BULLSEYE)); + lpt->m_oldCursor = (wxCursor *) wxSTANDARD_CURSOR; + } + if (GetCanvas()) + GetCanvas()->Refresh(); +} + +void wxLineShape::OnSizingEndDragLeft(wxControlPoint *pt, double x, double y, int WXUNUSED(keys), int WXUNUSED(attachment)) +{ + wxLineControlPoint *lpt = (wxLineControlPoint *) pt; + +#if 0 + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); +#endif + + this->SetDisableLabel(FALSE); + wxLineShape *lineShape = (wxLineShape *)this; + + if (lpt->m_type == CONTROL_POINT_LINE) + { + m_canvas->Snap(&x, &y); + + wxRealPoint pt = wxRealPoint(x, y); + + // Move the control point back to where it was; + // MoveControlPoint will move it to the new position + // if it decides it wants. We only moved the position + // during user feedback so we could redraw the line + // as it changed shape. + lpt->m_xpos = lpt->m_originalPos.x; + lpt->m_ypos = lpt->m_originalPos.y; + lpt->m_point->x = lpt->m_originalPos.x; + lpt->m_point->y = lpt->m_originalPos.y; + + OnMoveMiddleControlPoint(lpt, pt); + } + if (lpt->m_type == CONTROL_POINT_ENDPOINT_FROM) + { + if (lpt->m_oldCursor) + m_canvas->SetCursor(* lpt->m_oldCursor); + +// this->Erase(dc); + +// lpt->m_xpos = x; lpt->m_ypos = y; + + if (lineShape->GetFrom()) + { + lineShape->GetFrom()->MoveLineToNewAttachment(lineShape, x, y); + } + } + if (lpt->m_type == CONTROL_POINT_ENDPOINT_TO) + { + if (lpt->m_oldCursor) + m_canvas->SetCursor(* lpt->m_oldCursor); + +// lpt->m_xpos = x; lpt->m_ypos = y; + + if (lineShape->GetTo()) + { + lineShape->GetTo()->MoveLineToNewAttachment(lineShape, x, y); + } + } + + // Needed? +#if 0 + int i = 0; + for (i = 0; i < lineShape->GetLineControlPoints()->GetCount(); i++) + if (((wxRealPoint *)(lineShape->GetLineControlPoints()->Item(i)->GetData())) == lpt->m_point) + break; + + // N.B. in OnMoveControlPoint, an event handler in Hardy could have deselected + // the line and therefore deleted 'this'. -> GPF, intermittently. + // So assume at this point that we've been blown away. + + lineShape->OnMoveControlPoint(i + 1, x, y); +#endif + + if (GetCanvas()) + GetCanvas()->Refresh(); + +} + +// This is called only when a non-end control point is moved. +bool wxLineShape::OnMoveMiddleControlPoint(wxLineControlPoint *lpt, const wxRealPoint &pt) +{ + lpt->m_xpos = pt.x; + lpt->m_ypos = pt.y; + lpt->m_point->x = pt.x; + lpt->m_point->y = pt.y; + + GetEventHandler()->OnMoveLink(); + + if (GetCanvas()) + GetCanvas()->Refresh(); + + return TRUE; +} + +// Implement movement of endpoint to a new attachment +// OBSOLETE: done by dragging with the left button. + +#if 0 +void wxLineControlPoint::OnDragRight(bool draw, double x, double y, int keys, int attachment) +{ + if (m_type == CONTROL_POINT_ENDPOINT_FROM || m_type == CONTROL_POINT_ENDPOINT_TO) + { + m_xpos = x; + m_ypos = y; + } +} + +void wxLineControlPoint::OnBeginDragRight(double x, double y, int keys, int attachment) +{ + wxLineShape *lineShape = (wxLineShape *)m_shape; + if (m_type == CONTROL_POINT_ENDPOINT_FROM || m_type == CONTROL_POINT_ENDPOINT_TO) + { + lineShape->GetEventHandler()->OnDraw(dc); + if (m_type == CONTROL_POINT_ENDPOINT_FROM) + { + lineShape->GetFrom()->GetEventHandler()->OnDraw(dc); + lineShape->GetFrom()->GetEventHandler()->OnDrawContents(dc); + } + else + { + lineShape->GetTo()->GetEventHandler()->OnDraw(dc); + lineShape->GetTo()->GetEventHandler()->OnDrawContents(dc); + } + m_canvas->SetCursor(wxCursor(wxCURSOR_BULLSEYE)); + m_oldCursor = wxSTANDARD_CURSOR; + } + + if (GetCanvas()) + GetCanvas()->Refresh(); +} + +void wxLineControlPoint::OnEndDragRight(double x, double y, int keys, int attachment) +{ + wxLineShape *lineShape = (wxLineShape *)m_shape; + if (m_type == CONTROL_POINT_ENDPOINT_FROM) + { + if (m_oldCursor) + m_canvas->SetCursor(m_oldCursor); + + m_xpos = x; + m_ypos = y; + + if (lineShape->GetFrom()) + { + int new_attachment; + double distance; + + if (lineShape->GetFrom()->HitTest(x, y, &new_attachment, &distance)) + lineShape->SetAttachments(new_attachment, lineShape->GetAttachmentTo()); + + lineShape->GetFrom()->MoveLinks(); + } + } + if (m_type == CONTROL_POINT_ENDPOINT_TO) + { + if (m_oldCursor) + m_canvas->SetCursor(m_oldCursor); + m_shape->Erase(dc); + + m_xpos = x; + m_ypos = y; + + if (lineShape->GetTo()) + { + int new_attachment; + double distance; + if (lineShape->GetTo()->HitTest(x, y, &new_attachment, &distance)) + lineShape->SetAttachments(lineShape->GetAttachmentFrom(), new_attachment); + + lineShape->GetTo()->MoveLinks(); + } + } + int i = 0; + for (i = 0; i < lineShape->GetLineControlPoints()->GetCount(); i++) + if (((wxRealPoint *)(lineShape->GetLineControlPoints()->Item(i)->GetData())) == m_point) + break; + lineShape->OnMoveControlPoint(i + 1, x, y); + if (GetCanvas()) + GetCanvas()->Refresh(); +} +#endif + +/* + * Get the point on the given line (x1, y1) (x2, y2) + * distance 'length' along from the end, + * returned values in x and y + */ + +void GetPointOnLine(double x1, double y1, double x2, double y2, + double length, double *x, double *y) +{ + double l = (double)sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); + + if (l < 0.01) + l = (double) 0.01; + + double i_bar = (x2 - x1) / l; + double j_bar = (y2 - y1) / l; + + *x = (- length * i_bar) + x2; + *y = (- length * j_bar) + y2; +} + +wxArrowHead *wxLineShape::AddArrow(WXTYPE type, int end, double size, double xOffset, + const wxString &name, wxPseudoMetaFile *mf, long arrowId) +{ + wxArrowHead *arrow = new wxArrowHead(type, end, size, xOffset, name, mf, arrowId); + m_arcArrows.Append(arrow); + return arrow; +} + +/* + * Add arrowhead at a particular position in the arrowhead list. + */ +bool wxLineShape::AddArrowOrdered(wxArrowHead *arrow, wxList &referenceList, int end) +{ + wxNode *refNode = referenceList.GetFirst(); + wxNode *currNode = m_arcArrows.GetFirst(); + wxString targetName(arrow->GetName()); + if (!refNode) return FALSE; + + // First check whether we need to insert in front of list, + // because this arrowhead is the first in the reference + // list and should therefore be first in the current list. + wxArrowHead *refArrow = (wxArrowHead *)refNode->GetData(); + if (refArrow->GetName() == targetName) + { + m_arcArrows.Insert(arrow); + return TRUE; + } + + wxArrowHead *currArrow = (wxArrowHead *)currNode->GetData(); + while (refNode && currNode) + { + refArrow = (wxArrowHead *)refNode->GetData(); + + // Matching: advance current arrow pointer + if ((currArrow->GetArrowEnd() == end) && + (currArrow->GetName() == refArrow->GetName())) + { + currNode = currNode->GetNext(); // Could be NULL now + if (currNode) + currArrow = (wxArrowHead *)currNode->GetData(); + } + + // Check if we're at the correct position in the + // reference list + if (targetName == refArrow->GetName()) + { + if (currNode) + m_arcArrows.Insert(currNode, arrow); + else + m_arcArrows.Append(arrow); + return TRUE; + } + refNode = refNode->GetNext(); + } + m_arcArrows.Append(arrow); + return TRUE; +} + +void wxLineShape::ClearArrowsAtPosition(int end) +{ + wxNode *node = m_arcArrows.GetFirst(); + while (node) + { + wxArrowHead *arrow = (wxArrowHead *)node->GetData(); + wxNode *next = node->GetNext(); + switch (end) + { + case -1: + { + delete arrow; + delete node; + break; + } + case ARROW_POSITION_START: + { + if (arrow->GetArrowEnd() == ARROW_POSITION_START) + { + delete arrow; + delete node; + } + break; + } + case ARROW_POSITION_END: + { + if (arrow->GetArrowEnd() == ARROW_POSITION_END) + { + delete arrow; + delete node; + } + break; + } + case ARROW_POSITION_MIDDLE: + { + if (arrow->GetArrowEnd() == ARROW_POSITION_MIDDLE) + { + delete arrow; + delete node; + } + break; + } + } + node = next; + } +} + +bool wxLineShape::ClearArrow(const wxString &name) +{ + wxNode *node = m_arcArrows.GetFirst(); + while (node) + { + wxArrowHead *arrow = (wxArrowHead *)node->GetData(); + if (arrow->GetName() == name) + { + delete arrow; + delete node; + return TRUE; + } + node = node->GetNext(); + } + return FALSE; +} + +/* + * Finds an arrowhead at the given position (if -1, any position) + * + */ + +wxArrowHead *wxLineShape::FindArrowHead(int position, const wxString &name) +{ + wxNode *node = m_arcArrows.GetFirst(); + while (node) + { + wxArrowHead *arrow = (wxArrowHead *)node->GetData(); + if (((position == -1) || (position == arrow->GetArrowEnd())) && + (arrow->GetName() == name)) + return arrow; + node = node->GetNext(); + } + return NULL; +} + +wxArrowHead *wxLineShape::FindArrowHead(long arrowId) +{ + wxNode *node = m_arcArrows.GetFirst(); + while (node) + { + wxArrowHead *arrow = (wxArrowHead *)node->GetData(); + if (arrowId == arrow->GetId()) + return arrow; + node = node->GetNext(); + } + return NULL; +} + +/* + * Deletes an arrowhead at the given position (if -1, any position) + * + */ + +bool wxLineShape::DeleteArrowHead(int position, const wxString &name) +{ + wxNode *node = m_arcArrows.GetFirst(); + while (node) + { + wxArrowHead *arrow = (wxArrowHead *)node->GetData(); + if (((position == -1) || (position == arrow->GetArrowEnd())) && + (arrow->GetName() == name)) + { + delete arrow; + delete node; + return TRUE; + } + node = node->GetNext(); + } + return FALSE; +} + +// Overloaded DeleteArrowHead: pass arrowhead id. +bool wxLineShape::DeleteArrowHead(long id) +{ + wxNode *node = m_arcArrows.GetFirst(); + while (node) + { + wxArrowHead *arrow = (wxArrowHead *)node->GetData(); + if (arrow->GetId() == id) + { + delete arrow; + delete node; + return TRUE; + } + node = node->GetNext(); + } + return FALSE; +} + +/* + * Calculate the minimum width a line + * occupies, for the purposes of drawing lines in tools. + * + */ + +double wxLineShape::FindMinimumWidth() +{ + double minWidth = 0.0; + wxNode *node = m_arcArrows.GetFirst(); + while (node) + { + wxArrowHead *arrowHead = (wxArrowHead *)node->GetData(); + minWidth += arrowHead->GetSize(); + if (node->GetNext()) + minWidth += arrowHead->GetSpacing(); + + node = node->GetNext(); + } + // We have ABSOLUTE minimum now. So + // scale it to give it reasonable aesthetics + // when drawing with line. + if (minWidth > 0.0) + minWidth = (double)(minWidth * 1.4); + else + minWidth = 20.0; + + SetEnds(0.0, 0.0, minWidth, 0.0); + Initialise(); + + return minWidth; +} + +// Find which position we're talking about at this (x, y). +// Returns ARROW_POSITION_START, ARROW_POSITION_MIDDLE, ARROW_POSITION_END +int wxLineShape::FindLinePosition(double x, double y) +{ + double startX, startY, endX, endY; + GetEnds(&startX, &startY, &endX, &endY); + + // Find distances from centre, start and end. The smallest wins. + double centreDistance = (double)(sqrt((x - m_xpos) * (x - m_xpos) + (y - m_ypos) * (y - m_ypos))); + double startDistance = (double)(sqrt((x - startX) * (x - startX) + (y - startY) * (y - startY))); + double endDistance = (double)(sqrt((x - endX) * (x - endX) + (y - endY) * (y - endY))); + + if (centreDistance < startDistance && centreDistance < endDistance) + return ARROW_POSITION_MIDDLE; + else if (startDistance < endDistance) + return ARROW_POSITION_START; + else + return ARROW_POSITION_END; +} + +// Set alignment flags +void wxLineShape::SetAlignmentOrientation(bool isEnd, bool isHoriz) +{ + if (isEnd) + { + if (isHoriz && ((m_alignmentEnd & LINE_ALIGNMENT_HORIZ) != LINE_ALIGNMENT_HORIZ)) + m_alignmentEnd |= LINE_ALIGNMENT_HORIZ; + else if (!isHoriz && ((m_alignmentEnd & LINE_ALIGNMENT_HORIZ) == LINE_ALIGNMENT_HORIZ)) + m_alignmentEnd -= LINE_ALIGNMENT_HORIZ; + } + else + { + if (isHoriz && ((m_alignmentStart & LINE_ALIGNMENT_HORIZ) != LINE_ALIGNMENT_HORIZ)) + m_alignmentStart |= LINE_ALIGNMENT_HORIZ; + else if (!isHoriz && ((m_alignmentStart & LINE_ALIGNMENT_HORIZ) == LINE_ALIGNMENT_HORIZ)) + m_alignmentStart -= LINE_ALIGNMENT_HORIZ; + } +} + +void wxLineShape::SetAlignmentType(bool isEnd, int alignType) +{ + if (isEnd) + { + if (alignType == LINE_ALIGNMENT_TO_NEXT_HANDLE) + { + if ((m_alignmentEnd & LINE_ALIGNMENT_TO_NEXT_HANDLE) != LINE_ALIGNMENT_TO_NEXT_HANDLE) + m_alignmentEnd |= LINE_ALIGNMENT_TO_NEXT_HANDLE; + } + else if ((m_alignmentEnd & LINE_ALIGNMENT_TO_NEXT_HANDLE) == LINE_ALIGNMENT_TO_NEXT_HANDLE) + m_alignmentEnd -= LINE_ALIGNMENT_TO_NEXT_HANDLE; + } + else + { + if (alignType == LINE_ALIGNMENT_TO_NEXT_HANDLE) + { + if ((m_alignmentStart & LINE_ALIGNMENT_TO_NEXT_HANDLE) != LINE_ALIGNMENT_TO_NEXT_HANDLE) + m_alignmentStart |= LINE_ALIGNMENT_TO_NEXT_HANDLE; + } + else if ((m_alignmentStart & LINE_ALIGNMENT_TO_NEXT_HANDLE) == LINE_ALIGNMENT_TO_NEXT_HANDLE) + m_alignmentStart -= LINE_ALIGNMENT_TO_NEXT_HANDLE; + } +} + +bool wxLineShape::GetAlignmentOrientation(bool isEnd) +{ + if (isEnd) + return ((m_alignmentEnd & LINE_ALIGNMENT_HORIZ) == LINE_ALIGNMENT_HORIZ); + else + return ((m_alignmentStart & LINE_ALIGNMENT_HORIZ) == LINE_ALIGNMENT_HORIZ); +} + +int wxLineShape::GetAlignmentType(bool isEnd) +{ + if (isEnd) + return (m_alignmentEnd & LINE_ALIGNMENT_TO_NEXT_HANDLE); + else + return (m_alignmentStart & LINE_ALIGNMENT_TO_NEXT_HANDLE); +} + +wxRealPoint *wxLineShape::GetNextControlPoint(wxShape *nodeObject) +{ + int n = m_lineControlPoints->GetCount(); + int nn; + if (m_to == nodeObject) + { + // Must be END of line, so we want (n - 1)th control point. + // But indexing ends at n-1, so subtract 2. + nn = n - 2; + } + else nn = 1; + wxNode *node = m_lineControlPoints->Item(nn); + if (node) + { + return (wxRealPoint *)node->GetData(); + } + else + return FALSE; +} + +/* + * Arrowhead + * + */ + +IMPLEMENT_DYNAMIC_CLASS(wxArrowHead, wxObject) + +wxArrowHead::wxArrowHead(WXTYPE type, int end, double size, double dist, const wxString &name, + wxPseudoMetaFile *mf, long arrowId) +{ + m_arrowType = type; + m_arrowEnd = end; + m_arrowSize = size; + m_xOffset = dist; + m_yOffset = 0.0; + m_spacing = 5.0; + + m_arrowName = name; + m_metaFile = mf; + m_id = arrowId; + if (m_id == -1) + m_id = wxNewId(); +} + +wxArrowHead::wxArrowHead(wxArrowHead &toCopy) +{ + m_arrowType = toCopy.m_arrowType; + m_arrowEnd = toCopy.GetArrowEnd(); + m_arrowSize = toCopy.m_arrowSize; + m_xOffset = toCopy.m_xOffset; + m_yOffset = toCopy.m_yOffset; + m_spacing = toCopy.m_spacing; + m_arrowName = toCopy.m_arrowName ; + if (toCopy.m_metaFile) + m_metaFile = new wxPseudoMetaFile(*(toCopy.m_metaFile)); + else + m_metaFile = NULL; + m_id = wxNewId(); +} + +wxArrowHead::~wxArrowHead() +{ + if (m_metaFile) delete m_metaFile; +} + +void wxArrowHead::SetSize(double size) +{ + m_arrowSize = size; + if ((m_arrowType == ARROW_METAFILE) && m_metaFile) + { + double oldWidth = m_metaFile->m_width; + if (oldWidth == 0.0) + return; + + double scale = (double)(size / oldWidth); + if (scale != 1.0) + m_metaFile->Scale(scale, scale); + } +} + +// Can override this to create a different class of label shape +wxLabelShape *wxLineShape::OnCreateLabelShape(wxLineShape *parent, wxShapeRegion *region, double w, double h) +{ + return new wxLabelShape(parent, region, w, h); +} + +/* + * Label object + * + */ + +IMPLEMENT_DYNAMIC_CLASS(wxLabelShape, wxRectangleShape) + +wxLabelShape::wxLabelShape(wxLineShape *parent, wxShapeRegion *region, double w, double h): wxRectangleShape(w, h) +{ + m_lineShape = parent; + m_shapeRegion = region; + SetPen(wxThePenList->FindOrCreatePen(wxColour(0, 0, 0), 1, wxDOT)); +} + +wxLabelShape::~wxLabelShape() +{ +} + +void wxLabelShape::OnDraw(wxDC &dc) +{ + if (m_lineShape && !m_lineShape->GetDrawHandles()) + return; + + double x1 = (double)(m_xpos - m_width / 2.0); + double y1 = (double)(m_ypos - m_height / 2.0); + + if (m_pen) + { + if (m_pen->GetWidth() == 0) + dc.SetPen(* g_oglTransparentPen); + else + dc.SetPen(* m_pen); + } + dc.SetBrush(* wxTRANSPARENT_BRUSH); + + if (m_cornerRadius > 0.0) + dc.DrawRoundedRectangle(WXROUND(x1), WXROUND(y1), WXROUND(m_width), WXROUND(m_height), m_cornerRadius); + else + dc.DrawRectangle(WXROUND(x1), WXROUND(y1), WXROUND(m_width), WXROUND(m_height)); +} + +void wxLabelShape::OnDrawContents(wxDC &WXUNUSED(dc)) +{ +} + +void wxLabelShape::OnDragLeft(bool draw, double x, double y, int keys, int attachment) +{ + wxRectangleShape::OnDragLeft(draw, x, y, keys, attachment); +} + +void wxLabelShape::OnBeginDragLeft(double x, double y, int keys, int attachment) +{ + wxRectangleShape::OnBeginDragLeft(x, y, keys, attachment); +} + +void wxLabelShape::OnEndDragLeft(double x, double y, int keys, int attachment) +{ + wxRectangleShape::OnEndDragLeft(x, y, keys, attachment); +} + +bool wxLabelShape::OnMovePre(double x, double y, double old_x, double old_y, bool display) +{ + return m_lineShape->OnLabelMovePre(this, x, y, old_x, old_y, display); +} + +bool wxLineShape::OnLabelMovePre(wxLabelShape *labelShape, double x, double y, double WXUNUSED(old_x), double WXUNUSED(old_y), bool WXUNUSED(display)) +{ + labelShape->m_shapeRegion->SetSize(labelShape->GetWidth(), labelShape->GetHeight()); + + // Find position in line's region list + int i = 0; + wxNode *node = GetRegions().GetFirst(); + while (node) + { + if (labelShape->m_shapeRegion == (wxShapeRegion *)node->GetData()) + node = NULL; + else + { + node = node->GetNext(); + i ++; + } + } + double xx, yy; + GetLabelPosition(i, &xx, &yy); + // Set the region's offset, relative to the default position for + // each region. + labelShape->m_shapeRegion->SetPosition((double)(x - xx), (double)(y - yy)); + + labelShape->SetX(x); + labelShape->SetY(y); + + // Need to reformat to fit region. + if (!labelShape->m_shapeRegion->GetText().IsEmpty()) + { + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + wxString s(labelShape->m_shapeRegion->GetText()); + labelShape->FormatText(dc, s, i); + // DrawRegion(dc, labelShape->m_shapeRegion, xx, yy); + } + return TRUE; +} + +// Divert left and right clicks to line object +void wxLabelShape::OnLeftClick(double x, double y, int keys, int attachment) +{ + m_lineShape->GetEventHandler()->OnLeftClick(x, y, keys, attachment); +} + +void wxLabelShape::OnRightClick(double x, double y, int keys, int attachment) +{ + m_lineShape->GetEventHandler()->OnRightClick(x, y, keys, attachment); +} + diff --git a/ogl/mfutils.cpp b/ogl/mfutils.cpp new file mode 100644 index 0000000..81ca969 --- /dev/null +++ b/ogl/mfutils.cpp @@ -0,0 +1,1087 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// mfutils.cpp - Metafile utillities +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include +#include + +#include "ogl/ogl.h" + +#include + +static char _buf[1024]; // a temp buffer to use inplace of wxBuffer, which is deprecated. + +// 16-bit unsigned integer +static unsigned int getshort(FILE *fp) +{ + int c, c1; + c = getc(fp); + c1 = getc(fp); + unsigned int res = ((unsigned int) c) + (((unsigned int) c1) << 8); + return res; +} + +// 16-bit signed integer +static int getsignedshort(FILE *fp) +{ + int c, c1; + c = getc(fp); + c1 = getc(fp); +#if 0 + // this is not used value, no need to execute it + int testRes = ((unsigned int) c) + (((unsigned int) c1) << 8); +#endif + unsigned long res1 = ((unsigned int) c) + (((unsigned int) c1) << 8); + int res; + if (res1 > 32767) + res = (int)(res1 - 65536); + else + res = (int)(res1); + return res; +} + +// 32-bit integer +static long getint(FILE *fp) +{ + int c, c1, c2, c3; + c = getc(fp); + c1 = getc(fp); + c2 = getc(fp); + c3 = getc(fp); + long res = (long)((long) c) + + (((long) c1) << 8) + + (((long) c2) << 16) + + (((long) c3) << 24); + return res; +} + + +/* Placeable metafile header +struct mfPLACEABLEHEADER { + DWORD key; // 32-bit + HANDLE hmf; // 16-bit + RECT bbox; // 4x16 bit + WORD inch; // 16-bit + DWORD reserved; // 32-bit + WORD checksum; // 16-bit +}; +*/ + +wxMetaRecord::~wxMetaRecord(void) +{ + if (points) delete[] points; + if (stringParam) delete[] stringParam; +} + +wxXMetaFile::wxXMetaFile(const wxChar *file) +{ + ok = FALSE; + top = 0.0; + bottom = 0.0; + left = 0.0; + right = 0.0; + + if (file) + ok = ReadFile(file); +} + +/* + Handle table gdiObjects + ------------ ---------- + [0] wxPen + [1]----param2--- wxBrush + [2] | wxFont + [3] | -> wxPen + + The handle table works as follows. + When a GDI object is created whilst reading in the + metafile, the (e.g.) createpen record is added to the + first free entry in the handle table. The createpen + record's param1 is a pointer to the actual wxPen, and + its param2 is the index into the gdiObjects list, which only + grows and never shrinks (unlike the handle table.) + + When SelectObject(index) is found, the index in the file + refers to the position in the handle table. BUT we then + set param2 to be the position of the wxPen in gdiObjects, + i.e. to param2 of the CreatePen record, itself found in + the handle table. + + When an object is deleted, the entry in the handletable is + NULLed but the gdiObjects entry is not removed (no point, and + allows us to create all GDI objects in advance of playing the + metafile). +*/ + + +static wxMetaRecord *HandleTable[100]; +static int HandleTableSize = 0; + +void DeleteMetaRecordHandle(int index) +{ + HandleTable[index] = NULL; +} + +int AddMetaRecordHandle(wxMetaRecord *record) +{ + for (int i = 0; i < HandleTableSize; i++) + if (!HandleTable[i]) + { + HandleTable[i] = record; + return i; + } + // No free spaces in table, so append. + + HandleTable[HandleTableSize] = record; + HandleTableSize ++; + return (HandleTableSize - 1); +} + +bool wxXMetaFile::ReadFile(const wxChar *file) +{ + HandleTableSize = 0; + + FILE *handle = wxFopen(file, wxT("rb")); + if (!handle) return FALSE; + + // Read placeable metafile header, if any + long key = getint(handle); + + if (key == (long) 0x9AC6CDD7) + { + /* long hmf = */ getshort(handle); + int iLeft, iTop, iRight, iBottom; + iLeft = getsignedshort(handle); + iTop = getsignedshort(handle); + iRight = getsignedshort(handle); + iBottom = getsignedshort(handle); + + left = (double)iLeft; + top = (double)iTop; + right = (double)iRight; + bottom = (double)iBottom; + + /* int inch = */ + getshort(handle); + /* long reserved = */ + getint(handle); + /* int checksum = */ + getshort(handle); + /* + double widthInUnits = (double)right - left; + double heightInUnits = (double)bottom - top; + *width = (int)((widthInUnits*1440.0)/inch); + *height = (int)((heightInUnits*1440.0)/inch); + */ + } + else rewind(handle); + + // Read METAHEADER + int mtType = getshort(handle); + + if (mtType != 1 && mtType != 2) + { + fclose(handle); + return FALSE; + } + + /* int mtHeaderSize = */ getshort(handle); + int mtVersion = getshort(handle); + + if (mtVersion != 0x0300 && mtVersion != 0x0100) + { + fclose(handle); + return FALSE; + } + + /* long mtSize = */ getint(handle); + /* int mtNoObjects = */ + getshort(handle); + /* long mtMaxRecord = */ + getint(handle); + /* int mtNoParameters = */ + getshort(handle); + + while (!feof(handle)) + { + long rdSize = getint(handle); // 4 bytes + int rdFunction = getshort(handle); // 2 bytes + if (feof(handle)) + break; + + switch (rdFunction) + { + case META_SETBKCOLOR: + { + wxMetaRecord *rec = new wxMetaRecord(META_SETBKCOLOR); + long colorref = getint(handle); // COLORREF + rec->param1 = GetRValue(colorref); + rec->param2 = GetGValue(colorref); + rec->param3 = GetBValue(colorref); + metaRecords.Append(rec); + break; + } + case META_SETBKMODE: + { + wxMetaRecord *rec = new wxMetaRecord(META_SETBKMODE); + rec->param1 = getshort(handle); // Background mode + if (rec->param1 == OPAQUE) rec->param1 = wxSOLID; + else rec->param1 = wxTRANSPARENT; + metaRecords.Append(rec); + break; + } + case META_SETMAPMODE: + { + wxMetaRecord *rec = new wxMetaRecord(META_SETMAPMODE); + rec->param1 = getshort(handle); + metaRecords.Append(rec); + break; + } +// case META_SETROP2: +// case META_SETRELABS: +// case META_SETPOLYFILLMODE: +// case META_SETSTRETCHBLTMODE: +// case META_SETTEXTCHAREXTRA: + case META_SETTEXTCOLOR: + { + wxMetaRecord *rec = new wxMetaRecord(META_SETTEXTCOLOR); + long colorref = getint(handle); // COLORREF + rec->param1 = GetRValue(colorref); + rec->param2 = GetGValue(colorref); + rec->param3 = GetBValue(colorref); + metaRecords.Append(rec); + break; + } +// case META_SETTEXTJUSTIFICATION: + case META_SETWINDOWORG: + { + wxMetaRecord *rec = new wxMetaRecord(META_SETWINDOWORG); + rec->param2 = getshort(handle); + rec->param1 = getshort(handle); + metaRecords.Append(rec); + break; + } + case META_SETWINDOWEXT: + { + wxMetaRecord *rec = new wxMetaRecord(META_SETWINDOWEXT); + rec->param2 = getshort(handle); + rec->param1 = getshort(handle); + metaRecords.Append(rec); + break; + } +// case META_SETVIEWPORTORG: +// case META_SETVIEWPORTEXT: +// case META_OFFSETWINDOWORG: +// case META_SCALEWINDOWEXT: +// case META_OFFSETVIEWPORTORG: +// case META_SCALEVIEWPORTEXT: + case META_LINETO: + { + wxMetaRecord *rec = new wxMetaRecord(META_LINETO); + rec->param1 = getshort(handle); // x1 + rec->param2 = getshort(handle); // y1 + metaRecords.Append(rec); + break; + } + case META_MOVETO: + { + wxMetaRecord *rec = new wxMetaRecord(META_MOVETO); + rec->param1 = getshort(handle); // x1 + rec->param2 = getshort(handle); // y1 + metaRecords.Append(rec); + break; + } + case META_EXCLUDECLIPRECT: + { + wxMetaRecord *rec = new wxMetaRecord(META_EXCLUDECLIPRECT); + rec->param4 = getshort(handle); // y2 + rec->param3 = getshort(handle); // x2 + rec->param2 = getshort(handle); // y1 + rec->param1 = getshort(handle); // x1 + metaRecords.Append(rec); + break; + } + case META_INTERSECTCLIPRECT: + { + wxMetaRecord *rec = new wxMetaRecord(META_INTERSECTCLIPRECT); + rec->param4 = getshort(handle); // y2 + rec->param3 = getshort(handle); // x2 + rec->param2 = getshort(handle); // y1 + rec->param1 = getshort(handle); // x1 + metaRecords.Append(rec); + break; + } +// case META_ARC: // DO!!! + case META_ELLIPSE: + { + wxMetaRecord *rec = new wxMetaRecord(META_ELLIPSE); + rec->param4 = getshort(handle); // y2 + rec->param3 = getshort(handle); // x2 + rec->param2 = getshort(handle); // y1 + rec->param1 = getshort(handle); // x1 + metaRecords.Append(rec); + break; + } +// case META_FLOODFILL: +// case META_PIE: // DO!!! + case META_RECTANGLE: + { + wxMetaRecord *rec = new wxMetaRecord(META_RECTANGLE); + rec->param4 = getshort(handle); // y2 + rec->param3 = getshort(handle); // x2 + rec->param2 = getshort(handle); // y1 + rec->param1 = getshort(handle); // x1 + metaRecords.Append(rec); + break; + } + case META_ROUNDRECT: + { + wxMetaRecord *rec = new wxMetaRecord(META_ROUNDRECT); + rec->param6 = getshort(handle); // width + rec->param5 = getshort(handle); // height + rec->param4 = getshort(handle); // y2 + rec->param3 = getshort(handle); // x2 + rec->param2 = getshort(handle); // y1 + rec->param1 = getshort(handle); // x1 + metaRecords.Append(rec); + break; + } +// case META_PATBLT: +// case META_SAVEDC: + case META_SETPIXEL: + { + wxMetaRecord *rec = new wxMetaRecord(META_SETPIXEL); + rec->param1 = getshort(handle); // x1 + rec->param2 = getshort(handle); // y1 + rec->param3 = getint(handle); // COLORREF + metaRecords.Append(rec); + break; + } +// case META_OFFSETCLIPRGN: + case META_TEXTOUT: + { + wxMetaRecord *rec = new wxMetaRecord(META_TEXTOUT); + int count = getshort(handle); + rec->stringParam = new wxChar[count + 1]; + fread((void *)rec->stringParam, sizeof(wxChar), count, handle); + rec->stringParam[count] = 0; + rec->param2 = getshort(handle); // Y + rec->param1 = getshort(handle); // X + metaRecords.Append(rec); + break; + } + /* + case META_EXTTEXTOUT: + { + wxMetaRecord *rec = new wxMetaRecord(META_EXTTEXTOUT); + int cellSpacing = getshort(handle); + int count = getshort(handle); + rec->stringParam = new char[count+1]; + fread((void *)rec->stringParam, sizeof(char), count, handle); + rec->stringParam[count] = 0; + // Rectangle + int rectY2 = getshort(handle); + int rectX2 = getshort(handle); + int rectY1 = getshort(handle); + int rectX1 = getshort(handle); + int rectType = getshort(handle); + rec->param2 = getshort(handle); // Y + rec->param1 = getshort(handle); // X + metaRecords.Append(rec); + break; + } + */ +// case META_BITBLT: +// case META_STRETCHBLT: + case META_POLYGON: + { + wxMetaRecord *rec = new wxMetaRecord(META_POLYGON); + rec->param1 = getshort(handle); + rec->points = new wxRealPoint[(int)rec->param1]; + for (int i = 0; i < rec->param1; i++) + { + rec->points[i].x = getshort(handle); + rec->points[i].y = getshort(handle); + } + + metaRecords.Append(rec); + break; + } + case META_POLYLINE: + { + wxMetaRecord *rec = new wxMetaRecord(META_POLYLINE); + rec->param1 = (long)getshort(handle); + rec->points = new wxRealPoint[(int)rec->param1]; + for (int i = 0; i < rec->param1; i++) + { + rec->points[i].x = getshort(handle); + rec->points[i].y = getshort(handle); + } + + metaRecords.Append(rec); + break; + } +// case META_ESCAPE: +// case META_RESTOREDC: +// case META_FILLREGION: +// case META_FRAMEREGION: +// case META_INVERTREGION: +// case META_PAINTREGION: +// case META_SELECTCLIPREGION: // DO THIS! + case META_SELECTOBJECT: + { + wxMetaRecord *rec = new wxMetaRecord(META_SELECTOBJECT); + rec->param1 = (long)getshort(handle); // Position of object in gdiObjects list + metaRecords.Append(rec); + // param2 gives the index into gdiObjects, which is different from + // the index into the handle table. + rec->param2 = HandleTable[(int)rec->param1]->param2; + break; + } +// case META_SETTEXTALIGN: +// case META_DRAWTEXT: +// case META_CHORD: +// case META_SETMAPPERFLAGS: +// case META_EXTTEXTOUT: +// case META_SETDIBTODEV: +// case META_SELECTPALETTE: +// case META_REALIZEPALETTE: +// case META_ANIMATEPALETTE: +// case META_SETPALENTRIES: +// case META_POLYPOLYGON: +// case META_RESIZEPALETTE: +// case META_DIBBITBLT: +// case META_DIBSTRETCHBLT: + case META_DIBCREATEPATTERNBRUSH: + { + wxMetaRecord *rec = new wxMetaRecord(META_DIBCREATEPATTERNBRUSH); + fread((void *)_buf, sizeof(char), (int)((2 * rdSize) - 6), handle); + + metaRecords.Append(rec); + gdiObjects.Append(rec); + AddMetaRecordHandle(rec); + rec->param2 = (long)(gdiObjects.GetCount() - 1); + break; + } +// case META_STRETCHDIB: +// case META_EXTFLOODFILL: +// case META_RESETDC: +// case META_STARTDOC: +// case META_STARTPAGE: +// case META_ENDPAGE: +// case META_ABORTDOC: +// case META_ENDDOC: + case META_DELETEOBJECT: + { + int index = getshort(handle); + DeleteMetaRecordHandle(index); + break; + } + case META_CREATEPALETTE: + { + wxMetaRecord *rec = new wxMetaRecord(META_CREATEPALETTE); + fread((void *)_buf, sizeof(char), (int)((2 * rdSize) - 6), handle); + + metaRecords.Append(rec); + gdiObjects.Append(rec); + AddMetaRecordHandle(rec); + rec->param2 = (long)(gdiObjects.GetCount() - 1); + break; + } + case META_CREATEBRUSH: + { + wxMetaRecord *rec = new wxMetaRecord(META_CREATEBRUSH); + fread((void *)_buf, sizeof(char), (int)((2 * rdSize) - 6), handle); + metaRecords.Append(rec); + gdiObjects.Append(rec); + AddMetaRecordHandle(rec); + rec->param2 = (long)(gdiObjects.GetCount() - 1); + break; + } + case META_CREATEPATTERNBRUSH: + { + wxMetaRecord *rec = new wxMetaRecord(META_CREATEPATTERNBRUSH); + fread((void *)_buf, sizeof(char), (int)((2 * rdSize) - 6), handle); + metaRecords.Append(rec); + gdiObjects.Append(rec); + AddMetaRecordHandle(rec); + rec->param2 = (long)(gdiObjects.GetCount() - 1); + break; + } + case META_CREATEPENINDIRECT: + { + wxMetaRecord *rec = new wxMetaRecord(META_CREATEPENINDIRECT); + int msStyle = getshort(handle); // Style: 2 bytes + int x = getshort(handle); // X: 2 bytes + /* int y = */ + getshort(handle); // Y: 2 bytes + long colorref = getint(handle); // COLORREF 4 bytes + + int style; + if (msStyle == PS_DOT) + style = wxDOT; + else if (msStyle == PS_DASH) + style = wxSHORT_DASH; + else if (msStyle == PS_NULL) + style = wxTRANSPARENT; + else style = wxSOLID; + + wxColour colour(GetRValue(colorref), GetGValue(colorref), GetBValue(colorref)); + rec->param1 = (long)wxThePenList->FindOrCreatePen(colour, x, style); + metaRecords.Append(rec); + gdiObjects.Append(rec); + + AddMetaRecordHandle(rec); + rec->param2 = (long)(gdiObjects.GetCount() - 1); + + // For some reason, the size of this record is sometimes 9 words!!! + // instead of the usual 8. So read 2 characters extra. + if (rdSize == 9) + { + (void) getshort(handle); + } + break; + } + case META_CREATEFONTINDIRECT: + { + wxMetaRecord *rec = new wxMetaRecord(META_CREATEFONTINDIRECT); + int lfHeight = getshort(handle); // 2 bytes + /* int lfWidth = */ + getshort(handle); // 2 bytes + /* int lfEsc = */ + getshort(handle); // 2 bytes + /* int lfOrient = */ + getshort(handle); // 2 bytes + int lfWeight = getshort(handle); // 2 bytes + char lfItalic = getc(handle); // 1 byte + char lfUnderline = getc(handle); // 1 byte + /* char lfStrikeout = */ + getc(handle); // 1 byte + /* char lfCharSet = */ + getc(handle); // 1 byte + /* char lfOutPrecision = */ + getc(handle); // 1 byte + /* char lfClipPrecision = */ + getc(handle); // 1 byte + /* char lfQuality = */ + getc(handle); // 1 byte + char lfPitchAndFamily = getc(handle); // 1 byte (18th) + char lfFacename[32]; + // Read the rest of the record, which is total record size + // minus the number of bytes already read (18 record, 6 metarecord + // header) + fread((void *)lfFacename, sizeof(char), (int)((2 * rdSize) - 18 - 6), handle); + + int family; + if (lfPitchAndFamily & FF_MODERN) + family = wxMODERN; + else if (lfPitchAndFamily & FF_MODERN) + family = wxMODERN; + else if (lfPitchAndFamily & FF_ROMAN) + family = wxROMAN; + else if (lfPitchAndFamily & FF_SWISS) + family = wxSWISS; + else if (lfPitchAndFamily & FF_DECORATIVE) + family = wxDECORATIVE; + else + family = wxDEFAULT; + + int weight; + if (lfWeight == 300) + weight = wxLIGHT; + else if (lfWeight == 400) + weight = wxNORMAL; + else if (lfWeight == 900) + weight = wxBOLD; + else weight = wxNORMAL; + + int style; + if (lfItalic != 0) + style = wxITALIC; + else + style = wxNORMAL; + + // About how many pixels per inch??? + int logPixelsY = 100; + int pointSize = (int)(lfHeight * 72.0 / logPixelsY); + + wxFont *theFont = + wxTheFontList->FindOrCreateFont(pointSize, family, style, weight, (lfUnderline != 0)); + + rec->param1 = (long) theFont; + metaRecords.Append(rec); + gdiObjects.Append(rec); + AddMetaRecordHandle(rec); + rec->param2 = (long)(gdiObjects.GetCount() - 1); + break; + } + case META_CREATEBRUSHINDIRECT: + { + wxMetaRecord *rec = new wxMetaRecord(META_CREATEBRUSHINDIRECT); + int msStyle = getshort(handle); // Style: 2 bytes + long colorref = getint(handle); // COLORREF: 4 bytes + int hatchStyle = getshort(handle); // Hatch style 2 bytes + + int style; + switch (msStyle) + { + case BS_HATCHED: + { + switch (hatchStyle) + { + case HS_BDIAGONAL: + style = wxBDIAGONAL_HATCH; + break; + case HS_DIAGCROSS: + style = wxCROSSDIAG_HATCH; + break; + case HS_FDIAGONAL: + style = wxFDIAGONAL_HATCH; + break; + case HS_HORIZONTAL: + style = wxHORIZONTAL_HATCH; + break; + case HS_VERTICAL: + style = wxVERTICAL_HATCH; + break; + default: + case HS_CROSS: + style = wxCROSS_HATCH; + break; + } + break; + } + case BS_SOLID: + default: + style = wxSOLID; + break; + } + if (msStyle == PS_DOT) + style = wxDOT; + else if (msStyle == PS_DASH) + style = wxSHORT_DASH; + else if (msStyle == PS_NULL) + style = wxTRANSPARENT; + else style = wxSOLID; + + wxColour colour(GetRValue(colorref), GetGValue(colorref), GetBValue(colorref)); + rec->param1 = (long)wxTheBrushList->FindOrCreateBrush(colour, style); + metaRecords.Append(rec); + gdiObjects.Append(rec); + AddMetaRecordHandle(rec); + rec->param2 = (long)(gdiObjects.GetCount() - 1); + break; + } + case META_CREATEBITMAPINDIRECT: + { + wxMetaRecord *rec = new wxMetaRecord(META_CREATEBITMAPINDIRECT); + fread((void *)_buf, sizeof(char), (int)((2 * rdSize) - 6), handle); + + metaRecords.Append(rec); + gdiObjects.Append(rec); + AddMetaRecordHandle(rec); + rec->param2 = (long)(gdiObjects.GetCount() - 1); + break; + } + case META_CREATEBITMAP: + { + wxMetaRecord *rec = new wxMetaRecord(META_CREATEBITMAP); + fread((void *)_buf, sizeof(char), (int)((2 * rdSize) - 6), handle); + + metaRecords.Append(rec); + gdiObjects.Append(rec); + AddMetaRecordHandle(rec); + rec->param2 = (long)(gdiObjects.GetCount() - 1); + break; + } + case META_CREATEREGION: + { + wxMetaRecord *rec = new wxMetaRecord(META_CREATEREGION); + fread((void *)_buf, sizeof(char), (int)((2 * rdSize) - 6), handle); + + metaRecords.Append(rec); + gdiObjects.Append(rec); + AddMetaRecordHandle(rec); + rec->param2 = (long)(gdiObjects.GetCount() - 1); + break; + } + default: + { + fread((void *)_buf, sizeof(char), (int)((2 * rdSize) - 6), handle); + break; + } + } + } + fclose(handle); + return TRUE; +} + +wxXMetaFile::~wxXMetaFile(void) +{ + wxNode *node = metaRecords.GetFirst(); + while (node) + { + wxMetaRecord *rec = (wxMetaRecord *)node->GetData(); + delete rec; + wxNode *next = node->GetNext(); + delete node; + node = next; + } +} + +bool wxXMetaFile::SetClipboard(int WXUNUSED(width), int WXUNUSED(height)) +{ + return FALSE; +} + +bool wxXMetaFile::Play(wxDC *dc) +{ + wxNode *node = metaRecords.GetFirst(); + while (node) + { + wxMetaRecord *rec = (wxMetaRecord *)node->GetData(); + int rdFunction = rec->metaFunction; + + switch (rdFunction) + { + case META_SETBKCOLOR: + { + break; + } + case META_SETBKMODE: + { + break; + } + case META_SETMAPMODE: + { + break; + } +// case META_SETROP2: +// case META_SETRELABS: +// case META_SETPOLYFILLMODE: +// case META_SETSTRETCHBLTMODE: +// case META_SETTEXTCHAREXTRA: + case META_SETTEXTCOLOR: + { + break; + } +// case META_SETTEXTJUSTIFICATION: + case META_SETWINDOWORG: + { + break; + } + case META_SETWINDOWEXT: + { + break; + } +// case META_SETVIEWPORTORG: +// case META_SETVIEWPORTEXT: +// case META_OFFSETWINDOWORG: +// case META_SCALEWINDOWEXT: +// case META_OFFSETVIEWPORTORG: +// case META_SCALEVIEWPORTEXT: + case META_LINETO: + { + long x1 = rec->param1; + long y1 = rec->param2; + dc->DrawLine((long) lastX, (long) lastY, x1, y1); + break; + } + case META_MOVETO: + { + lastX = (double)rec->param1; + lastY = (double)rec->param2; + break; + } + case META_EXCLUDECLIPRECT: + { + break; + } + case META_INTERSECTCLIPRECT: + { + break; + } +// case META_ARC: // DO!!! + case META_ELLIPSE: + { + break; + } +// case META_FLOODFILL: +// case META_PIE: // DO!!! + case META_RECTANGLE: + { + dc->DrawRectangle((long)rec->param1, (long)rec->param2, + (long)rec->param3 - rec->param1, + (long)rec->param4 - rec->param2); + break; + } + case META_ROUNDRECT: + { + dc->DrawRoundedRectangle((long)rec->param1, (long)rec->param2, + (long)rec->param3 - rec->param1, + (long)rec->param4 - rec->param2, + (long)rec->param5); + break; + } +// case META_PATBLT: +// case META_SAVEDC: + case META_SETPIXEL: + { +// rec->param1 = getshort(handle); // x1 +// rec->param2 = getshort(handle); // y1 +// rec->param3 = getint(handle); // COLORREF + break; + } +// case META_OFFSETCLIPRGN: + case META_TEXTOUT: + { + /* + int count = getshort(handle); + rec->stringParam = new char[count+1]; + fread((void *)rec->stringParam, sizeof(char), count, handle); + rec->stringParam[count] = 0; + rec->param2 = getshort(handle); // Y + rec->param1 = getshort(handle); // X + */ + break; + } +// case META_BITBLT: +// case META_STRETCHBLT: + case META_POLYGON: + { + /* + rec->param1 = getshort(handle); + rec->points = new wxRealPoint[(int)rec->param1]; + for (int i = 0; i < rec->param1; i++) + { + rec->points[i].x = getshort(handle); + rec->points[i].y = getshort(handle); + } + */ + break; + } + case META_POLYLINE: + { + /* + wxMetaRecord *rec = new wxMetaRecord(META_POLYLINE); + rec->param1 = (long)getshort(handle); + rec->points = new wxRealPoint[(int)rec->param1]; + for (int i = 0; i < rec->param1; i++) + { + rec->points[i].x = getshort(handle); + rec->points[i].y = getshort(handle); + } + */ + break; + } +// case META_ESCAPE: +// case META_RESTOREDC: +// case META_FILLREGION: +// case META_FRAMEREGION: +// case META_INVERTREGION: +// case META_PAINTREGION: +// case META_SELECTCLIPREGION: // DO THIS! + case META_SELECTOBJECT: + { + /* + wxMetaRecord *rec = new wxMetaRecord(META_SELECTOBJECT); + rec->param1 = (long)getshort(handle); // Position of object in gdiObjects list + */ + break; + } +// case META_SETTEXTALIGN: +// case META_DRAWTEXT: +// case META_CHORD: +// case META_SETMAPPERFLAGS: +// case META_EXTTEXTOUT: +// case META_SETDIBTODEV: +// case META_SELECTPALETTE: +// case META_REALIZEPALETTE: +// case META_ANIMATEPALETTE: +// case META_SETPALENTRIES: +// case META_POLYPOLYGON: +// case META_RESIZEPALETTE: +// case META_DIBBITBLT: +// case META_DIBSTRETCHBLT: + case META_DIBCREATEPATTERNBRUSH: + { + /* + fread((void *)wxBuffer, sizeof(char), (int)(rdSize - 3), handle); + */ + break; + } +// case META_STRETCHDIB: +// case META_EXTFLOODFILL: +// case META_RESETDC: +// case META_STARTDOC: +// case META_STARTPAGE: +// case META_ENDPAGE: +// case META_ABORTDOC: +// case META_ENDDOC: +// case META_DELETEOBJECT: // DO!! + case META_CREATEPALETTE: + { + /* + wxMetaRecord *rec = new wxMetaRecord(META_CREATEPALETTE); + fread((void *)wxBuffer, sizeof(char), (int)(rdSize - 3), handle); + */ + break; + } + case META_CREATEBRUSH: + { + /* + fread((void *)wxBuffer, sizeof(char), (int)(rdSize - 3), handle); + */ + break; + } + case META_CREATEPATTERNBRUSH: + { + /* + fread((void *)wxBuffer, sizeof(char), (int)(rdSize - 3), handle); + */ + break; + } + case META_CREATEPENINDIRECT: + { + /* + int msStyle = getshort(handle); // Style: 2 bytes + int x = getshort(handle); // X: 2 bytes + int y = getshort(handle); // Y: 2 bytes + int colorref = getint(handle); // COLORREF 4 bytes + + int style; + if (msStyle == PS_DOT) + style = wxDOT; + else if (msStyle == PS_DASH) + style = wxSHORT_DASH; + else if (msStyle == PS_NULL) + style = wxTRANSPARENT; + else style = wxSOLID; + + wxColour colour(GetRValue(colorref), GetGValue(colorref), GetBValue(colorref)); + rec->param1 = (long)wxThePenList->FindOrCreatePen(&colour, x, style); + */ + break; + } + case META_CREATEFONTINDIRECT: + { + /* + int lfHeight = getshort(handle); + int lfWidth = getshort(handle); + int lfEsc = getshort(handle); + int lfOrient = getshort(handle); + int lfWeight = getshort(handle); + char lfItalic = getc(handle); + char lfUnderline = getc(handle); + char lfStrikeout = getc(handle); + char lfCharSet = getc(handle); + char lfOutPrecision = getc(handle); + char lfClipPrecision = getc(handle); + char lfQuality = getc(handle); + char lfPitchAndFamily = getc(handle); + char lfFacename[32]; + fread((void *)lfFacename, sizeof(char), 32, handle); + + int family; + if (lfPitchAndFamily & FF_MODERN) + family = wxMODERN; + else if (lfPitchAndFamily & FF_MODERN) + family = wxMODERN; + else if (lfPitchAndFamily & FF_ROMAN) + family = wxROMAN; + else if (lfPitchAndFamily & FF_SWISS) + family = wxSWISS; + else if (lfPitchAndFamily & FF_DECORATIVE) + family = wxDECORATIVE; + else + family = wxDEFAULT; + + int weight; + if (lfWeight == 300) + weight = wxLIGHT; + else if (lfWeight == 400) + weight = wxNORMAL; + else if (lfWeight == 900) + weight = wxBOLD; + else weight = wxNORMAL; + + int style; + if ((bool)lfItalic) + style = wxITALIC; + else + style = wxNORMAL; + + // About how many pixels per inch??? + int logPixelsY = 100; + int pointSize = (int)(lfHeight*72.0/logPixelsY); + + wxFont *theFont = + wxTheFontList->FindOrCreateFont(pointSize, family, style, weight, (bool)lfUnderline); + + rec->param1 = (long)theFont; + */ + break; + } + case META_CREATEBRUSHINDIRECT: + { + /* + int msStyle = getshort(handle); // Style: 2 bytes + int colorref = getint(handle); // COLORREF: 4 bytes + int hatchStyle = getshort(handle); // Hatch style 2 bytes + + int style; + if (msStyle == PS_DOT) + style = wxDOT; + else if (msStyle == PS_DASH) + style = wxSHORT_DASH; + else if (msStyle == PS_NULL) + style = wxTRANSPARENT; + else style = wxSOLID; + + wxColour colour(GetRValue(colorref), GetGValue(colorref), GetBValue(colorref)); + rec->param1 = (long)wxTheBrushList->FindOrCreateBrush(&colour, wxSOLID); + */ + break; + } + case META_CREATEBITMAPINDIRECT: + { + /* + fread((void *)wxBuffer, sizeof(char), (int)(rdSize - 3), handle); + */ + break; + } + case META_CREATEBITMAP: + { + /* + fread((void *)wxBuffer, sizeof(char), (int)(rdSize - 3), handle); + */ + break; + } + case META_CREATEREGION: + { + dc->DestroyClippingRegion(); + /* + rec->param1 = getshort(handle); // Style: 2 bytes + */ + break; + } + default: + { + break; + } + } + node = node->GetNext(); + } + return TRUE; +} + diff --git a/ogl/module.mk b/ogl/module.mk new file mode 100644 index 0000000..d83b850 --- /dev/null +++ b/ogl/module.mk @@ -0,0 +1,30 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/ogl/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + ogl/basic.cpp \ + ogl/bmpshape.cpp \ + ogl/composit.cpp \ + ogl/divided.cpp \ + ogl/lines.cpp \ + ogl/oglmisc.cpp \ + ogl/basic2.cpp \ + ogl/canvas.cpp \ + ogl/constrnt.cpp \ + ogl/drawn.cpp \ + ogl/mfutils.cpp \ + ogl/ogldiag.cpp + +EXTRA_DIST += \ + ogl/module.mk \ + ogl/README + + diff --git a/ogl/ogldiag.cpp b/ogl/ogldiag.cpp new file mode 100644 index 0000000..6719469 --- /dev/null +++ b/ogl/ogldiag.cpp @@ -0,0 +1,736 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ogldiag.cpp - wxDiagram +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include +#include +#include + +#include "ogl/ogl.h" + + +IMPLEMENT_DYNAMIC_CLASS(wxDiagram, wxObject) + +// Object canvas +wxDiagram::wxDiagram() +{ + m_diagramCanvas = NULL; + m_quickEditMode = FALSE; + m_snapToGrid = TRUE; + m_gridSpacing = 5.0; + m_shapeList = new wxList; + m_mouseTolerance = DEFAULT_MOUSE_TOLERANCE; +} + +wxDiagram::~wxDiagram() +{ + if (m_shapeList) + delete m_shapeList; +} + +void wxDiagram::SetSnapToGrid(bool snap) +{ + m_snapToGrid = snap; +} + +void wxDiagram::SetGridSpacing(double spacing) +{ + m_gridSpacing = spacing; +} + +void wxDiagram::Snap(double *x, double *y) +{ + if (m_snapToGrid) + { + *x = m_gridSpacing * ((int)(*x / m_gridSpacing + 0.5)); + *y = m_gridSpacing * ((int)(*y / m_gridSpacing + 0.5)); + } +} + + +void wxDiagram::Redraw(wxDC &dc) +{ + if (m_shapeList) + { + if (GetCanvas()) + GetCanvas()->SetCursor(* wxHOURGLASS_CURSOR); + wxNode *current = m_shapeList->GetFirst(); + + while (current) + { + wxShape *object = (wxShape *)current->GetData(); + if (!object->GetParent()) + object->Draw(dc); + + current = current->GetNext(); + } + if (GetCanvas()) + GetCanvas()->SetCursor(* wxSTANDARD_CURSOR); + } +} + +void wxDiagram::Clear(wxDC &dc) +{ + dc.Clear(); +} + +// Insert object after addAfter, or at end of list. +void wxDiagram::AddShape(wxShape *object, wxShape *addAfter) +{ + wxNode *nodeAfter = NULL; + + + if (addAfter) + { +#if wxCHECK_VERSION(2, 9, 0) + nodeAfter = m_shapeList->Find(addAfter); +#else + nodeAfter = m_shapeList->Member(addAfter); +#endif + } + + if (!m_shapeList->Member(object)) + { + if (nodeAfter) + { + if (nodeAfter->GetNext()) + m_shapeList->Insert(nodeAfter->GetNext(), object); + else + m_shapeList->Append(object); + } + else + m_shapeList->Append(object); + object->SetCanvas(GetCanvas()); + } +} + +void wxDiagram::InsertShape(wxShape *object) +{ + m_shapeList->Insert(object); + object->SetCanvas(GetCanvas()); +} + +void wxDiagram::RemoveShape(wxShape *object) +{ + m_shapeList->DeleteObject(object); + object->RemoveChildren(); +} + +// Should this delete the actual objects too? I think not. +void wxDiagram::RemoveAllShapes() +{ + m_shapeList->Clear(); +} + +void wxDiagram::DeleteAllShapes() +{ + wxNode *node = m_shapeList->GetFirst(); + while (node) + { + wxShape *shape = (wxShape *)node->GetData(); + if (!shape->GetParent()) + { + RemoveShape(shape); + delete shape; + node = m_shapeList->GetFirst(); + } + else + node = node->GetNext(); + } +} + +void wxDiagram::ShowAll(bool show) +{ + wxNode *current = m_shapeList->GetFirst(); + + while (current) + { + wxShape *object = (wxShape *)current->GetData(); + object->Show(show); + + current = current->GetNext(); + } +} + +void wxDiagram::DrawOutline(wxDC &dc, double x1, double y1, double x2, double y2) +{ + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + dc.SetPen(dottedPen); + dc.SetBrush((* wxTRANSPARENT_BRUSH)); + + wxPoint points[5]; + + points[0].x = (int) x1; + points[0].y = (int) y1; + + points[1].x = (int) x2; + points[1].y = (int) y1; + + points[2].x = (int) x2; + points[2].y = (int) y2; + + points[3].x = (int) x1; + points[3].y = (int) y2; + + points[4].x = (int) x1; + points[4].y = (int) y1; + dc.DrawLines(5, points); +} + +// Make sure all text that should be centred, is centred. +void wxDiagram::RecentreAll(wxDC &dc) +{ + wxNode *object_node = m_shapeList->GetFirst(); + while (object_node) + { + wxShape *obj = (wxShape *)object_node->GetData(); + obj->Recentre(dc); + object_node = object_node->GetNext(); + } +} + +// Input/output +#if wxUSE_PROLOGIO +bool wxDiagram::SaveFile(const wxString &filename) +{ + wxBeginBusyCursor(); + + wxExprDatabase *database = new wxExprDatabase; + + // First write the diagram type + wxExpr *header = new wxExpr(wxT("diagram")); + OnHeaderSave(*database, *header); + + database->Append(header); + + wxNode *node = m_shapeList->GetFirst(); + while (node) + { + wxShape *shape = (wxShape *)node->GetData(); + + if (!shape->IsKindOf(CLASSINFO(wxControlPoint))) + { + wxExpr *expr; + if (shape->IsKindOf(CLASSINFO(wxLineShape))) + expr = new wxExpr(wxT("line")); + else + expr = new wxExpr(wxT("shape")); + + OnShapeSave(*database, *shape, *expr); + } + node = node->GetNext(); + } + OnDatabaseSave(*database); + + wxString tempFile; + wxGetTempFileName(wxT("diag"), tempFile); + FILE *file = fopen(tempFile.mb_str(wxConvFile), "w"); + if (! file) + { + wxEndBusyCursor(); + delete database; + return FALSE; + } + + database->Write(file); + fclose(file); + delete database; + + /* + // Save backup + if (FileExists(filename)) + { + char buf[400]; + #ifdef __X__ + sprintf(buf, "%s.bak", filename); + #endif + #ifdef __WXMSW__ + sprintf(buf, "_diagram.bak"); + #endif + if (FileExists(buf)) wxRemoveFile(buf); + if (!wxRenameFile(filename, buf)) + { + wxCopyFile(filename, buf); + wxRemoveFile(filename); + } + } + */ + + // Copy the temporary file to the correct filename + if (!wxRenameFile(tempFile, filename)) + { + wxCopyFile(tempFile, filename); + wxRemoveFile(tempFile); + } + + wxEndBusyCursor(); + return TRUE; +} + +bool wxDiagram::LoadFile(const wxString &filename) +{ + wxBeginBusyCursor(); + + wxExprDatabase database(wxExprInteger, wxT("id")); + if (!database.Read(filename)) + { + wxEndBusyCursor(); + return FALSE; + } + + DeleteAllShapes(); + + database.BeginFind(); + wxExpr *header = database.FindClauseByFunctor(wxT("diagram")); + + if (header) + OnHeaderLoad(database, *header); + + // Scan through all clauses and register the ids + wxNode *node = database.GetFirst(); + while (node) + { + wxExpr *clause = (wxExpr *)node->GetData(); + long id = -1; + clause->GetAttributeValue(wxT("id"), id); + wxRegisterId(id); + node = node->GetNext(); + } + + ReadNodes(database); + ReadContainerGeometry(database); + ReadLines(database); + + OnDatabaseLoad(database); + + wxEndBusyCursor(); + + return TRUE; +} + +void wxDiagram::ReadNodes(wxExprDatabase &database) +{ + // Find and create the node images + database.BeginFind(); + wxExpr *clause = database.FindClauseByFunctor(wxT("shape")); + while (clause) + { + wxChar *type = NULL; + long parentId = -1; + + clause->AssignAttributeValue(wxT("type"), &type); + clause->AssignAttributeValue(wxT("parent"), &parentId); + wxClassInfo *classInfo = wxClassInfo::FindClass(type); + if (classInfo) + { + wxShape *shape = (wxShape *)classInfo->CreateObject(); + OnShapeLoad(database, *shape, *clause); + + shape->SetCanvas(GetCanvas()); + shape->Show(TRUE); + + m_shapeList->Append(shape); + + // If child of composite, link up + if (parentId > -1) + { + wxExpr *parentExpr = database.HashFind(wxT("shape"), parentId); + if (parentExpr && parentExpr->GetClientData()) + { + wxShape *parent = (wxShape *)parentExpr->GetClientData(); + shape->SetParent(parent); + parent->GetChildren().Append(shape); + } + } + + clause->SetClientData(shape); + } + if (type) + delete[] type; + + clause = database.FindClauseByFunctor(wxT("shape")); + } + return; +} + +void wxDiagram::ReadLines(wxExprDatabase &database) +{ + database.BeginFind(); + wxExpr *clause = database.FindClauseByFunctor(wxT("line")); + while (clause) + { + wxString type; + long parentId = -1; + + clause->GetAttributeValue(wxT("type"), type); + clause->GetAttributeValue(wxT("parent"), parentId); + wxClassInfo *classInfo = wxClassInfo::FindClass(type); + if (classInfo) + { + wxLineShape *shape = (wxLineShape *)classInfo->CreateObject(); + shape->Show(TRUE); + + OnShapeLoad(database, *shape, *clause); + shape->SetCanvas(GetCanvas()); + + long image_to = -1; + long image_from = -1; + clause->GetAttributeValue(wxT("to"), image_to); + clause->GetAttributeValue(wxT("from"), image_from); + + wxExpr *image_to_expr = database.HashFind(wxT("shape"), image_to); + + if (!image_to_expr) + { + // Error + } + wxExpr *image_from_expr = database.HashFind(wxT("shape"), image_from); + + if (!image_from_expr) + { + // Error + } + + if (image_to_expr && image_from_expr) + { + wxShape *image_to_object = (wxShape *)image_to_expr->GetClientData(); + wxShape *image_from_object = (wxShape *)image_from_expr->GetClientData(); + + if (image_to_object && image_from_object) + { + image_from_object->AddLine(shape, image_to_object, shape->GetAttachmentFrom(), shape->GetAttachmentTo()); + } + } + clause->SetClientData(shape); + + m_shapeList->Append(shape); + } + + clause = database.FindClauseByFunctor(wxT("line")); + } +} + +// Containers have divisions that reference adjoining divisions, +// so we need a separate pass to link everything up. +// Also used by Symbol Library. +void wxDiagram::ReadContainerGeometry(wxExprDatabase &database) +{ + database.BeginFind(); + wxExpr *clause = database.FindClauseByFunctor(wxT("shape")); + while (clause) + { + wxShape *image = (wxShape *)clause->GetClientData(); + if (image && image->IsKindOf(CLASSINFO(wxCompositeShape))) + { + wxCompositeShape *composite = (wxCompositeShape *)image; + wxExpr *divisionExpr = NULL; + + // Find the list of divisions in the composite + clause->GetAttributeValue(wxT("divisions"), &divisionExpr); + if (divisionExpr) + { + int i = 0; + wxExpr *idExpr = divisionExpr->Nth(i); + while (idExpr) + { + long divisionId = idExpr->IntegerValue(); + wxExpr *childExpr = database.HashFind(wxT("shape"), divisionId); + if (childExpr && childExpr->GetClientData()) + { + wxDivisionShape *child = (wxDivisionShape *)childExpr->GetClientData(); + composite->GetDivisions().Append(child); + + // Find the adjoining shapes + long leftSideId = -1; + long topSideId = -1; + long rightSideId = -1; + long bottomSideId = -1; + childExpr->GetAttributeValue(wxT("left_side"), leftSideId); + childExpr->GetAttributeValue(wxT("top_side"), topSideId); + childExpr->GetAttributeValue(wxT("right_side"), rightSideId); + childExpr->GetAttributeValue(wxT("bottom_side"), bottomSideId); + if (leftSideId > -1) + { + wxExpr *leftExpr = database.HashFind(wxT("shape"), leftSideId); + if (leftExpr && leftExpr->GetClientData()) + { + wxDivisionShape *leftSide = (wxDivisionShape *)leftExpr->GetClientData(); + child->SetLeftSide(leftSide); + } + } + if (topSideId > -1) + { + wxExpr *topExpr = database.HashFind(wxT("shape"), topSideId); + if (topExpr && topExpr->GetClientData()) + { + wxDivisionShape *topSide = (wxDivisionShape *)topExpr->GetClientData(); + child->SetTopSide(topSide); + } + } + if (rightSideId > -1) + { + wxExpr *rightExpr = database.HashFind(wxT("shape"), rightSideId); + if (rightExpr && rightExpr->GetClientData()) + { + wxDivisionShape *rightSide = (wxDivisionShape *)rightExpr->GetClientData(); + child->SetRightSide(rightSide); + } + } + if (bottomSideId > -1) + { + wxExpr *bottomExpr = database.HashFind(wxT("shape"), bottomSideId); + if (bottomExpr && bottomExpr->GetClientData()) + { + wxDivisionShape *bottomSide = (wxDivisionShape *)bottomExpr->GetClientData(); + child->SetBottomSide(bottomSide); + } + } + } + i ++; + idExpr = divisionExpr->Nth(i); + } + } + } + + clause = database.FindClauseByFunctor(wxT("shape")); + } +} + +// Allow for modifying file +bool wxDiagram::OnDatabaseLoad(wxExprDatabase &WXUNUSED(db)) +{ + return TRUE; +} + +bool wxDiagram::OnDatabaseSave(wxExprDatabase &WXUNUSED(db)) +{ + return TRUE; +} + +bool wxDiagram::OnShapeSave(wxExprDatabase &db, wxShape &shape, wxExpr &expr) +{ + shape.WriteAttributes(&expr); + db.Append(&expr); + + if (shape.IsKindOf(CLASSINFO(wxCompositeShape))) + { + wxNode *node = shape.GetChildren().GetFirst(); + while (node) + { + wxShape *childShape = (wxShape *)node->GetData(); + wxExpr *childExpr = new wxExpr(wxT("shape")); + OnShapeSave(db, *childShape, *childExpr); + node = node->GetNext(); + } + } + + return TRUE; +} + +bool wxDiagram::OnShapeLoad(wxExprDatabase &WXUNUSED(db), wxShape &shape, wxExpr &expr) +{ + shape.ReadAttributes(&expr); + return TRUE; +} + +bool wxDiagram::OnHeaderSave(wxExprDatabase &WXUNUSED(db), wxExpr &WXUNUSED(expr)) +{ + return TRUE; +} + +bool wxDiagram::OnHeaderLoad(wxExprDatabase &WXUNUSED(db), wxExpr &WXUNUSED(expr)) +{ + return TRUE; +} + +#endif + +void wxDiagram::SetCanvas(wxShapeCanvas *can) +{ + m_diagramCanvas = can; +} + +// Find a shape by its id +wxShape *wxDiagram::FindShape(long id) const +{ + wxNode *node = GetShapeList()->GetFirst(); + while (node) + { + wxShape *shape = (wxShape *) node->GetData(); + if (shape->GetId() == id) + return shape; + node = node->GetNext(); + } + return NULL; +} + + +//// Crossings classes + +wxLineCrossings::wxLineCrossings() +{ +} + +wxLineCrossings::~wxLineCrossings() +{ + ClearCrossings(); +} + +void wxLineCrossings::FindCrossings(wxDiagram &diagram) +{ + ClearCrossings(); + wxNode *node1 = diagram.GetShapeList()->GetFirst(); + while (node1) + { + wxShape *shape1 = (wxShape *) node1->GetData(); + if (shape1->IsKindOf(CLASSINFO(wxLineShape))) + { + wxLineShape *lineShape1 = (wxLineShape *) shape1; + // Iterate through the segments + wxList *pts1 = lineShape1->GetLineControlPoints(); + size_t i; + for (i = 0; i < (pts1->GetCount() - 1); i++) + { + wxRealPoint *pt1_a = (wxRealPoint *) (pts1->Item(i)->GetData()); + wxRealPoint *pt1_b = (wxRealPoint *) (pts1->Item(i + 1)->GetData()); + + // Now we iterate through the segments again + + wxNode *node2 = diagram.GetShapeList()->GetFirst(); + while (node2) + { + wxShape *shape2 = (wxShape *) node2->GetData(); + + // Assume that the same line doesn't cross itself + if (shape2->IsKindOf(CLASSINFO(wxLineShape)) && (shape1 != shape2)) + { + wxLineShape *lineShape2 = (wxLineShape *) shape2; + // Iterate through the segments + wxList *pts2 = lineShape2->GetLineControlPoints(); + int j; + for (j = 0; j < (int) (pts2->GetCount() - 1); j++) + { + wxRealPoint *pt2_a = (wxRealPoint *) (pts2->Item(j)->GetData()); + wxRealPoint *pt2_b = (wxRealPoint *) (pts2->Item(j + 1)->GetData()); + + // Now let's see if these two segments cross. + double ratio1, ratio2; + oglCheckLineIntersection(pt1_a->x, pt1_a->y, pt1_b->x, pt1_b->y, + pt2_a->x, pt2_a->y, pt2_b->x, pt2_b->y, + & ratio1, & ratio2); + + if ((ratio1 < 1.0) && (ratio1 > -1.0)) + { + // Intersection! + wxLineCrossing *crossing = new wxLineCrossing; + crossing->m_intersect.x = (pt1_a->x + (pt1_b->x - pt1_a->x) * ratio1); + crossing->m_intersect.y = (pt1_a->y + (pt1_b->y - pt1_a->y) * ratio1); + + crossing->m_pt1 = * pt1_a; + crossing->m_pt2 = * pt1_b; + crossing->m_pt3 = * pt2_a; + crossing->m_pt4 = * pt2_b; + + crossing->m_lineShape1 = lineShape1; + crossing->m_lineShape2 = lineShape2; + + m_crossings.Append(crossing); + } + } + } + node2 = node2->GetNext(); + } + } + } + + node1 = node1->GetNext(); + } +} + +void wxLineCrossings::DrawCrossings(wxDiagram &WXUNUSED(diagram), wxDC &dc) +{ + dc.SetBrush(*wxTRANSPARENT_BRUSH); + + long arcWidth = 8; + + wxNode *node = m_crossings.GetFirst(); + while (node) + { + wxLineCrossing *crossing = (wxLineCrossing *) node->GetData(); +// dc.DrawEllipse((long) (crossing->m_intersect.x - (arcWidth/2.0) + 0.5), (long) (crossing->m_intersect.y - (arcWidth/2.0) + 0.5), +// arcWidth, arcWidth); + + + // Let's do some geometry to find the points on either end of the arc. + /* + + (x1, y1) + |\ + | \ + | \ + | \ + | \ + | |\ c c1 + | a | \ + | \ + | - x <-- centre of arc + a1 | b |\ + | | \ c2 + | a2 | \ + | - \ + | b2 \ + | \ + |_______________\ (x2, y2) + b1 + + */ + + double a1 = wxMax(crossing->m_pt1.y, crossing->m_pt2.y) - wxMin(crossing->m_pt1.y, crossing->m_pt2.y) ; + double b1 = wxMax(crossing->m_pt1.x, crossing->m_pt2.x) - wxMin(crossing->m_pt1.x, crossing->m_pt2.x) ; + double c1 = sqrt( (a1 * a1) + (b1 * b1) ); + + double c = arcWidth / 2.0; + double a = c * a1 / c1 ; + double b = c * b1 / c1 ; + + // I'm not sure this is right, since we don't know which direction we should be going in - need + // to know which way the line slopes and choose the sign appropriately. + double arcX1 = crossing->m_intersect.x - b; + double arcY1 = crossing->m_intersect.y - a; + + double arcX2 = crossing->m_intersect.x + b; + double arcY2 = crossing->m_intersect.y + a; + + dc.SetPen(*wxBLACK_PEN); + dc.DrawArc( (long) arcX1, (long) arcY1, (long) arcX2, (long) arcY2, + (long) crossing->m_intersect.x, (long) crossing->m_intersect.y); + + dc.SetPen(*wxWHITE_PEN); + dc.DrawLine( (long) arcX1, (long) arcY1, (long) arcX2, (long) arcY2 ); + + node = node->GetNext(); + } +} + +void wxLineCrossings::ClearCrossings() +{ + wxNode *node = m_crossings.GetFirst(); + while (node) + { + wxLineCrossing *crossing = (wxLineCrossing *) node->GetData(); + delete crossing; + node = node->GetNext(); + } + m_crossings.Clear(); +} + diff --git a/ogl/oglmisc.cpp b/ogl/oglmisc.cpp new file mode 100644 index 0000000..fa932bd --- /dev/null +++ b/ogl/oglmisc.cpp @@ -0,0 +1,911 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// misc.cpp - Miscellaneous OGL support functions +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include +#include +#include + +#include "ogl/ogl.h" + + +wxFont *g_oglNormalFont; +wxPen *g_oglBlackPen; +wxPen *g_oglWhiteBackgroundPen; +wxPen *g_oglTransparentPen; +wxBrush *g_oglWhiteBackgroundBrush; +wxPen *g_oglBlackForegroundPen; +wxCursor *g_oglBullseyeCursor = NULL; + +wxChar *oglBuffer = NULL; + +wxList oglObjectCopyMapping(wxKEY_INTEGER); + + + +void wxOGLInitialize() +{ + g_oglBullseyeCursor = new wxCursor(wxCURSOR_BULLSEYE); + + g_oglNormalFont = new wxFont(10, wxSWISS, wxNORMAL, wxNORMAL); + + g_oglBlackPen = new wxPen(wxT("BLACK"), 1, wxSOLID); + + g_oglWhiteBackgroundPen = new wxPen(wxT("WHITE"), 1, wxSOLID); + g_oglTransparentPen = new wxPen(wxT("WHITE"), 1, wxTRANSPARENT); + g_oglWhiteBackgroundBrush = new wxBrush(wxT("WHITE"), wxSOLID); + g_oglBlackForegroundPen = new wxPen(wxT("BLACK"), 1, wxSOLID); + + OGLInitializeConstraintTypes(); + + // Initialize big buffer used when writing images + oglBuffer = new wxChar[3000]; + +} + +void wxOGLCleanUp() +{ + if (oglBuffer) + { + delete[] oglBuffer; + oglBuffer = NULL; + } + oglBuffer = NULL; + + if (g_oglBullseyeCursor) + { + delete g_oglBullseyeCursor; + g_oglBullseyeCursor = NULL; + } + + if (g_oglNormalFont) + { + delete g_oglNormalFont; + g_oglNormalFont = NULL; + } + if (g_oglBlackPen) + { + delete g_oglBlackPen; + g_oglBlackPen = NULL; + } + if (g_oglWhiteBackgroundPen) + { + delete g_oglWhiteBackgroundPen; + g_oglWhiteBackgroundPen = NULL; + } + if (g_oglTransparentPen) + { + delete g_oglTransparentPen; + g_oglTransparentPen = NULL; + } + if (g_oglWhiteBackgroundBrush) + { + delete g_oglWhiteBackgroundBrush; + g_oglWhiteBackgroundBrush = NULL; + } + if (g_oglBlackForegroundPen) + { + delete g_oglBlackForegroundPen; + g_oglBlackForegroundPen = NULL; + } + + OGLCleanUpConstraintTypes(); +} + +wxFont *oglMatchFont(int point_size) +{ + wxFont *font = wxTheFontList->FindOrCreateFont(point_size, wxSWISS, wxNORMAL, wxNORMAL); +#if 0 + switch (point_size) + { + case 4: + font = swiss_font_4; + break; + case 6: + font = swiss_font_6; + break; + case 8: + font = swiss_font_8; + break; + case 12: + font = swiss_font_12; + break; + case 14: + font = swiss_font_14; + break; + case 18: + font = swiss_font_18; + break; + case 24: + font = swiss_font_24; + break; + default: + case 10: + font = swiss_font_10; + break; + } +#endif + return font; +} + +int FontSizeDialog(wxFrame *parent, int old_size) +{ + if (old_size <= 0) + old_size = 10; + wxString buf; + buf << old_size; + wxString ans = wxGetTextFromUser(wxT("Enter point size"), wxT("Font size"), buf, parent); + if (ans.Length() == 0) + return 0; + + long new_size = 0; + ans.ToLong(&new_size); + if ((new_size <= 0) || (new_size > 40)) + { + wxMessageBox(wxT("Invalid point size!"), wxT("Error"), wxOK); + return 0; + } + return new_size; + /* + char *strings[8]; + strings[0] = "4"; + strings[1] = "6"; + strings[2] = "8"; + strings[3] = "10"; + strings[4] = "12"; + strings[5] = "14"; + strings[6] = "18"; + strings[7] = "24"; + char *ans = wxGetSingleChoice("Choose", "Choose a font size", 8, strings, parent); + if (ans) + { + int size; + sscanf(ans, "%d", &size); + return oglMatchFont(size); + } + else return NULL; + */ +} + +// Centre a list of strings in the given box. xOffset and yOffset are the +// the positions that these lines should be relative to, and this might be +// the same as m_xpos, m_ypos, but might be zero if formatting from left-justifying. +void oglCentreText(wxDC &dc, wxList *text_list, + double m_xpos, double m_ypos, double width, double height, + int formatMode) +{ + int n = text_list->GetCount(); + + if (!text_list || (n == 0)) + return; + + // First, get maximum dimensions of box enclosing text +#if wxCHECK_VERSION(2, 9, 0) + wxCoord char_height = 0; + wxCoord max_width = 0; + wxCoord current_width = 0; +#else + long char_height = 0; + long max_width = 0; + long current_width = 0; +#endif + + // Store text extents for speed + double *widths = new double[n]; + + wxNode *current = text_list->GetFirst(); + int i = 0; + while (current) + { + wxShapeTextLine *line = (wxShapeTextLine *)current->GetData(); + dc.GetTextExtent(line->GetText(), ¤t_width, &char_height); + widths[i] = current_width; + + if (current_width > max_width) + max_width = current_width; + current = current->GetNext(); + i ++; + } + + double max_height = n * char_height; + + double xoffset, yoffset, xOffset, yOffset; + + if (formatMode & FORMAT_CENTRE_VERT) + { + if (max_height < height) + yoffset = (double)(m_ypos - (height / 2.0) + (height - max_height) / 2.0); + else + yoffset = (double)(m_ypos - (height / 2.0)); + yOffset = m_ypos; + } + else + { + yoffset = 0.0; + yOffset = 0.0; + } + + if (formatMode & FORMAT_CENTRE_HORIZ) + { + xoffset = (double)(m_xpos - width / 2.0); + xOffset = m_xpos; + } + else + { + xoffset = 0.0; + xOffset = 0.0; + } + + current = text_list->GetFirst(); + i = 0; + + while (current) + { + wxShapeTextLine *line = (wxShapeTextLine *)current->GetData(); + + double x; + if ((formatMode & FORMAT_CENTRE_HORIZ) && (widths[i] < width)) + x = (double)((width - widths[i]) / 2.0 + xoffset); + else + x = xoffset; + double y = (double)(i * char_height + yoffset); + + line->SetX( x - xOffset ); + line->SetY( y - yOffset ); + current = current->GetNext(); + i ++; + } + + delete[] widths; +} + +// Centre a list of strings in the given box +void oglCentreTextNoClipping(wxDC &dc, wxList *text_list, + double m_xpos, double m_ypos, double width, double height) +{ + int n = text_list->GetCount(); + + if (!text_list || (n == 0)) + return; + + // First, get maximum dimensions of box enclosing text + +#if wxCHECK_VERSION(2, 9, 0) + wxCoord char_height = 0; + wxCoord max_width = 0; + wxCoord current_width = 0; +#else + long char_height = 0; + long max_width = 0; + long current_width = 0; +#endif + + // Store text extents for speed + double *widths = new double[n]; + + wxNode *current = text_list->GetFirst(); + int i = 0; + while (current) + { + wxShapeTextLine *line = (wxShapeTextLine *)current->GetData(); + dc.GetTextExtent(line->GetText(), ¤t_width, &char_height); + widths[i] = current_width; + + if (current_width > max_width) + max_width = current_width; + current = current->GetNext(); + i ++; + } + + double max_height = n * char_height; + + double yoffset = (double)(m_ypos - (height / 2.0) + (height - max_height) / 2.0); + + double xoffset = (double)(m_xpos - width / 2.0); + + current = text_list->GetFirst(); + i = 0; + + while (current) + { + wxShapeTextLine *line = (wxShapeTextLine *)current->GetData(); + + double x = (double)((width - widths[i]) / 2.0 + xoffset); + double y = (double)(i * char_height + yoffset); + + line->SetX( x - m_xpos ); + line->SetY( y - m_ypos ); + current = current->GetNext(); + i ++; + } + delete[] widths; +} + +void oglGetCentredTextExtent(wxDC &dc, wxList *text_list, + double WXUNUSED(m_xpos), double WXUNUSED(m_ypos), double WXUNUSED(width), double WXUNUSED(height), + double *actual_width, double *actual_height) +{ + int n = text_list->GetCount(); + + if (!text_list || (n == 0)) + { + *actual_width = 0; + *actual_height = 0; + return; + } + + // First, get maximum dimensions of box enclosing text +#if wxCHECK_VERSION(2, 9, 0) + wxCoord char_height = 0; + wxCoord max_width = 0; + wxCoord current_width = 0; +#else + long char_height = 0; + long max_width = 0; + long current_width = 0; +#endif + + wxNode *current = text_list->GetFirst(); + while (current) + { + wxShapeTextLine *line = (wxShapeTextLine *)current->GetData(); + dc.GetTextExtent(line->GetText(), ¤t_width, &char_height); + + if (current_width > max_width) + max_width = current_width; + current = current->GetNext(); + } + + *actual_height = n * char_height; + *actual_width = max_width; +} + +// Format a string to a list of strings that fit in the given box. +// Interpret %n and 10 or 13 as a new line. +wxArrayString *oglFormatText(wxDC &dc, const wxString &text, double width, double WXUNUSED(height), int formatMode) +{ + // First, parse the string into a list of words + wxArrayString word_list; + + // Make new lines into NULL strings at this point + int i = 0; + int len = text.Length(); + wxString word; + // word.Alloc(30); // Seems to be a bug in string allocation that causes assertion when first appending + bool end_word = FALSE; + bool new_line = FALSE; + while (i < len) + { + switch ((wxChar)text[i]) + { + case wxT('%'): + { + i ++; + if (i == len) + { + word += wxT('%'); + } + else + { + if (text[i] == wxT('n')) + { + new_line = TRUE; + end_word = TRUE; + i++; + } + else + { + word += wxT('%'); + word += text[i]; + i ++; + } + } + break; + } + case 10: + { + new_line = TRUE; + end_word = TRUE; + i++; + break; + } + case 13: + { + new_line = TRUE; + end_word = TRUE; + i++; + } + case wxT(' '): + { + end_word = TRUE; + i ++; + break; + } + default: + { + word += text[i]; + i ++; + break; + } + } + if (i == len) end_word = TRUE; + if (end_word) + { + word_list.Add(word); + word.Empty(); + end_word = FALSE; + } + if (new_line) + { + word_list.Add(wxT("\n")); + new_line = FALSE; + } + } + // Now, make a list of strings which can fit in the box + wxArrayString *string_list = new wxArrayString ; + + wxString buffer; + +#if wxCHECK_VERSION(2, 9, 0) + wxCoord x, y; +#else + long x, y; +#endif + + size_t k; + for (k = 0; k < word_list.GetCount(); k++) + { + wxString oldBuffer(buffer); + + const wxString &s = word_list[k]; + if (s == wxT("\n")) + { + // FORCE NEW LINE + // if (buffer.Length() > 0) + string_list->Add(buffer); + + buffer.Empty(); + } + else + { + if (buffer.Length() != 0) + buffer += wxT(" "); + + buffer += s; + dc.GetTextExtent(buffer, &x, &y); + + // Don't fit within the bounding box if we're fitting shape to contents + if ((x > width) && !(formatMode & FORMAT_SIZE_TO_CONTENTS)) + { + // Deal with first word being wider than box + if (oldBuffer.Length() > 0) + string_list->Add(oldBuffer); + + buffer.Empty(); + buffer += s; + } + } + } + + if (buffer.Length() != 0) + string_list->Add(buffer); + + return string_list; +} + +void oglDrawFormattedText(wxDC &dc, wxList *text_list, + double m_xpos, double m_ypos, double width, double height, + int formatMode) +{ + double xoffset, yoffset; + if (formatMode & FORMAT_CENTRE_HORIZ) + xoffset = m_xpos; + else + xoffset = (double)(m_xpos - (width / 2.0)); + + if (formatMode & FORMAT_CENTRE_VERT) + yoffset = m_ypos; + else + yoffset = (double)(m_ypos - (height / 2.0)); + + dc.SetClippingRegion( + (long)(m_xpos - width / 2.0), (long)(m_ypos - height / 2.0), + (long)width + 1, (long)height + 1); + + wxNode *current = text_list->GetFirst(); + while (current) + { + wxShapeTextLine *line = (wxShapeTextLine *)current->GetData(); + + dc.DrawText(line->GetText(), WXROUND(xoffset + line->GetX()), WXROUND(yoffset + line->GetY())); + current = current->GetNext(); + } + + dc.DestroyClippingRegion(); +} + +/* + * Find centroid given list of points comprising polyline + * + */ + +void oglFindPolylineCentroid(wxList *points, double *x, double *y) +{ + double xcount = 0; + double ycount = 0; + + wxNode *node = points->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + xcount += point->x; + ycount += point->y; + node = node->GetNext(); + } + + *x = (xcount / points->GetCount()); + *y = (ycount / points->GetCount()); +} + +/* + * Check that (x1, y1) -> (x2, y2) hits (x3, y3) -> (x4, y4). + * If so, ratio1 gives the proportion along the first line + * that the intersection occurs (or something like that). + * Used by functions below. + * + */ +void oglCheckLineIntersection(double x1, double y1, double x2, double y2, + double x3, double y3, double x4, double y4, + double *ratio1, double *ratio2) +{ + double denominator_term = (y4 - y3) * (x2 - x1) - (y2 - y1) * (x4 - x3); + double numerator_term = (x3 - x1) * (y4 - y3) + (x4 - x3) * (y1 - y3); + + double line_constant; + double length_ratio = 1.0; + double k_line = 1.0; + + // Check for parallel lines + if ((denominator_term < 0.005) && (denominator_term > -0.005)) + line_constant = -1.0; + else + line_constant = numerator_term / denominator_term; + + // Check for intersection + if ((line_constant < 1.0) && (line_constant > 0.0)) + { + // Now must check that other line hits + if (((y4 - y3) < 0.005) && ((y4 - y3) > -0.005)) + k_line = ((x1 - x3) + line_constant * (x2 - x1)) / (x4 - x3); + else + k_line = ((y1 - y3) + line_constant * (y2 - y1)) / (y4 - y3); + + if ((k_line >= 0.0) && (k_line < 1.0)) + length_ratio = line_constant; + else + k_line = 1.0; + } + *ratio1 = length_ratio; + *ratio2 = k_line; +} + +/* + * Find where (x1, y1) -> (x2, y2) hits one of the lines in xvec, yvec. + * (*x3, *y3) is the point where it hits. + * + */ +void oglFindEndForPolyline(double n, double xvec[], double yvec[], + double x1, double y1, double x2, double y2, double *x3, double *y3) +{ + int i; + double lastx = xvec[0]; + double lasty = yvec[0]; + + double min_ratio = 1.0; + double line_ratio; + double other_ratio; + + for (i = 1; i < n; i++) + { + oglCheckLineIntersection(x1, y1, x2, y2, lastx, lasty, xvec[i], yvec[i], + &line_ratio, &other_ratio); + lastx = xvec[i]; + lasty = yvec[i]; + + if (line_ratio < min_ratio) + min_ratio = line_ratio; + } + + // Do last (implicit) line if last and first doubles are not identical + if (!(xvec[0] == lastx && yvec[0] == lasty)) + { + oglCheckLineIntersection(x1, y1, x2, y2, lastx, lasty, xvec[0], yvec[0], + &line_ratio, &other_ratio); + + if (line_ratio < min_ratio) + min_ratio = line_ratio; + } + + *x3 = (x1 + (x2 - x1) * min_ratio); + *y3 = (y1 + (y2 - y1) * min_ratio); + +} + +/* + * Find where the line hits the box. + * + */ + +void oglFindEndForBox(double width, double height, + double x1, double y1, // Centre of box (possibly) + double x2, double y2, // other end of line + double *x3, double *y3) // End on box edge +{ + double xvec[5]; + double yvec[5]; + + xvec[0] = (double)(x1 - width / 2.0); + yvec[0] = (double)(y1 - height / 2.0); + xvec[1] = (double)(x1 - width / 2.0); + yvec[1] = (double)(y1 + height / 2.0); + xvec[2] = (double)(x1 + width / 2.0); + yvec[2] = (double)(y1 + height / 2.0); + xvec[3] = (double)(x1 + width / 2.0); + yvec[3] = (double)(y1 - height / 2.0); + xvec[4] = (double)(x1 - width / 2.0); + yvec[4] = (double)(y1 - height / 2.0); + + oglFindEndForPolyline(5, xvec, yvec, x2, y2, x1, y1, x3, y3); +} + +/* + * Find where the line hits the circle. + * + */ + +void oglFindEndForCircle(double radius, + double x1, double y1, // Centre of circle + double x2, double y2, // Other end of line + double *x3, double *y3) +{ + double H = (double)sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); + + if (H == 0.0) + { + *x3 = x1; + *y3 = y1; + } + else + { + *y3 = radius * (y2 - y1) / H + y1; + *x3 = radius * (x2 - x1) / H + x1; + } +} + +/* + * Given the line (x1, y1) -> (x2, y2), and an arrow size of given length and width, + * return the position of the tip of the arrow and the left and right vertices of the arrow. + * + */ + +void oglGetArrowPoints(double x1, double y1, double x2, double y2, + double length, double width, + double *tip_x, double *tip_y, + double *side1_x, double *side1_y, + double *side2_x, double *side2_y) +{ + double l = (double)sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); + + if (l < 0.01) + l = (double) 0.01; + + double i_bar = (x2 - x1) / l; + double j_bar = (y2 - y1) / l; + + double x3 = (- length * i_bar) + x2; + double y3 = (- length * j_bar) + y2; + + *side1_x = width * (-j_bar) + x3; + *side1_y = width * i_bar + y3; + + *side2_x = -width * (-j_bar) + x3; + *side2_y = -width * i_bar + y3; + + *tip_x = x2; + *tip_y = y2; +} + +/* + * Given an ellipse and endpoints of a line, returns the point at which + * the line touches the ellipse in values x4, y4. + * This function assumes that the centre of the ellipse is at x1, y1, and the + * ellipse has a width of width1 and a height of height1. It also assumes you are + * wanting to draw an arc FROM point x2, y2 TOWARDS point x3, y3. + * This function calculates the x,y coordinates of the intersection point of + * the arc with the ellipse. + * Author: Ian Harrison + */ + +void oglDrawArcToEllipse(double x1, double y1, double width1, double height1, double x2, double y2, double x3, double y3, + double *x4, double *y4) +{ + double a1 = (double)(width1 / 2.0); + double b1 = (double)(height1 / 2.0); + + // These are required to give top left x and y coordinates for DrawEllipse +// double top_left_x1 = (double)(x1 - a1); +// double top_left_y1 = (double)(y1 - b1); + /* + // Check for vertical line + if (fabs(x2 - x3) < 0.05) + { + *x4 = x3; + if (y2 < y3) + *y4 = (double)(y1 - b1); + else + *y4 = (double)(y1 + b1); + return; + } + */ + // Check that x2 != x3 + if (fabs(x2 - x3) < 0.05) + { + *x4 = x2; + if (y3 > y2) + *y4 = (double)(y1 - sqrt((b1 * b1 - (((x2 - x1) * (x2 - x1)) * (b1 * b1) / (a1 * a1))))); + else + *y4 = (double)(y1 + sqrt((b1 * b1 - (((x2 - x1) * (x2 - x1)) * (b1 * b1) / (a1 * a1))))); + return; + } + + // Calculate the x and y coordinates of the point where arc intersects ellipse + + double A, B, C, D, E, F, G, H, K; + double ellipse1_x, ellipse1_y; + + A = (double)(1 / (a1 * a1)); + B = (double)((y3 - y2) * (y3 - y2)) / ((x3 - x2) * (x3 - x2) * b1 * b1); + C = (double)(2 * (y3 - y2) * (y2 - y1)) / ((x3 - x2) * b1 * b1); + D = (double)((y2 - y1) * (y2 - y1)) / (b1 * b1); + E = (double)(A + B); + F = (double)(C - (2 * A * x1) - (2 * B * x2)); + G = (double)((A * x1 * x1) + (B * x2 * x2) - (C * x2) + D - 1); + H = (double)((y3 - y2) / (x3 - x2)); + K = (double)((F * F) - (4 * E * G)); + + if (K >= 0) + // In this case the line intersects the ellipse, so calculate intersection + { + if(x2 >= x1) + { + ellipse1_x = (double)(((F * -1) + sqrt(K)) / (2 * E)); + ellipse1_y = (double)((H * (ellipse1_x - x2)) + y2); + } + else + { + ellipse1_x = (double)(((F * -1) - sqrt(K)) / (2 * E)); + ellipse1_y = (double)((H * (ellipse1_x - x2)) + y2); + } + } + else + // in this case, arc does not intersect ellipse, so just draw arc + { + ellipse1_x = x3; + ellipse1_y = y3; + } + *x4 = ellipse1_x; + *y4 = ellipse1_y; + + /* + // Draw a little circle (radius = 2) at the end of the arc where it hits + // the ellipse . + + double circle_x = ellipse1_x - 2.0; + double circle_y = ellipse1_y - 2.0; + m_canvas->DrawEllipse(circle_x, circle_y, 4.0, 4.0); + */ +} + +// Update a list item from a list of strings +void UpdateListBox(wxListBox *item, wxList *list) +{ + item->Clear(); + if (!list) + return; + + wxNode *node = list->GetFirst(); + while (node) + { + wxChar *s = (wxChar *)node->GetData(); + item->Append(s); + node = node->GetNext(); + } +} + +bool oglRoughlyEqual(double val1, double val2, double tol) +{ + return ( (val1 < (val2 + tol)) && (val1 > (val2 - tol)) && + (val2 < (val1 + tol)) && (val2 > (val1 - tol))); +} + +/* + * Hex<->Dec conversion + */ + +// Array used in DecToHex conversion routine. +static wxChar sg_HexArray[] = { wxT('0'), wxT('1'), wxT('2'), wxT('3'), + wxT('4'), wxT('5'), wxT('6'), wxT('7'), + wxT('8'), wxT('9'), wxT('A'), wxT('B'), + wxT('C'), wxT('D'), wxT('E'), wxT('F') + }; + +// Convert 2-digit hex number to decimal +unsigned int oglHexToDec(wxChar *buf) +{ + int firstDigit, secondDigit; + + if (buf[0] >= wxT('A')) + firstDigit = buf[0] - wxT('A') + 10; + else + firstDigit = buf[0] - wxT('0'); + + if (buf[1] >= wxT('A')) + secondDigit = buf[1] - wxT('A') + 10; + else + secondDigit = buf[1] - wxT('0'); + + return firstDigit * 16 + secondDigit; +} + +// Convert decimal integer to 2-character hex string +void oglDecToHex(unsigned int dec, wxChar *buf) +{ + int firstDigit = (int)(dec / 16.0); + int secondDigit = (int)(dec - (firstDigit * 16.0)); + buf[0] = sg_HexArray[firstDigit]; + buf[1] = sg_HexArray[secondDigit]; + buf[2] = 0; +} + +// 3-digit hex to wxColour +wxColour oglHexToColour(const wxString &hex) +{ + if (hex.Length() == 6) + { + long r, g, b; + r = g = b = 0; + hex.Mid(0, 2).ToLong(&r, 16); + hex.Mid(2, 2).ToLong(&g, 16); + hex.Mid(4, 2).ToLong(&b, 16); + return wxColour(r, g, b); + } + else + return wxColour(0, 0, 0); +} + +// RGB to 3-digit hex +wxString oglColourToHex(const wxColour &colour) +{ + wxChar buf[7]; + unsigned int red = colour.Red(); + unsigned int green = colour.Green(); + unsigned int blue = colour.Blue(); + + oglDecToHex(red, buf); + oglDecToHex(green, buf + 2); + oglDecToHex(blue, buf + 4); + + return wxString(buf); +} + + diff --git a/pgscript/README b/pgscript/README new file mode 100644 index 0000000..e038862 --- /dev/null +++ b/pgscript/README @@ -0,0 +1,10 @@ +Please refer to xtra/pgscript/doc/developers.html for the pgScript developer +documentation. + +parser.sh must be called for regenerating Flex and Bison source files because it +does some more processing than just executing Bison and Flex: it replaces some +headers and add other ones. + +Please use Flex 2.5.33 otherwise the pgadmin/include/pgscript/FlexLexer.h file +will not be valid. If you use a different version from 2.5.33 you need to copy FlexLexer.h that comes along with your Flex distribution to +pgadmin/include/pgscript. diff --git a/pgscript/exceptions/module.mk b/pgscript/exceptions/module.mk new file mode 100644 index 0000000..7dfa269 --- /dev/null +++ b/pgscript/exceptions/module.mk @@ -0,0 +1,24 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/pgscript/exceptions/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + pgscript/exceptions/pgsArithmeticException.cpp \ + pgscript/exceptions/pgsAssertException.cpp \ + pgscript/exceptions/pgsBreakException.cpp \ + pgscript/exceptions/pgsCastException.cpp \ + pgscript/exceptions/pgsContinueException.cpp \ + pgscript/exceptions/pgsException.cpp \ + pgscript/exceptions/pgsInterruptException.cpp \ + pgscript/exceptions/pgsParameterException.cpp + +EXTRA_DIST += \ + pgscript/exceptions/module.mk + diff --git a/pgscript/exceptions/pgsArithmeticException.cpp b/pgscript/exceptions/pgsArithmeticException.cpp new file mode 100644 index 0000000..4d2d15f --- /dev/null +++ b/pgscript/exceptions/pgsArithmeticException.cpp @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/exceptions/pgsArithmeticException.h" + +pgsArithmeticException::pgsArithmeticException(const wxString &left, const wxString &right) : + pgsException(), m_left(left), m_right(right) +{ + +} + +pgsArithmeticException::~pgsArithmeticException() +{ + +} + +const wxString pgsArithmeticException::message() const +{ + return wxString() << PGSOUTEXCEPTION << + wxString::Format(_("Arithmetic Exception - Operation impossible between '%s' and '%s'"), + m_left.c_str(), m_right.c_str()); +} diff --git a/pgscript/exceptions/pgsAssertException.cpp b/pgscript/exceptions/pgsAssertException.cpp new file mode 100644 index 0000000..e33d35c --- /dev/null +++ b/pgscript/exceptions/pgsAssertException.cpp @@ -0,0 +1,28 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/exceptions/pgsAssertException.h" + +pgsAssertException::pgsAssertException(const wxString &message) : + m_message(message) +{ + +} + +pgsAssertException::~pgsAssertException() +{ + +} + +const wxString pgsAssertException::message() const +{ + return wxString() << PGSOUTEXCEPTION << _("Assert Exception - ") << m_message; +} diff --git a/pgscript/exceptions/pgsBreakException.cpp b/pgscript/exceptions/pgsBreakException.cpp new file mode 100644 index 0000000..9179c35 --- /dev/null +++ b/pgscript/exceptions/pgsBreakException.cpp @@ -0,0 +1,28 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/exceptions/pgsBreakException.h" + +pgsBreakException::pgsBreakException() : + pgsException() +{ + +} + +pgsBreakException::~pgsBreakException() +{ + +} + +const wxString pgsBreakException::message() const +{ + return wxT("BREAK"); +} diff --git a/pgscript/exceptions/pgsCastException.cpp b/pgscript/exceptions/pgsCastException.cpp new file mode 100644 index 0000000..7c537c4 --- /dev/null +++ b/pgscript/exceptions/pgsCastException.cpp @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/exceptions/pgsCastException.h" + +pgsCastException::pgsCastException(const wxString &value, const wxString &type) : + pgsException(), m_value(value), m_type(type) +{ + +} + +pgsCastException::~pgsCastException() +{ + +} + +const wxString pgsCastException::message() const +{ + return wxString() << PGSOUTEXCEPTION << + wxString::Format(_("Cast Exception - Cannot convert '%s' to '%s'"), + m_value.c_str(), m_type.c_str()); +} diff --git a/pgscript/exceptions/pgsContinueException.cpp b/pgscript/exceptions/pgsContinueException.cpp new file mode 100644 index 0000000..fdfd4e6 --- /dev/null +++ b/pgscript/exceptions/pgsContinueException.cpp @@ -0,0 +1,28 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/exceptions/pgsContinueException.h" + +pgsContinueException::pgsContinueException() : + pgsException() +{ + +} + +pgsContinueException::~pgsContinueException() +{ + +} + +const wxString pgsContinueException::message() const +{ + return wxT("CONTINUE"); +} diff --git a/pgscript/exceptions/pgsException.cpp b/pgscript/exceptions/pgsException.cpp new file mode 100644 index 0000000..3649cd3 --- /dev/null +++ b/pgscript/exceptions/pgsException.cpp @@ -0,0 +1,22 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/exceptions/pgsException.h" + +pgsException::pgsException() +{ + +} + +pgsException::~pgsException() +{ + +} diff --git a/pgscript/exceptions/pgsInterruptException.cpp b/pgscript/exceptions/pgsInterruptException.cpp new file mode 100644 index 0000000..89445b4 --- /dev/null +++ b/pgscript/exceptions/pgsInterruptException.cpp @@ -0,0 +1,28 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/exceptions/pgsInterruptException.h" + +pgsInterruptException::pgsInterruptException() : + pgsException() +{ + +} + +pgsInterruptException::~pgsInterruptException() +{ + +} + +const wxString pgsInterruptException::message() const +{ + return wxString() << PGSOUTEXCEPTION << _("pgScript interrupted"); +} diff --git a/pgscript/exceptions/pgsParameterException.cpp b/pgscript/exceptions/pgsParameterException.cpp new file mode 100644 index 0000000..5a653a5 --- /dev/null +++ b/pgscript/exceptions/pgsParameterException.cpp @@ -0,0 +1,35 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "pgscript/exceptions/pgsParameterException.h" + +pgsParameterException::pgsParameterException(const wxString &message) : + pgsException(), m_message(message) +{ + +} + +pgsParameterException::~pgsParameterException() +{ + +} + +const wxString pgsParameterException::message() const +{ + wxString message(m_message); + message.Replace(wxT("\n"), wxT("\n") + generate_spaces(PGSOUTEXCEPTION.Length())); + message.Prepend(wxT(">> ")); + message.Prepend(generate_spaces(PGSOUTEXCEPTION.Length())); + return wxString() << PGSOUTEXCEPTION << + wxString::Format(_("Parameter Exception - Some parameters are invalid:\n%s"), + message.c_str()); +} diff --git a/pgscript/expressions/module.mk b/pgscript/expressions/module.mk new file mode 100644 index 0000000..54f43ba --- /dev/null +++ b/pgscript/expressions/module.mk @@ -0,0 +1,53 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/pgscript/expressions/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + pgscript/expressions/pgsAnd.cpp \ + pgscript/expressions/pgsAssign.cpp \ + pgscript/expressions/pgsAssignToRecord.cpp \ + pgscript/expressions/pgsCast.cpp \ + pgscript/expressions/pgsColumns.cpp \ + pgscript/expressions/pgsDifferent.cpp \ + pgscript/expressions/pgsEqual.cpp \ + pgscript/expressions/pgsExecute.cpp \ + pgscript/expressions/pgsExpression.cpp \ + pgscript/expressions/pgsGenDate.cpp \ + pgscript/expressions/pgsGenDateTime.cpp \ + pgscript/expressions/pgsGenDictionary.cpp \ + pgscript/expressions/pgsGenInt.cpp \ + pgscript/expressions/pgsGenReal.cpp \ + pgscript/expressions/pgsGenReference.cpp \ + pgscript/expressions/pgsGenRegex.cpp \ + pgscript/expressions/pgsGenString.cpp \ + pgscript/expressions/pgsGenTime.cpp \ + pgscript/expressions/pgsGreater.cpp \ + pgscript/expressions/pgsGreaterEqual.cpp \ + pgscript/expressions/pgsIdent.cpp \ + pgscript/expressions/pgsIdentRecord.cpp \ + pgscript/expressions/pgsLines.cpp \ + pgscript/expressions/pgsLower.cpp \ + pgscript/expressions/pgsLowerEqual.cpp \ + pgscript/expressions/pgsMinus.cpp \ + pgscript/expressions/pgsModulo.cpp \ + pgscript/expressions/pgsNegate.cpp \ + pgscript/expressions/pgsNot.cpp \ + pgscript/expressions/pgsOperation.cpp \ + pgscript/expressions/pgsOr.cpp \ + pgscript/expressions/pgsOver.cpp \ + pgscript/expressions/pgsParenthesis.cpp \ + pgscript/expressions/pgsPlus.cpp \ + pgscript/expressions/pgsRemoveLine.cpp \ + pgscript/expressions/pgsTimes.cpp \ + pgscript/expressions/pgsTrim.cpp + +EXTRA_DIST += \ + pgscript/expressions/module.mk + diff --git a/pgscript/expressions/pgsAnd.cpp b/pgscript/expressions/pgsAnd.cpp new file mode 100644 index 0000000..d1d2d4b --- /dev/null +++ b/pgscript/expressions/pgsAnd.cpp @@ -0,0 +1,57 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsAnd.h" + +#include "pgscript/objects/pgsNumber.h" + +pgsAnd::pgsAnd(const pgsExpression *left, const pgsExpression *right) : + pgsOperation(left, right) +{ + +} + +pgsAnd::~pgsAnd() +{ + +} + +pgsExpression *pgsAnd::clone() const +{ + return pnew pgsAnd(*this); +} + +pgsAnd::pgsAnd(const pgsAnd &that) : + pgsOperation(that) +{ + +} + +pgsAnd &pgsAnd::operator =(const pgsAnd &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + + return (*this); +} + +wxString pgsAnd::value() const +{ + return wxString() << m_left->value() << wxT(" AND ") << m_right->value(); +} + +pgsOperand pgsAnd::eval(pgsVarMap &vars) const +{ + return pnew pgsNumber(wxString() << (m_left->eval(vars)->pgs_is_true() + && m_right->eval(vars)->pgs_is_true()), pgsInt); +} diff --git a/pgscript/expressions/pgsAssign.cpp b/pgscript/expressions/pgsAssign.cpp new file mode 100644 index 0000000..a4f0b12 --- /dev/null +++ b/pgscript/expressions/pgsAssign.cpp @@ -0,0 +1,59 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsAssign.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsAssign::pgsAssign(const wxString &name, const pgsExpression *var) : + pgsExpression(), m_name(name), m_var(var) +{ + +} + +pgsAssign::~pgsAssign() +{ + pdelete(m_var); +} + +pgsExpression *pgsAssign::clone() const +{ + return pnew pgsAssign(*this); +} + +pgsAssign::pgsAssign(const pgsAssign &that) : + pgsExpression(that), m_name(that.m_name) +{ + m_var = that.m_var->clone(); +} + +pgsAssign &pgsAssign::operator =(const pgsAssign &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + m_name = that.m_name; + pdelete(m_var); + m_var = that.m_var->clone(); + } + return (*this); +} + +wxString pgsAssign::value() const +{ + return wxString() << wxT("SET ") << m_name << wxT(" = ") << m_var->value(); +} + +pgsOperand pgsAssign::eval(pgsVarMap &vars) const +{ + vars[m_name] = m_var->eval(vars); + return vars[m_name]; +} diff --git a/pgscript/expressions/pgsAssignToRecord.cpp b/pgscript/expressions/pgsAssignToRecord.cpp new file mode 100644 index 0000000..a0c1faf --- /dev/null +++ b/pgscript/expressions/pgsAssignToRecord.cpp @@ -0,0 +1,138 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsAssignToRecord.h" + +#include "pgscript/exceptions/pgsParameterException.h" +#include "pgscript/expressions/pgsIdentRecord.h" +#include "pgscript/objects/pgsRecord.h" + +pgsAssignToRecord::pgsAssignToRecord(const wxString &name, const pgsExpression *line, + const pgsExpression *column, const pgsExpression *var) : + pgsAssign(name, var), m_line(line), m_column(column) +{ + +} + +pgsAssignToRecord::~pgsAssignToRecord() +{ + pdelete(m_line); + pdelete(m_column); +} + +pgsExpression *pgsAssignToRecord::clone() const +{ + return pnew pgsAssignToRecord(*this); +} + +pgsAssignToRecord::pgsAssignToRecord(const pgsAssignToRecord &that) : + pgsAssign(that) +{ + m_line = that.m_line->clone(); + m_column = that.m_column->clone(); +} + +pgsAssignToRecord &pgsAssignToRecord::operator =(const pgsAssignToRecord &that) +{ + if (this != &that) + { + pgsAssign::operator=(that); + pdelete(m_line); + pdelete(m_column); + m_line = that.m_line->clone(); + m_column = that.m_column->clone(); + } + return (*this); +} + +wxString pgsAssignToRecord::value() const +{ + return wxString() << wxT("SET ") << m_name << wxT("[") << m_line->value() + << wxT("]") << wxT("[") << m_column->value() << wxT("]") + << wxT(" = ") << m_var->value(); +} + +pgsOperand pgsAssignToRecord::eval(pgsVarMap &vars) const +{ + if (vars.find(m_name) != vars.end() && vars[m_name]->is_record()) + { + // Get the operand as a record + pgsRecord &rec = dynamic_cast(*vars[m_name]); + + // Get the value to assign + pgsOperand var(m_var->eval(vars)); + + if (!var->is_record()) + { + // Evaluate parameters + pgsOperand line(m_line->eval(vars)); + pgsOperand column(m_column->eval(vars)); + if (line->is_integer()) + { + long aux_line; + line->value().ToLong(&aux_line); + + if (column->is_integer() || column->is_string()) + { + bool success = false; + + if (column->is_integer()) + { + long aux_column; + column->value().ToLong(&aux_column); + if (aux_column < rec.count_columns()) + { + success = rec.insert(aux_line, aux_column, var); + } + } + else if (column->is_string()) + { + USHORT aux_column = rec.get_column(column->value()); + if (aux_column < rec.count_columns()) + { + success = rec.insert(aux_line, aux_column, var); + } + } + + if (success == false) + { + throw pgsParameterException(wxString() << wxT("An error ") + << wxT("occurred in record affectation: ") << value() + << wxT("\n") << wxT("One possible reason is a ") + << wxT("column index out of range")); + } + } + + else + { + throw pgsParameterException(wxString() << column->value() + << wxT(" is not a valid column number/name")); + } + } + else + { + throw pgsParameterException(wxString() << line->value() + << wxT(" is not a valid line number")); + } + } + else + { + throw pgsParameterException(wxString() << wxT("Cannot assign a record") + << wxT(" into a record: right member is a record")); + } + } + else + { + throw pgsParameterException(wxString() << m_name << wxT(" is not a record")); + } + + return pgsIdentRecord(m_name, m_line->clone(), m_column->clone()).eval(vars); +} diff --git a/pgscript/expressions/pgsCast.cpp b/pgscript/expressions/pgsCast.cpp new file mode 100644 index 0000000..e930c49 --- /dev/null +++ b/pgscript/expressions/pgsCast.cpp @@ -0,0 +1,100 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsCast.h" + +#include "pgscript/exceptions/pgsParameterException.h" +#include "pgscript/objects/pgsNumber.h" + +#include "pgscript/parser.tab.hh" +typedef pgscript::pgsParser::token token; + +pgsCast::pgsCast(const int &cast_type, const pgsExpression *var) : + pgsExpression(), m_cast_type(cast_type), m_var(var) +{ + +} + +pgsCast::~pgsCast() +{ + pdelete(m_var); +} + +pgsExpression *pgsCast::clone() const +{ + return pnew pgsCast(*this); +} + +pgsCast::pgsCast(const pgsCast &that) : + pgsExpression(that), m_cast_type(that.m_cast_type) +{ + m_var = that.m_var->clone(); +} + +pgsCast &pgsCast::operator =(const pgsCast &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + m_cast_type = that.m_cast_type; + pdelete(m_var); + m_var = that.m_var->clone(); + } + return (*this); +} + +wxString pgsCast::value() const +{ + wxString cast_type; + + switch (m_cast_type) + { + case token::PGS_INTEGER: + cast_type = wxT("integer"); + break; + case token::PGS_REAL: + cast_type = wxT("real"); + break; + case token::PGS_RECORD: + cast_type = wxT("record"); + break; + case token::PGS_STRING: + cast_type = wxT("string"); + break; + default: + cast_type = wxT("unknown"); + break; + } + return wxString() << wxT("CAST (") << m_var->value() << wxT(" AS ") + << cast_type.Upper() << wxT(") "); +} + +pgsOperand pgsCast::eval(pgsVarMap &vars) const +{ + pgsOperand var = m_var->eval(vars); + MAPM num; + + switch (m_cast_type) + { + case token::PGS_INTEGER: + num = pgsMapm::pgs_str_mapm(var->number().value()); + num = pgsMapm::pgs_mapm_round(num); + return pnew pgsNumber(pgsMapm::pgs_mapm_str(num, true), pgsInt); + case token::PGS_REAL: + return pnew pgsNumber(var->number().value(), pgsReal); + case token::PGS_RECORD: + return var->record().clone(); + case token::PGS_STRING: + return var->string().clone(); + default: + return var->clone(); + } +} diff --git a/pgscript/expressions/pgsColumns.cpp b/pgscript/expressions/pgsColumns.cpp new file mode 100644 index 0000000..1226c94 --- /dev/null +++ b/pgscript/expressions/pgsColumns.cpp @@ -0,0 +1,58 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsColumns.h" + +#include "pgscript/objects/pgsNumber.h" +#include "pgscript/objects/pgsRecord.h" + +pgsColumns::pgsColumns(const wxString &name) : + pgsExpression(), m_name(name) +{ + +} + +pgsColumns::~pgsColumns() +{ + +} + +pgsExpression *pgsColumns::clone() const +{ + return pnew pgsColumns(*this); +} + +wxString pgsColumns::value() const +{ + return wxString() << wxT("COLUMNS(") << m_name << wxT(")"); +} + +pgsOperand pgsColumns::eval(pgsVarMap &vars) const +{ + if (vars.find(m_name) != vars.end()) + { + if (vars[m_name]->is_record()) + { + const pgsRecord &rec = dynamic_cast(*vars[m_name]); + return pnew pgsNumber(wxString() << rec.count_columns(), pgsInt); + } + else + { + // Not a record: 1 line and 1 column + return pnew pgsNumber(wxT("1"), pgsInt); + } + } + else + { + // Does not exist: 0 line and 0 column + return pnew pgsNumber(wxT("0"), pgsInt); + } +} diff --git a/pgscript/expressions/pgsDifferent.cpp b/pgscript/expressions/pgsDifferent.cpp new file mode 100644 index 0000000..5e44ffd --- /dev/null +++ b/pgscript/expressions/pgsDifferent.cpp @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsDifferent.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsDifferent::pgsDifferent(const pgsExpression *left, const pgsExpression *right) : + pgsOperation(left, right) +{ + +} + +pgsDifferent::~pgsDifferent() +{ + +} + +pgsExpression *pgsDifferent::clone() const +{ + return pnew pgsDifferent(*this); +} + +pgsDifferent::pgsDifferent(const pgsDifferent &that) : + pgsOperation(that) +{ + +} + +pgsDifferent &pgsDifferent::operator =(const pgsDifferent &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + return (*this); +} + +wxString pgsDifferent::value() const +{ + return wxString() << m_left->value() << wxT(" <> ") << m_right->value(); +} + +pgsOperand pgsDifferent::eval(pgsVarMap &vars) const +{ + // Evaluate operands + pgsOperand left(m_left->eval(vars)); + pgsOperand right(m_right->eval(vars)); + + // Return the result + return (*left != *right); +} diff --git a/pgscript/expressions/pgsEqual.cpp b/pgscript/expressions/pgsEqual.cpp new file mode 100644 index 0000000..d071583 --- /dev/null +++ b/pgscript/expressions/pgsEqual.cpp @@ -0,0 +1,65 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsEqual.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsEqual::pgsEqual(const pgsExpression *left, const pgsExpression *right, + bool case_sensitive) : + pgsOperation(left, right), m_case_sensitive(case_sensitive) +{ + +} + +pgsEqual::~pgsEqual() +{ + +} + +pgsExpression *pgsEqual::clone() const +{ + return pnew pgsEqual(*this); +} + +pgsEqual::pgsEqual(const pgsEqual &that) : + pgsOperation(that), m_case_sensitive(that.m_case_sensitive) +{ + +} + +pgsEqual &pgsEqual::operator =(const pgsEqual &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + const pgsEqual *p = dynamic_cast(&that); + m_case_sensitive = (p != 0) ? + p->m_case_sensitive : true; + } + return (*this); +} + +wxString pgsEqual::value() const +{ + return wxString() << m_left->value() << (m_case_sensitive ? wxT(" = ") + : wxT(" ~= ")) << m_right->value(); +} + +pgsOperand pgsEqual::eval(pgsVarMap &vars) const +{ + // Evaluate operands + pgsOperand left(m_left->eval(vars)); + pgsOperand right(m_right->eval(vars)); + + // Return the result + return (m_case_sensitive ? (*left == *right) : (*left &= *right)); +} diff --git a/pgscript/expressions/pgsExecute.cpp b/pgscript/expressions/pgsExecute.cpp new file mode 100644 index 0000000..d6ac015 --- /dev/null +++ b/pgscript/expressions/pgsExecute.cpp @@ -0,0 +1,230 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsExecute.h" + +#include +#include "db/pgConn.h" +#include "db/pgQueryThread.h" +#include "pgscript/objects/pgsNumber.h" +#include "pgscript/objects/pgsRecord.h" +#include "pgscript/objects/pgsString.h" +#include "pgscript/utilities/pgsUtilities.h" +#include "pgscript/utilities/pgsThread.h" + +pgsExecute::pgsExecute(const wxString &query, pgsOutputStream *cout, + pgsThread *app) : + pgsExpression(), m_query(query), m_cout(cout), m_app(app) +{ + +} + +pgsExecute::~pgsExecute() +{ + +} + +pgsExpression *pgsExecute::clone() const +{ + return pnew pgsExecute(*this); +} + +pgsExecute &pgsExecute::operator=(const pgsExecute &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + m_query = that.m_query; + m_app = that.m_app; + m_query = that.m_query; + } + return (*this); +} + +wxString pgsExecute::value() const +{ + return m_query; +} + +pgsOperand pgsExecute::eval(pgsVarMap &vars) const +{ + // Copy statement locally + wxString stmt(m_query); + + // Build regular expressions + wxRegEx identifier(wxT("([^\\])(@[a-zA-Z0-9_#@]+)")); + wxRegEx escaped(wxT("\\\\(@|\\\\)")); // Backslash followed by @ or backslash + wxASSERT(identifier.IsValid() && escaped.IsValid()); + + // Replace variables in statement + while (identifier.Matches(stmt)) + { + wxString var = identifier.GetMatch(stmt, 2); + wxString chr = identifier.GetMatch(stmt, 1); + if (vars.find(var) != vars.end()) + { + wxString res = vars[var]->eval(vars)->value(); + identifier.ReplaceFirst(&stmt, chr + pgsUtilities::escape_quotes(res)); + } + else + { + identifier.ReplaceFirst(&stmt, chr + wxT("\\\\") + var); + } + } + escaped.ReplaceAll(&stmt, wxT("\\1")); + + // Perform operations only if we have a valid connection + if (m_app != 0 && m_app->connection() != 0 && !m_app->TestDestroy()) + { + pgQueryThread thread(m_app->connection(), stmt); + + if (thread.Create() == wxTHREAD_NO_ERROR) + { + if (thread.Run() == wxTHREAD_NO_ERROR) + { + while (true) + { + if (m_app->TestDestroy()) // wxThread::TestDestroy() + { + thread.Delete(); + break; + } + else if (thread.IsRunning()) + { + m_app->Yield(); + m_app->Sleep(20); + } + else + { + thread.Wait(); + break; + } + } + + if (thread.ReturnCode() != PGRES_COMMAND_OK + && thread.ReturnCode() != PGRES_TUPLES_OK) + { + if (m_cout != 0) + { + m_app->LockOutput(); + + (*m_cout) << PGSOUTWARNING; + wxString message(stmt + wxT("\n") + thread + .GetMessagesAndClear().Strip(wxString::both)); + wxRegEx multilf(wxT("(\n)+")); + multilf.ReplaceAll(&message, wxT("\n")); + message.Replace(wxT("\n"), wxT("\n") + + generate_spaces(PGSOUTWARNING.Length())); + (*m_cout) << message << wxT("\n"); + + m_app->UnlockOutput(); + } + } + else if (!m_app->TestDestroy()) + { + if (m_cout != 0) + { + m_app->LockOutput(); + + (*m_cout) << PGSOUTQUERY; + wxString message(thread.GetMessagesAndClear() + .Strip(wxString::both)); + if (!message.IsEmpty()) + message = stmt + wxT("\n") + message; + else + message = stmt; + wxRegEx multilf(wxT("(\n)+")); + multilf.ReplaceAll(&message, wxT("\n")); + message.Replace(wxT("\n"), wxT("\n") + + generate_spaces(PGSOUTQUERY.Length())); + (*m_cout) << message << wxT("\n"); + + m_app->UnlockOutput(); + } + + pgsRecord *rec = 0; + + if (thread.DataValid()) + { + pgSet *set = thread.DataSet(); + set->MoveFirst(); + rec = pnew pgsRecord(set->NumCols()); + wxArrayLong columns_int; // List of columns that contain integers + wxArrayLong columns_real; // List of columns that contain reals + for (long i = 0; i < set->NumCols(); i++) + { + rec->set_column_name(i, set->ColName(i)); + wxString col_type = set->ColType(i); + if (!col_type.CmpNoCase(wxT("bigint")) + || !col_type.CmpNoCase(wxT("smallint")) + || !col_type.CmpNoCase(wxT("integer"))) + { + columns_int.Add(i); + } + else if (!col_type.CmpNoCase(wxT("real")) + || !col_type.CmpNoCase(wxT("double precision")) + || !col_type.CmpNoCase(wxT("money")) + || !col_type.CmpNoCase(wxT("numeric"))) + { + columns_real.Add(i); + } + } + size_t line = 0; + while (!set->Eof()) + { + for (long i = 0; i < set->NumCols(); i++) + { + wxString value = set->GetVal(i); + + if (columns_int.Index(i) != wxNOT_FOUND + && pgsNumber::num_type(value) == pgsNumber::pgsTInt) + { + rec->insert(line, i, pnew pgsNumber(value, pgsInt)); + } + else if (columns_real.Index(i) != wxNOT_FOUND + && pgsNumber::num_type(value) == pgsNumber::pgsTReal) + { + rec->insert(line, i, pnew pgsNumber(value, pgsReal)); + } + else + { + rec->insert(line, i, pnew pgsString(value)); + } + } + set->MoveNext(); + ++line; + } + } + else + { + rec = pnew pgsRecord(1); + rec->insert(0, 0, pnew pgsNumber(wxT("1"))); + } + + return rec; + } + } + else + { + wxLogError(wxT("PGSCRIPT: Cannot run query thread for the query:\n%s"), + m_query.c_str()); + } + } + else + { + wxLogError(wxT("PGSCRIPT: Cannot create query thread for the query:\n%s"), + m_query.c_str()); + } + } + + // This must return a record whatever happens + return pnew pgsRecord(1); +} diff --git a/pgscript/expressions/pgsExpression.cpp b/pgscript/expressions/pgsExpression.cpp new file mode 100644 index 0000000..876cdba --- /dev/null +++ b/pgscript/expressions/pgsExpression.cpp @@ -0,0 +1,23 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsExpression.h" +#include "pgscript/objects/pgsVariable.h" + +pgsExpression::pgsExpression() +{ + +} + +pgsExpression::~pgsExpression() +{ + +} diff --git a/pgscript/expressions/pgsGenDate.cpp b/pgscript/expressions/pgsGenDate.cpp new file mode 100644 index 0000000..a393639 --- /dev/null +++ b/pgscript/expressions/pgsGenDate.cpp @@ -0,0 +1,123 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsGenDate.h" + +#include "pgscript/exceptions/pgsParameterException.h" +#include "pgscript/generators/pgsDateGen.h" +#include "pgscript/objects/pgsGenerator.h" + +pgsGenDate::pgsGenDate(const pgsExpression *min, const pgsExpression *max, + const pgsExpression *sequence, const pgsExpression *seed) : + pgsExpression(), m_min(min), m_max(max), m_sequence(sequence), m_seed(seed) +{ + +} + +pgsGenDate::~pgsGenDate() +{ + pdelete(m_min); + pdelete(m_max); + pdelete(m_sequence); + pdelete(m_seed); +} + +pgsExpression *pgsGenDate::clone() const +{ + return pnew pgsGenDate(*this); +} + +pgsGenDate::pgsGenDate(const pgsGenDate &that) : + pgsExpression(that) +{ + m_min = that.m_min->clone(); + m_max = that.m_max->clone(); + m_sequence = that.m_sequence->clone(); + m_seed = that.m_seed->clone(); +} + +pgsGenDate &pgsGenDate::operator =(const pgsGenDate &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + pdelete(m_min); + pdelete(m_max); + pdelete(m_sequence); + pdelete(m_seed); + m_min = that.m_min->clone(); + m_max = that.m_max->clone(); + m_sequence = that.m_sequence->clone(); + m_seed = that.m_seed->clone(); + } + return (*this); +} + +wxString pgsGenDate::value() const +{ + return wxString() << wxT("date[ min = ") << m_min->value() << wxT(" max = ") + << m_max->value() << wxT(" sequence = ") << m_sequence->value() + << wxT(" seed = ") << m_seed->value() << wxT(" ]"); +} + +pgsOperand pgsGenDate::eval(pgsVarMap &vars) const +{ + // Evaluate parameters + pgsOperand min(m_min->eval(vars)); + pgsOperand max(m_max->eval(vars)); + pgsOperand sequence(m_sequence->eval(vars)); + pgsOperand seed(m_seed->eval(vars)); + + // Check parameters and create the generator + if (min->is_string() && max->is_string() && sequence->is_integer() + && seed->is_integer()) + { + wxDateTime aux_min, aux_max; + if (aux_min.ParseDate(min->value()) != 0 && aux_max.ParseDate(max->value()) != 0 + && aux_min.IsValid() && aux_max.IsValid()) + { + long aux_sequence, aux_seed; + sequence->value().ToLong(&aux_sequence); + seed->value().ToLong(&aux_seed); + return pnew pgsGenerator(pgsVariable::pgsTString, + pnew pgsDateGen(aux_min, aux_max, aux_sequence != 0, aux_seed)); + } + else + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmin and/or max dates are not valid")); + } + } + else + { + // Deal with errors + if (!min->is_string()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmin should be a string")); + } + else if (!max->is_string()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmax should be a string")); + } + else if (!sequence->is_integer()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nsequence should be an integer")); + } + else + { + throw pgsParameterException(wxString() << value() + << wxT(":\nseed should be an integer")); + } + } +} diff --git a/pgscript/expressions/pgsGenDateTime.cpp b/pgscript/expressions/pgsGenDateTime.cpp new file mode 100644 index 0000000..cb77897 --- /dev/null +++ b/pgscript/expressions/pgsGenDateTime.cpp @@ -0,0 +1,123 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsGenDateTime.h" + +#include "pgscript/exceptions/pgsParameterException.h" +#include "pgscript/generators/pgsDateTimeGen.h" +#include "pgscript/objects/pgsGenerator.h" + +pgsGenDateTime::pgsGenDateTime(const pgsExpression *min, const pgsExpression *max, + const pgsExpression *sequence, const pgsExpression *seed) : + pgsExpression(), m_min(min), m_max(max), m_sequence(sequence), m_seed(seed) +{ + +} + +pgsGenDateTime::~pgsGenDateTime() +{ + pdelete(m_min); + pdelete(m_max); + pdelete(m_sequence); + pdelete(m_seed); +} + +pgsExpression *pgsGenDateTime::clone() const +{ + return pnew pgsGenDateTime(*this); +} + +pgsGenDateTime::pgsGenDateTime(const pgsGenDateTime &that) : + pgsExpression(that) +{ + m_min = that.m_min->clone(); + m_max = that.m_max->clone(); + m_sequence = that.m_sequence->clone(); + m_seed = that.m_seed->clone(); +} + +pgsGenDateTime &pgsGenDateTime::operator =(const pgsGenDateTime &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + pdelete(m_min); + pdelete(m_max); + pdelete(m_sequence); + pdelete(m_seed); + m_min = that.m_min->clone(); + m_max = that.m_max->clone(); + m_sequence = that.m_sequence->clone(); + m_seed = that.m_seed->clone(); + } + return (*this); +} + +wxString pgsGenDateTime::value() const +{ + return wxString() << wxT("date_time[ min = ") << m_min->value() << wxT(" max = ") + << m_max->value() << wxT(" sequence = ") << m_sequence->value() + << wxT(" seed = ") << m_seed->value() << wxT(" ]"); +} + +pgsOperand pgsGenDateTime::eval(pgsVarMap &vars) const +{ + // Evaluate parameters + pgsOperand min(m_min->eval(vars)); + pgsOperand max(m_max->eval(vars)); + pgsOperand sequence(m_sequence->eval(vars)); + pgsOperand seed(m_seed->eval(vars)); + + // Check parameters and create the generator + if (min->is_string() && max->is_string() && sequence->is_integer() + && seed->is_integer()) + { + wxDateTime aux_min, aux_max; + if (aux_min.ParseDateTime(min->value()) != 0 && aux_max.ParseDateTime(max->value()) != 0 + && aux_min.IsValid() && aux_max.IsValid()) + { + long aux_sequence, aux_seed; + sequence->value().ToLong(&aux_sequence); + seed->value().ToLong(&aux_seed); + return pnew pgsGenerator(pgsVariable::pgsTString, + pnew pgsDateTimeGen(aux_min, aux_max, aux_sequence != 0, aux_seed)); + } + else + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmin and/or max datetimes are not valid")); + } + } + else + { + // Deal with errors + if (!min->is_string()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmin should be a string")); + } + else if (!max->is_string()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmax should be a string")); + } + else if (!sequence->is_integer()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nsequence should be an integer")); + } + else + { + throw pgsParameterException(wxString() << value() + << wxT(":\nseed should be an integer")); + } + } +} diff --git a/pgscript/expressions/pgsGenDictionary.cpp b/pgscript/expressions/pgsGenDictionary.cpp new file mode 100644 index 0000000..4847fea --- /dev/null +++ b/pgscript/expressions/pgsGenDictionary.cpp @@ -0,0 +1,126 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsGenDictionary.h" + +#include +#include "pgscript/exceptions/pgsParameterException.h" +#include "pgscript/generators/pgsDictionaryGen.h" +#include "pgscript/objects/pgsGenerator.h" + +pgsGenDictionary::pgsGenDictionary(const pgsExpression *file_path, const pgsExpression *sequence, + const pgsExpression *seed, const pgsExpression *wx_conv) : + pgsExpression(), m_file_path(file_path), m_sequence(sequence), m_seed(seed), + m_wx_conv(wx_conv) +{ + +} + +pgsGenDictionary::~pgsGenDictionary() +{ + pdelete(m_file_path); + pdelete(m_sequence); + pdelete(m_seed); + pdelete(m_wx_conv); +} + +pgsExpression *pgsGenDictionary::clone() const +{ + return pnew pgsGenDictionary(*this); +} + +pgsGenDictionary::pgsGenDictionary(const pgsGenDictionary &that) : + pgsExpression(that) +{ + m_file_path = that.m_file_path->clone(); + m_sequence = that.m_sequence->clone(); + m_seed = that.m_seed->clone(); + m_wx_conv = that.m_wx_conv->clone(); +} + +pgsGenDictionary &pgsGenDictionary::operator =(const pgsGenDictionary &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + pdelete(m_file_path); + pdelete(m_sequence); + pdelete(m_seed); + pdelete(m_wx_conv); + m_file_path = that.m_file_path->clone(); + m_sequence = that.m_sequence->clone(); + m_seed = that.m_seed->clone(); + m_wx_conv = that.m_wx_conv->clone(); + } + return (*this); +} + +wxString pgsGenDictionary::value() const +{ + return wxString() << wxT("file[ file = ") << m_file_path->value() << wxT(" sequence = ") + << m_sequence->value() << wxT(" seed = ") << m_seed->value() + << wxT(" encoding = ") << m_wx_conv->value() << wxT(" ]"); +} + +pgsOperand pgsGenDictionary::eval(pgsVarMap &vars) const +{ + // Evaluate parameters + pgsOperand file_path(m_file_path->eval(vars)); + pgsOperand sequence(m_sequence->eval(vars)); + pgsOperand seed(m_seed->eval(vars)); + pgsOperand wx_conv(m_wx_conv->eval(vars)); + + // Check parameters and create the generator + if (file_path->is_string() && sequence->is_integer() && seed->is_integer() + && wx_conv->is_string()) + { + wxFileName file(file_path->value()); + if (file.FileExists() && file.IsFileReadable()) + { + long aux_sequence, aux_seed; + sequence->value().ToLong(&aux_sequence); + seed->value().ToLong(&aux_seed); + return pnew pgsGenerator(pgsVariable::pgsTString, + pnew pgsDictionaryGen(file_path->value(), aux_sequence != 0, + aux_seed, wxCSConv(wx_conv->value()))); + } + else + { + throw pgsParameterException(wxString() << value() + << wxT(":\nFile <") << file_path->value() + << wxT("> does not exist")); + } + } + else + { + // Deal with errors + if (!file_path->is_string()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nfile should be a string")); + } + else if (!sequence->is_integer()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nsequence should be an integer")); + } + else if (!seed->is_integer()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nseed should be an integer")); + } + else + { + throw pgsParameterException(wxString() << value() + << wxT(":\nencoding should be a string")); + } + } +} diff --git a/pgscript/expressions/pgsGenInt.cpp b/pgscript/expressions/pgsGenInt.cpp new file mode 100644 index 0000000..ddefb11 --- /dev/null +++ b/pgscript/expressions/pgsGenInt.cpp @@ -0,0 +1,114 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsGenInt.h" + +#include "pgscript/exceptions/pgsParameterException.h" +#include "pgscript/generators/pgsDictionaryGen.h" +#include "pgscript/objects/pgsGenerator.h" + +pgsGenInt::pgsGenInt(const pgsExpression *min, const pgsExpression *max, + const pgsExpression *sequence, const pgsExpression *seed) : + pgsExpression(), m_min(min), m_max(max), m_sequence(sequence), m_seed(seed) +{ + +} + +pgsGenInt::~pgsGenInt() +{ + pdelete(m_min); + pdelete(m_max); + pdelete(m_sequence); + pdelete(m_seed); +} + +pgsExpression *pgsGenInt::clone() const +{ + return pnew pgsGenInt(*this); +} + +pgsGenInt::pgsGenInt(const pgsGenInt &that) : + pgsExpression(that) +{ + m_min = that.m_min->clone(); + m_max = that.m_max->clone(); + m_sequence = that.m_sequence->clone(); + m_seed = that.m_seed->clone(); +} + +pgsGenInt &pgsGenInt::operator =(const pgsGenInt &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + pdelete(m_min); + pdelete(m_max); + pdelete(m_sequence); + pdelete(m_seed); + m_min = that.m_min->clone(); + m_max = that.m_max->clone(); + m_sequence = that.m_sequence->clone(); + m_seed = that.m_seed->clone(); + } + return (*this); +} + +wxString pgsGenInt::value() const +{ + return wxString() << wxT("integer[ min = ") << m_min->value() << wxT(" max = ") + << m_max->value() << wxT(" sequence = ") << m_sequence->value() + << wxT(" seed = ") << m_seed->value() << wxT(" ]"); +} + +pgsOperand pgsGenInt::eval(pgsVarMap &vars) const +{ + // Evaluate parameters + pgsOperand min(m_min->eval(vars)); + pgsOperand max(m_max->eval(vars)); + pgsOperand sequence(m_sequence->eval(vars)); + pgsOperand seed(m_seed->eval(vars)); + + // Check parameters and create the generator + if (min->is_integer() && max->is_integer() && sequence->is_integer() + && seed->is_integer()) + { + long aux_sequence, aux_seed; + sequence->value().ToLong(&aux_sequence); + seed->value().ToLong(&aux_seed); + return pnew pgsGenerator(pgsVariable::pgsTInt, + pnew pgsIntegerGen(pgsVariable::num(min), pgsVariable::num(max), + aux_sequence != 0, aux_seed)); + } + else + { + // Deal with errors + if (!min->is_integer()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmin should be an integer")); + } + else if (!max->is_integer()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmax should be an integer")); + } + else if (!sequence->is_integer()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nsequence should be an integer")); + } + else + { + throw pgsParameterException(wxString() << value() + << wxT(":\nseed should be an integer")); + } + } +} diff --git a/pgscript/expressions/pgsGenReal.cpp b/pgscript/expressions/pgsGenReal.cpp new file mode 100644 index 0000000..22a5153 --- /dev/null +++ b/pgscript/expressions/pgsGenReal.cpp @@ -0,0 +1,128 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsGenReal.h" + +#include "pgscript/exceptions/pgsParameterException.h" +#include "pgscript/generators/pgsRealGen.h" +#include "pgscript/objects/pgsGenerator.h" + +pgsGenReal::pgsGenReal(const pgsExpression *min, const pgsExpression *max, + const pgsExpression *precision, const pgsExpression *sequence, + const pgsExpression *seed) : + pgsExpression(), m_min(min), m_max(max), m_precision(precision), + m_sequence(sequence), m_seed(seed) +{ + +} + +pgsGenReal::~pgsGenReal() +{ + pdelete(m_min); + pdelete(m_max); + pdelete(m_precision); + pdelete(m_sequence); + pdelete(m_seed); +} + +pgsExpression *pgsGenReal::clone() const +{ + return pnew pgsGenReal(*this); +} + +pgsGenReal::pgsGenReal(const pgsGenReal &that) : + pgsExpression(that) +{ + m_min = that.m_min->clone(); + m_max = that.m_max->clone(); + m_precision = that.m_precision->clone(); + m_sequence = that.m_sequence->clone(); + m_seed = that.m_seed->clone(); +} + +pgsGenReal &pgsGenReal::operator =(const pgsGenReal &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + pdelete(m_min); + pdelete(m_max); + pdelete(m_precision); + pdelete(m_sequence); + pdelete(m_seed); + m_min = that.m_min->clone(); + m_max = that.m_max->clone(); + m_precision = that.m_precision->clone(); + m_sequence = that.m_sequence->clone(); + m_seed = that.m_seed->clone(); + } + return (*this); +} + +wxString pgsGenReal::value() const +{ + return wxString() << wxT("real[ min = ") << m_min->value() << wxT(" max = ") + << m_max->value() << wxT(" precision = ") << m_precision->value() + << wxT(" sequence = ") << m_sequence->value() << wxT(" seed = ") + << m_seed->value() << wxT(" ]"); +} + +pgsOperand pgsGenReal::eval(pgsVarMap &vars) const +{ + // Evaluate parameters + pgsOperand min(m_min->eval(vars)); + pgsOperand max(m_max->eval(vars)); + pgsOperand precision(m_precision->eval(vars)); + pgsOperand sequence(m_sequence->eval(vars)); + pgsOperand seed(m_seed->eval(vars)); + + // Check parameters and create the generator + if (min->is_number() && max->is_number() && sequence->is_integer() + && seed->is_integer() && precision->is_integer()) + { + long aux_sequence, aux_seed, aux_precision; + sequence->value().ToLong(&aux_sequence); + seed->value().ToLong(&aux_seed); + precision->value().ToLong(&aux_precision); + return pnew pgsGenerator(pgsVariable::pgsTReal, + pnew pgsRealGen(pgsVariable::num(min), pgsVariable::num(max), aux_precision, + aux_sequence != 0, aux_seed)); + } + else + { + // Deal with errors + if (!min->is_number()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmin should be a number")); + } + else if (!max->is_number()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmax should be a number")); + } + else if (!precision->is_integer()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nprecision should be an integer")); + } + else if (!sequence->is_integer()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nsequence should be an integer")); + } + else + { + throw pgsParameterException(wxString() << value() + << wxT(":\nseed should be an integer")); + } + } +} diff --git a/pgscript/expressions/pgsGenReference.cpp b/pgscript/expressions/pgsGenReference.cpp new file mode 100644 index 0000000..73a170c --- /dev/null +++ b/pgscript/expressions/pgsGenReference.cpp @@ -0,0 +1,131 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsGenReference.h" + +#include "pgscript/exceptions/pgsParameterException.h" +#include "pgscript/generators/pgsReferenceGen.h" +#include "pgscript/expressions/pgsExecute.h" +#include "pgscript/objects/pgsGenerator.h" + +pgsGenReference::pgsGenReference(const pgsExpression *table, const pgsExpression *column, + const pgsExpression *sequence, const pgsExpression *seed, pgsThread *app) : + pgsExpression(), m_table(table), m_column(column), m_sequence(sequence), + m_seed(seed), m_app(app) +{ + +} + +pgsGenReference::~pgsGenReference() +{ + pdelete(m_table); + pdelete(m_column); + pdelete(m_sequence); + pdelete(m_seed); +} + +pgsExpression *pgsGenReference::clone() const +{ + return pnew pgsGenReference(*this); +} + +pgsGenReference::pgsGenReference(const pgsGenReference &that) : + pgsExpression(that) +{ + m_table = that.m_table->clone(); + m_column = that.m_column->clone(); + m_sequence = that.m_sequence->clone(); + m_seed = that.m_seed->clone(); + m_app = that.m_app; +} + +pgsGenReference &pgsGenReference::operator =(const pgsGenReference &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + pdelete(m_table); + pdelete(m_column); + pdelete(m_sequence); + pdelete(m_seed); + m_table = that.m_table->clone(); + m_column = that.m_column->clone(); + m_sequence = that.m_sequence->clone(); + m_seed = that.m_seed->clone(); + m_app = that.m_app; + } + return (*this); +} + +wxString pgsGenReference::value() const +{ + return wxString() << wxT("reference[ table = ") << m_table->value() + << wxT(" column = ") << m_column->value() << wxT(" sequence = ") + << m_sequence->value() << wxT(" seed = ") << m_seed->value() << wxT(" ]"); +} + +pgsOperand pgsGenReference::eval(pgsVarMap &vars) const +{ + // Evaluate parameters + pgsOperand table(m_table->eval(vars)); + pgsOperand column(m_column->eval(vars)); + pgsOperand sequence(m_sequence->eval(vars)); + pgsOperand seed(m_seed->eval(vars)); + + // Check parameters and create the generator + if (table->is_string() && !table->value().IsEmpty() && column->is_string() + && !column->value().IsEmpty() && sequence->is_integer() + && seed->is_integer()) + { + // Check wheter the table and the column do exist + pgsOperand result = pgsExecute(wxString() << wxT("SELECT 1 FROM ") + << table->value() << wxT(" WHERE ") << column->value() + << wxT(" = ") << column->value(), 0, m_app).eval(vars); + if (result->pgs_is_true()) + { + long aux_sequence, aux_seed; + sequence->value().ToLong(&aux_sequence); + seed->value().ToLong(&aux_seed); + return pnew pgsGenerator(pgsVariable::pgsTString, + pnew pgsReferenceGen(m_app, table->value(), + column->value(), aux_sequence != 0, aux_seed)); + } + else + { + throw pgsParameterException(wxString() << value() + << wxT(":\ntable/column does not exist")); + } + } + else + { + // Deal with errors + if (!table->is_string() || table->value().IsEmpty()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\ntable should be a non-empty string")); + } + else if (!column->is_string() || column->value().IsEmpty()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\ncolumn should be a non-empty string")); + } + else if (!sequence->is_integer()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nsequence should be an integer")); + } + else + { + throw pgsParameterException(wxString() << value() + << wxT(":\nseed should be an integer")); + } + } +} diff --git a/pgscript/expressions/pgsGenRegex.cpp b/pgscript/expressions/pgsGenRegex.cpp new file mode 100644 index 0000000..1d4a9dd --- /dev/null +++ b/pgscript/expressions/pgsGenRegex.cpp @@ -0,0 +1,98 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsGenRegex.h" + +#include "pgscript/exceptions/pgsParameterException.h" +#include "pgscript/generators/pgsRegexGen.h" +#include "pgscript/objects/pgsGenerator.h" + +pgsGenRegex::pgsGenRegex(const pgsExpression *regex, const pgsExpression *seed) : + pgsExpression(), m_regex(regex), m_seed(seed) +{ + +} + +pgsGenRegex::~pgsGenRegex() +{ + pdelete(m_regex); + pdelete(m_seed); +} + +pgsExpression *pgsGenRegex::clone() const +{ + return pnew pgsGenRegex(*this); +} + +pgsGenRegex::pgsGenRegex(const pgsGenRegex &that) : + pgsExpression(that) +{ + m_regex = that.m_regex->clone(); + m_seed = that.m_seed->clone(); +} + +pgsGenRegex &pgsGenRegex::operator =(const pgsGenRegex &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + pdelete(m_regex); + pdelete(m_seed); + m_regex = that.m_regex->clone(); + m_seed = that.m_seed->clone(); + } + return (*this); +} + +wxString pgsGenRegex::value() const +{ + return wxString() << wxT("string[ regex = ") << m_regex->value() + << wxT(" seed = ") << m_seed->value() << wxT(" ]"); +} + +pgsOperand pgsGenRegex::eval(pgsVarMap &vars) const +{ + // Evaluate parameters + pgsOperand regex(m_regex->eval(vars)); + pgsOperand seed(m_seed->eval(vars)); + + // Check parameters and create the generator + if (regex->is_string() && seed->is_integer()) + { + long aux_seed; + seed->value().ToLong(&aux_seed); + pgsRegexGen *gen = pnew pgsRegexGen(regex->value(), aux_seed); + if (!gen->is_valid()) + { + pdelete(gen); + throw pgsParameterException(wxString() << value() + << wxT(":\nregex is not a valid regular expression")); + } + else + { + return pnew pgsGenerator(pgsVariable::pgsTString, gen); + } + } + else + { + // Deal with errors + if (!regex->is_string()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nregex should be a string")); + } + else + { + throw pgsParameterException(wxString() << value() + << wxT(":\nseed should be an integer")); + } + } +} diff --git a/pgscript/expressions/pgsGenString.cpp b/pgscript/expressions/pgsGenString.cpp new file mode 100644 index 0000000..b8ffb9a --- /dev/null +++ b/pgscript/expressions/pgsGenString.cpp @@ -0,0 +1,115 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsGenString.h" + +#include "pgscript/exceptions/pgsParameterException.h" +#include "pgscript/generators/pgsStringGen.h" +#include "pgscript/objects/pgsGenerator.h" + +pgsGenString::pgsGenString(const pgsExpression *min, const pgsExpression *max, + const pgsExpression *nb_words, const pgsExpression *seed) : + pgsExpression(), m_min(min), m_max(max), m_nb_words(nb_words), m_seed(seed) +{ + +} + +pgsGenString::~pgsGenString() +{ + pdelete(m_min); + pdelete(m_max); + pdelete(m_nb_words); + pdelete(m_seed); +} + +pgsExpression *pgsGenString::clone() const +{ + return pnew pgsGenString(*this); +} + +pgsGenString::pgsGenString(const pgsGenString &that) : + pgsExpression(that) +{ + m_min = that.m_min->clone(); + m_max = that.m_max->clone(); + m_nb_words = that.m_nb_words->clone(); + m_seed = that.m_seed->clone(); +} + +pgsGenString &pgsGenString::operator =(const pgsGenString &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + pdelete(m_min); + pdelete(m_max); + pdelete(m_nb_words); + pdelete(m_seed); + m_min = that.m_min->clone(); + m_max = that.m_max->clone(); + m_nb_words = that.m_nb_words->clone(); + m_seed = that.m_seed->clone(); + } + return (*this); +} + +wxString pgsGenString::value() const +{ + return wxString() << wxT("string[ min = ") << m_min->value() << wxT(" max = ") + << m_max->value() << wxT(" nb_words = ") << m_nb_words->value() + << wxT(" seed = ") << m_seed->value() << wxT(" ]"); +} + +pgsOperand pgsGenString::eval(pgsVarMap &vars) const +{ + // Evaluate parameters + pgsOperand min(m_min->eval(vars)); + pgsOperand max(m_max->eval(vars)); + pgsOperand nb_words(m_nb_words->eval(vars)); + pgsOperand seed(m_seed->eval(vars)); + + // Check parameters and create the generator + if (min->is_integer() && max->is_integer() && nb_words->is_integer() + && seed->is_integer()) + { + long aux_min, aux_max, aux_nb_words, aux_seed; + min->value().ToLong(&aux_min); + max->value().ToLong(&aux_max); + nb_words->value().ToLong(&aux_nb_words); + seed->value().ToLong(&aux_seed); + return pnew pgsGenerator(pgsVariable::pgsTString, + pnew pgsStringGen(aux_min, aux_max, aux_nb_words, aux_seed)); + } + else + { + // Deal with errors + if (!min->is_integer()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmin should be an integer")); + } + else if (!max->is_integer()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmax should be an integer")); + } + else if (!nb_words->is_integer()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nnb_words should be an integer")); + } + else + { + throw pgsParameterException(wxString() << value() + << wxT(":\nseed should be an integer")); + } + } +} diff --git a/pgscript/expressions/pgsGenTime.cpp b/pgscript/expressions/pgsGenTime.cpp new file mode 100644 index 0000000..3a6aaa5 --- /dev/null +++ b/pgscript/expressions/pgsGenTime.cpp @@ -0,0 +1,123 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsGenTime.h" + +#include "pgscript/exceptions/pgsParameterException.h" +#include "pgscript/generators/pgsTimeGen.h" +#include "pgscript/objects/pgsGenerator.h" + +pgsGenTime::pgsGenTime(const pgsExpression *min, const pgsExpression *max, + const pgsExpression *sequence, const pgsExpression *seed) : + pgsExpression(), m_min(min), m_max(max), m_sequence(sequence), m_seed(seed) +{ + +} + +pgsGenTime::~pgsGenTime() +{ + pdelete(m_min); + pdelete(m_max); + pdelete(m_sequence); + pdelete(m_seed); +} + +pgsExpression *pgsGenTime::clone() const +{ + return pnew pgsGenTime(*this); +} + +pgsGenTime::pgsGenTime(const pgsGenTime &that) : + pgsExpression(that) +{ + m_min = that.m_min->clone(); + m_max = that.m_max->clone(); + m_sequence = that.m_sequence->clone(); + m_seed = that.m_seed->clone(); +} + +pgsGenTime &pgsGenTime::operator =(const pgsGenTime &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + pdelete(m_min); + pdelete(m_max); + pdelete(m_sequence); + pdelete(m_seed); + m_min = that.m_min->clone(); + m_max = that.m_max->clone(); + m_sequence = that.m_sequence->clone(); + m_seed = that.m_seed->clone(); + } + return (*this); +} + +wxString pgsGenTime::value() const +{ + return wxString() << wxT("time[ min = ") << m_min->value() << wxT(" max = ") + << m_max->value() << wxT(" sequence = ") << m_sequence->value() + << wxT(" seed = ") << m_seed->value() << wxT(" ]"); +} + +pgsOperand pgsGenTime::eval(pgsVarMap &vars) const +{ + // Evaluate parameters + pgsOperand min(m_min->eval(vars)); + pgsOperand max(m_max->eval(vars)); + pgsOperand sequence(m_sequence->eval(vars)); + pgsOperand seed(m_seed->eval(vars)); + + // Check parameters and create the generator + if (min->is_string() && max->is_string() && sequence->is_integer() + && seed->is_integer()) + { + wxDateTime aux_min, aux_max; + if (aux_min.ParseTime(min->value()) != 0 && aux_max.ParseTime(max->value()) != 0 + && aux_min.IsValid() && aux_max.IsValid()) + { + long aux_sequence, aux_seed; + sequence->value().ToLong(&aux_sequence); + seed->value().ToLong(&aux_seed); + return pnew pgsGenerator(pgsVariable::pgsTString, + pnew pgsTimeGen(aux_min, aux_max, aux_sequence != 0, aux_seed)); + } + else + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmin and/or max times are not valid")); + } + } + else + { + // Deal with errors + if (!min->is_string()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmin should be a string")); + } + else if (!max->is_string()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmax should be a string")); + } + else if (!sequence->is_integer()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nsequence should be an integer")); + } + else + { + throw pgsParameterException(wxString() << value() + << wxT(":\nseed should be an integer")); + } + } +} diff --git a/pgscript/expressions/pgsGreater.cpp b/pgscript/expressions/pgsGreater.cpp new file mode 100644 index 0000000..fcfc942 --- /dev/null +++ b/pgscript/expressions/pgsGreater.cpp @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsGreater.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsGreater::pgsGreater(const pgsExpression *left, const pgsExpression *right) : + pgsOperation(left, right) +{ + +} + +pgsGreater::~pgsGreater() +{ + +} + +pgsExpression *pgsGreater::clone() const +{ + return pnew pgsGreater(*this); +} + +pgsGreater::pgsGreater(const pgsGreater &that) : + pgsOperation(that) +{ + +} + +pgsGreater &pgsGreater::operator =(const pgsGreater &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + return (*this); +} + +wxString pgsGreater::value() const +{ + return wxString() << m_left->value() << wxT(" > ") << m_right->value(); +} + +pgsOperand pgsGreater::eval(pgsVarMap &vars) const +{ + // Evaluate operands + pgsOperand left(m_left->eval(vars)); + pgsOperand right(m_right->eval(vars)); + + // Return the result + return (*left > *right); +} diff --git a/pgscript/expressions/pgsGreaterEqual.cpp b/pgscript/expressions/pgsGreaterEqual.cpp new file mode 100644 index 0000000..ba07f58 --- /dev/null +++ b/pgscript/expressions/pgsGreaterEqual.cpp @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsGreaterEqual.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsGreaterEqual::pgsGreaterEqual(const pgsExpression *left, const pgsExpression *right) : + pgsOperation(left, right) +{ + +} + +pgsGreaterEqual::~pgsGreaterEqual() +{ + +} + +pgsExpression *pgsGreaterEqual::clone() const +{ + return pnew pgsGreaterEqual(*this); +} + +pgsGreaterEqual::pgsGreaterEqual(const pgsGreaterEqual &that) : + pgsOperation(that) +{ + +} + +pgsGreaterEqual &pgsGreaterEqual::operator =(const pgsGreaterEqual &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + return (*this); +} + +wxString pgsGreaterEqual::value() const +{ + return wxString() << m_left->value() << wxT(" >= ") << m_right->value(); +} + +pgsOperand pgsGreaterEqual::eval(pgsVarMap &vars) const +{ + // Evaluate operands + pgsOperand left(m_left->eval(vars)); + pgsOperand right(m_right->eval(vars)); + + // Return the result + return (*left >= *right); +} diff --git a/pgscript/expressions/pgsIdent.cpp b/pgscript/expressions/pgsIdent.cpp new file mode 100644 index 0000000..19d9f60 --- /dev/null +++ b/pgscript/expressions/pgsIdent.cpp @@ -0,0 +1,56 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsIdent.h" + +#include +#include "pgscript/objects/pgsNumber.h" +#include "pgscript/objects/pgsString.h" + +const wxString pgsIdent::m_now = wxT("@NOW"); + +pgsIdent::pgsIdent(const wxString &name) : + pgsExpression(), m_name(name) +{ + +} + +pgsIdent::~pgsIdent() +{ + +} + +pgsExpression *pgsIdent::clone() const +{ + return pnew pgsIdent(*this); +} + +wxString pgsIdent::value() const +{ + return m_name; +} + +pgsOperand pgsIdent::eval(pgsVarMap &vars) const +{ + if (vars.find(m_name) != vars.end()) + { + return vars[m_name]; + } + else if (m_name == m_now) + { + time_t now = wxDateTime::GetTimeNow(); + return pnew pgsNumber(wxString() << now); + } + else + { + return pnew pgsString(wxT("")); + } +} diff --git a/pgscript/expressions/pgsIdentRecord.cpp b/pgscript/expressions/pgsIdentRecord.cpp new file mode 100644 index 0000000..5571d70 --- /dev/null +++ b/pgscript/expressions/pgsIdentRecord.cpp @@ -0,0 +1,103 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsIdentRecord.h" + +#include "pgscript/objects/pgsRecord.h" +#include "pgscript/objects/pgsString.h" + +pgsIdentRecord::pgsIdentRecord(const wxString &name, const pgsExpression *line, + const pgsExpression *column) : + pgsIdent(name), m_line(line), m_column(column) +{ + +} + +pgsIdentRecord::~pgsIdentRecord() +{ + pdelete(m_line); + pdelete(m_column); +} + +pgsExpression *pgsIdentRecord::clone() const +{ + return pnew pgsIdentRecord(*this); +} + +pgsIdentRecord::pgsIdentRecord(const pgsIdentRecord &that) : + pgsIdent(that) +{ + m_line = that.m_line->clone(); + m_column = that.m_column != 0 ? that.m_column->clone() : 0; +} + +pgsIdentRecord &pgsIdentRecord::operator=(const pgsIdentRecord &that) +{ + if (this != &that) + { + pgsIdent::operator=(that); + pdelete(m_line); + pdelete(m_column); + m_line = that.m_line->clone(); + m_column = that.m_column != 0 ? that.m_column->clone() : 0; + } + return (*this); +} + +wxString pgsIdentRecord::value() const +{ + wxString result; + result << m_name << wxT("[") << m_line->value() << wxT("]"); + if (m_column != 0) + { + result << wxT("[") << m_column->value() << wxT("]"); + } + return result; +} + +pgsOperand pgsIdentRecord::eval(pgsVarMap &vars) const +{ + // Check whether the variable is a record + if (vars.find(m_name) != vars.end() && vars[m_name]->is_record()) + { + // Get the operand as a record + const pgsRecord &rec = dynamic_cast(*vars[m_name]); + + // Evaluate parameters + pgsOperand line(m_line->eval(vars)); + if (line->is_integer()) + { + long aux_line; + line->value().ToLong(&aux_line); + + if (m_column != 0) + { + pgsOperand column(m_column->eval(vars)); + if (column->is_integer()) + { + long aux_column; + column->value().ToLong(&aux_column); + return rec.get(aux_line, aux_column); + } + else if (column->is_string()) + { + return rec.get(aux_line, rec.get_column(column->value())); + } + } + else + { + return rec.get_line(aux_line); + } + } + } + + return pnew pgsString(wxT("")); +} diff --git a/pgscript/expressions/pgsLines.cpp b/pgscript/expressions/pgsLines.cpp new file mode 100644 index 0000000..2bdc021 --- /dev/null +++ b/pgscript/expressions/pgsLines.cpp @@ -0,0 +1,58 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsLines.h" + +#include "pgscript/objects/pgsNumber.h" +#include "pgscript/objects/pgsRecord.h" + +pgsLines::pgsLines(const wxString &name) : + pgsExpression(), m_name(name) +{ + +} + +pgsLines::~pgsLines() +{ + +} + +pgsExpression *pgsLines::clone() const +{ + return pnew pgsLines(*this); +} + +wxString pgsLines::value() const +{ + return wxString() << wxT("LINES(") << m_name << wxT(")"); +} + +pgsOperand pgsLines::eval(pgsVarMap &vars) const +{ + if (vars.find(m_name) != vars.end()) + { + if (vars[m_name]->is_record()) + { + const pgsRecord &rec = dynamic_cast(*vars[m_name]); + return pnew pgsNumber(wxString() << rec.count_lines(), pgsInt); + } + else + { + // Not a record: 1 line and 1 column + return pnew pgsNumber(wxT("1"), pgsInt); + } + } + else + { + // Does not exist: 0 line and 0 column + return pnew pgsNumber(wxT("0"), pgsInt); + } +} diff --git a/pgscript/expressions/pgsLower.cpp b/pgscript/expressions/pgsLower.cpp new file mode 100644 index 0000000..8702a9c --- /dev/null +++ b/pgscript/expressions/pgsLower.cpp @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsLower.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsLower::pgsLower(const pgsExpression *left, const pgsExpression *right) : + pgsOperation(left, right) +{ + +} + +pgsLower::~pgsLower() +{ + +} + +pgsExpression *pgsLower::clone() const +{ + return pnew pgsLower(*this); +} + +pgsLower::pgsLower(const pgsLower &that) : + pgsOperation(that) +{ + +} + +pgsLower &pgsLower::operator =(const pgsLower &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + return (*this); +} + +wxString pgsLower::value() const +{ + return wxString() << m_left->value() << wxT(" < ") << m_right->value(); +} + +pgsOperand pgsLower::eval(pgsVarMap &vars) const +{ + // Evaluate operands + pgsOperand left(m_left->eval(vars)); + pgsOperand right(m_right->eval(vars)); + + // Return the result + return (*left < *right); +} diff --git a/pgscript/expressions/pgsLowerEqual.cpp b/pgscript/expressions/pgsLowerEqual.cpp new file mode 100644 index 0000000..c2fac92 --- /dev/null +++ b/pgscript/expressions/pgsLowerEqual.cpp @@ -0,0 +1,61 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsLowerEqual.h" +#include "pgscript/objects/pgsRecord.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsLowerEqual::pgsLowerEqual(const pgsExpression *left, const pgsExpression *right) : + pgsOperation(left, right) +{ + +} + +pgsLowerEqual::~pgsLowerEqual() +{ + +} + +pgsExpression *pgsLowerEqual::clone() const +{ + return pnew pgsLowerEqual(*this); +} + +pgsLowerEqual::pgsLowerEqual(const pgsLowerEqual &that) : + pgsOperation(that) +{ + +} + +pgsLowerEqual &pgsLowerEqual::operator =(const pgsLowerEqual &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + return (*this); +} + +wxString pgsLowerEqual::value() const +{ + return wxString() << m_left->value() << wxT(" <= ") << m_right->value(); +} + +pgsOperand pgsLowerEqual::eval(pgsVarMap &vars) const +{ + // Evaluate operands + pgsOperand left(m_left->eval(vars)); + pgsOperand right(m_right->eval(vars)); + + // Return the result + return (*left <= *right); +} diff --git a/pgscript/expressions/pgsMinus.cpp b/pgscript/expressions/pgsMinus.cpp new file mode 100644 index 0000000..8b65011 --- /dev/null +++ b/pgscript/expressions/pgsMinus.cpp @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsMinus.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsMinus::pgsMinus(const pgsExpression *left, const pgsExpression *right) : + pgsOperation(left, right) +{ + +} + +pgsMinus::~pgsMinus() +{ + +} + +pgsExpression *pgsMinus::clone() const +{ + return pnew pgsMinus(*this); +} + +pgsMinus::pgsMinus(const pgsMinus &that) : + pgsOperation(that) +{ + +} + +pgsMinus &pgsMinus::operator =(const pgsMinus &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + return (*this); +} + +wxString pgsMinus::value() const +{ + return wxString() << m_left->value() << wxT(" - ") << m_right->value(); +} + +pgsOperand pgsMinus::eval(pgsVarMap &vars) const +{ + // Evaluate operands + pgsOperand left(m_left->eval(vars)); + pgsOperand right(m_right->eval(vars)); + + // Return the result + return (*left - *right); +} diff --git a/pgscript/expressions/pgsModulo.cpp b/pgscript/expressions/pgsModulo.cpp new file mode 100644 index 0000000..f7aa9b6 --- /dev/null +++ b/pgscript/expressions/pgsModulo.cpp @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsModulo.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsModulo::pgsModulo(const pgsExpression *left, const pgsExpression *right) : + pgsOperation(left, right) +{ + +} + +pgsModulo::~pgsModulo() +{ + +} + +pgsExpression *pgsModulo::clone() const +{ + return pnew pgsModulo(*this); +} + +pgsModulo::pgsModulo(const pgsModulo &that) : + pgsOperation(that) +{ + +} + +pgsModulo &pgsModulo::operator =(const pgsModulo &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + return (*this); +} + +wxString pgsModulo::value() const +{ + return wxString() << m_left->value() << wxT(" % ") << m_right->value(); +} + +pgsOperand pgsModulo::eval(pgsVarMap &vars) const +{ + // Evaluate operands + pgsOperand left(m_left->eval(vars)); + pgsOperand right(m_right->eval(vars)); + + // Return the result + return (*left % *right); +} diff --git a/pgscript/expressions/pgsNegate.cpp b/pgscript/expressions/pgsNegate.cpp new file mode 100644 index 0000000..9c2b987 --- /dev/null +++ b/pgscript/expressions/pgsNegate.cpp @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsNegate.h" + +#include "pgscript/objects/pgsNumber.h" + +pgsNegate::pgsNegate(const pgsExpression *left) : + pgsOperation(left, 0) +{ + +} + +pgsNegate::~pgsNegate() +{ + +} + +pgsExpression *pgsNegate::clone() const +{ + return pnew pgsNegate(*this); +} + +pgsNegate::pgsNegate(const pgsNegate &that) : + pgsOperation(that) +{ + +} + +pgsNegate &pgsNegate::operator =(const pgsNegate &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + return (*this); +} + +wxString pgsNegate::value() const +{ + return wxString() << wxT("-") << m_left->value(); +} + +pgsOperand pgsNegate::eval(pgsVarMap &vars) const +{ + // Evaluate operands + pgsOperand left(pnew pgsNumber(wxT("0"), pgsInt)); + pgsOperand right(m_left->eval(vars)); + + // Return the result + return (*left - *right); +} diff --git a/pgscript/expressions/pgsNot.cpp b/pgscript/expressions/pgsNot.cpp new file mode 100644 index 0000000..a7b29fa --- /dev/null +++ b/pgscript/expressions/pgsNot.cpp @@ -0,0 +1,59 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsNot.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsNot::pgsNot(const pgsExpression *left) : + pgsOperation(left, 0) +{ + +} + +pgsNot::~pgsNot() +{ + +} + +pgsExpression *pgsNot::clone() const +{ + return pnew pgsNot(*this); +} + +pgsNot::pgsNot(const pgsNot &that) : + pgsOperation(that) +{ + +} + +pgsNot &pgsNot::operator =(const pgsNot &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + return (*this); +} + +wxString pgsNot::value() const +{ + return wxString() << wxT("NOT ") << m_left->value(); +} + +pgsOperand pgsNot::eval(pgsVarMap &vars) const +{ + // Evaluate operands + pgsOperand left(m_left->eval(vars)); + + // Return the result + return (!(*left)); +} diff --git a/pgscript/expressions/pgsOperation.cpp b/pgscript/expressions/pgsOperation.cpp new file mode 100644 index 0000000..6bfb56e --- /dev/null +++ b/pgscript/expressions/pgsOperation.cpp @@ -0,0 +1,46 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsOperation.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsOperation::pgsOperation(const pgsExpression *left, const pgsExpression *right) : + pgsExpression(), m_left(left), m_right(right) +{ + +} + +pgsOperation::~pgsOperation() +{ + pdelete(m_left); + pdelete(m_right); +} + +pgsOperation::pgsOperation(const pgsOperation &that) : + pgsExpression(that) +{ + m_left = that.m_left->clone(); + m_right = that.m_right != 0 ? that.m_right->clone() : 0; +} + +pgsOperation &pgsOperation::operator =(const pgsOperation &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + pdelete(m_left); + pdelete(m_right); + m_left = that.m_left->clone(); + m_right = that.m_right != 0 ? that.m_right->clone() : 0; + } + return (*this); +} diff --git a/pgscript/expressions/pgsOr.cpp b/pgscript/expressions/pgsOr.cpp new file mode 100644 index 0000000..f2c8234 --- /dev/null +++ b/pgscript/expressions/pgsOr.cpp @@ -0,0 +1,56 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsOr.h" + +#include "pgscript/objects/pgsNumber.h" + +pgsOr::pgsOr(const pgsExpression *left, const pgsExpression *right) : + pgsOperation(left, right) +{ + +} + +pgsOr::~pgsOr() +{ + +} + +pgsExpression *pgsOr::clone() const +{ + return pnew pgsOr(*this); +} + +pgsOr::pgsOr(const pgsOr &that) : + pgsOperation(that) +{ + +} + +pgsOr &pgsOr::operator =(const pgsOr &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + return (*this); +} + +wxString pgsOr::value() const +{ + return wxString() << m_left->value() << wxT(" OR ") << m_right->value(); +} + +pgsOperand pgsOr::eval(pgsVarMap &vars) const +{ + return pnew pgsNumber(wxString() << (m_left->eval(vars)->pgs_is_true() + || m_right->eval(vars)->pgs_is_true()), pgsInt); +} diff --git a/pgscript/expressions/pgsOver.cpp b/pgscript/expressions/pgsOver.cpp new file mode 100644 index 0000000..5905581 --- /dev/null +++ b/pgscript/expressions/pgsOver.cpp @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsOver.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsOver::pgsOver(const pgsExpression *left, const pgsExpression *right) : + pgsOperation(left, right) +{ + +} + +pgsOver::~pgsOver() +{ + +} + +pgsExpression *pgsOver::clone() const +{ + return pnew pgsOver(*this); +} + +pgsOver::pgsOver(const pgsOver &that) : + pgsOperation(that) +{ + +} + +pgsOver &pgsOver::operator =(const pgsOver &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + return (*this); +} + +wxString pgsOver::value() const +{ + return wxString() << m_left->value() << wxT(" / ") << m_right->value(); +} + +pgsOperand pgsOver::eval(pgsVarMap &vars) const +{ + // Evaluate operands + pgsOperand left(m_left->eval(vars)); + pgsOperand right(m_right->eval(vars)); + + // Return the result + return (*left / *right); +} diff --git a/pgscript/expressions/pgsParenthesis.cpp b/pgscript/expressions/pgsParenthesis.cpp new file mode 100644 index 0000000..7474104 --- /dev/null +++ b/pgscript/expressions/pgsParenthesis.cpp @@ -0,0 +1,59 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsParenthesis.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsParenthesis::pgsParenthesis(const pgsExpression *left) : + pgsOperation(left, 0) +{ + +} + +pgsParenthesis::~pgsParenthesis() +{ + +} + +pgsExpression *pgsParenthesis::clone() const +{ + return pnew pgsParenthesis(*this); +} + +pgsParenthesis::pgsParenthesis(const pgsParenthesis &that) : + pgsOperation(that) +{ + +} + +pgsParenthesis &pgsParenthesis::operator =(const pgsParenthesis &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + return (*this); +} + +wxString pgsParenthesis::value() const +{ + return wxString() << wxT("(") << m_left->value() << wxT(")"); +} + +pgsOperand pgsParenthesis::eval(pgsVarMap &vars) const +{ + // Evaluate operands + pgsOperand left(m_left->eval(vars)); + + // Return the result + return left; +} diff --git a/pgscript/expressions/pgsPlus.cpp b/pgscript/expressions/pgsPlus.cpp new file mode 100644 index 0000000..20c73c8 --- /dev/null +++ b/pgscript/expressions/pgsPlus.cpp @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsPlus.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsPlus::pgsPlus(const pgsExpression *left, const pgsExpression *right) : + pgsOperation(left, right) +{ + +} + +pgsPlus::~pgsPlus() +{ + +} + +pgsExpression *pgsPlus::clone() const +{ + return pnew pgsPlus(*this); +} + +pgsPlus::pgsPlus(const pgsPlus &that) : + pgsOperation(that) +{ + +} + +pgsPlus &pgsPlus::operator =(const pgsPlus &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + return (*this); +} + +wxString pgsPlus::value() const +{ + return wxString() << m_left->value() << wxT(" + ") << m_right->value(); +} + +pgsOperand pgsPlus::eval(pgsVarMap &vars) const +{ + // Evaluate operands + pgsOperand left(m_left->eval(vars)); + pgsOperand right(m_right->eval(vars)); + + // Return the result + return (*left + *right); +} diff --git a/pgscript/expressions/pgsRemoveLine.cpp b/pgscript/expressions/pgsRemoveLine.cpp new file mode 100644 index 0000000..38a23e0 --- /dev/null +++ b/pgscript/expressions/pgsRemoveLine.cpp @@ -0,0 +1,89 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsRemoveLine.h" + +#include "pgscript/exceptions/pgsParameterException.h" +#include "pgscript/objects/pgsRecord.h" +#include "pgscript/objects/pgsString.h" + +pgsRemoveLine::pgsRemoveLine(const wxString &rec, const pgsExpression *line) : + pgsExpression(), m_rec(rec), m_line(line) +{ + +} + +pgsRemoveLine::~pgsRemoveLine() +{ + pdelete(m_line); +} + +pgsExpression *pgsRemoveLine::clone() const +{ + return pnew pgsRemoveLine(*this); +} + +pgsRemoveLine::pgsRemoveLine(const pgsRemoveLine &that) : + pgsExpression(that), m_rec(that.m_rec) +{ + m_line = that.m_line->clone(); +} + +pgsRemoveLine &pgsRemoveLine::operator =(const pgsRemoveLine &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + m_rec = that.m_rec; + pdelete(m_line); + m_line = that.m_line->clone(); + } + return (*this); +} + +wxString pgsRemoveLine::value() const +{ + return wxString() << wxT("RMLINE(") << m_rec << wxT("[") + << m_line->value() << wxT("])"); +} + +pgsOperand pgsRemoveLine::eval(pgsVarMap &vars) const +{ + if (vars.find(m_rec) != vars.end() && vars[m_rec]->is_record()) + { + pgsRecord &rec = dynamic_cast(*vars[m_rec]); + + // Evaluate parameter + pgsOperand line(m_line->eval(vars)); + if (line->is_integer()) + { + long aux_line; + line->value().ToLong(&aux_line); + + if (!rec.remove_line(aux_line)) + { + throw pgsParameterException(wxString() << wxT("an error ") + << wxT("occurred while executing ") << value()); + } + } + else + { + throw pgsParameterException(wxString() << line->value() + << wxT(" is not a valid line number")); + } + + return vars[m_rec]; + } + else + { + throw pgsParameterException(wxString() << m_rec << wxT(" is not a record")); + } +} diff --git a/pgscript/expressions/pgsTimes.cpp b/pgscript/expressions/pgsTimes.cpp new file mode 100644 index 0000000..83ba59e --- /dev/null +++ b/pgscript/expressions/pgsTimes.cpp @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsTimes.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsTimes::pgsTimes(const pgsExpression *left, const pgsExpression *right) : + pgsOperation(left, right) +{ + +} + +pgsTimes::~pgsTimes() +{ + +} + +pgsExpression *pgsTimes::clone() const +{ + return pnew pgsTimes(*this); +} + +pgsTimes::pgsTimes(const pgsTimes &that) : + pgsOperation(that) +{ + +} + +pgsTimes &pgsTimes::operator =(const pgsTimes &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + return (*this); +} + +wxString pgsTimes::value() const +{ + return wxString() << m_left->value() << wxT(" * ") << m_right->value(); +} + +pgsOperand pgsTimes::eval(pgsVarMap &vars) const +{ + // Evaluate operands + pgsOperand left(m_left->eval(vars)); + pgsOperand right(m_right->eval(vars)); + + // Return the result + return (*left **right); +} diff --git a/pgscript/expressions/pgsTrim.cpp b/pgscript/expressions/pgsTrim.cpp new file mode 100644 index 0000000..f824ff3 --- /dev/null +++ b/pgscript/expressions/pgsTrim.cpp @@ -0,0 +1,57 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsTrim.h" + +#include "pgscript/objects/pgsString.h" + +pgsTrim::pgsTrim(const pgsExpression *exp) : + pgsExpression(), m_exp(exp) +{ + +} + +pgsTrim::~pgsTrim() +{ + pdelete(m_exp); +} + +pgsTrim::pgsTrim(const pgsTrim &that) : + pgsExpression(that) +{ + m_exp = that.m_exp->clone(); +} + +pgsTrim &pgsTrim::operator=(const pgsTrim &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + pdelete(m_exp); + m_exp = that.m_exp->clone(); + } + return (*this); +} + +pgsExpression *pgsTrim::clone() const +{ + return pnew pgsTrim(*this); +} + +wxString pgsTrim::value() const +{ + return wxString() << wxT("TRIM(") << m_exp->value() << wxT(")"); +} + +pgsOperand pgsTrim::eval(pgsVarMap &vars) const +{ + return pnew pgsString(m_exp->eval(vars)->value().Strip(wxString::both)); +} diff --git a/pgscript/generators/module.mk b/pgscript/generators/module.mk new file mode 100644 index 0000000..1b83871 --- /dev/null +++ b/pgscript/generators/module.mk @@ -0,0 +1,27 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/pgscript/generators/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + pgscript/generators/pgsDateGen.cpp \ + pgscript/generators/pgsDateTimeGen.cpp \ + pgscript/generators/pgsDictionaryGen.cpp \ + pgscript/generators/pgsIntegerGen.cpp \ + pgscript/generators/pgsNumberGen.cpp \ + pgscript/generators/pgsObjectGen.cpp \ + pgscript/generators/pgsRealGen.cpp \ + pgscript/generators/pgsReferenceGen.cpp \ + pgscript/generators/pgsRegexGen.cpp \ + pgscript/generators/pgsStringGen.cpp \ + pgscript/generators/pgsTimeGen.cpp + +EXTRA_DIST += \ + pgscript/generators/module.mk + diff --git a/pgscript/generators/pgsDateGen.cpp b/pgscript/generators/pgsDateGen.cpp new file mode 100644 index 0000000..a0bfbeb --- /dev/null +++ b/pgscript/generators/pgsDateGen.cpp @@ -0,0 +1,47 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/generators/pgsDateGen.h" + +pgsDateGen::pgsDateGen(wxDateTime min, wxDateTime max, const bool &sequence, + const long &seed) : + pgsObjectGen(seed), m_min(min.IsEarlierThan(max) || min.IsEqualTo(max) ? min : max), + m_max(max.IsLaterThan(min) || max.IsEqualTo(min) ? max : min), + m_range(m_max.Subtract(m_min).GetDays()), m_sequence(sequence) +{ + m_randomizer = pgsRandomizer(pnew pgsIntegerGen(0, m_range, is_sequence(), + m_seed)); +} + +bool pgsDateGen::is_sequence() const +{ + return m_sequence; +} + +wxString pgsDateGen::random() +{ + wxDateSpan date_span(0, 0, 0, m_randomizer->random_long()); + wxDateTime aux_min(m_min); + aux_min.Add(date_span); + wxASSERT(aux_min.IsLaterThan(m_min) || aux_min.IsEqualTo(m_min)); + wxASSERT(aux_min.IsEarlierThan(m_max) || aux_min.IsEqualTo(m_max)); + return aux_min.FormatISODate(); +} + +pgsDateGen::~pgsDateGen() +{ + +} + +pgsDateGen *pgsDateGen::clone() +{ + return pnew pgsDateGen(*this); +} diff --git a/pgscript/generators/pgsDateTimeGen.cpp b/pgscript/generators/pgsDateTimeGen.cpp new file mode 100644 index 0000000..76098fc --- /dev/null +++ b/pgscript/generators/pgsDateTimeGen.cpp @@ -0,0 +1,62 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/generators/pgsDateTimeGen.h" + +#include + +pgsDateTimeGen::pgsDateTimeGen(wxDateTime min, wxDateTime max, + const bool &sequence, const long &seed) : + pgsObjectGen(seed), m_min(min.IsEarlierThan(max) || min.IsEqualTo(max) ? min : max), + m_max(max.IsLaterThan(min) || max.IsEqualTo(min) ? max : min), + m_range(m_max.Subtract(m_min).GetSeconds()), m_sequence(sequence) +{ + m_randomizer = pgsRandomizer(pnew pgsIntegerGen(0, std::string(m_range + .ToString().mb_str()).c_str(), is_sequence(), m_seed)); +} + +bool pgsDateTimeGen::is_sequence() const +{ + return m_sequence; +} + +wxString pgsDateTimeGen::random() +{ + // Get a random number representing seconds + MAPM result = pgsMapm::pgs_str_mapm(m_randomizer->random()), quot, rem; + + // Use hours and seconds for avoiding overflows of seconds + result.integer_div_rem(3600, quot, rem); + long hours, seconds; + pgsMapm::pgs_mapm_str(quot, true).ToLong(&hours); + pgsMapm::pgs_mapm_str(rem, true).ToLong(&seconds); + wxTimeSpan time_span(hours, 0, seconds, 0); + + // Add the TimeSpan to the MinDate + wxDateTime aux_min(m_min); + aux_min.Add(time_span); + + // Post conditions + wxASSERT(aux_min.IsLaterThan(m_min) || aux_min.IsEqualTo(m_min)); + wxASSERT(aux_min.IsEarlierThan(m_max) || aux_min.IsEqualTo(m_max)); + + return aux_min.Format(wxT("%Y-%m-%d %H:%M:%S")); +} + +pgsDateTimeGen::~pgsDateTimeGen() +{ + +} + +pgsDateTimeGen *pgsDateTimeGen::clone() +{ + return pnew pgsDateTimeGen(*this); +} diff --git a/pgscript/generators/pgsDictionaryGen.cpp b/pgscript/generators/pgsDictionaryGen.cpp new file mode 100644 index 0000000..a339c72 --- /dev/null +++ b/pgscript/generators/pgsDictionaryGen.cpp @@ -0,0 +1,99 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/generators/pgsDictionaryGen.h" + +#include +#include +#include + +pgsDictionaryGen::pgsDictionaryGen(const wxString &file_path, + const bool &sequence, const long &seed, wxCSConv conv) : + pgsObjectGen(seed), m_file_path(file_path), m_conv(conv) +{ + m_nb_lines = this->count_lines(); + m_randomizer = pgsRandomizer(pnew pgsIntegerGen(1, m_nb_lines, + sequence, seed)); +} + +wxString pgsDictionaryGen::random() +{ + return this->get_line(m_randomizer->random_long()); +} + +pgsDictionaryGen::~pgsDictionaryGen() +{ + +} + +pgsDictionaryGen *pgsDictionaryGen::clone() +{ + return pnew pgsDictionaryGen(*this); +} + +const long &pgsDictionaryGen::nb_lines() const +{ + return m_nb_lines; +} + +long pgsDictionaryGen::count_lines() +{ + long result = 0; + + wxFileName file_path(m_file_path); + if (file_path.FileExists() && file_path.IsFileReadable()) + { + wxFFileInputStream input(m_file_path); + if (input.IsOk()) + { +#if wxUSE_UNICODE + wxTextInputStream text(input, wxT(" \t"), m_conv); +#else + wxTextInputStream text(input, wxT(" \t")); +#endif + wxString line; + while (!(line = text.ReadLine()).IsEmpty() && !input.Eof()) + { + ++result; + } + } + } + + if (result < 0) result = 0; + wxASSERT(result >= 0); + return result; +} + +wxString pgsDictionaryGen::get_line(long line_nb) +{ + long current_line = 1; + + if (m_nb_lines > 0) + { + wxFFileInputStream input(m_file_path); + if (input.IsOk()) + { +#if wxUSE_UNICODE + wxTextInputStream text(input, wxT(" \t"), m_conv); +#else + wxTextInputStream text(input, wxT(" \t")); +#endif + while (current_line < line_nb && !input.Eof()) + { + text.ReadLine(); + ++current_line; + } + return text.ReadLine(); + } + } + + return wxString(); +} diff --git a/pgscript/generators/pgsIntegerGen.cpp b/pgscript/generators/pgsIntegerGen.cpp new file mode 100644 index 0000000..def1fbc --- /dev/null +++ b/pgscript/generators/pgsIntegerGen.cpp @@ -0,0 +1,174 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/generators/pgsIntegerGen.h" + +pgsIntegerGen::pgsSequentialIntGen::pgsSequentialIntGen(const MAPM &range, + const long &seed) : + pgsNumberGen(range), m_state(seed), m_m(2), m_remainder(m_range) +{ + MAPM _2 = 2; + while (m_m < m_range) + { + m_m = m_m * _2; + } + m_buffer.Alloc(BUFFER_SIZE); +} + +MAPM pgsIntegerGen::pgsSequentialIntGen::random() +{ + // Bufferizer BUFFER_SIZE values in the vector + if (m_buffer.GetCount() == 0) + { + // Calculate the number of elements to bufferize + MAPM min = wxMin(m_remainder, MAPM(BUFFER_SIZE)); + + // Generate those elements + for (MAPM i = 0; i < min; i = i + 1) + { + do + { + m_state = (m_state * arg_a); + m_state = (m_state + arg_c) % m_m; + } + while (m_state >= m_range); + m_buffer.Add(m_state); + m_remainder -= 1; + } + + class pgsRandInt + { + + private: + + long m_state; + + public: + + pgsRandInt(long n) + : m_state(n) + { + + } + + long rand() + { + m_state = (1103515245L * m_state + 12345L) % 2147483647L; + return m_state; + } + + }; + + // Shuffle the vector of generated values + pgsRandInt rand_int(BUFFER_SIZE); + for (size_t i = 0; i < m_buffer.GetCount(); i++) + { + size_t r = i + (rand_int.rand() % (m_buffer.GetCount() - i)); + const MAPM a = m_buffer.Item(i); + m_buffer.Item(i) = m_buffer.Item(r); + m_buffer.Item(r) = a; + } + } + + if (m_remainder == 0) + { + m_remainder = m_range; + } + + // Take the last bufferized value + MAPM data = m_buffer.Last(); + m_buffer.RemoveAt(m_buffer.GetCount() - 1); + + // Return random value + return data; +} + +pgsIntegerGen::pgsSequentialIntGen::~pgsSequentialIntGen() +{ + +} + +pgsNumberGen *pgsIntegerGen::pgsSequentialIntGen::clone() +{ + return pnew pgsIntegerGen::pgsSequentialIntGen(*this); +} + +const MAPM pgsIntegerGen::pgsSequentialIntGen::arg_a = 5; +const MAPM pgsIntegerGen::pgsSequentialIntGen::arg_c = 1; + +pgsIntegerGen::pgsNormalIntGen::pgsNormalIntGen(const MAPM &range, + const long &seed) : + pgsNumberGen(range), m_state(seed), m_top(arg_m - 1) +{ + for (int i = 0; i < 10; i++) + random(); // Beginning of the sequence is garbage +} + +MAPM pgsIntegerGen::pgsNormalIntGen::random() +{ + m_state = (m_state * arg_a); + m_state = (m_state + arg_c) % arg_m; + return (m_state * m_range).div(m_top); +} + +pgsIntegerGen::pgsNormalIntGen::~pgsNormalIntGen() +{ + +} + +pgsNumberGen *pgsIntegerGen::pgsNormalIntGen::clone() +{ + return pnew pgsIntegerGen::pgsNormalIntGen(*this); +} + +const MAPM pgsIntegerGen::pgsNormalIntGen::arg_a = 16807L; +const MAPM pgsIntegerGen::pgsNormalIntGen::arg_c = 0; +const MAPM pgsIntegerGen::pgsNormalIntGen::arg_m = 2147483647L; + +pgsIntegerGen::pgsIntegerGen(const MAPM &min, const MAPM &max, + const bool &sequence, const long &seed) : + pgsObjectGen(seed), m_min(wxMin(min, max)), m_max(wxMax(min, max)), + m_range(m_max - m_min + 1), m_sequence(sequence) +{ + m_randomizer = is_sequence() + ? pgsRandomizer(pnew pgsSequentialIntGen(m_range, m_seed)) + : pgsRandomizer(pnew pgsNormalIntGen(m_range, m_seed)); +} + +bool pgsIntegerGen::is_sequence() const +{ + return m_sequence; +} + +wxString pgsIntegerGen::random() +{ + MAPM data = m_randomizer->random(); + data = data + m_min; + wxASSERT(data >= m_min && data <= m_max); + return pgsMapm::pgs_mapm_str(data); +} + +long pgsIntegerGen::random_long() +{ + long result; + random().ToLong(&result); + return result; +} + +pgsIntegerGen::~pgsIntegerGen() +{ + +} + +pgsIntegerGen *pgsIntegerGen::clone() +{ + return pnew pgsIntegerGen(*this); +} diff --git a/pgscript/generators/pgsNumberGen.cpp b/pgscript/generators/pgsNumberGen.cpp new file mode 100644 index 0000000..17bc446 --- /dev/null +++ b/pgscript/generators/pgsNumberGen.cpp @@ -0,0 +1,23 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/generators/pgsNumberGen.h" + +pgsNumberGen::pgsNumberGen(const MAPM &range) : + m_range(range) +{ + +} + +pgsNumberGen::~pgsNumberGen() +{ + +} diff --git a/pgscript/generators/pgsObjectGen.cpp b/pgscript/generators/pgsObjectGen.cpp new file mode 100644 index 0000000..1ec431f --- /dev/null +++ b/pgscript/generators/pgsObjectGen.cpp @@ -0,0 +1,23 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/generators/pgsObjectGen.h" + +pgsObjectGen::pgsObjectGen(const long &seed) : + m_seed(seed == 0 ? 1 : seed) +{ + +} + +pgsObjectGen::~pgsObjectGen() +{ + +} diff --git a/pgscript/generators/pgsRealGen.cpp b/pgscript/generators/pgsRealGen.cpp new file mode 100644 index 0000000..fcaabd3 --- /dev/null +++ b/pgscript/generators/pgsRealGen.cpp @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/generators/pgsRealGen.h" + +pgsRealGen::pgsRealGen(const MAPM &min, const MAPM &max, + const UCHAR &precision, const bool &sequence, const long &seed) : + pgsObjectGen(seed), m_min(wxMin(min, max)), m_max(wxMax(min, max)), + m_range(m_max - m_min), m_sequence(sequence) +{ + m_pow = MAPM(10).pow(MAPM(precision)); + m_int_max = pgsMapm::pgs_mapm_round(m_range * m_pow) + 1; + + m_randomizer = is_sequence() + ? pgsRandomizer(pnew pgsIntegerGen::pgsSequentialIntGen(m_int_max, m_seed)) + : pgsRandomizer(pnew pgsIntegerGen::pgsNormalIntGen(m_int_max, m_seed)); +} + +bool pgsRealGen::is_sequence() const +{ + return m_sequence; +} + +wxString pgsRealGen::random() +{ + MAPM data = m_randomizer->random() / m_pow; + data = data + m_min; + wxASSERT(data >= m_min && data <= m_max); + return pgsMapm::pgs_mapm_str(data); +} + +pgsRealGen::~pgsRealGen() +{ + +} + +pgsRealGen *pgsRealGen::clone() +{ + return pnew pgsRealGen(*this); +} diff --git a/pgscript/generators/pgsReferenceGen.cpp b/pgscript/generators/pgsReferenceGen.cpp new file mode 100644 index 0000000..ab0dc04 --- /dev/null +++ b/pgscript/generators/pgsReferenceGen.cpp @@ -0,0 +1,76 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/generators/pgsReferenceGen.h" + +#include "pgscript/expressions/pgsExecute.h" +#include "pgscript/objects/pgsNumber.h" +#include "pgscript/objects/pgsRecord.h" +#include "pgscript/utilities/pgsThread.h" + +pgsReferenceGen::pgsReferenceGen(pgsThread *app, const wxString &table, + const wxString &column, const bool &sequence, const long &seed) : + pgsObjectGen(seed), m_app(app), m_table(table), m_column(column), + m_sequence(sequence) +{ + // We need an empty symbol table for calling pgsExecute.eval(...) + pgsVarMap vars; + + // Count the number of lines in the table + pgsOperand result = pgsExecute(wxString() << wxT("SELECT count(*) FROM ") + << m_table, 0, m_app).eval(vars); + wxASSERT(result->is_record()); + wxString value = result->value(); + if (!value.IsEmpty()) + { + m_nb_rows = pgsMapm::pgs_str_mapm(result->number().value()); + } + else + { + m_nb_rows = 0; + } + wxLogScriptVerbose(wxT("REFGEN: Number of rows in %s: %s"), m_table.c_str(), + pgsMapm::pgs_mapm_str(m_nb_rows).c_str()); + + // Create an integer generator with that number of lines + m_randomizer = pgsRandomizer(pnew pgsIntegerGen(0, m_nb_rows - 1, + is_sequence(), m_seed)); +} + +bool pgsReferenceGen::is_sequence() const +{ + return m_sequence; +} + +wxString pgsReferenceGen::random() +{ + // We need an empty symbol table for calling pgsExecute.eval(...) + pgsVarMap vars; + + // Choose one line + pgsOperand result = pgsExecute(wxString() << wxT("SELECT ") << m_column + << wxT(" FROM ") << m_table << wxT(" LIMIT 1 OFFSET ") + << m_randomizer->random(), 0, m_app).eval(vars); + wxASSERT(result->is_record()); + + // Return the result as a single value + return dynamic_cast(*result).get(0, 0)->value(); +} + +pgsReferenceGen::~pgsReferenceGen() +{ + +} + +pgsReferenceGen *pgsReferenceGen::clone() +{ + return pnew pgsReferenceGen(*this); +} diff --git a/pgscript/generators/pgsRegexGen.cpp b/pgscript/generators/pgsRegexGen.cpp new file mode 100644 index 0000000..f5bb050 --- /dev/null +++ b/pgscript/generators/pgsRegexGen.cpp @@ -0,0 +1,309 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/generators/pgsRegexGen.h" + +#include +#include +#include + +#include +WX_DEFINE_OBJARRAY(pgsVectorStringGen); + +pgsRegexGen::pgsRegex::pgsRegex(const pgsVectorChar &characters, + const long &first, const long &second) : + m_characters(characters), m_first(wxMin(first, second)), + m_second(wxMax(first, second)) +{ + +} + +pgsRegexGen::pgsRegex::pgsRegex() : + m_characters(pgsVectorChar()), m_first(0), m_second(0) +{ + +} + +pgsRegexGen::pgsRegex::~pgsRegex() +{ + +} + +pgsRegexGen::pgsRegex *pgsRegexGen::pgsRegex::clone() +{ + return pnew pgsRegexGen::pgsRegex(*this); +} + +void pgsRegexGen::pgsRegex::set_characters(const pgsVectorChar &characters) +{ + m_characters = characters; +} + +void pgsRegexGen::pgsRegex::add_character(const wxChar &c) +{ + m_characters.Add(c); +} + +void pgsRegexGen::pgsRegex::set_first(const long &first) +{ + m_first = first; + m_second = first; +} + +void pgsRegexGen::pgsRegex::set_second(const long &second) +{ + long first = m_first; + m_first = wxMin(first, second); + m_second = wxMax(first, second); +} + +const pgsVectorChar &pgsRegexGen::pgsRegex::get_characters() const +{ + return m_characters; +} + +const long &pgsRegexGen::pgsRegex::get_first() const +{ + return m_first; +} + +const long &pgsRegexGen::pgsRegex::get_second() const +{ + return m_second; +} + +pgsRegexGen::pgsRegexGen(const wxString ®ex, const long &seed) : + pgsObjectGen(seed), m_regex(regex), m_valid(true), m_string_gens(pgsVectorStringGen()) +{ + wxLogScriptVerbose(wxT("REGEXGEN: %s"), m_regex.c_str()); + + // Transform regular expression into XML structure + bool escape = false, first_regex = true, list = false; + wxString result = wxT("\n"); + size_t i = 0; + while (i < m_regex.Length()) + { + if (escape) + { + if (list == true) + { + result.Append(espace_xml_char(m_regex[i])); + } + else + { + if (!first_regex) + result.Append(wxT(" \n")); + else + first_regex = false; + result.Append(wxT(" \n ")); + result.Append(espace_xml_char(m_regex[i])); + result.Append(wxT("\n")); + } + escape = false; + } + else if (list == true && m_regex[i] == wxT('-')) + { + if ((i + 1) < m_regex.Length()) + { + result.Append(char_range(m_regex[i - 1], m_regex[i + 1])); + } + } + else if (m_regex[i] == wxT('[')) + { + if (!first_regex) + result.Append(wxT(" \n")); + else + first_regex = false; + result.Append(wxT(" \n ")); + list = true; + } + else if (m_regex[i] == wxT(']')) + { + result.Append(wxT("\n")); + list = false; + } + else if (m_regex[i] == wxT('{')) + { + result.Append(wxT(" ")); + list = true; + } + else if (m_regex[i] == wxT('}')) + { + result.Append(wxT("\n")); + list = false; + } + else if (m_regex[i] == wxT('\\')) + { + escape = true; + } + else + { + if (list == true) + { + result.Append(espace_xml_char(m_regex[i])); + } + else + { + if (!first_regex) + result.Append(wxT(" \n")); + else + first_regex = false; + result.Append(wxT(" \n ")); + result.Append(espace_xml_char(m_regex[i])); + result.Append(wxT("\n")); + } + } + + ++i; + } + if (result != wxT("\n")) + result.Append(wxT(" \n")); + result.Append(wxT("\n")); + + wxLogScriptVerbose(wxT("REGEXGEN: %s"), result.c_str()); + + // Load this XML structure with the wxXmlDocument from wxWidgets + wxStringInputStream input(result); + wxXmlDocument doc; + if (!doc.Load(input, wxT("UTF-8"), wxXMLDOC_KEEP_WHITESPACE_NODES)) + { + m_valid = false; + } + else + { + // Start processing the XML file + if (doc.GetRoot()->GetName() != wxT("regexpressions")) + { + m_valid = false; + } + else + { + // Go through XML nodes + wxXmlNode *xml_regexpressions = doc.GetRoot()->GetChildren(); + while (xml_regexpressions && m_valid) + { + if (xml_regexpressions->GetName() == wxT("regex")) + { + wxXmlNode *xml_regex = xml_regexpressions->GetChildren(); + + pgsRegex regex; + regex.set_first(1); + + while (xml_regex && m_valid) + { + if (xml_regex->GetName() == wxT("characters")) + { + wxString content = xml_regex->GetNodeContent(); + for (size_t i = 0; i < content.Length(); i++) + { + regex.add_character(content[i]); + } + } + else if (xml_regex->GetName() == wxT("range")) + { + wxString content = xml_regex->GetNodeContent(); + wxRegEx ex(wxT("^([0-9]+)(,([0-9]+))?$")); + wxASSERT(ex.IsValid()); + if (ex.Matches(content)) + { + long min; + ex.GetMatch(content, 1).ToLong(&min); + regex.set_first(min); + wxString smax = ex.GetMatch(content, 3); + if (!smax.IsEmpty()) + { + long max; + smax.ToLong(&max); + regex.set_second(max); + } + } + else + { + // m_valid = false; + } + } + + xml_regex = xml_regex->GetNext(); + } + + m_string_gens.Add(pgsStringGen(regex.get_first(), + regex.get_second(), 1, seed, + regex.get_characters())); + } + + xml_regexpressions = xml_regexpressions->GetNext(); + } + } + } +} + +wxString pgsRegexGen::random() +{ + wxString result; + for (size_t i = 0; i < string_gens_size(); i++) + { + result.Append(m_string_gens.Item(i).random()); + } + return result; +} + +const pgsVectorStringGen &pgsRegexGen::string_gens() const +{ + return m_string_gens; +} + +size_t pgsRegexGen::string_gens_size() const +{ + return m_string_gens.size(); +} + +const bool &pgsRegexGen::is_valid() const +{ + return m_valid; +} + +wxString pgsRegexGen::espace_xml_char(const wxChar &c) +{ + if (c == wxT('<')) + return wxT("<"); + else if (c == wxT('&')) + return wxT("&"); + else if (c == wxT('>')) + return wxT(">"); + else if (c == wxT('"')) + return wxT("""); + else if (c == wxT('\'')) + return wxT("'"); + else return wxString(c); +} + +wxString pgsRegexGen::char_range(const wxChar &b, const wxChar &c) +{ + wxChar min = wxMin(b, c); + ++min; + wxChar max = wxMax(b, c); + wxString result; + for (wxChar i = min; i < max; i++) + { + result.Append(espace_xml_char(i)); + } + return result; +} + +pgsRegexGen::~pgsRegexGen() +{ + +} + +pgsRegexGen *pgsRegexGen::clone() +{ + return pnew pgsRegexGen(*this); +} diff --git a/pgscript/generators/pgsStringGen.cpp b/pgscript/generators/pgsStringGen.cpp new file mode 100644 index 0000000..7e0188d --- /dev/null +++ b/pgscript/generators/pgsStringGen.cpp @@ -0,0 +1,83 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/generators/pgsStringGen.h" + +#include +WX_DEFINE_OBJARRAY(pgsVectorChar); + +pgsStringGen::pgsStringGen(USHORT w_size_min, USHORT w_size_max, + const UCHAR &nb_words, const long &seed, pgsVectorChar characters) : + pgsObjectGen(seed), m_nb_words(nb_words), m_characters(characters) +{ + init_characters(); // Initialize vector if it is empty + + const USHORT w_size_aux = w_size_min; + w_size_min = wxMin(w_size_aux, w_size_max); + w_size_max = wxMax(w_size_aux, w_size_max); + + size_t char_count = m_characters.GetCount(); + m_w_size_randomizer = pgsRandomizer(pnew pgsIntegerGen(w_size_min, + w_size_max, false, seed)); + m_letter_randomizer = pgsRandomizer(pnew pgsIntegerGen(0, + wx_static_cast(long, char_count) - 1, false, seed)); +} + +wxString pgsStringGen::random() +{ + wxString str_result; + long w_size; + + for (UCHAR i = 0; i < m_nb_words; i++) + { + w_size = m_w_size_randomizer->random_long(); + for (long j = 0; j < w_size; j++) + { + str_result.Append(m_characters + .Item(m_letter_randomizer->random_long()), 1); + } + if (w_size > 0 && m_nb_words != (i + 1)) + { + str_result.Append(wxT(' '), 1); + } + } + + return str_result; +} + +pgsStringGen::~pgsStringGen() +{ + +} + +void pgsStringGen::init_characters() +{ + if (m_characters.size() == 0) + { + for (char c = '0'; c <= '9'; c++) + { + m_characters.push_back(c); + } + for (char c = 'A'; c <= 'Z'; c++) + { + m_characters.push_back(c); + } + for (char c = 'a'; c <= 'z'; c++) + { + m_characters.push_back(c); + } + } +} + +pgsStringGen *pgsStringGen::clone() +{ + return pnew pgsStringGen(*this); +} diff --git a/pgscript/generators/pgsTimeGen.cpp b/pgscript/generators/pgsTimeGen.cpp new file mode 100644 index 0000000..e933cba --- /dev/null +++ b/pgscript/generators/pgsTimeGen.cpp @@ -0,0 +1,52 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/generators/pgsTimeGen.h" + +#include + +pgsTimeGen::pgsTimeGen(wxDateTime min, wxDateTime max, const bool &sequence, + const long &seed) : + pgsObjectGen(seed), m_min(min.IsEarlierThan(max) || min.IsEqualTo(max) ? min : max), + m_max(max.IsLaterThan(min) || max.IsEqualTo(min) ? max : min), + m_range(m_max.Subtract(m_min).GetSeconds()), m_sequence(sequence) +{ + m_min.SetYear(1970); // We know this date is not a DST date + m_min.SetMonth(wxDateTime::Jan); + m_min.SetDay(1); + m_randomizer = pgsRandomizer(pnew pgsIntegerGen(0, std::string(m_range + .ToString().mb_str()).c_str(), is_sequence(), m_seed)); +} + +bool pgsTimeGen::is_sequence() const +{ + return m_sequence; +} + +wxString pgsTimeGen::random() +{ + wxTimeSpan time_span(0, 0, m_randomizer->random_long(), 0); + wxDateTime aux_min(m_min); + aux_min.Add(time_span); + wxASSERT(aux_min.IsLaterThan(m_min) || aux_min.IsEqualTo(m_min)); + wxASSERT(aux_min.IsEarlierThan(m_max) || aux_min.IsEqualTo(m_max)); + return aux_min.FormatISOTime(); +} + +pgsTimeGen::~pgsTimeGen() +{ + +} + +pgsTimeGen *pgsTimeGen::clone() +{ + return pnew pgsTimeGen(*this); +} diff --git a/pgscript/lex.pgs.cc b/pgscript/lex.pgs.cc new file mode 100644 index 0000000..0b69f03 --- /dev/null +++ b/pgscript/lex.pgs.cc @@ -0,0 +1,2696 @@ +#include "pgAdmin3.h" + + +#line 2 "pgscript/lex.pgs.cc" + +#line 4 "pgscript/lex.pgs.cc" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 33 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + + /* The c++ scanner is a mess. The FlexLexer.h header file relies on the + * following macro. This is required in order to pass the c++-multiple-scanners + * test in the regression suite. We get reports that it breaks inheritance. + * We will address this in a future release of flex, or omit the C++ scanner + * altogether. + */ + #define yyFlexLexer pgsFlexLexer + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! FLEXINT_H */ + +/* begin standard C++ headers. */ +#include +#include +#include +#include +/* end standard C++ headers. */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +#if __STDC__ + +#define YY_USE_CONST + +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +extern int yyleng; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, (yytext_ptr) ) + +/* The following is because we cannot portably get our hands on size_t + * (without autoconf's help, which isn't available because we want + * flex-generated scanners to compile on their own). + */ + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef unsigned int yy_size_t; +#endif + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + + std::istream* yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +void *pgsalloc (yy_size_t ); +void *pgsrealloc (void *,yy_size_t ); +void pgsfree (void * ); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +#define yywrap(n) 1 +#define YY_SKIP_YYWRAP + +typedef unsigned char YY_CHAR; + +#define yytext_ptr yytext + +#include "pgscript/FlexLexer.h" + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + yyleng = (size_t) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; + +#define YY_NUM_RULES 137 +#define YY_END_OF_BUFFER 138 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[444] = + { 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 138, 114, 111, 113, 112, 61, 64, 50, 51, 59, + 58, 55, 57, 54, 60, 35, 49, 46, 62, 43, + 63, 34, 52, 53, 114, 114, 114, 114, 114, 114, + 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, + 114, 114, 114, 47, 48, 114, 130, 129, 128, 130, + 122, 121, 120, 122, 115, 118, 119, 122, 122, 117, + 126, 125, 124, 126, 136, 135, 134, 133, 136, 111, + 48, 0, 36, 2, 38, 35, 0, 53, 47, 52, + 41, 45, 42, 34, 0, 0, 0, 11, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 13, 0, 8, 0, 0, 0, + 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 44, 127, + 0, 116, 3, 0, 123, 131, 132, 0, 1, 0, + 36, 0, 0, 37, 0, 0, 0, 39, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 103, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 38, 0, 0, 0, 0, 0, 0, + 19, 0, 0, 0, 0, 0, 0, 75, 0, 26, + 0, 0, 0, 0, 81, 9, 0, 0, 0, 0, + 25, 0, 0, 0, 0, 0, 90, 91, 92, 0, + 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, + 27, 17, 0, 0, 0, 0, 0, 0, 0, 0, + 36, 65, 66, 0, 0, 32, 5, 0, 71, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 87, 0, 0, 16, 0, + 0, 0, 14, 0, 0, 0, 24, 0, 0, 98, + 0, 0, 0, 0, 0, 0, 30, 105, 0, 0, + 0, 0, 0, 0, 0, 4, 0, 12, 0, 0, + 0, 0, 0, 74, 0, 76, 0, 0, 0, 79, + 0, 0, 0, 0, 0, 88, 0, 89, 93, 0, + 0, 20, 0, 0, 0, 6, 99, 18, 0, 0, + 102, 23, 0, 0, 108, 109, 110, 0, 67, 0, + 0, 0, 72, 15, 73, 0, 0, 0, 78, 80, + + 0, 0, 84, 85, 21, 94, 0, 0, 96, 97, + 0, 0, 0, 0, 10, 0, 0, 0, 7, 28, + 0, 0, 0, 83, 95, 0, 100, 0, 106, 107, + 0, 0, 0, 0, 31, 82, 29, 101, 68, 69, + 70, 77, 0 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 4, 4, 5, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 1, 1, 6, 7, 8, 1, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 19, 20, 21, + 22, 23, 1, 24, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 6, 37, 38, 39, 40, 41, 42, + 6, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 25, 26, 27, 1, 6, 1, 28, 29, 30, 31, + + 32, 33, 34, 35, 36, 6, 37, 38, 39, 40, + 41, 42, 6, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 1, 53, 54, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int32_t yy_meta[55] = + { 0, + 1, 1, 2, 1, 1, 3, 4, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, + 1, 1, 1, 3, 1, 1, 1, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 1, 1, 1 + } ; + +static yyconst flex_int16_t yy_base[453] = + { 0, + 0, 0, 52, 53, 63, 81, 56, 64, 76, 84, + 507, 508, 58, 508, 508, 483, 508, 508, 508, 508, + 508, 508, 490, 486, 491, 79, 479, 508, 86, 508, + 479, 0, 508, 508, 74, 72, 78, 92, 85, 90, + 34, 67, 91, 459, 458, 455, 454, 97, 105, 103, + 101, 468, 114, 508, 508, 473, 508, 508, 508, 477, + 508, 508, 508, 486, 508, 508, 508, 477, 479, 508, + 508, 508, 508, 483, 508, 508, 508, 480, 0, 143, + 508, 485, 99, 508, 112, 135, 139, 508, 508, 508, + 508, 508, 508, 0, 446, 441, 127, 441, 450, 451, + + 438, 449, 115, 124, 448, 434, 140, 434, 436, 432, + 444, 127, 429, 435, 508, 444, 508, 127, 133, 146, + 424, 425, 508, 143, 152, 431, 430, 420, 146, 425, + 155, 426, 156, 426, 432, 151, 426, 425, 508, 508, + 453, 508, 508, 452, 508, 508, 508, 455, 508, 188, + 175, 195, 439, 438, 412, 422, 415, 508, 420, 415, + 422, 404, 418, 403, 402, 399, 405, 398, 392, 413, + 408, 401, 400, 405, 406, 393, 402, 431, 402, 393, + 400, 397, 388, 395, 394, 393, 379, 392, 385, 389, + 384, 377, 378, 38, 376, 384, 383, 374, 381, 380, + + 365, 369, 373, 370, 375, 374, 403, 356, 360, 366, + 369, 361, 359, 362, 369, 350, 349, 349, 355, 374, + 373, 196, 372, 371, 343, 344, 336, 342, 344, 346, + 508, 345, 349, 335, 340, 168, 342, 508, 332, 331, + 337, 346, 328, 344, 508, 508, 185, 325, 342, 334, + 508, 323, 324, 332, 321, 332, 508, 508, 508, 330, + 334, 316, 508, 316, 316, 315, 308, 325, 327, 309, + 310, 315, 311, 321, 307, 318, 192, 508, 302, 306, + 508, 508, 315, 300, 298, 296, 309, 307, 307, 320, + 319, 508, 508, 285, 290, 332, 508, 291, 508, 300, + + 291, 290, 284, 288, 295, 290, 284, 281, 291, 279, + 278, 279, 274, 282, 508, 508, 272, 284, 508, 275, + 264, 270, 508, 276, 280, 278, 508, 277, 264, 508, + 267, 274, 273, 276, 262, 257, 508, 508, 267, 272, + 254, 266, 258, 252, 254, 508, 262, 508, 193, 252, + 249, 247, 245, 508, 243, 508, 249, 257, 254, 508, + 254, 256, 240, 250, 241, 508, 237, 508, 508, 247, + 244, 508, 237, 227, 243, 508, 508, 508, 244, 237, + 508, 508, 227, 239, 508, 508, 508, 227, 508, 220, + 199, 203, 508, 508, 508, 205, 204, 207, 232, 508, + + 192, 194, 508, 508, 508, 508, 189, 198, 508, 508, + 189, 185, 192, 183, 508, 194, 178, 180, 508, 508, + 174, 203, 174, 508, 508, 185, 508, 170, 508, 508, + 172, 128, 115, 116, 508, 508, 508, 508, 508, 508, + 508, 508, 508, 241, 245, 249, 253, 96, 255, 257, + 261, 265 + } ; + +static yyconst flex_int16_t yy_def[453] = + { 0, + 443, 1, 444, 444, 445, 445, 446, 446, 447, 447, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 448, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 449, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 450, 443, 443, 443, 443, 451, 443, + 443, 452, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 448, 443, 443, 443, 443, 443, 443, + + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 449, 443, 443, 450, 443, 443, 443, 452, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 0, 443, 443, 443, 443, 443, 443, 443, + 443, 443 + } ; + +static yyconst flex_int16_t yy_nxt[563] = + { 0, + 12, 13, 14, 13, 15, 12, 12, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 12, 34, 35, 36, 37, + 38, 39, 40, 41, 12, 42, 12, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 12, 12, + 12, 54, 55, 56, 58, 58, 59, 59, 72, 80, + 73, 80, 74, 60, 60, 62, 72, 63, 73, 64, + 74, 65, 66, 67, 115, 263, 116, 68, 76, 69, + 77, 264, 70, 62, 78, 63, 76, 64, 77, 65, + 66, 67, 78, 89, 85, 68, 86, 69, 94, 117, + + 70, 79, 95, 99, 90, 101, 118, 91, 92, 79, + 87, 96, 102, 97, 100, 103, 83, 98, 104, 106, + 105, 113, 110, 107, 111, 114, 119, 108, 125, 151, + 150, 120, 128, 112, 109, 126, 129, 127, 132, 130, + 134, 137, 135, 152, 80, 133, 80, 442, 138, 131, + 85, 153, 86, 153, 157, 164, 154, 158, 179, 441, + 165, 166, 167, 168, 440, 169, 87, 172, 180, 173, + 184, 185, 186, 188, 192, 189, 187, 174, 193, 194, + 216, 195, 209, 206, 196, 197, 247, 198, 217, 199, + 207, 212, 151, 277, 349, 200, 201, 210, 202, 302, + + 220, 213, 220, 303, 422, 221, 222, 223, 290, 223, + 290, 439, 224, 291, 438, 337, 437, 436, 434, 433, + 432, 431, 430, 429, 428, 427, 435, 426, 425, 311, + 424, 423, 312, 422, 421, 420, 419, 390, 418, 417, + 391, 57, 57, 57, 57, 61, 61, 61, 61, 71, + 71, 71, 71, 75, 75, 75, 75, 141, 141, 144, + 144, 147, 416, 147, 147, 148, 148, 148, 148, 415, + 414, 413, 412, 411, 410, 409, 408, 407, 406, 405, + 404, 403, 402, 401, 400, 399, 398, 397, 396, 395, + 394, 393, 392, 389, 388, 387, 386, 385, 384, 383, + + 382, 381, 380, 379, 378, 377, 376, 375, 374, 373, + 372, 371, 370, 369, 368, 367, 366, 365, 364, 363, + 362, 361, 360, 359, 358, 357, 356, 355, 354, 353, + 352, 351, 350, 349, 348, 347, 291, 291, 346, 345, + 344, 343, 342, 341, 340, 339, 338, 336, 335, 334, + 333, 332, 331, 330, 329, 328, 327, 326, 325, 324, + 323, 322, 321, 320, 319, 318, 317, 316, 315, 314, + 313, 310, 309, 308, 307, 306, 305, 304, 301, 300, + 299, 298, 297, 296, 295, 294, 293, 292, 224, 224, + 221, 221, 289, 288, 287, 286, 285, 284, 283, 282, + + 281, 280, 279, 278, 277, 276, 275, 274, 273, 272, + 271, 270, 269, 268, 267, 266, 265, 262, 261, 260, + 259, 258, 257, 256, 255, 254, 253, 252, 251, 250, + 249, 248, 247, 246, 245, 244, 243, 242, 241, 240, + 239, 238, 237, 236, 235, 234, 233, 232, 231, 230, + 229, 228, 227, 226, 225, 154, 154, 149, 145, 142, + 219, 218, 215, 214, 211, 208, 205, 204, 203, 191, + 190, 183, 182, 181, 178, 177, 176, 175, 171, 170, + 163, 162, 161, 160, 159, 156, 155, 149, 146, 145, + 143, 82, 142, 140, 139, 136, 124, 123, 122, 121, + + 93, 88, 84, 83, 82, 81, 443, 11, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443 + } ; + +static yyconst flex_int16_t yy_chk[563] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 4, 3, 4, 7, 13, + 7, 13, 7, 3, 4, 5, 8, 5, 8, 5, + 8, 5, 5, 5, 41, 194, 41, 5, 9, 5, + 9, 194, 5, 6, 9, 6, 10, 6, 10, 6, + 6, 6, 10, 29, 26, 6, 26, 6, 448, 42, + + 6, 9, 35, 36, 29, 37, 42, 29, 29, 10, + 26, 35, 37, 35, 36, 37, 83, 35, 37, 38, + 37, 40, 39, 38, 39, 40, 43, 38, 48, 85, + 83, 43, 49, 39, 38, 48, 49, 48, 50, 49, + 51, 53, 51, 85, 80, 50, 80, 434, 53, 49, + 86, 87, 86, 87, 97, 103, 87, 97, 112, 433, + 103, 104, 104, 104, 432, 104, 86, 107, 112, 107, + 118, 118, 119, 120, 124, 120, 119, 107, 124, 125, + 136, 125, 131, 129, 125, 125, 247, 125, 136, 125, + 129, 133, 151, 277, 349, 125, 125, 131, 125, 236, + + 150, 133, 150, 236, 422, 150, 151, 152, 222, 152, + 222, 431, 152, 222, 428, 277, 426, 423, 421, 418, + 417, 416, 414, 413, 412, 411, 422, 408, 407, 247, + 402, 401, 247, 399, 398, 397, 396, 349, 392, 391, + 349, 444, 444, 444, 444, 445, 445, 445, 445, 446, + 446, 446, 446, 447, 447, 447, 447, 449, 449, 450, + 450, 451, 390, 451, 451, 452, 452, 452, 452, 388, + 384, 383, 380, 379, 375, 374, 373, 371, 370, 367, + 365, 364, 363, 362, 361, 359, 358, 357, 355, 353, + 352, 351, 350, 347, 345, 344, 343, 342, 341, 340, + + 339, 336, 335, 334, 333, 332, 331, 329, 328, 326, + 325, 324, 322, 321, 320, 318, 317, 314, 313, 312, + 311, 310, 309, 308, 307, 306, 305, 304, 303, 302, + 301, 300, 298, 296, 295, 294, 291, 290, 289, 288, + 287, 286, 285, 284, 283, 280, 279, 276, 275, 274, + 273, 272, 271, 270, 269, 268, 267, 266, 265, 264, + 262, 261, 260, 256, 255, 254, 253, 252, 250, 249, + 248, 244, 243, 242, 241, 240, 239, 237, 235, 234, + 233, 232, 230, 229, 228, 227, 226, 225, 224, 223, + 221, 220, 219, 218, 217, 216, 215, 214, 213, 212, + + 211, 210, 209, 208, 207, 206, 205, 204, 203, 202, + 201, 200, 199, 198, 197, 196, 195, 193, 192, 191, + 190, 189, 188, 187, 186, 185, 184, 183, 182, 181, + 180, 179, 178, 177, 176, 175, 174, 173, 172, 171, + 170, 169, 168, 167, 166, 165, 164, 163, 162, 161, + 160, 159, 157, 156, 155, 154, 153, 148, 144, 141, + 138, 137, 135, 134, 132, 130, 128, 127, 126, 122, + 121, 116, 114, 113, 111, 110, 109, 108, 106, 105, + 102, 101, 100, 99, 98, 96, 95, 82, 78, 74, + 69, 68, 64, 60, 56, 52, 47, 46, 45, 44, + + 31, 27, 25, 24, 23, 16, 11, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443 + } ; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +#line 1 "pgscript/pgsScanner.ll" +#line 6 "pgscript/pgsScanner.ll" + +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + +#include "pgscript/pgScript.h" +#include "pgscript/parser.tab.hh" +#include "pgscript/utilities/pgsScanner.h" + +/* Import the parser's token type into a local typedef */ +typedef pgscript::pgsParser::token token; +typedef pgscript::pgsParser::token_type token_type; + +/* Work around an incompatibility in flex (at least versions 2.5.31 through + * 2.5.33): it generates code that does not conform to C89. See Debian bug + * 333231 . */ +#undef yywrap +#define yywrap() 1 + +/* By default yylex returns int, we use token_type. Unfortunately yyterminate + * by default returns 0, which is not of token_type. */ +#define yyterminate() return token::PGS_END + +/* This disables inclusion of unistd.h, which is not available under Visual C++ + * on Win32. The C++ scanner uses STL streams instead. */ +#define YY_NO_UNISTD_H + +/*** Flex Declarations and Options ***/ +/* Enable C++ scanner class generation */ +/* Change the name of the scanner class. Results in "pgsFlexLexer" */ +/* Case insensitive */ +/* The manual says "somewhat more optimized" */ +/* Prevent isatty warning in VC++ */ +/* For using start conditions */ +/* No support for include files is planned */ +/* The following paragraph suffices to track locations accurately. Each time + * yylex is invoked, the begin position is moved onto the end position. */ +#line 66 "pgscript/pgsScanner.ll" +#define YY_USER_ACTION yylloc->columns(yyleng); + + + + +#line 732 "pgscript/lex.pgs.cc" + +#define INITIAL 0 +#define SC_COMMENT 1 +#define SC_QUERY 2 +#define SC_DOLLAR 3 +#define SC_STRING 4 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ); +#endif + +#ifndef YY_NO_INPUT + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +#define ECHO LexerOutput( yytext, yyleng ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ +\ + if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) LexerError( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 +#define YY_DECL int yyFlexLexer::yylex() +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 74 "pgscript/pgsScanner.ll" + + + /* Code to place at the beginning of yylex() */ + + // Reset location + yylloc->step(); + + +#line 845 "pgscript/lex.pgs.cc" + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) + yyin = & std::cin; + + if ( ! yyout ) + yyout = & std::cout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 444 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_current_state != 443 ); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 82 "pgscript/pgsScanner.ll" +{ /* Ignore SQL comment */ } + YY_BREAK +case 2: +YY_RULE_SETUP +#line 83 "pgscript/pgsScanner.ll" +{ comment_caller = INITIAL; BEGIN(SC_COMMENT); } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 84 "pgscript/pgsScanner.ll" +{ comment_caller = SC_QUERY; BEGIN(SC_COMMENT); } + YY_BREAK + +case 4: +YY_RULE_SETUP +#line 87 "pgscript/pgsScanner.ll" +{ return token::PGS_WHILE; } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 88 "pgscript/pgsScanner.ll" +{ return token::PGS_BREAK; } + YY_BREAK +case 6: +YY_RULE_SETUP +#line 89 "pgscript/pgsScanner.ll" +{ return token::PGS_RETURN; } + YY_BREAK +case 7: +YY_RULE_SETUP +#line 90 "pgscript/pgsScanner.ll" +{ return token::PGS_CONTINUE; } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 91 "pgscript/pgsScanner.ll" +{ return token::PGS_IF; } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 92 "pgscript/pgsScanner.ll" +{ return token::PGS_ELSE; } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 93 "pgscript/pgsScanner.ll" +{ return token::PGS_WAITFOR; } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 94 "pgscript/pgsScanner.ll" +{ return token::PGS_AS; } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 96 "pgscript/pgsScanner.ll" +{ return token::PGS_ASSERT; } + YY_BREAK +case 13: +YY_RULE_SETUP +#line 97 "pgscript/pgsScanner.ll" +{ /* Ignore it */ } + YY_BREAK +case 14: +YY_RULE_SETUP +#line 98 "pgscript/pgsScanner.ll" +{ return token::PGS_PRINT; } + YY_BREAK +case 15: +YY_RULE_SETUP +#line 100 "pgscript/pgsScanner.ll" +{ return token::PGS_CNT_COLUMNS; } + YY_BREAK +case 16: +YY_RULE_SETUP +#line 101 "pgscript/pgsScanner.ll" +{ return token::PGS_CNT_LINES; } + YY_BREAK +case 17: +YY_RULE_SETUP +#line 102 "pgscript/pgsScanner.ll" +{ return token::PGS_TRIM; } + YY_BREAK +case 18: +YY_RULE_SETUP +#line 103 "pgscript/pgsScanner.ll" +{ return token::PGS_RM_LINE; } + YY_BREAK +case 19: +YY_RULE_SETUP +#line 104 "pgscript/pgsScanner.ll" +{ return token::PGS_CAST; } + YY_BREAK +case 20: +YY_RULE_SETUP +#line 106 "pgscript/pgsScanner.ll" +{ return token::PGS_RECORD; } + YY_BREAK +case 21: +YY_RULE_SETUP +#line 108 "pgscript/pgsScanner.ll" +{ return token::PGS_INTEGER; } + YY_BREAK +case 22: +YY_RULE_SETUP +#line 109 "pgscript/pgsScanner.ll" +{ return token::PGS_REAL; } + YY_BREAK +case 23: +YY_RULE_SETUP +#line 110 "pgscript/pgsScanner.ll" +{ return token::PGS_STRING; } + YY_BREAK +case 24: +YY_RULE_SETUP +#line 111 "pgscript/pgsScanner.ll" +{ return token::PGS_REGEX; } + YY_BREAK +case 25: +YY_RULE_SETUP +#line 112 "pgscript/pgsScanner.ll" +{ return token::PGS_FILE; } + YY_BREAK +case 26: +YY_RULE_SETUP +#line 113 "pgscript/pgsScanner.ll" +{ return token::PGS_DATE; } + YY_BREAK +case 27: +YY_RULE_SETUP +#line 114 "pgscript/pgsScanner.ll" +{ return token::PGS_TIME; } + YY_BREAK +case 28: +YY_RULE_SETUP +#line 115 "pgscript/pgsScanner.ll" +{ return token::PGS_DATE_TIME; } + YY_BREAK +case 29: +YY_RULE_SETUP +#line 116 "pgscript/pgsScanner.ll" +{ return token::PGS_REFERENCE; } + YY_BREAK +case 30: +YY_RULE_SETUP +#line 119 "pgscript/pgsScanner.ll" +{ unput('@'); yylloc->end.columns(-1); + return token::PGS_SET_ASSIGN; } + YY_BREAK +case 31: +YY_RULE_SETUP +#line 121 "pgscript/pgsScanner.ll" +{ unput('@'); yylloc->end.columns(-1); + return token::PGS_DECLARE_ASSGN; } + YY_BREAK +case 32: +YY_RULE_SETUP +#line 124 "pgscript/pgsScanner.ll" +{ /* Block opening */ return token::PGS_OPEN; } + YY_BREAK +case 33: +YY_RULE_SETUP +#line 125 "pgscript/pgsScanner.ll" +{ /* Block closing */ return token::PGS_CLOSE; } + YY_BREAK +case 34: +YY_RULE_SETUP +#line 127 "pgscript/pgsScanner.ll" +{ yylval->str = pnew wxString(yytext, m_conv); + return token::PGS_IDENTIFIER; } + YY_BREAK +case 35: +YY_RULE_SETUP +#line 130 "pgscript/pgsScanner.ll" +{ yylval->str = pnew wxString(yytext, m_conv); + return token::PGS_VAL_INT; } + YY_BREAK +case 36: +YY_RULE_SETUP +#line 133 "pgscript/pgsScanner.ll" +{ yylval->str = pnew wxString(yytext, m_conv); + return token::PGS_VAL_REAL; } + YY_BREAK +case 37: +YY_RULE_SETUP +#line 135 "pgscript/pgsScanner.ll" +{ yylval->str = pnew wxString(yytext, m_conv); + return token::PGS_VAL_REAL; } + YY_BREAK +case 38: +YY_RULE_SETUP +#line 137 "pgscript/pgsScanner.ll" +{ yylval->str = pnew wxString(yytext, m_conv); + return token::PGS_VAL_REAL; } + YY_BREAK +case 39: +YY_RULE_SETUP +#line 140 "pgscript/pgsScanner.ll" +{ return token::PGS_AND_OP; } + YY_BREAK +case 40: +YY_RULE_SETUP +#line 141 "pgscript/pgsScanner.ll" +{ return token::PGS_OR_OP; } + YY_BREAK +case 41: +YY_RULE_SETUP +#line 142 "pgscript/pgsScanner.ll" +{ return token::PGS_LE_OP; } + YY_BREAK +case 42: +YY_RULE_SETUP +#line 143 "pgscript/pgsScanner.ll" +{ return token::PGS_GE_OP; } + YY_BREAK +case 43: +YY_RULE_SETUP +#line 144 "pgscript/pgsScanner.ll" +{ return token::PGS_EQ_OP; } + YY_BREAK +case 44: +YY_RULE_SETUP +#line 145 "pgscript/pgsScanner.ll" +{ return token::PGS_AE_OP; } + YY_BREAK +case 45: +YY_RULE_SETUP +#line 146 "pgscript/pgsScanner.ll" +{ return token::PGS_NE_OP; } + YY_BREAK +case 46: +YY_RULE_SETUP +#line 147 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, ';'); } + YY_BREAK +case 47: +YY_RULE_SETUP +#line 148 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, '{'); } + YY_BREAK +case 48: +YY_RULE_SETUP +#line 149 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, '}'); } + YY_BREAK +case 49: +YY_RULE_SETUP +#line 150 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, ':'); } + YY_BREAK +case 50: +YY_RULE_SETUP +#line 151 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, '('); } + YY_BREAK +case 51: +YY_RULE_SETUP +#line 152 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, ')'); } + YY_BREAK +case 52: +YY_RULE_SETUP +#line 153 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, '['); } + YY_BREAK +case 53: +YY_RULE_SETUP +#line 154 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, ']'); } + YY_BREAK +case 54: +YY_RULE_SETUP +#line 155 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, '.'); } + YY_BREAK +case 55: +YY_RULE_SETUP +#line 156 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, ','); } + YY_BREAK +case 56: +YY_RULE_SETUP +#line 157 "pgscript/pgsScanner.ll" +{ return token::PGS_NOT_OP; } + YY_BREAK +case 57: +YY_RULE_SETUP +#line 158 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, '-'); } + YY_BREAK +case 58: +YY_RULE_SETUP +#line 159 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, '+'); } + YY_BREAK +case 59: +YY_RULE_SETUP +#line 160 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, '*'); } + YY_BREAK +case 60: +YY_RULE_SETUP +#line 161 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, '/'); } + YY_BREAK +case 61: +YY_RULE_SETUP +#line 162 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, '%'); } + YY_BREAK +case 62: +YY_RULE_SETUP +#line 163 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, '<'); } + YY_BREAK +case 63: +YY_RULE_SETUP +#line 164 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, '>'); } + YY_BREAK +case 64: +YY_RULE_SETUP +#line 166 "pgscript/pgsScanner.ll" +{ string_caller = INITIAL; BEGIN(SC_STRING); } + YY_BREAK +case 65: +YY_RULE_SETUP +#line 168 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_ABORT; + BEGIN(SC_QUERY); } + YY_BREAK +case 66: +YY_RULE_SETUP +#line 170 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_ALTER; + BEGIN(SC_QUERY); } + YY_BREAK +case 67: +YY_RULE_SETUP +#line 172 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_ANALYZE; + BEGIN(SC_QUERY); } + YY_BREAK +case 68: +YY_RULE_SETUP +#line 174 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_BEGIN; + BEGIN(SC_QUERY); } + YY_BREAK +case 69: +YY_RULE_SETUP +#line 176 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_BEGIN; + BEGIN(SC_QUERY); } + YY_BREAK +case 70: +YY_RULE_SETUP +#line 178 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_CHECKPOINT; + BEGIN(SC_QUERY); } + YY_BREAK +case 71: +YY_RULE_SETUP +#line 180 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_CLOSE_ST; + BEGIN(SC_QUERY); } + YY_BREAK +case 72: +YY_RULE_SETUP +#line 182 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_CLUSTER; + BEGIN(SC_QUERY); } + YY_BREAK +case 73: +YY_RULE_SETUP +#line 184 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_COMMENT; + BEGIN(SC_QUERY); } + YY_BREAK +case 74: +YY_RULE_SETUP +#line 186 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_COMMIT; + BEGIN(SC_QUERY); } + YY_BREAK +case 75: +YY_RULE_SETUP +#line 188 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_COPY; + BEGIN(SC_QUERY); } + YY_BREAK +case 76: +YY_RULE_SETUP +#line 190 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_CREATE; + BEGIN(SC_QUERY); } + YY_BREAK +case 77: +YY_RULE_SETUP +#line 192 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_DEALLOCATE; + BEGIN(SC_QUERY); } + YY_BREAK +case 78: +YY_RULE_SETUP +#line 194 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_DECLARE; + BEGIN(SC_QUERY); } + YY_BREAK +case 79: +YY_RULE_SETUP +#line 196 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_DELETE; + BEGIN(SC_QUERY); } + YY_BREAK +case 80: +YY_RULE_SETUP +#line 198 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_DISCARD; + BEGIN(SC_QUERY); } + YY_BREAK +case 81: +YY_RULE_SETUP +#line 200 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_DROP; + BEGIN(SC_QUERY); } + YY_BREAK +case 82: +YY_RULE_SETUP +#line 202 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_END_ST; + BEGIN(SC_QUERY); } + YY_BREAK +case 83: +YY_RULE_SETUP +#line 204 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_END_ST; + BEGIN(SC_QUERY); } + YY_BREAK +case 84: +YY_RULE_SETUP +#line 206 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_EXECUTE; + BEGIN(SC_QUERY); } + YY_BREAK +case 85: +YY_RULE_SETUP +#line 208 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_EXPLAIN; + BEGIN(SC_QUERY); } + YY_BREAK +case 86: +YY_RULE_SETUP +#line 210 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_FETCH; + BEGIN(SC_QUERY); } + YY_BREAK +case 87: +YY_RULE_SETUP +#line 212 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_GRANT; + BEGIN(SC_QUERY); } + YY_BREAK +case 88: +YY_RULE_SETUP +#line 214 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_INSERT; + BEGIN(SC_QUERY); } + YY_BREAK +case 89: +YY_RULE_SETUP +#line 216 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_LISTEN; + BEGIN(SC_QUERY); } + YY_BREAK +case 90: +YY_RULE_SETUP +#line 218 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_LOAD; + BEGIN(SC_QUERY); } + YY_BREAK +case 91: +YY_RULE_SETUP +#line 220 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_LOCK; + BEGIN(SC_QUERY); } + YY_BREAK +case 92: +YY_RULE_SETUP +#line 222 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_MOVE; + BEGIN(SC_QUERY); } + YY_BREAK +case 93: +YY_RULE_SETUP +#line 224 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_NOTIFY; + BEGIN(SC_QUERY); } + YY_BREAK +case 94: +YY_RULE_SETUP +#line 226 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_PREPARE; + BEGIN(SC_QUERY); } + YY_BREAK +case 95: +YY_RULE_SETUP +#line 228 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_REASSIGN; + BEGIN(SC_QUERY); } + YY_BREAK +case 96: +YY_RULE_SETUP +#line 230 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_REINDEX; + BEGIN(SC_QUERY); } + YY_BREAK +case 97: +YY_RULE_SETUP +#line 232 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_RELEASE; + BEGIN(SC_QUERY); } + YY_BREAK +case 98: +YY_RULE_SETUP +#line 234 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_RESET; + BEGIN(SC_QUERY); } + YY_BREAK +case 99: +YY_RULE_SETUP +#line 236 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_REVOKE; + BEGIN(SC_QUERY); } + YY_BREAK +case 100: +YY_RULE_SETUP +#line 238 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_ROLLBACK; + BEGIN(SC_QUERY); } + YY_BREAK +case 101: +YY_RULE_SETUP +#line 240 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_SAVEPOINT; + BEGIN(SC_QUERY); } + YY_BREAK +case 102: +YY_RULE_SETUP +#line 242 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_SELECT; + BEGIN(SC_QUERY); } + YY_BREAK +case 103: +YY_RULE_SETUP +#line 244 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_SET; + BEGIN(SC_QUERY); } + YY_BREAK +case 104: +YY_RULE_SETUP +#line 246 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_SHOW; + BEGIN(SC_QUERY); } + YY_BREAK +case 105: +YY_RULE_SETUP +#line 248 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_START; + BEGIN(SC_QUERY); } + YY_BREAK +case 106: +YY_RULE_SETUP +#line 250 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_TRUNCATE; + BEGIN(SC_QUERY); } + YY_BREAK +case 107: +YY_RULE_SETUP +#line 252 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_UNLISTEN; + BEGIN(SC_QUERY); } + YY_BREAK +case 108: +YY_RULE_SETUP +#line 254 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_UPDATE; + BEGIN(SC_QUERY); } + YY_BREAK +case 109: +YY_RULE_SETUP +#line 256 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_VACUUM; + BEGIN(SC_QUERY); } + YY_BREAK +case 110: +YY_RULE_SETUP +#line 258 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_VALUES; + BEGIN(SC_QUERY); } + YY_BREAK +case 111: +YY_RULE_SETUP +#line 261 "pgscript/pgsScanner.ll" +{ } + YY_BREAK +case 112: +YY_RULE_SETUP +#line 262 "pgscript/pgsScanner.ll" +{ yylloc->step(); } + YY_BREAK +case 113: +/* rule 113 can match eol */ +YY_RULE_SETUP +#line 263 "pgscript/pgsScanner.ll" +{ yylloc->lines(yyleng); yylloc->step(); } + YY_BREAK +case 114: +YY_RULE_SETUP +#line 264 "pgscript/pgsScanner.ll" +{ return token::PGS_UNKNOWN; } + YY_BREAK + + +case 115: +YY_RULE_SETUP +#line 268 "pgscript/pgsScanner.ll" +{ query += yytext; string_caller = SC_QUERY; BEGIN(SC_STRING); } + YY_BREAK +case 116: +YY_RULE_SETUP +#line 269 "pgscript/pgsScanner.ll" +{ query += yytext; dollar = yytext; BEGIN(SC_DOLLAR); } + YY_BREAK +case 117: +YY_RULE_SETUP +#line 270 "pgscript/pgsScanner.ll" +{ yylval->str = pnew wxString(query.c_str(), m_conv); + query.clear(); unput(';'); yylloc->end.columns(-1); + BEGIN(INITIAL); m_parent = 0; return query_token; } + YY_BREAK +case 118: +YY_RULE_SETUP +#line 273 "pgscript/pgsScanner.ll" +{ ++m_parent; query += yytext; } + YY_BREAK +case 119: +YY_RULE_SETUP +#line 274 "pgscript/pgsScanner.ll" +{ + --m_parent; + if (m_parent == -1) + { + yylval->str = pnew wxString(query.c_str(), m_conv); + query.clear(); unput(')'); yylloc->end.columns(-1); + BEGIN(INITIAL); m_parent = 0; return query_token; + } + else + { + query += yytext; + } + } + YY_BREAK +case 120: +YY_RULE_SETUP +#line 287 "pgscript/pgsScanner.ll" +{ query += yytext; yylloc->step(); } + YY_BREAK +case 121: +/* rule 121 can match eol */ +YY_RULE_SETUP +#line 288 "pgscript/pgsScanner.ll" +{ query += yytext; yylloc->lines(yyleng); yylloc->step(); } + YY_BREAK +case YY_STATE_EOF(SC_QUERY): +#line 289 "pgscript/pgsScanner.ll" +{ yylval->str = pnew wxString(query.c_str(), m_conv); + query.clear(); m_parent = 0; return query_token; } + YY_BREAK +case 122: +YY_RULE_SETUP +#line 291 "pgscript/pgsScanner.ll" +{ yylloc->columns(columns(*yytext)); query += yytext; } + YY_BREAK + + +case 123: +YY_RULE_SETUP +#line 295 "pgscript/pgsScanner.ll" +{ query += yytext; + if (std::string(yytext) == dollar) BEGIN(SC_QUERY); } + YY_BREAK +case 124: +YY_RULE_SETUP +#line 297 "pgscript/pgsScanner.ll" +{ query += yytext; yylloc->step(); } + YY_BREAK +case 125: +/* rule 125 can match eol */ +YY_RULE_SETUP +#line 298 "pgscript/pgsScanner.ll" +{ query += yytext; yylloc->lines(yyleng); yylloc->step(); } + YY_BREAK +case YY_STATE_EOF(SC_DOLLAR): +#line 299 "pgscript/pgsScanner.ll" +{ query += yytext; yylval->str = pnew wxString(query.c_str(), m_conv); + query.clear(); m_parent = 0; return query_token; } + YY_BREAK +case 126: +YY_RULE_SETUP +#line 301 "pgscript/pgsScanner.ll" +{ yylloc->columns(columns(*yytext)); query += yytext; } + YY_BREAK + + +case 127: +YY_RULE_SETUP +#line 305 "pgscript/pgsScanner.ll" +{ BEGIN(comment_caller); } + YY_BREAK +case 128: +YY_RULE_SETUP +#line 306 "pgscript/pgsScanner.ll" +{ yylloc->step(); } + YY_BREAK +case 129: +/* rule 129 can match eol */ +YY_RULE_SETUP +#line 307 "pgscript/pgsScanner.ll" +{ yylloc->lines(yyleng); yylloc->step(); } + YY_BREAK +case 130: +YY_RULE_SETUP +#line 308 "pgscript/pgsScanner.ll" +{ yylloc->columns(columns(*yytext)); } + YY_BREAK + + +case 131: +YY_RULE_SETUP +#line 312 "pgscript/pgsScanner.ll" +{ + if (string_caller == SC_QUERY) + query += yytext; + else + str += "'"; + } + YY_BREAK +case 132: +YY_RULE_SETUP +#line 318 "pgscript/pgsScanner.ll" +{ + if (string_caller == SC_QUERY) + query += yytext; + else + str += *(yytext + 1); + yylloc->columns(columns(*(yytext + 1))); + } + YY_BREAK +case 133: +YY_RULE_SETUP +#line 325 "pgscript/pgsScanner.ll" +{ + if (string_caller == SC_QUERY) + { + query += yytext; + BEGIN(string_caller); + } + else + { + yylval->str = pnew wxString(str.c_str(), m_conv); + str.clear(); + BEGIN(string_caller); + return token::PGS_VAL_STR; + } + } + YY_BREAK +case 134: +YY_RULE_SETUP +#line 339 "pgscript/pgsScanner.ll" +{ + if (string_caller == SC_QUERY) + query += yytext; + else + str += yytext; + yylloc->step(); + } + YY_BREAK +case 135: +/* rule 135 can match eol */ +YY_RULE_SETUP +#line 346 "pgscript/pgsScanner.ll" +{ + if (string_caller == SC_QUERY) + query += yytext; + else + str += yytext; + yylloc->lines(yyleng); yylloc->step(); + } + YY_BREAK +case YY_STATE_EOF(SC_STRING): +#line 353 "pgscript/pgsScanner.ll" +{ + if (string_caller == SC_QUERY) + { + query += yytext; yylval->str = pnew wxString(query.c_str(), m_conv); + query.clear(); m_parent = 0; return query_token; + } + else + { + yylval->str = pnew wxString(str.c_str(), m_conv); + str.clear(); + BEGIN(string_caller); + return token::PGS_VAL_STR; + } + } + YY_BREAK +case 136: +YY_RULE_SETUP +#line 367 "pgscript/pgsScanner.ll" +{ + if (string_caller == SC_QUERY) + query += yytext; + else + str += yytext; + yylloc->columns(columns(*yytext)); + } + YY_BREAK + +case 137: +YY_RULE_SETUP +#line 376 "pgscript/pgsScanner.ll" +ECHO; + YY_BREAK +#line 1764 "pgscript/lex.pgs.cc" +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(SC_COMMENT): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of yylex */ + +yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout ) +{ + yyin = arg_yyin; + yyout = arg_yyout; + yy_c_buf_p = 0; + yy_init = 0; + yy_start = 0; + yy_flex_debug = 0; + yylineno = 1; // this will only get updated if %option yylineno + + yy_did_buffer_switch_on_eof = 0; + + yy_looking_for_trail_begin = 0; + yy_more_flag = 0; + yy_more_len = 0; + yy_more_offset = yy_prev_more_offset = 0; + + yy_start_stack_ptr = yy_start_stack_depth = 0; + yy_start_stack = NULL; + + (yy_buffer_stack) = 0; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + + yy_state_buf = 0; + +} + +yyFlexLexer::~yyFlexLexer() +{ + delete [] yy_state_buf; + pgsfree(yy_start_stack ); + yy_delete_buffer( YY_CURRENT_BUFFER ); +} + +void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out ) +{ + if ( new_in ) + { + yy_delete_buffer( YY_CURRENT_BUFFER ); + yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE ) ); + } + + if ( new_out ) + yyout = new_out; +} + +#ifdef YY_INTERACTIVE +int yyFlexLexer::LexerInput( char* buf, int /* max_size */ ) +#else +int yyFlexLexer::LexerInput( char* buf, int max_size ) +#endif +{ + if ( yyin->eof() || yyin->fail() ) + return 0; + +#ifdef YY_INTERACTIVE + yyin->get( buf[0] ); + + if ( yyin->eof() ) + return 0; + + if ( yyin->bad() ) + return -1; + + return 1; + +#else + (void) yyin->read( buf, max_size ); + + if ( yyin->bad() ) + return -1; + else + return yyin->gcount(); +#endif +} + +void yyFlexLexer::LexerOutput( const char* buf, int size ) +{ + (void) yyout->write( buf, size ); +} + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +int yyFlexLexer::yy_get_next_buffer() +{ + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = (yytext_ptr); + register int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + pgsrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + yy_state_type yyFlexLexer::yy_get_previous_state() +{ + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 444 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state ) +{ + register int yy_is_jam; + register char *yy_cp = (yy_c_buf_p); + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 444 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 443); + + return yy_is_jam ? 0 : yy_current_state; +} + + void yyFlexLexer::yyunput( int c, register char* yy_bp) +{ + register char *yy_cp; + + yy_cp = (yy_c_buf_p); + + /* undo effects of setting up yytext */ + *yy_cp = (yy_hold_char); + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = (yy_n_chars) + 2; + register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + register char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; +} + + int yyFlexLexer::yyinput() +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + int offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return EOF; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyFlexLexer::yyrestart( std::istream* input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_init_buffer( YY_CURRENT_BUFFER, input_file ); + yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + + void yyFlexLexer::yy_load_buffer_state() +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) pgsalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) pgsalloc(b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ + void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + pgsfree((void *) b->yy_ch_buf ); + + pgsfree((void *) b ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file ) + +{ + int oerrno = errno; + + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = 0; + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yyFlexLexer::yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +void yyFlexLexer::yyensure_buffer_stack(void) +{ + int num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state**)pgsalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)pgsrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + + void yyFlexLexer::yy_push_state( int new_state ) +{ + if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) ) + { + yy_size_t new_size; + + (yy_start_stack_depth) += YY_START_STACK_INCR; + new_size = (yy_start_stack_depth) * sizeof( int ); + + if ( ! (yy_start_stack) ) + (yy_start_stack) = (int *) pgsalloc(new_size ); + + else + (yy_start_stack) = (int *) pgsrealloc((void *) (yy_start_stack),new_size ); + + if ( ! (yy_start_stack) ) + YY_FATAL_ERROR( + "out of memory expanding start-condition stack" ); + } + + (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START; + + BEGIN(new_state); +} + + void yyFlexLexer::yy_pop_state() +{ + if ( --(yy_start_stack_ptr) < 0 ) + YY_FATAL_ERROR( "start-condition stack underflow" ); + + BEGIN((yy_start_stack)[(yy_start_stack_ptr)]); +} + + int yyFlexLexer::yy_top_state() +{ + return (yy_start_stack)[(yy_start_stack_ptr) - 1]; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +void yyFlexLexer::LexerError( yyconst char msg[] ) +{ + std::cerr << msg << std::endl; + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s ) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *pgsalloc (yy_size_t size ) +{ + return (void *) malloc( size ); +} + +void *pgsrealloc (void * ptr, yy_size_t size ) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void pgsfree (void * ptr ) +{ + free( (char *) ptr ); /* see pgsrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 376 "pgscript/pgsScanner.ll" + + + +namespace pgscript +{ + +pgsScanner::pgsScanner(wxMBConv & conv, std::istream * in, std::ostream * out) : + pgsFlexLexer(in, out), m_parent(0), m_conv(conv) +{ + +} + +pgsScanner::~pgsScanner() +{ + +} + +void pgsScanner::set_debug(bool b) +{ + yy_flex_debug = b; +} + +int pgsScanner::columns(const char & c) +{ + if ((c & 0xF0) == 0xF0) // 4 bytes + return -3; + else if ((c & 0xE0) == 0xE0) // 3 bytes + return -2; + else if ((c & 0xC0) == 0xC0) // 2 bytes + return -1; + else return 0; +} + +} + +/* This implementation of pgsFlexLexer::yylex() is required to fill the + * vtable of the class pgsFlexLexer. We define the scanner's main yylex + * function via YY_DECL to reside in the pgsScanner class instead. */ + +#ifdef yylex +#undef yylex +#endif + +int pgsFlexLexer::yylex() +{ + return 0; +} + diff --git a/pgscript/module.mk b/pgscript/module.mk new file mode 100644 index 0000000..6c1ebcb --- /dev/null +++ b/pgscript/module.mk @@ -0,0 +1,29 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/pgscript/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + pgscript/pgsApplication.cpp \ + pgscript/lex.pgs.cc \ + pgscript/parser.tab.cc + +EXTRA_DIST += \ + pgscript/module.mk \ + pgscript/parser.sh \ + pgscript/pgsParser.yy \ + pgscript/pgsScanner.ll \ + pgscript/README + +include pgscript/exceptions/module.mk +include pgscript/expressions/module.mk +include pgscript/generators/module.mk +include pgscript/objects/module.mk +include pgscript/statements/module.mk +include pgscript/utilities/module.mk diff --git a/pgscript/objects/module.mk b/pgscript/objects/module.mk new file mode 100644 index 0000000..bea2f2b --- /dev/null +++ b/pgscript/objects/module.mk @@ -0,0 +1,21 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/pgscript/objects/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + pgscript/objects/pgsGenerator.cpp \ + pgscript/objects/pgsNumber.cpp \ + pgscript/objects/pgsRecord.cpp \ + pgscript/objects/pgsString.cpp \ + pgscript/objects/pgsVariable.cpp + +EXTRA_DIST += \ + pgscript/objects/module.mk + diff --git a/pgscript/objects/pgsGenerator.cpp b/pgscript/objects/pgsGenerator.cpp new file mode 100644 index 0000000..8f4eaaf --- /dev/null +++ b/pgscript/objects/pgsGenerator.cpp @@ -0,0 +1,154 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/objects/pgsGenerator.h" + +#include "pgscript/objects/pgsNumber.h" +#include "pgscript/objects/pgsRecord.h" +#include "pgscript/objects/pgsString.h" +#include "pgscript/exceptions/pgsCastException.h" + +pgsGenerator::pgsGenerator(const pgsTypes &generator_type, + pgsObjectGen *randomizer) : + pgsVariable(generator_type), m_randomizer(randomizer) +{ + +} + +pgsGenerator::~pgsGenerator() +{ + +} + +pgsVariable *pgsGenerator::clone() const +{ + return pnew pgsGenerator(*this); +} + +wxString pgsGenerator::value() const +{ + return m_randomizer->random(); +} + +pgsOperand pgsGenerator::operand() const +{ + switch (type()) + { + case pgsTInt: + return pnew pgsNumber(value(), pgsInt); + case pgsTReal: + return pnew pgsNumber(value(), pgsReal); + default: + return pnew pgsString(value()); + } +} + +pgsOperand pgsGenerator::eval(pgsVarMap &vars) const +{ + return this->clone(); +} + +pgsOperand pgsGenerator::pgs_plus(const pgsVariable &rhs) const +{ + return *operand() + rhs; +} + +pgsOperand pgsGenerator::pgs_minus(const pgsVariable &rhs) const +{ + return *operand() - rhs; +} + +pgsOperand pgsGenerator::pgs_times(const pgsVariable &rhs) const +{ + return *operand() * rhs; +} + +pgsOperand pgsGenerator::pgs_over(const pgsVariable &rhs) const +{ + return *operand() / rhs; +} + +pgsOperand pgsGenerator::pgs_modulo(const pgsVariable &rhs) const +{ + return *operand() % rhs; +} + +pgsOperand pgsGenerator::pgs_equal(const pgsVariable &rhs) const +{ + return *operand() == rhs; +} + +pgsOperand pgsGenerator::pgs_different(const pgsVariable &rhs) const +{ + return *operand() != rhs; +} + +pgsOperand pgsGenerator::pgs_greater(const pgsVariable &rhs) const +{ + return *operand() > rhs; +} + +pgsOperand pgsGenerator::pgs_lower(const pgsVariable &rhs) const +{ + return *operand() < rhs; +} + +pgsOperand pgsGenerator::pgs_lower_equal(const pgsVariable &rhs) const +{ + return *operand() <= rhs; +} + +pgsOperand pgsGenerator::pgs_greater_equal(const pgsVariable &rhs) const +{ + return *operand() >= rhs; +} + +pgsOperand pgsGenerator::pgs_not() const +{ + return !(*operand()); +} + +bool pgsGenerator::pgs_is_true() const +{ + return operand()->pgs_is_true(); +} + +pgsOperand pgsGenerator::pgs_almost_equal(const pgsVariable &rhs) const +{ + return *operand() &= rhs; +} + +pgsNumber pgsGenerator::number() const +{ + wxString data = value().Strip(wxString::both); + pgsTypes type = pgsNumber::num_type(data); + switch (type) + { + case pgsTInt: + return pgsNumber(data, pgsInt); + case pgsTReal: + return pgsNumber(data, pgsReal); + default: + throw pgsCastException(data, wxT("number")); + } +} + +pgsRecord pgsGenerator::record() const +{ + pgsRecord rec(1); + rec.insert(0, 0, operand()); + return rec; +} + +pgsString pgsGenerator::string() const +{ + return pgsString(value()); +} diff --git a/pgscript/objects/pgsNumber.cpp b/pgscript/objects/pgsNumber.cpp new file mode 100644 index 0000000..3ab6e00 --- /dev/null +++ b/pgscript/objects/pgsNumber.cpp @@ -0,0 +1,286 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/objects/pgsNumber.h" + +#include +#include "pgscript/objects/pgsRecord.h" +#include "pgscript/objects/pgsString.h" +#include "pgscript/exceptions/pgsArithmeticException.h" +#include "pgscript/exceptions/pgsCastException.h" + +#define PGS_INTEGER_FORM_1 wxT("^[+-]?[0-9]+$") +#define PGS_REAL_FORM_1 wxT("^[+-]?[0-9]+[Ee][+-]?[0-9]+$") +#define PGS_REAL_FORM_2 wxT("^[+-]?[0-9]*[.][0-9]+([Ee][+-]?[0-9]+)?$") +#define PGS_REAL_FORM_3 wxT("^[+-]?[0-9]+[.][0-9]*([Ee][+-]?[0-9]+)?$") + +pgsNumber::pgsNumber(const wxString &data, const bool &is_real) : + pgsVariable(!is_real ? pgsVariable::pgsTInt : pgsVariable::pgsTReal), + m_data(data.Strip(wxString::both)) +{ + wxASSERT(is_valid()); +} + +bool pgsNumber::is_valid() const +{ + pgsTypes type = num_type(m_data); + return (type == pgsTInt) || (type == pgsTReal && is_real()); +} + +pgsNumber::~pgsNumber() +{ + +} + +pgsNumber::pgsNumber(const pgsNumber &that) : + pgsVariable(that), m_data(that.m_data) +{ + wxASSERT(is_valid()); +} + +pgsNumber &pgsNumber::operator =(const pgsNumber &that) +{ + if (this != &that) + { + pgsVariable::operator=(that); + m_data = that.m_data; + } + + wxASSERT(is_valid()); + + return (*this); +} + +pgsVariable *pgsNumber::clone() const +{ + return pnew pgsNumber(*this); +} + +wxString pgsNumber::value() const +{ + return m_data; +} + +pgsOperand pgsNumber::eval(pgsVarMap &vars) const +{ + return this->clone(); +} + +pgsVariable::pgsTypes pgsNumber::num_type(const wxString &num) +{ + if (wxRegEx(PGS_INTEGER_FORM_1).Matches(num)) + { + return pgsTInt; + } + else if (( wxRegEx(PGS_REAL_FORM_1).Matches(num) + || wxRegEx(PGS_REAL_FORM_2).Matches(num) + || wxRegEx(PGS_REAL_FORM_3).Matches(num))) + { + return pgsTReal; + } + else + { + return pgsTString; + } +} + +pgsOperand pgsNumber::pgs_plus(const pgsVariable &rhs) const +{ + if (rhs.is_number()) + { + return pnew pgsNumber(pgsMapm::pgs_mapm_str(num(m_data) + + num(rhs.value())), is_real() || rhs.is_real()); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsNumber::pgs_minus(const pgsVariable &rhs) const +{ + if (rhs.is_number()) + { + return pnew pgsNumber(pgsMapm::pgs_mapm_str(num(m_data) + - num(rhs.value())), is_real() || rhs.is_real()); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsNumber::pgs_times(const pgsVariable &rhs) const +{ + if (rhs.is_number()) + { + return pnew pgsNumber(pgsMapm::pgs_mapm_str(num(m_data) + * num(rhs.value())), is_real() || rhs.is_real()); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsNumber::pgs_over(const pgsVariable &rhs) const +{ + if (rhs.is_number()) + { + if (num(rhs.value()) != 0) + { + if (is_real() || rhs.is_real()) + return pnew pgsNumber(pgsMapm::pgs_mapm_str(num(m_data) + / num(rhs.value())), is_real() || rhs.is_real()); + else + return pnew pgsNumber(pgsMapm::pgs_mapm_str(num(m_data) + .div(num(rhs.value()))), is_real() || rhs.is_real()); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsNumber::pgs_modulo(const pgsVariable &rhs) const +{ + if (rhs.is_number()) + { + if (num(rhs.value()) != 0) + { + return pnew pgsNumber(pgsMapm::pgs_mapm_str(num(m_data) + % num(rhs.value())), is_real() || rhs.is_real()); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsNumber::pgs_equal(const pgsVariable &rhs) const +{ + if (rhs.is_number()) + { + return pnew pgsNumber(num(m_data) == num(rhs.value()) + ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsNumber::pgs_different(const pgsVariable &rhs) const +{ + if (rhs.is_number()) + { + return pnew pgsNumber(num(m_data) != num(rhs.value()) + ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsNumber::pgs_greater(const pgsVariable &rhs) const +{ + if (rhs.is_number()) + { + return pnew pgsNumber(num(m_data) > num(rhs.value()) + ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsNumber::pgs_lower(const pgsVariable &rhs) const +{ + if (rhs.is_number()) + { + return pnew pgsNumber(num(m_data) < num(rhs.value()) + ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsNumber::pgs_lower_equal(const pgsVariable &rhs) const +{ + if (rhs.is_number()) + { + return pnew pgsNumber(num(m_data) <= num(rhs.value()) + ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsNumber::pgs_greater_equal(const pgsVariable &rhs) const +{ + if (rhs.is_number()) + { + return pnew pgsNumber(num(m_data) >= num(rhs.value()) + ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsNumber::pgs_not() const +{ + return pnew pgsNumber(num(m_data) == 0 ? wxT("1") : wxT("0")); +} + +bool pgsNumber::pgs_is_true() const +{ + return (num(m_data) != 0 ? true : false); +} + +pgsOperand pgsNumber::pgs_almost_equal(const pgsVariable &rhs) const +{ + return pgs_equal(rhs); +} + +pgsNumber pgsNumber::number() const +{ + return pgsNumber(*this); +} + +pgsRecord pgsNumber::record() const +{ + pgsRecord rec(1);; + rec.insert(0, 0, this->clone()); + return rec; +} + +pgsString pgsNumber::string() const +{ + return pgsString(m_data); +} diff --git a/pgscript/objects/pgsRecord.cpp b/pgscript/objects/pgsRecord.cpp new file mode 100644 index 0000000..5815923 --- /dev/null +++ b/pgscript/objects/pgsRecord.cpp @@ -0,0 +1,509 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/objects/pgsRecord.h" + +#include "pgscript/expressions/pgsEqual.h" +#include "pgscript/objects/pgsNumber.h" +#include "pgscript/objects/pgsString.h" +#include "pgscript/exceptions/pgsArithmeticException.h" +#include "pgscript/exceptions/pgsCastException.h" + +#include + +WX_DEFINE_OBJARRAY(pgsVectorRecordLine); +WX_DEFINE_OBJARRAY(pgsVectorRecord); + +pgsRecord::pgsRecord(const USHORT &nb_columns) : + pgsVariable(pgsVariable::pgsTRecord) +{ + m_columns.SetCount(nb_columns); +} + +pgsRecord::~pgsRecord() +{ + +} + +pgsVariable *pgsRecord::clone() const +{ + return pnew pgsRecord(*this); +} + +wxString pgsRecord::value() const +{ + wxString data; + pgsVarMap vars; + + // Go through each line and enclose it into braces + for (USHORT i = 0; i < count_lines(); i++) + { + data += wxT("("); + + // Go through each column and separate them with commas + for (USHORT j = 0; j < count_columns(); j++) + { + wxString elm(m_record[i][j]->eval(vars)->value()); + if (!m_record[i][j]->is_number()) + { + elm.Replace(wxT("\\"), wxT("\\\\")); + elm.Replace(wxT("\""), wxT("\\\"")); + elm = wxT("\"") + elm + wxT("\""); + } + data += elm + (j != count_columns() - 1 ? wxT(",") : wxT("")); + } + + data += (i == count_lines() - 1) ? wxT(")") : wxT(")\n"); + } + + // Return the string representation of the record + return data; +} + +pgsOperand pgsRecord::eval(pgsVarMap &vars) const +{ + return this->clone(); +} + +USHORT pgsRecord::count_lines() const +{ + return m_record.GetCount(); +} + +USHORT pgsRecord::count_columns() const +{ + return m_columns.GetCount(); +} + +bool pgsRecord::insert(const USHORT &line, const USHORT &column, + pgsOperand value) +{ + // Add lines to match the line number provided + for (USHORT i = count_lines(); i <= line; i++) + { + newline(); + } + + // Cannot insert if column is invalid + if (column >= count_columns()) + { + return false; + } + // Insert the value at line.column + else + { + m_record[line][column] = value; + return true; + } +} + +pgsOperand pgsRecord::get(const USHORT &line, + const USHORT &column) const +{ + if (line < count_lines() && column < count_columns()) + { + return m_record[line][column]; + } + else + { + return pnew pgsString(wxT("")); + } +} + +pgsOperand pgsRecord::get_line(const USHORT &line) const +{ + if (line < count_lines()) + { + pgsRecord *rec = pnew pgsRecord(count_columns()); + rec->m_columns = this->m_columns; + rec->newline(); + rec->m_record[0] = this->m_record[line]; + return rec; + } + else + { + return pnew pgsRecord(0); + } +} + +bool pgsRecord::set_column_name(const USHORT &column, wxString name) +{ + // Column number must be valid + if (column >= count_columns()) + { + return false; + } + + // Column name must not exist + // Column name must not be empty + name = name.Strip(wxString::both).Lower(); + if (m_columns.Index(name) != wxNOT_FOUND || name.IsEmpty()) + { + return false; + } + + // Set the column name + m_columns[column] = name; + + return true; +} + +USHORT pgsRecord::get_column(wxString name) const +{ + name = name.Strip(wxString::both).Lower(); + if (name.IsEmpty()) + { + return count_columns(); + } + for (USHORT i = 0; i < count_columns(); i++) + { + if (m_columns[i] == name) + return i; + } + return count_columns(); +} + +bool pgsRecord::remove_line(const USHORT &line) +{ + if (line < count_lines()) + { + m_record.RemoveAt(line); + return true; + } + return false; +} + +bool pgsRecord::newline() +{ + // Insert a line + m_record.Add(pgsVectorRecordLine()); + // Initialize each column of the line with an empty string + for (USHORT i = 0; i < count_columns(); i++) + { + m_record.Last().Add(pnew pgsString(wxT(""))); + } + return true; +} + +bool pgsRecord::valid() const +{ + return true; +} + +bool pgsRecord::operator==(const pgsRecord &rhs) const +{ + // Test the number of lines + if (this->count_lines() != rhs.count_lines()) + { + return false; + } + + return records_equal(*this, rhs, true); +} + +bool pgsRecord::operator!=(const pgsRecord &rhs) const +{ + return !(*this == rhs); +} + +bool pgsRecord::operator<(const pgsRecord &rhs) const +{ + // Test the number of lines + if (this->count_lines() >= rhs.count_lines()) + { + return false; + } + + return records_equal(*this, rhs, true); +} + +bool pgsRecord::operator>(const pgsRecord &rhs) const +{ + return (rhs < *this); +} + +bool pgsRecord::operator<=(const pgsRecord &rhs) const +{ + // Test the number of lines + if (this->count_lines() > rhs.count_lines()) + { + return false; + } + + return records_equal(*this, rhs, true); +} + +bool pgsRecord::operator>=(const pgsRecord &rhs) const +{ + return (rhs <= *this); +} + +bool pgsRecord::almost_equal(const pgsRecord &rhs) const +{ + // Test the number of lines + if (this->count_lines() != rhs.count_lines()) + { + return false; + } + + return records_equal(*this, rhs, false); +} + +bool pgsRecord::records_equal(const pgsRecord &lhs, const pgsRecord &rhs, + bool case_sensitive) const +{ + // Test the number of columns + if (lhs.count_columns() != rhs.count_columns()) + { + return false; + } + + // Test each line + wxArrayInt seen; + for (USHORT i = 0; i < lhs.count_lines(); i++) + { + bool result = false; + + // Test if the line of lhs matches with an unseen line of rhs + for (USHORT j = 0; result == false && j < rhs.count_lines(); j++) + { + int k = wx_static_cast(int, j); + if (seen.Index(k) == wxNOT_FOUND + && lines_equal(lhs.m_record[i], rhs.m_record[j], + case_sensitive)) + { + result = true; + seen.push_back(k); + } + else + { + // This is not OK... Continue with the next element + continue; + } + } + + if (result == false) + { + return false; + } + else + { + continue; + } + } + + return true; // End of the test +} + +bool pgsRecord::lines_equal(const pgsVectorRecordLine &lhs, + const pgsVectorRecordLine &rhs, bool case_sensitive) const +{ + pgsVarMap vars; + + // Both lines must have the same number of columns + if (lhs.GetCount() != rhs.GetCount()) + { + return false; + } + + // Test each element (column) of the line + for (USHORT j = 0; j < wx_static_cast(USHORT, lhs.GetCount()); j++) + { + // Test if the two elements are equal + pgsEqual test(lhs[j]->string().clone(), rhs[j]->string().clone(), + case_sensitive); + if (test.eval(vars)->value() == wxT("1")) + { + // lhs == rhs: continue + continue; + } + else + { + // lhs != rhs: lines are not equal + return false; + } + } + + return true; +} + +pgsOperand pgsRecord::pgs_plus(const pgsVariable &rhs) const +{ + throw pgsArithmeticException(value(), rhs.value()); +} + +pgsOperand pgsRecord::pgs_minus(const pgsVariable &rhs) const +{ + throw pgsArithmeticException(value(), rhs.value()); +} + +pgsOperand pgsRecord::pgs_times(const pgsVariable &rhs) const +{ + throw pgsArithmeticException(value(), rhs.value()); +} + +pgsOperand pgsRecord::pgs_over(const pgsVariable &rhs) const +{ + throw pgsArithmeticException(value(), rhs.value()); +} + +pgsOperand pgsRecord::pgs_modulo(const pgsVariable &rhs) const +{ + throw pgsArithmeticException(value(), rhs.value()); +} + +pgsOperand pgsRecord::pgs_equal(const pgsVariable &rhs) const +{ + if (rhs.is_record()) + { + const pgsRecord &rhs_op = dynamic_cast(rhs); + return pnew pgsNumber(*this == rhs_op ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(value(), rhs.value()); + } +} + +pgsOperand pgsRecord::pgs_different(const pgsVariable &rhs) const +{ + if (rhs.is_record()) + { + const pgsRecord &rhs_op = dynamic_cast(rhs); + return pnew pgsNumber(*this != rhs_op ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(value(), rhs.value()); + } +} + +pgsOperand pgsRecord::pgs_greater(const pgsVariable &rhs) const +{ + if (rhs.is_record()) + { + const pgsRecord &rhs_op = dynamic_cast(rhs); + return pnew pgsNumber(*this > rhs_op ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(value(), rhs.value()); + } +} + +pgsOperand pgsRecord::pgs_lower(const pgsVariable &rhs) const +{ + if (rhs.is_record()) + { + const pgsRecord &rhs_op = dynamic_cast(rhs); + return pnew pgsNumber(*this < rhs_op ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(value(), rhs.value()); + } +} + +pgsOperand pgsRecord::pgs_lower_equal(const pgsVariable &rhs) const +{ + if (rhs.is_record()) + { + const pgsRecord &rhs_op = dynamic_cast(rhs); + return pnew pgsNumber(*this <= rhs_op ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(value(), rhs.value()); + } +} + +pgsOperand pgsRecord::pgs_greater_equal(const pgsVariable &rhs) const +{ + if (rhs.is_record()) + { + const pgsRecord &rhs_op = dynamic_cast(rhs); + return pnew pgsNumber(*this >= rhs_op ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(value(), rhs.value()); + } +} + +pgsOperand pgsRecord::pgs_not() const +{ + if (pgs_is_true()) + { + // A record with no line is false + return pnew pgsRecord(count_columns()); + } + else + { + // A record with at least one line is true + pgsRecord *copy = pnew pgsRecord(*this); + copy->newline(); + return copy; // Insert one line and return the record + } +} + +bool pgsRecord::pgs_is_true() const +{ + return (count_lines() > 0 ? true : false); +} + +pgsOperand pgsRecord::pgs_almost_equal(const pgsVariable &rhs) const +{ + if (rhs.is_record()) + { + const pgsRecord &rhs_op = dynamic_cast(rhs); + return pnew pgsNumber(this->almost_equal(rhs_op) ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(value(), rhs.value()); + } +} + +pgsNumber pgsRecord::number() const +{ + wxString data = value().Strip(wxString::both); + + if (data.StartsWith(wxT("("))) + { + data = data.Mid(1); + } + + if (data.EndsWith(wxT(")"))) + { + data = data.Mid(0, data.Len() - 1); + } + + pgsTypes type = pgsNumber::num_type(data); + switch (type) + { + case pgsTInt: + return pgsNumber(data, pgsInt); + case pgsTReal: + return pgsNumber(data, pgsReal); + default: + throw pgsCastException(data, wxT("number")); + } +} + +pgsRecord pgsRecord::record() const +{ + return pgsRecord(*this); +} + +pgsString pgsRecord::string() const +{ + return pgsString(value()); +} diff --git a/pgscript/objects/pgsString.cpp b/pgscript/objects/pgsString.cpp new file mode 100644 index 0000000..a6cde77 --- /dev/null +++ b/pgscript/objects/pgsString.cpp @@ -0,0 +1,290 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/objects/pgsString.h" + +#include +#include "pgscript/objects/pgsNumber.h" +#include "pgscript/objects/pgsRecord.h" +#include "pgscript/exceptions/pgsArithmeticException.h" +#include "pgscript/exceptions/pgsCastException.h" + +pgsString::pgsString(const wxString &data) : + pgsVariable(pgsVariable::pgsTString), m_data(data) +{ + +} + +pgsString::~pgsString() +{ + +} + +pgsVariable *pgsString::clone() const +{ + return pnew pgsString(*this); +} + +wxString pgsString::value() const +{ + return m_data; +} + +pgsOperand pgsString::eval(pgsVarMap &vars) const +{ + return this->clone(); +} + +pgsOperand pgsString::pgs_plus(const pgsVariable &rhs) const +{ + if (rhs.is_string()) + { + return pnew pgsString(m_data + rhs.value()); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsString::pgs_minus(const pgsVariable &rhs) const +{ + throw pgsArithmeticException(m_data, rhs.value()); +} + +pgsOperand pgsString::pgs_times(const pgsVariable &rhs) const +{ + throw pgsArithmeticException(m_data, rhs.value()); +} + +pgsOperand pgsString::pgs_over(const pgsVariable &rhs) const +{ + throw pgsArithmeticException(m_data, rhs.value()); +} + +pgsOperand pgsString::pgs_modulo(const pgsVariable &rhs) const +{ + throw pgsArithmeticException(m_data, rhs.value()); +} + +pgsOperand pgsString::pgs_equal(const pgsVariable &rhs) const +{ + if (rhs.is_string()) + { + return pnew pgsNumber(m_data == rhs.value() ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsString::pgs_different(const pgsVariable &rhs) const +{ + if (rhs.is_string()) + { + return pnew pgsNumber(m_data != rhs.value() ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsString::pgs_greater(const pgsVariable &rhs) const +{ + if (rhs.is_string()) + { + return pnew pgsNumber(m_data > rhs.value() ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsString::pgs_lower(const pgsVariable &rhs) const +{ + if (rhs.is_string()) + { + return pnew pgsNumber(m_data < rhs.value() ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsString::pgs_lower_equal(const pgsVariable &rhs) const +{ + if (rhs.is_string()) + { + return pnew pgsNumber(m_data <= rhs.value() ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsString::pgs_greater_equal(const pgsVariable &rhs) const +{ + if (rhs.is_string()) + { + return pnew pgsNumber(m_data >= rhs.value() ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsString::pgs_not() const +{ + wxString data = m_data.Strip(wxString::both); + return pnew pgsString(data.IsEmpty() ? wxT("1") : wxT("")); +} + +bool pgsString::pgs_is_true() const +{ + wxString data = m_data.Strip(wxString::both); + return (!data.IsEmpty() ? true : false); +} + +pgsOperand pgsString::pgs_almost_equal(const pgsVariable &rhs) const +{ + if (rhs.is_string()) + { + return pnew pgsNumber(m_data.CmpNoCase(rhs.value()) == 0 + ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsNumber pgsString::number() const +{ + wxString data = m_data.Strip(wxString::both); + pgsTypes type = pgsNumber::num_type(data); + switch (type) + { + case pgsTInt: + return pgsNumber(data, pgsInt); + case pgsTReal: + return pgsNumber(data, pgsReal); + default: + throw pgsCastException(data, wxT("number")); + } +} + +pgsRecord pgsString::record() const +{ + pgsRecord *rec = 0; + + // Try to find the representation of a record in the string + { + wxString element(wxT("(\"([^\"\\\\]|\\\\.)*\")|((-|[a-zA-Z0-9\\+\\.])+)")); + wxString data(m_data); + wxRegEx regex1(wxString() << wxT("^[[:space:]]*\\([[:space:]]*(") + << element << wxT(")[[:space:]]*([,][[:space:]]*(") + << element << wxT(")[[:space:]]*)*\\)"), wxRE_DEFAULT | wxRE_ICASE); + + // Find each line + size_t line_nb = 0, nb_of_columns = 0; + bool count_columns = true; + while (regex1.Matches(data)) + { + // Process that line: find each element + wxString line(regex1.GetMatch(data)); + wxRegEx regex2(element); + size_t column_nb = 0; + while (regex2.Matches(line)) + { + if (count_columns == true) + { + ++nb_of_columns; + } + else + { + if (column_nb < nb_of_columns && rec != 0) + { + wxString value(regex2.GetMatch(line)); + if (value.StartsWith(wxT("\"")) + && value.EndsWith(wxT("\""))) + { + // This is a string + value = value.Mid(1, value.Len() - 2); + value.Replace(wxT("\\\""), wxT("\"")); + value.Replace(wxT("\\\\"), wxT("\\")); + rec->insert(line_nb, column_nb, + pnew pgsString(value)); + } + else + { + // This is a number or a string + pgsTypes type = pgsNumber::num_type(value); + switch (type) + { + case pgsTInt: + rec->insert(line_nb, column_nb, + pnew pgsNumber(value, pgsInt)); + break; + case pgsTReal: + rec->insert(line_nb, column_nb, + pnew pgsNumber(value, pgsReal)); + break; + default: + rec->insert(line_nb, column_nb, + pnew pgsString(value)); + break; + } + } + } + ++column_nb; + } + + regex2.ReplaceFirst(&line, wxT("")); + } + + // If it is the first loop we want to process this line a + // second time because the first one was meant to count + // the number of columns + if (count_columns == true) + { + count_columns = false; + rec = pnew pgsRecord(nb_of_columns); + } + else + { + regex1.ReplaceFirst(&data, wxT("")); + ++line_nb; + } + } + } + + // Process the case + if (rec == 0) + { + rec = pnew pgsRecord(1); + rec->insert(0, 0, this->clone()); + } + + pgsRecord ret_val(*rec); + pdelete(rec); + return ret_val; +} + +pgsString pgsString::string() const +{ + return pgsString(*this); +} diff --git a/pgscript/objects/pgsVariable.cpp b/pgscript/objects/pgsVariable.cpp new file mode 100644 index 0000000..1e72f21 --- /dev/null +++ b/pgscript/objects/pgsVariable.cpp @@ -0,0 +1,128 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/objects/pgsVariable.h" + +pgsVariable::pgsVariable(const pgsTypes &type) : + pgsExpression(), m_type(type) +{ + +} + +pgsVariable::~pgsVariable() +{ + +} + +MAPM pgsVariable::num(const pgsOperand &var) +{ + return pgsMapm::pgs_str_mapm(var->value()); +} + +MAPM pgsVariable::num(const wxString &var) +{ + return pgsMapm::pgs_str_mapm(var); +} + +bool pgsVariable::is_number() const +{ + return is_integer() || is_real(); +} + +bool pgsVariable::is_integer() const +{ + return m_type == pgsTInt; +} + +bool pgsVariable::is_real() const +{ + return m_type == pgsTReal; +} + +bool pgsVariable::is_string() const +{ + return m_type == pgsTString; +} + +bool pgsVariable::is_record() const +{ + return m_type == pgsTRecord; +} + +const pgsVariable::pgsTypes &pgsVariable::type() const +{ + return m_type; +} + +pgsOperand operator+(const pgsVariable &lhs, const pgsVariable &rhs) +{ + return lhs.pgs_plus(rhs); +} + +pgsOperand operator-(const pgsVariable &lhs, const pgsVariable &rhs) +{ + return lhs.pgs_minus(rhs); +} + +pgsOperand operator*(const pgsVariable &lhs, const pgsVariable &rhs) +{ + return lhs.pgs_times(rhs); +} + +pgsOperand operator/(const pgsVariable &lhs, const pgsVariable &rhs) +{ + return lhs.pgs_over(rhs); +} + +pgsOperand operator%(const pgsVariable &lhs, const pgsVariable &rhs) +{ + return lhs.pgs_modulo(rhs); +} + +pgsOperand operator==(const pgsVariable &lhs, const pgsVariable &rhs) +{ + return lhs.pgs_equal(rhs); +} + +pgsOperand operator!=(const pgsVariable &lhs, const pgsVariable &rhs) +{ + return lhs.pgs_different(rhs); +} + +pgsOperand operator<(const pgsVariable &lhs, const pgsVariable &rhs) +{ + return lhs.pgs_lower(rhs); +} + +pgsOperand operator>(const pgsVariable &lhs, const pgsVariable &rhs) +{ + return lhs.pgs_greater(rhs); +} + +pgsOperand operator<=(const pgsVariable &lhs, const pgsVariable &rhs) +{ + return lhs.pgs_lower_equal(rhs); +} + +pgsOperand operator>=(const pgsVariable &lhs, const pgsVariable &rhs) +{ + return lhs.pgs_greater_equal(rhs); +} + +pgsOperand operator!(const pgsVariable &lhs) +{ + return lhs.pgs_not(); +} + +pgsOperand operator&=(const pgsVariable &lhs, const pgsVariable &rhs) +{ + return lhs.pgs_almost_equal(rhs); +} diff --git a/pgscript/parser.sh b/pgscript/parser.sh new file mode 100644 index 0000000..d89d4fe --- /dev/null +++ b/pgscript/parser.sh @@ -0,0 +1,80 @@ +#!/bin/sh + +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# parser.sh - Runs Flex and Bison and processes the generated files +# +####################################################################### + +# Directory containing pgScript includes (relative to the src directory) +INCLUDEDIR="include/pgscript" +# Directory containing pgScript sources (relative to the src directory) +SOURCEDIR="pgscript" +# Headers generated by Bison that need to be moved to ${INCLUDEDIR} +FILESTOMOVE=( "location.hh" "parser.tab.hh" "position.hh" "stack.hh" ) + +# Flex destination +LEXER="pgscript/lex.pgs.cc" +# A temporary file +AUX="pgscript/auxfile" +# Bison destination +PARSER="pgscript/parser.tab.cc" + +####################################################################### + +# Find the current directory +THISDIR=`dirname $0` +PREVDIR="$PWD" + +# Go to the directory on top of the script directory +echo -n "cd ${THISDIR}/.. ... " +cd "${THISDIR}/.." +echo "done" +pwd +echo "" + +# Generate Bison file +echo -n "+ Generating Bison output... " +bison -o"${PARSER}" "${SOURCEDIR}/pgsParser.yy" +echo "done" + +# Generate Flex file +echo -n "+ Generating Flex output... " +flex -o"${LEXER}" "${SOURCEDIR}/pgsScanner.ll" +echo "done" + +# Add pgAdmin3.h include at the beginning and change to +# "pgscript/FlexLexer.h" for the Flex output +echo -n "+ Processing Flex output... " +cat "${LEXER}" | awk 'BEGIN {print "#include \"pgAdmin3.h\"\n\n"}{print $0}' \ + | sed -e 's//"pgscript\/FlexLexer\.h"/g' > "${AUX}" +mv -f "${AUX}" "${LEXER}" +echo "done" + +# Add pgAdmin3.h include at the beginning and a pragma and change +# "parser.tab.hh" to "pgscript/parser.tab.hh" to the Bison output +echo -n "+ Processing Bison output... " +cat "${PARSER}" | awk 'BEGIN {print "#include \"pgAdmin3.h\"\n#if _MSC_VER > 1000\n#pragma warning(disable: 4800)\n#endif\n"}{print $0}' | \ + sed -e 's/"parser.tab.hh"/"pgscript\/parser\.tab\.hh"/g' > "${AUX}" +sleep 1 +mv -f "${AUX}" "${PARSER}" +echo "done" + +# Move Bison include files to the include directory +echo + "Moving Bison header files... " +for file in ${FILESTOMOVE[@]} +do + echo " + mv ${SOURCEDIR}/${file} ${INCLUDEDIR}/${file}" + mv "${SOURCEDIR}/${file}" "${INCLUDEDIR}/${file}" +done +echo "... done" + +# Go back to the previous directory +echo "" +echo -n "cd $PREVDIR ... " +cd "$PREVDIR" +echo "done" diff --git a/pgscript/parser.tab.cc b/pgscript/parser.tab.cc new file mode 100644 index 0000000..cb3fbf4 --- /dev/null +++ b/pgscript/parser.tab.cc @@ -0,0 +1,2703 @@ +#include "pgAdmin3.h" +#if _MSC_VER > 1000 +#pragma warning(disable: 4800) +#endif + +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Skeleton implementation for Bison LALR(1) parsers in C++ + + Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +// Take the name prefix into account. +#define yylex pgscriptlex + +#include "pgscript/parser.tab.hh" + +/* User implementation prologue. */ +#line 251 "pgscript/pgsParser.yy" + + +#include "pgscript/utilities/pgsDriver.h" +#include "pgscript/utilities/pgsScanner.h" + +/* This "connects" the bison parser in the driver to the flex scanner class + * object. It defines the yylex() function call to pull the next token from the + * current lexer object of the driver context. */ +#undef yylex +#define yylex driver.lexer->lex + + + +/* Line 317 of lalr1.cc. */ +#line 57 "pgscript/parser.tab.cc" + +#ifndef YY_ +# if YYENABLE_NLS +# if ENABLE_NLS +# include /* FIXME: INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#define YYUSE(e) ((void) (e)) + +/* A pseudo ostream that takes yydebug_ into account. */ +# define YYCDEBUG \ + for (bool yydebugcond_ = yydebug_; yydebugcond_; yydebugcond_ = false) \ + (*yycdebug_) + +/* Enable debugging if requested. */ +#if YYDEBUG + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug_) \ + { \ + *yycdebug_ << Title << ' '; \ + yy_symbol_print_ ((Type), (Value), (Location)); \ + *yycdebug_ << std::endl; \ + } \ +} while (false) + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug_) \ + yy_reduce_print_ (Rule); \ +} while (false) + +# define YY_STACK_PRINT() \ +do { \ + if (yydebug_) \ + yystack_print_ (); \ +} while (false) + +#else /* !YYDEBUG */ + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_REDUCE_PRINT(Rule) +# define YY_STACK_PRINT() + +#endif /* !YYDEBUG */ + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + +namespace pgscript +{ +#if YYERROR_VERBOSE + + /* Return YYSTR after stripping away unnecessary quotes and + backslashes, so that it's suitable for yyerror. The heuristic is + that double-quoting is unnecessary unless the string contains an + apostrophe, a comma, or backslash (other than backslash-backslash). + YYSTR is taken from yytname. */ + std::string + pgsParser::yytnamerr_ (const char *yystr) + { + if (*yystr == '"') + { + std::string yyr = ""; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + yyr += *yyp; + break; + + case '"': + return yyr; + } + do_not_strip_quotes: ; + } + + return yystr; + } + +#endif + + /// Build a parser object. + pgsParser::pgsParser (class pgsDriver & driver_yyarg) + : yydebug_ (false), + yycdebug_ (&std::cerr), + driver (driver_yyarg) + { + } + + pgsParser::~pgsParser () + { + } + +#if YYDEBUG + /*--------------------------------. + | Print this symbol on YYOUTPUT. | + `--------------------------------*/ + + inline void + pgsParser::yy_symbol_value_print_ (int yytype, + const semantic_type* yyvaluep, const location_type* yylocationp) + { + YYUSE (yylocationp); + YYUSE (yyvaluep); + switch (yytype) + { + default: + break; + } + } + + + void + pgsParser::yy_symbol_print_ (int yytype, + const semantic_type* yyvaluep, const location_type* yylocationp) + { + *yycdebug_ << (yytype < yyntokens_ ? "token" : "nterm") + << ' ' << yytname_[yytype] << " (" + << *yylocationp << ": "; + yy_symbol_value_print_ (yytype, yyvaluep, yylocationp); + *yycdebug_ << ')'; + } +#endif /* ! YYDEBUG */ + + void + pgsParser::yydestruct_ (const char* yymsg, + int yytype, semantic_type* yyvaluep, location_type* yylocationp) + { + YYUSE (yylocationp); + YYUSE (yymsg); + YYUSE (yyvaluep); + + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + case 42: /* "\"ABORT\"" */ +#line 167 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 217 "pgscript/parser.tab.cc" + break; + case 43: /* "\"ALTER\"" */ +#line 168 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 222 "pgscript/parser.tab.cc" + break; + case 44: /* "\"ANALYZE\"" */ +#line 169 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 227 "pgscript/parser.tab.cc" + break; + case 45: /* "\"BEGIN\"" */ +#line 170 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 232 "pgscript/parser.tab.cc" + break; + case 46: /* "\"CHECKPOINT\"" */ +#line 171 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 237 "pgscript/parser.tab.cc" + break; + case 47: /* "\"CLOSE\"" */ +#line 172 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 242 "pgscript/parser.tab.cc" + break; + case 48: /* "\"CLUSTER\"" */ +#line 173 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 247 "pgscript/parser.tab.cc" + break; + case 49: /* "\"COMMENT\"" */ +#line 174 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 252 "pgscript/parser.tab.cc" + break; + case 50: /* "\"COMMIT\"" */ +#line 175 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 257 "pgscript/parser.tab.cc" + break; + case 51: /* "\"COPY\"" */ +#line 176 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 262 "pgscript/parser.tab.cc" + break; + case 52: /* "\"CREATE\"" */ +#line 177 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 267 "pgscript/parser.tab.cc" + break; + case 53: /* "\"DEALLOCATE\"" */ +#line 178 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 272 "pgscript/parser.tab.cc" + break; + case 54: /* "\"DECLARE\"" */ +#line 179 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 277 "pgscript/parser.tab.cc" + break; + case 55: /* "\"DELETE\"" */ +#line 180 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 282 "pgscript/parser.tab.cc" + break; + case 56: /* "\"DISCARD\"" */ +#line 181 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 287 "pgscript/parser.tab.cc" + break; + case 57: /* "\"DROP\"" */ +#line 182 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 292 "pgscript/parser.tab.cc" + break; + case 58: /* "\"END\"" */ +#line 183 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 297 "pgscript/parser.tab.cc" + break; + case 59: /* "\"EXECUTE\"" */ +#line 184 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 302 "pgscript/parser.tab.cc" + break; + case 60: /* "\"EXPLAIN\"" */ +#line 185 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 307 "pgscript/parser.tab.cc" + break; + case 61: /* "\"FETCH\"" */ +#line 186 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 312 "pgscript/parser.tab.cc" + break; + case 62: /* "\"GRANT\"" */ +#line 187 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 317 "pgscript/parser.tab.cc" + break; + case 63: /* "\"INSERT\"" */ +#line 188 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 322 "pgscript/parser.tab.cc" + break; + case 64: /* "\"LISTEN\"" */ +#line 189 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 327 "pgscript/parser.tab.cc" + break; + case 65: /* "\"LOAD\"" */ +#line 190 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 332 "pgscript/parser.tab.cc" + break; + case 66: /* "\"LOCK\"" */ +#line 191 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 337 "pgscript/parser.tab.cc" + break; + case 67: /* "\"MOVE\"" */ +#line 192 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 342 "pgscript/parser.tab.cc" + break; + case 68: /* "\"NOTIFY\"" */ +#line 193 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 347 "pgscript/parser.tab.cc" + break; + case 69: /* "\"PREPARE\"" */ +#line 194 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 352 "pgscript/parser.tab.cc" + break; + case 70: /* "\"REASSIGN\"" */ +#line 195 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 357 "pgscript/parser.tab.cc" + break; + case 71: /* "\"REINDEX\"" */ +#line 196 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 362 "pgscript/parser.tab.cc" + break; + case 72: /* "\"RELEASE\"" */ +#line 197 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 367 "pgscript/parser.tab.cc" + break; + case 73: /* "\"RESET\"" */ +#line 198 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 372 "pgscript/parser.tab.cc" + break; + case 74: /* "\"REVOKE\"" */ +#line 199 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 377 "pgscript/parser.tab.cc" + break; + case 75: /* "\"ROLLBACK\"" */ +#line 200 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 382 "pgscript/parser.tab.cc" + break; + case 76: /* "\"SAVEPOINT\"" */ +#line 201 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 387 "pgscript/parser.tab.cc" + break; + case 77: /* "\"SELECT\"" */ +#line 202 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 392 "pgscript/parser.tab.cc" + break; + case 78: /* "\"SET\"" */ +#line 203 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 397 "pgscript/parser.tab.cc" + break; + case 79: /* "\"SHOW\"" */ +#line 204 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 402 "pgscript/parser.tab.cc" + break; + case 80: /* "\"START\"" */ +#line 205 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 407 "pgscript/parser.tab.cc" + break; + case 81: /* "\"TRUNCATE\"" */ +#line 206 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 412 "pgscript/parser.tab.cc" + break; + case 82: /* "\"UNLISTEN\"" */ +#line 207 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 417 "pgscript/parser.tab.cc" + break; + case 83: /* "\"UPDATE\"" */ +#line 208 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 422 "pgscript/parser.tab.cc" + break; + case 84: /* "\"VACUUM\"" */ +#line 209 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 427 "pgscript/parser.tab.cc" + break; + case 85: /* "\"VALUES\"" */ +#line 210 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 432 "pgscript/parser.tab.cc" + break; + case 86: /* "\"IDENTIFIER\"" */ +#line 212 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 437 "pgscript/parser.tab.cc" + break; + case 87: /* "\"INTEGER VALUE\"" */ +#line 213 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 442 "pgscript/parser.tab.cc" + break; + case 88: /* "\"REAL VALUE\"" */ +#line 214 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 447 "pgscript/parser.tab.cc" + break; + case 89: /* "\"STRING VALUE\"" */ +#line 215 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 452 "pgscript/parser.tab.cc" + break; + + default: + break; + } + } + + void + pgsParser::yypop_ (unsigned int n) + { + yystate_stack_.pop (n); + yysemantic_stack_.pop (n); + yylocation_stack_.pop (n); + } + + std::ostream& + pgsParser::debug_stream () const + { + return *yycdebug_; + } + + void + pgsParser::set_debug_stream (std::ostream& o) + { + yycdebug_ = &o; + } + + + pgsParser::debug_level_type + pgsParser::debug_level () const + { + return yydebug_; + } + + void + pgsParser::set_debug_level (debug_level_type l) + { + yydebug_ = l; + } + + + int + pgsParser::parse () + { + /// Look-ahead and look-ahead in internal form. + int yychar = yyempty_; + int yytoken = 0; + + /* State. */ + int yyn; + int yylen = 0; + int yystate = 0; + + /* Error handling. */ + int yynerrs_ = 0; + int yyerrstatus_ = 0; + + /// Semantic value of the look-ahead. + semantic_type yylval; + /// Location of the look-ahead. + location_type yylloc; + /// The locations where the error started and ended. + location yyerror_range[2]; + + /// $$. + semantic_type yyval; + /// @$. + location_type yyloc; + + int yyresult; + + YYCDEBUG << "Starting parse" << std::endl; + + + /* User initialization code. */ + #line 43 "pgscript/pgsParser.yy" +{ + // Initialize the initial location object + yylloc.begin.filename = yylloc.end.filename; +} + /* Line 547 of yacc.c. */ +#line 534 "pgscript/parser.tab.cc" + /* Initialize the stacks. The initial state will be pushed in + yynewstate, since the latter expects the semantical and the + location values to have been already stored, initialize these + stacks with a primary value. */ + yystate_stack_ = state_stack_type (0); + yysemantic_stack_ = semantic_stack_type (0); + yylocation_stack_ = location_stack_type (0); + yysemantic_stack_.push (yylval); + yylocation_stack_.push (yylloc); + + /* New state. */ + yynewstate: + yystate_stack_.push (yystate); + YYCDEBUG << "Entering state " << yystate << std::endl; + goto yybackup; + + /* Backup. */ + yybackup: + + /* Try to take a decision without look-ahead. */ + yyn = yypact_[yystate]; + if (yyn == yypact_ninf_) + goto yydefault; + + /* Read a look-ahead token. */ + if (yychar == yyempty_) + { + YYCDEBUG << "Reading a token: "; + yychar = yylex (&yylval, &yylloc); + } + + + /* Convert token to internal form. */ + if (yychar <= yyeof_) + { + yychar = yytoken = yyeof_; + YYCDEBUG << "Now at end of input." << std::endl; + } + else + { + yytoken = yytranslate_ (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yytoken) + goto yydefault; + + /* Reduce or error. */ + yyn = yytable_[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == yytable_ninf_) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Accept? */ + if (yyn == yyfinal_) + goto yyacceptlab; + + /* Shift the look-ahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the token being shifted unless it is eof. */ + if (yychar != yyeof_) + yychar = yyempty_; + + yysemantic_stack_.push (yylval); + yylocation_stack_.push (yylloc); + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus_) + --yyerrstatus_; + + yystate = yyn; + goto yynewstate; + + /*-----------------------------------------------------------. + | yydefault -- do the default action for the current state. | + `-----------------------------------------------------------*/ + yydefault: + yyn = yydefact_[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + /*-----------------------------. + | yyreduce -- Do a reduction. | + `-----------------------------*/ + yyreduce: + yylen = yyr2_[yyn]; + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. Otherwise, use the top of the stack. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. */ + if (yylen) + yyval = yysemantic_stack_[yylen - 1]; + else + yyval = yysemantic_stack_[0]; + + { + slice slice (yylocation_stack_, yylen); + YYLLOC_DEFAULT (yyloc, slice, yylen); + } + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: +#line 268 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsIdentRecord(*((yysemantic_stack_[(7) - (1)].str)), (yysemantic_stack_[(7) - (3)].expr), (yysemantic_stack_[(7) - (6)].expr)); + pdelete((yysemantic_stack_[(7) - (1)].str)); + driver.context.pop_var(); driver.context.pop_var(); // $3 & $6 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 3: +#line 275 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsIdentRecord(*((yysemantic_stack_[(4) - (1)].str)), (yysemantic_stack_[(4) - (3)].expr)); + pdelete((yysemantic_stack_[(4) - (1)].str)); + driver.context.pop_var(); // $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 4: +#line 282 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsLines(*((yysemantic_stack_[(4) - (3)].str))); + pdelete((yysemantic_stack_[(4) - (3)].str)); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 5: +#line 288 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsColumns(*((yysemantic_stack_[(4) - (3)].str))); + pdelete((yysemantic_stack_[(4) - (3)].str)); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 6: +#line 294 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsTrim((yysemantic_stack_[(4) - (3)].expr)); + driver.context.pop_var(); // $3 + driver.context.push_var((yyval.expr)); // assert + ;} + break; + + case 7: +#line 300 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsIdent(*((yysemantic_stack_[(1) - (1)].str))); + pdelete((yysemantic_stack_[(1) - (1)].str)); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 8: +#line 306 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsNumber(*((yysemantic_stack_[(1) - (1)].str)), pgsInt); + pdelete((yysemantic_stack_[(1) - (1)].str)); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 9: +#line 312 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsNumber(*((yysemantic_stack_[(1) - (1)].str)), pgsReal); + pdelete((yysemantic_stack_[(1) - (1)].str)); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 10: +#line 318 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsString(*((yysemantic_stack_[(1) - (1)].str))); + pdelete((yysemantic_stack_[(1) - (1)].str)); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 11: +#line 323 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsExecute(*((yysemantic_stack_[(3) - (2)].str)), &driver.context.m_cout, + &(driver.thread)); + pdelete((yysemantic_stack_[(3) - (2)].str)); + driver.context.push_var((yyval.expr)); // SQL Expression statement + ;} + break; + + case 12: +#line 329 "pgscript/pgsParser.yy" + { (yyval.expr) = (yysemantic_stack_[(1) - (1)].expr); ;} + break; + + case 13: +#line 330 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsParenthesis((yysemantic_stack_[(3) - (2)].expr)); + driver.context.pop_var(); // $2 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 14: +#line 338 "pgscript/pgsParser.yy" + { (yyval.expr) = (yysemantic_stack_[(1) - (1)].expr); ;} + break; + + case 15: +#line 339 "pgscript/pgsParser.yy" + { (yyval.expr) = (yysemantic_stack_[(2) - (2)].expr); ;} + break; + + case 16: +#line 340 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsNegate((yysemantic_stack_[(2) - (2)].expr)); + driver.context.pop_var(); // $2 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 17: +#line 346 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsNot((yysemantic_stack_[(2) - (2)].expr)); + driver.context.pop_var(); // $2 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 18: +#line 354 "pgscript/pgsParser.yy" + { (yyval.expr) = (yysemantic_stack_[(1) - (1)].expr); ;} + break; + + case 19: +#line 356 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsCast((yysemantic_stack_[(6) - (5)].integer), (yysemantic_stack_[(6) - (3)].expr)); + driver.context.pop_var(); // $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 20: +#line 364 "pgscript/pgsParser.yy" + { (yyval.integer) = pgscript::pgsParser::token::PGS_INTEGER; ;} + break; + + case 21: +#line 365 "pgscript/pgsParser.yy" + { (yyval.integer) = pgscript::pgsParser::token::PGS_REAL; ;} + break; + + case 22: +#line 366 "pgscript/pgsParser.yy" + { (yyval.integer) = pgscript::pgsParser::token::PGS_STRING; ;} + break; + + case 23: +#line 367 "pgscript/pgsParser.yy" + { (yyval.integer) = pgscript::pgsParser::token::PGS_RECORD; ;} + break; + + case 24: +#line 371 "pgscript/pgsParser.yy" + { (yyval.expr) = (yysemantic_stack_[(1) - (1)].expr); ;} + break; + + case 25: +#line 373 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsTimes((yysemantic_stack_[(3) - (1)].expr), (yysemantic_stack_[(3) - (3)].expr)); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 26: +#line 380 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsOver((yysemantic_stack_[(3) - (1)].expr), (yysemantic_stack_[(3) - (3)].expr)); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 27: +#line 387 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsModulo((yysemantic_stack_[(3) - (1)].expr), (yysemantic_stack_[(3) - (3)].expr)); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 28: +#line 396 "pgscript/pgsParser.yy" + { (yyval.expr) = (yysemantic_stack_[(1) - (1)].expr); ;} + break; + + case 29: +#line 398 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsPlus((yysemantic_stack_[(3) - (1)].expr), (yysemantic_stack_[(3) - (3)].expr)); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 30: +#line 405 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsMinus((yysemantic_stack_[(3) - (1)].expr), (yysemantic_stack_[(3) - (3)].expr)); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 31: +#line 414 "pgscript/pgsParser.yy" + { (yyval.expr) = (yysemantic_stack_[(1) - (1)].expr); ;} + break; + + case 32: +#line 416 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsLower((yysemantic_stack_[(3) - (1)].expr), (yysemantic_stack_[(3) - (3)].expr)); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 33: +#line 423 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGreater((yysemantic_stack_[(3) - (1)].expr), (yysemantic_stack_[(3) - (3)].expr)); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 34: +#line 430 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsLowerEqual((yysemantic_stack_[(3) - (1)].expr), (yysemantic_stack_[(3) - (3)].expr)); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 35: +#line 437 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGreaterEqual((yysemantic_stack_[(3) - (1)].expr), (yysemantic_stack_[(3) - (3)].expr)); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 36: +#line 446 "pgscript/pgsParser.yy" + { (yyval.expr) = (yysemantic_stack_[(1) - (1)].expr); ;} + break; + + case 37: +#line 448 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsEqual((yysemantic_stack_[(3) - (1)].expr), (yysemantic_stack_[(3) - (3)].expr)); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 38: +#line 455 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsEqual((yysemantic_stack_[(3) - (1)].expr), (yysemantic_stack_[(3) - (3)].expr), false); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 39: +#line 462 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsDifferent((yysemantic_stack_[(3) - (1)].expr), (yysemantic_stack_[(3) - (3)].expr)); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 40: +#line 471 "pgscript/pgsParser.yy" + { (yyval.expr) = (yysemantic_stack_[(1) - (1)].expr); ;} + break; + + case 41: +#line 473 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsAnd((yysemantic_stack_[(3) - (1)].expr), (yysemantic_stack_[(3) - (3)].expr)); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 42: +#line 482 "pgscript/pgsParser.yy" + { (yyval.expr) = (yysemantic_stack_[(1) - (1)].expr); ;} + break; + + case 43: +#line 484 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsOr((yysemantic_stack_[(3) - (1)].expr), (yysemantic_stack_[(3) - (3)].expr)); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 44: +#line 493 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("%s"), (yysemantic_stack_[(1) - (1)].expr)->value().c_str()); + (yyval.expr) = (yysemantic_stack_[(1) - (1)].expr); + ;} + break; + + case 45: +#line 501 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenInt((yysemantic_stack_[(6) - (3)].expr), (yysemantic_stack_[(6) - (5)].expr), driver.context.zero(), + driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 46: +#line 509 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenInt((yysemantic_stack_[(8) - (3)].expr), (yysemantic_stack_[(8) - (5)].expr), (yysemantic_stack_[(8) - (7)].expr), driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 47: +#line 516 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenInt((yysemantic_stack_[(10) - (3)].expr), (yysemantic_stack_[(10) - (5)].expr), (yysemantic_stack_[(10) - (7)].expr), (yysemantic_stack_[(10) - (9)].expr)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 48: +#line 523 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenReal((yysemantic_stack_[(8) - (3)].expr), (yysemantic_stack_[(8) - (5)].expr), (yysemantic_stack_[(8) - (7)].expr), driver.context.zero(), + driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 49: +#line 532 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenReal((yysemantic_stack_[(10) - (3)].expr), (yysemantic_stack_[(10) - (5)].expr), (yysemantic_stack_[(10) - (7)].expr), (yysemantic_stack_[(10) - (9)].expr), driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 50: +#line 540 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenReal((yysemantic_stack_[(12) - (3)].expr), (yysemantic_stack_[(12) - (5)].expr), (yysemantic_stack_[(12) - (7)].expr), (yysemantic_stack_[(12) - (9)].expr), (yysemantic_stack_[(12) - (11)].expr)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 51: +#line 548 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenString((yysemantic_stack_[(6) - (3)].expr), (yysemantic_stack_[(6) - (5)].expr), driver.context.one(), + driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 52: +#line 556 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenString((yysemantic_stack_[(8) - (3)].expr), (yysemantic_stack_[(8) - (5)].expr), (yysemantic_stack_[(8) - (7)].expr), driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 53: +#line 563 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenString((yysemantic_stack_[(10) - (3)].expr), (yysemantic_stack_[(10) - (5)].expr), (yysemantic_stack_[(10) - (7)].expr), (yysemantic_stack_[(10) - (9)].expr)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 54: +#line 570 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenRegex((yysemantic_stack_[(4) - (3)].expr), driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 55: +#line 576 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenRegex((yysemantic_stack_[(6) - (3)].expr), (yysemantic_stack_[(6) - (5)].expr)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 56: +#line 582 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenDictionary((yysemantic_stack_[(4) - (3)].expr), driver.context.zero(), + driver.context.seed(), driver.context.encoding()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 57: +#line 590 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenDictionary((yysemantic_stack_[(6) - (3)].expr), (yysemantic_stack_[(6) - (5)].expr), driver.context.seed(), + driver.context.encoding()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 58: +#line 598 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenDictionary((yysemantic_stack_[(8) - (3)].expr), (yysemantic_stack_[(8) - (5)].expr), (yysemantic_stack_[(8) - (7)].expr), driver.context.encoding()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 59: +#line 605 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenDictionary((yysemantic_stack_[(10) - (3)].expr), (yysemantic_stack_[(10) - (5)].expr), (yysemantic_stack_[(10) - (7)].expr), (yysemantic_stack_[(10) - (9)].expr)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 60: +#line 612 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenDate((yysemantic_stack_[(6) - (3)].expr), (yysemantic_stack_[(6) - (5)].expr), driver.context.zero(), + driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 61: +#line 620 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenDate((yysemantic_stack_[(8) - (3)].expr), (yysemantic_stack_[(8) - (5)].expr), (yysemantic_stack_[(8) - (7)].expr), driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 62: +#line 627 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenDate((yysemantic_stack_[(10) - (3)].expr), (yysemantic_stack_[(10) - (5)].expr), (yysemantic_stack_[(10) - (7)].expr), (yysemantic_stack_[(10) - (9)].expr)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 63: +#line 634 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenTime((yysemantic_stack_[(6) - (3)].expr), (yysemantic_stack_[(6) - (5)].expr), driver.context.zero(), + driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 64: +#line 642 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenTime((yysemantic_stack_[(8) - (3)].expr), (yysemantic_stack_[(8) - (5)].expr), (yysemantic_stack_[(8) - (7)].expr), driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 65: +#line 649 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenTime((yysemantic_stack_[(10) - (3)].expr), (yysemantic_stack_[(10) - (5)].expr), (yysemantic_stack_[(10) - (7)].expr), (yysemantic_stack_[(10) - (9)].expr)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 66: +#line 656 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenDateTime((yysemantic_stack_[(6) - (3)].expr), (yysemantic_stack_[(6) - (5)].expr), driver.context.zero(), + driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 67: +#line 664 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenDateTime((yysemantic_stack_[(8) - (3)].expr), (yysemantic_stack_[(8) - (5)].expr), (yysemantic_stack_[(8) - (7)].expr), driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 68: +#line 671 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenDateTime((yysemantic_stack_[(10) - (3)].expr), (yysemantic_stack_[(10) - (5)].expr), (yysemantic_stack_[(10) - (7)].expr), (yysemantic_stack_[(10) - (9)].expr)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 69: +#line 678 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenReference((yysemantic_stack_[(6) - (3)].expr), (yysemantic_stack_[(6) - (5)].expr), driver.context.zero(), + driver.context.seed(), &(driver.thread)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 70: +#line 686 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenReference((yysemantic_stack_[(8) - (3)].expr), (yysemantic_stack_[(8) - (5)].expr), (yysemantic_stack_[(8) - (7)].expr), driver.context.seed(), + &(driver.thread)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 71: +#line 694 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenReference((yysemantic_stack_[(10) - (3)].expr), (yysemantic_stack_[(10) - (5)].expr), (yysemantic_stack_[(10) - (7)].expr), (yysemantic_stack_[(10) - (9)].expr), &(driver.thread)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 72: +#line 703 "pgscript/pgsParser.yy" + { (yyval.stmt) = (yysemantic_stack_[(1) - (1)].stmt); ;} + break; + + case 73: +#line 704 "pgscript/pgsParser.yy" + { (yyval.stmt) = (yysemantic_stack_[(1) - (1)].stmt); ;} + break; + + case 74: +#line 705 "pgscript/pgsParser.yy" + { (yyval.stmt) = (yysemantic_stack_[(1) - (1)].stmt); ;} + break; + + case 75: +#line 706 "pgscript/pgsParser.yy" + { (yyval.stmt) = (yysemantic_stack_[(2) - (1)].stmt); ;} + break; + + case 76: +#line 707 "pgscript/pgsParser.yy" + { (yyval.stmt) = (yysemantic_stack_[(2) - (1)].stmt); ;} + break; + + case 77: +#line 708 "pgscript/pgsParser.yy" + { (yyval.stmt) = (yysemantic_stack_[(2) - (1)].stmt); ;} + break; + + case 78: +#line 709 "pgscript/pgsParser.yy" + { (yyval.stmt) = (yysemantic_stack_[(2) - (1)].stmt); ;} + break; + + case 79: +#line 710 "pgscript/pgsParser.yy" + { (yyval.stmt) = (yysemantic_stack_[(2) - (1)].stmt); ;} + break; + + case 80: +#line 714 "pgscript/pgsParser.yy" + { + driver.context.pop_stmt(); // $1 + (yyval.stmt_list) = driver.context.stmt_list(&(driver.thread)); + (yyval.stmt_list)->insert_back((yysemantic_stack_[(1) - (1)].stmt)); + ;} + break; + + case 81: +#line 719 "pgscript/pgsParser.yy" + { + driver.context.pop_stmt(); // $2 + (yyval.stmt_list) = (yysemantic_stack_[(2) - (1)].stmt_list); + (yyval.stmt_list)->insert_back((yysemantic_stack_[(2) - (2)].stmt)); + ;} + break; + + case 82: +#line 727 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("BEGIN END")); + (yyval.stmt) = driver.context.stmt_list(&(driver.thread)); + ;} + break; + + case 83: +#line 732 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("BEGIN ... END")); + (yyval.stmt) = (yysemantic_stack_[(3) - (2)].stmt_list); + ;} + break; + + case 84: +#line 739 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("%s"), (yysemantic_stack_[(1) - (1)].expr)->value().c_str()); + (yyval.stmt) = pnew pgsExpressionStmt((yysemantic_stack_[(1) - (1)].expr), &(driver.thread)); + driver.context.pop_var(); // $1 + driver.context.push_stmt((yyval.stmt)); // pgsExpressionStmt + (yyval.stmt)->set_position(yyloc.begin.line); + ;} + break; + + case 85: +#line 749 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsExecute(*((yysemantic_stack_[(1) - (1)].str)), &driver.context.m_cout, + &(driver.thread)); + pdelete((yysemantic_stack_[(1) - (1)].str)); + driver.context.push_var((yyval.expr)); // pgsExecute + ;} + break; + + case 86: +#line 758 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 87: +#line 759 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 88: +#line 760 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 89: +#line 761 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 90: +#line 762 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 91: +#line 763 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 92: +#line 764 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 93: +#line 765 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 94: +#line 766 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 95: +#line 767 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 96: +#line 768 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 97: +#line 769 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 98: +#line 770 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 99: +#line 771 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 100: +#line 772 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 101: +#line 773 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 102: +#line 774 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 103: +#line 775 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 104: +#line 776 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 105: +#line 777 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 106: +#line 778 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 107: +#line 779 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 108: +#line 780 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 109: +#line 781 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 110: +#line 782 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 111: +#line 783 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 112: +#line 784 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 113: +#line 785 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 114: +#line 786 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 115: +#line 787 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 116: +#line 788 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 117: +#line 789 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 118: +#line 790 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 119: +#line 791 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 120: +#line 792 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 121: +#line 793 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 122: +#line 794 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 123: +#line 795 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 124: +#line 796 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 125: +#line 797 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 126: +#line 798 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 127: +#line 799 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 128: +#line 800 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 129: +#line 801 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 130: +#line 806 "pgscript/pgsParser.yy" + { + (yyval.stmt) = (yysemantic_stack_[(2) - (2)].stmt_list); + ;} + break; + + case 131: +#line 812 "pgscript/pgsParser.yy" + { + driver.context.pop_stmt(); // $1 + (yyval.stmt_list) = driver.context.stmt_list(&(driver.thread)); + (yyval.stmt_list)->insert_back((yysemantic_stack_[(1) - (1)].stmt)); + + ;} + break; + + case 132: +#line 819 "pgscript/pgsParser.yy" + { + driver.context.pop_stmt(); // $3 + (yyval.stmt_list) = (yysemantic_stack_[(3) - (1)].stmt_list); + (yyval.stmt_list)->insert_back((yysemantic_stack_[(3) - (3)].stmt)); + ;} + break; + + case 133: +#line 827 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("DECLARE %s"), (yysemantic_stack_[(1) - (1)].str)->c_str()); + + (yyval.stmt) = pnew pgsExpressionStmt(pnew pgsAssign(*((yysemantic_stack_[(1) - (1)].str)), + pnew pgsString(wxT(""))), &(driver.thread)); + driver.context.push_stmt((yyval.stmt)); // pgsExpressionStmt + (yyval.stmt)->set_position(yyloc.begin.line); + + pdelete((yysemantic_stack_[(1) - (1)].str)); + ;} + break; + + case 134: +#line 838 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("DECLARE %s"), (yysemantic_stack_[(4) - (1)].str)->c_str()); + + (yyval.stmt) = pnew pgsDeclareRecordStmt(*((yysemantic_stack_[(4) - (1)].str)), driver.context.columns(), + &(driver.thread)); + driver.context.push_stmt((yyval.stmt)); // pgsDeclareRecordStmt + (yyval.stmt)->set_position(yyloc.begin.line); + + driver.context.clear_columns(); + pdelete((yysemantic_stack_[(4) - (1)].str)); + ;} + break; + + case 135: +#line 853 "pgscript/pgsParser.yy" + { + (yyval.stmt) = (yysemantic_stack_[(2) - (2)].stmt_list); + ;} + break; + + case 136: +#line 859 "pgscript/pgsParser.yy" + { + driver.context.pop_stmt(); // $1 + (yyval.stmt_list) = driver.context.stmt_list(&(driver.thread)); + (yyval.stmt_list)->insert_back((yysemantic_stack_[(1) - (1)].stmt)); + ;} + break; + + case 137: +#line 865 "pgscript/pgsParser.yy" + { + driver.context.pop_stmt(); // $3 + (yyval.stmt_list) = (yysemantic_stack_[(3) - (1)].stmt_list); + (yyval.stmt_list)->insert_back((yysemantic_stack_[(3) - (3)].stmt)); + ;} + break; + + case 138: +#line 874 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("SET %s = %s"), (yysemantic_stack_[(3) - (1)].str)->c_str(), + (yysemantic_stack_[(3) - (3)].expr)->value().c_str()); + + (yyval.stmt) = pnew pgsExpressionStmt(pnew pgsAssign(*((yysemantic_stack_[(3) - (1)].str)), (yysemantic_stack_[(3) - (3)].expr)), + &(driver.thread)); + driver.context.pop_var(); // $3 + driver.context.push_stmt((yyval.stmt)); // pgsExpressionStmt + (yyval.stmt)->set_position(yyloc.begin.line); + + pdelete((yysemantic_stack_[(3) - (1)].str)); + ;} + break; + + case 139: +#line 887 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("SET %s[%s][%s] = %s"), + (yysemantic_stack_[(9) - (1)].str)->c_str(), (yysemantic_stack_[(9) - (3)].expr)->value().c_str(), + (yysemantic_stack_[(9) - (6)].expr)->value().c_str(), (yysemantic_stack_[(9) - (9)].expr)->value().c_str()); + + (yyval.stmt) = pnew pgsExpressionStmt(pnew pgsAssignToRecord(*((yysemantic_stack_[(9) - (1)].str)), + (yysemantic_stack_[(9) - (3)].expr), (yysemantic_stack_[(9) - (6)].expr), (yysemantic_stack_[(9) - (9)].expr)), &(driver.thread)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); // $3 & $6 & $9 + driver.context.push_stmt((yyval.stmt)); // pgsExpressionStmt + (yyval.stmt)->set_position(yyloc.begin.line); + + pdelete((yysemantic_stack_[(9) - (1)].str)); + ;} + break; + + case 140: +#line 902 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("SET %s = %s"), (yysemantic_stack_[(3) - (1)].str)->c_str(), + (yysemantic_stack_[(3) - (3)].expr)->value().c_str()); + + (yyval.stmt) = pnew pgsExpressionStmt(pnew pgsAssign(*((yysemantic_stack_[(3) - (1)].str)), (yysemantic_stack_[(3) - (3)].expr)), + &(driver.thread)); + driver.context.pop_var(); // $3 + driver.context.push_stmt((yyval.stmt)); // pgsExpressionStmt + (yyval.stmt)->set_position(yyloc.begin.line); + + pdelete((yysemantic_stack_[(3) - (1)].str)); + ;} + break; + + case 141: +#line 918 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("IF %s"), (yysemantic_stack_[(3) - (2)].expr)->value().c_str()); + + (yyval.stmt) = pnew pgsIfStmt((yysemantic_stack_[(3) - (2)].expr), (yysemantic_stack_[(3) - (3)].stmt), driver.context + .stmt_list(&(driver.thread)), &(driver.thread)); + driver.context.pop_var(); // $2 + driver.context.pop_stmt(); // $3 + driver.context.pop_stmt(); // stmt_list + driver.context.push_stmt((yyval.stmt)); // pgsIfStmt + (yyval.stmt)->set_position(yyloc.begin.line); + ;} + break; + + case 142: +#line 930 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("IF %s"), (yysemantic_stack_[(5) - (2)].expr)->value().c_str()); + + (yyval.stmt) = pnew pgsIfStmt((yysemantic_stack_[(5) - (2)].expr), (yysemantic_stack_[(5) - (3)].stmt), (yysemantic_stack_[(5) - (5)].stmt), &(driver.thread)); + driver.context.pop_var(); // $2 + driver.context.pop_stmt(); // $3 + driver.context.pop_stmt(); // $5 + driver.context.push_stmt((yyval.stmt)); // pgsIfStmt + (yyval.stmt)->set_position(yyloc.begin.line); + ;} + break; + + case 143: +#line 944 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("WHILE %s"), (yysemantic_stack_[(3) - (2)].expr)->value().c_str()); + + (yyval.stmt) = pnew pgsWhileStmt((yysemantic_stack_[(3) - (2)].expr), (yysemantic_stack_[(3) - (3)].stmt), &(driver.thread)); + driver.context.pop_var(); // $2 + driver.context.pop_stmt(); // $3 + driver.context.push_stmt((yyval.stmt)); // pgsWhileStmt + (yyval.stmt)->set_position(yyloc.begin.line); + ;} + break; + + case 144: +#line 956 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("BREAK")); + + (yyval.stmt) = pnew pgsBreakStmt(&(driver.thread)); + driver.context.push_stmt((yyval.stmt)); // pgsBreakStmt + (yyval.stmt)->set_position(yyloc.begin.line); + ;} + break; + + case 145: +#line 963 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("RETURN")); + + (yyval.stmt) = pnew pgsBreakStmt(&(driver.thread)); + driver.context.push_stmt((yyval.stmt)); // pgsBreakStmt + (yyval.stmt)->set_position(yyloc.begin.line); + ;} + break; + + case 146: +#line 970 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("CONTINUE")); + + (yyval.stmt) = pnew pgsContinueStmt(&(driver.thread)); + driver.context.push_stmt((yyval.stmt)); // pgsContinueStmt + (yyval.stmt)->set_position(yyloc.begin.line); + ;} + break; + + case 147: +#line 981 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("PRINT %s"), (yysemantic_stack_[(2) - (2)].expr)->value().c_str()); + + (yyval.stmt) = pnew pgsPrintStmt((yysemantic_stack_[(2) - (2)].expr), driver.context.m_cout, + &(driver.thread)); + driver.context.pop_var(); // $2 + driver.context.push_stmt((yyval.stmt)); // pgsPrintStmt + (yyval.stmt)->set_position(yyloc.begin.line); + ;} + break; + + case 148: +#line 991 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("ASSERT %s"), (yysemantic_stack_[(2) - (2)].expr)->value().c_str()); + + (yyval.stmt) = pnew pgsAssertStmt((yysemantic_stack_[(2) - (2)].expr), &(driver.thread)); + driver.context.pop_var(); // $2 + driver.context.push_stmt((yyval.stmt)); // pgsAssertStmt + (yyval.stmt)->set_position(yyloc.begin.line); + ;} + break; + + case 149: +#line 1000 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("RMLINE %s[%s]"), (yysemantic_stack_[(7) - (3)].str)->c_str(), + (yysemantic_stack_[(7) - (5)].expr)->value().c_str()); + + (yyval.stmt) = pnew pgsExpressionStmt(pnew pgsRemoveLine(*((yysemantic_stack_[(7) - (3)].str)), (yysemantic_stack_[(7) - (5)].expr)), + &(driver.thread)); + driver.context.pop_var(); // $5 + driver.context.push_stmt((yyval.stmt)); // pgsExpressionStmt + (yyval.stmt)->set_position(yyloc.begin.line); + + pdelete((yysemantic_stack_[(7) - (3)].str)); + ;} + break; + + case 150: +#line 1015 "pgscript/pgsParser.yy" + { + driver.context.add_column(*(yysemantic_stack_[(1) - (1)].str)); + pdelete((yysemantic_stack_[(1) - (1)].str)); + ;} + break; + + case 151: +#line 1020 "pgscript/pgsParser.yy" + { + driver.context.add_column(*(yysemantic_stack_[(3) - (3)].str)); + pdelete((yysemantic_stack_[(3) - (3)].str)); + ;} + break; + + case 153: +#line 1028 "pgscript/pgsParser.yy" + { + driver.program.eval((yysemantic_stack_[(2) - (1)].stmt_list)); + + driver.context.pop_stmt(); + pdelete((yysemantic_stack_[(2) - (1)].stmt_list)); // delete root statement $1 + ;} + break; + + + /* Line 675 of lalr1.cc. */ +#line 1866 "pgscript/parser.tab.cc" + default: break; + } + YY_SYMBOL_PRINT ("-> $$ =", yyr1_[yyn], &yyval, &yyloc); + + yypop_ (yylen); + yylen = 0; + YY_STACK_PRINT (); + + yysemantic_stack_.push (yyval); + yylocation_stack_.push (yyloc); + + /* Shift the result of the reduction. */ + yyn = yyr1_[yyn]; + yystate = yypgoto_[yyn - yyntokens_] + yystate_stack_[0]; + if (0 <= yystate && yystate <= yylast_ + && yycheck_[yystate] == yystate_stack_[0]) + yystate = yytable_[yystate]; + else + yystate = yydefgoto_[yyn - yyntokens_]; + goto yynewstate; + + /*------------------------------------. + | yyerrlab -- here on detecting error | + `------------------------------------*/ + yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus_) + { + ++yynerrs_; + error (yylloc, yysyntax_error_ (yystate, yytoken)); + } + + yyerror_range[0] = yylloc; + if (yyerrstatus_ == 3) + { + /* If just tried and failed to reuse look-ahead token after an + error, discard it. */ + + if (yychar <= yyeof_) + { + /* Return failure if at end of input. */ + if (yychar == yyeof_) + YYABORT; + } + else + { + yydestruct_ ("Error: discarding", yytoken, &yylval, &yylloc); + yychar = yyempty_; + } + } + + /* Else will try to reuse look-ahead token after shifting the error + token. */ + goto yyerrlab1; + + + /*---------------------------------------------------. + | yyerrorlab -- error raised explicitly by YYERROR. | + `---------------------------------------------------*/ + yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (false) + goto yyerrorlab; + + yyerror_range[0] = yylocation_stack_[yylen - 1]; + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + yypop_ (yylen); + yylen = 0; + yystate = yystate_stack_[0]; + goto yyerrlab1; + + /*-------------------------------------------------------------. + | yyerrlab1 -- common code for both syntax error and YYERROR. | + `-------------------------------------------------------------*/ + yyerrlab1: + yyerrstatus_ = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact_[yystate]; + if (yyn != yypact_ninf_) + { + yyn += yyterror_; + if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yyterror_) + { + yyn = yytable_[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yystate_stack_.height () == 1) + YYABORT; + + yyerror_range[0] = yylocation_stack_[0]; + yydestruct_ ("Error: popping", + yystos_[yystate], + &yysemantic_stack_[0], &yylocation_stack_[0]); + yypop_ (); + yystate = yystate_stack_[0]; + YY_STACK_PRINT (); + } + + if (yyn == yyfinal_) + goto yyacceptlab; + + yyerror_range[1] = yylloc; + // Using YYLLOC is tempting, but would change the location of + // the look-ahead. YYLOC is available though. + YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); + yysemantic_stack_.push (yylval); + yylocation_stack_.push (yyloc); + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos_[yyn], + &yysemantic_stack_[0], &yylocation_stack_[0]); + + yystate = yyn; + goto yynewstate; + + /* Accept. */ + yyacceptlab: + yyresult = 0; + goto yyreturn; + + /* Abort. */ + yyabortlab: + yyresult = 1; + goto yyreturn; + + yyreturn: + if (yychar != yyeof_ && yychar != yyempty_) + yydestruct_ ("Cleanup: discarding lookahead", yytoken, &yylval, &yylloc); + + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + yypop_ (yylen); + while (yystate_stack_.height () != 1) + { + yydestruct_ ("Cleanup: popping", + yystos_[yystate_stack_[0]], + &yysemantic_stack_[0], + &yylocation_stack_[0]); + yypop_ (); + } + + return yyresult; + } + + // Generate an error message. + std::string + pgsParser::yysyntax_error_ (int yystate, int tok) + { + std::string res; + YYUSE (yystate); +#if YYERROR_VERBOSE + int yyn = yypact_[yystate]; + if (yypact_ninf_ < yyn && yyn <= yylast_) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = yylast_ - yyn + 1; + int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_; + int count = 0; + for (int x = yyxbegin; x < yyxend; ++x) + if (yycheck_[x + yyn] == x && x != yyterror_) + ++count; + + // FIXME: This method of building the message is not compatible + // with internationalization. It should work like yacc.c does it. + // That is, first build a string that looks like this: + // "syntax error, unexpected %s or %s or %s" + // Then, invoke YY_ on this string. + // Finally, use the string as a format to output + // yytname_[tok], etc. + // Until this gets fixed, this message appears in English only. + res = "syntax error, unexpected "; + res += yytnamerr_ (yytname_[tok]); + if (count < 5) + { + count = 0; + for (int x = yyxbegin; x < yyxend; ++x) + if (yycheck_[x + yyn] == x && x != yyterror_) + { + res += (!count++) ? ", expecting " : " or "; + res += yytnamerr_ (yytname_[x]); + } + } + } + else +#endif + res = YY_("syntax error"); + return res; + } + + + /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ + const signed char pgsParser::yypact_ninf_ = -93; + const short int + pgsParser::yypact_[] = + { + 284, -93, 6, -93, -93, -93, 6, 453, 6, 6, + -88, -76, -61, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, 370, -93, + -65, -93, -93, -56, -45, -93, -93, -44, -28, 73, + 12, 13, 23, 27, 37, 42, 44, 50, 63, 65, + 66, 67, 68, 6, 0, -93, -93, -93, -11, 6, + 6, -93, -93, -93, 51, -74, 7, 117, 120, 124, + 619, -93, 619, -93, 536, -93, -93, 76, -25, 62, + -93, 61, 69, -93, -93, -93, -93, -93, -93, -93, + -93, -93, 79, 80, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, -93, 6, 74, 75, -93, + -93, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, -93, 161, -93, 81, 689, + 6, -76, 86, -61, 82, 83, 84, 163, 77, 78, + 85, -53, -52, 87, 89, 90, 91, 92, -93, -93, + -93, -93, -93, 51, 51, -74, -74, -74, -74, 7, + 7, 7, 117, 120, 619, 6, -93, -93, 93, -93, + -93, 34, -93, -93, -93, -93, 64, 6, 6, 6, + -93, 6, -93, 6, 6, 6, 6, 6, 95, -93, + 96, 103, 88, -93, -93, -93, -93, -93, 101, -51, + 94, -42, 104, -38, -37, -31, -22, -21, 6, 105, + 6, -93, -93, -93, 6, 6, -93, 6, -93, -93, + 6, -93, 6, -93, 6, -93, 6, -93, 6, 108, + -93, 109, -4, -2, 9, 10, 15, 16, 38, 39, + -93, 147, -93, 6, -93, 6, -93, 6, -93, 6, + -93, 6, -93, 6, -93, 6, -93, 6, 6, 111, + 40, 113, 119, 121, 122, 123, 125, -93, -93, -93, + 6, -93, -93, -93, -93, -93, -93, 126, -93 + }; + + /* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE + doesn't specify something else to do. Zero means the default is an + error. */ + const unsigned char + pgsParser::yydefact_[] = + { + 0, 152, 0, 144, 145, 146, 0, 0, 0, 0, + 0, 0, 0, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 80, 0, 72, + 0, 84, 85, 0, 0, 73, 74, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 8, 9, 10, 0, 0, + 0, 14, 18, 24, 28, 31, 36, 40, 42, 44, + 0, 12, 0, 82, 0, 148, 147, 0, 0, 135, + 136, 133, 130, 131, 153, 81, 75, 78, 79, 77, + 76, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 17, 0, 0, 0, 15, + 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 143, 141, 83, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 11, 13, + 25, 26, 27, 29, 30, 34, 35, 32, 33, 37, + 38, 39, 41, 43, 0, 0, 138, 140, 0, 137, + 150, 0, 132, 5, 4, 6, 0, 0, 0, 0, + 54, 0, 56, 0, 0, 0, 0, 0, 3, 142, + 0, 0, 0, 134, 23, 20, 21, 22, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 151, 19, 45, 0, 0, 51, 0, 55, 57, + 0, 60, 0, 63, 0, 66, 0, 69, 0, 0, + 149, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 46, 0, 48, 0, 52, 0, 58, 0, + 61, 0, 64, 0, 67, 0, 70, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 139, 47, 49, + 0, 53, 59, 62, 65, 68, 71, 0, 50 + }; + + /* YYPGOTO[NTERM-NUM]. */ + const short int + pgsParser::yypgoto_[] = + { + -93, -93, -93, -29, -93, -92, -3, -83, 28, 59, + -93, -6, -93, -57, 175, -93, -93, 58, -93, -93, + -93, 33, -93, -93, 60, -93, -93, -93, -93, -93, + -93 + }; + + /* YYDEFGOTO[NTERM-NUM]. */ + const short int + pgsParser::yydefgoto_[] = + { + -1, 91, 92, 93, 228, 94, 95, 96, 97, 98, + 99, 100, 101, 57, 58, 59, 60, 61, 62, 63, + 112, 113, 64, 109, 110, 65, 66, 67, 68, 201, + 69 + }; + + /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. */ + const signed char pgsParser::yytable_ninf_ = -1; + const unsigned short int + pgsParser::yytable_[] = + { + 102, 115, 105, 106, 107, 70, 71, 72, 159, 73, + 108, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 144, 145, 70, 71, 72, 111, 73, 83, 74, 75, + 76, 77, 78, 79, 80, 81, 82, 116, 146, 147, + 210, 212, 243, 155, 83, 156, 117, 115, 211, 213, + 244, 246, 183, 184, 135, 249, 251, 118, 119, 247, + 139, 140, 253, 250, 252, 160, 137, 189, 190, 191, + 254, 255, 257, 121, 120, 84, 85, 86, 87, 256, + 258, 88, 138, 89, 90, 224, 225, 226, 227, 272, + 136, 274, 84, 85, 86, 87, 167, 273, 88, 275, + 89, 90, 276, 278, 122, 123, 148, 149, 280, 282, + 277, 279, 180, 181, 182, 124, 281, 283, 166, 125, + 168, 169, 170, 171, 172, 173, 174, 175, 176, 126, + 177, 284, 286, 299, 127, 222, 128, 219, 223, 285, + 287, 300, 129, 185, 186, 187, 188, 141, 142, 143, + 150, 151, 152, 196, 198, 130, 153, 131, 132, 133, + 134, 154, 158, 161, 162, 164, 165, 178, 179, 194, + 163, 195, 200, 206, 241, 203, 204, 205, 207, 208, + 288, 192, 104, 218, 221, 238, 209, 239, 214, 220, + 215, 216, 217, 240, 242, 245, 202, 248, 260, 270, + 271, 229, 230, 231, 298, 232, 301, 233, 234, 235, + 236, 237, 302, 193, 303, 304, 305, 197, 306, 308, + 0, 199, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 259, 0, 261, 0, 0, 0, 262, 263, + 0, 264, 0, 0, 265, 0, 266, 0, 267, 0, + 268, 0, 269, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 289, 0, 290, + 0, 291, 0, 292, 0, 293, 0, 294, 0, 295, + 0, 296, 297, 0, 1, 0, 0, 2, 3, 4, + 5, 6, 0, 0, 307, 7, 0, 8, 9, 0, + 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 114, 0, 0, 2, 3, 4, 5, 6, 0, 0, + 0, 7, 0, 8, 9, 0, 0, 0, 0, 10, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 2, 3, 4, 5, + 6, 0, 0, 0, 7, 103, 8, 9, 0, 0, + 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 2, + 3, 4, 5, 6, 0, 0, 0, 7, 157, 8, + 9, 0, 0, 0, 0, 10, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 2, 3, 4, 5, 6, 0, 0, 0, + 7, 0, 8, 9, 0, 0, 0, 0, 10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 70, 71, 72, 0, 73, + 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, + 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 84, 85, 86, 87, 0, + 0, 88, 0, 89, 90 + }; + + /* YYCHECK. */ + const short int + pgsParser::yycheck_[] = + { + 6, 58, 8, 9, 92, 16, 17, 18, 33, 20, + 86, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 94, 95, 16, 17, 18, 86, 20, 38, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 102, 31, 32, + 93, 93, 93, 100, 38, 102, 102, 104, 101, 101, + 101, 93, 144, 145, 83, 93, 93, 102, 102, 101, + 89, 90, 93, 101, 101, 90, 77, 150, 151, 152, + 101, 93, 93, 0, 102, 86, 87, 88, 89, 101, + 101, 92, 88, 94, 95, 21, 22, 23, 24, 93, + 90, 93, 86, 87, 88, 89, 125, 101, 92, 101, + 94, 95, 93, 93, 92, 92, 99, 100, 93, 93, + 101, 101, 141, 142, 143, 92, 101, 101, 124, 92, + 126, 127, 128, 129, 130, 131, 132, 133, 134, 92, + 136, 93, 93, 93, 92, 101, 92, 194, 104, 101, + 101, 101, 92, 146, 147, 148, 149, 96, 97, 98, + 33, 34, 35, 159, 160, 92, 36, 92, 92, 92, + 92, 37, 86, 101, 103, 86, 86, 93, 93, 8, + 101, 90, 86, 10, 86, 93, 93, 93, 101, 101, + 33, 153, 7, 91, 91, 90, 101, 91, 101, 195, + 101, 101, 101, 90, 93, 101, 163, 93, 93, 91, + 91, 207, 208, 209, 93, 211, 93, 213, 214, 215, + 216, 217, 93, 154, 93, 93, 93, 159, 93, 93, + -1, 161, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 238, -1, 240, -1, -1, -1, 244, 245, + -1, 247, -1, -1, 250, -1, 252, -1, 254, -1, + 256, -1, 258, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 273, -1, 275, + -1, 277, -1, 279, -1, 281, -1, 283, -1, 285, + -1, 287, 288, -1, 0, -1, -1, 3, 4, 5, + 6, 7, -1, -1, 300, 11, -1, 13, 14, -1, + -1, -1, -1, 19, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, + 0, -1, -1, 3, 4, 5, 6, 7, -1, -1, + -1, 11, -1, 13, 14, -1, -1, -1, -1, 19, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 3, 4, 5, 6, + 7, -1, -1, -1, 11, 12, 13, 14, -1, -1, + -1, -1, 19, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 3, + 4, 5, 6, 7, -1, -1, -1, 11, 12, 13, + 14, -1, -1, -1, -1, 19, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, 3, 4, 5, 6, 7, -1, -1, -1, + 11, -1, 13, 14, -1, -1, -1, -1, 19, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 16, 17, 18, -1, 20, + -1, 22, 23, 24, 25, 26, 27, 28, 29, 30, + -1, -1, -1, -1, -1, -1, -1, 38, -1, -1, + -1, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, -1, + -1, 92, -1, 94, 95 + }; + + /* STOS_[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ + const unsigned char + pgsParser::yystos_[] = + { + 0, 0, 3, 4, 5, 6, 7, 11, 13, 14, + 19, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 118, 119, 120, + 121, 122, 123, 124, 127, 130, 131, 132, 133, 135, + 16, 17, 18, 20, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 38, 86, 87, 88, 89, 92, 94, + 95, 106, 107, 108, 110, 111, 112, 113, 114, 115, + 116, 117, 116, 12, 119, 116, 116, 92, 86, 128, + 129, 86, 125, 126, 0, 118, 102, 102, 102, 102, + 102, 0, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 108, 90, 77, 116, 108, + 108, 96, 97, 98, 94, 95, 31, 32, 99, 100, + 33, 34, 35, 36, 37, 118, 118, 12, 86, 33, + 90, 101, 103, 101, 86, 86, 116, 108, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 93, 93, + 108, 108, 108, 110, 110, 111, 111, 111, 111, 112, + 112, 112, 113, 114, 8, 90, 116, 122, 116, 129, + 86, 134, 126, 93, 93, 93, 10, 101, 101, 101, + 93, 101, 93, 101, 101, 101, 101, 101, 91, 118, + 116, 91, 101, 104, 21, 22, 23, 24, 109, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 90, 91, + 90, 86, 93, 93, 101, 101, 93, 101, 93, 93, + 101, 93, 101, 93, 101, 93, 101, 93, 101, 116, + 93, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 91, 91, 93, 101, 93, 101, 93, 101, 93, 101, + 93, 101, 93, 101, 93, 101, 93, 101, 33, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 93, 93, + 101, 93, 93, 93, 93, 93, 93, 116, 93 + }; + +#if YYDEBUG + /* TOKEN_NUMBER_[YYLEX-NUM] -- Internal symbol number corresponding + to YYLEX-NUM. */ + const unsigned short int + pgsParser::yytoken_number_[] = + { + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 91, 93, 40, 41, 43, 45, 42, 47, 37, 60, + 62, 44, 59, 123, 125 + }; +#endif + + /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ + const unsigned char + pgsParser::yyr1_[] = + { + 0, 105, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 107, 107, 107, 107, 108, 108, + 109, 109, 109, 109, 110, 110, 110, 110, 111, 111, + 111, 112, 112, 112, 112, 112, 113, 113, 113, 113, + 114, 114, 115, 115, 116, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 118, 118, 118, 118, 118, 118, 118, 118, + 119, 119, 120, 120, 121, 122, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 124, 125, 125, 126, 126, 127, 128, 128, 129, 129, + 129, 130, 130, 131, 132, 132, 132, 133, 133, 133, + 134, 134, 135, 135 + }; + + /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ + const unsigned char + pgsParser::yyr2_[] = + { + 0, 2, 7, 4, 4, 4, 4, 1, 1, 1, + 1, 3, 1, 3, 1, 2, 2, 2, 1, 6, + 1, 1, 1, 1, 1, 3, 3, 3, 1, 3, + 3, 1, 3, 3, 3, 3, 1, 3, 3, 3, + 1, 3, 1, 3, 1, 6, 8, 10, 8, 10, + 12, 6, 8, 10, 4, 6, 4, 6, 8, 10, + 6, 8, 10, 6, 8, 10, 6, 8, 10, 6, + 8, 10, 1, 1, 1, 2, 2, 2, 2, 2, + 1, 2, 2, 3, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 1, 3, 1, 4, 2, 1, 3, 3, 9, + 3, 3, 5, 3, 1, 1, 1, 2, 2, 7, + 1, 3, 1, 2 + }; + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE + /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at \a yyntokens_, nonterminals. */ + const char* + const pgsParser::yytname_[] = + { + "\"END OF FILE\"", "error", "$undefined", "\"WHILE\"", "\"BREAK\"", + "\"RETURN\"", "\"CONTINUE\"", "\"IF\"", "\"ELSE\"", "\"WAITFOR\"", + "\"AS\"", "\"BEGIN (BLOCK)\"", "\"END (BLOCK)\"", "\"ASSERT\"", + "\"PRINT\"", "\"LOG\"", "\"COLUMNS\"", "\"LINES\"", "\"TRIM\"", + "\"RMLINE\"", "\"CAST\"", "\"RECORD\"", "\"INTEGER\"", "\"REAL\"", + "\"STRING\"", "\"REGEX\"", "\"FILE\"", "\"DATE\"", "\"TIME\"", + "\"DATETIME\"", "\"REFERENCE\"", "\"<=\"", "\">=\"", "\"=\"", "\"~=\"", + "\"<>\"", "\"AND\"", "\"OR\"", "\"NOT\"", "\"character\"", + "\"SET @VARIABLE\"", "\"DECLARE @VARIABLE\"", "\"ABORT\"", "\"ALTER\"", + "\"ANALYZE\"", "\"BEGIN\"", "\"CHECKPOINT\"", "\"CLOSE\"", "\"CLUSTER\"", + "\"COMMENT\"", "\"COMMIT\"", "\"COPY\"", "\"CREATE\"", "\"DEALLOCATE\"", + "\"DECLARE\"", "\"DELETE\"", "\"DISCARD\"", "\"DROP\"", "\"END\"", + "\"EXECUTE\"", "\"EXPLAIN\"", "\"FETCH\"", "\"GRANT\"", "\"INSERT\"", + "\"LISTEN\"", "\"LOAD\"", "\"LOCK\"", "\"MOVE\"", "\"NOTIFY\"", + "\"PREPARE\"", "\"REASSIGN\"", "\"REINDEX\"", "\"RELEASE\"", "\"RESET\"", + "\"REVOKE\"", "\"ROLLBACK\"", "\"SAVEPOINT\"", "\"SELECT\"", "\"SET\"", + "\"SHOW\"", "\"START\"", "\"TRUNCATE\"", "\"UNLISTEN\"", "\"UPDATE\"", + "\"VACUUM\"", "\"VALUES\"", "\"IDENTIFIER\"", "\"INTEGER VALUE\"", + "\"REAL VALUE\"", "\"STRING VALUE\"", "'['", "']'", "'('", "')'", "'+'", + "'-'", "'*'", "'/'", "'%'", "'<'", "'>'", "','", "';'", "'{'", "'}'", + "$accept", "postfix_expression", "unary_expression", "cast_expression", + "type_name", "multiplicative_expression", "additive_expression", + "relational_expression", "equality_expression", "logical_and_expression", + "logical_or_expression", "expression", "random_generator", "statement", + "statement_list", "compound_statement", "sql_statement", + "sql_expression", "sql_query", "declaration_statement", + "declaration_list", "declaration_element", "assign_statement", + "assign_list", "assign_element", "selection_statement", + "iteration_statement", "jump_statement", "procedure_statement", + "record_declaration_list", "translation_unit", 0 + }; +#endif + +#if YYDEBUG + /* YYRHS -- A `-1'-separated list of the rules' RHS. */ + const pgsParser::rhs_number_type + pgsParser::yyrhs_[] = + { + 135, 0, -1, 86, 90, 116, 91, 90, 116, 91, + -1, 86, 90, 116, 91, -1, 17, 92, 86, 93, + -1, 16, 92, 86, 93, -1, 18, 92, 116, 93, + -1, 86, -1, 87, -1, 88, -1, 89, -1, 92, + 77, 93, -1, 117, -1, 92, 116, 93, -1, 106, + -1, 94, 108, -1, 95, 108, -1, 38, 108, -1, + 107, -1, 20, 92, 108, 10, 109, 93, -1, 22, + -1, 23, -1, 24, -1, 21, -1, 108, -1, 110, + 96, 108, -1, 110, 97, 108, -1, 110, 98, 108, + -1, 110, -1, 111, 94, 110, -1, 111, 95, 110, + -1, 111, -1, 112, 99, 111, -1, 112, 100, 111, + -1, 112, 31, 111, -1, 112, 32, 111, -1, 112, + -1, 113, 33, 112, -1, 113, 34, 112, -1, 113, + 35, 112, -1, 113, -1, 114, 36, 113, -1, 114, + -1, 115, 37, 114, -1, 115, -1, 22, 92, 116, + 101, 116, 93, -1, 22, 92, 116, 101, 116, 101, + 116, 93, -1, 22, 92, 116, 101, 116, 101, 116, + 101, 116, 93, -1, 23, 92, 116, 101, 116, 101, + 116, 93, -1, 23, 92, 116, 101, 116, 101, 116, + 101, 116, 93, -1, 23, 92, 116, 101, 116, 101, + 116, 101, 116, 101, 116, 93, -1, 24, 92, 116, + 101, 116, 93, -1, 24, 92, 116, 101, 116, 101, + 116, 93, -1, 24, 92, 116, 101, 116, 101, 116, + 101, 116, 93, -1, 25, 92, 116, 93, -1, 25, + 92, 116, 101, 116, 93, -1, 26, 92, 116, 93, + -1, 26, 92, 116, 101, 116, 93, -1, 26, 92, + 116, 101, 116, 101, 116, 93, -1, 26, 92, 116, + 101, 116, 101, 116, 101, 116, 93, -1, 27, 92, + 116, 101, 116, 93, -1, 27, 92, 116, 101, 116, + 101, 116, 93, -1, 27, 92, 116, 101, 116, 101, + 116, 101, 116, 93, -1, 28, 92, 116, 101, 116, + 93, -1, 28, 92, 116, 101, 116, 101, 116, 93, + -1, 28, 92, 116, 101, 116, 101, 116, 101, 116, + 93, -1, 29, 92, 116, 101, 116, 93, -1, 29, + 92, 116, 101, 116, 101, 116, 93, -1, 29, 92, + 116, 101, 116, 101, 116, 101, 116, 93, -1, 30, + 92, 116, 101, 116, 93, -1, 30, 92, 116, 101, + 116, 101, 116, 93, -1, 30, 92, 116, 101, 116, + 101, 116, 101, 116, 93, -1, 120, -1, 130, -1, + 131, -1, 121, 102, -1, 133, 102, -1, 132, 102, + -1, 124, 102, -1, 127, 102, -1, 118, -1, 119, + 118, -1, 11, 12, -1, 11, 119, 12, -1, 122, + -1, 123, -1, 42, -1, 43, -1, 44, -1, 45, + -1, 46, -1, 47, -1, 48, -1, 49, -1, 50, + -1, 51, -1, 52, -1, 53, -1, 54, -1, 55, + -1, 56, -1, 57, -1, 58, -1, 59, -1, 60, + -1, 61, -1, 62, -1, 63, -1, 64, -1, 65, + -1, 66, -1, 67, -1, 68, -1, 69, -1, 70, + -1, 71, -1, 72, -1, 73, -1, 74, -1, 75, + -1, 76, -1, 77, -1, 78, -1, 79, -1, 80, + -1, 81, -1, 82, -1, 83, -1, 84, -1, 85, + -1, 41, 125, -1, 126, -1, 125, 101, 126, -1, + 86, -1, 86, 103, 134, 104, -1, 40, 128, -1, + 129, -1, 128, 101, 129, -1, 86, 33, 116, -1, + 86, 90, 116, 91, 90, 116, 91, 33, 116, -1, + 86, 33, 122, -1, 7, 116, 118, -1, 7, 116, + 118, 8, 118, -1, 3, 116, 118, -1, 4, -1, + 5, -1, 6, -1, 14, 116, -1, 13, 116, -1, + 19, 92, 86, 90, 116, 91, 93, -1, 86, -1, + 134, 101, 86, -1, 0, -1, 119, 0, -1 + }; + + /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ + const unsigned short int + pgsParser::yyprhs_[] = + { + 0, 0, 3, 11, 16, 21, 26, 31, 33, 35, + 37, 39, 43, 45, 49, 51, 54, 57, 60, 62, + 69, 71, 73, 75, 77, 79, 83, 87, 91, 93, + 97, 101, 103, 107, 111, 115, 119, 121, 125, 129, + 133, 135, 139, 141, 145, 147, 154, 163, 174, 183, + 194, 207, 214, 223, 234, 239, 246, 251, 258, 267, + 278, 285, 294, 305, 312, 321, 332, 339, 348, 359, + 366, 375, 386, 388, 390, 392, 395, 398, 401, 404, + 407, 409, 412, 415, 419, 421, 423, 425, 427, 429, + 431, 433, 435, 437, 439, 441, 443, 445, 447, 449, + 451, 453, 455, 457, 459, 461, 463, 465, 467, 469, + 471, 473, 475, 477, 479, 481, 483, 485, 487, 489, + 491, 493, 495, 497, 499, 501, 503, 505, 507, 509, + 511, 514, 516, 520, 522, 527, 530, 532, 536, 540, + 550, 554, 558, 564, 568, 570, 572, 574, 577, 580, + 588, 590, 594, 596 + }; + + /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ + const unsigned short int + pgsParser::yyrline_[] = + { + 0, 267, 267, 274, 281, 287, 293, 299, 305, 311, + 317, 323, 329, 330, 338, 339, 340, 345, 354, 355, + 364, 365, 366, 367, 371, 372, 379, 386, 396, 397, + 404, 414, 415, 422, 429, 436, 446, 447, 454, 461, + 471, 472, 482, 483, 493, 500, 508, 515, 522, 531, + 539, 547, 555, 562, 569, 575, 581, 589, 597, 604, + 611, 619, 626, 633, 641, 648, 655, 663, 670, 677, + 685, 693, 703, 704, 705, 706, 707, 708, 709, 710, + 714, 719, 727, 731, 739, 749, 758, 759, 760, 761, + 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, + 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, + 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, + 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, + 805, 812, 818, 827, 837, 852, 859, 864, 873, 886, + 901, 917, 929, 943, 956, 963, 970, 980, 990, 999, + 1015, 1019, 1027, 1028 + }; + + // Print the state stack on the debug stream. + void + pgsParser::yystack_print_ () + { + *yycdebug_ << "Stack now"; + for (state_stack_type::const_iterator i = yystate_stack_.begin (); + i != yystate_stack_.end (); ++i) + *yycdebug_ << ' ' << *i; + *yycdebug_ << std::endl; + } + + // Report on the debug stream that the rule \a yyrule is going to be reduced. + void + pgsParser::yy_reduce_print_ (int yyrule) + { + unsigned int yylno = yyrline_[yyrule]; + int yynrhs = yyr2_[yyrule]; + /* Print the symbols being reduced, and their result. */ + *yycdebug_ << "Reducing stack by rule " << yyrule - 1 + << " (line " << yylno << "), "; + /* The symbols being reduced. */ + for (int yyi = 0; yyi < yynrhs; yyi++) + YY_SYMBOL_PRINT (" $" << yyi + 1 << " =", + yyrhs_[yyprhs_[yyrule] + yyi], + &(yysemantic_stack_[(yynrhs) - (yyi + 1)]), + &(yylocation_stack_[(yynrhs) - (yyi + 1)])); + } +#endif // YYDEBUG + + /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ + pgsParser::token_number_type + pgsParser::yytranslate_ (int t) + { + static + const token_number_type + translate_table[] = + { + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 98, 2, 2, + 92, 93, 96, 94, 101, 95, 2, 97, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 102, + 99, 2, 100, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 90, 2, 91, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 103, 2, 104, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89 + }; + if ((unsigned int) t <= yyuser_token_number_max_) + return translate_table[t]; + else + return yyundef_token_; + } + + const int pgsParser::yyeof_ = 0; + const int pgsParser::yylast_ = 784; + const int pgsParser::yynnts_ = 31; + const int pgsParser::yyempty_ = -2; + const int pgsParser::yyfinal_ = 121; + const int pgsParser::yyterror_ = 1; + const int pgsParser::yyerrcode_ = 256; + const int pgsParser::yyntokens_ = 105; + + const unsigned int pgsParser::yyuser_token_number_max_ = 344; + const pgsParser::token_number_type pgsParser::yyundef_token_ = 2; + +} // namespace pgscript + +#line 1036 "pgscript/pgsParser.yy" + /*** Additional Code ***/ + +void pgscript::pgsParser::error(const pgsParser::location_type & l, + const std::string & m) +{ + wxLogScriptVerbose(wxT("EXPR STACK SIZE = %u"), driver.context.size_vars()); + wxLogScriptVerbose(wxT("STMT STACK SIZE = %u"), driver.context.size_stmts()); + driver.context.clear_stacks(); + driver.error(l, wxString(m.c_str(), wxConvUTF8)); +} + diff --git a/pgscript/pgsApplication.cpp b/pgscript/pgsApplication.cpp new file mode 100644 index 0000000..6d2a615 --- /dev/null +++ b/pgscript/pgsApplication.cpp @@ -0,0 +1,215 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/pgsApplication.h" + +#include "db/pgConn.h" +#include "pgscript/expressions/pgsAssign.h" +#include "pgscript/expressions/pgsIdent.h" +#include "pgscript/objects/pgsString.h" +#include "pgscript/utilities/pgsThread.h" + +pgsApplication::pgsApplication(const wxString &host, const wxString &database, + const wxString &user, const wxString &password, int port) : + m_mutex(1, 1), m_stream(1, 1), m_connection(pnew pgConn(host, wxEmptyString, wxEmptyString, database, user, + password, port)), m_defined_conn(true), m_thread(0), m_caller(0) +{ + if (m_connection->GetStatus() != PGCONN_OK) + { + wxLogError(wxT("PGSCRIPT: Cannot connect to database %s:%d/%s with ") + wxT("credentials '%s'/'%s'"), host.c_str(), port, database.c_str(), + user.c_str(), password.c_str()); + } + + wxLogScript(wxT("Application created")); +} + +pgsApplication::pgsApplication(pgConn *connection) : + m_mutex(1, 1), m_stream(1, 1), m_connection(connection), + m_defined_conn(false), m_thread(0), m_caller(0) +{ + wxLogScript(wxT("Application created")); +} + +pgsApplication::~pgsApplication() +{ + if (m_defined_conn) + { + pdelete(m_connection); + } + + wxLogScript(wxT("Application destroyed")); +} + +bool pgsApplication::ParseFile(const wxString &file, pgsOutputStream &out, + wxMBConv *conv) +{ + if (!IsRunning()) + { + m_last_error_line = -1; + m_thread = new pgsThread(m_vars, m_mutex, m_connection, + file, out, *this, conv); + return RunThread(); + } + else + { + return false; + } +} + +bool pgsApplication::ParseString(const wxString &string, + pgsOutputStream &out) +{ + if (!IsRunning()) + { + m_last_error_line = -1; + m_thread = new pgsThread(m_vars, m_mutex, m_connection, + string, out, *this); + return RunThread(); + } + else + { + return false; + } +} + +bool pgsApplication::RunThread() +{ + bool created = false; + + if (m_thread != 0 && m_thread->Create() == wxTHREAD_NO_ERROR) + { + m_thread->SetPriority(WXTHREAD_MIN_PRIORITY); + + if (m_thread->Run() == wxTHREAD_NO_ERROR) + { + created = true; + } + } + + if (created) + { + wxLogScript(wxT("Running...")); + return true; + } + else + { + wxLogError(wxT("PGSCRIPT: Thread error")); + pdelete(m_thread); + return false; + } +} + +bool pgsApplication::IsRunning() +{ + if (m_mutex.TryWait() == wxSEMA_NO_ERROR) + { + m_mutex.Post(); + return false; + } + else + { + return true; + } +} + +void pgsApplication::Wait() +{ + if (IsRunning()) + { + wxLogScript(wxT("Waiting for pgScript")); + m_mutex.Wait(); + m_mutex.Post(); + } +} + +void pgsApplication::Terminate() +{ + if (IsRunning()) + { + wxLogScript(wxT("Deleting pgScript")); + m_thread->Delete(); + } +} + +void pgsApplication::Complete() +{ + // If last_error_line() == -1 then there was no error + // Else get the line number where the error occurred + m_last_error_line = m_thread->last_error_line(); + +#if !defined(PGSCLI) + if (m_caller != 0) + { + wxCommandEvent resultEvent(wxEVT_COMMAND_MENU_SELECTED, m_event_id); + +#if wxCHECK_VERSION(2, 9, 0) + m_caller->GetEventHandler()->AddPendingEvent(resultEvent); +#else + m_caller->AddPendingEvent(resultEvent); +#endif + } +#endif // PGSCLI + + wxLogScript(wxT("Execution completed")); +} + +void pgsApplication::SetConnection(pgConn *conn) +{ + if (m_defined_conn) + { + pdelete(m_connection); + m_defined_conn = false; + } + + m_connection = conn; +} + +void pgsApplication::ClearSymbols() +{ + if (!IsRunning()) + { + m_vars.clear(); + } +} + +#if !defined(PGSCLI) +void pgsApplication::SetCaller(wxWindow *caller, long event_id) +{ + m_caller = caller; + m_event_id = event_id; +} +#endif // PGSCLI + +bool pgsApplication::IsConnectionValid() const +{ + return (m_connection->GetStatus() == PGCONN_OK); +} + +void pgsApplication::LockOutput() +{ + m_stream.Wait(); +} + +void pgsApplication::UnlockOutput() +{ + m_stream.Post(); +} + +bool pgsApplication::errorOccurred() const +{ + return (m_last_error_line != -1); +} + +int pgsApplication::errorLine() const +{ + return m_last_error_line; +} diff --git a/pgscript/pgsParser.yy b/pgscript/pgsParser.yy new file mode 100644 index 0000000..15e0391 --- /dev/null +++ b/pgscript/pgsParser.yy @@ -0,0 +1,1045 @@ +%{ /*** C/C++ Declarations ***/ + +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + +#include "pgscript/pgScript.h" +#include "pgscript/statements/pgsStatements.h" +#include "pgscript/expressions/pgsExpressions.h" +#include "pgscript/objects/pgsObjects.h" +#include "pgscript/utilities/pgsContext.h" + +%} + +/*** YACC/Bison declarations ***/ + +/* Require bison 2.3 or later */ +%require "2.3" + +/* Start symbol is named "start" */ +%start translation_unit + +/* Write out a header file containing the token defines */ +%defines + +/* Use newer C++ skeleton file */ +%skeleton "lalr1.cc" + +/* Namespace to enclose parser in */ +%name-prefix="pgscript" + +/* Set the parser's class identifier */ +%define "parser_class_name" "pgsParser" + +/* Keep track of the current position within the input */ +%locations +%initial-action +{ + // Initialize the initial location object + @$.begin.filename = @$.end.filename; +}; + +/* The driver is passed by reference to the parser and to the scanner. This + * provides a simple but effective pure interface, not relying on global + * variables. */ +%parse-param { class pgsDriver & driver } + +/* Verbose error messages */ +%error-verbose + +%token PGS_END 0 "END OF FILE" + +%token PGS_WHILE "WHILE" +%token PGS_BREAK "BREAK" +%token PGS_RETURN "RETURN" +%token PGS_CONTINUE "CONTINUE" +%token PGS_IF "IF" +%token PGS_ELSE "ELSE" +%token PGS_WAITFOR "WAITFOR" +%token PGS_AS "AS" + +%token PGS_OPEN "BEGIN (BLOCK)" +%token PGS_CLOSE "END (BLOCK)" + +%token PGS_ASSERT "ASSERT" +%token PGS_PRINT "PRINT" +%token PGS_LOG "LOG" + +%token PGS_CNT_COLUMNS "COLUMNS" +%token PGS_CNT_LINES "LINES" +%token PGS_TRIM "TRIM" +%token PGS_RM_LINE "RMLINE" +%token PGS_CAST "CAST" + +%token PGS_RECORD "RECORD" + +%token PGS_INTEGER "INTEGER" +%token PGS_REAL "REAL" +%token PGS_STRING "STRING" +%token PGS_REGEX "REGEX" +%token PGS_FILE "FILE" +%token PGS_DATE "DATE" +%token PGS_TIME "TIME" +%token PGS_DATE_TIME "DATETIME" +%token PGS_REFERENCE "REFERENCE" + +%token PGS_LE_OP "<=" +%token PGS_GE_OP ">=" +%token PGS_EQ_OP "=" +%token PGS_AE_OP "~=" +%token PGS_NE_OP "<>" +%token PGS_AND_OP "AND" +%token PGS_OR_OP "OR" +%token PGS_NOT_OP "NOT" + +%token PGS_UNKNOWN "character" + +%right PGS_ELSE + +%union +{ + const wxString * str; + int integer; + pgsExpression * expr; + pgsStmt * stmt; + pgsStmtList * stmt_list; +} + +%token PGS_SET_ASSIGN "SET @VARIABLE" +%token PGS_DECLARE_ASSGN "DECLARE @VARIABLE" + +%token PGS_ABORT "ABORT" +%token PGS_ALTER "ALTER" +%token PGS_ANALYZE "ANALYZE" +%token PGS_BEGIN "BEGIN" +%token PGS_CHECKPOINT "CHECKPOINT" +%token PGS_CLOSE_ST "CLOSE" +%token PGS_CLUSTER "CLUSTER" +%token PGS_COMMENT "COMMENT" +%token PGS_COMMIT "COMMIT" +%token PGS_COPY "COPY" +%token PGS_CREATE "CREATE" +%token PGS_DEALLOCATE "DEALLOCATE" +%token PGS_DECLARE "DECLARE" +%token PGS_DELETE "DELETE" +%token PGS_DISCARD "DISCARD" +%token PGS_DROP "DROP" +%token PGS_END_ST "END" +%token PGS_EXECUTE "EXECUTE" +%token PGS_EXPLAIN "EXPLAIN" +%token PGS_FETCH "FETCH" +%token PGS_GRANT "GRANT" +%token PGS_INSERT "INSERT" +%token PGS_LISTEN "LISTEN" +%token PGS_LOAD "LOAD" +%token PGS_LOCK "LOCK" +%token PGS_MOVE "MOVE" +%token PGS_NOTIFY "NOTIFY" +%token PGS_PREPARE "PREPARE" +%token PGS_REASSIGN "REASSIGN" +%token PGS_REINDEX "REINDEX" +%token PGS_RELEASE "RELEASE" +%token PGS_RESET "RESET" +%token PGS_REVOKE "REVOKE" +%token PGS_ROLLBACK "ROLLBACK" +%token PGS_SAVEPOINT "SAVEPOINT" +%token PGS_SELECT "SELECT" +%token PGS_SET "SET" +%token PGS_SHOW "SHOW" +%token PGS_START "START" +%token PGS_TRUNCATE "TRUNCATE" +%token PGS_UNLISTEN "UNLISTEN" +%token PGS_UPDATE "UPDATE" +%token PGS_VACUUM "VACUUM" +%token PGS_VALUES "VALUES" + +%token PGS_IDENTIFIER "IDENTIFIER" +%token PGS_VAL_INT "INTEGER VALUE" +%token PGS_VAL_REAL "REAL VALUE" +%token PGS_VAL_STR "STRING VALUE" + +%destructor { pdelete($$); } PGS_ABORT +%destructor { pdelete($$); } PGS_ALTER +%destructor { pdelete($$); } PGS_ANALYZE +%destructor { pdelete($$); } PGS_BEGIN +%destructor { pdelete($$); } PGS_CHECKPOINT +%destructor { pdelete($$); } PGS_CLOSE_ST +%destructor { pdelete($$); } PGS_CLUSTER +%destructor { pdelete($$); } PGS_COMMENT +%destructor { pdelete($$); } PGS_COMMIT +%destructor { pdelete($$); } PGS_COPY +%destructor { pdelete($$); } PGS_CREATE +%destructor { pdelete($$); } PGS_DEALLOCATE +%destructor { pdelete($$); } PGS_DECLARE +%destructor { pdelete($$); } PGS_DELETE +%destructor { pdelete($$); } PGS_DISCARD +%destructor { pdelete($$); } PGS_DROP +%destructor { pdelete($$); } PGS_END_ST +%destructor { pdelete($$); } PGS_EXECUTE +%destructor { pdelete($$); } PGS_EXPLAIN +%destructor { pdelete($$); } PGS_FETCH +%destructor { pdelete($$); } PGS_GRANT +%destructor { pdelete($$); } PGS_INSERT +%destructor { pdelete($$); } PGS_LISTEN +%destructor { pdelete($$); } PGS_LOAD +%destructor { pdelete($$); } PGS_LOCK +%destructor { pdelete($$); } PGS_MOVE +%destructor { pdelete($$); } PGS_NOTIFY +%destructor { pdelete($$); } PGS_PREPARE +%destructor { pdelete($$); } PGS_REASSIGN +%destructor { pdelete($$); } PGS_REINDEX +%destructor { pdelete($$); } PGS_RELEASE +%destructor { pdelete($$); } PGS_RESET +%destructor { pdelete($$); } PGS_REVOKE +%destructor { pdelete($$); } PGS_ROLLBACK +%destructor { pdelete($$); } PGS_SAVEPOINT +%destructor { pdelete($$); } PGS_SELECT +%destructor { pdelete($$); } PGS_SET +%destructor { pdelete($$); } PGS_SHOW +%destructor { pdelete($$); } PGS_START +%destructor { pdelete($$); } PGS_TRUNCATE +%destructor { pdelete($$); } PGS_UNLISTEN +%destructor { pdelete($$); } PGS_UPDATE +%destructor { pdelete($$); } PGS_VACUUM +%destructor { pdelete($$); } PGS_VALUES + +%destructor { pdelete($$); } PGS_IDENTIFIER +%destructor { pdelete($$); } PGS_VAL_INT +%destructor { pdelete($$); } PGS_VAL_REAL +%destructor { pdelete($$); } PGS_VAL_STR + +%type postfix_expression +%type unary_expression +%type cast_expression +%type multiplicative_expression +%type additive_expression +%type relational_expression +%type equality_expression +%type logical_and_expression +%type logical_or_expression +%type expression +%type random_generator +%type sql_expression + +%type sql_query +%type type_name + +%type statement + +%type compound_statement +%type sql_statement +%type selection_statement +%type iteration_statement +%type procedure_statement +%type jump_statement +%type declaration_statement +%type assign_statement + +%type declaration_list +%type assign_list +%type declaration_element +%type assign_element + +%type statement_list + +%{ + +#include "pgscript/utilities/pgsDriver.h" +#include "pgscript/utilities/pgsScanner.h" + +/* This "connects" the bison parser in the driver to the flex scanner class + * object. It defines the yylex() function call to pull the next token from the + * current lexer object of the driver context. */ +#undef yylex +#define yylex driver.lexer->lex + +%} + +%% /*** Grammar Rules ***/ + +postfix_expression + : PGS_IDENTIFIER '[' expression ']' '[' expression ']' + { + $$ = pnew pgsIdentRecord(*($1), $3, $6); + pdelete($1); + driver.context.pop_var(); driver.context.pop_var(); // $3 & $6 + driver.context.push_var($$); + } + | PGS_IDENTIFIER '[' expression ']' + { + $$ = pnew pgsIdentRecord(*($1), $3); + pdelete($1); + driver.context.pop_var(); // $3 + driver.context.push_var($$); + } + | PGS_CNT_LINES '(' PGS_IDENTIFIER ')' + { + $$ = pnew pgsLines(*($3)); + pdelete($3); + driver.context.push_var($$); + } + | PGS_CNT_COLUMNS '(' PGS_IDENTIFIER ')' + { + $$ = pnew pgsColumns(*($3)); + pdelete($3); + driver.context.push_var($$); + } + | PGS_TRIM '(' expression ')' + { + $$ = pnew pgsTrim($3); + driver.context.pop_var(); // $3 + driver.context.push_var($$); // assert + } + | PGS_IDENTIFIER + { + $$ = pnew pgsIdent(*($1)); + pdelete($1); + driver.context.push_var($$); + } + | PGS_VAL_INT + { + $$ = pnew pgsNumber(*($1), pgsInt); + pdelete($1); + driver.context.push_var($$); + } + | PGS_VAL_REAL + { + $$ = pnew pgsNumber(*($1), pgsReal); + pdelete($1); + driver.context.push_var($$); + } + | PGS_VAL_STR + { + $$ = pnew pgsString(*($1)); + pdelete($1); + driver.context.push_var($$); + } + | '(' PGS_SELECT ')' { + $$ = pnew pgsExecute(*($2), &driver.context.m_cout, + &(driver.thread)); + pdelete($2); + driver.context.push_var($$); // SQL Expression statement + } + | random_generator { $$ = $1; } + | '(' expression ')' { + $$ = pnew pgsParenthesis($2); + driver.context.pop_var(); // $2 + driver.context.push_var($$); + } + ; + +unary_expression + : postfix_expression { $$ = $1; } + | '+' cast_expression { $$ = $2; } + | '-' cast_expression { + $$ = pnew pgsNegate($2); + driver.context.pop_var(); // $2 + driver.context.push_var($$); + } + | PGS_NOT_OP cast_expression + { + $$ = pnew pgsNot($2); + driver.context.pop_var(); // $2 + driver.context.push_var($$); + } + ; + +cast_expression + : unary_expression { $$ = $1; } + | PGS_CAST '(' cast_expression PGS_AS type_name ')' + { + $$ = pnew pgsCast($5, $3); + driver.context.pop_var(); // $3 + driver.context.push_var($$); + } + ; + +type_name + : PGS_INTEGER { $$ = pgscript::pgsParser::token::PGS_INTEGER; } + | PGS_REAL { $$ = pgscript::pgsParser::token::PGS_REAL; } + | PGS_STRING { $$ = pgscript::pgsParser::token::PGS_STRING; } + | PGS_RECORD { $$ = pgscript::pgsParser::token::PGS_RECORD; } + ; + +multiplicative_expression + : cast_expression { $$ = $1; } + | multiplicative_expression '*' cast_expression + { + $$ = pnew pgsTimes($1, $3); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var($$); + } + | multiplicative_expression '/' cast_expression + { + $$ = pnew pgsOver($1, $3); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var($$); + } + | multiplicative_expression '%' cast_expression + { + $$ = pnew pgsModulo($1, $3); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var($$); + } + ; + +additive_expression + : multiplicative_expression { $$ = $1; } + | additive_expression '+' multiplicative_expression + { + $$ = pnew pgsPlus($1, $3); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var($$); + } + | additive_expression '-' multiplicative_expression + { + $$ = pnew pgsMinus($1, $3); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var($$); + } + ; + +relational_expression + : additive_expression { $$ = $1; } + | relational_expression '<' additive_expression + { + $$ = pnew pgsLower($1, $3); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var($$); + } + | relational_expression '>' additive_expression + { + $$ = pnew pgsGreater($1, $3); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var($$); + } + | relational_expression PGS_LE_OP additive_expression + { + $$ = pnew pgsLowerEqual($1, $3); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var($$); + } + | relational_expression PGS_GE_OP additive_expression + { + $$ = pnew pgsGreaterEqual($1, $3); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var($$); + } + ; + +equality_expression + : relational_expression { $$ = $1; } + | equality_expression PGS_EQ_OP relational_expression + { + $$ = pnew pgsEqual($1, $3); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var($$); + } + | equality_expression PGS_AE_OP relational_expression + { + $$ = pnew pgsEqual($1, $3, false); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var($$); + } + | equality_expression PGS_NE_OP relational_expression + { + $$ = pnew pgsDifferent($1, $3); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var($$); + } + ; + +logical_and_expression + : equality_expression { $$ = $1; } + | logical_and_expression PGS_AND_OP equality_expression + { + $$ = pnew pgsAnd($1, $3); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var($$); + } + ; + +logical_or_expression + : logical_and_expression { $$ = $1; } + | logical_or_expression PGS_OR_OP logical_and_expression + { + $$ = pnew pgsOr($1, $3); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var($$); + } + ; + +expression + : logical_or_expression { + wxLogScriptVerbose(wxT("%s"), $1->value().c_str()); + $$ = $1; + } + ; + +random_generator + : PGS_INTEGER '(' expression ',' expression ')' + { + $$ = pnew pgsGenInt($3, $5, driver.context.zero(), + driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_INTEGER '(' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenInt($3, $5, $7, driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_INTEGER '(' expression ',' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenInt($3, $5, $7, $9); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_REAL '(' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenReal($3, $5, $7, driver.context.zero(), + driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_REAL '(' expression ',' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenReal($3, $5, $7, $9, driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_REAL '(' expression ',' expression ',' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenReal($3, $5, $7, $9, $11); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_STRING '(' expression ',' expression ')' + { + $$ = pnew pgsGenString($3, $5, driver.context.one(), + driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_STRING '(' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenString($3, $5, $7, driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_STRING '(' expression ',' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenString($3, $5, $7, $9); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_REGEX '(' expression ')' + { + $$ = pnew pgsGenRegex($3, driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_REGEX '(' expression ',' expression ')' + { + $$ = pnew pgsGenRegex($3, $5); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_FILE '(' expression ')' + { + $$ = pnew pgsGenDictionary($3, driver.context.zero(), + driver.context.seed(), driver.context.encoding()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_FILE '(' expression ',' expression ')' + { + $$ = pnew pgsGenDictionary($3, $5, driver.context.seed(), + driver.context.encoding()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_FILE '(' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenDictionary($3, $5, $7, driver.context.encoding()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_FILE '(' expression ',' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenDictionary($3, $5, $7, $9); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_DATE '(' expression ',' expression ')' + { + $$ = pnew pgsGenDate($3, $5, driver.context.zero(), + driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_DATE '(' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenDate($3, $5, $7, driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_DATE '(' expression ',' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenDate($3, $5, $7, $9); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_TIME '(' expression ',' expression ')' + { + $$ = pnew pgsGenTime($3, $5, driver.context.zero(), + driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_TIME '(' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenTime($3, $5, $7, driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_TIME '(' expression ',' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenTime($3, $5, $7, $9); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_DATE_TIME '(' expression ',' expression ')' + { + $$ = pnew pgsGenDateTime($3, $5, driver.context.zero(), + driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_DATE_TIME '(' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenDateTime($3, $5, $7, driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_DATE_TIME '(' expression ',' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenDateTime($3, $5, $7, $9); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_REFERENCE '(' expression ',' expression ')' + { + $$ = pnew pgsGenReference($3, $5, driver.context.zero(), + driver.context.seed(), &(driver.thread)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_REFERENCE '(' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenReference($3, $5, $7, driver.context.seed(), + &(driver.thread)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_REFERENCE '(' expression ',' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenReference($3, $5, $7, $9, &(driver.thread)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + ; + +statement + : compound_statement { $$ = $1; } + | selection_statement { $$ = $1; } + | iteration_statement { $$ = $1; } + | sql_statement ';' { $$ = $1; } + | procedure_statement ';' { $$ = $1; } + | jump_statement ';' { $$ = $1; } + | declaration_statement ';' { $$ = $1; } + | assign_statement ';' { $$ = $1; } + ; + +statement_list + : statement { + driver.context.pop_stmt(); // $1 + $$ = driver.context.stmt_list(&(driver.thread)); + $$->insert_back($1); + } + | statement_list statement { + driver.context.pop_stmt(); // $2 + $$ = $1; + $$->insert_back($2); + } + ; + +compound_statement + : PGS_OPEN PGS_CLOSE { + wxLogScriptVerbose(wxT("BEGIN END")); + $$ = driver.context.stmt_list(&(driver.thread)); + } + | PGS_OPEN statement_list PGS_CLOSE + { + wxLogScriptVerbose(wxT("BEGIN ... END")); + $$ = $2; + } + ; + +sql_statement + : sql_expression { + wxLogScriptVerbose(wxT("%s"), $1->value().c_str()); + $$ = pnew pgsExpressionStmt($1, &(driver.thread)); + driver.context.pop_var(); // $1 + driver.context.push_stmt($$); // pgsExpressionStmt + $$->set_position(yyloc.begin.line); + } + ; + +sql_expression + : sql_query { + $$ = pnew pgsExecute(*($1), &driver.context.m_cout, + &(driver.thread)); + pdelete($1); + driver.context.push_var($$); // pgsExecute + } + ; + +sql_query + : PGS_ABORT { $$ = $1; } + | PGS_ALTER { $$ = $1; } + | PGS_ANALYZE { $$ = $1; } + | PGS_BEGIN { $$ = $1; } + | PGS_CHECKPOINT { $$ = $1; } + | PGS_CLOSE_ST { $$ = $1; } + | PGS_CLUSTER { $$ = $1; } + | PGS_COMMENT { $$ = $1; } + | PGS_COMMIT { $$ = $1; } + | PGS_COPY { $$ = $1; } + | PGS_CREATE { $$ = $1; } + | PGS_DEALLOCATE { $$ = $1; } + | PGS_DECLARE { $$ = $1; } + | PGS_DELETE { $$ = $1; } + | PGS_DISCARD { $$ = $1; } + | PGS_DROP { $$ = $1; } + | PGS_END_ST { $$ = $1; } + | PGS_EXECUTE { $$ = $1; } + | PGS_EXPLAIN { $$ = $1; } + | PGS_FETCH { $$ = $1; } + | PGS_GRANT { $$ = $1; } + | PGS_INSERT { $$ = $1; } + | PGS_LISTEN { $$ = $1; } + | PGS_LOAD { $$ = $1; } + | PGS_LOCK { $$ = $1; } + | PGS_MOVE { $$ = $1; } + | PGS_NOTIFY { $$ = $1; } + | PGS_PREPARE { $$ = $1; } + | PGS_REASSIGN { $$ = $1; } + | PGS_REINDEX { $$ = $1; } + | PGS_RELEASE { $$ = $1; } + | PGS_RESET { $$ = $1; } + | PGS_REVOKE { $$ = $1; } + | PGS_ROLLBACK { $$ = $1; } + | PGS_SAVEPOINT { $$ = $1; } + | PGS_SELECT { $$ = $1; } + | PGS_SET { $$ = $1; } + | PGS_SHOW { $$ = $1; } + | PGS_START { $$ = $1; } + | PGS_TRUNCATE { $$ = $1; } + | PGS_UNLISTEN { $$ = $1; } + | PGS_UPDATE { $$ = $1; } + | PGS_VACUUM { $$ = $1; } + | PGS_VALUES { $$ = $1; } + ; + +declaration_statement + : PGS_DECLARE_ASSGN declaration_list + { + $$ = $2; + } + ; + +declaration_list + : declaration_element { + driver.context.pop_stmt(); // $1 + $$ = driver.context.stmt_list(&(driver.thread)); + $$->insert_back($1); + + } + | declaration_list ',' declaration_element + { + driver.context.pop_stmt(); // $3 + $$ = $1; + $$->insert_back($3); + } + ; + +declaration_element + : PGS_IDENTIFIER { + wxLogScriptVerbose(wxT("DECLARE %s"), $1->c_str()); + + $$ = pnew pgsExpressionStmt(pnew pgsAssign(*($1), + pnew pgsString(wxT(""))), &(driver.thread)); + driver.context.push_stmt($$); // pgsExpressionStmt + $$->set_position(yyloc.begin.line); + + pdelete($1); + } + | PGS_IDENTIFIER '{' record_declaration_list '}' + { + wxLogScriptVerbose(wxT("DECLARE %s"), $1->c_str()); + + $$ = pnew pgsDeclareRecordStmt(*($1), driver.context.columns(), + &(driver.thread)); + driver.context.push_stmt($$); // pgsDeclareRecordStmt + $$->set_position(yyloc.begin.line); + + driver.context.clear_columns(); + pdelete($1); + } + ; + +assign_statement + : PGS_SET_ASSIGN assign_list + { + $$ = $2; + } + ; + +assign_list + : assign_element { + driver.context.pop_stmt(); // $1 + $$ = driver.context.stmt_list(&(driver.thread)); + $$->insert_back($1); + } + | assign_list ',' assign_element + { + driver.context.pop_stmt(); // $3 + $$ = $1; + $$->insert_back($3); + } + ; + +assign_element + : PGS_IDENTIFIER PGS_EQ_OP expression + { + wxLogScriptVerbose(wxT("SET %s = %s"), $1->c_str(), + $3->value().c_str()); + + $$ = pnew pgsExpressionStmt(pnew pgsAssign(*($1), $3), + &(driver.thread)); + driver.context.pop_var(); // $3 + driver.context.push_stmt($$); // pgsExpressionStmt + $$->set_position(yyloc.begin.line); + + pdelete($1); + } + | PGS_IDENTIFIER '[' expression ']' '[' expression ']' PGS_EQ_OP expression + { + wxLogScriptVerbose(wxT("SET %s[%s][%s] = %s"), + $1->c_str(), $3->value().c_str(), + $6->value().c_str(), $9->value().c_str()); + + $$ = pnew pgsExpressionStmt(pnew pgsAssignToRecord(*($1), + $3, $6, $9), &(driver.thread)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); // $3 & $6 & $9 + driver.context.push_stmt($$); // pgsExpressionStmt + $$->set_position(yyloc.begin.line); + + pdelete($1); + } + | PGS_IDENTIFIER PGS_EQ_OP sql_expression + { + wxLogScriptVerbose(wxT("SET %s = %s"), $1->c_str(), + $3->value().c_str()); + + $$ = pnew pgsExpressionStmt(pnew pgsAssign(*($1), $3), + &(driver.thread)); + driver.context.pop_var(); // $3 + driver.context.push_stmt($$); // pgsExpressionStmt + $$->set_position(yyloc.begin.line); + + pdelete($1); + } + ; + +selection_statement + : PGS_IF expression statement %prec PGS_ELSE + { + wxLogScriptVerbose(wxT("IF %s"), $2->value().c_str()); + + $$ = pnew pgsIfStmt($2, $3, driver.context + .stmt_list(&(driver.thread)), &(driver.thread)); + driver.context.pop_var(); // $2 + driver.context.pop_stmt(); // $3 + driver.context.pop_stmt(); // stmt_list + driver.context.push_stmt($$); // pgsIfStmt + $$->set_position(yyloc.begin.line); + } + | PGS_IF expression statement PGS_ELSE statement + { + wxLogScriptVerbose(wxT("IF %s"), $2->value().c_str()); + + $$ = pnew pgsIfStmt($2, $3, $5, &(driver.thread)); + driver.context.pop_var(); // $2 + driver.context.pop_stmt(); // $3 + driver.context.pop_stmt(); // $5 + driver.context.push_stmt($$); // pgsIfStmt + $$->set_position(yyloc.begin.line); + } + ; + +iteration_statement + : PGS_WHILE expression statement + { + wxLogScriptVerbose(wxT("WHILE %s"), $2->value().c_str()); + + $$ = pnew pgsWhileStmt($2, $3, &(driver.thread)); + driver.context.pop_var(); // $2 + driver.context.pop_stmt(); // $3 + driver.context.push_stmt($$); // pgsWhileStmt + $$->set_position(yyloc.begin.line); + } + ; + +jump_statement + : PGS_BREAK { + wxLogScriptVerbose(wxT("BREAK")); + + $$ = pnew pgsBreakStmt(&(driver.thread)); + driver.context.push_stmt($$); // pgsBreakStmt + $$->set_position(yyloc.begin.line); + } + | PGS_RETURN { + wxLogScriptVerbose(wxT("RETURN")); + + $$ = pnew pgsBreakStmt(&(driver.thread)); + driver.context.push_stmt($$); // pgsBreakStmt + $$->set_position(yyloc.begin.line); + } + | PGS_CONTINUE { + wxLogScriptVerbose(wxT("CONTINUE")); + + $$ = pnew pgsContinueStmt(&(driver.thread)); + driver.context.push_stmt($$); // pgsContinueStmt + $$->set_position(yyloc.begin.line); + } + ; + +procedure_statement + : PGS_PRINT expression + { + wxLogScriptVerbose(wxT("PRINT %s"), $2->value().c_str()); + + $$ = pnew pgsPrintStmt($2, driver.context.m_cout, + &(driver.thread)); + driver.context.pop_var(); // $2 + driver.context.push_stmt($$); // pgsPrintStmt + $$->set_position(yyloc.begin.line); + } + | PGS_ASSERT expression + { + wxLogScriptVerbose(wxT("ASSERT %s"), $2->value().c_str()); + + $$ = pnew pgsAssertStmt($2, &(driver.thread)); + driver.context.pop_var(); // $2 + driver.context.push_stmt($$); // pgsAssertStmt + $$->set_position(yyloc.begin.line); + } + | PGS_RM_LINE '(' PGS_IDENTIFIER '[' expression ']' ')' + { + wxLogScriptVerbose(wxT("RMLINE %s[%s]"), $3->c_str(), + $5->value().c_str()); + + $$ = pnew pgsExpressionStmt(pnew pgsRemoveLine(*($3), $5), + &(driver.thread)); + driver.context.pop_var(); // $5 + driver.context.push_stmt($$); // pgsExpressionStmt + $$->set_position(yyloc.begin.line); + + pdelete($3); + } + ; + +record_declaration_list + : PGS_IDENTIFIER { + driver.context.add_column(*$1); + pdelete($1); + } + | record_declaration_list ',' PGS_IDENTIFIER + { + driver.context.add_column(*$3); + pdelete($3); + } + ; + +translation_unit + : PGS_END + | statement_list PGS_END { + driver.program.eval($1); + + driver.context.pop_stmt(); + pdelete($1); // delete root statement $1 + } + ; + +%% /*** Additional Code ***/ + +void pgscript::pgsParser::error(const pgsParser::location_type & l, + const std::string & m) +{ + wxLogScriptVerbose(wxT("EXPR STACK SIZE = %u"), driver.context.size_vars()); + wxLogScriptVerbose(wxT("STMT STACK SIZE = %u"), driver.context.size_stmts()); + driver.context.clear_stacks(); + driver.error(l, wxString(m.c_str(), wxConvUTF8)); +} diff --git a/pgscript/pgsScanner.ll b/pgscript/pgsScanner.ll new file mode 100644 index 0000000..8449902 --- /dev/null +++ b/pgscript/pgsScanner.ll @@ -0,0 +1,421 @@ +L [a-zA-Z_@#] +D [0-9] +E [e-eE-E][+-]?{D}+ + +%{ /*** C/C++ Declarations ***/ + +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + +#include "pgscript/pgScript.h" +#include "pgscript/parser.tab.hh" +#include "pgscript/utilities/pgsScanner.h" + +/* Import the parser's token type into a local typedef */ +typedef pgscript::pgsParser::token token; +typedef pgscript::pgsParser::token_type token_type; + +/* Work around an incompatibility in flex (at least versions 2.5.31 through + * 2.5.33): it generates code that does not conform to C89. See Debian bug + * 333231 . */ +#undef yywrap +#define yywrap() 1 + +/* By default yylex returns int, we use token_type. Unfortunately yyterminate + * by default returns 0, which is not of token_type. */ +#define yyterminate() return token::PGS_END + +/* This disables inclusion of unistd.h, which is not available under Visual C++ + * on Win32. The C++ scanner uses STL streams instead. */ +#define YY_NO_UNISTD_H + +%} + +/*** Flex Declarations and Options ***/ + +/* Enable C++ scanner class generation */ +%option c++ + +/* Change the name of the scanner class. Results in "pgsFlexLexer" */ +%option prefix="pgs" + +/* Case insensitive */ +%option case-insensitive + +/* The manual says "somewhat more optimized" */ +%option batch + +/* Prevent isatty warning in VC++ */ +%option never-interactive + +/* For using start conditions */ +%option stack + +/* No support for include files is planned */ +%option noyywrap + +/* The following paragraph suffices to track locations accurately. Each time + * yylex is invoked, the begin position is moved onto the end position. */ +%{ +#define YY_USER_ACTION yylloc->columns(yyleng); +%} + +%x SC_COMMENT +%x SC_QUERY +%x SC_DOLLAR +%x SC_STRING + +%% /*** Regular Expressions Part ***/ + + /* Code to place at the beginning of yylex() */ +%{ + // Reset location + yylloc->step(); +%} + +"--".*$ { /* Ignore SQL comment */ } +"/*" { comment_caller = INITIAL; BEGIN(SC_COMMENT); } +"/*" { comment_caller = SC_QUERY; BEGIN(SC_COMMENT); } + +{ +"WHILE" { return token::PGS_WHILE; } +"BREAK" { return token::PGS_BREAK; } +"RETURN" { return token::PGS_RETURN; } +"CONTINUE" { return token::PGS_CONTINUE; } +"IF" { return token::PGS_IF; } +"ELSE" { return token::PGS_ELSE; } +"WAITFOR" { return token::PGS_WAITFOR; } +"AS" { return token::PGS_AS; } + +"ASSERT" { return token::PGS_ASSERT; } +"GO" { /* Ignore it */ } +"PRINT" { return token::PGS_PRINT; } + +"COLUMNS" { return token::PGS_CNT_COLUMNS; } +"LINES" { return token::PGS_CNT_LINES; } +"TRIM" { return token::PGS_TRIM; } +"RMLINE" { return token::PGS_RM_LINE; } +"CAST" { return token::PGS_CAST; } + +"RECORD" { return token::PGS_RECORD; } + +"INTEGER" { return token::PGS_INTEGER; } +"REAL" { return token::PGS_REAL; } +"STRING" { return token::PGS_STRING; } +"REGEX" { return token::PGS_REGEX; } +"FILE" { return token::PGS_FILE; } +"DATE" { return token::PGS_DATE; } +"TIME" { return token::PGS_TIME; } +"DATETIME" { return token::PGS_DATE_TIME; } +"REFERENCE" { return token::PGS_REFERENCE; } + + +"SET"[ \t]+"@" { unput('@'); yylloc->end.columns(-1); + return token::PGS_SET_ASSIGN; } +"DECLARE"[ \t]+"@" { unput('@'); yylloc->end.columns(-1); + return token::PGS_DECLARE_ASSGN; } + +"BEGIN" { /* Block opening */ return token::PGS_OPEN; } +"END" { /* Block closing */ return token::PGS_CLOSE; } + +"@"({L}|{D})* { yylval->str = pnew wxString(yytext, m_conv); + return token::PGS_IDENTIFIER; } + +{D}+ { yylval->str = pnew wxString(yytext, m_conv); + return token::PGS_VAL_INT; } + +{D}*"."{D}+({E})? { yylval->str = pnew wxString(yytext, m_conv); + return token::PGS_VAL_REAL; } +{D}+{E} { yylval->str = pnew wxString(yytext, m_conv); + return token::PGS_VAL_REAL; } +{D}+"."{D}*({E})? { yylval->str = pnew wxString(yytext, m_conv); + return token::PGS_VAL_REAL; } + +"AND" { return token::PGS_AND_OP; } +"OR" { return token::PGS_OR_OP; } +"<=" { return token::PGS_LE_OP; } +">=" { return token::PGS_GE_OP; } +"=" { return token::PGS_EQ_OP; } +"~=" { return token::PGS_AE_OP; } +"<>" { return token::PGS_NE_OP; } +";" { return wx_static_cast(token_type, ';'); } +("{"|"<%") { return wx_static_cast(token_type, '{'); } +("}"|"%>") { return wx_static_cast(token_type, '}'); } +":" { return wx_static_cast(token_type, ':'); } +"(" { return wx_static_cast(token_type, '('); } +")" { return wx_static_cast(token_type, ')'); } +("["|"<:") { return wx_static_cast(token_type, '['); } +("]"|":>") { return wx_static_cast(token_type, ']'); } +"." { return wx_static_cast(token_type, '.'); } +"," { return wx_static_cast(token_type, ','); } +"NOT" { return token::PGS_NOT_OP; } +"-" { return wx_static_cast(token_type, '-'); } +"+" { return wx_static_cast(token_type, '+'); } +"*" { return wx_static_cast(token_type, '*'); } +"/" { return wx_static_cast(token_type, '/'); } +"%" { return wx_static_cast(token_type, '%'); } +"<" { return wx_static_cast(token_type, '<'); } +">" { return wx_static_cast(token_type, '>'); } + +"'" { string_caller = INITIAL; BEGIN(SC_STRING); } + +"ABORT" { query += yytext; query_token = token::PGS_ABORT; + BEGIN(SC_QUERY); } +"ALTER" { query += yytext; query_token = token::PGS_ALTER; + BEGIN(SC_QUERY); } +"ANALYZE" { query += yytext; query_token = token::PGS_ANALYZE; + BEGIN(SC_QUERY); } +"BEGIN"[ \t]+"TRAN" { query += yytext; query_token = token::PGS_BEGIN; + BEGIN(SC_QUERY); } +"BEGIN"[ \t]+"WORK" { query += yytext; query_token = token::PGS_BEGIN; + BEGIN(SC_QUERY); } +"CHECKPOINT" { query += yytext; query_token = token::PGS_CHECKPOINT; + BEGIN(SC_QUERY); } +"CLOSE" { query += yytext; query_token = token::PGS_CLOSE_ST; + BEGIN(SC_QUERY); } +"CLUSTER" { query += yytext; query_token = token::PGS_CLUSTER; + BEGIN(SC_QUERY); } +"COMMENT" { query += yytext; query_token = token::PGS_COMMENT; + BEGIN(SC_QUERY); } +"COMMIT" { query += yytext; query_token = token::PGS_COMMIT; + BEGIN(SC_QUERY); } +"COPY" { query += yytext; query_token = token::PGS_COPY; + BEGIN(SC_QUERY); } +"CREATE" { query += yytext; query_token = token::PGS_CREATE; + BEGIN(SC_QUERY); } +"DEALLOCATE" { query += yytext; query_token = token::PGS_DEALLOCATE; + BEGIN(SC_QUERY); } +"DECLARE" { query += yytext; query_token = token::PGS_DECLARE; + BEGIN(SC_QUERY); } +"DELETE" { query += yytext; query_token = token::PGS_DELETE; + BEGIN(SC_QUERY); } +"DISCARD" { query += yytext; query_token = token::PGS_DISCARD; + BEGIN(SC_QUERY); } +"DROP" { query += yytext; query_token = token::PGS_DROP; + BEGIN(SC_QUERY); } +"END"[ \t]+"TRANS" { query += yytext; query_token = token::PGS_END_ST; + BEGIN(SC_QUERY); } +"END"[ \t]+"WORK" { query += yytext; query_token = token::PGS_END_ST; + BEGIN(SC_QUERY); } +"EXECUTE" { query += yytext; query_token = token::PGS_EXECUTE; + BEGIN(SC_QUERY); } +"EXPLAIN" { query += yytext; query_token = token::PGS_EXPLAIN; + BEGIN(SC_QUERY); } +"FETCH" { query += yytext; query_token = token::PGS_FETCH; + BEGIN(SC_QUERY); } +"GRANT" { query += yytext; query_token = token::PGS_GRANT; + BEGIN(SC_QUERY); } +"INSERT" { query += yytext; query_token = token::PGS_INSERT; + BEGIN(SC_QUERY); } +"LISTEN" { query += yytext; query_token = token::PGS_LISTEN; + BEGIN(SC_QUERY); } +"LOAD" { query += yytext; query_token = token::PGS_LOAD; + BEGIN(SC_QUERY); } +"LOCK" { query += yytext; query_token = token::PGS_LOCK; + BEGIN(SC_QUERY); } +"MOVE" { query += yytext; query_token = token::PGS_MOVE; + BEGIN(SC_QUERY); } +"NOTIFY" { query += yytext; query_token = token::PGS_NOTIFY; + BEGIN(SC_QUERY); } +"PREPARE" { query += yytext; query_token = token::PGS_PREPARE; + BEGIN(SC_QUERY); } +"REASSIGN" { query += yytext; query_token = token::PGS_REASSIGN; + BEGIN(SC_QUERY); } +"REINDEX" { query += yytext; query_token = token::PGS_REINDEX; + BEGIN(SC_QUERY); } +"RELEASE" { query += yytext; query_token = token::PGS_RELEASE; + BEGIN(SC_QUERY); } +"RESET" { query += yytext; query_token = token::PGS_RESET; + BEGIN(SC_QUERY); } +"REVOKE" { query += yytext; query_token = token::PGS_REVOKE; + BEGIN(SC_QUERY); } +"ROLLBACK" { query += yytext; query_token = token::PGS_ROLLBACK; + BEGIN(SC_QUERY); } +"SAVEPOINT" { query += yytext; query_token = token::PGS_SAVEPOINT; + BEGIN(SC_QUERY); } +"SELECT" { query += yytext; query_token = token::PGS_SELECT; + BEGIN(SC_QUERY); } +"SET" { query += yytext; query_token = token::PGS_SET; + BEGIN(SC_QUERY); } +"SHOW" { query += yytext; query_token = token::PGS_SHOW; + BEGIN(SC_QUERY); } +"START" { query += yytext; query_token = token::PGS_START; + BEGIN(SC_QUERY); } +"TRUNCATE" { query += yytext; query_token = token::PGS_TRUNCATE; + BEGIN(SC_QUERY); } +"UNLISTEN" { query += yytext; query_token = token::PGS_UNLISTEN; + BEGIN(SC_QUERY); } +"UPDATE" { query += yytext; query_token = token::PGS_UPDATE; + BEGIN(SC_QUERY); } +"VACUUM" { query += yytext; query_token = token::PGS_VACUUM; + BEGIN(SC_QUERY); } +"VALUES" { query += yytext; query_token = token::PGS_VALUES; + BEGIN(SC_QUERY); } + +[ \t\v\f]+ { } +\r { yylloc->step(); } +\n { yylloc->lines(yyleng); yylloc->step(); } +. { return token::PGS_UNKNOWN; } +} + +{ +"'" { query += yytext; string_caller = SC_QUERY; BEGIN(SC_STRING); } +\$({L}|{D})*\$ { query += yytext; dollar = yytext; BEGIN(SC_DOLLAR); } +";" { yylval->str = pnew wxString(query.c_str(), m_conv); + query.clear(); unput(';'); yylloc->end.columns(-1); + BEGIN(INITIAL); m_parent = 0; return query_token; } +"(" { ++m_parent; query += yytext; } +")" { + --m_parent; + if (m_parent == -1) + { + yylval->str = pnew wxString(query.c_str(), m_conv); + query.clear(); unput(')'); yylloc->end.columns(-1); + BEGIN(INITIAL); m_parent = 0; return query_token; + } + else + { + query += yytext; + } + } +\r { query += yytext; yylloc->step(); } +\n { query += yytext; yylloc->lines(yyleng); yylloc->step(); } +<> { yylval->str = pnew wxString(query.c_str(), m_conv); + query.clear(); m_parent = 0; return query_token; } +. { yylloc->columns(columns(*yytext)); query += yytext; } +} + +{ +\$({L}|{D})*\$ { query += yytext; + if (std::string(yytext) == dollar) BEGIN(SC_QUERY); } +\r { query += yytext; yylloc->step(); } +\n { query += yytext; yylloc->lines(yyleng); yylloc->step(); } +<> { query += yytext; yylval->str = pnew wxString(query.c_str(), m_conv); + query.clear(); m_parent = 0; return query_token; } +. { yylloc->columns(columns(*yytext)); query += yytext; } +} + +{ +"*/" { BEGIN(comment_caller); } +\r { yylloc->step(); } +\n { yylloc->lines(yyleng); yylloc->step(); } +. { yylloc->columns(columns(*yytext)); } +} + +{ +"''" { + if (string_caller == SC_QUERY) + query += yytext; + else + str += "'"; + } +\\. { + if (string_caller == SC_QUERY) + query += yytext; + else + str += *(yytext + 1); + yylloc->columns(columns(*(yytext + 1))); + } +"'" { + if (string_caller == SC_QUERY) + { + query += yytext; + BEGIN(string_caller); + } + else + { + yylval->str = pnew wxString(str.c_str(), m_conv); + str.clear(); + BEGIN(string_caller); + return token::PGS_VAL_STR; + } + } +\r { + if (string_caller == SC_QUERY) + query += yytext; + else + str += yytext; + yylloc->step(); + } +\n { + if (string_caller == SC_QUERY) + query += yytext; + else + str += yytext; + yylloc->lines(yyleng); yylloc->step(); + } +<> { + if (string_caller == SC_QUERY) + { + query += yytext; yylval->str = pnew wxString(query.c_str(), m_conv); + query.clear(); m_parent = 0; return query_token; + } + else + { + yylval->str = pnew wxString(str.c_str(), m_conv); + str.clear(); + BEGIN(string_caller); + return token::PGS_VAL_STR; + } + } +. { + if (string_caller == SC_QUERY) + query += yytext; + else + str += yytext; + yylloc->columns(columns(*yytext)); + } +} + +%% /*** Additional Code ***/ + +namespace pgscript +{ + +pgsScanner::pgsScanner(wxMBConv & conv, std::istream * in, std::ostream * out) : + pgsFlexLexer(in, out), m_parent(0), m_conv(conv) +{ + +} + +pgsScanner::~pgsScanner() +{ + +} + +void pgsScanner::set_debug(bool b) +{ + yy_flex_debug = b; +} + +int pgsScanner::columns(const char & c) +{ + if ((c & 0xF0) == 0xF0) // 4 bytes + return -3; + else if ((c & 0xE0) == 0xE0) // 3 bytes + return -2; + else if ((c & 0xC0) == 0xC0) // 2 bytes + return -1; + else return 0; +} + +} + +/* This implementation of pgsFlexLexer::yylex() is required to fill the + * vtable of the class pgsFlexLexer. We define the scanner's main yylex + * function via YY_DECL to reside in the pgsScanner class instead. */ + +#ifdef yylex +#undef yylex +#endif + +int pgsFlexLexer::yylex() +{ + return 0; +} diff --git a/pgscript/statements/module.mk b/pgscript/statements/module.mk new file mode 100644 index 0000000..c5754d8 --- /dev/null +++ b/pgscript/statements/module.mk @@ -0,0 +1,27 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/pgscript/statements/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + pgscript/statements/pgsAssertStmt.cpp \ + pgscript/statements/pgsBreakStmt.cpp \ + pgscript/statements/pgsContinueStmt.cpp \ + pgscript/statements/pgsDeclareRecordStmt.cpp \ + pgscript/statements/pgsExpressionStmt.cpp \ + pgscript/statements/pgsIfStmt.cpp \ + pgscript/statements/pgsPrintStmt.cpp \ + pgscript/statements/pgsProgram.cpp \ + pgscript/statements/pgsStmt.cpp \ + pgscript/statements/pgsStmtList.cpp \ + pgscript/statements/pgsWhileStmt.cpp + +EXTRA_DIST += \ + pgscript/statements/module.mk + diff --git a/pgscript/statements/pgsAssertStmt.cpp b/pgscript/statements/pgsAssertStmt.cpp new file mode 100644 index 0000000..e86f9f7 --- /dev/null +++ b/pgscript/statements/pgsAssertStmt.cpp @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/statements/pgsAssertStmt.h" + +#include "pgscript/exceptions/pgsAssertException.h" + +pgsAssertStmt::pgsAssertStmt(const pgsExpression *cond, pgsThread *app) : + pgsStmt(app), m_cond(cond) +{ + +} + +pgsAssertStmt::~pgsAssertStmt() +{ + pdelete(m_cond); +} + +void pgsAssertStmt::eval(pgsVarMap &vars) const +{ + pgsOperand result = m_cond->eval(vars); + if (!result->pgs_is_true()) + { + throw pgsAssertException(m_cond->value()); + } +} diff --git a/pgscript/statements/pgsBreakStmt.cpp b/pgscript/statements/pgsBreakStmt.cpp new file mode 100644 index 0000000..c7057cf --- /dev/null +++ b/pgscript/statements/pgsBreakStmt.cpp @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/statements/pgsBreakStmt.h" + +#include "pgscript/exceptions/pgsBreakException.h" + +pgsBreakStmt::pgsBreakStmt(pgsThread *app) : + pgsStmt(app) +{ + +} + +pgsBreakStmt::~pgsBreakStmt() +{ + +} + +void pgsBreakStmt::eval(pgsVarMap &vars) const +{ + throw pgsBreakException(); +} diff --git a/pgscript/statements/pgsContinueStmt.cpp b/pgscript/statements/pgsContinueStmt.cpp new file mode 100644 index 0000000..2e716b5 --- /dev/null +++ b/pgscript/statements/pgsContinueStmt.cpp @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/statements/pgsContinueStmt.h" + +#include "pgscript/exceptions/pgsContinueException.h" + +pgsContinueStmt::pgsContinueStmt(pgsThread *app) : + pgsStmt(app) +{ + +} + +pgsContinueStmt::~pgsContinueStmt() +{ + +} + +void pgsContinueStmt::eval(pgsVarMap &vars) const +{ + throw pgsContinueException(); +} diff --git a/pgscript/statements/pgsDeclareRecordStmt.cpp b/pgscript/statements/pgsDeclareRecordStmt.cpp new file mode 100644 index 0000000..c3d54b1 --- /dev/null +++ b/pgscript/statements/pgsDeclareRecordStmt.cpp @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/statements/pgsDeclareRecordStmt.h" + +#include "pgscript/objects/pgsRecord.h" + +pgsDeclareRecordStmt::pgsDeclareRecordStmt(const wxString &rec, + const wxArrayString &columns, pgsThread *app) : + pgsStmt(app), m_rec(rec), m_columns(columns) +{ + +} + +pgsDeclareRecordStmt::~pgsDeclareRecordStmt() +{ + +} + +void pgsDeclareRecordStmt::eval(pgsVarMap &vars) const +{ + pgsRecord *rec = pnew pgsRecord(m_columns.size()); + for (size_t i = 0; i < m_columns.GetCount(); i++) + { + rec->set_column_name(i, m_columns.Item(i)); + } + vars[m_rec] = rec; +} diff --git a/pgscript/statements/pgsExpressionStmt.cpp b/pgscript/statements/pgsExpressionStmt.cpp new file mode 100644 index 0000000..85e8a7f --- /dev/null +++ b/pgscript/statements/pgsExpressionStmt.cpp @@ -0,0 +1,28 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/statements/pgsExpressionStmt.h" + +pgsExpressionStmt::pgsExpressionStmt(const pgsExpression *var, pgsThread *app) : + pgsStmt(app), m_var(var) +{ + +} + +pgsExpressionStmt::~pgsExpressionStmt() +{ + pdelete(m_var) +} + +void pgsExpressionStmt::eval(pgsVarMap &vars) const +{ + m_var->eval(vars); +} diff --git a/pgscript/statements/pgsIfStmt.cpp b/pgscript/statements/pgsIfStmt.cpp new file mode 100644 index 0000000..6b95095 --- /dev/null +++ b/pgscript/statements/pgsIfStmt.cpp @@ -0,0 +1,39 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/statements/pgsIfStmt.h" + +pgsIfStmt::pgsIfStmt(const pgsExpression *cond, const pgsStmt *stmt_list_if, + const pgsStmt *stmt_list_else, pgsThread *app) : + pgsStmt(app), m_cond(cond), m_stmt_list_if(stmt_list_if), + m_stmt_list_else(stmt_list_else) +{ + +} + +pgsIfStmt::~pgsIfStmt() +{ + pdelete(m_cond); + pdelete(m_stmt_list_if); + pdelete(m_stmt_list_else); +} + +void pgsIfStmt::eval(pgsVarMap &vars) const +{ + if (m_cond->eval(vars)->pgs_is_true()) + { + m_stmt_list_if->eval(vars); + } + else + { + m_stmt_list_else->eval(vars); + } +} diff --git a/pgscript/statements/pgsPrintStmt.cpp b/pgscript/statements/pgsPrintStmt.cpp new file mode 100644 index 0000000..662ad67 --- /dev/null +++ b/pgscript/statements/pgsPrintStmt.cpp @@ -0,0 +1,56 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/statements/pgsPrintStmt.h" + +#include "pgscript/exceptions/pgsException.h" +#include "pgscript/utilities/pgsThread.h" +#include "pgscript/utilities/pgsUtilities.h" + +pgsPrintStmt::pgsPrintStmt(const pgsExpression *var, pgsOutputStream &cout, + pgsThread *app) : + pgsStmt(app), m_var(var), m_cout(cout) +{ + +} + +pgsPrintStmt::~pgsPrintStmt() +{ + pdelete(m_var); +} + +void pgsPrintStmt::eval(pgsVarMap &vars) const +{ + if (m_app != 0) + { + m_app->LockOutput(); + } + + try + { + m_cout << PGSOUTPGSCRIPT << wx_static_cast(const wxString, + m_var->eval(vars)->value()) << wxT("\n"); + } + catch (const pgsException &) + { + if (m_app != 0) + { + m_app->UnlockOutput(); + } + + throw; + } + + if (m_app != 0) + { + m_app->UnlockOutput(); + } +} diff --git a/pgscript/statements/pgsProgram.cpp b/pgscript/statements/pgsProgram.cpp new file mode 100644 index 0000000..744634f --- /dev/null +++ b/pgscript/statements/pgsProgram.cpp @@ -0,0 +1,63 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/statements/pgsProgram.h" + +#include "pgscript/exceptions/pgsException.h" +#include "pgscript/statements/pgsStmtList.h" + +pgsProgram::pgsProgram(pgsVarMap &vars) : + m_vars(vars) +{ + +} + +pgsProgram::~pgsProgram() +{ + +} + +void pgsProgram::dump() +{ + dump(m_vars); +} + +void pgsProgram::dump(const pgsVarMap &vars) +{ + pgsVarMap::const_iterator it; + for (it = vars.begin(); it != vars.end(); it++) + { + wxLogMessage(wxString() << it->first << wxT(" -> ") + << it->second->value()); + } +} + +void pgsProgram::eval(pgsStmtList *stmt_list) +{ + wxLogScript(wxT("Entering program")); + + try + { + stmt_list->eval(m_vars); + } + catch (const pgsException &) + { + + } + catch (const std::exception &) + { + + } + + pgsStmtList::m_exception_thrown = false; + + wxLogScript(wxT("Leaving program")); +} diff --git a/pgscript/statements/pgsStmt.cpp b/pgscript/statements/pgsStmt.cpp new file mode 100644 index 0000000..4a29d91 --- /dev/null +++ b/pgscript/statements/pgsStmt.cpp @@ -0,0 +1,33 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/statements/pgsStmt.h" + +pgsStmt::pgsStmt(pgsThread *app) : + m_line(0), m_app(app) +{ + +} + +pgsStmt::~pgsStmt() +{ + +} + +void pgsStmt::set_position(int line) +{ + m_line = line; +} + +int pgsStmt::line() const +{ + return m_line; +} diff --git a/pgscript/statements/pgsStmtList.cpp b/pgscript/statements/pgsStmtList.cpp new file mode 100644 index 0000000..121702f --- /dev/null +++ b/pgscript/statements/pgsStmtList.cpp @@ -0,0 +1,115 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/statements/pgsStmtList.h" + +#include +#include "pgscript/exceptions/pgsBreakException.h" +#include "pgscript/exceptions/pgsContinueException.h" +#include "pgscript/exceptions/pgsInterruptException.h" +#include "pgscript/utilities/pgsThread.h" +#include "pgscript/utilities/pgsUtilities.h" + +#include +WX_DEFINE_LIST(pgsListStmt); + +bool pgsStmtList::m_exception_thrown = false; + +pgsStmtList::pgsStmtList(pgsOutputStream &cout, pgsThread *app) : + pgsStmt(app), m_cout(cout) +{ + +} + +pgsStmtList::~pgsStmtList() +{ + pgsListStmt::iterator it; + for (it = m_stmt_list.begin(); it != m_stmt_list.end(); it++) + { + pdelete(*it); + } +} + +void pgsStmtList::eval(pgsVarMap &vars) const +{ + pgsListStmt::const_iterator it; + for (it = m_stmt_list.begin(); it != m_stmt_list.end(); it++) + { + pgsStmt *current = *it; + + try + { + current->eval(vars); + + if (m_app != 0 && m_app->TestDestroy()) + throw pgsInterruptException(); + } + catch (const pgsException &e) + { + if (!m_exception_thrown && (typeid(e) != typeid(pgsBreakException)) + && (typeid(e) != typeid(pgsContinueException))) + { + if (m_app != 0) + { + m_app->LockOutput(); + m_app->last_error_line(current->line()); + } + + m_cout << wx_static_cast(const wxString, e.message()) + << wxT(" on line ") << current->line() << wxT("\n"); + m_exception_thrown = true; + + if (m_app != 0) + { + m_app->UnlockOutput(); + } + } + throw; + } + catch (const std::exception &e) + { + if (!m_exception_thrown) + { + if (m_app != 0) + { + m_app->LockOutput(); + m_app->last_error_line(current->line()); + } + + m_cout << PGSOUTERROR << _("Unknown exception:\n") + << wx_static_cast(const wxString, + wxString(e.what(), wxConvUTF8)); + m_exception_thrown = true; + + if (m_app != 0) + { + m_app->UnlockOutput(); + } + } + throw; + } + + if (m_app != 0) + { + m_app->Yield(); + } + } +} + +void pgsStmtList::insert_front(pgsStmt *stmt) +{ + m_stmt_list.push_front(stmt); +} + +void pgsStmtList::insert_back(pgsStmt *stmt) +{ + m_stmt_list.push_back(stmt); +} diff --git a/pgscript/statements/pgsWhileStmt.cpp b/pgscript/statements/pgsWhileStmt.cpp new file mode 100644 index 0000000..996b75a --- /dev/null +++ b/pgscript/statements/pgsWhileStmt.cpp @@ -0,0 +1,56 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/statements/pgsWhileStmt.h" + +#include "pgscript/exceptions/pgsBreakException.h" +#include "pgscript/exceptions/pgsContinueException.h" +#include "pgscript/exceptions/pgsInterruptException.h" +#include "pgscript/utilities/pgsThread.h" + +pgsWhileStmt::pgsWhileStmt(const pgsExpression *cond, const pgsStmt *stmt_list, + pgsThread *app) : + pgsStmt(app), m_cond(cond), m_stmt_list(stmt_list) +{ + +} + +pgsWhileStmt::~pgsWhileStmt() +{ + pdelete(m_cond); + pdelete(m_stmt_list); +} + +void pgsWhileStmt::eval(pgsVarMap &vars) const +{ +loop: + if (m_cond->eval(vars)->pgs_is_true()) + { + try + { + m_stmt_list->eval(vars); + } + catch (const pgsBreakException &) + { + goto end; + } + catch (const pgsContinueException &) + { + + } + if (m_app != 0 && m_app->TestDestroy()) + throw pgsInterruptException(); + + goto loop; + } +end: + ; +} diff --git a/pgscript/utilities/m_apm/mapm5sin.cpp b/pgscript/utilities/m_apm/mapm5sin.cpp new file mode 100644 index 0000000..c111c52 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm5sin.cpp @@ -0,0 +1,154 @@ + +/* + * M_APM - mapm5sin.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the functions that implement the sin (5x) + * and cos (4x) multiple angle relations + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +void M_5x_sin(M_APM r, int places, M_APM x) +{ + M_APM tmp8, tmp9; + + tmp8 = M_get_stack_var(); + tmp9 = M_get_stack_var(); + + m_apm_multiply(tmp9, x, MM_5x_125R); /* 1 / (5*5*5) */ + M_raw_sin(tmp8, (places + 6), tmp9); + M_5x_do_it(tmp9, (places + 4), tmp8); + M_5x_do_it(tmp8, (places + 4), tmp9); + M_5x_do_it(r, places, tmp8); + + M_restore_stack(2); +} +/****************************************************************************/ +void M_4x_cos(M_APM r, int places, M_APM x) +{ + M_APM tmp8, tmp9; + + tmp8 = M_get_stack_var(); + tmp9 = M_get_stack_var(); + + /* + * if |x| >= 1.0 use multiple angle identity 4 times + * if |x| < 1.0 use multiple angle identity 3 times + */ + + if (x->m_apm_exponent > 0) + { + m_apm_multiply(tmp9, x, MM_5x_256R); /* 1 / (4*4*4*4) */ + M_raw_cos(tmp8, (places + 8), tmp9); + M_4x_do_it(tmp9, (places + 8), tmp8); + M_4x_do_it(tmp8, (places + 6), tmp9); + M_4x_do_it(tmp9, (places + 4), tmp8); + M_4x_do_it(r, places, tmp9); + } + else + { + m_apm_multiply(tmp9, x, MM_5x_64R); /* 1 / (4*4*4) */ + M_raw_cos(tmp8, (places + 6), tmp9); + M_4x_do_it(tmp9, (places + 4), tmp8); + M_4x_do_it(tmp8, (places + 4), tmp9); + M_4x_do_it(r, places, tmp8); + } + + M_restore_stack(2); +} +/****************************************************************************/ +/* + * calculate the multiple angle identity for sin (5x) + * + * sin (5x) == 16 * sin^5 (x) - 20 * sin^3 (x) + 5 * sin(x) + */ +void M_5x_do_it(M_APM rr, int places, M_APM xx) +{ + M_APM tmp0, tmp1, t2, t3, t5; + + tmp0 = M_get_stack_var(); + tmp1 = M_get_stack_var(); + t2 = M_get_stack_var(); + t3 = M_get_stack_var(); + t5 = M_get_stack_var(); + + m_apm_multiply(tmp1, xx, xx); + m_apm_round(t2, (places + 4), tmp1); /* x ^ 2 */ + + m_apm_multiply(tmp1, t2, xx); + m_apm_round(t3, (places + 4), tmp1); /* x ^ 3 */ + + m_apm_multiply(t5, t2, t3); /* x ^ 5 */ + + m_apm_multiply(tmp0, xx, MM_Five); + m_apm_multiply(tmp1, t5, MM_5x_Sixteen); + m_apm_add(t2, tmp0, tmp1); + m_apm_multiply(tmp1, t3, MM_5x_Twenty); + m_apm_subtract(tmp0, t2, tmp1); + + m_apm_round(rr, places, tmp0); + M_restore_stack(5); +} +/****************************************************************************/ +/* + * calculate the multiple angle identity for cos (4x) + * + * cos (4x) == 8 * [ cos^4 (x) - cos^2 (x) ] + 1 + */ +void M_4x_do_it(M_APM rr, int places, M_APM xx) +{ + M_APM tmp0, tmp1, t2, t4; + + tmp0 = M_get_stack_var(); + tmp1 = M_get_stack_var(); + t2 = M_get_stack_var(); + t4 = M_get_stack_var(); + + m_apm_multiply(tmp1, xx, xx); + m_apm_round(t2, (places + 4), tmp1); /* x ^ 2 */ + m_apm_multiply(t4, t2, t2); /* x ^ 4 */ + + m_apm_subtract(tmp0, t4, t2); + m_apm_multiply(tmp1, tmp0, MM_5x_Eight); + m_apm_add(tmp0, MM_One, tmp1); + m_apm_round(rr, places, tmp0); + M_restore_stack(4); +} +/****************************************************************************/ +/* + * compute r = sqrt(1 - a ^ 2). + */ +void M_cos_to_sin(M_APM r, int places, M_APM a) +{ + M_APM tmp1, tmp2; + + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + + m_apm_multiply(tmp1, a, a); + m_apm_subtract(tmp2, MM_One, tmp1); + m_apm_sqrt(r, places, tmp2); + M_restore_stack(2); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapm_add.cpp b/pgscript/utilities/m_apm/mapm_add.cpp new file mode 100644 index 0000000..12c4bc5 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_add.cpp @@ -0,0 +1,329 @@ + +/* + * M_APM - mapm_add.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the functions that implement the sin (5x) + * and cos (4x) multiple angle relations + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +static M_APM M_work1 = NULL; +static M_APM M_work2 = NULL; +static int M_add_firsttime = TRUE; + +/****************************************************************************/ +void M_free_all_add() +{ + if (M_add_firsttime == FALSE) + { + m_apm_free(M_work1); + m_apm_free(M_work2); + M_add_firsttime = TRUE; + } +} +/****************************************************************************/ +void m_apm_add(M_APM r, M_APM a, M_APM b) +{ + int j, carry, sign, aexp, bexp, adigits, bdigits; + + if (M_add_firsttime) + { + M_add_firsttime = FALSE; + M_work1 = m_apm_init(); + M_work2 = m_apm_init(); + } + + if (a->m_apm_sign == 0) + { + m_apm_copy(r, b); + return; + } + + if (b->m_apm_sign == 0) + { + m_apm_copy(r, a); + return; + } + + if (a->m_apm_sign == 1 && b->m_apm_sign == -1) + { + b->m_apm_sign = 1; + m_apm_subtract(r, a, b); + b->m_apm_sign = -1; + return; + } + + if (a->m_apm_sign == -1 && b->m_apm_sign == 1) + { + a->m_apm_sign = 1; + m_apm_subtract(r, b, a); + a->m_apm_sign = -1; + return; + } + + sign = a->m_apm_sign; /* signs are the same, result will be same */ + + aexp = a->m_apm_exponent; + bexp = b->m_apm_exponent; + + m_apm_copy(M_work1, a); + m_apm_copy(M_work2, b); + + /* + * scale by at least 1 factor of 10 in case the MSB carrys + */ + + if (aexp == bexp) + { + M_apm_scale(M_work1, 2); /* shift 2 digits == 1 byte for efficiency */ + M_apm_scale(M_work2, 2); + } + else + { + if (aexp > bexp) + { + M_apm_scale(M_work1, 2); + M_apm_scale(M_work2, (aexp + 2 - bexp)); + } + else /* aexp < bexp */ + { + M_apm_scale(M_work2, 2); + M_apm_scale(M_work1, (bexp + 2 - aexp)); + } + } + + adigits = M_work1->m_apm_datalength; + bdigits = M_work2->m_apm_datalength; + + if (adigits >= bdigits) + { + m_apm_copy(r, M_work1); + j = (bdigits + 1) >> 1; + carry = 0; + + while (TRUE) + { + j--; + r->m_apm_data[j] += carry + M_work2->m_apm_data[j]; + + if (r->m_apm_data[j] >= 100) + { + r->m_apm_data[j] -= 100; + carry = 1; + } + else + carry = 0; + + if (j == 0) + break; + } + } + else + { + m_apm_copy(r, M_work2); + j = (adigits + 1) >> 1; + carry = 0; + + while (TRUE) + { + j--; + r->m_apm_data[j] += carry + M_work1->m_apm_data[j]; + + if (r->m_apm_data[j] >= 100) + { + r->m_apm_data[j] -= 100; + carry = 1; + } + else + carry = 0; + + if (j == 0) + break; + } + } + + r->m_apm_sign = sign; + + M_apm_normalize(r); +} +/****************************************************************************/ +void m_apm_subtract(M_APM r, M_APM a, M_APM b) +{ + int itmp, j, flag, icompare, sign, aexp, bexp, + borrow, adigits, bdigits; + + if (M_add_firsttime) + { + M_add_firsttime = FALSE; + M_work1 = m_apm_init(); + M_work2 = m_apm_init(); + } + + if (b->m_apm_sign == 0) + { + m_apm_copy(r, a); + return; + } + + if (a->m_apm_sign == 0) + { + m_apm_copy(r, b); + r->m_apm_sign = -(r->m_apm_sign); + return; + } + + if (a->m_apm_sign == 1 && b->m_apm_sign == -1) + { + b->m_apm_sign = 1; + m_apm_add(r, a, b); + b->m_apm_sign = -1; + return; + } + + if (a->m_apm_sign == -1 && b->m_apm_sign == 1) + { + b->m_apm_sign = -1; + m_apm_add(r, a, b); + b->m_apm_sign = 1; + return; + } + + /* now, the signs are the same */ + /* make a positive working copy */ + + m_apm_absolute_value(M_work1, a); + m_apm_absolute_value(M_work2, b); + + /* are they the same?? if so, the result is zero */ + + if ((icompare = m_apm_compare(M_work1, M_work2)) == 0) + { + M_set_to_zero(r); + return; + } + + if (icompare == 1) /* |a| > |b| (do A-B) */ + { + flag = TRUE; + sign = a->m_apm_sign; + } + else /* |b| > |a| (do B-A) */ + { + flag = FALSE; + sign = -(a->m_apm_sign); + } + + aexp = M_work1->m_apm_exponent; + bexp = M_work2->m_apm_exponent; + + if (aexp > bexp) + M_apm_scale(M_work2, (aexp - bexp)); + + if (aexp < bexp) + M_apm_scale(M_work1, (bexp - aexp)); + + adigits = M_work1->m_apm_datalength; + bdigits = M_work2->m_apm_datalength; + + if (adigits > bdigits) + M_apm_pad(M_work2, adigits); + + if (adigits < bdigits) + M_apm_pad(M_work1, bdigits); + + if (flag) /* perform A-B, M_work1 - M_work2 */ + { + m_apm_copy(r, M_work1); + j = (r->m_apm_datalength + 1) >> 1; + borrow = 0; + + while (TRUE) + { + j--; + itmp = (int)r->m_apm_data[j] - ((int)M_work2->m_apm_data[j] + borrow); + + if (itmp >= 0) + { + r->m_apm_data[j] = (UCHAR)itmp; + borrow = 0; + } + else + { + r->m_apm_data[j] = (UCHAR)(100 + itmp); + borrow = 1; + } + + if (j == 0) + break; + } + } + else /* perform B-A, M_work2 - M_work1 */ + { + m_apm_copy(r, M_work2); + j = (r->m_apm_datalength + 1) >> 1; + borrow = 0; + + while (TRUE) + { + j--; + itmp = (int)r->m_apm_data[j] - ((int)M_work1->m_apm_data[j] + borrow); + + if (itmp >= 0) + { + r->m_apm_data[j] = (UCHAR)itmp; + borrow = 0; + } + else + { + r->m_apm_data[j] = (UCHAR)(100 + itmp); + borrow = 1; + } + + if (j == 0) + break; + } + } + + r->m_apm_sign = sign; + + M_apm_normalize(r); +} +/****************************************************************************/ + +#ifdef __cplusplus + +MAPM operator+(const MAPM &a, const MAPM &b) +{ + MAPM ret; + m_apm_add(ret.val(), a.cval(), b.cval()); + return ret; +} +MAPM operator-(const MAPM &a, const MAPM &b) +{ + MAPM ret; + m_apm_subtract(ret.val(), a.cval(), b.cval()); + return ret; +} + +#endif diff --git a/pgscript/utilities/m_apm/mapm_cpi.cpp b/pgscript/utilities/m_apm/mapm_cpi.cpp new file mode 100644 index 0000000..4204699 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_cpi.cpp @@ -0,0 +1,161 @@ + +/* + * M_APM - mapm_cpi.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the PI related functions. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +/* + * check if our local copy of PI is precise enough + * for our purpose. if not, calculate PI so it's + * as precise as desired, accurate to 'places' decimal + * places. + */ +void M_check_PI_places(int places) +{ + int dplaces; + + dplaces = places + 2; + + if (dplaces > MM_lc_PI_digits) + { + MM_lc_PI_digits = dplaces + 2; + + /* compute PI using the AGM (see right below) */ + + M_calculate_PI_AGM(MM_lc_PI, (dplaces + 5)); + + m_apm_multiply(MM_lc_HALF_PI, MM_0_5, MM_lc_PI); + m_apm_multiply(MM_lc_2_PI, MM_Two, MM_lc_PI); + } +} +/****************************************************************************/ +/* + * Calculate PI using the AGM (Arithmetic-Geometric Mean) + * + * Init : A0 = 1 + * B0 = 1 / sqrt(2) + * Sum = 1 + * + * Iterate: n = 1... + * + * + * A = 0.5 * [ A + B ] + * n n-1 n-1 + * + * + * B = sqrt [ A * B ] + * n n-1 n-1 + * + * + * + * C = 0.5 * [ A - B ] + * n n-1 n-1 + * + * + * 2 n+1 + * Sum = Sum - C * 2 + * n + * + * + * At the end when C is 'small enough' : + * n + * + * 2 + * PI = 4 * A / Sum + * n+1 + * + * -OR- + * + * 2 + * PI = ( A + B ) / Sum + * n n + * + */ +void M_calculate_PI_AGM(M_APM outv, int places) +{ + M_APM tmp1, tmp2, a0, b0, c0, a1, b1, sum, pow_2; + int dplaces, nn; + + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + a0 = M_get_stack_var(); + b0 = M_get_stack_var(); + c0 = M_get_stack_var(); + a1 = M_get_stack_var(); + b1 = M_get_stack_var(); + sum = M_get_stack_var(); + pow_2 = M_get_stack_var(); + + dplaces = places + 16; + + m_apm_copy(a0, MM_One); + m_apm_copy(sum, MM_One); + m_apm_copy(pow_2, MM_Four); + m_apm_sqrt(b0, dplaces, MM_0_5); /* sqrt(0.5) */ + + while (TRUE) + { + m_apm_add(tmp1, a0, b0); + m_apm_multiply(a1, MM_0_5, tmp1); + + m_apm_multiply(tmp1, a0, b0); + m_apm_sqrt(b1, dplaces, tmp1); + + m_apm_subtract(tmp1, a0, b0); + m_apm_multiply(c0, MM_0_5, tmp1); + + /* + * the net 'PI' calculated from this iteration will + * be accurate to ~4 X the value of (c0)'s exponent. + * this was determined experimentally. + */ + + nn = -4 * c0->m_apm_exponent; + + m_apm_multiply(tmp1, c0, c0); + m_apm_multiply(tmp2, tmp1, pow_2); + m_apm_subtract(tmp1, sum, tmp2); + m_apm_round(sum, dplaces, tmp1); + + if (nn >= dplaces) + break; + + m_apm_copy(a0, a1); + m_apm_copy(b0, b1); + + m_apm_multiply(tmp1, pow_2, MM_Two); + m_apm_copy(pow_2, tmp1); + } + + m_apm_add(tmp1, a1, b1); + m_apm_multiply(tmp2, tmp1, tmp1); + m_apm_divide(tmp1, dplaces, tmp2, sum); + m_apm_round(outv, places, tmp1); + + M_restore_stack(9); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapm_div.cpp b/pgscript/utilities/m_apm/mapm_div.cpp new file mode 100644 index 0000000..cd5ee24 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_div.cpp @@ -0,0 +1,300 @@ + +/* + * M_APM - mapm_div.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the basic division functions + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +static M_APM M_div_worka; +static M_APM M_div_workb; +static M_APM M_div_tmp7; +static M_APM M_div_tmp8; +static M_APM M_div_tmp9; + +static int M_div_firsttime = TRUE; + +/****************************************************************************/ +void M_free_all_div() +{ + if (M_div_firsttime == FALSE) + { + m_apm_free(M_div_worka); + m_apm_free(M_div_workb); + m_apm_free(M_div_tmp7); + m_apm_free(M_div_tmp8); + m_apm_free(M_div_tmp9); + + M_div_firsttime = TRUE; + } +} +/****************************************************************************/ +void m_apm_integer_div_rem(M_APM qq, M_APM rr, M_APM aa, M_APM bb) +{ + m_apm_integer_divide(qq, aa, bb); + m_apm_multiply(M_div_tmp7, qq, bb); + m_apm_subtract(rr, aa, M_div_tmp7); +} +/****************************************************************************/ +void m_apm_integer_divide(M_APM rr, M_APM aa, M_APM bb) +{ + /* + * we must use this divide function since the + * faster divide function using the reciprocal + * will round the result (possibly changing + * nnm.999999... --> nn(m+1).0000 which would + * invalidate the 'integer_divide' goal). + */ + + M_apm_sdivide(rr, 4, aa, bb); + + if (rr->m_apm_exponent <= 0) /* result is 0 */ + { + M_set_to_zero(rr); + } + else + { + if (rr->m_apm_datalength > rr->m_apm_exponent) + { + rr->m_apm_datalength = rr->m_apm_exponent; + M_apm_normalize(rr); + } + } +} +/****************************************************************************/ +void M_apm_sdivide(M_APM r, int places, M_APM a, M_APM b) +{ + int j, k, m, b0, sign, nexp, indexr, icompare, iterations; + long trial_numer; + void *vp; + + if (M_div_firsttime) + { + M_div_firsttime = FALSE; + + M_div_worka = m_apm_init(); + M_div_workb = m_apm_init(); + M_div_tmp7 = m_apm_init(); + M_div_tmp8 = m_apm_init(); + M_div_tmp9 = m_apm_init(); + } + + sign = a->m_apm_sign * b->m_apm_sign; + + if (sign == 0) /* one number is zero, result is zero */ + { + if (b->m_apm_sign == 0) + { + M_apm_log_error_msg(M_APM_RETURN, "\'M_apm_sdivide\', Divide by 0"); + } + + M_set_to_zero(r); + return; + } + + /* + * Knuth step D1. Since base = 100, base / 2 = 50. + * (also make the working copies positive) + */ + + if (b->m_apm_data[0] >= 50) + { + m_apm_absolute_value(M_div_worka, a); + m_apm_absolute_value(M_div_workb, b); + } + else /* 'normal' step D1 */ + { + k = 100 / (b->m_apm_data[0] + 1); + m_apm_set_long(M_div_tmp9, (long)k); + + m_apm_multiply(M_div_worka, M_div_tmp9, a); + m_apm_multiply(M_div_workb, M_div_tmp9, b); + + M_div_worka->m_apm_sign = 1; + M_div_workb->m_apm_sign = 1; + } + + /* setup trial denominator for step D3 */ + + b0 = 100 * (int)M_div_workb->m_apm_data[0]; + + if (M_div_workb->m_apm_datalength >= 3) + b0 += M_div_workb->m_apm_data[1]; + + nexp = M_div_worka->m_apm_exponent - M_div_workb->m_apm_exponent; + + if (nexp > 0) + iterations = nexp + places + 1; + else + iterations = places + 1; + + k = (iterations + 1) >> 1; /* required size of result, in bytes */ + + if (k > r->m_apm_malloclength) + { + if ((vp = MAPM_REALLOC(r->m_apm_data, (k + 32))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, "\'M_apm_sdivide\', Out of memory"); + } + + r->m_apm_malloclength = k + 28; + r->m_apm_data = (UCHAR *)vp; + } + + /* clear the exponent in the working copies */ + + M_div_worka->m_apm_exponent = 0; + M_div_workb->m_apm_exponent = 0; + + /* if numbers are equal, ratio == 1.00000... */ + + if ((icompare = m_apm_compare(M_div_worka, M_div_workb)) == 0) + { + iterations = 1; + r->m_apm_data[0] = 10; + nexp++; + } + else /* ratio not 1, do the real division */ + { + if (icompare == 1) /* numerator > denominator */ + { + nexp++; /* to adjust the final exponent */ + M_div_worka->m_apm_exponent += 1; /* multiply numerator by 10 */ + } + else /* numerator < denominator */ + { + M_div_worka->m_apm_exponent += 2; /* multiply numerator by 100 */ + } + + indexr = 0; + m = 0; + + while (TRUE) + { + /* + * Knuth step D3. Only use the 3rd -> 6th digits if the number + * actually has that many digits. + */ + + trial_numer = 10000L * (long)M_div_worka->m_apm_data[0]; + + if (M_div_worka->m_apm_datalength >= 5) + { + trial_numer += 100 * M_div_worka->m_apm_data[1] + + M_div_worka->m_apm_data[2]; + } + else + { + if (M_div_worka->m_apm_datalength >= 3) + trial_numer += 100 * M_div_worka->m_apm_data[1]; + } + + j = (int)(trial_numer / b0); + + /* + * Since the library 'normalizes' all the results, we need + * to look at the exponent of the number to decide if we + * have a lead in 0n or 00. + */ + + if ((k = 2 - M_div_worka->m_apm_exponent) > 0) + { + while (TRUE) + { + j /= 10; + if (--k == 0) + break; + } + } + + if (j == 100) /* qhat == base ?? */ + j = 99; /* if so, decrease by 1 */ + + m_apm_set_long(M_div_tmp8, (long)j); + m_apm_multiply(M_div_tmp7, M_div_tmp8, M_div_workb); + + /* + * Compare our q-hat (j) against the desired number. + * j is either correct, 1 too large, or 2 too large + * per Theorem B on pg 272 of Art of Compter Programming, + * Volume 2, 3rd Edition. + * + * The above statement is only true if using the 2 leading + * digits of the numerator and the leading digit of the + * denominator. Since we are using the (3) leading digits + * of the numerator and the (2) leading digits of the + * denominator, we eliminate the case where our q-hat is + * 2 too large, (and q-hat being 1 too large is quite remote). + */ + + if (m_apm_compare(M_div_tmp7, M_div_worka) == 1) + { + j--; + m_apm_subtract(M_div_tmp8, M_div_tmp7, M_div_workb); + m_apm_copy(M_div_tmp7, M_div_tmp8); + } + + /* + * Since we know q-hat is correct, step D6 is unnecessary. + * + * Store q-hat, step D5. Since D6 is unnecessary, we can + * do D5 before D4 and decide if we are done. + */ + + r->m_apm_data[indexr++] = (UCHAR)j; /* j == 'qhat' */ + m += 2; + + if (m >= iterations) + break; + + /* step D4 */ + + m_apm_subtract(M_div_tmp9, M_div_worka, M_div_tmp7); + + /* + * if the subtraction yields zero, the division is exact + * and we are done early. + */ + + if (M_div_tmp9->m_apm_sign == 0) + { + iterations = m; + break; + } + + /* multiply by 100 and re-save */ + M_div_tmp9->m_apm_exponent += 2; + m_apm_copy(M_div_worka, M_div_tmp9); + } + } + + r->m_apm_sign = sign; + r->m_apm_exponent = nexp; + r->m_apm_datalength = iterations; + + M_apm_normalize(r); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapm_exp.cpp b/pgscript/utilities/m_apm/mapm_exp.cpp new file mode 100644 index 0000000..d2710e8 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_exp.cpp @@ -0,0 +1,294 @@ + +/* + * M_APM - mapm_exp.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the EXP function. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +static M_APM MM_exp_log2R; +static M_APM MM_exp_512R; +static int MM_firsttime1 = TRUE; + +/****************************************************************************/ +void M_free_all_exp() +{ + if (MM_firsttime1 == FALSE) + { + m_apm_free(MM_exp_log2R); + m_apm_free(MM_exp_512R); + + MM_firsttime1 = TRUE; + } +} +/****************************************************************************/ +void m_apm_exp(M_APM r, int places, M_APM x) +{ + M_APM tmp7, tmp8, tmp9; + int dplaces, nn, ii; + + if (MM_firsttime1) + { + MM_firsttime1 = FALSE; + + MM_exp_log2R = m_apm_init(); + MM_exp_512R = m_apm_init(); + + m_apm_set_string(MM_exp_log2R, "1.44269504089"); /* ~ 1 / log(2) */ + m_apm_set_string(MM_exp_512R, "1.953125E-3"); /* 1 / 512 */ + } + + tmp7 = M_get_stack_var(); + tmp8 = M_get_stack_var(); + tmp9 = M_get_stack_var(); + + if (x->m_apm_sign == 0) /* if input == 0, return '1' */ + { + m_apm_copy(r, MM_One); + M_restore_stack(3); + return; + } + + if (x->m_apm_exponent <= -3) /* already small enough so call _raw directly */ + { + M_raw_exp(tmp9, (places + 6), x); + m_apm_round(r, places, tmp9); + M_restore_stack(3); + return; + } + + /* + From David H. Bailey's MPFUN Fortran package : + + exp (t) = (1 + r + r^2 / 2! + r^3 / 3! + r^4 / 4! ...) ^ q * 2 ^ n + + where q = 256, r = t' / q, t' = t - n Log(2) and where n is chosen so + that -0.5 Log(2) < t' <= 0.5 Log(2). Reducing t mod Log(2) and + dividing by 256 insures that -0.001 < r <= 0.001, which accelerates + convergence in the above series. + + I use q = 512 and also limit how small 'r' can become. The 'r' used + here is limited in magnitude from 1.95E-4 < |r| < 1.35E-3. Forcing + 'r' into a narrow range keeps the algorithm 'well behaved'. + + ( the range is [0.1 / 512] to [log(2) / 512] ) + */ + + if (M_exp_compute_nn(&nn, tmp7, x) != 0) + { + M_apm_log_error_msg(M_APM_RETURN, + "\'m_apm_exp\', Input too large, Overflow"); + + M_set_to_zero(r); + M_restore_stack(3); + return; + } + + dplaces = places + 8; + + /* check to make sure our log(2) is accurate enough */ + + M_check_log_places(dplaces); + + m_apm_multiply(tmp8, tmp7, MM_lc_log2); + m_apm_subtract(tmp7, x, tmp8); + + /* + * guarantee that |tmp7| is between 0.1 and 0.9999999.... + * (in practice, the upper limit only reaches log(2), 0.693... ) + */ + + while (TRUE) + { + if (tmp7->m_apm_sign != 0) + { + if (tmp7->m_apm_exponent == 0) + break; + } + + if (tmp7->m_apm_sign >= 0) + { + nn++; + m_apm_subtract(tmp8, tmp7, MM_lc_log2); + m_apm_copy(tmp7, tmp8); + } + else + { + nn--; + m_apm_add(tmp8, tmp7, MM_lc_log2); + m_apm_copy(tmp7, tmp8); + } + } + + m_apm_multiply(tmp9, tmp7, MM_exp_512R); + + /* perform the series expansion ... */ + + M_raw_exp(tmp8, dplaces, tmp9); + + /* + * raise result to the 512 power + * + * note : x ^ 512 = (((x ^ 2) ^ 2) ^ 2) ... 9 times + */ + + ii = 9; + + while (TRUE) + { + m_apm_multiply(tmp9, tmp8, tmp8); + m_apm_round(tmp8, dplaces, tmp9); + + if (--ii == 0) + break; + } + + /* now compute 2 ^ N */ + + m_apm_integer_pow(tmp7, dplaces, MM_Two, nn); + + m_apm_multiply(tmp9, tmp7, tmp8); + m_apm_round(r, places, tmp9); + + M_restore_stack(3); /* restore the 3 locals we used here */ +} +/****************************************************************************/ +/* + compute int *n = round_to_nearest_int(a / log(2)) + M_APM b = MAPM version of *n + + returns 0: OK + -1, 1: failure +*/ +int M_exp_compute_nn(int *n, M_APM b, M_APM a) +{ + M_APM tmp0, tmp1; + void *vp; + char *cp, sbuf[48]; + int kk; + + *n = 0; + vp = NULL; + cp = sbuf; + tmp0 = M_get_stack_var(); + tmp1 = M_get_stack_var(); + + /* find 'n' and convert it to a normal C int */ + /* we just need an approx 1/log(2) for this calculation */ + + m_apm_multiply(tmp1, a, MM_exp_log2R); + + /* round to the nearest int */ + + if (tmp1->m_apm_sign >= 0) + { + m_apm_add(tmp0, tmp1, MM_0_5); + m_apm_floor(tmp1, tmp0); + } + else + { + m_apm_subtract(tmp0, tmp1, MM_0_5); + m_apm_ceil(tmp1, tmp0); + } + + kk = tmp1->m_apm_exponent; + if (kk >= 42) + { + if ((vp = (void *)MAPM_MALLOC((kk + 16) * sizeof(char))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, "\'M_exp_compute_nn\', Out of memory"); + } + + cp = (char *)vp; + } + + m_apm_to_integer_string(cp, tmp1); + *n = atoi(cp); + + m_apm_set_long(b, (long)(*n)); + + kk = m_apm_compare(b, tmp1); + + if (vp != NULL) + MAPM_FREE(vp); + + M_restore_stack(2); + return(kk); +} +/****************************************************************************/ +/* + calculate the exponential function using the following series : + + x^2 x^3 x^4 x^5 + exp(x) == 1 + x + --- + --- + --- + --- ... + 2! 3! 4! 5! + +*/ +void M_raw_exp(M_APM rr, int places, M_APM xx) +{ + M_APM tmp0, digit, term; + int tolerance, local_precision, prev_exp; + long m1; + + tmp0 = M_get_stack_var(); + term = M_get_stack_var(); + digit = M_get_stack_var(); + + local_precision = places + 8; + tolerance = -(places + 4); + prev_exp = 0; + + m_apm_add(rr, MM_One, xx); + m_apm_copy(term, xx); + + m1 = 2L; + + while (TRUE) + { + m_apm_set_long(digit, m1); + m_apm_multiply(tmp0, term, xx); + m_apm_divide(term, local_precision, tmp0, digit); + m_apm_add(tmp0, rr, term); + m_apm_copy(rr, tmp0); + + if ((term->m_apm_exponent < tolerance) || (term->m_apm_sign == 0)) + break; + + if (m1 != 2L) + { + local_precision = local_precision + term->m_apm_exponent - prev_exp; + + if (local_precision < 20) + local_precision = 20; + } + + prev_exp = term->m_apm_exponent; + m1++; + } + + M_restore_stack(3); /* restore the 3 locals we used here */ +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapm_fam.cpp b/pgscript/utilities/m_apm/mapm_fam.cpp new file mode 100644 index 0000000..5dac8c1 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_fam.cpp @@ -0,0 +1,55 @@ + +/* + * M_APM - mapm_fam.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the free all memory and similiar functions. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +void m_apm_free_all_mem() +{ + M_free_all_add(); /* call each module which has statically declared data */ + M_free_all_div(); + M_free_all_exp(); + +#ifndef NO_FFT_MULTIPLY + M_free_all_fft(); +#endif + + M_free_all_pow(); + M_free_all_rnd(); + M_free_all_set(); + M_free_all_cnst(); + M_free_all_fmul(); + M_free_all_stck(); + M_free_all_util(); +} +/****************************************************************************/ +void m_apm_trim_mem_usage() +{ + m_apm_free_all_mem(); + m_apm_free(m_apm_init()); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapm_fft.cpp b/pgscript/utilities/m_apm/mapm_fft.cpp new file mode 100644 index 0000000..248403c --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_fft.cpp @@ -0,0 +1,953 @@ + +/* + * M_APM - mapm_fft.c + * + * This FFT (Fast Fourier Transform) is from Takuya OOURA + * + * Copyright(C) 1996-1999 Takuya OOURA + * email: ooura@mmm.t.u-tokyo.ac.jp + * + * See full FFT documentation below ... (MCR) + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the FFT based FAST MULTIPLICATION function + * as well as its support functions. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +#ifndef MM_PI_2 +#define MM_PI_2 1.570796326794896619231321691639751442098584699687 +#endif + +#ifndef WR5000 /* cos(MM_PI_2*0.5000) */ +#define WR5000 0.707106781186547524400844362104849039284835937688 +#endif + +#ifndef RDFT_LOOP_DIV /* control of the RDFT's speed & tolerance */ +#define RDFT_LOOP_DIV 64 +#endif + +extern void M_fast_mul_fft(UCHAR *, UCHAR *, UCHAR *, int); + +extern void M_rdft(int, int, double *); +extern void M_bitrv2(int, double *); +extern void M_cftfsub(int, double *); +extern void M_cftbsub(int, double *); +extern void M_rftfsub(int, double *); +extern void M_rftbsub(int, double *); +extern void M_cft1st(int, double *); +extern void M_cftmdl(int, int, double *); + +static double *M_aa_array, *M_bb_array; +static int M_size = -1; + +static char *M_fft_error_msg = (char *)"\'M_fast_mul_fft\', Out of memory"; + +/****************************************************************************/ +void M_free_all_fft() +{ + if (M_size > 0) + { + MAPM_FREE(M_aa_array); + MAPM_FREE(M_bb_array); + M_size = -1; + } +} +/****************************************************************************/ +/* + * multiply 'uu' by 'vv' with nbytes each + * yielding a 2*nbytes result in 'ww'. + * each byte contains a base 100 'digit', + * i.e.: range from 0-99. + * + * MSB LSB + * + * uu,vv [0] [1] [2] ... [N-1] + * ww [0] [1] [2] ... [2N-1] + */ + +void M_fast_mul_fft(UCHAR *ww, UCHAR *uu, UCHAR *vv, int nbytes) +{ + int mflag, i, j, nn2, nn; + double carry, nnr, dtemp, *a, *b; + UCHAR *w0; + unsigned long ul; + + if (M_size < 0) /* if first time in, setup working arrays */ + { + if (M_get_sizeof_int() == 2) /* if still using 16 bit compilers */ + M_size = 516; + else + M_size = 8200; + + M_aa_array = (double *)MAPM_MALLOC(M_size * sizeof(double)); + M_bb_array = (double *)MAPM_MALLOC(M_size * sizeof(double)); + + if ((M_aa_array == NULL) || (M_bb_array == NULL)) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, M_fft_error_msg); + } + } + + nn = nbytes; + nn2 = nbytes >> 1; + + if (nn > M_size) + { + mflag = TRUE; + + a = (double *)MAPM_MALLOC((nn + 8) * sizeof(double)); + b = (double *)MAPM_MALLOC((nn + 8) * sizeof(double)); + + if ((a == NULL) || (b == NULL)) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, M_fft_error_msg); + } + } + else + { + mflag = FALSE; + + a = M_aa_array; + b = M_bb_array; + } + + /* + * convert normal base 100 MAPM numbers to base 10000 + * for the FFT operation. + */ + + i = 0; + for (j = 0; j < nn2; j++) + { + a[j] = (double)((int)uu[i] * 100 + uu[i + 1]); + b[j] = (double)((int)vv[i] * 100 + vv[i + 1]); + i += 2; + } + + /* zero fill the second half of the arrays */ + + for (j = nn2; j < nn; j++) + { + a[j] = 0.0; + b[j] = 0.0; + } + + /* perform the forward Fourier transforms for both numbers */ + + M_rdft(nn, 1, a); + M_rdft(nn, 1, b); + + /* perform the convolution ... */ + + b[0] *= a[0]; + b[1] *= a[1]; + + for (j = 3; j <= nn; j += 2) + { + dtemp = b[j - 1]; + b[j - 1] = dtemp * a[j - 1] - b[j] * a[j]; + b[j] = dtemp * a[j] + b[j] * a[j - 1]; + } + + /* perform the inverse transform on the result */ + + M_rdft(nn, -1, b); + + /* perform a final pass to release all the carries */ + /* we are still in base 10000 at this point */ + + carry = 0.0; + j = nn; + nnr = 2.0 / (double)nn; + + while (1) + { + dtemp = b[--j] * nnr + carry + 0.5; + ul = (unsigned long)(dtemp * 1.0E-4); + carry = (double)ul; + b[j] = dtemp - carry * 10000.0; + + if (j == 0) + break; + } + + /* copy result to our destination after converting back to base 100 */ + + w0 = ww; + M_get_div_rem((int)ul, w0, (w0 + 1)); + + for (j = 0; j <= (nn - 2); j++) + { + w0 += 2; + M_get_div_rem((int)b[j], w0, (w0 + 1)); + } + + if (mflag) + { + MAPM_FREE(b); + MAPM_FREE(a); + } +} +/****************************************************************************/ + +/* + * The following info is from Takuya OOURA's documentation : + * + * NOTE : MAPM only uses the 'RDFT' function (as well as the + * functions RDFT calls). All the code from here down + * in this file is from Takuya OOURA. The only change I + * made was to add 'M_' in front of all the functions + * I used. This was to guard against any possible + * name collisions in the future. + * + * MCR 06 July 2000 + * + * + * General Purpose FFT (Fast Fourier/Cosine/Sine Transform) Package + * + * Description: + * A package to calculate Discrete Fourier/Cosine/Sine Transforms of + * 1-dimensional sequences of length 2^N. + * + * fft4g_h.c : FFT Package in C - Simple Version I (radix 4,2) + * + * rdft: Real Discrete Fourier Transform + * + * Method: + * -------- rdft -------- + * A method with a following butterfly operation appended to "cdft". + * In forward transform : + * A[k] = sum_j=0^n-1 a[j]*W(n)^(j*k), 0<=k<=n/2, + * W(n) = exp(2*pi*i/n), + * this routine makes an array x[] : + * x[j] = a[2*j] + i*a[2*j+1], 0<=j RDFT + R[k] = sum_j=0^n-1 a[j]*cos(2*pi*j*k/n), 0<=k<=n/2 + I[k] = sum_j=0^n-1 a[j]*sin(2*pi*j*k/n), 0 IRDFT (excluding scale) + a[k] = (R[0] + R[n/2]*cos(pi*k))/2 + + sum_j=1^n/2-1 R[j]*cos(2*pi*j*k/n) + + sum_j=1^n/2-1 I[j]*sin(2*pi*j*k/n), 0<=k + rdft(n, 1, a); + + rdft(n, -1, a); + [parameters] + n :data length (int) + n >= 2, n = power of 2 + a[0...n-1] :input/output data (double *) + + output data + a[2*k] = R[k], 0<=k + input data + a[2*j] = R[j], 0<=j= 0) + { + if (n > 4) + { + M_bitrv2(n, a); + M_cftfsub(n, a); + M_rftfsub(n, a); + } + else if (n == 4) + { + M_cftfsub(n, a); + } + xi = a[0] - a[1]; + a[0] += a[1]; + a[1] = xi; + } + else + { + a[1] = 0.5 * (a[0] - a[1]); + a[0] -= a[1]; + if (n > 4) + { + M_rftbsub(n, a); + M_bitrv2(n, a); + M_cftbsub(n, a); + } + else if (n == 4) + { + M_cftfsub(n, a); + } + } +} + + + +void M_bitrv2(int n, double *a) +{ + int j0, k0, j1, k1, l, m, i, j, k; + double xr, xi, yr, yi; + + l = n >> 2; + m = 2; + while (m < l) + { + l >>= 1; + m <<= 1; + } + if (m == l) + { + j0 = 0; + for (k0 = 0; k0 < m; k0 += 2) + { + k = k0; + for (j = j0; j < j0 + k0; j += 2) + { + xr = a[j]; + xi = a[j + 1]; + yr = a[k]; + yi = a[k + 1]; + a[j] = yr; + a[j + 1] = yi; + a[k] = xr; + a[k + 1] = xi; + j1 = j + m; + k1 = k + 2 * m; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += m; + k1 -= m; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += m; + k1 += 2 * m; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + for (i = n >> 1; i > (k ^= i); i >>= 1); + } + j1 = j0 + k0 + m; + k1 = j1 + m; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + for (i = n >> 1; i > (j0 ^= i); i >>= 1); + } + } + else + { + j0 = 0; + for (k0 = 2; k0 < m; k0 += 2) + { + for (i = n >> 1; i > (j0 ^= i); i >>= 1); + k = k0; + for (j = j0; j < j0 + k0; j += 2) + { + xr = a[j]; + xi = a[j + 1]; + yr = a[k]; + yi = a[k + 1]; + a[j] = yr; + a[j + 1] = yi; + a[k] = xr; + a[k + 1] = xi; + j1 = j + m; + k1 = k + m; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + for (i = n >> 1; i > (k ^= i); i >>= 1); + } + } + } +} + + + +void M_cftfsub(int n, double *a) +{ + int j, j1, j2, j3, l; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + l = 2; + if (n > 8) + { + M_cft1st(n, a); + l = 8; + while ((l << 2) < n) + { + M_cftmdl(n, l, a); + l <<= 2; + } + } + if ((l << 2) == n) + { + for (j = 0; j < l; j += 2) + { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + a[j2] = x0r - x2r; + a[j2 + 1] = x0i - x2i; + a[j1] = x1r - x3i; + a[j1 + 1] = x1i + x3r; + a[j3] = x1r + x3i; + a[j3 + 1] = x1i - x3r; + } + } + else + { + for (j = 0; j < l; j += 2) + { + j1 = j + l; + x0r = a[j] - a[j1]; + x0i = a[j + 1] - a[j1 + 1]; + a[j] += a[j1]; + a[j + 1] += a[j1 + 1]; + a[j1] = x0r; + a[j1 + 1] = x0i; + } + } +} + + + +void M_cftbsub(int n, double *a) +{ + int j, j1, j2, j3, l; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + l = 2; + if (n > 8) + { + M_cft1st(n, a); + l = 8; + while ((l << 2) < n) + { + M_cftmdl(n, l, a); + l <<= 2; + } + } + if ((l << 2) == n) + { + for (j = 0; j < l; j += 2) + { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = -a[j + 1] - a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = -a[j + 1] + a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i - x2i; + a[j2] = x0r - x2r; + a[j2 + 1] = x0i + x2i; + a[j1] = x1r - x3i; + a[j1 + 1] = x1i - x3r; + a[j3] = x1r + x3i; + a[j3 + 1] = x1i + x3r; + } + } + else + { + for (j = 0; j < l; j += 2) + { + j1 = j + l; + x0r = a[j] - a[j1]; + x0i = -a[j + 1] + a[j1 + 1]; + a[j] += a[j1]; + a[j + 1] = -a[j + 1] - a[j1 + 1]; + a[j1] = x0r; + a[j1 + 1] = x0i; + } + } +} + + + +void M_cft1st(int n, double *a) +{ + int j, kj, kr; + double ew, wn4r, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + x0r = a[0] + a[2]; + x0i = a[1] + a[3]; + x1r = a[0] - a[2]; + x1i = a[1] - a[3]; + x2r = a[4] + a[6]; + x2i = a[5] + a[7]; + x3r = a[4] - a[6]; + x3i = a[5] - a[7]; + a[0] = x0r + x2r; + a[1] = x0i + x2i; + a[4] = x0r - x2r; + a[5] = x0i - x2i; + a[2] = x1r - x3i; + a[3] = x1i + x3r; + a[6] = x1r + x3i; + a[7] = x1i - x3r; + wn4r = WR5000; + x0r = a[8] + a[10]; + x0i = a[9] + a[11]; + x1r = a[8] - a[10]; + x1i = a[9] - a[11]; + x2r = a[12] + a[14]; + x2i = a[13] + a[15]; + x3r = a[12] - a[14]; + x3i = a[13] - a[15]; + a[8] = x0r + x2r; + a[9] = x0i + x2i; + a[12] = x2i - x0i; + a[13] = x0r - x2r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[10] = wn4r * (x0r - x0i); + a[11] = wn4r * (x0r + x0i); + x0r = x3i + x1r; + x0i = x3r - x1i; + a[14] = wn4r * (x0i - x0r); + a[15] = wn4r * (x0i + x0r); + ew = MM_PI_2 / n; + kr = 0; + for (j = 16; j < n; j += 16) + { + for (kj = n >> 2; kj > (kr ^= kj); kj >>= 1); + wk1r = cos(ew * kr); + wk1i = sin(ew * kr); + wk2r = 1 - 2 * wk1i * wk1i; + wk2i = 2 * wk1i * wk1r; + wk3r = wk1r - 2 * wk2i * wk1i; + wk3i = 2 * wk2i * wk1r - wk1i; + x0r = a[j] + a[j + 2]; + x0i = a[j + 1] + a[j + 3]; + x1r = a[j] - a[j + 2]; + x1i = a[j + 1] - a[j + 3]; + x2r = a[j + 4] + a[j + 6]; + x2i = a[j + 5] + a[j + 7]; + x3r = a[j + 4] - a[j + 6]; + x3i = a[j + 5] - a[j + 7]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + x0r -= x2r; + x0i -= x2i; + a[j + 4] = wk2r * x0r - wk2i * x0i; + a[j + 5] = wk2r * x0i + wk2i * x0r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j + 2] = wk1r * x0r - wk1i * x0i; + a[j + 3] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j + 6] = wk3r * x0r - wk3i * x0i; + a[j + 7] = wk3r * x0i + wk3i * x0r; + x0r = wn4r * (wk1r - wk1i); + wk1i = wn4r * (wk1r + wk1i); + wk1r = x0r; + wk3r = wk1r - 2 * wk2r * wk1i; + wk3i = 2 * wk2r * wk1r - wk1i; + x0r = a[j + 8] + a[j + 10]; + x0i = a[j + 9] + a[j + 11]; + x1r = a[j + 8] - a[j + 10]; + x1i = a[j + 9] - a[j + 11]; + x2r = a[j + 12] + a[j + 14]; + x2i = a[j + 13] + a[j + 15]; + x3r = a[j + 12] - a[j + 14]; + x3i = a[j + 13] - a[j + 15]; + a[j + 8] = x0r + x2r; + a[j + 9] = x0i + x2i; + x0r -= x2r; + x0i -= x2i; + a[j + 12] = -wk2i * x0r - wk2r * x0i; + a[j + 13] = -wk2i * x0i + wk2r * x0r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j + 10] = wk1r * x0r - wk1i * x0i; + a[j + 11] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j + 14] = wk3r * x0r - wk3i * x0i; + a[j + 15] = wk3r * x0i + wk3i * x0r; + } +} + + + +void M_cftmdl(int n, int l, double *a) +{ + int j, j1, j2, j3, k, kj, kr, m, m2; + double ew, wn4r, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + m = l << 2; + for (j = 0; j < l; j += 2) + { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + a[j2] = x0r - x2r; + a[j2 + 1] = x0i - x2i; + a[j1] = x1r - x3i; + a[j1 + 1] = x1i + x3r; + a[j3] = x1r + x3i; + a[j3 + 1] = x1i - x3r; + } + wn4r = WR5000; + for (j = m; j < l + m; j += 2) + { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + a[j2] = x2i - x0i; + a[j2 + 1] = x0r - x2r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j1] = wn4r * (x0r - x0i); + a[j1 + 1] = wn4r * (x0r + x0i); + x0r = x3i + x1r; + x0i = x3r - x1i; + a[j3] = wn4r * (x0i - x0r); + a[j3 + 1] = wn4r * (x0i + x0r); + } + ew = MM_PI_2 / n; + kr = 0; + m2 = 2 * m; + for (k = m2; k < n; k += m2) + { + for (kj = n >> 2; kj > (kr ^= kj); kj >>= 1); + wk1r = cos(ew * kr); + wk1i = sin(ew * kr); + wk2r = 1 - 2 * wk1i * wk1i; + wk2i = 2 * wk1i * wk1r; + wk3r = wk1r - 2 * wk2i * wk1i; + wk3i = 2 * wk2i * wk1r - wk1i; + for (j = k; j < l + k; j += 2) + { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + x0r -= x2r; + x0i -= x2i; + a[j2] = wk2r * x0r - wk2i * x0i; + a[j2 + 1] = wk2r * x0i + wk2i * x0r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j1] = wk1r * x0r - wk1i * x0i; + a[j1 + 1] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3] = wk3r * x0r - wk3i * x0i; + a[j3 + 1] = wk3r * x0i + wk3i * x0r; + } + x0r = wn4r * (wk1r - wk1i); + wk1i = wn4r * (wk1r + wk1i); + wk1r = x0r; + wk3r = wk1r - 2 * wk2r * wk1i; + wk3i = 2 * wk2r * wk1r - wk1i; + for (j = k + m; j < l + (k + m); j += 2) + { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + x0r -= x2r; + x0i -= x2i; + a[j2] = -wk2i * x0r - wk2r * x0i; + a[j2 + 1] = -wk2i * x0i + wk2r * x0r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j1] = wk1r * x0r - wk1i * x0i; + a[j1 + 1] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3] = wk3r * x0r - wk3i * x0i; + a[j3 + 1] = wk3r * x0i + wk3i * x0r; + } + } +} + + + +void M_rftfsub(int n, double *a) +{ + int i, i0, j, k; + double ec, w1r, w1i, wkr, wki, wdr, wdi, ss, xr, xi, yr, yi; + + ec = 2 * MM_PI_2 / n; + wkr = 0; + wki = 0; + wdi = cos(ec); + wdr = sin(ec); + wdi *= wdr; + wdr *= wdr; + w1r = 1 - 2 * wdr; + w1i = 2 * wdi; + ss = 2 * w1i; + i = n >> 1; + while (1) + { + i0 = i - 4 * RDFT_LOOP_DIV; + if (i0 < 4) + { + i0 = 4; + } + for (j = i - 4; j >= i0; j -= 4) + { + k = n - j; + xr = a[j + 2] - a[k - 2]; + xi = a[j + 3] + a[k - 1]; + yr = wdr * xr - wdi * xi; + yi = wdr * xi + wdi * xr; + a[j + 2] -= yr; + a[j + 3] -= yi; + a[k - 2] += yr; + a[k - 1] -= yi; + wkr += ss * wdi; + wki += ss * (0.5 - wdr); + xr = a[j] - a[k]; + xi = a[j + 1] + a[k + 1]; + yr = wkr * xr - wki * xi; + yi = wkr * xi + wki * xr; + a[j] -= yr; + a[j + 1] -= yi; + a[k] += yr; + a[k + 1] -= yi; + wdr += ss * wki; + wdi += ss * (0.5 - wkr); + } + if (i0 == 4) + { + break; + } + wkr = 0.5 * sin(ec * i0); + wki = 0.5 * cos(ec * i0); + wdr = 0.5 - (wkr * w1r - wki * w1i); + wdi = wkr * w1i + wki * w1r; + wkr = 0.5 - wkr; + i = i0; + } + xr = a[2] - a[n - 2]; + xi = a[3] + a[n - 1]; + yr = wdr * xr - wdi * xi; + yi = wdr * xi + wdi * xr; + a[2] -= yr; + a[3] -= yi; + a[n - 2] += yr; + a[n - 1] -= yi; +} + + + +void M_rftbsub(int n, double *a) +{ + int i, i0, j, k; + double ec, w1r, w1i, wkr, wki, wdr, wdi, ss, xr, xi, yr, yi; + + ec = 2 * MM_PI_2 / n; + wkr = 0; + wki = 0; + wdi = cos(ec); + wdr = sin(ec); + wdi *= wdr; + wdr *= wdr; + w1r = 1 - 2 * wdr; + w1i = 2 * wdi; + ss = 2 * w1i; + i = n >> 1; + a[i + 1] = -a[i + 1]; + while (1) + { + i0 = i - 4 * RDFT_LOOP_DIV; + if (i0 < 4) + { + i0 = 4; + } + for (j = i - 4; j >= i0; j -= 4) + { + k = n - j; + xr = a[j + 2] - a[k - 2]; + xi = a[j + 3] + a[k - 1]; + yr = wdr * xr + wdi * xi; + yi = wdr * xi - wdi * xr; + a[j + 2] -= yr; + a[j + 3] = yi - a[j + 3]; + a[k - 2] += yr; + a[k - 1] = yi - a[k - 1]; + wkr += ss * wdi; + wki += ss * (0.5 - wdr); + xr = a[j] - a[k]; + xi = a[j + 1] + a[k + 1]; + yr = wkr * xr + wki * xi; + yi = wkr * xi - wki * xr; + a[j] -= yr; + a[j + 1] = yi - a[j + 1]; + a[k] += yr; + a[k + 1] = yi - a[k + 1]; + wdr += ss * wki; + wdi += ss * (0.5 - wkr); + } + if (i0 == 4) + { + break; + } + wkr = 0.5 * sin(ec * i0); + wki = 0.5 * cos(ec * i0); + wdr = 0.5 - (wkr * w1r - wki * w1i); + wdi = wkr * w1i + wki * w1r; + wkr = 0.5 - wkr; + i = i0; + } + xr = a[2] - a[n - 2]; + xi = a[3] + a[n - 1]; + yr = wdr * xr + wdi * xi; + yi = wdr * xi - wdi * xr; + a[2] -= yr; + a[3] = yi - a[3]; + a[n - 2] += yr; + a[n - 1] = yi - a[n - 1]; + a[1] = -a[1]; +} + diff --git a/pgscript/utilities/m_apm/mapm_flr.cpp b/pgscript/utilities/m_apm/mapm_flr.cpp new file mode 100644 index 0000000..7bae5ae --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_flr.cpp @@ -0,0 +1,120 @@ + +/* + * M_APM - mapm_flr.c + * + * Copyright (C) 2001 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the floor and ceil functions + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/* + * input floor ceil + * ----- ------ ------ + * 329.0 329.0 329.0 + * -837.0 -837.0 -837.0 + * 372.64 372.0 373.0 + * -237.52 -238.0 -237.0 + */ + +/****************************************************************************/ +/* + * return the nearest integer <= input + */ +void m_apm_floor(M_APM bb, M_APM aa) +{ + M_APM mtmp; + + m_apm_copy(bb, aa); + + if (m_apm_is_integer(bb)) /* if integer, we're done */ + return; + + if (bb->m_apm_exponent <= 0) /* if |bb| < 1, result is -1 or 0 */ + { + if (bb->m_apm_sign < 0) + m_apm_negate(bb, MM_One); + else + M_set_to_zero(bb); + + return; + } + + if (bb->m_apm_sign < 0) + { + mtmp = M_get_stack_var(); + m_apm_negate(mtmp, bb); + + mtmp->m_apm_datalength = mtmp->m_apm_exponent; + M_apm_normalize(mtmp); + + m_apm_add(bb, mtmp, MM_One); + bb->m_apm_sign = -1; + M_restore_stack(1); + } + else + { + bb->m_apm_datalength = bb->m_apm_exponent; + M_apm_normalize(bb); + } +} +/****************************************************************************/ +/* + * return the nearest integer >= input + */ +void m_apm_ceil(M_APM bb, M_APM aa) +{ + M_APM mtmp; + + m_apm_copy(bb, aa); + + if (m_apm_is_integer(bb)) /* if integer, we're done */ + return; + + if (bb->m_apm_exponent <= 0) /* if |bb| < 1, result is 0 or 1 */ + { + if (bb->m_apm_sign < 0) + M_set_to_zero(bb); + else + m_apm_copy(bb, MM_One); + + return; + } + + if (bb->m_apm_sign < 0) + { + bb->m_apm_datalength = bb->m_apm_exponent; + M_apm_normalize(bb); + } + else + { + mtmp = M_get_stack_var(); + m_apm_copy(mtmp, bb); + + mtmp->m_apm_datalength = mtmp->m_apm_exponent; + M_apm_normalize(mtmp); + + m_apm_add(bb, mtmp, MM_One); + M_restore_stack(1); + } +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapm_fpf.cpp b/pgscript/utilities/m_apm/mapm_fpf.cpp new file mode 100644 index 0000000..4f7fe40 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_fpf.cpp @@ -0,0 +1,415 @@ + +/* + * M_APM - mapm_fpf.c + * + * Copyright (C) 2001 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the Fixed Point Formatting functions + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" +#include + +/****************************************************************************/ +char *m_apm_to_fixpt_stringexp(int dplaces, M_APM atmp, + char ch_radx, char ch_sep, int ct_sep) +{ + int places, xp, dl, ii; + char *cpr; + + places = dplaces; + + dl = atmp->m_apm_datalength; + xp = atmp->m_apm_exponent; + + if (places < 0) /* show ALL digits */ + { + if (xp < 0) + ii = dl - xp; + else + { + if (dl > xp) + ii = dl; + else + ii = xp; + } + } + else + { + ii = places; + + if (xp > 0) + ii += xp; + } + + if (ct_sep != 0 && ch_sep != 0 && xp > 0) + ii += xp / ct_sep; + + if ((cpr = (char *)MAPM_MALLOC((ii + 32) * sizeof(char))) == NULL) + return(NULL); + + m_apm_to_fixpt_stringex(cpr, places, atmp, ch_radx, ch_sep, ct_sep); + + return(cpr); +} +/****************************************************************************/ +void m_apm_to_fixpt_stringex(char *s, int dplaces, M_APM atmp, + char ch_radix, char ch_sep, int count_sep) +{ + M_APM btmp; + char ch, *cpd, *cps; + int ii, jj, kk, ct, dl, xp, no_sep_flg, places; + + btmp = M_get_stack_var(); + places = dplaces; + cpd = s; + no_sep_flg = FALSE; + + m_apm_absolute_value(btmp, atmp); /* do conversion of positive number */ + + if (ch_sep == 0 || count_sep == 0) /* no separator char OR count */ + no_sep_flg = TRUE; + + /* determine how much memory to get for the temp string */ + + dl = btmp->m_apm_datalength; + xp = btmp->m_apm_exponent; + + if (places < 0) /* show ALL digits */ + { + if (xp < 0) + ii = dl - xp; + else + { + if (dl > xp) + ii = dl; + else + ii = xp; + } + } + else + { + ii = places; + + if (xp > 0) + ii += xp; + } + + if ((cps = (char *)MAPM_MALLOC((ii + 32) * sizeof(char))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, + "\'m_apm_to_fixpt_stringex\', Out of memory"); + } + + m_apm_to_fixpt_string(cps, places, btmp); + + /* + * the converted string may be all 'zero', 0.0000... + * if so and the original number is negative, + * do NOT set the '-' sign of our output string. + */ + + if (atmp->m_apm_sign == -1) /* if input number negative */ + { + kk = 0; + jj = 0; + + while (TRUE) + { + ch = cps[kk++]; + if ((ch == '\0') || (jj != 0)) + break; + + if (isdigit((int)ch)) + { + if (ch != '0') + jj = 1; + } + } + + if (jj) + *cpd++ = '-'; + } + + ct = M_strposition(cps, (char *) "."); /* find the default (.) radix char */ + + if (ct == -1) /* if not found .. */ + { + strcat(cps, "."); /* add one */ + ct = M_strposition(cps, (char *) "."); /* and then find it */ + } + + if (places == 0) /* int format, terminate at radix char */ + cps[ct] = '\0'; + else + cps[ct] = ch_radix; /* assign the radix char */ + + /* + * if the number is small enough to not have any separator char's ... + */ + + if (ct <= count_sep) + no_sep_flg = TRUE; + + if (no_sep_flg) + { + strcpy(cpd, cps); + } + else + { + jj = 0; + kk = count_sep; + ii = ct / count_sep; + + if ((ii = ct - ii * count_sep) == 0) + ii = count_sep; + + while (TRUE) /* write out the first 1,2 */ + { + /* (up to count_sep) digits */ + *cpd++ = cps[jj++]; + + if (--ii == 0) + break; + } + + while (TRUE) /* write rest of the string */ + { + if (kk == count_sep) /* write a new separator char */ + { + if (jj != ct) /* unless we're at the radix */ + { + *cpd++ = ch_sep; /* note that this also disables */ + kk = 0; /* the separator char AFTER */ + } /* the radix char */ + } + + if ((*cpd++ = cps[jj++]) == '\0') + break; + + kk++; + } + } + + MAPM_FREE(cps); + M_restore_stack(1); +} +/****************************************************************************/ +void m_apm_to_fixpt_string(char *ss, int dplaces, M_APM mtmp) +{ + M_APM ctmp; + void *vp; + int places, i2, ii, jj, kk, xp, dl, numb; + UCHAR *ucp, numdiv, numrem; + char *cpw, *cpd, sbuf[128]; + + ctmp = M_get_stack_var(); + vp = NULL; + cpd = ss; + places = dplaces; + + /* just want integer portion if places == 0 */ + + if (places == 0) + { + if (mtmp->m_apm_sign >= 0) + m_apm_add(ctmp, mtmp, MM_0_5); + else + m_apm_subtract(ctmp, mtmp, MM_0_5); + + m_apm_to_integer_string(cpd, ctmp); + + M_restore_stack(1); + return; + } + + if (places > 0) + M_apm_round_fixpt(ctmp, places, mtmp); + else + m_apm_copy(ctmp, mtmp); /* show ALL digits */ + + if (ctmp->m_apm_sign == 0) /* result is 0 */ + { + if (places < 0) + { + cpd[0] = '0'; /* "0.0" */ + cpd[1] = '.'; + cpd[2] = '0'; + cpd[3] = '\0'; + } + else + { + memset(cpd, '0', (places + 2)); /* pre-load string with all '0' */ + cpd[1] = '.'; + cpd[places + 2] = '\0'; + } + + M_restore_stack(1); + return; + } + + xp = ctmp->m_apm_exponent; + dl = ctmp->m_apm_datalength; + numb = (dl + 1) >> 1; + + if (places < 0) + { + if (dl > xp) + jj = dl + 16; + else + jj = xp + 16; + } + else + { + jj = places + 16; + + if (xp > 0) + jj += xp; + } + + if (jj > 112) + { + if ((vp = (void *)MAPM_MALLOC((jj + 16) * sizeof(char))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, + "\'m_apm_to_fixpt_string\', Out of memory"); + } + + cpw = (char *)vp; + } + else + { + cpw = sbuf; + } + + /* + * at this point, the number is non-zero and the output + * string will contain at least 1 significant digit. + */ + + if (ctmp->m_apm_sign == -1) /* negative number */ + { + *cpd++ = '-'; + } + + ucp = ctmp->m_apm_data; + ii = 0; + + /* convert MAPM num to ASCII digits and store in working char array */ + + while (TRUE) + { + M_get_div_rem_10((int)(*ucp++), &numdiv, &numrem); + + cpw[ii++] = numdiv + '0'; + cpw[ii++] = numrem + '0'; + + if (--numb == 0) + break; + } + + i2 = ii; /* save for later */ + + if (places < 0) /* show ALL digits */ + { + places = dl - xp; + + if (places < 1) + places = 1; + } + + /* pad with trailing zeros if needed */ + + kk = xp + places + 2 - ii; + + if (kk > 0) + memset(&cpw[ii], '0', kk); + + if (xp > 0) /* |num| >= 1, NO lead-in "0.nnn" */ + { + ii = xp + places + 1; + jj = 0; + + for (kk = 0; kk < ii; kk++) + { + if (kk == xp) + cpd[jj++] = '.'; + + cpd[jj++] = cpw[kk]; + } + + cpd[ii] = '\0'; + } + else /* |num| < 1, have lead-in "0.nnn" */ + { + jj = 2 - xp; + ii = 2 + places; + memset(cpd, '0', (ii + 1)); /* pre-load string with all '0' */ + cpd[1] = '.'; /* assign decimal point */ + + for (kk = 0; kk < i2; kk++) + { + cpd[jj++] = cpw[kk]; + } + + cpd[ii] = '\0'; + } + + if (vp != NULL) + MAPM_FREE(vp); + + M_restore_stack(1); +} +/****************************************************************************/ +void M_apm_round_fixpt(M_APM btmp, int places, M_APM atmp) +{ + int xp, ii; + + xp = atmp->m_apm_exponent; + ii = xp + places - 1; + + M_set_to_zero(btmp); /* assume number is too small so the net result is 0 */ + + if (ii >= 0) + { + m_apm_round(btmp, ii, atmp); + } + else + { + if (ii == -1) /* next digit is significant which may round up */ + { + if (atmp->m_apm_data[0] >= 50) /* digit >= 5, round up */ + { + m_apm_copy(btmp, atmp); + btmp->m_apm_data[0] = 10; + btmp->m_apm_exponent += 1; + btmp->m_apm_datalength = 1; + M_apm_normalize(btmp); + } + } + } +} +/****************************************************************************/ + diff --git a/pgscript/utilities/m_apm/mapm_gcd.cpp b/pgscript/utilities/m_apm/mapm_gcd.cpp new file mode 100644 index 0000000..d3d136a --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_gcd.cpp @@ -0,0 +1,260 @@ + +/* + * M_APM - mapm_gcd.c + * + * Copyright (C) 2001 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the GCD and LCM functions + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +/* + * From Knuth, The Art of Computer Programming: + * + * This is the binary GCD algorithm as described + * in the book (Algorithm B) + */ +void m_apm_gcd(M_APM r, M_APM u, M_APM v) +{ + M_APM tmpM, tmpN, tmpT, tmpU, tmpV; + int kk, kr, mm; + long pow_2; + + /* 'is_integer' will return 0 || 1 */ + + if ((m_apm_is_integer(u) + m_apm_is_integer(v)) != 2) + { + M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_gcd\', Non-integer input"); + + M_set_to_zero(r); + return; + } + + if (u->m_apm_sign == 0) + { + m_apm_absolute_value(r, v); + return; + } + + if (v->m_apm_sign == 0) + { + m_apm_absolute_value(r, u); + return; + } + + tmpM = M_get_stack_var(); + tmpN = M_get_stack_var(); + tmpT = M_get_stack_var(); + tmpU = M_get_stack_var(); + tmpV = M_get_stack_var(); + + m_apm_absolute_value(tmpU, u); + m_apm_absolute_value(tmpV, v); + + /* Step B1 */ + + kk = 0; + + while (TRUE) + { + mm = 1; + if (m_apm_is_odd(tmpU)) + break; + + mm = 0; + if (m_apm_is_odd(tmpV)) + break; + + m_apm_multiply(tmpN, MM_0_5, tmpU); + m_apm_copy(tmpU, tmpN); + + m_apm_multiply(tmpN, MM_0_5, tmpV); + m_apm_copy(tmpV, tmpN); + + kk++; + } + + /* Step B2 */ + + if (mm) + { + m_apm_negate(tmpT, tmpV); + goto B4; + } + + m_apm_copy(tmpT, tmpU); + + /* Step: */ + +B3: + + m_apm_multiply(tmpN, MM_0_5, tmpT); + m_apm_copy(tmpT, tmpN); + + /* Step: */ + +B4: + + if (m_apm_is_even(tmpT)) + goto B3; + + /* Step B5 */ + + if (tmpT->m_apm_sign == 1) + m_apm_copy(tmpU, tmpT); + else + m_apm_negate(tmpV, tmpT); + + /* Step B6 */ + + m_apm_subtract(tmpT, tmpU, tmpV); + + if (tmpT->m_apm_sign != 0) + goto B3; + + /* + * result = U * 2 ^ kk + */ + + if (kk == 0) + m_apm_copy(r, tmpU); + else + { + if (kk == 1) + m_apm_multiply(r, tmpU, MM_Two); + + if (kk == 2) + m_apm_multiply(r, tmpU, MM_Four); + + if (kk >= 3) + { + mm = kk / 28; + kr = kk % 28; + pow_2 = 1L << kr; + + if (mm == 0) + { + m_apm_set_long(tmpN, pow_2); + m_apm_multiply(r, tmpU, tmpN); + } + else + { + m_apm_copy(tmpN, MM_One); + m_apm_set_long(tmpM, 0x10000000L); /* 2 ^ 28 */ + + while (TRUE) + { + m_apm_multiply(tmpT, tmpN, tmpM); + m_apm_copy(tmpN, tmpT); + + if (--mm == 0) + break; + } + + if (kr == 0) + { + m_apm_multiply(r, tmpU, tmpN); + } + else + { + m_apm_set_long(tmpM, pow_2); + m_apm_multiply(tmpT, tmpN, tmpM); + m_apm_multiply(r, tmpU, tmpT); + } + } + } + } + + M_restore_stack(5); +} +/****************************************************************************/ +/* + * u * v + * LCM(u,v) = ------------ + * GCD(u,v) + */ + +void m_apm_lcm(M_APM r, M_APM u, M_APM v) +{ + M_APM tmpN, tmpG; + + tmpN = M_get_stack_var(); + tmpG = M_get_stack_var(); + + m_apm_multiply(tmpN, u, v); + m_apm_gcd(tmpG, u, v); + m_apm_integer_divide(r, tmpN, tmpG); + + M_restore_stack(2); +} +/****************************************************************************/ + +#ifdef BIG_COMMENT_BLOCK + +/* + * traditional GCD included for reference + * (also useful for testing ...) + */ + +/* + * From Knuth, The Art of Computer Programming: + * + * To compute GCD(u,v) + * + * A1: + * if (v == 0) return (u) + * A2: + * t = u mod v + * u = v + * v = t + * goto A1 + */ +void m_apm_gcd_traditional(M_APM r, M_APM u, M_APM v) +{ + M_APM tmpD, tmpN, tmpU, tmpV; + + tmpD = M_get_stack_var(); + tmpN = M_get_stack_var(); + tmpU = M_get_stack_var(); + tmpV = M_get_stack_var(); + + m_apm_absolute_value(tmpU, u); + m_apm_absolute_value(tmpV, v); + + while (TRUE) + { + if (tmpV->m_apm_sign == 0) + break; + + m_apm_integer_div_rem(tmpD, tmpN, tmpU, tmpV); + m_apm_copy(tmpU, tmpV); + m_apm_copy(tmpV, tmpN); + } + + m_apm_copy(r, tmpU); + M_restore_stack(4); +} +/****************************************************************************/ + +#endif + diff --git a/pgscript/utilities/m_apm/mapm_lg2.cpp b/pgscript/utilities/m_apm/mapm_lg2.cpp new file mode 100644 index 0000000..8810650 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_lg2.cpp @@ -0,0 +1,152 @@ + +/* + * M_APM - mapm_lg2.c + * + * Copyright (C) 2003 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the iterative function to compute the LOG + * This is an internal function to the library and is not intended + * to be called directly by the user. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ + +/* + * compute rr = log(nn) + * + * input is assumed to not exceed the exponent range of a normal + * 'C' double ( |exponent| must be < 308) + */ + +/****************************************************************************/ +void M_log_solve_cubic(M_APM rr, int places, M_APM nn) +{ + M_APM tmp0, tmp1, tmp2, tmp3, guess; + int ii, maxp, tolerance, local_precision; + + guess = M_get_stack_var(); + tmp0 = M_get_stack_var(); + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + tmp3 = M_get_stack_var(); + + M_get_log_guess(guess, nn); + + tolerance = -(places + 4); + maxp = places + 16; + local_precision = 18; + + /* Use the following iteration to solve for log : + + exp(X) - N + X = X - 2 * ------------ + n+1 exp(X) + N + + + this is a cubically convergent algorithm + (each iteration yields 3X more digits) + */ + + ii = 0; + + while (TRUE) + { + m_apm_exp(tmp1, local_precision, guess); + + m_apm_subtract(tmp3, tmp1, nn); + m_apm_add(tmp2, tmp1, nn); + + m_apm_divide(tmp1, local_precision, tmp3, tmp2); + m_apm_multiply(tmp0, MM_Two, tmp1); + m_apm_subtract(tmp3, guess, tmp0); + + if (ii != 0) + { + if (((3 * tmp0->m_apm_exponent) < tolerance) || (tmp0->m_apm_sign == 0)) + break; + } + + m_apm_round(guess, local_precision, tmp3); + + local_precision *= 3; + + if (local_precision > maxp) + local_precision = maxp; + + ii = 1; + } + + m_apm_round(rr, places, tmp3); + M_restore_stack(5); +} +/****************************************************************************/ +/* + * find log(N) + * + * if places < 360 + * solve with cubically convergent algorithm above + * + * else + * + * let 'X' be 'close' to the solution (we use ~110 decimal places) + * + * let Y = N * exp(-X) - 1 + * + * then + * + * log(N) = X + log(1 + Y) + * + * since 'Y' will be small, we can use the efficient log_near_1 algorithm. + * + */ +void M_log_basic_iteration(M_APM rr, int places, M_APM nn) +{ + M_APM tmp0, tmp1, tmp2, tmpX; + + if (places < 360) + { + M_log_solve_cubic(rr, places, nn); + } + else + { + tmp0 = M_get_stack_var(); + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + tmpX = M_get_stack_var(); + + M_log_solve_cubic(tmpX, 110, nn); + + m_apm_negate(tmp0, tmpX); + m_apm_exp(tmp1, (places + 8), tmp0); + m_apm_multiply(tmp2, tmp1, nn); + m_apm_subtract(tmp1, tmp2, MM_One); + + M_log_near_1(tmp0, (places - 104), tmp1); + + m_apm_add(tmp1, tmpX, tmp0); + m_apm_round(rr, places, tmp1); + + M_restore_stack(4); + } +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapm_lg3.cpp b/pgscript/utilities/m_apm/mapm_lg3.cpp new file mode 100644 index 0000000..1059e18 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_lg3.cpp @@ -0,0 +1,204 @@ + +/* + * M_APM - mapm_lg3.c + * + * Copyright (C) 2003 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the function to compute log(2), log(10), + * and 1/log(10) to the desired precision using an AGM algorithm. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/* + * using the 'R' function (defined below) for 'N' decimal places : + * + * + * -N -N + * log(2) = R(1, 0.5 * 10 ) - R(1, 10 ) + * + * + * -N -N + * log(10) = R(1, 0.1 * 10 ) - R(1, 10 ) + * + * + * In general: + * + * -N -N + * log(x) = R(1, 10 / x) - R(1, 10 ) + * + * + * I found this on a web site which went into considerable detail + * on the history of log(2). This formula is algebraically identical + * to the formula specified in J. Borwein and P. Borwein's book + * "PI and the AGM". (reference algorithm 7.2) + */ + +/****************************************************************************/ +/* + * check if our local copy of log(2) & log(10) is precise + * enough for our purpose. if not, calculate them so it's + * as precise as desired, accurate to at least 'places'. + */ +void M_check_log_places(int places) +{ + M_APM tmp6, tmp7, tmp8, tmp9; + int dplaces; + + dplaces = places + 4; + + if (dplaces > MM_lc_log_digits) + { + MM_lc_log_digits = dplaces + 4; + + tmp6 = M_get_stack_var(); + tmp7 = M_get_stack_var(); + tmp8 = M_get_stack_var(); + tmp9 = M_get_stack_var(); + + dplaces += 6 + (int)log10((double)places); + + m_apm_copy(tmp7, MM_One); + tmp7->m_apm_exponent = -places; + + M_log_AGM_R_func(tmp8, dplaces, MM_One, tmp7); + + m_apm_multiply(tmp6, tmp7, MM_0_5); + + M_log_AGM_R_func(tmp9, dplaces, MM_One, tmp6); + + m_apm_subtract(MM_lc_log2, tmp9, tmp8); /* log(2) */ + + tmp7->m_apm_exponent -= 1; /* divide by 10 */ + + M_log_AGM_R_func(tmp9, dplaces, MM_One, tmp7); + + m_apm_subtract(MM_lc_log10, tmp9, tmp8); /* log(10) */ + m_apm_reciprocal(MM_lc_log10R, dplaces, MM_lc_log10); /* 1 / log(10) */ + + M_restore_stack(4); + } +} +/****************************************************************************/ + +/* + * define a notation for a function 'R' : + * + * + * + * 1 + * R (a0, b0) = ------------------------------ + * + * ---- + * \ + * \ n-1 2 2 + * 1 - | 2 * (a - b ) + * / n n + * / + * ---- + * n >= 0 + * + * + * where a, b are the classic AGM iteration : + * + * + * a = 0.5 * (a + b ) + * n+1 n n + * + * + * b = sqrt(a * b ) + * n+1 n n + * + * + * + * define a variable 'c' for more efficient computation : + * + * 2 2 2 + * c = 0.5 * (a - b ) , c = a - b + * n+1 n n n n n + * + */ + +/****************************************************************************/ +void M_log_AGM_R_func(M_APM rr, int places, M_APM aa, M_APM bb) +{ + M_APM tmp1, tmp2, tmp3, tmp4, tmpC2, sum, pow_2, tmpA0, tmpB0; + int tolerance, dplaces; + + tmpA0 = M_get_stack_var(); + tmpB0 = M_get_stack_var(); + tmpC2 = M_get_stack_var(); + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + tmp3 = M_get_stack_var(); + tmp4 = M_get_stack_var(); + sum = M_get_stack_var(); + pow_2 = M_get_stack_var(); + + tolerance = places + 8; + dplaces = places + 16; + + m_apm_copy(tmpA0, aa); + m_apm_copy(tmpB0, bb); + m_apm_copy(pow_2, MM_0_5); + + m_apm_multiply(tmp1, aa, aa); /* 0.5 * [ a ^ 2 - b ^ 2 ] */ + m_apm_multiply(tmp2, bb, bb); + m_apm_subtract(tmp3, tmp1, tmp2); + m_apm_multiply(sum, MM_0_5, tmp3); + + while (TRUE) + { + m_apm_subtract(tmp1, tmpA0, tmpB0); /* C n+1 = 0.5 * [ An - Bn ] */ + m_apm_multiply(tmp4, MM_0_5, tmp1); /* C n+1 */ + m_apm_multiply(tmpC2, tmp4, tmp4); /* C n+1 ^ 2 */ + + /* do the AGM */ + + m_apm_add(tmp1, tmpA0, tmpB0); + m_apm_multiply(tmp3, MM_0_5, tmp1); + + m_apm_multiply(tmp2, tmpA0, tmpB0); + m_apm_sqrt(tmpB0, dplaces, tmp2); + + m_apm_round(tmpA0, dplaces, tmp3); + + /* end AGM */ + + m_apm_multiply(tmp2, MM_Two, pow_2); + m_apm_copy(pow_2, tmp2); + + m_apm_multiply(tmp1, tmpC2, pow_2); + m_apm_add(tmp3, sum, tmp1); + + if ((tmp1->m_apm_sign == 0) || + ((-2 * tmp1->m_apm_exponent) > tolerance)) + break; + + m_apm_round(sum, dplaces, tmp3); + } + + m_apm_subtract(tmp4, MM_One, tmp3); + m_apm_reciprocal(rr, places, tmp4); + + M_restore_stack(9); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapm_lg4.cpp b/pgscript/utilities/m_apm/mapm_lg4.cpp new file mode 100644 index 0000000..a037f43 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_lg4.cpp @@ -0,0 +1,93 @@ + +/* + * M_APM - mapm_lg4.c + * + * Copyright (C) 2003 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the LOG_NEAR_1 function. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +/* + calculate log (1 + x) with the following series: + + x + y = ----- ( |y| < 1 ) + x + 2 + + + [ 1 + y ] y^3 y^5 y^7 + log [-------] = 2 * [ y + --- + --- + --- ... ] + [ 1 - y ] 3 5 7 + +*/ +void M_log_near_1(M_APM rr, int places, M_APM xx) +{ + M_APM tmp0, tmp1, tmp2, tmpS, term; + int tolerance, dplaces, local_precision; + long m1; + + tmp0 = M_get_stack_var(); + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + tmpS = M_get_stack_var(); + term = M_get_stack_var(); + + tolerance = xx->m_apm_exponent - (places + 6); + dplaces = (places + 12) - xx->m_apm_exponent; + + m_apm_add(tmp0, xx, MM_Two); + m_apm_divide(tmpS, (dplaces + 6), xx, tmp0); + + m_apm_copy(term, tmpS); + m_apm_multiply(tmp0, tmpS, tmpS); + m_apm_round(tmp2, (dplaces + 6), tmp0); + + m1 = 3L; + + while (TRUE) + { + m_apm_multiply(tmp0, term, tmp2); + + if ((tmp0->m_apm_exponent < tolerance) || (tmp0->m_apm_sign == 0)) + break; + + local_precision = dplaces + tmp0->m_apm_exponent; + + if (local_precision < 20) + local_precision = 20; + + m_apm_set_long(tmp1, m1); + m_apm_round(term, local_precision, tmp0); + m_apm_divide(tmp0, local_precision, term, tmp1); + m_apm_add(tmp1, tmpS, tmp0); + m_apm_copy(tmpS, tmp1); + m1 += 2; + } + + m_apm_multiply(tmp0, MM_Two, tmpS); + m_apm_round(rr, places, tmp0); + + M_restore_stack(5); /* restore the 5 locals we used here */ +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapm_log.cpp b/pgscript/utilities/m_apm/mapm_log.cpp new file mode 100644 index 0000000..9066120 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_log.cpp @@ -0,0 +1,138 @@ + +/* + * M_APM - mapm_log.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the LOG and LOG10 functions. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +/* + Calls the LOG function. The formula used is : + + log10(x) = A * log(x) where A = log (e) [0.43429448190325...] + 10 +*/ +void m_apm_log10(M_APM rr, int places, M_APM aa) +{ + int dplaces; + M_APM tmp8, tmp9; + + tmp8 = M_get_stack_var(); + tmp9 = M_get_stack_var(); + + dplaces = places + 4; + M_check_log_places(dplaces + 45); + + m_apm_log(tmp9, dplaces, aa); + m_apm_multiply(tmp8, tmp9, MM_lc_log10R); + m_apm_round(rr, places, tmp8); + M_restore_stack(2); /* restore the 2 locals we used here */ +} +/****************************************************************************/ +void m_apm_log(M_APM r, int places, M_APM a) +{ + M_APM tmp0, tmp1, tmp2; + int mexp, dplaces; + + if (a->m_apm_sign <= 0) + { + M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_log\', Negative argument"); + M_set_to_zero(r); + return; + } + + tmp0 = M_get_stack_var(); + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + + dplaces = places + 8; + + /* + * if the input is real close to 1, use the series expansion + * to compute the log. + * + * 0.9999 < a < 1.0001 + */ + + mexp = a->m_apm_exponent; + + if (mexp == 0 || mexp == 1) + { + m_apm_subtract(tmp0, a, MM_One); + + if (tmp0->m_apm_sign == 0) /* is input exactly 1 ?? */ + { + /* if so, result is 0 */ + M_set_to_zero(r); + M_restore_stack(3); + return; + } + + if (tmp0->m_apm_exponent <= -4) + { + M_log_near_1(r, places, tmp0); + M_restore_stack(3); + return; + } + } + + /* make sure our log(10) is accurate enough for this calculation */ + /* (and log(2) which is called from M_log_basic_iteration) */ + + M_check_log_places(dplaces + 25); + + if (abs(mexp) <= 3) + { + M_log_basic_iteration(r, places, a); + } + else + { + /* + * use log (x * y) = log(x) + log(y) + * + * here we use y = exponent of our base 10 number. + * + * let 'C' = log(10) = 2.3025850929940.... + * + * then log(x * y) = log(x) + ( C * base_10_exponent ) + */ + + m_apm_copy(tmp2, a); + + mexp = tmp2->m_apm_exponent - 2; + tmp2->m_apm_exponent = 2; /* force number between 10 & 100 */ + + M_log_basic_iteration(tmp0, dplaces, tmp2); + + m_apm_set_long(tmp1, (long)mexp); + m_apm_multiply(tmp2, tmp1, MM_lc_log10); + m_apm_add(tmp1, tmp2, tmp0); + + m_apm_round(r, places, tmp1); + } + + M_restore_stack(3); /* restore the 3 locals we used here */ +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapm_mul.cpp b/pgscript/utilities/m_apm/mapm_mul.cpp new file mode 100644 index 0000000..3ace4f8 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_mul.cpp @@ -0,0 +1,131 @@ + +/* + * M_APM - mapm_mul.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains basic multiplication function. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +extern void M_fast_multiply(M_APM, M_APM, M_APM); + +/****************************************************************************/ +void m_apm_multiply(M_APM r, M_APM a, M_APM b) +{ + int ai, itmp, sign, nexp, ii, jj, indexa, indexb, index0, numdigits; + UCHAR *cp, *cpr, *cp_div, *cp_rem; + void *vp; + + sign = a->m_apm_sign * b->m_apm_sign; + nexp = a->m_apm_exponent + b->m_apm_exponent; + + if (sign == 0) /* one number is zero, result is zero */ + { + M_set_to_zero(r); + return; + } + + numdigits = a->m_apm_datalength + b->m_apm_datalength; + indexa = (a->m_apm_datalength + 1) >> 1; + indexb = (b->m_apm_datalength + 1) >> 1; + + /* + * If we are multiplying 2 'big' numbers, use the fast algorithm. + * + * This is a **very** approx break even point between this algorithm + * and the FFT multiply. Note that different CPU's, operating systems, + * and compiler's may yield a different break even point. This point + * (~96 decimal digits) is how the test came out on the author's system. + */ + + if (indexa >= 48 && indexb >= 48) + { + M_fast_multiply(r, a, b); + return; + } + + ii = (numdigits + 1) >> 1; /* required size of result, in bytes */ + + if (ii > r->m_apm_malloclength) + { + if ((vp = MAPM_REALLOC(r->m_apm_data, (ii + 32))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, "\'m_apm_multiply\', Out of memory"); + } + + r->m_apm_malloclength = ii + 28; + r->m_apm_data = (UCHAR *)vp; + } + + M_get_div_rem_addr(&cp_div, &cp_rem); + + index0 = indexa + indexb; + cp = r->m_apm_data; + memset(cp, 0, index0); + ii = indexa; + + while (TRUE) + { + index0--; + cpr = cp + index0; + jj = indexb; + ai = (int)a->m_apm_data[--ii]; + + while (TRUE) + { + itmp = ai * b->m_apm_data[--jj]; + + *(cpr - 1) += cp_div[itmp]; + *cpr += cp_rem[itmp]; + + if (*cpr >= 100) + { + *cpr -= 100; + *(cpr - 1) += 1; + } + + cpr--; + + if (*cpr >= 100) + { + *cpr -= 100; + *(cpr - 1) += 1; + } + + if (jj == 0) + break; + } + + if (ii == 0) + break; + } + + r->m_apm_sign = sign; + r->m_apm_exponent = nexp; + r->m_apm_datalength = numdigits; + + M_apm_normalize(r); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapm_pow.cpp b/pgscript/utilities/m_apm/mapm_pow.cpp new file mode 100644 index 0000000..cf0a22f --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_pow.cpp @@ -0,0 +1,147 @@ + +/* + * M_APM - mapm_pow.c + * + * Copyright (C) 2000 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the POW function. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +static M_APM M_last_xx_input; +static M_APM M_last_xx_log; +static int M_last_log_digits; +static int M_size_flag = 0; + +/****************************************************************************/ +void M_free_all_pow() +{ + if (M_size_flag != 0) + { + m_apm_free(M_last_xx_input); + m_apm_free(M_last_xx_log); + M_size_flag = 0; + } +} +/****************************************************************************/ +/* + Calculate the POW function by calling EXP : + + Y A + X = e where A = Y * log(X) +*/ +void m_apm_pow(M_APM rr, int places, M_APM xx, M_APM yy) +{ + int iflag, pflag; + char sbuf[64]; + M_APM tmp8, tmp9; + + /* if yy == 0, return 1 */ + + if (yy->m_apm_sign == 0) + { + m_apm_copy(rr, MM_One); + return; + } + + /* if xx == 0, return 0 */ + + if (xx->m_apm_sign == 0) + { + M_set_to_zero(rr); + return; + } + + if (M_size_flag == 0) /* init locals on first call */ + { + M_size_flag = M_get_sizeof_int(); + M_last_log_digits = 0; + M_last_xx_input = m_apm_init(); + M_last_xx_log = m_apm_init(); + } + + /* + * if 'yy' is a small enough integer, call the more + * efficient _integer_pow function. + */ + + if (m_apm_is_integer(yy)) + { + iflag = FALSE; + + if (M_size_flag == 2) /* 16 bit compilers */ + { + if (yy->m_apm_exponent <= 4) + iflag = TRUE; + } + else /* >= 32 bit compilers */ + { + if (yy->m_apm_exponent <= 7) + iflag = TRUE; + } + + if (iflag) + { + m_apm_to_integer_string(sbuf, yy); + m_apm_integer_pow(rr, places, xx, atoi(sbuf)); + return; + } + } + + tmp8 = M_get_stack_var(); + tmp9 = M_get_stack_var(); + + /* + * If parameter 'X' is the same this call as it + * was the previous call, re-use the saved log + * calculation from last time. + */ + + pflag = FALSE; + + if (M_last_log_digits >= places) + { + if (m_apm_compare(xx, M_last_xx_input) == 0) + pflag = TRUE; + } + + if (pflag) + { + m_apm_round(tmp9, (places + 8), M_last_xx_log); + } + else + { + m_apm_log(tmp9, (places + 8), xx); + + M_last_log_digits = places + 2; + + /* save the 'X' input value and the log calculation */ + + m_apm_copy(M_last_xx_input, xx); + m_apm_copy(M_last_xx_log, tmp9); + } + + m_apm_multiply(tmp8, tmp9, yy); + m_apm_exp(rr, places, tmp8); + M_restore_stack(2); /* restore the 2 locals we used here */ +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapm_rcp.cpp b/pgscript/utilities/m_apm/mapm_rcp.cpp new file mode 100644 index 0000000..0709a12 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_rcp.cpp @@ -0,0 +1,168 @@ + +/* + * M_APM - mapm_rcp.c + * + * Copyright (C) 2000 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the fast division and reciprocal functions + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +void m_apm_divide(M_APM rr, int places, M_APM aa, M_APM bb) +{ + M_APM tmp0, tmp1; + int sn, nexp, dplaces; + + sn = aa->m_apm_sign * bb->m_apm_sign; + + if (sn == 0) /* one number is zero, result is zero */ + { + if (bb->m_apm_sign == 0) + { + M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_divide\', Divide by 0"); + } + + M_set_to_zero(rr); + return; + } + + /* + * Use the original 'Knuth' method for smaller divides. On the + * author's system, this was the *approx* break even point before + * the reciprocal method used below became faster. + */ + + if (places < 250) + { + M_apm_sdivide(rr, places, aa, bb); + return; + } + + /* mimic the decimal place behavior of the original divide */ + + nexp = aa->m_apm_exponent - bb->m_apm_exponent; + + if (nexp > 0) + dplaces = nexp + places; + else + dplaces = places; + + tmp0 = M_get_stack_var(); + tmp1 = M_get_stack_var(); + + m_apm_reciprocal(tmp0, (dplaces + 8), bb); + m_apm_multiply(tmp1, tmp0, aa); + m_apm_round(rr, dplaces, tmp1); + + M_restore_stack(2); +} +/****************************************************************************/ +void m_apm_reciprocal(M_APM rr, int places, M_APM aa) +{ + M_APM last_x, guess, tmpN, tmp1, tmp2; + char sbuf[32]; + int ii, bflag, dplaces, nexp, tolerance; + + if (aa->m_apm_sign == 0) + { + M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_reciprocal\', Input = 0"); + + M_set_to_zero(rr); + return; + } + + last_x = M_get_stack_var(); + guess = M_get_stack_var(); + tmpN = M_get_stack_var(); + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + + m_apm_absolute_value(tmpN, aa); + + /* + normalize the input number (make the exponent 0) so + the 'guess' below will not over/under flow on large + magnitude exponents. + */ + + nexp = aa->m_apm_exponent; + tmpN->m_apm_exponent -= nexp; + + m_apm_to_string(sbuf, 15, tmpN); + m_apm_set_double(guess, (1.0 / atof(sbuf))); + + tolerance = places + 4; + dplaces = places + 16; + bflag = FALSE; + + m_apm_negate(last_x, MM_Ten); + + /* Use the following iteration to calculate the reciprocal : + + + X = X * [ 2 - N * X ] + n+1 + */ + + ii = 0; + + while (TRUE) + { + m_apm_multiply(tmp1, tmpN, guess); + m_apm_subtract(tmp2, MM_Two, tmp1); + m_apm_multiply(tmp1, tmp2, guess); + + if (bflag) + break; + + m_apm_round(guess, dplaces, tmp1); + + /* force at least 2 iterations so 'last_x' has valid data */ + + if (ii != 0) + { + m_apm_subtract(tmp2, guess, last_x); + + if (tmp2->m_apm_sign == 0) + break; + + /* + * if we are within a factor of 4 on the error term, + * we will be accurate enough after the *next* iteration + * is complete. + */ + + if ((-4 * tmp2->m_apm_exponent) > tolerance) + bflag = TRUE; + } + + m_apm_copy(last_x, guess); + ii++; + } + + m_apm_round(rr, places, tmp1); + rr->m_apm_exponent -= nexp; + rr->m_apm_sign = aa->m_apm_sign; + M_restore_stack(5); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapm_rnd.cpp b/pgscript/utilities/m_apm/mapm_rnd.cpp new file mode 100644 index 0000000..66ca0fa --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_rnd.cpp @@ -0,0 +1,360 @@ + +/* + * M_APM - mapm_rnd.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the Random Number Generator function. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +#ifndef _HAVE_NI_LABWIN_CVI_ +#ifdef MSDOS +#include +#include +#else +#include +extern void M_get_microsec(unsigned long *, long *); +#endif +#endif + +#ifdef _HAVE_NI_LABWIN_CVI_ +#include +#include +#include +#endif + +extern void M_reverse_string(char *); +extern void M_get_rnd_seed(M_APM); + +static M_APM M_rnd_aa; +static M_APM M_rnd_mm; +static M_APM M_rnd_XX; +static M_APM M_rtmp0; +static M_APM M_rtmp1; + +static int M_firsttime2 = TRUE; + +/* + Used Knuth's The Art of Computer Programming, Volume 2 as + the basis. Assuming the random number is X, compute + (where all the math is performed on integers) : + + X = (a * X + c) MOD m + + From Knuth: + + 'm' should be large, at least 2^30 : we use 1.0E+15 + + 'a' should be between .01m and .99m and not have a simple + pattern. 'a' should not have any large factors in common + with 'm' and (since 'm' is a power of 10) if 'a' MOD 200 + = 21 then all 'm' different possible values will be + generated before 'X' starts to repeat. + + We use 'a' = 716805947629621. + + This is a prime number and also meets 'a' MOD 200 = 21. + Commented out below are many potential multipliers that + are all prime and meet 'a' MOD 200 = 21. + + There are few restrictions on 'c' except 'c' can have no + factor in common with 'm', hence we set 'c' = 'a'. + + On the first call, the system time is used to initialize X. +*/ + +/* + * the following constants are all potential multipliers. they are + * all prime numbers that also meet the criteria of NUM mod 200 = 21. + */ + +/* +439682071525421 439682071528421 439682071529221 439682071529821 +439682071530421 439682071532021 439682071538821 439682071539421 +439682071540021 439682071547021 439682071551221 439682071553821 +439682071555421 439682071557221 439682071558021 439682071558621 +439682071559821 439652381461621 439652381465221 439652381465621 +439652381466421 439652381467421 439652381468621 439652381470021 +439652381471221 439652381477021 439652381484221 439652381488421 +439652381491021 439652381492021 439652381494021 439652381496821 +617294387035621 617294387038621 617294387039221 617294387044421 +617294387045221 617294387048621 617294387051621 617294387051821 +617294387053621 617294387058421 617294387064221 617294387065621 +617294387068621 617294387069221 617294387069821 617294387070421 +617294387072021 617294387072621 617294387073821 617294387076821 +649378126517621 649378126517821 649378126518221 649378126520821 +649378126523821 649378126525621 649378126526621 649378126528421 +649378126529621 649378126530821 649378126532221 649378126533221 +649378126535221 649378126539421 649378126543621 649378126546021 +649378126546421 649378126549421 649378126550821 649378126555021 +649378126557421 649378126560221 649378126561621 649378126562021 +649378126564621 649378126565821 672091582360421 672091582364221 +672091582364621 672091582367021 672091582368421 672091582369021 +672091582370821 672091582371421 672091582376821 672091582380821 +716805243983221 716805243984821 716805947623621 716805947624621 +716805947629021 716805947629621 716805947630621 716805947633621 +716805947634221 716805947635021 716805947635621 716805947642221 +*/ + +/****************************************************************************/ +void M_free_all_rnd() +{ + if (M_firsttime2 == FALSE) + { + m_apm_free(M_rnd_aa); + m_apm_free(M_rnd_mm); + m_apm_free(M_rnd_XX); + m_apm_free(M_rtmp0); + m_apm_free(M_rtmp1); + + M_firsttime2 = TRUE; + } +} +/****************************************************************************/ +void m_apm_set_random_seed(char *ss) +{ + M_APM btmp; + + if (M_firsttime2) + { + btmp = M_get_stack_var(); + m_apm_get_random(btmp); + M_restore_stack(1); + } + + m_apm_set_string(M_rnd_XX, ss); +} +/****************************************************************************/ +/* + * compute X = (a * X + c) MOD m where c = a + */ +void m_apm_get_random(M_APM mrnd) +{ + + if (M_firsttime2) /* use the system time as the initial seed value */ + { + M_firsttime2 = FALSE; + + M_rnd_aa = m_apm_init(); + M_rnd_XX = m_apm_init(); + M_rnd_mm = m_apm_init(); + M_rtmp0 = m_apm_init(); + M_rtmp1 = m_apm_init(); + + /* set the multiplier M_rnd_aa and M_rnd_mm */ + + m_apm_set_string(M_rnd_aa, "716805947629621"); + m_apm_set_string(M_rnd_mm, "1.0E15"); + + M_get_rnd_seed(M_rnd_XX); + } + + m_apm_multiply(M_rtmp0, M_rnd_XX, M_rnd_aa); + m_apm_add(M_rtmp1, M_rtmp0, M_rnd_aa); + m_apm_integer_div_rem(M_rtmp0, M_rnd_XX, M_rtmp1, M_rnd_mm); + m_apm_copy(mrnd, M_rnd_XX); + mrnd->m_apm_exponent -= 15; +} +/****************************************************************************/ +void M_reverse_string(char *s) +{ + int ct; + char ch, *p1, *p2; + + if ((ct = strlen(s)) <= 1) + return; + + p1 = s; + p2 = s + ct - 1; + ct /= 2; + + while (TRUE) + { + ch = *p1; + *p1++ = *p2; + *p2-- = ch; + + if (--ct == 0) + break; + } +} +/****************************************************************************/ + +#ifndef _HAVE_NI_LABWIN_CVI_ + +#ifdef MSDOS + +/****************************************************************************/ +/* + * for DOS / Win 9x/NT systems : use 'ftime' + */ +void M_get_rnd_seed(M_APM mm) +{ + int millisec; + time_t timestamp; + unsigned long ul; + char ss[32], buf1[48], buf2[32]; + struct timeb timebuffer; + M_APM atmp; + + atmp = M_get_stack_var(); + + ftime(&timebuffer); + + millisec = (int)timebuffer.millitm; + timestamp = timebuffer.time; + ul = (unsigned long)(timestamp / 7); + ul += timestamp + 537; + strcpy(ss, ctime(×tamp)); /* convert to string and copy to ss */ + + sprintf(buf1, "%d", (millisec / 10)); + sprintf(buf2, "%lu", ul); + + ss[0] = ss[18]; + ss[1] = ss[17]; + ss[2] = ss[15]; + ss[3] = ss[14]; + ss[4] = ss[12]; + ss[5] = ss[11]; + ss[6] = ss[9]; + ss[7] = ss[23]; + ss[8] = ss[20]; + ss[9] = '\0'; + + M_reverse_string(buf2); + strcat(buf1, buf2); + strcat(buf1, ss); + + m_apm_set_string(atmp, buf1); + atmp->m_apm_exponent = 15; + m_apm_integer_divide(mm, atmp, MM_One); + + M_restore_stack(1); +} +/****************************************************************************/ + +#else + +/****************************************************************************/ +/* + * for unix systems : use 'gettimeofday' + */ +void M_get_rnd_seed(M_APM mm) +{ + unsigned long sec3; + long usec3; + char buf1[32], buf2[32]; + M_APM atmp; + + atmp = M_get_stack_var(); + M_get_microsec(&sec3, &usec3); + + sprintf(buf1, "%ld", usec3); + sprintf(buf2, "%lu", sec3); + M_reverse_string(buf2); + strcat(buf1, buf2); + + m_apm_set_string(atmp, buf1); + atmp->m_apm_exponent = 15; + m_apm_integer_divide(mm, atmp, MM_One); + + M_restore_stack(1); +} +/****************************************************************************/ +void M_get_microsec(unsigned long *sec, long *usec) +{ + struct timeval time_now; /* current time for elapsed time check */ + struct timezone time_zone; /* time zone for gettimeofday call */ + + gettimeofday(&time_now, &time_zone); /* get current time */ + + *sec = time_now.tv_sec; + *usec = time_now.tv_usec; +} +/****************************************************************************/ + +#endif +#endif + +#ifdef _HAVE_NI_LABWIN_CVI_ + +/****************************************************************************/ +/* + * for National Instruments LabWindows CVI + */ + +void M_get_rnd_seed(M_APM mm) +{ + double timer0; + int millisec; + char *cvi_time, *cvi_date, buf1[64], buf2[32]; + M_APM atmp; + + atmp = M_get_stack_var(); + + cvi_date = DateStr(); + cvi_time = TimeStr(); + timer0 = Timer(); + + /* + * note that Timer() is not syncronized to TimeStr(), + * but we don't care here since we are just looking + * for a random source of digits. + */ + + millisec = (int)(0.01 + 1000.0 * (timer0 - floor(timer0))); + + sprintf(buf1, "%d", millisec); + + buf2[0] = cvi_time[6]; /* time format: "HH:MM:SS" */ + buf2[1] = cvi_time[7]; + buf2[2] = cvi_time[3]; + buf2[3] = cvi_time[4]; + buf2[4] = cvi_time[0]; + buf2[5] = cvi_time[1]; + + buf2[6] = cvi_date[3]; /* date format: "MM-DD-YYYY" */ + buf2[7] = cvi_date[4]; + buf2[8] = cvi_date[0]; + buf2[9] = cvi_date[1]; + buf2[10] = cvi_date[8]; + buf2[11] = cvi_date[9]; + buf2[12] = cvi_date[7]; + + buf2[13] = '4'; + buf2[14] = '7'; + buf2[15] = '\0'; + + strcat(buf1, buf2); + + m_apm_set_string(atmp, buf1); + atmp->m_apm_exponent = 15; + m_apm_integer_divide(mm, atmp, MM_One); + + M_restore_stack(1); +} + +#endif + +/****************************************************************************/ + diff --git a/pgscript/utilities/m_apm/mapm_set.cpp b/pgscript/utilities/m_apm/mapm_set.cpp new file mode 100644 index 0000000..914c775 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_set.cpp @@ -0,0 +1,357 @@ + +/* + * M_APM - mapm_set.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the functions necessary to get C 'longs' and + * 'strings' into the MAPM number system. It also contains the function + * to get a string from a MAPM number. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +static char *M_buf = NULL; +static int M_lbuf = 0; +static const char *M_set_string_error_msg = "\'m_apm_set_string\', Out of memory"; + +/****************************************************************************/ +void M_free_all_set() +{ + if (M_lbuf != 0) + { + MAPM_FREE(M_buf); + M_buf = NULL; + M_lbuf = 0; + } +} +/****************************************************************************/ +void m_apm_set_long(M_APM atmp, long mm) +{ + int len, ii, nbytes; + char *p, *buf, ch, buf2[64]; + + /* if zero, return right away */ + + if (mm == 0) + { + M_set_to_zero(atmp); + return; + } + + M_long_2_ascii(buf2, mm); /* convert long -> ascii in base 10 */ + buf = buf2; + + if (mm < 0) + { + atmp->m_apm_sign = -1; + buf++; /* get past '-' sign */ + } + else + { + atmp->m_apm_sign = 1; + } + + len = strlen(buf); + atmp->m_apm_exponent = len; + + /* least significant nibble of ODD data-length must be 0 */ + + if ((len & 1) != 0) + { + buf[len] = '0'; + } + + /* remove any trailing '0' ... */ + + while (TRUE) + { + if (buf[--len] != '0') + break; + } + + atmp->m_apm_datalength = ++len; + + nbytes = (len + 1) >> 1; + p = buf; + + for (ii = 0; ii < nbytes; ii++) + { + ch = *p++ - '0'; + atmp->m_apm_data[ii] = 10 * ch + *p++ - '0'; + } +} +/****************************************************************************/ +void m_apm_set_string(M_APM ctmp, const char *s_in) +{ + char ch, *cp, *s, *p; + void *vp; + int i, j, zflag, exponent, sign; + + if (M_lbuf == 0) + { + M_lbuf = 256; + if ((M_buf = (char *)MAPM_MALLOC(256)) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, M_set_string_error_msg); + } + } + + if ((i = strlen(s_in)) > (M_lbuf - 4)) + { + M_lbuf = i + 32; + if ((vp = MAPM_REALLOC(M_buf, M_lbuf)) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, M_set_string_error_msg); + } + + M_buf = (char *)vp; + } + + s = M_buf; + strcpy(s, s_in); + + /* default == zero ... */ + + M_set_to_zero(ctmp); + + p = s; + + while (TRUE) + { + if (*p == ' ' || *p == '\t') + p++; + else + break; + } + + if (*p == '\0') + return; + + sign = 1; /* assume number is positive */ + + if (*p == '+') /* scan by optional '+' sign */ + p++; + else + { + if (*p == '-') /* check if number negative */ + { + sign = -1; + p++; + } + } + + M_lowercase(p); /* convert string to lowercase */ + exponent = 0; /* default */ + + if ((cp = strstr(p, "e")) != NULL) + { + exponent = atoi(cp + sizeof(char)); + *cp = '\0'; /* erase the exponent now */ + } + + j = M_strposition(p, (char *) "."); /* is there a decimal point ?? */ + if (j == -1) + { + strcat(p, "."); /* if not, append one */ + j = M_strposition(p, (char *) "."); /* now find it ... */ + } + + if (j > 0) /* normalize number and adjust exponent */ + { + exponent += j; + memmove((p + 1), p, (j * sizeof(char))); + } + + p++; /* scan past implied decimal point now in column 1 (index 0) */ + + i = strlen(p); + ctmp->m_apm_datalength = i; + + if ((i & 1) != 0) /* if odd number of digits, append a '0' to make it even */ + strcat(p, "0"); + + j = strlen(p) >> 1; /* number of bytes in encoded M_APM number */ + + /* do we need more memory to hold this number */ + + if (j > ctmp->m_apm_malloclength) + { + if ((vp = MAPM_REALLOC(ctmp->m_apm_data, (j + 32))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, M_set_string_error_msg); + } + + ctmp->m_apm_malloclength = j + 28; + ctmp->m_apm_data = (UCHAR *)vp; + } + + zflag = TRUE; + + for (i = 0; i < j; i++) + { + ch = *p++ - '0'; + if ((ch = (10 * ch + *p++ - '0')) != 0) + zflag = FALSE; + + if (((int)ch & 0xFF) >= 100) + { + M_apm_log_error_msg(M_APM_RETURN, + "\'m_apm_set_string\', Non-digit char found in parse"); + + M_apm_log_error_msg(M_APM_RETURN, "Text ="); + M_apm_log_error_msg(M_APM_RETURN, s_in); + + M_set_to_zero(ctmp); + return; + } + + ctmp->m_apm_data[i] = ch; + ctmp->m_apm_data[i + 1] = 0; + } + + ctmp->m_apm_exponent = exponent; + ctmp->m_apm_sign = sign; + + if (zflag) + { + ctmp->m_apm_exponent = 0; + ctmp->m_apm_sign = 0; + ctmp->m_apm_datalength = 1; + } + else + { + M_apm_normalize(ctmp); + } + + /* + * if our local temp string is getting too big, + * release it's memory and start over next time. + * (this 1000 byte threshold is quite arbitrary, + * it may be more efficient in your app to make + * this number bigger). + */ + + if (M_lbuf > 1000) + { + MAPM_FREE(M_buf); + M_buf = NULL; + M_lbuf = 0; + } +} +/****************************************************************************/ +void m_apm_to_string(char *s, int places, M_APM mtmp) +{ + M_APM ctmp; + char *cp; + int i, index, first, max_i, num_digits, dec_places; + UCHAR numdiv, numrem; + + ctmp = M_get_stack_var(); + dec_places = places; + + if (dec_places < 0) + m_apm_copy(ctmp, mtmp); + else + m_apm_round(ctmp, dec_places, mtmp); + + if (ctmp->m_apm_sign == 0) + { + if (dec_places < 0) + strcpy(s, "0.0E+0"); + else + { + strcpy(s, "0"); + + if (dec_places > 0) + strcat(s, "."); + + for (i = 0; i < dec_places; i++) + strcat(s, "0"); + + strcat(s, "E+0"); + } + + M_restore_stack(1); + return; + } + + max_i = (ctmp->m_apm_datalength + 1) >> 1; + + if (dec_places < 0) + num_digits = ctmp->m_apm_datalength; + else + num_digits = dec_places + 1; + + cp = s; + + if (ctmp->m_apm_sign == -1) + *cp++ = '-'; + + first = TRUE; + + i = 0; + index = 0; + + while (TRUE) + { + if (index >= max_i) + { + numdiv = 0; + numrem = 0; + } + else + M_get_div_rem_10((int)ctmp->m_apm_data[index], &numdiv, &numrem); + + index++; + + *cp++ = numdiv + '0'; + + if (++i == num_digits) + break; + + if (first) + { + first = FALSE; + *cp++ = '.'; + } + + *cp++ = numrem + '0'; + + if (++i == num_digits) + break; + } + + i = ctmp->m_apm_exponent - 1; + if (i >= 0) + sprintf(cp, "E+%d", i); + else + sprintf(cp, "E%d", i); + + M_restore_stack(1); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapm_sin.cpp b/pgscript/utilities/m_apm/mapm_sin.cpp new file mode 100644 index 0000000..8d26f05 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_sin.cpp @@ -0,0 +1,140 @@ + +/* + * M_APM - mapm_sin.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the top level (user callable) SIN / COS / TAN + * functions. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +void m_apm_sin(M_APM r, int places, M_APM a) +{ + M_APM tmp3; + + tmp3 = M_get_stack_var(); + M_limit_angle_to_pi(tmp3, (places + 6), a); + M_5x_sin(r, places, tmp3); + M_restore_stack(1); +} +/****************************************************************************/ +void m_apm_cos(M_APM r, int places, M_APM a) +{ + M_APM tmp3; + + tmp3 = M_get_stack_var(); + M_limit_angle_to_pi(tmp3, (places + 6), a); + M_4x_cos(r, places, tmp3); + M_restore_stack(1); +} +/****************************************************************************/ +void m_apm_sin_cos(M_APM sinv, M_APM cosv, int places, M_APM aa) +{ + M_APM tmp5, tmp6, tmp7; + + tmp5 = M_get_stack_var(); + tmp6 = M_get_stack_var(); + tmp7 = M_get_stack_var(); + + M_limit_angle_to_pi(tmp5, (places + 6), aa); + M_4x_cos(tmp7, (places + 6), tmp5); + + /* + * compute sin(x) = sqrt(1 - cos(x) ^ 2). + * + * note that the sign of 'sin' will always be positive after the + * sqrt call. we need to adjust the sign based on what quadrant + * the original angle is in. + */ + + M_cos_to_sin(tmp6, (places + 6), tmp7); + if (tmp6->m_apm_sign != 0) + tmp6->m_apm_sign = tmp5->m_apm_sign; + + m_apm_round(sinv, places, tmp6); + m_apm_round(cosv, places, tmp7); + M_restore_stack(3); +} +/****************************************************************************/ +void m_apm_tan(M_APM r, int places, M_APM a) +{ + M_APM tmps, tmpc, tmp0; + + tmps = M_get_stack_var(); + tmpc = M_get_stack_var(); + tmp0 = M_get_stack_var(); + + m_apm_sin_cos(tmps, tmpc, (places + 4), a); + + /* tan(x) = sin(x) / cos(x) */ + + m_apm_divide(tmp0, (places + 4), tmps, tmpc); + m_apm_round(r, places, tmp0); + M_restore_stack(3); +} +/****************************************************************************/ +void M_limit_angle_to_pi(M_APM rr, int places, M_APM aa) +{ + M_APM tmp7, tmp8, tmp9; + + M_check_PI_places(places); + + tmp9 = M_get_stack_var(); + m_apm_copy(tmp9, MM_lc_PI); + + if (m_apm_compare(aa, tmp9) == 1) /* > PI */ + { + tmp7 = M_get_stack_var(); + tmp8 = M_get_stack_var(); + + m_apm_add(tmp7, aa, tmp9); + m_apm_integer_divide(tmp9, tmp7, MM_lc_2_PI); + m_apm_multiply(tmp8, tmp9, MM_lc_2_PI); + m_apm_subtract(tmp9, aa, tmp8); + m_apm_round(rr, places, tmp9); + + M_restore_stack(3); + return; + } + + tmp9->m_apm_sign = -1; + if (m_apm_compare(aa, tmp9) == -1) /* < -PI */ + { + tmp7 = M_get_stack_var(); + tmp8 = M_get_stack_var(); + + m_apm_add(tmp7, aa, tmp9); + m_apm_integer_divide(tmp9, tmp7, MM_lc_2_PI); + m_apm_multiply(tmp8, tmp9, MM_lc_2_PI); + m_apm_subtract(tmp9, aa, tmp8); + m_apm_round(rr, places, tmp9); + + M_restore_stack(3); + return; + } + + m_apm_copy(rr, aa); + M_restore_stack(1); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapmasin.cpp b/pgscript/utilities/m_apm/mapmasin.cpp new file mode 100644 index 0000000..1b50e30 --- /dev/null +++ b/pgscript/utilities/m_apm/mapmasin.cpp @@ -0,0 +1,430 @@ + +/* + * M_APM - mapmasin.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the 'ARC' family of functions; ARC-SIN, ARC-COS, + * ARC-TAN, and ARC-TAN2. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +void m_apm_arctan2(M_APM rr, int places, M_APM yy, M_APM xx) +{ + M_APM tmp5, tmp6, tmp7; + int ix, iy; + + iy = yy->m_apm_sign; + ix = xx->m_apm_sign; + + if (ix == 0) /* x == 0 */ + { + if (iy == 0) /* y == 0 */ + { + M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_arctan2\', Both Inputs = 0"); + M_set_to_zero(rr); + return; + } + + M_check_PI_places(places); + m_apm_round(rr, places, MM_lc_HALF_PI); + rr->m_apm_sign = iy; + return; + } + + if (iy == 0) + { + if (ix == 1) + { + M_set_to_zero(rr); + } + else + { + M_check_PI_places(places); + m_apm_round(rr, places, MM_lc_PI); + } + + return; + } + + /* + * the special cases have been handled, now do the real work + */ + + tmp5 = M_get_stack_var(); + tmp6 = M_get_stack_var(); + tmp7 = M_get_stack_var(); + + m_apm_divide(tmp6, (places + 6), yy, xx); + m_apm_arctan(tmp5, (places + 6), tmp6); + + if (ix == 1) /* 'x' is positive */ + { + m_apm_round(rr, places, tmp5); + } + else /* 'x' is negative */ + { + M_check_PI_places(places); + + if (iy == 1) /* 'y' is positive */ + { + m_apm_add(tmp7, tmp5, MM_lc_PI); + m_apm_round(rr, places, tmp7); + } + else /* 'y' is negative */ + { + m_apm_subtract(tmp7, tmp5, MM_lc_PI); + m_apm_round(rr, places, tmp7); + } + } + + M_restore_stack(3); +} +/****************************************************************************/ +/* + Calculate arctan using the identity : + + x + arctan (x) == arcsin [ --------------- ] + sqrt(1 + x^2) + +*/ +void m_apm_arctan(M_APM rr, int places, M_APM xx) +{ + M_APM tmp8, tmp9; + + if (xx->m_apm_sign == 0) /* input == 0 ?? */ + { + M_set_to_zero(rr); + return; + } + + if (xx->m_apm_exponent <= -4) /* input close to 0 ?? */ + { + M_arctan_near_0(rr, places, xx); + return; + } + + if (xx->m_apm_exponent >= 4) /* large input */ + { + M_arctan_large_input(rr, places, xx); + return; + } + + tmp8 = M_get_stack_var(); + tmp9 = M_get_stack_var(); + + m_apm_multiply(tmp9, xx, xx); + m_apm_add(tmp8, tmp9, MM_One); + m_apm_sqrt(tmp9, (places + 6), tmp8); + m_apm_divide(tmp8, (places + 6), xx, tmp9); + m_apm_arcsin(rr, places, tmp8); + M_restore_stack(2); +} +/****************************************************************************/ +/* + + for large input values use : + + arctan(x) = (PI / 2) - arctan(1 / |x|) + + and sign of result = sign of original input + +*/ +void M_arctan_large_input(M_APM rr, int places, M_APM xx) +{ + M_APM tmp1, tmp2; + + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + + M_check_PI_places(places); + + m_apm_divide(tmp1, (places + 6), MM_One, xx); /* 1 / xx */ + tmp1->m_apm_sign = 1; /* make positive */ + m_apm_arctan(tmp2, (places + 6), tmp1); + m_apm_subtract(tmp1, MM_lc_HALF_PI, tmp2); + m_apm_round(rr, places, tmp1); + + rr->m_apm_sign = xx->m_apm_sign; /* fix final sign */ + + M_restore_stack(2); +} +/****************************************************************************/ +void m_apm_arcsin(M_APM r, int places, M_APM x) +{ + M_APM tmp0, tmp1, tmp2, tmp3, current_x; + int ii, maxiter, maxp, tolerance, local_precision; + + current_x = M_get_stack_var(); + tmp0 = M_get_stack_var(); + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + tmp3 = M_get_stack_var(); + + m_apm_absolute_value(tmp0, x); + + ii = m_apm_compare(tmp0, MM_One); + + if (ii == 1) /* |x| > 1 */ + { + M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_arcsin\', |Argument| > 1"); + M_set_to_zero(r); + M_restore_stack(5); + return; + } + + if (ii == 0) /* |x| == 1, arcsin = +/- PI / 2 */ + { + M_check_PI_places(places); + m_apm_round(r, places, MM_lc_HALF_PI); + r->m_apm_sign = x->m_apm_sign; + + M_restore_stack(5); + return; + } + + if (m_apm_compare(tmp0, MM_0_85) == 1) /* check if > 0.85 */ + { + M_cos_to_sin(tmp2, (places + 4), x); + m_apm_arccos(r, places, tmp2); + r->m_apm_sign = x->m_apm_sign; + + M_restore_stack(5); + return; + } + + if (x->m_apm_sign == 0) /* input == 0 ?? */ + { + M_set_to_zero(r); + M_restore_stack(5); + return; + } + + if (x->m_apm_exponent <= -4) /* input close to 0 ?? */ + { + M_arcsin_near_0(r, places, x); + M_restore_stack(5); + return; + } + + tolerance = -(places + 4); + maxp = places + 8 - x->m_apm_exponent; + local_precision = 20 - x->m_apm_exponent; + + /* + * compute the maximum number of iterations + * that should be needed to calculate to + * the desired accuracy. [ constant below ~= 1 / log(2) ] + */ + + maxiter = (int)(log((double)(places + 2)) * 1.442695) + 3; + + if (maxiter < 5) + maxiter = 5; + + M_get_asin_guess(current_x, x); + + /* Use the following iteration to solve for arc-sin : + + sin(X) - N + X = X - ------------ + n+1 cos(X) + */ + + ii = 0; + + while (TRUE) + { + M_4x_cos(tmp1, local_precision, current_x); + + M_cos_to_sin(tmp2, local_precision, tmp1); + if (tmp2->m_apm_sign != 0) + tmp2->m_apm_sign = current_x->m_apm_sign; + + m_apm_subtract(tmp3, tmp2, x); + m_apm_divide(tmp0, local_precision, tmp3, tmp1); + + m_apm_subtract(tmp2, current_x, tmp0); + m_apm_copy(current_x, tmp2); + + if (ii != 0) + { + if (((2 * tmp0->m_apm_exponent) < tolerance) || (tmp0->m_apm_sign == 0)) + break; + } + + if (++ii == maxiter) + { + M_apm_log_error_msg(M_APM_RETURN, + "\'m_apm_arcsin\', max iteration count reached"); + break; + } + + local_precision *= 2; + + if (local_precision > maxp) + local_precision = maxp; + } + + m_apm_round(r, places, current_x); + M_restore_stack(5); +} +/****************************************************************************/ +void m_apm_arccos(M_APM r, int places, M_APM x) +{ + M_APM tmp0, tmp1, tmp2, tmp3, current_x; + int ii, maxiter, maxp, tolerance, local_precision; + + current_x = M_get_stack_var(); + tmp0 = M_get_stack_var(); + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + tmp3 = M_get_stack_var(); + + m_apm_absolute_value(tmp0, x); + + ii = m_apm_compare(tmp0, MM_One); + + if (ii == 1) /* |x| > 1 */ + { + M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_arccos\', |Argument| > 1"); + M_set_to_zero(r); + M_restore_stack(5); + return; + } + + if (ii == 0) /* |x| == 1, arccos = 0, PI */ + { + if (x->m_apm_sign == 1) + { + M_set_to_zero(r); + } + else + { + M_check_PI_places(places); + m_apm_round(r, places, MM_lc_PI); + } + + M_restore_stack(5); + return; + } + + if (m_apm_compare(tmp0, MM_0_85) == 1) /* check if > 0.85 */ + { + M_cos_to_sin(tmp2, (places + 4), x); + + if (x->m_apm_sign == 1) + { + m_apm_arcsin(r, places, tmp2); + } + else + { + M_check_PI_places(places); + m_apm_arcsin(tmp3, (places + 4), tmp2); + m_apm_subtract(tmp1, MM_lc_PI, tmp3); + m_apm_round(r, places, tmp1); + } + + M_restore_stack(5); + return; + } + + if (x->m_apm_sign == 0) /* input == 0 ?? */ + { + M_check_PI_places(places); + m_apm_round(r, places, MM_lc_HALF_PI); + M_restore_stack(5); + return; + } + + if (x->m_apm_exponent <= -4) /* input close to 0 ?? */ + { + M_arccos_near_0(r, places, x); + M_restore_stack(5); + return; + } + + tolerance = -(places + 4); + maxp = places + 8; + local_precision = 18; + + /* + * compute the maximum number of iterations + * that should be needed to calculate to + * the desired accuracy. [ constant below ~= 1 / log(2) ] + */ + + maxiter = (int)(log((double)(places + 2)) * 1.442695) + 3; + + if (maxiter < 5) + maxiter = 5; + + M_get_acos_guess(current_x, x); + + /* Use the following iteration to solve for arc-cos : + + cos(X) - N + X = X + ------------ + n+1 sin(X) + */ + + ii = 0; + + while (TRUE) + { + M_4x_cos(tmp1, local_precision, current_x); + + M_cos_to_sin(tmp2, local_precision, tmp1); + if (tmp2->m_apm_sign != 0) + tmp2->m_apm_sign = current_x->m_apm_sign; + + m_apm_subtract(tmp3, tmp1, x); + m_apm_divide(tmp0, local_precision, tmp3, tmp2); + + m_apm_add(tmp2, current_x, tmp0); + m_apm_copy(current_x, tmp2); + + if (ii != 0) + { + if (((2 * tmp0->m_apm_exponent) < tolerance) || (tmp0->m_apm_sign == 0)) + break; + } + + if (++ii == maxiter) + { + M_apm_log_error_msg(M_APM_RETURN, + "\'m_apm_arccos\', max iteration count reached"); + break; + } + + local_precision *= 2; + + if (local_precision > maxp) + local_precision = maxp; + } + + m_apm_round(r, places, current_x); + M_restore_stack(5); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapmasn0.cpp b/pgscript/utilities/m_apm/mapmasn0.cpp new file mode 100644 index 0000000..688ea5e --- /dev/null +++ b/pgscript/utilities/m_apm/mapmasn0.cpp @@ -0,0 +1,157 @@ + +/* + * M_APM - mapmasn0.c + * + * Copyright (C) 2000 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the 'ARC' family of functions; ARC-SIN, + * ARC-COS, ARC-TAN when the input arg is very close to 0 (zero). + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +/* + Calculate arcsin using the identity : + + x + arcsin (x) == arctan [ --------------- ] + sqrt(1 - x^2) + +*/ +void M_arcsin_near_0(M_APM rr, int places, M_APM aa) +{ + M_APM tmp5, tmp6; + + tmp5 = M_get_stack_var(); + tmp6 = M_get_stack_var(); + + M_cos_to_sin(tmp5, (places + 8), aa); + m_apm_divide(tmp6, (places + 8), aa, tmp5); + M_arctan_near_0(rr, places, tmp6); + + M_restore_stack(2); +} +/****************************************************************************/ +/* + Calculate arccos using the identity : + + arccos (x) == PI / 2 - arcsin (x) + +*/ +void M_arccos_near_0(M_APM rr, int places, M_APM aa) +{ + M_APM tmp1, tmp2; + + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + + M_check_PI_places(places); + M_arcsin_near_0(tmp1, (places + 4), aa); + m_apm_subtract(tmp2, MM_lc_HALF_PI, tmp1); + m_apm_round(rr, places, tmp2); + + M_restore_stack(2); +} +/****************************************************************************/ +/* + calculate arctan (x) with the following series: + + x^3 x^5 x^7 x^9 + arctan (x) = x - --- + --- - --- + --- ... + 3 5 7 9 + +*/ +void M_arctan_near_0(M_APM rr, int places, M_APM aa) +{ + M_APM tmp0, tmp2, tmpR, tmpS, digit, term; + int tolerance, dplaces, local_precision; + long m1; + + tmp0 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + tmpR = M_get_stack_var(); + tmpS = M_get_stack_var(); + term = M_get_stack_var(); + digit = M_get_stack_var(); + + tolerance = aa->m_apm_exponent - (places + 4); + dplaces = (places + 8) - aa->m_apm_exponent; + + m_apm_copy(term, aa); + m_apm_copy(tmpS, aa); + m_apm_multiply(tmp0, aa, aa); + m_apm_round(tmp2, (dplaces + 8), tmp0); + + m1 = 1L; + + while (TRUE) + { + /* + * do the subtraction term + */ + + m_apm_multiply(tmp0, term, tmp2); + + if ((tmp0->m_apm_exponent < tolerance) || (tmp0->m_apm_sign == 0)) + { + m_apm_round(rr, places, tmpS); + break; + } + + local_precision = dplaces + tmp0->m_apm_exponent; + + if (local_precision < 20) + local_precision = 20; + + m1 += 2; + m_apm_set_long(digit, m1); + m_apm_round(term, local_precision, tmp0); + m_apm_divide(tmp0, local_precision, term, digit); + m_apm_subtract(tmpR, tmpS, tmp0); + + /* + * do the addition term + */ + + m_apm_multiply(tmp0, term, tmp2); + + if ((tmp0->m_apm_exponent < tolerance) || (tmp0->m_apm_sign == 0)) + { + m_apm_round(rr, places, tmpR); + break; + } + + local_precision = dplaces + tmp0->m_apm_exponent; + + if (local_precision < 20) + local_precision = 20; + + m1 += 2; + m_apm_set_long(digit, m1); + m_apm_round(term, local_precision, tmp0); + m_apm_divide(tmp0, local_precision, term, digit); + m_apm_add(tmpS, tmpR, tmp0); + } + + M_restore_stack(6); /* restore the 6 locals we used here */ +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapmcbrt.cpp b/pgscript/utilities/m_apm/mapmcbrt.cpp new file mode 100644 index 0000000..505b4a5 --- /dev/null +++ b/pgscript/utilities/m_apm/mapmcbrt.cpp @@ -0,0 +1,129 @@ + +/* + * M_APM - mapmcbrt.c + * + * Copyright (C) 2000 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the CBRT (cube root) function. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +void m_apm_cbrt(M_APM rr, int places, M_APM aa) +{ + M_APM last_x, guess, tmpN, tmp7, tmp8, tmp9; + int ii, nexp, bflag, tolerance, maxp, local_precision; + + /* result is 0 if input is 0 */ + + if (aa->m_apm_sign == 0) + { + M_set_to_zero(rr); + return; + } + + last_x = M_get_stack_var(); + guess = M_get_stack_var(); + tmpN = M_get_stack_var(); + tmp7 = M_get_stack_var(); + tmp8 = M_get_stack_var(); + tmp9 = M_get_stack_var(); + + /* compute the cube root of the positive number, we'll fix the sign later */ + + m_apm_absolute_value(tmpN, aa); + + /* + normalize the input number (make the exponent near 0) so + the 'guess' function will not over/under flow on large + magnitude exponents. + */ + + nexp = aa->m_apm_exponent / 3; + tmpN->m_apm_exponent -= 3 * nexp; + + M_get_cbrt_guess(guess, tmpN); + + tolerance = places + 4; + maxp = places + 16; + bflag = FALSE; + local_precision = 14; + + m_apm_negate(last_x, MM_Ten); + + /* Use the following iteration to calculate 1 / cbrt(N) : + + 4 + X = [ 4 * X - N * X ] / 3 + n+1 + */ + + ii = 0; + + while (TRUE) + { + m_apm_multiply(tmp8, guess, guess); + m_apm_multiply(tmp7, tmp8, tmp8); + m_apm_round(tmp8, local_precision, tmp7); + m_apm_multiply(tmp9, tmpN, tmp8); + + m_apm_multiply(tmp8, MM_Four, guess); + m_apm_subtract(tmp7, tmp8, tmp9); + m_apm_divide(guess, local_precision, tmp7, MM_Three); + + if (bflag) + break; + + /* force at least 2 iterations so 'last_x' has valid data */ + + if (ii != 0) + { + m_apm_subtract(tmp8, guess, last_x); + + if (tmp8->m_apm_sign == 0) + break; + + if ((-4 * tmp8->m_apm_exponent) > tolerance) + bflag = TRUE; + } + + local_precision *= 2; + + if (local_precision > maxp) + local_precision = maxp; + + m_apm_copy(last_x, guess); + ii = 1; + } + + /* final cbrt = N * guess ^ 2 */ + + m_apm_multiply(tmp9, guess, guess); + m_apm_multiply(tmp8, tmp9, tmpN); + m_apm_round(rr, places, tmp8); + + rr->m_apm_exponent += nexp; + rr->m_apm_sign = aa->m_apm_sign; + M_restore_stack(6); +} +/****************************************************************************/ + diff --git a/pgscript/utilities/m_apm/mapmcnst.cpp b/pgscript/utilities/m_apm/mapmcnst.cpp new file mode 100644 index 0000000..2e09deb --- /dev/null +++ b/pgscript/utilities/m_apm/mapmcnst.cpp @@ -0,0 +1,291 @@ + +/* + * M_APM - mapmcnst.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains declarations and initializes the constants + * used throughout the library. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +int MM_lc_PI_digits = 0; +int MM_lc_log_digits; +int MM_cpp_min_precision; /* only used in C++ wrapper */ + +M_APM MM_Zero = NULL; +M_APM MM_One = NULL; +M_APM MM_Two = NULL; +M_APM MM_Three = NULL; +M_APM MM_Four = NULL; +M_APM MM_Five = NULL; +M_APM MM_Ten = NULL; +M_APM MM_0_5 = NULL; +M_APM MM_E = NULL; +M_APM MM_PI = NULL; +M_APM MM_HALF_PI = NULL; +M_APM MM_2_PI = NULL; +M_APM MM_lc_PI = NULL; +M_APM MM_lc_HALF_PI = NULL; +M_APM MM_lc_2_PI = NULL; +M_APM MM_lc_log2 = NULL; +M_APM MM_lc_log10 = NULL; +M_APM MM_lc_log10R = NULL; +M_APM MM_0_85 = NULL; +M_APM MM_5x_125R = NULL; +M_APM MM_5x_64R = NULL; +M_APM MM_5x_256R = NULL; +M_APM MM_5x_Eight = NULL; +M_APM MM_5x_Sixteen = NULL; +M_APM MM_5x_Twenty = NULL; +M_APM MM_LOG_E_BASE_10 = NULL; +M_APM MM_LOG_10_BASE_E = NULL; +M_APM MM_LOG_2_BASE_E = NULL; +M_APM MM_LOG_3_BASE_E = NULL; + + +static char MM_cnst_PI[] = + "3.1415926535897932384626433832795028841971693993751058209749445923078\ +1640628620899862803482534211706798214808651328230664709384460955"; + +static char MM_cnst_E[] = + "2.7182818284590452353602874713526624977572470936999595749669676277240\ +76630353547594571382178525166427427466391932003059921817413596629"; + +static char MM_cnst_log_2[] = + "0.6931471805599453094172321214581765680755001343602552541206800094933\ +93621969694715605863326996418687542001481020570685733685520235758"; + +static char MM_cnst_log_3[] = + "1.0986122886681096913952452369225257046474905578227494517346943336374\ +9429321860896687361575481373208878797002906595786574236800422593"; + +static char MM_cnst_log_10[] = + "2.3025850929940456840179914546843642076011014886287729760333279009675\ +7260967735248023599720508959829834196778404228624863340952546508"; + +static char MM_cnst_1_log_10[] = + "0.4342944819032518276511289189166050822943970058036665661144537831658\ +64649208870774729224949338431748318706106744766303733641679287159"; + +/* + * the following constants have ~520 digits each, if needed + */ + +/* +static char MM_cnst_PI[] = +"3.1415926535897932384626433832795028841971693993751058209749445923078\ +164062862089986280348253421170679821480865132823066470938446095505822\ +317253594081284811174502841027019385211055596446229489549303819644288\ +109756659334461284756482337867831652712019091456485669234603486104543\ +266482133936072602491412737245870066063155881748815209209628292540917\ +153643678925903600113305305488204665213841469519415116094330572703657\ +595919530921861173819326117931051185480744623799627495673518857527248\ +91227938183011949129833673362440656643"; + +static char MM_cnst_E[] = +"2.7182818284590452353602874713526624977572470936999595749669676277240\ +766303535475945713821785251664274274663919320030599218174135966290435\ +729003342952605956307381323286279434907632338298807531952510190115738\ +341879307021540891499348841675092447614606680822648001684774118537423\ +454424371075390777449920695517027618386062613313845830007520449338265\ +602976067371132007093287091274437470472306969772093101416928368190255\ +151086574637721112523897844250569536967707854499699679468644549059879\ +3163688923009879312773617821542499923"; + +static char MM_cnst_log_2[] = +"0.6931471805599453094172321214581765680755001343602552541206800094933\ +936219696947156058633269964186875420014810205706857336855202357581305\ +570326707516350759619307275708283714351903070386238916734711233501153\ +644979552391204751726815749320651555247341395258829504530070953263666\ +426541042391578149520437404303855008019441706416715186447128399681717\ +845469570262716310645461502572074024816377733896385506952606683411372\ +738737229289564935470257626520988596932019650585547647033067936544325\ +47632744951250406069438147104689946506"; + +static char MM_cnst_log_3[] = +"1.0986122886681096913952452369225257046474905578227494517346943336374\ +942932186089668736157548137320887879700290659578657423680042259305198\ +210528018707672774106031627691833813671793736988443609599037425703167\ +959115211455919177506713470549401667755802222031702529468975606901065\ +215056428681380363173732985777823669916547921318181490200301038236301\ +222486527481982259910974524908964580534670088459650857484441190188570\ +876474948670796130858294116021661211840014098255143919487688936798494\ +3022557315353296853452952514592138765"; + +static char MM_cnst_log_10[] = +"2.3025850929940456840179914546843642076011014886287729760333279009675\ +726096773524802359972050895982983419677840422862486334095254650828067\ +566662873690987816894829072083255546808437998948262331985283935053089\ +653777326288461633662222876982198867465436674744042432743651550489343\ +149393914796194044002221051017141748003688084012647080685567743216228\ +355220114804663715659121373450747856947683463616792101806445070648000\ +277502684916746550586856935673420670581136429224554405758925724208241\ +31469568901675894025677631135691929203"; + +static char MM_cnst_1_log_10[] = +"0.4342944819032518276511289189166050822943970058036665661144537831658\ +646492088707747292249493384317483187061067447663037336416792871589639\ +065692210646628122658521270865686703295933708696588266883311636077384\ +905142844348666768646586085135561482123487653435434357317253835622281\ +395603048646652366095539377356176323431916710991411597894962993512457\ +934926357655469077671082419150479910989674900103277537653570270087328\ +550951731440674697951899513594088040423931518868108402544654089797029\ +86328682876262414401345704354613292060"; +*/ + + +/****************************************************************************/ +char *m_apm_lib_version(char *v) +{ + strcpy(v, MAPM_LIB_VERSION); + return(v); +} +/****************************************************************************/ +char *m_apm_lib_short_version(char *v) +{ + strcpy(v, MAPM_LIB_SHORT_VERSION); + return(v); +} +/****************************************************************************/ +void M_free_all_cnst() +{ + if (MM_lc_PI_digits != 0) + { + m_apm_free(MM_Zero); + m_apm_free(MM_One); + m_apm_free(MM_Two); + m_apm_free(MM_Three); + m_apm_free(MM_Four); + m_apm_free(MM_Five); + m_apm_free(MM_Ten); + m_apm_free(MM_0_5); + m_apm_free(MM_LOG_2_BASE_E); + m_apm_free(MM_LOG_3_BASE_E); + m_apm_free(MM_E); + m_apm_free(MM_PI); + m_apm_free(MM_HALF_PI); + m_apm_free(MM_2_PI); + m_apm_free(MM_lc_PI); + m_apm_free(MM_lc_HALF_PI); + m_apm_free(MM_lc_2_PI); + m_apm_free(MM_lc_log2); + m_apm_free(MM_lc_log10); + m_apm_free(MM_lc_log10R); + m_apm_free(MM_0_85); + m_apm_free(MM_5x_125R); + m_apm_free(MM_5x_64R); + m_apm_free(MM_5x_256R); + m_apm_free(MM_5x_Eight); + m_apm_free(MM_5x_Sixteen); + m_apm_free(MM_5x_Twenty); + m_apm_free(MM_LOG_E_BASE_10); + m_apm_free(MM_LOG_10_BASE_E); + + MM_lc_PI_digits = 0; + } +} +/****************************************************************************/ +void M_init_trig_globals() +{ + MM_lc_PI_digits = VALID_DECIMAL_PLACES; + MM_lc_log_digits = VALID_DECIMAL_PLACES; + MM_cpp_min_precision = 30; + + MM_Zero = m_apm_init(); + MM_One = m_apm_init(); + MM_Two = m_apm_init(); + MM_Three = m_apm_init(); + MM_Four = m_apm_init(); + MM_Five = m_apm_init(); + MM_Ten = m_apm_init(); + MM_0_5 = m_apm_init(); + MM_LOG_2_BASE_E = m_apm_init(); + MM_LOG_3_BASE_E = m_apm_init(); + MM_E = m_apm_init(); + MM_PI = m_apm_init(); + MM_HALF_PI = m_apm_init(); + MM_2_PI = m_apm_init(); + MM_lc_PI = m_apm_init(); + MM_lc_HALF_PI = m_apm_init(); + MM_lc_2_PI = m_apm_init(); + MM_lc_log2 = m_apm_init(); + MM_lc_log10 = m_apm_init(); + MM_lc_log10R = m_apm_init(); + MM_0_85 = m_apm_init(); + MM_5x_125R = m_apm_init(); + MM_5x_64R = m_apm_init(); + MM_5x_256R = m_apm_init(); + MM_5x_Eight = m_apm_init(); + MM_5x_Sixteen = m_apm_init(); + MM_5x_Twenty = m_apm_init(); + MM_LOG_E_BASE_10 = m_apm_init(); + MM_LOG_10_BASE_E = m_apm_init(); + + m_apm_set_string(MM_One, "1"); + m_apm_set_string(MM_Two, "2"); + m_apm_set_string(MM_Three, "3"); + m_apm_set_string(MM_Four, "4"); + m_apm_set_string(MM_Five, "5"); + m_apm_set_string(MM_Ten, "10"); + m_apm_set_string(MM_0_5, "0.5"); + m_apm_set_string(MM_0_85, "0.85"); + + m_apm_set_string(MM_5x_125R, "8.0E-3"); + m_apm_set_string(MM_5x_64R, "1.5625E-2"); + m_apm_set_string(MM_5x_256R, "3.90625E-3"); + m_apm_set_string(MM_5x_Eight, "8"); + m_apm_set_string(MM_5x_Sixteen, "16"); + m_apm_set_string(MM_5x_Twenty, "20"); + + m_apm_set_string(MM_LOG_2_BASE_E, MM_cnst_log_2); + m_apm_set_string(MM_LOG_3_BASE_E, MM_cnst_log_3); + m_apm_set_string(MM_LOG_10_BASE_E, MM_cnst_log_10); + m_apm_set_string(MM_LOG_E_BASE_10, MM_cnst_1_log_10); + + m_apm_set_string(MM_lc_log2, MM_cnst_log_2); + m_apm_set_string(MM_lc_log10, MM_cnst_log_10); + m_apm_set_string(MM_lc_log10R, MM_cnst_1_log_10); + + m_apm_set_string(MM_E, MM_cnst_E); + m_apm_set_string(MM_PI, MM_cnst_PI); + m_apm_multiply(MM_HALF_PI, MM_PI, MM_0_5); + m_apm_multiply(MM_2_PI, MM_PI, MM_Two); + + m_apm_copy(MM_lc_PI, MM_PI); + m_apm_copy(MM_lc_HALF_PI, MM_HALF_PI); + m_apm_copy(MM_lc_2_PI, MM_2_PI); +} +/****************************************************************************/ +void m_apm_cpp_precision(int digits) +{ + if (MM_lc_PI_digits == 0) + { + m_apm_free(m_apm_init()); + } + + if (digits >= 2) + MM_cpp_min_precision = digits; + else + MM_cpp_min_precision = 2; +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapmfact.cpp b/pgscript/utilities/m_apm/mapmfact.cpp new file mode 100644 index 0000000..b9c535c --- /dev/null +++ b/pgscript/utilities/m_apm/mapmfact.cpp @@ -0,0 +1,244 @@ + +/* + * M_APM - mapmfact.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the FACTORIAL function. + * + */ + +/* + * Brief explanation of the factorial algorithm. + * ---------------------------------------------- + * + * The old algorithm simply multiplied N * (N-1) * (N-2) etc, until + * the number counted down to '2'. So one term of the multiplication + * kept getting bigger while multiplying by the next number in the + * sequence. + * + * The new algorithm takes advantage of the fast multiplication + * algorithm. The "ideal" setup for fast multiplication is when + * both numbers have approx the same number of significant digits + * and the number of digits is very near (but not over) an exact + * power of 2. + * + * So, we will multiply N * (N-1) * (N-2), etc until the number of + * significant digits is approx 256. + * + * Store this temp product into an array. + * + * Then we will multiply the next sequence until the number of + * significant digits is approx 256. + * + * Store this temp product into the next element of the array. + * + * Continue until we've counted down to 2. + * + * We now have an array of numbers with approx the same number + * of digits (except for the last element, depending on where it + * ended.) Now multiply each of the array elements together to + * get the final product. + * + * The array multiplies are done as follows (assume we used 11 + * array elements for this example, indicated by [0] - [10] ) : + * + * initial iter-1 iter-2 iter-3 iter-4 + * + * [0] + * * -> [0] + * [1] + * * -> [0] + * + * [2] + * * -> [1] + * [3] + * * -> [0] + * + * [4] + * * -> [2] + * [5] + * + * * -> [1] + * + * [6] + * * -> [3] * -> [0] + * [7] + * + * + * [8] + * * -> [4] + * [9] + * * -> [2] -> [1] + * + * + * [10] -> [5] + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/* define size of local array for temp storage */ + +#define NDIM 32 + +/****************************************************************************/ +void m_apm_factorial(M_APM moutput, M_APM minput) +{ + int ii, nmul, ndigits, nd, jj, kk, mm, ct; + M_APM array[NDIM]; + M_APM iprod1, iprod2, tmp1, tmp2; + + /* return 1 for any input <= 1 */ + + if (m_apm_compare(minput, MM_One) <= 0) + { + m_apm_copy(moutput, MM_One); + return; + } + + ct = 0; + mm = NDIM - 2; + ndigits = 256; + nd = ndigits - 20; + tmp1 = m_apm_init(); + tmp2 = m_apm_init(); + iprod1 = m_apm_init(); + iprod2 = m_apm_init(); + array[0] = m_apm_init(); + + m_apm_copy(tmp2, minput); + + /* loop until multiply count-down has reached '2' */ + + while (TRUE) + { + m_apm_copy(iprod1, MM_One); + + /* + * loop until the number of significant digits in this + * partial result is slightly less than 256 + */ + + while (TRUE) + { + m_apm_multiply(iprod2, iprod1, tmp2); + + m_apm_subtract(tmp1, tmp2, MM_One); + + m_apm_multiply(iprod1, iprod2, tmp1); + + /* + * I know, I know. There just isn't a *clean* way + * to break out of 2 nested loops. + */ + + if (m_apm_compare(tmp1, MM_Two) <= 0) + goto PHASE2; + + m_apm_subtract(tmp2, tmp1, MM_One); + + if (iprod1->m_apm_datalength > nd) + break; + } + + if (ct == (NDIM - 1)) + { + /* + * if the array has filled up, start multiplying + * some of the partial products now. + */ + + m_apm_copy(tmp1, array[mm]); + m_apm_multiply(array[mm], iprod1, tmp1); + + if (mm == 0) + { + mm = NDIM - 2; + ndigits = ndigits << 1; + nd = ndigits - 20; + } + else + mm--; + } + else + { + /* + * store this partial product in the array + * and allocate the next array element + */ + + m_apm_copy(array[ct], iprod1); + array[++ct] = m_apm_init(); + } + } + +PHASE2: + + m_apm_copy(array[ct], iprod1); + + kk = ct; + + while (kk != 0) + { + ii = 0; + jj = 0; + nmul = (kk + 1) >> 1; + + while (TRUE) + { + /* must use tmp var when ii,jj point to same element */ + + if (ii == 0) + { + m_apm_copy(tmp1, array[ii]); + m_apm_multiply(array[jj], tmp1, array[ii + 1]); + } + else + m_apm_multiply(array[jj], array[ii], array[ii + 1]); + + if (++jj == nmul) + break; + + ii += 2; + } + + if ((kk & 1) == 0) + { + jj = kk >> 1; + m_apm_copy(array[jj], array[kk]); + } + + kk = kk >> 1; + } + + m_apm_copy(moutput, array[0]); + + for (ii = 0; ii <= ct; ii++) + { + m_apm_free(array[ii]); + } + + m_apm_free(tmp1); + m_apm_free(tmp2); + m_apm_free(iprod1); + m_apm_free(iprod2); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapmfmul.cpp b/pgscript/utilities/m_apm/mapmfmul.cpp new file mode 100644 index 0000000..6601c06 --- /dev/null +++ b/pgscript/utilities/m_apm/mapmfmul.cpp @@ -0,0 +1,685 @@ + +/* + * M_APM - mapmfmul.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * This file contains the divide-and-conquer FAST MULTIPLICATION + * function as well as its support functions. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +static int M_firsttimef = TRUE; + +/* + * specify the max size the FFT routine can handle + * (in MAPM, #digits = 2 * #bytes) + * + * this number *must* be an exact power of 2. + * + * **WORST** case input numbers (all 9's) has shown that + * the FFT math will overflow if the #define here is + * >= 1048576. On my system, 524,288 worked OK. I will + * factor down another factor of 2 to safeguard against + * other computers have less precise floating point math. + * If you are confident in your system, 524288 will + * theoretically work fine. + * + * the define here allows the FFT algorithm to multiply two + * 524,288 digit numbers yielding a 1,048,576 digit result. + */ + +#define MAX_FFT_BYTES 262144 + +/* + * the Divide-and-Conquer multiplication kicks in when the size of + * the numbers exceed the capability of the FFT (#define just above). + * + * #bytes D&C call depth + * ------ -------------- + * 512K 1 + * 1M 2 + * 2M 3 + * 4M 4 + * ... ... + * 2.1990E+12 23 + * + * the following stack sizes are sized to meet the + * above 2.199E+12 example, though I wouldn't want to + * wait for it to finish... + * + * Each call requires 7 stack variables to be saved so + * we need a stack depth of 23 * 7 + PAD. (we use 164) + * + * For 'exp_stack', 3 integers also are required to be saved + * for each recursive call so we need a stack depth of + * 23 * 3 + PAD. (we use 72) + * + * + * If the FFT multiply is disabled, resize the arrays + * as follows: + * + * the following stack sizes are sized to meet the + * worst case expected assuming we are multiplying + * numbers with 2.14E+9 (2 ^ 31) digits. + * + * For sizeof(int) == 4 (32 bits) there may be up to 32 recursive + * calls. Each call requires 7 stack variables so we need a + * stack depth of 32 * 7 + PAD. (we use 240) + * + * For 'exp_stack', 3 integers also are required to be saved + * for each recursive call so we need a stack depth of + * 32 * 3 + PAD. (we use 100) + */ + +#ifdef NO_FFT_MULTIPLY +#define M_STACK_SIZE 240 +#define M_ISTACK_SIZE 100 +#else +#define M_STACK_SIZE 164 +#define M_ISTACK_SIZE 72 +#endif + +static int exp_stack[M_ISTACK_SIZE]; +static int exp_stack_ptr; + +static UCHAR *mul_stack_data[M_STACK_SIZE]; +static int mul_stack_data_size[M_STACK_SIZE]; +static int M_mul_stack_ptr; + +static UCHAR *fmul_a1, *fmul_a0, *fmul_a9, *fmul_b1, *fmul_b0, + *fmul_b9, *fmul_t0; + +static int size_flag, bit_limit, stmp, itmp, mii; + +static M_APM M_ain; +static M_APM M_bin; + +static const char *M_stack_ptr_error_msg = "\'M_get_stack_ptr\', Out of memory"; + +extern void M_fast_multiply(M_APM, M_APM, M_APM); +extern void M_fmul_div_conq(UCHAR *, UCHAR *, UCHAR *, int); +extern void M_fmul_add(UCHAR *, UCHAR *, int, int); +extern int M_fmul_subtract(UCHAR *, UCHAR *, UCHAR *, int); +extern void M_fmul_split(UCHAR *, UCHAR *, UCHAR *, int); +extern int M_next_power_of_2(int); +extern int M_get_stack_ptr(int); +extern void M_push_mul_int(int); +extern int M_pop_mul_int(void); + +#ifdef NO_FFT_MULTIPLY +extern void M_4_byte_multiply(UCHAR *, UCHAR *, UCHAR *); +#else +extern void M_fast_mul_fft(UCHAR *, UCHAR *, UCHAR *, int); +#endif + +/* + * the following algorithm is used in this fast multiply routine + * (sometimes called the divide-and-conquer technique.) + * + * assume we have 2 numbers (a & b) with 2N digits. + * + * let : a = (2^N) * A1 + A0 , b = (2^N) * B1 + B0 + * + * where 'A1' is the 'most significant half' of 'a' and + * 'A0' is the 'least significant half' of 'a'. Same for + * B1 and B0. + * + * Now use the identity : + * + * 2N N N N + * ab = (2 + 2 ) A1B1 + 2 (A1-A0)(B0-B1) + (2 + 1)A0B0 + * + * + * The original problem of multiplying 2 (2N) digit numbers has + * been reduced to 3 multiplications of N digit numbers plus some + * additions, subtractions, and shifts. + * + * The fast multiplication algorithm used here uses the above + * identity in a recursive process. This algorithm results in + * O(n ^ 1.585) growth. + */ + + +/****************************************************************************/ +void M_free_all_fmul() +{ + int k; + + if (M_firsttimef == FALSE) + { + m_apm_free(M_ain); + m_apm_free(M_bin); + + for (k = 0; k < M_STACK_SIZE; k++) + { + if (mul_stack_data_size[k] != 0) + { + MAPM_FREE(mul_stack_data[k]); + } + } + + M_firsttimef = TRUE; + } +} +/****************************************************************************/ +void M_push_mul_int(int val) +{ + exp_stack[++exp_stack_ptr] = val; +} +/****************************************************************************/ +int M_pop_mul_int() +{ + return(exp_stack[exp_stack_ptr--]); +} +/****************************************************************************/ +void M_fmul_split(UCHAR *x1, UCHAR *x0, UCHAR *xin, int nbytes) +{ + memcpy(x1, xin, nbytes); + memcpy(x0, (xin + nbytes), nbytes); +} +/****************************************************************************/ +void M_fast_multiply(M_APM rr, M_APM aa, M_APM bb) +{ + void *vp; + int ii, k, nexp, sign; + + if (M_firsttimef) + { + M_firsttimef = FALSE; + + for (k = 0; k < M_STACK_SIZE; k++) + mul_stack_data_size[k] = 0; + + size_flag = M_get_sizeof_int(); + bit_limit = 8 * size_flag + 1; + + M_ain = m_apm_init(); + M_bin = m_apm_init(); + } + + exp_stack_ptr = -1; + M_mul_stack_ptr = -1; + + m_apm_copy(M_ain, aa); + m_apm_copy(M_bin, bb); + + sign = M_ain->m_apm_sign * M_bin->m_apm_sign; + nexp = M_ain->m_apm_exponent + M_bin->m_apm_exponent; + + if (M_ain->m_apm_datalength >= M_bin->m_apm_datalength) + ii = M_ain->m_apm_datalength; + else + ii = M_bin->m_apm_datalength; + + ii = (ii + 1) >> 1; + ii = M_next_power_of_2(ii); + + /* Note: 'ii' must be >= 4 here. this is guaranteed + by the caller: m_apm_multiply + */ + + k = 2 * ii; /* required size of result, in bytes */ + + M_apm_pad(M_ain, k); /* fill out the data so the number of */ + M_apm_pad(M_bin, k); /* bytes is an exact power of 2 */ + + if (k > rr->m_apm_malloclength) + { + if ((vp = MAPM_REALLOC(rr->m_apm_data, (k + 32))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, "\'M_fast_multiply\', Out of memory"); + } + + rr->m_apm_malloclength = k + 28; + rr->m_apm_data = (UCHAR *)vp; + } + +#ifdef NO_FFT_MULTIPLY + + M_fmul_div_conq(rr->m_apm_data, M_ain->m_apm_data, + M_bin->m_apm_data, ii); +#else + + /* + * if the numbers are *really* big, use the divide-and-conquer + * routine first until the numbers are small enough to be handled + * by the FFT algorithm. If the numbers are already small enough, + * call the FFT multiplication now. + * + * Note that 'ii' here is (and must be) an exact power of 2. + */ + + if (size_flag == 2) /* if still using 16 bit compilers .... */ + { + M_fast_mul_fft(rr->m_apm_data, M_ain->m_apm_data, + M_bin->m_apm_data, ii); + } + else /* >= 32 bit compilers */ + { + if (ii > (MAX_FFT_BYTES + 2)) + { + M_fmul_div_conq(rr->m_apm_data, M_ain->m_apm_data, + M_bin->m_apm_data, ii); + } + else + { + M_fast_mul_fft(rr->m_apm_data, M_ain->m_apm_data, + M_bin->m_apm_data, ii); + } + } + +#endif + + rr->m_apm_sign = sign; + rr->m_apm_exponent = nexp; + rr->m_apm_datalength = 4 * ii; + + M_apm_normalize(rr); +} +/****************************************************************************/ +/* + * This is the recursive function to perform the multiply. The + * design intent here is to have no local variables. Any local + * data that needs to be saved is saved on one of the two stacks. + */ +void M_fmul_div_conq(UCHAR *rr, UCHAR *aa, UCHAR *bb, int sz) +{ + +#ifdef NO_FFT_MULTIPLY + + if (sz == 4) /* multiply 4x4 yielding an 8 byte result */ + { + M_4_byte_multiply(rr, aa, bb); + return; + } + +#else + + /* + * if the numbers are now small enough, let the FFT algorithm + * finish up. + */ + + if (sz == MAX_FFT_BYTES) + { + M_fast_mul_fft(rr, aa, bb, sz); + return; + } + +#endif + + memset(rr, 0, (2 * sz)); /* zero out the result */ + mii = sz >> 1; + + itmp = M_get_stack_ptr(mii); + M_push_mul_int(itmp); + + fmul_a1 = mul_stack_data[itmp]; + + itmp = M_get_stack_ptr(mii); + fmul_a0 = mul_stack_data[itmp]; + + itmp = M_get_stack_ptr(2 * sz); + fmul_a9 = mul_stack_data[itmp]; + + itmp = M_get_stack_ptr(mii); + fmul_b1 = mul_stack_data[itmp]; + + itmp = M_get_stack_ptr(mii); + fmul_b0 = mul_stack_data[itmp]; + + itmp = M_get_stack_ptr(2 * sz); + fmul_b9 = mul_stack_data[itmp]; + + itmp = M_get_stack_ptr(2 * sz); + fmul_t0 = mul_stack_data[itmp]; + + M_fmul_split(fmul_a1, fmul_a0, aa, mii); + M_fmul_split(fmul_b1, fmul_b0, bb, mii); + + stmp = M_fmul_subtract(fmul_a9, fmul_a1, fmul_a0, mii); + stmp *= M_fmul_subtract(fmul_b9, fmul_b0, fmul_b1, mii); + + M_push_mul_int(stmp); + M_push_mul_int(mii); + + M_fmul_div_conq(fmul_t0, fmul_a0, fmul_b0, mii); + + mii = M_pop_mul_int(); + stmp = M_pop_mul_int(); + itmp = M_pop_mul_int(); + + M_push_mul_int(itmp); + M_push_mul_int(stmp); + M_push_mul_int(mii); + + /* to restore all stack variables ... + fmul_a1 = mul_stack_data[itmp]; + fmul_a0 = mul_stack_data[itmp+1]; + fmul_a9 = mul_stack_data[itmp+2]; + fmul_b1 = mul_stack_data[itmp+3]; + fmul_b0 = mul_stack_data[itmp+4]; + fmul_b9 = mul_stack_data[itmp+5]; + fmul_t0 = mul_stack_data[itmp+6]; + */ + + fmul_a1 = mul_stack_data[itmp]; + fmul_b1 = mul_stack_data[itmp + 3]; + fmul_t0 = mul_stack_data[itmp + 6]; + + memcpy((rr + sz), fmul_t0, sz); /* first 'add', result is now zero */ + /* so we just copy in the bytes */ + M_fmul_add(rr, fmul_t0, mii, sz); + + M_fmul_div_conq(fmul_t0, fmul_a1, fmul_b1, mii); + + mii = M_pop_mul_int(); + stmp = M_pop_mul_int(); + itmp = M_pop_mul_int(); + + M_push_mul_int(itmp); + M_push_mul_int(stmp); + M_push_mul_int(mii); + + fmul_a9 = mul_stack_data[itmp + 2]; + fmul_b9 = mul_stack_data[itmp + 5]; + fmul_t0 = mul_stack_data[itmp + 6]; + + M_fmul_add(rr, fmul_t0, 0, sz); + M_fmul_add(rr, fmul_t0, mii, sz); + + if (stmp != 0) + M_fmul_div_conq(fmul_t0, fmul_a9, fmul_b9, mii); + + mii = M_pop_mul_int(); + stmp = M_pop_mul_int(); + itmp = M_pop_mul_int(); + + fmul_t0 = mul_stack_data[itmp + 6]; + + /* + * if the sign of (A1 - A0)(B0 - B1) is positive, ADD to + * the result. if it is negative, SUBTRACT from the result. + */ + + if (stmp < 0) + { + fmul_a9 = mul_stack_data[itmp + 2]; + fmul_b9 = mul_stack_data[itmp + 5]; + + memset(fmul_b9, 0, (2 * sz)); + memcpy((fmul_b9 + mii), fmul_t0, sz); + M_fmul_subtract(fmul_a9, rr, fmul_b9, (2 * sz)); + memcpy(rr, fmul_a9, (2 * sz)); + } + + if (stmp > 0) + M_fmul_add(rr, fmul_t0, mii, sz); + + M_mul_stack_ptr -= 7; +} +/****************************************************************************/ +/* + * special addition function for use with the fast multiply operation + */ +void M_fmul_add(UCHAR *r, UCHAR *a, int offset, int sz) +{ + int i, j; + UCHAR carry; + + carry = 0; + j = offset + sz; + i = sz; + + while (TRUE) + { + r[--j] += carry + a[--i]; + + if (r[j] >= 100) + { + r[j] -= 100; + carry = 1; + } + else + carry = 0; + + if (i == 0) + break; + } + + if (carry) + { + while (TRUE) + { + r[--j] += 1; + + if (r[j] < 100) + break; + + r[j] -= 100; + } + } +} +/****************************************************************************/ +/* + * special subtraction function for use with the fast multiply operation + */ +int M_fmul_subtract(UCHAR *r, UCHAR *a, UCHAR *b, int sz) +{ + int k, jtmp, sflag, nb, borrow; + + nb = sz; + sflag = 0; /* sign flag: assume the numbers are equal */ + + /* + * find if a > b (so we perform a-b) + * or a < b (so we perform b-a) + */ + + for (k = 0; k < nb; k++) + { + if (a[k] < b[k]) + { + sflag = -1; + break; + } + + if (a[k] > b[k]) + { + sflag = 1; + break; + } + } + + if (sflag == 0) + { + memset(r, 0, nb); /* zero out the result */ + } + else + { + k = nb; + borrow = 0; + + while (TRUE) + { + k--; + + if (sflag == 1) + jtmp = (int)a[k] - ((int)b[k] + borrow); + else + jtmp = (int)b[k] - ((int)a[k] + borrow); + + if (jtmp >= 0) + { + r[k] = (UCHAR)jtmp; + borrow = 0; + } + else + { + r[k] = (UCHAR)(100 + jtmp); + borrow = 1; + } + + if (k == 0) + break; + } + } + + return(sflag); +} +/****************************************************************************/ +int M_next_power_of_2(int n) +{ + int ct, k; + + if (n <= 2) + return(n); + + k = 2; + ct = 0; + + while (TRUE) + { + if (k >= n) + break; + + k = k << 1; + + if (++ct == bit_limit) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, + "\'M_next_power_of_2\', ERROR :sizeof(int) too small ??"); + } + } + + return(k); +} +/****************************************************************************/ +int M_get_stack_ptr(int sz) +{ + int i, k; + UCHAR *cp; + + k = ++M_mul_stack_ptr; + + /* if size is 0, just need to malloc and return */ + if (mul_stack_data_size[k] == 0) + { + if ((i = sz) < 16) + i = 16; + + if ((cp = (UCHAR *)MAPM_MALLOC(i + 4)) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, M_stack_ptr_error_msg); + } + + mul_stack_data[k] = cp; + mul_stack_data_size[k] = i; + } + else /* it has been malloc'ed, see if it's big enough */ + { + if (sz > mul_stack_data_size[k]) + { + cp = mul_stack_data[k]; + + if ((cp = (UCHAR *)MAPM_REALLOC(cp, (sz + 4))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, M_stack_ptr_error_msg); + } + + mul_stack_data[k] = cp; + mul_stack_data_size[k] = sz; + } + } + + return(k); +} +/****************************************************************************/ + +#ifdef NO_FFT_MULTIPLY + +/* + * multiply a 4 byte number by a 4 byte number + * yielding an 8 byte result. each byte contains + * a base 100 'digit', i.e.: range from 0-99. + * + * MSB LSB + * + * a,b [0] [1] [2] [3] + * result [0] ..... [7] + */ + +void M_4_byte_multiply(UCHAR *r, UCHAR *a, UCHAR *b) +{ + int jj; + unsigned int *ip, t1, rr[8]; + + memset(rr, 0, (8 * sizeof(int))); /* zero out result */ + jj = 3; + ip = rr + 5; + + /* + * loop for one number [b], un-roll the inner 'loop' [a] + * + * accumulate partial sums in UINT array, release carries + * and convert back to base 100 at the end + */ + + while (1) + { + t1 = (unsigned int)b[jj]; + ip += 2; + + *ip-- += t1 * a[3]; + *ip-- += t1 * a[2]; + *ip-- += t1 * a[1]; + *ip += t1 * a[0]; + + if (jj-- == 0) + break; + } + + jj = 7; + + while (1) + { + t1 = rr[jj] / 100; + r[jj] = (UCHAR)(rr[jj] - 100 * t1); + + if (jj == 0) + break; + + rr[--jj] += t1; + } +} + +#endif + +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapmgues.cpp b/pgscript/utilities/m_apm/mapmgues.cpp new file mode 100644 index 0000000..e36c85b --- /dev/null +++ b/pgscript/utilities/m_apm/mapmgues.cpp @@ -0,0 +1,147 @@ + +/* + * M_APM - mapmgues.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the functions that generate the initial + * 'guesses' for the sqrt, cbrt, log, arcsin, and arccos functions. + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +void M_get_sqrt_guess(M_APM r, M_APM a) +{ + char buf[48]; + double dd; + + m_apm_to_string(buf, 15, a); + dd = atof(buf); /* sqrt algorithm actually finds 1/sqrt */ + m_apm_set_double(r, (1.0 / sqrt(dd))); +} +/****************************************************************************/ +/* + * for cbrt, log, asin, and acos we induce an error of 10 ^ -5. + * this enables the iterative routine to be more efficient + * by knowing exactly how accurate the initial guess is. + * + * this also prevents some corner conditions where the iterative + * functions may terminate too soon. + */ +/****************************************************************************/ +void M_get_cbrt_guess(M_APM r, M_APM a) +{ + char buf[48]; + double dd; + + m_apm_to_string(buf, 15, a); + dd = atof(buf); + dd = log(dd) / 3.0; /* cbrt algorithm actually finds 1/cbrt */ + m_apm_set_double(r, (1.00001 / exp(dd))); +} +/****************************************************************************/ +void M_get_log_guess(M_APM r, M_APM a) +{ + char buf[48]; + double dd; + + m_apm_to_string(buf, 15, a); + dd = atof(buf); + m_apm_set_double(r, (1.00001 * log(dd))); /* induce error of 10 ^ -5 */ +} +/****************************************************************************/ +/* + * the implementation of the asin & acos functions + * guarantee that 'a' is always < 0.85, so it is + * safe to multiply by a number > 1 + */ +void M_get_asin_guess(M_APM r, M_APM a) +{ + char buf[48]; + double dd; + + m_apm_to_string(buf, 15, a); + dd = atof(buf); + m_apm_set_double(r, (1.00001 * asin(dd))); /* induce error of 10 ^ -5 */ +} +/****************************************************************************/ +void M_get_acos_guess(M_APM r, M_APM a) +{ + char buf[48]; + double dd; + + m_apm_to_string(buf, 15, a); + dd = atof(buf); + m_apm_set_double(r, (1.00001 * acos(dd))); /* induce error of 10 ^ -5 */ +} +/****************************************************************************/ +/* + convert a C 'double' into an M_APM value. +*/ +void m_apm_set_double(M_APM atmp, double dd) +{ + char *cp, *p, *ps, buf[64]; + + if (dd == 0.0) /* special case for 0 exactly */ + M_set_to_zero(atmp); + else + { + sprintf(buf, "%.14E", dd); + + if ((cp = strstr(buf, "E")) == NULL) + { + M_apm_log_error_msg(M_APM_RETURN, + "\'m_apm_set_double\', Invalid double input (likely a NAN or +/- INF)"); + + M_set_to_zero(atmp); + return; + } + + if (atoi(cp + sizeof(char)) == 0) + *cp = '\0'; + + p = cp; + + while (TRUE) + { + p--; + if (*p == '0' || *p == '.') + *p = ' '; + else + break; + } + + ps = buf; + p = buf; + + while (TRUE) + { + if ((*p = *ps) == '\0') + break; + + if (*ps++ != ' ') + p++; + } + + m_apm_set_string(atmp, buf); + } +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapmhasn.cpp b/pgscript/utilities/m_apm/mapmhasn.cpp new file mode 100644 index 0000000..27dd518 --- /dev/null +++ b/pgscript/utilities/m_apm/mapmhasn.cpp @@ -0,0 +1,132 @@ + +/* + * M_APM - mapmhasn.c + * + * Copyright (C) 2000 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the Inverse Hyperbolic SIN, COS, & TAN functions. + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +/* + * arcsinh(x) == log [ x + sqrt(x^2 + 1) ] + * + * also, use arcsinh(-x) == -arcsinh(x) + */ +void m_apm_arcsinh(M_APM rr, int places, M_APM aa) +{ + M_APM tmp0, tmp1, tmp2; + + /* result is 0 if input is 0 */ + + if (aa->m_apm_sign == 0) + { + M_set_to_zero(rr); + return; + } + + tmp0 = M_get_stack_var(); + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + + m_apm_absolute_value(tmp0, aa); + m_apm_multiply(tmp1, tmp0, tmp0); + m_apm_add(tmp2, tmp1, MM_One); + m_apm_sqrt(tmp1, (places + 6), tmp2); + m_apm_add(tmp2, tmp0, tmp1); + m_apm_log(rr, places, tmp2); + + rr->m_apm_sign = aa->m_apm_sign; /* fix final sign */ + + M_restore_stack(3); +} +/****************************************************************************/ +/* + * arccosh(x) == log [ x + sqrt(x^2 - 1) ] + * + * x >= 1.0 + */ +void m_apm_arccosh(M_APM rr, int places, M_APM aa) +{ + M_APM tmp1, tmp2; + int ii; + + ii = m_apm_compare(aa, MM_One); + + if (ii == -1) /* x < 1 */ + { + M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_arccosh\', Argument < 1"); + M_set_to_zero(rr); + return; + } + + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + + m_apm_multiply(tmp1, aa, aa); + m_apm_subtract(tmp2, tmp1, MM_One); + m_apm_sqrt(tmp1, (places + 6), tmp2); + m_apm_add(tmp2, aa, tmp1); + m_apm_log(rr, places, tmp2); + + M_restore_stack(2); +} +/****************************************************************************/ +/* + * arctanh(x) == 0.5 * log [ (1 + x) / (1 - x) ] + * + * |x| < 1.0 + */ +void m_apm_arctanh(M_APM rr, int places, M_APM aa) +{ + M_APM tmp1, tmp2, tmp3; + int ii, local_precision; + + tmp1 = M_get_stack_var(); + + m_apm_absolute_value(tmp1, aa); + + ii = m_apm_compare(tmp1, MM_One); + + if (ii >= 0) /* |x| >= 1.0 */ + { + M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_arctanh\', |Argument| >= 1"); + M_set_to_zero(rr); + M_restore_stack(1); + return; + } + + tmp2 = M_get_stack_var(); + tmp3 = M_get_stack_var(); + + local_precision = places + 8; + + m_apm_add(tmp1, MM_One, aa); + m_apm_subtract(tmp2, MM_One, aa); + m_apm_divide(tmp3, local_precision, tmp1, tmp2); + m_apm_log(tmp2, local_precision, tmp3); + m_apm_multiply(tmp1, tmp2, MM_0_5); + m_apm_round(rr, places, tmp1); + + M_restore_stack(3); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapmhsin.cpp b/pgscript/utilities/m_apm/mapmhsin.cpp new file mode 100644 index 0000000..cb6eeee --- /dev/null +++ b/pgscript/utilities/m_apm/mapmhsin.cpp @@ -0,0 +1,100 @@ + +/* + * M_APM - mapmhsin.c + * + * Copyright (C) 2000 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the Hyperbolic SIN, COS, & TAN functions. + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +/* + * sinh(x) == 0.5 * [ exp(x) - exp(-x) ] + */ +void m_apm_sinh(M_APM rr, int places, M_APM aa) +{ + M_APM tmp1, tmp2, tmp3; + int local_precision; + + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + tmp3 = M_get_stack_var(); + + local_precision = places + 4; + + m_apm_exp(tmp1, local_precision, aa); + m_apm_reciprocal(tmp2, local_precision, tmp1); + m_apm_subtract(tmp3, tmp1, tmp2); + m_apm_multiply(tmp1, tmp3, MM_0_5); + m_apm_round(rr, places, tmp1); + + M_restore_stack(3); +} +/****************************************************************************/ +/* + * cosh(x) == 0.5 * [ exp(x) + exp(-x) ] + */ +void m_apm_cosh(M_APM rr, int places, M_APM aa) +{ + M_APM tmp1, tmp2, tmp3; + int local_precision; + + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + tmp3 = M_get_stack_var(); + + local_precision = places + 4; + + m_apm_exp(tmp1, local_precision, aa); + m_apm_reciprocal(tmp2, local_precision, tmp1); + m_apm_add(tmp3, tmp1, tmp2); + m_apm_multiply(tmp1, tmp3, MM_0_5); + m_apm_round(rr, places, tmp1); + + M_restore_stack(3); +} +/****************************************************************************/ +/* + * tanh(x) == [ exp(x) - exp(-x) ] / [ exp(x) + exp(-x) ] + */ +void m_apm_tanh(M_APM rr, int places, M_APM aa) +{ + M_APM tmp1, tmp2, tmp3, tmp4; + int local_precision; + + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + tmp3 = M_get_stack_var(); + tmp4 = M_get_stack_var(); + + local_precision = places + 4; + + m_apm_exp(tmp1, local_precision, aa); + m_apm_reciprocal(tmp2, local_precision, tmp1); + m_apm_subtract(tmp3, tmp1, tmp2); + m_apm_add(tmp4, tmp1, tmp2); + m_apm_divide(tmp1, local_precision, tmp3, tmp4); + m_apm_round(rr, places, tmp1); + + M_restore_stack(4); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapmipwr.cpp b/pgscript/utilities/m_apm/mapmipwr.cpp new file mode 100644 index 0000000..a43d73a --- /dev/null +++ b/pgscript/utilities/m_apm/mapmipwr.cpp @@ -0,0 +1,98 @@ + +/* + * M_APM - mapmipwr.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the Integer Power function. + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +void m_apm_integer_pow(M_APM rr, int places, M_APM aa, int mexp) +{ + M_APM tmp0, tmpy, tmpz; + int nexp, ii, signflag, local_precision; + + if (mexp == 0) + { + m_apm_copy(rr, MM_One); + return; + } + else + { + if (mexp > 0) + { + signflag = 0; + nexp = mexp; + } + else + { + signflag = 1; + nexp = -mexp; + } + } + + if (aa->m_apm_sign == 0) + { + M_set_to_zero(rr); + return; + } + + tmp0 = M_get_stack_var(); + tmpy = M_get_stack_var(); + tmpz = M_get_stack_var(); + + local_precision = places + 8; + + m_apm_copy(tmpy, MM_One); + m_apm_copy(tmpz, aa); + + while (TRUE) + { + ii = nexp & 1; + nexp = nexp >> 1; + + if (ii != 0) /* exponent -was- odd */ + { + m_apm_multiply(tmp0, tmpy, tmpz); + m_apm_round(tmpy, local_precision, tmp0); + + if (nexp == 0) + break; + } + + m_apm_multiply(tmp0, tmpz, tmpz); + m_apm_round(tmpz, local_precision, tmp0); + } + + if (signflag) + { + m_apm_reciprocal(rr, places, tmpy); + } + else + { + m_apm_round(rr, places, tmpy); + } + + M_restore_stack(3); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapmistr.cpp b/pgscript/utilities/m_apm/mapmistr.cpp new file mode 100644 index 0000000..e3c289a --- /dev/null +++ b/pgscript/utilities/m_apm/mapmistr.cpp @@ -0,0 +1,112 @@ + +/* + * M_APM - mapmistr.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains M_APM -> integer string function + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +void m_apm_to_integer_string(char *s, M_APM mtmp) +{ + void *vp; + UCHAR *ucp, numdiv, numrem; + char *cp, *p, sbuf[128]; + int ct, dl, numb, ii; + + vp = NULL; + ct = mtmp->m_apm_exponent; + dl = mtmp->m_apm_datalength; + + /* + * if |input| < 1, result is "0" + */ + + if (ct <= 0 || mtmp->m_apm_sign == 0) + { + s[0] = '0'; + s[1] = '\0'; + return; + } + + if (ct > 112) + { + if ((vp = (void *)MAPM_MALLOC((ct + 32) * sizeof(char))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, + "\'m_apm_to_integer_string\', Out of memory"); + } + + cp = (char *)vp; + } + else + { + cp = sbuf; + } + + p = cp; + ii = 0; + + /* handle a negative number */ + + if (mtmp->m_apm_sign == -1) + { + ii = 1; + *p++ = '-'; + } + + /* get num-bytes of data (#digits / 2) to use in the string */ + + if (ct > dl) + numb = (dl + 1) >> 1; + else + numb = (ct + 1) >> 1; + + ucp = mtmp->m_apm_data; + + while (TRUE) + { + M_get_div_rem_10((int)(*ucp++), &numdiv, &numrem); + + *p++ = numdiv + '0'; + *p++ = numrem + '0'; + + if (--numb == 0) + break; + } + + /* pad with trailing zeros if the exponent > datalength */ + + if (ct > dl) + memset(p, '0', (ct + 1 - dl)); + + cp[ct + ii] = '\0'; + strcpy(s, cp); + + if (vp != NULL) + MAPM_FREE(vp); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapmpwr2.cpp b/pgscript/utilities/m_apm/mapmpwr2.cpp new file mode 100644 index 0000000..bf2a504 --- /dev/null +++ b/pgscript/utilities/m_apm/mapmpwr2.cpp @@ -0,0 +1,107 @@ + +/* + * M_APM - mapmpwr2.c + * + * Copyright (C) 2002 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * This file contains the Integer Power function and the result + * is NOT ROUNDED. The exponent must be an integer >= zero. + * + * This will typically be used in an application where full integer + * precision is required to be maintained. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +void m_apm_integer_pow_nr(M_APM rr, M_APM aa, int mexp) +{ + M_APM tmp0, tmpy, tmpz; + int nexp, ii; + + if (mexp == 0) + { + m_apm_copy(rr, MM_One); + return; + } + else + { + if (mexp < 0) + { + M_apm_log_error_msg(M_APM_RETURN, + "\'m_apm_integer_pow_nr\', Negative exponent"); + + M_set_to_zero(rr); + return; + } + } + + if (mexp == 1) + { + m_apm_copy(rr, aa); + return; + } + + if (mexp == 2) + { + m_apm_multiply(rr, aa, aa); + return; + } + + nexp = mexp; + + if (aa->m_apm_sign == 0) + { + M_set_to_zero(rr); + return; + } + + tmp0 = M_get_stack_var(); + tmpy = M_get_stack_var(); + tmpz = M_get_stack_var(); + + m_apm_copy(tmpy, MM_One); + m_apm_copy(tmpz, aa); + + while (TRUE) + { + ii = nexp & 1; + nexp = nexp >> 1; + + if (ii != 0) /* exponent -was- odd */ + { + m_apm_multiply(tmp0, tmpy, tmpz); + + if (nexp == 0) + break; + + m_apm_copy(tmpy, tmp0); + } + + m_apm_multiply(tmp0, tmpz, tmpz); + m_apm_copy(tmpz, tmp0); + } + + m_apm_copy(rr, tmp0); + + M_restore_stack(3); +} +/****************************************************************************/ + diff --git a/pgscript/utilities/m_apm/mapmrsin.cpp b/pgscript/utilities/m_apm/mapmrsin.cpp new file mode 100644 index 0000000..5c0d62c --- /dev/null +++ b/pgscript/utilities/m_apm/mapmrsin.cpp @@ -0,0 +1,164 @@ + +/* + * M_APM - mapmrsin.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the basic series expansion functions for + * the SIN / COS functions. + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +/* + x^3 x^5 x^7 x^9 + sin(x) = x - --- + --- - --- + --- ... + 3! 5! 7! 9! +*/ +void M_raw_sin(M_APM rr, int places, M_APM xx) +{ + M_APM sum, term, tmp2, tmp7, tmp8; + int tolerance, flag, local_precision, dplaces; + long m1, m2; + + sum = M_get_stack_var(); + term = M_get_stack_var(); + tmp2 = M_get_stack_var(); + tmp7 = M_get_stack_var(); + tmp8 = M_get_stack_var(); + + m_apm_copy(sum, xx); + m_apm_copy(term, xx); + m_apm_multiply(tmp8, xx, xx); + m_apm_round(tmp2, (places + 6), tmp8); + + dplaces = (places + 8) - xx->m_apm_exponent; + tolerance = xx->m_apm_exponent - (places + 4); + + m1 = 2L; + flag = 0; + + while (TRUE) + { + m_apm_multiply(tmp8, term, tmp2); + + if ((tmp8->m_apm_exponent < tolerance) || (tmp8->m_apm_sign == 0)) + break; + + local_precision = dplaces + term->m_apm_exponent; + + if (local_precision < 20) + local_precision = 20; + + m2 = m1 * (m1 + 1); + m_apm_set_long(tmp7, m2); + + m_apm_divide(term, local_precision, tmp8, tmp7); + + if (flag == 0) + { + m_apm_subtract(tmp7, sum, term); + m_apm_copy(sum, tmp7); + } + else + { + m_apm_add(tmp7, sum, term); + m_apm_copy(sum, tmp7); + } + + m1 += 2; + flag = 1 - flag; + } + + m_apm_round(rr, places, sum); + M_restore_stack(5); +} +/****************************************************************************/ +/* + x^2 x^4 x^6 x^8 + cos(x) = 1 - --- + --- - --- + --- ... + 2! 4! 6! 8! +*/ +void M_raw_cos(M_APM rr, int places, M_APM xx) +{ + M_APM sum, term, tmp7, tmp8, tmp9; + int tolerance, flag, local_precision, prev_exp; + long m1, m2; + + sum = M_get_stack_var(); + term = M_get_stack_var(); + tmp7 = M_get_stack_var(); + tmp8 = M_get_stack_var(); + tmp9 = M_get_stack_var(); + + m_apm_copy(sum, MM_One); + m_apm_copy(term, MM_One); + + m_apm_multiply(tmp8, xx, xx); + m_apm_round(tmp9, (places + 6), tmp8); + + local_precision = places + 8; + tolerance = -(places + 4); + prev_exp = 0; + + m1 = 1L; + flag = 0; + + while (TRUE) + { + m2 = m1 * (m1 + 1); + m_apm_set_long(tmp7, m2); + + m_apm_multiply(tmp8, term, tmp9); + m_apm_divide(term, local_precision, tmp8, tmp7); + + if (flag == 0) + { + m_apm_subtract(tmp7, sum, term); + m_apm_copy(sum, tmp7); + } + else + { + m_apm_add(tmp7, sum, term); + m_apm_copy(sum, tmp7); + } + + if ((term->m_apm_exponent < tolerance) || (term->m_apm_sign == 0)) + break; + + if (m1 != 1L) + { + local_precision = local_precision + term->m_apm_exponent - prev_exp; + + if (local_precision < 20) + local_precision = 20; + } + + prev_exp = term->m_apm_exponent; + + m1 += 2; + flag = 1 - flag; + } + + m_apm_round(rr, places, sum); + M_restore_stack(5); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapmsqrt.cpp b/pgscript/utilities/m_apm/mapmsqrt.cpp new file mode 100644 index 0000000..ed9d835 --- /dev/null +++ b/pgscript/utilities/m_apm/mapmsqrt.cpp @@ -0,0 +1,130 @@ + +/* + * M_APM - mapmsqrt.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the SQRT function. + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +void m_apm_sqrt(M_APM rr, int places, M_APM aa) +{ + M_APM last_x, guess, tmpN, tmp7, tmp8, tmp9; + int ii, bflag, nexp, tolerance, dplaces; + + if (aa->m_apm_sign <= 0) + { + if (aa->m_apm_sign == -1) + { + M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_sqrt\', Negative argument"); + } + + M_set_to_zero(rr); + return; + } + + last_x = M_get_stack_var(); + guess = M_get_stack_var(); + tmpN = M_get_stack_var(); + tmp7 = M_get_stack_var(); + tmp8 = M_get_stack_var(); + tmp9 = M_get_stack_var(); + + m_apm_copy(tmpN, aa); + + /* + normalize the input number (make the exponent near 0) so + the 'guess' function will not over/under flow on large + magnitude exponents. + */ + + nexp = aa->m_apm_exponent / 2; + tmpN->m_apm_exponent -= 2 * nexp; + + M_get_sqrt_guess(guess, tmpN); /* actually gets 1/sqrt guess */ + + tolerance = places + 4; + dplaces = places + 16; + bflag = FALSE; + + m_apm_negate(last_x, MM_Ten); + + /* Use the following iteration to calculate 1 / sqrt(N) : + + X = 0.5 * X * [ 3 - N * X^2 ] + n+1 + */ + + ii = 0; + + while (TRUE) + { + m_apm_multiply(tmp9, tmpN, guess); + m_apm_multiply(tmp8, tmp9, guess); + m_apm_round(tmp7, dplaces, tmp8); + m_apm_subtract(tmp9, MM_Three, tmp7); + m_apm_multiply(tmp8, tmp9, guess); + m_apm_multiply(tmp9, tmp8, MM_0_5); + + if (bflag) + break; + + m_apm_round(guess, dplaces, tmp9); + + /* force at least 2 iterations so 'last_x' has valid data */ + + if (ii != 0) + { + m_apm_subtract(tmp7, guess, last_x); + + if (tmp7->m_apm_sign == 0) + break; + + /* + * if we are within a factor of 4 on the error term, + * we will be accurate enough after the *next* iteration + * is complete. (note that the sign of the exponent on + * the error term will be a negative number). + */ + + if ((-4 * tmp7->m_apm_exponent) > tolerance) + bflag = TRUE; + } + + m_apm_copy(last_x, guess); + ii++; + } + + /* + * multiply by the starting number to get the final + * sqrt and then adjust the exponent since we found + * the sqrt of the normalized number. + */ + + m_apm_multiply(tmp8, tmp9, tmpN); + m_apm_round(rr, places, tmp8); + rr->m_apm_exponent += nexp; + + M_restore_stack(6); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapmstck.cpp b/pgscript/utilities/m_apm/mapmstck.cpp new file mode 100644 index 0000000..1eb567e --- /dev/null +++ b/pgscript/utilities/m_apm/mapmstck.cpp @@ -0,0 +1,108 @@ + +/* + * M_APM - mapmstck.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the stack implementation for using + * local M_APM variables. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +static int M_stack_ptr = -1; +static int M_last_init = -1; +static int M_stack_size = 0; + +static const char *M_stack_err_msg = "\'M_get_stack_var\', Out of memory"; + +static M_APM *M_stack_array; + +/****************************************************************************/ +void M_free_all_stck() +{ + int k; + + if (M_last_init >= 0) + { + for (k = 0; k <= M_last_init; k++) + m_apm_free(M_stack_array[k]); + + M_stack_ptr = -1; + M_last_init = -1; + M_stack_size = 0; + + MAPM_FREE(M_stack_array); + } +} +/****************************************************************************/ +M_APM M_get_stack_var() +{ + void *vp; + + if (++M_stack_ptr > M_last_init) + { + if (M_stack_size == 0) + { + M_stack_size = 18; + if ((vp = MAPM_MALLOC(M_stack_size * sizeof(M_APM))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, M_stack_err_msg); + } + + M_stack_array = (M_APM *)vp; + } + + if ((M_last_init + 4) >= M_stack_size) + { + M_stack_size += 12; + if ((vp = MAPM_REALLOC(M_stack_array, + (M_stack_size * sizeof(M_APM)))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, M_stack_err_msg); + } + + M_stack_array = (M_APM *)vp; + } + + M_stack_array[M_stack_ptr] = m_apm_init(); + M_stack_array[M_stack_ptr + 1] = m_apm_init(); + M_stack_array[M_stack_ptr + 2] = m_apm_init(); + M_stack_array[M_stack_ptr + 3] = m_apm_init(); + + M_last_init = M_stack_ptr + 3; + + /* printf("M_last_init = %d \n",M_last_init); */ + } + + return(M_stack_array[M_stack_ptr]); +} +/****************************************************************************/ +void M_restore_stack(int count) +{ + M_stack_ptr -= count; +} +/****************************************************************************/ + diff --git a/pgscript/utilities/m_apm/mapmutil.cpp b/pgscript/utilities/m_apm/mapmutil.cpp new file mode 100644 index 0000000..33cde26 --- /dev/null +++ b/pgscript/utilities/m_apm/mapmutil.cpp @@ -0,0 +1,475 @@ + +/* + * M_APM - mapmutil.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains various utility functions needed by the + * library in addition to some basic user callable functions. + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +static UCHAR *M_mul_div = NULL; +static UCHAR *M_mul_rem = NULL; + +static UCHAR M_mul_div_10[100]; +static UCHAR M_mul_rem_10[100]; + +static int M_util_firsttime = TRUE; +static int M_firsttime3 = TRUE; + +static M_APM M_work_0_5; + +static const char *M_init_error_msg = "\'m_apm_init\', Out of memory"; + +/****************************************************************************/ +M_APM m_apm_init() +{ + M_APM atmp; + + if (M_firsttime3) + { + M_firsttime3 = FALSE; + M_init_util_data(); + M_init_trig_globals(); + } + + if ((atmp = (M_APM)MAPM_MALLOC(sizeof(M_APM_struct))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, M_init_error_msg); + } + + atmp->m_apm_id = M_APM_IDENT; + atmp->m_apm_malloclength = 80; + atmp->m_apm_datalength = 1; + atmp->m_apm_refcount = 1; /* not for us, for MAPM C++ class */ + atmp->m_apm_exponent = 0; + atmp->m_apm_sign = 0; + + if ((atmp->m_apm_data = (UCHAR *)MAPM_MALLOC(84)) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, M_init_error_msg); + } + + atmp->m_apm_data[0] = 0; + return(atmp); +} +/****************************************************************************/ +void m_apm_free(M_APM atmp) +{ + if (atmp->m_apm_id == M_APM_IDENT) + { + atmp->m_apm_id = 0x0FFFFFF0L; + MAPM_FREE(atmp->m_apm_data); + MAPM_FREE(atmp); + } + else + { + M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_free\', Invalid M_APM variable"); + } +} +/****************************************************************************/ +void M_free_all_util() +{ + if (M_util_firsttime == FALSE) + { + m_apm_free(M_work_0_5); + M_util_firsttime = TRUE; + } + + if (M_firsttime3 == FALSE) + { + MAPM_FREE(M_mul_div); + MAPM_FREE(M_mul_rem); + + M_mul_div = NULL; + M_mul_rem = NULL; + M_firsttime3 = TRUE; + } +} +/****************************************************************************/ +/* + * just a dummy wrapper to keep some compilers from complaining + */ +int M_get_sizeof_int() +{ + return(sizeof(int)); +} +/****************************************************************************/ +void M_init_util_data() +{ + int k; + UCHAR ndiv, nrem; + + if (M_mul_div != NULL) + return; + + M_mul_div = (UCHAR *)MAPM_MALLOC(10000 * sizeof(UCHAR)); + M_mul_rem = (UCHAR *)MAPM_MALLOC(10000 * sizeof(UCHAR)); + + if (M_mul_div == NULL || M_mul_rem == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, "\'M_init_util_data\', Out of memory"); + } + + ndiv = 0; + nrem = 0; + + for (k = 0; k < 100; k++) + { + M_mul_div_10[k] = ndiv; + M_mul_rem_10[k] = nrem; + + if (++nrem == 10) + { + nrem = 0; + ndiv++; + } + } + + ndiv = 0; + nrem = 0; + + for (k = 0; k < 10000; k++) + { + M_mul_div[k] = ndiv; + M_mul_rem[k] = nrem; + + if (++nrem == 100) + { + nrem = 0; + ndiv++; + } + } +} +/****************************************************************************/ +void M_get_div_rem_addr(UCHAR **ndivp, UCHAR **nremp) +{ + *ndivp = M_mul_div; + *nremp = M_mul_rem; +} +/****************************************************************************/ +void M_get_div_rem(int tbl_lookup, UCHAR *ndiv, UCHAR *nrem) +{ + *ndiv = M_mul_div[tbl_lookup]; + *nrem = M_mul_rem[tbl_lookup]; +} +/****************************************************************************/ +void M_get_div_rem_10(int tbl_lookup, UCHAR *ndiv, UCHAR *nrem) +{ + *ndiv = M_mul_div_10[tbl_lookup]; + *nrem = M_mul_rem_10[tbl_lookup]; +} +/****************************************************************************/ +void m_apm_round(M_APM btmp, int places, M_APM atmp) +{ + int ii; + + if (M_util_firsttime) + { + M_util_firsttime = FALSE; + + M_work_0_5 = m_apm_init(); + m_apm_set_string(M_work_0_5, "5"); + } + + ii = places + 1; + + if (atmp->m_apm_datalength <= ii) + { + m_apm_copy(btmp, atmp); + return; + } + + M_work_0_5->m_apm_exponent = atmp->m_apm_exponent - ii; + + if (atmp->m_apm_sign > 0) + m_apm_add(btmp, atmp, M_work_0_5); + else + m_apm_subtract(btmp, atmp, M_work_0_5); + + btmp->m_apm_datalength = ii; + M_apm_normalize(btmp); +} +/****************************************************************************/ +void M_apm_normalize(M_APM atmp) +{ + int i, index, datalength, exponent; + UCHAR *ucp, numdiv, numrem, numrem2; + + if (atmp->m_apm_sign == 0) + return; + + datalength = atmp->m_apm_datalength; + exponent = atmp->m_apm_exponent; + + /* make sure trailing bytes/chars are 0 */ + /* the following function will adjust the 'datalength' */ + /* we want the original value and will fix it later */ + + M_apm_pad(atmp, (datalength + 3)); + + while (TRUE) /* remove lead-in '0' if any */ + { + M_get_div_rem_10((int)atmp->m_apm_data[0], &numdiv, &numrem); + + if (numdiv >= 1) /* number is normalized, done here */ + break; + + index = (datalength + 1) >> 1; + + if (numrem == 0) /* both nibbles are 0, we can move full bytes */ + { + i = 0; + ucp = atmp->m_apm_data; + + while (TRUE) /* find out how many '00' bytes we can move */ + { + if (*ucp != 0) + break; + + ucp++; + i++; + } + + memmove(atmp->m_apm_data, ucp, (index + 1 - i)); + datalength -= 2 * i; + exponent -= 2 * i; + } + else + { + for (i = 0; i < index; i++) + { + M_get_div_rem_10((int)atmp->m_apm_data[i + 1], &numdiv, &numrem2); + atmp->m_apm_data[i] = 10 * numrem + numdiv; + numrem = numrem2; + } + + datalength--; + exponent--; + } + } + + while (TRUE) /* remove trailing '0' if any */ + { + index = ((datalength + 1) >> 1) - 1; + + if ((datalength & 1) == 0) /* back-up full bytes at a time if the */ + { + /* current length is an even number */ + ucp = atmp->m_apm_data + index; + if (*ucp == 0) + { + while (TRUE) + { + datalength -= 2; + index--; + ucp--; + + if (*ucp != 0) + break; + } + } + } + + M_get_div_rem_10((int)atmp->m_apm_data[index], &numdiv, &numrem); + + if (numrem != 0) /* last digit non-zero, all done */ + break; + + if ((datalength & 1) != 0) /* if odd, then first char must be non-zero */ + { + if (numdiv != 0) + break; + } + + if (datalength == 1) + { + atmp->m_apm_sign = 0; + exponent = 0; + break; + } + + datalength--; + } + + atmp->m_apm_datalength = datalength; + atmp->m_apm_exponent = exponent; +} +/****************************************************************************/ +void M_apm_scale(M_APM ctmp, int count) +{ + int ii, numb, ct; + UCHAR *chp, numdiv, numdiv2, numrem; + void *vp; + + ct = count; + + ii = (ctmp->m_apm_datalength + ct + 1) >> 1; + if (ii > ctmp->m_apm_malloclength) + { + if ((vp = MAPM_REALLOC(ctmp->m_apm_data, (ii + 32))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, "\'M_apm_scale\', Out of memory"); + } + + ctmp->m_apm_malloclength = ii + 28; + ctmp->m_apm_data = (UCHAR *)vp; + } + + if ((ct & 1) != 0) /* move odd number first */ + { + ct--; + chp = ctmp->m_apm_data; + ii = ((ctmp->m_apm_datalength + 1) >> 1) - 1; + + if ((ctmp->m_apm_datalength & 1) == 0) + { + /* + * original datalength is even: + * + * uv wx yz becomes --> 0u vw xy z0 + */ + + numdiv = 0; + + while (TRUE) + { + M_get_div_rem_10((int)chp[ii], &numdiv2, &numrem); + + chp[ii + 1] = 10 * numrem + numdiv; + numdiv = numdiv2; + + if (ii == 0) + break; + + ii--; + } + + chp[0] = numdiv2; + } + else + { + /* + * original datalength is odd: + * + * uv wx y0 becomes --> 0u vw xy + */ + + M_get_div_rem_10((int)chp[ii], &numdiv2, &numrem); + + if (ii == 0) + { + chp[0] = numdiv2; + } + else + { + while (TRUE) + { + M_get_div_rem_10((int)chp[ii - 1], &numdiv, &numrem); + + chp[ii] = 10 * numrem + numdiv2; + numdiv2 = numdiv; + + if (--ii == 0) + break; + } + + chp[0] = numdiv; + } + } + + ctmp->m_apm_exponent++; + ctmp->m_apm_datalength++; + } + + /* ct is even here */ + + if (ct > 0) + { + numb = (ctmp->m_apm_datalength + 1) >> 1; + ii = ct >> 1; + + memmove((ctmp->m_apm_data + ii), ctmp->m_apm_data, numb); + memset(ctmp->m_apm_data, 0, ii); + + ctmp->m_apm_datalength += ct; + ctmp->m_apm_exponent += ct; + } +} +/****************************************************************************/ +void M_apm_pad(M_APM ctmp, int new_length) +{ + int num1, numb, ct; + UCHAR numdiv, numrem; + void *vp; + + ct = new_length; + if (ctmp->m_apm_datalength >= ct) + return; + + numb = (ct + 1) >> 1; + if (numb > ctmp->m_apm_malloclength) + { + if ((vp = MAPM_REALLOC(ctmp->m_apm_data, (numb + 32))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, "\'M_apm_pad\', Out of memory"); + } + + ctmp->m_apm_malloclength = numb + 28; + ctmp->m_apm_data = (UCHAR *)vp; + } + + num1 = (ctmp->m_apm_datalength + 1) >> 1; + + if ((ctmp->m_apm_datalength & 1) != 0) + { + M_get_div_rem_10((int)ctmp->m_apm_data[num1 - 1], &numdiv, &numrem); + ctmp->m_apm_data[num1 - 1] = 10 * numdiv; + } + + memset((ctmp->m_apm_data + num1), 0, (numb - num1)); + ctmp->m_apm_datalength = ct; +} +/****************************************************************************/ + +/* + debug_dsp(cc) + M_APM cc; + { +static char buffer[8192]; + +m_apm_to_string(buffer, -1, cc); +printf("(dsp func) = [%s]\n",buffer); + + } +*/ + diff --git a/pgscript/utilities/m_apm/mapmutl1.cpp b/pgscript/utilities/m_apm/mapmutl1.cpp new file mode 100644 index 0000000..815a581 --- /dev/null +++ b/pgscript/utilities/m_apm/mapmutl1.cpp @@ -0,0 +1,47 @@ + +/* + * M_APM - mapmutl1.c + * + * Copyright (C) 2003 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + + * + * This file contains the utility function 'M_apm_log_error_msg' + * + * This is the only function in this file so a user can supply + * their own custom version easily without changing the base library. + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +void M_apm_log_error_msg(int fatal, const char *message) +{ + if (fatal) + { + fprintf(stderr, "MAPM Error: %s\n", message); + exit(100); + } + else + { + fprintf(stderr, "MAPM Warning: %s\n", message); + } +} +/****************************************************************************/ + diff --git a/pgscript/utilities/m_apm/mapmutl2.cpp b/pgscript/utilities/m_apm/mapmutl2.cpp new file mode 100644 index 0000000..93e6c94 --- /dev/null +++ b/pgscript/utilities/m_apm/mapmutl2.cpp @@ -0,0 +1,329 @@ + +/* + * M_APM - mapmutl2.c + * + * Copyright (C) 2002 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * This file contains various utility functions + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +int m_apm_sign(M_APM atmp) +{ + return(atmp->m_apm_sign); +} +/****************************************************************************/ +int m_apm_exponent(M_APM atmp) +{ + if (atmp->m_apm_sign == 0) + return(0); + else + return(atmp->m_apm_exponent - 1); +} +/****************************************************************************/ +int m_apm_significant_digits(M_APM atmp) +{ + return(atmp->m_apm_datalength); +} +/****************************************************************************/ +int m_apm_is_integer(M_APM atmp) +{ + if (atmp->m_apm_sign == 0) + return(1); + + if (atmp->m_apm_exponent >= atmp->m_apm_datalength) + return(1); + else + return(0); +} +/****************************************************************************/ +int m_apm_is_even(M_APM aa) +{ + int ii, jj; + + if (aa->m_apm_sign == 0) + return(1); + + ii = aa->m_apm_datalength; + jj = aa->m_apm_exponent; + + if (jj < ii) + { + M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_is_even\', Non-integer input"); + return(0); + } + + if (jj > ii) + return(1); + + ii = ((ii + 1) >> 1) - 1; + ii = (int)aa->m_apm_data[ii]; + + if ((jj & 1) != 0) /* exponent is odd */ + ii = ii / 10; + + if ((ii & 1) == 0) + return(1); + else + return(0); +} +/****************************************************************************/ +int m_apm_is_odd(M_APM bb) +{ + if (m_apm_is_even(bb)) + return(0); + else + return(1); +} +/****************************************************************************/ +void M_set_to_zero(M_APM z) +{ + z->m_apm_datalength = 1; + z->m_apm_sign = 0; + z->m_apm_exponent = 0; + z->m_apm_data[0] = 0; +} +/****************************************************************************/ +void m_apm_negate(M_APM d, M_APM s) +{ + m_apm_copy(d, s); + if (d->m_apm_sign != 0) + d->m_apm_sign = -(d->m_apm_sign); +} +/****************************************************************************/ +void m_apm_absolute_value(M_APM d, M_APM s) +{ + m_apm_copy(d, s); + if (d->m_apm_sign != 0) + d->m_apm_sign = 1; +} +/****************************************************************************/ +void m_apm_copy(M_APM dest, M_APM src) +{ + int j; + void *vp; + + j = (src->m_apm_datalength + 1) >> 1; + if (j > dest->m_apm_malloclength) + { + if ((vp = MAPM_REALLOC(dest->m_apm_data, (j + 32))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, "\'m_apm_copy\', Out of memory"); + } + + dest->m_apm_malloclength = j + 28; + dest->m_apm_data = (UCHAR *)vp; + } + + dest->m_apm_datalength = src->m_apm_datalength; + dest->m_apm_exponent = src->m_apm_exponent; + dest->m_apm_sign = src->m_apm_sign; + + memcpy(dest->m_apm_data, src->m_apm_data, j); +} +/****************************************************************************/ +int m_apm_compare(M_APM ltmp, M_APM rtmp) +{ + int llen, rlen, lsign, rsign, i, j, lexp, rexp; + + llen = ltmp->m_apm_datalength; + rlen = rtmp->m_apm_datalength; + + lsign = ltmp->m_apm_sign; + rsign = rtmp->m_apm_sign; + + lexp = ltmp->m_apm_exponent; + rexp = rtmp->m_apm_exponent; + + if (rsign == 0) + return(lsign); + + if (lsign == 0) + return(-rsign); + + if (lsign == -rsign) + return(lsign); + + /* signs are the same, check the exponents */ + + if (lexp > rexp) + goto E1; + + if (lexp < rexp) + goto E2; + + /* signs and exponents are the same, check the data */ + + if (llen < rlen) + j = (llen + 1) >> 1; + else + j = (rlen + 1) >> 1; + + for (i = 0; i < j; i++) + { + if (ltmp->m_apm_data[i] > rtmp->m_apm_data[i]) + goto E1; + + if (ltmp->m_apm_data[i] < rtmp->m_apm_data[i]) + goto E2; + } + + if (llen == rlen) + return(0); + else + { + if (llen > rlen) + goto E1; + else + goto E2; + } + +E1: + + if (lsign == 1) + return(1); + else + return(-1); + +E2: + + if (lsign == 1) + return(-1); + else + return(1); +} +/****************************************************************************/ +/* + * + * convert a signed long int to ASCII in base 10 + * + */ +void M_long_2_ascii(char *output, long input) +{ + long t, m; + int i, j; + char *p, tbuf[64]; + + m = input; + p = output; + i = 0; + t = 2147000000L; /* something < 2^31 */ + + if ((m > t) || (m < -t)) /* handle the bigger numbers with 'sprintf'. */ + { + /* let them worry about wrap-around problems */ + sprintf(p, "%ld", m); /* at 'LONG_MIN', etc. */ + } + else + { + if (m < 0) /* handle the sign */ + { + *p++ = '-'; + m = -m; + } + + while (TRUE) /* build the digits in reverse order */ + { + t = m / 10; + j = (int)(m - (10 * t)); + tbuf[i++] = (char)(j + '0'); + m = t; + + if (t == 0) + break; + } + + while (TRUE) /* fill output string in the correct order */ + { + *p++ = tbuf[--i]; + if (i == 0) + break; + } + + *p = '\0'; + } +} +/****************************************************************************/ +/* + * this function will convert a string to lowercase + */ +char *M_lowercase(char *s) +{ + char *p; + + p = s; + + while (TRUE) + { + if (*p >= 'A' && *p <= 'Z') + *p += 'a' - 'A'; + + if (*p++ == '\0') break; + } + return(s); +} +/****************************************************************************/ +/* returns char position of first occurrence of s2 in s1 + or -1 if no match found +*/ +int M_strposition(char *s1, char *s2) +{ + register char ch1, ch2; + char *p0, *p1, *p2; + int ct; + + ct = -1; + p0 = s1; + + if (*s2 == '\0') return(-1); + + while (TRUE) + { + ct++; + p1 = p0; + p2 = s2; + ch2 = *p2; + + while (TRUE) /* scan until first char matches */ + { + if ((ch1 = *p1) == '\0') return(-1); + if (ch1 == ch2) break; + p1++; + ct++; + } + + p2++; /* check remainder of 2 strings */ + p1++; + p0 = p1; + + while (TRUE) + { + if ((ch2 = *p2) == '\0') return(ct); + if (*p1 != ch2) break; + p1++; + p2++; + } + } +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/module.mk b/pgscript/utilities/m_apm/module.mk new file mode 100644 index 0000000..2ab8737 --- /dev/null +++ b/pgscript/utilities/m_apm/module.mk @@ -0,0 +1,54 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/pgscript/utilities/m_apm/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + pgscript/utilities/m_apm/mapm5sin.cpp \ + pgscript/utilities/m_apm/mapmasin.cpp \ + pgscript/utilities/m_apm/mapmasn0.cpp \ + pgscript/utilities/m_apm/mapmcbrt.cpp \ + pgscript/utilities/m_apm/mapmcnst.cpp \ + pgscript/utilities/m_apm/mapmfact.cpp \ + pgscript/utilities/m_apm/mapmfmul.cpp \ + pgscript/utilities/m_apm/mapmgues.cpp \ + pgscript/utilities/m_apm/mapmhasn.cpp \ + pgscript/utilities/m_apm/mapmhsin.cpp \ + pgscript/utilities/m_apm/mapmipwr.cpp \ + pgscript/utilities/m_apm/mapmistr.cpp \ + pgscript/utilities/m_apm/mapmpwr2.cpp \ + pgscript/utilities/m_apm/mapmrsin.cpp \ + pgscript/utilities/m_apm/mapmsqrt.cpp \ + pgscript/utilities/m_apm/mapmstck.cpp \ + pgscript/utilities/m_apm/mapmutil.cpp \ + pgscript/utilities/m_apm/mapmutl1.cpp \ + pgscript/utilities/m_apm/mapmutl2.cpp \ + pgscript/utilities/m_apm/mapm_add.cpp \ + pgscript/utilities/m_apm/mapm_cpi.cpp \ + pgscript/utilities/m_apm/mapm_div.cpp \ + pgscript/utilities/m_apm/mapm_exp.cpp \ + pgscript/utilities/m_apm/mapm_fam.cpp \ + pgscript/utilities/m_apm/mapm_fft.cpp \ + pgscript/utilities/m_apm/mapm_flr.cpp \ + pgscript/utilities/m_apm/mapm_fpf.cpp \ + pgscript/utilities/m_apm/mapm_gcd.cpp \ + pgscript/utilities/m_apm/mapm_lg2.cpp \ + pgscript/utilities/m_apm/mapm_lg3.cpp \ + pgscript/utilities/m_apm/mapm_lg4.cpp \ + pgscript/utilities/m_apm/mapm_log.cpp \ + pgscript/utilities/m_apm/mapm_mul.cpp \ + pgscript/utilities/m_apm/mapm_pow.cpp \ + pgscript/utilities/m_apm/mapm_rcp.cpp \ + pgscript/utilities/m_apm/mapm_rnd.cpp \ + pgscript/utilities/m_apm/mapm_set.cpp \ + pgscript/utilities/m_apm/mapm_sin.cpp + +EXTRA_DIST += \ + pgscript/utilities/m_apm/module.mk + diff --git a/pgscript/utilities/module.mk b/pgscript/utilities/module.mk new file mode 100644 index 0000000..72ca07c --- /dev/null +++ b/pgscript/utilities/module.mk @@ -0,0 +1,23 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/pgscript/utilities/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + pgscript/utilities/pgsAlloc.cpp \ + pgscript/utilities/pgsContext.cpp \ + pgscript/utilities/pgsDriver.cpp \ + pgscript/utilities/pgsMapm.cpp \ + pgscript/utilities/pgsThread.cpp \ + pgscript/utilities/pgsUtilities.cpp + +EXTRA_DIST += \ + pgscript/utilities/module.mk + +include pgscript/utilities/m_apm/module.mk diff --git a/pgscript/utilities/pgsAlloc.cpp b/pgscript/utilities/pgsAlloc.cpp new file mode 100644 index 0000000..96f324f --- /dev/null +++ b/pgscript/utilities/pgsAlloc.cpp @@ -0,0 +1,123 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" + +#if defined(PGSDEBUG) + +#include "pgscript/utilities/pgsAlloc.h" +#include +#include + +#undef new +#undef delete + +pgsAlloc::pgsAlloc() +{ + +} + +void pgsAlloc::add_malloc(const pgsMallocInfo &malloc_info) +{ + m_malloc_info[malloc_info.ptr] = malloc_info; +} + +void pgsAlloc::rm_malloc(const void *ptr) +{ + if (m_malloc_info.size() != 0) + { + pgsMallocInfoMap::iterator it = m_malloc_info.find(ptr); + if (it != m_malloc_info.end()) + { + m_malloc_info.erase(it); + } + } +} + +void pgsAlloc::dump() +{ + pgsMallocInfoMap::const_iterator it = m_malloc_info.begin(); + for (it = m_malloc_info.begin(); it != m_malloc_info.end(); it++) + { + const pgsMallocInfo &info = it->second; + + wxLogError(wxString() << info.filename << wxT(":") + << info.line_nb << wxT(" - ") << (int) info.ptr + << wxT(" of size ") << info.size); + } +} + +void *pgsAlloc::pmalloc(size_t size, const char *filename, size_t line_nb) +{ + // Nothing to do if there is nothing to allocate + if (size == 0) return 0; + + void *ptr = 0; + ptr = malloc(size); + + // Add allocation in the allocation map + pgsMallocInfo malloc_info; + malloc_info.ptr = ptr; + malloc_info.size = size; + malloc_info.filename = wxString(filename, wxConvFile); + malloc_info.line_nb = line_nb; + this->add_malloc(malloc_info); + + return ptr; +} + +void pgsAlloc::pfree(void *ptr) +{ + // Remove information from the map if this piece of data exists + this->rm_malloc(ptr); + + // Delete the data + free(ptr); +} + +pgsAlloc &pgsAlloc::instance() +{ + static pgsAlloc x; + return x; +} + +void *operator new(size_t size) throw (std::bad_alloc) +{ + return malloc(size); +} + +void *operator new[](size_t size) throw (std::bad_alloc) +{ + return malloc(size); +} + +void *operator new(size_t size, const char *filename, size_t line_nb) +throw (std::bad_alloc) +{ + return pgsAlloc::instance().pmalloc(size, filename, line_nb); +} + +void *operator new[](size_t size, const char *filename, size_t line_nb) +throw (std::bad_alloc) +{ + return pgsAlloc::instance().pmalloc(size, filename, line_nb); +} + +void operator delete(void *ptr) throw() +{ + pgsAlloc::instance().pfree(ptr); +} + +void operator delete[](void *ptr) throw() +{ + pgsAlloc::instance().pfree(ptr); +} + +#endif diff --git a/pgscript/utilities/pgsContext.cpp b/pgscript/utilities/pgsContext.cpp new file mode 100644 index 0000000..6de0147 --- /dev/null +++ b/pgscript/utilities/pgsContext.cpp @@ -0,0 +1,134 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/utilities/pgsContext.h" + +#include +#include +#include +#include "pgscript/objects/pgsNumber.h" +#include "pgscript/objects/pgsString.h" +#include "pgscript/statements/pgsExpressionStmt.h" + +#include +WX_DEFINE_LIST(pgsListExpression); + +pgsContext::pgsContext(pgsOutputStream &cout) : + m_cout(cout) +{ + +} + +pgsContext::~pgsContext() +{ + +} + +pgsVariable *pgsContext::zero() +{ + pgsVariable *zero = pnew pgsNumber(wxT("0")); + push_var(zero); + return zero; +} + +pgsVariable *pgsContext::one() +{ + pgsVariable *one = pnew pgsNumber(wxT("1")); + push_var(one); + return one; +} + +pgsVariable *pgsContext::seed() +{ + pgsVariable *seed = pnew pgsNumber(wxString() << wxDateTime::GetTimeNow()); + push_var(seed); + return seed; +} + +pgsVariable *pgsContext::encoding() +{ + pgsVariable *encoding = pnew pgsString(wxLocale::GetSystemEncodingName()); + push_var(encoding); + return encoding; +} + +pgsStmtList *pgsContext::stmt_list(pgsThread *app) +{ + pgsStmtList *stmt_list = pnew pgsStmtList(m_cout, app); + push_stmt(stmt_list); + return stmt_list; +} + +void pgsContext::add_column(const wxString &column) +{ + m_columns.Add(column); +} + +const wxArrayString &pgsContext::columns() +{ + return m_columns; +} + +void pgsContext::clear_columns() +{ + m_columns.Clear(); +} + +void pgsContext::push_var(pgsExpression *var) +{ + wxLogScriptVerbose(wxT("PUSH EXPR %s"), var->value().c_str()); + m_vars.push_back(var); +} + +void pgsContext::pop_var() +{ + wxLogScriptVerbose(wxT("POP EXPR %s"), m_vars.back()->value().c_str()); + m_vars.pop_back(); +} + +size_t pgsContext::size_vars() const +{ + return m_vars.GetCount(); +} + +void pgsContext::push_stmt(pgsStmt *stmt) +{ + wxLogScriptVerbose(wxT("PUSH STMT %s"), wxString(typeid(*stmt).name(), + wxConvUTF8).c_str()); + m_stmts.push_back(stmt); +} + +void pgsContext::pop_stmt() +{ + wxLogScriptVerbose(wxT("POP STMT %s"), wxString(typeid(*(m_stmts.back())) + .name(), wxConvUTF8).c_str()); + m_stmts.pop_back(); +} + +size_t pgsContext::size_stmts() const +{ + return m_stmts.GetCount(); +} + +void pgsContext::clear_stacks() +{ + while (!m_vars.empty()) + { + pdelete(m_vars.back()); + m_vars.pop_back(); + } + + while (!m_stmts.empty()) + { + pdelete(m_stmts.back()); + m_stmts.pop_back(); + } +} diff --git a/pgscript/utilities/pgsDriver.cpp b/pgscript/utilities/pgsDriver.cpp new file mode 100644 index 0000000..4d04765 --- /dev/null +++ b/pgscript/utilities/pgsDriver.cpp @@ -0,0 +1,81 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/utilities/pgsDriver.h" +#include "pgscript/utilities/pgsThread.h" +#include "pgscript/utilities/pgsUtilities.h" + +#include +#include + +namespace pgscript +{ + +pgsDriver::pgsDriver(class pgsContext &_context, class pgsProgram &_program, + class pgsThread &_thread) : + trace_scanning(false), trace_parsing(false), context(_context), + program(_program), thread(_thread) +{ + wxLogScript(wxT("Driver created")); +} + +pgsDriver::~pgsDriver() +{ + wxLogScript(wxT("Driver destroyed")); +} + +bool pgsDriver::parse_stream(std::istream &in) +{ + pgsScanner scanner(wxConvUTF8, &in); + scanner.set_debug(trace_scanning); + this->lexer = &scanner; + + pgsParser parser(*this); + parser.set_debug_level(trace_parsing); + return (parser.parse() == 0); +} + +bool pgsDriver::parse_file(const wxString &filename, wxMBConv &conv) +{ + wxFileName file_path(filename); + if (file_path.FileExists() && file_path.IsFileReadable()) + { + wxFFile file(filename); + wxString input; + file.ReadAll(&input, conv); + return parse_string(input); + } + else + { + wxLogError(wxT("PGSCRIPT: File %s does not exist"), filename.c_str()); + return false; + } +} + +bool pgsDriver::parse_string(const wxString &input) +{ + std::istringstream iss(std::string(input.mb_str(wxConvUTF8))); + return parse_stream(iss); +} + +void pgsDriver::error(const class location &l, const wxString &m) +{ + std::ostringstream oss; + oss << l; + thread.last_error_line(l.begin.line); + thread.LockOutput(); + context.m_cout << PGSOUTERROR + << wx_static_cast(const wxString, wxString(oss.str() + .c_str(), wxConvUTF8)) << wxT(": ") << m << wxT("\n"); + thread.UnlockOutput(); +} + +} // namespace pgscript diff --git a/pgscript/utilities/pgsMapm.cpp b/pgscript/utilities/pgsMapm.cpp new file mode 100644 index 0000000..a0189bc --- /dev/null +++ b/pgscript/utilities/pgsMapm.cpp @@ -0,0 +1,76 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/utilities/pgsMapm.h" +#include +#include +#include + +#include +WX_DEFINE_OBJARRAY(pgsVectorMapm); + +wxString pgsMapm::pgs_mapm_str(const MAPM &m, const bool &as_int) +{ + if (m.is_integer() || as_int) + { + wxString str = pgs_mapm_str_fixed(m); + str = str.substr(0, str.find_last_of('.')); // Remove .0 at the end of an integer + return str; + } + else + { + return pgs_mapm_str_float(m); + } +} + +MAPM pgsMapm::pgs_mapm_round(const MAPM &m) +{ + return MAPM(pgs_mapm_str(m, true).mb_str()); +} + +wxString pgsMapm::pgs_mapm_str_fixed(const MAPM &m) +{ + char *const res = m.toFixPtStringExp(-1, '.', ' ', INT_MAX); + wxString str(res, wxConvUTF8); + free(res); + return str; +} + +wxString pgsMapm::pgs_mapm_str_float(const MAPM &m) +{ + int str_len = m.significant_digits(); + + { + wxStringOutputStream sos; + wxTextOutputStream tos(sos); + tos << abs(m.exponent()); + str_len += sos.GetString().Length(); + } + + { + wxStringOutputStream sos; + wxTextOutputStream tos(sos); + tos << str_len; + str_len = m.significant_digits() + 10 + sos.GetString().Length(); + } + + char *res = pnew char[str_len]; + m.toString(res, -1); + wxString result(res, wxConvUTF8); + pdeletea(res); + + return result; +} + +MAPM pgsMapm::pgs_str_mapm(const wxString &s) +{ + return std::string(s.mb_str()).c_str(); +} diff --git a/pgscript/utilities/pgsThread.cpp b/pgscript/utilities/pgsThread.cpp new file mode 100644 index 0000000..d79a4cc --- /dev/null +++ b/pgscript/utilities/pgsThread.cpp @@ -0,0 +1,94 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/utilities/pgsThread.h" + +#include "pgscript/pgsApplication.h" +#include "pgscript/statements/pgsProgram.h" +#include "pgscript/utilities/pgsContext.h" +#include "pgscript/utilities/pgsDriver.h" + +pgsThread::pgsThread(pgsVarMap &vars, wxSemaphore &mutex, + pgConn *connection, const wxString &file, pgsOutputStream &out, + pgsApplication &app, wxMBConv *conv) : + wxThread(wxTHREAD_DETACHED), m_vars(vars), m_mutex(mutex), + m_connection(connection), m_data(file), m_out(out), + m_app(app), m_conv(conv), m_last_error_line(-1) +{ + wxLogScript(wxT("Starting thread")); + m_mutex.Wait(); +} + +pgsThread::pgsThread(pgsVarMap &vars, wxSemaphore &mutex, + pgConn *connection, const wxString &string, pgsOutputStream &out, + pgsApplication &app) : + wxThread(wxTHREAD_DETACHED), m_vars(vars), m_mutex(mutex), + m_connection(connection), m_data(string), m_out(out), + m_app(app), m_conv(0), m_last_error_line(-1) +{ + wxLogScript(wxT("Starting thread")); + m_mutex.Wait(); +} + +pgsThread::~pgsThread() +{ + wxLogScript(wxT("Finishing thread")); + m_app.Complete(); + m_mutex.Post(); + wxLogScript(wxT("Thread finished")); +} + +void *pgsThread::Entry() +{ + pgsProgram program(m_vars); + pgsContext context(m_out); + pgscript::pgsDriver driver(context, program, *this); + + if (m_conv) + { + wxLogScript(wxT("Parsing file")); + driver.parse_file(m_data, *m_conv); + wxLogScript(wxT("File parsed")); + } + else + { + wxLogScript(wxT("Parsing string")); + driver.parse_string(m_data); + wxLogScript(wxT("String parsed")); + } + + return 0; +} + +pgConn *pgsThread::connection() +{ + return m_connection; +} + +void pgsThread::LockOutput() +{ + m_app.LockOutput(); +} + +void pgsThread::UnlockOutput() +{ + m_app.UnlockOutput(); +} + +void pgsThread::last_error_line(int line) +{ + m_last_error_line = line; +} + +int pgsThread::last_error_line() const +{ + return m_last_error_line; +} diff --git a/pgscript/utilities/pgsUtilities.cpp b/pgscript/utilities/pgsUtilities.cpp new file mode 100644 index 0000000..f765c46 --- /dev/null +++ b/pgscript/utilities/pgsUtilities.cpp @@ -0,0 +1,33 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/utilities/pgsUtilities.h" + +wxString pgsUtilities::uniform_line_returns(wxString s) +{ + s.Replace(wxT("\r\n"), wxT("\n")); + s.Replace(wxT("\r"), wxT("\n")); + return s; +} + +wxString pgsUtilities::escape_quotes(wxString s) +{ + s.Replace(wxT("\\"), wxT("\\\\")); + s.Replace(wxT("'"), wxT("''")); + return s; +} + +wxString pgsUtilities::unescape_quotes(wxString s) +{ + s.Replace(wxT("''"), wxT("'")); + s.Replace(wxT("\\'"), wxT("'")); + return s; +} diff --git a/schema/edbPackage.cpp b/schema/edbPackage.cpp new file mode 100644 index 0000000..1078430 --- /dev/null +++ b/schema/edbPackage.cpp @@ -0,0 +1,355 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// edbPackage.cpp - EnterpriseDB Package class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/edbPackage.h" +#include "schema/edbPackageFunction.h" +#include "schema/edbPackageVariable.h" + +edbPackage::edbPackage(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, packageFactory, newName) +{ +} + +wxString edbPackage::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on package"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing package"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop package \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop package \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop package cascaded?"); + break; + case DROPTITLE: + message = _("Drop package?"); + break; + case PROPERTIESREPORT: + message = _("Package properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Package properties"); + break; + case DDLREPORT: + message = _("Package DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Package DDL"); + break; + } + + return message; +} + + +bool edbPackage::IsUpToDate() +{ + pgConn *conn = GetDatabase()->GetConnection(); + if (!conn) + return false; + + wxString sql; + if(conn->EdbMinimumVersion(8, 2)) + sql = wxT("SELECT xmin FROM pg_namespace WHERE oid = ") + this->GetOidStr(); + else + sql = wxT("SELECT xmin FROM edb_package WHERE oid = ") + this->GetOidStr(); + + if (conn->ExecuteScalar(sql) != NumToStr(GetXid())) + return false; + else + return true; +} + +bool edbPackage::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP PACKAGE ") + GetQuotedFullIdentifier(); + + return GetDatabase()->ExecuteVoid(sql); +} + +wxString edbPackage::GetSql(ctlTree *browser) +{ + wxString qtName = GetQuotedFullIdentifier(); + + if (sql.IsNull()) + { + sql = wxT("-- Package: ") + qtName + wxT("\n\n") + wxT("-- DROP PACKAGE ") + qtName; + + sql += wxT(";\n\n"); + sql += wxT("CREATE OR REPLACE PACKAGE ") + qtName + wxT("\nIS\n"); + sql += GetHeaderInner(); + sql += wxT("\nEND ") + qtIdent(GetName()) + wxT(";\n\n"); + + if (!GetBodyInner().Trim().IsEmpty()) + { + sql += wxT("CREATE OR REPLACE PACKAGE BODY ") + qtName + wxT("\nIS\n"); + sql += GetBodyInner(); + sql += wxT("\nEND ") + qtIdent(GetName()) + wxT(";\n\n"); + } + + sql += GetGrant(wxT("X"), wxT("PACKAGE ") + qtName); + + sql += wxT("\n"); + } + + return sql; +} + +wxString edbPackage::GetHeaderInner() +{ + return GetInner(GetHeader()); +} + +wxString edbPackage::GetBodyInner() +{ + return GetInner(GetBody()); +} + +wxString edbPackage::GetInner(const wxString &def) +{ + long start = 0, end = 0; + + wxStringTokenizer tkz(def, wxT("\t\r\n ")); + + // Find the opening AS/IF keyword + while ( tkz.HasMoreTokens() ) + { + wxString token = tkz.GetNextToken(); + if (token.Lower() == wxT("as") || token.Lower() == wxT("is")) + { + start = tkz.GetPosition(); + break; + } + } + + // Find the closing END keyword + wxString tmp = def; + tmp.Replace(wxT("\n"), wxT(" ")); + tmp.Replace(wxT("\r"), wxT(" ")); + tmp.Replace(wxT("\t"), wxT(" ")); + + int e1 = tmp.Lower().rfind(wxT(" end;")); + int e2 = tmp.Lower().rfind(wxT(" end ")); + + end = (e1 > e2 ? e1 : e2); + + return def.Mid(start, end - start); +} + +void edbPackage::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + + // Log + wxLogInfo(wxT("Adding child object to package %s"), GetIdentifier().c_str()); + + browser->AppendCollection(this, packageFunctionFactory); + browser->AppendCollection(this, packageProcedureFactory); + browser->AppendCollection(this, packageVariableFactory); + } + + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Header"), firstLineOnly(GetHeader())); + properties->AppendItem(_("Body"), firstLineOnly(GetBody())); + properties->AppendItem(_("ACL"), GetAcl()); + properties->AppendYesNoItem(_("System package?"), GetSystemObject()); + if (GetConnection()->EdbMinimumVersion(8, 2)) + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *edbPackage::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *package = 0; + + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + { + if (coll->GetConnection()->EdbMinimumVersion(8, 2)) + package = packageFactory.CreateObjects(coll, 0, wxT(" AND nspname=") + qtDbString(GetName())); + else + package = packageFactory.CreateObjects(coll, 0, wxT(" AND pkgname=") + qtDbString(GetName())); + } + + return package; +} + + + +pgObject *edbPackageFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + edbPackage *package = 0; + + wxString sql, pkgsrc; + + wxString whereclause; + + if (collection->GetConnection()->EdbMinimumVersion(9, 0)) + pkgsrc = wxT("pg_catalog.edb_get_packagebodydef(nsp.oid) AS pkgbodysrc, ") + wxT("pg_catalog.edb_get_packageheaddef(nsp.oid) AS pkgheadsrc,\n"); + else if (collection->GetConnection()->EdbMinimumVersion(8, 2)) + pkgsrc = wxT("nspbodysrc AS pkgbodysrc, nspheadsrc AS pkgheadsrc,\n"); + + if (collection->GetConnection()->EdbMinimumVersion(8, 2)) + { + whereclause = wxT(" WHERE nspparent = ") + NumToStr(collection->GetSchema()->GetOid()) + wxT("::oid\n"); + if (collection->GetConnection()->EdbMinimumVersion(9, 2)) + whereclause += wxT(" AND nspobjecttype = 0 "); + + sql = wxT("SELECT nsp.oid, nsp.xmin, nspname AS pkgname,\n") + pkgsrc + + wxT(" nspacl AS pkgacl, pg_get_userbyid(nspowner) AS owner, description\n") + wxT(" FROM pg_namespace nsp") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=nsp.oid AND des.classoid='pg_namespace'::regclass)\n") + + whereclause + + restriction + + wxT(" ORDER BY nspname;"); + } + else + { + + sql = wxT("SELECT oid, xmin, *, pg_get_userbyid(pkgowner) AS owner\n") + wxT(" FROM edb_package") + wxT(" WHERE pkgnamespace = ") + NumToStr(collection->GetSchema()->GetOid()) + wxT("::oid\n") + + restriction + + wxT(" ORDER BY pkgname;"); + } + + pgSet *packages = collection->GetDatabase()->ExecuteSet(sql); + + if (packages) + { + while (!packages->Eof()) + { + wxString name = packages->GetVal(wxT("pkgname")); + package = new edbPackage(collection->GetSchema(), name); + + package->iSetOid(packages->GetOid(wxT("oid"))); + package->iSetXid(packages->GetOid(wxT("xmin"))); + package->iSetDatabase(collection->GetDatabase()); + package->iSetOwner(packages->GetVal(wxT("owner"))); + if (collection->GetConnection()->EdbMinimumVersion(8, 2)) + package->iSetComment(packages->GetVal(wxT("description"))); + + // EnterpriseDB's CVS code has some new parser code + // which is stricter about the formatting of body & + // header code and leaves off trailing ;'s + wxString tmp = packages->GetVal(wxT("pkgheadsrc")).Strip(wxString::both); + if (!tmp.EndsWith(wxT(";"))) + package->iSetHeader(tmp + wxT(";")); + else + package->iSetHeader(tmp); + + tmp = packages->GetVal(wxT("pkgbodysrc")).Strip(wxString::both); + if (!tmp.EndsWith(wxT(";")) && !tmp.IsEmpty()) + package->iSetBody(tmp + wxT(";")); + else + package->iSetBody(tmp); + + package->iSetAcl(packages->GetVal(wxT("pkgacl"))); + + if (browser) + { + browser->AppendObject(collection, package); + packages->MoveNext(); + } + else + break; + } + delete packages; + } + return package; +} + +///////////////////////////// + +edbPackageCollection::edbPackageCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + +wxString edbPackageCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on packages"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing packages"); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for packages"); + break; + case OBJECTSLISTREPORT: + message = _("Packages list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/package.pngc" +#include "images/packages.pngc" + +edbPackageFactory::edbPackageFactory() + : pgSchemaObjFactory(__("Package"), __("New Package..."), __("Create a new package."), package_png_img) +{ + metaType = EDB_PACKAGE; +} + + +pgCollection *edbPackageFactory::CreateCollection(pgObject *obj) +{ + return new edbPackageCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +edbPackageFactory packageFactory; +static pgaCollectionFactory cf(&packageFactory, __("Packages"), packages_png_img); diff --git a/schema/edbPackageFunction.cpp b/schema/edbPackageFunction.cpp new file mode 100644 index 0000000..4aff518 --- /dev/null +++ b/schema/edbPackageFunction.cpp @@ -0,0 +1,562 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// edbPackageFunction.cpp - EnterpriseDB Package member function +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/pgfeatures.h" +#include "schema/edbPackageFunction.h" + + +edbPackageFunction::edbPackageFunction(edbPackage *newPackage, const wxString &newName) + : edbPackageObject(newPackage, packageFunctionFactory, newName) +{ +} + +edbPackageFunction::edbPackageFunction(edbPackage *newPackage, pgaFactory &factory, const wxString &newName) + : edbPackageObject(newPackage, factory, newName) +{ +} + +edbPackageProcedure::edbPackageProcedure(edbPackage *newPackage, const wxString &newName) + : edbPackageFunction(newPackage, packageProcedureFactory, newName) +{ +} + +wxString edbPackageFunction::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on package function"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing package function"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop package function \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop package function \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop package function cascaded?"); + break; + case DROPTITLE: + message = _("Drop package function?"); + break; + case PROPERTIESREPORT: + message = _("Package function properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Package function properties"); + break; + case DDLREPORT: + message = _("Package function DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Package function DDL"); + break; + } + + return message; +} + + +wxString edbPackageFunction::GetFullName() +{ + return GetName() + wxT("(") + GetArgSigList() + wxT(")"); +} + +wxString edbPackageProcedure::GetFullName() +{ + if (GetArgSigList().IsEmpty()) + return GetName(); + else + return GetName() + wxT("(") + GetArgSigList() + wxT(")"); +} + +wxString edbPackageFunction::GetArgListWithNames() +{ + wxString args; + + for (unsigned int i = 0; i < argTypesArray.Count(); i++) + { + if (i > 0) + args += wxT(", "); + + wxString arg; + + if (GetIsProcedure()) + { + if (!argNamesArray.Item(i).IsEmpty()) + arg += qtIdent(argNamesArray.Item(i)); + + if (!argModesArray.Item(i).IsEmpty()) + { + if (arg.IsEmpty()) + arg += argModesArray.Item(i); + else + arg += wxT(" ") + argModesArray.Item(i); + } + } + else + { + if (!argModesArray.Item(i).IsEmpty()) + arg += argModesArray.Item(i); + + if (!argNamesArray.Item(i).IsEmpty()) + { + if (arg.IsEmpty()) + arg += qtIdent(argNamesArray.Item(i)); + else + arg += wxT(" ") + qtIdent(argNamesArray.Item(i)); + } + } + + if (!arg.IsEmpty()) + arg += wxT(" ") + argTypesArray.Item(i); + else + arg += argTypesArray.Item(i); + + // Parameter default value + if (GetConnection()->HasFeature(FEATURE_FUNCTION_DEFAULTS) && + !argDefsArray.IsEmpty()) + { + if ((argModesArray.Item(i).IsEmpty() || + argModesArray.Item(i) == wxT("IN") || + argModesArray.Item(i) == wxT("VARIADIC")) && + !argDefsArray.Item(i).IsEmpty() && + i < argDefsArray.Count()) + arg += wxT(" DEFAULT ") + argDefsArray.Item(i); + } + + args += arg; + } + return args; +} + +wxString edbPackageFunction::GetArgSigList() +{ + wxString args; + + for (unsigned int i = 0; i < argTypesArray.Count(); i++) + { + // OUT parameters are not considered part of the signature + if (argModesArray.Item(i) != wxT("OUT")) + { + if (i > 0) + args += wxT(", "); + + args += argTypesArray.Item(i); + } + } + return args; +} + +wxString edbPackageFunction::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Package Function: ") + GetName() + wxT("\n\n"); + sql += GetSource() + wxT("\n\n"); + } + + return sql; +} + +wxString edbPackageProcedure::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Package Procedure: ") + GetName() + wxT("\n\n"); + sql += GetSource() + wxT("\n\n"); + } + + return sql; +} + +void edbPackageFunction::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Argument count"), GetArgCount()); + properties->AppendItem(_("Arguments"), GetArgListWithNames()); + properties->AppendItem(_("Signature arguments"), GetArgSigList()); + if (!GetIsProcedure()) + properties->AppendItem(_("Return type"), GetReturnType()); + properties->AppendItem(_("Visibility"), GetVisibility()); + properties->AppendItem(_("Source"), firstLineOnly(GetSource())); + } +} + + + +pgObject *edbPackageFunction::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *packageFunction = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + { + if (coll->GetConnection()->EdbMinimumVersion(8, 2)) + packageFunction = packageFunctionFactory.CreateObjects(coll, 0, wxT("\n AND pronamespace=") + GetPackage()->GetOidStr() + wxT(" AND proname='") + GetName() + wxT("'")); + else + packageFunction = packageFunctionFactory.CreateObjects(coll, 0, wxT("\n AND packageoid=") + GetPackage()->GetOidStr() + wxT(" AND eltname='") + GetName() + wxT("'")); + } + + return packageFunction; +} + + +///////////////////////////// + +edbPackageFunctionCollection::edbPackageFunctionCollection(pgaFactory *factory, edbPackage *pkg) + : edbPackageObjCollection(factory, pkg) +{ +} + +wxString edbPackageFunctionCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on package functions"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing package functions"); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for package functions"); + break; + case OBJECTSLISTREPORT: + message = _("Package functions list report"); + break; + } + + return message; +} + +/////////////////////////////////////////////////// + +edbPackageFunction *edbPackageFunctionFactory::AppendFunctions(pgObject *obj, edbPackage *package, ctlTree *browser, const wxString &restriction) +{ + edbPackageFunction *packageFunction = 0; + pgSet *packageFunctions; + + // Caches + cacheMap typeCache, exprCache; + wxString sql, argDefsCol; + + if (obj->GetConnection()->HasFeature(FEATURE_FUNCTION_DEFAULTS)) + { + if (obj->GetConnection()->EdbMinimumVersion(8, 4)) + { + argDefsCol = wxT("pg_get_expr(proargdefaults, 'pg_catalog.pg_class'::regclass) AS argdefaults, pronargdefaults, "); + } + else + { + argDefsCol = wxT("proargdefvals AS argdefaults, COALESCE(substring(array_dims(proargdefvals), E'1:(.*)\\]')::integer, 0) AS pronargdefaults, "); + } + } + + if (obj->GetConnection()->EdbMinimumVersion(8, 2)) + { + sql = wxT("SELECT pg_proc.oid, proname AS eltname, prorettype AS eltdatatype, pronargs AS nargs, proaccess AS visibility,\n") + wxT(" proallargtypes AS allargtypes, proargtypes AS argtypes, proargnames AS argnames, proargmodes AS argmodes,") + argDefsCol + wxT("\n") + wxT(" CASE WHEN format_type(prorettype, NULL) = 'void' THEN 'P' ELSE 'F' END AS eltclass\n") + wxT(" FROM pg_proc, pg_namespace\n") + + restriction + wxT("\n") + wxT(" AND pg_proc.pronamespace = pg_namespace.oid\n") + wxT(" ORDER BY eltname"); + } + else + { + sql = wxT("SELECT oid, eltname, eltdatatype, eltclass, nargs, visibility,\n") + wxT(" allargtypes, argtypes, argnames, argmodes\n") + wxT(" FROM edb_pkgelements\n") + + restriction + wxT("\n") + wxT(" ORDER BY eltname"); + } + + packageFunctions = obj->GetDatabase()->ExecuteSet(sql); + + pgSet *types = obj->GetDatabase()->ExecuteSet(wxT( + "SELECT oid, format_type(oid, NULL) AS typname FROM pg_type")); + + while(!types->Eof()) + { + typeCache[types->GetVal(wxT("oid"))] = types->GetVal(wxT("typname")); + types->MoveNext(); + } + + if (packageFunctions) + { + while (!packageFunctions->Eof()) + { + size_t inModeCnt = 0; + size_t defaultArgsCnt = 0; + if (packageFunctions->GetVal(wxT("eltclass")) == wxT("F")) + packageFunction = new edbPackageFunction(package, packageFunctions->GetVal(wxT("eltname"))); + else + packageFunction = new edbPackageProcedure(package, packageFunctions->GetVal(wxT("eltname"))); + + // Tokenize the arguments + wxStringTokenizer argTypesTkz(wxEmptyString), argModesTkz(wxEmptyString); + queryTokenizer argNamesTkz(wxEmptyString, (wxChar)','); + wxArrayString argDefValArray; + wxString tmp; + + // Types + tmp = packageFunctions->GetVal(wxT("allargtypes")); + if (!tmp.IsEmpty()) + argTypesTkz.SetString(tmp.Mid(1, tmp.Length() - 2), wxT(",")); + else + { + tmp = packageFunctions->GetVal(wxT("argtypes")); + if (!tmp.IsEmpty()) + argTypesTkz.SetString(tmp); + } + + // Names + tmp = packageFunctions->GetVal(wxT("argnames")); + if (!tmp.IsEmpty()) + argNamesTkz.SetString(tmp.Mid(1, tmp.Length() - 2), wxT(",")); + + // Modes + tmp = packageFunctions->GetVal(wxT("argmodes")); + if (!tmp.IsEmpty()) + argModesTkz.SetString(tmp.Mid(1, tmp.Length() - 2), wxT(",")); + + // Function defaults + if (obj->GetConnection()->HasFeature(FEATURE_FUNCTION_DEFAULTS)) + { + defaultArgsCnt = packageFunctions->GetLong(wxT("pronargdefaults")); + + if (defaultArgsCnt > 0) + { + tmp = packageFunctions->GetVal(wxT("argdefaults")); + + if (!tmp.IsEmpty()) + { + getArrayFromCommaSeparatedList(tmp.Mid(1, tmp.Length() - 2), argDefValArray); + } + } + } + + // Now iterate the arguments and build the arrays + wxString type, name, mode; + + while (argTypesTkz.HasMoreTokens()) + { + // Add the arg type. This is a type oid, so + // look it up in the hashmap + type = argTypesTkz.GetNextToken(); + packageFunction->iAddArgType(typeCache[type]); + + // Now add the name, stripping the quotes if + // necessary. + name = argNamesTkz.GetNextToken(); + if (!name.IsEmpty()) + { + if (name[0] == '"') + name = name.Mid(1, name.Length() - 2); + packageFunction->iAddArgName(name); + } + else + packageFunction->iAddArgName(wxEmptyString); + + // Now the mode + mode = argModesTkz.GetNextToken(); + if (!mode.IsEmpty()) + { + if (mode == wxT('o') || mode == wxT("2")) + mode = wxT("OUT"); + else if (mode == wxT("b")) + if (packageFunctions->GetVal(wxT("eltclass")) == wxT("F")) + mode = wxT("IN OUT"); + else + mode = wxT("INOUT"); + else if (mode == wxT("3")) + mode = wxT("IN OUT"); + else if (mode == wxT("v")) + { + inModeCnt++; + mode = wxT("VARIADIC"); + } + else + { + inModeCnt++; + mode = wxT("IN"); + } + + packageFunction->iAddArgMode(mode); + } + else + packageFunction->iAddArgMode(wxEmptyString); + } + + // Finally the defaults, as we got them. + if (packageFunction->GetConnection()->HasFeature(FEATURE_FUNCTION_DEFAULTS)) + { + size_t currINindex = 0; + while (inModeCnt) + { + for (size_t index = 0; index < packageFunction->GetArgTypesArray().Count(); index++) + { + wxString def = wxEmptyString; + if(packageFunction->GetArgModesArray()[index].IsEmpty() || + packageFunction->GetArgModesArray()[index] == wxT("IN") || + packageFunction->GetArgModesArray()[index] == wxT("VARIADIC")) + { + if (!argDefValArray.IsEmpty() && inModeCnt <= argDefValArray.GetCount()) + { + def = argDefValArray[currINindex++]; + + if (!def.IsEmpty() && def != wxT("-")) + { + // Only EDB 8.3 does not support get the + // default value using pg_get_expr directly + if (!packageFunction->GetConnection()->BackendMinimumVersion(8, 4)) + { + // Check the cache first - if we don't + // have a value, get it and cache for + // next time + wxString val = exprCache[def]; + + if (val == wxEmptyString) + { + val = obj->GetDatabase()->ExecuteScalar( + wxT("SELECT pg_get_expr('") + def.Mid(1, def.Length() - 2) + wxT("', 'pg_catalog.pg_class'::regclass)")); + exprCache[def] = val; + } + def = val; + } + } + else + { + def = wxEmptyString; + } + } + inModeCnt--; + } + packageFunction->iAddArgDef(def); + } + } + } + + packageFunction->iSetOid(packageFunctions->GetOid(wxT("oid"))); + packageFunction->iSetArgCount(packageFunctions->GetOid(wxT("nargs"))); + packageFunction->iSetReturnType(typeCache[packageFunctions->GetVal(wxT("eltdatatype"))]); + + if (packageFunctions->GetVal(wxT("visibility")) == wxT("+")) + packageFunction->iSetVisibility(_("Public")); + else if (packageFunctions->GetVal(wxT("visibility")) == wxT("-")) + packageFunction->iSetVisibility(_("Private")); + else + packageFunction->iSetVisibility(_("Unknown")); + + packageFunction->iSetSource(package->GetBodyInner()); + + if (browser) + { + browser->AppendObject(obj, packageFunction); + packageFunctions->MoveNext(); + } + else + break; + } + + delete packageFunctions; + delete types; + } + return packageFunction; +} + +pgObject *edbPackageFunctionFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + wxString restr; + + if (collection->GetDatabase()->GetConnection()->EdbMinimumVersion(8, 2)) + restr = wxT(" WHERE format_type(prorettype, NULL) != 'void' AND pronamespace = "); + else + restr = wxT(" WHERE eltclass = 'F' AND packageoid = "); + + restr += ((edbPackageObjCollection *)collection)->GetPackage()->GetOidStr(); + restr += restriction; + + return AppendFunctions(collection, ((edbPackageObjCollection *)collection)->GetPackage(), browser, restr); +} + +pgObject *edbPackageProcedureFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + wxString restr; + + if (collection->GetDatabase()->GetConnection()->EdbMinimumVersion(8, 2)) + restr = wxT(" WHERE format_type(prorettype, NULL) = 'void' AND pronamespace = "); + else + restr = wxT(" WHERE eltclass = 'P' AND packageoid = "); + + restr += ((edbPackageObjCollection *)collection)->GetPackage()->GetOidStr(); + restr += restriction; + + return AppendFunctions(collection, ((edbPackageObjCollection *)collection)->GetPackage(), browser, restr); +} + +#include "images/function.pngc" +#include "images/functions.pngc" + +edbPackageFunctionFactory::edbPackageFunctionFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img) + : edbPackageObjFactory(tn, ns, nls, img) +{ + metaType = EDB_PACKAGEFUNCTION; +} + +pgCollection *edbPackageFunctionFactory::CreateCollection(pgObject *obj) +{ + return new edbPackageFunctionCollection(GetCollectionFactory(), (edbPackage *)obj); +} + +edbPackageFunctionFactory packageFunctionFactory(__("Function"), __("New Function..."), __("Create a new Function."), function_png_img); +static pgaCollectionFactory cff(&packageFunctionFactory, __("Functions"), functions_png_img); + +pgCollection *edbPackageObjFactory::CreateCollection(pgObject *obj) +{ + return new edbPackageObjCollection(GetCollectionFactory(), (edbPackage *)obj); +} + +#include "images/procedure.pngc" +#include "images/procedures.pngc" + +edbPackageProcedureFactory::edbPackageProcedureFactory() + : edbPackageFunctionFactory(__("Procedure"), __("New Procedure..."), __("Create a new Procedure."), procedure_png_img) +{ +} + +edbPackageProcedureFactory packageProcedureFactory; +static pgaCollectionFactory cfp(&packageProcedureFactory, __("Procedures"), procedures_png_img); + + diff --git a/schema/edbPackageVariable.cpp b/schema/edbPackageVariable.cpp new file mode 100644 index 0000000..b64bd92 --- /dev/null +++ b/schema/edbPackageVariable.cpp @@ -0,0 +1,227 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// edbPackageVariable.cpp - EnterpriseDB Package variable +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "schema/edbPackageVariable.h" + + +edbPackageVariable::edbPackageVariable(edbPackage *newPackage, const wxString &newName) + : edbPackageObject(newPackage, packageVariableFactory, newName) +{ +} + +wxString edbPackageVariable::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on package variable"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing package variable"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop package variable \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop package variable \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop package variable cascaded?"); + break; + case DROPTITLE: + message = _("Drop package variable?"); + break; + case PROPERTIESREPORT: + message = _("Package variable properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Package variable properties"); + break; + case DDLREPORT: + message = _("Package variable DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Package variable DDL"); + break; + } + + return message; +} + + +wxString edbPackageVariable::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Package Variable: ") + GetName() + wxT("\n\n"); + sql += GetName() + wxT(" ") + GetDataType() + wxT(";\n\n"); + } + + return sql; +} + +void edbPackageVariable::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Data type"), GetDataType()); + properties->AppendItem(_("Visibility"), GetVisibility()); + } +} + + + +pgObject *edbPackageVariable::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *packageVariable = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + { + if (coll->GetConnection()->EdbMinimumVersion(8, 2)) + packageVariable = packageVariableFactory.CreateObjects(coll, 0, wxT("\n AND varname='") + GetName() + wxT("'")); + else + packageVariable = packageVariableFactory.CreateObjects(coll, 0, wxT("\n AND eltname='") + GetName() + wxT("'")); + } + + return packageVariable; +} + + +/////////////////////////////////////////////////// + +pgObject *edbPackageVariableFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + + edbPackageVariable *packageVariable = 0; + + pgSet *packageVariables; + + wxString sql; + + if (collection->GetConnection()->EdbMinimumVersion(8, 2)) + { + sql = wxT("SELECT oid, varname AS eltname, varaccess AS visibility, format_type(vartype, NULL) as datatype FROM edb_variable\n") + wxT(" WHERE varpackage = ") + ((edbPackageObjCollection *)collection)->GetPackage()->GetOidStr() + wxT("\n") + + restriction + wxT("\n") + wxT(" ORDER BY varname"); + } + else + { + sql = wxT("SELECT oid, eltname, visibility, format_type(eltdatatype, NULL) as datatype FROM edb_pkgelements\n") + wxT(" WHERE eltclass = 'V'\n") + wxT(" AND packageoid = ") + ((edbPackageObjCollection *)collection)->GetPackage()->GetOidStr() + wxT("\n") + + restriction + wxT("\n") + wxT(" ORDER BY eltname"); + } + + packageVariables = collection->GetDatabase()->ExecuteSet(sql); + + if (packageVariables) + { + edbPackage *package = ((edbPackageObjCollection *)collection)->GetPackage(); + + while (!packageVariables->Eof()) + { + // Do not create edbPackageVariable, if package is wrapped + if (package->GetBody().Trim(false).StartsWith(wxT("$__EDBwrapped__$"))) + { + packageVariables->MoveNext(); + continue; + } + packageVariable = new edbPackageVariable(package, packageVariables->GetVal(wxT("eltname"))); + packageVariable->iSetOid(packageVariables->GetOid(wxT("oid"))); + packageVariable->iSetDataType(packageVariables->GetVal(wxT("datatype"))); + if (packageVariables->GetVal(wxT("visibility")) == wxT("+")) + packageVariable->iSetVisibility(_("Public")); + else if (packageVariables->GetVal(wxT("visibility")) == wxT("-")) + packageVariable->iSetVisibility(_("Private")); + else + packageVariable->iSetVisibility(_("Unknown")); + + if (browser) + { + browser->AppendObject(collection, packageVariable); + packageVariables->MoveNext(); + } + else + break; + } + + delete packageVariables; + } + return packageVariable; +} + +///////////////////////////// + +edbPackageVariableCollection::edbPackageVariableCollection(pgaFactory *factory, edbPackage *pkg) + : edbPackageObjCollection(factory, pkg) +{ +} + +wxString edbPackageVariableCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on package variables"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing package variables"); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for package variables"); + break; + case OBJECTSLISTREPORT: + message = _("Package variables list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/variable.pngc" +#include "images/variables.pngc" + +edbPackageVariableFactory::edbPackageVariableFactory() + : edbPackageObjFactory(__("Variable"), __("New Variable..."), __("Create a new Variable."), variable_png_img) +{ + metaType = EDB_PACKAGEVARIABLE; +} + +pgCollection *edbPackageVariableFactory::CreateCollection(pgObject *obj) +{ + return new edbPackageVariableCollection(GetCollectionFactory(), (edbPackage *)obj); +} + +edbPackageVariableFactory packageVariableFactory; +static pgaCollectionFactory cf(&packageVariableFactory, __("Variables"), variables_png_img); diff --git a/schema/edbPrivateSynonym.cpp b/schema/edbPrivateSynonym.cpp new file mode 100644 index 0000000..65d1404 --- /dev/null +++ b/schema/edbPrivateSynonym.cpp @@ -0,0 +1,227 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// edbPrivateSynonym.cpp - EnterpriseDB Private/Public Synonym class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/edbPrivateSynonym.h" + +edbPrivateSynonym::edbPrivateSynonym(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, edbPrivFactory, newName) +{ + isPublic = false; + if (newSchema && newSchema->GetName() == wxT("public")) + isPublic = true; +} + +bool edbPrivateSynonym::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql; + if (isPublic) + sql = wxT("DROP PUBLIC SYNONYM ") + GetQuotedIdentifier(); + else + sql = wxT("DROP SYNONYM ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + GetQuotedIdentifier(); + + return GetDatabase()->ExecuteVoid(sql); +} + +wxString edbPrivateSynonym::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop synonym \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPTITLE: + message = _("Drop synonym?"); + break; + } + + return message; +} + +wxString edbPrivateSynonym::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + if (isPublic) + sql = wxT("-- Public synonym: ") + GetQuotedIdentifier() + wxT("\n\n") + + wxT("-- DROP PUBLIC SYNONYM ") + GetQuotedIdentifier(); + else + sql = wxT("-- Private synonym: ") + GetSchema()->GetQuotedIdentifier() + wxT(".") + GetQuotedIdentifier() + wxT("\n\n") + + wxT("-- DROP SYNONYM ") + GetSchema()->GetQuotedIdentifier() + wxT(".") + GetQuotedIdentifier(); + + if (isPublic) + sql += wxT("\n\nCREATE OR REPLACE PUBLIC SYNONYM ") + GetQuotedIdentifier() + wxT(" FOR "); + else + sql += wxT("\n\nCREATE OR REPLACE SYNONYM ") + GetSchema()->GetQuotedIdentifier() + wxT(".") + GetQuotedIdentifier() + wxT(" FOR "); + + if (GetTargetSchema() != wxEmptyString) + sql += qtIdent(GetTargetSchema()) + wxT("."); + + sql += qtIdent(GetTargetObject()) + wxT(";\n"); + } + + return sql; +} + +void edbPrivateSynonym::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Public Synonym"), isPublic ? _("Yes") : _("No")); + properties->AppendItem(_("Name"), GetName()); + if (!isPublic) + properties->AppendItem(_("Schema"), GetSchema()->GetName()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Target type"), GetTargetType()); + properties->AppendItem(_("Target schema"), GetTargetSchema()); + properties->AppendItem(_("Target object"), GetTargetObject()); + properties->AppendYesNoItem(_("System synonym?"), GetSystemObject()); + } +} + + + +pgObject *edbPrivateSynonym::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *synonym = 0; + + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + synonym = edbPrivFactory.CreateObjects(coll, 0, wxT(" WHERE s.synname=") + qtDbString(GetName()) + + wxT(" AND s.synnamespace=") + coll->GetSchema()->GetOidStr() + wxT(" \n")); + + return synonym; +} + + + +pgObject *edbPrivateSynonymFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + edbPrivateSynonym *synonym = 0; + + wxString sql = wxT("SELECT *, pg_get_userbyid(synowner) AS owner,\n") + wxT(" COALESCE((SELECT relkind \n") + wxT(" FROM pg_class c, pg_namespace n\n") + wxT(" WHERE c.relnamespace = n.oid\n") + wxT(" AND n.nspname = synobjschema\n") + wxT(" AND c.relname = synobjname),\n") + wxT(" (SELECT CASE WHEN p.protype = '0' THEN 'f'::\"char\" ELSE 'p'::\"char\" END \n") + wxT(" FROM pg_proc p, pg_namespace n\n") + wxT(" WHERE p.pronamespace = n.oid\n") + wxT(" AND n.nspname = synobjschema\n") + wxT(" AND p.proname = synobjname LIMIT 1), '') AS targettype\n") + wxT(" FROM pg_synonym s") + wxT(" JOIN pg_namespace ns ON s.synnamespace = ns.oid AND ns.nspname = ") + + qtConnString(collection->GetSchema()->GetName()) + wxT(" \n") + + restriction + + wxT(" ORDER BY synname;"); + + pgSet *synonyms = collection->GetDatabase()->ExecuteSet(sql); + + if (synonyms) + { + while (!synonyms->Eof()) + { + wxString name = synonyms->GetVal(wxT("synname")); + synonym = new edbPrivateSynonym(collection->GetSchema(), name); + + synonym->iSetDatabase(collection->GetDatabase()); + synonym->iSetOwner(synonyms->GetVal(wxT("owner"))); + + if (synonyms->GetVal(wxT("targettype")) == wxT("r")) + synonym->iSetTargetType(_("Table")); + else if (synonyms->GetVal(wxT("targettype")) == wxT("S")) + synonym->iSetTargetType(_("Sequence")); + else if (synonyms->GetVal(wxT("targettype")) == wxT("v")) + synonym->iSetTargetType(_("View")); + else if (synonyms->GetVal(wxT("targettype")) == wxT("f")) + synonym->iSetTargetType(_("Function")); + else if (synonyms->GetVal(wxT("targettype")) == wxT("p")) + synonym->iSetTargetType(_("Procedure")); + else + synonym->iSetTargetType(_("Synonym")); + + synonym->iSetTargetSchema(synonyms->GetVal(wxT("synobjschema"))); + synonym->iSetTargetObject(synonyms->GetVal(wxT("synobjname"))); + + if (browser) + { + browser->AppendObject(collection, synonym); + synonyms->MoveNext(); + } + else + break; + } + delete synonyms; + } + return synonym; +} + +///////////////////////////// + +edbPrivateSynonymCollection::edbPrivateSynonymCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + +wxString edbPrivateSynonymCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on private synonyms"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing private synonyms"); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for private synonyms"); + break; + case OBJECTSLISTREPORT: + message = _("Private synonyms list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/synonym.pngc" +#include "images/synonyms.pngc" + +edbPrivateSynonymFactory::edbPrivateSynonymFactory() + : pgSchemaObjFactory(__("Synonym"), __("New Synonym..."), __("Create a new Synonym."), synonym_png_img) +{ + metaType = EDB_SYNONYM; +} + +pgCollection *edbPrivateSynonymFactory::CreateCollection(pgObject *obj) +{ + return new edbPrivateSynonymCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +edbPrivateSynonymFactory edbPrivFactory; + +static pgaCollectionFactory cf(&edbPrivFactory, __("Synonyms"), synonyms_png_img); + diff --git a/schema/edbResourceGroup.cpp b/schema/edbResourceGroup.cpp new file mode 100644 index 0000000..c28a789 --- /dev/null +++ b/schema/edbResourceGroup.cpp @@ -0,0 +1,205 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// edbResourceGroup.cpp - Resource Group (only used for PPAS 9.4) +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/edbResourceGroup.h" + +#include "images/resourcegroup.pngc" +#include "images/resourcegroups.pngc" + +edbResourceGroup::edbResourceGroup(const wxString &newName) + : pgServerObject(resourceGroupFactory, newName), cpuRateLimit(0), dirtyRateLimit(0) +{ +} + +edbResourceGroup::~edbResourceGroup() +{ +} + +wxString edbResourceGroup::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on resource group"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing resouce group"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop resource group \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop resource group \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop resource group cascaded?"); + break; + case DROPTITLE: + message = _("Drop resource group?"); + break; + case PROPERTIESREPORT: + message = _("Resource group properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Resource group properties"); + break; + case DDLREPORT: + message = _("Resource group DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Resource group DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Resource group dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Resource group dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Resource group dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Resource group dependents"); + break; + } + + return message; +} + +bool edbResourceGroup::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return server->ExecuteVoid(wxT("DROP RESOURCE GROUP ") + GetQuotedFullIdentifier()); +} + +wxString edbResourceGroup::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- RESOURCE GROUP: ") + GetName() + wxT("\n\n") + + wxT("-- DROP RESOURCE GROUP ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE RESOURCE GROUP ") + GetQuotedIdentifier() + wxT(";") + + wxT("\nALTER RESOURCE GROUP ") + GetQuotedIdentifier() + wxT(" SET cpu_rate_limit = ") + + wxString::Format(wxT("%f"), GetCPURateLimit()) + wxT(", dirty_rate_limit = ") + + wxString::Format(wxT("%f"), GetDirtyRateLimit()) + wxT(";"); + } + + return sql; +} + +void edbResourceGroup::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("CPU Rate Limit"), GetCPURateLimit()); + properties->AppendItem(_("Dirty Rate Limit"), GetDirtyRateLimit()); + } +} + +pgObject *edbResourceGroup::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *group = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + group = resourceGroupFactory.CreateObjects(coll, 0, wxT("\n WHERE oid=") + GetOidStr()); + + return group; +} + + +edbResourceGroupFactory::edbResourceGroupFactory() + : pgServerObjFactory(__("Resource Group"), __("New Resource Group..."), __("Create a new Resource Group."), resourcegroup_png_img) +{ +} + +pgObject *edbResourceGroupFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + edbResourceGroup *resGroup = 0; + double cpuLimit, dirtyLimit; + + pgSet *groups = collection->GetServer()->ExecuteSet(wxT("SELECT oid, * from edb_resource_group") + restriction); + + if (groups) + { + while (!groups->Eof()) + { + resGroup = new edbResourceGroup(groups->GetVal(wxT("rgrpname"))); + resGroup->iSetServer(collection->GetServer()); + resGroup->iSetOid(groups->GetOid(wxT("oid"))); + groups->GetVal(wxT("rgrpcpuratelimit")).ToDouble(&cpuLimit); + resGroup->iSetCPURateLimit(cpuLimit); + groups->GetVal(wxT("rgrpdirtyratelimit")).ToDouble(&dirtyLimit); + resGroup->iSetDirtyRateLimit(dirtyLimit); + + if (browser) + { + browser->AppendObject(collection, resGroup); + groups->MoveNext(); + } + else + break; + } + + delete groups; + } + return resGroup; +} + +pgCollection *edbResourceGroupFactory::CreateCollection(pgObject *obj) +{ + return new edbResourceGroupCollection(GetCollectionFactory(), (pgServer *)obj); +} + +edbResourceGroupFactory resourceGroupFactory; +static pgaCollectionFactory rgcf(&resourceGroupFactory, __("Resource Groups"), resourcegroups_png_img); + +edbResourceGroupCollection::edbResourceGroupCollection(pgaFactory *factory, pgServer *sv) + : pgServerObjCollection(factory, sv) +{ +} + +wxString edbResourceGroupCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on resource groups"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing resource groups"); + break; + case OBJECTSLISTREPORT: + message = _("Resource groups list report"); + break; + } + + return message; +} + diff --git a/schema/edbSynonym.cpp b/schema/edbSynonym.cpp new file mode 100644 index 0000000..4c60ce5 --- /dev/null +++ b/schema/edbSynonym.cpp @@ -0,0 +1,239 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// edbSynonym.cpp - EnterpriseDB Synonym class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/edbSynonym.h" + +edbSynonym::edbSynonym(const wxString &newName) + : pgDatabaseObject(synonymFactory, newName) +{ +} + +wxString edbSynonym::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on synonym"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing synonym"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop synonym \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop synonym \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop synonym cascaded?"); + break; + case DROPTITLE: + message = _("Drop synonym?"); + break; + case PROPERTIESREPORT: + message = _("Synonym properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Synonym properties"); + break; + case DDLREPORT: + message = _("Synonym DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Synonym DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Synonym dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Synonym dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Synonym dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Synonym dependents"); + break; + } + + return message; +} + +bool edbSynonym::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP PUBLIC SYNONYM ") + GetQuotedIdentifier(); + + return GetDatabase()->ExecuteVoid(sql); +} + +wxString edbSynonym::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Public synonym: ") + GetQuotedIdentifier() + wxT("\n\n") + wxT("-- DROP PUBLIC SYNONYM ") + GetQuotedIdentifier(); + + sql += wxT("\n\nCREATE OR REPLACE PUBLIC SYNONYM ") + GetQuotedIdentifier() + wxT(" FOR "); + + if (GetTargetSchema() != wxEmptyString) + sql += qtIdent(GetTargetSchema()) + wxT("."); + + sql += qtIdent(GetTargetObject()) + wxT(";\n"); + } + + return sql; +} + +void edbSynonym::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Target type"), GetTargetType()); + properties->AppendItem(_("Target schema"), GetTargetSchema()); + properties->AppendItem(_("Target object"), GetTargetObject()); + properties->AppendYesNoItem(_("System synonym?"), GetSystemObject()); + } +} + + + +pgObject *edbSynonym::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *synonym = 0; + + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + synonym = synonymFactory.CreateObjects(coll, 0, wxT(" WHERE synname=") + qtDbString(GetName())); + + return synonym; +} + + + +pgObject *edbSynonymFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + edbSynonym *synonym = 0; + + wxString sql = wxT("SELECT *, pg_get_userbyid(synowner) AS owner,\n") + wxT(" COALESCE((SELECT relkind \n") + wxT(" FROM pg_class c, pg_namespace n\n") + wxT(" WHERE c.relnamespace = n.oid\n") + wxT(" AND n.nspname = synobjschema\n") + wxT(" AND c.relname = synobjname), '') AS targettype\n") + wxT(" FROM pg_synonym") + + restriction + + wxT(" ORDER BY synname;"); + + pgSet *synonyms = collection->GetDatabase()->ExecuteSet(sql); + + if (synonyms) + { + while (!synonyms->Eof()) + { + wxString name = synonyms->GetVal(wxT("synname")); + synonym = new edbSynonym(name); + + synonym->iSetDatabase(collection->GetDatabase()); + synonym->iSetOwner(synonyms->GetVal(wxT("owner"))); + + if (synonyms->GetVal(wxT("targettype")) == wxT("r")) + synonym->iSetTargetType(_("Table")); + else if (synonyms->GetVal(wxT("targettype")) == wxT("S")) + synonym->iSetTargetType(_("Sequence")); + else if (synonyms->GetVal(wxT("targettype")) == wxT("v")) + synonym->iSetTargetType(_("View")); + else + synonym->iSetTargetType(_("Public synonym")); + + synonym->iSetTargetSchema(synonyms->GetVal(wxT("synobjschema"))); + synonym->iSetTargetObject(synonyms->GetVal(wxT("synobjname"))); + + if (browser) + { + browser->AppendObject(collection, synonym); + synonyms->MoveNext(); + } + else + break; + } + delete synonyms; + } + return synonym; +} + +///////////////////////////// + +edbSynonymCollection::edbSynonymCollection(pgaFactory *factory, pgDatabase *db) + : pgDatabaseObjCollection(factory, db) +{ +} + +wxString edbSynonymCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on synonyms"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing synonyms"); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for synonyms"); + break; + case OBJECTSLISTREPORT: + message = _("Synonyms list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/synonym.pngc" +#include "images/synonyms.pngc" + +edbSynonymFactory::edbSynonymFactory() + : pgDatabaseObjFactory(__("Public Synonym"), __("New Public Synonym..."), __("Create a new Public Synonym."), synonym_png_img) +{ +} + + +pgCollection *edbSynonymFactory::CreateCollection(pgObject *obj) +{ + return new edbSynonymCollection(GetCollectionFactory(), (pgDatabase *)obj); +} + +edbSynonymFactory synonymFactory; +static pgaCollectionFactory cf(&synonymFactory, __("Public Synonyms"), synonyms_png_img); diff --git a/schema/gpExtTable.cpp b/schema/gpExtTable.cpp new file mode 100644 index 0000000..048c45a --- /dev/null +++ b/schema/gpExtTable.cpp @@ -0,0 +1,575 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gpExtTable.cpp - Greenplum External Table +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgColumn.h" +#include "schema/gpExtTable.h" +#include "frm/frmHint.h" + + +gpExtTable::gpExtTable(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, extTableFactory, newName) +{ +} + +gpExtTable::~gpExtTable() +{ +} + +wxString gpExtTable::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on external table"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing external table"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop external table \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop external table \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop external table cascaded?"); + break; + case DROPTITLE: + message = _("Drop external table?"); + break; + case PROPERTIESREPORT: + message = _("External table properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("External table properties"); + break; + case DDLREPORT: + message = _("External table DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("External table DDL"); + break; + case DEPENDENCIESREPORT: + message = _("External table dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("External table dependencies"); + break; + case DEPENDENTSREPORT: + message = _("External table dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("External table dependents"); + break; + } + + return message; +} + +bool gpExtTable::IsUpToDate() +{ + wxString sql = wxT("SELECT xmin FROM pg_class WHERE oid = ") + this->GetOidStr(); + if (!this->GetDatabase()->GetConnection() || this->GetDatabase()->ExecuteScalar(sql) != NumToStr(GetXid())) + return false; + else + return true; +} + +wxMenu *gpExtTable::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + if (schema->GetCreatePrivilege()) + schemaFactory.AppendMenu(menu); + + return menu; +} + + +bool gpExtTable::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP EXTERNAL TABLE ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + +wxString gpExtTable::GetSql(ctlTree *browser) +{ + wxString colDetails; + wxString prevComment; + wxString q; + + if (sql.IsNull()) + { + sql = wxT("-- External Table: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP EXTERNAL TABLE ") + GetQuotedFullIdentifier() + wxT(";\n\n"); + /* Now get required information from pg_exttable */ + if (GetDatabase()->BackendMinimumVersion(8, 2, 5)) + { + q += wxT( + "SELECT x.location, x.fmttype, x.fmtopts, x.command, ") + wxT("x.rejectlimit, x.rejectlimittype,") + wxT("(SELECT relname ") + wxT("FROM pg_class ") + wxT("WHERE Oid=x.fmterrtbl) AS errtblname, ") + wxT("pg_catalog.pg_encoding_to_char(x.encoding) ") + wxT("FROM pg_catalog.pg_exttable x, pg_catalog.pg_class c ") + wxT("WHERE x.reloid = c.oid AND c.oid = ") + GetOidStr(); + } + else + { + /* not SREH and encoding colums yet */ + q += wxT( + "SELECT x.location, x.fmttype, x.fmtopts, x.command, ") + wxT("-1 as rejectlimit, null as rejectlimittype,") + wxT("null as errtblname, ") + wxT("null as encoding ") + wxT("FROM pg_catalog.pg_exttable x, pg_catalog.pg_class c ") + wxT("WHERE x.reloid = c.oid AND c.oid = ") + GetOidStr(); + + } + + pgSet *extTable = GetDatabase()->ExecuteSet(q); + + wxString locations = extTable->GetVal(0); + wxString fmttype = extTable->GetVal(1); + wxString fmtopts = extTable->GetVal(2); + wxString command = extTable->GetVal(3); + wxString rejlim = extTable->GetVal(4); + wxString rejlimtype = extTable->GetVal(5); + wxString errtblname = extTable->GetVal(6); + wxString extencoding = extTable->GetVal(7); + + delete extTable; + + if ((command.Length() > 0) || + (locations.Mid(1, 4) == wxT("http"))) + { + sql += wxT("CREATE EXTERNAL WEB TABLE ") + + GetQuotedFullIdentifier() + wxT("\n(\n"); + } + else + { + sql += wxT("CREATE EXTERNAL TABLE ") + + GetQuotedFullIdentifier() + wxT("\n(\n"); + } + + // Get the columns + pgCollection *columns = browser->FindCollection(columnFactory, GetId()); + if (columns) + { + columns->ShowTreeDetail(browser); + treeObjectIterator colIt1(browser, columns); + treeObjectIterator colIt2(browser, columns); + + + int lastRealCol = 0; + int currentCol = 0; + pgColumn *column; + + // Iterate the columns to find the last 'real' one + while ((column = (pgColumn *)colIt1.GetNextObject()) != 0) + { + currentCol++; + + if (column->GetInheritedCount() == 0) + lastRealCol = currentCol; + } + + // Now build the actual column list + int colCount = 0; + while ((column = (pgColumn *)colIt2.GetNextObject()) != 0) + { + column->ShowTreeDetail(browser); + if (column->GetColNumber() > 0) + { + if (colCount) + { + // Only add a comma if this isn't the last 'real' column + if (colCount != lastRealCol) + sql += wxT(","); + if (!prevComment.IsEmpty()) + sql += wxT(" -- ") + firstLineOnly(prevComment); + + sql += wxT("\n"); + } + + /* if (column->GetInheritedCount() > 0) + { + if (!column->GetIsLocal()) + sql += wxString::Format(wxT("-- %s "), _("Inherited")) + + wxT("from table ") + column->GetInheritedTableName() + wxT(":"); + }*/ + + sql += wxT(" ") + column->GetQuotedIdentifier() + wxT(" ") + + column->GetDefinition(); + + prevComment = column->GetComment(); + + // Whilst we are looping round the columns, grab their comments as well. + // Perhaps we should also get storage types here? + colDetails += column->GetCommentSql(); + if (colDetails.Length() > 0) + if (colDetails.Last() != '\n') colDetails += wxT("\n"); + + colCount++; + } + } + } + if (!prevComment.IsEmpty()) + sql += wxT(" -- ") + firstLineOnly(prevComment); + + sql += wxT("\n)\n"); + + if(command.Length() > 0) + { + + wxString on_clause = locations; + + /* remove curly braces */ + on_clause = locations.Mid(1, locations.Length() - 2); + + + /* add EXECUTE clause */ + sql += wxT(" EXECUTE E'"); + for (size_t i = 0; i < command.Length(); i++) + { + if (command[i] == wxT('\\')) sql += wxT('\\'); + if (command[i] == wxT('\'')) sql += wxT('\''); + sql += command[i]; + } + sql += wxT("' "); + + + /* add ON clause */ + wxString temp; + + if(on_clause.StartsWith(wxT("HOST:"), &temp)) + { + sql += wxT("ON HOST '") + temp + wxT("'"); + } + else if(on_clause.StartsWith(wxT("PER_HOST"), &temp)) + sql += wxT("ON HOST "); + else if(on_clause.StartsWith(wxT("MASTER_ONLY"), &temp)) + sql += wxT("ON MASTER "); + else if(on_clause.StartsWith(wxT("SEGMENT_ID:"), &temp)) + sql += wxT("ON SEGMENT ") + temp + wxT(" "); + else if(on_clause.StartsWith(wxT("TOTAL_SEGS:"), &temp)) + sql += wxT("ON ") + temp + wxT(" "); + else if(on_clause.StartsWith(wxT("ALL_SEGMENTS"), &temp)) + sql += wxT("ON ALL "); + else + sql += on_clause; + + sql += wxT("\n "); + + } + else + { + + /* add LOCATION clause */ + + locations = locations.Mid(1, locations.Length() - 2); + wxStringTokenizer locs(locations, wxT(",")); + wxString token; + token = locs.GetNextToken(); + sql += wxT(" LOCATION (\n '"); + sql += token; + sql += wxT("'"); + while (locs.HasMoreTokens()) + { + sql += wxT(",\n '"); + sql += locs.GetNextToken(); + sql += wxT("'"); + } + sql += wxT("\n)\n "); + + } + + /* add FORMAT clause */ + sql += wxT("FORMAT '"); + sql += fmttype[0] == 't' ? wxT("text") : wxT("csv"); + sql += wxT("'"); + sql += wxT(" ("); + for (size_t i = 0; i < fmtopts.Length(); i++) + { + if (fmtopts[i] == wxT('\\')) sql += wxT('\\'); + sql += fmtopts[i]; + } + sql += wxT(")\n"); + + if (GetDatabase()->BackendMinimumVersion(8, 2)) + { + /* add ENCODING clause */ + sql += wxT("ENCODING '"); + sql += extencoding ; + sql += wxT("'"); + + /* add Single Row Error Handling clause (if any) */ + if(rejlim.Length() > 0) + { + sql += wxT("\n"); + + /* + * NOTE: error tables get automatically generated if don't exist. + * therefore we must be sure that this statement will be dumped after + * the error relation CREATE is dumped, so that we won't try to + * create it twice. For now we rely on the fact that we pick dumpable + * objects sorted by OID, and error table oid *should* always be less + * than its external table oid (could that not be true sometimes?) + */ + if(errtblname.Length() > 0) + { + sql += wxT("LOG ERRORS INTO "); + sql += errtblname; + sql += wxT(" "); + } + + /* reject limit */ + sql += wxT("SEGMENT REJECT LIMIT "); + sql += rejlim; + + /* reject limit type */ + if(rejlimtype[0] == 'r') + sql += wxT(" ROWS"); + else + sql += wxT(" PERCENT"); + } + } + + sql += wxT(";\n") + + GetOwnerSql(7, 3, wxEmptyString, wxT("TABLE")); + + + sql += GetGrant(wxT("r"), wxT("TABLE ") + GetQuotedFullIdentifier()); + + sql += GetCommentSql() + + wxT("\n"); + + // Column/constraint comments + if (!colDetails.IsEmpty()) + sql += colDetails + wxT("\n"); + + } + return sql; +} + + +wxString gpExtTable::GetCols(ctlTree *browser, size_t indent, wxString &QMs, bool withQM) +{ + wxString sql; + wxString line; + + int colcount = 0; + pgSetIterator set(GetConnection(), + wxT("SELECT attname\n") + wxT(" FROM pg_attribute\n") + wxT(" WHERE attrelid=") + GetOidStr() + wxT(" AND attnum>0\n") + wxT(" ORDER BY attnum")); + + + while (set.RowsLeft()) + { + if (colcount++) + { + line += wxT(", "); + QMs += wxT(", "); + } + if (line.Length() > 60) + { + if (!sql.IsEmpty()) + { + sql += wxT("\n") + wxString(' ', indent); + } + sql += line; + line = wxEmptyString; + QMs += wxT("\n") + wxString(' ', indent); + } + + line += qtIdent(set.GetVal(0)); + if (withQM) + line += wxT("=?"); + QMs += wxT("?"); + } + + if (!line.IsEmpty()) + { + if (!sql.IsEmpty()) + sql += wxT("\n") + wxString(' ', indent); + sql += line; + } + return sql; +} + + +wxString gpExtTable::GetSelectSql(ctlTree *browser) +{ + wxString qms; + wxString sql = + wxT("SELECT ") + GetCols(browser, 7, qms, false) + wxT("\n") + wxT(" FROM ") + GetQuotedFullIdentifier() + wxT(";\n"); + return sql; +} + + +void gpExtTable::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + browser->RemoveDummyChild(this); + + browser->AppendCollection(this, columnFactory); + } + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("ACL"), GetAcl()); + properties->AppendYesNoItem(_("System Table?"), GetSystemObject()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *gpExtTable::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *extTable = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + { + extTable = extTableFactory.CreateObjects(coll, 0, wxT("\n AND c.oid=") + GetOidStr()); + } + + return extTable; +} + +void gpExtTable::ShowHint(frmMain *form, bool force) +{ + wxArrayString hints; + hints.Add(HINT_OBJECT_EDITING); + frmHint::ShowHint((wxWindow *)form, hints, GetFullIdentifier(), force); +} + +/////////////////////////////////////////////////////// + + +pgObject *gpExtTableFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + gpExtTable *extTable = 0; + + + pgSet *extTables = collection->GetDatabase()->ExecuteSet( + wxT("SELECT c.oid, c.xmin, c.relname, pg_get_userbyid(c.relowner) AS exttableowner, c.relacl AS relacl, description \n") + wxT(" FROM pg_class c\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=c.oid AND des.objsubid=0 AND des.classoid='pg_class'::regclass)\n") + wxT(" WHERE (c.relkind = 'x' OR (c.relkind = 'r' AND c.relstorage = 'x'))\n") + wxT(" AND relnamespace = ") + collection->GetSchema()->GetOidStr() + wxT("\n") + + restriction + + wxT(" ORDER BY relname")); + + if (extTables) + { + while (!extTables->Eof()) + { + extTable = new gpExtTable(collection->GetSchema(), extTables->GetVal(wxT("relname"))); + + extTable->iSetOid(extTables->GetOid(wxT("oid"))); + extTable->iSetXid(extTables->GetOid(wxT("xmin"))); + extTable->iSetOwner(extTables->GetVal(wxT("exttableowner"))); + extTable->iSetComment(extTables->GetVal(wxT("description"))); + extTable->iSetAcl(extTables->GetVal(wxT("relacl"))); + //extTable->iSetDefinition(extTables->GetVal(wxT("definition"))); + + if (browser) + { + collection->AppendBrowserItem(browser, extTable); + extTables->MoveNext(); + } + else + break; + } + + delete extTables; + } + return extTable; +} + +///////////////////////////// + +gpExtTableCollection::gpExtTableCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + +wxString gpExtTableCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on external tables"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing external tables"); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for external tables"); + break; + case OBJECTSLISTREPORT: + message = _("External tables list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/exttable.pngc" +#include "images/exttable-sm.pngc" +#include "images/exttables.pngc" + +gpExtTableFactory::gpExtTableFactory() + : pgSchemaObjFactory(__("External Table"), __("New External Table..."), __("Create a new External Table."), exttable_png_img, exttable_sm_png_img) +{ + metaType = GP_EXTTABLE; +} + + +pgCollection *gpExtTableFactory::CreateCollection(pgObject *obj) +{ + return new gpExtTableCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +gpExtTableFactory extTableFactory; +static pgaCollectionFactory cf(&extTableFactory, __("External Tables"), exttables_png_img); diff --git a/schema/gpPartition.cpp b/schema/gpPartition.cpp new file mode 100644 index 0000000..73b7a37 --- /dev/null +++ b/schema/gpPartition.cpp @@ -0,0 +1,238 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gpPartition.cpp - Greenplum Table Partition class +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + + +#include "utils/misc.h" +#include "frm/frmHint.h" +#include "frm/frmMain.h" +#include "frm/frmMaintenance.h" +#include "schema/pgTable.h" +#include "schema/gpPartition.h" +#include "schema/pgColumn.h" +#include "schema/pgIndexConstraint.h" +#include "schema/pgForeignKey.h" +#include "schema/pgCheck.h" +#include "utils/sysSettings.h" +#include "utils/pgfeatures.h" +#include "schema/pgRule.h" +#include "schema/pgTrigger.h" +#include "schema/pgConstraints.h" + + +// App headers + +gpPartition::gpPartition(pgSchema *newSchema, const wxString &newName) + : pgTable(newSchema, partitionFactory, newName) +{ +} + +gpPartition::~gpPartition() +{ +} + +bool gpPartition::CanCreate() +{ + return false; +} + +wxMenu *gpPartition::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + if (schema->GetCreatePrivilege()) + { + + } + return menu; +} +/* +wxString gpPartition::GetCreate() +{ + wxString sql; + + // sql = GetQuotedIdentifier() + wxT(" ") + // + GetTypeName().Upper() + GetDefinition(); + sql = wxT("Not implemented yet..sorry"); + return sql; +}; +*/ + +wxString gpPartition::GetSql(ctlTree *browser) +{ + wxString sql; + sql = wxT("-- "); + sql += _("Note: This DDL is a representation of how the partition might look as a table."); + sql += wxT("\n\n"); + + sql += pgTable::GetSql(browser); + return sql; +} + +pgObject *gpPartition::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + gpPartition *partition = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + partition = (gpPartition *)partitionFactory.CreateObjects(coll, 0, wxT("\n AND rel.oid=") + GetOidStr()); + + return partition; +} + +/////////////////////////////////////////////////////////// + +gpPartitionCollection::gpPartitionCollection(pgaFactory *factory, gpPartition *_table) + : pgTableCollection(factory, _table->GetSchema()) +{ + iSetOid(_table->GetOid()); +} + + +pgObject *gpPartitionFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restriction) +{ + gpPartitionCollection *collection = (gpPartitionCollection *)coll; + wxString query; + gpPartition *table = 0; + + // Greenplum returns reltuples and relpages as tuples per segmentDB and pages per segmentDB, + // so we need to multiply them by the number of segmentDBs to get reasonable values. + long gp_segments = 1; + + query = wxT("SELECT count(*) AS gp_segments from pg_catalog.gp_configuration where definedprimary = 't' and content >= 0"); + gp_segments = StrToLong(collection->GetDatabase()->ExecuteScalar(query)); + if (gp_segments <= 1) + gp_segments = 1; + + + pgSet *tables; + + query = wxT("SELECT rel.oid, relname, rel.reltablespace AS spcoid, spcname, pg_get_userbyid(relowner) AS relowner, relacl, relhasoids, ") + wxT("relhassubclass, reltuples, description, conname, conkey, parname, \n") + wxT(" EXISTS(select 1 FROM pg_trigger\n") + wxT(" JOIN pg_proc pt ON pt.oid=tgfoid AND pt.proname='logtrigger'\n") + wxT(" JOIN pg_proc pc ON pc.pronamespace=pt.pronamespace AND pc.proname='slonyversion'\n") + wxT(" WHERE tgrelid=rel.oid) AS isrepl\n"); + + query += wxT(", substring(array_to_string(reloptions, ',') from 'fillfactor=([0-9]*)') AS fillfactor \n"); + query += wxT(", gpd.localoid, gpd.attrnums \n"); + query += wxT(", substring(array_to_string(reloptions, ',') from 'appendonly=([a-z]*)') AS appendonly \n"); + query += wxT(", substring(array_to_string(reloptions, ',') from 'compresslevel=([0-9]*)') AS compresslevel \n"); + query += wxT(", substring(array_to_string(reloptions, ',') from 'orientation=([a-z]*)') AS orientation \n"); + query += wxT(", substring(array_to_string(reloptions, ',') from 'compresstype=([a-z0-9]*)') AS compresstype \n"); + query += wxT(", substring(array_to_string(reloptions, ',') from 'blocksize=([0-9]*)') AS blocksize \n"); + query += wxT(", substring(array_to_string(reloptions, ',') from 'checksum=([a-z]*)') AS checksum \n"); + //query += wxT(", rel.oid in (select parrelid from pg_partition) as ispartitioned\n"); // This only works for top-level tables, not intermediate ones + // This looks for intermediate partitions that have subpartitions + query += wxT(", rel.oid in (select pr.parchildrelid from pg_partition_rule pr, pg_partition pp where pr.paroid = pp.oid and pp.parlevel < (select max(parlevel) from pg_partition where parrelid = pp.parrelid)) as ispartitioned \n"); + + + query += wxT(" FROM pg_class rel JOIN pg_partition_rule pr ON(rel.oid = pr.parchildrelid) JOIN pg_partition p ON (pr.paroid = p.oid)\n") + wxT(" JOIN pg_inherits i ON (rel.oid = i.inhrelid) \n") + wxT(" LEFT OUTER JOIN pg_tablespace ta on ta.oid=rel.reltablespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=rel.oid AND des.objsubid=0 AND des.classoid='pg_class'::regclass)\n") + wxT(" LEFT OUTER JOIN pg_constraint c ON c.conrelid=rel.oid AND c.contype='p'\n"); + query += wxT(" LEFT OUTER JOIN gp_distribution_policy gpd ON gpd.localoid=rel.oid\n"); + query += wxT(" WHERE relkind = 'r' "); + query += wxT(" AND i.inhparent = ") + collection->GetOidStr() + wxT("\n"); + + query += restriction + + wxT(" ORDER BY relname"); + + + tables = collection->GetDatabase()->ExecuteSet(query); + if (tables) + { + while (!tables->Eof()) + { + table = new gpPartition(collection->GetSchema(), tables->GetVal(wxT("relname"))); + + table->iSetOid(tables->GetOid(wxT("oid"))); + table->iSetOwner(tables->GetVal(wxT("relowner"))); + table->iSetAcl(tables->GetVal(wxT("relacl"))); + + if (tables->GetOid(wxT("spcoid")) == 0) + table->iSetTablespaceOid(collection->GetDatabase()->GetTablespaceOid()); + else + table->iSetTablespaceOid(tables->GetOid(wxT("spcoid"))); + + if (tables->GetVal(wxT("spcname")) == wxEmptyString) + table->iSetTablespace(collection->GetDatabase()->GetTablespace()); + else + table->iSetTablespace(tables->GetVal(wxT("spcname"))); + + table->iSetComment(tables->GetVal(wxT("description"))); + table->iSetHasOids(tables->GetBool(wxT("relhasoids"))); + table->iSetEstimatedRows(tables->GetDouble(wxT("reltuples")) * gp_segments); + + table->iSetFillFactor(tables->GetVal(wxT("fillfactor"))); + + table->iSetHasSubclass(tables->GetBool(wxT("relhassubclass"))); + table->iSetPartitionName(tables->GetVal(wxT("parname"))); + table->iSetPrimaryKeyName(tables->GetVal(wxT("conname"))); + table->iSetIsReplicated(tables->GetBool(wxT("isrepl"))); + wxString cn = tables->GetVal(wxT("conkey")); + cn = cn.Mid(1, cn.Length() - 2); + table->iSetPrimaryKeyColNumbers(cn); + + + Oid lo = tables->GetOid(wxT("localoid")); + wxString db = tables->GetVal(wxT("attrnums")); + db = db.Mid(1, db.Length() - 2); + table->iSetDistributionColNumbers(db); + if (lo > 0 && db.Length() == 0) + table->iSetDistributionIsRandom(); + table->iSetAppendOnly(tables->GetVal(wxT("appendonly"))); + table->iSetCompressLevel(tables->GetVal(wxT("compresslevel"))); + table->iSetOrientation(tables->GetVal(wxT("orientation"))); + table->iSetCompressType(tables->GetVal(wxT("compresstype"))); + table->iSetBlocksize(tables->GetVal(wxT("blocksize"))); + table->iSetChecksum(tables->GetVal(wxT("checksum"))); + + table->iSetPartitionDef(wxT("")); + table->iSetIsPartitioned(tables->GetBool(wxT("ispartitioned"))); + + if (browser) + { + browser->AppendObject(collection, table); + tables->MoveNext(); + } + else + break; + } + + delete tables; + } + return table; +} + +void gpPartitionFactory::AppendMenu(wxMenu *menu) +{ +} + +#include "images/table.pngc" +#include "images/table-sm.pngc" +#include "images/tables.pngc" + +gpPartitionFactory::gpPartitionFactory() + : pgTableObjFactory(__("Partition"), __("New Partition..."), __("Create a new Partition."), table_png_img, table_sm_png_img) +{ + metaType = GP_PARTITION; +} + +pgCollection *gpPartitionFactory::CreateCollection(pgObject *obj) +{ + return new gpPartitionCollection(GetCollectionFactory(), (gpPartition *)obj ); +} + +gpPartitionFactory partitionFactory; +static pgaCollectionFactory cf(&partitionFactory, __("Partitions"), tables_png_img); + + diff --git a/schema/gpResQueue.cpp b/schema/gpResQueue.cpp new file mode 100644 index 0000000..70205ba --- /dev/null +++ b/schema/gpResQueue.cpp @@ -0,0 +1,302 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gpResQueue.cpp - Greenplum Resource Queue +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/gpResQueue.h" +#include "frm/frmMain.h" +#include "utils/pgDefs.h" +#include "schema/pgDatabase.h" + + +gpResQueue::gpResQueue(pgaFactory &factory, const wxString &newName) + : pgServerObject(factory, newName) +{ +} + +gpResQueue::gpResQueue(const wxString &newName) + : pgServerObject(resQueueFactory, newName) +{ +} + +wxString gpResQueue::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on resource queue"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing resource queue"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop resource queue \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop resource queue \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop resource queue cascaded?"); + break; + case DROPTITLE: + message = _("Drop resource queue?"); + break; + case PROPERTIESREPORT: + message = _("Resource queue properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Resource queue properties"); + break; + case DDLREPORT: + message = _("Resource queue DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Resource queue DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Resource queue dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Resource queue dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Resource queue dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Resource queue dependents"); + break; + } + + return message; +} + +int gpResQueue::GetIconId() +{ + return resQueueFactory.GetIconId(); +} + + + +bool gpResQueue::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return server->ExecuteVoid(wxT("DROP RESOURCE QUEUE ") + GetQuotedFullIdentifier() + wxT(";")); +} + + +wxString gpResQueue::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Resource Queue: \"") + GetName() + wxT("\"\n\n") + + wxT("-- DROP RESOURCE QUEUE ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE RESOURCE QUEUE ") + GetQuotedIdentifier(); + + if (GetCountLimit() != -1.0) + { + sql += wxT(" ACTIVE THRESHOLD "); + sql += NumToStr(GetCountLimit()); + } + if (GetCostLimit() != -1.0) + { + sql += wxT(" COST THRESHOLD "); + sql += NumToStr(GetCostLimit()); + } + if (GetIgnoreCostLimit() != 0.0) + { + sql += wxT(" IGNORE THRESHOLD "); + sql += NumToStr(GetIgnoreCostLimit()); + } + if (GetOvercommit()) + sql += wxT(" OVERCOMMIT"); + else + sql += wxT(" NOOVERCOMMIT"); + } + return sql; +} + + + + + + +void gpResQueue::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + wxString queuesquery; + + queuesquery = wxT("SELECT rolname,\n") + wxT(" pg_catalog.shobj_description(r.oid, 'pg_authid') AS description\n"); + + queuesquery += wxT(" FROM pg_roles r\n") + wxT(" JOIN pg_resqueue q ON rolresqueue=q.oid\n") + wxT(" WHERE rolresqueue=") + GetOidStr() + wxT("\n") + wxT(" ORDER BY rolname"); + + pgSetIterator queues(GetConnection(), queuesquery); + + while (queues.RowsLeft()) + { + wxString queue = queues.GetVal(wxT("rolname")); + + queuesIn.Add(queue); + } + } + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Active threshold"), GetCountLimit()); + properties->AppendItem(_("Cost threshold"), GetCostLimit()); + properties->AppendItem(_("Ignore threshold"), GetIgnoreCostLimit()); + properties->AppendItem(_("Over commit?"), BoolToYesNo(GetOvercommit())); + + wxString roleList; + + size_t index; + for (index = 0 ; index < queuesIn.GetCount() ; index++) + { + if (!roleList.IsEmpty()) + roleList += wxT(", "); + roleList += queuesIn.Item(index); + } + properties->AppendItem(_("Roles using this"), roleList); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + } +} + + + + +pgObject *gpResQueue::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *queue = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + queue = resQueueFactory.CreateObjects(coll, 0, wxT("\n WHERE oid=") + GetOidStr()); + + return queue; +} + + + +pgObject *gpResQueueFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + gpResQueue *queue = 0; + pgSet *queues = 0; + + + + queues = collection->GetServer()->ExecuteSet(wxT("SELECT rsqname, rsqcountlimit, rsqcostlimit, rsqovercommit, rsqignorecostlimit, oid FROM pg_resqueue ORDER BY 1")); + + if (queues) + { + while (!queues->Eof()) + { + queue = new gpResQueue(queues->GetVal(wxT("rsqname"))); + + queue->iSetServer(collection->GetServer()); + queue->iSetCountLimit(queues->GetDouble(wxT("rsqcountlimit"))); + queue->iSetCostLimit(queues->GetDouble(wxT("rsqcostlimit"))); + queue->iSetOvercommit(queues->GetBool(wxT("rsqovercommit"))); + queue->iSetIgnoreCostLimit(queues->GetDouble(wxT("rsqignorecostlimit"))); + queue->iSetOid(queues->GetOid(wxT("oid"))); + + if (browser) + { + browser->AppendObject(collection, queue); + queues->MoveNext(); + } + else + break; + } + + delete queues; + } + return queue; +} + +///////////////////////////// + +gpResQueueCollection::gpResQueueCollection(pgaFactory *factory, pgServer *sv) + : pgServerObjCollection(factory, sv) +{ +} + +wxString gpResQueueCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on resource queues"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing resource queues"); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for resource queues"); + break; + case OBJECTSLISTREPORT: + message = _("Ressource queues list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/group.pngc" +#include "images/roles.pngc" + + +gpResQueueFactory::gpResQueueFactory() + : pgServerObjFactory(__("Resource Queue"), __("New Resource Queue..."), __("Create a new Resource Queue."), group_png_img) +{ + metaType = GP_RESOURCE_QUEUE; +} + + +pgCollection *gpResQueueFactory::CreateCollection(pgObject *obj) +{ + return new gpResQueueCollection(GetCollectionFactory(), (pgServer *)obj); +} + +gpResQueueFactory resQueueFactory; +static pgaCollectionFactory lcf(&resQueueFactory, __("Resource Queues"), roles_png_img); + + +dlgProperty *gpResQueueFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return 0; +} + diff --git a/schema/module.mk b/schema/module.mk new file mode 100644 index 0000000..9ce59c5 --- /dev/null +++ b/schema/module.mk @@ -0,0 +1,68 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/schema Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + schema/edbPackage.cpp \ + schema/edbPackageFunction.cpp \ + schema/edbPackageVariable.cpp \ + schema/edbSynonym.cpp \ + schema/edbPrivateSynonym.cpp \ + schema/pgAggregate.cpp \ + schema/pgCast.cpp \ + schema/pgCatalogObject.cpp \ + schema/pgCheck.cpp \ + schema/pgCollation.cpp \ + schema/pgCollection.cpp \ + schema/pgColumn.cpp \ + schema/pgConstraints.cpp \ + schema/pgConversion.cpp \ + schema/pgDatabase.cpp \ + schema/pgDatatype.cpp \ + schema/pgDomain.cpp \ + schema/pgEventTrigger.cpp \ + schema/pgExtension.cpp \ + schema/pgForeignDataWrapper.cpp \ + schema/pgForeignKey.cpp \ + schema/pgForeignServer.cpp \ + schema/pgForeignTable.cpp \ + schema/pgFunction.cpp \ + schema/pgGroup.cpp \ + schema/pgIndex.cpp \ + schema/pgIndexConstraint.cpp \ + schema/pgLanguage.cpp \ + schema/pgObject.cpp \ + schema/pgOperator.cpp \ + schema/pgOperatorClass.cpp \ + schema/pgOperatorFamily.cpp \ + schema/pgRole.cpp \ + schema/pgRule.cpp \ + schema/pgSchema.cpp \ + schema/pgSequence.cpp \ + schema/pgServer.cpp \ + schema/pgTable.cpp \ + schema/pgTablespace.cpp \ + schema/pgTextSearchConfiguration.cpp \ + schema/pgTextSearchDictionary.cpp \ + schema/pgTextSearchParser.cpp \ + schema/pgTextSearchTemplate.cpp \ + schema/pgTrigger.cpp \ + schema/pgType.cpp \ + schema/pgUser.cpp \ + schema/pgUserMapping.cpp \ + schema/pgView.cpp \ + schema/gpExtTable.cpp \ + schema/gpResQueue.cpp \ + schema/gpPartition.cpp \ + schema/edbResourceGroup.cpp + +EXTRA_DIST += \ + schema/module.mk + diff --git a/schema/pgAggregate.cpp b/schema/pgAggregate.cpp new file mode 100644 index 0000000..7b790df --- /dev/null +++ b/schema/pgAggregate.cpp @@ -0,0 +1,410 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgAggregate.cpp - Aggregate class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgAggregate.h" + + +pgAggregate::pgAggregate(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, aggregateFactory, newName) +{ +} + +wxString pgAggregate::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on aggregate"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing aggregate"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop aggregate \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop aggregate \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop aggregate cascaded?"); + break; + case DROPTITLE: + message = _("Drop aggregate?"); + break; + case PROPERTIESREPORT: + message = _("Aggregate properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Aggregate properties"); + break; + case DDLREPORT: + message = _("Aggregate DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Aggregate DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Aggregate dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Aggregate dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Aggregate dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Aggregate dependents"); + break; + } + + return message; +} + +bool pgAggregate::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP AGGREGATE ") + GetSchema()->GetQuotedIdentifier() + wxT(".") + GetFullName(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + +wxString pgAggregate::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Aggregate: ") + GetQuotedFullName() + wxT("\n\n") + + wxT("-- DROP AGGREGATE ") + GetQuotedFullName() + wxT(";"); + + if (GetDatabase()->BackendMinimumVersion(8, 2)) + { + sql += wxT("\n\nCREATE AGGREGATE ") + GetQuotedFullName() + wxT(" ("); + } + else + { + sql += wxT("\n\nCREATE AGGREGATE ") + GetQuotedFullIdentifier() + + wxT("(\n BASETYPE=") + GetInputTypesList() + wxT(","); + } + + sql += wxT("\n SFUNC=") + GetStateFunction() + + wxT(",\n STYPE=") + GetStateType(); + + AppendIfFilled(sql, wxT(",\n FINALFUNC="), qtIdent(GetFinalFunction())); + + if (GetInitialCondition().length() > 0) + { + if (GetInitialCondition() == wxT("''")) + sql += wxT(",\n INITCOND=''"); + else if (GetInitialCondition() == wxT("\\'\\'")) + sql += wxT(",\n INITCOND=''''''"); + else + sql += wxT(",\n INITCOND=") + qtDbString(GetInitialCondition()); + } + + AppendIfFilled(sql, wxT(",\n SORTOP="), GetQuotedSortOp()); + + sql += wxT("\n);\n"); + sql += GetOwnerSql(8, 0, wxT("AGGREGATE ") + GetQuotedFullName()) + + GetGrant(wxT("X"), wxT("FUNCTION ") + GetQuotedFullIdentifier()); + + if (!GetComment().IsNull()) + { + sql += wxT("COMMENT ON AGGREGATE ") + GetQuotedFullName() + + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += GetSeqLabelsSql(); + } + + return sql; +} + +void pgAggregate::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("ACL"), GetAcl()); + properties->AppendItem(_("Input types"), GetInputTypesList()); + properties->AppendItem(_("State type"), GetStateType()); + properties->AppendItem(_("State function"), GetStateFunction()); + properties->AppendItem(_("Final type"), GetFinalType()); + properties->AppendItem(_("Final function"), GetFinalFunction()); + if (GetConnection()->BackendMinimumVersion(8, 1)) + properties->AppendItem(_("Sort operator"), GetSortOp()); + + if (GetInitialCondition() == wxT("")) + properties->AppendItem(_("Initial condition"), _("")); + else if (GetInitialCondition() == wxT("''")) + properties->AppendItem(_("Initial condition"), _("")); + else if (GetInitialCondition() == wxT("\\'\\'")) + properties->AppendItem(_("Initial condition"), _("''")); + else + properties->AppendItem(_("Initial condition"), GetInitialCondition()); + + properties->AppendYesNoItem(_("System aggregate?"), GetSystemObject()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + if (!GetLabels().IsEmpty()) + { + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); + } + } + } + } +} + +pgObject *pgAggregate::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *aggregate = 0; + + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + aggregate = aggregateFactory.CreateObjects(coll, 0, wxT("\n AND aggfnoid::oid=") + GetOidStr()); + + return aggregate; +} + +wxString pgAggregate::GetQuotedFullName() +{ + return GetQuotedFullIdentifier() + wxT("(") + GetInputTypesList() + wxT(")"); +} + +wxString pgAggregate::GetFullName() +{ + return GetName() + wxT("(") + GetInputTypesList() + wxT(")"); +} + +// Return the list of input types +wxString pgAggregate::GetInputTypesList() +{ + wxString types; + + for (unsigned int i = 0; i < inputTypes.Count(); i++) + { + if (i > 0) + types += wxT(", "); + + types += inputTypes.Item(i); + } + return types; +} + +pgObject *pgAggregateFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgAggregate *aggregate = 0; + + // Build a cache of data types + pgSet *types = collection->GetDatabase()->ExecuteSet(wxT( + "SELECT oid, format_type(oid, typtypmod) AS typname FROM pg_type")); + cacheMap map; + while(!types->Eof()) + { + map[types->GetVal(wxT("oid"))] = types->GetVal(wxT("typname")); + types->MoveNext(); + } + + delete types; + // Build the query to get all objects + wxString sql = + wxT("SELECT aggfnoid::oid, proname AS aggname, pg_get_userbyid(proowner) AS aggowner, aggtransfn,\n") + wxT( "aggfinalfn, proargtypes, aggtranstype, proacl, ") + wxT( "CASE WHEN (tt.typlen = -1 AND tt.typelem != 0) THEN (SELECT at.typname FROM pg_type at WHERE at.oid = tt.typelem) || '[]' ELSE tt.typname END as transname, ") + wxT( "prorettype AS aggfinaltype, ") + wxT( "CASE WHEN (tf.typlen = -1 AND tf.typelem != 0) THEN (SELECT at.typname FROM pg_type at WHERE at.oid = tf.typelem) || '[]' ELSE tf.typname END as finalname, ") + wxT( "agginitval, description"); + + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + sql += wxT(",\n(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=aggfnoid) AS labels"); + sql += wxT(",\n(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=aggfnoid) AS providers"); + } + + if (collection->GetDatabase()->BackendMinimumVersion(8, 1)) + { + sql += wxT(", oprname, opn.nspname as oprnsp\n") + wxT(" FROM pg_aggregate ag\n") + wxT(" LEFT OUTER JOIN pg_operator op ON op.oid=aggsortop\n") + wxT(" LEFT OUTER JOIN pg_namespace opn ON opn.oid=op.oprnamespace"); + } + else + sql += wxT("\n FROM pg_aggregate ag\n"); + + pgSet *aggregates = collection->GetDatabase()->ExecuteSet(sql + + wxT(" JOIN pg_proc pr ON pr.oid = ag.aggfnoid\n") + wxT(" JOIN pg_type tt on tt.oid=aggtranstype\n") + wxT(" JOIN pg_type tf on tf.oid=prorettype\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=aggfnoid::oid AND des.classoid='pg_aggregate'::regclass)\n") + wxT(" WHERE pronamespace = ") + collection->GetSchema()->GetOidStr() + + restriction + + wxT("\n ORDER BY aggname")); + + if (aggregates) + { + while (!aggregates->Eof()) + { + aggregate = new pgAggregate(collection->GetSchema(), aggregates->GetVal(wxT("aggname"))); + + aggregate->iSetOid(aggregates->GetOid(wxT("aggfnoid"))); + aggregate->iSetOwner(aggregates->GetVal(wxT("aggowner"))); + aggregate->iSetAcl(aggregates->GetVal(wxT("proacl"))); + + // Get the input type names. From 8.2 onwards there might be + // multiple types in the array. In any case, we must properly + // quote "any" + + // Tokenize the arguments + wxStringTokenizer argTypes(wxEmptyString); + + if (aggregates->GetVal(wxT("proargtypes")) == wxEmptyString) + { + if (collection->GetDatabase()->BackendMinimumVersion(8, 2)) + aggregate->iAddInputType(wxT("*")); + else + aggregate->iAddInputType(wxT("\"any\"")); + } + else + { + argTypes.SetString(aggregates->GetVal(wxT("proargtypes"))); + + while (argTypes.HasMoreTokens()) + { + // Add the arg type. This is a type oid, so + // look it up in the hashmap + wxString type = argTypes.GetNextToken(); + if (map[type] == wxT("any")) + aggregate->iAddInputType(wxT("\"any\"")); + else + aggregate->iAddInputType(qtTypeIdent(map[type])); + } + } + + aggregate->iSetStateType(aggregates->GetVal(wxT("transname"))); + aggregate->iSetStateFunction(aggregates->GetVal(wxT("aggtransfn"))); + aggregate->iSetFinalType(aggregates->GetVal(wxT("finalname"))); + + wxString final = aggregates->GetVal(wxT("aggfinalfn")); + if (final != wxT("-")) + aggregate->iSetFinalFunction(final); + + if (!aggregates->IsNull(aggregates->ColNumber(wxT("agginitval")))) + { + if (aggregates->GetVal(wxT("agginitval")).IsEmpty()) + aggregate->iSetInitialCondition(wxT("''")); + else if (aggregates->GetVal(wxT("agginitval")) == wxT("''")) + aggregate->iSetInitialCondition(wxT("\\'\\'")); + else + aggregate->iSetInitialCondition(aggregates->GetVal(wxT("agginitval"))); + } + + aggregate->iSetComment(aggregates->GetVal(wxT("description"))); + if (collection->GetDatabase()->BackendMinimumVersion(8, 1)) + { + wxString oprname = aggregates->GetVal(wxT("oprname")); + if (!oprname.IsEmpty()) + { + wxString oprnsp = aggregates->GetVal(wxT("oprnsp")); + aggregate->iSetSortOp(collection->GetDatabase()->GetSchemaPrefix(oprnsp) + oprname); + aggregate->iSetQuotedSortOp(collection->GetDatabase()->GetQuotedSchemaPrefix(oprnsp) + + qtIdent(oprname)); + } + } + + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + aggregate->iSetProviders(aggregates->GetVal(wxT("providers"))); + aggregate->iSetLabels(aggregates->GetVal(wxT("labels"))); + } + + if (browser) + { + browser->AppendObject(collection, aggregate); + aggregates->MoveNext(); + } + else + break; + } + + delete aggregates; + } + return aggregate; +} + +///////////////////////////// + +pgAggregateCollection::pgAggregateCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + +wxString pgAggregateCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on aggregates"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing aggregates"); + break; + case OBJECTSLISTREPORT: + message = _("Aggregates list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/aggregate.pngc" +#include "images/aggregate-sm.pngc" +#include "images/aggregates.pngc" + +pgAggregateFactory::pgAggregateFactory() + : pgSchemaObjFactory(__("Aggregate"), __("New Aggregate..."), __("Create a new Aggregate."), aggregate_png_img, aggregate_sm_png_img) +{ +} + +pgCollection *pgAggregateFactory::CreateCollection(pgObject *obj) +{ + return new pgAggregateCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgAggregateFactory aggregateFactory; +static pgaCollectionFactory cf(&aggregateFactory, __("Aggregates"), aggregates_png_img); diff --git a/schema/pgCast.cpp b/schema/pgCast.cpp new file mode 100644 index 0000000..f301027 --- /dev/null +++ b/schema/pgCast.cpp @@ -0,0 +1,268 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgCast.cpp - Cast class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgCast.h" + +pgCast::pgCast(const wxString &newName) + : pgDatabaseObject(castFactory, newName) +{ +} + +pgCast::~pgCast() +{ +} + + +wxString pgCast::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on cast"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing cast"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop cast \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop cast \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop cast cascaded?"); + break; + case DROPTITLE: + message = _("Drop cast?"); + break; + case PROPERTIESREPORT: + message = _("Cast properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Cast properties"); + break; + case DDLREPORT: + message = _("Cast DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Cast DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Cast dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Cast dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Cast dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Cast dependents"); + break; + } + + return message; +} + + +bool pgCast::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP CAST (") + GetSourceType() + wxT(" AS ") + GetTargetType() + wxT(")"); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + +wxString pgCast::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Cast: ") + GetQuotedFullIdentifier() + wxT("\n\n") + wxT("-- DROP CAST (") + GetSourceType() + + wxT(" AS ") + GetTargetType() + wxT(");") + wxT("\n\nCREATE CAST (") + GetSourceType() + + wxT(" AS ") + GetTargetType(); + if (GetCastFunction().IsNull()) + sql += wxT(")\n WITHOUT FUNCTION"); + else + sql += wxT(")\n WITH FUNCTION ") + GetQuotedSchemaPrefix(GetCastNamespace()) + qtIdent(GetCastFunction()) + wxT("(") + GetSourceType() + wxT(")"); + if (GetCastContext() != wxT("EXPLICIT")) + sql += wxT("\n AS ") + GetCastContext(); + sql += wxT(";\n"); + } + + return sql; +} + +void pgCast::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Source type"), GetSourceType()); + properties->AppendItem(_("Target type"), GetTargetType()); + if (GetCastFunction().IsNull()) + properties->AppendItem(_("Function"), _("(binary compatible)")); + else + properties->AppendItem(_("Function"), GetCastFunction() + wxT("(") + GetSourceType() + wxT(")")); + properties->AppendItem(_("Context"), GetCastContext()); + properties->AppendYesNoItem(_("System cast?"), GetSystemObject()); + if (GetConnection()->BackendMinimumVersion(7, 5)) + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgCast::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *cast = 0; + + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + cast = castFactory.CreateObjects(coll, 0, wxT(" WHERE ca.oid=") + GetOidStr()); + + return cast; +} + + + +pgObject *pgCastFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgCast *cast = 0; + wxString systemRestriction; + if (!settings->GetShowSystemObjects() && restriction.IsEmpty()) + systemRestriction = wxT(" WHERE ca.oid > ") + NumToStr(collection->GetConnection()->GetLastSystemOID()) + wxT("\n"); + + pgSet *casts = collection->GetDatabase()->ExecuteSet( + wxT("SELECT ca.oid, ca.*, format_type(st.oid,NULL) AS srctyp, format_type(tt.oid,tt.typtypmod) AS trgtyp,") + wxT( " ns.nspname AS srcnspname, nt.nspname AS trgnspname,\n") + wxT( " proname, np.nspname AS pronspname, description\n") + wxT(" FROM pg_cast ca\n") + wxT(" JOIN pg_type st ON st.oid=castsource\n") + wxT(" JOIN pg_namespace ns ON ns.oid=st.typnamespace\n") + wxT(" JOIN pg_type tt ON tt.oid=casttarget\n") + wxT(" JOIN pg_namespace nt ON nt.oid=tt.typnamespace\n") + wxT(" LEFT JOIN pg_proc pr ON pr.oid=castfunc\n") + wxT(" LEFT JOIN pg_namespace np ON np.oid=pr.pronamespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=ca.oid AND des.objsubid=0 AND des.classoid='pg_cast'::regclass)\n") + + restriction + systemRestriction + + wxT(" ORDER BY st.typname, tt.typname")); + + if (casts) + { + while (!casts->Eof()) + { + wxString name = casts->GetVal(wxT("srctyp")) + wxT("->") + casts->GetVal(wxT("trgtyp")); + cast = new pgCast(name); + + cast->iSetOid(casts->GetOid(wxT("oid"))); + cast->iSetDatabase(collection->GetDatabase()); + cast->iSetSourceType(casts->GetVal(wxT("srctyp"))); + cast->iSetSourceNamespace(casts->GetVal(wxT("srcnspname"))); + cast->iSetSourceTypeOid(casts->GetOid(wxT("castsource"))); + cast->iSetTargetType(casts->GetVal(wxT("trgtyp"))); + cast->iSetTargetNamespace(casts->GetVal(wxT("trgnspname"))); + cast->iSetTargetTypeOid(casts->GetOid(wxT("casttarget"))); + cast->iSetCastFunction(casts->GetVal(wxT("proname"))); + cast->iSetCastNamespace(casts->GetVal(wxT("pronspname"))); + cast->iSetComment(casts->GetVal(wxT("description"))); + wxString ct = casts->GetVal(wxT("castcontext")); + cast->iSetCastContext( + ct == wxT("i") ? wxT("IMPLICIT") : + ct == wxT("a") ? wxT("ASSIGNMENT") : wxT("EXPLICIT")); + + if (settings->GetShowSystemObjects() || + (cast->GetOid() > collection->GetServer()->GetLastSystemOID())) + { + if (browser) + { + browser->AppendObject(collection, cast); + casts->MoveNext(); + } + else + break; + } + else + break; + } + delete casts; + } + return cast; +} + + +///////////////////////////// + +pgCastCollection::pgCastCollection(pgaFactory *factory, pgDatabase *db) + : pgDatabaseObjCollection(factory, db) +{ +} + + +wxString pgCastCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on casts"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing casts"); + break; + case OBJECTSLISTREPORT: + message = _("Casts list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/cast.pngc" +#include "images/cast-sm.pngc" +#include "images/casts.pngc" + +pgCastFactory::pgCastFactory() + : pgDatabaseObjFactory(__("Cast"), __("New Cast..."), __("Create a new Cast."), cast_png_img, cast_sm_png_img) +{ +} + + +pgCollection *pgCastFactory::CreateCollection(pgObject *obj) +{ + return new pgCastCollection(GetCollectionFactory(), (pgDatabase *)obj); +} + +pgCastFactory castFactory; +static pgaCollectionFactory cf(&castFactory, __("Casts"), casts_png_img); diff --git a/schema/pgCatalogObject.cpp b/schema/pgCatalogObject.cpp new file mode 100644 index 0000000..68359f2 --- /dev/null +++ b/schema/pgCatalogObject.cpp @@ -0,0 +1,208 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgCatalogObject.cpp - EnterpriseDB catalog class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgCatalogObject.h" +#include "schema/pgColumn.h" + + +pgCatalogObject::pgCatalogObject(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, catalogObjectFactory, newName) +{ +} + +wxString pgCatalogObject::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on catalog object"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing catalog object"); + message += wxT(" ") + GetName(); + break; + case PROPERTIESREPORT: + message = _("Catalog object properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Catalog object properties"); + break; + case DEPENDENCIESREPORT: + message = _("Catalog object dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Catalog object dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Catalog object dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Catalog object dependents"); + break; + } + + return message; +} + + +wxString pgCatalogObject::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Catalog Object: ") + GetQuotedIdentifier() + wxT("\n"); + } + return sql; +} + + +void pgCatalogObject::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + browser->AppendCollection(this, columnFactory); + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Comment"), GetComment()); + } +} + + + +pgObject *pgCatalogObject::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *catalog = 0; + pgCollection *parent = (pgCollection *)browser->GetItemData(browser->GetItemParent(item)); + if (parent) + catalog = catalogObjectFactory.CreateObjects(parent, 0, wxT("\n AND c.oid=") + GetOidStr()); + + return catalog; +} + + + +pgObject *pgCatalogObjectFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgCatalogObject *catalog = 0; + + wxString qry = wxT("SELECT c.oid, c.relname, pg_get_userbyid(relowner) AS owner, description\n") + wxT(" FROM pg_class c\n") + wxT(" LEFT OUTER JOIN pg_description d ON (d.objoid=c.oid AND d.classoid='pg_class'::regclass)\n") + wxT(" WHERE relnamespace = ") + NumToStr(collection->GetSchema()->GetOid()) + wxT("::oid\n"); + + qry += restriction + + wxT(" ORDER BY relname"); + + pgSet *catalogs = collection->GetServer()->ExecuteSet(qry); + + if (catalogs) + { + while (!catalogs->Eof()) + { + // On EnterpriseDB we need to ignore some objects in the sys + // catalog, namely, _*, dual and type_object_source. + if (!settings->GetShowSystemObjects() && + collection->GetSchema()->GetName() == wxT("sys") && + (catalogs->GetVal(wxT("relname")).StartsWith(wxT("_")) || + catalogs->GetVal(wxT("relname")) == wxT("dual") || + catalogs->GetVal(wxT("relname")) == wxT("type_object_source"))) + { + catalogs->MoveNext(); + continue; + } + + catalog = new pgCatalogObject(collection->GetSchema(), catalogs->GetVal(wxT("relname"))); + catalog->iSetOid(catalogs->GetOid(wxT("oid"))); + catalog->iSetOwner(catalogs->GetVal(wxT("owner"))); + catalog->iSetComment(catalogs->GetVal(wxT("description"))); + + if (browser) + { + browser->AppendObject(collection, catalog); + catalogs->MoveNext(); + } + else + break; + } + + delete catalogs; + } + return catalog; +} + +///////////////////////////// + +pgCatalogObjectCollection::pgCatalogObjectCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgCatalogObjectCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on catalog objects"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing catalog objects"); + break; + case OBJECTSLISTREPORT: + message = _("Catalog objects list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/catalogobject.pngc" +#include "images/catalogobject-sm.pngc" +#include "images/catalogobjects.pngc" + +pgCatalogObjectFactory::pgCatalogObjectFactory() + : pgSchemaObjFactory(__("Catalog Object"), __("New Catalog Object..."), __("Create a new Catalog Object."), catalogobject_png_img, catalogobject_sm_png_img) +{ + metaType = PGM_CATALOGOBJECT; +} + + +pgCollection *pgCatalogObjectFactory::CreateCollection(pgObject *obj) +{ + return new pgCatalogObjectCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgCatalogObjectFactory catalogObjectFactory; +static pgaCollectionFactory cf(&catalogObjectFactory, __("Catalog Objects"), catalogobjects_png_img); diff --git a/schema/pgCheck.cpp b/schema/pgCheck.cpp new file mode 100644 index 0000000..1002e5e --- /dev/null +++ b/schema/pgCheck.cpp @@ -0,0 +1,333 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgCheck.cpp - Check class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "frm/frmMain.h" +#include "utils/misc.h" +#include "schema/pgCheck.h" + + +pgCheck::pgCheck(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, checkFactory, newName) +{ +} + +pgCheck::~pgCheck() +{ +} + + +wxString pgCheck::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on check constraint"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing check constraint"); + message += wxT(" ") + GetName(); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for check constraint"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop check constraint \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop check constraint \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop check constraint cascaded?"); + break; + case DROPTITLE: + message = _("Drop check constraint?"); + break; + case PROPERTIESREPORT: + message = _("Check constraint properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Check constraint properties"); + break; + case DDLREPORT: + message = _("Check constraint DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Check constraint DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Check constraint dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Check constraint dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Check constraint dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Check constraint dependents"); + break; + } + + return message; +} + + +int pgCheck::GetIconId() +{ + if (!GetDatabase()->BackendMinimumVersion(9, 2) || GetValid()) + return checkFactory.GetIconId(); + else + return checkFactory.GetClosedIconId(); +} + + +bool pgCheck::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("ALTER ") + objectKind + wxT(" ") + qtIdent(objectSchema) + wxT(".") + qtIdent(objectName) + + wxT(" DROP CONSTRAINT ") + GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgCheck::GetConstraint() +{ + sql = GetQuotedIdentifier() + wxT(" CHECK "); + + sql += wxT("(") + GetDefinition() + wxT(")"); + + if (GetDatabase()->BackendMinimumVersion(9, 2) && GetNoInherit()) + sql += wxT(" NO INHERIT"); + + if (GetDatabase()->BackendMinimumVersion(9, 2) && !GetValid()) + sql += wxT(" NOT VALID"); + + return sql; +} + + +wxString pgCheck::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Check: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- ALTER ") + objectKind + wxT(" ") + GetQuotedSchemaPrefix(objectSchema) + qtIdent(objectName) + + wxT(" DROP CONSTRAINT ") + GetQuotedIdentifier() + + wxT(";\n\nALTER ") + objectKind + wxT(" ") + GetQuotedSchemaPrefix(objectSchema) + qtIdent(objectName) + + wxT("\n ADD CONSTRAINT ") + GetConstraint() + + wxT(";\n"); + + if (!GetComment().IsNull()) + { + sql += wxT("COMMENT ON CONSTRAINT ") + GetQuotedIdentifier() + + wxT(" ON ") + GetQuotedSchemaPrefix(objectSchema) + qtIdent(objectName) + + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + } + + return sql; +} + + +void pgCheck::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Definition"), GetDefinition()); + if (GetDatabase()->BackendMinimumVersion(9, 2)) + { + properties->AppendItem(_("No Inherit?"), BoolToYesNo(GetNoInherit())); + properties->AppendItem(_("Valid?"), BoolToYesNo(GetValid())); + } + // Check constraints on a domain don't have comments + if (objectKind.Upper() == wxT("TABLE")) + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + +pgObject *pgCheck::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *check = 0; + + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + check = checkFactory.CreateObjects(coll, 0, wxT("\n AND c.oid=") + GetOidStr()); + + return check; +} + + +void pgCheck::Validate(frmMain *form) +{ + wxString sql = wxT("ALTER ") + objectKind + wxT(" ") + + GetQuotedSchemaPrefix(objectSchema) + qtIdent(objectName) + + wxT("\n VALIDATE CONSTRAINT ") + GetQuotedIdentifier(); + GetDatabase()->ExecuteVoid(sql); + + iSetValid(true); + UpdateIcon(form->GetBrowser()); +} + + +pgObject *pgCheckFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restriction) +{ + pgSchemaObjCollection *collection = (pgSchemaObjCollection *)coll; + pgCheck *check = 0; + + wxString connoinherit = collection->GetDatabase()->BackendMinimumVersion(9, 2) ? wxT(", connoinherit") : wxEmptyString; + wxString convalidated = collection->GetDatabase()->BackendMinimumVersion(9, 2) ? wxT(", convalidated") : wxEmptyString; + + wxString sql = + wxT("SELECT 'TABLE' AS objectkind, c.oid, conname, relname, nspname, description,\n") + wxT(" pg_get_expr(conbin, conrelid") + collection->GetDatabase()->GetPrettyOption() + wxT(") as consrc\n") + + connoinherit + convalidated + + wxT(" FROM pg_constraint c\n") + wxT(" JOIN pg_class cl ON cl.oid=conrelid\n") + wxT(" JOIN pg_namespace nl ON nl.oid=relnamespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=c.oid AND des.classoid='pg_constraint'::regclass)\n") + wxT(" WHERE contype = 'c' AND conrelid = ") + NumToStr(collection->GetOid()) + + restriction + wxT("::oid\n") + wxT("UNION\n") + wxT("SELECT 'DOMAIN' AS objectkind, c.oid, conname, typname as relname, nspname, description,\n") + wxT(" regexp_replace(pg_get_constraintdef(c.oid, true), E'CHECK \\\\((.*)\\\\).*', E'\\\\1') as consrc\n") + + connoinherit + convalidated + + wxT(" FROM pg_constraint c\n") + wxT(" JOIN pg_type t ON t.oid=contypid\n") + wxT(" JOIN pg_namespace nl ON nl.oid=typnamespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=t.oid AND des.classoid='pg_constraint'::regclass)\n") + wxT(" WHERE contype = 'c' AND contypid = ") + NumToStr(collection->GetOid()) + + restriction + wxT("::oid\n") + wxT(" ORDER BY conname"); + + pgSet *checks = collection->GetDatabase()->ExecuteSet(sql); + + if (checks) + { + while (!checks->Eof()) + { + check = new pgCheck(collection->GetSchema()->GetSchema(), checks->GetVal(wxT("conname"))); + + check->iSetOid(checks->GetOid(wxT("oid"))); + check->iSetDefinition(checks->GetVal(wxT("consrc"))); + check->iSetObjectKind(checks->GetVal(wxT("objectkind"))); + check->iSetObjectName(checks->GetVal(wxT("relname"))); + check->iSetObjectSchema(checks->GetVal(wxT("nspname"))); + if (collection->GetDatabase()->BackendMinimumVersion(9, 2)) + { + check->iSetNoInherit(checks->GetBool(wxT("connoinherit"))); + check->iSetValid(checks->GetBool(wxT("convalidated"))); + } + check->iSetComment(checks->GetVal(wxT("description"))); + + if (browser) + { + browser->AppendObject(collection, check); + checks->MoveNext(); + } + else + break; + } + + delete checks; + } + return check; +} + +///////////////////////////// + +wxString pgCheckCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on check constraints"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing check constraints"); + break; + case OBJECTSLISTREPORT: + message = _("Check constraints list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/check.pngc" +#include "images/checkbad.pngc" + +pgCheckFactory::pgCheckFactory() + : pgSchemaObjFactory(__("Check"), __("New Check..."), __("Create a new Check constraint."), check_png_img) +{ + metaType = PGM_CHECK; + collectionFactory = &constraintCollectionFactory; + closedId = addIcon(checkbad_png_img); +} + + +pgCheckFactory checkFactory; + +validateCheckFactory::validateCheckFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Validate check constraint"), _("Validate the selected check constraint.")); +} + + +wxWindow *validateCheckFactory::StartDialog(frmMain *form, pgObject *obj) +{ + ((pgCheck *)obj)->Validate(form); + ((pgCheck *)obj)->SetDirty(); + + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + { + obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties()); + form->GetSqlPane()->SetReadOnly(false); + form->GetSqlPane()->SetText(((pgCheck *)obj)->GetSql(form->GetBrowser())); + form->GetSqlPane()->SetReadOnly(true); + } + form->GetMenuFactories()->CheckMenu(obj, form->GetMenuBar(), (ctlMenuToolbar *)form->GetToolBar()); + + return 0; +} + + +bool validateCheckFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(checkFactory) && obj->CanEdit() + && ((pgCheck *)obj)->GetConnection()->BackendMinimumVersion(9, 2) + && !((pgCheck *)obj)->GetValid(); +} diff --git a/schema/pgCollation.cpp b/schema/pgCollation.cpp new file mode 100644 index 0000000..35b4bb1 --- /dev/null +++ b/schema/pgCollation.cpp @@ -0,0 +1,249 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgCollation.cpp - Collation class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgCollation.h" +#include "schema/pgDatatype.h" + + +/* +dlgProperty *pgCollationFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return 0L; +} +*/ + + +pgCollation::pgCollation(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, collationFactory, newName) +{ +} + +pgCollation::~pgCollation() +{ +} + +wxString pgCollation::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on collation"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing collation"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop collation \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop collation \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop collation cascaded?"); + break; + case DROPTITLE: + message = _("Drop collation?"); + break; + case PROPERTIESREPORT: + message = _("Collation properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Collation properties"); + break; + case DDLREPORT: + message = _("Collation DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Collation DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Collation dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Collation dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Collation dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Collation dependents"); + break; + } + + return message; +} + + +bool pgCollation::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP COLLATION ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + +wxString pgCollation::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Collation: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP COLLATION ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE COLLATION ") + GetQuotedFullIdentifier() + + wxT("\n (LC_COLLATE=") + qtDbString(GetLcCollate()) + + wxT(", LC_CTYPE=") + qtDbString(GetLcCtype()) + + wxT(");\n"); + + sql += GetOwnerSql(9, 1) + + GetCommentSql(); + } + + return sql; +} + + +void pgCollation::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("LC_COLLATE"), GetLcCollate()); + properties->AppendItem(_("LC_CTYPE"), GetLcCtype()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgCollation::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *collation = 0; + + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + collation = collationFactory.CreateObjects(coll, 0, wxT(" AND c.oid=") + GetOidStr() + wxT("\n")); + + return collation; +} + + +//////////////////////////////////////////////////// + + + +pgObject *pgCollationFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgCollation *collation = 0; + + pgDatabase *db = collection->GetDatabase(); + + pgSet *collations = db->ExecuteSet( + wxT("SELECT c.oid, c.collname, c.collcollate, c.collctype, \n") + wxT(" pg_get_userbyid(c.collowner) as cowner, description\n") + wxT(" FROM pg_collation c\n") + wxT(" JOIN pg_namespace n ON n.oid=c.collnamespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=c.oid AND des.classoid='pg_collation'::regclass)\n") + wxT(" WHERE c.collnamespace = ") + NumToStr(collection->GetSchema()->GetOid()) + wxT("::oid\n") + + restriction + + wxT(" ORDER BY c.collname")); + + if (collations) + { + while (!collations->Eof()) + { + collation = new pgCollation(collection->GetSchema(), collations->GetVal(wxT("collname"))); + + collation->iSetOid(collations->GetOid(wxT("oid"))); + collation->iSetOwner(collations->GetVal(wxT("cowner"))); + collation->iSetLcCollate(collations->GetVal(wxT("collcollate"))); + collation->iSetLcCtype(collations->GetVal(wxT("collctype"))); + collation->iSetComment(collations->GetVal(wxT("description"))); + + if (browser) + { + browser->AppendObject(collection, collation); + collations->MoveNext(); + } + else + break; + } + + delete collations; + } + return collation; +} + +///////////////////////////// + +pgCollationCollection::pgCollationCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgCollationCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on collations"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing collations"); + break; + case OBJECTSLISTREPORT: + message = _("Collations list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/collation.pngc" +#include "images/collation-sm.pngc" +#include "images/collations.pngc" + +pgCollationFactory::pgCollationFactory() + : pgSchemaObjFactory(__("Collation"), __("New Collation..."), __("Create a new Collation."), collation_png_img, collation_sm_png_img) +{ +} + + +pgCollection *pgCollationFactory::CreateCollection(pgObject *obj) +{ + return new pgCollationCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgCollationFactory collationFactory; +static pgaCollectionFactory cf(&collationFactory, __("Collations"), collations_png_img); diff --git a/schema/pgCollection.cpp b/schema/pgCollection.cpp new file mode 100644 index 0000000..584c1bb --- /dev/null +++ b/schema/pgCollection.cpp @@ -0,0 +1,147 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgCollection.cpp - Simple object for use with 'collection' nodes +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "frm/menu.h" +#include "utils/misc.h" +#include "agent/pgaJob.h" +#include "schema/pgSchema.h" +#include "schema/pgTable.h" +#include "frm/frmMain.h" +#include "frm/frmReport.h" + +pgCollection::pgCollection(pgaFactory *factory) + : pgObject(*factory) +{ + um = 0; + fsrv = 0; + fdw = 0; + job = 0; + schema = 0; + database = 0; + server = 0; +} + +bool pgCollection::IsCollectionFor(pgObject *obj) +{ + if (!obj) + return false; + pgaFactory *f = obj->GetFactory(); + if (!f) + return false; + return GetFactory() == f->GetCollectionFactory(); +} + + +bool pgCollection::IsCollectionForType(const int type) +{ + if (GetFactory()) + { + pgaFactory *f = pgaFactory::GetFactoryByMetaType(type); + return (f && f->GetCollectionFactory() == GetFactory()); + } + return false; +} + + +void pgCollection::ShowList(ctlTree *browser, ctlListView *properties) +{ + ShowList(((pgaCollectionFactory *)GetFactory())->GetItemTypeName(), browser, properties); +} + +void pgCollection::ShowList(const wxString &name, ctlTree *browser, ctlListView *properties) +{ + if (properties) + { + // Display the properties. + wxCookieType cookie; + pgObject *data; + + // Setup listview + CreateList3Columns(properties, wxGetTranslation(name), _("Owner"), _("Comment")); + + wxTreeItemId item = browser->GetFirstChild(GetId(), cookie); + long pos = 0; + while (item) + { + data = browser->GetObject(item); + if (IsCollectionFor(data)) + { + properties->InsertItem(pos, data->GetFullName(), data->GetIconId()); + properties->SetItem(pos, 1, data->GetOwner()); + properties->SetItem(pos, 2, firstLineOnly(data->GetComment())); + pos++; + } + // Get the next item + item = browser->GetNextChild(GetId(), cookie); + } + } +} + +void pgCollection::UpdateChildCount(ctlTree *browser, int substract) +{ + wxString label; + label.Printf(wxString(wxGetTranslation(GetName())) + wxT(" (%d)"), (int)browser->GetChildrenCount(GetId(), false) - substract); + browser->SetItemText(GetId(), label); +} + + +int pgCollection::GetIconId() +{ + pgaFactory *objFactory = pgaFactory::GetFactory(GetType()); + if (objFactory) + return objFactory->GetIconId(); + return 0; +} + + +pgObject *pgCollection::FindChild(ctlTree *browser, const int index) +{ + wxCookieType cookie; + pgObject *data; + + wxTreeItemId item = browser->GetFirstChild(GetId(), cookie); + long pos = 0; + while (item && index >= 0) + { + data = browser->GetObject(item); + if (data && IsCollectionFor(data)) + { + if (index == pos) + return data; + + pos++; + } + item = browser->GetNextChild(GetId(), cookie); + } + return 0; +} + + + +void pgCollection::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (browser->GetChildrenCount(GetId(), false) == 0) + { + if (GetFactory()) + GetFactory()->CreateObjects(this, browser); + } + + UpdateChildCount(browser); + if (properties) + { + ShowList(browser, properties); + } +} diff --git a/schema/pgColumn.cpp b/schema/pgColumn.cpp new file mode 100644 index 0000000..9e0d776 --- /dev/null +++ b/schema/pgColumn.cpp @@ -0,0 +1,791 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgColumn.cpp - Column class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" +#include "schema/pgDatatype.h" +#include "schema/pgColumn.h" + + +pgColumn::pgColumn(pgTable *newTable, const wxString &newName) + : pgTableObject(newTable, columnFactory, newName) +{ + isFK = false; + isPK = false; + isReferenced = -1; +} + +pgColumn::~pgColumn() +{ +} + + +wxString pgColumn::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on column"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing column"); + message += wxT(" ") + GetName(); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for column"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop column \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop column \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop column cascaded?"); + break; + case DROPTITLE: + message = _("Drop column?"); + break; + case PROPERTIESREPORT: + message = _("Column properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Column properties"); + break; + case DDLREPORT: + message = _("Column DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Column DDL"); + break; + case STATISTICSREPORT: + message = _("Column statistics report"); + message += wxT(" - ") + GetName(); + break; + case OBJSTATISTICS: + message = _("Column statistics"); + break; + case DEPENDENCIESREPORT: + message = _("Column dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Column dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Column dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Column dependents"); + break; + } + + return message; +} + + +bool pgColumn::IsReferenced() +{ + if (isReferenced < 0) + { + isReferenced = (int)StrToLong(GetConnection()->ExecuteScalar( + wxT("SELECT COUNT(1) FROM pg_depend dep\n") + wxT(" JOIN pg_class cl ON dep.classid=cl.oid AND relname='pg_rewrite'\n") + wxT(" WHERE refobjid=") + GetTableOidStr() + + wxT(" AND refobjsubid=") + NumToStr(GetColNumber()))); + } + + return (isReferenced != 0); +} + + +bool pgColumn::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("ALTER TABLE ") + GetQuotedFullTable(); + sql += wxT(" DROP COLUMN ") + GetQuotedIdentifier(); + + return GetDatabase()->ExecuteVoid(sql); +} + + +void pgColumn::ShowDependencies(frmMain *form, ctlListView *Dependencies, const wxString &where) +{ + pgObject::ShowDependencies(form, Dependencies, + wxT("\n WHERE dep.objid=") + table->GetOidStr() + + wxT(" AND dep.objsubid=") + NumToStr(colNumber)); +} + + +void pgColumn::ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &where) +{ + pgObject::ShowDependents(form, referencedBy, + wxT("\n WHERE dep.refobjid=") + table->GetOidStr() + + wxT(" AND dep.refobjsubid=") + NumToStr(colNumber)); +} + +wxString pgColumn::GetSql(ctlTree *browser) +{ + if (sql.IsNull() && !GetSystemObject()) + { + if (GetTable()->GetMetaType() == PGM_VIEW) + { + sql = wxT("-- Column: ") + GetQuotedIdentifier() + wxT("\n\n"); + + if (!GetDefault().IsEmpty()) + sql += wxT("ALTER TABLE ") + GetQuotedFullTable() + + wxT(" ALTER COLUMN ") + GetQuotedIdentifier() + + wxT(" SET DEFAULT ") + GetDefault() + wxT(";\n"); + + sql += GetCommentSql(); + } + else if (GetTable()->GetMetaType() == PGM_CATALOGOBJECT || GetTable()->GetMetaType() == GP_EXTTABLE) + { + sql = wxT("-- Column: ") + GetQuotedIdentifier() + wxT("\n\n"); + } + else + { + if (GetInheritedCount()) + sql = wxT("-- Column inherited; cannot be changed"); + else + { + sql = wxT("-- Column: ") + GetQuotedIdentifier() + wxT("\n\n") + + wxT("-- ALTER TABLE ") + GetQuotedFullTable() + + wxT(" DROP COLUMN ") + GetQuotedIdentifier() + wxT(";") + + + wxT("\n\nALTER TABLE ") + GetQuotedFullTable() + + wxT(" ADD COLUMN ") + GetQuotedIdentifier() + wxT(" ") + + GetQuotedTypename(); + if (!GetCollation().IsEmpty() && GetCollation() != wxT("pg_catalog.\"default\"")) + sql += wxT(" COLLATE ") + GetCollation(); + sql += wxT(";\n"); + + sql += GetStorageSql(); + + if (GetNotNull()) + sql += wxT("ALTER TABLE ") + GetQuotedFullTable() + + wxT(" ALTER COLUMN ") + GetQuotedIdentifier() + + wxT(" SET NOT NULL;\n"); + if (!GetDefault().IsEmpty()) + sql += wxT("ALTER TABLE ") + GetQuotedFullTable() + + wxT(" ALTER COLUMN ") + GetQuotedIdentifier() + + wxT(" SET DEFAULT ") + GetDefault() + wxT(";\n"); + sql += GetAttstattargetSql(); + + sql += GetVariablesSql(); + + sql += GetCommentSql(); + + if (GetDatabase()->BackendMinimumVersion(8, 4)) + sql += GetPrivileges(); + + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += GetSeqLabelsSql(); + } + } + } + + return sql; +} + +wxString pgColumn::GetCommentSql() +{ + wxString commentSql; + + if (!GetComment().IsEmpty()) + commentSql = wxT("COMMENT ON COLUMN ") + GetQuotedFullTable() + wxT(".") + GetQuotedIdentifier() + + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); + + return commentSql; +} + +wxString pgColumn::GetStorageSql() +{ + wxString storageSql; + + if (GetStorage() != GetDefaultStorage()) + storageSql = wxT("ALTER TABLE ") + GetQuotedFullTable() + + wxT(" ALTER COLUMN ") + GetQuotedIdentifier() + + wxT(" SET STORAGE ") + GetStorage() + wxT(";\n"); + + return storageSql; +} + +wxString pgColumn::GetAttstattargetSql() +{ + wxString attstattargetSql; + + if (GetAttstattarget() >= 0) + attstattargetSql = wxT("ALTER TABLE ") + GetQuotedFullTable() + + wxT(" ALTER COLUMN ") + GetQuotedIdentifier() + + wxT(" SET STATISTICS ") + NumToStr(GetAttstattarget()) + wxT(";\n"); + + return attstattargetSql; +} + +wxString pgColumn::GetVariablesSql() +{ + wxString variablesSql; + + size_t i; + for (i = 0 ; i < variables.GetCount() ; i++) + variablesSql += wxT("ALTER TABLE ") + GetQuotedFullTable() + + wxT(" ALTER COLUMN ") + GetQuotedIdentifier() + + wxT(" SET (") + variables.Item(i) + wxT(");\n"); + + return variablesSql; +} + +wxString pgColumn::GetPrivileges() +{ + wxString privileges; + wxString strAcl = GetAcl(); + if (!strAcl.IsEmpty()) + { + wxArrayString aclArray; + strAcl = strAcl.Mid(1, strAcl.Length() - 2); + getArrayFromCommaSeparatedList(strAcl, aclArray); + wxString role; + for (unsigned int index = 0; index < aclArray.Count(); index++) + { + wxString strCurrAcl = aclArray[index]; + /* + * In rare case, we can have ',' (comma) in the user name. + * But, we need to handle them also + */ + if (strCurrAcl.Find(wxChar('=')) == wxNOT_FOUND) + { + // Check it is start of the ACL + if (strCurrAcl[0U] == (wxChar)'"') + role = strCurrAcl + wxT(","); + continue; + } + else + strCurrAcl = role + strCurrAcl; + + if (strCurrAcl[0U] == (wxChar)'"') + strCurrAcl = strCurrAcl.Mid(1, strCurrAcl.Length() - 1); + role = strCurrAcl.BeforeLast('='); + wxString value = strCurrAcl.Mid(role.Length() + 1).BeforeLast('/'); + + if (role.Left(6).IsSameAs(wxT("group "), false)) + { + role = wxT("group ") + qtIdent(qtStrip(role.Mid(6))); + } + else if (role.IsEmpty()) + { + role = wxT("public"); + } + else + role = qtIdent(qtStrip(role)); + + privileges += pgObject::GetPrivileges(wxT("awrx"), value, GetQuotedFullTable(), role, GetQuotedIdentifier()); + role.Clear(); + } + } + return privileges; +} +wxString pgColumn::GetDefinition() +{ + wxString sql = wxEmptyString; + wxString seqDefault1, seqDefault2; + + if (table->GetOfTypeOid() == 0) + sql += GetQuotedTypename(); + + if (!GetCollation().IsEmpty() && GetCollation() != wxT("pg_catalog.\"default\"")) + sql += wxT(" COLLATE ") + GetCollation(); + + wxString full_tabname = wxEmptyString; + if (GetDatabase()->BackendMinimumVersion(8, 1)) + { + wxString schpref; + + schpref = schema->GetQuotedPrefix(); + full_tabname = GetTableName() + wxT("_") + GetName() + wxT("_seq"); + + // If the generated sequence name is longer than 64 characters, then + // - If both table & column name exceed 29 chars, truncate both to 29 + // - If one of table or column name exceeds 29 chars, truncate it to + // 29 chars plus however much less than 29 chars the other name is. + if (full_tabname.Length() > 64) + { + int tlen = GetTableName().Length(); + int clen = GetName().Length(); + + if (tlen > 29 && clen > 29) + full_tabname = GetTableName().Left(29) + wxT("_") + GetName().Left(29) + wxT("_seq"); + else if (tlen > 29) + full_tabname = GetTableName().Left(29 + (29 - clen)) + wxT("_") + GetName() + wxT("_seq"); + else if (clen > 29) + full_tabname = GetTableName() + wxT("_") + GetName().Left(29 + (29 - tlen)) + wxT("_seq"); + } + + full_tabname = qtIdent(full_tabname); + + if (schpref != wxEmptyString) + full_tabname = schpref + full_tabname; + + seqDefault1 = wxT("nextval('") + full_tabname + wxT("'::regclass)"); + seqDefault2 = seqDefault1; + } + else + { + seqDefault1 = wxT("nextval('") + + schema->GetName() + wxT(".") + GetTableName() + + wxT("_") + GetName() + wxT("_seq'::text)"); + seqDefault2 = wxT("nextval('\"") + + schema->GetName() + wxT(".") + GetTableName() + + wxT("_") + GetName() + wxT("_seq\"'::text)"); + } + + if ((sql == wxT("integer") || sql == wxT("bigint") || sql == wxT("smallint") || + sql == wxT("pg_catalog.integer") || sql == wxT("pg_catalog.bigint") || sql == wxT("pg_catalog.smallint")) + && (GetDefault() == seqDefault1 || GetDefault() == seqDefault2)) + { + if (GetDatabase()->BackendMinimumVersion(8, 1)) + { + pgSet *set = ExecuteSet( + wxT("SELECT classid\n") + wxT(" FROM pg_depend\n") + wxT(" WHERE refobjid=") + table->GetOidStr() + + wxT(" AND refobjsubid = ") + NumToStr(GetColNumber()) + + wxT(" AND objid = '") + full_tabname + wxT("'::regclass") + + wxT(" AND deptype='a'")); + + if (set && set->NumRows()) + { + if (sql.Right(6) == wxT("bigint")) + sql = wxT("bigserial"); + else if (sql.Right(8) == wxT("smallint")) + sql = wxT("smallserial"); + else + sql = wxT("serial"); + } + + if (GetNotNull()) + sql += wxT(" NOT NULL"); + + if (!set || !(set->NumRows())) + AppendIfFilled(sql, wxT(" DEFAULT "), GetDefault()); + + if (set) + delete set; + } + else + { + if (sql.Right(6) == wxT("bigint")) + sql = wxT("bigserial"); + else if (sql.Right(8) == wxT("smallint")) + sql = wxT("smallserial"); + else + sql = wxT("serial"); + + if (GetNotNull()) + sql += wxT(" NOT NULL"); + } + } + else + { + if (GetNotNull()) + sql += wxT(" NOT NULL"); + AppendIfFilled(sql, wxT(" DEFAULT "), GetDefault()); + } + return sql; +} + + +void pgColumn::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + wxStringTokenizer indkey(pkCols); + while (indkey.HasMoreTokens()) + { + wxString str = indkey.GetNextToken(); + if (StrToLong(str) == GetColNumber()) + { + isPK = true; + break; + } + } + + if (!GetDatabase()->BackendMinimumVersion(7, 4)) + { + // 7.3 misses the ANY(array) comparison + pgSet *set = ExecuteSet( + wxT("SELECT conkey\n") + wxT(" FROM pg_constraint ct\n") + wxT(" JOIN pg_class cl on cl.oid=confrelid\n") + wxT(" WHERE contype='f' AND conrelid = ") + GetTableOidStr() + wxT("\n") + wxT(" ORDER BY conname")); + if (set) + { + wxString str; + while (!isFK && !set->Eof()) + { + wxStringTokenizer conkey(set->GetVal(0)); + + while (conkey.HasMoreTokens()) + { + str = conkey.GetNextToken(); + if (StrToLong(str.Mid(1)) == GetColNumber()) + { + isFK = true; + break; + } + } + + set->MoveNext(); + } + delete set; + } + } + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("Position"), GetColNumber()); + properties->AppendItem(_("Data type"), GetVarTypename()); + if (GetDatabase()->BackendMinimumVersion(9, 1)) + { + properties->AppendItem(_("Collation"), GetCollation()); + } + if (GetTable()->GetMetaType() != PGM_CATALOGOBJECT) + { + properties->AppendItem(_("Default"), GetDefault()); + if (GetTable()->GetMetaType() != PGM_VIEW && GetTable()->GetMetaType() != GP_EXTTABLE) + { + properties->AppendItem(_("Sequence"), database->GetSchemaPrefix(GetSerialSchema()) + GetSerialSequence()); + + properties->AppendYesNoItem(_("Not NULL?"), GetNotNull()); + properties->AppendYesNoItem(_("Primary key?"), GetIsPK()); + properties->AppendYesNoItem(_("Foreign key?"), GetIsFK()); + properties->AppendItem(_("Storage"), GetStorage()); + if (GetInheritedCount() != 0) + { + properties->AppendItem(_("Inherited"), + wxT("Yes (from table ") + GetInheritedTableName() + wxT(")")); + } + else + { + properties->AppendYesNoItem(_("Inherited"), false); + } + properties->AppendItem(_("Statistics"), GetAttstattarget()); + size_t i; + for (i = 0 ; i < variables.GetCount() ; i++) + { + wxString item = variables.Item(i); + properties->AppendItem(item.BeforeFirst('='), item.AfterFirst('=')); + } + properties->AppendYesNoItem(_("System column?"), GetSystemObject()); + } + } + if (GetDatabase()->BackendMinimumVersion(8, 4)) + { + properties->AppendItem(_("ACL"), GetAcl()); + } + + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + if (!GetLabels().IsEmpty()) + { + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); + } + } + } + } +} + + +void pgColumn::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + DisplayStatistics(statistics, + wxT("SELECT null_frac AS ") + qtIdent(_("Null Fraction")) + + wxT(", avg_width AS ") + qtIdent(_("Average Width")) + + wxT(", n_distinct AS ") + qtIdent(_("Distinct Values")) + + wxT(", most_common_vals AS ") + qtIdent(_("Most Common Values")) + + wxT(", most_common_freqs AS ") + qtIdent(_("Most Common Frequencies")) + + wxT(", histogram_bounds AS ") + qtIdent(_("Histogram Bounds")) + + wxT(", correlation AS ") + qtIdent(_("Correlation")) + wxT("\n") + wxT(" FROM pg_stats\n") + wxT(" WHERE schemaname = ") + qtDbString(schema->GetName()) + wxT("\n") + wxT(" AND tablename = ") + qtDbString(GetTableName()) + wxT("\n") + wxT(" AND attname = ") + qtDbString(GetName())); +} + + +pgObject *pgColumn::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *column = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + column = columnFactory.CreateObjects(coll, 0, wxT("\n AND att.attnum=") + NumToStr(GetColNumber())); + + return column; +} + + + +pgObject *pgColumnFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restriction) +{ + pgTableObjCollection *collection = (pgTableObjCollection *)coll; + pgColumn *column = 0; + pgDatabase *database = collection->GetDatabase(); + inheritHashMap inhMap; + + // grab inherited tables with attibute names + pgSet *inhtables = database->ExecuteSet( + wxT("SELECT\n") + wxT(" array_to_string(array_agg(inhrelname), ', ') inhrelname,\n") + wxT(" attrname\n") + wxT("FROM\n") + wxT(" (SELECT\n") + wxT(" inhparent::regclass AS inhrelname,\n") + wxT(" a.attname AS attrname\n") + wxT(" FROM\n") + wxT(" pg_inherits i\n") + wxT(" LEFT JOIN pg_attribute a ON\n") + wxT(" (attrelid = inhparent AND attnum > 0)\n") + wxT(" WHERE inhrelid = ") + collection->GetOidStr() + wxT("::oid\n") + wxT(" ORDER BY inhseqno) a\n") + wxT("GROUP BY attrname")); + + if (inhtables) + { + while (!inhtables->Eof()) + { + wxString attrName = inhtables->GetVal(wxT("attrname")); + wxString inhrelName = inhtables->GetVal(wxT("inhrelname")); + inhMap[attrName] = inhrelName; + inhtables->MoveNext(); + } + + delete inhtables; + } + + wxString systemRestriction; + if (!settings->GetShowSystemObjects()) + systemRestriction = wxT("\n AND att.attnum > 0"); + + wxString sql = + wxT("SELECT att.*, def.*, pg_catalog.pg_get_expr(def.adbin, def.adrelid) AS defval, CASE WHEN att.attndims > 0 THEN 1 ELSE 0 END AS isarray, format_type(ty.oid,NULL) AS typname, format_type(ty.oid,att.atttypmod) AS displaytypname, tn.nspname as typnspname, et.typname as elemtypname,\n") + wxT(" ty.typstorage AS defaultstorage, cl.relname, na.nspname, att.attstattarget, description, cs.relname AS sername, ns.nspname AS serschema,\n") + wxT(" (SELECT count(1) FROM pg_type t2 WHERE t2.typname=ty.typname) > 1 AS isdup, indkey"); + + if (database->BackendMinimumVersion(9, 1)) + sql += wxT(",\n coll.collname, nspc.nspname as collnspname"); + if (database->BackendMinimumVersion(8, 5)) + sql += wxT(",\n attoptions"); + if (database->BackendMinimumVersion(7, 4)) + sql += + wxT(",\n") + wxT(" EXISTS(SELECT 1 FROM pg_constraint WHERE conrelid=att.attrelid AND contype='f'") + wxT(" AND att.attnum=ANY(conkey)) As isfk"); + if (database->BackendMinimumVersion(9, 1)) + { + sql += wxT(",\n(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=att.attrelid AND sl1.objsubid=att.attnum) AS labels"); + sql += wxT(",\n(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=att.attrelid AND sl2.objsubid=att.attnum) AS providers"); + } + + sql += wxT("\n") + wxT(" FROM pg_attribute att\n") + wxT(" JOIN pg_type ty ON ty.oid=atttypid\n") + wxT(" JOIN pg_namespace tn ON tn.oid=ty.typnamespace\n") + wxT(" JOIN pg_class cl ON cl.oid=att.attrelid\n") + wxT(" JOIN pg_namespace na ON na.oid=cl.relnamespace\n") + wxT(" LEFT OUTER JOIN pg_type et ON et.oid=ty.typelem\n") + wxT(" LEFT OUTER JOIN pg_attrdef def ON adrelid=att.attrelid AND adnum=att.attnum\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=att.attrelid AND des.objsubid=att.attnum AND des.classoid='pg_class'::regclass)\n") + wxT(" LEFT OUTER JOIN (pg_depend JOIN pg_class cs ON classid='pg_class'::regclass AND objid=cs.oid AND cs.relkind='S') ON refobjid=att.attrelid AND refobjsubid=att.attnum\n") + wxT(" LEFT OUTER JOIN pg_namespace ns ON ns.oid=cs.relnamespace\n") + wxT(" LEFT OUTER JOIN pg_index pi ON pi.indrelid=att.attrelid AND indisprimary\n"); + if (database->BackendMinimumVersion(9, 1)) + sql += wxT(" LEFT OUTER JOIN pg_collation coll ON att.attcollation=coll.oid\n") + wxT(" LEFT OUTER JOIN pg_namespace nspc ON coll.collnamespace=nspc.oid\n"); + sql += wxT(" WHERE att.attrelid = ") + collection->GetOidStr() + + restriction + systemRestriction + wxT("\n") + wxT(" AND att.attisdropped IS FALSE\n") + wxT(" ORDER BY att.attnum"); + + pgSet *columns = database->ExecuteSet(sql); + if (columns) + { + while (!columns->Eof()) + { + wxString attrName = columns->GetVal(wxT("attname")); + column = new pgColumn(collection->GetTable(), attrName); + + column->iSetAttTypId(columns->GetOid(wxT("atttypid"))); + column->iSetColNumber(columns->GetLong(wxT("attnum"))); + column->iSetIsArray(columns->GetBool(wxT("isarray"))); + column->iSetComment(columns->GetVal(wxT("description"))); + column->iSetSerialSequence(columns->GetVal(wxT("sername"))); + column->iSetSerialSchema(columns->GetVal(wxT("serschema"))); + column->iSetPkCols(columns->GetVal(wxT("indkey"))); + if (database->BackendMinimumVersion(7, 4)) + column->iSetIsFK(columns->GetBool(wxT("isfk"))); + + if (columns->GetBool(wxT("atthasdef"))) + column->iSetDefault(columns->GetVal(wxT("defval"))); + column->iSetStatistics(columns->GetLong(wxT("attstattarget"))); + + wxString storage = columns->GetVal(wxT("attstorage")); + column->iSetStorage( + storage == wxT("p") ? wxT("PLAIN") : + storage == wxT("e") ? wxT("EXTERNAL") : + storage == wxT("m") ? wxT("MAIN") : + storage == wxT("x") ? wxT("EXTENDED") : wxT("Unknown")); + wxString defaultStorage = columns->GetVal(wxT("defaultstorage")); + column->iSetDefaultStorage( + defaultStorage == wxT("p") ? wxT("PLAIN") : + defaultStorage == wxT("e") ? wxT("EXTERNAL") : + defaultStorage == wxT("m") ? wxT("MAIN") : + defaultStorage == wxT("x") ? wxT("EXTENDED") : wxT("Unknown")); + + column->iSetTyplen(columns->GetLong(wxT("attlen"))); + + long typmod = columns->GetLong(wxT("atttypmod")); + pgDatatype dt(columns->GetVal(wxT("typnspname")), columns->GetVal(wxT("typname")), + columns->GetBool(wxT("isdup")), + columns->GetLong(wxT("attndims")), typmod); + + + column->iSetTypmod(typmod); + column->iSetLength(dt.Length()); + column->iSetPrecision(dt.Precision()); + column->iSetRawTypename(dt.Name()); + + column->iSetVarTypename(dt.FullName()); + column->iSetQuotedTypename(columns->GetVal(wxT("displaytypname"))); + + column->iSetNotNull(columns->GetBool(wxT("attnotnull"))); + column->iSetQuotedFullTable(database->GetQuotedSchemaPrefix(columns->GetVal(wxT("nspname"))) + + qtIdent(columns->GetVal(wxT("relname")))); + column->iSetTableName(columns->GetVal(wxT("relname"))); + column->iSetInheritedCount(columns->GetLong(wxT("attinhcount"))); + + // Check whether the attribute is inherited + inheritHashMap::iterator it = inhMap.find(attrName); + if (it != inhMap.end()) + column->iSetInheritedTableName(it->second); + + column->iSetIsLocal(columns->GetBool(wxT("attislocal"))); + column->iSetAttstattarget(columns->GetLong(wxT("attstattarget"))); + if (database->BackendMinimumVersion(8, 5)) + { + wxString str = columns->GetVal(wxT("attoptions")); + if (!str.IsEmpty()) + FillArray(column->GetVariables(), str.Mid(1, str.Length() - 2)); + } + if (database->BackendMinimumVersion(8, 4)) + column->iSetAcl(columns->GetVal(wxT("attacl"))); + if (database->BackendMinimumVersion(9, 1)) + { + wxString coll = wxEmptyString; + if (!columns->GetVal(wxT("collname")).IsEmpty()) + coll = qtIdent(columns->GetVal(wxT("collnspname"))) + wxT(".") + qtIdent(columns->GetVal(wxT("collname"))); + column->iSetCollation(coll); + } + + if (database->BackendMinimumVersion(9, 1)) + { + column->iSetProviders(columns->GetVal(wxT("providers"))); + column->iSetLabels(columns->GetVal(wxT("labels"))); + } + + if (browser) + { + browser->AppendObject(collection, column); + columns->MoveNext(); + } + else + break; + } + + delete columns; + } + + inhMap.clear(); + return column; +} + +///////////////////////////// + +pgColumnCollection::pgColumnCollection(pgaFactory *factory, pgTable *tbl) + : pgTableObjCollection(factory, tbl) +{ +} + + +wxString pgColumnCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on columns"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing columns"); + break; + case OBJECTSLISTREPORT: + message = _("Columns list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/column.pngc" +#include "images/column-sm.pngc" +#include "images/columns.pngc" + +pgColumnFactory::pgColumnFactory() + : pgTableObjFactory(__("Column"), __("New Column..."), __("Create a new Column."), column_png_img, column_sm_png_img) +{ + metaType = PGM_COLUMN; +} + + +pgCollection *pgColumnFactory::CreateCollection(pgObject *obj) +{ + return new pgColumnCollection(GetCollectionFactory(), (pgTable *)obj); +} + +pgColumnFactory columnFactory; +static pgaCollectionFactory cf(&columnFactory, __("Columns"), columns_png_img); diff --git a/schema/pgConstraints.cpp b/schema/pgConstraints.cpp new file mode 100644 index 0000000..b768e53 --- /dev/null +++ b/schema/pgConstraints.cpp @@ -0,0 +1,129 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgConstraint.cpp - Constraint collection +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + + +#include "pgAdmin3.h" +#include "schema/pgTable.h" +#include "schema/pgDomain.h" +#include "schema/pgConstraints.h" +#include "schema/pgIndexConstraint.h" +#include "schema/pgCheck.h" +#include "schema/pgForeignKey.h" +#include "schema/pgPartition.h" + + +pgConstraintCollection::pgConstraintCollection(pgaFactory *factory, pgSchema *schema) + : pgSchemaObjCollection(factory, schema) +{ +} + +wxMenu *pgConstraintCollection::GetNewMenu() +{ + if ((table && !table->CanCreate()) || (domain && !domain->CanCreate())) + return 0; + + wxMenu *menu = new wxMenu(); + if (table) + { + if (table->GetPrimaryKey().IsEmpty()) + primaryKeyFactory.AppendMenu(menu); + foreignKeyFactory.AppendMenu(menu); + excludeFactory.AppendMenu(menu); + uniqueFactory.AppendMenu(menu); + } + checkFactory.AppendMenu(menu); + return menu; +} + + +void pgConstraintCollection::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (browser->GetChildrenCount(GetId(), false) == 0) + { + browser->RemoveDummyChild(this); + + wxTreeItemId id = browser->GetItemParent(GetId()); + wxASSERT(id); + table = NULL; + domain = NULL; + if (browser->GetObject(id)->IsCreatedBy(tableFactory)) + { + table = (pgTable *)browser->GetObject(id); + } + if (browser->GetObject(id)->IsCreatedBy(pg_partitionFactory)) + { + table = (pgTable *)browser->GetObject(id); + } + + if (browser->GetObject(id)->IsCreatedBy(domainFactory)) + { + domain = (pgDomain *)browser->GetObject(id); + } + + if (table) + { + primaryKeyFactory.CreateObjects(this, browser); + foreignKeyFactory.CreateObjects(this, browser); + excludeFactory.CreateObjects(this, browser); + uniqueFactory.CreateObjects(this, browser); + } + checkFactory.CreateObjects(this, browser); + } + UpdateChildCount(browser); + if (properties) + ShowList(_("Constraints"), browser, properties); +} + + +wxString pgConstraintCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on constraints"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing constraints"); + break; + case OBJECTSLISTREPORT: + message = _("Constraints list report"); + break; + } + + return message; +} + + +///////////////////////////// + +#include "images/constraints.pngc" + +pgConstraintFactory::pgConstraintFactory() + : pgSchemaObjFactory(__("Constraint"), 0, 0, 0) +{ + metaType = PGM_CONSTRAINT; +} + +pgCollection *pgConstraintFactory::CreateCollection(pgObject *obj) +{ + return new pgConstraintCollection(GetCollectionFactory(), (pgSchema *)obj); +} + + +pgConstraintFactory constraintFactory; +pgaCollectionFactory constraintCollectionFactory(&constraintFactory, __("Constraints"), constraints_png_img); + + diff --git a/schema/pgConversion.cpp b/schema/pgConversion.cpp new file mode 100644 index 0000000..faf5fef --- /dev/null +++ b/schema/pgConversion.cpp @@ -0,0 +1,245 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgConversion.cpp - Conversion class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgConversion.h" + + +pgConversion::pgConversion(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, conversionFactory, newName) +{ +} + +pgConversion::~pgConversion() +{ +} + +wxString pgConversion::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on conversion"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing conversion"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop conversion \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop conversion \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop conversion cascaded?"); + break; + case DROPTITLE: + message = _("Drop conversion?"); + break; + case PROPERTIESREPORT: + message = _("Conversion properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Conversion properties"); + break; + case DDLREPORT: + message = _("Conversion DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Conversion DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Conversion dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Conversion dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Conversion dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Conversion dependents"); + break; + } + + return message; +} + + +bool pgConversion::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP CONVERSION ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + +wxString pgConversion::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Conversion: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP CONVERSION ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE "); + if (GetDefaultConversion()) + sql += wxT("DEFAULT "); + sql += wxT("CONVERSION ") + qtIdent(GetName()) + + wxT("\n FOR '") + GetForEncoding() + wxT("'") + + wxT("\n TO '") + GetToEncoding() + wxT("'") + + wxT("\n FROM ") + GetDatabase()->GetQuotedSchemaPrefix(GetProcNamespace()) + + qtIdent(GetProc()) + wxT(";\n") + + GetOwnerSql(8, 0); + } + + return sql; +} + +void pgConversion::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("From"), GetForEncoding()); + properties->AppendItem(_("To"), GetToEncoding()); + properties->AppendItem(_("Function"), GetSchemaPrefix(GetProcNamespace()) + GetProc()); + properties->AppendYesNoItem(_("Default?"), GetDefaultConversion()); + properties->AppendYesNoItem(_("System conversion?"), GetSystemObject()); + if (GetConnection()->BackendMinimumVersion(7, 5)) + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + + +pgObject *pgConversion::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *conversion = 0; + + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + conversion = conversionFactory.CreateObjects(coll, 0, wxT("\n AND co.oid=") + GetOidStr()); + + return conversion; +} + + + +pgObject *pgConversionFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgConversion *conversion = 0; + + pgSet *conversions = collection->GetDatabase()->ExecuteSet( + wxT("SELECT co.oid, co.*, pg_encoding_to_char(conforencoding) as forencoding, pg_get_userbyid(conowner) as owner,") + wxT("pg_encoding_to_char(contoencoding) as toencoding, proname, nspname, description\n") + wxT(" FROM pg_conversion co\n") + wxT(" JOIN pg_proc pr ON pr.oid=conproc\n") + wxT(" JOIN pg_namespace na ON na.oid=pr.pronamespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=co.oid AND des.objsubid=0 AND des.classoid='pg_conversion'::regclass)\n") + wxT(" WHERE connamespace = ") + collection->GetSchema()->GetOidStr() + + restriction + wxT("\n") + wxT(" ORDER BY conname")); + + if (conversions) + { + while (!conversions->Eof()) + { + conversion = new pgConversion(collection->GetSchema(), + conversions->GetVal(wxT("conname"))); + + conversion->iSetOid(conversions->GetOid(wxT("oid"))); + conversion->iSetOwner(conversions->GetVal(wxT("owner"))); + conversion->iSetComment(conversions->GetVal(wxT("description"))); + conversion->iSetForEncoding(conversions->GetVal(wxT("forencoding"))); + conversion->iSetToEncoding(conversions->GetVal(wxT("toencoding"))); + conversion->iSetProc(conversions->GetVal(wxT("proname"))); + conversion->iSetProcNamespace(conversions->GetVal(wxT("nspname"))); + conversion->iSetDefaultConversion(conversions->GetBool(wxT("condefault"))); + + if (browser) + { + browser->AppendObject(collection, conversion); + conversions->MoveNext(); + } + else + break; + } + + delete conversions; + } + return conversion; +} + +///////////////////////////// + +pgConversionCollection::pgConversionCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgConversionCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on conversions"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing conversions"); + break; + case OBJECTSLISTREPORT: + message = _("Conversions list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/conversion.pngc" +#include "images/conversions.pngc" + +pgConversionFactory::pgConversionFactory() + : pgSchemaObjFactory(__("Conversion"), __("New Conversion..."), __("Create a new Conversion."), conversion_png_img) +{ +} + + +pgCollection *pgConversionFactory::CreateCollection(pgObject *obj) +{ + return new pgConversionCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgConversionFactory conversionFactory; +static pgaCollectionFactory cf(&conversionFactory, __("Conversions"), conversions_png_img); diff --git a/schema/pgDatabase.cpp b/schema/pgDatabase.cpp new file mode 100644 index 0000000..571aba2 --- /dev/null +++ b/schema/pgDatabase.cpp @@ -0,0 +1,1350 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgDatabase.cpp - PostgreSQL Database +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgfeatures.h" +#include "frm/frmMain.h" +#include "schema/edbSynonym.h" +#include "schema/pgCast.h" +#include "schema/pgExtension.h" +#include "schema/pgForeignDataWrapper.h" +#include "schema/pgLanguage.h" +#include "schema/pgSchema.h" +#include "schema/pgEventTrigger.h" +#include "slony/slCluster.h" +#include "frm/frmHint.h" +#include "frm/frmReport.h" + + +pgDatabase::pgDatabase(const wxString &newName) + : pgServerObject(databaseFactory, newName) +{ + useServerConnection = true; + allowConnections = true; + connected = false; + conn = NULL; + missingFKs = 0; + canDebugPlpgsql = 0; + canDebugEdbspl = 0; +} + + +pgDatabase::~pgDatabase() +{ + Disconnect(); +} + + +wxString pgDatabase::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on database"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing database"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop database \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop database \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop database cascaded?"); + break; + case DROPTITLE: + message = _("Drop database?"); + break; + case PROPERTIESREPORT: + message = _("Database properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Database properties"); + break; + case DDLREPORT: + message = _("Database DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Database DDL"); + break; + case STATISTICSREPORT: + message = _("Database statistics report"); + message += wxT(" - ") + GetName(); + break; + case OBJSTATISTICS: + message = _("Database statistics"); + break; + case DEPENDENCIESREPORT: + message = _("Database dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Database dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Database dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Database dependents"); + break; + case BACKUPTITLE: + message = wxString::Format(_("Backup database \"%s\""), + GetFullIdentifier().c_str()); + break; + case RESTORETITLE: + message = wxString::Format(_("Restore database \"%s\""), + GetFullIdentifier().c_str()); + break; + } + + return message; +} + + +int pgDatabase::GetIconId() +{ + if (GetConnected()) + return databaseFactory.GetIconId(); + else + return databaseFactory.GetClosedIconId(); +} + + +wxMenu *pgDatabase::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + + if (GetConnection() && GetCreatePrivilege()) + { + if (settings->GetDisplayOption(_("Casts"))) + castFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Extensions")) && GetConnection()->BackendMinimumVersion(9, 1)) + extensionFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Foreign Data Wrappers")) && GetConnection()->BackendMinimumVersion(8, 4)) + foreignDataWrapperFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Languages"))) + languageFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Synonyms")) && GetConnection()->EdbMinimumVersion(8, 0)) + if (!GetConnection()->BackendMinimumVersion(8, 4)) + synonymFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Schemas"))) + schemaFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Slony"))) + slClusterFactory.AppendMenu(menu); + } + return menu; +} + +int pgDatabase::Connect() +{ + if (!allowConnections) + return PGCONN_REFUSED; + + if (!connected) + { + if (GetName() == server->GetDatabaseName() && server->connection()->GetStatus() == PGCONN_OK) + { + useServerConnection = true; + conn = 0; + } + else + { + useServerConnection = false; + wxString applicationname = appearanceFactory->GetLongAppName() + wxT(" - Browser"); + conn = CreateConn(applicationname); + + if (!conn) + { + connected = false; + return PGCONN_BAD; + } + } + + // Now we're connected. + + // check for extended ruleutils with pretty-print option + wxString exprname = connection()->ExecuteScalar(wxT("SELECT proname FROM pg_proc WHERE proname='pg_get_viewdef' AND proargtypes[1]=16")); + if (!exprname.IsEmpty()) + prettyOption = wxT(", true"); + + UpdateDefaultSchema(); + + if (connection()->BackendMinimumVersion(9, 0)) + { + m_defPrivsOnTables = connection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = 0::OID AND defaclobjtype='r'")); + m_defPrivsOnSeqs = connection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = 0::OID AND defaclobjtype='S'")); + m_defPrivsOnFuncs = connection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = 0::OID AND defaclobjtype='f'")); + } + if (connection()->BackendMinimumVersion(9, 2)) + { + m_defPrivsOnTypes = connection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = 0::OID AND defaclobjtype='T'")); + } + + connected = true; + } + + return connection()->GetStatus(); +} + + +pgConn *pgDatabase::connection() +{ + if (useServerConnection) + return server->connection(); + return conn; + +} + +void pgDatabase::CheckAlive() +{ + if (connected) + connected = connection()->IsAlive(); +} + +void pgDatabase::Disconnect() +{ + connected = false; + if (conn) + delete conn; + conn = 0; +} + + +bool pgDatabase::GetCanHint() +{ + if (encoding == wxT("SQL_ASCII")) + return true; + + if (encoding == wxT("UNICODE")) + { + wxString ver = GetServer()->GetVersionString(); + if (ver.Find(wxT("mingw32")) > 0 && ver.Find(wxT("SQL 8.0.")) > 0) + return true; + } + + if (GetServer()->GetConnection() == GetConnection() && + GetConnection()->BackendMinimumVersion(8, 0) && + !GetConnection()->HasFeature(FEATURE_FILEREAD)) + return true; + + return false; +} + + +void pgDatabase::ShowHint(frmMain *form, bool force) +{ + wxArrayString hints; + int rc = -1; + + if (encoding == wxT("SQL_ASCII")) + hints.Add(HINT_ENCODING_ASCII); + else if (encoding == wxT("UNICODE")) + { + wxString ver = GetServer()->GetVersionString(); + if (ver.Find(wxT("mingw32")) > 0 && ver.Find(wxT("SQL 8.0.")) > 0) + hints.Add(HINT_ENCODING_UNICODE); + } + + if (GetServer()->GetConnection() == GetConnection() && + GetConnection()->BackendMinimumVersion(8, 0) && + !GetConnection()->HasFeature(FEATURE_FILEREAD)) + { + // if the server release is 9.1 or more and the server has no adminpack + if (GetConnection()->BackendMinimumVersion(9, 1)) + { + // Search the adminpack extension + pgSet *set = GetConnection()->ExecuteSet(wxT("SELECT 1 FROM pg_available_extensions WHERE name='adminpack'")); + if (set->NumRows() == 1) + hints.Add(HINT_INSTRUMENTATION_91_WITH); + else + hints.Add(HINT_INSTRUMENTATION_91_WITHOUT); + delete set; + } + else + hints.Add(HINT_INSTRUMENTATION); + } + + if (force || !hintShown) + { + rc = frmHint::ShowHint(form, hints, GetFullIdentifier(), force); + if (rc == HINT_RC_FIX) + GetConnection()->ExecuteVoid(wxT("CREATE EXTENSION adminpack"), true); + } + hintShown = true; +} + + +void pgDatabase::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + if (GetConnection()) + { + bool hasSize = connection()->HasFeature(FEATURE_SIZE); + + wxString sql = wxT("SELECT numbackends AS ") + qtIdent(_("Backends")) + + wxT(", xact_commit AS ") + qtIdent(_("Xact Committed")) + + wxT(", xact_rollback AS ") + qtIdent(_("Xact Rolled Back")) + + wxT(", blks_read AS ") + qtIdent(_("Blocks Read")) + + wxT(", blks_hit AS ") + qtIdent(_("Blocks Hit")); + + if (connection()->BackendMinimumVersion(8, 3)) + sql += wxT(", tup_returned AS ") + qtIdent(_("Tuples Returned")) + + wxT(", tup_fetched AS ") + qtIdent(_("Tuples Fetched")) + + wxT(", tup_inserted AS ") + qtIdent(_("Tuples Inserted")) + + wxT(", tup_updated AS ") + qtIdent(_("Tuples Updated")) + + wxT(", tup_deleted AS ") + qtIdent(_("Tuples Deleted")); + + if (connection()->BackendMinimumVersion(9, 1)) + sql += wxT(", stats_reset AS ") + qtIdent(_("Last statistics reset")) + + wxT(", slave.confl_tablespace AS ") + qtIdent(_("Tablespace conflicts")) + + wxT(", slave.confl_lock AS ") + qtIdent(_("Lock conflicts")) + + wxT(", slave.confl_snapshot AS ") + qtIdent(_("Snapshot conflicts")) + + wxT(", slave.confl_bufferpin AS ") + qtIdent(_("Bufferpin conflicts")) + + wxT(", slave.confl_deadlock AS ") + qtIdent(_("Deadlock conflicts")); + + if (connection()->BackendMinimumVersion(9, 2)) + sql += wxT(", temp_files AS ") + qtIdent(_("Temporary files")) + + wxT(", pg_size_pretty(temp_bytes) AS ") + qtIdent(_("Size of temporary files")) + + wxT(", deadlocks AS ") + qtIdent(_("Deadlocks")) + + wxT(", blk_read_time AS ") + qtIdent(_("Block read time")) + + wxT(", blk_write_time AS ") + qtIdent(_("Block write time")); + + if (hasSize) + sql += wxT(", pg_size_pretty(pg_database_size(db.datid)) AS ") + qtIdent(_("Size")); + + sql += wxT("\n FROM pg_stat_database db"); + if (connection()->BackendMinimumVersion(9, 1)) + sql += wxT(" JOIN pg_stat_database_conflicts slave ON db.datid=slave.datid"); + sql += wxT(" WHERE db.datname=") + qtDbString(GetName()); + + // DisplayStatistics is not available for this object + + CreateListColumns(statistics, _("Statistic"), _("Value")); + + pgSet *stats = connection()->ExecuteSet(sql); + + if (stats) + { + int col; + for (col = 0 ; col < stats->NumCols() ; col++) + { + if (!stats->ColName(col).IsEmpty()) + statistics->AppendItem(stats->ColName(col), stats->GetVal(col)); + } + delete stats; + } + } +} + + +pgSet *pgDatabase::ExecuteSet(const wxString &sql) +{ + pgSet *set = 0; + if (connection()) + { + set = connection()->ExecuteSet(sql); + if (!set) + CheckAlive(); + } + return set; +} + + +wxString pgDatabase::ExecuteScalar(const wxString &sql) +{ + wxString str; + if (connection()) + { + str = connection()->ExecuteScalar(sql); + if (str.IsEmpty() && connection()->GetLastResultStatus() != PGRES_TUPLES_OK) + CheckAlive(); + } + return str; +} + + +bool pgDatabase::ExecuteVoid(const wxString &sql, bool reportError) +{ + bool rc = 0; + if (connection()) + { + rc = connection()->ExecuteVoid(sql, reportError); + if (!rc) + CheckAlive(); + } + return rc; +} + + +void pgDatabase::UpdateDefaultSchema() +{ + searchPath = connection()->ExecuteScalar(wxT("SHOW search_path")); + + if (!searchPath.IsEmpty()) + { + wxStringTokenizer tk(searchPath, wxT(",")); + pgSet *set = ExecuteSet(wxT("SELECT nspname, session_user=nspname AS isuser FROM pg_namespace")); + if (set) + { + while (tk.HasMoreTokens()) + { + wxString str = tk.GetNextToken(); + str.Strip(wxString::both); + + if (str.IsEmpty()) + continue; + long row; + for (row = 1 ; row <= set->NumRows() ; row++) + { + set->Locate(row); + defaultSchema = set->GetVal(wxT("nspname")); + if (str == defaultSchema || + ((str == wxT("$user") || str == wxT("\"$user\"")) && set->GetBool(wxT("isuser")))) + { + delete set; + return; + } + } + } + delete set; + } + } + defaultSchema = wxEmptyString; +} + + +wxString pgDatabase::GetSchemaPrefix(const wxString &name) const +{ + if (name.IsEmpty()) + return name; + + if (name == wxT("pg_catalog") || name == defaultSchema) + return wxEmptyString; + + return name + wxT("."); +} + + +wxString pgDatabase::GetQuotedSchemaPrefix(const wxString &name) const +{ + wxString str = GetSchemaPrefix(name); + if (!str.IsEmpty()) + return qtIdent(str.Left(str.Length() - 1)) + wxT("."); + return str; +} + + +bool pgDatabase::GetSystemObject() const +{ + if (server) + { + if (this->GetName() == wxT("template0")) return true; + return (this->GetOid() <= server->GetLastSystemOID()); + } + else + { + return false; + } +} + + +wxArrayString pgDatabase::GetSlonyClusters(ctlTree *browser) +{ + wxArrayString clusters; + + pgCollection *collection = browser->FindCollection(slClusterFactory, GetId()); + if (collection) + { + treeObjectIterator clusterIterator(browser, collection); + + slCluster *cluster; + while ((cluster = (slCluster *)clusterIterator.GetNextObject()) != 0) + clusters.Add(cluster->GetName()); + } + return clusters; +} + + +void pgDatabase::AppendSchemaChange(const wxString &sql) +{ + wxDateTime dt; + dt.Now(); + schemaChanges.Append(wxT("-- ") + DateToStr(dt) + wxT("\n")); + schemaChanges.Append(sql); + schemaChanges.Append(wxT("\n\n")); +} + +bool pgDatabase::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + if (useServerConnection) + { + wxMessageDialog(frame, _("Maintenance database can't be dropped."), + _("Dropping database not allowed"), wxICON_EXCLAMATION | wxOK).ShowModal(); + + return false; + } + Disconnect(); + + bool done = server->ExecuteVoid(wxT("DROP DATABASE ") + GetQuotedIdentifier() + wxT(";")); + if (!done) + Connect(); + + return done; +} + + + +wxString pgDatabase::GetSql(ctlTree *browser) +{ + if (sql.IsEmpty()) + { + // If we can't connect to this database, use the maintenance DB + pgConn *myConn = GetConnection(); + if (!myConn) + myConn = GetServer()->GetConnection(); + + sql = wxT("-- Database: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP DATABASE ") + GetQuotedIdentifier() + wxT(";") + + wxT("\n\nCREATE DATABASE ") + GetQuotedIdentifier() + + wxT("\n WITH OWNER = ") + qtIdent(GetOwner()) + + wxT("\n ENCODING = ") + qtDbString(GetEncoding()); + if (!GetTablespace().IsEmpty()) + sql += wxT("\n TABLESPACE = ") + qtIdent(GetTablespace()); + if (myConn && myConn->BackendMinimumVersion(8, 4)) + { + sql += wxT("\n LC_COLLATE = ") + qtDbString(GetCollate()); + sql += wxT("\n LC_CTYPE = ") + qtDbString(GetCType()); + } + if (myConn && myConn->BackendMinimumVersion(8, 1)) + { + sql += wxT("\n CONNECTION LIMIT = "); + sql << GetConnectionLimit(); + } + sql += wxT(";\n"); + + if (variables.GetCount() > 0) + { + size_t i; + wxString username = wxEmptyString; + wxString parameter = wxEmptyString; + wxString value = wxEmptyString; + + sql += wxT("\n"); + for (i = 0 ; i < variables.GetCount() ; i += 3) + { + username = variables.Item(i); + parameter = variables.Item(i + 1); + value = variables.Item(i + 2); + + if (username.Length() == 0) + { + sql += wxT("ALTER DATABASE ") + GetQuotedFullIdentifier(); + } + else + { + sql += wxT("ALTER ROLE ") + username + wxT(" IN DATABASE ") + GetQuotedFullIdentifier(); + } + + if (parameter != wxT("search_path") && parameter != wxT("temp_tablespaces")) + { + sql += wxT("\n SET ") + parameter + wxT(" = '") + value + wxT("';\n"); + } + else + { + sql += wxT("\n SET ") + parameter + wxT(" = ") + value + wxT(";\n"); + } + } + } + + if (myConn) + { + if (!myConn->BackendMinimumVersion(8, 2)) + sql += GetGrant(wxT("CT")); + else + sql += GetGrant(wxT("CTc")); + } + + sql += wxT("\n") + pgDatabase::GetDefaultPrivileges('r', m_defPrivsOnTables, wxT("")); + sql += pgDatabase::GetDefaultPrivileges('S', m_defPrivsOnSeqs, wxT("")); + sql += pgDatabase::GetDefaultPrivileges('f', m_defPrivsOnFuncs, wxT("")); + sql += pgDatabase::GetDefaultPrivileges('T', m_defPrivsOnTypes, wxT("")); + + sql += GetCommentSql(); + + if (myConn->BackendMinimumVersion(9, 2)) + sql += GetSeqLabelsSql(); + } + return sql; +} + + + +void pgDatabase::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (Connect() == PGCONN_OK) + { + // Set the icon if required + UpdateIcon(browser); + + // Add child nodes if necessary + if (browser->GetChildrenCount(GetId(), false) == 0) + { + wxLogInfo(wxT("Adding child object to database %s"), GetIdentifier().c_str()); + + if (settings->GetDisplayOption(_("Catalogs"))) + browser->AppendCollection(this, catalogFactory); + if (settings->GetDisplayOption(_("Casts"))) + browser->AppendCollection(this, castFactory); + if (connection()->BackendMinimumVersion(9, 3) && settings->GetDisplayOption(_("Event Triggers"))) + browser->AppendCollection(this, eventTriggerFactory); + if (settings->GetDisplayOption(_("Extensions")) && GetConnection()->BackendMinimumVersion(9, 1)) + browser->AppendCollection(this, extensionFactory); + if (settings->GetDisplayOption(_("Foreign Data Wrappers")) && GetConnection()->BackendMinimumVersion(8, 4)) + browser->AppendCollection(this, foreignDataWrapperFactory); + if (settings->GetDisplayOption(_("Languages"))) + browser->AppendCollection(this, languageFactory); + if (settings->GetDisplayOption(_("Synonyms")) && connection()->EdbMinimumVersion(8, 0)) + if (!GetConnection()->BackendMinimumVersion(8, 4)) + browser->AppendCollection(this, synonymFactory); + if (settings->GetDisplayOption(_("Schemas"))) + browser->AppendCollection(this, schemaFactory); + if (settings->GetDisplayOption(_("Slony-I Clusters"))) + browser->AppendCollection(this, slClusterFactory); + + wxString missingFKsql = wxT("SELECT COUNT(*) FROM\n") + wxT(" (SELECT tgargs from pg_trigger tr\n") + wxT(" LEFT JOIN pg_depend dep ON dep.objid=tr.oid AND deptype = 'i'\n") + wxT(" LEFT JOIN pg_constraint co ON refobjid = co.oid AND contype = 'f'\n") + wxT(" WHERE \n"); + if (connection()->BackendMinimumVersion(9, 0)) + missingFKsql += wxT("tgisinternal\n"); + else + missingFKsql += wxT("tgisconstraint\n"); + + missingFKsql += wxT(" AND co.oid IS NULL\n") + wxT(" GROUP BY tgargs\n") + wxT(" HAVING count(1) = 3) AS foo"); + missingFKs = StrToLong(connection()->ExecuteScalar(missingFKsql)); + + // Get configuration + wxString query; + if (connection()->BackendMinimumVersion(9, 0)) + { + query = wxT("WITH configs AS ") + wxT("(SELECT rolname, unnest(setconfig) AS config") + wxT(" FROM pg_db_role_setting s") + wxT(" LEFT JOIN pg_roles r ON r.oid=s.setrole") + wxT(" WHERE s.setdatabase=") + NumToStr(GetOid()) + wxT(")\n") + wxT("SELECT rolname, split_part(config, '=', 1) AS variable, ") + wxT(" replace(config, split_part(config, '=', 1) || '=', '') AS value\n") + wxT("FROM configs"); + } + else + { + wxString query_mydb = wxT("SELECT datconfig FROM pg_database WHERE oid=") + NumToStr(GetOid()); + query = wxT("SELECT '' AS rolname, split_part(config, '=', 1) AS variable,\n") + wxT(" replace(config,split_part(config, '=', 1) || '=', '') AS value\n") + wxT("FROM (\n") + wxT(" SELECT\n") + wxT(" (\n") + wxT(" SELECT datconfig[i]\n") + wxT(" FROM pg_database\n") + wxT(" WHERE oid=") + NumToStr(GetOid()) + wxT("\n") + wxT(" ) AS config\n") + wxT(" FROM generate_series(array_lower((") + query_mydb + wxT("),1), array_upper((") + query_mydb + wxT("),1)) AS i\n") + wxT(" ) configs"); + } + pgSet *configs = connection()->ExecuteSet(query); + if (configs) + { + while (!configs->Eof()) + { + variables.Add(configs->GetVal(wxT("rolname"))); + variables.Add(configs->GetVal(wxT("variable"))); + variables.Add(configs->GetVal(wxT("value"))); + configs->MoveNext(); + } + delete configs; + } + } + } + + GetServer()->iSetLastDatabase(GetName()); + + if (properties) + { + // Setup listview + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), NumToStr(GetOid())); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("ACL"), GetAcl()); + if (!GetPath().IsEmpty()) + properties->AppendItem(_("Path"), GetPath()); + + // We may not actually be connected... + if (GetConnection() && GetConnection()->BackendMinimumVersion(8, 0)) + { + properties->AppendItem(_("Tablespace"), GetTablespace()); + properties->AppendItem(_("Default tablespace"), GetDefaultTablespace()); + } + properties->AppendItem(_("Encoding"), GetEncoding()); + + if (GetConnection() && GetConnection()->BackendMinimumVersion(8, 4)) + { + properties->AppendItem(_("Collation"), GetCollate()); + properties->AppendItem(_("Character type"), GetCType()); + } + + properties->AppendItem(_("Default schema"), defaultSchema); + + if (GetConnection() && GetConnection()->BackendMinimumVersion(9, 0)) + { + properties->AppendItem(_("Default table ACL"), m_defPrivsOnTables); + properties->AppendItem(_("Default sequence ACL"), m_defPrivsOnSeqs); + properties->AppendItem(_("Default function ACL"), m_defPrivsOnFuncs); + } + if (GetConnection() && GetConnection()->BackendMinimumVersion(9, 2)) + properties->AppendItem(_("Default type ACL"), m_defPrivsOnTypes); + + size_t i; + wxString username; + wxString parameter; + wxString value; + for (i = 0 ; i < variables.GetCount() ; i += 3) + { + username = variables.Item(i); + parameter = variables.Item(i + 1); + value = variables.Item(i + 2); + + if (username.Length() == 0) + { + properties->AppendItem(parameter, value); + } + else + { + properties->AppendItem(parameter + wxT(" (role ") + username + wxT(")"), value); + } + } + properties->AppendYesNoItem(_("Allow connections?"), GetAllowConnections()); + properties->AppendYesNoItem(_("Connected?"), GetConnected()); + if (GetConnection() && GetConnection()->BackendMinimumVersion(8, 1)) + { + wxString strConnLimit; + strConnLimit.Printf(wxT("%ld"), GetConnectionLimit()); + properties->AppendItem(_("Connection limit"), strConnLimit); + } + properties->AppendYesNoItem(_("System database?"), GetSystemObject()); + if (GetMissingFKs()) + properties->AppendItem(_("Old style FKs"), GetMissingFKs()); + if (!GetSchemaRestriction().IsEmpty()) + properties->AppendItem(_("Schema restriction"), GetSchemaRestriction()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + if (!GetLabels().IsEmpty()) + { + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); + } + } + } + } + if (form && GetCanHint() && !hintShown) + { + ShowHint(form, false); + } +} + + + +pgObject *pgDatabase::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgDatabase *database = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + database = (pgDatabase *)databaseFactory.CreateObjects(coll, 0, wxT(" WHERE db.oid=") + GetOidStr() + wxT("\n")); + + return database; +} + + +pgObject *pgDatabaseFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgDatabase *database = 0; + + pgSet *databases; + + wxString datcollate, datctype, datconnlimit, seclabelsql; + + if (collection->GetConnection()->BackendMinimumVersion(8, 1)) + { + datconnlimit = wxT(", db.datconnlimit as connectionlimit"); + } + if (collection->GetConnection()->BackendMinimumVersion(8, 4)) + { + datctype = wxT(", db.datctype as ctype"); + datcollate = wxT(", db.datcollate as collate"); + } + if (collection->GetConnection()->BackendMinimumVersion(9, 2)) + { + seclabelsql = wxT(",\n(SELECT array_agg(label) FROM pg_shseclabel sl1 WHERE sl1.objoid=db.oid) AS labels") + wxT(",\n(SELECT array_agg(provider) FROM pg_shseclabel sl2 WHERE sl2.objoid=db.oid) AS providers"); + } + + wxString restr = restriction; + if (!collection->GetServer()->GetDbRestriction().IsEmpty()) + { + if (restr.IsEmpty()) + restr = wxT(" WHERE datname IN ("); + else + restr += wxT(" AND datname IN ("); + + restr += collection->GetServer()->GetDbRestriction() + wxT(")\n"); + } + + // In 9.0+, database config options are in pg_db_role_setting + if (collection->GetConnection()->BackendMinimumVersion(9, 0)) + { + databases = collection->GetServer()->ExecuteSet( + wxT("SELECT db.oid, datname, db.dattablespace AS spcoid, spcname, datallowconn, datacl, ") + wxT("pg_encoding_to_char(encoding) AS serverencoding, pg_get_userbyid(datdba) AS datowner,") + wxT("has_database_privilege(db.oid, 'CREATE') as cancreate, \n") + wxT("current_setting('default_tablespace') AS default_tablespace, \n") + wxT("descr.description\n") + + datconnlimit + datcollate + datctype + seclabelsql + + wxT(" FROM pg_database db\n") + wxT(" LEFT OUTER JOIN pg_tablespace ta ON db.dattablespace=ta.OID\n") + wxT(" LEFT OUTER JOIN pg_shdescription descr ON (db.oid=descr.objoid AND descr.classoid='pg_database'::regclass)\n") + + restr + + wxT(" ORDER BY datname")); + } + else if (collection->GetConnection()->BackendMinimumVersion(8, 0)) + databases = collection->GetServer()->ExecuteSet( + wxT("SELECT db.oid, datname, db.dattablespace AS spcoid, spcname, datallowconn, datacl, ") + wxT("pg_encoding_to_char(encoding) AS serverencoding, pg_get_userbyid(datdba) AS datowner,") + wxT("has_database_privilege(db.oid, 'CREATE') as cancreate, \n") + wxT("current_setting('default_tablespace') AS default_tablespace, \n") + wxT("descr.description\n") + + datconnlimit + datcollate + datctype + + wxT(" FROM pg_database db\n") + wxT(" LEFT OUTER JOIN pg_tablespace ta ON db.dattablespace=ta.OID\n") + wxT(" LEFT OUTER JOIN ") + + wxString(collection->GetConnection()->BackendMinimumVersion(8, 2) ? wxT("pg_shdescription") : wxT("pg_description")) + + wxT(" descr ON (db.oid=descr.objoid AND descr.classoid='pg_database'::regclass)\n") + + restr + + wxT(" ORDER BY datname")); + else + databases = collection->GetServer()->ExecuteSet( + wxT("SELECT db.oid, datname, datpath, datallowconn, datacl, ") + wxT("pg_encoding_to_char(encoding) AS serverencoding, pg_get_userbyid(datdba) AS datowner,") + wxT("has_database_privilege(db.oid, 'CREATE') as cancreate,\n") + wxT("descr.description\n") + wxT(" FROM pg_database db\n") + wxT(" LEFT OUTER JOIN pg_description descr ON (db.oid=descr.objoid AND descr.classoid='pg_database'::regclass)\n") + + restr + + wxT(" ORDER BY datname")); + + if (databases) + { + while (!databases->Eof()) + { + wxString name = databases->GetVal(wxT("datname")); + database = new pgDatabase(name); + database->iSetServer(collection->GetServer()); + database->iSetOid(databases->GetOid(wxT("oid"))); + database->iSetOwner(databases->GetVal(wxT("datowner"))); + database->iSetAcl(databases->GetVal(wxT("datacl"))); + database->iSetEncoding(databases->GetVal(wxT("serverencoding"))); + database->iSetCreatePrivilege(databases->GetBool(wxT("cancreate"))); + database->iSetComment(databases->GetVal(wxT("description"))); + database->iSetAllowConnections(databases->GetBool(wxT("datallowconn"))); + + if (collection->GetConnection()->BackendMinimumVersion(8, 0)) + { + database->iSetTablespace(databases->GetVal(wxT("spcname"))); + database->iSetTablespaceOid(databases->GetOid(wxT("spcoid"))); + if (databases->GetVal(wxT("default_tablespace")) == wxEmptyString || databases->GetVal(wxT("default_tablespace")) == wxT("unset")) + database->iSetDefaultTablespace(databases->GetVal(wxT("spcname"))); + else + database->iSetDefaultTablespace(databases->GetVal(wxT("default_tablespace"))); + } + else + database->iSetPath(databases->GetVal(wxT("datpath"))); + + if (collection->GetConnection()->BackendMinimumVersion(8, 1)) + { + database->iSetConnectionLimit(databases->GetLong(wxT("connectionlimit"))); + } + if (collection->GetConnection()->BackendMinimumVersion(8, 4)) + { + database->iSetCollate(databases->GetVal(wxT("collate"))); + database->iSetCType(databases->GetVal(wxT("ctype"))); + } + + if (collection->GetServer()->GetServerIndex()) + { + wxString value; + settings->Read(wxT("Servers/") + NumToStr(collection->GetServer()->GetServerIndex()) + + wxT("/Databases/") + name + wxT("/SchemaRestriction"), &value, wxEmptyString); + + database->iSetSchemaRestriction(value); + } + + if (collection->GetConnection()->BackendMinimumVersion(9, 2)) + { + database->iSetProviders(databases->GetVal(wxT("providers"))); + database->iSetLabels(databases->GetVal(wxT("labels"))); + } + + // Add the treeview node if required + if (settings->GetShowSystemObjects() || !database->GetSystemObject()) + { + if (browser) + { + int icon; + if (database->GetName() == database->GetServer()->GetDatabaseName()) + icon = databaseFactory.GetIconId(); + else + icon = databaseFactory.GetClosedIconId(); + + browser->AppendItem(collection->GetId(), database->GetIdentifier(), icon, -1, database); + } + else + break; + } + else + delete database; + + databases->MoveNext(); + } + delete databases; + } + return database; +} + +wxString pgDatabase::GetDefaultPrivileges(const wxChar &cType, wxString strDefPrivs, const wxString &strSchema) +{ + wxString strDefPrivsSql; + + if (!strDefPrivs.IsEmpty()) + { + wxString strRole, strPriv, strSupportedPrivs, strType; + strDefPrivs.Replace(wxT("\\\""), wxT("\""), true); + strDefPrivs.Replace(wxT("\\\\"), wxT("\\"), true); + + switch(cType) + { + case 'r': + strType = wxT("TABLES"); + strSupportedPrivs = wxT("arwdDxt"); + break; + case 'S': + strType = wxT("SEQUENCES"); + strSupportedPrivs = wxT("rwU"); + break; + case 'f': + strType = wxT("FUNCTIONS"); + strSupportedPrivs = wxT("X"); + break; + case 'T': + strType = wxT("TYPES"); + strSupportedPrivs = wxT("U"); + break; + default: + return wxT(""); + } + + // Removing starting brace '{' and ending brace '}' + strDefPrivs = strDefPrivs.SubString(1, strDefPrivs.Length() - 1); + + while (pgObject::findUserPrivs(strDefPrivs, strRole, strPriv)) + { + strDefPrivsSql += pgObject::GetDefaultPrivileges(strType, strSupportedPrivs, strSchema, wxT(""), strPriv, qtIdent(strRole)); + + strRole = wxT(""); + strPriv = wxT(""); + } + } + return strDefPrivsSql; +} + +bool pgDatabase::CanCreate() +{ + return GetDatabase()->GetCreatePrivilege(); +} + +bool pgDatabase::CanDebugPlpgsql() +{ + wxString preload_option; + + // Result cache - 0 = not tested, 1 = false, 2 = true. + if (canDebugPlpgsql == 1) + return false; + else if (canDebugPlpgsql == 2) + return true; + + // "show shared_preload_libraries" does not work for other than + // the super users. + if (GetServer()->GetSuperUser()) + { + // Parameter's name depends of the backend's version + if (server->GetConnection()->BackendMinimumVersion(8, 2)) + { + preload_option = wxT("shared_preload_libraries"); + } + else + { + preload_option = wxT("preload_libraries"); + } + + // Check the appropriate plugin is loaded + if (!ExecuteScalar(wxT("SHOW ") + preload_option).Contains(wxT("plugin_debugger"))) + { + canDebugPlpgsql = 1; + return false; + } + } + + if (ExecuteScalar(wxT("SELECT count(*) FROM pg_proc WHERE proname = 'pldbg_get_target_info';")) == wxT("0")) + { + canDebugPlpgsql = 1; + return false; + } + + // If this is EDBAS81, the debuggers will be built into the PLs + // so we don't need to check any further. + if (server->GetConnection()->EdbMinimumVersion(8, 1)) + { + canDebugPlpgsql = 2; + return true; + } + + // On EDBAS82 and PostgreSQL, we need to check to make sure that + // the debugger library is also available. + if (ExecuteScalar(wxT("SELECT count(*) FROM pg_proc WHERE proname = 'plpgsql_oid_debug';")) == wxT("0")) + { + canDebugPlpgsql = 1; + return false; + } + else + { + canDebugPlpgsql = 2; + return true; + } + + return true; +} + +bool pgDatabase::CanDebugEdbspl() +{ + // Result cache - 0 = not tested, 1 = false, 2 = true. + if (canDebugEdbspl == 1) + return false; + else if (canDebugEdbspl == 2) + return true; + + // "show shared_preload_libraries" does not work for other than + // the super users. + if (GetServer()->GetSuperUser()) + { + // Check the appropriate plugin is loaded + + // Before EDBAS92, there was a separate library for SPL and PL/pgSQL. + // Starting with 9.2, EDB uses the community version of pldebugger, + // and support for both languages is built into plugin_debugger.so + wxString library_name; + + if (server->GetConnection()->EdbMinimumVersion(9, 2)) + library_name = wxT("plugin_debugger"); + else + library_name = wxT("plugin_spl_debugger"); + + if (!ExecuteScalar(wxT("SHOW shared_preload_libraries;")).Contains(library_name)) + { + canDebugEdbspl = 1; + return false; + } + } + + if (ExecuteScalar(wxT("SELECT count(*) FROM pg_proc WHERE proname = 'pldbg_get_target_info';")) == wxT("0")) + { + canDebugEdbspl = 1; + return false; + } + + // If this is EDBAS81, the debuggers will be built into the PLs + // so we don't need to check any further. + if (server->GetConnection()->EdbMinimumVersion(8, 1)) + { + canDebugEdbspl = 2; + return true; + } + + // On EDBAS82 and PostgreSQL, we need to check to make sure that + // the debugger library is also available. + if (ExecuteScalar(wxT("SELECT count(*) FROM pg_proc WHERE proname = 'edb_oid_debug';")) == wxT("0")) + { + canDebugEdbspl = 1; + return false; + } + else + { + canDebugEdbspl = 2; + return true; + } + + return true; +} + +pgDatabaseCollection::pgDatabaseCollection(pgaFactory *factory, pgServer *sv) + : pgServerObjCollection(factory, sv) +{ +} + + +wxString pgDatabaseCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on databases"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing databases"); + break; + case STATISTICSREPORT: + message = _("Databases statistics report"); + break; + case OBJSTATISTICS: + message = _("Databases statistics"); + break; + case OBJECTSLISTREPORT: + message = _("Databases list report"); + break; + } + + return message; +} + + +void pgDatabaseCollection::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + wxLogInfo(wxT("Displaying statistics for databases on ") + GetServer()->GetIdentifier()); + + bool hasSize = GetConnection()->HasFeature(FEATURE_SIZE); + + wxString restr; + if (!GetServer()->GetDbRestriction().IsEmpty()) + { + if (restr.IsEmpty()) + restr = wxT(" WHERE db.datname IN ("); + else + restr = wxT(" AND db.datname IN ("); + + restr += GetServer()->GetDbRestriction() + wxT(")\n"); + } + + wxString sql = wxT("SELECT db.datid, db.datname, numbackends, xact_commit, xact_rollback, blks_read, blks_hit"); + + if (GetConnection()->BackendMinimumVersion(8, 3)) + sql += wxT(", tup_returned, tup_fetched, tup_inserted, tup_updated, tup_deleted"); + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += wxT(", stats_reset, slave.confl_tablespace, slave.confl_lock, slave.confl_snapshot, slave.confl_bufferpin, slave.confl_deadlock"); + if (hasSize) + sql += wxT(", pg_size_pretty(pg_database_size(db.datid)) as size"); + + sql += wxT("\n FROM pg_stat_database db\n"); + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += wxT(" JOIN pg_stat_database_conflicts slave ON db.datid=slave.datid\n"); + sql += restr + wxT(" ORDER BY db.datname"); + + // Add the statistics view columns + statistics->ClearAll(); + statistics->AddColumn(_("Database"), 60); + statistics->AddColumn(_("Backends"), 50); + if (hasSize) + statistics->AddColumn(_("Size"), 60); + statistics->AddColumn(_("Xact Committed"), 60); + statistics->AddColumn(_("Xact Rolled Back"), 60); + statistics->AddColumn(_("Blocks Read"), 60); + statistics->AddColumn(_("Blocks Hit"), 60); + if (GetConnection()->BackendMinimumVersion(8, 3)) + { + statistics->AddColumn(_("Tuples Returned"), 60); + statistics->AddColumn(_("Tuples Fetched"), 60); + statistics->AddColumn(_("Tuples Inserted"), 60); + statistics->AddColumn(_("Tuples Updated"), 60); + statistics->AddColumn(_("Tuples Deleted"), 60); + } + if (GetConnection()->BackendMinimumVersion(9, 1)) + { + statistics->AddColumn(_("Last statistics reset"), 60); + statistics->AddColumn(_("Tablespace conflicts"), 60); + statistics->AddColumn(_("Lock conflicts"), 60); + statistics->AddColumn(_("Snapshot conflicts"), 60); + statistics->AddColumn(_("Bufferpin conflicts"), 60); + statistics->AddColumn(_("Deadlock conflicts"), 60); + } + + bool sysobj; + pgSet *stats = GetServer()->ExecuteSet(sql); + if (stats) + { + while (!stats->Eof()) + { + if (stats->GetVal(wxT("datname")) == wxT("template0")) + sysobj = true; + else + sysobj = stats->GetOid(wxT("datid")) <= GetServer()->GetLastSystemOID(); + + if (settings->GetShowSystemObjects() || !sysobj) + { + statistics->InsertItem(statistics->GetItemCount(), stats->GetVal(wxT("datname")), PGICON_STATISTICS); + statistics->SetItem(statistics->GetItemCount() - 1, 1, stats->GetVal(wxT("numbackends"))); + if (hasSize) + statistics->SetItem(statistics->GetItemCount() - 1, 2, stats->GetVal(wxT("size"))); + statistics->SetItem(statistics->GetItemCount() - 1, 2 + (hasSize ? 1 : 0), stats->GetVal(wxT("xact_commit"))); + statistics->SetItem(statistics->GetItemCount() - 1, 3 + (hasSize ? 1 : 0), stats->GetVal(wxT("xact_rollback"))); + statistics->SetItem(statistics->GetItemCount() - 1, 4 + (hasSize ? 1 : 0), stats->GetVal(wxT("blks_read"))); + statistics->SetItem(statistics->GetItemCount() - 1, 5 + (hasSize ? 1 : 0), stats->GetVal(wxT("blks_hit"))); + if (GetConnection()->BackendMinimumVersion(8, 3)) + { + statistics->SetItem(statistics->GetItemCount() - 1, 6 + (hasSize ? 1 : 0), stats->GetVal(wxT("tup_returned"))); + statistics->SetItem(statistics->GetItemCount() - 1, 7 + (hasSize ? 1 : 0), stats->GetVal(wxT("tup_fetched"))); + statistics->SetItem(statistics->GetItemCount() - 1, 8 + (hasSize ? 1 : 0), stats->GetVal(wxT("tup_inserted"))); + statistics->SetItem(statistics->GetItemCount() - 1, 9 + (hasSize ? 1 : 0), stats->GetVal(wxT("tup_updated"))); + statistics->SetItem(statistics->GetItemCount() - 1, 10 + (hasSize ? 1 : 0), stats->GetVal(wxT("tup_deleted"))); + } + if (GetConnection()->BackendMinimumVersion(9, 1)) + { + statistics->SetItem(statistics->GetItemCount() - 1, 11 + (hasSize ? 1 : 0), stats->GetVal(wxT("stats_reset"))); + statistics->SetItem(statistics->GetItemCount() - 1, 12 + (hasSize ? 1 : 0), stats->GetVal(wxT("confl_tablespace"))); + statistics->SetItem(statistics->GetItemCount() - 1, 13 + (hasSize ? 1 : 0), stats->GetVal(wxT("confl_lock"))); + statistics->SetItem(statistics->GetItemCount() - 1, 14 + (hasSize ? 1 : 0), stats->GetVal(wxT("confl_snapshot"))); + statistics->SetItem(statistics->GetItemCount() - 1, 15 + (hasSize ? 1 : 0), stats->GetVal(wxT("confl_bufferpin"))); + statistics->SetItem(statistics->GetItemCount() - 1, 16 + (hasSize ? 1 : 0), stats->GetVal(wxT("confl_deadlock"))); + } + } + stats->MoveNext(); + } + + delete stats; + } +} + + + +///////////////////////////////////////////////////// + +pgDatabaseObjCollection::pgDatabaseObjCollection(pgaFactory *factory, pgDatabase *db) + : pgCollection(factory) +{ + database = db; + server = database->GetServer(); +} + + +bool pgDatabaseObjCollection::CanCreate() +{ + if (IsCollectionForType(PGM_CATALOG)) + return false; + + return GetDatabase()->GetCreatePrivilege(); +} + + +#include "images/database.pngc" +#include "images/database-sm.pngc" +#include "images/databases.pngc" +#include "images/closeddatabase.pngc" +#include "images/closeddatabase-sm.pngc" + +pgDatabaseFactory::pgDatabaseFactory() + : pgServerObjFactory(__("Database"), __("New Database..."), __("Create a new Database."), database_png_img, database_sm_png_img) +{ + metaType = PGM_DATABASE; + closedId = addIcon(closeddatabase_png_img); + smallClosedId = addIcon(closeddatabase_sm_png_img); +} + +pgCollection *pgDatabaseFactory::CreateCollection(pgObject *obj) +{ + return new pgDatabaseCollection(GetCollectionFactory(), (pgServer *)obj); +} + +pgCollection *pgDatabaseObjFactory::CreateCollection(pgObject *obj) +{ + return new pgDatabaseObjCollection(GetCollectionFactory(), (pgDatabase *)obj); +} + + +pgDatabaseFactory databaseFactory; +static pgaCollectionFactory cf(&databaseFactory, __("Databases"), databases_png_img); + + +disconnectDatabaseFactory::disconnectDatabaseFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Disconnec&t database"), _("Disconnect from the selected database.")); +} + + +wxWindow *disconnectDatabaseFactory::StartDialog(frmMain *form, pgObject *obj) +{ + ctlTree *browser = form->GetBrowser(); + pgDatabase *database = (pgDatabase *)obj; + + if (obj->CheckOpenDialogs(browser, browser->GetSelection())) + { + wxString msg = _("There are properties dialogues open for one or more objects that would be refreshed. Please close the properties dialogues and try again."); + wxMessageBox(msg, _("Cannot disconnect database"), wxICON_WARNING | wxOK); + } + else + { + database->Disconnect(); + database->UpdateIcon(browser); + browser->DeleteChildren(obj->GetId()); + browser->SelectItem(browser->GetItemParent(obj->GetId())); + form->execSelChange(browser->GetItemParent(obj->GetId()), true); + } + + return 0; +} + + +bool disconnectDatabaseFactory::CheckEnable(pgObject *obj) +{ + if (obj && obj->IsCreatedBy(databaseFactory)) + return ((pgDatabase *)obj)->GetConnected() && (((pgDatabase *)obj)->GetName() != ((pgDatabase *)obj)->GetServer()->GetDatabaseName()); + + return false; +} diff --git a/schema/pgDatatype.cpp b/schema/pgDatatype.cpp new file mode 100644 index 0000000..1d28ae6 --- /dev/null +++ b/schema/pgDatatype.cpp @@ -0,0 +1,320 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgDatatype.cpp - PostgreSQL Datatypes +// +////////////////////////////////////////////////////////////////////////// + + +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgDatatype.h" +#include "schema/pgDatabase.h" +#include "utils/pgDefs.h" + + +pgDatatype::pgDatatype(const wxString &nsp, const wxString &typname, bool isDup, long numdims, long typmod) +{ + needSchema = isDup; + schema = nsp; + + // Above 7.4, format_type also sends the schema name if it's not included + // in the search_path, so we need to skip it in the typname + if (typname.Contains(schema + wxT("\"."))) + name = typname.Mid(schema.Len() + 3); // "+2" because of the two double quotes + else if (typname.Contains(schema + wxT("."))) + name = typname.Mid(schema.Len() + 1); + else + name = typname; + + if (name.StartsWith(wxT("_"))) + { + if (!numdims) + numdims = 1; + name = name.Mid(1); + } + if (name.Right(2) == wxT("[]")) + { + if (!numdims) + numdims = 1; + name = name.Left(name.Len() - 2); + } + + if (name.StartsWith(wxT("\"")) && name.EndsWith(wxT("\""))) + name = name.Mid(1, name.Len() - 2); + + if (numdims > 0) + { + while (numdims--) + array += wxT("[]"); + } + + if (typmod != -1) + { + length = wxT("("); + if (name == wxT("numeric")) + { + len = (typmod - 4L) >> 16L; + prec = (typmod - 4) & 0xffff; + length += NumToStr(len); + if (prec) + length += wxT(",") + NumToStr(prec); + } + else if (name == wxT("time") || name == wxT("timetz") + || name == wxT("time without time zone") || name == wxT("time with time zone") + || name == wxT("timestamp") || name == wxT("timestamptz") + || name == wxT("timestamp without time zone") || name == wxT("timestamp with time zone") + || name == wxT("bit") || name == wxT("bit varying") || name == wxT("varbit")) + { + prec = 0; + len = typmod; + length += NumToStr(len); + } + else if (name == wxT("interval")) + { + prec = 0; + len = (typmod & 0xffff); + length += NumToStr(len); + } + else if (name == wxT("date")) + { + len = prec = 0; + length = wxT(""); /* Clear Length */ + } + else + { + prec = 0; + len = typmod - 4L; + length += NumToStr(len); + } + + if (length.Length() > 0) + length += wxT(")"); + } + else + len = prec = 0; +} + +// Return the full name of the type, with dimension and array qualifiers +wxString pgDatatype::FullName() const +{ + if (name == wxT("char") && schema == wxT("pg_catalog")) + return wxT("\"char\"") + array; + else if (name == wxT("time with time zone")) + return wxT("time") + length + wxT(" with time zone") + array; + else if (name == wxT("time without time zone")) + return wxT("time") + length + wxT(" without time zone") + array; + else if (name == wxT("timestamp with time zone")) + return wxT("timestamp") + length + wxT(" with time zone") + array; + else if (name == wxT("timestamp without time zone")) + return wxT("timestamp") + length + wxT(" without time zone") + array; + else + return name + length + array; +} + +// Return the quoted full name of the type, with dimension and array qualifiers +wxString pgDatatype::QuotedFullName() const +{ + if (name == wxT("char") && schema == wxT("pg_catalog")) + return wxT("\"char\"") + array; + else if (name == wxT("time with time zone")) + return wxT("time") + length + wxT(" with time zone") + array; + else if (name == wxT("time without time zone")) + return wxT("time") + length + wxT(" without time zone") + array; + else if (name == wxT("timestamp with time zone")) + return wxT("timestamp") + length + wxT(" with time zone") + array; + else if (name == wxT("timestamp without time zone")) + return wxT("timestamp") + length + wxT(" without time zone") + array; + else + return qtTypeIdent(name) + length + array; +} + +wxString pgDatatype::GetSchemaPrefix(pgDatabase *db) const +{ + if (schema.IsEmpty() || (!db && schema == wxT("pg_catalog"))) + return wxEmptyString; + + if (needSchema) + return schema + wxT("."); + + return db->GetSchemaPrefix(schema); +} + + +wxString pgDatatype::GetQuotedSchemaPrefix(pgDatabase *db) const +{ + wxString str = GetSchemaPrefix(db); + if (!str.IsEmpty()) + return qtIdent(str.Left(str.Length() - 1)) + wxT("."); + return str; +} + + +long pgDatatype::GetTypmod(const wxString &name, const wxString &len, const wxString &prec) +{ + if (len.IsEmpty()) + return -1; + if (name == wxT("numeric")) + { + return (((long)StrToLong(len) << 16) + StrToLong(prec)) + 4; + } + else if (name == wxT("time") || name == wxT("timetz") + || name == wxT("time without time zone") || name == wxT("time with time zone") + || name == wxT("timestamp") || name == wxT("timestamptz") + || name == wxT("timestamp without time zone") || name == wxT("timestamp with time zone") + || name == wxT("interval") || name == wxT("bit") || name == wxT("bit varying") || name == wxT("varbit")) + { + return StrToLong(len); + } + else + { + return StrToLong(len) + 4; + } +} + + +DatatypeReader::DatatypeReader(pgDatabase *db, const wxString &condition, bool addSerials) +{ + init(db, condition, addSerials); +} + + +DatatypeReader::DatatypeReader(pgDatabase *db, bool withDomains, bool addSerials) +{ + wxString condition = wxT("typisdefined AND typtype "); + // We don't get pseudotypes here + if (withDomains) + condition += wxT("IN ('b', 'c', 'd', 'e', 'r')"); + else + condition += wxT("IN ('b', 'c', 'e', 'r')"); + + condition += wxT("AND NOT EXISTS (select 1 from pg_class where relnamespace=typnamespace and relname = typname and relkind != 'c') AND (typname not like '_%' OR NOT EXISTS (select 1 from pg_class where relnamespace=typnamespace and relname = substring(typname from 2)::name and relkind != 'c')) "); + + if (!settings->GetShowSystemObjects()) + condition += wxT(" AND nsp.nspname != 'information_schema'"); + init(db, condition, addSerials); +} + +void DatatypeReader::init(pgDatabase *db, const wxString &condition, bool addSerials) +{ + database = db; + wxString sql = wxT("SELECT * FROM (SELECT format_type(t.oid,NULL) AS typname, CASE WHEN typelem > 0 THEN typelem ELSE t.oid END as elemoid, typlen, typtype, t.oid, nspname,\n") + wxT(" (SELECT COUNT(1) FROM pg_type t2 WHERE t2.typname = t.typname) > 1 AS isdup\n") + wxT(" FROM pg_type t\n") + wxT(" JOIN pg_namespace nsp ON typnamespace=nsp.oid\n") + wxT(" WHERE (NOT (typname = 'unknown' AND nspname = 'pg_catalog')) AND ") + condition + wxT("\n"); + + if (addSerials) + { + if (db->GetConnection()->BackendMinimumVersion(9, 2)) + { + sql += wxT(" UNION SELECT 'smallserial', 0, 2, 'b', 0, 'pg_catalog', false\n"); + } + sql += wxT(" UNION SELECT 'bigserial', 0, 8, 'b', 0, 'pg_catalog', false\n"); + sql += wxT(" UNION SELECT 'serial', 0, 4, 'b', 0, 'pg_catalog', false\n"); + } + + sql += wxT(" ) AS dummy ORDER BY nspname <> 'pg_catalog', nspname <> 'public', nspname, 1"); + + set = db->GetConnection()->ExecuteSet(sql); +} + + +bool DatatypeReader::IsDomain() const +{ + return set->GetVal(wxT("typtype")) == 'd'; +} + + +bool DatatypeReader::IsVarlen() const +{ + return set->GetLong(wxT("typlen")) == -1; +} + + +bool DatatypeReader::MaySpecifyLength() const +{ + if (IsDomain()) + return false; + + switch ((long)set->GetOid(wxT("elemoid"))) + { + case PGOID_TYPE_BIT: + case PGOID_TYPE_CHAR: + case PGOID_TYPE_VARCHAR: + case PGOID_TYPE_NUMERIC: + return true; + default: + return false; + } +} + + +bool DatatypeReader::MaySpecifyPrecision() const +{ + if (IsDomain()) + return false; + + switch ((long)set->GetOid(wxT("elemoid"))) + { + case PGOID_TYPE_NUMERIC: + return true; + default: + return false; + } +} + + +pgDatatype DatatypeReader::GetDatatype() const +{ + return pgDatatype(set->GetVal(wxT("nspname")), set->GetVal(wxT("typname")), set->GetBool(wxT("isdup"))); +} + + +wxString DatatypeReader::GetTypename() const +{ + return set->GetVal(wxT("typname")); +} + + +wxString DatatypeReader::GetSchema() const +{ + return set->GetVal(wxT("nspname")); +} + + +wxString DatatypeReader::GetSchemaPrefix() const +{ + if (set->GetBool(wxT("isdup"))) + return set->GetVal(wxT("nspname")) + wxT("."); + else + return database->GetSchemaPrefix(set->GetVal(wxT("nspname"))); +} + + +wxString DatatypeReader::GetQuotedSchemaPrefix() const +{ + if (set->GetBool(wxT("isdup"))) + return qtIdent(set->GetVal(wxT("nspname"))) + wxT("."); + else + return database->GetQuotedSchemaPrefix(set->GetVal(wxT("nspname"))); +} + + +wxString DatatypeReader::GetOidStr() const +{ + return set->GetVal(wxT("oid")); +} + + +OID DatatypeReader::GetOid() const +{ + return set->GetOid(wxT("oid")); +} diff --git a/schema/pgDomain.cpp b/schema/pgDomain.cpp new file mode 100644 index 0000000..2066b35 --- /dev/null +++ b/schema/pgDomain.cpp @@ -0,0 +1,425 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgDomain.cpp - Domain class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "frm/frmMain.h" +#include "utils/misc.h" +#include "schema/pgDomain.h" +#include "schema/pgDatatype.h" + +#include "schema/pgTable.h" +#include "schema/pgColumn.h" +#include "schema/pgIndexConstraint.h" +#include "schema/pgForeignKey.h" +#include "schema/pgCheck.h" +#include "utils/sysSettings.h" +#include "utils/pgfeatures.h" +#include "schema/pgRule.h" +#include "schema/pgTrigger.h" +#include "schema/pgConstraints.h" +#include "schema/gpPartition.h" + + +pgDomain::pgDomain(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, domainFactory, newName) +{ +} + +pgDomain::~pgDomain() +{ +} + +wxString pgDomain::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on domain"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing domain"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop domain \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop domain \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop domain cascaded?"); + break; + case DROPTITLE: + message = _("Drop domain?"); + break; + case PROPERTIESREPORT: + message = _("Domain properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Domain properties"); + break; + case DDLREPORT: + message = _("Domain DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Domain DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Domain dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Domain dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Domain dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Domain dependents"); + break; + } + + return message; +} + + +bool pgDomain::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP DOMAIN ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + +wxString pgDomain::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Domain: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP DOMAIN ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE DOMAIN ") + GetQuotedFullIdentifier() + + wxT("\n AS ") + GetQuotedBasetype(); + if (GetCollationOid() > 0) + sql += wxT("\n COLLATE ") + GetQuotedCollation(); + AppendIfFilled(sql, wxT("\n DEFAULT "), GetDefault()); + // CONSTRAINT Name Dont know where it's stored, may be omitted anyway + if (notNull) + sql += wxT("\n NOT NULL"); + + // Get a count of the constraints. + int consCount = 0; + pgCollection *constraints = browser->FindCollection(checkFactory, GetId()); + if (constraints) + { + constraints->ShowTreeDetail(browser); + treeObjectIterator consIt(browser, constraints); + + pgObject *data; + + while ((data = consIt.GetNextObject()) != 0) + { + data->ShowTreeDetail(browser); + + sql += wxT("\n CONSTRAINT ") + data->GetQuotedIdentifier() + + wxT(" ") + data->GetTypeName().Upper() + + wxT(" ") ; + + switch (data->GetMetaType()) + { + case PGM_CHECK: + sql += wxT("(") + ((pgCheck *)data)->GetDefinition() + wxT(")"); + if (GetDatabase()->BackendMinimumVersion(9, 2) && !((pgCheck *)data)->GetValid()) + sql += wxT(" NOT VALID"); + break; + } + } + } + + sql += wxT(";\n") + + GetOwnerSql(7, 4) + + GetCommentSql(); + + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += GetSeqLabelsSql(); + } + + return sql; +} + + +wxMenu *pgDomain::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + if (schema->GetCreatePrivilege()) + { + checkFactory.AppendMenu(menu); + } + return menu; +} + + +void pgDomain::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + + // Log + wxLogInfo(wxT("Adding child object to domain %s"), GetIdentifier().c_str()); + if (GetConnection()->BackendMinimumVersion(7, 4)) + browser->AppendCollection(this, constraintFactory); + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Base type"), GetBasetype()); + if (GetDimensions()) + properties->AppendItem(_("Dimensions"), GetDimensions()); + if (GetCollationOid() > 0) + properties->AppendItem(_("Collation"), GetQuotedCollation()); + properties->AppendItem(_("Default"), GetDefault()); + properties->AppendYesNoItem(_("Not NULL?"), GetNotNull()); + properties->AppendYesNoItem(_("System domain?"), GetSystemObject()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + if (!GetLabels().IsEmpty()) + { + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); + } + } + } + } +} + + + +pgObject *pgDomain::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *domain = 0; + + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + domain = domainFactory.CreateObjects(coll, 0, wxT(" AND d.oid=") + GetOidStr() + wxT("\n")); + + return domain; +} + + +void pgDomain::Validate(frmMain *form) +{ + wxString sql = wxT("ALTER DOMAIN ") + GetQuotedFullIdentifier() + + wxT("\n VALIDATE CONSTRAINT ") + GetCheckConstraintName(); + GetDatabase()->ExecuteVoid(sql); + + iSetValid(true); + UpdateIcon(form->GetBrowser()); +} + + +//////////////////////////////////////////////////// + + + +pgObject *pgDomainFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + wxString sql; + pgDomain *domain = 0; + + pgDatabase *db = collection->GetDatabase(); + + sql = wxT("SELECT d.oid, d.typname as domname, d.typbasetype, format_type(b.oid,NULL) as basetype, pg_get_userbyid(d.typowner) as domainowner, \n"); + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + sql += wxT("c.oid AS colloid, c.collname, cn.nspname as collnspname, \n"); + sql += wxT(" d.typlen, d.typtypmod, d.typnotnull, d.typdefault, d.typndims, d.typdelim, bn.nspname as basensp,\n") + wxT(" description, (SELECT COUNT(1) FROM pg_type t2 WHERE t2.typname=d.typname) > 1 AS domisdup,\n") + wxT(" (SELECT COUNT(1) FROM pg_type t3 WHERE t3.typname=b.typname) > 1 AS baseisdup"); + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + sql += wxT(",\n(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=d.oid) AS labels"); + sql += wxT(",\n(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=d.oid) AS providers"); + } + sql += wxT("\n FROM pg_type d\n") + wxT(" JOIN pg_type b ON b.oid = d.typbasetype\n") + wxT(" JOIN pg_namespace bn ON bn.oid=b.typnamespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=d.oid AND des.classoid='pg_type'::regclass)\n"); + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + sql += wxT(" LEFT OUTER JOIN pg_collation c ON d.typcollation=c.oid\n") + wxT(" LEFT OUTER JOIN pg_namespace cn ON c.collnamespace=cn.oid\n"); + sql += wxT(" WHERE d.typtype = 'd' AND d.typnamespace = ") + NumToStr(collection->GetSchema()->GetOid()) + wxT("::oid\n") + + restriction + + wxT(" ORDER BY d.typname"); + pgSet *domains = db->ExecuteSet(sql); + + if (domains) + { + while (!domains->Eof()) + { + domain = new pgDomain(collection->GetSchema(), domains->GetVal(wxT("domname"))); + + domain->iSetOid(domains->GetOid(wxT("oid"))); + domain->iSetOwner(domains->GetVal(wxT("domainowner"))); + domain->iSetBasetype(domains->GetVal(wxT("basetype"))); + domain->iSetBasetypeOid(domains->GetOid(wxT("typbasetype"))); + domain->iSetComment(domains->GetVal(wxT("description"))); + long typmod = domains->GetLong(wxT("typtypmod")); + + pgDatatype dt(domains->GetVal(wxT("basensp")), domains->GetVal(wxT("basetype")), + domains->GetBool(wxT("baseisdup")), domains->GetLong(wxT("typndims")), typmod); + + domain->iSetTyplen(domains->GetLong(wxT("typlen"))); + domain->iSetTypmod(typmod); + domain->iSetLength(dt.Length()); + domain->iSetPrecision(dt.Precision()); + domain->iSetBasetype(dt.GetSchemaPrefix(db) + dt.FullName()); + domain->iSetQuotedBasetype(dt.GetQuotedSchemaPrefix(db) + dt.QuotedFullName()); + domain->iSetDefault(domains->GetVal(wxT("typdefault"))); + domain->iSetNotNull(domains->GetBool(wxT("typnotnull"))); + domain->iSetDimensions(domains->GetLong(wxT("typndims"))); + domain->iSetDelimiter(domains->GetVal(wxT("typdelim"))); + domain->iSetIsDup(domains->GetBool(wxT("domisdup"))); + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + domain->iSetCollation(domains->GetVal(wxT("collname"))); + domain->iSetQuotedCollation(qtIdent(domains->GetVal(wxT("collnspname"))) + wxT(".") + qtIdent(domains->GetVal(wxT("collname")))); + domain->iSetCollationOid(domains->GetOid(wxT("colloid"))); + } + else + domain->iSetCollationOid(0); + + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + domain->iSetProviders(domains->GetVal(wxT("providers"))); + domain->iSetLabels(domains->GetVal(wxT("labels"))); + } + + // we suppose the constraint valid now + // this is checked in ShowTreeDetail for each domain + domain->iSetValid(true); + + if (browser) + { + browser->AppendObject(collection, domain); + domains->MoveNext(); + } + else + break; + } + + delete domains; + } + return domain; +} + +///////////////////////////// + +pgDomainCollection::pgDomainCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgDomainCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on domains"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing domains"); + break; + case OBJECTSLISTREPORT: + message = _("Domains list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/domain.pngc" +#include "images/domain-sm.pngc" +#include "images/domains.pngc" + +pgDomainFactory::pgDomainFactory() + : pgSchemaObjFactory(__("Domain"), __("New Domain..."), __("Create a new Domain."), domain_png_img, domain_sm_png_img) +{ + metaType = PGM_DOMAIN; +} + + +pgCollection *pgDomainFactory::CreateCollection(pgObject *obj) +{ + return new pgDomainCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgDomainFactory domainFactory; +static pgaCollectionFactory cf(&domainFactory, __("Domains"), domains_png_img); + +validateDomainCheckFactory::validateDomainCheckFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Validate domain check constraint"), _("Validate the selected domain check constraint.")); +} + + +wxWindow *validateDomainCheckFactory::StartDialog(frmMain *form, pgObject *obj) +{ + ((pgDomain *)obj)->Validate(form); + ((pgDomain *)obj)->SetDirty(); + + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + { + obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties()); + form->GetSqlPane()->SetReadOnly(false); + form->GetSqlPane()->SetText(((pgDomain *)obj)->GetSql(form->GetBrowser())); + form->GetSqlPane()->SetReadOnly(true); + } + form->GetMenuFactories()->CheckMenu(obj, form->GetMenuBar(), (ctlMenuToolbar *)form->GetToolBar()); + + return 0; +} + + +bool validateDomainCheckFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(domainFactory) && obj->CanEdit() + && ((pgDomain *)obj)->GetConnection()->BackendMinimumVersion(9, 2) + && !((pgDomain *)obj)->GetValid(); +} + diff --git a/schema/pgEventTrigger.cpp b/schema/pgEventTrigger.cpp new file mode 100644 index 0000000..2856dda --- /dev/null +++ b/schema/pgEventTrigger.cpp @@ -0,0 +1,350 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgEventTrigger.cpp - EventTrigger class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "frm/frmMain.h" +#include "utils/misc.h" +#include "schema/pgEventTrigger.h" +#include "schema/pgFunction.h" +#include "schema/pgSchema.h" + +pgEventTrigger::pgEventTrigger(const wxString &newName) + : pgDatabaseObject(eventTriggerFactory, newName) +{ + eventTriggerFunction = 0; + eventTriggerFunctionSchema = 0; +} + +pgEventTrigger::~pgEventTrigger() +{ + if (!expandedKids && eventTriggerFunction) + { + // eventTriggerFunction wasn't appended to tree, so we need to delete it manually. + delete eventTriggerFunction; + } + + delete eventTriggerFunctionSchema; +} + +pgCollection *pgEventTriggerFactory::CreateCollection(pgObject *obj) +{ + return new pgEventTriggerCollection(GetCollectionFactory(), (pgDatabase *)obj); +} + +pgObject *pgEventTriggerFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + wxString sql; + pgEventTrigger *eventTrigger = 0; + + sql = wxT("SELECT e.oid, e.xmin, e.evtname AS name, REPLACE(e.evtevent, '_', ' ') AS eventname, pg_catalog.pg_get_userbyid(e.evtowner) AS eventowner, ") + wxT(" CASE e.evtenabled WHEN 'O' THEN 'enabled' WHEN 'R' THEN 'replica' WHEN 'A' THEN 'always' WHEN 'D' THEN 'disabled' END AS enabled, ") + wxT(" e.evtfoid AS eventfuncoid, e.evtfoid::regproc AS eventfunname, array_to_string(array(select quote_literal(x) from unnest(evttags) as t(x)), ', ') AS when, ") + wxT(" pg_catalog.obj_description(e.oid, 'pg_event_trigger') AS comment, ") + wxT(" p.prosrc AS source, p.pronamespace AS schemaoid, l.lanname AS language") + wxT(" FROM pg_event_trigger e\n") + wxT(" LEFT OUTER JOIN pg_proc p ON p.oid=e.evtfoid\n") + wxT(" LEFT OUTER JOIN pg_language l ON l.oid=p.prolang\n") + wxT(" WHERE 1=1 "); + + if (!restriction.IsEmpty()) + sql += restriction + wxT("\n"); + sql += wxT(" ORDER BY e.evtname "); + + pgSet *eventTriggers = collection->GetDatabase()->ExecuteSet(sql); + + if (eventTriggers) + { + while (!eventTriggers->Eof()) + { + eventTrigger = new pgEventTrigger(eventTriggers->GetVal(wxT("name"))); + eventTrigger->iSetDatabase(collection->GetDatabase()); + eventTrigger->iSetOid(eventTriggers->GetOid(wxT("oid"))); + eventTrigger->iSetXid(eventTriggers->GetOid(wxT("xmin"))); + eventTrigger->iSetOwner(eventTriggers->GetVal(wxT("eventowner"))); + eventTrigger->iSetFunctionOid(eventTriggers->GetOid(wxT("eventfuncoid"))); + eventTrigger->iSetLanguage(eventTriggers->GetVal(wxT("language"))); + eventTrigger->iSetSource(eventTriggers->GetVal(wxT("source"))); + eventTrigger->iSetEventName(eventTriggers->GetVal(wxT("eventname"))); + eventTrigger->iSetFunction(eventTriggers->GetVal(wxT("eventfunname"))); + (eventTriggers->GetVal(wxT("enabled")) == wxT("disabled")) ? eventTrigger->iSetEnabled(false), eventTrigger->iSetEnableStatus(wxT("disabled")) + : eventTrigger->iSetEnabled(true), eventTrigger->iSetEnableStatus(eventTriggers->GetVal(wxT("enabled"))); + eventTrigger->iSetComment(eventTriggers->GetVal(wxT("comment"))); + eventTrigger->iSetWhen(eventTriggers->GetVal(wxT("when"))); + eventTrigger->iSetSchemaOid(eventTriggers->GetOid(wxT("schemaoid"))); + + if (browser) + { + browser->AppendObject(collection, eventTrigger); + eventTriggers->MoveNext(); + } + else + break; + } + + delete eventTriggers; + } + return eventTrigger; +} + +pgObject *pgEventTrigger::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *eventTrigger = 0; + pgCollection *coll = browser->GetParentCollection(item); + + if (coll) + { + wxString restr = wxT(" \n AND e.oid = ") + GetOidStr(); + eventTrigger = eventTriggerFactory.CreateObjects(coll, 0, restr); + } + return eventTrigger; +} + +void pgEventTrigger::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids && GetLanguage() != wxT("edbspl") && GetLanguage() != wxT("sql")) + { + if (browser) + { + // if no browser present, function will not be appended to tree + expandedKids = true; + } + + if (eventTriggerFunction) + delete eventTriggerFunction; + + wxString restr = wxT(" WHERE nsp.oid= ") + NumToStr(GetSchemaOid()) + wxT("::oid\n"); + eventTriggerFunctionSchema = (pgSchema *)schemaFactory.CreateObjects((pgCollection *)browser->GetObject(browser->GetSelection()), 0, restr); + + // append function here + eventTriggerFunction = functionFactory.AppendFunctions(this, eventTriggerFunctionSchema, browser, wxT(" WHERE pr.oid = ") + NumToStr(functionOid) + wxT("::oid\n")); + if (eventTriggerFunction) + { + iSetFunction(eventTriggerFunction->GetQuotedFullIdentifier()); + } + + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Event"), GetEventName()); + properties->AppendItem(_("Function"), GetFunction()); + properties->AppendItem(_("When?"), GetWhen()); + properties->AppendItem(_("Enabled?"), GetEnabled() ? wxT("Yes") : wxT("No")); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + +void pgEventTrigger::SetDirty() +{ + if (expandedKids) + eventTriggerFunction = 0; + pgObject::SetDirty(); +} + +wxString pgEventTrigger::GetSql(ctlTree *browser) +{ + if (sql.IsNull() && (this->eventTriggerFunction)) + { + sql = wxT("-- Event Trigger: ") + qtIdent(GetName()) + wxT(" on database ") + + qtIdent(((pgCollection *)browser->GetObject(browser->GetSelection()))->GetDatabase()->GetName()) + wxT("\n\n") + + wxT("-- DROP EVENT TRIGGER ") + qtIdent(GetName()) + wxT(";\n\n"); + + sql += wxT("CREATE EVENT TRIGGER ") + qtIdent(GetName()) + wxT(" ON ") + + GetEventName() + (GetWhen().IsEmpty() ? wxT("") : (wxT(" WHEN TAG IN (") + GetWhen() + wxT(")\n\n"))); + + // Event trigger backend function don't accept any arguments. + // Hence, it's not required to get/set empty arguments. + + sql += wxT(" EXECUTE PROCEDURE ") + eventTriggerFunction->GetQuotedFullIdentifier() + wxT("();\n\n"); + + if (!GetEnabled()) + { + sql += wxT("ALTER EVENT TRIGGER ") + qtIdent(GetName()) + wxT(" DISABLE;\n"); + } + + if (!GetComment().IsEmpty()) + sql += wxT("COMMENT ON EVENT TRIGGER ") + qtIdent(GetName()) + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + return sql; +} + +wxString pgEventTrigger::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on event trigger"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing event trigger"); + message += wxT(" ") + GetName(); + break; + case DROPCASCADETITLE: + message = _("Drop event trigger cascaded?"); + break; + case DROPTITLE: + message = _("Drop event trigger?"); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop event trigger \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop event trigger \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case PROPERTIESREPORT: + message = _("Event trigger properties report"); + message += wxT(" - ") + GetName(); + break; + case DDLREPORT: + message = _("Event trigger DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Event trigger DDL"); + break; + } + return message; +} + +int pgEventTrigger::GetIconId() +{ + if (GetEnabled()) + return eventTriggerFactory.GetIconId(); + else + return eventTriggerFactory.GetClosedIconId(); +} + + +wxString pgEventTriggerCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on event triggers"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing event triggers"); + break; + case OBJECTSLISTREPORT: + message = _("Event triggers list report"); + break; + } + return message; +} + +bool pgEventTrigger::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP EVENT TRIGGER ") + qtIdent(GetName()); + if (cascaded) + sql += wxT(" CASCADE"); + sql += wxT(" ;"); + + return GetDatabase()->ExecuteVoid(sql); +} + +void pgEventTrigger::SetEnabled(ctlTree *browser, const bool b) +{ + if (qtIdent(GetName()).Len() > 0 && ((enabled && !b) || (!enabled && b))) + { + wxString sql = wxT("ALTER EVENT TRIGGER ") + qtIdent(GetName()) ; + if (enabled && !b) + sql += wxT(" DISABLE"); + else if (!enabled && b) + sql += wxT(" ENABLE"); + GetDatabase()->ExecuteVoid(sql); + } + enabled = b; + UpdateIcon(browser); +} + +bool pgEventTrigger::IsUpToDate() +{ + wxString sql = wxT("SELECT xmin FROM pg_event_trigger WHERE oid = ") + this->GetOidStr(); + if (!this->GetDatabase()->GetConnection() || this->GetDatabase()->ExecuteScalar(sql) != NumToStr(GetXid())) + return false; + else + return true; +} + +///////////////////////////// + +pgEventTriggerCollection::pgEventTriggerCollection(pgaFactory *factory, pgDatabase *db) + : pgDatabaseObjCollection(factory, db) +{ + +} + + +/////////////////////////////////////////////////// + +#include "images/trigger.pngc" +#include "images/triggerbad.pngc" +#include "images/triggers.pngc" + +pgEventTriggerFactory::pgEventTriggerFactory() + : pgDatabaseObjFactory(__("Event Trigger"), __("New Event Trigger..."), __("Create a new Event Trigger."), trigger_png_img) +{ + metaType = PGM_EVENTTRIGGER; + closedId = addIcon(triggerbad_png_img); +} + +pgEventTriggerFactory eventTriggerFactory; +static pgaCollectionFactory cf(&eventTriggerFactory, __("Event Triggers"), triggers_png_img); + +enabledisableEventTriggerFactory::enabledisableEventTriggerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Event trigger enabled?"), _("Enable or disable selected event trigger."), wxITEM_CHECK); +} + +wxWindow *enabledisableEventTriggerFactory::StartDialog(frmMain *form, pgObject *obj) +{ + ((pgEventTrigger *)obj)->SetEnabled(form->GetBrowser(), !((pgEventTrigger *)obj)->GetEnabled()); + ((pgEventTrigger *)obj)->SetDirty(); + + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + { + form->GetBrowser()->DeleteChildren(item); + obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties()); + form->GetSqlPane()->SetReadOnly(false); + form->GetSqlPane()->SetText(((pgEventTrigger *)obj)->GetSql(form->GetBrowser())); + form->GetSqlPane()->SetReadOnly(true); + } + form->GetMenuFactories()->CheckMenu(obj, form->GetMenuBar(), (ctlMenuToolbar *)form->GetToolBar()); + + return 0; +} + +bool enabledisableEventTriggerFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(eventTriggerFactory) && obj->CanEdit() + && ((pgEventTrigger *)obj)->GetConnection()->BackendMinimumVersion(9, 3); +} + +bool enabledisableEventTriggerFactory::CheckChecked(pgObject *obj) +{ + return obj && obj->IsCreatedBy(eventTriggerFactory) && ((pgEventTrigger *)obj)->GetEnabled(); +} \ No newline at end of file diff --git a/schema/pgExtension.cpp b/schema/pgExtension.cpp new file mode 100644 index 0000000..fd90b44 --- /dev/null +++ b/schema/pgExtension.cpp @@ -0,0 +1,234 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgExtension.cpp - Extension class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgExtension.h" + + +pgExtension::pgExtension(const wxString &newName) + : pgDatabaseObject(extensionFactory, newName) +{ +} + +wxString pgExtension::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on extension"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing extension"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop extension \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop extension \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop extension cascaded?"); + break; + case DROPTITLE: + message = _("Drop extension?"); + break; + case PROPERTIESREPORT: + message = _("Extension properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Extension properties"); + break; + case DDLREPORT: + message = _("Extension DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Extension DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Extension dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Extension dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Extension dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Extension dependents"); + break; + } + + return message; +} + +bool pgExtension::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP EXTENSION ") + GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgExtension::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Extension: ") + GetQuotedIdentifier() + wxT("\n\n") + + wxT("-- DROP EXTENSION ") + GetQuotedIdentifier() + wxT(";") + + wxT("\n\n CREATE EXTENSION ") + GetName(); + + if (!GetSchemaStr().IsEmpty()) + sql += wxT("\n SCHEMA ") + qtIdent(GetSchemaStr()); + if (!GetVersion().IsEmpty()) + sql += wxT("\n VERSION ") + qtIdent(GetVersion()); + + sql += wxT(";\n"); + } + return sql; +} + + +void pgExtension::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Schema"), GetSchemaStr()); + properties->AppendYesNoItem(_("Relocatable?"), GetIsRelocatable()); + properties->AppendItem(_("Version"), GetVersion()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgExtension::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *language = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + language = extensionFactory.CreateObjects(coll, 0, wxT("\n AND x.oid=") + GetOidStr()); + + return language; +} + + + +pgObject *pgExtensionFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + wxString sql; + pgExtension *extension = 0; + + sql = wxT("select x.oid, pg_get_userbyid(extowner) AS owner, x.extname, n.nspname, x.extrelocatable, x.extversion, e.comment") + wxT(" FROM pg_extension x\n") + wxT(" JOIN pg_namespace n on x.extnamespace=n.oid\n") + wxT(" join pg_available_extensions() e(name, default_version, comment) ON x.extname=e.name\n") + + restriction + wxT("\n") + wxT(" ORDER BY x.extname"); + pgSet *extensions = collection->GetDatabase()->ExecuteSet(sql); + + if (extensions) + { + while (!extensions->Eof()) + { + + extension = new pgExtension(extensions->GetVal(wxT("extname"))); + extension->iSetDatabase(collection->GetDatabase()); + extension->iSetOid(extensions->GetOid(wxT("oid"))); + extension->iSetOwner(extensions->GetVal(wxT("owner"))); + extension->iSetSchemaStr(extensions->GetVal(wxT("nspname"))); + extension->iSetIsRelocatable(extensions->GetBool(wxT("extrelocatable"))); + extension->iSetVersion(extensions->GetVal(wxT("extversion"))); + extension->iSetComment(extensions->GetVal(wxT("comment"))); + + if (browser) + { + browser->AppendObject(collection, extension); + + extensions->MoveNext(); + } + else + break; + } + + delete extensions; + } + return extension; +} + + +///////////////////////////// + +pgExtensionCollection::pgExtensionCollection(pgaFactory *factory, pgDatabase *db) + : pgDatabaseObjCollection(factory, db) +{ +} + + +wxString pgExtensionCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on extensions"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing extensions"); + break; + case OBJECTSLISTREPORT: + message = _("Extensions list report"); + break; + } + + return message; +} + +/////////////////////////////////////////////////// + +#include "images/extension.pngc" +#include "images/extension-sm.pngc" +#include "images/extensions.pngc" + +pgExtensionFactory::pgExtensionFactory() + : pgDatabaseObjFactory(__("Extension"), __("New Extension..."), __("Create a new Extension."), extension_png_img, extension_sm_png_img) +{ +} + + +pgCollection *pgExtensionFactory::CreateCollection(pgObject *obj) +{ + return new pgExtensionCollection(GetCollectionFactory(), (pgDatabase *)obj); +} + +pgExtensionFactory extensionFactory; +static pgaCollectionFactory cf(&extensionFactory, __("Extensions"), extensions_png_img); diff --git a/schema/pgForeignDataWrapper.cpp b/schema/pgForeignDataWrapper.cpp new file mode 100644 index 0000000..1d9e2e2 --- /dev/null +++ b/schema/pgForeignDataWrapper.cpp @@ -0,0 +1,408 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgForeignDataWrapper.cpp - Foreign Data Wrapper class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgForeignDataWrapper.h" +#include "schema/pgForeignServer.h" + + +pgForeignDataWrapper::pgForeignDataWrapper(const wxString &newName) + : pgDatabaseObject(foreignDataWrapperFactory, newName) +{ +} + + +wxString pgForeignDataWrapper::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on foreign data wrapper"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing foreign data wrapper"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop foreign data wrapper \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop foreign data wrapper \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop foreign data wrapper cascaded?"); + break; + case DROPTITLE: + message = _("Drop foreign data wrapper?"); + break; + case PROPERTIESREPORT: + message = _("Foreign data wrapper properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Foreign data wrapper properties"); + break; + case DDLREPORT: + message = _("Foreign data wrapper DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Foreign data wrapper DDL"); + break; + case STATISTICSREPORT: + message = _("Foreign data wrapper statistics report"); + message += wxT(" - ") + GetName(); + break; + case OBJSTATISTICS: + message = _("Foreign data wrapper statistics"); + break; + case DEPENDENCIESREPORT: + message = _("Foreign data wrapper dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Foreign data wrapper dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Foreign data wrapper dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Foreign data wrapper dependents"); + break; + } + + return message; +} + + +bool pgForeignDataWrapper::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP FOREIGN DATA WRAPPER ") + GetQuotedFullIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgForeignDataWrapper::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Foreign Data Wrapper: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP FOREIGN DATA WRAPPER ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE "); + sql += wxT("FOREIGN DATA WRAPPER ") + GetName(); + + if (!GetHandlerProc().IsEmpty()) + sql += wxT("\n HANDLER ") + GetHandlerProc(); + + if (!GetValidatorProc().IsEmpty()) + sql += wxT("\n VALIDATOR ") + GetValidatorProc(); + + if (!GetOptions().IsEmpty()) + sql += wxT("\n OPTIONS (") + GetCreateOptions() + wxT(")"); + + sql += wxT(";\n") + + GetOwnerSql(8, 4, wxT("FOREIGN DATA WRAPPER ") + GetName()) + + GetGrant(wxT("U"), wxT("FOREIGN DATA WRAPPER ") + GetQuotedFullIdentifier()); + } + return sql; +} + + +void pgForeignDataWrapper::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + + // Log + wxLogInfo(wxT("Adding child object to foreign data wrapper %s"), GetIdentifier().c_str()); + + if (settings->GetDisplayOption(_("Foreign Servers"))) + browser->AppendCollection(this, foreignServerFactory); + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("ACL"), GetAcl()); + properties->AppendItem(_("Handler"), GetHandlerProc()); + properties->AppendItem(_("Validator"), GetValidatorProc()); + properties->AppendItem(_("Options"), GetOptions()); + } +} + + + +pgObject *pgForeignDataWrapper::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *fdw = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + fdw = foreignDataWrapperFactory.CreateObjects(coll, 0, wxT("\n WHERE fdw.oid=") + GetOidStr()); + + return fdw; +} + + + +wxMenu *pgForeignDataWrapper::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + if (database->GetCreatePrivilege()) + { + foreignServerFactory.AppendMenu(menu); + } + return menu; +} + + +pgObject *pgForeignDataWrapperFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + wxString sql; + pgForeignDataWrapper *fdw = 0; + + bool fdwHandlerSupport = (collection->GetDatabase()->BackendMinimumVersion(9, 1)); + + if(fdwHandlerSupport) + { + + sql = wxT("SELECT fdw.oid, fdwname, fdwhandler, fdwvalidator, fdwacl, ") + wxT("vh.proname as fdwhan, vp.proname as fdwval, description, ") + wxT("array_to_string(fdwoptions, ',') AS fdwoptions, ") + wxT("pg_get_userbyid(fdwowner) as fdwowner\n"); + sql += wxT(" FROM pg_foreign_data_wrapper fdw\n") + wxT(" LEFT OUTER JOIN pg_proc vh on vh.oid=fdwhandler\n") + wxT(" LEFT OUTER JOIN pg_proc vp on vp.oid=fdwvalidator\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=fdw.oid AND des.objsubid=0 AND des.classoid='pg_foreign_data_wrapper'::regclass)\n") + + restriction + wxT("\n") + wxT(" ORDER BY fdwname"); + } + else + { + + sql = wxT("SELECT fdw.oid, fdwname, fdwvalidator, fdwacl, ") + wxT("vp.proname as fdwval, description, ") + wxT("array_to_string(fdwoptions, ',') AS fdwoptions, ") + wxT("pg_get_userbyid(fdwowner) as fdwowner\n"); + sql += wxT(" FROM pg_foreign_data_wrapper fdw\n") + wxT(" LEFT OUTER JOIN pg_proc vp on vp.oid=fdwvalidator\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=fdw.oid AND des.objsubid=0 AND des.classoid='pg_foreign_data_wrapper'::regclass)\n") + + restriction + wxT("\n") + wxT(" ORDER BY fdwname"); + } + pgSet *fdws = collection->GetDatabase()->ExecuteSet(sql); + + if (fdws) + { + while (!fdws->Eof()) + { + + fdw = new pgForeignDataWrapper(fdws->GetVal(wxT("fdwname"))); + fdw->iSetDatabase(collection->GetDatabase()); + fdw->iSetOid(fdws->GetOid(wxT("oid"))); + fdw->iSetOwner(fdws->GetVal(wxT("fdwowner"))); + fdw->iSetAcl(fdws->GetVal(wxT("fdwacl"))); + if(fdwHandlerSupport) + fdw->iSetHandlerProc(fdws->GetVal(wxT("fdwhan"))); + fdw->iSetValidatorProc(fdws->GetVal(wxT("fdwval"))); + fdw->iSetOptions(fdws->GetVal(wxT("fdwoptions"))); + + if (browser) + { + browser->AppendObject(collection, fdw); + + fdws->MoveNext(); + } + else + break; + } + + delete fdws; + } + return fdw; +} + + +wxString pgForeignDataWrapper::GetCreateOptions() +{ + wxString options_create = wxEmptyString; + wxString opt; + wxString val; + + wxStringTokenizer tkz_options(options, wxT(",")); + while (tkz_options.HasMoreTokens()) + { + wxStringTokenizer tkz_option(tkz_options.GetNextToken(), wxT("=")); + opt = tkz_option.GetNextToken(); + val = tkz_option.GetNextToken(); + + if (!options_create.IsEmpty()) + options_create += wxT(","); + + options_create += opt + wxT(" '") + val + wxT("'"); + } + + return options_create; +} + + +/////////////////////////////////////////////////////////////// + +void pgForeignDataWrapperObject::SetForeignDataWrapper(pgForeignDataWrapper *newForeignDataWrapper) +{ + fdw = newForeignDataWrapper; + database = fdw->GetDatabase(); +} + +bool pgForeignDataWrapperObject::CanDrop() +{ + return true; //fdw->GetCreatePrivilege(); +} + + +bool pgForeignDataWrapperObject::CanCreate() +{ + return true; //fdw->GetCreatePrivilege(); +} + + +void pgForeignDataWrapperObject::SetContextInfo(frmMain *form) +{ +} + + +pgSet *pgForeignDataWrapperObject::ExecuteSet(const wxString &sql) +{ + return fdw->GetDatabase()->ExecuteSet(sql); +} + +wxString pgForeignDataWrapperObject::ExecuteScalar(const wxString &sql) +{ + return fdw->GetDatabase()->ExecuteScalar(sql); +} + + +bool pgForeignDataWrapperObject::ExecuteVoid(const wxString &sql) +{ + return fdw->GetDatabase()->ExecuteVoid(sql); +} + + +///////////////////////////////////////////////////// + +pgForeignDataWrapperObjCollection::pgForeignDataWrapperObjCollection(pgaFactory *factory, pgForeignDataWrapper *newfdw) + : pgCollection(factory) +{ + fdw = newfdw; + database = fdw->GetDatabase(); + server = database->GetServer(); + iSetOid(fdw->GetOid()); +} + + +wxString pgForeignDataWrapperObjCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on foreign data wrappers"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing foreign data wrappers"); + break; + case OBJECTSLISTREPORT: + message = _("Foreign data wrappers list report"); + break; + } + + return message; +} + +bool pgForeignDataWrapperObjCollection::CanCreate() +{ + return GetDatabase()->GetCreatePrivilege(); +} + + +pgCollection *pgForeignDataWrapperObjFactory::CreateCollection(pgObject *obj) +{ + return new pgForeignDataWrapperObjCollection(GetCollectionFactory(), (pgForeignDataWrapper *)obj); +} + + +///////////////////////////// + +pgForeignDataWrapperCollection::pgForeignDataWrapperCollection(pgaFactory *factory, pgDatabase *db) + : pgDatabaseObjCollection(factory, db) +{ +} + + +wxString pgForeignDataWrapperCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on foreign data wrappers"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing foreign data wrappers"); + break; + case OBJECTSLISTREPORT: + message = _("Foreign data wrappers list report"); + break; + } + + return message; +} + +/////////////////////////////////////////////////// + +#include "images/foreigndatawrapper.pngc" +#include "images/foreigndatawrapper-sm.pngc" +#include "images/foreigndatawrappers.pngc" + +pgForeignDataWrapperFactory::pgForeignDataWrapperFactory() + : pgDatabaseObjFactory(__("Foreign Data Wrapper"), __("New Foreign Data Wrapper..."), __("Create a new Foreign Data Wrapper."), foreigndatawrapper_png_img, foreigndatawrapper_sm_png_img) +{ +} + + +pgCollection *pgForeignDataWrapperFactory::CreateCollection(pgObject *obj) +{ + return new pgForeignDataWrapperCollection(GetCollectionFactory(), (pgDatabase *)obj); +} + +pgForeignDataWrapperFactory foreignDataWrapperFactory; +static pgaCollectionFactory cf(&foreignDataWrapperFactory, __("Foreign Data Wrappers"), foreigndatawrappers_png_img); diff --git a/schema/pgForeignKey.cpp b/schema/pgForeignKey.cpp new file mode 100644 index 0000000..135e7c9 --- /dev/null +++ b/schema/pgForeignKey.cpp @@ -0,0 +1,433 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgForeignKey.cpp - ForeignKey class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "frm/frmMain.h" +#include "schema/pgForeignKey.h" +#include "schema/pgConstraints.h" + +pgForeignKey::pgForeignKey(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, foreignKeyFactory, newName) +{ +} + +pgForeignKey::~pgForeignKey() +{ +} + + +wxString pgForeignKey::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on foreign key"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing foreign key"); + message += wxT(" ") + GetName(); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for foreign key"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop foreign key \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop foreign key \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop foreign key cascaded?"); + break; + case DROPTITLE: + message = _("Drop foreign key?"); + break; + case PROPERTIESREPORT: + message = _("Foreign key properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Foreign key properties"); + break; + case DDLREPORT: + message = _("Foreign key DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Foreign key DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Foreign key dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Foreign key dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Foreign key dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Foreign key dependents"); + break; + } + + return message; +} + + +int pgForeignKey::GetIconId() +{ + if (!GetDatabase()->BackendMinimumVersion(9, 1) || GetValid()) + return foreignKeyFactory.GetIconId(); + else + return foreignKeyFactory.GetClosedIconId(); +} + + +bool pgForeignKey::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("ALTER TABLE ") + GetQuotedSchemaPrefix(fkSchema) + qtIdent(fkTable) + + wxT(" DROP CONSTRAINT ") + GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgForeignKey::GetDefinition() +{ + wxString sql; + + sql = wxT("(") + GetQuotedFkColumns() + + wxT(")\n REFERENCES ") + GetQuotedSchemaPrefix(GetRefSchema()) + qtIdent(GetReferences()) + + wxT(" (") + GetQuotedRefColumns() + + wxT(")"); + + if (GetDatabase()->BackendMinimumVersion(7, 4) || GetMatch() == wxT("FULL")) + sql += wxT(" MATCH ") + GetMatch(); + + sql += wxT("\n ON UPDATE ") + GetOnUpdate() + + wxT(" ON DELETE ") + GetOnDelete(); + if (GetDeferrable()) + { + sql += wxT(" DEFERRABLE INITIALLY "); + if (GetDeferred()) + sql += wxT("DEFERRED"); + else + sql += wxT("IMMEDIATE"); + } + + if (GetDatabase()->BackendMinimumVersion(9, 1) && !GetValid()) + sql += wxT("\n NOT VALID"); + + return sql; +} + + +wxString pgForeignKey::GetConstraint() +{ + wxString sql; + sql = GetQuotedIdentifier() + + wxT(" FOREIGN KEY ") + GetDefinition(); + + return sql; +} + + +wxString pgForeignKey::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Foreign Key: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- ALTER TABLE ") + GetQuotedSchemaPrefix(fkSchema) + qtIdent(fkTable) + + wxT(" DROP CONSTRAINT ") + GetQuotedIdentifier() + wxT(";") + + wxT("\n\nALTER TABLE ") + GetQuotedSchemaPrefix(fkSchema) + qtIdent(fkTable) + + wxT("\n ADD CONSTRAINT ") + GetConstraint() + + wxT(";\n"); + if (!GetComment().IsEmpty()) + sql += wxT("COMMENT ON CONSTRAINT ") + GetQuotedIdentifier() + wxT(" ON ") + GetQuotedSchemaPrefix(fkSchema) + qtIdent(fkTable) + + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + + return sql; +} + + +wxString pgForeignKey::GetFullName() +{ + return GetName() + wxT(" -> ") + GetReferences(); +} + +void pgForeignKey::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + wxTreeItemId id = browser->GetItemParent(GetId()); + pgTable *table = (pgTable *)browser->GetObject(id); + + wxStringTokenizer c1l(GetConkey(), wxT(",")); + wxStringTokenizer c2l(GetConfkey(), wxT(",")); + wxString c1, c2; + + // resolve column names + while (c1l.HasMoreTokens()) + { + c1 = c1l.GetNextToken(); + c2 = c2l.GetNextToken(); + pgSet *set = ExecuteSet( + wxT("SELECT a1.attname as conattname, a2.attname as confattname\n") + wxT(" FROM pg_attribute a1, pg_attribute a2\n") + wxT(" WHERE a1.attrelid=") + NumToStr(table->GetOid()) + wxT("::oid") + wxT(" AND a1.attnum=") + c1 + wxT("\n") + wxT(" AND a2.attrelid=") + GetRelTableOidStr() + wxT(" AND a2.attnum=") + c2); + if (set) + { + if (!fkColumns.IsNull()) + { + fkColumns += wxT(", "); + refColumns += wxT(", "); + quotedFkColumns += wxT(", "); + quotedRefColumns += wxT(", "); + } + fkColumns += set->GetVal(0); + refColumns += set->GetVal(1); + quotedFkColumns += qtIdent(set->GetVal(0)); + quotedRefColumns += qtIdent(set->GetVal(1)); + delete set; + } + } + wxTreeItemId item = browser->GetItemParent(GetId()); + while (item) + { + pgTable *table = (pgTable *)browser->GetObject(item); + if (table && table->IsCreatedBy(tableFactory)) + { + coveringIndex = table->GetCoveringIndex(browser, fkColumns); + break; + } + item = browser->GetItemParent(item); + } + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), NumToStr(GetOid())); + properties->AppendItem(_("Child columns"), GetFkColumns()); + properties->AppendItem(_("References"), GetReferences() + + wxT("(") + GetRefColumns() + wxT(")")); + + properties->AppendItem(_("Covering index"), GetCoveringIndex()); + properties->AppendItem(_("Match type"), GetMatch()); + properties->AppendItem(_("On update"), GetOnUpdate()); + properties->AppendItem(_("On delete"), GetOnDelete()); + properties->AppendItem(_("Deferrable?"), BoolToYesNo(GetDeferrable())); + if (GetDeferrable()) + properties->AppendItem(_("Initially?"), + GetDeferred() ? wxT("DEFERRED") : wxT("IMMEDIATE")); + if (GetDatabase()->BackendMinimumVersion(9, 1)) + properties->AppendItem(_("Valid?"), BoolToYesNo(GetValid())); + properties->AppendItem(_("System foreign key?"), BoolToYesNo(GetSystemObject())); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + +pgObject *pgForeignKey::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *foreignKey = 0; + + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + foreignKey = foreignKeyFactory.CreateObjects(coll, 0, wxT("\n AND ct.oid=") + GetOidStr()); + + return foreignKey; +} + + +void pgForeignKey::Validate(frmMain *form) +{ + wxString sql = wxT("ALTER TABLE ") + GetQuotedSchemaPrefix(fkSchema) + qtIdent(fkTable) + + wxT("\n VALIDATE CONSTRAINT ") + GetQuotedIdentifier(); + GetDatabase()->ExecuteVoid(sql); + + iSetValid(true); + UpdateIcon(form->GetBrowser()); +} + + +pgObject *pgForeignKeyFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restriction) +{ + wxString sql; + pgTableObjCollection *collection = (pgTableObjCollection *)coll; + pgForeignKey *foreignKey = 0; + + sql = wxT("SELECT ct.oid, conname, condeferrable, condeferred, confupdtype, confdeltype, confmatchtype, ") + wxT("conkey, confkey, confrelid, nl.nspname as fknsp, cl.relname as fktab, ") + wxT("nr.nspname as refnsp, cr.relname as reftab, description"); + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + sql += wxT(", convalidated"); + sql += wxT("\n FROM pg_constraint ct\n") + wxT(" JOIN pg_class cl ON cl.oid=conrelid\n") + wxT(" JOIN pg_namespace nl ON nl.oid=cl.relnamespace\n") + wxT(" JOIN pg_class cr ON cr.oid=confrelid\n") + wxT(" JOIN pg_namespace nr ON nr.oid=cr.relnamespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=ct.oid AND des.classoid='pg_constraint'::regclass)\n") + wxT(" WHERE contype='f' AND conrelid = ") + collection->GetOidStr() + + restriction + wxT("\n") + wxT(" ORDER BY conname"); + + pgSet *foreignKeys = collection->GetDatabase()->ExecuteSet(sql); + + if (foreignKeys) + { + while (!foreignKeys->Eof()) + { + foreignKey = new pgForeignKey(collection->GetSchema()->GetSchema(), foreignKeys->GetVal(wxT("conname"))); + + foreignKey->iSetOid(foreignKeys->GetOid(wxT("oid"))); + foreignKey->iSetRelTableOid(foreignKeys->GetOid(wxT("confrelid"))); + foreignKey->iSetFkSchema(foreignKeys->GetVal(wxT("fknsp"))); + foreignKey->iSetComment(foreignKeys->GetVal(wxT("description"))); + foreignKey->iSetFkTable(foreignKeys->GetVal(wxT("fktab"))); + foreignKey->iSetRefSchema(foreignKeys->GetVal(wxT("refnsp"))); + foreignKey->iSetReferences(foreignKeys->GetVal(wxT("reftab"))); + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + foreignKey->iSetValid(foreignKeys->GetBool(wxT("convalidated"))); + wxString onUpd = foreignKeys->GetVal(wxT("confupdtype")); + wxString onDel = foreignKeys->GetVal(wxT("confdeltype")); + wxString match = foreignKeys->GetVal(wxT("confmatchtype")); + foreignKey->iSetOnUpdate( + onUpd.IsSameAs('a') ? wxT("NO ACTION") : + onUpd.IsSameAs('r') ? wxT("RESTRICT") : + onUpd.IsSameAs('c') ? wxT("CASCADE") : + onUpd.IsSameAs('d') ? wxT("SET DEFAULT") : + onUpd.IsSameAs('n') ? wxT("SET NULL") : wxT("Unknown")); + foreignKey->iSetOnDelete( + onDel.IsSameAs('a') ? wxT("NO ACTION") : + onDel.IsSameAs('r') ? wxT("RESTRICT") : + onDel.IsSameAs('c') ? wxT("CASCADE") : + onDel.IsSameAs('d') ? wxT("SET DEFAULT") : + onDel.IsSameAs('n') ? wxT("SET NULL") : wxT("Unknown")); + foreignKey->iSetMatch( + match.IsSameAs('f') ? wxT("FULL") : + match.IsSameAs('s') ? wxT("SIMPLE") : + match.IsSameAs('u') ? wxT("SIMPLE") : wxT("Unknown")); + + wxString cn = foreignKeys->GetVal(wxT("conkey")); + cn = cn.Mid(1, cn.Length() - 2); + foreignKey->iSetConkey(cn); + cn = foreignKeys->GetVal(wxT("confkey")); + cn = cn.Mid(1, cn.Length() - 2); + foreignKey->iSetConfkey(cn); + + foreignKey->iSetDeferrable(foreignKeys->GetBool(wxT("condeferrable"))); + foreignKey->iSetDeferred(foreignKeys->GetBool(wxT("condeferred"))); + + if (browser) + { + browser->AppendObject(collection, foreignKey); + foreignKeys->MoveNext(); + } + else + break; + } + + delete foreignKeys; + } + return foreignKey; +} + +///////////////////////////// + +wxString pgForeignKeyCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on foreign keys"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing foreign keys"); + break; + case OBJECTSLISTREPORT: + message = _("Foreign keys list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/foreignkey.pngc" +#include "images/foreignkeybad.pngc" + + +pgForeignKeyFactory::pgForeignKeyFactory() + : pgSchemaObjFactory(__("Foreign Key"), __("New Foreign Key..."), __("Create a new Foreign Key constraint."), foreignkey_png_img) +{ + metaType = PGM_FOREIGNKEY; + collectionFactory = &constraintCollectionFactory; + closedId = addIcon(foreignkeybad_png_img); +} + + +pgForeignKeyFactory foreignKeyFactory; + +validateForeignKeyFactory::validateForeignKeyFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Validate foreign key"), _("Validate the selected foreign key.")); +} + + +wxWindow *validateForeignKeyFactory::StartDialog(frmMain *form, pgObject *obj) +{ + ((pgForeignKey *)obj)->Validate(form); + ((pgForeignKey *)obj)->SetDirty(); + + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + { + obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties()); + form->GetSqlPane()->SetReadOnly(false); + form->GetSqlPane()->SetText(((pgForeignKey *)obj)->GetSql(form->GetBrowser())); + form->GetSqlPane()->SetReadOnly(true); + } + form->GetMenuFactories()->CheckMenu(obj, form->GetMenuBar(), (ctlMenuToolbar *)form->GetToolBar()); + + return 0; +} + + +bool validateForeignKeyFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(foreignKeyFactory) && obj->CanEdit() + && ((pgForeignKey *)obj)->GetConnection()->BackendMinimumVersion(9, 1) + && !((pgForeignKey *)obj)->GetValid(); +} diff --git a/schema/pgForeignServer.cpp b/schema/pgForeignServer.cpp new file mode 100644 index 0000000..bbc8775 --- /dev/null +++ b/schema/pgForeignServer.cpp @@ -0,0 +1,351 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgForeignServer.cpp - Foreign Server class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgForeignServer.h" +#include "schema/pgUserMapping.h" +#include "schema/pgDatatype.h" + + +pgForeignServer::pgForeignServer(pgForeignDataWrapper *newForeignDataWrapper, const wxString &newName) + : pgForeignDataWrapperObject(newForeignDataWrapper, foreignServerFactory, newName) +{ +} + + +wxString pgForeignServer::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on foreign server"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing foreign server"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop foreign server \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop foreign server \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop foreign server cascaded?"); + break; + case DROPTITLE: + message = _("Drop foreign server?"); + break; + case PROPERTIESREPORT: + message = _("Foreign server properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Foreign server properties"); + break; + case DDLREPORT: + message = _("Foreign server DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Foreign server DDL"); + break; + case STATISTICSREPORT: + message = _("Foreign server statistics report"); + message += wxT(" - ") + GetName(); + break; + case OBJSTATISTICS: + message = _("Foreign server statistics"); + break; + case DEPENDENCIESREPORT: + message = _("Foreign server dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Foreign server dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Foreign server dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Foreign server dependents"); + break; + } + + return message; +} + + +bool pgForeignServer::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP SERVER ") + GetQuotedFullIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgForeignServer::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Server: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP SERVER ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE SERVER ") + GetQuotedFullIdentifier() + + wxT("\n FOREIGN DATA WRAPPER ") + qtIdent(GetForeignDataWrapper()->GetName()); + + if (!GetType().IsEmpty()) + sql += wxT("\n TYPE ") + qtDbString(GetType()); + + if (!GetVersion().IsEmpty()) + sql += wxT("\n VERSION ") + qtDbString(GetVersion()); + + if (!GetOptions().IsEmpty()) + sql += wxT("\n OPTIONS (") + GetCreateOptions() + wxT(")"); + + sql += wxT(";\n") + + GetOwnerSql(8, 4, wxT("SERVER ") + GetQuotedFullIdentifier()) + + GetGrant(wxT("U"), wxT("FOREIGN SERVER ") + GetQuotedFullIdentifier()); + } + return sql; +} + + +void pgForeignServer::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + + // Log + wxLogInfo(wxT("Adding child object to foreign server %s"), GetIdentifier().c_str()); + + if (settings->GetDisplayOption(_("User Mappings"))) + browser->AppendCollection(this, userMappingFactory); + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("ACL"), GetAcl()); + properties->AppendItem(_("Type"), GetType()); + properties->AppendItem(_("Version"), GetVersion()); + properties->AppendItem(_("Options"), GetOptions()); + } +} + + + +pgObject *pgForeignServer::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *fs = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + fs = foreignServerFactory.CreateObjects(coll, 0, wxT(" AND srv.oid=") + GetOidStr()); + + return fs; +} + + +wxMenu *pgForeignServer::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + if (database->GetCreatePrivilege()) + { + userMappingFactory.AppendMenu(menu); + } + return menu; +} + + +//////////////////////////////////////////////////// + + +pgObject *pgForeignServerFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + wxString sql; + pgForeignServer *fs = 0; + + sql = wxT("SELECT srv.oid, srvname, srvtype, srvversion, srvacl, fdw.fdwname as fdwname, description, ") + wxT("array_to_string(srvoptions, ',') AS srvoptions, ") + wxT("pg_get_userbyid(srvowner) as srvowner\n") + wxT(" FROM pg_foreign_server srv\n") + wxT(" LEFT OUTER JOIN pg_foreign_data_wrapper fdw on fdw.oid=srvfdw\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=srv.oid AND des.objsubid=0 AND des.classoid='pg_foreign_server'::regclass)\n") + wxT(" WHERE srvfdw = ") + collection->GetOidStr() + + restriction + wxT("\n") + wxT(" ORDER BY srvname"); + pgSet *foreignservers = collection->GetDatabase()->ExecuteSet(sql); + if (foreignservers) + { + while (!foreignservers->Eof()) + { + fs = new pgForeignServer(collection->GetForeignDataWrapper(), foreignservers->GetVal(wxT("srvname"))); + fs->iSetOid(foreignservers->GetOid(wxT("oid"))); + fs->iSetOwner(foreignservers->GetVal(wxT("srvowner"))); + fs->iSetAcl(foreignservers->GetVal(wxT("srvacl"))); + fs->iSetComment(foreignservers->GetVal(wxT("description"))); + fs->iSetType(foreignservers->GetVal(wxT("srvtype"))); + fs->iSetVersion(foreignservers->GetVal(wxT("srvversion"))); + fs->iSetOptions(foreignservers->GetVal(wxT("srvoptions"))); + + if (browser) + { + browser->AppendObject(collection, fs); + foreignservers->MoveNext(); + } + else + break; + } + + delete foreignservers; + } + + return fs; +} + + +wxString pgForeignServer::GetCreateOptions() +{ + wxString options_create = wxEmptyString; + wxString opt; + wxString val; + + wxStringTokenizer tkz_options(options, wxT(",")); + while (tkz_options.HasMoreTokens()) + { + wxStringTokenizer tkz_option(tkz_options.GetNextToken(), wxT("=")); + opt = tkz_option.GetNextToken(); + val = tkz_option.GetNextToken(); + + if (!options_create.IsEmpty()) + options_create += wxT(","); + + options_create += opt + wxT(" '") + val + wxT("'"); + } + + return options_create; +} + + +///////////////////////////// + +pgForeignServerObjCollection::pgForeignServerObjCollection(pgaFactory *factory, pgForeignServer *newsrv) + : pgCollection(factory) +{ + fsrv = newsrv; + fdw = fsrv->GetForeignDataWrapper(); + database = fdw->GetDatabase(); + server = database->GetServer(); + iSetOid(fsrv->GetOid()); +} + + +wxString pgForeignServerObjCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on foreign servers"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing foreign servers"); + break; + case OBJECTSLISTREPORT: + message = _("Foreign servers list report"); + break; + } + + return message; +} + +pgCollection *pgForeignServerObjFactory::CreateCollection(pgObject *obj) +{ + return new pgForeignServerObjCollection(GetCollectionFactory(), (pgForeignServer *)obj); +} + + +/////////////////////////////////////////////////////////////// + +void pgForeignServerObject::SetForeignServer(pgForeignServer *newForeignServer) +{ + srv = newForeignServer; + database = fdw->GetDatabase(); +} + +bool pgForeignServerObject::CanDrop() +{ + return true; //fdw->GetCreatePrivilege(); +} + + +bool pgForeignServerObject::CanCreate() +{ + return true; //fdw->GetCreatePrivilege(); +} + + +void pgForeignServerObject::SetContextInfo(frmMain *form) +{ +} + + +pgSet *pgForeignServerObject::ExecuteSet(const wxString &sql) +{ + return srv->GetDatabase()->ExecuteSet(sql); +} + +wxString pgForeignServerObject::ExecuteScalar(const wxString &sql) +{ + return srv->GetDatabase()->ExecuteScalar(sql); +} + + +bool pgForeignServerObject::ExecuteVoid(const wxString &sql) +{ + return srv->GetDatabase()->ExecuteVoid(sql); +} + + +/////////////////////////////////////////////////// + +#include "images/foreignserver.pngc" +#include "images/foreignserver-sm.pngc" +#include "images/foreignservers.pngc" + +pgForeignServerFactory::pgForeignServerFactory() + : pgForeignDataWrapperObjFactory(__("Foreign Server"), __("New Foreign Server..."), + __("Create a new Foreign Server."), foreignserver_png_img, foreignserver_sm_png_img) +{ +} + + +pgForeignServerFactory foreignServerFactory; +static pgaCollectionFactory cf(&foreignServerFactory, __("Foreign Servers"), foreignservers_png_img); diff --git a/schema/pgForeignTable.cpp b/schema/pgForeignTable.cpp new file mode 100644 index 0000000..e3509ef --- /dev/null +++ b/schema/pgForeignTable.cpp @@ -0,0 +1,415 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgForeignTable.cpp - Foreign Table class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgForeignTable.h" +#include "schema/pgDatatype.h" + + +pgForeignTable::pgForeignTable(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, foreignTableFactory, newName) +{ +} + +pgForeignTable::~pgForeignTable() +{ +} + +wxString pgForeignTable::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on foreign table"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing foreign table"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop foreign table \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop foreign table \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop foreign table cascaded?"); + break; + case DROPTITLE: + message = _("Drop foreign table?"); + break; + case PROPERTIESREPORT: + message = _("Foreign table properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Foreign table properties"); + break; + case DDLREPORT: + message = _("Foreign table DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Foreign table DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Foreign table dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Foreign table dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Foreign table dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Foreign table dependents"); + break; + } + + return message; +} + + +bool pgForeignTable::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP FOREIGN TABLE ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + +wxString pgForeignTable::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Foreign Table: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP FOREIGN TABLE ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE FOREIGN TABLE ") + GetQuotedFullIdentifier() + + wxT("\n (") + GetQuotedTypesList() + + wxT(")\n SERVER ") + GetForeignServer(); + + if (!GetOptionsList().IsEmpty()) + sql += wxT("\n OPTIONS (") + GetOptionsList() + wxT(")"); + + sql += wxT(";\n") + + GetOwnerSql(9, 1) + + GetCommentSql(); + + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += GetSeqLabelsSql(); + } + + return sql; +} + + + +void pgForeignTable::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + wxString constraint; + + if (!expandedKids) + { + expandedKids = true; + pgSet *set = ExecuteSet( + wxT("SELECT attname, format_type(t.oid,NULL) AS typname, attndims, atttypmod, nspname, attnotnull,\n") + wxT(" (SELECT COUNT(1) from pg_type t2 WHERE t2.typname=t.typname) > 1 AS isdup\n") + wxT(" FROM pg_attribute att\n") + wxT(" JOIN pg_type t ON t.oid=atttypid\n") + wxT(" JOIN pg_namespace nsp ON t.typnamespace=nsp.oid\n") + wxT(" LEFT OUTER JOIN pg_type b ON t.typelem=b.oid\n") + wxT(" WHERE att.attrelid=") + GetOidStr() + wxT("\n") + wxT(" AND attnum>0\n") + wxT(" ORDER by attnum")); + if (set) + { + int anzvar = 0; + while (!set->Eof()) + { + pgDatatype dt(set->GetVal(wxT("nspname")), set->GetVal(wxT("typname")), + set->GetBool(wxT("isdup")), set->GetLong(wxT("attndims")) > 0, set->GetLong(wxT("atttypmod"))); + constraint = set->GetBool(wxT("attnotnull")) ? wxT("NOT NULL") : wxT(""); + + if (anzvar++) + { + typesList += wxT(", "); + quotedTypesList += wxT(",\n "); + } + + typesList += set->GetVal(wxT("attname")) + wxT(" ") + + dt.GetSchemaPrefix(GetDatabase()) + dt.FullName() + wxT(" ") + + constraint; + + quotedTypesList += qtIdent(set->GetVal(wxT("attname"))) + wxT(" ") + + dt.GetQuotedSchemaPrefix(GetDatabase()) + dt.QuotedFullName() + wxT(" ") + + constraint; + + typesArray.Add(set->GetVal(wxT("attname"))); + typesArray.Add(dt.GetSchemaPrefix(GetDatabase()) + dt.FullName()); + typesArray.Add(constraint); + + set->MoveNext(); + } + delete set; + } + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Server"), GetForeignServer()); + properties->AppendItem(_("Columns"), GetQuotedTypesList()); + properties->AppendItem(_("Options"), GetOptionsList()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + if (!GetLabels().IsEmpty()) + { + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); + } + } + } + } +} + + +wxString pgForeignTable::GetSelectSql(ctlTree *browser) +{ + + wxString columns = wxEmptyString; + wxArrayString elements = GetTypesArray(); + size_t i; + for (i = 0 ; i < elements.GetCount() ; i += 3) + { + if (!columns.IsEmpty()) + columns += wxT(", "); + columns += qtIdent(elements.Item(i)); + } + + wxString sql = + wxT("SELECT ") + columns + wxT("\n") + wxT(" FROM ") + GetQuotedFullIdentifier() + wxT(";\n"); + return sql; +} + + +pgObject *pgForeignTable::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *ft = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + ft = foreignTableFactory.CreateObjects(coll, 0, wxT("\n AND c.oid=") + GetOidStr()); + + return ft; +} + + +void pgForeignTable::iSetOptions(const wxString &tmpoptions) +{ + wxString tmp; + wxString option; + wxString value; + wxString currentChar; + bool wrappedInQuotes = false, antislash = false; + + options = wxEmptyString; + + if (tmpoptions == wxEmptyString) + return; + + // parse the options string + // we start at 1 and stop at length-1 to get rid of the { and } of the array + for (unsigned int index = 1 ; index < tmpoptions.Length() - 1 ; index++) + { + // get current char + currentChar = tmpoptions.Mid(index, 1); + + // if there is a double quote at the beginning of an option, + // the whole option=value will be wrapped in quotes + if (currentChar == wxT("\"") && tmp.IsEmpty()) + wrappedInQuotes = true; + else if (currentChar == wxT("\\") && wrappedInQuotes) + antislash = true; + else + { + if ((currentChar == wxT(",") && !wrappedInQuotes && !tmp.IsEmpty()) + || (currentChar == wxT("\"") && wrappedInQuotes && !antislash && !tmp.IsEmpty())) + { + // new options + + if (currentChar == wxT("\"") && wrappedInQuotes && !antislash && !tmp.IsEmpty()) + { + // In this specific case, the next character is the comma, + // but we don't want to start the next option with the comma + // so we skip it right now + index++; + } + + // we need to grab option and value from tmp string + option = tmp.BeforeFirst('='); + value = tmp.AfterFirst('='); + + // put them in the array + optionsArray.Add(option); + optionsArray.Add(value); + + // build the options string + if (options.Length() > 0) + options += wxT(", "); + options += option + wxT(" '") + value + wxT("'"); + + // reinit tmp + tmp = wxEmptyString; + wrappedInQuotes = false; + } + else + tmp += currentChar; + antislash = false; + } + } + + // last options + + if (!tmp.IsEmpty()) + { + // we need to grab option and value from tmp string + option = tmp.BeforeFirst('='); + value = tmp.AfterFirst('='); + + // put them in the array + optionsArray.Add(option); + optionsArray.Add(value); + + // build the options string + if (options.Length() > 0) + options += wxT(", "); + options += option + wxT(" '") + value + wxT("'"); + } +} + + +///////////////////////////////////////////////////////// + + +pgForeignTableCollection::pgForeignTableCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgForeignTableCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on foreign tables"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing foreign tables"); + break; + case OBJECTSLISTREPORT: + message = _("Foreign tables list report"); + break; + } + + return message; +} + + +///////////////////////////////////////////////////////// + + +pgObject *pgForeignTableFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgForeignTable *foreigntable = 0; + + wxString sql = wxT("SELECT c.oid AS ftoid, c.relname AS ftrelname, pg_get_userbyid(relowner) AS ftowner,\n") + wxT(" ftoptions, srvname AS ftsrvname, description,\n") + wxT(" (SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=c.oid) AS labels,\n") + wxT(" (SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=c.oid) AS providers\n") + wxT(" FROM pg_class c\n") + wxT(" JOIN pg_foreign_table ft ON c.oid=ft.ftrelid\n") + wxT(" LEFT OUTER JOIN pg_foreign_server fs ON ft.ftserver=fs.oid\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=c.oid AND des.classoid='pg_class'::regclass)\n") + wxT(" WHERE c.relnamespace = ") + collection->GetSchema()->GetOidStr() + wxT("\n") + + restriction + + wxT(" ORDER BY c.relname"); + + pgSet *foreigntables = collection->GetDatabase()->ExecuteSet(sql); + + if (foreigntables) + { + while (!foreigntables->Eof()) + { + foreigntable = new pgForeignTable(collection->GetSchema(), foreigntables->GetVal(wxT("ftrelname"))); + + foreigntable->iSetOid(foreigntables->GetOid(wxT("ftoid"))); + foreigntable->iSetOwner(foreigntables->GetVal(wxT("ftowner"))); + foreigntable->iSetForeignServer(foreigntables->GetVal(wxT("ftsrvname"))); + foreigntable->iSetOptions(foreigntables->GetVal(wxT("ftoptions"))); + foreigntable->iSetComment(foreigntables->GetVal(wxT("description"))); + foreigntable->iSetProviders(foreigntables->GetVal(wxT("providers"))); + foreigntable->iSetLabels(foreigntables->GetVal(wxT("labels"))); + + if (browser) + { + browser->AppendObject(collection, foreigntable); + foreigntables->MoveNext(); + } + else + break; + } + + delete foreigntables; + } + return foreigntable; +} + + +#include "images/foreigntable.pngc" +#include "images/foreigntables.pngc" + +pgForeignTableFactory::pgForeignTableFactory() + : pgSchemaObjFactory(__("Foreign Table"), __("New Foreign Table..."), __("Create a new Foreign Table."), foreigntable_png_img) +{ + metaType = PGM_FOREIGNTABLE; +} + + +pgCollection *pgForeignTableFactory::CreateCollection(pgObject *obj) +{ + return new pgForeignTableCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgForeignTableFactory foreignTableFactory; +static pgaCollectionFactory cf(&foreignTableFactory, __("Foreign Tables"), foreigntables_png_img); diff --git a/schema/pgFunction.cpp b/schema/pgFunction.cpp new file mode 100644 index 0000000..e7ee4f0 --- /dev/null +++ b/schema/pgFunction.cpp @@ -0,0 +1,1332 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgFunction.cpp - function class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "frm/menu.h" +#include "utils/pgfeatures.h" +#include "utils/misc.h" +#include "schema/pgFunction.h" +#include "frm/frmMain.h" +#include "frm/frmReport.h" +#include "frm/frmHint.h" + +pgFunction::pgFunction(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, functionFactory, newName) +{ +} + + +pgFunction::pgFunction(pgSchema *newSchema, pgaFactory &factory, const wxString &newName) + : pgSchemaObject(newSchema, factory, newName) +{ +} + + +pgTriggerFunction::pgTriggerFunction(pgSchema *newSchema, const wxString &newName) + : pgFunction(newSchema, triggerFunctionFactory, newName) +{ +} + +pgProcedure::pgProcedure(pgSchema *newSchema, const wxString &newName) + : pgFunction(newSchema, procedureFactory, newName) +{ +} + +wxString pgFunction::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on function"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing function"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop function \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop function \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop function cascaded?"); + break; + case DROPTITLE: + message = _("Drop function?"); + break; + case PROPERTIESREPORT: + message = _("Function properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Function properties"); + break; + case DDLREPORT: + message = _("Function DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Function DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Function dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Function dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Function dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Function dependents"); + break; + } + + return message; +} + +wxString pgTriggerFunction::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on trigger function"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing trigger function"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop trigger function \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop trigger function \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop trigger function cascaded?"); + break; + case DROPTITLE: + message = _("Drop trigger function?"); + break; + case PROPERTIESREPORT: + message = _("Trigger function properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Trigger function properties"); + break; + case DDLREPORT: + message = _("Trigger function DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Trigger function DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Trigger function dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Trigger function dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Trigger function dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Trigger function dependents"); + break; + } + + return message; +} + +wxString pgProcedure::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on procedure"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing procedure"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop procedure \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop procedure \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop procedure cascaded?"); + break; + case DROPTITLE: + message = _("Drop procedure?"); + break; + case PROPERTIESREPORT: + message = _("Procedure properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Procedure properties"); + break; + case DDLREPORT: + message = _("Procedure DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Procedure DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Procedure dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Procedure dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Procedure dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Procedure dependents"); + break; + } + + return message; +} + +void pgFunction::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + if (GetConnection()->BackendMinimumVersion(8, 4)) + { + wxString sql = wxT("SELECT calls AS ") + qtIdent(_("Number of calls")) + + wxT(", total_time AS ") + qtIdent(_("Total Time")) + + wxT(", self_time AS ") + qtIdent(_("Self Time")) + + wxT(" FROM pg_stat_user_functions") + + wxT(" WHERE funcid = ") + NumToStr(GetOid()); + DisplayStatistics(statistics, sql); + } +} + +bool pgFunction::IsUpToDate() +{ + wxString sql = wxT("SELECT xmin FROM pg_proc WHERE oid = ") + this->GetOidStr(); + if (!this->GetDatabase()->GetConnection() || this->GetDatabase()->ExecuteScalar(sql) != NumToStr(GetXid())) + return false; + else + return true; +} + +bool pgFunction::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP FUNCTION ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier() + wxT("(") + GetArgSigList() + wxT(")"); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + +bool pgFunction::ResetStats() +{ + wxString sql = wxT("SELECT pg_stat_reset_single_function_counters(") + + NumToStr(this->GetOid()) + + wxT(")"); + return GetDatabase()->ExecuteVoid(sql); +} + +wxString pgFunction::GetFullName() +{ + return GetName() + wxT("(") + GetArgSigList() + wxT(")"); +} + +wxString pgProcedure::GetFullName() +{ + if (GetArgSigList().IsEmpty()) + return GetName(); + else + return GetName() + wxT("(") + GetArgSigList() + wxT(")"); +} + + +wxString pgFunction::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + wxString qtName = GetQuotedFullIdentifier() + wxT("(") + GetArgListWithNames(true) + wxT(")"); + wxString qtSig = GetQuotedFullIdentifier() + wxT("(") + GetArgSigList() + wxT(")"); + + sql = wxT("-- Function: ") + qtSig + wxT("\n\n") + + wxT("-- DROP FUNCTION ") + qtSig + wxT(";") + + wxT("\n\nCREATE OR REPLACE FUNCTION ") + qtName; + + // Use Oracle style syntax for edb-spl functions + if (GetLanguage() == wxT("edbspl") && GetProcType() == 2) + { + sql += wxT("\nRETURN "); + sql += GetReturnType(); + + sql += wxT(" AS"); + if (GetSource().StartsWith(wxT("\n"))) + sql += GetSource(); + else + sql += wxT("\n") + GetSource(); + } + else + { + sql += wxT("\n RETURNS "); + sql += GetReturnType(); + + sql += wxT(" AS\n"); + + if (GetLanguage().IsSameAs(wxT("C"), false)) + { + sql += qtDbString(GetBin()) + wxT(", ") + qtDbString(GetSource()); + } + else + { + if (GetConnection()->BackendMinimumVersion(7, 5)) + sql += qtDbStringDollar(GetSource()); + else + sql += qtDbString(GetSource()); + } + sql += wxT("\n LANGUAGE ") + GetLanguage() + wxT(" "); + if (GetConnection()->BackendMinimumVersion(8, 4) && GetIsWindow()) + sql += wxT("WINDOW "); + sql += GetVolatility(); + if (GetConnection()->BackendMinimumVersion(9, 2) && GetIsLeakProof()) + sql += wxT(" LEAKPROOF"); + if (GetIsStrict()) + sql += wxT(" STRICT"); + if (GetSecureDefiner()) + sql += wxT(" SECURITY DEFINER"); + sql += wxT("\nPARALLEL ")+GetParallel(); + + // PostgreSQL 8.3+ cost/row estimations + if (GetConnection()->BackendMinimumVersion(8, 3)) + { + sql += wxT("\n COST ") + NumToStr(GetCost()); + + if (GetReturnAsSet()) + sql += wxT("\n ROWS ") + NumToStr(GetRows()); + } + } + + if (!sql.Strip(wxString::both).EndsWith(wxT(";"))) + sql += wxT(";"); + + size_t i; + for (i = 0 ; i < configList.GetCount() ; i++) + { + if (configList.Item(i).BeforeFirst('=') != wxT("search_path") && + configList.Item(i).BeforeFirst('=') != wxT("temp_tablespaces")) + sql += wxT("\nALTER FUNCTION ") + qtSig + + wxT(" SET ") + configList.Item(i).BeforeFirst('=') + wxT("='") + configList.Item(i).AfterFirst('=') + wxT("';\n"); + else + sql += wxT("\nALTER FUNCTION ") + qtSig + + wxT(" SET ") + configList.Item(i).BeforeFirst('=') + wxT("=") + configList.Item(i).AfterFirst('=') + wxT(";\n"); + } + + sql += wxT("\n") + + GetOwnerSql(8, 0, wxT("FUNCTION ") + qtSig) + + GetGrant(wxT("X"), wxT("FUNCTION ") + qtSig); + + if (!GetComment().IsNull()) + { + sql += wxT("COMMENT ON FUNCTION ") + qtSig + + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += GetSeqLabelsSql(); + } + + return sql; +} + + +void pgFunction::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Argument count"), GetArgCount()); + properties->AppendItem(_("Arguments"), GetArgListWithNames()); + properties->AppendItem(_("Signature arguments"), GetArgSigList()); + if (!GetIsProcedure()) + properties->AppendItem(_("Return type"), GetReturnType()); + properties->AppendItem(_("Language"), GetLanguage()); + properties->AppendYesNoItem(_("Returns a set?"), GetReturnAsSet()); + if (GetLanguage().IsSameAs(wxT("C"), false)) + { + properties->AppendItem(_("Object file"), GetBin()); + properties->AppendItem(_("Link symbol"), GetSource()); + } + else + properties->AppendItem(_("Source"), firstLineOnly(GetSource())); + + if (GetConnection()->BackendMinimumVersion(8, 3)) + { + properties->AppendItem(_("Estimated cost"), GetCost()); + if (GetReturnAsSet()) + properties->AppendItem(_("Estimated rows"), GetRows()); + } + + properties->AppendItem(_("Volatility"), GetVolatility()); + properties->AppendItem(_("Parallel"), GetParallel()); + if (GetConnection()->BackendMinimumVersion(9, 2)) + properties->AppendYesNoItem(_("Leak proof?"), GetIsLeakProof()); + properties->AppendYesNoItem(_("Security of definer?"), GetSecureDefiner()); + properties->AppendYesNoItem(_("Strict?"), GetIsStrict()); + if (GetConnection()->BackendMinimumVersion(8, 4)) + properties->AppendYesNoItem(_("Window?"), GetIsWindow()); + + size_t i; + for (i = 0 ; i < configList.GetCount() ; i++) + { + wxString item = configList.Item(i); + properties->AppendItem(item.BeforeFirst('='), item.AfterFirst('=')); + } + + properties->AppendItem(_("ACL"), GetAcl()); + properties->AppendYesNoItem(_("System function?"), GetSystemObject()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + if (!GetLabels().IsEmpty()) + { + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); + } + } + } + } +} + +void pgFunction::ShowHint(frmMain *form, bool force) +{ + wxArrayString hints; + hints.Add(HINT_OBJECT_EDITING); + frmHint::ShowHint((wxWindow *)form, hints, GetFullIdentifier(), force); +} + +wxString pgProcedure::GetSql(ctlTree *browser) +{ + if (!GetConnection()->BackendMinimumVersion(11, 0)) + return pgFunction::GetSql(browser); + + if (sql.IsNull()) + { + wxString qtName, qtSig; + + if (GetArgListWithNames().IsEmpty()) + { + qtName = GetQuotedFullIdentifier(); + qtSig = GetQuotedFullIdentifier(); + } + else + { + qtName = GetQuotedFullIdentifier() + wxT("(") + GetArgListWithNames() + wxT(")"); + qtSig = GetQuotedFullIdentifier() + wxT("(") + GetArgSigList() + wxT(")"); + } + + sql = wxT("-- Procedure: ") + qtSig + wxT("\n\n") + + wxT("-- DROP PROCEDURE ") + qtSig + wxT(";") + + wxT("\n\nCREATE OR REPLACE PROCEDURE ") + qtName; + + sql += wxT("\n LANGUAGE ") + GetLanguage() + wxT("\n "); + sql += wxT(" AS "); + sql += qtDbStringDollar(GetSource()); + sql += wxT(";\n\n"); + + size_t i; + for (i = 0 ; i < pgFunction::GetConfigList().GetCount() ; i++) + { + if (pgFunction::GetConfigList().Item(i).BeforeFirst('=') != wxT("search_path") && + pgFunction::GetConfigList().Item(i).BeforeFirst('=') != wxT("temp_tablespaces")) + sql += wxT("\nALTER PROCEDURE ") + qtSig + + wxT(" SET ") + pgFunction::GetConfigList().Item(i).BeforeFirst('=') + wxT("='") + pgFunction::GetConfigList().Item(i).AfterFirst('=') + wxT("';\n"); + else + sql += wxT("\nALTER PROCEDURE ") + qtSig + + wxT(" SET ") + pgFunction::GetConfigList().Item(i).BeforeFirst('=') + wxT("=") + pgFunction::GetConfigList().Item(i).AfterFirst('=') + wxT(";\n"); + } + + + sql += GetGrant(wxT("X"), wxT("PROCEDURE ") + qtSig); + + if (!GetComment().IsNull()) + { + sql += wxT("COMMENT ON PROCEDURE ") + GetQuotedFullIdentifier() + + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + } + + return sql; +} + + +bool pgProcedure::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + if (!GetConnection()->BackendMinimumVersion(11, 0)) + return pgFunction::DropObject(frame, browser, cascaded); + + wxString sql = wxT("DROP PROCEDURE ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + return GetDatabase()->ExecuteVoid(sql); +} + +wxString pgFunction::GetArgListWithNames(bool multiline) +{ + wxString args; + unsigned int nArgs = 0; + + for (unsigned int i = 0; i < argTypesArray.Count(); i++) + { + /* + * All Table arguments lies at the end of the list + * Do not include them as the part of the argument list + */ + if (argModesArray.Item(i) == wxT("TABLE")) + break; + + nArgs++; + if (args.Length() > 0) + { + args += (multiline) ? wxT(",\n ") : wxT(", "); + } + + wxString arg; + + if (GetIsProcedure()) + { + if (!argModesArray.Item(i).IsEmpty()) + { + arg += qtIdent(argNamesArray.Item(i)); + } + else + { + if (!argNamesArray.Item(i).IsEmpty()) + arg += qtIdent(argNamesArray.Item(i)); + arg += wxT(" ") + argModesArray.Item(i); + } + + if (!argModesArray.Item(i).IsEmpty()) + { + if (arg.IsEmpty()) + arg += argModesArray.Item(i); + else + arg += wxT(" ") + argModesArray.Item(i); + } + } + else + { + if (!argModesArray.Item(i).IsEmpty()) + arg += argModesArray.Item(i); + + if (!argNamesArray.Item(i).IsEmpty()) + { + if (arg.IsEmpty()) + arg += qtIdent(argNamesArray.Item(i)); + else + arg += wxT(" ") + qtIdent(argNamesArray.Item(i)); + } + } + + if (!arg.IsEmpty()) + arg += wxT(" ") + argTypesArray.Item(i); + else + arg += argTypesArray.Item(i); + + // Parameter default value + if (GetConnection()->HasFeature(FEATURE_FUNCTION_DEFAULTS) + && !argDefsArray.IsEmpty()) + { + if ((argModesArray.Item(i).IsEmpty() || + argModesArray.Item(i) == wxT("IN") || + // 'edbspl' does not support default value with + // INOUT parameter + (argModesArray.Item(i) == wxT("INOUT") && + GetLanguage() != wxT("edbspl")) || + argModesArray.Item(i) == wxT("VARIADIC")) && + !argDefsArray.Item(i).IsEmpty() && + i < argDefsArray.Count()) + { + arg += wxT(" DEFAULT ") + argDefsArray.Item(i); + } + } + + args += arg; + } + + if (multiline && nArgs > 1) + { + args = wxT("\n ") + args; + } + + return args; +} + +// Return the signature arguments list. If forScript = true, we format the list +// appropriately for use in a SELECT script. +wxString pgFunction::GetArgSigList(const bool forScript) +{ + wxString args; + + for (unsigned int i = 0; i < argTypesArray.Count(); i++) + { + // OUT parameters are not considered part of the signature, except for EDB-SPL, + // although this is not true for EDB AS90 onwards.. + if (argModesArray.Item(i) != wxT("OUT") && argModesArray.Item(i) != wxT("TABLE")) + { + if (args.Length() > 0) + { + if (forScript) + args += wxT(",\n"); + else + args += wxT(", "); + } + + if (forScript) + args += wxT(" <") + argTypesArray.Item(i) + wxT(">"); + else + args += argTypesArray.Item(i); + } + else + { + if (GetLanguage() == wxT("edbspl") && argModesArray.Item(i) != wxT("TABLE") && + !this->GetConnection()->EdbMinimumVersion(9, 0)) + { + if (args.Length() > 0) + { + if (forScript) + args += wxT(",\n"); + else + args += wxT(", "); + } + + if (forScript) + args += wxT(" <") + argTypesArray.Item(i) + wxT(">"); + else + args += argTypesArray.Item(i); + } + } + } + return args; +} + +pgFunction *pgFunctionFactory::AppendFunctions(pgObject *obj, pgSchema *schema, ctlTree *browser, const wxString &restriction) +{ + // Caches + cacheMap typeCache, exprCache; + + pgFunction *function = 0; + wxString argNamesCol, argDefsCol, proConfigCol, proType, seclab; + if (obj->GetConnection()->BackendMinimumVersion(8, 0)) + argNamesCol = wxT("proargnames, "); + if (obj->GetConnection()->HasFeature(FEATURE_FUNCTION_DEFAULTS) && !obj->GetConnection()->BackendMinimumVersion(8, 4)) + argDefsCol = wxT("proargdefvals, COALESCE(substring(array_dims(proargdefvals), E'1:(.*)\\]')::integer, 0) AS pronargdefaults, "); + if (obj->GetConnection()->BackendMinimumVersion(8, 4)) + argDefsCol = wxT("pg_get_expr(proargdefaults, 'pg_catalog.pg_class'::regclass) AS proargdefaultvals, pronargdefaults, "); + if (obj->GetConnection()->BackendMinimumVersion(8, 3)) + proConfigCol = wxT("proconfig, "); + if (obj->GetConnection()->EdbMinimumVersion(8, 1)) + proType = wxT("protype, "); + if (obj->GetConnection()->BackendMinimumVersion(9, 1)) + { + seclab = wxT(",\n") + wxT("(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=pr.oid) AS labels,\n") + wxT("(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=pr.oid) AS providers"); + } + + pgSet *functions; + if (obj->GetConnection()->GetIsGreenplum()) + { + // the Open Source version of Greenplum already has the pg_get_function_result() function, + // however the 4.3 stable release does not have this function + functions = obj->GetDatabase()->ExecuteSet( + wxT("SELECT pr.oid, pr.xmin, pr.*, format_type(TYP.oid, NULL) AS typname, typns.nspname AS typnsp, lanname, ") + + argNamesCol + argDefsCol + proConfigCol + proType + + wxT(" pg_get_userbyid(proowner) as funcowner, description") + seclab + wxT("\n") + wxT(" FROM pg_proc pr\n") + wxT(" JOIN pg_type typ ON typ.oid=prorettype\n") + wxT(" JOIN pg_namespace typns ON typns.oid=typ.typnamespace\n") + wxT(" JOIN pg_language lng ON lng.oid=prolang\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=pr.oid AND des.classoid='pg_proc'::regclass)\n") + + restriction + + wxT(" ORDER BY proname")); + } + else + { + // new code for !Greenplum + wxString sqlprokind; + if (obj->GetConnection()->BackendMinimumVersion(11, 0)) {sqlprokind= wxT(" prokind, "); + } else + { + sqlprokind= wxT("case when proisagg then 'a' when proiswindow then 'w' else 'f' end prokind, "); + } + functions = obj->GetDatabase()->ExecuteSet( + wxT("SELECT pr.oid, pr.xmin, pr.*,lanname, pg_get_function_result(pr.oid) AS typname, typns.nspname AS typnsp, ") +sqlprokind+ + argNamesCol + argDefsCol + proConfigCol + proType + + wxT(" pg_get_userbyid(proowner) as funcowner, description") + seclab + wxT("\n") + wxT(", CASE WHEN pr.proparallel = 'r' THEN 'RESTRICTED'") + wxT(" WHEN pr.proparallel = 's' THEN 'SAFE'\n") + wxT(" WHEN pr.proparallel = 'u' THEN 'UNSAFE'\n") + wxT(" END as \"parallel\"") + wxT(" FROM pg_proc pr\n") + wxT(" JOIN pg_type typ ON typ.oid=prorettype\n") + wxT(" JOIN pg_namespace typns ON typns.oid=typ.typnamespace\n") + wxT(" JOIN pg_language lng ON lng.oid=prolang\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=pr.oid AND des.classoid='pg_proc'::regclass)\n") + + restriction + + wxT(" ORDER BY proname")); + } + + pgSet *types = obj->GetDatabase()->ExecuteSet(wxT( + "SELECT oid, format_type(oid, NULL) AS typname FROM pg_type")); + + if (types) + { + while(!types->Eof()) + { + typeCache[types->GetVal(wxT("oid"))] = types->GetVal(wxT("typname")); + types->MoveNext(); + } + } + + if (functions) + { + while (!functions->Eof()) + { + bool isProcedure = false; + wxString prokind = functions->GetVal(wxT("prokind")); + wxString lanname = functions->GetVal(wxT("lanname")); + wxString typname = functions->GetVal(wxT("typname")); + + // Is this an EDB Stored Procedure? + if (obj->GetConnection()->EdbMinimumVersion(8, 1)) + { + wxString protype = functions->GetVal(wxT("protype")); + if (protype == wxT("1")) + isProcedure = true; + } + else if (obj->GetConnection()->BackendMinimumVersion(11, 0) && + prokind == wxT("p") ) + isProcedure = true; + + // Create the new object + if (isProcedure) + function = new pgProcedure(schema, functions->GetVal(wxT("proname"))); + else if (typname == wxT("\"trigger\"") || typname == wxT("trigger") || typname == wxT("event_trigger") || typname == wxT("\"event_trigger\"")) + function = new pgTriggerFunction(schema, functions->GetVal(wxT("proname"))); + else + function = new pgFunction(schema, functions->GetVal(wxT("proname"))); + + // Tokenize the arguments + wxStringTokenizer argTypesTkz(wxEmptyString), argModesTkz(wxEmptyString); + wxString tmp; + + wxArrayString argNamesArray; + wxArrayString argDefValArray; + + // We always have types + argTypesTkz.SetString(functions->GetVal(wxT("proargtypes"))); + + // We only have names in 8.0+ + if (obj->GetConnection()->BackendMinimumVersion(8, 0)) + { + tmp = functions->GetVal(wxT("proargnames")); + if (!tmp.IsEmpty()) + getArrayFromCommaSeparatedList(tmp.Mid(1, tmp.Length() - 2), argNamesArray); + } + + // EDB 8.0 had modes in pg_proc.proargdirs + //if (!obj->GetConnection()->EdbMinimumVersion(8, 1) && isProcedure) + // argModesTkz.SetString(functions->GetVal(wxT("proargdirs"))); + + if (obj->GetConnection()->EdbMinimumVersion(8, 1)) + function->iSetProcType(functions->GetLong(wxT("protype"))); + + // EDB 8.1 and PostgreSQL 8.1 have modes in pg_proc.proargmodes + if (obj->GetConnection()->BackendMinimumVersion(8, 1)) + { + tmp = functions->GetVal(wxT("proallargtypes")); + if (!tmp.IsEmpty()) + argTypesTkz.SetString(tmp.Mid(1, tmp.Length() - 2), wxT(",")); + + tmp = functions->GetVal(wxT("proargmodes")); + if (!tmp.IsEmpty()) + argModesTkz.SetString(tmp.Mid(1, tmp.Length() - 2), wxT(",")); + } + function->iSetIsWindow(false); + // EDB 8.3: Function defaults + if (obj->GetConnection()->HasFeature(FEATURE_FUNCTION_DEFAULTS) && + !obj->GetConnection()->BackendMinimumVersion(8, 4)) + { + tmp = functions->GetVal(wxT("proargdefvals")); + if (!tmp.IsEmpty()) + getArrayFromCommaSeparatedList(tmp.Mid(1, tmp.Length() - 2), argDefValArray); + + function->iSetArgDefValCount(functions->GetLong(wxT("pronargdefaults"))); + } + + if (obj->GetConnection()->BackendMinimumVersion(8, 4)) + { + tmp = functions->GetVal(wxT("proargdefaultvals")); + getArrayFromCommaSeparatedList(tmp, argDefValArray); + + function->iSetArgDefValCount(functions->GetLong(wxT("pronargdefaults"))); + + // Check if it is a window function + if (obj->GetConnection()->BackendMinimumVersion(11, 0)) + { + if (prokind == wxT("w")) function->iSetIsWindow(true); + } + else function->iSetIsWindow(functions->GetBool(wxT("proiswindow"))); + + } + else + function->iSetIsWindow(false); + + // Now iterate the arguments and build the arrays + wxString type, name, mode; + size_t nArgsIN = 0; + size_t nArgNames = 0; + + while (argTypesTkz.HasMoreTokens()) + { + if (nArgNames < argNamesArray.GetCount()) + { + name = argNamesArray[nArgNames++]; + } + else + name = wxEmptyString; + if (!name.IsEmpty()) + { + // Now add the name, stripping the quotes and \" if + // necessary. + if (name[0] == '"') + name = name.Mid(1, name.Length() - 2); + name.Replace(wxT("\\\""), wxT("\"")); + + // In EDBAS 90, if an SPL-function has both an OUT-parameter + // and a return value (which is not possible on PostgreSQL otherwise), + // the return value is transformed into an extra OUT-parameter + // named "_retval_" + if (obj->GetConnection()->EdbMinimumVersion(9, 0)) + { + if (name == wxT("_retval_")) + { + type = argTypesTkz.GetNextToken(); + // this will be the return type for this object + function->iSetReturnType(typeCache[type]); + + // consume uniformly, mode will definitely be "OUT" + mode = argModesTkz.GetNextToken(); + + continue; + } + } + function->iAddArgName(name); + } + else + function->iAddArgName(wxEmptyString); + + // Add the arg type. This is a type oid, so + // look it up in the hashmap + type = argTypesTkz.GetNextToken(); + function->iAddArgType(typeCache[type]); + + // Now the mode + mode = argModesTkz.GetNextToken(); + if (!mode.IsEmpty()) + { + if (mode == wxT('o') || mode == wxT("2")) + mode = wxT("OUT"); + else if (mode == wxT("b") || mode == wxT("3")) + { + nArgsIN++; + if (isProcedure) + mode = wxT("INOUT"); + else + { + mode = wxT("INOUT"); + // 'edbspl' does not support default values for the + // INOUT parameters. + //if (prokind != wxT("p")) + } + } + else if (mode == wxT("v")) + { + mode = wxT("VARIADIC"); + nArgsIN++; + } + else if (mode == wxT("t")) + mode = wxT("TABLE"); + else + { + mode = wxT("IN"); + nArgsIN++; + } + + function->iAddArgMode(mode); + } + else + { + function->iAddArgMode(wxEmptyString); + nArgsIN++; + } + } + + function->iSetArgCount(functions->GetLong(wxT("pronargs"))); + + wxString strReturnTableArgs; + // Process default values + size_t currINindex = 0; + for (size_t index = 0; index < function->GetArgModesArray().Count(); index++) + { + wxString def = wxEmptyString; + if(function->GetArgModesArray()[index].IsEmpty() || + function->GetArgModesArray()[index] == wxT("IN") || + (function->GetArgModesArray()[index] == wxT("INOUT") && + prokind != wxT("p")) || + function->GetArgModesArray()[index] == wxT("VARIADIC")) + { + if (!argDefValArray.IsEmpty() && nArgsIN <= argDefValArray.GetCount()) + { + def = argDefValArray[currINindex++]; + + if (!def.IsEmpty() && def != wxT("-")) + { + // Only EDB 8.3 does not support get the default value + // using pg_get_expr directly + if (function->GetConnection()->HasFeature(FEATURE_FUNCTION_DEFAULTS) && + !function->GetConnection()->BackendMinimumVersion(8, 4)) + { + // Check the cache first - if we don't have a value, get it and cache for next time + wxString val = exprCache[def]; + + if (val == wxEmptyString) + { + val = obj->GetDatabase()->ExecuteScalar( + wxT("SELECT pg_get_expr('") + def.Mid(1, def.Length() - 2) + wxT("', 'pg_catalog.pg_class'::regclass)")); + exprCache[def] = val; + } + def = val; + } + } + else + { + def = wxEmptyString; + } + } + nArgsIN--; + } + else if(function->GetConnection()->BackendMinimumVersion(8, 4) && + function->GetArgModesArray()[index] == wxT("TABLE")) + { + if (strReturnTableArgs.Length() > 0) + strReturnTableArgs += wxT(", "); + wxString strName = function->GetArgNamesArray()[index]; + if (!strName.IsEmpty()) + strReturnTableArgs += qtIdent(strName) + wxT(" "); + strReturnTableArgs += function->GetArgTypesArray()[index]; + } + function->iAddArgDef(def); + } + + function->iSetOid(functions->GetOid(wxT("oid"))); + function->iSetXid(functions->GetOid(wxT("xmin"))); + + if (browser) + function->UpdateSchema(browser, functions->GetOid(wxT("pronamespace"))); + + function->iSetOwner(functions->GetVal(wxT("funcowner"))); + function->iSetAcl(functions->GetVal(wxT("proacl"))); + + // set the return type only if not already set.. + if (function->GetReturnType().IsEmpty()) + { + wxString strType = functions->GetVal(wxT("typname")); + if (strType.Lower() == wxT("record") && !strReturnTableArgs.IsEmpty()) + { + strType = wxT("TABLE(") + strReturnTableArgs + wxT(")"); + } + function->iSetReturnType(strType); + } + function->iSetComment(functions->GetVal(wxT("description"))); + + function->iSetLanguage(lanname); + function->iSetSecureDefiner(functions->GetBool(wxT("prosecdef"))); + function->iSetReturnAsSet(functions->GetBool(wxT("proretset"))); + function->iSetIsStrict(functions->GetBool(wxT("proisstrict"))); + function->iSetSource(functions->GetVal(wxT("prosrc"))); + function->iSetBin(functions->GetVal(wxT("probin"))); + + wxString vol = functions->GetVal(wxT("provolatile")); + function->iSetVolatility( + vol.IsSameAs(wxT("i")) ? wxT("IMMUTABLE") : + vol.IsSameAs(wxT("s")) ? wxT("STABLE") : + vol.IsSameAs(wxT("v")) ? wxT("VOLATILE") : wxT("unknown")); + function->iSetParallel(functions->GetVal(wxT("parallel"))); + + // PostgreSQL 8.3 cost/row estimations + if (obj->GetConnection()->BackendMinimumVersion(8, 3)) + { + function->iSetCost(functions->GetLong(wxT("procost"))); + function->iSetRows(functions->GetLong(wxT("prorows"))); + wxString cfg = functions->GetVal(wxT("proconfig")); + if (!cfg.IsEmpty()) + FillArray(function->GetConfigList(), cfg.Mid(1, cfg.Length() - 2)); + } + + if (obj->GetConnection()->BackendMinimumVersion(9, 1)) + { + function->iSetProviders(functions->GetVal(wxT("providers"))); + function->iSetLabels(functions->GetVal(wxT("labels"))); + } + + if (obj->GetConnection()->BackendMinimumVersion(9, 2)) + { + function->iSetIsLeakProof(functions->GetBool(wxT("proleakproof"))); + } + + if (browser) + { + browser->AppendObject(obj, function); + functions->MoveNext(); + } + else + break; + } + + delete functions; + delete types; + } + return function; +} + + + +pgObject *pgFunction::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *function = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + function = functionFactory.AppendFunctions(coll, GetSchema(), 0, wxT(" WHERE pr.oid=") + GetOidStr() + wxT("\n")); + + // We might be linked to trigger.... + pgObject *trigger = browser->GetParentObject(item); + if (trigger->GetMetaType() == PGM_TRIGGER || trigger->GetMetaType() == PGM_EVENTTRIGGER) + function = functionFactory.AppendFunctions(trigger, GetSchema(), 0, wxT(" WHERE pr.oid=") + GetOidStr() + wxT("\n")); + + return function; +} + +// Generate the SELECT Script SQL +wxString pgFunction::GetSelectSql(ctlTree *browser) +{ + wxString args = GetArgSigList(true); + + wxString sql = wxT("SELECT ") + GetQuotedFullIdentifier(); + + if (args.Length()) + sql += wxT("(\n") + args + wxT("\n);\n"); + else + sql += wxT("();\n"); + + return sql; +} + +// Generate the EXEC Script SQL +wxString pgProcedure::GetExecSql(ctlTree *browser) +{ + wxString args = GetArgSigList(true); + + wxString sql = wxT("CALL ") + GetQuotedFullIdentifier(); + + if (args.Length()) + sql += wxT("(\n") + args + wxT("\n);\n"); + else + sql += wxT(";\n"); + + return sql; +} + +pgObject *pgFunctionFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restr) +{ + wxString sqlprokind; + if (collection->GetConnection()->BackendMinimumVersion(11, 0)) {sqlprokind= wxT("prokind <> 'p' "); + } else + { + sqlprokind= wxT("case when proisagg then 'a' when proiswindow then 'w' else 'f' end <>'p' "); + } + + wxString funcRestriction = wxT( + " WHERE ")+sqlprokind+wxT(" AND pronamespace = ") + NumToStr(collection->GetSchema()->GetOid()) + + wxT("::oid\n AND typname NOT IN ('trigger', 'event_trigger') \n"); + + if (collection->GetConnection()->EdbMinimumVersion(8, 1)) + funcRestriction += wxT(" AND NOT (lanname = 'edbspl' AND protype = '1')\n"); + else if (collection->GetConnection()->EdbMinimumVersion(8, 0)) + funcRestriction += wxT(" AND NOT (lanname = 'edbspl' AND typname = 'void')\n"); + + // Get the Functions + return AppendFunctions(collection, collection->GetSchema(), browser, funcRestriction); +} + + +pgCollection *pgFunctionFactory::CreateCollection(pgObject *obj) +{ + return new pgFunctionCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgObject *pgTriggerFunctionFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restr) +{ + wxString sqlprokind; + if (collection->GetConnection()->BackendMinimumVersion(11, 0)) {sqlprokind= wxT("prokind = 'f' "); + } else + { + sqlprokind= wxT("case when proisagg then 'a' when proiswindow then 'w' else 'f' end ='f' "); + } + + wxString funcRestriction = wxT( + " WHERE ")+sqlprokind+wxT(" AND pronamespace = ") + NumToStr(collection->GetSchema()->GetOid()) + + wxT("::oid\n"); + if(collection->GetConnection()->BackendMinimumVersion(9, 3)) + { + //funcRestriction += wxT("AND (typname IN ('trigger', 'event_trigger') \nAND lanname NOT IN ('edbspl', 'sql', 'internal'))"); + funcRestriction += wxT("AND (typname IN ('trigger', 'event_trigger') \n)"); + } + else + { + funcRestriction += wxT("AND (typname = 'trigger'\n AND lanname != 'edbspl')"); + } + + // Get the Functions + return AppendFunctions(collection, collection->GetSchema(), browser, funcRestriction); +} + + +pgObject *pgProcedureFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restr) +{ + wxString funcRestriction = wxT( + " WHERE prokind = 'p' AND pronamespace = ") + NumToStr(collection->GetSchema()->GetOid()) + + wxT("::oid\n"); + + //if (collection->GetConnection()->EdbMinimumVersion(8, 1)) + // funcRestriction += wxT(" AND protype = '1'\n"); + //else + // funcRestriction += wxT(" AND typname = 'void'\n"); + + // Get the Functions + return AppendFunctions(collection, collection->GetSchema(), browser, funcRestriction); +} + + +#include "images/function.pngc" +#include "images/functions.pngc" + +pgFunctionFactory::pgFunctionFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img) + : pgSchemaObjFactory(tn, ns, nls, img) +{ + metaType = PGM_FUNCTION; +} + +pgFunctionFactory functionFactory(__("Function"), __("New Function..."), __("Create a new Function."), function_png_img); +static pgaCollectionFactory cf(&functionFactory, __("Functions"), functions_png_img); + + +#include "images/triggerfunction.pngc" +#include "images/triggerfunctions.pngc" + +pgTriggerFunctionFactory::pgTriggerFunctionFactory() + : pgFunctionFactory(__("Trigger Function"), __("New Trigger Function..."), __("Create a new Trigger Function."), triggerfunction_png_img) +{ +} + +pgTriggerFunctionFactory triggerFunctionFactory; +static pgaCollectionFactory cft(&triggerFunctionFactory, __("Trigger Functions"), triggerfunctions_png_img); + +#include "images/procedure.pngc" +#include "images/procedures.pngc" + +pgProcedureFactory::pgProcedureFactory() + : pgFunctionFactory(__("Procedure"), __("New Procedure"), __("Create a new Procedure."), procedure_png_img) +{ +} + +pgProcedureFactory procedureFactory; +static pgaCollectionFactory cfp(&procedureFactory, __("Procedures"), procedures_png_img); + +pgFunctionCollection::pgFunctionCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + +wxString pgFunctionCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on functions"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing functions"); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for functions"); + break; + case OBJECTSLISTREPORT: + message = _("Functions list report"); + break; + } + + return message; +} + +void pgFunctionCollection::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + if (GetConnection()->BackendMinimumVersion(8, 4)) + { + wxLogInfo(wxT("Displaying statistics for functions on ") + GetSchema()->GetName()); + + wxString sql = wxT("SELECT funcname, calls, total_time, self_time") + wxT(" FROM pg_stat_user_functions") + wxT(" WHERE schemaname = ") + qtDbString(GetSchema()->GetName()) + + wxT(" ORDER BY funcname"); + + // Add the statistics view columns + statistics->ClearAll(); + statistics->AddColumn(_("Function"), 60); + statistics->AddColumn(_("Calls"), 50); + statistics->AddColumn(_("Total Time"), 60); + statistics->AddColumn(_("Self Time"), 60); + + pgSet *stats = GetDatabase()->ExecuteSet(sql); + if (stats) + { + long pos = 0; + while (!stats->Eof()) + { + statistics->InsertItem(pos, stats->GetVal(wxT("funcname")), PGICON_STATISTICS); + statistics->SetItem(pos, 1, stats->GetVal(wxT("calls"))); + statistics->SetItem(pos, 2, stats->GetVal(wxT("total_time"))); + statistics->SetItem(pos, 3, stats->GetVal(wxT("self_time"))); + stats->MoveNext(); + pos++; + } + + delete stats; + } + } +} + + +resetFunctionStatsFactory::resetFunctionStatsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Reset function statistics"), _("Reset statistics of the selected function.")); +} + + +wxWindow *resetFunctionStatsFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (wxMessageBox(_("Are you sure you wish to reset statistics of this function?"), _("Reset function statistics"), wxYES_NO) != wxYES) + return 0; + + ((pgFunction *)obj)->ResetStats(); + ((pgFunction *)obj)->ShowStatistics(form, form->GetStatistics()); + + return 0; +} + + +bool resetFunctionStatsFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(functionFactory) && ((pgFunction *)obj)->GetConnection()->BackendMinimumVersion(9, 0); +} + +wxString pgTriggerFunctionCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on trigger functions"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing trigger functions"); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for trigger functions"); + break; + case OBJECTSLISTREPORT: + message = _("Trigger functions list report"); + break; + } + + return message; +} + +wxString pgProcedureCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on procedures"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing procedures"); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for procedures"); + break; + case OBJECTSLISTREPORT: + message = _("Procedures list report"); + break; + } + + return message; +} + + diff --git a/schema/pgGroup.cpp b/schema/pgGroup.cpp new file mode 100644 index 0000000..6bff23c --- /dev/null +++ b/schema/pgGroup.cpp @@ -0,0 +1,233 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgGroup.cpp - PostgreSQL group (only used on pre-8.1 versions, pgRole +// is used on newer versions). +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgGroup.h" + + +pgGroup::pgGroup(const wxString &newName) + : pgServerObject(groupFactory, newName) +{ + memberCount = 0; +} + +wxString pgGroup::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on group"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing group"); + message += wxT(" ") + GetName(); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for group"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop group \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop group \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop group cascaded?"); + break; + case DROPTITLE: + message = _("Drop group?"); + break; + case PROPERTIESREPORT: + message = _("Group properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Group properties"); + break; + case DDLREPORT: + message = _("Group DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Group DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Group dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Group dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Group dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Group dependents"); + break; + } + + return message; +} + +bool pgGroup::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return server->ExecuteVoid(wxT("DROP GROUP ") + GetQuotedFullIdentifier()); +} + +wxString pgGroup::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Group: ") + GetName() + wxT("\n\n") + + wxT("DROP GROUP ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE Group ") + GetQuotedIdentifier() + + wxT("\n WITH SYSID ") + NumToStr(groupId) + + wxT("\n USER ") + quotedMembers + + wxT(";\n"); + } + return sql; +} + + +void pgGroup::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + if (!memberIds.IsEmpty()) + { + wxString ml = memberIds; + ml.Replace(wxT(" "), wxT(",")); + pgSet *set = server->ExecuteSet(wxT( + "SELECT usename FROM pg_user WHERE usesysid IN (") + ml + wxT(")")); + if (set) + { + while (!set->Eof()) + { + wxString user = set->GetVal(0); + if (memberCount) + { + members += wxT(", "); + quotedMembers += wxT(", "); + } + members += user; + quotedMembers += qtIdent(user); + memberCount++; + usersIn.Add(user); + set->MoveNext(); + } + delete set; + } + } + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("Group ID"), GetGroupId()); + properties->AppendItem(_("Member count"), GetMemberCount()); + properties->AppendItem(_("Members"), GetMembers()); + } +} + + + +pgObject *pgGroup::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *group = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + group = groupFactory.CreateObjects(coll, 0, wxT("\n WHERE grosysid=") + NumToStr(GetGroupId())); + + return group; +} + + + +pgObject *pgGroupFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgGroup *group = 0; + + pgSet *groups = collection->GetServer()->ExecuteSet(wxT( + "SELECT * from pg_group") + restriction + wxT(" ORDER BY groname")); + + if (groups) + { + while (!groups->Eof()) + { + group = new pgGroup(groups->GetVal(wxT("groname"))); + group->iSetGroupId(groups->GetLong(wxT("grosysid"))); + group->iSetServer(collection->GetServer()); + wxString mids = groups->GetVal(wxT("grolist")); + mids = mids.Mid(1, mids.Length() - 2); + group->iSetMemberIds(mids); + + if (browser) + { + browser->AppendObject(collection, group); + groups->MoveNext(); + } + else + break; + } + + delete groups; + } + return group; +} + +wxString pgGroupCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on groups"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing groups"); + break; + case OBJECTSLISTREPORT: + message = _("Groups list report"); + break; + } + + return message; +} + +#include "images/group.pngc" +#include "images/groups.pngc" + +pgGroupFactory::pgGroupFactory() + : pgServerObjFactory(__("Group"), __("New Group..."), __("Create a new Group."), group_png_img) +{ +} + + +pgGroupFactory groupFactory; +static pgaCollectionFactory cf(&groupFactory, __("Groups"), groups_png_img); diff --git a/schema/pgIndex.cpp b/schema/pgIndex.cpp new file mode 100644 index 0000000..be937f0 --- /dev/null +++ b/schema/pgIndex.cpp @@ -0,0 +1,756 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgIndex.cpp - Index class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "frm/frmMain.h" +#include "utils/misc.h" +#include "utils/pgfeatures.h" +#include "schema/pgIndex.h" +#include "schema/pgConstraints.h" +#include "schema/pgIndexConstraint.h" + + +pgIndexBase::pgIndexBase(pgSchema *newSchema, pgaFactory &factory, const wxString &newName) + : pgSchemaObject(newSchema, factory, newName) +{ + showExtendedStatistics = false; +} + +wxString pgIndexBase::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on index"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing index"); + message += wxT(" ") + GetName(); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for index"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop index \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop index \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop index cascaded?"); + break; + case DROPTITLE: + message = _("Drop index?"); + break; + case PROPERTIESREPORT: + message = _("Index properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Index properties"); + break; + case DDLREPORT: + message = _("Index DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Index DDL"); + break; + case STATISTICSREPORT: + message = _("Index statistics report"); + message += wxT(" - ") + GetName(); + break; + case OBJSTATISTICS: + message = _("Index statistics"); + break; + case DEPENDENCIESREPORT: + message = _("Index dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Index dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Index dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Index dependents"); + break; + } + + return message; +} + +bool pgIndexBase::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP INDEX ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + +wxString pgIndexBase::GetCreate() +{ + wxString str; +// no functional indexes so far + + str = wxT("CREATE "); + if (GetIsUnique()) + str += wxT("UNIQUE "); + str += wxT("INDEX "); + str += qtIdent(GetName()) + + wxT("\n ON ") + GetQuotedSchemaPrefix(GetIdxSchema()) + qtIdent(GetIdxTable()) + + wxT("\n USING ") + GetIndexType() + + wxT("\n ("); + if (GetProcName().IsNull()) + str += GetQuotedColumns(); + else + { + str += GetQuotedSchemaPrefix(GetProcNamespace()) + qtIdent(GetProcName()) + wxT("(") + GetQuotedColumns() + wxT(")"); + if (!this->GetOperatorClasses().IsNull()) + str += wxT(" ") + GetOperatorClasses(); + } + + str += wxT(")"); + + if (GetConnection()->BackendMinimumVersion(8, 2) && GetFillFactor().Length() > 0) + str += wxT("\n WITH (FILLFACTOR=") + GetFillFactor() + wxT(")"); + + if (GetConnection()->BackendMinimumVersion(8, 0) && tablespace != GetDatabase()->GetDefaultTablespace()) + str += wxT("\nTABLESPACE ") + qtIdent(tablespace); + + AppendIfFilled(str, wxT("\n WHERE "), GetConstraint()); + + str += wxT(";\n"); + + if (GetConnection()->BackendMinimumVersion(7, 5)) + if (GetIsClustered()) + str += wxT("ALTER TABLE ") + GetQuotedSchemaPrefix(GetIdxSchema()) + qtIdent(GetIdxTable()) + + wxT(" CLUSTER ON ") + qtIdent(GetName()) + + wxT(";\n"); + + return str; +} + + +wxString pgIndexBase::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Index: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP INDEX ") + GetQuotedFullIdentifier() + wxT(";\n\n") + + GetCreate() + + GetCommentSql(); + } + return sql; +} + + + +void pgIndexBase::ReadColumnDetails() +{ + if (!expandedKids) + { + expandedKids = true; + bool indexconstraint = GetMetaType() == PGM_PRIMARYKEY || GetMetaType() == PGM_UNIQUE || GetMetaType() == PGM_EXCLUDE; + + // Allocate memory to store column def + if (columnCount > 0) columnList.Alloc(columnCount); + + if (GetConnection()->BackendMinimumVersion(7, 4)) + { + long i; + + for (i = 1 ; i <= columnCount ; i++) + { + if (i > 1) + { + columns += wxT(", "); + quotedColumns += wxT(", "); + } + + wxString options, coldef, opcname; + if (GetConnection()->BackendMinimumVersion(8, 3)) + options = wxT(" i.indoption[") + NumToStr((long)(i - 1)) + wxT("] AS options,\n"); + + pgSet *res; + wxString query; + + if (GetConnection()->BackendMinimumVersion(9, 0)) + { + query = wxT("SELECT\n") + options + + wxT(" pg_get_indexdef(i.indexrelid, ") + NumToStr(i) + GetDatabase()->GetPrettyOption() + wxT(") AS coldef,\n") + + wxT(" op.oprname,\n") + + wxT(" CASE WHEN (o.opcdefault = FALSE) THEN o.opcname ELSE null END AS opcname\n"); + if (GetConnection()->BackendMinimumVersion(9, 1)) + query += wxT(",\n coll.collname, nspc.nspname as collnspname\n"); + query += wxT("FROM pg_index i\n") + wxT("JOIN pg_attribute a ON (a.attrelid = i.indexrelid AND attnum = ") + NumToStr(i) + wxT(")\n") + + wxT("LEFT OUTER JOIN pg_opclass o ON (o.oid = i.indclass[") + NumToStr((long)(i - 1)) + wxT("])\n") + + wxT("LEFT OUTER JOIN pg_constraint c ON (c.conindid = i.indexrelid) ") + wxT("LEFT OUTER JOIN pg_operator op ON (op.oid = c.conexclop[") + NumToStr(i) + wxT("])\n"); + if (GetConnection()->BackendMinimumVersion(9, 1)) + query += wxT("LEFT OUTER JOIN pg_collation coll ON a.attcollation=coll.oid\n") + wxT("LEFT OUTER JOIN pg_namespace nspc ON coll.collnamespace=nspc.oid\n"); + query += wxT("WHERE i.indexrelid = ") + GetOidStr(); + } + else + { + query = wxT("SELECT\n") + options + + wxT(" pg_get_indexdef(i.indexrelid, ") + NumToStr(i) + GetDatabase()->GetPrettyOption() + wxT(") AS coldef,\n") + + wxT(" CASE WHEN (o.opcdefault = FALSE) THEN o.opcname ELSE null END AS opcname\n") + + wxT("FROM pg_index i\n") + + wxT("JOIN pg_attribute a ON (a.attrelid = i.indexrelid AND attnum = ") + NumToStr(i) + wxT(")\n") + + wxT("LEFT OUTER JOIN pg_opclass o ON (o.oid = i.indclass[") + NumToStr((long)(i - 1)) + wxT("])\n") + + wxT("WHERE i.indexrelid = ") + GetOidStr(); + } + + res = ExecuteSet(query); + + if (res->NumRows() > 0) + { + coldef = res->GetVal(wxT("coldef")); + + if (GetConnection()->BackendMinimumVersion(9, 1) && !indexconstraint) + { + wxString collation = wxEmptyString; + if (!res->GetVal(wxT("collname")).IsEmpty()) + { + collation = qtIdent(res->GetVal(wxT("collnspname"))) + wxT(".") + qtIdent(res->GetVal(wxT("collname"))); + coldef += wxT(" COLLATE ") + collation; + } + collationsArray.Add(collation); + } + else + { + collationsArray.Add(wxEmptyString); + } + + opcname = res->GetVal(wxT("opcname")); + opclassesArray.Add(opcname); + if (!opcname.IsEmpty()) + coldef += wxT(" ") + opcname; + + // Get the column options + if (GetConnection()->BackendMinimumVersion(8, 3)) + { + long opt = res->GetLong(wxT("options")); + + if (opt && (opt & 0x0001)) // Descending... + { + ordersArray.Add(wxT("DESC")); + coldef += wxT(" DESC"); + // NULLS FIRST is the default for descending + if (!(opt && (opt & 0x0002))) + { + nullsArray.Add(wxT("NULLS LAST")); + coldef += wxT(" NULLS LAST"); + } + else + { + nullsArray.Add(wxEmptyString); + } + } + else // Ascending... + { + ordersArray.Add(wxT("ASC")); + if ((opt && (opt & 0x0002))) + { + nullsArray.Add(wxT("NULLS FIRST")); + coldef += wxT(" NULLS FIRST"); + } + else + { + nullsArray.Add(wxEmptyString); + } + } + } + else + { + ordersArray.Add(wxEmptyString); + nullsArray.Add(wxEmptyString); + } + } + + if (isExclude) + { + coldef += wxT(" WITH ") + res->GetVal(wxT("oprname")); + } + columns += coldef; + quotedColumns += coldef; + columnList.Add(coldef); + + //resolve memory leak occurred while expanding the index node in object browser + delete res; + res = NULL; + } + } + else + { + // its a 7.3 db + + // We cannot use SELECT IN (colNumbers) here because we couldn't be sure + // about the read order + wxStringTokenizer collist(GetColumnNumbers()); + wxStringTokenizer args(procArgTypeList); + wxString cn, ct; + columnCount = 0; + + while (collist.HasMoreTokens()) + { + cn = collist.GetNextToken(); + ct = args.GetNextToken(); + + pgSet *colSet = ExecuteSet( + wxT("SELECT attname as conattname\n") + wxT(" FROM pg_attribute\n") + wxT(" WHERE attrelid=") + GetOidStr() + wxT(" AND attnum=") + cn); + if (colSet) + { + if (columnCount) + { + columns += wxT(", "); + quotedColumns += wxT(", "); + } + wxString colName = colSet->GetVal(0); + columns += colName; + columnList.Add(colName); + ordersArray.Add(wxEmptyString); + nullsArray.Add(wxEmptyString); + opclassesArray.Add(wxEmptyString); + collationsArray.Add(wxEmptyString); + quotedColumns += qtIdent(colName); + + if (!ct.IsNull()) + { + pgSet *typeSet = ExecuteSet(wxT( + "SELECT typname FROM pg_type where oid=") + ct); + if (typeSet) + { + if (columnCount) + { + procArgs += wxT(", "); + typedColumns += wxT(", "); + quotedTypedColumns += wxT(", "); + } + wxString colType = typeSet->GetVal(0); + procArgs += colType; + typedColumns += colName + wxT("::") + colType; + quotedTypedColumns += qtIdent(colName) + wxT("::") + colType; + delete typeSet; + } + } + delete colSet; + } + columnCount++; + } + } + wxStringTokenizer ops(operatorClassList); + wxString op; + while (ops.HasMoreTokens()) + { + op = ops.GetNextToken(); + pgSet *set = ExecuteSet(wxT( + "SELECT opcname FROM pg_opclass WHERE oid=") + op); + if (set) + { + if (!operatorClasses.IsNull()) + operatorClasses += wxT(", "); + operatorClasses += set->GetVal(0); + delete set; + } + } + } +} + + +void pgIndexBase::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + ReadColumnDetails(); + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + if (GetConnection()->BackendMinimumVersion(8, 0)) + properties->AppendItem(_("Tablespace"), tablespace); + if (!GetProcName().IsNull()) + properties->AppendItem(_("Procedure "), GetSchemaPrefix(GetProcNamespace()) + GetProcName() + wxT("(") + GetTypedColumns() + wxT(")")); + else + properties->AppendItem(_("Columns"), GetColumns()); + + properties->AppendItem(_("Operator classes"), GetOperatorClasses()); + properties->AppendYesNoItem(_("Unique?"), GetIsUnique()); + properties->AppendYesNoItem(_("Primary?"), GetIsPrimary()); + properties->AppendYesNoItem(_("Clustered?"), GetIsClustered()); + properties->AppendYesNoItem(_("Valid?"), GetIsValid()); + properties->AppendItem(_("Access method"), GetIndexType()); + properties->AppendItem(_("Constraint"), GetConstraint()); + properties->AppendYesNoItem(_("System index?"), GetSystemObject()); + if (GetConnection()->BackendMinimumVersion(8, 2)) + properties->AppendItem(_("Fill factor"), GetFillFactor()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + +void pgIndexBase::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + wxString sql = + wxT("SELECT idx_scan AS ") + qtIdent(_("Index Scans")) + + wxT(", idx_tup_read AS ") + qtIdent(_("Index Tuples Read")) + + wxT(", idx_tup_fetch AS ") + qtIdent(_("Index Tuples Fetched")) + + wxT(", idx_blks_read AS ") + qtIdent(_("Index Blocks Read")) + + wxT(", idx_blks_hit AS ") + qtIdent(_("Index Blocks Hit")); + + if (GetConnection()->HasFeature(FEATURE_SIZE)) + sql += wxT(", pg_size_pretty(pg_relation_size(") + GetOidStr() + wxT(")) AS ") + qtIdent(_("Index Size")); + + if (showExtendedStatistics) + { + sql += wxT(", version AS ") + qtIdent(_("Version")) + wxT(",\n") + wxT(" tree_level AS ") + qtIdent(_("Tree Level")) + wxT(",\n") + wxT(" pg_size_pretty(index_size) AS ") + qtIdent(_("Index Size")) + wxT(",\n") + wxT(" root_block_no AS ") + qtIdent(_("Root Block No")) + wxT(",\n") + wxT(" internal_pages AS ") + qtIdent(_("Internal Pages")) + wxT(",\n") + wxT(" leaf_pages AS ") + qtIdent(_("Leaf Pages")) + wxT(",\n") + wxT(" empty_pages AS ") + qtIdent(_("Empty Pages")) + wxT(",\n") + wxT(" deleted_pages AS ") + qtIdent(_("Deleted Pages")) + wxT(",\n") + wxT(" avg_leaf_density AS ") + qtIdent(_("Average Leaf Density")) + wxT(",\n") + wxT(" leaf_fragmentation AS ") + qtIdent(_("Leaf Fragmentation")) + wxT("\n") + wxT(" FROM pgstatindex('") + GetQuotedFullIdentifier() + wxT("'), pg_stat_all_indexes stat"); + } + else + { + sql += wxT("\n") + wxT(" FROM pg_stat_all_indexes stat"); + } + sql += wxT("\n") + wxT(" JOIN pg_statio_all_indexes statio ON stat.indexrelid = statio.indexrelid\n") + wxT(" JOIN pg_class cl ON cl.oid=stat.indexrelid\n") + wxT(" WHERE stat.indexrelid = ") + GetOidStr(); + + DisplayStatistics(statistics, sql); +} + + +pgObject *pgIndexBase::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *index = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + index = indexFactory.CreateObjects(coll, 0, wxT("\n AND cls.oid=") + GetOidStr()); + + return index; +} + + +bool pgIndexBase::HasPgstatindex() +{ + return GetConnection()->HasFeature(FEATURE_PGSTATINDEX); +} + + +executePgstatindexFactory::executePgstatindexFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Extended index statistics"), _("Get extended statistics via pgstatindex for the selected object."), wxITEM_CHECK); +} + + +wxWindow *executePgstatindexFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (!((pgIndexBase *)obj)->GetShowExtendedStatistics()) + { + ((pgIndexBase *)obj)->iSetShowExtendedStatistics(true); + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + form->SelectStatisticsTab(); + } + else + ((pgIndexBase *)obj)->iSetShowExtendedStatistics(false); + + form->GetMenuFactories()->CheckMenu(obj, form->GetMenuBar(), (ctlMenuToolbar *)form->GetToolBar()); + + return 0; +} + + +bool executePgstatindexFactory::CheckEnable(pgObject *obj) +{ + return obj && + (obj->IsCreatedBy(indexFactory) || obj->IsCreatedBy(primaryKeyFactory) + || obj->IsCreatedBy(uniqueFactory) || obj->IsCreatedBy(excludeFactory)) && + ((pgIndexBase *)obj)->HasPgstatindex(); +} + +bool executePgstatindexFactory::CheckChecked(pgObject *obj) +{ + if (!obj) + return false; + + if (obj->GetMetaType() == PGM_INDEX || obj->GetMetaType() == PGM_PRIMARYKEY + || obj->GetMetaType() == PGM_UNIQUE || obj->GetMetaType() == PGM_EXCLUDE) + return ((pgIndexBase *)obj)->GetShowExtendedStatistics(); + + return false; +} + + +pgIndex::pgIndex(pgSchema *newSchema, const wxString &newName) + : pgIndexBase(newSchema, indexFactory, newName) +{ +} + + +pgObject *pgIndexBaseFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restriction) +{ + pgSchemaObjCollection *collection = (pgSchemaObjCollection *)coll; + pgIndexBase *index = 0; + wxString query; + + wxString proname, projoin; + if (collection->GetConnection()->BackendMinimumVersion(7, 4)) + { + proname = wxT("indnatts, "); + if (collection->GetConnection()->BackendMinimumVersion(7, 5)) + { + proname += wxT("cls.reltablespace AS spcoid, spcname, "); + projoin = wxT(" LEFT OUTER JOIN pg_tablespace ta on ta.oid=cls.reltablespace\n"); + } + } + else + { + proname = wxT("proname, pn.nspname as pronspname, proargtypes, "); + projoin = wxT(" LEFT OUTER JOIN pg_proc pr ON pr.oid=indproc\n") + wxT(" LEFT OUTER JOIN pg_namespace pn ON pn.oid=pr.pronamespace\n"); + } + query = wxT("SELECT DISTINCT ON(cls.relname) cls.oid, cls.relname as idxname, indrelid, indkey, indisclustered, indisvalid, indisunique, indisprimary, n.nspname,\n") + wxT(" ") + proname + wxT("tab.relname as tabname, indclass, con.oid AS conoid, CASE contype WHEN 'p' THEN desp.description WHEN 'u' THEN desp.description WHEN 'x' THEN desp.description ELSE des.description END AS description,\n") + wxT(" pg_get_expr(indpred, indrelid") + collection->GetDatabase()->GetPrettyOption() + wxT(") as indconstraint, contype, condeferrable, condeferred, amname\n"); + if (collection->GetConnection()->BackendMinimumVersion(8, 2)) + query += wxT(", substring(array_to_string(cls.reloptions, ',') from 'fillfactor=([0-9]*)') AS fillfactor \n"); + query += wxT(" FROM pg_index idx\n") + wxT(" JOIN pg_class cls ON cls.oid=indexrelid\n") + wxT(" JOIN pg_class tab ON tab.oid=indrelid\n") + + projoin + + wxT(" JOIN pg_namespace n ON n.oid=tab.relnamespace\n") + wxT(" JOIN pg_am am ON am.oid=cls.relam\n") + wxT(" LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i')\n") + wxT(" LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=cls.oid AND des.classoid='pg_class'::regclass)\n") + wxT(" LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0 AND desp.classoid='pg_constraint'::regclass)\n") + wxT(" WHERE indrelid = ") + collection->GetOidStr() + + restriction + wxT("\n") + wxT(" ORDER BY cls.relname"); + pgSet *indexes = collection->GetDatabase()->ExecuteSet(query); + + if (indexes) + { + while (!indexes->Eof()) + { + switch (*(indexes->GetCharPtr(wxT("contype")))) + { + case 0: + index = new pgIndex(collection->GetSchema()->GetSchema(), indexes->GetVal(wxT("idxname"))); + break; + case 'p': + index = new pgPrimaryKey(collection->GetSchema()->GetSchema(), indexes->GetVal(wxT("idxname"))); + ((pgPrimaryKey *)index)->iSetConstraintOid(indexes->GetOid(wxT("conoid"))); + break; + case 'u': + index = new pgUnique(collection->GetSchema()->GetSchema(), indexes->GetVal(wxT("idxname"))); + ((pgUnique *)index)->iSetConstraintOid(indexes->GetOid(wxT("conoid"))); + break; + case 'x': + index = new pgExclude(collection->GetSchema()->GetSchema(), indexes->GetVal(wxT("idxname"))); + ((pgExclude *)index)->iSetConstraintOid(indexes->GetOid(wxT("conoid"))); + break; + default: + index = 0; + break; + } + + index->iSetOid(indexes->GetOid(wxT("oid"))); + index->iSetIsClustered(indexes->GetBool(wxT("indisclustered"))); + index->iSetIsValid(indexes->GetBool(wxT("indisvalid"))); + index->iSetIsUnique(indexes->GetBool(wxT("indisunique"))); + index->iSetIsPrimary(indexes->GetBool(wxT("indisprimary"))); + index->iSetIsExclude(*(indexes->GetCharPtr(wxT("contype"))) == 'x'); + index->iSetColumnNumbers(indexes->GetVal(wxT("indkey"))); + index->iSetIdxSchema(indexes->GetVal(wxT("nspname"))); + index->iSetComment(indexes->GetVal(wxT("description"))); + index->iSetIdxTable(indexes->GetVal(wxT("tabname"))); + index->iSetRelTableOid(indexes->GetOid(wxT("indrelid"))); + if (collection->GetConnection()->BackendMinimumVersion(7, 4)) + { + index->iSetColumnCount(indexes->GetLong(wxT("indnatts"))); + if (collection->GetConnection()->BackendMinimumVersion(8, 0)) + { + if (indexes->GetOid(wxT("spcoid")) == 0) + index->iSetTablespaceOid(collection->GetDatabase()->GetTablespaceOid()); + else + index->iSetTablespaceOid(indexes->GetOid(wxT("spcoid"))); + + if (indexes->GetVal(wxT("spcname")) == wxEmptyString) + index->iSetTablespace(collection->GetDatabase()->GetTablespace()); + else + index->iSetTablespace(indexes->GetVal(wxT("spcname"))); + } + + } + else + { + index->iSetColumnCount(0L); + index->iSetProcNamespace(indexes->GetVal(wxT("pronspname"))); + index->iSetProcName(indexes->GetVal(wxT("proname"))); + index->iSetProcArgTypeList(indexes->GetVal(wxT("proargtypes"))); + } + index->iSetOperatorClassList(indexes->GetVal(wxT("indclass"))); + index->iSetDeferrable(indexes->GetBool(wxT("condeferrable"))); + index->iSetDeferred(indexes->GetBool(wxT("condeferred"))); + index->iSetConstraint(indexes->GetVal(wxT("indconstraint"))); + index->iSetIndexType(indexes->GetVal(wxT("amname"))); + if (collection->GetConnection()->BackendMinimumVersion(8, 2)) + index->iSetFillFactor(indexes->GetVal(wxT("fillfactor"))); + + if (browser) + { + browser->AppendObject(collection, index); + indexes->MoveNext(); + } + else + break; + } + + delete indexes; + } + return index; +} + + +pgCollection *pgIndexBaseFactory::CreateCollection(pgObject *obj) +{ + return new pgIndexBaseCollection(GetCollectionFactory(), (pgSchema *)obj); +} + + + +pgObject *pgIndexFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + return pgIndexBaseFactory::CreateObjects(collection, browser, restriction + wxT("\n AND conname IS NULL")); +} + + +wxString pgIndexBaseCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on indexes"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing indexes"); + break; + case OBJECTSLISTREPORT: + message = _("Indexes list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/index.pngc" +#include "images/indexes.pngc" + +pgIndexFactory::pgIndexFactory() + : pgIndexBaseFactory(__("Index"), __("New Index..."), __("Create a new Index."), index_png_img) +{ + metaType = PGM_INDEX; +} + + +pgIndexFactory indexFactory; +static pgaCollectionFactory cf(&indexFactory, __("Indexes"), indexes_png_img); + + +pgIndexBaseCollection::pgIndexBaseCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +void pgIndexBaseCollection::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + wxLogInfo(wxT("Displaying statistics for indexes on ") + GetSchema()->GetName()); + + bool hasSize = GetConnection()->HasFeature(FEATURE_SIZE); + + // Add the statistics view columns + statistics->ClearAll(); + statistics->AddColumn(_("Index Name")); + statistics->AddColumn(_("Index Scans")); + statistics->AddColumn(_("Index Tuples Read")); + statistics->AddColumn(_("Index Tuples Fetched")); + if (hasSize) + statistics->AddColumn(_("Size")); + + wxString sql = wxT("SELECT indexrelname, ") + wxT("idx_scan, idx_tup_read, idx_tup_fetch"); + + if (hasSize) + sql += wxT(", pg_size_pretty(pg_relation_size(indexrelid)) AS ") + qtIdent(wxT("size")); + + sql += wxT("\n") + wxT(" FROM pg_stat_all_indexes stat\n") + wxT(" JOIN pg_class cls ON cls.oid=indexrelid\n") + wxT(" LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint'))\n") + wxT(" LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)\n") + wxT(" WHERE schemaname = ") + qtDbString(GetSchema()->GetSchema()->GetName()) + + wxT(" AND stat.relname = ") + qtDbString(GetSchema()->GetName()) + + wxT(" AND con.contype IS NULL") + + wxT("\n ORDER BY indexrelname"); + + pgSet *stats = GetDatabase()->ExecuteSet(sql); + + if (stats) + { + long pos = 0; + while (!stats->Eof()) + { + statistics->InsertItem(pos, stats->GetVal(wxT("indexrelname")), PGICON_STATISTICS); + statistics->SetItem(pos, 1, stats->GetVal(wxT("idx_scan"))); + statistics->SetItem(pos, 2, stats->GetVal(wxT("idx_tup_read"))); + statistics->SetItem(pos, 3, stats->GetVal(wxT("idx_tup_fetch"))); + if (hasSize) + statistics->SetItem(pos, 4, stats->GetVal(wxT("size"))); + stats->MoveNext(); + pos++; + } + + delete stats; + } +} diff --git a/schema/pgIndexConstraint.cpp b/schema/pgIndexConstraint.cpp new file mode 100644 index 0000000..2c4b2d3 --- /dev/null +++ b/schema/pgIndexConstraint.cpp @@ -0,0 +1,504 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgIndexConstraint.cpp - IndexConstraint class: Primary Key, Unique +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgConstraints.h" +#include "schema/pgIndexConstraint.h" + + + +wxString pgIndexConstraint::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on index constraint"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing index constraint"); + message += wxT(" ") + GetName(); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for index constraint"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop index constraint \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop index constraint \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop index constraint cascaded?"); + break; + case DROPTITLE: + message = _("Drop index constraint?"); + break; + case PROPERTIESREPORT: + message = _("Index constraint properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Index constraint properties"); + break; + case DDLREPORT: + message = _("Index constraint DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Index constraint DDL"); + break; + case STATISTICSREPORT: + message = _("Index constraint statistics report"); + message += wxT(" - ") + GetName(); + break; + case OBJSTATISTICS: + message = _("Index constraint statistics"); + break; + case DEPENDENCIESREPORT: + message = _("Index constraint dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Index constraint dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Index constraint dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Index constraint dependents"); + break; + } + + return message; +} + + +bool pgIndexConstraint::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("ALTER TABLE ") + qtIdent(GetIdxSchema()) + wxT(".") + qtIdent(GetIdxTable()) + + wxT(" DROP CONSTRAINT ") + GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgIndexConstraint::GetDefinition() +{ + wxString sql = wxEmptyString; + + if (wxString(GetTypeName()).Upper() == wxT("EXCLUDE")) + sql += wxT("\n USING ") + GetIndexType() + wxT(" "); + + sql += wxT("(") + GetQuotedColumns() + wxT(")"); + + if (GetConnection()->BackendMinimumVersion(8, 2) && GetFillFactor().Length() > 0) + sql += wxT("\n WITH (FILLFACTOR=") + GetFillFactor() + wxT(")"); + + if (GetConnection()->BackendMinimumVersion(8, 0) && GetTablespace() != GetDatabase()->GetDefaultTablespace()) + sql += wxT("\n USING INDEX TABLESPACE ") + qtIdent(GetTablespace()); + + if (GetConstraint().Length() > 0) + sql += wxT(" WHERE (") + GetConstraint() + wxT(")"); + + if (GetDeferrable()) + { + sql += wxT("\n DEFERRABLE INITIALLY "); + if (GetDeferred()) + sql += wxT("DEFERRED"); + else + sql += wxT("IMMEDIATE"); + } + return sql; +} + + +wxString pgIndexConstraint::GetCreate() +{ + wxString sql; + + sql = GetQuotedIdentifier() + wxT(" ") + + GetTypeName().Upper() + GetDefinition(); + + return sql; +}; + + +wxString pgIndexConstraint::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Constraint: ") + GetQuotedFullIdentifier() + + wxT("\n\n-- ALTER TABLE ") + GetQuotedSchemaPrefix(GetIdxSchema()) + qtIdent(GetIdxTable()) + + wxT(" DROP CONSTRAINT ") + GetQuotedIdentifier() + wxT(";") + + wxT("\n\nALTER TABLE ") + GetQuotedSchemaPrefix(GetIdxSchema()) + qtIdent(GetIdxTable()) + + wxT("\n ADD CONSTRAINT ") + + GetCreate() + + wxT(";\n"); + + if (!GetComment().IsNull()) + { + sql += wxT("COMMENT ON CONSTRAINT ") + GetQuotedIdentifier() + wxT(" ON ") + GetQuotedSchemaPrefix(GetIdxSchema()) + qtIdent(GetIdxTable()) + + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + } + return sql; +} + + + +void pgIndexConstraint::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + ReadColumnDetails(); + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetConstraintOid()); + properties->AppendItem(_("Index OID"), GetOid()); + if (GetConnection()->BackendMinimumVersion(8, 0)) + properties->AppendItem(_("Tablespace"), GetTablespace()); + if (GetProcName().IsNull()) + properties->AppendItem(_("Columns"), GetColumns()); + else + { + properties->AppendItem(_("Procedure "), GetSchemaPrefix(GetProcNamespace()) + GetProcName() + wxT("(") + GetTypedColumns() + wxT(")")); + properties->AppendItem(_("Operator classes"), GetOperatorClasses()); + } + properties->AppendYesNoItem(_("Unique?"), GetIsUnique()); + properties->AppendYesNoItem(_("Primary?"), GetIsPrimary()); + properties->AppendYesNoItem(_("Clustered?"), GetIsClustered()); + properties->AppendYesNoItem(_("Valid?"), GetIsValid()); + properties->AppendItem(_("Access method"), GetIndexType()); + properties->AppendItem(_("Constraint"), GetConstraint()); + properties->AppendYesNoItem(_("System index?"), GetSystemObject()); + if (GetConnection()->BackendMinimumVersion(8, 2)) + properties->AppendItem(_("Fill factor"), GetFillFactor()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + +wxString pgPrimaryKey::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on primary key"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing primary key"); + message += wxT(" ") + GetName(); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for primary key"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop primary key \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop primary key \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop primary key cascaded?"); + break; + case DROPTITLE: + message = _("Drop primary key?"); + break; + case PROPERTIESREPORT: + message = _("Primary key properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Primary key properties"); + break; + case DDLREPORT: + message = _("Primary key DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Primary key DDL"); + break; + case STATISTICSREPORT: + message = _("Primary key statistics report"); + message += wxT(" - ") + GetName(); + break; + case OBJSTATISTICS: + message = _("Primary key statistics"); + break; + case DEPENDENCIESREPORT: + message = _("Primary key dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Primary key dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Primary key dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Primary key dependents"); + break; + } + + return message; +} + + +pgObject *pgPrimaryKey::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *index = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + index = primaryKeyFactory.CreateObjects(coll, 0, wxT("\n AND cls.oid=") + GetOidStr()); + + return index; +} + +wxString pgUnique::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on unique constraint"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing unique constraint"); + message += wxT(" ") + GetName(); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for unique constraint"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop unique constraint \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop unique constraint \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop unique constraint cascaded?"); + break; + case DROPTITLE: + message = _("Drop unique constraint?"); + break; + case PROPERTIESREPORT: + message = _("Unique constraint properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Unique constraint properties"); + break; + case DDLREPORT: + message = _("Unique constraint DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Unique constraint DDL"); + break; + case STATISTICSREPORT: + message = _("Unique constraint statistics report"); + message += wxT(" - ") + GetName(); + break; + case OBJSTATISTICS: + message = _("Unique constraint statistics"); + break; + case DEPENDENCIESREPORT: + message = _("Unique constraint dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Unique constraint dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Unique constraint dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Unique constraint dependents"); + break; + } + + return message; +} + + +pgObject *pgUnique::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *index = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + index = uniqueFactory.CreateObjects(coll, 0, wxT("\n AND cls.oid=") + GetOidStr()); + + return index; +} + +wxString pgExclude::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on exclusion constraint"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing exclusion constraint"); + message += wxT(" ") + GetName(); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for exclusion constraint"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop exclusion constraint \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop exclusion constraint \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop exclusion constraint cascaded?"); + break; + case DROPTITLE: + message = _("Drop exclusion constraint?"); + break; + case PROPERTIESREPORT: + message = _("Exclusion constraint properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Exclusion constraint properties"); + break; + case DDLREPORT: + message = _("Exclusion constraint DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Exclusion constraint DDL"); + break; + case STATISTICSREPORT: + message = _("Exclusion constraint statistics report"); + message += wxT(" - ") + GetName(); + break; + case OBJSTATISTICS: + message = _("Exclusion constraint statistics"); + break; + case DEPENDENCIESREPORT: + message = _("Exclusion constraint dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Exclusion constraint dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Exclusion constraint dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Exclusion constraint dependents"); + break; + } + + return message; +} + + +pgObject *pgExclude::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *index = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + index = excludeFactory.CreateObjects(coll, 0, wxT("\n AND cls.oid=") + GetOidStr()); + + return index; +} + +pgObject *pgPrimaryKeyFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &where) +{ + return pgIndexBaseFactory::CreateObjects(collection, browser, wxT(" AND contype='p'\n") + where); +} + + +pgObject *pgUniqueFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &where) +{ + return pgIndexBaseFactory::CreateObjects(collection, browser, wxT(" AND contype='u'\n") + where); +} + + +pgObject *pgExcludeFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &where) +{ + return pgIndexBaseFactory::CreateObjects(collection, browser, wxT(" AND contype='x'\n") + where); +} + + +#include "images/primarykey.pngc" + +pgPrimaryKeyFactory::pgPrimaryKeyFactory() + : pgIndexBaseFactory(__("Primary Key"), __("New Primary Key..."), __("Create a new Primary Key constraint."), primarykey_png_img) +{ + metaType = PGM_PRIMARYKEY; + collectionFactory = &constraintCollectionFactory; +} + + +pgPrimaryKeyFactory primaryKeyFactory; + +#include "images/unique.pngc" + +pgUniqueFactory::pgUniqueFactory() + : pgIndexBaseFactory(__("Unique"), __("New Unique Constraint..."), __("Create a new Unique constraint."), unique_png_img) +{ + metaType = PGM_UNIQUE; + collectionFactory = &constraintCollectionFactory; +} + + +pgUniqueFactory uniqueFactory; + + +#include "images/exclude.pngc" + +pgExcludeFactory::pgExcludeFactory() + : pgIndexBaseFactory(__("Exclude"), __("New Exclusion Constraint..."), __("Create a new Exclusion constraint."), exclude_png_img) +{ + metaType = PGM_EXCLUDE; + collectionFactory = &constraintCollectionFactory; +} + + +pgExcludeFactory excludeFactory; diff --git a/schema/pgLanguage.cpp b/schema/pgLanguage.cpp new file mode 100644 index 0000000..b1ba218 --- /dev/null +++ b/schema/pgLanguage.cpp @@ -0,0 +1,280 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgLanguage.cpp - Language class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgLanguage.h" + + +pgLanguage::pgLanguage(const wxString &newName) + : pgDatabaseObject(languageFactory, newName) +{ +} + +wxString pgLanguage::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on language"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing language"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop language \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop language \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop language cascaded?"); + break; + case DROPTITLE: + message = _("Drop language?"); + break; + case PROPERTIESREPORT: + message = _("Language properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Language properties"); + break; + case DDLREPORT: + message = _("Language DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Language DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Language dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Language dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Language dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Language dependents"); + break; + } + + return message; +} + +bool pgLanguage::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP LANGUAGE ") + GetQuotedFullIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + +wxString pgLanguage::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Language: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP LANGUAGE ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE "); + if (GetTrusted()) + sql += wxT("TRUSTED "); + sql += wxT("PROCEDURAL LANGUAGE '") + GetName() + + wxT("'\n HANDLER ") + qtIdent(GetHandlerProc()); + + if (!GetInlineProc().IsEmpty()) + sql += wxT("\n INLINE ") + qtIdent(GetInlineProc()); + + if (!GetValidatorProc().IsEmpty()) + sql += wxT("\n VALIDATOR ") + qtIdent(GetValidatorProc()); + + sql += wxT(";\n") + + GetOwnerSql(8, 3, wxT("LANGUAGE ") + GetName()) + + GetGrant(wxT("U"), wxT("LANGUAGE ") + GetQuotedFullIdentifier()); + + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += GetSeqLabelsSql(); + } + return sql; +} + +void pgLanguage::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + if (GetConnection()->BackendMinimumVersion(8, 3)) + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("ACL"), GetAcl()); + properties->AppendYesNoItem(_("Trusted?"), GetTrusted()); + properties->AppendItem(_("Handler function"), GetHandlerProc()); + if (GetConnection()->BackendMinimumVersion(9, 0)) + properties->AppendItem(_("Inline function"), GetInlineProc()); + properties->AppendItem(_("Validator function"), GetValidatorProc()); + properties->AppendYesNoItem(_("System language?"), GetSystemObject()); + if (GetConnection()->BackendMinimumVersion(7, 5)) + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + if (!GetLabels().IsEmpty()) + { + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); + } + } + } + } +} + +pgObject *pgLanguage::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *language = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + language = languageFactory.CreateObjects(coll, 0, wxT("\n AND lan.oid=") + GetOidStr()); + + return language; +} + +pgObject *pgLanguageFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + wxString sql; + pgLanguage *language = 0; + + sql = wxT("SELECT lan.oid, lanname, lanpltrusted, lanacl, hp.proname as lanproc, vp.proname as lanval, description"); + if (collection->GetConnection()->BackendMinimumVersion(8, 3)) + sql += wxT(", pg_get_userbyid(lan.lanowner) as languageowner"); + if (collection->GetConnection()->BackendMinimumVersion(9, 0)) + sql += wxT(", ip.proname as laninl"); + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + sql += wxT(",\n(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=lan.oid) AS labels"); + sql += wxT(",\n(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=lan.oid) AS providers"); + } + sql += wxT("\n FROM pg_language lan\n") + wxT(" JOIN pg_proc hp on hp.oid=lanplcallfoid\n"); + if (collection->GetConnection()->BackendMinimumVersion(9, 0)) + sql += wxT(" LEFT OUTER JOIN pg_proc ip on ip.oid=laninline\n"); + sql += wxT(" LEFT OUTER JOIN pg_proc vp on vp.oid=lanvalidator\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=lan.oid AND des.objsubid=0 AND des.classoid='pg_language'::regclass)\n") + wxT(" WHERE lanispl IS TRUE") + + restriction + wxT("\n") + wxT(" ORDER BY lanname"); + pgSet *languages = collection->GetDatabase()->ExecuteSet(sql); + + if (languages) + { + while (!languages->Eof()) + { + + language = new pgLanguage(languages->GetVal(wxT("lanname"))); + language->iSetDatabase(collection->GetDatabase()); + language->iSetOid(languages->GetOid(wxT("oid"))); + if (collection->GetConnection()->BackendMinimumVersion(8, 3)) + { + language->iSetOwner(languages->GetVal(wxT("languageowner"))); + } + language->iSetAcl(languages->GetVal(wxT("lanacl"))); + language->iSetComment(languages->GetVal(wxT("description"))); + language->iSetHandlerProc(languages->GetVal(wxT("lanproc"))); + if (collection->GetConnection()->BackendMinimumVersion(9, 0)) + { + language->iSetInlineProc(languages->GetVal(wxT("laninl"))); + } + language->iSetValidatorProc(languages->GetVal(wxT("lanval"))); + language->iSetTrusted(languages->GetBool(wxT("lanpltrusted"))); + + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + language->iSetProviders(languages->GetVal(wxT("providers"))); + language->iSetLabels(languages->GetVal(wxT("labels"))); + } + + if (browser) + { + browser->AppendObject(collection, language); + languages->MoveNext(); + } + else + break; + } + + delete languages; + } + return language; +} + +///////////////////////////// + +pgLanguageCollection::pgLanguageCollection(pgaFactory *factory, pgDatabase *db) + : pgDatabaseObjCollection(factory, db) +{ +} + +wxString pgLanguageCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on languages"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing languages"); + break; + case OBJECTSLISTREPORT: + message = _("Languages list report"); + break; + } + + return message; +} + +/////////////////////////////////////////////////// + +#include "images/language.pngc" +#include "images/language-sm.pngc" +#include "images/languages.pngc" + +pgLanguageFactory::pgLanguageFactory() + : pgDatabaseObjFactory(__("Language"), __("New Language..."), __("Create a new Language."), language_png_img, language_sm_png_img) +{ + metaType = PGM_LANGUAGE; +} + +pgCollection *pgLanguageFactory::CreateCollection(pgObject *obj) +{ + return new pgLanguageCollection(GetCollectionFactory(), (pgDatabase *)obj); +} + +pgLanguageFactory languageFactory; +static pgaCollectionFactory cf(&languageFactory, __("Languages"), languages_png_img); diff --git a/schema/pgObject.cpp b/schema/pgObject.cpp new file mode 100644 index 0000000..c824c5d --- /dev/null +++ b/schema/pgObject.cpp @@ -0,0 +1,2158 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgObject.cpp - PostgreSQL object base class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgObject.h" +#include "schema/pgServer.h" +#include "frm/frmMain.h" +#include "frm/frmReport.h" +#include "schema/pgDomain.h" +#include "schema/pgAggregate.h" +#include "schema/pgSequence.h" +#include "schema/pgFunction.h" +#include "schema/pgType.h" +#include "schema/pgDatabase.h" +#include "schema/pgTable.h" +#include "schema/pgColumn.h" +#include "schema/pgView.h" +#include "schema/pgType.h" +#include "schema/pgOperator.h" +#include "schema/pgLanguage.h" +#include "schema/pgConversion.h" +#include "schema/pgTablespace.h" +#include "schema/pgGroup.h" +#include "schema/pgUser.h" +#include "schema/pgUserMapping.h" +#include "schema/pgIndex.h" +#include "schema/pgTrigger.h" +#include "schema/pgCheck.h" +#include "schema/pgIndexConstraint.h" +#include "schema/pgForeignKey.h" +#include "schema/pgForeignDataWrapper.h" +#include "schema/pgForeignServer.h" +#include "schema/pgForeignTable.h" +#include "schema/pgRule.h" +#include "schema/pgRole.h" +#include "schema/pgCast.h" +#include "schema/pgCatalogObject.h" +#include "schema/pgTextSearchConfiguration.h" +#include "schema/pgTextSearchDictionary.h" +#include "schema/pgTextSearchParser.h" +#include "schema/pgTextSearchTemplate.h" +#include "schema/pgOperatorClass.h" +#include "schema/pgOperatorFamily.h" +#include "schema/pgSchema.h" +#include "schema/pgIndexConstraint.h" +#include "schema/pgExtension.h" +#include "schema/edbPackage.h" +#include "schema/edbSynonym.h" +#include "schema/pgCollation.h" +#include "utils/pgDefs.h" +#include "schema/gpExtTable.h" +#include "schema/gpResQueue.h" +#include "agent/pgaJob.h" +#include "agent/pgaSchedule.h" +#include "agent/pgaStep.h" +#include "schema/pgPartition.h" + +int pgObject::GetType() const +{ + if (factory) + return factory->GetId(); + return type; +} + + +int pgObject::GetMetaType() const +{ + if (factory) + return factory->GetMetaType(); + return PGM_UNKNOWN; +} + + +wxString pgObject::GetTypeName() const +{ + return factory->GetTypeName(); +} + + +wxString pgObject::GetTranslatedTypeName() const +{ + return wxString(wxGetTranslation(GetTypeName())); +} + + +wxString pgObject::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on unknown object of type"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing unknown object of type"); + break; + case BACKUPGLOBALS: + message = _("Backup globals of unknown object of type"); + break; + case BACKUPSERVERTITLE: + message = _("Backup unknown object of type"); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop object \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPTITLE: + message = _("Drop object?"); + break; + case BACKUPTITLE: + message = wxString::Format(_("Backup \"%s\""), + GetFullIdentifier().c_str()); + break; + case RESTORETITLE: + message = wxString::Format(_("Restore \"%s\""), + GetFullIdentifier().c_str()); + break; + } + //message += wxT(" ") + factory->GetTypeName(); + + return message; +} + + +int pgObject::GetIconId() +{ + int id = -1; + if (factory) + id = factory->GetIconId(); + + wxASSERT(id != -1); + return id; +} + + +int pgObject::GetTypeId(const wxString &typname) +{ + pgaFactory *factory = pgaFactory::GetFactory(typname); + if (factory) + return factory->GetId(); + + return -1; +} + + +pgObject::pgObject(pgaFactory &_factory, const wxString &newName) + : wxTreeItemData(), oid(0) +{ + factory = &_factory; + + if (factory->IsCollection() && newName.IsEmpty()) + name = factory->GetTypeName(); + else + name = newName; + + type = factory->GetId(); + expandedKids = false; + needReread = false; + hintShown = false; + dlg = NULL; +} + + +pgObject::pgObject(int newType, const wxString &newName) + : wxTreeItemData(), oid(0) +{ + factory = pgaFactory::GetFactory(newType); + + // Set the typename and type + type = newType; + + if (newName.IsEmpty()) + name = factory->GetTypeName(); + else + name = newName; + expandedKids = false; + needReread = false; + hintShown = false; + dlg = NULL; +} + + +void pgObject::AppendMenu(wxMenu *menu, int type) +{ + if (menu) + factory->AppendMenu(menu); +} + + +wxString pgObject::GetHelpPage(bool forCreate) const +{ + wxString page; + + if (!IsCollection()) + page = wxT("pg/sql-create") + GetTypeName().Lower(); + + return page; +} + + +wxMenu *pgObject::GetNewMenu() +{ + wxMenu *menu = new wxMenu(); + if (CanCreate()) + AppendMenu(menu); + return menu; +} + +void pgObject::ShowStatistics(frmMain *form, ctlListView *statistics) +{ +} + + +bool pgObject::UpdateIcon(ctlTree *browser) +{ + int icon = GetIconId(); + if (GetId() && browser->GetItemImage(GetId(), wxTreeItemIcon_Normal) != icon) + { + browser->SetItemImage(GetId(), GetIconId(), wxTreeItemIcon_Normal); + browser->SetItemImage(GetId(), GetIconId(), wxTreeItemIcon_Selected); + return true; + } + return false; +} + + +void pgObject::ShowDependency(pgDatabase *db, ctlListView *list, const wxString &query, const wxString &clsorder) +{ + list->ClearAll(); + list->AddColumn(_("Type"), 60); + list->AddColumn(_("Name"), 100); + list->AddColumn(_("Restriction"), 50); + + pgConn *conn = GetConnection(); + if (conn) + { + pgSet *set; + // currently missing: + // - pg_cast + // - pg_operator + // - pg_opclass + + // not being implemented: + // - pg_index (done by pg_class) + + set = conn->ExecuteSet(query + wxT("\n") + wxT(" AND ") + clsorder + wxT(" IN (\n") + wxT(" SELECT oid FROM pg_class\n") + wxT(" WHERE relname IN ('pg_class', 'pg_constraint', 'pg_conversion', 'pg_language', 'pg_proc', 'pg_extension', \n") + wxT(" 'pg_rewrite', 'pg_namespace', 'pg_trigger', 'pg_type', 'pg_attrdef', 'pg_event_trigger'))\n") + wxT(" ORDER BY ") + clsorder + wxT(", cl.relkind")); + + if (set) + { + while (!set->Eof()) + { + wxString refname; + wxString _refname = set->GetVal(wxT("refname")); + + if (db) + refname = db->GetQuotedSchemaPrefix(set->GetVal(wxT("nspname"))); + else + { + refname = qtIdent(set->GetVal(wxT("nspname"))); + if (!refname.IsEmpty()) + refname += wxT("."); + } + + wxString typestr = set->GetVal(wxT("type")); + pgaFactory *depFactory = 0; + switch ((wxChar)typestr.c_str()[0]) + { + case 'c': + case 's': // we don't know these; internally handled + case 't': + set->MoveNext(); + continue; + + case 'r': + { + if (StrToLong(typestr.Mid(1)) > 0) + depFactory = &columnFactory; + else + depFactory = &tableFactory; + break; + } + case 'i': + depFactory = &indexFactory; + break; + case 'E': + depFactory = &extensionFactory; + break; + + case 'S': + depFactory = &sequenceFactory; + break; + case 'v': + depFactory = &viewFactory; + break; + case 'x': + depFactory = &extTableFactory; + break; + case 'p': + depFactory = &functionFactory; + break; + case 'n': + depFactory = &schemaFactory; + break; + case 'y': + depFactory = &typeFactory; + break; + case 'T': + depFactory = &triggerFactory; + break; + case 'f': + depFactory = &foreignTableFactory; + break; + + case 'l': + depFactory = &languageFactory; + break; + case 'R': + { + refname = _refname + wxT(" ON ") + refname + set->GetVal(wxT("ownertable")); + _refname = wxEmptyString; + depFactory = &ruleFactory; + break; + } + case 'C': + { + switch ((wxChar)typestr.c_str()[1]) + { + case 'c': + depFactory = &checkFactory; + break; + case 'f': + refname += set->GetVal(wxT("ownertable")) + wxT("."); + depFactory = &foreignKeyFactory; + break; + case 'p': + depFactory = &primaryKeyFactory; + break; + case 'u': + depFactory = &uniqueFactory; + break; + case 'x': + depFactory = &excludeFactory; + break; + default: + break; + } + break; + } + case 'A': + { + // Include only functions + if (set->GetVal(wxT("adbin")).StartsWith(wxT("{FUNCEXPR"))) + { + depFactory = &functionFactory; + refname = set->GetVal(wxT("adsrc")); + break; + } + else + { + set->MoveNext(); + continue; + } + } + default: + break; + } + + refname += _refname; + + wxString typname; + int icon; + if (depFactory) + { + typname = depFactory->GetTypeName(); + icon = depFactory->GetIconId(); + } + else + { + typname = _("Unknown"); + icon = -1; + } + + wxString deptype; + + switch ( (wxChar) set->GetVal(wxT("deptype")).c_str()[0]) + { + case 'n': + deptype = wxT("normal"); + break; + case 'a': + deptype = wxT("auto"); + break; + case 'i': + { + if (settings->GetShowSystemObjects()) + deptype = wxT("internal"); + else + { + set->MoveNext(); + continue; + } + break; + } + case 'p': + deptype = wxT("pin"); + typname = wxEmptyString; + break; + default: + break; + } + + list->AppendItem(icon, typname, refname, deptype); + set->MoveNext(); + } + delete set; + } + } +} + +void pgObject::CreateList3Columns(ctlListView *list, const wxString &left, const wxString &middle, const wxString &right) +{ + list->ClearAll(); + list->AddColumn(left, 80); + list->AddColumn(middle, 80); + list->AddColumn(right, list->GetSize().GetWidth() - 170); +} + + +void pgObject::CreateListColumns(ctlListView *list, const wxString &left, const wxString &right) +{ + list->ClearAll(); + list->AddColumn(left, 130); + list->AddColumn(right, list->GetSize().GetWidth() - 140); +} + + +void pgObject::ShowDependencies(frmMain *form, ctlListView *Dependencies, const wxString &wh) +{ + if (this->IsCollection()) + return; + + // Bail out if this is a pgAgent object, as they use the OID for IDs + if (GetMetaType() == PGM_JOB || GetMetaType() == PGM_SCHEDULE || GetMetaType() == PGM_STEP) + return; + + wxString where; + if (wh.IsEmpty()) + { + if(!GetOidStr().IsSameAs(wxT("0"))) + where = wxT(" WHERE dep.objid=") + GetOidStr(); + else + return; + } + else + where = wh; + /* + * Behavior of concatinating operator (||) is different for EnterpriseDB. + * For the following query: + * SELECT a || null; + * When selected postgresql compatible mode, it will return null. + * And when selected oracle compatible mode, it will return 'a'. + * + * Hence, the following query may or may not work for EnterpriseDB depending on the + * compatiblity mode: + * COALESCE(cl.relname || '.' || att.attname, cl.relname, co.conname, pr.proname, + * tg.tgname, ty.typname, la.lanname, rw.rulename, ns.nspname) + * + * Instead of that, we will use the following query to run it correctly everytime: + * CASE WHEN cl.relname IS NOT NULL AND att.attname IS NOT NULL + * THEN cl.relname || '.' || att.attname + * ELSE COALESCE(cl.relname, co.conname, pr.proname, tg.tgname, ty.typname, + * la.lanname, rw.rulename, ns.nspname) + * END + */ + ShowDependency(GetDatabase(), Dependencies, + wxT("SELECT DISTINCT dep.deptype, dep.refclassid, cl.relkind, ad.adbin, ad.adsrc, \n") + wxT(" CASE WHEN cl.relkind IS NOT NULL THEN cl.relkind || COALESCE(dep.refobjsubid::text, '')\n") + wxT(" WHEN tg.oid IS NOT NULL THEN 'T'::text\n") + wxT(" WHEN ty.oid IS NOT NULL THEN 'y'::text\n") + wxT(" WHEN ns.oid IS NOT NULL THEN 'n'::text\n") + wxT(" WHEN pr.oid IS NOT NULL THEN 'p'::text\n") + wxT(" WHEN la.oid IS NOT NULL THEN 'l'::text\n") + wxT(" WHEN rw.oid IS NOT NULL THEN 'R'::text\n") + wxT(" WHEN co.oid IS NOT NULL THEN 'C'::text || contype\n") + wxT(" WHEN ad.oid IS NOT NULL THEN 'A'::text\n") + wxT(" WHEN ext.oid IS NOT NULL THEN 'E'::text\n") + wxT(" ELSE '' END AS type,\n") + wxT(" COALESCE(coc.relname, clrw.relname) AS ownertable,\n") + wxT(" CASE WHEN cl.relname IS NOT NULL AND att.attname IS NOT NULL THEN cl.relname || '.' || att.attname\n") + wxT(" ELSE COALESCE(ext.extname,cl.relname, co.conname, pr.proname, tg.tgname, ty.typname, la.lanname, rw.rulename, ns.nspname)\n") + wxT(" END AS refname,\n") + wxT(" COALESCE(nsc.nspname, nso.nspname, nsp.nspname, nst.nspname, nsrw.nspname) AS nspname\n") + wxT(" FROM pg_depend dep\n") + wxT(" LEFT JOIN pg_class cl ON dep.refobjid=cl.oid\n") + wxT(" LEFT JOIN pg_attribute att ON dep.refobjid=att.attrelid AND dep.refobjsubid=att.attnum\n") + wxT(" LEFT JOIN pg_namespace nsc ON cl.relnamespace=nsc.oid\n") + wxT(" LEFT JOIN pg_proc pr ON dep.refobjid=pr.oid\n") + wxT(" LEFT JOIN pg_namespace nsp ON pr.pronamespace=nsp.oid\n") + wxT(" LEFT JOIN pg_trigger tg ON dep.refobjid=tg.oid\n") + wxT(" LEFT JOIN pg_type ty ON dep.refobjid=ty.oid\n") + wxT(" LEFT JOIN pg_namespace nst ON ty.typnamespace=nst.oid\n") + wxT(" LEFT JOIN pg_constraint co ON dep.refobjid=co.oid\n") + wxT(" LEFT JOIN pg_class coc ON co.conrelid=coc.oid\n") + wxT(" LEFT JOIN pg_namespace nso ON co.connamespace=nso.oid\n") + wxT(" LEFT JOIN pg_rewrite rw ON dep.refobjid=rw.oid\n") + wxT(" LEFT JOIN pg_class clrw ON clrw.oid=rw.ev_class\n") + wxT(" LEFT JOIN pg_namespace nsrw ON clrw.relnamespace=nsrw.oid\n") + wxT(" LEFT JOIN pg_language la ON dep.refobjid=la.oid\n") + wxT(" LEFT JOIN pg_namespace ns ON dep.refobjid=ns.oid\n") + wxT(" LEFT JOIN pg_attrdef ad ON ad.adrelid=att.attrelid AND ad.adnum=att.attnum\n") + wxT(" LEFT JOIN pg_extension ext ON ext.oid=dep.refobjid\n") + + where, wxT("refclassid")); + + pgConn *conn = GetConnection(); + if (conn) + { + if (where.Find(wxT("subid")) < 0 && conn->BackendMinimumVersion(8, 1)) + { + int iconId = groupRoleFactory.GetCollectionFactory()->GetIconId(); + pgSetIterator set(conn, + wxT("SELECT rolname AS refname, refclassid, deptype\n") + wxT(" FROM pg_shdepend dep\n") + wxT(" LEFT JOIN pg_roles r ON refclassid=1260 AND refobjid=r.oid\n") + + where + wxT("\n") + wxT(" ORDER BY 1")); + + while (set.RowsLeft()) + { + wxString refname = set.GetVal(wxT("refname")); + wxString deptype = set.GetVal(wxT("deptype")); + if (deptype == wxT("a")) + deptype = wxT("ACL"); + else if (deptype == wxT("o")) + deptype = _("Owner"); + + if (set.GetOid(wxT("refclassid")) == PGOID_CLASS_PG_AUTHID) + Dependencies->AppendItem(iconId, wxT("Role"), refname, deptype); + } + } + /* + * + * A Corner case, reported by Guillaume Lelarge, could be found at: + * http://archives.postgresql.org/pgadmin-hackers/2009-03/msg00026.php + * + * SQL: + * CREATE TABLE t1 (id serial); + * CREATE TABLE t2 (LIKE t1 INCLUDING DEFAULTS); + * + * When we try to drop the table t1, it gives the following notice: + * "NOTICE: default for table t2 column id depends on sequence t1_id_seq" + * + * This suggests that the column 't2.id' should be shown in the "Dependency" list + * of the sequence 't1_seq_id' + * + * As we could not find any direct relationship between 't1_seq_id' and 't2' + * table, we come up with this solution. + * + */ + if (GetMetaType() == PGM_SEQUENCE) + { + int iconId = columnFactory.GetIconId(); + /* + * Behavior of concatinating operator (||) is different for EnterpriseDB. + * For the following query: + * SELECT a || null; + * When selected postgresql compatible mode, it will return null. + * And when selected oracle compatible mode, it will return 'a'. + * + * Hence, the following query may or may not work for EnterpriseDB depending on the + * compatiblity mode: + * COALESCE(ref.relname || '.' || att.attname, ref.relname) + * + * Instead of that, we will use the following query to run it correctly everytime: + * CASE WHEN ref.relname IS NOT NULL AND att.attname IS NOT NULL + * THEN ref.relname || '.' || att.attname + * ELSE ref.relname + * END + */ + pgSetIterator set(conn, + wxT("SELECT \n") + wxT(" CASE WHEN att.attname IS NOT NULL AND ref.relname IS NOT NULL THEN ref.relname || '.' || att.attname\n") + wxT(" ELSE ref.relname \n") + wxT(" END AS refname, \n") + wxT(" d2.refclassid, d1.deptype AS deptype\n") + wxT("FROM pg_depend d1\n") + wxT(" LEFT JOIN pg_depend d2 ON d1.objid=d2.objid AND d1.refobjid != d2.refobjid\n") + wxT(" LEFT JOIN pg_class ref ON ref.oid = d2.refobjid\n") + wxT(" LEFT JOIN pg_attribute att ON d2.refobjid=att.attrelid AND d2.refobjsubid=att.attnum\n") + wxT("WHERE d1.classid=(SELECT oid FROM pg_class WHERE relname='pg_attrdef')\n") + wxT(" AND d2.refobjid NOT IN (SELECT d3.refobjid FROM pg_depend d3 WHERE d3.objid=d1.refobjid)\n") + wxT(" AND d1.refobjid=") + GetOidStr()); + while (set.RowsLeft()) + { + wxString refname = set.GetVal(wxT("refname")); + wxString deptype = set.GetVal(wxT("deptype")); + if (deptype == wxT("n")) + deptype = wxT("normal"); + else if (deptype == wxT("i")) + deptype = _("internal"); + else if (deptype == wxT("a")) + deptype = _("auto"); + + Dependencies->AppendItem(iconId, wxT("Column"), refname, deptype); + } + } + } + +} + + +void pgObject::ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &wh) +{ + if (this->IsCollection()) + return; + + // Bail out if this is a pgAgent object, as they use the OID for IDs + if (GetMetaType() == PGM_JOB || GetMetaType() == PGM_SCHEDULE || GetMetaType() == PGM_STEP) + return; + + wxString where; + if (wh.IsEmpty()) + where = wxT(" WHERE dep.refobjid=") + GetOidStr(); + else + where = wh; + /* + * Behavior of concatinating operator (||) is different for EnterpriseDB. + * For the following query: + * SELECT a || null; + * When selected postgresql compatible mode, it will return null. + * And when selected oracle compatible mode, it will return 'a'. + * + * Hence, the following query may or may not work for EnterpriseDB depending on the + * compatiblity mode: + * COALESCE(cl.relname || '.' || att.attname, cl.relname, co.conname, pr.proname, + * tg.tgname, ty.typname, la.lanname, rw.rulename, ns.nspname) + * + * Instead of that, we will use the following query to run it correctly everytime: + * CASE WHEN cl.relname IS NOT NULL AND att.attname IS NOT NULL + * THEN cl.relname || '.' || att.attname + * ELSE COALESCE(cl.relname, co.conname, pr.proname, tg.tgname, ty.typname, + * la.lanname, rw.rulename, ns.nspname) + * END + */ + ShowDependency(GetDatabase(), referencedBy, + wxT("SELECT DISTINCT dep.deptype, dep.classid, cl.relkind, ad.adbin, ad.adsrc, \n") + wxT(" CASE WHEN cl.relkind IS NOT NULL THEN cl.relkind || COALESCE(dep.objsubid::text, '')\n") + wxT(" WHEN tg.oid IS NOT NULL THEN 'T'::text\n") + wxT(" WHEN ty.oid IS NOT NULL THEN 'y'::text\n") + wxT(" WHEN ns.oid IS NOT NULL THEN 'n'::text\n") + wxT(" WHEN pr.oid IS NOT NULL THEN 'p'::text\n") + wxT(" WHEN la.oid IS NOT NULL THEN 'l'::text\n") + wxT(" WHEN rw.oid IS NOT NULL THEN 'R'::text\n") + wxT(" WHEN co.oid IS NOT NULL THEN 'C'::text || contype\n") + wxT(" WHEN ad.oid IS NOT NULL THEN 'A'::text\n") + wxT(" WHEN ext.oid IS NOT NULL THEN 'E'::text\n") + wxT(" ELSE '' END AS type,\n") + wxT(" COALESCE(coc.relname, clrw.relname) AS ownertable,\n") + wxT(" CASE WHEN cl.relname IS NOT NULL AND att.attname IS NOT NULL THEN cl.relname || '.' || att.attname \n") + wxT(" ELSE COALESCE(ext.extname,cl.relname, co.conname, pr.proname, tg.tgname, ty.typname, la.lanname, rw.rulename, ns.nspname) \n") + wxT(" END AS refname,\n") + wxT(" COALESCE(nsc.nspname, nso.nspname, nsp.nspname, nst.nspname, nsrw.nspname) AS nspname\n") + wxT(" FROM pg_depend dep\n") + wxT(" LEFT JOIN pg_class cl ON dep.objid=cl.oid\n") + wxT(" LEFT JOIN pg_attribute att ON dep.objid=att.attrelid AND dep.objsubid=att.attnum\n") + wxT(" LEFT JOIN pg_namespace nsc ON cl.relnamespace=nsc.oid\n") + wxT(" LEFT JOIN pg_proc pr ON dep.objid=pr.oid\n") + wxT(" LEFT JOIN pg_namespace nsp ON pr.pronamespace=nsp.oid\n") + wxT(" LEFT JOIN pg_trigger tg ON dep.objid=tg.oid\n") + wxT(" LEFT JOIN pg_type ty ON dep.objid=ty.oid\n") + wxT(" LEFT JOIN pg_namespace nst ON ty.typnamespace=nst.oid\n") + wxT(" LEFT JOIN pg_constraint co ON dep.objid=co.oid\n") + wxT(" LEFT JOIN pg_class coc ON co.conrelid=coc.oid\n") + wxT(" LEFT JOIN pg_namespace nso ON co.connamespace=nso.oid\n") + wxT(" LEFT JOIN pg_rewrite rw ON dep.objid=rw.oid\n") + wxT(" LEFT JOIN pg_class clrw ON clrw.oid=rw.ev_class\n") + wxT(" LEFT JOIN pg_namespace nsrw ON clrw.relnamespace=nsrw.oid\n") + wxT(" LEFT JOIN pg_language la ON dep.objid=la.oid\n") + wxT(" LEFT JOIN pg_namespace ns ON dep.objid=ns.oid\n") + wxT(" LEFT JOIN pg_attrdef ad ON ad.oid=dep.objid\n") + wxT(" LEFT JOIN pg_extension ext ON ext.oid=dep.objid\n") + + where, wxT("classid")); + + /* + * + * A Corner case, reported by Guillaume Lelarge, could be found at: + * http://archives.postgresql.org/pgadmin-hackers/2009-03/msg00026.php + * + * SQL: + * CREATE TABLE t1 (id serial); + * CREATE TABLE t2 (LIKE t1 INCLUDING DEFAULTS); + * + * When we try to drop the table t1, it gives the following notice: + * "NOTICE: default for table t2 column id depends on sequence t1_id_seq" + * + * This suggests that the sequence 't1_seq_id' should be shown in the + * "Dependents" list of the table 't2' and column 't2.id' + * + * As we could not find any direct relationship between 't1_seq_id' and 't2' + * table, we come up with this solution. + * + */ + pgConn *conn = GetConnection(); + if (conn && (GetMetaType() == PGM_TABLE || GetMetaType() == PGM_COLUMN)) + { + int iconId = sequenceFactory.GetIconId(); + wxString strQuery = + wxT("SELECT ref.relname AS refname, d2.refclassid, dep.deptype AS deptype\n") + wxT(" FROM pg_depend dep\n") + wxT(" LEFT JOIN pg_depend d2 ON dep.objid=d2.objid AND dep.refobjid != d2.refobjid\n") + wxT(" LEFT JOIN pg_class ref ON ref.oid=d2.refobjid\n") + wxT(" LEFT JOIN pg_attribute att ON d2.refclassid=att.attrelid AND d2.refobjsubid=att.attnum\n") + + where + + wxT(" AND dep.classid=(SELECT oid FROM pg_class WHERE relname='pg_attrdef')\n") + wxT(" AND dep.refobjid NOT IN (SELECT d3.refobjid FROM pg_depend d3 WHERE d3.objid=d2.refobjid)"); + + + pgSetIterator set(conn, strQuery); + + while (set.RowsLeft()) + { + wxString refname = set.GetVal(wxT("refname")); + if (refname.IsEmpty()) + continue; + + wxString deptype = set.GetVal(wxT("deptype")); + if (deptype == wxT("a")) + deptype = _("auto"); + else if (deptype == wxT("n")) + deptype = _("normal"); + else if (deptype == wxT("i")) + deptype = _("internal"); + + referencedBy->AppendItem(iconId, wxT("Sequence"), refname, deptype); + } + } +} + + +void pgObject::ShowTree(frmMain *form, ctlTree *browser, ctlListView *properties, ctlSQLBox *sqlPane) +{ + pgConn *conn = GetConnection(); + if (conn) + { + int status = conn->GetStatus(); + if (status == PGCONN_BROKEN || status == PGCONN_BAD) + { + form->SetStatusText(_(" Connection broken.")); + return; + } + } + + wxLogInfo(wxT("Displaying properties for %s %s"), GetTypeName().c_str(), GetIdentifier().c_str()); + + if (form) + { + form->StartMsg(GetTranslatedMessage(RETRIEVINGDETAILS)); + + SetContextInfo(form); + + form->ShowObjStatistics(this); + } + + ShowTreeDetail(browser, form, properties, sqlPane); + if (form) + form->EndMsg(!GetConnection() || GetConnection()->GetStatus() == PGCONN_OK); +} + + +wxTreeItemId pgObject::AppendBrowserItem(ctlTree *browser, pgObject *object) +{ + return browser->AppendObject(this, object); +} + + +wxString pgObject::GetCommentSql() +{ + wxString cmt; + if (!comment.IsNull()) + { + cmt = wxT("COMMENT ON ") + GetTypeName().Upper() + wxT(" ") + GetQuotedFullIdentifier() + + wxT("\n IS ") + qtDbString(comment) + wxT(";\n"); + } + return cmt; +} + + +wxString pgObject::GetOwnerSql(int major, int minor, wxString objname, wxString objtype) +{ + wxString sql; + if (GetConnection()->BackendMinimumVersion(major, minor)) + { +// if (GetConnection()->GetUser() != owner) // optional? + { + if (objtype.IsEmpty()) + objtype = GetTypeName().Upper(); + + if (objname.IsEmpty()) + objname = objtype + wxT(" ") + GetQuotedFullIdentifier(); + + sql = wxT("ALTER ") + objname + wxT("\n OWNER TO ") + qtIdent(owner) + wxT(";\n"); + } + } + return sql; +} + + +void pgObject::AppendRight(wxString &rights, const wxString &acl, wxChar c, const wxChar *rightName, const wxString &column) +{ + if (acl.Find(c) >= 0) + { + if (!rights.IsNull()) + rights.Append(wxT(", ")); + rights.Append(rightName); + + if (!column.IsEmpty()) + rights.Append(wxT("(") + column + wxT(")")); + } +} + + +wxString pgObject::GetPrivilegeGrant(const wxString &allPattern, const wxString &acl, const wxString &grantOnObject, const wxString &user, const wxString &column) +{ + wxString rights; + + if (allPattern.Length() > 1 && acl == allPattern) + { + rights = wxT("ALL"); + if (!column.IsEmpty()) + rights += wxT("(") + column + wxT(")"); + } + else + { + AppendRight(rights, acl, 'r', wxT("SELECT"), column); + AppendRight(rights, acl, 'w', wxT("UPDATE"), column); + AppendRight(rights, acl, 'a', wxT("INSERT"), column); + AppendRight(rights, acl, 'D', wxT("TRUNCATE"), column); + AppendRight(rights, acl, 'c', wxT("CONNECT"), column); + AppendRight(rights, acl, 'd', wxT("DELETE"), column); + AppendRight(rights, acl, 'R', wxT("RULE"), column); + AppendRight(rights, acl, 'x', wxT("REFERENCES"), column); + AppendRight(rights, acl, 't', wxT("TRIGGER"), column); + AppendRight(rights, acl, 'X', wxT("EXECUTE"), column); + AppendRight(rights, acl, 'U', wxT("USAGE"), column); + AppendRight(rights, acl, 'C', wxT("CREATE"), column); + AppendRight(rights, acl, 'T', wxT("TEMPORARY"), column); + } + wxString grant; + if (rights.IsNull()) + { + grant += wxT("REVOKE ALL"); + if (!column.IsEmpty()) + grant += wxT("(") + column + wxT(")"); + } + else + grant += wxT("GRANT ") + rights; + + grant += wxT(" ON ") + grantOnObject; + + if (rights.IsNull()) grant += wxT(" FROM "); + else grant += wxT(" TO "); + + grant += user; + + return grant; +} + + +wxArrayString pgObject::GetProviderLabelArray() +{ + wxArrayString providersArray, labelsArray, seclabelsArray; + wxString currentChar; + wxString tmp; + bool wrappedInQuotes, antislash; + + if (labels.IsEmpty()) + return seclabelsArray; + + // parse the labels string + // we start at 1 and stop at length-1 to get rid of the { and } of the array + for (unsigned int index = 1 ; index < labels.Length() - 1 ; index++) + { + // get current char + currentChar = labels.Mid(index, 1); + + // if there is a double quote at the beginning of a label, + // the whole label will be wrapped in quotes + if (currentChar == wxT("\"") && tmp.IsEmpty()) + wrappedInQuotes = true; + else if (currentChar == wxT("\\") && wrappedInQuotes) + antislash = true; + else + { + if ((currentChar == wxT(",") && !wrappedInQuotes && !tmp.IsEmpty()) + || (currentChar == wxT("\"") && wrappedInQuotes && !antislash && !tmp.IsEmpty())) + { + // put new label in the array + labelsArray.Add(tmp); + + // reinit tmp + tmp = wxEmptyString; + wrappedInQuotes = false; + } + else + tmp += currentChar; + antislash = false; + } + } + + // last label + if (!tmp.IsEmpty()) + { + // put last label in the array + labelsArray.Add(tmp); + } + + // reinit tmp + tmp = wxEmptyString; + wrappedInQuotes = false; + + // parse the providers string + // we start at 1 and stop at length-1 to get rid of the { and } of the array + for (unsigned int index = 1 ; index < providers.Length() - 1 ; index++) + { + // get current char + currentChar = providers.Mid(index, 1); + + // if there is a double quote at the beginning of a provider, + // the whole provider will be wrapped in quotes + if (currentChar == wxT("\"") && tmp.IsEmpty()) + wrappedInQuotes = true; + else if (currentChar == wxT("\\") && wrappedInQuotes) + antislash = true; + else + { + if ((currentChar == wxT(",") && !wrappedInQuotes && !tmp.IsEmpty()) + || (currentChar == wxT("\"") && wrappedInQuotes && !antislash && !tmp.IsEmpty())) + { + // put new provider in the array + providersArray.Add(tmp); + + // reinit tmp + tmp = wxEmptyString; + wrappedInQuotes = false; + } + else + tmp += currentChar; + antislash = false; + } + } + + // last provider + if (!tmp.IsEmpty()) + { + // put last provider in the array + providersArray.Add(tmp); + } + + // now, build one wxArrayString from these two + for (unsigned int index = 0 ; index < providersArray.GetCount() ; index++) + { + seclabelsArray.Add(providersArray.Item(index)); + seclabelsArray.Add(labelsArray.Item(index)); + } + + // return the final one + return seclabelsArray; +} + + +wxString pgObject::GetSeqLabelsSql() +{ + wxString sql = wxEmptyString; + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + sql += wxT("SECURITY LABEL FOR ") + seclabels.Item(index) + + wxT("\n ON ") + GetTypeName().Upper() + wxT(" ") + GetQuotedFullIdentifier() + + wxT("\n IS ") + qtDbString(seclabels.Item(index + 1)) + wxT(";\n"); + } + } + + return sql; +} + + +wxString pgObject::GetPrivileges(const wxString &allPattern, const wxString &str, const wxString &grantOnObject, const wxString &user, const wxString &column) +{ + wxString aclWithGrant, aclWithoutGrant; + + const wxChar *p = str.c_str(); + while (*p) + { + if (allPattern.Find(*p) >= 0) + { + if (p[1] == (wxChar)'*') + aclWithGrant += *p; + else + aclWithoutGrant += *p; + } + p++; + if (*p == (wxChar)'*') + p++; + } + + wxString grant; + if (!aclWithoutGrant.IsEmpty() || aclWithGrant.IsEmpty()) + grant += GetPrivilegeGrant(allPattern, aclWithoutGrant, grantOnObject, user, column) + wxT(";\n"); + if (!aclWithGrant.IsEmpty()) + grant += GetPrivilegeGrant(allPattern, aclWithGrant, grantOnObject, user, column) + wxT(" WITH GRANT OPTION;\n"); + + return grant; +} + + +wxString pgObject::GetGrant(const wxString &allPattern, const wxString &_grantFor, const wxString &_column) +{ + wxString grant, str, user, grantFor, tmpUser; + + if (_grantFor.IsNull()) + { + grantFor = GetTypeName(); + grantFor.MakeUpper(); + grantFor += wxT(" ") + GetQuotedFullIdentifier(); + } + else + grantFor = _grantFor; + + if (!acl.IsNull()) + { + if (acl == wxT("{}")) + { + grant += GetPrivileges(allPattern, str, grantFor, wxT("public"), qtIdent(_column)); + grant += GetPrivileges(allPattern, str, grantFor, qtIdent(owner), qtIdent(_column)); + } + else + { + // checks if certain privilege is granted to public + bool grantedToPublic = false; + // checks if certain privilege is granted to owner + bool grantedToOwner = false; + + queryTokenizer acls(acl.Mid(1, acl.Length() - 2), ','); + while (acls.HasMoreTokens()) + { + str = acls.GetNextToken(); + + if (str.Left(1) == '"') + str = str.Mid(1, str.Length() - 2); + user = str.BeforeFirst('='); + str = str.AfterFirst('=').BeforeFirst('/'); + if (user == wxT("")) + { + user = wxT("public"); + grantedToPublic = true; + } + else + { + if (user.Left(6) == wxT("group ")) + { + tmpUser = user.Mid(6); + if (user.Mid(6).StartsWith(wxT("\\\"")) && user.Mid(6).EndsWith(wxT("\\\""))) + user = wxT("GROUP ") + qtIdent(user.Mid(8, user.Length() - 10)); + else + user = wxT("GROUP ") + qtIdent(user.Mid(6)); + } + else + { + tmpUser = user; + if (user.StartsWith(wxT("\\\"")) && user.EndsWith(wxT("\\\""))) + user = qtIdent(user.Mid(2, user.Length() - 4)); + else + user = qtIdent(user); + } + + if (tmpUser.Contains(owner)) + grantedToOwner = true; + } + + grant += GetPrivileges(allPattern, str, grantFor, user, qtIdent(_column)); + } + + str = wxEmptyString; + int metaType = GetMetaType(); + + // We check here that whether the user has revoked prvileges granted to databases, functions + // and languages. If so then this must be part of reverse engineered sql statement + if (!grantedToPublic && (metaType == PGM_LANGUAGE || metaType == PGM_FUNCTION || metaType == PGM_DATABASE)) + grant += GetPrivileges(allPattern, str, grantFor, wxT("public"), qtIdent(_column)); + // We check here that whether the owner has revoked prvileges on himself to this postgres + // object. If so then this must be part of reverse engineered sql statement + if (!grantedToOwner) + grant += GetPrivileges(allPattern, str, grantFor, qtIdent(owner), qtIdent(_column)); + } + } + return grant; +} + + + +pgConn *pgObject::GetConnection() const +{ + pgDatabase *db = GetDatabase(); + if (db) + return db->connection(); + + pgServer *server; + + if (IsCreatedBy(serverFactory)) + server = (pgServer *)this; + else + server = GetServer(); + + if (server) + return server->connection(); + return 0; +} + + +bool pgObject::CheckOpenDialogs(ctlTree *browser, wxTreeItemId node) +{ + pgObject *obj = browser->GetObject(node); + if (obj && obj->GetWindowPtr()) + return true; + + wxTreeItemIdValue cookie; + wxTreeItemId child = browser->GetFirstChild(node, cookie); + + while (child.IsOk()) + { + obj = browser->GetObject(child); + if (obj && obj->GetWindowPtr()) + return true; + + wxTreeItemIdValue subCookie; + wxTreeItemId subChildItem = browser->GetFirstChild(child, subCookie); + if (browser->IsExpanded(child)) + { + if (CheckOpenDialogs(browser, child)) + return true; + } + // It may be the case the user might have expanded the node opened the + // dialog and then collapsed the node again. This case is handled in the + // check below + else if (subChildItem && browser->GetItemData(subChildItem)) + { + if (CheckOpenDialogs(browser, child)) + return true; + } + + child = browser->GetNextChild(node, cookie); + } + + return false; +} + +////////////////////////////////////////////////////////////// + +bool pgServerObject::CanDrop() +{ + if (GetMetaType() == PGM_DATABASE) + return (server->GetCreatePrivilege() || server->GetSuperUser()); + else + { + if (server->GetConnection()->BackendMinimumVersion(8, 1) && GetMetaType() == PGM_ROLE) + return (server->GetCreateRole() || server->GetSuperUser()); + else + return server->GetSuperUser(); + } +} + + +bool pgServerObject::CanCreate() +{ + if (GetMetaType() == PGM_DATABASE) + return (server->GetCreatePrivilege() || server->GetSuperUser()); + else + { + if (server->GetConnection()->BackendMinimumVersion(8, 1) && GetMetaType() == PGM_ROLE) + return (server->GetCreateRole() || server->GetSuperUser()); + else + return server->GetSuperUser(); + } +} + + +void pgServerObject::FillOwned(ctlTree *browser, ctlListView *referencedBy, const wxArrayString &dblist, const wxString &query) +{ + pgCollection *databases = 0; + + wxCookieType cookie; + wxTreeItemId item = browser->GetFirstChild(GetServer()->GetId(), cookie); + while (item) + { + databases = (pgCollection *)browser->GetObject(item); + if (databases && databases->GetMetaType() == PGM_DATABASE) + break; + else + databases = 0; + + item = browser->GetNextChild(GetServer()->GetId(), cookie); + } + + size_t i; + for (i = 0 ; i < dblist.GetCount() ; i++) + { + wxString dbname = dblist.Item(i); + pgConn *conn = 0; + pgConn *tmpConn = 0; + + if (GetServer()->GetDatabaseName() == dbname) + conn = GetServer()->GetConnection(); + else + { + item = browser->GetFirstChild(databases->GetId(), cookie); + while (item) + { + pgDatabase *db = (pgDatabase *)browser->GetObject(item); + if (db && db->GetMetaType() == PGM_DATABASE && db->GetName() == dbname) + { + if (db->GetConnected()) + conn = db->GetConnection(); + break; + } + item = browser->GetNextChild(databases->GetId(), cookie); + } + } + if (conn && conn->GetStatus() != PGCONN_OK) + conn = 0; + + if (!conn) + { + tmpConn = GetServer()->CreateConn(dbname); + conn = tmpConn; + } + + if (conn) + { + pgSet *set = conn->ExecuteSet(query); + + if (set) + { + while (!set->Eof()) + { + wxString relname = qtIdent(set->GetVal(wxT("nspname"))); + if (!relname.IsEmpty()) + relname += wxT("."); + relname += qtIdent(set->GetVal(wxT("relname"))); + pgaFactory *ownerFactory = 0; + + switch ( (wxChar)set->GetVal(wxT("relkind")).c_str()[0]) + { + case 'r': + ownerFactory = &tableFactory; + break; + case 'i': + ownerFactory = &indexFactory; + relname = qtIdent(set->GetVal(wxT("indname"))) + wxT(" ON ") + relname; + break; + case 'S': + ownerFactory = &sequenceFactory; + break; + case 'v': + ownerFactory = &viewFactory; + break; + case 'x': + ownerFactory = &extTableFactory; + break; + case 'c': // composite type handled in PG_TYPE + case 's': // special + case 't': // toast + break; + case 'n': + ownerFactory = &schemaFactory; + break; + case 'y': + ownerFactory = &typeFactory; + break; + case 'd': + ownerFactory = &domainFactory; + break; + case 'C': + ownerFactory = &conversionFactory; + break; + case 'p': + ownerFactory = &functionFactory; + break; + case 'T': + ownerFactory = &triggerFunctionFactory; + break; + case 'o': + ownerFactory = &operatorFactory; + relname = set->GetVal(wxT("relname")); // unquoted + break; + } + + if (ownerFactory) + { + wxString typname; + int icon; + typname = ownerFactory->GetTypeName(); + icon = ownerFactory->GetIconId(); + referencedBy->AppendItem(icon, typname, dbname, relname); + } + + set->MoveNext(); + } + delete set; + } + } + + if (tmpConn) + delete tmpConn; + } +} + +////////////////////////////////////////////////////////////// + +pgServer *pgDatabaseObject::GetServer() const +{ + return database->GetServer(); +} + + +bool pgDatabaseObject::CanDrop() +{ + return (database->GetCreatePrivilege() && (GetMetaType() != PGM_CATALOG)); +} + + +bool pgDatabaseObject::CanCreate() +{ + return database->GetCreatePrivilege(); +} + + +wxString pgDatabaseObject::GetSchemaPrefix(const wxString &schemaname) const +{ + return database->GetSchemaPrefix(schemaname); +} + + +wxString pgDatabaseObject::GetQuotedSchemaPrefix(const wxString &schemaname) const +{ + return database->GetQuotedSchemaPrefix(schemaname); +} + + +void pgDatabaseObject::DisplayStatistics(ctlListView *statistics, const wxString &query) +{ + if (statistics) + { + wxLogInfo(wxT("Displaying statistics for %s %s"), GetTypeName().c_str(), GetFullIdentifier().c_str()); + + // Add the statistics view columns + CreateListColumns(statistics, _("Statistic"), _("Value")); + + pgSet *stats = database->ExecuteSet(query); + + if (stats) + { + int col; + for (col = 0 ; col < stats->NumCols() ; col++) + { + if (!stats->ColName(col).IsEmpty()) + statistics->AppendItem(stats->ColName(col), stats->GetVal(col)); + } + delete stats; + } + } +} + + +/////////////////////////////////////////////////////////////// + +void pgSchemaObject::SetSchema(pgSchema *newSchema) +{ + schema = newSchema; + database = schema->GetDatabase(); +} + + +void pgSchemaObject::UpdateSchema(ctlTree *browser, OID schemaOid) +{ + // used e.g. for triggers that use trigger functions from other namespaces + if (!browser) + return; + + if (schema->GetOid() != schemaOid) + { + pgObject *schemas = browser->GetObject(browser->GetItemParent(schema->GetId())); + + wxASSERT(schemas); + treeObjectIterator schIt(browser, schemas); + pgSchema *sch; + + while ((sch = (pgSchema *)schIt.GetNextObject()) != 0) + { + if (sch->GetOid() == schemaOid) + { + SetSchema(sch); + return; + } + } + + // If we get this far, it's possible the schema is actually a catalog + // in this case. We need to find the catalogs node and then search that. + pgObject *db = browser->GetObject(browser->GetItemParent(schemas->GetId())); + + wxASSERT(db); + treeObjectIterator catsIt(browser, db); + pgObject *catalogs; + + while ((catalogs = (pgObject *)catsIt.GetNextObject()) != 0) + { + if (catalogs->GetMetaType() == PGM_CATALOG) + break; + } + + // Assuming we got the catalogs node, now get the catalog + if (catalogs) + { + treeObjectIterator catIt(browser, catalogs); + pgCatalog *cat; + + while ((cat = (pgCatalog *)catIt.GetNextObject()) != 0) + { + if (cat->GetOid() == schemaOid) + { + SetSchema((pgSchema *)cat); + return; + } + } + } + + wxMessageBox(_("The schema oid can't be located, please refresh all schemas!"), + _("Missing information"), wxICON_EXCLAMATION | wxOK, browser); + } +} + + +bool pgSchemaObject::GetSystemObject() const +{ + if (!schema) + return false; + return GetOid() < GetConnection()->GetLastSystemOID(); +} + + +bool pgSchemaObject::CanDrop() +{ + return schema->GetCreatePrivilege() && schema->GetMetaType() != PGM_CATALOG; +} + + +bool pgSchemaObject::CanCreate() +{ + return schema->GetCreatePrivilege() && schema->GetMetaType() != PGM_CATALOG; +} + + +void pgSchemaObject::SetContextInfo(frmMain *form) +{ +// form->SetDatabase(schema->GetDatabase()); +} + +pgSet *pgSchemaObject::ExecuteSet(const wxString &sql) +{ + return schema->GetDatabase()->ExecuteSet(sql); +} + +wxString pgSchemaObject::ExecuteScalar(const wxString &sql) +{ + return schema->GetDatabase()->ExecuteScalar(sql); +} + +bool pgSchemaObject::ExecuteVoid(const wxString &sql) +{ + return schema->GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgSchemaObject::GetFullIdentifier() const +{ + return schema->GetPrefix() + GetName(); +} + + +wxString pgSchemaObject::GetQuotedFullIdentifier() const +{ + if (schema->GetTypeName() == wxT("Table")) + return schema->GetSchema()->GetQuotedPrefix() + GetQuotedIdentifier(); + else + return schema->GetQuotedPrefix() + GetQuotedIdentifier(); +} + + + + +enum tokentype +{ + SQLTK_NORMAL = 0, + SQLTK_JOINMOD, + SQLTK_JOIN, + SQLTK_ON, + SQLTK_UNION + +}; + +typedef struct __tokenaction +{ + const wxChar *keyword, *replaceKeyword; + int actionBefore, actionAfter; + tokentype special; + bool doBreak; +} tokenAction; + + +tokenAction sqlTokens[] = +{ + { wxT("WHERE")}, // initializing fails, so we're doing it in the code + { wxT("SELECT"), wxT(" SELECT"), 0, 8, SQLTK_NORMAL, true}, + { wxT("FROM"), wxT(" FROM"), -8, 8, SQLTK_NORMAL, true}, + { wxT("LEFT"), wxT(" LEFT"), -8, 13, SQLTK_JOINMOD, true}, + { wxT("RIGHT"), wxT(" RIGHT"), -8, 13, SQLTK_JOINMOD, true}, + { wxT("NATURAL"), wxT(" NATURAL"), -8, 13, SQLTK_JOINMOD, true}, + { wxT("FULL"), wxT(" FULL"), -8, 13, SQLTK_JOINMOD, true}, + { wxT("CROSS"), wxT(" CROSS"), -8, 13, SQLTK_JOINMOD, true}, + { wxT("UNION"), wxT(" UNION"), -8, 13, SQLTK_UNION, true}, + { wxT("JOIN"), wxT(" JOIN"), -8, 13, SQLTK_JOIN, true}, + { wxT("ON"), wxT("ON"), 0, -5, SQLTK_ON, false}, + { wxT("ORDER"), wxT(" ORDER"), -8, 8, SQLTK_NORMAL, true}, + { wxT("GROUP"), wxT(" GROUP"), -8, 8, SQLTK_NORMAL, true}, + { wxT("HAVING"), wxT(" HAVING"), -8, 8, SQLTK_NORMAL, true}, + { wxT("LIMIT"), wxT(" LIMIT"), -8, 8, SQLTK_NORMAL, true}, + { wxT("CASE"), wxT("CASE"), 0, 4, SQLTK_NORMAL, true}, + { wxT("WHEN"), wxT("WHEN"), 0, 0, SQLTK_NORMAL, true}, + { wxT("ELSE"), wxT("ELSE"), 0, 0, SQLTK_NORMAL, true}, + { wxT("END"), wxT("END "), -4, 0, SQLTK_NORMAL, true}, + {0, 0, 0, 0, SQLTK_NORMAL, false} +}; + +tokenAction secondOnToken = +{ wxT("ON"), wxT("ON"), -5, 0, SQLTK_ON, true}; + + + +wxString pgRuleObject::GetFormattedDefinition() +{ + // pgsql 7.4 does formatting itself + if (!GetDatabase()->GetPrettyOption().IsEmpty()) + return GetDefinition(); + + //////////////////////////////// + // ok, this code looks weird. It's necessary, because somebody (NOT the running code) + // will screw up that entry. It's broken in pgAdmin3::OnInit() already. + // maybe your compiler does better (VC6SP5, but an older c2xx to avoid other bugs) + + sqlTokens[0].replaceKeyword = wxT(" WHERE"); + sqlTokens[0].actionBefore = -8; + sqlTokens[0].actionAfter = 8; + sqlTokens[0].special = SQLTK_NORMAL; + sqlTokens[0].doBreak = true; + + wxString fc, token; + queryTokenizer tokenizer(GetDefinition()); + int indent = 0; + int position = 0; // col position. updated, but not used at the moment. + bool wasOn = false; + + while (tokenizer.HasMoreTokens()) + { + token = tokenizer.GetNextToken(); + +gotToken: + wxString trailingChars; + + // token may contain brackets + int bracketPos; + bracketPos = token.Find('(', true); + while (bracketPos >= 0) + { + fc += token.Left(bracketPos + 1); + token = token.Mid(bracketPos + 1); + bracketPos = token.Find('(', true); + } + + bracketPos = token.Find(')', true); + while (bracketPos >= 0) + { + trailingChars = token.Mid(bracketPos) + trailingChars; + token = token.Left(bracketPos); + bracketPos = token.Find(')', true); + } + // identify token + tokenAction *tp = sqlTokens; + while (tp->keyword) + { + if (!token.CmpNoCase(tp->keyword)) + { + if (tp->special == SQLTK_ON && wasOn) + tp = &secondOnToken; + else + wasOn = (tp->special == SQLTK_ON); + break; + } + tp++; + } + + if (tp && tp->keyword) + { + // we found a keyword. + if (tp->special == SQLTK_UNION || tp->special == SQLTK_JOINMOD) + { + token = tokenizer.GetNextToken(); + if (tp->special == SQLTK_UNION && token.CmpNoCase(wxT("JOIN"))) + { + fc += wxT("\nUNION\n"); + indent = 0; + goto gotToken; + } + else + { + trailingChars = token + wxT(" ") + trailingChars; + indent += tp->actionBefore; + if (indent < 0) indent = 0; + } + } + else + { + indent += tp->actionBefore; + if (indent < 0) indent = 0; + } + if (tp->doBreak) + { + fc += wxT("\n") + wxString(' ', (size_t)indent); + position = indent; + } + else + { + fc += wxT(" "); + position += 1; + } + fc += tp->replaceKeyword; + position += wxString(tp->replaceKeyword).Length(); + + indent += tp->actionAfter; + if (indent < 0) indent = 0; + } + else + { + fc += token; + position += token.Length(); + } + fc += wxT(" "); + position++; + if (!trailingChars.IsNull()) + { + fc += trailingChars + wxT(" ");; + position += trailingChars.Length() + 1; + } + } + return fc; +} + +wxString pgObject::qtDbString(const wxString &str) +{ + // Use the server aware version if possible + if (GetDatabase() && GetDatabase()->GetConnection()) + return GetDatabase()->GetConnection()->qtDbString(str); + else + { + wxString ret = str; + ret.Replace(wxT("\\"), wxT("\\\\")); + ret.Replace(wxT("'"), wxT("''")); + ret.Append(wxT("'")); + ret.Prepend(wxT("'")); + return ret; + } +} + +wxString pgObject::GetDefaultPrivileges(const wxString &strType, const wxString &strSupportedPrivs, + const wxString &strSchema, const wxString &strOrigDefPrivs, + const wxString &strNewDefPrivs, const wxString &strRole) +{ + wxString strDefPrivs, strGrant, strRevoke, strGrantOption, strRevokeGrantOption; + int privilegeCount = strSupportedPrivs.Length(); + + for (int index = 0; index < privilegeCount; index++) + { + bool inOrigPriv = false, inNewPriv = false, grantOptInOrigPriv = false, grantOptInNewPriv = false; + wxChar privChar = strSupportedPrivs.GetChar(index); + int privAt = strOrigDefPrivs.Find(privChar); + if (privAt != wxNOT_FOUND) + { + inOrigPriv = true; + if ((unsigned int)privAt < strOrigDefPrivs.Length() - 1 && + strOrigDefPrivs.GetChar(privAt + 1) == wxT('*')) + grantOptInOrigPriv = true; + } + + privAt = strNewDefPrivs.Find(privChar); + if (privAt != wxNOT_FOUND) + { + inNewPriv = true; + if ((unsigned int)privAt < strNewDefPrivs.Length() - 1 && + strNewDefPrivs.GetChar(privAt + 1) == wxT('*')) + grantOptInNewPriv = true; + } + if (inOrigPriv || inNewPriv || grantOptInOrigPriv || grantOptInNewPriv) + { + wxString strPrivilege = GetPrivilegeName(privChar); + if (!inOrigPriv && inNewPriv) + { + // GRANT PRIVILEGES + if (!grantOptInNewPriv) + strGrant += strPrivilege + wxT(", "); + // GRANT PRVILEGES WITH GRANT OPTION + else + strGrantOption += strPrivilege + wxT(", "); + } + // REVOKE PRIVILEGES + else if (inOrigPriv && !inNewPriv) + strRevoke += strPrivilege + wxT(", "); + else if (inOrigPriv && inNewPriv) + { + // REVOKE ONLY 'WITH GRANT OPTION' + if(grantOptInOrigPriv && !grantOptInNewPriv) + strRevokeGrantOption += strPrivilege + wxT(", "); + // GRANT PRVILEGES WITH GRANT OPTION + else if (!grantOptInOrigPriv && grantOptInNewPriv) + strGrantOption += strPrivilege + wxT(", "); + } + } + } + + bool isModified = false; + wxString strAltDefPriv; + + if (!strSchema.IsEmpty()) + strAltDefPriv = wxT("ALTER DEFAULT PRIVILEGES IN SCHEMA ") + strSchema; + else + strAltDefPriv = wxT("ALTER DEFAULT PRIVILEGES "); + + if (!strRevoke.IsEmpty()) + { + isModified = true; + strRevoke = strRevoke.SubString(0, strRevoke.Length() - 3); + strDefPrivs += strAltDefPriv + + wxT("\n REVOKE ") + strRevoke + wxT(" ON ") + strType + + wxT("\n FROM ") + strRole + wxT(";\n"); + } + if (!strRevokeGrantOption.IsEmpty()) + { + isModified = true; + strRevokeGrantOption = strRevokeGrantOption.SubString(0, strRevokeGrantOption.Length() - 3); + strDefPrivs += strAltDefPriv + + wxT("\n REVOKE GRANT OPTION FOR ") + strRevokeGrantOption + wxT(" ON ") + strType + + wxT("\n FROM ") + strRole + wxT(";\n"); + } + if (!strGrant.IsEmpty()) + { + isModified = true; + + strGrant = strGrant.SubString(0, strGrant.Length() - 3); + strDefPrivs += strAltDefPriv + + wxT("\n GRANT ") + strGrant + wxT(" ON ") + strType + + wxT("\n TO ") + strRole + wxT(";\n"); + } + if (!strGrantOption.IsEmpty()) + { + isModified = true; + strGrantOption = strGrantOption.SubString(0, strGrantOption.Length() - 3); + strDefPrivs += strAltDefPriv + + wxT("\n GRANT ") + strGrantOption + wxT(" ON ") + strType + + wxT("\n TO ") + strRole + wxT(" WITH GRANT OPTION;\n"); + } + if (isModified) + return strDefPrivs + wxT("\n"); + + return wxT(""); +} + +// Find the user-privileges pair from ACLs +// i.e. {=wDx/user1,postgres=adDxt/user1} +// Remove starting and ending curly braces, before supplying as the input +bool pgObject::findUserPrivs(wxString &strDefPrivs, wxString &strUser, wxString &strPriv) +{ + strUser = strPriv = wxT(""); + if (strDefPrivs.IsEmpty()) return false; + + bool startsWithQuote = false; + if (strDefPrivs.StartsWith(wxT("\""))) startsWithQuote = true; + + if (strDefPrivs.StartsWith(wxT("\"\""))) + { + wxChar currChar; + int quoteCount = 0; + int index = 0; + + currChar = strDefPrivs.GetChar(index); + + while (true) + { + if (currChar == wxT('=') && quoteCount % 2 == 0) + break; + strUser += currChar; + currChar = strDefPrivs.GetChar(++index); + if (currChar == wxT('"')) quoteCount++; + } + strUser = strUser.SubString(2, strUser.Length() - 2); + strUser.Replace(wxT("\"\""), wxT("\""), true); + strDefPrivs = strDefPrivs.SubString(index + 1, strDefPrivs.Length()); + } + else + { + /* Remove first quote */ + if (startsWithQuote) strDefPrivs = strDefPrivs.SubString(1, strDefPrivs.Length()); + + int equalCharAt = strDefPrivs.Find(wxT('=')); + + if (equalCharAt != 0) + strUser = strDefPrivs.SubString(0, equalCharAt - 1); + else + strUser = wxT("public"); + strDefPrivs = strDefPrivs.SubString(equalCharAt + 1, strDefPrivs.Length()); + } + + int slashCharAt = strDefPrivs.Find(wxT('/')); + strPriv = strDefPrivs.SubString(0, slashCharAt - 1); + + strDefPrivs = strDefPrivs.SubString(strPriv.Length() + 2, strDefPrivs.Length()); + + if (!strDefPrivs.StartsWith(wxT("\""))) + { + int commaCharAt = strDefPrivs.Find(wxT(',')); + if (commaCharAt == wxNOT_FOUND) strDefPrivs = wxT(""); + else strDefPrivs = strDefPrivs.SubString(commaCharAt + 1, strDefPrivs.Length()); + } + else + { + wxChar currChar; + int quoteCount = 0; + int index = 0; + + currChar = strDefPrivs.GetChar(index); + while (true) + { + if (currChar == wxT(',') && quoteCount % 2 == 0) + break; + currChar = strDefPrivs.GetChar(++index); + if (currChar == wxT('"')) quoteCount++; + } + strDefPrivs = strDefPrivs.SubString(index, strDefPrivs.Length()); + } + + return true; +} + +wxString pgObject::GetPrivilegeName(wxChar privilege) +{ + switch(privilege) + { + case 'a': + return wxT("INSERT"); + case 'r': + return wxT("SELECT"); + case 'w': + return wxT("UPDATE"); + case 'd': + return wxT("DELETE"); + case 'D': + return wxT("TRUNCATE"); + case 'x': + return wxT("REFERENCES"); + case 't': + return wxT("TRIGGER"); + case 'U': + return wxT("USAGE"); + case 'X': + return wxT("EXECUTE"); + default: + return wxT("UNKNOWN"); + } +} + +void pgObject::SetWindowPtr(dlgProperty *dlgprop) +{ + dlg = dlgprop; +} +wxString pgObject::GetSqlReCreate(frmMain *form, pgObject *obj) +{ + pgConn *conn = GetConnection(); + if (conn) + { + int status = conn->GetStatus(); + if (status == PGCONN_BROKEN || status == PGCONN_BAD) + { + form->SetStatusText(_(" Connection broken.")); + return wxT("");; + } + } + wxLogInfo(wxT("Recreate cascade object for %s %s"), GetTypeName().c_str(), GetIdentifier().c_str()); + + wxString sql; + wxString line; + ctlTree *browser=form->GetBrowser(); + wxString databasePath = form->GetNodePath(obj->GetDatabase()->GetId()); +// + int colcount = 0; + pgSetIterator set(GetConnection(), + wxT("WITH RECURSIVE t(lvl,classid,objid,type_child) AS (\n") + wxT(" select 1,c_classid::regclass,c_objid,type_child from (\n") + wxT(" select dd.*\n") + wxT(" ,(pg_identify_object_as_address(dd.classid, dd.objid, dd.objsubid)).type type_child\n") + wxT(" ,rule_to_view.classid c_classid\n") + wxT(" ,rule_to_view.objid c_objid\n") + wxT(" from pg_depend dd, lateral \n") + wxT(" pg_get_object_address(case when (pg_identify_object_as_address(classid, objid, objsubid)).type='rule' then 'view' \n") + wxT(" else (pg_identify_object_as_address(classid, objid, objsubid)).type end , \n") + wxT(" case when (pg_identify_object_as_address(classid, objid, objsubid)).type='rule' then \n") + wxT(" (pg_identify_object_as_address(classid, objid, objsubid)).object_names[1:2]\n") + wxT(" else (pg_identify_object_as_address(classid, objid, objsubid)).object_names\n") + wxT(" end\n") + wxT(" ,(pg_identify_object_as_address(classid, objid, objsubid)).object_args)\n") + wxT(" rule_to_view\n") + wxT(" where dd.deptype='n' and dd.refobjid=") + GetOidStr() + wxT("\n") + wxT(" ) d\n") + wxT(" where d.refobjid<>d.c_objid\n") + wxT(" group by c_classid,c_objid,type_child\n") + wxT("UNION ALL\n") + wxT("select lvl+1,c_classid::regclass classid,c_objid,type_child from (\n") + wxT(" select dd.*\n") + wxT(" ,(pg_identify_object_as_address(dd.classid, dd.objid, dd.objsubid)).type type_child\n") + wxT(" ,rule_to_view.classid c_classid\n") + wxT(" ,rule_to_view.objid c_objid\n") + wxT(" ,t.lvl\n") + wxT(" from pg_depend dd,t, lateral \n") + wxT(" pg_get_object_address(case when (pg_identify_object_as_address(dd.classid, dd.objid, dd.objsubid)).type='rule' then 'view' \n") + wxT(" else (pg_identify_object_as_address(dd.classid, dd.objid, dd.objsubid)).type end , \n") + wxT(" case when (pg_identify_object_as_address(dd.classid, dd.objid, dd.objsubid)).type='rule' then \n") + wxT(" (pg_identify_object_as_address(dd.classid, dd.objid, dd.objsubid)).object_names[1:2]\n") + wxT(" else (pg_identify_object_as_address(dd.classid, dd.objid, dd.objsubid)).object_names\n") + wxT(" end\n") + wxT(" ,(pg_identify_object_as_address(dd.classid, dd.objid, dd.objsubid)).object_args)\n") + wxT(" rule_to_view\n") + wxT(" where dd.deptype='n' and dd.refobjid=t.objid\n") + wxT(" ) d\n") + wxT(" where d.refobjid<>d.c_objid\n") + wxT(" group by c_classid,c_objid,type_child,lvl\n") + wxT(") select t.*,coalesce(cc.conname,vv.relname,tt.tgname) objname,coalesce(cc.connamespace::regnamespace,vv.relnamespace::regnamespace)::text sch\n") + wxT(",coalesce(cc.conrelid::regclass) parent,coalesce(vv.relkind) kind from t\n") + wxT("left join pg_constraint cc on t.classid='pg_constraint'::regclass and t.objid=cc.oid\n") + wxT("left join pg_class vv on (t.classid='pg_class'::regclass and t.objid=vv.oid) or (cc.conrelid=vv.oid)\n") + wxT("left join pg_trigger tt on t.classid='pg_trigger'::regclass and t.objid=tt.oid\n") + wxT("") + wxT("") + wxT("order by 1 desc,2 asc;") + ); + + // lvl;classid;objid;child_type;objname;sch;parent + sql=wxT("-- "); + pgCollection *database = 0; + wxTreeItemId dbitem = obj->GetDatabase()->GetId(); + //pgCollection *collect = 0; + pgCollection *collectSchEl = 0; + wxCookieType cookie; + pgCollection *collect= browser->FindCollection(schemaFactory,dbitem); + + wxTreeItemId item = browser->GetFirstChild(dbitem, cookie); +if (1==0) { + while (item) + { + collect = (pgCollection *)browser->GetObject(item); + if (collect && collect->GetMetaType() == PGM_SCHEMA) + break; + else + collect = 0; + item = browser->GetNextChild(dbitem, cookie); + } +} + wxString findobj=wxT(","); + wxString dropblock=wxT("-- \n"); + wxString createblock=wxT("-- \n"); + while (set.RowsLeft()) + { + wxString refname = set.GetVal(wxT("objname")); + wxString parent = set.GetVal(wxT("parent")); + wxString type = set.GetVal(wxT("type_child")); + wxString kind = set.GetVal(wxT("kind")); + wxString sxema = parent.BeforeFirst('.'); + wxString table = parent.AfterFirst('.'); + if (sxema.IsEmpty()) { + sxema=set.GetVal(wxT("sch")); + table=refname; + } + pgaFactory *depFactory = 0; + if (refname.IsEmpty()) + continue; + if (findobj.Contains(wxT(",")+table+wxT(".")+refname+wxT(","))) continue; + //pgaCollectionFactory + + item = browser->GetFirstChild(collect->GetId(), cookie); + while (item) + { + collectSchEl = (pgCollection *)browser->GetObject(item); + if (collectSchEl && collectSchEl->GetMetaType() == PGM_SCHEMA && collectSchEl->GetName()==sxema) + { + pgCollection *coll= 0; + wxString whatfindt; + wxString tmpsql; + wxString fn=collectSchEl->GetFullName(); + if (type.Contains(wxT("rule"))||(type.Contains(wxT("view")))) whatfindt=wxT("...bb"); + if (type.Contains(wxT("table constraint"))) { + //coll=browser->FindCollection(tableFactory,item); + whatfindt=wxT("Tables"); + } + // look for the item starting with the given prefix after it + + + wxTreeItemId id=item; + while ( id.IsOk() && + ( browser->GetItemText(id) == wxT("Dummy") && !browser->GetItemData(id) + || true )) + { + pgObject *oo= ((pgObject *) browser->GetItemData(id)); + if (oo) { + pgaFactory *ff=oo->GetFactory(); + fn=ff->GetTypeName(); + fn=oo->GetName(); + if (fn==wxT("history__0102")) { + fn=oo->GetFullName(); + pgaFactory *ff=oo->GetFactory(); + fn=ff->GetTypeName(); + if (ff==&pg_partitionFactory) { + fn=oo->GetFullName(); + }; + //oo->ShowTreeDetail(browser); + } + if ((oo->GetFactory()==&viewFactory || oo->GetFactory()==&tableFactory + || oo->GetFactory()==&pg_partitionFactory ) + && fn==table) { + break; + } + } + wxCookieType cookie; + if ( browser->HasChildren(id) &&((oo->GetFactory()==&viewFactory || oo->GetFactory()==&tableFactory + || oo->GetFactory()==&pg_partitionFactory + || oo->GetFactory()==&schemaFactory + ||oo->GetFactory()->GetTypeName()==whatfindt + ||oo->GetFactory()->GetTypeName()==wxT("Constraints") + ||oo->GetFactory()->GetTypeName()==wxT("Partitions") + ||oo->GetFactory()->GetTypeName()==wxT("Views") + ))) + { + if (oo) oo->ShowTreeDetail(browser); + id = browser->GetFirstChild(id, cookie); + } + else + { + // Try a sibling of this or ancestor instead + wxTreeItemId p = id; + wxTreeItemId toFind; + do + { + toFind = browser->GetNextSibling(p); + p = browser->GetItemParent(p); + } + while (p.IsOk() && !toFind.IsOk()); + id = toFind; + } + } + if ( id.IsOk() ) { + // + pgObject *db=(pgTable *) browser->GetItemData(id); + if (kind=='r') { + // "table constraint" + pgTable *tbl=(pgTable *) db; + tbl->ShowTreeDetail(browser); + pgCollection *cll=tbl->GetConstraintCollection(browser); + if (cll) { + fn=cll->GetFullName(); + } + wxTreeItemId matchItem = browser->FindItem(cll->GetId(),refname); + if ( matchItem.IsOk() ) { + pgObject *o=browser->GetObject(matchItem); + //fn=o->GetName()+wxT(" - type : ")+o->GetTypeName(); + //sql+=fn+wxT("\n"); + tmpsql=browser->GetObject(matchItem)->GetSql(browser); + } + + } + else + { + tmpsql=db->GetSql(browser); + + } + } else { + // + + } + findobj=findobj+table+wxT(".")+refname+wxT(","); + wxStringTokenizer rowslist(tmpsql, wxT("\n"),wxTOKEN_RET_EMPTY ); + wxString cn; + wxString distributionColumns; + int i=1; + while (rowslist.HasMoreTokens()) + { + cn = rowslist.GetNextToken(); + if (i==1) { + createblock+=cn+wxT("\n"); + dropblock+=cn+wxT("\n"); + i++; + continue; + } + if (i==3) { + dropblock+=cn.Mid(3)+wxT("\n"); + i++; + continue; + } + createblock+=cn+wxT("\n"); + i++; + } +// if (node->IsCollection()) +// owneritem = browser->GetParentObject(node->GetId())->GetId(); +// else +// owneritem = browser->GetParentObject(browser->GetParentObject(node->GetId())->GetId())->GetId(); + } + else + collectSchEl = 0; + item = browser->GetNextChild(collect, cookie); + } + + } + + sql+=dropblock+wxT("\n\n\n")+createblock; + return sql; +} diff --git a/schema/pgOperator.cpp b/schema/pgOperator.cpp new file mode 100644 index 0000000..0cda743 --- /dev/null +++ b/schema/pgOperator.cpp @@ -0,0 +1,379 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgOperator.cpp - Operator class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgOperator.h" + + +pgOperator::pgOperator(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, operatorFactory, newName) +{ +} + +pgOperator::~pgOperator() +{ +} + +wxString pgOperator::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on operator"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing operator"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop operator \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop operator \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop operator cascaded?"); + break; + case DROPTITLE: + message = _("Drop operator?"); + break; + case PROPERTIESREPORT: + message = _("Operator properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Operator properties"); + break; + case DDLREPORT: + message = _("Operator DDL report"); + message += wxT(" - ") + GetName();; + break; + case DDL: + message = _("Operator DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Operator dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Operator dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Operator dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Operator dependents"); + break; + } + + return message; +} + +bool pgOperator::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP OPERATOR ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetIdentifier(); + + if (GetLeftType().Length() > 0) + sql += wxT(" (") + qtTypeIdent(GetLeftType()); + else + sql += wxT(") (NONE"); + + if (GetRightType().Length() > 0) + sql += wxT(", ") + qtTypeIdent(GetLeftType()) + wxT(")"); + else + sql += wxT(", NONE)"); + + if (cascaded) + sql += wxT(" CASCADE"); + + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgOperator::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Operator: ") + GetQuotedFullIdentifier() + wxT("(") + GetOperands() + wxT(")\n\n") + + wxT("-- DROP OPERATOR ") + GetQuotedFullIdentifier() + + wxT("(") + GetOperands() + wxT(");\n\n") + wxT("CREATE OPERATOR ") + GetQuotedFullIdentifier() + + wxT("(\n PROCEDURE = ") + GetOperatorFunction(); + AppendIfFilled(sql, wxT(",\n LEFTARG = "), qtTypeIdent(GetLeftType())); + AppendIfFilled(sql, wxT(",\n RIGHTARG = "), qtTypeIdent(GetRightType())); + AppendIfFilled(sql, wxT(",\n COMMUTATOR = "), GetCommutator()); + AppendIfFilled(sql, wxT(",\n NEGATOR = "), GetNegator()); + AppendIfFilled(sql, wxT(",\n RESTRICT = "), GetRestrictFunction()); + AppendIfFilled(sql, wxT(",\n JOIN = "), GetJoinFunction()); + if (GetHashJoins()) sql += wxT(",\n HASHES"); + if (GetMergeJoins()) sql += wxT(",\n MERGES"); + + if (!GetDatabase()->BackendMinimumVersion(8, 3)) + { + AppendIfFilled(sql, wxT(",\n SORT1 = "), GetLeftSortOperator()); + AppendIfFilled(sql, wxT(",\n SORT2 = "), GetRightSortOperator()); + AppendIfFilled(sql, wxT(",\n LTCMP = "), GetLessOperator()); + AppendIfFilled(sql, wxT(",\n GTCMP = "), GetGreaterOperator()); + } + + sql += wxT(");\n"); + + if (!GetComment().IsNull()) + sql += wxT("COMMENT ON OPERATOR ") + GetQuotedFullIdentifier() + + wxT("(") + GetOperands() + wxT(") IS ") + + qtDbString(GetComment()) + wxT(";\n"); + } + + return sql; +} + + +wxString pgOperator::GetOperands() const +{ + wxString sql; + if (GetLeftType().IsEmpty()) + sql = wxT("NONE"); + else + sql = qtIdent(GetLeftType()); + sql += wxT(", "); + + if (GetRightType().IsEmpty()) + sql += wxT("NONE"); + else + sql += qtIdent(GetRightType()); + + return sql; +} +wxString pgOperator::GetFullName() +{ + if (leftType.IsEmpty() || rightType.IsEmpty()) + return GetName() + wxT(" (") + leftType + rightType + wxT(")"); + else + return GetName() + wxT(" (") + leftType + wxT(", ") + rightType + wxT(")"); +} + + +void pgOperator::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Kind"), GetKind()); + if (!leftType.IsNull()) + properties->AppendItem(_("Left type"), GetLeftType()); + if (!rightType.IsNull()) + properties->AppendItem(_("Right type"), GetRightType()); + properties->AppendItem(_("Result type"), GetResultType()); + properties->AppendItem(_("Operator function"), GetOperatorFunction()); + properties->AppendItem(_("Commutator"), GetCommutator()); + properties->AppendItem(_("Negator"), GetNegator()); + properties->AppendItem(_("Join function"), GetJoinFunction()); + properties->AppendItem(_("Restrict function"), GetRestrictFunction()); + + if (!GetDatabase()->BackendMinimumVersion(8, 3)) + { + properties->AppendItem(_("Left Sort operator"), GetLeftSortOperator()); + properties->AppendItem(_("Right Sort operator"), GetRightSortOperator()); + properties->AppendItem(_("Less Than operator"), GetLessOperator()); + properties->AppendItem(_("Greater than operator"), GetGreaterOperator()); + } + + properties->AppendYesNoItem(_("Supports hash?"), GetHashJoins()); + properties->AppendYesNoItem(_("Supports merge?"), GetMergeJoins()); + properties->AppendYesNoItem(_("System operator?"), GetSystemObject()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgOperator::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *oper = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + oper = operatorFactory.CreateObjects(coll, 0, wxT("\n AND op.oid=") + GetOidStr()); + + return oper; +} + + +////////////////////////////////////////////////////// + + +pgOperatorCollection::pgOperatorCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgOperatorCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on operators"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing operators"); + break; + case OBJECTSLISTREPORT: + message = _("Operators list report"); + break; + } + + return message; +} + + +////////////////////////////////////////////////////// + + +pgObject *pgOperatorFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgOperator *oper = 0; + + pgSet *operators; + if (collection->GetDatabase()->BackendMinimumVersion(8, 3)) + { + operators = collection->GetDatabase()->ExecuteSet( + wxT("SELECT op.oid, op.oprname, pg_get_userbyid(op.oprowner) as opowner, op.oprkind, op.oprcanhash, op.oprcanmerge,\n") + wxT(" op.oprleft, op.oprright, lt.typname as lefttype, rt.typname as righttype, et.typname as resulttype,\n") + wxT(" co.oprname as compop, ne.oprname as negop,\n") + wxT(" op.oprcode as operproc, op.oprjoin as joinproc, op.oprrest as restrproc, description\n") + wxT(" FROM pg_operator op\n") + wxT(" LEFT OUTER JOIN pg_type lt ON lt.oid=op.oprleft\n") + wxT(" LEFT OUTER JOIN pg_type rt ON rt.oid=op.oprright\n") + wxT(" JOIN pg_type et on et.oid=op.oprresult\n") + wxT(" LEFT OUTER JOIN pg_operator co ON co.oid=op.oprcom\n") + wxT(" LEFT OUTER JOIN pg_operator ne ON ne.oid=op.oprnegate\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=op.oid AND des.classoid='pg_operator'::regclass)\n") + wxT(" WHERE op.oprnamespace = ") + collection->GetSchema()->GetOidStr() + + restriction + wxT("\n") + wxT(" ORDER BY op.oprname")); + } + else + { + operators = collection->GetDatabase()->ExecuteSet( + wxT("SELECT op.oid, op.oprname, pg_get_userbyid(op.oprowner) as opowner, op.oprkind, op.oprcanhash,\n") + wxT(" op.oprleft, op.oprright, lt.typname as lefttype, rt.typname as righttype, et.typname as resulttype,\n") + wxT(" co.oprname as compop, ne.oprname as negop, lso.oprname as leftsortop, rso.oprname as rightsortop,\n") + wxT(" lco.oprname as lscmpop, gco.oprname as gtcmpop,\n") + wxT(" op.oprcode as operproc, op.oprjoin as joinproc, op.oprrest as restrproc, description\n") + wxT(" FROM pg_operator op\n") + wxT(" LEFT OUTER JOIN pg_type lt ON lt.oid=op.oprleft\n") + wxT(" LEFT OUTER JOIN pg_type rt ON rt.oid=op.oprright\n") + wxT(" JOIN pg_type et on et.oid=op.oprresult\n") + wxT(" LEFT OUTER JOIN pg_operator co ON co.oid=op.oprcom\n") + wxT(" LEFT OUTER JOIN pg_operator ne ON ne.oid=op.oprnegate\n") + wxT(" LEFT OUTER JOIN pg_operator lso ON lso.oid=op.oprlsortop\n") + wxT(" LEFT OUTER JOIN pg_operator rso ON rso.oid=op.oprrsortop\n") + wxT(" LEFT OUTER JOIN pg_operator lco ON lco.oid=op.oprltcmpop\n") + wxT(" LEFT OUTER JOIN pg_operator gco ON gco.oid=op.oprgtcmpop\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=op.oid AND des.classoid='pg_operator'::regclass)\n") + wxT(" WHERE op.oprnamespace = ") + collection->GetSchema()->GetOidStr() + + restriction + wxT("\n") + wxT(" ORDER BY op.oprname")); + } + + if (operators) + { + while (!operators->Eof()) + { + oper = new pgOperator(collection->GetSchema(), operators->GetVal(wxT("oprname"))); + oper->iSetOid(operators->GetOid(wxT("oid"))); + oper->iSetOwner(operators->GetVal(wxT("opowner"))); + oper->iSetComment(operators->GetVal(wxT("description"))); + oper->iSetLeftType(operators->GetVal(wxT("lefttype"))); + oper->iSetRightType(operators->GetVal(wxT("righttype"))); + oper->iSetLeftTypeOid(operators->GetOid(wxT("oprleft"))); + oper->iSetRightTypeOid(operators->GetOid(wxT("oprright"))); + oper->iSetResultType(operators->GetVal(wxT("resulttype"))); + oper->iSetOperatorFunction(operators->GetVal(wxT("operproc"))); + + wxString tmp = operators->GetVal(wxT("joinproc")); + if (tmp != wxT("-")) + oper->iSetJoinFunction(tmp); + tmp = operators->GetVal(wxT("restrproc")); + if (tmp != wxT("-")) + oper->iSetRestrictFunction(tmp); + + if (!collection->GetDatabase()->BackendMinimumVersion(8, 3)) + { + oper->iSetLeftSortOperator(operators->GetVal(wxT("leftsortop"))); + oper->iSetRightSortOperator(operators->GetVal(wxT("rightsortop"))); + oper->iSetLessOperator(operators->GetVal(wxT("lscmpop"))); + oper->iSetGreaterOperator(operators->GetVal(wxT("gtcmpop"))); + } + + oper->iSetCommutator(operators->GetVal(wxT("compop"))); + oper->iSetNegator(operators->GetVal(wxT("negop"))); + wxString kind = operators->GetVal(wxT("oprkind")); + oper->iSetKind(kind.IsSameAs(wxT("b")) ? wxT("infix") : + kind.IsSameAs(wxT("l")) ? wxT("prefix") : + kind.IsSameAs(wxT("r")) ? wxT("postfix") : wxT("unknown")); + oper->iSetHashJoins(operators->GetBool(wxT("oprcanhash"))); + + if (!collection->GetDatabase()->BackendMinimumVersion(8, 3)) + oper->iSetMergeJoins(!oper->GetLeftSortOperator().IsNull() || !oper->GetRightSortOperator().IsNull() || + !oper->GetLessOperator().IsNull() || !oper->GetGreaterOperator().IsNull()); + else + oper->iSetMergeJoins(operators->GetBool(wxT("oprcanmerge"))); + + + if (browser) + { + browser->AppendObject(collection, oper); + operators->MoveNext(); + } + else + break; + } + + delete operators; + } + return oper; +} + + +#include "images/operator.pngc" +#include "images/operators.pngc" + +pgOperatorFactory::pgOperatorFactory() + : pgSchemaObjFactory(__("Operator"), __("New Operator..."), __("Create a new Operator."), operator_png_img) +{ +} + + +pgCollection *pgOperatorFactory::CreateCollection(pgObject *obj) +{ + return new pgOperatorCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgOperatorFactory operatorFactory; +static pgaCollectionFactory cf(&operatorFactory, __("Operators"), operators_png_img); diff --git a/schema/pgOperatorClass.cpp b/schema/pgOperatorClass.cpp new file mode 100644 index 0000000..7c586d3 --- /dev/null +++ b/schema/pgOperatorClass.cpp @@ -0,0 +1,426 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgOperatorClass.cpp - OperatorClass class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgOperatorClass.h" +#include "schema/pgFunction.h" + + +pgOperatorClass::pgOperatorClass(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, operatorClassFactory, newName) +{ +} + +pgOperatorClass::~pgOperatorClass() +{ +} + +wxString pgOperatorClass::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on operator class"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing operator class"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop operator class \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop operator class \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop operator class cascaded?"); + break; + case DROPTITLE: + message = _("Drop operator class?"); + break; + case PROPERTIESREPORT: + message = _("Operator class properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Operator class properties"); + break; + case DDLREPORT: + message = _("Operator class DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Operator class DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Operator class dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Operator class dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Operator class dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Operator class dependents"); + break; + } + + return message; +} + +bool pgOperatorClass::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP OPERATOR CLASS ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier() + wxT(" USING ") + GetAccessMethod(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + +wxString pgOperatorClass::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Operator Class: ") + GetName() + wxT("\n\n") + + wxT("-- DROP OPERATOR CLASS ") + GetQuotedFullIdentifier() + wxT(" USING ") + GetAccessMethod() + wxT(";") + + wxT("\n\nCREATE OPERATOR CLASS ") + GetQuotedFullIdentifier(); + if (GetOpcDefault()) + sql += wxT(" DEFAULT"); + sql += wxT("\n FOR TYPE ") + GetInType() + + wxT(" USING ") + GetAccessMethod() + + wxT(" AS"); + unsigned int i; + bool needComma = false; + + for (i = 0 ; i < operators.Count() ; i++) + { + if (needComma) + sql += wxT(","); + + sql += wxT("\n OPERATOR ") + operators.Item(i); + needComma = true; + } + for (i = 0 ; i < functions.Count() ; i++) + { + if (needComma) + sql += wxT(","); + + sql += wxT("\n FUNCTION ") + quotedFunctions.Item(i); + needComma = true; + } + AppendIfFilled(sql, wxT("\n STORAGE "), GetKeyType()); + sql += wxT(";\n"); + } + + return sql; +} + + +void pgOperatorClass::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + pgSet *set; + + if (!GetConnection()->BackendMinimumVersion(8, 3)) + { + set = ExecuteSet( + wxT("SELECT amopstrategy, amopreqcheck, oprname, lt.typname as lefttype, rt.typname as righttype\n") + wxT(" FROM pg_amop am\n") + wxT(" JOIN pg_operator op ON amopopr=op.oid\n") + wxT(" LEFT OUTER JOIN pg_type lt ON lt.oid=oprleft\n") + wxT(" LEFT OUTER JOIN pg_type rt ON rt.oid=oprright\n") + wxT(" WHERE amopclaid=") + GetOidStr() + wxT("\n") + wxT(" ORDER BY amopstrategy")); + } + else if (!GetConnection()->BackendMinimumVersion(8, 4)) + { + set = ExecuteSet( + wxT("SELECT amopstrategy, amopreqcheck, oprname, lt.typname as lefttype, rt.typname as righttype\n") + wxT(" FROM pg_amop am\n") + wxT(" JOIN pg_operator op ON amopopr=op.oid\n") + wxT(" JOIN pg_opfamily opf ON amopfamily = opf.oid\n") + wxT(" JOIN pg_opclass opc ON opf.oid = opcfamily\n") + wxT(" LEFT OUTER JOIN pg_type lt ON lt.oid=oprleft\n") + wxT(" LEFT OUTER JOIN pg_type rt ON rt.oid=oprright\n") + wxT(" WHERE opc.oid=") + GetOidStr() + wxT("\n") + wxT(" AND amopmethod = opf.opfmethod\n") + wxT(" AND amoplefttype = op.oprleft AND amoprighttype = op.oprright\n") + wxT(" ORDER BY amopstrategy")); + } + else + { + set = ExecuteSet( + wxT("SELECT amopstrategy, oprname, lt.typname as lefttype, rt.typname as righttype\n") + wxT(" FROM pg_amop am\n") + wxT(" JOIN pg_operator op ON amopopr=op.oid\n") + wxT(" JOIN pg_opfamily opf ON amopfamily = opf.oid\n") + wxT(" JOIN pg_opclass opc ON opf.oid = opcfamily\n") + wxT(" LEFT OUTER JOIN pg_type lt ON lt.oid=oprleft\n") + wxT(" LEFT OUTER JOIN pg_type rt ON rt.oid=oprright\n") + wxT(" WHERE opc.oid=") + GetOidStr() + wxT("\n") + wxT(" AND amopmethod = opf.opfmethod\n") + wxT(" AND amoplefttype = op.oprleft AND amoprighttype = op.oprright\n") + wxT(" ORDER BY amopstrategy")); + } + + if (set) + { + while (!set->Eof()) + { + wxString str = set->GetVal(wxT("amopstrategy")) + wxT(" ") + set->GetVal(wxT("oprname")); + wxString lt = set->GetVal(wxT("lefttype")); + wxString rt = set->GetVal(wxT("righttype")); + if (lt == GetInType() && (rt.IsEmpty() || rt == GetInType())) + lt = wxEmptyString; + if (rt == GetInType() && lt.IsEmpty()) + rt = wxEmptyString; + + if (!lt.IsEmpty() || !rt.IsEmpty()) + { + str += wxT("("); + if (!lt.IsEmpty()) + { + str += lt; + if (!rt.IsEmpty()) + str += wxT(", "); + } + if (!rt.IsEmpty()) + str += rt; + str += wxT(")"); + } + + if (!GetConnection()->BackendMinimumVersion(8, 4)) + { + if (set->GetBool(wxT("amopreqcheck"))) + str += wxT(" RECHECK"); + } + + operators.Add(str); + set->MoveNext(); + } + delete set; + } + + if (!GetConnection()->BackendMinimumVersion(8, 3)) + { + set = ExecuteSet( + wxT("SELECT amprocnum, amproc::oid\n") + wxT(" FROM pg_amproc am\n") + wxT(" WHERE amopclaid=") + GetOidStr() + wxT("\n") + wxT(" ORDER BY amprocnum")); + } + else + { + set = ExecuteSet( + wxT("SELECT amprocnum, amproc::oid\n") + wxT(" FROM pg_amproc am\n") + wxT(" JOIN pg_opfamily opf ON amprocfamily = opf.oid\n") + wxT(" JOIN pg_opclass opc ON opf.oid = opcfamily\n") + wxT(" WHERE opc.oid=") + GetOidStr() + wxT("\n") + wxT(" AND amproclefttype = opc.opcintype AND amprocrighttype = opc.opcintype\n") + wxT(" ORDER BY amprocnum")); + } + + if (set) + { + while (!set->Eof()) + { + wxString amproc = set->GetVal(wxT("amproc")); + functionOids.Add(amproc); + + // We won't build a PG_FUNCTIONS collection under OperatorClass, so we create + // temporary function items + pgFunction *function = functionFactory.AppendFunctions(this, GetSchema(), 0, wxT(" WHERE pr.oid=") + amproc); + if (function) + { + functions.Add(set->GetVal(wxT("amprocnum")) + wxT(" ") + function->GetFullName()); + quotedFunctions.Add(set->GetVal(wxT("amprocnum")) + wxT(" ") + + function->GetQuotedFullIdentifier() + wxT("(") + function->GetArgSigList() + wxT(")")); + delete function; + } + + set->MoveNext(); + } + delete set; + } + } + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendYesNoItem(_("Default?"), GetOpcDefault()); + properties->AppendItem(_("For type"), GetInType()); + properties->AppendItem(_("Access method"), GetAccessMethod()); + if (GetConnection()->BackendMinimumVersion(8, 3)) + properties->AppendItem(_("Family"), GetFamily()); + + if (!GetKeyType().IsEmpty()) + properties->AppendItem(_("Storage"), GetKeyType()); + unsigned int i; + for (i = 0 ; i < operators.Count() ; i++) + properties->AppendItem(wxT("OPERATOR"), operators.Item(i)); + for (i = 0 ; i < functions.Count() ; i++) + properties->AppendItem(wxT("FUNCTION"), functions.Item(i)); + properties->AppendYesNoItem(_("System operator class?"), GetSystemObject()); + if (GetConnection()->BackendMinimumVersion(7, 5)) + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgOperatorClass::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *operatorClass = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + operatorClass = operatorClassFactory.CreateObjects(coll, 0, wxT("\n AND op.oid=") + GetOidStr()); + + return operatorClass; +} + + +/////////////////////////////////////////////////// + + +pgOperatorClassCollection::pgOperatorClassCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgOperatorClassCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on operator classes"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing operator classes"); + break; + case OBJECTSLISTREPORT: + message = _("Operator classes list report"); + break; + } + + return message; +} + + +/////////////////////////////////////////////////// + + +pgObject *pgOperatorClassFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgOperatorClass *operatorClass = 0; + + pgSet *operatorClasses; + if (collection->GetDatabase()->BackendMinimumVersion(8, 3)) + { + operatorClasses = collection->GetDatabase()->ExecuteSet( + wxT("SELECT op.oid, op.*, pg_get_userbyid(op.opcowner) as opowner, it.typname as intypename, dt.typname as keytypename, amname, opfname\n") + wxT(" FROM pg_opclass op\n") + wxT(" JOIN pg_opfamily opf ON op.opcfamily=opf.oid\n") + wxT(" JOIN pg_am am ON am.oid=opf.opfmethod\n") + wxT(" JOIN pg_type it ON it.oid=opcintype\n") + wxT(" LEFT OUTER JOIN pg_type dt ON dt.oid=opckeytype\n") + wxT(" WHERE opcnamespace = ") + collection->GetSchema()->GetOidStr() + + restriction + wxT("\n") + wxT(" ORDER BY opcname")); + } + else + { + operatorClasses = collection->GetDatabase()->ExecuteSet( + wxT("SELECT op.oid, op.*, pg_get_userbyid(op.opcowner) as opowner, it.typname as intypename, dt.typname as keytypename, amname\n") + wxT(" FROM pg_opclass op\n") + wxT(" JOIN pg_am am ON am.oid=opcamid\n") + wxT(" JOIN pg_type it ON it.oid=opcintype\n") + wxT(" LEFT OUTER JOIN pg_type dt ON dt.oid=opckeytype\n") + wxT(" WHERE opcnamespace = ") + collection->GetSchema()->GetOidStr() + + restriction + wxT("\n") + wxT(" ORDER BY opcname")); + } + + + if (operatorClasses) + { + while (!operatorClasses->Eof()) + { + operatorClass = new pgOperatorClass( + collection->GetSchema(), operatorClasses->GetVal(wxT("opcname"))); + + operatorClass->iSetOid(operatorClasses->GetOid(wxT("oid"))); + operatorClass->iSetOwner(operatorClasses->GetVal(wxT("opowner"))); + operatorClass->iSetAccessMethod(operatorClasses->GetVal(wxT("amname"))); + operatorClass->iSetInType(operatorClasses->GetVal(wxT("intypename"))); + operatorClass->iSetKeyType(operatorClasses->GetVal(wxT("keytypename"))); + operatorClass->iSetOpcDefault(operatorClasses->GetBool(wxT("opcdefault"))); + + if (collection->GetDatabase()->BackendMinimumVersion(8, 3)) + operatorClass->iSetFamily(operatorClasses->GetVal(wxT("opfname"))); + + if (browser) + { + browser->AppendObject(collection, operatorClass); + operatorClasses->MoveNext(); + } + else + break; + } + + delete operatorClasses; + } + return operatorClass; +} + + +#include "images/operatorclass.pngc" +#include "images/operatorclasses.pngc" + +pgOperatorClassFactory::pgOperatorClassFactory() + : pgSchemaObjFactory(__("Operator Class"), __("New Operator Class..."), __("Create a new Operator Class."), operatorclass_png_img) +{ + metaType = PGM_OPCLASS; +} + +dlgProperty *pgOperatorClassFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return 0; // not implemented +} + +pgCollection *pgOperatorClassFactory::CreateCollection(pgObject *obj) +{ + return new pgOperatorClassCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgOperatorClassFactory operatorClassFactory; +static pgaCollectionFactory cf(&operatorClassFactory, __("Operator Classes"), operatorclasses_png_img); diff --git a/schema/pgOperatorFamily.cpp b/schema/pgOperatorFamily.cpp new file mode 100644 index 0000000..0bfc9ac --- /dev/null +++ b/schema/pgOperatorFamily.cpp @@ -0,0 +1,237 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgOperatorFamily.cpp - OperatorFamily class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgOperatorFamily.h" +#include "schema/pgFunction.h" + + +pgOperatorFamily::pgOperatorFamily(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, operatorFamilyFactory, newName) +{ +} + +pgOperatorFamily::~pgOperatorFamily() +{ +} + +wxString pgOperatorFamily::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on operator family"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing operator family"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop operator family \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop operator family \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop operator family cascaded?"); + break; + case DROPTITLE: + message = _("Drop operator family?"); + break; + case PROPERTIESREPORT: + message = _("Operator family properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Operator family properties"); + break; + case DDLREPORT: + message = _("Operator family DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Operator family DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Operator family dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Operator family dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Operator family dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Operator family dependents"); + break; + } + + return message; +} + +bool pgOperatorFamily::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP OPERATOR FAMILY ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier() + wxT(" USING ") + GetAccessMethod(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + +wxString pgOperatorFamily::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Operator Family: ") + GetName() + wxT("\n\n") + + wxT("-- DROP OPERATOR FAMILY ") + GetQuotedFullIdentifier() + wxT(" USING ") + GetAccessMethod() + wxT(";") + + wxT("\n\nCREATE OPERATOR FAMILY ") + GetQuotedFullIdentifier() + + wxT(" USING ") + GetAccessMethod() + + wxT(";"); + } + + return sql; +} + + +void pgOperatorFamily::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Access method"), GetAccessMethod()); + properties->AppendYesNoItem(_("System operator family?"), GetSystemObject()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgOperatorFamily::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *operatorFamily = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + operatorFamily = operatorFamilyFactory.CreateObjects(coll, 0, wxT("\n AND opf.oid=") + GetOidStr()); + + return operatorFamily; +} + + +/////////////////////////////////////////////////// + + +pgOperatorFamilyCollection::pgOperatorFamilyCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgOperatorFamilyCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on operator families"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing operator families"); + break; + case OBJECTSLISTREPORT: + message = _("Operator families list report"); + break; + } + + return message; +} + + +/////////////////////////////////////////////////// + + +pgObject *pgOperatorFamilyFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgOperatorFamily *operatorFamily = 0; + + pgSet *operatorFamilies; + + operatorFamilies = collection->GetDatabase()->ExecuteSet( + wxT("SELECT opf.oid, opf.*, pg_get_userbyid(opf.opfowner) as opowner, amname\n") + wxT(" FROM pg_opfamily opf\n") + wxT(" JOIN pg_am am ON am.oid=opf.opfmethod\n") + wxT(" WHERE opfnamespace = ") + collection->GetSchema()->GetOidStr() + + restriction + wxT("\n") + wxT(" ORDER BY opfname")); + + + if (operatorFamilies) + { + while (!operatorFamilies->Eof()) + { + operatorFamily = new pgOperatorFamily( + collection->GetSchema(), operatorFamilies->GetVal(wxT("opfname"))); + + operatorFamily->iSetOid(operatorFamilies->GetOid(wxT("oid"))); + operatorFamily->iSetOwner(operatorFamilies->GetVal(wxT("opowner"))); + operatorFamily->iSetAccessMethod(operatorFamilies->GetVal(wxT("amname"))); + + if (browser) + { + browser->AppendObject(collection, operatorFamily); + operatorFamilies->MoveNext(); + } + else + break; + } + + delete operatorFamilies; + } + return operatorFamily; +} + + +#include "images/operatorfamily.pngc" +#include "images/operatorfamilies.pngc" + +pgOperatorFamilyFactory::pgOperatorFamilyFactory() + : pgSchemaObjFactory(__("Operator Family"), __("New Operator Family..."), __("Create a new Operator Family."), operatorfamily_png_img) +{ + metaType = PGM_OPFAMILY; +} + +dlgProperty *pgOperatorFamilyFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return 0; // not implemented +} + +pgCollection *pgOperatorFamilyFactory::CreateCollection(pgObject *obj) +{ + return new pgOperatorFamilyCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgOperatorFamilyFactory operatorFamilyFactory; +static pgaCollectionFactory cf(&operatorFamilyFactory, __("Operator Families"), operatorfamilies_png_img); diff --git a/schema/pgPartition.cpp b/schema/pgPartition.cpp new file mode 100644 index 0000000..873fba3 --- /dev/null +++ b/schema/pgPartition.cpp @@ -0,0 +1,321 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gpPartition.cpp - Greenplum Table Partition class +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + + +#include "utils/misc.h" +#include "frm/frmHint.h" +#include "frm/frmMain.h" +#include "frm/frmMaintenance.h" +#include "schema/pgTable.h" +#include "schema/pgPartition.h" +#include "schema/pgColumn.h" +#include "schema/pgIndexConstraint.h" +#include "schema/pgForeignKey.h" +#include "schema/pgCheck.h" +#include "utils/sysSettings.h" +#include "utils/pgfeatures.h" +#include "schema/pgRule.h" +#include "schema/pgTrigger.h" +#include "schema/pgConstraints.h" + + +// App headers + +pgPartition::pgPartition(pgSchema *newSchema, const wxString &newName) + : pgTable(newSchema, pg_partitionFactory, newName) +{ +} + +pgPartition::~pgPartition() +{ +} + +bool pgPartition::CanCreate() +{ + return true; +} + +wxMenu *pgPartition::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + if (schema->GetCreatePrivilege()) + { + + } + return menu; +} +/* +wxString gpPartition::GetCreate() +{ + wxString sql; + + // sql = GetQuotedIdentifier() + wxT(" ") + // + GetTypeName().Upper() + GetDefinition(); + sql = wxT("Not implemented yet..sorry"); + return sql; +}; +*/ + +wxString pgPartition::GetSql(ctlTree *browser) +{ + wxString sql; + sql = wxT("-- "); + sql += _("Note: This DDL is a representation of how the partition might look as a table."); + sql += wxT("\n\n"); + + sql += pgTable::GetSql(browser); + return sql; +} + +pgObject *pgPartition::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgPartition *partition = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + partition = (pgPartition *)pg_partitionFactory.CreateObjects(coll, 0, wxT("\n AND rel.oid=") + GetOidStr()); + + return partition; +} + +/////////////////////////////////////////////////////////// + +pgPartitionCollection::pgPartitionCollection(pgaFactory *factory, pgPartition *_table) + : pgTableCollection(factory, _table->GetSchema()) +{ + iSetOid(_table->GetOid()); +} + + +pgObject *pgPartitionFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restriction) +{ + pgPartitionCollection *collection = (pgPartitionCollection *)coll; + wxString query; + pgPartition *table = 0; + + // Greenplum returns reltuples and relpages as tuples per segmentDB and pages per segmentDB, + // so we need to multiply them by the number of segmentDBs to get reasonable values. + long gp_segments = 1; + + //query = wxT("SELECT count(*) AS gp_segments from pg_catalog.gp_configuration where definedprimary = 't' and content >= 0"); + //gp_segments = StrToLong(collection->GetDatabase()->ExecuteScalar(query)); + //if (gp_segments <= 1) + // gp_segments = 1; + + + pgSet *tables; + + query = wxT("SELECT rel.oid, rel.relname, rel.reltablespace AS spcoid, spc.spcname, pg_get_userbyid(rel.relowner) AS relowner, rel.relacl, rel.relhasoids, ") + wxT("rel.relhassubclass, rel.reltuples, des.description, con.conname, con.conkey,\n") + wxT(" EXISTS(select 1 FROM pg_trigger\n") + wxT(" JOIN pg_proc pt ON pt.oid=tgfoid AND pt.proname='logtrigger'\n") + wxT(" JOIN pg_proc pc ON pc.pronamespace=pt.pronamespace AND pc.proname='slonyversion'\n") + wxT(" WHERE tgrelid=rel.oid) AS isrepl,\n"); + query += wxT(" (select count(*) FROM pg_trigger\n") + wxT(" WHERE tgrelid=rel.oid AND tgisinternal = FALSE) AS triggercount\n"); + query += wxT(", rel.relpersistence \n"); + query += wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'fillfactor=([0-9]*)') AS fillfactor \n"); + query += wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') AS autovacuum_enabled \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS autovacuum_vacuum_threshold \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.][0-9]*)') AS autovacuum_vacuum_scale_factor \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_analyze_threshold=([0-9]*)') AS autovacuum_analyze_threshold \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_analyze_scale_factor=([0-9]*[.][0-9]*)') AS autovacuum_analyze_scale_factor \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS autovacuum_vacuum_cost_delay \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS autovacuum_vacuum_cost_limit \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_min_age=([0-9]*)') AS autovacuum_freeze_min_age \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_max_age=([0-9]*)') AS autovacuum_freeze_max_age \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS autovacuum_freeze_table_age \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') AS toast_autovacuum_enabled \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS toast_autovacuum_vacuum_threshold \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.][0-9]*)') AS toast_autovacuum_vacuum_scale_factor \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_analyze_threshold=([0-9]*)') AS toast_autovacuum_analyze_threshold \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_analyze_scale_factor=([0-9]*[.][0-9]*)') AS toast_autovacuum_analyze_scale_factor \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS toast_autovacuum_vacuum_cost_delay \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS toast_autovacuum_vacuum_cost_limit \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_min_age=([0-9]*)') AS toast_autovacuum_freeze_min_age \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_max_age=([0-9]*)') AS toast_autovacuum_freeze_max_age \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS toast_autovacuum_freeze_table_age \n") + wxT(", rel.reloptions AS reloptions, tst.reloptions AS toast_reloptions \n") + wxT(", (CASE WHEN rel.reltoastrelid = 0 THEN false ELSE true END) AS hastoasttable\n"); + query += wxT(", rel.reloftype, typ.typname\n"); + query += wxT(",\n(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=rel.oid AND sl1.objsubid=0) AS labels"); + query += wxT(",\n(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=rel.oid AND sl2.objsubid=0) AS providers"); + query += wxT(",pg_catalog.pg_get_partkeydef(rel.oid)\n AS partkeydef"); + query += wxT(",pg_get_expr(rel.relpartbound, rel.oid)\n AS partexp"); + query += wxT(" FROM pg_class rel\n") + wxT(" JOIN pg_inherits i ON (rel.oid = i.inhrelid) \n") + wxT(" LEFT OUTER JOIN pg_tablespace spc on spc.oid=rel.reltablespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=rel.oid AND des.objsubid=0 AND des.classoid='pg_class'::regclass)\n") + wxT(" LEFT OUTER JOIN pg_constraint con ON con.conrelid=rel.oid AND con.contype='p'\n"); + query += wxT(" LEFT OUTER JOIN pg_class tst ON tst.oid = rel.reltoastrelid\n"); + query += wxT("LEFT JOIN pg_type typ ON rel.reloftype=typ.oid\n"); + + query += wxT(" WHERE rel.relkind IN ('r','s','t','p') AND rel.relnamespace = ") + collection->GetSchema()->GetOidStr() + wxT("\n"); + query += wxT("--AND (not (rel.relkind='r' and rel.relpartbound IS NOT NULL))\n ") + wxT(" AND i.inhparent = ") + collection->GetOidStr() + wxT("\n"); + + query += restriction + + wxT(" ORDER BY rel.relname"); + + + tables = collection->GetDatabase()->ExecuteSet(query); + if (tables) + { + while (!tables->Eof()) + { + table = new pgPartition(collection->GetSchema(), tables->GetVal(wxT("relname"))); + + table->iSetOid(tables->GetOid(wxT("oid"))); + table->iSetOwner(tables->GetVal(wxT("relowner"))); + table->iSetAcl(tables->GetVal(wxT("relacl"))); + if (tables->GetOid(wxT("spcoid")) == 0) + table->iSetTablespaceOid(collection->GetDatabase()->GetTablespaceOid()); + else + table->iSetTablespaceOid(tables->GetOid(wxT("spcoid"))); + + if (tables->GetVal(wxT("spcname")) == wxEmptyString) + table->iSetTablespace(collection->GetDatabase()->GetTablespace()); + else + table->iSetTablespace(tables->GetVal(wxT("spcname"))); + table->iSetOfTypeOid(tables->GetOid(wxT("reloftype"))); + table->iSetOfType(tables->GetVal(wxT("typname"))); + table->iSetComment(tables->GetVal(wxT("description"))); + table->iSetUnlogged(tables->GetVal(wxT("relpersistence")) == wxT("u")); + table->iSetHasOids(tables->GetBool(wxT("relhasoids"))); + table->iSetEstimatedRows(tables->GetDouble(wxT("reltuples")) * gp_segments); + table->iSetFillFactor(tables->GetVal(wxT("fillfactor"))); + if (collection->GetConnection()->BackendMinimumVersion(8, 4)) + { + table->iSetRelOptions(tables->GetVal(wxT("reloptions"))); + if (table->GetCustomAutoVacuumEnabled()) + { + if (tables->GetVal(wxT("autovacuum_enabled")).IsEmpty()) + table->iSetAutoVacuumEnabled(2); + else if (tables->GetBool(wxT("autovacuum_enabled"))) + table->iSetAutoVacuumEnabled(1); + else + table->iSetAutoVacuumEnabled(0); + table->iSetAutoVacuumVacuumThreshold(tables->GetVal(wxT("autovacuum_vacuum_threshold"))); + table->iSetAutoVacuumVacuumScaleFactor(tables->GetVal(wxT("autovacuum_vacuum_scale_factor"))); + table->iSetAutoVacuumAnalyzeThreshold(tables->GetVal(wxT("autovacuum_analyze_threshold"))); + table->iSetAutoVacuumAnalyzeScaleFactor(tables->GetVal(wxT("autovacuum_analyze_scale_factor"))); + table->iSetAutoVacuumVacuumCostDelay(tables->GetVal(wxT("autovacuum_vacuum_cost_delay"))); + table->iSetAutoVacuumVacuumCostLimit(tables->GetVal(wxT("autovacuum_vacuum_cost_limit"))); + table->iSetAutoVacuumFreezeMinAge(tables->GetVal(wxT("autovacuum_freeze_min_age"))); + table->iSetAutoVacuumFreezeMaxAge(tables->GetVal(wxT("autovacuum_freeze_max_age"))); + table->iSetAutoVacuumFreezeTableAge(tables->GetVal(wxT("autovacuum_freeze_table_age"))); + } + table->iSetHasToastTable(tables->GetBool(wxT("hastoasttable"))); + if (table->GetHasToastTable()) + { + table->iSetToastRelOptions(tables->GetVal(wxT("toast_reloptions"))); + + if (table->GetToastCustomAutoVacuumEnabled()) + { + if (tables->GetVal(wxT("toast_autovacuum_enabled")).IsEmpty()) + table->iSetToastAutoVacuumEnabled(2); + else if (tables->GetBool(wxT("toast_autovacuum_enabled"))) + table->iSetToastAutoVacuumEnabled(1); + else + table->iSetToastAutoVacuumEnabled(0); + + table->iSetToastAutoVacuumVacuumThreshold(tables->GetVal(wxT("toast_autovacuum_vacuum_threshold"))); + table->iSetToastAutoVacuumVacuumScaleFactor(tables->GetVal(wxT("toast_autovacuum_vacuum_scale_factor"))); + table->iSetToastAutoVacuumVacuumCostDelay(tables->GetVal(wxT("toast_autovacuum_vacuum_cost_delay"))); + table->iSetToastAutoVacuumVacuumCostLimit(tables->GetVal(wxT("toast_autovacuum_vacuum_cost_limit"))); + table->iSetToastAutoVacuumFreezeMinAge(tables->GetVal(wxT("toast_autovacuum_freeze_min_age"))); + table->iSetToastAutoVacuumFreezeMaxAge(tables->GetVal(wxT("toast_autovacuum_freeze_max_age"))); + table->iSetToastAutoVacuumFreezeTableAge(tables->GetVal(wxT("toast_autovacuum_freeze_table_age"))); + } + } + } + table->iSetHasSubclass(tables->GetBool(wxT("relhassubclass"))); + table->iSetPrimaryKeyName(tables->GetVal(wxT("conname"))); + table->iSetIsReplicated(tables->GetBool(wxT("isrepl"))); + table->iSetTriggerCount(tables->GetLong(wxT("triggercount"))); + wxString cn = tables->GetVal(wxT("conkey")); + cn = cn.Mid(1, cn.Length() - 2); + table->iSetPrimaryKeyColNumbers(cn); + if (collection->GetConnection()->BackendMinimumVersion(10, 0)) + { + table->iSetPartKeyDef(tables->GetVal(wxT("partkeydef"))); + table->iSetPartExp(tables->GetVal(wxT("partexp"))); + } + if (collection->GetConnection()->GetIsGreenplum()) + { + Oid lo = tables->GetOid(wxT("localoid")); + wxString db = tables->GetVal(wxT("attrnums")); + db = db.Mid(1, db.Length() - 2); + table->iSetDistributionColNumbers(db); + if (lo > 0 && db.Length() == 0) + table->iSetDistributionIsRandom(); + table->iSetAppendOnly(tables->GetVal(wxT("appendonly"))); + table->iSetCompressLevel(tables->GetVal(wxT("compresslevel"))); + table->iSetOrientation(tables->GetVal(wxT("orientation"))); + table->iSetCompressType(tables->GetVal(wxT("compresstype"))); + table->iSetBlocksize(tables->GetVal(wxT("blocksize"))); + table->iSetChecksum(tables->GetVal(wxT("checksum"))); + + table->iSetPartitionDef(wxT("")); + table->iSetIsPartitioned(false); + + if (collection->GetConnection()->BackendMinimumVersion(8, 2, 9)) + { + table->iSetIsPartitioned(tables->GetBool(wxT("ispartitioned"))); + } + + } + + if (collection->GetConnection()->BackendMinimumVersion(9, 1)) + { + table->iSetProviders(tables->GetVal(wxT("providers"))); + table->iSetLabels(tables->GetVal(wxT("labels"))); + } + + if (browser) + { + browser->AppendObject(collection, table); + tables->MoveNext(); + } + else + break; + } + + delete tables; + } + return table; +} + +void pgPartitionFactory::AppendMenu(wxMenu *menu) +{ +} + +#include "images/table.pngc" +#include "images/table-sm.pngc" +#include "images/tables.pngc" + +pgPartitionFactory::pgPartitionFactory() + : pgTableObjFactory(__("Partition"), __("New Partition..."), __("Create a new Partition."), table_png_img, table_sm_png_img) +{ + metaType = PGM_TABLE; + typeName = wxT("TABLE"); +} + +pgCollection *pgPartitionFactory::CreateCollection(pgObject *obj) +{ + return new pgPartitionCollection(GetCollectionFactory(), (pgPartition *)obj ); +} + +pgPartitionFactory pg_partitionFactory; +static pgaCollectionFactory cf(&pg_partitionFactory, __("Partitions"), tables_png_img); + + diff --git a/schema/pgRole.cpp b/schema/pgRole.cpp new file mode 100644 index 0000000..579c729 --- /dev/null +++ b/schema/pgRole.cpp @@ -0,0 +1,820 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgRole.cpp - PostgreSQL Role +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgRole.h" +#include "frm/frmMain.h" +#include "dlg/dlgReassignDropOwned.h" +#include "utils/pgDefs.h" +#include "schema/pgDatabase.h" +#include "schema/pgTablespace.h" + + +pgLoginRole::pgLoginRole(const wxString &newName) + : pgRole(loginRoleFactory, newName) +{ +} + + +pgGroupRole::pgGroupRole(const wxString &newName) + : pgRole(groupRoleFactory, newName) +{ +} + + +pgRole::pgRole(pgaFactory &factory, const wxString &newName) + : pgServerObject(factory, newName) +{ +} + + +wxString pgLoginRole::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on login role"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing login role"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop login role \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop login role \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop login role cascaded?"); + break; + case DROPTITLE: + message = _("Drop login role?"); + break; + case PROPERTIESREPORT: + message = _("Login role properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Login role properties"); + break; + case DDLREPORT: + message = _("Login role DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Login role DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Login role dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Login role dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Login role dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Login role dependents"); + break; + } + + return message; +} + + +wxString pgGroupRole::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on group role"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing group role"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop group role \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop group role \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop group role cascaded?"); + break; + case DROPTITLE: + message = _("Drop group role?"); + break; + case PROPERTIESREPORT: + message = _("Group role properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Group role properties"); + break; + case DDLREPORT: + message = _("Group role DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Group role DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Group role dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Group role dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Group role dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Group role dependents"); + break; + } + + return message; +} + + +int pgRole::GetIconId() +{ + if (GetCanLogin()) + return loginRoleFactory.GetIconId(); + else + return groupRoleFactory.GetIconId(); +} + + +bool pgRole::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + if ((GetUpdateCatalog() && !server->GetConnection()->BackendMinimumVersion(9, 5)) || + (server->GetConnection()->BackendMinimumVersion(9, 5) && this->GetSuperuser())) + { + wxMessageDialog dlg(frame, + _("Deleting a superuser might result in unwanted behaviour (e.g. when restoring the database).\nAre you sure?"), + _("Confirm superuser deletion"), + wxICON_EXCLAMATION | wxYES_NO | wxNO_DEFAULT); + if (dlg.ShowModal() != wxID_YES) + return false; + } + return server->ExecuteVoid(wxT("DROP ROLE ") + GetQuotedFullIdentifier() + wxT(";")); +} + + +wxString pgRole::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Role: ") + GetName() + wxT("\n\n") + + wxT("-- DROP ROLE ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE ROLE ") + GetQuotedIdentifier(); + + if (GetCanLogin()) + { + sql += wxT(" LOGIN"); + if (GetPassword() != wxT("********") && !GetPassword().IsEmpty()) + AppendIfFilled(sql, wxT("\n ENCRYPTED PASSWORD "), qtDbString(GetPassword())); + } + sql += wxT("\n "); + if (this->GetSuperuser()) sql += wxT(" SUPERUSER"); + else sql += wxT(" NOSUPERUSER"); + if (GetInherits()) sql += wxT(" INHERIT"); + else sql += wxT(" NOINHERIT"); + if (GetCreateDatabase()) sql += wxT(" CREATEDB"); + else sql += wxT(" NOCREATEDB"); + if (GetCreateRole()) sql += wxT(" CREATEROLE"); + else sql += wxT(" NOCREATEROLE"); + if (server->GetConnection()->BackendMinimumVersion(9, 1)) + { + if (GetReplication()) sql += wxT(" REPLICATION"); + else sql += wxT(" NOREPLICATION"); + } + if (GetConnectionLimit() > 0) + sql += wxT(" CONNECTION LIMIT ") + NumToStr(GetConnectionLimit()); + if (GetAccountExpires().IsValid()) + AppendIfFilled(sql, wxT(" VALID UNTIL "), qtDbString(DateToAnsiStr(GetAccountExpires()))); + if (GetRolQueueName().Length() > 0) + AppendIfFilled(sql, wxT(" RESOURCE QUEUE "), GetRolQueueName()); + sql += wxT(";\n"); + + if (this->GetSuperuser() && !GetUpdateCatalog() && + !server->GetConnection()->BackendMinimumVersion(9, 5)) + sql += wxT("UPDATE pg_authid SET rolcatupdate=false WHERE rolname=") + qtDbString(GetIdentifier()) + wxT(";\n"); + + size_t index; + if (variables.GetCount() > 0) + { + wxString dbname = wxEmptyString; + wxString parameter = wxEmptyString; + wxString value = wxEmptyString; + + sql += wxT("\n"); + for (index = 0 ; index < variables.GetCount() ; index += 3) + { + dbname = variables.Item(index); + parameter = variables.Item(index + 1); + value = variables.Item(index + 2); + + if (dbname.Length() == 0) + { + sql += wxT("ALTER ROLE ") + GetQuotedFullIdentifier(); + } + else + { + sql += wxT("ALTER ROLE ") + GetQuotedFullIdentifier() + wxT(" IN DATABASE ") + dbname; + } + + if (parameter != wxT("search_path") && parameter != wxT("temp_tablespaces")) + { + sql += wxT("\n SET ") + parameter + wxT(" = '") + value + wxT("';\n"); + } + else + { + sql += wxT("\n SET ") + parameter + wxT(" = ") + value + wxT(";\n"); + } + } + } + + for (index = 0 ; index < rolesIn.GetCount() ; index++) + { + wxString role = rolesIn.Item(index); + bool admin = false; + if (role.Right(PGROLE_ADMINOPTION_LEN) == PGROLE_ADMINOPTION) + { + admin = true; + role = role.Left(role.Length() - PGROLE_ADMINOPTION_LEN); + } + sql += wxT("GRANT ") + qtIdent(role) + + wxT(" TO ") + GetQuotedIdentifier(); + + if (admin) + sql += wxT(" WITH ADMIN OPTION"); + + sql += wxT(";\n"); + } + + if (!GetComment().IsNull()) + { + sql += wxT("COMMENT ON ROLE ") + GetQuotedFullIdentifier() + wxT(" IS ") + + qtDbString(GetComment()) + wxT(";\n"); + } + + if (GetConnection()->BackendMinimumVersion(9, 2)) + sql += GetSeqLabelsSql(); + } + return sql; +} + + + +void pgRole::ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &where) +{ + form->StartMsg(_(" Retrieving Role owned objects")); + + referencedBy->ClearAll(); + referencedBy->AddColumn(_("Type"), 60); + referencedBy->AddColumn(_("Database"), 80); + referencedBy->AddColumn(_("Name"), 300); + + wxString sysoid = NumToStr(GetConnection()->GetLastSystemOID()); + + wxArrayString dblist; + + pgSet *set; + set = GetConnection()->ExecuteSet( + wxT("SELECT 'd' as type, datname, datallowconn, datdba\n") + wxT(" FROM pg_database db\n") + wxT("UNION\n") + wxT("SELECT 'M', spcname, null, null\n") + wxT(" FROM pg_tablespace where spcowner=") + GetOidStr() + wxT("\n") + wxT(" ORDER BY 1, 2")); + + if (set) + { + while (!set->Eof()) + { + wxString name = set->GetVal(wxT("datname")); + if (set->GetVal(wxT("type")) == wxT("d")) + { + if (set->GetBool(wxT("datallowconn"))) + dblist.Add(name); + if (GetOidStr() == set->GetVal(wxT("datdba"))) + referencedBy->AppendItem(databaseFactory.GetIconId(), _("Database"), name); + } + else + referencedBy->AppendItem(tablespaceFactory.GetIconId(), _("Tablespace"), wxEmptyString, name); + + set->MoveNext(); + } + delete set; + } + + // We ignore classid and refclassid here because we hope that oids are unique + // across system tables. + // Strictly speaking, we'd need to join pg_shdepend to each subquery + + wxString depOids = wxT("(SELECT objid FROM pg_shdepend WHERE refobjid=") + GetOidStr() + wxT(")"); + + FillOwned(form->GetBrowser(), referencedBy, dblist, + wxT("SELECT cl.relkind, COALESCE(cin.nspname, cln.nspname) as nspname, COALESCE(ci.relname, cl.relname) as relname, cl.relname as indname\n") + wxT(" FROM pg_class cl\n") + wxT(" JOIN pg_namespace cln ON cl.relnamespace=cln.oid\n") + wxT(" LEFT OUTER JOIN pg_index ind ON ind.indexrelid=cl.oid\n") + wxT(" LEFT OUTER JOIN pg_class ci ON ind.indrelid=ci.oid\n") + wxT(" LEFT OUTER JOIN pg_namespace cin ON ci.relnamespace=cin.oid\n") + wxT(" WHERE cl.oid IN ") + depOids + wxT(" AND cl.oid > ") + sysoid + wxT("\n") + wxT("UNION ALL\n") + wxT("SELECT 'n', null, nspname, null\n") + wxT(" FROM pg_namespace nsp WHERE nsp.oid IN ") + depOids + wxT(" AND nsp.oid > ") + sysoid + wxT("\n") + wxT("UNION ALL\n") + wxT("SELECT CASE WHEN typtype='d' THEN 'd' ELSE 'y' END, null, typname, null\n") + wxT(" FROM pg_type ty WHERE ty.oid IN ") + depOids + wxT(" AND ty.oid > ") + sysoid + wxT("\n") + wxT("UNION ALL\n") + wxT("SELECT 'C', null, conname, null\n") + wxT(" FROM pg_conversion co WHERE co.oid IN ") + depOids + wxT(" AND co.oid > ") + sysoid + wxT("\n") + wxT("UNION ALL\n") + wxT("SELECT CASE WHEN prorettype=") + NumToStr(PGOID_TYPE_TRIGGER) + wxT(" THEN 'T' ELSE 'p' END, null, proname, null\n") + wxT(" FROM pg_proc pr WHERE pr.oid IN ") + depOids + wxT(" AND pr.oid > ") + sysoid + wxT("\n") + wxT("UNION ALL\n") + wxT("SELECT 'o', null, oprname || '('::text || ") + wxT("COALESCE(tl.typname, ''::text) || ") + wxT("CASE WHEN tl.oid IS NOT NULL AND tr.oid IS NOT NULL THEN ','::text END || ") + wxT("COALESCE(tr.typname, ''::text) || ')'::text, null\n") + wxT(" FROM pg_operator op\n") + wxT(" LEFT JOIN pg_type tl ON tl.oid=op.oprleft\n") + wxT(" LEFT JOIN pg_type tr ON tr.oid=op.oprright\n") + wxT(" WHERE op.oid IN ") + depOids + wxT(" AND op.oid > ") + sysoid + wxT("\n") + wxT(" ORDER BY 1,2,3")); + + form->EndMsg(set != 0); +} + + +void pgRole::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + wxString rolesquery; + + if (GetConnection()->BackendMinimumVersion(8, 2)) + rolesquery = wxT("SELECT rolname, admin_option,\n") + wxT(" pg_catalog.shobj_description(r.oid, 'pg_authid') AS description\n"); + else + rolesquery = wxT("SELECT rolname, admin_option\n"); + + rolesquery += wxT(" FROM pg_roles r\n") + wxT(" JOIN pg_auth_members ON r.oid=roleid\n") + wxT(" WHERE member=") + GetOidStr() + wxT("\n") + wxT(" ORDER BY rolname"); + + pgSetIterator roles(GetConnection(), rolesquery); + + while (roles.RowsLeft()) + { + wxString role = roles.GetVal(wxT("rolname")); + if (roles.GetBool(wxT("admin_option"))) + role += PGROLE_ADMINOPTION; + + rolesIn.Add(role); + } + + // Get configuration + wxString query; + if (GetConnection()->BackendMinimumVersion(9, 0)) + { + query = wxT("WITH configs AS ") + wxT("(SELECT datname, unnest(setconfig) AS config") + wxT(" FROM pg_db_role_setting s") + wxT(" LEFT JOIN pg_database d ON d.oid=s.setdatabase") + wxT(" WHERE s.setrole=") + NumToStr(GetOid()) + wxT(")\n") + wxT("SELECT datname, split_part(config, '=', 1) AS variable, replace(config, split_part(config, '=', 1) || '=', '') AS value\n") + wxT("FROM configs"); + } + else + { + wxString query_myrole = wxT("SELECT rolconfig FROM pg_roles WHERE oid=") + NumToStr(GetOid()); + query = wxT("SELECT '' AS datname, split_part(config, '=', 1) AS variable,\n") + wxT(" replace(config,split_part(config, '=', 1) || '=', '') AS value\n") + wxT("FROM (\n") + wxT(" SELECT\n") + wxT(" (\n") + wxT(" SELECT rolconfig[i]\n") + wxT(" FROM pg_roles\n") + wxT(" WHERE oid=") + NumToStr(GetOid()) + wxT("\n") + wxT(" ) AS config\n") + wxT(" FROM generate_series(array_lower((") + query_myrole + wxT("),1), array_upper((") + query_myrole + wxT("),1)) AS i\n") + wxT(" ) configs"); + } + pgSet *configs = GetConnection()->ExecuteSet(query); + if (configs) + { + while (!configs->Eof()) + { + variables.Add(configs->GetVal(wxT("datname"))); + variables.Add(configs->GetVal(wxT("variable"))); + variables.Add(configs->GetVal(wxT("value"))); + configs->MoveNext(); + } + delete configs; + } + } + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Account expires"), DateToAnsiStr(GetAccountExpires())); + properties->AppendItem(_("Can login?"), BoolToYesNo(GetCanLogin())); + properties->AppendItem(_("Superuser?"), BoolToYesNo(GetSuperuser())); + properties->AppendItem(_("Create databases?"), BoolToYesNo(GetCreateDatabase())); + properties->AppendItem(_("Create roles?"), BoolToYesNo(GetCreateRole())); + + if (!server->GetConnection()->BackendMinimumVersion(9, 5)) + properties->AppendItem(_("Update catalogs?"), BoolToYesNo(GetUpdateCatalog())); + properties->AppendItem(_("Inherits?"), BoolToYesNo(GetInherits())); + if (server->GetConnection()->BackendMinimumVersion(9, 1)) + { + properties->AppendItem(_("Replication?"), BoolToYesNo(GetReplication())); + } + + wxString strConnLimit; + strConnLimit.Printf(wxT("%ld"), GetConnectionLimit()); + properties->AppendItem(_("Connection Limit"), strConnLimit); + + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + wxString roleList; + + size_t index; + for (index = 0 ; index < rolesIn.GetCount() ; index++) + { + if (!roleList.IsEmpty()) + roleList += wxT(", "); + roleList += rolesIn.Item(index); + } + properties->AppendItem(_("Member of"), roleList); + + wxString dbname; + wxString parameter; + wxString value; + for (index = 0; index < variables.GetCount() ; index += 3) + { + dbname = variables.Item(index); + parameter = variables.Item(index + 1); + value = variables.Item(index + 2); + + if (dbname.Length() == 0) + { + properties->AppendItem(parameter, value); + } + else + { + properties->AppendItem(parameter + wxT(" (database ") + dbname + wxT(")"), value); + } + } + + if (!GetLabels().IsEmpty()) + { + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); + } + } + } + } +} + +void pgRole::ReassignDropOwnedTo(frmMain *form) +{ + wxString query; + + dlgReassignDropOwned rdo(form, GetConnection(), this, GetServer()->GetDbRestriction()); + if (rdo.ShowModal() != wxID_CANCEL) + { + pgConn *conn; + conn = new pgConn(GetConnection()->GetHost(), + GetConnection()->GetService(), + GetConnection()->GetHostAddr(), + rdo.GetDatabase(), + GetConnection()->GetUser(), + GetConnection()->GetPassword(), + GetConnection()->GetPort(), + GetConnection()->GetRole(), + GetConnection()->GetSslMode(), + 0, + GetConnection()->GetApplicationName(), + GetConnection()->GetSSLCert(), + GetConnection()->GetSSLKey(), + GetConnection()->GetSSLRootCert(), + GetConnection()->GetSSLCrl(), + GetConnection()->GetSSLCompression()); + + if (conn->GetStatus() == PGCONN_OK) + { + if (rdo.IsReassign()) + { + if (wxMessageBox(_("Are you sure you wish to reassign all objects owned by the selected role?"), _("Reassign objects"), wxYES_NO) != wxYES) + return; + + query = wxT("REASSIGN OWNED BY ") + GetQuotedFullIdentifier() + wxT(" TO ") + qtIdent(rdo.GetRole()); + } + else + { + if (wxMessageBox(_("Are you sure you wish to drop all objects owned by the selected role?"), _("Drop objects"), wxYES_NO) != wxYES) + return; + + query = wxT("DROP OWNED BY ") + GetQuotedFullIdentifier(); + } + conn->ExecuteVoid(query); + } + else + { + wxMessageBox(wxT("Connection failed: ") + conn->GetLastError()); + } + } +} + + +pgObject *pgRole::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *role = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + { + if (coll->GetServer()->GetConnection()->BackendMinimumVersion(8, 5)) + role = loginRoleFactory.CreateObjects(coll, 0, wxT("\n WHERE tab.oid=") + GetOidStr()); + else + role = loginRoleFactory.CreateObjects(coll, 0, wxT("\n WHERE oid=") + GetOidStr()); + } + + return role; +} + + + +pgObject *pgRoleBaseFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgRole *role = 0; + pgSet *roles = 0; + wxString query; + + wxString tabname; + + if (collection->GetServer()->HasPrivilege(wxT("table"), wxT("pg_authid"), wxT("SELECT"))) + tabname = wxT("pg_authid"); + else + tabname = wxT("pg_roles"); + + // In 9.0+, role config options are in pg_db_role_setting + if (collection->GetServer()->GetConnection()->BackendMinimumVersion(8, 5)) + { + query = wxT("SELECT tab.oid, tab.*, pg_catalog.shobj_description(tab.oid, 'pg_authid') AS description"); + if (collection->GetServer()->GetConnection()->GetIsGreenplum()) + query += wxT(", (SELECT rsqname FROM pg_resqueue WHERE pg_resqueue.oid = rolresqueue) AS rsqname"); + if (collection->GetServer()->GetConnection()->BackendMinimumVersion(9, 2)) + { + query += wxT(",\n(SELECT array_agg(label) FROM pg_shseclabel sl1 WHERE sl1.objoid=tab.oid) AS labels") + wxT(",\n(SELECT array_agg(provider) FROM pg_shseclabel sl2 WHERE sl2.objoid=tab.oid) AS providers"); + } + query += wxT(" FROM ") + tabname + wxT(" tab") + + restriction + wxT(" ORDER BY rolname"); + } + else if (collection->GetServer()->GetConnection()->BackendMinimumVersion(8, 2)) + { + query = wxT("SELECT oid, *, pg_catalog.shobj_description(oid, 'pg_authid') AS description "); + if (collection->GetServer()->GetConnection()->GetIsGreenplum()) + query += wxT(", (SELECT rsqname FROM pg_resqueue WHERE pg_resqueue.oid = rolresqueue) AS rsqname"); + query += wxT(" FROM ") + tabname + restriction + wxT(" ORDER BY rolname"); + } + else + { + query = wxT("SELECT oid, *, '' AS description ") ; + if (collection->GetServer()->GetConnection()->GetIsGreenplum()) + query += wxT(", (SELECT rsqname FROM pg_resqueue WHERE pg_resqueue.oid = rolresqueue) AS rsqname"); + query += wxT(" FROM ") + tabname + restriction + wxT(" ORDER BY rolname"); + } + roles = collection->GetServer()->ExecuteSet(query); + + if (roles) + { + while (!roles->Eof()) + { + if (roles->GetBool(wxT("rolcanlogin"))) + role = new pgLoginRole(roles->GetVal(wxT("rolname"))); + else + role = new pgGroupRole(roles->GetVal(wxT("rolname"))); + role->iSetServer(collection->GetServer()); + role->iSetOid(roles->GetOid(wxT("oid"))); + role->iSetCanLogin(roles->GetBool(wxT("rolcanlogin"))); + role->iSetInherits(roles->GetBool(wxT("rolinherit"))); + role->iSetCreateRole(roles->GetBool(wxT("rolcreaterole"))); + role->iSetCreateDatabase(roles->GetBool(wxT("rolcreatedb"))); + role->iSetSuperuser(roles->GetBool(wxT("rolsuper"))); + + if (!collection->GetServer()->GetConnection()->BackendMinimumVersion(9, 5)) + role->iSetUpdateCatalog(roles->GetBool(wxT("rolcatupdate"))); + role->iSetAccountExpires(roles->GetDateTime(wxT("rolvaliduntil"))); + role->iSetIsValidInfinity(roles->GetVal(wxT("rolvaliduntil")) == wxT("infinity") ? true : false); + role->iSetPassword(roles->GetVal(wxT("rolpassword"))); + role->iSetComment(roles->GetVal(wxT("description"))); + role->iSetConnectionLimit(roles->GetLong(wxT("rolconnlimit"))); + + if (collection->GetServer()->GetConnection()->BackendMinimumVersion(9, 1)) + { + role->iSetReplication(roles->GetBool(wxT("rolreplication"))); + } + + if (collection->GetServer()->GetConnection()->GetIsGreenplum()) + { + role->iSetRolQueueName(roles->GetVal(wxT("rsqname"))); + } + + if (collection->GetServer()->GetConnection()->BackendMinimumVersion(9, 2)) + { + role->iSetProviders(roles->GetVal(wxT("providers"))); + role->iSetLabels(roles->GetVal(wxT("labels"))); + } + + if (browser) + { + browser->AppendObject(collection, role); + roles->MoveNext(); + } + else + break; + } + + delete roles; + } + return role; +} + + +///////////////////////////// + +pgLoginRoleCollection::pgLoginRoleCollection(pgaFactory *factory, pgServer *sv) + : pgServerObjCollection(factory, sv) +{ +} + + +wxString pgLoginRoleCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on login roles"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing login roles"); + break; + case OBJECTSLISTREPORT: + message = _("Login roles list report"); + break; + } + + return message; +} + + +///////////////////////////// + +pgGroupRoleCollection::pgGroupRoleCollection(pgaFactory *factory, pgServer *sv) + : pgServerObjCollection(factory, sv) +{ +} + + +wxString pgGroupRoleCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on group roles"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing group roles"); + break; + case OBJECTSLISTREPORT: + message = _("Group roles list report"); + break; + } + + return message; +} + + +pgObject *pgLoginRoleFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + if (restriction.IsEmpty()) + return pgRoleBaseFactory::CreateObjects(collection, browser, wxT(" WHERE rolcanlogin")); + else + return pgRoleBaseFactory::CreateObjects(collection, browser, restriction); +} + + +pgObject *pgGroupRoleFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + if (restriction.IsEmpty()) + return pgRoleBaseFactory::CreateObjects(collection, browser, wxT(" WHERE NOT rolcanlogin")); + else + return pgRoleBaseFactory::CreateObjects(collection, browser, restriction); +} + + +#include "images/user.pngc" +#include "images/group.pngc" +#include "images/roles.pngc" +#include "images/loginroles.pngc" + + +pgRoleBaseFactory::pgRoleBaseFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img) + : pgServerObjFactory(tn, ns, nls, img) +{ + metaType = PGM_ROLE; +} + +pgLoginRoleFactory::pgLoginRoleFactory() + : pgRoleBaseFactory(__("Login Role"), __("New Login Role..."), __("Create a new Login Role."), user_png_img) +{ +} + +pgCollection *pgLoginRoleFactory::CreateCollection(pgObject *obj) +{ + return new pgLoginRoleCollection(GetCollectionFactory(), (pgServer *)obj); +} + +pgLoginRoleFactory loginRoleFactory; +static pgaCollectionFactory lcf(&loginRoleFactory, __("Login Roles"), loginroles_png_img); + + +pgGroupRoleFactory::pgGroupRoleFactory() + : pgRoleBaseFactory(__("Group Role"), __("New Group Role..."), __("Create a new Group Role."), group_png_img) +{ +} + +pgCollection *pgGroupRoleFactory::CreateCollection(pgObject *obj) +{ + return new pgGroupRoleCollection(GetCollectionFactory(), (pgServer *)obj); +} + +pgGroupRoleFactory groupRoleFactory; +static pgaCollectionFactory gcf(&groupRoleFactory, __("Group Roles"), roles_png_img); + + +reassignDropOwnedFactory::reassignDropOwnedFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Reassign/Drop Owned..."), _("Reassigned or drop objects owned by the selected role.")); +} + + +wxWindow *reassignDropOwnedFactory::StartDialog(frmMain *form, pgObject *obj) +{ + ((pgRole *)obj)->ReassignDropOwnedTo(form); + + return 0; +} + +bool reassignDropOwnedFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(loginRoleFactory) && ((pgRole *)obj)->GetConnection()->BackendMinimumVersion(8, 2); +} diff --git a/schema/pgRule.cpp b/schema/pgRule.cpp new file mode 100644 index 0000000..a16bfd2 --- /dev/null +++ b/schema/pgRule.cpp @@ -0,0 +1,356 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgRule.cpp - Rule class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "frm/frmMain.h" +#include "utils/misc.h" +#include "schema/pgRule.h" + + +pgRule::pgRule(pgSchema *newSchema, const wxString &newName) + : pgRuleObject(newSchema, ruleFactory, newName) +{ +} + +pgRule::~pgRule() +{ +} + +wxString pgRule::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on rule"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing rule"); + message += wxT(" ") + GetName(); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for rule"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop rule \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop rule \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop rule cascaded?"); + break; + case DROPTITLE: + message = _("Drop rule?"); + break; + case PROPERTIESREPORT: + message = _("Rule properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Rule properties"); + break; + case DDLREPORT: + message = _("Rule DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Rule DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Rule dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Rule dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Rule dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Rule dependents"); + break; + } + + return message; +} + + +int pgRule::GetIconId() +{ + if (GetEnabled()) + return ruleFactory.GetIconId(); + else + return ruleFactory.GetClosedIconId(); +} + + +bool pgRule::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP RULE ") + GetQuotedIdentifier() + wxT(" ON ") + GetQuotedFullTable(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +void pgRule::SetEnabled(ctlTree *browser, const bool b) +{ + if (GetQuotedFullTable().Len() > 0 && ((enabled && !b) || (!enabled && b))) + { + wxString sql = wxT("ALTER TABLE ") + GetQuotedFullTable() + wxT(" "); + if (enabled && !b) + sql += wxT("DISABLE"); + else if (!enabled && b) + sql += wxT("ENABLE"); + sql += wxT(" RULE ") + GetQuotedIdentifier(); + GetDatabase()->ExecuteVoid(sql); + } + + enabled = b; + UpdateIcon(browser); +} + + +wxString pgRule::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Rule: ") + GetQuotedIdentifier() + wxT(" ON ") + GetQuotedFullTable() + wxT("\n\n") + + wxT("-- DROP RULE ") + GetQuotedIdentifier() + wxT(" ON ") + GetQuotedFullTable() + wxT(";\n\n") + + wxT("CREATE OR REPLACE") + GetFormattedDefinition().Mid(6) // the backend pg_get_ruledef gives CREATE only + + wxT("\n"); + + if (!GetEnabled()) + { + sql += wxT("ALTER TABLE ") + GetQuotedFullTable() + wxT(" ") + + wxT("DISABLE RULE ") + GetQuotedIdentifier() + wxT(";\n"); + } + + if (!GetComment().IsEmpty()) + sql += wxT("COMMENT ON RULE ") + GetQuotedIdentifier() + wxT(" ON ") + GetQuotedFullTable() + + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + return sql; +} + + +void pgRule::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + wxString def = GetFormattedDefinition(); + if (!def.IsEmpty()) + { + int doPos = def.Find(wxT(" DO INSTEAD ")); + if (doPos > 0) + def = def.Mid(doPos + 12).Strip(wxString::both); + else + { + doPos = def.Find(wxT(" DO ")); + if (doPos > 0) + def = def.Mid(doPos + 4).Strip(wxString::both); + } + } + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Event"), GetEvent()); + properties->AppendItem(_("Condition"), GetCondition()); + properties->AppendYesNoItem(_("Do instead?"), GetDoInstead()); + properties->AppendItem(_("Definition"), firstLineOnly(def)); + if (this->GetDatabase()->connection()->BackendMinimumVersion(8, 3)) + properties->AppendYesNoItem(_("Enabled?"), GetEnabled()); + properties->AppendYesNoItem(_("System rule?"), GetSystemObject()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgRule::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *rule = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + rule = ruleFactory.CreateObjects(coll, 0, wxT("\n AND rw.oid=") + GetOidStr()); + + return rule; +} + + +pgObject *pgRuleFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgRule *rule = 0; + + pgSet *rules = collection->GetDatabase()->ExecuteSet( + wxT("SELECT rw.oid, rw.*, relname, CASE WHEN relkind = 'r' THEN TRUE ELSE FALSE END AS parentistable, nspname, description,\n") + wxT(" pg_get_ruledef(rw.oid") + collection->GetDatabase()->GetPrettyOption() + wxT(") AS definition\n") + wxT(" FROM pg_rewrite rw\n") + wxT(" JOIN pg_class cl ON cl.oid=rw.ev_class\n") + wxT(" JOIN pg_namespace nsp ON nsp.oid=cl.relnamespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=rw.oid AND des.classoid='pg_rewrite'::regclass)\n") + wxT(" WHERE ev_class = ") + NumToStr(collection->GetOid()) + + restriction + wxT("\n") + wxT(" ORDER BY rw.rulename")); + + if (rules) + { + while (!rules->Eof()) + { + // Be careful that the schema of a rule (and a trigger) is the schema of the schema + rule = new pgRule(collection->GetSchema()->GetSchema(), rules->GetVal(wxT("rulename"))); + + rule->iSetOid(rules->GetOid(wxT("oid"))); + rule->iSetComment(rules->GetVal(wxT("description"))); + + if (collection->GetDatabase()->connection()->BackendMinimumVersion(8, 3)) + { + if (rules->GetVal(wxT("ev_enabled")) != wxT("D")) + rule->iSetEnabled(true); + else + rule->iSetEnabled(false); + } + + rule->iSetParentIsTable(rules->GetBool(wxT("parentistable"))); + rule->iSetDoInstead(rules->GetBool(wxT("is_instead"))); + rule->iSetAction(rules->GetVal(wxT("ev_action"))); + wxString definition = rules->GetVal(wxT("definition")); + int doPos = definition.Find(wxT(" DO ")); + int wherePos = definition.Find(wxT(" WHERE ")); + if (wherePos > 0 && wherePos < doPos) + rule->iSetCondition(definition.Mid(wherePos + 7, doPos - wherePos - 7)); + + rule->iSetDefinition(definition); + rule->iSetQuotedFullTable(collection->GetDatabase()->GetQuotedSchemaPrefix(rules->GetVal(wxT("nspname"))) + + qtIdent(rules->GetVal(wxT("relname")))); + const wxChar *evts[] = {0, wxT("SELECT"), wxT("UPDATE"), wxT("INSERT"), wxT("DELETE")}; + int evno = StrToLong(rules->GetVal(wxT("ev_type"))); + if (evno > 0 && evno < 5) + rule->iSetEvent(evts[evno]); + else + rule->iSetEvent(wxT("Unknown")); + + if (browser) + { + browser->AppendObject(collection, rule); + rules->MoveNext(); + } + else + break; + } + + delete rules; + } + return rule; +} + + +///////////////////////////// + + +pgRuleCollection::pgRuleCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgRuleCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on rules"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing rules"); + break; + case OBJECTSLISTREPORT: + message = _("Rules list report"); + break; + } + + return message; +} + + +///////////////////////////// + +#include "images/rule.pngc" +#include "images/rulebad.pngc" +#include "images/rules.pngc" + +pgRuleFactory::pgRuleFactory() + : pgSchemaObjFactory(__("Rule"), __("New Rule..."), __("Create a new Rule."), rule_png_img) +{ + metaType = PGM_RULE; + closedId = addIcon(rulebad_png_img); +} + + +pgCollection *pgRuleFactory::CreateCollection(pgObject *obj) +{ + return new pgRuleCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgRuleFactory ruleFactory; +static pgaCollectionFactory cf(&ruleFactory, __("Rules"), rules_png_img); + + +enabledisableRuleFactory::enabledisableRuleFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Rule enabled?"), _("Enable or disable selected rule."), wxITEM_CHECK); +} + + +wxWindow *enabledisableRuleFactory::StartDialog(frmMain *form, pgObject *obj) +{ + ((pgRule *)obj)->SetEnabled(form->GetBrowser(), !((pgRule *)obj)->GetEnabled()); + ((pgRule *)obj)->SetDirty(); + + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + { + obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties()); + form->GetSqlPane()->SetReadOnly(false); + form->GetSqlPane()->SetText(((pgRule *)obj)->GetSql(form->GetBrowser())); + form->GetSqlPane()->SetReadOnly(true); + } + form->GetMenuFactories()->CheckMenu(obj, form->GetMenuBar(), (ctlMenuToolbar *)form->GetToolBar()); + + return 0; +} + + +bool enabledisableRuleFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(ruleFactory) + && ((pgRule *)obj)->GetConnection()->BackendMinimumVersion(8, 3) + && ((pgRule *)obj)->GetParentIsTable(); +} + +bool enabledisableRuleFactory::CheckChecked(pgObject *obj) +{ + return obj && obj->IsCreatedBy(ruleFactory) && ((pgRule *)obj)->GetEnabled(); +} diff --git a/schema/pgSchema.cpp b/schema/pgSchema.cpp new file mode 100644 index 0000000..e9033b3 --- /dev/null +++ b/schema/pgSchema.cpp @@ -0,0 +1,815 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgSchema.cpp - schema class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "frm/menu.h" +#include "utils/misc.h" +#include "schema/pgSchema.h" +#include "frm/frmMain.h" +#include "schema/pgCatalogObject.h" +#include "schema/edbPackage.h" +#include "schema/pgCollation.h" +#include "schema/pgDomain.h" +#include "schema/pgAggregate.h" +#include "schema/pgConversion.h" +#include "schema/pgForeignTable.h" +#include "schema/pgFunction.h" +#include "schema/pgOperator.h" +#include "schema/pgOperatorClass.h" +#include "schema/pgOperatorFamily.h" +#include "schema/pgSequence.h" +#include "schema/pgTable.h" +#include "schema/gpExtTable.h" +#include "schema/pgTextSearchConfiguration.h" +#include "schema/pgTextSearchDictionary.h" +#include "schema/pgTextSearchParser.h" +#include "schema/pgTextSearchTemplate.h" +#include "schema/pgType.h" +#include "schema/pgView.h" +#include "schema/gpPartition.h" +#include "schema/edbPrivateSynonym.h" +#include "frm/frmReport.h" + +#include "wx/regex.h" + +pgSchema::pgSchema(const wxString &newName) + : pgSchemaBase(schemaFactory, newName) +{ +} + +wxString pgSchema::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on schema"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing schema"); + message += wxT(" ") + GetName(); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for schema"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop schema \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop schema \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop schema cascaded?"); + break; + case DROPTITLE: + message = _("Drop schema?"); + break; + case PROPERTIESREPORT: + message = _("Schema properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Schema properties"); + break; + case DDLREPORT: + message = _("Schema DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Schema DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Schema dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Schema dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Schema dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Schema dependents"); + break; + case BACKUPTITLE: + message = wxString::Format(_("Backup schema \"%s\""), + GetFullIdentifier().c_str()); + break; + case RESTORETITLE: + message = wxString::Format(_("Restore schema \"%s\""), + GetFullIdentifier().c_str()); + break; + } + + return message; +} + +pgCatalog::pgCatalog(const wxString &newName) + : pgSchemaBase(catalogFactory, newName) +{ +} + +wxString pgCatalog::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on catalog"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing catalog"); + message += wxT(" ") + GetName(); + break; + case PROPERTIESREPORT: + message = _("Catalog properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Catalog properties"); + break; + case DDLREPORT: + message = _("Catalog DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Catalog DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Catalog dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Catalog dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Catalog dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Catalog dependents"); + break; + } + + return message; +} + +pgSchemaBase::pgSchemaBase(pgaFactory &factory, const wxString &newName) + : pgDatabaseObject(factory, newName) +{ +} + +wxString pgCatalog::GetDisplayName() +{ + if (GetFullName() == wxT("pg_catalog")) + return wxT("PostgreSQL (pg_catalog)"); + else if (GetFullName() == wxT("pgagent")) + return wxT("pgAgent (pgagent)"); + else if (GetFullName() == wxT("information_schema")) + return wxT("ANSI (information_schema)"); + else if (GetFullName().StartsWith(wxT("_"))) + return wxT("Slony cluster (") + GetFullName().AfterFirst('_') + wxT(")"); + else if (GetFullName() == wxT("dbo")) + return wxT("Redmond (dbo)"); + else if (GetFullName() == wxT("sys")) + return wxT("Redwood (sys)"); + else + return GetFullName(); +} + + +wxMenu *pgSchemaBase::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + + if (GetCreatePrivilege()) + { + if (settings->GetDisplayOption(_("Aggregates"))) + aggregateFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Collations")) && GetConnection()->BackendMinimumVersion(9, 1)) + collationFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Conversions"))) + conversionFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Domains"))) + domainFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Functions"))) + functionFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Packages"))) + { + if (GetConnection()->EdbMinimumVersion(8, 0)) + packageFactory.AppendMenu(menu); + } + if (settings->GetDisplayOption(_("Procedures"))) + { + if (GetConnection()->BackendMinimumVersion(11, 0)) + procedureFactory.AppendMenu(menu); + } + if (settings->GetDisplayOption(_("Operators"))) + operatorFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Sequences"))) + sequenceFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Tables"))) + tableFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("FTS Configurations"))) + { + if (GetConnection()->BackendMinimumVersion(8, 3)) + textSearchConfigurationFactory.AppendMenu(menu); + } + if (settings->GetDisplayOption(_("FTS Dictionaries"))) + { + if (GetConnection()->BackendMinimumVersion(8, 3)) + textSearchDictionaryFactory.AppendMenu(menu); + } + if (settings->GetDisplayOption(_("FTS Parsers"))) + { + if (GetConnection()->BackendMinimumVersion(8, 3)) + textSearchParserFactory.AppendMenu(menu); + } + if (settings->GetDisplayOption(_("FTS Templates"))) + { + if (GetConnection()->BackendMinimumVersion(8, 3)) + textSearchTemplateFactory.AppendMenu(menu); + } + if (settings->GetDisplayOption(_("Foreign Tables"))) + { + if (GetConnection()->BackendMinimumVersion(9, 1)) + foreignTableFactory.AppendMenu(menu); + } + if (settings->GetDisplayOption(_("Trigger Functions"))) + triggerFunctionFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Types"))) + typeFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Views"))) + viewFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("External Tables"))) + { + if (GetConnection() != 0 && GetConnection()->GetIsGreenplum()) + extTableFactory.AppendMenu(menu); + } + if (settings->GetDisplayOption(_("Synonyms")) && GetConnection()->EdbMinimumVersion(8, 4)) + edbPrivFactory.AppendMenu(menu); + } + return menu; +} + +bool pgSchemaBase::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP SCHEMA ") + GetQuotedFullIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgSchemaBase::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + wxString strName = qtIdent(GetName()); + if (GetMetaType() == PGM_CATALOG) + sql = wxT("-- Catalog: ") + GetName() + wxT("\n\n"); + else + sql = wxT("-- Schema: ") + GetName() + wxT("\n\n"); + + sql += wxT("-- DROP SCHEMA ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE SCHEMA ") + strName + + wxT("\n AUTHORIZATION ") + qtIdent(GetOwner()); + sql += wxT(";\n\n"); + + sql += GetGrant(wxT("UC"), wxT("SCHEMA ") + GetQuotedFullIdentifier()) + + GetCommentSql(); + + sql += wxT("\n") + pgDatabase::GetDefaultPrivileges('r', m_defPrivsOnTables, strName); + sql += pgDatabase::GetDefaultPrivileges('S', m_defPrivsOnSeqs, strName); + sql += pgDatabase::GetDefaultPrivileges('f', m_defPrivsOnFuncs, strName); + if (GetConnection()->BackendMinimumVersion(9, 2)) + sql += pgDatabase::GetDefaultPrivileges('T', m_defPrivsOnTypes, strName); + + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += GetSeqLabelsSql(); + } + return sql; +} + + +void pgSchemaBase::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + + GetDatabase()->GetServer()->iSetLastDatabase(GetDatabase()->GetName()); + GetDatabase()->GetServer()->iSetLastSchema(GetName()); + + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + + // Log + wxLogInfo(wxT("Adding child object to schema %s"), GetIdentifier().c_str()); + + if (!(GetMetaType() == PGM_CATALOG && (GetFullName() == wxT("dbo") || GetFullName() == wxT("sys") || GetFullName() == wxT("information_schema")))) + { + if (settings->GetDisplayOption(_("Aggregates"))) + browser->AppendCollection(this, aggregateFactory); + if (settings->GetDisplayOption(_("Collations")) && GetConnection()->BackendMinimumVersion(9, 1)) + browser->AppendCollection(this, collationFactory); + if (settings->GetDisplayOption(_("Conversions"))) + browser->AppendCollection(this, conversionFactory); + if (settings->GetDisplayOption(_("Domains"))) + browser->AppendCollection(this, domainFactory); + if (settings->GetDisplayOption(_("Foreign Tables")) && GetConnection()->BackendMinimumVersion(9, 1)) + browser->AppendCollection(this, foreignTableFactory); + if (settings->GetDisplayOption(_("FTS Configurations"))) + { + if (GetConnection()->BackendMinimumVersion(8, 3)) + browser->AppendCollection(this, textSearchConfigurationFactory); + } + if (settings->GetDisplayOption(_("FTS Dictionaries"))) + { + if (GetConnection()->BackendMinimumVersion(8, 3)) + browser->AppendCollection(this, textSearchDictionaryFactory); + } + if (settings->GetDisplayOption(_("FTS Parsers"))) + { + if (GetConnection()->BackendMinimumVersion(8, 3)) + browser->AppendCollection(this, textSearchParserFactory); + } + if (settings->GetDisplayOption(_("FTS Templates"))) + { + if (GetConnection()->BackendMinimumVersion(8, 3)) + browser->AppendCollection(this, textSearchTemplateFactory); + } + if (settings->GetDisplayOption(_("Functions"))) + browser->AppendCollection(this, functionFactory); + + if (settings->GetDisplayOption(_("Operators"))) + browser->AppendCollection(this, operatorFactory); + if (settings->GetDisplayOption(_("Operator Classes"))) + browser->AppendCollection(this, operatorClassFactory); + + if (settings->GetDisplayOption(_("Operator Families"))) + { + if (GetConnection()->BackendMinimumVersion(8, 3)) + browser->AppendCollection(this, operatorFamilyFactory); + } + + if (settings->GetDisplayOption(_("Packages")) && GetConnection()->EdbMinimumVersion(8, 1)) + browser->AppendCollection(this, packageFactory); + + if (settings->GetDisplayOption(_("Procedures"))) + { + if (GetConnection()->BackendMinimumVersion(11, 0)) + browser->AppendCollection(this, procedureFactory); + } + + if (settings->GetDisplayOption(_("Sequences"))) + browser->AppendCollection(this, sequenceFactory); + if (settings->GetDisplayOption(_("Tables"))) + browser->AppendCollection(this, tableFactory); + if (settings->GetDisplayOption(_("External Tables"))) + { + if (GetConnection() != 0 && GetConnection()->GetIsGreenplum()) + browser->AppendCollection(this, extTableFactory); + } + if (settings->GetDisplayOption(_("Trigger Functions"))) + browser->AppendCollection(this, triggerFunctionFactory); + if (settings->GetDisplayOption(_("Types"))) + browser->AppendCollection(this, typeFactory); + if (settings->GetDisplayOption(_("Views"))) + browser->AppendCollection(this, viewFactory); + if (settings->GetDisplayOption(_("Synonyms")) && GetConnection()->EdbMinimumVersion(8, 4)) + browser->AppendCollection(this, edbPrivFactory); + } + else + browser->AppendCollection(this, catalogObjectFactory); + + if (GetConnection()->BackendMinimumVersion(9, 0)) + { + m_defPrivsOnTables = GetConnection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = ") + GetOidStr() + wxT(" AND defaclobjtype='r'")); + m_defPrivsOnSeqs = GetConnection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = ") + GetOidStr() + wxT(" AND defaclobjtype='S'")); + m_defPrivsOnFuncs = GetConnection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = ") + GetOidStr() + wxT(" AND defaclobjtype='f'")); + } + if (GetConnection()->BackendMinimumVersion(9, 2)) + { + m_defPrivsOnTypes = GetConnection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = ") + GetOidStr() + wxT(" AND defaclobjtype='T'")); + } + } + + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("ACL"), GetAcl()); + if (GetConnection()->BackendMinimumVersion(9, 0)) + { + properties->AppendItem(_("Default table ACL"), m_defPrivsOnTables); + properties->AppendItem(_("Default sequence ACL"), m_defPrivsOnSeqs); + properties->AppendItem(_("Default function ACL"), m_defPrivsOnFuncs); + } + if (GetConnection()->BackendMinimumVersion(9, 2)) + properties->AppendItem(_("Default type ACL"), m_defPrivsOnTypes); + + if (GetMetaType() != PGM_CATALOG) + properties->AppendYesNoItem(_("System schema?"), GetSystemObject()); + + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + if (!GetLabels().IsEmpty()) + { + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); + } + } + } + } +} + + + +pgObject *pgSchemaBase::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *schema = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + { + if (coll->IsCollectionForType(PGM_CATALOG)) + schema = catalogFactory.CreateObjects(coll, 0, wxT(" WHERE nsp.oid=") + GetOidStr() + wxT("\n")); + else + schema = schemaFactory.CreateObjects(coll, 0, wxT(" WHERE nsp.oid=") + GetOidStr() + wxT("\n")); + } + + return schema; +} + + + +pgObject *pgSchemaBaseFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgSchema *schema = 0; + pgCatalog *catalog = 0; + + wxString restr = restriction; + + if (restr.IsEmpty()) + restr += wxT(" WHERE "); + else + restr += wxT(" AND "); + + if (GetMetaType() != PGM_CATALOG) + { + restr += wxT("NOT "); + } + + restr += wxT("((nspname = 'pg_catalog' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'pg_class' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname = 'pgagent' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'pga_job' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname = 'information_schema' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'tables' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname LIKE '_%' AND EXISTS (SELECT 1 FROM pg_proc WHERE proname='slonyversion' AND pronamespace = nsp.oid LIMIT 1))\n"); + + // We add the below schemas at initdb time itself. So users cannot create + // schemas of the same name later. However if DB is started in PostgreSQL + // mode, we do not install all other edb-sys.sql objects. So just checking + // for presence of schemas with such names should be enough.. + if (collection->GetConnection()->EdbMinimumVersion(8, 1)) + restr += wxT("OR (nspname = 'dbo' OR nspname = 'sys'))\n"); + else + restr += wxT(")"); + + if (collection->GetConnection()->EdbMinimumVersion(8, 2)) + { + restr += wxT(" AND nsp.nspparent = 0\n"); + // Do not show dbms_job_procedure in schemas + if (!settings->GetShowSystemObjects()) + restr += wxT("AND NOT (nspname = 'dbms_job_procedure' AND EXISTS(SELECT 1 FROM pg_proc WHERE pronamespace = nsp.oid and proname = 'run_job' LIMIT 1))\n"); + } + + if (!collection->GetDatabase()->GetSchemaRestriction().IsEmpty()) + restr += wxT(" AND nspname IN (") + collection->GetDatabase()->GetSchemaRestriction() + wxT(")"); + + // Don't fetch temp schemas if not actually required, as Greenplum seems to + // generate thousands in some circumstances. + if (!settings->GetShowSystemObjects()) + { + if (collection->GetDatabase()->BackendMinimumVersion(8, 1)) + restr += wxT(" AND nspname NOT LIKE E'pg\\\\_temp\\\\_%'AND nspname NOT LIKE E'pg\\\\_toast_temp\\\\_%'"); + else + restr += wxT(" AND nspname NOT LIKE 'pg\\\\_temp\\\\_%'AND nspname NOT LIKE 'pg\\\\_toast_temp\\\\_%'"); + } + + wxString sql; + + if (GetMetaType() == PGM_CATALOG) + { + sql = wxT("SELECT 2 AS nsptyp,\n") + wxT(" nsp.nspname, nsp.oid, pg_get_userbyid(nspowner) AS namespaceowner, nspacl, description,") + wxT(" FALSE as cancreate\n") + wxT(" FROM pg_namespace nsp\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=nsp.oid AND des.classoid='pg_namespace'::regclass)\n") + + restr + + wxT(" ORDER BY 1, nspname"); + } + else + { + if (collection->GetDatabase()->BackendMinimumVersion(8, 1)) + { + sql = wxT("SELECT CASE WHEN nspname LIKE E'pg\\\\_temp\\\\_%' THEN 1\n") + wxT(" WHEN (nspname LIKE E'pg\\\\_%') THEN 0\n"); + } + else + { + sql = wxT("SELECT CASE WHEN nspname LIKE 'pg\\\\_temp\\\\_%' THEN 1\n") + wxT(" WHEN (nspname LIKE 'pg\\\\_%') THEN 0\n"); + } + sql += wxT(" ELSE 3 END AS nsptyp,\n") + wxT(" nsp.nspname, nsp.oid, pg_get_userbyid(nspowner) AS namespaceowner, nspacl, description,") + wxT(" has_schema_privilege(nsp.oid, 'CREATE') as cancreate"); + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + sql += wxT(",\n(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=nsp.oid) AS labels"); + sql += wxT(",\n(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=nsp.oid) AS providers"); + } + sql += wxT("\n FROM pg_namespace nsp\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=nsp.oid AND des.classoid='pg_namespace'::regclass)\n") + + restr + + wxT(" ORDER BY 1, nspname"); + } + + pgSet *schemas = collection->GetDatabase()->ExecuteSet(sql); + + if (schemas) + { + while (!schemas->Eof()) + { + wxString name = schemas->GetVal(wxT("nspname")); + long nsptyp = schemas->GetLong(wxT("nsptyp")); + + wxStringTokenizer tokens(settings->GetSystemSchemas(), wxT(",")); + while (tokens.HasMoreTokens()) + { + wxRegEx regex(tokens.GetNextToken()); + if (regex.Matches(name)) + { + nsptyp = SCHEMATYP_USERSYS; + break; + } + } + + if (nsptyp <= SCHEMATYP_USERSYS && this->GetMetaType() != PGM_CATALOG && !settings->GetShowSystemObjects()) + { + schemas->MoveNext(); + continue; + } + + if (GetMetaType() == PGM_CATALOG) + { + catalog = new pgCatalog(name); + + catalog->iSetSchemaTyp(nsptyp); + catalog->iSetDatabase(collection->GetDatabase()); + catalog->iSetComment(schemas->GetVal(wxT("description"))); + catalog->iSetOid(schemas->GetOid(wxT("oid"))); + catalog->iSetOwner(schemas->GetVal(wxT("namespaceowner"))); + catalog->iSetAcl(schemas->GetVal(wxT("nspacl"))); + catalog->iSetCreatePrivilege(false); + + if (collection->GetDatabase()->BackendMinimumVersion(9, 0)) + { + catalog->iSetDefPrivsOnTables(collection->GetConnection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = " + catalog->GetOidStr() + wxT(" AND defaclobjtype='r'")))); + catalog->iSetDefPrivsOnSeqs(collection->GetConnection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = " + catalog->GetOidStr() + wxT(" AND defaclobjtype='S'")))); + catalog->iSetDefPrivsOnFuncs(collection->GetConnection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = " + catalog->GetOidStr() + wxT(" AND defaclobjtype='f'")))); + } + if (collection->GetDatabase()->BackendMinimumVersion(9, 2)) + { + catalog->iSetDefPrivsOnTypes(collection->GetConnection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = " + catalog->GetOidStr() + wxT(" AND defaclobjtype='T'")))); + } + + if (browser) + { + browser->AppendObject(collection, catalog); + schemas->MoveNext(); + } + else + break; + } + else + { + schema = new pgSchema(name); + + schema->iSetSchemaTyp(nsptyp); + schema->iSetDatabase(collection->GetDatabase()); + schema->iSetComment(schemas->GetVal(wxT("description"))); + schema->iSetOid(schemas->GetOid(wxT("oid"))); + schema->iSetOwner(schemas->GetVal(wxT("namespaceowner"))); + schema->iSetAcl(schemas->GetVal(wxT("nspacl"))); + schema->iSetCreatePrivilege(schemas->GetBool(wxT("cancreate"))); + + if (collection->GetDatabase()->BackendMinimumVersion(9, 0)) + { + schema->iSetDefPrivsOnTables(collection->GetConnection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = " + schema->GetOidStr() + wxT(" AND defaclobjtype='r'")))); + schema->iSetDefPrivsOnSeqs(collection->GetConnection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = " + schema->GetOidStr() + wxT(" AND defaclobjtype='S'")))); + schema->iSetDefPrivsOnFuncs(collection->GetConnection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = " + schema->GetOidStr() + wxT(" AND defaclobjtype='f'")))); + } + if (collection->GetDatabase()->BackendMinimumVersion(9, 2)) + { + schema->iSetDefPrivsOnTypes(collection->GetConnection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = " + schema->GetOidStr() + wxT(" AND defaclobjtype='T'")))); + } + + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + schema->iSetProviders(schemas->GetVal(wxT("providers"))); + schema->iSetLabels(schemas->GetVal(wxT("labels"))); + } + + if (browser) + { + browser->AppendObject(collection, schema); + schemas->MoveNext(); + } + else + break; + } + } + + delete schemas; + } + + if (GetMetaType() == PGM_CATALOG) + return catalog; + else + return schema; +} + + +pgObject *pgSchemaBase::ReadObjects(pgCollection *collection, ctlTree *browser) +{ + wxString systemRestriction; + if (!settings->GetShowSystemObjects()) + systemRestriction = wxT("WHERE ") + collection->GetConnection()->SystemNamespaceRestriction(wxT("nsp.nspname")); + + // Get the schemas + return schemaFactory.CreateObjects(collection, browser, systemRestriction); +} + + +///////////////////////////////////////////////////// + +pgSchemaObjCollection::pgSchemaObjCollection(pgaFactory *factory, pgSchema *sch) + : pgCollection(factory) +{ + schema = sch; + database = schema->GetDatabase(); + server = database->GetServer(); + iSetOid(sch->GetOid()); +} + +bool pgSchemaObjCollection::CanCreate() +{ + if(IsCollectionForType(PGM_OPCLASS) || IsCollectionForType(PGM_OPFAMILY)) + return false; + + // TODO + // OK, this is a hack. Rules and Views are both derived from pgRuleObject, which + // is derived from pgSchemaObject. In order that they attach to the treeview + // under the relevant node however, the Schema object is actually the table or + // View (yeah, I know - I didn't write it :-p ). This works fine *except* for + // Get CreatePrivilege() which doesn't exist in these classes so must be fixed + // up at this level. This needs a major rethink in the longer term + if (GetSchema()->GetMetaType() == PGM_TABLE || GetSchema()->GetMetaType() == PGM_VIEW || GetSchema()->GetMetaType() == GP_EXTTABLE || GetSchema()->GetMetaType() == GP_PARTITION) + return GetSchema()->GetSchema()->GetCreatePrivilege(); + else + return GetSchema()->GetCreatePrivilege(); +} + + +///////////////////////////// + +pgSchemaCollection::pgSchemaCollection(pgaFactory *factory, pgDatabase *db) + : pgDatabaseObjCollection(factory, db) +{ +} + + +wxString pgSchemaCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on schemas"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing schemas"); + break; + case OBJECTSLISTREPORT: + message = _("Schemas list report"); + break; + } + + return message; +} + +///////////////////////////// + +pgCatalogCollection::pgCatalogCollection(pgaFactory *factory, pgDatabase *db) + : pgDatabaseObjCollection(factory, db) +{ +} + + +wxString pgCatalogCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on catalogs"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing catalogs"); + break; + case OBJECTSLISTREPORT: + message = _("Catalogs list report"); + break; + } + + return message; +} + +///////////////////////////////////////////////////// + + +#include "images/namespace.pngc" +#include "images/namespace-sm.pngc" +#include "images/namespaces.pngc" +#include "images/catalog.pngc" +#include "images/catalog-sm.pngc" +#include "images/catalogs.pngc" + +pgSchemaBaseFactory::pgSchemaBaseFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm) + : pgDatabaseObjFactory(tn, ns, nls, img, imgSm) +{ + +} + +pgSchemaFactory::pgSchemaFactory() + : pgSchemaBaseFactory(__("Schema"), __("New Schema..."), __("Create a new Schema."), namespace_png_img, namespace_sm_png_img) +{ + metaType = PGM_SCHEMA; +} + +pgCollection *pgSchemaFactory::CreateCollection(pgObject *obj) +{ + return new pgSchemaCollection(GetCollectionFactory(), (pgDatabase *)obj); +} + +pgCatalogFactory::pgCatalogFactory() + : pgSchemaBaseFactory(__("Catalog"), __("New Catalog..."), __("Create a new Catalog."), catalog_png_img, catalog_sm_png_img) +{ + metaType = PGM_CATALOG; +} + +pgCollection *pgCatalogFactory::CreateCollection(pgObject *obj) +{ + return new pgCatalogCollection(GetCollectionFactory(), (pgDatabase *)obj); +} + +pgCollection *pgSchemaObjFactory::CreateCollection(pgObject *obj) +{ + return new pgSchemaObjCollection(GetCollectionFactory(), (pgSchema *)obj); +} + + +pgSchemaFactory schemaFactory; +static pgaCollectionFactory scf(&schemaFactory, __("Schemas"), namespaces_png_img); + +pgCatalogFactory catalogFactory; +static pgaCollectionFactory ccf(&catalogFactory, __("Catalogs"), catalogs_png_img); diff --git a/schema/pgSequence.cpp b/schema/pgSequence.cpp new file mode 100644 index 0000000..d62e83b --- /dev/null +++ b/schema/pgSequence.cpp @@ -0,0 +1,369 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgSequence.cpp - Sequence class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgSequence.h" + + +pgSequence::pgSequence(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, sequenceFactory, newName) +{ + isReplicated = false; +} + +pgSequence::~pgSequence() +{ +} + +wxString pgSequence::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on sequence"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing sequence"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop sequence \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop sequence \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop sequence cascaded?"); + break; + case DROPTITLE: + message = _("Drop sequence?"); + break; + case PROPERTIESREPORT: + message = _("Sequence properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Sequence properties"); + break; + case DDLREPORT: + message = _("Sequence DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Sequence DDL"); + break; + case STATISTICSREPORT: + message = _("Sequence statistics report"); + message += wxT(" - ") + GetName(); + break; + case OBJSTATISTICS: + message = _("Sequence statistics"); + break; + case DEPENDENCIESREPORT: + message = _("Sequence dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Sequence dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Sequence dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Sequence dependents"); + break; + } + + return message; +} + + +int pgSequence::GetIconId() +{ + if (isReplicated) + return sequenceFactory.GetReplicatedIconId(); + else + return sequenceFactory.GetIconId(); +} + +bool pgSequence::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP SEQUENCE ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +void pgSequence::UpdateValues() +{ + wxString lsql; + wxString tabname = schema->GetQuotedPrefix() + qtIdent(GetName()); + if (GetConnection()->BackendMinimumVersion(10, 0)) + { + + lsql=wxT("SELECT pg_catalog.format_type(seqtypid, NULL) AS \"Type\",\n") + wxT(" seqstart AS \"start\",\n") + wxT(" seqmin AS \"min_value\",\n") + wxT(" seqmax AS \"max_value\",\n") + wxT(" seqincrement AS \"increment_by\",\n") + wxT(" CASE WHEN seqcycle THEN 'yes' ELSE 'no' END AS \"is_cycled\",\n") + wxT(" seqcache AS \"cache_value\",\n") + wxT(" last_value, is_called") + wxT(" FROM pg_catalog.pg_sequence,")+GetQuotedFullIdentifier()+wxT(" s") + wxT(" WHERE seqrelid = ")+GetOidStr()+wxT(""); + + } else + { + lsql=wxT("SELECT last_value, min_value, max_value, cache_value, is_cycled, increment_by, is_called\n") + wxT(" FROM ") + GetQuotedFullIdentifier(); + + } + pgSet *sequence = ExecuteSet(lsql); + + if (sequence) + { + lastValue = sequence->GetLongLong(wxT("last_value")); + minValue = sequence->GetLongLong(wxT("min_value")); + maxValue = sequence->GetLongLong(wxT("max_value")); + cacheValue = sequence->GetLongLong(wxT("cache_value")); + increment = sequence->GetLongLong(wxT("increment_by")); + cycled = sequence->GetBool(wxT("is_cycled")); + called = sequence->GetBool(wxT("is_called")); + if (called) + nextValue = lastValue + increment; + else + nextValue = lastValue; + + delete sequence; + } +} + + +wxString pgSequence::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + UpdateValues(); + sql = wxT("-- Sequence: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP SEQUENCE ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE SEQUENCE ") + GetQuotedFullIdentifier() + + wxT("\n INCREMENT ") + GetIncrement().ToString() + + wxT("\n MINVALUE ") + GetMinValue().ToString() + + wxT("\n MAXVALUE ") + GetMaxValue().ToString() + + wxT("\n START ") + GetLastValue().ToString() + + wxT("\n CACHE ") + GetCacheValue().ToString(); + if (GetCycled()) + sql += wxT("\n CYCLE"); + sql += wxT(";\n") + + GetOwnerSql(7, 3, wxT("TABLE ") + GetQuotedFullIdentifier()); + + if (!GetConnection()->BackendMinimumVersion(8, 2)) + sql += GetGrant(wxT("arwdRxt"), wxT("TABLE ") + GetQuotedFullIdentifier()); + else + sql += GetGrant(wxT("rwU"), wxT("SEQUENCE ") + GetQuotedFullIdentifier()); + + sql += GetCommentSql(); + + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += GetSeqLabelsSql(); + } + + return sql; +} + +void pgSequence::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + UpdateValues(); + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("ACL"), GetAcl()); + properties->AppendItem(_("Current value"), GetLastValue()); + properties->AppendItem(_("Next value"), GetNextValue()); + properties->AppendItem(_("Minimum"), GetMinValue()); + properties->AppendItem(_("Maximum"), GetMaxValue()); + properties->AppendItem(_("Increment"), GetIncrement()); + properties->AppendItem(_("Cache"), GetCacheValue()); + properties->AppendYesNoItem(_("Cycled?"), GetCycled()); + properties->AppendYesNoItem(_("Called?"), GetCalled()); + properties->AppendYesNoItem(_("System sequence?"), GetSystemObject()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + if (!GetLabels().IsEmpty()) + { + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); + } + } + } + } +} + + + +void pgSequence::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + wxLogInfo(wxT("Displaying statistics for sequence on ") + GetSchema()->GetIdentifier()); + + // Add the statistics view columns + CreateListColumns(statistics, _("Statistic"), _("Value")); + + pgSet *stats = GetSchema()->GetDatabase()->ExecuteSet(wxT( + "SELECT blks_read, blks_hit FROM pg_statio_all_sequences WHERE relid = ") + GetOidStr()); + + if (stats) + { + statistics->InsertItem(0, _("Blocks Read"), PGICON_STATISTICS); + statistics->SetItem(0l, 1, stats->GetVal(wxT("blks_read"))); + statistics->InsertItem(1, _("Blocks Hit"), PGICON_STATISTICS); + statistics->SetItem(1, 1, stats->GetVal(wxT("blks_hit"))); + + delete stats; + } +} + + +pgObject *pgSequence::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *sequence = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + sequence = sequenceFactory.CreateObjects(coll, 0, wxT("\n AND cl.oid=") + GetOidStr()); + + return sequence; +} + + +/////////////////////////////////////////////////// + + +pgSequenceCollection::pgSequenceCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgSequenceCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on sequences"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing sequences"); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for sequences"); + break; + case OBJECTSLISTREPORT: + message = _("Sequences list report"); + break; + } + + return message; +} + + +/////////////////////////////////////////////////////////////////////////////// + + +pgObject *pgSequenceFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgSet *sequences; + pgSequence *sequence = 0; + wxString sql; + + sql = wxT("SELECT cl.oid, relname, pg_get_userbyid(relowner) AS seqowner, relacl, description"); + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + sql += wxT(",\n(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=cl.oid) AS labels"); + sql += wxT(",\n(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=cl.oid) AS providers"); + } + sql += wxT("\n FROM pg_class cl\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=cl.oid AND des.classoid='pg_class'::regclass)\n") + wxT(" WHERE relkind = 'S' AND relnamespace = ") + collection->GetSchema()->GetOidStr() + + restriction + wxT("\n") + wxT(" ORDER BY relname"); + + sequences = collection->GetDatabase()->ExecuteSet(sql); + + if (sequences) + { + while (!sequences->Eof()) + { + sequence = new pgSequence(collection->GetSchema(), + sequences->GetVal(wxT("relname"))); + + sequence->iSetOid(sequences->GetOid(wxT("oid"))); + sequence->iSetComment(sequences->GetVal(wxT("description"))); + sequence->iSetOwner(sequences->GetVal(wxT("seqowner"))); + sequence->iSetAcl(sequences->GetVal(wxT("relacl"))); + + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + sequence->iSetProviders(sequences->GetVal(wxT("providers"))); + sequence->iSetLabels(sequences->GetVal(wxT("labels"))); + } + + if (browser) + { + browser->AppendObject(collection, sequence); + sequences->MoveNext(); + } + else + break; + } + delete sequences; + } + return sequence; +} + + +#include "images/sequence.pngc" +#include "images/sequences.pngc" + +pgSequenceFactory::pgSequenceFactory() + : pgSchemaObjFactory(__("Sequence"), __("New Sequence..."), __("Create a new Sequence."), sequence_png_img) +{ + metaType = PGM_SEQUENCE; +} + + +pgCollection *pgSequenceFactory::CreateCollection(pgObject *obj) +{ + return new pgSequenceCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgSequenceFactory sequenceFactory; +static pgaCollectionFactory cf(&sequenceFactory, __("Sequences"), sequences_png_img); diff --git a/schema/pgServer.cpp b/schema/pgServer.cpp new file mode 100644 index 0000000..217f4fc --- /dev/null +++ b/schema/pgServer.cpp @@ -0,0 +1,2271 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgServer.cpp - PostgreSQL Server +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include +#include + +// App headers +#include "ctl/ctlMenuToolbar.h" +#include "frm/menu.h" +#include "utils/misc.h" +#include "frm/frmMain.h" +#include "frm/frmHint.h" +#include "dlg/dlgConnect.h" +#include "schema/pgDatabase.h" +#include "schema/pgTablespace.h" +#include "schema/pgGroup.h" +#include "schema/pgUser.h" +#include "schema/pgRole.h" +#include "schema/gpResQueue.h" +#include "agent/pgaJob.h" +#include "utils/utffile.h" +#include "utils/pgfeatures.h" +#include "utils/registry.h" +#include "frm/frmReport.h" +#include "dlg/dlgServer.h" +#include "schema/edbResourceGroup.h" + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) +#include "utils/sshTunnel.h" +#endif + +#define DEFAULT_PG_DATABASE wxT("postgres") + +pgServer::pgServer(const wxString &newName, const wxString &newHostAddr, const wxString &newDescription, const wxString &newService, + const wxString &newDatabase, const wxString &newUsername, int newPort, bool _storePwd, const wxString &newRolename, bool _restore, + int _ssl, const wxString &_colour, const wxString &_group, bool _sshTunnel, const wxString &newTunnelHost, const wxString &newTunnelUserName, + bool _authModePwd, const wxString &newTunnelPassword, const wxString &newPublicKey, const wxString &newIdentity, const int &sshPort) + : pgObject(serverFactory, newName) +{ + description = newDescription; + hostaddr = newHostAddr; + service = newService; + database = newDatabase; + username = newUsername; + port = newPort; + ssl = _ssl; + colour = _colour; + group = _group; + + serverIndex = 0; + + connected = false; + lastSystemOID = 0; + + conn = NULL; + passwordValid = true; + storePwd = _storePwd; + rolename = newRolename; + restore = _restore; + superUser = false; + createPrivilege = false; + sshTunnel = _sshTunnel; + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + // SSH Tunnel + tunnelObj = NULL; + tunnelHost = newTunnelHost; + tunnelUserName = newTunnelUserName; + authModePwd = _authModePwd; + tunnelPassword = newTunnelPassword; + publicKeyFile = newPublicKey; + identityFile = newIdentity; + tunnelPort = sshPort; +#endif + +#ifdef WIN32 + scmHandle = 0; + serviceHandle = 0; +#endif +} + +pgServer::~pgServer() +{ + if (conn) + delete conn; + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + if(tunnelObj) + { + if(tunnelObj->IsAlive()) + { + tunnelObj->Cleanup(); + } + tunnelObj = NULL; + } +#endif + +#ifdef WIN32 + if (serviceHandle) + CloseServiceHandle(serviceHandle); + if (scmHandle) + CloseServiceHandle(scmHandle); +#endif +} + + +wxString pgServer::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on server"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing server"); + message += wxT(" ") + GetName(); + break; + case BACKUPGLOBALS: + message = _("Backup globals of server"); + message += wxT(" ") + GetName(); + break; + case BACKUPSERVERTITLE: + message = _("Backup server"); + message += wxT(" ") + GetName(); + break; + case DROPTITLE: + message = _("Drop server?"); + break; + case PROPERTIESREPORT: + message = _("Server properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Server properties"); + break; + case STATISTICSREPORT: + message = _("Server statistics report"); + message += wxT(" - ") + GetName(); + break; + case OBJSTATISTICS: + message = _("Server statistics"); + break; + } + + return message; +} + + +int pgServer::GetIconId() +{ + if (GetConnected()) + return serverFactory.GetIconId(); + else + return serverFactory.GetClosedIconId(); +} + + +wxMenu *pgServer::GetNewMenu() +{ + wxMenu *menu = 0; + if (connected && (GetSuperUser() || GetCreateRole())) + { + menu = new wxMenu(); + if (settings->GetDisplayOption(_("Tablespaces"))) + tablespaceFactory.AppendMenu(menu); + if (GetConnection()->BackendMinimumVersion(8, 1)) + { + if (settings->GetDisplayOption(_("Groups/group Roles"))) + groupRoleFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Users/login Roles"))) + loginRoleFactory.AppendMenu(menu); + if (GetConnection()->GetIsGreenplum()) + { + if (settings->GetDisplayOption(_("Resource Queues"))) + resQueueFactory.AppendMenu(menu); + } + } + else + { + if (settings->GetDisplayOption(_("Groups/group Roles"))) + groupFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Users/login Roles"))) + userFactory.AppendMenu(menu); + } + // Added Resource Group only for PPAS 9.4 and above + if (conn->GetIsEdb() && conn->EdbMinimumVersion(9, 4)) + { + if (settings->GetDisplayOption(_("Resource Groups"))) + resourceGroupFactory.AppendMenu(menu); + } + } + return menu; +} + +pgServer *pgServer::GetServer() const +{ + if (connected) + return (pgServer *)this; + return 0; +} + + +pgConn *pgServer::CreateConn(wxString dbName, OID oid, wxString applicationname) +{ + if (!connected) + return 0; + + if (dbName.IsEmpty()) + { + dbName = GetDatabaseName(); + oid = dbOid; + } + + pgConn *conn = NULL; +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + if(sshTunnel) + { + conn = new pgConn(local_listenhost, service, hostaddr, dbName, username, password, local_listenport, rolename, ssl, oid, applicationname, sslcert, sslkey, sslrootcert, sslcrl, sslcompression); + } + else +#endif + { + conn = new pgConn(GetName(), service, hostaddr, dbName, username, password, port, rolename, ssl, oid, applicationname, sslcert, sslkey, sslrootcert, sslcrl, sslcompression); + } + + if (conn && conn->GetStatus() != PGCONN_OK) + { + wxLogError(wxT("%s"), conn->GetLastError().c_str()); + delete conn; + return 0; + } + return conn; +} + + +wxString pgServer::GetFullName() +{ + if (GetDescription().Length() > 0) + return GetDescription() + wxT(" (") + GetIdentifier() + wxT(")"); + else + return wxT("(") + GetIdentifier() + wxT(")"); +} + +wxString pgServer::GetFullIdentifier() +{ + return GetFullName(); +} + +bool pgServer::Disconnect(frmMain *form) +{ +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + if(tunnelObj) + { + if(tunnelObj->IsAlive()) + { + tunnelObj->Cleanup(); + } + tunnelObj = NULL; + } +#endif + + if (conn) + { + delete conn; + conn = 0; + connected = false; + expandedKids = false; + ver = wxT(""); + versionNum = wxT(""); + lastSystemOID = 0; + } + + if (form) + UpdateIcon(form->GetBrowser()); + + return true; +} + + +bool pgServer::GetCanHint() +{ + return connected && conn->BackendMinimumVersion(8, 1) && !autovacuumRunning; +} + + +void pgServer::ShowHint(frmMain *form, bool force) +{ + wxArrayString hints; + + if (!autovacuumRunning) + hints.Add(HINT_AUTOVACUUM); + + if (force || !hintShown) + frmHint::ShowHint(form, hints, GetFullIdentifier(), force); + hintShown = true; +} + + +#define SERVICEBUFSIZE 10000 +#define QUERYBUFSIZE 256 + +#ifdef WIN32 +wxArrayString pgServer::GetDependentServices(SC_HANDLE handle) +{ + wxArrayString services; + LPENUM_SERVICE_STATUS sbuf = (LPENUM_SERVICE_STATUS) new char[SERVICEBUFSIZE]; + + DWORD servicesReturned = 0, bytesNeeded; + ::EnumDependentServices(handle, SERVICE_STATE_ALL, sbuf, SERVICEBUFSIZE, &bytesNeeded, &servicesReturned); + + + DWORD i; + for (i = 0 ; i < servicesReturned ; i++) + { + SC_HANDLE h =::OpenService(scmHandle, sbuf[i].lpServiceName, SERVICE_QUERY_CONFIG); + if (h) + { + char buffer[QUERYBUFSIZE]; + LPQUERY_SERVICE_CONFIG qsc = (LPQUERY_SERVICE_CONFIG)buffer; + if(::QueryServiceConfig(h, qsc, QUERYBUFSIZE, &bytesNeeded)) + { + if (qsc->dwStartType != SERVICE_DISABLED) + services.Add(sbuf[i].lpServiceName); + } + + ::CloseServiceHandle(h); + } + } + delete[] sbuf; + + return services; +} +#endif + + +bool pgServer::StartService() +{ + bool done = false; +#ifdef WIN32 + if (serviceHandle) + { + done = (::StartService(serviceHandle, 0, 0) != 0); + if (!done) + { + DWORD rc = ::GetLastError(); + if (rc == ERROR_SERVICE_ALREADY_RUNNING) + { + GetServerRunning(); + return true; + } + // report error + wxLogError(__("Failed to start server %s: Errcode=%d\nCheck event log for details."), + serviceId.c_str(), rc); + } + else + { + GetServerRunning(); // ignore result, just to wait for startup + + wxArrayString services = GetDependentServices(serviceHandle); + + if (services.GetCount() > 0) + { + size_t i; + wxString serviceString; + for (i = 0 ; i < services.GetCount() ; i++) + serviceString += wxT(" ") + services.Item(i) + wxT("\n"); + + wxMessageDialog msg(0, _("There are dependent services configured:\n\n") + + serviceString + _("\nStart dependent services too?"), _("Dependent services"), + wxICON_EXCLAMATION | wxYES_NO | wxYES_DEFAULT); + + if (msg.ShowModal() == wxID_YES) + { + for (i = 0 ; i < services.GetCount() ; i++) + { + SC_HANDLE h =::OpenService(scmHandle, services.Item(i), GENERIC_EXECUTE | GENERIC_READ); + if (h) + { + if (!::StartService(h, 0, 0)) + done = false; + CloseServiceHandle(h); + } + else + done = false; + } + if (!done) + { + wxMessageDialog msg(0, _("One or more dependent services didn't start; see the eventlog for details."), _("Service start problem"), + wxICON_EXCLAMATION | wxOK); + msg.ShowModal(); + done = true; + } + } + } + } + } +#else + wxString res = ExecProcess(serviceId + wxT(" start")); + done = (res.Find(wxT("tarting")) > 0); +#endif + return done; +} + + +bool pgServer::StopService() +{ + bool done = false; +#ifdef WIN32 + if (serviceHandle) + { + SERVICE_STATUS st; + + done = (::ControlService(serviceHandle, SERVICE_CONTROL_STOP, &st) != 0); + if (!done) + { + if (::GetLastError() == ERROR_DEPENDENT_SERVICES_RUNNING) + { + LPENUM_SERVICE_STATUS sbuf = (LPENUM_SERVICE_STATUS) new char[SERVICEBUFSIZE]; + DWORD bytesNeeded, servicesReturned = 0; + ::EnumDependentServices(serviceHandle, SERVICE_ACTIVE, sbuf, SERVICEBUFSIZE, &bytesNeeded, &servicesReturned); + + done = true; + + if (servicesReturned) + { + DWORD i; + wxString services; + for (i = 0 ; i < servicesReturned ; i++) + services += wxT(" ") + wxString(sbuf[i].lpDisplayName) + wxT("\n"); + + wxMessageDialog msg(0, _("There are dependent services running:\n\n") + + services + _("\nStop dependent services?"), _("Dependent services"), + wxICON_EXCLAMATION | wxYES_NO | wxYES_DEFAULT); + if (msg.ShowModal() != wxID_YES) + return false; + + for (i = 0 ; done && i < servicesReturned ; i++) + { + SC_HANDLE h =::OpenService(scmHandle, sbuf[i].lpServiceName, GENERIC_EXECUTE | GENERIC_READ); + if (h) + { + done = (::ControlService(h, SERVICE_CONTROL_STOP, &st) != 0); + CloseServiceHandle(h); + } + else + done = false; + } + if (done) + { + done = (::ControlService(serviceHandle, SERVICE_CONTROL_STOP, &st) != 0); + + int retries = 10; + while (!done && retries > 0) + { + done = (::ControlService(serviceHandle, SERVICE_CONTROL_STOP, &st) != 0); + retries--; + + wxSleep(5); + } + + } + } + } + // report error + + if (!done) + wxLogError(__("Failed to stop server %s: Errcode=%d\nCheck event log for details."), + serviceId.c_str(), ::GetLastError()); + } + } +#else + wxString res = ExecProcess(serviceId + wxT(" stop")); + done = (res.Find(wxT("stopped")) > 0); +#endif + return done; +} + + +bool pgServer::GetServerRunning() +{ + bool done = false; +#ifdef WIN32 + if (serviceHandle) + { + SERVICE_STATUS st; + int loops; + + for (loops = 0 ; loops < 20 ; loops++) + { + if (::QueryServiceStatus(serviceHandle, &st) == 0) + { + DWORD rc = ::GetLastError(); + CloseServiceHandle(serviceHandle); + CloseServiceHandle(scmHandle); + serviceHandle = 0; + scmHandle = 0; + + return false; + } + done = (st.dwCurrentState == SERVICE_RUNNING); + if (st.dwCurrentState == SERVICE_START_PENDING) + Sleep(100); + else + break; + } + } +#else + + wxString res = ExecProcess(serviceId + wxT(" status")); + done = (res.Find(wxT("PID: ")) > 0); + +#endif + return done; +} + + +void pgServer::iSetServiceID(const wxString &s) +{ + serviceId = s; +#ifdef WIN32 + if (serviceId.Find('\\') < 0) + scmHandle = OpenSCManager(0, SERVICES_ACTIVE_DATABASE, GENERIC_EXECUTE); + else + scmHandle = OpenSCManager(wxT("\\\\") + serviceId.BeforeFirst('\\'), SERVICES_ACTIVE_DATABASE, GENERIC_EXECUTE | GENERIC_READ); + + if (scmHandle) + serviceHandle = OpenService(scmHandle, serviceId.AfterLast('\\'), GENERIC_EXECUTE | GENERIC_READ); +#endif +} + + +bool pgServer::GetServerControllable() +{ +#ifdef WIN32 + return serviceHandle != 0; +#else + return !serviceId.IsEmpty(); +#endif +} + + +wxString pgServer::passwordFilename() +{ + wxString fname = sysSettings::GetConfigFile(sysSettings::PGPASS); + + wxLogInfo(wxT("Using password file %s"), fname.c_str()); + return fname; +} + + + +bool pgServer::GetPasswordIsStored() +{ + wxString fname = passwordFilename(); + + + if (!wxFile::Exists(fname)) + return false; + + wxUtfFile file(fname, wxFile::read, wxFONTENCODING_SYSTEM); + + if (file.IsOpened()) + { + wxString before; + file.Read(before); + + wxStringTokenizer lines(before, wxT("\n\r")); + + wxString seekStr = GetName() + wxT(":") + + NumToStr((long)GetPort()) + wxT(":*:") + + username + wxT(":") ; + + wxString seekStr2 = wxString(GetName().mb_str(wxConvUTF8), wxConvLibc) + wxT(":") + + NumToStr((long)GetPort()) + wxT(":*:") + + wxString(username.mb_str(wxConvUTF8), wxConvLibc) + wxT(":") ; + + while (lines.HasMoreTokens()) + { + wxString str = lines.GetNextToken(); + if (str.Left(seekStr.Length()) == seekStr) + return true; + + if (str.Left(seekStr2.Length()) == seekStr2) + return true; + } + } + + return false; +} + + +void pgServer::StorePassword() +{ + wxString fname = passwordFilename(); + + if (!wxFile::Exists(fname)) + { + return; + } + wxUtfFile file; + // Don't try to read and write in one OP - it doesn't work well + wxString before; + file.Open(fname, wxFile::read, wxFONTENCODING_SYSTEM); + file.Read(before); + file.Close(); + + file.Open(fname, wxFile::write, wxFONTENCODING_SYSTEM); + + if (file.IsOpened()) + { + wxString after; + + wxString passwd; + wxString seekStr; + + if (GetConnection()->GetNeedUtfConnectString()) + { + passwd = wxString(password.mb_str(wxConvUTF8), wxConvLibc); + seekStr = wxString(GetName().mb_str(wxConvUTF8), wxConvLibc) + wxT(":") + + NumToStr((long)GetPort()) + wxT(":*:") + + wxString(username.mb_str(wxConvUTF8), wxConvLibc) + wxT(":") ; + } + else + { + passwd = password; + seekStr = GetName() + wxT(":") + + NumToStr((long)GetPort()) + wxT(":*:") + + username + wxT(":") ; + } + + // Escape ":" and "\" from the password field + if (!passwd.IsEmpty()) + { + passwd.Replace(wxT("\\"), wxT("\\\\")); + passwd.Replace(wxT(":") , wxT("\\:")); + } + + file.Read(before); + wxStringTokenizer lines(before, wxT("\n\r")); + + file.Seek(0); + bool found = false; + while (lines.HasMoreTokens()) + { + wxString str = lines.GetNextToken(); + if (str.Left(seekStr.Length()) == seekStr && !passwd.IsEmpty()) + { + // entry found + found = true; + if (storePwd) + file.Write(seekStr + passwd + END_OF_LINE); + } + else + file.Write(str + END_OF_LINE); + } + if (!found && storePwd && !passwd.IsEmpty()) + file.Write(seekStr + passwd + END_OF_LINE); + + file.Close(); + } +} + + +int pgServer::Connect(frmMain *form, bool askPassword, const wxString &pwd, bool forceStorePassword, bool askTunnelPassword) +{ + wxLogInfo(wxT("Attempting to create a connection object...")); + + bool storePassword = false; + + if (!conn || conn->GetStatus() != PGCONN_OK) + { + if (conn) + { + delete conn; + conn = 0; + } + if (askPassword) + { + if ((sshTunnel || !passwordValid || !GetPasswordIsStored() || !GetStorePwd()) && GetSSLCert() == wxEmptyString) + { + wxString txt; + txt.Printf(_("Please enter password for user %s\non server %s (%s)"), username.c_str(), description.c_str(), GetName().c_str()); + dlgConnect *dlg = NULL; + // if sshTunnel is true then we have to hide 'Stored Password' option + if(sshTunnel) + dlg = new dlgConnect(NULL, txt, false); + else + dlg = new dlgConnect(form, txt, GetStorePwd()); + + dlg->SetWindowStyleFlag( dlg->GetWindowStyleFlag() | wxSTAY_ON_TOP); + + switch (dlg->Go()) + { + case wxID_OK: + // Give the UI a chance to redraw + wxSafeYield(); + wxMilliSleep(100); + wxSafeYield(); + break; + case wxID_CANCEL: + case -1: + // Give the UI a chance to redraw + wxSafeYield(); + wxMilliSleep(100); + wxSafeYield(); + return PGCONN_ABORTED; + default: + // Give the UI a chance to redraw + wxSafeYield(); + wxMilliSleep(100); + wxSafeYield(); + wxLogError(__("Couldn't create a connection dialogue!")); + return PGCONN_BAD; + } + + iSetStorePwd(dlg->GetStorePwd()); + password = dlg->GetPassword(); + storePassword = true; + if(dlg) + { + delete dlg; + dlg = NULL; + } + } + } + else + iSetPassword(pwd); + + form->StartMsg(_("Connecting to database")); + + wxString host; + int iPort; +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + if(sshTunnel) + { + //Ask Tunnel Password + if(askTunnelPassword) + { + wxString txt; + if(GetAuthModePwd()) + { + txt.Printf(_("Please enter the SSH tunnel password for user %s\non server %s"), tunnelUserName.c_str(), tunnelHost.c_str()); + } + else + { + txt.Printf(_("Please enter the pass phrase for the identity file\n%s"), identityFile.c_str()); + } + dlgConnect dlg(NULL, txt, false); + + switch (dlg.Go()) + { + case wxID_OK: + // Give the UI a chance to redraw + wxSafeYield(); + wxMilliSleep(100); + wxSafeYield(); + tunnelPassword = dlg.GetPassword(); + break; + case wxID_CANCEL: + case -1: + default: + // Give the UI a chance to redraw + wxSafeYield(); + wxMilliSleep(100); + wxSafeYield(); + form->EndMsg(false); + return PGCONN_ABORTED; + } + } + // Create SSH Tunnel if required + if(!tunnelObj) + { + if(!createSSHTunnel()) + { + form->EndMsg(false); + return PGCONN_SSHTUNNEL_ERROR; + } + } + + host = local_listenhost; + iPort = local_listenport; + } + else +#endif + { + host = GetName(); + iPort = port; + } + wxString usr=wxEmptyString; + wxGetEnv(wxT("USERNAME"),&usr); + if (database.IsEmpty()) + { + conn = new pgConn(host, service, hostaddr, DEFAULT_PG_DATABASE, username, password, iPort, rolename, ssl, 0, appearanceFactory->GetLongAppName() +wxT(" - ")+ usr, sslcert, sslkey, sslrootcert, sslcrl, sslcompression); + if (conn->GetStatus() == PGCONN_OK) + database = DEFAULT_PG_DATABASE; + else if (conn->GetStatus() == PGCONN_BAD && conn->GetLastError().Find( + wxT("database \"") DEFAULT_PG_DATABASE wxT("\" does not exist")) >= 0) + { + delete conn; + conn = new pgConn(host, service, hostaddr, wxT("template1"), username, password, iPort, rolename, ssl, 0, appearanceFactory->GetLongAppName() + wxT(" - Browser"), sslcert, sslkey, sslrootcert, sslcrl, sslcompression); + if (conn && conn->GetStatus() == PGCONN_OK) + database = wxT("template1"); + } + } + else + { + conn = new pgConn(host, service, hostaddr, database, username, password, iPort, rolename, ssl, 0, appearanceFactory->GetLongAppName() + _(" ")+usr, sslcert, sslkey, sslrootcert, sslcrl, sslcompression); + if (!conn) + { + form->EndMsg(false); + wxLogError(__("Couldn't create a connection object!")); + return PGCONN_BAD; + } + } + } + int status = conn->GetStatus(); + if (status == PGCONN_OK) + { + dbOid = conn->GetDbOid(); + + // Check the server version + if (conn->GetIsGreenplum()) + { + // Greenplum HAWQ (SQL on Hadoop) is not supported by this pgAdmin version + if (conn->GetIsHawq()) + { + wxLogWarning(_("The server you are connecting to is not a version that is supported by this release of %s.\n\n%s may not function as expected."), + appearanceFactory->GetLongAppName().c_str(), + appearanceFactory->GetLongAppName().c_str()); + } + else + { + // Check for Greenplum specific version + // Greenplum always shows PG version "8.2.15" for now + // this might change once the merge with recent PG versions makes progress + // therefore also check for the max version + if (!(conn->BackendMinimumVersion(GP_MIN_VERSION_N >> 8, GP_MIN_VERSION_N & 0x00FF)) || + (conn->BackendMinimumVersion(GP_MAX_VERSION_N >> 8, (GP_MAX_VERSION_N & 0x00FF) + 1))) + { + if (GP_MIN_VERSION_N == GP_MAX_VERSION_N) + { + wxLogWarning(_("The server you are connecting to is not a version that is supported by this release of %s.\n\n%s may not function as expected.\n\nSupported server version is %s."), + appearanceFactory->GetLongAppName().c_str(), + appearanceFactory->GetLongAppName().c_str(), + wxString(GP_MIN_VERSION_T).c_str()); + } + else + { + wxLogWarning(_("The server you are connecting to is not a version that is supported by this release of %s.\n\n%s may not function as expected.\n\nSupported server versions are %s to %s."), + appearanceFactory->GetLongAppName().c_str(), + appearanceFactory->GetLongAppName().c_str(), + wxString(GP_MIN_VERSION_T).c_str(), + wxString(GP_MAX_VERSION_T).c_str()); + } + } + } + } + else + { + if (!(conn->BackendMinimumVersion(SERVER_MIN_VERSION_N >> 8, SERVER_MIN_VERSION_N & 0x00FF)) || + (conn->BackendMinimumVersion(SERVER_MAX_VERSION_N >> 8, (SERVER_MAX_VERSION_N & 0x00FF) + 1))) { + wxLogWarning(_("The server you are connecting to is not a version that is supported by this release of %s.\n\n%s may not function as expected.\n\nSupported server versions are %s to %s."), + appearanceFactory->GetLongAppName().c_str(), + appearanceFactory->GetLongAppName().c_str(), + wxString(SERVER_MIN_VERSION_T).c_str(), + wxString(SERVER_MAX_VERSION_T).c_str()); + } + } + + connected = true; + bool hasUptime = false; + + wxString sql = wxT("SELECT usecreatedb, usesuper"); + if (conn->BackendMinimumVersion(8, 1)) + { + hasUptime = true; + sql += wxT(", CASE WHEN usesuper THEN pg_postmaster_start_time() ELSE NULL END as upsince"); + } + else if (conn->HasFeature(FEATURE_POSTMASTER_STARTTIME)) + { + hasUptime = true; + sql += wxT(", CASE WHEN usesuper THEN pg_postmaster_starttime() ELSE NULL END as upsince"); + } + if (conn->BackendMinimumVersion(8, 4)) + { + sql += wxT(", CASE WHEN usesuper THEN pg_conf_load_time() ELSE NULL END as confloadedsince"); + } + if (conn->BackendMinimumVersion(8, 5)) + { + sql += wxT(", CASE WHEN usesuper THEN pg_is_in_recovery() ELSE NULL END as inrecovery"); + if (conn->BackendMinimumVersion(10, 0)) + { + sql += wxT(", CASE WHEN usesuper THEN pg_last_wal_receive_lsn() ELSE NULL END as receiveloc"); + sql += wxT(", CASE WHEN usesuper THEN pg_last_wal_replay_lsn() ELSE NULL END as replayloc"); + } + else + { + sql += wxT(", CASE WHEN usesuper THEN pg_last_xlog_receive_location() ELSE NULL END as receiveloc"); + sql += wxT(", CASE WHEN usesuper THEN pg_last_xlog_replay_location() ELSE NULL END as replayloc"); + } + } + if (conn->BackendMinimumVersion(9, 1)) + { + sql += wxT(", CASE WHEN usesuper THEN pg_last_xact_replay_timestamp() ELSE NULL END as replay_timestamp"); + if (conn->BackendMinimumVersion(10, 0)) + sql += wxT(", CASE WHEN usesuper AND pg_is_in_recovery() THEN pg_is_wal_replay_paused() ELSE NULL END as isreplaypaused"); + else + sql += wxT(", CASE WHEN usesuper AND pg_is_in_recovery() THEN pg_is_xlog_replay_paused() ELSE NULL END as isreplaypaused"); + } + + pgSet *set = ExecuteSet(sql + wxT("\n FROM pg_user WHERE usename=current_user")); + if (set) + { + iSetCreatePrivilege(set->GetBool(wxT("usecreatedb"))); + iSetSuperUser(set->GetBool(wxT("usesuper"))); + if (hasUptime) + iSetUpSince(set->GetDateTime(wxT("upsince"))); + if (conn->BackendMinimumVersion(8, 4)) + iSetConfLoadedSince(set->GetDateTime(wxT("confloadedsince"))); + if (conn->BackendMinimumVersion(8, 5)) + { + iSetInRecovery(set->GetBool(wxT("inrecovery"))); + iSetReplayLoc(set->GetVal(wxT("replayloc"))); + iSetReceiveLoc(set->GetVal(wxT("receiveloc"))); + } + if (conn->BackendMinimumVersion(9, 1)) + { + iSetReplayTimestamp(set->GetVal(wxT("replay_timestamp"))); + SetReplayPaused(set->GetBool(wxT("isreplaypaused"))); + } + delete set; + } + + if (conn->BackendMinimumVersion(8, 1)) + { + set = ExecuteSet(wxT("SELECT rolcreaterole, rolcreatedb FROM pg_roles WHERE rolname = current_user;")); + + if (set) + { + iSetCreatePrivilege(set->GetBool(wxT("rolcreatedb"))); + iSetCreateRole(set->GetBool(wxT("rolcreaterole"))); + delete set; + } + } + else + iSetCreateRole(false); + + wxString version, allVersions; + version.Printf(wxT("%d.%d"), conn->GetMajorVersion(), conn->GetMinorVersion()); + allVersions = settings->Read(wxT("Updates/pgsql-Versions"), wxEmptyString); + if (allVersions.Find(version) < 0) + { + if (!allVersions.IsEmpty()) + allVersions += wxT(", "); + allVersions += version; + settings->Write(wxT("Updates/pgsql-Versions"), allVersions); + } + if (conn->IsSSLconnected()) + settings->WriteBool(wxT("Updates/UseSSL"), true); + + UpdateIcon(form->GetBrowser()); + if (storePassword || forceStorePassword) + StorePassword(); + } + else + { + connected = false; + } + + form->EndMsg(connected && status == PGCONN_OK); + + passwordValid = connected; + return status; +} + + +wxString pgServer::GetIdentifier() const +{ + wxString idstr; + if (GetService().IsEmpty()) + { + if (GetName().IsEmpty()) + idstr.Printf(wxT("local:.s.PGSQL.%d"), port); + else if (GetName().StartsWith(wxT("/"))) + idstr.Printf(wxT("local:%s/.s.PGSQL.%d"), GetName().c_str(), port); + else + idstr.Printf(wxT("%s:%d"), GetName().c_str(), port); + } + else + idstr.Printf(_("service %s"), GetService().c_str()); + return idstr; +} + + +wxString pgServer::GetVersionString() +{ + if (connected) + { + if (ver.IsEmpty()) + ver = wxString(conn->GetVersionString()); + return ver; + } + else + return wxEmptyString; +} + + +wxString pgServer::GetVersionNumber() +{ + if (connected) + { + if (versionNum.IsEmpty()) + { + int major = 0, minor = 0; + sscanf(GetVersionString().ToAscii(), "%*s %d.%d", &major, &minor); + versionNum.Printf(wxT("%d.%d"), major, minor); + } + + } + return versionNum; +} + + +OID pgServer::GetLastSystemOID() +{ + if (connected) + { + if (lastSystemOID == 0) + lastSystemOID = conn->GetLastSystemOID(); + return lastSystemOID; + } + else + return 0; +} + + +bool pgServer::SetPassword(const wxString &newVal) +{ + wxString sql; + sql.Printf(wxT("ALTER USER %s WITH ENCRYPTED PASSWORD %s;"), qtIdent(username).c_str(), qtDbString(conn->EncryptPassword(username, newVal)).c_str()); + bool executed = conn->ExecuteVoid(sql); + if (executed) + { + password = newVal; + StorePassword(); + return true; + } + else + return false; +} + + +wxString pgServer::GetLastError() const +{ + wxString msg; + if (conn) + { + if (error != wxT("")) + { + if (conn->GetLastError() != wxT("")) + { + msg.Printf(wxT("%s\n%s"), error.c_str(), conn->GetLastError().c_str()); + } + else + { + msg = error; + } + } + else + { + msg = conn->GetLastError(); + } + } + return msg; +} + + + +void pgServer::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + // Add child nodes if necessary + if (GetConnected()) + { + // Reset password menu option +// form->fileMenu->Enable(MNU_PASSWORD, true); + + if (!expandedKids) + { + expandedKids = true; + // Log + + wxLogInfo(wxT("Adding child object to server %s"), GetIdentifier().c_str()); + + if (settings->GetDisplayOption(_("Databases"))) + browser->AppendCollection(this, databaseFactory); + + if (conn->BackendMinimumVersion(8, 0) && settings->GetDisplayOption(_("Tablespaces"))) + browser->AppendCollection(this, tablespaceFactory); + + // Jobs + // We only add the Jobs node if the appropriate objects are the initial DB. + if (settings->GetDisplayOption(_("pgAgent Jobs"))) + { + wxString exists = conn->ExecuteScalar( + wxT("SELECT cl.oid FROM pg_class cl JOIN pg_namespace ns ON ns.oid=relnamespace\n") + wxT(" WHERE relname='pga_job' AND nspname='pgagent'")); + + if (!exists.IsNull()) + { + exists = conn->ExecuteScalar(wxT("SELECT has_schema_privilege('pgagent', 'USAGE')")); + + if (exists == wxT("t")) + browser->AppendCollection(this, jobFactory); + } + } + + if (conn->BackendMinimumVersion(8, 1)) + { + if (settings->GetDisplayOption(_("Groups/group Roles"))) + browser->AppendCollection(this, groupRoleFactory); + if (settings->GetDisplayOption(_("Users/login Roles"))) + browser->AppendCollection(this, loginRoleFactory); + if (GetConnection()->GetIsGreenplum()) + { + if (settings->GetDisplayOption(_("Resource Queues"))) + browser->AppendCollection(this, resQueueFactory); + } + } + else + { + if (settings->GetDisplayOption(_("Groups/group Roles"))) + browser->AppendCollection(this, groupFactory); + if (settings->GetDisplayOption(_("Users/login Roles"))) + browser->AppendCollection(this, userFactory); + } + + // Added Resource Group only for PPAS 9.4 and above + if (conn->GetIsEdb() && conn->EdbMinimumVersion(9, 4)) + { + if (settings->GetDisplayOption(_("Resource Groups"))) + browser->AppendCollection(this, resourceGroupFactory); + } + + autovacuumRunning = true; + + wxString qry; + if (conn->BackendMinimumVersion(8, 3)) + qry = wxT("SELECT setting FROM pg_settings WHERE name IN ('autovacuum', 'track_counts')"); + else + qry = wxT("SELECT setting FROM pg_settings WHERE name IN ('autovacuum', 'stats_start_collector', 'stats_row_level')"); + + pgSetIterator set(conn, qry); + + while (autovacuumRunning && set.RowsLeft()) + autovacuumRunning = set.GetBool(wxT("setting")); + } + } + + + if (properties) + { + // Add the properties view columns + CreateListColumns(properties); + + // Display the Server properties + + properties->AppendItem(_("Description"), GetDescription()); + properties->AppendItem(_("Service"), GetService()); + if (GetName().IsEmpty() || GetName().StartsWith(wxT("/"))) + { + if (GetName().IsEmpty() && !GetService().IsEmpty()) + properties->AppendItem(_("Hostname"), wxEmptyString); + else + properties->AppendItem(_("Hostname"), wxT("local:") + GetName()); + + if (GetPort() == 0 && !GetService().IsEmpty()) + properties->AppendItem(_("Port"), wxEmptyString); + else + properties->AppendItem(_("Port"), (long)GetPort()); + } + else + { + properties->AppendItem(_("Hostname"), GetName()); + properties->AppendItem(_("Host Address"), GetHostAddr()); + if (GetPort() == 0 && !GetService().IsEmpty()) + properties->AppendItem(_("Port"), wxEmptyString); + else + properties->AppendItem(_("Port"), (long)GetPort()); +#ifdef PG_SSL + if (GetConnected()) + { + properties->AppendItem(_("Encryption"), + conn->IsSSLconnected() ? _("SSL encrypted") : _("not encrypted")); + } + else + { + if (ssl > 0) + { + wxString sslMode; + switch (ssl) + { + case 1: + sslMode = _("require"); + break; + case 2: + sslMode = _("prefer"); + break; + case 3: + sslMode = _("allow"); + break; + case 4: + sslMode = _("disable"); + break; + case 5: + sslMode = _("verify-ca"); + break; + case 6: + sslMode = _("verify-full"); + break; + } + properties->AppendItem(_("SSL Mode"), sslMode); + } + } + properties->AppendItem(_("SSL Certificate File"), GetSSLCert()); + properties->AppendItem(_("SSL Key File"), GetSSLKey()); + properties->AppendItem(_("SSL Root Certificate File"), GetSSLRootCert()); + properties->AppendItem(_("SSL Certificate Revocation List"), GetSSLCrl()); + properties->AppendItem(_("SSL Compression?"), (GetSSLCompression() ? _("yes") : _("no"))); +#endif + } + if (!serviceId.IsEmpty()) + properties->AppendItem(_("Service ID"), serviceId); + + properties->AppendItem(_("Maintenance database"), GetDatabaseName()); + properties->AppendItem(_("Username"), GetUsername()); + if (!GetRolename().IsEmpty()) + properties->AppendItem(_("Default role"), GetRolename()); + + properties->AppendYesNoItem(_("Store password?"), GetStorePwd()); + properties->AppendYesNoItem(_("Restore environment?"), GetRestore()); + if (GetConnected()) + { + properties->AppendItem(_("Version string"), GetVersionString()); + properties->AppendItem(_("Version number"), GetVersionNumber()); + properties->AppendItem(_("Last system OID"), GetLastSystemOID()); + } + properties->AppendYesNoItem(_("Connected?"), GetConnected()); + if (GetConnected()) + { + if (GetUpSince().IsValid()) + properties->AppendItem(_("Up since"), GetUpSince()); + if (GetConfLoadedSince().IsValid()) + properties->AppendItem(_("Configuration loaded since"), GetConfLoadedSince()); + if (conn->BackendMinimumVersion(8, 1)) + properties->AppendItem(wxT("Autovacuum"), (autovacuumRunning ? _("running") : _("not running"))); + if (conn->BackendMinimumVersion(8, 5)) + { + properties->AppendItem(_("In recovery"), (GetInRecovery() ? _("yes") : _("no"))); + properties->AppendItem(_("Last XLOG receive location"), GetReceiveLoc()); + properties->AppendItem(_("Last XLOG replay location"), GetReplayLoc()); + } + if (conn->BackendMinimumVersion(9, 1)) + { + properties->AppendItem(_("Last XACT replay timestamp"), GetReplayTimestamp()); + if (GetInRecovery()) + properties->AppendItem(_("Replay paused"), (GetReplayPaused() ? _("paused") : _("running"))); + else + properties->AppendItem(_("Replay paused"), wxEmptyString); + } + } + if (GetServerControllable()) + properties->AppendYesNoItem(_("Running?"), GetServerRunning()); + + if (!GetDbRestriction().IsEmpty()) + properties->AppendItem(_("DB restriction"), GetDbRestriction()); + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + if(sshTunnel) + { + properties->AppendItem(_("SSH tunneling?"), (sshTunnel ? _("Yes") : _("No"))); + properties->AppendItem(_("Tunnel host"), GetTunnelHost()); + properties->AppendItem(_("Tunnel username"), GetTunnelUserName()); + properties->AppendItem(_("Authentication mode"), (GetAuthModePwd() ? _("Password") : _("Identity file"))); + if(!GetAuthModePwd()) + { + properties->AppendItem(_("Identity file path"), GetIdentityFile()); + } + } +#endif + } + + if(!GetConnected()) + return; + + if (form && GetCanHint() && !hintShown) + { + ShowHint(form, false); + } +} + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + +bool pgServer::createSSHTunnel() +{ + bool retVal = false; + + tunnelObj = new CSSHTunnelThread(tunnelHost, GetName(), port, tunnelUserName, tunnelPassword, publicKeyFile, + identityFile, authModePwd ? AUTH_PASSWORD : AUTH_PUBLICKEY, tunnelPort); + + if(tunnelObj) + { + if(tunnelObj->Initialize()) + { + if ( tunnelObj->Create() != wxTHREAD_NO_ERROR ) + { + delete tunnelObj; + tunnelObj = NULL; + wxLogError(_("SSH Error: Unable to create SSH Tunnling Thread")); + } + else + { + if (tunnelObj->Run() != wxTHREAD_NO_ERROR ) + { + delete tunnelObj; + tunnelObj = NULL; + wxLogError(_("SSH Error: Unable to start SSH Tunnling Thread")); + } + + SetLocalListenHost(tunnelObj->GetLocalListenIP()); + SetLocalListenPort(tunnelObj->GetLocalListenPort()); + retVal = true; + } + } + else + { + delete tunnelObj; + tunnelObj = NULL; + } + } + + return retVal; +} +#endif + +void pgServer::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + if (conn) + { + wxString pidcol = GetConnection()->BackendMinimumVersion(9, 2) ? wxT("pid") : wxT("procpid"); + wxString querycol = GetConnection()->BackendMinimumVersion(9, 2) ? wxT("query") : wxT("current_query"); + wxString sql; + wxString replication_query = wxT("state || ' (' || sent_location || ' sent, ' || write_location || ' written, ' || flush_location || ' flushed, ' || replay_location || ' applied)'"); + if (GetConnection()->BackendMinimumVersion(10, 0)) { + replication_query = wxT("state || ' (' || sent_lsn || ' sent, ' || write_lsn || ' written, ' || flush_lsn || ' flushed, ' || replay_lsn || ' applied)'"); + } + wxLogInfo(wxT("Displaying statistics for server %s"), GetIdentifier().c_str()); + + // Add the statistics view columns + statistics->ClearAll(); + statistics->AddColumn(wxT("PID"), 35); + statistics->AddColumn(_("User"), 70); + statistics->AddColumn(_("Database"), 70); + if (GetConnection()->BackendMinimumVersion(8, 1)) + { + statistics->AddColumn(_("Backend start"), 70); + statistics->AddColumn(_("Client"), 70); + } + statistics->AddColumn(_("Current Query"), 300); + + sql = wxT("SELECT ") + pidcol + wxT(" AS pid, usename, datname, backend_start, client_addr, "); + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += wxT("client_hostname, "); + sql += wxT("client_port, ") + querycol + wxT(" AS query FROM pg_stat_activity\n"); + if (GetConnection()->BackendMinimumVersion(9, 1)) + { + sql += wxT("UNION\n") + wxT("SELECT ") + pidcol + wxT(", usename, '' AS datname, backend_start, client_addr, client_hostname, client_port, ") + + replication_query + wxT(" AS query FROM pg_stat_replication"); + } + + pgSet *stats = ExecuteSet(sql); + if (stats) + { + int pos = 0; + while (!stats->Eof()) + { + statistics->InsertItem(pos, stats->GetVal(wxT("pid")), 0); + int colpos = 1; + statistics->SetItem(pos, colpos++, stats->GetVal(wxT("usename"))); + statistics->SetItem(pos, colpos++, stats->GetVal(wxT("datname"))); + if (GetConnection()->BackendMinimumVersion(8, 1)) + { + statistics->SetItem(pos, colpos++, stats->GetVal(wxT("backend_start"))); + wxString client; + if (GetConnection()->BackendMinimumVersion(9, 1) && !stats->GetVal(wxT("client_hostname")).IsEmpty()) + client = stats->GetVal(wxT("client_hostname")) + wxT(":") + stats->GetVal(wxT("client_port")); + else + client = stats->GetVal(wxT("client_addr")) + wxT(":") + stats->GetVal(wxT("client_port")); + if (client == wxT(":-1")) + client = _("local pipe"); + statistics->SetItem(pos, colpos++, client); + } + statistics->SetItem(pos, colpos++, stats->GetVal(wxT("query"))); + + stats->MoveNext(); + pos++; + } + + delete stats; + } + } +} + +void pgServer::ShowDependencies(frmMain *form, ctlListView *Dependencies, const wxString &wh) +{ +} + + +void pgServer::ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &wh) +{ +} + + +bool pgServer::ReloadConfiguration() +{ + wxString sql = wxT("select pg_reload_conf()"); + return conn->ExecuteVoid(sql); +} + + +bool pgServer::PauseReplay() +{ + SetReplayPaused(true); + wxString sql = wxT("SELECT pg_xlog_replay_pause()"); + return conn->ExecuteVoid(sql); +} + + +bool pgServer::ResumeReplay() +{ + SetReplayPaused(false); + wxString sql = wxT("SELECT pg_xlog_replay_resume()"); + return conn->ExecuteVoid(sql); +} + + +bool pgServer::AddNamedRestorePoint() +{ + wxString namedrestorepoint = wxGetTextFromUser(_("Enter the name of the restore point to add"), _("Restore point name")); + if (!namedrestorepoint.IsEmpty()) + { + wxString sql = wxT("select pg_create_restore_point(") + qtDbString(namedrestorepoint) + wxT(")"); + return conn->ExecuteVoid(sql); + } + return false; +} + +pgServerCollection::pgServerCollection(pgaFactory *factory) + : pgCollection(factory) +{ +} + + +wxString pgServerCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on servers"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing servers"); + break; + case OBJECTSLISTREPORT: + message = _("Servers list report"); + break; + } + + return message; +} + + +pgServerObjCollection::pgServerObjCollection(pgaFactory *factory, pgServer *sv) + : pgCollection(factory) +{ + server = sv; +} + + +bool pgServerObjCollection::CanCreate() +{ + // We can't create resource queues on Greenplum yet. + if (IsCollectionForType(GP_RESOURCE_QUEUE)) + return false; + + // We can't create tablespaces on Greenplum + if (server->GetConnection()->GetIsGreenplum() && IsCollectionForType(PGM_TABLESPACE)) + return false; + + if (server->GetMetaType() == PGM_DATABASE) + return (GetServer()->GetCreatePrivilege() || GetServer()->GetSuperUser()); + else + { + if (server->GetConnection()->BackendMinimumVersion(8, 1) && GetMetaType() == PGM_ROLE) + return (server->GetCreateRole() || server->GetSuperUser()); + else if (server->GetConnection()->BackendMinimumVersion(8, 1) && GetMetaType() == PGM_DATABASE) + return (server->GetCreatePrivilege() || server->GetSuperUser()); + else if (GetMetaType() == PGM_JOB) + return true; + else + return server->GetSuperUser(); + } +} + + +pgObject *pgServerFactory::CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr) +{ + wxTreeItemId groupitem, serveritem; + wxTreeItemIdValue groupcookie; + bool found; + + long numServers = settings->Read(wxT("Servers/Count"), 0L); + + long loop, port, ssl = 0; + wxString key, servername, hostaddr, description, service, database, username, lastDatabase, lastSchema; + wxString storePwd, rolename, restore, serviceID, discoveryID, dbRestriction, colour; + wxString group, sslcert, sslkey, sslrootcert, sslcrl, sslcompression; + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + wxString sshTunnel, authModePwd, tunnelHost, tunnelUserName, tunnelPassword, publicKeyFile, identityFile; + long tunnelPort; +#endif + pgServer *server = 0; + + wxArrayString discoveredServers; + + // Get the hostname for later... + char buf[255]; + gethostname(buf, 255); + wxString hostname = wxString(buf, wxConvUTF8); + + //wxLogError(wxT("Loading previously registered servers")); + wxLogInfo(wxT("Loading previously registered servers")); + + for (loop = 1; loop <= numServers; ++loop) + { + key.Printf(wxT("Servers/%d/"), (int)loop); + + settings->Read(key + wxT("Server"), &servername, wxEmptyString); + settings->Read(key + wxT("HostAddr"), &hostaddr, wxEmptyString); + settings->Read(key + wxT("Service"), &service, wxEmptyString); + settings->Read(key + wxT("ServiceID"), &serviceID, wxEmptyString); + settings->Read(key + wxT("DiscoveryID"), &discoveryID, serviceID); + settings->Read(key + wxT("Description"), &description, wxEmptyString); + settings->Read(key + wxT("StorePwd"), &storePwd, wxEmptyString); + settings->Read(key + wxT("Rolename"), &rolename, wxEmptyString); + settings->Read(key + wxT("Restore"), &restore, wxT("true")); + settings->Read(key + wxT("Port"), &port, 0); + settings->Read(key + wxT("Database"), &database, wxEmptyString); + settings->Read(key + wxT("Username"), &username, wxEmptyString); + settings->Read(key + wxT("LastDatabase"), &lastDatabase, wxEmptyString); + settings->Read(key + wxT("LastSchema"), &lastSchema, wxEmptyString); + settings->Read(key + wxT("DbRestriction"), &dbRestriction, wxEmptyString); + settings->Read(key + wxT("Colour"), &colour, wxEmptyString); + settings->Read(key + wxT("Group"), &group, wxT("Servers")); + settings->Read(key + wxT("SSLCert"), &sslcert, wxEmptyString); + settings->Read(key + wxT("SSLKey"), &sslkey, wxEmptyString); + settings->Read(key + wxT("SSLRootCert"), &sslrootcert, wxEmptyString); + settings->Read(key + wxT("SSLCrl"), &sslcrl, wxEmptyString); + settings->Read(key + wxT("SSLCompression"), &sslcompression, wxT("true")); +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + settings->Read(key + wxT("SSHTunnel"), &sshTunnel, wxT("false")); + settings->Read(key + wxT("TunnelHost"), &tunnelHost, wxEmptyString); + settings->Read(key + wxT("TunnelUserName"), &tunnelUserName, wxEmptyString); + settings->Read(key + wxT("TunnelModePwd"), &authModePwd, wxT("true")); + settings->Read(key + wxT("PublicKeyFile"), &publicKeyFile, wxEmptyString); + settings->Read(key + wxT("IdentityFile"), &identityFile, wxEmptyString); + settings->Read(key + wxT("TunnelPort"), &tunnelPort, DEFAULT_SSH_PORT); +#endif + // Sanitize the colour + colour = colour.Trim(); + + if (!colour.IsEmpty()) + { + wxColour cColour; + + if (cColour.Set(colour)) + colour = cColour.GetAsString(wxC2S_HTML_SYNTAX); + else + colour = wxEmptyString; + } + + if (colour.IsEmpty()) + { + wxColour cColour; + cColour.Set(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW).GetAsString(wxC2S_HTML_SYNTAX)); + colour = cColour.GetAsString(wxC2S_HTML_SYNTAX); + } + + // SSL mode +#ifdef PG_SSL + settings->Read(key + wxT("SSL"), &ssl, 0); +#endif + + // Sanitize the group + if (group.IsEmpty()) + { + group = _("Servers"); + } + + // Add the Server node +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + server = new pgServer(servername, hostaddr, description, service, database, username, port, StrToBool(storePwd), rolename, StrToBool(restore), ssl, + colour, group, StrToBool(sshTunnel), tunnelHost, tunnelUserName, StrToBool(authModePwd), tunnelPassword, publicKeyFile, identityFile, tunnelPort); +#else + server = new pgServer(servername, hostaddr, description, service, database, username, port, StrToBool(storePwd), rolename, StrToBool(restore), ssl, + colour, group); +#endif + server->iSetLastDatabase(lastDatabase); + server->iSetLastSchema(lastSchema); + server->iSetService(service); + server->iSetServiceID(serviceID); + server->iSetDiscoveryID(discoveryID); + server->iSetDiscovered(false); + server->iSetDbRestriction(dbRestriction); + server->iSetServerIndex(loop); + server->SetSSLCert(sslcert); + server->SetSSLKey(sslkey); + server->SetSSLRootCert(sslrootcert); + server->SetSSLCrl(sslcrl); + server->iSetSSLCompression(StrToBool(sslcompression)); + + found = false; + if (browser->ItemHasChildren(obj->GetId())) + { + groupitem = browser->GetFirstChild(obj->GetId(), groupcookie); + while (!found && groupitem) + { + if (browser->GetItemText(groupitem).StartsWith(group)) + found = true; + else + groupitem = browser->GetNextChild(obj->GetId(), groupcookie); + } + } + + if (!found) + { + groupitem = browser->AppendItem(obj->GetId(), group, obj->GetIconId()); + } + + serveritem = browser->AppendItem(groupitem, server->GetFullName(), server->GetIconId(), -1, server); + browser->SortChildren(groupitem); + if (!server->GetColour().IsEmpty()) + browser->SetItemBackgroundColour(serveritem, wxColour(server->GetColour())); + + // Note if we're reloading a discovered server + if (!discoveryID.IsEmpty()) + discoveredServers.Add(discoveryID); + } + + group = _("Servers"); + +#ifdef __WXMSW__ + + // Add local servers. Will currently only work on Win32 with >= BETA3 + // of the Win32 PostgreSQL installer. + wxLogInfo(wxT("Loading servers registered on the local machine")); + + pgRegKey::PGREGWOWMODE wowMode = pgRegKey::PGREG_WOW_DEFAULT; + if (::wxIsPlatform64Bit()) + wowMode = pgRegKey::PGREG_WOW32; + + pgRegKey *pgKey = pgRegKey::OpenRegKey(HKEY_LOCAL_MACHINE, wxT("Software\\PostgreSQL\\Services"), pgRegKey::PGREG_READ, wowMode); + + if (pgKey == NULL) + { + wowMode = pgRegKey::PGREG_WOW64; + pgKey = pgRegKey::OpenRegKey(HKEY_LOCAL_MACHINE, wxT("Software\\PostgreSQL\\Services"), pgRegKey::PGREG_READ, wowMode); + } + + while (pgKey != NULL) + { + pgRegKey *svcKey = NULL; + wxString svcName; + long cookie = 0; + DWORD tmpport = 0; + bool flag = false; + + flag = pgKey->GetFirstKey(svcKey, cookie); + + while (flag != false) + { + svcName = svcKey->GetKeyName(); + // On Windows, the discovery ID is always the service name. + // Only load the server if we didn't load it with all the others. + if (discoveredServers.Index(svcName, false) < 0) + { + servername = wxT("localhost"); + database = wxEmptyString; + svcKey->QueryValue(wxT("Display Name"), description); + svcKey->QueryValue(wxT("Database Superuser"), username); + svcKey->QueryValue(wxT("Port"), &tmpport); + + // Add the Server node + server = new pgServer(servername, wxEmptyString, description, wxEmptyString, database, username, (long)tmpport, false, wxEmptyString, false); + server->iSetDiscoveryID(svcName); + server->iSetDiscovered(true); + server->iSetServiceID(svcName); + server->iSetGroup(group); + + found = false; + + if (browser->ItemHasChildren(browser->GetRootItem())) + { + groupitem = browser->GetFirstChild(browser->GetRootItem(), groupcookie); + while (!found && groupitem) + { + if (browser->GetItemText(groupitem).StartsWith(group)) + found = true; + else + groupitem = browser->GetNextChild(browser->GetRootItem(), groupcookie); + } + } + + if (!found) + { + groupitem = browser->AppendItem(browser->GetRootItem(), group, obj->GetIconId()); + browser->SortChildren(browser->GetRootItem()); + } + + browser->AppendItem(groupitem, server->GetFullName(), server->GetIconId(), -1, server); + browser->SortChildren(groupitem); + } + // Release the current registry key + delete svcKey; + + // Get the next one... + flag = pgKey->GetNextKey(svcKey, cookie); + } + + /* Release current registry key */ + delete pgKey; + pgKey = NULL; + /* + * If wowMode is equal to WOW32, that means this machine is a 64 bit machine and we need to read now 64 bit registry + */ + if (wowMode == pgRegKey::PGREG_WOW32) + { + wowMode = pgRegKey::PGREG_WOW64; + pgKey = pgRegKey::OpenRegKey(HKEY_LOCAL_MACHINE, wxT("Software\\PostgreSQL\\Services"), pgRegKey::PGREG_READ, wowMode); + } + } +#endif // __WXMSW__ + + // Add local servers on non-Win32 platforms (on Win32, they will be picked up above) +#ifndef WIN32 + + // On Unix/Mac, the discovery ID can be anything. We use the PostgreSQL + // package config filename if it's present, as that is the only thing vaguely + // discoverable and unique to a given installation. We can do the same for + // other distros in the future if they drop a suitable file someplace. + // Look for any files that match the basic postgres*.ini pattern. + + wxLogInfo(wxT("Loading servers registered on the local machine")); + + if (wxFile::Exists(REGISTRY_FILE)) + { + wxString version, locale; + long cookie; + + wxFileInputStream fst(REGISTRY_FILE); + wxFileConfig *cnf = new wxFileConfig(fst); + + // PostgreSQL servers + cnf->SetPath(wxT("/PostgreSQL")); + bool flag = cnf->GetFirstGroup(version, cookie); + while (flag) + { + // If there is no Version entry, this is probably an uninstalled server + if (cnf->Read(version + wxT("/Version"), wxEmptyString) != wxEmptyString) + { + // Only load this server if we haven't read it from the pgAdmin config + if (discoveredServers.Index(cnf->GetPath() + wxT("/") + version, false) < 0) + { + + // Basic details + servername = wxT("localhost"); + cnf->Read(version + wxT("/Description"), &description, wxT("PostgreSQL ") + version); + cnf->Read(version + wxT("/Superuser"), &username, wxEmptyString); + cnf->Read(version + wxT("/Port"), &port, 0); + + // Add the item, if it looks sane + if (port != 0 && username != wxEmptyString) + { + server = new pgServer(servername, wxEmptyString, description, wxEmptyString, wxT("postgres"), username, port, false, rolename, 0); + server->iSetDiscoveryID(cnf->GetPath() + wxT("/") + version); + server->iSetDiscovered(true); + server->iSetGroup(group); + found = false; + if (browser->ItemHasChildren(browser->GetRootItem())) + { + groupitem = browser->GetFirstChild(browser->GetRootItem(), groupcookie); + while (!found && groupitem) + { + if (browser->GetItemText(groupitem).StartsWith(group)) + found = true; + else + groupitem = browser->GetNextChild(browser->GetRootItem(), groupcookie); + } + } + + if (!found) + { + groupitem = browser->AppendItem(browser->GetRootItem(), group, obj->GetIconId()); + browser->SortChildren(browser->GetRootItem()); + } + + browser->AppendItem(groupitem, server->GetFullName(), server->GetIconId(), -1, server); + browser->SortChildren(groupitem); + } + } + } + + flag = cnf->GetNextGroup(version, cookie); + } + + // EnterpriseDB servers + cnf->SetPath(wxT("/EnterpriseDB")); + flag = cnf->GetFirstGroup(version, cookie); + while (flag) + { + // If there is no Version entry, this is probably an uninstalled server + if (cnf->Read(version + wxT("/Version"), wxEmptyString) != wxEmptyString) + { + // Only load this server if we haven't read it from the pgAdmin config + if (discoveredServers.Index(cnf->GetPath() + wxT("/") + version, false) < 0) + { + + // Basic details + servername = wxT("localhost"); + cnf->Read(version + wxT("/Description"), &description, wxT("EnterpriseDB ") + version); + cnf->Read(version + wxT("/Superuser"), &username, wxEmptyString); + cnf->Read(version + wxT("/Port"), &port, 0); + + // Add the item, if it looks sane + if (port != 0 && username != wxEmptyString) + { + server = new pgServer(servername, wxEmptyString, description, wxEmptyString, wxT("edb"), username, port, false, rolename, 0); + server->iSetDiscoveryID(cnf->GetPath() + wxT("/") + version); + server->iSetDiscovered(true); + groupitem = browser->GetFirstChild(obj->GetId(), groupcookie); + if (!groupitem.IsOk()) + groupitem = browser->AppendItem(obj->GetId(), group, obj->GetIconId()); + browser->AppendItem(groupitem, server->GetFullName(), server->GetIconId(), -1, server); + } + } + } + + flag = cnf->GetNextGroup(version, cookie); + } + + delete cnf; + browser->SortChildren(obj->GetId()); + } + +#endif // !WIN32 + + return server; +} + +#include "images/servers.pngc" +#include "images/server.pngc" +#include "images/server-sm.pngc" +#include "images/serverbad.pngc" +#include "images/serverbad-sm.pngc" + +pgServerFactory::pgServerFactory() + : pgaFactory(__("Server"), __("New Server Registration"), __("Create a new Server registration."), server_png_img, server_sm_png_img) +{ + metaType = PGM_SERVER; + closedId = addIcon(serverbad_png_img); + smallClosedId = addIcon(serverbad_sm_png_img); +} + +pgCollection *pgServerFactory::CreateCollection(pgObject *obj) +{ + return new pgCollection(GetCollectionFactory()); +} + +pgCollection *pgServerObjFactory::CreateCollection(pgObject *obj) +{ + return new pgServerObjCollection(GetCollectionFactory(), (pgServer *)obj); +} + +pgServerFactory serverFactory; +static pgaCollectionFactory cf(&serverFactory, __("Servers"), servers_png_img); + +#include "images/connect.pngc" +addServerFactory::addServerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, _("&Add Server..."), _("Add a connection to a server.")); + toolbar->AddTool(id, _("Add Server"), *connect_png_bmp, _("Add a connection to a server."), wxITEM_NORMAL); +} + + +wxWindow *addServerFactory::StartDialog(frmMain *form, pgObject *obj) +{ + int rc = PGCONN_BAD; + + dlgServer dlg(&serverFactory, form, 0); + dlg.CenterOnParent(); + + while (rc != PGCONN_OK) + { + if (dlg.GoNew() != wxID_OK) + return 0; + + pgServer *server = (pgServer *)dlg.CreateObject(0); + + if (dlg.GetTryConnect()) + { + wxBusyInfo waiting(wxString::Format(_("Connecting to server %s (%s:%d)"), + server->GetDescription().c_str(), server->GetName().c_str(), server->GetPort()), form); + + // Give the UI a chance to redraw + wxSafeYield(); + wxMilliSleep(100); + wxSafeYield(); + + rc = server->Connect(form, false, dlg.GetPassword(), true); + } + else + { + rc = PGCONN_OK; + server->InvalidatePassword(); + } + switch (rc) + { + case PGCONN_OK: + { + int icon; + ctlTree *browser = form->GetBrowser(); + wxTreeItemId groupitem, parentitem; + wxTreeItemIdValue groupcookie; + int total; + wxString label; + + if (server->GetConnected()) + icon = serverFactory.GetIconId(); + else + icon = serverFactory.GetClosedIconId(); + wxLogInfo(wxT("pgServer object initialised as required.")); + + // Add the new server in its group + wxString group = server->GetGroup(); + if (group.Length() == 0) + group = _("Servers"); + + // Get the parent group + groupitem = browser->GetFirstChild(browser->GetRootItem(), groupcookie); + while (!parentitem && groupitem) + { + if (browser->GetItemText(groupitem).StartsWith(group)) + parentitem = groupitem; + groupitem = browser->GetNextChild(browser->GetRootItem(), groupcookie); + } + + if (!parentitem) + parentitem = browser->AppendItem(browser->GetRootItem(), group, icon, -1); + + browser->AppendItem(parentitem, server->GetFullName(), icon, -1, server); + browser->SortChildren(parentitem); + browser->Expand(parentitem); + + total = browser->GetChildrenCount(parentitem, false); + label = group + wxT(" (") + NumToStr((long)total) + wxT(")"); + browser->SetItemText(parentitem, label); + + form->StoreServers(); + return 0; + } + case PGCONN_DNSERR: + { + delete server; + break; + } + case PGCONN_BAD: + case PGCONN_BROKEN: + { + form->ReportConnError(server); + delete server; + + break; + } + case PGCONN_SSHTUNNEL_ERROR: + { + delete server; + break; + } + default: + { + wxLogInfo(__("pgServer object didn't initialise because the user aborted.")); + delete server; + return 0; + } + } + } + return 0; +} + + +startServiceFactory::startServiceFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Start Service"), _("Start PostgreSQL Service")); +} + + +wxWindow *startServiceFactory::StartDialog(frmMain *form, pgObject *obj) +{ + pgServer *server = (pgServer *)obj; + form->StartMsg(_("Starting Service")); + bool rc = server->StartService(); + if (rc) + form->execSelChange(server->GetId(), true); + form->EndMsg(rc); + return 0; +} + + +bool startServiceFactory::CheckEnable(pgObject *obj) +{ + if (obj && obj->IsCreatedBy(serverFactory)) + { + pgServer *server = (pgServer *)obj; + return server->GetServerControllable() && !server->GetServerRunning(); + } + return false; +} + + +stopServiceFactory::stopServiceFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Stop Service"), _("Stop PostgreSQL Service")); +} + + +wxWindow *stopServiceFactory::StartDialog(frmMain *form, pgObject *obj) +{ + pgServer *server = (pgServer *)obj; + wxMessageDialog msg(form, _("Are you sure you wish to shutdown this server?"), + _("Stop Service"), wxYES_NO | wxICON_QUESTION); + if (msg.ShowModal() == wxID_YES) + { + form->StartMsg(_("Stopping service")); + + bool done = server->StopService(); + + if (done) + { + if (server->Disconnect(form)) + { + form->GetBrowser()->DeleteChildren(server->GetId()); + form->execSelChange(server->GetId(), true); + } + } + form->EndMsg(done); + } + + return 0; +} + + +bool stopServiceFactory::CheckEnable(pgObject *obj) +{ + if (obj && obj->IsCreatedBy(serverFactory)) + { + pgServer *server = (pgServer *)obj; + return server->GetServerControllable() && server->GetServerRunning(); + } + return false; +} + + +connectServerFactory::connectServerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Connect"), _("Connect to the selected server.")); +} + + +wxWindow *connectServerFactory::StartDialog(frmMain *form, pgObject *obj) +{ + pgServer *server = (pgServer *)obj; + form->ReconnectServer(server); + return 0; +} + + +bool connectServerFactory::CheckEnable(pgObject *obj) +{ + if (obj && obj->IsCreatedBy(serverFactory)) + return !((pgServer *)obj)->GetConnected(); + + return false; +} + + +disconnectServerFactory::disconnectServerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Disconnec&t server"), _("Disconnect from the selected server.")); +} + + +wxWindow *disconnectServerFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (obj->CheckOpenDialogs(form->GetBrowser(), form->GetBrowser()->GetSelection())) + { + wxString msg = _("There are properties dialogues open for one or more objects belonging to a database which will be disconnected. Please close the properties dialogues and try again."); + wxMessageBox(msg, _("Cannot disconnect database"), wxICON_WARNING | wxOK); + } + else + { + pgServer *server = (pgServer *)obj; + server->Disconnect(form); + server->UpdateIcon(form->GetBrowser()); + form->GetBrowser()->DeleteChildren(obj->GetId()); + form->execSelChange(obj->GetId(), true); + } + + return 0; +} + + +bool disconnectServerFactory::CheckEnable(pgObject *obj) +{ + if (obj && obj->IsCreatedBy(serverFactory)) + return ((pgServer *)obj)->GetConnected(); + + return false; +} + +reloadconfServiceFactory::reloadconfServiceFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Reload configuration"), _("Reload configuration")); +} + + +wxWindow *reloadconfServiceFactory::StartDialog(frmMain *form, pgObject *obj) +{ + pgServer *server = (pgServer *)obj; + form->StartMsg(_("Reloading configuration")); + bool rc = server->ReloadConfiguration(); + form->EndMsg(rc); + return 0; +} + + +bool reloadconfServiceFactory::CheckEnable(pgObject *obj) +{ + if (obj && obj->IsCreatedBy(serverFactory)) + { + pgServer *server = (pgServer *)obj; + return server->GetConnected() && server->connection()->BackendMinimumVersion(8, 1); + } + return false; +} + + +pausereplayServiceFactory::pausereplayServiceFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Pause replay of WAL"), _("Pause replay of WAL")); +} + + +wxWindow *pausereplayServiceFactory::StartDialog(frmMain *form, pgObject *obj) +{ + pgServer *server = (pgServer *)obj; + form->StartMsg(_("Pausing replay of WAL")); + bool rc = server->PauseReplay(); + form->EndMsg(rc); + return 0; +} + + +bool pausereplayServiceFactory::CheckEnable(pgObject *obj) +{ + if (obj && obj->IsCreatedBy(serverFactory)) + { + pgServer *server = (pgServer *)obj; + return server->GetConnected() && + server->connection()->BackendMinimumVersion(9, 1) && + server->GetInRecovery() && + !server->GetReplayPaused(); + } + return false; +} + + +resumereplayServiceFactory::resumereplayServiceFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Resume replay of WAL"), _("Resume replay of WAL")); +} + + +wxWindow *resumereplayServiceFactory::StartDialog(frmMain *form, pgObject *obj) +{ + pgServer *server = (pgServer *)obj; + form->StartMsg(_("Resuming replay of WAL")); + bool rc = server->ResumeReplay(); + form->EndMsg(rc); + return 0; +} + + +bool resumereplayServiceFactory::CheckEnable(pgObject *obj) +{ + if (obj && obj->IsCreatedBy(serverFactory)) + { + pgServer *server = (pgServer *)obj; + return server->GetConnected() && + server->connection()->BackendMinimumVersion(9, 1) && + server->GetInRecovery() && + server->GetReplayPaused(); + } + return false; +} + + +addnamedrestorepointServiceFactory::addnamedrestorepointServiceFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Add named restore point"), _("Add named restore point")); +} + + +wxWindow *addnamedrestorepointServiceFactory::StartDialog(frmMain *form, pgObject *obj) +{ + pgServer *server = (pgServer *)obj; + form->StartMsg(_("Add named restore point")); + bool rc = server->AddNamedRestorePoint(); + form->EndMsg(rc); + return 0; +} + + +bool addnamedrestorepointServiceFactory::CheckEnable(pgObject *obj) +{ + if (obj && obj->IsCreatedBy(serverFactory)) + { + pgServer *server = (pgServer *)obj; + return server->GetConnected() && server->connection()->BackendMinimumVersion(9, 1) && !server->GetInRecovery(); + } + return false; +} \ No newline at end of file diff --git a/schema/pgTable.cpp b/schema/pgTable.cpp new file mode 100644 index 0000000..0ce6cd7 --- /dev/null +++ b/schema/pgTable.cpp @@ -0,0 +1,1956 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgTable.cpp - Table class +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + + +#include "utils/misc.h" +#include "frm/frmHint.h" +#include "frm/frmMain.h" +#include "frm/frmMaintenance.h" +#include "schema/pgTable.h" +#include "schema/pgColumn.h" +#include "schema/pgIndexConstraint.h" +#include "schema/pgForeignKey.h" +#include "schema/pgCheck.h" +#include "utils/sysSettings.h" +#include "utils/pgfeatures.h" +#include "schema/pgRule.h" +#include "schema/pgTrigger.h" +#include "schema/pgConstraints.h" +#include "schema/gpPartition.h" +#include "schema/pgPartition.h" + + +// App headers + +pgTable::pgTable(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, tableFactory, newName) +{ + Init(); +} + +pgTable::pgTable(pgSchema *newSchema, pgaFactory &newFactory, const wxString &newName) + : pgSchemaObject(newSchema, newFactory, newName) +{ + Init(); +} + +pgTable::~pgTable() +{ +} + + +void pgTable::Init() +{ + rows = 0; + estimatedRows = 0.0; + + hasToastTable = false; + autovacuum_enabled = 0; + toast_autovacuum_enabled = 0; + + isPartitioned = false; + hasOids = false; + unlogged = false; + hasSubclass = false; + rowsCounted = false; + isReplicated = false; + showExtendedStatistics = false; + distributionIsRandom = false; + + inheritedTableCount = 0; + triggerCount = 0; + + tablespaceOid = 0; + ofTypeOid = 0; +} + + +wxString pgTable::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on table"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing table"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop table \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop table \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop table cascaded?"); + break; + case DROPTITLE: + message = _("Drop table?"); + break; + case PROPERTIESREPORT: + message = _("Table properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Table properties"); + break; + case DDLREPORT: + message = _("Table DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Table DDL"); + break; + case DATADICTIONNARYREPORT: + message = _("Table Data dictionary report"); + message += wxT(" - ") + GetName(); + break; + case STATISTICSREPORT: + message = _("Table statistics report"); + message += wxT(" - ") + GetName(); + break; + case OBJSTATISTICS: + message = _("Table statistics"); + break; + case DEPENDENCIESREPORT: + message = _("Table dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Table dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Table dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Table dependents"); + break; + case BACKUPTITLE: + message = wxString::Format(_("Backup table \"%s\""), + GetFullIdentifier().c_str()); + break; + case RESTORETITLE: + message = wxString::Format(_("Restore table \"%s\""), + GetFullIdentifier().c_str()); + break; + } + + return message; +} + + +int pgTable::GetIconId() +{ + if (isReplicated) + return tableFactory.GetReplicatedIconId(); + else + if (!GetPartKeyDef().IsEmpty()) return tableFactory.GetPartitionsIconId(); + else + return tableFactory.GetIconId(); +} + + +wxMenu *pgTable::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + if (schema->GetCreatePrivilege()) + { + columnFactory.AppendMenu(menu); + if (GetPrimaryKey().IsEmpty()) // Will not notice if pk has been added after last refresh + primaryKeyFactory.AppendMenu(menu); + foreignKeyFactory.AppendMenu(menu); + excludeFactory.AppendMenu(menu); + uniqueFactory.AppendMenu(menu); + checkFactory.AppendMenu(menu); + indexFactory.AppendMenu(menu); + ruleFactory.AppendMenu(menu); + triggerFactory.AppendMenu(menu); + + /* + * TEMPORARY: Disable adding new partitions until that code is working right. + * + if (GetConnection() != 0 && GetConnection()->GetIsGreenplum() && GetIsPartitioned()) + partitionFactory.AppendMenu(menu); + */ + } + return menu; +} + + +int pgTable::GetReplicationStatus(ctlTree *browser, wxString *clusterName, long *setId) +{ + wxArrayString clusters = GetDatabase()->GetSlonyClusters(browser); + + bool isSubscribed = false; + + size_t i; + for (i = 0 ; i < clusters.GetCount() ; i++) + { + wxString nsp = qtIdent(wxT("_") + clusters.Item(i)); + + pgSetIterator sets(GetConnection(), + wxT("SELECT tab_set, sub_provider, ") + nsp + wxT(".getlocalnodeid(") + qtDbString(wxT("_") + clusters.Item(i)) + wxT(") AS localnode\n") + wxT(" FROM ") + nsp + wxT(".sl_table\n") + wxT(" LEFT JOIN ") + nsp + wxT(".sl_subscribe ON sub_set=tab_set\n") + wxT(" WHERE tab_reloid = ") + GetOidStr()); + + if (sets.RowsLeft()) + { + if (clusterName) + *clusterName = clusters.Item(i); + if (setId) + *setId = sets.GetLong(wxT("tab_set")); + if (isSubscribed) + return REPLICATIONSTATUS_MULTIPLY_PUBLISHED; + + long provider = sets.GetLong(wxT("sub_provider")); + if (provider) + { + if (provider != sets.GetLong(wxT("localnode"))) + return REPLICATIONSTATUS_REPLICATED; + + isSubscribed = true; + + } + } + } + if (isSubscribed) + return REPLICATIONSTATUS_SUBSCRIBED; + + return REPLICATIONSTATUS_NONE; +} + + +wxString pgTable::GetHelpPage(bool forCreate) const +{ + if (forCreate) + return wxT("pg/sql-createtable"); + else + return wxT("pg/sql-altertable"); +} + + +bool pgTable::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP TABLE ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +bool pgTable::Truncate(bool cascaded) +{ + wxString sql = wxT("TRUNCATE TABLE ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +bool pgTable::ResetStats() +{ + wxString sql = wxT("SELECT pg_stat_reset_single_table_counters(") + + NumToStr(this->GetOid()) + + wxT(")"); + return GetDatabase()->ExecuteVoid(sql); +} + + +void pgTable::AppendStuff(wxString &sql, ctlTree *browser, pgaFactory &factory) +{ + wxString tmp; + + pgCollection *collection = browser->FindCollection(factory, GetId()); + if (collection) + { + tmp += wxT("\n"); + collection->ShowTreeDetail(browser); + + treeObjectIterator idxIt(browser, collection); + pgObject *obj; + while ((obj = idxIt.GetNextObject()) != 0) + { + obj->ShowTreeDetail(browser); + + tmp += obj->GetSql(browser) + wxT("\n"); + } + } + + if (!tmp.IsEmpty() && tmp != wxT("\n")) + sql += tmp; +} + +void pgTable::AppendStuffNoSql(wxString &sql, ctlTree *browser, pgaFactory &factory) +{ + pgCollection *collection = browser->FindCollection(factory, GetId()); + if (collection) + { + collection->ShowTreeDetail(browser); + + treeObjectIterator idxIt(browser, collection); + pgObject *obj; + while ((obj = idxIt.GetNextObject()) != 0) + { + obj->ShowTreeDetail(browser); + } + } +} + + + +wxString pgTable::GetSql(ctlTree *browser) +{ + wxString colDetails, conDetails; + wxString prevComment; + wxString cols_sql = wxEmptyString; + + wxString columnPrivileges; + + if (sql.IsNull()) + { + // make sure all kids are appended + ShowTreeDetail(browser); + sql = wxT("-- Table: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP TABLE ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE "); + if (GetUnlogged()) + sql += wxT("UNLOGGED "); + sql += wxT("TABLE ") + GetQuotedFullIdentifier(); + + // of type (9.0 material) + if (ofTypeOid > 0) + sql += wxT("\nOF ") + qtIdent(ofType); + + // Get a count of the constraints. + int consCount = 0; + pgCollection *constraints = browser->FindCollection(primaryKeyFactory, GetId()); + if (constraints) + consCount = browser->GetChildrenCount(constraints->GetId()); + + // Get the columns + pgCollection *columns = browser->FindCollection(columnFactory, GetId()); + if (columns) + { + columns->ShowTreeDetail(browser); + treeObjectIterator colIt1(browser, columns); + treeObjectIterator colIt2(browser, columns); + + + int lastRealCol = 0; + int currentCol = 0; + pgColumn *column; + + // Iterate the columns to find the last 'real' one + while ((column = (pgColumn *)colIt1.GetNextObject()) != 0) + { + currentCol++; + + if (column->GetInheritedCount() == 0) + lastRealCol = currentCol; + } + + // Now build the actual column list + int colCount = 0; + while ((column = (pgColumn *)colIt2.GetNextObject()) != 0) + { + column->ShowTreeDetail(browser); + if (column->GetColNumber() > 0) + { + if (colCount) + { + // Only add a comma if this isn't the last 'real' column, or if there are constraints + if (colCount != lastRealCol || consCount) + cols_sql += wxT(","); + if (!prevComment.IsEmpty()) + cols_sql += wxT(" -- ") + firstLineOnly(prevComment); + + cols_sql += wxT("\n"); + } + + if (column->GetInheritedCount() > 0) + { + if (!column->GetIsLocal()) + { + cols_sql += wxString::Format(wxT("-- %s "), _("Inherited")) + + wxT("from table ") + column->GetInheritedTableName() + wxT(":"); + } + } + + if (ofTypeOid > 0) + { + if (column->GetDefinition().Length() == 0) + { + cols_sql += wxString::Format(wxT("-- %s "), _("Inherited")) + + wxT("from type ") + ofType + wxT(": ") + + column->GetQuotedIdentifier(); + } + else + { + cols_sql += wxT(" ") + column->GetQuotedIdentifier() + wxT(" WITH OPTIONS ") + + column->GetDefinition(); + } + } + else + { + cols_sql += wxT(" ") + column->GetQuotedIdentifier() + wxT(" ") + + column->GetDefinition(); + } + + prevComment = column->GetComment(); + + // Whilst we are looping round the columns, grab their comments as well. + colDetails += column->GetCommentSql(); + if (colDetails.Length() > 0) + if (colDetails.Last() != '\n') + colDetails += wxT("\n"); + colDetails += column->GetStorageSql(); + if (colDetails.Length() > 0) + if (colDetails.Last() != '\n') + colDetails += wxT("\n"); + colDetails += column->GetAttstattargetSql(); + if (colDetails.Length() > 0) + if (colDetails.Last() != '\n') + colDetails += wxT("\n"); + colDetails += column->GetVariablesSql(); + if (colDetails.Length() > 0) + if (colDetails.Last() != '\n') + colDetails += wxT("\n"); + + colCount++; + columnPrivileges += column->GetPrivileges(); + } + } + } + + // Now iterate the constraints + if (constraints) + { + constraints->ShowTreeDetail(browser); + treeObjectIterator consIt(browser, constraints); + + pgObject *data; + + while ((data = consIt.GetNextObject()) != 0) + { + data->ShowTreeDetail(browser); + + cols_sql += wxT(","); + + if (!prevComment.IsEmpty()) + cols_sql += wxT(" -- ") + firstLineOnly(prevComment); + + cols_sql += wxT("\n CONSTRAINT ") + data->GetQuotedIdentifier() + + wxT(" ") + data->GetTypeName().Upper() + + wxT(" ") ; + + prevComment = data->GetComment(); + if (!data->GetComment().IsEmpty()) + conDetails += wxT("COMMENT ON CONSTRAINT ") + data->GetQuotedIdentifier() + + wxT(" ON ") + GetQuotedFullIdentifier() + + wxT(" IS ") + qtDbString(data->GetComment()) + wxT(";\n"); + + switch (data->GetMetaType()) + { + case PGM_PRIMARYKEY: + case PGM_UNIQUE: + case PGM_EXCLUDE: + cols_sql += ((pgIndexConstraint *)data)->GetDefinition(); + break; + case PGM_FOREIGNKEY: + cols_sql += ((pgForeignKey *)data)->GetDefinition(); + break; + case PGM_CHECK: + cols_sql += wxT("(") + ((pgCheck *)data)->GetDefinition() + wxT(")"); + if (GetDatabase()->BackendMinimumVersion(9, 2) && ((pgCheck *)data)->GetNoInherit()) + cols_sql += wxT(" NO INHERIT"); + if (GetDatabase()->BackendMinimumVersion(9, 2) && !((pgCheck *)data)->GetValid()) + cols_sql += wxT(" NOT VALID"); + break; + } + } + } + if (!prevComment.IsEmpty()) + cols_sql += wxT(" -- ") + firstLineOnly(prevComment); + if (GetConnection()->BackendMinimumVersion(10, 0)&&!GetPartExp().IsEmpty()) + { + sql += wxT("\n PARTITION OF ") + GetQuotedInheritedTables() + wxT("(\n") + cols_sql + wxT("\n)"); + sql += wxT(" ") + GetPartExp() + wxT(" "); + } else + { + sql += wxT("\n(\n") + cols_sql + wxT("\n)"); + } + if (GetInheritedTableCount()) + { + if (GetConnection()->BackendMinimumVersion(10, 0)&&!GetPartExp().IsEmpty()) { + + } else + { + sql += wxT("\nINHERITS (") + GetQuotedInheritedTables() + wxT(")"); + } + } + if (GetConnection()->BackendMinimumVersion(10, 0)&&!GetPartKeyDef().IsEmpty()) + { + sql += wxT("\nPARTITION BY ") + GetPartKeyDef() + wxT(" "); + } + if (GetConnection()->BackendMinimumVersion(8, 2)) + { + sql += wxT("\nWITH ("); + if (GetFillFactor().Length() > 0) + sql += wxT("\n FILLFACTOR=") + GetFillFactor() + wxT(", "); + if (GetAppendOnly().Length() > 0) + sql += wxT("APPENDONLY=") + GetAppendOnly() + wxT(", "); + if (GetCompressLevel().Length() > 0) + sql += wxT("COMPRESSLEVEL=") + GetCompressLevel() + wxT(", "); + if (GetOrientation().Length() > 0) + sql += wxT("ORIENTATION=") + GetOrientation() + wxT(", "); + if (GetCompressType().Length() > 0) + sql += wxT("COMPRESSTYPE=") + GetCompressType() + wxT(", "); + if (GetBlocksize().Length() > 0) + sql += wxT("BLOCKSIZE=") + GetBlocksize() + wxT(", "); + if (GetChecksum().Length() > 0) + sql += wxT("CHECKSUM=") + GetChecksum() + wxT(", "); + if (GetHasOids()) + sql += wxT("\n OIDS=TRUE"); + else + sql += wxT("\n OIDS=FALSE"); + if(GetConnection()->BackendMinimumVersion(8, 4)) + { + if (GetCustomAutoVacuumEnabled()) + { + if (GetAutoVacuumEnabled() == 1) + sql += wxT(",\n autovacuum_enabled=true"); + else if (GetCustomAutoVacuumEnabled() == 0) + sql += wxT(",\n autovacuum_enabled=false"); + if (!GetAutoVacuumVacuumThreshold().IsEmpty()) + { + sql += wxT(",\n autovacuum_vacuum_threshold=") + GetAutoVacuumVacuumThreshold(); + } + if (!GetAutoVacuumVacuumScaleFactor().IsEmpty()) + { + sql += wxT(",\n autovacuum_vacuum_scale_factor=") + GetAutoVacuumVacuumScaleFactor(); + } + if (!GetAutoVacuumAnalyzeThreshold().IsEmpty()) + { + sql += wxT(",\n autovacuum_analyze_threshold=") + GetAutoVacuumAnalyzeThreshold(); + } + if (!GetAutoVacuumAnalyzeScaleFactor().IsEmpty()) + { + sql += wxT(",\n autovacuum_analyze_scale_factor=") + GetAutoVacuumAnalyzeScaleFactor(); + } + if (!GetAutoVacuumVacuumCostDelay().IsEmpty()) + { + sql += wxT(",\n autovacuum_vacuum_cost_delay=") + GetAutoVacuumVacuumCostDelay(); + } + if (!GetAutoVacuumVacuumCostLimit().IsEmpty()) + { + sql += wxT(",\n autovacuum_vacuum_cost_limit=") + GetAutoVacuumVacuumCostLimit(); + } + if (!GetAutoVacuumFreezeMinAge().IsEmpty()) + { + sql += wxT(",\n autovacuum_freeze_min_age=") + GetAutoVacuumFreezeMinAge(); + } + if (!GetAutoVacuumFreezeMaxAge().IsEmpty()) + { + sql += wxT(",\n autovacuum_freeze_max_age=") + GetAutoVacuumFreezeMaxAge(); + } + if (!GetAutoVacuumFreezeTableAge().IsEmpty()) + { + sql += wxT(",\n autovacuum_freeze_table_age=") + GetAutoVacuumFreezeTableAge(); + } + } + if (GetHasToastTable() && GetToastCustomAutoVacuumEnabled()) + { + if (GetToastAutoVacuumEnabled() == 1) + sql += wxT(",\n toast.autovacuum_enabled=true"); + else if (GetToastAutoVacuumEnabled() == 0) + sql += wxT(",\n toast.autovacuum_enabled=false"); + if (!GetToastAutoVacuumVacuumThreshold().IsEmpty()) + { + sql += wxT(",\n toast.autovacuum_vacuum_threshold=") + GetToastAutoVacuumVacuumThreshold(); + } + if (!GetToastAutoVacuumVacuumScaleFactor().IsEmpty()) + { + sql += wxT(",\n toast.autovacuum_vacuum_scale_factor=") + GetToastAutoVacuumVacuumScaleFactor(); + } + if (!GetToastAutoVacuumVacuumCostDelay().IsEmpty()) + { + sql += wxT(",\n toast.autovacuum_vacuum_cost_delay=") + GetToastAutoVacuumVacuumCostDelay(); + } + if (!GetToastAutoVacuumVacuumCostLimit().IsEmpty()) + { + sql += wxT(",\n toast.autovacuum_vacuum_cost_limit=") + GetToastAutoVacuumVacuumCostLimit(); + } + if (!GetToastAutoVacuumFreezeMinAge().IsEmpty()) + { + sql += wxT(",\n toast.autovacuum_freeze_min_age=") + GetToastAutoVacuumFreezeMinAge(); + } + if (!GetToastAutoVacuumFreezeMaxAge().IsEmpty()) + { + sql += wxT(",\n toast.autovacuum_freeze_max_age=") + GetToastAutoVacuumFreezeMaxAge(); + } + if (!GetToastAutoVacuumFreezeTableAge().IsEmpty()) + { + sql += wxT(",\n toast.autovacuum_freeze_table_age=") + GetToastAutoVacuumFreezeTableAge(); + } + } + } + sql += wxT("\n)"); + } + else + { + if (GetHasOids()) + sql += wxT("\nWITH OIDS"); + else + sql += wxT("\nWITHOUT OIDS"); + } + + if (GetConnection()->BackendMinimumVersion(8, 0) && tablespace != GetDatabase()->GetDefaultTablespace()) + sql += wxT("\nTABLESPACE ") + qtIdent(tablespace); + + if (GetConnection()->GetIsGreenplum()) + { + // Add Greenplum DISTRIBUTED BY + if (distributionIsRandom) + { + sql += wxT("\nDISTRIBUTED RANDOMLY"); + } + else if (GetDistributionColNumbers().Length() == 0) + { + // catalog table or other non-distributed table + } + else + { + // convert list of columns numbers to column names + wxStringTokenizer collist(GetDistributionColNumbers(), wxT(",")); + wxString cn; + wxString distributionColumns; + while (collist.HasMoreTokens()) + { + cn = collist.GetNextToken(); + pgSet *set = ExecuteSet( + wxT("SELECT attname\n") + wxT(" FROM pg_attribute\n") + wxT(" WHERE attrelid=") + GetOidStr() + wxT(" AND attnum IN (") + cn + wxT(")")); + if (set) + { + if (!distributionColumns.IsNull()) + { + distributionColumns += wxT(", "); + } + distributionColumns += qtIdent(set->GetVal(0)); + delete set; + } + } + + sql += wxT("\nDISTRIBUTED BY ("); + sql += distributionColumns; + + sql += wxT(")"); + } + + if (GetIsPartitioned()) + if (GetConnection()->BackendMinimumVersion(8, 2, 9) && GetConnection()->GetIsGreenplum()) + if (GetPartitionDef().Length() == 0) + { + wxString query = wxT("SELECT pg_get_partition_def("); + query += GetOidStr(); + query += wxT(", true) "); + wxString partition_def = GetDatabase()->ExecuteScalar(query); + iSetPartitionDef(partition_def); + // pg_get_partition_def() doesn't work on partitions + if (GetPartitionDef().Length() == 0) + iSetPartitionDef(wxT("-- This partition has subpartitions")); + } + if (partitionDef.Length() > 0) + sql += wxT("\n") + partitionDef + wxT("\n"); + + + } + + + sql += wxT(";\n") + + GetOwnerSql(7, 3); + + if (GetConnection()->BackendMinimumVersion(8, 4)) + sql += GetGrant(wxT("arwdDxt")); + else if (GetConnection()->BackendMinimumVersion(8, 2)) + sql += GetGrant(wxT("arwdxt")); + else + sql += GetGrant(wxT("arwdRxt")); + + sql += GetCommentSql(); + + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += GetSeqLabelsSql(); + + // Column/constraint comments + if (!colDetails.IsEmpty()) + sql += colDetails + wxT("\n"); + + if (!conDetails.IsEmpty()) + sql += conDetails + wxT("\n"); + + if (!columnPrivileges.IsEmpty()) + { + sql += columnPrivileges + wxT("\n"); + } + + AppendStuff(sql, browser, indexFactory); + AppendStuff(sql, browser, ruleFactory); + AppendStuff(sql, browser, triggerFactory); + + /* + * Disable adding partitions until that code works. + * + if (partitionDef.Length() > 0) + { + AppendStuffNoSql(sql, browser, partitionFactory); + } + */ + } + return sql; +} + +wxString pgTable::GetCoveringIndex(ctlTree *browser, const wxString &collist) +{ + // delivers the name of the index which covers the named columns + wxCookieType cookie; + + wxTreeItemId collItem = browser->GetFirstChild(GetId(), cookie); + while (collItem) + { + pgObject *data = browser->GetObject(collItem); + if (data && data->IsCollection() && (data->GetMetaType() == PGM_CONSTRAINT || data->GetMetaType() == PGM_INDEX)) + { + wxCookieType cookie2; + wxTreeItemId item = browser->GetFirstChild(collItem, cookie2); + while (item) + { + pgIndex *index = (pgIndex *)browser->GetObject(item); + if (index && (index->GetMetaType() == PGM_INDEX || index->GetMetaType() == PGM_PRIMARYKEY + || index->GetMetaType() == PGM_UNIQUE || index->GetMetaType() == PGM_EXCLUDE)) + { + index->ShowTreeDetail(browser); + if (collist == index->GetColumns() || + collist + wxT(",") == index->GetColumns().Left(collist.Length() + 1)) + return index->GetName(); + } + item = browser->GetNextChild(collItem, cookie2); + } + } + collItem = browser->GetNextChild(GetId(), cookie); + } + + return wxEmptyString; +} + + +wxString pgTable::GetCols(ctlTree *browser, size_t indent, wxString &QMs, bool withQM) +{ + wxString sql; + wxString line; + + int colcount = 0; + pgCollection *columns = browser->FindCollection(columnFactory, GetId()); + if (columns) + { + columns->ShowTreeDetail(browser); + treeObjectIterator colIt(browser, columns); + + pgColumn *column; + while ((column = (pgColumn *)colIt.GetNextObject()) != 0) + { + column->ShowTreeDetail(browser); + if (column->GetColNumber() > 0) + { + if (colcount++) + { + line += wxT(", "); + QMs += wxT(", "); + } + if (line.Length() > 60) + { + if (!sql.IsEmpty()) + { + sql += wxT("\n") + wxString(' ', indent); + } + sql += line; + line = wxEmptyString; + QMs += wxT("\n") + wxString(' ', indent); + } + + line += column->GetQuotedIdentifier(); + if (withQM) + line += wxT("=?"); + QMs += wxT("?"); + } + } + } + + if (!line.IsEmpty()) + { + if (!sql.IsEmpty()) + sql += wxT("\n") + wxString(' ', indent); + sql += line; + } + return sql; +} + +pgCollection *pgTable::GetColumnCollection(ctlTree *browser) +{ + pgCollection *columns = browser->FindCollection(columnFactory, GetId()); + return columns; +} + +pgCollection *pgTable::GetConstraintCollection(ctlTree *browser) +{ + pgCollection *constraints = browser->FindCollection(constraintFactory, GetId()); + return constraints; +} + +wxString pgTable::GetSelectSql(ctlTree *browser) +{ + wxString qms; + wxString sql = + wxT("SELECT ") + GetCols(browser, 7, qms, false) + wxT("\n") + wxT(" FROM ") + GetQuotedFullIdentifier() + wxT(";\n"); + return sql; +} + + +wxString pgTable::GetInsertSql(ctlTree *browser) +{ + wxString qms; + wxString sql = + wxT("INSERT INTO ") + GetQuotedFullIdentifier() + wxT("(\n") + wxT(" ") + GetCols(browser, 12, qms, false) + wxT(")\n") + wxT(" VALUES (") + qms + wxT(");\n"); + return sql; +} + + +wxString pgTable::GetUpdateSql(ctlTree *browser) +{ + wxString qms; + wxString sql = + wxT("UPDATE ") + GetQuotedFullIdentifier() + wxT("\n") + wxT(" SET ") + GetCols(browser, 7, qms, true) + wxT("\n") + wxT(" WHERE ;\n"); + return sql; +} + +wxString pgTable::GetDeleteSql(ctlTree *browser) +{ + wxString sql = + wxT("DELETE FROM ") + GetQuotedFullIdentifier() + wxT("\n") + wxT(" WHERE ;\n"); + return sql; +} + +bool pgTable::EnableTriggers(const bool b) +{ + wxString sql = wxT("ALTER TABLE ") + GetQuotedFullIdentifier() + wxT(" "); + + if (!b) + sql += wxT("DISABLE"); + else + sql += wxT("ENABLE"); + + sql += wxT(" TRIGGER ALL"); + + return GetDatabase()->ExecuteVoid(sql); +} + +void pgTable::UpdateRows() +{ + pgSet *props = ExecuteSet(wxT("SELECT count(*) AS rows FROM ONLY ") + GetQuotedFullIdentifier()); + if (props) + { + rows = props->GetLongLong(0); + delete props; + rowsCounted = true; + } +} + + +void pgTable::UpdateInheritance() +{ + // not checked so far + pgSet *props = ExecuteSet( + wxT("SELECT c.oid, c.relname , nspname\n") + wxT(" FROM pg_inherits i\n") + wxT(" JOIN pg_class c ON c.oid = i.inhparent\n") + wxT(" JOIN pg_namespace n ON n.oid=c.relnamespace\n") + wxT(" WHERE i.inhrelid = ") + GetOidStr() + wxT("\n") + wxT(" ORDER BY inhseqno")); + if (props) + { + inheritedTableCount = 0; + inheritedTables = wxT(""); + while (!props->Eof()) + { + if (inheritedTableCount) + { + inheritedTables += wxT(", "); + quotedInheritedTables += wxT(", "); + } + inheritedTables += props->GetVal(wxT("relname")); + quotedInheritedTables += GetQuotedSchemaPrefix(props->GetVal(wxT("nspname"))) + + qtIdent(props->GetVal(wxT("relname"))); + quotedInheritedTablesList.Add(GetQuotedSchemaPrefix(props->GetVal(wxT("nspname"))) + + qtIdent(props->GetVal(wxT("relname")))); + inheritedTablesOidList.Add(props->GetVal(wxT("oid"))); + props->MoveNext(); + inheritedTableCount++; + } + delete props; + } +} + + + + + +void pgTable::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + + // Log + wxLogInfo(wxT("Adding child object to table %s"), GetIdentifier().c_str()); + + browser->AppendCollection(this, columnFactory); + browser->AppendCollection(this, constraintFactory); + browser->AppendCollection(this, indexFactory); + browser->AppendCollection(this, ruleFactory); + browser->AppendCollection(this, triggerFactory); + + if (GetConnection() != 0 && GetConnection()->GetIsGreenplum() && GetIsPartitioned()) + browser->AppendCollection(this, partitionFactory); + + if (GetConnection() != 0 && !GetPartKeyDef().IsEmpty()) + browser->AppendCollection(this, pg_partitionFactory); + + + // convert list of columns numbers to column names + wxStringTokenizer collist(GetPrimaryKeyColNumbers(), wxT(",")); + wxString cn; + + while (collist.HasMoreTokens()) + { + cn = collist.GetNextToken(); + pgSet *set = ExecuteSet( + wxT("SELECT attname\n") + wxT(" FROM pg_attribute\n") + wxT(" WHERE attrelid=") + GetOidStr() + wxT(" AND attnum IN (") + cn + wxT(")")); + if (set) + { + if (!primaryKey.IsNull()) + { + quotedPrimaryKey += wxT(", "); + primaryKey += wxT(", "); + } + primaryKey += set->GetVal(0); + quotedPrimaryKey += qtIdent(set->GetVal(0)); + delete set; + } + } + + if (settings->GetAutoRowCountThreshold() >= GetEstimatedRows()) + UpdateRows(); + + UpdateInheritance(); + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + if (GetConnection() != 0 && GetConnection()->GetIsGreenplum()) + { + gpPartition *p = dynamic_cast(this); + if (p != 0) + properties->AppendItem(_("Partition Name"), p->GetPartitionName()); + } + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + if (GetConnection()->BackendMinimumVersion(8, 0)) + properties->AppendItem(_("Tablespace"), tablespace); + properties->AppendItem(_("ACL"), GetAcl()); + if (GetConnection()->BackendMinimumVersion(9, 0)) + properties->AppendItem(_("Of type"), ofType); + if (GetPrimaryKey().IsNull()) + properties->AppendItem(_("Primary key"), _("")); + else + properties->AppendItem(_("Primary key"), GetPrimaryKey()); + + properties->AppendItem(_("Rows (estimated)"), GetEstimatedRows()); + + if (GetConnection()->BackendMinimumVersion(8, 2)) + properties->AppendItem(_("Fill factor"), GetFillFactor()); + + if (rowsCounted) + properties->AppendItem(_("Rows (counted)"), rows); + else + properties->AppendItem(_("Rows (counted)"), _("not counted")); + + long setId; + wxString clusterName; + long repStat = GetReplicationStatus(browser, &clusterName, &setId); + + wxString clusterInfo; + clusterInfo.Printf(_("Cluster \"%s\", set %ld"), clusterName.c_str(), setId); + + wxString repString; + switch (repStat) + { + case REPLICATIONSTATUS_SUBSCRIBED: + repString = _("Published"); + break; + case REPLICATIONSTATUS_REPLICATED: + repString = _("Replicated"); + break; + case REPLICATIONSTATUS_MULTIPLY_PUBLISHED: + repString = _("Replicated"); + clusterName = _("Multiple clusters"); + break; + default: + break; + } + if (!repString.IsEmpty()) + properties->AppendItem(repString, clusterInfo); + + properties->AppendYesNoItem(_("Inherits tables"), GetHasSubclass()); + properties->AppendItem(_("Inherited tables count"), GetInheritedTableCount()); + if (GetInheritedTableCount()) + properties->AppendItem(_("Inherited tables"), GetInheritedTables()); + if (GetConnection()->BackendMinimumVersion(9, 1)) + properties->AppendYesNoItem(_("Unlogged?"), GetUnlogged()); + properties->AppendYesNoItem(_("Has OIDs?"), GetHasOids()); + properties->AppendYesNoItem(_("System table?"), GetSystemObject()); + + /* Custom AutoVacuum Settings */ + if (GetConnection()->BackendMinimumVersion(8, 4) && GetCustomAutoVacuumEnabled()) + { + if (GetAutoVacuumEnabled() != 2) + { + properties->AppendItem(_("Table auto-vacuum enabled?"), GetAutoVacuumEnabled() == 1 ? _("Yes") : _("No")); + } + if (!GetAutoVacuumVacuumThreshold().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum VACUUM base threshold"), GetAutoVacuumVacuumThreshold()); + if (!GetAutoVacuumVacuumScaleFactor().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum VACUUM scale factor"), GetAutoVacuumVacuumScaleFactor()); + if (!GetAutoVacuumAnalyzeThreshold().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum ANALYZE base threshold"), GetAutoVacuumAnalyzeThreshold()); + if (!GetAutoVacuumAnalyzeScaleFactor().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum ANALYZE scale factor"), GetAutoVacuumAnalyzeScaleFactor()); + if (!GetAutoVacuumVacuumCostDelay().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum VACUUM cost delay"), GetAutoVacuumVacuumCostDelay()); + if (!GetAutoVacuumVacuumCostLimit().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum VACUUM cost limit"), GetAutoVacuumVacuumCostLimit()); + if (!GetAutoVacuumFreezeMinAge().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum FREEZE minimum age"), GetAutoVacuumFreezeMinAge()); + if (!GetAutoVacuumFreezeMaxAge().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum FREEZE maximum age"), GetAutoVacuumFreezeMaxAge()); + if (!GetAutoVacuumFreezeTableAge().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum FREEZE table age"), GetAutoVacuumFreezeTableAge()); + } + + /* Custom TOAST-TABLE AutoVacuum Settings */ + if (GetConnection()->BackendMinimumVersion(8, 4) && + GetHasToastTable() && + GetToastCustomAutoVacuumEnabled()) + { + if (GetToastAutoVacuumEnabled() != 2) + { + properties->AppendItem(_("Toast auto-vacuum enabled?"), GetToastAutoVacuumEnabled() == 1 ? _("Yes") : _("No")); + } + if (!GetToastAutoVacuumVacuumThreshold().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum VACUUM base threshold"), GetToastAutoVacuumVacuumThreshold()); + if (!GetToastAutoVacuumVacuumScaleFactor().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum VACUUM scale factor"), GetToastAutoVacuumVacuumScaleFactor()); + if (!GetToastAutoVacuumVacuumCostDelay().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum VACUUM cost delay"), GetToastAutoVacuumVacuumCostDelay()); + if (!GetToastAutoVacuumVacuumCostLimit().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum VACUUM cost limit"), GetToastAutoVacuumVacuumCostLimit()); + if (!GetToastAutoVacuumFreezeMinAge().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum FREEZE minimum age"), GetToastAutoVacuumFreezeMinAge()); + if (!GetToastAutoVacuumFreezeMaxAge().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum FREEZE maximum age"), GetToastAutoVacuumFreezeMaxAge()); + if (!GetToastAutoVacuumFreezeTableAge().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum FREEZE table age"), GetToastAutoVacuumFreezeTableAge()); + } + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + if (!GetLabels().IsEmpty()) + { + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); + } + } + } + } + if (form && GetVacuumHint() && !hintShown) + { + ShowHint(form, false); + } +} + + +bool pgTable::GetCanHint() +{ + return (GetVacuumHint() || primaryKey.IsEmpty()); +} + + +bool pgTable::GetVacuumHint() +{ + bool canHint = false; + + if (rowsCounted) + { + if (!estimatedRows || (estimatedRows == 1000 && rows.GetValue() != 1000)) + canHint = (rows >= 20); + else + { + double rowsDbl = (wxLongLong_t)rows.GetValue(); + double quot = rowsDbl * 10. / estimatedRows; + canHint = ((quot > 12 || quot < 8) && (rowsDbl < estimatedRows - 20. || rowsDbl > estimatedRows + 20.)); + } + } + else if (estimatedRows == 1000) + { + canHint = true; + } + return canHint; +} + + +void pgTable::ShowHint(frmMain *form, bool force) +{ + hintShown = true; + int rc; + + if (force) + { + wxArrayString hints; + if (GetVacuumHint()) + hints.Add(HINT_VACUUM); + if (primaryKey.IsEmpty()) + hints.Add(HINT_PRIMARYKEY); + + rc = frmHint::ShowHint(form, hints, GetFullIdentifier(), force); + } + else + rc = frmHint::ShowHint(form, HINT_VACUUM, GetFullIdentifier(), force); + + if (rc == HINT_RC_FIX) + { + frmMaintenance *frm = new frmMaintenance(form, this); + frm->Go(); + } +} + + + + +pgObject *pgTable::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgTable *table = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + table = (pgTable *)tableFactory.CreateObjects(coll, 0, wxT("\n AND rel.oid=") + GetOidStr()); + + return table; +} + + +bool pgTable::HasPgstattuple() +{ + return GetConnection()->HasFeature(FEATURE_PGSTATTUPLE); +} + +void pgTable::iSetTriggersEnabled(ctlTree *browser, bool enable) +{ + pgCollection *triggers = browser->FindCollection(triggerFactory, GetId()); + if (triggers) + { + triggers->ShowTreeDetail(browser); + treeObjectIterator trgIt(browser, triggers); + + pgTrigger *trigger; + while ((trigger = (pgTrigger *)trgIt.GetNextObject()) != 0) + { + trigger->SetEnabled(browser, enable); + } + } +} + +/////////////////////////////////////////////////////////// + + +pgTableCollection::pgTableCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgTableCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on tables"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing tables"); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for tables"); + break; + case STATISTICSREPORT: + message = _("Tables statistics report"); + break; + case OBJSTATISTICS: + message = _("Tables statistics"); + break; + case OBJECTSLISTREPORT: + message = _("Tables list report"); + break; + } + + return message; +} + + +void pgTableCollection::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + wxLogInfo(wxT("Displaying statistics for tables on %s"), GetSchema()->GetIdentifier().c_str()); + + bool hasSize = GetConnection()->HasFeature(FEATURE_SIZE); + + // Add the statistics view columns + statistics->ClearAll(); + statistics->AddColumn(_("Table Name")); + statistics->AddColumn(_("Tuples inserted")); + statistics->AddColumn(_("Tuples updated")); + statistics->AddColumn(_("Tuples deleted")); + if (GetConnection()->BackendMinimumVersion(8, 3)) + { + statistics->AddColumn(_("Tuples HOT updated")); + statistics->AddColumn(_("Live tuples")); + statistics->AddColumn(_("Dead tuples")); + } + if (GetConnection()->BackendMinimumVersion(8, 2)) + { + statistics->AddColumn(_("Last vacuum")); + statistics->AddColumn(_("Last autovacuum")); + statistics->AddColumn(_("Last analyze")); + statistics->AddColumn(_("Last autoanalyze")); + } + if (GetConnection()->BackendMinimumVersion(9, 1)) + { + statistics->AddColumn(_("Vacuum counter")); + statistics->AddColumn(_("Autovacuum counter")); + statistics->AddColumn(_("Analyze counter")); + statistics->AddColumn(_("Autoanalyze counter")); + } + if (hasSize) + statistics->AddColumn(_("Size"), 50); + + wxString sql = wxT("SELECT st.relname, n_tup_ins, n_tup_upd, n_tup_del"); + if (GetConnection()->BackendMinimumVersion(8, 3)) + sql += wxT(", n_tup_hot_upd, n_live_tup, n_dead_tup"); + if (GetConnection()->BackendMinimumVersion(8, 2)) + sql += wxT(", last_vacuum, last_autovacuum, last_analyze, last_autoanalyze"); + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += wxT(", vacuum_count, autovacuum_count, analyze_count, autoanalyze_count"); + if (hasSize) + sql += wxT(", pg_size_pretty(pg_relation_size(st.relid)") + wxT(" + CASE WHEN cl.reltoastrelid = 0 THEN 0 ELSE pg_relation_size(cl.reltoastrelid) + COALESCE((SELECT SUM(pg_relation_size(indexrelid)) FROM pg_index WHERE indrelid=cl.reltoastrelid)::int8, 0) END") + wxT(" + COALESCE((SELECT SUM(pg_relation_size(indexrelid)) FROM pg_index WHERE indrelid=st.relid)::int8, 0)) AS size"); + + sql += wxT("\n FROM pg_stat_all_tables st") + wxT(" JOIN pg_class cl on cl.oid=st.relid\n") + wxT(" WHERE schemaname = ") + qtDbString(GetSchema()->GetName()) + + wxT("\n ORDER BY relname"); + + pgSet *stats = GetDatabase()->ExecuteSet(sql); + + if (stats) + { + long pos = 0; + int i; + while (!stats->Eof()) + { + i = 4; + statistics->InsertItem(pos, stats->GetVal(wxT("relname")), PGICON_STATISTICS); + statistics->SetItem(pos, 1, stats->GetVal(wxT("n_tup_ins"))); + statistics->SetItem(pos, 2, stats->GetVal(wxT("n_tup_upd"))); + statistics->SetItem(pos, 3, stats->GetVal(wxT("n_tup_del"))); + if (GetConnection()->BackendMinimumVersion(8, 3)) + { + statistics->SetItem(pos, i++, stats->GetVal(wxT("n_tup_hot_upd"))); + statistics->SetItem(pos, i++, stats->GetVal(wxT("n_live_tup"))); + statistics->SetItem(pos, i++, stats->GetVal(wxT("n_dead_tup"))); + } + if (GetConnection()->BackendMinimumVersion(8, 2)) + { + statistics->SetItem(pos, i++, stats->GetVal(wxT("last_vacuum"))); + statistics->SetItem(pos, i++, stats->GetVal(wxT("last_autovacuum"))); + statistics->SetItem(pos, i++, stats->GetVal(wxT("last_analyze"))); + statistics->SetItem(pos, i++, stats->GetVal(wxT("last_autoanalyze"))); + } + if (GetConnection()->BackendMinimumVersion(9, 1)) + { + statistics->SetItem(pos, i++, stats->GetVal(wxT("vacuum_count"))); + statistics->SetItem(pos, i++, stats->GetVal(wxT("autovacuum_count"))); + statistics->SetItem(pos, i++, stats->GetVal(wxT("analyze_count"))); + statistics->SetItem(pos, i++, stats->GetVal(wxT("autoanalyze_count"))); + } + if (hasSize) + statistics->SetItem(pos, i, stats->GetVal(wxT("size"))); + stats->MoveNext(); + pos++; + } + + delete stats; + } + +} + + +/////////////////////////////////////////////////////////// + + +void pgTable::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + wxString sql = + wxT("SELECT seq_scan AS ") + qtIdent(_("Sequential Scans")) + + wxT(", seq_tup_read AS ") + qtIdent(_("Sequential Tuples Read")) + + wxT(", idx_scan AS ") + qtIdent(_("Index Scans")) + + wxT(", idx_tup_fetch AS ") + qtIdent(_("Index Tuples Fetched")) + + wxT(", n_tup_ins AS ") + qtIdent(_("Tuples Inserted")) + + wxT(", n_tup_upd AS ") + qtIdent(_("Tuples Updated")) + + wxT(", n_tup_del AS ") + qtIdent(_("Tuples Deleted")); + + if (GetConnection()->BackendMinimumVersion(8, 3)) + { + sql += + wxT(", n_tup_hot_upd AS ") + qtIdent(_("Tuples HOT Updated")) + + wxT(", n_live_tup AS ") + qtIdent(_("Live Tuples")) + + wxT(", n_dead_tup AS ") + qtIdent(_("Dead Tuples")); + } + + sql += wxT(", heap_blks_read AS ") + qtIdent(_("Heap Blocks Read")) + + wxT(", heap_blks_hit AS ") + qtIdent(_("Heap Blocks Hit")) + + wxT(", idx_blks_read AS ") + qtIdent(_("Index Blocks Read")) + + wxT(", idx_blks_hit AS ") + qtIdent(_("Index Blocks Hit")) + + wxT(", toast_blks_read AS ") + qtIdent(_("Toast Blocks Read")) + + wxT(", toast_blks_hit AS ") + qtIdent(_("Toast Blocks Hit")) + + wxT(", tidx_blks_read AS ") + qtIdent(_("Toast Index Blocks Read")) + + wxT(", tidx_blks_hit AS ") + qtIdent(_("Toast Index Blocks Hit")); + + if (GetConnection()->BackendMinimumVersion(8, 2)) + { + sql += + wxT(", last_vacuum AS ") + qtIdent(_("Last Vacuum")) + + wxT(", last_autovacuum AS ") + qtIdent(_("Last Autovacuum")) + + wxT(", last_analyze AS ") + qtIdent(_("Last Analyze")) + + wxT(", last_autoanalyze AS ") + qtIdent(_("Last Autoanalyze")); + } + + if (GetConnection()->BackendMinimumVersion(9, 1)) + { + sql += + wxT(", vacuum_count AS ") + qtIdent(_("Vacuum counter")) + + wxT(", autovacuum_count AS ") + qtIdent(_("Autovacuum counter")) + + wxT(", analyze_count AS ") + qtIdent(_("Analyze counter")) + + wxT(", autoanalyze_count AS ") + qtIdent(_("Autoanalyze counter")); + } + + if (GetConnection()->HasFeature(FEATURE_SIZE)) + { + sql += wxT(", pg_size_pretty(pg_relation_size(stat.relid)) AS ") + qtIdent(_("Table Size")) + + wxT(", CASE WHEN cl.reltoastrelid = 0 THEN ") + qtDbString(_("none")) + wxT(" ELSE pg_size_pretty(pg_relation_size(cl.reltoastrelid)+ COALESCE((SELECT SUM(pg_relation_size(indexrelid)) FROM pg_index WHERE indrelid=cl.reltoastrelid)::int8, 0)) END AS ") + qtIdent(_("Toast Table Size")) + + wxT(", pg_size_pretty(COALESCE((SELECT SUM(pg_relation_size(indexrelid)) FROM pg_index WHERE indrelid=stat.relid)::int8, 0)) AS ") + qtIdent(_("Indexes Size")); + } + + if (showExtendedStatistics) + { + sql += wxT("\n") + wxT(", tuple_count AS ") + qtIdent(_("Tuple Count")) + wxT(",\n") + wxT(" pg_size_pretty(tuple_len) AS ") + qtIdent(_("Tuple Length")) + wxT(",\n") + wxT(" tuple_percent AS ") + qtIdent(_("Tuple Percent")) + wxT(",\n") + wxT(" dead_tuple_count AS ") + qtIdent(_("Dead Tuple Count")) + wxT(",\n") + wxT(" pg_size_pretty(dead_tuple_len) AS ") + qtIdent(_("Dead Tuple Length")) + wxT(",\n") + wxT(" dead_tuple_percent AS ") + qtIdent(_("Dead Tuple Percent")) + wxT(",\n") + wxT(" pg_size_pretty(free_space) AS ") + qtIdent(_("Free Space")) + wxT(",\n") + wxT(" free_percent AS ") + qtIdent(_("Free Percent")) + wxT("\n") + wxT(" FROM pgstattuple('") + GetQuotedFullIdentifier() + wxT("'), pg_stat_all_tables stat"); + } + else + { + sql += wxT("\n") + wxT(" FROM pg_stat_all_tables stat"); + } + sql += wxT("\n") + wxT(" JOIN pg_statio_all_tables statio ON stat.relid = statio.relid\n") + wxT(" JOIN pg_class cl ON cl.oid=stat.relid\n") + wxT(" WHERE stat.relid = ") + GetOidStr(); + + + DisplayStatistics(statistics, sql); +} + + +pgObject *pgTableFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + wxString query; + pgTable *table = 0; + + // Greenplum returns reltuples and relpages as tuples per segmentDB and pages per segmentDB, + // so we need to multiply them by the number of segmentDBs to get reasonable values. + long gp_segments = 1; + if (collection->GetConnection()->GetIsGreenplum()) + { + query = wxT("SELECT count(*) AS gp_segments from pg_catalog.gp_configuration where definedprimary = 't' and content >= 0"); + gp_segments = StrToLong(collection->GetDatabase()->ExecuteScalar(query)); + if (gp_segments <= 1) + gp_segments = 1; + } + + pgSet *tables; + if (collection->GetConnection()->BackendMinimumVersion(8, 0)) + { + query = wxT("SELECT rel.oid, rel.relname, rel.reltablespace AS spcoid, spc.spcname, pg_get_userbyid(rel.relowner) AS relowner, rel.relacl, rel.relhasoids, ") + wxT("rel.relhassubclass, rel.reltuples, des.description, con.conname, con.conkey,\n") + wxT(" EXISTS(select 1 FROM pg_trigger\n") + wxT(" JOIN pg_proc pt ON pt.oid=tgfoid AND pt.proname='logtrigger'\n") + wxT(" JOIN pg_proc pc ON pc.pronamespace=pt.pronamespace AND pc.proname='slonyversion'\n") + wxT(" WHERE tgrelid=rel.oid) AS isrepl,\n"); + + if (collection->GetConnection()->BackendMinimumVersion(9, 0)) + { + query += wxT(" (select count(*) FROM pg_trigger\n") + wxT(" WHERE tgrelid=rel.oid AND tgisinternal = FALSE) AS triggercount\n"); + } + else + { + query += wxT(" (select count(*) FROM pg_trigger\n") + wxT(" WHERE tgrelid=rel.oid AND tgisconstraint = FALSE) AS triggercount\n"); + } + + if (collection->GetConnection()->BackendMinimumVersion(9, 1)) + query += wxT(", rel.relpersistence \n"); + if (collection->GetConnection()->BackendMinimumVersion(8, 2)) + query += wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'fillfactor=([0-9]*)') AS fillfactor \n"); + if (collection->GetConnection()->GetIsGreenplum()) + { + query += wxT(", gpd.localoid, gpd.attrnums \n"); + query += wxT(", substring(array_to_string(rel.reloptions, ',') from 'appendonly=([a-z]*)') AS appendonly \n"); + query += wxT(", substring(array_to_string(rel.reloptions, ',') from 'compresslevel=([0-9]*)') AS compresslevel \n"); + query += wxT(", substring(array_to_string(rel.reloptions, ',') from 'orientation=([a-z]*)') AS orientation \n"); + query += wxT(", substring(array_to_string(rel.reloptions, ',') from 'compresstype=([a-z0-9]*)') AS compresstype \n"); + query += wxT(", substring(array_to_string(rel.reloptions, ',') from 'blocksize=([0-9]*)') AS blocksize \n"); + query += wxT(", substring(array_to_string(rel.reloptions, ',') from 'checksum=([a-z]*)') AS checksum \n"); + if (collection->GetConnection()->GetIsGreenplum() && collection->GetConnection()->BackendMinimumVersion(8, 2, 9)) + query += wxT(", rel.oid in (select parrelid from pg_partition) as ispartitioned\n"); + } + else if (collection->GetConnection()->BackendMinimumVersion(8, 4)) + { + query += wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') AS autovacuum_enabled \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS autovacuum_vacuum_threshold \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.][0-9]*)') AS autovacuum_vacuum_scale_factor \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_analyze_threshold=([0-9]*)') AS autovacuum_analyze_threshold \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_analyze_scale_factor=([0-9]*[.][0-9]*)') AS autovacuum_analyze_scale_factor \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS autovacuum_vacuum_cost_delay \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS autovacuum_vacuum_cost_limit \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_min_age=([0-9]*)') AS autovacuum_freeze_min_age \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_max_age=([0-9]*)') AS autovacuum_freeze_max_age \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS autovacuum_freeze_table_age \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') AS toast_autovacuum_enabled \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS toast_autovacuum_vacuum_threshold \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.][0-9]*)') AS toast_autovacuum_vacuum_scale_factor \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_analyze_threshold=([0-9]*)') AS toast_autovacuum_analyze_threshold \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_analyze_scale_factor=([0-9]*[.][0-9]*)') AS toast_autovacuum_analyze_scale_factor \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS toast_autovacuum_vacuum_cost_delay \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS toast_autovacuum_vacuum_cost_limit \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_min_age=([0-9]*)') AS toast_autovacuum_freeze_min_age \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_max_age=([0-9]*)') AS toast_autovacuum_freeze_max_age \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS toast_autovacuum_freeze_table_age \n") + wxT(", rel.reloptions AS reloptions, tst.reloptions AS toast_reloptions \n") + wxT(", (CASE WHEN rel.reltoastrelid = 0 THEN false ELSE true END) AS hastoasttable\n"); + } + if (collection->GetConnection()->BackendMinimumVersion(9, 0)) + query += wxT(", rel.reloftype, typ.typname\n"); + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + query += wxT(",\n(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=rel.oid AND sl1.objsubid=0) AS labels"); + query += wxT(",\n(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=rel.oid AND sl2.objsubid=0) AS providers"); + } + wxString pg10=wxEmptyString; + if (collection->GetDatabase()->BackendMinimumVersion(10, 1)) + { + query += wxT(",pg_catalog.pg_get_partkeydef(rel.oid)\n AS partkeydef"); + query += wxT(",pg_get_expr(rel.relpartbound, rel.oid)\n AS partexp"); + pg10=wxT("pg_get_expr(rel.relpartbound, rel.oid) is null and"); + //query += wxT(",\n(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=rel.oid AND sl2.objsubid=0) AS providers"); + } + + query += wxT(" FROM pg_class rel\n") + wxT(" LEFT OUTER JOIN pg_tablespace spc on spc.oid=rel.reltablespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=rel.oid AND des.objsubid=0 AND des.classoid='pg_class'::regclass)\n") + wxT(" LEFT OUTER JOIN pg_constraint con ON con.conrelid=rel.oid AND con.contype='p'\n"); + + // Add the toast table for vacuum parameters. + if (collection->GetConnection()->BackendMinimumVersion(8, 4)) + query += wxT(" LEFT OUTER JOIN pg_class tst ON tst.oid = rel.reltoastrelid\n"); + + if (collection->GetConnection()->GetIsGreenplum()) + query += wxT(" LEFT OUTER JOIN gp_distribution_policy gpd ON gpd.localoid=rel.oid\n"); + + if (collection->GetConnection()->BackendMinimumVersion(9, 0)) + query += wxT("LEFT JOIN pg_type typ ON rel.reloftype=typ.oid\n"); + + query += wxT(" WHERE ")+pg10+wxT(" rel.relkind IN ('r','s','t','p') AND rel.relnamespace = ") + collection->GetSchema()->GetOidStr() + wxT("\n"); + + // Greenplum: Eliminate (sub)partitions from the display, only show the parent partitioned table + // and eliminate external tables + if (collection->GetConnection()->GetIsGreenplum() && collection->GetConnection()->BackendMinimumVersion(8, 2, 9)) + query += wxT("AND rel.relstorage <> 'x' AND rel.oid NOT IN (SELECT parchildrelid from pg_partition_rule)"); + // only show the parent partitioned table + if (collection->GetConnection()->BackendMinimumVersion(10, 0)){ + //addIcon(tables_png_img); + query += wxT("AND (not (rel.relkind='r' and rel.relpartbound IS NOT NULL)) "); + } + + query += restriction + + wxT(" ORDER BY rel.relname"); + } + else + { + query = wxT("SELECT rel.oid, rel.relname, pg_get_userbyid(rel.relowner) AS relowner, rel.relacl, rel.relhasoids, ") + wxT("rel.relhassubclass, rel.reltuples, des.description, con.conname, con.conkey,\n") + wxT(" (select count(*) FROM pg_trigger\n") + wxT(" WHERE tgrelid=rel.oid AND tgisconstraint = FALSE) AS triggercount,\n") + wxT(" EXISTS(select 1 FROM pg_trigger\n") + wxT(" JOIN pg_proc pt ON pt.oid=tgfoid AND pt.proname='logtrigger'\n") + wxT(" JOIN pg_proc pc ON pc.pronamespace=pt.pronamespace AND pc.proname='slonyversion'\n") + wxT(" WHERE tgrelid=rel.oid) AS isrepl\n") + wxT(" FROM pg_class rel\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=rel.oid AND des.objsubid=0 AND des.classoid='pg_class'::regclass)\n") + wxT(" LEFT OUTER JOIN pg_constraint con ON con.conrelid=rel.oid AND con.contype='p'\n") + wxT(" WHERE rel.relkind IN ('r','s','t') AND rel.relnamespace = ") + collection->GetSchema()->GetOidStr() + wxT("\n") + + restriction + + wxT(" ORDER BY rel.relname"); + } + tables = collection->GetDatabase()->ExecuteSet(query); + if (tables) + { + while (!tables->Eof()) + { + table = new pgTable(collection->GetSchema(), tables->GetVal(wxT("relname"))); + + table->iSetOid(tables->GetOid(wxT("oid"))); + table->iSetOwner(tables->GetVal(wxT("relowner"))); + table->iSetAcl(tables->GetVal(wxT("relacl"))); + if (collection->GetConnection()->BackendMinimumVersion(8, 0)) + { + if (tables->GetOid(wxT("spcoid")) == 0) + table->iSetTablespaceOid(collection->GetDatabase()->GetTablespaceOid()); + else + table->iSetTablespaceOid(tables->GetOid(wxT("spcoid"))); + + if (tables->GetVal(wxT("spcname")) == wxEmptyString) + table->iSetTablespace(collection->GetDatabase()->GetTablespace()); + else + table->iSetTablespace(tables->GetVal(wxT("spcname"))); + } + if (collection->GetConnection()->BackendMinimumVersion(9, 0)) + { + table->iSetOfTypeOid(tables->GetOid(wxT("reloftype"))); + table->iSetOfType(tables->GetVal(wxT("typname"))); + } + else + { + table->iSetOfTypeOid(0); + table->iSetOfType(wxT("")); + } + table->iSetComment(tables->GetVal(wxT("description"))); + if (collection->GetConnection()->BackendMinimumVersion(9, 1)) + table->iSetUnlogged(tables->GetVal(wxT("relpersistence")) == wxT("u")); + else + table->iSetUnlogged(false); + table->iSetHasOids(tables->GetBool(wxT("relhasoids"))); + table->iSetEstimatedRows(tables->GetDouble(wxT("reltuples")) * gp_segments); + if (collection->GetConnection()->BackendMinimumVersion(8, 2)) + { + table->iSetFillFactor(tables->GetVal(wxT("fillfactor"))); + } + if (collection->GetConnection()->BackendMinimumVersion(8, 4)) + { + table->iSetRelOptions(tables->GetVal(wxT("reloptions"))); + if (table->GetCustomAutoVacuumEnabled()) + { + if (tables->GetVal(wxT("autovacuum_enabled")).IsEmpty()) + table->iSetAutoVacuumEnabled(2); + else if (tables->GetBool(wxT("autovacuum_enabled"))) + table->iSetAutoVacuumEnabled(1); + else + table->iSetAutoVacuumEnabled(0); + table->iSetAutoVacuumVacuumThreshold(tables->GetVal(wxT("autovacuum_vacuum_threshold"))); + table->iSetAutoVacuumVacuumScaleFactor(tables->GetVal(wxT("autovacuum_vacuum_scale_factor"))); + table->iSetAutoVacuumAnalyzeThreshold(tables->GetVal(wxT("autovacuum_analyze_threshold"))); + table->iSetAutoVacuumAnalyzeScaleFactor(tables->GetVal(wxT("autovacuum_analyze_scale_factor"))); + table->iSetAutoVacuumVacuumCostDelay(tables->GetVal(wxT("autovacuum_vacuum_cost_delay"))); + table->iSetAutoVacuumVacuumCostLimit(tables->GetVal(wxT("autovacuum_vacuum_cost_limit"))); + table->iSetAutoVacuumFreezeMinAge(tables->GetVal(wxT("autovacuum_freeze_min_age"))); + table->iSetAutoVacuumFreezeMaxAge(tables->GetVal(wxT("autovacuum_freeze_max_age"))); + table->iSetAutoVacuumFreezeTableAge(tables->GetVal(wxT("autovacuum_freeze_table_age"))); + } + table->iSetHasToastTable(tables->GetBool(wxT("hastoasttable"))); + if (table->GetHasToastTable()) + { + table->iSetToastRelOptions(tables->GetVal(wxT("toast_reloptions"))); + + if (table->GetToastCustomAutoVacuumEnabled()) + { + if (tables->GetVal(wxT("toast_autovacuum_enabled")).IsEmpty()) + table->iSetToastAutoVacuumEnabled(2); + else if (tables->GetBool(wxT("toast_autovacuum_enabled"))) + table->iSetToastAutoVacuumEnabled(1); + else + table->iSetToastAutoVacuumEnabled(0); + + table->iSetToastAutoVacuumVacuumThreshold(tables->GetVal(wxT("toast_autovacuum_vacuum_threshold"))); + table->iSetToastAutoVacuumVacuumScaleFactor(tables->GetVal(wxT("toast_autovacuum_vacuum_scale_factor"))); + table->iSetToastAutoVacuumVacuumCostDelay(tables->GetVal(wxT("toast_autovacuum_vacuum_cost_delay"))); + table->iSetToastAutoVacuumVacuumCostLimit(tables->GetVal(wxT("toast_autovacuum_vacuum_cost_limit"))); + table->iSetToastAutoVacuumFreezeMinAge(tables->GetVal(wxT("toast_autovacuum_freeze_min_age"))); + table->iSetToastAutoVacuumFreezeMaxAge(tables->GetVal(wxT("toast_autovacuum_freeze_max_age"))); + table->iSetToastAutoVacuumFreezeTableAge(tables->GetVal(wxT("toast_autovacuum_freeze_table_age"))); + } + } + } + table->iSetHasSubclass(tables->GetBool(wxT("relhassubclass"))); + table->iSetPrimaryKeyName(tables->GetVal(wxT("conname"))); + table->iSetIsReplicated(tables->GetBool(wxT("isrepl"))); + table->iSetTriggerCount(tables->GetLong(wxT("triggercount"))); + wxString cn = tables->GetVal(wxT("conkey")); + cn = cn.Mid(1, cn.Length() - 2); + table->iSetPrimaryKeyColNumbers(cn); + if (collection->GetConnection()->BackendMinimumVersion(10, 0)) + { + table->iSetPartKeyDef(tables->GetVal(wxT("partkeydef"))); + table->iSetPartExp(tables->GetVal(wxT("partexp"))); + } + if (collection->GetConnection()->GetIsGreenplum()) + { + Oid lo = tables->GetOid(wxT("localoid")); + wxString db = tables->GetVal(wxT("attrnums")); + db = db.Mid(1, db.Length() - 2); + table->iSetDistributionColNumbers(db); + if (lo > 0 && db.Length() == 0) + table->iSetDistributionIsRandom(); + table->iSetAppendOnly(tables->GetVal(wxT("appendonly"))); + table->iSetCompressLevel(tables->GetVal(wxT("compresslevel"))); + table->iSetOrientation(tables->GetVal(wxT("orientation"))); + table->iSetCompressType(tables->GetVal(wxT("compresstype"))); + table->iSetBlocksize(tables->GetVal(wxT("blocksize"))); + table->iSetChecksum(tables->GetVal(wxT("checksum"))); + + table->iSetPartitionDef(wxT("")); + table->iSetIsPartitioned(false); + + if (collection->GetConnection()->BackendMinimumVersion(8, 2, 9)) + { + table->iSetIsPartitioned(tables->GetBool(wxT("ispartitioned"))); + } + + } + + if (collection->GetConnection()->BackendMinimumVersion(9, 1)) + { + table->iSetProviders(tables->GetVal(wxT("providers"))); + table->iSetLabels(tables->GetVal(wxT("labels"))); + } + + if (browser) + { + browser->AppendObject(collection, table); + tables->MoveNext(); + } + else + break; + } + + delete tables; + } + return table; +} + +bool pgTableObjCollection::CanCreate() +{ + // We don't create sub-objects of Views or External tables + if (GetTable()->GetMetaType() == PGM_VIEW || GetTable()->GetMetaType() == GP_EXTTABLE) + return false; + + return GetSchema()->GetCreatePrivilege(); +} + + +#include "images/table.pngc" +#include "images/table-repl.pngc" +#include "images/table-repl-sm.pngc" +#include "images/table-sm.pngc" +#include "images/tables.pngc" + +pgTableFactory::pgTableFactory() + : pgSchemaObjFactory(__("Table"), __("New Table..."), __("Create a new Table."), table_png_img, table_sm_png_img) +{ + metaType = PGM_TABLE; + if (WantSmallIcon()) + replicatedIconId = addIcon(table_repl_sm_png_img); + else + replicatedIconId = addIcon(table_repl_png_img); + partitionsIconId=addIcon(tables_png_img); +} + +pgCollection *pgTableFactory::CreateCollection(pgObject *obj) +{ + return new pgTableCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgTableFactory tableFactory; +static pgaCollectionFactory cf(&tableFactory, __("Tables"), tables_png_img); + + +pgCollection *pgTableObjFactory::CreateCollection(pgObject *obj) +{ + return new pgTableObjCollection(GetCollectionFactory(), (pgTable *)obj); +} + + +countRowsFactory::countRowsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Count"), _("Count rows in the selected object.")); +} + + +wxWindow *countRowsFactory::StartDialog(frmMain *form, pgObject *obj) +{ + form->StartMsg(_("Counting rows")); + + ((pgTable *)obj)->UpdateRows(); + + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties()); + + form->EndMsg(); + + return 0; +} + + +bool countRowsFactory::CheckEnable(pgObject *obj) +{ + return obj && ( obj->IsCreatedBy(pg_partitionFactory) ||obj->IsCreatedBy(tableFactory)); +} + + +executePgstattupleFactory::executePgstattupleFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Extended table statistics"), _("Get extended statistics via pgstattuple for the selected object."), wxITEM_CHECK); +} + + +wxWindow *executePgstattupleFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (!((pgTable *)obj)->GetShowExtendedStatistics()) + { + ((pgTable *)obj)->iSetShowExtendedStatistics(true); + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + form->SelectStatisticsTab(); + } + else + ((pgTable *)obj)->iSetShowExtendedStatistics(false); + + form->GetMenuFactories()->CheckMenu(obj, form->GetMenuBar(), (ctlMenuToolbar *)form->GetToolBar()); + + return 0; +} + + +bool executePgstattupleFactory::CheckEnable(pgObject *obj) +{ + return obj && ( obj->IsCreatedBy(pg_partitionFactory) ||obj->IsCreatedBy(tableFactory)) && ((pgTable *)obj)->HasPgstattuple(); +} + +bool executePgstattupleFactory::CheckChecked(pgObject *obj) +{ + return obj && ( obj->IsCreatedBy(pg_partitionFactory) ||obj->IsCreatedBy(tableFactory)) && ((pgTable *)obj)->GetShowExtendedStatistics(); +} + +disableAllTriggersFactory::disableAllTriggersFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Disable triggers"), _("Disable all triggers on the selected table.")); +} + + +wxWindow *disableAllTriggersFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (wxMessageBox(_("Are you sure you wish to disable all triggers on this table?"), _("Disable triggers"), wxYES_NO) != wxYES) + return 0; + + if (!((pgTable *)obj)->EnableTriggers(false)) + return 0; + + ((pgTable *)obj)->iSetTriggersEnabled(form->GetBrowser(), false); + + return 0; +} + + +bool disableAllTriggersFactory::CheckEnable(pgObject *obj) +{ + return obj && ( obj->IsCreatedBy(pg_partitionFactory) ||obj->IsCreatedBy(tableFactory)) && obj->CanEdit() + && (obj->GetOwner() == obj->GetConnection()->GetUser() || obj->GetServer()->GetSuperUser()) + && ((pgTable *)obj)->GetConnection()->BackendMinimumVersion(8, 1) + && ((pgTable *)obj)->GetTriggerCount() > 0; +} + +enableAllTriggersFactory::enableAllTriggersFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Enable triggers"), _("Enable all triggers on the selected table.")); +} + + +wxWindow *enableAllTriggersFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (wxMessageBox(_("Are you sure you wish to enable all triggers on this table?"), _("Enable triggers"), wxYES_NO) != wxYES) + return 0; + + if (!((pgTable *)obj)->EnableTriggers(true)) + return 0; + + ((pgTable *)obj)->iSetTriggersEnabled(form->GetBrowser(), true); + + return 0; +} + + +bool enableAllTriggersFactory::CheckEnable(pgObject *obj) +{ + return obj && ( obj->IsCreatedBy(pg_partitionFactory) ||obj->IsCreatedBy(tableFactory)) && obj->CanEdit() + && (obj->GetOwner() == obj->GetConnection()->GetUser() || obj->GetServer()->GetSuperUser()) + && ((pgTable *)obj)->GetConnection()->BackendMinimumVersion(8, 1) + && ((pgTable *)obj)->GetTriggerCount() > 0; +} + +truncateFactory::truncateFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Truncate"), _("Truncate the selected table.")); +} + + +wxWindow *truncateFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (wxMessageBox(_("Are you sure you wish to truncate this table?\n\nWARNING: This action will delete ALL data in the table!"), _("Truncate table"), wxYES_NO | wxICON_QUESTION | wxNO_DEFAULT) != wxYES) + return 0; + + ((pgTable *)obj)->Truncate(false); + ((pgTable *)obj)->UpdateRows(); + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties()); + + return 0; +} + + +bool truncateFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(tableFactory); +} + + +truncateCascadedFactory::truncateCascadedFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Truncate Cascaded"), _("Truncate the selected table and all referencing tables.")); +} + + +wxWindow *truncateCascadedFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (wxMessageBox(_("Are you sure you wish to truncate this table and all tables that have foreign key references to this table?\n\nWARNING: This action will delete ALL data in the tables!"), _("Truncate table cascaded"), wxYES_NO | wxICON_QUESTION | wxNO_DEFAULT) != wxYES) + return 0; + + ((pgTable *)obj)->Truncate(true); + ((pgTable *)obj)->UpdateRows(); + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties()); + + return 0; +} + + +bool truncateCascadedFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(tableFactory) && ((pgTable *)obj)->GetConnection()->BackendMinimumVersion(8, 2); +} + + +resetTableStatsFactory::resetTableStatsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Reset table statistics"), _("Reset statistics of the selected table.")); +} + + +wxWindow *resetTableStatsFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (wxMessageBox(_("Are you sure you wish to reset statistics of this table?"), _("Reset statistics"), wxYES_NO) != wxYES) + return 0; + + ((pgTable *)obj)->ResetStats(); + ((pgTable *)obj)->ShowStatistics(form, form->GetStatistics()); + + return 0; +} + + +bool resetTableStatsFactory::CheckEnable(pgObject *obj) +{ + return obj && ( obj->IsCreatedBy(pg_partitionFactory) ||obj->IsCreatedBy(tableFactory)) && ((pgTable *)obj)->GetConnection()->BackendMinimumVersion(9, 0); +} diff --git a/schema/pgTablespace.cpp b/schema/pgTablespace.cpp new file mode 100644 index 0000000..6449c30 --- /dev/null +++ b/schema/pgTablespace.cpp @@ -0,0 +1,467 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgTablespace.cpp - PostgreSQL Tablespace +// +////////////////////////////////////////////////////////////////////////// + + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgfeatures.h" +#include "schema/pgTablespace.h" +#include "schema/pgDatabase.h" +#include "frm/frmMain.h" +#include "dlg/dlgMoveTablespace.h" + + +pgTablespace::pgTablespace(const wxString &newName) + : pgServerObject(tablespaceFactory, newName) +{ +} + +wxString pgTablespace::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on tablespace"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing tablespace"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop tablespace \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop tablespace \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop tablespace cascaded?"); + break; + case DROPTITLE: + message = _("Drop tablespace?"); + break; + case PROPERTIESREPORT: + message = _("Tablespace properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Tablespace properties"); + break; + case DDLREPORT: + message = _("Tablespace DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Tablespace DDL"); + break; + case STATISTICSREPORT: + message = _("Tablespace statistics report"); + message += wxT(" - ") + GetName(); + break; + case OBJSTATISTICS: + message = _("Tablespace statistics"); + break; + case DEPENDENCIESREPORT: + message = _("Tablespace dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Tablespace dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Tablespace dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Tablespace dependents"); + break; + } + + return message; +} + +void pgTablespace::ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &where) +{ + form->StartMsg(_(" Retrieving tablespace usage")); + + referencedBy->ClearAll(); + referencedBy->AddColumn(_("Type"), 60); + referencedBy->AddColumn(_("Database"), 80); + referencedBy->AddColumn(_("Name"), 300); + + wxArrayString dblist; + + pgSet *set = GetConnection()->ExecuteSet( + wxT("SELECT datname, datallowconn, dattablespace\n") + wxT(" FROM pg_database db\n") + wxT(" ORDER BY datname")); + + if (set) + { + while (!set->Eof()) + { + wxString datname = set->GetVal(wxT("datname")); + if (set->GetBool(wxT("datallowconn"))) + dblist.Add(datname); + OID oid = set->GetOid(wxT("dattablespace")); + if (oid == GetOid()) + referencedBy->AppendItem(databaseFactory.GetIconId(), _("Database"), datname); + + set->MoveNext(); + } + delete set; + } + + FillOwned(form->GetBrowser(), referencedBy, dblist, + wxT("SELECT cl.relkind, COALESCE(cin.nspname, cln.nspname) as nspname, COALESCE(ci.relname, cl.relname) as relname, cl.relname as indname\n") + wxT(" FROM pg_class cl\n") + wxT(" JOIN pg_namespace cln ON cl.relnamespace=cln.oid\n") + wxT(" LEFT OUTER JOIN pg_index ind ON ind.indexrelid=cl.oid\n") + wxT(" LEFT OUTER JOIN pg_class ci ON ind.indrelid=ci.oid\n") + wxT(" LEFT OUTER JOIN pg_namespace cin ON ci.relnamespace=cin.oid,\n") + wxT(" pg_database\n") + wxT(" WHERE datname = current_database()\n") + wxT(" AND (cl.reltablespace = ") + GetOidStr() + wxT("\n") + wxT(" OR (cl.reltablespace=0 AND dattablespace = ") + GetOidStr() + wxT("))\n") + wxT(" ORDER BY 1,2,3")); + + form->EndMsg(set != 0); +} + + +bool pgTablespace::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return GetConnection()->ExecuteVoid(wxT("DROP TABLESPACE ") + GetQuotedFullIdentifier() + wxT(";")); +} + + +wxString pgTablespace::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Tablespace: ") + GetName() + wxT("\n\n"); + if (location.IsEmpty()) + sql += wxT("-- System Tablespace\n"); + else + sql += wxT("-- DROP TABLESPACE ") + GetQuotedIdentifier() + + wxT("\n\nCREATE TABLESPACE ") + GetQuotedIdentifier() + + wxT("\n OWNER ") + qtIdent(GetOwner()) + + wxT("\n LOCATION ") + qtDbString(location) + + wxT(";\n"); + sql += GetCommentSql(); + + size_t i; + for (i = 0 ; i < variables.GetCount() ; i++) + sql += wxT("ALTER TABLESPACE ") + GetQuotedFullIdentifier() + + wxT(" SET (") + variables.Item(i) + wxT(");\n"); + + if (GetConnection()->BackendMinimumVersion(9, 2)) + sql += GetSeqLabelsSql(); + } + return sql; +} + + +void pgTablespace::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + } + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Location"), GetLocation()); + size_t i; + for (i = 0 ; i < variables.GetCount() ; i++) + { + wxString item = variables.Item(i); + properties->AppendItem(item.BeforeFirst('='), item.AfterFirst('=')); + } + properties->AppendItem(_("ACL"), GetAcl()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + if (!GetLabels().IsEmpty()) + { + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); + } + } + } + } +} + + +void pgTablespace::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + if (statistics) + { + if (GetConnection()->HasFeature(FEATURE_SIZE)) + { + wxLogInfo(wxT("Displaying statistics for %s"), GetTypeName().c_str()); + + // Add the statistics view columns + CreateListColumns(statistics, _("Statistic"), _("Value")); + + pgSet *stats = GetConnection()->ExecuteSet( + wxT("SELECT pg_size_pretty(pg_tablespace_size(") + GetOidStr() + wxT(")) AS ") + qtIdent(_("Tablespace Size"))); + + if (stats) + { + int col; + for (col = 0 ; col < stats->NumCols() ; col++) + { + if (!stats->ColName(col).IsEmpty()) + statistics->AppendItem(stats->ColName(col), stats->GetVal(col)); + } + delete stats; + } + } + } +} + + +void pgTablespace::MoveTablespace(frmMain *form) +{ + wxString query; + + dlgMoveTablespace rdo(form, GetConnection(), this); + if (rdo.ShowModal() != wxID_CANCEL) + { + if (wxMessageBox(wxString::Format( + _("Are you sure you wish to move objects from %s to %s?"), + GetQuotedFullIdentifier().c_str(), rdo.GetTablespace().c_str()), + _("Move tablespace?"), + wxYES_NO) != wxYES) + return; + + wxArrayString kind = rdo.GetKind(); + wxString ownerInfo, + moveTo = qtIdent(rdo.GetTablespace()), + currTblSpace = GetQuotedFullIdentifier(); + + if (rdo.GetOwner().Length() > 0) + { + ownerInfo = wxString::Format( + wxT(" OWNED BY %s"), + qtIdent(rdo.GetOwner()).c_str()); + } + + for(size_t index = 0; index < kind.GetCount(); ++index) + { + query += wxString::Format( + wxT("ALTER %s ALL IN TABLESPACE %s%s SET TABLESPACE %s;\n"), + kind.Item(index).c_str(), + currTblSpace.c_str(), + ownerInfo.c_str(), + moveTo.c_str()); + } + GetConnection()->ExecuteVoid(query); + } +} + + +pgObject *pgTablespace::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *tablespace = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + tablespace = tablespaceFactory.CreateObjects(coll, 0, wxT("\n WHERE ts.oid=") + GetOidStr()); + + return tablespace; +} + + + +pgObject *pgTablespaceFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgTablespace *tablespace = 0; + + pgSet *tablespaces; + if (collection->GetConnection()->BackendMinimumVersion(9, 2)) + tablespaces = collection->GetServer()->ExecuteSet( + wxT("SELECT ts.oid, spcname, pg_catalog.pg_tablespace_location(ts.oid) AS spclocation, spcoptions, ") + wxT("pg_get_userbyid(spcowner) as spcuser, spcacl, ") + wxT("pg_catalog.shobj_description(oid, 'pg_tablespace') AS description, ") + wxT("(SELECT array_agg(label) FROM pg_shseclabel sl1 WHERE sl1.objoid=ts.oid) AS labels, ") + wxT("(SELECT array_agg(provider) FROM pg_shseclabel sl2 WHERE sl2.objoid=ts.oid) AS providers ") + wxT("FROM pg_tablespace ts\n") + + restriction + wxT(" ORDER BY spcname")); + else if (collection->GetConnection()->BackendMinimumVersion(8, 5)) + tablespaces = collection->GetServer()->ExecuteSet( + wxT("SELECT ts.oid, spcname, spclocation, spcoptions, pg_get_userbyid(spcowner) as spcuser, spcacl, pg_catalog.shobj_description(oid, 'pg_tablespace') AS description FROM pg_tablespace ts\n") + + restriction + wxT(" ORDER BY spcname")); + else if (collection->GetConnection()->BackendMinimumVersion(8, 2)) + tablespaces = collection->GetServer()->ExecuteSet( + wxT("SELECT ts.oid, spcname, spclocation, pg_get_userbyid(spcowner) as spcuser, spcacl, pg_catalog.shobj_description(oid, 'pg_tablespace') AS description FROM pg_tablespace ts\n") + + restriction + wxT(" ORDER BY spcname")); + else + tablespaces = collection->GetServer()->ExecuteSet( + wxT("SELECT ts.oid, spcname, spclocation, '' AS description, pg_get_userbyid(spcowner) as spcuser, spcacl FROM pg_tablespace ts\n") + + restriction + wxT(" ORDER BY spcname")); + + if (tablespaces) + { + while (!tablespaces->Eof()) + { + + tablespace = new pgTablespace(tablespaces->GetVal(wxT("spcname"))); + tablespace->iSetServer(collection->GetServer()); + tablespace->iSetOid(tablespaces->GetOid(wxT("oid"))); + tablespace->iSetOwner(tablespaces->GetVal(wxT("spcuser"))); + tablespace->iSetLocation(tablespaces->GetVal(wxT("spclocation"))); + tablespace->iSetAcl(tablespaces->GetVal(wxT("spcacl"))); + if (collection->GetConnection()->BackendMinimumVersion(8, 2)) + tablespace->iSetComment(tablespaces->GetVal(wxT("description"))); + if (collection->GetConnection()->BackendMinimumVersion(8, 5)) + { + wxString str = tablespaces->GetVal(wxT("spcoptions")); + if (!str.IsEmpty()) + FillArray(tablespace->GetVariables(), str.Mid(1, str.Length() - 2)); + } + if (collection->GetConnection()->BackendMinimumVersion(9, 2)) + { + tablespace->iSetProviders(tablespaces->GetVal(wxT("providers"))); + tablespace->iSetLabels(tablespaces->GetVal(wxT("labels"))); + } + + if (browser) + { + browser->AppendObject(collection, tablespace); + tablespaces->MoveNext(); + } + else + break; + } + + delete tablespaces; + } + return tablespace; +} + + +pgTablespaceCollection::pgTablespaceCollection(pgaFactory *factory, pgServer *sv) + : pgServerObjCollection(factory, sv) +{ +} + + +void pgTablespaceCollection::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + if (GetConnection()->HasFeature(FEATURE_SIZE)) + { + wxLogInfo(wxT("Displaying statistics for tablespaces")); + + // Add the statistics view columns + statistics->ClearAll(); + statistics->AddColumn(_("Tablespace"), 100); + statistics->AddColumn(_("Size"), 60); + + pgSet *stats = GetConnection()->ExecuteSet( + wxT("SELECT spcname, pg_size_pretty(pg_tablespace_size(oid)) AS size FROM pg_tablespace ORDER BY spcname")); + + if (stats) + { + long pos = 0; + while (!stats->Eof()) + { + statistics->InsertItem(pos, stats->GetVal(wxT("spcname")), PGICON_STATISTICS); + statistics->SetItem(pos, 1, stats->GetVal(wxT("size"))); + stats->MoveNext(); + pos++; + } + + delete stats; + } + } +} + + +wxString pgTablespaceCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on tablespaces"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing tablespaces"); + break; + case STATISTICSREPORT: + message = _("Tablespaces statistics report"); + break; + case OBJSTATISTICS: + message = _("Tablespaces statistics"); + break; + case OBJECTSLISTREPORT: + message = _("Tablespaces list report"); + break; + } + + return message; +} + + +#include "images/tablespace.pngc" +#include "images/tablespaces.pngc" + + +pgTablespaceFactory::pgTablespaceFactory() + : pgServerObjFactory(__("Tablespace"), __("New Tablespace..."), __("Create a new Tablespace."), tablespace_png_img) +{ + metaType = PGM_TABLESPACE; +} + + +pgCollection *pgTablespaceFactory::CreateCollection(pgObject *obj) +{ + return new pgTablespaceCollection(GetCollectionFactory(), (pgServer *)obj); +} + +pgTablespaceFactory tablespaceFactory; +static pgaCollectionFactory cf(&tablespaceFactory, __("Tablespaces"), tablespaces_png_img); + +moveTablespaceFactory::moveTablespaceFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Move objects to..."), _("Move objects of the selected tablespace to another one.")); +} + + +wxWindow *moveTablespaceFactory::StartDialog(frmMain *form, pgObject *obj) +{ + ((pgTablespace *)obj)->MoveTablespace(form); + + return 0; +} + +bool moveTablespaceFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(tablespaceFactory) && ((pgTablespace *)obj)->GetConnection()->BackendMinimumVersion(9, 4); +} diff --git a/schema/pgTextSearchConfiguration.cpp b/schema/pgTextSearchConfiguration.cpp new file mode 100644 index 0000000..bbe3109 --- /dev/null +++ b/schema/pgTextSearchConfiguration.cpp @@ -0,0 +1,277 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgTextSearchConfiguration.cpp - Text Search Configuration class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgTextSearchConfiguration.h" + + +pgTextSearchConfiguration::pgTextSearchConfiguration(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, textSearchConfigurationFactory, newName) +{ +} + +pgTextSearchConfiguration::~pgTextSearchConfiguration() +{ +} + +wxString pgTextSearchConfiguration::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on FTS configuration"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing FTS configuration"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop FTS configuration \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop FTS configuration \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop FTS configuration cascaded?"); + break; + case DROPTITLE: + message = _("Drop FTS configuration?"); + break; + case PROPERTIESREPORT: + message = _("FTS configuration properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("FTS configuration properties"); + break; + case DDLREPORT: + message = _("FTS configuration DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("FTS configuration DDL"); + break; + case DEPENDENCIESREPORT: + message = _("FTS configuration dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("FTS configuration dependencies"); + break; + case DEPENDENTSREPORT: + message = _("FTS configuration dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("FTS configuration dependents"); + break; + } + + return message; +} + +bool pgTextSearchConfiguration::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP TEXT SEARCH CONFIGURATION ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + qtIdent(this->GetIdentifier()); + + if (cascaded) + sql += wxT(" CASCADE"); + + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgTextSearchConfiguration::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Text Search Configuration: ") + GetFullIdentifier() + wxT("\n\n") + + wxT("-- DROP TEXT SEARCH CONFIGURATION ") + GetFullIdentifier() + wxT("\n\n") + + wxT("CREATE TEXT SEARCH CONFIGURATION ") + GetFullIdentifier() + wxT(" (") + + wxT("\n PARSER = ") + qtTypeIdent(GetParser()) + + wxT("\n);\n"); + + for (size_t i = 0 ; i < tokens.GetCount() ; i++) + sql += wxT("ALTER TEXT SEARCH CONFIGURATION ") + GetQuotedFullIdentifier() + + wxT(" ADD MAPPING FOR ") + tokens.Item(i).BeforeFirst('/') + + wxT(" WITH ") + tokens.Item(i).AfterFirst('/') + + wxT(";\n"); + + if (!GetComment().IsNull()) + sql += wxT("COMMENT ON TEXT SEARCH CONFIGURATION ") + GetFullIdentifier() + + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + + return sql; +} + + +void pgTextSearchConfiguration::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Parser"), GetParser()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgTextSearchConfiguration::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *config = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + config = textSearchConfigurationFactory.CreateObjects(coll, 0, wxT("\n AND cfg.oid=") + GetOidStr()); + + return config; +} + + +/////////////////////////////////////////////////// + + +pgTextSearchConfigurationCollection::pgTextSearchConfigurationCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgTextSearchConfigurationCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on FTS configurations"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing FTS configurations"); + break; + case OBJECTSLISTREPORT: + message = _("FTS configurations list report"); + break; + } + + return message; +} + + +////////////////////////////////////////////////////// + + +pgObject *pgTextSearchConfigurationFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgTextSearchConfiguration *config = 0; + + pgSet *configurations; + configurations = collection->GetDatabase()->ExecuteSet( + wxT("SELECT cfg.oid, cfg.cfgname, pg_get_userbyid(cfg.cfgowner) as cfgowner, cfg.cfgparser, parser.prsname as parsername, description\n") + wxT(" FROM pg_ts_config cfg\n") + wxT(" LEFT OUTER JOIN pg_ts_parser parser ON parser.oid=cfg.cfgparser\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=cfg.oid AND des.classoid='pg_ts_config'::regclass)\n") + wxT(" WHERE cfg.cfgnamespace = ") + collection->GetSchema()->GetOidStr() + + restriction + wxT("\n") + wxT(" ORDER BY cfg.cfgname")); + + if (configurations) + { + while (!configurations->Eof()) + { + config = new pgTextSearchConfiguration(collection->GetSchema(), configurations->GetVal(wxT("cfgname"))); + config->iSetOid(configurations->GetOid(wxT("oid"))); + config->iSetOwner(configurations->GetVal(wxT("cfgowner"))); + config->iSetComment(configurations->GetVal(wxT("description"))); + config->iSetParser(configurations->GetVal(wxT("parsername"))); + config->iSetParserOid(configurations->GetOid(wxT("cfgparser"))); + + pgSet *maps; + maps = collection->GetDatabase()->ExecuteSet( + wxT("SELECT\n") + wxT(" (SELECT t.alias FROM pg_catalog.ts_token_type(cfgparser) AS t") + wxT(" WHERE t.tokid = maptokentype) AS tokenalias,\n") + wxT(" dictname\n") + wxT("FROM pg_ts_config_map\n") + wxT(" LEFT OUTER JOIN pg_ts_config ON mapcfg=pg_ts_config.oid\n") + wxT(" LEFT OUTER JOIN pg_ts_dict ON mapdict=pg_ts_dict.oid\n") + wxT("WHERE mapcfg=") + config->GetOidStr() + wxT("\n") + wxT("ORDER BY 1, mapseqno")); + + if (maps) + { + wxString tokenToAdd; + while (!maps->Eof()) + { + if (tokenToAdd.Length() > 0 && + !tokenToAdd.BeforeFirst('/').IsSameAs(maps->GetVal(wxT("tokenalias")), false)) + { + config->GetTokens().Add(tokenToAdd); + tokenToAdd = wxT(""); + } + + if (tokenToAdd.Length() == 0) + tokenToAdd = maps->GetVal(wxT("tokenalias")) + wxT("/") + maps->GetVal(wxT("dictname")); + else + tokenToAdd += wxT(",") + maps->GetVal(wxT("dictname")); + + maps->MoveNext(); + } + + delete maps; + } + + if (browser) + { + browser->AppendObject(collection, config); + configurations->MoveNext(); + } + else + break; + } + + delete configurations; + } + return config; +} + + +#include "images/configuration.pngc" +#include "images/configurations.pngc" + +pgTextSearchConfigurationFactory::pgTextSearchConfigurationFactory() + : pgSchemaObjFactory(__("FTS Configuration"), __("New FTS Configuration..."), __("Create a new FTS Configuration."), configuration_png_img) +{ +} + + +pgCollection *pgTextSearchConfigurationFactory::CreateCollection(pgObject *obj) +{ + return new pgTextSearchConfigurationCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgTextSearchConfigurationFactory textSearchConfigurationFactory; +static pgaCollectionFactory cf(&textSearchConfigurationFactory, __("FTS Configurations"), configurations_png_img); diff --git a/schema/pgTextSearchDictionary.cpp b/schema/pgTextSearchDictionary.cpp new file mode 100644 index 0000000..10b1248 --- /dev/null +++ b/schema/pgTextSearchDictionary.cpp @@ -0,0 +1,241 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgTextSearchDictionary.cpp - Text Search Dictionary class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgTextSearchDictionary.h" + + +pgTextSearchDictionary::pgTextSearchDictionary(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, textSearchDictionaryFactory, newName) +{ +} + +pgTextSearchDictionary::~pgTextSearchDictionary() +{ +} + +wxString pgTextSearchDictionary::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on FTS dictionary"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing FTS dictionary"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop FTS dictionary \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop FTS dictionary \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop FTS dictionary cascaded?"); + break; + case DROPTITLE: + message = _("Drop FTS dictionary?"); + break; + case PROPERTIESREPORT: + message = _("FTS dictionary properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("FTS dictionary properties"); + break; + case DDLREPORT: + message = _("FTS dictionary DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("FTS dictionary DDL"); + break; + case DEPENDENCIESREPORT: + message = _("FTS dictionary dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("FTS dictionary dependencies"); + break; + case DEPENDENTSREPORT: + message = _("FTS dictionary dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("FTS dictionary dependents"); + break; + } + + return message; +} + +bool pgTextSearchDictionary::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP TEXT SEARCH DICTIONARY ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + qtIdent(this->GetIdentifier()); + + if (cascaded) + sql += wxT(" CASCADE"); + + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgTextSearchDictionary::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Text Search Dictionary: ") + GetFullIdentifier() + wxT("\n\n") + + wxT("-- DROP TEXT SEARCH DICTIONARY ") + GetFullIdentifier() + wxT("\n\n") + + wxT("CREATE TEXT SEARCH DICTIONARY ") + GetFullIdentifier() + wxT(" (") + + wxT("\n TEMPLATE = ") + qtTypeIdent(GetTemplate()); + + if (options.Length() > 0) + sql += wxT(",\n ") + options; + + sql += wxT("\n);\n"); + + if (!GetComment().IsNull()) + sql += wxT("COMMENT ON TEXT SEARCH DICTIONARY ") + GetFullIdentifier() + + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + + return sql; +} + + +void pgTextSearchDictionary::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Template"), GetTemplate()); + properties->AppendItem(_("Options"), GetOptions()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgTextSearchDictionary::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *dict = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + dict = textSearchDictionaryFactory.CreateObjects(coll, 0, wxT("\n AND dict.oid=") + GetOidStr()); + + return dict; +} + + +/////////////////////////////////////////////////// + + +pgTextSearchDictionaryCollection::pgTextSearchDictionaryCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgTextSearchDictionaryCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on FTS dictionaries"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing FTS dictionaries"); + break; + case OBJECTSLISTREPORT: + message = _("FTS dictionaries list report"); + break; + } + + return message; +} + + +////////////////////////////////////////////////////// + + +pgObject *pgTextSearchDictionaryFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgTextSearchDictionary *dict = 0; + + pgSet *dictionaries; + dictionaries = collection->GetDatabase()->ExecuteSet( + wxT("SELECT dict.oid, dict.dictname, pg_get_userbyid(dict.dictowner) as dictowner, t.tmplname, dict.dictinitoption, description\n") + wxT(" FROM pg_ts_dict dict\n") + wxT(" LEFT OUTER JOIN pg_ts_template t ON t.oid=dict.dicttemplate\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=dict.oid AND des.classoid='pg_ts_dict'::regclass)\n") + wxT(" WHERE dict.dictnamespace = ") + collection->GetSchema()->GetOidStr() + + restriction + wxT("\n") + wxT(" ORDER BY dict.dictname")); + + if (dictionaries) + { + while (!dictionaries->Eof()) + { + dict = new pgTextSearchDictionary(collection->GetSchema(), dictionaries->GetVal(wxT("dictname"))); + dict->iSetOid(dictionaries->GetOid(wxT("oid"))); + dict->iSetOwner(dictionaries->GetVal(wxT("dictowner"))); + dict->iSetComment(dictionaries->GetVal(wxT("description"))); + dict->iSetTemplate(dictionaries->GetVal(wxT("tmplname"))); + dict->iSetOptions(dictionaries->GetVal(wxT("dictinitoption"))); + + if (browser) + { + browser->AppendObject(collection, dict); + dictionaries->MoveNext(); + } + else + break; + } + + delete dictionaries; + } + return dict; +} + + +#include "images/dictionary.pngc" +#include "images/dictionaries.pngc" + +pgTextSearchDictionaryFactory::pgTextSearchDictionaryFactory() + : pgSchemaObjFactory(__("FTS Dictionary"), __("New FTS Dictionary..."), __("Create a new FTS Dictionary."), dictionary_png_img) +{ +} + + +pgCollection *pgTextSearchDictionaryFactory::CreateCollection(pgObject *obj) +{ + return new pgTextSearchDictionaryCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgTextSearchDictionaryFactory textSearchDictionaryFactory; +static pgaCollectionFactory cf(&textSearchDictionaryFactory, __("FTS Dictionaries"), dictionaries_png_img); diff --git a/schema/pgTextSearchParser.cpp b/schema/pgTextSearchParser.cpp new file mode 100644 index 0000000..5216216 --- /dev/null +++ b/schema/pgTextSearchParser.cpp @@ -0,0 +1,253 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgTextSearchParser.cpp - Text Search Parser class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgTextSearchParser.h" + + +pgTextSearchParser::pgTextSearchParser(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, textSearchParserFactory, newName) +{ +} + +pgTextSearchParser::~pgTextSearchParser() +{ +} + +wxString pgTextSearchParser::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on FTS parser"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing FTS parser"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop FTS parser \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop FTS parser \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop FTS parser cascaded?"); + break; + case DROPTITLE: + message = _("Drop FTS parser?"); + break; + case PROPERTIESREPORT: + message = _("FTS parser properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("FTS parser properties"); + break; + case DDLREPORT: + message = _("FTS parser DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("FTS parser DDL"); + break; + case DEPENDENCIESREPORT: + message = _("FTS parser dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("FTS parser dependencies"); + break; + case DEPENDENTSREPORT: + message = _("FTS parser dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("FTS parser dependents"); + break; + } + + return message; +} + +bool pgTextSearchParser::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP TEXT SEARCH PARSER ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + qtIdent(this->GetIdentifier()); + + if (cascaded) + sql += wxT(" CASCADE"); + + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgTextSearchParser::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Text Search Parser: ") + GetFullIdentifier() + wxT("\n\n") + + wxT("-- DROP TEXT SEARCH PARSER ") + GetFullIdentifier() + wxT("\n\n") + + wxT("CREATE TEXT SEARCH PARSER ") + GetFullIdentifier() + wxT(" (") + + wxT("\n START = ") + qtTypeIdent(GetStart()) + + wxT(",\n GETTOKEN = ") + qtTypeIdent(GetGettoken()) + + wxT(",\n END = ") + qtTypeIdent(GetEnd()) + + wxT(",\n LEXTYPES = ") + qtTypeIdent(GetLextypes()); + + AppendIfFilled(sql, wxT(",\n HEADLINE = "), GetHeadline()); + + sql += wxT("\n);\n"); + + if (!GetComment().IsNull()) + sql += wxT("COMMENT ON TEXT SEARCH PARSER ") + GetFullIdentifier() + + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + + return sql; +} + + +void pgTextSearchParser::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Start"), GetStart()); + properties->AppendItem(_("Gettoken"), GetGettoken()); + properties->AppendItem(_("End"), GetEnd()); + properties->AppendItem(_("Lextypes"), GetLextypes()); + properties->AppendItem(_("Headline"), GetHeadline()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgTextSearchParser::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *parser = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + parser = textSearchParserFactory.CreateObjects(coll, 0, wxT("\n AND prs.oid=") + GetOidStr()); + + return parser; +} + + +/////////////////////////////////////////////////// + + +pgTextSearchParserCollection::pgTextSearchParserCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgTextSearchParserCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on FTS parsers"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing FTS parsers"); + break; + case OBJECTSLISTREPORT: + message = _("FTS parsers list report"); + break; + } + + return message; +} + + +////////////////////////////////////////////////////// + + +pgObject *pgTextSearchParserFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgTextSearchParser *parser = 0; + + pgSet *parsers; + parsers = collection->GetDatabase()->ExecuteSet( + wxT("SELECT prs.oid, prs.prsname, prs.prsstart, prs.prstoken, prs.prsend, prs.prslextype, prs.prsheadline, description\n") + wxT(" FROM pg_ts_parser prs\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=prs.oid AND des.classoid='pg_ts_parser'::regclass)\n") + wxT(" WHERE prs.prsnamespace = ") + collection->GetSchema()->GetOidStr() + + restriction + wxT("\n") + wxT(" ORDER BY prs.prsname")); + + if (parsers) + { + while (!parsers->Eof()) + { + parser = new pgTextSearchParser(collection->GetSchema(), parsers->GetVal(wxT("prsname"))); + parser->iSetOid(parsers->GetOid(wxT("oid"))); + parser->iSetComment(parsers->GetVal(wxT("description"))); + parser->iSetStart(parsers->GetVal(wxT("prsstart"))); + parser->iSetGettoken(parsers->GetVal(wxT("prstoken"))); + parser->iSetEnd(parsers->GetVal(wxT("prsend"))); + parser->iSetLextypes(parsers->GetVal(wxT("prslextype"))); + if (parsers->GetVal(wxT("prsheadline")).Cmp(wxT("-")) != 0) + { + parser->iSetHeadline(parsers->GetVal(wxT("prsheadline"))); + } + else + { + parser->iSetHeadline(wxT("")); + } + + if (browser) + { + browser->AppendObject(collection, parser); + parsers->MoveNext(); + } + else + break; + } + + delete parsers; + } + return parser; +} + + +#include "images/parser.pngc" +#include "images/parsers.pngc" + +pgTextSearchParserFactory::pgTextSearchParserFactory() + : pgSchemaObjFactory(__("FTS Parser"), __("New FTS Parser..."), __("Create a new FTS Parser."), parser_png_img) +{ +} + + +pgCollection *pgTextSearchParserFactory::CreateCollection(pgObject *obj) +{ + return new pgTextSearchParserCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgTextSearchParserFactory textSearchParserFactory; +static pgaCollectionFactory cf(&textSearchParserFactory, __("FTS Parsers"), parsers_png_img); diff --git a/schema/pgTextSearchTemplate.cpp b/schema/pgTextSearchTemplate.cpp new file mode 100644 index 0000000..6eb8cf4 --- /dev/null +++ b/schema/pgTextSearchTemplate.cpp @@ -0,0 +1,242 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgTextSearchTemplate.cpp - Text Search Template class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgTextSearchTemplate.h" + + +pgTextSearchTemplate::pgTextSearchTemplate(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, textSearchTemplateFactory, newName) +{ +} + +pgTextSearchTemplate::~pgTextSearchTemplate() +{ +} + +wxString pgTextSearchTemplate::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on FTS template"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing FTS template"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop FTS template \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop FTS template \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop FTS template cascaded?"); + break; + case DROPTITLE: + message = _("Drop FTS template?"); + break; + case PROPERTIESREPORT: + message = _("FTS template properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("FTS template properties"); + break; + case DDLREPORT: + message = _("FTS template DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("FTS template DDL"); + break; + case DEPENDENCIESREPORT: + message = _("FTS template dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("FTS template dependencies"); + break; + case DEPENDENTSREPORT: + message = _("FTS template dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("FTS template dependents"); + break; + } + + return message; +} + +bool pgTextSearchTemplate::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP TEXT SEARCH TEMPLATE ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + qtIdent(this->GetIdentifier()); + + if (cascaded) + sql += wxT(" CASCADE"); + + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgTextSearchTemplate::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Text Search Template: ") + GetFullIdentifier() + wxT("\n\n") + + wxT("-- DROP TEXT SEARCH TEMPLATE ") + GetFullIdentifier() + wxT("\n\n") + wxT("CREATE TEXT SEARCH TEMPLATE ") + GetFullIdentifier() + wxT(" ("); + AppendIfFilled(sql, wxT("\n INIT = "), GetInit()); + AppendIfFilled(sql, wxT(",\n LEXIZE = "), GetLexize()); + sql += wxT("\n);\n"); + + if (!GetComment().IsNull()) + sql += wxT("COMMENT ON TEXT SEARCH TEMPLATE ") + GetFullIdentifier() + + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + + return sql; +} + + +void pgTextSearchTemplate::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Init"), GetInit()); + properties->AppendItem(_("Lexize"), GetLexize()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgTextSearchTemplate::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *tstemplate = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + tstemplate = textSearchTemplateFactory.CreateObjects(coll, 0, wxT("\n AND tmpl.oid=") + GetOidStr()); + + return tstemplate; +} + + +/////////////////////////////////////////////////// + + +pgTextSearchTemplateCollection::pgTextSearchTemplateCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgTextSearchTemplateCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on FTS templates"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing FTS templates"); + break; + case OBJECTSLISTREPORT: + message = _("FTS templates list report"); + break; + } + + return message; +} + + +////////////////////////////////////////////////////// + + +pgObject *pgTextSearchTemplateFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgTextSearchTemplate *tmpl = 0; + + pgSet *templates; + templates = collection->GetDatabase()->ExecuteSet( + wxT("SELECT tmpl.oid, tmpl.tmplname, tmpl.tmplinit, tmpl.tmpllexize, description\n") + wxT(" FROM pg_ts_template tmpl\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=tmpl.oid AND des.classoid='pg_ts_template'::regclass)\n") + wxT(" WHERE tmpl.tmplnamespace = ") + collection->GetSchema()->GetOidStr() + + restriction + wxT("\n") + wxT(" ORDER BY tmpl.tmplname")); + + if (templates) + { + while (!templates->Eof()) + { + tmpl = new pgTextSearchTemplate(collection->GetSchema(), templates->GetVal(wxT("tmplname"))); + tmpl->iSetOid(templates->GetOid(wxT("oid"))); + tmpl->iSetComment(templates->GetVal(wxT("description"))); + if (templates->GetVal(wxT("tmplinit")).Cmp(wxT("-")) != 0) + { + tmpl->iSetInit(templates->GetVal(wxT("tmplinit"))); + } + else + { + tmpl->iSetInit(wxT("")); + } + tmpl->iSetLexize(templates->GetVal(wxT("tmpllexize"))); + + if (browser) + { + browser->AppendObject(collection, tmpl); + templates->MoveNext(); + } + else + break; + } + + delete templates; + } + return tmpl; +} + + +#include "images/template.pngc" +#include "images/templates.pngc" + +pgTextSearchTemplateFactory::pgTextSearchTemplateFactory() + : pgSchemaObjFactory(__("FTS Template"), __("New FTS Template..."), __("Create a new FTS Template."), template_png_img) +{ +} + + +pgCollection *pgTextSearchTemplateFactory::CreateCollection(pgObject *obj) +{ + return new pgTextSearchTemplateCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgTextSearchTemplateFactory textSearchTemplateFactory; +static pgaCollectionFactory cf(&textSearchTemplateFactory, __("FTS Templates"), templates_png_img); diff --git a/schema/pgTrigger.cpp b/schema/pgTrigger.cpp new file mode 100644 index 0000000..a381951 --- /dev/null +++ b/schema/pgTrigger.cpp @@ -0,0 +1,637 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgTrigger.cpp - Trigger class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "frm/frmMain.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" +#include "schema/pgObject.h" +#include "schema/pgTrigger.h" +#include "schema/pgFunction.h" + + +pgTrigger::pgTrigger(pgSchema *newSchema, const wxString &newName) + : pgTriggerObject(newSchema, triggerFactory, newName) +{ + triggerFunction = 0; +} + + +pgTrigger::~pgTrigger() +{ + if (!expandedKids && triggerFunction) + { + // triggerFunction wasn't appended to tree, so we + // need to delete it manually + delete triggerFunction; + } +} + +wxString pgTrigger::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on trigger"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing trigger"); + message += wxT(" ") + GetName(); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for trigger"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop trigger \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop trigger \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop trigger cascaded?"); + break; + case DROPTITLE: + message = _("Drop trigger?"); + break; + case PROPERTIESREPORT: + message = _("Trigger properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Trigger properties"); + break; + case DDLREPORT: + message = _("Trigger DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Trigger DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Trigger dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Trigger dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Trigger dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Trigger dependents"); + break; + } + + return message; +} + +int pgTrigger::GetIconId() +{ + if (GetEnabled()) + return triggerFactory.GetIconId(); + else + return triggerFactory.GetClosedIconId(); +} + + +bool pgTrigger::IsUpToDate() +{ + wxString sql = wxT("SELECT xmin FROM pg_trigger WHERE oid = ") + this->GetOidStr(); + if (!this->GetDatabase()->GetConnection() || this->GetDatabase()->ExecuteScalar(sql) != NumToStr(GetXid())) + return false; + else + return true; +} + +bool pgTrigger::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP TRIGGER ") + GetQuotedIdentifier() + wxT(" ON ") + GetQuotedFullTable(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +void pgTrigger::SetEnabled(ctlTree *browser, const bool b) +{ + if (GetQuotedFullTable().Len() > 0 && ((enabled && !b) || (!enabled && b))) + { + wxString sql = wxT("ALTER TABLE ") + GetQuotedFullTable() + wxT(" "); + if (enabled && !b) + sql += wxT("DISABLE"); + else if (!enabled && b) + sql += wxT("ENABLE"); + sql += wxT(" TRIGGER ") + GetQuotedIdentifier(); + GetDatabase()->ExecuteVoid(sql); + } + enabled = b; + UpdateIcon(browser); +} + + +void pgTrigger::SetDirty() +{ + if (expandedKids) + triggerFunction = 0; + pgObject::SetDirty(); +} + + +wxString pgTrigger::GetSql(ctlTree *browser) +{ + if (sql.IsNull() && (this->triggerFunction || GetLanguage() == wxT("edbspl"))) + { + sql = wxT("-- Trigger: ") + GetName() + wxT(" on ") + GetQuotedFullTable() + wxT("\n\n") + + wxT("-- DROP TRIGGER ") + qtIdent(GetName()) + + wxT(" ON ") + GetQuotedFullTable() + wxT(";\n\n"); + + if (GetLanguage() == wxT("edbspl")) + sql += wxT("CREATE OR REPLACE TRIGGER "); + else if (GetConnection()->BackendMinimumVersion(8, 2) && GetIsConstraint()) + sql += wxT("CREATE CONSTRAINT TRIGGER "); + else + sql += wxT("CREATE TRIGGER "); + + sql += qtIdent(GetName()) + wxT("\n ") + + GetFireWhen() + + wxT(" ") + GetEvent(); + + sql += wxT("\n ON ") + GetQuotedFullTable(); + if (GetDeferrable()) + { + sql += wxT("\n DEFERRABLE INITIALLY "); + if (GetDeferred()) + sql += wxT("DEFERRED"); + else + sql += wxT("IMMEDIATE"); + } + if (!GetReferences().IsEmpty()) + { + sql += wxT("\n ")+GetReferences(); + } + + sql += wxT("\n FOR EACH ") + GetForEach(); + + if (GetConnection()->BackendMinimumVersion(8, 5) + && !GetWhen().IsEmpty()) + sql += wxT("\n WHEN (") + GetWhen() + wxT(")"); + + if (GetLanguage() == wxT("edbspl")) + { + sql += wxT("\n") + GetSource(); + if (!sql.Trim().EndsWith(wxT(";"))) + sql = sql.Trim() + wxT(";"); + sql += wxT("\n"); + } + else + { + sql += wxT("\n EXECUTE PROCEDURE ") + triggerFunction->GetQuotedFullIdentifier() + + wxT("(") + GetArguments() + wxT(")") + + wxT(";\n"); + } + + if (!GetEnabled()) + { + sql += wxT("ALTER TABLE ") + GetQuotedFullTable() + wxT(" ") + + wxT("DISABLE TRIGGER ") + GetQuotedIdentifier() + wxT(";\n"); + } + + if (!GetComment().IsEmpty()) + sql += wxT("COMMENT ON TRIGGER ") + GetQuotedIdentifier() + wxT(" ON ") + GetQuotedFullTable() + + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + + return sql; +} + + +wxString pgTrigger::GetFireWhen() const +{ + wxString when = wxEmptyString; + + if (triggerType & TRIGGER_TYPE_BEFORE) + when = wxT("BEFORE"); + else if (triggerType & TRIGGER_TYPE_INSTEAD) + when = wxT("INSTEAD OF"); + else + when = wxT("AFTER"); + return when; +} + + +wxString pgTrigger::GetEvent() const +{ + wxString event; + if (triggerType & TRIGGER_TYPE_INSERT) + event = wxT("INSERT"); + if (triggerType & TRIGGER_TYPE_UPDATE) + { + if (!event.IsNull()) + event += wxT(" OR "); + event += wxT("UPDATE"); + if (!GetQuotedColumns().IsEmpty()) + event += wxT(" OF ") + GetQuotedColumns(); + } + if (triggerType & TRIGGER_TYPE_DELETE) + { + if (!event.IsNull()) + event += wxT(" OR "); + event += wxT("DELETE"); + } + if (triggerType & TRIGGER_TYPE_TRUNCATE) + { + if (!event.IsNull()) + event += wxT(" OR "); + event += wxT("TRUNCATE"); + } + return event; +} + +wxString pgTrigger::GetForEach() const +{ + return (triggerType & TRIGGER_TYPE_ROW) ? wxT("ROW") : wxT("STATEMENT"); +} + + + +void pgTrigger::ReadColumnDetails() +{ + if (!expandedKids) + { + expandedKids = true; + + if (GetConnection()->BackendMinimumVersion(8, 5)) + { + pgSet *res = ExecuteSet( + wxT("SELECT attname\n") + wxT("FROM pg_attribute,\n") + wxT("(SELECT tgrelid, unnest(tgattr) FROM pg_trigger\n") + wxT(" WHERE oid=") + GetOidStr() + wxT(") AS columns(tgrelid, colnum)\n") + wxT("WHERE colnum=attnum AND tgrelid=attrelid")); + + // Allocate memory to store column def + if (res->NumRows() > 0) columnList.Alloc(res->NumRows()); + + long i = 1; + columns = wxT(""); + quotedColumns = wxT(""); + + while (!res->Eof()) + { + if (i > 1) + { + columns += wxT(", "); + quotedColumns += wxT(", "); + } + + columns += res->GetVal(wxT("attname")); + quotedColumns += qtIdent(res->GetVal(wxT("attname"))); + columnList.Add(res->GetVal(wxT("attname"))); + + i++; + res->MoveNext(); + } + delete res; + } + else + { + columns = wxT(""); + quotedColumns = wxT(""); + } + } +} + + +void pgTrigger::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + ReadColumnDetails(); + + if (browser) + { + // if no browser present, function will not be appended to tree + expandedKids = true; + } + + if (GetLanguage() != wxT("edbspl")) + { + if (triggerFunction) + delete triggerFunction; + + // append function here + triggerFunction = functionFactory.AppendFunctions(this, GetSchema(), browser, wxT( + "WHERE pr.oid=") + NumToStr(functionOid) + wxT("::oid\n")); + if (triggerFunction) + { + iSetFunction(triggerFunction->GetQuotedFullIdentifier()); + } + } + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + if (GetConnection()->BackendMinimumVersion(8, 2)) + properties->AppendYesNoItem(_("Constraint?"), GetIsConstraint()); + properties->AppendItem(_("Fires"), GetFireWhen()); + properties->AppendItem(_("Event"), GetEvent()); + if (!GetQuotedColumns().IsEmpty()) + { + properties->AppendItem(_("Columns"), GetColumns()); + } + properties->AppendItem(_("For each"), GetForEach()); + if (GetLanguage() != wxT("edbspl")) + properties->AppendItem(_("Function"), GetFunction() + wxT("(") + GetArguments() + wxT(")")); + if (GetConnection()->BackendMinimumVersion(8, 5)) + properties->AppendItem(_("When?"), GetWhen()); + properties->AppendYesNoItem(_("Enabled?"), GetEnabled()); + properties->AppendYesNoItem(_("System trigger?"), GetSystemObject()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgTrigger::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *trigger = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + { + wxString restr = wxT("\n AND t.tgname=") + qtDbString(GetName()) + + wxT(" AND cl.oid=") + NumToStr(GetRelationOid()) + + wxT("::oid AND cl.relnamespace=") + GetSchema()->GetOidStr() + wxT("::oid"); + trigger = triggerFactory.CreateObjects(coll, 0, restr); + } + + return trigger; +} + + + +pgObject *pgTriggerFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restriction) +{ + pgSchemaObjCollection *collection = (pgSchemaObjCollection *)coll; + pgTrigger *trigger = 0; + wxString ref=wxT(""); + if (collection->GetDatabase()->connection()->BackendMinimumVersion(10, 0)) + { + ref = wxT("tgoldtable,tgnewtable,"); + } + + wxString trig_sql; + trig_sql = wxT("SELECT t.oid, t.xmin, t.*, relname, CASE WHEN relkind = 'r' THEN TRUE ELSE FALSE END AS parentistable, ")+ref+ + wxT(" nspname, des.description, l.lanname, p.prosrc, \n") + wxT(" COALESCE(substring(pg_get_triggerdef(t.oid), 'WHEN (.*) EXECUTE PROCEDURE'), substring(pg_get_triggerdef(t.oid), 'WHEN (.*) \\$trigger')) AS whenclause\n") + wxT(" FROM pg_trigger t\n") + wxT(" JOIN pg_class cl ON cl.oid=tgrelid\n") + wxT(" JOIN pg_namespace na ON na.oid=relnamespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=t.oid AND des.classoid='pg_trigger'::regclass)\n") + wxT(" LEFT OUTER JOIN pg_proc p ON p.oid=t.tgfoid\n") + wxT(" LEFT OUTER JOIN pg_language l ON l.oid=p.prolang\n") + wxT(" WHERE "); + if (collection->GetDatabase()->connection()->BackendMinimumVersion(9, 0)) + { + trig_sql += wxT("NOT tgisinternal"); + } + else if (collection->GetDatabase()->connection()->BackendMinimumVersion(8, 3)) + { + trig_sql += wxT("tgconstraint=0"); + } + else + { + trig_sql += wxT("NOT tgisconstraint"); + } + if (restriction.IsEmpty()) + trig_sql += wxT("\n AND tgrelid = ") + collection->GetOidStr() + wxT("\n"); + else + trig_sql += restriction + wxT("\n"); + trig_sql += wxT(" ORDER BY tgname"); + pgSet *triggers = collection->GetDatabase()->ExecuteSet(trig_sql); + + if (triggers) + { + while (!triggers->Eof()) + { + // Be careful that the schema of a trigger (and a rule) is the schema of the schema + trigger = new pgTrigger(collection->GetSchema()->GetSchema(), triggers->GetVal(wxT("tgname"))); + + trigger->iSetOid(triggers->GetOid(wxT("oid"))); + trigger->iSetXid(triggers->GetOid(wxT("xmin"))); + trigger->iSetComment(triggers->GetVal(wxT("description"))); + trigger->iSetFunctionOid(triggers->GetOid(wxT("tgfoid"))); + trigger->iSetRelationOid(triggers->GetOid(wxT("tgrelid"))); + if (!ref.IsEmpty()) { + wxString strsum=wxT(""); + if (!triggers->GetVal(wxT("tgoldtable")).IsEmpty()) { + strsum=wxT("REFERENCING OLD TABLE AS ")+triggers->GetVal(wxT("tgoldtable")); + } + if (!triggers->GetVal(wxT("tgnewtable")).IsEmpty()) { + if (strsum.IsEmpty()) strsum=wxT("REFERENCING"); + strsum+=wxT(" NEW TABLE AS ")+triggers->GetVal(wxT("tgnewtable")); + } + + trigger->iSetReferences(strsum); + } + if (collection->GetDatabase()->connection()->BackendMinimumVersion(8, 3)) + { + if (triggers->GetVal(wxT("tgenabled")) != wxT("D")) + trigger->iSetEnabled(true); + else + trigger->iSetEnabled(false); + } + else + trigger->iSetEnabled(triggers->GetBool(wxT("tgenabled"))); + + if (collection->GetDatabase()->connection()->BackendMinimumVersion(8, 2)) + { + if (collection->GetDatabase()->connection()->BackendMinimumVersion(9, 0)) + trigger->SetIsConstraint(triggers->GetLong(wxT("tgconstraint")) > 0); + else + trigger->SetIsConstraint(triggers->GetBool(wxT("tgisconstraint"))); + + trigger->iSetDeferrable(triggers->GetBool(wxT("tgdeferrable"))); + trigger->iSetDeferred(triggers->GetBool(wxT("tginitdeferred"))); + } + else + { + trigger->SetIsConstraint(false); + trigger->iSetDeferrable(false); + trigger->iSetDeferred(false); + } + + trigger->iSetTriggerType(triggers->GetLong(wxT("tgtype"))); + trigger->iSetParentIsTable(triggers->GetBool(wxT("parentistable"))); + + trigger->iSetLanguage(triggers->GetVal(wxT("lanname"))); + trigger->iSetSource(triggers->GetVal(wxT("prosrc"))); + trigger->iSetQuotedFullTable(collection->GetDatabase()->GetQuotedSchemaPrefix(triggers->GetVal(wxT("nspname"))) + qtIdent(triggers->GetVal(wxT("relname")))); + wxString arglist = wxEmptyString; + if (triggers->GetLong(wxT("tgnargs")) > 0) + arglist = triggers->GetVal(wxT("tgargs")); + wxString args = wxEmptyString; + + while (!arglist.IsEmpty()) + { + int pos = arglist.Find(wxT("\\000")); + if (pos != 0) + { + wxString arg; + if (pos > 0) + arg = arglist.Left(pos); + else + arg = arglist; + + if (!args.IsEmpty()) + args += wxT(", "); + if (NumToStr(StrToLong(arg)) == arg) + args += arg; + else + args += collection->GetDatabase()->GetConnection()->qtDbString(arg); + } + else + { + if (!args.IsEmpty()) + args += wxT(", "); + args += collection->GetDatabase()->GetConnection()->qtDbString(wxEmptyString); + } + if (pos >= 0) + arglist = arglist.Mid(pos + 4); + else + break; + } + trigger->iSetArguments(args); + + if (collection->GetDatabase()->connection()->BackendMinimumVersion(8, 5)) + { + wxString clause = triggers->GetVal(wxT("whenclause")); + trigger->iSetWhen(clause.SubString(1, clause.Length() - 2)); + } + + if (browser) + { + browser->AppendObject(collection, trigger); + triggers->MoveNext(); + } + else + break; + } + + delete triggers; + } + return trigger; +} + + +///////////////////////////// + + +pgTriggerCollection::pgTriggerCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgTriggerCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on triggers"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing triggers"); + break; + case OBJECTSLISTREPORT: + message = _("Triggers list report"); + break; + } + + return message; +} + + +///////////////////////////// + +#include "images/trigger.pngc" +#include "images/triggerbad.pngc" +#include "images/triggers.pngc" + +pgTriggerFactory::pgTriggerFactory() + : pgSchemaObjFactory(__("Trigger"), __("New Trigger..."), __("Create a new Trigger."), trigger_png_img) +{ + metaType = PGM_TRIGGER; + closedId = addIcon(triggerbad_png_img); +} + + +pgCollection *pgTriggerFactory::CreateCollection(pgObject *obj) +{ + return new pgTriggerCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgTriggerFactory triggerFactory; +static pgaCollectionFactory cf(&triggerFactory, __("Triggers"), triggers_png_img); + +enabledisableTriggerFactory::enabledisableTriggerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Trigger enabled?"), _("Enable or disable selected trigger."), wxITEM_CHECK); +} + + +wxWindow *enabledisableTriggerFactory::StartDialog(frmMain *form, pgObject *obj) +{ + ((pgTrigger *)obj)->SetEnabled(form->GetBrowser(), !((pgTrigger *)obj)->GetEnabled()); + ((pgTrigger *)obj)->SetDirty(); + + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + { + form->GetBrowser()->DeleteChildren(item); + obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties()); + form->GetSqlPane()->SetReadOnly(false); + form->GetSqlPane()->SetText(((pgTrigger *)obj)->GetSql(form->GetBrowser())); + form->GetSqlPane()->SetReadOnly(true); + } + form->GetMenuFactories()->CheckMenu(obj, form->GetMenuBar(), (ctlMenuToolbar *)form->GetToolBar()); + + return 0; +} + + +bool enabledisableTriggerFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(triggerFactory) && obj->CanEdit() + && ((pgTrigger *)obj)->GetConnection()->BackendMinimumVersion(8, 1) + && ((pgTrigger *)obj)->GetParentIsTable(); +} + +bool enabledisableTriggerFactory::CheckChecked(pgObject *obj) +{ + return obj && obj->IsCreatedBy(triggerFactory) && ((pgTrigger *)obj)->GetEnabled(); +} diff --git a/schema/pgType.cpp b/schema/pgType.cpp new file mode 100644 index 0000000..510782f --- /dev/null +++ b/schema/pgType.cpp @@ -0,0 +1,572 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgType.cpp - Type class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgType.h" +#include "schema/pgDatatype.h" + + +pgType::pgType(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, typeFactory, newName) +{ +} + +pgType::~pgType() +{ +} + +wxString pgType::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on type"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing type"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop type \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop type \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop type cascaded?"); + break; + case DROPTITLE: + message = _("Drop type?"); + break; + case PROPERTIESREPORT: + message = _("Type properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Type properties"); + break; + case DDLREPORT: + message = _("Type DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Type DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Type dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Type dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Type dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Type dependents"); + break; + } + + return message; +} + + +bool pgType::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP TYPE ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + +wxString pgType::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Type: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP TYPE ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE TYPE ") + GetQuotedFullIdentifier(); + if (GetTypeClass() == TYPE_COMPOSITE) + { + sql += wxT(" AS\n ("); + sql += GetQuotedTypesList(); + } + else if (GetTypeClass() == TYPE_ENUM) + { + sql += wxT(" AS ENUM\n ("); + sql += GetQuotedLabelList(); + } + else if (GetTypeClass() == TYPE_RANGE) + { + sql += wxT(" AS RANGE\n (") + wxT("SUBTYPE=") + rngsubtypestr; + if (!rngsubopcstr.IsEmpty()) + sql += wxT(",\n SUBTYPE_OPCLASS=") + rngsubopcstr; + if (!rngcollationstr.IsEmpty()) + sql += wxT(",\n COLLATION=") + rngcollationstr; + if (!rngcanonical.IsEmpty()) + sql += wxT(",\n CANONICAL=") + rngcanonical; + if (!rngsubdiff.IsEmpty()) + sql += wxT(",\n SUBTYPE_DIFF=") + rngsubdiff; + } + else + { + sql += wxT("\n (INPUT=") + qtIdent(GetInputFunction()) + + wxT(",\n OUTPUT=") + qtIdent(GetOutputFunction()); + if (GetConnection()->BackendMinimumVersion(7, 4)) + { + if (!GetReceiveFunction().IsEmpty()) + { + sql += wxT(",\n RECEIVE=") + GetReceiveFunction(); + } + if (!GetSendFunction().IsEmpty()) + { + sql += wxT(",\n SEND=") + GetSendFunction(); + } + } + if (GetConnection()->BackendMinimumVersion(8, 3)) + { + if (!GetTypmodinFunction().IsEmpty()) + sql += wxT(",\n TYPMOD_IN=") + GetTypmodinFunction(); + if (!GetTypmodoutFunction().IsEmpty()) + sql += wxT(",\n TYPMOD_OUT=") + GetTypmodoutFunction(); + if (GetAnalyzeFunction() != wxEmptyString) + sql += wxT(",\n ANALYZE=") + GetAnalyzeFunction(); + } + if (GetConnection()->BackendMinimumVersion(8, 4)) + { + sql += wxT(",\n CATEGORY=") + qtDbString(GetCategory()); + if (GetPrefered()) + sql += wxT(",\n PREFERRED=true"); + } + if (GetPassedByValue()) + sql += wxT(",\n PASSEDBYVALUE"); + AppendIfFilled(sql, wxT(", DEFAULT="), qtDbString(GetDefault())); + if (!GetElement().IsNull()) + { + sql += wxT(",\n ELEMENT=") + GetElement() + + wxT(", DELIMITER='") + GetDelimiter() + wxT("'"); + } + sql += wxT(",\n INTERNALLENGTH=") + NumToStr(GetInternalLength()) + + wxT(", ALIGNMENT=" + GetAlignment() + + wxT(", STORAGE=") + GetStorage()); + if (GetConnection()->BackendMinimumVersion(9, 1) && GetCollatable()) + { + sql += wxT(",\n COLLATABLE=true"); + } + if (GetConnection()->BackendMinimumVersion(9, 1) && GetCollatable()) + { + sql += wxT(",\n COLLATABLE=true"); + } + } + sql += wxT(");\n") + + GetOwnerSql(8, 0) + + GetCommentSql(); + + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += GetSeqLabelsSql(); + } + + return sql; +} + + + +void pgType::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + wxString query; + wxString collation; + + if (!expandedKids) + { + expandedKids = true; + if (GetTypeClass() == TYPE_COMPOSITE) + { + query = wxT("SELECT attname, format_type(t.oid,NULL) AS typname, attndims, atttypmod, nsp.nspname,\n") + wxT(" (SELECT COUNT(1) from pg_type t2 WHERE t2.typname=t.typname) > 1 AS isdup"); + if (GetConnection()->BackendMinimumVersion(9, 1)) + query += wxT(",\n collname, nspc.nspname as collnspname"); + query += wxT("\n FROM pg_attribute att\n") + wxT(" JOIN pg_type t ON t.oid=atttypid\n") + wxT(" JOIN pg_namespace nsp ON t.typnamespace=nsp.oid\n") + wxT(" LEFT OUTER JOIN pg_type b ON t.typelem=b.oid\n"); + if (GetConnection()->BackendMinimumVersion(9, 1)) + query += wxT(" LEFT OUTER JOIN pg_collation c ON att.attcollation=c.oid\n") + wxT(" LEFT OUTER JOIN pg_namespace nspc ON c.collnamespace=nspc.oid\n"); + query += wxT(" WHERE att.attrelid=") + NumToStr(relOid) + wxT("\n") + wxT(" ORDER by attnum"); + pgSet *set = ExecuteSet(query); + if (set) + { + int anzvar = 0; + while (!set->Eof()) + { + if (anzvar++) + { + typesList += wxT(", "); + quotedTypesList += wxT(",\n "); + } + typesList += set->GetVal(wxT("attname")) + wxT(" "); + typesArray.Add(set->GetVal(wxT("attname"))); + quotedTypesList += qtIdent(set->GetVal(wxT("attname"))) + wxT(" "); + + pgDatatype dt(set->GetVal(wxT("nspname")), set->GetVal(wxT("typname")), + set->GetBool(wxT("isdup")), set->GetLong(wxT("attndims")) > 0, set->GetLong(wxT("atttypmod"))); + + typesList += dt.GetSchemaPrefix(GetDatabase()) + dt.FullName(); + typesArray.Add(dt.GetSchemaPrefix(GetDatabase()) + dt.FullName()); + quotedTypesList += dt.GetQuotedSchemaPrefix(GetDatabase()) + dt.QuotedFullName(); + + if (GetConnection()->BackendMinimumVersion(9, 1)) + { + if (set->GetVal(wxT("collname")).IsEmpty() || (set->GetVal(wxT("collname")) == wxT("default") && set->GetVal(wxT("collnspname")) == wxT("pg_catalog"))) + collation = wxEmptyString; + else + { + collation = qtIdent(set->GetVal(wxT("collnspname"))) + wxT(".") + qtIdent(set->GetVal(wxT("collname"))); + quotedTypesList += wxT(" COLLATE ") + collation; + } + collationsArray.Add(collation); + } + typesArray.Add(collation); + + set->MoveNext(); + } + delete set; + } + } + else if (GetTypeClass() == TYPE_ENUM) + { + query = wxT("SELECT enumlabel\n") + wxT(" FROM pg_enum\n") + wxT(" WHERE enumtypid=") + GetOidStr() + wxT("\n"); + if (GetConnection()->BackendMinimumVersion(9, 1)) + query += wxT(" ORDER by enumsortorder"); + else + query += wxT(" ORDER by oid"); + pgSet *set = ExecuteSet(query); + if (set) + { + int anzvar = 0; + while (!set->Eof()) + { + if (anzvar++) + { + labelList += wxT(", "); + quotedLabelList += wxT(",\n "); + } + labelList += set->GetVal(wxT("enumlabel")); + labelArray.Add(set->GetVal(wxT("enumlabel"))); + quotedLabelList += GetDatabase()->connection()->qtDbString(set->GetVal(wxT("enumlabel"))); + + set->MoveNext(); + } + delete set; + } + } + else if (GetTypeClass() == TYPE_RANGE) + { + query = wxT("SELECT rngsubtype, st.typname, ") + wxT("rngcollation, col.collname, ") + wxT("rngsubopc, opc.opcname, ") + wxT("rngcanonical, rngsubdiff\n") + wxT("FROM pg_range\n") + wxT("LEFT JOIN pg_type st ON st.oid=rngsubtype\n") + wxT("LEFT JOIN pg_collation col ON col.oid=rngcollation\n") + wxT("LEFT JOIN pg_opclass opc ON opc.oid=rngsubopc\n") + wxT("WHERE rngtypid=") + GetOidStr(); + pgSet *set = ExecuteSet(query); + if (set) + { + iSetSubtypeFunction(set->GetLong(wxT("rngsubtype"))); + iSetSubtypeFunctionStr(set->GetVal(wxT("typname"))); + iSetCollationFunction(set->GetLong(wxT("rngcollation"))); + iSetCollationFunctionStr(set->GetVal(wxT("collname"))); + iSetSubtypeOpClassFunction(set->GetLong(wxT("rngsubopc"))); + iSetSubtypeOpClassFunctionStr(set->GetVal(wxT("opcname"))); + if (set->GetVal(wxT("rngcanonical")) != wxT("-")) + iSetCanonical(set->GetVal(wxT("rngcanonical"))); + if (set->GetVal(wxT("rngsubdiff")) != wxT("-")) + iSetSubtypeDiff(set->GetVal(wxT("rngsubdiff"))); + } + delete set; + } + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + if (GetConnection()->BackendMinimumVersion(9, 2)) + properties->AppendItem(_("ACL"), GetAcl()); + properties->AppendItem(_("Alias"), GetAlias()); + if (GetTypeClass() == TYPE_COMPOSITE) + { + properties->AppendItem(_("Members"), GetTypesList()); + } + if (GetTypeClass() == TYPE_ENUM) + { + properties->AppendItem(_("Labels"), GetLabelList()); + } + else if (GetTypeClass() == TYPE_RANGE) + { + properties->AppendItem(_("Subtype"), GetSubtypeFunctionStr()); + properties->AppendItem(_("Collation"), GetCollationFunctionStr()); + properties->AppendItem(_("Subtype OpClass"), GetSubtypeOpClassFunctionStr()); + properties->AppendItem(_("Canonical"), GetCanonical()); + properties->AppendItem(_("Subtype diff"), GetSubtypeDiff()); + } + else + { + properties->AppendItem(_("Alignment"), GetAlignment()); + properties->AppendItem(_("Internal length"), GetInternalLength()); + properties->AppendItem(_("Default"), GetDefault()); + properties->AppendItem(_("Passed by Value?"), BoolToYesNo(GetPassedByValue())); + if (!GetElement().IsEmpty()) + { + properties->AppendItem(_("Element"), GetElement()); + properties->AppendItem(_("Delimiter"), GetDelimiter()); + } + properties->AppendItem(_("Input function"), GetInputFunction()); + properties->AppendItem(_("Output function"), GetOutputFunction()); + if (GetConnection()->BackendMinimumVersion(7, 4)) + { + properties->AppendItem(_("Receive function"), GetReceiveFunction()); + properties->AppendItem(_("Send function"), GetSendFunction()); + properties->AppendItem(_("Analyze function"), GetAnalyzeFunction()); + } + if (GetConnection()->BackendMinimumVersion(8, 4)) + { + properties->AppendItem(_("Category"), GetCategory()); + properties->AppendItem(_("Prefered?"), BoolToYesNo(GetPrefered())); + } + if (GetConnection()->BackendMinimumVersion(8, 3)) + { + if (GetTypmodinFunction().Length() > 0) + properties->AppendItem(_("Typmod in function"), GetTypmodinFunction()); + if (GetTypmodoutFunction().Length() > 0) + properties->AppendItem(_("Typmod out function"), GetTypmodoutFunction()); + } + properties->AppendItem(_("Storage"), GetStorage()); + if (GetConnection()->BackendMinimumVersion(9, 1)) + properties->AppendItem(_("Collatable?"), BoolToYesNo(GetCollatable())); + } + properties->AppendYesNoItem(_("System type?"), GetSystemObject()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + if (!GetLabels().IsEmpty()) + { + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); + } + } + } + } +} + + + +pgObject *pgType::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *type = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + type = typeFactory.CreateObjects(coll, 0, wxT("\n AND t.oid=") + GetOidStr()); + + return type; +} + + +/////////////////////////////////////////////////// + + +pgTypeCollection::pgTypeCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgTypeCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on types"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing types"); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for types"); + break; + case OBJECTSLISTREPORT: + message = _("Types list report"); + break; + } + + return message; +} + + +///////////////////////////////////////////////////////// + + +pgObject *pgTypeFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgType *type = 0; + wxString systemRestriction; + if (!settings->GetShowSystemObjects()) + systemRestriction = wxT(" AND ct.oid IS NULL\n"); + + wxString sql = wxT("SELECT t.oid, t.*, format_type(t.oid, null) AS alias,\n") + wxT("pg_get_userbyid(t.typowner) as typeowner, e.typname as element,\n") + wxT("description, ct.oid AS taboid"); + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + sql += wxT(",\n(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=t.oid) AS labels"); + sql += wxT(",\n(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=t.oid) AS providers"); + } + sql += wxT("\n FROM pg_type t\n") + wxT(" LEFT OUTER JOIN pg_type e ON e.oid=t.typelem\n") + wxT(" LEFT OUTER JOIN pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c'\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=t.oid AND des.classoid='pg_type'::regclass)\n"); + + if (collection->GetDatabase()->BackendMinimumVersion(8, 1)) + sql += wxT(" WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\\\_%' AND t.typnamespace = ") + collection->GetSchema()->GetOidStr() + wxT("\n"); + else + sql += wxT(" WHERE t.typtype != 'd' AND t.typname NOT LIKE '\\\\_%' AND t.typnamespace = ") + collection->GetSchema()->GetOidStr() + wxT("\n"); + + sql += restriction + systemRestriction + + wxT(" ORDER BY t.typname"); + + pgSet *types = collection->GetDatabase()->ExecuteSet(sql); + + if (types) + { + while (!types->Eof()) + { + type = new pgType(collection->GetSchema(), types->GetVal(wxT("typname"))); + + type->iSetOid(types->GetOid(wxT("oid"))); + type->iSetOwner(types->GetVal(wxT("typeowner"))); + if (collection->GetConnection()->BackendMinimumVersion(9, 2)) + type->iSetAcl(types->GetVal(wxT("typacl"))); + type->iSetAlias(types->GetVal(wxT("alias"))); + type->iSetComment(types->GetVal(wxT("description"))); + type->iSetPassedByValue(types->GetBool(wxT("typbyval"))); + + if (types->GetVal(wxT("typtype")) == wxT("c")) + type->iSetTypeClass(TYPE_COMPOSITE); + else if (types->GetVal(wxT("typtype")) == wxT("e")) + type->iSetTypeClass(TYPE_ENUM); + else if (types->GetVal(wxT("typtype")) == wxT("r")) + type->iSetTypeClass(TYPE_RANGE); + else + type->iSetTypeClass(TYPE_EXTERNAL); + + type->iSetRelOid(types->GetOid(wxT("typrelid"))); + type->iSetIsRecordType(types->GetOid(wxT("taboid")) != 0); + type->iSetInternalLength(types->GetLong(wxT("typlen"))); + type->iSetDelimiter(types->GetVal(wxT("typdelim"))); + type->iSetElement(types->GetVal(wxT("element"))); + type->iSetInputFunction(types->GetVal(wxT("typinput"))); + type->iSetOutputFunction(types->GetVal(wxT("typoutput"))); + if (collection->GetConnection()->BackendMinimumVersion(7, 4)) + { + type->iSetReceiveFunction(types->GetVal(wxT("typreceive"))); + type->iSetSendFunction(types->GetVal(wxT("typsend"))); + type->iSetAnalyzeFunction(types->GetVal(wxT("typanalyze"))); + } + if (collection->GetConnection()->BackendMinimumVersion(8, 4)) + { + type->iSetCategory(types->GetVal(wxT("typcategory"))); + type->iSetPrefered(types->GetBool(wxT("typispreferred"))); + } + if (collection->GetConnection()->BackendMinimumVersion(8, 3)) + { + if (types->GetVal(wxT("typmodin")) != wxT("-")) + type->iSetTypmodinFunction(types->GetVal(wxT("typmodin"))); + if (types->GetVal(wxT("typmodout")) != wxT("-")) + type->iSetTypmodoutFunction(types->GetVal(wxT("typmodout"))); + } + wxString align = types->GetVal(wxT("typalign")); + type->iSetAlignment( + align == wxT("c") ? wxT("char") : + align == wxT("s") ? wxT("int2") : + align == wxT("i") ? wxT("int4") : + align == wxT("d") ? wxT("double") : wxT("unknown")); + type->iSetDefault(types->GetVal(wxT("typdefault"))); + wxString storage = types->GetVal(wxT("typstorage")); + type->iSetStorage( + storage == wxT("p") ? wxT("PLAIN") : + storage == wxT("e") ? wxT("EXTERNAL") : + storage == wxT("m") ? wxT("MAIN") : + storage == wxT("x") ? wxT("EXTENDED") : wxT("unknown")); + if (collection->GetConnection()->BackendMinimumVersion(9, 1)) + type->iSetCollatable(types->GetLong(wxT("typcollation")) == 100); + + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + type->iSetProviders(types->GetVal(wxT("providers"))); + type->iSetLabels(types->GetVal(wxT("labels"))); + } + + if (browser) + { + browser->AppendObject(collection, type); + types->MoveNext(); + } + else + break; + } + + delete types; + } + return type; +} + + +#include "images/type.pngc" +#include "images/types.pngc" + +pgTypeFactory::pgTypeFactory() + : pgSchemaObjFactory(__("Type"), __("New Type..."), __("Create a new Type."), type_png_img) +{ +} + + +pgCollection *pgTypeFactory::CreateCollection(pgObject *obj) +{ + return new pgTypeCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgTypeFactory typeFactory; +static pgaCollectionFactory cf(&typeFactory, __("Types"), types_png_img); diff --git a/schema/pgUser.cpp b/schema/pgUser.cpp new file mode 100644 index 0000000..4ca8f02 --- /dev/null +++ b/schema/pgUser.cpp @@ -0,0 +1,387 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgUser.cpp - PostgreSQL User (only used on pre-8.1 versions, pgRole +// is used on newer versions). +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgUser.h" +#include "frm/frmMain.h" +#include "utils/pgDefs.h" +#include "schema/pgDatabase.h" +#include "schema/pgTablespace.h" + +pgUser::pgUser(const wxString &newName) + : pgServerObject(userFactory, newName) +{ +} + +wxString pgUser::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on user"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing user"); + message += wxT(" ") + GetName(); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for user"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop user \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop user \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop user cascaded?"); + break; + case DROPTITLE: + message = _("Drop user?"); + break; + case PROPERTIESREPORT: + message = _("User properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("User properties"); + break; + case DDLREPORT: + message = _("User DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("User DDL"); + break; + case DEPENDENCIESREPORT: + message = _("User dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("User dependencies"); + break; + case DEPENDENTSREPORT: + message = _("User dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("User dependents"); + break; + } + + return message; +} + + +bool pgUser::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + if (GetUpdateCatalog()) + { + wxMessageDialog dlg(frame, + _("Deleting a superuser might result in unwanted behaviour (e.g. when restoring the database).\nAre you sure?"), + _("Confirm superuser deletion"), + wxICON_EXCLAMATION | wxYES_NO | wxNO_DEFAULT); + if (dlg.ShowModal() != wxID_YES) + return false; + } + return server->ExecuteVoid(wxT("DROP USER ") + GetQuotedFullIdentifier() + wxT(";")); +} + + +wxString pgUser::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- User: ") + GetName() + wxT("\n\n") + + wxT("-- DROP USER ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE USER ") + GetQuotedIdentifier() + + wxT("\n WITH SYSID ") + NumToStr(userId); + if (GetPassword() != wxT("********")) + AppendIfFilled(sql, wxT("\n ENCRYPTED PASSWORD "), qtDbString(GetPassword())); + sql += wxT("\n "); + if (GetCreateDatabase()) sql += wxT(" CREATEDB"); + else sql += wxT(" NOCREATEDB"); + if (GetUpdateCatalog()) sql += wxT(" CREATEUSER"); + else sql += wxT(" NOCREATEUSER"); + if (GetAccountExpires().IsValid()) + AppendIfFilled(sql, wxT(" VALID UNTIL "), qtDbString(DateToAnsiStr(GetAccountExpires()))); + sql += wxT(";\n"); + + size_t index; + for (index = 0 ; index < configList.GetCount() ; index++) + { + if (configList.Item(index).BeforeFirst('=') != wxT("search_path") && + configList.Item(index).BeforeFirst('=') != wxT("temp_tablespaces")) + sql += wxT("ALTER USER ") + GetQuotedIdentifier() + + wxT(" SET ") + configList.Item(index).BeforeFirst('=') + wxT("='") + configList.Item(index).AfterFirst('=') + wxT("';\n"); + else + sql += wxT("ALTER USER ") + GetQuotedIdentifier() + + wxT(" SET ") + configList.Item(index).BeforeFirst('=') + wxT("=") + configList.Item(index).AfterFirst('=') + wxT(";\n"); + } + for (index = 0 ; index < groupsIn.GetCount() ; index++) + sql += wxT("ALTER GROUP ") + qtIdent(groupsIn.Item(index)) + + wxT(" ADD USER ") + GetQuotedIdentifier() + wxT(";\n"); + + } + return sql; +} + + + +void pgUser::ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &where) +{ + form->StartMsg(_(" Retrieving user owned objects")); + + referencedBy->ClearAll(); + referencedBy->AddColumn(_("Type"), 60); + referencedBy->AddColumn(_("Database"), 80); + referencedBy->AddColumn(_("Name"), 300); + + wxString uid = NumToStr(GetUserId()); + wxString sysoid = NumToStr(GetConnection()->GetLastSystemOID()); + + wxArrayString dblist; + + pgSet *set; + if (GetConnection()->BackendMinimumVersion(7, 5)) + set = GetConnection()->ExecuteSet( + wxT("SELECT 'd' as type, datname, datallowconn, datdba\n") + wxT(" FROM pg_database db\n") + wxT("UNION\n") + wxT("SELECT 'M', spcname, null, null\n") + wxT(" FROM pg_tablespace where spcowner=") + uid + wxT("\n") + wxT(" ORDER BY 1, 2")); + else + set = GetConnection()->ExecuteSet( + wxT("SELECT 'd' as type, datname, datallowconn, datdba\n") + wxT(" FROM pg_database db")); + + if (set) + { + while (!set->Eof()) + { + wxString name = set->GetVal(wxT("datname")); + if (set->GetVal(wxT("type")) == wxT("d")) + { + if (set->GetBool(wxT("datallowconn"))) + dblist.Add(name); + if (GetUserId() == set->GetLong(wxT("datdba"))) + referencedBy->AppendItem(databaseFactory.GetIconId(), _("Database"), name); + } + else + referencedBy->AppendItem(tablespaceFactory.GetIconId(), _("Tablespace"), wxEmptyString, name); + + set->MoveNext(); + } + delete set; + } + + FillOwned(form->GetBrowser(), referencedBy, dblist, + wxT("SELECT cl.relkind, COALESCE(cin.nspname, cln.nspname) as nspname, COALESCE(ci.relname, cl.relname) as relname, cl.relname as indname\n") + wxT(" FROM pg_class cl\n") + wxT(" JOIN pg_namespace cln ON cl.relnamespace=cln.oid\n") + wxT(" LEFT OUTER JOIN pg_index ind ON ind.indexrelid=cl.oid\n") + wxT(" LEFT OUTER JOIN pg_class ci ON ind.indrelid=ci.oid\n") + wxT(" LEFT OUTER JOIN pg_namespace cin ON ci.relnamespace=cin.oid\n") + wxT(" WHERE cl.relowner = ") + uid + wxT(" AND cl.oid > ") + sysoid + wxT("\n") + wxT("UNION ALL\n") + wxT("SELECT 'n', null, nspname, null\n") + wxT(" FROM pg_namespace nsp WHERE nspowner = ") + uid + wxT(" AND nsp.oid > ") + sysoid + wxT("\n") + wxT("UNION ALL\n") + wxT("SELECT CASE WHEN typtype='d' THEN 'd' ELSE 'y' END, null, typname, null\n") + wxT(" FROM pg_type ty WHERE typowner = ") + uid + wxT(" AND ty.oid > ") + sysoid + wxT("\n") + wxT("UNION ALL\n") + wxT("SELECT 'C', null, conname, null\n") + wxT(" FROM pg_conversion co WHERE conowner = ") + uid + wxT(" AND co.oid > ") + sysoid + wxT("\n") + wxT("UNION ALL\n") + wxT("SELECT CASE WHEN prorettype=") + NumToStr(PGOID_TYPE_TRIGGER) + wxT(" THEN 'T' ELSE 'p' END, null, proname, null\n") + wxT(" FROM pg_proc pr WHERE proowner = ") + uid + wxT(" AND pr.oid > ") + sysoid + wxT("\n") + wxT("UNION ALL\n") + wxT("SELECT 'o', null, oprname || '('::text || ") + wxT("COALESCE(tl.typname, ''::text) || ") + wxT("CASE WHEN tl.oid IS NOT NULL AND tr.oid IS NOT NULL THEN ','::text END || ") + wxT("COALESCE(tr.typname, ''::text) || ')'::text, null\n") + wxT(" FROM pg_operator op\n") + wxT(" LEFT JOIN pg_type tl ON tl.oid=op.oprleft\n") + wxT(" LEFT JOIN pg_type tr ON tr.oid=op.oprright\n") + wxT(" WHERE oprowner = ") + uid + wxT(" AND op.oid > ") + sysoid + wxT("\n") + wxT(" ORDER BY 1,2,3")); + + form->EndMsg(set != 0); +} + + +void pgUser::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + pgSet *set = GetServer()->ExecuteSet(wxT("SELECT groname, grolist FROM pg_group ORDER BY groname")); + if (set) + { + while (!set->Eof()) + { + wxString groupName = set->GetVal(wxT("groname")); + wxString str = set->GetVal(wxT("grolist")); + if (!str.IsNull()) + { + wxStringTokenizer ids(str.Mid(1, str.Length() - 2), wxT(",")); + while (ids.HasMoreTokens()) + { + if (StrToLong(ids.GetNextToken()) == GetUserId()) + { + groupsIn.Add(groupName); + break; + } + } + } + set->MoveNext(); + } + delete set; + } + } + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("User ID"), GetUserId()); + properties->AppendItem(_("Account expires"), DateToAnsiStr(GetAccountExpires())); + properties->AppendItem(_("Superuser?"), BoolToYesNo(GetSuperuser())); + properties->AppendItem(_("Create databases?"), BoolToYesNo(GetCreateDatabase())); + properties->AppendItem(_("Update catalogs?"), BoolToYesNo(GetUpdateCatalog())); + + wxString groupList; + + size_t index; + for (index = 0 ; index < groupsIn.GetCount() ; index++) + { + if (!groupList.IsEmpty()) + groupList += wxT(", "); + groupList += groupsIn.Item(index); + } + properties->AppendItem(_("Member of"), groupList); + + for (index = 0; index < configList.GetCount() ; index++) + { + wxString item = configList.Item(index); + properties->AppendItem(item.BeforeFirst('='), item.AfterFirst('=')); + } + } +} + + + +pgObject *pgUser::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *user = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + user = userFactory.CreateObjects(coll, 0, wxT("\n WHERE usesysid=") + NumToStr(GetUserId())); + + return user; +} + +///////////////////////////// + +wxString pgUserCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on users"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing users"); + break; + case OBJECTSLISTREPORT: + message = _("Users list report"); + break; + } + + return message; +} + +///////////////////////////// + +pgObject *pgUserFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgUser *user = 0; + + wxString tabname; + + if (collection->GetServer()->HasPrivilege(wxT("table"), wxT("pg_shadow"), wxT("SELECT"))) + tabname = wxT("pg_shadow"); + else + tabname = wxT("pg_user"); + + pgSet *users = collection->GetServer()->ExecuteSet(wxT( + "SELECT * FROM ") + tabname + restriction + wxT(" ORDER BY usename")); + + if (users) + { + while (!users->Eof()) + { + + user = new pgUser(users->GetVal(wxT("usename"))); + user->iSetServer(collection->GetServer()); + user->iSetUserId(users->GetLong(wxT("usesysid"))); + user->iSetCreateDatabase(users->GetBool(wxT("usecreatedb"))); + user->iSetSuperuser(users->GetBool(wxT("usesuper"))); + user->iSetUpdateCatalog(users->GetBool(wxT("usecatupd"))); + user->iSetAccountExpires(users->GetDateTime(wxT("valuntil"))); + user->iSetPassword(users->GetVal(wxT("passwd"))); + + wxString cfg = users->GetVal(wxT("useconfig")); + if (!cfg.IsEmpty()) + FillArray(user->GetConfigList(), cfg.Mid(1, cfg.Length() - 2)); + + if (browser) + { + browser->AppendObject(collection, user); + users->MoveNext(); + } + else + break; + } + + delete users; + } + return user; +} + + +#include "images/user.pngc" +#include "images/users.pngc" + +pgUserFactory::pgUserFactory() + : pgServerObjFactory(__("User"), __("New User..."), __("Create a new User."), user_png_img) +{ +} + + +pgUserFactory userFactory; +static pgaCollectionFactory cf(&userFactory, __("Users"), users_png_img); diff --git a/schema/pgUserMapping.cpp b/schema/pgUserMapping.cpp new file mode 100644 index 0000000..6e21015 --- /dev/null +++ b/schema/pgUserMapping.cpp @@ -0,0 +1,269 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgUserMapping.cpp - User Mapping class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgForeignServer.h" +#include "schema/pgUserMapping.h" +#include "schema/pgDatatype.h" + + +pgUserMapping::pgUserMapping(pgForeignServer *newForeignServer, const wxString &newName) + : pgForeignServerObject(newForeignServer, userMappingFactory, newName) +{ +} + + +wxString pgUserMapping::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on user mapping"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing user mapping"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop user mapping \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop user mapping \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop user mapping cascaded?"); + break; + case DROPTITLE: + message = _("Drop user mapping?"); + break; + case PROPERTIESREPORT: + message = _("User mapping properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("User mapping properties"); + break; + case DDLREPORT: + message = _("User mapping DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("User mapping DDL"); + break; + case STATISTICSREPORT: + message = _("User mapping statistics report"); + message += wxT(" - ") + GetName(); + break; + case OBJSTATISTICS: + message = _("User mapping statistics"); + break; + case DEPENDENCIESREPORT: + message = _("User mapping dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("User mapping dependencies"); + break; + case DEPENDENTSREPORT: + message = _("User mapping dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("User mapping dependents"); + break; + } + + return message; +} + + +bool pgUserMapping::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP USER MAPPING FOR ") + GetUsr() + wxT(" SERVER ") + qtIdent(GetForeignServer()->GetName()); + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgUserMapping::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Server: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP USER MAPPING FOR ") + GetUsr() + wxT(" SERVER ") + qtIdent(GetForeignServer()->GetName()) + wxT(";") + + wxT("\n\nCREATE USER MAPPING ") + + wxT("\n FOR ") + qtIdent(GetUsr()) + + wxT("\n SERVER ") + qtIdent(GetForeignServer()->GetName()); + + if (!GetOptions().IsEmpty()) + sql += wxT("\n OPTIONS (") + GetCreateOptions() + wxT(")"); + + sql += wxT(";\n"); + } + return sql; +} + + +void pgUserMapping::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("User"), GetUsr()); + properties->AppendItem(_("Options"), GetOptions()); + } +} + + + +pgObject *pgUserMapping::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *um = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + um = userMappingFactory.CreateObjects(coll, 0, wxT(" AND u.oid=") + GetOidStr()); + + return um; +} + + +//////////////////////////////////////////////////// + + +pgObject *pgUserMappingFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + wxString sql; + pgUserMapping *um = 0; + + sql = wxT("SELECT u.oid AS um_oid,\n") + wxT("CASE WHEN u.umuser = 0::oid THEN 'public'::name ELSE a.rolname END AS usr_name,\n") + wxT("array_to_string(u.umoptions, ',') AS um_options\n") + wxT("FROM pg_user_mapping u\n") + wxT(" LEFT JOIN pg_authid a ON a.oid = u.umuser\n") + wxT(" WHERE u.umserver = ") + collection->GetOidStr() + + restriction + wxT("\n") + wxT("ORDER BY 2"); + pgSet *usermappings = collection->GetDatabase()->ExecuteSet(sql); + if (usermappings) + { + while (!usermappings->Eof()) + { + um = new pgUserMapping(collection->GetForeignServer(), usermappings->GetVal(wxT("usr_name"))); + um->iSetOid(usermappings->GetOid(wxT("um_oid"))); + um->iSetUsr(usermappings->GetVal(wxT("usr_name"))); + um->iSetOptions(usermappings->GetVal(wxT("um_options"))); + + if (browser) + { + browser->AppendObject(collection, um); + usermappings->MoveNext(); + } + else + break; + } + + delete usermappings; + } + + return um; +} + + +wxString pgUserMapping::GetCreateOptions() +{ + wxString options_create = wxEmptyString; + wxString opt; + wxString val; + + wxStringTokenizer tkz_options(options, wxT(",")); + while (tkz_options.HasMoreTokens()) + { + wxStringTokenizer tkz_option(tkz_options.GetNextToken(), wxT("=")); + opt = tkz_option.GetNextToken(); + val = tkz_option.GetNextToken(); + + if (!options_create.IsEmpty()) + options_create += wxT(","); + + options_create += opt + wxT(" '") + val + wxT("'"); + } + + return options_create; +} + + +pgCollection *pgUserMappingObjFactory::CreateCollection(pgObject *obj) +{ + return new pgUserMappingCollection(GetCollectionFactory(), (pgUserMapping *)obj); +} + + +///////////////////////////// + +pgUserMappingCollection::pgUserMappingCollection(pgaFactory *factory, pgUserMapping *newum) + : pgCollection(factory) +{ + um = newum; + fsrv = um->GetForeignServer(); + fdw = fsrv->GetForeignDataWrapper(); + database = fdw->GetDatabase(); + server = database->GetServer(); + iSetOid(fsrv->GetOid()); +} + + +wxString pgUserMappingCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on user mappings"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing user mappings"); + break; + case OBJECTSLISTREPORT: + message = _("User mappings list report"); + break; + } + + return message; +} + +/////////////////////////////////////////////////// + +#include "images/usermapping.pngc" +#include "images/usermapping-sm.pngc" +#include "images/usermappings.pngc" + +pgUserMappingFactory::pgUserMappingFactory() + : pgForeignServerObjFactory(__("User Mapping"), __("New User Mapping..."), + __("Create a new User Mapping."), usermapping_png_img, usermapping_sm_png_img) +{ +} + + +pgUserMappingFactory userMappingFactory; +static pgaCollectionFactory cf(&userMappingFactory, __("User Mappings"), usermappings_png_img); diff --git a/schema/pgView.cpp b/schema/pgView.cpp new file mode 100644 index 0000000..b307519 --- /dev/null +++ b/schema/pgView.cpp @@ -0,0 +1,967 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgView.cpp - View class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgColumn.h" +#include "schema/pgIndexConstraint.h" +#include "schema/pgView.h" +#include "frm/frmMain.h" +#include "frm/frmHint.h" +#include "schema/pgTrigger.h" + + +pgView::pgView(pgSchema *newSchema, const wxString &newName) + : pgRuleObject(newSchema, viewFactory, newName) +{ + hasInsertRule = false; + hasUpdateRule = false; + hasDeleteRule = false; +} + +pgView::~pgView() +{ +} + +wxString pgView::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on view"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing view"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop view \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop view \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop view cascaded?"); + break; + case DROPTITLE: + message = _("Drop view?"); + break; + case PROPERTIESREPORT: + message = _("View properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("View properties"); + break; + case DDLREPORT: + message = _("View DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("View DDL"); + break; + case DEPENDENCIESREPORT: + message = _("View dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("View dependencies"); + break; + case DEPENDENTSREPORT: + message = _("View dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("View dependents"); + break; + } + + return message; +} + + +bool pgView::IsUpToDate() +{ + wxString sql = wxT("SELECT xmin FROM pg_class WHERE oid = ") + this->GetOidStr(); + if (!this->GetDatabase()->GetConnection() || this->GetDatabase()->ExecuteScalar(sql) != NumToStr(GetXid())) + return false; + else + return true; +} + +wxMenu *pgView::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + if (schema->GetCreatePrivilege()) + { + ruleFactory.AppendMenu(menu); + triggerFactory.AppendMenu(menu); + if (GetMaterializedView()) + { + indexFactory.AppendMenu(menu); + } + } + return menu; +} + + +bool pgView::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + if (GetMaterializedView()) + sql = wxT("DROP MATERIALIZED VIEW ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + else + sql = wxT("DROP VIEW ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgView::GetSql(ctlTree *browser) +{ + wxString withoptions; + + if (sql.IsNull()) + { + bool IsMatViewFlag = false; + if (!GetMaterializedView()) + { + sql = wxT("-- View: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP VIEW ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE OR REPLACE VIEW ") + GetQuotedFullIdentifier(); + + if (GetConnection()->BackendMinimumVersion(9, 2) && GetSecurityBarrier().Length() > 0) + withoptions = wxT("security_barrier=") + GetSecurityBarrier(); + if (GetConnection()->BackendMinimumVersion(9, 4) && GetCheckOption().Length() > 0) + { + if (withoptions.Length() > 0) + withoptions += wxT(", "); + withoptions = wxT("check_option=") + GetCheckOption(); + } + if (withoptions.Length() > 0) + sql += wxT(" WITH (") + withoptions + wxT(")"); + } + else + { + sql = wxT("-- Materialized View: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP MATERIALIZED VIEW ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE MATERIALIZED VIEW ") + GetQuotedFullIdentifier(); + + IsMatViewFlag = true; + + if (GetConnection()->BackendMinimumVersion(9, 3)) + { + if (GetFillFactor().Length() > 0 || GetAutoVacuumEnabled() == 1 || GetToastAutoVacuumEnabled() == 1) + { + bool tmpFlagTable = false; + bool tmpFlagToastTable = false; + + sql += wxT("\nWITH ("); + if (GetFillFactor().Length() > 0) + sql += wxT("\n FILLFACTOR=") + GetFillFactor(); + else + tmpFlagTable = true; + + if (GetCustomAutoVacuumEnabled()) + { + if (GetAutoVacuumEnabled() == 1) + { + if (tmpFlagTable) + sql += wxT("\n autovacuum_enabled=true"); + else + sql += wxT(",\n autovacuum_enabled=true"); + tmpFlagToastTable = true; + } + else if (GetCustomAutoVacuumEnabled() == 0) + { + sql += wxT(",\n autovacuum_enabled=false"); + } + if (!GetAutoVacuumVacuumThreshold().IsEmpty()) + { + sql += wxT(",\n autovacuum_vacuum_threshold=") + GetAutoVacuumVacuumThreshold(); + } + if (!GetAutoVacuumVacuumScaleFactor().IsEmpty()) + { + sql += wxT(",\n autovacuum_vacuum_scale_factor=") + GetAutoVacuumVacuumScaleFactor(); + } + if (!GetAutoVacuumAnalyzeThreshold().IsEmpty()) + { + sql += wxT(",\n autovacuum_analyze_threshold=") + GetAutoVacuumAnalyzeThreshold(); + } + if (!GetAutoVacuumAnalyzeScaleFactor().IsEmpty()) + { + sql += wxT(",\n autovacuum_analyze_scale_factor=") + GetAutoVacuumAnalyzeScaleFactor(); + } + if (!GetAutoVacuumVacuumCostDelay().IsEmpty()) + { + sql += wxT(",\n autovacuum_vacuum_cost_delay=") + GetAutoVacuumVacuumCostDelay(); + } + if (!GetAutoVacuumVacuumCostLimit().IsEmpty()) + { + sql += wxT(",\n autovacuum_vacuum_cost_limit=") + GetAutoVacuumVacuumCostLimit(); + } + if (!GetAutoVacuumFreezeMinAge().IsEmpty()) + { + sql += wxT(",\n autovacuum_freeze_min_age=") + GetAutoVacuumFreezeMinAge(); + } + if (!GetAutoVacuumFreezeMaxAge().IsEmpty()) + { + sql += wxT(",\n autovacuum_freeze_max_age=") + GetAutoVacuumFreezeMaxAge(); + } + if (!GetAutoVacuumFreezeTableAge().IsEmpty()) + { + sql += wxT(",\n autovacuum_freeze_table_age=") + GetAutoVacuumFreezeTableAge(); + } + } + if (GetHasToastTable() && GetToastCustomAutoVacuumEnabled()) + { + if (GetToastAutoVacuumEnabled() == 1) + { + if (tmpFlagTable && !tmpFlagToastTable) + sql += wxT("\n toast.autovacuum_enabled=true"); + else + sql += wxT(",\n toast.autovacuum_enabled=true"); + } + else if (GetToastAutoVacuumEnabled() == 0) + sql += wxT(",\n toast.autovacuum_enabled=false"); + if (!GetToastAutoVacuumVacuumThreshold().IsEmpty()) + { + sql += wxT(",\n toast.autovacuum_vacuum_threshold=") + GetToastAutoVacuumVacuumThreshold(); + } + if (!GetToastAutoVacuumVacuumScaleFactor().IsEmpty()) + { + sql += wxT(",\n toast.autovacuum_vacuum_scale_factor=") + GetToastAutoVacuumVacuumScaleFactor(); + } + if (!GetToastAutoVacuumVacuumCostDelay().IsEmpty()) + { + sql += wxT(",\n toast.autovacuum_vacuum_cost_delay=") + GetToastAutoVacuumVacuumCostDelay(); + } + if (!GetToastAutoVacuumVacuumCostLimit().IsEmpty()) + { + sql += wxT(",\n toast.autovacuum_vacuum_cost_limit=") + GetToastAutoVacuumVacuumCostLimit(); + } + if (!GetToastAutoVacuumFreezeMinAge().IsEmpty()) + { + sql += wxT(",\n toast.autovacuum_freeze_min_age=") + GetToastAutoVacuumFreezeMinAge(); + } + if (!GetToastAutoVacuumFreezeMaxAge().IsEmpty()) + { + sql += wxT(",\n toast.autovacuum_freeze_max_age=") + GetToastAutoVacuumFreezeMaxAge(); + } + if (!GetToastAutoVacuumFreezeTableAge().IsEmpty()) + { + sql += wxT(",\n toast.autovacuum_freeze_table_age=") + GetToastAutoVacuumFreezeTableAge(); + } + } + sql += wxT("\n)"); + } + + if (tablespace != GetDatabase()->GetDefaultTablespace()) + sql += wxT("\nTABLESPACE ") + qtIdent(tablespace); + + wxString isPopulated; + if (GetIsPopulated().Cmp(wxT("t")) == 0) + isPopulated = wxT("WITH DATA;"); + else + isPopulated = wxT("WITH NO DATA;"); + + wxString sqlDefinition; + bool tmpLoopFlag = true; + sqlDefinition = GetFormattedDefinition(); + + // Remove semicolon from the end of the string + while(tmpLoopFlag) + { + int length = sqlDefinition.Len(); + int position = sqlDefinition.Find(';', true); + if ((position != wxNOT_FOUND) && (position = (length - 1))) + sqlDefinition.Remove(position, 1); + else + tmpLoopFlag = false; + } + + sql += wxT(" AS \n") + + sqlDefinition + + wxT("\n") + + isPopulated + + wxT("\n\n") + + GetOwnerSql(7, 3, wxT("TABLE ") + GetQuotedFullIdentifier()); + } + } + + if (!IsMatViewFlag) + { + sql += wxT(" AS \n") + + GetFormattedDefinition() + + wxT("\n\n") + + GetOwnerSql(7, 3, wxT("TABLE ") + GetQuotedFullIdentifier()); + } + + if (GetConnection()->BackendMinimumVersion(8, 2)) + sql += GetGrant(wxT("arwdxt"), wxT("TABLE ") + GetQuotedFullIdentifier()); + else + sql += GetGrant(wxT("arwdRxt"), wxT("TABLE ") + GetQuotedFullIdentifier()); + + // "MATERIALIZED" isn't part of the object type name, it's a property, so + // we need to generate the comment SQL manually here, instead of using + // wxString pgObject::GetCommentSql() + + if (!GetComment().IsNull()) + { + if (IsMatViewFlag) + { + sql += wxT("COMMENT ON MATERIALIZED VIEW ") + GetQuotedFullIdentifier() + + wxT("\n IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + else + { + sql += wxT("COMMENT ON VIEW ") + GetQuotedFullIdentifier() + + wxT("\n IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + } + + pgCollection *columns = browser->FindCollection(columnFactory, GetId()); + if (columns) + { + wxString defaults, comments; + columns->ShowTreeDetail(browser); + treeObjectIterator colIt(browser, columns); + + pgColumn *column; + while ((column = (pgColumn *)colIt.GetNextObject()) != 0) + { + column->ShowTreeDetail(browser); + if (column->GetColNumber() > 0) + { + if (!column->GetDefault().IsEmpty()) + { + defaults += wxT("ALTER TABLE ") + GetQuotedFullIdentifier() + + wxT(" ALTER COLUMN ") + column->GetQuotedIdentifier() + + wxT(" SET DEFAULT ") + column->GetDefault() + + wxT(";\n"); + } + comments += column->GetCommentSql(); + } + } + if (!defaults.IsEmpty()) + sql += defaults + wxT("\n"); + + if (!comments.IsEmpty()) + sql += comments + wxT("\n"); + + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += GetSeqLabelsSql(); + } + + if (IsMatViewFlag) + { + AppendStuff(sql, browser, indexFactory); + } + AppendStuff(sql, browser, ruleFactory); + AppendStuff(sql, browser, triggerFactory); + } + return sql; +} + + +wxString pgView::GetCols(ctlTree *browser, size_t indent, wxString &QMs, bool withQM) +{ + wxString sql; + wxString line; + + int colcount = 0; + pgSetIterator set(GetConnection(), + wxT("SELECT attname\n") + wxT(" FROM pg_attribute\n") + wxT(" WHERE attrelid=") + GetOidStr() + wxT(" AND attnum>0\n") + wxT(" ORDER BY attnum")); + + + while (set.RowsLeft()) + { + if (colcount++) + { + line += wxT(", "); + QMs += wxT(", "); + } + if (line.Length() > 60) + { + if (!sql.IsEmpty()) + { + sql += wxT("\n") + wxString(' ', indent); + } + sql += line; + line = wxEmptyString; + QMs += wxT("\n") + wxString(' ', indent); + } + + line += qtIdent(set.GetVal(0)); + if (withQM) + line += wxT("=?"); + QMs += wxT("?"); + } + + if (!line.IsEmpty()) + { + if (!sql.IsEmpty()) + sql += wxT("\n") + wxString(' ', indent); + sql += line; + } + return sql; +} + + +wxString pgView::GetSelectSql(ctlTree *browser) +{ + wxString qms; + wxString sql = + wxT("SELECT ") + GetCols(browser, 7, qms, false) + wxT("\n") + wxT(" FROM ") + GetQuotedFullIdentifier() + wxT(";\n"); + return sql; +} + + +wxString pgView::GetInsertSql(ctlTree *browser) +{ + wxString qms; + wxString sql = + wxT("INSERT INTO ") + GetQuotedFullIdentifier() + wxT("(\n") + wxT(" ") + GetCols(browser, 12, qms, false) + wxT(")\n") + wxT(" VALUES (") + qms + wxT(");\n"); + return sql; +} + + +wxString pgView::GetUpdateSql(ctlTree *browser) +{ + wxString qms; + wxString sql = + wxT("UPDATE ") + GetQuotedFullIdentifier() + wxT("\n") + wxT(" SET ") + GetCols(browser, 7, qms, true) + wxT("\n") + wxT(" WHERE ;\n"); + return sql; +} + + +void pgView::RefreshMatView(bool concurrently) +{ + wxString sql = wxT("REFRESH MATERIALIZED VIEW "); + if (concurrently) + sql += wxT("CONCURRENTLY "); + sql += GetQuotedFullIdentifier(); + GetDatabase()->ExecuteVoid(sql); +} + + +void pgView::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + browser->RemoveDummyChild(this); + + browser->AppendCollection(this, columnFactory); + + if (GetMaterializedView()) + browser->AppendCollection(this, indexFactory); + + pgCollection *collection = browser->AppendCollection(this, ruleFactory); + collection->iSetOid(GetOid()); + collection->ShowTreeDetail(browser); + treeObjectIterator colIt(browser, collection); + + pgRule *rule; + while (!hasInsertRule && !hasUpdateRule && !hasDeleteRule && (rule = (pgRule *)colIt.GetNextObject()) != 0) + { + if (rule->GetEvent().Find(wxT("INSERT")) >= 0) + hasInsertRule = true; + if (rule->GetEvent().Find(wxT("UPDATE")) >= 0) + hasUpdateRule = true; + if (rule->GetEvent().Find(wxT("DELETE")) >= 0) + hasDeleteRule = true; + } + + if (GetConnection()->BackendMinimumVersion(9, 1)) + browser->AppendCollection(this, triggerFactory); + } + if (properties) + { + CreateListColumns(properties); + wxString def = GetDefinition().Left(250); + def.Replace(wxT("\n"), wxT(" ")); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("ACL"), GetAcl()); + properties->AppendItem(_("Definition"), def); + properties->AppendYesNoItem(_("System view?"), GetSystemObject()); + if (GetConnection()->BackendMinimumVersion(9, 2) && GetSecurityBarrier().Length() > 0) + properties->AppendItem(_("Security barrier?"), GetSecurityBarrier()); + + if (GetConnection()->BackendMinimumVersion(9, 3)) + properties->AppendYesNoItem(_("Materialized view?"), GetMaterializedView()); + + /* Custom AutoVacuum Settings */ + if (GetConnection()->BackendMinimumVersion(9, 3) && GetMaterializedView()) + { + if (!GetFillFactor().IsEmpty()) + properties->AppendItem(_("Fill factor"), GetFillFactor()); + + if (GetCustomAutoVacuumEnabled()) + { + if (GetAutoVacuumEnabled() != 2) + { + properties->AppendItem(_("Table auto-vacuum enabled?"), GetAutoVacuumEnabled() == 1 ? _("Yes") : _("No")); + } + if (!GetAutoVacuumVacuumThreshold().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum VACUUM base threshold"), GetAutoVacuumVacuumThreshold()); + if (!GetAutoVacuumVacuumScaleFactor().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum VACUUM scale factor"), GetAutoVacuumVacuumScaleFactor()); + if (!GetAutoVacuumAnalyzeThreshold().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum ANALYZE base threshold"), GetAutoVacuumAnalyzeThreshold()); + if (!GetAutoVacuumAnalyzeScaleFactor().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum ANALYZE scale factor"), GetAutoVacuumAnalyzeScaleFactor()); + if (!GetAutoVacuumVacuumCostDelay().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum VACUUM cost delay"), GetAutoVacuumVacuumCostDelay()); + if (!GetAutoVacuumVacuumCostLimit().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum VACUUM cost limit"), GetAutoVacuumVacuumCostLimit()); + if (!GetAutoVacuumFreezeMinAge().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum FREEZE minimum age"), GetAutoVacuumFreezeMinAge()); + if (!GetAutoVacuumFreezeMaxAge().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum FREEZE maximum age"), GetAutoVacuumFreezeMaxAge()); + if (!GetAutoVacuumFreezeTableAge().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum FREEZE table age"), GetAutoVacuumFreezeTableAge()); + } + + if (GetHasToastTable() && GetToastCustomAutoVacuumEnabled()) + { + if (GetToastAutoVacuumEnabled() != 2) + { + properties->AppendItem(_("Toast auto-vacuum enabled?"), GetToastAutoVacuumEnabled() == 1 ? _("Yes") : _("No")); + } + if (!GetToastAutoVacuumVacuumThreshold().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum VACUUM base threshold"), GetToastAutoVacuumVacuumThreshold()); + if (!GetToastAutoVacuumVacuumScaleFactor().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum VACUUM scale factor"), GetToastAutoVacuumVacuumScaleFactor()); + if (!GetToastAutoVacuumVacuumCostDelay().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum VACUUM cost delay"), GetToastAutoVacuumVacuumCostDelay()); + if (!GetToastAutoVacuumVacuumCostLimit().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum VACUUM cost limit"), GetToastAutoVacuumVacuumCostLimit()); + if (!GetToastAutoVacuumFreezeMinAge().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum FREEZE minimum age"), GetToastAutoVacuumFreezeMinAge()); + if (!GetToastAutoVacuumFreezeMaxAge().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum FREEZE maximum age"), GetToastAutoVacuumFreezeMaxAge()); + if (!GetToastAutoVacuumFreezeTableAge().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum FREEZE table age"), GetToastAutoVacuumFreezeTableAge()); + } + + properties->AppendItem(_("Tablespace"), tablespace); + + if (GetIsPopulated().Cmp(wxT("t")) == 0) + properties->AppendItem(_("With data?"), _("Yes")); + else + properties->AppendItem(_("With data?"), _("No")); + } + + if (GetConnection()->BackendMinimumVersion(9, 4)) + properties->AppendItem(_("Check Option"), GetCheckOption()); + + if (!GetLabels().IsEmpty()) + { + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); + } + } + } + + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgView::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *view = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + { + // OIDs may change in EDB which allows the returned column set to be changed. + if (GetConnection()->EdbMinimumVersion(8, 0)) + view = viewFactory.CreateObjects(coll, 0, wxT("\n AND c.relname=") + GetConnection()->qtDbString(GetName())); + else + view = viewFactory.CreateObjects(coll, 0, wxT("\n AND c.oid=") + GetOidStr()); + } + + return view; +} + +void pgView::ShowHint(frmMain *form, bool force) +{ + wxArrayString hints; + hints.Add(HINT_OBJECT_EDITING); + frmHint::ShowHint((wxWindow *)form, hints, GetFullIdentifier(), force); +} + +void pgView::AppendStuff(wxString &sql, ctlTree *browser, pgaFactory &factory) +{ + wxString tmp; + + pgCollection *collection = browser->FindCollection(factory, GetId()); + if (collection) + { + tmp += wxT("\n"); + collection->ShowTreeDetail(browser); + + treeObjectIterator idxIt(browser, collection); + pgObject *obj; + while ((obj = idxIt.GetNextObject()) != 0) + { + if (obj->GetName() != wxT("_RETURN")) + { + obj->ShowTreeDetail(browser); + + tmp += obj->GetSql(browser) + wxT("\n"); + } + } + } + + if (!tmp.IsEmpty() && tmp != wxT("\n")) + sql += tmp; +} + +int pgView::GetIconId() +{ + if (GetMaterializedView()) + return viewFactory.GetMaterializedIconId(); + else + return viewFactory.GetIconId(); +} + +/////////////////////////////////////////////////// + + +pgViewCollection::pgViewCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgViewCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on views"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing views"); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for views"); + break; + case OBJECTSLISTREPORT: + message = _("Views list report"); + break; + } + + return message; +} + + +/////////////////////////////////////////////////////// + + +pgObject *pgViewFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgView *view = 0; + wxString sql; + + if (collection->GetDatabase()->BackendMinimumVersion(9, 3)) + { + sql = wxT("SELECT c.oid, c.xmin, c.relname,c.reltablespace AS spcoid, c.relkind, c.relispopulated AS ispopulated,spc.spcname, pg_get_userbyid(c.relowner) AS viewowner, c.relacl, description, ") + wxT("pg_get_viewdef(c.oid") + collection->GetDatabase()->GetPrettyOption() + wxT(") AS definition"); + } + else + { + sql = wxT("SELECT c.oid, c.xmin, c.relname,c.reltablespace AS spcoid,spc.spcname, pg_get_userbyid(c.relowner) AS viewowner, c.relacl, description, ") + wxT("pg_get_viewdef(c.oid") + collection->GetDatabase()->GetPrettyOption() + wxT(") AS definition"); + } + + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + sql += wxT(",\n(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=c.oid AND sl1.objsubid=0) AS labels"); + sql += wxT(",\n(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=c.oid AND sl2.objsubid=0) AS providers"); + } + if (collection->GetConnection()->BackendMinimumVersion(9, 2)) + { + sql += wxT(",\nsubstring(array_to_string(c.reloptions, ',') FROM 'security_barrier=([a-z|0-9]*)') AS security_barrier"); + } + + if (collection->GetConnection()->BackendMinimumVersion(9, 3)) + { + sql += wxT(", substring(array_to_string(c.reloptions, ',') FROM 'fillfactor=([0-9]*)') AS fillfactor \n"); + + sql += wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') AS autovacuum_enabled \n") + wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS autovacuum_vacuum_threshold \n") + wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.][0-9]*)') AS autovacuum_vacuum_scale_factor \n") + wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_analyze_threshold=([0-9]*)') AS autovacuum_analyze_threshold \n") + wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_analyze_scale_factor=([0-9]*[.][0-9]*)') AS autovacuum_analyze_scale_factor \n") + wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS autovacuum_vacuum_cost_delay \n") + wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS autovacuum_vacuum_cost_limit \n") + wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_freeze_min_age=([0-9]*)') AS autovacuum_freeze_min_age \n") + wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_freeze_max_age=([0-9]*)') AS autovacuum_freeze_max_age \n") + wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS autovacuum_freeze_table_age \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') AS toast_autovacuum_enabled \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS toast_autovacuum_vacuum_threshold \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.][0-9]*)') AS toast_autovacuum_vacuum_scale_factor \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_analyze_threshold=([0-9]*)') AS toast_autovacuum_analyze_threshold \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_analyze_scale_factor=([0-9]*[.][0-9]*)') AS toast_autovacuum_analyze_scale_factor \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS toast_autovacuum_vacuum_cost_delay \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS toast_autovacuum_vacuum_cost_limit \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_min_age=([0-9]*)') AS toast_autovacuum_freeze_min_age \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_max_age=([0-9]*)') AS toast_autovacuum_freeze_max_age \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS toast_autovacuum_freeze_table_age \n") + wxT(", c.reloptions AS reloptions, tst.reloptions AS toast_reloptions \n") + wxT(", (CASE WHEN c.reltoastrelid = 0 THEN false ELSE true END) AS hastoasttable\n"); + } + if (collection->GetConnection()->BackendMinimumVersion(9, 4)) + { + sql += wxT(",\nsubstring(array_to_string(c.reloptions, ',') FROM 'check_option=([a-z]*)') AS check_option"); + } + + + + sql += wxT("\n FROM pg_class c\n") + wxT(" LEFT OUTER JOIN pg_tablespace spc on spc.oid=c.reltablespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=c.oid and des.objsubid=0 AND des.classoid='pg_class'::regclass)\n"); + + // Add the toast table for vacuum parameters. + if (collection->GetConnection()->BackendMinimumVersion(9, 3)) + sql += wxT(" LEFT OUTER JOIN pg_class tst ON tst.oid = c.reltoastrelid\n"); + + sql += wxT(" WHERE ((c.relhasrules AND (EXISTS (\n") + wxT(" SELECT r.rulename FROM pg_rewrite r\n") + wxT(" WHERE ((r.ev_class = c.oid)\n") + wxT(" AND (bpchar(r.ev_type) = '1'::bpchar)) ))) OR (c.relkind = 'v'::char))\n") + wxT(" AND c.relnamespace = ") + collection->GetSchema()->GetOidStr() + wxT("\n") + + restriction + + wxT(" ORDER BY relname"); + + pgSet *views = collection->GetDatabase()->ExecuteSet(sql); + + if (views) + { + while (!views->Eof()) + { + view = new pgView(collection->GetSchema(), views->GetVal(wxT("relname"))); + + view->iSetOid(views->GetOid(wxT("oid"))); + view->iSetXid(views->GetOid(wxT("xmin"))); + view->iSetOwner(views->GetVal(wxT("viewowner"))); + view->iSetComment(views->GetVal(wxT("description"))); + view->iSetAcl(views->GetVal(wxT("relacl"))); + view->iSetDefinition(views->GetVal(wxT("definition"))); + view->iSetMaterializedView(false); + if (collection->GetDatabase()->BackendMinimumVersion(9, 4)) + { + view->iSetCheckOption(views->GetVal(wxT("check_option"))); + } + + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + view->iSetProviders(views->GetVal(wxT("providers"))); + view->iSetLabels(views->GetVal(wxT("labels"))); + } + if (collection->GetConnection()->BackendMinimumVersion(9, 2)) + { + view->iSetSecurityBarrier(views->GetVal(wxT("security_barrier"))); + } + + if (collection->GetConnection()->BackendMinimumVersion(9, 3)) + { + view->iSetFillFactor(views->GetVal(wxT("fillfactor"))); + + if (views->GetOid(wxT("spcoid")) == 0) + view->iSetTablespaceOid(collection->GetDatabase()->GetTablespaceOid()); + else + view->iSetTablespaceOid(views->GetOid(wxT("spcoid"))); + + view->iSetRelOptions(views->GetVal(wxT("reloptions"))); + + view->iSetIsPopulated(views->GetVal(wxT("ispopulated"))); + + if (view->GetCustomAutoVacuumEnabled()) + { + if (views->GetVal(wxT("autovacuum_enabled")).IsEmpty()) + view->iSetAutoVacuumEnabled(2); + else if (views->GetBool(wxT("autovacuum_enabled"))) + view->iSetAutoVacuumEnabled(1); + else + view->iSetAutoVacuumEnabled(0); + view->iSetAutoVacuumVacuumThreshold(views->GetVal(wxT("autovacuum_vacuum_threshold"))); + view->iSetAutoVacuumVacuumScaleFactor(views->GetVal(wxT("autovacuum_vacuum_scale_factor"))); + view->iSetAutoVacuumAnalyzeThreshold(views->GetVal(wxT("autovacuum_analyze_threshold"))); + view->iSetAutoVacuumAnalyzeScaleFactor(views->GetVal(wxT("autovacuum_analyze_scale_factor"))); + view->iSetAutoVacuumVacuumCostDelay(views->GetVal(wxT("autovacuum_vacuum_cost_delay"))); + view->iSetAutoVacuumVacuumCostLimit(views->GetVal(wxT("autovacuum_vacuum_cost_limit"))); + view->iSetAutoVacuumFreezeMinAge(views->GetVal(wxT("autovacuum_freeze_min_age"))); + view->iSetAutoVacuumFreezeMaxAge(views->GetVal(wxT("autovacuum_freeze_max_age"))); + view->iSetAutoVacuumFreezeTableAge(views->GetVal(wxT("autovacuum_freeze_table_age"))); + } + + view->iSetHasToastTable(views->GetBool(wxT("hastoasttable"))); + + if (view->GetHasToastTable()) + { + view->iSetToastRelOptions(views->GetVal(wxT("toast_reloptions"))); + + if (view->GetToastCustomAutoVacuumEnabled()) + { + if (views->GetVal(wxT("toast_autovacuum_enabled")).IsEmpty()) + view->iSetToastAutoVacuumEnabled(2); + else if (views->GetBool(wxT("toast_autovacuum_enabled"))) + view->iSetToastAutoVacuumEnabled(1); + else + view->iSetToastAutoVacuumEnabled(0); + + view->iSetToastAutoVacuumVacuumThreshold(views->GetVal(wxT("toast_autovacuum_vacuum_threshold"))); + view->iSetToastAutoVacuumVacuumScaleFactor(views->GetVal(wxT("toast_autovacuum_vacuum_scale_factor"))); + view->iSetToastAutoVacuumVacuumCostDelay(views->GetVal(wxT("toast_autovacuum_vacuum_cost_delay"))); + view->iSetToastAutoVacuumVacuumCostLimit(views->GetVal(wxT("toast_autovacuum_vacuum_cost_limit"))); + view->iSetToastAutoVacuumFreezeMinAge(views->GetVal(wxT("toast_autovacuum_freeze_min_age"))); + view->iSetToastAutoVacuumFreezeMaxAge(views->GetVal(wxT("toast_autovacuum_freeze_max_age"))); + view->iSetToastAutoVacuumFreezeTableAge(views->GetVal(wxT("toast_autovacuum_freeze_table_age"))); + } + } + + if (views->GetVal(wxT("spcname")) == wxEmptyString) + view->iSetTablespace(collection->GetDatabase()->GetTablespace()); + else + view->iSetTablespace(views->GetVal(wxT("spcname"))); + + if (views->GetVal(wxT("relkind")).Cmp(wxT("m")) == 0) + view->iSetMaterializedView(true); + } + + if (browser) + { + collection->AppendBrowserItem(browser, view); + // If it is materialized view then display the materialized view icon + if (collection->GetConnection()->BackendMinimumVersion(9, 3) && views->GetVal(wxT("relkind")).Cmp(wxT("m")) == 0) + browser->SetItemImage(view->GetId(), viewFactory.GetMaterializedIconId()); + + views->MoveNext(); + } + else + break; + } + + delete views; + } + return view; +} + + +#include "images/view.pngc" +#include "images/view-sm.pngc" +#include "images/views.pngc" +#include "images/mview.pngc" +#include "images/mview-sm.pngc" + +pgViewFactory::pgViewFactory() + : pgSchemaObjFactory(__("View"), __("New View..."), __("Create a new View."), view_png_img, view_sm_png_img) +{ + metaType = PGM_VIEW; + materializedId = addIcon(mview_png_img); + smallMaterializedId = addIcon(mview_sm_png_img); +} + + +pgCollection *pgViewFactory::CreateCollection(pgObject *obj) +{ + return new pgViewCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgViewFactory viewFactory; +static pgaCollectionFactory cf(&viewFactory, __("Views"), views_png_img); + +refreshMatViewFactory::refreshMatViewFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Refresh data"), _("Refresh data for the selected object.")); +} + + +wxWindow *refreshMatViewFactory::StartDialog(frmMain *form, pgObject *obj) +{ + form->StartMsg(_("Refreshing data")); + + ((pgView *)obj)->RefreshMatView(false); + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties()); + + form->EndMsg(); + + return 0; +} + + +bool refreshMatViewFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(viewFactory) && ((pgView *)obj)->GetMaterializedView(); +} + + +refreshConcurrentlyMatViewFactory::refreshConcurrentlyMatViewFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Refresh data concurrently"), _("Refresh data concurrently for the selected object.")); +} + + +wxWindow *refreshConcurrentlyMatViewFactory::StartDialog(frmMain *form, pgObject *obj) +{ + form->StartMsg(_("Refreshing data concurrently")); + + ((pgView *)obj)->RefreshMatView(true); + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties()); + + form->EndMsg(); + + return 0; +} + + +bool refreshConcurrentlyMatViewFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(viewFactory) + && ((pgView *)obj)->GetMaterializedView() + && ((pgView *)obj)->GetConnection()->BackendMinimumVersion(9, 4);; +} diff --git a/slony/dlgRepCluster.cpp b/slony/dlgRepCluster.cpp new file mode 100644 index 0000000..547d572 --- /dev/null +++ b/slony/dlgRepCluster.cpp @@ -0,0 +1,1628 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepCluster.cpp - PostgreSQL Slony-I Cluster Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/pgDefs.h" +#include +#include + +#include "frm/frmMain.h" +#include "slony/dlgRepCluster.h" +#include "slony/slCluster.h" +#include "slony/slSet.h" +#include "slony/slCluster.h" +#include "schema/pgDatatype.h" +#include "utils/sysProcess.h" + +#define cbServer CTRL_COMBOBOX("cbServer") +#define cbDatabase CTRL_COMBOBOX("cbDatabase") +#define cbClusterName CTRL_COMBOBOX("cbClusterName") + +BEGIN_EVENT_TABLE(dlgRepClusterBase, dlgProperty) + EVT_COMBOBOX(XRCID("cbServer"), dlgRepClusterBase::OnChangeServer) + EVT_COMBOBOX(XRCID("cbDatabase"), dlgRepClusterBase::OnChangeDatabase) +END_EVENT_TABLE(); + + + +dlgRepClusterBase::dlgRepClusterBase(pgaFactory *f, frmMain *frame, const wxString &dlgName, slCluster *node, pgDatabase *db) + : dlgProperty(f, frame, dlgName) +{ + cluster = node; + remoteServer = 0; + remoteConn = 0; + + pgObject *obj = db; + servers = obj->GetId(); + while (obj && obj != frame->GetServerCollection()) + { + servers = frame->GetBrowser()->GetItemParent(servers); + if (servers) + obj = frame->GetBrowser()->GetObject(servers); + } +} + + +dlgRepClusterBase::~dlgRepClusterBase() +{ + if (remoteConn) + { + delete remoteConn; + remoteConn = 0; + } +} + + +pgObject *dlgRepClusterBase::GetObject() +{ + return cluster; +} + + +bool dlgRepClusterBase::AddScript(wxString &sql, const wxString &fn) +{ + wxFileName filename; + filename.Assign(settings->GetSlonyPath(), fn); + + if (!wxFile::Exists(filename.GetFullPath())) + return false; + + wxFile file(filename.GetFullPath(), wxFile::read); + if (!file.IsOpened()) + return false; + + char *buffer; + size_t done; + + buffer = new char[file.Length() + 1]; + done = file.Read(buffer, file.Length()); + buffer[done] = 0; + sql += wxTextBuffer::Translate(wxString::FromAscii(buffer), wxTextFileType_Unix); + delete[] buffer; + + return done > 0; +} + + +int dlgRepClusterBase::Go(bool modal) +{ + return dlgProperty::Go(modal); +} + + +void dlgRepClusterBase::OnChangeServer(wxCommandEvent &ev) +{ + cbDatabase->Clear(); + if (remoteConn) + { + delete remoteConn; + remoteConn = 0; + } + int sel = cbServer->GetCurrentSelection(); + if (sel >= 0) + { + remoteServer = (pgServer *)cbServer->wxItemContainer::GetClientData(sel); + + if (!remoteServer->GetConnected()) + { + remoteServer->Connect(mainForm, remoteServer->GetStorePwd()); + if (!remoteServer->GetConnected()) + { + wxLogError(remoteServer->GetLastError()); + return; + } + } + if (remoteServer->GetConnected()) + { + pgSet *set = remoteServer->ExecuteSet( + wxT("SELECT DISTINCT datname\n") + wxT(" FROM pg_database db\n") + wxT(" WHERE datallowconn ORDER BY datname")); + if (set) + { + while (!set->Eof()) + { + cbDatabase->Append(set->GetVal(wxT("datname"))); + set->MoveNext(); + } + delete set; + + if (cbDatabase->GetCount()) + cbDatabase->SetSelection(0); + } + } + + } + OnChangeDatabase(ev); +} + + + +void dlgRepClusterBase::OnChangeDatabase(wxCommandEvent &ev) +{ + cbClusterName->Clear(); + + int sel = cbDatabase->GetCurrentSelection(); + if (remoteServer && sel >= 0) + { + if (remoteConn) + { + delete remoteConn; + remoteConn = 0; + } + remoteConn = remoteServer->CreateConn(cbDatabase->GetValue()); + if (remoteConn) + { + pgSet *set = remoteConn->ExecuteSet( + wxT("SELECT substr(nspname, 2) as clustername\n") + wxT(" FROM pg_namespace nsp\n") + wxT(" JOIN pg_proc pro ON pronamespace=nsp.oid AND proname = 'slonyversion'\n") + wxT(" ORDER BY nspname")); + + if (set) + { + while (!set->Eof()) + { + cbClusterName->Append(set->GetVal(wxT("clustername"))); + set->MoveNext(); + } + delete set; + } + + if (cbClusterName->GetCount()) + cbClusterName->SetSelection(0); + } + } + OnChangeCluster(ev); +} + +////////////////////////////////////////////////////////////////////////////////7 + +// pointer to controls +#define chkJoinCluster CTRL_CHECKBOX("chkJoinCluster") +#define txtClusterName CTRL_TEXT("txtClusterName") +#define txtNodeID CTRL_TEXT("txtNodeID") +#define txtNodeName CTRL_TEXT("txtNodeName") +#define txtAdminNodeID CTRL_TEXT("txtAdminNodeID") +#define txtAdminNodeName CTRL_TEXT("txtAdminNodeName") +#define cbAdminNode CTRL_COMBOBOX("cbAdminNode") + + +BEGIN_EVENT_TABLE(dlgRepCluster, dlgRepClusterBase) + EVT_BUTTON(wxID_OK, dlgRepCluster::OnOK) + EVT_CHECKBOX(XRCID("chkJoinCluster"), dlgRepCluster::OnChangeJoin) + EVT_COMBOBOX(XRCID("cbClusterName"), dlgRepCluster::OnChangeCluster) + EVT_TEXT(XRCID("txtClusterName"), dlgRepCluster::OnChange) + EVT_TEXT(XRCID("txtNodeID"), dlgRepCluster::OnChange) + EVT_TEXT(XRCID("txtNodeName"), dlgRepCluster::OnChange) + EVT_COMBOBOX(XRCID("cbAdminNode"), dlgRepCluster::OnChange) + EVT_END_PROCESS(-1, dlgRepCluster::OnEndProcess) +END_EVENT_TABLE(); + + +dlgProperty *pgaSlClusterFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgRepCluster(this, frame, (slCluster *)node, (pgDatabase *)parent); +} + + +dlgRepCluster::dlgRepCluster(pgaFactory *f, frmMain *frame, slCluster *node, pgDatabase *db) + : dlgRepClusterBase(f, frame, wxT("dlgRepCluster"), node, db) +{ + process = 0; +} + + + +wxString dlgRepCluster::GetHelpPage() const +{ + wxString page = wxT("slony-install"); + if (chkJoinCluster->GetValue()) + page += wxT("#join"); + + return page; +} + +bool dlgRepCluster::SlonyMaximumVersion(const wxString &series, long minor) +{ + + wxString slonySeries; + long slonyMinorVersion; + + slonySeries = slonyVersion.BeforeLast('.'); + slonyVersion.AfterLast('.').ToLong(&slonyMinorVersion); + + return slonySeries == series && slonyMinorVersion <= minor; +} + + + +int dlgRepCluster::Go(bool modal) +{ + chkJoinCluster->SetValue(false); + + if (cluster) + { + // edit mode + txtClusterName->SetValue(cluster->GetName()); + txtNodeID->SetValue(NumToStr(cluster->GetLocalNodeID())); + txtClusterName->Disable(); + txtNodeID->Disable(); + txtNodeName->SetValue(cluster->GetLocalNodeName()); + txtNodeName->Disable(); + chkJoinCluster->Disable(); + + txtAdminNodeID->Hide(); + txtAdminNodeName->Hide(); + + wxString sql = + wxT("SELECT no_id, no_comment\n") + wxT(" FROM ") + cluster->GetSchemaPrefix() + wxT("sl_node\n") + wxT(" JOIN ") + cluster->GetSchemaPrefix() + wxT("sl_path ON no_id = pa_client\n") + wxT(" WHERE pa_server = ") + NumToStr(cluster->GetLocalNodeID()) + + wxT(" AND pa_conninfo LIKE ") + qtDbString(wxT("%host=") + cluster->GetServer()->GetName() + wxT("%")) + + wxT(" AND pa_conninfo LIKE ") + qtDbString(wxT("%dbname=") + cluster->GetDatabase()->GetName() + wxT("%")); + + if (cluster->GetServer()->GetPort() != 5432) + sql += wxT(" AND pa_conninfo LIKE ") + qtDbString(wxT("%port=") + NumToStr((long)cluster->GetServer()->GetPort()) + wxT("%")); + + sql += wxT(" ORDER BY no_id"); + + pgSet *set = connection->ExecuteSet(sql); + if (set) + { + while (!set->Eof()) + { + long id = set->GetLong(wxT("no_id")); + cbAdminNode->Append(IdAndName(id, set->GetVal(wxT("no_comment"))), (void *)id); + if (id == cluster->GetAdminNodeID()) + cbAdminNode->SetSelection(cbAdminNode->GetCount() - 1); + + set->MoveNext(); + } + delete set; + } + if (!cbAdminNode->GetCount()) + { + cbAdminNode->Append(_(""), (void *) - 1); + cbAdminNode->SetSelection(0); + } + + cbServer->Append(cluster->GetServer()->GetName()); + cbServer->SetSelection(0); + cbDatabase->Append(cluster->GetDatabase()->GetName()); + cbDatabase->SetSelection(0); + cbClusterName->Append(cluster->GetName()); + cbClusterName->SetSelection(0); + } + else + { + // create mode + cbAdminNode->Hide(); + + wxString scriptVersion = wxEmptyString; + wxString xxidVersion = wxEmptyString; + + txtNodeID->SetValidator(numericValidator); + txtAdminNodeID->SetValidator(numericValidator); + txtClusterName->Hide(); + + //We need to find the exact Slony Version. + //NOTE: We are not supporting Slony versions less than 1.2.0 + wxString tempScript = wxEmptyString; + bool isSlonyVersionBefore2_2_0 = false; + + if(!AddScript(tempScript, wxT("slony1_funcs.sql"))) + { + if(!AddScript(tempScript, wxT("slony1_funcs.2.2.0.sql"))) + { + isSlonyVersionBefore2_2_0 = true; + } + else + { + isSlonyVersionBefore2_2_0 = false; + } + } + else + { + isSlonyVersionBefore2_2_0 = true; + } + + if (tempScript.Contains(wxT("@MODULEVERSION@")) && slonyVersion.IsEmpty()) + { + bool hasVerFunc = false; + this->database->ExecuteVoid(wxT("RESET SEARCH_PATH;")); + + if (isSlonyVersionBefore2_2_0) + hasVerFunc = this->database->ExecuteVoid(wxT("CREATE OR REPLACE FUNCTION pgadmin_slony_version() returns text as '$libdir/slony1_funcs', '_Slony_I_getModuleVersion' LANGUAGE C"), false); + else + hasVerFunc = this->database->ExecuteVoid(wxT("CREATE OR REPLACE FUNCTION pgadmin_slony_version() returns text as '$libdir/slony1_funcs.2.2.0', '_Slony_I_2_2_0_getModuleVersion' LANGUAGE C"), false); + + if (hasVerFunc) + { + slonyVersion = this->database->ExecuteScalar(wxT("SELECT pgadmin_slony_version();")); + this->database->ExecuteVoid(wxT("DROP FUNCTION pgadmin_slony_version()"), false); + } + else + { + tempScript.Empty(); + } + + if (slonyVersion.IsEmpty()) + { + wxLogError(_("Couldn't test for the Slony version. Assuming 1.2.0")); + slonyVersion = wxT("1.2.0"); + } + } + + //Here we are finding the exact slony scripts version, which is based on Slony Version and PG Version. + // For Slony 1.2.0 to 1.2.21 and 2.0.0 if PG 7.3 script version is v73 + // For Slony 1.2.0 to 1.2.21 and 2.0.0 if PG 7.4 script version is v74 + // For Slony 1.2.0 to 1.2.6 if PG 8.0+ script version is v80 + // For Slony 1.2.7 to 1.2.21 and 2.0.0 if PG 8.0 script version is v80 + // For Slony 1.2.7 to 1.2.21 and 2.0.0 if PG 8.1+ script version is v81 + // For Slony 2.0.1 and 2.0.2 if PG 8.3+ script version is v83. (These version onwards do not support PG Version less than 8.3) + // For Slony 2.0.3 if PG 8.3 script version is v83. + // For Slony 2.0.3 if PG 8.4+ script version is v84. + // For Slony 2.1.0 to 2.2.0 if PG 8.3 script version v83 + // For Slony 2.1.0 to 2.2.0 if PG 8.4+ script version v84 + // Since both 1.2 and 2.0 series is increasing, the following code needs to be updated with each Slony or PG update. + // For Slony 1.2.22 onwards if PG 7.4 script version v74 + // For Slony 1.2.22 onwards if PG 8.0 script version v80 + // For Slony 1.2.22 onwards if PG 8.3 script version v81 + // For Slony 1.2.22 onwards if PG 8.4+ script version v84 + if (!tempScript.IsEmpty()) + { + wxString slonySeries; + long slonyMinorVersion; + slonySeries = slonyVersion.BeforeLast('.'); + slonyVersion.AfterLast('.').ToLong(&slonyMinorVersion); + + //Set the slony_base and slony_funcs script version. + if (SlonyMaximumVersion(wxT("1.2"), 6)) + { + if (connection->BackendMinimumVersion(8, 0)) + scriptVersion = wxT("v80"); + else + { + if (connection->BackendMinimumVersion(7, 4)) + scriptVersion = wxT("v74"); + else + scriptVersion = wxT("v73"); + } + } + else + { + // For slony verion 1.2.22 and above set the script version + if (slonySeries == wxT("1.2") && slonyMinorVersion >= 22) + { + if (connection->BackendMinimumVersion(8, 4)) + scriptVersion = wxT("v84"); + else + { + if (connection->BackendMinimumVersion(8, 1)) + scriptVersion = wxT("v81"); + else + { + if (connection->BackendMinimumVersion(8, 0)) + scriptVersion = wxT("v80"); + else + scriptVersion = wxT("v74"); + } + } + } + + // For slony major version 1.2, minor version <= 21 and slony version 2.0, set the script version + if (SlonyMaximumVersion(wxT("1.2"), 21) || SlonyMaximumVersion(wxT("2.0"), 0)) + { + if (connection->BackendMinimumVersion(8, 1)) + scriptVersion = wxT("v81"); + else + { + if (connection->BackendMinimumVersion(8, 0)) + scriptVersion = wxT("v80"); + else + { + if (connection->BackendMinimumVersion(7, 4)) + scriptVersion = wxT("v74"); + else + scriptVersion = wxT("v73"); + } + } + } + else + { + if (SlonyMaximumVersion(wxT("2.0"), 2)) + scriptVersion = wxT("v83"); + else + { + if (SlonyMaximumVersion(wxT("2.0"), 8)) + { + if (connection->BackendMinimumVersion(8, 4)) + scriptVersion = wxT("v84"); + } + + if (SlonyMaximumVersion(wxT("2.1"), 4) || SlonyMaximumVersion(wxT("2.2"), 0)) + { + if (connection->BackendMinimumVersion(8, 4)) + scriptVersion = wxT("v84"); + } + else + { + if (scriptVersion.IsEmpty()) + scriptVersion = wxT("v83"); + } + } + } + } + + //Set the correct xxid version if applicable + // For Slony 1.2.0 to 1.2.17 and 2.0.0 if PG 7.3 xxid version is v73 + // For Slony 1.2.1 to 1.2.17 and 2.0.0 if PG 7.4+ xxid version is v74 + // For Slony 1.2.0 if PG 8.0 xxid version is v80 + // For Slony 2.0.1+ and PG8.4+ xxid is obsolete. + + if (SlonyMaximumVersion(wxT("1.2"), 0)) + { + if (connection->BackendMinimumVersion(8, 0)) + xxidVersion = wxT("v80"); + else + { + if (connection->BackendMinimumVersion(7, 4)) + xxidVersion = wxT("v74"); + else + xxidVersion = wxT("v73"); + } + } + else + { + // For Slony 1.2.22 and above if PG 7.4 xxid version is v74 + // For Slony 1.2.22 and above if PG 8.0 xxid version is v80 + // For Slony 1.2.22 and above if PG 8.1 xxid version is v81 + // For Slony 1.2.22 and above if PG 8.4+ xxid version is v84 + if (slonySeries == wxT("1.2") && slonyMinorVersion >= 22) + { + if (connection->BackendMinimumVersion(8, 4)) + xxidVersion = wxT("v84"); + else + { + if (connection->BackendMinimumVersion(8, 1)) + xxidVersion = wxT("v81"); + else + { + if (connection->BackendMinimumVersion(8, 0)) + xxidVersion = wxT("v80"); + else + xxidVersion = wxT("v74"); + } + } + } + + if (SlonyMaximumVersion(wxT("1.2"), 21) || SlonyMaximumVersion(wxT("2.0"), 0)) + { + if (!connection->BackendMinimumVersion(8, 4)) + { + if (connection->BackendMinimumVersion(7, 4)) + xxidVersion = wxT("v74"); + else + xxidVersion = wxT("v73"); + } + } + } + + wxString slonyBaseVersionFilename; + wxString slonyFuncsVersionFilename; + + if (SlonyMaximumVersion(wxT("2.2"), 0)) + { + slonyBaseVersionFilename = wxT("slony1_base.") + scriptVersion + wxT(".2.2.0.sql"); + slonyFuncsVersionFilename = wxT("slony1_funcs.") + scriptVersion + wxT(".2.2.0.sql"); + } + else + { + slonyBaseVersionFilename = wxT("slony1_base.") + scriptVersion + wxT(".sql"); + slonyFuncsVersionFilename = wxT("slony1_funcs.") + scriptVersion + wxT(".sql"); + } + + wxString xxidVersionFilename; + + if (!xxidVersion.IsEmpty()) + xxidVersionFilename = wxT("xxid.") + xxidVersion + wxT(".sql"); + + if (SlonyMaximumVersion(wxT("2.2"), 0)) + { + if (((!xxidVersion.IsEmpty() && !AddScript(createScript, xxidVersionFilename)) || + !AddScript(createScript, wxT("slony1_base.2.2.0.sql")) || + !AddScript(createScript, slonyBaseVersionFilename) || + !AddScript(createScript, wxT("slony1_funcs.2.2.0.sql")) || + !AddScript(createScript, slonyFuncsVersionFilename))) + createScript = wxEmptyString; + } + else + { + if (((!xxidVersion.IsEmpty() && !AddScript(createScript, xxidVersionFilename)) || + !AddScript(createScript, wxT("slony1_base.sql")) || + !AddScript(createScript, slonyBaseVersionFilename) || + !AddScript(createScript, wxT("slony1_funcs.sql")) || + !AddScript(createScript, slonyFuncsVersionFilename))) + createScript = wxEmptyString; + } + } + + // Populate the server combo box + ctlTree *browser = mainForm->GetBrowser(); + wxTreeItemIdValue foldercookie, servercookie; + wxTreeItemId folderitem, serveritem; + pgObject *object; + pgServer *server; + int sel = -1; + + folderitem = browser->GetFirstChild(browser->GetRootItem(), foldercookie); + while (folderitem) + { + if (browser->ItemHasChildren(folderitem)) + { + serveritem = browser->GetFirstChild(folderitem, servercookie); + while (serveritem) + { + object = browser->GetObject(serveritem); + if (object && object->IsCreatedBy(serverFactory)) + { + server = (pgServer *)object; + if (server == database->GetServer()) + sel = cbServer->GetCount(); + cbServer->Append(browser->GetItemText(server->GetId()), (void *)server); + } + serveritem = browser->GetNextChild(folderitem, servercookie); + } + } + folderitem = browser->GetNextChild(browser->GetRootItem(), foldercookie); + } + + if (sel >= 0) + cbServer->SetSelection(sel); + } + + wxCommandEvent ev; + OnChangeJoin(ev); + + return dlgRepClusterBase::Go(modal); +} + + +void dlgRepCluster::OnChangeJoin(wxCommandEvent &ev) +{ + bool joinCluster = chkJoinCluster->GetValue(); + txtClusterName->Show(!joinCluster); + cbClusterName->Show(joinCluster); + + cbServer->Enable(joinCluster); + cbDatabase->Enable(joinCluster); + + txtAdminNodeID->Show(!joinCluster && !cluster); + txtAdminNodeName->Show(!joinCluster && !cluster); + cbAdminNode->Show(joinCluster || cluster); + cbAdminNode->Move(txtAdminNodeID->GetPosition()); + + // Force the dialogue to resize to prevent a drawing issue on GTK +#ifdef __WXGTK__ + SetSize(GetSize().x + 1, GetSize().y + 1); + Layout(); + SetSize(GetSize().x - 1, GetSize().y - 1); +#endif + + if (joinCluster && !cbDatabase->GetCount()) + { + OnChangeServer(ev); + return; + } + + OnChange(ev); +} + + +void dlgRepCluster::OnChangeCluster(wxCommandEvent &ev) +{ + clusterBackup = wxEmptyString; + remoteVersion = wxEmptyString; + + cbAdminNode->Clear(); + cbAdminNode->Append(_(""), (void *) - 1); + + int sel = cbClusterName->GetCurrentSelection(); + if (remoteConn && sel >= 0) + { + wxString schemaPrefix = qtIdent(wxT("_") + cbClusterName->GetValue()) + wxT("."); + long adminNodeID = settings->Read(wxT("Replication/") + cbClusterName->GetValue() + wxT("/AdminNode"), -1L); + + remoteVersion = remoteConn->ExecuteScalar(wxT("SELECT ") + schemaPrefix + wxT("slonyVersion();")); + + wxString sql = + wxT("SELECT no_id, no_comment\n") + wxT(" FROM ") + schemaPrefix + wxT("sl_node\n") + wxT(" JOIN ") + schemaPrefix + wxT("sl_path ON no_id = pa_client\n") + wxT(" WHERE pa_server = (SELECT last_value FROM ") + schemaPrefix + wxT("sl_local_node_id)\n") + wxT(" AND pa_conninfo ILIKE ") + qtDbString(wxT("%host=") + remoteServer->GetName() + wxT("%")) + wxT("\n") + wxT(" AND pa_conninfo LIKE ") + qtDbString(wxT("%dbname=") + cbDatabase->GetValue() + wxT("%")) + wxT("\n"); + + if (remoteServer->GetPort() != 5432) + sql += wxT(" AND pa_conninfo LIKE ") + qtDbString(wxT("%port=") + NumToStr((long)remoteServer->GetPort()) + wxT("%")); + + pgSet *set = remoteConn->ExecuteSet(sql); + if (set) + { + if (!set->Eof()) + { + long id = set->GetLong(wxT("no_id")); + cbAdminNode->Append(IdAndName(id, set->GetVal(wxT("no_comment"))), (void *)id); + if (adminNodeID == id) + cbAdminNode->SetSelection(cbAdminNode->GetCount() - 1); + } + } + + + usedNodes.Clear(); + set = remoteConn->ExecuteSet( + wxT("SELECT no_id FROM ") + schemaPrefix + wxT("sl_node")); + + if (set) + { + while (!set->Eof()) + { + usedNodes.Add(set->GetLong(wxT("no_id"))); + set->MoveNext(); + } + delete set; + } + } + OnChange(ev); +} + + + +bool dlgRepCluster::CopyTable(pgConn *from, pgConn *to, const wxString &table) +{ + bool ok = true; + + pgSet *set = from->ExecuteSet(wxT("SELECT * FROM ") + table); + if (!set) + return false; + + while (ok && !set->Eof()) + { + wxString sql = wxT("INSERT INTO ") + table + wxT("("); + wxString vals; + int i; + + for (i = 0 ; i < set->NumCols() ; i++) + { + if (i) + { + sql += wxT(", ");; + vals += wxT(", "); + } + + sql += set->ColName(i); + + if (set->IsNull(i)) + vals += wxT("NULL"); + else + { + switch (set->ColTypeOid(i)) + { + case PGOID_TYPE_BOOL: + case PGOID_TYPE_BYTEA: + case PGOID_TYPE_CHAR: + case PGOID_TYPE_NAME: + case PGOID_TYPE_TEXT: + case PGOID_TYPE_VARCHAR: + case PGOID_TYPE_TIME: + case PGOID_TYPE_TIMESTAMP: + case PGOID_TYPE_TIME_ARRAY: + case PGOID_TYPE_TIMESTAMPTZ: + case PGOID_TYPE_INTERVAL: + case PGOID_TYPE_TIMETZ: + vals += qtDbString(set->GetVal(i)); + break; + default: + vals += set->GetVal(i); + } + } + } + + ok = to->ExecuteVoid( + sql + wxT(")\n VALUES (") + vals + wxT(");")); + + + set->MoveNext(); + } + delete set; + return ok; +} + + +void dlgRepCluster::OnOK(wxCommandEvent &ev) +{ +#ifdef __WXGTK__ + if (!btnOK->IsEnabled()) + return; +#endif + EnableOK(false); + + bool done = true; + done = connection->ExecuteVoid(wxT("BEGIN TRANSACTION;")); + + if (remoteConn) + done = remoteConn->ExecuteVoid(wxT("BEGIN TRANSACTION;")); + + // initialize cluster on local node + done = connection->ExecuteVoid(GetSql()); + + if (done && chkJoinCluster->GetValue()) + { + // we're joining an existing cluster + + wxString schemaPrefix = qtIdent(wxT("_") + cbClusterName->GetValue()) + wxT("."); + + wxString clusterVersion = remoteConn->ExecuteScalar( + wxT("SELECT ") + schemaPrefix + wxT("slonyversion()")); + + wxString newVersion = connection->ExecuteScalar( + wxT("SELECT ") + schemaPrefix + wxT("slonyversion()")); + + if (clusterVersion != newVersion) + { + wxMessageDialog msg(this, + wxString::Format(_("The newly created cluster version (%s)\n doesn't match the existing cluster's version (%s)"), + newVersion.c_str(), clusterVersion.c_str()), + _("Error while joining replication cluster"), wxICON_ERROR); + msg.ShowModal(); + done = false; + } + + if (done) + done = CopyTable(remoteConn, connection, schemaPrefix + wxT("sl_node")); + if (done) + done = CopyTable(remoteConn, connection, schemaPrefix + wxT("sl_path")); + if (done) + done = CopyTable(remoteConn, connection, schemaPrefix + wxT("sl_listen")); + if (done) + done = CopyTable(remoteConn, connection, schemaPrefix + wxT("sl_set")); + if (done) + done = CopyTable(remoteConn, connection, schemaPrefix + wxT("sl_subscribe")); + + + // make sure event seqno starts correctly after node reusage + if (done) + { + pgSet *set = connection->ExecuteSet( + wxT("SELECT ev_origin, MAX(ev_seqno) as seqno\n") + wxT(" FROM ") + schemaPrefix + wxT("sl_event\n") + wxT(" GROUP BY ev_origin")); + if (set) + { + while (done && !set->Eof()) + { + if (set->GetVal(wxT("ev_origin")) == txtNodeID->GetValue()) + { + done = connection->ExecuteVoid( + wxT("SELECT pg_catalog.setval(") + + qtDbString(wxT("_") + cbClusterName->GetValue() + wxT(".sl_event_seq")) + + wxT(", ") + set->GetVal(wxT("seqno")) + wxT("::int8 +1)")); + } + else + { + done = connection->ExecuteVoid( + wxT("INSERT INTO ") + schemaPrefix + wxT("sl_confirm(con_origin, con_received, con_seqno, con_timestamp\n") + wxT(" VALUES (") + set->GetVal(wxT("ev_origin")) + + wxT(", ") + txtNodeID->GetValue() + + wxT(", ") + set->GetVal(wxT("seqno")) + + wxT(", current_timestamp")); + + } + set->MoveNext(); + } + delete set; + } + } + + + // make sure rowid seq starts correctly + if (done) + { + wxString seqno = connection->ExecuteScalar( + wxT("SELECT MAX(seql_last_value)\n") + wxT(" FROM ") + schemaPrefix + wxT("sl_seqlog\n") + wxT(" WHERE seql_seqid = 0 AND seql_origin = ") + txtNodeID->GetValue()); + + if (!seqno.IsEmpty()) + { + done = connection->ExecuteVoid( + wxT("SELECT pg_catalog.setval(") + + qtDbString(wxT("_") + cbClusterName->GetValue() + wxT(".sl_rowid_seq")) + + wxT(", ") + seqno + wxT(")")); + } + } + + // create new node on the existing cluster + if (done) + { + wxString sql = + wxT("SELECT ") + schemaPrefix + wxT("storenode(") + + txtNodeID->GetValue() + wxT(", ") + + qtDbString(txtNodeName->GetValue()); + + // When user has not selected cluster drop down in that case "schemaPrefix" will be NULL, + // we have to use slonyVersion instead of remoteVersion + if (remoteVersion.IsEmpty()) + { + if (StrToDouble(slonyVersion) >= 1.1 && StrToDouble(slonyVersion) < 2.0) + sql += wxT(", false"); + } + else + { + if (StrToDouble(remoteVersion) >= 1.1 && StrToDouble(remoteVersion) < 2.0) + sql += wxT(", false"); + } + + sql += wxT(");\n") + wxT("SELECT ") + schemaPrefix + wxT("enablenode(") + + txtNodeID->GetValue() + wxT(");\n"); + + done = remoteConn->ExecuteVoid(sql); + } + + // add admin info to cluster + + if (done && cbAdminNode->GetCurrentSelection() > 0) + { + done = remoteConn->ExecuteVoid( + wxT("SELECT ") + schemaPrefix + wxT("storepath(") + + txtNodeID->GetValue() + wxT(", ") + + NumToStr((long)cbAdminNode->wxItemContainer::GetClientData(cbAdminNode->GetCurrentSelection())) + wxT(", ") + + qtDbString(wxT("host=") + database->GetServer()->GetName() + + wxT(" port=") + NumToStr((long)database->GetServer()->GetPort()) + + wxT(" dbname=") + database->GetName()) + wxT(", ") + wxT("0);\n")); + } + } + if (!done) + { + if (remoteConn) + done = remoteConn->ExecuteVoid(wxT("ROLLBACK TRANSACTION;")); + done = connection->ExecuteVoid(wxT("ROLLBACK TRANSACTION;")); + EnableOK(true); + return; + } + + if (remoteConn) + done = remoteConn->ExecuteVoid(wxT("COMMIT TRANSACTION;")); + done = connection->ExecuteVoid(wxT("COMMIT TRANSACTION;")); + + ShowObject(); + Destroy(); +} + + +pgObject *dlgRepCluster::CreateObject(pgCollection *collection) +{ + pgObject *obj = slClusterFactory.CreateObjects(collection, 0, + wxT(" WHERE nspname = ") + qtDbString(wxT("_") + GetName())); + + return obj; +} + + +void dlgRepCluster::CheckChange() +{ + if (cluster) + { + int sel = cbAdminNode->GetCurrentSelection(); + bool changed = (sel >= 0 && (long)cbAdminNode->wxEvtHandler::GetClientData() != cluster->GetAdminNodeID()); + + EnableOK(changed || txtComment->GetValue() != cluster->GetComment()); + } + else + { + size_t i; + bool enable = true; + + CheckValid(enable, chkJoinCluster->GetValue() || (!createScript.IsEmpty()), + _("Slony-I creation scripts not available; only joining possible.")); + + if (chkJoinCluster->GetValue()) + CheckValid(enable, !cbClusterName->GetValue().IsEmpty(), _("Please select a cluster name.")); + else + CheckValid(enable, !txtClusterName->GetValue().IsEmpty(), _("Please specify name.")); + + long nodeId = StrToLong(txtNodeID->GetValue()); + CheckValid(enable, nodeId > 0, _("Please specify local node ID.")); + for (i = 0 ; i < usedNodes.GetCount() && enable; i++) + CheckValid(enable, nodeId != usedNodes[i], _("Node ID is already in use.")); + + CheckValid(enable, !txtNodeName->GetValue().IsEmpty(), _("Please specify local node name.")); + + txtAdminNodeName->Enable(nodeId != StrToLong(txtAdminNodeID->GetValue())); + + EnableOK(enable); + } +} + + +void dlgRepCluster::OnEndProcess(wxProcessEvent &ev) +{ + if (process) + { + wxString error = process->ReadErrorStream(); + clusterBackup += process->ReadInputStream(); + delete process; + process = 0; + } +} + + +// this is necessary because wxString::Replace is ridiculously slow on large strings. + +void AppendBuf(wxChar *&buf, int &buflen, int &len, const wxChar *str, int slen = -1) +{ + if (slen < 0) + slen = wxStrlen(str); + if (!slen) + return; + if (buflen < len + slen) + { + buflen = (len + slen) * 6 / 5; + wxChar *tmp = new wxChar[buflen + 1]; + memcpy(tmp, buf, len * sizeof(wxChar)); + delete[] buf; + buf = tmp; + } + memcpy(buf + len, str, slen * sizeof(wxChar)); + len += slen; +} + + +wxString ReplaceString(const wxString &str, const wxString &oldStr, const wxString &newStr) +{ + int buflen = str.Length() + 100; + int len = 0; + + wxChar *buf = new wxChar[buflen + 1]; + + const wxChar *ptrIn = str.c_str(); + const wxChar *ptrFound = wxStrstr(ptrIn, oldStr); + + while (ptrFound) + { + AppendBuf(buf, buflen, len, ptrIn, ptrFound - ptrIn); + AppendBuf(buf, buflen, len, newStr.c_str()); + ptrIn = ptrFound + oldStr.Length(); + ptrFound = wxStrstr(ptrIn, oldStr); + } + + AppendBuf(buf, buflen, len, ptrIn); + buf[len] = 0; + wxString tmpstr(buf); + delete[] buf; + + return tmpstr; +} + + +wxString dlgRepCluster::GetSql() +{ + wxString sql; + wxString name; + if (chkJoinCluster->GetValue()) + name = wxT("_") + cbClusterName->GetValue(); + else + name = wxT("_") + txtClusterName->GetValue(); + + wxString quotedName = qtIdent(name); + + + if (cluster) + { + // edit mode + int sel = cbAdminNode->GetCurrentSelection(); + if (sel >= 0) + { + long id = (long)cbAdminNode->wxItemContainer::GetClientData(sel); + if (id != cluster->GetAdminNodeID()) + settings->WriteLong(wxT("Replication/") + cluster->GetName() + wxT("/AdminNode"), id); + } + } + else + { + // create mode + wxString backupExecutable; + if (remoteServer && remoteServer->GetConnection()->EdbMinimumVersion(8, 0)) + backupExecutable = edbBackupExecutable; + else if (remoteServer && remoteServer->GetConnection()->GetIsGreenplum()) + backupExecutable = gpBackupExecutable; + else + backupExecutable = pgBackupExecutable; + + if (remoteServer && clusterBackup.IsEmpty() && !backupExecutable.IsEmpty()) + { + wxArrayString environment; + if (!remoteServer->GetPasswordIsStored()) + environment.Add(wxT("PGPASSWORD=") + remoteServer->GetPassword()); + + process = sysProcess::Create(backupExecutable + + wxT(" -i -F p -h ") + remoteServer->GetName() + + wxT(" -p ") + NumToStr((long)remoteServer->GetPort()) + + wxT(" -U ") + remoteServer->GetUsername() + + wxT(" -s -O -n ") + name + + wxT(" ") + cbDatabase->GetValue(), + this, &environment); + + wxBusyCursor wait; + while (process) + { + wxSafeYield(); + if (process) + clusterBackup += process->ReadInputStream(); + wxSafeYield(); + wxMilliSleep(10); + } + } + + if (!clusterBackup.IsEmpty()) + { + int opclassPos = clusterBackup.Find(wxT("CREATE OPERATOR CLASS")); + sql = wxT("-- Extracted schema from existing cluster\n\n") + + clusterBackup.Left(opclassPos > 0 ? opclassPos : 99999999); + if (opclassPos > 0) + { + sql += wxT("----------- inserted by pgadmin: add public operators\n") + wxT("CREATE OPERATOR public.< (PROCEDURE = xxidlt,") + wxT(" LEFTARG = xxid, RIGHTARG = xxid,") + wxT(" COMMUTATOR = public.\">\", NEGATOR = public.\">=\",") + wxT(" RESTRICT = scalarltsel, JOIN = scalarltjoinsel);\n") + wxT("CREATE OPERATOR public.= (PROCEDURE = xxideq,") + wxT(" LEFTARG = xxid, RIGHTARG = xxid,") + wxT(" COMMUTATOR = public.\"=\", NEGATOR = public.\"<>\",") + wxT(" RESTRICT = eqsel, JOIN = eqjoinsel,") + wxT(" SORT1 = public.\"<\", SORT2 = public.\"<\", HASHES);\n") + wxT("CREATE OPERATOR public.<> (PROCEDURE = xxidne,") + wxT(" LEFTARG = xxid, RIGHTARG = xxid,") + wxT(" COMMUTATOR = public.\"<>\", NEGATOR = public.\"=\",") + wxT(" RESTRICT = neqsel, JOIN = neqjoinsel);\n") + wxT("CREATE OPERATOR public.> (PROCEDURE = xxidgt,") + wxT(" LEFTARG = xxid, RIGHTARG = xxid,") + wxT(" COMMUTATOR = public.\"<\", NEGATOR = public.\"<=\",") + wxT(" RESTRICT = scalargtsel, JOIN = scalargtjoinsel);\n") + wxT("CREATE OPERATOR public.<= (PROCEDURE = xxidle,") + wxT(" LEFTARG = xxid, RIGHTARG = xxid,") + wxT(" COMMUTATOR = public.\">=\", NEGATOR = public.\">\",") + wxT(" RESTRICT = scalarltsel, JOIN = scalarltjoinsel);\n") + wxT("CREATE OPERATOR public.>= (PROCEDURE = xxidge,") + wxT(" LEFTARG = xxid, RIGHTARG = xxid,") + wxT(" COMMUTATOR = public.\"<=\", NEGATOR = public.\"<\",") + wxT(" RESTRICT = scalargtsel, JOIN = scalargtjoinsel);\n") + wxT("------------- continue with backup script\n") + + clusterBackup.Mid(opclassPos); + } + } + else + { + sql = wxT("CREATE SCHEMA ") + quotedName + wxT(";\n\n") + + ReplaceString(createScript, wxT("@NAMESPACE@"), quotedName); + + if (chkJoinCluster->GetValue()) + sql = ReplaceString(sql, wxT("@CLUSTERNAME@"), cbClusterName->GetValue()); + else + sql = ReplaceString(sql, wxT("@CLUSTERNAME@"), txtClusterName->GetValue()); + + // From Slony 1.2 onwards, the scripts include the module version. + // To figure it out, temporarily load and use _Slony_I_getModuleVersion. + // We'll cache the result to save doing it again. + if (sql.Contains(wxT("@MODULEVERSION@")) && slonyVersion.IsEmpty()) + { + bool hasVerFunc = this->database->ExecuteVoid(wxT("CREATE OR REPLACE FUNCTION pgadmin_slony_version() returns text as '$libdir/slony1_funcs', '_Slony_I_getModuleVersion' LANGUAGE C"), false); + if (!hasVerFunc) + { + hasVerFunc = this->database->ExecuteVoid(wxT("CREATE OR REPLACE FUNCTION pgadmin_slony_version() returns text as '$libdir/slony1_funcs.2.2.0', '_Slony_I_2_2_0_getModuleVersion' LANGUAGE C"), false); + } + if (hasVerFunc) + { + slonyVersion = this->database->ExecuteScalar(wxT("SELECT pgadmin_slony_version();")); + this->database->ExecuteVoid(wxT("DROP FUNCTION pgadmin_slony_version()"), false); + } + + if (slonyVersion.IsEmpty()) + { + wxLogError(_("Couldn't test for the Slony version. Assuming 1.2.0")); + slonyVersion = wxT("1.2.0"); + } + } + sql = ReplaceString(sql, wxT("@MODULEVERSION@"), slonyVersion); + + // If slony version is greater then equal to 2.2 then replace @FUNCVERSION to 2_2_0 + if (sql.Contains(wxT("@FUNCVERSION@")) && SlonyMaximumVersion(wxT("2.2"), 0)) + { + wxString slonyFuncVersion = slonyVersion; + slonyFuncVersion.Replace(wxT("."), wxT("_")); + sql = ReplaceString(sql, wxT("@FUNCVERSION@"), slonyFuncVersion); + } + } + + sql += wxT("\n") + wxT("SELECT ") + quotedName + wxT(".initializelocalnode(") + + txtNodeID->GetValue() + wxT(", ") + qtDbString(txtNodeName->GetValue()) + + wxT(");\n") + wxT("SELECT ") + quotedName; + + if (chkJoinCluster->GetValue()) + sql += wxT(".enablenode_int("); + else + sql += wxT(".enablenode("); + + sql += txtNodeID->GetValue() + + wxT(");\n"); + } + + if ((!cluster && !txtComment->IsEmpty()) || (cluster && + cluster->GetComment() != txtComment->GetValue())) + { + sql += wxT("\n") + wxT("COMMENT ON SCHEMA ") + quotedName + wxT(" IS ") + + qtDbString(txtComment->GetValue()) + wxT(";\n"); + } + + if (chkJoinCluster->GetValue()) + sql += wxT("\n\n-- In addition, the configuration is copied from the existing cluster.\n"); + else + { + wxString schemaPrefix = qtIdent(wxT("_") + txtClusterName->GetValue()) + wxT("."); + long adminNode = StrToLong(txtAdminNodeID->GetValue()); + if (adminNode > 0 && adminNode != StrToLong(txtNodeID->GetValue())) + { + sql += + wxT("\n-- Create admin node\n") + wxT("SELECT ") + schemaPrefix + wxT("storeNode(") + + NumToStr(adminNode) + wxT(", ") + + qtDbString(txtAdminNodeName->GetValue()); + + + // When user has not selected cluster drop down in that case "schemaPrefix" will be NULL, + // we have to use slonyVersion instead of remoteVersion + if (remoteVersion.IsEmpty()) + { + if (StrToDouble(slonyVersion) >= 1.1 && StrToDouble(slonyVersion) < 2.0) + sql += wxT(", false"); + } + else + { + // storeNode API contains three argument in slony version 1.1 and 1.2 (storeNode(int4,text,boolean)), + // slony version 2.0 onwards, storeNode API contains only two arguments e.g. storeNode(int4,text) + if (StrToDouble(remoteVersion) >= 1.1 && StrToDouble(remoteVersion) < 2.0) + sql += wxT(", false"); + } + + sql += wxT(");\n") + wxT("SELECT ") + schemaPrefix + wxT("storepath(") + + txtNodeID->GetValue() + wxT(", ") + + NumToStr(adminNode) + wxT(", ") + + qtDbString(wxT("host=") + database->GetServer()->GetName() + + wxT(" port=") + NumToStr((long)database->GetServer()->GetPort()) + + wxT(" dbname=") + database->GetName()) + wxT(", ") + wxT("0);\n"); + } + } + return sql; +} + + + +////////////////////////////////////////////////////////////////////////////////7 + + +#define txtCurrentVersion CTRL_TEXT("txtCurrentVersion") +#define txtVersion CTRL_TEXT("txtVersion") + +BEGIN_EVENT_TABLE(dlgRepClusterUpgrade, dlgRepClusterBase) + EVT_COMBOBOX(XRCID("cbClusterName"), dlgRepClusterUpgrade::OnChangeCluster) +END_EVENT_TABLE(); + +// no factory needed; called by slFunction + +dlgRepClusterUpgrade::dlgRepClusterUpgrade(pgaFactory *f, frmMain *frame, slCluster *cl) + : dlgRepClusterBase(f, frame, wxT("dlgRepClusterUpgrade"), cl, cl->GetDatabase()) +{ +} + + +int dlgRepClusterUpgrade::Go(bool modal) +{ + txtCurrentVersion->SetValue(cluster->GetClusterVersion()); + txtCurrentVersion->Disable(); + txtVersion->Disable(); + + // Populate the server combo box + ctlTree *browser = mainForm->GetBrowser(); + wxTreeItemIdValue foldercookie, servercookie; + wxTreeItemId folderitem, serveritem; + pgObject *object; + pgServer *server; + + folderitem = browser->GetFirstChild(browser->GetRootItem(), foldercookie); + while (folderitem) + { + if (browser->ItemHasChildren(folderitem)) + { + serveritem = browser->GetFirstChild(folderitem, servercookie); + while (serveritem) + { + object = browser->GetObject(serveritem); + if (object && object->IsCreatedBy(serverFactory)) + { + server = (pgServer *)object; + cbServer->Append(browser->GetItemText(server->GetId()), (void *)server); + } + serveritem = browser->GetNextChild(folderitem, servercookie); + } + } + folderitem = browser->GetNextChild(browser->GetRootItem(), foldercookie); + } + + if (cbServer->GetCount()) + cbServer->SetSelection(0); + + wxCommandEvent ev; + OnChangeServer(ev); + + return dlgRepClusterBase::Go(modal); +} + + +void dlgRepClusterUpgrade::CheckChange() +{ + bool enable = true; + CheckValid(enable, cluster->GetSlonPid() == 0, _("Slon process running on node; stop it before upgrading.")); + CheckValid(enable, cbDatabase->GetCount() > 0, _("Select server with Slony-I cluster installed.")); + CheckValid(enable, cbClusterName->GetCount() > 0, _("Select database with Slony-I cluster installed.")); + CheckValid(enable, cbClusterName->GetCurrentSelection() >= 0, _("Select Slony-I cluster.")); + CheckValid(enable, version > cluster->GetClusterVersion(), _("Selected cluster doesn't contain newer software.")); + EnableOK(enable); +} + + +wxString dlgRepClusterUpgrade::GetSql() +{ + if (sql.IsEmpty() && !version.IsEmpty() && remoteConn) + { + wxString remoteCluster = wxT("_") + cbClusterName->GetValue(); + sql = wxT("SET SEARCH_PATH = ") + qtIdent(wxT("_") + cluster->GetName()) + wxT(", pg_catalog;\n\n"); + + bool upgradeSchemaAvailable = false; + + { + // update functions + pgSetIterator func(remoteConn, + wxT("SELECT proname, proisagg, prosecdef, proisstrict, proretset, provolatile, pronargs, prosrc, probin,\n") + wxT(" lanname, tr.typname as rettype,\n") + wxT(" t0.typname AS arg0, t1.typname AS arg1, t2.typname AS arg2, t3.typname AS arg3, t4.typname AS arg4,\n") + wxT(" t5.typname AS arg5, t6.typname AS arg6, t7.typname AS arg7, t8.typname AS arg8, t9.typname AS arg9, \n") + wxT(" proargnames[0] AS an0, proargnames[1] AS an1, proargnames[2] AS an2, proargnames[3] AS an3, proargnames[4] AS an4,\n") + wxT(" proargnames[5] AS an5, proargnames[6] AS an6, proargnames[7] AS an7, proargnames[8] AS an8, proargnames[9] AS an9\n") + wxT(" FROM pg_proc\n") + wxT(" JOIN pg_namespace nsp ON nsp.oid=pronamespace\n") + wxT(" JOIN pg_language l ON l.oid=prolang\n") + wxT(" JOIN pg_type tr ON tr.oid=prorettype\n") + wxT(" LEFT JOIN pg_type t0 ON t0.oid=proargtypes[0]\n") + wxT(" LEFT JOIN pg_type t1 ON t1.oid=proargtypes[1]\n") + wxT(" LEFT JOIN pg_type t2 ON t2.oid=proargtypes[2]\n") + wxT(" LEFT JOIN pg_type t3 ON t3.oid=proargtypes[3]\n") + wxT(" LEFT JOIN pg_type t4 ON t4.oid=proargtypes[4]\n") + wxT(" LEFT JOIN pg_type t5 ON t5.oid=proargtypes[5]\n") + wxT(" LEFT JOIN pg_type t6 ON t6.oid=proargtypes[6]\n") + wxT(" LEFT JOIN pg_type t7 ON t7.oid=proargtypes[7]\n") + wxT(" LEFT JOIN pg_type t8 ON t8.oid=proargtypes[8]\n") + wxT(" LEFT JOIN pg_type t9 ON t9.oid=proargtypes[9]\n") + wxT(" WHERE nspname = ") + qtDbString(remoteCluster) + ); + + while (func.RowsLeft()) + { + wxString proname = func.GetVal(wxT("proname")); + if (proname == wxT("upgradeschema")) + upgradeSchemaAvailable = true; + + sql += wxT("CREATE OR REPLACE FUNCTION " + qtIdent(proname) + wxT("("); + + wxString language = func.GetVal(wxT("lanname")); + wxString volat = func.GetVal(wxT("provolatile")); + long numArgs = func.GetLong(wxT("pronargs")); + + long i; + + for (i = 0 ; i < numArgs ; i++) + { + if (i) + sql += wxT(", "); + wxString argname = func.GetVal(wxT("an") + NumToStr(i)); + if (!argname.IsEmpty()) + sql += qtIdent(argname) + wxT(" "); + + sql += qtIdent(func.GetVal(wxT("arg") + NumToStr(i))); + } + sql += wxT(")\n") + wxT(" RETURNS "); + if (func.GetBool(wxT("proretset"))) + sql += wxT("SETOF ")); + sql += qtIdent(func.GetVal(wxT("rettype"))); + + if (language == wxT("c")) + sql += wxT("\n") + wxT("AS '" + func.GetVal(wxT("probin")) + wxT("', '") + func.GetVal(wxT("prosrc")) + wxT("'")); + else + sql += wxT(" AS\n") + wxT("$BODY$") + func.GetVal(wxT("prosrc")) + wxT("$BODY$"); + + sql += wxT(" LANGUAGE ") + language; + + if (volat == wxT("v")) + sql += wxT(" VOLATILE"); + else if (volat == wxT("i")) + sql += wxT(" IMMUTABLE"); + else + sql += wxT(" STABLE"); + + if (func.GetBool(wxT("proisstrict"))) + sql += wxT(" STRICT"); + + if (func.GetBool(wxT("prosecdef"))) + sql += wxT(" SECURITY DEFINER"); + + sql += wxT(";\n\n"); + } + } + + if (upgradeSchemaAvailable) + sql += wxT("SELECT upgradeSchema(") + qtDbString(cluster->GetClusterVersion()) + wxT(");\n\n"); + + { + // Create missing tables and columns + // we don't expect column names and types to change + + pgSetIterator srcCols(remoteConn, + wxT("SELECT relname, attname, attndims, atttypmod, attnotnull, adsrc, ty.typname, tn.nspname as typnspname,\n") + wxT(" (SELECT count(1) FROM pg_type t2 WHERE t2.typname=ty.typname) > 1 AS isdup\n") + wxT(" FROM pg_attribute\n") + wxT(" JOIN pg_class c ON c.oid=attrelid\n") + wxT(" JOIN pg_namespace n ON n.oid=relnamespace") + wxT(" LEFT JOIN pg_attrdef d ON adrelid=attrelid and adnum=attnum\n") + wxT(" JOIN pg_type ty ON ty.oid=atttypid\n") + wxT(" JOIN pg_namespace tn ON tn.oid=ty.typnamespace\n") + wxT(" WHERE n.nspname = ") + qtDbString(remoteCluster) + + wxT(" AND attnum>0 and relkind='r'\n") + wxT(" ORDER BY (relname != 'sl_confirm'), relname, attname") + ); + + pgSetIterator destCols(connection, + wxT("SELECT relname, attname, adsrc\n") + wxT(" FROM pg_attribute\n") + wxT(" JOIN pg_class c ON c.oid=attrelid\n") + wxT(" JOIN pg_namespace n ON n.oid=relnamespace") + wxT(" LEFT JOIN pg_attrdef d ON adrelid=attrelid and adnum=attnum\n") + wxT(" WHERE n.nspname = ") + qtDbString(wxT("_") + cluster->GetName()) + + wxT(" AND attnum>0 and relkind='r'\n") + wxT(" ORDER BY (relname != 'sl_confirm'), relname, attname") + ); + + if (!destCols.RowsLeft()) + return wxT("error"); + + wxString lastTable; + while (srcCols.RowsLeft()) + { + wxString table = srcCols.GetVal(wxT("relname")); + wxString column = srcCols.GetVal(wxT("attname")); + wxString defVal = srcCols.GetVal(wxT("adsrc")); + + if (table == wxT("sl_node")) + { + table = wxT("sl_node"); + } + pgDatatype dt(srcCols.GetVal(wxT("typnspname")), srcCols.GetVal(wxT("typname")), + srcCols.GetBool(wxT("isdup")), + srcCols.GetLong(wxT("attndims")), srcCols.GetLong(wxT("atttypmod"))); + + + if (destCols.Set()->Eof() || + destCols.GetVal(wxT("relname")) != table || + destCols.GetVal(wxT("attname")) != column) + { + if (table == lastTable || table == destCols.GetVal(wxT("relname"))) + { + // just an additional column + sql += wxT("ALTER TABLE ") + qtIdent(table) + + wxT(" ADD COLUMN ") + qtIdent(column) + + wxT(" ") + dt.GetQuotedSchemaPrefix(0) + dt.QuotedFullName(); + + if (!defVal.IsEmpty()) + sql += wxT(" DEFAULT ") + defVal; + if (srcCols.GetBool(wxT("attnotnull"))) + sql += wxT(" NOT NULL"); + + sql += wxT(";\n"); + } + else + { + // new table + // sl_confirm will always exist and be the first so no need for special + // precautions in case a new table is the very first in the set + + sql += wxT("CREATE TABLE ") + qtIdent(table) + + wxT(" (") + qtIdent(column) + + wxT(" ") + dt.GetQuotedSchemaPrefix(0) + dt.QuotedFullName(); + + if (!defVal.IsEmpty()) + sql += wxT(" DEFAULT ") + defVal; + + sql += wxT(");\n"); + } + } + else + { + // column is found + if (destCols.GetVal(wxT("adsrc")) != defVal) + { + sql += wxT("ALTER TABLE ") + qtIdent(table) + + wxT(" ALTER COLUMN ") + qtIdent(column); + if (defVal.IsEmpty()) + sql += wxT(" DROP DEFAULT;\n"); + else + sql += wxT(" SET DEFAULT ") + defVal + wxT(";\n"); + } + destCols.RowsLeft(); + } + lastTable = table; + } + } + + { + // check missing indexes + pgSetIterator srcIndexes(remoteConn, + wxT("SELECT t.relname, indkey, ti.relname as indname, pg_get_indexdef(indexrelid) AS inddef\n") + wxT(" FROM pg_index i\n") + wxT(" JOIN pg_class ti ON indexrelid=ti.oid\n") + wxT(" JOIN pg_class t ON indrelid=t.oid\n") + wxT(" JOIN pg_namespace n ON n.oid=t.relnamespace\n") + wxT(" WHERE nspname = ") + qtDbString(remoteCluster) + + wxT(" ORDER BY t.relname, ti.relname, indkey")); + + pgSetIterator destIndexes(remoteConn, + wxT("SELECT t.relname, indkey, ti.relname as indnamen") + wxT(" FROM pg_index i\n") + wxT(" JOIN pg_class ti ON indexrelid=ti.oid\n") + wxT(" JOIN pg_class t ON indrelid=t.oid\n") + wxT(" JOIN pg_namespace n ON n.oid=t.relnamespace\n") + wxT(" WHERE nspname = ") + qtDbString(wxT("_") + cluster->GetName()) + + wxT(" ORDER BY t.relname, ti.relname, indkey")); + + if (!destIndexes.RowsLeft()) + return wxT("error"); + + while (srcIndexes.RowsLeft()) + { + wxString table = srcIndexes.GetVal(wxT("relname")); + + bool needUpdate = destIndexes.Set()->Eof() || + destIndexes.GetVal(wxT("relname")) != table; + + if (!needUpdate && destIndexes.GetVal(wxT("indkey")) != srcIndexes.GetVal(wxT("indkey"))) + { + // better ignore index name and check column names here + needUpdate = destIndexes.GetVal(wxT("indname")) != srcIndexes.GetVal(wxT("indname")); + } + if (needUpdate) + { + wxString inddef = srcIndexes.GetVal(wxT("inddef")); + inddef.Replace(qtIdent(remoteCluster) + wxT("."), qtIdent(wxT("_") + cluster->GetName()) + wxT(".")); + sql += inddef + wxT(";\n"); + } + else + destIndexes.RowsLeft(); + } + } + + { + // check missing constraints + // we don't expect constraint definitions to change + + pgSetIterator srcConstraints(remoteConn, + wxT("SELECT t.relname, contype, conkey, conname,\n") + wxT(" pg_get_constraintdef(c.oid) AS condef\n") + wxT(" FROM pg_constraint c\n") + wxT(" JOIN pg_class t ON c.conrelid=t.oid\n") + wxT(" JOIN pg_namespace n ON n.oid=relnamespace\n") + wxT(" WHERE nspname = ") + qtDbString(remoteCluster) + wxT("\n") + wxT(" ORDER BY (contype != 'p'), relname, contype, conname, conkey") + ); + + pgSetIterator destConstraints(connection, + wxT("SELECT t.relname, contype, conkey, conname\n") + wxT(" FROM pg_constraint c\n") + wxT(" JOIN pg_class t ON c.conrelid=t.oid\n") + wxT(" JOIN pg_namespace n ON n.oid=relnamespace\n") + wxT(" WHERE nspname = ") + qtDbString(wxT("_") + cluster->GetName()) + wxT("\n") + wxT(" ORDER BY (contype != 'p'), relname, contype, conname, conkey") + ); + + if (!destConstraints.RowsLeft()) + return wxT("error"); + + while (srcConstraints.RowsLeft()) + { + wxString table = srcConstraints.GetVal(wxT("relname")); + wxString contype = srcConstraints.GetVal(wxT("contype")); + + bool needUpdate = destConstraints.Set()->Eof() || + destConstraints.GetVal(wxT("relname")) != table || + destConstraints.GetVal(wxT("contype")) != contype; + if (!needUpdate && destConstraints.GetVal(wxT("conkey")) != srcConstraints.GetVal(wxT("conkey"))) + { + // better ignore constraint name and compare column names here + needUpdate = destConstraints.GetVal(wxT("conname")) != srcConstraints.GetVal(wxT("conname")); + } + if (needUpdate) + { + wxString condef = srcConstraints.GetVal(wxT("condef")); + condef.Replace(qtIdent(remoteCluster) + wxT("."), qtIdent(wxT("_") + cluster->GetName()) + wxT(".")); + + sql += wxT("ALTER TABLE ") + qtIdent(table) + + wxT(" ADD CONSTRAINT ") + qtIdent(srcConstraints.GetVal(wxT("conname"))) + + wxT(" ") + condef + + wxT(";\n"); + } + else + destConstraints.RowsLeft(); + } + + sql += wxT("\nNOTIFY ") + qtIdent(wxT("_") + cluster->GetName() + wxT("_Restart")) + + wxT(";\n\n"); + } + } + return sql; +} + + +pgObject *dlgRepClusterUpgrade::CreateObject(pgCollection *collection) +{ + return 0; +} + + +void dlgRepClusterUpgrade::OnChangeCluster(wxCommandEvent &ev) +{ + version = wxEmptyString; + sql = wxEmptyString; + + int sel = cbClusterName->GetCurrentSelection(); + if (remoteConn && sel >= 0) + { + wxString schemaPrefix = qtIdent(wxT("_") + cbClusterName->GetValue()) + wxT("."); + + version = remoteConn->ExecuteScalar(wxT("SELECT ") + schemaPrefix + wxT("slonyversion();")); + } + OnChange(ev); + + + txtVersion->SetValue(version); + OnChange(ev); +} diff --git a/slony/dlgRepListen.cpp b/slony/dlgRepListen.cpp new file mode 100644 index 0000000..3cb5993 --- /dev/null +++ b/slony/dlgRepListen.cpp @@ -0,0 +1,159 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepListen.cpp - PostgreSQL Slony-I Listen Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" + +#include "slony/dlgRepListen.h" +#include "slony/slCluster.h" +#include "slony/slNode.h" +#include "slony/slListen.h" +#include "schema/pgDatatype.h" + +// pointer to controls + +#define cbOrigin CTRL_COMBOBOX("cbOrigin") +#define txtReceiver CTRL_TEXT("txtReceiver") +#define cbProvider CTRL_COMBOBOX("cbProvider") + + + + +BEGIN_EVENT_TABLE(dlgRepListen, dlgProperty) + EVT_COMBOBOX(XRCID("cbOrigin"), dlgRepListen::OnChange) + EVT_COMBOBOX(XRCID("cbProvider"), dlgRepListen::OnChange) +END_EVENT_TABLE(); + + +dlgProperty *slListenFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgRepListen(this, frame, (slListen *)node, (slNode *)parent); +} + +dlgRepListen::dlgRepListen(pgaFactory *f, frmMain *frame, slListen *l, slNode *n) + : dlgRepProperty(f, frame, n->GetCluster(), wxT("dlgRepListen")) +{ + listen = l; + node = n; +} + + +pgObject *dlgRepListen::GetObject() +{ + return listen; +} + + +int dlgRepListen::Go(bool modal) +{ + txtReceiver->SetValue(IdAndName(node->GetSlId(), node->GetName())); + txtReceiver->Disable(); + + if (listen) + { + // edit mode + cbOrigin->Append(IdAndName(listen->GetSlId(), listen->GetName())); + cbOrigin->SetSelection(0); + cbProvider->Append(IdAndName(listen->GetProviderId(), listen->GetProviderName())); + cbProvider->SetSelection(0); + cbOrigin->Disable(); + cbProvider->Disable(); + } + else + { + // create mode + + pgSet *nodes = connection->ExecuteSet( + wxT("SELECT no_id, no_comment, pa_server\n") + wxT(" FROM ") + cluster->GetSchemaPrefix() + wxT("sl_node\n") + wxT(" LEFT JOIN ") + cluster->GetSchemaPrefix() + wxT("sl_path ON pa_server=no_id") + wxT(" AND pa_client=") + NumToStr(node->GetSlId()) + wxT("\n") + wxT(" WHERE no_id <> ") + NumToStr(node->GetSlId()) + wxT("\n") + wxT(" ORDER BY no_id") + ); + + if (nodes) + { + while (!nodes->Eof()) + { + long id = nodes->GetLong(wxT("no_id")); + wxString name = IdAndName(id, nodes->GetVal(wxT("no_comment"))); + + cbOrigin->Append(name, (void *)id); + + if (nodes->GetLong(wxT("pa_server")) > 0) + cbProvider->Append(name, (void *)id); + + nodes->MoveNext(); + } + delete nodes; + } + } + + return dlgProperty::Go(modal); +} + + +pgObject *dlgRepListen::CreateObject(pgCollection *collection) +{ + pgObject *obj = listenFactory.CreateObjects(collection, 0, + wxT(" WHERE li_origin = ") + NumToStr((OID)cbOrigin->wxItemContainer::GetClientData(cbOrigin->GetCurrentSelection())) + + wxT(" AND li_receiver = ") + NumToStr(node->GetSlId()) + + wxT(" AND li_provider = ") + NumToStr((OID)cbProvider->wxItemContainer::GetClientData(cbProvider->GetCurrentSelection())) + ); + + return obj; +} + + + + +void dlgRepListen::CheckChange() +{ + if (listen) + { + } + else + { + bool enable = true; + CheckValid(enable, cbProvider->GetCount() > 0, _("No path to any provider node; add proper path.")); + CheckValid(enable, cbOrigin->GetCurrentSelection() >= 0, _("Please select origin node of replication events.")); + CheckValid(enable, cbProvider->GetCurrentSelection() >= 0, _("Please select provider node for replication events.")); + + EnableOK(enable); + } +} + + + +wxString dlgRepListen::GetSql() +{ + wxString sql; + + if (listen) + { + // edit mode + } + else + { + // create mode + + sql = wxT("SELECT ") + cluster->GetSchemaPrefix() + wxT("storelisten(") + + NumToStr((OID)cbOrigin->wxItemContainer::GetClientData(cbOrigin->GetCurrentSelection())) + wxT(", ") + + NumToStr((OID)cbProvider->wxItemContainer::GetClientData(cbProvider->GetCurrentSelection())) + wxT(", ") + + NumToStr(node->GetSlId()) + wxT(");"); + } + + return sql; +} diff --git a/slony/dlgRepNode.cpp b/slony/dlgRepNode.cpp new file mode 100644 index 0000000..57aacee --- /dev/null +++ b/slony/dlgRepNode.cpp @@ -0,0 +1,122 @@ +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepNode.cpp - PostgreSQL Slony-I Node Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" + + +#include "slony/dlgRepNode.h" +#include "slony/slCluster.h" +#include "slony/slNode.h" + + +// pointer to controls +#define txtID CTRL_TEXT("txtID") + + + +BEGIN_EVENT_TABLE(dlgRepNode, dlgProperty) +END_EVENT_TABLE(); + + +dlgProperty *slNodeFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgRepNode(this, frame, (slNode *)node, (slCluster *)parent); +} + +dlgRepNode::dlgRepNode(pgaFactory *f, frmMain *frame, slNode *s, slCluster *c) + : dlgRepProperty(f, frame, c, wxT("dlgRepNode")) +{ + node = s; +} + + +pgObject *dlgRepNode::GetObject() +{ + return node; +} + + +int dlgRepNode::Go(bool modal) +{ + txtID->SetValidator(numericValidator); + + if (node) + { + // edit mode + txtID->SetValue(NumToStr(node->GetSlId())); + txtID->Disable(); + } + else + { + // create mode + EnableOK(true); + } + + return dlgProperty::Go(modal); +} + + +pgObject *dlgRepNode::CreateObject(pgCollection *collection) +{ + wxString restriction; + if (StrToLong(txtID->GetValue()) > 0) + restriction = txtID->GetValue(); + else + restriction = wxT("(SELECT MAX(no_id) FROM ") + cluster->GetSchemaPrefix() + wxT("sl_node)"); + + pgObject *obj = nodeFactory.CreateObjects(collection, 0, + wxT(" WHERE no_id = ") + restriction); + + return obj; +} + + +void dlgRepNode::CheckChange() +{ + if (node) + { + EnableOK(txtComment->GetValue() != node->GetComment()); + } + else + { + bool enable = true; + + EnableOK(enable); + } +} + + + +wxString dlgRepNode::GetSql() +{ + wxString sql; + + sql = wxT("-- Create replication node\n\n") + wxT("SELECT ") + cluster->GetSchemaPrefix() + wxT("storenode("); + + if (StrToLong(txtID->GetValue()) > 0) + sql += txtID->GetValue(); + else + sql += wxT("(SELECT COALESCE(MAX(no_id), 0) + 1 FROM ") + + cluster->GetSchemaPrefix() + wxT("sl_node)"); + + sql += wxT(", ") + qtDbString(txtComment->GetValue()); + + // The spool parameter was removed for Slony 2.0 + if (!cluster->ClusterMinimumVersion(2, 0)) + sql += wxT(", false"); + + sql += wxT(");\n"); + + return sql; +} diff --git a/slony/dlgRepPath.cpp b/slony/dlgRepPath.cpp new file mode 100644 index 0000000..dc10acd --- /dev/null +++ b/slony/dlgRepPath.cpp @@ -0,0 +1,154 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepPath.cpp - PostgreSQL Slony-I Path Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" + +#include "slony/dlgRepPath.h" +#include "slony/slCluster.h" +#include "slony/slNode.h" +#include "slony/slPath.h" +#include "schema/pgDatatype.h" + + +// pointer to controls +#define cbServer CTRL_COMBOBOX("cbServer") +#define txtConnInfo CTRL_TEXT("txtConnInfo") +#define txtConnRetry CTRL_TEXT("txtConnRetry") + + +BEGIN_EVENT_TABLE(dlgRepPath, dlgProperty) + EVT_TEXT(XRCID("txtConnInfo"), dlgRepPath::OnChange) + EVT_COMBOBOX(XRCID("cbServer"), dlgRepPath::OnChange) +END_EVENT_TABLE(); + +dlgProperty *slPathFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgRepPath(this, frame, (slPath *)node, (slNode *)parent); +} + + +dlgRepPath::dlgRepPath(pgaFactory *f, frmMain *frame, slPath *p, slNode *n) + : dlgRepProperty(f, frame, n->GetCluster(), wxT("dlgRepPath")) +{ + path = p; + node = n; +} + + +pgObject *dlgRepPath::GetObject() +{ + return path; +} + + +int dlgRepPath::Go(bool modal) +{ + + if (path) + { + // edit mode + cbServer->Append(IdAndName(path->GetSlId(), path->GetName()), (void *)path->GetSlId()); + cbServer->SetSelection(0); + cbServer->Disable(); + + txtConnInfo->SetValue(path->GetConnInfo()); + txtConnRetry->SetValue(NumToStr(path->GetConnRetry())); + } + else + { + // create mode + + txtConnRetry->SetValue(wxT("10")); + + pgSet *nodes = connection->ExecuteSet( + wxT("SELECT no_id, no_comment\n") + wxT(" FROM ") + cluster->GetSchemaPrefix() + wxT("sl_node\n") + wxT(" LEFT JOIN ") + cluster->GetSchemaPrefix() + wxT("sl_path ON pa_client=\n") + NumToStr(node->GetSlId()) + + wxT(" AND pa_server=no_id\n") + wxT(" WHERE no_active AND pa_client IS NULL\n") + wxT(" AND no_id <> ") + NumToStr(node->GetSlId()) + wxT("\n") + wxT(" ORDER BY no_id") + ); + + if (nodes) + { + while (!nodes->Eof()) + { + cbServer->Append(IdAndName(nodes->GetLong(wxT("no_id")), nodes->GetVal(wxT("no_comment"))), + (void *)nodes->GetLong(wxT("no_id"))); + nodes->MoveNext(); + } + delete nodes; + } + if (cbServer->GetCount() > 0) + cbServer->SetSelection(0); + } + + return dlgProperty::Go(modal); +} + + +pgObject *dlgRepPath::CreateObject(pgCollection *collection) +{ + pgObject *obj = pathFactory.CreateObjects(collection, 0, + wxT(" WHERE pa_server = ") + NumToStr((OID)cbServer->wxItemContainer::GetClientData(cbServer->GetCurrentSelection())) + + wxT(" AND pa_client = ") + NumToStr(node->GetSlId())); + + return obj; +} + + + + +void dlgRepPath::CheckChange() +{ + if (path) + { + EnableOK(txtConnInfo->GetValue() != path->GetConnInfo() + || StrToLong(txtConnRetry->GetValue()) != path->GetConnRetry()); + } + else + { + bool enable = true; + CheckValid(enable, cbServer->GetCount() > 0, _("No provider node without path definition left.")); + CheckValid(enable, cbServer->GetCurrentSelection() >= 0, _("Please select provider node.")); + + wxString connInfo = txtConnInfo->GetValue(); + CheckValid(enable, connInfo.Find(wxT("host=")) >= 0, _("Please provide host in connect info.")); + CheckValid(enable, connInfo.Find(wxT("dbname=")) >= 0, _("Please provide dbname in connect info.")); + CheckValid(enable, connInfo.Find(wxT("user=")) >= 0, _("Please provide user in connect info.")); + + EnableOK(enable); + } +} + + + +wxString dlgRepPath::GetSql() +{ + wxString sql; + + int sel = cbServer->GetCurrentSelection(); + + if (sel >= 0) + { + sql = wxT("SELECT ") + cluster->GetSchemaPrefix() + wxT("storepath(") + + NumToStr((OID)cbServer->wxItemContainer::GetClientData(sel)) + wxT(", ") + + NumToStr(node->GetSlId()) + wxT(", ") + + qtDbString(txtConnInfo->GetValue()) + wxT(", ") + + NumToStr(StrToLong(txtConnRetry->GetValue())) + wxT(");"); + } + return sql; +} diff --git a/slony/dlgRepProperty.cpp b/slony/dlgRepProperty.cpp new file mode 100644 index 0000000..d589fcf --- /dev/null +++ b/slony/dlgRepProperty.cpp @@ -0,0 +1,25 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepProperty.cpp - PostgreSQL Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "slony/dlgRepProperty.h" +#include "slony/slCluster.h" + + +dlgRepProperty::dlgRepProperty(pgaFactory *f, frmMain *frame, slCluster *c, const wxString &resName) + : dlgProperty(f, frame, resName) +{ + cluster = c; +} diff --git a/slony/dlgRepSequence.cpp b/slony/dlgRepSequence.cpp new file mode 100644 index 0000000..33e2e91 --- /dev/null +++ b/slony/dlgRepSequence.cpp @@ -0,0 +1,166 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepSequence.cpp - PostgreSQL Slony-I Sequence Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" + +#include "slony/dlgRepSequence.h" +#include "slony/slCluster.h" +#include "slony/slSet.h" +#include "slony/slSequence.h" +#include "schema/pgDatatype.h" + + +// pointer to controls +#define txtID CTRL_TEXT("txtID") +#define cbSequence CTRL_COMBOBOX2("cbSequence") + + + +BEGIN_EVENT_TABLE(dlgRepSequence, dlgProperty) + EVT_TEXT(XRCID("txtID"), dlgRepSequence::OnChange) + EVT_TEXT(XRCID("cbSequence"), dlgRepSequence::OnChange) + EVT_COMBOBOX(XRCID("cbSequence"), dlgRepSequence::OnChangeSel) + EVT_TEXT(XRCID("cbSequence"), dlgRepSequence::OnChange) +END_EVENT_TABLE(); + +dlgProperty *slSlSequenceFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgRepSequence(this, frame, (slSequence *)node, (slSet *)parent); +} + + +dlgRepSequence::dlgRepSequence(pgaFactory *f, frmMain *frame, slSequence *node, slSet *s) + : dlgRepProperty(f, frame, s->GetCluster(), wxT("dlgRepSequence")) +{ + sequence = node; + set = s; +} + + +pgObject *dlgRepSequence::GetObject() +{ + return sequence; +} + + +int dlgRepSequence::Go(bool modal) +{ + txtID->SetValidator(numericValidator); + + if (sequence) + { + // edit mode + cbSequence->Append(sequence->GetName()); + cbSequence->SetSelection(0); + + txtID->SetValue(NumToStr(sequence->GetSlId())); + + cbSequence->Disable(); + txtComment->Disable(); + txtID->Disable(); + } + else + { + // create mode + + wxString restriction; + if (!settings->GetShowSystemObjects()) + restriction = wxT("\n AND ") + connection->SystemNamespaceRestriction(wxT("nspname")); + + pgSet *tabs = connection->ExecuteSet( + wxT("SELECT DISTINCT cl.oid, nspname, relname\n") + wxT(" FROM pg_class cl\n") + wxT(" JOIN pg_namespace nsp ON relnamespace=nsp.oid\n") + wxT(" LEFT JOIN ") + cluster->GetSchemaPrefix() + wxT("sl_sequence s ON s.seq_reloid=cl.oid\n") + wxT(" WHERE s.seq_id IS NULL AND cl.relkind = 'S'") + restriction + wxT("\n") + wxT(" ORDER BY nspname, relname") + ); + + if (tabs) + { + while (!tabs->Eof()) + { + cbSequence->Append(tabs->GetVal(wxT("nspname")) + wxT(".") + tabs->GetVal(wxT("relname")), + (void *)tabs->GetOid(wxT("oid"))); + tabs->MoveNext(); + } + delete tabs; + } + } + + return dlgProperty::Go(modal); +} + + +pgObject *dlgRepSequence::CreateObject(pgCollection *collection) +{ + pgObject *obj = slSequenceFactory.CreateObjects(collection, 0, + wxT(" WHERE seq_reloid = ") + NumToStr((OID)cbSequence->wxItemContainer::GetClientData(cbSequence->GetGuessedSelection()))); + + return obj; +} + + +void dlgRepSequence::OnChangeSel(wxCommandEvent &ev) +{ + cbSequence->GuessSelection(ev); + OnChange(ev); +} + + +void dlgRepSequence::CheckChange() +{ + if (sequence) + { + EnableOK(txtComment->GetValue() != sequence->GetComment()); + } + else + { + bool enable = true; + CheckValid(enable, cbSequence->GetGuessedSelection() >= 0, _("Please select sequence to replicate.")); + + EnableOK(enable); + } +} + + + +wxString dlgRepSequence::GetSql() +{ + wxString sql; + + if (sequence) + { + // edit mode + } + else + { + // create mode + + sql = wxT("SELECT ") + cluster->GetSchemaPrefix() + wxT("setaddsequence(") + + NumToStr(set->GetSlId()) + wxT(", "); + + if (StrToLong(txtID->GetValue()) > 0) + sql += txtID->GetValue(); + else + sql += wxT("(SELECT COALESCE(MAX(seq_id), 0) + 1 FROM ") + cluster->GetSchemaPrefix() + wxT("sl_sequence)"); + + sql += wxT(", ") + qtDbString(cbSequence->GetGuessedStringSelection()) + + wxT(", ") + qtDbString(txtComment->GetValue()) + + wxT(")\n"); + } + + return sql; +} diff --git a/slony/dlgRepSet.cpp b/slony/dlgRepSet.cpp new file mode 100644 index 0000000..db3491c --- /dev/null +++ b/slony/dlgRepSet.cpp @@ -0,0 +1,332 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepSet.cpp - PostgreSQL Slony-I Set Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" + +#include "slony/dlgRepSet.h" +#include "slony/slCluster.h" +#include "slony/slNode.h" +#include "slony/slSet.h" +#include "frm/frmMain.h" + + +// pointer to controls +#define txtOrigin CTRL_TEXT("txtOrigin") +#define txtID CTRL_TEXT("txtID") + + + +BEGIN_EVENT_TABLE(dlgRepSet, dlgProperty) +END_EVENT_TABLE(); + + +dlgProperty *slSetFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgRepSet(this, frame, (slSet *)node, (slCluster *)parent); +} + +dlgRepSet::dlgRepSet(pgaFactory *f, frmMain *frame, slSet *s, slCluster *c) + : dlgRepProperty(f, frame, c, wxT("dlgRepSet")) +{ + set = s; +} + + +int dlgRepSet::Go(bool modal) +{ + txtID->SetValidator(numericValidator); + + if (set) + { + // edit mode + txtID->SetValue(NumToStr(set->GetSlId())); + txtID->Disable(); + txtOrigin->SetValue(IdAndName(set->GetOriginId(), set->GetOriginNode())); + txtComment->Disable(); + } + else + { + // create mode + txtOrigin->SetValue(IdAndName(cluster->GetLocalNodeID(), cluster->GetLocalNodeName())); + EnableOK(true); + } + + txtOrigin->Disable(); + + return dlgProperty::Go(modal); +} + + +pgObject *dlgRepSet::CreateObject(pgCollection *collection) +{ + wxString restriction; + if (StrToLong(txtID->GetValue()) > 0) + restriction = txtID->GetValue(); + else + restriction = wxT("(SELECT MAX(set_id) FROM ") + cluster->GetSchemaPrefix() + wxT("sl_set)"); + + pgObject *obj = setFactory.CreateObjects(collection, 0, + wxT(" WHERE set_id = ") + restriction); + + return obj; +} + + +void dlgRepSet::CheckChange() +{ + if (set) + { + EnableOK(txtComment->GetValue() != set->GetComment()); + } + else + { + bool enable = (!txtComment->IsEmpty()); + + EnableOK(enable); + } +} + + + +wxString dlgRepSet::GetSql() +{ + wxString sql; + + sql = wxT("-- Create replication set\n\n") + wxT("SELECT ") + cluster->GetSchemaPrefix() + wxT("storeset("); + + if (StrToLong(txtID->GetValue()) > 0) + sql += txtID->GetValue(); + else + sql += wxT("(SELECT COALESCE(MAX(set_id), 0) + 1 FROM ") + + cluster->GetSchemaPrefix() + wxT("sl_set)"); + + sql += wxT(", ") + qtDbString(txtComment->GetValue()) + + wxT(");\n"); + + return sql; +} + + +//////////////////////////////////////////////////////////////////////////////////////// + + +#define cbTargetID CTRL_COMBOBOX("cbTargetID") + +BEGIN_EVENT_TABLE(dlgRepSetMerge, dlgProperty) + EVT_COMBOBOX(XRCID("cbTargetID"), dlgRepSetMerge::OnChange) +END_EVENT_TABLE(); + + +dlgRepSetMerge::dlgRepSetMerge(pgaFactory *f, frmMain *frame, slSet *s) + : dlgRepProperty(f, frame, s->GetCluster(), wxT("dlgRepSetMerge")) +{ + set = s; +} + + +int dlgRepSetMerge::Go(bool modal) +{ + txtID->SetValue(IdAndName(set->GetSlId(), set->GetName())); + txtID->Disable(); + + wxString sql = + wxT("SELECT set_id, set_comment\n") + wxT(" FROM ") + cluster->GetSchemaPrefix() + wxT("sl_set\n") + wxT(" LEFT JOIN ") + cluster->GetSchemaPrefix() + wxT("sl_subscribe ON set_id=sub_set\n") + wxT(" WHERE set_origin = ") + NumToStr(cluster->GetLocalNodeID()) + + wxT(" AND set_id <> ") + NumToStr(set->GetSlId()); + + if (set->GetSubscriptionCount() > 0) + sql += wxT("\n") + wxT(" GROUP BY set_id, set_comment\n") + wxT("HAVING COUNT(sub_set) > 0"); + else + sql += wxT("\n") + wxT(" AND sub_set IS NULL"); + + pgSet *sets = connection->ExecuteSet(sql); + + if (sets) + { + while (!sets->Eof()) + { + long id = sets->GetLong(wxT("set_id")); + cbTargetID->Append(IdAndName(id, sets->GetVal(wxT("set_comment"))), (void *)id); + sets->MoveNext(); + } + delete sets; + } + + return dlgProperty::Go(modal); +} + + +void dlgRepSetMerge::CheckChange() +{ + bool enable = true; + + CheckValid(enable, cbTargetID->GetCount() > 0 , _("No set available to merge to.")); + CheckValid(enable, cbTargetID->GetCurrentSelection() >= 0, _("Please select replication set to merged to.")); + EnableOK(enable); +} + + +wxString dlgRepSetMerge::GetSql() +{ + wxString sql; + wxString addId = NumToStr(set->GetSlId()); + wxString toId = NumToStr((long)cbTargetID->wxItemContainer::GetClientData(cbTargetID->GetCurrentSelection())); + wxString prefix = cluster->GetSchemaPrefix(); + + if (set->GetSubscriptionCount() > 0) + { + sql = wxT("SELECT ") + cluster->GetSchemaPrefix() + wxT("mergeset(") + toId + wxT(", ") + addId + wxT(");\n"); + } + else + { + sql = wxT("-- remember objects to replicate\n") + wxT("CREATE TEMPORARY TABLE pga_tmp_repl_tables(tab_id int4, tabname text, idxname text, comment text, trgname text);\n") + wxT("INSERT INTO pga_tmp_repl_tables(tab_id, tabname, idxname, comment, trgname)\n"); + + if (cluster->ClusterMinimumVersion(2, 0)) + { + sql += wxT("SELECT tab_id, nsp.nspname || '.' || relname, tab_idxname, tab_comment, tgname\n") + wxT(" FROM ") + prefix + wxT("sl_table\n") + wxT(" JOIN pg_class cl ON cl.oid=tab_reloid\n") + wxT(" JOIN pg_namespace nsp ON nsp.oid=relnamespace\n") + wxT(" LEFT JOIN pg_trigger t ON t.tgrelid = tab_reloid\n") + wxT(" JOIN pg_proc p ON t.tgfoid = p.oid\n") + wxT(" JOIN pg_namespace np ON p.pronamespace = np.oid\n") + wxT(" WHERE tab_set = ") + addId + + wxT(" AND np.nspname = ") + qtDbString(wxT("_") + cluster->GetName()) + wxT(";\n"); + } + else + { + sql += wxT("SELECT tab_id, nspname || '.' || relname, tab_idxname, tab_comment, trig_tgname\n") + wxT(" FROM ") + prefix + wxT("sl_table\n") + wxT(" JOIN pg_class cl ON cl.oid=tab_reloid\n") + wxT(" JOIN pg_namespace nsp ON nsp.oid=relnamespace\n") + wxT(" LEFT JOIN ") + prefix + wxT("sl_trigger ON tab_id=trig_tabid") + wxT(" WHERE tab_set = ") + addId + wxT(";\n"); + } + + sql += wxT("\n") + wxT("CREATE TEMPORARY TABLE pga_tmp_repl_seqs(seq_id int4, seqname text, comment text);\n") + wxT("INSERT INTO pga_tmp_repl_seqs(seq_id, seqname, comment)\n") + wxT("SELECT seq_id, nspname ||'.' || relname, seq_comment\n") + wxT(" FROM ") + prefix + wxT("sl_sequence\n") + wxT(" JOIN pg_class cl ON cl.oid=seq_reloid\n") + wxT(" JOIN pg_namespace nsp ON nsp.oid=relnamespace\n") + wxT(" WHERE seq_set = ") + addId + wxT(";\n") + wxT("\n") + + wxT("-- drop objects in old set: tables, sequences\n") + wxT("SELECT ") + prefix + wxT("setdroptable(tab_id)\n") + wxT(" FROM (SELECT DISTINCT tab_id FROM pga_tmp_repl_tables) AS tmp;\n") + wxT("\n") + wxT("SELECT ") + prefix + wxT("setdropsequence(seq_id)\n") + wxT(" FROM pga_tmp_repl_seqs;\n") + wxT("\n") + + wxT("-- add objects to new set: tables, triggers, sequences\n") + wxT("SELECT ") + prefix + wxT("setaddtable(") + toId + wxT(", tab_id, tabname, idxname, comment)\n") + wxT(" FROM (SELECT DISTINCT tab_id, tabname, idxname, comment FROM pga_tmp_repl_tables) AS tmp;\n") + wxT("\n"); + + if (!cluster->ClusterMinimumVersion(2, 0)) + { + sql += wxT("SELECT ") + prefix + wxT("storetrigger(tab_id, trgname)\n") + wxT(" FROM pga_tmp_repl_tables WHERE trgname IS NOT NULL;\n") + wxT("\n"); + } + + sql += wxT("SELECT ") + prefix + wxT("setaddsequence(") + toId + wxT(", seq_id, seqname, comment)\n") + wxT(" FROM pga_tmp_repl_seqs;\n") + wxT("\n") + + wxT("-- finally, drop old set\n") + wxT("SELECT ") + prefix + wxT("dropset(") + addId + wxT(");\n") + wxT("\n") + wxT("-- cleanup\n") + wxT("DROP TABLE pga_tmp_repl_tables;\n") + wxT("DROP TABLE pga_tmp_repl_seqs;\n"); + } + + return sql; +} + + +//////////////////////////////////////////////////////////////////////////////////////// + + +#define cbTargetNode CTRL_COMBOBOX("cbTargetNode") + +BEGIN_EVENT_TABLE(dlgRepSetMove, dlgProperty) + EVT_COMBOBOX(XRCID("cbTargetNode"), dlgRepSetMove::OnChange) +END_EVENT_TABLE(); + + +dlgRepSetMove::dlgRepSetMove(pgaFactory *f, frmMain *frame, slSet *s) + : dlgRepProperty(f, frame, s->GetCluster(), wxT("dlgRepSetMove")) +{ + set = s; +} + + +int dlgRepSetMove::Go(bool modal) +{ + txtID->SetValue(IdAndName(set->GetSlId(), set->GetName())); + txtID->Disable(); + + pgSet *nodes = connection->ExecuteSet( + wxT("SELECT no_id, no_comment\n") + wxT(" FROM ") + cluster->GetSchemaPrefix() + wxT("sl_node\n") + wxT(" JOIN ") + cluster->GetSchemaPrefix() + wxT("sl_subscribe ON sub_receiver=no_id\n") + wxT(" WHERE sub_set = ") + NumToStr(set->GetSlId())); + + if (nodes) + { + while (!nodes->Eof()) + { + long id = nodes->GetLong(wxT("no_id")); + cbTargetNode->Append(IdAndName(id, nodes->GetVal(wxT("no_comment"))), (void *)id); + nodes->MoveNext(); + } + delete nodes; + } + return dlgProperty::Go(modal); +} + + +void dlgRepSetMove::CheckChange() +{ + bool enable = true; + + CheckValid(enable, cbTargetNode->GetCount() > 0 , _("No node available to move this set to.")); + CheckValid(enable, cbTargetNode->GetCurrentSelection() >= 0, _("Please select node to move this replication set to.")); + EnableOK(enable); +} + + +wxString dlgRepSetMove::GetSql() +{ + wxString toId = NumToStr((long)cbTargetNode->wxItemContainer::GetClientData(cbTargetNode->GetCurrentSelection())); + + wxString sql = + wxT("SELECT ") + cluster->GetSchemaPrefix() + wxT("moveset(") + + NumToStr(set->GetSlId()) + wxT(", ") + toId + wxT(");\n"); + return sql; +} diff --git a/slony/dlgRepSubscription.cpp b/slony/dlgRepSubscription.cpp new file mode 100644 index 0000000..99b7a84 --- /dev/null +++ b/slony/dlgRepSubscription.cpp @@ -0,0 +1,182 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepSubscription.cpp - PostgreSQL Slony-I Subscription Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" + +#include "slony/dlgRepSubscription.h" +#include "slony/slCluster.h" +#include "slony/slSubscription.h" +#include "slony/slSet.h" + + + +// pointer to controls +#define txtOrigin CTRL_TEXT("txtOrigin") +#define stReceiver CTRL_STATIC("stReceiver") +#define txtReceiver CTRL_TEXT("txtReceiver") +#define cbProvider CTRL_COMBOBOX("cbProvider") +#define stProvider CTRL_TEXT("stProvider") +#define chkForward CTRL_CHECKBOX("chkForward") + + + +BEGIN_EVENT_TABLE(dlgRepSubscription, dlgProperty) + EVT_COMBOBOX(XRCID("cbProvider"), dlgRepSubscription::OnChange) + EVT_CHECKBOX(XRCID("chkForward"), dlgRepSubscription::OnChange) +END_EVENT_TABLE(); + + +dlgProperty *slSubscriptionFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgRepSubscription(this, frame, (slSubscription *)node, (slSet *)parent); +} + +dlgRepSubscription::dlgRepSubscription(pgaFactory *f, frmMain *frame, slSubscription *sub, slSet *s) + : dlgRepProperty(f, frame, s->GetCluster(), wxT("dlgRepSubscription")) +{ + subscription = sub; + set = s; +} + + +pgObject *dlgRepSubscription::GetObject() +{ + return subscription; +} + + +int dlgRepSubscription::Go(bool modal) +{ + txtOrigin->SetValue(NumToStr(set->GetOriginId())); + if (subscription) + { + // edit mode + chkForward->SetValue(subscription->GetForward()); + txtReceiver->SetValue(IdAndName(subscription->GetReceiverId(), subscription->GetReceiverNode())); + } + else + { + // create mode + txtReceiver->SetValue(IdAndName(cluster->GetLocalNodeID(), cluster->GetLocalNodeName())); + + if (cluster->ClusterMinimumVersion(1, 1)) + { + // This is very ugly: starting with Slony-I 1.1, this must be called on the provider, + // not on the receiver. + stProvider->SetLabel(_("Receiver")); + stReceiver->SetLabel(_("Provider")); + } + } + + if (set->GetOriginId() == cluster->GetLocalNodeID() && subscription) + { + chkForward->SetValue(subscription->GetForward()); + cbProvider->Append(IdAndName(subscription->GetProviderId(), subscription->GetProviderNode())); + cbProvider->SetSelection(0); + cbProvider->Disable(); + chkForward->Disable(); + EnableOK(false); + } + else + { + pgSet *sets = connection->ExecuteSet( + wxT("SELECT no_id, no_comment\n") + wxT(" FROM ") + cluster->GetSchemaPrefix() + wxT("sl_node\n") + wxT(" WHERE no_active AND no_id <> ") + NumToStr(cluster->GetLocalNodeID())); + + if (sets) + { + while (!sets->Eof()) + { + cbProvider->Append(IdAndName(sets->GetLong(wxT("no_id")), sets->GetVal(wxT("no_comment"))), + (void *)sets->GetLong(wxT("no_id"))); + + if (subscription && sets->GetLong(wxT("no_id")) == subscription->GetProviderId()) + cbProvider->SetSelection(cbProvider->GetCount() - 1); + sets->MoveNext(); + } + delete sets; + } + } + if (!subscription && cbProvider->GetCount()) + { + cbProvider->SetSelection(0); + EnableOK(true); + } + return dlgProperty::Go(modal); +} + + +pgObject *dlgRepSubscription::CreateObject(pgCollection *collection) +{ + pgObject *obj = subscriptionFactory.CreateObjects(collection, 0, + wxT(" WHERE set_id = ") + NumToStr(set->GetSlId()) + + wxT(" AND sub_receiver = ") + NumToStr(cluster->GetLocalNodeID())); + + return obj; +} + + +void dlgRepSubscription::CheckChange() +{ + if (subscription) + { + int sel = cbProvider->GetCurrentSelection(); + + EnableOK(sel >= 0 && (chkForward->GetValue() != subscription->GetForward() + || (long)cbProvider->wxItemContainer::GetClientData(sel) != subscription->GetProviderId())); + } + else + { + bool enable = true; + + EnableOK(enable); + } +} + + + +wxString dlgRepSubscription::GetSql() +{ + wxString sql; + + sql = wxT("SELECT ") + cluster->GetSchemaPrefix() + wxT("subscribeset(") + + NumToStr(set->GetSlId()) + wxT(", "); + + if (cluster && cluster->ClusterMinimumVersion(1, 1)) + { + // Actually, provider and receiver are exchanged here. + sql += NumToStr(cluster->GetLocalNodeID()) + wxT(", ") + + NumToStr((long)cbProvider->wxItemContainer::GetClientData(cbProvider->GetCurrentSelection())); + } + else + { + sql += NumToStr((long)cbProvider->wxItemContainer::GetClientData(cbProvider->GetCurrentSelection())) + wxT(", ") + + NumToStr(cluster->GetLocalNodeID()); + } + sql += wxT(", ") + + BoolToStr(chkForward->GetValue()); + + // Omit copy? + if (cluster && cluster->ClusterMinimumVersion(2, 0) && + cluster->GetClusterVersion() != wxT("2.0.0") && + cluster->GetClusterVersion() != wxT("2.0.1") && + cluster->GetClusterVersion() != wxT("2.0.2")) + sql += wxT(", false"); + + sql += wxT(");"); + + return sql; +} diff --git a/slony/dlgRepTable.cpp b/slony/dlgRepTable.cpp new file mode 100644 index 0000000..e0b1a1d --- /dev/null +++ b/slony/dlgRepTable.cpp @@ -0,0 +1,317 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepTable.cpp - PostgreSQL Slony-I Table Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" + +#include "slony/dlgRepTable.h" +#include "slony/slCluster.h" +#include "slony/slSet.h" +#include "slony/slTable.h" +#include "schema/pgDatatype.h" + + +// pointer to controls +#define txtID CTRL_TEXT("txtID") +#define cbTable CTRL_COMBOBOX2("cbTable") +#define cbIndex CTRL_COMBOBOX("cbIndex") +#define chkTrigger CTRL_CHECKLISTBOX("chkTrigger") + + + +BEGIN_EVENT_TABLE(dlgRepTable, dlgRepProperty) + EVT_TEXT(XRCID("txtID"), dlgRepTable::OnChange) + EVT_COMBOBOX(XRCID("cbTable"), dlgRepTable::OnChangeTableSel) + EVT_TEXT(XRCID("cbTable"), dlgRepTable::OnChangeTable) + EVT_COMBOBOX(XRCID("cbIndex"), dlgRepTable::OnChange) + EVT_CHECKLISTBOX(XRCID("chkTrigger"), dlgRepTable::OnChange) +END_EVENT_TABLE(); + + +dlgProperty *slSlTableFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgRepTable(this, frame, (slTable *)node, (slSet *)parent); +} + + +dlgRepTable::dlgRepTable(pgaFactory *f, frmMain *frame, slTable *node, slSet *s) + : dlgRepProperty(f, frame, s->GetCluster(), wxT("dlgRepTable")) +{ + table = node; + set = s; +} + + +pgObject *dlgRepTable::GetObject() +{ + return table; +} + + +int dlgRepTable::Go(bool modal) +{ + txtID->SetValidator(numericValidator); + + if (table) + { + // edit mode + cbTable->Append(table->GetName(), (void *)0); + cbTable->SetSelection(0); + cbIndex->Append(table->GetIndexName()); + cbIndex->SetSelection(0); + + txtID->SetValue(NumToStr(table->GetSlId())); + + cbTable->Disable(); + cbIndex->Disable(); + txtComment->Disable(); + txtID->Disable(); + + LoadTrigger(table->GetOid()); + + size_t i; + for (i = 0 ; i < table->GetTriggers().GetCount() ; i++) + { + int sel = chkTrigger->FindString(table->GetTriggers()[i]); + if (sel >= 0) + chkTrigger->Check(sel); + } + } + else + { + // create mode + + wxString restriction; + if (!settings->GetShowSystemObjects()) + restriction = wxT("\n AND ") + connection->SystemNamespaceRestriction(wxT("nspname")); + + pgSet *tabs = connection->ExecuteSet( + wxT("SELECT DISTINCT cl.oid, nspname, relname\n") + wxT(" FROM pg_class cl\n") + wxT(" JOIN pg_namespace nsp ON relnamespace=nsp.oid\n") + wxT(" JOIN pg_index on indrelid=cl.oid AND indisunique\n") + wxT(" LEFT JOIN ") + cluster->GetSchemaPrefix() + wxT("sl_table t ON t.tab_reloid=cl.oid\n") + wxT(" WHERE t.tab_id IS NULL AND cl.relkind = 'r'") + restriction + wxT("\n") + wxT(" ORDER BY nspname, relname") + ); + + if (tabs) + { + while (!tabs->Eof()) + { + cbTable->Append(tabs->GetVal(wxT("nspname")) + wxT(".") + tabs->GetVal(wxT("relname")), (void *)tabs->GetOid(wxT("oid"))); + tabs->MoveNext(); + } + delete tabs; + } + } + + return dlgProperty::Go(modal); +} + + +pgObject *dlgRepTable::CreateObject(pgCollection *collection) +{ + pgObject *obj = slTableFactory.CreateObjects(collection, 0, + wxT(" WHERE tab_reloid = ") + NumToStr((OID)cbTable->wxItemContainer::GetClientData(cbTable->GetGuessedSelection()))); + + return obj; +} + + + +void dlgRepTable::OnChangeTableSel(wxCommandEvent &ev) +{ + cbTable->GuessSelection(ev); + OnChangeTable(ev); +} + + +void dlgRepTable::OnChangeTable(wxCommandEvent &ev) +{ + int sel = cbTable->GetGuessedSelection(); + + cbIndex->Clear(); + chkTrigger->Clear(); + + if (sel >= 0) + { + OID relid = (OID)cbTable->wxItemContainer::GetClientData(sel); + + pgSet *idx = connection->ExecuteSet( + wxT("SELECT relname\n") + wxT(" FROM pg_index JOIN pg_class cl ON cl.oid=indexrelid\n") + wxT(" WHERE indrelid=") + NumToStr(relid) + wxT("\n") + wxT(" ORDER BY NOT indisprimary, relname") + ); + if (idx) + { + while (!idx->Eof()) + { + cbIndex->Append(idx->GetVal(wxT("relname"))); + idx->MoveNext(); + } + delete idx; + + cbIndex->SetSelection(0); + } + + LoadTrigger(relid); + } + + OnChange(ev); +} + + +void dlgRepTable::LoadTrigger(OID relid) +{ + wxString sql = wxT("SELECT tgname FROM pg_trigger\n") + wxT(" JOIN pg_proc pr ON pr.oid=tgfoid\n") + wxT(" JOIN pg_namespace ns ON ns.oid=pronamespace\n") + wxT(" WHERE tgrelid=") + NumToStr(relid); + if (connection->BackendMinimumVersion(8, 5)) + sql += wxT(" AND tgconstraint=0\n"); + else + sql += wxT(" AND NOT tgisconstraint\n"); + sql += wxT(" AND nspname <> ") + qtDbString(wxT("_") + set->GetCluster()->GetName()) + wxT("\n") + wxT(" ORDER BY tgname"); + + pgSet *trg = connection->ExecuteSet(sql); + + if (trg) + { + while (!trg->Eof()) + { + chkTrigger->Append(trg->GetVal(wxT("tgname"))); + trg->MoveNext(); + } + delete trg; + } +} + +void dlgRepTable::CheckChange() +{ + if (table) + { + bool tgChanged = false; + + unsigned int i; + int cnt = 0; + + for (i = 0 ; !tgChanged && i < chkTrigger->GetCount() ; i++) + { + if (chkTrigger->IsChecked(i)) + { + cnt++; + if (table->GetTriggers().Index(chkTrigger->GetString(i)) < 0) + tgChanged = true; + + } + } + + EnableOK(tgChanged + || (int)table->GetTriggers().GetCount() != cnt + || txtComment->GetValue() != table->GetComment()); + } + else + { + bool enable = true; + CheckValid(enable, cbTable->GetGuessedSelection() >= 0, _("Please select table to replicate.")); + CheckValid(enable, cbIndex->GetCurrentSelection() >= 0, _("Please select index.")); + + EnableOK(enable); + } +} + + + +wxString dlgRepTable::GetSql() +{ + wxString sql; + wxString id = txtID->GetValue();; + + wxArrayString newTriggers; + + unsigned int i; + for (i = 0 ; i < chkTrigger->GetCount() ; i++) + { + if (chkTrigger->IsChecked(i)) + newTriggers.Add(chkTrigger->GetString(i)); + } + + if (table) + { + // edit mode + + wxArrayString oldTriggers = table->GetTriggers(); + + i = oldTriggers.GetCount(); + while (i--) + { + int j = newTriggers.Index(oldTriggers[i]); + if (j >= 0) + { + newTriggers.RemoveAt(j); + oldTriggers.RemoveAt(i); + } + } + + // these triggers have been deleted + for (i = 0 ; i < (unsigned int)oldTriggers.GetCount() ; i++) + { + sql += wxT("SELECT ") + cluster->GetSchemaPrefix() + wxT("droptrigger(") + + id + wxT(", ") + + qtDbString(oldTriggers[i]) + wxT(");\n"); + } + } + else + { + // create mode + sql = wxT("SELECT ") + cluster->GetSchemaPrefix() + wxT("setaddtable(") + + NumToStr(set->GetSlId()) + wxT(", "); + + if (StrToLong(id) > 0) + { + sql += id; + } + else + { + sql += wxT("(SELECT COALESCE(MAX(tab_id), 0) + 1 FROM ") + cluster->GetSchemaPrefix() + wxT("sl_table)"); + + + id = wxT("(SELECT tab_id FROM ") + cluster->GetSchemaPrefix() + wxT("sl_table\n") + wxT(" JOIN pg_class cl ON cl.oid=tab_reloid\n") + wxT(" JOIN pg_namespace nsp ON nsp.oid=relnamespace\n") + wxT(" WHERE tab_set = ") + NumToStr(set->GetSlId()) + + wxT(" AND nspname ||'.' || relname = ") + qtDbString(cbTable->GetGuessedStringSelection()) + + wxT(")"); + + } + sql += wxT(", ") + qtDbString(cbTable->GetGuessedStringSelection()) + + wxT(", ") + qtDbString(cbIndex->GetStringSelection()) + + wxT(", ") + qtDbString(txtComment->GetValue()) + + wxT(");\n"); + } + + + // these triggers have been added + for (i = 0 ; i < (unsigned int)newTriggers.GetCount() ; i++) + { + sql += wxT("SELECT ") + cluster->GetSchemaPrefix() + wxT("storetrigger(") + + id + wxT(", ") + + qtDbString(newTriggers[i]) + wxT(");\n"); + } + + return sql; +} diff --git a/slony/module.mk b/slony/module.mk new file mode 100644 index 0000000..5aa65d4 --- /dev/null +++ b/slony/module.mk @@ -0,0 +1,34 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/slony/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + slony/dlgRepCluster.cpp \ + slony/dlgRepListen.cpp \ + slony/dlgRepNode.cpp \ + slony/dlgRepPath.cpp \ + slony/dlgRepProperty.cpp \ + slony/dlgRepSequence.cpp \ + slony/dlgRepSet.cpp \ + slony/dlgRepSubscription.cpp \ + slony/dlgRepTable.cpp \ + slony/slCluster.cpp \ + slony/slListen.cpp \ + slony/slNode.cpp \ + slony/slPath.cpp \ + slony/slSequence.cpp \ + slony/slSet.cpp \ + slony/slSubscription.cpp \ + slony/slTable.cpp + +EXTRA_DIST += \ + slony/module.mk + + diff --git a/slony/slCluster.cpp b/slony/slCluster.cpp new file mode 100644 index 0000000..10469bc --- /dev/null +++ b/slony/slCluster.cpp @@ -0,0 +1,613 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slCluster.cpp PostgreSQL Slony-I Cluster +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgObject.h" +#include "slony/dlgRepCluster.h" +#include "slony/slCluster.h" +#include "slony/slNode.h" +#include "slony/slSet.h" +#include "frm/frmMain.h" + +#include + + +class RemoteConn +{ +public: + RemoteConn(long id, const wxString str, pgConn *c) + { + connInfo = str; + nodeID = id; + conn = c; + } + ~RemoteConn() + { + if (conn) delete conn; + } + + wxString connInfo; + pgConn *conn; + long nodeID; +}; + + +WX_DEFINE_OBJARRAY(RemoteConnArray); + +slCluster::slCluster(const wxString &newName) + : pgDatabaseObject(slClusterFactory, newName) +{ + localNode = 0; +} + +wxMenu *slCluster::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + +// if (GetCreatePrivilege()) + { + setFactory.AppendMenu(menu); + nodeFactory.AppendMenu(menu); + } + return menu; +} + + +bool slCluster::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return GetDatabase()->ExecuteVoid( + wxT("SELECT ") + GetSchemaPrefix() + wxT("uninstallnode();\n") + wxT("DROP SCHEMA ") + qtIdent(wxT("_") + GetName()) + wxT(" CASCADE;")); +} + + +wxString slCluster::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony cluster"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony cluster"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony cluster \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony cluster \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop Slony cluster cascaded?"); + break; + case DROPTITLE: + message = _("Drop Slony cluster?"); + break; + case PROPERTIESREPORT: + message = _("Slony cluster properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Slony cluster properties"); + break; + case DDLREPORT: + message = _("Slony cluster DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Slony cluster DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Slony cluster dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Slony cluster dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Slony cluster dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Slony cluster dependents"); + break; + } + + return message; +} + +wxString slCluster::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = _("-- Use the installation wizard\n-- to generate the Slony-I replication cluster.\n"); + } + return sql; +} + + +slNode *slCluster::GetLocalNode(ctlTree *browser) +{ + pgCollection *nodes = browser->FindCollection(nodeFactory, GetId()); + if (nodes) + { + slNode *node; + + treeObjectIterator ni(browser, nodes); + while ((node = (slNode *)ni.GetNextObject()) != 0) + { + if (node->GetSlId() == GetLocalNodeID()) + return node; + } + } + return 0; +} + + +pgConn *slCluster::GetNodeConn(frmMain *form, long nodeId, bool create) +{ + size_t i; + + if (nodeId == GetLocalNodeID()) + return GetDatabase()->GetConnection(); + + for (i = 0 ; i < remoteConns.GetCount() ; i++) + { + if (remoteConns[i].nodeID == nodeId) + return remoteConns[i].conn; + } + + if (create && adminNodeID >= 0) + { + wxString connstr = GetDatabase()->ExecuteScalar( + wxT("SELECT pa_conninfo FROM ") + GetSchemaPrefix() + wxT("sl_path\n") + wxT(" WHERE pa_server = ") + NumToStr(nodeId) + + wxT(" AND pa_client = ") + NumToStr(adminNodeID)); + + if (!connstr.IsEmpty()) + { + // check for server registration + wxTreeItemId servers = GetId(); + pgObject *obj = this; + while (obj && obj != form->GetServerCollection()) + { + servers = form->GetBrowser()->GetItemParent(servers); + if (servers) + obj = form->GetBrowser()->GetObject(servers); + } + + wxCookieType cookie; + + wxStringTokenizer strtok(connstr, wxT(" "), wxTOKEN_RET_EMPTY); + + wxString lastToken; + wxArrayString tokens; + wxString str; + + while (strtok.HasMoreTokens()) + { + str = strtok.GetNextToken(); + if (str.Find('=') < 0) + { + if (!lastToken.IsEmpty()) + lastToken += wxT(" "); + lastToken += str; + } + else + { + if (!lastToken.IsEmpty()) + tokens.Add(lastToken); + lastToken = str; + } + } + if (!lastToken.IsEmpty()) + tokens.Add(lastToken); + + size_t i; + + wxString host, dbname; + int port = 5432; + for (i = 0 ; i < tokens.GetCount() ; i++) + { + str = tokens[i].BeforeFirst('='); + if (str == wxT("host")) + host = tokens[i].AfterFirst('='); + else if (str == wxT("dbname")) + dbname = tokens[i].AfterFirst('='); + else if (str == wxT("port")) + port = StrToLong(tokens[i].AfterFirst('=')); + } + + if (host.IsEmpty() || dbname.IsEmpty()) + return NULL; + + wxTreeItemId serverItem = form->GetBrowser()->GetFirstChild(servers, cookie); + while (serverItem) + { + pgServer *server = (pgServer *)form->GetBrowser()->GetObject(serverItem); + if (server && server->IsCreatedBy(serverFactory)) + { + if (server->GetName() == host && server->GetPort() == port) + { + if (!server->GetConnected()) + { + server->Connect(form, server->GetStorePwd()); + if (!server->GetConnected()) + { + wxLogError(server->GetLastError()); + return NULL; + } + } + pgConn *conn = server->CreateConn(dbname); + + if (conn) + remoteConns.Add(new RemoteConn(nodeId, connstr, conn)); + + return conn; + } + } + serverItem = form->GetBrowser()->GetNextChild(servers, cookie); + } + + } + } + return NULL; +} + + +bool slCluster::ClusterMinimumVersion(int major, int minor) +{ + long ma = StrToLong(clusterVersion); + long mi = StrToLong(clusterVersion.AfterFirst('.')); + return ma > major || (ma == major && mi >= minor); +} + + +long slCluster::GetSlonPid() +{ + long slonPid; + wxString pidcol = GetConnection()->BackendMinimumVersion(9, 2) ? wxT("pid") : wxT("procpid"); + + if (GetConnection()->BackendMinimumVersion(9, 0)) + { + slonPid = StrToLong(GetConnection()->ExecuteScalar( + wxT("SELECT nl_backendpid FROM ") + qtIdent(wxT("_") + GetName()) + wxT(".sl_nodelock nl, ") + wxT("pg_stat_activity sa WHERE nl.nl_backendpid = sa.") + pidcol + wxT(" AND nl_nodeid = ") + + NumToStr(GetLocalNodeID()))); + } + else + { + slonPid = StrToLong(GetConnection()->ExecuteScalar( + wxT("SELECT listenerpid FROM pg_listener WHERE relname = ") + + qtDbString(wxT("_") + GetName() + wxT("_Event")))); + } + + return slonPid; +} + + +void slCluster::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + pgSet *set; + + set = GetDatabase()->ExecuteSet( + wxT("SELECT no_id, no_comment, ") + GetSchemaPrefix() + wxT("slonyversion() AS version\n") + wxT(" FROM ") + GetSchemaPrefix() + wxT("sl_local_node_id\n") + wxT(" JOIN ") + GetSchemaPrefix() + wxT("sl_node ON no_id = last_value")); + if (set) + { + iSetClusterVersion(set->GetVal(wxT("version"))); + iSetLocalNodeID(set->GetLong(wxT("no_id"))); + iSetLocalNodeName(set->GetVal(wxT("no_comment")).BeforeFirst('\n')); + delete set; + } + + adminNodeID = settings->Read(wxT("Replication/") + GetName() + wxT("/AdminNode"), -1L); + + wxString sql = wxT("SELECT no_id, no_comment\n") + wxT(" FROM ") + GetSchemaPrefix() + wxT("sl_node\n"); + + if (adminNodeID == -1L) + { + sql += wxT(" JOIN ") + GetSchemaPrefix() + wxT("sl_path ON no_id = pa_client\n") + wxT(" WHERE pa_server = ") + NumToStr(localNodeID) + + wxT(" AND pa_conninfo LIKE ") + qtDbString(wxT("%host=") + GetServer()->GetName() + wxT("%")) + + wxT(" AND pa_conninfo LIKE ") + qtDbString(wxT("%dbname=") + GetDatabase()->GetName() + wxT("%")); + } + else + sql += wxT(" WHERE no_id = ") + NumToStr(adminNodeID); + + + set = GetDatabase()->ExecuteSet(sql); + if (set) + { + if (!set->Eof()) + { + adminNodeID = set->GetLong(wxT("no_id")); + adminNodeName = set->GetVal(wxT("no_comment")); + settings->WriteLong(wxT("Replication/") + GetName() + wxT("/AdminNode"), adminNodeID); + } + delete set; + } + + wxLogInfo(wxT("Adding child object to cluster %s"), GetIdentifier().c_str()); + + browser->AppendCollection(this, nodeFactory); + browser->AppendCollection(this, setFactory); + } + + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("Local node ID"), GetLocalNodeID()); + properties->AppendItem(_("Local node"), GetLocalNodeName()); + + if (GetAdminNodeID() == -1L) + properties->AppendItem(_("Admin node"), _("")); + else + { + properties->AppendItem(_("Admin node ID"), GetAdminNodeID()); + properties->AppendItem(_("Admin node"), GetAdminNodeName()); + } + + long slonPid = GetSlonPid(); + if (slonPid) + properties->AppendItem(wxT("Slon PID"), slonPid); + else + properties->AppendItem(wxT("Slon PID"), _("unknown")); + + properties->AppendItem(_("Version"), GetClusterVersion()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *slCluster::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *cluster = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + cluster = slClusterFactory.CreateObjects(coll, 0, wxT(" WHERE nsp.oid=") + GetOidStr() + wxT("\n")); + + return cluster; +} + + + +pgObject *pgaSlClusterFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restriction) +{ + slCluster *cluster = 0; + + pgSet *clusters = coll->GetDatabase()->ExecuteSet( + wxT("SELECT nsp.oid, substr(nspname, 2) as clustername, nspname, pg_get_userbyid(nspowner) AS namespaceowner, description\n") + wxT(" FROM pg_namespace nsp\n") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=nsp.oid\n") + wxT(" JOIN pg_proc pro ON pronamespace=nsp.oid AND proname = 'slonyversion'\n") + + restriction + + wxT(" ORDER BY nspname")); + + if (clusters) + { + while (!clusters->Eof()) + { + cluster = new slCluster(clusters->GetVal(wxT("clustername"))); + cluster->iSetOid(clusters->GetOid(wxT("oid"))); + cluster->iSetDatabase(coll->GetDatabase()); + cluster->iSetSchemaPrefix(qtIdent(clusters->GetVal(wxT("nspname"))) + wxT(".")); + cluster->iSetOwner(clusters->GetVal(wxT("namespaceowner"))); + cluster->iSetComment(clusters->GetVal(wxT("description"))); + + if (browser) + { + browser->AppendObject(coll, cluster); + clusters->MoveNext(); + } + else + break; + } + + delete clusters; + } + return cluster; +} + + + +pgObject *slCluster::ReadObjects(pgCollection *coll, ctlTree *browser) +{ + // Get the clusters + return slClusterFactory.CreateObjects(coll, browser, wxEmptyString); +} + +///////////////////////////// + +slClusterCollection::slClusterCollection(pgaFactory *factory, pgDatabase *db) + : pgDatabaseObjCollection(factory, db) +{ +} + + +wxString slClusterCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony clusters"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony clusters"); + break; + case OBJECTSLISTREPORT: + message = _("Slony clusters list report"); + break; + } + + return message; +} + + +///////////////////////////// + + +#include "images/slcluster.pngc" +#include "images/slclusters.pngc" + +pgaSlClusterFactory::pgaSlClusterFactory() + : pgDatabaseObjFactory(__("Slony-I cluster"), __("New Slony-I cluster..."), __("Create new Slony-I Replication Cluster"), slcluster_png_img) +{ +// metaType = SLM_CLUSTER; +} + + +pgCollection *pgaSlClusterFactory::CreateCollection(pgObject *obj) +{ + return new slClusterCollection(GetCollectionFactory(), (pgDatabase *)obj); +} + + +slObject::slObject(slCluster *cl, pgaFactory &factory, const wxString &newName) + : pgDatabaseObject(factory, newName) +{ + cluster = cl; + iSetDatabase(cl->GetDatabase()); +} + +slObjCollection::slObjCollection(pgaFactory *factory, slCluster *_cluster) + : pgDatabaseObjCollection(factory, _cluster->GetDatabase()) +{ + cluster = _cluster; +} + +pgCollection *slObjFactory::CreateCollection(pgObject *obj) +{ + return new slObjCollection(GetCollectionFactory(), (slCluster *)obj); +} + + +pgaSlClusterFactory slClusterFactory; +static pgaCollectionFactory cf(&slClusterFactory, __("Slony Replication"), slclusters_png_img); + +//////////////////////////////////////////////7 + +bool clusterActionFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(slClusterFactory); +} + + +slonyRestartFactory::slonyRestartFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : clusterActionFactory(list) +{ + mnu->Append(id, _("Restart Node"), _("Restart node.")); +} + + +wxWindow *slonyRestartFactory::StartDialog(frmMain *form, pgObject *obj) +{ + slCluster *cluster = (slCluster *)obj; + + wxString notifyName; + wxString pidcol = cluster->GetDatabase()->BackendMinimumVersion(9, 2) ? wxT(" sa.pid ") : wxT(" sa.procpid "); + + if (cluster->GetDatabase()->BackendMinimumVersion(9, 0)) + { + notifyName = cluster->GetDatabase()->ExecuteScalar( + wxT("SELECT ") + cluster->GetDatabase()->GetConnection()->qtDbString(wxT("_") + cluster->GetName() + wxT("_Restart")) + + wxT(" FROM _") + cluster->GetName() + wxT(".sl_nodelock nl,") + wxT(" pg_stat_activity sa WHERE nl.nl_backendpid = ") + pidcol + wxT("AND nl_nodeid = ") + + NumToStr(cluster->GetLocalNodeID())); + } + else + { + notifyName = cluster->GetDatabase()->ExecuteScalar( + wxT("SELECT relname FROM pg_listener") + wxT(" WHERE relname=") + cluster->GetDatabase()->GetConnection()->qtDbString(wxT("_") + cluster->GetName() + wxT("_Restart"))); + } + + if (notifyName.IsEmpty()) + { + wxMessageDialog dlg(form, wxString::Format(_("Node \"%s\" not running"), cluster->GetLocalNodeName().c_str()), + _("Can't restart node"), wxICON_EXCLAMATION | wxOK); + dlg.ShowModal(); + form->CheckAlive(); + + return 0; + } + + wxMessageDialog dlg(form, wxString::Format(_("Restart node \"%s\"?"), + cluster->GetLocalNodeName().c_str()), _("Restart node"), wxICON_EXCLAMATION | wxYES_NO | wxNO_DEFAULT); + + if (dlg.ShowModal() != wxID_YES) + return 0; + + if (!cluster->GetDatabase()->ExecuteVoid( + wxT("NOTIFY ") + qtIdent(notifyName))) + form->CheckAlive(); + + return 0; +} + + +slonyUpgradeFactory::slonyUpgradeFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : clusterActionFactory(list) +{ + mnu->Append(id, _("Upgrade Node"), _("Upgrade node to newest replication software version.")); +} + + +wxWindow *slonyUpgradeFactory::StartDialog(frmMain *form, pgObject *obj) +{ + dlgProperty *dlg = new dlgRepClusterUpgrade(&slClusterFactory, form, (slCluster *)obj); + dlg->InitDialog(form, obj); + dlg->CreateAdditionalPages(); + dlg->Go(false); + dlg->CheckChange(); + return 0; +} + + +slonyFailoverFactory::slonyFailoverFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : clusterActionFactory(list) +{ + mnu->Append(id, _("Failover"), _("Failover to backup node.")); +} + + +wxWindow *slonyFailoverFactory::StartDialog(frmMain *form, pgObject *obj) +{ + return 0; +} + + +bool slonyFailoverFactory::CheckEnable(pgObject *obj) +{ + return false; +} diff --git a/slony/slListen.cpp b/slony/slListen.cpp new file mode 100644 index 0000000..e30b572 --- /dev/null +++ b/slony/slListen.cpp @@ -0,0 +1,244 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slListen.cpp PostgreSQL Slony-I listen +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgObject.h" +#include "slony/slListen.h" +#include "slony/slNode.h" +#include "slony/slCluster.h" +#include "frm/frmMain.h" + + +slListen::slListen(slNode *n, const wxString &newName) + : slNodeObject(n, listenFactory, newName) +{ +} + +bool slListen::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return GetDatabase()->ExecuteVoid( + wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + + wxT("droplisten(") + NumToStr(GetSlId()) + + wxT(", ") + NumToStr(GetProviderId()) + + wxT(", ") + NumToStr(GetNode()->GetSlId()) + + wxT(");\n")); +} + + +wxString slListen::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony listen"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony listen"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony listen \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony listen \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop Slony listen cascaded?"); + break; + case DROPTITLE: + message = _("Drop Slony listen?"); + break; + case PROPERTIESREPORT: + message = _("Slony listen properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Slony listen properties"); + break; + case DDLREPORT: + message = _("Slony listen DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Slony listen DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Slony listen dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Slony listen dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Slony listen dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Slony listen dependents"); + break; + } + + return message; +} + +wxString slListen::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Node will listen to ") + GetProviderName() + + wxT(" for replication data from ") + GetOriginName() + wxT(".\n\n") + + wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + + wxT("storelisten(") + NumToStr(GetSlId()) + + wxT(", ") + NumToStr(GetProviderId()) + + wxT(", ") + NumToStr(GetNode()->GetSlId()) + + wxT(");\n"); + } + return sql; +} + + +void slListen::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + } + + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Origin"), GetOriginName()); + properties->AppendItem(_("Origin ID"), GetSlId()); + properties->AppendItem(_("Provider"), GetProviderName()); + properties->AppendItem(_("Provider ID"), GetProviderId()); + } +} + + + +pgObject *slListen::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *listen = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + listen = listenFactory.CreateObjects(coll, 0, + wxT(" WHERE li_origin =") + NumToStr(GetSlId()) + + wxT(" AND li_provider = ") + NumToStr(GetProviderId()) + + wxT(" AND li_receiver = ") + NumToStr(GetNode()->GetSlId()) + + wxT("\n")); + + return listen; +} + + + +pgObject *slListenFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restr) +{ + slNodeObjCollection *collection = (slNodeObjCollection *)coll; + slListen *listen = 0; + wxString restriction; + if (restr.IsEmpty()) + restriction = wxT(" WHERE li_receiver = ") + NumToStr(collection->GetSlId()); + else + restriction = restr; + + pgSet *listens = collection->GetDatabase()->ExecuteSet( + wxT("SELECT li_origin, li_provider, li_receiver, no.no_comment as origin_name, np.no_comment as provider_name\n") + wxT(" FROM ") + collection->GetCluster()->GetSchemaPrefix() + wxT("sl_listen\n") + wxT(" JOIN ") + collection->GetCluster()->GetSchemaPrefix() + wxT("sl_node no ON no.no_id=li_origin\n") + wxT(" JOIN ") + collection->GetCluster()->GetSchemaPrefix() + wxT("sl_node np ON np.no_id=li_provider\n") + + restriction + + wxT(" ORDER BY li_origin, li_provider")); + + if (listens) + { + while (!listens->Eof()) + { + wxString orgName = listens->GetVal(wxT("origin_name")).BeforeFirst('\n'); + wxString provName = listens->GetVal(wxT("provider_name")).BeforeFirst('\n'); + + listen = new slListen(collection->GetNode(), orgName + wxT(" (") + provName + wxT(")")); + listen->iSetSlId(listens->GetLong(wxT("li_origin"))); + listen->iSetProviderId(listens->GetLong(wxT("li_provider"))); + listen->iSetOriginName(orgName); + listen->iSetProviderName(provName); + + if (browser) + { + browser->AppendObject(collection, listen); + listens->MoveNext(); + } + else + break; + } + + delete listens; + } + return listen; +} + + +wxString slListenCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony listens"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony listens"); + break; + case OBJECTSLISTREPORT: + message = _("Slony listens list report"); + break; + } + + return message; +} + + +/////////////////////////////////////////////////// + +#include "images/sllisten.pngc" +#include "images/sllistens.pngc" + +slListenFactory::slListenFactory() + : slNodeObjFactory(__("Listen"), __("New Listen"), __("Create a new Listen."), sllisten_png_img) +{ + metaType = SLM_LISTEN; +} + + +pgCollection *slListenFactory::CreateCollection(pgObject *obj) +{ + return new slListenCollection(GetCollectionFactory(), (slNode *)obj); +} + + +slListenFactory listenFactory; +static pgaCollectionFactory cf(&listenFactory, __("listens"), sllistens_png_img); diff --git a/slony/slNode.cpp b/slony/slNode.cpp new file mode 100644 index 0000000..b90f9a4 --- /dev/null +++ b/slony/slNode.cpp @@ -0,0 +1,499 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slNode.cpp PostgreSQL Slony-I node +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgObject.h" +#include "slony/slNode.h" +#include "slony/slCluster.h" +#include "slony/slPath.h" +#include "slony/slListen.h" +#include "slony/slSet.h" +#include "frm/frmMain.h" + + +slNode::slNode(slCluster *cl, const wxString &newName) + : slObject(cl, nodeFactory, newName) +{ + pid = -1; +} + +int slNode::GetIconId() +{ + if (!GetActive()) + return nodeFactory.GetDisabledIconId(); + else if (GetSlId() == GetCluster()->GetLocalNodeID()) + return nodeFactory.GetLocalIconId(); + else + return nodeFactory.GetIconId(); +} + + +wxMenu *slNode::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + +// if (GetCreatePrivilege()) + pathFactory.AppendMenu(menu); + listenFactory.AppendMenu(menu); + + return menu; +} + + +bool slNode::CanDrop() +{ + return (GetSlId() != GetCluster()->GetLocalNodeID()); +} + + +bool slNode::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return GetDatabase()->ExecuteVoid( + wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + + wxT("dropnode(") + NumToStr(GetSlId()) + wxT(");\n")); +} + + +wxString slNode::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony node"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony node"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony node \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony node \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop Slony node cascaded?"); + break; + case DROPTITLE: + message = _("Drop Slony node?"); + break; + case PROPERTIESREPORT: + message = _("Slony node properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Slony node properties"); + break; + case DDLREPORT: + message = _("Slony node DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Slony node DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Slony node dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Slony node dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Slony node dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Slony node dependents"); + break; + } + + return message; +} + +bool slNode::WaitForEvent(long evNode) +{ + return true; +} + + +wxString slNode::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Create replication node ") + GetName() + wxT(".\n\n") + wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + wxT("storenode(") + + NumToStr(GetSlId()) + wxT(", ") + + qtDbString(GetComment()); + + if (GetCluster()->ClusterMinimumVersion(1, 1) && !GetCluster()->ClusterMinimumVersion(2, 0)) + sql += wxT(", ") + BoolToStr(GetSpool()); + sql += wxT(");\n"); + } + return sql; +} + + +long slNode::GetOutstandingAcks() +{ + long l = StrToLong(GetDatabase()->ExecuteScalar( + wxT("SELECT SUM(st_lag_num_events) AS sumlagevents\n") + wxT(" FROM ") + GetCluster()->GetSchemaPrefix() + wxT("sl_status\n") + wxT(" WHERE st_origin = ") + NumToStr(GetCluster()->GetLocalNodeID()) + wxT("\n") + wxT(" GROUP BY st_last_event"))); + + return l; +} + + +bool slNode::CheckAcksAndContinue(wxFrame *frame) +{ + long l = GetOutstandingAcks(); + if (!l) + return true; + + wxMessageDialog dlg(frame, wxString::Format(wxPLURAL("There are %ld event acknowledgement outstanding.\nContinue anyway?", + "There are %ld event acknowledgements outstanding.\nContinue anyway?", l), l), + _("Events pending"), wxYES_NO | wxNO_DEFAULT); + + return dlg.ShowModal() == wxID_YES; +} + + +void slNode::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + CreateListColumns(statistics, _("Statistic"), _("Value")); + + if (GetActive()) + { + if (GetCluster()->GetLocalNodeID() == GetSlId()) + { + pgSet *stats = GetDatabase()->ExecuteSet( + wxT("SELECT st_last_event,\n") + wxT(" MAX(st_last_received_ts - st_last_received_event_ts) AS roundtrip,\n") + wxT(" SUM(st_lag_num_events) AS sumlagevents, st_last_event - MAX(st_lag_num_events) as oldestlagevent,\n") + wxT(" MAX(st_last_event_ts - st_last_received_ts) AS maxeventlag\n") + wxT(" FROM ") + GetCluster()->GetSchemaPrefix() + wxT("sl_status\n") + wxT(" WHERE st_origin = ") + NumToStr(GetCluster()->GetLocalNodeID()) + wxT("\n") + wxT(" GROUP BY st_last_event")); + + if (stats) + { + wxString roundtrip = stats->GetVal(wxT("roundtrip")); + long lags = stats->GetLong(wxT("sumlagevents")); + if (roundtrip.Left(6) == wxT("00:00:")) + roundtrip = NumToStr(StrToLong(roundtrip.Mid(6))) + roundtrip.Mid(8) + wxT(" s"); + else if (roundtrip.Left(3) == wxT("00:")) + roundtrip = NumToStr(StrToLong(roundtrip.Mid(3))) + roundtrip.Mid(5); + + statistics->AppendItem(_("Last event"), stats->GetLong(wxT("st_last_event"))); + statistics->AppendItem(_("Max response time"), roundtrip); + statistics->AppendItem(_("Acks outstanding"), lags); + + + if (lags > 0) + { + long lagEvent = stats->GetLong(wxT("oldestlagevent")); + statistics->AppendItem(_("Oldest outstanding"), lagEvent); + statistics->AppendItem(_("Outstanding for"), stats->GetVal(wxT("maxeventlag"))); + } + + delete stats; + } + } + else + { + pgSet *stats = GetDatabase()->ExecuteSet( + wxT("SELECT st_last_event, st_last_event_ts, st_last_received, st_last_received_ts,\n") + wxT(" st_last_received_ts - st_last_received_event_ts AS roundtrip,\n") + wxT(" st_last_event_ts - st_last_received_ts AS eventlag,") + wxT(" ev_seqno, ev_type || ' ' || COALESCE(ev_data1, '') AS hanging\n") + wxT(" FROM ") + GetCluster()->GetSchemaPrefix() + wxT("sl_status\n") + wxT(" LEFT JOIN ") + GetCluster()->GetSchemaPrefix() + wxT("sl_event ON ev_origin=st_origin AND ev_seqno=\n") + wxT(" (SELECT MIN(ev_seqno) FROM ") + GetCluster()->GetSchemaPrefix() + wxT("sl_event WHERE ev_seqno > st_last_received)\n") + wxT(" WHERE st_origin = ") + NumToStr(GetCluster()->GetLocalNodeID()) + wxT("\n") + wxT(" AND st_received = ") + NumToStr(GetSlId())); + + if (stats) + { + long evno = stats->GetLong(wxT("st_last_event")); + long ack = stats->GetLong(wxT("st_last_received")); + wxString roundtrip = stats->GetVal(wxT("roundtrip")); + if (roundtrip.Left(6) == wxT("00:00:")) + roundtrip = NumToStr(StrToLong(roundtrip.Mid(6))) + roundtrip.Mid(8) + wxT(" s"); + else if (roundtrip.Left(3) == wxT("00:")) + roundtrip = NumToStr(StrToLong(roundtrip.Mid(3))) + roundtrip.Mid(5); + + statistics->AppendItem(_("Last event"), evno); + statistics->AppendItem(_("Last event timestamp"), stats->GetDateTime(wxT("st_last_event_ts"))); + statistics->AppendItem(_("Last acknowledged"), ack); + statistics->AppendItem(_("Last ack timestamp"), stats->GetDateTime(wxT("st_last_received_ts"))); + statistics->AppendItem(_("Last response time"), roundtrip); + + if (evno > ack) + { + statistics->AppendItem(_("Outstanding acks"), evno - ack); + statistics->AppendItem(_("No ack for"), stats->GetVal(wxT("eventlag"))); + statistics->AppendItem(_("Hanging event"), stats->GetVal(wxT("ev_seqno"))); + statistics->AppendItem(_("Command"), stats->GetVal(wxT("hanging"))); + } + + delete stats; + } + } + } + else + statistics->AppendItem(_("not active"), wxEmptyString); +} + + +void slNode::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + wxString pidcol = wxEmptyString; + pgConn *conn = GetCluster()->GetNodeConn(form, GetSlId(), pid < 0); + + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + // Log + wxLogInfo(wxT("Adding child object to node %s"), GetIdentifier().c_str()); + + browser->AppendCollection(this, pathFactory); + browser->AppendCollection(this, listenFactory); + } + + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("ID"), GetSlId()); + if (GetCluster()->GetLocalNodeID() == GetSlId()) + properties->AppendYesNoItem(_("Local node"), true); + properties->AppendYesNoItem(_("Active"), GetActive()); + if (GetCluster()->ClusterMinimumVersion(1, 1)) + properties->AppendYesNoItem(_("Log spooler"), GetSpool()); + properties->AppendYesNoItem(_("Connected"), conn != NULL); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + if (conn && pid < 0) + { + if (conn->BackendMinimumVersion(9, 0)) + { + if (conn->BackendMinimumVersion(9, 2)) + pidcol = wxT("pid"); + else + pidcol = wxT("procpid"); + + pid = StrToLong(conn->ExecuteScalar( + wxT("SELECT nl_backendpid FROM ") + qtIdent(wxT("_") + GetCluster()->GetName()) + wxT(".sl_nodelock nl, ") + wxT("pg_stat_activity sa WHERE nl.nl_backendpid = sa.") + pidcol + wxT(" AND nl_nodeid = ") + + NumToStr(GetCluster()->GetLocalNodeID()))); + } + else + { + pid = StrToLong(conn->ExecuteScalar( + wxT("SELECT listenerpid FROM pg_listener WHERE relname=") + qtDbString(wxT("_") + GetCluster()->GetName() + wxT("_Restart")))); + } + } + + if (conn) + { + if (GetPid()) + properties->AppendItem(_("Running PID"), GetPid()); + else + properties->AppendItem(_("Running PID"), _("not running")); + } + else + { + if (GetSlId() != GetCluster()->GetAdminNodeID()) + properties->AppendItem(_("Running PID"), _("administrative node")); + } + } +} + + + +pgObject *slNode::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *node = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + node = nodeFactory.CreateObjects(coll, 0, wxT(" WHERE no_id=") + NumToStr(GetSlId()) + wxT("\n")); + + return node; +} + + + +pgObject *slNodeFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restriction) +{ + slObjCollection *collection = (slObjCollection *)coll; + slNode *node = 0; + + pgSet *nodes = collection->GetDatabase()->ExecuteSet( + wxT("SELECT * FROM ") + collection->GetCluster()->GetSchemaPrefix() + wxT("sl_node\n") + + restriction + + wxT(" ORDER BY no_id")); + + if (nodes) + { + while (!nodes->Eof()) + { + node = new slNode(collection->GetCluster(), nodes->GetVal(wxT("no_comment")).BeforeFirst('\n')); + node->iSetSlId(nodes->GetLong(wxT("no_id"))); + node->iSetActive(nodes->GetBool(wxT("no_active"))); + node->iSetComment(nodes->GetVal(wxT("no_comment"))); + + if (collection->GetCluster()->ClusterMinimumVersion(1, 1)) + { + if (nodes->HasColumn(wxT("no_spool"))) + node->iSetSpool(nodes->GetBool(wxT("no_spool"))); + } + + if (browser) + { + browser->AppendObject(collection, node); + nodes->MoveNext(); + } + else + break; + } + + delete nodes; + } + return node; +} + + +wxString slNodeCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony nodes"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony nodes"); + break; + case OBJECTSLISTREPORT: + message = _("Slony nodes list report"); + break; + } + + return message; +} + + +void slNodeCollection::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + wxLogInfo(wxT("Displaying statistics for nodes on Cluster %s"), GetCluster()->GetIdentifier().c_str()); + + // Add the statistics view columns + statistics->ClearAll(); + statistics->AddColumn(_("Node"), 50); + statistics->AddColumn(_("Roundtrip"), 50); + statistics->AddColumn(_("Acks outstanding"), 50); + statistics->AddColumn(_("Outstanding time"), 50); + statistics->AddColumn(_("Event No"), 50); + statistics->AddColumn(_("Command"), 250); + + pgSet *stats = GetDatabase()->ExecuteSet( + wxT("SELECT st_received, st_last_event, st_lag_num_events, st_last_event_ts, st_last_received, st_last_received_ts,\n") + wxT(" st_last_received_ts - st_last_received_event_ts AS roundtrip,\n") + wxT(" CASE WHEN st_lag_num_events > 0 THEN st_last_event_ts - st_last_received_ts END AS eventlag,") + wxT(" ev_seqno, ev_type || ' ' || COALESCE(ev_data1, '') AS hanging\n") + wxT(" FROM ") + GetCluster()->GetSchemaPrefix() + wxT("sl_status\n") + wxT(" LEFT JOIN ") + GetCluster()->GetSchemaPrefix() + wxT("sl_event ON ev_origin=st_origin AND ev_seqno=\n") + wxT(" (SELECT MIN(ev_seqno) FROM ") + GetCluster()->GetSchemaPrefix() + wxT("sl_event WHERE ev_seqno > st_last_received)\n") + wxT(" WHERE st_origin = ") + NumToStr(GetCluster()->GetLocalNodeID())); + + if (stats) + { + long pos = 0; + while (!stats->Eof()) + { + long lagEvents = stats->GetLong(wxT("st_lag_num_events")); + statistics->InsertItem(pos, NumToStr(stats->GetLong(wxT("st_received"))), nodeFactory.GetIconId()); + statistics->SetItem(pos, 1, stats->GetVal(wxT("roundtrip"))); + statistics->SetItem(pos, 2, NumToStr(lagEvents)); + statistics->SetItem(pos, 3, stats->GetVal(wxT("eventlag"))); + if (lagEvents) + { + statistics->SetItem(pos, 4, stats->GetVal(wxT("ev_seqno"))); + statistics->SetItem(pos, 5, stats->GetVal(wxT("hanging"))); + } + stats->MoveNext(); + pos++; + } + + delete stats; + } +} + + +/////////////////////////////////////////////////// + +#include "images/slnode.pngc" +#include "images/slnode-local.pngc" +#include "images/slnode-disabled.pngc" +#include "images/slnodes.pngc" + +slNodeFactory::slNodeFactory() + : slObjFactory(__("Node"), __("New Node"), __("Create a new Node."), slnode_png_img) +{ + localIconId = addIcon(slnode_local_png_img); + disabledIconId = addIcon(slnode_disabled_png_img); + metaType = SLM_NODE; +} + +pgCollection *slNodeFactory::CreateCollection(pgObject *obj) +{ + return new slNodeCollection(GetCollectionFactory(), (slCluster *)obj); +} + + +slNodeObject::slNodeObject(slNode *n, pgaFactory &factory, const wxString &newName) + : slObject(n->GetCluster(), factory, newName) +{ + node = n; +} + +slNodeObjCollection::slNodeObjCollection(pgaFactory *factory, slNode *n) + : slObjCollection(factory, n->GetCluster()) +{ + node = n; + iSetSlId(n->GetSlId()); +} + + +pgCollection *slNodeObjFactory::CreateCollection(pgObject *obj) +{ + return new slNodeObjCollection(GetCollectionFactory(), (slNode *)obj); +} + + +slNodeFactory nodeFactory; +static pgaCollectionFactory cf(&nodeFactory, __("Nodes"), slnodes_png_img); diff --git a/slony/slPath.cpp b/slony/slPath.cpp new file mode 100644 index 0000000..d4b5b0a --- /dev/null +++ b/slony/slPath.cpp @@ -0,0 +1,236 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slPath.cpp PostgreSQL Slony-I path +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgObject.h" +#include "slony/slPath.h" +#include "slony/slNode.h" +#include "slony/slCluster.h" +#include "frm/frmMain.h" + + +slPath::slPath(slNode *n, const wxString &newName) + : slNodeObject(n, pathFactory, newName) +{ +} + +bool slPath::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return GetDatabase()->ExecuteVoid( + wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + + wxT("droppath(") + NumToStr(GetSlId()) + + wxT(", ") + NumToStr(GetNode()->GetSlId()) + + wxT(");\n")); +} + + +wxString slPath::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony path"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony path"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony path \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony path \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop Slony path cascaded?"); + break; + case DROPTITLE: + message = _("Drop Slony path?"); + break; + case PROPERTIESREPORT: + message = _("Slony path properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Slony path properties"); + break; + case DDLREPORT: + message = _("Slony path DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Slony path DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Slony path dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Slony path dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Slony path dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Slony path dependents"); + break; + } + + return message; +} + +wxString slPath::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Register path to node ") + GetName() + wxT(".\n\n") + wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + + wxT("storepath(") + NumToStr(GetSlId()) + + wxT(", ") + NumToStr(GetNode()->GetSlId()) + + wxT(", ") + qtDbString(GetConnInfo()) + + wxT(", ") + NumToStr(GetConnRetry()) + + wxT(");\n"); + } + return sql; +} + + +void slPath::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + } + + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Server name"), GetName().BeforeFirst('\n')); + properties->AppendItem(_("Server ID"), GetSlId()); + properties->AppendItem(_("Connect info"), GetConnInfo()); + properties->AppendItem(_("Retry"), GetConnRetry()); + } +} + + + +pgObject *slPath::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *path = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + path = pathFactory.CreateObjects(coll, 0, + wxT(" WHERE pa_server=") + NumToStr(GetSlId()) + + wxT(" AND pa_client=") + NumToStr(GetNode()->GetSlId()) + + wxT("\n")); + + return path; +} + + + +pgObject *slPathFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restr) +{ + slNodeObjCollection *collection = (slNodeObjCollection *)coll; + slPath *path = 0; + wxString restriction; + if (restr.IsEmpty()) + restriction = wxT(" WHERE pa_client = ") + NumToStr(collection->GetSlId()); + else + restriction = restr; + + pgSet *paths = collection->GetDatabase()->ExecuteSet( + wxT("SELECT pa_client, pa_server, pa_conninfo, pa_connretry, no_comment\n") + wxT(" FROM ") + collection->GetCluster()->GetSchemaPrefix() + wxT("sl_path\n") + wxT(" JOIN ") + collection->GetCluster()->GetSchemaPrefix() + wxT("sl_node on no_id=pa_server\n") + + restriction + + wxT(" ORDER BY pa_server")); + + if (paths) + { + while (!paths->Eof()) + { + path = new slPath(collection->GetNode(), paths->GetVal(wxT("no_comment")).BeforeFirst('\n')); + path->iSetSlId(paths->GetLong(wxT("pa_server"))); + path->iSetConnInfo(paths->GetVal(wxT("pa_conninfo"))); + path->iSetConnRetry(paths->GetLong(wxT("pa_connretry"))); + + if (browser) + { + browser->AppendObject(collection, path); + paths->MoveNext(); + } + else + break; + } + + delete paths; + } + return path; +} + + +wxString slPathCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony paths"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony paths"); + break; + case OBJECTSLISTREPORT: + message = _("Slony paths list report"); + break; + } + + return message; +} + + +/////////////////////////////////////////////////// + +#include "images/slpath.pngc" +#include "images/slpaths.pngc" + +slPathFactory::slPathFactory() + : slNodeObjFactory(__("Path"), __("New Path"), __("Create a new Path."), slpath_png_img) +{ + metaType = SLM_PATH; +} + + +pgCollection *slPathFactory::CreateCollection(pgObject *obj) +{ + return new slPathCollection(GetCollectionFactory(), (slNode *)obj); +} + + +slPathFactory pathFactory; +static pgaCollectionFactory cf(&pathFactory, __("Paths"), slpaths_png_img); diff --git a/slony/slSequence.cpp b/slony/slSequence.cpp new file mode 100644 index 0000000..3e034ac --- /dev/null +++ b/slony/slSequence.cpp @@ -0,0 +1,230 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slSequence.cpp PostgreSQL Slony-I sequence +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgObject.h" +#include "slony/slSequence.h" +#include "slony/slSet.h" +#include "slony/slCluster.h" +#include "frm/frmMain.h" + + +slSequence::slSequence(slSet *s, const wxString &newName) + : slSetObject(s, slSequenceFactory, newName) +{ +} + +bool slSequence::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return GetDatabase()->ExecuteVoid( + wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + + wxT("setdropsequence(") + NumToStr(GetSlId()) + wxT(");\n")); +} + + +wxString slSequence::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony sequence"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony sequence"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony sequence \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony sequence \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop Slony sequence cascaded?"); + break; + case DROPTITLE: + message = _("Drop Slony sequence?"); + break; + case PROPERTIESREPORT: + message = _("Slony sequence properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Slony sequence properties"); + break; + case DDLREPORT: + message = _("Slony sequence DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Slony sequence DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Slony sequence dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Slony sequence dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Slony sequence dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Slony sequence dependents"); + break; + } + + return message; +} + +wxString slSequence::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Register sequence ") + GetName() + wxT(" for replication.\n\n") + wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + wxT("setaddsequence(") + + NumToStr(GetSet()->GetSlId()) + wxT(", ") + + NumToStr(GetSlId()) + wxT(", ") + + qtDbString(GetName()) + wxT(", ") + + qtDbString(GetComment()) + wxT(");\n"); + } + return sql; +} + + +void slSequence::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + } + + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("ID"), GetSlId()); + properties->AppendYesNoItem(_("Active"), GetActive()); + } +} + + + +pgObject *slSequence::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *sequence = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + sequence = slSequenceFactory.CreateObjects(coll, 0, wxT(" WHERE seq_id=") + NumToStr(GetSlId()) + wxT("\n")); + + return sequence; +} + + + +pgObject *slSlSequenceFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restr) +{ + slSetObjCollection *collection = (slSetObjCollection *)coll; + slSequence *sequence = 0; + wxString restriction; + if (restr.IsEmpty()) + restriction = wxT(" WHERE seq_set = ") + NumToStr(collection->GetSlId()); + else + restriction = restr; + + pgSet *sequences = collection->GetDatabase()->ExecuteSet( + wxT("SELECT seq_id, seq_set, nspname, relname, seq_comment\n") + wxT(" FROM ") + collection->GetCluster()->GetSchemaPrefix() + wxT("sl_sequence\n") + wxT(" JOIN ") + collection->GetCluster()->GetSchemaPrefix() + wxT("sl_set ON set_id=seq_set\n") + wxT(" JOIN pg_class cl ON cl.oid=seq_reloid\n") + wxT(" JOIN pg_namespace nsp ON nsp.oid=relnamespace\n") + + restriction + + wxT(" ORDER BY seq_id")); + + if (sequences) + { + while (!sequences->Eof()) + { + sequence = new slSequence(collection->GetSet(), sequences->GetVal(wxT("nspname")) + wxT(".") + sequences->GetVal(wxT("relname"))); + sequence->iSetSlId(sequences->GetLong(wxT("seq_id"))); + sequence->iSetComment(sequences->GetVal(wxT("seq_comment"))); + + if (browser) + { + browser->AppendObject(collection, sequence); + sequences->MoveNext(); + } + else + break; + } + + delete sequences; + } + return sequence; +} + + +wxString slSlSequenceCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony sequences"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony sequences"); + break; + case OBJECTSLISTREPORT: + message = _("Slony sequences list report"); + break; + } + + return message; +} + + +/////////////////////////////////////////////////// + +#include "images/sequence-repl.pngc" +#include "images/sequences.pngc" + +slSlSequenceFactory::slSlSequenceFactory() + : slSetObjFactory(__("Sequence"), __("New Sequence"), __("Create a new Sequence."), sequence_repl_png_img) +{ + metaType = SLM_SEQUENCE; +} + + +pgCollection *slSlSequenceFactory::CreateCollection(pgObject *obj) +{ + return new slSlSequenceCollection(GetCollectionFactory(), (slSet *)obj); +} + + +slSlSequenceFactory slSequenceFactory; +static pgaCollectionFactory cf(&slSequenceFactory, __("Sequences"), sequences_png_img); diff --git a/slony/slSet.cpp b/slony/slSet.cpp new file mode 100644 index 0000000..4c4e66a --- /dev/null +++ b/slony/slSet.cpp @@ -0,0 +1,565 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slSet.cpp PostgreSQL Slony-I Set +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgObject.h" +#include "slony/dlgRepSet.h" +#include "slony/slSet.h" +#include "slony/slCluster.h" +#include "slony/slNode.h" +#include "slony/slSequence.h" +#include "slony/slTable.h" +#include "slony/slSubscription.h" +#include "frm/frmMain.h" + + +slSet::slSet(slCluster *cl, const wxString &newName) + : slObject(cl, setFactory, newName) +{ +} + +int slSet::GetIconId() +{ + if (GetOriginId() == GetCluster()->GetLocalNodeID()) + return setFactory.GetExportedIconId(); + else + return setFactory.GetIconId(); +} + + +wxMenu *slSet::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + + if (GetOriginId() == GetCluster()->GetLocalNodeID()) + { + slSequenceFactory.AppendMenu(menu); + slTableFactory.AppendMenu(menu); + } + + subscriptionFactory.AppendMenu(menu); + + return menu; +} + + +bool slSet::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return GetDatabase()->ExecuteVoid( + wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + + wxT("dropset(") + NumToStr(GetSlId()) + wxT(");\n")); +} + + +wxString slSet::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony set"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony set"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony set \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony set \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop Slony set cascaded?"); + break; + case DROPTITLE: + message = _("Drop Slony set?"); + break; + case PROPERTIESREPORT: + message = _("Slony set properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Slony set properties"); + break; + case DDLREPORT: + message = _("Slony set DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Slony set DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Slony set dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Slony set dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Slony set dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Slony set dependents"); + break; + } + + return message; +} + +wxString slSet::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Create replication set ") + GetName() + wxT(".\n\n") + wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + wxT("storeset(") + + NumToStr(GetSlId()) + wxT(", ") + + qtDbString(GetComment()) + wxT(");\n"); + } + return sql; +} + +void slSet::ShowDependencies(frmMain *form, ctlListView *list, const wxString &wh) +{ + list->ClearAll(); + list->AddColumn(_("Type"), 60); + list->AddColumn(_("Name"), 100); + list->AddColumn(_("Comment"), 200); + + wxString where; + if (wh.IsEmpty()) + where = wxT(" WHERE set_id=") + NumToStr(GetSlId()); + else + where = wh; + + pgSet *set = GetDatabase()->ExecuteSet( + wxT("SELECT relkind, nspname, relname, id, comment\n") + wxT(" FROM pg_class cl\n") + wxT(" JOIN pg_namespace nsp ON nsp.oid=cl.relnamespace\n") + wxT(" JOIN (\n") + wxT(" SELECT tab_id AS id, tab_reloid AS oid, tab_altered AS altered, tab_comment AS comment\n") + wxT(" FROM ") + GetCluster()->GetSchemaPrefix() + wxT("sl_table t\n") + wxT(" JOIN ") + GetCluster()->GetSchemaPrefix() + wxT("sl_set s ON tab_set=set_id ") + where + wxT("\n") + wxT(" UNION\n") + wxT(" SELECT seq_id, seq_reloid, NULL, seq_comment\n") + wxT(" FROM ") + GetCluster()->GetSchemaPrefix() + wxT("sl_sequence t\n") + wxT(" JOIN ") + GetCluster()->GetSchemaPrefix() + wxT("sl_set s ON seq_set=set_id ") + where + wxT("\n") + wxT(" ) AS set ON set.oid=cl.oid")); + + if (set) + { + while (!set->Eof()) + { + wxString name = set->GetVal(wxT("nspname")) + wxT(".") + set->GetVal(wxT("relname")); + wxString typestr = set->GetVal(wxT("relkind")); + wxString comment = set->GetVal(wxT("comment")); + wxString typname; + int icon = -1; + switch ( (wxChar)typestr.c_str()[0]) + { + case 'S': + typname = _("Sequence"); + icon = -1; + break; + case 'r': + typname = _("Table"); + icon = -1; + break; + } + + list->AppendItem(icon, typname, name, comment); + + set->MoveNext(); + } + delete set; + } +} + + +wxString slSet::GetLockXXID() +{ + return GetConnection()->ExecuteScalar( + wxT("SELECT set_locked FROM ") + + GetCluster()->GetSchemaPrefix() + wxT("sl_set\n") + wxT(" WHERE set_id=") + NumToStr(GetSlId())); +} + + +bool slSet::Lock() +{ + return GetConnection()->ExecuteVoid(wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + + wxT("lockSet(") + NumToStr(GetSlId()) + wxT(");")); +} + + +bool slSet::Unlock() +{ + return GetConnection()->ExecuteVoid(wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + + wxT("unlockSet(") + NumToStr(GetSlId()) + wxT(");")); +} + + +bool slSet::CanDrop() +{ + if (GetMetaType() != SLM_SUBSCRIPTION) + return !GetSubscriptionCount() && GetOriginId() == GetCluster()->GetLocalNodeID(); + else + return GetOriginId() != GetCluster()->GetLocalNodeID(); +} + + +void slSet::ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &wh) +{ +} + + +void slSet::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + // Log + wxLogInfo(wxT("Adding child object to set %s"), GetIdentifier().c_str()); + + if (GetOriginId() == GetCluster()->GetLocalNodeID()) + { + browser->AppendCollection(this, slSequenceFactory); + browser->AppendCollection(this, slTableFactory); + } + browser->AppendCollection(this, subscriptionFactory); + } + + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("ID"), GetSlId()); + properties->AppendItem(_("Origin ID"), GetOriginId()); + properties->AppendItem(_("Origin Node"), GetOriginNode()); + properties->AppendItem(_("Subscriptions"), GetSubscriptionCount()); + + wxString lockXXID = GetLockXXID(); + + if (!lockXXID.IsEmpty()) + properties->AppendItem(_("Lock XXID"), lockXXID); + + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *slSet::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *set = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + set = setFactory.CreateObjects(coll, 0, wxT(" WHERE set_id=") + NumToStr(GetSlId()) + wxT("\n")); + + return set; +} + + + +pgObject *slSetFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restriction) +{ + slSet *set = 0; + slObjCollection *collection = (slObjCollection *)coll; + wxString prefix = collection->GetCluster()->GetSchemaPrefix(); + + pgSet *sets = collection->GetDatabase()->ExecuteSet( + wxT("SELECT set_id, set_origin, no_comment, set_comment,\n") + wxT(" (SELECT COUNT(1) FROM ") + prefix + wxT("sl_subscribe where sub_set=set_id) AS subcount\n") + wxT(" FROM ") + prefix + wxT("sl_set\n") + wxT(" JOIN ") + prefix + wxT("sl_node ON set_origin=no_id\n") + + restriction + + wxT(" ORDER BY set_id")); + + if (sets) + { + while (!sets->Eof()) + { + set = new slSet(collection->GetCluster(), sets->GetVal(wxT("set_comment")).BeforeFirst('\n')); + set->iSetSlId(sets->GetLong(wxT("set_id"))); + set->iSetOriginId(sets->GetLong(wxT("set_origin"))); + set->iSetOriginNode(sets->GetVal(wxT("no_comment"))); + set->iSetSubscriptionCount(sets->GetLong(wxT("subcount"))); + set->iSetComment(sets->GetVal(wxT("set_comment"))); + + if (browser) + { + browser->AppendObject(coll, set); + sets->MoveNext(); + } + else + break; + } + + delete sets; + } + return set; +} + + +wxString slSetCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony sets"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony sets"); + break; + case OBJECTSLISTREPORT: + message = _("Slony sets list report"); + break; + } + + return message; +} + + +////////////////////////////////////////////////// + +#include "images/slset.pngc" +#include "images/slset2.pngc" +#include "images/slsets.pngc" + +slSetFactory::slSetFactory() + : slObjFactory(__("Set"), __("New Replication Set"), __("Create a new Replication Set."), slset2_png_img) +{ + exportedIconId = addIcon(slset_png_img); + metaType = SLM_SET; +} + + +pgCollection *slSetFactory::CreateCollection(pgObject *obj) +{ + return new slSetCollection(GetCollectionFactory(), (slCluster *)obj); +} + + +slSetObject::slSetObject(slSet *s, pgaFactory &factory, const wxString &newName) + : slObject(s->GetCluster(), factory, newName) +{ + set = s; +} + +bool slSetObject::CanDrop() +{ + if (GetMetaType() != SLM_SUBSCRIPTION) + return !set->GetSubscriptionCount() && set->GetOriginId() == GetCluster()->GetLocalNodeID(); + else + { + if (GetCluster()->ClusterMinimumVersion(1, 1)) + return (set->GetOriginId() == GetCluster()->GetLocalNodeID() || ((slSubscription *)this)->GetForward()); + else + return set->GetOriginId() != GetCluster()->GetLocalNodeID(); + } +} + + +bool slSetObject::CanCreate() +{ + if (GetMetaType() != SLM_SUBSCRIPTION) + return !set->GetSubscriptionCount() && set->GetOriginId() == GetCluster()->GetLocalNodeID(); + else + { + if (GetCluster()->ClusterMinimumVersion(1, 1)) + return (set->GetOriginId() == GetCluster()->GetLocalNodeID() || ((slSubscription *)this)->GetForward()); + else + return set->GetOriginId() != GetCluster()->GetLocalNodeID(); + } +} + + +slSetObjCollection::slSetObjCollection(pgaFactory *factory, slSet *_set) + : slObjCollection(factory, _set->GetCluster()) +{ + set = _set; + subscription = 0; + iSetSlId(set->GetSlId()); +} + + +bool slSetObjCollection::CanCreate() +{ + switch (GetMetaType()) + { + case SLM_SUBSCRIPTION: + if (GetCluster()->ClusterMinimumVersion(1, 1)) + return (set->GetOriginId() == GetCluster()->GetLocalNodeID() || ((slSubscription *)this)->GetForward()); + else + return set->GetOriginId() != GetCluster()->GetLocalNodeID(); + + case SLM_TABLE: + case SLM_SEQUENCE: + if (set->GetSubscriptionCount()) + return false; + else + return set->GetOriginId() == GetCluster()->GetLocalNodeID(); + default: + return false; + } +} + + +pgCollection *slSetObjFactory::CreateCollection(pgObject *obj) +{ + return new slSetObjCollection(GetCollectionFactory(), (slSet *)obj); +} + +slSetFactory setFactory; +static pgaCollectionFactory cf(&setFactory, __("Replication Sets"), slsets_png_img); + +//////////////////////////////////////////////////////////// + +slonyMergeSetFactory::slonyMergeSetFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Merge Set"), _("Merge two replication sets.")); +} + + +wxWindow *slonyMergeSetFactory::StartDialog(frmMain *form, pgObject *obj) +{ + dlgProperty *dlg = new dlgRepSetMerge(&setFactory, form, (slSet *)obj); + dlg->InitDialog(form, obj); + dlg->CreateAdditionalPages(); + dlg->Go(false); + dlg->CheckChange(); + return 0; +} + + +bool slonyMergeSetFactory::CheckEnable(pgObject *obj) +{ + if (!obj || !obj->IsCreatedBy(setFactory)) + return false; + + slSet *set = (slSet *)obj; + + return set->GetOriginId() == set->GetCluster()->GetLocalNodeID(); +} + + +///////////////////////////// + +slonyLockSetFactory::slonyLockSetFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Lock Set"), _("Lock a replication set against updates.")); +} + + +wxWindow *slonyLockSetFactory::StartDialog(frmMain *form, pgObject *obj) +{ + slSet *set = (slSet *)obj; + + if (set->GetCluster()->GetLocalNode(form->GetBrowser())->CheckAcksAndContinue(form)) + { + if (set->Lock()) + form->Refresh(set); + } + return 0; +} + + +bool slonyLockSetFactory::CheckEnable(pgObject *obj) +{ + if (!obj || !obj->IsCreatedBy(setFactory)) + return false; + + slSet *set = (slSet *)obj; + + return set->GetOriginId() == set->GetCluster()->GetLocalNodeID() && set->GetLockXXID().IsEmpty(); +} + + +///////////////////////////// + +slonyUnlockSetFactory::slonyUnlockSetFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Unlock Set"), _("Unlock a replication set and re-allow updates.")); +} + + +wxWindow *slonyUnlockSetFactory::StartDialog(frmMain *form, pgObject *obj) +{ + slSet *set = (slSet *)obj; + + if (set->GetCluster()->GetLocalNode(form->GetBrowser())->CheckAcksAndContinue(form)) + { + if (set->Unlock()) + form->Refresh(set); + } + return 0; +} + + +bool slonyUnlockSetFactory::CheckEnable(pgObject *obj) +{ + if (!obj || !obj->IsCreatedBy(setFactory)) + return false; + + slSet *set = (slSet *)obj; + + return set->GetOriginId() == set->GetCluster()->GetLocalNodeID() && !set->GetLockXXID().IsEmpty(); +} + + +//////////////////////////////// + + +slonyMoveSetFactory::slonyMoveSetFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Move Set"), _("Move replication set to different node")); +} + + +wxWindow *slonyMoveSetFactory::StartDialog(frmMain *form, pgObject *obj) +{ + dlgProperty *dlg = new dlgRepSetMove(&setFactory, form, (slSet *)obj); + dlg->InitDialog(form, obj); + dlg->CreateAdditionalPages(); + dlg->Go(false); + dlg->CheckChange(); + return 0; +} + + +bool slonyMoveSetFactory::CheckEnable(pgObject *obj) +{ + if (!obj || ! obj->IsCreatedBy(setFactory)) + return false; + + slSet *set = (slSet *)obj; + + return set->GetOriginId() == set->GetCluster()->GetLocalNodeID() && !set->GetLockXXID().IsEmpty(); +} + + + diff --git a/slony/slSubscription.cpp b/slony/slSubscription.cpp new file mode 100644 index 0000000..73557b1 --- /dev/null +++ b/slony/slSubscription.cpp @@ -0,0 +1,294 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slSubscription.cpp PostgreSQL Slony-I subscription +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "slony/slSubscription.h" +#include "slony/slTable.h" +#include "slony/slSequence.h" +#include "frm/frmMain.h" + + + +slSubscription::slSubscription(slSet *s, const wxString &newName) + : slSetObject(s, subscriptionFactory, newName) +{ +} + +int slSubscription::GetIconId() +{ + if (GetReceiverId() == GetCluster()->GetLocalNodeID()) + return subscriptionFactory.GetIconId(); + else + return subscriptionFactory.GetExportedIconId(); +} + + +bool slSubscription::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return GetDatabase()->ExecuteVoid( + wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + + wxT("unsubscribeset(") + NumToStr(GetSet()->GetSlId()) + + wxT(", ") + NumToStr(GetReceiverId()) + + wxT(");")); + +} + + +wxString slSubscription::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony subscription"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony subscription"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony subscription \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony subscription \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop Slony subscription cascaded?"); + break; + case DROPTITLE: + message = _("Drop Slony subscription?"); + break; + case PROPERTIESREPORT: + message = _("Slony subscription properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Slony subscription properties"); + break; + case DDLREPORT: + message = _("Slony subscription DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Slony subscription DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Slony subscription dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Slony subscription dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Slony subscription dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Slony subscription dependents"); + break; + } + + return message; +} + +bool slSubscription::CanCreate() +{ + return GetSet()->GetOriginId() != GetReceiverId() && slSetObject::CanCreate(); +} + + +bool slSubscription::CanDrop() +{ + return GetReceiverId() == GetCluster()->GetLocalNodeID(); +} + + +wxString slSubscription::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + if (GetReceiverId() != GetCluster()->GetLocalNodeID()) + sql = wxT("-- Subscription must be maintained on receiver node.\n"); + else + sql = wxT("-- subscribe replication set\n\n") + wxT(" SELECT ") + GetCluster()->GetSchemaPrefix() + wxT("subscribeset(") + + NumToStr(GetSet()->GetSlId()) + wxT(", ") + + NumToStr(GetProviderId()) + wxT(", ") + + NumToStr(GetReceiverId()) + wxT(", ") + + BoolToStr(GetForward()) + wxT(");"); + } + return sql; +} + + +bool slSubscription::WantDummyChild() +{ + return GetSet()->GetOriginId() != GetCluster()->GetLocalNodeID(); +} + + +void slSubscription::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + // Log + + if (WantDummyChild()) + { + wxTreeItemId id = browser->GetItemParent(browser->GetItemParent(GetId())); + if (id) + { + slSet *set = (slSet *)browser->GetObject(id); + if (set && set->IsCreatedBy(setFactory)) + { + wxLogInfo(wxT("Adding child object to subscription %s"), GetIdentifier().c_str()); + + browser->AppendCollection(this, slSequenceFactory); + browser->AppendCollection(this, slTableFactory); + } + } + } + } + + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Provider ID"), GetProviderId()); + properties->AppendItem(_("Provider Name"), GetProviderNode()); + properties->AppendItem(_("Receiver ID"), GetReceiverId()); + properties->AppendItem(_("Receiver Name"), GetReceiverNode()); + + properties->AppendYesNoItem(_("Active"), GetActive()); + properties->AppendYesNoItem(_("May forward"), GetForward()); + if (GetForward()) + properties->AppendYesNoItem(_("Is forwarded"), GetIsSubscribed()); + } +} + + + +pgObject *slSubscription::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *subscription = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + subscription = subscriptionFactory.CreateObjects(coll, 0, wxT(" WHERE sub_set=") + NumToStr(GetSet()->GetSlId()) + + wxT(" AND sub_receiver = ") + NumToStr(GetReceiverId()) + wxT("\n")); + return subscription; +} + + + +pgObject *slSubscriptionFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restr) +{ + slSetObjCollection *collection = (slSetObjCollection *)coll; + slSubscription *subscription = 0; + wxString restriction; + if (restr.IsEmpty()) + restriction = wxT(" WHERE sub_set = ") + NumToStr(collection->GetSlId()); + else + restriction = restr; + + wxString prefix = collection->GetCluster()->GetSchemaPrefix(); + pgSet *subscriptions = collection->GetDatabase()->ExecuteSet( + wxT("SELECT sub_set, sub_provider, sub_receiver, sub_forward, sub_active,\n") + wxT(" re.no_comment as receiver_name, pr.no_comment as provider_name,\n") + wxT(" EXISTS (SELECT 1 FROM ") + prefix + wxT("sl_subscribe s2 WHERE s2.sub_provider = s1.sub_receiver AND s1.sub_set=s2.sub_set) AS is_subscribed\n") + wxT(" FROM ") + prefix + wxT("sl_subscribe s1\n") + wxT(" JOIN ") + prefix + wxT("sl_set ON set_id = sub_set\n") + wxT(" JOIN ") + prefix + wxT("sl_node pr ON pr.no_id = sub_provider\n") + wxT(" JOIN ") + prefix + wxT("sl_node re ON re.no_id = sub_receiver\n") + + restriction + + wxT(" ORDER BY sub_provider, sub_receiver")); + + if (subscriptions) + { + while (!subscriptions->Eof()) + { + subscription = new slSubscription(collection->GetSet(), subscriptions->GetVal(wxT("receiver_name"))); + subscription->iSetActive(subscriptions->GetBool(wxT("sub_active"))); + subscription->iSetForward(subscriptions->GetBool(wxT("sub_forward"))); + subscription->iSetReceiverId(subscriptions->GetLong(wxT("sub_receiver"))); + subscription->iSetProviderId(subscriptions->GetLong(wxT("sub_provider"))); + subscription->iSetReceiverNode(subscriptions->GetVal(wxT("receiver_name"))); + subscription->iSetProviderNode(subscriptions->GetVal(wxT("provider_name"))); + subscription->iSetIsSubscribed(subscriptions->GetBool(wxT("is_subscribed"))); + + if (browser) + { + browser->AppendObject(coll, subscription); + subscriptions->MoveNext(); + } + else + break; + } + + delete subscriptions; + } + return subscription; +} + + +wxString slSubscriptionCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony subscriptions"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony subscriptions"); + break; + case OBJECTSLISTREPORT: + message = _("Slony subscriptions list report"); + break; + } + + return message; +} + + +/////////////////////////////////////////////////// + +#include "images/slsubscription.pngc" +#include "images/slsubscriptions.pngc" + +slSubscriptionFactory::slSubscriptionFactory() + : slSetObjFactory(__("Subscription"), __("New Subscription"), __("Create a new Subscription."), slsubscription_png_img) +{ + metaType = SLM_SUBSCRIPTION; +} + + +pgCollection *slSubscriptionFactory::CreateCollection(pgObject *obj) +{ + return new slSubscriptionCollection(GetCollectionFactory(), (slSet *)obj); +} + + +slSubscriptionFactory subscriptionFactory; +static pgaCollectionFactory cf(&subscriptionFactory, __("Subscriptions"), slsubscriptions_png_img); diff --git a/slony/slTable.cpp b/slony/slTable.cpp new file mode 100644 index 0000000..a9e8807 --- /dev/null +++ b/slony/slTable.cpp @@ -0,0 +1,277 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slTable.cpp PostgreSQL Slony-I table +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "slony/slTable.h" +#include "frm/frmMain.h" + + +slTable::slTable(slSet *s, const wxString &newName) + : slSetObject(s, slTableFactory, newName) +{ +} + +bool slTable::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return GetDatabase()->ExecuteVoid( + wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + + wxT("setdroptable(") + NumToStr(GetSlId()) + wxT(");\n")); +} + + +wxString slTable::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony table"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony table"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony table \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony table \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop Slony table cascaded?"); + break; + case DROPTITLE: + message = _("Drop Slony table?"); + break; + case PROPERTIESREPORT: + message = _("Slony table properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Slony table properties"); + break; + case DDLREPORT: + message = _("Slony table DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Slony table DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Slony table dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Slony table dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Slony table dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Slony table dependents"); + break; + } + + return message; +} + +wxString slTable::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Register table ") + GetName() + wxT(" for replication.\n\n") + wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + wxT("setaddtable(") + + NumToStr(GetSet()->GetSlId()) + wxT(", ") + + NumToStr(GetSlId()) + wxT(", ") + + qtDbString(GetName()) + wxT(", ") + + qtDbString(GetIndexName()) + wxT(", ") + + qtDbString(GetComment()) + wxT(");\n"); + + + size_t i; + for (i = 0 ; i < triggers.GetCount() ; i++) + { + sql += wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + wxT("storetrigger(") + + NumToStr(GetSlId()) + wxT(", ") + + qtDbString(triggers[i]) + wxT(");\n"); + } + } + return sql; +} + + +void slTable::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + pgSet *set; + + if (GetConnection()->BackendMinimumVersion(9, 0)) + { + set = GetConnection()->ExecuteSet( + wxT("SELECT tgname AS trig_tgname FROM pg_trigger t, pg_proc p, pg_namespace n ") + wxT("WHERE t.tgfoid = p.oid AND p.pronamespace = n.oid ") + wxT("AND n.nspname = ") + qtDbString(wxT("_") + GetCluster()->GetName())); + } + else + { + set = GetConnection()->ExecuteSet( + wxT("SELECT trig_tgname\n") + wxT(" FROM ") + GetCluster()->GetSchemaPrefix() + wxT("sl_trigger\n") + wxT(" WHERE trig_tabid = ") + NumToStr(GetSlId())); + } + + if (set) + { + while (!set->Eof()) + { + triggers.Add(set->GetVal(wxT("trig_tgname"))); + set->MoveNext(); + } + delete set; + } + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("ID"), GetSlId()); + properties->AppendItem(_("Index Name"), GetIndexName()); + properties->AppendYesNoItem(_("Altered"), GetAltered()); + + if (triggers.GetCount() > 0) + { + size_t i; + wxString triglist; + for (i = 0; i < triggers.GetCount() ; i++) + triglist += triggers[i] + wxT(", "); + + properties->AppendItem(_("Triggers"), triglist.BeforeLast(',')); + } + + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *slTable::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *table = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + table = slTableFactory.CreateObjects(coll, 0, wxT(" WHERE tab_id=") + NumToStr(GetSlId()) + wxT("\n")); + + return table; +} + + + +pgObject *slSlTableFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restr) +{ + slSetObjCollection *collection = (slSetObjCollection *)coll; + slTable *table = 0; + wxString restriction; + if (restr.IsEmpty()) + restriction = wxT(" WHERE tab_set = ") + NumToStr(collection->GetSlId()); + else + restriction = restr; + + pgSet *tables = collection->GetDatabase()->ExecuteSet( + wxT("SELECT tab_id, tab_reloid, tab_set, nspname, relname, tab_idxname, tab_altered, tab_comment") + wxT(" FROM ") + collection->GetCluster()->GetSchemaPrefix() + wxT("sl_table\n") + wxT(" JOIN ") + collection->GetCluster()->GetSchemaPrefix() + wxT("sl_set ON set_id=tab_set\n") + wxT(" JOIN pg_class cl ON cl.oid=tab_reloid\n") + wxT(" JOIN pg_namespace nsp ON nsp.oid=relnamespace\n") + + restriction + + wxT(" ORDER BY tab_id")); + + if (tables) + { + while (!tables->Eof()) + { + table = new slTable(collection->GetSet(), tables->GetVal(wxT("nspname")) + wxT(".") + tables->GetVal(wxT("relname"))); + table->iSetSlId(tables->GetLong(wxT("tab_id"))); + table->iSetIndexName(tables->GetVal(wxT("tab_idxname"))); + table->iSetComment(tables->GetVal(wxT("tab_comment"))); + table->iSetAltered(tables->GetBool(wxT("tab_altered"))); + table->iSetOid(tables->GetOid(wxT("tab_reloid"))); + + if (browser) + { + browser->AppendObject(collection, table); + tables->MoveNext(); + } + else + break; + } + + delete tables; + } + return table; +} + + +wxString slSlTableCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony tables"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony tables"); + break; + case OBJECTSLISTREPORT: + message = _("Slony tables list report"); + break; + } + + return message; +} + + +/////////////////////////////////////////////////// + +#include "images/table-repl.pngc" +#include "images/table-repl-sm.pngc" +#include "images/tables.pngc" + +slSlTableFactory::slSlTableFactory() + : slSetObjFactory(__("Table"), __("New Table"), __("Create a new Table."), table_repl_png_img, table_repl_sm_png_img) +{ + metaType = SLM_TABLE; +} + + +pgCollection *slSlTableFactory::CreateCollection(pgObject *obj) +{ + return new slSlTableCollection(GetCollectionFactory(), (slSet *)obj); +} + + +slSlTableFactory slTableFactory; +static pgaCollectionFactory cf(&slTableFactory, __("Tables"), tables_png_img); diff --git a/ui/_xrcDialogs.cpp b/ui/_xrcDialogs.cpp new file mode 100644 index 0000000..a9b26e3 --- /dev/null +++ b/ui/_xrcDialogs.cpp @@ -0,0 +1,39917 @@ +// +// This file was automatically generated by wxrc, do not edit by hand. +// + +#include + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include +#include +#include +#include + +#if wxCHECK_VERSION(2,8,5) && wxABI_VERSION >= 20805 + #define XRC_ADD_FILE(name, data, size, mime) \ + wxMemoryFSHandler::AddFileWithMimeType(name, data, size, mime) +#else + #define XRC_ADD_FILE(name, data, size, mime) \ + wxMemoryFSHandler::AddFile(name, data, size) +#endif + +static size_t xml_res_size_0 = 3537; +static unsigned char xml_res_file_0[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,100,80,114,101,99,105,115,105,111,110,83,99,97,108,101,68, +105,97,108,111,103,34,62,10,32,32,32,32,60,116,105,116,108,101,62,68,97, +116,97,116,121,112,101,32,112,114,111,112,101,114,116,105,101,115,60,47, +116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44, +49,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, +69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,49,52,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,80,114,101,99,105,115,105,111,110,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,80,114,101,99,105,115,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,80, +114,101,99,105,115,105,111,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,99,97,108,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,83,99,97,108,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,83,99,97, +108,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97, +116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_1 = 2978; +static unsigned char xml_res_file_1[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,100,84,97,98,108,101,78,97,109,101,68,105,97,108,111,103, +34,62,10,32,32,32,32,60,116,105,116,108,101,62,84,97,98,108,101,32,112, +114,111,112,101,114,116,105,101,115,60,47,116,105,116,108,101,62,10,32, +32,32,32,60,115,105,122,101,62,51,48,48,44,49,54,53,100,60,47,115,105,122, +101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85, +76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73, +79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83, +73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99, +111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98, +108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111, +116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101, +98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,50,57,54,44,49,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108, +101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,80,114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,85,115, +117,97,108,84,97,98,108,101,78,97,109,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,117, +97,108,32,84,97,98,108,101,32,78,97,109,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,85, +115,117,97,108,84,97,98,108,101,78,97,109,101,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_2 = 2897; +static unsigned char xml_res_file_2[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,65,100,100,70,97,118,111,117,114,105,116,101,34,62, +10,32,32,32,32,60,116,105,116,108,101,62,65,100,100,32,102,97,118,111,117, +114,105,116,101,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105, +122,101,62,50,50,48,44,50,53,48,100,60,47,115,105,122,101,62,10,32,32,32, +32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76, +79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83, +89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82, +68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,109,105,110,115,105,122, +101,62,50,49,54,44,50,50,53,100,60,47,109,105,110,115,105,122,101,62,10, +32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,51,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,84,105,116,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,84,105,116,108,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,116,120,116,84,105,116,108,101,34,47,62,10,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,111, +99,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,76,111,99,97,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,99,116,108,84,114,101,101,34,32,110,97,109,101, +61,34,116,114,76,111,99,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,82,95,72,65,83,95,66,85,84, +84,79,78,83,32,124,32,119,120,83,73,77,80,76,69,95,66,79,82,68,69,82,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +98,116,110,78,101,119,70,111,108,100,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,101,119,32,70,111,108, +100,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,76,69,70,84,124,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,66,79, +84,84,79,77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60, +47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62, +10}; + +static size_t xml_res_size_3 = 12101; +static unsigned char xml_res_file_3[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,65,103,103,114,101,103,97,116,101,34,62,10,32,32, +32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62, +51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84, +69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,52,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109, +101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119, +110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,99,104,101,109,97,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109,97,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67, +111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76, +84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98, +108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,73,110,112,117,116,84,121,112,101,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,73,110,112,117,116,32,116,121,112,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,84,121,112, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,82,101,109,111,118, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,54,48,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,66,79,84,84,79,77,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116, +114,108,34,32,110,97,109,101,61,34,108,115,116,73,110,112,117,116,84,121, +112,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,65,100,100,84,121,112, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,38,97,109,112,59,65,100,100,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,54,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,73,110,112,117, +116,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,83,116,97,116,101,84,121,112,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,83,116,97,116,101,32,116,121,112,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,116, +97,116,101,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,116,97,116,101,70,117,110,99,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,83,116,97,116,101,32,102,117,110,99,116,105,111,110,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,83,116,97,116,101,70,117,110,99,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,70,105,110,97,108,70,117,110,99,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,70,105,110,97,108,32,102,117,110,99,116,105,111,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,70,105,110,97,108,70,117,110,99,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,83,111,114,116,79,112,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +111,114,116,32,79,112,101,114,97,116,111,114,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,111,114, +116,79,112,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87, +78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,110, +105,116,105,97,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,73,110,105,116,105,97,108,32,99, +111,110,100,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +116,120,116,73,110,105,116,105,97,108,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_4 = 7896; +static unsigned char xml_res_file_4[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,67,97,115,116,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,50,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,67,97,115,116,110,97,109,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101, +110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,111,117,114,99,101,84,121, +112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,83,111,117,114,99,101,32,116,121,112,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,83,111,117,114,99,101,84,121,112,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +84,97,114,103,101,116,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,97,114,103, +101,116,32,116,121,112,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,84,97,114,103,101,116, +84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,70,117,110,99,116,105,111,110,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,70,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,70,117,110,99,116, +105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87, +78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,109, +112,108,105,99,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,109,112,108,105,99,105, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +66,111,120,34,32,110,97,109,101,61,34,99,104,107,73,109,112,108,105,99, +105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_5 = 6737; +static unsigned char xml_res_file_5[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,67,104,101,99,107,34,62,10,32,32,32,32,60,116,105, +116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54, +53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62, +119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124, +119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78, +85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121, +108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101, +61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100, +62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,87,104,101,114,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,67,104,101,99,107,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,87, +104,101,114,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76, +73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,78,111,73,110,104,101,114,105,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,111,32,73,110,104,101,114,105,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,78,111, +73,110,104,101,114,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,68,111,110,116,86,97,108,105,100,97,116,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,111,110,39,116,32,118,97,108,105,100,97,116,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,68,111,110,116,86,97,108,105,100,97,116,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_6 = 9024; +static unsigned char xml_res_file_6[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,67,111,108,108,97,116,105,111,110,34,62,10,32,32, +32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62, +50,50,48,44,50,56,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84, +69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,50,53,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,52,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109, +101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119, +110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,99,104,101,109,97,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109,97,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67, +111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76, +84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,76,111,99,97,108,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76,111, +99,97,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,76,111,99,97,108,101,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,76,99,67,111,108,108,97,116,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,76,67,95,67,79,76,76,65,84,69,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,76,99,67, +111,108,108,97,116,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,99,67,116,121,112, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,76,67,95,67,84,89,80,69,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,76,99,67,116,121,112,101,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,108, +108,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,112,121,32,99,111,108, +108,97,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,67,111,108,108,97,116,105,111, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_7 = 13272; +static unsigned char xml_res_file_7[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,67,111,108,117,109,110,34,62,10,32,32,32,32,60,116, +105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44, +50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, +69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,52,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78, +97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,68,97,116,97,32,116,121,112,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,68,97,116,97,116,121,112,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,101,110,103,116,104, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,76,101,110,103,116,104,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,76, +101,110,103,116,104,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,80,114,101,99,105,115,105,111, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,80,114,101,99,105,115,105,111,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,80,114,101,99,105,115,105,111,110,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,49,48,44,49,48,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,108,108,97,116,105,111, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,111,108,108,97,116,105,111,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,67,111,108,108,97,116,105,111,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,101,102,97, +117,108,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,68,101,102,97,117,108,116,32,118,97,108, +117,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,68,101,102,97,117,108,116,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,78,111,116,78,117,108,108,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78, +111,116,32,78,85,76,76,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +66,111,120,34,32,110,97,109,101,61,34,99,104,107,78,111,116,78,117,108, +108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,65,116,116, +115,116,97,116,116,97,114,103,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,116,97,116, +105,115,116,105,99,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,65,116,116,115,116,97, +116,116,97,114,103,101,116,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,116,111,114,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,83,116,111,114,97,103,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,83,116,111,114,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120, +67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,86,97,114,105,97,98,108,101,115,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,86,97,114,105,97,98,108,101,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,52,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61, +34,108,115,116,86,97,114,105,97,98,108,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,54, +100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82, +84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79, +87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,112,111,115,62,48,44,48,100,60,47,112,111,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,65,68, +68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,65,100,100,47,67,104,97,110,103,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,77,79,86,69,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,86,97,114,110,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,97,114,105,97,98,108,101,32,78,97,109,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,86,97,114,110,97,109,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80, +68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,114,105,97,98, +108,101,32,86,97,108,117,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,86,97,108,117, +101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79,87, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_8 = 2535; +static unsigned char xml_res_file_8[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,67,111,110,110,101,99,116,34,62,10,32,32,32,32,60, +116,105,116,108,101,62,67,111,110,110,101,99,116,32,116,111,32,83,101,114, +118,101,114,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122, +101,62,50,48,53,44,56,51,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69, +82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,51,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,68,101,115,99,114,105,112,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50, +48,53,44,32,50,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,80,97,115,115,119,111,114,100,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,80,65,83,83,87, +79,82,68,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +60,116,111,111,108,116,105,112,62,69,110,116,101,114,32,116,104,101,32, +112,97,115,115,119,111,114,100,32,116,111,32,117,115,101,32,119,104,101, +110,32,99,111,110,110,101,99,116,105,110,103,32,116,111,32,116,104,101, +32,115,101,114,118,101,114,46,60,47,116,111,111,108,116,105,112,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,49,50, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,116,111, +114,101,80,119,100,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,83,116,111,114,101,32,112,97,115,115,119,111,114,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107, +101,100,62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,49,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51, +44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76, +80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,56,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98, +106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_9 = 9325; +static unsigned char xml_res_file_9[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,67,111,110,118,101,114,115,105,111,110,34,62,10,32, +32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101, +62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69, +82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,52,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109, +101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,84,79,80,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110, +101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,99,104,101, +109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,83,99,104,101,109,97,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101, +102,105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108, +68,101,102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,101,102,97,117, +108,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,68,101,102,97,117,108,116,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61, +34,99,104,107,68,101,102,97,117,108,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,83,111,117,114,99,101,69,110,99,111,100,105,110, +103,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,111,117,114,99,101,32,101,110,99,111,100,105, +110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,99,98,83,111,117,114,99,101,69,110,99,111,100,105, +110,103,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,84,97,114,103,101,116,69,110,99,111,100,105,110,103, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,84,97,114,103,101,116,32,101,110,99,111,100,105,110, +103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,84,97,114,103,101,116,69,110,99,111,100,105,110, +103,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,70,117,110,99,116,105,111,110,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,117, +110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,70,117,110,99,116,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_10 = 15692; +static unsigned char xml_res_file_10[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,68,97,116,97,98,97,115,101,34,62,10,32,32,32,32,60, +116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48, +44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +51,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119,110,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,119,110,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109, +109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,68,101,102,105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,68,101,102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,55,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,69,110,99,111,100,105,110,103,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,99, +111,100,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,99,98,69,110,99,111,100,105,110,103, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119, +120,67,66,95,83,79,82,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,84,101,109,112,108,97,116,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84, +101,109,112,108,97,116,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,84,101,109,112,108,97, +116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,80,97,116, +104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,80,97,116,104,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,80,97,116, +104,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,84,97,98,108,101,115,112,97,99,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,84,97,98,108,101,115,112,97,99,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +84,97,98,108,101,115,112,97,99,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,111,108,108,97,116,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67, +111,108,108,97,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,111,108,108,97,116, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,124,119,120,67,66,95,83,79,82,84,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,84,121,112,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,104,97,114,97,99,116,101,114,32,116,121,112,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,67,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,83, +79,82,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,110,110,76,105,109,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,110,110,101, +99,116,105,111,110,32,76,105,109,105,116,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67, +111,110,110,76,105,109,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,62, +45,49,60,47,109,105,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,99,104, +101,109,97,82,101,115,116,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,99,104,101,109,97, +32,114,101,115,116,114,105,99,116,105,111,110,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,83,99,104,101,109,97,82,101,115,116,114,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,86,97,114,105,97,98,108,101,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108, +34,32,110,97,109,101,61,34,112,110,108,86,97,114,105,97,98,108,101,115, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,52,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112, +62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110, +97,109,101,61,34,108,115,116,86,97,114,105,97,98,108,101,115,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,53,44,54,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82, +69,80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,112,111,115,62,48,44,48,100,60,47,112,111,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,65,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,47,67,104,97, +110,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,77,79,86, +69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,86,97,114,110,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,86,97,114,105,97,98,108,101,32,78,97,109, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,86,97,114,110,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,114, +105,97,98,108,101,32,86,97,108,117,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,44,49,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, +67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,86,97,108,117,101, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,86,97, +108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124, +119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,86,97,114,85,115,101,114,110,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,85,115,101,114,32,78,97,109,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,86,97,114,85,115,101,114,110,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79,87,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101, +61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69, +71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_11 = 3334; +static unsigned char xml_res_file_11[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,68,105,114,101,99,116,68,98,103,34,62,10,32,32,32, +32,60,116,105,116,108,101,62,86,105,101,119,32,68,97,116,97,32,79,112,116, +105,111,110,115,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105, +122,101,62,52,53,48,44,50,49,48,100,60,47,115,105,122,101,62,10,32,32,32, +32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76, +79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83, +89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82, +68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119, +115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111, +111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,52,48,48,44, +49,56,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101, +100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111, +112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114, +111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,49,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,77,101, +115,115,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,69,110,116,101,114,32,116,104,101, +32,114,101,113,117,105,114,101,100,32,118,97,108,117,101,115,32,102,111, +114,32,101,97,99,104,32,112,97,114,97,109,101,116,101,114,58,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,71,114,105,100,34,32, +110,97,109,101,61,34,103,114,100,80,97,114,97,109,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116, +105,112,62,83,101,116,32,116,104,101,32,102,117,110,99,116,105,111,110, +47,112,114,111,99,101,100,117,114,101,32,112,97,114,97,109,101,116,101, +114,32,118,97,108,117,101,115,46,60,47,116,111,111,108,116,105,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,99,104,107,80,107,103,73,110,105,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,68,101,98,117,103,32,112,97,99,107,97,103,101,32,105,110,105,116,105, +97,108,105,122,101,114,63,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,68,101,98,117,103, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,116,111,111,108,116,105,112,62,65,99,99,101,112,116,32,116,104,101,32, +99,117,114,114,101,110,116,32,111,112,116,105,111,110,115,32,97,110,100, +32,99,108,111,115,101,32,116,104,101,32,100,105,97,108,111,103,117,101, +46,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117, +108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,67,97,110,99,101,108,32,97,110, +121,32,99,104,97,110,103,101,115,32,97,110,100,32,99,108,111,115,101,32, +116,104,101,32,100,105,97,108,111,103,117,101,46,60,47,116,111,111,108, +116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110, +107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_12 = 12541; +static unsigned char xml_res_file_12[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,68,111,109,97,105,110,34,62,10,32,32,32,32,60,116, +105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44, +50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, +69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,52,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78, +97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119, +110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,99,104,101, +109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,83,99,104,101,109,97,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101, +102,105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108, +68,101,102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,97,116,97,116,121, +112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,66,97,115,101,32,116,121,112,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,68,97,116,97,116,121,112,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,76,101,110,103,116,104,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,76,101,110,103,116,104,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,76,101,110, +103,116,104,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,80,114,101,99,105,115,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,80,114,101,99,105,115,105,111,110,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,80,114,101,99,105,115,105,111,110,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +68,101,102,97,117,108,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,97,117,108,116, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,68,101,102,97,117,108,116,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,111,116,78,117,108,108,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,111,116,32, +78,85,76,76,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,49,49,50,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,78,111,116,78,117,108,108,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,108,108,97,116,105,111,110,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,111,108,108,97,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,111, +108,108,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107, +112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,111,110,115,116,114,97,105,110,116,115,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,67,111,110,115,116,114,97,105,110,116,115,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61, +34,108,115,116,67,111,110,115,116,114,97,105,110,116,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,50,55,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95, +83,69,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71, +82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,53,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98, +111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,111,110,115,116,114, +84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,65,100,100,67,111,110,115,116,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,82,101,109,111,118,101,67,111,110,115,116,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79,87,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_13 = 6909; +static unsigned char xml_res_file_13[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,69,100,105,116,71,114,105,100,79,112,116,105,111, +110,115,34,62,10,32,32,32,32,60,116,105,116,108,101,62,86,105,101,119,32, +68,97,116,97,32,79,112,116,105,111,110,115,60,47,116,105,116,108,101,62, +10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53,100,60,47,115, +105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70, +65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80, +84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82, +69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119, +97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,79, +112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,116,97,32,83,111,114,116, +105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,83,111,114,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53, +60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103,114, +111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,108,98,108,83,111,114,116,67,111,108,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,83,101,108,101,99,116,101,100,32,67,111,108,117,109,110,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115, +116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116,83,111,114,116, +67,111,108,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82,84, +124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +116,111,111,108,116,105,112,62,76,105,115,116,115,32,116,104,101,32,99, +111,108,117,109,110,115,32,116,104,97,116,32,116,104,101,32,100,97,116, +97,32,119,105,108,108,32,98,101,32,115,111,114,116,101,100,32,98,121,46, +60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108, +65,118,97,105,108,67,111,108,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,118,97,105,108, +97,98,108,101,32,67,111,108,117,109,110,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,111,67,111,108,117,109,110,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116, +111,111,108,116,105,112,62,83,101,108,101,99,116,32,97,32,99,111,108,117, +109,110,32,116,111,32,97,100,100,32,116,111,32,116,104,101,32,115,111,114, +116,32,108,105,115,116,46,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,44,49,44,50,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,98,116,110,65,115,99,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65, +115,99,101,110,100,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, +111,108,116,105,112,62,65,100,100,32,116,104,101,32,115,101,108,101,99, +116,32,99,111,108,117,109,110,32,102,111,114,32,97,115,99,101,110,100,105, +110,103,32,115,111,114,116,46,60,47,116,111,111,108,116,105,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,112,101,114,115,112,101,99,116,105,118, +101,62,49,60,47,112,101,114,115,112,101,99,116,105,118,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110, +68,101,115,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,115,99,101,110,100, +105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112, +62,65,100,100,32,116,104,101,32,115,101,108,101,99,116,32,99,111,108,117, +109,110,32,102,111,114,32,100,101,115,99,101,110,100,105,110,103,32,115, +111,114,116,46,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,112,101,114,115,112,101,99,116,105,118,101,62,49,60,47,112, +101,114,115,112,101,99,116,105,118,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,77,79,86, +69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,82,101,109,111,118, +101,32,116,104,101,32,115,101,108,101,99,116,101,100,32,115,111,114,116, +32,99,111,108,117,109,110,46,60,47,116,111,111,108,116,105,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,112,101,114,115,112,101,99,116,105,118, +101,62,49,60,47,112,101,114,115,112,101,99,116,105,118,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,70,105,108,116,101,114,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,70,105,108,116,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,108,98,108,70,105,108,116,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,116, +101,114,32,83,116,114,105,110,103,32,40,101,103,46,32,111,105,100,32,38, +103,116,59,32,49,48,32,65,78,68,32,111,105,100,32,38,108,116,59,32,53,48, +41,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,99,116,108,83,81,76,66,111,120,34,32,110,97,109,101,61,34,115,113, +108,70,105,108,116,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,69,110,116,101, +114,32,116,104,101,32,102,105,108,116,101,114,32,115,116,114,105,110,103, +32,116,111,32,97,112,112,108,121,32,116,111,32,116,104,101,32,100,97,116, +97,46,32,83,81,76,32,115,121,110,116,97,120,32,115,104,111,117,108,100, +32,98,101,32,117,115,101,100,32,97,115,32,116,104,101,32,115,116,114,105, +110,103,32,119,105,108,108,32,98,101,32,117,115,101,100,32,97,115,32,97, +32,39,87,72,69,82,69,39,32,99,108,97,117,115,101,46,60,47,116,111,111,108, +116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,86,97,108,105,100, +97,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,86,97,108,105,100,97,116,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,86,97,108,105,100,97,116,101, +32,116,104,101,32,115,121,110,116,97,120,32,111,102,32,116,104,101,32,102, +105,108,116,101,114,32,115,116,114,105,110,103,46,60,47,116,111,111,108, +116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,65,99,99,101,112,116,32,116,104,101,32,99,117,114,114, +101,110,116,32,111,112,116,105,111,110,115,32,97,110,100,32,99,108,111, +115,101,32,116,104,101,32,100,105,97,108,111,103,117,101,46,60,47,116,111, +111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,67,97,110,99, +101,108,32,97,110,121,32,99,104,97,110,103,101,115,32,97,110,100,32,99, +108,111,115,101,32,116,104,101,32,100,105,97,108,111,103,117,101,46,60, +47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111, +117,114,99,101,62,10}; + +static size_t xml_res_size_14 = 9704; +static unsigned char xml_res_file_14[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,69,118,101,110,116,84,114,105,103,103,101,114,34, +62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53,100,60,47, +115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +65,80,84,73,79,78,124,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119, +120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98, +108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110, +98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,51,50,48,44,50,52,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,62,51,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,76,69,70, +84,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,76, +69,70,84,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,76,69, +70,84,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,52,48,53,44,51,49,51,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107, +112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,52, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,82,111,119,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,97,98, +108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76, +73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,69,110,97,98,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,111,110,115,116,114,97,105,110,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,69,110,97,98,108,101,100,32,83,116,97,116,117,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,65,76,73, +71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100, +105,111,66,111,120,34,32,110,97,109,101,61,34,114,100,98,69,110,97,98,108, +101,83,116,97,116,117,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,69,78,65,66,76,69,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,82,69,80,76,73,67,65,60,47,105,116,101,109,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,65,76,87,65,89,83,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,50,49,48,44,51,56,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,82,65,95,83,80,69,67,73,70,89,95,82,79,87,83,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,70,117,110,99,116,105,111,110,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,114, +105,103,103,101,114,32,102,117,110,99,116,105,111,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,70,117,110,99,116,105,111,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,69,118,101,110,116,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,69,118,101,110,116,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,111,120,34,32,110, +97,109,101,61,34,114,100,98,69,118,101,110,116,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,68,68,76,32,67,79,77,77,65, +78,68,32,83,84,65,82,84,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,68,68, +76,32,67,79,77,77,65,78,68,32,69,78,68,60,47,105,116,101,109,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,83,81,76,32,68,82,79,80,60,47,105,116,101,109,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116, +101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,51,51,51,44,51,56,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,82,65,95,83,80,69,67,73,70,89,95,82,79,87,83,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,87,104,101,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,87,104,101, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124, +119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,87,104,101,110,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,45,49,44,45,49,60,47, +112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,51,55,52,44,49,56,55,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105, +110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,72,79,82,73,90,79,78,84,65,76,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71, +78,95,84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73, +71,78,95,84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,84,79,80,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119, +120,65,76,73,71,78,95,84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,84,79,80, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116, +117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99, +116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_15 = 6236; +static unsigned char xml_res_file_15[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,69,120,116,84,97,98,108,101,34,62,10,32,32,32,32, +60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48, +48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +51,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119,110,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,119,110,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109, +109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101, +114,83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67, +65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,50,44,50,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,83,81,76,66,111,120, +34,32,110,97,109,101,61,34,116,120,116,83,113,108,66,111,120,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97, +116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_16 = 6709; +static unsigned char xml_res_file_16[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,69,120,116,101,110,115,105,111,110,34,62,10,32,32, +32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62, +51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84, +69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,50,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,78,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73, +78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101, +32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,108,117, +115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,99,104,101,109, +97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,79,98,106,101,99,116,115,83,99,104,101,109,97,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +86,101,114,115,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,101,114,115,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,86,101,114,115,105,111,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_17 = 8453; +static unsigned char xml_res_file_17[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,70,105,110,100,82,101,112,108,97,99,101,34,62,10, +32,32,32,32,60,116,105,116,108,101,62,70,105,110,100,32,97,110,100,32,82, +101,112,108,97,99,101,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115, +105,122,101,62,51,48,48,44,49,54,54,100,60,47,115,105,122,101,62,10,32, +32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73, +65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119, +120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66, +79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,70,105,110,100,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +70,105,110,100,32,119,104,97,116,58,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,70,105,110,100,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,69,110,116,101, +114,32,116,104,101,32,115,116,114,105,110,103,32,116,111,32,115,101,97, +114,99,104,32,102,111,114,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,70,73,78,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,70,105,110,100,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60, +47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,116,111,111,108,116,105,112,62,70,105,110,100,32,116,104,101,32, +115,112,101,99,105,102,105,101,100,32,116,101,120,116,60,47,116,111,111, +108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,108,98,108,82,101,112,108,97,99,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,112,108,97, +99,101,32,119,105,116,104,58,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,82,101,112,108,97,99,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,69,110,116, +101,114,32,116,104,101,32,114,101,112,108,97,99,101,109,101,110,116,32, +116,101,120,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,80,76,65,67,69,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,82,101,112,108,97,99,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112, +62,70,105,110,100,32,97,110,100,32,114,101,112,108,97,99,101,32,116,104, +101,32,115,112,101,99,105,102,105,101,100,32,116,101,120,116,60,47,116, +111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +82,69,80,76,65,67,69,65,76,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,82,101,112,108,97,99,101,32,38,97,109, +112,59,65,108,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,70,105,110,100,32,97, +110,100,32,114,101,112,108,97,99,101,32,97,108,108,32,111,99,99,117,114, +114,101,110,99,101,115,32,111,102,32,116,104,101,32,115,112,101,99,105, +102,105,101,100,32,116,101,120,116,60,47,116,111,111,108,116,105,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,98,79,114,105,103,105,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,114,105, +103,105,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +114,100,79,114,105,103,105,110,67,117,114,115,111,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70, +114,111,109,32,116,104,101,32,99,117,114,115,111,114,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +97,108,117,101,62,49,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,66,101, +103,105,110,32,115,101,97,114,99,104,105,110,103,32,97,116,32,116,104,101, +32,99,117,114,114,101,110,116,32,99,117,114,115,111,114,32,112,111,115, +105,116,105,111,110,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,114,100,79,114,105,103,105,110,84,111,112,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,70,114,111,109,32,116,104,101,32,116,111,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116, +111,111,108,116,105,112,62,66,101,103,105,110,32,115,101,97,114,99,104, +105,110,103,32,97,116,32,116,104,101,32,116,111,112,32,111,102,32,116,104, +101,32,116,101,120,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,98,68,105,114,101,99,116,105,111,110,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +68,105,114,101,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,114,100,68,105,114,101,99,116,105,111,110,70,111,114, +119,97,114,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,70,111,114,119,97,114,100,115,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,97,108,117,101,62,49,60,47,118,97,108,117,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112, +62,83,101,97,114,99,104,32,102,111,114,119,97,114,100,115,32,116,104,114, +111,117,103,104,32,116,104,101,32,116,101,120,116,60,47,116,111,111,108, +116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,114,100,68,105,114,101, +99,116,105,111,110,66,97,99,107,119,97,114,100,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,66,97,99, +107,119,97,114,100,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,83, +101,97,114,99,104,32,98,97,99,107,119,97,114,100,115,32,116,104,114,111, +117,103,104,32,116,104,101,32,116,101,120,116,60,47,116,111,111,108,116, +105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,98,79,112,116,105,111,110,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,79,112,116,105,111,110,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,99,104,107,79,112,116,105,111,110,115,87,104,111,108,101, +87,111,114,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,87,104,111,108,101,32,119,111,114,100,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,77,97,116,99,104,32,111,110, +32,119,104,111,108,101,32,119,111,114,100,115,60,47,116,111,111,108,116, +105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,79,112,116,105,111,110,115,77, +97,116,99,104,67,97,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,116,99,104,32,99,97,115, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,116,111,111,108,116,105,112,62,77,97,116,99,104,32,116, +104,101,32,99,97,115,101,32,111,102,32,116,104,101,32,116,101,120,116,60, +47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +79,112,116,105,111,110,115,85,115,101,82,101,103,101,120,112,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,82,101,103,117,108,97,114,32,101,120,112,114,101,115,115,105,111, +110,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,85,115,101,32,114, +101,103,117,108,97,114,32,101,120,112,114,101,115,115,105,111,110,115,32, +119,104,101,110,32,115,101,97,114,99,104,105,110,103,60,47,116,111,111, +108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,67,108,111,115,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,67, +108,111,115,101,32,116,104,101,32,100,105,97,108,111,103,60,47,116,111, +111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99, +116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_18 = 11336; +static unsigned char xml_res_file_18[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,70,111,114,101,105,103,110,68,97,116,97,87,114,97, +112,112,101,114,34,62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32, +32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53,100,60,47,115,105,122, +101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85, +76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73, +79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83, +73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99, +111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111, +119,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111, +116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101, +98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108, +101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,80,114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,51,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44, +45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,108,117,115, +116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,32,83,108,111,110, +121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,67,108,117,115,116,101,114, +83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45, +49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,68,101,102,105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,68,101,102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,72,97,110, +100,108,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,72,97,110,100,108,101,114,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,72,97,110,100,108,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,86,97,108,105,100,97,116,111,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,97,108,105,100,97,116,111,114,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,86,97,108,105,100,97,116,111,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111, +116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,79,112,116,105,111,110,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,79,112,116,105,111,110,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47, +103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34,32, +110,97,109,101,61,34,108,115,116,79,112,116,105,111,110,115,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,55,48,44,49,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67, +95,82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,56,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,79,112,116,105,111,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,79,112,116,105,111,110,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,79,112,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,108,117,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,86,97,108,117,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,66,79,84,84,79, +77,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,72,79,82,73,90,79, +78,84,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,82,69,77,79,86,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111, +118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,51,44,53,56, +100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,65,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,47,67,104, +97,110,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,51,44, +55,56,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,44,50,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,55,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44, +51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,71,82,79,87,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110, +107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82, +79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_19 = 14711; +static unsigned char xml_res_file_19[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,70,111,114,101,105,103,110,75,101,121,34,62,10,32, +32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101, +62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69, +82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,49,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109, +101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76, +73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101, +32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,99,98,67,108,117,115,116,101,114,83, +101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,68,101,102,101,114,114,97,98,108,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +101,114,114,97,98,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,68,101,102,101, +114,114,97,98,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +68,101,102,101,114,114,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,101,114,114, +101,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34, +32,110,97,109,101,61,34,99,104,107,68,101,102,101,114,114,101,100,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,77,97,116,99,104,70,117, +108,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,77,97,116,99,104,32,102,117,108,108,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,77,97,116,99,104,70,117,108,108,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,68,111,110,116,86,97,108,105,100, +97,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,68,111,110,39,116,32,118,97,108,105,100, +97,116,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34, +32,110,97,109,101,61,34,99,104,107,68,111,110,116,86,97,108,105,100,97, +116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,65,117, +116,111,73,110,100,101,120,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,117,116,111,32,70,75, +32,105,110,100,101,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +66,111,120,34,32,110,97,109,101,61,34,99,104,107,65,117,116,111,73,110, +100,101,120,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99, +104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,110,100, +101,120,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,118,101,114,105,110,103, +32,105,110,100,101,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,73,110,100,101,120,78, +97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,67,111,108,117,109,110,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, +115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34, +32,110,97,109,101,61,34,108,115,116,67,111,108,117,109,110,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95, +83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,84,79,80,124,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,124,119,120,71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +50,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,82,101, +102,101,114,101,110,99,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,102, +101,114,101,110,99,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98, +111,66,111,120,34,32,110,97,109,101,61,34,99,98,82,101,102,101,114,101, +110,99,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,108,117,109,110,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,76,111,99,97,108,32,99,111,108,117,109,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,111,108,117,109,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,82,101,102,67,111,108,117,109,110,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,82,101,102,101,114,101,110,99,105,110,103,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,82,101,102,67,111,108,117,109,110,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120, +71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,65,100,100,82,101,102, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,82,101,109,111,118,101,82,101,102,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,82,101,109,111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,71,82, +79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,65,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,65,99,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,44,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97, +100,105,111,66,111,120,34,32,110,97,109,101,61,34,114,98,79,110,85,112, +100,97,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,79,110,32,85,112,100,97,116,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,78,79, +32,65,67,84,73,79,78,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,82,69,83, +84,82,73,67,84,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,67,65,83,67,65, +68,69,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,83,69,84,32,78,85,76,76, +60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,105,116,101,109,62,83,69,84,32,68,69,70,65,85,76, +84,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,105,109,101,110,115, +105,111,110,62,49,60,47,100,105,109,101,110,115,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,82,65,95,83,80,69,67,73,70,89,95,67,79,76,83,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97, +100,105,111,66,111,120,34,32,110,97,109,101,61,34,114,98,79,110,68,101, +108,101,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,79,110,32,68,101,108,101,116,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,78,79, +32,65,67,84,73,79,78,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,82,69,83, +84,82,73,67,84,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,67,65,83,67,65, +68,69,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,83,69,84,32,78,85,76,76, +60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,105,116,101,109,62,83,69,84,32,68,69,70,65,85,76, +84,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,105,109,101,110,115, +105,111,110,62,49,60,47,100,105,109,101,110,115,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,82,65,95,83,80,69,67,73,70,89,95,67,79,76,83,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101, +61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69, +71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_20 = 11156; +static unsigned char xml_res_file_20[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,70,111,114,101,105,103,110,83,101,114,118,101,114, +34,62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115, +105,122,101,62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32, +32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73, +65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119, +120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66, +79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98, +111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111, +107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57, +54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99, +116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80, +114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110, +108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,114,111,119,115,62,51,60,47,103,114,111,119,97,98,108,101,114, +111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,79,73,68,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,79,73,68,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53, +44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,79,119,110,101,114,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,108,117,115, +116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,32,83,108,111,110, +121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,67,108,117,115,116,101,114, +83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45, +49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,68,101,102,105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,68,101,102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,121, +112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,84,121,112,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,84, +121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,86,101,114,115,105,111,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,86,101,114,115,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,86, +101,114,115,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,116,105, +111,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,79,112,116,105,111,110, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67, +116,114,108,34,32,110,97,109,101,61,34,108,115,116,79,112,116,105,111,110, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,112,111,115,62,55,48,44,49,53,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71, +76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,56,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124, +119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,112,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,79,112,116,105,111,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,86,97,108,117,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,86,97,108,117, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,66, +79,84,84,79,77,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,72,79, +82,73,90,79,78,84,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,119,120,73,68,95,82,69,77,79,86,69,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,82,101,109,111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,49,51,44,53,56,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,65,68,68,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65, +100,100,47,67,104,97,110,103,101,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111, +115,62,49,51,44,55,56,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,124,119,120,65,76,73,71,78,95,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,50,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,44, +50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,55,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,71,82,79,87,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110, +107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82, +79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_21 = 17722; +static unsigned char xml_res_file_21[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,70,111,114,101,105,103,110,84,97,98,108,101,34,62, +10,32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122, +101,62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32, +60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79, +71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89, +83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68, +69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111, +107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50, +52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60, +115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111, +112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114, +111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,52,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109, +101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119, +110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,99,104,101,109,97,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109,97,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67, +111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76, +84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,70,111,114,101,105,103,110,83,101,114,118,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,70,111,114,101,105,103,110,32,83,101,114,118,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,70,111,114,101,105,103,110,83,101,114,118,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,108,117, +109,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,67,111,108,117,109,110, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,44,49, +44,50,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,67, +111,109,112,111,115,105,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76, +105,115,116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116,77,101, +109,98,101,114,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67, +95,82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,77,101,109,98,101,114,110,97,109, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,109,98,101, +114,32,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,77,101,109,98,101,114,110,97,109,101,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,68,97,116,97,116,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,68,97,116,97,32,116,121,112,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,68,97,116,97,116,121,112,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,76,101,110,103,116,104,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,76,101,110,103,116,104,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108, +34,32,110,97,109,101,61,34,116,120,116,76,101,110,103,116,104,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,80,114,101,99,105,115,105,111,110,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,101,99,105,115,105,111,110, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,80,114,101, +99,105,115,105,111,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,111,116,78,117, +108,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,79,84,32, +78,85,76,76,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,78,111,116,78,117,108,108,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,77,101,109,98,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,65, +76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,65,100,100,77,101,109, +98,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,65,76, +73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,67,104,97,110,103,101, +77,101,109,98,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,104,97,110,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115, +62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111, +111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,112,116,105,111,110,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61, +34,112,110,108,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119, +97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101, +61,34,108,115,116,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,55,48,44,49, +53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79, +82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,56,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,112,116,105,111,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,112,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116, +79,112,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,108, +117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,108,117,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,66,79,84,84,79,77,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,72,79,82,73,90,79,78,84,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,77,79,86, +69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,112,111,115,62,49,51,44,53,56,100,60,47,112,111,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119, +120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,65,68,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,65,100,100,47,67,104,97,110,103,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,112,111,115,62,49,51,44,55,56,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_22 = 26790; +static unsigned char xml_res_file_22[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,70,117,110,99,116,105,111,110,34,62,10,32,32,32,32, +60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,53, +48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,51,52,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +52,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119,110,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,119,110,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,83,99,104,101,109,97,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111, +109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,108,117,115, +116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,32,83,108,111,110, +121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,67,108,117,115,116,101,114, +83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87, +78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111, +111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53, +60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,65,114,103,117,109,101,110,116,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,114, +103,117,109,101,110,116,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,65,114,103,117, +109,101,110,116,115,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,82,101,116,117,114,110,116,121, +112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,82,101,116,117,114,110,32,116,121,112,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,82,101,116,117,114,110,116,121,112,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +76,97,110,103,117,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76,97,110,103,117,97, +103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,76,97,110,103,117,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,79,112,116,105,111,110,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,79,112,116,105,111,110,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,86,111,108,97,116,105,108,105,116,121, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,86,111,108,97,116,105,108,105,116,121,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,86,111,108,97,116,105,108,105,116,121,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,105,116,101,109,62,86,79,76,65,84,73,76,69,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,83,84,65,66,76,69,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,73,77,77,85,84,65,66,76,69,60,47,105,116,101,109,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,101,108,101,99,116,105,111,110,62,48,60,47,115,101,108, +101,99,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,101,116,111,102,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,82,101,116,117,114,110,115,32,115,101,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,83,101,116,111,102,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,83,116,114,105,99,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,116,114,105,99, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,99,104,107,83,116,114,105,99,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,83,101,99,117,114,101,68,101,102,105, +110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,83,101,99,117,114,105,116,121,32,111,102, +32,100,101,102,105,110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,101,99,117,114, +101,68,101,102,105,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,87,105,110,100,111,119,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,87,105,110, +100,111,119,32,102,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,87,105, +110,100,111,119,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,115,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,69,115,116,105,109,97,116,101,100,32, +99,111,115,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,67,111,115,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,82,111,119,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,69,115,116,105,109,97,116,101,100,32,114,111,119,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,82,111,119,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,76,101,97,107,80,114,111,111,102,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,76,101,97,107,32,112,114,111,111,102,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,76,101,97,107, +80,114,111,111,102,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,80,97,114,97,109,101,116,101,114,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,97,114,97,109,101,116,101,114,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105, +115,116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116,65,114,103, +117,109,101,110,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80, +79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,56,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,68,97,116,97,116,121,112,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,68,97,116,97,116,121,112,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +68,97,116,97,116,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,77,111,100,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,111,100,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,114, +100,98,73,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,78,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82, +66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,114, +100,98,79,117,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,85,84, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,114,100,98,73,110,79,117,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,78,32,79,85,84,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,114,100,98,86,97,114,105,97,100,105, +99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,82,73,65,68,73,67, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,84,79,80,124,119,120,66,79,84,84,79,77,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,65,114,103,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,114,103, +117,109,101,110,116,32,110,97,109,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,65,114,103,78,97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,65,114,103,68, +101,102,86,97,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,97,117,108, +116,32,86,97,108,117,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,65,114,103,68, +101,102,86,97,108,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,52,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,52,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95, +66,79,84,84,79,77,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,72, +79,82,73,90,79,78,84,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,77,79,86, +69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,65,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,67,72,65,78,71,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,104,97,110, +103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114, +111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116, +101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,100,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,67,111,100,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,62,48,44,49,60,47,103,114,111,119,97,98,108,101, +114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,79,98,106,101,99,116,70,105, +108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,79,98,106,101,99,116,32,102,105, +108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,79,98,106,101,99,116,70,105, +108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,105,110,107,83,121, +109,98,111,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76,105,110,107,32,115,121, +109,98,111,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,76,105,110,107,83,121,109,98, +111,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,83,81,76,66,111,120,34,32,110,97,109, +101,61,34,116,120,116,83,113,108,66,111,120,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,77,85,76,84,73,76,73,78,69,124,119,120,83,85,78,75,69,78,95, +66,79,82,68,69,82,124,119,120,84,69,95,82,73,67,72,50,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86, +97,114,105,97,98,108,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,86, +97,114,105,97,98,108,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,52,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115, +116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116,86,97,114,105, +97,98,108,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,112,111,115,62,53,44,54,100,60,47,112,111,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95,83,73, +78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,48,44, +48,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,65,100,100,86,97,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,65,100,100,47,67,104,97,110,103,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110, +82,101,109,111,118,101,86,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101, +109,111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,86,97,114,110,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,86,97,114,105,97,98,108,101,32,78,97,109, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,86,97,114,110,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,114, +105,97,98,108,101,32,86,97,108,117,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,44,49,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, +67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,86,97,108,117,101, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,86,97, +108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124, +119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79, +87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_23 = 7226; +static unsigned char xml_res_file_23[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,71,114,111,117,112,34,62,10,32,32,32,32,60,116,105, +116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54, +53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62, +119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124, +119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78, +85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121, +108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101, +61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100, +62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,71,114,111,117,112,110,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,71,114,111,117,112,32,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83, +101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65, +68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77, +101,109,98,101,114,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,77,101,109, +98,101,114,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,49,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,44,50,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,85,115,101,114,115,78, +111,116,73,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,78,111,116,32,77,101,109,98,101,114, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,44,50,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +85,115,101,114,115,73,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,109,98,101,114,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,76,105,115,116,66,111,120,34,32,110,97,109,101, +61,34,108,98,85,115,101,114,115,78,111,116,73,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,56,54,44,49,50,51,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,66,95,78,69,69,68,69,68,95,83,66,124,119,120, +76,66,95,83,79,82,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60, +47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,98,116,110,65,100,100,85,115,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,38,103,116,59,38,103,116,59,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,49,56,44,45,49,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,66,79,84,84,79,77,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,68,101,108,85,115,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,108,116,59,38,108,116,59,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,49,56,44,45,49,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,84,79,80,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,66, +111,120,34,32,110,97,109,101,61,34,108,98,85,115,101,114,115,73,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,56,54,44,49,50,51,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,76,66,95,78,69,69,68,69,68,95, +83,66,124,119,120,76,66,95,83,79,82,84,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82, +79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_24 = 5724; +static unsigned char xml_res_file_24[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,72,98,97,67,111,110,102,105,103,34,62,10,32,32,32, +32,60,116,105,116,108,101,62,67,108,105,101,110,116,32,65,99,99,101,115, +115,32,67,111,110,102,105,103,117,114,97,116,105,111,110,60,47,116,105, +116,108,101,62,10,32,32,32,32,60,115,105,122,101,62,50,50,48,44,49,53,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,69,110,97,98,108,101,100,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,97,98,108, +101,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,69,110, +97,98,108,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,84,121,112,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,68,97,116,97,98,97,115,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +68,97,116,97,98,97,115,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,68,97,116,97,98,97,115,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,85,115,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +85,115,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,85,115,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,73,80,97,100,100,114,101,115,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73, +80,32,65,100,100,114,101,115,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,73,80,97,100,100,114,101,115,115,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,77,101, +116,104,111,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,77,101,116,104,111,100,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,77,101,116,104,111,100,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,112,116,105,111,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,116,105,111,110, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,112,116, +105,111,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111, +117,114,99,101,62,10}; + +static size_t xml_res_size_25 = 16342; +static unsigned char xml_res_file_25[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,73,110,100,101,120,34,62,10,32,32,32,32,60,116,105, +116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54, +53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62, +119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124, +119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78, +85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121, +108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101, +61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100, +62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101, +102,105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108, +68,101,102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,62,54,60,47,103,114,111,119,97,98,108,101,114,111, +119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +84,97,98,108,101,115,112,97,99,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,97,98,108,101, +115,112,97,99,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,84,97,98,108,101,115,112,97,99,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,121,112,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,65,99,99,101,115,115,32,109,101,116,104,111,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,70,105,108,108,70,97,99,116,111,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70, +105,108,108,32,102,97,99,116,111,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,105,108, +108,70,97,99,116,111,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,85,110,105,113,117,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,85,110,105,113,117,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,85,110, +105,113,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,108,117,115,116,101,114,101,100,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,108,117,115, +116,101,114,101,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,67,108,117,115,116,101,114, +101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111, +110,99,117,114,114,101,110,116,108,121,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,110, +99,117,114,114,101,110,116,32,98,117,105,108,100,63,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,67,111,110,99,117,114,114,101,110,116,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,87,104,101,114,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111, +110,115,116,114,97,105,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,87,104,101,114,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85, +76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111, +116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,67,111,108,117,109,110,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, +115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34, +32,110,97,109,101,61,34,108,115,116,67,111,108,117,109,110,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95, +83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47, +103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,108,117,109,110,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,111,108,117,109,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,67,111,108,108,97,116,105,111,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,111,108,108,97,116,105,111,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34, +99,98,67,111,108,108,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,112, +67,108,97,115,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,101,114,97,116, +111,114,32,99,108,97,115,115,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,112,67,108,97,115, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,68,101,115,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,69,83,67,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,53,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +68,101,115,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,82,73,71,72,84,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,49,53,44,51,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,117,108,108,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,78,85,76,76,115,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,49,48,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115, +62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +114,100,98,78,117,108,108,115,70,105,114,115,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,70,73,82,83,84,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82,66,95, +71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,53,44, +51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,114,100,98,78,117,108,108, +115,76,97,115,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,76,65,83,84,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,97,108,117,101,62,49,60,47,118,97,108,117,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98, +116,110,65,100,100,67,111,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,82,101, +109,111,118,101,67,111,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109, +111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,48,44, +45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119, +120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_26 = 16411; +static unsigned char xml_res_file_26[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,73,110,100,101,120,67,111,110,115,116,114,97,105, +110,116,34,62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32, +60,115,105,122,101,62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62, +10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95, +68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124, +119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69, +95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101, +114,111,119,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116, +101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98, +111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101, +99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +80,114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,49,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,54,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,97,98,108, +101,115,112,97,99,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,84,97,98,108,101,115,112,97,99, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,84,97,98,108,101,115,112,97,99,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,73,110,100,101,120,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,73,110,100,101,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,73,110,100,101,120,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,121,112,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,65,99,99,101,115,115,32,109,101,116,104,111,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,70,105,108,108,70,97,99,116,111,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70, +105,108,108,32,102,97,99,116,111,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,105,108, +108,70,97,99,116,111,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,101,102,101,114,114, +97,98,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,68,101,102,101,114,114,97,98,108,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,99,104,107,68,101,102,101,114,114,97,98,108,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,101,102,101,114,114, +101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,68,101,102,101,114,114,101,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,68,101,102,101,114,114,101,100,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,87,104,101,114,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,110,115,116,114,97,105,110,116,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,87,104,101,114,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95, +77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,67,111,108,117,109,110,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, +115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34, +32,110,97,109,101,61,34,108,115,116,67,111,108,117,109,110,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95, +83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47, +103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,108,117,109,110,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,111,108,117,109,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,79,112,67,108,97,115,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,79,112,101,114,97,116,111,114,32,99,108,97,115,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,79,112,67,108,97,115,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,101,115,99,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,69,83,67,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +53,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,68,101,115,99,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,53,44,51, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,117,108,108,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,78,85,76,76,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +48,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,114,100,98,78,117,108,108,115,70, +105,114,115,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +70,73,82,83,84,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,49,53,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,114,100,98,78,117,108,108,115,76,97,115,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,76,65,83,84,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,49,60,47,118, +97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,79,112,101,114,97,116,111,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,112,101,114,97,116,111,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,112,101,114,97, +116,111,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51, +44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,98,116,110,65,100,100,67,111,108,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,67,111,108,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,53,48,44,45,49,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116, +117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99, +116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_27 = 13557; +static unsigned char xml_res_file_27[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,74,111,98,34,62,10,32,32,32,32,60,116,105,116,108, +101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,50,48,44,50,56,48,100, +60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120, +68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120, +67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119, +120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,49,54,44,50,53,53,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,73,68,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,73,68,34, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,69,110,97,98,108,101,100,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69, +110,97,98,108,101,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,69,110,97,98,108,101,100, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,74,111,98,99,108,97,115,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,74,111,98,32,99,108,97,115,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,74,111,98, +99,108,97,115,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68, +79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +72,111,115,116,65,103,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,111,115,116,32, +97,103,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,72,111,115,116,65,103,101,110, +116,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,114,101,97,116,101,100,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,114,101,97,116,101,100,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,114,101, +97,116,101,100,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,104,97,110,103,101,100,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,104,97,110,103,101,100,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,104,97, +110,103,101,100,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,78,101,120,116,114,117,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,78,101,120,116,32,114,117,110,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78, +101,120,116,114,117,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,97,115,116,114,117, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,76,97,115,116,32,114,117,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,76,97,115,116,114,117,110,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,97,115, +116,82,101,115,117,108,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76,97,115,116,32,114,101, +115,117,108,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,76,97,115,116,82,101,115,117, +108,116,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76, +73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98, +111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,116,101,112,115,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,83,116,101,112,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114, +111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115, +116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116,83,116,101,112, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120, +76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60, +47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98, +116,110,67,104,97,110,103,101,83,116,101,112,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,104,97,110,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110, +65,100,100,83,116,101,112,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,83,116, +101,112,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107, +112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,83,99,104,101,100,117,108,101,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,83,99,104,101,100,117,108,101,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116, +83,99,104,101,100,117,108,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95, +82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,67,104,97,110,103,101,83,99,104,101, +100,117,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,104,97,110,103,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,98,116,110,65,100,100,83,99,104,101,100,117, +108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,98,116,110,82,101,109,111,118,101,83,99,104,101,100,117,108,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101, +61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69, +71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_28 = 8800; +static unsigned char xml_res_file_28[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,76,97,110,103,117,97,103,101,34,62,10,32,32,32,32, +60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48, +48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +51,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,99,98,78,97,109,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110, +101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,84,114,117,115,116,101,100,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,84,114,117,115,116,101,100,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,84,114, +117,115,116,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49, +60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +72,97,110,100,108,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,97,110,100,108,101,114, +32,102,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,72,97,110,100,108, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,110, +108,105,110,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,73,110,108,105,110,101,32,102,117,110, +99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,73,110,108,105,110,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,86,97,108,105,100,97,116,111,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,86,97,108,105,100,97,116,111,114,32,102,117,110,99, +116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,86,97,108,105,100,97,116,111,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65, +68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97, +116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_29 = 4926; +static unsigned char xml_res_file_29[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,77,97,105,110,67,111,110,102,105,103,34,62,10,32, +32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101, +62,50,52,56,44,49,57,56,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69, +82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, +115,62,50,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,69,110,97,98,108,101, +100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,69,110,97,98,108,101,100,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,69,110,97,98,108,101,100,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,86,97,108,117,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,108, +117,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +116,120,116,86,97,108,117,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +66,111,120,34,32,110,97,109,101,61,34,99,104,107,86,97,108,117,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67, +111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,109,109,101,110,116,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32, +32,60,112,111,115,62,53,44,53,53,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,101,115,99, +114,105,112,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62, +49,48,44,54,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,50,51,56,44,57,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95, +78,79,95,65,85,84,79,82,69,83,73,90,69,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_30 = 2870; +static unsigned char xml_res_file_30[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,77,97,110,97,103,101,70,97,118,111,117,114,105,116, +101,115,34,62,10,32,32,32,32,60,116,105,116,108,101,62,77,97,110,97,103, +101,32,102,97,118,111,117,114,105,116,101,115,60,47,116,105,116,108,101, +62,10,32,32,32,32,60,115,105,122,101,62,50,49,56,44,49,57,56,100,60,47, +115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68, +69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67, +65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119, +120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +99,116,108,84,114,101,101,34,32,110,97,109,101,61,34,116,114,76,111,99, +97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,53,44,55,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,50,48,56,44,49,53,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,82,95, +72,65,83,95,66,85,84,84,79,78,83,32,124,32,119,120,83,73,77,80,76,69,95, +66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +51,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,82,101,110,97,109, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,82,101,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,68,101,108,101,116,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,108,101,116,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,98,116,110,78,101,119,70,111,108,100, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,78,101,119,32,102,111,108,100,101,114,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114, +101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_31 = 4804; +static unsigned char xml_res_file_31[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,77,97,110,97,103,101,77,97,99,114,111,115,34,62,10, +32,32,32,32,60,116,105,116,108,101,62,77,97,110,97,103,101,32,77,97,99, +114,111,115,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109, +101,61,34,108,115,116,75,101,121,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82, +84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119, +120,76,69,70,84,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +109,105,110,115,105,122,101,62,49,53,48,100,60,47,109,105,110,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,53,44,53,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,53,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78, +97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,50,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119, +120,71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,44, +53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108, +83,81,76,66,111,120,34,32,110,97,109,101,61,34,116,120,116,83,113,108,66, +111,120,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,83,85,78,75,69,78,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,66,79,84,84,79,77,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,115,105,122, +101,62,50,48,48,44,49,48,48,100,60,47,109,105,110,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,53,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,44,53,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,67,108,101,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,108,101, +97,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,52,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,44,53,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,83,97,118,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,97,118,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,44,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,62,50,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,50,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,124,119,120,71,82,79,87,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_32 = 3447; +static unsigned char xml_res_file_32[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,114,101, +115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34, +100,108,103,77,111,118,101,84,97,98,108,101,115,112,97,99,101,34,62,10, +32,32,32,32,60,116,105,116,108,101,62,77,111,118,101,32,111,98,106,101, +99,116,115,32,116,111,32,97,110,111,116,104,101,114,32,116,97,98,108,101, +115,112,97,99,101,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105, +122,101,62,50,48,48,44,50,48,48,100,60,47,115,105,122,101,62,10,32,32,32, +32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76, +79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83, +89,83,84,69,77,95,77,69,78,85,60,47,115,116,121,108,101,62,10,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99, +111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101, +114,111,119,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,77,111,118,101,84,111,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,38,97,109,112,59,78,101,119,32,116,97,98, +108,101,115,112,97,99,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,77,111,118,101,84,111,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82, +69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,75,105,110,100,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,79,98,106,101,99,116,115,39,32, +107,105,110,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,75,105,110,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,98,106,101,99,116,115,39,32,111,119,110,101,114, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,119,110,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67, +69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98, +106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_33 = 15920; +static unsigned char xml_res_file_33[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,79,112,101,114,97,116,111,114,34,62,10,32,32,32,32, +60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48, +48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +52,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119,110,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,119,110,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,99,104,101, +109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73, +78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101, +32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,108,117, +115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,76,101,102,116,84,121,112,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76,101,102, +116,32,116,121,112,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,76,101,102,116,84,121,112,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,82,105,103,104,116,84,121,112,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,105, +103,104,116,32,116,121,112,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,82,105,103,104,116, +84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,80,114,111,99,101,100,117,114,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,112,101,114,97,116,111,114,32,102,117,110,99,116,105,111,110, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,80,114,111,99,101,100,117,114,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87, +78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73, +109,112,108,101,109,101,110,116,97,116,105,111,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,50,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,82,101,115,116,114,105,99,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,115,116,114, +105,99,116,32,102,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,82,101,115, +116,114,105,99,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68, +79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +74,111,105,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,74,111,105,110,32,102,117,110,99,116, +105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,99,98,74,111,105,110,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,109,109,117,116,97,116,111,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,111,109,109,117,116,97,116,111,114,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,111,109,109,117,116,97,116,111,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,78,101,103,97,116,111,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78, +101,103,97,116,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,78,101,103,97,116,111,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65, +68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,76,101,102,116,83,111,114,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,76,101,102,116,32,115,111,114,116,32,111,112,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,76,101,102,116,83,111,114,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,82,105,103,104,116,83,111,114,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,82,105,103,104,116,32,115,111,114,116,32,111,112,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,82,105,103,104,116,83,111,114,116,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,76,101,115,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,108,116, +59,32,111,112,101,114,97,116,111,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,76,101,115,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65, +68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,71,114,101,97,116,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,38,103,116,59,32,111,112,101,114,97,116,111,114,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,71,114,101,97,116,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,97,110,72,97,115,104,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +117,112,112,111,114,116,115,32,104,97,115,104,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,67,97, +110,72,97,115,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,97,110,77,101,114,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,117,112,112,111,114, +116,115,32,109,101,114,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,67,97,110,77,101, +114,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_34 = 7045; +static unsigned char xml_res_file_34[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,80,97,99,107,97,103,101,34,62,10,32,32,32,32,60,116, +105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44, +50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, +69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,51,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,79,119,110,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,119,110,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111, +109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97, +100,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,72,101,97,100,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112, +62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,83,81,76,66,111,120,34,32,110,97,109, +101,61,34,116,120,116,72,101,97,100,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,77,85,76,84,73,76,73,78,69,124,119,120,83,85,78,75,69,78,95, +66,79,82,68,69,82,124,119,120,84,69,95,82,73,67,72,50,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,66,111,100,121,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,66,111,100,121,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,83,81,76,66,111,120,34,32,110,97,109,101,61,34,116,120,116,66,111,100, +121,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,124, +119,120,83,85,78,75,69,78,95,66,79,82,68,69,82,124,119,120,84,69,95,82, +73,67,72,50,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_35 = 5366; +static unsigned char xml_res_file_35[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,80,103,112,97,115,115,67,111,110,102,105,103,34,62, +10,32,32,32,32,60,116,105,116,108,101,62,67,108,105,101,110,116,32,65,99, +99,101,115,115,32,67,111,110,102,105,103,117,114,97,116,105,111,110,60, +47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48, +44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,115,105, +122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,69,110, +97,98,108,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,69,110,97,98,108,101,100,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,69,110,97,98,108,101,100,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,72,111, +115,116,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,72,111,115,116,110,97,109,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,72,111,115,116,110,97, +109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,80,111,114,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,80,111,114,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,80,111,114,116,34,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,97,116, +97,98,97,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,68,97,116,97,98,97,115,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108, +34,32,110,97,109,101,61,34,116,120,116,68,97,116,97,98,97,115,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +85,115,101,114,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,85,115,101,114,110,97,109,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, +67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,85,115,101,114,110, +97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,80,97,115,115,119,111,114,100,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,97,115,115,119, +111,114,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,80,97,115,115,119,111,114,100,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,80,65,83,83, +87,79,82,68,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,82,101,80,97,115,115,119,111,114, +100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,80,97,115,115,119,111,114,100,32,40,97,103,97,105,110,41,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, +67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,82,101,80,97,115, +115,119,111,114,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,84,69,95,80,65,83,83,87,79,82,68,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_36 = 3212; +static unsigned char xml_res_file_36[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,114,101, +115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34, +100,108,103,82,101,97,115,115,105,103,110,68,114,111,112,79,119,110,101, +100,34,62,10,32,32,32,32,60,116,105,116,108,101,62,82,101,97,115,115,105, +103,110,47,68,114,111,112,32,79,119,110,101,100,60,47,116,105,116,108,101, +62,10,32,32,32,32,60,115,105,122,101,62,50,48,48,44,50,48,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68, +69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67, +65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,114,98,82,101,97,115,115,105,103,110,84, +111,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,82,101,97,115,115,105,103,110,32,111,98,106,101, +99,116,115,32,116,111,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,82,111,108,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79, +78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,114,98,68,114,111,112,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,38,97,109,112,59,68,114,111,112,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,68,97,116,97,98,97,115,101,115, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,70,114,111,109,32,100,97,116,97,98,97,115,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,68,97,116,97,98,97,115, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60, +47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62, +10}; + +static size_t xml_res_size_37 = 9858; +static unsigned char xml_res_file_37[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,67,108,117,115,116,101,114,34,62,10,32, +32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101, +62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69, +82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,54,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,74,111,105,110, +67,108,117,115,116,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,74,111,105,110,32,101,120, +105,115,116,105,110,103,32,99,108,117,115,116,101,114,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,74,111,105,110,67,108,117,115,116,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,101,114,118,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,101,114,118,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,101,114,118,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,97,116,97,98,97,115, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,97,116,97,98,97,115,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +68,97,116,97,98,97,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,108,117,115,116,101,114,78,97,109,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,108,117,115,116,101,114,32,110,97,109,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,44,49,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,67,108,117,115,116,101,114,78,97,109,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,108,117, +115,116,101,114,78,97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,78,111,100,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +76,111,99,97,108,32,78,111,100,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,78,111,100,101,73,68,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,111,100,101,78,97,109, +101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +65,100,109,105,110,78,111,100,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,109,105,110, +32,78,111,100,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116, +65,100,109,105,110,78,111,100,101,73,68,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +116,120,116,65,100,109,105,110,78,111,100,101,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,65,100,109,105,110,78,111,100,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_38 = 5387; +static unsigned char xml_res_file_38[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,67,108,117,115,116,101,114,85,112,103, +114,97,100,101,34,62,10,32,32,32,32,60,116,105,116,108,101,62,85,112,103, +114,97,100,101,32,99,108,117,115,116,101,114,32,115,111,102,116,119,97, +114,101,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101, +62,50,50,48,44,49,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69, +82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49,50,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,117,114,114,101,110,116,86, +101,114,115,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,117,114,114,101,110,116, +32,118,101,114,115,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,117,114,114, +101,110,116,86,101,114,115,105,111,110,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,101, +114,118,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,83,101,114,118,101,114,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,83,101,114,118,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,68,97,116,97,98,97,115,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68, +97,116,97,98,97,115,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,68,97,116,97,98,97,115,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101, +114,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,108,117,115,116,101,114,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,67,108,117,115,116,101,114,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,86,101,114,115,105,111,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,86,101,114,115,105,111,110,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,86,101,114,115,105,111,110,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_39 = 4038; +static unsigned char xml_res_file_39[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,76,105,115,116,101,110,34,62,10,32,32, +32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62, +50,50,48,44,49,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84, +69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49,50,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,79,114,105,103,105,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,79,114,105,103,105,110,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,114,105,103,105, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,82,101,99,101,105, +118,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,82,101,99,101,105,118,101,114,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,82,101,99,101,105,118,101,114,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,80,114,111,118,105,100,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,80,114,111,118,105,100,101,114,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,80,114,111,118,105,100,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_40 = 3343; +static unsigned char xml_res_file_40[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,78,111,100,101,34,62,10,32,32,32,32,60, +116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,50,48, +44,49,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49,50,53,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,49,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,73,68,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73, +68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,73,68,34,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111, +109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114, +101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_41 = 3939; +static unsigned char xml_res_file_41[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,80,97,116,104,34,62,10,32,32,32,32,60, +116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,50,48, +44,49,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49,50,53,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,101,114,118,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,101,114,118,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,101,114,118,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,110,110,73,110, +102,111,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,110,110,101,99,116,32,105,110,102, +111,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,110,110,73,110,102,111,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,67,111,110,110,82,101,116,114,121,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,110,110,32,114,101,116,114,121,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,67,111,110,110,82,101,116,114,121,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_42 = 4031; +static unsigned char xml_res_file_42[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,83,101,113,117,101,110,99,101,34,62,10, +32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122, +101,62,50,50,48,44,49,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32, +60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79, +71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89, +83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68, +69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111, +107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49, +50,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60, +115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111, +112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114, +111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,62,50,60,47,103,114,111,119,97,98,108,101, +114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,101,113, +117,101,110,99,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,83,101,113,117,101,110,99,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,83,101,113,117,101,110,99,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,68,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,73,68,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114, +101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_43 = 4313; +static unsigned char xml_res_file_43[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,83,101,116,34,62,10,32,32,32,32,60,116, +105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,50,48,44, +49,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, +69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49,50,53,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,50,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,79,114,105,103,105,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,79,114,105,103,105,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53, +44,55,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,79,114,105,103,105,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,55,48, +44,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,68,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,50,50,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,112,111,115,62,55,48,44,50,48,100,60,47,112,111,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,51, +55,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +112,111,115,62,55,48,44,51,53,100,60,47,112,111,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51, +53,44,54,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69, +95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_44 = 3396; +static unsigned char xml_res_file_44[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,83,101,116,77,101,114,103,101,34,62,10, +32,32,32,32,60,116,105,116,108,101,62,77,101,114,103,101,32,115,101,116, +32,105,110,116,111,32,97,110,111,116,104,101,114,32,115,101,116,60,47,116, +105,116,108,101,62,10,32,32,32,32,60,115,105,122,101,62,50,50,48,44,49, +53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101, +62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69, +124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69, +78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49,50,53,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,116,32,116,111, +32,109,101,114,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,73,68,34,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,84,97,114,103,101,116,73,68,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,97,114, +103,101,116,32,111,102,32,109,101,114,103,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,84,97,114,103,101,116,73,68,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_45 = 3381; +static unsigned char xml_res_file_45[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,83,101,116,77,111,118,101,34,62,10,32, +32,32,32,60,116,105,116,108,101,62,77,111,118,101,32,115,101,116,32,116, +111,32,111,116,104,101,114,32,110,111,100,101,60,47,116,105,116,108,101, +62,10,32,32,32,32,60,115,105,122,101,62,50,50,48,44,49,53,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68, +69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67, +65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119, +120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,49,54,44,49,50,53,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,73,68,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,73, +68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,84,97,114,103,101,116,78,111,100,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,84,97,114,103,101,116,32,78,111,100,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,84,97,114,103,101,116,78,111,100,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111, +117,114,99,101,62,10}; + +static size_t xml_res_size_46 = 4740; +static unsigned char xml_res_file_46[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,83,117,98,115,99,114,105,112,116,105,111, +110,34,62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60, +115,105,122,101,62,50,50,48,44,49,53,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68, +73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119, +120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66, +79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111, +119,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98, +111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111, +107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,49, +54,44,49,50,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99, +116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80, +114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110, +108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,114,105,103, +105,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,114,105,103,105,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,79,114,105,103,105,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,82,101,99,101,105,118,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101, +99,101,105,118,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,82,101,99,101,105,118, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,80,114, +111,118,105,100,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,118,105,100,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,80,114,111,118,105,100,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,70,111,114,119,97,114,100,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,97,110,32,102,111,114,119,97,114,100,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,70,111,114,119,97,114,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_47 = 5504; +static unsigned char xml_res_file_47[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,84,97,98,108,101,34,62,10,32,32,32,32, +60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,50, +48,44,49,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49,50,53,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,51,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,84,97,98,108,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,84,97,98,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,84,97,98,108,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,73,68,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,73,68,34, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,73,110,100,101,120,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,100, +101,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,73,110,100,101,120,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84, +114,105,103,103,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,84,114,105, +103,103,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,76,105, +115,116,66,111,120,34,32,110,97,109,101,61,34,99,104,107,84,114,105,103, +103,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,53,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,50,48,48,44,57,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111, +117,114,99,101,62,10}; + +static size_t xml_res_size_48 = 4089; +static unsigned char xml_res_file_48[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,115,111,117,114,99,101,71,114,111,117,112, +34,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,82,101,115,71,114,112,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,71,114,111, +117,112,32,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,80,85,82,97,116,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,80, +85,32,82,97,116,101,32,76,105,109,105,116,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67, +80,85,82,97,116,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,68,105,114,116,121,82,97,116, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,105,114,116,121,32,82,97,116,101,32,76,105,109, +105,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,68,105,114,116,121,82,97,116,101,34, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,49,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50, +49,54,44,50,48,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116, +117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,115,105,122,101, +62,50,50,48,44,50,51,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69, +82,60,47,115,116,121,108,101,62,10,32,32,60,47,111,98,106,101,99,116,62, +10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_49 = 20602; +static unsigned char xml_res_file_49[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,111,108,101,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,55,48,44,50,53,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,54,54,44,50,50,53,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,50,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,111, +108,101,32,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,79,73,68,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73, +78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,80,97,115,115,119,100,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,80,97,115,115,119,111,114,100,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,80, +97,115,115,119,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,80,65,83,83,87, +79,82,68,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +82,101,80,97,115,115,119,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,97,115,115,119,111, +114,100,32,40,97,103,97,105,110,41,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,82,101,80, +97,115,115,119,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,80,65,83,83,87, +79,82,68,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +86,97,108,105,100,85,110,116,105,108,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,99,99,111,117, +110,116,32,101,120,112,105,114,101,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,97,108,101,110,100,97, +114,66,111,120,34,32,110,97,109,101,61,34,100,97,116,86,97,108,105,100, +85,110,116,105,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,68,80,95,65, +76,76,79,87,78,79,78,69,124,119,120,68,80,95,68,82,79,80,68,79,87,78,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,105,109, +101,83,112,105,110,67,116,114,108,34,32,110,97,109,101,61,34,116,105,109, +86,97,108,105,100,85,110,116,105,108,34,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,110,110, +101,99,116,105,111,110,76,105,109,105,116,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,110, +110,101,99,116,105,111,110,32,76,105,109,105,116,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,67,111,110,110,101,99,116,105,111,110,76,105,109,105,116,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,82,111,108,101,32,112,114,105,118, +105,108,101,103,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,82,111,108, +101,115,80,114,105,118,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,67,97,110,76,111,103,105,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,97,110,32,108,111,103,105,110,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,73,110,104,101,114,105,116,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +73,110,104,101,114,105,116,115,32,114,105,103,104,116,115,32,102,114,111, +109,32,112,97,114,101,110,116,32,114,111,108,101,115,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61, +34,99,104,107,83,117,112,101,114,117,115,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +117,112,101,114,117,115,101,114,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,67,114,101,97,116,101,68,66,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,110,32,99,114, +101,97,116,101,32,100,97,116,97,98,97,115,101,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,67,114,101,97,116,101,82,111,108,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,97,110,32,99,114,101,97,116,101,32,114,111,108,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,49,54,54,44,49,50,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34, +32,110,97,109,101,61,34,99,104,107,85,112,100,97,116,101,67,97,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,97,110,32,109,111,100,105,102,121,32,99,97,116,97,108, +111,103,32,100,105,114,101,99,116,108,121,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,82,101,112,108,105,99,97,116,105,111,110,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,97,110,32,105,110,105,116,105,97,116,101,32,115,116,114,101,97, +109,105,110,103,32,114,101,112,108,105,99,97,116,105,111,110,32,97,110, +100,32,98,97,99,107,117,112,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107, +112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,82,111,108,101,32,109,101,109,98,101,114,115,104,105,112,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34, +32,110,97,109,101,61,34,112,110,108,82,111,108,101,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,44,50,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,82,111,108,101,115,78,111,116,73,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,78,111,116,32,77,101,109,98,101,114,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,82,111,108,101,115,73, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,77,101,109,98,101,114,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +76,105,115,116,66,111,120,34,32,110,97,109,101,61,34,108,98,82,111,108, +101,115,78,111,116,73,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +56,54,44,49,50,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +76,66,95,78,69,69,68,69,68,95,83,66,124,119,120,76,66,95,83,79,82,84,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,98,116,110,65,100,100,82,111,108,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,103,116,59,38,103,116,59,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,49,56,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,66,79,84,84,79,77,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116, +110,68,101,108,82,111,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,108,116, +59,38,108,116,59,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +56,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,84, +79,80,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,76,105,115,116,66,111,120,34,32,110,97,109, +101,61,34,108,98,82,111,108,101,115,73,110,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,56,54,44,49,50,51,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,76,66,95,78,69,69,68,69,68,95,83,66,124,119,120,76,66,95, +83,79,82,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,65,100,109,105,110,79,112,116,105,111,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,87,73,84,72,32,65,68,77,73,78,32,79,80,84,73,79,78,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,86,97,114,105,97,98,108,101,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,86,97,114,105,97,98,108,101,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,52,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111, +119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +76,105,115,116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116,86, +97,114,105,97,98,108,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,54,100,60,47,112,111, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76, +67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,48,44,48,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,65,68,68,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,65,100,100,47,67,104,97,110,103,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,112,111,115,62,57,48,44,49,51,50,100,60,47,112,111,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69, +77,79,86,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,53,48,44,49,51,50,100,60, +47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,86,97,114,110,97,109,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,86,97,114,105,97,98,108,101,32,78,97,109,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99, +116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,86, +97,114,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,108,117,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,86,97,114,105,97,98,108,101,32,86,97,108, +117,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,44,49,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,86,97,108,117,101,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,86,97,108,117,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,114, +68,98,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,116,97,98,97, +115,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,86,97,114,68,98,110,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79, +87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_50 = 8283; +static unsigned char xml_res_file_50[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,117,108,101,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,50,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73, +78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,50,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,69,118,101, +110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,69,118,101,110,116,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,82,97,100,105,111,66,111,120,34,32,110,97,109,101,61,34,114, +98,120,69,118,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,83,69,76,69,67,84,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,73,78,83,69,82,84,60,47,105,116,101,109,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +85,80,68,65,84,69,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,68,69,76,69, +84,69,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,105,109,101,110, +115,105,111,110,62,49,60,47,100,105,109,101,110,115,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,82,65,95,83,80,69,67,73,70,89,95,67,79,76,83,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,111,73,110,115,116, +101,97,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,68,111,32,105,110,115,116,101,97,100,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,68,111,73,110,115,116,101,97,100,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,111,110,100,105,116,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,67,111,110,100,105,116,105,111,110,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,116,120,116,67,111,110,100,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,116,97,116,101,109,101,110,116,115,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,83,116,97,116,101,109,101,110,116,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101, +114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99, +116,108,83,81,76,66,111,120,34,32,110,97,109,101,61,34,116,120,116,83,113, +108,66,111,120,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76, +73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79, +87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_51 = 19358; +static unsigned char xml_res_file_51[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,99,104,101,100,117,108,101,34,62,10,32,32,32,32, +60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,50, +48,44,50,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,50,50,53,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +53,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,68,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78, +76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +69,110,97,98,108,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,97,98,108,101,100,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,69,110,97,98,108,101,100,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,83,116,97,114,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,116,97,114, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60, +47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,44,49,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,97,108,101,110,100,97,114,66,111,120,34,32,110,97,109, +101,61,34,99,97,108,83,116,97,114,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,68,80,95,65,76,76,79,87,78,79,78,69,124,119,120,68,80,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,105,109,101,83,112,105,110,67,116,114,108,34,32,110,97,109, +101,61,34,116,105,109,83,116,97,114,116,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,69,110,100,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +69,110,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,44,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,97,108,101,110,100,97,114,66,111,120,34,32, +110,97,109,101,61,34,99,97,108,69,110,100,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,68,80,95,65,76,76,79,87,78,79,78,69,124,119,120,68,80,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,105,109,101,83,112,105,110,67,116,114,108,34,32,110,97,109, +101,61,34,116,105,109,69,110,100,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,121,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108, +34,32,110,97,109,101,61,34,112,110,108,68,97,121,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,50,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,87,101,101,107,100,97,121,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,87, +101,101,107,32,68,97,121,115,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, +109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110, +87,101,101,107,100,97,121,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65, +85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,66,79,84,84,79,77,124,119,120,65,76,73,71,78, +95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,76,105,115,116,66,111,120,34,32,110,97,109,101,61,34, +99,104,107,87,101,101,107,100,97,121,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,45,49,44,55, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,83,117,110,100,97,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,77, +111,110,100,97,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,84,117, +101,115,100,97,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,87,101, +100,110,101,115,100,97,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,84, +104,117,114,115,100,97,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,70, +114,105,100,97,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,83,97,116, +117,114,100,97,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,77,111,110,116,104,100,97,121,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,77,111,110,116,104,32,68,97,121,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,98,116,110,77,111,110,116,104,100,97,121,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,66,79,84,84,79,77,124,119, +120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,76,105,115,116,66,111,120,34,32, +110,97,109,101,61,34,99,104,107,77,111,110,116,104,100,97,121,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,45,49,44,55,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,105,116,101,109,62,49,115,116,60,47,105,116,101,109,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101, +109,62,50,110,100,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,51,114,100, +60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,105,116,101,109,62,52,116,104,60,47,105,116,101, +109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,105,116,101,109,62,53,116,104,60,47,105,116,101,109,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101, +109,62,54,116,104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,55,116,104, +60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,105,116,101,109,62,56,116,104,60,47,105,116,101, +109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,105,116,101,109,62,57,116,104,60,47,105,116,101,109,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101, +109,62,49,48,116,104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,49,49,116, +104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,49,50,116,104,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,49,51,116,104,60,47,105,116,101,109,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +105,116,101,109,62,49,52,116,104,60,47,105,116,101,109,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,49,53,116,104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,49,54,116, +104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,49,55,116,104,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,49,56,116,104,60,47,105,116,101,109,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +105,116,101,109,62,49,57,116,104,60,47,105,116,101,109,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,50,48,116,104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,50,49,115, +116,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,50,50,110,100,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,50,51,114,100,60,47,105,116,101,109,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +105,116,101,109,62,50,52,116,104,60,47,105,116,101,109,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,50,53,116,104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,50,54,116, +104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,50,55,116,104,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,50,56,116,104,60,47,105,116,101,109,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +105,116,101,109,62,50,57,116,104,60,47,105,116,101,109,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,51,48,116,104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,51,49,115, +116,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,76,97,115,116,32,100,97, +121,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,77,111,110,116,104,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,111, +110,116,104,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105, +116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116, +110,77,111,110,116,104,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85, +84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,66,79,84,84,79,77,124,119,120,65,76,73,71,78,95,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,76,105,115,116,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,77,111,110,116,104,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,74,97,110,117,97,114,121,60,47,105,116,101,109,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +70,101,98,114,117,97,114,121,60,47,105,116,101,109,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +77,97,114,99,104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,65,112,114, +105,108,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,77,97,121,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,74,117,110,101,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,74,117,108,121,60,47,105,116,101,109,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,65,117,103,117,115,116,60,47,105,116,101,109,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101, +109,62,83,101,112,116,101,109,98,101,114,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,79,99,116,111,98,101,114,60,47,105,116,101,109,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101, +109,62,78,111,118,101,109,98,101,114,60,47,105,116,101,109,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,68,101,99,101,109,98,101,114,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,84,105,109,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,84,105,109, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,50,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,72,111,117,114,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,111,117,114,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,72,111,117, +114,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,66,79,84,84,79,77,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,76, +105,115,116,66,111,120,34,32,110,97,109,101,61,34,99,104,107,72,111,117, +114,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,45,49,44,49,48,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,77,105, +110,117,116,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,77,105,110,117,116,101,115,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,77,105,110,117, +116,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65, +87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,66,79,84,84,79,77,124,119,120,65,76,73,71,78,95,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +76,105,115,116,66,111,120,34,32,110,97,109,101,61,34,99,104,107,77,105, +110,117,116,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,69,120,99,101,112,116,105,111,110, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,69,120,99,101,112,116,105,111, +110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34,32, +110,97,109,101,61,34,108,115,116,69,120,99,101,112,116,105,111,110,115, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76, +67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,44,51,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,68,97,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,116,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,97,108,101,110,100,97,114,66,111,120,34,32, +110,97,109,101,61,34,99,97,108,69,120,99,101,112,116,105,111,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,68,80,95,65,76,76,79,87,78,79,78,69, +124,119,120,68,80,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,84,105,109,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,84,105,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,105,109,101, +83,112,105,110,67,116,114,108,34,32,110,97,109,101,61,34,116,105,109,69, +120,99,101,112,116,105,111,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,67,104,97,110,103,101,69,120,99,101,112,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,104,97,110,103,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,98,116,110,65,100,100,69,120,99,101,112,116,105,111,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116, +110,82,101,109,111,118,101,69,120,99,101,112,116,105,111,110,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_52 = 5520; +static unsigned char xml_res_file_52[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,99,104,101,109,97,34,62,10,32,32,32,32,60,116, +105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44, +50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, +69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,51,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78, +97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119, +110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_53 = 7618; +static unsigned char xml_res_file_53[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,101,97,114,99,104,79,98,106,101,99,116,34,62,10, +32,32,32,32,60,116,105,116,108,101,62,83,101,97,114,99,104,32,79,98,106, +101,99,116,115,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122, +101,62,51,53,51,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32, +60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79, +71,95,83,84,89,76,69,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, +119,115,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,124,119,120,65,76,76, +124,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,71,114,105,100,66,97,103,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,51,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,51,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,101,108,108,112,111,115,62,48,44,48,60, +47,99,101,108,108,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,101,108,108,115,112,97,110,62,49,44,49,60,47,99,101,108,108,115,112, +97,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,84,79,80,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,80,97,116,116,101,114,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,80,97,116,116,101,114,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,101,108,108,112,111,115,62,48,44,49,60, +47,99,101,108,108,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,101,108,108,115,112,97,110,62,49,44,49,60,47,99,101,108,108,115,112, +97,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115, +62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114, +111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,69,88,80,65,78,68,124,119,120,76,69,70,84,124,119, +120,84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,80,97,116,116,101,114,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, +111,108,116,105,112,62,69,110,116,101,114,32,112,97,114,116,32,111,102, +32,116,104,101,32,111,98,106,101,99,116,39,115,32,97,116,116,114,105,98, +117,116,101,32,121,111,117,39,114,101,32,108,111,111,107,105,110,103,32, +102,111,114,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110, +83,101,97,114,99,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,70,105,110,100,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100, +101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,101,108,108,112,111,115,62,49,44,48,60,47,99,101,108, +108,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,101,108, +108,115,112,97,110,62,49,44,49,60,47,99,101,108,108,115,112,97,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,124,119,120,84,79,80,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,84, +121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,84,121,112,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +101,108,108,112,111,115,62,49,44,49,60,47,99,101,108,108,112,111,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,101,108,108,115,112,97,110, +62,49,44,49,60,47,99,101,108,108,115,112,97,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,66,79,84,84,79,77,124,119, +120,69,88,80,65,78,68,124,119,120,76,69,70,84,124,119,120,84,79,80,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,84,121, +112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,55,48,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,101,108,108,112,111,115, +62,50,44,48,60,47,99,101,108,108,112,111,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,101,108,108,115,112,97,110,62,49,44,49,60,47,99,101, +108,108,115,112,97,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119, +120,84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,99,104,101,109,97,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,101,108,108,112,111,115,62,50,44, +49,60,47,99,101,108,108,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,101,108,108,115,112,97,110,62,49,44,49,60,47,99,101,108,108, +115,112,97,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,66,79,84,84,79,77,124,119,120,69,88,80,65,78,68,124,119, +120,76,69,70,84,124,119,120,84,79,80,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109,97,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76, +89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,50,55,48,44,45,49,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,101,108,108,112,111,115,62,51,44,48,60,47, +99,101,108,108,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,101,108,108,115,112,97,110,62,49,44,49,60,47,99,101,108,108,115,112, +97,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,84,79,80,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,82,101,115,117,108,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,82,101,115,117,108,116,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,101,108,108,112,111,115,62,51,44,49,60, +47,99,101,108,108,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,101,108,108,115,112,97,110,62,49,44,50,60,47,99,101,108,108,115,112, +97,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115, +62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114, +111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101, +61,34,108,99,82,101,115,117,108,116,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,52,48,44,49,53,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82, +84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,101,108,108, +112,111,115,62,48,44,50,60,47,99,101,108,108,112,111,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,101,108,108,115,112,97,110,62,51,44,49, +60,47,99,101,108,108,115,112,97,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,72,79,82,73,90,79,78,84,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,76,69,70,84,124,119,120, +84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,78,97,109,101,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +110,97,109,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47, +99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,76,69,70,84,124,119,120,84,79,80,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,68,101,102,105,110,105,116,105,111,110,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,100,101, +102,105,110,105,116,105,111,110,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101, +100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,76,69,70,84,124,119,120,84,79,80,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,67,111,109,109,101,110,116,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,99,111, +109,109,101,110,116,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48, +60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,108,111,115,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32, +110,97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84, +95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114, +101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_54 = 1165; +static unsigned char xml_res_file_54[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,101,108,101,99,116,67,111,110,110,101,99,116,105, +111,110,34,62,10,32,32,32,32,60,116,105,116,108,101,62,67,111,110,110,101, +99,116,32,116,111,32,83,101,114,118,101,114,60,47,116,105,116,108,101,62, +10,32,32,32,32,60,115,105,122,101,62,50,48,53,44,57,56,100,60,47,115,105, +122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65, +85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84, +73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,60,47,115,116,121, +108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,83,101,114,118,101,114,34,62,10,32,32,32,32,32,32,60,108, +97,98,101,108,62,83,101,114,118,101,114,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,60,112,111,115,62,53,44,55,100,60,47,112,111,115,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,68,97,116,97,98,97,115,101,34,62, +10,32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,116,97,98,97,115,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,53,44, +50,50,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,85,115,101,114,110,97,109,101,34,62,10,32,32,32,32,32,32,60,108,97, +98,101,108,62,85,115,101,114,110,97,109,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,60,112,111,115,62,53,44,51,55,100,60,47,112,111,115, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,82,111,108,101,110, +97,109,101,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,82,111,108, +101,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112, +111,115,62,53,44,53,52,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,60,108,97,98, +101,108,62,38,97,109,112,59,72,101,108,112,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,60,112,111,115,62,50,44,56,48,100,60,47,112,111,115,62, +10,32,32,32,32,32,32,60,115,116,121,108,101,47,62,10,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,60,112,111,115,62,57,55,44,56,48,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,60,115,116,121,108,101,47,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,60,112, +111,115,62,49,53,48,44,56,48,100,60,47,112,111,115,62,10,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10, +60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_55 = 10154; +static unsigned char xml_res_file_55[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,101,113,117,101,110,99,101,34,62,10,32,32,32,32, +60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48, +48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +52,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119,110,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,119,110,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,99,104,101, +109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73, +78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101, +32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,50,52,55, +100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,112,111,115,62,55,48,44,50,52,53,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,73,110,99,114,101,109,101,110, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,73,110,99,114,101,109,101,110,116,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,73,110,99,114,101,109,101,110,116,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +83,116,97,114,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,83,116,97,114,116,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,83,116,97,114,116,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,77,105,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,77,105,110,105,109,117,109,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,77,105,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,77,97,120,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,77,97,120,105,109,117,109,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,77,97,120,34, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,97,99,104,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,99,104, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,97,99,104,101,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,121,99,108,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,121,99,108,101,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,67,121,99,108,101,100,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_56 = 24087; +static unsigned char xml_res_file_56[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,101,114,118,101,114,34,62,10,32,32,32,32,60,116, +105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44, +50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, +69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,68,101,115,99,114,105,112,116,105,111,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,68,101,115,99, +114,105,112,116,105,111,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,72,111,115,116,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,80,111,114,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,111,114, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,80,111,114,116,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +83,101,114,118,105,99,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,114,118,105,99,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,83,101,114,118,105,99,101,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,68,97,116,97,98,97,115,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,105,110, +116,101,110,97,110,99,101,32,68,66,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,68,97,116,97,98, +97,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,85,115,101,114,110,97,109,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +85,115,101,114,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,85,115,101,114, +110,97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,80,97,115,115,119,111,114,100,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,80,97,115,115,119,111,114,100,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,80,97,115,115,119,111,114,100,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84, +69,95,80,65,83,83,87,79,82,68,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,83,116,111,114,101,80,119,100,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +83,116,111,114,101,32,112,97,115,115,119,111,114,100,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,83,116,111,114,101,80,119,100,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101, +100,62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,108,111,117,114,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,108,111,117,114, +80,105,99,107,101,114,34,32,110,97,109,101,61,34,99,111,108,111,117,114, +80,105,99,107,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,71,114, +111,117,112,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,71,114,111,117,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +71,114,111,117,112,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68, +79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,83,83,76,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110, +108,83,83,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,83,76,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,83,76, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,83,83,76,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,83,76,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,83,76, +82,111,111,116,67,101,114,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,114,118,101,114, +32,82,111,111,116,32,67,101,114,116,105,102,105,99,97,116,101,32,70,105, +108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,105,108,101,80,105,99,107,101, +114,67,116,114,108,34,32,110,97,109,101,61,34,112,105,99,107,101,114,83, +83,76,82,111,111,116,67,101,114,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,109,101,115,115,97,103,101,62,83,101, +108,101,99,116,32,83,83,76,32,82,111,111,116,32,67,101,114,116,105,102, +105,99,97,116,101,32,70,105,108,101,60,47,109,101,115,115,97,103,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,105, +108,100,99,97,114,100,62,42,46,99,114,116,60,47,119,105,108,100,99,97,114, +100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84, +82,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +83,83,76,67,114,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,114,118,101,114,32,67, +101,114,116,105,102,105,99,97,116,101,32,82,101,118,111,99,97,116,105,111, +110,32,76,105,115,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,105,108,101,80,105, +99,107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105,99,107, +101,114,83,83,76,67,114,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,109,101,115,115,97,103,101,62,83,101,108,101, +99,116,32,83,83,76,32,67,101,114,116,105,102,105,99,97,116,101,32,82,101, +118,111,99,97,116,105,111,110,32,76,105,115,116,32,70,105,108,101,60,47, +109,101,115,115,97,103,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,119,105,108,100,99,97,114,100,62,42,46,99,114,108, +60,47,119,105,108,100,99,97,114,100,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,70,76,80, +95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,83,76,67,101,114,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,108,105,101,110,116,32,67,101,114,116,105,102,105,99,97,116,101, +32,70,105,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,105,108,101,80,105,99, +107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105,99,107,101, +114,83,83,76,67,101,114,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,109,101,115,115,97,103,101,62,83,101,108,101, +99,116,32,83,83,76,32,99,101,114,116,105,102,105,99,97,116,101,32,102,105, +108,101,60,47,109,101,115,115,97,103,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,119,105,108,100,99,97,114,100,62, +42,46,99,114,116,60,47,119,105,108,100,99,97,114,100,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,83,76,75,101,121,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,108,105,101,110,116,32,75,101,121,32,70,105,108,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,105,108,101,80,105,99,107,101,114,67,116,114, +108,34,32,110,97,109,101,61,34,112,105,99,107,101,114,83,83,76,75,101,121, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +109,101,115,115,97,103,101,62,83,101,108,101,99,116,32,83,83,76,32,107, +101,121,32,102,105,108,101,60,47,109,101,115,115,97,103,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,105,108,100, +99,97,114,100,62,42,46,107,101,121,60,47,119,105,108,100,99,97,114,100, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84,82, +76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,83,76, +67,111,109,112,114,101,115,115,105,111,110,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,83,76, +32,67,111,109,112,114,101,115,115,105,111,110,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,83, +76,67,111,109,112,114,101,115,115,105,111,110,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101, +99,107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98, +111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,83,72,32,84,117,110,110,101,108,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,83,83,72,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,83,72,84,117,110, +110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,85,115,101,32,83,83,72,32,116,117,110, +110,101,108,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,83,72,84,117,110,110, +101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104, +101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,117,110,110,101, +108,72,111,115,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,84,117,110,110,101,108,32,104,111, +115,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,84,117,110,110,101,108,72,111,115,116, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,84,117,110,110,101,108,80,111,114,116,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,84,117,110,110,101,108,32,112,111,114,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,84,117,110,110,101,108,80,111,114,116,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +84,117,110,110,101,108,85,115,101,114,110,97,109,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,85,115,101,114,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,84,117,110, +110,101,108,85,115,101,114,110,97,109,101,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +65,117,116,104,101,110,116,105,99,97,116,105,111,110,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,65,117,116,104,101,110,116,105,99,97,116,105,111,110,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,49,48,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,49,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +114,97,100,105,111,66,116,110,80,97,115,115,119,111,114,100,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,80,97,115,115,119,111,114,100,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100, +105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,114,97,100,105, +111,66,116,110,75,101,121,102,105,108,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,73,100,101,110,116,105,116,121,32,102,105,108,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,100,101,110, +116,105,116,121,70,105,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,100,101,110,116,105, +116,121,32,102,105,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,105,108, +101,80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112, +105,99,107,101,114,73,100,101,110,116,105,116,121,70,105,108,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,101, +115,115,97,103,101,62,83,101,108,101,99,116,32,105,100,101,110,116,105, +116,121,32,102,105,108,101,60,47,109,101,115,115,97,103,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,105,108,100, +99,97,114,100,62,42,60,47,119,105,108,100,99,97,114,100,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,80,117,98,108,105,99,75,101, +121,70,105,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,117,98,108,105,99,32,107,101, +121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,105,108,101,80,105,99,107,101,114,67, +116,114,108,34,32,110,97,109,101,61,34,112,105,99,107,101,114,80,117,98, +108,105,99,75,101,121,70,105,108,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,109,101,115,115,97,103,101,62,83,101, +108,101,99,116,32,112,117,98,108,105,99,32,107,101,121,32,102,105,108,101, +60,47,109,101,115,115,97,103,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,119,105,108,100,99,97,114,100,62,42,46,112, +117,98,60,47,119,105,108,100,99,97,114,100,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,70, +76,80,95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,84,117,110,110,101,108,80,97,115,115, +119,111,114,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,80,97,115,115,119,111,114,100,47,80, +97,115,115,112,104,114,97,115,101,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,84,117,110, +110,101,108,80,97,115,115,119,111,114,100,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +84,69,95,80,65,83,83,87,79,82,68,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,65,100,118,97,110,99,101,100,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,79,112,116,105,111,110,97,108,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,62,52,60,47,103,114,111,119,97,98, +108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,72,111,115,116,65,100,100,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,111,115, +116,32,65,100,100,114,101,115,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,72,111,115, +116,65,100,100,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,84,114,121,67,111,110,110,101, +99,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,67,111,110,110,101,99,116,32,110,111,119,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,84,114,121,67,111,110,110,101,99,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,82,101,115,116,111,114,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,82,101,115,116,111,114,101,32,101,110,118,63,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,82,101,115,116,111,114,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +82,111,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,111,108,101,110,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,82,111,108,101,110,97,109,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,68,98,82,101,115,116,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68, +66,32,114,101,115,116,114,105,99,116,105,111,110,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,68,98,82,101,115,116,114,105,99,116,105,111,110,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,83,101,114,118,105,99,101,73,68, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,83,101,114,118,105,99,101,32,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,116,120,116,83,101,114,118,105,99,101,73,68,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97, +116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_57 = 10963; +static unsigned char xml_res_file_57[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,116,101,112,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,55,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,73,68,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,73,68,34, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,69,110,97,98,108,101,100,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69, +110,97,98,108,101,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,69,110,97,98,108,101,100, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107, +101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,110,110,84,121,112,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,67,111,110,110,101,99,116,105,111,110,32,84,121,112, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105, +111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,114,98,76,111,99, +97,108,67,111,110,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82,66,95, +71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +76,111,99,97,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,101,110,97,98,108,101, +62,48,60,47,101,110,97,98,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,114,98,82,101,109,111,116, +101,67,111,110,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,116,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,101,110,97,98,108,101,62,48,60,47,101, +110,97,98,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +68,97,116,97,98,97,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,116,97,98,97,115, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,68,97,116,97,98, +97,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87, +78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,101,110,97,98,108,101,62,48,60,47,101,110,97, +98,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111, +114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,110,110,83,116,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,111,110,110,101,99,116,105,111,110,32,83,116,114,105,110, +103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,84,79,80,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,67,111,110,110,83,116,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,101,110,97, +98,108,101,62,48,60,47,101,110,97,98,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,83,101,108,68,97,116,97,98,97,115,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,101,110,97,98,108, +101,62,48,60,47,101,110,97,98,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,53, +44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,111, +120,34,32,110,97,109,101,61,34,114,98,120,75,105,110,100,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,83,81,76,60,47,105,116,101,109,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105, +116,101,109,62,66,97,116,99,104,60,47,105,116,101,109,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101, +110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,101,108,101,99,116,105,111,110,62,48,60,47,115,101,108,101,99, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,75,105,110,100,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100, +105,109,101,110,115,105,111,110,62,49,60,47,100,105,109,101,110,115,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,82,65,95,83,80,69,67,73,70,89,95,67, +79,76,83,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,111,120,34, +32,110,97,109,101,61,34,114,98,120,79,110,69,114,114,111,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,110,32,101,114,114,111,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,105,111,110,62,48,60,47,115,101,108,101,99,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,105,116,101,109,62,70,97,105,108,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,83,117,99,99,101,101,100,60,47,105,116,101,109,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +105,116,101,109,62,73,103,110,111,114,101,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,100,105,109,101,110,115,105,111,110,62,49,60,47,100,105,109, +101,110,115,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82,65,95,83,80,69,67, +73,70,89,95,67,79,76,83,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111, +109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67, +111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76, +84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,83,113,108,66,111,120,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101, +61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69, +71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_58 = 7474; +static unsigned char xml_res_file_58[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,121,110,111,110,121,109,34,62,10,32,32,32,32,60, +116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48, +44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,50,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67, +111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76, +84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,84,97,114,103,101,116,84,121,112,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,84,97,114,103,101,116,32,116,121,112,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,84,97,114,103,101,116,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,84,97,114,103,101,116,83,99,104,101,109,97,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,84,97,114,103,101,116,32,115,99,104,101,109,97,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,84,97,114,103,101,116,83,99,104,101,109,97,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,84,97,114,103,101,116,79,98,106, +101,99,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,84,97,114,103,101,116,32,111,98,106,101, +99,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,84,97,114,103,101,116,79,98,106,101,99,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,53,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97, +116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_59 = 40708; +static unsigned char xml_res_file_59[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,97,98,108,101,34,62,10,32,32,32,32,60,116,105, +116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,53,48,44,50,54, +53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62, +119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124, +119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78, +85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121, +108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101, +61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,51,52,54,44,50,52,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100, +62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,52,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119, +110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,99,104,101, +109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,83,99,104,101,109,97,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101, +102,105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108, +68,101,102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,97,98,108,101,115, +112,97,99,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,84,97,98,108,101,115,112,97,99,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,84,97,98,108,101,115,112,97,99,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,79,102,84,121,112,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,102,32,116,121,112,101,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,102,84,121, +112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,70,105,108,108,70,97,99,116,111,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,70,105,108,108,32,70,97,99,116,111,114,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70, +105,108,108,70,97,99,116,111,114,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,72,97,115, +79,105,100,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,72,97,115,32,79,73,68,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,72,97,115,79,105,100,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101, +99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,85,110,108,111,103,103,101,100,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,85,110,108,111,103,103,101,100,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,85,110,108, +111,103,103,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48, +60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +73,110,104,101,114,105,116,115,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,73, +110,104,101,114,105,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115, +116,66,111,120,34,32,110,97,109,101,61,34,108,98,84,97,98,108,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,84,97,98,108, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,65,100, +100,84,97,98,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,84,97,98,108, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,76,105,107,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,76,105,107,101,82,101,108,97,116,105,111,110,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,76,105,107,101,82,101,108,97,116,105,111,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82, +101,108,97,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,76,105,107,101,82,101, +108,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,73,110,99,108,117,100,105,110,103,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110, +99,108,117,100,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,73,110,99,108,117, +100,105,110,103,68,101,102,97,117,108,116,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101, +102,97,117,108,116,32,118,97,108,117,101,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104, +101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,73,110,99,108,117, +100,105,110,103,67,111,110,115,116,114,97,105,110,116,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,111,110,115,116,114,97,105,110,116,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105, +122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,73,110,99,108, +117,100,105,110,103,73,110,100,101,120,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73, +110,100,101,120,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,73,110,99,108,117,100,105,110,103, +83,116,111,114,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,116,111,114,97,103,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99, +107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99, +104,107,73,110,99,108,117,100,105,110,103,67,111,109,109,101,110,116,115, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,67,111,109,109,101,110,116,115,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,67,111,108,117,109,110,115,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,67,111,108,117,109,110,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101, +114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116, +67,111,108,117,109,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69, +80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,67,104,97,110,103,101,67,111,108,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,104,97,110,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110, +65,100,100,67,111,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,67,111,108,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,53,48,44,45,49,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67, +111,110,115,116,114,97,105,110,116,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,67,111,110,115,116,114,97,105,110,116,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98, +108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61,34,108, +115,116,67,111,110,115,116,114,97,105,110,116,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50, +55,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76, +67,95,82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69, +76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79, +87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,53,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98, +111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,111,110,115,116,114, +84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,65,100,100,67,111,110,115,116,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,82,101,109,111,118,101,67,111,110,115,116,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79,87,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,65,117,116,111,45,118,97,99,117,117,109,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,86,97,99,117,117,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101, +108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98, +111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,84,97,98,108,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,67,117,115,116,111,109,86,97,99,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,117,115,116,111,109,32,97,117,116,111,45,118,97,99,117, +117,109,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44, +51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,99,69,110,97,98, +108,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,97,98,108,101,100,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,86,97,99,69,110,97,98,108,101,100,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,117,114,114,101, +110,116,32,118,97,108,117,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,66,97,115, +101,86,97,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,67,85,85,77,32,98,97, +115,101,32,116,104,114,101,115,104,111,108,100,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116, +66,97,115,101,86,97,99,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,66,97,115,101,86,97,99,67,117, +114,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,66,97,115,101,65,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,65,78,65,76,89,90,69,32,98,97,115,101, +32,116,104,114,101,115,104,111,108,100,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,66,97,115, +101,65,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,66,97,115,101,65,110,67,117,114,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,70,97,99,116,111,114,86,97,99,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,86,65,67,85,85,77,32,115,99,97,108,101,32,102,97, +99,116,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,70,97,99,116,111,114,86,97,99, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,70,97,99,116,111,114,86,97,99,67,117,114,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,70,97,99,116,111,114,65,110,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,65,78,65,76,89,90,69,32,115,99,97,108,101,32,102,97,99, +116,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,70,97,99,116,111,114,65,110, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,70,97,99,116,111,114,65,110,67,117,114,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,86,97,99,68,101,108,97,121,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,86,65,67,85,85,77,32,99,111,115,116,32,100,101,108,97,121,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,116,120,116,86,97,99,68,101,108,97,121,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,99, +68,101,108,97,121,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +86,97,99,76,105,109,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,67,85, +85,77,32,99,111,115,116,32,108,105,109,105,116,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116, +86,97,99,76,105,109,105,116,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,86,97,99,76,105,109,105,116, +67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,114,101,101, +122,101,77,105,110,65,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,82,69, +69,90,69,32,109,105,110,105,109,117,109,32,97,103,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,70,114,101,101,122,101,77,105,110,65,103,101,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,114, +101,101,122,101,77,105,110,65,103,101,67,117,114,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,70,114,101,101,122,101,77,97,120,65,103,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,70,82,69,69,90,69,32,109,97,120,105,109,117, +109,32,97,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,114,101, +101,122,101,77,97,120,65,103,101,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,114, +101,101,122,101,77,97,120,65,103,101,67,117,114,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,70,114,101,101,122,101,84,97, +98,108,101,65,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,82,69,69,90,69, +32,116,97,98,108,101,32,97,103,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +116,120,116,70,114,101,101,122,101,84,97,98,108,101,65,103,101,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,70,114,101,101,122,101,84,97,98,108,101,65, +103,101,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,32,110,97,109,101,61,34,110, +98,112,84,111,97,115,116,86,97,99,117,117,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,111,97,115,116, +32,116,97,98,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,67,117,115,116, +111,109,84,111,97,115,116,86,97,99,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67, +117,115,116,111,109,32,97,117,116,111,45,118,97,99,117,117,109,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,84,111,97,115,116,86,97,99,69,110,97,98,108,101, +100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,69,110,97,98,108,101,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,84,111,97,115,116,86,97,99,69,110,97,98,108,101,100, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,117,114, +114,101,110,116,32,118,97,108,117,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,66,97,115, +101,84,111,97,115,116,86,97,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,67, +85,85,77,32,98,97,115,101,32,116,104,114,101,115,104,111,108,100,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,66,97,115,101,84,111,97,115,116,86,97,99,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,66,97,115,101,84,111,97,115,116,86,97,99,67,117,114,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,70,97,99,116,111,114,84,111,97,115,116,86, +97,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,86,65,67,85,85,77,32,115,99,97,108, +101,32,102,97,99,116,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,97,99,116, +111,114,84,111,97,115,116,86,97,99,34,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,97,99,116,111,114, +84,111,97,115,116,86,97,99,67,117,114,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,84,111,97,115,116,86,97,99,68,101,108,97,121,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,65,67,85,85,77,32,99,111,115,116,32,100,101,108,97, +121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,84,111,97,115,116,86,97,99,68,101,108,97,121, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,84,111,97,115,116,86,97,99,68,101,108,97,121,67,117,114,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,86,97,99,76, +105,109,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,67,85,85,77,32,99, +111,115,116,32,108,105,109,105,116,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,84,111,97, +115,116,86,97,99,76,105,109,105,116,34,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,86, +97,99,76,105,109,105,116,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,84,111,97,115,116,70,114,101,101,122,101,77,105,110,65,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,70,82,69,69,90,69,32,109,105,110,105,109,117, +109,32,97,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,84,111,97,115,116,70,114, +101,101,122,101,77,105,110,65,103,101,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,70, +114,101,101,122,101,77,105,110,65,103,101,67,117,114,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,84,111,97,115,116,70,114,101,101,122,101,77,97, +120,65,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,82,69,69,90,69,32,109, +97,120,105,109,117,109,32,97,103,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +116,120,116,84,111,97,115,116,70,114,101,101,122,101,77,97,120,65,103,101, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,70,114,101,101,122, +101,77,97,120,65,103,101,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,84,111,97,115,116,70,114,101,101,122,101,84, +97,98,108,101,65,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,82,69,69,90, +69,32,116,97,98,108,101,32,97,103,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +116,120,116,84,111,97,115,116,70,114,101,101,122,101,84,97,98,108,101,65, +103,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,70,114,101, +101,122,101,84,97,98,108,101,65,103,101,67,117,114,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97, +116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_60 = 10511; +static unsigned char xml_res_file_60[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,97,98,108,101,115,112,97,99,101,34,62,10,32,32, +32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62, +51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84, +69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,51,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62, +53,44,55,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,116,120,116,78,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,55,48,44, +53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110, +101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,51,55,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62, +55,48,44,51,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111, +109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,53,50,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112, +111,115,62,55,48,44,53,48,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,76,111,99,97,116,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,76,111,99,97,116,105,111,110,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112, +111,115,62,53,44,50,50,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,76,111,99,97,116,105,111, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,112,111,115,62,55,48,44,50,48,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98, +111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,86,97,114,105,97,98,108,101,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,86,97,114,105,97,98,108,101,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,52,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61, +34,108,115,116,86,97,114,105,97,98,108,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,54, +100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82, +84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79, +87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,112,111,115,62,48,44,48,100,60,47,112,111,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,65,68, +68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,65,100,100,47,67,104,97,110,103,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,77,79,86,69,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,86,97,114,110,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,97,114,105,97,98,108,101,32,78,97,109,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,86,97,114,110,97,109,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80, +68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,114,105,97,98, +108,101,32,86,97,108,117,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,44,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,86,97,108,117,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,86,97,108,117,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82, +79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79,87,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_61 = 12794; +static unsigned char xml_res_file_61[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,101,120,116,83,101,97,114,99,104,67,111,110,102, +105,103,117,114,97,116,105,111,110,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,52,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119, +110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,99,104,101,109,97,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,83,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109, +97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82, +69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53, +44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95, +77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,80,97,114,115,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80, +97,114,115,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,80,97,114,115,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,112,121,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,111,112,121,32,67,111,110,102,105,103,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,67,111,112,121,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,84,111,107,101,110,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61, +34,112,110,108,84,111,107,101,110,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61, +34,108,115,116,84,111,107,101,110,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,55,48,44,49,53,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82,84, +124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,56,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,84,111,107,101,110,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84, +111,107,101,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,84,111,107,101,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,68,105,99,116,105,111,110,97,114,121,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,105,99,116,105,111,110,97,114,105,101,115,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,68,105,99,116,105,111,110,97,114,121,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,49,49,49,44,45,49,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,111,105,99,101,34,32,110,97,109,101,61,34,99,98,68,105,99,116,105, +111,110,97,114,121,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,54,44,45, +49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,66,79,84,84,79,77,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,72,79,82,73,90,79,78,84,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69, +77,79,86,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,51,44,53,56,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +65,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,47,67,104,97,110,103, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,51,44,55,56,100,60, +47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,44,50,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,55,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,50,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97, +109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102, +97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,124,119,120,71,82,79,87,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117, +115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117, +115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79,87,124,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10, +60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_62 = 11304; +static unsigned char xml_res_file_62[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,101,120,116,83,101,97,114,99,104,68,105,99,116, +105,111,110,97,114,121,34,62,10,32,32,32,32,60,116,105,116,108,101,47,62, +10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53,100,60,47,115, +105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70, +65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80, +84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82, +69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101, +114,111,119,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78, +111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47, +115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,52,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110, +101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,99,104,101,109,97,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,83,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109, +97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82, +69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53, +44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95, +77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,84,101,109,112,108,97,116,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,84,101,109,112,108,97,116,101,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,84,101,109,112, +108,97,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44, +45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,112,116,105,111,110,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61, +34,108,115,116,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,55,48,44,49,53, +100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82, +84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,56,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,112,116,105,111,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,112,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116, +79,112,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,108, +117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,108,117,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,66,79,84,84,79,77,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,72,79,82,73,90,79,78,84,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,77,79,86, +69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,112,111,115,62,49,51,44,53,56,100,60,47,112,111,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119, +120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,65,68,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,65,100,100,47,67,104,97,110,103,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,112,111,115,62,49,51,44,55,56,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,50,44,50,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,55, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,50,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,124,119,120,71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114, +34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,71,82,79,87,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114, +101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_63 = 10694; +static unsigned char xml_res_file_63[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,101,120,116,83,101,97,114,99,104,80,97,114,115, +101,114,34,62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32, +60,115,105,122,101,62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62, +10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95, +68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124, +119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69, +95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116, +101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98, +111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101, +99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +80,114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,52,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44, +45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,83,99,104,101,109,97,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,83,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109,97, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76, +84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,83,116,97,114,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,116,97,114,116,32, +70,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,116,97,114,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +71,101,116,84,111,107,101,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,71,101,116,116,111,107, +101,110,32,70,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,71,101, +116,84,111,107,101,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,69,110,100,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,100,32,70, +117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,69,110,100,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,101,120,116,121,112, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,76,101,120,116,121,112,101,115,32,70,117, +110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,76,101,120,116,121,112,101, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68, +79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +72,101,97,100,108,105,110,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97,100,108,105, +110,101,32,70,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,72,101, +97,100,108,105,110,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,44,50,100,60,47,115,105, +122,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,55,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44, +51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,71,82,79,87,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110, +107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82, +79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_64 = 8482; +static unsigned char xml_res_file_64[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,101,120,116,83,101,97,114,99,104,84,101,109,112, +108,97,116,101,34,62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32, +32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53,100,60,47,115,105,122, +101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85, +76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73, +79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83, +73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99, +111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111, +119,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111, +116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101, +98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108, +101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,80,114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,52,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44, +45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,83,99,104,101,109,97,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,83,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109,97, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76, +84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,73,110,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,105,116,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,73,110,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,76,101,120,105,122,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76, +101,120,105,122,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,76,101,120,105,122,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119, +120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,50,44,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,55,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,50,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44, +51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44, +51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,71,82, +79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101, +61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69, +71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101, +62,10}; + +static size_t xml_res_size_65 = 16584; +static unsigned char xml_res_file_65[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,114,105,103,103,101,114,34,62,10,32,32,32,32,60, +116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48, +44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +50,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69, +95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +45,49,44,52,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101, +32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,99,98,67,108,117,115,116,101,114,83, +101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,56,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,82,111,119,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,111,119,32,116,114, +105,103,103,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,82,111,119,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,111,110,115,116,114,97,105,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,111,110,115,116,114,97,105,110,116,32,116,114,105,103, +103,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34, +32,110,97,109,101,61,34,99,104,107,67,111,110,115,116,114,97,105,110,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107, +101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,68,101,102,101,114,114,97,98, +108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,68,101,102,101,114,114,97,98,108,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,68,101,102,101,114,114,97,98,108,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,68,101,102,101,114,114,101,100,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,68,101,102,101,114,114,101,100,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,68,101,102,101,114,114,101,100,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,70,117,110,99,116,105,111,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +84,114,105,103,103,101,114,32,102,117,110,99,116,105,111,110,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,70,117,110,99,116,105,111,110,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,65,114,103,117,109,101, +110,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,65,114,103,117,109,101,110,116,115,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,65,114,103,117,109,101,110,116,115,34,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,70,105,114,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,114,101,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,111,120,34,32,110, +97,109,101,61,34,114,100,98,70,105,114,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,105,116,101,109,62,66,69,70,79,82,69,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,65,70,84,69,82,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,73,78,83,84,69,65,68,32,79,70,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,101,108,101,99,116,105,111,110,62,48,60,47, +115,101,108,101,99,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,100,105,109,101,110,115,105,111,110,62, +49,60,47,100,105,109,101,110,115,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +82,65,95,83,80,69,67,73,70,89,95,82,79,87,83,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,69,118,101,110,116,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,69,118,101,110,116,115,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,44,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,73,110,115,101,114,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,73,78,83,69,82,84,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,85,112, +100,97,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,80,68,65,84,69,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,68,101,108,101,116,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,69,76,69,84,69,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,84,114,117,110,99, +97,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,82,85,78,67,65,84,69,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,87,104,101,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,87,104,101,110,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,87,104,101,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,45,49,44,52,48,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,67,111,108,117,109,110,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, +115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34, +32,110,97,109,101,61,34,108,115,116,67,111,108,117,109,110,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95, +83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47, +103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,108,117,109,110,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,111,108,117,109,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,65,100,100,67,111,108, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,67,111,108,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,53,48,44,45,49,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111, +116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,66,111,100,121,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,66,111,100,121,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,83,81,76,66,111,120,34,32,110,97,109,101,61,34,116,120,116, +66,111,100,121,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76, +73,78,69,124,119,120,83,85,78,75,69,78,95,66,79,82,68,69,82,124,119,120, +84,69,95,82,73,67,72,50,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80, +124,119,120,82,73,71,72,84,124,119,120,71,82,79,87,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116, +117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99, +116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_66 = 43189; +static unsigned char xml_res_file_66[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,121,112,101,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,52,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119, +110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,99,104,101, +109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,83,99,104,101,109,97,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111, +116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,82,97,100,105,111,66,111,120,34,32,110,97,109,101,61,34,114, +100,98,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105, +116,101,109,62,67,111,109,112,111,115,105,116,101,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,69,110,117,109,101,114,97,116,105,111,110,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,69,120,116,101,114,110,97,108,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,82,97,110,103,101,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,100,105,109,101,110,115,105,111,110,62,49,60,47, +100,105,109,101,110,115,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82,65,95, +83,80,69,67,73,70,89,95,67,79,76,83,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,44,49,44,50, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,67,111, +109,112,111,115,105,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47, +103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115,116, +67,116,114,108,34,32,110,97,109,101,61,34,108,115,116,77,101,109,98,101, +114,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69, +80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,77,101,109,98,101,114,110,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,109,98,101,114,32, +110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120, +116,77,101,109,98,101,114,110,97,109,101,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +68,97,116,97,116,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,97,116,97,32,116,121,112,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,68,97,116,97,116,121,112,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +115,116,76,101,110,103,116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,76,101,110,103,116,104,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,76,101,110,103,116,104,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,80,114,101,99,105,115,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,80,114,101,99,105,115,105,111,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108, +34,32,110,97,109,101,61,34,116,120,116,80,114,101,99,105,115,105,111,110, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,67,111,108,108,97,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,108,108,97,116,105, +111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,111, +108,108,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,77,101,109,98,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,65, +76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,65,100,100,77,101,109, +98,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,65,76, +73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,67,104,97,110,103,101, +77,101,109,98,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,104,97,110,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115, +62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110, +108,68,101,102,105,110,105,116,105,111,110,69,110,117,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47, +103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61, +34,108,115,116,76,97,98,101,108,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53, +44,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,48,48,44, +49,53,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71, +76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,97,98, +101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76,97,98,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84, +101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,76,97, +98,101,108,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,44,50,100,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +98,116,110,65,100,100,66,101,102,111,114,101,76,97,98,101,108,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,32,98,101,102,111, +114,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,98,116,110,65,100,100,65,102,116,101,114,76,97,98,101,108,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,32,97,102,116,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110, +82,101,109,111,118,101,76,97,98,101,108,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105, +116,105,111,110,69,120,116,101,114,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78, +111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,68,101,102, +105,110,105,116,105,111,110,69,120,116,101,114,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116, +101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,82,101,113,117,105,114,101,100,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, +97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,73,110,112,117,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,73,110,112,117,116,32,102,117,110,99,116,105,111,110, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,73,110,112,117,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79, +78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,79,117,116,112,117,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,117,116, +112,117,116,32,102,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,117,116, +112,117,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,112,116,105,111,110,97,108,32,49,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,82,101,99,101,105,118,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,99,101,105,118,101, +32,102,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,82,101,99,101,105, +118,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,83,101,110,100,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,83,101,110,100,32,102,117,110,99,116,105, +111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,99,98,83,101,110,100,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65, +68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,84,121,112,109,111,100,105,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84, +121,112,109,111,100,32,105,110,32,102,117,110,99,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +84,121,112,109,111,100,105,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,84,121,112,109,111,100,111,117,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121, +112,109,111,100,32,111,117,116,32,102,117,110,99,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +84,121,112,109,111,100,111,117,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,73,110,116,76,101,110,103,116,104, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73, +110,116,101,114,110,97,108,32,108,101,110,103,116,104,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,73,110,116,76,101,110,103,116,104,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,86,97,114,105,97,98,108,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,114,105,97,98,108, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,86,97,114,105,97,98,108,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,68,101,102,97,117,108,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101, +102,97,117,108,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,68,101,102,97,117,108,116,34, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,65,110,97,108,121,122,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,110, +97,108,121,122,101,32,102,117,110,99,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,65,110,97,108,121, +122,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,67,97,116,101,103,111,114,121,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,116,101,103,111,114, +121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,67,97,116,101,103,111,114,121,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,65,114,114,97,121,32, +116,121,112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,105,116,101,109,62,66,111,111,108,101,97,110,32,116, +121,112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,105,116,101,109,62,67,111,109,112,111,115,105,116,101, +32,116,121,112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,105,116,101,109,62,68,97,116,101,47,116,105,109, +101,32,116,121,112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,69,110,117,109,32,116,121, +112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,105,116,101,109,62,71,101,111,109,101,116,114,105,99,32,116, +121,112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,105,116,101,109,62,78,101,116,119,111,114,107,32,97,100, +100,114,101,115,115,32,116,121,112,101,115,60,47,105,116,101,109,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,78,117, +109,101,114,105,99,32,116,121,112,101,115,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,80,115,101, +117,100,111,45,116,121,112,101,115,60,47,105,116,101,109,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,83,116,114,105,110, +103,32,116,121,112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,84,105,109,101,115,112,97, +110,32,116,121,112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,85,115,101,114,45,100,101, +102,105,110,101,100,32,116,121,112,101,115,60,47,105,116,101,109,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,66,105, +116,45,115,116,114,105,110,103,32,116,121,112,101,115,60,47,105,116,101, +109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +117,110,107,110,111,119,110,32,116,121,112,101,115,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,80,114,101,102,101,114,101,100,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,101,102,101,114,101,100,63, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,80,114,101,102,101,114,101,100,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107, +112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,116, +105,111,110,97,108,32,50,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,69,108, +101,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,69,108,101,109,101,110,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,69,108, +101,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,68,101,108,105,109,105,116,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,108,105, +109,105,116,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,68,101,108,105,109,105,116,101, +114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,65,108,105,103,110,109,101,110, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +65,108,105,103,110,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,65,108,105,103,110, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,99,104,97,114,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,105,110,116,50,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,105,110,116,52,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,100,111,117,98,108,101,60, +47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111, +110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,83,116,111,114,97,103,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,116,111,114,97,103,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,83,116,111,114,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,101,108,101,99,116,105,111,110,62,48,60,47, +115,101,108,101,99,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,80,97,115,115,101,100,66,121,86,97,108, +117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,80,97,115,115,101,100,32,98,121,32,118,97,108,117,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,66,121,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,111,108,108,97,116,97,98,108, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,108,108,97,116,97,98,108,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,67,111,108, +108,97,116,97,98,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105, +116,105,111,110,82,97,110,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,83,117,98,116,121,112,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,83,117,98,116,121,112,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,99,98,83,117,98,116,121,112,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,117,98,116,121,112, +101,79,112,99,108,97,115,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +117,98,116,121,112,101,32,111,112,101,114,97,116,111,114,32,99,108,97,115, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,117,98,116, +121,112,101,79,112,99,108,97,115,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,82,110,103,67,111,108,108,97,116,105,111,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,108,108,97,116,105,111,110,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,82,110,103,67,111,108, +108,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,97,110,111,110,105,99,97,108,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,97,110,111,110,105,99,97,108,32,102,117,110,99,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,97,110,111,110,105, +99,97,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,117, +98,116,121,112,101,68,105,102,102,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +83,117,98,116,121,112,101,32,100,105,102,102,32,102,117,110,99,116,105, +111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,117,98, +116,121,112,101,68,105,102,102,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101, +61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69, +71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_67 = 15725; +static unsigned char xml_res_file_67[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,85,115,101,114,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,54,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115, +101,114,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,114,32,73,68, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,73,68,34,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,80,97,115, +115,119,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,80,97,115,115,119,111,114,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,80,97,115,115,119,100,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84, +69,95,80,65,83,83,87,79,82,68,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,82,101,80,97,115,115,119,100,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +80,97,115,115,119,111,114,100,32,40,97,103,97,105,110,41,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,82,101,80,97,115,115,119,100,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,80,65,83,83,87,79,82,68,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,86,97,108,105,100,85,110,116,105,108,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,65,99,99,111,117,110,116,32,101,120,112,105,114,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,97,108,101,110,100,97,114,66,111,120,34,32,110,97,109,101,61,34,100, +97,116,86,97,108,105,100,85,110,116,105,108,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,80,95,65,76,76,79,87,78,79,78,69,124,119,120,68,80,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,105,109,101,83,112,105,110,67,116,114,108,34,32,110,97, +109,101,61,34,116,105,109,86,97,108,105,100,85,110,116,105,108,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,108,117,115,116, +101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68, +79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,82,111,108,101,32,112,114,105,118,105,108,101,103,101,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,82,111,108,101,115,80,114,105,118,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +67,114,101,97,116,101,68,66,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,114,32,99,97, +110,32,99,114,101,97,116,101,32,100,97,116,97,98,97,115,101,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101, +100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,67,114,101,97,116,101,85,115,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,83,117,112,101,114,117,115,101,114,32,40,99,97,110,32,99,114,101, +97,116,101,32,117,115,101,114,115,41,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,71,114,111,117,112,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,71,114,111,117,112,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,49,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,44,50,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,71,114, +111,117,112,115,78,111,116,73,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,111,116,32,77, +101,109,98,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,71,114,111,117,112,115,73,110,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,101, +109,98,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,66,111,120, +34,32,110,97,109,101,61,34,108,98,71,114,111,117,112,115,78,111,116,73, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,54,44,49,50,51,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,66,95,78,69,69,68,69, +68,95,83,66,124,119,120,76,66,95,83,79,82,84,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116, +110,65,100,100,71,114,111,117,112,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,103, +116,59,38,103,116,59,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +49,56,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,66,79,84,84,79,77,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,68,101,108, +71,114,111,117,112,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,108,116,59,38,108, +116,59,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,56,44,45,49, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,84,79,80,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,76,105,115,116,66,111,120,34,32,110,97,109,101,61,34,108, +98,71,114,111,117,112,115,73,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,56,54,44,49,50,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,76,66,95,78,69,69,68,69,68,95,83,66,124,119,120,76,66,95,83,79, +82,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98, +111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,86,97,114,105,97,98,108,101,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,86,97,114,105,97,98,108,101,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,52,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61, +34,108,115,116,86,97,114,105,97,98,108,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,54, +100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82, +84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79, +87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,112,111,115,62,48,44,48,100,60,47,112,111,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,65,68, +68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,65,100,100,47,67,104,97,110,103,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,57,48,44,49,51,50,100,60, +47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,82,69,77,79,86,69,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +82,101,109,111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62, +49,53,48,44,49,51,50,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,114,110, +97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,114,105,97,98,108,101, +32,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,86,97,114,110,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,86,97,108,117,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,86,97,114,105,97,98,108,101,32,86,97,108,117,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,44,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,86, +97,108,117,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61, +34,99,104,107,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116, +117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99, +116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_68 = 8224; +static unsigned char xml_res_file_68[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,85,115,101,114,77,97,112,112,105,110,103,34,62,10, +32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122, +101,62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32, +60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79, +71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89, +83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68, +69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111, +107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50, +52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60, +115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111, +112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114, +111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,49,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,85,115,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,114,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,85,115,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,116,105,111,110,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108, +34,32,110,97,109,101,61,34,112,110,108,79,112,116,105,111,110,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114, +108,34,32,110,97,109,101,61,34,108,115,116,79,112,116,105,111,110,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112, +111,115,62,55,48,44,49,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95, +83,69,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,56, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,112,116,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,79,112,116,105,111,110,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,79,112,116,105,111,110,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,108, +117,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,86,97,108,117,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,66,79,84, +84,79,77,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,72,79,82,73, +90,79,78,84,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,82,69,77,79,86,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109, +111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,51,44,53, +56,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,65,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100, +47,67,104,97,110,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62, +49,51,44,55,56,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,44,50,100,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,55,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,71,82,79,87,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110, +107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82, +79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_69 = 36699; +static unsigned char xml_res_file_69[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,86,105,101,119,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,52,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119, +110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,99,104,101, +109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,83,99,104,101,109,97,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,50,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,101,99, +117,114,105,116,121,66,97,114,114,105,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101, +99,117,114,105,116,121,32,66,97,114,114,105,101,114,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,83,101,99,117,114,105,116,121,66,97,114,114,105,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,104,101,99,107,79,112,116,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,87,105,116,104,32,67,104,101,99,107,32,79,112,116, +105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,99,98,67,104,101,99,107,79,112,116,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,78,111,60,47,105,116,101, +109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,105,116,101,109,62,76,111,99,97,108,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,67,97,115,99,97,100,101,100,60,47,105,116,101,109,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,68,101,102,105,110,105,116,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,99,116,108,83,81,76,66,111,120,34,32,110,97,109,101,61,34, +116,120,116,83,113,108,66,111,120,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95, +77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82, +79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,77,97,116,101,114,105,97,108,105,122,97,116,105,111,110, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108, +34,32,110,97,109,101,61,34,112,110,108,77,97,116,101,114,105,97,108,105, +122,101,100,86,105,101,119,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111, +119,115,62,49,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,77,97,116,101,114,105,97,108,105,122, +101,100,86,105,101,119,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,116,101, +114,105,97,108,105,122,101,100,32,86,105,101,119,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +77,97,116,101,114,105,97,108,105,122,101,100,86,105,101,119,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99, +104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,50,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,49,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111, +111,107,34,32,110,97,109,101,61,34,110,98,86,97,99,117,117,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,79,112,116,105,111,110,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114, +111,119,115,62,51,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,84,97,98,108,101,83,112,97,99,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,84,97,98,108,101,115,112,97,99,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,111,84,97,98,108,101,115,112,97,99,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,52, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,52,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,70,105,108,108,70,97,99,116,111,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,70,105,108,108,32,70,97,99,116,111,114,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,105,108,108, +70,97,99,116,111,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,77,97,116,86,105,101, +119,87,105,116,104,68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,87,105,116,104,32,68,97,116,97,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,77,97,116,86,105,101,119,87,105,116, +104,68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,62,51,60,47,103,114,111,119,97,98, +108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,84,97,98,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,52,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,52,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44, +51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,67,117,115,116,111,109,86,97,99,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,67,117,115,116,111,109,32,97,117,116,111,45, +118,97,99,117,117,109,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,99,69,110, +97,98,108,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69, +110,97,98,108,101,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,86,97,99,69,110,97,98,108,101,100,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,67,117,114,114,101,110,116,32,118,97,108,117, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,66, +97,115,101,86,97,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +86,65,67,85,85,77,32,98,97,115,101,32,116,104,114,101,115,104,111,108,100, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,66,97,115, +101,86,97,99,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,66,97,115,101,86,97,99,67,117, +114,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,66,97,115,101,65,110,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,65,78,65,76,89,90,69,32,98,97,115,101, +32,116,104,114,101,115,104,111,108,100,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,116,120,116,66,97,115,101,65,110,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,66,97,115,101,65,110,67,117,114,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70, +97,99,116,111,114,86,97,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,86,65,67,85,85,77,32,115,99,97,108,101,32,102,97,99,116,111,114, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,97,99, +116,111,114,86,97,99,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,97,99,116,111,114, +86,97,99,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,70,97,99,116,111,114,65,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,78,65,76,89,90,69,32,115, +99,97,108,101,32,102,97,99,116,111,114,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,116,120,116,70,97,99,116,111,114,65,110,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,70,97,99,116,111,114,65,110,67,117,114,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,86,97,99,68,101,108,97,121,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,65,67,85,85,77,32,99,111,115,116,32,100,101,108,97, +121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84, +101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,86,97, +99,68,101,108,97,121,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,99,68,101,108,97, +121,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,86,97,99,76,105,109,105,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,67,85,85,77,32,99,111, +115,116,32,108,105,109,105,116,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,86,97,99,76,105,109,105,116,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +115,116,86,97,99,76,105,109,105,116,67,117,114,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +70,114,101,101,122,101,77,105,110,65,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,70,82,69,69,90,69,32,109,105,110,105,109,117,109, +32,97,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120, +116,70,114,101,101,122,101,77,105,110,65,103,101,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,70,114,101,101,122,101,77,105,110,65,103,101,67,117,114,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +115,116,70,114,101,101,122,101,77,97,120,65,103,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,70,82,69,69,90,69,32,109,97,120,105,109,117, +109,32,97,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120, +116,70,114,101,101,122,101,77,97,120,65,103,101,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,70,114,101,101,122,101,77,97,120,65,103,101,67,117,114,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +115,116,70,114,101,101,122,101,84,97,98,108,101,65,103,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,70,82,69,69,90,69,32,116,97,98,108, +101,32,97,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120, +116,70,114,101,101,122,101,84,97,98,108,101,65,103,101,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,70,114,101,101,122,101,84,97,98,108,101,65,103,101,67,117,114, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107, +112,97,103,101,34,32,110,97,109,101,61,34,110,98,112,84,111,97,115,116, +86,97,99,117,117,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,111,97,115,116,32,116, +97,98,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,118,103,97,112,62,52,60,47,118,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,52,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +67,117,115,116,111,109,84,111,97,115,116,86,97,99,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,117,115,116,111,109,32,97,117,116,111, +45,118,97,99,117,117,109,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115, +116,86,97,99,69,110,97,98,108,101,100,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,69,110,97,98,108,101,100,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,84,111,97,115,116,86,97,99,69,110, +97,98,108,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,117,114,114,101,110,116,32,118,97,108,117,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,66,97,115,101,84,111, +97,115,116,86,97,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +86,65,67,85,85,77,32,98,97,115,101,32,116,104,114,101,115,104,111,108,100, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,66,97,115, +101,84,111,97,115,116,86,97,99,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,66,97,115, +101,84,111,97,115,116,86,97,99,67,117,114,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,97,99, +116,111,114,84,111,97,115,116,86,97,99,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,65,67,85,85,77,32,115,99,97,108,101,32,102,97,99,116, +111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70, +97,99,116,111,114,84,111,97,115,116,86,97,99,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,70,97,99,116,111,114,84,111,97,115,116,86,97,99,67,117,114,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,84,111,97,115,116,86,97,99,68,101,108,97,121,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,86,65,67,85,85,77,32,99,111,115,116, +32,100,101,108,97,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,84,111,97,115,116,86,97,99,68,101,108,97,121,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,84,111,97,115,116,86,97,99,68,101,108,97,121,67,117,114,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,84,111,97,115,116,86,97,99,76,105,109,105,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,67,85,85,77,32, +99,111,115,116,32,108,105,109,105,116,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,116,120,116,84,111,97,115,116,86,97,99,76,105,109, +105,116,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,86,97,99,76,105, +109,105,116,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,70, +114,101,101,122,101,77,105,110,65,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,70,82,69,69,90,69,32,109,105,110,105,109,117,109,32, +97,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120, +116,84,111,97,115,116,70,114,101,101,122,101,77,105,110,65,103,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,84,111,97,115,116,70,114,101,101,122,101,77, +105,110,65,103,101,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,70, +114,101,101,122,101,77,97,120,65,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,70,82,69,69,90,69,32,109,97,120,105,109,117,109,32, +97,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120, +116,84,111,97,115,116,70,114,101,101,122,101,77,97,120,65,103,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,84,111,97,115,116,70,114,101,101,122,101,77, +97,120,65,103,101,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,70, +114,101,101,122,101,84,97,98,108,101,65,103,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,70,82,69,69,90,69,32,116,97,98,108,101,32,97, +103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,84, +111,97,115,116,70,114,101,101,122,101,84,97,98,108,101,65,103,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,84,111,97,115,116,70,114,101,101,122,101,84, +97,98,108,101,65,103,101,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_70 = 18754; +static unsigned char xml_res_file_70[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,66,97,99,107,117,112,34,62,10,32,32,32,32,60,116, +105,116,108,101,62,66,97,99,107,117,112,60,47,116,105,116,108,101,62,10, +32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,51,51,100,60,47,115,105, +122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65, +85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84, +73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69, +83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60, +99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114, +111,119,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78, +111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,112, +111,115,62,50,44,50,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,50,56,53,44,50,50,52,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +78,66,95,66,79,84,84,79,77,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,32,79,112,116,105, +111,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,70,105,108,101,79,112, +116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,70,105,108,101,110,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,70,105,108,101,110,97,109,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,105,108,101, +110,97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,98,116,110,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,111,114, +109,97,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,70,111,114,109,97,116,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,70,111,114,109,97,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,67,111,109,112,114,101,115,115,82,97,116,105,111,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,111,109,112,114,101,115,115,32,82,97,116,105,111,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,109,112,114,101,115,115,82,97,116,105,111,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,69,110,99,111,100,105,110,103,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +69,110,99,111,100,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,69,110,99,111,100,105, +110,103,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +124,119,120,67,66,95,83,79,82,84,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,78,117,109,98,101,114,79,102,74,111,98,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,78,117,109,98,101,114,32,79,102,32,74,111,98,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,78,117,109,98,101,114,79,102,74,111,98,115,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,82,111,108,101,110,97,109,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +82,111,108,101,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,82,111,108,101,110,97, +109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +124,119,120,67,66,95,83,79,82,84,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,68,117,109,112,32,79,112,116,105,111,110,115, +32,35,49,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,68,117,109,112,79,112,116, +105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,111,120,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,83,101,99,116,105,111,110,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65,76, +60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,83,101,99,116,105,111,110,80,114,101,68,97,116, +97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,80,114,101,45,100,97,116,97,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,83,101,99,116,105,111,110, +68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,116,97,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,83,101,99,116,105,111,110, +80,111,115,116,68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,111,115, +116,45,100,97,116,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,32,79,102,32, +79,98,106,101,99,116,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53, +60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62, +119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,79,110,108,121, +68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,110,108,121,32,100,97,116, +97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,79,110,108,121, +83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,110,108,121,32, +115,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,66,108,111,98,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,66,108,111,98,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47, +99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,111,110,39,116,32,115,97,118,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60, +47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65,76,60, +47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,78,111,79,119,110,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99, +104,107,78,111,80,114,105,118,105,108,101,103,101,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,80,114,105,118,105,108,101,103,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,99,104,107,78,111,84,97,98,108,101,115,112,97,99,101,115, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,84,97,98,108,101,115,112,97,99,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,78,111,85,110,108, +111,103,103,101,100,84,97,98,108,101,68,97,116,97,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,85,110,108,111,103,103,101,100,32,116,97,98,108,101,32,100,97, +116,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111, +116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,68,117,109,112,32,79,112,116,105,111, +110,115,32,35,50,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,117,109,112, +79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,81,117,101,114,105,101,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73, +67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,67,114,101,97,116,101,68,98,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,73,110,99,108,117,100,101,32,67,82,69,65,84, +69,32,68,65,84,65,66,65,83,69,32,115,116,97,116,101,109,101,110,116,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,68,114,111,112,68, +98,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,73,110,99,108,117,100,101,32,68,82, +79,80,32,68,65,84,65,66,65,83,69,32,115,116,97,116,101,109,101,110,116, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,67,111,108,117, +109,110,73,110,115,101,114,116,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,67,111,108,117,109,110,32,73,110,115,101,114,116,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,73,110,115,101,114,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,85,115,101,32,73,110,115,101,114,116,32,99, +111,109,109,97,110,100,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,105,115,97,98,108, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84, +73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,68,105,115,97,98,108,101,84,114, +105,103,103,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,114,105,103,103, +101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,68,105,115, +97,98,108,101,68,111,108,108,97,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68, +111,108,108,97,114,32,113,117,111,116,105,110,103,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +77,105,115,99,101,108,108,97,110,111,117,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101, +110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,85,115,101,83,101,116,83,101,115,115,105,111,110,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,85,115,101,32,83,69,84,32,83,69,83,83,73,79,78,32,65,85,84, +72,79,82,73,90,65,84,73,79,78,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,79,105,100,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,87,105, +116,104,32,79,73,68,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,86,101,114,98,111,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,101,114, +98,111,115,101,32,109,101,115,115,97,103,101,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,99,104,107,70,111,114,99,101,81,117,111,116,101,70,111, +114,73,100,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,111,114,99, +101,32,100,111,117,98,108,101,32,113,117,111,116,101,115,32,111,110,32, +105,100,101,110,116,105,102,105,101,114,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +79,98,106,101,99,116,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99, +116,108,67,104,101,99,107,84,114,101,101,86,105,101,119,34,32,110,97,109, +101,61,34,99,116,118,79,98,106,101,99,116,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,82,95,72,65, +83,95,66,85,84,84,79,78,83,124,119,120,83,73,77,80,76,69,95,66,79,82,68, +69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,77,101,115,115,97,103,101,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,77,101,115,115,97,103,101,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85, +76,84,73,76,73,78,69,124,119,120,84,69,95,82,69,65,68,79,78,76,89,124,119, +120,72,83,67,82,79,76,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120, +71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,66,97,99,107,117,112, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_71 = 3997; +static unsigned char xml_res_file_71[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,66,97,99,107,117,112,71,108,111,98,97,108,115,34, +62,10,32,32,32,32,60,116,105,116,108,101,62,66,97,99,107,117,112,32,71, +108,111,98,97,108,115,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115, +105,122,101,62,50,49,48,44,49,53,51,100,60,47,115,105,122,101,62,10,32, +32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73, +65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119, +120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66, +79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110, +98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98, +111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,79,112,116,105,111,110,115,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,110,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,112,111,115,62,56,44,55,100,60,47,112,111,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,116,120,116,70,105,108,101,110,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,54,53,44,53, +100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,49,53,48,44,45,49,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,98,116,110,70,105,108,101,110,97,109,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,46,46,46, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,112,111,115,62,50,50,48,44,53,100,60,47,112,111,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,53,44, +45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +82,111,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,82,111,108,101,110,97,109,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,112,111,115,62,56,44,50,55,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,82,111,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,112,111,115,62,54,53,44,50,53,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,55,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87, +78,124,119,120,67,66,95,83,79,82,84,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,116,120,116,78,111,116,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,111,116, +101,58,32,79,110,108,121,32,111,98,106,101,99,116,115,32,103,108,111,98, +97,108,32,116,111,32,116,104,101,32,101,110,116,105,114,101,32,100,97,116, +97,98,97,115,101,32,99,108,117,115,116,101,114,32,119,105,108,108,32,98, +101,32,98,97,99,107,101,100,92,110,117,112,46,32,84,104,101,32,98,97,99, +107,117,112,32,102,111,114,109,97,116,32,119,105,108,108,32,98,101,32,80, +76,65,73,78,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,112,111,115,62,56,44,52,55,100,60,47,112,111,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,70,111,114,99,101,81,117,111, +116,101,70,111,114,73,100,101,110,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,111,114,99,101,32,100, +111,117,98,108,101,32,113,117,111,116,101,115,32,111,110,32,105,100,101, +110,116,105,102,105,101,114,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,48,44,49,50, +48,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,86,101,114,98,111, +115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,101,114,98,111,115,101,32,109,101,115,115,97,103,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101, +100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,49,48,44,49,52,52,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,101,108,101,99,116,101,100,62,49,60,47,115,101,108,101, +99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,50,44,50,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,50,52,53,44,49,55,52,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,78,66,95,66,79,84,84,79, +77,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,77,101,115,115,97,103,101,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,116,120,116,77,101,115,115,97,103,101,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84, +69,95,77,85,76,84,73,76,73,78,69,124,119,120,84,69,95,82,69,65,68,79,78, +76,89,124,119,120,72,83,67,82,79,76,76,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68, +124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,50,44,49,51,53,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,66,97,99,107,117,112,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, +62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,112,111,115,62,57,51,44,49,51,53,100,60,47,112,111,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84, +79,80,124,119,120,66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78, +67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,52, +54,44,49,51,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80, +65,78,68,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,71,82,79,87,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119, +97,98,108,101,114,111,119,115,62,10,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111, +117,114,99,101,62,10}; + +static size_t xml_res_size_72 = 3924; +static unsigned char xml_res_file_72[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,66,97,99,107,117,112,83,101,114,118,101,114,34,62, +10,32,32,32,32,60,116,105,116,108,101,62,66,97,99,107,117,112,32,83,101, +114,118,101,114,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105, +122,101,62,50,49,48,44,49,53,51,100,60,47,115,105,122,101,62,10,32,32,32, +32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76, +79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83, +89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82, +68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78, +111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,112,116,105,111,110,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,110,97,109,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,112,111,115,62,56,44,55,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,54,53,44,53,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,49,53,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,46,46,46,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +112,111,115,62,50,50,48,44,53,100,60,47,112,111,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,53,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,82,111,108,101, +110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,82,111,108,101,110,97,109,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,56,44,50,55,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,82,111, +108,101,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,112,111,115,62,54,53,44,50,53,100,60,47,112,111,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,55, +48,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65, +68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120, +67,66,95,83,79,82,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,116,120,116,78,111,116,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,111,116,101,58,32,84,104, +101,32,98,97,99,107,117,112,32,102,111,114,109,97,116,32,119,105,108,108, +32,98,101,32,80,76,65,73,78,46,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,56,44,52,55,100,60, +47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,70,111,114,99,101, +81,117,111,116,101,70,111,114,73,100,101,110,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,111,114,99, +101,32,100,111,117,98,108,101,32,113,117,111,116,101,115,32,111,110,32, +105,100,101,110,116,105,102,105,101,114,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,49, +48,44,49,50,48,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +86,101,114,98,111,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,86,101,114,98,111,115,101,32,109,101, +115,115,97,103,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47, +99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,112,111,115,62,49,48,44,49,52,52,100,60,47,112,111,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +49,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,112, +111,115,62,50,44,50,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,50,52,53,44,49,55,52,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +78,66,95,66,79,84,84,79,77,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,77,101,115,115,97,103,101,115,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,77,101,115,115,97,103,101, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,124,119,120,84,69,95, +82,69,65,68,79,78,76,89,124,119,120,72,83,67,82,79,76,76,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124, +119,120,69,88,80,65,78,68,124,119,120,71,82,79,87,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,38,97,109,112,59,72,101,108,112,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,50,44,49,51,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79, +77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,38,97,109,112,59,66,97,99,107,117,112,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,57,51,44,49, +51,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,112,111,115,62,49,52,54,44,49,51,53,100,60,47,112,111,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79, +80,124,119,120,66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,71,82,79,87,124,119, +120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101, +99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_73 = 3589; +static unsigned char xml_res_file_73[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,69,120,112,111,114,116,34,62,10,32,32,32,32,60,116, +105,116,108,101,62,69,120,112,111,114,116,32,100,97,116,97,32,116,111,32, +102,105,108,101,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105, +122,101,62,50,53,51,44,49,52,51,100,60,47,115,105,122,101,62,10,32,32,32, +32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76, +79,71,95,83,84,89,76,69,60,47,115,116,121,108,101,62,10,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,34,32,110,97,109,101,61,34,114,98,82,111,119,83,101,112, +97,114,97,116,111,114,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62, +82,111,119,32,115,101,112,97,114,97,116,111,114,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,60,112,111,115,62,53,44,53,100,60,47,112,111,115, +62,10,32,32,32,32,32,32,60,115,105,122,101,62,49,50,48,44,51,56,100,60, +47,115,105,122,101,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,114, +98,76,70,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,76,70,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,60,118,97,108,117,101,62,49,60, +47,118,97,108,117,101,62,10,32,32,32,32,32,32,60,112,111,115,62,49,48,44, +49,55,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,82,66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,114,98,67,82,76,70,34,62,10, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,82,47,76,70,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,49,48,44,50,57,100,60, +47,112,111,115,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111, +108,83,101,112,97,114,97,116,111,114,34,62,10,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,111,108,117,109,110,32,115,101,112,97,114,97,116,111, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,53, +44,53,53,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,111,108,83,101,112,97,114,97,116,111,114,34,62,10,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,59,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,60,105, +116,101,109,62,44,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,60, +105,116,101,109,62,124,60,47,105,116,101,109,62,10,32,32,32,32,32,32,60, +47,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,60,115,101,108,101, +99,116,105,111,110,62,48,60,47,115,101,108,101,99,116,105,111,110,62,10, +32,32,32,32,32,32,60,112,111,115,62,49,48,48,44,53,51,100,60,47,112,111, +115,62,10,32,32,32,32,32,32,60,115,105,122,101,62,50,53,44,49,50,100,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,81,117,111,116,101,67,104,97,114, +34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,81,117,111,116,101,32, +99,104,97,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111, +115,62,53,44,55,48,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,81,117,111,116,101,67,104,97,114,34,62,10,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,34,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,60,105, +116,101,109,62,39,60,47,105,116,101,109,62,10,32,32,32,32,32,32,60,47,99, +111,110,116,101,110,116,62,10,32,32,32,32,32,32,60,115,101,108,101,99,116, +105,111,110,62,48,60,47,115,101,108,101,99,116,105,111,110,62,10,32,32, +32,32,32,32,60,112,111,115,62,49,48,48,44,54,56,100,60,47,112,111,115,62, +10,32,32,32,32,32,32,60,115,105,122,101,62,50,53,44,49,50,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,67,111,108,110,97,109,101,115,34,62, +10,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,32, +110,97,109,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112, +111,115,62,53,44,56,53,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,67,111,108,110,97,109,101,115,34,62,10,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,60,99,104,101,99, +107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32, +32,60,112,111,115,62,49,48,48,44,56,51,100,60,47,112,111,115,62,10,32,32, +32,32,32,32,60,115,105,122,101,62,49,50,44,49,50,100,60,47,115,105,122, +101,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,34,32,110,97,109,101,61,34,115,98,69,110,99,111,100,105, +110,103,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,99,111, +100,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112, +111,115,62,49,51,48,44,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +60,115,105,122,101,62,49,50,48,44,51,56,100,60,47,115,105,122,101,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,114,98,76,111,99,97,108,34,62, +10,32,32,32,32,32,32,60,108,97,98,101,108,62,76,111,99,97,108,32,99,104, +97,114,115,101,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,118, +97,108,117,101,62,49,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,60, +112,111,115,62,49,52,48,44,49,55,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82, +97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,114,98, +85,110,105,99,111,100,101,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108, +62,85,110,105,99,111,100,101,32,85,84,70,45,56,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,60,112,111,115,62,49,52,48,44,50,57,100,60,47,112, +111,115,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,34,32,110,97,109,101,61,34,115,98,81,117,111,116,105, +110,103,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,81,117,111,116, +105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111, +115,62,49,51,48,44,52,56,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +60,115,105,122,101,62,49,50,48,44,53,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,114,98,81,117,111,116,101,78, +111,110,101,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,110,111, +32,113,117,111,116,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,60,112,111,115,62,49,52,48,44,54,48,100,60,47,112,111,115,62,10,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +114,98,81,117,111,116,101,83,116,114,105,110,103,115,34,62,10,32,32,32, +32,32,32,60,108,97,98,101,108,62,111,110,108,121,32,115,116,114,105,110, +103,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,118,97,108,117, +101,62,49,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,60,112,111,115, +62,49,52,48,44,55,50,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,114,98,81,117,111,116,101,65,108,108,34,62,10,32,32, +32,32,32,32,60,108,97,98,101,108,62,97,108,108,32,99,111,108,117,109,110, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,49, +52,48,44,56,52,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32,32, +32,60,108,97,98,101,108,62,70,105,108,101,110,97,109,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,53,44,49,48,55,100,60, +47,112,111,115,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,105,108, +101,110,97,109,101,34,62,10,32,32,32,32,32,32,60,112,111,115,62,49,48,48, +44,49,48,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,105,122, +101,62,49,51,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,98,116,110,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32, +32,32,60,108,97,98,101,108,62,46,46,46,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,60,112,111,115,62,50,51,53,44,49,48,53,100,60,47,112,111, +115,62,10,32,32,32,32,32,32,60,115,105,122,101,62,49,53,44,45,49,100,60, +47,115,105,122,101,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112, +111,115,62,50,44,49,50,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +60,115,116,121,108,101,47,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +79,75,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,60,112,111,115,62,49,52,55,44,49,50,53,100,60,47,112,111,115,62,10, +32,32,32,32,32,32,60,115,116,121,108,101,47,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,60,108, +97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60, +47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,60,112,111,115,62, +50,48,48,44,49,50,53,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114, +101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_74 = 1443; +static unsigned char xml_res_file_74[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,71,114,97,110,116,87,105,122,97,114,100,34,62,10, +32,32,32,32,60,116,105,116,108,101,62,71,114,97,110,116,32,87,105,122,97, +114,100,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101, +62,50,48,48,44,51,48,51,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,60,47,115,116,121,108,101,62,10,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101, +98,111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111, +111,107,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,108,101,99,116,105, +111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34, +32,110,97,109,101,61,34,112,110,108,83,101,108,101,99,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,76,105,115,116,66,111,120,34, +32,110,97,109,101,61,34,99,104,107,76,105,115,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,112,111,115,62,50,44,51,100,60,47,112,111, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +56,51,44,50,51,52,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,67,104,107,65,108,108, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67, +104,101,99,107,32,97,108,108,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,112,111,115,62,50,44,50,52,48,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +53,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,98,116,110,85,110,99,104,107,65,108, +108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +85,110,99,104,101,99,107,32,97,108,108,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,54,48,44,50,52,48,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,53,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,115,101,108, +101,99,116,101,100,62,49,60,47,115,101,108,101,99,116,101,100,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,112, +111,115,62,50,44,50,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60,115, +105,122,101,62,49,57,53,44,50,55,54,100,60,47,115,105,122,101,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32, +32,32,60,108,97,98,101,108,62,38,97,109,112,59,72,101,108,112,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,50,44,50,56,53, +100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +79,75,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,60,112,111,115,62,57,51,44,50,56,53,100,60,47,112,111,115,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,49,52, +54,44,50,56,53,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101, +115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_75 = 3111; +static unsigned char xml_res_file_75[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,72,105,110,116,34,62,10,32,32,32,32,60,116,105,116, +108,101,62,112,103,65,100,109,105,110,32,71,117,114,117,32,72,105,110,116, +60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101,62,50,48, +48,44,49,53,51,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,72,116,109, +108,87,105,110,100,111,119,34,32,110,97,109,101,61,34,104,116,109,108,72, +105,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,85,78,75,69,78,95,66,79,82,68,69,82,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,60,109,105,110,115,105,122,101,62,51,48,48,44,50,48,48,100,60, +47,109,105,110,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,117, +112,112,114,101,115,115,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,68,111,32,110,111,116,32,115,104,111,119,32,116,104,105,115, +32,104,105,110,116,32,97,103,97,105,110,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,55,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,112,111,115,62,50,44,49,51,53,100,60,47,112,111, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +84,79,80,124,119,120,66,79,84,84,79,77,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,98,116,110,70,105,120,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,70,105,120,32,105,116,33,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,112,111,115,62,57,51,44,49,51,53,100,60,47,112,111,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,89,69,83,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,89,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97, +117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111, +115,62,57,51,44,49,51,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,66,79, +84,84,79,77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,78,79,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,78, +111,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,57,51, +44,49,51,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,57,51,44,49,51,53,100,60, +47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +112,111,115,62,49,52,54,44,49,51,53,100,60,47,112,111,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124, +119,120,69,88,80,65,78,68,124,119,120,71,82,79,87,124,119,120,65,76,73, +71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,71, +82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62, +10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_76 = 12319; +static unsigned char xml_res_file_76[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,73,109,112,111,114,116,34,62,10,32,32,32,32,60,116, +105,116,108,101,62,73,109,112,111,114,116,32,100,97,116,97,32,102,114,111, +109,32,102,105,108,101,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115, +105,122,101,62,51,48,48,44,49,51,51,100,60,47,115,105,122,101,62,10,32, +32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73, +65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119, +120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66, +79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98, +111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111, +107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,50,44,50,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,50,56,53,44,49,50,52,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,78,66,95,66,79,84,84,79, +77,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,70,105,108,101,32,79,112,116,105,111,110,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,70,105,108,101,79,112,116,105,111,110,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108, +101,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,105,108,101,80,105,99, +107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105,99,107,101, +114,73,109,112,111,114,116,102,105,108,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,101,115,115,97,103,101,62, +83,101,108,101,99,116,32,116,104,101,32,102,105,108,101,32,116,111,32,105, +109,112,111,114,116,60,47,109,101,115,115,97,103,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,70,76,80,95,79,80,69,78,124,119,120,70,76,80,95,85,83,69,95, +84,69,88,84,67,84,82,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,105,108,100,99,97,114, +100,62,42,46,99,115,118,59,42,46,42,59,42,60,47,119,105,108,100,99,97,114, +100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +116,111,111,108,116,105,112,62,69,110,116,101,114,32,97,32,102,105,108, +101,110,97,109,101,32,116,111,32,105,109,112,111,114,116,46,60,47,116,111, +111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,111,114,109, +97,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,70,111,114,109,97,116,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +70,111,114,109,97,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,116, +101,120,116,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,99,115,118,60,47, +105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,105,116,101,109,62,98,105,110,97,114,121,60,47,105,116, +101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,105,111,110,62, +48,60,47,115,101,108,101,99,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +69,110,99,111,100,105,110,103,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,99,111,100,105, +110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,99,98,69,110,99,111,100,105,110,103,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95, +83,79,82,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,67,111,108,117,109,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,67, +111,108,117,109,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,49,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,108,117,109, +110,115,84,111,73,109,112,111,114,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,108, +117,109,110,115,32,116,111,32,105,109,112,111,114,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,76,105,115,116,66,111,120,34,32,110,97,109, +101,61,34,108,115,116,67,111,108,117,109,110,115,84,111,73,109,112,111, +114,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,77,105,115,99,46,32,79,112,116,105,111,110,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108, +34,32,110,97,109,101,61,34,112,110,108,77,105,115,99,79,112,116,105,111, +110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,105,100,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,79,105,100,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107, +101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,72,101,97,100,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97,100,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,99,104,107,72,101,97,100,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,68,101,108,105,109,105,116,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,101,108,105,109,105,116,101,114,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,68,101,108, +105,109,105,116,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +59,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,44,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,124,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,91, +116,97,98,93,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,81,117,111,116,101,32,79,112,116, +105,111,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, +97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,81,117,111,116,101, +79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,81,117,111,116,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,81,117,111,116,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,81,117,111,116,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,34,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,39,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,69,115,99,97,112,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,69,115,99,97,112,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,69,115,99, +97,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,34,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,39,60,47,105,116,101,109,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87, +78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111, +111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,85,76,76,32,79,112,116,105,111,110,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,78,117,108,108,79,112,116,105,111,110,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,117,108,108,83,116,114,105,110,103,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,78,85,76,76,32,115,116,114,105,110,103,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,78,117,108,108,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,103,110,111, +114,101,70,111,114,67,111,108,117,109,110,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,103, +110,111,114,101,32,102,111,114,32,99,111,108,117,109,110,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,76,105,115,116,66,111,120,34,32, +110,97,109,101,61,34,108,115,116,73,103,110,111,114,101,70,111,114,67,111, +108,117,109,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124, +119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,71,97,117,103,101, +34,32,110,97,109,101,61,34,103,97,117,103,101,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,73,109,112,111,114,116,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, +102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_77 = 5178; +static unsigned char xml_res_file_77[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,77,97,105,110,116,101,110,97,110,99,101,34,62,10, +32,32,32,32,60,116,105,116,108,101,62,77,97,105,110,116,101,110,97,110, +99,101,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101,62, +50,48,48,44,49,53,51,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84, +69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,78,66,95, +66,79,84,84,79,77,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116, +101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,112,116,105,111,110,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97, +100,105,111,66,111,120,34,32,110,97,109,101,61,34,114,98,120,65,99,116, +105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,77,97,105,110,116,101,110,97,110,99,101, +32,111,112,101,114,97,116,105,111,110,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,105,116,101,109,62,86,65,67,85,85,77,60,47,105,116,101, +109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,105,116,101,109,62,65,78,65,76,89,90,69,60,47,105,116,101,109,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +105,116,101,109,62,82,69,73,78,68,69,88,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,67,76,85,83,84,69,82,60,47,105,116,101,109,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101, +110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,101,108,101,99,116,105,111,110,62,48,60,47,115,101,108,101,99, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,82,65,95,83,80,69,67,73,70,89, +95,82,79,87,83,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +86,65,67,85,85,77,32,111,112,116,105,111,110,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111, +114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,70,117,108,108,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70, +85,76,76,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,70,114,101, +101,122,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,82,69,69,90,69,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,65,110,97,108,121,122,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,65,78,65,76,89,90,69,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,86,101, +114,98,111,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,86,101,114,98,111,115,101,32,109, +101,115,115,97,103,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +101,108,101,99,116,101,100,62,49,60,47,115,101,108,101,99,116,101,100,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,115,115,97,103,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, +67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,77,101,115,115,97, +103,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,124,119,120, +84,69,95,82,69,65,68,79,78,76,89,124,119,120,72,83,67,82,79,76,76,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119, +120,66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +124,119,120,69,88,80,65,78,68,124,119,120,71,82,79,87,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,38,97,109,112,59,72,101,108,112,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,50,44,49,51,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79, +77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, +108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,112,111,115,62,57,51,44,49,51,53,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112, +111,115,62,49,52,54,44,49,51,53,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124, +119,120,69,88,80,65,78,68,124,119,120,71,82,79,87,124,119,120,65,76,73, +71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,71, +82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60, +47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62, +10}; + +static size_t xml_res_size_78 = 68517; +static unsigned char xml_res_file_78[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,79,112,116,105,111,110,115,34,62,10,32,32,32,32,60, +116,105,116,108,101,62,79,112,116,105,111,110,115,60,47,116,105,116,108, +101,62,10,32,32,32,32,60,115,105,122,101,62,52,56,48,44,50,53,48,100,60, +47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120, +68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120, +67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119, +120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,84,114,101,101,34,32,110,97,109,101,61,34,109,101,110,117, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,49,48,48,44,50,50,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,82,95,72, +65,83,95,66,85,84,84,79,78,83,124,119,120,83,73,77,80,76,69,95,66,79,82, +68,69,82,124,119,120,84,82,95,72,73,68,69,95,82,79,79,84,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,48,44,49,44,50,44,51,44,52,44,53,44,54,44,55,44,56,44,57, +44,49,48,44,49,49,44,49,50,44,49,51,44,49,52,44,49,53,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,77,105,115, +99,72,101,108,112,80,97,116,104,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,105,100,100,101,110,62,49,60,47,104,105, +100,100,101,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,80,103,72,101,108,112,80,97, +116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,71,32,104,101,108,112,32,112, +97,116,104,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,80,103,72,101,108,112,80,97, +116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,69,110,116,101,114, +32,116,104,101,32,112,97,116,104,32,111,114,32,85,82,76,32,116,111,32,116, +104,101,32,80,111,115,116,103,114,101,83,81,76,32,100,111,99,117,109,101, +110,116,97,116,105,111,110,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,69,100,98,72,101,108,112,80,97,116,104,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,69,68,66,32,104,101,108,112,32,112,97,116,104,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,116,120,116,69,100,98,72,101,108,112,80,97,116,104,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,71,112,72,101,108,112,80,97,116,104,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,71,80,32,104,101,108,112,32,112,97,116,104,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116, +71,112,72,101,108,112,80,97,116,104,34,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,108,111,110,121,72, +101,108,112,80,97,116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,108,111, +110,121,32,104,101,108,112,32,112,97,116,104,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,83, +108,111,110,121,72,101,108,112,80,97,116,104,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,77,105,115, +99,85,73,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,105,100,100,101,110,62,49,60,47,104,105,100,100,101,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,76,97,110,103,117,97,103,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,85,115,101,114,32,108,97,110,103,117,97,103,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,76,97,110,103,117,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,83,121,115,116,101,109,83,99,104,101, +109,97,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,121,115,116,101,109,32, +115,99,104,101,109,97,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, +67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,83,121,115,116,101, +109,83,99,104,101,109,97,115,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,66,114,111,119,115,101, +114,68,105,115,112,108,97,121,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,105,100,100,101,110,62,49,60,47,104,105,100, +100,101,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,97,116, +97,98,97,115,101,79,98,106,101,99,116,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,68,105,115,112,108,97,121,32,116,104,101,32,102,111,108,108,111,119, +105,110,103,32,100,97,116,97,98,97,115,101,32,111,98,106,101,99,116,115, +58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,76,105,115,116,66,111,120,34,32,110,97,109,101,61,34,108,115,116, +68,105,115,112,108,97,121,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,98,116,110,68,101,102,97,117,108,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,68,101,102,97,117,108,116,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,66,114,111,119,115,101,114,80,114,111,112, +101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,104,105,100,100,101,110,62,49,60,47,104,105,100,100,101, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,65,117,116,111,82,111,119,67,111,117,110, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,67,111,117,110,116,32,114,111,119,115, +32,105,102,32,101,115,116,105,109,97,116,101,100,32,108,101,115,115,32, +116,104,97,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,65,117,116,111,82,111,119,67, +111,117,110,116,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,66,114,111,119,115,101,114,66,105,110,80,97, +116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,105,100,100,101,110,62,49,60,47,104,105,100,100,101,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,53,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,108,111,110,121,80,97,116, +104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,83,108,111,110,121,45,73,32,112,97, +116,104,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,114,80,105,99,107, +101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105,99,107,101,114, +83,108,111,110,121,80,97,116,104,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,101,115,115,97,103,101, +62,83,101,108,101,99,116,32,100,105,114,101,99,116,111,114,121,32,119,105, +116,104,32,83,108,111,110,121,45,73,32,99,114,101,97,116,105,111,110,32, +115,99,114,105,112,116,115,60,47,109,101,115,115,97,103,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,73,82,80,95,85,83,69,95,84,69,88,84,67,84, +82,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,80,111, +115,116,103,114,101,115,113,108,80,97,116,104,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,80,71,32,98,105,110,32,112,97,116,104,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +68,105,114,80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101,61, +34,112,105,99,107,101,114,80,111,115,116,103,114,101,115,113,108,80,97, +116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,109,101,115,115,97,103,101,62,83,101,108,101,99,116, +32,100,105,114,101,99,116,111,114,121,32,119,105,116,104,32,80,111,115, +116,103,114,101,83,81,76,32,117,116,105,108,105,116,105,101,115,60,47,109, +101,115,115,97,103,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,68,73,82, +80,95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,69,110,116,101,114,112,114,105,115,101, +100,98,80,97,116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,68,66,32,98,105, +110,32,112,97,116,104,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,114,80,105,99, +107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105,99,107,101, +114,69,110,116,101,114,112,114,105,115,101,100,98,80,97,116,104,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,109,101,115,115,97,103,101,62,83,101,108,101,99,116,32,100,105,114,101, +99,116,111,114,121,32,119,105,116,104,32,69,110,116,101,114,112,114,105, +115,101,68,66,32,117,116,105,108,105,116,105,101,115,60,47,109,101,115, +115,97,103,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,68,73,82,80,95,85, +83,69,95,84,69,88,84,67,84,82,76,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,71,80,68,66,80,97,116,104,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,71,80,32,98,105,110,32,112,97,116,104,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,68,105,114,80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101, +61,34,112,105,99,107,101,114,71,80,68,66,80,97,116,104,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,101, +115,115,97,103,101,62,83,101,108,101,99,116,32,100,105,114,101,99,116,111, +114,121,32,119,105,116,104,32,71,114,101,101,110,112,108,117,109,68,66, +32,117,116,105,108,105,116,105,101,115,60,47,109,101,115,115,97,103,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,68,73,82,80,95,85,83,69,95,84,69, +88,84,67,84,82,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,73,103,110,111,114,101,86,101,114,115,105,111,110,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,73,103,110,111,114,101,32,115,101,114,118,101,114,47,117, +116,105,108,105,116,121,32,118,101,114,115,105,111,110,32,109,105,115,109, +97,116,99,104,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,86,101,114,115,105,111,110,77,105,115,109,97,116,99,104,87,97, +114,110,105,110,103,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,87,97,114,110,105, +110,103,58,32,66,97,99,107,117,112,32,111,114,32,114,101,115,116,111,114, +101,32,111,112,101,114,97,116,105,111,110,115,32,109,97,121,32,102,97,105, +108,32,105,102,32,116,104,101,32,80,111,115,116,103,114,101,83,81,76,32, +117,116,105,108,105,116,105,101,115,32,100,111,32,110,111,116,32,109,97, +116,99,104,32,116,104,101,32,115,101,114,118,101,114,32,118,101,114,115, +105,111,110,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110, +108,66,114,111,119,115,101,114,77,105,115,99,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,104,105,100,100,101,110,62,49,60, +47,104,105,100,100,101,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,70,111,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,70,111,110,116,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +111,110,116,80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101,61, +34,112,105,99,107,101,114,70,111,110,116,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,65,115,107,68,101, +108,101,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,110,102,105,114, +109,32,111,98,106,101,99,116,32,100,101,108,101,116,105,111,110,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,83,121,115,116,101,109,79, +98,106,101,99,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,104,111,119,32, +83,121,115,116,101,109,32,79,98,106,101,99,116,115,32,105,110,32,116,104, +101,32,116,114,101,101,118,105,101,119,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,83,104,111,119,85,115,101,114,115,70,111,114,80, +114,105,118,105,108,101,103,101,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +104,111,119,32,117,115,101,114,115,32,102,111,114,32,112,114,105,118,105, +108,101,103,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107, +101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,68,111,117,98,108,101,67,108,105,99,107,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,104,111,119,32,111,98,106, +101,99,116,32,112,114,111,112,101,114,116,105,101,115,32,111,110,32,100, +111,117,98,108,101,32,99,108,105,99,107,32,105,110,32,116,114,101,101,118, +105,101,119,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,104, +111,119,78,111,116,105,99,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,104, +111,119,32,78,79,84,73,67,69,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104, +101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,82,101,102,114,101,115,104,79,110,67,108,105,99,107,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,82,101,102,114,101,115,104,32,111,110,32, +99,108,105,99,107,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,82,101,102,114,101,115,104,79,110, +67,108,105,99,107,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,105,116,101,109,62,78,111,110,101,60,47,105,116, +101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,82,101,102,114,101, +115,104,32,111,98,106,101,99,116,32,111,110,32,99,108,105,99,107,60,47, +105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,82,101,102, +114,101,115,104,32,111,98,106,101,99,116,32,97,110,100,32,99,104,105,108, +100,114,101,110,32,111,110,32,99,108,105,99,107,60,47,105,116,101,109,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,81,117,101,114,121,84,111,111,108,69,100,105, +116,111,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,104,105,100,100,101,110,62,49,60,47,104,105,100,100,101,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,83,113,108,70,111,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,70,111,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,111,110,116, +80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105, +99,107,101,114,83,113,108,70,111,110,116,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,77,97,120,67, +111,108,83,105,122,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,120,46,32, +99,104,97,114,97,99,116,101,114,115,32,112,101,114,32,99,111,108,117,109, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,77,97,120,67,111,108,83,105,122,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,97,108,117,101,62,50,53,54,60,47,118,97,108,117,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,73,110,100,101,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,73,110,100,101,110,116,32,99,104,97,114,97,99,116,101,114,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,116,120,116,73,110,100,101,110,116,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,112,97, +99,101,115,70,111,114,84,97,98,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,115,112,97,99,101,115,32,105,110,115,116,101,97,100,32,111,102, +32,116,97,98,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,83,112,97,99,101,115,70,111, +114,84,97,98,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,116,105,99,107,121, +83,113,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,112,121,32,83,81,76, +32,102,114,111,109,32,109,97,105,110,32,119,105,110,100,111,119,32,116, +111,32,113,117,101,114,121,32,116,111,111,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,116, +105,99,107,121,83,113,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,65,117,116,111,82,111,108,108,98,97,99,107,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,69,110,97,98,108,101,32,65,117,116,111,32, +82,79,76,76,66,65,67,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,65,117,116,111,82, +111,108,108,98,97,99,107,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104, +101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,65,117,116,111,67,111,109,109,105,116,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,69,110,97,98,108,101,32,65,117,116,111,67,111,109, +109,105,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,65,117,116,111,67,111,109,109, +105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101, +100,62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,75,101,121,119,111,114,100,73,110,85,112,112,101,114,99,97,115,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,75,101,121,119,111,114,100,115,32,105, +110,32,117,112,112,101,114,99,97,115,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,75,101, +121,119,111,114,100,115,73,110,85,112,112,101,114,99,97,115,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,69,120,116,70, +111,114,109,97,116,67,109,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,120,116, +101,114,110,97,108,32,102,111,114,109,97,116,116,105,110,103,32,117,116, +108,105,116,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,105,108,101,80,105,99, +107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105,99,107,101, +114,69,120,116,70,111,114,109,97,116,67,109,100,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,101,115, +115,97,103,101,62,83,101,108,101,99,116,32,117,116,105,108,105,116,121, +32,116,111,32,102,111,114,109,97,116,32,116,101,120,116,60,47,109,101,115, +115,97,103,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,119,105,108,100,99,97,114,100,62,42,60,47,119,105, +108,100,99,97,114,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,70,76,80,95, +79,80,69,78,124,119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84,82,76, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,65,32, +99,111,109,109,97,110,100,32,108,105,110,101,32,117,116,105,108,105,116, +121,32,119,104,105,99,104,32,114,101,97,100,115,32,83,84,68,73,78,32,97, +110,100,32,100,105,114,101,99,116,115,32,111,117,116,112,117,116,32,116, +111,32,83,84,68,79,85,84,46,60,47,116,111,111,108,116,105,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,81,117,101,114,121,84,111,111,108,67,111,108, +111,117,114,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,105,100,100,101,110,62,49,60,47,104,105,100,100,101,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,70,111,114,101,103,114,111,117,110, +100,47,66,97,99,107,103,114,111,117,110,100,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65,76,60,47, +111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,52,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,52,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,44, +49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,83,81,76,85,115,101,83,121,115,116,101,109,66, +97,99,107,103,114,111,117,110,100,67,111,108,111,117,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,32,115,121,115,116, +101,109,32,98,97,99,107,103,114,111,117,110,100,32,99,111,108,111,114,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,83,81,76,67,117,115,116,111,109, +66,97,99,107,103,114,111,117,110,100,67,111,108,111,117,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,117,115,116,111,109,32, +98,97,99,107,103,114,111,117,110,100,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,99,116,108,67,111,108,111,117,114,80,105,99,107,101,114,34,32, +110,97,109,101,61,34,112,105,99,107,101,114,83,81,76,66,97,99,107,103,114, +111,117,110,100,67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,83,81,76,85,115,101,83,121,115,116,101,109,70,111, +114,101,103,114,111,117,110,100,67,111,108,111,117,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,32,115,121,115,116,101, +109,32,102,111,114,101,103,114,111,117,110,100,32,99,111,108,111,114,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,83,81,76,67,117,115,116,111,109, +70,111,114,101,103,114,111,117,110,100,67,111,108,111,117,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,117,115,116,111,109, +32,102,111,114,101,103,114,111,117,110,100,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,99,116,108,67,111,108,111,117,114,80,105,99,107,101, +114,34,32,110,97,109,101,61,34,112,105,99,107,101,114,83,81,76,70,111,114, +101,103,114,111,117,110,100,67,111,108,111,117,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,81,76,77,97,114,103,105,110, +66,97,99,107,103,114,111,117,110,100,67,111,108,111,117,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,114,103,105,110,32,98, +97,99,107,103,114,111,117,110,100,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,99,116,108,67,111,108,111,117,114,80,105,99,107,101,114,34,32, +110,97,109,101,61,34,112,105,99,107,101,114,83,81,76,77,97,114,103,105, +110,66,97,99,107,103,114,111,117,110,100,67,111,108,111,117,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,114, +101,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119, +120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,52,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,52,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,44,49,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,81,76, +67,97,114,101,116,67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,67,97,114,101,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,99,116,108,67,111,108,111,117,114,80,105,99, +107,101,114,34,32,110,97,109,101,61,34,112,105,99,107,101,114,83,81,76, +67,97,114,101,116,67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,111,120,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,81,76,32,83,121,110,116, +97,120,32,72,105,103,104,108,105,103,104,116,105,110,103,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67, +65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,52, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,52,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,44,50,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,83,81,76,67,111,108,111,117,114, +49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,117,108, +116,105,108,105,110,101,32,99,111,109,109,101,110,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,108,111,117,114,80, +105,99,107,101,114,34,32,110,97,109,101,61,34,112,105,99,107,101,114,83, +81,76,67,111,108,111,117,114,49,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,55,48,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,83,81,76,67,111,108,111,117,114,54,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,111,117,98,108,101,32,113,117, +111,116,101,100,32,115,116,114,105,110,103,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,99,116,108,67,111,108,111,117,114,80,105,99,107,101, +114,34,32,110,97,109,101,61,34,112,105,99,107,101,114,83,81,76,67,111,108, +111,117,114,54,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55, +48,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +83,81,76,67,111,108,111,117,114,50,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,83,105,110,103,108,101,32,108,105,110,101,32,99,111, +109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99, +116,108,67,111,108,111,117,114,80,105,99,107,101,114,34,32,110,97,109,101, +61,34,112,105,99,107,101,114,83,81,76,67,111,108,111,117,114,50,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,81,76,67,111,108, +111,117,114,55,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +83,105,110,103,108,101,32,113,117,111,116,101,100,32,115,116,114,105,110, +103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,108,111,117,114,80,105,99,107,101,114,34,32,110,97,109,101,61,34,112, +105,99,107,101,114,83,81,76,67,111,108,111,117,114,55,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,83,81,76,67,111,108,111,117,114, +51,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,81,76,32, +100,111,99,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,108,111,117,114,80,105,99,107,101,114,34,32,110,97,109,101,61, +34,112,105,99,107,101,114,83,81,76,67,111,108,111,117,114,51,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,81,76,67,111,108,111,117, +114,49,48,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112, +101,114,97,116,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,67,111,108,111,117,114,80,105,99,107,101,114,34,32,110,97, +109,101,61,34,112,105,99,107,101,114,83,81,76,67,111,108,111,117,114,49, +48,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49,50, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,81,76, +67,111,108,111,117,114,52,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,78,117,109,98,101,114,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,99,116,108,67,111,108,111,117,114,80,105,99,107,101,114,34,32, +110,97,109,101,61,34,112,105,99,107,101,114,83,81,76,67,111,108,111,117, +114,52,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49, +50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83, +81,76,67,111,108,111,117,114,49,49,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,73,100,101,110,116,105,102,105,101,114,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,108,111,117,114, +80,105,99,107,101,114,34,32,110,97,109,101,61,34,112,105,99,107,101,114, +83,81,76,67,111,108,111,117,114,49,49,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,83,81,76,67,111,108,111,117,114,53,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,75,101,121,119,111,114,100, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,108, +111,117,114,80,105,99,107,101,114,34,32,110,97,109,101,61,34,112,105,99, +107,101,114,83,81,76,67,111,108,111,117,114,53,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,81,117,101,114,121,84,111,111,108,82,101,115, +117,108,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,105,100,100,101,110,62,49,60,47,104,105,100,100,101,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,112,121,81,117,111,116,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,82,101,115,117,108,116,32,99,111,112,121,32,113,117, +111,116,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,99,98,67,111,112,121,81,117,111,116, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,78,111,110,101,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +83,116,114,105,110,103,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,65,108,108,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116, +101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,112,121,81,117, +111,116,101,67,104,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,115, +117,108,116,32,99,111,112,121,32,113,117,111,116,101,32,99,104,97,114,97, +99,116,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,67,111,112,121,81,117,111,116,101, +67,104,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105, +116,101,109,62,34,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +39,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,112,121,83,101, +112,97,114,97,116,111,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,115, +117,108,116,32,99,111,112,121,32,102,105,101,108,100,32,115,101,112,97, +114,97,116,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,99,98,67,111,112,121,83,101,112,97,114, +97,116,111,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105, +116,101,109,62,59,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +44,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,124,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,84,97,98,60,47,105,116,101, +109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,73,110,100,105,99,97,116,101,78,117,108, +108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,83,104,111,119,32,78,85,76,76,32,118, +97,108,117,101,115,32,97,115,32,38,108,116,59,78,85,76,76,38,103,116,59, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,73,110,100,105,99,97,116,101,78,117,108,108,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48, +60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,104, +111,117,115,97,110,100,115,83,101,112,97,114,97,116,111,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,84,104,111,117,115,97,110,100,115,32,115,101,112,97, +114,97,116,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,84,104,111,117,115,97,110, +100,115,83,101,112,97,114,97,116,111,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101, +100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,68,101,99,105,109,97,108,77, +97,114,107,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,99,105,109,97,108,32, +109,97,114,107,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,68,101,99,105,109,97,108,77, +97,114,107,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107, +101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,111,108,117,109,110,78,97,109,101,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,111,112,121,32,99,111,108,117,109,110,32,110,97,109,101,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,67,111,108,117,109,110,78,97,109,101,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60, +47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108, +81,117,101,114,121,84,111,111,108,70,105,108,101,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,105,100,100,101,110, +62,49,60,47,104,105,100,100,101,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,85,110,105,99,111, +100,101,70,105,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,97,100, +32,97,110,100,32,119,114,105,116,101,32,85,110,105,99,111,100,101,32,85, +84,70,45,56,32,102,105,108,101,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,87,114,105,116,101,66,79,77,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,87,114,105,116,101,32,66,79,77,32,102,111,114,32,85,84,70,32,102, +105,108,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,65,115, +107,83,97,118,101,67,111,110,102,105,114,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,111,32,110,111,116,32,112,114,111,109,112,116,32,102,111,114, +32,117,110,115,97,118,101,100,32,102,105,108,101,115,32,111,110,32,101, +120,105,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110, +108,81,117,101,114,121,84,111,111,108,70,97,118,111,117,114,105,116,101, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +105,100,100,101,110,62,49,60,47,104,105,100,100,101,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60, +47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,70,97,118,111,117,114,105,116,101,115,70,105,108,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,70,97,118,111,117,114,105,116,101,115,32,102,105, +108,101,32,112,97,116,104,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,105,108,101, +80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105, +99,107,101,114,70,97,118,111,117,114,105,116,101,115,70,105,108,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,109,101,115,115,97,103,101,62,83,101,108,101,99,116,32,102,105, +108,101,32,116,111,32,115,116,111,114,101,32,102,97,118,111,117,114,105, +116,101,115,32,113,117,101,114,105,101,115,60,47,109,101,115,115,97,103, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,70,76,80,95,79,80,69,78,124, +119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,81,117,101,114,121,84, +111,111,108,77,97,99,114,111,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,105,100,100,101,110,62,49,60,47,104,105, +100,100,101,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,77,97,99,114,111,115,70,105, +108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,99,114,111,115,32,102,105, +108,101,32,112,97,116,104,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,105,108,101, +80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105, +99,107,101,114,77,97,99,114,111,115,70,105,108,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,101, +115,115,97,103,101,62,83,101,108,101,99,116,32,102,105,108,101,32,116,111, +32,115,116,111,114,101,32,109,97,99,114,111,115,60,47,109,101,115,115,97, +103,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,70,76,80,95,79,80,69,78, +124,119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, +97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,81,117,101,114,121, +84,111,111,108,72,105,115,116,111,114,121,70,105,108,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,105,100,100,101, +110,62,49,60,47,104,105,100,100,101,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,72,105,115,116, +111,114,121,70,105,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,105,115, +116,111,114,121,32,102,105,108,101,32,112,97,116,104,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,105,108,101,80,105,99,107,101,114,67,116,114,108,34,32,110, +97,109,101,61,34,112,105,99,107,101,114,72,105,115,116,111,114,121,70,105, +108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,109,101,115,115,97,103,101,62,83,101,108,101,99,116, +32,102,105,108,101,32,116,111,32,115,116,111,114,101,32,113,117,101,114, +105,101,115,32,104,105,115,116,111,114,121,60,47,109,101,115,115,97,103, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,70,76,80,95,79,80,69,78,124, +119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,108,98,108,72,105,115,116,111,114,121, +77,97,120,81,117,101,114,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77, +97,120,105,109,117,109,32,113,117,101,114,105,101,115,32,116,111,32,115, +116,111,114,101,32,105,110,32,104,105,115,116,111,114,121,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,72,105,115,116,111,114,121, +77,97,120,81,117,101,114,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,49, +48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,72,105, +115,116,111,114,121,77,97,120,81,117,101,114,121,83,105,122,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,77,97,120,105,109,117,109,32,115,105,122,101,32, +111,102,32,97,32,115,116,111,114,101,100,32,113,117,101,114,121,32,40,105, +110,32,98,121,116,101,115,41,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,72,105,115,116, +111,114,121,77,97,120,81,117,101,114,121,83,105,122,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +97,108,117,101,62,49,48,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61, +34,112,110,108,83,101,114,118,101,114,83,116,97,116,117,115,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,105,100,100,101, +110,62,49,60,47,104,105,100,100,101,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,100,108,101, +80,114,111,99,101,115,115,67,111,108,111,117,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,73,100,108,101,32,80,114,111,99,101,115,115,32,67,111,108,111,117, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111, +108,111,117,114,80,105,99,107,101,114,34,32,110,97,109,101,61,34,112,105, +99,107,101,114,73,100,108,101,80,114,111,99,101,115,115,67,111,108,111, +117,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105, +122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,65,99,116,105,118,101,80,114, +111,99,101,115,115,67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,65,99,116,105,118,101,32,80,114,111,99,101,115,115,32,67,111,108,111, +117,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,108,111,117,114, +80,105,99,107,101,114,34,32,110,97,109,101,61,34,112,105,99,107,101,114, +65,99,116,105,118,101,80,114,111,99,101,115,115,67,111,108,111,117,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,83,108,111,119,80,114,111,99,101,115, +115,67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,108,111, +119,32,80,114,111,99,101,115,115,32,67,111,108,111,117,114,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,99,116,108,67,111,108,111,117,114,80,105,99,107,101,114,34,32,110, +97,109,101,61,34,112,105,99,107,101,114,83,108,111,119,80,114,111,99,101, +115,115,67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49, +50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,66,108, +111,99,107,101,100,80,114,111,99,101,115,115,67,111,108,111,117,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,66,108,111,99,107,101,100,32,80,114,111,99, +101,115,115,32,67,111,108,111,117,114,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,108,111,117,114,80,105,99,107,101,114,34,32,110,97,109,101,61,34,112, +105,99,107,101,114,66,108,111,99,107,101,100,80,114,111,99,101,115,115, +67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49,50,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,97,116, +97,98,97,115,101,68,101,115,105,103,110,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,105,100,100,101,110,62,49, +60,47,104,105,100,100,101,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,70,111,110,116,68,68,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,70,111,110,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,111,110,116,80,105,99,107,101,114,67,116,114,108,34,32,110,97,109, +101,61,34,112,105,99,107,101,114,70,111,110,116,68,68,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,103,65,103,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +105,100,100,101,110,62,49,60,47,104,105,100,100,101,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,77,97,120,82,111,119, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,120,105,109,117,109,32, +114,111,119,115,32,116,111,32,114,101,116,114,105,101,118,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,77,97,120,82, +111,119,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,49,48,48,60,47,118, +97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,77,97,120, +105,109,117,109,115,32,114,111,119,115,32,116,111,32,114,101,116,114,105, +101,118,101,32,105,110,116,111,32,111,117,116,112,117,116,32,119,105,110, +100,111,119,59,32,48,32,61,32,117,110,108,105,109,105,116,101,100,60,47, +116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108, +77,105,115,99,71,117,114,117,72,105,110,116,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,105,100,100,101,110,62,49, +60,47,104,105,100,100,101,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,117,112,112,114, +101,115,115,72,105,110,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,111,32, +110,111,116,32,115,104,111,119,32,103,117,114,117,32,104,105,110,116,115, +59,32,73,39,109,32,111,110,101,32,109,121,115,101,108,102,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,82,101,115,101,116,72,105, +110,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,115,101,116,32,103, +117,114,117,32,104,105,110,116,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,77,105,115,99,76,111,103,103,105,110,103,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,105,100,100,101, +110,62,49,60,47,104,105,100,100,101,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,76,111,103, +102,105,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76,111,103,102,105,108, +101,32,40,37,73,68,32,119,105,108,108,32,98,101,32,114,101,112,108,97,99, +101,100,32,119,105,116,104,32,116,104,101,32,80,114,111,99,101,115,115, +32,73,68,41,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,105, +108,101,80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101,61,34, +112,105,99,107,101,114,76,111,103,102,105,108,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,101, +115,115,97,103,101,62,83,101,108,101,99,116,32,108,111,103,32,102,105,108, +101,60,47,109,101,115,115,97,103,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,70,76,80,95,79,80,69,78,124,119,120,70,76,80,95,85,83,69,95,84,69,88, +84,67,84,82,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116, +105,112,62,69,110,116,101,114,32,97,32,102,105,108,101,110,97,109,101,32, +116,111,32,119,114,105,116,101,32,97,112,112,108,105,99,97,116,105,111, +110,32,108,111,103,115,32,116,111,46,60,47,116,111,111,108,116,105,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,111,120,34,32,110, +97,109,101,61,34,114,97,100,76,111,103,108,101,118,101,108,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,76,111,103,32,76,101,118,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +38,97,109,112,59,78,111,32,108,111,103,103,105,110,103,60,47,105,116,101, +109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,105,116,101,109,62,38,97,109,112,59,69,114,114,111,114, +115,32,111,110,108,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101, +109,62,69,114,114,111,114,115,32,97,110,100,32,78,38,97,109,112,59,111, +116,105,99,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,69,114,114,111,114,115,44,32,78,111,116,105,99,101,115,44,32,38,97,109, +112,59,83,81,76,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +38,97,109,112,59,68,101,98,117,103,32,40,110,111,116,32,114,101,99,111, +109,109,101,110,100,101,100,32,102,111,114,32,110,111,114,109,97,108,32, +117,115,101,41,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,101,108,101,99,116,105,111,110,62,50,60,47,115,101,108, +101,99,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,100,105,109,101,110,115,105,111,110,62, +49,60,47,100,105,109,101,110,115,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,82,65,95,83,80,69,67,73,70,89,95,67,79,76,83,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,116,111,111,108,116,105,112,62,83,101,108,101,99,116, +32,116,104,101,32,108,101,118,101,108,32,111,102,32,100,101,116,97,105, +108,32,116,111,32,114,101,99,111,114,100,32,105,110,32,116,104,101,32,108, +111,103,102,105,108,101,46,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116, +111,111,108,116,105,112,62,65,99,99,101,112,116,32,116,104,101,32,99,117, +114,114,101,110,116,32,115,101,116,116,105,110,103,115,32,97,110,100,32, +99,108,111,115,101,32,116,104,101,32,100,105,97,108,111,103,117,101,46, +60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,67, +97,110,99,101,108,32,97,110,121,32,99,104,97,110,103,101,115,32,97,110, +100,32,99,108,111,115,101,32,116,104,101,32,100,105,97,108,111,103,117, +101,46,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_79 = 1417; +static unsigned char xml_res_file_79[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,80,97,115,115,119,111,114,100,34,62,10,32,32,32,32, +60,116,105,116,108,101,62,67,104,97,110,103,101,32,80,97,115,115,119,111, +114,100,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101, +62,49,55,53,44,55,51,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84, +69,77,95,77,69,78,85,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,67,117,114,114, +101,110,116,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,67,117,114, +114,101,110,116,32,80,97,115,115,119,111,114,100,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,60,112,111,115,62,53,44,55,100,60,47,112,111,115, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,117,114,114,101,110, +116,34,62,10,32,32,32,32,32,32,60,112,111,115,62,55,48,44,53,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,60,115,105,122,101,62,49,48,48,44,45, +49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,80,65,83,83,87,79,82,68,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,78,101,119,34,62, +10,32,32,32,32,32,32,60,108,97,98,101,108,62,78,101,119,32,80,97,115,115, +119,111,114,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112, +111,115,62,53,44,50,50,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,78,101,119,34,62,10,32,32,32,32,32,32,60,112,111, +115,62,55,48,44,50,48,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60, +115,105,122,101,62,49,48,48,44,45,49,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,80,65,83,83,87, +79,82,68,60,47,115,116,121,108,101,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,108,98,108,67,111,110,102,105,114,109,34,62,10,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,111,110,102,105,114,109,32,80,97,115,115,119, +111,114,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111, +115,62,53,44,51,55,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,110,102,105,114,109,34,62,10,32,32,32,32,32,32, +60,112,111,115,62,55,48,44,51,53,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,60,115,105,122,101,62,49,48,48,44,45,49,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,80,65, +83,83,87,79,82,68,60,47,115,116,121,108,101,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,60,108,97,98, +101,108,62,38,97,109,112,59,72,101,108,112,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,60,112,111,115,62,53,44,53,53,100,60,47,112,111,115,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,112,111,115,62,54,51,44,53,53,100,60,47, +112,111,115,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60, +112,111,115,62,49,50,48,44,53,53,100,60,47,112,111,115,62,10,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62, +10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_80 = 5273; +static unsigned char xml_res_file_80[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,82,101,112,111,114,116,34,62,10,32,32,32,32,60,116, +105,116,108,101,62,71,101,110,101,114,97,116,101,32,97,32,114,101,112,111, +114,116,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101, +62,50,53,51,44,51,48,51,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,105,116,108,101,34, +62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,112,111,114,116, +32,84,105,116,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60, +112,111,115,62,53,44,53,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,84,105,116,108,101,34,62,10,32,32,32,32,32,32,60, +112,111,115,62,53,44,49,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +60,115,105,122,101,62,50,52,51,44,45,49,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,69,110,116,101,114, +32,97,32,116,105,116,108,101,32,102,111,114,32,116,104,101,32,114,101,112, +111,114,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,78,111,116,101,115,34,62,10,32,32,32,32,32,32, +60,108,97,98,101,108,62,82,101,112,111,114,116,32,78,111,116,101,115,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,53,44,51, +53,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116, +78,111,116,101,115,34,62,10,32,32,32,32,32,32,60,112,111,115,62,53,44,52, +53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,105,122,101,62, +50,52,51,44,52,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,69,95,65,85,84,79,95,83,67,82,79,76,76, +124,119,120,84,69,95,77,85,76,84,73,76,73,78,69,124,119,120,72,83,67,82, +79,76,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,69,110,116,101,114,32,97,110,121,32,97,100,100,105,116, +105,111,110,97,108,32,110,111,116,101,115,32,116,111,32,105,110,99,108, +117,100,101,32,111,110,32,116,104,101,32,114,101,112,111,114,116,60,47, +116,111,111,108,116,105,112,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +83,113,108,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,99, +108,117,100,101,32,116,104,101,32,83,81,76,32,105,110,32,116,104,101,32, +114,101,112,111,114,116,63,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,60,112,111,115,62,53,44,57,57,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,60,116,111,111,108,116,105,112,62,73,110,99,108,117,100,101,32,116, +104,101,32,83,81,76,32,102,114,111,109,32,116,104,101,32,111,98,106,101, +99,116,32,111,114,32,113,117,101,114,121,32,105,110,32,116,104,101,32,114, +101,112,111,114,116,63,60,47,116,111,111,108,116,105,112,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,111,120,34,32, +110,97,109,101,61,34,115,98,70,111,114,109,97,116,34,62,10,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,117,116,112,117,116,32,102,111,114,109, +97,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62, +53,44,49,49,51,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,105, +122,101,62,50,52,51,44,52,53,100,60,47,115,105,122,101,62,10,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,114,98,72,116,109,108,34,62,10,32,32,32, +32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,88,72,84,77,76,32,49, +46,48,32,84,114,97,110,115,105,116,105,111,110,97,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,118,97,108,117,101,62,49,60,47,118,97,108, +117,101,62,10,32,32,32,32,32,32,60,112,111,115,62,49,48,44,49,50,56,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,82,66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,60,116,111,111,108,116,105,112,62,67,114,101,97,116,101,32,116,104, +101,32,114,101,112,111,114,116,32,105,110,32,88,72,84,77,76,32,49,46,48, +32,84,114,97,110,115,105,116,105,111,110,97,108,32,102,111,114,109,97,116, +60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,114,98,88,109,108,34,62,10,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,88,77,76,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,60,118,97,108,117,101,62,49,60,47,118,97,108,117,101,62,10,32, +32,32,32,32,32,60,112,111,115,62,49,48,44,49,52,49,100,60,47,112,111,115, +62,10,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,67,114,101,97, +116,101,32,116,104,101,32,114,101,112,111,114,116,32,105,110,32,88,77,76, +32,102,111,114,109,97,116,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,111,120, +34,32,110,97,109,101,61,34,115,98,83,116,121,108,101,115,104,101,101,116, +34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,83,116,121,108,101,115, +104,101,101,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112, +111,115,62,53,44,49,54,51,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +60,115,105,122,101,62,50,52,51,44,55,53,100,60,47,115,105,122,101,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,114,98,72,116,109,108,66,117, +105,108,116,105,110,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,69,109,98,101,100,32,116,104,101,32,100,101,102,97,117, +108,116,32,115,116,121,108,101,115,104,101,101,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,118,97,108,117,101,62,49,60,47,118,97,108, +117,101,62,10,32,32,32,32,32,32,60,112,111,115,62,49,48,44,49,55,56,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,82,66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,60,116,111,111,108,116,105,112,62,69,109,98,101,100,32,112,103,65, +100,109,105,110,39,115,32,100,101,102,97,117,108,116,32,115,116,121,108, +101,115,104,101,101,116,32,105,110,116,111,32,116,104,101,32,114,101,112, +111,114,116,46,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,114,98,72,116,109,108,69,109,98,101,100,34,62,10, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,69,109,98,101, +100,32,97,110,32,101,120,116,101,114,110,97,108,32,115,116,121,108,101, +115,104,101,101,116,32,40,115,112,101,99,105,102,105,101,100,32,102,105, +108,101,32,109,117,115,116,32,101,120,105,115,116,41,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,112,111,115,62,49,48,44,49,57,49,100,60, +47,112,111,115,62,10,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62, +69,109,98,101,100,32,97,110,32,101,120,116,101,114,110,97,108,32,115,116, +121,108,101,115,104,101,101,116,32,105,110,116,111,32,116,104,101,32,114, +101,112,111,114,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,114,98,72,116,109,108,76,105,110,107,34, +62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,76,105, +110,107,32,116,111,32,97,110,32,101,120,116,101,114,110,97,108,32,115,116, +121,108,101,115,104,101,101,116,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,60,112,111,115,62,49,48,44,50,48,52,100,60,47,112,111,115,62,10, +32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,73,110,99,108,117,100, +101,32,97,32,108,105,110,107,32,116,111,32,97,110,32,101,120,116,101,114, +110,97,108,32,115,116,121,108,101,115,104,101,101,116,32,105,110,32,116, +104,101,32,114,101,112,111,114,116,46,60,47,116,111,111,108,116,105,112, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,114,98,88,109,108,80, +108,97,105,110,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97, +109,112,59,68,111,32,110,111,116,32,117,115,101,32,97,32,115,116,121,108, +101,115,104,101,101,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +60,118,97,108,117,101,62,49,60,47,118,97,108,117,101,62,10,32,32,32,32, +32,32,60,112,111,115,62,49,48,44,49,55,56,100,60,47,112,111,115,62,10,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,60,116,111,111,108,116, +105,112,62,68,111,32,110,111,116,32,117,115,101,32,97,32,115,116,121,108, +101,115,104,101,101,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,114,98,88,109,108,76,105,110,107,34,62,10, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,76,105,110,107, +32,116,111,32,97,110,32,101,120,116,101,114,110,97,108,32,115,116,121,108, +101,115,104,101,101,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +60,112,111,115,62,49,48,44,49,57,49,100,60,47,112,111,115,62,10,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,73,110,99,108,117,100,101,32, +97,32,108,105,110,107,32,116,111,32,116,104,101,32,115,112,101,99,105,102, +105,101,100,32,115,116,121,108,101,115,104,101,101,116,32,105,110,32,116, +104,101,32,88,77,76,32,102,105,108,101,60,47,116,111,111,108,116,105,112, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,114,98,88,109,108,80, +114,111,99,101,115,115,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,88,83,76,84,32,80,114,111,99,101,115,115,32,116,104, +101,32,88,77,76,32,100,97,116,97,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,60,112,111,115,62,49,48,44,50,48,52,100,60,47,112,111,115,62,10, +32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,80,114,111,99,101,115, +115,32,116,104,101,32,88,77,76,32,100,97,116,97,32,117,115,105,110,103, +32,116,104,101,32,115,112,101,99,105,102,105,101,100,32,115,116,121,108, +101,115,104,101,101,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,83,116,121,108,101,115,104,101,101,116, +34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,110,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115, +62,49,48,44,50,50,51,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,72,116,109,108,83,116,121,108,101,115,104,101,101, +116,34,62,10,32,32,32,32,32,32,60,112,111,115,62,54,48,44,50,50,48,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,105,122,101,62,49,54,50, +44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,83,101,108,101,99,116,32,116,104,101,32,115,116,121, +108,101,115,104,101,101,116,32,116,111,32,117,115,101,46,60,47,116,111, +111,108,116,105,112,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,88, +109,108,83,116,121,108,101,115,104,101,101,116,34,62,10,32,32,32,32,32, +32,60,112,111,115,62,54,48,44,50,50,48,100,60,47,112,111,115,62,10,32,32, +32,32,32,32,60,115,105,122,101,62,49,54,50,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,83,101,108, +101,99,116,32,116,104,101,32,115,116,121,108,101,115,104,101,101,116,32, +116,111,32,117,115,101,46,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110, +97,109,101,61,34,98,116,110,83,116,121,108,101,115,104,101,101,116,34,62, +10,32,32,32,32,32,32,60,108,97,98,101,108,62,46,46,46,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,112,111,115,62,50,50,55,44,50,50,48,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,105,122,101,62,49,53,44, +45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,83,101,108,101,99,116,32,116,104,101,32,115,116,121, +108,101,115,104,101,101,116,32,116,111,32,117,115,101,46,60,47,116,111, +111,108,116,105,112,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +70,105,108,101,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,79,117, +116,112,117,116,32,102,105,108,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,60,112,111,115,62,53,44,50,52,56,100,60,47,112,111,115,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,72,116,109,108,70,105,108,101, +34,62,10,32,32,32,32,32,32,60,112,111,115,62,53,53,44,50,52,53,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,60,115,105,122,101,62,49,55,53,44,45, +49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,116,111,111,108, +116,105,112,62,83,101,108,101,99,116,32,116,104,101,32,102,105,108,101, +32,116,111,32,119,114,105,116,101,32,116,104,101,32,114,101,112,111,114, +116,32,116,111,46,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,88,109,108,70,105,108,101,34,62,10,32,32,32, +32,32,32,60,112,111,115,62,53,53,44,50,52,53,100,60,47,112,111,115,62,10, +32,32,32,32,32,32,60,115,105,122,101,62,49,55,53,44,45,49,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,83, +101,108,101,99,116,32,116,104,101,32,102,105,108,101,32,116,111,32,119, +114,105,116,101,32,116,104,101,32,114,101,112,111,114,116,32,116,111,46, +60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116, +110,70,105,108,101,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,46, +46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62, +50,51,53,44,50,52,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60,115, +105,122,101,62,49,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,83,101,108,101,99,116,32,116, +104,101,32,102,105,108,101,32,116,111,32,119,114,105,116,101,32,116,104, +101,32,114,101,112,111,114,116,32,116,111,46,60,47,116,111,111,108,116, +105,112,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,66,114,111,119, +115,101,114,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,101, +110,32,116,104,101,32,111,117,116,112,117,116,32,102,105,108,101,32,105, +110,32,116,104,101,32,100,101,102,97,117,108,116,32,98,114,111,119,115, +101,114,63,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115, +62,53,44,50,54,53,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,60,112,111,115,62,50,44,50,56,53,100,60,47,112,111,115,62, +10,32,32,32,32,32,32,60,115,116,121,108,101,47,62,10,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,60,112,111,115,62,49,52,55,44,50,56,53,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,116,121,108,101,47,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,60,112,111,115,62,50,48,48,44,50,56,53,100,60,47,112,111,115,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101, +99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_81 = 16296; +static unsigned char xml_res_file_81[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,82,101,115,116,111,114,101,34,62,10,32,32,32,32,60, +116,105,116,108,101,62,82,101,115,116,111,114,101,60,47,116,105,116,108, +101,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,49,57,51,100,60, +47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120, +68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120, +67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119, +120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98, +108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110, +98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,112,111,115,62,50,44,50,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,50,56,53,44,49,56,52,100,60,47,115,105, +122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,78,66,95,66,79,84,84,79,77,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,32,79,112,116, +105,111,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, +97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,70,105,108,101,79, +112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,70,111,114,109,97,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,70,111,114,109,97,116,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,70,111,114,109,97,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,105,108,101,110,97, +109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,70,105,108,101,110,97,109,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70, +105,108,101,110,97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,70,105,108,101,110,97,109,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,46,46,46,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +78,117,109,98,101,114,79,102,74,111,98,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,117,109, +98,101,114,32,79,102,32,74,111,98,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,117,109, +98,101,114,79,102,74,111,98,115,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,82,111,108, +101,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,82,111,108,101,110,97,109,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,82,111,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68, +79,87,78,124,119,120,67,66,95,83,79,82,84,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111, +116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,82,101,115,116,111,114,101,32,79,112, +116,105,111,110,115,32,35,49,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68, +117,109,112,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,99,116,105, +111,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69, +82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,83,101,99,116,105,111,110,80, +114,101,68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,101,45,100, +97,116,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,101,99,116, +105,111,110,68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,116,97,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,101,99,116,105, +111,110,80,111,115,116,68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80, +111,115,116,45,100,97,116,97,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101, +32,79,102,32,79,98,106,101,99,116,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101, +110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,79,110, +108,121,68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,110,108,121,32, +100,97,116,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,79,110, +108,121,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,110,108, +121,32,115,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,111,110,39, +116,32,115,97,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119, +120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,78,111,79,119,110, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110,101,114,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,78,111,80,114,105,118,105, +108,101,103,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,105,118,105, +108,101,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,78,111, +84,97,98,108,101,115,112,97,99,101,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +84,97,98,108,101,115,112,97,99,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,115, +116,111,114,101,32,79,112,116,105,111,110,115,32,35,50,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,68,117,109,112,79,112,116,105,111,110,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,66,111,120,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,81,117,101,114,105,101,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101, +110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,67,114, +101,97,116,101,68,98,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,99,108,117, +100,101,32,67,82,69,65,84,69,32,68,65,84,65,66,65,83,69,32,115,116,97,116, +101,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,67,108,101,97,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,108,101,97,110, +32,98,101,102,111,114,101,32,114,101,115,116,111,114,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,83,105,110,103,108,101,88,97, +99,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,83,105,110,103,108,101,32,116,114, +97,110,115,97,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,105,115,97, +98,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69, +82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,68,105,115,97,98,108,101,84,114, +105,103,103,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,114,105,103,103, +101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,78,111,68,97, +116,97,70,111,114,70,97,105,108,101,100,84,97,98,108,101,115,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,111,32,68,97,116,97,32,102,111,114,32,70,97,105, +108,101,100,32,84,97,98,108,101,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,105,115,99, +101,108,108,97,110,111,117,115,32,47,32,66,101,104,97,118,105,111,114,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73, +67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,85,115,101,83,101,116,83,101,115, +115,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,32,83,69,84, +32,83,69,83,83,73,79,78,32,65,85,84,72,79,82,73,90,65,84,73,79,78,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,69,120,105,116,79,110,69, +114,114,111,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,120,105,116,32,79,110, +32,69,114,114,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,86,101,114,98,111,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,101,114, +98,111,115,101,32,109,101,115,115,97,103,101,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,79,98,106,101,99,116,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +99,116,108,67,104,101,99,107,84,114,101,101,86,105,101,119,34,32,110,97, +109,101,61,34,99,116,118,79,98,106,101,99,116,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,82,95, +72,65,83,95,66,85,84,84,79,78,83,124,119,120,83,73,77,80,76,69,95,66,79, +82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,77,101,115,115,97,103,101,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,116,120,116,77,101,115,115,97,103,101,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84, +69,95,77,85,76,84,73,76,73,78,69,124,119,120,84,69,95,82,69,65,68,79,78, +76,89,124,119,120,72,83,67,82,79,76,76,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68, +124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,53,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,86,105,101,119,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,68,105,115,112,108,97,121,32,111,98,106,101,99,116,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,116,111,111,108,116,105,112,62,68,105,115,112,108,97,121,32,111,98,106, +101,99,116,115,32,99,111,110,116,97,105,110,101,100,32,105,110,32,116,104, +101,32,100,117,109,112,32,111,110,32,97,32,115,112,101,99,105,102,105,99, +32,116,97,98,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,82,101, +115,116,111,114,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,71,82,79,87,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99, +116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +void InitXmlResource() +{ + + // Check for memory FS. If not present, load the handler: + { + wxMemoryFSHandler::AddFile(wxT("XRC_resource/dummy_file"), wxT("dummy one")); + wxFileSystem fsys; + wxFSFile *f = fsys.OpenFile(wxT("memory:XRC_resource/dummy_file")); + wxMemoryFSHandler::RemoveFile(wxT("XRC_resource/dummy_file")); + if (f) delete f; + else wxFileSystem::AddHandler(new wxMemoryFSHandler); + } + + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_ddPrecisionScaleDialog.xrc"), xml_res_file_0, xml_res_size_0, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_ddTableNameDialog.xrc"), xml_res_file_1, xml_res_size_1, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgAddFavourite.xrc"), xml_res_file_2, xml_res_size_2, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgAggregate.xrc"), xml_res_file_3, xml_res_size_3, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgCast.xrc"), xml_res_file_4, xml_res_size_4, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgCheck.xrc"), xml_res_file_5, xml_res_size_5, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgCollation.xrc"), xml_res_file_6, xml_res_size_6, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgColumn.xrc"), xml_res_file_7, xml_res_size_7, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgConnect.xrc"), xml_res_file_8, xml_res_size_8, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgConversion.xrc"), xml_res_file_9, xml_res_size_9, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgDatabase.xrc"), xml_res_file_10, xml_res_size_10, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgDirectDbg.xrc"), xml_res_file_11, xml_res_size_11, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgDomain.xrc"), xml_res_file_12, xml_res_size_12, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgEditGridOptions.xrc"), xml_res_file_13, xml_res_size_13, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgEventTrigger.xrc"), xml_res_file_14, xml_res_size_14, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgExtTable.xrc"), xml_res_file_15, xml_res_size_15, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgExtension.xrc"), xml_res_file_16, xml_res_size_16, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgFindReplace.xrc"), xml_res_file_17, xml_res_size_17, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgForeignDataWrapper.xrc"), xml_res_file_18, xml_res_size_18, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgForeignKey.xrc"), xml_res_file_19, xml_res_size_19, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgForeignServer.xrc"), xml_res_file_20, xml_res_size_20, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgForeignTable.xrc"), xml_res_file_21, xml_res_size_21, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgFunction.xrc"), xml_res_file_22, xml_res_size_22, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgGroup.xrc"), xml_res_file_23, xml_res_size_23, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgHbaConfig.xrc"), xml_res_file_24, xml_res_size_24, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgIndex.xrc"), xml_res_file_25, xml_res_size_25, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgIndexConstraint.xrc"), xml_res_file_26, xml_res_size_26, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgJob.xrc"), xml_res_file_27, xml_res_size_27, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgLanguage.xrc"), xml_res_file_28, xml_res_size_28, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgMainConfig.xrc"), xml_res_file_29, xml_res_size_29, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgManageFavourites.xrc"), xml_res_file_30, xml_res_size_30, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgManageMacros.xrc"), xml_res_file_31, xml_res_size_31, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgMoveTablespace.xrc"), xml_res_file_32, xml_res_size_32, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgOperator.xrc"), xml_res_file_33, xml_res_size_33, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgPackage.xrc"), xml_res_file_34, xml_res_size_34, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgPgpassConfig.xrc"), xml_res_file_35, xml_res_size_35, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgReassignDropOwned.xrc"), xml_res_file_36, xml_res_size_36, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepCluster.xrc"), xml_res_file_37, xml_res_size_37, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepClusterUpgrade.xrc"), xml_res_file_38, xml_res_size_38, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepListen.xrc"), xml_res_file_39, xml_res_size_39, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepNode.xrc"), xml_res_file_40, xml_res_size_40, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepPath.xrc"), xml_res_file_41, xml_res_size_41, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepSequence.xrc"), xml_res_file_42, xml_res_size_42, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepSet.xrc"), xml_res_file_43, xml_res_size_43, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepSetMerge.xrc"), xml_res_file_44, xml_res_size_44, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepSetMove.xrc"), xml_res_file_45, xml_res_size_45, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepSubscription.xrc"), xml_res_file_46, xml_res_size_46, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepTable.xrc"), xml_res_file_47, xml_res_size_47, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgResourceGroup.xrc"), xml_res_file_48, xml_res_size_48, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRole.xrc"), xml_res_file_49, xml_res_size_49, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRule.xrc"), xml_res_file_50, xml_res_size_50, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgSchedule.xrc"), xml_res_file_51, xml_res_size_51, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgSchema.xrc"), xml_res_file_52, xml_res_size_52, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgSearchObject.xrc"), xml_res_file_53, xml_res_size_53, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgSelectConnection.xrc"), xml_res_file_54, xml_res_size_54, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgSequence.xrc"), xml_res_file_55, xml_res_size_55, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgServer.xrc"), xml_res_file_56, xml_res_size_56, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgStep.xrc"), xml_res_file_57, xml_res_size_57, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgSynonym.xrc"), xml_res_file_58, xml_res_size_58, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgTable.xrc"), xml_res_file_59, xml_res_size_59, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgTablespace.xrc"), xml_res_file_60, xml_res_size_60, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgTextSearchConfiguration.xrc"), xml_res_file_61, xml_res_size_61, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgTextSearchDictionary.xrc"), xml_res_file_62, xml_res_size_62, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgTextSearchParser.xrc"), xml_res_file_63, xml_res_size_63, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgTextSearchTemplate.xrc"), xml_res_file_64, xml_res_size_64, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgTrigger.xrc"), xml_res_file_65, xml_res_size_65, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgType.xrc"), xml_res_file_66, xml_res_size_66, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgUser.xrc"), xml_res_file_67, xml_res_size_67, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgUserMapping.xrc"), xml_res_file_68, xml_res_size_68, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgView.xrc"), xml_res_file_69, xml_res_size_69, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmBackup.xrc"), xml_res_file_70, xml_res_size_70, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmBackupGlobals.xrc"), xml_res_file_71, xml_res_size_71, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmBackupServer.xrc"), xml_res_file_72, xml_res_size_72, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmExport.xrc"), xml_res_file_73, xml_res_size_73, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmGrantWizard.xrc"), xml_res_file_74, xml_res_size_74, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmHint.xrc"), xml_res_file_75, xml_res_size_75, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmImport.xrc"), xml_res_file_76, xml_res_size_76, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmMaintenance.xrc"), xml_res_file_77, xml_res_size_77, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmOptions.xrc"), xml_res_file_78, xml_res_size_78, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmPassword.xrc"), xml_res_file_79, xml_res_size_79, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmReport.xrc"), xml_res_file_80, xml_res_size_80, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmRestore.xrc"), xml_res_file_81, xml_res_size_81, wxT("text/xml")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_ddPrecisionScaleDialog.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_ddTableNameDialog.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgAddFavourite.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgAggregate.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgCast.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgCheck.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgCollation.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgColumn.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgConnect.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgConversion.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgDatabase.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgDirectDbg.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgDomain.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgEditGridOptions.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgEventTrigger.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgExtTable.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgExtension.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgFindReplace.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgForeignDataWrapper.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgForeignKey.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgForeignServer.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgForeignTable.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgFunction.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgGroup.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgHbaConfig.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgIndex.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgIndexConstraint.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgJob.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgLanguage.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgMainConfig.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgManageFavourites.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgManageMacros.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgMoveTablespace.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgOperator.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgPackage.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgPgpassConfig.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgReassignDropOwned.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepCluster.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepClusterUpgrade.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepListen.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepNode.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepPath.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepSequence.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepSet.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepSetMerge.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepSetMove.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepSubscription.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepTable.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgResourceGroup.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRole.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRule.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgSchedule.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgSchema.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgSearchObject.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgSelectConnection.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgSequence.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgServer.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgStep.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgSynonym.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgTable.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgTablespace.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgTextSearchConfiguration.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgTextSearchDictionary.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgTextSearchParser.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgTextSearchTemplate.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgTrigger.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgType.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgUser.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgUserMapping.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgView.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmBackup.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmBackupGlobals.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmBackupServer.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmExport.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmGrantWizard.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmHint.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmImport.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmMaintenance.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmOptions.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmPassword.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmReport.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmRestore.xrc")); +} diff --git a/ui/ddPrecisionScaleDialog.xrc b/ui/ddPrecisionScaleDialog.xrc new file mode 100644 index 0000000..e763fd7 --- /dev/null +++ b/ui/ddPrecisionScaleDialog.xrc @@ -0,0 +1,97 @@ + + + + Datatype properties + 300,165d + + + 1 + 0 + 0 + + + 296,140d + 0 + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/ddTableNameDialog.xrc b/ui/ddTableNameDialog.xrc new file mode 100644 index 0000000..fe50845 --- /dev/null +++ b/ui/ddTableNameDialog.xrc @@ -0,0 +1,84 @@ + + + + Table properties + 300,165d + + + 1 + 0 + 0 + + + 296,140d + 0 + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgAddFavourite.xrc b/ui/dlgAddFavourite.xrc new file mode 100644 index 0000000..22bd989 --- /dev/null +++ b/ui/dlgAddFavourite.xrc @@ -0,0 +1,84 @@ + + + + Add favourite + 220,250d + + + 216,225d + 1 + 5 + 5 + 3 + 0 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 1 + + + + + wxLEFT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + + 0,0d + + + + + + 3 + 0 + + 0,0d + + + + + 1 + + wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + + wxEXPAND + + + + diff --git a/ui/dlgAggregate.xrc b/ui/dlgAggregate.xrc new file mode 100644 index 0000000..f21e53d --- /dev/null +++ b/ui/dlgAggregate.xrc @@ -0,0 +1,288 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + 0 + + + 1 + 5 + 5 + 0 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 60,-1d + + wxEXPAND|wxALIGN_BOTTOM|wxALL + 4 + + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 60,-1d + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgCast.xrc b/ui/dlgCast.xrc new file mode 100644 index 0000000..0e42d04 --- /dev/null +++ b/ui/dlgCast.xrc @@ -0,0 +1,197 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 2 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgCheck.xrc b/ui/dlgCheck.xrc new file mode 100644 index 0000000..57584cb --- /dev/null +++ b/ui/dlgCheck.xrc @@ -0,0 +1,170 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 1 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + + + 2 + 5 + 5 + 0 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgCollation.xrc b/ui/dlgCollation.xrc new file mode 100644 index 0000000..a6dbdde --- /dev/null +++ b/ui/dlgCollation.xrc @@ -0,0 +1,222 @@ + + + + + 220,280d + + + 1 + 0 + 0 + + + 216,255d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgColumn.xrc b/ui/dlgColumn.xrc new file mode 100644 index 0000000..43bfba9 --- /dev/null +++ b/ui/dlgColumn.xrc @@ -0,0 +1,319 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 10,10d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 4 + 5 + 0 + 0 + + + 5,6d + + + wxALL|wxGROW|wxALIGN_CENTRE + 4 + + + + 3 + 0 + + 0,0d + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + wxGROW + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgConnect.xrc b/ui/dlgConnect.xrc new file mode 100644 index 0000000..dcce0ad --- /dev/null +++ b/ui/dlgConnect.xrc @@ -0,0 +1,74 @@ + + + + Connect to Server + 205,83d + + + 1 + 3 + 0 + + + 205, 25d + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + Enter the password to use when connecting to the server. + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 12 + + + + + 1 + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 10 + + + 3,3d + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxALL + 8 + + + + diff --git a/ui/dlgConversion.xrc b/ui/dlgConversion.xrc new file mode 100644 index 0000000..bcbbddf --- /dev/null +++ b/ui/dlgConversion.xrc @@ -0,0 +1,227 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_TOP|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgDatabase.xrc b/ui/dlgDatabase.xrc new file mode 100644 index 0000000..204a7b6 --- /dev/null +++ b/ui/dlgDatabase.xrc @@ -0,0 +1,368 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 3 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 7 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + -1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 1 + 4 + 5 + 0 + 0 + + + 5,6d + + + wxALL|wxGROW|wxALIGN_CENTRE + 4 + + + + 3 + 0 + + 0,0d + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 0,1 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + wxALL|wxGROW|wxALIGN_CENTRE + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxGROW + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgDirectDbg.xrc b/ui/dlgDirectDbg.xrc new file mode 100644 index 0000000..76347a6 --- /dev/null +++ b/ui/dlgDirectDbg.xrc @@ -0,0 +1,86 @@ + + + + View Data Options + 450,210d + + + 1 + 0 + 0 + + + 400,180d + 0 + + + + + 1 + 5 + 5 + 1 + 0 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Set the function/procedure parameter values. + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 3 + 0 + + 0,0d + + + + + Accept the current options and close the dialogue. + 1 + + wxEXPAND|wxALL + 3 + + + + + Cancel any changes and close the dialogue. + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + + + + diff --git a/ui/dlgDomain.xrc b/ui/dlgDomain.xrc new file mode 100644 index 0000000..07d2545 --- /dev/null +++ b/ui/dlgDomain.xrc @@ -0,0 +1,302 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 5,112d + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + 1 + 5 + 5 + 0 + 0 + + + 270,-1d + + + wxGROW + + + + 5 + 0 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + wxGROW + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgEditGridOptions.xrc b/ui/dlgEditGridOptions.xrc new file mode 100644 index 0000000..fdab748 --- /dev/null +++ b/ui/dlgEditGridOptions.xrc @@ -0,0 +1,157 @@ + + + + View Data Options + 300,265d + + + 1 + 0 + 0 + + + 296,240d + + + + + 1 + 5 + 5 + 1 + 0 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + Lists the columns that the data will be sorted by. + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + Select a column to add to the sort list. + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 3 + 5 + 5 + 0 + 0,1,2 + + + + Add the select column for ascending sort. + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + 1 + + + + + Add the select column for descending sort. + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + 1 + + + + + Remove the selected sort column. + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + 1 + + + + + + + + + + + 1 + 0 + 1 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + Enter the filter string to apply to the data. SQL syntax should be used as the string will be used as a 'WHERE' clause. + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + Validate the syntax of the filter string. + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 3 + 0 + + 0,0d + + + + + Accept the current options and close the dialogue. + + wxEXPAND|wxALL + 3 + + + + + Cancel any changes and close the dialogue. + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/dlgEventTrigger.xrc b/ui/dlgEventTrigger.xrc new file mode 100644 index 0000000..312c0f1 --- /dev/null +++ b/ui/dlgEventTrigger.xrc @@ -0,0 +1,229 @@ + + + + 300,265d + + + 1 + 0 + 0 + + + 320,240d + + + + 2 + 5 + 5 + 1 + 3 + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 4 + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 4 + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 4 + + + + + + wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 5 + + + + + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 4 + + + + 405,313 + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + 4 + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 4 + + + + 1 + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 4 + + + + + + wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 5 + + + + + + + ENABLE + REPLICA + ALWAYS + + 210,38 + + + wxALL|wxEXPAND|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 4 + + + + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 4 + + + + + + DDL COMMAND START + DDL COMMAND END + SQL DROP + + 333,38 + + + wxALL|wxEXPAND|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 4 + + + + -1,-1 + 374,187 + + + wxALL|wxEXPAND|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 4 + + + + + + + wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL + 3 + + + + 4 + 1 + + + + + wxALL|wxEXPAND|wxALIGN_LEFT|wxALIGN_TOP + 3 + + + wxALIGN_LEFT|wxALIGN_TOP + 0,0d + + + + + 1 + + wxALL|wxEXPAND|wxALIGN_LEFT|wxALIGN_TOP + 3 + + + + + + wxALL|wxEXPAND|wxALIGN_LEFT|wxALIGN_TOP + 3 + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_LEFT|wxALIGN_TOP + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgExtTable.xrc b/ui/dlgExtTable.xrc new file mode 100644 index 0000000..5ae4c39 --- /dev/null +++ b/ui/dlgExtTable.xrc @@ -0,0 +1,160 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 3 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + wxVERTICAL + + 2,2d + + + + + + + wxEXPAND|wxALIGN_CENTER|wxALL + + + + + + wxEXPAND|wxALIGN_CENTER|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgExtension.xrc b/ui/dlgExtension.xrc new file mode 100644 index 0000000..7cb16e1 --- /dev/null +++ b/ui/dlgExtension.xrc @@ -0,0 +1,170 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 2 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgFindReplace.xrc b/ui/dlgFindReplace.xrc new file mode 100644 index 0000000..83bc398 --- /dev/null +++ b/ui/dlgFindReplace.xrc @@ -0,0 +1,204 @@ + + + + Find and Replace + 300,166d + + + 1 + 0 + 0 + + + 3 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Enter the string to search for + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + Find the specified text + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Enter the replacement text + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + Find and replace the specified text + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0,0d + + + 0,0d + + + + + Find and replace all occurrences of the specified text + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 3 + 2 + + + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + 1 + Begin searching at the current cursor position + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + Begin searching at the top of the text + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + 1 + Search forwards through the text + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + Search backwards through the text + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + Match on whole words + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + Match the case of the text + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + Use regular expressions when searching + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0,0d + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 0 + + 0,0d + + + + + Close the dialog + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + + + diff --git a/ui/dlgForeignDataWrapper.xrc b/ui/dlgForeignDataWrapper.xrc new file mode 100644 index 0000000..3276bf0 --- /dev/null +++ b/ui/dlgForeignDataWrapper.xrc @@ -0,0 +1,278 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 3 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 0 + 0 + + + 70,15d + + + + wxALL|wxEXPAND + 5 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + + + + + wxALIGN_CENTRE_VERTICAL + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + + wxALL|wxEXPAND|wxALIGN_BOTTOM|wxALIGN_CENTRE_HORIZONTAL + 5 + + + + 2 + + + + 13,58d + + wxALL|wxALIGN_RIGHT + 2 + + + + + 13,78d + + wxALL|wxALIGN_RIGHT + 2 + + + wxALIGN_RIGHT + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + 2,2d + + + + 7 + 2 + + 3,3d + + + + + + + + 3,3d + + + + + 1 + + + + 3,3d + + + + + + + + 3,3d + + + wxTOP|wxLEFT|wxRIGHT|wxGROW + + + 3,3d + + + + + + wxGROW|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgForeignKey.xrc b/ui/dlgForeignKey.xrc new file mode 100644 index 0000000..a2cb922 --- /dev/null +++ b/ui/dlgForeignKey.xrc @@ -0,0 +1,346 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 1 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 0 + 0 + + + + + wxTOP||wxLEFT|wxRIGHT|wxGROW + 2 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxTOP|wxBOTTOM|wxGROW + + + + 3 + 0 + + 0,0d + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + wxTOP|wxGROW + + + + + + + + + 2 + 5 + 5 + 0 + 0,1 + + + + + NO ACTION + RESTRICT + CASCADE + SET NULL + SET DEFAULT + + 1 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + NO ACTION + RESTRICT + CASCADE + SET NULL + SET DEFAULT + + 1 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgForeignServer.xrc b/ui/dlgForeignServer.xrc new file mode 100644 index 0000000..a7b284d --- /dev/null +++ b/ui/dlgForeignServer.xrc @@ -0,0 +1,274 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 3 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 0 + 0 + + + 70,15d + + + + wxALL|wxEXPAND + 5 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + + + + + wxALIGN_CENTRE_VERTICAL + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + + wxALL|wxEXPAND|wxALIGN_BOTTOM|wxALIGN_CENTRE_HORIZONTAL + 5 + + + + 2 + + + + 13,58d + + wxALL|wxALIGN_RIGHT + 2 + + + + + 13,78d + + wxALL|wxALIGN_RIGHT + 2 + + + wxALIGN_RIGHT + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + 2,2d + + + + 7 + 2 + + 3,3d + + + + + + + + 3,3d + + + + + 1 + + + + 3,3d + + + + + + + + 3,3d + + + wxTOP|wxLEFT|wxRIGHT|wxGROW + + + 3,3d + + + + + + wxGROW|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgForeignTable.xrc b/ui/dlgForeignTable.xrc new file mode 100644 index 0000000..d0eff32 --- /dev/null +++ b/ui/dlgForeignTable.xrc @@ -0,0 +1,398 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 5 + 5 + 0,1,2 + 0 + + + + 1 + 5 + 5 + 0 + 0 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + wxALL|wxALIGN_RIGHT + 2 + + + + + + wxALL|wxALIGN_RIGHT + 2 + + + + + + wxALL|wxALIGN_RIGHT + 2 + + 3 + + wxALIGN_RIGHT + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 0 + 0 + + + 70,15d + + + + wxALL|wxEXPAND + 5 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + + + + + wxALIGN_CENTRE_VERTICAL + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + + wxALL|wxEXPAND|wxALIGN_BOTTOM|wxALIGN_CENTRE_HORIZONTAL + 5 + + + + 2 + + + + 13,58d + + wxALL|wxALIGN_RIGHT + 2 + + + + + 13,78d + + wxALL|wxALIGN_RIGHT + 2 + + + wxALIGN_RIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgFunction.xrc b/ui/dlgFunction.xrc new file mode 100644 index 0000000..ddd3a30 --- /dev/null +++ b/ui/dlgFunction.xrc @@ -0,0 +1,633 @@ + + + + + 350,265d + + + 1 + 0 + 0 + + + 346,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 2 + 5 + 5 + + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + VOLATILE + STABLE + IMMUTABLE + + 0 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + UNSAFE + RESTRICTED + SAFE + + 0 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + + + + + + wxALL|wxEXPAND + 5 + + + + + + + + wxALIGN_CENTRE_VERTICAL + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + + + + + wxALIGN_CENTRE_VERTICAL + + + + 4 + + + + + + + + + + + + + + + + + + + + + + + wxTOP|wxBOTTOM + 5 + + + + + + wxALIGN_CENTRE_VERTICAL + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + + + + + wxALIGN_CENTRE_VERTICAL + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + 2 + 4 + 4 + 1 + + wxALL|wxEXPAND|wxALIGN_BOTTOM|wxALIGN_CENTRE_HORIZONTAL + 5 + + + + + + + + wxALL|wxALIGN_RIGHT + 2 + + + + + + wxALL|wxALIGN_RIGHT + 2 + + + + + + wxALL|wxALIGN_RIGHT + 2 + + 3 + + wxALIGN_RIGHT + + 0 + 0 + + + + + + + + 1 + 5 + 5 + 0 + 0,1 + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxALL|wxEXPAND + 5 + + + + + + wxALL|wxEXPAND + 5 + + + + + + + + + 1 + 4 + 5 + 0 + 0 + + + 5,6d + + + wxALL|wxGROW|wxALIGN_CENTRE + 4 + + + + 3 + 0 + + 0,0d + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 0,1 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + wxALL|wxGROW|wxALIGN_CENTRE + 4 + + + wxGROW + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 4 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 4 + + + + + + wxEXPAND|wxALL + 4 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgGroup.xrc b/ui/dlgGroup.xrc new file mode 100644 index 0000000..f45395b --- /dev/null +++ b/ui/dlgGroup.xrc @@ -0,0 +1,184 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 3 + 5 + 5 + 1 + 0,2 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 2,2d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 86,123d + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + 1 + 5 + 5 + + + + 18,-1d + + wxEXPAND|wxALIGN_BOTTOM|wxALL + 4 + + + + + 18,-1d + + wxEXPAND|wxALIGN_TOP|wxALL + 4 + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + 86,123d + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgHbaConfig.xrc b/ui/dlgHbaConfig.xrc new file mode 100644 index 0000000..a864a19 --- /dev/null +++ b/ui/dlgHbaConfig.xrc @@ -0,0 +1,156 @@ + + + + Client Access Configuration + 220,150d + + + 1 + 5 + 5 + 0 + 0 + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/dlgIndex.xrc b/ui/dlgIndex.xrc new file mode 100644 index 0000000..2574b71 --- /dev/null +++ b/ui/dlgIndex.xrc @@ -0,0 +1,377 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 1 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 6 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 1 + 0 + 0 + + + + + wxEXPAND|wxALL + 4 + + + + 2 + 5 + 5 + 1 + 0 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 5 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT + 4 + + + 15,3d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 10,3d + + + + 3 + + + + + + + + 15,3d + + + + + 1 + + + + wxTOP + 5 + + + wxEXPAND|wxALL + 4 + + + wxEXPAND|wxALL + 4 + + + + 4 + 0 + + 3,3d + + + + + + + + 3,3d + + + + + 50,-1d + + + + wxEXPAND|wxALL + 4 + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgIndexConstraint.xrc b/ui/dlgIndexConstraint.xrc new file mode 100644 index 0000000..79ef279 --- /dev/null +++ b/ui/dlgIndexConstraint.xrc @@ -0,0 +1,379 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 1 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 6 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 1 + 0 + 0 + + + + + wxEXPAND|wxALL + 4 + + + + 2 + 5 + 5 + 1 + 0 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 5 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT + 4 + + + 15,3d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 10,3d + + + + 3 + + + + + + + + 15,3d + + + + + 1 + + + + wxTOP + 5 + + + wxEXPAND|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALL + 4 + + + + 4 + 0 + + 3,3d + + + + + + + + 3,3d + + + + + 50,-1d + + + + wxEXPAND|wxALL + 4 + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgJob.xrc b/ui/dlgJob.xrc new file mode 100644 index 0000000..8031eab --- /dev/null +++ b/ui/dlgJob.xrc @@ -0,0 +1,326 @@ + + + + + 220,280d + + + 1 + 0 + 0 + + + 216,255d + 0 + + + + + 2 + 5 + 5 + 10 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + + 1 + 5 + 5 + 0 + 0 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 4 + 5 + 5 + 0 + + 0,0d + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + + + + + + 1 + 5 + 5 + 0 + 0 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 4 + 5 + 5 + 0 + + 0,0d + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgLanguage.xrc b/ui/dlgLanguage.xrc new file mode 100644 index 0000000..94d3354 --- /dev/null +++ b/ui/dlgLanguage.xrc @@ -0,0 +1,215 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 3 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgMainConfig.xrc b/ui/dlgMainConfig.xrc new file mode 100644 index 0000000..47cf9bb --- /dev/null +++ b/ui/dlgMainConfig.xrc @@ -0,0 +1,139 @@ + + + + + 248,198d + + + 1 + 5 + 5 + 2 + 0 + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + 5 + 5 + 0 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + + 5,55d + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 10,65d + 238,90d + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/dlgManageFavourites.xrc b/ui/dlgManageFavourites.xrc new file mode 100644 index 0000000..c0df58b --- /dev/null +++ b/ui/dlgManageFavourites.xrc @@ -0,0 +1,83 @@ + + + + Manage favourites + 218,198d + + + 1 + 5 + 5 + 0 + 0 + + + 5,7d + 208,150d + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 4 + 5 + 5 + 3 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0,0d + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 3 + 0 + + 0,0d + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + wxEXPAND + + + + diff --git a/ui/dlgManageMacros.xrc b/ui/dlgManageMacros.xrc new file mode 100644 index 0000000..4dd1fc0 --- /dev/null +++ b/ui/dlgManageMacros.xrc @@ -0,0 +1,133 @@ + + + + Manage Macros + + + 1 + 5 + 5 + 0 + 0 + + + 3 + + + + + wxTOP|wxBOTTOM|wxLEFT|wxEXPAND + 5 + 150d + + + 5,5d + + + + 1 + + + + + + + wxALIGN_CENTRE_VERTICAL + + + 5d + + + + wxLEFT|wxRIGHT|wxEXPAND + + 3 + 2 + + wxTOP|wxLEFT|wxRIGHT|wxGROW + 5 + + + 5,5d + + + + + + wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND + 5 + 200,100d + + 0 + + + 5 + + 5,5d + + + + + + + 5 + 4 + + 5,5d + + + + + + + + 5,5d + + + wxALL + + 2 + + wxALL|wxGROW + + 0 + 2 + + wxTOP|wxLEFT|wxRIGHT|wxGROW|wxALIGN_CENTRE + 5 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/dlgMoveTablespace.xrc b/ui/dlgMoveTablespace.xrc new file mode 100644 index 0000000..3fa2413 --- /dev/null +++ b/ui/dlgMoveTablespace.xrc @@ -0,0 +1,95 @@ + + + + Move objects to another tablespace + 200,200d + + + 1 + 5 + 5 + 0 + 0 + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 3 + 0 + + 0,0d + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + wxEXPAND + + + + diff --git a/ui/dlgOperator.xrc b/ui/dlgOperator.xrc new file mode 100644 index 0000000..adb215e --- /dev/null +++ b/ui/dlgOperator.xrc @@ -0,0 +1,370 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgPackage.xrc b/ui/dlgPackage.xrc new file mode 100644 index 0000000..3253cbc --- /dev/null +++ b/ui/dlgPackage.xrc @@ -0,0 +1,180 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 1 + 3 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + + 1 + 5 + 5 + 0 + 0 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + + 1 + 5 + 5 + 0 + 0 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgPgpassConfig.xrc b/ui/dlgPgpassConfig.xrc new file mode 100644 index 0000000..ac6f30b --- /dev/null +++ b/ui/dlgPgpassConfig.xrc @@ -0,0 +1,145 @@ + + + + Client Access Configuration + 300,265d + + + 1 + 5 + 5 + 0 + 0 + 296,240d + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 3 + 0 + + 0,0d + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + wxEXPAND + + + + diff --git a/ui/dlgReassignDropOwned.xrc b/ui/dlgReassignDropOwned.xrc new file mode 100644 index 0000000..e873262 --- /dev/null +++ b/ui/dlgReassignDropOwned.xrc @@ -0,0 +1,90 @@ + + + + Reassign/Drop Owned + 200,200d + + + 1 + 5 + 5 + 0 + 0 + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0,0d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 3 + 0 + + 0,0d + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + wxEXPAND + + + + diff --git a/ui/dlgRepCluster.xrc b/ui/dlgRepCluster.xrc new file mode 100644 index 0000000..9c9de45 --- /dev/null +++ b/ui/dlgRepCluster.xrc @@ -0,0 +1,235 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 6 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + 5 + 5 + 0 + 0,1 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 1 + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + 5 + 5 + 0 + + + 2 + 5 + 5 + 1 + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgRepClusterUpgrade.xrc b/ui/dlgRepClusterUpgrade.xrc new file mode 100644 index 0000000..5f530e8 --- /dev/null +++ b/ui/dlgRepClusterUpgrade.xrc @@ -0,0 +1,135 @@ + + + + Upgrade cluster software + 220,150d + + + 1 + 0 + 0 + + + 216,125d + 0 + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/dlgRepListen.xrc b/ui/dlgRepListen.xrc new file mode 100644 index 0000000..bc96de4 --- /dev/null +++ b/ui/dlgRepListen.xrc @@ -0,0 +1,107 @@ + + + + + 220,150d + + + 1 + 0 + 0 + + + 216,125d + 0 + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/dlgRepNode.xrc b/ui/dlgRepNode.xrc new file mode 100644 index 0000000..c7c0e23 --- /dev/null +++ b/ui/dlgRepNode.xrc @@ -0,0 +1,92 @@ + + + + + 220,150d + + + 1 + 0 + 0 + + + 216,125d + 0 + + + + + 2 + 5 + 5 + 1 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/dlgRepPath.xrc b/ui/dlgRepPath.xrc new file mode 100644 index 0000000..e03acf6 --- /dev/null +++ b/ui/dlgRepPath.xrc @@ -0,0 +1,105 @@ + + + + + 220,150d + + + 1 + 0 + 0 + + + 216,125d + 0 + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/dlgRepSequence.xrc b/ui/dlgRepSequence.xrc new file mode 100644 index 0000000..2d02668 --- /dev/null +++ b/ui/dlgRepSequence.xrc @@ -0,0 +1,107 @@ + + + + + 220,150d + + + 1 + 0 + 0 + + + 216,125d + 0 + + + + + 2 + 5 + 5 + 1 + 2 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/dlgRepSet.xrc b/ui/dlgRepSet.xrc new file mode 100644 index 0000000..020c771 --- /dev/null +++ b/ui/dlgRepSet.xrc @@ -0,0 +1,114 @@ + + + + + 220,150d + + + 1 + 0 + 0 + + + 216,125d + 0 + + + + + 2 + 5 + 5 + 1 + 2 + + + + 5,7d + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,5d + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 5,22d + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,20d + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 5,37d + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + 70,35d + 135,60d + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/dlgRepSetMerge.xrc b/ui/dlgRepSetMerge.xrc new file mode 100644 index 0000000..760b723 --- /dev/null +++ b/ui/dlgRepSetMerge.xrc @@ -0,0 +1,92 @@ + + + + Merge set into another set + 220,150d + + + 1 + 0 + 0 + + + 216,125d + 0 + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/dlgRepSetMove.xrc b/ui/dlgRepSetMove.xrc new file mode 100644 index 0000000..c72d268 --- /dev/null +++ b/ui/dlgRepSetMove.xrc @@ -0,0 +1,92 @@ + + + + Move set to other node + 220,150d + + + 1 + 0 + 0 + + + 216,125d + 0 + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/dlgRepSubscription.xrc b/ui/dlgRepSubscription.xrc new file mode 100644 index 0000000..76c78cd --- /dev/null +++ b/ui/dlgRepSubscription.xrc @@ -0,0 +1,121 @@ + + + + + 220,150d + + + 1 + 0 + 0 + + + 216,125d + 0 + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/dlgRepTable.xrc b/ui/dlgRepTable.xrc new file mode 100644 index 0000000..00db0e2 --- /dev/null +++ b/ui/dlgRepTable.xrc @@ -0,0 +1,143 @@ + + + + + 220,150d + + + 1 + 0 + 0 + + + 216,125d + 0 + + + + + 2 + 5 + 5 + 1 + 3 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + + 1 + 5 + 5 + 0 + 0 + + + + 5,5d + 200,90d + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/dlgResourceGroup.xrc b/ui/dlgResourceGroup.xrc new file mode 100644 index 0000000..7338c22 --- /dev/null +++ b/ui/dlgResourceGroup.xrc @@ -0,0 +1,106 @@ + + + + + 1 + 0 + 0 + + + + + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + 2 + 15 + 5 + 1 + + + + + + 216,205d + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + 220,230d + + + \ No newline at end of file diff --git a/ui/dlgRole.xrc b/ui/dlgRole.xrc new file mode 100644 index 0000000..8291b3a --- /dev/null +++ b/ui/dlgRole.xrc @@ -0,0 +1,479 @@ + + + + + 270,250d + + + 1 + 0 + 0 + + + 266,225d + 0 + + + + + 2 + 5 + 5 + 2 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 0 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 0 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + + 1 + 5 + 5 + 0 + + + + 166,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + 166,12d + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 166,12d + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 166,12d + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 166,12d + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 166,12d + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 166,12d + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 3 + 5 + 5 + 1 + 0,2 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0,0d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 86,123d + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + 1 + 5 + 5 + + + + 18,-1d + + wxEXPAND|wxALIGN_BOTTOM|wxALL + 4 + + + + + 18,-1d + + wxEXPAND|wxALIGN_TOP|wxALL + 4 + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + 86,123d + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + 0,0d + + + 0,0d + + + + + + + + + 1 + 4 + 5 + 0 + 0 + + + 5,6d + + + wxALL|wxGROW|wxALIGN_CENTRE + 4 + + + + 3 + 0 + + 0,0d + + + + + 90,132d + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 150,132d + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 0,1 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + wxALL|wxGROW|wxALIGN_CENTRE + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxGROW + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgRule.xrc b/ui/dlgRule.xrc new file mode 100644 index 0000000..810bba2 --- /dev/null +++ b/ui/dlgRule.xrc @@ -0,0 +1,209 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 2 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 2 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + SELECT + INSERT + UPDATE + DELETE + + 1 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 1 + 5 + 5 + 0 + 0 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgSchedule.xrc b/ui/dlgSchedule.xrc new file mode 100644 index 0000000..aeae60d --- /dev/null +++ b/ui/dlgSchedule.xrc @@ -0,0 +1,460 @@ + + + + + 220,250d + + + 1 + 0 + 0 + + + 216,225d + 0 + + + + + 2 + 5 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 0,1 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 0,1 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + + 3 + 5 + 5 + 2 + 2 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_BOTTOM|wxALIGN_RIGHT + 4 + + + + -1,70d + + Sunday + Monday + Tuesday + Wednesday + Thursday + Friday + Saturday + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_BOTTOM|wxALIGN_RIGHT + 4 + + + + -1,70d + + 1st + 2nd + 3rd + 4th + 5th + 6th + 7th + 8th + 9th + 10th + 11th + 12th + 13th + 14th + 15th + 16th + 17th + 18th + 19th + 20th + 21st + 22nd + 23rd + 24th + 25th + 26th + 27th + 28th + 29th + 30th + 31st + Last day + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_BOTTOM|wxALIGN_RIGHT + 4 + + + + + January + February + March + April + May + June + July + August + September + October + November + December + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + + 3 + 5 + 5 + 1 + 2 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_BOTTOM|wxALIGN_RIGHT + 4 + + + + -1,100d + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_BOTTOM|wxALIGN_RIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + + 1 + 5 + 5 + 0 + 0 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 4 + 5 + 5 + 1,3 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + 4 + 5 + 5 + 0 + + 0,0d + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgSchema.xrc b/ui/dlgSchema.xrc new file mode 100644 index 0000000..53962cb --- /dev/null +++ b/ui/dlgSchema.xrc @@ -0,0 +1,142 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 3 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgSearchObject.xrc b/ui/dlgSearchObject.xrc new file mode 100644 index 0000000..f3846b9 --- /dev/null +++ b/ui/dlgSearchObject.xrc @@ -0,0 +1,214 @@ + + + + Search Objects + 353,240d + + + 0 + 1 + 0 + 0 + 0 + 0 + + + wxALIGN_CENTER|wxALL|wxEXPAND + 3 + + 5 + 3 + 1 + 3 + + 0,0 + 1,1 + wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP + 4 + + + + + + 0,1 + 1,1 + wxEXPAND + 0 + + 0 + 2 + 5 + 5 + 0 + 0 + + + wxALIGN_CENTER_VERTICAL|wxEXPAND|wxLEFT|wxTOP + 3 + + Enter part of the object's attribute you're looking for + + + + + wxALIGN_CENTER_VERTICAL|wxTOP + 3 + + + 1 + + + + + + 1,0 + 1,1 + wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP + 4 + + + + + + 1,1 + 1,1 + wxBOTTOM|wxEXPAND|wxLEFT|wxTOP + 3 + + + 270,-1d + + + + + 2,0 + 1,1 + wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP + 4 + + + + + + 2,1 + 1,1 + wxBOTTOM|wxEXPAND|wxLEFT|wxTOP + 3 + + + 270,-1d + + + + + 3,0 + 1,1 + wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP + 4 + + + + + + 3,1 + 1,2 + wxEXPAND + 5 + + 0 + 1 + 0 + 0 + 0 + 0 + + + wxALL|wxEXPAND + 3 + + 340,150d + + + + + + + 0,2 + 3,1 + wxALIGN_CENTER_HORIZONTAL + 5 + + wxVERTICAL + + + wxLEFT|wxTOP + 5 + + + 1 + + + + + wxLEFT|wxTOP + 5 + + + 0 + + + + + wxLEFT|wxTOP + 5 + + + 0 + + + + + + + + + wxEXPAND + 5 + + 0 + 3 + 0 + 0 + 1 + + + + wxEXPAND|wxALL + 3 + + + + + + 0,0d + + + + wxEXPAND|wxALL + 3 + + + + + + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgSelectConnection.xrc b/ui/dlgSelectConnection.xrc new file mode 100644 index 0000000..0424936 --- /dev/null +++ b/ui/dlgSelectConnection.xrc @@ -0,0 +1,40 @@ + + + + Connect to Server + 205,98d + + + + 5,7d + + + + 5,22d + + + + 5,37d + + + + 5,54d + + + + 2,80d + + + + + 1 + 97,80d + + + + + 0 + 150,80d + + + diff --git a/ui/dlgSequence.xrc b/ui/dlgSequence.xrc new file mode 100644 index 0000000..049a625 --- /dev/null +++ b/ui/dlgSequence.xrc @@ -0,0 +1,249 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 5,247d + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + 70,245d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgServer.xrc b/ui/dlgServer.xrc new file mode 100644 index 0000000..1637675 --- /dev/null +++ b/ui/dlgServer.xrc @@ -0,0 +1,538 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select SSL Root Certificate File + *.crt + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select SSL Certificate Revocation List File + *.crl + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select SSL certificate file + *.crt + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select SSL key file + *.key + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 10 + 10 + 1 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select identity file + * + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 0 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select public key file + *.pub + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgStep.xrc b/ui/dlgStep.xrc new file mode 100644 index 0000000..a6802a7 --- /dev/null +++ b/ui/dlgStep.xrc @@ -0,0 +1,262 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 7 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + 2 + 0 + + + + + 0 + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + + + + + 0 + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + 0 + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxVERTICAL + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + + wxALIGN_TOP|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxTOP + 4 + + + + 0 + 0 + 2 + + 0 + + + 0 + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + + + + + 0 + 15,-1d + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + SQL + Batch + + 0 + + 1 + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + Fail + Succeed + Ignore + + 1 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + + 1 + 5 + 5 + 0 + 0 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgSynonym.xrc b/ui/dlgSynonym.xrc new file mode 100644 index 0000000..17a4859 --- /dev/null +++ b/ui/dlgSynonym.xrc @@ -0,0 +1,185 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 1 + 2 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 5 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgTable.xrc b/ui/dlgTable.xrc new file mode 100644 index 0000000..6ebaa32 --- /dev/null +++ b/ui/dlgTable.xrc @@ -0,0 +1,892 @@ + + + + + 350,265d + + + 1 + 0 + 0 + + + 346,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 5 + 5 + 0 + 0 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 3 + 5 + 5 + 0 + + 3,3d + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0,0d + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0,0d + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0,0d + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0,0d + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 5 + 5 + 0 + 0 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 4 + 0 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + 50,-1d + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 5 + 5 + 0 + 0 + + + 270,-1d + + + wxGROW + + + + 5 + 0 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + wxGROW + + + + + + + + 0 + + + + + 3 + 5 + 5 + 1 + + 3,3d + + + 3,3d + + + 3,3d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 3,3d + + + 3,3d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + + 3 + 5 + 5 + 1 + + 3,3d + + + 3,3d + + + 3,3d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 3,3d + + + 3,3d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgTablespace.xrc b/ui/dlgTablespace.xrc new file mode 100644 index 0000000..6c1fe0a --- /dev/null +++ b/ui/dlgTablespace.xrc @@ -0,0 +1,256 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 3 + 1 + + + + 5,7d + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,5d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 5,37d + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 70,35d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 5,52d + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + 70,50d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + 5,22d + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,20d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 4 + 5 + 0 + 0 + + + 5,6d + + + wxALL|wxGROW|wxALIGN_CENTRE + 4 + + + + 3 + 0 + + 0,0d + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 0,1 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + wxALL|wxGROW|wxALIGN_CENTRE + 4 + + + wxGROW + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgTextSearchConfiguration.xrc b/ui/dlgTextSearchConfiguration.xrc new file mode 100644 index 0000000..d03f8f0 --- /dev/null +++ b/ui/dlgTextSearchConfiguration.xrc @@ -0,0 +1,310 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 0 + 0 + + + 70,15d + + + + wxALL|wxEXPAND + 5 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL + + + + 135,-1d + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL + + + + 2 + 5 + 5 + 0 + + + 111,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + 56,-1d + + + wxALIGN_CENTER_VERTICAL + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxALL|wxEXPAND|wxALIGN_BOTTOM|wxALIGN_CENTRE_HORIZONTAL + 5 + + + + 3 + + + + 13,58d + + wxALL|wxALIGN_RIGHT + 2 + + + + + 13,78d + + wxALL|wxALIGN_RIGHT + 2 + + + wxALIGN_RIGHT + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + 2,2d + + + + 7 + 2 + + 3,3d + + + + + + + + 3,3d + + + + + 1 + + + + 3,3d + + + + + + + + 3,3d + + + wxTOP|wxLEFT|wxRIGHT|wxGROW + + + 3,3d + + + + + + wxGROW|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgTextSearchDictionary.xrc b/ui/dlgTextSearchDictionary.xrc new file mode 100644 index 0000000..400ccdf --- /dev/null +++ b/ui/dlgTextSearchDictionary.xrc @@ -0,0 +1,277 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 0 + 0 + + + 70,15d + + + + wxALL|wxEXPAND + 5 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + + + + + wxALIGN_CENTRE_VERTICAL + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + + wxALL|wxEXPAND|wxALIGN_BOTTOM|wxALIGN_CENTRE_HORIZONTAL + 5 + + + + 2 + + + + 13,58d + + wxALL|wxALIGN_RIGHT + 2 + + + + + 13,78d + + wxALL|wxALIGN_RIGHT + 2 + + + wxALIGN_RIGHT + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + 2,2d + + + + 7 + 2 + + 3,3d + + + + + + + + 3,3d + + + + + 1 + + + + 3,3d + + + + + + + + 3,3d + + + wxTOP|wxLEFT|wxRIGHT|wxGROW + + + 3,3d + + + + + + wxGROW|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgTextSearchParser.xrc b/ui/dlgTextSearchParser.xrc new file mode 100644 index 0000000..953d566 --- /dev/null +++ b/ui/dlgTextSearchParser.xrc @@ -0,0 +1,263 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + 2,2d + + + + 7 + 2 + + 3,3d + + + + + + + + 3,3d + + + + + 1 + + + + 3,3d + + + + + + + + 3,3d + + + wxTOP|wxLEFT|wxRIGHT|wxGROW + + + 3,3d + + + + + + wxGROW|wxALIGN_CENTRE + 3 + + + + + diff --git a/ui/dlgTextSearchTemplate.xrc b/ui/dlgTextSearchTemplate.xrc new file mode 100644 index 0000000..988875e --- /dev/null +++ b/ui/dlgTextSearchTemplate.xrc @@ -0,0 +1,214 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + 2,2d + + + + 7 + 2 + + 3,3d + + + + + + + + 3,3d + + + + + 1 + + + + 3,3d + + + + + + + + 3,3d + + + wxTOP|wxLEFT|wxRIGHT|wxGROW + + + 3,3d + + + + + + wxGROW|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgTrigger.xrc b/ui/dlgTrigger.xrc new file mode 100644 index 0000000..cb85a93 --- /dev/null +++ b/ui/dlgTrigger.xrc @@ -0,0 +1,394 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 2 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + -1,40 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 8 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + BEFORE + AFTER + INSTEAD OF + + 0 + 1 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 0,1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + -1,40 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 1 + 0 + 0 + + + + + wxEXPAND|wxALL + 4 + + + + 2 + 5 + 5 + 1 + 0 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALL + 4 + + + + 4 + 0 + + 3,3d + + + + + + + + 3,3d + + + + + 50,-1d + + + + wxEXPAND|wxALL + 4 + + + + + + + + + 1 + 0 + 0 + + + + + + wxTOP|wxRIGHT|wxGROW + 5 + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgType.xrc b/ui/dlgType.xrc new file mode 100644 index 0000000..2f183cf --- /dev/null +++ b/ui/dlgType.xrc @@ -0,0 +1,832 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + Composite + Enumeration + External + Range + + 1 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 5 + 5 + 0,1,2 + 0 + + + + 1 + 5 + 5 + 0 + 0 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + wxALL|wxALIGN_RIGHT + 2 + + + + + + wxALL|wxALIGN_RIGHT + 2 + + + + + + wxALL|wxALIGN_RIGHT + 2 + + 3 + + wxALIGN_RIGHT + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + 5 + 5 + 0 + 0 + + + 5,5d + 200,155d + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 4 + 5 + 5 + 0 + + 2,2d + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + 5 + 5 + 0 + 0 + + + 0 + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + Array types + Boolean types + Composite types + Date/time types + Enum types + Geometric types + Network address types + Numeric types + Pseudo-types + String types + Timespan types + User-defined types + Bit-string types + unknown types + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + char + int2 + int4 + double + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + 0 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgUser.xrc b/ui/dlgUser.xrc new file mode 100644 index 0000000..e65dbc6 --- /dev/null +++ b/ui/dlgUser.xrc @@ -0,0 +1,371 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 6 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 0 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 5 + 5 + 0 + + + + 1 + 166,12d + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 166,12d + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 3 + 5 + 5 + 1 + 0,2 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0,0d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 86,123d + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + 1 + 5 + 5 + + + + 18,-1d + + wxEXPAND|wxALIGN_BOTTOM|wxALL + 4 + + + + + 18,-1d + + wxEXPAND|wxALIGN_TOP|wxALL + 4 + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + 86,123d + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + + 1 + 4 + 5 + 0 + 0 + + + 5,6d + + + wxALL|wxGROW|wxALIGN_CENTRE + 4 + + + + 3 + 0 + + 0,0d + + + + + 90,132d + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 150,132d + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 0,1 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + wxALL|wxGROW|wxALIGN_CENTRE + 4 + + + wxGROW + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgUserMapping.xrc b/ui/dlgUserMapping.xrc new file mode 100644 index 0000000..87d18e7 --- /dev/null +++ b/ui/dlgUserMapping.xrc @@ -0,0 +1,207 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 1 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 1 + 0 + 0 + + + 70,15d + + + + wxALL|wxEXPAND + 5 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + + + + + wxALIGN_CENTRE_VERTICAL + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + + wxALL|wxEXPAND|wxALIGN_BOTTOM|wxALIGN_CENTRE_HORIZONTAL + 5 + + + + 2 + + + + 13,58d + + wxALL|wxALIGN_RIGHT + 2 + + + + + 13,78d + + wxALL|wxALIGN_RIGHT + 2 + + + wxALIGN_RIGHT + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + 2,2d + + + + 7 + 2 + + 3,3d + + + + + + + + 3,3d + + + + + 1 + + + + 3,3d + + + + + + + + 3,3d + + + wxTOP|wxLEFT|wxRIGHT|wxGROW + + + 3,3d + + + + + + wxGROW|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgView.xrc b/ui/dlgView.xrc new file mode 100644 index 0000000..0b0f083 --- /dev/null +++ b/ui/dlgView.xrc @@ -0,0 +1,728 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 2 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + No + Local + Cascaded + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxGROW + + + + + + + + + 1 + + + 2 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + 2 + 1 + 1 + 1 + + + + + 0 + + + + + 2 + 3 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + 4 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + 3 + + + + + + + + 3 + 4 + 4 + 1 + + 3,3d + + + 3,3d + + + 3,3d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 3,3d + + + 3,3d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + + + + 3 + 4 + 4 + 1 + + 3,3d + + + 3,3d + + + 3,3d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 3,3d + + + 3,3d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + 5 + 5 + 0 + 1 + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/embed-xrc b/ui/embed-xrc new file mode 100644 index 0000000..86d33e5 --- /dev/null +++ b/ui/embed-xrc @@ -0,0 +1,24 @@ +#!/bin/sh + +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# embed-xrc - convert xrc files to c++ files +# +####################################################################### + +echo Rebuilding xrcdialogs.cpp... + +wxrc -c -o $( dirname $0 )/xrcDialogs.cpp.new $( dirname $0 )/*.xrc + +diff $( dirname $0 )/xrcDialogs.cpp.new $( dirname $0 )/xrcDialogs.cpp 1> /dev/null +rc=$? + +if [ x"$rc" != x"0" ] ; then + mv $( dirname $0 )/xrcDialogs.cpp.new $( dirname $0 )/xrcDialogs.cpp +else + rm $( dirname $0 )/xrcDialogs.cpp.new +fi diff --git a/ui/embed-xrc.bat b/ui/embed-xrc.bat new file mode 100644 index 0000000..ef1ffeb --- /dev/null +++ b/ui/embed-xrc.bat @@ -0,0 +1,13 @@ +@echo off +REM ####################################################################### +REM # +REM # pgAdmin III - PostgreSQL Tools +REM # Copyright (C) 2002 - 2016, The pgAdmin Development Team +REM # This software is released under the PostgreSQL Licence +REM # +REM # embed-xrc.bat - convert xrc files to c++ files +REM # +REM ####################################################################### + +"D:\wxWidgets-2.8.12\utils\wxrc\vc_msw\wxrc" -c -o xrcDialogs.cpp *.xrc + diff --git a/ui/frmBackup.xrc b/ui/frmBackup.xrc new file mode 100644 index 0000000..62262be --- /dev/null +++ b/ui/frmBackup.xrc @@ -0,0 +1,412 @@ + + + + Backup + 300,233d + + + 1 + 0 + 0 + + + 2,2d + 285,224d + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 0 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 5 + 5 + 0 + + + + 1 + 5 + 5 + 0 + wxVERTICAL + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + 5 + 5 + 0 + wxVERTICAL + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + 5 + 5 + 0 + wxVERTICAL + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 5 + 5 + 0 + + + + 1 + 5 + 5 + 0 + wxVERTICAL + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + 5 + 5 + 0 + wxVERTICAL + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + 5 + 5 + 0 + wxVERTICAL + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + + + + + + + + + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxGROW|wxALIGN_CENTRE + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/frmBackupGlobals.xrc b/ui/frmBackupGlobals.xrc new file mode 100644 index 0000000..8f41e19 --- /dev/null +++ b/ui/frmBackupGlobals.xrc @@ -0,0 +1,105 @@ + + + + Backup Globals + 210,153d + + + 1 + + + + + + + + 8,7d + + + 65,5d + 150,-1d + + + + 220,5d + 15,-1d + + + + 8,27d + + + 65,25d + 170,-1d + + + + + + 8,47d + + + + + 10,120d + + + + 1 + 10,144d + + + 1 + + 2,2d + 245,174d + + + + + + + + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxGROW|wxALIGN_CENTRE + + + + 4 + + + + 2,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT + 5 + + + 0,0 + + + + + 1 + 93,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT + 5 + + + + + 146,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxGROW|wxALIGN_RIGHT + 5 + + 1 + + wxEXPAND|wxGROW + + 0 + 0 + + + diff --git a/ui/frmBackupServer.xrc b/ui/frmBackupServer.xrc new file mode 100644 index 0000000..3f22b25 --- /dev/null +++ b/ui/frmBackupServer.xrc @@ -0,0 +1,105 @@ + + + + Backup Server + 210,153d + + + 1 + + + + + + + + 8,7d + + + 65,5d + 150,-1d + + + + 220,5d + 15,-1d + + + + 8,27d + + + 65,25d + 170,-1d + + + + + + 8,47d + + + + + 10,120d + + + + 1 + 10,144d + + + 1 + + 2,2d + 245,174d + + + + + + + + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxGROW|wxALIGN_CENTRE + + + + 4 + + + + 2,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT + 5 + + + 0,0 + + + + + 1 + 93,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT + 5 + + + + + 146,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxGROW|wxALIGN_RIGHT + 5 + + 1 + + wxEXPAND|wxGROW + + 0 + 0 + + + diff --git a/ui/frmExport.xrc b/ui/frmExport.xrc new file mode 100644 index 0000000..9482f4e --- /dev/null +++ b/ui/frmExport.xrc @@ -0,0 +1,131 @@ + + + + Export data to file + 253,143d + + + + 5,5d + 120,38d + + + + 1 + 10,17d + + + + + 10,29d + + + + 5,55d + + + + ; + , + | + + 0 + 100,53d + 25,12d + + + + + 5,70d + + + + " + ' + + 0 + 100,68d + 25,12d + + + + + 5,85d + + + + 1 + 100,83d + 12,12d + + + + 130,5d + 120,38d + + + + 1 + 140,17d + + + + + 140,29d + + + + 130,48d + 120,50d + + + + 140,60d + + + + + 1 + 140,72d + + + + 140,84d + + + + 5,107d + + + 100,105d + 130,-1d + + + + 235,105d + 15,-1d + + + + 2,125d + + + + + 1 + 55,125d + 70,12d + + + + 1 + 147,125d + + + + + 0 + 200,125d + + + \ No newline at end of file diff --git a/ui/frmGrantWizard.xrc b/ui/frmGrantWizard.xrc new file mode 100644 index 0000000..5317d6f --- /dev/null +++ b/ui/frmGrantWizard.xrc @@ -0,0 +1,46 @@ + + + + Grant Wizard + 200,303d + + + + + + + + 2,3d + 183,234d + + + + 2,240d + 50,-1d + + + + 60,240d + 50,-1d + + + 1 + + 2,2d + 195,276d + + + + 2,285d + + + + 1 + 93,285d + + + + 146,285d + + + \ No newline at end of file diff --git a/ui/frmHint.xrc b/ui/frmHint.xrc new file mode 100644 index 0000000..be39ffe --- /dev/null +++ b/ui/frmHint.xrc @@ -0,0 +1,90 @@ + + + + pgAdmin Guru Hint + 200,153d + + + 1 + + + + + wxALL|wxGROW + 5 + 300,200d + + + + + + wxALL + 5 + + + + 7 + + + + 2,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT + 5 + + + 0,0 + + + + + 1 + 93,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT + 5 + + + + + 1 + 93,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT + 5 + + + + + 1 + 93,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT + 5 + + + + + 1 + 93,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT + 5 + + + + + 146,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxGROW|wxALIGN_RIGHT + 5 + + 1 + + wxEXPAND|wxGROW + + 0 + 0 + + + diff --git a/ui/frmImport.xrc b/ui/frmImport.xrc new file mode 100644 index 0000000..f47405d --- /dev/null +++ b/ui/frmImport.xrc @@ -0,0 +1,301 @@ + + + + Import data from file + 300,133d + + + 1 + 0 + 0 + + + 2,2d + 285,124d + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select the file to import + + *.csv;*.*;* + Enter a filename to import. + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + text + csv + binary + + 0 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 5 + 5 + 1 + 0 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + ; + , + | + [tab] + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + " + ' + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + " + ' + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxGROW|wxALIGN_CENTRE + + + + 1 + 0 + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/frmMaintenance.xrc b/ui/frmMaintenance.xrc new file mode 100644 index 0000000..cbb96b5 --- /dev/null +++ b/ui/frmMaintenance.xrc @@ -0,0 +1,128 @@ + + + + Maintenance + 200,153d + + + 1 + 0 + 0 + + + + + + + + 1 + 5 + 5 + 0 + + + + + VACUUM + ANALYZE + REINDEX + CLUSTER + + 0 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 3 + 5 + 5 + 0 + wxHORIZONTAL + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + + + + + + + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxGROW|wxALIGN_CENTRE + + + + 4 + + + + 2,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT + 5 + + + 0,0 + + + + + 1 + 93,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT + 5 + + + + + 146,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxGROW|wxALIGN_RIGHT + 5 + + 1 + + wxEXPAND|wxGROW + + + + diff --git a/ui/frmOptions.xrc b/ui/frmOptions.xrc new file mode 100644 index 0000000..732e803 --- /dev/null +++ b/ui/frmOptions.xrc @@ -0,0 +1,1344 @@ + + + + Options + 480,250d + + + 1 + 0 + 0 + + + 2 + 0 + 1 + + + 100,225d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 3 + + + + 1 + 5 + 5 + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 + 0 + + + 1 + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Enter the path or URL to the PostgreSQL documentation + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 1 + 5 + 5 + 1 + 0 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 2 + 5 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select directory with Slony-I creation scripts + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select directory with PostgreSQL utilities + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select directory with EnterpriseDB utilities + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select directory with GreenplumDB utilities + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 1 + 5 + 5 + 0 + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + None + Refresh object on click + Refresh object and children on click + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 256 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select utility to format text + * + + A command line utility which reads STDIN and directs output to STDOUT. + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 1 + 5 + 5 + 0 + + + + wxVERTICAL + + + 3 + 4 + 4 + 0,1 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0,0d + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxVERTICAL + + + 2 + 4 + 4 + 0,1 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxVERTICAL + + + 4 + 4 + 4 + 0,2 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + None + Strings + All + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + " + ' + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + ; + , + | + Tab + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 1 + 5 + 5 + 0 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select file to store favourites queries + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select file to store macros + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select file to store queries history + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 10 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 100 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 2 + 5 + 5 + 0 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 1 + 5 + 5 + 0 + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 100 + Maximums rows to retrieve into output window; 0 = unlimited + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 1 + 5 + 5 + 0 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 1 + 5 + 5 + 0 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select log file + + Enter a filename to write application logs to. + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + &No logging + &Errors only + Errors and N&otices + Errors, Notices, &SQL + &Debug (not recommended for normal use) + + 2 + 1 + + Select the level of detail to record in the logfile. + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + Accept the current settings and close the dialogue. + + wxEXPAND|wxALL + 3 + + + + + Cancel any changes and close the dialogue. + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/frmPassword.xrc b/ui/frmPassword.xrc new file mode 100644 index 0000000..d672510 --- /dev/null +++ b/ui/frmPassword.xrc @@ -0,0 +1,47 @@ + + + + Change Password + 175,73d + + + + 5,7d + + + 70,5d + 100,-1d + + + + + 5,22d + + + 70,20d + 100,-1d + + + + + 5,37d + + + 70,35d + 100,-1d + + + + + 5,55d + + + + 63,55d + + + + 120,55d + + + \ No newline at end of file diff --git a/ui/frmReport.xrc b/ui/frmReport.xrc new file mode 100644 index 0000000..fa862ff --- /dev/null +++ b/ui/frmReport.xrc @@ -0,0 +1,149 @@ + + + + Generate a report + 253,303d + + + + 5,5d + + + 5,15d + 243,-1d + Enter a title for the report + + + + 5,35d + + + 5,45d + 243,45d + + Enter any additional notes to include on the report + + + + 5,99d + Include the SQL from the object or query in the report? + + + + 5,113d + 243,45d + + + + 1 + 10,128d + + Create the report in XHTML 1.0 Transitional format + + + + 1 + 10,141d + Create the report in XML format + + + + 5,163d + 243,75d + + + + 1 + 10,178d + + Embed pgAdmin's default stylesheet into the report. + + + + 10,191d + Embed an external stylesheet into the report + + + + 10,204d + Include a link to an external stylesheet in the report. + + + + 1 + 10,178d + + Do not use a stylesheet + + + + 10,191d + Include a link to the specified stylesheet in the XML file + + + + 10,204d + Process the XML data using the specified stylesheet + + + + 10,223d + + + 60,220d + 162,-1d + Select the stylesheet to use. + + + 60,220d + 162,-1d + Select the stylesheet to use. + + + + 227,220d + 15,-1d + Select the stylesheet to use. + + + + 5,248d + + + 55,245d + 175,-1d + Select the file to write the report to. + + + 55,245d + 175,-1d + Select the file to write the report to. + + + + 235,245d + 15,-1d + Select the file to write the report to. + + + + 5,265d + + + + 2,285d + + + + + 1 + 147,285d + + + + + 0 + 200,285d + + + \ No newline at end of file diff --git a/ui/frmRestore.xrc b/ui/frmRestore.xrc new file mode 100644 index 0000000..0a5a6fd --- /dev/null +++ b/ui/frmRestore.xrc @@ -0,0 +1,364 @@ + + + + Restore + 300,193d + + + 1 + 0 + 0 + + + 2,2d + 285,184d + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 0 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 5 + 5 + 0 + + + + 1 + 5 + 5 + 0 + wxVERTICAL + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + 5 + 5 + 0 + wxVERTICAL + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + 5 + 5 + 0 + wxVERTICAL + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 5 + 5 + 0 + + + + 1 + 5 + 5 + 0 + wxVERTICAL + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + 5 + 5 + 0 + wxVERTICAL + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + 5 + 5 + 0 + wxVERTICAL + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + + + + + + + + + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxGROW|wxALIGN_CENTRE + + + + 5 + + + + + wxEXPAND|wxALL + 3 + + + 0,0 + + + + + Display objects contained in the dump on a specific tab + 1 + + wxEXPAND|wxALL + 3 + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + 1 + + wxEXPAND|wxGROW + + + + diff --git a/ui/module.mk b/ui/module.mk new file mode 100644 index 0000000..b546e41 --- /dev/null +++ b/ui/module.mk @@ -0,0 +1,104 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/slony/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + ui/xrcDialogs.cpp + +TMP_ui += \ + ui/ddPrecisionScaleDialog.xrc \ + ui/ddTableNameDialog.xrc \ + ui/dlgAddFavourite.xrc \ + ui/dlgAggregate.xrc \ + ui/dlgCast.xrc \ + ui/dlgCheck.xrc \ + ui/dlgCollation.xrc \ + ui/dlgColumn.xrc \ + ui/dlgConnect.xrc \ + ui/dlgConversion.xrc \ + ui/dlgDatabase.xrc \ + ui/dlgDirectDbg.xrc \ + ui/dlgDomain.xrc \ + ui/dlgEventTrigger.xrc \ + ui/dlgExtension.xrc \ + ui/dlgEditGridOptions.xrc \ + ui/dlgExtTable.xrc \ + ui/dlgFindReplace.xrc \ + ui/dlgForeignDataWrapper.xrc \ + ui/dlgForeignKey.xrc \ + ui/dlgForeignServer.xrc \ + ui/dlgForeignTable.xrc \ + ui/dlgFunction.xrc \ + ui/dlgGroup.xrc \ + ui/dlgHbaConfig.xrc \ + ui/dlgIndex.xrc \ + ui/dlgIndexConstraint.xrc \ + ui/dlgJob.xrc \ + ui/dlgLanguage.xrc \ + ui/dlgMainConfig.xrc \ + ui/dlgManageFavourites.xrc \ + ui/dlgManageMacros.xrc \ + ui/dlgMoveTablespace.xrc \ + ui/dlgOperator.xrc \ + ui/dlgPackage.xrc \ + ui/dlgPgpassConfig.xrc \ + ui/dlgReassignDropOwned.xrc \ + ui/dlgRepCluster.xrc \ + ui/dlgRepClusterUpgrade.xrc \ + ui/dlgRepListen.xrc \ + ui/dlgRepNode.xrc \ + ui/dlgRepPath.xrc \ + ui/dlgRepSequence.xrc \ + ui/dlgRepSet.xrc \ + ui/dlgRepSetMerge.xrc \ + ui/dlgRepSetMove.xrc \ + ui/dlgRepSubscription.xrc \ + ui/dlgRepTable.xrc \ + ui/dlgRole.xrc \ + ui/dlgRule.xrc \ + ui/dlgSchedule.xrc \ + ui/dlgSchema.xrc \ + ui/dlgSearchObject.xrc \ + ui/dlgSelectConnection.xrc \ + ui/dlgSequence.xrc \ + ui/dlgServer.xrc \ + ui/dlgStep.xrc \ + ui/dlgSynonym.xrc \ + ui/dlgTable.xrc \ + ui/dlgTablespace.xrc \ + ui/dlgTextSearchConfiguration.xrc \ + ui/dlgTextSearchDictionary.xrc \ + ui/dlgTextSearchParser.xrc \ + ui/dlgTextSearchTemplate.xrc \ + ui/dlgTrigger.xrc \ + ui/dlgType.xrc \ + ui/dlgUser.xrc \ + ui/dlgUserMapping.xrc \ + ui/dlgView.xrc \ + ui/frmBackup.xrc \ + ui/frmBackupGlobals.xrc \ + ui/frmBackupServer.xrc \ + ui/frmExport.xrc \ + ui/frmGrantWizard.xrc \ + ui/frmHint.xrc \ + ui/frmImport.xrc \ + ui/frmMaintenance.xrc \ + ui/frmOptions.xrc \ + ui/frmPassword.xrc \ + ui/frmReport.xrc \ + ui/frmRestore.xrc \ + ui/dlgResourceGroup.xrc + +EXTRA_DIST += \ + ui/module.mk \ + ui/embed-xrc \ + ui/embed-xrc.bat + + diff --git a/ui/xrcDialogs.cpp b/ui/xrcDialogs.cpp new file mode 100644 index 0000000..8cd53ab --- /dev/null +++ b/ui/xrcDialogs.cpp @@ -0,0 +1,39966 @@ +// +// This file was automatically generated by wxrc, do not edit by hand. +// + +#include + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include +#include +#include +#include + +#if wxCHECK_VERSION(2,8,5) && wxABI_VERSION >= 20805 + #define XRC_ADD_FILE(name, data, size, mime) \ + wxMemoryFSHandler::AddFileWithMimeType(name, data, size, mime) +#else + #define XRC_ADD_FILE(name, data, size, mime) \ + wxMemoryFSHandler::AddFile(name, data, size) +#endif + +static size_t xml_res_size_0 = 3537; +static unsigned char xml_res_file_0[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,100,80,114,101,99,105,115,105,111,110,83,99,97,108,101,68, +105,97,108,111,103,34,62,10,32,32,32,32,60,116,105,116,108,101,62,68,97, +116,97,116,121,112,101,32,112,114,111,112,101,114,116,105,101,115,60,47, +116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44, +49,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, +69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,49,52,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,80,114,101,99,105,115,105,111,110,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,80,114,101,99,105,115,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,80, +114,101,99,105,115,105,111,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,99,97,108,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,83,99,97,108,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,83,99,97, +108,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97, +116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_1 = 2978; +static unsigned char xml_res_file_1[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,100,84,97,98,108,101,78,97,109,101,68,105,97,108,111,103, +34,62,10,32,32,32,32,60,116,105,116,108,101,62,84,97,98,108,101,32,112, +114,111,112,101,114,116,105,101,115,60,47,116,105,116,108,101,62,10,32, +32,32,32,60,115,105,122,101,62,51,48,48,44,49,54,53,100,60,47,115,105,122, +101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85, +76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73, +79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83, +73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99, +111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98, +108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111, +116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101, +98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,50,57,54,44,49,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108, +101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,80,114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,85,115, +117,97,108,84,97,98,108,101,78,97,109,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,117, +97,108,32,84,97,98,108,101,32,78,97,109,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,85, +115,117,97,108,84,97,98,108,101,78,97,109,101,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_2 = 2897; +static unsigned char xml_res_file_2[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,65,100,100,70,97,118,111,117,114,105,116,101,34,62, +10,32,32,32,32,60,116,105,116,108,101,62,65,100,100,32,102,97,118,111,117, +114,105,116,101,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105, +122,101,62,50,50,48,44,50,53,48,100,60,47,115,105,122,101,62,10,32,32,32, +32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76, +79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83, +89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82, +68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,109,105,110,115,105,122, +101,62,50,49,54,44,50,50,53,100,60,47,109,105,110,115,105,122,101,62,10, +32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,51,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,84,105,116,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,84,105,116,108,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,116,120,116,84,105,116,108,101,34,47,62,10,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,111, +99,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,76,111,99,97,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,99,116,108,84,114,101,101,34,32,110,97,109,101, +61,34,116,114,76,111,99,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,82,95,72,65,83,95,66,85,84, +84,79,78,83,32,124,32,119,120,83,73,77,80,76,69,95,66,79,82,68,69,82,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +98,116,110,78,101,119,70,111,108,100,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,101,119,32,70,111,108, +100,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,76,69,70,84,124,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,66,79, +84,84,79,77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60, +47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62, +10}; + +static size_t xml_res_size_3 = 12101; +static unsigned char xml_res_file_3[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,65,103,103,114,101,103,97,116,101,34,62,10,32,32, +32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62, +51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84, +69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,52,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109, +101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119, +110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,99,104,101,109,97,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109,97,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67, +111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76, +84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98, +108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,73,110,112,117,116,84,121,112,101,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,73,110,112,117,116,32,116,121,112,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,84,121,112, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,82,101,109,111,118, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,54,48,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,66,79,84,84,79,77,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116, +114,108,34,32,110,97,109,101,61,34,108,115,116,73,110,112,117,116,84,121, +112,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,65,100,100,84,121,112, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,38,97,109,112,59,65,100,100,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,54,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,73,110,112,117, +116,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,83,116,97,116,101,84,121,112,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,83,116,97,116,101,32,116,121,112,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,116, +97,116,101,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,116,97,116,101,70,117,110,99,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,83,116,97,116,101,32,102,117,110,99,116,105,111,110,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,83,116,97,116,101,70,117,110,99,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,70,105,110,97,108,70,117,110,99,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,70,105,110,97,108,32,102,117,110,99,116,105,111,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,70,105,110,97,108,70,117,110,99,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,83,111,114,116,79,112,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +111,114,116,32,79,112,101,114,97,116,111,114,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,111,114, +116,79,112,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87, +78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,110, +105,116,105,97,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,73,110,105,116,105,97,108,32,99, +111,110,100,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +116,120,116,73,110,105,116,105,97,108,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_4 = 7896; +static unsigned char xml_res_file_4[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,67,97,115,116,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,50,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,67,97,115,116,110,97,109,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101, +110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,111,117,114,99,101,84,121, +112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,83,111,117,114,99,101,32,116,121,112,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,83,111,117,114,99,101,84,121,112,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +84,97,114,103,101,116,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,97,114,103, +101,116,32,116,121,112,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,84,97,114,103,101,116, +84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,70,117,110,99,116,105,111,110,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,70,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,70,117,110,99,116, +105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87, +78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,109, +112,108,105,99,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,109,112,108,105,99,105, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +66,111,120,34,32,110,97,109,101,61,34,99,104,107,73,109,112,108,105,99, +105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_5 = 6737; +static unsigned char xml_res_file_5[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,67,104,101,99,107,34,62,10,32,32,32,32,60,116,105, +116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54, +53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62, +119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124, +119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78, +85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121, +108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101, +61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100, +62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,87,104,101,114,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,67,104,101,99,107,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,87, +104,101,114,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76, +73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,78,111,73,110,104,101,114,105,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,111,32,73,110,104,101,114,105,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,78,111, +73,110,104,101,114,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,68,111,110,116,86,97,108,105,100,97,116,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,111,110,39,116,32,118,97,108,105,100,97,116,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,68,111,110,116,86,97,108,105,100,97,116,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_6 = 9024; +static unsigned char xml_res_file_6[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,67,111,108,108,97,116,105,111,110,34,62,10,32,32, +32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62, +50,50,48,44,50,56,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84, +69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,50,53,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,52,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109, +101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119, +110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,99,104,101,109,97,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109,97,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67, +111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76, +84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,76,111,99,97,108,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76,111, +99,97,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,76,111,99,97,108,101,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,76,99,67,111,108,108,97,116,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,76,67,95,67,79,76,76,65,84,69,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,76,99,67, +111,108,108,97,116,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,99,67,116,121,112, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,76,67,95,67,84,89,80,69,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,76,99,67,116,121,112,101,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,108, +108,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,112,121,32,99,111,108, +108,97,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,67,111,108,108,97,116,105,111, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_7 = 13272; +static unsigned char xml_res_file_7[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,67,111,108,117,109,110,34,62,10,32,32,32,32,60,116, +105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44, +50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, +69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,52,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78, +97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,68,97,116,97,32,116,121,112,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,68,97,116,97,116,121,112,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,101,110,103,116,104, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,76,101,110,103,116,104,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,76, +101,110,103,116,104,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,80,114,101,99,105,115,105,111, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,80,114,101,99,105,115,105,111,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,80,114,101,99,105,115,105,111,110,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,49,48,44,49,48,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,108,108,97,116,105,111, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,111,108,108,97,116,105,111,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,67,111,108,108,97,116,105,111,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,101,102,97, +117,108,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,68,101,102,97,117,108,116,32,118,97,108, +117,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,68,101,102,97,117,108,116,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,78,111,116,78,117,108,108,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78, +111,116,32,78,85,76,76,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +66,111,120,34,32,110,97,109,101,61,34,99,104,107,78,111,116,78,117,108, +108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,65,116,116, +115,116,97,116,116,97,114,103,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,116,97,116, +105,115,116,105,99,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,65,116,116,115,116,97, +116,116,97,114,103,101,116,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,116,111,114,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,83,116,111,114,97,103,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,83,116,111,114,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120, +67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,86,97,114,105,97,98,108,101,115,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,86,97,114,105,97,98,108,101,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,52,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61, +34,108,115,116,86,97,114,105,97,98,108,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,54, +100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82, +84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79, +87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,112,111,115,62,48,44,48,100,60,47,112,111,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,65,68, +68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,65,100,100,47,67,104,97,110,103,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,77,79,86,69,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,86,97,114,110,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,97,114,105,97,98,108,101,32,78,97,109,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,86,97,114,110,97,109,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80, +68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,114,105,97,98, +108,101,32,86,97,108,117,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,86,97,108,117, +101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79,87, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_8 = 2535; +static unsigned char xml_res_file_8[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,67,111,110,110,101,99,116,34,62,10,32,32,32,32,60, +116,105,116,108,101,62,67,111,110,110,101,99,116,32,116,111,32,83,101,114, +118,101,114,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122, +101,62,50,48,53,44,56,51,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69, +82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,51,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,68,101,115,99,114,105,112,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50, +48,53,44,32,50,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,80,97,115,115,119,111,114,100,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,80,65,83,83,87, +79,82,68,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +60,116,111,111,108,116,105,112,62,69,110,116,101,114,32,116,104,101,32, +112,97,115,115,119,111,114,100,32,116,111,32,117,115,101,32,119,104,101, +110,32,99,111,110,110,101,99,116,105,110,103,32,116,111,32,116,104,101, +32,115,101,114,118,101,114,46,60,47,116,111,111,108,116,105,112,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,49,50, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,116,111, +114,101,80,119,100,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,83,116,111,114,101,32,112,97,115,115,119,111,114,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107, +101,100,62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,49,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51, +44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76, +80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,56,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98, +106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_9 = 9325; +static unsigned char xml_res_file_9[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,67,111,110,118,101,114,115,105,111,110,34,62,10,32, +32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101, +62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69, +82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,52,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109, +101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,84,79,80,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110, +101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,99,104,101, +109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,83,99,104,101,109,97,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101, +102,105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108, +68,101,102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,101,102,97,117, +108,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,68,101,102,97,117,108,116,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61, +34,99,104,107,68,101,102,97,117,108,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,83,111,117,114,99,101,69,110,99,111,100,105,110, +103,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,111,117,114,99,101,32,101,110,99,111,100,105, +110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,99,98,83,111,117,114,99,101,69,110,99,111,100,105, +110,103,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,84,97,114,103,101,116,69,110,99,111,100,105,110,103, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,84,97,114,103,101,116,32,101,110,99,111,100,105,110, +103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,84,97,114,103,101,116,69,110,99,111,100,105,110, +103,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,70,117,110,99,116,105,111,110,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,117, +110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,70,117,110,99,116,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_10 = 15692; +static unsigned char xml_res_file_10[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,68,97,116,97,98,97,115,101,34,62,10,32,32,32,32,60, +116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48, +44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +51,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119,110,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,119,110,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109, +109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,68,101,102,105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,68,101,102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,55,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,69,110,99,111,100,105,110,103,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,99, +111,100,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,99,98,69,110,99,111,100,105,110,103, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119, +120,67,66,95,83,79,82,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,84,101,109,112,108,97,116,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84, +101,109,112,108,97,116,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,84,101,109,112,108,97, +116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,80,97,116, +104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,80,97,116,104,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,80,97,116, +104,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,84,97,98,108,101,115,112,97,99,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,84,97,98,108,101,115,112,97,99,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +84,97,98,108,101,115,112,97,99,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,111,108,108,97,116,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67, +111,108,108,97,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,111,108,108,97,116, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,124,119,120,67,66,95,83,79,82,84,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,84,121,112,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,104,97,114,97,99,116,101,114,32,116,121,112,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,67,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,83, +79,82,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,110,110,76,105,109,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,110,110,101, +99,116,105,111,110,32,76,105,109,105,116,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67, +111,110,110,76,105,109,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,62, +45,49,60,47,109,105,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,99,104, +101,109,97,82,101,115,116,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,99,104,101,109,97, +32,114,101,115,116,114,105,99,116,105,111,110,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,83,99,104,101,109,97,82,101,115,116,114,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,86,97,114,105,97,98,108,101,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108, +34,32,110,97,109,101,61,34,112,110,108,86,97,114,105,97,98,108,101,115, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,52,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112, +62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110, +97,109,101,61,34,108,115,116,86,97,114,105,97,98,108,101,115,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,53,44,54,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82, +69,80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,112,111,115,62,48,44,48,100,60,47,112,111,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,65,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,47,67,104,97, +110,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,77,79,86, +69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,86,97,114,110,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,86,97,114,105,97,98,108,101,32,78,97,109, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,86,97,114,110,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,114, +105,97,98,108,101,32,86,97,108,117,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,44,49,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, +67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,86,97,108,117,101, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,86,97, +108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124, +119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,86,97,114,85,115,101,114,110,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,85,115,101,114,32,78,97,109,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,86,97,114,85,115,101,114,110,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79,87,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101, +61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69, +71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_11 = 3334; +static unsigned char xml_res_file_11[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,68,105,114,101,99,116,68,98,103,34,62,10,32,32,32, +32,60,116,105,116,108,101,62,86,105,101,119,32,68,97,116,97,32,79,112,116, +105,111,110,115,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105, +122,101,62,52,53,48,44,50,49,48,100,60,47,115,105,122,101,62,10,32,32,32, +32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76, +79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83, +89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82, +68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119, +115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111, +111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,52,48,48,44, +49,56,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101, +100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111, +112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114, +111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,49,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,77,101, +115,115,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,69,110,116,101,114,32,116,104,101, +32,114,101,113,117,105,114,101,100,32,118,97,108,117,101,115,32,102,111, +114,32,101,97,99,104,32,112,97,114,97,109,101,116,101,114,58,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,71,114,105,100,34,32, +110,97,109,101,61,34,103,114,100,80,97,114,97,109,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116, +105,112,62,83,101,116,32,116,104,101,32,102,117,110,99,116,105,111,110, +47,112,114,111,99,101,100,117,114,101,32,112,97,114,97,109,101,116,101, +114,32,118,97,108,117,101,115,46,60,47,116,111,111,108,116,105,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,99,104,107,80,107,103,73,110,105,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,68,101,98,117,103,32,112,97,99,107,97,103,101,32,105,110,105,116,105, +97,108,105,122,101,114,63,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,68,101,98,117,103, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,116,111,111,108,116,105,112,62,65,99,99,101,112,116,32,116,104,101,32, +99,117,114,114,101,110,116,32,111,112,116,105,111,110,115,32,97,110,100, +32,99,108,111,115,101,32,116,104,101,32,100,105,97,108,111,103,117,101, +46,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117, +108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,67,97,110,99,101,108,32,97,110, +121,32,99,104,97,110,103,101,115,32,97,110,100,32,99,108,111,115,101,32, +116,104,101,32,100,105,97,108,111,103,117,101,46,60,47,116,111,111,108, +116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110, +107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_12 = 12541; +static unsigned char xml_res_file_12[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,68,111,109,97,105,110,34,62,10,32,32,32,32,60,116, +105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44, +50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, +69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,52,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78, +97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119, +110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,99,104,101, +109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,83,99,104,101,109,97,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101, +102,105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108, +68,101,102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,97,116,97,116,121, +112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,66,97,115,101,32,116,121,112,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,68,97,116,97,116,121,112,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,76,101,110,103,116,104,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,76,101,110,103,116,104,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,76,101,110, +103,116,104,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,80,114,101,99,105,115,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,80,114,101,99,105,115,105,111,110,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,80,114,101,99,105,115,105,111,110,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +68,101,102,97,117,108,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,97,117,108,116, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,68,101,102,97,117,108,116,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,111,116,78,117,108,108,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,111,116,32, +78,85,76,76,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,49,49,50,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,78,111,116,78,117,108,108,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,108,108,97,116,105,111,110,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,111,108,108,97,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,111, +108,108,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107, +112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,111,110,115,116,114,97,105,110,116,115,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,67,111,110,115,116,114,97,105,110,116,115,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61, +34,108,115,116,67,111,110,115,116,114,97,105,110,116,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,50,55,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95, +83,69,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71, +82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,53,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98, +111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,111,110,115,116,114, +84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,65,100,100,67,111,110,115,116,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,82,101,109,111,118,101,67,111,110,115,116,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79,87,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_13 = 6909; +static unsigned char xml_res_file_13[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,69,100,105,116,71,114,105,100,79,112,116,105,111, +110,115,34,62,10,32,32,32,32,60,116,105,116,108,101,62,86,105,101,119,32, +68,97,116,97,32,79,112,116,105,111,110,115,60,47,116,105,116,108,101,62, +10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53,100,60,47,115, +105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70, +65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80, +84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82, +69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119, +97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,79, +112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,116,97,32,83,111,114,116, +105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,83,111,114,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53, +60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103,114, +111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,108,98,108,83,111,114,116,67,111,108,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,83,101,108,101,99,116,101,100,32,67,111,108,117,109,110,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115, +116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116,83,111,114,116, +67,111,108,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82,84, +124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +116,111,111,108,116,105,112,62,76,105,115,116,115,32,116,104,101,32,99, +111,108,117,109,110,115,32,116,104,97,116,32,116,104,101,32,100,97,116, +97,32,119,105,108,108,32,98,101,32,115,111,114,116,101,100,32,98,121,46, +60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108, +65,118,97,105,108,67,111,108,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,118,97,105,108, +97,98,108,101,32,67,111,108,117,109,110,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,111,67,111,108,117,109,110,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116, +111,111,108,116,105,112,62,83,101,108,101,99,116,32,97,32,99,111,108,117, +109,110,32,116,111,32,97,100,100,32,116,111,32,116,104,101,32,115,111,114, +116,32,108,105,115,116,46,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,44,49,44,50,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,98,116,110,65,115,99,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65, +115,99,101,110,100,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, +111,108,116,105,112,62,65,100,100,32,116,104,101,32,115,101,108,101,99, +116,32,99,111,108,117,109,110,32,102,111,114,32,97,115,99,101,110,100,105, +110,103,32,115,111,114,116,46,60,47,116,111,111,108,116,105,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,112,101,114,115,112,101,99,116,105,118, +101,62,49,60,47,112,101,114,115,112,101,99,116,105,118,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110, +68,101,115,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,115,99,101,110,100, +105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112, +62,65,100,100,32,116,104,101,32,115,101,108,101,99,116,32,99,111,108,117, +109,110,32,102,111,114,32,100,101,115,99,101,110,100,105,110,103,32,115, +111,114,116,46,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,112,101,114,115,112,101,99,116,105,118,101,62,49,60,47,112, +101,114,115,112,101,99,116,105,118,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,77,79,86, +69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,82,101,109,111,118, +101,32,116,104,101,32,115,101,108,101,99,116,101,100,32,115,111,114,116, +32,99,111,108,117,109,110,46,60,47,116,111,111,108,116,105,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,112,101,114,115,112,101,99,116,105,118, +101,62,49,60,47,112,101,114,115,112,101,99,116,105,118,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,70,105,108,116,101,114,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,70,105,108,116,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,108,98,108,70,105,108,116,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,116, +101,114,32,83,116,114,105,110,103,32,40,101,103,46,32,111,105,100,32,38, +103,116,59,32,49,48,32,65,78,68,32,111,105,100,32,38,108,116,59,32,53,48, +41,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,99,116,108,83,81,76,66,111,120,34,32,110,97,109,101,61,34,115,113, +108,70,105,108,116,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,69,110,116,101, +114,32,116,104,101,32,102,105,108,116,101,114,32,115,116,114,105,110,103, +32,116,111,32,97,112,112,108,121,32,116,111,32,116,104,101,32,100,97,116, +97,46,32,83,81,76,32,115,121,110,116,97,120,32,115,104,111,117,108,100, +32,98,101,32,117,115,101,100,32,97,115,32,116,104,101,32,115,116,114,105, +110,103,32,119,105,108,108,32,98,101,32,117,115,101,100,32,97,115,32,97, +32,39,87,72,69,82,69,39,32,99,108,97,117,115,101,46,60,47,116,111,111,108, +116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,86,97,108,105,100, +97,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,86,97,108,105,100,97,116,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,86,97,108,105,100,97,116,101, +32,116,104,101,32,115,121,110,116,97,120,32,111,102,32,116,104,101,32,102, +105,108,116,101,114,32,115,116,114,105,110,103,46,60,47,116,111,111,108, +116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,65,99,99,101,112,116,32,116,104,101,32,99,117,114,114, +101,110,116,32,111,112,116,105,111,110,115,32,97,110,100,32,99,108,111, +115,101,32,116,104,101,32,100,105,97,108,111,103,117,101,46,60,47,116,111, +111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,67,97,110,99, +101,108,32,97,110,121,32,99,104,97,110,103,101,115,32,97,110,100,32,99, +108,111,115,101,32,116,104,101,32,100,105,97,108,111,103,117,101,46,60, +47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111, +117,114,99,101,62,10}; + +static size_t xml_res_size_14 = 9704; +static unsigned char xml_res_file_14[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,69,118,101,110,116,84,114,105,103,103,101,114,34, +62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53,100,60,47, +115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +65,80,84,73,79,78,124,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119, +120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98, +108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110, +98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,51,50,48,44,50,52,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,62,51,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,76,69,70, +84,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,76, +69,70,84,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,76,69, +70,84,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,52,48,53,44,51,49,51,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107, +112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,52, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,82,111,119,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,97,98, +108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76, +73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,69,110,97,98,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,111,110,115,116,114,97,105,110,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,69,110,97,98,108,101,100,32,83,116,97,116,117,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,65,76,73, +71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100, +105,111,66,111,120,34,32,110,97,109,101,61,34,114,100,98,69,110,97,98,108, +101,83,116,97,116,117,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,69,78,65,66,76,69,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,82,69,80,76,73,67,65,60,47,105,116,101,109,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,65,76,87,65,89,83,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,50,49,48,44,51,56,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,82,65,95,83,80,69,67,73,70,89,95,82,79,87,83,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,70,117,110,99,116,105,111,110,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,114, +105,103,103,101,114,32,102,117,110,99,116,105,111,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,70,117,110,99,116,105,111,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,69,118,101,110,116,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,69,118,101,110,116,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,111,120,34,32,110, +97,109,101,61,34,114,100,98,69,118,101,110,116,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,68,68,76,32,67,79,77,77,65, +78,68,32,83,84,65,82,84,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,68,68, +76,32,67,79,77,77,65,78,68,32,69,78,68,60,47,105,116,101,109,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,83,81,76,32,68,82,79,80,60,47,105,116,101,109,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116, +101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,51,51,51,44,51,56,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,82,65,95,83,80,69,67,73,70,89,95,82,79,87,83,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,87,104,101,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,87,104,101, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124, +119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,87,104,101,110,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,45,49,44,45,49,60,47, +112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,51,55,52,44,49,56,55,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105, +110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,72,79,82,73,90,79,78,84,65,76,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71, +78,95,84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73, +71,78,95,84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,84,79,80,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119, +120,65,76,73,71,78,95,84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,84,79,80, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116, +117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99, +116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_15 = 6709; +static unsigned char xml_res_file_15[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,69,120,116,101,110,115,105,111,110,34,62,10,32,32, +32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62, +51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84, +69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,50,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,78,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73, +78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101, +32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,108,117, +115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,99,104,101,109, +97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,79,98,106,101,99,116,115,83,99,104,101,109,97,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +86,101,114,115,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,101,114,115,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,86,101,114,115,105,111,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_16 = 6236; +static unsigned char xml_res_file_16[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,69,120,116,84,97,98,108,101,34,62,10,32,32,32,32, +60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48, +48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +51,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119,110,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,119,110,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109, +109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101, +114,83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67, +65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,50,44,50,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,83,81,76,66,111,120, +34,32,110,97,109,101,61,34,116,120,116,83,113,108,66,111,120,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97, +116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_17 = 8453; +static unsigned char xml_res_file_17[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,70,105,110,100,82,101,112,108,97,99,101,34,62,10, +32,32,32,32,60,116,105,116,108,101,62,70,105,110,100,32,97,110,100,32,82, +101,112,108,97,99,101,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115, +105,122,101,62,51,48,48,44,49,54,54,100,60,47,115,105,122,101,62,10,32, +32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73, +65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119, +120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66, +79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,70,105,110,100,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +70,105,110,100,32,119,104,97,116,58,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,70,105,110,100,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,69,110,116,101, +114,32,116,104,101,32,115,116,114,105,110,103,32,116,111,32,115,101,97, +114,99,104,32,102,111,114,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,70,73,78,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,70,105,110,100,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60, +47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,116,111,111,108,116,105,112,62,70,105,110,100,32,116,104,101,32, +115,112,101,99,105,102,105,101,100,32,116,101,120,116,60,47,116,111,111, +108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,108,98,108,82,101,112,108,97,99,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,112,108,97, +99,101,32,119,105,116,104,58,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,82,101,112,108,97,99,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,69,110,116, +101,114,32,116,104,101,32,114,101,112,108,97,99,101,109,101,110,116,32, +116,101,120,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,80,76,65,67,69,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,82,101,112,108,97,99,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112, +62,70,105,110,100,32,97,110,100,32,114,101,112,108,97,99,101,32,116,104, +101,32,115,112,101,99,105,102,105,101,100,32,116,101,120,116,60,47,116, +111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +82,69,80,76,65,67,69,65,76,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,82,101,112,108,97,99,101,32,38,97,109, +112,59,65,108,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,70,105,110,100,32,97, +110,100,32,114,101,112,108,97,99,101,32,97,108,108,32,111,99,99,117,114, +114,101,110,99,101,115,32,111,102,32,116,104,101,32,115,112,101,99,105, +102,105,101,100,32,116,101,120,116,60,47,116,111,111,108,116,105,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,98,79,114,105,103,105,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,114,105, +103,105,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +114,100,79,114,105,103,105,110,67,117,114,115,111,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70, +114,111,109,32,116,104,101,32,99,117,114,115,111,114,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +97,108,117,101,62,49,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,66,101, +103,105,110,32,115,101,97,114,99,104,105,110,103,32,97,116,32,116,104,101, +32,99,117,114,114,101,110,116,32,99,117,114,115,111,114,32,112,111,115, +105,116,105,111,110,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,114,100,79,114,105,103,105,110,84,111,112,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,70,114,111,109,32,116,104,101,32,116,111,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116, +111,111,108,116,105,112,62,66,101,103,105,110,32,115,101,97,114,99,104, +105,110,103,32,97,116,32,116,104,101,32,116,111,112,32,111,102,32,116,104, +101,32,116,101,120,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,98,68,105,114,101,99,116,105,111,110,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +68,105,114,101,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,114,100,68,105,114,101,99,116,105,111,110,70,111,114, +119,97,114,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,70,111,114,119,97,114,100,115,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,97,108,117,101,62,49,60,47,118,97,108,117,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112, +62,83,101,97,114,99,104,32,102,111,114,119,97,114,100,115,32,116,104,114, +111,117,103,104,32,116,104,101,32,116,101,120,116,60,47,116,111,111,108, +116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,114,100,68,105,114,101, +99,116,105,111,110,66,97,99,107,119,97,114,100,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,66,97,99, +107,119,97,114,100,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,83, +101,97,114,99,104,32,98,97,99,107,119,97,114,100,115,32,116,104,114,111, +117,103,104,32,116,104,101,32,116,101,120,116,60,47,116,111,111,108,116, +105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,98,79,112,116,105,111,110,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,79,112,116,105,111,110,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,99,104,107,79,112,116,105,111,110,115,87,104,111,108,101, +87,111,114,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,87,104,111,108,101,32,119,111,114,100,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,77,97,116,99,104,32,111,110, +32,119,104,111,108,101,32,119,111,114,100,115,60,47,116,111,111,108,116, +105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,79,112,116,105,111,110,115,77, +97,116,99,104,67,97,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,116,99,104,32,99,97,115, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,116,111,111,108,116,105,112,62,77,97,116,99,104,32,116, +104,101,32,99,97,115,101,32,111,102,32,116,104,101,32,116,101,120,116,60, +47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +79,112,116,105,111,110,115,85,115,101,82,101,103,101,120,112,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,82,101,103,117,108,97,114,32,101,120,112,114,101,115,115,105,111, +110,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,85,115,101,32,114, +101,103,117,108,97,114,32,101,120,112,114,101,115,115,105,111,110,115,32, +119,104,101,110,32,115,101,97,114,99,104,105,110,103,60,47,116,111,111, +108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,67,108,111,115,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,67, +108,111,115,101,32,116,104,101,32,100,105,97,108,111,103,60,47,116,111, +111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99, +116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_18 = 11336; +static unsigned char xml_res_file_18[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,70,111,114,101,105,103,110,68,97,116,97,87,114,97, +112,112,101,114,34,62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32, +32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53,100,60,47,115,105,122, +101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85, +76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73, +79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83, +73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99, +111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111, +119,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111, +116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101, +98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108, +101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,80,114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,51,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44, +45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,108,117,115, +116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,32,83,108,111,110, +121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,67,108,117,115,116,101,114, +83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45, +49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,68,101,102,105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,68,101,102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,72,97,110, +100,108,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,72,97,110,100,108,101,114,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,72,97,110,100,108,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,86,97,108,105,100,97,116,111,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,97,108,105,100,97,116,111,114,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,86,97,108,105,100,97,116,111,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111, +116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,79,112,116,105,111,110,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,79,112,116,105,111,110,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47, +103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34,32, +110,97,109,101,61,34,108,115,116,79,112,116,105,111,110,115,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,55,48,44,49,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67, +95,82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,56,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,79,112,116,105,111,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,79,112,116,105,111,110,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,79,112,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,108,117,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,86,97,108,117,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,66,79,84,84,79, +77,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,72,79,82,73,90,79, +78,84,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,82,69,77,79,86,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111, +118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,51,44,53,56, +100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,65,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,47,67,104, +97,110,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,51,44, +55,56,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,44,50,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,55,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44, +51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,71,82,79,87,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110, +107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82, +79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_19 = 14711; +static unsigned char xml_res_file_19[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,70,111,114,101,105,103,110,75,101,121,34,62,10,32, +32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101, +62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69, +82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,49,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109, +101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76, +73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101, +32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,99,98,67,108,117,115,116,101,114,83, +101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,68,101,102,101,114,114,97,98,108,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +101,114,114,97,98,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,68,101,102,101, +114,114,97,98,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +68,101,102,101,114,114,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,101,114,114, +101,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34, +32,110,97,109,101,61,34,99,104,107,68,101,102,101,114,114,101,100,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,77,97,116,99,104,70,117, +108,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,77,97,116,99,104,32,102,117,108,108,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,77,97,116,99,104,70,117,108,108,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,68,111,110,116,86,97,108,105,100, +97,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,68,111,110,39,116,32,118,97,108,105,100, +97,116,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34, +32,110,97,109,101,61,34,99,104,107,68,111,110,116,86,97,108,105,100,97, +116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,65,117, +116,111,73,110,100,101,120,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,117,116,111,32,70,75, +32,105,110,100,101,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +66,111,120,34,32,110,97,109,101,61,34,99,104,107,65,117,116,111,73,110, +100,101,120,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99, +104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,110,100, +101,120,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,118,101,114,105,110,103, +32,105,110,100,101,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,73,110,100,101,120,78, +97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,67,111,108,117,109,110,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, +115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34, +32,110,97,109,101,61,34,108,115,116,67,111,108,117,109,110,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95, +83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,84,79,80,124,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,124,119,120,71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +50,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,82,101, +102,101,114,101,110,99,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,102, +101,114,101,110,99,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98, +111,66,111,120,34,32,110,97,109,101,61,34,99,98,82,101,102,101,114,101, +110,99,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,108,117,109,110,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,76,111,99,97,108,32,99,111,108,117,109,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,111,108,117,109,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,82,101,102,67,111,108,117,109,110,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,82,101,102,101,114,101,110,99,105,110,103,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,82,101,102,67,111,108,117,109,110,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120, +71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,65,100,100,82,101,102, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,82,101,109,111,118,101,82,101,102,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,82,101,109,111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,71,82, +79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,65,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,65,99,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,44,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97, +100,105,111,66,111,120,34,32,110,97,109,101,61,34,114,98,79,110,85,112, +100,97,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,79,110,32,85,112,100,97,116,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,78,79, +32,65,67,84,73,79,78,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,82,69,83, +84,82,73,67,84,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,67,65,83,67,65, +68,69,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,83,69,84,32,78,85,76,76, +60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,105,116,101,109,62,83,69,84,32,68,69,70,65,85,76, +84,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,105,109,101,110,115, +105,111,110,62,49,60,47,100,105,109,101,110,115,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,82,65,95,83,80,69,67,73,70,89,95,67,79,76,83,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97, +100,105,111,66,111,120,34,32,110,97,109,101,61,34,114,98,79,110,68,101, +108,101,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,79,110,32,68,101,108,101,116,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,78,79, +32,65,67,84,73,79,78,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,82,69,83, +84,82,73,67,84,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,67,65,83,67,65, +68,69,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,83,69,84,32,78,85,76,76, +60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,105,116,101,109,62,83,69,84,32,68,69,70,65,85,76, +84,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,105,109,101,110,115, +105,111,110,62,49,60,47,100,105,109,101,110,115,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,82,65,95,83,80,69,67,73,70,89,95,67,79,76,83,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101, +61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69, +71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_20 = 11156; +static unsigned char xml_res_file_20[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,70,111,114,101,105,103,110,83,101,114,118,101,114, +34,62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115, +105,122,101,62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32, +32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73, +65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119, +120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66, +79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98, +111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111, +107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57, +54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99, +116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80, +114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110, +108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,114,111,119,115,62,51,60,47,103,114,111,119,97,98,108,101,114, +111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,79,73,68,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,79,73,68,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53, +44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,79,119,110,101,114,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,108,117,115, +116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,32,83,108,111,110, +121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,67,108,117,115,116,101,114, +83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45, +49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,68,101,102,105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,68,101,102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,121, +112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,84,121,112,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,84, +121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,86,101,114,115,105,111,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,86,101,114,115,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,86, +101,114,115,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,116,105, +111,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,79,112,116,105,111,110, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67, +116,114,108,34,32,110,97,109,101,61,34,108,115,116,79,112,116,105,111,110, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,112,111,115,62,55,48,44,49,53,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71, +76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,56,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124, +119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,112,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,79,112,116,105,111,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,86,97,108,117,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,86,97,108,117, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,66, +79,84,84,79,77,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,72,79, +82,73,90,79,78,84,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,119,120,73,68,95,82,69,77,79,86,69,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,82,101,109,111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,49,51,44,53,56,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,65,68,68,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65, +100,100,47,67,104,97,110,103,101,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111, +115,62,49,51,44,55,56,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,124,119,120,65,76,73,71,78,95,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,50,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,44, +50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,55,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,71,82,79,87,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110, +107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82, +79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_21 = 17722; +static unsigned char xml_res_file_21[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,70,111,114,101,105,103,110,84,97,98,108,101,34,62, +10,32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122, +101,62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32, +60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79, +71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89, +83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68, +69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111, +107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50, +52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60, +115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111, +112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114, +111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,52,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109, +101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119, +110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,99,104,101,109,97,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109,97,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67, +111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76, +84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,70,111,114,101,105,103,110,83,101,114,118,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,70,111,114,101,105,103,110,32,83,101,114,118,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,70,111,114,101,105,103,110,83,101,114,118,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,108,117, +109,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,67,111,108,117,109,110, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,44,49, +44,50,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,67, +111,109,112,111,115,105,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76, +105,115,116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116,77,101, +109,98,101,114,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67, +95,82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,77,101,109,98,101,114,110,97,109, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,109,98,101, +114,32,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,77,101,109,98,101,114,110,97,109,101,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,68,97,116,97,116,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,68,97,116,97,32,116,121,112,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,68,97,116,97,116,121,112,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,76,101,110,103,116,104,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,76,101,110,103,116,104,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108, +34,32,110,97,109,101,61,34,116,120,116,76,101,110,103,116,104,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,80,114,101,99,105,115,105,111,110,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,101,99,105,115,105,111,110, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,80,114,101, +99,105,115,105,111,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,111,116,78,117, +108,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,79,84,32, +78,85,76,76,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,78,111,116,78,117,108,108,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,77,101,109,98,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,65, +76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,65,100,100,77,101,109, +98,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,65,76, +73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,67,104,97,110,103,101, +77,101,109,98,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,104,97,110,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115, +62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111, +111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,112,116,105,111,110,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61, +34,112,110,108,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119, +97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101, +61,34,108,115,116,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,55,48,44,49, +53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79, +82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,56,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,112,116,105,111,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,112,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116, +79,112,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,108, +117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,108,117,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,66,79,84,84,79,77,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,72,79,82,73,90,79,78,84,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,77,79,86, +69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,112,111,115,62,49,51,44,53,56,100,60,47,112,111,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119, +120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,65,68,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,65,100,100,47,67,104,97,110,103,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,112,111,115,62,49,51,44,55,56,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_22 = 27690; +static unsigned char xml_res_file_22[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,70,117,110,99,116,105,111,110,34,62,10,32,32,32,32, +60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,53, +48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,51,52,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +52,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119,110,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,119,110,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,83,99,104,101,109,97,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111, +109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,108,117,115, +116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,32,83,108,111,110, +121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,67,108,117,115,116,101,114, +83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87, +78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111, +111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53, +60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,65,114,103,117,109,101,110,116,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,114, +103,117,109,101,110,116,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,65,114,103,117, +109,101,110,116,115,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,82,101,116,117,114,110,116,121, +112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,82,101,116,117,114,110,32,116,121,112,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,82,101,116,117,114,110,116,121,112,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +76,97,110,103,117,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76,97,110,103,117,97, +103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,76,97,110,103,117,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,79,112,116,105,111,110,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,79,112,116,105,111,110,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,86,111,108,97,116,105,108,105,116,121, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,86,111,108,97,116,105,108,105,116,121,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,86,111,108,97,116,105,108,105,116,121,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,105,116,101,109,62,86,79,76,65,84,73,76,69,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,83,84,65,66,76,69,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,73,77,77,85,84,65,66,76,69,60,47,105,116,101,109,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,101,108,101,99,116,105,111,110,62,48,60,47,115,101,108, +101,99,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,80,97,114,97,108,108,101,108, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,80,97,114,97,108,108,101,108,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +80,97,114,97,108,108,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101, +109,62,85,78,83,65,70,69,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,82, +69,83,84,82,73,67,84,69,68,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,83, +65,70,69,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99, +116,105,111,110,62,48,60,47,115,101,108,101,99,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,83,101,116,111,102,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,116,117, +114,110,115,32,115,101,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,101,116,111, +102,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,116,114, +105,99,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,83,116,114,105,99,116,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61, +34,99,104,107,83,116,114,105,99,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,83,101,99,117,114,101,68,101,102,105,110,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,83,101,99,117,114,105,116,121,32,111,102,32,100,101, +102,105,110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,83,101,99,117,114,101,68, +101,102,105,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,87,105,110,100,111,119,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,87,105,110,100,111, +119,32,102,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,87,105,110, +100,111,119,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,115,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,69,115,116,105,109,97,116,101,100,32, +99,111,115,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,67,111,115,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,82,111,119,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,69,115,116,105,109,97,116,101,100,32,114,111,119,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,82,111,119,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,76,101,97,107,80,114,111,111,102,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,76,101,97,107,32,112,114,111,111,102,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,76,101,97,107, +80,114,111,111,102,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,80,97,114,97,109,101,116,101,114,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,97,114,97,109,101,116,101,114,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105, +115,116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116,65,114,103, +117,109,101,110,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80, +79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,56,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,68,97,116,97,116,121,112,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,68,97,116,97,116,121,112,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +68,97,116,97,116,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,77,111,100,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,111,100,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,114, +100,98,73,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,78,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82, +66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,114, +100,98,79,117,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,85,84, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,114,100,98,73,110,79,117,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,78,32,79,85,84,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,114,100,98,86,97,114,105,97,100,105, +99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,82,73,65,68,73,67, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,84,79,80,124,119,120,66,79,84,84,79,77,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,65,114,103,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,114,103, +117,109,101,110,116,32,110,97,109,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,65,114,103,78,97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,65,114,103,68, +101,102,86,97,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,97,117,108, +116,32,86,97,108,117,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,65,114,103,68, +101,102,86,97,108,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,52,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,52,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95, +66,79,84,84,79,77,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,72, +79,82,73,90,79,78,84,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,77,79,86, +69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,65,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,67,72,65,78,71,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,104,97,110, +103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114, +111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116, +101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,100,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,67,111,100,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,62,48,44,49,60,47,103,114,111,119,97,98,108,101, +114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,79,98,106,101,99,116,70,105, +108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,79,98,106,101,99,116,32,102,105, +108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,79,98,106,101,99,116,70,105, +108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,105,110,107,83,121, +109,98,111,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76,105,110,107,32,115,121, +109,98,111,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,76,105,110,107,83,121,109,98, +111,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,83,81,76,66,111,120,34,32,110,97,109, +101,61,34,116,120,116,83,113,108,66,111,120,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,77,85,76,84,73,76,73,78,69,124,119,120,83,85,78,75,69,78,95, +66,79,82,68,69,82,124,119,120,84,69,95,82,73,67,72,50,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86, +97,114,105,97,98,108,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,86, +97,114,105,97,98,108,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,52,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115, +116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116,86,97,114,105, +97,98,108,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,112,111,115,62,53,44,54,100,60,47,112,111,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95,83,73, +78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,48,44, +48,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,65,100,100,86,97,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,65,100,100,47,67,104,97,110,103,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110, +82,101,109,111,118,101,86,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101, +109,111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,86,97,114,110,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,86,97,114,105,97,98,108,101,32,78,97,109, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,86,97,114,110,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,114, +105,97,98,108,101,32,86,97,108,117,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,44,49,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, +67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,86,97,108,117,101, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,86,97, +108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124, +119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79, +87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_23 = 7226; +static unsigned char xml_res_file_23[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,71,114,111,117,112,34,62,10,32,32,32,32,60,116,105, +116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54, +53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62, +119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124, +119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78, +85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121, +108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101, +61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100, +62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,71,114,111,117,112,110,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,71,114,111,117,112,32,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83, +101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65, +68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77, +101,109,98,101,114,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,77,101,109, +98,101,114,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,49,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,44,50,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,85,115,101,114,115,78, +111,116,73,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,78,111,116,32,77,101,109,98,101,114, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,44,50,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +85,115,101,114,115,73,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,109,98,101,114,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,76,105,115,116,66,111,120,34,32,110,97,109,101, +61,34,108,98,85,115,101,114,115,78,111,116,73,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,56,54,44,49,50,51,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,66,95,78,69,69,68,69,68,95,83,66,124,119,120, +76,66,95,83,79,82,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60, +47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,98,116,110,65,100,100,85,115,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,38,103,116,59,38,103,116,59,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,49,56,44,45,49,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,66,79,84,84,79,77,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,68,101,108,85,115,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,108,116,59,38,108,116,59,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,49,56,44,45,49,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,84,79,80,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,66, +111,120,34,32,110,97,109,101,61,34,108,98,85,115,101,114,115,73,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,56,54,44,49,50,51,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,76,66,95,78,69,69,68,69,68,95, +83,66,124,119,120,76,66,95,83,79,82,84,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82, +79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_24 = 5724; +static unsigned char xml_res_file_24[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,72,98,97,67,111,110,102,105,103,34,62,10,32,32,32, +32,60,116,105,116,108,101,62,67,108,105,101,110,116,32,65,99,99,101,115, +115,32,67,111,110,102,105,103,117,114,97,116,105,111,110,60,47,116,105, +116,108,101,62,10,32,32,32,32,60,115,105,122,101,62,50,50,48,44,49,53,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,69,110,97,98,108,101,100,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,97,98,108, +101,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,69,110, +97,98,108,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,84,121,112,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,68,97,116,97,98,97,115,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +68,97,116,97,98,97,115,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,68,97,116,97,98,97,115,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,85,115,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +85,115,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,85,115,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,73,80,97,100,100,114,101,115,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73, +80,32,65,100,100,114,101,115,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,73,80,97,100,100,114,101,115,115,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,77,101, +116,104,111,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,77,101,116,104,111,100,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,77,101,116,104,111,100,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,112,116,105,111,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,116,105,111,110, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,112,116, +105,111,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111, +117,114,99,101,62,10}; + +static size_t xml_res_size_25 = 16342; +static unsigned char xml_res_file_25[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,73,110,100,101,120,34,62,10,32,32,32,32,60,116,105, +116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54, +53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62, +119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124, +119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78, +85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121, +108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101, +61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100, +62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101, +102,105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108, +68,101,102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,62,54,60,47,103,114,111,119,97,98,108,101,114,111, +119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +84,97,98,108,101,115,112,97,99,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,97,98,108,101, +115,112,97,99,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,84,97,98,108,101,115,112,97,99,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,121,112,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,65,99,99,101,115,115,32,109,101,116,104,111,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,70,105,108,108,70,97,99,116,111,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70, +105,108,108,32,102,97,99,116,111,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,105,108, +108,70,97,99,116,111,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,85,110,105,113,117,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,85,110,105,113,117,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,85,110, +105,113,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,108,117,115,116,101,114,101,100,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,108,117,115, +116,101,114,101,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,67,108,117,115,116,101,114, +101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111, +110,99,117,114,114,101,110,116,108,121,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,110, +99,117,114,114,101,110,116,32,98,117,105,108,100,63,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,67,111,110,99,117,114,114,101,110,116,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,87,104,101,114,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111, +110,115,116,114,97,105,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,87,104,101,114,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85, +76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111, +116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,67,111,108,117,109,110,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, +115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34, +32,110,97,109,101,61,34,108,115,116,67,111,108,117,109,110,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95, +83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47, +103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,108,117,109,110,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,111,108,117,109,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,67,111,108,108,97,116,105,111,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,111,108,108,97,116,105,111,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34, +99,98,67,111,108,108,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,112, +67,108,97,115,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,101,114,97,116, +111,114,32,99,108,97,115,115,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,112,67,108,97,115, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,68,101,115,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,69,83,67,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,53,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +68,101,115,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,82,73,71,72,84,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,49,53,44,51,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,117,108,108,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,78,85,76,76,115,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,49,48,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115, +62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +114,100,98,78,117,108,108,115,70,105,114,115,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,70,73,82,83,84,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82,66,95, +71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,53,44, +51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,114,100,98,78,117,108,108, +115,76,97,115,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,76,65,83,84,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,97,108,117,101,62,49,60,47,118,97,108,117,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98, +116,110,65,100,100,67,111,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,82,101, +109,111,118,101,67,111,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109, +111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,48,44, +45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119, +120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_26 = 16411; +static unsigned char xml_res_file_26[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,73,110,100,101,120,67,111,110,115,116,114,97,105, +110,116,34,62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32, +60,115,105,122,101,62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62, +10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95, +68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124, +119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69, +95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101, +114,111,119,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116, +101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98, +111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101, +99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +80,114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,49,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,54,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,97,98,108, +101,115,112,97,99,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,84,97,98,108,101,115,112,97,99, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,84,97,98,108,101,115,112,97,99,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,73,110,100,101,120,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,73,110,100,101,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,73,110,100,101,120,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,121,112,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,65,99,99,101,115,115,32,109,101,116,104,111,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,70,105,108,108,70,97,99,116,111,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70, +105,108,108,32,102,97,99,116,111,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,105,108, +108,70,97,99,116,111,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,101,102,101,114,114, +97,98,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,68,101,102,101,114,114,97,98,108,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,99,104,107,68,101,102,101,114,114,97,98,108,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,101,102,101,114,114, +101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,68,101,102,101,114,114,101,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,68,101,102,101,114,114,101,100,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,87,104,101,114,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,110,115,116,114,97,105,110,116,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,87,104,101,114,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95, +77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,67,111,108,117,109,110,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, +115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34, +32,110,97,109,101,61,34,108,115,116,67,111,108,117,109,110,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95, +83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47, +103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,108,117,109,110,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,111,108,117,109,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,79,112,67,108,97,115,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,79,112,101,114,97,116,111,114,32,99,108,97,115,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,79,112,67,108,97,115,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,101,115,99,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,69,83,67,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +53,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,68,101,115,99,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,53,44,51, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,117,108,108,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,78,85,76,76,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +48,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,114,100,98,78,117,108,108,115,70, +105,114,115,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +70,73,82,83,84,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,49,53,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,114,100,98,78,117,108,108,115,76,97,115,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,76,65,83,84,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,49,60,47,118, +97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,79,112,101,114,97,116,111,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,112,101,114,97,116,111,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,112,101,114,97, +116,111,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51, +44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,98,116,110,65,100,100,67,111,108,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,67,111,108,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,53,48,44,45,49,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116, +117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99, +116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_27 = 13557; +static unsigned char xml_res_file_27[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,74,111,98,34,62,10,32,32,32,32,60,116,105,116,108, +101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,50,48,44,50,56,48,100, +60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120, +68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120, +67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119, +120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,49,54,44,50,53,53,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,73,68,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,73,68,34, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,69,110,97,98,108,101,100,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69, +110,97,98,108,101,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,69,110,97,98,108,101,100, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,74,111,98,99,108,97,115,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,74,111,98,32,99,108,97,115,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,74,111,98, +99,108,97,115,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68, +79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +72,111,115,116,65,103,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,111,115,116,32, +97,103,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,72,111,115,116,65,103,101,110, +116,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,114,101,97,116,101,100,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,114,101,97,116,101,100,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,114,101, +97,116,101,100,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,104,97,110,103,101,100,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,104,97,110,103,101,100,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,104,97, +110,103,101,100,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,78,101,120,116,114,117,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,78,101,120,116,32,114,117,110,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78, +101,120,116,114,117,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,97,115,116,114,117, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,76,97,115,116,32,114,117,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,76,97,115,116,114,117,110,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,97,115, +116,82,101,115,117,108,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76,97,115,116,32,114,101, +115,117,108,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,76,97,115,116,82,101,115,117, +108,116,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76, +73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98, +111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,116,101,112,115,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,83,116,101,112,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114, +111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115, +116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116,83,116,101,112, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120, +76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60, +47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98, +116,110,67,104,97,110,103,101,83,116,101,112,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,104,97,110,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110, +65,100,100,83,116,101,112,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,83,116, +101,112,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107, +112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,83,99,104,101,100,117,108,101,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,83,99,104,101,100,117,108,101,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116, +83,99,104,101,100,117,108,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95, +82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,67,104,97,110,103,101,83,99,104,101, +100,117,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,104,97,110,103,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,98,116,110,65,100,100,83,99,104,101,100,117, +108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,98,116,110,82,101,109,111,118,101,83,99,104,101,100,117,108,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101, +61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69, +71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_28 = 8800; +static unsigned char xml_res_file_28[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,76,97,110,103,117,97,103,101,34,62,10,32,32,32,32, +60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48, +48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +51,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,99,98,78,97,109,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110, +101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,84,114,117,115,116,101,100,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,84,114,117,115,116,101,100,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,84,114, +117,115,116,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49, +60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +72,97,110,100,108,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,97,110,100,108,101,114, +32,102,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,72,97,110,100,108, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,110, +108,105,110,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,73,110,108,105,110,101,32,102,117,110, +99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,73,110,108,105,110,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,86,97,108,105,100,97,116,111,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,86,97,108,105,100,97,116,111,114,32,102,117,110,99, +116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,86,97,108,105,100,97,116,111,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65, +68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97, +116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_29 = 4926; +static unsigned char xml_res_file_29[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,77,97,105,110,67,111,110,102,105,103,34,62,10,32, +32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101, +62,50,52,56,44,49,57,56,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69, +82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, +115,62,50,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,69,110,97,98,108,101, +100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,69,110,97,98,108,101,100,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,69,110,97,98,108,101,100,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,86,97,108,117,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,108, +117,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +116,120,116,86,97,108,117,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +66,111,120,34,32,110,97,109,101,61,34,99,104,107,86,97,108,117,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67, +111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,109,109,101,110,116,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32, +32,60,112,111,115,62,53,44,53,53,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,101,115,99, +114,105,112,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62, +49,48,44,54,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,50,51,56,44,57,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95, +78,79,95,65,85,84,79,82,69,83,73,90,69,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_30 = 2870; +static unsigned char xml_res_file_30[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,77,97,110,97,103,101,70,97,118,111,117,114,105,116, +101,115,34,62,10,32,32,32,32,60,116,105,116,108,101,62,77,97,110,97,103, +101,32,102,97,118,111,117,114,105,116,101,115,60,47,116,105,116,108,101, +62,10,32,32,32,32,60,115,105,122,101,62,50,49,56,44,49,57,56,100,60,47, +115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68, +69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67, +65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119, +120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +99,116,108,84,114,101,101,34,32,110,97,109,101,61,34,116,114,76,111,99, +97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,53,44,55,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,50,48,56,44,49,53,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,82,95, +72,65,83,95,66,85,84,84,79,78,83,32,124,32,119,120,83,73,77,80,76,69,95, +66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +51,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,82,101,110,97,109, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,82,101,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,68,101,108,101,116,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,108,101,116,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,98,116,110,78,101,119,70,111,108,100, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,78,101,119,32,102,111,108,100,101,114,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114, +101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_31 = 4804; +static unsigned char xml_res_file_31[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,77,97,110,97,103,101,77,97,99,114,111,115,34,62,10, +32,32,32,32,60,116,105,116,108,101,62,77,97,110,97,103,101,32,77,97,99, +114,111,115,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109, +101,61,34,108,115,116,75,101,121,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82, +84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119, +120,76,69,70,84,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +109,105,110,115,105,122,101,62,49,53,48,100,60,47,109,105,110,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,53,44,53,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,53,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78, +97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,50,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119, +120,71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,44, +53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108, +83,81,76,66,111,120,34,32,110,97,109,101,61,34,116,120,116,83,113,108,66, +111,120,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,83,85,78,75,69,78,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,66,79,84,84,79,77,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,115,105,122, +101,62,50,48,48,44,49,48,48,100,60,47,109,105,110,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,53,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,44,53,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,67,108,101,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,108,101, +97,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,52,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,44,53,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,83,97,118,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,97,118,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,44,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,62,50,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,50,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,124,119,120,71,82,79,87,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_32 = 3447; +static unsigned char xml_res_file_32[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,114,101, +115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34, +100,108,103,77,111,118,101,84,97,98,108,101,115,112,97,99,101,34,62,10, +32,32,32,32,60,116,105,116,108,101,62,77,111,118,101,32,111,98,106,101, +99,116,115,32,116,111,32,97,110,111,116,104,101,114,32,116,97,98,108,101, +115,112,97,99,101,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105, +122,101,62,50,48,48,44,50,48,48,100,60,47,115,105,122,101,62,10,32,32,32, +32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76, +79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83, +89,83,84,69,77,95,77,69,78,85,60,47,115,116,121,108,101,62,10,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99, +111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101, +114,111,119,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,77,111,118,101,84,111,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,38,97,109,112,59,78,101,119,32,116,97,98, +108,101,115,112,97,99,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,77,111,118,101,84,111,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82, +69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,75,105,110,100,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,79,98,106,101,99,116,115,39,32, +107,105,110,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,75,105,110,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,98,106,101,99,116,115,39,32,111,119,110,101,114, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,119,110,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67, +69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98, +106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_33 = 15920; +static unsigned char xml_res_file_33[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,79,112,101,114,97,116,111,114,34,62,10,32,32,32,32, +60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48, +48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +52,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119,110,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,119,110,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,99,104,101, +109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73, +78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101, +32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,108,117, +115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,76,101,102,116,84,121,112,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76,101,102, +116,32,116,121,112,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,76,101,102,116,84,121,112,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,82,105,103,104,116,84,121,112,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,105, +103,104,116,32,116,121,112,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,82,105,103,104,116, +84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,80,114,111,99,101,100,117,114,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,112,101,114,97,116,111,114,32,102,117,110,99,116,105,111,110, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,80,114,111,99,101,100,117,114,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87, +78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73, +109,112,108,101,109,101,110,116,97,116,105,111,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,50,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,82,101,115,116,114,105,99,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,115,116,114, +105,99,116,32,102,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,82,101,115, +116,114,105,99,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68, +79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +74,111,105,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,74,111,105,110,32,102,117,110,99,116, +105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,99,98,74,111,105,110,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,109,109,117,116,97,116,111,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,111,109,109,117,116,97,116,111,114,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,111,109,109,117,116,97,116,111,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,78,101,103,97,116,111,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78, +101,103,97,116,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,78,101,103,97,116,111,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65, +68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,76,101,102,116,83,111,114,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,76,101,102,116,32,115,111,114,116,32,111,112,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,76,101,102,116,83,111,114,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,82,105,103,104,116,83,111,114,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,82,105,103,104,116,32,115,111,114,116,32,111,112,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,82,105,103,104,116,83,111,114,116,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,76,101,115,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,108,116, +59,32,111,112,101,114,97,116,111,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,76,101,115,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65, +68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,71,114,101,97,116,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,38,103,116,59,32,111,112,101,114,97,116,111,114,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,71,114,101,97,116,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,97,110,72,97,115,104,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +117,112,112,111,114,116,115,32,104,97,115,104,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,67,97, +110,72,97,115,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,97,110,77,101,114,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,117,112,112,111,114, +116,115,32,109,101,114,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,67,97,110,77,101, +114,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_34 = 7045; +static unsigned char xml_res_file_34[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,80,97,99,107,97,103,101,34,62,10,32,32,32,32,60,116, +105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44, +50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, +69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,51,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,79,119,110,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,119,110,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111, +109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97, +100,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,72,101,97,100,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112, +62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,83,81,76,66,111,120,34,32,110,97,109, +101,61,34,116,120,116,72,101,97,100,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,77,85,76,84,73,76,73,78,69,124,119,120,83,85,78,75,69,78,95, +66,79,82,68,69,82,124,119,120,84,69,95,82,73,67,72,50,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,66,111,100,121,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,66,111,100,121,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,83,81,76,66,111,120,34,32,110,97,109,101,61,34,116,120,116,66,111,100, +121,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,124, +119,120,83,85,78,75,69,78,95,66,79,82,68,69,82,124,119,120,84,69,95,82, +73,67,72,50,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_35 = 5366; +static unsigned char xml_res_file_35[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,80,103,112,97,115,115,67,111,110,102,105,103,34,62, +10,32,32,32,32,60,116,105,116,108,101,62,67,108,105,101,110,116,32,65,99, +99,101,115,115,32,67,111,110,102,105,103,117,114,97,116,105,111,110,60, +47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48, +44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,115,105, +122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,69,110, +97,98,108,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,69,110,97,98,108,101,100,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,69,110,97,98,108,101,100,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,72,111, +115,116,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,72,111,115,116,110,97,109,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,72,111,115,116,110,97, +109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,80,111,114,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,80,111,114,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,80,111,114,116,34,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,97,116, +97,98,97,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,68,97,116,97,98,97,115,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108, +34,32,110,97,109,101,61,34,116,120,116,68,97,116,97,98,97,115,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +85,115,101,114,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,85,115,101,114,110,97,109,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, +67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,85,115,101,114,110, +97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,80,97,115,115,119,111,114,100,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,97,115,115,119, +111,114,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,80,97,115,115,119,111,114,100,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,80,65,83,83, +87,79,82,68,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,82,101,80,97,115,115,119,111,114, +100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,80,97,115,115,119,111,114,100,32,40,97,103,97,105,110,41,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, +67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,82,101,80,97,115, +115,119,111,114,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,84,69,95,80,65,83,83,87,79,82,68,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_36 = 3212; +static unsigned char xml_res_file_36[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,114,101, +115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34, +100,108,103,82,101,97,115,115,105,103,110,68,114,111,112,79,119,110,101, +100,34,62,10,32,32,32,32,60,116,105,116,108,101,62,82,101,97,115,115,105, +103,110,47,68,114,111,112,32,79,119,110,101,100,60,47,116,105,116,108,101, +62,10,32,32,32,32,60,115,105,122,101,62,50,48,48,44,50,48,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68, +69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67, +65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,114,98,82,101,97,115,115,105,103,110,84, +111,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,82,101,97,115,115,105,103,110,32,111,98,106,101, +99,116,115,32,116,111,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,82,111,108,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79, +78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,114,98,68,114,111,112,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,38,97,109,112,59,68,114,111,112,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,68,97,116,97,98,97,115,101,115, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,70,114,111,109,32,100,97,116,97,98,97,115,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,68,97,116,97,98,97,115, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60, +47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62, +10}; + +static size_t xml_res_size_37 = 9858; +static unsigned char xml_res_file_37[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,67,108,117,115,116,101,114,34,62,10,32, +32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101, +62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69, +82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,54,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,74,111,105,110, +67,108,117,115,116,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,74,111,105,110,32,101,120, +105,115,116,105,110,103,32,99,108,117,115,116,101,114,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,74,111,105,110,67,108,117,115,116,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,101,114,118,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,101,114,118,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,101,114,118,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,97,116,97,98,97,115, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,97,116,97,98,97,115,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +68,97,116,97,98,97,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,108,117,115,116,101,114,78,97,109,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,108,117,115,116,101,114,32,110,97,109,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,44,49,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,67,108,117,115,116,101,114,78,97,109,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,108,117, +115,116,101,114,78,97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,78,111,100,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +76,111,99,97,108,32,78,111,100,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,78,111,100,101,73,68,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,111,100,101,78,97,109, +101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +65,100,109,105,110,78,111,100,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,109,105,110, +32,78,111,100,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116, +65,100,109,105,110,78,111,100,101,73,68,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +116,120,116,65,100,109,105,110,78,111,100,101,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,65,100,109,105,110,78,111,100,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_38 = 5387; +static unsigned char xml_res_file_38[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,67,108,117,115,116,101,114,85,112,103, +114,97,100,101,34,62,10,32,32,32,32,60,116,105,116,108,101,62,85,112,103, +114,97,100,101,32,99,108,117,115,116,101,114,32,115,111,102,116,119,97, +114,101,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101, +62,50,50,48,44,49,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69, +82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49,50,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,117,114,114,101,110,116,86, +101,114,115,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,117,114,114,101,110,116, +32,118,101,114,115,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,117,114,114, +101,110,116,86,101,114,115,105,111,110,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,101, +114,118,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,83,101,114,118,101,114,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,83,101,114,118,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,68,97,116,97,98,97,115,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68, +97,116,97,98,97,115,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,68,97,116,97,98,97,115,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101, +114,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,108,117,115,116,101,114,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,67,108,117,115,116,101,114,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,86,101,114,115,105,111,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,86,101,114,115,105,111,110,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,86,101,114,115,105,111,110,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_39 = 4038; +static unsigned char xml_res_file_39[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,76,105,115,116,101,110,34,62,10,32,32, +32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62, +50,50,48,44,49,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84, +69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49,50,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,79,114,105,103,105,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,79,114,105,103,105,110,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,114,105,103,105, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,82,101,99,101,105, +118,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,82,101,99,101,105,118,101,114,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,82,101,99,101,105,118,101,114,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,80,114,111,118,105,100,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,80,114,111,118,105,100,101,114,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,80,114,111,118,105,100,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_40 = 3343; +static unsigned char xml_res_file_40[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,78,111,100,101,34,62,10,32,32,32,32,60, +116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,50,48, +44,49,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49,50,53,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,49,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,73,68,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73, +68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,73,68,34,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111, +109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114, +101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_41 = 3939; +static unsigned char xml_res_file_41[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,80,97,116,104,34,62,10,32,32,32,32,60, +116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,50,48, +44,49,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49,50,53,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,101,114,118,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,101,114,118,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,101,114,118,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,110,110,73,110, +102,111,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,110,110,101,99,116,32,105,110,102, +111,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,110,110,73,110,102,111,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,67,111,110,110,82,101,116,114,121,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,110,110,32,114,101,116,114,121,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,67,111,110,110,82,101,116,114,121,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_42 = 4031; +static unsigned char xml_res_file_42[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,83,101,113,117,101,110,99,101,34,62,10, +32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122, +101,62,50,50,48,44,49,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32, +60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79, +71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89, +83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68, +69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111, +107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49, +50,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60, +115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111, +112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114, +111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,62,50,60,47,103,114,111,119,97,98,108,101, +114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,101,113, +117,101,110,99,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,83,101,113,117,101,110,99,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,83,101,113,117,101,110,99,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,68,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,73,68,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114, +101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_43 = 4313; +static unsigned char xml_res_file_43[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,83,101,116,34,62,10,32,32,32,32,60,116, +105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,50,48,44, +49,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, +69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49,50,53,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,50,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,79,114,105,103,105,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,79,114,105,103,105,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53, +44,55,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,79,114,105,103,105,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,55,48, +44,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,68,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,50,50,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,112,111,115,62,55,48,44,50,48,100,60,47,112,111,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,51, +55,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +112,111,115,62,55,48,44,51,53,100,60,47,112,111,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51, +53,44,54,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69, +95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_44 = 3396; +static unsigned char xml_res_file_44[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,83,101,116,77,101,114,103,101,34,62,10, +32,32,32,32,60,116,105,116,108,101,62,77,101,114,103,101,32,115,101,116, +32,105,110,116,111,32,97,110,111,116,104,101,114,32,115,101,116,60,47,116, +105,116,108,101,62,10,32,32,32,32,60,115,105,122,101,62,50,50,48,44,49, +53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101, +62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69, +124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69, +78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49,50,53,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,116,32,116,111, +32,109,101,114,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,73,68,34,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,84,97,114,103,101,116,73,68,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,97,114, +103,101,116,32,111,102,32,109,101,114,103,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,84,97,114,103,101,116,73,68,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_45 = 3381; +static unsigned char xml_res_file_45[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,83,101,116,77,111,118,101,34,62,10,32, +32,32,32,60,116,105,116,108,101,62,77,111,118,101,32,115,101,116,32,116, +111,32,111,116,104,101,114,32,110,111,100,101,60,47,116,105,116,108,101, +62,10,32,32,32,32,60,115,105,122,101,62,50,50,48,44,49,53,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68, +69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67, +65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119, +120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,49,54,44,49,50,53,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,73,68,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,73, +68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,84,97,114,103,101,116,78,111,100,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,84,97,114,103,101,116,32,78,111,100,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,84,97,114,103,101,116,78,111,100,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111, +117,114,99,101,62,10}; + +static size_t xml_res_size_46 = 4740; +static unsigned char xml_res_file_46[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,83,117,98,115,99,114,105,112,116,105,111, +110,34,62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60, +115,105,122,101,62,50,50,48,44,49,53,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68, +73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119, +120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66, +79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111, +119,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98, +111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111, +107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,49, +54,44,49,50,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99, +116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80, +114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110, +108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,114,105,103, +105,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,114,105,103,105,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,79,114,105,103,105,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,82,101,99,101,105,118,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101, +99,101,105,118,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,82,101,99,101,105,118, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,80,114, +111,118,105,100,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,118,105,100,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,80,114,111,118,105,100,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,70,111,114,119,97,114,100,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,97,110,32,102,111,114,119,97,114,100,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,70,111,114,119,97,114,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_47 = 5504; +static unsigned char xml_res_file_47[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,84,97,98,108,101,34,62,10,32,32,32,32, +60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,50, +48,44,49,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49,50,53,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,51,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,84,97,98,108,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,84,97,98,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,84,97,98,108,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,73,68,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,73,68,34, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,73,110,100,101,120,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,100, +101,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,73,110,100,101,120,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84, +114,105,103,103,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,84,114,105, +103,103,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,76,105, +115,116,66,111,120,34,32,110,97,109,101,61,34,99,104,107,84,114,105,103, +103,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,53,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,50,48,48,44,57,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111, +117,114,99,101,62,10}; + +static size_t xml_res_size_48 = 4089; +static unsigned char xml_res_file_48[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,115,111,117,114,99,101,71,114,111,117,112, +34,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,82,101,115,71,114,112,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,71,114,111, +117,112,32,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,80,85,82,97,116,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,80, +85,32,82,97,116,101,32,76,105,109,105,116,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67, +80,85,82,97,116,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,68,105,114,116,121,82,97,116, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,105,114,116,121,32,82,97,116,101,32,76,105,109, +105,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,68,105,114,116,121,82,97,116,101,34, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,49,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50, +49,54,44,50,48,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116, +117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,115,105,122,101, +62,50,50,48,44,50,51,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69, +82,60,47,115,116,121,108,101,62,10,32,32,60,47,111,98,106,101,99,116,62, +10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_49 = 20602; +static unsigned char xml_res_file_49[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,111,108,101,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,55,48,44,50,53,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,54,54,44,50,50,53,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,50,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,111, +108,101,32,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,79,73,68,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73, +78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,80,97,115,115,119,100,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,80,97,115,115,119,111,114,100,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,80, +97,115,115,119,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,80,65,83,83,87, +79,82,68,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +82,101,80,97,115,115,119,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,97,115,115,119,111, +114,100,32,40,97,103,97,105,110,41,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,82,101,80, +97,115,115,119,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,80,65,83,83,87, +79,82,68,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +86,97,108,105,100,85,110,116,105,108,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,99,99,111,117, +110,116,32,101,120,112,105,114,101,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,97,108,101,110,100,97, +114,66,111,120,34,32,110,97,109,101,61,34,100,97,116,86,97,108,105,100, +85,110,116,105,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,68,80,95,65, +76,76,79,87,78,79,78,69,124,119,120,68,80,95,68,82,79,80,68,79,87,78,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,105,109, +101,83,112,105,110,67,116,114,108,34,32,110,97,109,101,61,34,116,105,109, +86,97,108,105,100,85,110,116,105,108,34,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,110,110, +101,99,116,105,111,110,76,105,109,105,116,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,110, +110,101,99,116,105,111,110,32,76,105,109,105,116,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,67,111,110,110,101,99,116,105,111,110,76,105,109,105,116,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,82,111,108,101,32,112,114,105,118, +105,108,101,103,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,82,111,108, +101,115,80,114,105,118,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,67,97,110,76,111,103,105,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,97,110,32,108,111,103,105,110,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,73,110,104,101,114,105,116,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +73,110,104,101,114,105,116,115,32,114,105,103,104,116,115,32,102,114,111, +109,32,112,97,114,101,110,116,32,114,111,108,101,115,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61, +34,99,104,107,83,117,112,101,114,117,115,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +117,112,101,114,117,115,101,114,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,67,114,101,97,116,101,68,66,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,110,32,99,114, +101,97,116,101,32,100,97,116,97,98,97,115,101,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,67,114,101,97,116,101,82,111,108,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,97,110,32,99,114,101,97,116,101,32,114,111,108,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,49,54,54,44,49,50,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34, +32,110,97,109,101,61,34,99,104,107,85,112,100,97,116,101,67,97,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,97,110,32,109,111,100,105,102,121,32,99,97,116,97,108, +111,103,32,100,105,114,101,99,116,108,121,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,82,101,112,108,105,99,97,116,105,111,110,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,97,110,32,105,110,105,116,105,97,116,101,32,115,116,114,101,97, +109,105,110,103,32,114,101,112,108,105,99,97,116,105,111,110,32,97,110, +100,32,98,97,99,107,117,112,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107, +112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,82,111,108,101,32,109,101,109,98,101,114,115,104,105,112,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34, +32,110,97,109,101,61,34,112,110,108,82,111,108,101,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,44,50,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,82,111,108,101,115,78,111,116,73,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,78,111,116,32,77,101,109,98,101,114,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,82,111,108,101,115,73, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,77,101,109,98,101,114,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +76,105,115,116,66,111,120,34,32,110,97,109,101,61,34,108,98,82,111,108, +101,115,78,111,116,73,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +56,54,44,49,50,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +76,66,95,78,69,69,68,69,68,95,83,66,124,119,120,76,66,95,83,79,82,84,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,98,116,110,65,100,100,82,111,108,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,103,116,59,38,103,116,59,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,49,56,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,66,79,84,84,79,77,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116, +110,68,101,108,82,111,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,108,116, +59,38,108,116,59,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +56,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,84, +79,80,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,76,105,115,116,66,111,120,34,32,110,97,109, +101,61,34,108,98,82,111,108,101,115,73,110,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,56,54,44,49,50,51,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,76,66,95,78,69,69,68,69,68,95,83,66,124,119,120,76,66,95, +83,79,82,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,65,100,109,105,110,79,112,116,105,111,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,87,73,84,72,32,65,68,77,73,78,32,79,80,84,73,79,78,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,86,97,114,105,97,98,108,101,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,86,97,114,105,97,98,108,101,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,52,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111, +119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +76,105,115,116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116,86, +97,114,105,97,98,108,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,54,100,60,47,112,111, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76, +67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,48,44,48,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,65,68,68,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,65,100,100,47,67,104,97,110,103,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,112,111,115,62,57,48,44,49,51,50,100,60,47,112,111,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69, +77,79,86,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,53,48,44,49,51,50,100,60, +47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,86,97,114,110,97,109,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,86,97,114,105,97,98,108,101,32,78,97,109,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99, +116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,86, +97,114,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,108,117,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,86,97,114,105,97,98,108,101,32,86,97,108, +117,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,44,49,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,86,97,108,117,101,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,86,97,108,117,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,114, +68,98,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,116,97,98,97, +115,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,86,97,114,68,98,110,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79, +87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_50 = 8283; +static unsigned char xml_res_file_50[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,117,108,101,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,50,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73, +78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,50,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,69,118,101, +110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,69,118,101,110,116,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,82,97,100,105,111,66,111,120,34,32,110,97,109,101,61,34,114, +98,120,69,118,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,83,69,76,69,67,84,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,73,78,83,69,82,84,60,47,105,116,101,109,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +85,80,68,65,84,69,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,68,69,76,69, +84,69,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,105,109,101,110, +115,105,111,110,62,49,60,47,100,105,109,101,110,115,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,82,65,95,83,80,69,67,73,70,89,95,67,79,76,83,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,111,73,110,115,116, +101,97,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,68,111,32,105,110,115,116,101,97,100,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,68,111,73,110,115,116,101,97,100,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,111,110,100,105,116,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,67,111,110,100,105,116,105,111,110,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,116,120,116,67,111,110,100,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,116,97,116,101,109,101,110,116,115,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,83,116,97,116,101,109,101,110,116,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101, +114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99, +116,108,83,81,76,66,111,120,34,32,110,97,109,101,61,34,116,120,116,83,113, +108,66,111,120,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76, +73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79, +87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_51 = 19358; +static unsigned char xml_res_file_51[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,99,104,101,100,117,108,101,34,62,10,32,32,32,32, +60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,50, +48,44,50,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,50,50,53,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +53,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,68,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78, +76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +69,110,97,98,108,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,97,98,108,101,100,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,69,110,97,98,108,101,100,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,83,116,97,114,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,116,97,114, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60, +47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,44,49,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,97,108,101,110,100,97,114,66,111,120,34,32,110,97,109, +101,61,34,99,97,108,83,116,97,114,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,68,80,95,65,76,76,79,87,78,79,78,69,124,119,120,68,80,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,105,109,101,83,112,105,110,67,116,114,108,34,32,110,97,109, +101,61,34,116,105,109,83,116,97,114,116,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,69,110,100,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +69,110,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,44,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,97,108,101,110,100,97,114,66,111,120,34,32, +110,97,109,101,61,34,99,97,108,69,110,100,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,68,80,95,65,76,76,79,87,78,79,78,69,124,119,120,68,80,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,105,109,101,83,112,105,110,67,116,114,108,34,32,110,97,109, +101,61,34,116,105,109,69,110,100,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,121,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108, +34,32,110,97,109,101,61,34,112,110,108,68,97,121,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,50,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,87,101,101,107,100,97,121,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,87, +101,101,107,32,68,97,121,115,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, +109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110, +87,101,101,107,100,97,121,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65, +85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,66,79,84,84,79,77,124,119,120,65,76,73,71,78, +95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,76,105,115,116,66,111,120,34,32,110,97,109,101,61,34, +99,104,107,87,101,101,107,100,97,121,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,45,49,44,55, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,83,117,110,100,97,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,77, +111,110,100,97,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,84,117, +101,115,100,97,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,87,101, +100,110,101,115,100,97,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,84, +104,117,114,115,100,97,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,70, +114,105,100,97,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,83,97,116, +117,114,100,97,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,77,111,110,116,104,100,97,121,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,77,111,110,116,104,32,68,97,121,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,98,116,110,77,111,110,116,104,100,97,121,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,66,79,84,84,79,77,124,119, +120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,76,105,115,116,66,111,120,34,32, +110,97,109,101,61,34,99,104,107,77,111,110,116,104,100,97,121,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,45,49,44,55,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,105,116,101,109,62,49,115,116,60,47,105,116,101,109,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101, +109,62,50,110,100,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,51,114,100, +60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,105,116,101,109,62,52,116,104,60,47,105,116,101, +109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,105,116,101,109,62,53,116,104,60,47,105,116,101,109,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101, +109,62,54,116,104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,55,116,104, +60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,105,116,101,109,62,56,116,104,60,47,105,116,101, +109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,105,116,101,109,62,57,116,104,60,47,105,116,101,109,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101, +109,62,49,48,116,104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,49,49,116, +104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,49,50,116,104,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,49,51,116,104,60,47,105,116,101,109,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +105,116,101,109,62,49,52,116,104,60,47,105,116,101,109,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,49,53,116,104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,49,54,116, +104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,49,55,116,104,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,49,56,116,104,60,47,105,116,101,109,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +105,116,101,109,62,49,57,116,104,60,47,105,116,101,109,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,50,48,116,104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,50,49,115, +116,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,50,50,110,100,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,50,51,114,100,60,47,105,116,101,109,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +105,116,101,109,62,50,52,116,104,60,47,105,116,101,109,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,50,53,116,104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,50,54,116, +104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,50,55,116,104,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,50,56,116,104,60,47,105,116,101,109,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +105,116,101,109,62,50,57,116,104,60,47,105,116,101,109,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,51,48,116,104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,51,49,115, +116,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,76,97,115,116,32,100,97, +121,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,77,111,110,116,104,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,111, +110,116,104,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105, +116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116, +110,77,111,110,116,104,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85, +84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,66,79,84,84,79,77,124,119,120,65,76,73,71,78,95,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,76,105,115,116,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,77,111,110,116,104,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,74,97,110,117,97,114,121,60,47,105,116,101,109,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +70,101,98,114,117,97,114,121,60,47,105,116,101,109,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +77,97,114,99,104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,65,112,114, +105,108,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,77,97,121,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,74,117,110,101,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,74,117,108,121,60,47,105,116,101,109,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,65,117,103,117,115,116,60,47,105,116,101,109,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101, +109,62,83,101,112,116,101,109,98,101,114,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,79,99,116,111,98,101,114,60,47,105,116,101,109,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101, +109,62,78,111,118,101,109,98,101,114,60,47,105,116,101,109,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,68,101,99,101,109,98,101,114,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,84,105,109,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,84,105,109, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,50,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,72,111,117,114,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,111,117,114,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,72,111,117, +114,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,66,79,84,84,79,77,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,76, +105,115,116,66,111,120,34,32,110,97,109,101,61,34,99,104,107,72,111,117, +114,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,45,49,44,49,48,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,77,105, +110,117,116,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,77,105,110,117,116,101,115,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,77,105,110,117, +116,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65, +87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,66,79,84,84,79,77,124,119,120,65,76,73,71,78,95,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +76,105,115,116,66,111,120,34,32,110,97,109,101,61,34,99,104,107,77,105, +110,117,116,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,69,120,99,101,112,116,105,111,110, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,69,120,99,101,112,116,105,111, +110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34,32, +110,97,109,101,61,34,108,115,116,69,120,99,101,112,116,105,111,110,115, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76, +67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,44,51,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,68,97,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,116,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,97,108,101,110,100,97,114,66,111,120,34,32, +110,97,109,101,61,34,99,97,108,69,120,99,101,112,116,105,111,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,68,80,95,65,76,76,79,87,78,79,78,69, +124,119,120,68,80,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,84,105,109,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,84,105,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,105,109,101, +83,112,105,110,67,116,114,108,34,32,110,97,109,101,61,34,116,105,109,69, +120,99,101,112,116,105,111,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,67,104,97,110,103,101,69,120,99,101,112,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,104,97,110,103,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,98,116,110,65,100,100,69,120,99,101,112,116,105,111,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116, +110,82,101,109,111,118,101,69,120,99,101,112,116,105,111,110,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_52 = 5520; +static unsigned char xml_res_file_52[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,99,104,101,109,97,34,62,10,32,32,32,32,60,116, +105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44, +50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, +69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,51,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78, +97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119, +110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_53 = 7618; +static unsigned char xml_res_file_53[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,101,97,114,99,104,79,98,106,101,99,116,34,62,10, +32,32,32,32,60,116,105,116,108,101,62,83,101,97,114,99,104,32,79,98,106, +101,99,116,115,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122, +101,62,51,53,51,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32, +60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79, +71,95,83,84,89,76,69,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, +119,115,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,124,119,120,65,76,76, +124,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,71,114,105,100,66,97,103,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,51,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,51,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,101,108,108,112,111,115,62,48,44,48,60, +47,99,101,108,108,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,101,108,108,115,112,97,110,62,49,44,49,60,47,99,101,108,108,115,112, +97,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,84,79,80,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,80,97,116,116,101,114,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,80,97,116,116,101,114,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,101,108,108,112,111,115,62,48,44,49,60, +47,99,101,108,108,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,101,108,108,115,112,97,110,62,49,44,49,60,47,99,101,108,108,115,112, +97,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115, +62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114, +111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,69,88,80,65,78,68,124,119,120,76,69,70,84,124,119, +120,84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,80,97,116,116,101,114,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, +111,108,116,105,112,62,69,110,116,101,114,32,112,97,114,116,32,111,102, +32,116,104,101,32,111,98,106,101,99,116,39,115,32,97,116,116,114,105,98, +117,116,101,32,121,111,117,39,114,101,32,108,111,111,107,105,110,103,32, +102,111,114,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110, +83,101,97,114,99,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,70,105,110,100,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100, +101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,101,108,108,112,111,115,62,49,44,48,60,47,99,101,108, +108,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,101,108, +108,115,112,97,110,62,49,44,49,60,47,99,101,108,108,115,112,97,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,124,119,120,84,79,80,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,84, +121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,84,121,112,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +101,108,108,112,111,115,62,49,44,49,60,47,99,101,108,108,112,111,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,101,108,108,115,112,97,110, +62,49,44,49,60,47,99,101,108,108,115,112,97,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,66,79,84,84,79,77,124,119, +120,69,88,80,65,78,68,124,119,120,76,69,70,84,124,119,120,84,79,80,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,84,121, +112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,55,48,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,101,108,108,112,111,115, +62,50,44,48,60,47,99,101,108,108,112,111,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,101,108,108,115,112,97,110,62,49,44,49,60,47,99,101, +108,108,115,112,97,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119, +120,84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,99,104,101,109,97,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,101,108,108,112,111,115,62,50,44, +49,60,47,99,101,108,108,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,101,108,108,115,112,97,110,62,49,44,49,60,47,99,101,108,108, +115,112,97,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,66,79,84,84,79,77,124,119,120,69,88,80,65,78,68,124,119, +120,76,69,70,84,124,119,120,84,79,80,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109,97,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76, +89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,50,55,48,44,45,49,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,101,108,108,112,111,115,62,51,44,48,60,47, +99,101,108,108,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,101,108,108,115,112,97,110,62,49,44,49,60,47,99,101,108,108,115,112, +97,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,84,79,80,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,82,101,115,117,108,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,82,101,115,117,108,116,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,101,108,108,112,111,115,62,51,44,49,60, +47,99,101,108,108,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,101,108,108,115,112,97,110,62,49,44,50,60,47,99,101,108,108,115,112, +97,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115, +62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114, +111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101, +61,34,108,99,82,101,115,117,108,116,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,52,48,44,49,53,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82, +84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,101,108,108, +112,111,115,62,48,44,50,60,47,99,101,108,108,112,111,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,101,108,108,115,112,97,110,62,51,44,49, +60,47,99,101,108,108,115,112,97,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,72,79,82,73,90,79,78,84,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,76,69,70,84,124,119,120, +84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,78,97,109,101,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +110,97,109,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47, +99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,76,69,70,84,124,119,120,84,79,80,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,68,101,102,105,110,105,116,105,111,110,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,100,101, +102,105,110,105,116,105,111,110,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101, +100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,76,69,70,84,124,119,120,84,79,80,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,67,111,109,109,101,110,116,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,99,111, +109,109,101,110,116,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48, +60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,108,111,115,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32, +110,97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84, +95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114, +101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_54 = 1165; +static unsigned char xml_res_file_54[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,101,108,101,99,116,67,111,110,110,101,99,116,105, +111,110,34,62,10,32,32,32,32,60,116,105,116,108,101,62,67,111,110,110,101, +99,116,32,116,111,32,83,101,114,118,101,114,60,47,116,105,116,108,101,62, +10,32,32,32,32,60,115,105,122,101,62,50,48,53,44,57,56,100,60,47,115,105, +122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65, +85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84, +73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,60,47,115,116,121, +108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,83,101,114,118,101,114,34,62,10,32,32,32,32,32,32,60,108, +97,98,101,108,62,83,101,114,118,101,114,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,60,112,111,115,62,53,44,55,100,60,47,112,111,115,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,68,97,116,97,98,97,115,101,34,62, +10,32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,116,97,98,97,115,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,53,44, +50,50,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,85,115,101,114,110,97,109,101,34,62,10,32,32,32,32,32,32,60,108,97, +98,101,108,62,85,115,101,114,110,97,109,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,60,112,111,115,62,53,44,51,55,100,60,47,112,111,115, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,82,111,108,101,110, +97,109,101,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,82,111,108, +101,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112, +111,115,62,53,44,53,52,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,60,108,97,98, +101,108,62,38,97,109,112,59,72,101,108,112,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,60,112,111,115,62,50,44,56,48,100,60,47,112,111,115,62, +10,32,32,32,32,32,32,60,115,116,121,108,101,47,62,10,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,60,112,111,115,62,57,55,44,56,48,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,60,115,116,121,108,101,47,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,60,112, +111,115,62,49,53,48,44,56,48,100,60,47,112,111,115,62,10,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10, +60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_55 = 10154; +static unsigned char xml_res_file_55[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,101,113,117,101,110,99,101,34,62,10,32,32,32,32, +60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48, +48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +52,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119,110,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,119,110,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,99,104,101, +109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73, +78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101, +32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,50,52,55, +100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,112,111,115,62,55,48,44,50,52,53,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,73,110,99,114,101,109,101,110, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,73,110,99,114,101,109,101,110,116,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,73,110,99,114,101,109,101,110,116,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +83,116,97,114,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,83,116,97,114,116,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,83,116,97,114,116,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,77,105,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,77,105,110,105,109,117,109,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,77,105,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,77,97,120,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,77,97,120,105,109,117,109,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,77,97,120,34, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,97,99,104,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,99,104, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,97,99,104,101,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,121,99,108,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,121,99,108,101,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,67,121,99,108,101,100,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_56 = 24087; +static unsigned char xml_res_file_56[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,101,114,118,101,114,34,62,10,32,32,32,32,60,116, +105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44, +50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, +69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,68,101,115,99,114,105,112,116,105,111,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,68,101,115,99, +114,105,112,116,105,111,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,72,111,115,116,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,80,111,114,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,111,114, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,80,111,114,116,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +83,101,114,118,105,99,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,114,118,105,99,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,83,101,114,118,105,99,101,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,68,97,116,97,98,97,115,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,105,110, +116,101,110,97,110,99,101,32,68,66,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,68,97,116,97,98, +97,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,85,115,101,114,110,97,109,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +85,115,101,114,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,85,115,101,114, +110,97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,80,97,115,115,119,111,114,100,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,80,97,115,115,119,111,114,100,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,80,97,115,115,119,111,114,100,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84, +69,95,80,65,83,83,87,79,82,68,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,83,116,111,114,101,80,119,100,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +83,116,111,114,101,32,112,97,115,115,119,111,114,100,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,83,116,111,114,101,80,119,100,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101, +100,62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,108,111,117,114,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,108,111,117,114, +80,105,99,107,101,114,34,32,110,97,109,101,61,34,99,111,108,111,117,114, +80,105,99,107,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,71,114, +111,117,112,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,71,114,111,117,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +71,114,111,117,112,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68, +79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,83,83,76,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110, +108,83,83,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,83,76,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,83,76, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,83,83,76,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,83,76,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,83,76, +82,111,111,116,67,101,114,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,114,118,101,114, +32,82,111,111,116,32,67,101,114,116,105,102,105,99,97,116,101,32,70,105, +108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,105,108,101,80,105,99,107,101, +114,67,116,114,108,34,32,110,97,109,101,61,34,112,105,99,107,101,114,83, +83,76,82,111,111,116,67,101,114,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,109,101,115,115,97,103,101,62,83,101, +108,101,99,116,32,83,83,76,32,82,111,111,116,32,67,101,114,116,105,102, +105,99,97,116,101,32,70,105,108,101,60,47,109,101,115,115,97,103,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,105, +108,100,99,97,114,100,62,42,46,99,114,116,60,47,119,105,108,100,99,97,114, +100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84, +82,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +83,83,76,67,114,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,114,118,101,114,32,67, +101,114,116,105,102,105,99,97,116,101,32,82,101,118,111,99,97,116,105,111, +110,32,76,105,115,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,105,108,101,80,105, +99,107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105,99,107, +101,114,83,83,76,67,114,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,109,101,115,115,97,103,101,62,83,101,108,101, +99,116,32,83,83,76,32,67,101,114,116,105,102,105,99,97,116,101,32,82,101, +118,111,99,97,116,105,111,110,32,76,105,115,116,32,70,105,108,101,60,47, +109,101,115,115,97,103,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,119,105,108,100,99,97,114,100,62,42,46,99,114,108, +60,47,119,105,108,100,99,97,114,100,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,70,76,80, +95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,83,76,67,101,114,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,108,105,101,110,116,32,67,101,114,116,105,102,105,99,97,116,101, +32,70,105,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,105,108,101,80,105,99, +107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105,99,107,101, +114,83,83,76,67,101,114,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,109,101,115,115,97,103,101,62,83,101,108,101, +99,116,32,83,83,76,32,99,101,114,116,105,102,105,99,97,116,101,32,102,105, +108,101,60,47,109,101,115,115,97,103,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,119,105,108,100,99,97,114,100,62, +42,46,99,114,116,60,47,119,105,108,100,99,97,114,100,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,83,76,75,101,121,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,108,105,101,110,116,32,75,101,121,32,70,105,108,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,105,108,101,80,105,99,107,101,114,67,116,114, +108,34,32,110,97,109,101,61,34,112,105,99,107,101,114,83,83,76,75,101,121, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +109,101,115,115,97,103,101,62,83,101,108,101,99,116,32,83,83,76,32,107, +101,121,32,102,105,108,101,60,47,109,101,115,115,97,103,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,105,108,100, +99,97,114,100,62,42,46,107,101,121,60,47,119,105,108,100,99,97,114,100, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84,82, +76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,83,76, +67,111,109,112,114,101,115,115,105,111,110,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,83,76, +32,67,111,109,112,114,101,115,115,105,111,110,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,83, +76,67,111,109,112,114,101,115,115,105,111,110,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101, +99,107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98, +111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,83,72,32,84,117,110,110,101,108,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,83,83,72,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,83,72,84,117,110, +110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,85,115,101,32,83,83,72,32,116,117,110, +110,101,108,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,83,72,84,117,110,110, +101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104, +101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,117,110,110,101, +108,72,111,115,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,84,117,110,110,101,108,32,104,111, +115,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,84,117,110,110,101,108,72,111,115,116, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,84,117,110,110,101,108,80,111,114,116,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,84,117,110,110,101,108,32,112,111,114,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,84,117,110,110,101,108,80,111,114,116,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +84,117,110,110,101,108,85,115,101,114,110,97,109,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,85,115,101,114,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,84,117,110, +110,101,108,85,115,101,114,110,97,109,101,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +65,117,116,104,101,110,116,105,99,97,116,105,111,110,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,65,117,116,104,101,110,116,105,99,97,116,105,111,110,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,49,48,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,49,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +114,97,100,105,111,66,116,110,80,97,115,115,119,111,114,100,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,80,97,115,115,119,111,114,100,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100, +105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,114,97,100,105, +111,66,116,110,75,101,121,102,105,108,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,73,100,101,110,116,105,116,121,32,102,105,108,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,100,101,110, +116,105,116,121,70,105,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,100,101,110,116,105, +116,121,32,102,105,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,105,108, +101,80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112, +105,99,107,101,114,73,100,101,110,116,105,116,121,70,105,108,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,101, +115,115,97,103,101,62,83,101,108,101,99,116,32,105,100,101,110,116,105, +116,121,32,102,105,108,101,60,47,109,101,115,115,97,103,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,105,108,100, +99,97,114,100,62,42,60,47,119,105,108,100,99,97,114,100,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,80,117,98,108,105,99,75,101, +121,70,105,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,117,98,108,105,99,32,107,101, +121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,105,108,101,80,105,99,107,101,114,67, +116,114,108,34,32,110,97,109,101,61,34,112,105,99,107,101,114,80,117,98, +108,105,99,75,101,121,70,105,108,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,109,101,115,115,97,103,101,62,83,101, +108,101,99,116,32,112,117,98,108,105,99,32,107,101,121,32,102,105,108,101, +60,47,109,101,115,115,97,103,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,119,105,108,100,99,97,114,100,62,42,46,112, +117,98,60,47,119,105,108,100,99,97,114,100,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,70, +76,80,95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,84,117,110,110,101,108,80,97,115,115, +119,111,114,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,80,97,115,115,119,111,114,100,47,80, +97,115,115,112,104,114,97,115,101,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,84,117,110, +110,101,108,80,97,115,115,119,111,114,100,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +84,69,95,80,65,83,83,87,79,82,68,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,65,100,118,97,110,99,101,100,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,79,112,116,105,111,110,97,108,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,62,52,60,47,103,114,111,119,97,98, +108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,72,111,115,116,65,100,100,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,111,115, +116,32,65,100,100,114,101,115,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,72,111,115, +116,65,100,100,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,84,114,121,67,111,110,110,101, +99,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,67,111,110,110,101,99,116,32,110,111,119,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,84,114,121,67,111,110,110,101,99,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,82,101,115,116,111,114,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,82,101,115,116,111,114,101,32,101,110,118,63,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,82,101,115,116,111,114,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +82,111,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,111,108,101,110,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,82,111,108,101,110,97,109,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,68,98,82,101,115,116,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68, +66,32,114,101,115,116,114,105,99,116,105,111,110,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,68,98,82,101,115,116,114,105,99,116,105,111,110,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,83,101,114,118,105,99,101,73,68, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,83,101,114,118,105,99,101,32,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,116,120,116,83,101,114,118,105,99,101,73,68,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97, +116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_57 = 10963; +static unsigned char xml_res_file_57[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,116,101,112,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,55,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,73,68,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,73,68,34, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,69,110,97,98,108,101,100,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69, +110,97,98,108,101,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,69,110,97,98,108,101,100, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107, +101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,110,110,84,121,112,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,67,111,110,110,101,99,116,105,111,110,32,84,121,112, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105, +111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,114,98,76,111,99, +97,108,67,111,110,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82,66,95, +71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +76,111,99,97,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,101,110,97,98,108,101, +62,48,60,47,101,110,97,98,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,114,98,82,101,109,111,116, +101,67,111,110,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,116,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,101,110,97,98,108,101,62,48,60,47,101, +110,97,98,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +68,97,116,97,98,97,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,116,97,98,97,115, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,68,97,116,97,98, +97,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87, +78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,101,110,97,98,108,101,62,48,60,47,101,110,97, +98,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111, +114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,110,110,83,116,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,111,110,110,101,99,116,105,111,110,32,83,116,114,105,110, +103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,84,79,80,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,67,111,110,110,83,116,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,101,110,97, +98,108,101,62,48,60,47,101,110,97,98,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,83,101,108,68,97,116,97,98,97,115,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,101,110,97,98,108, +101,62,48,60,47,101,110,97,98,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,53, +44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,111, +120,34,32,110,97,109,101,61,34,114,98,120,75,105,110,100,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,83,81,76,60,47,105,116,101,109,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105, +116,101,109,62,66,97,116,99,104,60,47,105,116,101,109,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101, +110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,101,108,101,99,116,105,111,110,62,48,60,47,115,101,108,101,99, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,75,105,110,100,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100, +105,109,101,110,115,105,111,110,62,49,60,47,100,105,109,101,110,115,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,82,65,95,83,80,69,67,73,70,89,95,67, +79,76,83,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,111,120,34, +32,110,97,109,101,61,34,114,98,120,79,110,69,114,114,111,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,110,32,101,114,114,111,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,105,111,110,62,48,60,47,115,101,108,101,99,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,105,116,101,109,62,70,97,105,108,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,83,117,99,99,101,101,100,60,47,105,116,101,109,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +105,116,101,109,62,73,103,110,111,114,101,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,100,105,109,101,110,115,105,111,110,62,49,60,47,100,105,109, +101,110,115,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82,65,95,83,80,69,67, +73,70,89,95,67,79,76,83,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111, +109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67, +111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76, +84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,83,113,108,66,111,120,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101, +61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69, +71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_58 = 7474; +static unsigned char xml_res_file_58[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,121,110,111,110,121,109,34,62,10,32,32,32,32,60, +116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48, +44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,50,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67, +111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76, +84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,84,97,114,103,101,116,84,121,112,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,84,97,114,103,101,116,32,116,121,112,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,84,97,114,103,101,116,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,84,97,114,103,101,116,83,99,104,101,109,97,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,84,97,114,103,101,116,32,115,99,104,101,109,97,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,84,97,114,103,101,116,83,99,104,101,109,97,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,84,97,114,103,101,116,79,98,106, +101,99,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,84,97,114,103,101,116,32,111,98,106,101, +99,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,84,97,114,103,101,116,79,98,106,101,99,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,53,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97, +116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_59 = 40708; +static unsigned char xml_res_file_59[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,97,98,108,101,34,62,10,32,32,32,32,60,116,105, +116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,53,48,44,50,54, +53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62, +119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124, +119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78, +85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121, +108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101, +61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,51,52,54,44,50,52,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100, +62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,52,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119, +110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,99,104,101, +109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,83,99,104,101,109,97,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101, +102,105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108, +68,101,102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,97,98,108,101,115, +112,97,99,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,84,97,98,108,101,115,112,97,99,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,84,97,98,108,101,115,112,97,99,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,79,102,84,121,112,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,102,32,116,121,112,101,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,102,84,121, +112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,70,105,108,108,70,97,99,116,111,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,70,105,108,108,32,70,97,99,116,111,114,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70, +105,108,108,70,97,99,116,111,114,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,72,97,115, +79,105,100,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,72,97,115,32,79,73,68,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,72,97,115,79,105,100,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101, +99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,85,110,108,111,103,103,101,100,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,85,110,108,111,103,103,101,100,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,85,110,108, +111,103,103,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48, +60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +73,110,104,101,114,105,116,115,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,73, +110,104,101,114,105,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115, +116,66,111,120,34,32,110,97,109,101,61,34,108,98,84,97,98,108,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,84,97,98,108, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,65,100, +100,84,97,98,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,84,97,98,108, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,76,105,107,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,76,105,107,101,82,101,108,97,116,105,111,110,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,76,105,107,101,82,101,108,97,116,105,111,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82, +101,108,97,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,76,105,107,101,82,101, +108,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,73,110,99,108,117,100,105,110,103,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110, +99,108,117,100,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,73,110,99,108,117, +100,105,110,103,68,101,102,97,117,108,116,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101, +102,97,117,108,116,32,118,97,108,117,101,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104, +101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,73,110,99,108,117, +100,105,110,103,67,111,110,115,116,114,97,105,110,116,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,111,110,115,116,114,97,105,110,116,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105, +122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,73,110,99,108, +117,100,105,110,103,73,110,100,101,120,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73, +110,100,101,120,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,73,110,99,108,117,100,105,110,103, +83,116,111,114,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,116,111,114,97,103,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99, +107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99, +104,107,73,110,99,108,117,100,105,110,103,67,111,109,109,101,110,116,115, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,67,111,109,109,101,110,116,115,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,67,111,108,117,109,110,115,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,67,111,108,117,109,110,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101, +114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116, +67,111,108,117,109,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69, +80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,67,104,97,110,103,101,67,111,108,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,104,97,110,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110, +65,100,100,67,111,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,67,111,108,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,53,48,44,45,49,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67, +111,110,115,116,114,97,105,110,116,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,67,111,110,115,116,114,97,105,110,116,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98, +108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61,34,108, +115,116,67,111,110,115,116,114,97,105,110,116,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50, +55,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76, +67,95,82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69, +76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79, +87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,53,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98, +111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,111,110,115,116,114, +84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,65,100,100,67,111,110,115,116,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,82,101,109,111,118,101,67,111,110,115,116,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79,87,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,65,117,116,111,45,118,97,99,117,117,109,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,86,97,99,117,117,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101, +108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98, +111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,84,97,98,108,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,67,117,115,116,111,109,86,97,99,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,117,115,116,111,109,32,97,117,116,111,45,118,97,99,117, +117,109,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44, +51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,99,69,110,97,98, +108,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,97,98,108,101,100,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,86,97,99,69,110,97,98,108,101,100,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,117,114,114,101, +110,116,32,118,97,108,117,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,66,97,115, +101,86,97,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,67,85,85,77,32,98,97, +115,101,32,116,104,114,101,115,104,111,108,100,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116, +66,97,115,101,86,97,99,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,66,97,115,101,86,97,99,67,117, +114,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,66,97,115,101,65,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,65,78,65,76,89,90,69,32,98,97,115,101, +32,116,104,114,101,115,104,111,108,100,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,66,97,115, +101,65,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,66,97,115,101,65,110,67,117,114,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,70,97,99,116,111,114,86,97,99,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,86,65,67,85,85,77,32,115,99,97,108,101,32,102,97, +99,116,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,70,97,99,116,111,114,86,97,99, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,70,97,99,116,111,114,86,97,99,67,117,114,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,70,97,99,116,111,114,65,110,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,65,78,65,76,89,90,69,32,115,99,97,108,101,32,102,97,99, +116,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,70,97,99,116,111,114,65,110, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,70,97,99,116,111,114,65,110,67,117,114,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,86,97,99,68,101,108,97,121,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,86,65,67,85,85,77,32,99,111,115,116,32,100,101,108,97,121,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,116,120,116,86,97,99,68,101,108,97,121,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,99, +68,101,108,97,121,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +86,97,99,76,105,109,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,67,85, +85,77,32,99,111,115,116,32,108,105,109,105,116,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116, +86,97,99,76,105,109,105,116,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,86,97,99,76,105,109,105,116, +67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,114,101,101, +122,101,77,105,110,65,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,82,69, +69,90,69,32,109,105,110,105,109,117,109,32,97,103,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,70,114,101,101,122,101,77,105,110,65,103,101,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,114, +101,101,122,101,77,105,110,65,103,101,67,117,114,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,70,114,101,101,122,101,77,97,120,65,103,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,70,82,69,69,90,69,32,109,97,120,105,109,117, +109,32,97,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,114,101, +101,122,101,77,97,120,65,103,101,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,114, +101,101,122,101,77,97,120,65,103,101,67,117,114,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,70,114,101,101,122,101,84,97, +98,108,101,65,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,82,69,69,90,69, +32,116,97,98,108,101,32,97,103,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +116,120,116,70,114,101,101,122,101,84,97,98,108,101,65,103,101,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,70,114,101,101,122,101,84,97,98,108,101,65, +103,101,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,32,110,97,109,101,61,34,110, +98,112,84,111,97,115,116,86,97,99,117,117,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,111,97,115,116, +32,116,97,98,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,67,117,115,116, +111,109,84,111,97,115,116,86,97,99,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67, +117,115,116,111,109,32,97,117,116,111,45,118,97,99,117,117,109,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,84,111,97,115,116,86,97,99,69,110,97,98,108,101, +100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,69,110,97,98,108,101,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,84,111,97,115,116,86,97,99,69,110,97,98,108,101,100, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,117,114, +114,101,110,116,32,118,97,108,117,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,66,97,115, +101,84,111,97,115,116,86,97,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,67, +85,85,77,32,98,97,115,101,32,116,104,114,101,115,104,111,108,100,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,66,97,115,101,84,111,97,115,116,86,97,99,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,66,97,115,101,84,111,97,115,116,86,97,99,67,117,114,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,70,97,99,116,111,114,84,111,97,115,116,86, +97,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,86,65,67,85,85,77,32,115,99,97,108, +101,32,102,97,99,116,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,97,99,116, +111,114,84,111,97,115,116,86,97,99,34,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,97,99,116,111,114, +84,111,97,115,116,86,97,99,67,117,114,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,84,111,97,115,116,86,97,99,68,101,108,97,121,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,65,67,85,85,77,32,99,111,115,116,32,100,101,108,97, +121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,84,111,97,115,116,86,97,99,68,101,108,97,121, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,84,111,97,115,116,86,97,99,68,101,108,97,121,67,117,114,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,86,97,99,76, +105,109,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,67,85,85,77,32,99, +111,115,116,32,108,105,109,105,116,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,84,111,97, +115,116,86,97,99,76,105,109,105,116,34,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,86, +97,99,76,105,109,105,116,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,84,111,97,115,116,70,114,101,101,122,101,77,105,110,65,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,70,82,69,69,90,69,32,109,105,110,105,109,117, +109,32,97,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,84,111,97,115,116,70,114, +101,101,122,101,77,105,110,65,103,101,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,70, +114,101,101,122,101,77,105,110,65,103,101,67,117,114,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,84,111,97,115,116,70,114,101,101,122,101,77,97, +120,65,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,82,69,69,90,69,32,109, +97,120,105,109,117,109,32,97,103,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +116,120,116,84,111,97,115,116,70,114,101,101,122,101,77,97,120,65,103,101, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,70,114,101,101,122, +101,77,97,120,65,103,101,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,84,111,97,115,116,70,114,101,101,122,101,84, +97,98,108,101,65,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,82,69,69,90, +69,32,116,97,98,108,101,32,97,103,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +116,120,116,84,111,97,115,116,70,114,101,101,122,101,84,97,98,108,101,65, +103,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,70,114,101, +101,122,101,84,97,98,108,101,65,103,101,67,117,114,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97, +116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_60 = 10511; +static unsigned char xml_res_file_60[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,97,98,108,101,115,112,97,99,101,34,62,10,32,32, +32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62, +51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84, +69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,51,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62, +53,44,55,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,116,120,116,78,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,55,48,44, +53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110, +101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,51,55,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62, +55,48,44,51,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111, +109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,53,50,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112, +111,115,62,55,48,44,53,48,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,76,111,99,97,116,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,76,111,99,97,116,105,111,110,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112, +111,115,62,53,44,50,50,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,76,111,99,97,116,105,111, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,112,111,115,62,55,48,44,50,48,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98, +111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,86,97,114,105,97,98,108,101,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,86,97,114,105,97,98,108,101,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,52,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61, +34,108,115,116,86,97,114,105,97,98,108,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,54, +100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82, +84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79, +87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,112,111,115,62,48,44,48,100,60,47,112,111,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,65,68, +68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,65,100,100,47,67,104,97,110,103,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,77,79,86,69,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,86,97,114,110,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,97,114,105,97,98,108,101,32,78,97,109,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,86,97,114,110,97,109,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80, +68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,114,105,97,98, +108,101,32,86,97,108,117,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,44,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,86,97,108,117,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,86,97,108,117,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82, +79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79,87,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_61 = 12794; +static unsigned char xml_res_file_61[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,101,120,116,83,101,97,114,99,104,67,111,110,102, +105,103,117,114,97,116,105,111,110,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,52,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119, +110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,99,104,101,109,97,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,83,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109, +97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82, +69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53, +44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95, +77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,80,97,114,115,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80, +97,114,115,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,80,97,114,115,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,112,121,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,111,112,121,32,67,111,110,102,105,103,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,67,111,112,121,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,84,111,107,101,110,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61, +34,112,110,108,84,111,107,101,110,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61, +34,108,115,116,84,111,107,101,110,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,55,48,44,49,53,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82,84, +124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,56,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,84,111,107,101,110,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84, +111,107,101,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,84,111,107,101,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,68,105,99,116,105,111,110,97,114,121,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,105,99,116,105,111,110,97,114,105,101,115,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,68,105,99,116,105,111,110,97,114,121,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,49,49,49,44,45,49,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,111,105,99,101,34,32,110,97,109,101,61,34,99,98,68,105,99,116,105, +111,110,97,114,121,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,54,44,45, +49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,66,79,84,84,79,77,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,72,79,82,73,90,79,78,84,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69, +77,79,86,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,51,44,53,56,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +65,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,47,67,104,97,110,103, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,51,44,55,56,100,60, +47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,44,50,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,55,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,50,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97, +109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102, +97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,124,119,120,71,82,79,87,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117, +115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117, +115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79,87,124,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10, +60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_62 = 11304; +static unsigned char xml_res_file_62[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,101,120,116,83,101,97,114,99,104,68,105,99,116, +105,111,110,97,114,121,34,62,10,32,32,32,32,60,116,105,116,108,101,47,62, +10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53,100,60,47,115, +105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70, +65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80, +84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82, +69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101, +114,111,119,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78, +111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47, +115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,52,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110, +101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,99,104,101,109,97,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,83,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109, +97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82, +69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53, +44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95, +77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,84,101,109,112,108,97,116,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,84,101,109,112,108,97,116,101,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,84,101,109,112, +108,97,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44, +45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,112,116,105,111,110,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61, +34,108,115,116,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,55,48,44,49,53, +100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82, +84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,56,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,112,116,105,111,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,112,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116, +79,112,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,108, +117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,108,117,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,66,79,84,84,79,77,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,72,79,82,73,90,79,78,84,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,77,79,86, +69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,112,111,115,62,49,51,44,53,56,100,60,47,112,111,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119, +120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,65,68,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,65,100,100,47,67,104,97,110,103,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,112,111,115,62,49,51,44,55,56,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,50,44,50,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,55, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,50,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,124,119,120,71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114, +34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,71,82,79,87,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114, +101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_63 = 10694; +static unsigned char xml_res_file_63[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,101,120,116,83,101,97,114,99,104,80,97,114,115, +101,114,34,62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32, +60,115,105,122,101,62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62, +10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95, +68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124, +119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69, +95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116, +101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98, +111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101, +99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +80,114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,52,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44, +45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,83,99,104,101,109,97,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,83,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109,97, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76, +84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,83,116,97,114,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,116,97,114,116,32, +70,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,116,97,114,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +71,101,116,84,111,107,101,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,71,101,116,116,111,107, +101,110,32,70,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,71,101, +116,84,111,107,101,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,69,110,100,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,100,32,70, +117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,69,110,100,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,101,120,116,121,112, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,76,101,120,116,121,112,101,115,32,70,117, +110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,76,101,120,116,121,112,101, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68, +79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +72,101,97,100,108,105,110,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97,100,108,105, +110,101,32,70,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,72,101, +97,100,108,105,110,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,44,50,100,60,47,115,105, +122,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,55,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44, +51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,71,82,79,87,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110, +107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82, +79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_64 = 8482; +static unsigned char xml_res_file_64[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,101,120,116,83,101,97,114,99,104,84,101,109,112, +108,97,116,101,34,62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32, +32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53,100,60,47,115,105,122, +101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85, +76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73, +79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83, +73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99, +111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111, +119,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111, +116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101, +98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108, +101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,80,114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,52,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44, +45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,83,99,104,101,109,97,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,83,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109,97, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76, +84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,73,110,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,105,116,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,73,110,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,76,101,120,105,122,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76, +101,120,105,122,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,76,101,120,105,122,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119, +120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,50,44,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,55,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,50,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44, +51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44, +51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,71,82, +79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101, +61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69, +71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101, +62,10}; + +static size_t xml_res_size_65 = 16584; +static unsigned char xml_res_file_65[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,114,105,103,103,101,114,34,62,10,32,32,32,32,60, +116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48, +44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +50,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69, +95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +45,49,44,52,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101, +32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,99,98,67,108,117,115,116,101,114,83, +101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,56,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,82,111,119,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,111,119,32,116,114, +105,103,103,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,82,111,119,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,111,110,115,116,114,97,105,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,111,110,115,116,114,97,105,110,116,32,116,114,105,103, +103,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34, +32,110,97,109,101,61,34,99,104,107,67,111,110,115,116,114,97,105,110,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107, +101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,68,101,102,101,114,114,97,98, +108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,68,101,102,101,114,114,97,98,108,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,68,101,102,101,114,114,97,98,108,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,68,101,102,101,114,114,101,100,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,68,101,102,101,114,114,101,100,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,68,101,102,101,114,114,101,100,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,70,117,110,99,116,105,111,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +84,114,105,103,103,101,114,32,102,117,110,99,116,105,111,110,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,70,117,110,99,116,105,111,110,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,65,114,103,117,109,101, +110,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,65,114,103,117,109,101,110,116,115,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,65,114,103,117,109,101,110,116,115,34,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,70,105,114,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,114,101,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,111,120,34,32,110, +97,109,101,61,34,114,100,98,70,105,114,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,105,116,101,109,62,66,69,70,79,82,69,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,65,70,84,69,82,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,73,78,83,84,69,65,68,32,79,70,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,101,108,101,99,116,105,111,110,62,48,60,47, +115,101,108,101,99,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,100,105,109,101,110,115,105,111,110,62, +49,60,47,100,105,109,101,110,115,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +82,65,95,83,80,69,67,73,70,89,95,82,79,87,83,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,69,118,101,110,116,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,69,118,101,110,116,115,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,44,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,73,110,115,101,114,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,73,78,83,69,82,84,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,85,112, +100,97,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,80,68,65,84,69,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,68,101,108,101,116,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,69,76,69,84,69,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,84,114,117,110,99, +97,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,82,85,78,67,65,84,69,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,87,104,101,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,87,104,101,110,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,87,104,101,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,45,49,44,52,48,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,67,111,108,117,109,110,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, +115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34, +32,110,97,109,101,61,34,108,115,116,67,111,108,117,109,110,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95, +83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47, +103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,108,117,109,110,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,111,108,117,109,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,65,100,100,67,111,108, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,67,111,108,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,53,48,44,45,49,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111, +116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,66,111,100,121,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,66,111,100,121,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,83,81,76,66,111,120,34,32,110,97,109,101,61,34,116,120,116, +66,111,100,121,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76, +73,78,69,124,119,120,83,85,78,75,69,78,95,66,79,82,68,69,82,124,119,120, +84,69,95,82,73,67,72,50,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80, +124,119,120,82,73,71,72,84,124,119,120,71,82,79,87,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116, +117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99, +116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_66 = 43189; +static unsigned char xml_res_file_66[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,121,112,101,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,52,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119, +110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,99,104,101, +109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,83,99,104,101,109,97,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111, +116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,82,97,100,105,111,66,111,120,34,32,110,97,109,101,61,34,114, +100,98,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105, +116,101,109,62,67,111,109,112,111,115,105,116,101,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,69,110,117,109,101,114,97,116,105,111,110,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,69,120,116,101,114,110,97,108,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,82,97,110,103,101,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,100,105,109,101,110,115,105,111,110,62,49,60,47, +100,105,109,101,110,115,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82,65,95, +83,80,69,67,73,70,89,95,67,79,76,83,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,44,49,44,50, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,67,111, +109,112,111,115,105,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47, +103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115,116, +67,116,114,108,34,32,110,97,109,101,61,34,108,115,116,77,101,109,98,101, +114,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69, +80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,77,101,109,98,101,114,110,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,109,98,101,114,32, +110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120, +116,77,101,109,98,101,114,110,97,109,101,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +68,97,116,97,116,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,97,116,97,32,116,121,112,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,68,97,116,97,116,121,112,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +115,116,76,101,110,103,116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,76,101,110,103,116,104,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,76,101,110,103,116,104,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,80,114,101,99,105,115,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,80,114,101,99,105,115,105,111,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108, +34,32,110,97,109,101,61,34,116,120,116,80,114,101,99,105,115,105,111,110, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,67,111,108,108,97,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,108,108,97,116,105, +111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,111, +108,108,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,77,101,109,98,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,65, +76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,65,100,100,77,101,109, +98,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,65,76, +73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,67,104,97,110,103,101, +77,101,109,98,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,104,97,110,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115, +62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110, +108,68,101,102,105,110,105,116,105,111,110,69,110,117,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47, +103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61, +34,108,115,116,76,97,98,101,108,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53, +44,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,48,48,44, +49,53,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71, +76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,97,98, +101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76,97,98,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84, +101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,76,97, +98,101,108,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,44,50,100,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +98,116,110,65,100,100,66,101,102,111,114,101,76,97,98,101,108,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,32,98,101,102,111, +114,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,98,116,110,65,100,100,65,102,116,101,114,76,97,98,101,108,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,32,97,102,116,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110, +82,101,109,111,118,101,76,97,98,101,108,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105, +116,105,111,110,69,120,116,101,114,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78, +111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,68,101,102, +105,110,105,116,105,111,110,69,120,116,101,114,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116, +101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,82,101,113,117,105,114,101,100,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, +97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,73,110,112,117,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,73,110,112,117,116,32,102,117,110,99,116,105,111,110, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,73,110,112,117,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79, +78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,79,117,116,112,117,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,117,116, +112,117,116,32,102,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,117,116, +112,117,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,112,116,105,111,110,97,108,32,49,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,82,101,99,101,105,118,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,99,101,105,118,101, +32,102,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,82,101,99,101,105, +118,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,83,101,110,100,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,83,101,110,100,32,102,117,110,99,116,105, +111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,99,98,83,101,110,100,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65, +68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,84,121,112,109,111,100,105,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84, +121,112,109,111,100,32,105,110,32,102,117,110,99,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +84,121,112,109,111,100,105,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,84,121,112,109,111,100,111,117,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121, +112,109,111,100,32,111,117,116,32,102,117,110,99,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +84,121,112,109,111,100,111,117,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,73,110,116,76,101,110,103,116,104, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73, +110,116,101,114,110,97,108,32,108,101,110,103,116,104,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,73,110,116,76,101,110,103,116,104,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,86,97,114,105,97,98,108,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,114,105,97,98,108, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,86,97,114,105,97,98,108,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,68,101,102,97,117,108,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101, +102,97,117,108,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,68,101,102,97,117,108,116,34, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,65,110,97,108,121,122,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,110, +97,108,121,122,101,32,102,117,110,99,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,65,110,97,108,121, +122,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,67,97,116,101,103,111,114,121,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,116,101,103,111,114, +121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,67,97,116,101,103,111,114,121,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,65,114,114,97,121,32, +116,121,112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,105,116,101,109,62,66,111,111,108,101,97,110,32,116, +121,112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,105,116,101,109,62,67,111,109,112,111,115,105,116,101, +32,116,121,112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,105,116,101,109,62,68,97,116,101,47,116,105,109, +101,32,116,121,112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,69,110,117,109,32,116,121, +112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,105,116,101,109,62,71,101,111,109,101,116,114,105,99,32,116, +121,112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,105,116,101,109,62,78,101,116,119,111,114,107,32,97,100, +100,114,101,115,115,32,116,121,112,101,115,60,47,105,116,101,109,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,78,117, +109,101,114,105,99,32,116,121,112,101,115,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,80,115,101, +117,100,111,45,116,121,112,101,115,60,47,105,116,101,109,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,83,116,114,105,110, +103,32,116,121,112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,84,105,109,101,115,112,97, +110,32,116,121,112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,85,115,101,114,45,100,101, +102,105,110,101,100,32,116,121,112,101,115,60,47,105,116,101,109,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,66,105, +116,45,115,116,114,105,110,103,32,116,121,112,101,115,60,47,105,116,101, +109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +117,110,107,110,111,119,110,32,116,121,112,101,115,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,80,114,101,102,101,114,101,100,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,101,102,101,114,101,100,63, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,80,114,101,102,101,114,101,100,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107, +112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,116, +105,111,110,97,108,32,50,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,69,108, +101,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,69,108,101,109,101,110,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,69,108, +101,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,68,101,108,105,109,105,116,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,108,105, +109,105,116,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,68,101,108,105,109,105,116,101, +114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,65,108,105,103,110,109,101,110, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +65,108,105,103,110,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,65,108,105,103,110, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,99,104,97,114,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,105,110,116,50,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,105,110,116,52,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,100,111,117,98,108,101,60, +47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111, +110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,83,116,111,114,97,103,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,116,111,114,97,103,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,83,116,111,114,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,101,108,101,99,116,105,111,110,62,48,60,47, +115,101,108,101,99,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,80,97,115,115,101,100,66,121,86,97,108, +117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,80,97,115,115,101,100,32,98,121,32,118,97,108,117,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,66,121,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,111,108,108,97,116,97,98,108, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,108,108,97,116,97,98,108,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,67,111,108, +108,97,116,97,98,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105, +116,105,111,110,82,97,110,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,83,117,98,116,121,112,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,83,117,98,116,121,112,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,99,98,83,117,98,116,121,112,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,117,98,116,121,112, +101,79,112,99,108,97,115,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +117,98,116,121,112,101,32,111,112,101,114,97,116,111,114,32,99,108,97,115, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,117,98,116, +121,112,101,79,112,99,108,97,115,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,82,110,103,67,111,108,108,97,116,105,111,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,108,108,97,116,105,111,110,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,82,110,103,67,111,108, +108,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,97,110,111,110,105,99,97,108,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,97,110,111,110,105,99,97,108,32,102,117,110,99,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,97,110,111,110,105, +99,97,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,117, +98,116,121,112,101,68,105,102,102,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +83,117,98,116,121,112,101,32,100,105,102,102,32,102,117,110,99,116,105, +111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,117,98, +116,121,112,101,68,105,102,102,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101, +61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69, +71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_67 = 15725; +static unsigned char xml_res_file_67[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,85,115,101,114,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,54,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115, +101,114,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,114,32,73,68, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,73,68,34,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,80,97,115, +115,119,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,80,97,115,115,119,111,114,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,80,97,115,115,119,100,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84, +69,95,80,65,83,83,87,79,82,68,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,82,101,80,97,115,115,119,100,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +80,97,115,115,119,111,114,100,32,40,97,103,97,105,110,41,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,82,101,80,97,115,115,119,100,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,80,65,83,83,87,79,82,68,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,86,97,108,105,100,85,110,116,105,108,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,65,99,99,111,117,110,116,32,101,120,112,105,114,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,97,108,101,110,100,97,114,66,111,120,34,32,110,97,109,101,61,34,100, +97,116,86,97,108,105,100,85,110,116,105,108,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,80,95,65,76,76,79,87,78,79,78,69,124,119,120,68,80,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,105,109,101,83,112,105,110,67,116,114,108,34,32,110,97, +109,101,61,34,116,105,109,86,97,108,105,100,85,110,116,105,108,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,108,117,115,116, +101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68, +79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,82,111,108,101,32,112,114,105,118,105,108,101,103,101,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,82,111,108,101,115,80,114,105,118,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +67,114,101,97,116,101,68,66,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,114,32,99,97, +110,32,99,114,101,97,116,101,32,100,97,116,97,98,97,115,101,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101, +100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,67,114,101,97,116,101,85,115,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,83,117,112,101,114,117,115,101,114,32,40,99,97,110,32,99,114,101, +97,116,101,32,117,115,101,114,115,41,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,71,114,111,117,112,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,71,114,111,117,112,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,49,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,44,50,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,71,114, +111,117,112,115,78,111,116,73,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,111,116,32,77, +101,109,98,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,71,114,111,117,112,115,73,110,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,101, +109,98,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,66,111,120, +34,32,110,97,109,101,61,34,108,98,71,114,111,117,112,115,78,111,116,73, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,54,44,49,50,51,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,66,95,78,69,69,68,69, +68,95,83,66,124,119,120,76,66,95,83,79,82,84,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116, +110,65,100,100,71,114,111,117,112,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,103, +116,59,38,103,116,59,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +49,56,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,66,79,84,84,79,77,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,68,101,108, +71,114,111,117,112,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,108,116,59,38,108, +116,59,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,56,44,45,49, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,84,79,80,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,76,105,115,116,66,111,120,34,32,110,97,109,101,61,34,108, +98,71,114,111,117,112,115,73,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,56,54,44,49,50,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,76,66,95,78,69,69,68,69,68,95,83,66,124,119,120,76,66,95,83,79, +82,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98, +111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,86,97,114,105,97,98,108,101,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,86,97,114,105,97,98,108,101,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,52,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61, +34,108,115,116,86,97,114,105,97,98,108,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,54, +100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82, +84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79, +87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,112,111,115,62,48,44,48,100,60,47,112,111,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,65,68, +68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,65,100,100,47,67,104,97,110,103,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,57,48,44,49,51,50,100,60, +47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,82,69,77,79,86,69,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +82,101,109,111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62, +49,53,48,44,49,51,50,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,114,110, +97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,114,105,97,98,108,101, +32,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,86,97,114,110,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,86,97,108,117,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,86,97,114,105,97,98,108,101,32,86,97,108,117,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,44,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,86, +97,108,117,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61, +34,99,104,107,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116, +117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99, +116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_68 = 8224; +static unsigned char xml_res_file_68[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,85,115,101,114,77,97,112,112,105,110,103,34,62,10, +32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122, +101,62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32, +60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79, +71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89, +83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68, +69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111, +107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50, +52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60, +115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111, +112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114, +111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,49,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,85,115,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,114,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,85,115,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,116,105,111,110,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108, +34,32,110,97,109,101,61,34,112,110,108,79,112,116,105,111,110,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114, +108,34,32,110,97,109,101,61,34,108,115,116,79,112,116,105,111,110,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112, +111,115,62,55,48,44,49,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95, +83,69,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,56, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,112,116,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,79,112,116,105,111,110,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,79,112,116,105,111,110,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,108, +117,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,86,97,108,117,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,66,79,84, +84,79,77,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,72,79,82,73, +90,79,78,84,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,82,69,77,79,86,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109, +111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,51,44,53, +56,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,65,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100, +47,67,104,97,110,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62, +49,51,44,55,56,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,44,50,100,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,55,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,71,82,79,87,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110, +107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82, +79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_69 = 36699; +static unsigned char xml_res_file_69[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,86,105,101,119,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,52,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119, +110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,99,104,101, +109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,83,99,104,101,109,97,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,50,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,101,99, +117,114,105,116,121,66,97,114,114,105,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101, +99,117,114,105,116,121,32,66,97,114,114,105,101,114,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,83,101,99,117,114,105,116,121,66,97,114,114,105,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,104,101,99,107,79,112,116,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,87,105,116,104,32,67,104,101,99,107,32,79,112,116, +105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,99,98,67,104,101,99,107,79,112,116,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,78,111,60,47,105,116,101, +109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,105,116,101,109,62,76,111,99,97,108,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,67,97,115,99,97,100,101,100,60,47,105,116,101,109,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,68,101,102,105,110,105,116,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,99,116,108,83,81,76,66,111,120,34,32,110,97,109,101,61,34, +116,120,116,83,113,108,66,111,120,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95, +77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82, +79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,77,97,116,101,114,105,97,108,105,122,97,116,105,111,110, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108, +34,32,110,97,109,101,61,34,112,110,108,77,97,116,101,114,105,97,108,105, +122,101,100,86,105,101,119,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111, +119,115,62,49,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,77,97,116,101,114,105,97,108,105,122, +101,100,86,105,101,119,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,116,101, +114,105,97,108,105,122,101,100,32,86,105,101,119,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +77,97,116,101,114,105,97,108,105,122,101,100,86,105,101,119,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99, +104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,50,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,49,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111, +111,107,34,32,110,97,109,101,61,34,110,98,86,97,99,117,117,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,79,112,116,105,111,110,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114, +111,119,115,62,51,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,84,97,98,108,101,83,112,97,99,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,84,97,98,108,101,115,112,97,99,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,111,84,97,98,108,101,115,112,97,99,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,52, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,52,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,70,105,108,108,70,97,99,116,111,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,70,105,108,108,32,70,97,99,116,111,114,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,105,108,108, +70,97,99,116,111,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,77,97,116,86,105,101, +119,87,105,116,104,68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,87,105,116,104,32,68,97,116,97,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,77,97,116,86,105,101,119,87,105,116, +104,68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,62,51,60,47,103,114,111,119,97,98, +108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,84,97,98,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,52,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,52,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44, +51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,67,117,115,116,111,109,86,97,99,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,67,117,115,116,111,109,32,97,117,116,111,45, +118,97,99,117,117,109,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,99,69,110, +97,98,108,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69, +110,97,98,108,101,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,86,97,99,69,110,97,98,108,101,100,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,67,117,114,114,101,110,116,32,118,97,108,117, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,66, +97,115,101,86,97,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +86,65,67,85,85,77,32,98,97,115,101,32,116,104,114,101,115,104,111,108,100, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,66,97,115, +101,86,97,99,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,66,97,115,101,86,97,99,67,117, +114,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,66,97,115,101,65,110,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,65,78,65,76,89,90,69,32,98,97,115,101, +32,116,104,114,101,115,104,111,108,100,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,116,120,116,66,97,115,101,65,110,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,66,97,115,101,65,110,67,117,114,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70, +97,99,116,111,114,86,97,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,86,65,67,85,85,77,32,115,99,97,108,101,32,102,97,99,116,111,114, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,97,99, +116,111,114,86,97,99,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,97,99,116,111,114, +86,97,99,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,70,97,99,116,111,114,65,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,78,65,76,89,90,69,32,115, +99,97,108,101,32,102,97,99,116,111,114,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,116,120,116,70,97,99,116,111,114,65,110,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,70,97,99,116,111,114,65,110,67,117,114,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,86,97,99,68,101,108,97,121,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,65,67,85,85,77,32,99,111,115,116,32,100,101,108,97, +121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84, +101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,86,97, +99,68,101,108,97,121,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,99,68,101,108,97, +121,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,86,97,99,76,105,109,105,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,67,85,85,77,32,99,111, +115,116,32,108,105,109,105,116,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,86,97,99,76,105,109,105,116,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +115,116,86,97,99,76,105,109,105,116,67,117,114,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +70,114,101,101,122,101,77,105,110,65,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,70,82,69,69,90,69,32,109,105,110,105,109,117,109, +32,97,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120, +116,70,114,101,101,122,101,77,105,110,65,103,101,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,70,114,101,101,122,101,77,105,110,65,103,101,67,117,114,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +115,116,70,114,101,101,122,101,77,97,120,65,103,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,70,82,69,69,90,69,32,109,97,120,105,109,117, +109,32,97,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120, +116,70,114,101,101,122,101,77,97,120,65,103,101,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,70,114,101,101,122,101,77,97,120,65,103,101,67,117,114,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +115,116,70,114,101,101,122,101,84,97,98,108,101,65,103,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,70,82,69,69,90,69,32,116,97,98,108, +101,32,97,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120, +116,70,114,101,101,122,101,84,97,98,108,101,65,103,101,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,70,114,101,101,122,101,84,97,98,108,101,65,103,101,67,117,114, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107, +112,97,103,101,34,32,110,97,109,101,61,34,110,98,112,84,111,97,115,116, +86,97,99,117,117,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,111,97,115,116,32,116, +97,98,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,118,103,97,112,62,52,60,47,118,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,52,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +67,117,115,116,111,109,84,111,97,115,116,86,97,99,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,117,115,116,111,109,32,97,117,116,111, +45,118,97,99,117,117,109,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115, +116,86,97,99,69,110,97,98,108,101,100,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,69,110,97,98,108,101,100,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,84,111,97,115,116,86,97,99,69,110, +97,98,108,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,117,114,114,101,110,116,32,118,97,108,117,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,66,97,115,101,84,111, +97,115,116,86,97,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +86,65,67,85,85,77,32,98,97,115,101,32,116,104,114,101,115,104,111,108,100, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,66,97,115, +101,84,111,97,115,116,86,97,99,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,66,97,115, +101,84,111,97,115,116,86,97,99,67,117,114,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,97,99, +116,111,114,84,111,97,115,116,86,97,99,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,65,67,85,85,77,32,115,99,97,108,101,32,102,97,99,116, +111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70, +97,99,116,111,114,84,111,97,115,116,86,97,99,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,70,97,99,116,111,114,84,111,97,115,116,86,97,99,67,117,114,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,84,111,97,115,116,86,97,99,68,101,108,97,121,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,86,65,67,85,85,77,32,99,111,115,116, +32,100,101,108,97,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,84,111,97,115,116,86,97,99,68,101,108,97,121,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,84,111,97,115,116,86,97,99,68,101,108,97,121,67,117,114,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,84,111,97,115,116,86,97,99,76,105,109,105,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,67,85,85,77,32, +99,111,115,116,32,108,105,109,105,116,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,116,120,116,84,111,97,115,116,86,97,99,76,105,109, +105,116,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,86,97,99,76,105, +109,105,116,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,70, +114,101,101,122,101,77,105,110,65,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,70,82,69,69,90,69,32,109,105,110,105,109,117,109,32, +97,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120, +116,84,111,97,115,116,70,114,101,101,122,101,77,105,110,65,103,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,84,111,97,115,116,70,114,101,101,122,101,77, +105,110,65,103,101,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,70, +114,101,101,122,101,77,97,120,65,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,70,82,69,69,90,69,32,109,97,120,105,109,117,109,32, +97,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120, +116,84,111,97,115,116,70,114,101,101,122,101,77,97,120,65,103,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,84,111,97,115,116,70,114,101,101,122,101,77, +97,120,65,103,101,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,70, +114,101,101,122,101,84,97,98,108,101,65,103,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,70,82,69,69,90,69,32,116,97,98,108,101,32,97, +103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,84, +111,97,115,116,70,114,101,101,122,101,84,97,98,108,101,65,103,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,84,111,97,115,116,70,114,101,101,122,101,84, +97,98,108,101,65,103,101,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_70 = 18754; +static unsigned char xml_res_file_70[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,66,97,99,107,117,112,34,62,10,32,32,32,32,60,116, +105,116,108,101,62,66,97,99,107,117,112,60,47,116,105,116,108,101,62,10, +32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,51,51,100,60,47,115,105, +122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65, +85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84, +73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69, +83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60, +99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114, +111,119,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78, +111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,112, +111,115,62,50,44,50,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,50,56,53,44,50,50,52,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +78,66,95,66,79,84,84,79,77,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,32,79,112,116,105, +111,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,70,105,108,101,79,112, +116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,70,105,108,101,110,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,70,105,108,101,110,97,109,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,105,108,101, +110,97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,98,116,110,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,111,114, +109,97,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,70,111,114,109,97,116,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,70,111,114,109,97,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,67,111,109,112,114,101,115,115,82,97,116,105,111,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,111,109,112,114,101,115,115,32,82,97,116,105,111,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,109,112,114,101,115,115,82,97,116,105,111,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,69,110,99,111,100,105,110,103,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +69,110,99,111,100,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,69,110,99,111,100,105, +110,103,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +124,119,120,67,66,95,83,79,82,84,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,78,117,109,98,101,114,79,102,74,111,98,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,78,117,109,98,101,114,32,79,102,32,74,111,98,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,78,117,109,98,101,114,79,102,74,111,98,115,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,82,111,108,101,110,97,109,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +82,111,108,101,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,82,111,108,101,110,97, +109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +124,119,120,67,66,95,83,79,82,84,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,68,117,109,112,32,79,112,116,105,111,110,115, +32,35,49,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,68,117,109,112,79,112,116, +105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,111,120,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,83,101,99,116,105,111,110,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65,76, +60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,83,101,99,116,105,111,110,80,114,101,68,97,116, +97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,80,114,101,45,100,97,116,97,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,83,101,99,116,105,111,110, +68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,116,97,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,83,101,99,116,105,111,110, +80,111,115,116,68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,111,115, +116,45,100,97,116,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,32,79,102,32, +79,98,106,101,99,116,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53, +60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62, +119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,79,110,108,121, +68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,110,108,121,32,100,97,116, +97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,79,110,108,121, +83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,110,108,121,32, +115,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,66,108,111,98,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,66,108,111,98,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47, +99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,111,110,39,116,32,115,97,118,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60, +47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65,76,60, +47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,78,111,79,119,110,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99, +104,107,78,111,80,114,105,118,105,108,101,103,101,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,80,114,105,118,105,108,101,103,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,99,104,107,78,111,84,97,98,108,101,115,112,97,99,101,115, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,84,97,98,108,101,115,112,97,99,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,78,111,85,110,108, +111,103,103,101,100,84,97,98,108,101,68,97,116,97,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,85,110,108,111,103,103,101,100,32,116,97,98,108,101,32,100,97, +116,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111, +116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,68,117,109,112,32,79,112,116,105,111, +110,115,32,35,50,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,117,109,112, +79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,81,117,101,114,105,101,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73, +67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,67,114,101,97,116,101,68,98,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,73,110,99,108,117,100,101,32,67,82,69,65,84, +69,32,68,65,84,65,66,65,83,69,32,115,116,97,116,101,109,101,110,116,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,68,114,111,112,68, +98,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,73,110,99,108,117,100,101,32,68,82, +79,80,32,68,65,84,65,66,65,83,69,32,115,116,97,116,101,109,101,110,116, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,67,111,108,117, +109,110,73,110,115,101,114,116,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,67,111,108,117,109,110,32,73,110,115,101,114,116,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,73,110,115,101,114,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,85,115,101,32,73,110,115,101,114,116,32,99, +111,109,109,97,110,100,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,105,115,97,98,108, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84, +73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,68,105,115,97,98,108,101,84,114, +105,103,103,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,114,105,103,103, +101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,68,105,115, +97,98,108,101,68,111,108,108,97,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68, +111,108,108,97,114,32,113,117,111,116,105,110,103,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +77,105,115,99,101,108,108,97,110,111,117,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101, +110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,85,115,101,83,101,116,83,101,115,115,105,111,110,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,85,115,101,32,83,69,84,32,83,69,83,83,73,79,78,32,65,85,84, +72,79,82,73,90,65,84,73,79,78,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,79,105,100,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,87,105, +116,104,32,79,73,68,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,86,101,114,98,111,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,101,114, +98,111,115,101,32,109,101,115,115,97,103,101,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,99,104,107,70,111,114,99,101,81,117,111,116,101,70,111, +114,73,100,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,111,114,99, +101,32,100,111,117,98,108,101,32,113,117,111,116,101,115,32,111,110,32, +105,100,101,110,116,105,102,105,101,114,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +79,98,106,101,99,116,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99, +116,108,67,104,101,99,107,84,114,101,101,86,105,101,119,34,32,110,97,109, +101,61,34,99,116,118,79,98,106,101,99,116,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,82,95,72,65, +83,95,66,85,84,84,79,78,83,124,119,120,83,73,77,80,76,69,95,66,79,82,68, +69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,77,101,115,115,97,103,101,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,77,101,115,115,97,103,101,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85, +76,84,73,76,73,78,69,124,119,120,84,69,95,82,69,65,68,79,78,76,89,124,119, +120,72,83,67,82,79,76,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120, +71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,66,97,99,107,117,112, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_71 = 3997; +static unsigned char xml_res_file_71[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,66,97,99,107,117,112,71,108,111,98,97,108,115,34, +62,10,32,32,32,32,60,116,105,116,108,101,62,66,97,99,107,117,112,32,71, +108,111,98,97,108,115,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115, +105,122,101,62,50,49,48,44,49,53,51,100,60,47,115,105,122,101,62,10,32, +32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73, +65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119, +120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66, +79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110, +98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98, +111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,79,112,116,105,111,110,115,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,110,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,112,111,115,62,56,44,55,100,60,47,112,111,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,116,120,116,70,105,108,101,110,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,54,53,44,53, +100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,49,53,48,44,45,49,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,98,116,110,70,105,108,101,110,97,109,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,46,46,46, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,112,111,115,62,50,50,48,44,53,100,60,47,112,111,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,53,44, +45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +82,111,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,82,111,108,101,110,97,109,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,112,111,115,62,56,44,50,55,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,82,111,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,112,111,115,62,54,53,44,50,53,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,55,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87, +78,124,119,120,67,66,95,83,79,82,84,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,116,120,116,78,111,116,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,111,116, +101,58,32,79,110,108,121,32,111,98,106,101,99,116,115,32,103,108,111,98, +97,108,32,116,111,32,116,104,101,32,101,110,116,105,114,101,32,100,97,116, +97,98,97,115,101,32,99,108,117,115,116,101,114,32,119,105,108,108,32,98, +101,32,98,97,99,107,101,100,92,110,117,112,46,32,84,104,101,32,98,97,99, +107,117,112,32,102,111,114,109,97,116,32,119,105,108,108,32,98,101,32,80, +76,65,73,78,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,112,111,115,62,56,44,52,55,100,60,47,112,111,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,70,111,114,99,101,81,117,111, +116,101,70,111,114,73,100,101,110,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,111,114,99,101,32,100, +111,117,98,108,101,32,113,117,111,116,101,115,32,111,110,32,105,100,101, +110,116,105,102,105,101,114,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,48,44,49,50, +48,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,86,101,114,98,111, +115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,101,114,98,111,115,101,32,109,101,115,115,97,103,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101, +100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,49,48,44,49,52,52,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,101,108,101,99,116,101,100,62,49,60,47,115,101,108,101, +99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,50,44,50,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,50,52,53,44,49,55,52,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,78,66,95,66,79,84,84,79, +77,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,77,101,115,115,97,103,101,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,116,120,116,77,101,115,115,97,103,101,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84, +69,95,77,85,76,84,73,76,73,78,69,124,119,120,84,69,95,82,69,65,68,79,78, +76,89,124,119,120,72,83,67,82,79,76,76,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68, +124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,50,44,49,51,53,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,66,97,99,107,117,112,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, +62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,112,111,115,62,57,51,44,49,51,53,100,60,47,112,111,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84, +79,80,124,119,120,66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78, +67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,52, +54,44,49,51,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80, +65,78,68,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,71,82,79,87,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119, +97,98,108,101,114,111,119,115,62,10,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111, +117,114,99,101,62,10}; + +static size_t xml_res_size_72 = 3924; +static unsigned char xml_res_file_72[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,66,97,99,107,117,112,83,101,114,118,101,114,34,62, +10,32,32,32,32,60,116,105,116,108,101,62,66,97,99,107,117,112,32,83,101, +114,118,101,114,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105, +122,101,62,50,49,48,44,49,53,51,100,60,47,115,105,122,101,62,10,32,32,32, +32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76, +79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83, +89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82, +68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78, +111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,112,116,105,111,110,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,110,97,109,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,112,111,115,62,56,44,55,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,54,53,44,53,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,49,53,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,46,46,46,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +112,111,115,62,50,50,48,44,53,100,60,47,112,111,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,53,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,82,111,108,101, +110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,82,111,108,101,110,97,109,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,56,44,50,55,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,82,111, +108,101,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,112,111,115,62,54,53,44,50,53,100,60,47,112,111,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,55, +48,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65, +68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120, +67,66,95,83,79,82,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,116,120,116,78,111,116,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,111,116,101,58,32,84,104, +101,32,98,97,99,107,117,112,32,102,111,114,109,97,116,32,119,105,108,108, +32,98,101,32,80,76,65,73,78,46,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,56,44,52,55,100,60, +47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,70,111,114,99,101, +81,117,111,116,101,70,111,114,73,100,101,110,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,111,114,99, +101,32,100,111,117,98,108,101,32,113,117,111,116,101,115,32,111,110,32, +105,100,101,110,116,105,102,105,101,114,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,49, +48,44,49,50,48,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +86,101,114,98,111,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,86,101,114,98,111,115,101,32,109,101, +115,115,97,103,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47, +99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,112,111,115,62,49,48,44,49,52,52,100,60,47,112,111,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +49,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,112, +111,115,62,50,44,50,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,50,52,53,44,49,55,52,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +78,66,95,66,79,84,84,79,77,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,77,101,115,115,97,103,101,115,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,77,101,115,115,97,103,101, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,124,119,120,84,69,95, +82,69,65,68,79,78,76,89,124,119,120,72,83,67,82,79,76,76,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124, +119,120,69,88,80,65,78,68,124,119,120,71,82,79,87,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,38,97,109,112,59,72,101,108,112,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,50,44,49,51,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79, +77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,38,97,109,112,59,66,97,99,107,117,112,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,57,51,44,49, +51,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,112,111,115,62,49,52,54,44,49,51,53,100,60,47,112,111,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79, +80,124,119,120,66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,71,82,79,87,124,119, +120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101, +99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_73 = 3765; +static unsigned char xml_res_file_73[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,69,120,112,111,114,116,34,62,10,32,32,32,32,60,116, +105,116,108,101,62,69,120,112,111,114,116,32,100,97,116,97,32,116,111,32, +102,105,108,101,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105, +122,101,62,50,53,51,44,49,52,51,100,60,47,115,105,122,101,62,10,32,32,32, +32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76, +79,71,95,83,84,89,76,69,60,47,115,116,121,108,101,62,10,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,34,32,110,97,109,101,61,34,114,98,82,111,119,83,101,112, +97,114,97,116,111,114,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62, +82,111,119,32,115,101,112,97,114,97,116,111,114,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,60,112,111,115,62,53,44,53,100,60,47,112,111,115, +62,10,32,32,32,32,32,32,60,115,105,122,101,62,49,50,48,44,51,56,100,60, +47,115,105,122,101,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,114, +98,76,70,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,76,70,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,60,118,97,108,117,101,62,49,60, +47,118,97,108,117,101,62,10,32,32,32,32,32,32,60,112,111,115,62,49,48,44, +49,55,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,82,66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,114,98,67,82,76,70,34,62,10, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,82,47,76,70,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,49,48,44,50,57,100,60, +47,112,111,115,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111, +108,83,101,112,97,114,97,116,111,114,34,62,10,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,111,108,117,109,110,32,115,101,112,97,114,97,116,111, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,53, +44,53,53,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,111,108,83,101,112,97,114,97,116,111,114,34,62,10,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,59,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,60,105, +116,101,109,62,44,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,60, +105,116,101,109,62,124,60,47,105,116,101,109,62,10,32,32,32,32,32,32,60, +47,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,60,115,101,108,101, +99,116,105,111,110,62,48,60,47,115,101,108,101,99,116,105,111,110,62,10, +32,32,32,32,32,32,60,112,111,115,62,49,48,48,44,53,51,100,60,47,112,111, +115,62,10,32,32,32,32,32,32,60,115,105,122,101,62,50,53,44,49,50,100,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,81,117,111,116,101,67,104,97,114, +34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,81,117,111,116,101,32, +99,104,97,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111, +115,62,53,44,55,48,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,81,117,111,116,101,67,104,97,114,34,62,10,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,34,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,60,105, +116,101,109,62,39,60,47,105,116,101,109,62,10,32,32,32,32,32,32,60,47,99, +111,110,116,101,110,116,62,10,32,32,32,32,32,32,60,115,101,108,101,99,116, +105,111,110,62,48,60,47,115,101,108,101,99,116,105,111,110,62,10,32,32, +32,32,32,32,60,112,111,115,62,49,48,48,44,54,56,100,60,47,112,111,115,62, +10,32,32,32,32,32,32,60,115,105,122,101,62,50,53,44,49,50,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,67,111,108,110,97,109,101,115,34,62, +10,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,32, +110,97,109,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112, +111,115,62,53,44,56,53,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,67,111,108,110,97,109,101,115,34,62,10,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,60,99,104,101,99, +107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32, +32,60,112,111,115,62,49,48,48,44,56,51,100,60,47,112,111,115,62,10,32,32, +32,32,32,32,60,115,105,122,101,62,49,50,44,49,50,100,60,47,115,105,122, +101,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,34,32,110,97,109,101,61,34,115,98,69,110,99,111,100,105, +110,103,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,99,111, +100,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112, +111,115,62,49,51,48,44,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +60,115,105,122,101,62,49,50,48,44,51,56,100,60,47,115,105,122,101,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,114,98,76,111,99,97,108,34,62, +10,32,32,32,32,32,32,60,108,97,98,101,108,62,76,111,99,97,108,32,99,104, +97,114,115,101,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,118, +97,108,117,101,62,49,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,60, +112,111,115,62,49,52,48,44,49,55,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82, +97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,114,98, +85,110,105,99,111,100,101,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108, +62,85,110,105,99,111,100,101,32,85,84,70,45,56,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,60,112,111,115,62,49,52,48,44,50,57,100,60,47,112, +111,115,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,34,32,110,97,109,101,61,34,115,98,81,117,111,116,105, +110,103,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,81,117,111,116, +105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111, +115,62,49,51,48,44,52,56,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +60,115,105,122,101,62,49,50,48,44,53,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,114,98,81,117,111,116,101,78, +111,110,101,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,110,111, +32,113,117,111,116,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,60,112,111,115,62,49,52,48,44,54,48,100,60,47,112,111,115,62,10,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +114,98,81,117,111,116,101,83,116,114,105,110,103,115,34,62,10,32,32,32, +32,32,32,60,108,97,98,101,108,62,111,110,108,121,32,115,116,114,105,110, +103,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,118,97,108,117, +101,62,49,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,60,112,111,115, +62,49,52,48,44,55,50,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,114,98,81,117,111,116,101,65,108,108,34,62,10,32,32, +32,32,32,32,60,108,97,98,101,108,62,97,108,108,32,99,111,108,117,109,110, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,49, +52,48,44,56,52,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32,32, +32,60,108,97,98,101,108,62,70,105,108,101,110,97,109,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,53,44,49,48,55,100,60, +47,112,111,115,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,105,108, +101,110,97,109,101,34,62,10,32,32,32,32,32,32,60,112,111,115,62,49,48,48, +44,49,48,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,105,122, +101,62,49,51,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,98,116,110,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32, +32,32,60,108,97,98,101,108,62,46,46,46,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,60,112,111,115,62,50,51,53,44,49,48,53,100,60,47,112,111, +115,62,10,32,32,32,32,32,32,60,115,105,122,101,62,49,53,44,45,49,100,60, +47,115,105,122,101,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112, +111,115,62,50,44,49,50,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +60,115,116,121,108,101,47,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +88,108,115,67,111,112,121,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108, +62,88,108,115,32,102,109,116,32,99,111,112,121,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104, +101,99,107,101,100,62,10,32,32,32,32,32,32,60,112,111,115,62,53,53,44,49, +50,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,105,122,101, +62,55,48,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,60,112,111,115,62,49,52,55,44,49,50,53,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,60,115,116,121,108,101,47,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,60,112, +111,115,62,50,48,48,44,49,50,53,100,60,47,112,111,115,62,10,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62, +10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_74 = 1443; +static unsigned char xml_res_file_74[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,71,114,97,110,116,87,105,122,97,114,100,34,62,10, +32,32,32,32,60,116,105,116,108,101,62,71,114,97,110,116,32,87,105,122,97, +114,100,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101, +62,50,48,48,44,51,48,51,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,60,47,115,116,121,108,101,62,10,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101, +98,111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111, +111,107,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,108,101,99,116,105, +111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34, +32,110,97,109,101,61,34,112,110,108,83,101,108,101,99,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,76,105,115,116,66,111,120,34, +32,110,97,109,101,61,34,99,104,107,76,105,115,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,112,111,115,62,50,44,51,100,60,47,112,111, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +56,51,44,50,51,52,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,67,104,107,65,108,108, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67, +104,101,99,107,32,97,108,108,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,112,111,115,62,50,44,50,52,48,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +53,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,98,116,110,85,110,99,104,107,65,108, +108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +85,110,99,104,101,99,107,32,97,108,108,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,54,48,44,50,52,48,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,53,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,115,101,108, +101,99,116,101,100,62,49,60,47,115,101,108,101,99,116,101,100,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,112, +111,115,62,50,44,50,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60,115, +105,122,101,62,49,57,53,44,50,55,54,100,60,47,115,105,122,101,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32, +32,32,60,108,97,98,101,108,62,38,97,109,112,59,72,101,108,112,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,50,44,50,56,53, +100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +79,75,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,60,112,111,115,62,57,51,44,50,56,53,100,60,47,112,111,115,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,49,52, +54,44,50,56,53,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101, +115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_75 = 3111; +static unsigned char xml_res_file_75[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,72,105,110,116,34,62,10,32,32,32,32,60,116,105,116, +108,101,62,112,103,65,100,109,105,110,32,71,117,114,117,32,72,105,110,116, +60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101,62,50,48, +48,44,49,53,51,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,72,116,109, +108,87,105,110,100,111,119,34,32,110,97,109,101,61,34,104,116,109,108,72, +105,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,85,78,75,69,78,95,66,79,82,68,69,82,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,60,109,105,110,115,105,122,101,62,51,48,48,44,50,48,48,100,60, +47,109,105,110,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,117, +112,112,114,101,115,115,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,68,111,32,110,111,116,32,115,104,111,119,32,116,104,105,115, +32,104,105,110,116,32,97,103,97,105,110,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,55,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,112,111,115,62,50,44,49,51,53,100,60,47,112,111, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +84,79,80,124,119,120,66,79,84,84,79,77,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,98,116,110,70,105,120,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,70,105,120,32,105,116,33,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,112,111,115,62,57,51,44,49,51,53,100,60,47,112,111,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,89,69,83,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,89,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97, +117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111, +115,62,57,51,44,49,51,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,66,79, +84,84,79,77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,78,79,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,78, +111,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,57,51, +44,49,51,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,57,51,44,49,51,53,100,60, +47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +112,111,115,62,49,52,54,44,49,51,53,100,60,47,112,111,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124, +119,120,69,88,80,65,78,68,124,119,120,71,82,79,87,124,119,120,65,76,73, +71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,71, +82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62, +10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_76 = 12319; +static unsigned char xml_res_file_76[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,73,109,112,111,114,116,34,62,10,32,32,32,32,60,116, +105,116,108,101,62,73,109,112,111,114,116,32,100,97,116,97,32,102,114,111, +109,32,102,105,108,101,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115, +105,122,101,62,51,48,48,44,49,51,51,100,60,47,115,105,122,101,62,10,32, +32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73, +65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119, +120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66, +79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98, +111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111, +107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,50,44,50,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,50,56,53,44,49,50,52,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,78,66,95,66,79,84,84,79, +77,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,70,105,108,101,32,79,112,116,105,111,110,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,70,105,108,101,79,112,116,105,111,110,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108, +101,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,105,108,101,80,105,99, +107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105,99,107,101, +114,73,109,112,111,114,116,102,105,108,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,101,115,115,97,103,101,62, +83,101,108,101,99,116,32,116,104,101,32,102,105,108,101,32,116,111,32,105, +109,112,111,114,116,60,47,109,101,115,115,97,103,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,70,76,80,95,79,80,69,78,124,119,120,70,76,80,95,85,83,69,95, +84,69,88,84,67,84,82,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,105,108,100,99,97,114, +100,62,42,46,99,115,118,59,42,46,42,59,42,60,47,119,105,108,100,99,97,114, +100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +116,111,111,108,116,105,112,62,69,110,116,101,114,32,97,32,102,105,108, +101,110,97,109,101,32,116,111,32,105,109,112,111,114,116,46,60,47,116,111, +111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,111,114,109, +97,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,70,111,114,109,97,116,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +70,111,114,109,97,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,116, +101,120,116,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,99,115,118,60,47, +105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,105,116,101,109,62,98,105,110,97,114,121,60,47,105,116, +101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,105,111,110,62, +48,60,47,115,101,108,101,99,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +69,110,99,111,100,105,110,103,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,99,111,100,105, +110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,99,98,69,110,99,111,100,105,110,103,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95, +83,79,82,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,67,111,108,117,109,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,67, +111,108,117,109,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,49,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,108,117,109, +110,115,84,111,73,109,112,111,114,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,108, +117,109,110,115,32,116,111,32,105,109,112,111,114,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,76,105,115,116,66,111,120,34,32,110,97,109, +101,61,34,108,115,116,67,111,108,117,109,110,115,84,111,73,109,112,111, +114,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,77,105,115,99,46,32,79,112,116,105,111,110,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108, +34,32,110,97,109,101,61,34,112,110,108,77,105,115,99,79,112,116,105,111, +110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,105,100,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,79,105,100,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107, +101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,72,101,97,100,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97,100,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,99,104,107,72,101,97,100,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,68,101,108,105,109,105,116,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,101,108,105,109,105,116,101,114,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,68,101,108, +105,109,105,116,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +59,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,44,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,124,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,91, +116,97,98,93,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,81,117,111,116,101,32,79,112,116, +105,111,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, +97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,81,117,111,116,101, +79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,81,117,111,116,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,81,117,111,116,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,81,117,111,116,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,34,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,39,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,69,115,99,97,112,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,69,115,99,97,112,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,69,115,99, +97,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,34,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,39,60,47,105,116,101,109,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87, +78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111, +111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,85,76,76,32,79,112,116,105,111,110,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,78,117,108,108,79,112,116,105,111,110,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,117,108,108,83,116,114,105,110,103,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,78,85,76,76,32,115,116,114,105,110,103,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,78,117,108,108,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,103,110,111, +114,101,70,111,114,67,111,108,117,109,110,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,103, +110,111,114,101,32,102,111,114,32,99,111,108,117,109,110,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,76,105,115,116,66,111,120,34,32, +110,97,109,101,61,34,108,115,116,73,103,110,111,114,101,70,111,114,67,111, +108,117,109,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124, +119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,71,97,117,103,101, +34,32,110,97,109,101,61,34,103,97,117,103,101,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,73,109,112,111,114,116,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, +102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_77 = 5178; +static unsigned char xml_res_file_77[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,77,97,105,110,116,101,110,97,110,99,101,34,62,10, +32,32,32,32,60,116,105,116,108,101,62,77,97,105,110,116,101,110,97,110, +99,101,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101,62, +50,48,48,44,49,53,51,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84, +69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,78,66,95, +66,79,84,84,79,77,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116, +101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,112,116,105,111,110,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97, +100,105,111,66,111,120,34,32,110,97,109,101,61,34,114,98,120,65,99,116, +105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,77,97,105,110,116,101,110,97,110,99,101, +32,111,112,101,114,97,116,105,111,110,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,105,116,101,109,62,86,65,67,85,85,77,60,47,105,116,101, +109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,105,116,101,109,62,65,78,65,76,89,90,69,60,47,105,116,101,109,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +105,116,101,109,62,82,69,73,78,68,69,88,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,67,76,85,83,84,69,82,60,47,105,116,101,109,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101, +110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,101,108,101,99,116,105,111,110,62,48,60,47,115,101,108,101,99, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,82,65,95,83,80,69,67,73,70,89, +95,82,79,87,83,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +86,65,67,85,85,77,32,111,112,116,105,111,110,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111, +114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,70,117,108,108,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70, +85,76,76,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,70,114,101, +101,122,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,82,69,69,90,69,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,65,110,97,108,121,122,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,65,78,65,76,89,90,69,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,86,101, +114,98,111,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,86,101,114,98,111,115,101,32,109, +101,115,115,97,103,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +101,108,101,99,116,101,100,62,49,60,47,115,101,108,101,99,116,101,100,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,115,115,97,103,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, +67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,77,101,115,115,97, +103,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,124,119,120, +84,69,95,82,69,65,68,79,78,76,89,124,119,120,72,83,67,82,79,76,76,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119, +120,66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +124,119,120,69,88,80,65,78,68,124,119,120,71,82,79,87,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,38,97,109,112,59,72,101,108,112,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,50,44,49,51,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79, +77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, +108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,112,111,115,62,57,51,44,49,51,53,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112, +111,115,62,49,52,54,44,49,51,53,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124, +119,120,69,88,80,65,78,68,124,119,120,71,82,79,87,124,119,120,65,76,73, +71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,71, +82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60, +47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62, +10}; + +static size_t xml_res_size_78 = 68517; +static unsigned char xml_res_file_78[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,79,112,116,105,111,110,115,34,62,10,32,32,32,32,60, +116,105,116,108,101,62,79,112,116,105,111,110,115,60,47,116,105,116,108, +101,62,10,32,32,32,32,60,115,105,122,101,62,52,56,48,44,50,53,48,100,60, +47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120, +68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120, +67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119, +120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,84,114,101,101,34,32,110,97,109,101,61,34,109,101,110,117, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,49,48,48,44,50,50,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,82,95,72, +65,83,95,66,85,84,84,79,78,83,124,119,120,83,73,77,80,76,69,95,66,79,82, +68,69,82,124,119,120,84,82,95,72,73,68,69,95,82,79,79,84,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,48,44,49,44,50,44,51,44,52,44,53,44,54,44,55,44,56,44,57, +44,49,48,44,49,49,44,49,50,44,49,51,44,49,52,44,49,53,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,77,105,115, +99,72,101,108,112,80,97,116,104,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,105,100,100,101,110,62,49,60,47,104,105, +100,100,101,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,80,103,72,101,108,112,80,97, +116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,71,32,104,101,108,112,32,112, +97,116,104,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,80,103,72,101,108,112,80,97, +116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,69,110,116,101,114, +32,116,104,101,32,112,97,116,104,32,111,114,32,85,82,76,32,116,111,32,116, +104,101,32,80,111,115,116,103,114,101,83,81,76,32,100,111,99,117,109,101, +110,116,97,116,105,111,110,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,69,100,98,72,101,108,112,80,97,116,104,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,69,68,66,32,104,101,108,112,32,112,97,116,104,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,116,120,116,69,100,98,72,101,108,112,80,97,116,104,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,71,112,72,101,108,112,80,97,116,104,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,71,80,32,104,101,108,112,32,112,97,116,104,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116, +71,112,72,101,108,112,80,97,116,104,34,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,108,111,110,121,72, +101,108,112,80,97,116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,108,111, +110,121,32,104,101,108,112,32,112,97,116,104,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,83, +108,111,110,121,72,101,108,112,80,97,116,104,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,77,105,115, +99,85,73,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,105,100,100,101,110,62,49,60,47,104,105,100,100,101,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,76,97,110,103,117,97,103,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,85,115,101,114,32,108,97,110,103,117,97,103,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,76,97,110,103,117,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,83,121,115,116,101,109,83,99,104,101, +109,97,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,121,115,116,101,109,32, +115,99,104,101,109,97,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, +67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,83,121,115,116,101, +109,83,99,104,101,109,97,115,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,66,114,111,119,115,101, +114,68,105,115,112,108,97,121,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,105,100,100,101,110,62,49,60,47,104,105,100, +100,101,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,97,116, +97,98,97,115,101,79,98,106,101,99,116,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,68,105,115,112,108,97,121,32,116,104,101,32,102,111,108,108,111,119, +105,110,103,32,100,97,116,97,98,97,115,101,32,111,98,106,101,99,116,115, +58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,76,105,115,116,66,111,120,34,32,110,97,109,101,61,34,108,115,116, +68,105,115,112,108,97,121,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,98,116,110,68,101,102,97,117,108,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,68,101,102,97,117,108,116,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,66,114,111,119,115,101,114,80,114,111,112, +101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,104,105,100,100,101,110,62,49,60,47,104,105,100,100,101, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,65,117,116,111,82,111,119,67,111,117,110, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,67,111,117,110,116,32,114,111,119,115, +32,105,102,32,101,115,116,105,109,97,116,101,100,32,108,101,115,115,32, +116,104,97,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,65,117,116,111,82,111,119,67, +111,117,110,116,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,66,114,111,119,115,101,114,66,105,110,80,97, +116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,105,100,100,101,110,62,49,60,47,104,105,100,100,101,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,53,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,108,111,110,121,80,97,116, +104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,83,108,111,110,121,45,73,32,112,97, +116,104,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,114,80,105,99,107, +101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105,99,107,101,114, +83,108,111,110,121,80,97,116,104,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,101,115,115,97,103,101, +62,83,101,108,101,99,116,32,100,105,114,101,99,116,111,114,121,32,119,105, +116,104,32,83,108,111,110,121,45,73,32,99,114,101,97,116,105,111,110,32, +115,99,114,105,112,116,115,60,47,109,101,115,115,97,103,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,73,82,80,95,85,83,69,95,84,69,88,84,67,84, +82,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,80,111, +115,116,103,114,101,115,113,108,80,97,116,104,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,80,71,32,98,105,110,32,112,97,116,104,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +68,105,114,80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101,61, +34,112,105,99,107,101,114,80,111,115,116,103,114,101,115,113,108,80,97, +116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,109,101,115,115,97,103,101,62,83,101,108,101,99,116, +32,100,105,114,101,99,116,111,114,121,32,119,105,116,104,32,80,111,115, +116,103,114,101,83,81,76,32,117,116,105,108,105,116,105,101,115,60,47,109, +101,115,115,97,103,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,68,73,82, +80,95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,69,110,116,101,114,112,114,105,115,101, +100,98,80,97,116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,68,66,32,98,105, +110,32,112,97,116,104,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,114,80,105,99, +107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105,99,107,101, +114,69,110,116,101,114,112,114,105,115,101,100,98,80,97,116,104,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,109,101,115,115,97,103,101,62,83,101,108,101,99,116,32,100,105,114,101, +99,116,111,114,121,32,119,105,116,104,32,69,110,116,101,114,112,114,105, +115,101,68,66,32,117,116,105,108,105,116,105,101,115,60,47,109,101,115, +115,97,103,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,68,73,82,80,95,85, +83,69,95,84,69,88,84,67,84,82,76,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,71,80,68,66,80,97,116,104,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,71,80,32,98,105,110,32,112,97,116,104,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,68,105,114,80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101, +61,34,112,105,99,107,101,114,71,80,68,66,80,97,116,104,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,101, +115,115,97,103,101,62,83,101,108,101,99,116,32,100,105,114,101,99,116,111, +114,121,32,119,105,116,104,32,71,114,101,101,110,112,108,117,109,68,66, +32,117,116,105,108,105,116,105,101,115,60,47,109,101,115,115,97,103,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,68,73,82,80,95,85,83,69,95,84,69, +88,84,67,84,82,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,73,103,110,111,114,101,86,101,114,115,105,111,110,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,73,103,110,111,114,101,32,115,101,114,118,101,114,47,117, +116,105,108,105,116,121,32,118,101,114,115,105,111,110,32,109,105,115,109, +97,116,99,104,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,86,101,114,115,105,111,110,77,105,115,109,97,116,99,104,87,97, +114,110,105,110,103,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,87,97,114,110,105, +110,103,58,32,66,97,99,107,117,112,32,111,114,32,114,101,115,116,111,114, +101,32,111,112,101,114,97,116,105,111,110,115,32,109,97,121,32,102,97,105, +108,32,105,102,32,116,104,101,32,80,111,115,116,103,114,101,83,81,76,32, +117,116,105,108,105,116,105,101,115,32,100,111,32,110,111,116,32,109,97, +116,99,104,32,116,104,101,32,115,101,114,118,101,114,32,118,101,114,115, +105,111,110,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110, +108,66,114,111,119,115,101,114,77,105,115,99,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,104,105,100,100,101,110,62,49,60, +47,104,105,100,100,101,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,70,111,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,70,111,110,116,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +111,110,116,80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101,61, +34,112,105,99,107,101,114,70,111,110,116,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,65,115,107,68,101, +108,101,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,110,102,105,114, +109,32,111,98,106,101,99,116,32,100,101,108,101,116,105,111,110,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,83,121,115,116,101,109,79, +98,106,101,99,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,104,111,119,32, +83,121,115,116,101,109,32,79,98,106,101,99,116,115,32,105,110,32,116,104, +101,32,116,114,101,101,118,105,101,119,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,83,104,111,119,85,115,101,114,115,70,111,114,80, +114,105,118,105,108,101,103,101,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +104,111,119,32,117,115,101,114,115,32,102,111,114,32,112,114,105,118,105, +108,101,103,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107, +101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,68,111,117,98,108,101,67,108,105,99,107,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,104,111,119,32,111,98,106, +101,99,116,32,112,114,111,112,101,114,116,105,101,115,32,111,110,32,100, +111,117,98,108,101,32,99,108,105,99,107,32,105,110,32,116,114,101,101,118, +105,101,119,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,104, +111,119,78,111,116,105,99,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,104, +111,119,32,78,79,84,73,67,69,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104, +101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,82,101,102,114,101,115,104,79,110,67,108,105,99,107,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,82,101,102,114,101,115,104,32,111,110,32, +99,108,105,99,107,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,82,101,102,114,101,115,104,79,110, +67,108,105,99,107,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,105,116,101,109,62,78,111,110,101,60,47,105,116, +101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,82,101,102,114,101, +115,104,32,111,98,106,101,99,116,32,111,110,32,99,108,105,99,107,60,47, +105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,82,101,102, +114,101,115,104,32,111,98,106,101,99,116,32,97,110,100,32,99,104,105,108, +100,114,101,110,32,111,110,32,99,108,105,99,107,60,47,105,116,101,109,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,81,117,101,114,121,84,111,111,108,69,100,105, +116,111,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,104,105,100,100,101,110,62,49,60,47,104,105,100,100,101,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,83,113,108,70,111,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,70,111,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,111,110,116, +80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105, +99,107,101,114,83,113,108,70,111,110,116,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,77,97,120,67, +111,108,83,105,122,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,120,46,32, +99,104,97,114,97,99,116,101,114,115,32,112,101,114,32,99,111,108,117,109, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,77,97,120,67,111,108,83,105,122,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,97,108,117,101,62,50,53,54,60,47,118,97,108,117,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,73,110,100,101,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,73,110,100,101,110,116,32,99,104,97,114,97,99,116,101,114,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,116,120,116,73,110,100,101,110,116,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,112,97, +99,101,115,70,111,114,84,97,98,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,115,112,97,99,101,115,32,105,110,115,116,101,97,100,32,111,102, +32,116,97,98,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,83,112,97,99,101,115,70,111, +114,84,97,98,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,116,105,99,107,121, +83,113,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,112,121,32,83,81,76, +32,102,114,111,109,32,109,97,105,110,32,119,105,110,100,111,119,32,116, +111,32,113,117,101,114,121,32,116,111,111,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,116, +105,99,107,121,83,113,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,65,117,116,111,82,111,108,108,98,97,99,107,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,69,110,97,98,108,101,32,65,117,116,111,32, +82,79,76,76,66,65,67,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,65,117,116,111,82, +111,108,108,98,97,99,107,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104, +101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,65,117,116,111,67,111,109,109,105,116,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,69,110,97,98,108,101,32,65,117,116,111,67,111,109, +109,105,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,65,117,116,111,67,111,109,109, +105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101, +100,62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,75,101,121,119,111,114,100,73,110,85,112,112,101,114,99,97,115,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,75,101,121,119,111,114,100,115,32,105, +110,32,117,112,112,101,114,99,97,115,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,75,101, +121,119,111,114,100,115,73,110,85,112,112,101,114,99,97,115,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,69,120,116,70, +111,114,109,97,116,67,109,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,120,116, +101,114,110,97,108,32,102,111,114,109,97,116,116,105,110,103,32,117,116, +108,105,116,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,105,108,101,80,105,99, +107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105,99,107,101, +114,69,120,116,70,111,114,109,97,116,67,109,100,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,101,115, +115,97,103,101,62,83,101,108,101,99,116,32,117,116,105,108,105,116,121, +32,116,111,32,102,111,114,109,97,116,32,116,101,120,116,60,47,109,101,115, +115,97,103,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,119,105,108,100,99,97,114,100,62,42,60,47,119,105, +108,100,99,97,114,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,70,76,80,95, +79,80,69,78,124,119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84,82,76, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,65,32, +99,111,109,109,97,110,100,32,108,105,110,101,32,117,116,105,108,105,116, +121,32,119,104,105,99,104,32,114,101,97,100,115,32,83,84,68,73,78,32,97, +110,100,32,100,105,114,101,99,116,115,32,111,117,116,112,117,116,32,116, +111,32,83,84,68,79,85,84,46,60,47,116,111,111,108,116,105,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,81,117,101,114,121,84,111,111,108,67,111,108, +111,117,114,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,105,100,100,101,110,62,49,60,47,104,105,100,100,101,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,70,111,114,101,103,114,111,117,110, +100,47,66,97,99,107,103,114,111,117,110,100,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65,76,60,47, +111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,52,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,52,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,44, +49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,83,81,76,85,115,101,83,121,115,116,101,109,66, +97,99,107,103,114,111,117,110,100,67,111,108,111,117,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,32,115,121,115,116, +101,109,32,98,97,99,107,103,114,111,117,110,100,32,99,111,108,111,114,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,83,81,76,67,117,115,116,111,109, +66,97,99,107,103,114,111,117,110,100,67,111,108,111,117,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,117,115,116,111,109,32, +98,97,99,107,103,114,111,117,110,100,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,99,116,108,67,111,108,111,117,114,80,105,99,107,101,114,34,32, +110,97,109,101,61,34,112,105,99,107,101,114,83,81,76,66,97,99,107,103,114, +111,117,110,100,67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,83,81,76,85,115,101,83,121,115,116,101,109,70,111, +114,101,103,114,111,117,110,100,67,111,108,111,117,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,32,115,121,115,116,101, +109,32,102,111,114,101,103,114,111,117,110,100,32,99,111,108,111,114,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,83,81,76,67,117,115,116,111,109, +70,111,114,101,103,114,111,117,110,100,67,111,108,111,117,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,117,115,116,111,109, +32,102,111,114,101,103,114,111,117,110,100,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,99,116,108,67,111,108,111,117,114,80,105,99,107,101, +114,34,32,110,97,109,101,61,34,112,105,99,107,101,114,83,81,76,70,111,114, +101,103,114,111,117,110,100,67,111,108,111,117,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,81,76,77,97,114,103,105,110, +66,97,99,107,103,114,111,117,110,100,67,111,108,111,117,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,114,103,105,110,32,98, +97,99,107,103,114,111,117,110,100,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,99,116,108,67,111,108,111,117,114,80,105,99,107,101,114,34,32, +110,97,109,101,61,34,112,105,99,107,101,114,83,81,76,77,97,114,103,105, +110,66,97,99,107,103,114,111,117,110,100,67,111,108,111,117,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,114, +101,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119, +120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,52,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,52,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,44,49,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,81,76, +67,97,114,101,116,67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,67,97,114,101,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,99,116,108,67,111,108,111,117,114,80,105,99, +107,101,114,34,32,110,97,109,101,61,34,112,105,99,107,101,114,83,81,76, +67,97,114,101,116,67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,111,120,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,81,76,32,83,121,110,116, +97,120,32,72,105,103,104,108,105,103,104,116,105,110,103,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67, +65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,52, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,52,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,44,50,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,83,81,76,67,111,108,111,117,114, +49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,117,108, +116,105,108,105,110,101,32,99,111,109,109,101,110,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,108,111,117,114,80, +105,99,107,101,114,34,32,110,97,109,101,61,34,112,105,99,107,101,114,83, +81,76,67,111,108,111,117,114,49,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,55,48,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,83,81,76,67,111,108,111,117,114,54,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,111,117,98,108,101,32,113,117, +111,116,101,100,32,115,116,114,105,110,103,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,99,116,108,67,111,108,111,117,114,80,105,99,107,101, +114,34,32,110,97,109,101,61,34,112,105,99,107,101,114,83,81,76,67,111,108, +111,117,114,54,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55, +48,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +83,81,76,67,111,108,111,117,114,50,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,83,105,110,103,108,101,32,108,105,110,101,32,99,111, +109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99, +116,108,67,111,108,111,117,114,80,105,99,107,101,114,34,32,110,97,109,101, +61,34,112,105,99,107,101,114,83,81,76,67,111,108,111,117,114,50,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,81,76,67,111,108, +111,117,114,55,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +83,105,110,103,108,101,32,113,117,111,116,101,100,32,115,116,114,105,110, +103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,108,111,117,114,80,105,99,107,101,114,34,32,110,97,109,101,61,34,112, +105,99,107,101,114,83,81,76,67,111,108,111,117,114,55,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,83,81,76,67,111,108,111,117,114, +51,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,81,76,32, +100,111,99,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,108,111,117,114,80,105,99,107,101,114,34,32,110,97,109,101,61, +34,112,105,99,107,101,114,83,81,76,67,111,108,111,117,114,51,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,81,76,67,111,108,111,117, +114,49,48,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112, +101,114,97,116,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,67,111,108,111,117,114,80,105,99,107,101,114,34,32,110,97, +109,101,61,34,112,105,99,107,101,114,83,81,76,67,111,108,111,117,114,49, +48,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49,50, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,81,76, +67,111,108,111,117,114,52,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,78,117,109,98,101,114,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,99,116,108,67,111,108,111,117,114,80,105,99,107,101,114,34,32, +110,97,109,101,61,34,112,105,99,107,101,114,83,81,76,67,111,108,111,117, +114,52,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49, +50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83, +81,76,67,111,108,111,117,114,49,49,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,73,100,101,110,116,105,102,105,101,114,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,108,111,117,114, +80,105,99,107,101,114,34,32,110,97,109,101,61,34,112,105,99,107,101,114, +83,81,76,67,111,108,111,117,114,49,49,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,83,81,76,67,111,108,111,117,114,53,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,75,101,121,119,111,114,100, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,108, +111,117,114,80,105,99,107,101,114,34,32,110,97,109,101,61,34,112,105,99, +107,101,114,83,81,76,67,111,108,111,117,114,53,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,81,117,101,114,121,84,111,111,108,82,101,115, +117,108,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,105,100,100,101,110,62,49,60,47,104,105,100,100,101,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,112,121,81,117,111,116,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,82,101,115,117,108,116,32,99,111,112,121,32,113,117, +111,116,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,99,98,67,111,112,121,81,117,111,116, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,78,111,110,101,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +83,116,114,105,110,103,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,65,108,108,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116, +101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,112,121,81,117, +111,116,101,67,104,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,115, +117,108,116,32,99,111,112,121,32,113,117,111,116,101,32,99,104,97,114,97, +99,116,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,67,111,112,121,81,117,111,116,101, +67,104,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105, +116,101,109,62,34,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +39,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,112,121,83,101, +112,97,114,97,116,111,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,115, +117,108,116,32,99,111,112,121,32,102,105,101,108,100,32,115,101,112,97, +114,97,116,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,99,98,67,111,112,121,83,101,112,97,114, +97,116,111,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105, +116,101,109,62,59,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +44,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,124,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,84,97,98,60,47,105,116,101, +109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,73,110,100,105,99,97,116,101,78,117,108, +108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,83,104,111,119,32,78,85,76,76,32,118, +97,108,117,101,115,32,97,115,32,38,108,116,59,78,85,76,76,38,103,116,59, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,73,110,100,105,99,97,116,101,78,117,108,108,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48, +60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,104, +111,117,115,97,110,100,115,83,101,112,97,114,97,116,111,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,84,104,111,117,115,97,110,100,115,32,115,101,112,97, +114,97,116,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,84,104,111,117,115,97,110, +100,115,83,101,112,97,114,97,116,111,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101, +100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,68,101,99,105,109,97,108,77, +97,114,107,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,99,105,109,97,108,32, +109,97,114,107,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,68,101,99,105,109,97,108,77, +97,114,107,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107, +101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,111,108,117,109,110,78,97,109,101,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,111,112,121,32,99,111,108,117,109,110,32,110,97,109,101,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,67,111,108,117,109,110,78,97,109,101,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60, +47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108, +81,117,101,114,121,84,111,111,108,70,105,108,101,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,105,100,100,101,110, +62,49,60,47,104,105,100,100,101,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,85,110,105,99,111, +100,101,70,105,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,97,100, +32,97,110,100,32,119,114,105,116,101,32,85,110,105,99,111,100,101,32,85, +84,70,45,56,32,102,105,108,101,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,87,114,105,116,101,66,79,77,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,87,114,105,116,101,32,66,79,77,32,102,111,114,32,85,84,70,32,102, +105,108,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,65,115, +107,83,97,118,101,67,111,110,102,105,114,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,111,32,110,111,116,32,112,114,111,109,112,116,32,102,111,114, +32,117,110,115,97,118,101,100,32,102,105,108,101,115,32,111,110,32,101, +120,105,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110, +108,81,117,101,114,121,84,111,111,108,70,97,118,111,117,114,105,116,101, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +105,100,100,101,110,62,49,60,47,104,105,100,100,101,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60, +47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,70,97,118,111,117,114,105,116,101,115,70,105,108,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,70,97,118,111,117,114,105,116,101,115,32,102,105, +108,101,32,112,97,116,104,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,105,108,101, +80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105, +99,107,101,114,70,97,118,111,117,114,105,116,101,115,70,105,108,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,109,101,115,115,97,103,101,62,83,101,108,101,99,116,32,102,105, +108,101,32,116,111,32,115,116,111,114,101,32,102,97,118,111,117,114,105, +116,101,115,32,113,117,101,114,105,101,115,60,47,109,101,115,115,97,103, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,70,76,80,95,79,80,69,78,124, +119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,81,117,101,114,121,84, +111,111,108,77,97,99,114,111,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,105,100,100,101,110,62,49,60,47,104,105, +100,100,101,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,77,97,99,114,111,115,70,105, +108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,99,114,111,115,32,102,105, +108,101,32,112,97,116,104,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,105,108,101, +80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105, +99,107,101,114,77,97,99,114,111,115,70,105,108,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,101, +115,115,97,103,101,62,83,101,108,101,99,116,32,102,105,108,101,32,116,111, +32,115,116,111,114,101,32,109,97,99,114,111,115,60,47,109,101,115,115,97, +103,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,70,76,80,95,79,80,69,78, +124,119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, +97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,81,117,101,114,121, +84,111,111,108,72,105,115,116,111,114,121,70,105,108,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,105,100,100,101, +110,62,49,60,47,104,105,100,100,101,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,72,105,115,116, +111,114,121,70,105,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,105,115, +116,111,114,121,32,102,105,108,101,32,112,97,116,104,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,105,108,101,80,105,99,107,101,114,67,116,114,108,34,32,110, +97,109,101,61,34,112,105,99,107,101,114,72,105,115,116,111,114,121,70,105, +108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,109,101,115,115,97,103,101,62,83,101,108,101,99,116, +32,102,105,108,101,32,116,111,32,115,116,111,114,101,32,113,117,101,114, +105,101,115,32,104,105,115,116,111,114,121,60,47,109,101,115,115,97,103, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,70,76,80,95,79,80,69,78,124, +119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,108,98,108,72,105,115,116,111,114,121, +77,97,120,81,117,101,114,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77, +97,120,105,109,117,109,32,113,117,101,114,105,101,115,32,116,111,32,115, +116,111,114,101,32,105,110,32,104,105,115,116,111,114,121,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,72,105,115,116,111,114,121, +77,97,120,81,117,101,114,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,49, +48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,72,105, +115,116,111,114,121,77,97,120,81,117,101,114,121,83,105,122,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,77,97,120,105,109,117,109,32,115,105,122,101,32, +111,102,32,97,32,115,116,111,114,101,100,32,113,117,101,114,121,32,40,105, +110,32,98,121,116,101,115,41,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,72,105,115,116, +111,114,121,77,97,120,81,117,101,114,121,83,105,122,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +97,108,117,101,62,49,48,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61, +34,112,110,108,83,101,114,118,101,114,83,116,97,116,117,115,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,105,100,100,101, +110,62,49,60,47,104,105,100,100,101,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,100,108,101, +80,114,111,99,101,115,115,67,111,108,111,117,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,73,100,108,101,32,80,114,111,99,101,115,115,32,67,111,108,111,117, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111, +108,111,117,114,80,105,99,107,101,114,34,32,110,97,109,101,61,34,112,105, +99,107,101,114,73,100,108,101,80,114,111,99,101,115,115,67,111,108,111, +117,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105, +122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,65,99,116,105,118,101,80,114, +111,99,101,115,115,67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,65,99,116,105,118,101,32,80,114,111,99,101,115,115,32,67,111,108,111, +117,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,108,111,117,114, +80,105,99,107,101,114,34,32,110,97,109,101,61,34,112,105,99,107,101,114, +65,99,116,105,118,101,80,114,111,99,101,115,115,67,111,108,111,117,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,83,108,111,119,80,114,111,99,101,115, +115,67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,108,111, +119,32,80,114,111,99,101,115,115,32,67,111,108,111,117,114,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,99,116,108,67,111,108,111,117,114,80,105,99,107,101,114,34,32,110, +97,109,101,61,34,112,105,99,107,101,114,83,108,111,119,80,114,111,99,101, +115,115,67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49, +50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,66,108, +111,99,107,101,100,80,114,111,99,101,115,115,67,111,108,111,117,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,66,108,111,99,107,101,100,32,80,114,111,99, +101,115,115,32,67,111,108,111,117,114,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,108,111,117,114,80,105,99,107,101,114,34,32,110,97,109,101,61,34,112, +105,99,107,101,114,66,108,111,99,107,101,100,80,114,111,99,101,115,115, +67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49,50,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,97,116, +97,98,97,115,101,68,101,115,105,103,110,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,105,100,100,101,110,62,49, +60,47,104,105,100,100,101,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,70,111,110,116,68,68,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,70,111,110,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,111,110,116,80,105,99,107,101,114,67,116,114,108,34,32,110,97,109, +101,61,34,112,105,99,107,101,114,70,111,110,116,68,68,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,103,65,103,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +105,100,100,101,110,62,49,60,47,104,105,100,100,101,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,77,97,120,82,111,119, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,120,105,109,117,109,32, +114,111,119,115,32,116,111,32,114,101,116,114,105,101,118,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,77,97,120,82, +111,119,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,49,48,48,60,47,118, +97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,77,97,120, +105,109,117,109,115,32,114,111,119,115,32,116,111,32,114,101,116,114,105, +101,118,101,32,105,110,116,111,32,111,117,116,112,117,116,32,119,105,110, +100,111,119,59,32,48,32,61,32,117,110,108,105,109,105,116,101,100,60,47, +116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108, +77,105,115,99,71,117,114,117,72,105,110,116,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,105,100,100,101,110,62,49, +60,47,104,105,100,100,101,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,117,112,112,114, +101,115,115,72,105,110,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,111,32, +110,111,116,32,115,104,111,119,32,103,117,114,117,32,104,105,110,116,115, +59,32,73,39,109,32,111,110,101,32,109,121,115,101,108,102,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,82,101,115,101,116,72,105, +110,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,115,101,116,32,103, +117,114,117,32,104,105,110,116,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,77,105,115,99,76,111,103,103,105,110,103,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,105,100,100,101, +110,62,49,60,47,104,105,100,100,101,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,76,111,103, +102,105,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76,111,103,102,105,108, +101,32,40,37,73,68,32,119,105,108,108,32,98,101,32,114,101,112,108,97,99, +101,100,32,119,105,116,104,32,116,104,101,32,80,114,111,99,101,115,115, +32,73,68,41,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,105, +108,101,80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101,61,34, +112,105,99,107,101,114,76,111,103,102,105,108,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,101, +115,115,97,103,101,62,83,101,108,101,99,116,32,108,111,103,32,102,105,108, +101,60,47,109,101,115,115,97,103,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,70,76,80,95,79,80,69,78,124,119,120,70,76,80,95,85,83,69,95,84,69,88, +84,67,84,82,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116, +105,112,62,69,110,116,101,114,32,97,32,102,105,108,101,110,97,109,101,32, +116,111,32,119,114,105,116,101,32,97,112,112,108,105,99,97,116,105,111, +110,32,108,111,103,115,32,116,111,46,60,47,116,111,111,108,116,105,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,111,120,34,32,110, +97,109,101,61,34,114,97,100,76,111,103,108,101,118,101,108,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,76,111,103,32,76,101,118,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +38,97,109,112,59,78,111,32,108,111,103,103,105,110,103,60,47,105,116,101, +109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,105,116,101,109,62,38,97,109,112,59,69,114,114,111,114, +115,32,111,110,108,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101, +109,62,69,114,114,111,114,115,32,97,110,100,32,78,38,97,109,112,59,111, +116,105,99,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,69,114,114,111,114,115,44,32,78,111,116,105,99,101,115,44,32,38,97,109, +112,59,83,81,76,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +38,97,109,112,59,68,101,98,117,103,32,40,110,111,116,32,114,101,99,111, +109,109,101,110,100,101,100,32,102,111,114,32,110,111,114,109,97,108,32, +117,115,101,41,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,101,108,101,99,116,105,111,110,62,50,60,47,115,101,108, +101,99,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,100,105,109,101,110,115,105,111,110,62, +49,60,47,100,105,109,101,110,115,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,82,65,95,83,80,69,67,73,70,89,95,67,79,76,83,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,116,111,111,108,116,105,112,62,83,101,108,101,99,116, +32,116,104,101,32,108,101,118,101,108,32,111,102,32,100,101,116,97,105, +108,32,116,111,32,114,101,99,111,114,100,32,105,110,32,116,104,101,32,108, +111,103,102,105,108,101,46,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116, +111,111,108,116,105,112,62,65,99,99,101,112,116,32,116,104,101,32,99,117, +114,114,101,110,116,32,115,101,116,116,105,110,103,115,32,97,110,100,32, +99,108,111,115,101,32,116,104,101,32,100,105,97,108,111,103,117,101,46, +60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,67, +97,110,99,101,108,32,97,110,121,32,99,104,97,110,103,101,115,32,97,110, +100,32,99,108,111,115,101,32,116,104,101,32,100,105,97,108,111,103,117, +101,46,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_79 = 1417; +static unsigned char xml_res_file_79[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,80,97,115,115,119,111,114,100,34,62,10,32,32,32,32, +60,116,105,116,108,101,62,67,104,97,110,103,101,32,80,97,115,115,119,111, +114,100,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101, +62,49,55,53,44,55,51,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84, +69,77,95,77,69,78,85,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,67,117,114,114, +101,110,116,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,67,117,114, +114,101,110,116,32,80,97,115,115,119,111,114,100,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,60,112,111,115,62,53,44,55,100,60,47,112,111,115, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,117,114,114,101,110, +116,34,62,10,32,32,32,32,32,32,60,112,111,115,62,55,48,44,53,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,60,115,105,122,101,62,49,48,48,44,45, +49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,80,65,83,83,87,79,82,68,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,78,101,119,34,62, +10,32,32,32,32,32,32,60,108,97,98,101,108,62,78,101,119,32,80,97,115,115, +119,111,114,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112, +111,115,62,53,44,50,50,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,78,101,119,34,62,10,32,32,32,32,32,32,60,112,111, +115,62,55,48,44,50,48,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60, +115,105,122,101,62,49,48,48,44,45,49,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,80,65,83,83,87, +79,82,68,60,47,115,116,121,108,101,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,108,98,108,67,111,110,102,105,114,109,34,62,10,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,111,110,102,105,114,109,32,80,97,115,115,119, +111,114,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111, +115,62,53,44,51,55,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,110,102,105,114,109,34,62,10,32,32,32,32,32,32, +60,112,111,115,62,55,48,44,51,53,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,60,115,105,122,101,62,49,48,48,44,45,49,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,80,65, +83,83,87,79,82,68,60,47,115,116,121,108,101,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,60,108,97,98, +101,108,62,38,97,109,112,59,72,101,108,112,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,60,112,111,115,62,53,44,53,53,100,60,47,112,111,115,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,112,111,115,62,54,51,44,53,53,100,60,47, +112,111,115,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60, +112,111,115,62,49,50,48,44,53,53,100,60,47,112,111,115,62,10,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62, +10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_80 = 5273; +static unsigned char xml_res_file_80[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,82,101,112,111,114,116,34,62,10,32,32,32,32,60,116, +105,116,108,101,62,71,101,110,101,114,97,116,101,32,97,32,114,101,112,111, +114,116,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101, +62,50,53,51,44,51,48,51,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,105,116,108,101,34, +62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,112,111,114,116, +32,84,105,116,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60, +112,111,115,62,53,44,53,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,84,105,116,108,101,34,62,10,32,32,32,32,32,32,60, +112,111,115,62,53,44,49,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +60,115,105,122,101,62,50,52,51,44,45,49,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,69,110,116,101,114, +32,97,32,116,105,116,108,101,32,102,111,114,32,116,104,101,32,114,101,112, +111,114,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,78,111,116,101,115,34,62,10,32,32,32,32,32,32, +60,108,97,98,101,108,62,82,101,112,111,114,116,32,78,111,116,101,115,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,53,44,51, +53,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116, +78,111,116,101,115,34,62,10,32,32,32,32,32,32,60,112,111,115,62,53,44,52, +53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,105,122,101,62, +50,52,51,44,52,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,69,95,65,85,84,79,95,83,67,82,79,76,76, +124,119,120,84,69,95,77,85,76,84,73,76,73,78,69,124,119,120,72,83,67,82, +79,76,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,69,110,116,101,114,32,97,110,121,32,97,100,100,105,116, +105,111,110,97,108,32,110,111,116,101,115,32,116,111,32,105,110,99,108, +117,100,101,32,111,110,32,116,104,101,32,114,101,112,111,114,116,60,47, +116,111,111,108,116,105,112,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +83,113,108,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,99, +108,117,100,101,32,116,104,101,32,83,81,76,32,105,110,32,116,104,101,32, +114,101,112,111,114,116,63,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,60,112,111,115,62,53,44,57,57,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,60,116,111,111,108,116,105,112,62,73,110,99,108,117,100,101,32,116, +104,101,32,83,81,76,32,102,114,111,109,32,116,104,101,32,111,98,106,101, +99,116,32,111,114,32,113,117,101,114,121,32,105,110,32,116,104,101,32,114, +101,112,111,114,116,63,60,47,116,111,111,108,116,105,112,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,111,120,34,32, +110,97,109,101,61,34,115,98,70,111,114,109,97,116,34,62,10,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,117,116,112,117,116,32,102,111,114,109, +97,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62, +53,44,49,49,51,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,105, +122,101,62,50,52,51,44,52,53,100,60,47,115,105,122,101,62,10,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,114,98,72,116,109,108,34,62,10,32,32,32, +32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,88,72,84,77,76,32,49, +46,48,32,84,114,97,110,115,105,116,105,111,110,97,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,118,97,108,117,101,62,49,60,47,118,97,108, +117,101,62,10,32,32,32,32,32,32,60,112,111,115,62,49,48,44,49,50,56,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,82,66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,60,116,111,111,108,116,105,112,62,67,114,101,97,116,101,32,116,104, +101,32,114,101,112,111,114,116,32,105,110,32,88,72,84,77,76,32,49,46,48, +32,84,114,97,110,115,105,116,105,111,110,97,108,32,102,111,114,109,97,116, +60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,114,98,88,109,108,34,62,10,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,88,77,76,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,60,118,97,108,117,101,62,49,60,47,118,97,108,117,101,62,10,32, +32,32,32,32,32,60,112,111,115,62,49,48,44,49,52,49,100,60,47,112,111,115, +62,10,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,67,114,101,97, +116,101,32,116,104,101,32,114,101,112,111,114,116,32,105,110,32,88,77,76, +32,102,111,114,109,97,116,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,111,120, +34,32,110,97,109,101,61,34,115,98,83,116,121,108,101,115,104,101,101,116, +34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,83,116,121,108,101,115, +104,101,101,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112, +111,115,62,53,44,49,54,51,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +60,115,105,122,101,62,50,52,51,44,55,53,100,60,47,115,105,122,101,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,114,98,72,116,109,108,66,117, +105,108,116,105,110,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,69,109,98,101,100,32,116,104,101,32,100,101,102,97,117, +108,116,32,115,116,121,108,101,115,104,101,101,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,118,97,108,117,101,62,49,60,47,118,97,108, +117,101,62,10,32,32,32,32,32,32,60,112,111,115,62,49,48,44,49,55,56,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,82,66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,60,116,111,111,108,116,105,112,62,69,109,98,101,100,32,112,103,65, +100,109,105,110,39,115,32,100,101,102,97,117,108,116,32,115,116,121,108, +101,115,104,101,101,116,32,105,110,116,111,32,116,104,101,32,114,101,112, +111,114,116,46,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,114,98,72,116,109,108,69,109,98,101,100,34,62,10, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,69,109,98,101, +100,32,97,110,32,101,120,116,101,114,110,97,108,32,115,116,121,108,101, +115,104,101,101,116,32,40,115,112,101,99,105,102,105,101,100,32,102,105, +108,101,32,109,117,115,116,32,101,120,105,115,116,41,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,112,111,115,62,49,48,44,49,57,49,100,60, +47,112,111,115,62,10,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62, +69,109,98,101,100,32,97,110,32,101,120,116,101,114,110,97,108,32,115,116, +121,108,101,115,104,101,101,116,32,105,110,116,111,32,116,104,101,32,114, +101,112,111,114,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,114,98,72,116,109,108,76,105,110,107,34, +62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,76,105, +110,107,32,116,111,32,97,110,32,101,120,116,101,114,110,97,108,32,115,116, +121,108,101,115,104,101,101,116,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,60,112,111,115,62,49,48,44,50,48,52,100,60,47,112,111,115,62,10, +32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,73,110,99,108,117,100, +101,32,97,32,108,105,110,107,32,116,111,32,97,110,32,101,120,116,101,114, +110,97,108,32,115,116,121,108,101,115,104,101,101,116,32,105,110,32,116, +104,101,32,114,101,112,111,114,116,46,60,47,116,111,111,108,116,105,112, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,114,98,88,109,108,80, +108,97,105,110,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97, +109,112,59,68,111,32,110,111,116,32,117,115,101,32,97,32,115,116,121,108, +101,115,104,101,101,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +60,118,97,108,117,101,62,49,60,47,118,97,108,117,101,62,10,32,32,32,32, +32,32,60,112,111,115,62,49,48,44,49,55,56,100,60,47,112,111,115,62,10,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,60,116,111,111,108,116, +105,112,62,68,111,32,110,111,116,32,117,115,101,32,97,32,115,116,121,108, +101,115,104,101,101,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,114,98,88,109,108,76,105,110,107,34,62,10, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,76,105,110,107, +32,116,111,32,97,110,32,101,120,116,101,114,110,97,108,32,115,116,121,108, +101,115,104,101,101,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +60,112,111,115,62,49,48,44,49,57,49,100,60,47,112,111,115,62,10,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,73,110,99,108,117,100,101,32, +97,32,108,105,110,107,32,116,111,32,116,104,101,32,115,112,101,99,105,102, +105,101,100,32,115,116,121,108,101,115,104,101,101,116,32,105,110,32,116, +104,101,32,88,77,76,32,102,105,108,101,60,47,116,111,111,108,116,105,112, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,114,98,88,109,108,80, +114,111,99,101,115,115,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,88,83,76,84,32,80,114,111,99,101,115,115,32,116,104, +101,32,88,77,76,32,100,97,116,97,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,60,112,111,115,62,49,48,44,50,48,52,100,60,47,112,111,115,62,10, +32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,80,114,111,99,101,115, +115,32,116,104,101,32,88,77,76,32,100,97,116,97,32,117,115,105,110,103, +32,116,104,101,32,115,112,101,99,105,102,105,101,100,32,115,116,121,108, +101,115,104,101,101,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,83,116,121,108,101,115,104,101,101,116, +34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,110,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115, +62,49,48,44,50,50,51,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,72,116,109,108,83,116,121,108,101,115,104,101,101, +116,34,62,10,32,32,32,32,32,32,60,112,111,115,62,54,48,44,50,50,48,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,105,122,101,62,49,54,50, +44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,83,101,108,101,99,116,32,116,104,101,32,115,116,121, +108,101,115,104,101,101,116,32,116,111,32,117,115,101,46,60,47,116,111, +111,108,116,105,112,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,88, +109,108,83,116,121,108,101,115,104,101,101,116,34,62,10,32,32,32,32,32, +32,60,112,111,115,62,54,48,44,50,50,48,100,60,47,112,111,115,62,10,32,32, +32,32,32,32,60,115,105,122,101,62,49,54,50,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,83,101,108, +101,99,116,32,116,104,101,32,115,116,121,108,101,115,104,101,101,116,32, +116,111,32,117,115,101,46,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110, +97,109,101,61,34,98,116,110,83,116,121,108,101,115,104,101,101,116,34,62, +10,32,32,32,32,32,32,60,108,97,98,101,108,62,46,46,46,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,112,111,115,62,50,50,55,44,50,50,48,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,105,122,101,62,49,53,44, +45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,83,101,108,101,99,116,32,116,104,101,32,115,116,121, +108,101,115,104,101,101,116,32,116,111,32,117,115,101,46,60,47,116,111, +111,108,116,105,112,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +70,105,108,101,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,79,117, +116,112,117,116,32,102,105,108,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,60,112,111,115,62,53,44,50,52,56,100,60,47,112,111,115,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,72,116,109,108,70,105,108,101, +34,62,10,32,32,32,32,32,32,60,112,111,115,62,53,53,44,50,52,53,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,60,115,105,122,101,62,49,55,53,44,45, +49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,116,111,111,108, +116,105,112,62,83,101,108,101,99,116,32,116,104,101,32,102,105,108,101, +32,116,111,32,119,114,105,116,101,32,116,104,101,32,114,101,112,111,114, +116,32,116,111,46,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,88,109,108,70,105,108,101,34,62,10,32,32,32, +32,32,32,60,112,111,115,62,53,53,44,50,52,53,100,60,47,112,111,115,62,10, +32,32,32,32,32,32,60,115,105,122,101,62,49,55,53,44,45,49,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,83, +101,108,101,99,116,32,116,104,101,32,102,105,108,101,32,116,111,32,119, +114,105,116,101,32,116,104,101,32,114,101,112,111,114,116,32,116,111,46, +60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116, +110,70,105,108,101,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,46, +46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62, +50,51,53,44,50,52,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60,115, +105,122,101,62,49,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,83,101,108,101,99,116,32,116, +104,101,32,102,105,108,101,32,116,111,32,119,114,105,116,101,32,116,104, +101,32,114,101,112,111,114,116,32,116,111,46,60,47,116,111,111,108,116, +105,112,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,66,114,111,119, +115,101,114,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,101, +110,32,116,104,101,32,111,117,116,112,117,116,32,102,105,108,101,32,105, +110,32,116,104,101,32,100,101,102,97,117,108,116,32,98,114,111,119,115, +101,114,63,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115, +62,53,44,50,54,53,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,60,112,111,115,62,50,44,50,56,53,100,60,47,112,111,115,62, +10,32,32,32,32,32,32,60,115,116,121,108,101,47,62,10,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,60,112,111,115,62,49,52,55,44,50,56,53,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,116,121,108,101,47,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,60,112,111,115,62,50,48,48,44,50,56,53,100,60,47,112,111,115,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101, +99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_81 = 16296; +static unsigned char xml_res_file_81[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,82,101,115,116,111,114,101,34,62,10,32,32,32,32,60, +116,105,116,108,101,62,82,101,115,116,111,114,101,60,47,116,105,116,108, +101,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,49,57,51,100,60, +47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120, +68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120, +67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119, +120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98, +108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110, +98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,112,111,115,62,50,44,50,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,50,56,53,44,49,56,52,100,60,47,115,105, +122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,78,66,95,66,79,84,84,79,77,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,32,79,112,116, +105,111,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, +97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,70,105,108,101,79, +112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,70,111,114,109,97,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,70,111,114,109,97,116,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,70,111,114,109,97,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,105,108,101,110,97, +109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,70,105,108,101,110,97,109,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70, +105,108,101,110,97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,70,105,108,101,110,97,109,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,46,46,46,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +78,117,109,98,101,114,79,102,74,111,98,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,117,109, +98,101,114,32,79,102,32,74,111,98,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,117,109, +98,101,114,79,102,74,111,98,115,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,82,111,108, +101,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,82,111,108,101,110,97,109,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,82,111,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68, +79,87,78,124,119,120,67,66,95,83,79,82,84,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111, +116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,82,101,115,116,111,114,101,32,79,112, +116,105,111,110,115,32,35,49,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68, +117,109,112,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,99,116,105, +111,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69, +82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,83,101,99,116,105,111,110,80, +114,101,68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,101,45,100, +97,116,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,101,99,116, +105,111,110,68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,116,97,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,101,99,116,105, +111,110,80,111,115,116,68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80, +111,115,116,45,100,97,116,97,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101, +32,79,102,32,79,98,106,101,99,116,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101, +110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,79,110, +108,121,68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,110,108,121,32, +100,97,116,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,79,110, +108,121,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,110,108, +121,32,115,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,111,110,39, +116,32,115,97,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119, +120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,78,111,79,119,110, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110,101,114,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,78,111,80,114,105,118,105, +108,101,103,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,105,118,105, +108,101,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,78,111, +84,97,98,108,101,115,112,97,99,101,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +84,97,98,108,101,115,112,97,99,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,115, +116,111,114,101,32,79,112,116,105,111,110,115,32,35,50,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,68,117,109,112,79,112,116,105,111,110,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,66,111,120,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,81,117,101,114,105,101,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101, +110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,67,114, +101,97,116,101,68,98,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,99,108,117, +100,101,32,67,82,69,65,84,69,32,68,65,84,65,66,65,83,69,32,115,116,97,116, +101,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,67,108,101,97,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,108,101,97,110, +32,98,101,102,111,114,101,32,114,101,115,116,111,114,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,83,105,110,103,108,101,88,97, +99,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,83,105,110,103,108,101,32,116,114, +97,110,115,97,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,105,115,97, +98,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69, +82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,68,105,115,97,98,108,101,84,114, +105,103,103,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,114,105,103,103, +101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,78,111,68,97, +116,97,70,111,114,70,97,105,108,101,100,84,97,98,108,101,115,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,111,32,68,97,116,97,32,102,111,114,32,70,97,105, +108,101,100,32,84,97,98,108,101,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,105,115,99, +101,108,108,97,110,111,117,115,32,47,32,66,101,104,97,118,105,111,114,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73, +67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,85,115,101,83,101,116,83,101,115, +115,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,32,83,69,84, +32,83,69,83,83,73,79,78,32,65,85,84,72,79,82,73,90,65,84,73,79,78,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,69,120,105,116,79,110,69, +114,114,111,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,120,105,116,32,79,110, +32,69,114,114,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,86,101,114,98,111,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,101,114, +98,111,115,101,32,109,101,115,115,97,103,101,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,79,98,106,101,99,116,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +99,116,108,67,104,101,99,107,84,114,101,101,86,105,101,119,34,32,110,97, +109,101,61,34,99,116,118,79,98,106,101,99,116,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,82,95, +72,65,83,95,66,85,84,84,79,78,83,124,119,120,83,73,77,80,76,69,95,66,79, +82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,77,101,115,115,97,103,101,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,116,120,116,77,101,115,115,97,103,101,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84, +69,95,77,85,76,84,73,76,73,78,69,124,119,120,84,69,95,82,69,65,68,79,78, +76,89,124,119,120,72,83,67,82,79,76,76,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68, +124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,53,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,86,105,101,119,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,68,105,115,112,108,97,121,32,111,98,106,101,99,116,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,116,111,111,108,116,105,112,62,68,105,115,112,108,97,121,32,111,98,106, +101,99,116,115,32,99,111,110,116,97,105,110,101,100,32,105,110,32,116,104, +101,32,100,117,109,112,32,111,110,32,97,32,115,112,101,99,105,102,105,99, +32,116,97,98,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,82,101, +115,116,111,114,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,71,82,79,87,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99, +116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +void InitXmlResource() +{ + + // Check for memory FS. If not present, load the handler: + { + wxMemoryFSHandler::AddFile(wxT("XRC_resource/dummy_file"), wxT("dummy one")); + wxFileSystem fsys; + wxFSFile *f = fsys.OpenFile(wxT("memory:XRC_resource/dummy_file")); + wxMemoryFSHandler::RemoveFile(wxT("XRC_resource/dummy_file")); + if (f) delete f; + else wxFileSystem::AddHandler(new wxMemoryFSHandler); + } + + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._ddPrecisionScaleDialog.xrc"), xml_res_file_0, xml_res_size_0, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._ddTableNameDialog.xrc"), xml_res_file_1, xml_res_size_1, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgAddFavourite.xrc"), xml_res_file_2, xml_res_size_2, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgAggregate.xrc"), xml_res_file_3, xml_res_size_3, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgCast.xrc"), xml_res_file_4, xml_res_size_4, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgCheck.xrc"), xml_res_file_5, xml_res_size_5, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgCollation.xrc"), xml_res_file_6, xml_res_size_6, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgColumn.xrc"), xml_res_file_7, xml_res_size_7, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgConnect.xrc"), xml_res_file_8, xml_res_size_8, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgConversion.xrc"), xml_res_file_9, xml_res_size_9, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgDatabase.xrc"), xml_res_file_10, xml_res_size_10, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgDirectDbg.xrc"), xml_res_file_11, xml_res_size_11, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgDomain.xrc"), xml_res_file_12, xml_res_size_12, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgEditGridOptions.xrc"), xml_res_file_13, xml_res_size_13, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgEventTrigger.xrc"), xml_res_file_14, xml_res_size_14, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgExtension.xrc"), xml_res_file_15, xml_res_size_15, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgExtTable.xrc"), xml_res_file_16, xml_res_size_16, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgFindReplace.xrc"), xml_res_file_17, xml_res_size_17, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgForeignDataWrapper.xrc"), xml_res_file_18, xml_res_size_18, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgForeignKey.xrc"), xml_res_file_19, xml_res_size_19, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgForeignServer.xrc"), xml_res_file_20, xml_res_size_20, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgForeignTable.xrc"), xml_res_file_21, xml_res_size_21, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgFunction.xrc"), xml_res_file_22, xml_res_size_22, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgGroup.xrc"), xml_res_file_23, xml_res_size_23, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgHbaConfig.xrc"), xml_res_file_24, xml_res_size_24, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgIndex.xrc"), xml_res_file_25, xml_res_size_25, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgIndexConstraint.xrc"), xml_res_file_26, xml_res_size_26, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgJob.xrc"), xml_res_file_27, xml_res_size_27, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgLanguage.xrc"), xml_res_file_28, xml_res_size_28, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgMainConfig.xrc"), xml_res_file_29, xml_res_size_29, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgManageFavourites.xrc"), xml_res_file_30, xml_res_size_30, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgManageMacros.xrc"), xml_res_file_31, xml_res_size_31, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgMoveTablespace.xrc"), xml_res_file_32, xml_res_size_32, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgOperator.xrc"), xml_res_file_33, xml_res_size_33, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgPackage.xrc"), xml_res_file_34, xml_res_size_34, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgPgpassConfig.xrc"), xml_res_file_35, xml_res_size_35, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgReassignDropOwned.xrc"), xml_res_file_36, xml_res_size_36, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgRepCluster.xrc"), xml_res_file_37, xml_res_size_37, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgRepClusterUpgrade.xrc"), xml_res_file_38, xml_res_size_38, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgRepListen.xrc"), xml_res_file_39, xml_res_size_39, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgRepNode.xrc"), xml_res_file_40, xml_res_size_40, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgRepPath.xrc"), xml_res_file_41, xml_res_size_41, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgRepSequence.xrc"), xml_res_file_42, xml_res_size_42, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgRepSet.xrc"), xml_res_file_43, xml_res_size_43, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgRepSetMerge.xrc"), xml_res_file_44, xml_res_size_44, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgRepSetMove.xrc"), xml_res_file_45, xml_res_size_45, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgRepSubscription.xrc"), xml_res_file_46, xml_res_size_46, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgRepTable.xrc"), xml_res_file_47, xml_res_size_47, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgResourceGroup.xrc"), xml_res_file_48, xml_res_size_48, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgRole.xrc"), xml_res_file_49, xml_res_size_49, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgRule.xrc"), xml_res_file_50, xml_res_size_50, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgSchedule.xrc"), xml_res_file_51, xml_res_size_51, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgSchema.xrc"), xml_res_file_52, xml_res_size_52, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgSearchObject.xrc"), xml_res_file_53, xml_res_size_53, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgSelectConnection.xrc"), xml_res_file_54, xml_res_size_54, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgSequence.xrc"), xml_res_file_55, xml_res_size_55, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgServer.xrc"), xml_res_file_56, xml_res_size_56, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgStep.xrc"), xml_res_file_57, xml_res_size_57, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgSynonym.xrc"), xml_res_file_58, xml_res_size_58, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgTable.xrc"), xml_res_file_59, xml_res_size_59, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgTablespace.xrc"), xml_res_file_60, xml_res_size_60, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgTextSearchConfiguration.xrc"), xml_res_file_61, xml_res_size_61, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgTextSearchDictionary.xrc"), xml_res_file_62, xml_res_size_62, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgTextSearchParser.xrc"), xml_res_file_63, xml_res_size_63, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgTextSearchTemplate.xrc"), xml_res_file_64, xml_res_size_64, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgTrigger.xrc"), xml_res_file_65, xml_res_size_65, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgType.xrc"), xml_res_file_66, xml_res_size_66, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgUser.xrc"), xml_res_file_67, xml_res_size_67, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgUserMapping.xrc"), xml_res_file_68, xml_res_size_68, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgView.xrc"), xml_res_file_69, xml_res_size_69, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._frmBackup.xrc"), xml_res_file_70, xml_res_size_70, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._frmBackupGlobals.xrc"), xml_res_file_71, xml_res_size_71, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._frmBackupServer.xrc"), xml_res_file_72, xml_res_size_72, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._frmExport.xrc"), xml_res_file_73, xml_res_size_73, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._frmGrantWizard.xrc"), xml_res_file_74, xml_res_size_74, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._frmHint.xrc"), xml_res_file_75, xml_res_size_75, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._frmImport.xrc"), xml_res_file_76, xml_res_size_76, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._frmMaintenance.xrc"), xml_res_file_77, xml_res_size_77, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._frmOptions.xrc"), xml_res_file_78, xml_res_size_78, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._frmPassword.xrc"), xml_res_file_79, xml_res_size_79, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._frmReport.xrc"), xml_res_file_80, xml_res_size_80, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._frmRestore.xrc"), xml_res_file_81, xml_res_size_81, wxT("text/xml")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._ddPrecisionScaleDialog.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._ddTableNameDialog.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgAddFavourite.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgAggregate.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgCast.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgCheck.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgCollation.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgColumn.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgConnect.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgConversion.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgDatabase.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgDirectDbg.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgDomain.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgEditGridOptions.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgEventTrigger.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgExtension.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgExtTable.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgFindReplace.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgForeignDataWrapper.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgForeignKey.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgForeignServer.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgForeignTable.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgFunction.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgGroup.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgHbaConfig.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgIndex.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgIndexConstraint.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgJob.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgLanguage.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgMainConfig.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgManageFavourites.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgManageMacros.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgMoveTablespace.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgOperator.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgPackage.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgPgpassConfig.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgReassignDropOwned.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgRepCluster.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgRepClusterUpgrade.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgRepListen.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgRepNode.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgRepPath.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgRepSequence.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgRepSet.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgRepSetMerge.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgRepSetMove.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgRepSubscription.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgRepTable.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgResourceGroup.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgRole.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgRule.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgSchedule.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgSchema.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgSearchObject.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgSelectConnection.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgSequence.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgServer.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgStep.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgSynonym.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgTable.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgTablespace.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgTextSearchConfiguration.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgTextSearchDictionary.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgTextSearchParser.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgTextSearchTemplate.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgTrigger.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgType.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgUser.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgUserMapping.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgView.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._frmBackup.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._frmBackupGlobals.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._frmBackupServer.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._frmExport.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._frmGrantWizard.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._frmHint.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._frmImport.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._frmMaintenance.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._frmOptions.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._frmPassword.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._frmReport.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._frmRestore.xrc")); +} diff --git a/utils/csvfiles.cpp b/utils/csvfiles.cpp new file mode 100644 index 0000000..6b03ede --- /dev/null +++ b/utils/csvfiles.cpp @@ -0,0 +1,142 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// csvfiles.cpp - CSV file parsing +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" +#include "utils/sysLogger.h" +#include "utils/csvfiles.h" + +// PostgreSQL and GPDB now support CSV format logs. +// So, we need a way to parse the CSV files into lines, and lines into tokens (fields). + +bool CSVTokenizer::HasMoreTokens() const +{ + if ( m_string.length() > 0) + { + if ( m_pos >= m_string.length()) + return false; + + if ( m_string.find_first_not_of(wxT(','), m_pos) != wxString::npos ) + // there are non delimiter characters left, so we do have more tokens + return true; + + if (m_string[m_pos] == wxT('\n')) + return false; + } + return m_pos == 0 && !m_string.empty(); +} + +wxString CSVTokenizer::GetNextToken() +{ + wxString token; + + if ( !HasMoreTokens() ) + return token; + + // skip leading blanks if not quoted. + while (m_pos < m_string.length() && m_string[m_pos] == wxT(' ')) + m_pos ++; + + // Are we a quoted field? Must handle this special. + bool quoted_string = (m_string[m_pos] == wxT('\"')); + bool inquote = false; + + size_t pos = m_pos; + + // find the end of this token. + for (; pos < m_string.length(); pos++) + { + if (quoted_string && m_string[pos] == wxT('\"')) + inquote = !inquote; + + if (!inquote) + { + // Check to see if we have found the end of this token. + // Tokens normally end with a ',' delimiter. + if (m_string[pos] == wxT(',')) + break; + + // Last token is delimited by '\n' or by end of string. + if (m_string[pos] == wxT('\n') && pos == m_string.length() - 1) + break; + } + } + + if (quoted_string && !inquote) + { + token.assign(m_string, m_pos + 1, pos - m_pos - 2); // Remove leading and trailing quotes + + // Remove double doublequote chars, replace with single doublequote chars + token.Replace(wxT("\"\""), wxT("\""), true); + } + else + token.assign(m_string, m_pos, pos - m_pos); + + if (quoted_string && inquote) + { + wxLogNotice(wxT("unterminated double quoted string: %s\n"), token.c_str()); + } + + m_pos = pos + 1; // Skip token and delimiter + + if (m_pos > m_string.length()) // Perhaps no delimiter if at end of string if orig string didn't have '\n'. + m_pos = m_string.length(); + + return token; +} + +bool CSVLineTokenizer::HasMoreLines() const +{ + if ( m_string.find_first_not_of(wxT('\n'), m_pos) != wxString::npos ) + // there are non line-end characters left, so we do have more lines + return true; + return false; +} + +wxString CSVLineTokenizer::GetNextLine(bool &partial) +{ + wxString token; + partial = true; + + if ( !HasMoreLines() ) + return token; + + // find the end of this line. CSV lines end in "\n", but + // CSV lines may have "\n" chars inside double-quoted strings, so we need to find that out. + + bool inquote = false; + for (size_t pos = m_pos; pos < m_string.length(); pos++) + { + if (m_string[pos] == wxT('\"')) + inquote = !inquote; + + if (m_string[pos] == wxT('\n') && !inquote) + { + // Good, we found a complete log line terminated + // by "\n", and the "\n" wasn't in a quoted string. + + size_t len = pos - m_pos + 1; // return the line, including the trailing "\n" + token.assign(m_string, m_pos, len); + m_pos = pos + 1; // point to next line. + partial = false; + return token; + } + } + + // no more delimiters, so the line is everything till the end of + // string, but we don't have all of the CSV the line... Some must still be coming. + + token.assign(m_string, m_pos, wxString::npos); + partial = true; + + m_pos = m_string.length(); + + return token; +} diff --git a/utils/factory.cpp b/utils/factory.cpp new file mode 100644 index 0000000..d5fe6fe --- /dev/null +++ b/utils/factory.cpp @@ -0,0 +1,428 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// factory.cpp - Object classes factory +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +#include "ctl/ctlMenuToolbar.h" +#include "schema/pgCollection.h" +#include "frm/menu.h" + +// wxWindows headers +#include + +wxArrayPtrVoid *factoryArray = 0; + +#define FACTORY_OFFSET 100 + +pgaFactory::pgaFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm) +{ + if (!factoryArray) + factoryArray = new wxArrayPtrVoid; + id = factoryArray->GetCount() + FACTORY_OFFSET; + factoryArray->Add(this); + collectionFactory = 0; + smallIconId = -1; + typeName = (wxChar *)tn; + if (ns) + newString = (wxChar *)ns; + else + newString = typeName; + if (nls) + newLongString = (wxChar *)nls; + else + newLongString = newString; + metaType = PGM_UNKNOWN; + + if (img && img->IsOk()) + { + image = *img; + iconId = addIcon(img); + if (imgSm && imgSm->IsOk()) + smallIconId = addIcon(imgSm); + } + else + iconId = -1; +} + + +bool pgaFactory::WantSmallIcon() +{ +#ifdef __WXMSW__ + return true; +#else + return false; +#endif +} + +int pgaFactory::GetIconId() +{ + if (WantSmallIcon() && smallIconId >= 0) + return smallIconId; + + return iconId; +} + +pgaFactory *pgaFactory::GetFactory(int id) +{ + id -= FACTORY_OFFSET; + if (id >= 0 && id < (int)factoryArray->GetCount()) + return (pgaFactory *)factoryArray->Item(id);; + + return 0; +} + + +pgaFactory *pgaFactory::GetFactory(const wxString &name) +{ + int i; + pgaFactory *factory; + + for (i = FACTORY_OFFSET ; (factory = GetFactory(i)) != 0 ; i++) + { + if (name.Matches(factory->GetTypeName())) + return factory; + } + return 0; +} + +pgaFactory *pgaFactory::GetFactoryByMetaType(const int type) +{ + int i; + pgaFactory *factory; + + for (i = FACTORY_OFFSET ; (factory = GetFactory(i)) != 0 ; i++) + { + if (factory->GetMetaType() == type) + return factory; + } + return 0; +} + + +#include "images/property.pngc" +#include "images/statistics.pngc" + +wxArrayPtrVoid *deferredImagesArray = 0; + +int pgaFactory::addIcon(wxImage *img) +{ + if (!imageList) + { + if (!deferredImagesArray) + { + //Setup the global imagelist + deferredImagesArray = new wxArrayPtrVoid; + + deferredImagesArray->Add(property_png_img); + deferredImagesArray->Add(statistics_png_img); + } + + deferredImagesArray->Add(img); + + return deferredImagesArray->GetCount() - 1; + } + else + { + wxBitmap bmp(*img); + wxIcon *ico = new wxIcon(); + ico->CopyFromBitmap(bmp); + return imageList->Add(*ico); + } +} + +void pgaFactory::RealizeImages() +{ + if (!imageList && deferredImagesArray) + { + imageList = new wxImageList(16, 16, true, deferredImagesArray->GetCount()); + size_t i; + for (i = 0 ; i < deferredImagesArray->GetCount() ; i++) + { + wxImage *img = (wxImage *)deferredImagesArray->Item(i); + wxBitmap bmp(*img); + wxIcon *ico = new wxIcon(); + ico->CopyFromBitmap(bmp); + imageList->Add(*ico); + } + + delete deferredImagesArray; + deferredImagesArray = 0; + } +} + +void pgaFactory::RegisterMenu(wxWindow *w, wxObjectEventFunction func) +{ + w->Connect(GetFactory(FACTORY_OFFSET)->GetId() + MNU_NEW, + GetFactory(factoryArray->GetCount() + FACTORY_OFFSET - 1)->GetId() + MNU_NEW, + wxEVT_COMMAND_MENU_SELECTED, func); +} + + +void pgaFactory::AppendMenu(wxMenu *menu) +{ + if (menu && GetNewString()) + { + wxMenuItem *item = menu->Append(MNU_NEW + GetId(), wxGetTranslation(GetNewString()), wxGetTranslation(GetNewLongString())); + if (image.IsOk()) + { + (void)item; + // doesn't work? + // item->SetBitmap(wxBitmap(image)); + } + } +} + + +int pgaFactory::GetMetaType() +{ + if (IsCollection()) + return ((pgaCollectionFactory *)this)->GetItemFactory()->GetMetaType(); + return metaType; +} + + +pgaCollectionFactory::pgaCollectionFactory(pgaFactory *f, const wxChar *tn, wxImage *img, wxImage *imgSm) + : pgaFactory(tn, f->GetNewString(), f->GetNewLongString()) +{ + itemFactory = f; + f->collectionFactory = this; + if (img && img->IsOk()) + { + image = *img; + iconId = addIcon(img); + if (imgSm && imgSm->IsOk()) + smallIconId = addIcon(imgSm); + } + else + iconId = f->GetIconId(); +} + + +pgObject *pgaCollectionFactory::CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr) +{ + if (itemFactory) + return itemFactory->CreateObjects(obj, browser, restr); + return 0; +} + + +dlgProperty *pgaCollectionFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + if (itemFactory) + return itemFactory->CreateDialog(frame, node, parent); + return 0; +} + + +//////////////////////////////////////////////// + + +menuFactoryList::~menuFactoryList() +{ + while (GetCount()) + { + delete (menuFactory *)Item(0); + RemoveAt(0); + } +} + +actionFactory *menuFactoryList::GetFactory(int id, bool actionOnly) +{ + id -= MNU_ACTION; + if (id >= 0 && id < (int)GetCount()) + { + actionFactory *f = (actionFactory *)Item(id); + if (f->IsAction() || !actionOnly) + return f; + } + return 0; +} + + +void menuFactoryList::RegisterMenu(wxWindow *w, wxObjectEventFunction func) +{ + w->Connect(MNU_ACTION, MNU_ACTION + GetCount() - 1, + wxEVT_COMMAND_MENU_SELECTED, func); +} + + +void menuFactoryList::CheckMenu(pgObject *obj, wxMenuBar *menubar, ctlMenuToolbar *toolbar) +{ + size_t id; + for (id = MNU_ACTION ; id < GetCount() + MNU_ACTION ; id++) + { + actionFactory *f = GetFactory(id); + if (f) + { + bool how = f->CheckEnable(obj); + if (menubar->FindItem(id)) + menubar->Enable(id, how); + if (toolbar) + toolbar->EnableTool(id, how); + + bool chk = f->CheckChecked(obj); + wxMenuItem *itm = menubar->FindItem(id); + if (itm && itm->IsCheckable()) + menubar->Check(id, chk); + } + } + for (id = 0 ; id < GetCount() ; id++) + { + actionFactory *f = (actionFactory *)Item(id); + if (f->IsSubmenu()) + EnableSubmenu(menubar, id + MNU_ACTION); + } +} + + +void menuFactoryList::EnableSubmenu(wxMenuBar *menuBar, int id) +{ + wxMenuItem *item = menuBar->FindItem(id); + if (item) + { + wxMenu *menu = item->GetSubMenu(); + wxASSERT(menu); + if (!menu) + return; + + size_t position; + for (position = 0 ; position < menu->GetMenuItemCount() ; position++) + { + item = menu->FindItemByPosition(position); + if (item && item->IsEnabled()) + { + menuBar->Enable(id, true); + return; + } + } + + menuBar->Enable(id, false); + } +} + + +void menuFactoryList::AppendEnabledMenus(wxMenuBar *menuBar, wxMenu *treeContextMenu) +{ + size_t id; + wxMenuItem *lastItem = 0; + for (id = MNU_ACTION ; id < GetCount() + MNU_ACTION ; id++) + { + actionFactory *f = GetFactory(id, false); + if (f->IsAction()) + { + if (f->GetContext()) + { + wxMenuItem *menuItem = menuBar->FindItem(id); + if (menuItem && menuItem->IsEnabled()) + { + if (!menuItem->IsSubMenu()) + { +#if wxCHECK_VERSION(2, 9, 0) + wxString lab = menuItem->GetItemLabelText(); +#else + wxString lab = menuItem->GetLabel(); // deprecated +#endif + lastItem = treeContextMenu->Append(id, lab, menuItem->GetHelp(), menuItem->IsCheckable() ? wxITEM_CHECK : wxITEM_NORMAL); + if (menuItem->IsCheckable() && menuItem->IsChecked()) + treeContextMenu->FindItem(id)->Check(); + } + else + { + /* Copy of submenu */ + wxMenu *oldSubMenu = menuItem->GetSubMenu(); + wxMenu *newSubMenu = new wxMenu(); + + size_t i; + int itemCount = 0; + wxMenuItem *singleMenuItem = 0; + for (i = 0; i < oldSubMenu->GetMenuItemCount(); i++) + { + wxMenuItem *oldMenuItem = oldSubMenu->FindItemByPosition(i); + if (oldMenuItem->IsEnabled()) + { +#if wxCHECK_VERSION(2, 9, 0) + wxString oldLab = oldMenuItem->GetItemLabelText(); +#else + wxString oldLab = oldMenuItem->GetLabel(); // deprecated +#endif + newSubMenu->Append(oldMenuItem->GetId(), oldLab, oldMenuItem->GetHelp(), menuItem->IsCheckable() ? wxITEM_CHECK : wxITEM_NORMAL); + if (oldMenuItem->IsCheckable() && oldMenuItem->IsChecked()) + newSubMenu->FindItem(oldMenuItem->GetId())->Check(); + + itemCount++; + singleMenuItem = oldMenuItem; + } + } + if (itemCount > 1) + { +#if wxCHECK_VERSION(2, 9, 0) + wxString lab = menuItem->GetItemLabelText(); +#else + wxString lab = menuItem->GetLabel(); // deprecated +#endif + lastItem = treeContextMenu->Append(id, lab, newSubMenu); + } + else + { + delete newSubMenu; + if (itemCount) + { +#if wxCHECK_VERSION(2, 9, 0) + wxString lab = singleMenuItem->GetItemLabelText(); +#else + wxString lab = singleMenuItem->GetLabel(); // deprecated +#endif + lastItem = treeContextMenu->Append(singleMenuItem->GetId(), lab, singleMenuItem->GetHelp(), menuItem->IsCheckable() ? wxITEM_CHECK : wxITEM_NORMAL); + if (singleMenuItem->IsCheckable() && singleMenuItem->IsChecked()) + treeContextMenu->FindItem(singleMenuItem->GetId())->Check(); + } + } + } + } + } + } + else + { + if (lastItem && lastItem->GetId() >= 0) + lastItem = treeContextMenu->AppendSeparator(); + } + } + + if (lastItem && lastItem->GetId() < 0) + { + treeContextMenu->Remove(lastItem); + delete lastItem; + } +} + + +menuFactory::menuFactory(menuFactoryList *list) +{ + if (list) + list->Add(this); +} + +menuFactory::~menuFactory() +{ +} + +actionFactory::actionFactory(menuFactoryList *list) : menuFactory(list) +{ + if (list) + id = list->GetCount() + MNU_ACTION - 1; + else + id = 0; + context = false; +} + + + diff --git a/utils/favourites.cpp b/utils/favourites.cpp new file mode 100644 index 0000000..52dde1b --- /dev/null +++ b/utils/favourites.cpp @@ -0,0 +1,359 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// favourites.cpp - Query favourites +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +#include "pgAdmin3.h" +#include "utils/favourites.h" +#include "utils/sysSettings.h" + +#include + +// +// libxml convenience macros +// +#define XML_FROM_WXSTRING(s) ((const xmlChar *)(const char *)s.mb_str(wxConvUTF8)) +#define WXSTRING_FROM_XML(s) wxString((char *)s, wxConvUTF8) +#define XML_STR(s) ((const xmlChar *)s) + +// +// libxml convenience function +// +static void SkipToEndElement(xmlTextReaderPtr reader) +{ + while (xmlTextReaderRead(reader) == 1) + { + if (xmlTextReaderNodeType(reader) == 15) + return; + } +} + + +// +// queryFavouriteItem - base class representing a single favourite item, or +// acting as the base for folders. +// +queryFavouriteItem::queryFavouriteItem(const wxString newtitle, const wxString newcontents) +{ + title = newtitle; + contents = newcontents; + id = -1; +} + +void queryFavouriteItem::AppendToMenu(wxMenu *menu, int newid) +{ + id = newid; + menu->Append(id, title); +} + + +// +// queryFavouriteFolder - represents a folder containing zero or more favourites +// +queryFavouriteFolder::queryFavouriteFolder(wxString title) : queryFavouriteItem(title, wxT("")) +{ + id = -2; +} + +queryFavouriteFolder::queryFavouriteFolder(xmlTextReaderPtr reader, wxString title) : queryFavouriteItem(title, wxT("")) +{ + id = -2; + + // Element of type , meaning empty folder + if (xmlTextReaderIsEmptyElement(reader)) + return; + + while (xmlTextReaderRead(reader)) + { + int type = xmlTextReaderNodeType(reader); + + if (type == 15) + return; // Close on parent element + if (xmlTextReaderNodeType(reader) != 1) + continue; // Any unknown element type + + wxString nodename = WXSTRING_FROM_XML(xmlTextReaderConstName(reader)); + + xmlChar *ctitle = xmlTextReaderGetAttribute(reader, XML_STR("title")); + if (!ctitle) + continue; // We ignore nodes without title + wxString title = WXSTRING_FROM_XML(ctitle); + xmlFree(ctitle); + + if (nodename == wxT("favourite")) + { + xmlChar *cont = xmlTextReaderReadString(reader); + if (!cont) + continue; // No contents, so ignore node + + favourites.Add(new queryFavouriteItem(title, WXSTRING_FROM_XML(cont))); + xmlFree(cont); + SkipToEndElement(reader); + } + else if (nodename == wxT("folder")) + { + favourites.Add(new queryFavouriteFolder(reader, title)); + } + } +} + +queryFavouriteFolder::~queryFavouriteFolder() +{ + WX_CLEAR_ARRAY(favourites); +} + +void queryFavouriteFolder::AddNewFavourite(const wxString &title, const wxString &contents) +{ + favourites.Add(new queryFavouriteItem(title, contents)); +} + +queryFavouriteFolder *queryFavouriteFolder::AddNewFolder(const wxString &title) +{ + queryFavouriteFolder *fld = new queryFavouriteFolder(title); + favourites.Add(fld); + return fld; +} + +int queryFavouriteFolder::AppendAllToMenu(wxMenu *menu, int startid) +{ + int id = startid; + size_t i; + + for (i = 0; i < favourites.GetCount(); i++) + { + if (favourites.Item(i)->GetId() == -2) // id=-2 reserved for submenus + { + queryFavouriteFolder *fld = (queryFavouriteFolder *)favourites.Item(i); + + wxMenu *newmenu = new wxMenu(); + id = fld->AppendAllToMenu(newmenu, id); + menu->Append(-1, fld->title, newmenu); + } + else + { + favourites.Item(i)->AppendToMenu(menu, id); + id++; + } + } + return id; +} + +void queryFavouriteFolder::AppendAllToTree(wxTreeCtrl *tree, const wxTreeItemId &parent, bool onlyfolders) +{ + size_t i; + + treeid = parent; + + for (i = 0; i < favourites.GetCount(); i++) + { + if (favourites.Item(i)->GetId() == -2) // id=-1 reserved for submenus + { + queryFavouriteFolder *fld = (queryFavouriteFolder *)favourites.Item(i); + + wxTreeItemId newtreeitem = tree->AppendItem(parent, fld->title, onlyfolders ? 0 : 1); + fld->AppendAllToTree(tree, newtreeitem, onlyfolders); + tree->Expand(newtreeitem); + } + else + { + if (!onlyfolders) + favourites.Item(i)->SetTreeId(tree->AppendItem(parent, favourites.Item(i)->GetTitle(), 0)); + } + } +} + +bool queryFavouriteFolder::DeleteTreeItem(const wxTreeItemId &treeitem) +{ + if (treeid == treeitem) + /* Can't delete ourselves, parent should handle that. */ + return false; + + size_t i; + for (i = 0; i < favourites.GetCount(); i++) + { + if (favourites.Item(i)->GetTreeId() == treeitem) + { + queryFavouriteItem *itm = favourites.Item(i); + delete itm; + favourites.RemoveAt(i); + return true; + } + if (favourites.Item(i)->GetId() == -2) + { + queryFavouriteFolder *subfolder = (queryFavouriteFolder *)favourites.Item(i); + if (subfolder->DeleteTreeItem(treeitem)) + return true; + } + } + return false; +} + +queryFavouriteItem *queryFavouriteFolder::FindFavourite(int id) +{ + size_t i; + for (i = 0; i < favourites.GetCount(); i++) + { + if (favourites.Item(i)->GetId() == id) + return favourites.Item(i); + if (favourites.Item(i)->GetId() == -2) + { + queryFavouriteFolder *subfolder = (queryFavouriteFolder *)favourites.Item(i); + queryFavouriteItem *match = subfolder->FindFavourite(id); + if (match != NULL) + return match; + } + } + return NULL; +} + +queryFavouriteItem *queryFavouriteFolder::FindFavourite(const wxString &title) +{ + size_t i; + for (i = 0; i < favourites.GetCount(); i++) + { + if (favourites.Item(i)->GetId() == -2) + { + queryFavouriteFolder *subfolder = (queryFavouriteFolder *)favourites.Item(i); + queryFavouriteItem *match = subfolder->FindFavourite(title); + if (match != NULL) + return match; + } + else if (favourites.Item(i)->GetTitle() == title) + return favourites.Item(i); + } + return NULL; +} + +queryFavouriteItem *queryFavouriteFolder::FindTreeItem(const wxTreeItemId &treeitem) +{ + if (treeid == treeitem) + return this; + + size_t i; + for (i = 0; i < favourites.GetCount(); i++) + { + if (favourites.Item(i)->GetId() == -2) + { + queryFavouriteFolder *subfolder = (queryFavouriteFolder *)favourites.Item(i); + queryFavouriteItem *match = subfolder->FindTreeItem(treeitem); + if (match != NULL) + return match; + } + else if (favourites.Item(i)->GetTreeId() == treeitem) + return favourites.Item(i); + } + return NULL; +} + +bool queryFavouriteFolder::ContainsFolder(const wxString &title) +{ + size_t i; + for (i = 0; i < favourites.GetCount(); i++) + { + if (favourites.Item(i)->GetId() == -2) + { + if (favourites.Item(i)->GetTitle() == title) + return true; + } + } + return false; +} + +void queryFavouriteFolder::saveFolder(xmlTextWriterPtr writer) +{ + size_t i; + + for (i = 0; i < favourites.GetCount(); i++) + { + if (favourites.Item(i)->GetId() == -2) + { + queryFavouriteFolder *subfolder = (queryFavouriteFolder *)favourites.Item(i); + + xmlTextWriterStartElement(writer, XML_STR("folder")); + xmlTextWriterWriteAttribute(writer, XML_STR("title"), XML_FROM_WXSTRING(subfolder->title)); + subfolder->saveFolder(writer); + xmlTextWriterEndElement(writer); + } + else + { + xmlTextWriterStartElement(writer, XML_STR("favourite")); + xmlTextWriterWriteAttribute(writer, XML_STR("title"), XML_FROM_WXSTRING(favourites.Item(i)->GetTitle())); + xmlTextWriterWriteString(writer, XML_FROM_WXSTRING(favourites.Item(i)->GetContents())); + xmlTextWriterEndElement(writer); + } + } +} + +// +// queryFavouriteFileProvider - load and save favourites from a XML file in the users +// home directory +// +queryFavouriteFolder *queryFavouriteFileProvider::LoadFavourites(bool emptyonfailure) +{ + xmlTextReaderPtr reader; + int ret; + + if (!wxFile::Access(settings->GetFavouritesFile(), wxFile::read)) + return emptyonfailure ? (new queryFavouriteFolder()) : NULL; + + reader = xmlReaderForFile((const char *)settings->GetFavouritesFile().mb_str(wxConvUTF8), NULL, 0); + if (!reader) + { + wxMessageBox(_("Failed to load favourites file!")); + return emptyonfailure ? (new queryFavouriteFolder()) : NULL; + } + + ret = xmlTextReaderRead(reader); + if (ret != 1) + { + wxMessageBox(_("Failed to read favourites file!")); + return emptyonfailure ? (new queryFavouriteFolder()) : NULL; + } + + queryFavouriteFolder *f = (queryFavouriteFolder *)(new queryFavouriteFolder(reader, wxT(""))); + + xmlTextReaderClose(reader); + xmlFreeTextReader(reader); + xmlCleanupParser(); + + return f; +} + +void queryFavouriteFileProvider::SaveFavourites(queryFavouriteFolder *favourites) +{ + xmlTextWriterPtr writer; + + writer = xmlNewTextWriterFilename((const char *)settings->GetFavouritesFile().mb_str(wxConvUTF8), 0); + if (!writer) + { + wxMessageBox(_("Failed to write to favourites file!")); + return; + } + xmlTextWriterSetIndent(writer, 1); + + if ((xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL) < 0) || + (xmlTextWriterStartElement(writer, XML_STR("favourites")) < 0)) + { + wxMessageBox(_("Failed to write to favourites file!")); + xmlFreeTextWriter(writer); + return; + } + + ((queryFavouriteFolder *)favourites)->saveFolder(writer); + + if (xmlTextWriterEndDocument(writer) < 0) + { + wxMessageBox(_("Failed to write to favourites file!")); + } + + xmlFreeTextWriter(writer); +} diff --git a/utils/macros.cpp b/utils/macros.cpp new file mode 100644 index 0000000..6fc24f5 --- /dev/null +++ b/utils/macros.cpp @@ -0,0 +1,349 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// macros.cpp - Query macros +// +////////////////////////////////////////////////////////////////////////// + +#include + +#include "pgAdmin3.h" +#include "utils/favourites.h" +#include "utils/macros.h" +#include "utils/sysSettings.h" + +#include + +// +// libxml convenience macros +// +#define XML_FROM_WXSTRING(s) ((const xmlChar *)(const char *)s.mb_str(wxConvUTF8)) +#define WXSTRING_FROM_XML(s) wxString((char *)s, wxConvUTF8) +#define XML_STR(s) ((const xmlChar *)s) + +// +// libxml convenience function +// +static void SkipToEndElement(xmlTextReaderPtr reader) +{ + while (xmlTextReaderRead(reader) == 1) + { + if (xmlTextReaderNodeType(reader) == 15) + return; + } +} + +queryMacroItem::queryMacroItem(const wxString newKey, const wxString newName, const wxString newQuery, const int newId) +{ + key = newKey; + name = newName; + query = newQuery; + id = newId; +} + +void queryMacroItem::AppendToMenu(wxMenu *menu, int newId) +{ + id = newId; + menu->Append(id, name + wxT("\t") + key, query); +} + +void queryMacroItem::Update(const wxString &newName, const wxString &newQuery) +{ + name = newName; + query = newQuery; +} + +queryMacroList::queryMacroList(xmlTextReaderPtr reader) +{ + // Element of type , meaning empty folder + if (xmlTextReaderIsEmptyElement(reader)) + return; + + while (xmlTextReaderRead(reader)) + { + int type = xmlTextReaderNodeType(reader); + + if (type == 15) + return; // Close on parent element + if (xmlTextReaderNodeType(reader) != 1) + continue; // Any unknown element type + + wxString nodename = WXSTRING_FROM_XML(xmlTextReaderConstName(reader)); + + xmlChar *ckey = xmlTextReaderGetAttribute(reader, XML_STR("key")); + if (!ckey) + continue; + wxString key = WXSTRING_FROM_XML(ckey); + xmlFree(ckey); + + xmlChar *cname = xmlTextReaderGetAttribute(reader, XML_STR("name")); + if (!cname) + continue; + wxString name = WXSTRING_FROM_XML(cname); + xmlFree(cname); + + if (nodename == wxT("macro")) + { + xmlChar *cquery = xmlTextReaderReadString(reader); + if (!cquery) + continue; + wxString query = WXSTRING_FROM_XML(cquery); + xmlFree(cquery); + macros.Add(new queryMacroItem(key, name, query)); + SkipToEndElement(reader); + } + } +} + +queryMacroList::~queryMacroList() +{ + WX_CLEAR_ARRAY(macros); +} + +int queryMacroList::AppendAllToMenu(wxMenu *menu, int startId) +{ + int id = startId; + size_t i; + + for (i = 0; i < macros.GetCount(); i++) + { + macros.Item(i)->AppendToMenu(menu, id); + id++; + } + return id; +} + +void queryMacroList::AddNewMacro(const wxString &key, const wxString &name, const wxString &query) +{ + macros.Add(new queryMacroItem(key, name, query)); +} + +void queryMacroList::AddOrUpdateMacro(const wxString &key, const wxString &name, const wxString &query) +{ + queryMacroItem *item = FindMacro(key); + if (item != NULL) + { + item->Update(name, query); + } + else + { + AddNewMacro(key, name, query); + } +} + +bool queryMacroList::DelMacro(int id) +{ + size_t i; + + for (i = 0; i < macros.GetCount(); i++) + { + if (macros.Item(i)->GetId() == id) + { + queryMacroItem *itm = macros.Item(i); + delete itm; + macros.RemoveAt(i); + return true; + } + } + return false; +} + +bool queryMacroList::DelMacro(const wxString &key) +{ + size_t i; + + for (i = 0; i < macros.GetCount(); i++) + { + if (macros.Item(i)->GetKey() == key) + { + queryMacroItem *itm = macros.Item(i); + delete itm; + macros.RemoveAt(i); + return true; + } + } + return false; +} + +queryMacroItem *queryMacroList::FindMacro(int id) +{ + size_t i; + + for (i = 0; i < macros.GetCount(); i++) + { + if (macros.Item(i)->GetId() == id) + return macros.Item(i); + } + + return NULL; +} +queryMacroItem *queryMacroList::GetItem(int i) +{ + if (i < macros.GetCount()) { + return macros.Item(i); + } + return NULL; +} +int queryMacroList::Count() +{ + return macros.GetCount(); + +} + +queryMacroItem *queryMacroList::FindMacro(const wxString &key) +{ + size_t i; + + for (i = 0; i < macros.GetCount(); i++) + { + if (macros.Item(i)->GetKey() == key) + return macros.Item(i); + } + + return NULL; +} + +void queryMacroList::saveList(xmlTextWriterPtr writer) +{ + size_t i; + + for (i = 0; i < macros.GetCount(); i++) + { + xmlTextWriterStartElement(writer, XML_STR("macro")); + xmlTextWriterWriteAttribute(writer, XML_STR("key"), + XML_FROM_WXSTRING(macros.Item(i)->GetKey())); + xmlTextWriterWriteAttribute(writer, XML_STR("name"), + XML_FROM_WXSTRING(macros.Item(i)->GetName())); + xmlTextWriterWriteString(writer, + XML_FROM_WXSTRING(macros.Item(i)->GetQuery())); + xmlTextWriterEndElement(writer); + } +} + +// +// queryMacroFileProvider - load and save macros from a XML file in the users +// home directory +// +queryMacroList *queryMacroFileProvider::LoadMacros(bool emptyOnFailure) +{ + xmlTextReaderPtr reader; + int ret; + + if (!wxFile::Access(settings->GetMacrosFile(), wxFile::read)) + return emptyOnFailure ? (new queryMacroList()) : NULL; + + reader = xmlReaderForFile((const char *)settings->GetMacrosFile().mb_str(wxConvUTF8), NULL, 0); + if (!reader) + { + wxMessageBox(_("Failed to load macros file!")); + return emptyOnFailure ? (new queryMacroList()) : NULL; + } + + ret = xmlTextReaderRead(reader); + if (ret != 1) + { + wxMessageBox(_("Failed to read macros file!")); + return emptyOnFailure ? (new queryMacroList()) : NULL; + } + + queryMacroList *f = (queryMacroList *)(new queryMacroList(reader)); + + xmlTextReaderClose(reader); + xmlFreeTextReader(reader); + xmlCleanupParser(); + + return f; +} +queryMacroList *queryMacroFileProvider::LoadAutoReplace(bool emptyOnFailure) +{ + xmlTextReaderPtr reader; + int ret; + + if (!wxFile::Access(settings->GetAutoReplaceFile(), wxFile::read)) + return emptyOnFailure ? (new queryMacroList()) : NULL; + + reader = xmlReaderForFile((const char *)settings->GetAutoReplaceFile().mb_str(wxConvUTF8), NULL, 0); + if (!reader) + { + wxMessageBox(_("Failed to load AutoReplace file!")); + return emptyOnFailure ? (new queryMacroList()) : NULL; + } + + ret = xmlTextReaderRead(reader); + if (ret != 1) + { + wxMessageBox(_("Failed to read AutoReplace file!")); + return emptyOnFailure ? (new queryMacroList()) : NULL; + } + + queryMacroList *f = (queryMacroList *)(new queryMacroList(reader)); + + xmlTextReaderClose(reader); + xmlFreeTextReader(reader); + xmlCleanupParser(); + + return f; +} +void queryMacroFileProvider::SaveAutoReplace(queryMacroList *macros) +{ + xmlTextWriterPtr writer; + + writer = xmlNewTextWriterFilename((const char *)settings->GetAutoReplaceFile().mb_str(wxConvUTF8), 0); + if (!writer) + { + wxMessageBox(_("Failed to open AutoReplace file!")); + return; + } + xmlTextWriterSetIndent(writer, 1); + + if ((xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL) < 0) || + (xmlTextWriterStartElement(writer, XML_STR("macros")) < 0)) + { + wxMessageBox(_("Failed to write to AutoReplace file!")); + xmlFreeTextWriter(writer); + return; + } + + ((queryMacroList *)macros)->saveList(writer); + + if (xmlTextWriterEndDocument(writer) < -1) + { + wxMessageBox(_("Failed to write to AutoReplace file!")); + } + + xmlFreeTextWriter(writer); +} + +void queryMacroFileProvider::SaveMacros(queryMacroList *macros) +{ + xmlTextWriterPtr writer; + + writer = xmlNewTextWriterFilename((const char *)settings->GetMacrosFile().mb_str(wxConvUTF8), 0); + if (!writer) + { + wxMessageBox(_("Failed to open macros file!")); + return; + } + xmlTextWriterSetIndent(writer, 1); + + if ((xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL) < 0) || + (xmlTextWriterStartElement(writer, XML_STR("macros")) < 0)) + { + wxMessageBox(_("Failed to write to macros file!")); + xmlFreeTextWriter(writer); + return; + } + + ((queryMacroList *)macros)->saveList(writer); + + if (xmlTextWriterEndDocument(writer) < -1) + { + wxMessageBox(_("Failed to write to macros file!")); + } + + xmlFreeTextWriter(writer); +} diff --git a/utils/misc.cpp b/utils/misc.cpp new file mode 100644 index 0000000..f0047b3 --- /dev/null +++ b/utils/misc.cpp @@ -0,0 +1,1407 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// misc.cpp - Miscellaneous Utilities +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils/utffile.h" +#include + +#ifdef __WXMSW__ +#include +#endif + +// Standard headers +#include + +// App headers +#include "utils/misc.h" + +#if !defined(PGSCLI) + +// App headers +#include "frm/frmMain.h" + +wxImageList *imageList = 0; + +#endif // PGSCLI + +extern "C" +{ +#define YYSTYPE_IS_DECLARED +#define DECIMAL DECIMAL_P + typedef int YYSTYPE; +#include "parser/keywords.h" +} + +// we dont have an appropriate wxLongLong method +#ifdef __WIN32__ +#define atolonglong _atoi64 +#else +#ifdef __WXMAC__ +#define atolonglong(str) strtoll(str, (char **)NULL, 10) +#else +#ifdef __FreeBSD__ +#define atolonglong(str) strtoll(str, (char **)NULL, 10) +#else +#define atolonglong atoll +#endif +#endif +#endif + + + +// Conversions + + +wxString BoolToYesNo(bool value) +{ + return value ? _("Yes") : _("No"); +} + + +wxString BoolToStr(bool value) +{ + return value ? wxT("true") : wxT("false"); +} + + + +bool StrToBool(const wxString &value) +{ + if (value.StartsWith(wxT("t"))) + { + return true; + } + else if (value.StartsWith(wxT("T"))) + { + return true; + } + else if (value.StartsWith(wxT("1"))) + { + return true; + } + else if (value.StartsWith(wxT("Y"))) + { + return true; + } + else if (value.StartsWith(wxT("y"))) + { + return true; + } + else if (value == wxT("on")) + return true; + + return false; +} + +wxString NumToStr(long value) +{ + wxString result; + result.Printf(wxT("%ld"), value); + return result; +} + + +wxString NumToStr(OID value) +{ + wxString result; + result.Printf(wxT("%lu"), (long)value); + return result; +} + + +long StrToLong(const wxString &value) +{ + return atol(value.ToAscii()); +} + + +OID StrToOid(const wxString &value) +{ + return (OID)strtoul(value.ToAscii(), 0, 10); +} + +wxString generate_spaces(int length) +{ + return wxString().Pad(length); +} + +wxString NumToStr(double value) +{ + wxString result; + static wxString decsep; + + if (decsep.Length() == 0) + { + decsep.Printf(wxT("%lf"), 1.2); + decsep = decsep[(unsigned int)1]; + } + + result.Printf(wxT("%lf"), value); + result.Replace(decsep, wxT(".")); + + // Get rid of excessive decimal places + if (result.Contains(wxT("."))) + while (result.Right(1) == wxT("0")) + result.RemoveLast(); + if (result.Right(1) == wxT(".")) + result.RemoveLast(); + + return result; +} + + +wxString NumToStr(wxLongLong value) +{ + wxString str; +#if wxCHECK_VERSION(2, 9, 0) + str.Printf("%" wxLongLongFmtSpec "d", value.GetValue()); +#else + str.Printf(wxT("%") wxLongLongFmtSpec wxT("d"), value.GetValue()); +#endif + return str; +} + + +double StrToDouble(const wxString &value) +{ + wxCharBuffer buf = value.ToAscii(); + char *p = (char *)strchr(buf, '.'); + if (p) + *p = localeconv()->decimal_point[0]; + + return strtod(buf, 0); +} + + +wxLongLong StrToLongLong(const wxString &value) +{ + return atolonglong(value.ToAscii()); +} + + +wxString DateToAnsiStr(const wxDateTime &datetime) +{ + if (!datetime.IsValid()) + return wxEmptyString; + + return datetime.FormatISODate() + wxT(" ") + datetime.FormatISOTime(); +} + + +wxString DateToStr(const wxDateTime &datetime) +{ + if (!datetime.IsValid()) + return wxEmptyString; + + return datetime.FormatDate() + wxT(" ") + datetime.FormatTime(); +} + + +wxString ElapsedTimeToStr(wxLongLong msec) +{ + wxTimeSpan tsMsec(0, 0, 0, msec); + + int days = tsMsec.GetDays(); + int hours = (wxTimeSpan(tsMsec.GetHours(), 0, 0, 0) - wxTimeSpan(days * 24)).GetHours(); + int minutes = (wxTimeSpan(0, tsMsec.GetMinutes(), 0, 0) - wxTimeSpan(hours)).GetMinutes(); + long seconds = (wxTimeSpan(0, 0, tsMsec.GetSeconds(), 0) - wxTimeSpan(hours, minutes)).GetSeconds().ToLong(); + long milliseconds = (wxTimeSpan(0, 0, 0, tsMsec.GetMilliseconds()) - wxTimeSpan(0, 0, seconds)).GetMilliseconds().ToLong(); + + if (days > 0) + return wxString::Format( + wxT("%d %s, %02d:%02d:%02ld hours"), + days, wxT("days"), hours, minutes, seconds + ); + else if (hours > 0) + return wxString::Format( + wxT("%02d:%02d:%02ld hours"), hours, minutes, seconds + ); + else if (msec >= 1000 * 60) + return wxString::Format(wxT("%02d:%02ld minutes"), minutes, seconds); + else if (msec >= 1000) + return wxString::Format( + wxT("%ld.%ld secs"), seconds, milliseconds / 100 + ); + else + return msec.ToString() + wxT(" msec"); +} + +wxDateTime StrToDateTime(const wxString &value) +{ + wxDateTime dt; + /* This hasn't just been used. ( Is not infinity ) */ + if ( !value.IsEmpty() ) + dt.ParseDateTime(value); + return dt; +} + +#if !defined(PGSCLI) + +void CheckOnScreen(wxWindow *win, wxPoint &pos, wxSize &size, const int w0, const int h0) +{ + wxRect rect; + int scrH, scrW; + + wxSize screenSize = wxGetDisplaySize(); + scrW = screenSize.x; + scrH = screenSize.y; + + if (pos.x > scrW - w0) + pos.x = scrW - w0; + if (pos.y > scrH - h0) + pos.y = scrH - h0; + + if (pos.x < 0) + pos.x = 0; + if (pos.y < 0) + pos.y = 0; + + if (size.GetWidth() < w0) + size.SetWidth(w0); + if (size.GetHeight() < h0) + size.SetHeight(h0); + + if (size.GetWidth() > scrW) + size.SetWidth(scrW); + if (size.GetHeight() > scrH) + size.SetHeight(scrH); +} + +#endif // PGSCLI + +wxString qtConnString(const wxString &value) +{ + wxString result = value; + + result.Replace(wxT("\\"), wxT("\\\\")); + result.Replace(wxT("'"), wxT("\\'")); + result.Append(wxT("'")); + result.Prepend(wxT("'")); + + return result; +} + +#if !defined(PGSCLI) + +wxString IdAndName(long id, const wxString &name) +{ + wxString str; + str.Printf(wxT("%ld - %s"), id, name.BeforeFirst('\n').c_str()); + return str; +} + + +wxString qtDbStringDollar(const wxString &value) +{ + wxString qtDefault = wxT("BODY"); + wxString qt = qtDefault; + int counter = 1; + if (value.Find('\'') < 0 && value.Find('\n') < 0 && value.Find('\r') < 0) + { + wxString ret = value; + ret.Replace(wxT("\\"), wxT("\\\\")); + ret.Replace(wxT("'"), wxT("''")); + ret.Append(wxT("'")); + ret.Prepend(wxT("'")); + return ret; + } + + while (value.Find(wxT("$") + qt + wxT("$")) >= 0) + qt.Printf(wxT("%s%d"), qtDefault.c_str(), counter++); + + + return wxT("$") + qt + wxT("$") + + value + + wxT("$") + qt + wxT("$"); +} + + +void FillKeywords(wxString &str) +{ + // unfortunately, the keyword list is static. + int i; + + str = wxString(); + + for (i = 0; i < NumScanKeywords; i++) + { + str += wxT(" ") + wxString::FromAscii(ScanKeywords[i].name); + } + for (i = 0; i < NumScanKeywordsExtra; i++) + { + str += wxT(" ") + wxString::FromAscii(ScanKeywordsExtra[i].name); + } +} + +#endif // PGSCLI + +static bool needsQuoting(wxString &value, bool forTypes) +{ + // Is it a number? + if (value.IsNumber()) + return true; + else + { + // certain types should not be quoted even though it contains a space. Evilness. + wxString valNoArray; + if (forTypes && value.Right(2) == wxT("[]")) + valNoArray = value.Mid(0, value.Len() - 2); + else + valNoArray = value; + + if (forTypes && + (!valNoArray.CmpNoCase(wxT("character varying")) || + !valNoArray.CmpNoCase(wxT("\"char\"")) || + !valNoArray.CmpNoCase(wxT("bit varying")) || + !valNoArray.CmpNoCase(wxT("double precision")) || + !valNoArray.CmpNoCase(wxT("timestamp without time zone")) || + !valNoArray.CmpNoCase(wxT("timestamp with time zone")) || + !valNoArray.CmpNoCase(wxT("time without time zone")) || + !valNoArray.CmpNoCase(wxT("time with time zone")) || + !valNoArray.CmpNoCase(wxT("\"trigger\"")) || + !valNoArray.CmpNoCase(wxT("\"unknown\"")))) + return false; + + int pos = 0; + while (pos < (int)valNoArray.length()) + { + wxChar c = valNoArray.GetChar(pos); + if (!((pos > 0) && (c >= '0' && c <= '9')) && + !(c >= 'a' && c <= 'z') && + !(c == '_')) + { + return true; + } + pos++; + } + } + + // is it a keyword? + const ScanKeyword *sk = ScanKeywordLookup(value.ToAscii()); + if (!sk) + return false; + if (sk->category == UNRESERVED_KEYWORD) + return false; + if (forTypes && sk->category == COL_NAME_KEYWORD) + return false; + return true; +} + +wxString qtTypeIdent(const wxString &value) +{ + if (value.Length() == 0) + return value; + + wxString result = value; + + if (needsQuoting(result, true)) + { + result.Replace(wxT("\""), wxT("\"\"")); + return wxT("\"") + result + wxT("\""); + } + else + return result; +} + + +wxString qtIdent(const wxString &value) +{ + if (value.Length() == 0) + return value; + + wxString result = value; + + if (needsQuoting(result, false)) + { + result.Replace(wxT("\""), wxT("\"\"")); + return wxT("\"") + result + wxT("\""); + } + else + return result; +} + +#if !defined(PGSCLI) + +wxString qtStrip(const wxString &str) +{ + if (str.Left(2) == wxT("\\\"")) + return str.Mid(2, str.Length() - 4); + else + return str; +} + + +wxString TransformToNewDatconfig(const wxString &list) +{ + const wxChar *cp = list.c_str(); + + wxString config = wxEmptyString; + wxString str = wxEmptyString; + bool quote = false; + + while (*cp) + { + switch (*cp) + { + case '\\': + { + if (cp[1] == '"') + { + str.Append(*cp); + cp++; + str.Append(*cp); + } + break; + } + case '"': + case '\'': + { + quote = !quote; + str.Append(*cp); + break; + } + case ',': + { + if (!quote) + { + if (!config.IsEmpty()) + config += wxT(","); + config += wxT("=") + str; + str = wxEmptyString; + break; + } + } + default: + { + str.Append(*cp); + break; + } + } + cp++; + } + + if (!str.IsEmpty()) + { + if (!config.IsEmpty()) + config += wxT(","); + config += wxT("=") + str; + } + + return config; +} + + +void FillArray(wxArrayString &array, const wxString &list) +{ + const wxChar *cp = list.c_str(); + + wxString str; + bool quote = false; + + while (*cp) + { + switch (*cp) + { + case '\\': + { + if (cp[1] == '"') + { + cp++; + str.Append(*cp); + } + break; + } + case '"': + case '\'': + { + quote = !quote; + break; + } + case ',': + { + if (!quote) + { + array.Add(str); + str = wxEmptyString; + break; + } + } + default: + { + str.Append(*cp); + break; + } + } + cp++; + } + if (!str.IsEmpty()) + array.Add(str); +} + + +queryTokenizer::queryTokenizer(const wxString &str, const wxChar delim) + : wxStringTokenizer() +{ + if (delim == (wxChar)' ') + SetString(str, wxT(" \n\r\t"), wxTOKEN_RET_EMPTY_ALL); + else + SetString(str, delim, wxTOKEN_RET_EMPTY_ALL); + delimiter = delim; +} + + +void AppendIfFilled(wxString &str, const wxString &delimiter, const wxString &what) +{ + if (!what.IsNull()) + str += delimiter + what; +} + + +wxString queryTokenizer::GetNextToken() +{ + // we need to override wxStringTokenizer, because we have to handle quotes + wxString str; + + bool foundQuote = false; + do + { + wxString s = wxStringTokenizer::GetNextToken(); + str.Append(s); + int quotePos; + do + { + quotePos = s.Find('"'); + if (quotePos >= 0) + { + foundQuote = !foundQuote; + s = s.Mid(quotePos + 1); + } + } + while (quotePos >= 0); + + if (foundQuote) + str.Append(delimiter); + } + while (foundQuote & HasMoreTokens()); + + return str; +} + + +wxString FileRead(const wxString &filename, int format) +{ + wxString str; + + wxFontEncoding encoding; + if (format > 0) + encoding = wxFONTENCODING_UTF8; + else + encoding = wxFONTENCODING_DEFAULT; + + wxUtfFile file(filename, wxFile::read, encoding); + + if (file.IsOpened()) + file.Read(str); + + return wxTextBuffer::Translate(str, wxTextFileType_Unix); // we want only \n +} + + +bool FileWrite(const wxString &filename, const wxString &data, int format) +{ + wxFontEncoding encoding = wxFONTENCODING_DEFAULT; + wxUtfFile file; + + if (format < 0) + { + if (wxFile::Access(filename, wxFile::read)) + { + file.Open(filename); + encoding = file.GetEncoding(); + file.Close(); + } + if (encoding == wxFONTENCODING_DEFAULT) + encoding = settings->GetUnicodeFile() ? wxFONTENCODING_UTF8 : wxFONTENCODING_SYSTEM; + } + else + encoding = format ? wxFONTENCODING_UTF8 : wxFONTENCODING_SYSTEM; + + + file.Open(filename, wxFile::write, wxS_DEFAULT, encoding); + + if (file.IsOpened()) + return file.Write(wxTextBuffer::Translate(data)); + + return false; +} + + +wxString CleanHelpPath(const wxString &path) +{ + wxString thePath = path; + + if (thePath.IsEmpty()) + return wxEmptyString; + + // If the filename ends in .chm, .hhp, .pdf or .zip, it's + // a file based help system and we can assumes it's + // correct. + if (thePath.Lower().EndsWith(wxT(".hhp")) || +#if defined (__WXMSW__) || wxUSE_LIBMSPACK + thePath.Lower().EndsWith(wxT(".chm")) || +#endif + thePath.Lower().EndsWith(wxT(".pdf")) || + thePath.Lower().EndsWith(wxT(".zip"))) + return thePath; + + // In all other cases we must have a directory + wxString sep; + + // Figure out the appropriate seperator + if (thePath.Lower().Contains(wxT("://"))) + sep = wxT("/"); + else + sep = wxFileName::GetPathSeparator(); + + // First, correct the path separators + thePath.Replace(wxT("/"), sep); + thePath.Replace(wxT("\\"), sep); + + // Now, append the seperator if it's not there + if (!thePath.EndsWith(sep)) + thePath += sep; + + return thePath; +} + +bool HelpPathValid(const wxString &path) +{ + if (path.IsEmpty()) + return true; + + // If the filename contains any of the sensible URL schemes + // we just assume it's correct if the end also looks right. + if ((path.Lower().StartsWith(wxT("http://")) || + path.Lower().StartsWith(wxT("https://")) || + path.Lower().StartsWith(wxT("file://")) || + path.Lower().StartsWith(wxT("ftp://"))) && + (path.Lower().EndsWith(wxT(".hhp")) || +#if defined (__WXMSW__) || wxUSE_LIBMSPACK + path.Lower().EndsWith(wxT(".chm")) || +#endif + path.Lower().EndsWith(wxT(".pdf")) || + path.Lower().EndsWith(wxT(".zip")) || + path.Lower().EndsWith(wxT("/")))) + return true; + + // Otherwise, we're looking for a file (or directory) that + // actually exists. + wxString sep = wxFileName::GetPathSeparator(); + if (path.Lower().EndsWith(wxT(".hhp")) || +#if defined (__WXMSW__) || wxUSE_LIBMSPACK + path.Lower().EndsWith(wxT(".chm")) || +#endif + path.Lower().EndsWith(wxT(".pdf")) || + path.Lower().EndsWith(wxT(".zip"))) + return wxFile::Exists(path); + else if (path.Lower().EndsWith(sep)) + return wxDir::Exists(path); + else + return false; +} + +void DisplayHelp(const wxString &helpTopic, const HelpType helpType) +{ + static wxHelpControllerBase *pgHelpCtl = 0; + static wxHelpControllerBase *edbHelpCtl = 0; + static wxHelpControllerBase *greenplumHelpCtl = 0; + static wxHelpControllerBase *slonyHelpCtl = 0; + static wxString pgInitPath = wxEmptyString; + static wxString edbInitPath = wxEmptyString; + static wxString gpInitPath = wxEmptyString; + static wxString slonyInitPath = wxEmptyString; + + switch (helpType) + { + case HELP_PGADMIN: + DisplayPgAdminHelp(helpTopic); + break; + + case HELP_POSTGRESQL: + DisplayExternalHelp(helpTopic, settings->GetPgHelpPath(), pgHelpCtl, (pgInitPath != settings->GetPgHelpPath() ? true : false)); + pgInitPath = settings->GetPgHelpPath(); + break; + + case HELP_ENTERPRISEDB: + DisplayExternalHelp(helpTopic, settings->GetEdbHelpPath(), edbHelpCtl, (edbInitPath != settings->GetEdbHelpPath() ? true : false)); + edbInitPath = settings->GetEdbHelpPath(); + break; + + case HELP_GREENPLUM: + { + // the old help path (stored in the settings) is no longer working + static wxString gpHelpPath = settings->GetGpHelpPath(); + + // Note: never end the URL on "index.html" + // InitHelp() does obscure magic with this ending + if (gpHelpPath.CmpNoCase(wxT("http://docs.gopivotal.com/gpdb/")) == 0) + { + gpHelpPath = wxT("http://gpdb.docs.pivotal.io/"); + // Replace the path to the old domain with the link to + // the new documentation path + // The old link is working for now, but there is no guarantee + // that it will stay this way + // Also the new link automatically redirects to the latest version + settings->SetGpHelpPath(gpHelpPath); + } + + if (gpHelpPath.CmpNoCase(wxT("http://www.greenplum.com/docs/3300/")) == 0) + { + gpHelpPath = wxT("http://gpdb.docs.pivotal.io/"); + // this is the old link, update the link to the new documentation link + // problem: this saves the link into the configuration file + settings->SetGpHelpPath(gpHelpPath); + } + DisplayExternalHelp(helpTopic, settings->GetGpHelpPath(), greenplumHelpCtl, (gpInitPath != settings->GetGpHelpPath() ? true : false)); + gpInitPath = settings->GetGpHelpPath(); + } + break; + + case HELP_SLONY: + DisplayExternalHelp(helpTopic, settings->GetSlonyHelpPath(), slonyHelpCtl, (slonyInitPath != settings->GetSlonyHelpPath() ? true : false)); + slonyInitPath = settings->GetSlonyHelpPath(); + break; + + default: + DisplayPgAdminHelp(helpTopic); + break; + } +} + +void DisplayPgAdminHelp(const wxString &helpTopic) +{ + static wxHelpControllerBase *helpCtl = 0; + static bool firstCall = true; + + // Startup the main help system + if (firstCall) + { + firstCall = false; + wxString helpdir = docPath + wxT("/") + settings->GetCanonicalLanguageName(); + + if (!wxFile::Exists(helpdir + wxT("/pgadmin3.hhp")) && +#if defined(__WXMSW__) || wxUSE_LIBMSPACK + !wxFile::Exists(helpdir + wxT("/pgadmin3.chm")) && +#endif + !wxFile::Exists(helpdir + wxT("/pgadmin3.zip"))) + helpdir = docPath + wxT("/en_US"); + +#ifdef __WXMSW__ +#ifndef __WXDEBUG__ + if (wxFile::Exists(helpdir + wxT("/pgadmin3.chm"))) + { + helpCtl = new wxCHMHelpController(); + helpCtl->Initialize(helpdir + wxT("/pgadmin3")); + } + else +#endif +#endif +#if wxUSE_LIBMSPACK + if (wxFile::Exists(helpdir + wxT("/pgadmin3.chm")) || + wxFile::Exists(helpdir + wxT("/pgadmin3.hhp")) || wxFile::Exists(helpdir + wxT("/pgadmin3.zip"))) +#else + if (wxFile::Exists(helpdir + wxT("/pgadmin3.hhp")) || wxFile::Exists(helpdir + wxT("/pgadmin3.zip"))) +#endif + { + helpCtl = new wxHtmlHelpController(); + helpCtl->Initialize(helpdir + wxT("/pgadmin3")); + } + } + + wxString page; + int hashPos = helpTopic.Find('#'); + if (hashPos < 0) + page = helpTopic + wxT(".html"); + else + page = helpTopic.Left(hashPos) + wxT(".html") + helpTopic.Mid(hashPos); + + if (helpCtl) + { + if (helpTopic == wxT("index.html")) + helpCtl->DisplayContents(); + else + helpCtl->DisplaySection(page); + } + else + { + wxLaunchDefaultBrowser(page); + } +} + +void DisplayExternalHelp(const wxString &helpTopic, const wxString &docPath, wxHelpControllerBase *helpCtl, const bool init) +{ + // Build the page name + wxString page; + int hashPos = helpTopic.Find('#'); + if (hashPos < 0) + page = helpTopic + wxT(".html"); + else + page = helpTopic.Left(hashPos) + wxT(".html") + helpTopic.Mid(hashPos); + + // If the docPath ends in .pdf, then open the file in the browser. No + // bookmarks though :-( + if (docPath.Lower().EndsWith(wxT(".pdf"))) + { + wxLaunchDefaultBrowser(docPath); + return; + } + + // If the docPath doesn't end in .chm, .zip or .hhp, then we must be using + // plain HTML files, so just fire off the browser and be done with it. + if (!docPath.Lower().EndsWith(wxT(".hhp")) && +#if defined (__WXMSW__) || wxUSE_LIBMSPACK + !docPath.Lower().EndsWith(wxT(".chm")) && +#endif + !docPath.Lower().EndsWith(wxT(".zip"))) + { + wxLaunchDefaultBrowser(docPath + page); + return; + } + + // We must be using HTML Help, so init the appropriate help controller + // Note the path that we init for - if it changes, we need to init a + // new controller in case it's no longer the same type + if (init || !helpCtl) + { + // Get shot of the old help controller if there is one. + if (helpCtl) + delete helpCtl; + +#ifdef __WXMSW__ + // For Windows builds we us the MS HTML Help viewer for .chm files + if (docPath.Lower().EndsWith(wxT(".chm")) && wxFile::Exists(docPath)) + { + helpCtl = new wxCHMHelpController(); + helpCtl->Initialize(docPath); + } + else +#endif +#if wxUSE_LIBMSPACK + // If we can use a .chm file... + if ((docPath.Lower().EndsWith(wxT(".chm")) && wxFile::Exists(docPath)) || + (docPath.Lower().EndsWith(wxT(".hhp")) && wxFile::Exists(docPath)) || + (docPath.Lower().EndsWith(wxT(".zip")) && wxFile::Exists(docPath))) +#else + // Otherwise... + if ((docPath.Lower().EndsWith(wxT(".hhp")) && wxFile::Exists(docPath)) || + (docPath.Lower().EndsWith(wxT(".zip")) && wxFile::Exists(docPath))) +#endif + { + helpCtl = new wxHtmlHelpController(); + helpCtl->Initialize(docPath); + } + } + + // Display the page using the help controller + // If it's foobar'ed, use the browser. + if (helpCtl) + { + if (helpTopic == wxT("index.html")) + helpCtl->DisplayContents(); + else + helpCtl->DisplaySection(page); + } + else + { + wxLogError(_("The help source (\"%s\") could not be opened. Please check the help configuration options."), docPath.c_str()); + } +} + +wxString GetHtmlEntity(const wxChar ch) +{ + // REWRITE THIS - IT'S (STILL) BLOODY INEFFICIENT!! + + // Quick bailout + if ((ch >= 'a' && ch <= 'z') || + (ch >= 'A' && ch <= 'Z') || + (ch >= '0' && ch <= '9')) + return wxString(ch); + + unsigned short ents[] = + { + 34, + 39, + 38, + 60, + 62, + 160, + 161, + 164, + 162, + 163, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 8482, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 215, + 247, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 248, + 249, + 250, + 251, + 252, + 253, + 254, + 255, + 338, + 339, + 352, + 353, + 376, + 710, + 732, + 8194, + 8195, + 8201, + 8204, + 8205, + 8206, + 8207, + 8211, + 8212, + 8216, + 8217, + 8218, + 8220, + 8221, + 8222, + 8224, + 8225, + 8230, + 8240, + 8249, + 8250, + 8364, + 0 + }; + + int elem = 0; + + while (ents[elem] != 0) + { + if (ch == ents[elem]) + { + wxString ret = wxT("&#"); + ret += NumToStr((long)ents[elem]); + ret += wxT(";"); + return ret; + } + elem++; + } + + return wxString(ch); +} + +wxString HtmlEntities(const wxString &str) +{ + wxString ret; + + for (unsigned int x = 0; x < str.Length(); x++) + { + if (str[x] != 13) + ret += GetHtmlEntity(str[x]); + } + + return ret; +} + + +#ifndef WIN32 +wxString ExecProcess(const wxString &cmd) +{ + wxString res; + FILE *f = popen(cmd.ToAscii(), "r"); + + if (f) + { + char buffer[1024]; + int cnt; + while ((cnt = fread(buffer, 1, 1024, f)) > 0) + { + res += wxString::FromAscii(buffer); + } + pclose(f); + } + return res; +} + +int ExecProcess(const wxString &command, wxArrayString &result) +{ + FILE *fp_command; + char buf[4098]; + + fp_command = popen(command.mb_str(wxConvUTF8), "r"); + + if (!fp_command) + return -1; + + while(!feof(fp_command)) + { + if (fgets(buf, 4096, fp_command) != NULL) + result.Add(wxString::FromAscii(buf)); + } + + return pclose(fp_command); +} +#endif + +#ifdef WIN32 +#if (_MSC_VER < 1300) +/* _ftol2 is more than VC7. */ +extern "C" long _ftol( double ); +extern "C" long _ftol2( double dblSource ) +{ + return _ftol( dblSource ); +} +#endif +#endif + +wxString firstLineOnly(const wxString &str) +{ + wxString ip, tmp; + ip = str; + ip = ip.Trim(true).Trim(false); + + if (ip.Contains(wxT("\r\n")) && (ip.First(wxT("\r")) < ip.First(wxT("\n")))) + { + tmp = ip.BeforeFirst('\r'); + if (ip.BeforeFirst('\r').Length() != ip.Length()) + tmp += wxT("..."); + } + else + { + tmp = ip.BeforeFirst('\n'); + if (ip.BeforeFirst('\n').Length() != ip.Length()) + tmp += wxT("..."); + } + + return tmp; +} + +bool pgAppMinimumVersion(const wxString &cmd, const int majorVer, const int minorVer) +{ + wxArrayString output; + bool isEnterpriseDB = false; + +#ifdef __WXMSW__ + if (wxExecute(cmd + wxT(" --version"), output, 0) != 0) +#else + if (ExecProcess(cmd + wxT(" --version"), output) != 0) +#endif + { + wxLogError(_("Failed to execute: %s --version"), cmd.c_str()); + return false; + } + + // Is this an EDB utility? + if (output[0].Contains(wxT("EnterpriseDB"))) + isEnterpriseDB = true; + + wxString version = output[0].AfterLast(' '); + long actualMajor = 0, actualMinor = 0; + + wxString tmp = wxT(""); + int x = 0; + while(version[x] == '0' || version[x] == '1' || version[x] == '2' || version[x] == '3' || version[x] == '4' || + version[x] == '5' || version[x] == '6' || version[x] == '7' || version[x] == '8' || version[x] == '9') + { + tmp += version[x]; + x++; + } + tmp.ToLong(&actualMajor); + x++; + + tmp = wxT(""); + while(version[x] == '0' || version[x] == '1' || version[x] == '2' || version[x] == '3' || version[x] == '4' || + version[x] == '5' || version[x] == '6' || version[x] == '7' || version[x] == '8' || version[x] == '9') + { + tmp += version[x]; + x++; + } + + tmp.ToLong(&actualMinor); + + // EnterpriseDB's 8.3R1 utilties are based on PG8.2, so correct the version number here. + // This will need more work when 8.3R2 is released :-( + if (isEnterpriseDB && actualMajor == 8 && actualMinor == 3) + actualMinor = 2; + + if (actualMajor > majorVer) + return true; + + if (actualMajor == majorVer && actualMinor >= minorVer) + return true; + + return false; +} + +bool isPgApp(const wxString &app) +{ + if (!wxFile::Exists(app)) + return false; + + wxArrayString output; + +#ifdef __WXMSW__ + if (wxExecute(app + wxT(" --version"), output, 0) != 0) +#else + if (ExecProcess(app + wxT(" --version"), output) != 0) +#endif + { + wxLogError(_("Failed to execute: %s --version"), app.c_str()); + return false; + } + + if (output[0].Contains(wxT("PostgreSQL"))) + return true; + + return false; +} + +bool isEdbApp(const wxString &app) +{ + if (!wxFile::Exists(app)) + return false; + + wxArrayString output; + +#ifdef __WXMSW__ + if (wxExecute(app + wxT(" --version"), output, 0) != 0) +#else + if (ExecProcess(app + wxT(" --version"), output) != 0) +#endif + { + wxLogError(_("Failed to execute: %s --version"), app.c_str()); + return false; + } + + if (output[0].Contains(wxT("EnterpriseDB"))) + return true; + + return false; +} + +bool isGpApp(const wxString &app) +{ + if (!wxFile::Exists(app)) + return false; + + wxArrayString output; + +#ifdef __WXMSW__ + if (wxExecute(app + wxT(" --version"), output, 0) != 0) +#else + if (ExecProcess(app + wxT(" --version"), output) != 0) +#endif + { + wxLogError(_("Failed to execute: %s --version"), app.c_str()); + return false; + } + + if (output[0].Contains(wxT("8.2"))) // Ugly... No way to tell Greenplum app from PostgreSQL 8.2 app + return true; + + return false; +} + +wxString sanitizePath(const wxString &path) +{ + if (path.Length()) + { + wxFileName fn = path; + fn.Normalize(); + return fn.GetLongPath(); + } + + return wxEmptyString; +} + +/** + * FUNCTION: commandLineCleanOption + * INPUTS: + * option - input string needs to be reformatted + * schemaObject - Is this an object related to schema? + * PURPOSE: + * - Fixup a (double-quoted) string for use on the command line + */ +wxString commandLineCleanOption(const wxString &option, bool schemaObject) +{ + wxString tmp = option; + + if (schemaObject) + { + // Replace double-quote with slash & double-quote + tmp.Replace(wxT("\""), wxT("\\\"")); + } + else + { + // If required, clean the string to know the real object name + if (option.StartsWith(wxT("\"")) && option.EndsWith(wxT("\""))) + tmp = option.AfterFirst((wxChar)'"').BeforeLast((wxChar)'"'); + + // Replace single splash to double-splash + tmp.Replace(wxT("\\"), wxT("\\\\")); + + // Replace double-quote with slash & double-quote + tmp.Replace(wxT("\""), wxT("\\\"")); + + // Replace double (slash & double-quote) combination to single (slash & double-quote) combination + tmp.Replace(wxT("\\\"\\\""), wxT("\\\"")); + + // Add the double quotes + tmp = wxT("\"") + tmp + wxT("\""); + } + + return tmp; +} + +#endif // PGSCLI + +// Get an array from a comma separated list +bool getArrayFromCommaSeparatedList(const wxString &str, wxArrayString &res) +{ + size_t len = str.Len(), index = 0, nBracketLevel = 0, startArray = 0; + bool inSingleQuote = false, inDoubleQuote = false; + + if (len == 0) + return true; + + for(; index < len; index++) + { + wxChar curr = str.GetChar(index); + if (!inDoubleQuote && curr == (wxChar)'\'') + inSingleQuote = !inSingleQuote; + else if (!inSingleQuote && curr == (wxChar)'"') + inDoubleQuote = !inDoubleQuote; + else if (!inDoubleQuote && !inSingleQuote && curr == (wxChar)'(') + nBracketLevel++; + else if (!inDoubleQuote && !inSingleQuote && curr == (wxChar)')') + nBracketLevel--; + else if (!inDoubleQuote && !inSingleQuote && nBracketLevel == 0 && curr == (wxChar)',') + { + if (index != startArray) + res.Add(str.SubString(startArray, index - 1).Trim(true).Trim(false)); + else + res.Add(wxEmptyString); + startArray = index + 1; + } + } + if (inDoubleQuote || inSingleQuote || nBracketLevel != 0) + return false; + + // Add last value to array + res.Add(str.SubString(startArray, index).Trim(true).Trim(false)); + + return true; +} + diff --git a/utils/module.mk b/utils/module.mk new file mode 100644 index 0000000..822b534 --- /dev/null +++ b/utils/module.mk @@ -0,0 +1,34 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/utils/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + utils/csvfiles.cpp \ + utils/factory.cpp \ + utils/favourites.cpp \ + utils/misc.cpp \ + utils/pgconfig.cpp \ + utils/registry.cpp \ + utils/sysLogger.cpp \ + utils/sysProcess.cpp \ + utils/sysSettings.cpp \ + utils/tabcomplete.c \ + utils/utffile.cpp \ + utils/macros.cpp + +if BUILD_SSH_TUNNEL +pgadmin3_SOURCES += \ + utils/sshTunnel.cpp +endif + +EXTRA_DIST += \ + utils/module.mk \ + utils/tab-complete.inc \ + utils/tabcomplete.pl diff --git a/utils/pgconfig.cpp b/utils/pgconfig.cpp new file mode 100644 index 0000000..7488084 --- /dev/null +++ b/utils/pgconfig.cpp @@ -0,0 +1,624 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgconfig.cpp - backend configuration classes +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include + +#include "utils/pgconfig.h" +#include "db/pgConn.h" +#include "db/pgSet.h" +#include "utils/utffile.h" + + +#define DEFAULT_COMMENT_INDEX wxT("\t\t# ") + + +int FindToken(const wxString &str, const wxChar **list) +{ + int index; + for (index = 0 ; list[index] ; index++) + { + if (list[index] == str) + return index; + + } + return -1; +} + + +const wxChar *pgConfigTypeStrings[] = +{ + wxT("bool"), + wxT("integer"), + wxT("real"), + wxT("string"), + 0 +}; + + +void pgSettingItem::SetType(const wxString &str) +{ + int index = FindToken(str, pgConfigTypeStrings); + if (index < 0) + type = PGC_STRING; + else + type = (pgConfigType)index; +} + + +const wxChar *pgConfigContextStrings[] = +{ + wxT("internal"), + wxT("postmaster"), + wxT("sighup"), + wxT("backend"), + wxT("superuser"), + wxT("userlimit"), + wxT("user"), + 0 +}; + + +void pgSettingItem::SetContext(const wxString &str) +{ + int index = FindToken(str, pgConfigContextStrings); + if (index < 0) + context = PGC_INTERNAL; + else + context = (pgConfigContext)index; +} + + +const wxChar *pgConfigSourceStrings[] = +{ + wxT("default"), + wxT("environment variable"), + wxT("configuration file"), + wxT("command line"), + wxT("unprivileged"), + wxT("database"), + wxT("user"), + wxT("client"), + wxT("override"), + wxT("interactive"), + wxT("test"), + wxT("session"), + 0 +}; + + +void pgSettingItem::SetSource(const wxString &str) +{ + int index = FindToken(str, pgConfigSourceStrings); + if (index < 0) + source = PGC_UNKNOWNSOURCE; + else + source = (pgConfigSource)index; +} + + +wxString pgSettingItem::GetActiveValue() +{ + if (newLine) + { + if (!newLine->isComment) + return newLine->value; + } + else if (orgLine) + { + if (!orgLine->isComment) + return orgLine->value; + } + return value; +} + + +pgConfigLine::pgConfigLine(pgConfigLine *line) +{ + item = line->item; + value = line->value; + comment = line->comment; + isComment = line->isComment; +} + + +bool pgConfigLine::Differs(pgConfigLine *line) +{ + return value != line->value || comment != line->comment || isComment != line->isComment; +} + + +wxString pgConfigLine::GetNewText() +{ + wxString quote; + wxString newLine; + if (item->type == pgSettingItem::PGC_STRING) + { + if (value.Find('\'') >= 0) + quote = wxT("\""); + else + quote = wxT("'"); + } + if (isComment) + newLine = wxT("# "); + + newLine += item->name + wxT(" = ") + + quote + value + quote; + + if (!comment.IsEmpty()) + { + if (item->orgLine && item->orgLine->commentIndent.Find('#') >= 0) + newLine += item->orgLine->commentIndent; + else + newLine += DEFAULT_COMMENT_INDEX; + newLine += comment; + } + return newLine; +} + + +pgConfigOrgLine::pgConfigOrgLine(pgConfigLine *line) : pgConfigLine(line) +{ + text = line->GetNewText(); + if (isComment) + commentIndent = DEFAULT_COMMENT_INDEX; +} + + +wxString pgConfigOrgLine::GetNewText() +{ + if (!item || !item->newLine) + return text; + return item->newLine->GetNewText(); +} + + +//////////////////////////////////////////////// + + +pgSettingFileReader::pgSettingFileReader(bool localized) +{ + + wxUtfFile file; + + wxString path = i18nPath + wxT("/") + settings->GetCanonicalLanguageName() + wxT("/pg_settings.csv"); + if (localized && wxFile::Exists(path)) + file.Open(path); + else + file.Open(i18nPath + wxT("/pg_settings.csv")); + + if (file.IsOpened()) + { + file.Read(buffer); + file.Close(); + } + + if (!buffer.IsEmpty()) + { + buffer = wxTextBuffer::Translate(buffer, wxTextFileType_Unix); + + columnNames = buffer.BeforeFirst('\n'); + bp = const_cast((const wxChar *)buffer + columnNames.Length() + 1); + } +} + + +pgSettingFileReader::~pgSettingFileReader() +{ +} + + +pgSettingItem *pgSettingFileReader::GetNextItem() +{ + if (!bp || !*bp || *bp == '\n') + return 0; + + pgSettingItem *item = new pgSettingItem; + wxStringTokenizer tk(columnNames, wxT(";")); + wxString column = tk.GetNextToken(); + + wxChar *c = bp; + while (*c) + { + wxString value; + + if (*c++ != '"') + { + // invalid syntax + return 0; + } + while (*c && *c != '\n') + { + if (*c == '"') + { + if (c[1] == '"') + c++; + else + break; + } + value.Append(*c++); + } + if (*c++ != '"') + { + // format error + return 0; + } + if (column == wxT("name") || column == wxT("\"name\"")) + item->name = value.Lower(); + else if (column == wxT("category") || column == wxT("\"category\"")) + item->category = value; + else if (column == wxT("short_desc") || column == wxT("\"short_desc\"")) + item->short_desc = value; + else if (column == wxT("extra_desc") || column == wxT("\"extra_desc\"")) + item->extra_desc = value; + else if (column == wxT("min_val") || column == wxT("\"min_val\"")) + item->min_val = value; + else if (column == wxT("max_val") || column == wxT("\"max_val\"")) + item->max_val = value; + else if (column == wxT("context") || column == wxT("\"context\"")) + item->SetContext(value); + else if (column == wxT("vartype") || column == wxT("\"vartype\"")) + item->SetType(value); + + column = tk.GetNextToken(); + if (*c == '\n') + { + bp = c + 1; + break; + } + else if (!*c) + { + bp = 0; + break; + } + else if (*c == ';') + c++; + else + { + // invalid syntax + return 0; + } + } + + return item; +} + + +pgSettingDbReader::pgSettingDbReader(pgConn *conn) +{ + set = conn->ExecuteSet(wxT("SELECT name, setting, source, category, short_desc, extra_desc, context, vartype, min_val, max_val FROM pg_settings ORDER BY name")); +} + + +pgSettingDbReader::~pgSettingDbReader() +{ + if (set) + delete set; +} + +pgSettingItem *pgSettingDbReader::GetNextItem() +{ + if (set->Eof()) + return 0; + + pgSettingItem *item = new pgSettingItem; + + item->name = set->GetVal(wxT("name")).Lower(); + item->category = set->GetVal(wxT("category")); + item->short_desc = set->GetVal(wxT("short_desc")); + item->extra_desc = set->GetVal(wxT("extra_desc")); + item->min_val = set->GetVal(wxT("min_val")); + item->max_val = set->GetVal(wxT("max_val")); + item->SetContext(set->GetVal(wxT("context"))); + item->SetType(set->GetVal(wxT("vartype"))); + item->SetSource(set->GetVal(wxT("source"))); + item->value = set->GetVal(wxT("setting")); + + set->MoveNext(); + + return item; +} + + +/////////////////////////////////////////////////////// + +// must match enum pgHbaConnectType!!! +const wxChar *pgHbaConnectTypeStrings[] = +{ + wxT("local"), + wxT("host"), + wxT("hostssl"), + wxT("hostnossl"), + 0 +}; + + +// must match enum pgHbaMethod!!! +const wxChar *pgHbaMethodStrings[] = +{ + wxT("trust"), + wxT("reject"), + wxT("md5"), + wxT("crypt"), + wxT("password"), + wxT("krb4"), + wxT("krb5"), + wxT("ident"), + wxT("pam"), + wxT("ldap"), + wxT("gss"), + wxT("sspi"), + wxT("cert"), + wxT("peer"), + wxT("radius"), + 0 +}; + + +bool IsSpaceChar(wxChar c, const wxChar *spaceChars = wxT("\t ")) +{ + return wxStrchr(spaceChars, c) != NULL; +} + + +void SkipSpace(const wxChar *&ptr, const wxChar *spaceChars = wxT("\t ")) +{ + while (*ptr && IsSpaceChar(*ptr)) + ptr++; +} + + +void SkipNonspace(const wxChar *&ptr, const wxChar *spaceChars = wxT("\t ")) +{ + while (*ptr && !IsSpaceChar(*ptr)) + ptr++; +} + + +pgHbaConfigLine::pgHbaConfigLine(const wxString &line) +{ + item = -1; + isValid = false; + isComment = true; + connectType = PGC_INVALIDCONF; + method = PGC_INVALIDMETHOD; + Init(line); +} + + +void pgHbaConfigLine::Init(const wxString &line) +{ + isValid = false; + connectType = PGC_INVALIDCONF; + changed = false; + + if (line.IsEmpty()) + return; + + text = line; + + const wxChar *p0 = line.c_str(); + + if (*p0 == '#') + { + isComment = true; + p0++; + SkipSpace(p0); + } + else + isComment = false; + + + const wxChar *p1 = p0; + SkipNonspace(p1); + + wxString str = line.Mid(p0 - line.c_str(), p1 - p0); + + int i = FindToken(str, pgHbaConnectTypeStrings); + + if (i >= 0) + connectType = (pgHbaConnectType)i; + else + { + connectType = PGC_INVALIDCONF; + return; + } + + SkipSpace(p1); + + const wxChar *p2 = p1; + bool quoted = false; + + while (*p2) + { + if (!quoted && IsSpaceChar(*p2)) + break; + if (*p2 == '"') + quoted = !quoted; + p2++; + } + + database = line.Mid(p1 - line.c_str(), p2 - p1); + + SkipSpace(p2); + + const wxChar *p3 = p2; + + quoted = false; + while (*p3) + { + if (!quoted && IsSpaceChar(*p3)) + break; + if (*p3 == '"') + quoted = !quoted; + p3++; + } + + user = line.Mid(p2 - line.c_str(), p3 - p2); + + SkipSpace(p3); + + const wxChar *p4 = p3; + + if (connectType == PGC_LOCAL) + { + // no ip address + } + else + { + bool hasCidr = false; + while (*p4 && !IsSpaceChar(*p4)) + { + if (*p4 == '/') + hasCidr = true; + p4++; + } + if (!hasCidr) + { + SkipSpace(p4); + SkipNonspace(p4); + } + + ipaddress = line.Mid(p3 - line.c_str(), p4 - p3); + SkipSpace(p4); + } + + const wxChar *p5 = p4; + SkipNonspace(p5); + + str = line.Mid(p4 - line.c_str(), p5 - p4); + + i = FindToken(str, pgHbaMethodStrings); + + if (i >= 0) + method = (pgHbaMethod)i; + else + { + return; + } + SkipSpace(p5); + option = p5; + + isValid = true; +} + + +const wxChar *pgHbaConfigLine::GetConnectType() +{ + if (connectType >= 0 && connectType < PGC_INVALIDCONF) + return pgHbaConnectTypeStrings[connectType]; + return 0; +} + + +const wxChar *pgHbaConfigLine::GetMethod() +{ + if (method >= 0 && method < PGC_INVALIDMETHOD) + return pgHbaMethodStrings[method]; + return 0; +} + + +wxString pgHbaConfigLine::GetText() +{ + if (!changed) + return text; + + wxString str; + wxString tabspace = wxT("\t "); + if (isComment) + str = wxT("# "); + + str += GetConnectType() + + tabspace + database + + tabspace + user; + + if (connectType != PGC_LOCAL) + str += tabspace + ipaddress; + + str += tabspace + GetMethod(); + + if (method >= PGC_IDENT && !option.IsEmpty()) + str += tabspace + option; + + return str; +} + + +//////////////////////////////////////////////// +pgPassConfigLine::pgPassConfigLine(const wxString &line) +{ + item = -1; + Init(line); +} + +void pgPassConfigLine::Init(const wxString &line) +{ + text = line; + + if (line.IsEmpty()) + return; + + isComment = line.StartsWith(wxT("#")); + + wxString tmpLine = line; + // De-escape backslash "\" + tmpLine.Replace(wxT("\\\\"), wxT("\\")); + + int iVarCount = 0; + wxStringTokenizer tok(isComment ? tmpLine.Mid(1) : tmpLine, wxT(":")); + while(tok.HasMoreTokens()) + { + wxString val = tok.GetNextToken(); + if (!val.IsEmpty()) + { + /* if last charecter of the token is backslash "\" then it means + that it is used to escape ":" so we need to add the next token. + */ + while(val.Last() == wxT('\\')) + { + val.RemoveLast(); + val = val + wxT(":") + tok.GetNextToken(); + } + + iVarCount++; + switch(iVarCount) + { + case 1: // hostname + hostname = val; + break; + case 2: // port + port = val; + break; + case 3: // database + database = val; + break; + case 4: //username + username = val; + break; + case 5: // password + password = val; + break; + } + } + } +} + +wxString pgPassConfigLine::GetText() +{ + return (isComment ? wxT("#") : wxT("")) + + hostname + wxT(":") + + port + wxT(":") + + database + wxT(":") + + username + wxT(":") + + password; +} diff --git a/utils/registry.cpp b/utils/registry.cpp new file mode 100644 index 0000000..9cd4154 --- /dev/null +++ b/utils/registry.cpp @@ -0,0 +1,377 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// RCS-ID: +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// registry.cpp - Windows Registry Reader for both 32 and 64 mode +// +////////////////////////////////////////////////////////////////////////// +#include "pgAdmin3.h" + +#include "utils/registry.h" + +#ifdef __WXMSW__ + +#define RESERVED 0 +#define PGREG_SEPERATOR wxT("\\") + +static struct stdkey +{ + HKEY key; + wxString name; +} +aStdHKeys[] = +{ + {HKEY_CLASSES_ROOT, wxT("HKEY_CLASSES_ROOT")}, + {HKEY_CURRENT_USER, wxT("HKEY_CURRENT_USER")}, + {HKEY_LOCAL_MACHINE, wxT("HKEY_LOCAL_MACHINE") }, + {HKEY_USERS, wxT("HKEY_USERS")}, + {HKEY_CURRENT_CONFIG, wxT("HKEY_CURRENT_CONFIG")} +}; + +#define NOS_STD_KEYS (size_t)(sizeof(aStdHKeys)/sizeof(stdkey)) + +pgRegKey::pgRegKey(HKEY root, const wxString &subkey, PGREGWOWMODE wowMode, PGREGACCESSMODE accessMode) +{ + Init(root, subkey, wowMode, accessMode); +} + +pgRegKey::pgRegKey(const pgRegKey &parent, const wxString &key) +{ + wxString strKey; + strKey << parent.m_strName << PGREG_SEPERATOR << key; + + Init(parent.m_hRoot, strKey, PGREG_WOW_DEFAULT, parent.m_accessMode); + m_wowMode = parent.m_wowMode; +} + +void pgRegKey::Init(HKEY root, const wxString &subkey, PGREGWOWMODE wowMode, PGREGACCESSMODE accessMode) +{ + m_hRoot = root; + m_strName = subkey; + m_accessMode = accessMode; + m_hKey = NULL; +#ifdef __WIN64__ + m_wowMode = KEY_WOW64_64KEY; +#else + m_wowMode = KEY_WOW64_32KEY; +#endif + + switch (wowMode) + { + case PGREG_WOW32: +#ifdef __WIN64__ + m_wowMode = KEY_WOW64_32KEY; +#endif // __WIN64__ + break; + + case PGREG_WOW64: +#ifndef __WIN64__ + // we can only access 64 bit registry under 64 bit platforms + if (::wxIsPlatform64Bit()) + m_wowMode = KEY_WOW64_64KEY; +#endif // !__WIN64__ + break; + } +} + +pgRegKey *pgRegKey::OpenRegKey(HKEY root, const wxString &subkey, PGREGACCESSMODE accessmode, PGREGWOWMODE wowMode) +{ + wxString strKey = subkey; + + !subkey.IsEmpty() && subkey.EndsWith(wxT("\\"), &strKey); + pgRegKey *tmpKey = new pgRegKey(root, strKey, wowMode, accessmode); + + HKEY tmpRegKey = 0; + long nError = ::RegOpenKeyEx(root, (LPCTSTR)strKey, RESERVED, + (accessmode == PGREG_READ ? KEY_READ : KEY_ALL_ACCESS) | tmpKey->m_wowMode, + &tmpRegKey); + + if (nError != ERROR_SUCCESS) + { + delete(tmpKey); + tmpKey = NULL; + } + else + tmpKey->m_hKey = tmpRegKey; + + return tmpKey; +} + +void pgRegKey::Close() +{ + if (m_hKey) + { + ::RegCloseKey(m_hKey); + m_hKey = NULL; + } +} + +pgRegKey::~pgRegKey() +{ + Close(); +} + +bool pgRegKey::KeyExists(HKEY root, const wxString &subkey, PGREGWOWMODE wowMode) +{ + if (subkey.IsEmpty()) + return true; + +#ifdef __WIN64__ + long keyWowMode = KEY_WOW64_64KEY; +#else + long keyWowMode = KEY_WOW64_32KEY; +#endif + + switch (wowMode) + { + case PGREG_WOW32: +#ifdef __WIN64__ + keyWowMode = KEY_WOW64_32KEY; +#endif // __WIN64__ + break; + + case PGREG_WOW64: +#ifndef __WIN64__ + // we can only access 64 bit registry under 64 bit platforms + if (::wxIsPlatform64Bit()) + keyWowMode = KEY_WOW64_64KEY; +#endif // ! __WIN64__ + break; + } + + HKEY hkeyDummy; + if (::RegOpenKeyEx(root, (LPCTSTR)subkey, RESERVED, KEY_READ | keyWowMode, &hkeyDummy) == ERROR_SUCCESS) + { + ::RegCloseKey(hkeyDummy); + return true; + } + return false; +} + +bool pgRegKey::GetKeyInfo(size_t *pnSubKeys, size_t *pnMaxKeyLen, size_t *pnValues, size_t *pnMaxValueLen) const +{ + + long nError = ::RegQueryInfoKey(m_hKey, NULL, NULL, RESERVED, (LPDWORD)pnSubKeys, (LPDWORD)pnMaxKeyLen, NULL, + (LPDWORD)pnValues, (LPDWORD)pnMaxValueLen, NULL, NULL, NULL); + + if (nError != ERROR_SUCCESS) + return false; + return true; +} + +wxString pgRegKey::ToString() const +{ + wxString str; + size_t index = 0; + for (; index < NOS_STD_KEYS; index++) + { + if (m_hRoot == aStdHKeys[index].key) + { + str = aStdHKeys[index].name; + break; + } + } + + if (!m_strName.IsEmpty()) + str << wxT("\\") << m_strName; + + return str; +} + +wxString pgRegKey::GetKeyName() const +{ + if (!m_strName.IsEmpty()) + { + int index = m_strName.Find(wxT('\\'), true); + return m_strName.SubString(index + 1, m_strName.Len()); + } + return wxEmptyString; +} + +bool pgRegKey::QueryValue(const wxString &strkey, LPDWORD pVal) const +{ + if (strkey.IsEmpty()) + return false; + + DWORD dwType, dwSize = sizeof(DWORD); + unsigned char *pBuf = (unsigned char *)pVal; + + long nError = ::RegQueryValueEx(m_hKey, (LPCTSTR)strkey, RESERVED, &dwType, pBuf, &dwSize); + + if (nError != ERROR_SUCCESS) + return false; + + if (dwType != REG_DWORD && dwType != REG_DWORD_BIG_ENDIAN) + return false; + return true; +} + +bool pgRegKey::QueryValue(const wxString &strVal, wxString &sVal) const +{ + DWORD dwType, dwSize; + + long nError = RegQueryValueEx(m_hKey, (LPCTSTR)strVal, RESERVED, &dwType, NULL, &dwSize); + + if (nError == ERROR_SUCCESS) + { + sVal = wxT(""); + if (dwSize == 0) + return true; + + wxChar *pBuf = (wxChar *)calloc(dwSize, sizeof(wxChar)); + nError = ::RegQueryValueEx(m_hKey, (LPCTSTR)strVal, RESERVED, &dwType, (LPBYTE)pBuf, &dwSize); + + DWORD index = 0; + if (dwType == REG_EXPAND_SZ || dwType == REG_MULTI_SZ) + { + wxChar *actualValueStr = (wxChar *)calloc(dwSize, sizeof(wxChar)); + memcpy(actualValueStr, pBuf, dwSize * sizeof(wxChar)); + + wxChar *curr_line; + sVal = wxT(""); + do + { + DWORD dwExpSize = ::ExpandEnvironmentStrings((actualValueStr + index), NULL, 0); + curr_line = (wxChar *)calloc(dwExpSize, sizeof(wxChar)); + + ::ExpandEnvironmentStrings(actualValueStr + index, curr_line, dwExpSize); + + if (index != 0) + sVal << wxT("\n\r") << curr_line; + else + sVal << curr_line; + index += (DWORD)wxStrlen(actualValueStr + index) + 1; + free(curr_line); + } + while (actualValueStr[index] && dwType == REG_MULTI_SZ); + + free(actualValueStr); + } + else + sVal = pBuf; + + free(pBuf); + return true; + } + return false; +} + +bool pgRegKey::QueryValue(const wxString &strVal, LPBYTE &pVal, DWORD &len) const +{ + DWORD dwType; + if(RegQueryValueEx(m_hKey, (LPCTSTR)strVal, + RESERVED, &dwType, pVal, &len) == ERROR_SUCCESS) + return true; + len = 0; + return false; +} + +bool pgRegKey::GetFirstValue(wxString &strkey, long &lIndex) const +{ + lIndex = 0; + return GetNextValue(strkey, lIndex); +} + +bool pgRegKey::GetNextValue(wxString &strval, long &lIndex) const +{ + if (lIndex < 0) + return false; + + TCHAR szVal[1024]; + DWORD dwValLen = 1024; + + long nError = RegEnumValue(m_hKey, lIndex, szVal, &dwValLen, RESERVED, NULL, NULL, NULL); + + if (nError != ERROR_SUCCESS) + { + if (nError == ERROR_NO_MORE_ITEMS) + { + nError = ERROR_SUCCESS; + lIndex = -1; + } + return false; + } + strval = szVal; + lIndex++; + return true; +} + +bool pgRegKey::HasValue(const wxString &strval) +{ + long nRetVal = ::RegQueryValueEx(m_hKey, (LPCTSTR)strval, RESERVED, NULL, NULL, NULL); + + return nRetVal == ERROR_SUCCESS; +} + +bool pgRegKey::GetFirstKey(pgRegKey *&pkey, long &lIndex) const +{ + lIndex = 0; + return GetNextKey(pkey, lIndex); +} + +bool pgRegKey::GetNextKey(pgRegKey *&pKey, long &lIndex) const +{ + pKey = NULL; + + if (lIndex < 0) + return false; + + TCHAR szKey[1024]; + DWORD dwKeyLen = 1023; + long nError = ::RegEnumKeyEx(m_hKey, lIndex, szKey, &dwKeyLen, NULL, NULL, NULL, NULL); + + if (nError != ERROR_SUCCESS) + { + lIndex = -1; + return false; + } + lIndex++; + wxString strSubKey = m_strName; + strSubKey << wxT("\\") << szKey; + + pgRegKey *tmpKey = new pgRegKey(m_hRoot, (LPCTSTR)strSubKey, PGREG_WOW_DEFAULT, m_accessMode); + tmpKey->m_wowMode = m_wowMode; + + HKEY tmpRegKey = 0; + nError + = ::RegOpenKeyEx(m_hRoot, (LPCTSTR)strSubKey, RESERVED, (m_accessMode == PGREG_READ ? KEY_READ : KEY_ALL_ACCESS) | m_wowMode, &tmpRegKey); + + if (nError != ERROR_SUCCESS) + { + delete(tmpKey); + tmpKey = NULL; + pKey = NULL; + + return false; + } + else + tmpKey->m_hKey = tmpRegKey; + + pKey = tmpKey; + + return true; +} + +bool pgRegKey::HasKey(const wxString &strKey) const +{ + wxString strSubKey = m_strName; + strSubKey << wxT("\\") << strKey; + + return pgRegKey::KeyExists(m_hRoot, strSubKey, m_wowMode == KEY_WOW64_64KEY ? PGREG_WOW64 : PGREG_WOW32) ; +} + +DWORD pgRegKey::GetValueType(const wxString &key) const +{ + DWORD dwType; + long nError = RegQueryValueEx((HKEY) m_hKey, (LPCTSTR)key, RESERVED, + &dwType, NULL, NULL); + + if (nError != ERROR_SUCCESS) + return REG_NONE; + return dwType; +} + +#endif // __WXMSW__ diff --git a/utils/sshTunnel.cpp b/utils/sshTunnel.cpp new file mode 100644 index 0000000..041a854 --- /dev/null +++ b/utils/sshTunnel.cpp @@ -0,0 +1,628 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// sshTunnel.cpp - Used to create SSH Tunnels +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" +#include + +#undef ssize_t +#define ssize_t long +#include "libssh2/libssh2.h" +#include "utils/sshTunnel.h" +#include "frm/frmMain.h" + +#pragma comment (lib, "Ws2_32.lib") + +typedef const char *(*inet_ntop_t) (int af, const void *src, char *dst, socklen_t size); + +#ifdef WIN32 +const char *custom_inet_ntop(int af, const void *src, char *dst, int cnt) +{ + struct sockaddr_in srcaddr; + + memset(&srcaddr, 0, sizeof(struct sockaddr_in)); + memcpy(&(srcaddr.sin_addr), src, sizeof(srcaddr.sin_addr)); + + srcaddr.sin_family = af; + if (WSAAddressToStringA((struct sockaddr *) &srcaddr, sizeof(struct sockaddr_in), 0, dst, (LPDWORD) &cnt) != 0) + { + + wxLogInfo(wxT("SSH error: WSAAddressToStringA failed with error code %d"), WSAGetLastError()); + return NULL; + } + return dst; +} + +static inet_ntop_t gs_fnPtr_inet_ntop = &custom_inet_ntop; +#else +static inet_ntop_t gs_fnPtr_inet_ntop = &inet_ntop; +#endif + +char CSSHTunnelThread::m_keyboard_interactive_pwd[SSH_MAX_PASSWORD_LEN]; + +CSSHTunnelThread::CSSHTunnelThread(const wxString tunnelhost, const wxString remote_desthost, const unsigned int remote_destport, + const wxString username, const wxString password, const wxString publickey, const wxString privatekey, + const enAuthenticationMethod &enAuthMethod, const unsigned int tunnelPort) + : m_tunnelhost(tunnelhost), m_remote_desthost(remote_desthost), m_remote_destport(remote_destport), m_username(username), + m_password(password), m_publickey(publickey), m_privatekey(privatekey), m_enAuthMethod(enAuthMethod), m_tunnelPort(tunnelPort) +{ + m_local_listenip = wxEmptyString; + m_local_listenport = 0; + m_listensock = -1, m_sock = -1; + m_session = NULL; + + memset(m_keyboard_interactive_pwd, 0 , strlen(m_keyboard_interactive_pwd)); + strncpy(m_keyboard_interactive_pwd, (const char *)password.mb_str(wxConvUTF8), password.Length()); +} + +CSSHTunnelThread::~CSSHTunnelThread(void) +{ +} + +bool CSSHTunnelThread::Initialize() +{ + int rc, auth = AUTH_NONE; + const char *fingerprint; + char *userauthlist; + +#ifdef WIN32 + char sockopt; + WSADATA wsadata; + int err; + + err = WSAStartup(MAKEWORD(2, 0), &wsadata); + if(err != 0) + { + wxLogInfo(wxT("WSAStartup failed with error: %d"), err); + return false; + } +#else + int sockopt; +#endif + + wxArrayString arrTunnelHostIP; + + if (resolveDNS(m_tunnelhost.mb_str(), arrTunnelHostIP)) + { + rc = libssh2_init (0); + + if (rc != 0) + { + LogSSHTunnelErrors(wxString::Format(_("libssh2 initialization failed with error code %d"), rc), GetId()); + return false; + } + + /* Connect to SSH server */ + m_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + m_sin.sin_family = AF_INET; + if (INADDR_NONE == (m_sin.sin_addr.s_addr = inet_addr(arrTunnelHostIP.Item(0).mb_str()))) + { + LogSSHTunnelErrors(wxString::Format(_("SSH error: Error in inet address with error code %d"), wxSysErrorCode()), GetId()); + return false; + } + m_sin.sin_port = htons(m_tunnelPort); + if (connect(m_sock, (struct sockaddr *)(&m_sin), + sizeof(struct sockaddr_in)) != 0) + { + LogSSHTunnelErrors(wxString::Format(_("SSH error: Could not connect to socket with error code %d"), wxSysErrorCode()), GetId()); + return false; + } + + /* Create a session instance */ + m_session = libssh2_session_init(); + + if (!m_session) + { + LogSSHTunnelErrors(_("SSH error: Could not initialize SSH session!"), GetId()); + return false; + } + + /* ... start it up. This will trade welcome banners, exchange keys, + * and setup crypto, compression, and MAC layers + */ + rc = libssh2_session_handshake(m_session, m_sock); + if (rc) + { + LogSSHTunnelErrors(wxString::Format(_("SSH error: Error when starting up SSH session with error code %d"), rc), GetId(), m_session); + return false; + } + + /* At this point we havn't yet authenticated. The first thing to do + * is check the hostkey's fingerprint against our known hosts Your app + * may have it hard coded, may go to a file, may present it to the + * user, that's your call + */ + fingerprint = libssh2_hostkey_hash(m_session, LIBSSH2_HOSTKEY_HASH_SHA1); + wxString newHostKey = wxEmptyString; + for(int i = 0; i < 20; i++) + { + newHostKey += wxString::Format(wxT("%02X "), (unsigned char)fingerprint[i]); + } + + // Check if the SSH Host Key is verified + if(!IsHostKeyVerified(newHostKey)) + { + Cleanup(); + return false; + } + + + /* check what authentication methods are available */ + userauthlist = libssh2_userauth_list(m_session, m_username.mb_str(), strlen(m_username.mb_str())); + + if (strstr(userauthlist, "password")) + auth |= AUTH_PASSWORD; + if(strstr(userauthlist, "keyboard-interactive")) + auth |= AUTH_KEYBOARD_INTERACTIVE; + if (strstr(userauthlist, "publickey")) + auth |= AUTH_PUBLICKEY; + + if ((auth & AUTH_PASSWORD) && (m_enAuthMethod == AUTH_PASSWORD)) + auth = AUTH_PASSWORD; + else if ((auth & AUTH_KEYBOARD_INTERACTIVE) && (m_enAuthMethod == AUTH_PASSWORD)) + auth = AUTH_KEYBOARD_INTERACTIVE; + if ((auth & AUTH_PUBLICKEY) && (m_enAuthMethod == AUTH_PUBLICKEY)) + auth = AUTH_PUBLICKEY; + + if (auth & AUTH_PASSWORD) + { + rc = libssh2_userauth_password(m_session, m_username.mb_str(), m_password.mb_str()); + if (rc) + { + LogSSHTunnelErrors(wxString::Format(_("SSH error: Authentication by password failed with error code %d"), rc), GetId(), m_session); + Cleanup(); + return false; + } + } + else if (auth & AUTH_KEYBOARD_INTERACTIVE) + { + rc = libssh2_userauth_keyboard_interactive(m_session, m_username.mb_str(), &CSSHTunnelThread::keyboard_interactive); + if (rc) + { + LogSSHTunnelErrors(wxString::Format(_("SSH error: Authentication by password failed with error code %d"), rc), GetId(), m_session); + Cleanup(); + return false; + } + } + else if (auth & AUTH_PUBLICKEY) + { +#ifdef HAVE_GCRYPT + rc = libssh2_userauth_publickey_fromfile(m_session, m_username.mb_str(), m_publickey.mb_str(), m_privatekey.mb_str(), m_password.mb_str()); +#else + rc = libssh2_userauth_publickey_fromfile(m_session, m_username.mb_str(), NULL, m_privatekey.mb_str(), m_password.mb_str()); +#endif + if (rc) + { + LogSSHTunnelErrors(wxString::Format(_("SSH error: Authentication by identity file failed with error code %d"), rc), GetId(), m_session); + Cleanup(); + return false; + } + } + else + { + LogSSHTunnelErrors(_("SSH error: No supported authentication methods found!"), GetId()); + Cleanup(); + return false; + } + + // Get the IP Address of local machine + wxArrayString arrLocalIP; + if(resolveDNS("localhost", arrLocalIP)) + { + m_listensock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + memset(&m_sin, 0 , sizeof(m_sin)); + m_sin.sin_family = AF_INET; + + // Give port no to 0 so that bind will automatically select the available port. + m_sin.sin_port = htons(0); + if (INADDR_NONE == (m_sin.sin_addr.s_addr = inet_addr(arrLocalIP.Item(0).mb_str()))) + { + Cleanup(); + return false; + } + + sockopt = 1; + setsockopt(m_listensock, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(sockopt)); + m_sinlen = sizeof(m_sin); + if (-1 == bind(m_listensock, (struct sockaddr *)&m_sin, m_sinlen)) + { + LogSSHTunnelErrors(wxString::Format(_("SSH error: bind failed with error code %d"), wxSysErrorCode()), GetId()); + Cleanup(); + return false; + } + + if (getsockname(m_listensock, (struct sockaddr *)&m_sin, &m_sinlen) == -1) + { + LogSSHTunnelErrors(wxString::Format(_("SSH error: getsockname() failed with error code %d"), wxSysErrorCode()), GetId()); + Cleanup(); + return false; + } + + if (-1 == listen(m_listensock, 2)) + { + LogSSHTunnelErrors(wxString::Format(_("SSH error: listen failed with error code %d"), wxSysErrorCode()), GetId()); + Cleanup(); + return false; + } + + m_local_listenip = wxString(inet_ntoa(m_sin.sin_addr), wxConvLibc); + m_local_listenport = ntohs(m_sin.sin_port); + + wxLogInfo(wxT("Waiting for TCP connection on %s:%d..."), m_local_listenip.c_str(), m_local_listenport); + return true; + } + else + { + LogSSHTunnelErrors(_("SSH error: Unable to resolve localhost"), GetId()); + } + } + else + { + LogSSHTunnelErrors(wxString::Format(_("SSH error: Unable to resolve host: %s"), m_tunnelhost.c_str()), GetId()); + } + + return false; +} + +void *CSSHTunnelThread::Entry() +{ + while (1) + { + int forwardsock = accept(m_listensock, (struct sockaddr *) & m_sin, &m_sinlen); + if (-1 == forwardsock) + { +#ifdef WIN32 + if(wxSysErrorCode() != WSAEINTR && wxSysErrorCode() != WSAEBADF) +#else + if(wxSysErrorCode() != EINTR && wxSysErrorCode() != EBADF && wxSysErrorCode() != ECONNABORTED) +#endif + { + LogSSHTunnelErrors(wxString::Format(_("SSH error: accept failed with error code %d"), wxSysErrorCode()), GetId()); + Cleanup(); + } + break; + } + + // Create thread for read/write. + CSubThread *subThread = new CSubThread(m_sin, m_remote_desthost, m_remote_destport, m_session, forwardsock); + if ( subThread->Create() != wxTHREAD_NO_ERROR ) + { + delete subThread; + subThread = NULL; + } + else + { + if (subThread->Run() != wxTHREAD_NO_ERROR ) + { + delete subThread; + subThread = NULL; + } + else + { + g_SSHThreadMutex.Lock(); + g_setSocketDescriptor.insert(forwardsock); + g_SSHThreadMutex.Unlock(); + } + } + } + + return NULL; +} + +void CSSHTunnelThread::Cleanup() +{ + // Close all the sockets + g_SSHThreadMutex.Lock(); + subThreadSDSet::iterator it; + for( it = g_setSocketDescriptor.begin(); it != g_setSocketDescriptor.end(); ++it ) + { + int socketDescriptor = *it; +#ifdef WIN32 + closesocket(socketDescriptor); +#else + close(socketDescriptor); +#endif + } + g_SSHThreadMutex.Unlock(); + + Sleep(1000); + + if(m_session) + { + libssh2_session_disconnect(m_session, "Client disconnecting normally"); + libssh2_session_free(m_session); + m_session = NULL; + } + + if (m_listensock) + { +#ifdef WIN32 + closesocket(m_listensock); +#else + close(m_listensock); +#endif + m_listensock = 0; + } + + if (m_sock) + { +#ifdef WIN32 + closesocket(m_sock); +#else + close(m_sock); +#endif + m_sock = 0; + } + + libssh2_exit(); +} + +bool CSSHTunnelThread::resolveDNS(const char *host, wxArrayString &arrIPAddress) +{ + struct addrinfo hints, *res, *p; + int status; + char ipstr[INET6_ADDRSTRLEN]; + + memset(&hints, 0, sizeof hints); + memset(&ipstr, 0, sizeof ipstr); + hints.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE; + + if ((status = getaddrinfo(host, NULL, &hints, &res)) != 0) + { + wxLogInfo(wxT("getaddrinfo failed with error code: %d"), status); + return false; + } + + for(p = res; p != NULL; p = p->ai_next) + { + void *addr; + if (p->ai_family == AF_INET) + { + struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr; + addr = &(ipv4->sin_addr); + + /* convert the IP to a string*/ + if(NULL != gs_fnPtr_inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr)) + arrIPAddress.Add(wxString(ipstr, wxConvLocal)); + } + } + + if(res) + { + freeaddrinfo(res); // free the linked list + } + + if(arrIPAddress.Count() > 0) + { + return true; + } + + return false; +} + +void CSSHTunnelThread::keyboard_interactive(const char *name, int name_len, const char *instr, int instr_len, + int num_prompts, const struct _LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts, struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE *res, + void **abstract) +{ + if (num_prompts == 1) + { + res[0].text = strdup(m_keyboard_interactive_pwd); + res[0].length = strlen(m_keyboard_interactive_pwd); + } +} + +bool CSSHTunnelThread::IsHostKeyVerified(const wxString &newHostKey) +{ + bool bIsVerified = false; + wxString cachedHostKey = settings->Read(wxT("HostKeys/") + m_tunnelhost, wxEmptyString); + + // If cached host key is empty then ask user to accept or reject + if (cachedHostKey == wxEmptyString) + { + // Prompt User to accept or reject + wxString msg = wxString::Format(wxT("Host key received for the SSH server \"%s\" is \n\n%s\n\nWould you like to accept it and continue with the connection?"), m_tunnelhost.c_str(), newHostKey.c_str()); + int answer = wxMessageBox(msg, wxT("Host key verification"), wxYES_NO | wxNO_DEFAULT); + if (answer == wxYES) + { + // Write the host key with respect to tunnel host + settings->Write(wxT("HostKeys/") + m_tunnelhost, newHostKey); + bIsVerified = true; + } + } + else + { + // Compare the cached host key with the new key + if (cachedHostKey.compare(newHostKey) == 0) + bIsVerified = true; + else + { + // Prompt user to accept or reject the new host key received for the tunnel host + wxString msg = wxString::Format(wxT("The host key received from the server \"%s\" is\n\n%s\n\nbut the stored key is\n\n%s\n\nThis may indicate that this is not the same server that was previously used.\n\nDo you wish to accept and store the new key, and continue with the connection?"), m_tunnelhost.c_str(), newHostKey.c_str(), cachedHostKey.c_str()); + int answer = wxMessageBox(msg, wxT("Host key verification - WARNING"), wxYES_NO | wxNO_DEFAULT); + if (answer == wxYES) + { + // Write the host key with respect to tunnel host + settings->Write(wxT("HostKeys/") + m_tunnelhost, newHostKey); + bIsVerified = true; + } + } + } + + return bIsVerified; +} + +CSubThread::CSubThread(const struct sockaddr_in sin, const wxString remote_desthost, const unsigned int remote_destport, + LIBSSH2_SESSION *session, int forwardsock) + : m_sin(sin), m_remote_desthost(remote_desthost), m_remote_destport(remote_destport), + m_subThreadSession(session), m_forwardsock(forwardsock) +{ +} + +CSubThread::~CSubThread(void) +{ + g_SSHThreadMutex.Lock(); + g_setSocketDescriptor.erase(m_forwardsock); + g_SSHThreadMutex.Unlock(); +} + +void * +CSubThread::Entry() +{ + fd_set fds; + struct timeval tv; + ssize_t len, wr; + char buf[20480]; + int rc, i = 0; + + const char *shost = inet_ntoa(m_sin.sin_addr); + unsigned int sport = ntohs(m_sin.sin_port); + + wxLogInfo(wxT("Forwarding connection from %s:%d to %s:%d"), wxString(inet_ntoa(m_sin.sin_addr), wxConvLibc).c_str(), + sport, m_remote_desthost.c_str(), m_remote_destport); + + /* Must use blocking here to avoid connect errors */ + //libssh2_session_set_blocking(m_subThreadSession, 1); + + while((m_channel = libssh2_channel_direct_tcpip_ex(m_subThreadSession, m_remote_desthost.mb_str(), + m_remote_destport, shost, sport)) == NULL) + { + rc = libssh2_session_last_error(m_subThreadSession, NULL, NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) + Sleep(10); + else + break; + } + + /* Must use non-blocking IO hereafter due to the current libssh2 API */ + libssh2_session_set_blocking(m_subThreadSession, 0); + + if (!m_channel) + { + wxLogInfo(_("SSH error: Could not open a direct-tcpip channel!")); + goto shutdown; + } + + while (1) + { + FD_ZERO(&fds); + FD_SET(m_forwardsock, &fds); + tv.tv_sec = 0; + tv.tv_usec = 100000; + rc = select(m_forwardsock + 1, &fds, NULL, NULL, &tv); + memset(buf, 0, sizeof(buf)); + if (-1 == rc) + { + wxLogInfo(_("SSH error: select failed with error code %d"), wxSysErrorCode()); + goto shutdown; + } + if (rc && FD_ISSET(m_forwardsock, &fds)) + { + len = recv(m_forwardsock, buf, sizeof(buf), 0); + if (len < 0) + { + wxLogInfo(_("SSH error: read failed with error code %d"), wxSysErrorCode()); + goto shutdown; + } + else if (0 == len) + { + wxLogInfo(_("The client at %s:%d disconnected!"), wxString(inet_ntoa(m_sin.sin_addr), wxConvLibc).c_str(), sport); + goto shutdown; + } + wr = 0; + do + { + i = libssh2_channel_write(m_channel, buf, len); + + if (i < 0) + { + wxLogInfo(_("SSH error: libssh2_channel_write with error code %d"), i); + goto shutdown; + } + wr += i; + } + while (i > 0 && wr < len); + } + while (1) + { + len = libssh2_channel_read(m_channel, buf, sizeof(buf)); + + if (LIBSSH2_ERROR_EAGAIN == len) + break; + else if (len < 0) + { + wxLogInfo(_("SSH error: libssh2_channel_read with error code %d"), (int)len); + goto shutdown; + } + wr = 0; + while (wr < len) + { + i = send(m_forwardsock, buf + wr, len - wr, 0); + if (i <= 0) + { + wxLogInfo(_("SSH error: write failed with error code %d"), wxSysErrorCode()); + goto shutdown; + } + wr += i; + } + if (libssh2_channel_eof(m_channel)) + { + wxLogInfo(_("Connection at %s:%d disconnected by server"), + wxString(inet_ntoa(m_sin.sin_addr), wxConvLibc).c_str(), sport); + goto shutdown; + } + } + } +shutdown: +#ifdef WIN32 + closesocket(m_forwardsock); +#else + close(m_forwardsock); +#endif + + if (m_channel) + { + libssh2_channel_close(m_channel); + libssh2_channel_free(m_channel); + m_channel = NULL; + } + + return NULL; +} + +void LogSSHTunnelErrors(const wxString &msg, const int &id, struct _LIBSSH2_SESSION *session) +{ + g_SSHThreadMutex.TryLock(); + + wxString errorMsg = msg; + // If session is not NULL then fetch the last error on that session + if (session) + { + char *errmsg; + int errmsg_len; + libssh2_session_last_error(session, &errmsg, &errmsg_len, 0); + if (errmsg_len > 0) + { + wxString errmsg_s(errmsg, wxConvLibc); + errorMsg += wxString::Format(_(" [%s]"), errmsg_s.c_str()); + } + } + + wxCommandEvent event(SSH_TUNNEL_ERROR_EVENT, id); + // Give it some contents + event.SetString(errorMsg); + + // Do send it + wxPostEvent(winMain, event); + + g_SSHThreadMutex.Unlock(); +} diff --git a/utils/sysLogger.cpp b/utils/sysLogger.cpp new file mode 100644 index 0000000..e2319d7 --- /dev/null +++ b/utils/sysLogger.cpp @@ -0,0 +1,312 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// sysLogger.cpp - Log handling class +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include + +// App headers +#if !defined(PGSCLI) +#include "copyright.h" // needed for APPNAME_L caption +#endif // PGSCLI + +#include "utils/sysLogger.h" + +wxLogLevel sysLogger::logLevel = LOG_ERRORS; +wxString sysLogger::logFile = wxT("debug.log"); + +#if !wxCHECK_VERSION(2, 9, 0) + +// IMPLEMENT_LOG_FUNCTION(Sql) from wx../common/log.c +void wxVLogQuietError(const wxChar *szFormat, va_list argptr) +{ + static wxChar s_szBuf[8192]; + + if (sysLogger::logLevel >= LOG_ERRORS) + { + wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr); + wxLog::OnLog(wxLOG_QuietError, s_szBuf, time(NULL)); + + } +} + +void wxLogQuietError(const wxChar *szFormat, ...) +{ + va_list argptr; + va_start(argptr, szFormat); + wxVLogQuietError(szFormat, argptr); + va_end(argptr); +} + + +void wxVLogSql(const wxChar *szFormat, va_list argptr) +{ + static wxChar s_szBuf[8192]; + + if (sysLogger::logLevel >= LOG_SQL) + { + wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr); + wxLog::OnLog(wxLOG_Sql, s_szBuf, time(NULL)); + + } +} + +void wxLogSql(const wxChar *szFormat, ...) +{ + va_list argptr; + va_start(argptr, szFormat); + wxVLogSql(szFormat, argptr); + va_end(argptr); +} + + + +void wxVLogNotice(const wxChar *szFormat, va_list argptr) +{ + static wxChar s_szBuf[8192]; + + if (sysLogger::logLevel >= LOG_NOTICE) + { + wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr); + wxLog::OnLog(wxLOG_Notice, s_szBuf, time(NULL)); + } +} + +void wxLogNotice(const wxChar *szFormat, ...) +{ + va_list argptr; + va_start(argptr, szFormat); + wxVLogNotice(szFormat, argptr); + va_end(argptr); +} + +void wxVLogScript(const wxChar *szFormat, va_list argptr) +{ + static wxChar s_szBuf[8192]; + + if (sysLogger::logLevel >= LOG_SQL) + { + wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr); + wxLog::OnLog(wxLOG_Script, s_szBuf, time(NULL)); + } +} + +void wxLogScript(const wxChar *szFormat, ...) +{ + va_list argptr; + va_start(argptr, szFormat); + wxVLogScript(szFormat, argptr); + va_end(argptr); +} + +void wxVLogScriptVerbose(const wxChar *szFormat, va_list argptr) +{ + static wxChar s_szBuf[8192]; + + if (sysLogger::logLevel >= LOG_DEBUG) + { + wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr); + wxLog::OnLog(wxLOG_ScriptVerbose, s_szBuf, time(NULL)); + } +} + +void wxLogScriptVerbose(const wxChar *szFormat, ...) +{ + va_list argptr; + va_start(argptr, szFormat); + wxVLogScriptVerbose(szFormat, argptr); + va_end(argptr); +} + +#endif + +#if wxCHECK_VERSION(2, 9, 0) +void sysLogger::DoLogTextAtLevel(wxLogLevel level, const wxString &msg) +#else +void sysLogger::DoLog(wxLogLevel level, const wxChar *msg, time_t timestamp) +#endif +{ + wxString msgtype, preamble; + int icon = 0; + + switch (level) + { + case wxLOG_FatalError: + msgtype = wxT("FATAL "); + preamble = _("A fatal error has occurred:\n\n"); + icon = wxICON_ERROR; + break; + + case wxLOG_Error: + msgtype = wxT("ERROR "); + preamble = _("An error has occurred:\n\n"); + icon = wxICON_ERROR; + break; + + case wxLOG_QuietError: + msgtype = wxT("ERROR "); + break; + + case wxLOG_Warning: + msgtype = wxT("WARNING"); + preamble = _("Warning:\n\n"); + icon = wxICON_EXCLAMATION; + break; + + case wxLOG_Message: + msgtype = wxT("MESSAGE"); + preamble = wxT(""); + icon = wxICON_INFORMATION; + break; + + case wxLOG_Info: + msgtype = wxT("INFO "); + break; + + case wxLOG_Status: + msgtype = wxT("STATUS "); + break; + + case wxLOG_Notice: + msgtype = wxT("NOTICE "); + break; + + case wxLOG_Sql: + msgtype = wxT("QUERY "); + break; + + case wxLOG_Script: + msgtype = wxT("SCRIPT "); + break; + + case wxLOG_ScriptVerbose: + msgtype = wxT("SCRIPT "); + break; + + case wxLOG_Trace: + msgtype = wxT("TRACE "); + break; + + case wxLOG_Debug: + msgtype = wxT("DEBUG "); + break; + + default: + msgtype = wxT("UNKNOWN"); + icon = wxICON_INFORMATION; + break; + } + + wxString fullmsg; + +#if wxCHECK_VERSION(2, 9, 0) + // Build the message. + fullmsg << msgtype << wxT(": ") << msg; +#else + // Convert the timestamp + wxDateTime *time = new wxDateTime(timestamp); + + // Build the message. + fullmsg << time->FormatISODate() << wxT(" ") << + time->FormatISOTime() << wxT(" ") << msgtype << wxT(": ") << msg; + + // Make sure to delete the time that we allocated + delete time; +#endif + + // Display the message if required + switch (logLevel) + { + case LOG_NONE: + break; + + case LOG_ERRORS: + if (level == wxLOG_FatalError || + level == wxLOG_Error || + level == wxLOG_QuietError) + WriteLog(fullmsg); + break; + + case LOG_NOTICE: + if (level == wxLOG_FatalError || + level == wxLOG_Error || + level == wxLOG_QuietError || + level == wxLOG_Notice) + WriteLog(fullmsg); + break; + + case LOG_SQL: + if (level == wxLOG_FatalError || + level == wxLOG_Error || + level == wxLOG_QuietError || + level == wxLOG_Message || + level == wxLOG_Status || + level == wxLOG_Notice || + level == wxLOG_Sql || + level == wxLOG_Script) + WriteLog(fullmsg); + break; + + case LOG_DEBUG: + WriteLog(fullmsg); + break; + } + + // Display a messagebox if required. +#if !defined(PGSCLI) + if (icon != 0 && !SilenceMessage(msg)) + wxMessageBox(preamble + wxGetTranslation(msg), appearanceFactory->GetLongAppName(), wxOK | wxCENTRE | icon); +#endif // PGSCLI +} + + +void sysLogger::WriteLog(const wxString &msg) +{ + wxString pid, logfile; + + // Disable logging to prevent recursion in the event of a problem + wxLogNull foo; + + pid.Printf(wxT("%ld"), wxGetProcessId()); + logfile.Printf(wxT("%s"), logFile.c_str()); + logfile.Replace(wxT("%ID"), pid); + + wxFFile file(logfile, wxT("a")); + +#if !defined(PGSCLI) + if (!file.IsOpened()) + { + wxMessageBox(_("Cannot open the logfile!"), _("FATAL"), wxOK | wxCENTRE | wxICON_ERROR); + return; + } +#endif // PGSCLI + + file.Write(msg + wxT("\n")); + file.Close(); +} + +// Check to see if a message should be silenced (because it's meaningless +// and cannot be silenced at source +bool sysLogger::SilenceMessage(const wxString &msg) +{ +#ifdef __WXMAC__ + // This one crops up on the Mac and originates from the logging code + // for no obviously apparent reason. + if (msg.Contains(_("can't flush file descriptor"))) + return true; +#endif + return false; +} + diff --git a/utils/sysProcess.cpp b/utils/sysProcess.cpp new file mode 100644 index 0000000..cc3540a --- /dev/null +++ b/utils/sysProcess.cpp @@ -0,0 +1,112 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// sysProcess.cpp - External process +// +////////////////////////////////////////////////////////////////////////// + + +// wxWindows headers +#include + + +// App headers +#include "pgAdmin3.h" +#include "utils/sysProcess.h" + + +sysProcess::sysProcess(wxEvtHandler *evh, wxMBConv &conv) + : wxProcess(evh), m_conv(conv) +{ + pid = 0; + Redirect(); +} + + +sysProcess *sysProcess::Create(const wxString &exec, wxEvtHandler *evh, wxArrayString *env, wxMBConv &conv) +{ + sysProcess *proc = new sysProcess(evh, conv); + if (env) + proc->SetEnvironment(*env); + + if (!proc->Run(exec)) + { + delete proc; + proc = 0; + } + return proc; +} + + +bool sysProcess::Run(const wxString &exec) +{ + pid = wxExecute(exec, wxEXEC_ASYNC, this); + return (pid != 0); +} + + +void sysProcess::SetEnvironment(const wxArrayString &environment) +{ + size_t i; + for (i = 0 ; i < environment.GetCount() ; i++) + { + wxString str = environment.Item(i); + wxSetEnv(str.BeforeFirst('='), str.AfterFirst('=')); + } +} + + +void sysProcess::Abort() +{ + if (pid) + wxKill(pid, wxSIGTERM); +} + + +wxString sysProcess::ReadInputStream() +{ + if (IsInputAvailable()) + return ReadStream(GetInputStream()); + return wxEmptyString; +} + + +wxString sysProcess::ReadErrorStream() +{ + if (IsErrorAvailable()) + return ReadStream(GetErrorStream()); + return wxEmptyString; +} + +void sysProcess::WriteOutputStream(const wxString &out) +{ + // With wxEOL_DOS (=wxEOL_NATIVE in Windows) WriteString() will turn each '\n' + // into "\r\n", thus making "\r\n" a wrong "\r\r\n". + // With wxEOL_UNIX it passes EOL characters as-is, which is preferable. + wxTextOutputStream tos(*GetOutputStream(), wxEOL_UNIX); + tos.WriteString(out); +} + +wxString sysProcess::ReadStream(wxInputStream *input) +{ + wxString str; + + char buffer[1000 + 1]; + size_t size = 1; + while (size && !input->Eof()) + { + input->Read(buffer, sizeof(buffer) - 1); + size = input->LastRead(); + if (size) + { + buffer[size] = 0; + str.Append(wxString::Format(wxT("%s"), wxString(buffer, m_conv).c_str())); + } + } + return str; +} + diff --git a/utils/sysSettings.cpp b/utils/sysSettings.cpp new file mode 100644 index 0000000..90a41e6 --- /dev/null +++ b/utils/sysSettings.cpp @@ -0,0 +1,935 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// sysSettings.cpp - Settings handling class +// +// Note: This class stores and manages all the applications settings. +// Settings are all read in the ctor, but may be written either in +// the relevant SetXXX() member function for rarely written settings +// or in the dtor for regularly changed settings such as form sizes. +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + + +// wxWindows headers +#include +#include +#include +#include +#include +#include +#include +#include +// App headers +#include "utils/sysSettings.h" +#include "utils/sysLogger.h" +#include "utils/misc.h" +sysSettings::sysSettings(const wxString &name) : wxConfig(name) +{ + // Open the default settings file + defaultSettings = NULL; + if (!settingsIni.IsEmpty()) + { + wxFileInputStream fst(settingsIni); + defaultSettings = new wxFileConfig(fst); + } + + // Convert settings from pre-1.5 + long i, serverCount; + Read(wxT("Servers/Count"), &serverCount, 0L); + for (i = 1 ; i <= serverCount ; i++) + { + if (moveStringValue(wxT("Servers/Database%d"), wxT("Servers/%d/Database"), i)) + { + moveStringValue(wxT("Servers/Description%d"), wxT("Servers/%d/Description"), i); + moveStringValue(wxT("Servers/LastDatabase%d"), wxT("Servers/%d/LastDatabase"), i); + moveStringValue(wxT("Servers/LastSchema%d"), wxT("Servers/%d/LastSchema"), i); + moveStringValue(wxT("Servers/Server%d"), wxT("Servers/%d/Server"), i); + moveStringValue(wxT("Servers/ServiceId%d"), wxT("Servers/%d/ServiceId"), i); + moveStringValue(wxT("Servers/StorePWD%d"), wxT("Servers/%d/StorePWD"), i); + moveStringValue(wxT("Servers/Rolename%d"), wxT("Servers/%d/Rolename"), i); + moveStringValue(wxT("Servers/Username%d"), wxT("Servers/%d/Username"), i); + moveLongValue(wxT("Servers/Port%d"), wxT("Servers/%d/Port"), i); + moveLongValue(wxT("Servers/SSL%d"), wxT("Servers/%d/SSL"), i); + } + } +} + +sysSettings::~sysSettings() +{ + + if(defaultSettings) + { + delete defaultSettings; + defaultSettings = NULL; + } +} + +bool sysSettings::GetDisplayOption(const wxString &objtype, bool GetDefault) +{ + bool retval, def = true; + wxString engtype; + + if (objtype == _("Databases")) + engtype = wxT("Databases"); + else if (objtype == _("Tablespaces")) + engtype = wxT("Tablespaces"); + else if (objtype == _("pgAgent Jobs")) + engtype = wxT("pgAgent Jobs"); + else if (objtype == _("Groups/group Roles")) + engtype = wxT("Groups-login Roles"); + else if (objtype == _("Users/login Roles")) + engtype = wxT("Users-login Roles"); + else if (objtype == _("Resource Queues")) + engtype = wxT("Resource Queues"); + else if (objtype == _("Resource Groups")) + engtype = wxT("Resource Groups"); + else if (objtype == _("Catalogs")) + engtype = wxT("Catalogs"); + else if (objtype == _("Casts")) + { + engtype = wxT("Casts"); + def = false; + } + else if (objtype == _("Foreign Data Wrappers")) + { + engtype = wxT("Foreign Data Wrappers"); + def = false; + } + else if (objtype == _("Foreign Servers")) + { + engtype = wxT("Foreign Servers"); + def = false; + } + else if (objtype == _("User Mappings")) + { + engtype = wxT("User Mappings"); + def = false; + } + else if (objtype == _("Foreign Tables")) + { + engtype = wxT("Foreign Tables"); + def = false; + } + else if (objtype == _("Languages")) + { + engtype = wxT("Languages"); + def = false; + } + else if (objtype == _("Extensions")) + engtype = wxT("Extensions"); + else if (objtype == _("Synonyms")) + engtype = wxT("Synonyms"); + else if (objtype == _("Schemas")) + engtype = wxT("Schemas"); + else if (objtype == _("Slony-I Clusters")) + engtype = wxT("Slony-I Clusters"); + else if (objtype == _("Aggregates")) + { + engtype = wxT("Aggregates"); + def = false; + } + else if (objtype == _("Conversions")) + { + engtype = wxT("Conversions"); + def = false; + } + else if (objtype == _("Domains")) + engtype = wxT("Domains"); + else if (objtype == _("Functions")) + engtype = wxT("Functions"); + else if (objtype == _("Trigger Functions")) + engtype = wxT("Trigger Functions"); + else if (objtype == _("Packages")) + engtype = wxT("Packages"); + else if (objtype == _("Procedures")) + engtype = wxT("Procedures"); + else if (objtype == _("Operators")) + { + engtype = wxT("Operators"); + def = false; + } + else if (objtype == _("Operator Classes")) + { + engtype = wxT("Operator Classes"); + def = false; + } + else if (objtype == _("Operator Families")) + { + engtype = wxT("Operator Families"); + def = false; + } + else if (objtype == _("Sequences")) + engtype = wxT("Sequences"); + else if (objtype == _("Tables")) + engtype = wxT("Tables"); + else if (objtype == _("FTS Configurations")) + engtype = wxT("FTS Configurations"); + else if (objtype == _("FTS Dictionaries")) + engtype = wxT("FTS Dictionaries"); + else if (objtype == _("FTS Parsers")) + engtype = wxT("FTS Parsers"); + else if (objtype == _("FTS Templates")) + engtype = wxT("FTS Templates"); + else if (objtype == _("Types")) + { + engtype = wxT("Types"); + def = false; + } + else if (objtype == _("Views")) + engtype = wxT("Views"); + else if (objtype == _("External Tables")) + engtype = wxT("External Tables"); + else if (objtype == _("Event Triggers")) + engtype = wxT("Event Triggers"); + + // If we just want the default, return it. + if (GetDefault) + return def; + + // Otherwise get the reg value. + Read(wxT("Display/") + engtype, &retval, def); + return retval; +} + +void sysSettings::SetDisplayOption(const wxString &objtype, bool display) +{ + wxString engtype; + + if (objtype == _("Databases")) engtype = wxT("Databases"); + else if (objtype == _("Tablespaces")) engtype = wxT("Tablespaces"); + else if (objtype == _("pgAgent Jobs")) engtype = wxT("pgAgent Jobs"); + else if (objtype == _("Groups/group Roles")) engtype = wxT("Groups-login Roles"); + else if (objtype == _("Users/login Roles")) engtype = wxT("Users-login Roles"); + else if (objtype == _("Resource Queues")) engtype = wxT("Resource Queues"); + else if (objtype == _("Resource Groups")) engtype = wxT("Resource Groups"); + else if (objtype == _("Catalogs")) engtype = wxT("Catalogs"); + else if (objtype == _("Casts")) engtype = wxT("Casts"); + else if (objtype == _("Foreign Data Wrappers")) engtype = wxT("Foreign Data Wrappers"); + else if (objtype == _("Foreign Servers")) engtype = wxT("Foreign Servers"); + else if (objtype == _("User Mappings")) engtype = wxT("User mappings"); + else if (objtype == _("Foreign Tables")) engtype = wxT("Foreign Tables"); + else if (objtype == _("Languages")) engtype = wxT("Languages"); + else if (objtype == _("Event Triggers")) engtype = wxT("Event Triggers"); + else if (objtype == _("Extensions")) engtype = wxT("Extensions"); + else if (objtype == _("Synonyms")) engtype = wxT("Synonyms"); + else if (objtype == _("Schemas")) engtype = wxT("Schemas"); + else if (objtype == _("Slony-I Clusters")) engtype = wxT("Slony-I Clusters"); + else if (objtype == _("Aggregates")) engtype = wxT("Aggregates"); + else if (objtype == _("Conversions")) engtype = wxT("Conversions"); + else if (objtype == _("Domains")) engtype = wxT("Domains"); + else if (objtype == _("Functions")) engtype = wxT("Functions"); + else if (objtype == _("Trigger Functions")) engtype = wxT("Trigger Functions"); + else if (objtype == _("Packages")) engtype = wxT("Packages"); + else if (objtype == _("Procedures")) engtype = wxT("Procedures"); + else if (objtype == _("Operators")) engtype = wxT("Operators"); + else if (objtype == _("Operator Classes")) engtype = wxT("Operator Classes"); + else if (objtype == _("Operator Families")) engtype = wxT("Operator Families"); + else if (objtype == _("Sequences")) engtype = wxT("Sequences"); + else if (objtype == _("Tables")) engtype = wxT("Tables"); + else if (objtype == _("FTS Configurations")) engtype = wxT("FTS Configurations"); + else if (objtype == _("FTS Dictionaries")) engtype = wxT("FTS Dictionaries"); + else if (objtype == _("FTS Parsers")) engtype = wxT("FTS Parsers"); + else if (objtype == _("FTS Templates")) engtype = wxT("FTS Templates"); + else if (objtype == _("Types")) engtype = wxT("Types"); + else if (objtype == _("Views")) engtype = wxT("Views"); + else if (objtype == _("External Tables")) engtype = wxT("External Tables"); + + WriteBool(wxT("Display/") + engtype, display); +} + +bool sysSettings::moveStringValue(const wxChar *oldKey, const wxChar *newKey, int index) +{ + wxString k1, k2; + if (index >= 0) + { + k1.Printf(oldKey, index); + k2.Printf(newKey, index); + } + else + { + k1 = oldKey; + k2 = newKey; + } + + if (!Exists(k2) && Exists(k1)) + { + wxString value; + Read(k1, &value, wxEmptyString); + Write(k2, value); + + return true; + } + + return false; +} + + + +bool sysSettings::moveLongValue(const wxChar *oldKey, const wxChar *newKey, int index) +{ + wxString k1, k2; + if (index >= 0) + { + k1.Printf(oldKey, index); + k2.Printf(newKey, index); + } + else + { + k1 = oldKey; + k2 = newKey; + } + + if (!Exists(k2) && Exists(k1)) + { + long value; + Read(k1, &value, 0L); + WriteLong(k2, value); + + return true; + } + + return false; +} + +// Read a string value +bool sysSettings::Read(const wxString &key, wxString *str, const wxString &defaultVal) const +{ + wxString actualDefault = defaultVal; + + // Get the default from the defaults file, in preference + // to the hardcoded value + if (defaultSettings) + defaultSettings->Read(key, &actualDefault, defaultVal); + + return wxConfig::Read(key, str, actualDefault); +} + +// Return a string value +wxString sysSettings::Read(const wxString &key, const wxString &defaultVal) const +{ + wxString actualDefault = defaultVal; + + // Get the default from the defaults file, in preference + // to the hardcoded value + if (defaultSettings) + defaultSettings->Read(key, &actualDefault, defaultVal); + + return wxConfig::Read(key, actualDefault); +} + +// Read an int value +bool sysSettings::Read(const wxString &key, int *i, int defaultVal) const +{ + int actualDefault = defaultVal; + + // Get the default from the defaults file, in preference + // to the hardcoded value + if (defaultSettings) + defaultSettings->Read(key, &actualDefault, defaultVal); + + return wxConfig::Read(key, i, actualDefault); +} + +// Read a long value +bool sysSettings::Read(const wxString &key, long *l, long defaultVal) const +{ + long actualDefault = defaultVal; + + // Get the default from the defaults file, in preference + // to the hardcoded value + if (defaultSettings) + defaultSettings->Read(key, &actualDefault, defaultVal); + + return wxConfig::Read(key, l, actualDefault); +} + + +// Return a long value +long sysSettings::Read(const wxString &key, long defaultVal) const +{ + long actualDefault = defaultVal; + + // Get the default from the defaults file, in preference + // to the hardcoded value + if (defaultSettings) + defaultSettings->Read(key, &actualDefault, defaultVal); + + return wxConfig::Read(key, actualDefault); +} + +// Read a boolean value +bool sysSettings::Read(const wxString &key, bool *val, bool defaultVal) const +{ + wxString actualDefault = BoolToStr(defaultVal); + wxString str; + + // Get the default from the defaults file, in preference + // to the hardcoded value + if (defaultSettings) + defaultSettings->Read(key, &actualDefault, BoolToStr(defaultVal)); + + Read(key, &str, actualDefault); + *val = StrToBool(str); + return true; +} + +// Read a point value +wxPoint sysSettings::Read(const wxString &key, const wxPoint &defaultVal) const +{ + wxPoint actualDefault = defaultVal; + + // Get the default from the defaults file, in preference + // to the hardcoded value + if (defaultSettings) + { + actualDefault.x = defaultSettings->Read(key + wxT("/Left"), defaultVal.x); + actualDefault.y = defaultSettings->Read(key + wxT("/Top"), defaultVal.y); + } + + return wxPoint(wxConfig::Read(key + wxT("/Left"), actualDefault.x), + wxConfig::Read(key + wxT("/Top"), actualDefault.y)); +} + +// Read a size value +wxSize sysSettings::Read(const wxString &key, const wxSize &defaultVal) const +{ + wxSize actualDefault = defaultVal; + + // Get the default from the defaults file, in preference + // to the hardcoded value + if (defaultSettings) + { + actualDefault.x = defaultSettings->Read(key + wxT("/Width"), defaultVal.x); + actualDefault.y = defaultSettings->Read(key + wxT("/Height"), defaultVal.y); + } + + return wxSize(wxConfig::Read(key + wxT("/Width"), actualDefault.x), + wxConfig::Read(key + wxT("/Height"), actualDefault.y)); +} + +// Write a boolean value +bool sysSettings::WriteBool(const wxString &key, bool value) +{ + return Write(key, BoolToStr(value)); +} + +// Write a point value +bool sysSettings::WritePoint(const wxString &key, const wxPoint &value) +{ + bool rc = wxConfig::Write(key + wxT("/Left"), value.x); + if (rc) + rc = wxConfig::Write(key + wxT("/Top"), value.y); + return rc; +} + +// Write a size value +bool sysSettings::WriteSize(const wxString &key, const wxSize &value) +{ + bool rc = wxConfig::Write(key + wxT("/Width"), value.x); + if (rc) + rc = wxConfig::Write(key + wxT("/Height"), value.y); + return rc; +} + + +////////////////////////////////////////////////////////////////////////// +// Log +////////////////////////////////////////////////////////////////////////// + +wxString sysSettings::GetLogFile() +{ + wxString logFile; + + // Try to get a vaguely usable default path. + char *homedir; +#ifdef __WXMSW__ + char *homedrive; +#endif + + wxString deflog; + +#ifdef __WXMSW__ + homedrive = getenv("HOMEDRIVE"); + homedir = getenv("HOMEPATH"); +#else + homedir = getenv("HOME"); +#endif + + if (!homedir) + deflog = wxT("pgadmin.log"); + else + { + +#ifdef __WXMSW__ +#if wxCHECK_VERSION(2, 9, 5) + wxStandardPaths &paths = wxStandardPaths::Get(); +#else + wxStandardPaths paths; +#endif + deflog = paths.GetDocumentsDir(); + deflog += wxT("\\pgadmin.log"); +#else + deflog = wxString::FromAscii(homedir); + deflog += wxT("/pgadmin.log"); +#endif + } + + Read(wxT("LogFile"), &logFile, deflog); + + return logFile; +} + +////////////////////////////////////////////////////////////////////////// +// Help files +////////////////////////////////////////////////////////////////////////// + +wxString sysSettings::GetSlonyHelpPath() +{ + wxString path; + + Read(wxT("SlonyHelpPath"), &path, wxT("")); + path = CleanHelpPath(path); + + if (!HelpPathValid(path)) + path = wxEmptyString; + + return path; +} + +wxString sysSettings::GetPgHelpPath() +{ + wxString path; + + Read(wxT("PostgreSQLHelpPath"), &path, wxT("")); + path = CleanHelpPath(path); + + if (!HelpPathValid(path)) + path = wxEmptyString; + + return path; +} + +wxString sysSettings::GetEdbHelpPath() +{ + wxString path; + + Read(wxT("EnterpriseDBHelpPath"), &path, wxT("")); + path = CleanHelpPath(path); + + if (!HelpPathValid(path)) + path = wxEmptyString; + + return path; +} + +wxString sysSettings::GetGpHelpPath() +{ + wxString path; + + Read(wxT("GreenplumDBHelpPath"), &path, wxT("")); + path = CleanHelpPath(path); + + if (!HelpPathValid(path)) + path = wxEmptyString; + + return path; +} +////////////////////////////////////////////////////////////////////////// +// Copy quoting +////////////////////////////////////////////////////////////////////////// + +int sysSettings::GetCopyQuoting() +{ + wxString val; + + Read(wxT("Copy/Quote"), &val, wxT("Strings")); + if (val == wxT("All")) + return 2; + else if (val == wxT("Strings")) + return 1; + else + return 0; +} + +void sysSettings::SetCopyQuoting(const int i) +{ + switch (i) + { + case 2: + Write(wxT("Copy/Quote"), wxT("All")); + break; + case 1: + Write(wxT("Copy/Quote"), wxT("Strings")); + break; + case 0: + Write(wxT("Copy/Quote"), wxT("None")); + break; + default: + break; + } +} + +////////////////////////////////////////////////////////////////////////// +// Export quoting +////////////////////////////////////////////////////////////////////////// + +int sysSettings::GetExportQuoting() +{ + wxString val; + + Read(wxT("Export/Quote"), &val, wxT("Strings")); + if (val == wxT("All")) + return 2; + else if (val == wxT("Strings")) + return 1; + else + return 0; +} + +void sysSettings::SetExportQuoting(const int i) +{ + switch (i) + { + case 2: + Write(wxT("Export/Quote"), wxT("All")); + break; + case 1: + Write(wxT("Export/Quote"), wxT("Strings")); + break; + case 0: + Write(wxT("Export/Quote"), wxT("None")); + break; + default: + break; + } +} + +////////////////////////////////////////////////////////////////////////// +// Export quoting +////////////////////////////////////////////////////////////////////////// + +wxString sysSettings::GetExportRowSeparator() +{ + wxString val; +#ifdef __WXMSW__ + Read(wxT("Export/RowSeparator"), &val, wxT("CR/LF")); +#else + Read(wxT("Export/RowSeparator"), &val, wxT("LF")); +#endif + if (val == wxT("CR/LF")) + return wxT("\r\n"); + else + return wxT("\n"); +} + +void sysSettings::SetExportRowSeparator(const wxString &s) +{ + if (s == wxT("\r\n")) + Write(wxT("Export/RowSeparator"), wxT("CR/LF")); + else + Write(wxT("Export/RowSeparator"), wxT("LF")); +} + +////////////////////////////////////////////////////////////////////////// +// System Font +////////////////////////////////////////////////////////////////////////// + +wxFont sysSettings::GetSystemFont() +{ + wxString fontName; + + Read(wxT("Font"), &fontName, wxEmptyString); + + if (fontName.IsEmpty()) + return wxSystemSettings::GetFont(wxSYS_ICONTITLE_FONT); + else + return wxFont(fontName); +} + +void sysSettings::SetSystemFont(const wxFont &font) +{ + wxString fontName = font.GetNativeFontInfoDesc(); + + if (fontName == wxSystemSettings::GetFont(wxSYS_ICONTITLE_FONT).GetNativeFontInfoDesc()) + Write(wxT("Font"), wxString(wxEmptyString)); + else + Write(wxT("Font"), fontName); +} + +////////////////////////////////////////////////////////////////////////// +// SQL Font +////////////////////////////////////////////////////////////////////////// + +wxFont sysSettings::GetSQLFont() +{ + wxString fontName; + + Read(wxT("frmQuery/Font"), &fontName, wxEmptyString); + + if (fontName.IsEmpty()) + { +#ifdef __WXMSW__ + return wxFont(9, wxTELETYPE, wxNORMAL, wxNORMAL); +#else +#ifdef __WXGTK__ + return wxFont(10, wxTELETYPE, wxNORMAL, wxNORMAL); +#else + return wxFont(12, wxTELETYPE, wxNORMAL, wxNORMAL); +#endif +#endif + } + else + return wxFont(fontName); +} + +void sysSettings::SetSQLFont(const wxFont &font) +{ + wxString fontName = font.GetNativeFontInfoDesc(); + + Write(wxT("frmQuery/Font"), fontName); +} + +////////////////////////////////////////////////////////////////////////// +// Database Designer Font +////////////////////////////////////////////////////////////////////////// + +wxFont sysSettings::GetDDFont() +{ + wxString fontName; + + Read(wxT("DDFont"), &fontName, wxEmptyString); + + if (fontName.IsEmpty()) + return wxSystemSettings::GetFont(wxSYS_ICONTITLE_FONT); + else + return wxFont(fontName); +} + +void sysSettings::SetDDFont(const wxFont &font) +{ + wxString fontName = font.GetNativeFontInfoDesc(); + + if (fontName == wxSystemSettings::GetFont(wxSYS_ICONTITLE_FONT).GetNativeFontInfoDesc()) + Write(wxT("DDFont"), wxString(wxEmptyString)); + else + Write(wxT("DDFont"), fontName); +} + +////////////////////////////////////////////////////////////////////////// +// Language +////////////////////////////////////////////////////////////////////////// + +wxString sysSettings::GetCanonicalLanguageName() +{ + const wxLanguageInfo *langInfo; + + langInfo = wxLocale::GetLanguageInfo(Read(wxT("LanguageId"), wxLANGUAGE_DEFAULT)); + + if (langInfo) + return langInfo->CanonicalName; + + return wxEmptyString; +} + +void sysSettings::SetCanonicalLanguage(const wxLanguage &lang) +{ + if (wxLocale::GetLanguageName(lang) != GetCanonicalLanguageName()) + { + delete locale; + locale = new wxLocale(); + if (locale->Init(lang)) + { +#ifdef __LINUX__ + { + wxLogNull noLog; + locale->AddCatalog(wxT("fileutils")); + } +#endif + locale->AddCatalog(wxT("pgadmin3")); + settings->WriteLong(wxT("LanguageId"), (long)lang); + } + } +} + +////////////////////////////////////////////////////////////////////////// +// Get system wide configuration file names +////////////////////////////////////////////////////////////////////////// +wxString sysSettings::GetConfigFile(configFileName cfgname) +{ + wxASSERT_MSG(cfgname == sysSettings::PGPASS, + wxT("Handles only pgpass configuration")); + if (cfgname == PGPASS) + { +#if wxCHECK_VERSION(2, 9, 5) + wxStandardPaths &stdp = wxStandardPaths::Get(); +#else + wxStandardPaths stdp; +#endif + wxString fname; + bool bpsfile = wxGetEnv(wxT("PGPASSFILE"), &fname); + if (!bpsfile) + { + fname = stdp.GetUserConfigDir(); +#ifdef WIN32 + fname += wxT("\\postgresql"); + if (!wxDirExists(fname)) + wxMkdir(fname); + fname += wxT("\\pgpass.conf"); + } +#else + fname += wxT("/.pgpass"); + } +#endif + else + { + if(!wxFileName::FileExists(fname)) + { + wxFileName dirTemp = wxFileName::DirName(fname); + /* + * wxFileName::DirName() does not return the directory path of + * the file. It assumes that the given path is of a directory, + * when the specified file/directory does not exist. + * + * Hence - removeing it to get the actual parent directory. + */ + dirTemp.RemoveLastDir(); + + if (!dirTemp.DirExists()) + { + wxFileName dir = dirTemp; + + // Decide which are folders we need to create + wxString sRemoveOnError = dirTemp.GetPath(); + + while(!dirTemp.DirExists()) + { + sRemoveOnError = dirTemp.GetPath(); + dirTemp.RemoveLastDir(); + } + + if (!dir.Mkdir(0755, wxPATH_MKDIR_FULL)) + { + // In case of failure decide - we may need to delete + // the created directory structure from exists parent + // directory. + if (wxDir::Exists(sRemoveOnError)) + wxFileName::Rmdir(sRemoveOnError); + } + } + } + } + + wxFile f; + if (!f.Exists(fname)) + f.Create(fname, false, wxS_IRUSR | wxS_IWUSR); + + return fname; + } + + return wxT(""); +} + + +wxString sysSettings::GetFavouritesFile() +{ + wxString s, tmp; + +#if wxCHECK_VERSION(2, 9, 5) + wxStandardPaths &stdp = wxStandardPaths::Get(); +#else + wxStandardPaths stdp; +#endif + tmp = stdp.GetUserConfigDir(); +#ifdef WIN32 + tmp += wxT("\\postgresql"); + if (!wxDirExists(tmp)) + wxMkdir(tmp); + tmp += wxT("\\pgadmin_favourites.xml"); +#else + tmp += wxT("/.pgadminfavourites"); +#endif + + Read(wxT("FavouritesFile"), &s, tmp); + + return s; +} + + +wxString sysSettings::GetMacrosFile() +{ + wxString s, tmp; + +#if wxCHECK_VERSION(2, 9, 5) + wxStandardPaths &stdp = wxStandardPaths::Get(); +#else + wxStandardPaths stdp; +#endif + tmp = stdp.GetUserConfigDir(); +#ifdef WIN32 + tmp += wxT("\\postgresql"); + if (!wxDirExists(tmp)) + wxMkdir(tmp); + tmp += wxT("\\pgadmin_macros.xml"); +#else + tmp += wxT("/.pgadminmacros"); +#endif + + Read(wxT("MacrosFile"), &s, tmp); + + return s; +} +wxString sysSettings::GetAutoReplaceFile() +{ + wxString s, tmp; + +#if wxCHECK_VERSION(2, 9, 5) + wxStandardPaths &stdp = wxStandardPaths::Get(); +#else + wxStandardPaths stdp; +#endif + tmp = stdp.GetUserConfigDir(); +#ifdef WIN32 + tmp += wxT("\\postgresql"); + if (!wxDirExists(tmp)) + wxMkdir(tmp); + tmp += wxT("\\pgadmin_autoreplace.xml"); +#else + tmp += wxT("/.pgadminautoreplace"); +#endif + + Read(wxT("AutoReplaceFile"), &s, tmp); + + return s; +} + + +wxString sysSettings::GetHistoryFile() +{ + wxString s, tmp; + +#if wxCHECK_VERSION(2, 9, 5) + wxStandardPaths &stdp = wxStandardPaths::Get(); +#else + wxStandardPaths stdp; +#endif + tmp = stdp.GetUserConfigDir(); +#ifdef WIN32 + tmp += wxT("\\postgresql"); + if (!wxDirExists(tmp)) + wxMkdir(tmp); + tmp += wxT("\\pgadmin_histoqueries.xml"); +#else + tmp += wxT("/.pgadmin_histoqueries"); +#endif + + Read(wxT("History/File"), &s, tmp); + + return s; +} + diff --git a/utils/tab-complete.inc b/utils/tab-complete.inc new file mode 100644 index 0000000..98b7a35 --- /dev/null +++ b/utils/tab-complete.inc @@ -0,0 +1,1741 @@ +typedef struct SchemaQuery +{ + /* + * Name of catalog or catalogs to be queried, with alias, eg. + * "pg_catalog.pg_class c". Note that "pg_namespace n" will be added. + */ + const char *catname; + + /* + * Selection condition --- only rows meeting this condition are candidates + * to display. If catname mentions multiple tables, include the necessary + * join condition here. For example, "c.relkind = 'r'". Write NULL (not + * an empty string) if not needed. + */ + const char *selcondition; + + /* + * Visibility condition --- which rows are visible without schema + * qualification? For example, "pg_catalog.pg_table_is_visible(c.oid)". + */ + const char *viscondition; + + /* + * Namespace --- name of field to join to pg_namespace.oid. For example, + * "c.relnamespace". + */ + const char *namespace; + + /* + * Result --- the appropriately-quoted name to return, in the case of an + * unqualified name. For example, "pg_catalog.quote_ident(c.relname)". + */ + const char *result; + + /* + * In some cases a different result must be used for qualified names. + * Enter that here, or write NULL if result can be used. + */ + const char *qualresult; +} SchemaQuery; + + +/* + * Communication variables set by COMPLETE_WITH_FOO macros and then used by + * the completion callback functions. Ugly but there is no better way. + */ +static const char *completion_charp; /* to pass a string */ +static const char *const * completion_charpp; /* to pass a list of strings */ +static const char *completion_info_charp; /* to pass a second string */ + +/* + * Assembly instructions for schema queries + */ + +static const SchemaQuery Query_for_list_of_aggregates = { + /* catname */ + "pg_catalog.pg_proc p", + /* selcondition */ + "p.proisagg", + /* viscondition */ + "pg_catalog.pg_function_is_visible(p.oid)", + /* namespace */ + "p.pronamespace", + /* result */ + "pg_catalog.quote_ident(p.proname)", + /* qualresult */ + NULL +}; + +static const SchemaQuery Query_for_list_of_datatypes = { + /* catname */ + "pg_catalog.pg_type t", + /* selcondition --- ignore table rowtypes and array types */ + "(t.typrelid = 0 " + " OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)) " + "AND t.typname !~ '^_'", + /* viscondition */ + "pg_catalog.pg_type_is_visible(t.oid)", + /* namespace */ + "t.typnamespace", + /* result */ + "pg_catalog.format_type(t.oid, NULL)", + /* qualresult */ + "pg_catalog.quote_ident(t.typname)" +}; + +static const SchemaQuery Query_for_list_of_domains = { + /* catname */ + "pg_catalog.pg_type t", + /* selcondition */ + "t.typtype = 'd'", + /* viscondition */ + "pg_catalog.pg_type_is_visible(t.oid)", + /* namespace */ + "t.typnamespace", + /* result */ + "pg_catalog.quote_ident(t.typname)", + /* qualresult */ + NULL +}; + +static const SchemaQuery Query_for_list_of_functions = { + /* catname */ + "pg_catalog.pg_proc p", + /* selcondition */ + NULL, + /* viscondition */ + "pg_catalog.pg_function_is_visible(p.oid)", + /* namespace */ + "p.pronamespace", + /* result */ + "pg_catalog.quote_ident(p.proname)", + /* qualresult */ + NULL +}; + +static const SchemaQuery Query_for_list_of_indexes = { + /* catname */ + "pg_catalog.pg_class c", + /* selcondition */ + "c.relkind IN ('i')", + /* viscondition */ + "pg_catalog.pg_table_is_visible(c.oid)", + /* namespace */ + "c.relnamespace", + /* result */ + "pg_catalog.quote_ident(c.relname)", + /* qualresult */ + NULL +}; + +static const SchemaQuery Query_for_list_of_sequences = { + /* catname */ + "pg_catalog.pg_class c", + /* selcondition */ + "c.relkind IN ('S')", + /* viscondition */ + "pg_catalog.pg_table_is_visible(c.oid)", + /* namespace */ + "c.relnamespace", + /* result */ + "pg_catalog.quote_ident(c.relname)", + /* qualresult */ + NULL +}; + +static const SchemaQuery Query_for_list_of_tables = { + /* catname */ + "pg_catalog.pg_class c", + /* selcondition */ + "c.relkind IN ('r')", + /* viscondition */ + "pg_catalog.pg_table_is_visible(c.oid)", + /* namespace */ + "c.relnamespace", + /* result */ + "pg_catalog.quote_ident(c.relname)", + /* qualresult */ + NULL +}; + +static const SchemaQuery Query_for_list_of_tisv = { + /* catname */ + "pg_catalog.pg_class c", + /* selcondition */ + "c.relkind IN ('r', 'i', 'S', 'v')", + /* viscondition */ + "pg_catalog.pg_table_is_visible(c.oid)", + /* namespace */ + "c.relnamespace", + /* result */ + "pg_catalog.quote_ident(c.relname)", + /* qualresult */ + NULL +}; + +static const SchemaQuery Query_for_list_of_tsv = { + /* catname */ + "pg_catalog.pg_class c", + /* selcondition */ + "c.relkind IN ('r', 'S', 'v')", + /* viscondition */ + "pg_catalog.pg_table_is_visible(c.oid)", + /* namespace */ + "c.relnamespace", + /* result */ + "pg_catalog.quote_ident(c.relname)", + /* qualresult */ + NULL +}; + +static const SchemaQuery Query_for_list_of_views = { + /* catname */ + "pg_catalog.pg_class c", + /* selcondition */ + "c.relkind IN ('v')", + /* viscondition */ + "pg_catalog.pg_table_is_visible(c.oid)", + /* namespace */ + "c.relnamespace", + /* result */ + "pg_catalog.quote_ident(c.relname)", + /* qualresult */ + NULL +}; + + +/* + * Queries to get lists of names of various kinds of things, possibly + * restricted to names matching a partially entered name. In these queries, + * %s will be replaced by the text entered so far (suitably escaped to + * become a SQL literal string). %d will be replaced by the length of the + * string (in unescaped form). A second %s, if present, will be replaced + * by a suitably-escaped version of the string provided in + * completion_info_charp. + * + * Beware that the allowed sequences of %s and %d are determined by + * _complete_from_query(). + */ + +#define Query_for_list_of_attributes \ +"SELECT pg_catalog.quote_ident(attname) "\ +" FROM pg_catalog.pg_attribute a, pg_catalog.pg_class c "\ +" WHERE c.oid = a.attrelid "\ +" AND a.attnum > 0 "\ +" AND NOT a.attisdropped "\ +" AND substring(pg_catalog.quote_ident(attname),1,%d)='%s' "\ +" AND pg_catalog.quote_ident(relname)='%s' "\ +" AND pg_catalog.pg_table_is_visible(c.oid)" + +#define Query_for_list_of_databases \ +"SELECT pg_catalog.quote_ident(datname) FROM pg_catalog.pg_database "\ +" WHERE substring(pg_catalog.quote_ident(datname),1,%d)='%s'" + +#define Query_for_list_of_tablespaces \ +"SELECT pg_catalog.quote_ident(spcname) FROM pg_catalog.pg_tablespace "\ +" WHERE substring(pg_catalog.quote_ident(spcname),1,%d)='%s'" + +#define Query_for_list_of_encodings \ +" SELECT DISTINCT pg_catalog.pg_encoding_to_char(conforencoding) "\ +" FROM pg_catalog.pg_conversion "\ +" WHERE substring(pg_catalog.pg_encoding_to_char(conforencoding),1,%d)=UPPER('%s')" + +#define Query_for_list_of_languages \ +"SELECT pg_catalog.quote_ident(lanname) "\ +" FROM pg_language "\ +" WHERE lanname != 'internal' "\ +" AND substring(pg_catalog.quote_ident(lanname),1,%d)='%s' " + +#define Query_for_list_of_schemas \ +"SELECT pg_catalog.quote_ident(nspname) FROM pg_catalog.pg_namespace "\ +" WHERE substring(pg_catalog.quote_ident(nspname),1,%d)='%s'" + +#define Query_for_list_of_set_vars \ +"SELECT name FROM "\ +" (SELECT pg_catalog.lower(name) AS name FROM pg_catalog.pg_settings "\ +" WHERE context IN ('user', 'superuser') "\ +" UNION ALL SELECT 'constraints' "\ +" UNION ALL SELECT 'transaction' "\ +" UNION ALL SELECT 'session' "\ +" UNION ALL SELECT 'role' "\ +" UNION ALL SELECT 'all') ss "\ +" WHERE substring(name,1,%d)='%s'" + +#define Query_for_list_of_show_vars \ +"SELECT name FROM "\ +" (SELECT pg_catalog.lower(name) AS name FROM pg_catalog.pg_settings "\ +" UNION ALL SELECT 'session authorization' "\ +" UNION ALL SELECT 'all') ss "\ +" WHERE substring(name,1,%d)='%s'" + +#define Query_for_list_of_system_relations \ +"SELECT pg_catalog.quote_ident(relname) "\ +" FROM pg_catalog.pg_class c, pg_catalog.pg_namespace n "\ +" WHERE c.relkind IN ('r', 'v', 's', 'S') "\ +" AND substring(pg_catalog.quote_ident(relname),1,%d)='%s' "\ +" AND c.relnamespace = n.oid "\ +" AND n.nspname = 'pg_catalog'" + +#define Query_for_list_of_roles \ +" SELECT pg_catalog.quote_ident(rolname) "\ +" FROM pg_catalog.pg_roles "\ +" WHERE substring(pg_catalog.quote_ident(rolname),1,%d)='%s'" + +#define Query_for_list_of_grant_roles \ +" SELECT pg_catalog.quote_ident(rolname) "\ +" FROM pg_catalog.pg_roles "\ +" WHERE substring(pg_catalog.quote_ident(rolname),1,%d)='%s'"\ +" UNION ALL SELECT 'PUBLIC'" + +/* the silly-looking length condition is just to eat up the current word */ +#define Query_for_table_owning_index \ +"SELECT pg_catalog.quote_ident(c1.relname) "\ +" FROM pg_catalog.pg_class c1, pg_catalog.pg_class c2, pg_catalog.pg_index i"\ +" WHERE c1.oid=i.indrelid and i.indexrelid=c2.oid"\ +" and (%d = length('%s'))"\ +" and pg_catalog.quote_ident(c2.relname)='%s'"\ +" and pg_catalog.pg_table_is_visible(c2.oid)" + +/* the silly-looking length condition is just to eat up the current word */ +#define Query_for_index_of_table \ +"SELECT pg_catalog.quote_ident(c2.relname) "\ +" FROM pg_catalog.pg_class c1, pg_catalog.pg_class c2, pg_catalog.pg_index i"\ +" WHERE c1.oid=i.indrelid and i.indexrelid=c2.oid"\ +" and (%d = length('%s'))"\ +" and pg_catalog.quote_ident(c1.relname)='%s'"\ +" and pg_catalog.pg_table_is_visible(c2.oid)" + +/* the silly-looking length condition is just to eat up the current word */ +#define Query_for_list_of_tables_for_trigger \ +"SELECT pg_catalog.quote_ident(relname) "\ +" FROM pg_catalog.pg_class"\ +" WHERE (%d = length('%s'))"\ +" AND oid IN "\ +" (SELECT tgrelid FROM pg_catalog.pg_trigger "\ +" WHERE pg_catalog.quote_ident(tgname)='%s')" + +/* + * This is a list of all "things" in Pgsql, which can show up after CREATE or + * DROP; and there is also a query to get a list of them. + */ + +typedef struct +{ + const char *name; + const char *query; /* simple query, or NULL */ + const SchemaQuery *squery; /* schema query, or NULL */ +} pgsql_thing_t; + +static const pgsql_thing_t words_after_create[] = { + {"AGGREGATE", NULL, &Query_for_list_of_aggregates}, + {"CAST", NULL, NULL}, /* Casts have complex structures for names, so + * skip it */ + + /* + * CREATE CONSTRAINT TRIGGER is not supported here because it is designed + * to be used only by pg_dump. + */ + {"CONVERSION", "SELECT pg_catalog.quote_ident(conname) FROM pg_catalog.pg_conversion WHERE substring(pg_catalog.quote_ident(conname),1,%d)='%s'"}, + {"DATABASE", Query_for_list_of_databases}, + {"DOMAIN", NULL, &Query_for_list_of_domains}, + {"FUNCTION", NULL, &Query_for_list_of_functions}, + {"GROUP", Query_for_list_of_roles}, + {"LANGUAGE", Query_for_list_of_languages}, + {"INDEX", NULL, &Query_for_list_of_indexes}, + {"OPERATOR", NULL, NULL}, /* Querying for this is probably not such a + * good idea. */ + {"ROLE", Query_for_list_of_roles}, + {"RULE", "SELECT pg_catalog.quote_ident(rulename) FROM pg_catalog.pg_rules WHERE substring(pg_catalog.quote_ident(rulename),1,%d)='%s'"}, + {"SCHEMA", Query_for_list_of_schemas}, + {"SEQUENCE", NULL, &Query_for_list_of_sequences}, + {"TABLE", NULL, &Query_for_list_of_tables}, + {"TABLESPACE", Query_for_list_of_tablespaces}, + {"TEMP", NULL, NULL}, /* for CREATE TEMP TABLE ... */ + {"TRIGGER", "SELECT pg_catalog.quote_ident(tgname) FROM pg_catalog.pg_trigger WHERE substring(pg_catalog.quote_ident(tgname),1,%d)='%s'"}, + {"TYPE", NULL, &Query_for_list_of_datatypes}, + {"UNIQUE", NULL, NULL}, /* for CREATE UNIQUE INDEX ... */ + {"USER", Query_for_list_of_roles}, + {"VIEW", NULL, &Query_for_list_of_views}, + {NULL, NULL, NULL} /* end of list */ +}; + + +/* The completion function. Acc. to readline spec this gets passed the text + entered to far and its start and end in the readline buffer. The return value + is some partially obscure list format that can be generated by the readline + libraries completion_matches() function, so we don't have to worry about it. +*/ +static char * psql_completion(char *text, int start, int end, void *dbptr) +{ + /* This is the variable we'll return. */ + char *matches = NULL; + + /* These are going to contain some scannage of the input line. */ + char *prev_wd, + *prev2_wd, + *prev3_wd, + *prev4_wd, + *prev5_wd; + + static const char *const sql_commands[] = { + "ABORT", "ALTER", "ANALYZE", "BEGIN", "CHECKPOINT", "CLOSE", "CLUSTER", "COMMENT", + "COMMIT", "COPY", "CREATE", "DEALLOCATE", "DECLARE", "DELETE FROM", "DROP", "END", "EXECUTE", + "EXPLAIN", "FETCH", "GRANT", "INSERT", "LISTEN", "LOAD", "LOCK", "MOVE", "NOTIFY", + "PREPARE", "REINDEX", "RELEASE", "RESET", "REVOKE", "ROLLBACK", "SAVEPOINT", + "SELECT", "SET", "SHOW", "START", "TRUNCATE", "UNLISTEN", "UPDATE", "VACUUM", NULL + }; + + static const char *const backslash_commands[] = { + "\\a", "\\connect", "\\C", "\\cd", "\\copy", "\\copyright", + "\\d", "\\da", "\\db", "\\dc", "\\dC", "\\dd", "\\dD", "\\df", + "\\dg", "\\di", "\\dl", "\\dn", "\\do", "\\dp", "\\ds", "\\dS", + "\\dt", "\\dT", "\\dv", "\\du", + "\\e", "\\echo", "\\encoding", + "\\f", "\\g", "\\h", "\\help", "\\H", "\\i", "\\l", + "\\lo_import", "\\lo_export", "\\lo_list", "\\lo_unlink", + "\\o", "\\p", "\\password", "\\pset", "\\q", "\\qecho", "\\r", "\\set", "\\t", "\\T", + "\\timing", "\\unset", "\\x", "\\w", "\\z", "\\!", NULL + }; + + (void) end; /* not used */ + +#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER + rl_completion_append_character = ' '; +#endif + + /* Clear a few things. */ + completion_charp = NULL; + completion_charpp = NULL; + completion_info_charp = NULL; + + /* + * Scan the input line before our current position for the last four + * words. According to those we'll make some smart decisions on what the + * user is probably intending to type. TODO: Use strtokx() to do this. + */ + prev_wd = previous_word(start, 0); + prev2_wd = previous_word(start, 1); + prev3_wd = previous_word(start, 2); + prev4_wd = previous_word(start, 3); + prev5_wd = previous_word(start, 4); + + /* If a backslash command was started, continue */ + if (text[0] == '\\') + COMPLETE_WITH_LIST(backslash_commands); + + /* If no previous word, suggest one of the basic sql commands */ + else if (!prev_wd) + COMPLETE_WITH_LIST(sql_commands); + +/* CREATE or DROP but not ALTER (TABLE|DOMAIN|GROUP) sth DROP */ + /* complete with something you can create or drop */ + else if (pg_strcasecmp(prev_wd, "CREATE") == 0 || + (pg_strcasecmp(prev_wd, "DROP") == 0 && + pg_strcasecmp(prev3_wd, "TABLE") != 0 && + pg_strcasecmp(prev3_wd, "DOMAIN") != 0 && + pg_strcasecmp(prev3_wd, "GROUP") != 0)) + matches = complete_create_command(text); + +/* ALTER */ + + /* + * complete with what you can alter (TABLE, GROUP, USER, ...) unless we're + * in ALTER TABLE sth ALTER + */ + else if (pg_strcasecmp(prev_wd, "ALTER") == 0 && + pg_strcasecmp(prev3_wd, "TABLE") != 0) + { + static const char *const list_ALTER[] = + {"AGGREGATE", "CONVERSION", "DATABASE", "DOMAIN", "FUNCTION", + "GROUP", "INDEX", "LANGUAGE", "OPERATOR", "ROLE", "SCHEMA", "SEQUENCE", "TABLE", + "TABLESPACE", "TRIGGER", "TYPE", "USER", NULL}; + + COMPLETE_WITH_LIST(list_ALTER); + } + /* ALTER AGGREGATE,FUNCTION */ + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && + (pg_strcasecmp(prev2_wd, "AGGREGATE") == 0 || + pg_strcasecmp(prev2_wd, "FUNCTION") == 0)) + { + static const char *const list_ALTERAGG[] = + {"OWNER TO", "RENAME TO", "SET SCHEMA", NULL}; + + COMPLETE_WITH_LIST(list_ALTERAGG); + } + + /* ALTER CONVERSION,SCHEMA */ + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && + (pg_strcasecmp(prev2_wd, "CONVERSION") == 0 || + pg_strcasecmp(prev2_wd, "SCHEMA") == 0)) + { + static const char *const list_ALTERGEN[] = + {"OWNER TO", "RENAME TO", NULL}; + + COMPLETE_WITH_LIST(list_ALTERGEN); + } + + /* ALTER DATABASE */ + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && + pg_strcasecmp(prev2_wd, "DATABASE") == 0) + { + static const char *const list_ALTERDATABASE[] = + {"RESET", "SET", "OWNER TO", "RENAME TO", "CONNECTION LIMIT", NULL}; + + COMPLETE_WITH_LIST(list_ALTERDATABASE); + } + + /* ALTER INDEX */ + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && + pg_strcasecmp(prev2_wd, "INDEX") == 0) + { + static const char *const list_ALTERINDEX[] = + {"SET TABLESPACE", "OWNER TO", "RENAME TO", NULL}; + + COMPLETE_WITH_LIST(list_ALTERINDEX); + } + + /* ALTER LANGUAGE */ + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && + pg_strcasecmp(prev2_wd, "LANGUAGE") == 0) + COMPLETE_WITH_CONST("RENAME TO"); + + /* ALTER USER,ROLE */ + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && + (pg_strcasecmp(prev2_wd, "USER") == 0 || + pg_strcasecmp(prev2_wd, "ROLE") == 0)) + { + static const char *const list_ALTERUSER[] = + {"ENCRYPTED", "UNENCRYPTED", "CREATEDB", "NOCREATEDB", "CREATEUSER", + "NOCREATEUSER", "CREATEROLE", "NOCREATEROLE", "INHERIT", "NOINHERIT", + "LOGIN", "NOLOGIN", "CONNECTION LIMIT", "VALID UNTIL", "RENAME TO", + "SUPERUSER", "NOSUPERUSER", "SET", "RESET", NULL}; + + COMPLETE_WITH_LIST(list_ALTERUSER); + } + + /* complete ALTER USER,ROLE ENCRYPTED,UNENCRYPTED with PASSWORD */ + else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 && + (pg_strcasecmp(prev3_wd, "ROLE") == 0 || pg_strcasecmp(prev3_wd, "USER") == 0) && + (pg_strcasecmp(prev_wd, "ENCRYPTED") == 0 || pg_strcasecmp(prev_wd, "UNENCRYPTED") == 0)) + { + COMPLETE_WITH_CONST("PASSWORD"); + } + /* ALTER DOMAIN */ + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && + pg_strcasecmp(prev2_wd, "DOMAIN") == 0) + { + static const char *const list_ALTERDOMAIN[] = + {"ADD", "DROP", "OWNER TO", "SET", NULL}; + + COMPLETE_WITH_LIST(list_ALTERDOMAIN); + } + /* ALTER DOMAIN DROP */ + else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 && + pg_strcasecmp(prev3_wd, "DOMAIN") == 0 && + pg_strcasecmp(prev_wd, "DROP") == 0) + { + static const char *const list_ALTERDOMAIN2[] = + {"CONSTRAINT", "DEFAULT", "NOT NULL", NULL}; + + COMPLETE_WITH_LIST(list_ALTERDOMAIN2); + } + /* ALTER DOMAIN SET */ + else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 && + pg_strcasecmp(prev3_wd, "DOMAIN") == 0 && + pg_strcasecmp(prev_wd, "SET") == 0) + { + static const char *const list_ALTERDOMAIN3[] = + {"DEFAULT", "NOT NULL", "SCHEMA", NULL}; + + COMPLETE_WITH_LIST(list_ALTERDOMAIN3); + } + /* ALTER SEQUENCE */ + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && + pg_strcasecmp(prev2_wd, "SEQUENCE") == 0) + { + static const char *const list_ALTERSEQUENCE[] = + {"INCREMENT", "MINVALUE", "MAXVALUE", "RESTART", "NO", "CACHE", "CYCLE", + "SET SCHEMA", NULL}; + + COMPLETE_WITH_LIST(list_ALTERSEQUENCE); + } + /* ALTER SEQUENCE NO */ + else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 && + pg_strcasecmp(prev3_wd, "SEQUENCE") == 0 && + pg_strcasecmp(prev_wd, "NO") == 0) + { + static const char *const list_ALTERSEQUENCE2[] = + {"MINVALUE", "MAXVALUE", "CYCLE", NULL}; + + COMPLETE_WITH_LIST(list_ALTERSEQUENCE2); + } + /* ALTER TRIGGER , add ON */ + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && + pg_strcasecmp(prev2_wd, "TRIGGER") == 0) + COMPLETE_WITH_CONST("ON"); + + else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 && + pg_strcasecmp(prev3_wd, "TRIGGER") == 0) + { + completion_info_charp = prev2_wd; + COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_trigger); + } + + /* + * If we have ALTER TRIGGER ON, then add the correct tablename + */ + else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 && + pg_strcasecmp(prev3_wd, "TRIGGER") == 0 && + pg_strcasecmp(prev_wd, "ON") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); + + /* ALTER TRIGGER ON */ + else if (pg_strcasecmp(prev4_wd, "TRIGGER") == 0 && + pg_strcasecmp(prev2_wd, "ON") == 0) + COMPLETE_WITH_CONST("RENAME TO"); + + /* + * If we detect ALTER TABLE , suggest either ADD, DROP, ALTER, + * RENAME, CLUSTER ON or OWNER + */ + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && + pg_strcasecmp(prev2_wd, "TABLE") == 0) + { + static const char *const list_ALTER2[] = + {"ADD", "ALTER", "CLUSTER ON", "DROP", "RENAME", "OWNER TO", + "SET", NULL}; + + COMPLETE_WITH_LIST(list_ALTER2); + } + /* If we have TABLE ALTER|RENAME, provide list of columns */ + else if (pg_strcasecmp(prev3_wd, "TABLE") == 0 && + (pg_strcasecmp(prev_wd, "ALTER") == 0 || + pg_strcasecmp(prev_wd, "RENAME") == 0)) + COMPLETE_WITH_ATTR(prev2_wd); + + /* ALTER TABLE xxx RENAME yyy */ + else if (pg_strcasecmp(prev4_wd, "TABLE") == 0 && + pg_strcasecmp(prev2_wd, "RENAME") == 0 && + pg_strcasecmp(prev_wd, "TO") != 0) + COMPLETE_WITH_CONST("TO"); + + /* If we have TABLE DROP, provide COLUMN or CONSTRAINT */ + else if (pg_strcasecmp(prev3_wd, "TABLE") == 0 && + pg_strcasecmp(prev_wd, "DROP") == 0) + { + static const char *const list_TABLEDROP[] = + {"COLUMN", "CONSTRAINT", NULL}; + + COMPLETE_WITH_LIST(list_TABLEDROP); + } + /* If we have TABLE DROP COLUMN, provide list of columns */ + else if (pg_strcasecmp(prev4_wd, "TABLE") == 0 && + pg_strcasecmp(prev2_wd, "DROP") == 0 && + pg_strcasecmp(prev_wd, "COLUMN") == 0) + COMPLETE_WITH_ATTR(prev3_wd); + /* ALTER TABLE ALTER [COLUMN] */ + else if ((pg_strcasecmp(prev3_wd, "ALTER") == 0 && + pg_strcasecmp(prev2_wd, "COLUMN") == 0) || + (pg_strcasecmp(prev4_wd, "TABLE") == 0 && + pg_strcasecmp(prev2_wd, "ALTER") == 0)) + { + /* DROP ... does not work well yet */ + static const char *const list_COLUMNALTER[] = + {"TYPE", "SET DEFAULT", "DROP DEFAULT", "SET NOT NULL", + "DROP NOT NULL", "SET STATISTICS", "SET STORAGE", NULL}; + + COMPLETE_WITH_LIST(list_COLUMNALTER); + } + else if (pg_strcasecmp(prev3_wd, "TABLE") == 0 && + pg_strcasecmp(prev_wd, "CLUSTER") == 0) + COMPLETE_WITH_CONST("ON"); + else if (pg_strcasecmp(prev4_wd, "TABLE") == 0 && + pg_strcasecmp(prev2_wd, "CLUSTER") == 0 && + pg_strcasecmp(prev_wd, "ON") == 0) + { + completion_info_charp = prev3_wd; + COMPLETE_WITH_QUERY(Query_for_index_of_table); + } + /* If we have TABLE SET, provide WITHOUT,TABLESPACE and SCHEMA */ + else if (pg_strcasecmp(prev3_wd, "TABLE") == 0 && + pg_strcasecmp(prev_wd, "SET") == 0) + { + static const char *const list_TABLESET[] = + {"WITHOUT", "TABLESPACE", "SCHEMA", NULL}; + + COMPLETE_WITH_LIST(list_TABLESET); + } + /* If we have TABLE SET TABLESPACE provide a list of tablespaces */ + else if (pg_strcasecmp(prev4_wd, "TABLE") == 0 && + pg_strcasecmp(prev2_wd, "SET") == 0 && + pg_strcasecmp(prev_wd, "TABLESPACE") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces); + /* If we have TABLE SET WITHOUT provide CLUSTER or OIDS */ + else if (pg_strcasecmp(prev4_wd, "TABLE") == 0 && + pg_strcasecmp(prev2_wd, "SET") == 0 && + pg_strcasecmp(prev_wd, "WITHOUT") == 0) + { + static const char *const list_TABLESET2[] = + {"CLUSTER", "OIDS", NULL}; + + COMPLETE_WITH_LIST(list_TABLESET2); + } + /* we have ALTER TABLESPACE, so suggest RENAME TO, OWNER TO */ + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && + pg_strcasecmp(prev2_wd, "TABLESPACE") == 0) + { + static const char *const list_ALTERTSPC[] = + {"RENAME TO", "OWNER TO", NULL}; + + COMPLETE_WITH_LIST(list_ALTERTSPC); + } + /* complete ALTER TYPE with OWNER TO, SET SCHEMA */ + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && + pg_strcasecmp(prev2_wd, "TYPE") == 0) + { + static const char *const list_ALTERTYPE[] = + {"OWNER TO", "SET SCHEMA", NULL}; + + COMPLETE_WITH_LIST(list_ALTERTYPE); + } + /* complete ALTER GROUP */ + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && + pg_strcasecmp(prev2_wd, "GROUP") == 0) + { + static const char *const list_ALTERGROUP[] = + {"ADD USER", "DROP USER", "RENAME TO", NULL}; + + COMPLETE_WITH_LIST(list_ALTERGROUP); + } + /* complete ALTER GROUP ADD|DROP with USER */ + else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 && + pg_strcasecmp(prev3_wd, "GROUP") == 0 && + (pg_strcasecmp(prev_wd, "ADD") == 0 || + pg_strcasecmp(prev_wd, "DROP") == 0)) + COMPLETE_WITH_CONST("USER"); + /* complete {ALTER} GROUP ADD|DROP USER with a user name */ + else if (pg_strcasecmp(prev4_wd, "GROUP") == 0 && + (pg_strcasecmp(prev2_wd, "ADD") == 0 || + pg_strcasecmp(prev2_wd, "DROP") == 0) && + pg_strcasecmp(prev_wd, "USER") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_roles); + +/* BEGIN, END, ABORT */ + else if (pg_strcasecmp(prev_wd, "BEGIN") == 0 || + pg_strcasecmp(prev_wd, "END") == 0 || + pg_strcasecmp(prev_wd, "ABORT") == 0) + { + static const char *const list_TRANS[] = + {"WORK", "TRANSACTION", NULL}; + + COMPLETE_WITH_LIST(list_TRANS); + } +/* COMMIT */ + else if (pg_strcasecmp(prev_wd, "COMMIT") == 0) + { + static const char *const list_COMMIT[] = + {"WORK", "TRANSACTION", "PREPARED", NULL}; + + COMPLETE_WITH_LIST(list_COMMIT); + } +/* RELEASE SAVEPOINT */ + else if (pg_strcasecmp(prev_wd, "RELEASE") == 0) + COMPLETE_WITH_CONST("SAVEPOINT"); +/* ROLLBACK*/ + else if (pg_strcasecmp(prev_wd, "ROLLBACK") == 0) + { + static const char *const list_TRANS[] = + {"WORK", "TRANSACTION", "TO SAVEPOINT", "PREPARED", NULL}; + + COMPLETE_WITH_LIST(list_TRANS); + } +/* CLUSTER */ + + /* + * If the previous word is CLUSTER and not without produce list of + * indexes. + */ + else if (pg_strcasecmp(prev_wd, "CLUSTER") == 0 && + pg_strcasecmp(prev2_wd, "WITHOUT") != 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL); + /* If we have CLUSTER , then add "ON" */ + else if (pg_strcasecmp(prev2_wd, "CLUSTER") == 0 && + pg_strcasecmp(prev_wd, "ON") != 0) + COMPLETE_WITH_CONST("ON"); + + /* + * If we have CLUSTER ON, then add the correct tablename as well. + */ + else if (pg_strcasecmp(prev3_wd, "CLUSTER") == 0 && + pg_strcasecmp(prev_wd, "ON") == 0) + { + completion_info_charp = prev2_wd; + COMPLETE_WITH_QUERY(Query_for_table_owning_index); + } + +/* COMMENT */ + else if (pg_strcasecmp(prev_wd, "COMMENT") == 0) + COMPLETE_WITH_CONST("ON"); + else if (pg_strcasecmp(prev2_wd, "COMMENT") == 0 && + pg_strcasecmp(prev_wd, "ON") == 0) + { + static const char *const list_COMMENT[] = + {"CAST", "CONVERSION", "DATABASE", "INDEX", "LANGUAGE", "RULE", "SCHEMA", + "SEQUENCE", "TABLE", "TYPE", "VIEW", "COLUMN", "AGGREGATE", "FUNCTION", + "OPERATOR", "TRIGGER", "CONSTRAINT", "DOMAIN", "LARGE OBJECT", NULL}; + + COMPLETE_WITH_LIST(list_COMMENT); + } + else if (pg_strcasecmp(prev4_wd, "COMMENT") == 0 && + pg_strcasecmp(prev3_wd, "ON") == 0) + COMPLETE_WITH_CONST("IS"); + +/* COPY */ + + /* + * If we have COPY [BINARY] (which you'd have to type yourself), offer + * list of tables (Also cover the analogous backslash command) + */ + else if (pg_strcasecmp(prev_wd, "COPY") == 0 || + pg_strcasecmp(prev_wd, "\\copy") == 0 || + (pg_strcasecmp(prev2_wd, "COPY") == 0 && + pg_strcasecmp(prev_wd, "BINARY") == 0)) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); + /* If we have COPY|BINARY , complete it with "TO" or "FROM" */ + else if (pg_strcasecmp(prev2_wd, "COPY") == 0 || + pg_strcasecmp(prev2_wd, "\\copy") == 0 || + pg_strcasecmp(prev2_wd, "BINARY") == 0) + { + static const char *const list_FROMTO[] = + {"FROM", "TO", NULL}; + + COMPLETE_WITH_LIST(list_FROMTO); + } + /* If we have COPY|BINARY FROM|TO, complete with filename */ + else if ((pg_strcasecmp(prev3_wd, "COPY") == 0 || + pg_strcasecmp(prev3_wd, "\\copy") == 0 || + pg_strcasecmp(prev3_wd, "BINARY") == 0) && + (pg_strcasecmp(prev_wd, "FROM") == 0 || + pg_strcasecmp(prev_wd, "TO") == 0)) + matches = complete_filename(); + + /* Handle COPY|BINARY FROM|TO filename */ + else if ((pg_strcasecmp(prev4_wd, "COPY") == 0 || + pg_strcasecmp(prev4_wd, "\\copy") == 0 || + pg_strcasecmp(prev4_wd, "BINARY") == 0) && + (pg_strcasecmp(prev2_wd, "FROM") == 0 || + pg_strcasecmp(prev2_wd, "TO") == 0)) + { + static const char *const list_COPY[] = + {"BINARY", "OIDS", "DELIMITER", "NULL", "CSV", NULL}; + + COMPLETE_WITH_LIST(list_COPY); + } + + /* Handle COPY|BINARY FROM|TO filename CSV */ + else if (pg_strcasecmp(prev_wd, "CSV") == 0 && + (pg_strcasecmp(prev3_wd, "FROM") == 0 || + pg_strcasecmp(prev3_wd, "TO") == 0)) + { + static const char *const list_CSV[] = + {"HEADER", "QUOTE", "ESCAPE", "FORCE QUOTE", NULL}; + + COMPLETE_WITH_LIST(list_CSV); + } + + /* CREATE DATABASE */ + else if (pg_strcasecmp(prev3_wd, "CREATE") == 0 && + pg_strcasecmp(prev2_wd, "DATABASE") == 0) + { + static const char *const list_DATABASE[] = + {"OWNER", "TEMPLATE", "ENCODING", "TABLESPACE", "CONNECTION LIMIT", + NULL}; + + COMPLETE_WITH_LIST(list_DATABASE); + } + + /* CREATE INDEX */ + /* First off we complete CREATE UNIQUE with "INDEX" */ + else if (pg_strcasecmp(prev2_wd, "CREATE") == 0 && + pg_strcasecmp(prev_wd, "UNIQUE") == 0) + COMPLETE_WITH_CONST("INDEX"); + /* If we have CREATE|UNIQUE INDEX , then add "ON" */ + else if (pg_strcasecmp(prev2_wd, "INDEX") == 0 && + (pg_strcasecmp(prev3_wd, "CREATE") == 0 || + pg_strcasecmp(prev3_wd, "UNIQUE") == 0)) + COMPLETE_WITH_CONST("ON"); + /* Complete ... INDEX ON with a list of tables */ + else if (pg_strcasecmp(prev3_wd, "INDEX") == 0 && + pg_strcasecmp(prev_wd, "ON") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); + + /* + * Complete INDEX ON with a list of table columns (which + * should really be in parens) + */ + else if (pg_strcasecmp(prev4_wd, "INDEX") == 0 && + pg_strcasecmp(prev2_wd, "ON") == 0) + { + if (find_open_parenthesis(end)) + COMPLETE_WITH_ATTR(prev_wd); + else + COMPLETE_WITH_CONST("("); + } + else if (pg_strcasecmp(prev5_wd, "INDEX") == 0 && + pg_strcasecmp(prev3_wd, "ON") == 0 && + pg_strcasecmp(prev_wd, "(") == 0) + COMPLETE_WITH_ATTR(prev2_wd); + /* same if you put in USING */ + else if (pg_strcasecmp(prev4_wd, "ON") == 0 && + pg_strcasecmp(prev2_wd, "USING") == 0) + COMPLETE_WITH_ATTR(prev3_wd); + /* Complete USING with an index method */ + else if (pg_strcasecmp(prev_wd, "USING") == 0) + { + static const char *const index_mth[] = + {"BTREE", "HASH", "GIST", NULL}; + + COMPLETE_WITH_LIST(index_mth); + } + +/* CREATE RULE */ + /* Complete "CREATE RULE " with "AS" */ + else if (pg_strcasecmp(prev3_wd, "CREATE") == 0 && + pg_strcasecmp(prev2_wd, "RULE") == 0) + COMPLETE_WITH_CONST("AS"); + /* Complete "CREATE RULE AS with "ON" */ + else if (pg_strcasecmp(prev4_wd, "CREATE") == 0 && + pg_strcasecmp(prev3_wd, "RULE") == 0 && + pg_strcasecmp(prev_wd, "AS") == 0) + COMPLETE_WITH_CONST("ON"); + /* Complete "RULE * AS ON" with SELECT|UPDATE|DELETE|INSERT */ + else if (pg_strcasecmp(prev4_wd, "RULE") == 0 && + pg_strcasecmp(prev2_wd, "AS") == 0 && + pg_strcasecmp(prev_wd, "ON") == 0) + { + static const char *const rule_events[] = + {"SELECT", "UPDATE", "INSERT", "DELETE", NULL}; + + COMPLETE_WITH_LIST(rule_events); + } + /* Complete "AS ON " with a "TO" */ + else if (pg_strcasecmp(prev3_wd, "AS") == 0 && + pg_strcasecmp(prev2_wd, "ON") == 0 && + (toupper((unsigned char) prev_wd[4]) == 'T' || + toupper((unsigned char) prev_wd[5]) == 'T')) + COMPLETE_WITH_CONST("TO"); + /* Complete "AS ON TO" with a table name */ + else if (pg_strcasecmp(prev4_wd, "AS") == 0 && + pg_strcasecmp(prev3_wd, "ON") == 0 && + pg_strcasecmp(prev_wd, "TO") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); + +/* CREATE TABLE */ + /* Complete CREATE TEMP with "TABLE" */ + else if (pg_strcasecmp(prev2_wd, "CREATE") == 0 && + pg_strcasecmp(prev_wd, "TEMP") == 0) + COMPLETE_WITH_CONST("TABLE"); + +/* CREATE TABLESPACE */ + else if (pg_strcasecmp(prev3_wd, "CREATE") == 0 && + pg_strcasecmp(prev2_wd, "TABLESPACE") == 0) + { + static const char *const list_CREATETABLESPACE[] = + {"OWNER", "LOCATION", NULL}; + + COMPLETE_WITH_LIST(list_CREATETABLESPACE); + } + /* Complete CREATE TABLESPACE name OWNER name with "LOCATION" */ + else if (pg_strcasecmp(prev5_wd, "CREATE") == 0 && + pg_strcasecmp(prev4_wd, "TABLESPACE") == 0 && + pg_strcasecmp(prev2_wd, "OWNER") == 0) + { + COMPLETE_WITH_CONST("LOCATION"); + } + +/* CREATE TRIGGER */ + /* complete CREATE TRIGGER with BEFORE,AFTER */ + else if (pg_strcasecmp(prev3_wd, "CREATE") == 0 && + pg_strcasecmp(prev2_wd, "TRIGGER") == 0) + { + static const char *const list_CREATETRIGGER[] = + {"BEFORE", "AFTER", NULL}; + + COMPLETE_WITH_LIST(list_CREATETRIGGER); + } + /* complete CREATE TRIGGER BEFORE,AFTER sth with OR,ON */ + else if (pg_strcasecmp(prev5_wd, "CREATE") == 0 && + pg_strcasecmp(prev4_wd, "TRIGGER") == 0 && + (pg_strcasecmp(prev2_wd, "BEFORE") == 0 || + pg_strcasecmp(prev2_wd, "AFTER") == 0)) + { + static const char *const list_CREATETRIGGER2[] = + {"ON", "OR", NULL}; + + COMPLETE_WITH_LIST(list_CREATETRIGGER2); + } + +/* CREATE ROLE,USER,GROUP */ + else if (pg_strcasecmp(prev3_wd, "CREATE") == 0 && + (pg_strcasecmp(prev2_wd, "ROLE") == 0 || + pg_strcasecmp(prev2_wd, "GROUP") == 0 || pg_strcasecmp(prev2_wd, "USER") == 0)) + { + static const char *const list_CREATEROLE[] = + {"ADMIN", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE", "CREATEUSER", + "ENCRYPTED", "IN", "INHERIT", "LOGIN", "NOINHERIT", "NOLOGIN", "NOCREATEDB", + "NOCREATEROLE", "NOCREATEUSER", "NOSUPERUSER", "ROLE", "SUPERUSER", "SYSID", + "UNENCRYPTED", NULL}; + + COMPLETE_WITH_LIST(list_CREATEROLE); + } + + /* + * complete CREATE ROLE,USER,GROUP ENCRYPTED,UNENCRYPTED with + * PASSWORD + */ + else if (pg_strcasecmp(prev4_wd, "CREATE") == 0 && + (pg_strcasecmp(prev3_wd, "ROLE") == 0 || + pg_strcasecmp(prev3_wd, "GROUP") == 0 || pg_strcasecmp(prev3_wd, "USER") == 0) && + (pg_strcasecmp(prev_wd, "ENCRYPTED") == 0 || pg_strcasecmp(prev_wd, "UNENCRYPTED") == 0)) + { + COMPLETE_WITH_CONST("PASSWORD"); + } + /* complete CREATE ROLE,USER,GROUP IN with ROLE,GROUP */ + else if (pg_strcasecmp(prev4_wd, "CREATE") == 0 && + (pg_strcasecmp(prev3_wd, "ROLE") == 0 || + pg_strcasecmp(prev3_wd, "GROUP") == 0 || pg_strcasecmp(prev3_wd, "USER") == 0) && + pg_strcasecmp(prev_wd, "IN") == 0) + { + static const char *const list_CREATEROLE3[] = + {"GROUP", "ROLE", NULL}; + + COMPLETE_WITH_LIST(list_CREATEROLE3); + } + +/* CREATE VIEW */ + /* Complete CREATE VIEW with AS */ + else if (pg_strcasecmp(prev3_wd, "CREATE") == 0 && + pg_strcasecmp(prev2_wd, "VIEW") == 0) + COMPLETE_WITH_CONST("AS"); + /* Complete "CREATE VIEW AS with "SELECT" */ + else if (pg_strcasecmp(prev4_wd, "CREATE") == 0 && + pg_strcasecmp(prev3_wd, "VIEW") == 0 && + pg_strcasecmp(prev_wd, "AS") == 0) + COMPLETE_WITH_CONST("SELECT"); + +/* DECLARE */ + else if (pg_strcasecmp(prev2_wd, "DECLARE") == 0) + { + static const char *const list_DECLARE[] = + {"BINARY", "INSENSITIVE", "SCROLL", "NO SCROLL", "CURSOR", NULL}; + + COMPLETE_WITH_LIST(list_DECLARE); + } + + else if (pg_strcasecmp(prev_wd, "CURSOR") == 0) + { + static const char *const list_DECLARECURSOR[] = + {"WITH HOLD", "WITHOUT HOLD", "FOR", NULL}; + + COMPLETE_WITH_LIST(list_DECLARECURSOR); + } + + +/* DELETE */ + + /* + * Complete DELETE with FROM (only if the word before that is not "ON" + * (cf. rules) or "BEFORE" or "AFTER" (cf. triggers) or GRANT) + */ + else if (pg_strcasecmp(prev_wd, "DELETE") == 0 && + !(pg_strcasecmp(prev2_wd, "ON") == 0 || + pg_strcasecmp(prev2_wd, "GRANT") == 0 || + pg_strcasecmp(prev2_wd, "BEFORE") == 0 || + pg_strcasecmp(prev2_wd, "AFTER") == 0)) + COMPLETE_WITH_CONST("FROM"); + /* Complete DELETE FROM with a list of tables */ + else if (pg_strcasecmp(prev2_wd, "DELETE") == 0 && + pg_strcasecmp(prev_wd, "FROM") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); + /* Complete DELETE FROM
    */ + else if (pg_strcasecmp(prev3_wd, "DELETE") == 0 && + pg_strcasecmp(prev2_wd, "FROM") == 0) + { + static const char *const list_DELETE[] = + {"USING", "WHERE", "SET", NULL}; + + COMPLETE_WITH_LIST(list_DELETE); + } + /* XXX: implement tab completion for DELETE ... USING */ + +/* DROP (when not the previous word) */ + /* DROP AGGREGATE */ + else if (pg_strcasecmp(prev3_wd, "DROP") == 0 && + pg_strcasecmp(prev2_wd, "AGGREGATE") == 0) + COMPLETE_WITH_CONST("("); + + /* DROP object with CASCADE / RESTRICT */ + else if ((pg_strcasecmp(prev3_wd, "DROP") == 0 && + (pg_strcasecmp(prev2_wd, "CONVERSION") == 0 || + pg_strcasecmp(prev2_wd, "DOMAIN") == 0 || + pg_strcasecmp(prev2_wd, "FUNCTION") == 0 || + pg_strcasecmp(prev2_wd, "INDEX") == 0 || + pg_strcasecmp(prev2_wd, "LANGUAGE") == 0 || + pg_strcasecmp(prev2_wd, "SCHEMA") == 0 || + pg_strcasecmp(prev2_wd, "SEQUENCE") == 0 || + pg_strcasecmp(prev2_wd, "TABLE") == 0 || + pg_strcasecmp(prev2_wd, "TYPE") == 0 || + pg_strcasecmp(prev2_wd, "VIEW") == 0)) || + (pg_strcasecmp(prev4_wd, "DROP") == 0 && + pg_strcasecmp(prev3_wd, "AGGREGATE") == 0 && + prev_wd[strlen(prev_wd) - 1] == ')')) + { + + if ((pg_strcasecmp(prev3_wd, "DROP") == 0) && (pg_strcasecmp(prev2_wd, "FUNCTION") == 0)) + { + if (find_open_parenthesis(end)) + { + static const char func_args_query[] = "select pg_catalog.oidvectortypes(proargtypes)||')' from pg_proc where proname='%s'"; + char *tmp_buf = malloc(strlen(func_args_query) + strlen(prev_wd)); + sprintf(tmp_buf, func_args_query, prev_wd); + COMPLETE_WITH_QUERY(tmp_buf); + free(tmp_buf); + } + else + { + COMPLETE_WITH_CONST("("); + } + } + else + { + static const char *const list_DROPCR[] = + {"CASCADE", "RESTRICT", NULL}; + + COMPLETE_WITH_LIST(list_DROPCR); + } + } + else if (pg_strcasecmp(prev4_wd, "DROP") == 0 && + pg_strcasecmp(prev3_wd, "FUNCTION") == 0 && + pg_strcasecmp(prev_wd, "(") == 0 ) + { + static const char func_args_query[] = "select pg_catalog.oidvectortypes(proargtypes)||')' from pg_proc where proname='%s'"; + char *tmp_buf = malloc(strlen(func_args_query) + strlen(prev2_wd)); + sprintf(tmp_buf, func_args_query, prev2_wd); + COMPLETE_WITH_QUERY(tmp_buf); + free(tmp_buf); + } + + + +/* EXPLAIN */ + + /* + * Complete EXPLAIN [ANALYZE] [VERBOSE] with list of EXPLAIN-able commands + */ + else if (pg_strcasecmp(prev_wd, "EXPLAIN") == 0) + { + static const char *const list_EXPLAIN[] = + {"SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE", "ANALYZE", "VERBOSE", NULL}; + + COMPLETE_WITH_LIST(list_EXPLAIN); + } + else if (pg_strcasecmp(prev2_wd, "EXPLAIN") == 0 && + pg_strcasecmp(prev_wd, "ANALYZE") == 0) + { + static const char *const list_EXPLAIN[] = + {"SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE", "VERBOSE", NULL}; + + COMPLETE_WITH_LIST(list_EXPLAIN); + } + else if (pg_strcasecmp(prev_wd, "VERBOSE") == 0 && + pg_strcasecmp(prev3_wd, "VACUUM") != 0 && + pg_strcasecmp(prev4_wd, "VACUUM") != 0 && + (pg_strcasecmp(prev2_wd, "ANALYZE") == 0 || + pg_strcasecmp(prev2_wd, "EXPLAIN") == 0)) + { + static const char *const list_EXPLAIN[] = + {"SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE", NULL}; + + COMPLETE_WITH_LIST(list_EXPLAIN); + } + +/* FETCH && MOVE */ + /* Complete FETCH with one of FORWARD, BACKWARD, RELATIVE */ + else if (pg_strcasecmp(prev_wd, "FETCH") == 0 || + pg_strcasecmp(prev_wd, "MOVE") == 0) + { + static const char *const list_FETCH1[] = + {"ABSOLUTE", "BACKWARD", "FORWARD", "RELATIVE", NULL}; + + COMPLETE_WITH_LIST(list_FETCH1); + } + /* Complete FETCH with one of ALL, NEXT, PRIOR */ + else if (pg_strcasecmp(prev2_wd, "FETCH") == 0 || + pg_strcasecmp(prev2_wd, "MOVE") == 0) + { + static const char *const list_FETCH2[] = + {"ALL", "NEXT", "PRIOR", NULL}; + + COMPLETE_WITH_LIST(list_FETCH2); + } + + /* + * Complete FETCH with "FROM" or "IN". These are equivalent, + * but we may as well tab-complete both: perhaps some users prefer one + * variant or the other. + */ + else if (pg_strcasecmp(prev3_wd, "FETCH") == 0 || + pg_strcasecmp(prev3_wd, "MOVE") == 0) + { + static const char *const list_FROMIN[] = + {"FROM", "IN", NULL}; + + COMPLETE_WITH_LIST(list_FROMIN); + } + +/* GRANT && REVOKE*/ + /* Complete GRANT/REVOKE with a list of privileges */ + else if (pg_strcasecmp(prev_wd, "GRANT") == 0 || + pg_strcasecmp(prev_wd, "REVOKE") == 0) + { + static const char *const list_privileg[] = + {"SELECT", "INSERT", "UPDATE", "DELETE", "RULE", "REFERENCES", + "TRIGGER", "CREATE", "TEMPORARY", "EXECUTE", "USAGE", "ALL", NULL}; + + COMPLETE_WITH_LIST(list_privileg); + } + /* Complete GRANT/REVOKE with "ON" */ + else if (pg_strcasecmp(prev2_wd, "GRANT") == 0 || + pg_strcasecmp(prev2_wd, "REVOKE") == 0) + COMPLETE_WITH_CONST("ON"); + + /* + * Complete GRANT/REVOKE ON with a list of tables, views, sequences, + * and indexes + * + * keywords DATABASE, FUNCTION, LANGUAGE, SCHEMA added to query result via + * UNION; seems to work intuitively + * + * Note: GRANT/REVOKE can get quite complex; tab-completion as implemented + * here will only work if the privilege list contains exactly one + * privilege + */ + else if ((pg_strcasecmp(prev3_wd, "GRANT") == 0 || + pg_strcasecmp(prev3_wd, "REVOKE") == 0) && + pg_strcasecmp(prev_wd, "ON") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsv, + " UNION SELECT 'DATABASE'" + " UNION SELECT 'FUNCTION'" + " UNION SELECT 'LANGUAGE'" + " UNION SELECT 'SCHEMA'" + " UNION SELECT 'TABLESPACE'"); + + /* Complete "GRANT/REVOKE * ON * " with "TO" */ + else if ((pg_strcasecmp(prev4_wd, "GRANT") == 0 || + pg_strcasecmp(prev4_wd, "REVOKE") == 0) && + pg_strcasecmp(prev2_wd, "ON") == 0) + { + if (pg_strcasecmp(prev_wd, "DATABASE") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_databases); + else if (pg_strcasecmp(prev_wd, "FUNCTION") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL); + else if (pg_strcasecmp(prev_wd, "LANGUAGE") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_languages); + else if (pg_strcasecmp(prev_wd, "SCHEMA") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_schemas); + else if (pg_strcasecmp(prev_wd, "TABLESPACE") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces); + else if (pg_strcasecmp(prev4_wd, "GRANT") == 0) + COMPLETE_WITH_CONST("TO"); + else + COMPLETE_WITH_CONST("FROM"); + } + + /* Complete "GRANT/REVOKE * ON * TO/FROM" with username, GROUP, or PUBLIC */ + else if (pg_strcasecmp(prev3_wd, "ON") == 0 && + ((pg_strcasecmp(prev5_wd, "GRANT") == 0 && + pg_strcasecmp(prev_wd, "TO") == 0) || + (pg_strcasecmp(prev5_wd, "REVOKE") == 0 && + pg_strcasecmp(prev_wd, "FROM") == 0))) + COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles); + +/* GROUP BY */ + else if (pg_strcasecmp(prev3_wd, "FROM") == 0 && + pg_strcasecmp(prev_wd, "GROUP") == 0) + COMPLETE_WITH_CONST("BY"); + +/* INSERT */ + /* Complete INSERT with "INTO" */ + else if (pg_strcasecmp(prev_wd, "INSERT") == 0) + COMPLETE_WITH_CONST("INTO"); + /* Complete INSERT INTO with table names */ + else if (pg_strcasecmp(prev2_wd, "INSERT") == 0 && + pg_strcasecmp(prev_wd, "INTO") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); + /* Complete "INSERT INTO
    (" with attribute names */ + else if (rl_line_buffer[start - 1] == '(' && + pg_strcasecmp(prev3_wd, "INSERT") == 0 && + pg_strcasecmp(prev2_wd, "INTO") == 0) + COMPLETE_WITH_ATTR(prev_wd); + + /* + * Complete INSERT INTO
    with "VALUES" or "SELECT" or "DEFAULT + * VALUES" + */ + else if (pg_strcasecmp(prev3_wd, "INSERT") == 0 && + pg_strcasecmp(prev2_wd, "INTO") == 0) + { + static const char *const list_INSERT[] = + {"DEFAULT VALUES", "SELECT", "VALUES", NULL}; + + COMPLETE_WITH_LIST(list_INSERT); + } + /* Complete INSERT INTO
    (attribs) with "VALUES" or "SELECT" */ + else if (pg_strcasecmp(prev4_wd, "INSERT") == 0 && + pg_strcasecmp(prev3_wd, "INTO") == 0 && + prev_wd[strlen(prev_wd) - 1] == ')') + { + static const char *const list_INSERT[] = + {"SELECT", "VALUES", NULL}; + + COMPLETE_WITH_LIST(list_INSERT); + } + + /* Insert an open parenthesis after "VALUES" */ + else if (pg_strcasecmp(prev_wd, "VALUES") == 0 && + pg_strcasecmp(prev2_wd, "DEFAULT") != 0) + COMPLETE_WITH_CONST("("); + +/* LOCK */ + /* Complete LOCK [TABLE] with a list of tables */ + else if (pg_strcasecmp(prev_wd, "LOCK") == 0 || + (pg_strcasecmp(prev_wd, "TABLE") == 0 && + pg_strcasecmp(prev2_wd, "LOCK") == 0)) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); + + /* For the following, handle the case of a single table only for now */ + + /* Complete LOCK [TABLE]
    with "IN" */ + else if ((pg_strcasecmp(prev2_wd, "LOCK") == 0 && + pg_strcasecmp(prev_wd, "TABLE")) || + (pg_strcasecmp(prev2_wd, "TABLE") == 0 && + pg_strcasecmp(prev3_wd, "LOCK") == 0)) + COMPLETE_WITH_CONST("IN"); + + /* Complete LOCK [TABLE]
    IN with a lock mode */ + else if (pg_strcasecmp(prev_wd, "IN") == 0 && + (pg_strcasecmp(prev3_wd, "LOCK") == 0 || + (pg_strcasecmp(prev3_wd, "TABLE") == 0 && + pg_strcasecmp(prev4_wd, "LOCK") == 0))) + { + static const char *const lock_modes[] = + {"ACCESS SHARE MODE", + "ROW SHARE MODE", "ROW EXCLUSIVE MODE", + "SHARE UPDATE EXCLUSIVE MODE", "SHARE MODE", + "SHARE ROW EXCLUSIVE MODE", + "EXCLUSIVE MODE", "ACCESS EXCLUSIVE MODE", NULL}; + + COMPLETE_WITH_LIST(lock_modes); + } + +/* NOTIFY */ + else if (pg_strcasecmp(prev_wd, "NOTIFY") == 0) + COMPLETE_WITH_QUERY("SELECT pg_catalog.quote_ident(relname) FROM pg_catalog.pg_listener WHERE substring(pg_catalog.quote_ident(relname),1,%d)='%s'"); + +/* OWNER TO - complete with available roles*/ + else if (pg_strcasecmp(prev2_wd, "OWNER") == 0 && + pg_strcasecmp(prev_wd, "TO") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_roles); + +/* ORDER BY */ + else if (pg_strcasecmp(prev3_wd, "FROM") == 0 && + pg_strcasecmp(prev_wd, "ORDER") == 0) + COMPLETE_WITH_CONST("BY"); + else if (pg_strcasecmp(prev4_wd, "FROM") == 0 && + pg_strcasecmp(prev2_wd, "ORDER") == 0 && + pg_strcasecmp(prev_wd, "BY") == 0) + COMPLETE_WITH_ATTR(prev3_wd); + +/* PREPARE xx AS */ + else if (pg_strcasecmp(prev_wd, "AS") == 0 && + pg_strcasecmp(prev3_wd, "PREPARE") == 0) + { + static const char *const list_PREPARE[] = + {"SELECT", "UPDATE", "INSERT", "DELETE", NULL}; + + COMPLETE_WITH_LIST(list_PREPARE); + } + + +/* REINDEX */ + else if (pg_strcasecmp(prev_wd, "REINDEX") == 0) + { + static const char *const list_REINDEX[] = + {"TABLE", "INDEX", "SYSTEM", "DATABASE", NULL}; + + COMPLETE_WITH_LIST(list_REINDEX); + } + else if (pg_strcasecmp(prev2_wd, "REINDEX") == 0) + { + if (pg_strcasecmp(prev_wd, "TABLE") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); + else if (pg_strcasecmp(prev_wd, "INDEX") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL); + else if (pg_strcasecmp(prev_wd, "SYSTEM") == 0 || + pg_strcasecmp(prev_wd, "DATABASE") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_databases); + } + +/* SELECT */ + /* naah . . . */ + +/* SET, RESET, SHOW */ + /* Complete with a variable name */ + else if ((pg_strcasecmp(prev_wd, "SET") == 0 && + pg_strcasecmp(prev3_wd, "UPDATE") != 0) || + pg_strcasecmp(prev_wd, "RESET") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_set_vars); + else if (pg_strcasecmp(prev_wd, "SHOW") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_show_vars); + /* Complete "SET TRANSACTION" */ + else if ((pg_strcasecmp(prev2_wd, "SET") == 0 && + pg_strcasecmp(prev_wd, "TRANSACTION") == 0) + || (pg_strcasecmp(prev2_wd, "START") == 0 + && pg_strcasecmp(prev_wd, "TRANSACTION") == 0) + || (pg_strcasecmp(prev2_wd, "BEGIN") == 0 + && pg_strcasecmp(prev_wd, "WORK") == 0) + || (pg_strcasecmp(prev2_wd, "BEGIN") == 0 + && pg_strcasecmp(prev_wd, "TRANSACTION") == 0) + || (pg_strcasecmp(prev4_wd, "SESSION") == 0 + && pg_strcasecmp(prev3_wd, "CHARACTERISTICS") == 0 + && pg_strcasecmp(prev2_wd, "AS") == 0 + && pg_strcasecmp(prev_wd, "TRANSACTION") == 0)) + { + static const char *const my_list[] = + {"ISOLATION LEVEL", "READ", NULL}; + + COMPLETE_WITH_LIST(my_list); + } + else if ((pg_strcasecmp(prev3_wd, "SET") == 0 + || pg_strcasecmp(prev3_wd, "BEGIN") == 0 + || pg_strcasecmp(prev3_wd, "START") == 0 + || (pg_strcasecmp(prev4_wd, "CHARACTERISTICS") == 0 + && pg_strcasecmp(prev3_wd, "AS") == 0)) + && (pg_strcasecmp(prev2_wd, "TRANSACTION") == 0 + || pg_strcasecmp(prev2_wd, "WORK") == 0) + && pg_strcasecmp(prev_wd, "ISOLATION") == 0) + COMPLETE_WITH_CONST("LEVEL"); + else if ((pg_strcasecmp(prev4_wd, "SET") == 0 + || pg_strcasecmp(prev4_wd, "BEGIN") == 0 + || pg_strcasecmp(prev4_wd, "START") == 0 + || pg_strcasecmp(prev4_wd, "AS") == 0) + && (pg_strcasecmp(prev3_wd, "TRANSACTION") == 0 + || pg_strcasecmp(prev3_wd, "WORK") == 0) + && pg_strcasecmp(prev2_wd, "ISOLATION") == 0 + && pg_strcasecmp(prev_wd, "LEVEL") == 0) + { + static const char *const my_list[] = + {"READ", "REPEATABLE", "SERIALIZABLE", NULL}; + + COMPLETE_WITH_LIST(my_list); + } + else if ((pg_strcasecmp(prev4_wd, "TRANSACTION") == 0 || + pg_strcasecmp(prev4_wd, "WORK") == 0) && + pg_strcasecmp(prev3_wd, "ISOLATION") == 0 && + pg_strcasecmp(prev2_wd, "LEVEL") == 0 && + pg_strcasecmp(prev_wd, "READ") == 0) + { + static const char *const my_list[] = + {"UNCOMMITTED", "COMMITTED", NULL}; + + COMPLETE_WITH_LIST(my_list); + } + else if ((pg_strcasecmp(prev4_wd, "TRANSACTION") == 0 || + pg_strcasecmp(prev4_wd, "WORK") == 0) && + pg_strcasecmp(prev3_wd, "ISOLATION") == 0 && + pg_strcasecmp(prev2_wd, "LEVEL") == 0 && + pg_strcasecmp(prev_wd, "REPEATABLE") == 0) + COMPLETE_WITH_CONST("READ"); + else if ((pg_strcasecmp(prev3_wd, "SET") == 0 || + pg_strcasecmp(prev3_wd, "BEGIN") == 0 || + pg_strcasecmp(prev3_wd, "START") == 0 || + pg_strcasecmp(prev3_wd, "AS") == 0) && + (pg_strcasecmp(prev2_wd, "TRANSACTION") == 0 || + pg_strcasecmp(prev2_wd, "WORK") == 0) && + pg_strcasecmp(prev_wd, "READ") == 0) + { + static const char *const my_list[] = + {"ONLY", "WRITE", NULL}; + + COMPLETE_WITH_LIST(my_list); + } + /* Complete SET CONSTRAINTS with DEFERRED|IMMEDIATE */ + else if (pg_strcasecmp(prev3_wd, "SET") == 0 && + pg_strcasecmp(prev2_wd, "CONSTRAINTS") == 0) + { + static const char *const constraint_list[] = + {"DEFERRED", "IMMEDIATE", NULL}; + + COMPLETE_WITH_LIST(constraint_list); + } + /* Complete SET ROLE */ + else if (pg_strcasecmp(prev2_wd, "SET") == 0 && + pg_strcasecmp(prev_wd, "ROLE") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_roles); + /* Complete SET SESSION with AUTHORIZATION or CHARACTERISTICS... */ + else if (pg_strcasecmp(prev2_wd, "SET") == 0 && + pg_strcasecmp(prev_wd, "SESSION") == 0) + { + static const char *const my_list[] = + {"AUTHORIZATION", "CHARACTERISTICS AS TRANSACTION", NULL}; + + COMPLETE_WITH_LIST(my_list); + } + /* Complete SET SESSION AUTHORIZATION with username */ + else if (pg_strcasecmp(prev3_wd, "SET") == 0 + && pg_strcasecmp(prev2_wd, "SESSION") == 0 + && pg_strcasecmp(prev_wd, "AUTHORIZATION") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_roles); + /* Complete RESET SESSION with AUTHORIZATION */ + else if (pg_strcasecmp(prev2_wd, "RESET") == 0 && + pg_strcasecmp(prev_wd, "SESSION") == 0) + COMPLETE_WITH_CONST("AUTHORIZATION"); + /* Complete SET with "TO" */ + else if (pg_strcasecmp(prev2_wd, "SET") == 0 && + pg_strcasecmp(prev4_wd, "UPDATE") != 0 && + pg_strcasecmp(prev_wd, "TABLESPACE") != 0 && + pg_strcasecmp(prev4_wd, "DOMAIN") != 0) + COMPLETE_WITH_CONST("TO"); + /* Suggest possible variable values */ + else if (pg_strcasecmp(prev3_wd, "SET") == 0 && + (pg_strcasecmp(prev_wd, "TO") == 0 || strcmp(prev_wd, "=") == 0)) + { + if (pg_strcasecmp(prev2_wd, "DateStyle") == 0) + { + static const char *const my_list[] = + {"ISO", "SQL", "Postgres", "German", + "YMD", "DMY", "MDY", + "US", "European", "NonEuropean", + "DEFAULT", NULL}; + + COMPLETE_WITH_LIST(my_list); + } + else if (pg_strcasecmp(prev2_wd, "GEQO") == 0) + { + static const char *const my_list[] = + {"ON", "OFF", "DEFAULT", NULL}; + + COMPLETE_WITH_LIST(my_list); + } + else + { + static const char *const my_list[] = + {"DEFAULT", NULL}; + + COMPLETE_WITH_LIST(my_list); + } + } + +/* START TRANSACTION */ + else if (pg_strcasecmp(prev_wd, "START") == 0) + COMPLETE_WITH_CONST("TRANSACTION"); + +/* TRUNCATE */ + else if (pg_strcasecmp(prev_wd, "TRUNCATE") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); + +/* UNLISTEN */ + else if (pg_strcasecmp(prev_wd, "UNLISTEN") == 0) + COMPLETE_WITH_QUERY("SELECT pg_catalog.quote_ident(relname) FROM pg_catalog.pg_listener WHERE substring(pg_catalog.quote_ident(relname),1,%d)='%s' UNION SELECT '*'"); + +/* UPDATE */ + /* If prev. word is UPDATE suggest a list of tables */ + else if (pg_strcasecmp(prev_wd, "UPDATE") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); + /* Complete UPDATE
    with "SET" */ + else if (pg_strcasecmp(prev2_wd, "UPDATE") == 0) + COMPLETE_WITH_CONST("SET"); + + /* + * If the previous word is SET (and it wasn't caught above as the _first_ + * word) the word before it was (hopefully) a table name and we'll now + * make a list of attributes. + */ + else if (pg_strcasecmp(prev_wd, "SET") == 0) + COMPLETE_WITH_ATTR(prev2_wd); + +/* UPDATE xx SET yy = */ + else if (pg_strcasecmp(prev2_wd, "SET") == 0 && + pg_strcasecmp(prev4_wd, "UPDATE") == 0) + COMPLETE_WITH_CONST("="); + +/* + * VACUUM [ FULL | FREEZE ] [ VERBOSE ] [ table ] + * VACUUM [ FULL | FREEZE ] [ VERBOSE ] ANALYZE [ table [ (column [, ...] ) ] ] + */ + else if (pg_strcasecmp(prev_wd, "VACUUM") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, + " UNION SELECT 'FULL'" + " UNION SELECT 'FREEZE'" + " UNION SELECT 'ANALYZE'" + " UNION SELECT 'VERBOSE'"); + else if (pg_strcasecmp(prev2_wd, "VACUUM") == 0 && + (pg_strcasecmp(prev_wd, "FULL") == 0 || + pg_strcasecmp(prev_wd, "FREEZE") == 0)) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, + " UNION SELECT 'ANALYZE'" + " UNION SELECT 'VERBOSE'"); + else if (pg_strcasecmp(prev3_wd, "VACUUM") == 0 && + pg_strcasecmp(prev_wd, "ANALYZE") == 0 && + (pg_strcasecmp(prev2_wd, "FULL") == 0 || + pg_strcasecmp(prev2_wd, "FREEZE") == 0)) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, + " UNION SELECT 'VERBOSE'"); + else if (pg_strcasecmp(prev3_wd, "VACUUM") == 0 && + pg_strcasecmp(prev_wd, "VERBOSE") == 0 && + (pg_strcasecmp(prev2_wd, "FULL") == 0 || + pg_strcasecmp(prev2_wd, "FREEZE") == 0)) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, + " UNION SELECT 'ANALYZE'"); + else if (pg_strcasecmp(prev2_wd, "VACUUM") == 0 && + pg_strcasecmp(prev_wd, "VERBOSE") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, + " UNION SELECT 'ANALYZE'"); + else if (pg_strcasecmp(prev2_wd, "VACUUM") == 0 && + pg_strcasecmp(prev_wd, "ANALYZE") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, + " UNION SELECT 'VERBOSE'"); + else if ((pg_strcasecmp(prev_wd, "ANALYZE") == 0 && + pg_strcasecmp(prev2_wd, "VERBOSE") == 0) || + (pg_strcasecmp(prev_wd, "VERBOSE") == 0 && + pg_strcasecmp(prev2_wd, "ANALYZE") == 0)) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); + +/* ANALYZE */ + /* If the previous word is ANALYZE, produce list of tables */ + else if (pg_strcasecmp(prev_wd, "ANALYZE") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); + +/* WHERE */ + /* Simple case of the word before the where being the table name */ + else if (pg_strcasecmp(prev_wd, "WHERE") == 0) + COMPLETE_WITH_ATTR(prev2_wd); + +/* ... FROM ... */ +/* TODO: also include SRF ? */ + else if (pg_strcasecmp(prev_wd, "FROM") == 0 && + pg_strcasecmp(prev3_wd, "COPY") != 0 && + pg_strcasecmp(prev3_wd, "\\copy") != 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsv, NULL); + + +/* Backslash commands */ +/* TODO: \dc \dd \dl */ + else if (strcmp(prev_wd, "\\connect") == 0 || strcmp(prev_wd, "\\c") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_databases); + else if (strcmp(prev_wd, "\\d") == 0 || strcmp(prev_wd, "\\d+") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tisv, NULL); + else if (strcmp(prev_wd, "\\da") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_aggregates, NULL); + else if (strcmp(prev_wd, "\\db") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces); + else if (strcmp(prev_wd, "\\dD") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains, NULL); + else if (strcmp(prev_wd, "\\df") == 0 || strcmp(prev_wd, "\\df+") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL); + else if (strcmp(prev_wd, "\\di") == 0 || strcmp(prev_wd, "\\di+") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL); + else if (strcmp(prev_wd, "\\dn") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_schemas); + else if (strcmp(prev_wd, "\\dp") == 0 || strcmp(prev_wd, "\\z") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsv, NULL); + else if (strcmp(prev_wd, "\\ds") == 0 || strcmp(prev_wd, "\\ds+") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences, NULL); + else if (strcmp(prev_wd, "\\dS") == 0 || strcmp(prev_wd, "\\dS+") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_system_relations); + else if (strcmp(prev_wd, "\\dt") == 0 || strcmp(prev_wd, "\\dt+") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); + else if (strcmp(prev_wd, "\\dT") == 0 || strcmp(prev_wd, "\\dT+") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes, NULL); + else if (strcmp(prev_wd, "\\du") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_roles); + else if (strcmp(prev_wd, "\\dv") == 0 || strcmp(prev_wd, "\\dv+") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL); + else if (strcmp(prev_wd, "\\encoding") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_encodings); + else if (strcmp(prev_wd, "\\h") == 0 || strcmp(prev_wd, "\\help") == 0) + COMPLETE_WITH_LIST(sql_commands); + else if (strcmp(prev_wd, "\\password") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_roles); + else if (strcmp(prev_wd, "\\pset") == 0) + { + static const char *const my_list[] = + {"format", "border", "expanded", + "null", "fieldsep", "tuples_only", "title", "tableattr", "pager", + "recordsep", NULL}; + + COMPLETE_WITH_LIST(my_list); + } + else if (strcmp(prev_wd, "\\cd") == 0 || + strcmp(prev_wd, "\\e") == 0 || strcmp(prev_wd, "\\edit") == 0 || + strcmp(prev_wd, "\\g") == 0 || + strcmp(prev_wd, "\\i") == 0 || strcmp(prev_wd, "\\include") == 0 || + strcmp(prev_wd, "\\o") == 0 || strcmp(prev_wd, "\\out") == 0 || + strcmp(prev_wd, "\\s") == 0 || + strcmp(prev_wd, "\\w") == 0 || strcmp(prev_wd, "\\write") == 0 + ) + matches = complete_filename(); + + + /* + * Finally, we look through the list of "things", such as TABLE, INDEX and + * check if that was the previous word. If so, execute the query to get a + * list of them. + */ + else + { + int i; + + for (i = 0; words_after_create[i].name; i++) + { + if (pg_strcasecmp(prev_wd, words_after_create[i].name) == 0) + { + if (words_after_create[i].query) + COMPLETE_WITH_QUERY(words_after_create[i].query); + else if (words_after_create[i].squery) + COMPLETE_WITH_SCHEMA_QUERY(*words_after_create[i].squery, + NULL); + break; + } + } + } + + /* + * If we still don't have anything to match we have to fabricate some sort + * of default list. If we were to just return NULL, readline automatically + * attempts filename completion, and that's usually no good. + */ + if (matches == NULL) + { + COMPLETE_WITH_CONST(""); +#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER + rl_completion_append_character = '\0'; +#endif + } + + /* free storage */ + free(prev_wd); + free(prev2_wd); + free(prev3_wd); + free(prev4_wd); + free(prev5_wd); + + /* Return our Grand List O' Matches */ + return matches; +} + + + + + diff --git a/utils/tabcomplete.c b/utils/tabcomplete.c new file mode 100644 index 0000000..f8cba05 --- /dev/null +++ b/utils/tabcomplete.c @@ -0,0 +1,415 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - Tab completion +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// tab-complete.cpp - Functions interfacing with tab-complete from psql +// +////////////////////////////////////////////////////////////////////////// + +/* + * BUG: Must compile as C and not C++, because of + * http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B315481 + * Adds a bit of C<->C++ cruft... + */ + +#define _CRT_NONSTDC_NO_DEPRECATE +#include +#include +#include +#include +#include + +/* + * Callbacks to the C++ world + */ +char *pg_query_to_single_ordered_string(char *query, void *dbptr); + + +/* + * Global vars for readline emulation + */ +static char *rl_line_buffer; + +/* + * Macros to ease typing present in psql, rewritten for our API + */ +#define COMPLETE_WITH_QUERY(query) \ + do { matches = complete_from_query(text,query,NULL,dbptr); } while (0) +#define COMPLETE_WITH_SCHEMA_QUERY(query, addon) \ + do { matches = complete_from_schema_query(text,&query, addon, dbptr); } while (0) +#define COMPLETE_WITH_LIST(list) \ + do { matches = complete_from_list(text,list); } while (0) +#define COMPLETE_WITH_CONST(str) \ + do { matches = complete_from_const(text,str); } while (0) +#define COMPLETE_WITH_ATTR(table) \ + do { matches = complete_from_query(text,Query_for_list_of_attributes, table, dbptr); } while (0) + +/* + * Functions used by the tab completion in psql normally found in pgport + */ +static void *pg_malloc(size_t size) +{ + return malloc(size); +} + +static int pg_strcasecmp(const char *s1, const char *s2) +{ +#ifdef WIN32 + return _stricmp(s1, s2); +#else + return strcasecmp(s1, s2); +#endif +} + +static int pg_strncasecmp(const char *s1, const char *s2, int len) +{ +#ifdef WIN32 + return _strnicmp(s1, s2, len); +#else + return strncasecmp(s1, s2, len); +#endif +} + +/* + * Return the word (space delimited) before point. Set skip > 0 to + * skip that many words; e.g. skip=1 finds the word before the + * previous one. Return value is NULL or a malloc'ed string. + * + * Copied directly from psql. + */ +static char * +previous_word(int point, int skip) +{ + int i, + start = 0, + end = -1, + inquotes = 0; + char *s; + + while (skip-- >= 0) + { + /* first we look for a space before the current word */ + for (i = point; i >= 0; i--) + if (rl_line_buffer[i] == ' ') + break; + + /* now find the first non-space which then constitutes the end */ + for (; i >= 0; i--) + if (rl_line_buffer[i] != ' ') + { + end = i; + break; + } + + /* + * If no end found we return null, because there is no word before the + * point + */ + if (end == -1) + return NULL; + + /* + * Otherwise we now look for the start. The start is either the last + * character before any space going backwards from the end, or it's + * simply character 0 + */ + for (start = end; start > 0; start--) + { + if (rl_line_buffer[start] == '"') + inquotes = !inquotes; + if ((rl_line_buffer[start - 1] == ' ') && inquotes == 0) + break; + } + + point = start; + } + + /* make a copy */ + s = (char *)pg_malloc(end - start + 2); + + strncpy(s, &rl_line_buffer[start], end - start + 1); + s[end - start + 1] = '\0'; + + return s; +} + +/* Find the parenthesis after the last word */ +/* Copied directly from psql */ +static int find_open_parenthesis(int end) +{ + int i = end-1; + + while((rl_line_buffer[i]!=' ')&&(i>=0)) + { + if (rl_line_buffer[i]=='(') return 1; + i--; + } + while((rl_line_buffer[i]==' ')&&(i>=0)) + { + i--; + } + if (rl_line_buffer[i]=='(') + { + return 1; + } + return 0; + +} + + +/* + * Forward declarations + */ +static char *complete_from_list(const char *text, const char * const *list); +static char *complete_from_const(const char *text, const char *string); +static char *complete_from_query(const char *text, const char *query, const char *addon, void *dbptr); +static char *complete_from_schema_query(const char *text, const void* query, const char *addon, void *dbptr); +static char *complete_create_command(char *text); +static char *complete_filename(); + +/* + * Include the main tab completion functionality from psql + */ +#include "tab-complete.inc" + + +/* + * Completion functions mimicking those from psql, only returning a single space separated + * string instead of being called multiple times by the readline library. + */ +static char *_complete_from_list(const char *text, const char * const *list, int casesensitive) +{ + int string_length = strlen(text); + int size = 0; + int i; + char *r; + + for (i = 0; list[i] != NULL; i++) + { + if (casesensitive && strncmp(text, list[i], string_length) == 0) + size += strlen(list[i]); + if (!casesensitive && pg_strncasecmp(text, list[i], string_length) == 0) + size += strlen(list[i]); + } + + if (size == 0) + return NULL; + + r = calloc(size + i*2 + 1, 1); + for (i = 0; list[i] != NULL; i++) + { + if ((casesensitive && strncmp(text, list[i], string_length) == 0) + || + (!casesensitive && pg_strncasecmp(text, list[i], string_length) == 0)) + { + strcat(r,list[i]); + strcat(r," \t"); + } + } + r[strlen(r)-1] = '\0'; /* Chop of trailing space */ + return r; +} + +static char *complete_from_list(const char *text, const char * const *list) +{ + char *r = _complete_from_list(text, list, 1); + if (r) + return r; + return _complete_from_list(text, list, 0); +} + + +static char *complete_from_const(const char *text, const char *string) +{ + return strdup(string); +} + +static char *_complete_from_query(const char *text, const char *query, const SchemaQuery *squery, const char *addon, void *dbptr) +{ + int string_length = strlen(text); + char *e_text; + char *complete_query = NULL; + char *t; + + e_text = malloc(string_length*2+1); + PQescapeString(e_text, text, string_length); + + if (query != NULL) + { + /* Normal query */ + int bufsize = 1024; + char *e_addon; + + /* Normal query needs escaped string */ + if (addon) + { + e_addon = malloc(strlen(addon)*2+1); + PQescapeString(e_addon, addon, strlen(addon)); + } + else + e_addon = strdup(""); + + while (1) + { + int r; + complete_query = realloc(complete_query, bufsize); +#ifdef WIN32 + r = _snprintf(complete_query, bufsize, query, string_length, e_text, e_addon); +#else + r = snprintf(complete_query, bufsize, query, string_length, e_text, e_addon); +#endif + if (r < 0 || r >= bufsize) + bufsize *= 2; + else + break; + } + free(e_addon); + } + else + { + /* Schema query */ + char *selcondition = NULL; + char *viscondition = NULL; + char *suppress_str = NULL; + const char *qualresult; + int bufsize = 2048; + + if (squery->selcondition) + { + selcondition = malloc(strlen(squery->selcondition)+10); + sprintf(selcondition,"%s AND ",squery->selcondition); + } + else + selcondition = strdup(""); + + if (squery->viscondition) + { + viscondition = malloc(strlen(squery->viscondition)+10); + sprintf(viscondition, " AND %s",squery->viscondition); + } + else + viscondition = strdup(""); + + if (strcmp(squery->catname,"pg_catalog.pg_class c") == 0 && + strncmp(text, "pg_", 3) != 0) + suppress_str = " AND c.relnamespace <> (SELECT oid FROM pg_catalog.pg_namespace WHERE nspname = 'pg_catalog')"; + else + suppress_str = ""; + + qualresult = squery->qualresult; + if (qualresult == NULL) + qualresult = squery->result; + + while (1) + { + int r; + complete_query = realloc(complete_query, bufsize); +#ifdef WIN32 + r = _snprintf(complete_query, bufsize, +#else + r = snprintf(complete_query, bufsize, +#endif + "SELECT %s FROM %s WHERE %s substring(%s,1,%d)='%s' %s %s " + "\nUNION\n" + "SELECT pg_catalog.quote_ident(n.nspname) || '.' FROM pg_catalog.pg_namespace n WHERE substring(pg_catalog.quote_ident(n.nspname) || '.',1,%d)='%s' AND (SELECT pg_catalog.count(*) FROM pg_catalog.pg_namespace WHERE substring(pg_catalog.quote_ident(nspname) || '.',1,%d)= substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(nspname))+1))>1" + "\nUNION\n" + "SELECT pg_catalog.quote_ident(n.nspname) || '.' || %s FROM %s, pg_catalog.pg_namespace n WHERE %s = n.oid AND %s substring(pg_catalog.quote_ident(n.nspname) || '.' || %s,1,%d)='%s' AND substring(pg_catalog.quote_ident(n.nspname) || '.',1,%d) = substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(n.nspname))+1) AND (SELECT pg_catalog.count(*) FROM pg_catalog.pg_namespace WHERE substring(pg_catalog.quote_ident(nspname) || '.',1,%d) = substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(nspname))+1)) = 1" + "\n%s", + squery->result, + squery->catname, + selcondition, + squery->result, + string_length, + e_text, + viscondition, + suppress_str, + string_length, + e_text, + string_length, + e_text, + qualresult, + squery->catname, + squery->namespace, + selcondition, + qualresult, + string_length, + e_text, + string_length, + e_text, + string_length, + e_text, + addon?addon:""); + + if (r < 0 || r >= bufsize) + bufsize *= 2; + else + break; + + } + + free(viscondition); + free(selcondition); + + } + t = pg_query_to_single_ordered_string(complete_query, dbptr); + if (complete_query) + free(complete_query); + free(e_text); + return t; +} + +static char *complete_from_query(const char *text, const char *query, const char *addon, void *dbptr) +{ + return _complete_from_query(text, query, NULL, addon, dbptr); +} + +static char *complete_from_schema_query(const char *text, const void* query, const char *addon, void *dbptr) +{ + /* query really is a SchemaQuery, but we don't know about SchemaQuery early enough. */ + return _complete_from_query(text, NULL, (SchemaQuery *)query, addon, dbptr); +} + +static char *complete_create_command(char *text) +{ + int string_length = strlen(text); + int size = 0; + int i; + char *r; + + for (i = 0; words_after_create[i].name != NULL; i++) + { + if (pg_strncasecmp(text, words_after_create[i].name, string_length) == 0) + size += strlen(words_after_create[i].name); + } + + r = calloc(size + i*2 + 1, 1); + for (i = 0; words_after_create[i].name != NULL; i++) + { + if (pg_strncasecmp(text, words_after_create[i].name, string_length) == 0) + { + strcat(r,words_after_create[i].name); + strcat(r," \t"); + } + } + r[strlen(r)-1] = '\0'; /* Chop of trailing space */ + return r; +} + +/* Not implemented */ +static char *complete_filename() +{ + return NULL; +} + + +/* + * Entrypoint from the C++ world + */ +char *tab_complete(const char *allstr, const int startptr, const int endptr, void *dbptr) +{ + rl_line_buffer = (char *)allstr; + return psql_completion((char *)(allstr + startptr), startptr,endptr,dbptr); +} diff --git a/utils/tabcomplete.pl b/utils/tabcomplete.pl new file mode 100644 index 0000000..81ef3da --- /dev/null +++ b/utils/tabcomplete.pl @@ -0,0 +1,55 @@ +#!/usr/bin/perl +########################################################################## +## +## pgAdmin III - Tab completion +## +## Copyright (C) 2002 - 2016, The pgAdmin Development Team +## This software is released under the PostgreSQL Licence +## +## tab-complete.pl - Script to build tab-complete.inc +## +########################################################################## + + +# This script builds tab-complete.inc from tab-complete.c. The +# source file (tab-complete.c) should be copied from the latest +# PostgreSQL sources (src/bin/psql/tab-complete.c), so we don't +# have to do all the work ourselves... + +use strict; +use warnings; + +open(F, "tab-complete.c") || die("Could not open tab-complete.c!"); +undef $/; +my $alltxt = ; +close(F); + +# Get rid of everything before and after the parts we're interested in +$alltxt =~ /.*(typedef struct SchemaQuery.*)\/\* GENERATOR FUNCTIONS\s+.*/s || die("Failed match 1"); +$alltxt = $1; + +# Get rid of forward declarations and initialize_readline +$alltxt =~ /(.*)\/\*\s+Forward declaration of functions \*\/.*(\/\* The completion function\..*)/s || die("Failed match 2"); +$alltxt = $1 . $2; + +# Get rid of completion macros, we define them ourselves +$alltxt =~ /(.*)\/\* A couple of macros to ease typing.*\*\/\s+#define COMPLETE_WITH_QUERY.*\s+(\/\*\s+\* Assembly instructions.*)/s || die("Failed match 4"); +$alltxt = $1 . $2; + +# Rewrite matches that don't use the macros +$alltxt =~ s/completion_matches\(text, create_command_generator\)/complete_create_command\(text\)/gs || die("Failed match 5"); +$alltxt =~ s/completion_matches\(text, filename_completion_function\)/complete_filename\(\)/gs || die("Failed match 6"); + +# We're going to return char*, not char** +$alltxt =~ s/static char \*\*\s+psql_completion/static char \* psql_completion/s || die("Failed match 7"); +$alltxt =~ s/char\s+\*\*matches = NULL/char \*matches = NULL/s || die("Failed match 8"); + +# Add an extra parameter to psql_completion +$alltxt =~ s/psql_completion\(char \*text, int start, int end\)/psql_completion\(char \*text, int start, int end, void \*dbptr\)/s || die("Failed match 9"); + +open(F,">tab-complete.inc") || die("Could not open tab-complete.inc!"); +print F $alltxt; +print F "\n\n"; +close(F); + +print "Done.\n"; diff --git a/utils/utffile.cpp b/utils/utffile.cpp new file mode 100644 index 0000000..55a0822 --- /dev/null +++ b/utils/utffile.cpp @@ -0,0 +1,337 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// utffile.cpp - file io with BOM interpretation +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" +#include "utils/utffile.h" +#include "utils/sysLogger.h" + +wxMBConvUTF16BE wxConvUTF16BE; +wxMBConvUTF16LE wxConvUTF16LE; +wxMBConvUTF32BE wxConvUTF32BE; +wxMBConvUTF32LE wxConvUTF32LE; + +// these are the magic characters identifying an Unicode file +#define BOM_UTF8 "\357\273\277" +#define BOM_UTF16LE "\377\376" +#define BOM_UTF16BE "\376\377" +#define BOM_UTF32LE "\377\376\000\000" +#define BOM_UTF32BE "\000\000\376\377" + +wxUtfFile::wxUtfFile() : wxFile() +{ +} + + +wxUtfFile::wxUtfFile(const wxChar *szFileName, OpenMode mode, wxFontEncoding encoding) : wxFile() +{ + m_strFileName = szFileName; + Open(szFileName, mode, wxS_DEFAULT, encoding); +} + + +wxUtfFile::wxUtfFile(int fd, wxFontEncoding encoding) : wxFile(fd) +{ + EvalBOM(encoding); +} + + +off_t wxUtfFile::Read(wxString &str, off_t nCount) +{ + if (nCount == (off_t) - 1) + nCount = Length() - Tell(); + if (!nCount) + return 0; + + char *buffer = new char[nCount + 4]; + // on some systems, len returned from wxFile::read might not reflect the number of bytes written + // to the buffer, but the bytes read from file. In case of CR/LF translation, this is not the same. + memset(buffer, 0, nCount + 4); + off_t len = wxFile::Read(buffer, nCount); + + if (len >= 0) + { + memset(buffer + len, 0, 4); + + if (m_conversion) + { + int decr; + size_t nLen = 0; + + + // We are trying 4 times to convert, in case the last utf char + // was truncated. + for (decr = 0 ; len > 0 && decr < 4 ; decr++) + { + nLen = m_conversion->MB2WC(NULL, buffer, 0); + if ( nLen != (size_t) - 1 ) + break; + len--; + buffer[len] = 0; + } + + if (nLen == (size_t) - 1) + { + if (!m_strFileName.IsEmpty()) + { + wxLogWarning(_("The file \"%s\" could not be opened because it contains characters that could not be interpreted."), m_strFileName.c_str()); + } + Seek(decr - nLen, wxFromCurrent); + return (size_t) - 1; + } + if (decr) + Seek(-decr, wxFromCurrent); + + m_conversion->MB2WC((wchar_t *)(wxChar *)wxStringBuffer(str, nLen + 1), (const char *)buffer, (size_t)(nLen + 1)); + } + else + str = (wxChar *)buffer; + } + + delete[] buffer; + return len; +} + + +bool wxUtfFile::Write(const wxString &str) +{ + size_t len = str.Length(); + if (!len) + return true; + + if (m_conversion) + { + wxWX2MBbuf buf = str.mb_str(*m_conversion); + if (!buf) + return false; + + return wxFile::Write(str, *m_conversion); + } + else + return wxFile::Write(str.c_str(), len * sizeof(wxChar)) == len * sizeof(wxChar); +} + + + +bool wxUtfFile::Create(const wxChar *szFileName, bool bOverwrite, int access, wxFontEncoding encoding) +{ + if (!wxFile::Create(szFileName, bOverwrite, access)) + return false; + + DetermineConversion(encoding); + WriteBOM(); + + return true; +} + + +bool wxUtfFile::Open(const wxChar *szFileName, OpenMode mode, int access, wxFontEncoding encoding) +{ + if (!wxFile::Open(szFileName, mode, access)) + return false; + + + m_bomOffset = 0; + DetermineConversion(wxFONTENCODING_SYSTEM); + + if (mode != write && EvalBOM(encoding)) + { + // File freshly created, need BOM + if (mode != read) + WriteBOM(); + } + else if (mode != read && encoding != wxFONTENCODING_DEFAULT) + { + // force BOM to a specific value + switch (encoding) + { + case wxFONTENCODING_UTF8: + case wxFONTENCODING_UTF16BE: + case wxFONTENCODING_UTF16LE: + case wxFONTENCODING_UTF32BE: + case wxFONTENCODING_UTF32LE: + break; + default: + encoding = wxFONTENCODING_SYSTEM; + break; + } + if (encoding != m_encoding) + { + DetermineConversion(encoding); + WriteBOM(); + } + } + return true; +} + + +void wxUtfFile::Attach(int fd, wxFontEncoding encoding) +{ + wxFile::Attach(fd); + EvalBOM(encoding); +} + + +off_t wxUtfFile::Seek(off_t ofs, wxSeekMode mode) +{ + off_t pos; + if (mode == wxFromStart) + pos = wxFile::Seek(ofs + m_bomOffset, wxFromStart) - m_bomOffset; + else + pos = wxFile::Seek(ofs, mode) - m_bomOffset; + + if (pos != wxInvalidOffset) + pos -= m_bomOffset; + + return pos; +} + + + +wxFontEncoding wxUtfFile::GetEncoding() +{ + if (IsOpened()) + return m_encoding; + else + return wxFONTENCODING_DEFAULT; +} + + +void wxUtfFile::WriteBOM() +{ + if (!settings->GetWriteBOM()) + return; + + wxFile::Seek(0); + switch (m_encoding) + { + case wxFONTENCODING_UTF8: + wxFile::Write(BOM_UTF8, 3); + m_bomOffset = 3; + break; + case wxFONTENCODING_UTF16BE: + wxFile::Write(BOM_UTF16BE, 2); + m_bomOffset = 2; + break; + case wxFONTENCODING_UTF16LE: + wxFile::Write(BOM_UTF16LE, 2); + m_bomOffset = 2; + break; + case wxFONTENCODING_UTF32BE: + wxFile::Write(BOM_UTF32LE, 4); + m_bomOffset = 4; + break; + case wxFONTENCODING_UTF32LE: + wxFile::Write(BOM_UTF32LE, 4); + m_bomOffset = 4; + break; + default: + m_bomOffset = 0; + break; + } +} + + +void wxUtfFile::DetermineConversion(wxFontEncoding encoding) +{ + switch (encoding) + { + case wxFONTENCODING_UTF8: + case wxFONTENCODING_UTF16BE: + case wxFONTENCODING_UTF16LE: + case wxFONTENCODING_UTF32BE: + case wxFONTENCODING_UTF32LE: + // we know these + m_encoding = encoding; + break; + default: + m_encoding = wxFONTENCODING_SYSTEM; + break; + } + + if (m_encoding == wxFONTENCODING_UNICODE) + m_conversion = 0; + else + { + switch (m_encoding) + { + case wxFONTENCODING_SYSTEM: + m_conversion = &wxConvLibc; + break; + case wxFONTENCODING_UTF8: + m_conversion = &wxConvUTF8; + break; + case wxFONTENCODING_UTF16BE: + m_conversion = &wxConvUTF16BE; + break; + case wxFONTENCODING_UTF16LE: + m_conversion = &wxConvUTF16LE; + break; + case wxFONTENCODING_UTF32BE: + m_conversion = &wxConvUTF32BE; + break; + case wxFONTENCODING_UTF32LE: + m_conversion = &wxConvUTF32LE; + break; + default: + break; + } + } +} + + +bool wxUtfFile::EvalBOM(wxFontEncoding encoding) +{ + // returns true, if BOM needs to be written. + + char bombuf[4] = "###"; + long len = wxFile::Read(bombuf, 4); + + if (!memcmp(bombuf, BOM_UTF32BE, 4)) + { + encoding = wxFONTENCODING_UTF32BE; + m_bomOffset = 4; + } + else if (!memcmp(bombuf, BOM_UTF32LE, 4)) + { + encoding = wxFONTENCODING_UTF32LE; + m_bomOffset = 4; + } + else if (!memcmp(bombuf, BOM_UTF8, 3)) + { + encoding = wxFONTENCODING_UTF8; + m_bomOffset = 3; + } + else if (!memcmp(bombuf, BOM_UTF16BE, 2)) + { + encoding = wxFONTENCODING_UTF16BE; + m_bomOffset = 2; + } + else if (!memcmp(bombuf, BOM_UTF16LE, 2)) + { + encoding = wxFONTENCODING_UTF16LE; + m_bomOffset = 2; + } + else + { + // no encoding was found. + m_bomOffset = 0; + } + + DetermineConversion(encoding); + + // if this file has length 0, BOM needs to be written because it's freshly created + if (len == 0) + return true; + else if (len != m_bomOffset) + Seek(0); + + return false; +}

    +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�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£r(R-Hs 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

  • LYe=>i4Yi&cK7SJ5B9<3 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